Using resource override instead of code-swap for ApiWrapper
Bug: 330920490
Flag: None
Test: Presubmit
Change-Id: Iac19f32e64d2c76ed5b4f8592943ee4ae7af51b5
diff --git a/quickstep/res/values/config.xml b/quickstep/res/values/config.xml
index 31d4071..c4ee11a 100644
--- a/quickstep/res/values/config.xml
+++ b/quickstep/res/values/config.xml
@@ -38,6 +38,7 @@
<string name="nav_handle_long_press_handler_class" translatable="false"></string>
<string name="assist_utils_class" translatable="false"></string>
<string name="assist_state_manager_class" translatable="false"></string>
+ <string name="api_wrapper_class" translatable="false">com.android.launcher3.uioverrides.SystemApiWrapper</string>
<!-- The number of thumbnails and icons to keep in the cache. The thumbnail cache size also
determines how many thumbnails will be fetched in the background. -->
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
index 390dec9..98ce2ed 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
@@ -113,8 +113,8 @@
import com.android.launcher3.testing.shared.TestProtocol;
import com.android.launcher3.touch.ItemClickHandler;
import com.android.launcher3.touch.ItemClickHandler.ItemClickProxy;
-import com.android.launcher3.uioverrides.ApiWrapper;
import com.android.launcher3.util.ActivityOptionsWrapper;
+import com.android.launcher3.util.ApiWrapper;
import com.android.launcher3.util.ComponentKey;
import com.android.launcher3.util.DisplayController;
import com.android.launcher3.util.Executors;
@@ -1120,7 +1120,7 @@
} else if (info.isPromise()) {
TestLogging.recordEvent(
TestProtocol.SEQUENCE_MAIN, "start: taskbarPromiseIcon");
- intent = ApiWrapper.getAppMarketActivityIntent(this,
+ intent = ApiWrapper.INSTANCE.get(this).getAppMarketActivityIntent(
info.getTargetPackage(), Process.myUserHandle());
startActivity(intent);
diff --git a/quickstep/src/com/android/launcher3/uioverrides/ApiWrapper.java b/quickstep/src/com/android/launcher3/uioverrides/ApiWrapper.java
deleted file mode 100644
index 873dea8..0000000
--- a/quickstep/src/com/android/launcher3/uioverrides/ApiWrapper.java
+++ /dev/null
@@ -1,201 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.launcher3.uioverrides;
-
-import android.app.ActivityOptions;
-import android.app.PendingIntent;
-import android.app.Person;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentSender;
-import android.content.pm.ActivityInfo;
-import android.content.pm.LauncherActivityInfo;
-import android.content.pm.LauncherApps;
-import android.content.pm.LauncherUserInfo;
-import android.content.pm.ShortcutInfo;
-import android.graphics.drawable.ColorDrawable;
-import android.net.Uri;
-import android.os.UserHandle;
-import android.os.UserManager;
-import android.util.ArrayMap;
-import android.window.RemoteTransition;
-
-import com.android.launcher3.Flags;
-import com.android.launcher3.Utilities;
-import com.android.launcher3.proxy.ProxyActivityStarter;
-import com.android.launcher3.util.StartActivityParams;
-import com.android.launcher3.util.UserIconInfo;
-import com.android.quickstep.util.FadeOutRemoteTransition;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-
-/**
- * A wrapper for the hidden API calls
- */
-public class ApiWrapper {
-
- public static final boolean TASKBAR_DRAWN_IN_PROCESS = true;
-
- public static Person[] getPersons(ShortcutInfo si) {
- Person[] persons = si.getPersons();
- return persons == null ? Utilities.EMPTY_PERSON_ARRAY : persons;
- }
-
- public static Map<String, LauncherActivityInfo> getActivityOverrides(Context context) {
- return context.getSystemService(LauncherApps.class).getActivityOverrides();
- }
-
- /**
- * Creates an ActivityOptions to play fade-out animation on closing targets
- */
- public static ActivityOptions createFadeOutAnimOptions(Context context) {
- ActivityOptions options = ActivityOptions.makeBasic();
- options.setRemoteTransition(new RemoteTransition(new FadeOutRemoteTransition()));
- return options;
- }
-
- /**
- * Returns a map of all users on the device to their corresponding UI properties
- */
- public static Map<UserHandle, UserIconInfo> queryAllUsers(Context context) {
- UserManager um = context.getSystemService(UserManager.class);
- Map<UserHandle, UserIconInfo> users = new ArrayMap<>();
- List<UserHandle> usersActual = um.getUserProfiles();
- if (usersActual != null) {
- for (UserHandle user : usersActual) {
- if (android.os.Flags.allowPrivateProfile() && Flags.enablePrivateSpace()) {
- LauncherApps launcherApps = context.getSystemService(LauncherApps.class);
- LauncherUserInfo launcherUserInfo = launcherApps.getLauncherUserInfo(user);
- if (launcherUserInfo == null) {
- continue;
- }
- // UserTypes not supported in Launcher are deemed to be the current
- // Foreground User.
- int userType = switch (launcherUserInfo.getUserType()) {
- case UserManager.USER_TYPE_PROFILE_MANAGED -> UserIconInfo.TYPE_WORK;
- case UserManager.USER_TYPE_PROFILE_CLONE -> UserIconInfo.TYPE_CLONED;
- case UserManager.USER_TYPE_PROFILE_PRIVATE -> UserIconInfo.TYPE_PRIVATE;
- default -> UserIconInfo.TYPE_MAIN;
- };
- long serial = launcherUserInfo.getUserSerialNumber();
- users.put(user, new UserIconInfo(user, userType, serial));
- } else {
- long serial = um.getSerialNumberForUser(user);
-
- // Simple check to check if the provided user is work profile
- // TODO: Migrate to a better platform API
- NoopDrawable d = new NoopDrawable();
- boolean isWork = (d != context.getPackageManager().getUserBadgedIcon(d, user));
- UserIconInfo info = new UserIconInfo(
- user,
- isWork ? UserIconInfo.TYPE_WORK : UserIconInfo.TYPE_MAIN,
- serial);
- users.put(user, info);
- }
- }
- }
- return users;
- }
-
- /**
- * Returns the list of the system packages that are installed at user creation.
- * An empty list denotes that all system packages are installed for that user at creation.
- */
- public static List<String> getPreInstalledSystemPackages(Context context, UserHandle user) {
- LauncherApps launcherApps = context.getSystemService(LauncherApps.class);
- if (android.os.Flags.allowPrivateProfile() && Flags.enablePrivateSpace()
- && Flags.privateSpaceSysAppsSeparation()) {
- return launcherApps.getPreInstalledSystemPackages(user);
- } else {
- return new ArrayList<>();
- }
- }
-
- /**
- * Returns an intent which can be used to start the App Market activity (Installer
- * Activity).
- */
- public static Intent getAppMarketActivityIntent(Context context, String packageName,
- UserHandle user) {
- LauncherApps launcherApps = context.getSystemService(LauncherApps.class);
- if (android.os.Flags.allowPrivateProfile()
- && Flags.enablePrivateSpace()
- && (Flags.privateSpaceAppInstallerButton()
- || Flags.enablePrivateSpaceInstallShortcut())) {
- StartActivityParams params = new StartActivityParams((PendingIntent) null, 0);
- params.intentSender = launcherApps.getAppMarketActivityIntent(packageName, user);
- ActivityOptions options = ActivityOptions.makeBasic()
- .setPendingIntentBackgroundActivityStartMode(ActivityOptions
- .MODE_BACKGROUND_ACTIVITY_START_ALLOWED);
- params.options = options.toBundle();
- params.requireActivityResult = false;
- return ProxyActivityStarter.getLaunchIntent(context, params);
- } else {
- return new Intent(Intent.ACTION_VIEW)
- .setData(new Uri.Builder()
- .scheme("market")
- .authority("details")
- .appendQueryParameter("id", packageName)
- .build())
- .putExtra(Intent.EXTRA_REFERRER, new Uri.Builder().scheme("android-app")
- .authority(context.getPackageName()).build());
- }
- }
-
- /**
- * Returns an intent which can be used to open Private Space Settings.
- */
- public static Intent getPrivateSpaceSettingsIntent(Context context) {
- if (android.os.Flags.allowPrivateProfile() && Flags.enablePrivateSpace()) {
- LauncherApps launcherApps = context.getSystemService(LauncherApps.class);
- IntentSender intentSender = launcherApps.getPrivateSpaceSettingsIntent();
- if (intentSender == null) {
- return null;
- }
- StartActivityParams params = new StartActivityParams((PendingIntent) null, 0);
- params.intentSender = intentSender;
- ActivityOptions options = ActivityOptions.makeBasic()
- .setPendingIntentBackgroundActivityStartMode(ActivityOptions
- .MODE_BACKGROUND_ACTIVITY_START_ALLOWED);
- params.options = options.toBundle();
- params.requireActivityResult = false;
- return ProxyActivityStarter.getLaunchIntent(context, params);
- }
- return null;
- }
-
- /**
- * Checks if an activity is flagged as non-resizeable.
- */
- public static boolean isNonResizeableActivity(LauncherActivityInfo lai) {
- return lai.getActivityInfo().resizeMode == ActivityInfo.RESIZE_MODE_UNRESIZEABLE;
- }
-
- private static class NoopDrawable extends ColorDrawable {
- @Override
- public int getIntrinsicHeight() {
- return 1;
- }
-
- @Override
- public int getIntrinsicWidth() {
- return 1;
- }
- }
-}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/SystemApiWrapper.kt b/quickstep/src/com/android/launcher3/uioverrides/SystemApiWrapper.kt
new file mode 100644
index 0000000..535b4c2
--- /dev/null
+++ b/quickstep/src/com/android/launcher3/uioverrides/SystemApiWrapper.kt
@@ -0,0 +1,133 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.launcher3.uioverrides
+
+import android.app.ActivityOptions
+import android.app.PendingIntent
+import android.content.Context
+import android.content.Intent
+import android.content.pm.ActivityInfo
+import android.content.pm.LauncherActivityInfo
+import android.content.pm.LauncherApps
+import android.content.pm.ShortcutInfo
+import android.os.Flags.allowPrivateProfile
+import android.os.UserHandle
+import android.os.UserManager
+import android.util.ArrayMap
+import android.window.RemoteTransition
+import com.android.launcher3.Flags.enablePrivateSpace
+import com.android.launcher3.Flags.enablePrivateSpaceInstallShortcut
+import com.android.launcher3.Flags.privateSpaceAppInstallerButton
+import com.android.launcher3.Flags.privateSpaceSysAppsSeparation
+import com.android.launcher3.Utilities
+import com.android.launcher3.proxy.ProxyActivityStarter
+import com.android.launcher3.util.ApiWrapper
+import com.android.launcher3.util.StartActivityParams
+import com.android.launcher3.util.UserIconInfo
+import com.android.quickstep.util.FadeOutRemoteTransition
+
+/** A wrapper for the hidden API calls */
+class SystemApiWrapper(context: Context?) : ApiWrapper(context) {
+
+ override fun getPersons(si: ShortcutInfo) = si.persons ?: Utilities.EMPTY_PERSON_ARRAY
+
+ override fun getActivityOverrides(): Map<String, LauncherActivityInfo> =
+ mContext.getSystemService(LauncherApps::class.java)!!.activityOverrides
+
+ override fun createFadeOutAnimOptions(): ActivityOptions =
+ ActivityOptions.makeBasic().apply {
+ remoteTransition = RemoteTransition(FadeOutRemoteTransition())
+ }
+
+ override fun queryAllUsers(): Map<UserHandle, UserIconInfo> {
+ if (!allowPrivateProfile() || !enablePrivateSpace()) {
+ return super.queryAllUsers()
+ }
+ val users = ArrayMap<UserHandle, UserIconInfo>()
+ mContext.getSystemService(UserManager::class.java)!!.userProfiles?.forEach { user ->
+ mContext.getSystemService(LauncherApps::class.java)!!.getLauncherUserInfo(user)?.apply {
+ users[user] =
+ UserIconInfo(
+ user,
+ when (userType) {
+ UserManager.USER_TYPE_PROFILE_MANAGED -> UserIconInfo.TYPE_WORK
+ UserManager.USER_TYPE_PROFILE_CLONE -> UserIconInfo.TYPE_CLONED
+ UserManager.USER_TYPE_PROFILE_PRIVATE -> UserIconInfo.TYPE_PRIVATE
+ else -> UserIconInfo.TYPE_MAIN
+ },
+ userSerialNumber.toLong()
+ )
+ }
+ }
+ return users
+ }
+
+ override fun getPreInstalledSystemPackages(user: UserHandle): List<String> =
+ if (allowPrivateProfile() && enablePrivateSpace() && privateSpaceSysAppsSeparation())
+ mContext
+ .getSystemService(LauncherApps::class.java)!!
+ .getPreInstalledSystemPackages(user)
+ else ArrayList()
+
+ override fun getAppMarketActivityIntent(packageName: String, user: UserHandle): Intent =
+ if (
+ allowPrivateProfile() &&
+ enablePrivateSpace() &&
+ (privateSpaceAppInstallerButton() || enablePrivateSpaceInstallShortcut())
+ )
+ ProxyActivityStarter.getLaunchIntent(
+ mContext,
+ StartActivityParams(null as PendingIntent?, 0).apply {
+ intentSender =
+ mContext
+ .getSystemService(LauncherApps::class.java)!!
+ .getAppMarketActivityIntent(packageName, user)
+ options =
+ ActivityOptions.makeBasic()
+ .setPendingIntentBackgroundActivityStartMode(
+ ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED
+ )
+ .toBundle()
+ requireActivityResult = false
+ }
+ )
+ else super.getAppMarketActivityIntent(packageName, user)
+
+ /** Returns an intent which can be used to open Private Space Settings. */
+ override fun getPrivateSpaceSettingsIntent(): Intent? =
+ if (allowPrivateProfile() && enablePrivateSpace())
+ ProxyActivityStarter.getLaunchIntent(
+ mContext,
+ StartActivityParams(null as PendingIntent?, 0).apply {
+ intentSender =
+ mContext
+ .getSystemService(LauncherApps::class.java)
+ ?.privateSpaceSettingsIntent
+ ?: return null
+ options =
+ ActivityOptions.makeBasic()
+ .setPendingIntentBackgroundActivityStartMode(
+ ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED
+ )
+ .toBundle()
+ requireActivityResult = false
+ }
+ )
+ else null
+
+ override fun isNonResizeableActivity(lai: LauncherActivityInfo) =
+ lai.activityInfo.resizeMode == ActivityInfo.RESIZE_MODE_UNRESIZEABLE
+}
diff --git a/res/values/config.xml b/res/values/config.xml
index 599584b..f820e76 100644
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -78,6 +78,7 @@
<string name="launcher_restore_event_logger_class" translatable="false"></string>
<!-- Used for determining category of a widget presented in widget recommendations. -->
<string name="widget_recommendation_category_provider_class" translatable="false"></string>
+ <string name="api_wrapper_class" translatable="false"></string>
<!-- Default packages -->
<string name="wallpaper_picker_package" translatable="false"></string>
diff --git a/src/com/android/launcher3/AutoInstallsLayout.java b/src/com/android/launcher3/AutoInstallsLayout.java
index c7cdfa8..cf86528 100644
--- a/src/com/android/launcher3/AutoInstallsLayout.java
+++ b/src/com/android/launcher3/AutoInstallsLayout.java
@@ -52,7 +52,7 @@
import com.android.launcher3.pm.UserCache;
import com.android.launcher3.qsb.QsbContainerView;
import com.android.launcher3.shortcuts.ShortcutKey;
-import com.android.launcher3.uioverrides.ApiWrapper;
+import com.android.launcher3.util.ApiWrapper;
import com.android.launcher3.util.IntArray;
import com.android.launcher3.util.Partner;
import com.android.launcher3.util.Thunk;
@@ -203,7 +203,7 @@
mIdp = LauncherAppState.getIDP(context);
mRowCount = mIdp.numRows;
mColumnCount = mIdp.numColumns;
- mActivityOverride = ApiWrapper.getActivityOverrides(context);
+ mActivityOverride = ApiWrapper.INSTANCE.get(context).getActivityOverrides();
}
/**
diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java
index 3ddc7aa..6cb33a8 100644
--- a/src/com/android/launcher3/DeviceProfile.java
+++ b/src/com/android/launcher3/DeviceProfile.java
@@ -63,13 +63,13 @@
import com.android.launcher3.responsive.ResponsiveSpec.Companion.ResponsiveSpecType;
import com.android.launcher3.responsive.ResponsiveSpec.DimensionType;
import com.android.launcher3.responsive.ResponsiveSpecsProvider;
-import com.android.launcher3.uioverrides.ApiWrapper;
import com.android.launcher3.util.CellContentDimensions;
import com.android.launcher3.util.DisplayController;
import com.android.launcher3.util.DisplayController.Info;
import com.android.launcher3.util.IconSizeSteps;
import com.android.launcher3.util.ResourceHelper;
import com.android.launcher3.util.WindowBounds;
+import com.android.launcher3.util.window.WindowManagerProxy;
import java.io.PrintWriter;
import java.util.Locale;
@@ -350,7 +350,8 @@
isTablet = info.isTablet(windowBounds);
isPhone = !isTablet;
isTwoPanels = isTablet && isMultiDisplay;
- isTaskbarPresent = isTablet && ApiWrapper.TASKBAR_DRAWN_IN_PROCESS;
+ isTaskbarPresent = isTablet
+ && WindowManagerProxy.INSTANCE.get(context).isTaskbarDrawnInProcess();
// Some more constants.
context = getContext(context, info, isVerticalBarLayout() || (isTablet && isLandscape)
diff --git a/src/com/android/launcher3/allapps/PrivateProfileManager.java b/src/com/android/launcher3/allapps/PrivateProfileManager.java
index be120cc..1def8a3 100644
--- a/src/com/android/launcher3/allapps/PrivateProfileManager.java
+++ b/src/com/android/launcher3/allapps/PrivateProfileManager.java
@@ -72,7 +72,7 @@
import com.android.launcher3.model.data.AppInfo;
import com.android.launcher3.model.data.PrivateSpaceInstallAppButtonInfo;
import com.android.launcher3.pm.UserCache;
-import com.android.launcher3.uioverrides.ApiWrapper;
+import com.android.launcher3.util.ApiWrapper;
import com.android.launcher3.util.Preconditions;
import com.android.launcher3.util.SettingsCache;
import com.android.launcher3.views.ActivityContext;
@@ -122,7 +122,9 @@
super(userManager, statsLogManager, userCache);
mAllApps = allApps;
mPrivateProfileMatcher = (user) -> userCache.getUserInfo(user).isPrivate();
- UI_HELPER_EXECUTOR.post(this::initializeInBackgroundThread);
+
+ Context appContext = allApps.getContext().getApplicationContext();
+ UI_HELPER_EXECUTOR.post(() -> initializeInBackgroundThread(appContext));
mPsHeaderHeight = mAllApps.getContext().getResources().getDimensionPixelSize(
R.dimen.ps_header_height);
}
@@ -187,7 +189,7 @@
/** Whether private profile should be hidden on Launcher. */
public boolean isPrivateSpaceHidden() {
return getCurrentState() == STATE_DISABLED && SettingsCache.INSTANCE
- .get(mAllApps.mActivityContext).getValue(PRIVATE_SPACE_HIDE_WHEN_LOCKED_URI, 0);
+ .get(mAllApps.getContext()).getValue(PRIVATE_SPACE_HIDE_WHEN_LOCKED_URI, 0);
}
/**
@@ -215,8 +217,8 @@
/** Opens the Private Space Settings Page. */
public void openPrivateSpaceSettings() {
if (mPrivateSpaceSettingsAvailable) {
- mAllApps.getContext()
- .startActivity(ApiWrapper.getPrivateSpaceSettingsIntent(mAllApps.getContext()));
+ mAllApps.getContext().startActivity(
+ ApiWrapper.INSTANCE.get(mAllApps.getContext()).getPrivateSpaceSettingsIntent());
}
}
@@ -239,33 +241,17 @@
* This case should still be ok, as locking the Private Space container and unlocking it,
* reloads the values, fixing the incorrect UI.
*/
- private void initializeInBackgroundThread() {
+ private void initializeInBackgroundThread(Context appContext) {
Preconditions.assertNonUiThread();
- setPreInstalledSystemPackages();
- setAppInstallerIntent();
- initializePrivateSpaceSettingsState();
- }
-
- private void initializePrivateSpaceSettingsState() {
- Preconditions.assertNonUiThread();
- Intent psSettingsIntent = ApiWrapper.getPrivateSpaceSettingsIntent(mAllApps.getContext());
- setPrivateSpaceSettingsAvailable(psSettingsIntent != null);
- }
-
- private void setPreInstalledSystemPackages() {
- Preconditions.assertNonUiThread();
- if (getProfileUser() != null) {
- mPreInstalledSystemPackages = new HashSet<>(ApiWrapper
- .getPreInstalledSystemPackages(mAllApps.getContext(), getProfileUser()));
+ ApiWrapper apiWrapper = ApiWrapper.INSTANCE.get(appContext);
+ UserHandle profileUser = getProfileUser();
+ if (profileUser != null) {
+ mPreInstalledSystemPackages = new HashSet<>(
+ apiWrapper.getPreInstalledSystemPackages(profileUser));
+ mAppInstallerIntent = apiWrapper
+ .getAppMarketActivityIntent(BuildConfig.APPLICATION_ID, profileUser);
}
- }
-
- private void setAppInstallerIntent() {
- Preconditions.assertNonUiThread();
- if (getProfileUser() != null) {
- mAppInstallerIntent = ApiWrapper.getAppMarketActivityIntent(mAllApps.getContext(),
- BuildConfig.APPLICATION_ID, getProfileUser());
- }
+ setPrivateSpaceSettingsAvailable(apiWrapper.getPrivateSpaceSettingsIntent() != null);
}
@VisibleForTesting
diff --git a/src/com/android/launcher3/dragndrop/AddItemActivity.java b/src/com/android/launcher3/dragndrop/AddItemActivity.java
index 29aa216..05fdcef 100644
--- a/src/com/android/launcher3/dragndrop/AddItemActivity.java
+++ b/src/com/android/launcher3/dragndrop/AddItemActivity.java
@@ -67,7 +67,7 @@
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.model.data.PackageItemInfo;
import com.android.launcher3.pm.PinRequestHelper;
-import com.android.launcher3.uioverrides.ApiWrapper;
+import com.android.launcher3.util.ApiWrapper;
import com.android.launcher3.util.PackageManagerHelper;
import com.android.launcher3.util.SystemUiController;
import com.android.launcher3.views.AbstractSlideInView;
@@ -259,7 +259,8 @@
.setPackage(getPackageName())
.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
Launcher.ACTIVITY_TRACKER.registerCallback(listener, "AddItemActivity.onLongClick");
- startActivity(homeIntent, ApiWrapper.createFadeOutAnimOptions(this).toBundle());
+ startActivity(homeIntent,
+ ApiWrapper.INSTANCE.get(this).createFadeOutAnimOptions().toBundle());
logCommand(LAUNCHER_ADD_EXTERNAL_ITEM_DRAGGED);
mFinishOnPause = true;
return false;
diff --git a/src/com/android/launcher3/model/PackageUpdatedTask.java b/src/com/android/launcher3/model/PackageUpdatedTask.java
index ea1ae2e..e42e679 100644
--- a/src/com/android/launcher3/model/PackageUpdatedTask.java
+++ b/src/com/android/launcher3/model/PackageUpdatedTask.java
@@ -48,7 +48,7 @@
import com.android.launcher3.pm.PackageInstallInfo;
import com.android.launcher3.pm.UserCache;
import com.android.launcher3.shortcuts.ShortcutRequest;
-import com.android.launcher3.uioverrides.ApiWrapper;
+import com.android.launcher3.util.ApiWrapper;
import com.android.launcher3.util.FlagOp;
import com.android.launcher3.util.IntSet;
import com.android.launcher3.util.ItemInfoMatcher;
@@ -286,7 +286,7 @@
}
if (si.itemType == Favorites.ITEM_TYPE_APPLICATION) {
if (activities != null && !activities.isEmpty()) {
- si.status = ApiWrapper
+ si.status = ApiWrapper.INSTANCE.get(context)
.isNonResizeableActivity(activities.get(0))
? si.status | WorkspaceItemInfo.FLAG_NON_RESIZEABLE
: si.status & ~WorkspaceItemInfo.FLAG_NON_RESIZEABLE;
diff --git a/src/com/android/launcher3/model/WorkspaceItemProcessor.kt b/src/com/android/launcher3/model/WorkspaceItemProcessor.kt
index a900d1f..ff95bbb 100644
--- a/src/com/android/launcher3/model/WorkspaceItemProcessor.kt
+++ b/src/com/android/launcher3/model/WorkspaceItemProcessor.kt
@@ -41,7 +41,7 @@
import com.android.launcher3.model.data.WorkspaceItemInfo
import com.android.launcher3.pm.PackageInstallInfo
import com.android.launcher3.shortcuts.ShortcutKey
-import com.android.launcher3.uioverrides.ApiWrapper
+import com.android.launcher3.util.ApiWrapper
import com.android.launcher3.util.ComponentKey
import com.android.launcher3.util.PackageManagerHelper
import com.android.launcher3.util.PackageUserKey
@@ -325,7 +325,7 @@
}
val activityInfo = c.launcherActivityInfo
if (activityInfo != null) {
- if (ApiWrapper.isNonResizeableActivity(activityInfo)) {
+ if (ApiWrapper.INSTANCE.get(app.context).isNonResizeableActivity(activityInfo)) {
info.status = info.status or WorkspaceItemInfo.FLAG_NON_RESIZEABLE
}
info.setProgressLevel(
diff --git a/src/com/android/launcher3/model/data/ItemInfoWithIcon.java b/src/com/android/launcher3/model/data/ItemInfoWithIcon.java
index be3aa10..faeed29 100644
--- a/src/com/android/launcher3/model/data/ItemInfoWithIcon.java
+++ b/src/com/android/launcher3/model/data/ItemInfoWithIcon.java
@@ -28,7 +28,7 @@
import com.android.launcher3.icons.FastBitmapDrawable;
import com.android.launcher3.logging.FileLog;
import com.android.launcher3.pm.PackageInstallInfo;
-import com.android.launcher3.uioverrides.ApiWrapper;
+import com.android.launcher3.util.ApiWrapper;
/**
* Represents an ItemInfo which also holds an icon.
@@ -251,8 +251,8 @@
String targetPackage = getTargetPackage();
return targetPackage != null
- ? ApiWrapper.getAppMarketActivityIntent(
- context, targetPackage, Process.myUserHandle())
+ ? ApiWrapper.INSTANCE.get(context).getAppMarketActivityIntent(
+ targetPackage, Process.myUserHandle())
: null;
}
diff --git a/src/com/android/launcher3/model/data/WorkspaceItemInfo.java b/src/com/android/launcher3/model/data/WorkspaceItemInfo.java
index 9917ad7..5ae7003 100644
--- a/src/com/android/launcher3/model/data/WorkspaceItemInfo.java
+++ b/src/com/android/launcher3/model/data/WorkspaceItemInfo.java
@@ -32,7 +32,7 @@
import com.android.launcher3.icons.IconCache;
import com.android.launcher3.pm.UserCache;
import com.android.launcher3.shortcuts.ShortcutKey;
-import com.android.launcher3.uioverrides.ApiWrapper;
+import com.android.launcher3.util.ApiWrapper;
import com.android.launcher3.util.ContentWriter;
import java.util.Arrays;
@@ -201,7 +201,7 @@
runtimeStatusFlags &= ~FLAG_DISABLED_VERSION_LOWER;
}
- Person[] persons = ApiWrapper.getPersons(shortcutInfo);
+ Person[] persons = ApiWrapper.INSTANCE.get(context).getPersons(shortcutInfo);
personKeys = persons.length == 0 ? Utilities.EMPTY_STRING_ARRAY
: Arrays.stream(persons).map(Person::getKey).sorted().toArray(String[]::new);
}
diff --git a/src/com/android/launcher3/pm/UserCache.java b/src/com/android/launcher3/pm/UserCache.java
index 032de31..185e0b5 100644
--- a/src/com/android/launcher3/pm/UserCache.java
+++ b/src/com/android/launcher3/pm/UserCache.java
@@ -17,7 +17,6 @@
package com.android.launcher3.pm;
import static com.android.launcher3.Utilities.ATLEAST_U;
-import static com.android.launcher3.uioverrides.ApiWrapper.queryAllUsers;
import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
import android.content.Context;
@@ -34,6 +33,7 @@
import com.android.launcher3.icons.BitmapInfo;
import com.android.launcher3.icons.UserBadgeDrawable;
+import com.android.launcher3.util.ApiWrapper;
import com.android.launcher3.util.FlagOp;
import com.android.launcher3.util.MainThreadInitializedObject;
import com.android.launcher3.util.SafeCloseable;
@@ -119,7 +119,7 @@
@WorkerThread
private void updateCache() {
- mUserToSerialMap = queryAllUsers(mContext);
+ mUserToSerialMap = ApiWrapper.INSTANCE.get(mContext).queryAllUsers();
}
/**
diff --git a/src/com/android/launcher3/popup/SystemShortcut.java b/src/com/android/launcher3/popup/SystemShortcut.java
index 0af7e67..0c5a0ec 100644
--- a/src/com/android/launcher3/popup/SystemShortcut.java
+++ b/src/com/android/launcher3/popup/SystemShortcut.java
@@ -31,7 +31,7 @@
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.model.data.WorkspaceItemInfo;
import com.android.launcher3.pm.UserCache;
-import com.android.launcher3.uioverrides.ApiWrapper;
+import com.android.launcher3.util.ApiWrapper;
import com.android.launcher3.util.ComponentKey;
import com.android.launcher3.util.InstantAppResolver;
import com.android.launcher3.util.PackageManagerHelper;
@@ -259,10 +259,8 @@
@Override
public void onClick(View view) {
Intent intent =
- ApiWrapper.getAppMarketActivityIntent(
- view.getContext(),
- mItemInfo.getTargetComponent().getPackageName(),
- mSpaceUser);
+ ApiWrapper.INSTANCE.get(view.getContext()).getAppMarketActivityIntent(
+ mItemInfo.getTargetComponent().getPackageName(), mSpaceUser);
mTarget.startActivitySafely(view, intent, mItemInfo);
AbstractFloatingView.closeAllOpenViews(mTarget);
mTarget.getStatsLogManager()
@@ -303,9 +301,8 @@
@Override
public void onClick(View view) {
- Intent intent = ApiWrapper.getAppMarketActivityIntent(view.getContext(),
- mItemInfo.getTargetComponent().getPackageName(),
- Process.myUserHandle());
+ Intent intent = ApiWrapper.INSTANCE.get(view.getContext()).getAppMarketActivityIntent(
+ mItemInfo.getTargetComponent().getPackageName(), Process.myUserHandle());
mTarget.startActivitySafely(view, intent, mItemInfo);
AbstractFloatingView.closeAllOpenViews(mTarget);
}
diff --git a/src/com/android/launcher3/provider/RestoreDbTask.java b/src/com/android/launcher3/provider/RestoreDbTask.java
index b4e6365..d702e51 100644
--- a/src/com/android/launcher3/provider/RestoreDbTask.java
+++ b/src/com/android/launcher3/provider/RestoreDbTask.java
@@ -70,7 +70,7 @@
import com.android.launcher3.model.data.WorkspaceItemInfo;
import com.android.launcher3.pm.UserCache;
import com.android.launcher3.provider.LauncherDbUtils.SQLiteTransaction;
-import com.android.launcher3.uioverrides.ApiWrapper;
+import com.android.launcher3.util.ApiWrapper;
import com.android.launcher3.util.ContentWriter;
import com.android.launcher3.util.IntArray;
import com.android.launcher3.util.LogConfig;
@@ -560,9 +560,8 @@
protected static void maybeOverrideShortcuts(Context context, ModelDbController controller,
SQLiteDatabase db, long currentUser) {
- Map<String, LauncherActivityInfo> activityOverrides = ApiWrapper.getActivityOverrides(
- context);
-
+ Map<String, LauncherActivityInfo> activityOverrides =
+ ApiWrapper.INSTANCE.get(context).getActivityOverrides();
if (activityOverrides == null || activityOverrides.isEmpty()) {
return;
}
diff --git a/src/com/android/launcher3/touch/ItemClickHandler.java b/src/com/android/launcher3/touch/ItemClickHandler.java
index 50df775..49ec0cb 100644
--- a/src/com/android/launcher3/touch/ItemClickHandler.java
+++ b/src/com/android/launcher3/touch/ItemClickHandler.java
@@ -63,7 +63,7 @@
import com.android.launcher3.shortcuts.ShortcutKey;
import com.android.launcher3.testing.TestLogging;
import com.android.launcher3.testing.shared.TestProtocol;
-import com.android.launcher3.uioverrides.ApiWrapper;
+import com.android.launcher3.util.ApiWrapper;
import com.android.launcher3.util.ItemInfoMatcher;
import com.android.launcher3.views.FloatingIconView;
import com.android.launcher3.views.Snackbar;
@@ -234,7 +234,7 @@
}
}
// Fallback to using custom market intent.
- Intent intent = ApiWrapper.getAppMarketActivityIntent(launcher,
+ Intent intent = ApiWrapper.INSTANCE.get(launcher).getAppMarketActivityIntent(
packageName, Process.myUserHandle());
launcher.startActivitySafely(v, intent, item);
};
@@ -372,12 +372,12 @@
if (item instanceof ItemInfoWithIcon itemInfoWithIcon) {
if ((itemInfoWithIcon.runtimeStatusFlags
& ItemInfoWithIcon.FLAG_INSTALL_SESSION_ACTIVE) != 0) {
- intent = ApiWrapper.getAppMarketActivityIntent(launcher,
+ intent = ApiWrapper.INSTANCE.get(launcher).getAppMarketActivityIntent(
itemInfoWithIcon.getTargetComponent().getPackageName(),
Process.myUserHandle());
} else if (itemInfoWithIcon.itemType
== LauncherSettings.Favorites.ITEM_TYPE_PRIVATE_SPACE_INSTALL_APP_BUTTON) {
- intent = ApiWrapper.getAppMarketActivityIntent(launcher,
+ intent = ApiWrapper.INSTANCE.get(launcher).getAppMarketActivityIntent(
BuildConfig.APPLICATION_ID,
launcher.getAppsView().getPrivateProfileManager().getProfileUser());
launcher.getStatsLogManager().logger().log(
diff --git a/src_no_quickstep/com/android/launcher3/uioverrides/ApiWrapper.java b/src/com/android/launcher3/util/ApiWrapper.java
similarity index 67%
rename from src_no_quickstep/com/android/launcher3/uioverrides/ApiWrapper.java
rename to src/com/android/launcher3/util/ApiWrapper.java
index 90271c1..6429a43 100644
--- a/src_no_quickstep/com/android/launcher3/uioverrides/ApiWrapper.java
+++ b/src/com/android/launcher3/util/ApiWrapper.java
@@ -14,7 +14,9 @@
* limitations under the License.
*/
-package com.android.launcher3.uioverrides;
+package com.android.launcher3.util;
+
+import static com.android.launcher3.util.MainThreadInitializedObject.forOverride;
import android.app.ActivityOptions;
import android.app.Person;
@@ -28,10 +30,12 @@
import android.os.UserManager;
import android.util.ArrayMap;
-import com.android.launcher3.Utilities;
-import com.android.launcher3.util.UserIconInfo;
+import androidx.annotation.Nullable;
-import java.util.ArrayList;
+import com.android.launcher3.BuildConfig;
+import com.android.launcher3.R;
+import com.android.launcher3.Utilities;
+
import java.util.Collections;
import java.util.List;
import java.util.Map;
@@ -39,30 +43,40 @@
/**
* A wrapper for the hidden API calls
*/
-public class ApiWrapper {
+public class ApiWrapper implements ResourceBasedOverride, SafeCloseable {
- public static final boolean TASKBAR_DRAWN_IN_PROCESS = false;
+ public static final MainThreadInitializedObject<ApiWrapper> INSTANCE =
+ forOverride(ApiWrapper.class, R.string.api_wrapper_class);
- public static Person[] getPersons(ShortcutInfo si) {
+ protected final Context mContext;
+
+ public ApiWrapper(Context context) {
+ mContext = context;
+ }
+
+ /**
+ * Returns the list of persons associated with the provided shortcut info
+ */
+ public Person[] getPersons(ShortcutInfo si) {
return Utilities.EMPTY_PERSON_ARRAY;
}
- public static Map<String, LauncherActivityInfo> getActivityOverrides(Context context) {
+ public Map<String, LauncherActivityInfo> getActivityOverrides() {
return Collections.emptyMap();
}
/**
* Creates an ActivityOptions to play fade-out animation on closing targets
*/
- public static ActivityOptions createFadeOutAnimOptions(Context context) {
- return ActivityOptions.makeCustomAnimation(context, 0, android.R.anim.fade_out);
+ public ActivityOptions createFadeOutAnimOptions() {
+ return ActivityOptions.makeCustomAnimation(mContext, 0, android.R.anim.fade_out);
}
/**
* Returns a map of all users on the device to their corresponding UI properties
*/
- public static Map<UserHandle, UserIconInfo> queryAllUsers(Context context) {
- UserManager um = context.getSystemService(UserManager.class);
+ public Map<UserHandle, UserIconInfo> queryAllUsers() {
+ UserManager um = mContext.getSystemService(UserManager.class);
Map<UserHandle, UserIconInfo> users = new ArrayMap<>();
List<UserHandle> usersActual = um.getUserProfiles();
if (usersActual != null) {
@@ -72,7 +86,7 @@
// Simple check to check if the provided user is work profile
// TODO: Migrate to a better platform API
NoopDrawable d = new NoopDrawable();
- boolean isWork = (d != context.getPackageManager().getUserBadgedIcon(d, user));
+ boolean isWork = (d != mContext.getPackageManager().getUserBadgedIcon(d, user));
UserIconInfo info = new UserIconInfo(
user,
isWork ? UserIconInfo.TYPE_WORK : UserIconInfo.TYPE_MAIN,
@@ -87,16 +101,15 @@
* Returns the list of the system packages that are installed at user creation.
* An empty list denotes that all system packages are installed for that user at creation.
*/
- public static List<String> getPreInstalledSystemPackages(Context context, UserHandle user) {
- return new ArrayList<>();
+ public List<String> getPreInstalledSystemPackages(UserHandle user) {
+ return Collections.emptyList();
}
/**
* Returns an intent which can be used to start the App Market activity (Installer
* Activity).
*/
- public static Intent getAppMarketActivityIntent(Context context, String packageName,
- UserHandle user) {
+ public Intent getAppMarketActivityIntent(String packageName, UserHandle user) {
return new Intent(Intent.ACTION_VIEW)
.setData(new Uri.Builder()
.scheme("market")
@@ -104,24 +117,27 @@
.appendQueryParameter("id", packageName)
.build())
.putExtra(Intent.EXTRA_REFERRER, new Uri.Builder().scheme("android-app")
- .authority(context.getPackageName()).build());
+ .authority(BuildConfig.APPLICATION_ID).build());
}
/**
* Returns an intent which can be used to open Private Space Settings.
*/
- public static Intent getPrivateSpaceSettingsIntent(Context context) {
+ @Nullable
+ public Intent getPrivateSpaceSettingsIntent() {
return null;
}
/**
* Checks if an activity is flagged as non-resizeable.
*/
- public static boolean isNonResizeableActivity(LauncherActivityInfo lai) {
+ public boolean isNonResizeableActivity(LauncherActivityInfo lai) {
// Overridden in quickstep
return false;
}
+ @Override
+ public void close() { }
private static class NoopDrawable extends ColorDrawable {
@Override
diff --git a/src/com/android/launcher3/util/PackageManagerHelper.java b/src/com/android/launcher3/util/PackageManagerHelper.java
index 316506a..6ed875d 100644
--- a/src/com/android/launcher3/util/PackageManagerHelper.java
+++ b/src/com/android/launcher3/util/PackageManagerHelper.java
@@ -16,6 +16,8 @@
package com.android.launcher3.util;
+import static com.android.launcher3.model.data.ItemInfoWithIcon.FLAG_INSTALL_SESSION_ACTIVE;
+
import android.content.ActivityNotFoundException;
import android.content.ComponentName;
import android.content.Context;
@@ -46,7 +48,6 @@
import com.android.launcher3.model.data.ItemInfoWithIcon;
import com.android.launcher3.model.data.LauncherAppWidgetInfo;
import com.android.launcher3.model.data.WorkspaceItemInfo;
-import com.android.launcher3.uioverrides.ApiWrapper;
import java.util.List;
import java.util.Objects;
@@ -169,11 +170,9 @@
* Starts the details activity for {@code info}
*/
public void startDetailsActivityForInfo(ItemInfo info, Rect sourceBounds, Bundle opts) {
- if (info instanceof ItemInfoWithIcon
- && (((ItemInfoWithIcon) info).runtimeStatusFlags
- & ItemInfoWithIcon.FLAG_INSTALL_SESSION_ACTIVE) != 0) {
- ItemInfoWithIcon appInfo = (ItemInfoWithIcon) info;
- mContext.startActivity(ApiWrapper.getAppMarketActivityIntent(mContext,
+ if (info instanceof ItemInfoWithIcon appInfo
+ && (appInfo.runtimeStatusFlags & FLAG_INSTALL_SESSION_ACTIVE) != 0) {
+ mContext.startActivity(ApiWrapper.INSTANCE.get(mContext).getAppMarketActivityIntent(
appInfo.getTargetComponent().getPackageName(), Process.myUserHandle()));
return;
}
diff --git a/src/com/android/launcher3/util/window/WindowManagerProxy.java b/src/com/android/launcher3/util/window/WindowManagerProxy.java
index 4a906d3..998191e 100644
--- a/src/com/android/launcher3/util/window/WindowManagerProxy.java
+++ b/src/com/android/launcher3/util/window/WindowManagerProxy.java
@@ -94,6 +94,13 @@
}
/**
+ * Returns true if taskbar is drawn in process
+ */
+ public boolean isTaskbarDrawnInProcess() {
+ return mTaskbarDrawnInProcess;
+ }
+
+ /**
* Returns a map of normalized info of internal displays to estimated window bounds
* for that display
*/
diff --git a/tests/src/com/android/launcher3/AbstractDeviceProfileTest.kt b/tests/src/com/android/launcher3/AbstractDeviceProfileTest.kt
index ffcf83f..577334b 100644
--- a/tests/src/com/android/launcher3/AbstractDeviceProfileTest.kt
+++ b/tests/src/com/android/launcher3/AbstractDeviceProfileTest.kt
@@ -38,17 +38,18 @@
import com.android.launcher3.util.window.CachedDisplayInfo
import com.android.launcher3.util.window.WindowManagerProxy
import com.google.common.truth.Truth
-import org.junit.Rule
-import org.mockito.kotlin.any
-import org.mockito.kotlin.mock
-import org.mockito.kotlin.spy
-import org.mockito.kotlin.whenever
import java.io.BufferedReader
import java.io.File
import java.io.PrintWriter
import java.io.StringWriter
import kotlin.math.max
import kotlin.math.min
+import org.junit.Rule
+import org.mockito.kotlin.any
+import org.mockito.kotlin.doReturn
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.spy
+import org.mockito.kotlin.whenever
/**
* This is an abstract class for DeviceProfile tests that create an InvariantDeviceProfile based on
@@ -286,6 +287,9 @@
.thenReturn(
if (isGestureMode) NavigationMode.NO_BUTTON else NavigationMode.THREE_BUTTONS
)
+ doReturn(WindowManagerProxy.INSTANCE[runningContext].isTaskbarDrawnInProcess)
+ .whenever(windowManagerProxy)
+ .isTaskbarDrawnInProcess()
val density = densityDpi / DisplayMetrics.DENSITY_DEFAULT.toFloat()
val config =
diff --git a/tests/src/com/android/launcher3/allapps/PrivateProfileManagerTest.java b/tests/src/com/android/launcher3/allapps/PrivateProfileManagerTest.java
index e9d2f6e..8f398a6 100644
--- a/tests/src/com/android/launcher3/allapps/PrivateProfileManagerTest.java
+++ b/tests/src/com/android/launcher3/allapps/PrivateProfileManagerTest.java
@@ -47,8 +47,8 @@
import com.android.launcher3.logging.StatsLogManager;
import com.android.launcher3.pm.UserCache;
-import com.android.launcher3.uioverrides.ApiWrapper;
import com.android.launcher3.util.ActivityContextWrapper;
+import com.android.launcher3.util.ApiWrapper;
import com.android.launcher3.util.UserIconInfo;
import com.android.launcher3.util.rule.TestStabilityRule;
@@ -108,7 +108,8 @@
when(mUserCache.getUserInfo(Process.myUserHandle())).thenReturn(MAIN_ICON_INFO);
when(mUserCache.getUserInfo(PRIVATE_HANDLE)).thenReturn(PRIVATE_ICON_INFO);
when(mAllApps.getContext()).thenReturn(mContext);
- when(mAllApps.getContext().getResources()).thenReturn(mResources);
+ when(mContext.getResources()).thenReturn(mResources);
+ when(mContext.getApplicationContext()).thenReturn(getApplicationContext());
when(mAllApps.getAppsStore()).thenReturn(mAllAppsStore);
when(mAllApps.getActiveRecyclerView()).thenReturn(mAllAppsRecyclerView);
when(mContext.getPackageManager()).thenReturn(mPackageManager);
@@ -200,14 +201,15 @@
@Test
public void openPrivateSpaceSettings_triggersCorrectIntent() {
- Intent expectedIntent = ApiWrapper.getPrivateSpaceSettingsIntent(mContext);
+ Intent expectedIntent = ApiWrapper.INSTANCE.get(mContext).getPrivateSpaceSettingsIntent();
ArgumentCaptor<Intent> acIntent = ArgumentCaptor.forClass(Intent.class);
mPrivateProfileManager.setPrivateSpaceSettingsAvailable(true);
mPrivateProfileManager.openPrivateSpaceSettings();
Mockito.verify(mContext).startActivity(acIntent.capture());
- assertEquals("Intent Action is different", expectedIntent, acIntent.getValue());
+ assertEquals("Intent Action is different",
+ expectedIntent.toUri(0), acIntent.getValue().toUri(0));
}
private static void awaitTasksCompleted() throws Exception {