Search in sources :

Example 1 with Folder

use of com.android.launcher3.folder.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);
}
Also used : ItemInfo(com.android.launcher3.model.data.ItemInfo) WorkspaceItemInfo(com.android.launcher3.model.data.WorkspaceItemInfo) ArrayList(java.util.ArrayList) FolderInfo(com.android.launcher3.model.data.FolderInfo) ArrowTipView(com.android.launcher3.views.ArrowTipView) View(android.view.View) ArrayDeque(java.util.ArrayDeque) WorkspaceItemInfo(com.android.launcher3.model.data.WorkspaceItemInfo)

Example 2 with Folder

use of com.android.launcher3.folder.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;
}
Also used : LauncherAppWidgetProviderInfo(com.android.launcher3.widget.LauncherAppWidgetProviderInfo) ArrayList(java.util.ArrayList) WidgetManagerHelper(com.android.launcher3.widget.WidgetManagerHelper) ComponentName(android.content.ComponentName) Utilities.getPointString(com.android.launcher3.Utilities.getPointString) Utilities.parsePoint(com.android.launcher3.Utilities.parsePoint) Point(android.graphics.Point) Cursor(android.database.Cursor) Utilities.parsePoint(com.android.launcher3.Utilities.parsePoint) Point(android.graphics.Point)

Example 3 with Folder

use of com.android.launcher3.folder.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();
    }
}
Also used : LongSparseArray(android.util.LongSparseArray) HashMap(java.util.HashMap) ComponentKey(com.android.launcher3.util.ComponentKey) SessionInfo(android.content.pm.PackageInstaller.SessionInfo) ShortcutKey(com.android.launcher3.shortcuts.ShortcutKey) ShortcutRequest(com.android.launcher3.shortcuts.ShortcutRequest) ContentResolver(android.content.ContentResolver) QueryResult(com.android.launcher3.shortcuts.ShortcutRequest.QueryResult) UserHandle(android.os.UserHandle) FolderGridOrganizer(com.android.launcher3.folder.FolderGridOrganizer) AppWidgetProviderInfo(android.appwidget.AppWidgetProviderInfo) LauncherAppWidgetProviderInfo(com.android.launcher3.widget.LauncherAppWidgetProviderInfo) WidgetManagerHelper(com.android.launcher3.widget.WidgetManagerHelper) PackageManagerHelper(com.android.launcher3.util.PackageManagerHelper) ComponentName(android.content.ComponentName) Context(android.content.Context) LauncherAppWidgetProviderInfo(com.android.launcher3.widget.LauncherAppWidgetProviderInfo) ComponentWithIconCachingLogic(com.android.launcher3.icons.ComponentWithLabelAndIcon.ComponentWithIconCachingLogic) LauncherActivityCachingLogic(com.android.launcher3.icons.LauncherActivityCachingLogic) ShortcutCachingLogic(com.android.launcher3.icons.ShortcutCachingLogic) ShortcutInfo(android.content.pm.ShortcutInfo) Bundle(android.os.Bundle) PackageUserKey(com.android.launcher3.util.PackageUserKey) LauncherAppWidgetInfo(com.android.launcher3.model.data.LauncherAppWidgetInfo) Intent(android.content.Intent) FolderInfo(com.android.launcher3.model.data.FolderInfo) CancellationException(java.util.concurrent.CancellationException) SuppressLint(android.annotation.SuppressLint) Point(android.graphics.Point) LauncherActivityInfo(android.content.pm.LauncherActivityInfo) WorkspaceItemInfo(com.android.launcher3.model.data.WorkspaceItemInfo)

Example 4 with Folder

use of com.android.launcher3.folder.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);
            }
        });
    }
}
Also used : ShortcutAndWidgetContainer(com.android.launcher3.ShortcutAndWidgetContainer) TimeInterpolator(android.animation.TimeInterpolator) Animator(android.animation.Animator) ObjectAnimator(android.animation.ObjectAnimator) CellLayout(com.android.launcher3.CellLayout) AnimatorListenerAdapter(android.animation.AnimatorListenerAdapter) BubbleTextView(com.android.launcher3.BubbleTextView)

Example 5 with Folder

use of com.android.launcher3.folder.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;
}
Also used : Rect(android.graphics.Rect) ObjectAnimator(android.animation.ObjectAnimator) PropertyResetListener(com.android.launcher3.anim.PropertyResetListener) AnimatorSet(android.animation.AnimatorSet) BaseDragLayer(com.android.launcher3.views.BaseDragLayer) Animator(android.animation.Animator) ObjectAnimator(android.animation.ObjectAnimator) CellLayout(com.android.launcher3.CellLayout) AnimatorListenerAdapter(android.animation.AnimatorListenerAdapter) BubbleTextView(com.android.launcher3.BubbleTextView)

Aggregations

View (android.view.View)18 WorkspaceItemInfo (com.android.launcher3.model.data.WorkspaceItemInfo)18 Point (android.graphics.Point)16 FolderInfo (com.android.launcher3.model.data.FolderInfo)15 ItemInfo (com.android.launcher3.model.data.ItemInfo)14 Folder (com.android.launcher3.folder.Folder)13 AppWidgetHostView (android.appwidget.AppWidgetHostView)12 FolderIcon (com.android.launcher3.folder.FolderIcon)12 SuppressLint (android.annotation.SuppressLint)11 Rect (android.graphics.Rect)11 DragView (com.android.launcher3.dragndrop.DragView)10 LauncherAppWidgetHostView (com.android.launcher3.widget.LauncherAppWidgetHostView)9 PendingAppWidgetHostView (com.android.launcher3.widget.PendingAppWidgetHostView)8 ArrayList (java.util.ArrayList)8 Drawable (android.graphics.drawable.Drawable)7 DraggableView (com.android.launcher3.dragndrop.DraggableView)7 Animator (android.animation.Animator)6 AnimatorListenerAdapter (android.animation.AnimatorListenerAdapter)6 Context (android.content.Context)6 Bitmap (android.graphics.Bitmap)6