示例#1
0
  /** Sign out and disconnect from the APIs. */
  public void signOut() {
    if (!mGoogleApiClient.isConnected()) {
      // nothing to do
      debugLog("signOut: was already disconnected, ignoring.");
      return;
    }

    // for Plus, "signing out" means clearing the default account and
    // then disconnecting
    if (0 != (mRequestedClients & CLIENT_PLUS)) {
      debugLog("Clearing default account on PlusClient.");
      Plus.AccountApi.clearDefaultAccount(mGoogleApiClient);
    }

    // For the games client, signing out means calling signOut and
    // disconnecting
    if (0 != (mRequestedClients & CLIENT_GAMES)) {
      debugLog("Signing out from the Google API Client.");
      Games.signOut(mGoogleApiClient);
    }

    // Ready to disconnect
    debugLog("Disconnecting client.");
    mConnectOnStart = false;
    mConnecting = false;
    mGoogleApiClient.disconnect();
  }
示例#2
0
  /** Call this method from your Activity's onStart(). */
  public void onStart(Activity act) {
    mActivity = act;
    mAppContext = act.getApplicationContext();

    debugLog("onStart");
    assertConfigured("onStart");

    if (mConnectOnStart) {
      if (mGoogleApiClient.isConnected()) {
        Log.w(TAG, "GameHelper: client was already connected on onStart()");
      } else {
        debugLog("Connecting client.");
        mConnecting = true;
        mGoogleApiClient.connect();
      }
    } else {
      debugLog("Not attempting to connect becase mConnectOnStart=false");
      debugLog("Instead, reporting a sign-in failure.");
      mHandler.postDelayed(
          new Runnable() {
            @Override
            public void run() {
              notifyListener(false);
            }
          },
          1000);
    }
  }
示例#3
0
 /** Called when we are disconnected from the Google API client. */
 @Override
 public void onConnectionSuspended(int cause) {
   debugLog("onConnectionSuspended, cause=" + cause);
   disconnect();
   mSignInFailureReason = null;
   debugLog("Making extraordinary call to onSignInFailed callback");
   mConnecting = false;
   notifyListener(false);
 }
示例#4
0
 void connect() {
   if (mGoogleApiClient.isConnected()) {
     debugLog("Already connected.");
     return;
   }
   debugLog("Starting connection.");
   mConnecting = true;
   mInvitation = null;
   mTurnBasedMatch = null;
   mGoogleApiClient.connect();
 }
示例#5
0
  /**
   * Handle activity result. Call this method from your Activity's onActivityResult callback. If the
   * activity result pertains to the sign-in process, processes it appropriately.
   */
  public void onActivityResult(int requestCode, int responseCode, Intent intent) {
    debugLog(
        "onActivityResult: req="
            + (requestCode == RC_RESOLVE ? "RC_RESOLVE" : String.valueOf(requestCode))
            + ", resp="
            + GameHelperUtils.activityResponseCodeToString(responseCode));
    if (requestCode != RC_RESOLVE) {
      debugLog("onActivityResult: request code not meant for us. Ignoring.");
      return;
    }

    // no longer expecting a resolution
    mExpectingResolution = false;

    if (!mConnecting) {
      debugLog("onActivityResult: ignoring because we are not connecting.");
      return;
    }

    // We're coming back from an activity that was launched to resolve a
    // connection problem. For example, the sign-in UI.
    if (responseCode == Activity.RESULT_OK) {
      // Ready to try to connect again.
      debugLog("onAR: Resolution was RESULT_OK, so connecting current client again.");
      connect();
    } else if (responseCode == GamesActivityResultCodes.RESULT_RECONNECT_REQUIRED) {
      debugLog("onAR: Resolution was RECONNECT_REQUIRED, so reconnecting.");
      connect();
    } else if (responseCode == Activity.RESULT_CANCELED) {
      // User cancelled.
      debugLog("onAR: Got a cancellation result, so disconnecting.");
      mSignInCancelled = true;
      mConnectOnStart = false;
      mUserInitiatedSignIn = false;
      mSignInFailureReason = null; // cancelling is not a failure!
      mConnecting = false;
      mGoogleApiClient.disconnect();

      // increment # of cancellations
      int prevCancellations = getSignInCancellations();
      int newCancellations = incrementSignInCancellations();
      debugLog(
          "onAR: # of cancellations "
              + prevCancellations
              + " --> "
              + newCancellations
              + ", max "
              + mMaxAutoSignInAttempts);

      notifyListener(false);
    } else {
      // Whatever the problem we were trying to solve, it was not
      // solved. So give up and show an error message.
      debugLog(
          "onAR: responseCode="
              + GameHelperUtils.activityResponseCodeToString(responseCode)
              + ", so giving up.");
      giveUp(new SignInFailureReason(mConnectionResult.getErrorCode(), responseCode));
    }
  }
示例#6
0
  /** Call this method from your Activity's onStop(). */
  public void onStop() {
    debugLog("onStop");
    assertConfigured("onStop");
    if (mGoogleApiClient.isConnected()) {
      debugLog("Disconnecting client due to onStop");
      mGoogleApiClient.disconnect();
    } else {
      debugLog("Client already disconnected when we got onStop.");
    }
    mConnecting = false;
    mExpectingResolution = false;

    // let go of the Activity reference
    mActivity = null;
  }
示例#7
0
 void succeedSignIn() {
   debugLog("succeedSignIn");
   mSignInFailureReason = null;
   mConnectOnStart = true;
   mUserInitiatedSignIn = false;
   mConnecting = false;
   notifyListener(true);
 }
示例#8
0
 public void disconnect() {
   if (mGoogleApiClient.isConnected()) {
     debugLog("Disconnecting client.");
     mGoogleApiClient.disconnect();
   } else {
     Log.w(TAG, "disconnect() called when client was already disconnected.");
   }
 }
示例#9
0
  /**
   * Starts a user-initiated sign-in flow. This should be called when the user clicks on a "Sign In"
   * button. As a result, authentication/consent dialogs may show up. At the end of the process, the
   * GameHelperListener's onSignInSucceeded() or onSignInFailed() methods will be called.
   */
  public void beginUserInitiatedSignIn() {
    debugLog("beginUserInitiatedSignIn: resetting attempt count.");
    resetSignInCancellations();
    mSignInCancelled = false;
    mConnectOnStart = true;

    if (mGoogleApiClient.isConnected()) {
      // nothing to do
      logWarn(
          "beginUserInitiatedSignIn() called when already connected. "
              + "Calling listener directly to notify of success.");
      notifyListener(true);
      return;
    } else if (mConnecting) {
      logWarn(
          "beginUserInitiatedSignIn() called when already connecting. "
              + "Be patient! You can only call this method after you get an "
              + "onSignInSucceeded() or onSignInFailed() callback. Suggestion: disable "
              + "the sign-in button on startup and also when it's clicked, and re-enable "
              + "when you get the callback.");
      // ignore call (listener will get a callback when the connection
      // process finishes)
      return;
    }

    debugLog("Starting USER-INITIATED sign-in flow.");

    // indicate that user is actively trying to sign in (so we know to
    // resolve
    // connection problems by showing dialogs)
    mUserInitiatedSignIn = true;

    if (mConnectionResult != null) {
      // We have a pending connection result from a previous failure, so
      // start with that.
      debugLog("beginUserInitiatedSignIn: continuing pending sign-in flow.");
      mConnecting = true;
      resolveConnectionResult();
    } else {
      // We don't have a pending connection result, so start anew.
      debugLog("beginUserInitiatedSignIn: starting new sign-in flow.");
      mConnecting = true;
      connect();
    }
  }
示例#10
0
 /** Disconnects the API client, then connects again. */
 public void reconnectClient() {
   if (!mGoogleApiClient.isConnected()) {
     Log.w(TAG, "reconnectClient() called when client is not connected.");
     // interpret it as a request to connect
     connect();
   } else {
     debugLog("Reconnecting client.");
     mGoogleApiClient.reconnect();
   }
 }
示例#11
0
  /** Called when we successfully obtain a connection to a client. */
  @Override
  public void onConnected(Bundle connectionHint) {
    debugLog("onConnected: connected!");

    if (connectionHint != null) {
      debugLog("onConnected: connection hint provided. Checking for invite.");
      Invitation inv = connectionHint.getParcelable(Multiplayer.EXTRA_INVITATION);
      if (inv != null && inv.getInvitationId() != null) {
        // retrieve and cache the invitation ID
        debugLog("onConnected: connection hint has a room invite!");
        mInvitation = inv;
        debugLog("Invitation ID: " + mInvitation.getInvitationId());
      }

      // Do we have any requests pending?
      mRequests = Games.Requests.getGameRequestsFromBundle(connectionHint);
      if (!mRequests.isEmpty()) {
        // We have requests in onConnected's connectionHint.
        debugLog("onConnected: connection hint has " + mRequests.size() + " request(s)");
      }

      debugLog("onConnected: connection hint provided. Checking for TBMP game.");
      mTurnBasedMatch = connectionHint.getParcelable(Multiplayer.EXTRA_TURN_BASED_MATCH);
    }

    // we're good to go
    succeedSignIn();
  }
示例#12
0
  /**
   * Attempts to resolve a connection failure. This will usually involve starting a UI flow that
   * lets the user give the appropriate consents necessary for sign-in to work.
   */
  void resolveConnectionResult() {
    // Try to resolve the problem
    if (mExpectingResolution) {
      debugLog("We're already expecting the result of a previous resolution.");
      return;
    }

    if (mActivity == null) {
      debugLog("No need to resolve issue, activity does not exist anymore");
      return;
    }

    debugLog("resolveConnectionResult: trying to resolve result: " + mConnectionResult);
    if (mConnectionResult.hasResolution()) {
      // This problem can be fixed. So let's try to fix it.
      debugLog("Result has resolution. Starting it.");
      try {
        // launch appropriate UI flow (which might, for example, be the
        // sign-in flow)
        mExpectingResolution = true;
        mConnectionResult.startResolutionForResult(mActivity, RC_RESOLVE);
      } catch (SendIntentException e) {
        // Try connecting again
        debugLog("SendIntentException, so connecting again.");
        connect();
      }
    } else {
      // It's not a problem what we can solve, so give up and show an
      // error.
      debugLog("resolveConnectionResult: result has no resolution. Giving up.");
      giveUp(new SignInFailureReason(mConnectionResult.getErrorCode()));
    }
  }
示例#13
0
 void notifyListener(boolean success) {
   debugLog(
       "Notifying LISTENER of sign-in "
           + (success
               ? "SUCCESS"
               : mSignInFailureReason != null ? "FAILURE (error)" : "FAILURE (no error)"));
   if (mListener != null) {
     if (success) {
       mListener.onSignInSucceeded();
     } else {
       mListener.onSignInFailed();
     }
   }
 }
示例#14
0
  public void showFailureDialog() {
    if (mSignInFailureReason != null) {
      int errorCode = mSignInFailureReason.getServiceErrorCode();
      int actResp = mSignInFailureReason.getActivityResultCode();

      if (mShowErrorDialogs) {
        showFailureDialog(mActivity, actResp, errorCode);
      } else {
        debugLog(
            "Not showing error dialog because mShowErrorDialogs==false. "
                + ""
                + "Error was: "
                + mSignInFailureReason);
      }
    }
  }
示例#15
0
  /**
   * Performs setup on this GameHelper object. Call this from the onCreate() method of your
   * Activity. This will create the clients and do a few other initialization tasks. Next,
   * call @link{#onStart} from the onStart() method of your Activity.
   *
   * @param listener The listener to be notified of sign-in events.
   */
  public void setup(GameHelperListener listener) {
    if (mSetupDone) {
      String error = "GameHelper: you cannot call GameHelper.setup() more than once!";
      logError(error);
      throw new IllegalStateException(error);
    }
    mListener = listener;
    debugLog("Setup: requested clients: " + mRequestedClients);

    if (mGoogleApiClientBuilder == null) {
      // we don't have a builder yet, so create one
      createApiClientBuilder();
    }

    mGoogleApiClient = mGoogleApiClientBuilder.build();
    mGoogleApiClientBuilder = null;
    mSetupDone = true;
  }
示例#16
0
 // Not recommended for general use. This method forces the
 // "connect on start" flag
 // to a given state. This may be useful when using GameHelper in a
 // non-standard
 // sign-in flow.
 public void setConnectOnStart(boolean connectOnStart) {
   debugLog("Forcing mConnectOnStart=" + connectOnStart);
   mConnectOnStart = connectOnStart;
 }
示例#17
0
 /** Enables debug logging */
 public void enableDebugLog(boolean enabled) {
   mDebugLog = enabled;
   if (enabled) {
     debugLog("Debug log enabled.");
   }
 }
示例#18
0
  /** Handles a connection failure. */
  @Override
  public void onConnectionFailed(ConnectionResult result) {
    // save connection result for later reference
    debugLog("onConnectionFailed");

    mConnectionResult = result;
    debugLog("Connection failure:");
    debugLog("   - code: " + GameHelperUtils.errorCodeToString(mConnectionResult.getErrorCode()));
    debugLog("   - resolvable: " + mConnectionResult.hasResolution());
    debugLog("   - details: " + mConnectionResult.toString());

    int cancellations = getSignInCancellations();
    boolean shouldResolve;

    if (mUserInitiatedSignIn) {
      debugLog("onConnectionFailed: WILL resolve because user initiated sign-in.");
      shouldResolve = true;
    } else if (mSignInCancelled) {
      debugLog("onConnectionFailed WILL NOT resolve (user already cancelled once).");
      shouldResolve = false;
    } else if (cancellations < mMaxAutoSignInAttempts) {
      debugLog(
          "onConnectionFailed: WILL resolve because we have below the max# of "
              + "attempts, "
              + cancellations
              + " < "
              + mMaxAutoSignInAttempts);
      shouldResolve = true;
    } else {
      shouldResolve = false;
      debugLog(
          "onConnectionFailed: Will NOT resolve; not user-initiated and max attempts "
              + "reached: "
              + cancellations
              + " >= "
              + mMaxAutoSignInAttempts);
    }

    if (!shouldResolve) {
      // Fail and wait for the user to want to sign in.
      debugLog("onConnectionFailed: since we won't resolve, failing now.");
      mConnectionResult = result;
      mConnecting = false;
      notifyListener(false);
      return;
    }

    debugLog("onConnectionFailed: resolving problem...");

    // Resolve the connection result. This usually means showing a dialog or
    // starting an Activity that will allow the user to give the appropriate
    // consents so that sign-in can be successful.
    resolveConnectionResult();
  }