/* * Copyright 2014 Google Inc. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.google.samples.apps.iosched.sync.userdata.gms; import com.google.samples.apps.iosched.util.AccountUtils; import com.google.android.gms.common.ConnectionResult; import com.google.android.gms.common.GooglePlayServicesUtil; import com.google.android.gms.common.api.GoogleApiClient; import com.google.android.gms.common.api.GoogleApiClient.ConnectionCallbacks; import com.google.android.gms.common.api.GoogleApiClient.OnConnectionFailedListener; import com.google.android.gms.drive.Drive; import android.app.Activity; import android.content.Context; import android.content.IntentSender; import android.os.AsyncTask; import android.os.Bundle; import android.util.Log; import java.util.concurrent.CountDownLatch; import static com.google.samples.apps.iosched.util.LogUtils.makeLogTag; /** * An AsyncTask that maintains a connected client. */ public abstract class ApiClientAsyncTask<Params, Progress, Result> extends AsyncTask<Params, Progress, Result> { private static final String TAG = makeLogTag(ApiClientAsyncTask.class); private static final int REQUEST_CODE_RESOLUTION = 1; private GoogleApiClient mClient; private Context mContext; private String lastUsedAccountName; public ApiClientAsyncTask(Context context) { this.mContext = context; } @Override protected final Result doInBackground(Params... params) { Log.d(TAG, "doInBackground of ApiClientAsyncTask"); getGoogleApiClient(); final CountDownLatch latch = new CountDownLatch(1); mClient.registerConnectionCallbacks(new ConnectionCallbacks() { @Override public void onConnectionSuspended(int cause) { } @Override public void onConnected(Bundle arg0) { Log.d(TAG, "ApiClientAsyncTask onConnected"); latch.countDown(); } }); mClient.registerConnectionFailedListener(new OnConnectionFailedListener() { @Override public void onConnectionFailed(ConnectionResult result) { Log.i(TAG, "GoogleApiClient connection failed: " + result.toString()); if (!result.hasResolution()) { // show the localized error dialog. GooglePlayServicesUtil.getErrorDialog(result.getErrorCode(), (Activity) ApiClientAsyncTask.this.getContext(), 0).show(); return; } try { result.startResolutionForResult((Activity) ApiClientAsyncTask.this.getContext(), REQUEST_CODE_RESOLUTION); } catch (IntentSender.SendIntentException e) { Log.e(TAG, "Exception while starting resolution activity", e); } latch.countDown(); } }); mClient.connect(); try { latch.await(); } catch (InterruptedException e) { return null; } if (!mClient.isConnected()) { return null; } try { return doInBackgroundConnected(params); } catch (RuntimeException e) { Log.e(TAG, "ApiClientAsyncTask exception on doInBackgroundConnected!", e); throw e; } finally { mClient.disconnect(); } } /** * Override this method to perform a computation on a background thread, while the client is * connected. */ protected abstract Result doInBackgroundConnected(Params... params); /** * Gets the GoogleApliClient owned by this async task. */ protected GoogleApiClient getGoogleApiClient() { String currentAccountName = AccountUtils.getActiveAccountName(mContext); if (lastUsedAccountName != null && !lastUsedAccountName.equals(currentAccountName)) { if (mClient != null && mClient.isConnected()) { mClient.disconnect(); } mClient = null; lastUsedAccountName = currentAccountName; } if (mClient == null) { GoogleApiClient.Builder builder = new GoogleApiClient.Builder(mContext) .addApi(Drive.API) .setAccountName(currentAccountName) .addScope(Drive.SCOPE_APPFOLDER); mClient = builder.build(); } mClient.connect(); return mClient; } public Context getContext() { return mContext; } }