diff options
| author | 2023-05-11 21:48:51 +0000 | |
|---|---|---|
| committer | 2023-05-11 21:48:51 +0000 | |
| commit | b745811bc5e9f67af724477fb9cb0293d309c4b2 (patch) | |
| tree | 4b0f1f310b934b619ca6e5ed6aaa2cf9347f64d1 /java/src | |
| parent | eb4a813cf3d4de7a6b76b863d620ffaf53a53019 (diff) | |
| parent | 0c4e819245027d0babd68cc12276b3e474bc965d (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.java | 132 | ||||
| -rw-r--r-- | java/src/com/android/intentresolver/ResolverActivity.java | 2 |
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; }; |