diff --git a/res/values/strings.xml b/res/values/strings.xml index 1931e67c6db..34f3c51768d 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -8165,6 +8165,11 @@ Games + + Audio files + + Music + Uninstalled for user %s\n diff --git a/src/com/android/settings/Utils.java b/src/com/android/settings/Utils.java index 248358c6901..f5bd2ce4ee3 100644 --- a/src/com/android/settings/Utils.java +++ b/src/com/android/settings/Utils.java @@ -25,6 +25,7 @@ import android.app.Fragment; import android.app.IActivityManager; import android.app.KeyguardManager; import android.app.admin.DevicePolicyManager; +import android.content.ActivityNotFoundException; import android.content.ComponentName; import android.content.ContentResolver; import android.content.Context; @@ -1224,4 +1225,24 @@ public final class Utils extends com.android.settingslib.Utils { return null; } } + + /** + * Launches an intent which may optionally have a user id defined. + * @param fragment Fragment to use to launch the activity. + * @param intent Intent to launch. + */ + public static void launchIntent(Fragment fragment, Intent intent) { + try { + final int userId = intent.getIntExtra(Intent.EXTRA_USER_ID, -1); + + if (userId == -1) { + fragment.startActivity(intent); + } else { + fragment.getActivity().startActivityAsUser(intent, new UserHandle(userId)); + } + } catch (ActivityNotFoundException e) { + Log.w(TAG, "No activity found for " + intent); + } + } + } diff --git a/src/com/android/settings/applications/FileViewHolderController.java b/src/com/android/settings/applications/FileViewHolderController.java new file mode 100644 index 00000000000..e8af722cda3 --- /dev/null +++ b/src/com/android/settings/applications/FileViewHolderController.java @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2016 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.applications; + +import android.app.Fragment; +import android.view.View; + +/** + * FileViewHolderController handles adapting the AppViewHolder to work as a general purpose + * storage categorization preference in the ManageApplications view. + */ +public interface FileViewHolderController { + /** + * Begins a synchronous query for statistics for the files. + */ + void queryStats(); + + /** + * Returns if the preference should be shown. + */ + boolean shouldShow(); + + /** + * Initializes the view within an AppViewHolder. + * @param holder The holder to use to initialize. + */ + void setupView(AppViewHolder holder); + + /** + * Handles the behavior when the view is clicked. + * @param fragment Fragment where the click originated. + */ + void onClick(Fragment fragment); +} diff --git a/src/com/android/settings/applications/ManageApplications.java b/src/com/android/settings/applications/ManageApplications.java index f6b303c0d5b..443ce348b46 100644 --- a/src/com/android/settings/applications/ManageApplications.java +++ b/src/com/android/settings/applications/ManageApplications.java @@ -17,6 +17,7 @@ package com.android.settings.applications; import android.app.Activity; +import android.app.usage.StorageStatsManager; import android.content.Context; import android.content.Intent; import android.content.pm.ApplicationInfo; @@ -32,6 +33,7 @@ import android.os.UserHandle; import android.os.UserManager; import android.preference.PreferenceFrameLayout; import android.text.TextUtils; +import android.text.format.Formatter; import android.util.Log; import android.view.LayoutInflater; import android.view.Menu; @@ -71,6 +73,7 @@ import com.android.settings.applications.AppStateInstallAppsBridge.InstallAppsSt import com.android.settings.applications.AppStateUsageBridge.UsageState; import com.android.settings.core.InstrumentedPreferenceFragment; import com.android.settings.dashboard.SummaryLoader; +import com.android.settings.deviceinfo.storage.StorageStatsSource; import com.android.settings.fuelgauge.HighPowerDetail; import com.android.settings.fuelgauge.PowerWhitelistBackend; import com.android.settings.notification.AppNotificationSettings; @@ -108,6 +111,7 @@ public class ManageApplications extends InstrumentedPreferenceFragment // Used for storage only. public static final String EXTRA_VOLUME_UUID = "volumeUuid"; public static final String EXTRA_VOLUME_NAME = "volumeName"; + public static final String EXTRA_STORAGE_TYPE = "storageType"; private static final String EXTRA_SORT_ORDER = "sortOrder"; private static final String EXTRA_SHOW_SYSTEM = "showSystem"; @@ -140,6 +144,10 @@ public class ManageApplications extends InstrumentedPreferenceFragment public static final int FILTER_APPS_WRITE_SETTINGS = 10; public static final int FILTER_APPS_INSTALL_SOURCES = 12; + // Storage types. Used to determine what the extra item in the list of preferences is. + public static final int STORAGE_TYPE_DEFAULT = 0; + public static final int STORAGE_TYPE_MUSIC = 1; + // This is the string labels for the filter modes above, the order must be kept in sync. public static final int[] FILTER_LABELS = new int[]{ R.string.high_power_filter_on, // High power whitelist, on @@ -227,6 +235,7 @@ public class ManageApplications extends InstrumentedPreferenceFragment private ResetAppsHelper mResetAppsHelper; private String mVolumeUuid; private String mVolumeName; + private int mStorageType; @Override public void onCreate(Bundle savedInstanceState) { @@ -250,6 +259,7 @@ public class ManageApplications extends InstrumentedPreferenceFragment if (args != null && args.containsKey(EXTRA_VOLUME_UUID)) { mVolumeUuid = args.getString(EXTRA_VOLUME_UUID); mVolumeName = args.getString(EXTRA_VOLUME_NAME); + mStorageType = args.getInt(EXTRA_STORAGE_TYPE, STORAGE_TYPE_DEFAULT); mListType = LIST_TYPE_STORAGE; } else { // No volume selected, display a normal list, sorted by size. @@ -316,6 +326,13 @@ public class ManageApplications extends InstrumentedPreferenceFragment mApplications.mHasReceivedBridgeCallback = savedInstanceState.getBoolean(EXTRA_HAS_BRIDGE, false); } + if (mStorageType == STORAGE_TYPE_MUSIC) { + Context context = getContext(); + mApplications.setExtraViewController(new MusicViewHolderController( + context, + new StorageStatsSource(context), + mVolumeUuid)); + } mListView.setAdapter(mApplications); mListView.setRecyclerListener(mApplications); mListView.setFastScrollEnabled(isFastScrollEnabled()); @@ -361,7 +378,11 @@ public class ManageApplications extends InstrumentedPreferenceFragment mFilterAdapter.enableFilter(FILTER_APPS_POWER_WHITELIST_ALL); } if (mListType == LIST_TYPE_STORAGE) { - mApplications.setOverrideFilter(new VolumeFilter(mVolumeUuid)); + AppFilter filter = new VolumeFilter(mVolumeUuid); + if (mStorageType == STORAGE_TYPE_MUSIC) { + filter = new CompoundFilter(ApplicationsState.FILTER_AUDIO, filter); + } + mApplications.setOverrideFilter(filter); } if (mListType == LIST_TYPE_GAMES) { mApplications.setOverrideFilter(ApplicationsState.FILTER_GAMES); @@ -626,11 +647,17 @@ public class ManageApplications extends InstrumentedPreferenceFragment @Override public void onItemClick(AdapterView parent, View view, int position, long id) { - if (mApplications != null && mApplications.getCount() > position) { + if (mApplications == null) { + return; + } + + if (mApplications.getApplicationCount() > position) { ApplicationsState.AppEntry entry = mApplications.getAppEntry(position); mCurrentPkgName = entry.info.packageName; mCurrentUid = entry.info.uid; startApplicationDetailsActivity(); + } else { + mApplications.mExtraViewController.onClick(this); } } @@ -769,6 +796,7 @@ public class ManageApplications extends InstrumentedPreferenceFragment private AppFilter mOverrideFilter; private boolean mHasReceivedLoadEntries; private boolean mHasReceivedBridgeCallback; + private FileViewHolderController mExtraViewController; // These two variables are used to remember and restore the last scroll position when this // fragment is paused. We need this special handling because app entries are added gradually @@ -839,6 +867,10 @@ public class ManageApplications extends InstrumentedPreferenceFragment rebuild(true); } + public void setExtraViewController(FileViewHolderController extraViewController) { + mExtraViewController = extraViewController; + } + public void resume(int sort) { if (DEBUG) Log.i(TAG, "Resume! mResumed=" + mResumed); if (!mResumed) { @@ -889,7 +921,6 @@ public class ManageApplications extends InstrumentedPreferenceFragment // Don't rebuild the list until all the app entries are loaded. return; } - if (DEBUG) Log.i(TAG, "Rebuilding app list..."); ApplicationsState.AppFilter filterObj; Comparator comparatorObj; boolean emulated = Environment.isExternalStorageEmulated(); @@ -924,8 +955,12 @@ public class ManageApplications extends InstrumentedPreferenceFragment comparatorObj = ApplicationsState.ALPHA_COMPARATOR; break; } - filterObj = new CompoundFilter(filterObj, ApplicationsState.FILTER_NOT_HIDE); + if (mExtraViewController != null) { + mExtraViewController.queryStats(); + } + + filterObj = new CompoundFilter(filterObj, ApplicationsState.FILTER_NOT_HIDE); AppFilter finalFilterObj = filterObj; mBgHandler.post(() -> { final ArrayList entries = mSession.rebuild(finalFilterObj, @@ -1104,6 +1139,10 @@ public class ManageApplications extends InstrumentedPreferenceFragment public void onPackageSizeChanged(String packageName) { for (int i = 0; i < mActive.size(); i++) { AppViewHolder holder = (AppViewHolder) mActive.get(i).getTag(); + ApplicationInfo info = holder.entry.info; + if (info == null) { + continue; + } if (holder.entry.info.packageName.equals(packageName)) { synchronized (holder.entry) { updateSummary(holder); @@ -1136,10 +1175,22 @@ public class ManageApplications extends InstrumentedPreferenceFragment } public int getCount() { + if (mEntries == null) { + return 0; + } + int extraViewAddition = + (mExtraViewController != null && mExtraViewController.shouldShow()) ? 1 : 0; + return mEntries.size() + extraViewAddition; + } + + public int getApplicationCount() { return mEntries != null ? mEntries.size() : 0; } public Object getItem(int position) { + if (position == mEntries.size()) { + return mExtraViewController; + } return mEntries.get(position); } @@ -1148,6 +1199,9 @@ public class ManageApplications extends InstrumentedPreferenceFragment } public long getItemId(int position) { + if (position == mEntries.size()) { + return -1; + } return mEntries.get(position).id; } @@ -1158,6 +1212,11 @@ public class ManageApplications extends InstrumentedPreferenceFragment @Override public boolean isEnabled(int position) { + if (position == mEntries.size() && mExtraViewController != null && + mExtraViewController.shouldShow()) { + return true; + } + if (mManageApplications.mListType != LIST_TYPE_HIGH_POWER) { return true; } @@ -1172,31 +1231,38 @@ public class ManageApplications extends InstrumentedPreferenceFragment convertView); convertView = holder.rootView; - // Bind the data efficiently with the holder - ApplicationsState.AppEntry entry = mEntries.get(position); - synchronized (entry) { - holder.entry = entry; - if (entry.label != null) { - holder.appName.setText(entry.label); - } - mState.ensureIcon(entry); - if (entry.icon != null) { - holder.appIcon.setImageDrawable(entry.icon); - } - updateSummary(holder); - if ((entry.info.flags & ApplicationInfo.FLAG_INSTALLED) == 0) { - holder.disabled.setVisibility(View.VISIBLE); - holder.disabled.setText(R.string.not_installed); - } else if (!entry.info.enabled) { - holder.disabled.setVisibility(View.VISIBLE); - holder.disabled.setText(R.string.disabled); - } else { - holder.disabled.setVisibility(View.GONE); + // Handle the extra view if it is the last entry. + if (mEntries != null && mExtraViewController != null && position == mEntries.size()) { + mExtraViewController.setupView(holder); + convertView.setEnabled(true); + } else { + // Bind the data efficiently with the holder + ApplicationsState.AppEntry entry = mEntries.get(position); + synchronized (entry) { + holder.entry = entry; + if (entry.label != null) { + holder.appName.setText(entry.label); + } + mState.ensureIcon(entry); + if (entry.icon != null) { + holder.appIcon.setImageDrawable(entry.icon); + } + updateSummary(holder); + if ((entry.info.flags & ApplicationInfo.FLAG_INSTALLED) == 0) { + holder.disabled.setVisibility(View.VISIBLE); + holder.disabled.setText(R.string.not_installed); + } else if (!entry.info.enabled) { + holder.disabled.setVisibility(View.VISIBLE); + holder.disabled.setText(R.string.disabled); + } else { + holder.disabled.setVisibility(View.GONE); + } } + convertView.setEnabled(isEnabled(position)); } + mActive.remove(convertView); mActive.add(convertView); - convertView.setEnabled(isEnabled(position)); return convertView; } diff --git a/src/com/android/settings/applications/MusicViewHolderController.java b/src/com/android/settings/applications/MusicViewHolderController.java new file mode 100644 index 00000000000..18c87dbcc62 --- /dev/null +++ b/src/com/android/settings/applications/MusicViewHolderController.java @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2016 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.applications; + +import android.app.Fragment; +import android.content.Context; +import android.content.Intent; +import android.os.UserHandle; +import android.provider.DocumentsContract; +import android.support.annotation.WorkerThread; +import android.text.format.Formatter; + +import com.android.settings.R; +import com.android.settings.Utils; +import com.android.settings.deviceinfo.storage.StorageStatsSource; + +/** + * MusicViewHolderController controls an Audio/Music file view in the ManageApplications view. + */ +public class MusicViewHolderController implements FileViewHolderController { + private static final String AUTHORITY_MEDIA = "com.android.providers.media.documents"; + + private Context mContext; + private StorageStatsSource mSource; + private String mVolumeUuid; + private long mMusicSize; + + public MusicViewHolderController( + Context context, StorageStatsSource source, String volumeUuid) { + mContext = context; + mSource = source; + mVolumeUuid = volumeUuid; + } + + @Override + @WorkerThread + public void queryStats() { + mMusicSize = mSource.getExternalStorageStats(mVolumeUuid, UserHandle.CURRENT).audioBytes; + } + + @Override + public boolean shouldShow() { + return true; + } + + @Override + public void setupView(AppViewHolder holder) { + holder.appIcon.setImageDrawable(mContext.getDrawable(R.drawable.empty_icon)); + holder.appName.setText(mContext.getText(R.string.audio_files_title)); + holder.summary.setText(Formatter.formatFileSize(mContext, mMusicSize)); + } + + @Override + public void onClick(Fragment fragment) { + Intent intent = new Intent(DocumentsContract.ACTION_BROWSE); + intent.setData(DocumentsContract.buildRootUri(AUTHORITY_MEDIA, "audio_root")); + intent.addCategory(Intent.CATEGORY_DEFAULT); + intent.putExtra(Intent.EXTRA_USER_ID, UserHandle.CURRENT); + Utils.launchIntent(fragment, intent); + } +} diff --git a/src/com/android/settings/deviceinfo/PrivateVolumeSettings.java b/src/com/android/settings/deviceinfo/PrivateVolumeSettings.java index b0a99026cd7..ce26c0fea21 100644 --- a/src/com/android/settings/deviceinfo/PrivateVolumeSettings.java +++ b/src/com/android/settings/deviceinfo/PrivateVolumeSettings.java @@ -533,7 +533,7 @@ public class PrivateVolumeSettings extends SettingsPreferenceFragment { if (intent != null) { intent.putExtra(Intent.EXTRA_USER_ID, userId); - launchIntent(this, intent); + Utils.launchIntent(this, intent); return true; } return super.onPreferenceTreeClick(pref); @@ -670,20 +670,6 @@ public class PrivateVolumeSettings extends SettingsPreferenceFragment { return total; } - private static void launchIntent(Fragment fragment, Intent intent) { - try { - final int userId = intent.getIntExtra(Intent.EXTRA_USER_ID, -1); - - if (userId == -1) { - fragment.startActivity(intent); - } else { - fragment.getActivity().startActivityAsUser(intent, new UserHandle(userId)); - } - } catch (ActivityNotFoundException e) { - Log.w(TAG, "No activity found for " + intent); - } - } - private final StorageEventListener mStorageListener = new StorageEventListener() { @Override public void onVolumeStateChanged(VolumeInfo vol, int oldState, int newState) { @@ -815,7 +801,7 @@ public class PrivateVolumeSettings extends SettingsPreferenceFragment { new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { - launchIntent(OtherInfoFragment.this, intent); + Utils.launchIntent(OtherInfoFragment.this, intent); } }); builder.setNegativeButton(android.R.string.cancel, null); diff --git a/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceController.java b/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceController.java index 22f9c4c71fb..16dcd18908f 100644 --- a/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceController.java +++ b/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceController.java @@ -243,10 +243,15 @@ public class StorageItemPreferenceController extends PreferenceController } private Intent getAudioIntent() { - Intent intent = new Intent(DocumentsContract.ACTION_BROWSE); - intent.setData(DocumentsContract.buildRootUri(AUTHORITY_MEDIA, "audio_root")); - intent.addCategory(Intent.CATEGORY_DEFAULT); - return intent; + Bundle args = new Bundle(); + args.putString(ManageApplications.EXTRA_CLASSNAME, + Settings.StorageUseActivity.class.getName()); + args.putString(ManageApplications.EXTRA_VOLUME_UUID, mVolume.getFsUuid()); + args.putString(ManageApplications.EXTRA_VOLUME_NAME, mVolume.getDescription()); + args.putInt(ManageApplications.EXTRA_STORAGE_TYPE, ManageApplications.STORAGE_TYPE_MUSIC); + return Utils.onBuildStartFragmentIntent(mContext, + ManageApplications.class.getName(), args, null, R.string.audio_storage_title, null, + false); } private Intent getAppsIntent() { diff --git a/src/com/android/settings/deviceinfo/storage/StorageStatsSource.java b/src/com/android/settings/deviceinfo/storage/StorageStatsSource.java new file mode 100644 index 00000000000..b6e03fb2c78 --- /dev/null +++ b/src/com/android/settings/deviceinfo/storage/StorageStatsSource.java @@ -0,0 +1,58 @@ +/* + * 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.app.usage.StorageStatsManager; +import android.content.Context; +import android.os.UserHandle; + +/** + * StorageStatsSource wraps the StorageStatsManager for testability purposes. + */ +public class StorageStatsSource { + private StorageStatsManager mSsm; + + public StorageStatsSource(Context context) { + mSsm = context.getSystemService(StorageStatsManager.class); + } + + public ExternalStorageStats getExternalStorageStats(String volumeUuid, UserHandle user) { + return new ExternalStorageStats(mSsm.queryExternalStatsForUser(volumeUuid, user)); + } + + public static class ExternalStorageStats { + public long totalBytes; + public long audioBytes; + public long videoBytes; + public long imageBytes; + + public ExternalStorageStats(long totalBytes, long audioBytes, long videoBytes, + long imageBytes) { + this.totalBytes = totalBytes; + this.audioBytes = audioBytes; + this.videoBytes = videoBytes; + this.imageBytes = imageBytes; + } + + public ExternalStorageStats(android.app.usage.ExternalStorageStats stats) { + totalBytes = stats.getTotalBytes(); + audioBytes = stats.getAudioBytes(); + videoBytes = stats.getVideoBytes(); + imageBytes = stats.getImageBytes(); + } + } +} diff --git a/tests/robotests/src/com/android/settings/applications/MusicViewHolderControllerTest.java b/tests/robotests/src/com/android/settings/applications/MusicViewHolderControllerTest.java new file mode 100644 index 00000000000..2a2de66012e --- /dev/null +++ b/tests/robotests/src/com/android/settings/applications/MusicViewHolderControllerTest.java @@ -0,0 +1,106 @@ +/* + * 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.applications; + +import static com.google.common.truth.Truth.assertThat; + +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import android.app.Fragment; +import android.content.Context; +import android.content.Intent; +import android.os.UserHandle; +import android.os.storage.VolumeInfo; +import android.provider.DocumentsContract; +import android.view.LayoutInflater; + +import com.android.settings.SettingsRobolectricTestRunner; +import com.android.settings.TestConfig; +import com.android.settings.deviceinfo.storage.StorageStatsSource; +import com.android.settingslib.deviceinfo.StorageVolumeProvider; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Answers; +import org.mockito.ArgumentCaptor; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.robolectric.RuntimeEnvironment; +import org.robolectric.annotation.Config; + + +@RunWith(SettingsRobolectricTestRunner.class) +@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION) +public class MusicViewHolderControllerTest { + @Mock(answer = Answers.RETURNS_DEEP_STUBS) + private Fragment mFragment; + @Mock + private StorageVolumeProvider mSvp; + @Mock + private StorageStatsSource mSource; + + private Context mContext; + private MusicViewHolderController mController; + private VolumeInfo mVolume; + private AppViewHolder mHolder; + + @Before + public void setUp() throws Exception { + MockitoAnnotations.initMocks(this); + mContext = RuntimeEnvironment.application; + mVolume = new VolumeInfo("id", 0, null, "id"); + mController = new MusicViewHolderController(mContext, mSource, mVolume.fsUuid); + + LayoutInflater inflater = LayoutInflater.from(mContext); + mHolder = AppViewHolder.createOrRecycle(inflater, null); + } + + @Test + public void storageShouldBeZeroBytesIfQueriedBeforeStorageQueryFinishes() { + mController.setupView(mHolder); + + assertThat(mHolder.summary.getText().toString()).isEqualTo("0.00B"); + } + + @Test + public void storageShouldRepresentStorageStatsQuery() { + when(mSource.getExternalStorageStats(any(String.class), any(UserHandle.class))).thenReturn( + new StorageStatsSource.ExternalStorageStats(1, 1, 0, 0)); + + mController.queryStats(); + mController.setupView(mHolder); + + assertThat(mHolder.summary.getText().toString()).isEqualTo("1.00B"); + } + + @Test + public void clickingShouldIntentIntoFilesApp() { + mController.onClick(mFragment); + + final ArgumentCaptor argumentCaptor = ArgumentCaptor.forClass(Intent.class); + verify(mFragment).startActivity(argumentCaptor.capture()); + Intent intent = argumentCaptor.getValue(); + + assertThat(intent.getAction()).isEqualTo(DocumentsContract.ACTION_BROWSE); + assertThat(intent.getData()).isEqualTo(DocumentsContract.buildRootUri( + "com.android.providers.media.documents", + "audio_root")); + } +} 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 a377505d113..f7baba365cb 100644 --- a/tests/robotests/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceControllerTest.java @@ -35,6 +35,7 @@ import android.view.View; import android.widget.LinearLayout; import com.android.settings.R; +import com.android.settings.Settings; import com.android.settings.SettingsActivity; import com.android.settings.SettingsRobolectricTestRunner; import com.android.settings.SubSettings; @@ -118,12 +119,15 @@ public class StorageItemPreferenceControllerTest { final ArgumentCaptor argumentCaptor = ArgumentCaptor.forClass(Intent.class); verify(mFragment.getActivity()).startActivityAsUser(argumentCaptor.capture(), any(UserHandle.class)); - Intent intent = argumentCaptor.getValue(); - assertThat(intent.getAction()).isEqualTo(DocumentsContract.ACTION_BROWSE); - assertThat(intent.getData()).isEqualTo(DocumentsContract.buildRootUri( - "com.android.providers.media.documents", - "audio_root")); + + assertThat(intent.getAction()).isEqualTo(Intent.ACTION_MAIN); + assertThat(intent.getComponent().getClassName()).isEqualTo(SubSettings.class.getName()); + assertThat(intent.getStringExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT)).isEqualTo( + ManageApplications.class.getName()); + assertThat(intent.getBundleExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT_ARGUMENTS).getInt( + ManageApplications.EXTRA_STORAGE_TYPE, 0)).isEqualTo( + ManageApplications.STORAGE_TYPE_MUSIC); } @Test diff --git a/tests/robotests/src/com/android/settings/deviceinfo/storage/StorageSummaryDonutPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/deviceinfo/storage/StorageSummaryDonutPreferenceControllerTest.java index fa0851e0e3a..990223aa3a2 100644 --- a/tests/robotests/src/com/android/settings/deviceinfo/storage/StorageSummaryDonutPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/deviceinfo/storage/StorageSummaryDonutPreferenceControllerTest.java @@ -61,7 +61,6 @@ public class StorageSummaryDonutPreferenceControllerTest { final View view = inflater.inflate( mPreference.getLayoutResource(), new LinearLayout(mContext), false); - mHolder = new PreferenceViewHolder(view); }