public static Account getAccount(final AccountManager manager, final Activity activity) throws IOException, AccountsException { if (activity == null) throw new IllegalArgumentException("Activity cannot be null."); if (activity.isFinishing()) throw new OperationCanceledException(); Account account = getAccount(activity); if (account == null) { try { manager.addAccount(ACCOUNT_TYPE, null, null, null, activity, null, null).getResult(); } catch (Exception e) { Timber.w(e, "Exception while adding account."); if (e instanceof OperationCanceledException) activity.finish(); else throw e; } // XXX What? account = getAccount(manager, activity); } return account; }
public Instance(Account account, AccountManager manager) throws AccountsException, IOException { mUrl = manager.getUserData(account, Authenticator.KEY_INSTANCE_URL); mEmail = manager.getUserData(account, Authenticator.KEY_ACCOUNT_NAME); mToken = manager.blockingGetAuthToken(account, Authenticator.AUTH_TOKEN_TYPE_GLOBAL, true); if (BuildConfig.DEBUG) Log.d("Instance URL", "URL = " + mUrl); if (BuildConfig.DEBUG) Log.d("Instance Token", "TOKEN = " + mToken); }
/** * Adds a Google account to the device. * * <p>TODO(adorokhine): Support adding accounts of other types with an optional 'type' kwarg. * * <p>TODO(adorokhine): Allow users to choose whether to enable/disable sync with a kwarg. * * @param username Username of the account to add (including @gmail.com). * @param password Password of the account to add. */ @Rpc( description = "Add a Google (GMail) account to the device, with account data sync disabled." ) public void addAccount(String username, String password) throws AccountSnippetException, AccountsException, IOException { // Check for existing account. If we try to re-add an existing account, Android throws an // exception that says "Account does not exist or not visible. Maybe change pwd?" which is // a little hard to understand. if (listAccounts().contains(username)) { throw new AccountSnippetException( "Account " + username + " already exists on the device"); } Bundle addAccountOptions = new Bundle(); addAccountOptions.putString("username", username); addAccountOptions.putString("password", password); AccountManagerFuture<Bundle> future = mAccountManager.addAccount( GOOGLE_ACCOUNT_TYPE, AUTH_TOKEN_TYPE, null /* requiredFeatures */, addAccountOptions, null /* activity */, null /* authCallback */, null /* handler */); Bundle result = future.getResult(); if (result.containsKey(AccountManager.KEY_ERROR_CODE)) { throw new AccountSnippetException( String.format( Locale.US, "Failed to add account due to code %d: %s", result.getInt(AccountManager.KEY_ERROR_CODE), result.getString(AccountManager.KEY_ERROR_MESSAGE))); } // Disable sync to avoid test flakiness as accounts fetch additional data. // It takes a while for all sync adapters to be populated, so register for broadcasts when // sync is starting and disable them there. // NOTE: this listener is NOT unregistered because several sync requests for the new account // will come in over time. Account account = new Account(username, GOOGLE_ACCOUNT_TYPE); Object handle = ContentResolver.addStatusChangeListener( ContentResolver.SYNC_OBSERVER_TYPE_ACTIVE | ContentResolver.SYNC_OBSERVER_TYPE_PENDING, which -> { for (SyncAdapterType adapter : ContentResolver.getSyncAdapterTypes()) { // Ignore non-Google account types. if (!adapter.accountType.equals(GOOGLE_ACCOUNT_TYPE)) { continue; } // If a content provider is not whitelisted, then disable it. // Because startSync and stopSync synchronously update the whitelist // and sync settings, writelock both the whitelist check and the // call to sync together. mLock.writeLock().lock(); try { if (!isAdapterWhitelisted(username, adapter.authority)) { updateSync(account, adapter.authority, false /* sync */); } } finally { mLock.writeLock().unlock(); } } }); mSyncStatusObserverHandles.add(handle); }
@Override public void onError(Throwable e) { int reason = R.string.fast_exception_other_error; int code = FastError.EXCEPTION_OTHER_ERROR; Activity current = FastStackUtil.getInstance().getCurrent(); if (!NetworkUtil.isConnected(current)) { reason = R.string.fast_exception_network_not_connected; code = FastError.EXCEPTION_NETWORK_NOT_CONNECTED; } else { if (e instanceof NetworkErrorException) {//网络异常--继承于AccountsException reason = R.string.fast_exception_network_error; code = FastError.EXCEPTION_NETWORK_ERROR; } else if (e instanceof AccountsException) {//账户异常 reason = R.string.fast_exception_accounts; code = FastError.EXCEPTION_ACCOUNTS; } else if (e instanceof ConnectException) {//连接异常--继承于SocketException reason = R.string.fast_exception_connect; code = FastError.EXCEPTION_CONNECT; } else if (e instanceof SocketException) {//socket异常 reason = R.string.fast_exception_socket; code = FastError.EXCEPTION_SOCKET; } else if (e instanceof HttpException) {// http异常 reason = R.string.fast_exception_http; code = FastError.EXCEPTION_HTTP; } else if (e instanceof UnknownHostException) {//DNS错误 reason = R.string.fast_exception_unknown_host; code = FastError.EXCEPTION_UNKNOWN_HOST; } else if (e instanceof JsonSyntaxException || e instanceof JsonIOException || e instanceof JsonParseException) {//数据格式化错误 reason = R.string.fast_exception_json_syntax; code = FastError.EXCEPTION_JSON_SYNTAX; } else if (e instanceof SocketTimeoutException || e instanceof TimeoutException) { reason = R.string.fast_exception_time_out; code = FastError.EXCEPTION_TIME_OUT; } else if (e instanceof ClassCastException) { reason = R.string.fast_exception_class_cast; code = FastError.EXCEPTION_CLASS_CAST; } } if (mContext != null && FastConfig.getInstance(mContext). getHttpErrorControl(). createHttpErrorControl(reason, code, e,mContext, mArgs)) { return; } _onError(reason, code, e); }
/** * Core download method: requests a file to download and stores it. * * @param downloadKey Key to access the download to perform, contained in mPendingDownloads */ private void downloadFile(String downloadKey) { /*Log_OC.v( "NOW " + TAG + ", thread " + Thread.currentThread().getName(), "Getting download of " + downloadKey);*/ mCurrentDownload = mPendingDownloads.get(downloadKey); if (mCurrentDownload != null) { // Detect if the account exists if (AccountUtils.exists(mCurrentDownload.getAccount(), getApplicationContext())) { Log_OC.d(TAG, "Account " + mCurrentDownload.getAccount().name + " exists"); notifyDownloadStart(mCurrentDownload); RemoteOperationResult downloadResult = null; try { /// prepare client object to send the request to the ownCloud server if (mCurrentAccount == null || !mCurrentAccount.equals(mCurrentDownload.getAccount())) { mCurrentAccount = mCurrentDownload.getAccount(); mStorageManager = new FileDataStorageManager( mCurrentAccount, getContentResolver() ); } // else, reuse storage manager from previous operation // always get client from client manager, to get fresh credentials in case // of update OwnCloudAccount ocAccount = new OwnCloudAccount(mCurrentAccount, this); mDownloadClient = OwnCloudClientManagerFactory.getDefaultSingleton(). getClientFor(ocAccount, this); /// perform the download /*Log_OC.v( "NOW " + TAG + ", thread " + Thread.currentThread().getName(), "Executing download of " + mCurrentDownload.getRemotePath());*/ downloadResult = mCurrentDownload.execute(mDownloadClient); if (downloadResult.isSuccess()) { saveDownloadedFile(); } } catch (AccountsException | IOException e) { Log_OC.e(TAG, "Error while trying to get authorization for " + mCurrentAccount.name, e); downloadResult = new RemoteOperationResult(e); } finally { /*Log_OC.v( "NOW " + TAG + ", thread " + Thread.currentThread().getName(), "Removing payload " + mCurrentDownload.getRemotePath());*/ Pair<DownloadFileOperation, String> removeResult = mPendingDownloads.removePayload(mCurrentAccount, mCurrentDownload.getRemotePath()); /// notify result notifyDownloadResult(mCurrentDownload, downloadResult); sendBroadcastDownloadFinished(mCurrentDownload, downloadResult, removeResult.second); } } else { // Cancel the transfer Log_OC.d(TAG, "Account " + mCurrentDownload.getAccount().toString() + " doesn't exist"); cancelDownloadsForAccount(mCurrentDownload.getAccount()); } } }
public static void loginAppEngine(Activity parent, CookieManagerAvailableListener listener, Account account) throws IOException, AccountsException { loginAppEngine(parent, listener, account, -1); }
/** * @param listener * will send back the CookieManager to be used in subsequent * calls * @param account * is the account with which you want to login * * @param requestCode * is the code that will be used to call back to the calling * activity if the user needed to select an account to use and * must be != -1. * @return The CookieManager for subsequence call * @throws IOException */ public static void loginAppEngine(final Activity parent, final CookieManagerAvailableListener listener, final Account account, int requestCode) throws IOException, AccountsException { if (account == null) { if (useAccountSelector && requestCode != -1) { chooseAccount(parent, requestCode); return; } else if (useAccountSelector && requestCode == -1) { throw new AccountsException( "Provided Request code cannot be equal to -1"); } else { throw new AccountsException( "Account needs to be provided to login to App Engine."); } } if (localDevMode) { URL url = new URL(loginUrl + "/_ah/login"); String email = URLEncoder.encode(account.name, "UTF-8"); String serviceUrl = URLEncoder.encode("nowhere", "UTF-8"); String requestData = "email=" + email + "&continue=" + serviceUrl; Runnable runnable = new GetCookieRunnable(parent, url, requestData, listener); new Thread(runnable).start(); } // Non Dev Mode else { if (!account.type.equals(GOOGLE_ACCOUNT_TYPE)) { Toast.makeText(parent, R.string.spa_non_dev_toast, Toast.LENGTH_SHORT).show(); if (useAccountSelector && requestCode != -1) { chooseAccount(parent, requestCode); return; } else if (useAccountSelector && requestCode == -1) { throw new AccountsException( "Provided Request code cannot be equal to -1"); } else { throw new AccountsException( "Only Google Accounts can be used for deployed App Engine Services."); } } final AccountManager accountManager = AccountManager.get(parent .getApplicationContext()); accountManager.getAuthToken(account, GAE_SERVICE_NAME, null, false, new GAEAMCallback(parent, account, loginUrl, listener), null); } }
public RemoteOperationResult(Exception e) { mException = e; if (e instanceof OperationCancelledException) { mCode = ResultCode.CANCELLED; } else if (e instanceof SocketException) { mCode = ResultCode.WRONG_CONNECTION; } else if (e instanceof SocketTimeoutException) { mCode = ResultCode.TIMEOUT; } else if (e instanceof ConnectTimeoutException) { mCode = ResultCode.TIMEOUT; } else if (e instanceof MalformedURLException) { mCode = ResultCode.INCORRECT_ADDRESS; } else if (e instanceof UnknownHostException) { mCode = ResultCode.HOST_NOT_AVAILABLE; } else if (e instanceof AccountNotFoundException) { mCode = ResultCode.ACCOUNT_NOT_FOUND; } else if (e instanceof AccountsException) { mCode = ResultCode.ACCOUNT_EXCEPTION; } else if (e instanceof SSLException || e instanceof RuntimeException) { CertificateCombinedException se = getCertificateCombinedException(e); if (se != null) { mException = se; if (se.isRecoverable()) { mCode = ResultCode.SSL_RECOVERABLE_PEER_UNVERIFIED; } } else if (e instanceof RuntimeException) { mCode = ResultCode.HOST_NOT_AVAILABLE; } else { mCode = ResultCode.SSL_ERROR; } } else { mCode = ResultCode.UNKNOWN_ERROR; } }
public AccountsExceptionCommand() { setName(AccountsException.class.getSimpleName()); }
@Override public void execute() throws Exception { throw new AccountsException(name()); }
/** * This call blocks, so shouldn't be called on the UI thread. * This call is what makes the login screen pop up. If the user has * not logged in there will no accounts in the {@link android.accounts.AccountManager} * and therefore the Activity that is referenced in the * {@link fr.pagesjaunes.mdm.authenticator.BootstrapAccountAuthenticator} will get started. * If you want to remove the authentication then you can comment out the code below and return a string such as * "foo" and the authentication process will not be kicked off. Alternatively, you can remove this class * completely and clean up any references to the authenticator. * * * @return API key to be used for authorization with a * {@link fr.pagesjaunes.mdm.core.BootstrapService} instance * @throws AccountsException * @throws IOException */ public String getAuthKey(final Activity activity) throws AccountsException, IOException { final AccountManagerFuture<Bundle> accountManagerFuture = accountManager.getAuthTokenByFeatures(BOOTSTRAP_ACCOUNT_TYPE, AUTHTOKEN_TYPE, new String[0], activity, null, null, null, null); return accountManagerFuture.getResult().getString(KEY_AUTHTOKEN); }
/** * Get service for configured key provider * <p/> * This method gets an auth key and so it blocks and shouldn't be called on the main thread. * * @return bootstrap service * @throws IOException * @throws AccountsException */ public BootstrapService getService(final Activity activity) throws IOException, AccountsException { // The call to keyProvider.getAuthKey(...) is what initiates the login screen. Call that now. keyProvider.getAuthKey(activity); // TODO: See how that affects the bootstrap service. return new BootstrapService(restAdapter); }