summaryrefslogtreecommitdiff
path: root/PermissionController/src/com/android/permissioncontroller/role
diff options
context:
space:
mode:
authorTreeHugger Robot <treehugger-gerrit@google.com>2022-11-04 20:02:30 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2022-11-04 20:02:30 +0000
commit2941dd6afabfc20d41b7493a656ea55482c6789f (patch)
treed43a3ba6befa99c0b4fc1ba9b3088ee38d3c15f0 /PermissionController/src/com/android/permissioncontroller/role
parent892ecbd6fc3cc5038a894ea9930432aef886a2ee (diff)
parentfdfff7df88617d67f22af4b581258f02205d8a19 (diff)
downloadPermission-2941dd6afabfc20d41b7493a656ea55482c6789f.tar.gz
Merge "Extract UI references from role model code to enable move to system server"
Diffstat (limited to 'PermissionController/src/com/android/permissioncontroller/role')
-rw-r--r--PermissionController/src/com/android/permissioncontroller/role/Role.md3
-rw-r--r--PermissionController/src/com/android/permissioncontroller/role/model/AssistantRoleBehavior.java29
-rw-r--r--PermissionController/src/com/android/permissioncontroller/role/model/BrowserRoleBehavior.java7
-rw-r--r--PermissionController/src/com/android/permissioncontroller/role/model/DialerRoleBehavior.java33
-rw-r--r--PermissionController/src/com/android/permissioncontroller/role/model/EmergencyRoleBehavior.java14
-rw-r--r--PermissionController/src/com/android/permissioncontroller/role/model/HomeRoleBehavior.java81
-rw-r--r--PermissionController/src/com/android/permissioncontroller/role/model/Role.java120
-rw-r--r--PermissionController/src/com/android/permissioncontroller/role/model/RoleBehavior.java55
-rw-r--r--PermissionController/src/com/android/permissioncontroller/role/model/RoleParser.java5
-rw-r--r--PermissionController/src/com/android/permissioncontroller/role/model/SmsRoleBehavior.java15
-rw-r--r--PermissionController/src/com/android/permissioncontroller/role/service/RoleControllerServiceImpl.java8
-rw-r--r--PermissionController/src/com/android/permissioncontroller/role/service/RoleSearchIndexablesProvider.java4
-rw-r--r--PermissionController/src/com/android/permissioncontroller/role/ui/DefaultAppActivity.java4
-rw-r--r--PermissionController/src/com/android/permissioncontroller/role/ui/DefaultAppChildFragment.java9
-rw-r--r--PermissionController/src/com/android/permissioncontroller/role/ui/DefaultAppListChildFragment.java7
-rw-r--r--PermissionController/src/com/android/permissioncontroller/role/ui/RequestRoleActivity.java3
-rw-r--r--PermissionController/src/com/android/permissioncontroller/role/ui/RoleListLiveData.java3
-rw-r--r--PermissionController/src/com/android/permissioncontroller/role/ui/RoleLiveData.java4
-rw-r--r--PermissionController/src/com/android/permissioncontroller/role/ui/behavior/AssistantRoleUiBehavior.java63
-rw-r--r--PermissionController/src/com/android/permissioncontroller/role/ui/behavior/BrowserRoleUiBehavior.java37
-rw-r--r--PermissionController/src/com/android/permissioncontroller/role/ui/behavior/DialerRoleUiBehavior.java65
-rw-r--r--PermissionController/src/com/android/permissioncontroller/role/ui/behavior/EmergencyRoleUiBehavior.java47
-rw-r--r--PermissionController/src/com/android/permissioncontroller/role/ui/behavior/HomeRoleUiBehavior.java114
-rw-r--r--PermissionController/src/com/android/permissioncontroller/role/ui/behavior/RoleUiBehavior.java121
-rw-r--r--PermissionController/src/com/android/permissioncontroller/role/ui/behavior/SmsRoleUiBehavior.java47
-rw-r--r--PermissionController/src/com/android/permissioncontroller/role/ui/specialappaccess/SpecialAppAccessActivity.java4
-rw-r--r--PermissionController/src/com/android/permissioncontroller/role/ui/specialappaccess/SpecialAppAccessChildFragment.java6
-rw-r--r--PermissionController/src/com/android/permissioncontroller/role/ui/specialappaccess/SpecialAppAccessListChildFragment.java8
-rw-r--r--PermissionController/src/com/android/permissioncontroller/role/utils/RoleUiBehaviorUtils.java151
29 files changed, 706 insertions, 361 deletions
diff --git a/PermissionController/src/com/android/permissioncontroller/role/Role.md b/PermissionController/src/com/android/permissioncontroller/role/Role.md
index fa9188a1e..bde9f86f0 100644
--- a/PermissionController/src/com/android/permissioncontroller/role/Role.md
+++ b/PermissionController/src/com/android/permissioncontroller/role/Role.md
@@ -92,6 +92,9 @@ defaults to `false`.
- `visible`: Whether this role is visible to users. If a role is invisible (a.k.a. hidden) to users,
users won't be able to find it in Settings, and apps won't be able to request it. The role can still
be managed by system APIs and shell command.
+- `uiBehavior`: Optional name of a [`RoleUiBehavior`](ui/behavior/RoleUiBehavior.java) class to
+control certain role UI behavior in Java code, e.g. `DialerRoleUiBehavior`. This can be useful
+when the XML syntax cannot express certain UI behavior specific to the role.
The following tags can be specified inside a `<role>` tag:
diff --git a/PermissionController/src/com/android/permissioncontroller/role/model/AssistantRoleBehavior.java b/PermissionController/src/com/android/permissioncontroller/role/model/AssistantRoleBehavior.java
index 66dd8ccb9..bd661093e 100644
--- a/PermissionController/src/com/android/permissioncontroller/role/model/AssistantRoleBehavior.java
+++ b/PermissionController/src/com/android/permissioncontroller/role/model/AssistantRoleBehavior.java
@@ -27,7 +27,6 @@ import android.content.res.Resources;
import android.content.res.XmlResourceParser;
import android.os.Process;
import android.os.UserHandle;
-import android.provider.Settings;
import android.service.voice.VoiceInteractionService;
import android.util.ArraySet;
import android.util.AttributeSet;
@@ -37,7 +36,6 @@ import android.util.Xml;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
-import com.android.permissioncontroller.R;
import com.android.permissioncontroller.role.utils.UserUtils;
import org.xmlpull.v1.XmlPullParserException;
@@ -78,33 +76,6 @@ public class AssistantRoleBehavior implements RoleBehavior {
return !UserUtils.isProfile(user, context);
}
- @Override
- public boolean isVisibleAsUser(@NonNull Role role, @NonNull UserHandle user,
- @NonNull Context context) {
- return VisibilityMixin.isVisible("config_showDefaultAssistant", context);
- }
-
- @Nullable
- @Override
- public Intent getManageIntentAsUser(@NonNull Role role, @NonNull UserHandle user,
- @NonNull Context context) {
- boolean isAutomotive =
- context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE);
-
- if (isAutomotive) {
- return null;
- }
-
- return new Intent(Settings.ACTION_VOICE_INPUT_SETTINGS);
- }
-
- @Nullable
- @Override
- public CharSequence getConfirmationMessage(@NonNull Role role, @NonNull String packageName,
- @NonNull Context context) {
- return context.getString(R.string.assistant_confirmation_message);
- }
-
@Nullable
@Override
public List<String> getQualifyingPackagesAsUser(@NonNull Role role, @NonNull UserHandle user,
diff --git a/PermissionController/src/com/android/permissioncontroller/role/model/BrowserRoleBehavior.java b/PermissionController/src/com/android/permissioncontroller/role/model/BrowserRoleBehavior.java
index 109983539..62a452da4 100644
--- a/PermissionController/src/com/android/permissioncontroller/role/model/BrowserRoleBehavior.java
+++ b/PermissionController/src/com/android/permissioncontroller/role/model/BrowserRoleBehavior.java
@@ -29,7 +29,6 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.android.modules.utils.build.SdkLevel;
-import com.android.permissioncontroller.R;
import com.android.permissioncontroller.permission.utils.CollectionUtils;
import com.android.permissioncontroller.role.utils.PackageUtils;
import com.android.permissioncontroller.role.utils.UserUtils;
@@ -151,10 +150,4 @@ public class BrowserRoleBehavior implements RoleBehavior {
}
}
}
-
- @Override
- public boolean isVisibleAsUser(@NonNull Role role, @NonNull UserHandle user,
- @NonNull Context context) {
- return context.getResources().getBoolean(R.bool.config_showBrowserRole);
- }
}
diff --git a/PermissionController/src/com/android/permissioncontroller/role/model/DialerRoleBehavior.java b/PermissionController/src/com/android/permissioncontroller/role/model/DialerRoleBehavior.java
index 36be7e88a..d90d09bc3 100644
--- a/PermissionController/src/com/android/permissioncontroller/role/model/DialerRoleBehavior.java
+++ b/PermissionController/src/com/android/permissioncontroller/role/model/DialerRoleBehavior.java
@@ -17,22 +17,16 @@
package com.android.permissioncontroller.role.model;
import android.content.Context;
-import android.content.pm.ApplicationInfo;
import android.os.UserHandle;
-import android.telecom.TelecomManager;
import android.telephony.TelephonyManager;
import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.preference.Preference;
import com.android.modules.utils.build.SdkLevel;
-import com.android.permissioncontroller.R;
import com.android.permissioncontroller.role.utils.PackageUtils;
import java.util.Arrays;
import java.util.List;
-import java.util.Objects;
/**
* Class for behavior of the dialer role.
@@ -58,33 +52,6 @@ public class DialerRoleBehavior implements RoleBehavior {
}
@Override
- public void prepareApplicationPreferenceAsUser(@NonNull Role role,
- @NonNull Preference preference, @NonNull ApplicationInfo applicationInfo,
- @NonNull UserHandle user, @NonNull Context context) {
- TelecomManager telecomManager = context.getSystemService(TelecomManager.class);
- String systemPackageName = telecomManager.getSystemDialerPackage();
- if (Objects.equals(applicationInfo.packageName, systemPackageName)) {
- preference.setSummary(R.string.default_app_system_default);
- } else {
- preference.setSummary(null);
- }
- }
-
- @Nullable
- @Override
- public CharSequence getConfirmationMessage(@NonNull Role role, @NonNull String packageName,
- @NonNull Context context) {
- return EncryptionUnawareConfirmationMixin.getConfirmationMessage(role, packageName,
- context);
- }
-
- @Override
- public boolean isVisibleAsUser(@NonNull Role role, @NonNull UserHandle user,
- @NonNull Context context) {
- return context.getResources().getBoolean(R.bool.config_showDialerRole);
- }
-
- @Override
public void grant(@NonNull Role role, @NonNull String packageName, @NonNull Context context) {
if (SdkLevel.isAtLeastS()) {
if (PackageUtils.isSystemPackage(packageName, context)) {
diff --git a/PermissionController/src/com/android/permissioncontroller/role/model/EmergencyRoleBehavior.java b/PermissionController/src/com/android/permissioncontroller/role/model/EmergencyRoleBehavior.java
index d0b2bf42a..e2bbe4590 100644
--- a/PermissionController/src/com/android/permissioncontroller/role/model/EmergencyRoleBehavior.java
+++ b/PermissionController/src/com/android/permissioncontroller/role/model/EmergencyRoleBehavior.java
@@ -66,18 +66,4 @@ public class EmergencyRoleBehavior implements RoleBehavior {
}
return fallbackPackageInfo != null ? fallbackPackageInfo.packageName : null;
}
-
- @Override
- public boolean isVisibleAsUser(@NonNull Role role, @NonNull UserHandle user,
- @NonNull Context context) {
- return VisibilityMixin.isVisible("config_showDefaultEmergency", context);
- }
-
- @Nullable
- @Override
- public CharSequence getConfirmationMessage(@NonNull Role role, @NonNull String packageName,
- @NonNull Context context) {
- return EncryptionUnawareConfirmationMixin.getConfirmationMessage(role, packageName,
- context);
- }
}
diff --git a/PermissionController/src/com/android/permissioncontroller/role/model/HomeRoleBehavior.java b/PermissionController/src/com/android/permissioncontroller/role/model/HomeRoleBehavior.java
index af6acfeec..3ec4871cf 100644
--- a/PermissionController/src/com/android/permissioncontroller/role/model/HomeRoleBehavior.java
+++ b/PermissionController/src/com/android/permissioncontroller/role/model/HomeRoleBehavior.java
@@ -16,28 +16,18 @@
package com.android.permissioncontroller.role.model;
-import android.app.admin.DevicePolicyResources.Strings.DefaultAppSettings;
-import android.app.role.RoleManager;
-import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.PermissionInfo;
import android.content.pm.ResolveInfo;
-import android.os.Build;
import android.os.UserHandle;
import android.provider.Settings;
-import android.util.Log;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
-import androidx.preference.Preference;
-import com.android.permissioncontroller.R;
-import com.android.permissioncontroller.permission.utils.CollectionUtils;
-import com.android.permissioncontroller.permission.utils.Utils;
-import com.android.permissioncontroller.role.ui.TwoTargetPreference;
import com.android.permissioncontroller.role.utils.UserUtils;
import java.util.Arrays;
@@ -53,8 +43,6 @@ import java.util.Objects;
*/
public class HomeRoleBehavior implements RoleBehavior {
- private static final String LOG_TAG = HomeRoleBehavior.class.getSimpleName();
-
private static final List<String> AUTOMOTIVE_PERMISSIONS = Arrays.asList(
android.Manifest.permission.READ_CALL_LOG,
android.Manifest.permission.WRITE_CALL_LOG,
@@ -100,71 +88,10 @@ public class HomeRoleBehavior implements RoleBehavior {
return packageName;
}
- @Override
- public boolean isVisibleAsUser(@NonNull Role role, @NonNull UserHandle user,
- @NonNull Context context) {
- return VisibilityMixin.isVisible("config_showDefaultHome", context);
- }
-
- @Override
- public void preparePreferenceAsUser(@NonNull Role role, @NonNull TwoTargetPreference preference,
- @NonNull UserHandle user, @NonNull Context context) {
- TwoTargetPreference.OnSecondTargetClickListener listener = null;
- RoleManager roleManager = context.getSystemService(RoleManager.class);
- String packageName = CollectionUtils.firstOrNull(roleManager.getRoleHoldersAsUser(
- role.getName(), user));
- if (packageName != null) {
- Intent intent = new Intent(Intent.ACTION_APPLICATION_PREFERENCES)
- .setPackage(packageName)
- .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
- PackageManager userPackageManager = UserUtils.getUserContext(context, user)
- .getPackageManager();
- ResolveInfo resolveInfo = userPackageManager.resolveActivity(intent, 0);
- if (resolveInfo != null && resolveInfo.activityInfo != null
- && resolveInfo.activityInfo.exported) {
- listener = preference2 -> {
- try {
- context.startActivity(intent);
- } catch (ActivityNotFoundException e) {
- Log.e(LOG_TAG, "Cannot start activity for home app preferences", e);
- }
- };
- }
- }
- preference.setOnSecondTargetClickListener(listener);
- }
-
- @Override
- public boolean isApplicationVisibleAsUser(@NonNull Role role,
- @NonNull ApplicationInfo applicationInfo, @NonNull UserHandle user,
- @NonNull Context context) {
- // Home is not available for work profile, so we can just use the current user.
- return !isSettingsApplication(applicationInfo, context);
- }
-
- @Override
- public void prepareApplicationPreferenceAsUser(@NonNull Role role,
- @NonNull Preference preference, @NonNull ApplicationInfo applicationInfo,
- @NonNull UserHandle user, @NonNull Context context) {
- boolean missingWorkProfileSupport = isMissingWorkProfileSupport(applicationInfo, context);
- preference.setEnabled(!missingWorkProfileSupport);
- preference.setSummary(missingWorkProfileSupport ? Utils.getEnterpriseString(context,
- DefaultAppSettings.HOME_MISSING_WORK_PROFILE_SUPPORT_MESSAGE,
- R.string.home_missing_work_profile_support) : null);
- }
-
- private boolean isMissingWorkProfileSupport(@NonNull ApplicationInfo applicationInfo,
- @NonNull Context context) {
- boolean hasWorkProfile = UserUtils.getWorkProfile(context) != null;
- if (!hasWorkProfile) {
- return false;
- }
- boolean isWorkProfileSupported = applicationInfo.targetSdkVersion
- >= Build.VERSION_CODES.LOLLIPOP;
- return !isWorkProfileSupported;
- }
-
- private boolean isSettingsApplication(@NonNull ApplicationInfo applicationInfo,
+ /**
+ * Check if the application is a settings application
+ */
+ public static boolean isSettingsApplication(@NonNull ApplicationInfo applicationInfo,
@NonNull Context context) {
PackageManager packageManager = context.getPackageManager();
ResolveInfo resolveInfo = packageManager.resolveActivity(new Intent(
diff --git a/PermissionController/src/com/android/permissioncontroller/role/model/Role.java b/PermissionController/src/com/android/permissioncontroller/role/model/Role.java
index ddd7ff6b5..58671a59c 100644
--- a/PermissionController/src/com/android/permissioncontroller/role/model/Role.java
+++ b/PermissionController/src/com/android/permissioncontroller/role/model/Role.java
@@ -20,7 +20,6 @@ import android.app.ActivityManager;
import android.app.role.RoleManager;
import android.content.ComponentName;
import android.content.Context;
-import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.SharedLibraryInfo;
@@ -37,13 +36,11 @@ import android.util.Log;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.StringRes;
-import androidx.preference.Preference;
import com.android.modules.utils.build.SdkLevel;
import com.android.permissioncontroller.Constants;
import com.android.permissioncontroller.permission.utils.CollectionUtils;
import com.android.permissioncontroller.permission.utils.Utils;
-import com.android.permissioncontroller.role.ui.TwoTargetPreference;
import com.android.permissioncontroller.role.utils.PackageUtils;
import com.android.permissioncontroller.role.utils.RoleManagerCompat;
import com.android.permissioncontroller.role.utils.UserUtils;
@@ -223,6 +220,9 @@ public class Role {
@NonNull
private final List<PreferredActivity> mPreferredActivities;
+ @Nullable
+ private final String mUiBehaviorName;
+
public Role(@NonNull String name, boolean allowBypassingQualification,
@Nullable RoleBehavior behavior, @Nullable String defaultHoldersResourceName,
@StringRes int descriptionResource, boolean exclusive, boolean fallBackToDefaultHolder,
@@ -233,7 +233,8 @@ public class Role {
boolean showNone, boolean statik, boolean systemOnly, boolean visible,
@NonNull List<RequiredComponent> requiredComponents,
@NonNull List<Permission> permissions, @NonNull List<String> appOpPermissions,
- @NonNull List<AppOp> appOps, @NonNull List<PreferredActivity> preferredActivities) {
+ @NonNull List<AppOp> appOps, @NonNull List<PreferredActivity> preferredActivities,
+ @Nullable String uiBehaviorName) {
mName = name;
mAllowBypassingQualification = allowBypassingQualification;
mBehavior = behavior;
@@ -259,6 +260,7 @@ public class Role {
mAppOpPermissions = appOpPermissions;
mAppOps = appOps;
mPreferredActivities = preferredActivities;
+ mUiBehaviorName = uiBehaviorName;
}
@NonNull
@@ -352,6 +354,11 @@ public class Role {
return mPreferredActivities;
}
+ @Nullable
+ public String getUiBehaviorName() {
+ return mUiBehaviorName;
+ }
+
/**
* Callback when this role is added to the system for the first time.
*
@@ -534,110 +541,6 @@ public class Role {
}
/**
- * Check whether this role should be visible to user.
- *
- * @param user the user to check for
- * @param context the {@code Context} to retrieve system services
- *
- * @return whether this role should be visible to user
- */
- public boolean isVisibleAsUser(@NonNull UserHandle user, @NonNull Context context) {
- return mVisible && (mBehavior == null || mBehavior.isVisibleAsUser(this, user, context));
- }
-
- /**
- * Check whether this role should be visible to user, for current user.
- *
- * @param context the {@code Context} to retrieve system services
- *
- * @return whether this role should be visible to user.
- */
- public boolean isVisible(@NonNull Context context) {
- return isVisibleAsUser(Process.myUserHandle(), context);
- }
-
- /**
- * Get the {@link Intent} to manage this role, or {@code null} to use the default UI.
- *
- * @param user the user to manage this role for
- * @param context the {@code Context} to retrieve system services
- *
- * @return the {@link Intent} to manage this role, or {@code null} to use the default UI.
- */
- @Nullable
- public Intent getManageIntentAsUser(@NonNull UserHandle user, @NonNull Context context) {
- if (mBehavior != null) {
- return mBehavior.getManageIntentAsUser(this, user, context);
- }
- return null;
- }
-
- /**
- * Prepare a {@link Preference} for this role.
- *
- * @param preference the {@link Preference} for this role
- * @param user the user for this role
- * @param context the {@code Context} to retrieve system services
- */
- public void preparePreferenceAsUser(@NonNull TwoTargetPreference preference,
- @NonNull UserHandle user, @NonNull Context context) {
- if (mBehavior != null) {
- mBehavior.preparePreferenceAsUser(this, preference, user, context);
- }
- }
-
- /**
- * Check whether a qualifying application should be visible to user.
- *
- * @param applicationInfo the {@link ApplicationInfo} for the application
- * @param user the user for the application
- * @param context the {@code Context} to retrieve system services
- *
- * @return whether the qualifying application should be visible to user
- */
- public boolean isApplicationVisibleAsUser(@NonNull ApplicationInfo applicationInfo,
- @NonNull UserHandle user, @NonNull Context context) {
- if (mBehavior != null) {
- return mBehavior.isApplicationVisibleAsUser(this, applicationInfo, user, context);
- }
- return true;
- }
-
- /**
- * Prepare a {@link Preference} for an application.
- *
- * @param preference the {@link Preference} for the application
- * @param applicationInfo the {@link ApplicationInfo} for the application
- * @param user the user for the application
- * @param context the {@code Context} to retrieve system services
- */
- public void prepareApplicationPreferenceAsUser(@NonNull Preference preference,
- @NonNull ApplicationInfo applicationInfo, @NonNull UserHandle user,
- @NonNull Context context) {
- if (mBehavior != null) {
- mBehavior.prepareApplicationPreferenceAsUser(this, preference, applicationInfo, user,
- context);
- }
- }
-
- /**
- * Get the confirmation message for adding an application as a holder of this role.
- *
- * @param packageName the package name of the application to get confirmation message for
- * @param context the {@code Context} to retrieve system services
- *
- * @return the confirmation message, or {@code null} if no confirmation is needed
- */
- @Nullable
- public CharSequence getConfirmationMessage(@NonNull String packageName,
- @NonNull Context context) {
- if (mBehavior != null) {
- return mBehavior.getConfirmationMessage(this, packageName, context);
- }
- return null;
- }
-
- /**
* Check whether this role is allowed to bypass qualification, if enabled globally.
*
* @param context the {@code Context} to retrieve system services
@@ -1085,6 +988,7 @@ public class Role {
+ ", mAppOpPermissions=" + mAppOpPermissions
+ ", mAppOps=" + mAppOps
+ ", mPreferredActivities=" + mPreferredActivities
+ + ", mUiBehaviorName=" + mUiBehaviorName
+ '}';
}
}
diff --git a/PermissionController/src/com/android/permissioncontroller/role/model/RoleBehavior.java b/PermissionController/src/com/android/permissioncontroller/role/model/RoleBehavior.java
index e5402c2ed..71daff044 100644
--- a/PermissionController/src/com/android/permissioncontroller/role/model/RoleBehavior.java
+++ b/PermissionController/src/com/android/permissioncontroller/role/model/RoleBehavior.java
@@ -17,15 +17,10 @@
package com.android.permissioncontroller.role.model;
import android.content.Context;
-import android.content.Intent;
-import android.content.pm.ApplicationInfo;
import android.os.UserHandle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
-import androidx.preference.Preference;
-
-import com.android.permissioncontroller.role.ui.TwoTargetPreference;
import java.util.Collections;
import java.util.List;
@@ -65,56 +60,6 @@ public interface RoleBehavior {
}
/**
- * @see Role#isVisibleAsUser(UserHandle, Context)
- */
- default boolean isVisibleAsUser(@NonNull Role role, @NonNull UserHandle user,
- @NonNull Context context) {
- return true;
- }
-
- /**
- * @see Role#getManageIntentAsUser(UserHandle, Context)
- */
- @Nullable
- default Intent getManageIntentAsUser(@NonNull Role role, @NonNull UserHandle user,
- @NonNull Context context) {
- return null;
- }
-
- /**
- * @see Role#preparePreferenceAsUser(TwoTargetPreference, UserHandle, Context)
- */
- default void preparePreferenceAsUser(@NonNull Role role,
- @NonNull TwoTargetPreference preference, @NonNull UserHandle user,
- @NonNull Context context) {}
-
- /**
- * @see Role#isApplicationVisibleAsUser(ApplicationInfo, UserHandle, Context)
- */
- default boolean isApplicationVisibleAsUser(@NonNull Role role,
- @NonNull ApplicationInfo applicationInfo, @NonNull UserHandle user,
- @NonNull Context context) {
- return true;
- }
-
- /**
- * @see Role#prepareApplicationPreferenceAsUser(Preference, ApplicationInfo, UserHandle,
- * Context)
- */
- default void prepareApplicationPreferenceAsUser(@NonNull Role role,
- @NonNull Preference preference, @NonNull ApplicationInfo applicationInfo,
- @NonNull UserHandle user, @NonNull Context context) {}
-
- /**
- * @see Role#getConfirmationMessage(String, Context)
- */
- @Nullable
- default CharSequence getConfirmationMessage(@NonNull Role role, @NonNull String packageName,
- @NonNull Context context) {
- return null;
- }
-
- /**
* @see Role#shouldAllowBypassingQualification(Context)
*/
@Nullable
diff --git a/PermissionController/src/com/android/permissioncontroller/role/model/RoleParser.java b/PermissionController/src/com/android/permissioncontroller/role/model/RoleParser.java
index 3fac0b578..1efa495b1 100644
--- a/PermissionController/src/com/android/permissioncontroller/role/model/RoleParser.java
+++ b/PermissionController/src/com/android/permissioncontroller/role/model/RoleParser.java
@@ -92,6 +92,7 @@ public class RoleParser {
private static final String ATTRIBUTE_SHOW_NONE = "showNone";
private static final String ATTRIBUTE_STATIC = "static";
private static final String ATTRIBUTE_SYSTEM_ONLY = "systemOnly";
+ private static final String ATTRIBUTE_UI_BEHAVIOR = "uiBehavior";
private static final String ATTRIBUTE_VISIBLE = "visible";
private static final String ATTRIBUTE_MIN_TARGET_SDK_VERSION = "minTargetSdkVersion";
private static final String ATTRIBUTE_PERMISSION = "permission";
@@ -408,6 +409,8 @@ public class RoleParser {
boolean systemOnly = getAttributeBooleanValue(parser, ATTRIBUTE_SYSTEM_ONLY, false);
+ String uiBehaviorName = getAttributeValue(parser, ATTRIBUTE_UI_BEHAVIOR);
+
List<RequiredComponent> requiredComponents = null;
List<Permission> permissions = null;
List<String> appOpPermissions = null;
@@ -491,7 +494,7 @@ public class RoleParser {
maxSdkVersion, minSdkVersion, overrideUserWhenGranting, requestDescriptionResource,
requestTitleResource, requestable, searchKeywordsResource, shortLabelResource,
showNone, statik, systemOnly, visible, requiredComponents, permissions,
- appOpPermissions, appOps, preferredActivities);
+ appOpPermissions, appOps, preferredActivities, uiBehaviorName);
}
@NonNull
diff --git a/PermissionController/src/com/android/permissioncontroller/role/model/SmsRoleBehavior.java b/PermissionController/src/com/android/permissioncontroller/role/model/SmsRoleBehavior.java
index 341c2d032..4dc9b9150 100644
--- a/PermissionController/src/com/android/permissioncontroller/role/model/SmsRoleBehavior.java
+++ b/PermissionController/src/com/android/permissioncontroller/role/model/SmsRoleBehavior.java
@@ -26,7 +26,6 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.android.modules.utils.build.SdkLevel;
-import com.android.permissioncontroller.R;
import com.android.permissioncontroller.permission.utils.CollectionUtils;
import com.android.permissioncontroller.role.utils.PackageUtils;
import com.android.permissioncontroller.role.utils.UserUtils;
@@ -93,20 +92,6 @@ public class SmsRoleBehavior implements RoleBehavior {
return CollectionUtils.firstOrNull(qualifyingPackageNames);
}
- @Nullable
- @Override
- public CharSequence getConfirmationMessage(@NonNull Role role, @NonNull String packageName,
- @NonNull Context context) {
- return EncryptionUnawareConfirmationMixin.getConfirmationMessage(role, packageName,
- context);
- }
-
- @Override
- public boolean isVisibleAsUser(@NonNull Role role, @NonNull UserHandle user,
- @NonNull Context context) {
- return context.getResources().getBoolean(R.bool.config_showSmsRole);
- }
-
@Override
public void grant(@NonNull Role role, @NonNull String packageName, @NonNull Context context) {
if (SdkLevel.isAtLeastS() && PackageUtils.isSystemPackage(packageName, context)) {
diff --git a/PermissionController/src/com/android/permissioncontroller/role/service/RoleControllerServiceImpl.java b/PermissionController/src/com/android/permissioncontroller/role/service/RoleControllerServiceImpl.java
index fbb9c2e2e..a1210e748 100644
--- a/PermissionController/src/com/android/permissioncontroller/role/service/RoleControllerServiceImpl.java
+++ b/PermissionController/src/com/android/permissioncontroller/role/service/RoleControllerServiceImpl.java
@@ -32,6 +32,7 @@ import com.android.permissioncontroller.permission.utils.CollectionUtils;
import com.android.permissioncontroller.role.model.Role;
import com.android.permissioncontroller.role.model.Roles;
import com.android.permissioncontroller.role.utils.PackageUtils;
+import com.android.permissioncontroller.role.utils.RoleUiBehaviorUtils;
import java.util.ArrayList;
import java.util.List;
@@ -428,8 +429,8 @@ public class RoleControllerServiceImpl extends RoleControllerService {
return false;
}
ApplicationInfo applicationInfo = PackageUtils.getApplicationInfo(packageName, this);
- if (applicationInfo == null || !role.isApplicationVisibleAsUser(applicationInfo,
- Process.myUserHandle(), this)) {
+ if (applicationInfo == null || !RoleUiBehaviorUtils.isApplicationVisibleAsUser(role,
+ applicationInfo, Process.myUserHandle(), this)) {
return false;
}
return true;
@@ -444,7 +445,8 @@ public class RoleControllerServiceImpl extends RoleControllerService {
if (!role.isAvailable(this)) {
return false;
}
- return role.isVisibleAsUser(Process.myUserHandle(), this);
+
+ return RoleUiBehaviorUtils.isVisibleAsUser(role, Process.myUserHandle(), this);
}
private static boolean checkFlags(int flags, int allowedFlags) {
diff --git a/PermissionController/src/com/android/permissioncontroller/role/service/RoleSearchIndexablesProvider.java b/PermissionController/src/com/android/permissioncontroller/role/service/RoleSearchIndexablesProvider.java
index 7201acffc..b0d006429 100644
--- a/PermissionController/src/com/android/permissioncontroller/role/service/RoleSearchIndexablesProvider.java
+++ b/PermissionController/src/com/android/permissioncontroller/role/service/RoleSearchIndexablesProvider.java
@@ -29,6 +29,7 @@ import com.android.permissioncontroller.R;
import com.android.permissioncontroller.permission.service.BaseSearchIndexablesProvider;
import com.android.permissioncontroller.role.model.Role;
import com.android.permissioncontroller.role.model.Roles;
+import com.android.permissioncontroller.role.utils.RoleUiBehaviorUtils;
/**
* {@link android.provider.SearchIndexablesProvider} for roles.
@@ -53,7 +54,8 @@ public class RoleSearchIndexablesProvider extends BaseSearchIndexablesProvider {
long token = Binder.clearCallingIdentity();
try {
- if (!role.isAvailable(context) || !role.isVisible(context)) {
+ if (!role.isAvailable(context) || !RoleUiBehaviorUtils.isVisible(role,
+ context)) {
continue;
}
} finally {
diff --git a/PermissionController/src/com/android/permissioncontroller/role/ui/DefaultAppActivity.java b/PermissionController/src/com/android/permissioncontroller/role/ui/DefaultAppActivity.java
index 0ddb6c3ac..7b6e7ee4a 100644
--- a/PermissionController/src/com/android/permissioncontroller/role/ui/DefaultAppActivity.java
+++ b/PermissionController/src/com/android/permissioncontroller/role/ui/DefaultAppActivity.java
@@ -33,6 +33,7 @@ import com.android.permissioncontroller.role.model.Role;
import com.android.permissioncontroller.role.model.Roles;
import com.android.permissioncontroller.role.ui.auto.AutoDefaultAppFragment;
import com.android.permissioncontroller.role.ui.handheld.HandheldDefaultAppFragment;
+import com.android.permissioncontroller.role.utils.RoleUiBehaviorUtils;
/**
* Activity for a default app.
@@ -86,7 +87,8 @@ public class DefaultAppActivity extends SettingsActivity {
finish();
return;
}
- if (!role.isVisibleAsUser(user, this)) {
+
+ if (!RoleUiBehaviorUtils.isVisibleAsUser(role, user, this)) {
Log.e(LOG_TAG, "Role is invisible: " + roleName);
finish();
return;
diff --git a/PermissionController/src/com/android/permissioncontroller/role/ui/DefaultAppChildFragment.java b/PermissionController/src/com/android/permissioncontroller/role/ui/DefaultAppChildFragment.java
index b4e4aaa80..010cb0cd9 100644
--- a/PermissionController/src/com/android/permissioncontroller/role/ui/DefaultAppChildFragment.java
+++ b/PermissionController/src/com/android/permissioncontroller/role/ui/DefaultAppChildFragment.java
@@ -41,6 +41,7 @@ import com.android.permissioncontroller.R;
import com.android.permissioncontroller.permission.utils.Utils;
import com.android.permissioncontroller.role.model.Role;
import com.android.permissioncontroller.role.model.Roles;
+import com.android.permissioncontroller.role.utils.RoleUiBehaviorUtils;
import java.util.List;
import java.util.Objects;
@@ -208,7 +209,8 @@ public class DefaultAppChildFragment<PF extends PreferenceFragmentCompat
preference.setChecked(checked);
if (applicationInfo != null) {
- mRole.prepareApplicationPreferenceAsUser(preference, applicationInfo, mUser, context);
+ RoleUiBehaviorUtils.prepareApplicationPreferenceAsUser(mRole, preference,
+ applicationInfo, mUser, context);
}
preferenceScreen.addPreference(preference);
@@ -238,8 +240,9 @@ public class DefaultAppChildFragment<PF extends PreferenceFragmentCompat
mViewModel.setNoneDefaultApp();
} else {
String packageName = key;
- CharSequence confirmationMessage = mRole.getConfirmationMessage(packageName,
- requireContext());
+ CharSequence confirmationMessage =
+ RoleUiBehaviorUtils.getConfirmationMessage(mRole, packageName,
+ requireContext());
if (confirmationMessage != null) {
DefaultAppConfirmationDialogFragment.show(packageName, confirmationMessage, this);
} else {
diff --git a/PermissionController/src/com/android/permissioncontroller/role/ui/DefaultAppListChildFragment.java b/PermissionController/src/com/android/permissioncontroller/role/ui/DefaultAppListChildFragment.java
index 752dfb9cc..59637fd58 100644
--- a/PermissionController/src/com/android/permissioncontroller/role/ui/DefaultAppListChildFragment.java
+++ b/PermissionController/src/com/android/permissioncontroller/role/ui/DefaultAppListChildFragment.java
@@ -42,6 +42,7 @@ import com.android.permissioncontroller.R;
import com.android.permissioncontroller.permission.utils.Utils;
import com.android.permissioncontroller.role.model.Role;
import com.android.permissioncontroller.role.model.Roles;
+import com.android.permissioncontroller.role.utils.RoleUiBehaviorUtils;
import java.util.List;
import java.util.Objects;
@@ -186,8 +187,8 @@ public class DefaultAppListChildFragment<PF extends PreferenceFragmentCompat
preference.setIcon(Utils.getBadgedIcon(context, holderApplicationInfo));
preference.setSummary(Utils.getAppLabel(holderApplicationInfo, context));
}
- role.preparePreferenceAsUser((TwoTargetPreference) preference, user, context);
-
+ RoleUiBehaviorUtils.preparePreferenceAsUser(role, (TwoTargetPreference) preference,
+ user, context);
preferenceGroup.addPreference(preference);
}
}
@@ -198,7 +199,7 @@ public class DefaultAppListChildFragment<PF extends PreferenceFragmentCompat
Context context = requireContext();
Role role = Roles.get(context).get(roleName);
UserHandle user = preference.getExtras().getParcelable(Intent.EXTRA_USER);
- Intent intent = role.getManageIntentAsUser(user, context);
+ Intent intent = RoleUiBehaviorUtils.getManageIntentAsUser(role, user, context);
if (intent == null) {
intent = DefaultAppActivity.createIntent(roleName, user, context);
}
diff --git a/PermissionController/src/com/android/permissioncontroller/role/ui/RequestRoleActivity.java b/PermissionController/src/com/android/permissioncontroller/role/ui/RequestRoleActivity.java
index 0d5216991..0fcf8135c 100644
--- a/PermissionController/src/com/android/permissioncontroller/role/ui/RequestRoleActivity.java
+++ b/PermissionController/src/com/android/permissioncontroller/role/ui/RequestRoleActivity.java
@@ -38,6 +38,7 @@ import com.android.permissioncontroller.role.model.Role;
import com.android.permissioncontroller.role.model.Roles;
import com.android.permissioncontroller.role.model.UserDeniedManager;
import com.android.permissioncontroller.role.utils.PackageUtils;
+import com.android.permissioncontroller.role.utils.RoleUiBehaviorUtils;
import java.util.List;
import java.util.Objects;
@@ -109,7 +110,7 @@ public class RequestRoleActivity extends FragmentActivity {
return;
}
- if (!role.isVisible(this)) {
+ if (!RoleUiBehaviorUtils.isVisible(role, this)) {
Log.e(LOG_TAG, "Role is invisible: " + mRoleName);
reportRequestResult(
PermissionControllerStatsLog.ROLE_REQUEST_RESULT_REPORTED__RESULT__IGNORED);
diff --git a/PermissionController/src/com/android/permissioncontroller/role/ui/RoleListLiveData.java b/PermissionController/src/com/android/permissioncontroller/role/ui/RoleListLiveData.java
index 9742ed923..a57b6f532 100644
--- a/PermissionController/src/com/android/permissioncontroller/role/ui/RoleListLiveData.java
+++ b/PermissionController/src/com/android/permissioncontroller/role/ui/RoleListLiveData.java
@@ -32,6 +32,7 @@ import com.android.permissioncontroller.AsyncTaskLiveData;
import com.android.permissioncontroller.role.model.Role;
import com.android.permissioncontroller.role.model.Roles;
import com.android.permissioncontroller.role.utils.PackageUtils;
+import com.android.permissioncontroller.role.utils.RoleUiBehaviorUtils;
import java.util.ArrayList;
import java.util.List;
@@ -96,7 +97,7 @@ public class RoleListLiveData extends AsyncTaskLiveData<List<RoleItem>>
continue;
}
- if (!role.isVisibleAsUser(mUser, mContext)) {
+ if (!RoleUiBehaviorUtils.isVisibleAsUser(role, mUser, mContext)) {
continue;
}
diff --git a/PermissionController/src/com/android/permissioncontroller/role/ui/RoleLiveData.java b/PermissionController/src/com/android/permissioncontroller/role/ui/RoleLiveData.java
index 31042f974..f4bc508c2 100644
--- a/PermissionController/src/com/android/permissioncontroller/role/ui/RoleLiveData.java
+++ b/PermissionController/src/com/android/permissioncontroller/role/ui/RoleLiveData.java
@@ -31,6 +31,7 @@ import androidx.lifecycle.LiveData;
import com.android.permissioncontroller.AsyncTaskLiveData;
import com.android.permissioncontroller.role.model.Role;
import com.android.permissioncontroller.role.utils.PackageUtils;
+import com.android.permissioncontroller.role.utils.RoleUiBehaviorUtils;
import java.util.ArrayList;
import java.util.List;
@@ -94,7 +95,8 @@ public class RoleLiveData extends AsyncTaskLiveData<List<Pair<ApplicationInfo, B
+ qualifyingPackageName);
continue;
}
- if (!mRole.isApplicationVisibleAsUser(qualifyingApplicationInfo, mUser, mContext)) {
+ if (!RoleUiBehaviorUtils.isApplicationVisibleAsUser(mRole, qualifyingApplicationInfo,
+ mUser, mContext)) {
continue;
}
boolean isHolderApplication = holderPackageNames.contains(qualifyingPackageName);
diff --git a/PermissionController/src/com/android/permissioncontroller/role/ui/behavior/AssistantRoleUiBehavior.java b/PermissionController/src/com/android/permissioncontroller/role/ui/behavior/AssistantRoleUiBehavior.java
new file mode 100644
index 000000000..1a9bf4559
--- /dev/null
+++ b/PermissionController/src/com/android/permissioncontroller/role/ui/behavior/AssistantRoleUiBehavior.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.permissioncontroller.role.ui.behavior;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.os.UserHandle;
+import android.provider.Settings;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import com.android.permissioncontroller.R;
+import com.android.permissioncontroller.role.model.Role;
+import com.android.permissioncontroller.role.model.VisibilityMixin;
+
+/***
+ * Class for UI behavior of Assistant role
+ */
+public class AssistantRoleUiBehavior implements RoleUiBehavior {
+
+ @Override
+ public boolean isVisibleAsUser(@NonNull Role role, @NonNull UserHandle user,
+ @NonNull Context context) {
+ return VisibilityMixin.isVisible("config_showDefaultAssistant", context);
+ }
+
+ @Nullable
+ @Override
+ public Intent getManageIntentAsUser(@NonNull Role role, @NonNull UserHandle user,
+ @NonNull Context context) {
+ boolean isAutomotive =
+ context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE);
+
+ if (isAutomotive) {
+ return null;
+ }
+
+ return new Intent(Settings.ACTION_VOICE_INPUT_SETTINGS);
+ }
+
+ @Nullable
+ @Override
+ public CharSequence getConfirmationMessage(@NonNull Role role, @NonNull String packageName,
+ @NonNull Context context) {
+ return context.getString(R.string.assistant_confirmation_message);
+ }
+}
diff --git a/PermissionController/src/com/android/permissioncontroller/role/ui/behavior/BrowserRoleUiBehavior.java b/PermissionController/src/com/android/permissioncontroller/role/ui/behavior/BrowserRoleUiBehavior.java
new file mode 100644
index 000000000..7be63d270
--- /dev/null
+++ b/PermissionController/src/com/android/permissioncontroller/role/ui/behavior/BrowserRoleUiBehavior.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.permissioncontroller.role.ui.behavior;
+
+import android.content.Context;
+import android.os.UserHandle;
+
+import androidx.annotation.NonNull;
+
+import com.android.permissioncontroller.R;
+import com.android.permissioncontroller.role.model.Role;
+
+/***
+ * Class for UI behavior of Browser role
+ */
+public class BrowserRoleUiBehavior implements RoleUiBehavior {
+
+ @Override
+ public boolean isVisibleAsUser(@NonNull Role role, @NonNull UserHandle user,
+ @NonNull Context context) {
+ return context.getResources().getBoolean(R.bool.config_showBrowserRole);
+ }
+}
diff --git a/PermissionController/src/com/android/permissioncontroller/role/ui/behavior/DialerRoleUiBehavior.java b/PermissionController/src/com/android/permissioncontroller/role/ui/behavior/DialerRoleUiBehavior.java
new file mode 100644
index 000000000..a4970efdc
--- /dev/null
+++ b/PermissionController/src/com/android/permissioncontroller/role/ui/behavior/DialerRoleUiBehavior.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.permissioncontroller.role.ui.behavior;
+
+import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.os.UserHandle;
+import android.telecom.TelecomManager;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.preference.Preference;
+
+import com.android.permissioncontroller.R;
+import com.android.permissioncontroller.role.model.EncryptionUnawareConfirmationMixin;
+import com.android.permissioncontroller.role.model.Role;
+
+import java.util.Objects;
+
+/***
+ * Class for UI behavior of Dialer role
+ */
+public class DialerRoleUiBehavior implements RoleUiBehavior {
+
+ @Override
+ public void prepareApplicationPreferenceAsUser(@NonNull Role role,
+ @NonNull Preference preference, @NonNull ApplicationInfo applicationInfo,
+ @NonNull UserHandle user, @NonNull Context context) {
+ TelecomManager telecomManager = context.getSystemService(TelecomManager.class);
+ String systemPackageName = telecomManager.getSystemDialerPackage();
+ if (Objects.equals(applicationInfo.packageName, systemPackageName)) {
+ preference.setSummary(R.string.default_app_system_default);
+ } else {
+ preference.setSummary(null);
+ }
+ }
+
+ @Override
+ public boolean isVisibleAsUser(@NonNull Role role, @NonNull UserHandle user,
+ @NonNull Context context) {
+ return context.getResources().getBoolean(R.bool.config_showDialerRole);
+ }
+
+ @Nullable
+ @Override
+ public CharSequence getConfirmationMessage(@NonNull Role role, @NonNull String packageName,
+ @NonNull Context context) {
+ return EncryptionUnawareConfirmationMixin.getConfirmationMessage(role, packageName,
+ context);
+ }
+}
diff --git a/PermissionController/src/com/android/permissioncontroller/role/ui/behavior/EmergencyRoleUiBehavior.java b/PermissionController/src/com/android/permissioncontroller/role/ui/behavior/EmergencyRoleUiBehavior.java
new file mode 100644
index 000000000..a23adc171
--- /dev/null
+++ b/PermissionController/src/com/android/permissioncontroller/role/ui/behavior/EmergencyRoleUiBehavior.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.permissioncontroller.role.ui.behavior;
+
+import android.content.Context;
+import android.os.UserHandle;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import com.android.permissioncontroller.role.model.EncryptionUnawareConfirmationMixin;
+import com.android.permissioncontroller.role.model.Role;
+import com.android.permissioncontroller.role.model.VisibilityMixin;
+
+/***
+ * Class for UI behavior of Emergency role
+ */
+public class EmergencyRoleUiBehavior implements RoleUiBehavior {
+
+ @Override
+ public boolean isVisibleAsUser(@NonNull Role role, @NonNull UserHandle user,
+ @NonNull Context context) {
+ return VisibilityMixin.isVisible("config_showDefaultEmergency", context);
+ }
+
+ @Nullable
+ @Override
+ public CharSequence getConfirmationMessage(@NonNull Role role, @NonNull String packageName,
+ @NonNull Context context) {
+ return EncryptionUnawareConfirmationMixin.getConfirmationMessage(role, packageName,
+ context);
+ }
+}
diff --git a/PermissionController/src/com/android/permissioncontroller/role/ui/behavior/HomeRoleUiBehavior.java b/PermissionController/src/com/android/permissioncontroller/role/ui/behavior/HomeRoleUiBehavior.java
new file mode 100644
index 000000000..fe066ac02
--- /dev/null
+++ b/PermissionController/src/com/android/permissioncontroller/role/ui/behavior/HomeRoleUiBehavior.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.permissioncontroller.role.ui.behavior;
+
+import android.app.admin.DevicePolicyResources;
+import android.app.role.RoleManager;
+import android.content.ActivityNotFoundException;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.os.Build;
+import android.os.UserHandle;
+import android.util.Log;
+
+import androidx.annotation.NonNull;
+import androidx.preference.Preference;
+
+import com.android.permissioncontroller.R;
+import com.android.permissioncontroller.permission.utils.CollectionUtils;
+import com.android.permissioncontroller.permission.utils.Utils;
+import com.android.permissioncontroller.role.model.HomeRoleBehavior;
+import com.android.permissioncontroller.role.model.Role;
+import com.android.permissioncontroller.role.model.VisibilityMixin;
+import com.android.permissioncontroller.role.ui.TwoTargetPreference;
+import com.android.permissioncontroller.role.utils.UserUtils;
+
+/***
+ * Class for UI behavior of Home role
+ */
+public class HomeRoleUiBehavior implements RoleUiBehavior {
+
+ private static final String LOG_TAG = HomeRoleUiBehavior.class.getSimpleName();
+
+ @Override
+ public boolean isVisibleAsUser(@NonNull Role role, @NonNull UserHandle user,
+ @NonNull Context context) {
+ return VisibilityMixin.isVisible("config_showDefaultHome", context);
+ }
+
+ @Override
+ public void preparePreferenceAsUser(@NonNull Role role, @NonNull TwoTargetPreference preference,
+ @NonNull UserHandle user, @NonNull Context context) {
+ TwoTargetPreference.OnSecondTargetClickListener listener = null;
+ RoleManager roleManager = context.getSystemService(RoleManager.class);
+ String packageName = CollectionUtils.firstOrNull(roleManager.getRoleHoldersAsUser(
+ role.getName(), user));
+ if (packageName != null) {
+ Intent intent = new Intent(Intent.ACTION_APPLICATION_PREFERENCES)
+ .setPackage(packageName)
+ .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
+ PackageManager userPackageManager = UserUtils.getUserContext(context, user)
+ .getPackageManager();
+ ResolveInfo resolveInfo = userPackageManager.resolveActivity(intent, 0);
+ if (resolveInfo != null && resolveInfo.activityInfo != null
+ && resolveInfo.activityInfo.exported) {
+ listener = preference2 -> {
+ try {
+ context.startActivity(intent);
+ } catch (ActivityNotFoundException e) {
+ Log.e(LOG_TAG, "Cannot start activity for home app preferences", e);
+ }
+ };
+ }
+ }
+ preference.setOnSecondTargetClickListener(listener);
+ }
+
+ @Override
+ public boolean isApplicationVisibleAsUser(@NonNull Role role,
+ @NonNull ApplicationInfo applicationInfo, @NonNull UserHandle user,
+ @NonNull Context context) {
+ // Home is not available for work profile, so we can just use the current user.
+ return !HomeRoleBehavior.isSettingsApplication(applicationInfo, context);
+ }
+
+ @Override
+ public void prepareApplicationPreferenceAsUser(@NonNull Role role,
+ @NonNull Preference preference, @NonNull ApplicationInfo applicationInfo,
+ @NonNull UserHandle user, @NonNull Context context) {
+ boolean missingWorkProfileSupport = isMissingWorkProfileSupport(applicationInfo, context);
+ preference.setEnabled(!missingWorkProfileSupport);
+ preference.setSummary(missingWorkProfileSupport ? Utils.getEnterpriseString(context,
+ DevicePolicyResources.Strings.DefaultAppSettings
+ .HOME_MISSING_WORK_PROFILE_SUPPORT_MESSAGE,
+ R.string.home_missing_work_profile_support) : null);
+ }
+
+ private boolean isMissingWorkProfileSupport(@NonNull ApplicationInfo applicationInfo,
+ @NonNull Context context) {
+ boolean hasWorkProfile = UserUtils.getWorkProfile(context) != null;
+ if (!hasWorkProfile) {
+ return false;
+ }
+ boolean isWorkProfileSupported = applicationInfo.targetSdkVersion
+ >= Build.VERSION_CODES.LOLLIPOP;
+ return !isWorkProfileSupported;
+ }
+}
diff --git a/PermissionController/src/com/android/permissioncontroller/role/ui/behavior/RoleUiBehavior.java b/PermissionController/src/com/android/permissioncontroller/role/ui/behavior/RoleUiBehavior.java
new file mode 100644
index 000000000..a57a75748
--- /dev/null
+++ b/PermissionController/src/com/android/permissioncontroller/role/ui/behavior/RoleUiBehavior.java
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.permissioncontroller.role.ui.behavior;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ApplicationInfo;
+import android.os.UserHandle;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.preference.Preference;
+
+import com.android.permissioncontroller.role.model.Role;
+import com.android.permissioncontroller.role.ui.TwoTargetPreference;
+
+/***
+ * Interface for UI behavior for roles
+ */
+public interface RoleUiBehavior {
+
+ /**
+ * Check whether this role should be visible to user.
+ *
+ * @param role the role to check for
+ * @param user the user to check for
+ * @param context the `Context` to retrieve system services
+ *
+ * @return whether this role should be visible to user
+ */
+ default boolean isVisibleAsUser(@NonNull Role role, @NonNull UserHandle user,
+ @NonNull Context context) {
+ return true;
+ }
+
+ /**
+ * Get the {@link Intent} to manage this role, or {@code null} to use the default UI.
+ *
+ * @param role the role to get the intent for
+ * @param user the user to manage this role for
+ * @param context the {@code Context} to retrieve system services
+ *
+ * @return the {@link Intent} to manage this role, or {@code null} to use the default UI.
+ */
+ @Nullable
+ default Intent getManageIntentAsUser(@NonNull Role role, @NonNull UserHandle user,
+ @NonNull Context context) {
+ return null;
+ }
+
+ /**
+ * Prepare a {@link Preference} for this role.
+ *
+ * @param role the role to prepare the preference for
+ * @param preference the {@link Preference} for this role
+ * @param user the user for this role
+ * @param context the {@code Context} to retrieve system services
+ */
+ default void preparePreferenceAsUser(@NonNull Role role,
+ @NonNull TwoTargetPreference preference,
+ @NonNull UserHandle user,
+ @NonNull Context context) {
+ }
+
+ /**
+ * Check whether a qualifying application should be visible to user.
+ *
+ * @param applicationInfo the {@link ApplicationInfo} for the application
+ * @param user the user for the application
+ * @param context the {@code Context} to retrieve system services
+ *
+ * @return whether the qualifying application should be visible to user
+ */
+ default boolean isApplicationVisibleAsUser(@NonNull Role role,
+ @NonNull ApplicationInfo applicationInfo, @NonNull UserHandle user,
+ @NonNull Context context) {
+ return true;
+ }
+
+ /**
+ * Prepare a {@link Preference} for this role.
+ *
+ * @param role the role to prepare the preference for
+ * @param preference the {@link Preference} for this role
+ * @param user the user for this role
+ * @param context the {@code Context} to retrieve system services
+ */
+ default void prepareApplicationPreferenceAsUser(@NonNull Role role,
+ @NonNull Preference preference, @NonNull ApplicationInfo applicationInfo,
+ @NonNull UserHandle user, @NonNull Context context) {
+ }
+
+ /**
+ * Get the confirmation message for adding an application as a holder of this role.
+ *
+ * @param role the role to get confirmation message for
+ * @param packageName the package name of the application to get confirmation message for
+ * @param context the {@code Context} to retrieve system services
+ *
+ * @return the confirmation message, or {@code null} if no confirmation is needed
+ */
+ @Nullable
+ default CharSequence getConfirmationMessage(@NonNull Role role, @NonNull String packageName,
+ @NonNull Context context) {
+ return null;
+ }
+}
diff --git a/PermissionController/src/com/android/permissioncontroller/role/ui/behavior/SmsRoleUiBehavior.java b/PermissionController/src/com/android/permissioncontroller/role/ui/behavior/SmsRoleUiBehavior.java
new file mode 100644
index 000000000..06ebd3889
--- /dev/null
+++ b/PermissionController/src/com/android/permissioncontroller/role/ui/behavior/SmsRoleUiBehavior.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.permissioncontroller.role.ui.behavior;
+
+import android.content.Context;
+import android.os.UserHandle;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import com.android.permissioncontroller.R;
+import com.android.permissioncontroller.role.model.EncryptionUnawareConfirmationMixin;
+import com.android.permissioncontroller.role.model.Role;
+
+/***
+ * Class for UI behavior of SMS role
+ */
+public class SmsRoleUiBehavior implements RoleUiBehavior {
+
+ @Override
+ public boolean isVisibleAsUser(@NonNull Role role, @NonNull UserHandle user,
+ @NonNull Context context) {
+ return context.getResources().getBoolean(R.bool.config_showSmsRole);
+ }
+
+ @Nullable
+ @Override
+ public CharSequence getConfirmationMessage(@NonNull Role role, @NonNull String packageName,
+ @NonNull Context context) {
+ return EncryptionUnawareConfirmationMixin.getConfirmationMessage(role, packageName,
+ context);
+ }
+}
diff --git a/PermissionController/src/com/android/permissioncontroller/role/ui/specialappaccess/SpecialAppAccessActivity.java b/PermissionController/src/com/android/permissioncontroller/role/ui/specialappaccess/SpecialAppAccessActivity.java
index 2328bb94e..188dc88af 100644
--- a/PermissionController/src/com/android/permissioncontroller/role/ui/specialappaccess/SpecialAppAccessActivity.java
+++ b/PermissionController/src/com/android/permissioncontroller/role/ui/specialappaccess/SpecialAppAccessActivity.java
@@ -32,6 +32,7 @@ import com.android.permissioncontroller.role.model.Roles;
import com.android.permissioncontroller.role.ui.SettingsActivity;
import com.android.permissioncontroller.role.ui.auto.AutoSpecialAppAccessFragment;
import com.android.permissioncontroller.role.ui.specialappaccess.handheld.HandheldSpecialAppAccessFragment;
+import com.android.permissioncontroller.role.utils.RoleUiBehaviorUtils;
/**
* Activity for a special app access.
@@ -75,7 +76,8 @@ public class SpecialAppAccessActivity extends SettingsActivity {
finish();
return;
}
- if (!role.isVisible(this)) {
+
+ if (!RoleUiBehaviorUtils.isVisible(role, this)) {
Log.e(LOG_TAG, "Role is invisible: " + roleName);
finish();
return;
diff --git a/PermissionController/src/com/android/permissioncontroller/role/ui/specialappaccess/SpecialAppAccessChildFragment.java b/PermissionController/src/com/android/permissioncontroller/role/ui/specialappaccess/SpecialAppAccessChildFragment.java
index 66e1e53ff..fb19d58c5 100644
--- a/PermissionController/src/com/android/permissioncontroller/role/ui/specialappaccess/SpecialAppAccessChildFragment.java
+++ b/PermissionController/src/com/android/permissioncontroller/role/ui/specialappaccess/SpecialAppAccessChildFragment.java
@@ -39,6 +39,7 @@ import com.android.permissioncontroller.permission.utils.Utils;
import com.android.permissioncontroller.role.model.Role;
import com.android.permissioncontroller.role.model.Roles;
import com.android.permissioncontroller.role.ui.ManageRoleHolderStateLiveData;
+import com.android.permissioncontroller.role.utils.RoleUiBehaviorUtils;
import java.util.List;
@@ -157,9 +158,8 @@ public class SpecialAppAccessChildFragment<PF extends PreferenceFragmentCompat
preference.setChecked(isHolderPackage);
UserHandle user = UserHandle.getUserHandleForUid(qualifyingApplicationInfo.uid);
- mRole.prepareApplicationPreferenceAsUser(preference, qualifyingApplicationInfo, user,
- context);
-
+ RoleUiBehaviorUtils.prepareApplicationPreferenceAsUser(mRole, preference,
+ qualifyingApplicationInfo, user, context);
preferenceScreen.addPreference(preference);
}
diff --git a/PermissionController/src/com/android/permissioncontroller/role/ui/specialappaccess/SpecialAppAccessListChildFragment.java b/PermissionController/src/com/android/permissioncontroller/role/ui/specialappaccess/SpecialAppAccessListChildFragment.java
index 52b7aa08d..c54e0d97b 100644
--- a/PermissionController/src/com/android/permissioncontroller/role/ui/specialappaccess/SpecialAppAccessListChildFragment.java
+++ b/PermissionController/src/com/android/permissioncontroller/role/ui/specialappaccess/SpecialAppAccessListChildFragment.java
@@ -36,6 +36,7 @@ import com.android.permissioncontroller.role.model.Role;
import com.android.permissioncontroller.role.model.Roles;
import com.android.permissioncontroller.role.ui.RoleItem;
import com.android.permissioncontroller.role.ui.TwoTargetPreference;
+import com.android.permissioncontroller.role.utils.RoleUiBehaviorUtils;
import java.util.List;
@@ -110,10 +111,9 @@ public class SpecialAppAccessListChildFragment<PF extends PreferenceFragmentComp
preference.setPersistent(false);
preference.setOnPreferenceClickListener(this);
}
-
- role.preparePreferenceAsUser((TwoTargetPreference) preference, Process.myUserHandle(),
+ RoleUiBehaviorUtils.preparePreferenceAsUser(role, (TwoTargetPreference) preference,
+ Process.myUserHandle(),
context);
-
preferenceScreen.addPreference(preference);
}
@@ -126,7 +126,7 @@ public class SpecialAppAccessListChildFragment<PF extends PreferenceFragmentComp
Context context = requireContext();
Role role = Roles.get(context).get(roleName);
UserHandle user = Process.myUserHandle();
- Intent intent = role.getManageIntentAsUser(user, context);
+ Intent intent = RoleUiBehaviorUtils.getManageIntentAsUser(role, user, context);
if (intent == null) {
intent = SpecialAppAccessActivity.createIntent(roleName, context);
}
diff --git a/PermissionController/src/com/android/permissioncontroller/role/utils/RoleUiBehaviorUtils.java b/PermissionController/src/com/android/permissioncontroller/role/utils/RoleUiBehaviorUtils.java
new file mode 100644
index 000000000..678ecdfd0
--- /dev/null
+++ b/PermissionController/src/com/android/permissioncontroller/role/utils/RoleUiBehaviorUtils.java
@@ -0,0 +1,151 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.permissioncontroller.role.utils;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ApplicationInfo;
+import android.os.Process;
+import android.os.UserHandle;
+import android.util.Log;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.preference.Preference;
+
+import com.android.permissioncontroller.role.model.Role;
+import com.android.permissioncontroller.role.ui.TwoTargetPreference;
+import com.android.permissioncontroller.role.ui.behavior.RoleUiBehavior;
+
+/**
+ * Utility methods for Role UI behavior
+ */
+public final class RoleUiBehaviorUtils {
+
+ private static final String LOG_TAG = RoleUiBehaviorUtils.class.getSimpleName();
+
+ /**
+ * Get the role ui behavior if available
+ */
+ @Nullable
+ private static RoleUiBehavior getUiBehavior(@NonNull Role role) {
+ String uiBehaviorName = role.getUiBehaviorName();
+ if (uiBehaviorName == null) {
+ return null;
+ }
+ RoleUiBehavior uiBehavior;
+ String uiBehaviorClassName = RoleUiBehavior.class.getPackage().getName() + '.'
+ + uiBehaviorName;
+ try {
+ uiBehavior = (RoleUiBehavior) Class.forName(uiBehaviorClassName).newInstance();
+ } catch (ClassNotFoundException | IllegalAccessException | InstantiationException e) {
+ Log.e(LOG_TAG, "Unable to instantiate UI behavior: " + uiBehaviorClassName, e);
+ return null;
+ }
+ return uiBehavior;
+ }
+
+ /**
+ * @see RoleUiBehavior#isVisibleAsUser
+ */
+ public static boolean isVisibleAsUser(@NonNull Role role, @NonNull UserHandle user,
+ @NonNull Context context) {
+ RoleUiBehavior uiBehavior = getUiBehavior(role);
+ if (uiBehavior == null) {
+ return role.isVisible();
+ }
+ return role.isVisible() && uiBehavior.isVisibleAsUser(role, user, context);
+ }
+
+ /**
+ * Check whether this role should be visible to user, for current user.
+ *
+ * @param context the `Context` to retrieve system services
+ *
+ * @return whether this role should be visible to user.
+ */
+ public static boolean isVisible(@NonNull Role role, @NonNull Context context) {
+ return isVisibleAsUser(role, Process.myUserHandle(), context);
+ }
+
+
+ /**
+ * @see RoleUiBehavior#getManageIntentAsUser
+ */
+ @Nullable
+ public static Intent getManageIntentAsUser(@NonNull Role role, @NonNull UserHandle user,
+ @NonNull Context context) {
+ RoleUiBehavior uiBehavior = getUiBehavior(role);
+ if (uiBehavior == null) {
+ return null;
+ }
+ return uiBehavior.getManageIntentAsUser(role, user, context);
+ }
+
+ /**
+ * @see RoleUiBehavior#preparePreferenceAsUser
+ */
+ public static void preparePreferenceAsUser(@NonNull Role role,
+ @NonNull TwoTargetPreference preference, @NonNull UserHandle user,
+ @NonNull Context context) {
+ RoleUiBehavior uiBehavior = getUiBehavior(role);
+ if (uiBehavior == null) {
+ return;
+ }
+ uiBehavior.preparePreferenceAsUser(role, preference, user, context);
+ }
+
+ /**
+ * @see RoleUiBehavior#isApplicationVisibleAsUser
+ */
+ public static boolean isApplicationVisibleAsUser(@NonNull Role role,
+ @NonNull ApplicationInfo applicationInfo, @NonNull UserHandle user,
+ @NonNull Context context) {
+ RoleUiBehavior uiBehavior = getUiBehavior(role);
+ if (uiBehavior == null) {
+ return true;
+ }
+ return uiBehavior.isApplicationVisibleAsUser(role, applicationInfo, user, context);
+ }
+
+ /**
+ * @see RoleUiBehavior#prepareApplicationPreferenceAsUser
+ */
+ public static void prepareApplicationPreferenceAsUser(@NonNull Role role,
+ @NonNull Preference preference, @NonNull ApplicationInfo applicationInfo,
+ @NonNull UserHandle user, @NonNull Context context) {
+ RoleUiBehavior uiBehavior = getUiBehavior(role);
+ if (uiBehavior == null) {
+ return;
+ }
+ uiBehavior.prepareApplicationPreferenceAsUser(role, preference, applicationInfo, user,
+ context);
+ }
+
+ /**
+ * @see RoleUiBehavior#getConfirmationMessage
+ */
+ @Nullable
+ public static CharSequence getConfirmationMessage(@NonNull Role role,
+ @NonNull String packageName, @NonNull Context context) {
+ RoleUiBehavior uiBehavior = getUiBehavior(role);
+ if (uiBehavior == null) {
+ return null;
+ }
+ return uiBehavior.getConfirmationMessage(role, packageName, context);
+ }
+}