summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--PermissionController/src/com/android/permissioncontroller/permission/ui/auto/dashboard/AutoPermissionUsageDetailsFragment.kt47
-rw-r--r--PermissionController/src/com/android/permissioncontroller/permission/ui/handheld/v34/AppDataSharingDetailsPreference.kt2
-rw-r--r--PermissionController/src/com/android/permissioncontroller/role/ui/DefaultAppChildFragment.java15
-rw-r--r--PermissionController/src/com/android/permissioncontroller/role/ui/DefaultAppListChildFragment.java15
-rw-r--r--PermissionController/src/com/android/permissioncontroller/role/ui/RoleApplicationPreference.java32
-rw-r--r--PermissionController/src/com/android/permissioncontroller/role/ui/RolePreference.java29
-rw-r--r--PermissionController/src/com/android/permissioncontroller/role/ui/TwoTargetPreference.java9
-rw-r--r--PermissionController/src/com/android/permissioncontroller/role/ui/UserRestrictionAwarePreference.java30
-rw-r--r--PermissionController/src/com/android/permissioncontroller/role/ui/UserRestrictionAwarePreferenceMixin.java69
-rw-r--r--PermissionController/src/com/android/permissioncontroller/role/ui/auto/AutoDefaultAppFragment.java6
-rw-r--r--PermissionController/src/com/android/permissioncontroller/role/ui/auto/AutoDefaultAppListFragment.java6
-rw-r--r--PermissionController/src/com/android/permissioncontroller/role/ui/auto/AutoRadioPreference.java (renamed from PermissionController/src/com/android/permissioncontroller/role/ui/auto/AutoDefaultAppPreference.java)23
-rw-r--r--PermissionController/src/com/android/permissioncontroller/role/ui/auto/AutoRolePreference.java (renamed from PermissionController/src/com/android/permissioncontroller/role/ui/auto/AutoSettingsPreference.java)33
-rw-r--r--PermissionController/src/com/android/permissioncontroller/role/ui/auto/AutoSpecialAppAccessFragment.java7
-rw-r--r--PermissionController/src/com/android/permissioncontroller/role/ui/auto/AutoSpecialAppAccessListFragment.java6
-rw-r--r--PermissionController/src/com/android/permissioncontroller/role/ui/auto/AutoSwitchPreference.java76
-rw-r--r--PermissionController/src/com/android/permissioncontroller/role/ui/handheld/HandheldDefaultAppListPreferenceFragment.java6
-rw-r--r--PermissionController/src/com/android/permissioncontroller/role/ui/handheld/HandheldDefaultAppPreferenceFragment.java7
-rw-r--r--PermissionController/src/com/android/permissioncontroller/role/ui/handheld/HandheldRadioPreference.java75
-rw-r--r--PermissionController/src/com/android/permissioncontroller/role/ui/handheld/HandheldRolePreference.java (renamed from PermissionController/src/com/android/permissioncontroller/role/ui/handheld/SettingsButtonPreference.java)30
-rw-r--r--PermissionController/src/com/android/permissioncontroller/role/ui/specialappaccess/SpecialAppAccessChildFragment.java16
-rw-r--r--PermissionController/src/com/android/permissioncontroller/role/ui/specialappaccess/SpecialAppAccessListChildFragment.java16
-rw-r--r--PermissionController/src/com/android/permissioncontroller/role/ui/specialappaccess/handheld/HandheldSpecialAppAccessListPreferenceFragment.java8
-rw-r--r--PermissionController/src/com/android/permissioncontroller/role/ui/specialappaccess/handheld/HandheldSpecialAppAccessPreferenceFragment.java7
-rw-r--r--PermissionController/src/com/android/permissioncontroller/role/ui/specialappaccess/handheld/HandheldSwitchPreference.java74
-rw-r--r--PermissionController/src/com/android/permissioncontroller/role/utils/RoleUiBehaviorUtils.java39
-rw-r--r--PermissionController/src/com/android/permissioncontroller/safetycenter/ui/IssueCardAnimator.kt108
-rw-r--r--PermissionController/src/com/android/permissioncontroller/safetycenter/ui/PreferenceHighlightManager.kt2
-rw-r--r--PermissionController/src/com/android/permissioncontroller/safetycenter/ui/SafetyBrandChipPreference.kt2
-rw-r--r--PermissionController/src/com/android/permissioncontroller/safetycenter/ui/SafetyCenterFragment.kt2
-rw-r--r--PermissionController/src/com/android/permissioncontroller/safetycenter/ui/SafetyGroupPreference.kt7
-rw-r--r--tests/functional/safetycenter/singleuser/src/android/safetycenter/functional/SafetyCenterNotificationTest.kt96
-rw-r--r--tests/functional/safetycenter/singleuser/src/android/safetycenter/functional/SafetyCenterShellCommandsTest.kt (renamed from tests/cts/safetycenter/src/android/safetycenter/cts/SafetyCenterShellCommandsTest.kt)44
-rw-r--r--tests/hostside/safetycenter/src/android/safetycenter/hostside/SafetyCenterInteractionLoggingHostTest.kt17
-rw-r--r--tests/utils/safetycenter/java/com/android/safetycenter/testing/Coroutines.kt3
-rw-r--r--tests/utils/safetycenter/java/com/android/safetycenter/testing/UiTestHelper.kt6
36 files changed, 749 insertions, 221 deletions
diff --git a/PermissionController/src/com/android/permissioncontroller/permission/ui/auto/dashboard/AutoPermissionUsageDetailsFragment.kt b/PermissionController/src/com/android/permissioncontroller/permission/ui/auto/dashboard/AutoPermissionUsageDetailsFragment.kt
index a16bc1ce4..481543eb6 100644
--- a/PermissionController/src/com/android/permissioncontroller/permission/ui/auto/dashboard/AutoPermissionUsageDetailsFragment.kt
+++ b/PermissionController/src/com/android/permissioncontroller/permission/ui/auto/dashboard/AutoPermissionUsageDetailsFragment.kt
@@ -112,8 +112,10 @@ class AutoPermissionUsageDetailsFragment :
activity?.finish()
return
}
- if (!requireArguments().containsKey(Intent.EXTRA_PERMISSION_GROUP_NAME) or
- (requireArguments().getString(Intent.EXTRA_PERMISSION_GROUP_NAME) == null)) {
+ if (
+ !requireArguments().containsKey(Intent.EXTRA_PERMISSION_GROUP_NAME) or
+ (requireArguments().getString(Intent.EXTRA_PERMISSION_GROUP_NAME) == null)
+ ) {
DumpableLog.e(LOG_TAG, "Missing argument ${Intent.EXTRA_USER}")
activity?.finish()
return
@@ -128,14 +130,19 @@ class AutoPermissionUsageDetailsFragment :
headerLabel =
resources.getString(
R.string.permission_group_usage_title,
- getPermGroupLabel(requireContext(), filterGroup))
+ getPermGroupLabel(requireContext(), filterGroup)
+ )
val context = preferenceManager.getContext()
permissionUsages = PermissionUsages(context)
roleManager = Utils.getSystemServiceSafe(context, RoleManager::class.java)
val usageViewModelFactory =
PermissionUsageDetailsViewModelFactoryLegacy(
- PermissionControllerApplication.get(), roleManager, filterGroup, sessionId)
+ PermissionControllerApplication.get(),
+ roleManager,
+ filterGroup,
+ sessionId
+ )
usageViewModel =
ViewModelProvider(this, usageViewModelFactory)[
PermissionUsageDetailsViewModelLegacy::class.java]
@@ -157,7 +164,11 @@ class AutoPermissionUsageDetailsFragment :
/** Reloads the data to show. */
private fun reloadData() {
usageViewModel.loadPermissionUsages(
- requireActivity().getLoaderManager(), permissionUsages, this, FILTER_24_HOURS)
+ requireActivity().getLoaderManager(),
+ permissionUsages,
+ this,
+ FILTER_24_HOURS
+ )
if (finishedInitialLoad) {
setLoading(true)
}
@@ -176,7 +187,8 @@ class AutoPermissionUsageDetailsFragment :
PermissionControllerStatsLog.write(
PERMISSION_USAGE_FRAGMENT_INTERACTION,
sessionId,
- PERMISSION_USAGE_FRAGMENT_INTERACTION__ACTION__SHOW_SYSTEM_CLICKED)
+ PERMISSION_USAGE_FRAGMENT_INTERACTION__ACTION__SHOW_SYSTEM_CLICKED
+ )
}
showSystem = !showSystem
updateAction()
@@ -206,19 +218,25 @@ class AutoPermissionUsageDetailsFragment :
val uiData =
usageViewModel.buildPermissionUsageDetailsUiData(
- appPermissionUsages, showSystem, SHOW_7_DAYS)
+ appPermissionUsages,
+ showSystem,
+ SHOW_7_DAYS
+ )
if (hasSystemApps != uiData.shouldDisplayShowSystemToggle) {
hasSystemApps = uiData.shouldDisplayShowSystemToggle
updateAction()
}
- val category = AtomicReference(PreferenceCategory(context))
+ val category = AtomicReference(PreferenceCategory(requireContext()))
preferenceScreen.addPreference(category.get())
AppDataLoader(context) {
renderHistoryPreferences(
- uiData.getHistoryPreferenceDataList(), category, preferenceScreen)
+ uiData.getHistoryPreferenceDataList(),
+ category,
+ preferenceScreen
+ )
setLoading(false)
finishedInitialLoad = true
@@ -239,7 +257,8 @@ class AutoPermissionUsageDetailsFragment :
summary =
getString(
R.string.permission_group_usage_subtitle_24h,
- getPermGroupLabel(requireContext(), filterGroup))
+ getPermGroupLabel(requireContext(), filterGroup)
+ )
isSelectable = false
}
preferenceScreen.addPreference(preference)
@@ -252,7 +271,8 @@ class AutoPermissionUsageDetailsFragment :
summary =
getString(
R.string.manage_permission_summary,
- getPermGroupLabel(requireContext(), filterGroup))
+ getPermGroupLabel(requireContext(), filterGroup)
+ )
onPreferenceClickListener =
Preference.OnPreferenceClickListener {
val intent =
@@ -279,12 +299,13 @@ class AutoPermissionUsageDetailsFragment :
val currentDateMs =
ZonedDateTime.ofInstant(
Instant.ofEpochMilli(usageTimestamp),
- Clock.system(ZoneId.systemDefault()).zone)
+ Clock.system(ZoneId.systemDefault()).zone
+ )
.truncatedTo(ChronoUnit.DAYS)
.toEpochSecond() * 1000L
if (currentDateMs != previousDateMs) {
if (previousDateMs != 0L) {
- category.set(PreferenceCategory(context))
+ category.set(PreferenceCategory(requireContext()))
preferenceScreen.addPreference(category.get())
}
if (usageTimestamp > MIDNIGHT_TODAY) {
diff --git a/PermissionController/src/com/android/permissioncontroller/permission/ui/handheld/v34/AppDataSharingDetailsPreference.kt b/PermissionController/src/com/android/permissioncontroller/permission/ui/handheld/v34/AppDataSharingDetailsPreference.kt
index 014627c3c..70d0632f9 100644
--- a/PermissionController/src/com/android/permissioncontroller/permission/ui/handheld/v34/AppDataSharingDetailsPreference.kt
+++ b/PermissionController/src/com/android/permissioncontroller/permission/ui/handheld/v34/AppDataSharingDetailsPreference.kt
@@ -45,7 +45,7 @@ class AppDataSharingDetailsPreference : Preference {
}
override fun onBindViewHolder(holder: PreferenceViewHolder) {
- val noUpdatesMessage = holder.findViewById(R.id.no_updates_message)
+ val noUpdatesMessage = holder.findViewById(R.id.no_updates_message)!!
noUpdatesMessage.isVisible = showNoUpdates
super.onBindViewHolder(holder)
}
diff --git a/PermissionController/src/com/android/permissioncontroller/role/ui/DefaultAppChildFragment.java b/PermissionController/src/com/android/permissioncontroller/role/ui/DefaultAppChildFragment.java
index 06e5ed264..a8b16c521 100644
--- a/PermissionController/src/com/android/permissioncontroller/role/ui/DefaultAppChildFragment.java
+++ b/PermissionController/src/com/android/permissioncontroller/role/ui/DefaultAppChildFragment.java
@@ -196,20 +196,25 @@ public class DefaultAppChildFragment<PF extends PreferenceFragmentCompat
@NonNull CharSequence title, boolean checked, @Nullable ApplicationInfo applicationInfo,
@NonNull ArrayMap<String, Preference> oldPreferences,
@NonNull PreferenceScreen preferenceScreen, @NonNull Context context) {
- TwoStatePreference preference = (TwoStatePreference) oldPreferences.get(key);
- if (preference == null) {
- preference = requirePreferenceFragment().createApplicationPreference();
+ RoleApplicationPreference roleApplicationPreference =
+ (RoleApplicationPreference) oldPreferences.get(key);
+ TwoStatePreference preference;
+ if (roleApplicationPreference == null) {
+ roleApplicationPreference = requirePreferenceFragment().createApplicationPreference();
+ preference = roleApplicationPreference.asTwoStatePreference();
preference.setKey(key);
preference.setIcon(icon);
preference.setTitle(title);
preference.setPersistent(false);
preference.setOnPreferenceChangeListener((preference2, newValue) -> false);
preference.setOnPreferenceClickListener(this);
+ } else {
+ preference = roleApplicationPreference.asTwoStatePreference();
}
preference.setChecked(checked);
if (applicationInfo != null) {
- RoleUiBehaviorUtils.prepareApplicationPreferenceAsUser(mRole, preference,
+ RoleUiBehaviorUtils.prepareApplicationPreferenceAsUser(mRole, roleApplicationPreference,
applicationInfo, mUser, context);
}
@@ -281,7 +286,7 @@ public class DefaultAppChildFragment<PF extends PreferenceFragmentCompat
* @return a new preference for an application
*/
@NonNull
- TwoStatePreference createApplicationPreference();
+ RoleApplicationPreference createApplicationPreference();
/**
* Create a new preference for the footer.
diff --git a/PermissionController/src/com/android/permissioncontroller/role/ui/DefaultAppListChildFragment.java b/PermissionController/src/com/android/permissioncontroller/role/ui/DefaultAppListChildFragment.java
index 3c8af1136..f9a0193bd 100644
--- a/PermissionController/src/com/android/permissioncontroller/role/ui/DefaultAppListChildFragment.java
+++ b/PermissionController/src/com/android/permissioncontroller/role/ui/DefaultAppListChildFragment.java
@@ -167,15 +167,19 @@ public class DefaultAppListChildFragment<PF extends PreferenceFragmentCompat
RoleItem roleItem = roleItems.get(i);
Role role = roleItem.getRole();
- Preference preference = oldPreferences.get(role.getName());
- if (preference == null) {
- preference = (Preference) preferenceFragment.createPreference();
+ RolePreference rolePreference = (RolePreference) oldPreferences.get(role.getName());
+ Preference preference;
+ if (rolePreference == null) {
+ rolePreference = preferenceFragment.createPreference();
+ preference = rolePreference.asPreference();
preference.setKey(role.getName());
preference.setIconSpaceReserved(true);
preference.setTitle(role.getShortLabelResource());
preference.setPersistent(false);
preference.setOnPreferenceClickListener(listener);
preference.getExtras().putParcelable(Intent.EXTRA_USER, user);
+ } else {
+ preference = rolePreference.asPreference();
}
List<ApplicationInfo> holderApplicationInfos = roleItem.getHolderApplicationInfos();
@@ -187,8 +191,7 @@ public class DefaultAppListChildFragment<PF extends PreferenceFragmentCompat
preference.setIcon(Utils.getBadgedIcon(context, holderApplicationInfo));
preference.setSummary(Utils.getAppLabel(holderApplicationInfo, context));
}
- RoleUiBehaviorUtils.preparePreferenceAsUser(role, (TwoTargetPreference) preference,
- user, context);
+ RoleUiBehaviorUtils.preparePreferenceAsUser(role, rolePreference, user, context);
preferenceGroup.addPreference(preference);
}
}
@@ -283,7 +286,7 @@ public class DefaultAppListChildFragment<PF extends PreferenceFragmentCompat
* @return a new preference for a default app
*/
@NonNull
- TwoTargetPreference createPreference();
+ RolePreference createPreference();
/**
* Callback when changes have been made to the {@link PreferenceScreen} of the parent
diff --git a/PermissionController/src/com/android/permissioncontroller/role/ui/RoleApplicationPreference.java b/PermissionController/src/com/android/permissioncontroller/role/ui/RoleApplicationPreference.java
new file mode 100644
index 000000000..1b5b27971
--- /dev/null
+++ b/PermissionController/src/com/android/permissioncontroller/role/ui/RoleApplicationPreference.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2023 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;
+
+import androidx.annotation.NonNull;
+import androidx.preference.TwoStatePreference;
+
+/**
+ * Preference for application being a candidate or holding a role.
+ */
+public interface RoleApplicationPreference extends UserRestrictionAwarePreference {
+
+ /**
+ * Get instance of {@code this} as {@link TwoStatePreference}.
+ */
+ @NonNull
+ TwoStatePreference asTwoStatePreference();
+}
diff --git a/PermissionController/src/com/android/permissioncontroller/role/ui/RolePreference.java b/PermissionController/src/com/android/permissioncontroller/role/ui/RolePreference.java
new file mode 100644
index 000000000..442963ce6
--- /dev/null
+++ b/PermissionController/src/com/android/permissioncontroller/role/ui/RolePreference.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2023 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;
+
+import androidx.preference.Preference;
+
+/**
+ * Preference used by the default apps list UI.
+ */
+public interface RolePreference extends TwoTargetPreference, UserRestrictionAwarePreference {
+ /**
+ * Return this preference as {@link Preference}.
+ */
+ Preference asPreference();
+}
diff --git a/PermissionController/src/com/android/permissioncontroller/role/ui/TwoTargetPreference.java b/PermissionController/src/com/android/permissioncontroller/role/ui/TwoTargetPreference.java
index 23044b833..3a8cd55d3 100644
--- a/PermissionController/src/com/android/permissioncontroller/role/ui/TwoTargetPreference.java
+++ b/PermissionController/src/com/android/permissioncontroller/role/ui/TwoTargetPreference.java
@@ -18,6 +18,7 @@ package com.android.permissioncontroller.role.ui;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import androidx.preference.Preference;
/**
* {@link androidx.preference.Preference} with the widget layout as a separate target.
@@ -38,6 +39,11 @@ public interface TwoTargetPreference {
void setOnSecondTargetClickListener(@Nullable OnSecondTargetClickListener listener);
/**
+ * Return this preference as {@link Preference}.
+ */
+ Preference asPreference();
+
+ /**
* Listener for second target click.
*/
interface OnSecondTargetClickListener {
@@ -49,7 +55,4 @@ public interface TwoTargetPreference {
*/
void onSecondTargetClick(@NonNull TwoTargetPreference preference);
}
-
- /** @see androidx.preference.Preference#setEnabled(boolean) */
- void setEnabled(boolean enabled);
}
diff --git a/PermissionController/src/com/android/permissioncontroller/role/ui/UserRestrictionAwarePreference.java b/PermissionController/src/com/android/permissioncontroller/role/ui/UserRestrictionAwarePreference.java
new file mode 100644
index 000000000..e6bc9bab6
--- /dev/null
+++ b/PermissionController/src/com/android/permissioncontroller/role/ui/UserRestrictionAwarePreference.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2023 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;
+
+import androidx.annotation.Nullable;
+
+/**
+ * Preference that is aware of user restrictions that can block them.
+ */
+public interface UserRestrictionAwarePreference {
+
+ /**
+ * Specifies user restriction that blocks this preference.
+ */
+ void setUserRestriction(@Nullable String userRestriction);
+}
diff --git a/PermissionController/src/com/android/permissioncontroller/role/ui/UserRestrictionAwarePreferenceMixin.java b/PermissionController/src/com/android/permissioncontroller/role/ui/UserRestrictionAwarePreferenceMixin.java
new file mode 100644
index 000000000..033507991
--- /dev/null
+++ b/PermissionController/src/com/android/permissioncontroller/role/ui/UserRestrictionAwarePreferenceMixin.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2023 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;
+
+import android.app.admin.DevicePolicyManager;
+import android.content.Intent;
+import android.provider.Settings;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.preference.Preference;
+import androidx.preference.PreferenceViewHolder;
+
+/**
+ * Mixin for implementing {@link UserRestrictionAwarePreference}.
+ */
+public class UserRestrictionAwarePreferenceMixin {
+
+ @NonNull
+ private final Preference mPreference;
+ @Nullable
+ private String mUserRestriction = null;
+
+ public UserRestrictionAwarePreferenceMixin(@NonNull Preference preference) {
+ mPreference = preference;
+ }
+
+ /**
+ * Implementation for {@link UserRestrictionAwarePreference#setUserRestriction}.
+ */
+ public void setUserRestriction(@Nullable String userRestriction) {
+ mUserRestriction = userRestriction;
+ mPreference.setEnabled(mUserRestriction == null);
+ }
+
+ /**
+ * Call after {@link Preference#onBindViewHolder} to apply blocking effects.
+ */
+ public void onAfterBindViewHolder(@NonNull PreferenceViewHolder holder) {
+ if (mUserRestriction != null) {
+ // We set the item view to enabled to make the preference row clickable.
+ // Normal disabled preferences have the whole view hierarchy disabled, so by making only
+ // the top-level itemView enabled, we don't change the fact that the whole preference
+ // still "looks" disabled (see Preference.onBindViewHolder).
+ // Preference.onBindViewHolder sets the onClickListener as well on each preference, so
+ // we don't need to unset the listener here (we wouldn't know the correct one anyway).
+ // This approach is used already by com.android.settingslib.RestrictedPreferenceHelper.
+ holder.itemView.setEnabled(true);
+ Intent intent = new Intent(Settings.ACTION_SHOW_ADMIN_SUPPORT_DETAILS)
+ .putExtra(DevicePolicyManager.EXTRA_RESTRICTION, mUserRestriction);
+ holder.itemView.setOnClickListener(
+ (view) -> holder.itemView.getContext().startActivity(intent));
+ }
+ }
+}
diff --git a/PermissionController/src/com/android/permissioncontroller/role/ui/auto/AutoDefaultAppFragment.java b/PermissionController/src/com/android/permissioncontroller/role/ui/auto/AutoDefaultAppFragment.java
index dbd4c7c03..dc6c03d09 100644
--- a/PermissionController/src/com/android/permissioncontroller/role/ui/auto/AutoDefaultAppFragment.java
+++ b/PermissionController/src/com/android/permissioncontroller/role/ui/auto/AutoDefaultAppFragment.java
@@ -23,11 +23,11 @@ import android.os.UserHandle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.preference.Preference;
-import androidx.preference.TwoStatePreference;
import com.android.permissioncontroller.R;
import com.android.permissioncontroller.auto.AutoSettingsFrameFragment;
import com.android.permissioncontroller.role.ui.DefaultAppChildFragment;
+import com.android.permissioncontroller.role.ui.RoleApplicationPreference;
import com.android.role.controller.model.Role;
/** Screen to pick a default app for a particular {@link Role}. */
@@ -90,8 +90,8 @@ public class AutoDefaultAppFragment extends AutoSettingsFrameFragment implements
@NonNull
@Override
- public TwoStatePreference createApplicationPreference() {
- return new AutoDefaultAppPreference(requireContext());
+ public RoleApplicationPreference createApplicationPreference() {
+ return new AutoRadioPreference(requireContext());
}
@NonNull
diff --git a/PermissionController/src/com/android/permissioncontroller/role/ui/auto/AutoDefaultAppListFragment.java b/PermissionController/src/com/android/permissioncontroller/role/ui/auto/AutoDefaultAppListFragment.java
index b74caa7ed..081e3153b 100644
--- a/PermissionController/src/com/android/permissioncontroller/role/ui/auto/AutoDefaultAppListFragment.java
+++ b/PermissionController/src/com/android/permissioncontroller/role/ui/auto/AutoDefaultAppListFragment.java
@@ -24,7 +24,7 @@ import androidx.annotation.Nullable;
import com.android.permissioncontroller.R;
import com.android.permissioncontroller.auto.AutoSettingsFrameFragment;
import com.android.permissioncontroller.role.ui.DefaultAppListChildFragment;
-import com.android.permissioncontroller.role.ui.TwoTargetPreference;
+import com.android.permissioncontroller.role.ui.RolePreference;
/** Shows various roles for which a default app can be picked. */
public class AutoDefaultAppListFragment extends AutoSettingsFrameFragment implements
@@ -57,8 +57,8 @@ public class AutoDefaultAppListFragment extends AutoSettingsFrameFragment implem
@NonNull
@Override
- public TwoTargetPreference createPreference() {
- return new AutoSettingsPreference(requireContext());
+ public RolePreference createPreference() {
+ return new AutoRolePreference(requireContext());
}
@Override
diff --git a/PermissionController/src/com/android/permissioncontroller/role/ui/auto/AutoDefaultAppPreference.java b/PermissionController/src/com/android/permissioncontroller/role/ui/auto/AutoRadioPreference.java
index c91e40561..97a3dad26 100644
--- a/PermissionController/src/com/android/permissioncontroller/role/ui/auto/AutoDefaultAppPreference.java
+++ b/PermissionController/src/com/android/permissioncontroller/role/ui/auto/AutoRadioPreference.java
@@ -19,16 +19,23 @@ package com.android.permissioncontroller.role.ui.auto;
import android.content.Context;
import android.widget.RadioButton;
+import androidx.annotation.Nullable;
import androidx.core.content.res.TypedArrayUtils;
import androidx.preference.PreferenceViewHolder;
import androidx.preference.TwoStatePreference;
import com.android.permissioncontroller.R;
+import com.android.permissioncontroller.role.ui.RoleApplicationPreference;
+import com.android.permissioncontroller.role.ui.UserRestrictionAwarePreferenceMixin;
/** Preference used to represent apps that can be picked as a default app. */
-public class AutoDefaultAppPreference extends TwoStatePreference {
+public class AutoRadioPreference extends TwoStatePreference implements
+ RoleApplicationPreference {
- public AutoDefaultAppPreference(Context context) {
+ private final UserRestrictionAwarePreferenceMixin mUserRestrictionAwarePreferenceMixin =
+ new UserRestrictionAwarePreferenceMixin(this);
+
+ public AutoRadioPreference(Context context) {
super(context, null, TypedArrayUtils.getAttr(context, R.attr.preferenceStyle,
android.R.attr.preferenceStyle));
init();
@@ -45,6 +52,18 @@ public class AutoDefaultAppPreference extends TwoStatePreference {
RadioButton radioButton = (RadioButton) holder.findViewById(R.id.radio_button);
radioButton.setChecked(isChecked());
+
+ mUserRestrictionAwarePreferenceMixin.onAfterBindViewHolder(holder);
+ }
+
+ @Override
+ public void setUserRestriction(@Nullable String userRestriction) {
+ mUserRestrictionAwarePreferenceMixin.setUserRestriction(userRestriction);
+ }
+
+ @Override
+ public AutoRadioPreference asTwoStatePreference() {
+ return this;
}
}
diff --git a/PermissionController/src/com/android/permissioncontroller/role/ui/auto/AutoSettingsPreference.java b/PermissionController/src/com/android/permissioncontroller/role/ui/auto/AutoRolePreference.java
index ba5b17be9..d2f1b6cde 100644
--- a/PermissionController/src/com/android/permissioncontroller/role/ui/auto/AutoSettingsPreference.java
+++ b/PermissionController/src/com/android/permissioncontroller/role/ui/auto/AutoRolePreference.java
@@ -22,34 +22,57 @@ import android.util.AttributeSet;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.preference.Preference;
+import androidx.preference.PreferenceViewHolder;
+import com.android.permissioncontroller.role.ui.RolePreference;
import com.android.permissioncontroller.role.ui.TwoTargetPreference;
+import com.android.permissioncontroller.role.ui.UserRestrictionAwarePreferenceMixin;
/**
* Preference for use in auto lists. Extends {@link TwoTargetPreference} in order to make sure of
* shared logic between phone and auto settings UI.
*/
-public class AutoSettingsPreference extends Preference implements TwoTargetPreference {
+public class AutoRolePreference extends Preference implements RolePreference {
- public AutoSettingsPreference(@NonNull Context context,
+ private UserRestrictionAwarePreferenceMixin mUserRestrictionAwarePreferenceMixin =
+ new UserRestrictionAwarePreferenceMixin(this);
+
+ public AutoRolePreference(@NonNull Context context,
@Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
- public AutoSettingsPreference(@NonNull Context context, @Nullable AttributeSet attrs,
+ public AutoRolePreference(@NonNull Context context, @Nullable AttributeSet attrs,
int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
- public AutoSettingsPreference(@NonNull Context context, @Nullable AttributeSet attrs) {
+ public AutoRolePreference(@NonNull Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
- public AutoSettingsPreference(@NonNull Context context) {
+ public AutoRolePreference(@NonNull Context context) {
super(context);
}
@Override
public void setOnSecondTargetClickListener(@Nullable OnSecondTargetClickListener listener) {
}
+
+ @Override
+ public void setUserRestriction(@Nullable String userRestriction) {
+ mUserRestrictionAwarePreferenceMixin.setUserRestriction(userRestriction);
+ }
+
+ @Override
+ public void onBindViewHolder(PreferenceViewHolder holder) {
+ super.onBindViewHolder(holder);
+
+ mUserRestrictionAwarePreferenceMixin.onAfterBindViewHolder(holder);
+ }
+
+ @Override
+ public AutoRolePreference asPreference() {
+ return this;
+ }
}
diff --git a/PermissionController/src/com/android/permissioncontroller/role/ui/auto/AutoSpecialAppAccessFragment.java b/PermissionController/src/com/android/permissioncontroller/role/ui/auto/AutoSpecialAppAccessFragment.java
index c561420da..c37735427 100644
--- a/PermissionController/src/com/android/permissioncontroller/role/ui/auto/AutoSpecialAppAccessFragment.java
+++ b/PermissionController/src/com/android/permissioncontroller/role/ui/auto/AutoSpecialAppAccessFragment.java
@@ -22,11 +22,10 @@ import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.preference.Preference;
-import androidx.preference.SwitchPreference;
-import androidx.preference.TwoStatePreference;
import com.android.permissioncontroller.R;
import com.android.permissioncontroller.auto.AutoSettingsFrameFragment;
+import com.android.permissioncontroller.role.ui.RoleApplicationPreference;
import com.android.permissioncontroller.role.ui.specialappaccess.SpecialAppAccessChildFragment;
/** Automotive fragment for displaying special app access for a role. */
@@ -81,8 +80,8 @@ public class AutoSpecialAppAccessFragment extends AutoSettingsFrameFragment impl
@NonNull
@Override
- public TwoStatePreference createApplicationPreference() {
- return new SwitchPreference(requireContext());
+ public RoleApplicationPreference createApplicationPreference() {
+ return new AutoSwitchPreference(requireContext());
}
@NonNull
diff --git a/PermissionController/src/com/android/permissioncontroller/role/ui/auto/AutoSpecialAppAccessListFragment.java b/PermissionController/src/com/android/permissioncontroller/role/ui/auto/AutoSpecialAppAccessListFragment.java
index e2dce4a94..59e6766cc 100644
--- a/PermissionController/src/com/android/permissioncontroller/role/ui/auto/AutoSpecialAppAccessListFragment.java
+++ b/PermissionController/src/com/android/permissioncontroller/role/ui/auto/AutoSpecialAppAccessListFragment.java
@@ -24,7 +24,7 @@ import androidx.annotation.Nullable;
import com.android.permissioncontroller.R;
import com.android.permissioncontroller.auto.AutoSettingsFrameFragment;
-import com.android.permissioncontroller.role.ui.TwoTargetPreference;
+import com.android.permissioncontroller.role.ui.RolePreference;
import com.android.permissioncontroller.role.ui.specialappaccess.SpecialAppAccessListChildFragment;
/** Automotive fragment for the list of role related special app accesses. */
@@ -59,8 +59,8 @@ public class AutoSpecialAppAccessListFragment extends AutoSettingsFrameFragment
@NonNull
@Override
- public TwoTargetPreference createPreference(@NonNull Context context) {
- return new AutoSettingsPreference(context);
+ public RolePreference createPreference(@NonNull Context context) {
+ return new AutoRolePreference(context);
}
@Override
diff --git a/PermissionController/src/com/android/permissioncontroller/role/ui/auto/AutoSwitchPreference.java b/PermissionController/src/com/android/permissioncontroller/role/ui/auto/AutoSwitchPreference.java
new file mode 100644
index 000000000..900e58551
--- /dev/null
+++ b/PermissionController/src/com/android/permissioncontroller/role/ui/auto/AutoSwitchPreference.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2023 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.auto;
+
+import android.content.Context;
+import android.util.AttributeSet;
+
+import androidx.annotation.AttrRes;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.annotation.StyleRes;
+import androidx.preference.PreferenceViewHolder;
+import androidx.preference.SwitchPreference;
+
+import com.android.permissioncontroller.role.ui.RoleApplicationPreference;
+import com.android.permissioncontroller.role.ui.UserRestrictionAwarePreferenceMixin;
+
+/**
+ * Role application preference represented as a switch.
+ */
+public class AutoSwitchPreference extends SwitchPreference
+ implements RoleApplicationPreference {
+
+ private UserRestrictionAwarePreferenceMixin mUserRestrictionAwarePreferenceMixin =
+ new UserRestrictionAwarePreferenceMixin(this);
+
+ public AutoSwitchPreference(@NonNull Context context, @Nullable AttributeSet attrs,
+ @AttrRes int defStyleAttr, @StyleRes int defStyleRes) {
+ super(context, attrs, defStyleAttr, defStyleRes);
+ }
+
+ public AutoSwitchPreference(@NonNull Context context, @Nullable AttributeSet attrs,
+ @StyleRes int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ }
+
+ public AutoSwitchPreference(@NonNull Context context, @Nullable AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public AutoSwitchPreference(@NonNull Context context) {
+ super(context);
+ }
+
+ @Override
+ public void setUserRestriction(@Nullable String userRestriction) {
+ mUserRestrictionAwarePreferenceMixin.setUserRestriction(userRestriction);
+ }
+
+ @Override
+ public void onBindViewHolder(PreferenceViewHolder holder) {
+ super.onBindViewHolder(holder);
+
+ mUserRestrictionAwarePreferenceMixin.onAfterBindViewHolder(holder);
+ }
+
+ @NonNull
+ @Override
+ public AutoSwitchPreference asTwoStatePreference() {
+ return this;
+ }
+}
diff --git a/PermissionController/src/com/android/permissioncontroller/role/ui/handheld/HandheldDefaultAppListPreferenceFragment.java b/PermissionController/src/com/android/permissioncontroller/role/ui/handheld/HandheldDefaultAppListPreferenceFragment.java
index b76b8c561..da920ea7f 100644
--- a/PermissionController/src/com/android/permissioncontroller/role/ui/handheld/HandheldDefaultAppListPreferenceFragment.java
+++ b/PermissionController/src/com/android/permissioncontroller/role/ui/handheld/HandheldDefaultAppListPreferenceFragment.java
@@ -23,7 +23,7 @@ import androidx.annotation.Nullable;
import androidx.preference.PreferenceFragmentCompat;
import com.android.permissioncontroller.role.ui.DefaultAppListChildFragment;
-import com.android.permissioncontroller.role.ui.TwoTargetPreference;
+import com.android.permissioncontroller.role.ui.RolePreference;
/**
* Handheld preference fragment for the list of default apps.
@@ -62,8 +62,8 @@ public class HandheldDefaultAppListPreferenceFragment extends PreferenceFragment
@NonNull
@Override
- public TwoTargetPreference createPreference() {
- return new SettingsButtonPreference(requireContext());
+ public RolePreference createPreference() {
+ return new HandheldRolePreference(requireContext());
}
@Override
diff --git a/PermissionController/src/com/android/permissioncontroller/role/ui/handheld/HandheldDefaultAppPreferenceFragment.java b/PermissionController/src/com/android/permissioncontroller/role/ui/handheld/HandheldDefaultAppPreferenceFragment.java
index 94c07ef67..b8156590a 100644
--- a/PermissionController/src/com/android/permissioncontroller/role/ui/handheld/HandheldDefaultAppPreferenceFragment.java
+++ b/PermissionController/src/com/android/permissioncontroller/role/ui/handheld/HandheldDefaultAppPreferenceFragment.java
@@ -24,11 +24,10 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.preference.Preference;
import androidx.preference.PreferenceFragmentCompat;
-import androidx.preference.TwoStatePreference;
import com.android.permissioncontroller.role.ui.DefaultAppChildFragment;
+import com.android.permissioncontroller.role.ui.RoleApplicationPreference;
import com.android.settingslib.widget.FooterPreference;
-import com.android.settingslib.widget.SelectorWithWidgetPreference;
/**
* Handheld preference fragment for a default app.
@@ -96,8 +95,8 @@ public class HandheldDefaultAppPreferenceFragment extends PreferenceFragmentComp
@NonNull
@Override
- public TwoStatePreference createApplicationPreference() {
- return new SelectorWithWidgetPreference(requireContext());
+ public RoleApplicationPreference createApplicationPreference() {
+ return new HandheldRadioPreference(requireContext());
}
@NonNull
diff --git a/PermissionController/src/com/android/permissioncontroller/role/ui/handheld/HandheldRadioPreference.java b/PermissionController/src/com/android/permissioncontroller/role/ui/handheld/HandheldRadioPreference.java
new file mode 100644
index 000000000..d9ef047d6
--- /dev/null
+++ b/PermissionController/src/com/android/permissioncontroller/role/ui/handheld/HandheldRadioPreference.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2023 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.handheld;
+
+import android.content.Context;
+import android.util.AttributeSet;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.preference.PreferenceViewHolder;
+
+import com.android.permissioncontroller.role.ui.RoleApplicationPreference;
+import com.android.permissioncontroller.role.ui.UserRestrictionAwarePreferenceMixin;
+import com.android.settingslib.widget.SelectorWithWidgetPreference;
+
+/**
+ * Preference used to represent apps that can be picked as a default app.
+ */
+public class HandheldRadioPreference extends SelectorWithWidgetPreference implements
+ RoleApplicationPreference {
+
+ private final UserRestrictionAwarePreferenceMixin mUserRestrictionAwarePreferenceMixin =
+ new UserRestrictionAwarePreferenceMixin(this);
+
+ public HandheldRadioPreference(@NonNull Context context,
+ @Nullable AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ }
+
+ public HandheldRadioPreference(@NonNull Context context,
+ @Nullable AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public HandheldRadioPreference(@NonNull Context context, boolean isCheckbox) {
+ super(context, isCheckbox);
+ }
+
+ public HandheldRadioPreference(@NonNull Context context) {
+ super(context);
+ }
+
+ @Override
+ public void setUserRestriction(
+ @Nullable String userRestriction) {
+ mUserRestrictionAwarePreferenceMixin.setUserRestriction(userRestriction);
+ }
+
+ @Override
+ public void onBindViewHolder(PreferenceViewHolder holder) {
+ super.onBindViewHolder(holder);
+
+ mUserRestrictionAwarePreferenceMixin.onAfterBindViewHolder(holder);
+ }
+
+ @NonNull
+ @Override
+ public HandheldRadioPreference asTwoStatePreference() {
+ return this;
+ }
+}
diff --git a/PermissionController/src/com/android/permissioncontroller/role/ui/handheld/SettingsButtonPreference.java b/PermissionController/src/com/android/permissioncontroller/role/ui/handheld/HandheldRolePreference.java
index f54c9d95d..978fe7d5a 100644
--- a/PermissionController/src/com/android/permissioncontroller/role/ui/handheld/SettingsButtonPreference.java
+++ b/PermissionController/src/com/android/permissioncontroller/role/ui/handheld/HandheldRolePreference.java
@@ -28,7 +28,9 @@ import androidx.preference.Preference;
import androidx.preference.PreferenceViewHolder;
import com.android.permissioncontroller.R;
-import com.android.permissioncontroller.role.ui.TwoTargetPreference;
+import com.android.permissioncontroller.role.ui.RolePreference;
+import com.android.permissioncontroller.role.ui.UserRestrictionAwarePreferenceMixin;
+import com.android.settingslib.widget.TwoTargetPreference;
/**
* {@link Preference} with a settings button.
@@ -36,33 +38,35 @@ import com.android.permissioncontroller.role.ui.TwoTargetPreference;
* @see com.android.settings.widget.GearPreference
*/
// Made public for com.android.permissioncontroller.role.ui.specialappaccess.handheld
-public class SettingsButtonPreference extends com.android.settingslib.widget.TwoTargetPreference
- implements TwoTargetPreference {
+public class HandheldRolePreference extends TwoTargetPreference implements RolePreference {
+
+ private final UserRestrictionAwarePreferenceMixin mUserRestrictionAwarePreferenceMixin =
+ new UserRestrictionAwarePreferenceMixin(this);
@Nullable
private OnSecondTargetClickListener mOnSecondTargetClickListener;
- public SettingsButtonPreference(@NonNull Context context, @Nullable AttributeSet attrs,
+ public HandheldRolePreference(@NonNull Context context, @Nullable AttributeSet attrs,
@AttrRes int defStyleAttr, @StyleRes int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
init();
}
- public SettingsButtonPreference(@NonNull Context context, @Nullable AttributeSet attrs,
+ public HandheldRolePreference(@NonNull Context context, @Nullable AttributeSet attrs,
@AttrRes int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
- public SettingsButtonPreference(@NonNull Context context, @Nullable AttributeSet attrs) {
+ public HandheldRolePreference(@NonNull Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
init();
}
- public SettingsButtonPreference(@NonNull Context context) {
+ public HandheldRolePreference(@NonNull Context context) {
super(context);
init();
@@ -89,6 +93,11 @@ public class SettingsButtonPreference extends com.android.settingslib.widget.Two
}
@Override
+ public void setUserRestriction(@Nullable String userRestriction) {
+ mUserRestrictionAwarePreferenceMixin.setUserRestriction(userRestriction);
+ }
+
+ @Override
public void onBindViewHolder(@NonNull PreferenceViewHolder holder) {
super.onBindViewHolder(holder);
@@ -103,5 +112,12 @@ public class SettingsButtonPreference extends com.android.settingslib.widget.Two
}
// Make the settings button enabled even if the preference itself is disabled.
settingsButton.setEnabled(true);
+
+ mUserRestrictionAwarePreferenceMixin.onAfterBindViewHolder(holder);
+ }
+
+ @Override
+ public HandheldRolePreference asPreference() {
+ return this;
}
}
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 d75747b52..b95440bbd 100644
--- a/PermissionController/src/com/android/permissioncontroller/role/ui/specialappaccess/SpecialAppAccessChildFragment.java
+++ b/PermissionController/src/com/android/permissioncontroller/role/ui/specialappaccess/SpecialAppAccessChildFragment.java
@@ -37,6 +37,7 @@ import androidx.preference.TwoStatePreference;
import com.android.permissioncontroller.permission.utils.Utils;
import com.android.permissioncontroller.role.ui.ManageRoleHolderStateLiveData;
+import com.android.permissioncontroller.role.ui.RoleApplicationPreference;
import com.android.permissioncontroller.role.utils.RoleUiBehaviorUtils;
import com.android.role.controller.model.Role;
import com.android.role.controller.model.Roles;
@@ -143,9 +144,12 @@ public class SpecialAppAccessChildFragment<PF extends PreferenceFragmentCompat
String key = qualifyingApplicationInfo.packageName + '_'
+ qualifyingApplicationInfo.uid;
- TwoStatePreference preference = (TwoStatePreference) oldPreferences.get(key);
- if (preference == null) {
- preference = preferenceFragment.createApplicationPreference();
+ RoleApplicationPreference roleApplicationPreference =
+ (RoleApplicationPreference) oldPreferences.get(key);
+ TwoStatePreference preference;
+ if (roleApplicationPreference == null) {
+ roleApplicationPreference = preferenceFragment.createApplicationPreference();
+ preference = roleApplicationPreference.asTwoStatePreference();
preference.setKey(key);
preference.setIcon(Utils.getBadgedIcon(context, qualifyingApplicationInfo));
preference.setTitle(Utils.getFullAppLabel(qualifyingApplicationInfo, context));
@@ -154,11 +158,13 @@ public class SpecialAppAccessChildFragment<PF extends PreferenceFragmentCompat
preference.setOnPreferenceClickListener(this);
preference.getExtras().putParcelable(PREFERENCE_EXTRA_APPLICATION_INFO,
qualifyingApplicationInfo);
+ } else {
+ preference = roleApplicationPreference.asTwoStatePreference();
}
preference.setChecked(isHolderPackage);
UserHandle user = UserHandle.getUserHandleForUid(qualifyingApplicationInfo.uid);
- RoleUiBehaviorUtils.prepareApplicationPreferenceAsUser(mRole, preference,
+ RoleUiBehaviorUtils.prepareApplicationPreferenceAsUser(mRole, roleApplicationPreference,
qualifyingApplicationInfo, user, context);
preferenceScreen.addPreference(preference);
}
@@ -228,7 +234,7 @@ public class SpecialAppAccessChildFragment<PF extends PreferenceFragmentCompat
* @return a new preference for an application
*/
@NonNull
- TwoStatePreference createApplicationPreference();
+ RoleApplicationPreference createApplicationPreference();
/**
* Create a new preference for the footer.
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 ec4de84e1..4b256cef0 100644
--- a/PermissionController/src/com/android/permissioncontroller/role/ui/specialappaccess/SpecialAppAccessListChildFragment.java
+++ b/PermissionController/src/com/android/permissioncontroller/role/ui/specialappaccess/SpecialAppAccessListChildFragment.java
@@ -33,7 +33,7 @@ import androidx.preference.PreferenceManager;
import androidx.preference.PreferenceScreen;
import com.android.permissioncontroller.role.ui.RoleItem;
-import com.android.permissioncontroller.role.ui.TwoTargetPreference;
+import com.android.permissioncontroller.role.ui.RolePreference;
import com.android.permissioncontroller.role.utils.RoleUiBehaviorUtils;
import com.android.role.controller.model.Role;
import com.android.role.controller.model.Roles;
@@ -102,16 +102,20 @@ public class SpecialAppAccessListChildFragment<PF extends PreferenceFragmentComp
RoleItem roleItem = roleItems.get(i);
Role role = roleItem.getRole();
- Preference preference = oldPreferences.get(role.getName());
- if (preference == null) {
- preference = (Preference) preferenceFragment.createPreference(context);
+ RolePreference rolePreference = (RolePreference) oldPreferences.get(role.getName());
+ Preference preference;
+ if (rolePreference == null) {
+ rolePreference = preferenceFragment.createPreference(context);
+ preference = rolePreference.asPreference();
preference.setKey(role.getName());
preference.setIconSpaceReserved(true);
preference.setTitle(role.getShortLabelResource());
preference.setPersistent(false);
preference.setOnPreferenceClickListener(this);
+ } else {
+ preference = rolePreference.asPreference();
}
- RoleUiBehaviorUtils.preparePreferenceAsUser(role, (TwoTargetPreference) preference,
+ RoleUiBehaviorUtils.preparePreferenceAsUser(role, rolePreference,
Process.myUserHandle(),
context);
preferenceScreen.addPreference(preference);
@@ -153,7 +157,7 @@ public class SpecialAppAccessListChildFragment<PF extends PreferenceFragmentComp
* @return a new preference for a special app access
*/
@NonNull
- TwoTargetPreference createPreference(@NonNull Context context);
+ RolePreference createPreference(@NonNull Context context);
/**
* Callback when changes have been made to the {@link PreferenceScreen} of the parent
diff --git a/PermissionController/src/com/android/permissioncontroller/role/ui/specialappaccess/handheld/HandheldSpecialAppAccessListPreferenceFragment.java b/PermissionController/src/com/android/permissioncontroller/role/ui/specialappaccess/handheld/HandheldSpecialAppAccessListPreferenceFragment.java
index e0d7884a1..26d858d72 100644
--- a/PermissionController/src/com/android/permissioncontroller/role/ui/specialappaccess/handheld/HandheldSpecialAppAccessListPreferenceFragment.java
+++ b/PermissionController/src/com/android/permissioncontroller/role/ui/specialappaccess/handheld/HandheldSpecialAppAccessListPreferenceFragment.java
@@ -23,8 +23,8 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.preference.PreferenceFragmentCompat;
-import com.android.permissioncontroller.role.ui.TwoTargetPreference;
-import com.android.permissioncontroller.role.ui.handheld.SettingsButtonPreference;
+import com.android.permissioncontroller.role.ui.RolePreference;
+import com.android.permissioncontroller.role.ui.handheld.HandheldRolePreference;
import com.android.permissioncontroller.role.ui.specialappaccess.SpecialAppAccessListChildFragment;
/**
@@ -65,8 +65,8 @@ public class HandheldSpecialAppAccessListPreferenceFragment extends PreferenceFr
@NonNull
@Override
- public TwoTargetPreference createPreference(@NonNull Context context) {
- return new SettingsButtonPreference(context);
+ public RolePreference createPreference(@NonNull Context context) {
+ return new HandheldRolePreference(context);
}
@Override
diff --git a/PermissionController/src/com/android/permissioncontroller/role/ui/specialappaccess/handheld/HandheldSpecialAppAccessPreferenceFragment.java b/PermissionController/src/com/android/permissioncontroller/role/ui/specialappaccess/handheld/HandheldSpecialAppAccessPreferenceFragment.java
index c1bb0fb23..bfcbefdca 100644
--- a/PermissionController/src/com/android/permissioncontroller/role/ui/specialappaccess/handheld/HandheldSpecialAppAccessPreferenceFragment.java
+++ b/PermissionController/src/com/android/permissioncontroller/role/ui/specialappaccess/handheld/HandheldSpecialAppAccessPreferenceFragment.java
@@ -23,10 +23,9 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.preference.Preference;
import androidx.preference.PreferenceFragmentCompat;
-import androidx.preference.TwoStatePreference;
+import com.android.permissioncontroller.role.ui.RoleApplicationPreference;
import com.android.permissioncontroller.role.ui.specialappaccess.SpecialAppAccessChildFragment;
-import com.android.settingslib.widget.AppSwitchPreference;
import com.android.settingslib.widget.FooterPreference;
/**
@@ -90,8 +89,8 @@ public class HandheldSpecialAppAccessPreferenceFragment extends PreferenceFragme
@NonNull
@Override
- public TwoStatePreference createApplicationPreference() {
- return new AppSwitchPreference(requireContext());
+ public RoleApplicationPreference createApplicationPreference() {
+ return new HandheldSwitchPreference(requireContext());
}
@NonNull
diff --git a/PermissionController/src/com/android/permissioncontroller/role/ui/specialappaccess/handheld/HandheldSwitchPreference.java b/PermissionController/src/com/android/permissioncontroller/role/ui/specialappaccess/handheld/HandheldSwitchPreference.java
new file mode 100644
index 000000000..1b4dd78a4
--- /dev/null
+++ b/PermissionController/src/com/android/permissioncontroller/role/ui/specialappaccess/handheld/HandheldSwitchPreference.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2023 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.specialappaccess.handheld;
+
+import android.content.Context;
+import android.util.AttributeSet;
+
+import androidx.annotation.AttrRes;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.annotation.StyleRes;
+import androidx.preference.PreferenceViewHolder;
+
+import com.android.permissioncontroller.role.ui.RoleApplicationPreference;
+import com.android.permissioncontroller.role.ui.UserRestrictionAwarePreferenceMixin;
+import com.android.settingslib.widget.AppSwitchPreference;
+
+/** {@link AppSwitchPreference} that is a role application preference. */
+public class HandheldSwitchPreference extends AppSwitchPreference
+ implements RoleApplicationPreference {
+
+ private UserRestrictionAwarePreferenceMixin mUserRestrictionAwarePreferenceMixin =
+ new UserRestrictionAwarePreferenceMixin(this);
+
+ public HandheldSwitchPreference(@NonNull Context context, @Nullable AttributeSet attrs,
+ @AttrRes int defStyleAttr, @StyleRes int defStyleRes) {
+ super(context, attrs, defStyleAttr, defStyleRes);
+ }
+
+ public HandheldSwitchPreference(@NonNull Context context, @Nullable AttributeSet attrs,
+ @AttrRes int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ }
+
+ public HandheldSwitchPreference(@NonNull Context context, @Nullable AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public HandheldSwitchPreference(@NonNull Context context) {
+ super(context);
+ }
+
+ @Override
+ public void setUserRestriction(@Nullable String userRestriction) {
+ mUserRestrictionAwarePreferenceMixin.setUserRestriction(userRestriction);
+ }
+
+ @Override
+ public void onBindViewHolder(PreferenceViewHolder holder) {
+ super.onBindViewHolder(holder);
+
+ mUserRestrictionAwarePreferenceMixin.onAfterBindViewHolder(holder);
+ }
+
+ @NonNull
+ @Override
+ public HandheldSwitchPreference asTwoStatePreference() {
+ return this;
+ }
+}
diff --git a/PermissionController/src/com/android/permissioncontroller/role/utils/RoleUiBehaviorUtils.java b/PermissionController/src/com/android/permissioncontroller/role/utils/RoleUiBehaviorUtils.java
index 40088c7e0..6081695b5 100644
--- a/PermissionController/src/com/android/permissioncontroller/role/utils/RoleUiBehaviorUtils.java
+++ b/PermissionController/src/com/android/permissioncontroller/role/utils/RoleUiBehaviorUtils.java
@@ -26,10 +26,11 @@ import android.util.Log;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
-import androidx.preference.Preference;
import com.android.modules.utils.build.SdkLevel;
-import com.android.permissioncontroller.role.ui.TwoTargetPreference;
+import com.android.permissioncontroller.role.ui.RoleApplicationPreference;
+import com.android.permissioncontroller.role.ui.RolePreference;
+import com.android.permissioncontroller.role.ui.UserRestrictionAwarePreference;
import com.android.permissioncontroller.role.ui.behavior.RoleUiBehavior;
import com.android.role.controller.model.Role;
@@ -102,13 +103,9 @@ public final class RoleUiBehaviorUtils {
* @see RoleUiBehavior#preparePreferenceAsUser
*/
public static void preparePreferenceAsUser(@NonNull Role role,
- @NonNull TwoTargetPreference preference, @NonNull UserHandle user,
+ @NonNull RolePreference preference, @NonNull UserHandle user,
@NonNull Context context) {
- if (SdkLevel.isAtLeastU() && role.isExclusive()) {
- final UserManager userManager = context.getSystemService(UserManager.class);
- preference.setEnabled(!userManager.hasUserRestrictionForUser(
- UserManager.DISALLOW_CONFIG_DEFAULT_APPS, user));
- }
+ prepareUserRestrictionAwarePreferenceAsUser(role, preference, user, context);
RoleUiBehavior uiBehavior = getUiBehavior(role);
if (uiBehavior == null) {
@@ -134,22 +131,32 @@ public final class RoleUiBehaviorUtils {
* @see RoleUiBehavior#prepareApplicationPreferenceAsUser
*/
public static void prepareApplicationPreferenceAsUser(@NonNull Role role,
- @NonNull Preference preference, @NonNull ApplicationInfo applicationInfo,
- @NonNull UserHandle user, @NonNull Context context) {
- if (SdkLevel.isAtLeastU() && role.isExclusive()) {
- final UserManager userManager = context.getSystemService(UserManager.class);
- preference.setEnabled(!userManager.hasUserRestrictionForUser(
- UserManager.DISALLOW_CONFIG_DEFAULT_APPS, user));
- }
+ @NonNull RoleApplicationPreference preference,
+ @NonNull ApplicationInfo applicationInfo, @NonNull UserHandle user,
+ @NonNull Context context) {
+ prepareUserRestrictionAwarePreferenceAsUser(role, preference, user, context);
RoleUiBehavior uiBehavior = getUiBehavior(role);
if (uiBehavior == null) {
return;
}
- uiBehavior.prepareApplicationPreferenceAsUser(role, preference, applicationInfo, user,
+ uiBehavior.prepareApplicationPreferenceAsUser(
+ role, preference.asTwoStatePreference(), applicationInfo, user,
context);
}
+ private static void prepareUserRestrictionAwarePreferenceAsUser(@NonNull Role role,
+ @NonNull UserRestrictionAwarePreference preference, @NonNull UserHandle user,
+ @NonNull Context context) {
+ if (SdkLevel.isAtLeastU() && role.isExclusive()) {
+ UserManager userManager = context.getSystemService(UserManager.class);
+ boolean hasDisallowConfigDefaultApps = userManager.hasUserRestrictionForUser(
+ UserManager.DISALLOW_CONFIG_DEFAULT_APPS, user);
+ preference.setUserRestriction(hasDisallowConfigDefaultApps
+ ? UserManager.DISALLOW_CONFIG_DEFAULT_APPS : null);
+ }
+ }
+
/**
* @see RoleUiBehavior#getConfirmationMessage
*/
diff --git a/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/IssueCardAnimator.kt b/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/IssueCardAnimator.kt
index a0c7c01b9..2bc83eb10 100644
--- a/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/IssueCardAnimator.kt
+++ b/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/IssueCardAnimator.kt
@@ -55,35 +55,36 @@ class IssueCardAnimator(val callback: AnimationCallback) {
// Ensure AVD is reset before transition starts
(resolvedImageView.drawable as AnimatedVectorDrawable).reset()
- val defaultIssueContentGroup = holder.findViewById(R.id.default_issue_content)
- val resolvedIssueContentGroup = holder.findViewById(R.id.resolved_issue_content)
-
- val transitionSet = TransitionSet()
- .setOrdering(TransitionSet.ORDERING_SEQUENTIAL)
- .setInterpolator(linearInterpolator)
- .addTransition(hideIssueContentTransition)
- .addTransition(
- showResolvedImageTransition
- .clone()
- .addListener(
- object : TransitionListenerAdapter() {
- override fun onTransitionEnd(
- transition: Transition
- ) {
- super.onTransitionEnd(transition)
- startIssueResolvedAnimation(
- resolvedIssueContentGroup,
- resolvedImageView
- )
+ val defaultIssueContentGroup = holder.findViewById(R.id.default_issue_content)!!
+ val resolvedIssueContentGroup = holder.findViewById(R.id.resolved_issue_content)!!
+
+ val transitionSet =
+ TransitionSet()
+ .setOrdering(TransitionSet.ORDERING_SEQUENTIAL)
+ .setInterpolator(linearInterpolator)
+ .addTransition(hideIssueContentTransition)
+ .addTransition(
+ showResolvedImageTransition
+ .clone()
+ .addListener(
+ object : TransitionListenerAdapter() {
+ override fun onTransitionEnd(transition: Transition) {
+ super.onTransitionEnd(transition)
+ startIssueResolvedAnimation(
+ resolvedIssueContentGroup,
+ resolvedImageView
+ )
+ }
}
- })
- )
- .addTransition(showResolvedTextTransition)
+ )
+ )
+ .addTransition(showResolvedTextTransition)
// Defer transition so that it's called after the root ViewGroup has been laid out.
holder.itemView.post {
TransitionManager.beginDelayedTransition(
- defaultIssueContentGroup.parent as ViewGroup?, transitionSet
+ defaultIssueContentGroup.parent as ViewGroup?,
+ transitionSet
)
// Setting INVISIBLE rather than GONE to ensure consistent card height between
@@ -111,7 +112,8 @@ class IssueCardAnimator(val callback: AnimationCallback) {
resolvedImageView
)
}
- })
+ }
+ )
}
private fun makeInvisibleIfVisible(view: View?) {
@@ -133,23 +135,27 @@ class IssueCardAnimator(val callback: AnimationCallback) {
super.onAnimationEnd(drawable)
transitionResolvedIssueUiToHiddenAndMarkComplete(resolvedIssueContentGroup)
}
- })
+ }
+ )
animatedDrawable.start()
}
private fun transitionResolvedIssueUiToHiddenAndMarkComplete(resolvedIssueContentGroup: View) {
- val hideTransition = hideResolvedUiTransition
- .clone()
- .setInterpolator(linearInterpolator)
- .addListener(
- object : TransitionListenerAdapter() {
- override fun onTransitionEnd(transition: Transition) {
- super.onTransitionEnd(transition)
- callback.markIssueResolvedUiCompleted()
+ val hideTransition =
+ hideResolvedUiTransition
+ .clone()
+ .setInterpolator(linearInterpolator)
+ .addListener(
+ object : TransitionListenerAdapter() {
+ override fun onTransitionEnd(transition: Transition) {
+ super.onTransitionEnd(transition)
+ callback.markIssueResolvedUiCompleted()
+ }
}
- })
+ )
TransitionManager.beginDelayedTransition(
- resolvedIssueContentGroup.parent as ViewGroup, hideTransition
+ resolvedIssueContentGroup.parent as ViewGroup,
+ hideTransition
)
resolvedIssueContentGroup.visibility = View.GONE
}
@@ -191,10 +197,14 @@ class IssueCardAnimator(val callback: AnimationCallback) {
// Using getter due to reliance on DeviceConfig property modification in tests
private val hideResolvedUiTransitionDelay
- get() = Duration.ofMillis(
- DeviceConfig.getLong(DeviceConfig.NAMESPACE_PRIVACY,
- PROPERTY_HIDE_RESOLVED_UI_TRANSITION_DELAY_MILLIS,
- 400))
+ get() =
+ Duration.ofMillis(
+ DeviceConfig.getLong(
+ DeviceConfig.NAMESPACE_PRIVACY,
+ PROPERTY_HIDE_RESOLVED_UI_TRANSITION_DELAY_MILLIS,
+ 400
+ )
+ )
private val linearInterpolator = LinearInterpolator()
@@ -207,14 +217,16 @@ class IssueCardAnimator(val callback: AnimationCallback) {
.setDuration(0)
.addTarget(R.id.resolved_issue_image)
- private val showResolvedTextTransition = Fade(Fade.IN)
- .setStartDelay(SHOW_RESOLVED_TEXT_TRANSITION_DELAY.toMillis())
- .setDuration(SHOW_RESOLVED_TEXT_TRANSITION_DURATION.toMillis())
- .addTarget(R.id.resolved_issue_text)
+ private val showResolvedTextTransition =
+ Fade(Fade.IN)
+ .setStartDelay(SHOW_RESOLVED_TEXT_TRANSITION_DELAY.toMillis())
+ .setDuration(SHOW_RESOLVED_TEXT_TRANSITION_DURATION.toMillis())
+ .addTarget(R.id.resolved_issue_text)
private val hideResolvedUiTransition
- get() = Fade(Fade.OUT)
- .setStartDelay(hideResolvedUiTransitionDelay.toMillis())
- .setDuration(HIDE_RESOLVED_UI_TRANSITION_DURATION.toMillis())
+ get() =
+ Fade(Fade.OUT)
+ .setStartDelay(hideResolvedUiTransitionDelay.toMillis())
+ .setDuration(HIDE_RESOLVED_UI_TRANSITION_DURATION.toMillis())
}
-} \ No newline at end of file
+}
diff --git a/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/PreferenceHighlightManager.kt b/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/PreferenceHighlightManager.kt
index 2acd6b5a3..613493f82 100644
--- a/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/PreferenceHighlightManager.kt
+++ b/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/PreferenceHighlightManager.kt
@@ -59,7 +59,7 @@ internal class PreferenceHighlightManager(private val fragment: PreferenceFragme
/** Creates a new [HighlightablePreferenceGroupAdapter] instance */
fun createAdapter(
- preferenceScreen: PreferenceScreen?,
+ preferenceScreen: PreferenceScreen,
): RecyclerView.Adapter<RecyclerView.ViewHolder> {
val intent = fragment.getActivity()?.getIntent()
preferenceGroupAdapter =
diff --git a/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/SafetyBrandChipPreference.kt b/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/SafetyBrandChipPreference.kt
index bf2d0565c..57e4175ca 100644
--- a/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/SafetyBrandChipPreference.kt
+++ b/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/SafetyBrandChipPreference.kt
@@ -42,7 +42,7 @@ internal class SafetyBrandChipPreference(context: Context, attrs: AttributeSet)
override fun onBindViewHolder(holder: PreferenceViewHolder) {
super.onBindViewHolder(holder)
- val brandChipButton = holder.findViewById(R.id.brand_chip)
+ val brandChipButton = holder.findViewById(R.id.brand_chip)!!
brandChipButton.setOnClickListener(brandChipClickListener)
}
diff --git a/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/SafetyCenterFragment.kt b/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/SafetyCenterFragment.kt
index 365dc0efa..6f146e48c 100644
--- a/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/SafetyCenterFragment.kt
+++ b/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/SafetyCenterFragment.kt
@@ -50,7 +50,7 @@ abstract class SafetyCenterFragment : PreferenceFragmentCompat() {
}
override fun onCreateAdapter(
- preferenceScreen: PreferenceScreen?
+ preferenceScreen: PreferenceScreen
): RecyclerView.Adapter<RecyclerView.ViewHolder> {
/* The scroll-to-result functionality for settings search is currently implemented only for
* subpages i.e. non expand-and-collapse type entries. Hence, we check that the flag is
diff --git a/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/SafetyGroupPreference.kt b/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/SafetyGroupPreference.kt
index 2a9f6f780..46590448e 100644
--- a/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/SafetyGroupPreference.kt
+++ b/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/SafetyGroupPreference.kt
@@ -45,10 +45,10 @@ class SafetyGroupPreference(
layoutResource = R.layout.preference_group
}
- override fun onBindViewHolder(holder: PreferenceViewHolder?) {
+ override fun onBindViewHolder(holder: PreferenceViewHolder) {
super.onBindViewHolder(holder)
- (holder?.itemView as? SafetyEntryGroupView)?.showGroup(
+ (holder.itemView as? SafetyEntryGroupView)?.showGroup(
group,
isExpanded,
isFirstCard,
@@ -56,7 +56,8 @@ class SafetyGroupPreference(
getTaskIdForEntry,
viewModel,
onExpandedListener,
- onCollapsedListener)
+ onCollapsedListener
+ )
}
override fun isSameItem(preference: Preference): Boolean =
diff --git a/tests/functional/safetycenter/singleuser/src/android/safetycenter/functional/SafetyCenterNotificationTest.kt b/tests/functional/safetycenter/singleuser/src/android/safetycenter/functional/SafetyCenterNotificationTest.kt
index 353f99c04..86bc5f88e 100644
--- a/tests/functional/safetycenter/singleuser/src/android/safetycenter/functional/SafetyCenterNotificationTest.kt
+++ b/tests/functional/safetycenter/singleuser/src/android/safetycenter/functional/SafetyCenterNotificationTest.kt
@@ -31,7 +31,8 @@ import android.safetycenter.SafetySourceIssue
import androidx.test.core.app.ApplicationProvider.getApplicationContext
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SdkSuppress
-import com.android.compatibility.common.util.UiAutomatorUtils2.getUiDevice
+import com.android.compatibility.common.util.DisableAnimationRule
+import com.android.compatibility.common.util.FreezeRotationRule
import com.android.safetycenter.pendingintents.PendingIntentSender
import com.android.safetycenter.testing.Coroutines
import com.android.safetycenter.testing.Coroutines.TIMEOUT_SHORT
@@ -55,9 +56,9 @@ import com.android.safetycenter.testing.SafetySourceReceiver
import com.android.safetycenter.testing.SafetySourceTestData
import com.android.safetycenter.testing.SafetySourceTestData.Companion.ISSUE_TYPE_ID
import com.android.safetycenter.testing.ShellPermissions.callWithShellPermissionIdentity
+import com.android.safetycenter.testing.StatusBarNotificationWithChannel
import com.android.safetycenter.testing.SupportsSafetyCenterRule
import com.android.safetycenter.testing.TestNotificationListener
-import com.android.safetycenter.testing.UiTestHelper.clickNotificationElementWithText
import com.android.safetycenter.testing.UiTestHelper.waitSourceIssueDisplayed
import com.google.common.truth.Truth.assertThat
import java.time.Duration
@@ -77,13 +78,15 @@ class SafetyCenterNotificationTest {
private val safetyCenterTestConfigs = SafetyCenterTestConfigs(context)
private val safetyCenterManager =
requireNotNull(context.getSystemService(SafetyCenterManager::class.java)) {
- "Could not get system service"
+ "Could not get SafetyCenterManager"
}
@get:Rule(order = 1) val supportsSafetyCenterRule = SupportsSafetyCenterRule(context)
@get:Rule(order = 2)
val safetyCenterTestRule =
SafetyCenterTestRule(safetyCenterTestHelper, withNotifications = true)
+ @get:Rule(order = 3) val disableAnimationRule = DisableAnimationRule()
+ @get:Rule(order = 4) val freezeRotationRule = FreezeRotationRule()
@Before
fun enableNotificationsForTestSourceBeforeTest() {
@@ -907,7 +910,7 @@ class SafetyCenterNotificationTest {
}
@Test
- fun successNotificationClicked_successNotificationCancelled() {
+ fun successNotification_notificationHasAutoCancel() {
safetyCenterTestHelper.setData(
SINGLE_SOURCE_ID,
safetySourceTestData.criticalWithResolvingIssueWithSuccessMessage
@@ -921,18 +924,16 @@ class SafetyCenterNotificationTest {
Response.SetData(safetySourceTestData.information)
)
sendActionPendingIntentAndWaitWithPermission(action)
- TestNotificationListener.waitForSingleNotificationMatching(
- NotificationCharacteristics(
- "Issue solved",
- "",
- actions = emptyList(),
+ val issueSolvedNotificationWithChannel =
+ TestNotificationListener.waitForSingleNotificationMatching(
+ NotificationCharacteristics(
+ "Issue solved",
+ "",
+ actions = emptyList(),
+ )
)
- )
-
- clickNotificationElementWithText("Issue solved")
- TestNotificationListener.waitForZeroNotifications()
- getUiDevice().pressBack()
+ assertThat(issueSolvedNotificationWithChannel.hasAutoCancel()).isTrue()
}
// TODO(b/284271124): Decide what to do with existing notifications when flag flipped off
@@ -1021,12 +1022,10 @@ class SafetyCenterNotificationTest {
safetySourceTestData.recommendationWithDeviceIssue
)
val notificationWithChannel = TestNotificationListener.waitForSingleNotification()
- val contentIntent = notificationWithChannel.statusBarNotification.notification.contentIntent
- executeBlockAndExit(
- launchActivity = { PendingIntentSender.send(contentIntent) },
- block = { waitSourceIssueDisplayed(safetySourceTestData.recommendationDeviceIssue) }
- )
+ sendContentPendingIntent(notificationWithChannel) {
+ waitSourceIssueDisplayed(safetySourceTestData.recommendationDeviceIssue)
+ }
}
@Test
@@ -1042,50 +1041,37 @@ class SafetyCenterNotificationTest {
safetySourceTestData.criticalWithResolvingGeneralIssue
)
val notificationWithChannel = TestNotificationListener.waitForSingleNotification()
- val contentIntent = notificationWithChannel.statusBarNotification.notification.contentIntent
- executeBlockAndExit(
- launchActivity = { PendingIntentSender.send(contentIntent) },
- block = {
- waitSourceIssueDisplayed(safetySourceTestData.criticalResolvingGeneralIssue)
- waitSourceIssueDisplayed(safetySourceTestData.recommendationGeneralIssue)
- }
- )
+ sendContentPendingIntent(notificationWithChannel) {
+ waitSourceIssueDisplayed(safetySourceTestData.criticalResolvingGeneralIssue)
+ waitSourceIssueDisplayed(safetySourceTestData.recommendationDeviceIssue)
+ }
}
@Test
- fun sendContentPendingIntent_whenGreenIssue_notificationCancelled() {
+ fun whenGreenIssue_notificationHasAutoCancel() {
safetyCenterTestHelper.setData(SINGLE_SOURCE_ID, safetySourceTestData.informationWithIssue)
- TestNotificationListener.waitForSingleNotification()
-
- clickNotificationElementWithText(safetySourceTestData.informationIssue.summary.toString())
+ val notificationWithChannel = TestNotificationListener.waitForSingleNotification()
- TestNotificationListener.waitForZeroNotifications()
- getUiDevice().pressBack()
+ assertThat(notificationWithChannel.hasAutoCancel()).isTrue()
}
@Test
- fun sendContentPendingIntent_whenNotGreenIssue_notificationNotCancelled() {
+ fun whenNotGreenIssue_notificationDoesntHaveAutoCancel() {
safetyCenterTestHelper.setData(
SINGLE_SOURCE_ID,
safetySourceTestData.recommendationWithDeviceIssue
)
- TestNotificationListener.waitForSingleNotification()
-
- clickNotificationElementWithText(
- safetySourceTestData.recommendationDeviceIssue.summary.toString()
- )
+ val notificationWithChannel = TestNotificationListener.waitForSingleNotification()
- waitSourceIssueDisplayed(safetySourceTestData.recommendationDeviceIssue)
- TestNotificationListener.waitForSingleNotification()
- getUiDevice().pressBack()
+ assertThat(notificationWithChannel.hasAutoCancel()).isFalse()
}
- companion object {
- private val SafetyCenterData.inFlightActions: List<SafetyCenterIssue.Action>
+ private companion object {
+ val SafetyCenterData.inFlightActions: List<SafetyCenterIssue.Action>
get() = issues.flatMap { it.actions }.filter { it.isInFlight }
- private fun sendActionPendingIntentAndWaitWithPermission(
+ fun sendActionPendingIntentAndWaitWithPermission(
action: Notification.Action,
timeout: Duration = Coroutines.TIMEOUT_LONG
) {
@@ -1097,10 +1083,28 @@ class SafetyCenterNotificationTest {
}
}
- private fun setFlagsForImmediateNotifications(vararg sourceIds: String) {
+ fun setFlagsForImmediateNotifications(vararg sourceIds: String) {
SafetyCenterFlags.notificationsAllowedSources = sourceIds.toSet()
SafetyCenterFlags.immediateNotificationBehaviorIssues =
sourceIds.map { "$it/$ISSUE_TYPE_ID" }.toSet()
}
+
+ fun StatusBarNotificationWithChannel.hasAutoCancel(): Boolean {
+ val autoCancelMask =
+ statusBarNotification.notification.flags and Notification.FLAG_AUTO_CANCEL
+ return autoCancelMask != 0
+ }
+
+ fun sendContentPendingIntent(
+ statusBarNotificationWithChannel: StatusBarNotificationWithChannel,
+ andExecuteBlock: () -> Unit = {}
+ ) {
+ val contentIntent =
+ statusBarNotificationWithChannel.statusBarNotification.notification.contentIntent
+ executeBlockAndExit(
+ launchActivity = { PendingIntentSender.send(contentIntent) },
+ block = andExecuteBlock
+ )
+ }
}
}
diff --git a/tests/cts/safetycenter/src/android/safetycenter/cts/SafetyCenterShellCommandsTest.kt b/tests/functional/safetycenter/singleuser/src/android/safetycenter/functional/SafetyCenterShellCommandsTest.kt
index 4057410fa..7c5b41944 100644
--- a/tests/cts/safetycenter/src/android/safetycenter/cts/SafetyCenterShellCommandsTest.kt
+++ b/tests/functional/safetycenter/singleuser/src/android/safetycenter/functional/SafetyCenterShellCommandsTest.kt
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2022 The Android Open Source Project
+ * Copyright (C) 2023 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.
@@ -14,20 +14,23 @@
* limitations under the License.
*/
-package android.safetycenter.cts
+package android.safetycenter.functional
+import android.Manifest.permission.INTERACT_ACROSS_USERS
+import android.app.ActivityManager
import android.content.Context
import android.safetycenter.SafetyCenterManager
import androidx.test.core.app.ApplicationProvider.getApplicationContext
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.android.compatibility.common.util.SystemUtil
import com.android.safetycenter.testing.SafetyCenterApisWithShellPermissions.isSafetyCenterEnabledWithPermission
+import com.android.safetycenter.testing.ShellPermissions.callWithShellPermissionIdentity
import com.android.safetycenter.testing.deviceSupportsSafetyCenter
import com.google.common.truth.Truth.assertThat
import org.junit.Test
import org.junit.runner.RunWith
-/** CTS tests for Safety Center's shell commands. */
+/** Tests for Safety Center's shell commands. */
@RunWith(AndroidJUnit4::class)
class SafetyCenterShellCommandsTest {
private val context: Context = getApplicationContext()
@@ -54,6 +57,39 @@ class SafetyCenterShellCommandsTest {
assertThat(packageName).isEqualTo(context.packageManager.permissionControllerPackageName)
}
+ @Test
+ fun clearData_executesSuccessfully() {
+ executeShellCommand("cmd safety_center clear-data")
+ }
+
+ @Test
+ fun refresh_executesSuccessfully() {
+ val currentUser =
+ callWithShellPermissionIdentity(INTERACT_ACROSS_USERS) {
+ ActivityManager.getCurrentUser()
+ }
+ executeShellCommand("cmd safety_center refresh --reason OTHER --user $currentUser")
+ }
+
+ @Test
+ fun help_containsAllCommands() {
+ val help = executeShellCommand("cmd safety_center help")
+
+ assertThat(help).contains("help")
+ assertThat(help).contains("enabled")
+ assertThat(help).contains("supported")
+ assertThat(help).contains("package-name")
+ assertThat(help).contains("clear-data")
+ assertThat(help).contains("refresh")
+ }
+
+ @Test
+ fun dump_containsSafetyCenterService() {
+ val dump = executeShellCommand("dumpsys safety_center")
+
+ assertThat(dump).contains("SafetyCenterService")
+ }
+
private fun executeShellCommand(command: String): String =
- SystemUtil.runShellCommand(command).trim()
+ SystemUtil.runShellCommandOrThrow(command).trim()
}
diff --git a/tests/hostside/safetycenter/src/android/safetycenter/hostside/SafetyCenterInteractionLoggingHostTest.kt b/tests/hostside/safetycenter/src/android/safetycenter/hostside/SafetyCenterInteractionLoggingHostTest.kt
index 43884d76d..5fe9e0a2a 100644
--- a/tests/hostside/safetycenter/src/android/safetycenter/hostside/SafetyCenterInteractionLoggingHostTest.kt
+++ b/tests/hostside/safetycenter/src/android/safetycenter/hostside/SafetyCenterInteractionLoggingHostTest.kt
@@ -20,6 +20,7 @@ import android.cts.statsdatom.lib.ConfigUtils
import android.cts.statsdatom.lib.ReportUtils
import android.safetycenter.hostside.rules.HelperAppRule
import android.safetycenter.hostside.rules.RequireSafetyCenterRule
+import com.android.compatibility.common.util.ApiLevelUtil
import com.android.os.AtomsProto.Atom
import com.android.os.AtomsProto.SafetyCenterInteractionReported
import com.android.os.AtomsProto.SafetyCenterInteractionReported.Action
@@ -27,12 +28,9 @@ import com.android.os.AtomsProto.SafetyCenterInteractionReported.ViewType
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner
import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test
import com.google.common.truth.Truth.assertThat
-import com.android.compatibility.common.util.ApiLevelUtil
-import org.junit.Assume.assumeTrue
-
import org.junit.After
+import org.junit.Assume.assumeTrue
import org.junit.Before
-import org.junit.Ignore
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
@@ -106,26 +104,21 @@ class SafetyCenterInteractionLoggingHostTest : BaseHostJUnit4Test() {
}
@Test
- @Ignore
- // TODO(b/278202773): Fix/de-flake this test
fun openSubpageFromHomepage_recordsEventWithSafetyCenterNavigationSource() {
assumeAtLeastUpsideDownCake("Safety Center subpages require Android U+")
helperAppRule.runTest(TEST_CLASS_NAME, testMethodName = "openSubpageFromHomepage")
val safetyCenterViewedAtoms = getInteractionReportedAtoms(Action.SAFETY_CENTER_VIEWED)
+ val subpageViewedEvent = safetyCenterViewedAtoms.find { it.viewType == ViewType.SUBPAGE }
- assertThat(safetyCenterViewedAtoms.map { it.viewType })
- .containsExactly(ViewType.FULL, ViewType.SUBPAGE, ViewType.FULL)
- .inOrder()
- assertThat(safetyCenterViewedAtoms[1].navigationSource)
+ assertThat(subpageViewedEvent).isNotNull()
+ assertThat(subpageViewedEvent!!.navigationSource)
.isEqualTo(SafetyCenterInteractionReported.NavigationSource.SAFETY_CENTER)
assertThat(safetyCenterViewedAtoms.map { it.sessionId }.distinct()).hasSize(1)
}
@Test
- @Ignore
- // TODO(b/278202773): Fix/de-flake this test
fun openSubpageFromSettingsSearch_recordsEventWithSettingsNavigationSource() {
assumeAtLeastUpsideDownCake("Safety Center subpages require Android U+")
diff --git a/tests/utils/safetycenter/java/com/android/safetycenter/testing/Coroutines.kt b/tests/utils/safetycenter/java/com/android/safetycenter/testing/Coroutines.kt
index 18402e286..6c6336da3 100644
--- a/tests/utils/safetycenter/java/com/android/safetycenter/testing/Coroutines.kt
+++ b/tests/utils/safetycenter/java/com/android/safetycenter/testing/Coroutines.kt
@@ -19,7 +19,6 @@ package com.android.safetycenter.testing
import android.util.Log
import androidx.test.platform.app.InstrumentationRegistry
import java.time.Duration
-import kotlin.comparisons.minOf
import kotlinx.coroutines.DEBUG_PROPERTY_NAME
import kotlinx.coroutines.DEBUG_PROPERTY_VALUE_AUTO
import kotlinx.coroutines.DEBUG_PROPERTY_VALUE_ON
@@ -39,7 +38,7 @@ object Coroutines {
/** A long timeout, to be used for actions that are expected to complete. */
val TIMEOUT_LONG: Duration
- get() = minOf(TEST_TIMEOUT.dividedBy(2), Duration.ofMinutes(1))
+ get() = TEST_TIMEOUT.dividedBy(2)
/** A short timeout, to be used for actions that are expected not to complete. */
val TIMEOUT_SHORT: Duration = Duration.ofSeconds(1)
diff --git a/tests/utils/safetycenter/java/com/android/safetycenter/testing/UiTestHelper.kt b/tests/utils/safetycenter/java/com/android/safetycenter/testing/UiTestHelper.kt
index 24a2d2ea2..915780d4e 100644
--- a/tests/utils/safetycenter/java/com/android/safetycenter/testing/UiTestHelper.kt
+++ b/tests/utils/safetycenter/java/com/android/safetycenter/testing/UiTestHelper.kt
@@ -187,12 +187,6 @@ object UiTestHelper {
waitDisplayed(By.text(MORE_ISSUES_LABEL)) { it.click() }
}
- /** Clicks on a notification element that contains the given text. */
- fun clickNotificationElementWithText(text: String) {
- getUiDevice().openNotification()
- waitDisplayed(By.text(text)) { it.click() }
- }
-
/** Enables or disables animations based on [enabled]. */
fun setAnimationsEnabled(enabled: Boolean) {
val scale =