summaryrefslogtreecommitdiff
path: root/java/src/com
diff options
context:
space:
mode:
author Govinda Wasserman <gwasserman@google.com> 2023-10-31 12:39:10 -0400
committer Govinda Wasserman <gwasserman@google.com> 2023-10-31 13:08:10 -0400
commit29f2a6eaec0c37ac4d92bdb0b049447d0d00b70d (patch)
treede2b8c5d6f6bee5725b4ae8d15b4af5682ac4e29 /java/src/com
parent505d41c41d1520f3e84f2cc13e53343d88e9f692 (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')
-rw-r--r--java/src/com/android/intentresolver/v2/ActivityLogic.kt59
-rw-r--r--java/src/com/android/intentresolver/v2/ChooserActivity.java6
-rw-r--r--java/src/com/android/intentresolver/v2/ChooserActivityLogic.kt11
-rw-r--r--java/src/com/android/intentresolver/v2/ResolverActivity.java49
-rw-r--r--java/src/com/android/intentresolver/v2/ResolverActivityLogic.kt11
-rw-r--r--java/src/com/android/intentresolver/v2/util/MutableLazy.kt36
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)