From 8e58e2c7a504a3b2402bf1efaae9c577241c395d Mon Sep 17 00:00:00 2001 From: Tsung-Mao Fang Date: Mon, 28 Oct 2019 18:57:00 +0800 Subject: [PATCH] Remove permission bar chart in Privacy setting - Because permission hub is already postponed, we don't need to show this UI in privacy settings. Test: Rebuild, visual, robotest Change-Id: I51aca52bc605a3c6b0cafc084e8e491c280d770f Fix: 143447873 Merged-In: I51aca52bc605a3c6b0cafc084e8e491c280d770f (cherry picked from commit ab914adc003f5c3e745ba9c3fa8d76043c5b2f17) --- res/xml/privacy_dashboard_settings.xml | 7 - ...ermissionBarChartPreferenceController.java | 243 ------------------ .../privacy/PrivacyDashboardFragment.java | 30 --- ...ssionBarChartPreferenceControllerTest.java | 120 --------- .../privacy/PrivacyDashboardFragmentTest.java | 111 -------- 5 files changed, 511 deletions(-) delete mode 100644 src/com/android/settings/privacy/PermissionBarChartPreferenceController.java delete mode 100644 tests/robotests/src/com/android/settings/privacy/PermissionBarChartPreferenceControllerTest.java delete mode 100644 tests/robotests/src/com/android/settings/privacy/PrivacyDashboardFragmentTest.java diff --git a/res/xml/privacy_dashboard_settings.xml b/res/xml/privacy_dashboard_settings.xml index 3ac6f4233b4..1dd609e4c22 100644 --- a/res/xml/privacy_dashboard_settings.xml +++ b/res/xml/privacy_dashboard_settings.xml @@ -22,13 +22,6 @@ android:title="@string/privacy_dashboard_title" settings:initialExpandedChildrenCount="4"> - - - mOldUsageInfos; - private PackageManager mPackageManager; - private PrivacyDashboardFragment mParent; - private BarChartPreference mBarChartPreference; - - public PermissionBarChartPreferenceController(Context context, String preferenceKey) { - super(context, preferenceKey); - mOldUsageInfos = new ArrayList<>(); - mPackageManager = context.getPackageManager(); - } - - public void setFragment(PrivacyDashboardFragment fragment) { - mParent = fragment; - } - - @Override - public void onCreate(Bundle savedInstanceState) { - if (savedInstanceState != null) { - mOldUsageInfos = savedInstanceState.getParcelableArrayList(KEY_PERMISSION_USAGE); - } - } - - @Override - public void onSaveInstanceState(Bundle outState) { - outState.putParcelableList(KEY_PERMISSION_USAGE, mOldUsageInfos); - } - - @Override - public int getAvailabilityStatus() { - return UNSUPPORTED_ON_DEVICE; - } - - @Override - public void displayPreference(PreferenceScreen screen) { - super.displayPreference(screen); - mBarChartPreference = screen.findPreference(getPreferenceKey()); - - final BarChartInfo info = new BarChartInfo.Builder() - .setTitle(R.string.permission_bar_chart_title) - .setDetails(R.string.permission_bar_chart_details) - .setEmptyText(R.string.permission_bar_chart_empty_text) - .setDetailsOnClickListener((View v) -> { - final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSION_USAGE); - intent.putExtra(Intent.EXTRA_DURATION_MILLIS, DAYS.toMillis(1)); - mContext.startActivity(intent); - }) - .build(); - - mBarChartPreference.initializeBarChart(info); - if (!mOldUsageInfos.isEmpty()) { - mBarChartPreference.setBarViewInfos(createBarViews(mOldUsageInfos)); - } - } - - @Override - public void onStart() { - if (!isAvailable()) { - return; - } - - // We don't hide chart when we have existing data. - mBarChartPreference.updateLoadingState(mOldUsageInfos.isEmpty() /* isLoading */); - // But we still need to hint user with progress bar that we are updating new usage data. - mParent.setLoadingEnabled(true /* enabled */); - retrievePermissionUsageData(); - } - - @Override - public void onPermissionUsageResult(@NonNull List usageInfos) { - usageInfos.sort((x, y) -> { - int usageDiff = y.getAppAccessCount() - x.getAppAccessCount(); - if (usageDiff != 0) { - return usageDiff; - } - String xName = x.getName(); - String yName = y.getName(); - if (xName.equals(LOCATION)) { - return -1; - } else if (yName.equals(LOCATION)) { - return 1; - } else if (xName.equals(MICROPHONE)) { - return -1; - } else if (yName.equals(MICROPHONE)) { - return 1; - } else if (xName.equals(CAMERA)) { - return -1; - } else if (yName.equals(CAMERA)) { - return 1; - } - return x.getName().compareTo(y.getName()); - }); - - // If the result is different, we need to update bar views. - if (!areSamePermissionGroups(usageInfos)) { - mBarChartPreference.setBarViewInfos(createBarViews(usageInfos)); - mOldUsageInfos = usageInfos; - } - - mBarChartPreference.updateLoadingState(false /* isLoading */); - mParent.setLoadingEnabled(false /* enabled */); - } - - private void retrievePermissionUsageData() { - mContext.getSystemService(PermissionControllerManager.class).getPermissionUsages( - false /* countSystem */, (int) DAYS.toMillis(1), - mContext.getMainExecutor() /* executor */, this /* callback */); - } - - private BarViewInfo[] createBarViews(List usageInfos) { - if (usageInfos.isEmpty()) { - return null; - } - - final BarViewInfo[] barViewInfos = new BarViewInfo[ - Math.min(BarChartPreference.MAXIMUM_BAR_VIEWS, usageInfos.size())]; - - for (int index = 0; index < barViewInfos.length; index++) { - final RuntimePermissionUsageInfo permissionGroupInfo = usageInfos.get(index); - final int count = permissionGroupInfo.getAppAccessCount(); - final CharSequence permLabel = getPermissionGroupLabel(permissionGroupInfo.getName()); - - barViewInfos[index] = new BarViewInfo( - getPermissionGroupIcon(permissionGroupInfo.getName()), count, permLabel, - mContext.getResources().getQuantityString(R.plurals.permission_bar_chart_label, - count, count), permLabel); - - // Set the click listener for each bar view. - // The listener will navigate user to permission usage app. - barViewInfos[index].setClickListener((View v) -> { - final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSION_USAGE); - intent.putExtra(Intent.EXTRA_PERMISSION_GROUP_NAME, permissionGroupInfo.getName()); - intent.putExtra(Intent.EXTRA_DURATION_MILLIS, DAYS.toMillis(1)); - mContext.startActivity(intent); - }); - } - - return barViewInfos; - } - - private Drawable getPermissionGroupIcon(String permissionGroup) { - Drawable icon = null; - try { - icon = mPackageManager.getPermissionGroupInfo(permissionGroup, 0) - .loadIcon(mPackageManager); - icon.setTintList(Utils.getColorAttr(mContext, android.R.attr.textColorSecondary)); - } catch (PackageManager.NameNotFoundException e) { - Log.w(TAG, "Cannot find group icon for " + permissionGroup, e); - } - - return icon; - } - - private CharSequence getPermissionGroupLabel(String permissionGroup) { - CharSequence label = null; - try { - label = mPackageManager.getPermissionGroupInfo(permissionGroup, 0) - .loadLabel(mPackageManager); - } catch (PackageManager.NameNotFoundException e) { - Log.w(TAG, "Cannot find group label for " + permissionGroup, e); - } - - return label; - } - - private boolean areSamePermissionGroups(List newUsageInfos) { - if (newUsageInfos.size() != mOldUsageInfos.size()) { - return false; - } - - for (int index = 0; index < newUsageInfos.size(); index++) { - final RuntimePermissionUsageInfo newInfo = newUsageInfos.get(index); - final RuntimePermissionUsageInfo oldInfo = mOldUsageInfos.get(index); - - if (!newInfo.getName().equals(oldInfo.getName()) || - newInfo.getAppAccessCount() != oldInfo.getAppAccessCount()) { - return false; - } - } - return true; - } -} diff --git a/src/com/android/settings/privacy/PrivacyDashboardFragment.java b/src/com/android/settings/privacy/PrivacyDashboardFragment.java index fa21f9dd444..1869cffa5df 100644 --- a/src/com/android/settings/privacy/PrivacyDashboardFragment.java +++ b/src/com/android/settings/privacy/PrivacyDashboardFragment.java @@ -18,14 +18,12 @@ package com.android.settings.privacy; import android.app.settings.SettingsEnums; import android.content.Context; -import android.os.Bundle; import android.provider.SearchIndexableResource; import android.view.View; import androidx.annotation.VisibleForTesting; import com.android.settings.R; -import com.android.settings.Utils; import com.android.settings.dashboard.DashboardFragment; import com.android.settings.notification.LockScreenNotificationPreferenceController; import com.android.settings.search.BaseSearchIndexProvider; @@ -75,34 +73,6 @@ public class PrivacyDashboardFragment extends DashboardFragment { return buildPreferenceControllers(context, getSettingsLifecycle()); } - @Override - public void onAttach(Context context) { - super.onAttach(context); - use(PermissionBarChartPreferenceController.class).setFragment(this /* fragment */); - } - - @Override - public void onViewCreated(View view, Bundle savedInstanceState) { - super.onViewCreated(view, savedInstanceState); - Utils.setActionBarShadowAnimation(getActivity(), getSettingsLifecycle(), getListView()); - initLoadingBar(); - } - - @VisibleForTesting - void initLoadingBar() { - mProgressHeader = setPinnedHeaderView(R.layout.progress_header); - mProgressAnimation = mProgressHeader.findViewById(R.id.progress_bar_animation); - setLoadingEnabled(false); - } - - @VisibleForTesting - void setLoadingEnabled(boolean enabled) { - if (mProgressHeader != null && mProgressAnimation != null) { - mProgressHeader.setVisibility(enabled ? View.VISIBLE : View.INVISIBLE); - mProgressAnimation.setVisibility(enabled ? View.VISIBLE : View.INVISIBLE); - } - } - private static List buildPreferenceControllers( Context context, Lifecycle lifecycle) { final List controllers = new ArrayList<>(); diff --git a/tests/robotests/src/com/android/settings/privacy/PermissionBarChartPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/privacy/PermissionBarChartPreferenceControllerTest.java deleted file mode 100644 index 1335db5c5ed..00000000000 --- a/tests/robotests/src/com/android/settings/privacy/PermissionBarChartPreferenceControllerTest.java +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Copyright (C) 2019 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.settings.privacy; - -import static android.Manifest.permission_group.CALENDAR; -import static android.Manifest.permission_group.CAMERA; -import static android.Manifest.permission_group.CONTACTS; -import static android.Manifest.permission_group.LOCATION; -import static android.Manifest.permission_group.MICROPHONE; -import static android.Manifest.permission_group.PHONE; -import static android.Manifest.permission_group.SMS; - -import static com.android.settings.core.BasePreferenceController.AVAILABLE_UNSEARCHABLE; -import static com.android.settings.core.BasePreferenceController.UNSUPPORTED_ON_DEVICE; - -import static com.google.common.truth.Truth.assertThat; - -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import android.content.Context; -import android.content.pm.UserInfo; -import android.os.UserManager; -import android.permission.RuntimePermissionUsageInfo; -import android.provider.DeviceConfig; -import android.view.accessibility.AccessibilityManager; - -import androidx.preference.PreferenceScreen; - -import com.android.internal.widget.LockPatternUtils; -import com.android.settings.Utils; -import com.android.settings.testutils.FakeFeatureFactory; -import com.android.settings.testutils.shadow.ShadowDeviceConfig; -import com.android.settings.testutils.shadow.ShadowPermissionControllerManager; -import com.android.settings.testutils.shadow.ShadowUserManager; -import com.android.settingslib.widget.BarChartInfo; -import com.android.settingslib.widget.BarChartPreference; -import com.android.settingslib.widget.BarViewInfo; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.RuntimeEnvironment; -import org.robolectric.annotation.Config; -import org.robolectric.shadow.api.Shadow; -import org.robolectric.shadows.ShadowAccessibilityManager; -import org.robolectric.shadows.androidx.fragment.FragmentController; - -import java.util.ArrayList; -import java.util.List; - -@RunWith(RobolectricTestRunner.class) -@Config(shadows = {ShadowDeviceConfig.class, ShadowUserManager.class, - ShadowPermissionControllerManager.class}) -public class PermissionBarChartPreferenceControllerTest { - - @Mock - private PreferenceScreen mScreen; - @Mock - private LockPatternUtils mLockPatternUtils; - - private PermissionBarChartPreferenceController mController; - private BarChartPreference mPreference; - private PrivacyDashboardFragment mFragment; - - @Before - public void setUp() { - MockitoAnnotations.initMocks(this); - final Context context = RuntimeEnvironment.application; - final UserManager userManager = context.getSystemService(UserManager.class); - final ShadowUserManager shadowUserManager = Shadow.extract(userManager); - final ShadowAccessibilityManager accessibilityManager = Shadow.extract( - AccessibilityManager.getInstance(context)); - accessibilityManager.setEnabledAccessibilityServiceList(new ArrayList<>()); - shadowUserManager.addProfile(new UserInfo(123, null, 0)); - when(FakeFeatureFactory.setupForTest().securityFeatureProvider.getLockPatternUtils( - any(Context.class))).thenReturn(mLockPatternUtils); - - mController = spy(new PermissionBarChartPreferenceController(context, "test_key")); - mFragment = spy(FragmentController.of(new PrivacyDashboardFragment()) - .create().start().get()); - mController.setFragment(mFragment); - mPreference = spy(new BarChartPreference(context)); - when(mScreen.findPreference(mController.getPreferenceKey())) - .thenReturn((BarChartPreference) mPreference); - } - - @After - public void tearDown() { - ShadowDeviceConfig.reset(); - } - - @Test - public void getAvailabilityStatus_permissionHubNotSet_shouldReturnUnsupported() { - // We have not yet set the property to show the Permissions Hub. - assertThat(mController.getAvailabilityStatus()).isEqualTo(UNSUPPORTED_ON_DEVICE); - } -} diff --git a/tests/robotests/src/com/android/settings/privacy/PrivacyDashboardFragmentTest.java b/tests/robotests/src/com/android/settings/privacy/PrivacyDashboardFragmentTest.java deleted file mode 100644 index 80f3900e00d..00000000000 --- a/tests/robotests/src/com/android/settings/privacy/PrivacyDashboardFragmentTest.java +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright (C) 2019 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.settings.privacy; - -import static com.google.common.truth.Truth.assertThat; - -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import android.content.Context; -import android.content.pm.UserInfo; -import android.os.Bundle; -import android.os.UserManager; -import android.permission.PermissionControllerManager; -import android.view.View; -import android.view.accessibility.AccessibilityManager; - -import com.android.internal.widget.LockPatternUtils; -import com.android.settings.testutils.FakeFeatureFactory; -import com.android.settings.testutils.shadow.ShadowPermissionControllerManager; -import com.android.settings.testutils.shadow.ShadowUserManager; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.RuntimeEnvironment; -import org.robolectric.annotation.Config; -import org.robolectric.shadow.api.Shadow; -import org.robolectric.shadows.ShadowAccessibilityManager; -import org.robolectric.shadows.androidx.fragment.FragmentController; - -import java.util.ArrayList; - - -@RunWith(RobolectricTestRunner.class) -@Config(shadows = {ShadowUserManager.class, ShadowPermissionControllerManager.class}) -public class PrivacyDashboardFragmentTest { - - @Mock - private LockPatternUtils mLockPatternUtils; - @Mock - private PermissionControllerManager mPCM; - - private Context mContext; - private PrivacyDashboardFragment mFragment; - - @Before - public void setUp() { - MockitoAnnotations.initMocks(this); - mContext = RuntimeEnvironment.application; - final UserManager userManager = mContext.getSystemService(UserManager.class); - final ShadowUserManager shadowUserManager = Shadow.extract(userManager); - final ShadowAccessibilityManager accessibilityManager = Shadow.extract( - AccessibilityManager.getInstance(mContext)); - accessibilityManager.setEnabledAccessibilityServiceList(new ArrayList<>()); - shadowUserManager.addProfile(new UserInfo(123, null, 0)); - when(FakeFeatureFactory.setupForTest().securityFeatureProvider.getLockPatternUtils( - any(Context.class))).thenReturn(mLockPatternUtils); - mFragment = spy(FragmentController.of(new PrivacyDashboardFragment()) - .create().start().get()); - } - - @Test - public void onViewCreated_shouldSetActionBarShadowAnimation() { - mFragment.onViewCreated(new View(mContext), new Bundle()); - - assertThat(mFragment.getActivity().getActionBar().getElevation()).isEqualTo(0.f); - } - - @Test - public void onViewCreated_shouldInitLinearProgressBar() { - mFragment.onViewCreated(new View(mContext), new Bundle()); - - verify(mFragment).initLoadingBar(); - } - - @Test - public void updateLinearProgressbar_isVisible_shouldShowProgressBar() { - mFragment.setLoadingEnabled(true /* enabled */); - - assertThat(mFragment.mProgressHeader.getVisibility()).isEqualTo(View.VISIBLE); - assertThat(mFragment.mProgressAnimation.getVisibility()).isEqualTo(View.VISIBLE); - } - - @Test - public void updateLinearProgressbar_isInVisible_shouldHideProgressBar() { - mFragment.setLoadingEnabled(false /* enabled */); - - assertThat(mFragment.mProgressHeader.getVisibility()).isEqualTo(View.INVISIBLE); - assertThat(mFragment.mProgressAnimation.getVisibility()).isEqualTo(View.INVISIBLE); - } -}