mirror of
https://github.com/LawnchairLauncher/lawnchair.git
synced 2026-02-27 15:26:58 +00:00
Add support for progress bar for archived apps in AllApps view.
Working Video: https://drive.google.com/file/d/1-cSD63FQLmqyeTkUuXqcSsjb03m31ULO/view?usp=sharing Test: TaplPromiseIconUiTest Bug: 302115555 Bug: 317108448 Flag: ACONFIG com.android.launcher3.enable_support_for_archiving DEVELOPMENT Change-Id: Iebaa338789430c5e0a004bd8b05bdbda87cd986e
This commit is contained in:
@@ -933,9 +933,7 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver,
|
||||
if (mIcon instanceof PreloadIconDrawable) {
|
||||
preloadIconDrawable = (PreloadIconDrawable) mIcon;
|
||||
preloadIconDrawable.setLevel(progressLevel);
|
||||
// TODO(b/302115555): For archived apps, show icon as disabled if active session
|
||||
// exists.
|
||||
preloadIconDrawable.setIsDisabled(info.getProgressLevel() == 0);
|
||||
preloadIconDrawable.setIsDisabled(isIconDisabled(info));
|
||||
} else {
|
||||
preloadIconDrawable = makePreloadIcon();
|
||||
setIcon(preloadIconDrawable);
|
||||
@@ -960,11 +958,18 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver,
|
||||
final PreloadIconDrawable preloadDrawable = newPendingIcon(getContext(), info);
|
||||
|
||||
preloadDrawable.setLevel(progressLevel);
|
||||
// TODO(b/302115555): For archived apps, show icon as disabled if active session exists.
|
||||
preloadDrawable.setIsDisabled(info.getProgressLevel() == 0);
|
||||
preloadDrawable.setIsDisabled(isIconDisabled(info));
|
||||
return preloadDrawable;
|
||||
}
|
||||
|
||||
private boolean isIconDisabled(ItemInfoWithIcon info) {
|
||||
if (info.isArchived()) {
|
||||
return info.getProgressLevel() == 0
|
||||
&& (info.runtimeStatusFlags & FLAG_INSTALL_SESSION_ACTIVE) != 0;
|
||||
}
|
||||
return info.getProgressLevel() == 0;
|
||||
}
|
||||
|
||||
public void applyDotState(ItemInfo itemInfo, boolean animate) {
|
||||
if (mIcon instanceof FastBitmapDrawable) {
|
||||
boolean wasDotted = mDotInfo != null;
|
||||
|
||||
@@ -16,8 +16,10 @@
|
||||
|
||||
package com.android.launcher3.model;
|
||||
|
||||
import static com.android.launcher3.Flags.enableSupportForArchiving;
|
||||
import static com.android.launcher3.model.data.AppInfo.COMPONENT_KEY_COMPARATOR;
|
||||
import static com.android.launcher3.model.data.AppInfo.EMPTY_ARRAY;
|
||||
import static com.android.launcher3.model.data.ItemInfoWithIcon.FLAG_ARCHIVED;
|
||||
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
@@ -53,6 +55,7 @@ import java.util.function.Predicate;
|
||||
/**
|
||||
* Stores the list of all applications for the all apps view.
|
||||
*/
|
||||
@SuppressWarnings("NewApi")
|
||||
public class AllAppsList {
|
||||
|
||||
private static final String TAG = "AllAppsList";
|
||||
@@ -200,13 +203,18 @@ public class AllAppsList {
|
||||
if (tgtComp != null && tgtComp.getPackageName().equals(installInfo.packageName)
|
||||
&& appInfo.user.equals(user)) {
|
||||
if (installInfo.state == PackageInstallInfo.STATUS_INSTALLED_DOWNLOADING
|
||||
|| installInfo.state == PackageInstallInfo.STATUS_INSTALLING) {
|
||||
|| installInfo.state == PackageInstallInfo.STATUS_INSTALLING
|
||||
// In case unarchival fails, we would want to keep the icon and update
|
||||
// back the progress to 0 for the all apps view without removing the
|
||||
// icon, which is contrary to what happens during normal app installation
|
||||
// flow.
|
||||
|| (installInfo.state == PackageInstallInfo.STATUS_FAILED
|
||||
&& appInfo.isArchived())) {
|
||||
if (appInfo.isAppStartable()
|
||||
&& installInfo.state == PackageInstallInfo.STATUS_INSTALLING) {
|
||||
&& installInfo.state == PackageInstallInfo.STATUS_INSTALLING
|
||||
&& !appInfo.isArchived()) {
|
||||
continue;
|
||||
}
|
||||
// TODO(b/302115555): Handle the case when archived apps are to be updated
|
||||
// during unarchival start.
|
||||
appInfo.setProgressLevel(installInfo);
|
||||
|
||||
updatedAppInfos.add(appInfo);
|
||||
@@ -322,6 +330,11 @@ public class AllAppsList {
|
||||
PackageManagerHelper.getLoadingProgress(info),
|
||||
PackageInstallInfo.STATUS_INSTALLED_DOWNLOADING);
|
||||
applicationInfo.intent = launchIntent;
|
||||
if (enableSupportForArchiving() && info.getActivityInfo().isArchived) {
|
||||
// In case an app is archived, the respective item flag corresponding to
|
||||
// archiving should also be applied during package updates
|
||||
applicationInfo.runtimeStatusFlags |= FLAG_ARCHIVED;
|
||||
}
|
||||
|
||||
mDataChanged = true;
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ package com.android.launcher3.model;
|
||||
|
||||
import static com.android.launcher3.BuildConfig.WIDGET_ON_FIRST_SCREEN;
|
||||
import static com.android.launcher3.Flags.enableLauncherBrMetricsFixed;
|
||||
import static com.android.launcher3.Flags.enableSupportForArchiving;
|
||||
import static com.android.launcher3.LauncherPrefs.IS_FIRST_LOAD_AFTER_RESTORE;
|
||||
import static com.android.launcher3.LauncherPrefs.SHOULD_SHOW_SMARTSPACE;
|
||||
import static com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_APP_PAIR;
|
||||
@@ -30,6 +31,7 @@ import static com.android.launcher3.model.BgDataModel.Callbacks.FLAG_QUIET_MODE_
|
||||
import static com.android.launcher3.model.BgDataModel.Callbacks.FLAG_QUIET_MODE_ENABLED;
|
||||
import static com.android.launcher3.model.BgDataModel.Callbacks.FLAG_WORK_PROFILE_QUIET_MODE_ENABLED;
|
||||
import static com.android.launcher3.model.ModelUtils.filterCurrentWorkspaceItems;
|
||||
import static com.android.launcher3.model.data.ItemInfoWithIcon.FLAG_INSTALL_SESSION_ACTIVE;
|
||||
import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
|
||||
import static com.android.launcher3.util.PackageManagerHelper.hasShortcutsPermission;
|
||||
|
||||
@@ -143,6 +145,7 @@ public class LoaderTask implements Runnable {
|
||||
private final UserManagerState mUserManagerState;
|
||||
protected final Map<ComponentKey, AppWidgetProviderInfo> mWidgetProvidersMap = new ArrayMap<>();
|
||||
private Map<ShortcutKey, ShortcutInfo> mShortcutKeyToPinnedShortcuts;
|
||||
private HashMap<PackageUserKey, SessionInfo> mInstallingPkgsCached;
|
||||
|
||||
private boolean mStopped;
|
||||
|
||||
@@ -170,6 +173,7 @@ public class LoaderTask implements Runnable {
|
||||
mSessionHelper = InstallSessionHelper.INSTANCE.get(mApp.getContext());
|
||||
mIconCache = mApp.getIconCache();
|
||||
mUserManagerState = userManagerState;
|
||||
mInstallingPkgsCached = null;
|
||||
}
|
||||
|
||||
protected synchronized void waitForIdle() {
|
||||
@@ -253,7 +257,7 @@ public class LoaderTask implements Runnable {
|
||||
Trace.beginSection("LoadAllApps");
|
||||
List<LauncherActivityInfo> allActivityList;
|
||||
try {
|
||||
allActivityList = loadAllApps();
|
||||
allActivityList = loadAllApps();
|
||||
} finally {
|
||||
Trace.endSection();
|
||||
}
|
||||
@@ -418,6 +422,9 @@ public class LoaderTask implements Runnable {
|
||||
|
||||
final HashMap<PackageUserKey, SessionInfo> installingPkgs =
|
||||
mSessionHelper.getActiveSessions();
|
||||
if (enableSupportForArchiving()) {
|
||||
mInstallingPkgsCached = installingPkgs;
|
||||
}
|
||||
installingPkgs.forEach(mApp.getIconCache()::updateSessionCache);
|
||||
FileLog.d(TAG, "loadWorkspace: Packages with active install sessions: "
|
||||
+ installingPkgs.keySet().stream().map(info -> info.mPackageName).toList());
|
||||
@@ -651,8 +658,20 @@ public class LoaderTask implements Runnable {
|
||||
for (int i = 0; i < apps.size(); i++) {
|
||||
LauncherActivityInfo app = apps.get(i);
|
||||
AppInfo appInfo = new AppInfo(app, user, quietMode);
|
||||
// TODO(b/302115555): Handle the case when archived apps with active sessions are
|
||||
// loaded.
|
||||
if (enableSupportForArchiving() && app.getApplicationInfo().isArchived) {
|
||||
// For archived apps, include progress info in case there is a pending
|
||||
// install session post restart of device.
|
||||
String appPackageName = app.getApplicationInfo().packageName;
|
||||
SessionInfo si = mInstallingPkgsCached != null ? mInstallingPkgsCached.get(
|
||||
new PackageUserKey(appPackageName, user))
|
||||
: mSessionHelper.getActiveSessionInfo(user,
|
||||
appPackageName);
|
||||
if (si != null) {
|
||||
appInfo.runtimeStatusFlags |= FLAG_INSTALL_SESSION_ACTIVE;
|
||||
appInfo.setProgressLevel((int) (si.getProgress() * 100),
|
||||
PackageInstallInfo.STATUS_INSTALLING);
|
||||
}
|
||||
}
|
||||
|
||||
iconRequestInfos.add(new IconRequestInfo<>(
|
||||
appInfo, app, /* useLowResIcon= */ false));
|
||||
|
||||
@@ -35,6 +35,7 @@ import androidx.test.runner.AndroidJUnit4;
|
||||
|
||||
import com.android.launcher3.Launcher;
|
||||
import com.android.launcher3.LauncherState;
|
||||
import com.android.launcher3.tapl.AllApps;
|
||||
import com.android.launcher3.ui.AbstractLauncherUiTest;
|
||||
import com.android.launcher3.util.LauncherBindableItemsContainer.ItemOperator;
|
||||
import com.android.launcher3.util.TestUtil;
|
||||
@@ -143,16 +144,26 @@ public class TaplPromiseIconUiTest extends AbstractLauncherUiTest {
|
||||
assertThat(mDevice.executeShellCommand(String.format("pm archive %s", DUMMY_PACKAGE)))
|
||||
.isEqualTo("Success\n");
|
||||
|
||||
final ItemOperator findPromiseApp = (info, view) ->
|
||||
info != null && TextUtils.equals(info.title, DUMMY_LABEL);
|
||||
|
||||
// Create and add test session
|
||||
mSessionId = createSession(DUMMY_PACKAGE, /* label= */ "",
|
||||
Bitmap.createBitmap(100, 100, Bitmap.Config.ALPHA_8));
|
||||
|
||||
// Verify promise icon is added
|
||||
waitForLauncherCondition("Test Promise App not found on workspace", launcher ->
|
||||
launcher.getWorkspace().getFirstMatch(findPromiseApp) != null);
|
||||
// Verify promise icon is added to all apps view. The icon may not be added to the
|
||||
// workspace even if there might be no icon present for archived app. But icon will
|
||||
// always be in all apps view. In case an icon is not added, an exception would be thrown.
|
||||
final AllApps allApps = mLauncher.getWorkspace().switchToAllApps();
|
||||
|
||||
// Wait for the promise icon to be added.
|
||||
waitForLauncherCondition(
|
||||
DUMMY_PACKAGE + " app was not found on all apps after being archived",
|
||||
launcher -> {
|
||||
try {
|
||||
allApps.getAppIcon(DUMMY_LABEL);
|
||||
} catch (Throwable t) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
// Remove session
|
||||
mTargetContext.getPackageManager().getPackageInstaller().abandonSession(mSessionId);
|
||||
|
||||
Reference in New Issue
Block a user