diff options
author | android-build-team Robot <android-build-team-robot@google.com> | 2020-02-15 03:11:27 +0000 |
---|---|---|
committer | android-build-team Robot <android-build-team-robot@google.com> | 2020-02-15 03:11:27 +0000 |
commit | d941612150424f9070fb6a91c2e12fc4dd865500 (patch) | |
tree | 0a0f7e984d43db081c9e8f1bf104890135670b75 | |
parent | 015bfc663b5ec8c30f83bf2b21806a383ef59d27 (diff) | |
parent | 16a521333e0e8b1377de28a6fe65b92d684946e5 (diff) | |
download | platform_external_robolectric-shadows-d941612150424f9070fb6a91c2e12fc4dd865500.tar.gz platform_external_robolectric-shadows-d941612150424f9070fb6a91c2e12fc4dd865500.tar.bz2 platform_external_robolectric-shadows-d941612150424f9070fb6a91c2e12fc4dd865500.zip |
Snap for 6210127 from 16a521333e0e8b1377de28a6fe65b92d684946e5 to rvc-release
Change-Id: Ib870600ee81aff07db72fb61deb5fcae8defeb6f
-rw-r--r-- | shadows/framework/src/main/java/org/robolectric/shadows/ShadowCrossProfileApps.java | 83 | ||||
-rw-r--r-- | shadows/framework/src/main/java/org/robolectric/shadows/ShadowUserManager.java | 37 |
2 files changed, 78 insertions, 42 deletions
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowCrossProfileApps.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowCrossProfileApps.java index e35f7e92e..f54ca7126 100644 --- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowCrossProfileApps.java +++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowCrossProfileApps.java @@ -23,10 +23,12 @@ import static android.os.Build.VERSION_CODES.Q; import static android.os.Build.VERSION_CODES.R; import static com.google.common.base.Preconditions.checkNotNull; +import android.Manifest; import android.Manifest.permission; import android.annotation.NonNull; import android.annotation.RequiresPermission; import android.annotation.SystemApi; +import android.app.AppOpsManager; import android.app.AppOpsManager.Mode; import android.content.ComponentName; import android.content.Context; @@ -43,6 +45,7 @@ import android.text.TextUtils; import com.google.common.collect.ImmutableList; import com.google.common.collect.Iterables; import java.util.ArrayList; +import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; @@ -51,6 +54,8 @@ import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Set; +import java.util.stream.Collectors; + import javax.annotation.Nullable; import org.robolectric.annotation.Implementation; import org.robolectric.annotation.Implements; @@ -61,13 +66,15 @@ import org.robolectric.annotation.Resetter; public class ShadowCrossProfileApps { // BEGIN-INTERNAL + private final static String INTERACT_ACROSS_PROFILES_APPOP = AppOpsManager.permissionToOp( + Manifest.permission.INTERACT_ACROSS_PROFILES); private static final Set<String> configurableInteractAcrossProfilePackages = new HashSet<>(); // END-INTERNAL private final Set<UserHandle> targetUserProfiles = new LinkedHashSet<>(); private final List<StartedMainActivity> startedMainActivities = new ArrayList<>(); private final List<StartedActivity> startedActivities = - Collections.synchronizedList(new ArrayList<>()); + Collections.synchronizedList(new ArrayList<>()); private final Map<String, Integer> packageNameAppOpModes = new HashMap<>(); private Context context; @@ -219,19 +226,19 @@ public class ShadowCrossProfileApps { private void verifyCanAccessUser(UserHandle userHandle) { if (!targetUserProfiles.contains(userHandle)) { throw new SecurityException( - "Not allowed to access " - + userHandle - + " (did you forget to call addTargetUserProfile?)"); + "Not allowed to access " + + userHandle + + " (did you forget to call addTargetUserProfile?)"); } } private void verifyHasInteractAcrossProfilesPermission() { if (context.checkSelfPermission(permission.INTERACT_ACROSS_PROFILES) - != PackageManager.PERMISSION_GRANTED) { + != PackageManager.PERMISSION_GRANTED) { throw new SecurityException( - "Attempt to launch activity without required " - + permission.INTERACT_ACROSS_PROFILES - + " permission"); + "Attempt to launch activity without required " + + permission.INTERACT_ACROSS_PROFILES + + " permission"); } } @@ -247,37 +254,37 @@ public class ShadowCrossProfileApps { Intent launchIntent = new Intent(); if (requireMainActivity) { launchIntent - .setAction(Intent.ACTION_MAIN) - .addCategory(Intent.CATEGORY_LAUNCHER) - .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) - .setPackage(component.getPackageName()); + .setAction(Intent.ACTION_MAIN) + .addCategory(Intent.CATEGORY_LAUNCHER) + .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) + .setPackage(component.getPackageName()); } else { launchIntent.setComponent(component); } boolean existsMatchingActivity = - Iterables.any( - packageManager.queryIntentActivities( - launchIntent, MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE), - resolveInfo -> { - ActivityInfo activityInfo = resolveInfo.activityInfo; - return TextUtils.equals(activityInfo.packageName, component.getPackageName()) - && TextUtils.equals(activityInfo.name, component.getClassName()) - && activityInfo.exported; - }); + Iterables.any( + packageManager.queryIntentActivities( + launchIntent, MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE), + resolveInfo -> { + ActivityInfo activityInfo = resolveInfo.activityInfo; + return TextUtils.equals(activityInfo.packageName, component.getPackageName()) + && TextUtils.equals(activityInfo.name, component.getClassName()) + && activityInfo.exported; + }); if (!existsMatchingActivity) { throw new SecurityException( - "Attempt to launch activity without " - + " category Intent.CATEGORY_LAUNCHER or activity is not exported" - + component); + "Attempt to launch activity without " + + " category Intent.CATEGORY_LAUNCHER or activity is not exported" + + component); } } // BEGIN-INTERNAL @Implementation(minSdk = R) @RequiresPermission( - allOf={android.Manifest.permission.MANAGE_APP_OPS_MODES, - android.Manifest.permission.INTERACT_ACROSS_USERS}) + allOf={android.Manifest.permission.MANAGE_APP_OPS_MODES, + android.Manifest.permission.INTERACT_ACROSS_USERS}) protected void setInteractAcrossProfilesAppOp(String packageName, @Mode int newMode) { packageNameAppOpModes.put(packageName, newMode); } @@ -295,6 +302,24 @@ public class ShadowCrossProfileApps { configurableInteractAcrossProfilePackages.add(packageName); } + @Implementation(minSdk = R) + protected void resetInteractAcrossProfilesAppOps( + @NonNull Collection<String> previousCrossProfilePackages, + @NonNull Set<String> newCrossProfilePackages) { + + final List<String> unsetCrossProfilePackages = + previousCrossProfilePackages.stream() + .filter(packageName -> !newCrossProfilePackages.contains(packageName)) + .collect(Collectors.toList()); + + for (String packageName : unsetCrossProfilePackages) { + if (!canConfigureInteractAcrossProfiles(packageName)) { + setInteractAcrossProfilesAppOp(packageName, + AppOpsManager.opToDefaultMode(INTERACT_ACROSS_PROFILES_APPOP)); + } + } + } + @Implementation protected boolean canConfigureInteractAcrossProfiles(@NonNull String packageName) { return configurableInteractAcrossProfilePackages.contains(packageName); @@ -341,7 +366,7 @@ public class ShadowCrossProfileApps { } StartedMainActivity that = (StartedMainActivity) o; return Objects.equals(componentName, that.componentName) - && Objects.equals(userHandle, that.userHandle); + && Objects.equals(userHandle, that.userHandle); } @Override @@ -382,7 +407,7 @@ public class ShadowCrossProfileApps { } StartedActivity that = (StartedActivity) o; return Objects.equals(componentName, that.componentName) - && Objects.equals(userHandle, that.userHandle); + && Objects.equals(userHandle, that.userHandle); } @Override @@ -390,4 +415,4 @@ public class ShadowCrossProfileApps { return Objects.hash(componentName, userHandle); } } -} +}
\ No newline at end of file diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowUserManager.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowUserManager.java index d4cc6ef32..9464c2f77 100644 --- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowUserManager.java +++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowUserManager.java @@ -10,6 +10,7 @@ import static android.os.Build.VERSION_CODES.R; import static org.robolectric.shadow.api.Shadow.directlyOn; import android.Manifest.permission; +import android.annotation.UserIdInt; import android.content.Context; import android.content.pm.PackageManager; import android.content.pm.UserInfo; @@ -174,8 +175,8 @@ public class ShadowUserManager { protected boolean isManagedProfile() { if (enforcePermissions && !hasManageUsersPermission()) { throw new SecurityException( - "You need MANAGE_USERS permission to: check if specified user a " + - "managed profile outside your profile group"); + "You need MANAGE_USERS permission to: check if specified user a " + + "managed profile outside your profile group"); } return managedProfile; } @@ -277,6 +278,16 @@ public class ShadowUserManager { return userProfiles.inverse().get(serialNumber); } + /** + * @see #addProfile(int, int, String, int) + * @see #addUser(int, String, int) + */ + @Implementation + protected int getUserSerialNumber(@UserIdInt int userHandle) { + Long result = userProfiles.get(UserHandle.of(userHandle)); + return result != null ? result.intValue() : -1; + } + private boolean hasManageUsersPermission() { return context.getPackageManager().checkPermission(permission.MANAGE_USERS, context.getPackageName()) == PackageManager.PERMISSION_GRANTED; } @@ -426,8 +437,8 @@ public class ShadowUserManager { UserState state = userState.get(handle.getIdentifier()); if (state == UserState.STATE_RUNNING_LOCKED - || state == UserState.STATE_RUNNING_UNLOCKED - || state == UserState.STATE_RUNNING_UNLOCKING) { + || state == UserState.STATE_RUNNING_UNLOCKED + || state == UserState.STATE_RUNNING_UNLOCKING) { return true; } else { return false; @@ -443,9 +454,9 @@ public class ShadowUserManager { UserState state = userState.get(handle.getIdentifier()); if (state == UserState.STATE_RUNNING_LOCKED - || state == UserState.STATE_RUNNING_UNLOCKED - || state == UserState.STATE_RUNNING_UNLOCKING - || state == UserState.STATE_STOPPING) { + || state == UserState.STATE_RUNNING_UNLOCKED + || state == UserState.STATE_RUNNING_UNLOCKING + || state == UserState.STATE_STOPPING) { return true; } else { return false; @@ -533,16 +544,16 @@ public class ShadowUserManager { */ public void addUser(int id, String name, int flags) { UserHandle userHandle = - id == UserHandle.USER_SYSTEM ? Process.myUserHandle() : new UserHandle(id); + id == UserHandle.USER_SYSTEM ? Process.myUserHandle() : new UserHandle(id); addUserProfile(userHandle); setSerialNumberForUser(userHandle, (long) id); profiles.putIfAbsent(id, new ArrayList<>()); userInfoMap.put(id, new UserInfo(id, name, flags)); userPidMap.put( - id, - id == UserHandle.USER_SYSTEM - ? Process.myUid() - : id * UserHandle.PER_USER_RANGE + ShadowProcess.getRandomApplicationUid()); + id, + id == UserHandle.USER_SYSTEM + ? Process.myUid() + : id * UserHandle.PER_USER_RANGE + ShadowProcess.getRandomApplicationUid()); } @Resetter @@ -554,4 +565,4 @@ public class ShadowUserManager { userPidMap.put(UserHandle.USER_SYSTEM, Process.myUid()); } } -} +}
\ No newline at end of file |