use of com.android.launcher3.tapl.Widget in project Neo-Launcher by NeoApplications.
the class AppWidgetsRestoredReceiver method restoreAppWidgetIds.
/**
* Updates the app widgets whose id has changed during the restore process.
*/
@WorkerThread
public static void restoreAppWidgetIds(Context context, int[] oldWidgetIds, int[] newWidgetIds) {
AppWidgetHost appWidgetHost = new LauncherAppWidgetHost(context);
if (FeatureFlags.GO_DISABLE_WIDGETS) {
Log.e(TAG, "Skipping widget ID remap as widgets not supported");
appWidgetHost.deleteHost();
return;
}
if (!RestoreDbTask.isPending(context)) {
// Someone has already gone through our DB once, probably LoaderTask. Skip any further
// modifications of the DB.
Log.e(TAG, "Skipping widget ID remap as DB already in use");
for (int widgetId : newWidgetIds) {
Log.d(TAG, "Deleting widgetId: " + widgetId);
appWidgetHost.deleteAppWidgetId(widgetId);
}
return;
}
final ContentResolver cr = context.getContentResolver();
final AppWidgetManager widgets = AppWidgetManager.getInstance(context);
for (int i = 0; i < oldWidgetIds.length; i++) {
Log.i(TAG, "Widget state restore id " + oldWidgetIds[i] + " => " + newWidgetIds[i]);
final AppWidgetProviderInfo provider = widgets.getAppWidgetInfo(newWidgetIds[i]);
final int state;
if (LoaderTask.isValidProvider(provider)) {
// This will ensure that we show 'Click to setup' UI if required.
state = LauncherAppWidgetInfo.FLAG_UI_NOT_READY;
} else {
state = LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY;
}
// b/135926478: Work profile widget restore is broken in platform. This forces us to
// recreate the widget during loading with the correct host provider.
long mainProfileId = UserManagerCompat.getInstance(context).getSerialNumberForUser(myUserHandle());
String oldWidgetId = Integer.toString(oldWidgetIds[i]);
int result = new ContentWriter(context, new ContentWriter.CommitParams("appWidgetId=? and (restored & 1) = 1 and profileId=?", new String[] { oldWidgetId, Long.toString(mainProfileId) })).put(LauncherSettings.Favorites.APPWIDGET_ID, newWidgetIds[i]).put(LauncherSettings.Favorites.RESTORED, state).commit();
if (result == 0) {
Cursor cursor = cr.query(Favorites.CONTENT_URI, new String[] { Favorites.APPWIDGET_ID }, "appWidgetId=?", new String[] { oldWidgetId }, null);
try {
if (!cursor.moveToFirst()) {
// The widget no long exists.
appWidgetHost.deleteAppWidgetId(newWidgetIds[i]);
}
} finally {
cursor.close();
}
}
}
LauncherAppState app = LauncherAppState.getInstanceNoCreate();
if (app != null) {
app.getModel().forceReload();
}
}
use of com.android.launcher3.tapl.Widget in project Neo-Launcher by NeoApplications.
the class AppWidgetResizeFrame method showForWidget.
public static void showForWidget(LauncherAppWidgetHostView widget, CellLayout cellLayout) {
Launcher launcher = Launcher.getLauncher(cellLayout.getContext());
AbstractFloatingView.closeAllOpenViews(launcher);
DragLayer dl = launcher.getDragLayer();
AppWidgetResizeFrame frame = (AppWidgetResizeFrame) launcher.getLayoutInflater().inflate(R.layout.app_widget_resize_frame, dl, false);
frame.setupForWidget(widget, cellLayout, dl);
((DragLayer.LayoutParams) frame.getLayoutParams()).customPosition = true;
dl.addView(frame);
frame.mIsOpen = true;
frame.snapToWidget(false);
}
use of com.android.launcher3.tapl.Widget in project Neo-Launcher by NeoApplications.
the class Launcher method inflateAppWidget.
private View inflateAppWidget(LauncherAppWidgetInfo item) {
if (mIsSafeModeEnabled) {
PendingAppWidgetHostView view = new PendingAppWidgetHostView(this, item, mIconCache, true);
prepareAppWidget(view, item);
return view;
}
TraceHelper.beginSection("BIND_WIDGET");
final LauncherAppWidgetProviderInfo appWidgetInfo;
if (item.hasRestoreFlag(LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY)) {
// If the provider is not ready, bind as a pending widget.
appWidgetInfo = null;
} else if (item.hasRestoreFlag(LauncherAppWidgetInfo.FLAG_ID_NOT_VALID)) {
// The widget id is not valid. Try to find the widget based on the provider info.
appWidgetInfo = mAppWidgetManager.findProvider(item.providerName, item.user);
} else {
appWidgetInfo = mAppWidgetManager.getLauncherAppWidgetInfo(item.appWidgetId);
}
// If the provider is ready, but the width is not yet restored, try to restore it.
if (!item.hasRestoreFlag(LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY) && (item.restoreStatus != LauncherAppWidgetInfo.RESTORE_COMPLETED)) {
if (appWidgetInfo == null) {
Log.d(TAG, "Removing restored widget: id=" + item.appWidgetId + " belongs to component " + item.providerName + ", as the provider is null");
getModelWriter().deleteItemFromDatabase(item);
return null;
}
// If we do not have a valid id, try to bind an id.
if (item.hasRestoreFlag(LauncherAppWidgetInfo.FLAG_ID_NOT_VALID)) {
if (!item.hasRestoreFlag(LauncherAppWidgetInfo.FLAG_ID_ALLOCATED)) {
// Id has not been allocated yet. Allocate a new id.
item.appWidgetId = mAppWidgetHost.allocateAppWidgetId();
item.restoreStatus |= LauncherAppWidgetInfo.FLAG_ID_ALLOCATED;
// Also try to bind the widget. If the bind fails, the user will be shown
// a click to setup UI, which will ask for the bind permission.
PendingAddWidgetInfo pendingInfo = new PendingAddWidgetInfo(appWidgetInfo);
pendingInfo.spanX = item.spanX;
pendingInfo.spanY = item.spanY;
pendingInfo.minSpanX = item.minSpanX;
pendingInfo.minSpanY = item.minSpanY;
Bundle options = WidgetHostViewLoader.getDefaultOptionsForWidget(this, pendingInfo);
boolean isDirectConfig = item.hasRestoreFlag(LauncherAppWidgetInfo.FLAG_DIRECT_CONFIG);
if (isDirectConfig && item.bindOptions != null) {
Bundle newOptions = item.bindOptions.getExtras();
if (options != null) {
newOptions.putAll(options);
}
options = newOptions;
}
boolean success = mAppWidgetManager.bindAppWidgetIdIfAllowed(item.appWidgetId, appWidgetInfo, options);
// We tried to bind once. If we were not able to bind, we would need to
// go through the permission dialog, which means we cannot skip the config
// activity.
item.bindOptions = null;
item.restoreStatus &= ~LauncherAppWidgetInfo.FLAG_DIRECT_CONFIG;
// Bind succeeded
if (success) {
// If the widget has a configure activity, it is still needs to set it up,
// otherwise the widget is ready to go.
item.restoreStatus = (appWidgetInfo.configure == null) || isDirectConfig ? LauncherAppWidgetInfo.RESTORE_COMPLETED : LauncherAppWidgetInfo.FLAG_UI_NOT_READY;
}
getModelWriter().updateItemInDatabase(item);
}
} else if (item.hasRestoreFlag(LauncherAppWidgetInfo.FLAG_UI_NOT_READY) && (appWidgetInfo.configure == null)) {
// The widget was marked as UI not ready, but there is no configure activity to
// update the UI.
item.restoreStatus = LauncherAppWidgetInfo.RESTORE_COMPLETED;
getModelWriter().updateItemInDatabase(item);
}
}
final AppWidgetHostView view;
if (item.restoreStatus == LauncherAppWidgetInfo.RESTORE_COMPLETED) {
// Verify that we own the widget
if (appWidgetInfo == null) {
FileLog.e(TAG, "Removing invalid widget: id=" + item.appWidgetId);
getModelWriter().deleteWidgetInfo(item, getAppWidgetHost());
return null;
}
item.minSpanX = appWidgetInfo.minSpanX;
item.minSpanY = appWidgetInfo.minSpanY;
view = mAppWidgetHost.createView(this, item.appWidgetId, appWidgetInfo);
} else {
view = new PendingAppWidgetHostView(this, item, mIconCache, false);
}
prepareAppWidget(view, item);
TraceHelper.endSection("BIND_WIDGET", "id=" + item.appWidgetId);
return view;
}
use of com.android.launcher3.tapl.Widget in project Neo-Launcher by NeoApplications.
the class FocusHelper method handleHotseatButtonKeyEvent.
/**
* Handles key events in the workspace hotseat (bottom of the screen).
* <p>Currently we don't special case for the phone UI in different orientations, even though
* the hotseat is on the side in landscape mode. This is to ensure that accessibility
* consistency is maintained across rotations.
*/
static boolean handleHotseatButtonKeyEvent(View v, int keyCode, KeyEvent e) {
boolean consume = FocusLogic.shouldConsume(keyCode);
if (e.getAction() == KeyEvent.ACTION_UP || !consume) {
return consume;
}
final Launcher launcher = Launcher.getLauncher(v.getContext());
final DeviceProfile profile = launcher.getDeviceProfile();
if (DEBUG) {
Log.v(TAG, String.format("Handle HOTSEAT BUTTONS keyevent=[%s] on hotseat buttons, isVertical=%s", KeyEvent.keyCodeToString(keyCode), profile.isVerticalBarLayout()));
}
// Initialize the variables.
final Workspace workspace = (Workspace) v.getRootView().findViewById(R.id.workspace);
final ShortcutAndWidgetContainer hotseatParent = (ShortcutAndWidgetContainer) v.getParent();
final CellLayout hotseatLayout = (CellLayout) hotseatParent.getParent();
final ItemInfo itemInfo = (ItemInfo) v.getTag();
int pageIndex = workspace.getNextPage();
int pageCount = workspace.getChildCount();
int iconIndex = hotseatParent.indexOfChild(v);
int iconRank = ((CellLayout.LayoutParams) hotseatLayout.getShortcutsAndWidgets().getChildAt(iconIndex).getLayoutParams()).cellX;
final CellLayout iconLayout = (CellLayout) workspace.getChildAt(pageIndex);
if (iconLayout == null) {
// animation.)
return consume;
}
final ViewGroup iconParent = iconLayout.getShortcutsAndWidgets();
ViewGroup parent = null;
int[][] matrix = null;
if (keyCode == KeyEvent.KEYCODE_DPAD_UP && !profile.isVerticalBarLayout()) {
matrix = FocusLogic.createSparseMatrixWithHotseat(iconLayout, hotseatLayout, profile);
iconIndex += iconParent.getChildCount();
parent = iconParent;
} else if (keyCode == KeyEvent.KEYCODE_DPAD_LEFT && profile.isVerticalBarLayout()) {
matrix = FocusLogic.createSparseMatrixWithHotseat(iconLayout, hotseatLayout, profile);
iconIndex += iconParent.getChildCount();
parent = iconParent;
} else if (keyCode == KeyEvent.KEYCODE_DPAD_RIGHT && profile.isVerticalBarLayout()) {
keyCode = KeyEvent.KEYCODE_PAGE_DOWN;
} else {
// For other KEYCODE_DPAD_LEFT and KEYCODE_DPAD_RIGHT navigation, do not use the
// matrix extended with hotseat.
matrix = FocusLogic.createSparseMatrix(hotseatLayout);
parent = hotseatParent;
}
// Process the focus.
int newIconIndex = FocusLogic.handleKeyEvent(keyCode, matrix, iconIndex, pageIndex, pageCount, Utilities.isRtl(v.getResources()));
View newIcon = null;
switch(newIconIndex) {
case FocusLogic.NEXT_PAGE_FIRST_ITEM:
parent = getCellLayoutChildrenForIndex(workspace, pageIndex + 1);
newIcon = parent.getChildAt(0);
// TODO(hyunyoungs): handle cases where the child is not an icon but
// a folder or a widget.
workspace.snapToPage(pageIndex + 1);
break;
case FocusLogic.PREVIOUS_PAGE_FIRST_ITEM:
parent = getCellLayoutChildrenForIndex(workspace, pageIndex - 1);
newIcon = parent.getChildAt(0);
// TODO(hyunyoungs): handle cases where the child is not an icon but
// a folder or a widget.
workspace.snapToPage(pageIndex - 1);
break;
case FocusLogic.PREVIOUS_PAGE_LAST_ITEM:
parent = getCellLayoutChildrenForIndex(workspace, pageIndex - 1);
newIcon = parent.getChildAt(parent.getChildCount() - 1);
// TODO(hyunyoungs): handle cases where the child is not an icon but
// a folder or a widget.
workspace.snapToPage(pageIndex - 1);
break;
case FocusLogic.PREVIOUS_PAGE_LEFT_COLUMN:
case FocusLogic.PREVIOUS_PAGE_RIGHT_COLUMN:
// Go to the previous page but keep the focus on the same hotseat icon.
workspace.snapToPage(pageIndex - 1);
break;
case FocusLogic.NEXT_PAGE_LEFT_COLUMN:
case FocusLogic.NEXT_PAGE_RIGHT_COLUMN:
// Go to the next page but keep the focus on the same hotseat icon.
workspace.snapToPage(pageIndex + 1);
break;
}
if (parent == iconParent && newIconIndex >= iconParent.getChildCount()) {
newIconIndex -= iconParent.getChildCount();
}
if (parent != null) {
if (newIcon == null && newIconIndex >= 0) {
newIcon = parent.getChildAt(newIconIndex);
}
if (newIcon != null) {
newIcon.requestFocus();
playSoundEffect(keyCode, v);
}
}
return consume;
}
use of com.android.launcher3.tapl.Widget in project Neo-Launcher by NeoApplications.
the class Workspace method onDrop.
public void onDrop(final DragObject d, DragOptions options) {
if (TestProtocol.sDebugTracing) {
Log.d(TestProtocol.NO_DRAG_TO_WORKSPACE, "Workspace.onDrop");
}
mDragViewVisualCenter = d.getVisualCenter(mDragViewVisualCenter);
CellLayout dropTargetLayout = mDropToLayout;
// We want the point to be mapped to the dragTarget.
if (dropTargetLayout != null) {
mapPointFromDropLayout(dropTargetLayout, mDragViewVisualCenter);
}
boolean droppedOnOriginalCell = false;
int snapScreen = -1;
boolean resizeOnDrop = false;
if (d.dragSource != this || mDragInfo == null) {
final int[] touchXY = new int[] { (int) mDragViewVisualCenter[0], (int) mDragViewVisualCenter[1] };
onDropExternal(touchXY, dropTargetLayout, d);
} else {
final View cell = mDragInfo.cell;
boolean droppedOnOriginalCellDuringTransition = false;
Runnable onCompleteRunnable = null;
if (dropTargetLayout != null && !d.cancelled) {
// Move internally
boolean hasMovedLayouts = (getParentCellLayoutForView(cell) != dropTargetLayout);
boolean hasMovedIntoHotseat = mLauncher.isHotseatLayout(dropTargetLayout);
int container = hasMovedIntoHotseat ? LauncherSettings.Favorites.CONTAINER_HOTSEAT : LauncherSettings.Favorites.CONTAINER_DESKTOP;
int screenId = (mTargetCell[0] < 0) ? mDragInfo.screenId : getIdForScreen(dropTargetLayout);
int spanX = mDragInfo != null ? mDragInfo.spanX : 1;
int spanY = mDragInfo != null ? mDragInfo.spanY : 1;
// First we find the cell nearest to point at which the item is
// dropped, without any consideration to whether there is an item there.
mTargetCell = findNearestArea((int) mDragViewVisualCenter[0], (int) mDragViewVisualCenter[1], spanX, spanY, dropTargetLayout, mTargetCell);
float distance = dropTargetLayout.getDistanceFromCell(mDragViewVisualCenter[0], mDragViewVisualCenter[1], mTargetCell);
// cell also contains a shortcut, then create a folder with the two shortcuts.
if (createUserFolderIfNecessary(cell, container, dropTargetLayout, mTargetCell, distance, false, d.dragView) || addToExistingFolderIfNecessary(cell, dropTargetLayout, mTargetCell, distance, d, false)) {
mLauncher.getStateManager().goToState(NORMAL, SPRING_LOADED_EXIT_DELAY);
return;
}
// Aside from the special case where we're dropping a shortcut onto a shortcut,
// we need to find the nearest cell location that is vacant
ItemInfo item = d.dragInfo;
int minSpanX = item.spanX;
int minSpanY = item.spanY;
if (item.minSpanX > 0 && item.minSpanY > 0) {
minSpanX = item.minSpanX;
minSpanY = item.minSpanY;
}
droppedOnOriginalCell = item.screenId == screenId && item.container == container && item.cellX == mTargetCell[0] && item.cellY == mTargetCell[1];
droppedOnOriginalCellDuringTransition = droppedOnOriginalCell && mIsSwitchingState;
// When quickly moving an item, a user may accidentally rearrange their
// workspace. So instead we move the icon back safely to its original position.
boolean returnToOriginalCellToPreventShuffling = !isFinishedSwitchingState() && !droppedOnOriginalCellDuringTransition && !dropTargetLayout.isRegionVacant(mTargetCell[0], mTargetCell[1], spanX, spanY);
int[] resultSpan = new int[2];
if (returnToOriginalCellToPreventShuffling) {
mTargetCell[0] = mTargetCell[1] = -1;
} else {
mTargetCell = dropTargetLayout.performReorder((int) mDragViewVisualCenter[0], (int) mDragViewVisualCenter[1], minSpanX, minSpanY, spanX, spanY, cell, mTargetCell, resultSpan, CellLayout.MODE_ON_DROP);
}
boolean foundCell = mTargetCell[0] >= 0 && mTargetCell[1] >= 0;
// if the widget resizes on drop
if (foundCell && (cell instanceof AppWidgetHostView) && (resultSpan[0] != item.spanX || resultSpan[1] != item.spanY)) {
resizeOnDrop = true;
item.spanX = resultSpan[0];
item.spanY = resultSpan[1];
AppWidgetHostView awhv = (AppWidgetHostView) cell;
AppWidgetResizeFrame.updateWidgetSizeRanges(awhv, mLauncher, resultSpan[0], resultSpan[1]);
}
if (foundCell) {
if (getScreenIdForPageIndex(mCurrentPage) != screenId && !hasMovedIntoHotseat) {
snapScreen = getPageIndexForScreenId(screenId);
snapToPage(snapScreen);
}
final ItemInfo info = (ItemInfo) cell.getTag();
if (hasMovedLayouts) {
// Reparent the view
CellLayout parentCell = getParentCellLayoutForView(cell);
if (parentCell != null) {
parentCell.removeView(cell);
} else if (FeatureFlags.IS_DOGFOOD_BUILD) {
throw new NullPointerException("mDragInfo.cell has null parent");
}
addInScreen(cell, container, screenId, mTargetCell[0], mTargetCell[1], info.spanX, info.spanY);
}
// update the item's position after drop
CellLayout.LayoutParams lp = (CellLayout.LayoutParams) cell.getLayoutParams();
lp.cellX = lp.tmpCellX = mTargetCell[0];
lp.cellY = lp.tmpCellY = mTargetCell[1];
lp.cellHSpan = item.spanX;
lp.cellVSpan = item.spanY;
lp.isLockedToGrid = true;
if (container != LauncherSettings.Favorites.CONTAINER_HOTSEAT && cell instanceof LauncherAppWidgetHostView) {
final CellLayout cellLayout = dropTargetLayout;
// We post this call so that the widget has a chance to be placed
// in its final location
final LauncherAppWidgetHostView hostView = (LauncherAppWidgetHostView) cell;
AppWidgetProviderInfo pInfo = hostView.getAppWidgetInfo();
if (pInfo != null && pInfo.resizeMode != AppWidgetProviderInfo.RESIZE_NONE && !d.accessibleDrag) {
onCompleteRunnable = new Runnable() {
public void run() {
if (!isPageInTransition()) {
AppWidgetResizeFrame.showForWidget(hostView, cellLayout);
}
}
};
}
}
mLauncher.getModelWriter().modifyItemInDatabase(info, container, screenId, lp.cellX, lp.cellY, item.spanX, item.spanY);
} else {
if (!returnToOriginalCellToPreventShuffling) {
onNoCellFound(dropTargetLayout);
}
// If we can't find a drop location, we return the item to its original position
CellLayout.LayoutParams lp = (CellLayout.LayoutParams) cell.getLayoutParams();
mTargetCell[0] = lp.cellX;
mTargetCell[1] = lp.cellY;
CellLayout layout = (CellLayout) cell.getParent().getParent();
layout.markCellsAsOccupiedForView(cell);
}
}
final CellLayout parent = (CellLayout) cell.getParent().getParent();
if (d.dragView.hasDrawn()) {
if (droppedOnOriginalCellDuringTransition) {
// Animate the item to its original position, while simultaneously exiting
// spring-loaded mode so the page meets the icon where it was picked up.
mLauncher.getDragController().animateDragViewToOriginalPosition(onCompleteRunnable, cell, SPRING_LOADED_TRANSITION_MS);
mLauncher.getStateManager().goToState(NORMAL);
mLauncher.getDropTargetBar().onDragEnd();
parent.onDropChild(cell);
return;
}
final ItemInfo info = (ItemInfo) cell.getTag();
boolean isWidget = info.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET || info.itemType == LauncherSettings.Favorites.ITEM_TYPE_CUSTOM_APPWIDGET;
if (isWidget) {
int animationType = resizeOnDrop ? ANIMATE_INTO_POSITION_AND_RESIZE : ANIMATE_INTO_POSITION_AND_DISAPPEAR;
animateWidgetDrop(info, parent, d.dragView, null, animationType, cell, false);
} else {
int duration = snapScreen < 0 ? -1 : ADJACENT_SCREEN_DROP_DURATION;
mLauncher.getDragLayer().animateViewIntoPosition(d.dragView, cell, duration, this);
}
} else {
d.deferDragViewCleanupPostAnimation = false;
cell.setVisibility(VISIBLE);
}
parent.onDropChild(cell);
mLauncher.getStateManager().goToState(NORMAL, SPRING_LOADED_EXIT_DELAY, onCompleteRunnable);
}
if (d.stateAnnouncer != null && !droppedOnOriginalCell) {
d.stateAnnouncer.completeAction(R.string.item_moved);
}
}
Aggregations