Add an alert dialog before clearing data in deletion helper.

The dialog states how much space will be freed by the deletion
and prompts the user to either cancel or continue with the
deletion.

BUG: 28762412
Change-Id: I8db2a8f928c82ebaa2cf5fea030b6b6f4730eb3e
diff --git a/res/values/strings.xml b/res/values/strings.xml
index f533d89..76f573f 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -7598,4 +7598,10 @@
     <!-- Summary for when when there is nothing in the downloads folder to clear. [CHAR LIMIT=NONE]-->
     <string name="deletion_helper_downloads_summary_empty"><xliff:g id="used" example="1.2GB">%1$s</xliff:g></string>
 
+    <!-- Message to warn the user before clearing space in the deletion helper. [CHAR LIMIT=NONE] -->
+    <string name="deletion_helper_clear_dialog_message">Remove <xliff:g id="clearable_bytes" example="1.2GB">%1$s</xliff:g> from your device.</string>
+
+    <!-- Button label for the dialog prompt for clearing data in deletion helper. [CHAR LIMIT=40] -->
+    <string name="deletion_helper_clear_dialog_remove">Remove</string>
+
 </resources>
diff --git a/src/com/android/settings/deletionhelper/ConfirmDeletionDialog.java b/src/com/android/settings/deletionhelper/ConfirmDeletionDialog.java
new file mode 100644
index 0000000..fc6033e
--- /dev/null
+++ b/src/com/android/settings/deletionhelper/ConfirmDeletionDialog.java
@@ -0,0 +1,64 @@
+/*
+ * 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
index b4c03e7..cc1a084 100644
--- a/src/com/android/settings/deletionhelper/DeletionHelperFragment.java
+++ b/src/com/android/settings/deletionhelper/DeletionHelperFragment.java
@@ -46,7 +46,8 @@
  */
 public class DeletionHelperFragment extends SettingsPreferenceFragment implements
         ApplicationsState.Callbacks, AppStateBaseBridge.Callback,
-        Preference.OnPreferenceChangeListener, DeletionType.FreeableChangedListener {
+        Preference.OnPreferenceChangeListener, DeletionType.FreeableChangedListener,
+        View.OnClickListener {
     private static final String TAG = "DeletionHelperFragment";
 
     private static final String EXTRA_HAS_BRIDGE = "hasBridge";
@@ -108,53 +109,11 @@
     private void initializeButtons(View v) {
         mCancel = (Button) v.findViewById(R.id.back_button);
         mCancel.setText(R.string.cancel);
-        mCancel.setOnClickListener(new View.OnClickListener() {
-            @Override
-            public void onClick(View v) {
-                finishFragment();
-            }
-        });
+        mCancel.setOnClickListener(this);
 
         mFree = (Button) v.findViewById(R.id.next_button);
         mFree.setText(R.string.storage_menu_free);
-        mFree.setOnClickListener(new View.OnClickListener() {
-            @Override
-            public void onClick(View v) {
-                // 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();
-                }
-                if (mDownloadsPreference != null && mDownloadsPreference.isChecked()) {
-                    mDownloadsDeletion.clearFreeableData();
-                }
-
-                ArraySet<String> 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.");
-                            }
-                        });
-                finishFragment();
-                task.run();
-            }
-        });
+        mFree.setOnClickListener(this);
     }
 
     private void initializeDeletionPreferences() {
@@ -329,6 +288,54 @@
         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();
+        }
+
+        ArraySet<String> 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.");
+                    }
+                });
+        task.run();
+        finishFragment();
+    }
+
     private long getTotalFreeableSpace() {
         long freeableSpace = 0;
         if (mAppEntries != null) {