Merge "Showing alert dialog when shortcut version higher than the App" into tm-dev

This commit is contained in:
Sihua Ma
2022-04-14 18:26:10 +00:00
committed by Android (Google) Code Review
5 changed files with 84 additions and 10 deletions
+11
View File
@@ -303,6 +303,17 @@
<!-- Title for an app whose download has been started. -->
<string name="app_waiting_download_title"><xliff:g id="name" example="Messenger">%1$s</xliff:g> waiting to install</string>
<!-- Title shown on the alert dialog prompting the user to update the application in market
in order to re-enable the disabled shortcuts -->
<string name="dialog_update_title">App update required</string>
<!-- Message shown on the alert dialog prompting the user to update the application -->
<string name="dialog_update_message">The app for this icon isn\'t updated. You can update manually to re-enable this shortcut, or remove the icon.</string>
<!-- Message for the update button in the alert dialog, will bring the user to market -->
<string name="dialog_update">Update</string>
<!-- Message for the remove button in the alert dialog -->
<string name="dialog_remove">Remove</string>
<!-- Strings for widgets & more in the popup container/bottom sheet -->
<!-- Accessibility title for the popup containing a list of widgets. [CHAR_LIMIT=50] -->
+6 -5
View File
@@ -50,7 +50,6 @@ import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.os.Message;
import android.os.Parcelable;
import android.os.UserHandle;
import android.util.AttributeSet;
import android.util.Log;
import android.util.SparseArray;
@@ -123,7 +122,6 @@ import com.android.launcher3.widget.util.WidgetSizes;
import com.android.systemui.plugins.shared.LauncherOverlayManager.LauncherOverlay;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.function.Consumer;
@@ -3297,9 +3295,12 @@ public class Workspace<T extends View & PageIndicator> extends PagedView<T>
}
}
public void removeAbandonedPromise(String packageName, UserHandle user) {
ItemInfoMatcher matcher = ItemInfoMatcher.ofPackages(
Collections.singleton(packageName), user);
/**
* Remove workspace icons & widget information related to items in matcher.
*
* @param matcher the matcher generated by the caller.
*/
public void persistRemoveItemsByMatcher(ItemInfoMatcher matcher) {
mLauncher.getModelWriter().deleteItemsFromDatabase(matcher);
removeItemsByMatcher(matcher);
}
@@ -71,10 +71,6 @@ public abstract class ItemInfoWithIcon extends ItemInfo {
*/
public static final int FLAG_DISABLED_LOCKED_USER = 1 << 5;
public static final int FLAG_DISABLED_MASK = FLAG_DISABLED_SAFEMODE
| FLAG_DISABLED_NOT_AVAILABLE | FLAG_DISABLED_SUSPENDED
| FLAG_DISABLED_QUIET_USER | FLAG_DISABLED_BY_PUBLISHER | FLAG_DISABLED_LOCKED_USER;
/**
* The item points to a system app.
*/
@@ -113,6 +109,16 @@ public abstract class ItemInfoWithIcon extends ItemInfo {
public static final int FLAG_SHOW_DOWNLOAD_PROGRESS_MASK = FLAG_INSTALL_SESSION_ACTIVE
| FLAG_INCREMENTAL_DOWNLOAD_ACTIVE;
/**
* Indicates that the icon is a disabled shortcut and application updates are required.
*/
public static final int FLAG_DISABLED_VERSION_LOWER = 1 << 12;
public static final int FLAG_DISABLED_MASK = FLAG_DISABLED_SAFEMODE
| FLAG_DISABLED_NOT_AVAILABLE | FLAG_DISABLED_SUSPENDED
| FLAG_DISABLED_QUIET_USER | FLAG_DISABLED_BY_PUBLISHER | FLAG_DISABLED_LOCKED_USER
| FLAG_DISABLED_VERSION_LOWER;
/**
* Status associated with the system state of the underlying item. This is calculated every
* time a new info is created and not persisted on the disk.
@@ -180,12 +180,25 @@ public class WorkspaceItemInfo extends ItemInfoWithIcon {
runtimeStatusFlags |= FLAG_DISABLED_BY_PUBLISHER;
}
disabledMessage = shortcutInfo.getDisabledMessage();
if (Utilities.ATLEAST_P
&& shortcutInfo.getDisabledReason() == ShortcutInfo.DISABLED_REASON_VERSION_LOWER) {
runtimeStatusFlags |= FLAG_DISABLED_VERSION_LOWER;
} else {
runtimeStatusFlags &= ~FLAG_DISABLED_VERSION_LOWER;
}
Person[] persons = ApiWrapper.getPersons(shortcutInfo);
personKeys = persons.length == 0 ? Utilities.EMPTY_STRING_ARRAY
: Arrays.stream(persons).map(Person::getKey).sorted().toArray(String[]::new);
}
/**
* {@code true} if the shortcut is disabled due to its app being a lower version.
*/
public boolean isDisabledVersionLower() {
return (runtimeStatusFlags & FLAG_DISABLED_VERSION_LOWER) != 0;
}
/** Returns the WorkspaceItemInfo id associated with the deep shortcut. */
public String getDeepShortcutId() {
return itemType == Favorites.ITEM_TYPE_DEEP_SHORTCUT
@@ -43,6 +43,7 @@ import android.widget.Toast;
import com.android.launcher3.BubbleTextView;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherSettings;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
import com.android.launcher3.folder.Folder;
@@ -58,8 +59,10 @@ import com.android.launcher3.model.data.LauncherAppWidgetInfo;
import com.android.launcher3.model.data.SearchActionItemInfo;
import com.android.launcher3.model.data.WorkspaceItemInfo;
import com.android.launcher3.pm.InstallSessionHelper;
import com.android.launcher3.shortcuts.ShortcutKey;
import com.android.launcher3.testing.TestLogging;
import com.android.launcher3.testing.TestProtocol;
import com.android.launcher3.util.ItemInfoMatcher;
import com.android.launcher3.util.PackageManagerHelper;
import com.android.launcher3.views.FloatingIconView;
import com.android.launcher3.widget.LauncherAppWidgetProviderInfo;
@@ -67,6 +70,8 @@ import com.android.launcher3.widget.PendingAppWidgetHostView;
import com.android.launcher3.widget.WidgetAddFlowHandler;
import com.android.launcher3.widget.WidgetManagerHelper;
import java.util.Collections;
/**
* Class for handling clicks on workspace and all-apps items
*/
@@ -171,7 +176,8 @@ public class ItemClickHandler {
(d, i) -> startMarketIntentForPackage(v, launcher, packageName))
.setNeutralButton(R.string.abandoned_clean_this,
(d, i) -> launcher.getWorkspace()
.removeAbandonedPromise(packageName, user))
.persistRemoveItemsByMatcher(ItemInfoMatcher.ofPackages(
Collections.singleton(packageName), user)))
.create().show();
}
@@ -205,6 +211,12 @@ public class ItemClickHandler {
public static boolean handleDisabledItemClicked(WorkspaceItemInfo shortcut, Context context) {
final int disabledFlags = shortcut.runtimeStatusFlags
& WorkspaceItemInfo.FLAG_DISABLED_MASK;
// Handle the case where the disabled reason is DISABLED_REASON_VERSION_LOWER.
// Show an AlertDialog for the user to choose either updating the app or cancel the launch.
if (maybeCreateAlertDialogForShortcut(shortcut, context)) {
return true;
}
if ((disabledFlags
& ~FLAG_DISABLED_SUSPENDED
& ~FLAG_DISABLED_QUIET_USER) == 0) {
@@ -230,6 +242,37 @@ public class ItemClickHandler {
}
}
private static boolean maybeCreateAlertDialogForShortcut(final WorkspaceItemInfo shortcut,
Context context) {
try {
final Launcher launcher = Launcher.getLauncher(context);
if (shortcut.itemType == LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT
&& shortcut.isDisabledVersionLower()) {
new AlertDialog.Builder(context)
.setTitle(R.string.dialog_update_title)
.setMessage(R.string.dialog_update_message)
.setPositiveButton(R.string.dialog_update, (d, i) -> {
// Direct the user to the play store to update the app
context.startActivity(shortcut.getMarketIntent(context));
})
.setNeutralButton(R.string.dialog_remove, (d, i) -> {
// Remove the icon if launcher is successfully initialized
launcher.getWorkspace().persistRemoveItemsByMatcher(ItemInfoMatcher
.ofShortcutKeys(Collections.singleton(ShortcutKey
.fromItemInfo(shortcut))));
})
.create()
.show();
return true;
}
} catch (Exception e) {
Log.e(TAG, "Error creating alert dialog", e);
}
return false;
}
/**
* Event handler for an app shortcut click.
*