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
This commit is contained in:
Arc Wang
2021-05-31 11:50:22 +08:00
parent 3940e5293c
commit 51b3e7a093
11 changed files with 95 additions and 649 deletions

View File

@@ -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<StorageAsyncLoader.StorageResult> 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<StorageAsyncLoader.StorageResult> 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);

View File

@@ -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);

View File

@@ -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<StorageAsyncLoader.StorageResult> 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<StorageAsyncLoader.StorageResult> 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<StorageAsyncLoader.StorageResult> 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<StorageAsyncLoader.StorageResult> 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);
}
}

View File

@@ -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();
}