summaryrefslogtreecommitdiffstats
path: root/mobile/android/services/src/main/java/org/mozilla/gecko/fxa/sync/FxAccountProfileService.java
blob: 7f03eff1c9847543afdbb166a561d0a3071b474c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
/* 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.fxa.sync;

import android.accounts.AccountManager;
import android.app.Activity;
import android.app.IntentService;
import android.content.Intent;
import android.os.Bundle;
import android.os.ResultReceiver;

import org.mozilla.gecko.background.common.log.Logger;
import org.mozilla.gecko.background.fxa.FxAccountUtils;
import org.mozilla.gecko.background.fxa.oauth.FxAccountAbstractClient;
import org.mozilla.gecko.background.fxa.oauth.FxAccountAbstractClientException;
import org.mozilla.gecko.background.fxa.profile.FxAccountProfileClient10;
import org.mozilla.gecko.fxa.FxAccountConstants;
import org.mozilla.gecko.sync.ExtendedJSONObject;

import java.util.concurrent.Executor;
import java.util.concurrent.Executors;

public class FxAccountProfileService extends IntentService {
  private static final String LOG_TAG = "FxAccountProfileService";
  private static final Executor EXECUTOR_SERVICE = Executors.newSingleThreadExecutor();
  public static final String KEY_AUTH_TOKEN = "auth_token";
  public static final String KEY_PROFILE_SERVER_URI = "profileServerURI";
  public static final String KEY_RESULT_RECEIVER = "resultReceiver";
  public static final String KEY_RESULT_STRING = "RESULT_STRING";

  public FxAccountProfileService() {
    super("FxAccountProfileService");
  }

  @Override
  protected void onHandleIntent(Intent intent) {
    final String authToken = intent.getStringExtra(KEY_AUTH_TOKEN);
    final String profileServerURI = intent.getStringExtra(KEY_PROFILE_SERVER_URI);
    final ResultReceiver resultReceiver = intent.getParcelableExtra(KEY_RESULT_RECEIVER);

    if (resultReceiver == null) {
      Logger.warn(LOG_TAG, "Result receiver must not be null; ignoring intent.");
      return;
    }

    if (authToken == null || authToken.length() == 0) {
      Logger.warn(LOG_TAG, "Invalid Auth Token");
      sendResult("Invalid Auth Token", resultReceiver, Activity.RESULT_CANCELED);
      return;
    }

    if (profileServerURI == null || profileServerURI.length() == 0) {
      Logger.warn(LOG_TAG, "Invalid profile Server Endpoint");
      sendResult("Invalid profile Server Endpoint", resultReceiver, Activity.RESULT_CANCELED);
      return;
    }

    // This delegate fetches the profile avatar json.
    FxAccountProfileClient10.RequestDelegate<ExtendedJSONObject> delegate = new FxAccountAbstractClient.RequestDelegate<ExtendedJSONObject>() {
      @Override
      public void handleError(Exception e) {
        Logger.error(LOG_TAG, "Error fetching Account profile.", e);
        sendResult("Error fetching Account profile.", resultReceiver, Activity.RESULT_CANCELED);
      }

      @Override
      public void handleFailure(FxAccountAbstractClientException.FxAccountAbstractClientRemoteException e) {
        Logger.warn(LOG_TAG, "Failed to fetch Account profile.", e);

        if (e.isInvalidAuthentication()) {
          // The profile server rejected the cached oauth token! Invalidate it.
          // A new token will be generated upon next request.
          Logger.info(LOG_TAG, "Invalidating oauth token after 401!");
          AccountManager.get(FxAccountProfileService.this).invalidateAuthToken(FxAccountConstants.ACCOUNT_TYPE, authToken);
        }

        sendResult("Failed to fetch Account profile.", resultReceiver, Activity.RESULT_CANCELED);
      }

      @Override
      public void handleSuccess(ExtendedJSONObject result) {
        if (result != null){
          FxAccountUtils.pii(LOG_TAG, "Profile server return profile: " + result.toJSONString());
          sendResult(result.toJSONString(), resultReceiver, Activity.RESULT_OK);
        }
      }
    };

    FxAccountProfileClient10 client = new FxAccountProfileClient10(profileServerURI, EXECUTOR_SERVICE);
    try {
      client.profile(authToken, delegate);
    } catch (Exception e) {
      Logger.error(LOG_TAG, "Got exception fetching profile.", e);
      delegate.handleError(e);
    }
  }

  private void sendResult(final String result, final ResultReceiver resultReceiver, final int code) {
    if (resultReceiver != null) {
      final Bundle bundle = new Bundle();
      bundle.putString(KEY_RESULT_STRING, result);
      resultReceiver.send(code, bundle);
    }
  }
}