Merge "Cache storage values for fast loading." into oc-mr1-dev
am: 7fae6c67fb
Change-Id: I5e29852872dd08e0e5bb3f1822127879dc354319
This commit is contained in:
@@ -40,6 +40,7 @@ import com.android.settings.applications.UserManagerWrapper;
|
|||||||
import com.android.settings.applications.UserManagerWrapperImpl;
|
import com.android.settings.applications.UserManagerWrapperImpl;
|
||||||
import com.android.settings.dashboard.DashboardFragment;
|
import com.android.settings.dashboard.DashboardFragment;
|
||||||
import com.android.settings.deviceinfo.storage.AutomaticStorageManagementSwitchPreferenceController;
|
import com.android.settings.deviceinfo.storage.AutomaticStorageManagementSwitchPreferenceController;
|
||||||
|
import com.android.settings.deviceinfo.storage.CachedStorageValuesHelper;
|
||||||
import com.android.settings.deviceinfo.storage.SecondaryUserController;
|
import com.android.settings.deviceinfo.storage.SecondaryUserController;
|
||||||
import com.android.settings.deviceinfo.storage.StorageAsyncLoader;
|
import com.android.settings.deviceinfo.storage.StorageAsyncLoader;
|
||||||
import com.android.settings.deviceinfo.storage.StorageItemPreferenceController;
|
import com.android.settings.deviceinfo.storage.StorageItemPreferenceController;
|
||||||
@@ -68,6 +69,7 @@ public class StorageDashboardFragment extends DashboardFragment
|
|||||||
private VolumeInfo mVolume;
|
private VolumeInfo mVolume;
|
||||||
private PrivateStorageInfo mStorageInfo;
|
private PrivateStorageInfo mStorageInfo;
|
||||||
private SparseArray<StorageAsyncLoader.AppsStorageResult> mAppsResult;
|
private SparseArray<StorageAsyncLoader.AppsStorageResult> mAppsResult;
|
||||||
|
private CachedStorageValuesHelper mCachedStorageValuesHelper;
|
||||||
|
|
||||||
private StorageSummaryDonutPreferenceController mSummaryController;
|
private StorageSummaryDonutPreferenceController mSummaryController;
|
||||||
private StorageItemPreferenceController mPreferenceController;
|
private StorageItemPreferenceController mPreferenceController;
|
||||||
@@ -102,7 +104,10 @@ public class StorageDashboardFragment extends DashboardFragment
|
|||||||
@Override
|
@Override
|
||||||
public void onViewCreated(View v, Bundle savedInstanceState) {
|
public void onViewCreated(View v, Bundle savedInstanceState) {
|
||||||
super.onViewCreated(v, savedInstanceState);
|
super.onViewCreated(v, savedInstanceState);
|
||||||
setLoading(true, false);
|
initializeCacheProvider();
|
||||||
|
if (mAppsResult == null || mStorageInfo == null) {
|
||||||
|
setLoading(true, false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -249,6 +254,7 @@ public class StorageDashboardFragment extends DashboardFragment
|
|||||||
public void onLoadFinished(Loader<SparseArray<StorageAsyncLoader.AppsStorageResult>> loader,
|
public void onLoadFinished(Loader<SparseArray<StorageAsyncLoader.AppsStorageResult>> loader,
|
||||||
SparseArray<StorageAsyncLoader.AppsStorageResult> data) {
|
SparseArray<StorageAsyncLoader.AppsStorageResult> data) {
|
||||||
mAppsResult = data;
|
mAppsResult = data;
|
||||||
|
maybeCacheFreshValues();
|
||||||
onReceivedSizes();
|
onReceivedSizes();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -256,6 +262,48 @@ public class StorageDashboardFragment extends DashboardFragment
|
|||||||
public void onLoaderReset(Loader<SparseArray<StorageAsyncLoader.AppsStorageResult>> loader) {
|
public void onLoaderReset(Loader<SparseArray<StorageAsyncLoader.AppsStorageResult>> loader) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
public void setCachedStorageValuesHelper(CachedStorageValuesHelper helper) {
|
||||||
|
mCachedStorageValuesHelper = helper;
|
||||||
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
public PrivateStorageInfo getPrivateStorageInfo() {
|
||||||
|
return mStorageInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
public SparseArray<StorageAsyncLoader.AppsStorageResult> getAppsStorageResult() {
|
||||||
|
return mAppsResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
public void initializeCachedValues() {
|
||||||
|
PrivateStorageInfo info = mCachedStorageValuesHelper.getCachedPrivateStorageInfo();
|
||||||
|
SparseArray<StorageAsyncLoader.AppsStorageResult> loaderResult =
|
||||||
|
mCachedStorageValuesHelper.getCachedAppsStorageResult();
|
||||||
|
if (info == null || loaderResult == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mStorageInfo = info;
|
||||||
|
mAppsResult = loaderResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initializeCacheProvider() {
|
||||||
|
mCachedStorageValuesHelper =
|
||||||
|
new CachedStorageValuesHelper(getContext(), UserHandle.myUserId());
|
||||||
|
initializeCachedValues();
|
||||||
|
onReceivedSizes();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void maybeCacheFreshValues() {
|
||||||
|
if (mStorageInfo != null && mAppsResult != null) {
|
||||||
|
mCachedStorageValuesHelper.cacheResult(
|
||||||
|
mStorageInfo, mAppsResult.get(UserHandle.myUserId()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* IconLoaderCallbacks exists because StorageDashboardFragment already implements
|
* IconLoaderCallbacks exists because StorageDashboardFragment already implements
|
||||||
* LoaderCallbacks for a different type.
|
* LoaderCallbacks for a different type.
|
||||||
@@ -308,6 +356,7 @@ public class StorageDashboardFragment extends DashboardFragment
|
|||||||
}
|
}
|
||||||
|
|
||||||
mStorageInfo = privateStorageInfo;
|
mStorageInfo = privateStorageInfo;
|
||||||
|
maybeCacheFreshValues();
|
||||||
onReceivedSizes();
|
onReceivedSizes();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,172 @@
|
|||||||
|
/*
|
||||||
|
* 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.support.annotation.VisibleForTesting;
|
||||||
|
import android.util.SparseArray;
|
||||||
|
|
||||||
|
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 MUSIC_APPS_SIZE_KEY = "music_apps_size";
|
||||||
|
public static final String VIDEO_APPS_SIZE_KEY = "video_apps_size";
|
||||||
|
public static final String PHOTO_APPS_SIZE_KEY = "photo_apps_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);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SparseArray<StorageAsyncLoader.AppsStorageResult> getCachedAppsStorageResult() {
|
||||||
|
if (!isDataValid()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
final long gamesSize = mSharedPreferences.getLong(GAME_APPS_SIZE_KEY, -1);
|
||||||
|
final long musicAppsSize = mSharedPreferences.getLong(MUSIC_APPS_SIZE_KEY, -1);
|
||||||
|
final long videoAppsSize = mSharedPreferences.getLong(VIDEO_APPS_SIZE_KEY, -1);
|
||||||
|
final long photoAppSize = mSharedPreferences.getLong(PHOTO_APPS_SIZE_KEY, -1);
|
||||||
|
final long otherAppsSize = mSharedPreferences.getLong(OTHER_APPS_SIZE_KEY, -1);
|
||||||
|
final long cacheSize = mSharedPreferences.getLong(CACHE_APPS_SIZE_KEY, -1);
|
||||||
|
if (gamesSize < 0
|
||||||
|
|| musicAppsSize < 0
|
||||||
|
|| videoAppsSize < 0
|
||||||
|
|| photoAppSize < 0
|
||||||
|
|| otherAppsSize < 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.AppsStorageResult result =
|
||||||
|
new StorageAsyncLoader.AppsStorageResult();
|
||||||
|
result.gamesSize = gamesSize;
|
||||||
|
result.musicAppsSize = musicAppsSize;
|
||||||
|
result.videoAppsSize = videoAppsSize;
|
||||||
|
result.photosAppsSize = photoAppSize;
|
||||||
|
result.otherAppsSize = otherAppsSize;
|
||||||
|
result.cacheSize = cacheSize;
|
||||||
|
result.externalStats = externalStats;
|
||||||
|
final SparseArray<StorageAsyncLoader.AppsStorageResult> resultArray = new SparseArray<>();
|
||||||
|
resultArray.append(mUserId, result);
|
||||||
|
return resultArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void cacheResult(
|
||||||
|
PrivateStorageInfo storageInfo, StorageAsyncLoader.AppsStorageResult result) {
|
||||||
|
mSharedPreferences
|
||||||
|
.edit()
|
||||||
|
.putLong(FREE_BYTES_KEY, storageInfo.freeBytes)
|
||||||
|
.putLong(TOTAL_BYTES_KEY, storageInfo.totalBytes)
|
||||||
|
.putLong(GAME_APPS_SIZE_KEY, result.gamesSize)
|
||||||
|
.putLong(MUSIC_APPS_SIZE_KEY, result.musicAppsSize)
|
||||||
|
.putLong(VIDEO_APPS_SIZE_KEY, result.videoAppsSize)
|
||||||
|
.putLong(PHOTO_APPS_SIZE_KEY, result.photosAppsSize)
|
||||||
|
.putLong(OTHER_APPS_SIZE_KEY, result.otherAppsSize)
|
||||||
|
.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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -20,13 +20,18 @@ import static com.google.common.truth.Truth.assertThat;
|
|||||||
|
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.os.storage.StorageManager;
|
import android.os.storage.StorageManager;
|
||||||
import android.provider.SearchIndexableResource;
|
import android.provider.SearchIndexableResource;
|
||||||
|
import android.util.SparseArray;
|
||||||
|
|
||||||
|
import com.android.settings.deviceinfo.storage.CachedStorageValuesHelper;
|
||||||
|
import com.android.settings.deviceinfo.storage.StorageAsyncLoader;
|
||||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||||
import com.android.settings.TestConfig;
|
import com.android.settings.TestConfig;
|
||||||
|
import com.android.settingslib.deviceinfo.PrivateStorageInfo;
|
||||||
import com.android.settingslib.drawer.CategoryKey;
|
import com.android.settingslib.drawer.CategoryKey;
|
||||||
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
@@ -68,6 +73,47 @@ public class StorageDashboardFragmentTest {
|
|||||||
verify(activity).invalidateOptionsMenu();
|
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.AppsStorageResult> result = new SparseArray<>();
|
||||||
|
when(helper.getCachedAppsStorageResult()).thenReturn(result);
|
||||||
|
|
||||||
|
mFragment.setCachedStorageValuesHelper(helper);
|
||||||
|
mFragment.initializeCachedValues();
|
||||||
|
|
||||||
|
assertThat(mFragment.getPrivateStorageInfo()).isEqualTo(info);
|
||||||
|
assertThat(mFragment.getAppsStorageResult()).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.getAppsStorageResult()).isNull();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test_cacheProviderDoesntProvideValuesIfVolumeInfoMissing() {
|
||||||
|
CachedStorageValuesHelper helper = mock(CachedStorageValuesHelper.class);
|
||||||
|
SparseArray<StorageAsyncLoader.AppsStorageResult> result = new SparseArray<>();
|
||||||
|
when(helper.getCachedAppsStorageResult()).thenReturn(result);
|
||||||
|
|
||||||
|
mFragment.setCachedStorageValuesHelper(helper);
|
||||||
|
mFragment.initializeCachedValues();
|
||||||
|
|
||||||
|
assertThat(mFragment.getPrivateStorageInfo()).isNull();
|
||||||
|
assertThat(mFragment.getAppsStorageResult()).isNull();
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSearchIndexProvider_shouldIndexResource() {
|
public void testSearchIndexProvider_shouldIndexResource() {
|
||||||
final List<SearchIndexableResource> indexRes =
|
final List<SearchIndexableResource> indexRes =
|
||||||
|
@@ -0,0 +1,295 @@
|
|||||||
|
/*
|
||||||
|
* 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.CACHE_APPS_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.MUSIC_APPS_SIZE_KEY;
|
||||||
|
import static com.android.settings.deviceinfo.storage.CachedStorageValuesHelper.OTHER_APPS_SIZE_KEY;
|
||||||
|
import static com.android.settings.deviceinfo.storage.CachedStorageValuesHelper.PHOTO_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.USER_ID_KEY;
|
||||||
|
import static com.android.settings.deviceinfo.storage.CachedStorageValuesHelper.VIDEO_APPS_SIZE_KEY;
|
||||||
|
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.SharedPreferences;
|
||||||
|
import android.util.SparseArray;
|
||||||
|
|
||||||
|
import com.android.settings.TestConfig;
|
||||||
|
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||||
|
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.RuntimeEnvironment;
|
||||||
|
import org.robolectric.annotation.Config;
|
||||||
|
|
||||||
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
|
|
||||||
|
@RunWith(SettingsRobolectricTestRunner.class)
|
||||||
|
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
|
||||||
|
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.getApplicationContext();
|
||||||
|
mSharedPreferences = mContext.getSharedPreferences(SHARED_PREFERENCES_NAME, 0);
|
||||||
|
mCachedValuesHelper = new CachedStorageValuesHelper(mContext, 0);
|
||||||
|
mCachedValuesHelper.mClock = mMockClock;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getCachedPrivateStorageInfo_cachedValuesAreLoaded() throws Exception {
|
||||||
|
when(mMockClock.getCurrentTime()).thenReturn(10001L);
|
||||||
|
mSharedPreferences
|
||||||
|
.edit()
|
||||||
|
.putLong(GAME_APPS_SIZE_KEY, 0)
|
||||||
|
.putLong(MUSIC_APPS_SIZE_KEY, 10)
|
||||||
|
.putLong(VIDEO_APPS_SIZE_KEY, 100)
|
||||||
|
.putLong(PHOTO_APPS_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();
|
||||||
|
|
||||||
|
PrivateStorageInfo info = mCachedValuesHelper.getCachedPrivateStorageInfo();
|
||||||
|
|
||||||
|
assertThat(info.freeBytes).isEqualTo(1000L);
|
||||||
|
assertThat(info.totalBytes).isEqualTo(6000L);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getCachedAppsStorageResult_cachedValuesAreLoaded() throws Exception {
|
||||||
|
when(mMockClock.getCurrentTime()).thenReturn(10001L);
|
||||||
|
mSharedPreferences
|
||||||
|
.edit()
|
||||||
|
.putLong(GAME_APPS_SIZE_KEY, 1)
|
||||||
|
.putLong(MUSIC_APPS_SIZE_KEY, 10)
|
||||||
|
.putLong(VIDEO_APPS_SIZE_KEY, 100)
|
||||||
|
.putLong(PHOTO_APPS_SIZE_KEY, 1000)
|
||||||
|
.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();
|
||||||
|
|
||||||
|
SparseArray<StorageAsyncLoader.AppsStorageResult> result =
|
||||||
|
mCachedValuesHelper.getCachedAppsStorageResult();
|
||||||
|
|
||||||
|
StorageAsyncLoader.AppsStorageResult primaryResult = result.get(0);
|
||||||
|
assertThat(primaryResult.gamesSize).isEqualTo(1L);
|
||||||
|
assertThat(primaryResult.musicAppsSize).isEqualTo(10L);
|
||||||
|
assertThat(primaryResult.videoAppsSize).isEqualTo(100L);
|
||||||
|
assertThat(primaryResult.photosAppsSize).isEqualTo(1000L);
|
||||||
|
assertThat(primaryResult.otherAppsSize).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() throws Exception {
|
||||||
|
when(mMockClock.getCurrentTime()).thenReturn(10000000L);
|
||||||
|
mSharedPreferences
|
||||||
|
.edit()
|
||||||
|
.putLong(GAME_APPS_SIZE_KEY, 0)
|
||||||
|
.putLong(MUSIC_APPS_SIZE_KEY, 10)
|
||||||
|
.putLong(VIDEO_APPS_SIZE_KEY, 100)
|
||||||
|
.putLong(PHOTO_APPS_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();
|
||||||
|
|
||||||
|
PrivateStorageInfo info = mCachedValuesHelper.getCachedPrivateStorageInfo();
|
||||||
|
assertThat(info).isNull();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getCachedAppsStorageResult_nullIfDataIsStale() throws Exception {
|
||||||
|
when(mMockClock.getCurrentTime()).thenReturn(10000000L);
|
||||||
|
mSharedPreferences
|
||||||
|
.edit()
|
||||||
|
.putLong(GAME_APPS_SIZE_KEY, 0)
|
||||||
|
.putLong(MUSIC_APPS_SIZE_KEY, 10)
|
||||||
|
.putLong(VIDEO_APPS_SIZE_KEY, 100)
|
||||||
|
.putLong(PHOTO_APPS_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();
|
||||||
|
|
||||||
|
SparseArray<StorageAsyncLoader.AppsStorageResult> result =
|
||||||
|
mCachedValuesHelper.getCachedAppsStorageResult();
|
||||||
|
assertThat(result).isNull();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getCachedPrivateStorageInfo_nullIfWrongUser() throws Exception {
|
||||||
|
when(mMockClock.getCurrentTime()).thenReturn(10001L);
|
||||||
|
mSharedPreferences
|
||||||
|
.edit()
|
||||||
|
.putLong(GAME_APPS_SIZE_KEY, 0)
|
||||||
|
.putLong(MUSIC_APPS_SIZE_KEY, 10)
|
||||||
|
.putLong(VIDEO_APPS_SIZE_KEY, 100)
|
||||||
|
.putLong(PHOTO_APPS_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();
|
||||||
|
|
||||||
|
PrivateStorageInfo info = mCachedValuesHelper.getCachedPrivateStorageInfo();
|
||||||
|
assertThat(info).isNull();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getCachedAppsStorageResult_nullIfWrongUser() throws Exception {
|
||||||
|
when(mMockClock.getCurrentTime()).thenReturn(10001L);
|
||||||
|
mSharedPreferences
|
||||||
|
.edit()
|
||||||
|
.putLong(GAME_APPS_SIZE_KEY, 0)
|
||||||
|
.putLong(MUSIC_APPS_SIZE_KEY, 10)
|
||||||
|
.putLong(VIDEO_APPS_SIZE_KEY, 100)
|
||||||
|
.putLong(PHOTO_APPS_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();
|
||||||
|
|
||||||
|
SparseArray<StorageAsyncLoader.AppsStorageResult> result =
|
||||||
|
mCachedValuesHelper.getCachedAppsStorageResult();
|
||||||
|
assertThat(result).isNull();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getCachedPrivateStorageInfo_nullIfEmpty() throws Exception {
|
||||||
|
PrivateStorageInfo info = mCachedValuesHelper.getCachedPrivateStorageInfo();
|
||||||
|
assertThat(info).isNull();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getCachedAppsStorageResult_nullIfEmpty() throws Exception {
|
||||||
|
SparseArray<StorageAsyncLoader.AppsStorageResult> result =
|
||||||
|
mCachedValuesHelper.getCachedAppsStorageResult();
|
||||||
|
assertThat(result).isNull();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void cacheResult_succeeds() throws Exception {
|
||||||
|
when(mMockClock.getCurrentTime()).thenReturn(10000L);
|
||||||
|
final StorageStatsSource.ExternalStorageStats externalStats =
|
||||||
|
new StorageStatsSource.ExternalStorageStats(22222l, 2l, 20L, 200L, 2000L);
|
||||||
|
final StorageAsyncLoader.AppsStorageResult result =
|
||||||
|
new StorageAsyncLoader.AppsStorageResult();
|
||||||
|
result.gamesSize = 1L;
|
||||||
|
result.musicAppsSize = 10l;
|
||||||
|
result.videoAppsSize = 100L;
|
||||||
|
result.photosAppsSize = 1000L;
|
||||||
|
result.otherAppsSize = 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(MUSIC_APPS_SIZE_KEY, -1)).isEqualTo(10L);
|
||||||
|
assertThat(mSharedPreferences.getLong(VIDEO_APPS_SIZE_KEY, -1)).isEqualTo(100L);
|
||||||
|
assertThat(mSharedPreferences.getLong(PHOTO_APPS_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);
|
||||||
|
};
|
||||||
|
}
|
Reference in New Issue
Block a user