Merge "Adding an API that provides a map of shortcuts to be replaced." into udc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
1e69f441e0
@@ -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.
|
||||
@@ -60,6 +63,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.
|
||||
*/
|
||||
@@ -85,5 +94,9 @@ public abstract class DevicePolicyCache {
|
||||
public boolean canAdminGrantSensorsPermissions() {
|
||||
return false;
|
||||
}
|
||||
@Override
|
||||
public List<String> getLauncherShortcutOverrides() {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 =
|
||||
|
||||
@@ -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,12 +794,44 @@ 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.
|
||||
*
|
||||
@@ -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());
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -1077,6 +1080,55 @@ public class LauncherAppsService extends SystemService {
|
||||
callingPackage, injectBinderCallingPid(), injectBinderCallingUid());
|
||||
}
|
||||
|
||||
@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,
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user