@Implements(value=android.content.pm.CrossProfileApps.class, minSdk=28) public class ShadowCrossProfileApps extends Object
CrossProfileApps
.Modifier and Type | Class | Description |
---|---|---|
static class |
ShadowCrossProfileApps.StartedActivity |
Container object to hold parameters passed to
startMainActivity(ComponentName,
UserHandle) or startActivity(ComponentName, UserHandle) . |
static class |
ShadowCrossProfileApps.StartedMainActivity |
Deprecated.
Use
peekNextStartedActivity() and ShadowCrossProfileApps.StartedActivity instead. |
Constructor | Description |
---|---|
ShadowCrossProfileApps() |
Modifier and Type | Method | Description |
---|---|---|
protected void |
__constructor__(Context context,
ICrossProfileApps service) |
|
void |
addTargetUserProfile(UserHandle userHandle) |
Adds
userHandle to the list of accessible handles. |
protected boolean |
canConfigureInteractAcrossProfiles(String packageName) |
Unlike the real system, we will assume a package can always configure its own cross profile
interaction.
|
protected boolean |
canInteractAcrossProfiles() |
Checks if the current application can interact across profile.
|
protected boolean |
canRequestInteractAcrossProfiles() |
Returns whether the calling package can request to navigate the user to the relevant settings
page to request user consent to interact across profiles.
|
void |
clearNextStartedActivities() |
Clears all records of
ShadowCrossProfileApps.StartedActivity s from calls to CrossProfileApps.startActivity(ComponentName, UserHandle) or CrossProfileApps.startMainActivity(ComponentName, UserHandle) . |
void |
clearTargetUserProfiles() |
Clears the list of accessible handles.
|
protected Intent |
createRequestInteractAcrossProfilesIntent() |
Returns an intent with the same action as the one returned by system when requesting the same.
|
ShadowCrossProfileApps.StartedActivity |
getNextStartedActivity() |
Consumes the most recent
ComponentName , UserHandle pair started by CrossProfileApps.startMainActivity(ComponentName, UserHandle) or CrossProfileApps.startActivity(ComponentName, UserHandle) , and returns it wrapped in ShadowCrossProfileApps.StartedActivity . |
protected Drawable |
getProfileSwitchingIconDrawable(UserHandle userHandle) |
Returns a
Drawable that can be shown for profile switching, which is guaranteed to
always be the same for a particular user and to be distinct between users. |
protected CharSequence |
getProfileSwitchingLabel(UserHandle userHandle) |
Returns a
CharSequence that can be shown as a label for profile switching, which is
guaranteed to always be the same for a particular user and to be distinct between users. |
protected List<UserHandle> |
getTargetUserProfiles() |
Returns a list of
UserHandle s currently accessible. |
boolean |
isRequestInteractAcrossProfilesIntent(Intent intent) |
Checks whether the given intent will redirect toward the screen allowing the user to change the
interact across profiles AppOps.
|
ShadowCrossProfileApps.StartedActivity |
peekNextStartedActivity() |
Returns the most recent
ComponentName , UserHandle pair started by CrossProfileApps.startMainActivity(ComponentName, UserHandle) or CrossProfileApps.startActivity(ComponentName, UserHandle) , wrapped in ShadowCrossProfileApps.StartedActivity . |
ShadowCrossProfileApps.StartedMainActivity |
peekNextStartedMainActivity() |
Deprecated.
Use
peekNextStartedActivity() instead. |
void |
removeTargetUserProfile(UserHandle userHandle) |
Removes
userHandle from the list of accessible handles, if present. |
void |
setHasRequestedInteractAcrossProfiles(boolean value) |
Sets whether or not the current application has requested the interact across profile
permission in its manifest.
|
void |
setInteractAcrossProfilesAppOp(int newMode) |
Forces the {code interact_across_profile} AppOps for the current package.
|
protected void |
setInteractAcrossProfilesAppOp(String packageName,
int newMode) |
Checks permission and changes the AppOps value stored in
ShadowCrossProfileApps . |
protected void |
startActivity(ComponentName componentName,
UserHandle targetUser) |
Simulates starting the activity specified in the specified profile, performing the same
security checks done by the real
CrossProfileApps . |
protected void |
startMainActivity(ComponentName componentName,
UserHandle targetUser) |
Simulates starting the main activity specified in the specified profile, performing the same
security checks done by the real
CrossProfileApps . |
protected void |
verifyHasInteractAcrossProfilesPermission() |
Ensure the current package has the permission to interact across profiles.
|
@Implementation protected void __constructor__(Context context, ICrossProfileApps service)
@Implementation protected List<UserHandle> getTargetUserProfiles()
UserHandle
s currently accessible. This list is populated from calls
to addTargetUserProfile(UserHandle)
.@Implementation protected Drawable getProfileSwitchingIconDrawable(UserHandle userHandle)
Drawable
that can be shown for profile switching, which is guaranteed to
always be the same for a particular user and to be distinct between users.@Implementation protected CharSequence getProfileSwitchingLabel(UserHandle userHandle)
CharSequence
that can be shown as a label for profile switching, which is
guaranteed to always be the same for a particular user and to be distinct between users.@Implementation protected void startMainActivity(ComponentName componentName, UserHandle targetUser)
CrossProfileApps
.
The most recent main activity started can be queried by peekNextStartedActivity()
()}.
@Implementation(minSdk=29) protected void startActivity(ComponentName componentName, UserHandle targetUser)
CrossProfileApps
.
The most recent main activity started can be queried by peekNextStartedActivity()
()}.
public void addTargetUserProfile(UserHandle userHandle)
userHandle
to the list of accessible handles.public void removeTargetUserProfile(UserHandle userHandle)
userHandle
from the list of accessible handles, if present.public void clearTargetUserProfiles()
@Nullable @Deprecated public ShadowCrossProfileApps.StartedMainActivity peekNextStartedMainActivity()
peekNextStartedActivity()
instead.ComponentName
, UserHandle
pair started by CrossProfileApps.startMainActivity(ComponentName, UserHandle)
, wrapped in ShadowCrossProfileApps.StartedMainActivity
.@Nullable public ShadowCrossProfileApps.StartedActivity peekNextStartedActivity()
ComponentName
, UserHandle
pair started by CrossProfileApps.startMainActivity(ComponentName, UserHandle)
or CrossProfileApps.startActivity(ComponentName, UserHandle)
, wrapped in ShadowCrossProfileApps.StartedActivity
.@Nullable public ShadowCrossProfileApps.StartedActivity getNextStartedActivity()
ComponentName
, UserHandle
pair started by CrossProfileApps.startMainActivity(ComponentName, UserHandle)
or CrossProfileApps.startActivity(ComponentName, UserHandle)
, and returns it wrapped in ShadowCrossProfileApps.StartedActivity
.public void clearNextStartedActivities()
ShadowCrossProfileApps.StartedActivity
s from calls to CrossProfileApps.startActivity(ComponentName, UserHandle)
or CrossProfileApps.startMainActivity(ComponentName, UserHandle)
.protected void verifyHasInteractAcrossProfilesPermission()
@Implementation(minSdk=30) protected boolean canInteractAcrossProfiles()
This checks for the existence of a target user profile, and if the app has
INTERACT_ACROSS_USERS, INTERACT_ACROSS_USERS_FULL or INTERACT_ACROSS_PROFILES permission.
Importantly, the interact_across_profiles
AppOps is only checked through the value set
by setInteractAcrossProfilesAppOp(int)
or by setInteractAcrossProfilesAppOp(String, int)
, if the application has the needed permissions.
@Implementation(minSdk=30) protected boolean canRequestInteractAcrossProfiles()
This checks for the existence of a target user profile, and if the app has requested the
INTERACT_ACROSS_PROFILES permission in its manifest. As Robolectric doesn't interpret the
permissions in the manifest, whether or not the app has requested this is defined by setHasRequestedInteractAcrossProfiles(boolean)
.
If the test uses setInteractAcrossProfilesAppOp(int)
, it implies the app has
requested the AppOps.
In short, compared to canInteractAcrossProfiles()
, it doesn't check if the user has
the AppOps or not.
public void setHasRequestedInteractAcrossProfiles(boolean value)
@Implementation(minSdk=30) protected Intent createRequestInteractAcrossProfilesIntent()
Note: Currently, the system will also set the package name as a URI, but as this is not specified in the main doc, we shouldn't rely on it. The purpose is only to make an intent can that be recognised in a test.
SecurityException
- if this is called while CrossProfileApps.canRequestInteractAcrossProfiles()
returns false.public boolean isRequestInteractAcrossProfilesIntent(Intent intent)
public void setInteractAcrossProfilesAppOp(int newMode)
If the value changes, this also sends the CrossProfileApps.ACTION_CAN_INTERACT_ACROSS_PROFILES_CHANGED
broadcast.
@Implementation(minSdk=30) protected void setInteractAcrossProfilesAppOp(String packageName, int newMode)
ShadowCrossProfileApps
.
In the real implementation, if there is no target profile, the AppOps is not changed, as it will be set during the profile's initialization. The real implementation also really changes the AppOps for all profiles the package is installed in.
@Implementation(minSdk=30) protected boolean canConfigureInteractAcrossProfiles(String packageName)