Loading res/values/strings.xml +5 −0 Original line number Diff line number Diff line Loading @@ -8165,6 +8165,11 @@ <!-- Title of games app storage screen [CHAR LIMIT=30] --> <string name="game_storage_settings">Games</string> <!-- Title for audio files preference. [CHAR LIMIT=50] --> <string name="audio_files_title">Audio files</string> <!-- Title for the Audio storage view. [CHAR LIMIT=50] --> <string name="audio_storage_title">Music</string> <!-- UI webview setting: WebView uninstalled-for-user explanatory text [CHAR LIMIT=30] --> <string name="webview_uninstalled_for_user">Uninstalled for user <xliff:g id="user" example="John Doe">%s</xliff:g>\n</string> <!-- UI webview setting: WebView disabled-for-user explanatory text [CHAR LIMIT=30] --> src/com/android/settings/Utils.java +21 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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); } } } src/com/android/settings/applications/FileViewHolderController.java 0 → 100644 +48 −0 Original line number Diff line number Diff line /* * 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); } src/com/android/settings/applications/ManageApplications.java +91 −25 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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"; Loading Loading @@ -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 Loading Loading @@ -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) { Loading @@ -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. Loading Loading @@ -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()); Loading Loading @@ -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); Loading Loading @@ -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); } } Loading Loading @@ -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 Loading Loading @@ -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) { Loading Loading @@ -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<AppEntry> comparatorObj; boolean emulated = Environment.isExternalStorageEmulated(); Loading Loading @@ -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<AppEntry> entries = mSession.rebuild(finalFilterObj, Loading Loading @@ -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); Loading Loading @@ -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); } Loading @@ -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; } Loading @@ -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; } Loading @@ -1172,6 +1231,11 @@ public class ManageApplications extends InstrumentedPreferenceFragment convertView); convertView = holder.rootView; // 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) { Loading @@ -1194,9 +1258,11 @@ public class ManageApplications extends InstrumentedPreferenceFragment holder.disabled.setVisibility(View.GONE); } } convertView.setEnabled(isEnabled(position)); } mActive.remove(convertView); mActive.add(convertView); convertView.setEnabled(isEnabled(position)); return convertView; } Loading src/com/android/settings/applications/MusicViewHolderController.java 0 → 100644 +75 −0 Original line number Diff line number Diff line /* * 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); } } Loading
res/values/strings.xml +5 −0 Original line number Diff line number Diff line Loading @@ -8165,6 +8165,11 @@ <!-- Title of games app storage screen [CHAR LIMIT=30] --> <string name="game_storage_settings">Games</string> <!-- Title for audio files preference. [CHAR LIMIT=50] --> <string name="audio_files_title">Audio files</string> <!-- Title for the Audio storage view. [CHAR LIMIT=50] --> <string name="audio_storage_title">Music</string> <!-- UI webview setting: WebView uninstalled-for-user explanatory text [CHAR LIMIT=30] --> <string name="webview_uninstalled_for_user">Uninstalled for user <xliff:g id="user" example="John Doe">%s</xliff:g>\n</string> <!-- UI webview setting: WebView disabled-for-user explanatory text [CHAR LIMIT=30] -->
src/com/android/settings/Utils.java +21 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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); } } }
src/com/android/settings/applications/FileViewHolderController.java 0 → 100644 +48 −0 Original line number Diff line number Diff line /* * 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); }
src/com/android/settings/applications/ManageApplications.java +91 −25 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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"; Loading Loading @@ -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 Loading Loading @@ -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) { Loading @@ -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. Loading Loading @@ -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()); Loading Loading @@ -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); Loading Loading @@ -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); } } Loading Loading @@ -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 Loading Loading @@ -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) { Loading Loading @@ -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<AppEntry> comparatorObj; boolean emulated = Environment.isExternalStorageEmulated(); Loading Loading @@ -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<AppEntry> entries = mSession.rebuild(finalFilterObj, Loading Loading @@ -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); Loading Loading @@ -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); } Loading @@ -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; } Loading @@ -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; } Loading @@ -1172,6 +1231,11 @@ public class ManageApplications extends InstrumentedPreferenceFragment convertView); convertView = holder.rootView; // 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) { Loading @@ -1194,9 +1258,11 @@ public class ManageApplications extends InstrumentedPreferenceFragment holder.disabled.setVisibility(View.GONE); } } convertView.setEnabled(isEnabled(position)); } mActive.remove(convertView); mActive.add(convertView); convertView.setEnabled(isEnabled(position)); return convertView; } Loading
src/com/android/settings/applications/MusicViewHolderController.java 0 → 100644 +75 −0 Original line number Diff line number Diff line /* * 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); } }