use of com.android.launcher3.tapl.Folder in project android_packages_apps_Launcher3 by crdroidandroid.
the class HotseatEduController method migrateToFolder.
/**
* This migration places all non folder items in the hotseat into a folder and then moves
* all folders in the hotseat to a workspace page that has enough empty spots.
*
* @return pageId that has accepted the items.
*/
private int migrateToFolder() {
ArrayDeque<FolderInfo> folders = new ArrayDeque<>();
ArrayList<WorkspaceItemInfo> putIntoFolder = new ArrayList<>();
// separate folders and items that can get in folders
for (int i = 0; i < mLauncher.getDeviceProfile().numShownHotseatIcons; i++) {
View view = mHotseat.getChildAt(i, 0);
if (view == null)
continue;
ItemInfo info = (ItemInfo) view.getTag();
if (info.itemType == LauncherSettings.Favorites.ITEM_TYPE_FOLDER) {
folders.add((FolderInfo) info);
} else if (info instanceof WorkspaceItemInfo && info.container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) {
putIntoFolder.add((WorkspaceItemInfo) info);
}
}
// create a temp folder and add non folder items to it
if (!putIntoFolder.isEmpty()) {
ItemInfo firstItem = putIntoFolder.get(0);
FolderInfo folderInfo = new FolderInfo();
mLauncher.getModelWriter().addItemToDatabase(folderInfo, firstItem.container, firstItem.screenId, firstItem.cellX, firstItem.cellY);
folderInfo.setTitle("", mLauncher.getModelWriter());
folderInfo.contents.addAll(putIntoFolder);
for (int i = 0; i < folderInfo.contents.size(); i++) {
ItemInfo item = folderInfo.contents.get(i);
item.rank = i;
mLauncher.getModelWriter().moveItemInDatabase(item, folderInfo.id, 0, item.cellX, item.cellY);
}
folders.add(folderInfo);
}
mNewItems.addAll(folders);
return placeFoldersInWorkspace(folders);
}
use of com.android.launcher3.tapl.Folder in project android_packages_apps_Launcher3 by crdroidandroid.
the class GridSizeMigrationTask method loadWorkspaceEntries.
/**
* Loads entries for a particular screen id.
*/
protected ArrayList<DbEntry> loadWorkspaceEntries(int screen) {
Cursor c = queryWorkspace(new String[] { // 0
Favorites._ID, // 1
Favorites.ITEM_TYPE, // 2
Favorites.CELLX, // 3
Favorites.CELLY, // 4
Favorites.SPANX, // 5
Favorites.SPANY, // 6
Favorites.INTENT, // 7
Favorites.APPWIDGET_PROVIDER, // 8
Favorites.APPWIDGET_ID }, Favorites.CONTAINER + " = " + Favorites.CONTAINER_DESKTOP + " AND " + Favorites.SCREEN + " = " + screen);
final int indexId = c.getColumnIndexOrThrow(Favorites._ID);
final int indexItemType = c.getColumnIndexOrThrow(Favorites.ITEM_TYPE);
final int indexCellX = c.getColumnIndexOrThrow(Favorites.CELLX);
final int indexCellY = c.getColumnIndexOrThrow(Favorites.CELLY);
final int indexSpanX = c.getColumnIndexOrThrow(Favorites.SPANX);
final int indexSpanY = c.getColumnIndexOrThrow(Favorites.SPANY);
final int indexIntent = c.getColumnIndexOrThrow(Favorites.INTENT);
final int indexAppWidgetProvider = c.getColumnIndexOrThrow(Favorites.APPWIDGET_PROVIDER);
final int indexAppWidgetId = c.getColumnIndexOrThrow(Favorites.APPWIDGET_ID);
ArrayList<DbEntry> entries = new ArrayList<>();
WidgetManagerHelper widgetManagerHelper = new WidgetManagerHelper(mContext);
while (c.moveToNext()) {
DbEntry entry = new DbEntry();
entry.id = c.getInt(indexId);
entry.itemType = c.getInt(indexItemType);
entry.cellX = c.getInt(indexCellX);
entry.cellY = c.getInt(indexCellY);
entry.spanX = c.getInt(indexSpanX);
entry.spanY = c.getInt(indexSpanY);
entry.screenId = screen;
try {
// calculate weight
switch(entry.itemType) {
case Favorites.ITEM_TYPE_SHORTCUT:
case Favorites.ITEM_TYPE_DEEP_SHORTCUT:
case Favorites.ITEM_TYPE_APPLICATION:
{
verifyIntent(c.getString(indexIntent));
entry.weight = entry.itemType == Favorites.ITEM_TYPE_APPLICATION ? WT_APPLICATION : WT_SHORTCUT;
break;
}
case Favorites.ITEM_TYPE_APPWIDGET:
{
String provider = c.getString(indexAppWidgetProvider);
ComponentName cn = ComponentName.unflattenFromString(provider);
verifyPackage(cn.getPackageName());
entry.weight = Math.max(WT_WIDGET_MIN, WT_WIDGET_FACTOR * entry.spanX * entry.spanY);
int widgetId = c.getInt(indexAppWidgetId);
LauncherAppWidgetProviderInfo pInfo = widgetManagerHelper.getLauncherAppWidgetInfo(widgetId);
Point spans = null;
if (pInfo != null) {
spans = pInfo.getMinSpans();
}
if (spans != null) {
entry.minSpanX = spans.x > 0 ? spans.x : entry.spanX;
entry.minSpanY = spans.y > 0 ? spans.y : entry.spanY;
} else {
// Assume that the widget be resized down to 2x2
entry.minSpanX = entry.minSpanY = 2;
}
if (entry.minSpanX > mTrgX || entry.minSpanY > mTrgY) {
throw new Exception("Widget can't be resized down to fit the grid");
}
break;
}
case Favorites.ITEM_TYPE_FOLDER:
{
int total = getFolderItemsCount(entry.id);
if (total == 0) {
throw new Exception("Folder is empty");
}
entry.weight = WT_FOLDER_FACTOR * total;
break;
}
default:
throw new Exception("Invalid item type");
}
} catch (Exception e) {
if (DEBUG) {
Log.d(TAG, "Removing item " + entry.id, e);
}
mEntryToRemove.add(entry.id);
continue;
}
entries.add(entry);
}
c.close();
return entries;
}
use of com.android.launcher3.tapl.Folder 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.tapl.Folder in project android_packages_apps_Launcher3 by crdroidandroid.
the class FolderAnimationManager method addPreviewItemAnimators.
/**
* Animate the items on the current page.
*/
private void addPreviewItemAnimators(AnimatorSet animatorSet, final float folderScale, int previewItemOffsetX, int previewItemOffsetY) {
ClippedFolderIconLayoutRule rule = mFolderIcon.getLayoutRule();
boolean isOnFirstPage = mFolder.mContent.getCurrentPage() == 0;
final List<BubbleTextView> itemsInPreview = getPreviewIconsOnPage(isOnFirstPage ? 0 : mFolder.mContent.getCurrentPage());
final int numItemsInPreview = itemsInPreview.size();
final int numItemsInFirstPagePreview = isOnFirstPage ? numItemsInPreview : MAX_NUM_ITEMS_IN_PREVIEW;
TimeInterpolator previewItemInterpolator = getPreviewItemInterpolator();
ShortcutAndWidgetContainer cwc = mContent.getPageAt(0).getShortcutsAndWidgets();
for (int i = 0; i < numItemsInPreview; ++i) {
final BubbleTextView btv = itemsInPreview.get(i);
CellLayout.LayoutParams btvLp = (CellLayout.LayoutParams) btv.getLayoutParams();
// Calculate the final values in the LayoutParams.
btvLp.isLockedToGrid = true;
cwc.setupLp(btv);
// Match scale of icons in the preview of the items on the first page.
float previewScale = rule.scaleForItem(numItemsInFirstPagePreview);
float previewSize = rule.getIconSize() * previewScale;
float iconScale = previewSize / itemsInPreview.get(i).getIconSize();
final float initialScale = iconScale / folderScale;
final float finalScale = 1f;
float scale = mIsOpening ? initialScale : finalScale;
btv.setScaleX(scale);
btv.setScaleY(scale);
// Match positions of the icons in the folder with their positions in the preview
rule.computePreviewItemDrawingParams(i, numItemsInFirstPagePreview, mTmpParams);
// The PreviewLayoutRule assumes that the icon size takes up the entire width so we
// offset by the actual size.
int iconOffsetX = (int) ((btvLp.width - btv.getIconSize()) * iconScale) / 2;
final int previewPosX = (int) ((mTmpParams.transX - iconOffsetX + previewItemOffsetX) / folderScale);
final float paddingTop = btv.getPaddingTop() * iconScale;
final int previewPosY = (int) ((mTmpParams.transY + previewItemOffsetY - paddingTop) / folderScale);
final float xDistance = previewPosX - btvLp.x;
final float yDistance = previewPosY - btvLp.y;
Animator translationX = getAnimator(btv, View.TRANSLATION_X, xDistance, 0f);
translationX.setInterpolator(previewItemInterpolator);
play(animatorSet, translationX);
Animator translationY = getAnimator(btv, View.TRANSLATION_Y, yDistance, 0f);
translationY.setInterpolator(previewItemInterpolator);
play(animatorSet, translationY);
Animator scaleAnimator = getAnimator(btv, SCALE_PROPERTY, initialScale, finalScale);
scaleAnimator.setInterpolator(previewItemInterpolator);
play(animatorSet, scaleAnimator);
if (mFolder.getItemCount() > MAX_NUM_ITEMS_IN_PREVIEW) {
// These delays allows the preview items to move as part of the Folder's motion,
// and its only necessary for large folders because of differing interpolators.
int delay = mIsOpening ? mDelay : mDelay * 2;
if (mIsOpening) {
translationX.setStartDelay(delay);
translationY.setStartDelay(delay);
scaleAnimator.setStartDelay(delay);
}
translationX.setDuration(translationX.getDuration() - delay);
translationY.setDuration(translationY.getDuration() - delay);
scaleAnimator.setDuration(scaleAnimator.getDuration() - delay);
}
animatorSet.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animation) {
super.onAnimationStart(animation);
// Necessary to initialize values here because of the start delay.
if (mIsOpening) {
btv.setTranslationX(xDistance);
btv.setTranslationY(yDistance);
btv.setScaleX(initialScale);
btv.setScaleY(initialScale);
}
}
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
btv.setTranslationX(0.0f);
btv.setTranslationY(0.0f);
btv.setScaleX(1f);
btv.setScaleY(1f);
}
});
}
}
use of com.android.launcher3.tapl.Folder in project android_packages_apps_Launcher3 by crdroidandroid.
the class FolderAnimationManager method getAnimator.
/**
* Prepares the Folder for animating between open / closed states.
*/
public AnimatorSet getAnimator() {
final BaseDragLayer.LayoutParams lp = (BaseDragLayer.LayoutParams) mFolder.getLayoutParams();
mFolderIcon.getPreviewItemManager().recomputePreviewDrawingParams();
ClippedFolderIconLayoutRule rule = mFolderIcon.getLayoutRule();
final List<BubbleTextView> itemsInPreview = getPreviewIconsOnPage(0);
// Match position of the FolderIcon
final Rect folderIconPos = new Rect();
float scaleRelativeToDragLayer = mFolder.mActivityContext.getDragLayer().getDescendantRectRelativeToSelf(mFolderIcon, folderIconPos);
int scaledRadius = mPreviewBackground.getScaledRadius();
float initialSize = (scaledRadius * 2) * scaleRelativeToDragLayer;
// Match size/scale of icons in the preview
float previewScale = rule.scaleForItem(itemsInPreview.size());
float previewSize = rule.getIconSize() * previewScale;
float initialScale = previewSize / itemsInPreview.get(0).getIconSize() * scaleRelativeToDragLayer;
final float finalScale = 1f;
float scale = mIsOpening ? initialScale : finalScale;
mFolder.setPivotX(0);
mFolder.setPivotY(0);
// Scale the contents of the folder.
mFolder.mContent.setScaleX(scale);
mFolder.mContent.setScaleY(scale);
mFolder.mContent.setPivotX(0);
mFolder.mContent.setPivotY(0);
mFolder.mFooter.setScaleX(scale);
mFolder.mFooter.setScaleY(scale);
mFolder.mFooter.setPivotX(0);
mFolder.mFooter.setPivotY(0);
// We want to create a small X offset for the preview items, so that they follow their
// expected path to their final locations. ie. an icon should not move right, if it's final
// location is to its left. This value is arbitrarily defined.
int previewItemOffsetX = (int) (previewSize / 2);
if (Utilities.isRtl(mContext.getResources())) {
previewItemOffsetX = (int) (lp.width * initialScale - initialSize - previewItemOffsetX);
}
final int paddingOffsetX = (int) (mContent.getPaddingLeft() * initialScale);
final int paddingOffsetY = (int) (mContent.getPaddingTop() * initialScale);
int initialX = folderIconPos.left + mFolder.getPaddingLeft() + mPreviewBackground.getOffsetX() - paddingOffsetX - previewItemOffsetX;
int initialY = folderIconPos.top + mFolder.getPaddingTop() + mPreviewBackground.getOffsetY() - paddingOffsetY;
final float xDistance = initialX - lp.x;
final float yDistance = initialY - lp.y;
// Set up the Folder background.
final int finalColor;
int folderFillColor = Themes.getAttrColor(mContext, R.attr.folderFillColor);
if (mIsOpening) {
finalColor = folderFillColor;
} else {
finalColor = mFolderBackground.getColor().getDefaultColor();
}
final int initialColor = setColorAlphaBound(folderFillColor, mPreviewBackground.getBackgroundAlpha());
mFolderBackground.mutate();
mFolderBackground.setColor(mIsOpening ? initialColor : finalColor);
// Set up the reveal animation that clips the Folder.
int totalOffsetX = paddingOffsetX + previewItemOffsetX;
Rect startRect = new Rect(totalOffsetX, paddingOffsetY, Math.round((totalOffsetX + initialSize)), Math.round((paddingOffsetY + initialSize)));
Rect endRect = new Rect(0, 0, lp.width, lp.height);
float finalRadius = mFolderBackground.getCornerRadius();
// Create the animators.
AnimatorSet a = new AnimatorSet();
// Initialize the Folder items' text.
PropertyResetListener colorResetListener = new PropertyResetListener<>(TEXT_ALPHA_PROPERTY, 1f);
for (BubbleTextView icon : mFolder.getItemsOnPage(mFolder.mContent.getCurrentPage())) {
if (mIsOpening) {
icon.setTextVisibility(false);
}
ObjectAnimator anim = icon.createTextAlphaAnimator(mIsOpening);
anim.addListener(colorResetListener);
play(a, anim);
}
mBgColorAnimator = getAnimator(mFolderBackground, "color", initialColor, finalColor);
play(a, mBgColorAnimator);
play(a, getAnimator(mFolder, View.TRANSLATION_X, xDistance, 0f));
play(a, getAnimator(mFolder, View.TRANSLATION_Y, yDistance, 0f));
play(a, getAnimator(mFolder.mContent, SCALE_PROPERTY, initialScale, finalScale));
play(a, getAnimator(mFolder.mFooter, SCALE_PROPERTY, initialScale, finalScale));
final int footerAlphaDuration;
final int footerStartDelay;
if (isLargeFolder()) {
if (mIsOpening) {
footerAlphaDuration = LARGE_FOLDER_FOOTER_DURATION;
footerStartDelay = mDuration - footerAlphaDuration;
} else {
footerAlphaDuration = 0;
footerStartDelay = 0;
}
} else {
footerStartDelay = 0;
footerAlphaDuration = mDuration;
}
play(a, getAnimator(mFolder.mFooter, ALPHA, 0, 1f), footerStartDelay, footerAlphaDuration);
// Create reveal animator for the folder background
play(a, getShape().createRevealAnimator(mFolder, startRect, endRect, finalRadius, !mIsOpening));
// Create reveal animator for the folder content (capture the top 4 icons 2x2)
int width = mDeviceProfile.folderCellLayoutBorderSpacingPx + mDeviceProfile.folderCellWidthPx * 2;
int height = mDeviceProfile.folderCellLayoutBorderSpacingPx + mDeviceProfile.folderCellHeightPx * 2;
int page = mIsOpening ? mContent.getCurrentPage() : mContent.getDestinationPage();
int left = mContent.getPaddingLeft() + page * lp.width;
Rect contentStart = new Rect(left, 0, left + width, height);
Rect contentEnd = new Rect(left, 0, left + lp.width, lp.height);
play(a, getShape().createRevealAnimator(mFolder.getContent(), contentStart, contentEnd, finalRadius, !mIsOpening));
// Fade in the folder name, as the text can overlap the icons when grid size is small.
mFolder.mFolderName.setAlpha(mIsOpening ? 0f : 1f);
play(a, getAnimator(mFolder.mFolderName, View.ALPHA, 0, 1), mIsOpening ? FOLDER_NAME_ALPHA_DURATION : 0, mIsOpening ? mDuration - FOLDER_NAME_ALPHA_DURATION : FOLDER_NAME_ALPHA_DURATION);
// Translate the footer so that it tracks the bottom of the content.
float normalHeight = mFolder.getContentAreaHeight();
float scaledHeight = normalHeight * initialScale;
float diff = normalHeight - scaledHeight;
play(a, getAnimator(mFolder.mFooter, View.TRANSLATION_Y, -diff, 0f));
// Animate the elevation midway so that the shadow is not noticeable in the background.
int midDuration = mDuration / 2;
Animator z = getAnimator(mFolder, View.TRANSLATION_Z, -mFolder.getElevation(), 0);
play(a, z, mIsOpening ? midDuration : 0, midDuration);
// Store clip variables
CellLayout cellLayout = mContent.getCurrentCellLayout();
boolean folderClipChildren = mFolder.getClipChildren();
boolean folderClipToPadding = mFolder.getClipToPadding();
boolean contentClipChildren = mContent.getClipChildren();
boolean contentClipToPadding = mContent.getClipToPadding();
boolean cellLayoutClipChildren = cellLayout.getClipChildren();
boolean cellLayoutClipPadding = cellLayout.getClipToPadding();
mFolder.setClipChildren(false);
mFolder.setClipToPadding(false);
mContent.setClipChildren(false);
mContent.setClipToPadding(false);
cellLayout.setClipChildren(false);
cellLayout.setClipToPadding(false);
a.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
mFolder.setTranslationX(0.0f);
mFolder.setTranslationY(0.0f);
mFolder.setTranslationZ(0.0f);
mFolder.mContent.setScaleX(1f);
mFolder.mContent.setScaleY(1f);
mFolder.mFooter.setScaleX(1f);
mFolder.mFooter.setScaleY(1f);
mFolder.mFooter.setTranslationX(0f);
mFolder.mFolderName.setAlpha(1f);
mFolder.setClipChildren(folderClipChildren);
mFolder.setClipToPadding(folderClipToPadding);
mContent.setClipChildren(contentClipChildren);
mContent.setClipToPadding(contentClipToPadding);
cellLayout.setClipChildren(cellLayoutClipChildren);
cellLayout.setClipToPadding(cellLayoutClipPadding);
}
});
// animators may use a different interpolator.
for (Animator animator : a.getChildAnimations()) {
animator.setInterpolator(mFolderInterpolator);
}
int radiusDiff = scaledRadius - mPreviewBackground.getRadius();
addPreviewItemAnimators(a, initialScale / scaleRelativeToDragLayer, // difference to keep the preview items centered.
previewItemOffsetX + radiusDiff, radiusDiff);
return a;
}
Aggregations