Merge "Removing support for lagacy shortcuts" into udc-qpr-dev

This commit is contained in:
TreeHugger Robot
2023-05-17 19:25:45 +00:00
committed by Android (Google) Code Review
36 changed files with 470 additions and 760 deletions
+1 -2
View File
@@ -1928,7 +1928,7 @@ public class Launcher extends StatefulActivity<LauncherState>
case LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET:
addAppWidgetFromDrop((PendingAddWidgetInfo) info);
break;
case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT:
case LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT:
processShortcutFromDrop((PendingAddShortcutInfo) info);
break;
default:
@@ -2435,7 +2435,6 @@ public class Launcher extends StatefulActivity<LauncherState>
final View view;
switch (item.itemType) {
case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION:
case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT:
case LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT: {
WorkspaceItemInfo info = (WorkspaceItemInfo) item;
view = createShortcut(info);
@@ -104,6 +104,8 @@ public class LauncherAppState implements SafeCloseable {
});
mContext.getSystemService(LauncherApps.class).registerCallback(mModel);
mOnTerminateCallback.add(() ->
mContext.getSystemService(LauncherApps.class).unregisterCallback(mModel));
SimpleBroadcastReceiver modelChangeReceiver =
new SimpleBroadcastReceiver(mModel::onBroadcastIntent);
@@ -123,8 +125,9 @@ public class LauncherAppState implements SafeCloseable {
mOnTerminateCallback.add(userChangeListener::close);
LockedUserState.get(context).runOnUserUnlocked(() -> {
CustomWidgetManager.INSTANCE.get(mContext)
.setWidgetRefreshCallback(mModel::refreshAndBindWidgetsAndShortcuts);
CustomWidgetManager cwm = CustomWidgetManager.INSTANCE.get(mContext);
cwm.setWidgetRefreshCallback(mModel::refreshAndBindWidgetsAndShortcuts);
mOnTerminateCallback.add(() -> cwm.setWidgetRefreshCallback(null));
IconObserver observer = new IconObserver();
SafeCloseable iconChangeTracker = mIconProvider.registerIconChangeListener(
@@ -159,6 +162,7 @@ public class LauncherAppState implements SafeCloseable {
mModel = new LauncherModel(context, this, mIconCache, new AppFilter(mContext),
iconCacheFileName != null);
mOnTerminateCallback.add(mIconCache::close);
mOnTerminateCallback.add(mModel::destroy);
}
private void onNotificationSettingsChanged(boolean areNotificationDotsEnabled) {
@@ -180,9 +184,6 @@ public class LauncherAppState implements SafeCloseable {
*/
@Override
public void close() {
mModel.destroy();
mContext.getSystemService(LauncherApps.class).unregisterCallback(mModel);
CustomWidgetManager.INSTANCE.get(mContext).setWidgetRefreshCallback(null);
mOnTerminateCallback.executeAllAndDestroy();
}
@@ -89,7 +89,9 @@ public class LauncherSettings {
/**
* The gesture is an application created shortcut
* @deprecated This is no longer supported. Use {@link #ITEM_TYPE_DEEP_SHORTCUT} instead
*/
@Deprecated
public static final int ITEM_TYPE_SHORTCUT = 1;
/**
@@ -213,7 +215,6 @@ public class LauncherSettings {
public static final String itemTypeToString(int type) {
switch(type) {
case ITEM_TYPE_APPLICATION: return "APP";
case ITEM_TYPE_SHORTCUT: return "SHORTCUT";
case ITEM_TYPE_FOLDER: return "FOLDER";
case ITEM_TYPE_APPWIDGET: return "WIDGET";
case ITEM_TYPE_CUSTOM_APPWIDGET: return "CUSTOMWIDGET";
+2 -4
View File
@@ -1840,7 +1840,6 @@ public class Workspace<T extends View & PageIndicator> extends PagedView<T>
!= LauncherSettings.Favorites.CONTAINER_HOTSEAT_PREDICTION);
boolean willBecomeShortcut =
(info.itemType == ITEM_TYPE_APPLICATION ||
info.itemType == LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT ||
info.itemType == LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT);
return (aboveShortcut && willBecomeShortcut);
@@ -2759,7 +2758,7 @@ public class Workspace<T extends View & PageIndicator> extends PagedView<T>
final PendingAddItemInfo pendingInfo = (PendingAddItemInfo) info;
boolean findNearestVacantCell = true;
if (pendingInfo.itemType == LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT) {
if (pendingInfo.itemType == LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT) {
mTargetCell = findNearestArea(touchXY[0], touchXY[1], spanX, spanY,
cellLayout, mTargetCell);
float distance = cellLayout.getDistanceFromWorkspaceCellVisualCenter(
@@ -2832,8 +2831,7 @@ public class Workspace<T extends View & PageIndicator> extends PagedView<T>
View view;
switch (info.itemType) {
case ITEM_TYPE_APPLICATION:
case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT:
case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION:
case LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT:
case LauncherSettings.Favorites.ITEM_TYPE_SEARCH_ACTION:
if (info instanceof WorkspaceItemFactory) {
@@ -881,7 +881,6 @@ public class Folder extends AbstractFloatingView implements ClipPathView, DragSo
final ItemInfo item = d.dragInfo;
final int itemType = item.itemType;
return ((itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION ||
itemType == LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT ||
itemType == LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT));
}
@@ -260,7 +260,6 @@ public class FolderIcon extends FrameLayout implements FolderListener, IconLabel
private boolean willAcceptItem(ItemInfo item) {
final int itemType = item.itemType;
return ((itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION ||
itemType == LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT ||
itemType == LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT) &&
item != mInfo && !mFolder.isOpen());
}
@@ -34,13 +34,9 @@ import android.appwidget.AppWidgetHostView;
import android.appwidget.AppWidgetProviderInfo;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.Intent;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.graphics.PointF;
import android.graphics.Rect;
import android.graphics.drawable.AdaptiveIconDrawable;
import android.graphics.drawable.ColorDrawable;
import android.os.Build;
import android.os.Handler;
import android.os.Looper;
@@ -78,8 +74,6 @@ import com.android.launcher3.celllayout.CellLayoutLayoutParams;
import com.android.launcher3.celllayout.CellPosMapper;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.folder.FolderIcon;
import com.android.launcher3.icons.BaseIconFactory;
import com.android.launcher3.icons.BitmapInfo;
import com.android.launcher3.icons.LauncherIcons;
import com.android.launcher3.model.BgDataModel;
import com.android.launcher3.model.BgDataModel.FixedContainerItems;
@@ -183,7 +177,6 @@ public class LauncherPreviewRenderer extends ContextWrapper
private final DeviceProfile mDp;
private final DeviceProfile mDpOrig;
private final Rect mInsets;
private final WorkspaceItemInfo mWorkspaceItemInfo;
private final LayoutInflater mHomeElementInflater;
private final InsettableFrameLayout mRootView;
private final Hotseat mHotseat;
@@ -221,19 +214,6 @@ public class LauncherPreviewRenderer extends ContextWrapper
mDp.isTaskbarPresent ? 0 : currentWindowInsets.getSystemWindowInsetBottom());
mDp.updateInsets(mInsets);
BaseIconFactory iconFactory =
new BaseIconFactory(context, mIdp.fillResIconDpi, mIdp.iconBitmapSize) { };
BitmapInfo iconInfo = iconFactory.createBadgedIconBitmap(
new AdaptiveIconDrawable(
new ColorDrawable(Color.WHITE),
new ColorDrawable(Color.WHITE)));
mWorkspaceItemInfo = new WorkspaceItemInfo();
mWorkspaceItemInfo.bitmap = iconInfo;
mWorkspaceItemInfo.intent = new Intent();
mWorkspaceItemInfo.contentDescription = mWorkspaceItemInfo.title =
context.getString(R.string.label_application);
mHomeElementInflater = LayoutInflater.from(
new ContextThemeWrapper(this, R.style.HomeScreenElementTheme));
mHomeElementInflater.setFactory2(this);
@@ -483,7 +463,6 @@ public class LauncherPreviewRenderer extends ContextWrapper
for (ItemInfo itemInfo : currentWorkspaceItems) {
switch (itemInfo.itemType) {
case Favorites.ITEM_TYPE_APPLICATION:
case Favorites.ITEM_TYPE_SHORTCUT:
case Favorites.ITEM_TYPE_DEEP_SHORTCUT:
inflateAndAddIcon((WorkspaceItemInfo) itemInfo);
break;
@@ -91,8 +91,7 @@ public class AddWorkspaceItemsTask extends BaseModelUpdateTask {
List<ItemInfo> filteredItems = new ArrayList<>();
for (Pair<ItemInfo, Object> entry : mItemList) {
ItemInfo item = entry.first;
if (item.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION ||
item.itemType == LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT) {
if (item.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION) {
// Short-circuit this logic if the icon exists somewhere on the workspace
if (shortcutExists(dataModel, item.getIntent(), item.user)) {
continue;
@@ -210,7 +210,6 @@ public class BgDataModel {
// Fall through.
}
case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION:
case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT:
workspaceItems.remove(item);
break;
case LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET:
@@ -245,7 +244,6 @@ public class BgDataModel {
break;
case LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT:
case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION:
case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT:
if (item.container == LauncherSettings.Favorites.CONTAINER_DESKTOP ||
item.container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) {
workspaceItems.add(item);
@@ -455,7 +455,6 @@ public class GridSizeMigrationUtil {
try {
// calculate weight
switch (entry.itemType) {
case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT:
case LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT:
case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION: {
entry.mIntent = c.getString(indexIntent);
@@ -531,7 +530,6 @@ public class GridSizeMigrationUtil {
try {
// calculate weight
switch (entry.itemType) {
case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT:
case LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT:
case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION: {
entry.mIntent = c.getString(indexIntent);
@@ -286,7 +286,6 @@ public class ItemInstallQueue {
final WorkspaceItemInfo si = new WorkspaceItemInfo();
si.user = user;
si.itemType = ITEM_TYPE_APPLICATION;
LauncherActivityInfo lai;
boolean usePackageIcon = laiList.isEmpty();
@@ -193,9 +193,7 @@ public class LoaderCursor extends CursorWrapper {
public IconRequestInfo<WorkspaceItemInfo> createIconRequestInfo(
WorkspaceItemInfo wai, boolean useLowResIcon) {
byte[] iconBlob = itemType == Favorites.ITEM_TYPE_SHORTCUT
|| itemType == Favorites.ITEM_TYPE_DEEP_SHORTCUT
|| restoreFlag != 0
byte[] iconBlob = itemType == Favorites.ITEM_TYPE_DEEP_SHORTCUT || restoreFlag != 0
? getIconBlob() : null;
return new IconRequestInfo<>(wai, mActivityInfo, iconBlob, useLowResIcon);
@@ -347,7 +345,6 @@ public class LoaderCursor extends CursorWrapper {
}
final WorkspaceItemInfo info = new WorkspaceItemInfo();
info.itemType = Favorites.ITEM_TYPE_APPLICATION;
info.user = user;
info.intent = newIntent;
@@ -503,7 +503,6 @@ public class LoaderTask implements Runnable {
boolean allowMissingTarget = false;
switch (c.itemType) {
case Favorites.ITEM_TYPE_SHORTCUT:
case Favorites.ITEM_TYPE_APPLICATION:
case Favorites.ITEM_TYPE_DEEP_SHORTCUT:
Intent intent = c.parseIntent();
@@ -517,9 +516,8 @@ public class LoaderTask implements Runnable {
ComponentName cn = intent.getComponent();
String targetPkg = cn == null ? intent.getPackage() : cn.getPackageName();
if (TextUtils.isEmpty(targetPkg)
&& c.itemType != Favorites.ITEM_TYPE_SHORTCUT) {
c.markDeleted("Only legacy shortcuts can have null package");
if (TextUtils.isEmpty(targetPkg)) {
c.markDeleted("Shortcuts can't have null package");
return;
}
@@ -498,7 +498,6 @@ public class ModelWriter {
modelItem.container == Favorites.CONTAINER_HOTSEAT)) {
switch (modelItem.itemType) {
case Favorites.ITEM_TYPE_APPLICATION:
case Favorites.ITEM_TYPE_SHORTCUT:
case Favorites.ITEM_TYPE_DEEP_SHORTCUT:
case Favorites.ITEM_TYPE_FOLDER:
if (!mBgDataModel.workspaceItems.contains(modelItem)) {
@@ -30,7 +30,6 @@ import static com.android.launcher3.LauncherSettings.Favorites.EXTENDED_CONTAINE
import static com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_APPLICATION;
import static com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET;
import static com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT;
import static com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT;
import static com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_TASK;
import static com.android.launcher3.logger.LauncherAtom.ContainerInfo.ContainerCase.CONTAINER_NOT_SET;
import static com.android.launcher3.shortcuts.ShortcutKey.EXTRA_SHORTCUT_ID;
@@ -87,7 +86,6 @@ public class ItemInfo {
/**
* One of {@link Favorites#ITEM_TYPE_APPLICATION},
* {@link Favorites#ITEM_TYPE_SHORTCUT},
* {@link Favorites#ITEM_TYPE_DEEP_SHORTCUT}
* {@link Favorites#ITEM_TYPE_FOLDER},
* {@link Favorites#ITEM_TYPE_APP_PAIR},
@@ -361,13 +359,6 @@ public class ItemInfo {
})
.orElse(LauncherAtom.Shortcut.newBuilder()));
break;
case ITEM_TYPE_SHORTCUT:
itemBuilder
.setShortcut(nullableComponent
.map(component -> LauncherAtom.Shortcut.newBuilder()
.setShortcutName(component.flattenToShortString()))
.orElse(LauncherAtom.Shortcut.newBuilder()));
break;
case ITEM_TYPE_APPWIDGET:
itemBuilder
.setWidget(nullableComponent
@@ -96,7 +96,7 @@ public class WorkspaceItemInfo extends ItemInfoWithIcon {
public WorkspaceItemInfo() {
itemType = LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT;
itemType = LauncherSettings.Favorites.ITEM_TYPE_APPLICATION;
}
public WorkspaceItemInfo(WorkspaceItemInfo info) {
@@ -205,8 +205,8 @@ public class WorkspaceItemInfo extends ItemInfoWithIcon {
@Override
public ComponentName getTargetComponent() {
ComponentName cn = super.getTargetComponent();
if (cn == null && (itemType == Favorites.ITEM_TYPE_SHORTCUT || hasStatusFlag(
FLAG_SUPPORTS_WEB_UI | FLAG_AUTOINSTALL_ICON | FLAG_RESTORED_ICON))) {
if (cn == null && hasStatusFlag(
FLAG_SUPPORTS_WEB_UI | FLAG_AUTOINSTALL_ICON | FLAG_RESTORED_ICON)) {
// Legacy shortcuts and promise icons with web UI may not have a componentName but just
// a packageName. In that case create a empty componentName instead of adding additional
// check everywhere.
@@ -72,7 +72,7 @@ public abstract class ShortcutConfigActivityInfo implements ComponentWithLabelAn
}
public int getItemType() {
return LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT;
return LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT;
}
@Override
@@ -250,6 +250,11 @@ public class IntArray implements Cloneable, Iterable<Integer> {
return b.toString();
}
@Override
public String toString() {
return "IntArray [" + toConcatString() + "]";
}
public static IntArray fromConcatString(String concatString) {
StringTokenizer tokenizer = new StringTokenizer(concatString, ",");
int[] array = new int[tokenizer.countTokens()];
@@ -48,8 +48,8 @@ public class MainThreadInitializedObject<T> {
}
public T get(Context context) {
if (context instanceof SandboxContext) {
return ((SandboxContext) context).getObject(this, mProvider);
if (context instanceof SandboxContext sc) {
return sc.getObject(this);
}
if (mValue == null) {
@@ -131,24 +131,22 @@ public class MainThreadInitializedObject<T> {
* Find a cached object from mObjectMap if we have already created one. If not, generate
* an object using the provider.
*/
protected <T> T getObject(MainThreadInitializedObject<T> object,
ObjectProvider<T> provider) {
protected <T> T getObject(MainThreadInitializedObject<T> object) {
synchronized (mDestroyLock) {
if (mDestroyed) {
Log.e(TAG, "Static object access with a destroyed context");
}
T t = (T) mObjectMap.get(object);
if (t != null) {
return t;
}
if (Looper.myLooper() == Looper.getMainLooper()) {
t = createObject(provider);
t = createObject(object);
// Check if we've explicitly allowed the object or if it's a SafeCloseable,
// it will get destroyed in onDestroy()
if (!mAllowedObjects.contains(object) && !(t instanceof SafeCloseable)) {
throw new IllegalStateException(
"Leaking unknown objects " + object + " " + provider + " " + t);
throw new IllegalStateException("Leaking unknown objects "
+ object + " " + object.mProvider + " " + t);
}
mObjectMap.put(object, t);
mOrderedObjects.add(t);
@@ -157,15 +155,15 @@ public class MainThreadInitializedObject<T> {
}
try {
return MAIN_EXECUTOR.submit(() -> getObject(object, provider)).get();
return MAIN_EXECUTOR.submit(() -> getObject(object)).get();
} catch (InterruptedException | ExecutionException e) {
throw new RuntimeException(e);
}
}
@UiThread
protected <T> T createObject(ObjectProvider<T> provider) {
return provider.get(this);
protected <T> T createObject(MainThreadInitializedObject<T> object) {
return object.mProvider.get(this);
}
}
}
@@ -332,6 +332,12 @@ public interface ActivityContext {
return null;
}
boolean isShortcut = (item instanceof WorkspaceItemInfo)
&& item.itemType == LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT
&& !((WorkspaceItemInfo) item).isPromise();
if (isShortcut && GO_DISABLE_WIDGETS) {
return null;
}
ActivityOptionsWrapper options = v != null ? getActivityLaunchOptions(v, item)
: makeDefaultActivityOptions(item != null && item.animationType == DEFAULT_NO_ICON
? SPLASH_SCREEN_STYLE_SOLID_COLOR : -1 /* SPLASH_SCREEN_STYLE_UNDEFINED */);
@@ -343,13 +349,11 @@ public interface ActivityContext {
intent.setSourceBounds(Utilities.getViewBounds(v));
}
try {
boolean isShortcut = (item instanceof WorkspaceItemInfo)
&& (item.itemType == LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT
|| item.itemType == LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT)
&& !((WorkspaceItemInfo) item).isPromise();
if (isShortcut) {
// Shortcuts need some special checks due to legacy reasons.
startShortcutIntentSafely(intent, optsBundle, item);
String id = ((WorkspaceItemInfo) item).getDeepShortcutId();
String packageName = intent.getPackage();
((Context) this).getSystemService(LauncherApps.class).startShortcut(
packageName, id, intent.getSourceBounds(), optsBundle, user);
} else if (user == null || user.equals(Process.myUserHandle())) {
// Could be launching some bookkeeping activity
context.startActivity(intent, optsBundle);
@@ -424,55 +428,6 @@ public interface ActivityContext {
return new ActivityOptionsWrapper(options, new RunnableList());
}
/**
* Safely launches an intent for a shortcut.
*
* @param intent Intent to start.
* @param optsBundle Optional launch arguments.
* @param info Shortcut information.
*/
default void startShortcutIntentSafely(Intent intent, Bundle optsBundle, ItemInfo info) {
try {
StrictMode.VmPolicy oldPolicy = StrictMode.getVmPolicy();
try {
// Temporarily disable deathPenalty on all default checks. For eg, shortcuts
// containing file Uri's would cause a crash as penaltyDeathOnFileUriExposure
// is enabled by default on NYC.
StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder().detectAll()
.penaltyLog().build());
if (info.itemType == LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT) {
String id = ((WorkspaceItemInfo) info).getDeepShortcutId();
String packageName = intent.getPackage();
startShortcut(packageName, id, intent.getSourceBounds(), optsBundle, info.user);
} else {
// Could be launching some bookkeeping activity
((Context) this).startActivity(intent, optsBundle);
}
} finally {
StrictMode.setVmPolicy(oldPolicy);
}
} catch (SecurityException e) {
throw e;
}
}
/**
* A wrapper around the platform method with Launcher specific checks.
*/
default void startShortcut(String packageName, String id, Rect sourceBounds,
Bundle startActivityOptions, UserHandle user) {
if (GO_DISABLE_WIDGETS) {
return;
}
try {
((Context) this).getSystemService(LauncherApps.class).startShortcut(packageName, id,
sourceBounds, startActivityOptions, user);
} catch (SecurityException | IllegalStateException e) {
Log.e(TAG, "Failed to start shortcut", e);
}
}
default CellPosMapper getCellPosMapper() {
return CellPosMapper.DEFAULT;
}
@@ -290,7 +290,6 @@ public class OptionsPopupView extends ArrowPopup<Launcher>
static WorkspaceItemInfo placeholderInfo(Intent intent) {
WorkspaceItemInfo placeholderInfo = new WorkspaceItemInfo();
placeholderInfo.intent = intent;
placeholderInfo.itemType = LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT;
placeholderInfo.container = LauncherSettings.Favorites.CONTAINER_SETTINGS;
return placeholderInfo;
}