diff --git a/AndroidManifest.xml b/AndroidManifest.xml index cd061fc0791..3afca521111 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -2921,17 +2921,6 @@ android:value="true" /> - - - - - - - - - - - - - - - - - diff --git a/res/drawable/ic_keyboard_arrow_down_black_32.xml b/res/drawable/ic_keyboard_arrow_down_black_32.xml deleted file mode 100644 index 12ce9c2e4b3..00000000000 --- a/res/drawable/ic_keyboard_arrow_down_black_32.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - - - \ No newline at end of file diff --git a/res/drawable/ic_keyboard_arrow_up_black_32.xml b/res/drawable/ic_keyboard_arrow_up_black_32.xml deleted file mode 100644 index d41980061c4..00000000000 --- a/res/drawable/ic_keyboard_arrow_up_black_32.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - - - \ No newline at end of file diff --git a/res/values/bools.xml b/res/values/bools.xml index 15706df7918..6f0445712f2 100644 --- a/res/values/bools.xml +++ b/res/values/bools.xml @@ -41,6 +41,6 @@ false - - false + + false diff --git a/res/values/strings.xml b/res/values/strings.xml index 9515eca61f5..914dbd911c7 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -7493,17 +7493,6 @@ Demo mode - - Remove from Device - - %1$s • Last used %2$d days ago - - %1$s • Never used before - - %1$s • Not sure when last used - - Free up %1$s - We\'re here to help @@ -7610,27 +7599,6 @@ Bluetooth - - Photos & Videos (%1$d) - - - %1$s • Older than %2$d days - - - Downloads (%1$d) - - - %1$s • Last modified %2$s - - - %1$s - - - Remove %1$s from your device. - - - Remove - Storage manager @@ -7640,21 +7608,6 @@ Remove photos & videos - - %1$s now free. Manage storage automatically? - - Let Storage manager automatically free up space by removing backed up content from your device? - - No thanks - - Turn on - - - Apps (%1$d) - - - %1$s • Last used %2$d days ago - Automatic @@ -7664,12 +7617,6 @@ Free space now - - Storage manager - - - Automatic Storage Management Service - Gestures diff --git a/res/xml/deletion_helper_list.xml b/res/xml/deletion_helper_list.xml deleted file mode 100644 index 64bd3b5974a..00000000000 --- a/res/xml/deletion_helper_list.xml +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - - - - - - diff --git a/src/com/android/settings/CollapsibleCheckboxPreferenceGroup.java b/src/com/android/settings/CollapsibleCheckboxPreferenceGroup.java deleted file mode 100644 index a0f9d988ade..00000000000 --- a/src/com/android/settings/CollapsibleCheckboxPreferenceGroup.java +++ /dev/null @@ -1,147 +0,0 @@ -/* - * 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; - -import android.content.Context; -import android.support.v7.preference.Preference; -import android.support.v7.preference.PreferenceGroup; -import android.support.v7.preference.PreferenceViewHolder; -import android.util.AttributeSet; - -import android.util.Log; -import android.util.TypedValue; -import android.view.View; -import android.widget.Checkable; -import android.widget.TextView; - -import java.util.LinkedHashMap; - -/** - * CollapsibleCheckboxPreferenceGroup is a preference group that can be expanded or collapsed and - * also has a checkbox. - */ -public class CollapsibleCheckboxPreferenceGroup extends PreferenceGroup implements - View.OnClickListener { - private boolean mCollapsed; - private boolean mChecked; - - public CollapsibleCheckboxPreferenceGroup(Context context) { - this(context, null); - } - - public CollapsibleCheckboxPreferenceGroup(Context context, AttributeSet attrs) { - super(context, attrs); - setWidgetLayoutResource(com.android.settings.R.layout.preference_widget_checkbox); - } - - @Override - public void onBindViewHolder(PreferenceViewHolder holder) { - super.onBindViewHolder(holder); - View checkbox = holder.findViewById(com.android.internal.R.id.checkbox); - if (checkbox != null && checkbox instanceof Checkable) { - ((Checkable) checkbox).setChecked(mChecked); - checkbox.setClickable(true); - checkbox.setFocusable(true); - checkbox.setOnClickListener(this); - } - - final TextView titleView = (TextView) holder.findViewById(android.R.id.title); - if (titleView != null) { - Context context = getContext(); - TypedValue value = new TypedValue(); - context.getTheme().resolveAttribute(android.R.attr.colorAccent, value, true); - titleView.setTextColor(context.getColor(value.resourceId)); - } - } - - @Override - public boolean addPreference(Preference p) { - super.addPreference(p); - p.setVisible(!isCollapsed()); - return true; - } - - // The preference click handler. - @Override - protected void onClick() { - super.onClick(); - setCollapse(!isCollapsed()); - } - - // The checkbox view click handler. - @Override - public void onClick(View v) { - setChecked(!isChecked()); - } - - /** - * Return if the view is collapsed. - */ - public boolean isCollapsed() { - return mCollapsed; - } - - /** - * Returns the checked state of the preference. - */ - public boolean isChecked() { - return mChecked; - } - - /** - * Sets the checked state and notifies listeners of the state change. - */ - public void setChecked(boolean checked) { - if (mChecked != checked) { - mChecked = checked; - - callChangeListener(checked); - notifyDependencyChange(shouldDisableDependents()); - notifyChanged(); - } - } - - private void setCollapse(boolean isCollapsed) { - if (mCollapsed == isCollapsed) { - return; - } - - mCollapsed = isCollapsed; - if (isCollapsed) { - hideDropdownPreferences(); - } else { - showDropdownPreferences(); - } - } - - private void showDropdownPreferences() { - setAllPreferencesVisibility(true); - setIcon(R.drawable.ic_keyboard_arrow_down_black_32); - } - - private void hideDropdownPreferences() { - setAllPreferencesVisibility(false); - setIcon(R.drawable.ic_keyboard_arrow_up_black_32); - } - - private void setAllPreferencesVisibility(boolean visible) { - for (int i = 0; i < getPreferenceCount(); i++) { - Preference p = getPreference(i); - p.setVisible(visible); - } - } -} diff --git a/src/com/android/settings/DeletionPreference.java b/src/com/android/settings/DeletionPreference.java deleted file mode 100644 index 93d76e6d9ad..00000000000 --- a/src/com/android/settings/DeletionPreference.java +++ /dev/null @@ -1,117 +0,0 @@ -/* - * 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; - -import android.content.Context; -import android.content.res.Resources; -import android.graphics.drawable.Drawable; -import android.support.v7.preference.Preference; -import android.support.v7.preference.Preference.OnPreferenceChangeListener; -import android.support.v7.preference.CheckBoxPreference; -import android.support.v7.preference.PreferenceViewHolder; -import android.util.AttributeSet; -import android.util.TypedValue; -import android.text.format.Formatter; -import android.widget.TextView; -import com.android.settings.deletionhelper.DeletionType; - -/** - * Preference to handle the deletion of various data types in the Deletion Helper. - */ -public abstract class DeletionPreference extends CheckBoxPreference implements - DeletionType.FreeableChangedListener, OnPreferenceChangeListener { - private DeletionType.FreeableChangedListener mListener; - private boolean mChecked; - private long mFreeableBytes; - private int mFreeableItems; - private DeletionType mDeletionService; - - public DeletionPreference(Context context, AttributeSet attrs) { - super(context, attrs); - setOnPreferenceChangeListener(this); - } - - @Override - public void onBindViewHolder(PreferenceViewHolder holder) { - super.onBindViewHolder(holder); - final TextView titleView = (TextView) holder.findViewById(android.R.id.title); - if (titleView != null) { - titleView.setTextColor(getTintColor(getContext())); - } - } - - /** - * Returns the number of bytes which can be cleared by the deletion service. - * @return The number of bytes. - */ - public long getFreeableBytes() { - return mChecked ? mFreeableBytes : 0; - } - - /** - * Register a listener to be called back on when the freeable bytes have changed. - * @param listener The callback listener. - */ - public void registerFreeableChangedListener(DeletionType.FreeableChangedListener listener) { - mListener = listener; - } - - /** - * Registers a deletion service to update the preference's information. - * @param deletionService A photo/video deletion service. - */ - public void registerDeletionService(DeletionType deletionService) { - mDeletionService = deletionService; - if (mDeletionService != null) { - mDeletionService.registerFreeableChangedListener(this); - } - } - - /** - * Returns the deletion service powering the preference. - * @return The deletion service. - */ - public DeletionType getDeletionService() { - return mDeletionService; - } - - @Override - public void onFreeableChanged(int numItems, long freeableBytes) { - mFreeableItems = numItems; - mFreeableBytes = freeableBytes; - maybeUpdateListener(); - } - - @Override - public boolean onPreferenceChange(Preference preference, Object newValue) { - mChecked = (boolean) newValue; - maybeUpdateListener(); - return true; - } - - private int getTintColor(Context context) { - TypedValue value = new TypedValue(); - context.getTheme().resolveAttribute(android.R.attr.colorAccent, value, true); - return context.getColor(value.resourceId); - } - - private void maybeUpdateListener() { - if (mListener != null) { - mListener.onFreeableChanged(mFreeableItems, getFreeableBytes()); - } - } -} diff --git a/src/com/android/settings/PhotosDeletionPreference.java b/src/com/android/settings/PhotosDeletionPreference.java deleted file mode 100644 index 643b3f131a5..00000000000 --- a/src/com/android/settings/PhotosDeletionPreference.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * 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; - -import android.content.Context; -import android.content.res.Resources; -import android.graphics.drawable.Drawable; -import android.util.AttributeSet; -import android.text.format.Formatter; - -/** - * Preference to handle the deletion of photos and videos in the Deletion Helper. - */ -public class PhotosDeletionPreference extends DeletionPreference { - public static final int DAYS_TO_KEEP = 30; - - public PhotosDeletionPreference(Context context, AttributeSet attrs) { - super(context, attrs); - setIcon(getIcon(context)); - updatePreferenceText(0, 0); - } - - /** - * Updates the title and summary of the preference with fresh information. - */ - public void updatePreferenceText(int items, long bytes) { - Context context = getContext(); - setTitle(context.getString(R.string.deletion_helper_photos_title, items)); - setSummary(context.getString(R.string.deletion_helper_photos_summary, - Formatter.formatFileSize(context, bytes), DAYS_TO_KEEP)); - } - - @Override - public void onFreeableChanged(int items, long bytes) { - super.onFreeableChanged(items, bytes); - updatePreferenceText(items, bytes); - } - - private Drawable getIcon(Context context) { - final Drawable iconDrawable; - try { - Resources resources = context.getResources(); - final int resId = resources.getIdentifier("ic_photos_black_24", "drawable", - context.getPackageName()); - iconDrawable = context.getDrawable(resId); - } catch (Resources.NotFoundException e) { - return null; - } - return iconDrawable; - } -} diff --git a/src/com/android/settings/SettingsActivity.java b/src/com/android/settings/SettingsActivity.java index 9cd9e516d42..c08a7908df1 100644 --- a/src/com/android/settings/SettingsActivity.java +++ b/src/com/android/settings/SettingsActivity.java @@ -74,7 +74,6 @@ import com.android.settings.bluetooth.BluetoothSettings; import com.android.settings.dashboard.DashboardContainerFragment; import com.android.settings.dashboard.SearchResultsSummary; import com.android.settings.datausage.DataUsageSummary; -import com.android.settings.deletionhelper.DeletionHelperFragment; import com.android.settings.deviceinfo.ImeiInformation; import com.android.settings.deviceinfo.PrivateVolumeForget; import com.android.settings.deviceinfo.PrivateVolumeSettings; @@ -343,7 +342,6 @@ public class SettingsActivity extends SettingsDrawerActivity WallpaperTypeSettings.class.getName(), VrListenerSettings.class.getName(), ManagedProfileSettings.class.getName(), - DeletionHelperFragment.class.getName(), ChooseAccountActivity.class.getName(), IccLockSettings.class.getName(), ImeiInformation.class.getName(), diff --git a/src/com/android/settings/deletionhelper/AppDeletionPreference.java b/src/com/android/settings/deletionhelper/AppDeletionPreference.java deleted file mode 100644 index 97420c29518..00000000000 --- a/src/com/android/settings/deletionhelper/AppDeletionPreference.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * 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.deletionhelper; - -import android.content.Context; -import android.support.v14.preference.SwitchPreference; -import android.support.v7.preference.Preference; -import android.support.v7.preference.PreferenceViewHolder; -import android.text.format.Formatter; -import android.view.View; -import android.widget.Switch; -import android.widget.TextView; -import com.android.settings.deletionhelper.AppStateUsageStatsBridge.UsageStatsState; -import com.android.settings.R; - -import com.android.settingslib.applications.ApplicationsState; -import com.android.settingslib.applications.ApplicationsState.AppEntry; - -/** - * Preference item for an app with a switch to signify if it should be uninstalled. - * This shows the name and icon of the app along with the days since its last use. - */ -public class AppDeletionPreference extends SwitchPreference { - private AppEntry mEntry; - private Context mContext; - - public AppDeletionPreference(Context context, AppEntry item, ApplicationsState state) { - super(context); - mEntry = item; - mContext = context; - setLayoutResource(com.android.settings.R.layout.preference_app); - setWidgetLayoutResource(R.layout.widget_text_views); - - synchronized (item) { - state.ensureIcon(item); - if (item.icon != null) - setIcon(item.icon); - if (item.label != null) - setTitle(item.label); - } - } - - @Override - public void onBindViewHolder(PreferenceViewHolder holder) { - super.onBindViewHolder(holder); - Switch switchWidget = (Switch) holder.findViewById(com.android.internal.R.id.switch_widget); - switchWidget.setVisibility(View.VISIBLE); - - TextView summary = (TextView) holder.findViewById(R.id.widget_text1); - updateSummaryText(summary); - } - - public String getPackageName() { - return mEntry.label; - } - - private void updateSummaryText(TextView summary) { - if (mEntry.extraInfo == null) return; - if (mEntry.size == ApplicationsState.SIZE_UNKNOWN || - mEntry.size == ApplicationsState.SIZE_INVALID) { - return; - } - - UsageStatsState extraData = (UsageStatsState) mEntry.extraInfo; - String fileSize = Formatter.formatFileSize(mContext, mEntry.size); - if (extraData.daysSinceLastUse == AppStateUsageStatsBridge.NEVER_USED) { - summary.setText(mContext.getString(R.string.deletion_helper_app_summary_never_used, - fileSize)); - } else if (extraData.daysSinceLastUse == AppStateUsageStatsBridge.UNKNOWN_LAST_USE) { - summary.setText(mContext.getString(R.string.deletion_helper_app_summary_unknown_used, - fileSize)); - } else { - summary.setText(mContext.getString(R.string.deletion_helper_app_summary, - fileSize, - extraData.daysSinceLastUse)); - } - } - -} diff --git a/src/com/android/settings/deletionhelper/AppStateUsageStatsBridge.java b/src/com/android/settings/deletionhelper/AppStateUsageStatsBridge.java deleted file mode 100644 index 6f77a2999dd..00000000000 --- a/src/com/android/settings/deletionhelper/AppStateUsageStatsBridge.java +++ /dev/null @@ -1,152 +0,0 @@ -/* - * 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.deletionhelper; - -import android.app.usage.UsageStats; -import android.app.usage.UsageStatsManager; -import android.content.Context; -import android.content.pm.ApplicationInfo; - -import android.content.pm.PackageInfo; -import android.content.pm.PackageManager; -import android.util.Log; -import com.android.settings.applications.AppStateBaseBridge; -import com.android.settingslib.applications.ApplicationsState; -import com.android.settingslib.applications.ApplicationsState.AppEntry; -import com.android.settingslib.applications.ApplicationsState.AppFilter; - -import java.util.ArrayList; -import java.util.Map; -import java.util.concurrent.TimeUnit; - -/** - * Connects data from the UsageStatsManager to the ApplicationsState. - */ -public class AppStateUsageStatsBridge extends AppStateBaseBridge { - private static final String TAG = "AppStateUsageStatsBridge"; - private UsageStatsManager mUsageStatsManager; - private PackageManager mPm; - public static final long NEVER_USED = -1; - public static final long UNKNOWN_LAST_USE = -2; - public static final long UNUSED_DAYS_DELETION_THRESHOLD = 60; - - public AppStateUsageStatsBridge(Context context, ApplicationsState appState, - Callback callback) { - super(appState, callback); - mUsageStatsManager = - (UsageStatsManager) context.getSystemService(Context.USAGE_STATS_SERVICE); - mPm = context.getPackageManager(); - } - - @Override - protected void loadAllExtraInfo() { - ArrayList apps = mAppSession.getAllApps(); - if (apps == null) return; - - final Map map = mUsageStatsManager.queryAndAggregateUsageStats(0, - System.currentTimeMillis()); - for (AppEntry entry : apps) { - UsageStats usageStats = map.get(entry.info.packageName); - entry.extraInfo = new UsageStatsState(getDaysSinceLastUse(usageStats), - getDaysSinceInstalled(entry.info.packageName)); - } - } - - @Override - protected void updateExtraInfo(AppEntry app, String pkg, int uid) { - Map map = mUsageStatsManager.queryAndAggregateUsageStats(0, - System.currentTimeMillis()); - UsageStats usageStats = map.get(app.info.packageName); - app.extraInfo = new UsageStatsState(getDaysSinceLastUse(usageStats), - getDaysSinceInstalled(app.info.packageName)); - } - - private long getDaysSinceLastUse(UsageStats stats) { - if (stats == null) { - return NEVER_USED; - } - long lastUsed = stats.getLastTimeUsed(); - // Sometimes, a usage is recorded without a time and we don't know when the use was. - if (lastUsed == 0) { - return UNKNOWN_LAST_USE; - } - return TimeUnit.MILLISECONDS.toDays(System.currentTimeMillis() - lastUsed); - } - - private long getDaysSinceInstalled(String packageName) { - PackageInfo pi = null; - try { - pi = mPm.getPackageInfo(packageName, 0); - } catch (PackageManager.NameNotFoundException e) { - Log.e(TAG, packageName + " was not found."); - } - - if (pi == null) { - return NEVER_USED; - } - - return (TimeUnit.MILLISECONDS.toDays(System.currentTimeMillis() - pi.firstInstallTime)); - } - - /** - * Filters only non-system apps which haven't been used in the last 60 days. If an app's last - * usage is unknown, it is skipped. - */ - public static final AppFilter FILTER_USAGE_STATS = new AppFilter() { - - @Override - public void init() { - } - - @Override - public boolean filterApp(AppEntry info) { - if (info == null) return false; - return isExtraInfoValid(info.extraInfo) && !isBundled(info) - && !isPersistentProcess(info); - } - - private boolean isExtraInfoValid(Object extraInfo) { - if (extraInfo == null || !(extraInfo instanceof UsageStatsState)) { - return false; - } - - UsageStatsState state = (UsageStatsState) extraInfo; - long mostRecentUse = Math.max(state.daysSinceFirstInstall, state.daysSinceLastUse); - return mostRecentUse >= UNUSED_DAYS_DELETION_THRESHOLD || mostRecentUse == NEVER_USED; - } - - private boolean isBundled(AppEntry info) { - return (info.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; - } - - private boolean isPersistentProcess(AppEntry info) { - return (info.info.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; - } - }; - - /** - * UsageStatsState contains the days since the last use and first install of a given app. - */ - public static class UsageStatsState { - public long daysSinceLastUse; - public long daysSinceFirstInstall; - - public UsageStatsState(long daysSinceLastUse, long daysSinceFirstInstall) { - this.daysSinceLastUse = daysSinceLastUse; - this.daysSinceFirstInstall = daysSinceFirstInstall; - } - } -} diff --git a/src/com/android/settings/deletionhelper/AutomaticStorageBroadcastReceiver.java b/src/com/android/settings/deletionhelper/AutomaticStorageBroadcastReceiver.java deleted file mode 100644 index e7b04693083..00000000000 --- a/src/com/android/settings/deletionhelper/AutomaticStorageBroadcastReceiver.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * 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.deletionhelper; - -import android.app.job.JobInfo; -import android.app.job.JobScheduler; -import android.content.BroadcastReceiver; -import android.content.ComponentName; -import android.content.Context; -import android.content.Intent; -import android.text.format.DateUtils; - -/** - * A {@link BroadcastReceiver} listening for {@link Intent#ACTION_BOOT_COMPLETED} broadcasts to - * schedule an automatic storage management job. Automatic storage management jobs are only - * scheduled once a day for a plugged in device. - */ -public class AutomaticStorageBroadcastReceiver extends BroadcastReceiver { - private static final int AUTOMATIC_STORAGE_JOB_ID = 0; - private static final long PERIOD = DateUtils.DAY_IN_MILLIS; - - @Override - public void onReceive(Context context, Intent intent) { - JobScheduler jobScheduler = - (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE); - ComponentName component = new ComponentName(context, - AutomaticStorageManagementJobService.class); - JobInfo job = new JobInfo.Builder(AUTOMATIC_STORAGE_JOB_ID, component) - .setRequiresCharging(true) - .setRequiresDeviceIdle(true) - .setPeriodic(PERIOD) - .build(); - jobScheduler.schedule(job); - } -} diff --git a/src/com/android/settings/deletionhelper/AutomaticStorageManagementJobService.java b/src/com/android/settings/deletionhelper/AutomaticStorageManagementJobService.java deleted file mode 100644 index 990e328f51f..00000000000 --- a/src/com/android/settings/deletionhelper/AutomaticStorageManagementJobService.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * 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.deletionhelper; - -import android.app.job.JobParameters; -import android.app.job.JobService; -import android.content.Context; -import android.content.SharedPreferences; -import android.os.storage.StorageManager; -import android.os.storage.VolumeInfo; -import android.provider.Settings; -import android.util.Log; -import com.android.settings.overlay.FeatureFactory; -import com.android.settings.overlay.StorageManagementJobProvider; - -import java.io.File; - -/** - * {@link JobService} class to start automatic storage clearing jobs to free up space. The job only - * starts if the device is under a certain percent of free storage. - */ -public class AutomaticStorageManagementJobService extends JobService { - private static final String TAG = "AsmJobService"; - private static final String SHARED_PREFRENCES_NAME = "automatic_storage_manager_settings"; - private static final String KEY_DAYS_TO_RETAIN = "days_to_retain"; - - private static final long DEFAULT_LOW_FREE_PERCENT = 15; - - private StorageManagementJobProvider mProvider; - - @Override - public boolean onStartJob(JobParameters args) { - boolean isEnabled = - Settings.Secure.getInt(getContentResolver(), - Settings.Secure.AUTOMATIC_STORAGE_MANAGER_ENABLED, 0) != 0; - if (!isEnabled) { - return false; - } - - StorageManager manager = getSystemService(StorageManager.class); - VolumeInfo internalVolume = manager.findVolumeById(VolumeInfo.ID_PRIVATE_INTERNAL); - - final File dataPath = internalVolume.getPath(); - if (!volumeNeedsManagement(dataPath)) { - Log.i(TAG, "Skipping automatic storage management."); - return false; - } - mProvider = FeatureFactory.getFactory(this).getStorageManagementJobProvider(); - if (mProvider != null) { - return mProvider.onStartJob(this, args, getDaysToRetain()); - } - - return false; - } - - @Override - public boolean onStopJob(JobParameters args) { - if (mProvider != null) { - return mProvider.onStopJob(this, args); - } - - return false; - } - - private int getDaysToRetain() { - SharedPreferences sharedPreferences = - getSharedPreferences(SHARED_PREFRENCES_NAME, Context.MODE_PRIVATE); - return sharedPreferences.getInt(KEY_DAYS_TO_RETAIN, - AutomaticStorageManagerSettings.DEFAULT_DAYS_TO_RETAIN); - } - - private boolean volumeNeedsManagement(final File dataPath) { - long lowStorageThreshold = (dataPath.getTotalSpace() * DEFAULT_LOW_FREE_PERCENT) / 100; - return dataPath.getFreeSpace() < lowStorageThreshold; - } -} \ No newline at end of file diff --git a/src/com/android/settings/deletionhelper/AutomaticStorageManagerSettings.java b/src/com/android/settings/deletionhelper/AutomaticStorageManagerSettings.java index 670eed10673..4946016603f 100644 --- a/src/com/android/settings/deletionhelper/AutomaticStorageManagerSettings.java +++ b/src/com/android/settings/deletionhelper/AutomaticStorageManagerSettings.java @@ -18,6 +18,7 @@ package com.android.settings.deletionhelper; import android.app.Activity; import android.content.Context; +import android.content.Intent; import android.content.res.Resources; import android.os.Bundle; import android.provider.Settings; @@ -115,8 +116,8 @@ public class AutomaticStorageManagerSettings extends SettingsPreferenceFragment @Override public boolean onPreferenceClick(Preference preference) { if (KEY_DELETION_HELPER.equals(preference.getKey())) { - startFragment(this, DeletionHelperFragment.class.getCanonicalName(), - R.string.deletion_helper_title, 0, null); + Intent intent = new Intent(Settings.ACTION_DELETION_HELPER_SETTINGS); + getContext().startActivity(intent); } return true; } diff --git a/src/com/android/settings/deletionhelper/ConfirmDeletionDialog.java b/src/com/android/settings/deletionhelper/ConfirmDeletionDialog.java deleted file mode 100644 index fc6033e9341..00000000000 --- a/src/com/android/settings/deletionhelper/ConfirmDeletionDialog.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * 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.deletionhelper; - -import android.app.AlertDialog; -import android.app.Dialog; -import android.app.DialogFragment; -import android.content.Context; -import android.content.DialogInterface; -import android.os.Bundle; -import android.text.format.Formatter; -import com.android.settings.R; - -/** - * Fragment used to confirm that the user wishes to delete a certain amount of data. - */ -public class ConfirmDeletionDialog extends DialogFragment implements - DialogInterface.OnClickListener { - public static final String TAG = "ConfirmDeletionDialog"; - private static final String ARG_TOTAL_SPACE = "total_freeable"; - - public static ConfirmDeletionDialog newInstance(long freeableBytes) { - Bundle args = new Bundle(1); - args.putLong(ARG_TOTAL_SPACE, freeableBytes); - - ConfirmDeletionDialog dialog = new ConfirmDeletionDialog(); - dialog.setArguments(args); - - return dialog; - } - - @Override - public Dialog onCreateDialog(Bundle savedInstanceState) { - final Bundle args = getArguments(); - long totalFreeableSpace = args.getLong(ARG_TOTAL_SPACE); - - final Context context = getContext(); - return new AlertDialog.Builder(context) - .setMessage(context.getString(R.string.deletion_helper_clear_dialog_message, - Formatter.formatFileSize(context, totalFreeableSpace))) - .setPositiveButton(R.string.deletion_helper_clear_dialog_remove, this) - .setNegativeButton(android.R.string.cancel, null) - .create(); - } - - @Override - public void onClick(DialogInterface dialog, int which) { - ((DeletionHelperFragment) getTargetFragment()).clearData(); - } -} diff --git a/src/com/android/settings/deletionhelper/DeletionHelperFragment.java b/src/com/android/settings/deletionhelper/DeletionHelperFragment.java deleted file mode 100644 index 9e1d0ea873b..00000000000 --- a/src/com/android/settings/deletionhelper/DeletionHelperFragment.java +++ /dev/null @@ -1,415 +0,0 @@ -/* - * 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.deletionhelper; - -import android.app.Activity; -import android.app.Application; -import android.content.Intent; -import android.os.Bundle; -import android.support.v7.preference.Preference; -import android.text.format.Formatter; -import android.util.ArraySet; -import android.util.Log; -import android.view.View; -import android.widget.Button; -import com.android.settings.CollapsibleCheckboxPreferenceGroup; -import com.android.settings.PhotosDeletionPreference; -import com.android.settings.SettingsPreferenceFragment; -import com.android.settings.R; -import com.android.internal.logging.MetricsProto.MetricsEvent; -import com.android.settings.applications.AppStateBaseBridge; -import com.android.settings.overlay.DeletionHelperFeatureProvider; -import com.android.settings.overlay.FeatureFactory; -import com.android.settingslib.applications.ApplicationsState; -import com.android.settingslib.applications.ApplicationsState.AppEntry; -import com.android.settingslib.applications.ApplicationsState.Callbacks; -import com.android.settingslib.applications.ApplicationsState.Session; - -import java.util.ArrayList; -import java.util.HashSet; - -/** - * Settings screen for the deletion helper, which manually removes data which is not recently used. - */ -public class DeletionHelperFragment extends SettingsPreferenceFragment implements - ApplicationsState.Callbacks, AppStateBaseBridge.Callback, - Preference.OnPreferenceChangeListener, DeletionType.FreeableChangedListener, - View.OnClickListener { - public static final int CLEAR_DATA_RESULT = 1; - public static final String FREED_BYTES_KEY = "freed"; - - private static final String TAG = "DeletionHelperFragment"; - - private static final String EXTRA_HAS_BRIDGE = "hasBridge"; - private static final String EXTRA_HAS_SIZES = "hasSizes"; - private static final String EXTRA_CHECKED_SET = "checkedSet"; - - private static final String KEY_APPS_GROUP = "apps_group"; - private static final String KEY_PHOTOS_VIDEOS_PREFERENCE = "delete_photos"; - private static final String KEY_DOWNLOADS_PREFERENCE = "delete_downloads"; - - private static final int DOWNLOADS_LOADER_ID = 1; - - private Button mCancel, mFree; - private CollapsibleCheckboxPreferenceGroup mApps; - private PhotosDeletionPreference mPhotoPreference; - private DownloadsDeletionPreferenceGroup mDownloadsPreference; - - private ApplicationsState mState; - private Session mSession; - private HashSet mCheckedApplications; - private AppStateUsageStatsBridge mDataUsageBridge; - private ArrayList mAppEntries; - private boolean mHasReceivedAppEntries, mHasReceivedBridgeCallback, mFinishedLoading; - private DeletionHelperFeatureProvider mProvider; - private DeletionType mPhotoVideoDeletion; - private DownloadsDeletionType mDownloadsDeletion; - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setAnimationAllowed(true); - Application app = getActivity().getApplication(); - mState = ApplicationsState.getInstance(app); - mSession = mState.newSession(this); - mCheckedApplications = new HashSet<>(); - mDataUsageBridge = new AppStateUsageStatsBridge(getActivity(), mState, this); - - addPreferencesFromResource(R.xml.deletion_helper_list); - mApps = (CollapsibleCheckboxPreferenceGroup) findPreference(KEY_APPS_GROUP); - mPhotoPreference = (PhotosDeletionPreference) findPreference(KEY_PHOTOS_VIDEOS_PREFERENCE); - mDownloadsPreference = - (DownloadsDeletionPreferenceGroup) findPreference(KEY_DOWNLOADS_PREFERENCE); - mProvider = - FeatureFactory.getFactory(app).getDeletionHelperFeatureProvider(); - if (mProvider != null) { - mPhotoVideoDeletion = mProvider.createPhotoVideoDeletionType(getContext()); - } - mDownloadsDeletion = new DownloadsDeletionType(getActivity()); - - if (savedInstanceState != null) { - mHasReceivedAppEntries = - savedInstanceState.getBoolean(EXTRA_HAS_SIZES, false); - mHasReceivedBridgeCallback = - savedInstanceState.getBoolean(EXTRA_HAS_BRIDGE, false); - mCheckedApplications = - (HashSet) savedInstanceState.getSerializable(EXTRA_CHECKED_SET); - } - } - - private void initializeButtons(View v) { - mCancel = (Button) v.findViewById(R.id.skip_button); - mCancel.setText(R.string.cancel); - mCancel.setOnClickListener(this); - mCancel.setVisibility(View.VISIBLE); - - mFree = (Button) v.findViewById(R.id.next_button); - mFree.setText(R.string.storage_menu_free); - mFree.setOnClickListener(this); - - Button back = (Button) v.findViewById(R.id.back_button); - back.setVisibility(View.GONE); - } - - private void initializeDeletionPreferences() { - if (mProvider == null) { - getPreferenceScreen().removePreference(mPhotoPreference); - mPhotoPreference = null; - } else { - mPhotoPreference.registerFreeableChangedListener(this); - mPhotoPreference.registerDeletionService(mPhotoVideoDeletion); - } - - mDownloadsPreference.registerFreeableChangedListener(this); - mDownloadsPreference.registerDeletionService(mDownloadsDeletion); - mApps.setOnPreferenceChangeListener(this); - } - - @Override - public void onViewCreated(View v, Bundle savedInstanceState) { - super.onViewCreated(v, savedInstanceState); - initializeButtons(v); - initializeDeletionPreferences(); - setLoading(true, false); - } - - @Override - public void onResume() { - super.onResume(); - mSession.resume(); - mDataUsageBridge.resume(); - mDownloadsDeletion.onResume(); - getLoaderManager().initLoader(DOWNLOADS_LOADER_ID, new Bundle(), mDownloadsDeletion); - - if (mPhotoVideoDeletion != null) { - mPhotoVideoDeletion.onResume(); - } - } - - - @Override - public void onSaveInstanceState(Bundle outState) { - super.onSaveInstanceState(outState); - outState.putBoolean(EXTRA_HAS_SIZES, mHasReceivedAppEntries); - outState.putBoolean(EXTRA_HAS_BRIDGE, mHasReceivedBridgeCallback); - outState.putSerializable(EXTRA_CHECKED_SET, mCheckedApplications); - } - - - @Override - public void onPause() { - super.onPause(); - mDataUsageBridge.pause(); - mSession.pause(); - mDownloadsDeletion.onPause(); - - if (mPhotoVideoDeletion != null) { - mPhotoVideoDeletion.onPause(); - } - } - - private void rebuild() { - // Only rebuild if we have the packages and their usage stats. - if (!mHasReceivedBridgeCallback || !mHasReceivedAppEntries) { - return; - } - - final ArrayList apps = - mSession.rebuild(AppStateUsageStatsBridge.FILTER_USAGE_STATS, - ApplicationsState.SIZE_COMPARATOR); - if (apps == null) return; - mAppEntries = apps; - refreshAppGroup(apps); - - // All applications should be filled in if we've received the sizes. - // setLoading being called multiple times causes flickering, so we only do it once. - if (mHasReceivedAppEntries && !mFinishedLoading) { - mFinishedLoading = true; - setLoading(false, true); - getButtonBar().setVisibility(View.VISIBLE); - } - updateFreeButtonText(); - } - - private void updateFreeButtonText() { - mFree.setText(String.format(getActivity().getString(R.string.deletion_helper_free_button), - Formatter.formatFileSize(getActivity(), getTotalFreeableSpace()))); - } - - @Override - public void onRunningStateChanged(boolean running) { - // No-op. - } - - @Override - public void onPackageListChanged() { - rebuild(); - } - - @Override - public void onRebuildComplete(ArrayList apps) { - } - - @Override - public void onPackageIconChanged() { - } - - @Override - public void onPackageSizeChanged(String packageName) { - rebuild(); - } - - @Override - public void onAllSizesComputed() { - rebuild(); - } - - @Override - public void onLauncherInfoChanged() { - } - - @Override - public void onLoadEntriesCompleted() { - mHasReceivedAppEntries = true; - rebuild(); - } - - @Override - public void onExtraInfoUpdated() { - mHasReceivedBridgeCallback = true; - rebuild(); - } - - @Override - protected int getMetricsCategory() { - return MetricsEvent.DEVICEINFO_STORAGE; - } - - @Override - public boolean onPreferenceChange(Preference preference, Object newValue) { - boolean checked = (boolean) newValue; - if (preference.getKey().equals(mApps.getKey())) { - return toggleAllApps(checked); - } - - String packageName = ((AppDeletionPreference) preference).getPackageName(); - if (checked) { - mCheckedApplications.add(packageName); - } else { - mCheckedApplications.remove(packageName); - - // We remove the preference change listener to avoid toggling every app on and off. - mApps.setOnPreferenceChangeListener(null); - mApps.setChecked(false); - mApps.setOnPreferenceChangeListener(this); - } - updateFreeButtonText(); - return true; - } - - @Override - public void onFreeableChanged(int numItems, long freeableBytes) { - updateFreeButtonText(); - } - - @Override - public void onClick(View v) { - if (v.getId() == mFree.getId()) { - ConfirmDeletionDialog dialog = - ConfirmDeletionDialog.newInstance(getTotalFreeableSpace()); - // The 0 is a placeholder for an optional result code. - dialog.setTargetFragment(this, 0); - dialog.show(getFragmentManager(), ConfirmDeletionDialog.TAG); - } else { - finishFragment(); - } - } - - /** - * Clears out the selected apps and data from the device and closes the fragment. - */ - protected void clearData() { - // This should be fine as long as there is only one extra deletion feature. - // In the future, this should be done in an async queue in order to not - // interfere with the simultaneous PackageDeletionTask. - if (mPhotoPreference != null && mPhotoPreference.isChecked()) { - mPhotoVideoDeletion.clearFreeableData(); - } - mDownloadsDeletion.clearFreeableData(); - - ArraySet apps = new ArraySet<>(); - for (AppEntry entry : mAppEntries) { - if (mCheckedApplications.contains(entry.label)) { - synchronized (entry) { - apps.add(entry.info.packageName); - } - } - } - // TODO: If needed, add an action on the callback. - PackageDeletionTask task = new PackageDeletionTask(getActivity().getPackageManager(), apps, - new PackageDeletionTask.Callback() { - @Override - public void onSuccess() { - } - - @Override - public void onError() { - Log.e(TAG, "An error occurred while uninstalling packages."); - } - }); - Intent data = new Intent(); - data.putExtra(FREED_BYTES_KEY, getTotalFreeableSpace()); - getActivity().setResult(CLEAR_DATA_RESULT, data); - - task.run(); - finishFragment(); - } - - private long getTotalFreeableSpace() { - long freeableSpace = 0; - freeableSpace += getTotalAppsFreeableSpace(false); - if (mPhotoPreference != null) { - freeableSpace += mPhotoPreference.getFreeableBytes(); - } - freeableSpace += mDownloadsDeletion.getFreeableBytes(); - return freeableSpace; - } - - private void refreshAppGroup(ArrayList apps) { - int entryCount = apps.size(); - cacheRemoveAllPrefs(mApps); - for (int i = 0; i < entryCount; i++) { - AppEntry entry = apps.get(i); - final String packageName = entry.label; - AppDeletionPreference preference = - (AppDeletionPreference) getCachedPreference(entry.label); - if (preference == null) { - preference = new AppDeletionPreference(getActivity(), entry, mState); - preference.setKey(packageName); - preference.setOnPreferenceChangeListener(this); - mApps.addPreference(preference); - } - preference.setChecked(mCheckedApplications.contains(packageName)); - preference.setOrder(i); - } - removeCachedPrefs(mApps); - updateAppsGroupText(); - } - - private long getTotalAppsFreeableSpace(boolean countUnchecked) { - long freeableSpace = 0; - if (mAppEntries != null) { - for (int i = 0; i < mAppEntries.size(); i++) { - final AppEntry entry = mAppEntries.get(i); - long entrySize = mAppEntries.get(i).size; - // If the entrySize is negative, it is either an unknown size or an error occurred. - if ((countUnchecked || - mCheckedApplications.contains(entry.label)) && entrySize > 0) { - freeableSpace += entrySize; - } - } - } - - return freeableSpace; - } - - private void updateAppsGroupText() { - if (mAppEntries != null) { - Activity app = getActivity(); - mApps.setTitle(app.getString(R.string.deletion_helper_apps_group_title, - mAppEntries.size())); - mApps.setSummary(app.getString(R.string.deletion_helper_apps_group_summary, - Formatter.formatFileSize(app, - getTotalAppsFreeableSpace(true)), - AppStateUsageStatsBridge.UNUSED_DAYS_DELETION_THRESHOLD)); - } - } - - private boolean toggleAllApps(boolean checked) { - for (AppEntry entry : mAppEntries) { - final String packageName = entry.label; - if (checked) { - mCheckedApplications.add(packageName); - } else { - mCheckedApplications.remove(packageName); - } - } - refreshAppGroup(mAppEntries); - updateFreeButtonText(); - return true; - } -} \ No newline at end of file diff --git a/src/com/android/settings/deletionhelper/DeletionType.java b/src/com/android/settings/deletionhelper/DeletionType.java deleted file mode 100644 index ee1e0f7a80f..00000000000 --- a/src/com/android/settings/deletionhelper/DeletionType.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * 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.deletionhelper; - -import android.content.Context; -import android.support.v7.preference.PreferenceGroup; -import android.support.v7.preference.Preference; - -/** - * Helper for the Deletion Helper which can query, clear out, and visualize deletable data. - * This could represent a helper for deleting photos, downloads, movies, etc. - */ -public interface DeletionType { - /** - * Registers a callback to call when the amount of freeable space is updated. - * @param listener A callback. - */ - void registerFreeableChangedListener(FreeableChangedListener listener); - - /** - * Resumes an operation, intended to be called when the deletion fragment resumes. - */ - void onResume(); - - /** - * Pauses the feature's operations, intended to be called when the deletion fragment is paused. - */ - void onPause(); - - /** - * Asynchronously free up the freeable information for the feature. - */ - void clearFreeableData(); - - /** - * Callback interface to listen for when a deletion feature's amount of freeable space updates. - */ - interface FreeableChangedListener { - void onFreeableChanged(int numItems, long bytesFreeable); - } -} diff --git a/src/com/android/settings/deletionhelper/DownloadsDeletionPreferenceGroup.java b/src/com/android/settings/deletionhelper/DownloadsDeletionPreferenceGroup.java deleted file mode 100644 index 440b96248df..00000000000 --- a/src/com/android/settings/deletionhelper/DownloadsDeletionPreferenceGroup.java +++ /dev/null @@ -1,157 +0,0 @@ -/* - * 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.deletionhelper; - -import android.content.Context; -import android.support.v7.preference.Preference; -import android.text.format.DateUtils; -import android.text.format.Formatter; -import android.util.ArrayMap; -import android.util.AttributeSet; -import com.android.settings.CollapsibleCheckboxPreferenceGroup; -import com.android.settings.R; - -import java.io.File; -import java.util.Set; - -/** - * DownloadsDeletionPreferenceGroup defines a checkable preference group which contains - * downloads file deletion preferences. - */ -public class DownloadsDeletionPreferenceGroup extends CollapsibleCheckboxPreferenceGroup - implements DeletionType.FreeableChangedListener, Preference.OnPreferenceChangeListener { - private DownloadsDeletionType mDeletionType; - private DeletionType.FreeableChangedListener mListener; - - public DownloadsDeletionPreferenceGroup(Context context) { - this(context, null); - } - - public DownloadsDeletionPreferenceGroup(Context context, AttributeSet attrs) { - super(context, attrs); - setOrderingAsAdded(false); - setOnPreferenceChangeListener(this); - } - - /** - * Set up a deletion type to get info for the preference group. - * @param type A {@link DownloadsDeletionType}. - */ - public void registerDeletionService(DownloadsDeletionType type) { - mDeletionType = type; - mDeletionType.registerFreeableChangedListener(this); - } - - /** - * Registers a callback to be called when the amount of freeable space updates. - * @param listener The callback listener. - */ - public void registerFreeableChangedListener(DeletionType.FreeableChangedListener listener) { - mListener = listener; - } - - @Override - public void onFreeableChanged(int numItems, long freeableBytes) { - updatePreferenceText(numItems, freeableBytes, mDeletionType.getMostRecentLastModified()); - maybeUpdateListener(numItems, freeableBytes); - updateFiles(); - } - - @Override - public boolean onPreferenceChange(Preference preference, Object newValue) { - boolean checked = (boolean) newValue; - if (!checked) { - // Temporarily stop listening to avoid propagating the checked change to children. - setOnPreferenceChangeListener(null); - setChecked(false); - setOnPreferenceChangeListener(this); - } - - // If the group checkbox changed, we need to toggle every child preference. - if (preference == this) { - for (int i = 0; i < getPreferenceCount(); i++) { - DownloadsFilePreference p = (DownloadsFilePreference) getPreference(i); - p.setOnPreferenceChangeListener(null); - mDeletionType.toggleFile(p.getFile(), checked); - p.setChecked(checked); - p.setOnPreferenceChangeListener(this); - } - maybeUpdateListener(mDeletionType.getFiles().size(), mDeletionType.getFreeableBytes()); - return true; - } - - // If a single DownloadFilePreference changed, we need to toggle just itself. - DownloadsFilePreference p = (DownloadsFilePreference) preference; - mDeletionType.toggleFile(p.getFile(), checked); - maybeUpdateListener(mDeletionType.getFiles().size(), mDeletionType.getFreeableBytes()); - return true; - } - - - private void updatePreferenceText(int itemCount, long bytes, long mostRecent) { - Context context = getContext(); - setTitle(context.getString(R.string.deletion_helper_downloads_title, itemCount)); - // If there are no files to clear, show the empty text instead. - if (itemCount != 0) { - setSummary(context.getString(R.string.deletion_helper_downloads_summary, - Formatter.formatFileSize(context, bytes), - DateUtils.getRelativeTimeSpanString(mostRecent, - System.currentTimeMillis(), - DateUtils.DAY_IN_MILLIS, - DateUtils.FORMAT_ABBREV_RELATIVE))); - } else { - setSummary(context.getString(R.string.deletion_helper_downloads_summary_empty, - Formatter.formatFileSize(context, bytes))); - } - } - - private void maybeUpdateListener(int numItems, long bytesFreeable) { - if (mListener != null) { - mListener.onFreeableChanged(numItems, bytesFreeable); - } - } - - private void updateFiles() { - // TODO: Remove impl overlap with the cached preferences methods in - // SettingsPreferenceFragment. - - // Cache the existing file preferences. - ArrayMap cachedPreferences = new ArrayMap<>(); - for (int i = 0; i < getPreferenceCount(); i++) { - Preference p = getPreference(i); - cachedPreferences.put(p.getKey(), p); - } - - // Iterate over all of the files and re-use the old file preference, if it exists. - Set files = mDeletionType.getFiles(); - for (File file : files) { - DownloadsFilePreference filePreference = - (DownloadsFilePreference) cachedPreferences.remove(file.getPath()); - if (filePreference == null) { - filePreference = new DownloadsFilePreference(getContext(), file); - filePreference.setChecked(isChecked()); - filePreference.setOnPreferenceChangeListener(this); - } - addPreference(filePreference); - } - - // Remove all of the unused preferences. - for (Preference p : cachedPreferences.values()) { - removePreference(p); - } - } -} diff --git a/src/com/android/settings/deletionhelper/DownloadsDeletionType.java b/src/com/android/settings/deletionhelper/DownloadsDeletionType.java deleted file mode 100644 index 3a251eb3f79..00000000000 --- a/src/com/android/settings/deletionhelper/DownloadsDeletionType.java +++ /dev/null @@ -1,149 +0,0 @@ -/* - * 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.deletionhelper; - -import android.app.LoaderManager.LoaderCallbacks; -import android.content.Context; -import android.content.Loader; -import android.os.AsyncTask; -import android.os.Bundle; -import android.os.Environment; -import android.util.ArrayMap; -import android.util.ArraySet; -import com.android.settings.deletionhelper.FetchDownloadsLoader.DownloadsResult; - -import java.io.File; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.Set; - -/** - * The DownloadsDeletionType provides stale download file information to the - * {@link DownloadsDeletionPreferenceGroup}. - */ -public class DownloadsDeletionType implements DeletionType, LoaderCallbacks { - private long mBytes; - private long mMostRecent; - private FreeableChangedListener mListener; - private Context mContext; - private ArrayMap mFiles; - - public DownloadsDeletionType(Context context) { - mContext = context; - mFiles = new ArrayMap<>(); - } - - @Override - public void registerFreeableChangedListener(FreeableChangedListener listener) { - mListener = listener; - if (mFiles != null) { - maybeUpdateListener(); - } - } - - @Override - public void onResume() { - } - - @Override - public void onPause() { - } - - @Override - public void clearFreeableData() { - if (mFiles != null) { - AsyncTask.execute(new Runnable() { - @Override - public void run() { - for (Map.Entry entry : mFiles.entrySet()) { - if (entry.getValue()) { - entry.getKey().delete(); - } - } - } - }); - } - } - - @Override - public Loader onCreateLoader(int id, Bundle args) { - return new FetchDownloadsLoader(mContext, - Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)); - } - - @Override - public void onLoadFinished(Loader loader, DownloadsResult data) { - mMostRecent = data.youngestLastModified; - for (File file : data.files) { - if (mFiles.containsKey(file)) { - continue; - } - mFiles.put(file, false); - } - mBytes = data.totalSize; - maybeUpdateListener(); - } - - @Override - public void onLoaderReset(Loader loader) { - } - - /** - * Returns the most recent last modified time for any clearable file. - * @return The last modified time. - */ - public long getMostRecentLastModified() { - return mMostRecent; - } - - /** - * Returns the files in the Downloads folder after the loader task finishes. - */ - public Set getFiles() { - if (mFiles == null) { - return null; - } - return mFiles.keySet(); - } - - /** - * Toggle if a file should be deleted when the service is asked to clear files. - */ - public void toggleFile(File file, boolean checked) { - mFiles.put(file, checked); - } - - /** - * Returns the number of bytes that would be cleared if the deletion tasks runs. - */ - public long getFreeableBytes() { - long freedBytes = 0; - for (Map.Entry entry : mFiles.entrySet()) { - if (entry.getValue()) { - freedBytes += entry.getKey().length(); - } - } - return freedBytes; - } - - private void maybeUpdateListener() { - if (mListener != null) { - mListener.onFreeableChanged(mFiles.size(), mBytes); - } - } -} diff --git a/src/com/android/settings/deletionhelper/DownloadsFilePreference.java b/src/com/android/settings/deletionhelper/DownloadsFilePreference.java deleted file mode 100644 index af8f6b6bae5..00000000000 --- a/src/com/android/settings/deletionhelper/DownloadsFilePreference.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * 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.deletionhelper; - -import android.content.Context; -import android.support.v7.preference.Preference; -import android.support.v7.preference.CheckBoxPreference; -import android.text.format.DateUtils; -import android.text.format.Formatter; -import com.android.settings.R; - -import java.io.File; - -/** - * DownloadsFilePreference is a preference representing a file in the Downloads folder - * with a checkbox that represents if the file should be deleted. - */ -public class DownloadsFilePreference extends CheckBoxPreference { - private File mFile; - - public DownloadsFilePreference(Context context, File file) { - super(context); - mFile = file; - setKey(mFile.getPath()); - setTitle(file.getName()); - setSummary(context.getString(R.string.deletion_helper_downloads_summary, - Formatter.formatFileSize(getContext(), file.length()), - DateUtils.getRelativeTimeSpanString(mFile.lastModified(), - System.currentTimeMillis(), - DateUtils.DAY_IN_MILLIS, - DateUtils.FORMAT_ABBREV_RELATIVE))); - } - - public File getFile() { - return mFile; - } - - @Override - public int compareTo(Preference other) { - if (other == null) { - return 1; - } - - if (other instanceof DownloadsFilePreference) { - DownloadsFilePreference preference = (DownloadsFilePreference) other; - return Long.compare(getFile().length(), preference.getFile().length()); - } else { - // If a non-DownloadsFilePreference appears, consider ourselves to be greater. - // This means if a non-DownloadsFilePreference sneaks into a DownloadsPreferenceGroup - // then the DownloadsFilePreference will appear higher. - return 1; - } - } -} diff --git a/src/com/android/settings/deletionhelper/FetchDownloadsLoader.java b/src/com/android/settings/deletionhelper/FetchDownloadsLoader.java deleted file mode 100644 index 86352c918a0..00000000000 --- a/src/com/android/settings/deletionhelper/FetchDownloadsLoader.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * 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.deletionhelper; - -import android.content.Context; -import android.support.annotation.VisibleForTesting; -import com.android.settings.utils.AsyncLoader; - -import java.io.File; -import java.util.ArrayList; - -/** - * FetchDownloadsLoader is an asynchronous task which returns files in the Downloads - * directory which have not been modified in longer than 90 days. - */ -public class FetchDownloadsLoader extends - AsyncLoader { - private File mDirectory; - - /** - * Sets up a FetchDownloadsLoader in any directory. - * @param directory The directory to look into. - */ - public FetchDownloadsLoader(Context context, File directory) { - super(context); - mDirectory = directory; - } - - @Override - protected void onDiscardResult(DownloadsResult result) {} - - @Override - public DownloadsResult loadInBackground() { - return collectFiles(mDirectory); - } - - @VisibleForTesting - static DownloadsResult collectFiles(File dir) { - return collectFiles(dir, new DownloadsResult()); - } - - private static DownloadsResult collectFiles(File dir, DownloadsResult result) { - File downloadFiles[] = dir.listFiles(); - if (downloadFiles == null) { - } - if (downloadFiles != null && downloadFiles.length > 0) { - for (File currentFile : downloadFiles) { - if (currentFile.isDirectory()) { - collectFiles(currentFile, result); - } else { - if (currentFile.lastModified() < result.youngestLastModified) { - result.youngestLastModified = currentFile.lastModified(); - } - result.files.add(currentFile); - result.totalSize += currentFile.length(); - } - } - } - - return result; - } - - /** - * The DownloadsResult is the result of a {@link FetchDownloadsLoader} with the files - * and the amount of space they use. - */ - public static class DownloadsResult { - public long totalSize; - public long youngestLastModified; - public ArrayList files; - - public DownloadsResult() { - this(0, Long.MAX_VALUE, new ArrayList()); - } - - public DownloadsResult(long totalSize, long youngestLastModified, ArrayList files) { - this.totalSize = totalSize; - this.youngestLastModified = youngestLastModified; - this.files = files; - } - } -} \ No newline at end of file diff --git a/src/com/android/settings/deletionhelper/PackageDeletionTask.java b/src/com/android/settings/deletionhelper/PackageDeletionTask.java deleted file mode 100644 index 69e6a6cb384..00000000000 --- a/src/com/android/settings/deletionhelper/PackageDeletionTask.java +++ /dev/null @@ -1,58 +0,0 @@ -package com.android.settings.deletionhelper; - -import android.content.pm.IPackageDeleteObserver; -import android.content.pm.PackageManager; -import android.os.UserHandle; - -import java.util.Set; -import java.util.concurrent.atomic.AtomicInteger; - -/** - * Deletes a specified set of apps as a specified user and calls back once done. - */ -public class PackageDeletionTask { - private Set mPackages; - private Callback mCallback; - private PackageManager mPm; - private UserHandle mUser; - - public PackageDeletionTask(PackageManager pm, Set packageNames, Callback callback) { - mPackages = packageNames; - mCallback = callback; - mPm = pm; - mUser = android.os.Process.myUserHandle(); - } - - public void run() { - PackageDeletionObserver observer = new PackageDeletionObserver(mPackages.size()); - for (String packageName : mPackages) { - mPm.deletePackageAsUser(packageName, observer, 0, mUser.getIdentifier()); - } - } - - private class PackageDeletionObserver extends IPackageDeleteObserver.Stub { - private final AtomicInteger mPackagesRemaining = new AtomicInteger(0); - - public PackageDeletionObserver(int packages) { - mPackagesRemaining.set(packages); - } - - @Override - public void packageDeleted(String packageName, int returnCode) { - if (returnCode != PackageManager.DELETE_SUCCEEDED) { - mCallback.onError(); - return; - } - - int remaining = mPackagesRemaining.decrementAndGet(); - if (remaining == 0) { - mCallback.onSuccess(); - } - } - } - - public static abstract class Callback { - public abstract void onSuccess(); - public abstract void onError(); - } -} diff --git a/src/com/android/settings/deletionhelper/StorageManagerUpsellDialog.java b/src/com/android/settings/deletionhelper/StorageManagerUpsellDialog.java deleted file mode 100644 index e72933ad006..00000000000 --- a/src/com/android/settings/deletionhelper/StorageManagerUpsellDialog.java +++ /dev/null @@ -1,128 +0,0 @@ -/* - * 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.deletionhelper; - -import android.app.AlertDialog; -import android.app.Dialog; -import android.app.DialogFragment; -import android.content.Context; -import android.content.DialogInterface; -import android.content.SharedPreferences; -import android.os.Bundle; -import android.text.format.Formatter; -import com.android.settings.R; -import android.util.Log; - -import java.util.concurrent.TimeUnit; - -/** - * Fragment for activating the storage manager after a manual clear. - */ -public class StorageManagerUpsellDialog extends DialogFragment - implements DialogInterface.OnClickListener, DialogInterface.OnDismissListener { - public static final String TAG = "StorageManagerUpsellDialog"; - private static final String SHARED_PREFERENCES_NAME = "StorageManagerUpsellDialog"; - private static final String NEXT_SHOW_TIME = "next_show_time"; - private static final String DISMISSED_COUNT = "dismissed_count"; - private static final String NO_THANKS_COUNT = "no_thanks_count"; - - private static final String ARGS_FREED_BYTES = "freed_bytes"; - - private static final long NEVER = -1; - private static final long DISMISS_SHORT_DELAY = TimeUnit.DAYS.toMillis(14); - private static final long DISMISS_LONG_DELAY = TimeUnit.DAYS.toMillis(90); - private static final int DISMISS_LONG_THRESHOLD = 9; - private static final long NO_THANKS_SHORT_DELAY = TimeUnit.DAYS.toMillis(90); - private static final long NO_THANKS_LONG_DELAY = NEVER; - private static final int NO_THANKS_LONG_THRESHOLD = 3; - - public static StorageManagerUpsellDialog newInstance(long freedBytes) { - StorageManagerUpsellDialog dialog = new StorageManagerUpsellDialog(); - Bundle args = new Bundle(1); - args.putLong(ARGS_FREED_BYTES, freedBytes); - dialog.setArguments(args); - return dialog; - } - - @Override - public Dialog onCreateDialog(Bundle savedInstanceState) { - final Bundle args = getArguments(); - long freedBytes = args.getLong(ARGS_FREED_BYTES); - - final Context context = getContext(); - return new AlertDialog.Builder(context) - .setTitle(context.getString(R.string.deletion_helper_upsell_title, - Formatter.formatFileSize(context, freedBytes))) - .setMessage(context.getString(R.string.deletion_helper_upsell_summary)) - .setPositiveButton(R.string.deletion_helper_upsell_activate, this) - .setNegativeButton(R.string.deletion_helper_upsell_cancel, this) - .create(); - } - - @Override - public void onClick(DialogInterface dialog, int buttonId) { - if (buttonId == DialogInterface.BUTTON_POSITIVE) { - // TODO: Activate the storage manager once the storage manager is landed. - } else { - SharedPreferences sp = getSharedPreferences(getContext()); - int noThanksCount = sp.getInt(NO_THANKS_COUNT, 0) + 1; - SharedPreferences.Editor editor = sp.edit(); - editor.putInt(NO_THANKS_COUNT, noThanksCount); - editor.putLong(NEXT_SHOW_TIME, - System.currentTimeMillis() + getNoThanksDelay(noThanksCount)); - editor.apply(); - } - } - - @Override - public void onCancel(DialogInterface dialog) { - SharedPreferences sp = getSharedPreferences(getContext()); - int dismissCount = sp.getInt(DISMISSED_COUNT, 0) + 1; - SharedPreferences.Editor editor = sp.edit(); - editor.putInt(DISMISSED_COUNT, dismissCount); - editor.putLong(NEXT_SHOW_TIME, - System.currentTimeMillis() + getDismissDelay(dismissCount)); - editor.apply(); - } - - /** - * Returns if the dialog should be shown, given the delays between when it is shown. - * @param context Context to get shared preferences for determining the next show time. - */ - public static boolean shouldShow(Context context) { - // TODO: If the Storage Manager is enabled, return false. - long nextTimeToShow = getSharedPreferences(context).getLong(NEXT_SHOW_TIME, 0); - - if (nextTimeToShow == NEVER) { - return false; - } - - return System.currentTimeMillis() > nextTimeToShow; - } - - private static SharedPreferences getSharedPreferences(Context context) { - return context.getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE); - } - - private static long getNoThanksDelay(int noThanksCount) { - return (noThanksCount > NO_THANKS_LONG_THRESHOLD) - ? NO_THANKS_LONG_DELAY : NO_THANKS_SHORT_DELAY; - } - - private static long getDismissDelay(int dismissCount) { - return (dismissCount > DISMISS_LONG_THRESHOLD) - ? DISMISS_LONG_DELAY : DISMISS_SHORT_DELAY; - } -} diff --git a/src/com/android/settings/deviceinfo/PrivateVolumeSettings.java b/src/com/android/settings/deviceinfo/PrivateVolumeSettings.java index 76334073bee..06986668d24 100644 --- a/src/com/android/settings/deviceinfo/PrivateVolumeSettings.java +++ b/src/com/android/settings/deviceinfo/PrivateVolumeSettings.java @@ -38,6 +38,7 @@ import android.os.storage.StorageManager; import android.os.storage.VolumeInfo; import android.os.storage.VolumeRecord; import android.provider.DocumentsContract; +import android.provider.Settings; import android.support.v7.preference.Preference; import android.support.v7.preference.PreferenceCategory; import android.support.v7.preference.PreferenceGroup; @@ -59,9 +60,7 @@ import com.android.settings.Settings.StorageUseActivity; import com.android.settings.SettingsPreferenceFragment; import com.android.settings.Utils; import com.android.settings.applications.ManageApplications; -import com.android.settings.deletionhelper.DeletionHelperFragment; import com.android.settings.deletionhelper.AutomaticStorageManagerSettings; -import com.android.settings.deletionhelper.StorageManagerUpsellDialog; import com.android.settings.deviceinfo.StorageSettings.MountTask; import com.android.settingslib.deviceinfo.StorageMeasurement; import com.android.settingslib.deviceinfo.StorageMeasurement.MeasurementDetails; @@ -445,8 +444,9 @@ public class PrivateVolumeSettings extends SettingsPreferenceFragment { startActivity(intent); return true; case R.id.storage_free: - startFragment(this, DeletionHelperFragment.class.getCanonicalName(), - R.string.deletion_helper_title, DELETION_HELPER_SETTINGS, args); + final Intent deletion_helper_intent = + new Intent(Settings.ACTION_DELETION_HELPER_SETTINGS); + startActivity(deletion_helper_intent); return true; } return super.onOptionsItemSelected(item); @@ -540,18 +540,6 @@ public class PrivateVolumeSettings extends SettingsPreferenceFragment { return super.onPreferenceTreeClick(pref); } - @Override - public void onActivityResult(int requestCode, int resultCode, Intent data) { - super.onActivityResult(requestCode, resultCode, data); - if (requestCode == DELETION_HELPER_SETTINGS && resultCode == DELETION_HELPER_CLEAR && - StorageManagerUpsellDialog.shouldShow(getActivity())) { - long freedBytes = data.getLongExtra(DeletionHelperFragment.FREED_BYTES_KEY, 0); - StorageManagerUpsellDialog dialog = - StorageManagerUpsellDialog.newInstance(freedBytes); - dialog.show(getFragmentManager(), StorageManagerUpsellDialog.TAG); - } - } - private final MeasurementReceiver mReceiver = new MeasurementReceiver() { @Override public void onDetailsChanged(MeasurementDetails details) { diff --git a/src/com/android/settings/overlay/DeletionHelperFeatureProvider.java b/src/com/android/settings/overlay/DeletionHelperFeatureProvider.java deleted file mode 100644 index 15b58964e91..00000000000 --- a/src/com/android/settings/overlay/DeletionHelperFeatureProvider.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * 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.overlay; - -import android.content.Context; -import android.support.v7.preference.PreferenceGroup; -import com.android.settings.deletionhelper.DeletionType; - -/** - * Feature provider for the manual deletion helper Settings page. - */ -public interface DeletionHelperFeatureProvider { - /** - * Creates a {@link DeletionType} for clearing out stored photos and videos on the device. - */ - DeletionType createPhotoVideoDeletionType(Context context); -} diff --git a/src/com/android/settings/overlay/FeatureFactory.java b/src/com/android/settings/overlay/FeatureFactory.java index 04f2f810961..1bffc2b2ab0 100644 --- a/src/com/android/settings/overlay/FeatureFactory.java +++ b/src/com/android/settings/overlay/FeatureFactory.java @@ -61,12 +61,6 @@ public abstract class FeatureFactory { public abstract SupportFeatureProvider getSupportFeatureProvider(Context context); - /** - * Return a provider which adds additional deletion services to the Deletion Helper. - */ - public abstract DeletionHelperFeatureProvider getDeletionHelperFeatureProvider(); - public abstract StorageManagementJobProvider getStorageManagementJobProvider(); - public static final class FactoryNotFoundException extends RuntimeException { public FactoryNotFoundException(Throwable throwable) { super("Unable to create factory. Did you misconfigure Proguard?", throwable); diff --git a/src/com/android/settings/overlay/FeatureFactoryImpl.java b/src/com/android/settings/overlay/FeatureFactoryImpl.java index 054724787ac..ce561f3d17d 100644 --- a/src/com/android/settings/overlay/FeatureFactoryImpl.java +++ b/src/com/android/settings/overlay/FeatureFactoryImpl.java @@ -28,14 +28,4 @@ public final class FeatureFactoryImpl extends FeatureFactory { return null; } - @Override - public DeletionHelperFeatureProvider getDeletionHelperFeatureProvider() { - return null; - } - - @Override - public StorageManagementJobProvider getStorageManagementJobProvider() { - return null; - } - } diff --git a/src/com/android/settings/overlay/StorageManagementJobProvider.java b/src/com/android/settings/overlay/StorageManagementJobProvider.java deleted file mode 100644 index 80f8737a597..00000000000 --- a/src/com/android/settings/overlay/StorageManagementJobProvider.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * 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.overlay; - -import android.app.job.JobParameters; -import android.content.Context; - -/** - * Feature provider for automatic storage management jobs. - */ -public interface StorageManagementJobProvider { - /** - * Starts an asynchronous deletion job to clear out storage older than - * @param params Standard JobService parameters. - * @param daysToRetain Number of days of information to retain on the device. - * @return If the job needs to process the work on a separate thread. - */ - boolean onStartJob(Context context, JobParameters params, int daysToRetain); - - /** - * Attempt to stop the execution of the job. - * @param params Parameters specifying info about this job. - * @return If the job should be rescheduled. - */ - boolean onStopJob(Context context, JobParameters params); -} diff --git a/tests/unit/src/com/android/settings/deletionhelper/FetchDownloadsLoaderTest.java b/tests/unit/src/com/android/settings/deletionhelper/FetchDownloadsLoaderTest.java deleted file mode 100644 index 52312d1b763..00000000000 --- a/tests/unit/src/com/android/settings/deletionhelper/FetchDownloadsLoaderTest.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * 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.deletionhelper; - -import com.android.settings.deletionhelper.FetchDownloadsLoader.DownloadsResult; - -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.rules.TemporaryFolder; -import org.junit.runners.JUnit4; - -import java.io.File; -import java.io.FileWriter; - -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertEquals; - -@RunWith(JUnit4.class) -public class FetchDownloadsLoaderTest { - @Rule - public TemporaryFolder temporaryFolder = new TemporaryFolder(); - - @Test - public void testEmptyDirectory() throws Exception { - DownloadsResult result = - FetchDownloadsLoader.collectFiles(temporaryFolder.getRoot()); - assertNotNull(result); - assertEquals(0, result.totalSize); - assertEquals(0, result.files.size()); - } - - @Test - public void testFilesInDirectory() throws Exception { - temporaryFolder.newFile(); - temporaryFolder.newFile(); - - DownloadsResult result = - FetchDownloadsLoader.collectFiles(temporaryFolder.getRoot()); - assertNotNull(result); - assertEquals(0, result.totalSize); - assertEquals(2, result.files.size()); - } - - @Test - public void testNestedDirectories() throws Exception { - File tempDir = temporaryFolder.newFolder(); - - File testFile = File.createTempFile("test", null, tempDir); - testFile.deleteOnExit(); - DownloadsResult result = - FetchDownloadsLoader.collectFiles(temporaryFolder.getRoot()); - assertNotNull(result); - assertEquals(0, result.totalSize); - assertEquals(1, result.files.size()); - } - - @Test - public void testSumFileSizes() throws Exception { - File first = temporaryFolder.newFile(); - FileWriter fileWriter = new FileWriter(first); - fileWriter.write("test"); - fileWriter.close(); - - File second = temporaryFolder.newFile(); - fileWriter = new FileWriter(second); - fileWriter.write("test2"); - fileWriter.close(); - - DownloadsResult result = - FetchDownloadsLoader.collectFiles(temporaryFolder.getRoot()); - assertNotNull(result); - assertEquals(9, result.totalSize); - assertEquals(2, result.files.size()); - } -} diff --git a/tests/unit/src/com/android/settings/deletionhelper/PackageDeletionTaskTest.java b/tests/unit/src/com/android/settings/deletionhelper/PackageDeletionTaskTest.java deleted file mode 100644 index 10ba5850cc0..00000000000 --- a/tests/unit/src/com/android/settings/deletionhelper/PackageDeletionTaskTest.java +++ /dev/null @@ -1,120 +0,0 @@ -/* - * 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.deletionhelper; - -import android.test.AndroidTestCase; -import android.content.pm.IPackageDeleteObserver; -import android.content.pm.PackageManager; -import android.os.RemoteException; -import android.test.mock.MockPackageManager; -import android.test.suitebuilder.annotation.SmallTest; - -import com.android.settings.deletionhelper.PackageDeletionTask; -import com.android.settings.deletionhelper.PackageDeletionTask.Callback; - -import java.util.Set; -import java.util.HashSet; - -public class PackageDeletionTaskTest extends AndroidTestCase { - private FakePackageManager mPackageManager; - private Set mDeletedApps; - - @Override - protected void setUp() throws Exception { - mPackageManager = new FakePackageManager(); - mDeletedApps = new HashSet(); - } - - @SmallTest - public void testDeleteNoApps() throws Exception { - runTask(new HashSet(), false); - } - - @SmallTest - public void testDeleteOneApp() throws Exception { - HashSet appsToDelete = new HashSet(); - appsToDelete.add("app.test1"); - runTask(appsToDelete, false); - } - - @SmallTest - public void testDeleteManyApps() throws Exception { - HashSet appsToDelete = new HashSet(); - appsToDelete.add("app.test1"); - appsToDelete.add("app.test2"); - runTask(appsToDelete, false); - } - - @SmallTest - public void testDeleteFails() throws Exception { - HashSet appsToDelete = new HashSet(); - appsToDelete.add("app.test1"); - mPackageManager.deletionSucceeds = false; - runTask(appsToDelete, true); - } - - private void runTask(HashSet appsToDelete, boolean shouldFail) { - PackageDeletionTask task = new PackageDeletionTask(mPackageManager, appsToDelete, - new VerifierCallback(appsToDelete, shouldFail)); - task.run(); - } - - class FakePackageManager extends MockPackageManager { - public boolean deletionSucceeds = true; - - @Override - public void deletePackageAsUser(String packageName, IPackageDeleteObserver observer, - int flags, int userId) { - int resultCode; - if (deletionSucceeds) { - resultCode = PackageManager.DELETE_SUCCEEDED; - mDeletedApps.add(packageName); - } else { - resultCode = PackageManager.DELETE_FAILED_INTERNAL_ERROR; - } - - try { - observer.packageDeleted(packageName, resultCode); - } catch (RemoteException e) { - fail(e.toString()); - } - } - } - - class VerifierCallback extends Callback { - private Set mExpectedDeletedApps; - private boolean mShouldFail; - - public VerifierCallback(HashSet expectedDeletedApps, boolean shouldFail) { - mExpectedDeletedApps = expectedDeletedApps; - mShouldFail = shouldFail; - } - - @Override - public void onSuccess() { - System.out.println("lol"); - assertFalse(mShouldFail); - assertEquals(mExpectedDeletedApps, mDeletedApps); - } - - @Override - public void onError() { - assertTrue(mShouldFail); - } - } - -}