summaryrefslogtreecommitdiff
path: root/java/src
diff options
context:
space:
mode:
author Joshua Trask <joshtrask@google.com> 2023-05-11 21:48:51 +0000
committer Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> 2023-05-11 21:48:51 +0000
commitb745811bc5e9f67af724477fb9cb0293d309c4b2 (patch)
tree4b0f1f310b934b619ca6e5ed6aaa2cf9347f64d1 /java/src
parenteb4a813cf3d4de7a6b76b863d620ffaf53a53019 (diff)
parent0c4e819245027d0babd68cc12276b3e474bc965d (diff)
Merge "Scaffolding for AnnotatedUserHandles testing." into udc-dev am: 0c4e819245
Original change: https://googleplex-android-review.googlesource.com/c/platform/packages/modules/IntentResolver/+/22963725 Change-Id: I4a0a6ff546bbd3e072f3b932b5f5616eb54c0725 Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
Diffstat (limited to 'java/src')
-rw-r--r--java/src/com/android/intentresolver/AnnotatedUserHandles.java132
-rw-r--r--java/src/com/android/intentresolver/ResolverActivity.java2
2 files changed, 102 insertions, 32 deletions
diff --git a/java/src/com/android/intentresolver/AnnotatedUserHandles.java b/java/src/com/android/intentresolver/AnnotatedUserHandles.java
index 769195ed..168f36d6 100644
--- a/java/src/com/android/intentresolver/AnnotatedUserHandles.java
+++ b/java/src/com/android/intentresolver/AnnotatedUserHandles.java
@@ -22,6 +22,8 @@ import android.app.ActivityManager;
import android.os.UserHandle;
import android.os.UserManager;
+import androidx.annotation.VisibleForTesting;
+
/**
* Helper class to precompute the (immutable) designations of various user handles in the system
* that may contribute to the current Sharesheet session.
@@ -78,28 +80,74 @@ public final class AnnotatedUserHandles {
*/
public final UserHandle tabOwnerUserHandleForLaunch;
- public AnnotatedUserHandles(Activity forShareActivity) {
- userIdOfCallingApp = forShareActivity.getLaunchedFromUid();
- if ((userIdOfCallingApp < 0) || UserHandle.isIsolated(userIdOfCallingApp)) {
- throw new SecurityException("Can't start a resolver from uid " + userIdOfCallingApp);
- }
-
- // TODO: integrate logic for `ResolverActivity.EXTRA_CALLING_USER`.
- userHandleSharesheetLaunchedAs = UserHandle.of(UserHandle.myUserId());
+ /** Compute all handle designations for a new Sharesheet session in the specified activity. */
+ public static AnnotatedUserHandles forShareActivity(Activity shareActivity) {
+ // TODO: consider integrating logic for `ResolverActivity.EXTRA_CALLING_USER`?
+ UserHandle userHandleSharesheetLaunchedAs = UserHandle.of(UserHandle.myUserId());
// ActivityManager.getCurrentUser() refers to the current Foreground user. When clone/work
// profile is active, we always make the personal tab from the foreground user.
// Outside profiles, current foreground user is potentially the same as the sharesheet
// process's user (UserHandle.myUserId()), so we continue to create personal tab with the
// current foreground user.
- personalProfileUserHandle = UserHandle.of(ActivityManager.getCurrentUser());
+ UserHandle personalProfileUserHandle = UserHandle.of(ActivityManager.getCurrentUser());
+
+ UserManager userManager = shareActivity.getSystemService(UserManager.class);
+
+ return newBuilder()
+ .setUserIdOfCallingApp(shareActivity.getLaunchedFromUid())
+ .setUserHandleSharesheetLaunchedAs(userHandleSharesheetLaunchedAs)
+ .setPersonalProfileUserHandle(personalProfileUserHandle)
+ .setWorkProfileUserHandle(
+ getWorkProfileForUser(userManager, personalProfileUserHandle))
+ .setCloneProfileUserHandle(
+ getCloneProfileForUser(userManager, personalProfileUserHandle))
+ .build();
+ }
+
+ @VisibleForTesting static Builder newBuilder() {
+ return new Builder();
+ }
+
+ /**
+ * Returns the {@link UserHandle} to use when querying resolutions for intents in a
+ * {@link ResolverListController} configured for the provided {@code userHandle}.
+ */
+ public UserHandle getQueryIntentsUser(UserHandle userHandle) {
+ // In case launching app is in clonedProfile, and we are building the personal tab, intent
+ // resolution will be attempted as clonedUser instead of user 0. This is because intent
+ // resolution from user 0 and clonedUser is not guaranteed to return same results.
+ // We do not care about the case when personal adapter is started with non-root user
+ // (secondary user case), as clone profile is guaranteed to be non-active in that case.
+ UserHandle queryIntentsUser = userHandle;
+ if (isLaunchedAsCloneProfile() && userHandle.equals(personalProfileUserHandle)) {
+ queryIntentsUser = cloneProfileUserHandle;
+ }
+ return queryIntentsUser;
+ }
+
+ private Boolean isLaunchedAsCloneProfile() {
+ return userHandleSharesheetLaunchedAs.equals(cloneProfileUserHandle);
+ }
- UserManager userManager = forShareActivity.getSystemService(UserManager.class);
- workProfileUserHandle = getWorkProfileForUser(userManager, personalProfileUserHandle);
- cloneProfileUserHandle = getCloneProfileForUser(userManager, personalProfileUserHandle);
+ private AnnotatedUserHandles(
+ int userIdOfCallingApp,
+ UserHandle userHandleSharesheetLaunchedAs,
+ UserHandle personalProfileUserHandle,
+ @Nullable UserHandle workProfileUserHandle,
+ @Nullable UserHandle cloneProfileUserHandle) {
+ if ((userIdOfCallingApp < 0) || UserHandle.isIsolated(userIdOfCallingApp)) {
+ throw new SecurityException("Can't start a resolver from uid " + userIdOfCallingApp);
+ }
- tabOwnerUserHandleForLaunch = (userHandleSharesheetLaunchedAs == workProfileUserHandle)
- ? workProfileUserHandle : personalProfileUserHandle;
+ this.userIdOfCallingApp = userIdOfCallingApp;
+ this.userHandleSharesheetLaunchedAs = userHandleSharesheetLaunchedAs;
+ this.personalProfileUserHandle = personalProfileUserHandle;
+ this.workProfileUserHandle = workProfileUserHandle;
+ this.cloneProfileUserHandle = cloneProfileUserHandle;
+ this.tabOwnerUserHandleForLaunch =
+ (userHandleSharesheetLaunchedAs == workProfileUserHandle)
+ ? workProfileUserHandle : personalProfileUserHandle;
}
@Nullable
@@ -124,24 +172,46 @@ public final class AnnotatedUserHandles {
.orElse(null);
}
- /**
- * Returns the {@link UserHandle} to use when querying resolutions for intents in a
- * {@link ResolverListController} configured for the provided {@code userHandle}.
- */
- public UserHandle getQueryIntentsUser(UserHandle userHandle) {
- // In case launching app is in clonedProfile, and we are building the personal tab, intent
- // resolution will be attempted as clonedUser instead of user 0. This is because intent
- // resolution from user 0 and clonedUser is not guaranteed to return same results.
- // We do not care about the case when personal adapter is started with non-root user
- // (secondary user case), as clone profile is guaranteed to be non-active in that case.
- UserHandle queryIntentsUser = userHandle;
- if (isLaunchedAsCloneProfile() && userHandle.equals(personalProfileUserHandle)) {
- queryIntentsUser = cloneProfileUserHandle;
+ @VisibleForTesting
+ static class Builder {
+ private int mUserIdOfCallingApp;
+ private UserHandle mUserHandleSharesheetLaunchedAs;
+ private UserHandle mPersonalProfileUserHandle;
+ private UserHandle mWorkProfileUserHandle;
+ private UserHandle mCloneProfileUserHandle;
+
+ public Builder setUserIdOfCallingApp(int id) {
+ mUserIdOfCallingApp = id;
+ return this;
}
- return queryIntentsUser;
- }
- private Boolean isLaunchedAsCloneProfile() {
- return userHandleSharesheetLaunchedAs.equals(cloneProfileUserHandle);
+ public Builder setUserHandleSharesheetLaunchedAs(UserHandle user) {
+ mUserHandleSharesheetLaunchedAs = user;
+ return this;
+ }
+
+ public Builder setPersonalProfileUserHandle(UserHandle user) {
+ mPersonalProfileUserHandle = user;
+ return this;
+ }
+
+ public Builder setWorkProfileUserHandle(UserHandle user) {
+ mWorkProfileUserHandle = user;
+ return this;
+ }
+
+ public Builder setCloneProfileUserHandle(UserHandle user) {
+ mCloneProfileUserHandle = user;
+ return this;
+ }
+
+ public AnnotatedUserHandles build() {
+ return new AnnotatedUserHandles(
+ mUserIdOfCallingApp,
+ mUserHandleSharesheetLaunchedAs,
+ mPersonalProfileUserHandle,
+ mWorkProfileUserHandle,
+ mCloneProfileUserHandle);
+ }
}
}
diff --git a/java/src/com/android/intentresolver/ResolverActivity.java b/java/src/com/android/intentresolver/ResolverActivity.java
index aea6c2c9..ced7bf58 100644
--- a/java/src/com/android/intentresolver/ResolverActivity.java
+++ b/java/src/com/android/intentresolver/ResolverActivity.java
@@ -228,7 +228,7 @@ public class ResolverActivity extends FragmentActivity implements
// new component whose lifecycle is limited to the "created" Activity (so that we can just hold
// the annotations as a `final` ivar, which is a better way to show immutability).
private Supplier<AnnotatedUserHandles> mLazyAnnotatedUserHandles = () -> {
- final AnnotatedUserHandles result = new AnnotatedUserHandles(this);
+ final AnnotatedUserHandles result = AnnotatedUserHandles.forShareActivity(this);
mLazyAnnotatedUserHandles = () -> result;
return result;
};