diff options
8 files changed, 215 insertions, 71 deletions
diff --git a/api/current.txt b/api/current.txt index 2ee5e1eab5f5..200177c0290f 100644 --- a/api/current.txt +++ b/api/current.txt @@ -11233,6 +11233,7 @@ package android.content.pm { public class LauncherApps { method public java.util.List<android.content.pm.LauncherActivityInfo> getActivityList(String, android.os.UserHandle); + method @NonNull public java.util.List<android.content.pm.PackageInstaller.SessionInfo> getAllPackageInstallerSessions(); method @Nullable public android.content.pm.LauncherApps.AppUsageLimit getAppUsageLimit(String, android.os.UserHandle); method public android.content.pm.ApplicationInfo getApplicationInfo(@NonNull String, int, @NonNull android.os.UserHandle) throws android.content.pm.PackageManager.NameNotFoundException; method public android.content.pm.LauncherApps.PinItemRequest getPinItemRequest(android.content.Intent); @@ -11249,13 +11250,16 @@ package android.content.pm { method public void pinShortcuts(@NonNull String, @NonNull java.util.List<java.lang.String>, @NonNull android.os.UserHandle); method public void registerCallback(android.content.pm.LauncherApps.Callback); method public void registerCallback(android.content.pm.LauncherApps.Callback, android.os.Handler); + method public void registerPackageInstallerSessionCallback(@NonNull java.util.concurrent.Executor, @NonNull android.content.pm.PackageInstaller.SessionCallback); method public android.content.pm.LauncherActivityInfo resolveActivity(android.content.Intent, android.os.UserHandle); method public boolean shouldHideFromSuggestions(@NonNull String, @NonNull android.os.UserHandle); method public void startAppDetailsActivity(android.content.ComponentName, android.os.UserHandle, android.graphics.Rect, android.os.Bundle); method public void startMainActivity(android.content.ComponentName, android.os.UserHandle, android.graphics.Rect, android.os.Bundle); + method public void startPackageInstallerSessionDetailsActivity(android.content.pm.PackageInstaller.SessionInfo, android.graphics.Rect, android.os.Bundle); method public void startShortcut(@NonNull String, @NonNull String, @Nullable android.graphics.Rect, @Nullable android.os.Bundle, @NonNull android.os.UserHandle); method public void startShortcut(@NonNull android.content.pm.ShortcutInfo, @Nullable android.graphics.Rect, @Nullable android.os.Bundle); method public void unregisterCallback(android.content.pm.LauncherApps.Callback); + method public void unregisterPackageInstallerSessionCallback(android.content.pm.PackageInstaller.SessionCallback); field public static final String ACTION_CONFIRM_PIN_APPWIDGET = "android.content.pm.action.CONFIRM_PIN_APPWIDGET"; field public static final String ACTION_CONFIRM_PIN_SHORTCUT = "android.content.pm.action.CONFIRM_PIN_SHORTCUT"; field public static final String EXTRA_PIN_ITEM_REQUEST = "android.content.pm.extra.PIN_ITEM_REQUEST"; @@ -11445,6 +11449,7 @@ package android.content.pm { method public long getSize(); method public int getStagedSessionErrorCode(); method public String getStagedSessionErrorMessage(); + method public android.os.UserHandle getUser(); method public boolean isActive(); method public boolean isMultiPackage(); method public boolean isSealed(); diff --git a/core/java/android/content/pm/ILauncherApps.aidl b/core/java/android/content/pm/ILauncherApps.aidl index d1bc37791d40..50bb3c721763 100644 --- a/core/java/android/content/pm/ILauncherApps.aidl +++ b/core/java/android/content/pm/ILauncherApps.aidl @@ -24,6 +24,8 @@ import android.content.pm.ActivityInfo; import android.content.pm.ApplicationInfo; import android.content.pm.IOnAppsChangedListener; import android.content.pm.LauncherApps; +import android.content.pm.IPackageInstallerCallback; +import android.content.pm.PackageInstaller; import android.content.pm.ParceledListSlice; import android.content.pm.ResolveInfo; import android.content.pm.ShortcutInfo; @@ -44,6 +46,9 @@ interface ILauncherApps { String callingPackage, String packageName, in UserHandle user); ActivityInfo resolveActivity( String callingPackage, in ComponentName component, in UserHandle user); + void startSessionDetailsActivityAsUser(in IApplicationThread caller, String callingPackage, + in PackageInstaller.SessionInfo sessionInfo, in Rect sourceBounds, in Bundle opts, + in UserHandle user); void startActivityAsUser(in IApplicationThread caller, String callingPackage, in ComponentName component, in Rect sourceBounds, in Bundle opts, in UserHandle user); @@ -79,4 +84,9 @@ interface ILauncherApps { String callingPackage, String packageName, in UserHandle user); IntentSender getShortcutConfigActivityIntent(String callingPackage, in ComponentName component, in UserHandle user); + + // Unregister is performed using package installer + void registerPackageInstallerCallback(String callingPackage, + in IPackageInstallerCallback callback); + ParceledListSlice getAllSessions(String callingPackage); } diff --git a/core/java/android/content/pm/LauncherApps.java b/core/java/android/content/pm/LauncherApps.java index 98dd9b3aa30b..b0d16cdace21 100644 --- a/core/java/android/content/pm/LauncherApps.java +++ b/core/java/android/content/pm/LauncherApps.java @@ -16,6 +16,7 @@ package android.content.pm; +import android.annotation.CallbackExecutor; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; @@ -32,6 +33,9 @@ import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.IntentSender; +import android.content.pm.PackageInstaller.SessionCallback; +import android.content.pm.PackageInstaller.SessionCallbackDelegate; +import android.content.pm.PackageInstaller.SessionInfo; import android.content.pm.PackageManager.ApplicationInfoFlags; import android.content.pm.PackageManager.NameNotFoundException; import android.content.res.Resources; @@ -65,7 +69,9 @@ import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; +import java.util.Iterator; import java.util.List; +import java.util.concurrent.Executor; /** * Class for retrieving a list of launchable activities for the current user and any associated @@ -154,8 +160,8 @@ public class LauncherApps { private final PackageManager mPm; private final UserManager mUserManager; - private List<CallbackMessageHandler> mCallbacks - = new ArrayList<CallbackMessageHandler>(); + private final List<CallbackMessageHandler> mCallbacks = new ArrayList<>(); + private final List<SessionCallbackDelegate> mDelegates = new ArrayList<>(); /** * Callbacks for package changes to this and related managed profiles. @@ -572,6 +578,24 @@ public class LauncherApps { } /** + * Starts an activity to show the details of the specified session. + * + * @param sessionInfo The SessionInfo of the session + * @param sourceBounds The Rect containing the source bounds of the clicked icon + * @param opts Options to pass to startActivity + */ + public void startPackageInstallerSessionDetailsActivity(SessionInfo sessionInfo, + Rect sourceBounds, Bundle opts) { + try { + mService.startSessionDetailsActivityAsUser(mContext.getIApplicationThread(), + mContext.getPackageName(), sessionInfo, sourceBounds, opts, + sessionInfo.getUser()); + } catch (RemoteException re) { + throw re.rethrowFromSystemServer(); + } + } + + /** * Starts the settings activity to show the application details for a * package in the specified profile. * @@ -1131,7 +1155,7 @@ public class LauncherApps { } /** - * Registers a callback for changes to packages in current and managed profiles. + * Registers a callback for changes to packages in this user and managed profiles. * * @param callback The callback to register. */ @@ -1140,7 +1164,7 @@ public class LauncherApps { } /** - * Registers a callback for changes to packages in current and managed profiles. + * Registers a callback for changes to packages in this user and managed profiles. * * @param callback The callback to register. * @param handler that should be used to post callbacks on, may be null. @@ -1446,6 +1470,64 @@ public class LauncherApps { } /** + * Register a callback to watch for session lifecycle events in this user and managed profiles. + * @param callback The callback to register. + * @param executor {@link Executor} to handle the callbacks, cannot be null. + * + * @see PackageInstaller#registerSessionCallback(SessionCallback) + */ + public void registerPackageInstallerSessionCallback( + @NonNull @CallbackExecutor Executor executor, @NonNull SessionCallback callback) { + if (executor == null) { + throw new NullPointerException("Executor must not be null"); + } + + synchronized (mDelegates) { + final SessionCallbackDelegate delegate = new SessionCallbackDelegate(callback, + executor); + try { + mService.registerPackageInstallerCallback(mContext.getPackageName(), + delegate); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + mDelegates.add(delegate); + } + } + + /** + * Unregisters a callback that was previously registered. + * + * @param callback The callback to unregister. + * @see #registerPackageInstallerSessionCallback(Executor, SessionCallback) + */ + public void unregisterPackageInstallerSessionCallback(SessionCallback callback) { + synchronized (mDelegates) { + for (Iterator<SessionCallbackDelegate> i = mDelegates.iterator(); i.hasNext();) { + final SessionCallbackDelegate delegate = i.next(); + if (delegate.mCallback == callback) { + mPm.getPackageInstaller().unregisterSessionCallback(delegate.mCallback); + i.remove(); + } + } + } + } + + /** + * Return list of all known install sessions in this user and managed profiles, regardless + * of the installer. + * + * @see PackageInstaller#getAllSessions() + */ + public @NonNull List<SessionInfo> getAllPackageInstallerSessions() { + try { + return mService.getAllSessions(mContext.getPackageName()).getList(); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** * A helper method to extract a {@link PinItemRequest} set to * the {@link #EXTRA_PIN_ITEM_REQUEST} extra. */ diff --git a/core/java/android/content/pm/PackageInstaller.java b/core/java/android/content/pm/PackageInstaller.java index 2dc014c45fad..4f674bd378c0 100644 --- a/core/java/android/content/pm/PackageInstaller.java +++ b/core/java/android/content/pm/PackageInstaller.java @@ -36,20 +36,21 @@ import android.net.Uri; import android.os.Build; import android.os.FileBridge; import android.os.Handler; -import android.os.Looper; -import android.os.Message; +import android.os.HandlerExecutor; import android.os.Parcel; import android.os.ParcelFileDescriptor; import android.os.Parcelable; import android.os.ParcelableException; import android.os.RemoteException; import android.os.SystemProperties; +import android.os.UserHandle; import android.system.ErrnoException; import android.system.Os; import android.util.ExceptionUtils; import com.android.internal.util.IndentingPrintWriter; import com.android.internal.util.Preconditions; +import com.android.internal.util.function.pooled.PooledLambda; import java.io.Closeable; import java.io.IOException; @@ -61,6 +62,7 @@ import java.security.MessageDigest; import java.util.ArrayList; import java.util.Iterator; import java.util.List; +import java.util.concurrent.Executor; /** * Offers the ability to install, upgrade, and remove applications on the @@ -659,8 +661,7 @@ public class PackageInstaller { } /** {@hide} */ - private static class SessionCallbackDelegate extends IPackageInstallerCallback.Stub implements - Handler.Callback { + static class SessionCallbackDelegate extends IPackageInstallerCallback.Stub { private static final int MSG_SESSION_CREATED = 1; private static final int MSG_SESSION_BADGING_CHANGED = 2; private static final int MSG_SESSION_ACTIVE_CHANGED = 3; @@ -668,63 +669,41 @@ public class PackageInstaller { private static final int MSG_SESSION_FINISHED = 5; final SessionCallback mCallback; - final Handler mHandler; + final Executor mExecutor; - public SessionCallbackDelegate(SessionCallback callback, Looper looper) { + SessionCallbackDelegate(SessionCallback callback, Executor executor) { mCallback = callback; - mHandler = new Handler(looper, this); - } - - @Override - public boolean handleMessage(Message msg) { - final int sessionId = msg.arg1; - switch (msg.what) { - case MSG_SESSION_CREATED: - mCallback.onCreated(sessionId); - return true; - case MSG_SESSION_BADGING_CHANGED: - mCallback.onBadgingChanged(sessionId); - return true; - case MSG_SESSION_ACTIVE_CHANGED: - final boolean active = msg.arg2 != 0; - mCallback.onActiveChanged(sessionId, active); - return true; - case MSG_SESSION_PROGRESS_CHANGED: - mCallback.onProgressChanged(sessionId, (float) msg.obj); - return true; - case MSG_SESSION_FINISHED: - mCallback.onFinished(sessionId, msg.arg2 != 0); - return true; - } - return false; + mExecutor = executor; } @Override public void onSessionCreated(int sessionId) { - mHandler.obtainMessage(MSG_SESSION_CREATED, sessionId, 0).sendToTarget(); + mExecutor.execute(PooledLambda.obtainRunnable(SessionCallback::onCreated, mCallback, + sessionId).recycleOnUse()); } @Override public void onSessionBadgingChanged(int sessionId) { - mHandler.obtainMessage(MSG_SESSION_BADGING_CHANGED, sessionId, 0).sendToTarget(); + mExecutor.execute(PooledLambda.obtainRunnable(SessionCallback::onBadgingChanged, + mCallback, sessionId).recycleOnUse()); } @Override public void onSessionActiveChanged(int sessionId, boolean active) { - mHandler.obtainMessage(MSG_SESSION_ACTIVE_CHANGED, sessionId, active ? 1 : 0) - .sendToTarget(); + mExecutor.execute(PooledLambda.obtainRunnable(SessionCallback::onActiveChanged, + mCallback, sessionId, active).recycleOnUse()); } @Override public void onSessionProgressChanged(int sessionId, float progress) { - mHandler.obtainMessage(MSG_SESSION_PROGRESS_CHANGED, sessionId, 0, progress) - .sendToTarget(); + mExecutor.execute(PooledLambda.obtainRunnable(SessionCallback::onProgressChanged, + mCallback, sessionId, progress).recycleOnUse()); } @Override public void onSessionFinished(int sessionId, boolean success) { - mHandler.obtainMessage(MSG_SESSION_FINISHED, sessionId, success ? 1 : 0) - .sendToTarget(); + mExecutor.execute(PooledLambda.obtainRunnable(SessionCallback::onFinished, + mCallback, sessionId, success).recycleOnUse()); } } @@ -758,7 +737,7 @@ public class PackageInstaller { public void registerSessionCallback(@NonNull SessionCallback callback, @NonNull Handler handler) { synchronized (mDelegates) { final SessionCallbackDelegate delegate = new SessionCallbackDelegate(callback, - handler.getLooper()); + new HandlerExecutor(handler)); try { mInstaller.registerCallback(delegate, mUserId); } catch (RemoteException e) { @@ -1649,6 +1628,8 @@ public class PackageInstaller { @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) public int sessionId; /** {@hide} */ + public int userId; + /** {@hide} */ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) public String installerPackageName; /** {@hide} */ @@ -1720,6 +1701,7 @@ public class PackageInstaller { /** {@hide} */ public SessionInfo(Parcel source) { sessionId = source.readInt(); + userId = source.readInt(); installerPackageName = source.readString(); resolvedBaseCodePath = source.readString(); progress = source.readFloat(); @@ -1761,6 +1743,13 @@ public class PackageInstaller { } /** + * Return the user associated with this session. + */ + public UserHandle getUser() { + return new UserHandle(userId); + } + + /** * Return the package name of the app that owns this session. */ public @Nullable String getInstallerPackageName() { @@ -2091,6 +2080,7 @@ public class PackageInstaller { @Override public void writeToParcel(Parcel dest, int flags) { dest.writeInt(sessionId); + dest.writeInt(userId); dest.writeString(installerPackageName); dest.writeString(resolvedBaseCodePath); dest.writeFloat(progress); diff --git a/services/core/java/com/android/server/pm/LauncherAppsService.java b/services/core/java/com/android/server/pm/LauncherAppsService.java index e3c41f3aaf3b..62c4815a7de0 100644 --- a/services/core/java/com/android/server/pm/LauncherAppsService.java +++ b/services/core/java/com/android/server/pm/LauncherAppsService.java @@ -34,9 +34,11 @@ import android.content.pm.ActivityInfo; import android.content.pm.ApplicationInfo; import android.content.pm.ILauncherApps; import android.content.pm.IOnAppsChangedListener; +import android.content.pm.IPackageInstallerCallback; import android.content.pm.LauncherApps; import android.content.pm.LauncherApps.ShortcutQuery; import android.content.pm.PackageInfo; +import android.content.pm.PackageInstaller.SessionInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManagerInternal; import android.content.pm.ParceledListSlice; @@ -56,6 +58,7 @@ import android.os.IInterface; import android.os.ParcelFileDescriptor; import android.os.RemoteCallbackList; import android.os.RemoteException; +import android.os.ServiceManager; import android.os.UserHandle; import android.os.UserManager; import android.os.UserManagerInternal; @@ -153,6 +156,8 @@ public class LauncherAppsService extends SystemService { private final Object mVouchedSignaturesLocked = new Object(); + private PackageInstallerService mPackageInstallerService; + public LauncherAppsImpl(Context context) { mContext = context; mUm = (UserManager) mContext.getSystemService(Context.USER_SERVICE); @@ -204,8 +209,7 @@ public class LauncherAppsService extends SystemService { } /* - * @see android.content.pm.ILauncherApps#addOnAppsChangedListener( - * android.content.pm.IOnAppsChangedListener) + * @see android.content.pm.ILauncherApps#addOnAppsChangedListener */ @Override public void addOnAppsChangedListener(String callingPackage, IOnAppsChangedListener listener) @@ -228,8 +232,7 @@ public class LauncherAppsService extends SystemService { } /* - * @see android.content.pm.ILauncherApps#removeOnAppsChangedListener( - * android.content.pm.IOnAppsChangedListener) + * @see android.content.pm.ILauncherApps#removeOnAppsChangedListener */ @Override public void removeOnAppsChangedListener(IOnAppsChangedListener listener) @@ -246,6 +249,44 @@ public class LauncherAppsService extends SystemService { } /** + * @see android.content.pm.ILauncherApps#registerPackageInstallerCallback + */ + @Override + public void registerPackageInstallerCallback(String callingPackage, + IPackageInstallerCallback callback) { + verifyCallingPackage(callingPackage); + UserHandle callingIdUserHandle = new UserHandle(getCallingUserId()); + getPackageInstallerService().registerCallback(callback, eventUserId -> + isEnabledProfileOf(callingIdUserHandle, + new UserHandle(eventUserId), "shouldReceiveEvent")); + } + + @Override + public ParceledListSlice<SessionInfo> getAllSessions(String callingPackage) { + verifyCallingPackage(callingPackage); + List<SessionInfo> sessionInfos = new ArrayList<>(); + int[] userIds = mUm.getEnabledProfileIds(getCallingUserId()); + long token = Binder.clearCallingIdentity(); + try { + for (int userId : userIds) { + sessionInfos.addAll(getPackageInstallerService().getAllSessions(userId) + .getList()); + } + } finally { + Binder.restoreCallingIdentity(token); + } + return new ParceledListSlice<>(sessionInfos); + } + + private PackageInstallerService getPackageInstallerService() { + if (mPackageInstallerService == null) { + mPackageInstallerService = ((PackageInstallerService) ((PackageManagerService) + ServiceManager.getService("package")).getPackageInstaller()); + } + return mPackageInstallerService; + } + + /** * Register a receiver to watch for package broadcasts */ private void startWatchingPackageBroadcasts() { @@ -869,6 +910,29 @@ public class LauncherAppsService extends SystemService { } @Override + public void startSessionDetailsActivityAsUser(IApplicationThread caller, + String callingPackage, SessionInfo sessionInfo, Rect sourceBounds, + Bundle opts, UserHandle userHandle) throws RemoteException { + int userId = userHandle.getIdentifier(); + if (!canAccessProfile(userId, "Cannot start details activity")) { + return; + } + + Intent i = new Intent(Intent.ACTION_VIEW) + .setData(new Uri.Builder() + .scheme("market") + .authority("details") + .appendQueryParameter("id", sessionInfo.appPackageName) + .build()) + .putExtra(Intent.EXTRA_REFERRER, new Uri.Builder().scheme("android-app") + .authority(callingPackage).build()); + i.setSourceBounds(sourceBounds); + + mActivityTaskManagerInternal.startActivityAsUser(caller, callingPackage, i, opts, + userId); + } + + @Override public void startActivityAsUser(IApplicationThread caller, String callingPackage, ComponentName component, Rect sourceBounds, Bundle opts, UserHandle user) throws RemoteException { diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java index 146a2f3d8433..a3e0d8db8ad5 100644 --- a/services/core/java/com/android/server/pm/PackageInstallerService.java +++ b/services/core/java/com/android/server/pm/PackageInstallerService.java @@ -59,7 +59,6 @@ import android.os.Process; import android.os.RemoteCallbackList; import android.os.RemoteException; import android.os.SELinux; -import android.os.UserHandle; import android.os.UserManager; import android.os.storage.StorageManager; import android.system.ErrnoException; @@ -107,6 +106,7 @@ import java.util.Collections; import java.util.List; import java.util.Objects; import java.util.Random; +import java.util.function.IntPredicate; /** The service responsible for installing packages. */ public class PackageInstallerService extends IPackageInstaller.Stub implements @@ -804,7 +804,14 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements public void registerCallback(IPackageInstallerCallback callback, int userId) { mPermissionManager.enforceCrossUserPermission( Binder.getCallingUid(), userId, true, false, "registerCallback"); - mCallbacks.register(callback, userId); + registerCallback(callback, eventUserId -> userId == eventUserId); + } + + /** + * Assume permissions already checked and caller's identity cleared + */ + public void registerCallback(IPackageInstallerCallback callback, IntPredicate userCheck) { + mCallbacks.register(callback, userCheck); } @Override @@ -1026,8 +1033,8 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements super(looper); } - public void register(IPackageInstallerCallback callback, int userId) { - mCallbacks.register(callback, new UserHandle(userId)); + public void register(IPackageInstallerCallback callback, IntPredicate userCheck) { + mCallbacks.register(callback, userCheck); } public void unregister(IPackageInstallerCallback callback) { @@ -1040,9 +1047,8 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements final int n = mCallbacks.beginBroadcast(); for (int i = 0; i < n; i++) { final IPackageInstallerCallback callback = mCallbacks.getBroadcastItem(i); - final UserHandle user = (UserHandle) mCallbacks.getBroadcastCookie(i); - // TODO: dispatch notifications for slave profiles - if (userId == user.getIdentifier()) { + final IntPredicate userCheck = (IntPredicate) mCallbacks.getBroadcastCookie(i); + if (userCheck.test(userId)) { try { invokeCallback(callback, msg); } catch (RemoteException ignored) { diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java index 494ec3ff67aa..de0849fa9951 100644 --- a/services/core/java/com/android/server/pm/PackageInstallerSession.java +++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java @@ -473,6 +473,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { final SessionInfo info = new SessionInfo(); synchronized (mLock) { info.sessionId = sessionId; + info.userId = userId; info.installerPackageName = mInstallerPackageName; info.resolvedBaseCodePath = (mResolvedBaseFile != null) ? mResolvedBaseFile.getAbsolutePath() : null; diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java index 4f20590a47ff..d0f192d597c6 100644 --- a/services/core/java/com/android/server/pm/UserManagerService.java +++ b/services/core/java/com/android/server/pm/UserManagerService.java @@ -1109,14 +1109,7 @@ public class UserManagerService extends IUserManager.Stub { @Override public int getManagedProfileBadge(@UserIdInt int userId) { - int callingUserId = UserHandle.getCallingUserId(); - if (callingUserId != userId && !hasManageUsersPermission()) { - if (!isSameProfileGroupNoChecks(callingUserId, userId)) { - throw new SecurityException( - "You need MANAGE_USERS permission to: check if specified user a " + - "managed profile outside your profile group"); - } - } + checkManageOrInteractPermIfCallerInOtherProfileGroup(userId, "getManagedProfileBadge"); synchronized (mUsersLock) { UserInfo userInfo = getUserInfoLU(userId); return userInfo != null ? userInfo.profileBadge : 0; @@ -1125,14 +1118,7 @@ public class UserManagerService extends IUserManager.Stub { @Override public boolean isManagedProfile(int userId) { - int callingUserId = UserHandle.getCallingUserId(); - if (callingUserId != userId && !hasManageUsersPermission()) { - if (!isSameProfileGroupNoChecks(callingUserId, userId)) { - throw new SecurityException( - "You need MANAGE_USERS permission to: check if specified user a " + - "managed profile outside your profile group"); - } - } + checkManageOrInteractPermIfCallerInOtherProfileGroup(userId, "isManagedProfile"); synchronized (mUsersLock) { UserInfo userInfo = getUserInfoLU(userId); return userInfo != null && userInfo.isManagedProfile(); |