diff options
| author | 2023-10-31 12:39:10 -0400 | |
|---|---|---|
| committer | 2023-10-31 13:08:10 -0400 | |
| commit | 29f2a6eaec0c37ac4d92bdb0b049447d0d00b70d (patch) | |
| tree | de2b8c5d6f6bee5725b4ae8d15b4af5682ac4e29 /java/src/com | |
| parent | 505d41c41d1520f3e84f2cc13e53343d88e9f692 (diff) | |
Moves theme and profile switch message to ActivityLogic
Test: atest com.android.intentresolver.v2
BUG:302113519
Change-Id: Idb7a269c55b9315646127c5b82e10edc48fbe230
Diffstat (limited to 'java/src/com')
6 files changed, 123 insertions, 49 deletions
diff --git a/java/src/com/android/intentresolver/v2/ActivityLogic.kt b/java/src/com/android/intentresolver/v2/ActivityLogic.kt index 0613882e..a3e90033 100644 --- a/java/src/com/android/intentresolver/v2/ActivityLogic.kt +++ b/java/src/com/android/intentresolver/v2/ActivityLogic.kt @@ -1,10 +1,16 @@ package com.android.intentresolver.v2 import android.app.Activity +import android.app.admin.DevicePolicyManager +import android.app.admin.DevicePolicyResources.Strings.Core.FORWARD_INTENT_TO_PERSONAL +import android.app.admin.DevicePolicyResources.Strings.Core.FORWARD_INTENT_TO_WORK import android.content.Context import android.content.Intent import android.net.Uri +import android.os.UserHandle +import android.os.UserManager import androidx.activity.ComponentActivity +import com.android.intentresolver.R import com.android.intentresolver.icons.TargetDataLoader /** @@ -30,11 +36,20 @@ interface ActivityLogic : CommonActivityLogic { val supportsAlwaysUseOption: Boolean /** Fetches display info for processed candidates. */ val targetDataLoader: TargetDataLoader + /** The theme to use. */ + val themeResId: Int + /** + * Message showing that intent is forwarded from managed profile to owner or other way around. + */ + val profileSwitchMessage: String? /** * Called after Activity superclass creation, but before any other onCreate logic is performed. */ fun preInitialization() + + /** Sets [profileSwitchMessage] to null */ + fun clearProfileSwitchMessage() } /** @@ -46,6 +61,13 @@ interface CommonActivityLogic { val activity: ComponentActivity /** The name of the referring package. */ val referrerPackageName: String? + /** User manager system service. */ + val userManager: UserManager + /** Device policy manager system service. */ + val devicePolicyManager: DevicePolicyManager + + /** Returns display message indicating intent forwarding or null if not intent forwarding. */ + fun forwardMessageFor(intent: Intent): String? // TODO: For some reason the IDE complains about getting Activity fields from a // ComponentActivity. These are a band-aid until the bug is fixed and should be removed when @@ -74,6 +96,43 @@ class CommonActivityLogicImpl(activityProvider: () -> ComponentActivity) : Commo } } + override val userManager: UserManager by lazy { + activity.context.getSystemService(Context.USER_SERVICE) as UserManager + } + + override val devicePolicyManager: DevicePolicyManager by lazy { + activity.context.getSystemService(DevicePolicyManager::class.java)!! + } + + private val forwardToPersonalMessage: String? by lazy { + devicePolicyManager.resources.getString(FORWARD_INTENT_TO_PERSONAL) { + activity.context.getString(R.string.forward_intent_to_owner) + } + } + + private val forwardToWorkMessage: String? by lazy { + devicePolicyManager.resources.getString(FORWARD_INTENT_TO_WORK) { + activity.context.getString(R.string.forward_intent_to_work) + } + } + + override fun forwardMessageFor(intent: Intent): String? { + val contentUserHint = intent.contentUserHint + if ( + contentUserHint != UserHandle.USER_CURRENT && contentUserHint != UserHandle.myUserId() + ) { + val originUserInfo = userManager.getUserInfo(contentUserHint) + val originIsManaged = originUserInfo?.isManagedProfile ?: false + val targetIsManaged = userManager.isManagedProfile + return when { + originIsManaged && !targetIsManaged -> forwardToPersonalMessage + !originIsManaged && targetIsManaged -> forwardToWorkMessage + else -> null + } + } + return null + } + companion object { private const val ANDROID_APP_URI_SCHEME = "android-app" } diff --git a/java/src/com/android/intentresolver/v2/ChooserActivity.java b/java/src/com/android/intentresolver/v2/ChooserActivity.java index d2dabfb3..ef2d68bc 100644 --- a/java/src/com/android/intentresolver/v2/ChooserActivity.java +++ b/java/src/com/android/intentresolver/v2/ChooserActivity.java @@ -291,6 +291,7 @@ public class ChooserActivity extends Hilt_ChooserActivity implements // Skip initializing any additional resources. return; } + setTheme(mLogic.getThemeResId()); getEventLog().logSharesheetTriggered(); @@ -379,11 +380,6 @@ public class ChooserActivity extends Hilt_ChooserActivity implements return requireNonNull(getChooserRequest()); } - @Override - protected int appliedThemeResId() { - return R.style.Theme_DeviceDefault_Chooser; - } - private void createProfileRecords( AppPredictorFactory factory, IntentFilter targetIntentFilter) { UserHandle mainUserHandle = getAnnotatedUserHandles().personalProfileUserHandle; diff --git a/java/src/com/android/intentresolver/v2/ChooserActivityLogic.kt b/java/src/com/android/intentresolver/v2/ChooserActivityLogic.kt index 1db3f407..da0fa033 100644 --- a/java/src/com/android/intentresolver/v2/ChooserActivityLogic.kt +++ b/java/src/com/android/intentresolver/v2/ChooserActivityLogic.kt @@ -5,7 +5,9 @@ import android.content.Intent import android.util.Log import androidx.activity.ComponentActivity import com.android.intentresolver.ChooserRequestParameters +import com.android.intentresolver.R import com.android.intentresolver.icons.TargetDataLoader +import com.android.intentresolver.v2.util.mutableLazy /** Activity logic for [ChooserActivity]. */ class ChooserActivityLogic( @@ -37,6 +39,11 @@ class ChooserActivityLogic( override val targetDataLoader: TargetDataLoader by lazy { targetDataLoaderProvider() } + override val themeResId: Int = R.style.Theme_DeviceDefault_Chooser + + private val _profileSwitchMessage = mutableLazy { forwardMessageFor(targetIntent) } + override val profileSwitchMessage: String? by _profileSwitchMessage + val chooserRequestParameters: ChooserRequestParameters? by lazy { try { ChooserRequestParameters( @@ -53,4 +60,8 @@ class ChooserActivityLogic( override fun preInitialization() { onPreInitialization() } + + override fun clearProfileSwitchMessage() { + _profileSwitchMessage.setLazy(null) + } } diff --git a/java/src/com/android/intentresolver/v2/ResolverActivity.java b/java/src/com/android/intentresolver/v2/ResolverActivity.java index 1c9ee99d..6fdc2df3 100644 --- a/java/src/com/android/intentresolver/v2/ResolverActivity.java +++ b/java/src/com/android/intentresolver/v2/ResolverActivity.java @@ -17,8 +17,6 @@ package com.android.intentresolver.v2; import static android.Manifest.permission.INTERACT_ACROSS_PROFILES; -import static android.app.admin.DevicePolicyResources.Strings.Core.FORWARD_INTENT_TO_PERSONAL; -import static android.app.admin.DevicePolicyResources.Strings.Core.FORWARD_INTENT_TO_WORK; import static android.app.admin.DevicePolicyResources.Strings.Core.RESOLVER_CANT_ACCESS_PERSONAL; import static android.app.admin.DevicePolicyResources.Strings.Core.RESOLVER_CANT_ACCESS_WORK; import static android.app.admin.DevicePolicyResources.Strings.Core.RESOLVER_CROSS_PROFILE_BLOCKED_TITLE; @@ -157,7 +155,6 @@ public class ResolverActivity extends FragmentActivity implements private Button mOnceButton; protected View mProfileView; private int mLastSelected = AbsListView.INVALID_POSITION; - private String mProfileSwitchMessage; private int mLayoutId; @VisibleForTesting protected final ArrayList<Intent> mIntents = new ArrayList<>(); @@ -337,6 +334,7 @@ public class ResolverActivity extends FragmentActivity implements // Skip initializing any additional resources. return; } + setTheme(mLogic.getThemeResId()); mLogic.preInitialization(); init( mLogic.getTargetIntent(), @@ -354,12 +352,6 @@ public class ResolverActivity extends FragmentActivity implements Intent[] initialIntents, TargetDataLoader targetDataLoader ) { - setTheme(appliedThemeResId()); - - // Determine whether we should show that intent is forwarded - // from managed profile to owner or other way around. - setProfileSwitchMessage(intent.getContentUserHint()); - // Force computation of user handle annotations in order to validate the caller ID. (See the // associated TODO comment to explain why this is structured as a lazy computation.) AnnotatedUserHandles unusedReferenceToHandles = mLazyAnnotatedUserHandles.get(); @@ -501,10 +493,6 @@ public class ResolverActivity extends FragmentActivity implements getAnnotatedUserHandles().tabOwnerUserHandleForLaunch); } - protected int appliedThemeResId() { - return R.style.Theme_DeviceDefault_Resolver; - } - /** * Numerous layouts are supported, each with optional ViewGroups. * Make sure the inset gets added to the correct View, using @@ -1244,7 +1232,7 @@ public class ResolverActivity extends FragmentActivity implements } // Do not show the profile switch message anymore. - mProfileSwitchMessage = null; + mLogic.clearProfileSwitchMessage(); onTargetSelected(dri, false); finish(); @@ -1331,34 +1319,6 @@ public class ResolverActivity extends FragmentActivity implements } } - private void setProfileSwitchMessage(int contentUserHint) { - if ((contentUserHint != UserHandle.USER_CURRENT) - && (contentUserHint != UserHandle.myUserId())) { - UserManager userManager = (UserManager) getSystemService(Context.USER_SERVICE); - UserInfo originUserInfo = userManager.getUserInfo(contentUserHint); - boolean originIsManaged = originUserInfo != null ? originUserInfo.isManagedProfile() - : false; - boolean targetIsManaged = userManager.isManagedProfile(); - if (originIsManaged && !targetIsManaged) { - mProfileSwitchMessage = getForwardToPersonalMsg(); - } else if (!originIsManaged && targetIsManaged) { - mProfileSwitchMessage = getForwardToWorkMsg(); - } - } - } - - private String getForwardToPersonalMsg() { - return getSystemService(DevicePolicyManager.class).getResources().getString( - FORWARD_INTENT_TO_PERSONAL, - () -> getString(R.string.forward_intent_to_owner)); - } - - private String getForwardToWorkMsg() { - return getSystemService(DevicePolicyManager.class).getResources().getString( - FORWARD_INTENT_TO_WORK, - () -> getString(R.string.forward_intent_to_work)); - } - protected final CharSequence getTitleForAction(Intent intent, int defaultTitleRes) { final ActionTitle title = mLogic.getResolvingHome() ? ActionTitle.HOME @@ -1612,8 +1572,9 @@ public class ResolverActivity extends FragmentActivity implements } // If needed, show that intent is forwarded // from managed profile to owner or other way around. - if (mProfileSwitchMessage != null) { - Toast.makeText(this, mProfileSwitchMessage, Toast.LENGTH_LONG).show(); + String profileSwitchMessage = mLogic.getProfileSwitchMessage(); + if (profileSwitchMessage != null) { + Toast.makeText(this, profileSwitchMessage, Toast.LENGTH_LONG).show(); } try { if (cti.startAsCaller(this, options, user.getIdentifier())) { diff --git a/java/src/com/android/intentresolver/v2/ResolverActivityLogic.kt b/java/src/com/android/intentresolver/v2/ResolverActivityLogic.kt index 1d02e6c2..c8f02885 100644 --- a/java/src/com/android/intentresolver/v2/ResolverActivityLogic.kt +++ b/java/src/com/android/intentresolver/v2/ResolverActivityLogic.kt @@ -2,8 +2,10 @@ package com.android.intentresolver.v2 import android.content.Intent import androidx.activity.ComponentActivity +import com.android.intentresolver.R import com.android.intentresolver.icons.DefaultTargetDataLoader import com.android.intentresolver.icons.TargetDataLoader +import com.android.intentresolver.v2.util.mutableLazy /** Activity logic for [ResolverActivity]. */ class ResolverActivityLogic( @@ -55,7 +57,16 @@ class ResolverActivityLogic( ) } + override val themeResId: Int = R.style.Theme_DeviceDefault_Resolver + + private val _profileSwitchMessage = mutableLazy { forwardMessageFor(targetIntent) } + override val profileSwitchMessage: String? by _profileSwitchMessage + override fun preInitialization() { // Do nothing } + + override fun clearProfileSwitchMessage() { + _profileSwitchMessage.setLazy(null) + } } diff --git a/java/src/com/android/intentresolver/v2/util/MutableLazy.kt b/java/src/com/android/intentresolver/v2/util/MutableLazy.kt new file mode 100644 index 00000000..4ce9b7fd --- /dev/null +++ b/java/src/com/android/intentresolver/v2/util/MutableLazy.kt @@ -0,0 +1,36 @@ +package com.android.intentresolver.v2.util + +import java.util.concurrent.atomic.AtomicReference +import kotlin.reflect.KProperty + +/** A lazy delegate that can be changed to a new lazy or null at any time. */ +class MutableLazy<T>(initializer: () -> T?) : Lazy<T?> { + + override val value: T? + get() = lazy.get()?.value + + private var lazy: AtomicReference<Lazy<T?>?> = AtomicReference(lazy(initializer)) + + override fun isInitialized(): Boolean = lazy.get()?.isInitialized() != false + + operator fun getValue(thisRef: Any?, property: KProperty<*>): T? = + lazy.get()?.getValue(thisRef, property) + + /** Replace the existing lazy logic with the [newLazy] */ + fun setLazy(newLazy: Lazy<T?>?) { + lazy.set(newLazy) + } + + /** Replace the existing lazy logic with a [Lazy] created from the [newInitializer]. */ + fun setLazy(newInitializer: () -> T?) { + lazy.set(lazy(newInitializer)) + } + + /** Set the lazy logic to null. */ + fun clear() { + lazy.set(null) + } +} + +/** Constructs a [MutableLazy] using the given [initializer] */ +fun <T> mutableLazy(initializer: () -> T?) = MutableLazy(initializer) |