Bug 965811 - Support Firefox Account-based Sync in SendTabActivity. r=nalexander

This commit is contained in:
Richard Newman 2014-03-26 22:21:19 -07:00
parent 2fb365ee88
commit 944d36c10b

View File

@ -12,15 +12,18 @@ import java.util.Map.Entry;
import org.mozilla.gecko.R;
import org.mozilla.gecko.background.common.log.Logger;
import org.mozilla.gecko.fxa.FxAccountConstants;
import org.mozilla.gecko.fxa.activities.FxAccountGetStartedActivity;
import org.mozilla.gecko.fxa.authenticator.AndroidFxAccount;
import org.mozilla.gecko.sync.CommandProcessor;
import org.mozilla.gecko.sync.CommandRunner;
import org.mozilla.gecko.sync.GlobalSession;
import org.mozilla.gecko.sync.SyncConfiguration;
import org.mozilla.gecko.sync.SyncConstants;
import org.mozilla.gecko.sync.Utils;
import org.mozilla.gecko.sync.repositories.NullCursorException;
import org.mozilla.gecko.sync.repositories.android.ClientsDatabaseAccessor;
import org.mozilla.gecko.sync.repositories.domain.ClientRecord;
import org.mozilla.gecko.sync.setup.Constants;
import org.mozilla.gecko.sync.setup.SyncAccounts;
import org.mozilla.gecko.sync.stage.SyncClientsEngineStage;
import org.mozilla.gecko.sync.syncadapter.SyncAdapter;
@ -28,6 +31,8 @@ import org.mozilla.gecko.sync.syncadapter.SyncAdapter;
import android.accounts.Account;
import android.accounts.AccountManager;
import android.app.Activity;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.AsyncTask;
@ -38,10 +43,79 @@ import android.widget.TextView;
import android.widget.Toast;
public class SendTabActivity extends Activity {
private interface TabSender {
static final String[] CLIENTS_STAGE = new String[] { SyncClientsEngineStage.COLLECTION_NAME };
/**
* @return Return null if the account isn't correctly initialized. Return
* the account GUID otherwise.
*/
String getAccountGUID();
/**
* Sync this account, specifying only clients as the engine to sync.
*/
void syncClientsStage();
}
public class FxAccountTabSender implements TabSender {
private final AndroidFxAccount account;
public FxAccountTabSender(Context context, Account account) {
this.account = new AndroidFxAccount(context, account);
}
@Override
public String getAccountGUID() {
try {
final SharedPreferences prefs = this.account.getSyncPrefs();
return prefs.getString(SyncConfiguration.PREF_ACCOUNT_GUID, null);
} catch (Exception e) {
Logger.warn(LOG_TAG, "Could not get Firefox Account parameters or preferences; aborting.");
return null;
}
}
@Override
public void syncClientsStage() {
final Bundle extras = new Bundle();
Utils.putStageNamesToSync(extras, CLIENTS_STAGE, null);
extras.putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, true);
this.account.requestSync(extras);
}
}
private static class Sync11TabSender implements TabSender {
private final Account account;
private final AccountManager accountManager;
private final Context context;
private Sync11TabSender(Context context, Account syncAccount, AccountManager accountManager) {
this.context = context;
this.account = syncAccount;
this.accountManager = accountManager;
}
@Override
public String getAccountGUID() {
try {
final SharedPreferences prefs = SyncAccounts.blockingPrefsFromDefaultProfileV0(this.context, this.accountManager, this.account);
return prefs.getString(SyncConfiguration.PREF_ACCOUNT_GUID, null);
} catch (Exception e) {
Logger.warn(LOG_TAG, "Could not get Sync account parameters or preferences; aborting.");
return null;
}
}
@Override
public void syncClientsStage() {
SyncAdapter.requestImmediateSync(this.account, CLIENTS_STAGE);
}
}
public static final String LOG_TAG = "SendTabActivity";
private ClientRecordArrayAdapter arrayAdapter;
private AccountManager accountManager;
private Account localAccount;
private TabSender tabSender;
private SendTabData sendTabData;
@Override
@ -142,8 +216,35 @@ public class SendTabActivity extends Activity {
Logger.info(LOG_TAG, "Called SendTabActivity.onResume.");
super.onResume();
redirectIfNoSyncAccount();
registerDisplayURICommand();
/*
* First, decide if we are able to send anything.
*/
final Context applicationContext = getApplicationContext();
final AccountManager accountManager = AccountManager.get(applicationContext);
final Account[] fxAccounts = accountManager.getAccountsByType(FxAccountConstants.ACCOUNT_TYPE);
if (fxAccounts.length > 0) {
this.tabSender = new FxAccountTabSender(applicationContext, fxAccounts[0]);
Logger.info(LOG_TAG, "Allowing tab send for Firefox Account.");
registerDisplayURICommand();
return;
}
final Account[] syncAccounts = accountManager.getAccountsByType(SyncConstants.ACCOUNTTYPE_SYNC);
if (syncAccounts.length > 0) {
this.tabSender = new Sync11TabSender(applicationContext, syncAccounts[0], accountManager);
Logger.info(LOG_TAG, "Allowing tab send for Sync account.");
registerDisplayURICommand();
return;
}
// Offer to set up a Firefox Account, and finish this activity.
final Intent intent = new Intent(applicationContext, FxAccountGetStartedActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
finish();
}
private static void registerDisplayURICommand() {
@ -156,41 +257,6 @@ public class SendTabActivity extends Activity {
});
}
private void redirectIfNoSyncAccount() {
accountManager = AccountManager.get(getApplicationContext());
Account[] accts = accountManager.getAccountsByType(SyncConstants.ACCOUNTTYPE_SYNC);
// A Sync account exists.
if (accts.length > 0) {
localAccount = accts[0];
return;
}
Intent intent = new Intent(this, RedirectToSetupActivity.class);
intent.setFlags(Constants.FLAG_ACTIVITY_REORDER_TO_FRONT_NO_ANIMATION);
startActivity(intent);
finish();
}
/**
* @return Return null if there is no account set up. Return the account GUID otherwise.
*/
private String getAccountGUID() {
if (localAccount == null) {
Logger.warn(LOG_TAG, "Null local account; aborting.");
return null;
}
SharedPreferences prefs;
try {
prefs = SyncAccounts.blockingPrefsFromDefaultProfileV0(this, accountManager, localAccount);
return prefs.getString(SyncConfiguration.PREF_ACCOUNT_GUID, null);
} catch (Exception e) {
Logger.warn(LOG_TAG, "Could not get Sync account parameters or preferences; aborting.");
return null;
}
}
public void sendClickHandler(View view) {
Logger.info(LOG_TAG, "Send was clicked.");
final List<String> remoteClientGuids = arrayAdapter.getCheckedGUIDs();
@ -202,6 +268,14 @@ public class SendTabActivity extends Activity {
return;
}
final TabSender sender = this.tabSender;
if (sender == null) {
// This should never happen.
Logger.warn(LOG_TAG, "tabSender was null; aborting without sending tab.");
notifyAndFinish(false);
return;
}
// Fetching local client GUID hits the DB, and we want to update the UI
// afterward, so we perform the tab sending on another thread.
new AsyncTask<Void, Void, Boolean>() {
@ -210,7 +284,7 @@ public class SendTabActivity extends Activity {
protected Boolean doInBackground(Void... params) {
final CommandProcessor processor = CommandProcessor.getProcessor();
final String accountGUID = getAccountGUID();
final String accountGUID = sender.getAccountGUID();
Logger.debug(LOG_TAG, "Retrieved local account GUID '" + accountGUID + "'.");
if (accountGUID == null) {
return false;
@ -221,7 +295,7 @@ public class SendTabActivity extends Activity {
}
Logger.info(LOG_TAG, "Requesting immediate clients stage sync.");
SyncAdapter.requestImmediateSync(localAccount, new String[] { SyncClientsEngineStage.COLLECTION_NAME });
sender.syncClientsStage();
return true;
}
@ -286,7 +360,12 @@ public class SendTabActivity extends Activity {
return new ArrayList<ClientRecord>(0);
}
final String ourGUID = getAccountGUID();
if (this.tabSender == null) {
Logger.warn(LOG_TAG, "No tab sender when fetching other client IDs.");
return new ArrayList<ClientRecord>(0);
}
final String ourGUID = this.tabSender.getAccountGUID();
if (ourGUID == null) {
return all.values();
}