From a9ddae85e16fe2cf666d652aa29c3d608bdf3734 Mon Sep 17 00:00:00 2001 From: Abel Tesfaye Date: Tue, 18 May 2021 22:04:41 +0000 Subject: [PATCH 1/9] Fix LifecycleObserver implementation in SmartAutoRotateBatterySaverController Test: locally with flame, make RunSettingsRoboTests -j96 ROBOTEST_FILTER=SmartAutoRotateBatterySaverControllerTest,SmartAutoRotateControllerTest Bug: 188448874 Change-Id: I30ad19da617a166989e9c93e8d2b19263d58419f --- .../settings/display/SmartAutoRotateBatterySaverController.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/com/android/settings/display/SmartAutoRotateBatterySaverController.java b/src/com/android/settings/display/SmartAutoRotateBatterySaverController.java index d135d4b06a4..4e083029ce9 100644 --- a/src/com/android/settings/display/SmartAutoRotateBatterySaverController.java +++ b/src/com/android/settings/display/SmartAutoRotateBatterySaverController.java @@ -25,12 +25,12 @@ import android.content.IntentFilter; import android.os.PowerManager; import androidx.annotation.VisibleForTesting; -import androidx.lifecycle.LifecycleObserver; import androidx.preference.Preference; import androidx.preference.PreferenceScreen; import com.android.settings.R; import com.android.settings.core.BasePreferenceController; +import com.android.settingslib.core.lifecycle.LifecycleObserver; import com.android.settingslib.core.lifecycle.events.OnStart; import com.android.settingslib.core.lifecycle.events.OnStop; import com.android.settingslib.widget.BannerMessagePreference; From 10e459921953825d34e70cc4da846aac703d913c Mon Sep 17 00:00:00 2001 From: Hugh Chen Date: Thu, 3 Jun 2021 16:38:24 +0800 Subject: [PATCH 2/9] Fix phishing attacks over Bluetooth due to unclear warning message This CL add more prompts presented for users to avoid phishing attacks. Screenshot: https://screenshot.googleplex.com/p5PZbphN46ddPFV.png https://screenshot.googleplex.com/6Q2wKfPbNQmTtx8.png https://screenshot.googleplex.com/987VpYgNUZL2K4T.png https://screenshot.googleplex.com/9eVg6SAGScVXU8U.png Bug: 167403112 Test: manually test Change-Id: Iadec059b662fd91754ad573bbe688702cdd3c9af --- res/values/strings.xml | 21 +++++++++++++++++ .../BluetoothPermissionActivity.java | 23 ++++++++++++------- .../bluetooth/BluetoothPermissionRequest.java | 12 ++++++---- 3 files changed, 44 insertions(+), 12 deletions(-) diff --git a/res/values/strings.xml b/res/values/strings.xml index e023c700d77..30d3ad910d8 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -13409,4 +13409,25 @@ Game settings Turn on Game Dashboard shortcut, etc + + + SIM card access request + + A device wants to access your SIM card. Tap for details. + + Allow access to SIM card? + + A Bluetooth device, %1$s, wants to access data on your SIM card. This includes your contacts.\n\nWhile connected, %2$s will receive all calls made to %3$s. + + Bluetooth device available + + A device wants to connect. Tap for details. + + Connect to Bluetooth device? + + %1$s wants to connect to this phone.\n\nYou haven\u2019t connected to %2$s before. + + Don\u2019t connect + + Connect diff --git a/src/com/android/settings/bluetooth/BluetoothPermissionActivity.java b/src/com/android/settings/bluetooth/BluetoothPermissionActivity.java index 8794b08129b..211bcc6f4b4 100644 --- a/src/com/android/settings/bluetooth/BluetoothPermissionActivity.java +++ b/src/com/android/settings/bluetooth/BluetoothPermissionActivity.java @@ -25,6 +25,7 @@ import android.content.DialogInterface; import android.content.Intent; import android.content.IntentFilter; import android.os.Bundle; +import android.telephony.TelephonyManager; import android.util.Log; import android.view.View; import android.widget.Button; @@ -94,13 +95,13 @@ public class BluetoothPermissionActivity extends AlertActivity implements if(DEBUG) Log.i(TAG, "onCreate() Request type: " + mRequestType); if (mRequestType == BluetoothDevice.REQUEST_TYPE_PROFILE_CONNECTION) { - showDialog(getString(R.string.bluetooth_connection_permission_request), mRequestType); + showDialog(getString(R.string.bluetooth_connect_access_dialog_title), mRequestType); } else if (mRequestType == BluetoothDevice.REQUEST_TYPE_PHONEBOOK_ACCESS) { showDialog(getString(R.string.bluetooth_phonebook_access_dialog_title), mRequestType); } else if (mRequestType == BluetoothDevice.REQUEST_TYPE_MESSAGE_ACCESS) { showDialog(getString(R.string.bluetooth_message_access_dialog_title), mRequestType); } else if (mRequestType == BluetoothDevice.REQUEST_TYPE_SIM_ACCESS) { - showDialog(getString(R.string.bluetooth_sap_request), mRequestType); + showDialog(getString(R.string.bluetooth_sim_card_access_dialog_title), mRequestType); } else { Log.e(TAG, "Error: bad request type: " + mRequestType); @@ -133,9 +134,14 @@ public class BluetoothPermissionActivity extends AlertActivity implements p.mView = createSapDialogView(); break; } - p.mPositiveButtonText = getString(R.string.allow); + p.mPositiveButtonText = getString( + requestType == BluetoothDevice.REQUEST_TYPE_PROFILE_CONNECTION + ? R.string.bluetooth_connect_access_dialog_positive : R.string.allow); p.mPositiveButtonListener = this; - p.mNegativeButtonText = getString(R.string.request_manage_bluetooth_permission_dont_allow); + p.mNegativeButtonText = getString( + requestType == BluetoothDevice.REQUEST_TYPE_PROFILE_CONNECTION + ? R.string.bluetooth_connect_access_dialog_negative + : R.string.request_manage_bluetooth_permission_dont_allow); p.mNegativeButtonListener = this; mOkButton = mAlert.getButton(DialogInterface.BUTTON_POSITIVE); setupAlert(); @@ -156,8 +162,8 @@ public class BluetoothPermissionActivity extends AlertActivity implements String mRemoteName = Utils.createRemoteName(this, mDevice); mView = getLayoutInflater().inflate(R.layout.bluetooth_access, null); messageView = (TextView)mView.findViewById(R.id.message); - messageView.setText(getString(R.string.bluetooth_connection_dialog_text, - mRemoteName)); + messageView.setText(getString(R.string.bluetooth_connect_access_dialog_content, + mRemoteName, mRemoteName)); return mView; } @@ -181,10 +187,11 @@ public class BluetoothPermissionActivity extends AlertActivity implements private View createSapDialogView() { String mRemoteName = Utils.createRemoteName(this, mDevice); + TelephonyManager tm = getSystemService(TelephonyManager.class); mView = getLayoutInflater().inflate(R.layout.bluetooth_access, null); messageView = (TextView)mView.findViewById(R.id.message); - messageView.setText(getString(R.string.bluetooth_sap_acceptance_dialog_text, - mRemoteName, mRemoteName)); + messageView.setText(getString(R.string.bluetooth_sim_card_access_dialog_content, + mRemoteName, mRemoteName, tm.getLine1Number())); return mView; } diff --git a/src/com/android/settings/bluetooth/BluetoothPermissionRequest.java b/src/com/android/settings/bluetooth/BluetoothPermissionRequest.java index 66665f06761..ff1c1471c02 100644 --- a/src/com/android/settings/bluetooth/BluetoothPermissionRequest.java +++ b/src/com/android/settings/bluetooth/BluetoothPermissionRequest.java @@ -144,13 +144,17 @@ public final class BluetoothPermissionRequest extends BroadcastReceiver { R.string.bluetooth_message_access_notification_content); break; case BluetoothDevice.REQUEST_TYPE_SIM_ACCESS: - title = context.getString(R.string.bluetooth_sap_request); - message = context.getString(R.string.bluetooth_sap_acceptance_dialog_text, + title = context.getString( + R.string.bluetooth_sim_card_access_notification_title); + message = context.getString( + R.string.bluetooth_sim_card_access_notification_content, deviceAlias, deviceAlias); break; default: - title = context.getString(R.string.bluetooth_connection_permission_request); - message = context.getString(R.string.bluetooth_connection_dialog_text, + title = context.getString( + R.string.bluetooth_connect_access_notification_title); + message = context.getString( + R.string.bluetooth_connect_access_notification_content, deviceAlias, deviceAlias); break; } From 5b219a34ab8659b0bc51d43ad61d630aeb4625e0 Mon Sep 17 00:00:00 2001 From: Yi-Ling Chuang Date: Thu, 3 Jun 2021 18:04:36 +0800 Subject: [PATCH 3/9] Disable RecyclerView animation to fix the broken UI RecyclerView has item animation by default. In this bug, RV animation seems to be interrupted by the page transitions(Shared Axis), and so items could not finish sliding to its position. Hence, disable RV animation to fix it. Fixes: 189720797 Test: Navigate to Mobile & Wifi usage page and see the normal UI. Change-Id: I52920715ae4b63ef78a73fcb9c76c6d20f80e012 --- src/com/android/settings/datausage/AppDataUsage.java | 10 ++++++++++ .../notification/app/AppNotificationSettings.java | 9 +++++++++ 2 files changed, 19 insertions(+) diff --git a/src/com/android/settings/datausage/AppDataUsage.java b/src/com/android/settings/datausage/AppDataUsage.java index 460f3909f74..5c5900e8f37 100644 --- a/src/com/android/settings/datausage/AppDataUsage.java +++ b/src/com/android/settings/datausage/AppDataUsage.java @@ -39,8 +39,10 @@ import androidx.loader.content.Loader; import androidx.preference.Preference; import androidx.preference.Preference.OnPreferenceChangeListener; import androidx.preference.PreferenceCategory; +import androidx.recyclerview.widget.RecyclerView; import com.android.settings.R; +import com.android.settings.Utils; import com.android.settings.applications.AppInfoBase; import com.android.settings.widget.EntityHeaderController; import com.android.settingslib.AppItem; @@ -221,6 +223,14 @@ public class AppDataUsage extends DataUsageBaseFragment implements OnPreferenceC } LoaderManager.getInstance(this).restartLoader(LOADER_APP_USAGE_DATA, null /* args */, mUidDataCallbacks); + + if (Utils.isPageTransitionEnabled(mContext)) { + final RecyclerView recyclerView = getListView(); + if (recyclerView != null) { + recyclerView.setItemAnimator(null); + } + } + updatePrefs(); } diff --git a/src/com/android/settings/notification/app/AppNotificationSettings.java b/src/com/android/settings/notification/app/AppNotificationSettings.java index d7694d7e45e..8d0819cd979 100644 --- a/src/com/android/settings/notification/app/AppNotificationSettings.java +++ b/src/com/android/settings/notification/app/AppNotificationSettings.java @@ -25,9 +25,11 @@ import android.util.Log; import androidx.preference.Preference; import androidx.preference.PreferenceGroup; import androidx.preference.PreferenceScreen; +import androidx.recyclerview.widget.RecyclerView; import com.android.internal.widget.LockPatternUtils; import com.android.settings.R; +import com.android.settings.Utils; import com.android.settingslib.core.AbstractPreferenceController; import java.util.ArrayList; @@ -78,6 +80,13 @@ public class AppNotificationSettings extends NotificationSettings { return; } + if (Utils.isPageTransitionEnabled(mContext)) { + final RecyclerView recyclerView = getListView(); + if (recyclerView != null) { + recyclerView.setItemAnimator(null); + } + } + for (NotificationPreferenceController controller : mControllers) { controller.onResume(mAppRow, mChannel, mChannelGroup, null, null, mSuspendedAppsAdmin, null); From 578affca57f599066b398ae22bb8a63c4453a6b7 Mon Sep 17 00:00:00 2001 From: Arc Wang Date: Fri, 4 Jun 2021 10:45:36 +0800 Subject: [PATCH 4/9] Set font size 20 for StorageItemPreference To improve UX. Bug: 189390237 Test: manual visual Change-Id: Ice40b7c8c86f7f4c220d43fd7f4a035e6160e50d --- res/layout/storage_item.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/res/layout/storage_item.xml b/res/layout/storage_item.xml index 40796f7b373..45a99917780 100644 --- a/res/layout/storage_item.xml +++ b/res/layout/storage_item.xml @@ -47,6 +47,7 @@ android:layout_height="wrap_content" android:singleLine="true" android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Subhead" + android:textSize="20sp" android:textAlignment="viewStart" android:ellipsize="marquee" app:layout_constraintStart_toStartOf="parent" @@ -58,6 +59,7 @@ android:layout_height="wrap_content" android:textAlignment="viewStart" android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Body1" + android:textSize="20sp" android:textColor="?android:attr/textColorSecondary" android:maxLines="10" app:layout_constraintBaseline_toBaselineOf="@android:id/title" From 51b3e7a09336f1f0701eed5a94cfaaf4e41fb79f Mon Sep 17 00:00:00 2001 From: Arc Wang Date: Mon, 31 May 2021 11:50:22 +0800 Subject: [PATCH 5/9] Storage Settings hides categories when loading To hide sorting animation. - Storage Settings always loads cache and updates UI, then loads storage size and updates UI. Remove the chche design because storage category preferences will hide during loading, it no meaning to load from cache and update UI. - Hides loading circle before storage category preferences become visible, it prevents flickers. - Remove Calculating... summary of StorageItemPreference. - Private storage category preferences and secondary user preference become visible at StorageItemPreferenceController#onLoadFinished. Bug: 188731179 Bug: 185547228 Bug: 188615591 Test: atest com.android.settings.deviceinfo atest com.android.settings.deviceinfo.storage make RunSettingsRoboTests -j ROBOTEST_FILTER=com.android.settings.deviceinfo make RunSettingsRoboTests -j ROBOTEST_FILTER=com.android.settings.deviceinfo.storage manual visual Change-Id: I3ebef5829ef4f806add07f58fa02520804768be5 --- res/xml/storage_category_fragment.xml | 3 +- .../deviceinfo/StorageCategoryFragment.java | 63 ++-- .../deviceinfo/StorageDashboardFragment.java | 63 ++-- .../deviceinfo/StorageItemPreference.java | 1 - .../storage/CachedStorageValuesHelper.java | 184 ----------- .../storage/SecondaryUserController.java | 21 +- .../StorageItemPreferenceController.java | 45 +-- .../StorageDashboardFragmentTest.java | 43 --- .../deviceinfo/StorageItemPreferenceTest.java | 6 - .../CachedStorageValuesHelperTest.java | 304 ------------------ .../StorageItemPreferenceControllerTest.java | 11 +- 11 files changed, 95 insertions(+), 649 deletions(-) delete mode 100644 src/com/android/settings/deviceinfo/storage/CachedStorageValuesHelper.java delete mode 100644 tests/robotests/src/com/android/settings/deviceinfo/storage/CachedStorageValuesHelperTest.java diff --git a/res/xml/storage_category_fragment.xml b/res/xml/storage_category_fragment.xml index 72623d7b269..fb62beeaecf 100644 --- a/res/xml/storage_category_fragment.xml +++ b/res/xml/storage_category_fragment.xml @@ -24,8 +24,7 @@ android:order="4" android:title="@string/storage_free_up_space_title" android:summary="@string/storage_free_up_space_summary" - android:icon="@drawable/ic_files_go_round" - settings:allowDividerAbove="true"/> + android:icon="@drawable/ic_files_go_round"/> mAppsResult; - private CachedStorageValuesHelper mCachedStorageValuesHelper; private StorageItemPreferenceController mPreferenceController; private List mSecondaryUsers; @@ -104,6 +103,10 @@ public class StorageCategoryFragment extends DashboardFragment return; } + // To prevent flicker, hides secondary users preference. + // onReceivedSizes will set it visible for private storage. + setSecondaryUsersVisible(false); + if (!mSelectedStorageEntry.isMounted()) { // Set null volume to hide category stats. mPreferenceController.setVolume(null); @@ -114,6 +117,10 @@ public class StorageCategoryFragment extends DashboardFragment mAppsResult = null; maybeSetLoading(isQuotaSupported()); + // To prevent flicker, sets null volume to hide category preferences. + // onReceivedSizes will setVolume with the volume of selected storage. + mPreferenceController.setVolume(null); + // Stats data is only available on private volumes. getLoaderManager().restartLoader(STORAGE_JOB_ID, Bundle.EMPTY, this); getLoaderManager() @@ -157,7 +164,6 @@ public class StorageCategoryFragment extends DashboardFragment @Override public void onViewCreated(View v, Bundle savedInstanceState) { super.onViewCreated(v, savedInstanceState); - initializeCacheProvider(); EntityHeaderController.newInstance(getActivity(), this /*fragment*/, null /* header view */) @@ -184,6 +190,10 @@ public class StorageCategoryFragment extends DashboardFragment return; } + if (getView().findViewById(R.id.loading_container).getVisibility() == View.VISIBLE) { + setLoading(false /* loading */, true /* animate */); + } + final long privateUsedBytes = mStorageInfo.totalBytes - mStorageInfo.freeBytes; mPreferenceController.setVolume(mSelectedStorageEntry.getVolumeInfo()); mPreferenceController.setUsedSize(privateUsedBytes); @@ -198,10 +208,7 @@ public class StorageCategoryFragment extends DashboardFragment mPreferenceController.onLoadFinished(mAppsResult, mUserId); updateSecondaryUserControllers(mSecondaryUsers, mAppsResult); - - if (getView().findViewById(R.id.loading_container).getVisibility() == View.VISIBLE) { - setLoading(false, true); - } + setSecondaryUsersVisible(true); } @Override @@ -263,7 +270,6 @@ public class StorageCategoryFragment extends DashboardFragment public void onLoadFinished(Loader> loader, SparseArray data) { mAppsResult = data; - maybeCacheFreshValues(); onReceivedSizes(); } @@ -286,11 +292,6 @@ public class StorageCategoryFragment extends DashboardFragment return false; } - @VisibleForTesting - public void setCachedStorageValuesHelper(CachedStorageValuesHelper helper) { - mCachedStorageValuesHelper = helper; - } - @VisibleForTesting public PrivateStorageInfo getPrivateStorageInfo() { return mStorageInfo; @@ -311,19 +312,6 @@ public class StorageCategoryFragment extends DashboardFragment mAppsResult = info; } - @VisibleForTesting - void initializeCachedValues() { - final PrivateStorageInfo info = mCachedStorageValuesHelper.getCachedPrivateStorageInfo(); - final SparseArray loaderResult = - mCachedStorageValuesHelper.getCachedStorageResult(); - if (info == null || loaderResult == null) { - return; - } - - mStorageInfo = info; - mAppsResult = loaderResult; - } - /** * Activate loading UI and animation if it's necessary. */ @@ -337,24 +325,22 @@ public class StorageCategoryFragment extends DashboardFragment } } - private void initializeCacheProvider() { - mCachedStorageValuesHelper = new CachedStorageValuesHelper(getContext(), mUserId); - initializeCachedValues(); - onReceivedSizes(); - } - - private void maybeCacheFreshValues() { - if (mStorageInfo != null && mAppsResult != null) { - mCachedStorageValuesHelper.cacheResult(mStorageInfo, mAppsResult.get(mUserId)); - } - } - private boolean isQuotaSupported() { return mSelectedStorageEntry.isMounted() && getActivity().getSystemService(StorageStatsManager.class) .isQuotaSupported(mSelectedStorageEntry.getFsUuid()); } + private void setSecondaryUsersVisible(boolean visible) { + final Optional secondaryUserController = mSecondaryUsers.stream() + .filter(controller -> controller instanceof SecondaryUserController) + .map(controller -> (SecondaryUserController) controller) + .findAny(); + if (secondaryUserController.isPresent()) { + secondaryUserController.get().setPreferenceGroupVisible(visible); + } + } + /** * IconLoaderCallbacks exists because StorageCategoryFragment already implements * LoaderCallbacks for a different type. @@ -414,7 +400,6 @@ public class StorageCategoryFragment extends DashboardFragment } mStorageInfo = privateStorageInfo; - maybeCacheFreshValues(); onReceivedSizes(); } } diff --git a/src/com/android/settings/deviceinfo/StorageDashboardFragment.java b/src/com/android/settings/deviceinfo/StorageDashboardFragment.java index b76d1cbdbf5..6dbc3aa9a7e 100644 --- a/src/com/android/settings/deviceinfo/StorageDashboardFragment.java +++ b/src/com/android/settings/deviceinfo/StorageDashboardFragment.java @@ -44,7 +44,6 @@ import com.android.settings.R; import com.android.settings.Utils; import com.android.settings.dashboard.DashboardFragment; import com.android.settings.deviceinfo.storage.AutomaticStorageManagementSwitchPreferenceController; -import com.android.settings.deviceinfo.storage.CachedStorageValuesHelper; import com.android.settings.deviceinfo.storage.DiskInitFragment; import com.android.settings.deviceinfo.storage.SecondaryUserController; import com.android.settings.deviceinfo.storage.StorageAsyncLoader; @@ -68,6 +67,7 @@ import com.android.settingslib.search.SearchIndexable; import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import java.util.Optional; /** * Storage Settings main UI is composed by 3 fragments: @@ -101,7 +101,6 @@ public class StorageDashboardFragment extends DashboardFragment private StorageEntry mSelectedStorageEntry; private PrivateStorageInfo mStorageInfo; private SparseArray mAppsResult; - private CachedStorageValuesHelper mCachedStorageValuesHelper; private StorageItemPreferenceController mPreferenceController; private VolumeOptionMenuController mOptionMenuController; @@ -232,6 +231,10 @@ public class StorageDashboardFragment extends DashboardFragment mOptionMenuController.setSelectedStorageEntry(mSelectedStorageEntry); getActivity().invalidateOptionsMenu(); + // To prevent flicker, hides secondary users preference. + // onReceivedSizes will set it visible for private storage. + setSecondaryUsersVisible(false); + if (!mSelectedStorageEntry.isMounted()) { // Set null volume to hide category stats. mPreferenceController.setVolume(null); @@ -242,6 +245,10 @@ public class StorageDashboardFragment extends DashboardFragment mAppsResult = null; maybeSetLoading(isQuotaSupported()); + // To prevent flicker, sets null volume to hide category preferences. + // onReceivedSizes will setVolume with the volume of selected storage. + mPreferenceController.setVolume(null); + // Stats data is only available on private volumes. getLoaderManager().restartLoader(STORAGE_JOB_ID, Bundle.EMPTY, this); getLoaderManager() @@ -316,7 +323,6 @@ public class StorageDashboardFragment extends DashboardFragment @Override public void onViewCreated(View v, Bundle savedInstanceState) { super.onViewCreated(v, savedInstanceState); - initializeCacheProvider(); EntityHeaderController.newInstance(getActivity(), this /*fragment*/, null /* header view */) @@ -355,6 +361,10 @@ public class StorageDashboardFragment extends DashboardFragment return; } + if (getView().findViewById(R.id.loading_container).getVisibility() == View.VISIBLE) { + setLoading(false /* loading */, true /* animate */); + } + final long privateUsedBytes = mStorageInfo.totalBytes - mStorageInfo.freeBytes; mPreferenceController.setVolume(mSelectedStorageEntry.getVolumeInfo()); mPreferenceController.setUsedSize(privateUsedBytes); @@ -369,10 +379,7 @@ public class StorageDashboardFragment extends DashboardFragment mPreferenceController.onLoadFinished(mAppsResult, mUserId); updateSecondaryUserControllers(mSecondaryUsers, mAppsResult); - - if (getView().findViewById(R.id.loading_container).getVisibility() == View.VISIBLE) { - setLoading(false, true); - } + setSecondaryUsersVisible(true); } @Override @@ -463,7 +470,6 @@ public class StorageDashboardFragment extends DashboardFragment public void onLoadFinished(Loader> loader, SparseArray data) { mAppsResult = data; - maybeCacheFreshValues(); onReceivedSizes(); } @@ -486,11 +492,6 @@ public class StorageDashboardFragment extends DashboardFragment return false; } - @VisibleForTesting - public void setCachedStorageValuesHelper(CachedStorageValuesHelper helper) { - mCachedStorageValuesHelper = helper; - } - @VisibleForTesting public PrivateStorageInfo getPrivateStorageInfo() { return mStorageInfo; @@ -511,19 +512,6 @@ public class StorageDashboardFragment extends DashboardFragment mAppsResult = info; } - @VisibleForTesting - void initializeCachedValues() { - final PrivateStorageInfo info = mCachedStorageValuesHelper.getCachedPrivateStorageInfo(); - final SparseArray loaderResult = - mCachedStorageValuesHelper.getCachedStorageResult(); - if (info == null || loaderResult == null) { - return; - } - - mStorageInfo = info; - mAppsResult = loaderResult; - } - /** * Activate loading UI and animation if it's necessary. */ @@ -537,24 +525,22 @@ public class StorageDashboardFragment extends DashboardFragment } } - private void initializeCacheProvider() { - mCachedStorageValuesHelper = new CachedStorageValuesHelper(getContext(), mUserId); - initializeCachedValues(); - onReceivedSizes(); - } - - private void maybeCacheFreshValues() { - if (mStorageInfo != null && mAppsResult != null) { - mCachedStorageValuesHelper.cacheResult(mStorageInfo, mAppsResult.get(mUserId)); - } - } - private boolean isQuotaSupported() { return mSelectedStorageEntry.isMounted() && getActivity().getSystemService(StorageStatsManager.class) .isQuotaSupported(mSelectedStorageEntry.getFsUuid()); } + private void setSecondaryUsersVisible(boolean visible) { + final Optional secondaryUserController = mSecondaryUsers.stream() + .filter(controller -> controller instanceof SecondaryUserController) + .map(controller -> (SecondaryUserController) controller) + .findAny(); + if (secondaryUserController.isPresent()) { + secondaryUserController.get().setPreferenceGroupVisible(visible); + } + } + /** * IconLoaderCallbacks exists because StorageDashboardFragment already implements * LoaderCallbacks for a different type. @@ -614,7 +600,6 @@ public class StorageDashboardFragment extends DashboardFragment } mStorageInfo = privateStorageInfo; - maybeCacheFreshValues(); onReceivedSizes(); } } diff --git a/src/com/android/settings/deviceinfo/StorageItemPreference.java b/src/com/android/settings/deviceinfo/StorageItemPreference.java index cdb9f9d6fe1..934ff3f603b 100644 --- a/src/com/android/settings/deviceinfo/StorageItemPreference.java +++ b/src/com/android/settings/deviceinfo/StorageItemPreference.java @@ -43,7 +43,6 @@ public class StorageItemPreference extends Preference { public StorageItemPreference(Context context, AttributeSet attrs) { super(context, attrs); setLayoutResource(R.layout.storage_item); - setSummary(R.string.memory_calculating_size); } public void setStorageSize(long size, long total) { diff --git a/src/com/android/settings/deviceinfo/storage/CachedStorageValuesHelper.java b/src/com/android/settings/deviceinfo/storage/CachedStorageValuesHelper.java deleted file mode 100644 index 4ca623dc53d..00000000000 --- a/src/com/android/settings/deviceinfo/storage/CachedStorageValuesHelper.java +++ /dev/null @@ -1,184 +0,0 @@ -/* - * Copyright (C) 2017 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.deviceinfo.storage; - -import android.content.Context; -import android.content.SharedPreferences; -import android.provider.Settings; -import android.util.SparseArray; - -import androidx.annotation.VisibleForTesting; - -import com.android.settingslib.applications.StorageStatsSource; -import com.android.settingslib.deviceinfo.PrivateStorageInfo; - -import java.util.concurrent.TimeUnit; - -public class CachedStorageValuesHelper { - - @VisibleForTesting public static final String SHARED_PREFERENCES_NAME = "CachedStorageValues"; - public static final String TIMESTAMP_KEY = "last_query_timestamp"; - public static final String FREE_BYTES_KEY = "free_bytes"; - public static final String TOTAL_BYTES_KEY = "total_bytes"; - public static final String GAME_APPS_SIZE_KEY = "game_apps_size"; - public static final String AUDIO_SIZE_KEY = "audio_size"; - public static final String VIDEOS_SIZE_KEY = "videos_size"; - public static final String IMAGES_SIZE_KEY = "images_size"; - public static final String DOCUMENTS_AND_OTHER_SIZE_KEY = "documents_and_other_size"; - public static final String TRASH_SIZE_KEY = "trash_size"; - public static final String OTHER_APPS_SIZE_KEY = "other_apps_size"; - public static final String CACHE_APPS_SIZE_KEY = "cache_apps_size"; - public static final String EXTERNAL_TOTAL_BYTES = "external_total_bytes"; - public static final String EXTERNAL_AUDIO_BYTES = "external_audio_bytes"; - public static final String EXTERNAL_VIDEO_BYTES = "external_video_bytes"; - public static final String EXTERNAL_IMAGE_BYTES = "external_image_bytes"; - public static final String EXTERNAL_APP_BYTES = "external_apps_bytes"; - public static final String USER_ID_KEY = "user_id"; - private final Long mClobberThreshold; - private final SharedPreferences mSharedPreferences; - private final int mUserId; - // This clock is used to provide the time. By default, it uses the system clock, but can be - // replaced for test purposes. - protected Clock mClock; - - public CachedStorageValuesHelper(Context context, int userId) { - mSharedPreferences = - context.getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE); - mClock = new Clock(); - mUserId = userId; - mClobberThreshold = - Settings.Global.getLong( - context.getContentResolver(), - Settings.Global.STORAGE_SETTINGS_CLOBBER_THRESHOLD, - TimeUnit.MINUTES.toMillis(5)); - } - - public PrivateStorageInfo getCachedPrivateStorageInfo() { - if (!isDataValid()) { - return null; - } - final long freeBytes = mSharedPreferences.getLong(FREE_BYTES_KEY, -1); - final long totalBytes = mSharedPreferences.getLong(TOTAL_BYTES_KEY, -1); - if (freeBytes < 0 || totalBytes < 0) { - return null; - } - - return new PrivateStorageInfo(freeBytes, totalBytes); - } - - /** Returns cached storage result or null if it's not available. */ - public SparseArray getCachedStorageResult() { - if (!isDataValid()) { - return null; - } - final long gamesSize = mSharedPreferences.getLong(GAME_APPS_SIZE_KEY, -1); - final long audioSize = mSharedPreferences.getLong(AUDIO_SIZE_KEY, -1); - final long videosSize = mSharedPreferences.getLong(VIDEOS_SIZE_KEY, -1); - final long imagesSize = mSharedPreferences.getLong(IMAGES_SIZE_KEY, -1); - final long documentsAndOtherSize = - mSharedPreferences.getLong(DOCUMENTS_AND_OTHER_SIZE_KEY, -1); - final long trashSize = mSharedPreferences.getLong(TRASH_SIZE_KEY, -1); - final long allAppsExceptGamesSize = mSharedPreferences.getLong(OTHER_APPS_SIZE_KEY, -1); - final long cacheSize = mSharedPreferences.getLong(CACHE_APPS_SIZE_KEY, -1); - if (gamesSize < 0 - || audioSize < 0 - || videosSize < 0 - || imagesSize < 0 - || documentsAndOtherSize < 0 - || trashSize < 0 - || allAppsExceptGamesSize < 0 - || cacheSize < 0) { - return null; - } - - final long externalTotalBytes = mSharedPreferences.getLong(EXTERNAL_TOTAL_BYTES, -1); - final long externalAudioBytes = mSharedPreferences.getLong(EXTERNAL_AUDIO_BYTES, -1); - final long externalVideoBytes = mSharedPreferences.getLong(EXTERNAL_VIDEO_BYTES, -1); - final long externalImageBytes = mSharedPreferences.getLong(EXTERNAL_IMAGE_BYTES, -1); - final long externalAppBytes = mSharedPreferences.getLong(EXTERNAL_APP_BYTES, -1); - if (externalTotalBytes < 0 - || externalAudioBytes < 0 - || externalVideoBytes < 0 - || externalImageBytes < 0 - || externalAppBytes < 0) { - return null; - } - - final StorageStatsSource.ExternalStorageStats externalStats = - new StorageStatsSource.ExternalStorageStats( - externalTotalBytes, - externalAudioBytes, - externalVideoBytes, - externalImageBytes, - externalAppBytes); - final StorageAsyncLoader.StorageResult result = new StorageAsyncLoader.StorageResult(); - result.gamesSize = gamesSize; - result.audioSize = audioSize; - result.videosSize = videosSize; - result.imagesSize = imagesSize; - result.documentsAndOtherSize = documentsAndOtherSize; - result.trashSize = trashSize; - result.allAppsExceptGamesSize = allAppsExceptGamesSize; - result.cacheSize = cacheSize; - result.externalStats = externalStats; - final SparseArray resultArray = new SparseArray<>(); - resultArray.append(mUserId, result); - return resultArray; - } - - public void cacheResult( - PrivateStorageInfo storageInfo, StorageAsyncLoader.StorageResult result) { - mSharedPreferences - .edit() - .putLong(FREE_BYTES_KEY, storageInfo.freeBytes) - .putLong(TOTAL_BYTES_KEY, storageInfo.totalBytes) - .putLong(GAME_APPS_SIZE_KEY, result.gamesSize) - .putLong(AUDIO_SIZE_KEY, result.audioSize) - .putLong(VIDEOS_SIZE_KEY, result.videosSize) - .putLong(IMAGES_SIZE_KEY, result.imagesSize) - .putLong(DOCUMENTS_AND_OTHER_SIZE_KEY, result.documentsAndOtherSize) - .putLong(TRASH_SIZE_KEY, result.trashSize) - .putLong(OTHER_APPS_SIZE_KEY, result.allAppsExceptGamesSize) - .putLong(CACHE_APPS_SIZE_KEY, result.cacheSize) - .putLong(EXTERNAL_TOTAL_BYTES, result.externalStats.totalBytes) - .putLong(EXTERNAL_AUDIO_BYTES, result.externalStats.audioBytes) - .putLong(EXTERNAL_VIDEO_BYTES, result.externalStats.videoBytes) - .putLong(EXTERNAL_IMAGE_BYTES, result.externalStats.imageBytes) - .putLong(EXTERNAL_APP_BYTES, result.externalStats.appBytes) - .putInt(USER_ID_KEY, mUserId) - .putLong(TIMESTAMP_KEY, mClock.getCurrentTime()) - .apply(); - } - - private boolean isDataValid() { - final int cachedUserId = mSharedPreferences.getInt(USER_ID_KEY, -1); - if (cachedUserId != mUserId) { - return false; - } - - final long lastQueryTime = mSharedPreferences.getLong(TIMESTAMP_KEY, Long.MAX_VALUE); - final long currentTime = mClock.getCurrentTime(); - return currentTime - lastQueryTime < mClobberThreshold; - } - - /** Clock provides the current time. */ - static class Clock { - public long getCurrentTime() { - return System.currentTimeMillis(); - } - } -} diff --git a/src/com/android/settings/deviceinfo/storage/SecondaryUserController.java b/src/com/android/settings/deviceinfo/storage/SecondaryUserController.java index 6475029f21b..f87a06a76f0 100644 --- a/src/com/android/settings/deviceinfo/storage/SecondaryUserController.java +++ b/src/com/android/settings/deviceinfo/storage/SecondaryUserController.java @@ -53,9 +53,11 @@ public class SecondaryUserController extends AbstractPreferenceController implem UserInfo mUser; private @Nullable StorageItemPreference mStoragePreference; + private PreferenceGroup mPreferenceGroup; private Drawable mUserIcon; private long mSize; private long mTotalSizeBytes; + private boolean mIsVisible; /** * Adds the appropriate controllers to a controller list for handling all secondary users on @@ -115,16 +117,15 @@ public class SecondaryUserController extends AbstractPreferenceController implem if (mStoragePreference == null) { mStoragePreference = new StorageItemPreference(screen.getContext()); - PreferenceGroup group = - screen.findPreference(TARGET_PREFERENCE_GROUP_KEY); + mPreferenceGroup = screen.findPreference(TARGET_PREFERENCE_GROUP_KEY); mStoragePreference.setTitle(mUser.name); mStoragePreference.setKey(PREFERENCE_KEY_BASE + mUser.id); if (mSize != SIZE_NOT_SET) { mStoragePreference.setStorageSize(mSize, mTotalSizeBytes); } - group.setVisible(true); - group.addPreference(mStoragePreference); + mPreferenceGroup.setVisible(mIsVisible); + mPreferenceGroup.addPreference(mStoragePreference); maybeSetIcon(); } } @@ -168,6 +169,18 @@ public class SecondaryUserController extends AbstractPreferenceController implem mTotalSizeBytes = totalSizeBytes; } + /** + * Sets visibility of the PreferenceGroup of secondary user. + * + * @param visible Visibility of the PreferenceGroup. + */ + public void setPreferenceGroupVisible(boolean visible) { + mIsVisible = visible; + if (mPreferenceGroup != null) { + mPreferenceGroup.setVisible(mIsVisible); + } + } + @Override public void handleResult(SparseArray stats) { final StorageAsyncLoader.StorageResult result = stats.get(getUser().id); diff --git a/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceController.java b/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceController.java index 41e26ee983e..22ea98fda3e 100644 --- a/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceController.java +++ b/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceController.java @@ -221,7 +221,15 @@ public class StorageItemPreferenceController extends AbstractPreferenceControlle public void setVolume(VolumeInfo volume) { mVolume = volume; - updateCategoryPreferencesVisibility(); + if (mPublicStoragePreference != null) { + mPublicStoragePreference.setVisible(isValidPublicVolume()); + } + + // If isValidPrivateVolume() is true, these preferences will become visible at + // onLoadFinished. + if (!isValidPrivateVolume()) { + setPrivateStorageCategoryPreferencesVisibility(false); + } } // Stats data is only available on private volumes. @@ -242,30 +250,28 @@ public class StorageItemPreferenceController extends AbstractPreferenceControlle || mVolume.getState() == VolumeInfo.STATE_MOUNTED_READ_ONLY); } - private void updateCategoryPreferencesVisibility() { + @VisibleForTesting + void setPrivateStorageCategoryPreferencesVisibility(boolean visible) { if (mScreen == null) { return; } - mPublicStoragePreference.setVisible(isValidPublicVolume()); + mImagesPreference.setVisible(visible); + mVideosPreference.setVisible(visible); + mAudioPreference.setVisible(visible); + mAppsPreference.setVisible(visible); + mGamesPreference.setVisible(visible); + mSystemPreference.setVisible(visible); + mTrashPreference.setVisible(visible); - final boolean privateStoragePreferencesVisible = isValidPrivateVolume(); - mImagesPreference.setVisible(privateStoragePreferencesVisible); - mVideosPreference.setVisible(privateStoragePreferencesVisible); - mAudioPreference.setVisible(privateStoragePreferencesVisible); - mAppsPreference.setVisible(privateStoragePreferencesVisible); - mGamesPreference.setVisible(privateStoragePreferencesVisible); - mDocumentsAndOtherPreference.setVisible(privateStoragePreferencesVisible); - mSystemPreference.setVisible(privateStoragePreferencesVisible); - mTrashPreference.setVisible(privateStoragePreferencesVisible); - - if (privateStoragePreferencesVisible) { + // If we don't have a shared volume for our internal storage (or the shared volume isn't + // mounted as readable for whatever reason), we should hide the File preference. + if (visible) { final VolumeInfo sharedVolume = mSvp.findEmulatedForPrivate(mVolume); - // If we don't have a shared volume for our internal storage (or the shared volume isn't - // mounted as readable for whatever reason), we should hide the File preference. - if (sharedVolume == null || !sharedVolume.isMountedReadable()) { - mDocumentsAndOtherPreference.setVisible(false); - } + mDocumentsAndOtherPreference.setVisible(sharedVolume != null + && sharedVolume.isMountedReadable()); + } else { + mDocumentsAndOtherPreference.setVisible(false); } } @@ -390,6 +396,7 @@ public class StorageItemPreferenceController extends AbstractPreferenceControlle } updatePrivateStorageCategoryPreferencesOrder(); + setPrivateStorageCategoryPreferencesVisibility(true); } public void setUsedSize(long usedSizeBytes) { diff --git a/tests/robotests/src/com/android/settings/deviceinfo/StorageDashboardFragmentTest.java b/tests/robotests/src/com/android/settings/deviceinfo/StorageDashboardFragmentTest.java index af1900ac83a..411a3cf3efa 100644 --- a/tests/robotests/src/com/android/settings/deviceinfo/StorageDashboardFragmentTest.java +++ b/tests/robotests/src/com/android/settings/deviceinfo/StorageDashboardFragmentTest.java @@ -33,8 +33,6 @@ import android.view.View; import androidx.recyclerview.widget.RecyclerView; -import com.android.settings.deviceinfo.storage.CachedStorageValuesHelper; -import com.android.settings.deviceinfo.storage.StorageAsyncLoader; import com.android.settingslib.deviceinfo.PrivateStorageInfo; import com.android.settingslib.drawer.CategoryKey; @@ -72,47 +70,6 @@ public class StorageDashboardFragmentTest { verify(activity).invalidateOptionsMenu(); } - @Test - public void test_cacheProviderProvidesValuesIfBothCached() { - CachedStorageValuesHelper helper = mock(CachedStorageValuesHelper.class); - PrivateStorageInfo info = new PrivateStorageInfo(0, 0); - when(helper.getCachedPrivateStorageInfo()).thenReturn(info); - SparseArray result = new SparseArray<>(); - when(helper.getCachedStorageResult()).thenReturn(result); - - mFragment.setCachedStorageValuesHelper(helper); - mFragment.initializeCachedValues(); - - assertThat(mFragment.getPrivateStorageInfo()).isEqualTo(info); - assertThat(mFragment.getStorageResult()).isEqualTo(result); - } - - @Test - public void test_cacheProviderDoesntProvideValuesIfAppsMissing() { - CachedStorageValuesHelper helper = mock(CachedStorageValuesHelper.class); - PrivateStorageInfo info = new PrivateStorageInfo(0, 0); - when(helper.getCachedPrivateStorageInfo()).thenReturn(info); - - mFragment.setCachedStorageValuesHelper(helper); - mFragment.initializeCachedValues(); - - assertThat(mFragment.getPrivateStorageInfo()).isNull(); - assertThat(mFragment.getStorageResult()).isNull(); - } - - @Test - public void test_cacheProviderDoesntProvideValuesIfVolumeInfoMissing() { - CachedStorageValuesHelper helper = mock(CachedStorageValuesHelper.class); - SparseArray result = new SparseArray<>(); - when(helper.getCachedStorageResult()).thenReturn(result); - - mFragment.setCachedStorageValuesHelper(helper); - mFragment.initializeCachedValues(); - - assertThat(mFragment.getPrivateStorageInfo()).isNull(); - assertThat(mFragment.getStorageResult()).isNull(); - } - @Test public void test_loadWhenQuotaOffIfVolumeInfoNotLoaded() { View fakeView = mock(View.class, RETURNS_DEEP_STUBS); diff --git a/tests/robotests/src/com/android/settings/deviceinfo/StorageItemPreferenceTest.java b/tests/robotests/src/com/android/settings/deviceinfo/StorageItemPreferenceTest.java index 24543801ef7..984d945dac6 100644 --- a/tests/robotests/src/com/android/settings/deviceinfo/StorageItemPreferenceTest.java +++ b/tests/robotests/src/com/android/settings/deviceinfo/StorageItemPreferenceTest.java @@ -45,12 +45,6 @@ public class StorageItemPreferenceTest { mPreference = new StorageItemPreference(mContext); } - @Test - public void testBeforeLoad() { - assertThat(mPreference.getSummary()) - .isEqualTo(mContext.getString(R.string.memory_calculating_size)); - } - @Test public void testAfterLoad() { mPreference.setStorageSize(MEGABYTE_IN_BYTES * 10, MEGABYTE_IN_BYTES * 100); diff --git a/tests/robotests/src/com/android/settings/deviceinfo/storage/CachedStorageValuesHelperTest.java b/tests/robotests/src/com/android/settings/deviceinfo/storage/CachedStorageValuesHelperTest.java deleted file mode 100644 index ccc9152a014..00000000000 --- a/tests/robotests/src/com/android/settings/deviceinfo/storage/CachedStorageValuesHelperTest.java +++ /dev/null @@ -1,304 +0,0 @@ -/* - * Copyright (C) 2017 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.deviceinfo.storage; - -import static com.android.settings.deviceinfo.storage.CachedStorageValuesHelper.AUDIO_SIZE_KEY; -import static com.android.settings.deviceinfo.storage.CachedStorageValuesHelper.CACHE_APPS_SIZE_KEY; -import static com.android.settings.deviceinfo.storage.CachedStorageValuesHelper.DOCUMENTS_AND_OTHER_SIZE_KEY; -import static com.android.settings.deviceinfo.storage.CachedStorageValuesHelper.EXTERNAL_APP_BYTES; -import static com.android.settings.deviceinfo.storage.CachedStorageValuesHelper - .EXTERNAL_AUDIO_BYTES; -import static com.android.settings.deviceinfo.storage.CachedStorageValuesHelper - .EXTERNAL_IMAGE_BYTES; -import static com.android.settings.deviceinfo.storage.CachedStorageValuesHelper - .EXTERNAL_TOTAL_BYTES; -import static com.android.settings.deviceinfo.storage.CachedStorageValuesHelper - .EXTERNAL_VIDEO_BYTES; -import static com.android.settings.deviceinfo.storage.CachedStorageValuesHelper.FREE_BYTES_KEY; -import static com.android.settings.deviceinfo.storage.CachedStorageValuesHelper.GAME_APPS_SIZE_KEY; -import static com.android.settings.deviceinfo.storage.CachedStorageValuesHelper.IMAGES_SIZE_KEY; -import static com.android.settings.deviceinfo.storage.CachedStorageValuesHelper.OTHER_APPS_SIZE_KEY; -import static com.android.settings.deviceinfo.storage.CachedStorageValuesHelper - .SHARED_PREFERENCES_NAME; -import static com.android.settings.deviceinfo.storage.CachedStorageValuesHelper.TIMESTAMP_KEY; -import static com.android.settings.deviceinfo.storage.CachedStorageValuesHelper.TOTAL_BYTES_KEY; -import static com.android.settings.deviceinfo.storage.CachedStorageValuesHelper.TRASH_SIZE_KEY; -import static com.android.settings.deviceinfo.storage.CachedStorageValuesHelper.USER_ID_KEY; -import static com.android.settings.deviceinfo.storage.CachedStorageValuesHelper.VIDEOS_SIZE_KEY; - -import static com.google.common.truth.Truth.assertThat; - -import static org.mockito.Mockito.when; - -import android.content.Context; -import android.content.SharedPreferences; -import android.util.SparseArray; - -import com.android.settingslib.applications.StorageStatsSource; -import com.android.settingslib.deviceinfo.PrivateStorageInfo; - -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; - -@RunWith(RobolectricTestRunner.class) -public class CachedStorageValuesHelperTest { - - private Context mContext; - - @Mock private CachedStorageValuesHelper.Clock mMockClock; - private CachedStorageValuesHelper mCachedValuesHelper; - private SharedPreferences mSharedPreferences; - - @Before - public void setUp() throws Exception { - MockitoAnnotations.initMocks(this); - mContext = RuntimeEnvironment.application; - mSharedPreferences = mContext.getSharedPreferences(SHARED_PREFERENCES_NAME, 0); - mCachedValuesHelper = new CachedStorageValuesHelper(mContext, 0); - mCachedValuesHelper.mClock = mMockClock; - } - - @Test - public void getCachedPrivateStorageInfo_cachedValuesAreLoaded() { - when(mMockClock.getCurrentTime()).thenReturn(10001L); - mSharedPreferences - .edit() - .putLong(GAME_APPS_SIZE_KEY, 0) - .putLong(AUDIO_SIZE_KEY, 10) - .putLong(VIDEOS_SIZE_KEY, 100) - .putLong(IMAGES_SIZE_KEY, 1000) - .putLong(OTHER_APPS_SIZE_KEY, 10000) - .putLong(CACHE_APPS_SIZE_KEY, 100000) - .putLong(EXTERNAL_TOTAL_BYTES, 2) - .putLong(EXTERNAL_AUDIO_BYTES, 22) - .putLong(EXTERNAL_VIDEO_BYTES, 222) - .putLong(EXTERNAL_IMAGE_BYTES, 2222) - .putLong(EXTERNAL_APP_BYTES, 22222) - .putLong(FREE_BYTES_KEY, 1000L) - .putLong(TOTAL_BYTES_KEY, 6000L) - .putInt(USER_ID_KEY, 0) - .putLong(TIMESTAMP_KEY, 10000L) - .apply(); - - final PrivateStorageInfo info = mCachedValuesHelper.getCachedPrivateStorageInfo(); - - assertThat(info.freeBytes).isEqualTo(1000L); - assertThat(info.totalBytes).isEqualTo(6000L); - } - - @Test - public void getCachedStorageResult_cachedValuesAreLoaded() { - when(mMockClock.getCurrentTime()).thenReturn(10001L); - mSharedPreferences - .edit() - .putLong(GAME_APPS_SIZE_KEY, 1) - .putLong(AUDIO_SIZE_KEY, 10) - .putLong(VIDEOS_SIZE_KEY, 100) - .putLong(IMAGES_SIZE_KEY, 1000) - .putLong(DOCUMENTS_AND_OTHER_SIZE_KEY, 1001) - .putLong(TRASH_SIZE_KEY, 1002) - .putLong(OTHER_APPS_SIZE_KEY, 10000) - .putLong(CACHE_APPS_SIZE_KEY, 100000) - .putLong(EXTERNAL_TOTAL_BYTES, 222222) - .putLong(EXTERNAL_AUDIO_BYTES, 22) - .putLong(EXTERNAL_VIDEO_BYTES, 222) - .putLong(EXTERNAL_IMAGE_BYTES, 2222) - .putLong(EXTERNAL_APP_BYTES, 22222) - .putLong(FREE_BYTES_KEY, 1000L) - .putLong(TOTAL_BYTES_KEY, 5000L) - .putInt(USER_ID_KEY, 0) - .putLong(TIMESTAMP_KEY, 10000L) - .apply(); - - final SparseArray result = - mCachedValuesHelper.getCachedStorageResult(); - - StorageAsyncLoader.StorageResult primaryResult = result.get(0); - assertThat(primaryResult.gamesSize).isEqualTo(1L); - assertThat(primaryResult.audioSize).isEqualTo(10L); - assertThat(primaryResult.videosSize).isEqualTo(100L); - assertThat(primaryResult.imagesSize).isEqualTo(1000L); - assertThat(primaryResult.documentsAndOtherSize).isEqualTo(1001L); - assertThat(primaryResult.trashSize).isEqualTo(1002L); - assertThat(primaryResult.allAppsExceptGamesSize).isEqualTo(10000L); - assertThat(primaryResult.cacheSize).isEqualTo(100000L); - assertThat(primaryResult.externalStats.totalBytes).isEqualTo(222222L); - assertThat(primaryResult.externalStats.audioBytes).isEqualTo(22L); - assertThat(primaryResult.externalStats.videoBytes).isEqualTo(222L); - assertThat(primaryResult.externalStats.imageBytes).isEqualTo(2222L); - assertThat(primaryResult.externalStats.appBytes).isEqualTo(22222L); - } - - @Test - public void getCachedPrivateStorageInfo_nullIfDataIsStale() { - when(mMockClock.getCurrentTime()).thenReturn(10000000L); - mSharedPreferences - .edit() - .putLong(GAME_APPS_SIZE_KEY, 0) - .putLong(AUDIO_SIZE_KEY, 10) - .putLong(VIDEOS_SIZE_KEY, 100) - .putLong(IMAGES_SIZE_KEY, 1000) - .putLong(OTHER_APPS_SIZE_KEY, 10000) - .putLong(CACHE_APPS_SIZE_KEY, 100000) - .putLong(EXTERNAL_TOTAL_BYTES, 2) - .putLong(EXTERNAL_AUDIO_BYTES, 22) - .putLong(EXTERNAL_VIDEO_BYTES, 222) - .putLong(EXTERNAL_IMAGE_BYTES, 2222) - .putLong(EXTERNAL_APP_BYTES, 22222) - .putLong(FREE_BYTES_KEY, 1000L) - .putLong(TOTAL_BYTES_KEY, 5000L) - .putInt(USER_ID_KEY, 0) - .putLong(TIMESTAMP_KEY, 10000L) - .apply(); - - final PrivateStorageInfo info = mCachedValuesHelper.getCachedPrivateStorageInfo(); - assertThat(info).isNull(); - } - - @Test - public void getCachedStorageResult_nullIfDataIsStale() { - when(mMockClock.getCurrentTime()).thenReturn(10000000L); - mSharedPreferences - .edit() - .putLong(GAME_APPS_SIZE_KEY, 0) - .putLong(AUDIO_SIZE_KEY, 10) - .putLong(VIDEOS_SIZE_KEY, 100) - .putLong(IMAGES_SIZE_KEY, 1000) - .putLong(OTHER_APPS_SIZE_KEY, 10000) - .putLong(CACHE_APPS_SIZE_KEY, 100000) - .putLong(EXTERNAL_TOTAL_BYTES, 2) - .putLong(EXTERNAL_AUDIO_BYTES, 22) - .putLong(EXTERNAL_VIDEO_BYTES, 222) - .putLong(EXTERNAL_IMAGE_BYTES, 2222) - .putLong(EXTERNAL_APP_BYTES, 22222) - .putLong(FREE_BYTES_KEY, 1000L) - .putLong(TOTAL_BYTES_KEY, 5000L) - .putInt(USER_ID_KEY, 0) - .putLong(TIMESTAMP_KEY, 10000L) - .apply(); - - final SparseArray result = - mCachedValuesHelper.getCachedStorageResult(); - assertThat(result).isNull(); - } - - @Test - public void getCachedPrivateStorageInfo_nullIfWrongUser() { - when(mMockClock.getCurrentTime()).thenReturn(10001L); - mSharedPreferences - .edit() - .putLong(GAME_APPS_SIZE_KEY, 0) - .putLong(AUDIO_SIZE_KEY, 10) - .putLong(VIDEOS_SIZE_KEY, 100) - .putLong(IMAGES_SIZE_KEY, 1000) - .putLong(OTHER_APPS_SIZE_KEY, 10000) - .putLong(CACHE_APPS_SIZE_KEY, 100000) - .putLong(EXTERNAL_TOTAL_BYTES, 2) - .putLong(EXTERNAL_AUDIO_BYTES, 22) - .putLong(EXTERNAL_VIDEO_BYTES, 222) - .putLong(EXTERNAL_IMAGE_BYTES, 2222) - .putLong(EXTERNAL_APP_BYTES, 22222) - .putLong(FREE_BYTES_KEY, 1000L) - .putLong(TOTAL_BYTES_KEY, 5000L) - .putInt(USER_ID_KEY, 1) - .putLong(TIMESTAMP_KEY, 10000L) - .apply(); - - final PrivateStorageInfo info = mCachedValuesHelper.getCachedPrivateStorageInfo(); - assertThat(info).isNull(); - } - - @Test - public void getCachedStorageResult_nullIfWrongUser() { - when(mMockClock.getCurrentTime()).thenReturn(10001L); - mSharedPreferences - .edit() - .putLong(GAME_APPS_SIZE_KEY, 0) - .putLong(AUDIO_SIZE_KEY, 10) - .putLong(VIDEOS_SIZE_KEY, 100) - .putLong(IMAGES_SIZE_KEY, 1000) - .putLong(OTHER_APPS_SIZE_KEY, 10000) - .putLong(CACHE_APPS_SIZE_KEY, 100000) - .putLong(EXTERNAL_TOTAL_BYTES, 2) - .putLong(EXTERNAL_AUDIO_BYTES, 22) - .putLong(EXTERNAL_VIDEO_BYTES, 222) - .putLong(EXTERNAL_IMAGE_BYTES, 2222) - .putLong(EXTERNAL_APP_BYTES, 22222) - .putLong(FREE_BYTES_KEY, 1000L) - .putLong(TOTAL_BYTES_KEY, 5000L) - .putInt(USER_ID_KEY, 1) - .putLong(TIMESTAMP_KEY, 10000L) - .apply(); - - final SparseArray result = - mCachedValuesHelper.getCachedStorageResult(); - assertThat(result).isNull(); - } - - @Test - public void getCachedPrivateStorageInfo_nullIfEmpty() { - final PrivateStorageInfo info = mCachedValuesHelper.getCachedPrivateStorageInfo(); - assertThat(info).isNull(); - } - - @Test - public void getCachedStorageResult_nullIfEmpty() { - final SparseArray result = - mCachedValuesHelper.getCachedStorageResult(); - assertThat(result).isNull(); - } - - @Test - public void cacheResult_succeeds() { - when(mMockClock.getCurrentTime()).thenReturn(10000L); - final StorageStatsSource.ExternalStorageStats externalStats = - new StorageStatsSource.ExternalStorageStats(22222L, 2L, 20L, 200L, 2000L); - final StorageAsyncLoader.StorageResult result = - new StorageAsyncLoader.StorageResult(); - result.gamesSize = 1L; - result.audioSize = 10L; - result.videosSize = 100L; - result.imagesSize = 1000L; - result.allAppsExceptGamesSize = 10000L; - result.cacheSize = 100000L; - result.externalStats = externalStats; - final PrivateStorageInfo info = new PrivateStorageInfo(1000L, 6000L); - - mCachedValuesHelper.cacheResult(info, result); - - assertThat(mSharedPreferences.getLong(GAME_APPS_SIZE_KEY, -1)).isEqualTo(1L); - assertThat(mSharedPreferences.getLong(AUDIO_SIZE_KEY, -1)).isEqualTo(10L); - assertThat(mSharedPreferences.getLong(VIDEOS_SIZE_KEY, -1)).isEqualTo(100L); - assertThat(mSharedPreferences.getLong(IMAGES_SIZE_KEY, -1)).isEqualTo(1000L); - assertThat(mSharedPreferences.getLong(OTHER_APPS_SIZE_KEY, -1)).isEqualTo(10000L); - assertThat(mSharedPreferences.getLong(CACHE_APPS_SIZE_KEY, -1)).isEqualTo(100000L); - assertThat(mSharedPreferences.getLong(EXTERNAL_TOTAL_BYTES, -1)).isEqualTo(22222L); - assertThat(mSharedPreferences.getLong(EXTERNAL_AUDIO_BYTES, -1)).isEqualTo(2L); - assertThat(mSharedPreferences.getLong(EXTERNAL_VIDEO_BYTES, -1)).isEqualTo(20L); - assertThat(mSharedPreferences.getLong(EXTERNAL_IMAGE_BYTES, -1)).isEqualTo(200L); - assertThat(mSharedPreferences.getLong(EXTERNAL_APP_BYTES, -1)).isEqualTo(2000L); - assertThat(mSharedPreferences.getLong(FREE_BYTES_KEY, -1)).isEqualTo(1000L); - assertThat(mSharedPreferences.getLong(TOTAL_BYTES_KEY, -1)).isEqualTo(6000L); - assertThat(mSharedPreferences.getInt(USER_ID_KEY, -1)).isEqualTo(0); - assertThat(mSharedPreferences.getLong(TIMESTAMP_KEY, -1)).isEqualTo(10000L); - } -} diff --git a/tests/robotests/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceControllerTest.java index cfc9e933ab9..3eab600d841 100644 --- a/tests/robotests/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceControllerTest.java @@ -150,12 +150,6 @@ public class StorageItemPreferenceControllerTest { return screen; } - @Test - public void testUpdateStateWithInitialState() { - assertThat(mPreference.getSummary().toString()) - .isEqualTo(mContext.getString(R.string.memory_calculating_size)); - } - @Test public void launchPublicStorageIntent_nonNullBrowseIntent_settingsIntent() { final String fakeBrowseAction = "FAKE_BROWSE_ACTION"; @@ -398,16 +392,17 @@ public class StorageItemPreferenceControllerTest { } @Test - public void setVolume_updateFilePreferenceToHideAfterSettingVolume_hidePreference() { + public void setPrivateStorageCategoryPreferencesVisibility_updateFilePreferenceToHideAfterSettingVolume_hidePreference() { when(mSvp.findEmulatedForPrivate(nullable(VolumeInfo.class))).thenReturn(mVolume); when(mVolume.getType()).thenReturn(VolumeInfo.TYPE_PRIVATE); when(mVolume.getState()).thenReturn(VolumeInfo.STATE_MOUNTED); when(mVolume.isMountedReadable()).thenReturn(true); - mController.displayPreference(mPreferenceScreen); when(mSvp.findEmulatedForPrivate(nullable(VolumeInfo.class))).thenReturn(null); mController.setVolume(mVolume); + mController.setPrivateStorageCategoryPreferencesVisibility(true); + assertThat(mController.mDocumentsAndOtherPreference.isVisible()).isFalse(); } From 1beae1bf91d0b7a238cf3fb5b2aaea070ca6877c Mon Sep 17 00:00:00 2001 From: Arc Wang Date: Fri, 4 Jun 2021 15:17:11 +0800 Subject: [PATCH 6/9] Set storage volume spinner invsible when only 1 volume Bug: 189390166 Test: atest StorageSelectionPreferenceControllerTest Change-Id: I93e5fbf50153580ec60c146959d21e61f556c18c --- .../StorageSelectionPreferenceController.java | 4 +- ...rageSelectionPreferenceControllerTest.java | 45 ++++++++++++++----- 2 files changed, 37 insertions(+), 12 deletions(-) diff --git a/src/com/android/settings/deviceinfo/storage/StorageSelectionPreferenceController.java b/src/com/android/settings/deviceinfo/storage/StorageSelectionPreferenceController.java index 2ab02391d62..5d5a2a58194 100644 --- a/src/com/android/settings/deviceinfo/storage/StorageSelectionPreferenceController.java +++ b/src/com/android/settings/deviceinfo/storage/StorageSelectionPreferenceController.java @@ -75,7 +75,7 @@ public class StorageSelectionPreferenceController extends BasePreferenceControll mStorageAdapter.addAll(storageEntries); if (mSpinnerPreference != null) { - mSpinnerPreference.setClickable(mStorageAdapter.getCount() > 1); + mSpinnerPreference.setVisible(mStorageAdapter.getCount() > 1); } } @@ -97,7 +97,7 @@ public class StorageSelectionPreferenceController extends BasePreferenceControll mSpinnerPreference = screen.findPreference(getPreferenceKey()); mSpinnerPreference.setAdapter(mStorageAdapter); mSpinnerPreference.setOnItemSelectedListener(this); - mSpinnerPreference.setClickable(mStorageAdapter.getCount() > 1); + mSpinnerPreference.setVisible(mStorageAdapter.getCount() > 1); } @Override diff --git a/tests/unit/src/com/android/settings/deviceinfo/storage/StorageSelectionPreferenceControllerTest.java b/tests/unit/src/com/android/settings/deviceinfo/storage/StorageSelectionPreferenceControllerTest.java index 86351cb70b1..f4661ef7646 100644 --- a/tests/unit/src/com/android/settings/deviceinfo/storage/StorageSelectionPreferenceControllerTest.java +++ b/tests/unit/src/com/android/settings/deviceinfo/storage/StorageSelectionPreferenceControllerTest.java @@ -18,6 +18,8 @@ package com.android.settings.deviceinfo.storage; import static com.google.common.truth.Truth.assertThat; +import static org.mockito.Mockito.mock; + import android.content.Context; import android.os.Looper; import android.os.storage.StorageManager; @@ -33,6 +35,7 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; @@ -47,9 +50,20 @@ public class StorageSelectionPreferenceControllerTest { @Before public void setUp() throws Exception { + if (Looper.myLooper() == null) { + Looper.prepare(); + } mContext = ApplicationProvider.getApplicationContext(); mStorageManager = mContext.getSystemService(StorageManager.class); mController = new StorageSelectionPreferenceController(mContext, PREFERENCE_KEY); + + final PreferenceManager preferenceManager = new PreferenceManager(mContext); + final PreferenceScreen preferenceScreen = + preferenceManager.createPreferenceScreen(mContext); + final SettingsSpinnerPreference spinnerPreference = new SettingsSpinnerPreference(mContext); + spinnerPreference.setKey(PREFERENCE_KEY); + preferenceScreen.addPreference(spinnerPreference); + mController.displayPreference(preferenceScreen); } @Test @@ -70,16 +84,6 @@ public class StorageSelectionPreferenceControllerTest { @Test public void setSelectedStorageEntry_primaryStorage_correctSelectedAdapterItem() { - if (Looper.myLooper() == null) { - Looper.prepare(); - } - final PreferenceManager preferenceManager = new PreferenceManager(mContext); - final PreferenceScreen preferenceScreen = - preferenceManager.createPreferenceScreen(mContext); - final SettingsSpinnerPreference spinnerPreference = new SettingsSpinnerPreference(mContext); - spinnerPreference.setKey(PREFERENCE_KEY); - preferenceScreen.addPreference(spinnerPreference); - mController.displayPreference(preferenceScreen); final StorageEntry primaryStorageEntry = StorageEntry.getDefaultInternalStorageEntry(mContext); mController.setStorageEntries(mStorageManager.getVolumes().stream() @@ -91,5 +95,26 @@ public class StorageSelectionPreferenceControllerTest { assertThat((StorageEntry) mController.mSpinnerPreference.getSelectedItem()) .isEqualTo(primaryStorageEntry); } + + @Test + public void setStorageEntries_1StorageEntry_preferenceInvisible() { + final List storageEntries = new ArrayList<>(); + storageEntries.add(mock(StorageEntry.class)); + + mController.setStorageEntries(storageEntries); + + assertThat(mController.mSpinnerPreference.isVisible()).isFalse(); + } + + @Test + public void setStorageEntries_2StorageEntries_preferenceVisible() { + final List storageEntries = new ArrayList<>(); + storageEntries.add(mock(StorageEntry.class)); + storageEntries.add(mock(StorageEntry.class)); + + mController.setStorageEntries(storageEntries); + + assertThat(mController.mSpinnerPreference.isVisible()).isTrue(); + } } From 9312dc83fae9b6bc8715f799586a95a1412908c1 Mon Sep 17 00:00:00 2001 From: Yi-Ling Chuang Date: Thu, 3 Jun 2021 20:32:40 +0800 Subject: [PATCH 7/9] Apply sliding transition to biometric settings Bug: 187542491 Test: rebuild Change-Id: Ife645785a37c4ac838204d0613dffd5a5911a47e --- .../biometrics/BiometricStatusPreferenceController.java | 4 ++++ .../biometrics/combination/BiometricsSettingsBase.java | 4 ++++ .../biometrics/fingerprint/FingerprintEnrollFinish.java | 1 + .../security/ChangeProfileScreenLockPreferenceController.java | 2 ++ .../security/LockUnificationPreferenceController.java | 4 ++++ 5 files changed, 15 insertions(+) diff --git a/src/com/android/settings/biometrics/BiometricStatusPreferenceController.java b/src/com/android/settings/biometrics/BiometricStatusPreferenceController.java index 70f0baf3de5..801dd03bf48 100644 --- a/src/com/android/settings/biometrics/BiometricStatusPreferenceController.java +++ b/src/com/android/settings/biometrics/BiometricStatusPreferenceController.java @@ -30,7 +30,9 @@ import androidx.preference.Preference; import com.android.internal.widget.LockPatternUtils; import com.android.settings.Utils; import com.android.settings.core.BasePreferenceController; +import com.android.settings.core.SettingsBaseActivity; import com.android.settings.overlay.FeatureFactory; +import com.android.settingslib.transition.SettingsTransitionHelper; public abstract class BiometricStatusPreferenceController extends BasePreferenceController { @@ -127,6 +129,8 @@ public abstract class BiometricStatusPreferenceController extends BasePreference } intent.putExtra(Intent.EXTRA_USER_ID, userId); intent.putExtra(EXTRA_FROM_SETTINGS_SUMMARY, true); + intent.putExtra(SettingsBaseActivity.EXTRA_PAGE_TRANSITION_TYPE, + SettingsTransitionHelper.TransitionType.TRANSITION_SLIDE); context.startActivity(intent); return true; } diff --git a/src/com/android/settings/biometrics/combination/BiometricsSettingsBase.java b/src/com/android/settings/biometrics/combination/BiometricsSettingsBase.java index d8197c02abb..68473674220 100644 --- a/src/com/android/settings/biometrics/combination/BiometricsSettingsBase.java +++ b/src/com/android/settings/biometrics/combination/BiometricsSettingsBase.java @@ -34,9 +34,11 @@ import com.android.settings.R; import com.android.settings.Utils; import com.android.settings.biometrics.BiometricEnrollBase; import com.android.settings.biometrics.BiometricUtils; +import com.android.settings.core.SettingsBaseActivity; import com.android.settings.dashboard.DashboardFragment; import com.android.settings.password.ChooseLockGeneric; import com.android.settings.password.ChooseLockSettingsHelper; +import com.android.settingslib.transition.SettingsTransitionHelper; /** * Base fragment with the confirming credential functionality for combined biometrics settings. @@ -203,6 +205,8 @@ public abstract class BiometricsSettingsBase extends DashboardFragment { true); intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_REQUEST_GK_PW_HANDLE, true); intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_FOR_BIOMETRICS, true); + intent.putExtra(SettingsBaseActivity.EXTRA_PAGE_TRANSITION_TYPE, + SettingsTransitionHelper.TransitionType.TRANSITION_SLIDE); if (mUserId != UserHandle.USER_NULL) { intent.putExtra(Intent.EXTRA_USER_ID, mUserId); diff --git a/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollFinish.java b/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollFinish.java index a989eef93f7..80a6f0555e2 100644 --- a/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollFinish.java +++ b/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollFinish.java @@ -153,6 +153,7 @@ public class FingerprintEnrollFinish extends BiometricEnrollBase { intent.putExtra(Intent.EXTRA_USER_ID, mUserId); intent.putExtra(BiometricEnrollBase.EXTRA_KEY_CHALLENGE, mChallenge); startActivity(intent); + overridePendingTransition(R.anim.sud_slide_back_in, R.anim.sud_slide_back_out); } private void onAddAnotherButtonClick(View view) { diff --git a/src/com/android/settings/security/ChangeProfileScreenLockPreferenceController.java b/src/com/android/settings/security/ChangeProfileScreenLockPreferenceController.java index 54b78be65fa..8e1a4f8dd8f 100644 --- a/src/com/android/settings/security/ChangeProfileScreenLockPreferenceController.java +++ b/src/com/android/settings/security/ChangeProfileScreenLockPreferenceController.java @@ -30,6 +30,7 @@ import com.android.settings.SettingsPreferenceFragment; import com.android.settings.Utils; import com.android.settings.core.SubSettingLauncher; import com.android.settings.password.ChooseLockGeneric; +import com.android.settingslib.transition.SettingsTransitionHelper; public class ChangeProfileScreenLockPreferenceController extends ChangeScreenLockPreferenceController { @@ -81,6 +82,7 @@ public class ChangeProfileScreenLockPreferenceController extends .setDestination(ChooseLockGeneric.ChooseLockGenericFragment.class.getName()) .setSourceMetricsCategory(mHost.getMetricsCategory()) .setArguments(extras) + .setTransitionType(SettingsTransitionHelper.TransitionType.TRANSITION_SLIDE) .launch(); return true; diff --git a/src/com/android/settings/security/LockUnificationPreferenceController.java b/src/com/android/settings/security/LockUnificationPreferenceController.java index 98a3c6ff3de..b6e215c8bf7 100644 --- a/src/com/android/settings/security/LockUnificationPreferenceController.java +++ b/src/com/android/settings/security/LockUnificationPreferenceController.java @@ -26,6 +26,7 @@ import android.content.Intent; import android.os.Bundle; import android.os.UserHandle; import android.os.UserManager; +import android.util.Log; import androidx.preference.Preference; import androidx.preference.PreferenceScreen; @@ -43,6 +44,7 @@ import com.android.settings.password.ChooseLockSettingsHelper; import com.android.settingslib.RestrictedLockUtilsInternal; import com.android.settingslib.RestrictedSwitchPreference; import com.android.settingslib.core.AbstractPreferenceController; +import com.android.settingslib.transition.SettingsTransitionHelper; /** * Controller for password unification/un-unification flows. @@ -173,6 +175,7 @@ public class LockUnificationPreferenceController extends AbstractPreferenceContr .setDestination(ChooseLockGeneric.ChooseLockGenericFragment.class.getName()) .setSourceMetricsCategory(mHost.getMetricsCategory()) .setArguments(extras) + .setTransitionType(SettingsTransitionHelper.TransitionType.TRANSITION_SLIDE) .launch(); } @@ -229,6 +232,7 @@ public class LockUnificationPreferenceController extends AbstractPreferenceContr .setTitleRes(R.string.lock_settings_picker_title) .setSourceMetricsCategory(mHost.getMetricsCategory()) .setArguments(extras) + .setTransitionType(SettingsTransitionHelper.TransitionType.TRANSITION_SLIDE) .launch(); } From 481b3abe0d9b645013d1a03645c4d651b71f15e4 Mon Sep 17 00:00:00 2001 From: Stanley Wang Date: Fri, 4 Jun 2021 16:15:04 +0800 Subject: [PATCH 8/9] Fix NPE in SettingsMainSwitchPreference. - Check if the RestrictedPreferenceHelper is null to avoid NPE. Fix: 190135868 Test: run robotest and manually test that page. Change-Id: I746099260d8f53dc30513ccbb30aec5cbe3657e7 --- .../android/settings/widget/SettingsMainSwitchPreference.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/com/android/settings/widget/SettingsMainSwitchPreference.java b/src/com/android/settings/widget/SettingsMainSwitchPreference.java index 7f349bc6846..de7d6926d03 100644 --- a/src/com/android/settings/widget/SettingsMainSwitchPreference.java +++ b/src/com/android/settings/widget/SettingsMainSwitchPreference.java @@ -84,7 +84,9 @@ public class SettingsMainSwitchPreference extends TwoStatePreference implements mMainSwitchBar = (SettingsMainSwitchBar) holder.findViewById(R.id.main_switch_bar); mMainSwitchBar.show(); - mEnforcedAdmin = mRestrictedHelper.checkRestrictionEnforced(); + if (mRestrictedHelper != null) { + mEnforcedAdmin = mRestrictedHelper.checkRestrictionEnforced(); + } updateStatus(isChecked()); registerListenerToSwitchBar(); From 5028e6e6a69e20eff9fa096c0a772e2f9ec68493 Mon Sep 17 00:00:00 2001 From: Chloris Kuo Date: Thu, 3 Jun 2021 15:26:50 -0700 Subject: [PATCH 9/9] Fix NotificationAssistantPreferenceController constructor Fix flaky test due to the constructor must either only take Context, or (Context, String). Bug: 187998873 Test: CodeInspectionTest, NotificationAssistantPreferenceControllerTest Change-Id: Ie383ea6773afda05adfb7aa9d7de9e27676f6b29 --- res/xml/configure_notification_settings.xml | 3 ++- .../ConfigureNotificationSettings.java | 19 ++++++++++++------- ...ficationAssistantPreferenceController.java | 18 +++++++++++++----- ...tionAssistantPreferenceControllerTest.java | 5 +++-- 4 files changed, 30 insertions(+), 15 deletions(-) diff --git a/res/xml/configure_notification_settings.xml b/res/xml/configure_notification_settings.xml index dad5e0e5453..cce790ba8a3 100644 --- a/res/xml/configure_notification_settings.xml +++ b/res/xml/configure_notification_settings.xml @@ -159,6 +159,7 @@ android:key="notification_assistant" android:order="23" android:title="@string/notification_assistant_title" - android:summary="@string/notification_assistant_summary"/> + android:summary="@string/notification_assistant_summary" + settings:controller="com.android.settings.notification.NotificationAssistantPreferenceController"/> diff --git a/src/com/android/settings/notification/ConfigureNotificationSettings.java b/src/com/android/settings/notification/ConfigureNotificationSettings.java index a41fab60f4f..644d5cbc53d 100644 --- a/src/com/android/settings/notification/ConfigureNotificationSettings.java +++ b/src/com/android/settings/notification/ConfigureNotificationSettings.java @@ -19,14 +19,11 @@ package com.android.settings.notification; import android.app.Activity; import android.app.Application; import android.app.settings.SettingsEnums; -import android.app.usage.IUsageStatsManager; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.os.Bundle; -import android.os.ServiceManager; import android.os.UserHandle; -import android.os.UserManager; import androidx.annotation.VisibleForTesting; import androidx.fragment.app.Fragment; @@ -57,10 +54,11 @@ public class ConfigureNotificationSettings extends DashboardFragment implements private static final int REQUEST_CODE = 200; private static final String SELECTED_PREFERENCE_KEY = "selected_preference"; private static final String KEY_ADVANCED_CATEGORY = "configure_notifications_advanced"; - private static final String KEY_NAS = "notification_assistant"; private RingtonePreference mRequestPreference; + private NotificationAssistantPreferenceController mNotificationAssistantPreferenceController; + @Override public int getMetricsCategory() { return SettingsEnums.CONFIGURE_NOTIFICATION; @@ -88,6 +86,16 @@ public class ConfigureNotificationSettings extends DashboardFragment implements return buildPreferenceControllers(context, app, this); } + @Override + public void onAttach(Context context) { + super.onAttach(context); + + mNotificationAssistantPreferenceController = + use(NotificationAssistantPreferenceController.class); + mNotificationAssistantPreferenceController.setFragment(this); + mNotificationAssistantPreferenceController.setBackend(new NotificationBackend()); + } + @Override protected boolean isParalleledControllers() { return true; @@ -105,9 +113,6 @@ public class ConfigureNotificationSettings extends DashboardFragment implements } }); - controllers.add(new NotificationAssistantPreferenceController(context, - new NotificationBackend(), host, KEY_NAS)); - controllers.add(new EmergencyBroadcastPreferenceController(context, "app_and_notif_cell_broadcast_settings")); diff --git a/src/com/android/settings/notification/NotificationAssistantPreferenceController.java b/src/com/android/settings/notification/NotificationAssistantPreferenceController.java index a46f1646113..bdbc478e740 100644 --- a/src/com/android/settings/notification/NotificationAssistantPreferenceController.java +++ b/src/com/android/settings/notification/NotificationAssistantPreferenceController.java @@ -30,6 +30,8 @@ import com.google.common.annotations.VisibleForTesting; public class NotificationAssistantPreferenceController extends TogglePreferenceController { private static final String TAG = "NASPreferenceController"; + private static final String KEY_NAS = "notification_assistant"; + private static final int AVAILABLE = 1; private final UserManager mUserManager; private Fragment mFragment; @@ -38,11 +40,8 @@ public class NotificationAssistantPreferenceController extends TogglePreferenceC @VisibleForTesting protected NotificationBackend mNotificationBackend; - public NotificationAssistantPreferenceController(Context context, NotificationBackend backend, - Fragment fragment, String preferenceKey) { - super(context, preferenceKey); - mNotificationBackend = backend; - mFragment = fragment; + public NotificationAssistantPreferenceController(Context context) { + super(context, KEY_NAS); mUserManager = UserManager.get(context); } @@ -87,4 +86,13 @@ public class NotificationAssistantPreferenceController extends TogglePreferenceC NotificationAssistantDialogFragment.newInstance(mFragment, cn); dialogFragment.show(mFragment.getFragmentManager(), TAG); } + + public void setFragment(Fragment fragment) { + mFragment = fragment; + } + + @VisibleForTesting + void setBackend(NotificationBackend backend) { + mNotificationBackend = backend; + } } \ No newline at end of file diff --git a/tests/robotests/src/com/android/settings/notification/NotificationAssistantPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/NotificationAssistantPreferenceControllerTest.java index fe36615c569..d1307114e65 100644 --- a/tests/robotests/src/com/android/settings/notification/NotificationAssistantPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/notification/NotificationAssistantPreferenceControllerTest.java @@ -79,8 +79,9 @@ public class NotificationAssistantPreferenceControllerTest { when(mFragment.getFragmentManager()).thenReturn(mFragmentManager); when(mFragmentManager.beginTransaction()).thenReturn(mFragmentTransaction); when(mBackend.getDefaultNotificationAssistant()).thenReturn(mNASComponent); - mPreferenceController = new NotificationAssistantPreferenceController(mContext, - mBackend, mFragment, KEY); + mPreferenceController = new NotificationAssistantPreferenceController(mContext); + mPreferenceController.setBackend(mBackend); + mPreferenceController.setFragment(mFragment); when(mUserManager.getProfileIds(eq(0), anyBoolean())).thenReturn(new int[] {0, 10}); when(mUserManager.getProfileIds(eq(20), anyBoolean())).thenReturn(new int[] {20}); }