Class ShadowCrossProfileApps
@Implements(value=android.content.pm.CrossProfileApps.class, minSdk=28) public class ShadowCrossProfileApps extends Object
CrossProfileApps
.-
Nested Class Summary
Nested Classes Modifier and Type Class Description static class
ShadowCrossProfileApps.StartedActivity
Container object to hold parameters passed tostartMainActivity(ComponentName, UserHandle)
orstartActivity(ComponentName, UserHandle)
,startActivity(Intent, UserHandle, Activity)
,startActivity(Intent, UserHandle, Activity, Bundle)
.static class
ShadowCrossProfileApps.StartedMainActivity
Deprecated.UsepeekNextStartedActivity()
andShadowCrossProfileApps.StartedActivity
instead. -
Constructor Summary
Constructors Constructor Description ShadowCrossProfileApps()
-
Method Summary
Modifier and Type Method Description protected void
__constructor__(Context context, ICrossProfileApps service)
void
addTargetUserProfile(UserHandle userHandle)
AddsuserHandle
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()
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 recentComponentName
,UserHandle
pair started byCrossProfileApps.startMainActivity(ComponentName, UserHandle)
orCrossProfileApps.startActivity(ComponentName, UserHandle)
,startActivity(Intent, UserHandle, Activity)
,startActivity(Intent, UserHandle, Activity, Bundle)
, and returns it wrapped inShadowCrossProfileApps.StartedActivity
.protected Drawable
getProfileSwitchingIconDrawable(UserHandle userHandle)
Returns aDrawable
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 aCharSequence
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 ofUserHandle
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 recentComponentName
,UserHandle
pair started byCrossProfileApps.startMainActivity(ComponentName, UserHandle)
orCrossProfileApps.startActivity(ComponentName, UserHandle)
,startActivity(Intent, UserHandle, Activity)
,startActivity(Intent, UserHandle, Activity, Bundle)
, wrapped inShadowCrossProfileApps.StartedActivity
.ShadowCrossProfileApps.StartedMainActivity
peekNextStartedMainActivity()
Deprecated.UsepeekNextStartedActivity()
instead.void
removeTargetUserProfile(UserHandle userHandle)
RemovesuserHandle
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 inShadowCrossProfileApps
.protected void
startActivity(ComponentName componentName, UserHandle targetUser)
Simulates starting the activity specified in the specified profile, performing the same security checks done by the realCrossProfileApps
.protected void
startActivity(Intent intent, UserHandle targetUser, Activity activity)
Simulates starting the activity specified in the specified profile, performing the same security checks done by the realCrossProfileApps
.protected void
startActivity(Intent intent, UserHandle targetUser, Activity activity, Bundle options)
Simulates starting the activity specified in the specified profile, performing the same security checks done by the realCrossProfileApps
.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 realCrossProfileApps
.protected void
verifyHasInteractAcrossProfilesPermission()
Ensure the current package has the permission to interact across profiles.
-
Constructor Details
-
ShadowCrossProfileApps
public ShadowCrossProfileApps()
-
-
Method Details
-
__constructor__
-
getTargetUserProfiles
Returns a list ofUserHandle
s currently accessible. This list is populated from calls toaddTargetUserProfile(UserHandle)
. -
getProfileSwitchingIconDrawable
Returns aDrawable
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. -
getProfileSwitchingLabel
Returns aCharSequence
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. -
startMainActivity
@Implementation 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 realCrossProfileApps
.The most recent main activity started can be queried by
peekNextStartedActivity()
. -
startActivity
@Implementation(minSdk=29) protected void startActivity(ComponentName componentName, UserHandle targetUser)Simulates starting the activity specified in the specified profile, performing the same security checks done by the realCrossProfileApps
.The most recent main activity started can be queried by
peekNextStartedActivity()
. -
startActivity
@Implementation(minSdk=30) protected void startActivity(Intent intent, UserHandle targetUser, @Nullable Activity activity)Simulates starting the activity specified in the specified profile, performing the same security checks done by the realCrossProfileApps
.The most recent main activity started can be queried by
peekNextStartedActivity()
. -
startActivity
@Implementation(minSdk=30) protected void startActivity(Intent intent, UserHandle targetUser, @Nullable Activity activity, @Nullable Bundle options)Simulates starting the activity specified in the specified profile, performing the same security checks done by the realCrossProfileApps
.The most recent main activity started can be queried by
peekNextStartedActivity()
. -
addTargetUserProfile
AddsuserHandle
to the list of accessible handles. -
removeTargetUserProfile
RemovesuserHandle
from the list of accessible handles, if present. -
clearTargetUserProfiles
public void clearTargetUserProfiles()Clears the list of accessible handles. -
peekNextStartedMainActivity
@Nullable @Deprecated public ShadowCrossProfileApps.StartedMainActivity peekNextStartedMainActivity()Deprecated.UsepeekNextStartedActivity()
instead.Returns the most recentComponentName
,UserHandle
pair started byCrossProfileApps.startMainActivity(ComponentName, UserHandle)
, wrapped inShadowCrossProfileApps.StartedMainActivity
. -
peekNextStartedActivity
Returns the most recentComponentName
,UserHandle
pair started byCrossProfileApps.startMainActivity(ComponentName, UserHandle)
orCrossProfileApps.startActivity(ComponentName, UserHandle)
,startActivity(Intent, UserHandle, Activity)
,startActivity(Intent, UserHandle, Activity, Bundle)
, wrapped inShadowCrossProfileApps.StartedActivity
. -
getNextStartedActivity
Consumes the most recentComponentName
,UserHandle
pair started byCrossProfileApps.startMainActivity(ComponentName, UserHandle)
orCrossProfileApps.startActivity(ComponentName, UserHandle)
,startActivity(Intent, UserHandle, Activity)
,startActivity(Intent, UserHandle, Activity, Bundle)
, and returns it wrapped inShadowCrossProfileApps.StartedActivity
. -
clearNextStartedActivities
public void clearNextStartedActivities() -
verifyHasInteractAcrossProfilesPermission
protected void verifyHasInteractAcrossProfilesPermission()Ensure the current package has the permission to interact across profiles. -
canInteractAcrossProfiles
Checks if the current application can interact across profile.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 bysetInteractAcrossProfilesAppOp(int)
or bysetInteractAcrossProfilesAppOp(String, int)
, if the application has the needed permissions. -
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.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. -
setHasRequestedInteractAcrossProfiles
public void setHasRequestedInteractAcrossProfiles(boolean value)Sets whether or not the current application has requested the interact across profile permission in its manifest. -
createRequestInteractAcrossProfilesIntent
Returns an intent with the same action as the one returned by system when requesting the same.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.
- Throws:
SecurityException
- if this is called whileCrossProfileApps.canRequestInteractAcrossProfiles()
returns false.
-
isRequestInteractAcrossProfilesIntent
Checks whether the given intent will redirect toward the screen allowing the user to change the interact across profiles AppOps. -
setInteractAcrossProfilesAppOp
public void setInteractAcrossProfilesAppOp(int newMode)Forces the {code interact_across_profile} AppOps for the current package.If the value changes, this also sends the
CrossProfileApps.ACTION_CAN_INTERACT_ACROSS_PROFILES_CHANGED
broadcast. -
setInteractAcrossProfilesAppOp
@Implementation(minSdk=30) protected void setInteractAcrossProfilesAppOp(String packageName, int newMode)Checks permission and changes the AppOps value stored inShadowCrossProfileApps
.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.
-
canConfigureInteractAcrossProfiles
@Implementation(minSdk=30) protected boolean canConfigureInteractAcrossProfiles(String packageName)Unlike the real system, we will assume a package can always configure its own cross profile interaction.
-