зеркало из https://github.com/mozilla/gecko-dev.git
242 строки
8.0 KiB
Java
242 строки
8.0 KiB
Java
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
package org.mozilla.gecko.sync.setup.activities;
|
|
|
|
import java.util.List;
|
|
|
|
import org.mozilla.gecko.R;
|
|
import org.mozilla.gecko.sync.CommandProcessor;
|
|
import org.mozilla.gecko.sync.CommandRunner;
|
|
import org.mozilla.gecko.sync.CredentialException;
|
|
import org.mozilla.gecko.sync.GlobalConstants;
|
|
import org.mozilla.gecko.sync.GlobalSession;
|
|
import org.mozilla.gecko.sync.Logger;
|
|
import org.mozilla.gecko.sync.SyncConfiguration;
|
|
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.setup.SyncAccounts.SyncAccountParameters;
|
|
import org.mozilla.gecko.sync.stage.SyncClientsEngineStage;
|
|
import org.mozilla.gecko.sync.syncadapter.SyncAdapter;
|
|
|
|
import android.accounts.Account;
|
|
import android.accounts.AccountManager;
|
|
import android.app.Activity;
|
|
import android.content.Context;
|
|
import android.content.Intent;
|
|
import android.content.SharedPreferences;
|
|
import android.os.AsyncTask;
|
|
import android.os.Bundle;
|
|
import android.view.View;
|
|
import android.widget.ListView;
|
|
import android.widget.Toast;
|
|
|
|
public class SendTabActivity extends Activity {
|
|
public static final String LOG_TAG = "SendTabActivity";
|
|
private ClientRecordArrayAdapter arrayAdapter;
|
|
private AccountManager accountManager;
|
|
private Account localAccount;
|
|
|
|
@Override
|
|
public void onCreate(Bundle savedInstanceState) {
|
|
super.onCreate(savedInstanceState);
|
|
}
|
|
|
|
@Override
|
|
public void onResume() {
|
|
Logger.info(LOG_TAG, "Called SendTabActivity.onResume.");
|
|
super.onResume();
|
|
|
|
redirectIfNoSyncAccount();
|
|
registerDisplayURICommand();
|
|
|
|
setContentView(R.layout.sync_send_tab);
|
|
final ListView listview = (ListView) findViewById(R.id.device_list);
|
|
listview.setItemsCanFocus(true);
|
|
listview.setTextFilterEnabled(true);
|
|
listview.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
|
|
enableSend(false);
|
|
|
|
// Fetching the client list hits the clients database, so we spin this onto
|
|
// a background task.
|
|
final Context context = this;
|
|
new AsyncTask<Void, Void, ClientRecord[]>() {
|
|
|
|
@Override
|
|
protected ClientRecord[] doInBackground(Void... params) {
|
|
return getClientArray();
|
|
}
|
|
|
|
@Override
|
|
protected void onPostExecute(final ClientRecord[] clientArray) {
|
|
// We're allowed to update the UI from here.
|
|
arrayAdapter = new ClientRecordArrayAdapter(context, R.layout.sync_list_item, clientArray);
|
|
listview.setAdapter(arrayAdapter);
|
|
}
|
|
}.execute();
|
|
}
|
|
|
|
private static void registerDisplayURICommand() {
|
|
final CommandProcessor processor = CommandProcessor.getProcessor();
|
|
processor.registerCommand("displayURI", new CommandRunner(3) {
|
|
@Override
|
|
public void executeCommand(final GlobalSession session, List<String> args) {
|
|
CommandProcessor.displayURI(args, session.getContext());
|
|
}
|
|
});
|
|
}
|
|
|
|
private void redirectIfNoSyncAccount() {
|
|
accountManager = AccountManager.get(getApplicationContext());
|
|
Account[] accts = accountManager.getAccountsByType(GlobalConstants.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;
|
|
}
|
|
|
|
SyncAccountParameters params;
|
|
try {
|
|
params = SyncAccounts.blockingFromAndroidAccountV0(this, accountManager, localAccount);
|
|
} catch (CredentialException e) {
|
|
Logger.warn(LOG_TAG, "Could not get sync account parameters; aborting.");
|
|
return null;
|
|
}
|
|
|
|
SharedPreferences prefs;
|
|
try {
|
|
final String product = GlobalConstants.BROWSER_INTENT_PACKAGE;
|
|
final String profile = Constants.DEFAULT_PROFILE;
|
|
final long version = SyncConfiguration.CURRENT_PREFS_VERSION;
|
|
prefs = Utils.getSharedPreferences(getApplicationContext(), product, params.username, params.serverURL, profile, version);
|
|
return prefs.getString(SyncConfiguration.PREF_ACCOUNT_GUID, null);
|
|
} catch (Exception e) {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
public void sendClickHandler(View view) {
|
|
Logger.info(LOG_TAG, "Send was clicked.");
|
|
Bundle extras = this.getIntent().getExtras();
|
|
if (extras == null) {
|
|
Logger.warn(LOG_TAG, "extras was null; aborting without sending tab.");
|
|
notifyAndFinish(false);
|
|
return;
|
|
}
|
|
|
|
final String uri = extras.getString(Intent.EXTRA_TEXT);
|
|
final String title = extras.getString(Intent.EXTRA_SUBJECT);
|
|
final List<String> guids = arrayAdapter.getCheckedGUIDs();
|
|
|
|
if (title == null) {
|
|
Logger.warn(LOG_TAG, "title was null; ignoring and sending tab anyway.");
|
|
}
|
|
|
|
if (uri == null) {
|
|
Logger.warn(LOG_TAG, "uri was null; aborting without sending tab.");
|
|
notifyAndFinish(false);
|
|
return;
|
|
}
|
|
|
|
if (guids == null) {
|
|
// Should never happen.
|
|
Logger.warn(LOG_TAG, "guids 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>() {
|
|
|
|
@Override
|
|
protected Boolean doInBackground(Void... params) {
|
|
final CommandProcessor processor = CommandProcessor.getProcessor();
|
|
|
|
final String accountGUID = getAccountGUID();
|
|
Logger.debug(LOG_TAG, "Retrieved local account GUID '" + accountGUID + "'.");
|
|
if (accountGUID == null) {
|
|
return false;
|
|
}
|
|
|
|
for (String guid : guids) {
|
|
processor.sendURIToClientForDisplay(uri, guid, title, accountGUID, getApplicationContext());
|
|
}
|
|
|
|
Logger.info(LOG_TAG, "Requesting immediate clients stage sync.");
|
|
SyncAdapter.requestImmediateSync(localAccount, new String[] { SyncClientsEngineStage.COLLECTION_NAME });
|
|
|
|
return true;
|
|
}
|
|
|
|
@Override
|
|
protected void onPostExecute(final Boolean success) {
|
|
// We're allowed to update the UI from here.
|
|
notifyAndFinish(success.booleanValue());
|
|
}
|
|
}.execute();
|
|
}
|
|
|
|
/**
|
|
* Notify the user about sent tabs status and then finish the activity.
|
|
* <p>
|
|
* "Success" is a bit of a misnomer: we wrote "displayURI" commands to the local
|
|
* command database, and they will be sent on next sync. There is no way to
|
|
* verify that the commands were successfully received by the intended remote
|
|
* client, so we lie and say they were sent.
|
|
*
|
|
* @param success true if tab was sent successfully; false otherwise.
|
|
*/
|
|
protected void notifyAndFinish(final boolean success) {
|
|
int textId;
|
|
if (success) {
|
|
textId = R.string.sync_text_tab_sent;
|
|
} else {
|
|
textId = R.string.sync_text_tab_not_sent;
|
|
}
|
|
|
|
Toast.makeText(this, textId, Toast.LENGTH_LONG).show();
|
|
finish();
|
|
}
|
|
|
|
public void enableSend(boolean shouldEnable) {
|
|
View sendButton = findViewById(R.id.send_button);
|
|
sendButton.setEnabled(shouldEnable);
|
|
sendButton.setClickable(shouldEnable);
|
|
}
|
|
|
|
protected ClientRecord[] getClientArray() {
|
|
ClientsDatabaseAccessor db = new ClientsDatabaseAccessor(this.getApplicationContext());
|
|
|
|
try {
|
|
return db.fetchAllClients().values().toArray(new ClientRecord[0]);
|
|
} catch (NullCursorException e) {
|
|
Logger.warn(LOG_TAG, "NullCursorException while populating device list.", e);
|
|
return null;
|
|
} finally {
|
|
db.close();
|
|
}
|
|
}
|
|
}
|