Search in sources :

Example 66 with Folder

use of com.android.launcher3.tapl.Folder in project android_packages_apps_Trebuchet by LineageOS.

the class DefaultLayoutProviderTest method testCustomProfileLoaded_with_folder.

@Test
public void testCustomProfileLoaded_with_folder() throws Exception {
    writeLayoutAndLoad(new LauncherLayoutBuilder().atHotseat(0).putFolder(android.R.string.copy).addApp(TEST_PACKAGE, TEST_PACKAGE).addApp(TEST_PACKAGE, TEST_PACKAGE).addApp(TEST_PACKAGE, TEST_PACKAGE).build());
    // Verify folder
    assertEquals(1, mModelHelper.getBgDataModel().workspaceItems.size());
    ItemInfo info = mModelHelper.getBgDataModel().workspaceItems.get(0);
    assertEquals(LauncherSettings.Favorites.ITEM_TYPE_FOLDER, info.itemType);
    assertEquals(3, ((FolderInfo) info).contents.size());
}
Also used : LauncherLayoutBuilder(com.android.launcher3.util.LauncherLayoutBuilder) ItemInfo(com.android.launcher3.model.data.ItemInfo) FolderInfo(com.android.launcher3.model.data.FolderInfo) Test(org.junit.Test)

Example 67 with Folder

use of com.android.launcher3.tapl.Folder in project android_packages_apps_Trebuchet by LineageOS.

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 MultiHashMap<UserHandle, String> pendingPackages = new MultiHashMap<>();
    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();
        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);
        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 LongSparseArray<UserHandle> allUsers = c.allUsers;
            final LongSparseArray<Boolean> unlockedUsers = new LongSparseArray<>();
            mUserManagerState.init(mUserCache, mUserManager);
            for (UserHandle user : mUserCache.getUserProfiles()) {
                long serialNo = mUserCache.getSerialNumberForUser(user);
                allUsers.put(serialNo, 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;
            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 (allUsers.indexOfValue(c.user) < 0) {
                                if (c.itemType == LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT) {
                                    c.markDeleted("Legacy shortcuts are only allowed for current users");
                                    continue;
                                } else if (c.restoreFlag != 0) {
                                    // Don't restore items for other profiles.
                                    c.markDeleted("Restore from other profiles not supported");
                                    continue;
                                }
                            }
                            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);
                                    pendingPackages.addToList(c.user, targetPkg);
                                    // 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;
                                }
                                if (c.restoreFlag != 0 && !TextUtils.isEmpty(targetPkg)) {
                                    tempPackageKey.update(targetPkg, c.user);
                                    SessionInfo si = installingPkgs.get(tempPackageKey);
                                    if (si == null) {
                                        info.status &= ~WorkspaceItemInfo.FLAG_INSTALL_SESSION_ACTIVE;
                                    } else {
                                        info.setInstallProgress((int) (si.getProgress() * 100));
                                    }
                                }
                                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);
                            if (mWidgetProvidersMap == null) {
                                mWidgetProvidersMap = WidgetManagerHelper.getAllProvidersMap(context);
                            }
                            final AppWidgetProviderInfo provider = mWidgetProvidersMap.get(new ComponentKey(component, c.user));
                            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;
                                if (appWidgetInfo.spanX <= 0 || appWidgetInfo.spanY <= 0) {
                                    c.markDeleted("Widget has invalid size: " + appWidgetInfo.spanX + "x" + appWidgetInfo.spanY);
                                    continue;
                                }
                                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) {
                                    String pkg = appWidgetInfo.providerName.getPackageName();
                                    appWidgetInfo.pendingItemInfo = new PackageItemInfo(pkg);
                                    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);
        }
        // Break early if we've stopped loading
        if (mStopped) {
            mBgDataModel.clear();
            return;
        }
        if (contentUri == LauncherSettings.Favorites.CONTENT_URI) {
            // Remove dead items
            if (c.commitDeleted()) {
                // Remove any empty folder
                int[] deletedFolderIds = LauncherSettings.Settings.call(contentResolver, LauncherSettings.Settings.METHOD_DELETE_EMPTY_FOLDERS).getIntArray(LauncherSettings.Settings.EXTRA_VALUE);
                for (int folderId : deletedFolderIds) {
                    mBgDataModel.workspaceItems.remove(mBgDataModel.folders.get(folderId));
                    mBgDataModel.folders.remove(folderId);
                    mBgDataModel.itemsIdMap.remove(folderId);
                }
                // Remove any ghost widgets
                LauncherSettings.Settings.call(contentResolver, LauncherSettings.Settings.METHOD_REMOVE_GHOST_WIDGETS);
            }
            // Unpin shortcuts that don't exist on the workspace.
            HashSet<ShortcutKey> pendingShortcuts = InstallShortcutReceiver.getPendingShortcuts(context);
            for (ShortcutKey key : shortcutKeyToPinnedShortcuts.keySet()) {
                MutableInt numTimesPinned = mBgDataModel.pinnedShortcutCounts.get(key);
                if ((numTimesPinned == null || numTimesPinned.value == 0) && !pendingShortcuts.contains(key)) {
                    // Shortcut is pinned but doesn't exist on the workspace; unpin it.
                    mBgDataModel.unpinShortcut(context, key);
                }
            }
        }
        // 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();
        if (!isSdCardReady && !pendingPackages.isEmpty()) {
            context.registerReceiver(new SdCardAvailableReceiver(mApp, pendingPackages), new IntentFilter(Intent.ACTION_BOOT_COMPLETED), null, MODEL_EXECUTOR.getHandler());
        }
    }
}
Also used : LongSparseArray(android.util.LongSparseArray) MultiHashMap(com.android.launcher3.util.MultiHashMap) HashMap(java.util.HashMap) ComponentKey(com.android.launcher3.util.ComponentKey) SessionInfo(android.content.pm.PackageInstaller.SessionInfo) MultiHashMap(com.android.launcher3.util.MultiHashMap) 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) PackageItemInfo(com.android.launcher3.model.data.PackageItemInfo) PackageManagerHelper(com.android.launcher3.util.PackageManagerHelper) ComponentName(android.content.ComponentName) Context(android.content.Context) IntentFilter(android.content.IntentFilter) ComponentWithIconCachingLogic(com.android.launcher3.icons.ComponentWithLabelAndIcon.ComponentWithIconCachingLogic) LauncherActivityCachingLogic(com.android.launcher3.icons.LauncherActivityCachingLogic) ShortcutCachingLogic(com.android.launcher3.icons.ShortcutCachingLogic) ShortcutInfo(android.content.pm.ShortcutInfo) 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) MutableInt(android.util.MutableInt) WorkspaceItemInfo(com.android.launcher3.model.data.WorkspaceItemInfo)

Example 68 with Folder

use of com.android.launcher3.tapl.Folder in project android_packages_apps_Trebuchet by LineageOS.

the class ImportDataTask method importWorkspaceItems.

/**
 * 1) Imports all the workspace entries from the source provider.
 * 2) For home screen entries, maps the screen id based on {@param screenIdMap}
 * 3) In the end fills any holes in hotseat with items from default hotseat layout.
 */
private void importWorkspaceItems() throws Exception {
    String profileId = Long.toString(UserCache.INSTANCE.get(mContext).getSerialNumberForUser(Process.myUserHandle()));
    boolean createEmptyRowOnFirstScreen;
    if (FeatureFlags.QSB_ON_FIRST_SCREEN) {
        try (Cursor c = mContext.getContentResolver().query(mOtherFavoritesUri, null, // get items on the first row of the first screen (min screen id)
        "profileId = ? AND container = -100 AND cellY = 0 AND screen = " + "(SELECT MIN(screen) FROM favorites WHERE container = -100)", new String[] { profileId }, null)) {
            // First row of first screen is not empty
            createEmptyRowOnFirstScreen = c.moveToNext();
        }
    } else {
        createEmptyRowOnFirstScreen = false;
    }
    ArrayList<ContentProviderOperation> insertOperations = new ArrayList<>(BATCH_INSERT_SIZE);
    // Set of package names present in hotseat
    final HashSet<String> hotseatTargetApps = new HashSet<>();
    int maxId = 0;
    // Number of imported items on workspace and hotseat
    int totalItemsOnWorkspace = 0;
    try (Cursor c = mContext.getContentResolver().query(mOtherFavoritesUri, null, // Only migrate the primary user
    Favorites.PROFILE_ID + " = ?", new String[] { profileId }, // before the corresponding items.
    Favorites.CONTAINER + " , " + Favorites.SCREEN)) {
        // various columns we expect to exist.
        final int idIndex = c.getColumnIndexOrThrow(Favorites._ID);
        final int intentIndex = c.getColumnIndexOrThrow(Favorites.INTENT);
        final int titleIndex = c.getColumnIndexOrThrow(Favorites.TITLE);
        final int containerIndex = c.getColumnIndexOrThrow(Favorites.CONTAINER);
        final int itemTypeIndex = c.getColumnIndexOrThrow(Favorites.ITEM_TYPE);
        final int widgetProviderIndex = c.getColumnIndexOrThrow(Favorites.APPWIDGET_PROVIDER);
        final int screenIndex = c.getColumnIndexOrThrow(Favorites.SCREEN);
        final int cellXIndex = c.getColumnIndexOrThrow(Favorites.CELLX);
        final int cellYIndex = c.getColumnIndexOrThrow(Favorites.CELLY);
        final int spanXIndex = c.getColumnIndexOrThrow(Favorites.SPANX);
        final int spanYIndex = c.getColumnIndexOrThrow(Favorites.SPANY);
        final int rankIndex = c.getColumnIndexOrThrow(Favorites.RANK);
        final int iconIndex = c.getColumnIndexOrThrow(Favorites.ICON);
        final int iconPackageIndex = c.getColumnIndexOrThrow(Favorites.ICON_PACKAGE);
        final int iconResourceIndex = c.getColumnIndexOrThrow(Favorites.ICON_RESOURCE);
        SparseBooleanArray mValidFolders = new SparseBooleanArray();
        ContentValues values = new ContentValues();
        Integer firstScreenId = null;
        while (c.moveToNext()) {
            values.clear();
            int id = c.getInt(idIndex);
            maxId = Math.max(maxId, id);
            int type = c.getInt(itemTypeIndex);
            int container = c.getInt(containerIndex);
            int screen = c.getInt(screenIndex);
            int cellX = c.getInt(cellXIndex);
            int cellY = c.getInt(cellYIndex);
            int spanX = c.getInt(spanXIndex);
            int spanY = c.getInt(spanYIndex);
            switch(container) {
                case Favorites.CONTAINER_DESKTOP:
                    {
                        if (screen < Workspace.FIRST_SCREEN_ID) {
                            FileLog.d(TAG, String.format("Skipping item %d, type %d not on a valid screen %d", id, type, screen));
                            continue;
                        }
                        if (firstScreenId == null) {
                            firstScreenId = screen;
                        }
                        // Reset the screen to 0-index value
                        if (createEmptyRowOnFirstScreen && firstScreenId.equals(screen)) {
                            // Shift items by 1.
                            cellY++;
                            // Change the screen id to first screen
                            screen = Workspace.FIRST_SCREEN_ID;
                        }
                        mMaxGridSizeX = Math.max(mMaxGridSizeX, cellX + spanX);
                        mMaxGridSizeY = Math.max(mMaxGridSizeY, cellY + spanY);
                        break;
                    }
                case Favorites.CONTAINER_HOTSEAT:
                    {
                        mHotseatSize = Math.max(mHotseatSize, screen + 1);
                        break;
                    }
                default:
                    if (!mValidFolders.get(container)) {
                        FileLog.d(TAG, String.format("Skipping item %d, type %d not in a valid folder %d", id, type, container));
                        continue;
                    }
            }
            Intent intent = null;
            switch(type) {
                case Favorites.ITEM_TYPE_FOLDER:
                    {
                        mValidFolders.put(id, true);
                        // Use a empty intent to indicate a folder.
                        intent = new Intent();
                        break;
                    }
                case Favorites.ITEM_TYPE_APPWIDGET:
                    {
                        values.put(Favorites.RESTORED, LauncherAppWidgetInfo.FLAG_ID_NOT_VALID | LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY | LauncherAppWidgetInfo.FLAG_UI_NOT_READY);
                        values.put(Favorites.APPWIDGET_PROVIDER, c.getString(widgetProviderIndex));
                        break;
                    }
                case Favorites.ITEM_TYPE_SHORTCUT:
                case Favorites.ITEM_TYPE_APPLICATION:
                    {
                        intent = Intent.parseUri(c.getString(intentIndex), 0);
                        if (PackageManagerHelper.isLauncherAppTarget(intent)) {
                            type = Favorites.ITEM_TYPE_APPLICATION;
                        } else {
                            values.put(Favorites.ICON_PACKAGE, c.getString(iconPackageIndex));
                            values.put(Favorites.ICON_RESOURCE, c.getString(iconResourceIndex));
                        }
                        values.put(Favorites.ICON, c.getBlob(iconIndex));
                        values.put(Favorites.INTENT, intent.toUri(0));
                        values.put(Favorites.RANK, c.getInt(rankIndex));
                        values.put(Favorites.RESTORED, 1);
                        break;
                    }
                default:
                    FileLog.d(TAG, String.format("Skipping item %d, not a valid type %d", id, type));
                    continue;
            }
            if (container == Favorites.CONTAINER_HOTSEAT) {
                if (intent == null) {
                    FileLog.d(TAG, String.format("Skipping item %d, null intent on hotseat", id));
                    continue;
                }
                if (intent.getComponent() != null) {
                    intent.setPackage(intent.getComponent().getPackageName());
                }
                hotseatTargetApps.add(getPackage(intent));
            }
            values.put(Favorites._ID, id);
            values.put(Favorites.ITEM_TYPE, type);
            values.put(Favorites.CONTAINER, container);
            values.put(Favorites.SCREEN, screen);
            values.put(Favorites.CELLX, cellX);
            values.put(Favorites.CELLY, cellY);
            values.put(Favorites.SPANX, spanX);
            values.put(Favorites.SPANY, spanY);
            values.put(Favorites.TITLE, c.getString(titleIndex));
            insertOperations.add(ContentProviderOperation.newInsert(Favorites.CONTENT_URI).withValues(values).build());
            if (container < 0) {
                totalItemsOnWorkspace++;
            }
            if (insertOperations.size() >= BATCH_INSERT_SIZE) {
                mContext.getContentResolver().applyBatch(LauncherProvider.AUTHORITY, insertOperations);
                insertOperations.clear();
            }
        }
    }
    FileLog.d(TAG, totalItemsOnWorkspace + " items imported from external source");
    if (totalItemsOnWorkspace < MIN_ITEM_COUNT_FOR_SUCCESSFUL_MIGRATION) {
        throw new Exception("Insufficient data");
    }
    if (!insertOperations.isEmpty()) {
        mContext.getContentResolver().applyBatch(LauncherProvider.AUTHORITY, insertOperations);
        insertOperations.clear();
    }
    IntSparseArrayMap<Object> hotseatItems = GridSizeMigrationTask.removeBrokenHotseatItems(mContext);
    int myHotseatCount = LauncherAppState.getIDP(mContext).numHotseatIcons;
    if (hotseatItems.size() < myHotseatCount) {
        // Insufficient hotseat items. Add a few more.
        HotseatParserCallback parserCallback = new HotseatParserCallback(hotseatTargetApps, hotseatItems, insertOperations, maxId + 1, myHotseatCount);
        new HotseatLayoutParser(mContext, parserCallback).loadLayout(null, new IntArray());
        mHotseatSize = hotseatItems.keyAt(hotseatItems.size() - 1) + 1;
        if (!insertOperations.isEmpty()) {
            mContext.getContentResolver().applyBatch(LauncherProvider.AUTHORITY, insertOperations);
        }
    }
}
Also used : ContentValues(android.content.ContentValues) ContentProviderOperation(android.content.ContentProviderOperation) ArrayList(java.util.ArrayList) Intent(android.content.Intent) Cursor(android.database.Cursor) URISyntaxException(java.net.URISyntaxException) IntArray(com.android.launcher3.util.IntArray) SparseBooleanArray(android.util.SparseBooleanArray) HashSet(java.util.HashSet)

Example 69 with Folder

use of com.android.launcher3.tapl.Folder in project android_packages_apps_Trebuchet by LineageOS.

the class GridSizeMigrationTask method getFolderItemsCount.

/**
 * @return the number of valid items in the folder.
 */
private int getFolderItemsCount(int folderId) {
    Cursor c = queryWorkspace(new String[] { Favorites._ID, Favorites.INTENT }, Favorites.CONTAINER + " = " + folderId);
    int total = 0;
    while (c.moveToNext()) {
        try {
            verifyIntent(c.getString(1));
            total++;
        } catch (Exception e) {
            mEntryToRemove.add(c.getInt(0));
        }
    }
    c.close();
    return total;
}
Also used : Cursor(android.database.Cursor) Utilities.parsePoint(com.android.launcher3.Utilities.parsePoint) Point(android.graphics.Point)

Example 70 with Folder

use of com.android.launcher3.tapl.Folder in project android_packages_apps_Trebuchet by LineageOS.

the class GridSizeMigrationTask method loadHotseatEntries.

private ArrayList<DbEntry> loadHotseatEntries() {
    Cursor c = queryWorkspace(new String[] { // 0
    Favorites._ID, // 1
    Favorites.ITEM_TYPE, // 2
    Favorites.INTENT, // 3
    Favorites.SCREEN }, Favorites.CONTAINER + " = " + Favorites.CONTAINER_HOTSEAT);
    final int indexId = c.getColumnIndexOrThrow(Favorites._ID);
    final int indexItemType = c.getColumnIndexOrThrow(Favorites.ITEM_TYPE);
    final int indexIntent = c.getColumnIndexOrThrow(Favorites.INTENT);
    final int indexScreen = c.getColumnIndexOrThrow(Favorites.SCREEN);
    ArrayList<DbEntry> entries = new ArrayList<>();
    while (c.moveToNext()) {
        DbEntry entry = new DbEntry();
        entry.id = c.getInt(indexId);
        entry.itemType = c.getInt(indexItemType);
        entry.screenId = c.getInt(indexScreen);
        if (entry.screenId >= mSrcHotseatSize) {
            mEntryToRemove.add(entry.id);
            continue;
        }
        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_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 : ArrayList(java.util.ArrayList) Cursor(android.database.Cursor) Utilities.parsePoint(com.android.launcher3.Utilities.parsePoint) Point(android.graphics.Point)

Aggregations

View (android.view.View)119 WorkspaceItemInfo (com.android.launcher3.model.data.WorkspaceItemInfo)112 FolderInfo (com.android.launcher3.model.data.FolderInfo)93 ItemInfo (com.android.launcher3.model.data.ItemInfo)86 Point (android.graphics.Point)83 FolderIcon (com.android.launcher3.folder.FolderIcon)83 Folder (com.android.launcher3.folder.Folder)82 AppWidgetHostView (android.appwidget.AppWidgetHostView)80 SuppressLint (android.annotation.SuppressLint)73 DragView (com.android.launcher3.dragndrop.DragView)64 PendingAppWidgetHostView (com.android.launcher3.widget.PendingAppWidgetHostView)64 Rect (android.graphics.Rect)63 LauncherAppWidgetHostView (com.android.launcher3.widget.LauncherAppWidgetHostView)61 BubbleTextView (com.android.launcher3.BubbleTextView)56 ArrayList (java.util.ArrayList)49 LauncherAppWidgetInfo (com.android.launcher3.model.data.LauncherAppWidgetInfo)47 Animator (android.animation.Animator)40 AnimatorListenerAdapter (android.animation.AnimatorListenerAdapter)40 Drawable (android.graphics.drawable.Drawable)37 CellLayout (com.android.launcher3.CellLayout)37