summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Nicolas Sleiman <nsl@google.com> 2023-03-07 16:39:43 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2023-03-07 16:39:43 +0000
commit1e69f441e023edb7d2d727b14a8b5d6b7d8883ce (patch)
treed76fba26db7dac3fce3a3b32999526fbd8d47c0d
parentc86ab980d7a5bbc872947eaef872932dc7037839 (diff)
parent23cc38d526f35625d0de6ec22e3a82abdcc2e4e4 (diff)
Merge "Adding an API that provides a map of shortcuts to be replaced." into udc-dev
-rw-r--r--core/java/android/app/admin/DevicePolicyCache.java13
-rw-r--r--core/java/android/content/pm/ILauncherApps.aidl2
-rw-r--r--core/java/android/content/pm/LauncherActivityInfo.java8
-rw-r--r--core/java/android/content/pm/LauncherActivityInfoInternal.java22
-rw-r--r--core/java/android/content/pm/LauncherApps.java37
-rw-r--r--services/core/java/com/android/server/pm/LauncherAppsService.java56
-rw-r--r--services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyCacheImpl.java25
-rw-r--r--services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java39
8 files changed, 186 insertions, 16 deletions
diff --git a/core/java/android/app/admin/DevicePolicyCache.java b/core/java/android/app/admin/DevicePolicyCache.java
index 3957732c56dd..b6e83c8bc8a1 100644
--- a/core/java/android/app/admin/DevicePolicyCache.java
+++ b/core/java/android/app/admin/DevicePolicyCache.java
@@ -19,6 +19,9 @@ import android.annotation.UserIdInt;
import com.android.server.LocalServices;
+import java.util.ArrayList;
+import java.util.List;
+
/**
* Stores a copy of the set of device policies maintained by {@link DevicePolicyManager} that
* can be accessed from any place without risking dead locks.
@@ -61,6 +64,12 @@ public abstract class DevicePolicyCache {
public abstract boolean canAdminGrantSensorsPermissions();
/**
+ * Returns a list of package names for which all launcher shortcuts should be modified to be
+ * launched in the managed profile and badged accordingly.
+ */
+ public abstract List<String> getLauncherShortcutOverrides();
+
+ /**
* Empty implementation.
*/
private static class EmptyDevicePolicyCache extends DevicePolicyCache {
@@ -85,5 +94,9 @@ public abstract class DevicePolicyCache {
public boolean canAdminGrantSensorsPermissions() {
return false;
}
+ @Override
+ public List<String> getLauncherShortcutOverrides() {
+ return new ArrayList<>();
+ }
}
}
diff --git a/core/java/android/content/pm/ILauncherApps.aidl b/core/java/android/content/pm/ILauncherApps.aidl
index 08cfbf76a040..96a42e24bc1a 100644
--- a/core/java/android/content/pm/ILauncherApps.aidl
+++ b/core/java/android/content/pm/ILauncherApps.aidl
@@ -33,6 +33,7 @@ import android.content.pm.PackageInstaller;
import android.content.pm.ParceledListSlice;
import android.content.pm.ResolveInfo;
import android.content.pm.ShortcutInfo;
+import android.content.pm.LauncherActivityInfoInternal;
import android.graphics.Rect;
import android.os.Bundle;
import android.os.UserHandle;
@@ -114,4 +115,5 @@ interface ILauncherApps {
String getShortcutIconUri(String callingPackage, String packageName, String shortcutId,
int userId);
+ Map<String, LauncherActivityInfoInternal> getActivityOverrides(String callingPackage, int userId);
}
diff --git a/core/java/android/content/pm/LauncherActivityInfo.java b/core/java/android/content/pm/LauncherActivityInfo.java
index 16e720e3794c..a4d532712cfe 100644
--- a/core/java/android/content/pm/LauncherActivityInfo.java
+++ b/core/java/android/content/pm/LauncherActivityInfo.java
@@ -34,7 +34,6 @@ import android.util.DisplayMetrics;
*/
public class LauncherActivityInfo {
private final PackageManager mPm;
- private UserHandle mUser;
private final LauncherActivityInfoInternal mInternal;
/**
@@ -43,9 +42,8 @@ public class LauncherActivityInfo {
* @param context The context for fetching resources.
*/
- LauncherActivityInfo(Context context, UserHandle user, LauncherActivityInfoInternal internal) {
+ LauncherActivityInfo(Context context, LauncherActivityInfoInternal internal) {
mPm = context.getPackageManager();
- mUser = user;
mInternal = internal;
}
@@ -70,7 +68,7 @@ public class LauncherActivityInfo {
* @return The UserHandle of the profile.
*/
public UserHandle getUser() {
- return mUser;
+ return mInternal.getUser();
}
/**
@@ -180,6 +178,6 @@ public class LauncherActivityInfo {
public Drawable getBadgedIcon(int density) {
Drawable originalIcon = getIcon(density);
- return mPm.getUserBadgedIcon(originalIcon, mUser);
+ return mPm.getUserBadgedIcon(originalIcon, mInternal.getUser());
}
}
diff --git a/core/java/android/content/pm/LauncherActivityInfoInternal.java b/core/java/android/content/pm/LauncherActivityInfoInternal.java
index 46c415df7525..5aac97d784b3 100644
--- a/core/java/android/content/pm/LauncherActivityInfoInternal.java
+++ b/core/java/android/content/pm/LauncherActivityInfoInternal.java
@@ -21,6 +21,7 @@ import android.compat.annotation.UnsupportedAppUsage;
import android.content.ComponentName;
import android.os.Parcel;
import android.os.Parcelable;
+import android.os.UserHandle;
/**
* @hide
@@ -30,23 +31,27 @@ public class LauncherActivityInfoInternal implements Parcelable {
@NonNull private ActivityInfo mActivityInfo;
@NonNull private ComponentName mComponentName;
@NonNull private IncrementalStatesInfo mIncrementalStatesInfo;
+ @NonNull private UserHandle mUser;
/**
* @param info ActivityInfo from which to create the LauncherActivityInfo.
* @param incrementalStatesInfo The package's states.
+ * @param user The user the activity info belongs to.
*/
public LauncherActivityInfoInternal(@NonNull ActivityInfo info,
- @NonNull IncrementalStatesInfo incrementalStatesInfo) {
+ @NonNull IncrementalStatesInfo incrementalStatesInfo,
+ @NonNull UserHandle user) {
mActivityInfo = info;
mComponentName = new ComponentName(info.packageName, info.name);
mIncrementalStatesInfo = incrementalStatesInfo;
+ mUser = user;
}
public LauncherActivityInfoInternal(Parcel source) {
- mActivityInfo = source.readParcelable(ActivityInfo.class.getClassLoader(), android.content.pm.ActivityInfo.class);
+ mActivityInfo = source.readTypedObject(ActivityInfo.CREATOR);
mComponentName = new ComponentName(mActivityInfo.packageName, mActivityInfo.name);
- mIncrementalStatesInfo = source.readParcelable(
- IncrementalStatesInfo.class.getClassLoader(), android.content.pm.IncrementalStatesInfo.class);
+ mIncrementalStatesInfo = source.readTypedObject(IncrementalStatesInfo.CREATOR);
+ mUser = source.readTypedObject(UserHandle.CREATOR);
}
public ComponentName getComponentName() {
@@ -57,6 +62,10 @@ public class LauncherActivityInfoInternal implements Parcelable {
return mActivityInfo;
}
+ public UserHandle getUser() {
+ return mUser;
+ }
+
public IncrementalStatesInfo getIncrementalStatesInfo() {
return mIncrementalStatesInfo;
}
@@ -68,8 +77,9 @@ public class LauncherActivityInfoInternal implements Parcelable {
@Override
public void writeToParcel(Parcel dest, int flags) {
- dest.writeParcelable(mActivityInfo, 0);
- dest.writeParcelable(mIncrementalStatesInfo, 0);
+ dest.writeTypedObject(mActivityInfo, flags);
+ dest.writeTypedObject(mIncrementalStatesInfo, flags);
+ dest.writeTypedObject(mUser, flags);
}
public static final @android.annotation.NonNull Creator<LauncherActivityInfoInternal> CREATOR =
diff --git a/core/java/android/content/pm/LauncherApps.java b/core/java/android/content/pm/LauncherApps.java
index f8c49744d834..8989006a7e83 100644
--- a/core/java/android/content/pm/LauncherApps.java
+++ b/core/java/android/content/pm/LauncherApps.java
@@ -64,6 +64,7 @@ import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.UserHandle;
import android.os.UserManager;
+import android.util.ArrayMap;
import android.util.DisplayMetrics;
import android.util.Log;
import android.util.Pair;
@@ -793,13 +794,45 @@ public class LauncherApps {
if (ai == null) {
return null;
}
- return new LauncherActivityInfo(mContext, user, ai);
+ return new LauncherActivityInfo(mContext, ai);
} catch (RemoteException re) {
throw re.rethrowFromSystemServer();
}
}
/**
+ * Returns overrides for the activities that should be launched for the shortcuts of certain
+ * package names.
+ *
+ * @return {@link Map} whose keys are package names and whose values are the
+ * {@link LauncherActivityInfo}s that should be used for those packages' shortcuts. If there are
+ * no activity overrides, an empty {@link Map} will be returned.
+ *
+ * @hide
+ */
+ @NonNull
+ public Map<String, LauncherActivityInfo> getActivityOverrides() {
+ Map<String, LauncherActivityInfo> activityOverrides = new ArrayMap<>();
+ try {
+ Map<String, LauncherActivityInfoInternal> activityOverridesInternal =
+ mService.getActivityOverrides(mContext.getPackageName(), mContext.getUserId());
+ for (Map.Entry<String, LauncherActivityInfoInternal> packageToOverride :
+ activityOverridesInternal.entrySet()) {
+ activityOverrides.put(
+ packageToOverride.getKey(),
+ new LauncherActivityInfo(
+ mContext,
+ packageToOverride.getValue()
+ )
+ );
+ }
+ } catch (RemoteException re) {
+ throw re.rethrowFromSystemServer();
+ }
+ return activityOverrides;
+ }
+
+ /**
* Starts a Main activity in the specified profile.
*
* @param component The ComponentName of the activity to launch
@@ -916,7 +949,7 @@ public class LauncherApps {
}
ArrayList<LauncherActivityInfo> lais = new ArrayList<>();
for (LauncherActivityInfoInternal internal : internals.getList()) {
- LauncherActivityInfo lai = new LauncherActivityInfo(mContext, user, internal);
+ LauncherActivityInfo lai = new LauncherActivityInfo(mContext, internal);
if (DEBUG) {
Log.v(TAG, "Returning activity for profile " + user + " : "
+ lai.getComponentName());
diff --git a/services/core/java/com/android/server/pm/LauncherAppsService.java b/services/core/java/com/android/server/pm/LauncherAppsService.java
index 9e01c7af0f0b..84bee50b77b0 100644
--- a/services/core/java/com/android/server/pm/LauncherAppsService.java
+++ b/services/core/java/com/android/server/pm/LauncherAppsService.java
@@ -39,6 +39,7 @@ import android.app.ActivityOptions;
import android.app.AppGlobals;
import android.app.IApplicationThread;
import android.app.PendingIntent;
+import android.app.admin.DevicePolicyCache;
import android.app.admin.DevicePolicyManager;
import android.app.usage.UsageStatsManagerInternal;
import android.content.ActivityNotFoundException;
@@ -85,6 +86,7 @@ import android.os.ServiceManager;
import android.os.UserHandle;
import android.os.UserManager;
import android.provider.Settings;
+import android.util.ArrayMap;
import android.util.Log;
import android.util.Pair;
import android.util.Slog;
@@ -107,6 +109,7 @@ import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
+import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ExecutionException;
@@ -623,7 +626,7 @@ public class LauncherAppsService extends SystemService {
// package does not exist; should not happen
return null;
}
- return new LauncherActivityInfoInternal(activityInfo, incrementalStatesInfo);
+ return new LauncherActivityInfoInternal(activityInfo, incrementalStatesInfo, user);
} finally {
Binder.restoreCallingIdentity(ident);
}
@@ -676,7 +679,7 @@ public class LauncherAppsService extends SystemService {
continue;
}
results.add(new LauncherActivityInfoInternal(ri.activityInfo,
- incrementalStatesInfo));
+ incrementalStatesInfo, user));
}
return results;
}
@@ -1078,6 +1081,55 @@ public class LauncherAppsService extends SystemService {
}
@Override
+ @NonNull
+ public Map<String, LauncherActivityInfoInternal> getActivityOverrides(String callingPackage,
+ int userId) {
+ ensureShortcutPermission(callingPackage);
+ int callingUid = Binder.getCallingUid();
+ final long callerIdentity = Binder.clearCallingIdentity();
+ try {
+ Map<String, LauncherActivityInfoInternal> shortcutOverridesInfo = new ArrayMap<>();
+ UserHandle managedUserHandle = getManagedProfile(userId);
+ if (managedUserHandle == null) {
+ return shortcutOverridesInfo;
+ }
+
+ List<String> packagesToOverride =
+ DevicePolicyCache.getInstance().getLauncherShortcutOverrides();
+ for (String packageName : packagesToOverride) {
+ Intent intent = new Intent(Intent.ACTION_MAIN)
+ .addCategory(Intent.CATEGORY_LAUNCHER)
+ .setPackage(packageName);
+
+ List<LauncherActivityInfoInternal> possibleShortcutOverrides =
+ queryIntentLauncherActivities(
+ intent,
+ callingUid,
+ managedUserHandle
+ );
+
+ if (!possibleShortcutOverrides.isEmpty()) {
+ shortcutOverridesInfo.put(packageName, possibleShortcutOverrides.get(0));
+ }
+ }
+ return shortcutOverridesInfo;
+ } finally {
+ Binder.restoreCallingIdentity(callerIdentity);
+ }
+ }
+
+
+ @Nullable
+ private UserHandle getManagedProfile(int userId) {
+ for (UserInfo profile : mUm.getProfiles(userId)) {
+ if (profile.isManagedProfile()) {
+ return profile.getUserHandle();
+ }
+ }
+ return null;
+ }
+
+ @Override
public boolean startShortcut(String callingPackage, String packageName, String featureId,
String shortcutId, Rect sourceBounds, Bundle startActivityOptions,
int targetUserId) {
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyCacheImpl.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyCacheImpl.java
index 4351bc1c81ce..80100a927e82 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyCacheImpl.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyCacheImpl.java
@@ -24,6 +24,8 @@ import android.util.SparseIntArray;
import com.android.internal.annotations.GuardedBy;
+import java.util.ArrayList;
+import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
/**
@@ -52,6 +54,11 @@ public class DevicePolicyCacheImpl extends DevicePolicyCache {
@GuardedBy("mLock")
private final SparseIntArray mPermissionPolicy = new SparseIntArray();
+ @GuardedBy("mLock")
+ private List<String> mLauncherShortcutOverrides =
+ new ArrayList<>();
+
+
/** Maps to {@code ActiveAdmin.mAdminCanGrantSensorsPermissions}. */
private final AtomicBoolean mCanGrantSensorsPermissions = new AtomicBoolean(false);
@@ -122,6 +129,22 @@ public class DevicePolicyCacheImpl extends DevicePolicyCache {
mCanGrantSensorsPermissions.set(canGrant);
}
+ @Override
+ public List<String> getLauncherShortcutOverrides() {
+ synchronized (mLock) {
+ return new ArrayList<>(mLauncherShortcutOverrides);
+ }
+ }
+
+ /**
+ * Sets a list of packages for which shortcuts should be replaced by their badged version.
+ */
+ public void setLauncherShortcutOverrides(List<String> launcherShortcutOverrides) {
+ synchronized (mLock) {
+ mLauncherShortcutOverrides = new ArrayList<>(launcherShortcutOverrides);
+ }
+ }
+
/** Dump content */
public void dump(IndentingPrintWriter pw) {
synchronized (mLock) {
@@ -131,6 +154,8 @@ public class DevicePolicyCacheImpl extends DevicePolicyCache {
pw.println("Password quality: " + mPasswordQuality);
pw.println("Permission policy: " + mPermissionPolicy);
pw.println("Admin can grant sensors permission: " + mCanGrantSensorsPermissions.get());
+ pw.print("Shortcuts overrides: ");
+ pw.println(mLauncherShortcutOverrides);
pw.decreaseIndent();
}
}
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 400ee1d3baf3..a4e563b21bec 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -3522,16 +3522,30 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
userId == UserHandle.USER_SYSTEM ? UserHandle.USER_ALL : userId);
updatePermissionPolicyCache(userId);
updateAdminCanGrantSensorsPermissionCache(userId);
-
final List<PreferentialNetworkServiceConfig> preferentialNetworkServiceConfigs;
+ boolean isManagedSubscription;
+
synchronized (getLockObject()) {
ActiveAdmin owner = getDeviceOrProfileOwnerAdminLocked(userId);
preferentialNetworkServiceConfigs = owner != null
? owner.mPreferentialNetworkServiceConfigs
: List.of(PreferentialNetworkServiceConfig.DEFAULT);
+
+ isManagedSubscription = owner != null && owner.mManagedSubscriptionsPolicy != null
+ && owner.mManagedSubscriptionsPolicy.getPolicyType()
+ == ManagedSubscriptionsPolicy.TYPE_ALL_MANAGED_SUBSCRIPTIONS;
}
updateNetworkPreferenceForUser(userId, preferentialNetworkServiceConfigs);
+ if (isManagedSubscription) {
+ String defaultDialerPackageName = getDefaultRoleHolderPackageName(
+ com.android.internal.R.string.config_defaultDialer);
+ String defaultSmsPackageName = getDefaultRoleHolderPackageName(
+ com.android.internal.R.string.config_defaultSms);
+ updateDialerAndSmsManagedShortcutsOverrideCache(defaultDialerPackageName,
+ defaultSmsPackageName);
+ }
+
startOwnerService(userId, "start-user");
if (isDevicePolicyEngineEnabled()) {
mDevicePolicyEngine.handleStartUser(userId);
@@ -7614,6 +7628,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
if (isWorkProfileTelephonyFlagEnabled()) {
clearManagedSubscriptionsPolicy();
+ clearLauncherShortcutOverrides();
updateTelephonyCrossProfileIntentFilters(parentId, UserHandle.USER_NULL, false);
}
Slogf.i(LOG_TAG, "Cleaning up device-wide policies done.");
@@ -7631,6 +7646,10 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
}
}
+ private void clearLauncherShortcutOverrides() {
+ mPolicyCache.setLauncherShortcutOverrides(new ArrayList<>());
+ }
+
private void updateTelephonyCrossProfileIntentFilters(int parentUserId, int profileUserId,
boolean enableWorkTelephony) {
try {
@@ -22755,12 +22774,30 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
} else {
Slogf.w(LOG_TAG, "Couldn't install sms app, sms app package is null");
}
+
+ updateDialerAndSmsManagedShortcutsOverrideCache(defaultDialerPackageName,
+ defaultSmsPackageName);
} catch (RemoteException re) {
// shouldn't happen
Slogf.wtf(LOG_TAG, "Failed to install dialer/sms app", re);
}
}
+ private void updateDialerAndSmsManagedShortcutsOverrideCache(
+ String defaultDialerPackageName, String defaultSmsPackageName) {
+
+ List<String> shortcutOverrides = new ArrayList<>();
+
+ if (defaultDialerPackageName != null) {
+ shortcutOverrides.add(defaultDialerPackageName);
+ }
+
+ if (defaultSmsPackageName != null) {
+ shortcutOverrides.add(defaultSmsPackageName);
+ }
+ mPolicyCache.setLauncherShortcutOverrides(shortcutOverrides);
+ }
+
private void registerListenerToAssignSubscriptionsToUser(int userId) {
synchronized (mSubscriptionsChangedListenerLock) {
if (mSubscriptionsChangedListener != null) {