зеркало из https://github.com/mozilla/gecko-dev.git
Bug 714304 - Handle 'Upgrade Required' error response. r=rnewman, a=blocking-fennec
This commit is contained in:
Родитель
3db6dbbf82
Коммит
a6f2573921
|
@ -393,13 +393,39 @@ public class GlobalSession implements CredentialsSource, PrefsSource, HttpRespon
|
|||
callback.requestBackoff(responseBackoff);
|
||||
}
|
||||
|
||||
if (response.getStatusLine() != null && response.getStatusLine().getStatusCode() == 401) {
|
||||
/*
|
||||
* Alert our callback we have a 401 on a cluster URL. This GlobalSession
|
||||
* will fail, but the next one will fetch a new cluster URL and will
|
||||
* distinguish between "node reassignment" and "user password changed".
|
||||
*/
|
||||
callback.informUnauthorizedResponse(this, config.getClusterURL());
|
||||
if (response.getStatusLine() != null) {
|
||||
final int statusCode = response.getStatusLine().getStatusCode();
|
||||
switch(statusCode) {
|
||||
|
||||
case 400:
|
||||
SyncStorageResponse storageResponse = new SyncStorageResponse(response);
|
||||
this.interpretHTTPBadRequestBody(storageResponse);
|
||||
break;
|
||||
|
||||
case 401:
|
||||
/*
|
||||
* Alert our callback we have a 401 on a cluster URL. This GlobalSession
|
||||
* will fail, but the next one will fetch a new cluster URL and will
|
||||
* distinguish between "node reassignment" and "user password changed".
|
||||
*/
|
||||
callback.informUnauthorizedResponse(this, config.getClusterURL());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void interpretHTTPBadRequestBody(final SyncStorageResponse storageResponse) {
|
||||
try {
|
||||
final String body = storageResponse.body();
|
||||
if (body == null) {
|
||||
return;
|
||||
}
|
||||
if (SyncStorageResponse.RESPONSE_CLIENT_UPGRADE_REQUIRED.equals(body)) {
|
||||
callback.informUpgradeRequiredResponse(this);
|
||||
return;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Logger.warn(LOG_TAG, "Exception parsing HTTP 400 body.", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -51,10 +51,16 @@ public interface GlobalSessionCallback {
|
|||
*/
|
||||
void informNodeAuthenticationFailed(GlobalSession globalSession, URI failedClusterURL);
|
||||
|
||||
/**
|
||||
* Called when an HTTP failure indicates that a software upgrade is required.
|
||||
*/
|
||||
void informUpgradeRequiredResponse(GlobalSession session);
|
||||
|
||||
void handleAborted(GlobalSession globalSession, String reason);
|
||||
void handleError(GlobalSession globalSession, Exception ex);
|
||||
void handleSuccess(GlobalSession globalSession);
|
||||
void handleStageCompleted(Stage currentState, GlobalSession globalSession);
|
||||
|
||||
boolean shouldBackOff();
|
||||
|
||||
}
|
||||
|
|
|
@ -13,6 +13,9 @@ import ch.boye.httpclientandroidlib.HttpResponse;
|
|||
|
||||
public class SyncStorageResponse extends SyncResponse {
|
||||
|
||||
// Responses that are actionable get constant status codes.
|
||||
public static final String RESPONSE_CLIENT_UPGRADE_REQUIRED = "16";
|
||||
|
||||
private static final String LOG_TAG = "SyncStorageResponse";
|
||||
public static HashMap<String, String> SERVER_ERROR_MESSAGES;
|
||||
static {
|
||||
|
@ -34,6 +37,7 @@ public class SyncStorageResponse extends SyncResponse {
|
|||
errors.put("13", "Invalid collection");
|
||||
errors.put("14", "User over quota");
|
||||
errors.put("15", "The email does not match the username");
|
||||
errors.put(RESPONSE_CLIENT_UPGRADE_REQUIRED, "Client upgrade required");
|
||||
errors.put("255", "An unexpected server error occurred: pool is empty.");
|
||||
|
||||
// Infrastructure-generated errors.
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
/* 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.receivers;
|
||||
|
||||
import org.mozilla.gecko.sync.Logger;
|
||||
import org.mozilla.gecko.sync.ThreadPool;
|
||||
import org.mozilla.gecko.sync.setup.Constants;
|
||||
import org.mozilla.gecko.sync.setup.SyncAccounts;
|
||||
|
||||
import android.accounts.Account;
|
||||
import android.accounts.AccountManager;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
|
||||
public class UpgradeReceiver extends BroadcastReceiver {
|
||||
private static final String LOG_TAG = "UpgradeReceiver";
|
||||
|
||||
@Override
|
||||
public void onReceive(final Context context, Intent intent) {
|
||||
Logger.debug(LOG_TAG, "Broadcast received.");
|
||||
// Should filter for specific MY_PACKAGE_REPLACED intent, but Android does
|
||||
// not expose it.
|
||||
ThreadPool.run(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
AccountManager accountManager = AccountManager.get(context);
|
||||
Account[] accounts = accountManager.getAccounts();
|
||||
for (Account a : accounts) {
|
||||
if ("1".equals(accountManager.getUserData(a, Constants.DATA_ENABLE_ON_UPGRADE))) {
|
||||
SyncAccounts.setSyncAutomatically(a, true);
|
||||
accountManager.setUserData(a, Constants.DATA_ENABLE_ON_UPGRADE, "0");
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
|
@ -16,6 +16,7 @@ public class Constants {
|
|||
public static final String ACCOUNT_GUID = "account.guid";
|
||||
public static final String CLIENT_NAME = "account.clientName";
|
||||
public static final String NUM_CLIENTS = "account.numClients";
|
||||
public static final String DATA_ENABLE_ON_UPGRADE = "data.enableOnUpgrade";
|
||||
|
||||
// Constants for Activities.
|
||||
public static final String INTENT_EXTRA_IS_SETUP = "isSetup";
|
||||
|
|
|
@ -18,6 +18,7 @@ import org.mozilla.gecko.sync.NonObjectJSONException;
|
|||
import org.mozilla.gecko.sync.SyncConfiguration;
|
||||
import org.mozilla.gecko.sync.SyncConfigurationException;
|
||||
import org.mozilla.gecko.sync.SyncException;
|
||||
import org.mozilla.gecko.sync.ThreadPool;
|
||||
import org.mozilla.gecko.sync.Utils;
|
||||
import org.mozilla.gecko.sync.crypto.KeyBundle;
|
||||
import org.mozilla.gecko.sync.delegates.ClientsDataDelegate;
|
||||
|
@ -532,4 +533,22 @@ public class SyncAdapter extends AbstractThreadedSyncAdapter implements GlobalSe
|
|||
public void informUnauthorizedResponse(GlobalSession session, URI oldClusterURL) {
|
||||
setClusterURLIsStale(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void informUpgradeRequiredResponse(final GlobalSession session) {
|
||||
final AccountManager manager = mAccountManager;
|
||||
final Account toDisable = localAccount;
|
||||
if (toDisable == null || manager == null) {
|
||||
Logger.warn(LOG_TAG, "Attempting to disable account, but null found.");
|
||||
return;
|
||||
}
|
||||
// Sync needs to be upgraded. Don't automatically sync anymore.
|
||||
ThreadPool.run(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
manager.setUserData(toDisable, Constants.DATA_ENABLE_ON_UPGRADE, "1");
|
||||
SyncAccounts.setSyncAutomatically(toDisable, false);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
|
@ -18,3 +18,9 @@
|
|||
android:name="org.mozilla.gecko.sync.setup.activities.SetupFailureActivity" />
|
||||
<activity
|
||||
android:name="org.mozilla.gecko.sync.setup.activities.SetupSuccessActivity" />
|
||||
<receiver
|
||||
android:name="org.mozilla.gecko.sync.receivers.UpgradeReceiver">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MY_PACKAGE_REPLACED" />
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
|
|
Загрузка…
Ссылка в новой задаче