2 * Copyright (C) 2016 The Android Open Source Project
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License
16 package com.android.settings.deviceinfo.storage;
19 import static com.android.settings.utils.FileSizeFormatter.MEGABYTE_IN_BYTES;
21 import static com.google.common.truth.Truth.assertThat;
23 import static org.mockito.ArgumentMatchers.nullable;
24 import static org.mockito.Matchers.any;
25 import static org.mockito.Matchers.eq;
26 import static org.mockito.Mockito.mock;
27 import static org.mockito.Mockito.spy;
28 import static org.mockito.Mockito.times;
29 import static org.mockito.Mockito.verify;
30 import static org.mockito.Mockito.when;
32 import android.app.Fragment;
33 import android.content.Context;
34 import android.content.Intent;
35 import android.graphics.drawable.Drawable;
36 import android.os.UserHandle;
37 import android.os.storage.VolumeInfo;
38 import android.support.v7.preference.PreferenceScreen;
39 import android.util.SparseArray;
40 import android.view.LayoutInflater;
41 import android.view.View;
42 import android.widget.LinearLayout;
44 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
45 import com.android.settings.R;
46 import com.android.settings.SettingsActivity;
47 import com.android.settings.testutils.SettingsRobolectricTestRunner;
48 import com.android.settings.SubSettings;
49 import com.android.settings.TestConfig;
50 import com.android.settings.applications.ManageApplications;
51 import com.android.settings.core.instrumentation.MetricsFeatureProvider;
52 import com.android.settings.deviceinfo.PrivateVolumeSettings;
53 import com.android.settings.deviceinfo.StorageItemPreference;
54 import com.android.settings.testutils.FakeFeatureFactory;
55 import com.android.settings.testutils.shadow.SettingsShadowResources;
56 import com.android.settingslib.applications.StorageStatsSource;
57 import com.android.settingslib.deviceinfo.StorageVolumeProvider;
59 import org.junit.After;
60 import org.junit.Before;
61 import org.junit.Test;
62 import org.junit.runner.RunWith;
63 import org.mockito.Answers;
64 import org.mockito.ArgumentCaptor;
65 import org.mockito.Mock;
66 import org.mockito.MockitoAnnotations;
67 import org.robolectric.RuntimeEnvironment;
68 import org.robolectric.annotation.Config;
70 @RunWith(SettingsRobolectricTestRunner.class)
71 @Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
72 public class StorageItemPreferenceControllerTest {
73 private Context mContext;
74 private VolumeInfo mVolume;
75 @Mock(answer = Answers.RETURNS_DEEP_STUBS)
76 private Fragment mFragment;
78 private StorageVolumeProvider mSvp;
79 private StorageItemPreferenceController mController;
80 private StorageItemPreference mPreference;
81 private FakeFeatureFactory mFakeFeatureFactory;
82 private MetricsFeatureProvider mMetricsFeatureProvider;
85 public void setUp() throws Exception {
86 MockitoAnnotations.initMocks(this);
87 SettingsShadowResources.overrideResource("android:string/fileSizeSuffix", "%1$s %2$s");
88 SettingsShadowResources.overrideResource("android:string/gigabyteShort", "GB");
89 mContext = spy(RuntimeEnvironment.application.getApplicationContext());
90 FakeFeatureFactory.setupForTest(mContext);
91 mFakeFeatureFactory = (FakeFeatureFactory) FakeFeatureFactory.getFactory(mContext);
92 mMetricsFeatureProvider = mFakeFeatureFactory.getMetricsFeatureProvider();
93 mVolume = spy(new VolumeInfo("id", 0, null, "id"));
94 // Note: null is passed as the Lifecycle because we are handling it outside of the normal
95 // Settings fragment lifecycle for test purposes.
96 mController = new StorageItemPreferenceController(mContext, mFragment, mVolume, mSvp);
97 mPreference = new StorageItemPreference(mContext);
99 // Inflate the preference and the widget.
100 LayoutInflater inflater = LayoutInflater.from(mContext);
101 final View view = inflater.inflate(
102 mPreference.getLayoutResource(), new LinearLayout(mContext), false);
106 public void tearDown() {
107 SettingsShadowResources.reset();
111 public void testUpdateStateWithInitialState() {
112 assertThat(mPreference.getSummary().toString()).isEqualTo(
113 mContext.getString(R.string.memory_calculating_size));
117 public void testClickPhotos() {
118 mPreference.setKey("pref_photos_videos");
119 mController.handlePreferenceTreeClick(mPreference);
121 final ArgumentCaptor<Intent> argumentCaptor = ArgumentCaptor.forClass(Intent.class);
122 verify(mFragment.getActivity()).startActivityAsUser(argumentCaptor.capture(),
123 nullable(UserHandle.class));
125 Intent intent = argumentCaptor.getValue();
126 assertThat(intent.getType()).isEqualTo("image/*");
127 assertThat(intent.getAction()).isEqualTo(android.content.Intent.ACTION_VIEW);
128 assertThat(intent.getBooleanExtra(Intent.EXTRA_FROM_STORAGE, false)).isTrue();
132 public void testClickAudio() {
133 mPreference.setKey("pref_music_audio");
134 mController.handlePreferenceTreeClick(mPreference);
136 final ArgumentCaptor<Intent> argumentCaptor = ArgumentCaptor.forClass(Intent.class);
137 verify(mFragment.getActivity()).startActivityAsUser(argumentCaptor.capture(),
138 nullable(UserHandle.class));
139 Intent intent = argumentCaptor.getValue();
141 assertThat(intent.getAction()).isEqualTo(Intent.ACTION_MAIN);
142 assertThat(intent.getComponent().getClassName()).isEqualTo(SubSettings.class.getName());
143 assertThat(intent.getStringExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT)).isEqualTo(
144 ManageApplications.class.getName());
145 assertThat(intent.getBundleExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT_ARGUMENTS).getInt(
146 ManageApplications.EXTRA_STORAGE_TYPE, 0)).isEqualTo(
147 ManageApplications.STORAGE_TYPE_MUSIC);
151 public void handlePreferenceTreeClick_tappingAudioWhileUninitializedDoesntCrash() {
152 mController.setVolume(null);
154 mPreference.setKey("pref_music_audio");
155 mController.handlePreferenceTreeClick(mPreference);
159 public void testClickApps() {
160 mPreference.setKey("pref_other_apps");
161 mController.handlePreferenceTreeClick(mPreference);
163 final ArgumentCaptor<Intent> argumentCaptor = ArgumentCaptor.forClass(Intent.class);
164 verify(mFragment.getActivity()).startActivityAsUser(argumentCaptor.capture(),
165 nullable(UserHandle.class));
167 Intent intent = argumentCaptor.getValue();
168 assertThat(intent.getAction()).isEqualTo(Intent.ACTION_MAIN);
169 assertThat(intent.getComponent().getClassName()).isEqualTo(SubSettings.class.getName());
170 assertThat(intent.getStringExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT)).isEqualTo(
171 ManageApplications.class.getName());
172 assertThat(intent.getIntExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT_TITLE_RESID, 0))
173 .isEqualTo(R.string.apps_storage);
177 public void handlePreferenceTreeClick_tappingAppsWhileUninitializedDoesntCrash() {
178 mController.setVolume(null);
180 mPreference.setKey("pref_other_apps");
181 mController.handlePreferenceTreeClick(mPreference);
185 public void testClickFiles() {
186 when(mSvp.findEmulatedForPrivate(nullable(VolumeInfo.class))).thenReturn(mVolume);
187 mPreference.setKey("pref_files");
188 mController.handlePreferenceTreeClick(mPreference);
190 final ArgumentCaptor<Intent> argumentCaptor = ArgumentCaptor.forClass(Intent.class);
191 verify(mFragment.getActivity()).startActivityAsUser(argumentCaptor.capture(),
192 nullable(UserHandle.class));
194 Intent intent = argumentCaptor.getValue();
195 Intent browseIntent = mVolume.buildBrowseIntent();
196 assertThat(intent.getAction()).isEqualTo(browseIntent.getAction());
197 assertThat(intent.getData()).isEqualTo(browseIntent.getData());
198 verify(mMetricsFeatureProvider, times(1)).action(
199 nullable(Context.class), eq(MetricsEvent.STORAGE_FILES));
203 public void testClickGames() {
204 mPreference.setKey("pref_games");
205 mController.handlePreferenceTreeClick(mPreference);
207 final ArgumentCaptor<Intent> argumentCaptor = ArgumentCaptor.forClass(Intent.class);
208 verify(mFragment.getActivity()).startActivityAsUser(argumentCaptor.capture(),
209 nullable(UserHandle.class));
211 Intent intent = argumentCaptor.getValue();
212 assertThat(intent.getAction()).isEqualTo(Intent.ACTION_MAIN);
213 assertThat(intent.getComponent().getClassName()).isEqualTo(SubSettings.class.getName());
214 assertThat(intent.getStringExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT)).isEqualTo(
215 ManageApplications.class.getName());
216 assertThat(intent.getIntExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT_TITLE_RESID, 0))
217 .isEqualTo(R.string.game_storage_settings);
221 public void testClickMovies() {
222 mPreference.setKey("pref_movies");
223 mController.handlePreferenceTreeClick(mPreference);
225 final ArgumentCaptor<Intent> argumentCaptor = ArgumentCaptor.forClass(Intent.class);
226 verify(mFragment.getActivity()).startActivityAsUser(argumentCaptor.capture(),
227 nullable(UserHandle.class));
229 Intent intent = argumentCaptor.getValue();
230 assertThat(intent.getAction()).isEqualTo(Intent.ACTION_MAIN);
231 assertThat(intent.getComponent().getClassName()).isEqualTo(SubSettings.class.getName());
232 assertThat(intent.getStringExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT)).isEqualTo(
233 ManageApplications.class.getName());
234 assertThat(intent.getIntExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT_TITLE_RESID, 0))
235 .isEqualTo(R.string.storage_movies_tv);
239 public void testClickSystem() {
240 mPreference.setKey("pref_system");
241 assertThat(mController.handlePreferenceTreeClick(mPreference)).isTrue();
243 verify(mFragment.getFragmentManager().beginTransaction()).add(
244 nullable(PrivateVolumeSettings.SystemInfoFragment.class), nullable(String.class));
248 public void testMeasurementCompletedUpdatesPreferences() {
249 StorageItemPreference audio = new StorageItemPreference(mContext);
250 StorageItemPreference image = new StorageItemPreference(mContext);
251 StorageItemPreference games = new StorageItemPreference(mContext);
252 StorageItemPreference movies = new StorageItemPreference(mContext);
253 StorageItemPreference apps = new StorageItemPreference(mContext);
254 StorageItemPreference system = new StorageItemPreference(mContext);
255 StorageItemPreference files = new StorageItemPreference(mContext);
256 PreferenceScreen screen = mock(PreferenceScreen.class);
257 when(screen.findPreference(
258 eq(StorageItemPreferenceController.AUDIO_KEY))).thenReturn(audio);
259 when(screen.findPreference(
260 eq(StorageItemPreferenceController.PHOTO_KEY))).thenReturn(image);
261 when(screen.findPreference(
262 eq(StorageItemPreferenceController.GAME_KEY))).thenReturn(games);
263 when(screen.findPreference(
264 eq(StorageItemPreferenceController.MOVIES_KEY))).thenReturn(movies);
265 when(screen.findPreference(
266 eq(StorageItemPreferenceController.OTHER_APPS_KEY))).thenReturn(apps);
267 when(screen.findPreference(
268 eq(StorageItemPreferenceController.SYSTEM_KEY))).thenReturn(system);
269 when(screen.findPreference(
270 eq(StorageItemPreferenceController.FILES_KEY))).thenReturn(files);
271 mController.displayPreference(screen);
273 mController.setUsedSize(MEGABYTE_IN_BYTES * 970); // There should 870MB attributed.
274 StorageAsyncLoader.AppsStorageResult result = new StorageAsyncLoader.AppsStorageResult();
275 result.gamesSize = MEGABYTE_IN_BYTES * 80;
276 result.videoAppsSize = MEGABYTE_IN_BYTES * 160;
277 result.musicAppsSize = MEGABYTE_IN_BYTES * 40;
278 result.otherAppsSize = MEGABYTE_IN_BYTES * 90;
279 result.externalStats =
280 new StorageStatsSource.ExternalStorageStats(
281 MEGABYTE_IN_BYTES * 500, // total
282 MEGABYTE_IN_BYTES * 100, // audio
283 MEGABYTE_IN_BYTES * 150, // video
284 MEGABYTE_IN_BYTES * 200, 0); // image
286 SparseArray<StorageAsyncLoader.AppsStorageResult> results = new SparseArray<>();
287 results.put(0, result);
288 mController.onLoadFinished(results, 0);
290 assertThat(audio.getSummary().toString()).isEqualTo("0.14GB");
291 assertThat(image.getSummary().toString()).isEqualTo("0.35GB");
292 assertThat(games.getSummary().toString()).isEqualTo("0.08GB");
293 assertThat(movies.getSummary().toString()).isEqualTo("0.16GB");
294 assertThat(apps.getSummary().toString()).isEqualTo("0.09GB");
295 assertThat(files.getSummary().toString()).isEqualTo("0.05GB");
299 public void settingUserIdAppliesNewIcons() {
300 StorageItemPreference audio = spy(new StorageItemPreference(mContext));
301 audio.setIcon(R.drawable.ic_media_stream);
302 StorageItemPreference video = spy(new StorageItemPreference(mContext));
303 video.setIcon(R.drawable.ic_local_movies);
304 StorageItemPreference image = spy(new StorageItemPreference(mContext));
305 image.setIcon(R.drawable.ic_photo_library);
306 StorageItemPreference games = spy(new StorageItemPreference(mContext));
307 games.setIcon(R.drawable.ic_videogame_vd_theme_24);
308 StorageItemPreference apps = spy(new StorageItemPreference(mContext));
309 apps.setIcon(R.drawable.ic_storage_apps);
310 StorageItemPreference system = spy(new StorageItemPreference(mContext));
311 system.setIcon(R.drawable.ic_system_update_vd_theme_24);
312 StorageItemPreference files = spy(new StorageItemPreference(mContext));
313 files.setIcon(R.drawable.ic_folder_vd_theme_24);
314 PreferenceScreen screen = mock(PreferenceScreen.class);
315 when(screen.findPreference(
316 eq(StorageItemPreferenceController.AUDIO_KEY))).thenReturn(audio);
317 when(screen.findPreference(
318 eq(StorageItemPreferenceController.MOVIES_KEY))).thenReturn(video);
319 when(screen.findPreference(
320 eq(StorageItemPreferenceController.PHOTO_KEY))).thenReturn(image);
321 when(screen.findPreference(
322 eq(StorageItemPreferenceController.GAME_KEY))).thenReturn(games);
323 when(screen.findPreference(
324 eq(StorageItemPreferenceController.OTHER_APPS_KEY))).thenReturn(apps);
325 when(screen.findPreference(
326 eq(StorageItemPreferenceController.SYSTEM_KEY))).thenReturn(system);
327 when(screen.findPreference(
328 eq(StorageItemPreferenceController.FILES_KEY))).thenReturn(files);
329 mController.displayPreference(screen);
331 mController.setUserId(new UserHandle(10));
333 verify(audio, times(2)).setIcon(nullable(Drawable.class));
334 verify(video, times(2)).setIcon(nullable(Drawable.class));
335 verify(image, times(2)).setIcon(nullable(Drawable.class));
336 verify(games, times(2)).setIcon(nullable(Drawable.class));
337 verify(apps, times(2)).setIcon(nullable(Drawable.class));
338 verify(system, times(2)).setIcon(nullable(Drawable.class));
339 verify(files, times(2)).setIcon(nullable(Drawable.class));
343 public void displayPreference_dontHideFilePreferenceWhenEmulatedInternalStorageUsed() {
344 StorageItemPreference audio = new StorageItemPreference(mContext);
345 StorageItemPreference image = new StorageItemPreference(mContext);
346 StorageItemPreference games = new StorageItemPreference(mContext);
347 StorageItemPreference apps = new StorageItemPreference(mContext);
348 StorageItemPreference system = new StorageItemPreference(mContext);
349 StorageItemPreference files = new StorageItemPreference(mContext);
350 PreferenceScreen screen = mock(PreferenceScreen.class);
351 when(screen.findPreference(eq(StorageItemPreferenceController.AUDIO_KEY)))
353 when(screen.findPreference(eq(StorageItemPreferenceController.PHOTO_KEY)))
355 when(screen.findPreference(eq(StorageItemPreferenceController.GAME_KEY))).thenReturn(games);
356 when(screen.findPreference(eq(StorageItemPreferenceController.OTHER_APPS_KEY)))
358 when(screen.findPreference(eq(StorageItemPreferenceController.SYSTEM_KEY)))
360 when(screen.findPreference(eq(StorageItemPreferenceController.FILES_KEY)))
363 when(mSvp.findEmulatedForPrivate(nullable(VolumeInfo.class))).thenReturn(mVolume);
364 when(mVolume.isMountedReadable()).thenReturn(true);
366 mController.displayPreference(screen);
368 verify(screen, times(0)).removePreference(files);
372 public void displayPreference_hideFilePreferenceWhenEmulatedStorageUnreadable() {
373 StorageItemPreference audio = new StorageItemPreference(mContext);
374 StorageItemPreference image = new StorageItemPreference(mContext);
375 StorageItemPreference games = new StorageItemPreference(mContext);
376 StorageItemPreference apps = new StorageItemPreference(mContext);
377 StorageItemPreference system = new StorageItemPreference(mContext);
378 StorageItemPreference files = new StorageItemPreference(mContext);
379 PreferenceScreen screen = mock(PreferenceScreen.class);
380 when(screen.findPreference(eq(StorageItemPreferenceController.AUDIO_KEY)))
382 when(screen.findPreference(eq(StorageItemPreferenceController.PHOTO_KEY)))
384 when(screen.findPreference(eq(StorageItemPreferenceController.GAME_KEY))).thenReturn(games);
385 when(screen.findPreference(eq(StorageItemPreferenceController.OTHER_APPS_KEY)))
387 when(screen.findPreference(eq(StorageItemPreferenceController.SYSTEM_KEY)))
389 when(screen.findPreference(eq(StorageItemPreferenceController.FILES_KEY)))
392 when(mSvp.findEmulatedForPrivate(nullable(VolumeInfo.class))).thenReturn(mVolume);
393 when(mVolume.isMountedReadable()).thenReturn(false);
395 mController.displayPreference(screen);
397 verify(screen).removePreference(files);
401 public void displayPreference_hideFilePreferenceWhenNoEmulatedInternalStorage() {
402 StorageItemPreference audio = new StorageItemPreference(mContext);
403 StorageItemPreference image = new StorageItemPreference(mContext);
404 StorageItemPreference games = new StorageItemPreference(mContext);
405 StorageItemPreference apps = new StorageItemPreference(mContext);
406 StorageItemPreference system = new StorageItemPreference(mContext);
407 StorageItemPreference files = new StorageItemPreference(mContext);
408 PreferenceScreen screen = mock(PreferenceScreen.class);
409 when(screen.findPreference(eq(StorageItemPreferenceController.AUDIO_KEY)))
411 when(screen.findPreference(eq(StorageItemPreferenceController.PHOTO_KEY)))
413 when(screen.findPreference(eq(StorageItemPreferenceController.GAME_KEY))).thenReturn(games);
414 when(screen.findPreference(eq(StorageItemPreferenceController.OTHER_APPS_KEY)))
416 when(screen.findPreference(eq(StorageItemPreferenceController.SYSTEM_KEY)))
418 when(screen.findPreference(eq(StorageItemPreferenceController.FILES_KEY)))
421 when(mSvp.findEmulatedForPrivate(nullable(VolumeInfo.class))).thenReturn(null);
423 mController.displayPreference(screen);
425 verify(screen).removePreference(files);
429 public void displayPreference_updateFilePreferenceToHideAfterSettingVolume() {
430 StorageItemPreference audio = new StorageItemPreference(mContext);
431 StorageItemPreference image = new StorageItemPreference(mContext);
432 StorageItemPreference games = new StorageItemPreference(mContext);
433 StorageItemPreference apps = new StorageItemPreference(mContext);
434 StorageItemPreference system = new StorageItemPreference(mContext);
435 StorageItemPreference files = new StorageItemPreference(mContext);
436 PreferenceScreen screen = mock(PreferenceScreen.class);
437 when(screen.findPreference(eq(StorageItemPreferenceController.AUDIO_KEY)))
439 when(screen.findPreference(eq(StorageItemPreferenceController.PHOTO_KEY)))
441 when(screen.findPreference(eq(StorageItemPreferenceController.GAME_KEY))).thenReturn(games);
442 when(screen.findPreference(eq(StorageItemPreferenceController.OTHER_APPS_KEY)))
444 when(screen.findPreference(eq(StorageItemPreferenceController.SYSTEM_KEY)))
446 when(screen.findPreference(eq(StorageItemPreferenceController.FILES_KEY)))
449 when(mSvp.findEmulatedForPrivate(nullable(VolumeInfo.class))).thenReturn(mVolume);
450 when(mVolume.isMountedReadable()).thenReturn(true);
452 mController.displayPreference(screen);
453 when(mSvp.findEmulatedForPrivate(nullable(VolumeInfo.class))).thenReturn(null);
454 mController.setVolume(mVolume);
456 verify(screen).removePreference(files);
461 public void displayPreference_updateFilePreferenceToShowAfterSettingVolume() {
462 StorageItemPreference audio = new StorageItemPreference(mContext);
463 StorageItemPreference image = new StorageItemPreference(mContext);
464 StorageItemPreference games = new StorageItemPreference(mContext);
465 StorageItemPreference apps = new StorageItemPreference(mContext);
466 StorageItemPreference system = new StorageItemPreference(mContext);
467 StorageItemPreference files = new StorageItemPreference(mContext);
468 PreferenceScreen screen = mock(PreferenceScreen.class);
469 when(screen.findPreference(eq(StorageItemPreferenceController.AUDIO_KEY)))
471 when(screen.findPreference(eq(StorageItemPreferenceController.PHOTO_KEY)))
473 when(screen.findPreference(eq(StorageItemPreferenceController.GAME_KEY))).thenReturn(games);
474 when(screen.findPreference(eq(StorageItemPreferenceController.OTHER_APPS_KEY)))
476 when(screen.findPreference(eq(StorageItemPreferenceController.SYSTEM_KEY)))
478 when(screen.findPreference(eq(StorageItemPreferenceController.FILES_KEY)))
481 // This will hide it initially.
482 mController.displayPreference(screen);
484 when(mSvp.findEmulatedForPrivate(nullable(VolumeInfo.class))).thenReturn(mVolume);
485 when(mVolume.isMountedReadable()).thenReturn(true);
487 // And we bring it back.
488 mController.setVolume(mVolume);
490 verify(screen).addPreference(files);