summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--PermissionController/res/values/config.xml9
-rw-r--r--PermissionController/res/values/overlayable.xml11
-rw-r--r--PermissionController/res/values/strings.xml6
-rw-r--r--PermissionController/role-controller/java/com/android/role/controller/util/SignedPackage.java35
-rw-r--r--PermissionController/role-controller/java/com/android/role/controller/util/SignedPackageUtils.java22
-rw-r--r--PermissionController/src/com/android/permissioncontroller/role/ui/DefaultAppChildFragment.java78
-rw-r--r--PermissionController/src/com/android/permissioncontroller/role/ui/DefaultAppViewModel.java25
-rw-r--r--PermissionController/src/com/android/permissioncontroller/role/ui/behavior/AssistantRoleUiBehavior.java23
-rw-r--r--PermissionController/src/com/android/permissioncontroller/role/ui/behavior/RoleUiBehavior.java16
-rw-r--r--PermissionController/src/com/android/permissioncontroller/role/utils/RoleUiBehaviorUtils.java15
10 files changed, 223 insertions, 17 deletions
diff --git a/PermissionController/res/values/config.xml b/PermissionController/res/values/config.xml
index 675368cba..657dc07dd 100644
--- a/PermissionController/res/values/config.xml
+++ b/PermissionController/res/values/config.xml
@@ -19,6 +19,15 @@
<bool name="config_showBrowserRole">true</bool>
<bool name="config_showDialerRole">true</bool>
<bool name="config_showSmsRole">true</bool>
+ <!--
+ ~ Semicolon separated list of packages that are recommended for the assistant role.
+ ~ <p>
+ ~ This follows the same format as config_defaultAssistant and also requires a signing
+ ~ certificate digest (separated by a colon from the package name) if the app is not a system
+ ~ app.
+ -->
+ <string name="config_recommendedAssistants"></string>
+
<bool name="config_useAlternativePermGroupSummary">false</bool>
<bool name="config_useWindowBlur">false</bool>
<bool name="config_useMaterial3PermissionGrantDialog">false</bool>
diff --git a/PermissionController/res/values/overlayable.xml b/PermissionController/res/values/overlayable.xml
index e94c5bd04..72896fcdb 100644
--- a/PermissionController/res/values/overlayable.xml
+++ b/PermissionController/res/values/overlayable.xml
@@ -371,14 +371,15 @@
<item type="style" name="ThemeOverlay.PermissionSettings" />
<!-- END THEMES -->
- <!-- START VISIBILITY CONFIGS -->
- <!-- Assistant role uses: config_showDefaultAssistant -->
- <!-- Home role uses: config_showDefaultHome -->
- <!-- Emergency role uses: config_showDefaultEmergency -->
+ <!-- START ROLE CONFIGS -->
+ <!-- Assistant role uses android:bool/config_showDefaultAssistant -->
+ <!-- Home role uses android:bool/config_showDefaultHome -->
+ <!-- Emergency role uses android:bool/config_showDefaultEmergency -->
<item type="bool" name="config_showBrowserRole" />
<item type="bool" name="config_showDialerRole" />
<item type="bool" name="config_showSmsRole" />
- <!-- END VISIBILITY CONFIGS -->
+ <item type="string" name="config_recommendedAssistants" />
+ <!-- END ROLE CONFIGS -->
<!-- START CAR DIMENS -->
<item type="dimen" name="car_action_bar_height" />
diff --git a/PermissionController/res/values/strings.xml b/PermissionController/res/values/strings.xml
index 48747bd2a..5714a2460 100644
--- a/PermissionController/res/values/strings.xml
+++ b/PermissionController/res/values/strings.xml
@@ -1337,6 +1337,12 @@
<!-- Title for category of default apps for private profile [CHAR LIMIT=50] -->
<string name="default_apps_for_private_profile">Default for private space</string>
+ <!-- Title for category of apps that are optimized for the device [CHAR LIMIT=50] -->
+ <string name="default_app_recommended">Optimized for device</string>
+
+ <!-- Title for category of other apps [CHAR LIMIT=50] -->
+ <string name="default_app_others">Others</string>
+
<!-- Summary of a default app when there is no app set [CHAR LIMIT=60] -->
<string name="default_app_none">None</string>
diff --git a/PermissionController/role-controller/java/com/android/role/controller/util/SignedPackage.java b/PermissionController/role-controller/java/com/android/role/controller/util/SignedPackage.java
index a3869b349..b13ac3731 100644
--- a/PermissionController/role-controller/java/com/android/role/controller/util/SignedPackage.java
+++ b/PermissionController/role-controller/java/com/android/role/controller/util/SignedPackage.java
@@ -30,6 +30,7 @@ import androidx.annotation.Nullable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
+import java.util.Objects;
/**
* A package name with an optional signing certificate.
@@ -120,7 +121,7 @@ public class SignedPackage {
return signedPackages;
}
- /*
+ /**
* Checks whether this signed package is available, i.e. it is installed, and either has the
* specified signing certificate or is a system app if no signing certificate is specified.
*
@@ -152,4 +153,36 @@ public class SignedPackage {
}
return true;
}
+
+ /**
+ * Checks whether an {@link ApplicationInfo} matches this signed package, i.e. it has the same
+ * package name, and either has the specified signing certificate or is a system app if no
+ * signing certificate is specified.
+ *
+ * @param applicationInfo the {@link ApplicationInfo} to check for
+ * @param context the {@code Context} to retrieve system services
+ *
+ * @return whether the {@link ApplicationInfo} matches this signed package
+ */
+ public boolean matches(@NonNull ApplicationInfo applicationInfo, @NonNull Context context) {
+ if (!Objects.equals(applicationInfo.packageName, mPackageName)) {
+ return false;
+ }
+ if (mCertificate != null) {
+ UserHandle user = UserHandle.getUserHandleForUid(applicationInfo.uid);
+ if (!PackageUtils.hasSigningCertificateAsUser(mPackageName, mCertificate, user,
+ context)) {
+ Log.w(LOG_TAG, "Package doesn't have required signing certificate: "
+ + mPackageName);
+ return false;
+ }
+ } else {
+ if ((applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
+ Log.w(LOG_TAG, "Package didn't specify a signing certificate and isn't a" +
+ " system app: " + mPackageName);
+ return false;
+ }
+ }
+ return true;
+ }
}
diff --git a/PermissionController/role-controller/java/com/android/role/controller/util/SignedPackageUtils.java b/PermissionController/role-controller/java/com/android/role/controller/util/SignedPackageUtils.java
index 817c31c5f..169bed347 100644
--- a/PermissionController/role-controller/java/com/android/role/controller/util/SignedPackageUtils.java
+++ b/PermissionController/role-controller/java/com/android/role/controller/util/SignedPackageUtils.java
@@ -17,6 +17,7 @@
package com.android.role.controller.util;
import android.content.Context;
+import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.os.UserHandle;
@@ -81,4 +82,25 @@ public final class SignedPackageUtils {
}
return signedPackage.getPackageName();
}
+
+ /**
+ * Check whether an {@link ApplicationInfo} matches any of the {@link SignedPackage}s.
+ *
+ * @param applicationInfo the {@link ApplicationInfo} to check for
+ * @param signedPackages the list of {@link SignedPackage}s to check against
+ * @param context the {@code Context} to retrieve system services
+ *
+ * @return whether the {@link ApplicationInfo} matches any of the {@link SignedPackage}s
+ */
+ public static boolean matchesAny(@NonNull ApplicationInfo applicationInfo,
+ @NonNull List<SignedPackage> signedPackages, @NonNull Context context) {
+ int signedPackagesSize = signedPackages.size();
+ for (int i = 0; i < signedPackagesSize; i++) {
+ SignedPackage signedPackage = signedPackages.get(i);
+ if (signedPackage.matches(applicationInfo, context)) {
+ return true;
+ }
+ }
+ return false;
+ }
}
diff --git a/PermissionController/src/com/android/permissioncontroller/role/ui/DefaultAppChildFragment.java b/PermissionController/src/com/android/permissioncontroller/role/ui/DefaultAppChildFragment.java
index 5f870b1e3..268633c4f 100644
--- a/PermissionController/src/com/android/permissioncontroller/role/ui/DefaultAppChildFragment.java
+++ b/PermissionController/src/com/android/permissioncontroller/role/ui/DefaultAppChildFragment.java
@@ -32,6 +32,7 @@ import androidx.appcompat.content.res.AppCompatResources;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModelProvider;
import androidx.preference.Preference;
+import androidx.preference.PreferenceCategory;
import androidx.preference.PreferenceFragmentCompat;
import androidx.preference.PreferenceGroup;
import androidx.preference.PreferenceManager;
@@ -39,6 +40,7 @@ import androidx.preference.PreferenceScreen;
import androidx.preference.TwoStatePreference;
import com.android.modules.utils.build.SdkLevel;
+import com.android.permission.flags.Flags;
import com.android.permissioncontroller.R;
import com.android.permissioncontroller.permission.utils.Utils;
import com.android.permissioncontroller.role.utils.PackageUtils;
@@ -63,6 +65,10 @@ public class DefaultAppChildFragment<PF extends PreferenceFragmentCompat
implements DefaultAppConfirmationDialogFragment.Listener,
Preference.OnPreferenceClickListener {
+ private static final String PREFERENCE_KEY_RECOMMENDED_CATEGORY =
+ DefaultAppChildFragment.class.getName() + ".preference.RECOMMENDED_CATEGORY";
+ private static final String PREFERENCE_KEY_OTHERS_CATEGORY =
+ DefaultAppChildFragment.class.getName() + ".preference.OTHERS_CATEGORY";
private static final String PREFERENCE_KEY_NONE = DefaultAppChildFragment.class.getName()
+ ".preference.NONE";
private static final String PREFERENCE_KEY_DESCRIPTION = DefaultAppChildFragment.class.getName()
@@ -125,14 +131,21 @@ public class DefaultAppChildFragment<PF extends PreferenceFragmentCompat
ViewModelProvider.Factory viewModelFactory = new DefaultAppViewModel.Factory(mRole, mUser,
activity.getApplication());
mViewModel = new ViewModelProvider(this, viewModelFactory).get(DefaultAppViewModel.class);
+ mViewModel.getRecommendedLiveData().observe(this,
+ applicationItems -> onApplicationListChanged());
mViewModel.getLiveData().observe(this, applicationItems -> onApplicationListChanged());
mViewModel.getManageRoleHolderStateLiveData().observe(this,
this::onManageRoleHolderStateChanged);
}
private void onApplicationListChanged() {
- List<RoleApplicationItem> applicationItems = mViewModel.getLiveData().getValue();
- if (applicationItems == null) {
+ List<RoleApplicationItem> recommendedApplicationItems =
+ mViewModel.getRecommendedLiveData().getValue();
+ if (recommendedApplicationItems == null) {
+ return;
+ }
+ List<RoleApplicationItem> otherApplicationItems = mViewModel.getLiveData().getValue();
+ if (otherApplicationItems == null) {
return;
}
@@ -141,17 +154,43 @@ public class DefaultAppChildFragment<PF extends PreferenceFragmentCompat
Context context = preferenceManager.getContext();
PreferenceScreen preferenceScreen = preferenceFragment.getPreferenceScreen();
+ PreferenceCategory oldRecommendedPreferenceCategory = null;
+ PreferenceCategory oldOthersPreferenceCategory = null;
ArrayMap<String, Preference> oldPreferences = new ArrayMap<>();
if (preferenceScreen == null) {
preferenceScreen = preferenceManager.createPreferenceScreen(context);
preferenceFragment.setPreferenceScreen(preferenceScreen);
} else {
+ if (Flags.defaultAppsRecommendationEnabled()) {
+ oldRecommendedPreferenceCategory =
+ preferenceScreen.findPreference(PREFERENCE_KEY_RECOMMENDED_CATEGORY);
+ clearPreferenceCategory(oldRecommendedPreferenceCategory, oldPreferences);
+ oldOthersPreferenceCategory =
+ preferenceScreen.findPreference(PREFERENCE_KEY_OTHERS_CATEGORY);
+ clearPreferenceCategory(oldOthersPreferenceCategory, oldPreferences);
+ }
clearPreferences(preferenceScreen, oldPreferences);
}
- boolean noneChecked = !hasHolderApplication(applicationItems);
- addNonePreferenceIfNeeded(preferenceScreen, noneChecked, oldPreferences, context);
- addApplicationPreferences(preferenceScreen, applicationItems, oldPreferences, context);
+ if (Flags.defaultAppsRecommendationEnabled() && !recommendedApplicationItems.isEmpty()) {
+ addApplicationPreferenceCategory(oldRecommendedPreferenceCategory,
+ PREFERENCE_KEY_RECOMMENDED_CATEGORY,
+ getString(R.string.default_app_recommended), preferenceScreen, false, false,
+ recommendedApplicationItems, oldPreferences, context);
+ if (mRole.shouldShowNone() || !otherApplicationItems.isEmpty()) {
+ boolean noneChecked = !(hasHolderApplication(recommendedApplicationItems)
+ || hasHolderApplication(otherApplicationItems));
+ addApplicationPreferenceCategory(oldOthersPreferenceCategory,
+ PREFERENCE_KEY_OTHERS_CATEGORY, getString(R.string.default_app_others),
+ preferenceScreen, true, noneChecked, otherApplicationItems, oldPreferences,
+ context);
+ }
+ } else {
+ boolean noneChecked = !hasHolderApplication(otherApplicationItems);
+ addNonePreferenceIfNeeded(preferenceScreen, noneChecked, oldPreferences, context);
+ addApplicationPreferences(preferenceScreen, otherApplicationItems, oldPreferences,
+ context);
+ }
addNonPaymentNfcServicesPreference(preferenceScreen, oldPreferences, context);
addDescriptionPreference(preferenceScreen, oldPreferences);
@@ -159,6 +198,16 @@ public class DefaultAppChildFragment<PF extends PreferenceFragmentCompat
preferenceFragment.onPreferenceScreenChanged();
}
+ private static void clearPreferenceCategory(@Nullable PreferenceCategory preferenceCategory,
+ @NonNull ArrayMap<String, Preference> oldPreferences) {
+ if (preferenceCategory == null) {
+ return;
+ }
+ clearPreferences(preferenceCategory, oldPreferences);
+ preferenceCategory.getParent().removePreference(preferenceCategory);
+ preferenceCategory.setOrder(Preference.DEFAULT_ORDER);
+ }
+
private static void clearPreferences(@NonNull PreferenceGroup preferenceGroup,
@NonNull ArrayMap<String, Preference> oldPreferences) {
for (int i = preferenceGroup.getPreferenceCount() - 1; i >= 0; --i) {
@@ -170,6 +219,25 @@ public class DefaultAppChildFragment<PF extends PreferenceFragmentCompat
}
}
+ private void addApplicationPreferenceCategory(
+ @Nullable PreferenceCategory oldPreferenceCategory, @NonNull String key,
+ @Nullable String title, @NonNull PreferenceScreen preferenceScreen,
+ boolean addNonePreferenceIfNeeded, boolean noneChecked,
+ @NonNull List<RoleApplicationItem> applicationItems,
+ @NonNull ArrayMap<String, Preference> oldPreferences, @NonNull Context context) {
+ PreferenceCategory preferenceCategory = oldPreferenceCategory;
+ if (preferenceCategory == null) {
+ preferenceCategory = new PreferenceCategory(context);
+ preferenceCategory.setKey(key);
+ preferenceCategory.setTitle(title);
+ }
+ preferenceScreen.addPreference(preferenceCategory);
+ if (addNonePreferenceIfNeeded) {
+ addNonePreferenceIfNeeded(preferenceCategory, noneChecked, oldPreferences, context);
+ }
+ addApplicationPreferences(preferenceCategory, applicationItems, oldPreferences, context);
+ }
+
private static boolean hasHolderApplication(
@NonNull List<RoleApplicationItem> applicationItems) {
int applicationItemsSize = applicationItems.size();
diff --git a/PermissionController/src/com/android/permissioncontroller/role/ui/DefaultAppViewModel.java b/PermissionController/src/com/android/permissioncontroller/role/ui/DefaultAppViewModel.java
index 790c55d84..f4ba94f1d 100644
--- a/PermissionController/src/com/android/permissioncontroller/role/ui/DefaultAppViewModel.java
+++ b/PermissionController/src/com/android/permissioncontroller/role/ui/DefaultAppViewModel.java
@@ -28,10 +28,12 @@ import androidx.lifecycle.Transformations;
import androidx.lifecycle.ViewModel;
import androidx.lifecycle.ViewModelProvider;
+import com.android.permissioncontroller.role.utils.RoleUiBehaviorUtils;
import com.android.permissioncontroller.role.utils.UserUtils;
import com.android.role.controller.model.Role;
import java.util.List;
+import java.util.function.Predicate;
/**
* {@link ViewModel} for a default app.
@@ -46,6 +48,9 @@ public class DefaultAppViewModel extends AndroidViewModel {
private final UserHandle mUser;
@NonNull
+ private final LiveData<List<RoleApplicationItem>> mRecommendedLiveData;
+
+ @NonNull
private final LiveData<List<RoleApplicationItem>> mLiveData;
@NonNull
@@ -61,22 +66,34 @@ public class DefaultAppViewModel extends AndroidViewModel {
mUser = role.getExclusivity() == Role.EXCLUSIVITY_PROFILE_GROUP
? UserUtils.getProfileParentOrSelf(user, application)
: user;
- RoleLiveData liveData = new RoleLiveData(role, mUser, application);
+ RoleLiveData userLiveData = new RoleLiveData(role, mUser, application);
RoleSortFunction sortFunction = new RoleSortFunction(application);
+ LiveData<List<RoleApplicationItem>> liveData;
if (role.getExclusivity() == Role.EXCLUSIVITY_PROFILE_GROUP) {
// Context user might be work profile, ensure we get a non-null UserHandle if work
// profile exists. getWorkProfile returns null if context user is work profile.
UserHandle workProfile = UserUtils.getWorkProfileOrSelf(application);
if (workProfile != null) {
RoleLiveData workLiveData = new RoleLiveData(role, workProfile, application);
- mLiveData = Transformations.map(new MergeRoleLiveData(liveData, workLiveData),
+ liveData = Transformations.map(new MergeRoleLiveData(userLiveData, workLiveData),
sortFunction);
} else {
- mLiveData = Transformations.map(liveData, sortFunction);
+ liveData = Transformations.map(userLiveData, sortFunction);
}
} else {
- mLiveData = Transformations.map(liveData, sortFunction);
+ liveData = Transformations.map(userLiveData, sortFunction);
}
+ Predicate<RoleApplicationItem> recommendedApplicationFilter =
+ RoleUiBehaviorUtils.getRecommendedApplicationFilter(role, application);
+ mRecommendedLiveData = Transformations.map(liveData,
+ new ListLiveDataFilterFunction<>(recommendedApplicationFilter));
+ mLiveData = Transformations.map(liveData,
+ new ListLiveDataFilterFunction<>(recommendedApplicationFilter.negate()));
+ }
+
+ @NonNull
+ public LiveData<List<RoleApplicationItem>> getRecommendedLiveData() {
+ return mRecommendedLiveData;
}
@NonNull
diff --git a/PermissionController/src/com/android/permissioncontroller/role/ui/behavior/AssistantRoleUiBehavior.java b/PermissionController/src/com/android/permissioncontroller/role/ui/behavior/AssistantRoleUiBehavior.java
index 4df3ccf99..c74c3d519 100644
--- a/PermissionController/src/com/android/permissioncontroller/role/ui/behavior/AssistantRoleUiBehavior.java
+++ b/PermissionController/src/com/android/permissioncontroller/role/ui/behavior/AssistantRoleUiBehavior.java
@@ -25,8 +25,15 @@ import android.provider.Settings;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import com.android.permission.flags.Flags;
import com.android.permissioncontroller.R;
+import com.android.permissioncontroller.role.ui.RoleApplicationItem;
import com.android.role.controller.model.Role;
+import com.android.role.controller.util.SignedPackage;
+import com.android.role.controller.util.SignedPackageUtils;
+
+import java.util.List;
+import java.util.function.Predicate;
/***
* Class for UI behavior of Assistant role
@@ -39,14 +46,26 @@ public class AssistantRoleUiBehavior implements RoleUiBehavior {
@NonNull Context context) {
boolean isAutomotive =
context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE);
-
if (isAutomotive) {
return null;
}
-
return new Intent(Settings.ACTION_VOICE_INPUT_SETTINGS);
}
+ @NonNull
+ @Override
+ public Predicate<RoleApplicationItem> getRecommendedApplicationFilter(
+ @NonNull Role role, @NonNull Context context) {
+ if (Flags.defaultAppsRecommendationEnabled()) {
+ List<SignedPackage> signedPackages = SignedPackage.parseList(
+ context.getResources().getString(R.string.config_recommendedAssistants));
+ return applicationItem -> SignedPackageUtils.matchesAny(
+ applicationItem.getApplicationInfo(), signedPackages, context);
+ } else {
+ return RoleUiBehavior.super.getRecommendedApplicationFilter(role, context);
+ }
+ }
+
@Nullable
@Override
public CharSequence getConfirmationMessage(@NonNull Role role, @NonNull String packageName,
diff --git a/PermissionController/src/com/android/permissioncontroller/role/ui/behavior/RoleUiBehavior.java b/PermissionController/src/com/android/permissioncontroller/role/ui/behavior/RoleUiBehavior.java
index ae5c03676..e1bf213a0 100644
--- a/PermissionController/src/com/android/permissioncontroller/role/ui/behavior/RoleUiBehavior.java
+++ b/PermissionController/src/com/android/permissioncontroller/role/ui/behavior/RoleUiBehavior.java
@@ -26,10 +26,12 @@ import androidx.annotation.Nullable;
import androidx.preference.Preference;
import com.android.permissioncontroller.role.ui.RequestRoleItemView;
+import com.android.permissioncontroller.role.ui.RoleApplicationItem;
import com.android.permissioncontroller.role.ui.TwoTargetPreference;
import com.android.role.controller.model.Role;
import java.util.List;
+import java.util.function.Predicate;
/***
* Interface for UI behavior for roles
@@ -92,6 +94,20 @@ public interface RoleUiBehavior {
@NonNull UserHandle user, @NonNull Context context) {}
/**
+ * Get the filter for recommended applications of this role.
+ *
+ * @param role the role to get the recommended application filter for
+ * @param context the {@code Context} to retrieve system services
+ *
+ * @return the filter for recommended applications
+ */
+ @NonNull
+ default Predicate<RoleApplicationItem> getRecommendedApplicationFilter(
+ @NonNull Role role, @NonNull Context context) {
+ return applicationItem -> false;
+ }
+
+ /**
* Get the confirmation message for adding an application as a holder of this role.
*
* @param role the role to get confirmation message for
diff --git a/PermissionController/src/com/android/permissioncontroller/role/utils/RoleUiBehaviorUtils.java b/PermissionController/src/com/android/permissioncontroller/role/utils/RoleUiBehaviorUtils.java
index c11a74259..255d88ff0 100644
--- a/PermissionController/src/com/android/permissioncontroller/role/utils/RoleUiBehaviorUtils.java
+++ b/PermissionController/src/com/android/permissioncontroller/role/utils/RoleUiBehaviorUtils.java
@@ -26,12 +26,14 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.android.permissioncontroller.role.ui.RequestRoleItemView;
+import com.android.permissioncontroller.role.ui.RoleApplicationItem;
import com.android.permissioncontroller.role.ui.RoleApplicationPreference;
import com.android.permissioncontroller.role.ui.RolePreference;
import com.android.permissioncontroller.role.ui.behavior.RoleUiBehavior;
import com.android.role.controller.model.Role;
import java.util.List;
+import java.util.function.Predicate;
/**
* Utility methods for Role UI behavior
@@ -117,6 +119,19 @@ public final class RoleUiBehaviorUtils {
}
/**
+ * @see RoleUiBehavior#getRecommendedApplicationFilter
+ */
+ @NonNull
+ public static Predicate<RoleApplicationItem> getRecommendedApplicationFilter(
+ @NonNull Role role, @NonNull Context context) {
+ RoleUiBehavior uiBehavior = getUiBehavior(role);
+ if (uiBehavior == null) {
+ return applicationItem -> false;
+ }
+ return uiBehavior.getRecommendedApplicationFilter(role, context);
+ }
+
+ /**
* @see RoleUiBehavior#getConfirmationMessage
*/
@Nullable