/*
* Copyright (C) Winson Chiu
*
* 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 cw.kop.autobackground.settings;
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.preference.PreferenceFragment;
import android.preference.SwitchPreference;
import android.text.TextUtils;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;
import com.dropbox.client2.DropboxAPI;
import com.dropbox.client2.android.AndroidAuthSession;
import com.dropbox.client2.session.AppKeyPair;
import com.google.android.gms.auth.GoogleAuthException;
import com.google.android.gms.auth.GoogleAuthUtil;
import com.google.android.gms.auth.UserRecoverableAuthException;
import com.google.api.client.extensions.android.http.AndroidHttp;
import com.google.api.client.googleapis.extensions.android.gms.auth.GoogleAccountCredential;
import com.google.api.client.googleapis.extensions.android.gms.auth.UserRecoverableAuthIOException;
import com.google.api.client.json.gson.GsonFactory;
import com.google.api.services.drive.Drive;
import com.google.api.services.drive.DriveScopes;
import java.io.IOException;
import java.util.Collections;
import cw.kop.autobackground.BuildConfig;
import cw.kop.autobackground.R;
import cw.kop.autobackground.accounts.GoogleAccount;
public class AccountSettingsFragment extends PreferenceFragment implements SharedPreferences.OnSharedPreferenceChangeListener {
private static final int REQUEST_DRIVE_ACCOUNT = 9005;
private static final int REQUEST_DRIVE_AUTH = 9006;
private Context appContext;
private SwitchPreference googlePref;
private DropboxAPI<AndroidAuthSession> dropboxAPI;
private GoogleAccountCredential driveCredential;
private Drive drive;
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
appContext = activity;
}
@Override
public void onDetach() {
appContext = null;
super.onDetach();
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.preferences_accounts);
AppKeyPair appKeys = new AppKeyPair(ApiKeys.DROPBOX_KEY, ApiKeys.DROPBOX_SECRET);
AndroidAuthSession session = new AndroidAuthSession(appKeys);
dropboxAPI = new DropboxAPI<>(session);
driveCredential = GoogleAccountCredential.usingOAuth2(
appContext,
Collections.singleton(DriveScopes.DRIVE));
if (!TextUtils.isEmpty(AppSettings.getDriveAccountName())) {
driveCredential.setSelectedAccountName(AppSettings.getDriveAccountName());
}
drive = new Drive.Builder(AndroidHttp.newCompatibleTransport(), GsonFactory.getDefaultInstance(), driveCredential)
.setApplicationName(appContext.getResources().getString(R.string.app_name) + "/" + BuildConfig.VERSION_NAME)
.build();
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
googlePref = (SwitchPreference) findPreference("use_google_account");
return inflater.inflate(R.layout.fragment_list, container, false);
}
@Override
public void onResume() {
super.onResume();
getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);
if (dropboxAPI.getSession().authenticationSuccessful()) {
try {
dropboxAPI.getSession().finishAuthentication();
AppSettings.setUseDropboxAccount(true);
AppSettings.setDropboxAccountToken(dropboxAPI.getSession().getOAuth2AccessToken());
}
catch (IllegalStateException e) {
Log.i("DbAuthLog", "Error authenticating", e);
}
}
}
@Override
public void onPause() {
getPreferenceScreen().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this);
super.onPause();
}
@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
if (!((Activity) appContext).isFinishing()) {
switch (key) {
case "use_google_account":
if (AppSettings.useGoogleAccount()) {
startActivityForResult(GoogleAccount.getPickerIntent(),
GoogleAccount.GOOGLE_ACCOUNT_SIGN_IN);
}
else {
GoogleAccount.deleteAccount();
if (AppSettings.useToast()) {
Toast.makeText(appContext,
"Google access token has been deleted",
Toast.LENGTH_SHORT).show();
}
}
break;
case "use_dropbox_account":
if (AppSettings.useDropboxAccount()) {
dropboxAPI.getSession().startOAuth2Authentication(appContext);
}
else {
AppSettings.setDropboxAccountToken("");
if (AppSettings.useToast()) {
Toast.makeText(appContext,
"Dropbox access token has been deleted",
Toast.LENGTH_SHORT).show();
}
}
case "use_google_drive_account":
if (TextUtils.isEmpty(AppSettings.getDriveAccountName())) {
startActivityForResult(driveCredential.newChooseAccountIntent(), REQUEST_DRIVE_ACCOUNT);
}
else {
AppSettings.setDriveAccountName("");
new Thread(new Runnable() {
@Override
public void run() {
try {
driveCredential.getGoogleAccountManager().invalidateAuthToken(driveCredential.getToken());
}
catch (IOException | GoogleAuthException e) {
e.printStackTrace();
}
}
}).start();
if (AppSettings.useToast()) {
Toast.makeText(appContext,
"Google Drive account deactivated",
Toast.LENGTH_SHORT).show();
}
}
}
}
}
@Override
public void onActivityResult(int requestCode, int responseCode, Intent intent) {
if (requestCode == REQUEST_DRIVE_AUTH && responseCode == Activity.RESULT_OK) {
String accountName = intent.getExtras().getString(AccountManager.KEY_ACCOUNT_NAME);
if (!TextUtils.isEmpty(accountName)) {
AppSettings.setDriveAccountName(accountName);
AppSettings.setUseGoogleDriveAccount(true);
driveCredential.setSelectedAccountName(accountName);
new Thread(new Runnable() {
@Override
public void run() {
try {
// Send an about request to check if app is authenticated
drive.about().get().execute();
}
catch (UserRecoverableAuthIOException e) {
startActivityForResult(e.getIntent(), REQUEST_DRIVE_ACCOUNT);
}
catch (IOException e) {
e.printStackTrace();
}
}
}).start();
}
}
else if (requestCode == REQUEST_DRIVE_ACCOUNT && responseCode == Activity.RESULT_OK) {
String accountName = intent.getExtras().getString(AccountManager.KEY_ACCOUNT_NAME);
if (!TextUtils.isEmpty(accountName)) {
AppSettings.setDriveAccountName(accountName);
AppSettings.setUseGoogleDriveAccount(true);
driveCredential.setSelectedAccountName(accountName);
new Thread(new Runnable() {
@Override
public void run() {
try {
// Send an about request to check if app is authenticated
drive.about().get().execute();
}
catch (UserRecoverableAuthIOException e) {
startActivityForResult(e.getIntent(), REQUEST_DRIVE_ACCOUNT);
}
catch (IOException e) {
e.printStackTrace();
}
}
}).start();
}
}
else if (requestCode == GoogleAccount.GOOGLE_ACCOUNT_SIGN_IN) {
if (responseCode == Activity.RESULT_OK) {
final String accountName = intent.getStringExtra(AccountManager.KEY_ACCOUNT_NAME);
AppSettings.setGoogleAccountName(accountName);
new AsyncTask<Void, Void, Void>() {
@Override
protected Void doInBackground(Void... params) {
try {
String authToken = GoogleAuthUtil.getToken(appContext,
accountName,
"oauth2:https://picasaweb.google.com/data/");
AppSettings.setGoogleAccountToken(authToken);
Log.i("MA", "GOOGLE_ACCOUNT_SIGN_IN Token: " + authToken);
}
catch (IOException transientEx) {
return null;
}
catch (UserRecoverableAuthException e) {
e.printStackTrace();
if (isAdded()) {
startActivityForResult(e.getIntent(),
GoogleAccount.GOOGLE_AUTH_CODE);
}
return null;
}
catch (GoogleAuthException authEx) {
return null;
}
catch (Exception e) {
throw new RuntimeException(e);
}
return null;
}
}.execute();
}
else {
googlePref.setChecked(false);
GoogleAccount.deleteAccount();
}
}
else if (requestCode == GoogleAccount.GOOGLE_AUTH_CODE) {
if (responseCode == Activity.RESULT_OK) {
new AsyncTask<Void, Void, Void>() {
@Override
protected Void doInBackground(Void... params) {
try {
String authToken = GoogleAuthUtil.getToken(appContext,
AppSettings.getGoogleAccountName(),
"oauth2:https://picasaweb.google.com/data/");
AppSettings.setGoogleAccountToken(authToken);
Log.i("MA", "GOOGLE_AUTH_CODE Token: " + authToken);
}
catch (IOException transientEx) {
return null;
}
catch (UserRecoverableAuthException e) {
return null;
}
catch (GoogleAuthException authEx) {
return null;
}
catch (Exception e) {
throw new RuntimeException(e);
}
return null;
}
}.execute();
}
else {
googlePref.setChecked(false);
GoogleAccount.deleteAccount();
}
}
}
}