aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorandroid-build-team Robot <android-build-team-robot@google.com>2020-02-15 03:11:27 +0000
committerandroid-build-team Robot <android-build-team-robot@google.com>2020-02-15 03:11:27 +0000
commitd941612150424f9070fb6a91c2e12fc4dd865500 (patch)
tree0a0f7e984d43db081c9e8f1bf104890135670b75
parent015bfc663b5ec8c30f83bf2b21806a383ef59d27 (diff)
parent16a521333e0e8b1377de28a6fe65b92d684946e5 (diff)
downloadplatform_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.java83
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowUserManager.java37
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