Move packages between candidate volumes.

We now allow moving packages between all possible candidate volumes,
as determined by the framework.  Moving now jumps through wizard to
help user understand what's going on.

Bug: 19993667
Change-Id: I5416ed2865f400b1d718c68a3f0e033080fefa0e
diff --git a/res/layout/preference_list_fragment.xml b/res/layout/preference_list_fragment.xml
index 6e8ad91..195f6eb 100644
--- a/res/layout/preference_list_fragment.xml
+++ b/res/layout/preference_list_fragment.xml
@@ -36,7 +36,7 @@
         <ListView android:id="@android:id/list"
                   style="@style/PreferenceFragmentListSinglePane"
                   android:layout_width="match_parent"
-                  android:layout_height="wrap_content"
+                  android:layout_height="match_parent"
                   android:paddingStart="@dimen/settings_side_margin"
                   android:paddingEnd="@dimen/settings_side_margin"
                   android:paddingTop="@dimen/dashboard_padding_top"
diff --git a/src/com/android/settings/applications/AppStorageSettings.java b/src/com/android/settings/applications/AppStorageSettings.java
index 4b80fdd..647be4d 100644
--- a/src/com/android/settings/applications/AppStorageSettings.java
+++ b/src/com/android/settings/applications/AppStorageSettings.java
@@ -23,13 +23,12 @@
 import android.content.Intent;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.IPackageDataObserver;
-import android.content.pm.IPackageMoveObserver;
-import android.content.pm.PackageManager;
 import android.os.Bundle;
 import android.os.Environment;
 import android.os.Handler;
 import android.os.Message;
-import android.os.RemoteException;
+import android.os.storage.StorageManager;
+import android.os.storage.VolumeInfo;
 import android.text.format.Formatter;
 import android.util.Log;
 import android.view.View;
@@ -38,11 +37,16 @@
 import android.widget.TextView;
 
 import com.android.internal.logging.MetricsLogger;
+import com.android.settings.DropDownPreference;
 import com.android.settings.R;
 import com.android.settings.Utils;
 import com.android.settings.applications.ApplicationsState.AppEntry;
 import com.android.settings.applications.ApplicationsState.Callbacks;
-import com.android.settings.DropDownPreference;
+import com.android.settings.deviceinfo.StorageWizardMoveConfirm;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Objects;
 
 public class AppStorageSettings extends AppInfoWithHeader
         implements OnClickListener, Callbacks, DropDownPreference.Callback {
@@ -53,7 +57,6 @@
     private static final int OP_FAILED = 2;
     private static final int MSG_CLEAR_USER_DATA = 1;
     private static final int MSG_CLEAR_CACHE = 3;
-    private static final int MSG_PACKAGE_MOVE = 4;
 
     // invalid size value used initially and also when size retrieval through PackageManager
     // fails for whatever reason
@@ -64,13 +67,11 @@
 
     private static final int DLG_CLEAR_DATA = DLG_BASE + 1;
     private static final int DLG_CANNOT_CLEAR_DATA = DLG_BASE + 2;
-    private static final int DLG_MOVE_FAILED = DLG_BASE + 3;
 
     private static final String KEY_MOVE_PREFERENCE = "app_location_setting";
     private static final String KEY_STORAGE_SETTINGS = "storage_settings";
     private static final String KEY_CACHE_SETTINGS = "cache_settings";
 
-    private CanBeOnSdCardChecker mCanBeOnSdCardChecker;
     private TextView mTotalSize;
     private TextView mAppSize;
     private TextView mDataSize;
@@ -83,7 +84,6 @@
     private Button mClearCacheButton;
 
     private DropDownPreference mMoveDropDown;
-    private boolean mMoveInProgress = false;
 
     private boolean mCanClearData = true;
     private boolean mHaveSizes = false;
@@ -97,7 +97,6 @@
 
     private ClearCacheObserver mClearCacheObserver;
     private ClearUserDataObserver mClearDataObserver;
-    private PackageMoveObserver mPackageMoveObserver;
 
     // Resource strings
     private CharSequence mInvalidSizeStr;
@@ -107,7 +106,6 @@
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
 
-        mCanBeOnSdCardChecker = new CanBeOnSdCardChecker();
         addPreferencesFromResource(R.xml.app_storage_settings);
         setupViews();
     }
@@ -166,18 +164,19 @@
 
     @Override
     public boolean onItemSelected(int pos, Object value) {
-        boolean selectedExternal = (Boolean) value;
-        boolean isExternal = (mAppEntry.info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
-        if (selectedExternal ^ isExternal) {
-            if (mPackageMoveObserver == null) {
-                mPackageMoveObserver = new PackageMoveObserver();
-            }
-            int moveFlags = selectedExternal ? PackageManager.MOVE_EXTERNAL_MEDIA
-                    : PackageManager.MOVE_INTERNAL;
-            mMoveInProgress = true;
-            refreshButtons();
-            mPm.movePackage(mAppEntry.info.packageName, mPackageMoveObserver, moveFlags);
+        final Context context = getActivity();
+
+        // If not current volume, kick off move wizard
+        final VolumeInfo targetVol = (VolumeInfo) value;
+        final VolumeInfo currentVol = context.getPackageManager().getApplicationCurrentVolume(
+                mAppEntry.info);
+        if (!Objects.equals(targetVol, currentVol)) {
+            final Intent intent = new Intent(context, StorageWizardMoveConfirm.class);
+            intent.putExtra(VolumeInfo.EXTRA_VOLUME_ID, targetVol.getId());
+            intent.putExtra(Intent.EXTRA_PACKAGE_NAME, mAppEntry.info.packageName);
+            startActivity(intent);
         }
+
         return true;
     }
 
@@ -260,27 +259,17 @@
         retrieveAppEntry();
         refreshButtons();
         refreshSizeInfo();
-        boolean isExternal = (mAppEntry.info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
-        mMoveDropDown.setSelectedItem(isExternal ? 1 : 0);
+
+        final VolumeInfo currentVol = getActivity().getPackageManager()
+                .getApplicationCurrentVolume(mAppEntry.info);
+        mMoveDropDown.setSelectedValue(currentVol);
+
         return true;
     }
 
     private void refreshButtons() {
-        if (!mMoveInProgress) {
-            initMoveDropDown();
-            initDataButtons();
-        } else {
-            mMoveDropDown.setSummary(R.string.moving);
-            mMoveDropDown.setSelectable(false);
-        }
-    }
-
-    private void updateMoveEnabled(boolean enabled) {
-        mMoveDropDown.clearItems();
-        mMoveDropDown.addItem(R.string.storage_type_internal, false);
-        if (enabled) {
-            mMoveDropDown.addItem(R.string.storage_type_external, true);
-        }
+        initMoveDropDown();
+        initDataButtons();
     }
 
     private void initDataButtons() {
@@ -310,20 +299,18 @@
     }
 
     private void initMoveDropDown() {
-        if (Environment.isExternalStorageEmulated()) {
-            updateMoveEnabled(false);
-            return;
+        final Context context = getActivity();
+        final StorageManager storage = context.getSystemService(StorageManager.class);
+
+        final List<VolumeInfo> candidates = context.getPackageManager()
+                .getApplicationCandidateVolumes(mAppEntry.info);
+        Collections.sort(candidates, VolumeInfo.getDescriptionComparator());
+
+        mMoveDropDown.clearItems();
+        for (VolumeInfo vol : candidates) {
+            final String volDescrip = storage.getBestVolumeDescription(vol);
+            mMoveDropDown.addItem(volDescrip, vol);
         }
-        boolean dataOnly = (mPackageInfo == null) && (mAppEntry != null);
-        boolean moveDisable = true;
-        if ((mAppEntry.info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
-            // Always let apps move to internal storage from sdcard.
-            moveDisable = false;
-        } else {
-            mCanBeOnSdCardChecker.init();
-            moveDisable = !mCanBeOnSdCardChecker.check(mAppEntry.info);
-        }
-        updateMoveEnabled(!moveDisable);
         mMoveDropDown.setSelectable(!mAppControlRestricted);
     }
 
@@ -351,21 +338,6 @@
         }
     }
 
-    private void processMoveMsg(Message msg) {
-        int result = msg.arg1;
-        String packageName = mAppEntry.info.packageName;
-        // Refresh the button attributes.
-        mMoveInProgress = false;
-        if (result == PackageManager.MOVE_SUCCEEDED) {
-            Log.i(TAG, "Moved resources for " + packageName);
-            // Refresh size information again.
-            mState.requestSize(mPackageName, mUserId);
-        } else {
-            showDialogInner(DLG_MOVE_FAILED, result);
-        }
-        refreshUi();
-    }
-
     /*
      * Private method to handle clear message notification from observer when
      * the async operation from PackageManager is complete
@@ -382,24 +354,6 @@
         }
     }
 
-    private CharSequence getMoveErrMsg(int errCode) {
-        switch (errCode) {
-            case PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE:
-                return getActivity().getString(R.string.insufficient_storage);
-            case PackageManager.MOVE_FAILED_DOESNT_EXIST:
-                return getActivity().getString(R.string.does_not_exist);
-            case PackageManager.MOVE_FAILED_FORWARD_LOCKED:
-                return getActivity().getString(R.string.app_forward_locked);
-            case PackageManager.MOVE_FAILED_INVALID_LOCATION:
-                return getActivity().getString(R.string.invalid_location);
-            case PackageManager.MOVE_FAILED_SYSTEM_PACKAGE:
-                return getActivity().getString(R.string.system_package);
-            case PackageManager.MOVE_FAILED_INTERNAL_ERROR:
-                return "";
-        }
-        return "";
-    }
-
     @Override
     protected AlertDialog createDialog(int id, int errorCode) {
         switch (id) {
@@ -427,14 +381,6 @@
                             }
                         })
                         .create();
-            case DLG_MOVE_FAILED:
-                CharSequence msg = getActivity().getString(R.string.move_app_failed_dlg_text,
-                        getMoveErrMsg(errorCode));
-                return new AlertDialog.Builder(getActivity())
-                        .setTitle(getActivity().getText(R.string.move_app_failed_dlg_title))
-                        .setMessage(msg)
-                        .setNeutralButton(R.string.dlg_ok, null)
-                        .create();
         }
         return null;
     }
@@ -459,9 +405,6 @@
                     // Refresh size info
                     mState.requestSize(mPackageName, mUserId);
                     break;
-                case MSG_PACKAGE_MOVE:
-                    processMoveMsg(msg);
-                    break;
             }
         }
     };
@@ -508,13 +451,4 @@
            mHandler.sendMessage(msg);
         }
     }
-
-    class PackageMoveObserver extends IPackageMoveObserver.Stub {
-        public void packageMoved(String packageName, int returnCode) throws RemoteException {
-            final Message msg = mHandler.obtainMessage(MSG_PACKAGE_MOVE);
-            msg.arg1 = returnCode;
-            mHandler.sendMessage(msg);
-        }
-    }
-
 }
diff --git a/src/com/android/settings/applications/ApplicationsState.java b/src/com/android/settings/applications/ApplicationsState.java
index 162ca77..ddfc207 100644
--- a/src/com/android/settings/applications/ApplicationsState.java
+++ b/src/com/android/settings/applications/ApplicationsState.java
@@ -295,20 +295,6 @@
         }
     };
 
-    public static final AppFilter FILTER_ON_SD_CARD = new AppFilter() {
-        final CanBeOnSdCardChecker mCanBeOnSdCardChecker
-                = new CanBeOnSdCardChecker();
-
-        public void init() {
-            mCanBeOnSdCardChecker.init();
-        }
-
-        @Override
-        public boolean filterApp(AppEntry entry) {
-            return mCanBeOnSdCardChecker.check(entry.info);
-        }
-    };
-
     public static final AppFilter FILTER_DISABLED = new AppFilter() {
         public void init() {
         }
diff --git a/src/com/android/settings/applications/ManageApplications.java b/src/com/android/settings/applications/ManageApplications.java
index b6b2b82..362903e 100644
--- a/src/com/android/settings/applications/ManageApplications.java
+++ b/src/com/android/settings/applications/ManageApplications.java
@@ -20,15 +20,11 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.ApplicationInfo;
-import android.content.pm.IPackageManager;
 import android.content.pm.IntentFilterVerificationInfo;
-import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
 import android.net.Uri;
 import android.os.Bundle;
 import android.os.Environment;
-import android.os.RemoteException;
-import android.os.ServiceManager;
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.preference.PreferenceFrameLayout;
@@ -53,7 +49,6 @@
 import android.widget.ListView;
 import android.widget.Spinner;
 
-import com.android.internal.content.PackageHelper;
 import com.android.internal.logging.MetricsLogger;
 import com.android.settings.HelpUtils;
 import com.android.settings.InstrumentedFragment;
@@ -74,47 +69,6 @@
 import java.util.Comparator;
 import java.util.List;
 
-final class CanBeOnSdCardChecker {
-    final IPackageManager mPm;
-    int mInstallLocation;
-
-    CanBeOnSdCardChecker() {
-        mPm = IPackageManager.Stub.asInterface(
-                ServiceManager.getService("package"));
-    }
-
-    void init() {
-        try {
-            mInstallLocation = mPm.getInstallLocation();
-        } catch (RemoteException e) {
-            Log.e("CanBeOnSdCardChecker", "Is Package Manager running?");
-            return;
-        }
-    }
-
-    boolean check(ApplicationInfo info) {
-        boolean canBe = false;
-        if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
-            canBe = true;
-        } else {
-            if ((info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
-                if (info.installLocation == PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL ||
-                        info.installLocation == PackageInfo.INSTALL_LOCATION_AUTO) {
-                    canBe = true;
-                } else if (info.installLocation
-                        == PackageInfo.INSTALL_LOCATION_UNSPECIFIED) {
-                    if (mInstallLocation == PackageHelper.APP_INSTALL_EXTERNAL) {
-                        // For apps with no preference and the default value set
-                        // to install on sdcard.
-                        canBe = true;
-                    }
-                }
-            }
-        }
-        return canBe;
-    }
-}
-
 /**
  * Activity to pick an application that will be used to display installation information and
  * options to uninstall/delete user data for system applications. This activity
diff --git a/src/com/android/settings/deviceinfo/StorageSettings.java b/src/com/android/settings/deviceinfo/StorageSettings.java
index 1e33230d..74040ef 100644
--- a/src/com/android/settings/deviceinfo/StorageSettings.java
+++ b/src/com/android/settings/deviceinfo/StorageSettings.java
@@ -41,7 +41,6 @@
 
 import java.util.ArrayList;
 import java.util.Collections;
-import java.util.Comparator;
 import java.util.List;
 
 /**
@@ -91,21 +90,6 @@
         setHasOptionsMenu(true);
     }
 
-    private static final Comparator<VolumeInfo> sVolumeComparator = new Comparator<VolumeInfo>() {
-        @Override
-        public int compare(VolumeInfo lhs, VolumeInfo rhs) {
-            if (VolumeInfo.ID_PRIVATE_INTERNAL.equals(lhs.getId())) {
-                return -1;
-            } else if (lhs.getDescription() == null) {
-                return 1;
-            } else if (rhs.getDescription() == null) {
-                return -1;
-            } else {
-                return lhs.getDescription().compareTo(rhs.getDescription());
-            }
-        }
-    };
-
     private final StorageEventListener mStorageListener = new StorageEventListener() {
         @Override
         public void onVolumeStateChanged(VolumeInfo vol, int oldState, int newState) {
@@ -133,7 +117,7 @@
         mExternalCategory.removeAll();
 
         final List<VolumeInfo> volumes = mStorageManager.getVolumes();
-        Collections.sort(volumes, sVolumeComparator);
+        Collections.sort(volumes, VolumeInfo.getDescriptionComparator());
 
         for (VolumeInfo vol : volumes) {
             if (vol.getType() == VolumeInfo.TYPE_PRIVATE) {
diff --git a/src/com/android/settings/deviceinfo/StorageWizardMoveConfirm.java b/src/com/android/settings/deviceinfo/StorageWizardMoveConfirm.java
new file mode 100644
index 0000000..36750c0
--- /dev/null
+++ b/src/com/android/settings/deviceinfo/StorageWizardMoveConfirm.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.deviceinfo;
+
+import android.content.Intent;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.os.Bundle;
+import android.os.storage.VolumeInfo;
+
+import com.android.internal.util.Preconditions;
+import com.android.settings.R;
+
+public class StorageWizardMoveConfirm extends StorageWizardBase {
+    private String mPackageName;
+    private ApplicationInfo mApp;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.storage_wizard_generic);
+
+        try {
+            mPackageName = getIntent().getStringExtra(Intent.EXTRA_PACKAGE_NAME);
+            mApp = getPackageManager().getApplicationInfo(mPackageName, 0);
+        } catch (NameNotFoundException e) {
+            throw new RuntimeException(e);
+        }
+
+        Preconditions.checkNotNull(mVolume);
+        Preconditions.checkNotNull(mApp);
+
+        // Sanity check that target volume is candidate
+        Preconditions.checkState(
+                getPackageManager().getApplicationCandidateVolumes(mApp).contains(mVolume));
+
+        final String appName = getPackageManager().getApplicationLabel(mApp).toString();
+        final String volumeName = mStorage.getBestVolumeDescription(mVolume);
+
+        setHeaderText(R.string.storage_wizard_move_confirm_title, appName);
+        setBodyText(R.string.storage_wizard_move_confirm_body, appName, volumeName);
+
+        getNextButton().setText(R.string.move_app);
+    }
+
+    @Override
+    public void onNavigateNext() {
+        final Intent intent = new Intent(this, StorageWizardMoveProgress.class);
+        intent.putExtra(VolumeInfo.EXTRA_VOLUME_ID, mVolume.getId());
+        intent.putExtra(Intent.EXTRA_PACKAGE_NAME, mPackageName);
+        startActivity(intent);
+        finishAffinity();
+    }
+}
diff --git a/src/com/android/settings/deviceinfo/StorageWizardMoveProgress.java b/src/com/android/settings/deviceinfo/StorageWizardMoveProgress.java
new file mode 100644
index 0000000..2023335
--- /dev/null
+++ b/src/com/android/settings/deviceinfo/StorageWizardMoveProgress.java
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.deviceinfo;
+
+import static com.android.settings.deviceinfo.StorageSettings.TAG;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.IPackageMoveObserver;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.os.RemoteException;
+import android.os.storage.VolumeInfo;
+import android.util.Log;
+import android.view.View;
+import android.widget.Toast;
+
+import com.android.internal.util.Preconditions;
+import com.android.settings.R;
+
+import java.util.concurrent.CountDownLatch;
+
+public class StorageWizardMoveProgress extends StorageWizardBase {
+    private String mPackageName;
+    private ApplicationInfo mApp;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.storage_wizard_progress);
+
+        try {
+            mPackageName = getIntent().getStringExtra(Intent.EXTRA_PACKAGE_NAME);
+            mApp = getPackageManager().getApplicationInfo(mPackageName, 0);
+        } catch (NameNotFoundException e) {
+            throw new RuntimeException(e);
+        }
+
+        Preconditions.checkNotNull(mVolume);
+        Preconditions.checkNotNull(mApp);
+
+        final String appName = getPackageManager().getApplicationLabel(mApp).toString();
+        final String volumeName = mStorage.getBestVolumeDescription(mVolume);
+
+        setHeaderText(R.string.storage_wizard_move_progress_title, appName);
+        setBodyText(R.string.storage_wizard_move_progress_body, volumeName, appName);
+
+        setCurrentProgress(20);
+
+        getNextButton().setVisibility(View.GONE);
+
+        new MoveTask().execute();
+    }
+
+    private CharSequence moveStatusToMessage(int returnCode) {
+        switch (returnCode) {
+            case PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE:
+                return getString(R.string.insufficient_storage);
+            case PackageManager.MOVE_FAILED_DOESNT_EXIST:
+                return getString(R.string.does_not_exist);
+            case PackageManager.MOVE_FAILED_FORWARD_LOCKED:
+                return getString(R.string.app_forward_locked);
+            case PackageManager.MOVE_FAILED_INVALID_LOCATION:
+                return getString(R.string.invalid_location);
+            case PackageManager.MOVE_FAILED_SYSTEM_PACKAGE:
+                return getString(R.string.system_package);
+            case PackageManager.MOVE_FAILED_INTERNAL_ERROR:
+            default:
+                return getString(R.string.insufficient_storage);
+        }
+    }
+
+    private class LocalPackageMoveObserver extends IPackageMoveObserver.Stub {
+        public int returnCode;
+        public CountDownLatch finished = new CountDownLatch(1);
+
+        @Override
+        public void packageMoved(String packageName, int returnCode) throws RemoteException {
+            this.returnCode = returnCode;
+            this.finished.countDown();
+        }
+    }
+
+    public class MoveTask extends AsyncTask<Void, Void, Integer> {
+        @Override
+        protected Integer doInBackground(Void... params) {
+            try {
+                final LocalPackageMoveObserver observer = new LocalPackageMoveObserver();
+
+                if (mApp.isExternalAsec()) {
+                    getPackageManager().movePackage(mPackageName, observer,
+                            PackageManager.MOVE_INTERNAL);
+                } else if (mVolume.getType() == VolumeInfo.TYPE_PUBLIC) {
+                    getPackageManager().movePackage(mPackageName, observer,
+                            PackageManager.MOVE_EXTERNAL_MEDIA);
+                } else {
+                    getPackageManager().movePackageAndData(mPackageName, mVolume.fsUuid, observer);
+                }
+
+                observer.finished.await();
+                return observer.returnCode;
+            } catch (Exception e) {
+                Log.e(TAG, "Failed to move", e);
+                return PackageManager.MOVE_FAILED_INTERNAL_ERROR;
+            }
+        }
+
+        @Override
+        protected void onPostExecute(Integer returnCode) {
+            final Context context = StorageWizardMoveProgress.this;
+            if (returnCode == PackageManager.MOVE_SUCCEEDED) {
+                finishAffinity();
+
+            } else {
+                Log.w(TAG, "Move failed with status " + returnCode);
+                Toast.makeText(context, moveStatusToMessage(returnCode), Toast.LENGTH_LONG).show();
+                finishAffinity();
+            }
+        }
+    }
+}