Bug 1191064 - Part 3: Handle removing Android Accounts from fxa-content-server. r=markh

This adds a new JS to Java ping-pong; exposes it via Accounts.jsm; and
uses it in response to the fxa-content-server message.
This commit is contained in:
Nick Alexander 2015-09-14 17:21:19 -04:00
parent 6086af7511
commit 2fedad2648
3 changed files with 80 additions and 1 deletions

View File

@ -6,6 +6,11 @@
package org.mozilla.gecko; package org.mozilla.gecko;
import android.accounts.Account; import android.accounts.Account;
import android.accounts.AccountManager;
import android.accounts.AccountManagerCallback;
import android.accounts.AccountManagerFuture;
import android.accounts.AuthenticatorException;
import android.accounts.OperationCanceledException;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.util.Log; import android.util.Log;
@ -22,6 +27,7 @@ import org.mozilla.gecko.util.EventCallback;
import org.mozilla.gecko.util.NativeEventListener; import org.mozilla.gecko.util.NativeEventListener;
import org.mozilla.gecko.util.NativeJSObject; import org.mozilla.gecko.util.NativeJSObject;
import java.io.IOException;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.net.URISyntaxException; import java.net.URISyntaxException;
import java.security.GeneralSecurityException; import java.security.GeneralSecurityException;
@ -48,6 +54,7 @@ public class AccountsHelper implements NativeEventListener {
"Accounts:CreateFirefoxAccountFromJSON", "Accounts:CreateFirefoxAccountFromJSON",
"Accounts:UpdateFirefoxAccountFromJSON", "Accounts:UpdateFirefoxAccountFromJSON",
"Accounts:Create", "Accounts:Create",
"Accounts:DeleteFirefoxAccount",
"Accounts:Exist"); "Accounts:Exist");
} }
@ -61,11 +68,12 @@ public class AccountsHelper implements NativeEventListener {
"Accounts:CreateFirefoxAccountFromJSON", "Accounts:CreateFirefoxAccountFromJSON",
"Accounts:UpdateFirefoxAccountFromJSON", "Accounts:UpdateFirefoxAccountFromJSON",
"Accounts:Create", "Accounts:Create",
"Accounts:DeleteFirefoxAccount",
"Accounts:Exist"); "Accounts:Exist");
} }
@Override @Override
public void handleMessage(String event, NativeJSObject message, EventCallback callback) { public void handleMessage(String event, NativeJSObject message, final EventCallback callback) {
if ("Accounts:CreateFirefoxAccountFromJSON".equals(event)) { if ("Accounts:CreateFirefoxAccountFromJSON".equals(event)) {
AndroidFxAccount fxAccount = null; AndroidFxAccount fxAccount = null;
try { try {
@ -157,6 +165,43 @@ public class AccountsHelper implements NativeEventListener {
} }
mContext.startActivity(intent); mContext.startActivity(intent);
} else if ("Accounts:DeleteFirefoxAccount".equals(event)) {
try {
final Account account = FirefoxAccounts.getFirefoxAccount(mContext);
if (account == null) {
Log.w(LOGTAG, "Could not delete Firefox Account since none exists!");
if (callback != null) {
callback.sendError("Could not delete Firefox Account since none exists");
}
return;
}
final AccountManagerCallback<Boolean> accountManagerCallback = new AccountManagerCallback<Boolean>() {
@Override
public void run(AccountManagerFuture<Boolean> future) {
try {
final boolean result = future.getResult();
Log.i(LOGTAG, "Account named like " + Utils.obfuscateEmail(account.name) + " removed: " + result);
if (callback != null) {
callback.sendSuccess(result);
}
} catch (OperationCanceledException | IOException | AuthenticatorException e) {
if (callback != null) {
callback.sendError("Could not delete Firefox Account: " + e.toString());
}
}
}
};
AccountManager.get(mContext).removeAccount(account, accountManagerCallback, null);
} catch (Exception e) {
Log.w(LOGTAG, "Got exception updating Firefox Account from JSON; ignoring.", e);
if (callback != null) {
callback.sendError("Could not update Firefox Account from JSON: " + e.toString());
return;
}
}
} else if ("Accounts:Exist".equals(event)) { } else if ("Accounts:Exist".equals(event)) {
if (callback == null) { if (callback == null) {
Log.w(LOGTAG, "Accounts:Exist requires a callback"); Log.w(LOGTAG, "Accounts:Exist requires a callback");

View File

@ -131,5 +131,18 @@ let Accounts = Object.freeze({
delete data.exists; delete data.exists;
return data; return data;
}); });
},
/**
* Delete an existing Android Firefox Account.
*
* It is an error if no Android Account exists.
*
* Returns a Promise that resolves to a boolean indicating success.
*/
deleteFirefoxAccount: function () {
return Messaging.sendRequestForResult({
type: "Accounts:DeleteFirefoxAccount",
});
} }
}); });

View File

@ -28,6 +28,7 @@ const COMMAND_LOADED = "fxaccounts:loaded";
const COMMAND_CAN_LINK_ACCOUNT = "fxaccounts:can_link_account"; const COMMAND_CAN_LINK_ACCOUNT = "fxaccounts:can_link_account";
const COMMAND_LOGIN = "fxaccounts:login"; const COMMAND_LOGIN = "fxaccounts:login";
const COMMAND_CHANGE_PASSWORD = "fxaccounts:change_password"; const COMMAND_CHANGE_PASSWORD = "fxaccounts:change_password";
const COMMAND_DELETE_ACCOUNT = "fxaccounts:delete_account";
const PREF_LAST_FXA_USER = "identity.fxaccounts.lastSignedInUserHash"; const PREF_LAST_FXA_USER = "identity.fxaccounts.lastSignedInUserHash";
@ -315,6 +316,26 @@ this.FxAccountsWebChannel.prototype = {
}); });
break; break;
case COMMAND_DELETE_ACCOUNT:
// The fxa-content-server has already confirmed the user's intent.
// Bombs away. There's no recovery from failure, and not even a
// real need to check an account exists (although we do, for error
// messaging only).
Accounts.getFirefoxAccount().then(account => {
if (!account) {
throw new Error("Can't delete non-existent Firefox Account!");
}
return Accounts.deleteFirefoxAccount().then(success => {
if (!success) {
throw new Error("Could not delete Firefox Account!");
}
log.i("Firefox Account deleted.");
});
}).catch(e => {
log.e(e.toString());
});
break;
default: default:
log.w("Ignoring unrecognized FxAccountsWebChannel command: " + JSON.stringify(command)); log.w("Ignoring unrecognized FxAccountsWebChannel command: " + JSON.stringify(command));
break; break;