use of com.android.launcher3.userevent.nano.LauncherLogProto.Target in project android_packages_apps_Launcher3 by crdroidandroid.
the class QuickstepTransitionManager method getOpeningWindowAnimators.
/**
* @return Animator that controls the window of the opening targets from app icons.
*/
private Animator getOpeningWindowAnimators(View v, RemoteAnimationTargetCompat[] appTargets, RemoteAnimationTargetCompat[] wallpaperTargets, RemoteAnimationTargetCompat[] nonAppTargets, Rect windowTargetBounds, boolean appTargetsAreTranslucent, int rotationChange) {
RectF launcherIconBounds = new RectF();
FloatingIconView floatingView = FloatingIconView.getFloatingIconView(mLauncher, v, !appTargetsAreTranslucent, launcherIconBounds, true);
Rect crop = new Rect();
Matrix matrix = new Matrix();
RemoteAnimationTargets openingTargets = new RemoteAnimationTargets(appTargets, wallpaperTargets, nonAppTargets, MODE_OPENING);
SurfaceTransactionApplier surfaceApplier = new SurfaceTransactionApplier(floatingView);
openingTargets.addReleaseCheck(surfaceApplier);
RemoteAnimationTargetCompat navBarTarget = openingTargets.getNavBarRemoteAnimationTarget();
int[] dragLayerBounds = new int[2];
mDragLayer.getLocationOnScreen(dragLayerBounds);
final boolean hasSplashScreen;
if (supportsSSplashScreen()) {
int taskId = openingTargets.getFirstAppTargetTaskId();
Pair<Integer, Integer> defaultParams = Pair.create(STARTING_WINDOW_TYPE_NONE, 0);
Pair<Integer, Integer> taskParams = mTaskStartParams.getOrDefault(taskId, defaultParams);
mTaskStartParams.remove(taskId);
hasSplashScreen = taskParams.first == STARTING_WINDOW_TYPE_SPLASH_SCREEN;
} else {
hasSplashScreen = false;
}
AnimOpenProperties prop = new AnimOpenProperties(mLauncher.getResources(), mDeviceProfile, windowTargetBounds, launcherIconBounds, v, dragLayerBounds[0], dragLayerBounds[1], hasSplashScreen, floatingView.isDifferentFromAppIcon());
int left = (int) (prop.cropCenterXStart - prop.cropWidthStart / 2);
int top = (int) (prop.cropCenterYStart - prop.cropHeightStart / 2);
int right = (int) (left + prop.cropWidthStart);
int bottom = (int) (top + prop.cropHeightStart);
// Set the crop here so we can calculate the corner radius below.
crop.set(left, top, right, bottom);
RectF floatingIconBounds = new RectF();
RectF tmpRectF = new RectF();
Point tmpPos = new Point();
AnimatorSet animatorSet = new AnimatorSet();
ValueAnimator appAnimator = ValueAnimator.ofFloat(0, 1);
appAnimator.setDuration(APP_LAUNCH_DURATION);
appAnimator.setInterpolator(LINEAR);
appAnimator.addListener(floatingView);
appAnimator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
if (v instanceof BubbleTextView) {
((BubbleTextView) v).setStayPressed(false);
}
openingTargets.release();
}
});
final float initialWindowRadius = supportsRoundedCornersOnWindows(mLauncher.getResources()) ? Math.max(crop.width(), crop.height()) / 2f : 0f;
final float finalWindowRadius = mDeviceProfile.isMultiWindowMode ? 0 : getWindowCornerRadius(mLauncher.getResources());
final float finalShadowRadius = appTargetsAreTranslucent ? 0 : mMaxShadowRadius;
MultiValueUpdateListener listener = new MultiValueUpdateListener() {
FloatProp mDx = new FloatProp(0, prop.dX, 0, APP_LAUNCH_DURATION, mOpeningXInterpolator);
FloatProp mDy = new FloatProp(0, prop.dY, 0, APP_LAUNCH_DURATION, mOpeningInterpolator);
FloatProp mIconScaleToFitScreen = new FloatProp(prop.initialAppIconScale, prop.finalAppIconScale, 0, APP_LAUNCH_DURATION, mOpeningInterpolator);
FloatProp mIconAlpha = new FloatProp(prop.iconAlphaStart, 0f, APP_LAUNCH_ALPHA_START_DELAY, APP_LAUNCH_ALPHA_DURATION, LINEAR);
FloatProp mWindowRadius = new FloatProp(initialWindowRadius, finalWindowRadius, 0, APP_LAUNCH_DURATION, mOpeningInterpolator);
FloatProp mShadowRadius = new FloatProp(0, finalShadowRadius, 0, APP_LAUNCH_DURATION, mOpeningInterpolator);
FloatProp mCropRectCenterX = new FloatProp(prop.cropCenterXStart, prop.cropCenterXEnd, 0, APP_LAUNCH_DURATION, mOpeningInterpolator);
FloatProp mCropRectCenterY = new FloatProp(prop.cropCenterYStart, prop.cropCenterYEnd, 0, APP_LAUNCH_DURATION, mOpeningInterpolator);
FloatProp mCropRectWidth = new FloatProp(prop.cropWidthStart, prop.cropWidthEnd, 0, APP_LAUNCH_DURATION, mOpeningInterpolator);
FloatProp mCropRectHeight = new FloatProp(prop.cropHeightStart, prop.cropHeightEnd, 0, APP_LAUNCH_DURATION, mOpeningInterpolator);
FloatProp mNavFadeOut = new FloatProp(1f, 0f, 0, ANIMATION_NAV_FADE_OUT_DURATION, NAV_FADE_OUT_INTERPOLATOR);
FloatProp mNavFadeIn = new FloatProp(0f, 1f, ANIMATION_DELAY_NAV_FADE_IN, ANIMATION_NAV_FADE_IN_DURATION, NAV_FADE_IN_INTERPOLATOR);
@Override
public void onUpdate(float percent, boolean initOnly) {
// Calculate the size of the scaled icon.
float iconWidth = launcherIconBounds.width() * mIconScaleToFitScreen.value;
float iconHeight = launcherIconBounds.height() * mIconScaleToFitScreen.value;
int left = (int) (mCropRectCenterX.value - mCropRectWidth.value / 2);
int top = (int) (mCropRectCenterY.value - mCropRectHeight.value / 2);
int right = (int) (left + mCropRectWidth.value);
int bottom = (int) (top + mCropRectHeight.value);
crop.set(left, top, right, bottom);
final int windowCropWidth = crop.width();
final int windowCropHeight = crop.height();
if (rotationChange != 0) {
Utilities.rotateBounds(crop, mDeviceProfile.widthPx, mDeviceProfile.heightPx, rotationChange);
}
// Scale the size of the icon to match the size of the window crop.
float scaleX = iconWidth / windowCropWidth;
float scaleY = iconHeight / windowCropHeight;
float scale = Math.min(1f, Math.max(scaleX, scaleY));
float scaledCropWidth = windowCropWidth * scale;
float scaledCropHeight = windowCropHeight * scale;
float offsetX = (scaledCropWidth - iconWidth) / 2;
float offsetY = (scaledCropHeight - iconHeight) / 2;
// Calculate the window position to match the icon position.
tmpRectF.set(launcherIconBounds);
tmpRectF.offset(dragLayerBounds[0], dragLayerBounds[1]);
tmpRectF.offset(mDx.value, mDy.value);
Utilities.scaleRectFAboutCenter(tmpRectF, mIconScaleToFitScreen.value);
float windowTransX0 = tmpRectF.left - offsetX - crop.left * scale;
float windowTransY0 = tmpRectF.top - offsetY - crop.top * scale;
// Calculate the icon position.
floatingIconBounds.set(launcherIconBounds);
floatingIconBounds.offset(mDx.value, mDy.value);
Utilities.scaleRectFAboutCenter(floatingIconBounds, mIconScaleToFitScreen.value);
floatingIconBounds.left -= offsetX;
floatingIconBounds.top -= offsetY;
floatingIconBounds.right += offsetX;
floatingIconBounds.bottom += offsetY;
if (initOnly) {
// For the init pass, we want full alpha since the window is not yet ready.
floatingView.update(1f, 255, floatingIconBounds, percent, 0f, mWindowRadius.value * scale, true);
return;
}
ArrayList<SurfaceParams> params = new ArrayList<>();
for (int i = appTargets.length - 1; i >= 0; i--) {
RemoteAnimationTargetCompat target = appTargets[i];
SurfaceParams.Builder builder = new SurfaceParams.Builder(target.leash);
if (target.mode == MODE_OPENING) {
matrix.setScale(scale, scale);
if (rotationChange == 1) {
matrix.postTranslate(windowTransY0, mDeviceProfile.widthPx - (windowTransX0 + scaledCropWidth));
} else if (rotationChange == 2) {
matrix.postTranslate(mDeviceProfile.widthPx - (windowTransX0 + scaledCropWidth), mDeviceProfile.heightPx - (windowTransY0 + scaledCropHeight));
} else if (rotationChange == 3) {
matrix.postTranslate(mDeviceProfile.heightPx - (windowTransY0 + scaledCropHeight), windowTransX0);
} else {
matrix.postTranslate(windowTransX0, windowTransY0);
}
floatingView.update(mIconAlpha.value, 255, floatingIconBounds, percent, 0f, mWindowRadius.value * scale, true);
builder.withMatrix(matrix).withWindowCrop(crop).withAlpha(1f - mIconAlpha.value).withCornerRadius(mWindowRadius.value).withShadowRadius(mShadowRadius.value);
} else if (target.mode == MODE_CLOSING) {
if (target.localBounds != null) {
final Rect localBounds = target.localBounds;
tmpPos.set(target.localBounds.left, target.localBounds.top);
} else {
tmpPos.set(target.position.x, target.position.y);
}
final Rect crop = new Rect(target.screenSpaceBounds);
crop.offsetTo(0, 0);
if ((rotationChange % 2) == 1) {
int tmp = crop.right;
crop.right = crop.bottom;
crop.bottom = tmp;
tmp = tmpPos.x;
tmpPos.x = tmpPos.y;
tmpPos.y = tmp;
}
matrix.setTranslate(tmpPos.x, tmpPos.y);
builder.withMatrix(matrix).withWindowCrop(crop).withAlpha(1f);
}
params.add(builder.build());
}
if (navBarTarget != null) {
final SurfaceParams.Builder navBuilder = new SurfaceParams.Builder(navBarTarget.leash);
if (mNavFadeIn.value > mNavFadeIn.getStartValue()) {
matrix.setScale(scale, scale);
matrix.postTranslate(windowTransX0, windowTransY0);
navBuilder.withMatrix(matrix).withWindowCrop(crop).withAlpha(mNavFadeIn.value);
} else {
navBuilder.withAlpha(mNavFadeOut.value);
}
params.add(navBuilder.build());
}
surfaceApplier.scheduleApply(params.toArray(new SurfaceParams[params.size()]));
}
};
appAnimator.addUpdateListener(listener);
// Since we added a start delay, call update here to init the FloatingIconView properly.
listener.onUpdate(0, true);
animatorSet.playTogether(appAnimator, getBackgroundAnimator(appTargets));
return animatorSet;
}
use of com.android.launcher3.userevent.nano.LauncherLogProto.Target in project android_packages_apps_Launcher3 by crdroidandroid.
the class HotseatPredictionModel method convertDataModelToAppTargetBundle.
/**
* Creates and returns bundle using workspace items
*/
public static Bundle convertDataModelToAppTargetBundle(Context context, BgDataModel dataModel) {
Bundle bundle = new Bundle();
ArrayList<AppTargetEvent> events = new ArrayList<>();
ArrayList<ItemInfo> workspaceItems = dataModel.getAllWorkspaceItems();
for (ItemInfo item : workspaceItems) {
AppTarget target = getAppTargetFromInfo(context, item);
if (target != null && !isTrackedForPrediction(item))
continue;
events.add(wrapAppTargetWithLocation(target, AppTargetEvent.ACTION_PIN, item));
}
ArrayList<AppTarget> currentTargets = new ArrayList<>();
FixedContainerItems hotseatItems = dataModel.extraItems.get(CONTAINER_HOTSEAT_PREDICTION);
if (hotseatItems != null) {
for (ItemInfo itemInfo : hotseatItems.items) {
AppTarget target = getAppTargetFromInfo(context, itemInfo);
if (target != null)
currentTargets.add(target);
}
}
bundle.putParcelableArrayList(BUNDLE_KEY_PIN_EVENTS, events);
bundle.putParcelableArrayList(BUNDLE_KEY_CURRENT_ITEMS, currentTargets);
return bundle;
}
use of com.android.launcher3.userevent.nano.LauncherLogProto.Target in project android_packages_apps_Launcher3 by crdroidandroid.
the class LoaderTask method loadWorkspace.
protected void loadWorkspace(List<ShortcutInfo> allDeepShortcuts, Uri contentUri, String selection) {
final Context context = mApp.getContext();
final ContentResolver contentResolver = context.getContentResolver();
final PackageManagerHelper pmHelper = new PackageManagerHelper(context);
final boolean isSafeMode = pmHelper.isSafeMode();
final boolean isSdCardReady = Utilities.isBootCompleted();
final WidgetManagerHelper widgetHelper = new WidgetManagerHelper(context);
boolean clearDb = false;
try {
ImportDataTask.performImportIfPossible(context);
} catch (Exception e) {
// Migration failed. Clear workspace.
clearDb = true;
}
if (!clearDb && (MULTI_DB_GRID_MIRATION_ALGO.get() ? !GridSizeMigrationTaskV2.migrateGridIfNeeded(context) : !GridSizeMigrationTask.migrateGridIfNeeded(context))) {
// Migration failed. Clear workspace.
clearDb = true;
}
if (clearDb) {
Log.d(TAG, "loadWorkspace: resetting launcher database");
LauncherSettings.Settings.call(contentResolver, LauncherSettings.Settings.METHOD_CREATE_EMPTY_DB);
}
Log.d(TAG, "loadWorkspace: loading default favorites");
LauncherSettings.Settings.call(contentResolver, LauncherSettings.Settings.METHOD_LOAD_DEFAULT_FAVORITES);
synchronized (mBgDataModel) {
mBgDataModel.clear();
mPendingPackages.clear();
final HashMap<PackageUserKey, SessionInfo> installingPkgs = mSessionHelper.getActiveSessions();
installingPkgs.forEach(mApp.getIconCache()::updateSessionCache);
final PackageUserKey tempPackageKey = new PackageUserKey(null, null);
mFirstScreenBroadcast = new FirstScreenBroadcast(installingPkgs);
Map<ShortcutKey, ShortcutInfo> shortcutKeyToPinnedShortcuts = new HashMap<>();
final LoaderCursor c = new LoaderCursor(contentResolver.query(contentUri, null, selection, null, null), contentUri, mApp, mUserManagerState);
final Bundle extras = c.getExtras();
mDbName = extras == null ? null : extras.getString(LauncherSettings.Settings.EXTRA_DB_NAME);
try {
final int appWidgetIdIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.APPWIDGET_ID);
final int appWidgetProviderIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.APPWIDGET_PROVIDER);
final int spanXIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.SPANX);
final int spanYIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.SPANY);
final int rankIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.RANK);
final int optionsIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.OPTIONS);
final int sourceContainerIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.APPWIDGET_SOURCE);
final LongSparseArray<Boolean> unlockedUsers = new LongSparseArray<>();
mUserManagerState.init(mUserCache, mUserManager);
for (UserHandle user : mUserCache.getUserProfiles()) {
long serialNo = mUserCache.getSerialNumberForUser(user);
boolean userUnlocked = mUserManager.isUserUnlocked(user);
// We can only query for shortcuts when the user is unlocked.
if (userUnlocked) {
QueryResult pinnedShortcuts = new ShortcutRequest(context, user).query(ShortcutRequest.PINNED);
if (pinnedShortcuts.wasSuccess()) {
for (ShortcutInfo shortcut : pinnedShortcuts) {
shortcutKeyToPinnedShortcuts.put(ShortcutKey.fromInfo(shortcut), shortcut);
}
} else {
// Shortcut manager can fail due to some race condition when the
// lock state changes too frequently. For the purpose of the loading
// shortcuts, consider the user is still locked.
userUnlocked = false;
}
}
unlockedUsers.put(serialNo, userUnlocked);
}
WorkspaceItemInfo info;
LauncherAppWidgetInfo appWidgetInfo;
LauncherAppWidgetProviderInfo widgetProviderInfo;
Intent intent;
String targetPkg;
while (!mStopped && c.moveToNext()) {
try {
if (c.user == null) {
// User has been deleted, remove the item.
c.markDeleted("User has been deleted");
continue;
}
boolean allowMissingTarget = false;
switch(c.itemType) {
case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT:
case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION:
case LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT:
intent = c.parseIntent();
if (intent == null) {
c.markDeleted("Invalid or null intent");
continue;
}
int disabledState = mUserManagerState.isUserQuiet(c.serialNumber) ? WorkspaceItemInfo.FLAG_DISABLED_QUIET_USER : 0;
ComponentName cn = intent.getComponent();
targetPkg = cn == null ? intent.getPackage() : cn.getPackageName();
if (TextUtils.isEmpty(targetPkg) && c.itemType != LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT) {
c.markDeleted("Only legacy shortcuts can have null package");
continue;
}
// If there is no target package, its an implicit intent
// (legacy shortcut) which is always valid
boolean validTarget = TextUtils.isEmpty(targetPkg) || mLauncherApps.isPackageEnabled(targetPkg, c.user);
// If it's a deep shortcut, we'll use pinned shortcuts to restore it
if (cn != null && validTarget && c.itemType != LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT) {
// If the component is already present
if (mLauncherApps.isActivityEnabled(cn, c.user)) {
// no special handling necessary for this item
c.markRestored();
} else {
// Gracefully try to find a fallback activity.
intent = pmHelper.getAppLaunchIntent(targetPkg, c.user);
if (intent != null) {
c.restoreFlag = 0;
c.updater().put(LauncherSettings.Favorites.INTENT, intent.toUri(0)).commit();
cn = intent.getComponent();
} else {
c.markDeleted("Unable to find a launch target");
continue;
}
}
}
if (!TextUtils.isEmpty(targetPkg) && !validTarget) {
if (c.restoreFlag != 0) {
// Package is not yet available but might be
// installed later.
FileLog.d(TAG, "package not yet restored: " + targetPkg);
tempPackageKey.update(targetPkg, c.user);
if (c.hasRestoreFlag(WorkspaceItemInfo.FLAG_RESTORE_STARTED)) {
// Restore has started once.
} else if (installingPkgs.containsKey(tempPackageKey)) {
// App restore has started. Update the flag
c.restoreFlag |= WorkspaceItemInfo.FLAG_RESTORE_STARTED;
c.updater().put(LauncherSettings.Favorites.RESTORED, c.restoreFlag).commit();
} else {
c.markDeleted("Unrestored app removed: " + targetPkg);
continue;
}
} else if (pmHelper.isAppOnSdcard(targetPkg, c.user)) {
// Package is present but not available.
disabledState |= WorkspaceItemInfo.FLAG_DISABLED_NOT_AVAILABLE;
// Add the icon on the workspace anyway.
allowMissingTarget = true;
} else if (!isSdCardReady) {
// SdCard is not ready yet. Package might get available,
// once it is ready.
Log.d(TAG, "Missing pkg, will check later: " + targetPkg);
mPendingPackages.add(new PackageUserKey(targetPkg, c.user));
// Add the icon on the workspace anyway.
allowMissingTarget = true;
} else {
// Do not wait for external media load anymore.
c.markDeleted("Invalid package removed: " + targetPkg);
continue;
}
}
if ((c.restoreFlag & WorkspaceItemInfo.FLAG_SUPPORTS_WEB_UI) != 0) {
validTarget = false;
}
if (validTarget) {
// The shortcut points to a valid target (either no target
// or something which is ready to be used)
c.markRestored();
}
boolean useLowResIcon = !c.isOnWorkspaceOrHotseat();
if (c.restoreFlag != 0) {
// Already verified above that user is same as default user
info = c.getRestoredItemInfo(intent);
} else if (c.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION) {
info = c.getAppShortcutInfo(intent, allowMissingTarget, useLowResIcon);
} else if (c.itemType == LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT) {
ShortcutKey key = ShortcutKey.fromIntent(intent, c.user);
if (unlockedUsers.get(c.serialNumber)) {
ShortcutInfo pinnedShortcut = shortcutKeyToPinnedShortcuts.get(key);
if (pinnedShortcut == null) {
// The shortcut is no longer valid.
c.markDeleted("Pinned shortcut not found");
continue;
}
info = new WorkspaceItemInfo(pinnedShortcut, context);
// If the pinned deep shortcut is no longer published,
// use the last saved icon instead of the default.
mIconCache.getShortcutIcon(info, pinnedShortcut, c::loadIcon);
if (pmHelper.isAppSuspended(pinnedShortcut.getPackage(), info.user)) {
info.runtimeStatusFlags |= FLAG_DISABLED_SUSPENDED;
}
intent = info.getIntent();
allDeepShortcuts.add(pinnedShortcut);
} else {
// Create a shortcut info in disabled mode for now.
info = c.loadSimpleWorkspaceItem();
info.runtimeStatusFlags |= FLAG_DISABLED_LOCKED_USER;
}
} else {
// item type == ITEM_TYPE_SHORTCUT
info = c.loadSimpleWorkspaceItem();
// Shortcuts are only available on the primary profile
if (!TextUtils.isEmpty(targetPkg) && pmHelper.isAppSuspended(targetPkg, c.user)) {
disabledState |= FLAG_DISABLED_SUSPENDED;
}
// here
if (intent.getAction() != null && intent.getCategories() != null && intent.getAction().equals(Intent.ACTION_MAIN) && intent.getCategories().contains(Intent.CATEGORY_LAUNCHER)) {
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
}
}
if (info != null) {
c.applyCommonProperties(info);
info.intent = intent;
info.rank = c.getInt(rankIndex);
info.spanX = 1;
info.spanY = 1;
info.runtimeStatusFlags |= disabledState;
if (isSafeMode && !isSystemApp(context, intent)) {
info.runtimeStatusFlags |= FLAG_DISABLED_SAFEMODE;
}
LauncherActivityInfo activityInfo = c.getLauncherActivityInfo();
if (activityInfo != null) {
info.setProgressLevel(PackageManagerHelper.getLoadingProgress(activityInfo), PackageInstallInfo.STATUS_INSTALLED_DOWNLOADING);
}
if (c.restoreFlag != 0 && !TextUtils.isEmpty(targetPkg)) {
tempPackageKey.update(targetPkg, c.user);
SessionInfo si = installingPkgs.get(tempPackageKey);
if (si == null) {
info.runtimeStatusFlags &= ~ItemInfoWithIcon.FLAG_INSTALL_SESSION_ACTIVE;
} else if (activityInfo == null) {
int installProgress = (int) (si.getProgress() * 100);
info.setProgressLevel(installProgress, PackageInstallInfo.STATUS_INSTALLING);
}
}
c.checkAndAddItem(info, mBgDataModel);
} else {
throw new RuntimeException("Unexpected null WorkspaceItemInfo");
}
break;
case LauncherSettings.Favorites.ITEM_TYPE_FOLDER:
FolderInfo folderInfo = mBgDataModel.findOrMakeFolder(c.id);
c.applyCommonProperties(folderInfo);
// Do not trim the folder label, as is was set by the user.
folderInfo.title = c.getString(c.titleIndex);
folderInfo.spanX = 1;
folderInfo.spanY = 1;
folderInfo.options = c.getInt(optionsIndex);
// no special handling required for restored folders
c.markRestored();
c.checkAndAddItem(folderInfo, mBgDataModel);
break;
case LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET:
if (WidgetsModel.GO_DISABLE_WIDGETS) {
c.markDeleted("Only legacy shortcuts can have null package");
continue;
}
// Follow through
case LauncherSettings.Favorites.ITEM_TYPE_CUSTOM_APPWIDGET:
// Read all Launcher-specific widget details
boolean customWidget = c.itemType == LauncherSettings.Favorites.ITEM_TYPE_CUSTOM_APPWIDGET;
int appWidgetId = c.getInt(appWidgetIdIndex);
String savedProvider = c.getString(appWidgetProviderIndex);
final ComponentName component;
boolean isSearchWidget = (c.getInt(optionsIndex) & LauncherAppWidgetInfo.OPTION_SEARCH_WIDGET) != 0;
if (isSearchWidget) {
component = QsbContainerView.getSearchComponentName(context);
if (component == null) {
c.markDeleted("Discarding SearchWidget without packagename ");
continue;
}
} else {
component = ComponentName.unflattenFromString(savedProvider);
}
final boolean isIdValid = !c.hasRestoreFlag(LauncherAppWidgetInfo.FLAG_ID_NOT_VALID);
final boolean wasProviderReady = !c.hasRestoreFlag(LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY);
ComponentKey providerKey = new ComponentKey(component, c.user);
if (!mWidgetProvidersMap.containsKey(providerKey)) {
mWidgetProvidersMap.put(providerKey, widgetHelper.findProvider(component, c.user));
}
final AppWidgetProviderInfo provider = mWidgetProvidersMap.get(providerKey);
final boolean isProviderReady = isValidProvider(provider);
if (!isSafeMode && !customWidget && wasProviderReady && !isProviderReady) {
c.markDeleted("Deleting widget that isn't installed anymore: " + provider);
} else {
if (isProviderReady) {
appWidgetInfo = new LauncherAppWidgetInfo(appWidgetId, provider.provider);
// The provider is available. So the widget is either
// available or not available. We do not need to track
// any future restore updates.
int status = c.restoreFlag & ~LauncherAppWidgetInfo.FLAG_RESTORE_STARTED & ~LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY;
if (!wasProviderReady) {
// Id would be valid only if the widget restore broadcast was received.
if (isIdValid) {
status |= LauncherAppWidgetInfo.FLAG_UI_NOT_READY;
}
}
appWidgetInfo.restoreStatus = status;
} else {
Log.v(TAG, "Widget restore pending id=" + c.id + " appWidgetId=" + appWidgetId + " status =" + c.restoreFlag);
appWidgetInfo = new LauncherAppWidgetInfo(appWidgetId, component);
appWidgetInfo.restoreStatus = c.restoreFlag;
tempPackageKey.update(component.getPackageName(), c.user);
SessionInfo si = installingPkgs.get(tempPackageKey);
Integer installProgress = si == null ? null : (int) (si.getProgress() * 100);
if (c.hasRestoreFlag(LauncherAppWidgetInfo.FLAG_RESTORE_STARTED)) {
// Restore has started once.
} else if (installProgress != null) {
// App restore has started. Update the flag
appWidgetInfo.restoreStatus |= LauncherAppWidgetInfo.FLAG_RESTORE_STARTED;
} else if (!isSafeMode) {
c.markDeleted("Unrestored widget removed: " + component);
continue;
}
appWidgetInfo.installProgress = installProgress == null ? 0 : installProgress;
}
if (appWidgetInfo.hasRestoreFlag(LauncherAppWidgetInfo.FLAG_DIRECT_CONFIG)) {
appWidgetInfo.bindOptions = c.parseIntent();
}
c.applyCommonProperties(appWidgetInfo);
appWidgetInfo.spanX = c.getInt(spanXIndex);
appWidgetInfo.spanY = c.getInt(spanYIndex);
appWidgetInfo.options = c.getInt(optionsIndex);
appWidgetInfo.user = c.user;
appWidgetInfo.sourceContainer = c.getInt(sourceContainerIndex);
if (appWidgetInfo.spanX <= 0 || appWidgetInfo.spanY <= 0) {
c.markDeleted("Widget has invalid size: " + appWidgetInfo.spanX + "x" + appWidgetInfo.spanY);
continue;
}
widgetProviderInfo = widgetHelper.getLauncherAppWidgetInfo(appWidgetId);
if (widgetProviderInfo != null && (appWidgetInfo.spanX < widgetProviderInfo.minSpanX || appWidgetInfo.spanY < widgetProviderInfo.minSpanY)) {
FileLog.d(TAG, "Widget " + widgetProviderInfo.getComponent() + " minSizes not meet: span=" + appWidgetInfo.spanX + "x" + appWidgetInfo.spanY + " minSpan=" + widgetProviderInfo.minSpanX + "x" + widgetProviderInfo.minSpanY);
logWidgetInfo(mApp.getInvariantDeviceProfile(), widgetProviderInfo);
}
if (!c.isOnWorkspaceOrHotseat()) {
c.markDeleted("Widget found where container != " + "CONTAINER_DESKTOP nor CONTAINER_HOTSEAT - ignoring!");
continue;
}
if (!customWidget) {
String providerName = appWidgetInfo.providerName.flattenToString();
if (!providerName.equals(savedProvider) || (appWidgetInfo.restoreStatus != c.restoreFlag)) {
c.updater().put(LauncherSettings.Favorites.APPWIDGET_PROVIDER, providerName).put(LauncherSettings.Favorites.RESTORED, appWidgetInfo.restoreStatus).commit();
}
}
if (appWidgetInfo.restoreStatus != LauncherAppWidgetInfo.RESTORE_COMPLETED) {
appWidgetInfo.pendingItemInfo = WidgetsModel.newPendingItemInfo(appWidgetInfo.providerName);
appWidgetInfo.pendingItemInfo.user = appWidgetInfo.user;
mIconCache.getTitleAndIconForApp(appWidgetInfo.pendingItemInfo, false);
}
c.checkAndAddItem(appWidgetInfo, mBgDataModel);
}
break;
}
} catch (Exception e) {
Log.e(TAG, "Desktop items loading interrupted", e);
}
}
} finally {
IOUtils.closeSilently(c);
}
// Load delegate items
mModelDelegate.loadItems(mUserManagerState, shortcutKeyToPinnedShortcuts);
// Break early if we've stopped loading
if (mStopped) {
mBgDataModel.clear();
return;
}
// Remove dead items
mItemsDeleted = c.commitDeleted();
// Sort the folder items, update ranks, and make sure all preview items are high res.
FolderGridOrganizer verifier = new FolderGridOrganizer(mApp.getInvariantDeviceProfile());
for (FolderInfo folder : mBgDataModel.folders) {
Collections.sort(folder.contents, Folder.ITEM_POS_COMPARATOR);
verifier.setFolderInfo(folder);
int size = folder.contents.size();
// for now. Database will be updated once user manually modifies folder.
for (int rank = 0; rank < size; ++rank) {
WorkspaceItemInfo info = folder.contents.get(rank);
info.rank = rank;
if (info.usingLowResIcon() && info.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION && verifier.isItemInPreview(info.rank)) {
mIconCache.getTitleAndIcon(info, false);
}
}
}
c.commitRestoredItems();
}
}
use of com.android.launcher3.userevent.nano.LauncherLogProto.Target in project android_packages_apps_Launcher3 by crdroidandroid.
the class FolderPagedView method realTimeReorder.
/**
* Reorders the items such that the {@param empty} spot moves to {@param target}
*/
public void realTimeReorder(int empty, int target) {
if (!mViewsBound) {
return;
}
completePendingPageChanges();
int delay = 0;
float delayAmount = START_VIEW_REORDER_DELAY;
// Animation only happens on the current page.
int pageToAnimate = getNextPage();
int maxItemsPerPage = mOrganizer.getMaxItemsPerPage();
int pageT = target / maxItemsPerPage;
int pagePosT = target % maxItemsPerPage;
if (pageT != pageToAnimate) {
Log.e(TAG, "Cannot animate when the target cell is invisible");
}
int pagePosE = empty % maxItemsPerPage;
int pageE = empty / maxItemsPerPage;
int startPos, endPos;
int moveStart, moveEnd;
int direction;
if (target == empty) {
// No animation
return;
} else if (target > empty) {
// Items will move backwards to make room for the empty cell.
direction = 1;
// If empty cell is in a different page, move them instantly.
if (pageE < pageToAnimate) {
moveStart = empty;
// Instantly move the first item in the current page.
moveEnd = pageToAnimate * maxItemsPerPage;
// Animate the 2nd item in the current page, as the first item was already moved to
// the last page.
startPos = 0;
} else {
moveStart = moveEnd = -1;
startPos = pagePosE;
}
endPos = pagePosT;
} else {
// The items will move forward.
direction = -1;
if (pageE > pageToAnimate) {
// Move the items immediately.
moveStart = empty;
// Instantly move the last item in the current page.
moveEnd = (pageToAnimate + 1) * maxItemsPerPage - 1;
// Animations start with the second last item in the page
startPos = maxItemsPerPage - 1;
} else {
moveStart = moveEnd = -1;
startPos = pagePosE;
}
endPos = pagePosT;
}
// Instant moving views.
while (moveStart != moveEnd) {
int rankToMove = moveStart + direction;
int p = rankToMove / maxItemsPerPage;
int pagePos = rankToMove % maxItemsPerPage;
int x = pagePos % mGridCountX;
int y = pagePos / mGridCountX;
final CellLayout page = getPageAt(p);
final View v = page.getChildAt(x, y);
if (v != null) {
if (pageToAnimate != p) {
page.removeView(v);
addViewForRank(v, (WorkspaceItemInfo) v.getTag(), moveStart);
} else {
// Do a fake animation before removing it.
final int newRank = moveStart;
final float oldTranslateX = v.getTranslationX();
Runnable endAction = new Runnable() {
@Override
public void run() {
mPendingAnimations.remove(v);
v.setTranslationX(oldTranslateX);
((CellLayout) v.getParent().getParent()).removeView(v);
addViewForRank(v, (WorkspaceItemInfo) v.getTag(), newRank);
}
};
v.animate().translationXBy((direction > 0 ^ mIsRtl) ? -v.getWidth() : v.getWidth()).setDuration(REORDER_ANIMATION_DURATION).setStartDelay(0).withEndAction(endAction);
mPendingAnimations.put(v, endAction);
}
}
moveStart = rankToMove;
}
if ((endPos - startPos) * direction <= 0) {
// No animation
return;
}
CellLayout page = getPageAt(pageToAnimate);
for (int i = startPos; i != endPos; i += direction) {
int nextPos = i + direction;
View v = page.getChildAt(nextPos % mGridCountX, nextPos / mGridCountX);
if (page.animateChildToPosition(v, i % mGridCountX, i / mGridCountX, REORDER_ANIMATION_DURATION, delay, true, true)) {
delay += delayAmount;
delayAmount *= VIEW_REORDER_DELAY_FACTOR;
}
}
}
use of com.android.launcher3.userevent.nano.LauncherLogProto.Target in project android_packages_apps_Launcher3 by crdroidandroid.
the class Folder method onDropCompleted.
@Override
public void onDropCompleted(final View target, final DragObject d, final boolean success) {
if (success) {
if (mDeleteFolderOnDropCompleted && !mItemAddedBackToSelfViaIcon && target != this) {
replaceFolderWithFinalItem();
}
} else {
// The drag failed, we need to return the item to the folder
WorkspaceItemInfo info = (WorkspaceItemInfo) d.dragInfo;
View icon = (mCurrentDragView != null && mCurrentDragView.getTag() == info) ? mCurrentDragView : mContent.createNewView(info);
ArrayList<View> views = getIconsInReadingOrder();
info.rank = Utilities.boundToRange(info.rank, 0, views.size());
views.add(info.rank, icon);
mContent.arrangeChildren(views);
mItemsInvalidated = true;
try (SuppressInfoChanges s = new SuppressInfoChanges()) {
mFolderIcon.onDrop(d, true);
}
}
if (target != this) {
if (mOnExitAlarm.alarmPending()) {
mOnExitAlarm.cancelAlarm();
if (!success) {
mSuppressFolderDeletion = true;
}
mScrollPauseAlarm.cancelAlarm();
completeDragExit();
}
}
mDeleteFolderOnDropCompleted = false;
mDragInProgress = false;
mItemAddedBackToSelfViaIcon = false;
mCurrentDragView = null;
// Reordering may have occured, and we need to save the new item locations. We do this once
// at the end to prevent unnecessary database operations.
updateItemLocationsInDatabaseBatch(false);
// been refreshed yet.
if (getItemCount() <= mContent.itemsPerPage()) {
// Show the animation, next time something is added to the folder.
mInfo.setOption(FolderInfo.FLAG_MULTI_PAGE_ANIMATION, false, mLauncherDelegate.getModelWriter());
}
}
Aggregations