email: add an option for delete the account

Change-Id: I0f0f2b7ea950d5154f90cd60261c6918b7ad36b7
Signed-off-by: Jorge Ruesga <jorge@ruesga.com>
This commit is contained in:
Jorge Ruesga 2015-03-20 03:13:35 +01:00 committed by Steve Kondik
parent f119f904ed
commit 8b1818d4a8
4 changed files with 165 additions and 5 deletions

View File

@ -18,6 +18,7 @@ package com.android.emailcommon.service;
import android.content.Context;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
@ -30,6 +31,7 @@ import com.android.emailcommon.provider.Policy;
import com.android.mail.utils.LogUtils;
import java.io.IOException;
import java.util.concurrent.Executor;
/**
* The EmailServiceProxy class provides a simple interface for the UI to call into the various
@ -258,6 +260,11 @@ public class EmailServiceProxy extends ServiceProxy implements IEmailService {
@Override
public void deleteExternalAccountPIMData(final String emailAddress) throws RemoteException {
setTask(new ProxyTask() {
@Override
public Executor runInExecutor() {
return AsyncTask.THREAD_POOL_EXECUTOR;
}
@Override
public void run() throws RemoteException {
mService.deleteExternalAccountPIMData(emailAddress);

View File

@ -31,6 +31,8 @@ import android.os.RemoteException;
import com.android.emailcommon.provider.EmailContent;
import com.android.mail.utils.LogUtils;
import java.util.concurrent.Executor;
/**
* ServiceProxy is a superclass for proxy objects which make a single call to a service. It handles
* connecting to the service, running a task supplied by the subclass when the connection is ready,
@ -133,8 +135,8 @@ public abstract class ServiceProxy {
"RuntimeException when trying to unbind from service");
}
}
mTaskCompleted = true;
synchronized(mConnection) {
mTaskCompleted = true;
if (DEBUG_PROXY) {
LogUtils.v(mTag, "Task " + mName + " completed; disconnecting");
}
@ -142,7 +144,7 @@ public abstract class ServiceProxy {
}
return null;
}
}.execute();
}.executeOnExecutor(mTask.runInExecutor());
}
@Override
@ -154,8 +156,11 @@ public abstract class ServiceProxy {
}
}
protected interface ProxyTask {
public void run() throws RemoteException;
protected abstract class ProxyTask {
public Executor runInExecutor() {
return AsyncTask.SERIAL_EXECUTOR;
};
public abstract void run() throws RemoteException;
}
public ServiceProxy setTimeout(int secs) {
@ -178,6 +183,9 @@ public abstract class ServiceProxy {
if (DEBUG_PROXY) {
LogUtils.v(mTag, "Bind requested for task " + mName);
}
synchronized (mConnection) {
mTaskCompleted = false;
}
return mContext.bindService(mIntent, mConnection, Context.BIND_AUTO_CREATE);
}
@ -203,7 +211,9 @@ public abstract class ServiceProxy {
if (DEBUG_PROXY) {
LogUtils.v(mTag, "Waiting for task " + mName + " to complete...");
}
mConnection.wait(mTimeout * 1000L);
if (!mTaskCompleted) {
mConnection.wait(mTimeout * 1000L);
}
} catch (InterruptedException e) {
// Can be ignored safely
}

24
res/values/cm_strings.xml Normal file
View File

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2015 The CaynogenMod 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.
-->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<!-- Delete account -->
<string name="delete_account">Delete account</string>
<string name="delete_account_confirmation_msg">This will delete all the settings and emails of the
account <xliff:g id="account">%s</xliff:g>. This operation cannot be undone.\n\nContinue?</string>
<string name="deleting_account_msg">Deleting account\u2026</string>
<string name="delete_account_failed">Couldn\'t delete the account</string>
</resources>

View File

@ -16,11 +16,15 @@
package com.android.email.activity.setup;
import android.accounts.AccountManager;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.LoaderManager;
import android.app.ProgressDialog;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.Loader;
import android.content.res.Resources;
@ -28,7 +32,11 @@ import android.database.Cursor;
import android.media.Ringtone;
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.Handler.Callback;
import android.os.Message;
import android.os.Vibrator;
import android.preference.CheckBoxPreference;
import android.preference.EditTextPreference;
@ -43,8 +51,12 @@ import android.provider.ContactsContract;
import android.provider.Settings;
import android.support.annotation.NonNull;
import android.text.TextUtils;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.Window;
import android.widget.Toast;
import com.android.email.R;
import com.android.email.SecurityPolicy;
@ -63,6 +75,7 @@ import com.android.mail.providers.Folder;
import com.android.mail.providers.UIProvider;
import com.android.mail.ui.MailAsyncTaskLoader;
import com.android.mail.ui.settings.MailAccountPrefsFragment;
import com.android.mail.ui.settings.PublicPreferenceActivity;
import com.android.mail.ui.settings.SettingsUtils;
import com.android.mail.utils.ContentProviderTask.UpdateTask;
import com.android.mail.utils.LogUtils;
@ -118,6 +131,9 @@ public class AccountSettingsFragment extends MailAccountPrefsFragment
// Request code to start different activities.
private static final int RINGTONE_REQUEST_CODE = 0;
// Message codes
private static final int MSG_DELETE_ACCOUNT = 0;
private EditTextPreference mAccountDescription;
private EditTextPreference mAccountName;
private EditTextPreference mAccountSignature;
@ -128,6 +144,7 @@ public class AccountSettingsFragment extends MailAccountPrefsFragment
private Preference mInboxRingtone;
private Context mContext;
private Handler mHandler;
private Account mAccount;
private com.android.mail.providers.Account mUiAccount;
@ -136,6 +153,18 @@ public class AccountSettingsFragment extends MailAccountPrefsFragment
private Ringtone mRingtone;
private MenuItem mDeleteAccountItem;
private final Callback mHandlerCallback = new Callback() {
@Override
public boolean handleMessage(Message msg) {
if (msg.what == MSG_DELETE_ACCOUNT) {
deleteAccount();
}
return false;
}
};
/**
* This may be null if the account exists but the inbox has not yet been created in the database
* (waiting for initial sync)
@ -176,6 +205,7 @@ public class AccountSettingsFragment extends MailAccountPrefsFragment
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mHandler = new Handler(mHandlerCallback);
setHasOptionsMenu(true);
@ -412,9 +442,39 @@ public class AccountSettingsFragment extends MailAccountPrefsFragment
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
menu.clear();
// Delete account item
mDeleteAccountItem = menu.add(Menu.NONE, Menu.NONE, 0, R.string.delete_account);
mDeleteAccountItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
inflater.inflate(R.menu.settings_fragment_menu, menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.equals(mDeleteAccountItem)) {
AlertDialog.Builder alertBuilder = new AlertDialog.Builder(mContext);
alertBuilder.setTitle(R.string.delete_account);
String msg = getString(R.string.delete_account_confirmation_msg, mAccountEmail);
alertBuilder.setMessage(msg);
alertBuilder.setCancelable(true);
final DialogInterface.OnClickListener cb = new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
mHandler.dispatchMessage(Message.obtain(mHandler, MSG_DELETE_ACCOUNT));
}
};
alertBuilder.setPositiveButton(android.R.string.ok, cb);
alertBuilder.setNegativeButton(android.R.string.cancel, null);
alertBuilder.create().show();
return true;
}
return super.onOptionsItemSelected(item);
}
/**
* Async task loader to load account in order to view/edit it
*/
@ -987,4 +1047,63 @@ public class AccountSettingsFragment extends MailAccountPrefsFragment
AccountServerSettingsActivity.getIntentForOutgoing(getActivity(), account);
getActivity().startActivity(intent);
}
private void deleteAccount() {
AsyncTask<Void, Void, Boolean> task = new AsyncTask<Void, Void, Boolean>() {
private ProgressDialog mDialog;
@Override
protected void onPreExecute() {
// Display an alert dialog to advise the user that the operation is in progress
mDialog = new ProgressDialog(mContext);
mDialog.setMessage(mContext.getString(R.string.deleting_account_msg));
mDialog.setCancelable(false);
mDialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
mDialog.show();
}
@Override
protected void onPostExecute(Boolean result) {
if (!result) {
Toast.makeText(mContext, R.string.delete_account_failed,
Toast.LENGTH_SHORT).show();
}
mDialog.dismiss();
}
@Override
protected Boolean doInBackground(Void... params) {
try {
// Retrieve the necessary information
AccountManager accountManager = (AccountManager)mContext.getSystemService(
Context.ACCOUNT_SERVICE);
android.accounts.Account account = mUiAccount.getAccountManagerAccount();
// Remove the email account and its notifications
ContentResolver resolver = mContext.getContentResolver();
int ret = resolver.delete(mUiAccount.uri, null, null);
if (ret <= 0) {
LogUtils.w(LogUtils.TAG, "Failed to delete account %s", mAccountEmail);
return Boolean.FALSE;
}
NotificationUtils.clearAccountNotifications(mContext, account);
// And now we remove the system account that holds the email service
accountManager.removeAccount(account, getActivity(), null, null);
// We deleted the account, so we need to clear the activity stack, so just show
// the settings fragment and clear the activity stack
Intent intent = new Intent(getActivity(), PublicPreferenceActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK |
Intent.FLAG_ACTIVITY_CLEAR_TOP);
getActivity().startActivity(intent);
} catch (Exception ex) {
LogUtils.w(LogUtils.TAG, ex, "Failed to delete account %s", mAccountEmail);
return Boolean.FALSE;
}
return Boolean.TRUE;
}
};
task.execute();
}
}