M7350v1_en_gpl

This commit is contained in:
T
2024-09-09 08:52:07 +00:00
commit f9cc65cfda
65988 changed files with 26357421 additions and 0 deletions

View File

@ -0,0 +1,502 @@
/*
* Copyright (C) 2009 The Android Open Source Project
*
* 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 android.accounts;
import android.os.Bundle;
import android.os.RemoteException;
import android.os.Binder;
import android.os.IBinder;
import android.content.pm.PackageManager;
import android.content.Context;
import android.content.Intent;
import android.Manifest;
import android.text.TextUtils;
import android.util.Log;
import java.util.Arrays;
/**
* Abstract base class for creating AccountAuthenticators.
* In order to be an authenticator one must extend this class, provider implementations for the
* abstract methods and write a service that returns the result of {@link #getIBinder()}
* in the service's {@link android.app.Service#onBind(android.content.Intent)} when invoked
* with an intent with action {@link AccountManager#ACTION_AUTHENTICATOR_INTENT}. This service
* must specify the following intent filter and metadata tags in its AndroidManifest.xml file
* <pre>
* &lt;intent-filter&gt;
* &lt;action android:name="android.accounts.AccountAuthenticator" /&gt;
* &lt;/intent-filter&gt;
* &lt;meta-data android:name="android.accounts.AccountAuthenticator"
* android:resource="@xml/authenticator" /&gt;
* </pre>
* The <code>android:resource</code> attribute must point to a resource that looks like:
* <pre>
* &lt;account-authenticator xmlns:android="http://schemas.android.com/apk/res/android"
* android:accountType="typeOfAuthenticator"
* android:icon="@drawable/icon"
* android:smallIcon="@drawable/miniIcon"
* android:label="@string/label"
* android:accountPreferences="@xml/account_preferences"
* /&gt;
* </pre>
* Replace the icons and labels with your own resources. The <code>android:accountType</code>
* attribute must be a string that uniquely identifies your authenticator and will be the same
* string that user will use when making calls on the {@link AccountManager} and it also
* corresponds to {@link Account#type} for your accounts. One user of the android:icon is the
* "Account & Sync" settings page and one user of the android:smallIcon is the Contact Application's
* tab panels.
* <p>
* The preferences attribute points to an PreferenceScreen xml hierarchy that contains
* a list of PreferenceScreens that can be invoked to manage the authenticator. An example is:
* <pre>
* &lt;PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"&gt;
* &lt;PreferenceCategory android:title="@string/title_fmt" /&gt;
* &lt;PreferenceScreen
* android:key="key1"
* android:title="@string/key1_action"
* android:summary="@string/key1_summary"&gt;
* &lt;intent
* android:action="key1.ACTION"
* android:targetPackage="key1.package"
* android:targetClass="key1.class" /&gt;
* &lt;/PreferenceScreen&gt;
* &lt;/PreferenceScreen&gt;
* </pre>
*
* <p>
* The standard pattern for implementing any of the abstract methods is the following:
* <ul>
* <li> If the supplied arguments are enough for the authenticator to fully satisfy the request
* then it will do so and return a {@link Bundle} that contains the results.
* <li> If the authenticator needs information from the user to satisfy the request then it
* will create an {@link Intent} to an activity that will prompt the user for the information
* and then carry out the request. This intent must be returned in a Bundle as key
* {@link AccountManager#KEY_INTENT}.
* <p>
* The activity needs to return the final result when it is complete so the Intent should contain
* the {@link AccountAuthenticatorResponse} as {@link AccountManager#KEY_ACCOUNT_MANAGER_RESPONSE}.
* The activity must then call {@link AccountAuthenticatorResponse#onResult} or
* {@link AccountAuthenticatorResponse#onError} when it is complete.
* <li> If the authenticator cannot synchronously process the request and return a result then it
* may choose to return null and then use the AccountManagerResponse to send the result
* when it has completed the request.
* </ul>
* <p>
* The following descriptions of each of the abstract authenticator methods will not describe the
* possible asynchronous nature of the request handling and will instead just describe the input
* parameters and the expected result.
* <p>
* When writing an activity to satisfy these requests one must pass in the AccountManagerResponse
* and return the result via that response when the activity finishes (or whenever else the
* activity author deems it is the correct time to respond).
* The {@link AccountAuthenticatorActivity} handles this, so one may wish to extend that when
* writing activities to handle these requests.
*/
public abstract class AbstractAccountAuthenticator {
private static final String TAG = "AccountAuthenticator";
private final Context mContext;
public AbstractAccountAuthenticator(Context context) {
mContext = context;
}
private class Transport extends IAccountAuthenticator.Stub {
public void addAccount(IAccountAuthenticatorResponse response, String accountType,
String authTokenType, String[] features, Bundle options)
throws RemoteException {
if (Log.isLoggable(TAG, Log.VERBOSE)) {
Log.v(TAG, "addAccount: accountType " + accountType
+ ", authTokenType " + authTokenType
+ ", features " + (features == null ? "[]" : Arrays.toString(features)));
}
checkBinderPermission();
try {
final Bundle result = AbstractAccountAuthenticator.this.addAccount(
new AccountAuthenticatorResponse(response),
accountType, authTokenType, features, options);
if (Log.isLoggable(TAG, Log.VERBOSE)) {
result.keySet(); // force it to be unparcelled
Log.v(TAG, "addAccount: result " + AccountManager.sanitizeResult(result));
}
if (result != null) {
response.onResult(result);
}
} catch (NetworkErrorException e) {
if (Log.isLoggable(TAG, Log.VERBOSE)) {
Log.v(TAG, "addAccount", e);
}
response.onError(AccountManager.ERROR_CODE_NETWORK_ERROR, e.getMessage());
} catch (UnsupportedOperationException e) {
if (Log.isLoggable(TAG, Log.VERBOSE)) {
Log.v(TAG, "addAccount", e);
}
response.onError(AccountManager.ERROR_CODE_UNSUPPORTED_OPERATION,
"addAccount not supported");
}
}
public void confirmCredentials(IAccountAuthenticatorResponse response,
Account account, Bundle options) throws RemoteException {
if (Log.isLoggable(TAG, Log.VERBOSE)) {
Log.v(TAG, "confirmCredentials: " + account);
}
checkBinderPermission();
try {
final Bundle result = AbstractAccountAuthenticator.this.confirmCredentials(
new AccountAuthenticatorResponse(response), account, options);
if (Log.isLoggable(TAG, Log.VERBOSE)) {
result.keySet(); // force it to be unparcelled
Log.v(TAG, "confirmCredentials: result "
+ AccountManager.sanitizeResult(result));
}
if (result != null) {
response.onResult(result);
}
} catch (NetworkErrorException e) {
if (Log.isLoggable(TAG, Log.VERBOSE)) {
Log.v(TAG, "confirmCredentials", e);
}
response.onError(AccountManager.ERROR_CODE_NETWORK_ERROR, e.getMessage());
} catch (UnsupportedOperationException e) {
if (Log.isLoggable(TAG, Log.VERBOSE)) {
Log.v(TAG, "confirmCredentials", e);
}
response.onError(AccountManager.ERROR_CODE_UNSUPPORTED_OPERATION,
"confirmCredentials not supported");
}
}
public void getAuthTokenLabel(IAccountAuthenticatorResponse response,
String authTokenType)
throws RemoteException {
if (Log.isLoggable(TAG, Log.VERBOSE)) {
Log.v(TAG, "getAuthTokenLabel: authTokenType " + authTokenType);
}
checkBinderPermission();
try {
Bundle result = new Bundle();
result.putString(AccountManager.KEY_AUTH_TOKEN_LABEL,
AbstractAccountAuthenticator.this.getAuthTokenLabel(authTokenType));
if (Log.isLoggable(TAG, Log.VERBOSE)) {
result.keySet(); // force it to be unparcelled
Log.v(TAG, "getAuthTokenLabel: result "
+ AccountManager.sanitizeResult(result));
}
if (result != null) {
response.onResult(result);
}
} catch (IllegalArgumentException e) {
if (Log.isLoggable(TAG, Log.VERBOSE)) {
Log.v(TAG, "getAuthTokenLabel", e);
}
response.onError(AccountManager.ERROR_CODE_BAD_ARGUMENTS,
"unknown authTokenType");
} catch (UnsupportedOperationException e) {
if (Log.isLoggable(TAG, Log.VERBOSE)) {
Log.v(TAG, "getAuthTokenLabel", e);
}
response.onError(AccountManager.ERROR_CODE_UNSUPPORTED_OPERATION,
"getAuthTokenTypeLabel not supported");
}
}
public void getAuthToken(IAccountAuthenticatorResponse response,
Account account, String authTokenType, Bundle loginOptions)
throws RemoteException {
if (Log.isLoggable(TAG, Log.VERBOSE)) {
Log.v(TAG, "getAuthToken: " + account
+ ", authTokenType " + authTokenType);
}
checkBinderPermission();
try {
final Bundle result = AbstractAccountAuthenticator.this.getAuthToken(
new AccountAuthenticatorResponse(response), account,
authTokenType, loginOptions);
if (Log.isLoggable(TAG, Log.VERBOSE)) {
result.keySet(); // force it to be unparcelled
Log.v(TAG, "getAuthToken: result " + AccountManager.sanitizeResult(result));
}
if (result != null) {
response.onResult(result);
}
} catch (UnsupportedOperationException e) {
if (Log.isLoggable(TAG, Log.VERBOSE)) {
Log.v(TAG, "getAuthToken", e);
}
response.onError(AccountManager.ERROR_CODE_UNSUPPORTED_OPERATION,
"getAuthToken not supported");
} catch (NetworkErrorException e) {
if (Log.isLoggable(TAG, Log.VERBOSE)) {
Log.v(TAG, "getAuthToken", e);
}
response.onError(AccountManager.ERROR_CODE_NETWORK_ERROR, e.getMessage());
}
}
public void updateCredentials(IAccountAuthenticatorResponse response, Account account,
String authTokenType, Bundle loginOptions) throws RemoteException {
if (Log.isLoggable(TAG, Log.VERBOSE)) {
Log.v(TAG, "updateCredentials: " + account
+ ", authTokenType " + authTokenType);
}
checkBinderPermission();
try {
final Bundle result = AbstractAccountAuthenticator.this.updateCredentials(
new AccountAuthenticatorResponse(response), account,
authTokenType, loginOptions);
if (Log.isLoggable(TAG, Log.VERBOSE)) {
result.keySet(); // force it to be unparcelled
Log.v(TAG, "updateCredentials: result "
+ AccountManager.sanitizeResult(result));
}
if (result != null) {
response.onResult(result);
}
} catch (NetworkErrorException e) {
if (Log.isLoggable(TAG, Log.VERBOSE)) {
Log.v(TAG, "updateCredentials", e);
}
response.onError(AccountManager.ERROR_CODE_NETWORK_ERROR, e.getMessage());
} catch (UnsupportedOperationException e) {
if (Log.isLoggable(TAG, Log.VERBOSE)) {
Log.v(TAG, "updateCredentials", e);
}
response.onError(AccountManager.ERROR_CODE_UNSUPPORTED_OPERATION,
"updateCredentials not supported");
}
}
public void editProperties(IAccountAuthenticatorResponse response,
String accountType) throws RemoteException {
checkBinderPermission();
try {
final Bundle result = AbstractAccountAuthenticator.this.editProperties(
new AccountAuthenticatorResponse(response), accountType);
if (result != null) {
response.onResult(result);
}
} catch (UnsupportedOperationException e) {
response.onError(AccountManager.ERROR_CODE_UNSUPPORTED_OPERATION,
"editProperties not supported");
}
}
public void hasFeatures(IAccountAuthenticatorResponse response,
Account account, String[] features) throws RemoteException {
checkBinderPermission();
try {
final Bundle result = AbstractAccountAuthenticator.this.hasFeatures(
new AccountAuthenticatorResponse(response), account, features);
if (result != null) {
response.onResult(result);
}
} catch (UnsupportedOperationException e) {
response.onError(AccountManager.ERROR_CODE_UNSUPPORTED_OPERATION,
"hasFeatures not supported");
} catch (NetworkErrorException e) {
response.onError(AccountManager.ERROR_CODE_NETWORK_ERROR, e.getMessage());
}
}
public void getAccountRemovalAllowed(IAccountAuthenticatorResponse response,
Account account) throws RemoteException {
checkBinderPermission();
try {
final Bundle result = AbstractAccountAuthenticator.this.getAccountRemovalAllowed(
new AccountAuthenticatorResponse(response), account);
if (result != null) {
response.onResult(result);
}
} catch (UnsupportedOperationException e) {
response.onError(AccountManager.ERROR_CODE_UNSUPPORTED_OPERATION,
"getAccountRemovalAllowed not supported");
} catch (NetworkErrorException e) {
response.onError(AccountManager.ERROR_CODE_NETWORK_ERROR, e.getMessage());
}
}
}
private void checkBinderPermission() {
final int uid = Binder.getCallingUid();
final String perm = Manifest.permission.ACCOUNT_MANAGER;
if (mContext.checkCallingOrSelfPermission(perm) != PackageManager.PERMISSION_GRANTED) {
throw new SecurityException("caller uid " + uid + " lacks " + perm);
}
}
private Transport mTransport = new Transport();
/**
* @return the IBinder for the AccountAuthenticator
*/
public final IBinder getIBinder() {
return mTransport.asBinder();
}
/**
* Returns a Bundle that contains the Intent of the activity that can be used to edit the
* properties. In order to indicate success the activity should call response.setResult()
* with a non-null Bundle.
* @param response used to set the result for the request. If the Constants.INTENT_KEY
* is set in the bundle then this response field is to be used for sending future
* results if and when the Intent is started.
* @param accountType the AccountType whose properties are to be edited.
* @return a Bundle containing the result or the Intent to start to continue the request.
* If this is null then the request is considered to still be active and the result should
* sent later using response.
*/
public abstract Bundle editProperties(AccountAuthenticatorResponse response,
String accountType);
/**
* Adds an account of the specified accountType.
* @param response to send the result back to the AccountManager, will never be null
* @param accountType the type of account to add, will never be null
* @param authTokenType the type of auth token to retrieve after adding the account, may be null
* @param requiredFeatures a String array of authenticator-specific features that the added
* account must support, may be null
* @param options a Bundle of authenticator-specific options, may be null
* @return a Bundle result or null if the result is to be returned via the response. The result
* will contain either:
* <ul>
* <li> {@link AccountManager#KEY_INTENT}, or
* <li> {@link AccountManager#KEY_ACCOUNT_NAME} and {@link AccountManager#KEY_ACCOUNT_TYPE} of
* the account that was added, or
* <li> {@link AccountManager#KEY_ERROR_CODE} and {@link AccountManager#KEY_ERROR_MESSAGE} to
* indicate an error
* </ul>
* @throws NetworkErrorException if the authenticator could not honor the request due to a
* network error
*/
public abstract Bundle addAccount(AccountAuthenticatorResponse response, String accountType,
String authTokenType, String[] requiredFeatures, Bundle options)
throws NetworkErrorException;
/**
* Checks that the user knows the credentials of an account.
* @param response to send the result back to the AccountManager, will never be null
* @param account the account whose credentials are to be checked, will never be null
* @param options a Bundle of authenticator-specific options, may be null
* @return a Bundle result or null if the result is to be returned via the response. The result
* will contain either:
* <ul>
* <li> {@link AccountManager#KEY_INTENT}, or
* <li> {@link AccountManager#KEY_BOOLEAN_RESULT}, true if the check succeeded, false otherwise
* <li> {@link AccountManager#KEY_ERROR_CODE} and {@link AccountManager#KEY_ERROR_MESSAGE} to
* indicate an error
* </ul>
* @throws NetworkErrorException if the authenticator could not honor the request due to a
* network error
*/
public abstract Bundle confirmCredentials(AccountAuthenticatorResponse response,
Account account, Bundle options)
throws NetworkErrorException;
/**
* Gets the authtoken for an account.
* @param response to send the result back to the AccountManager, will never be null
* @param account the account whose credentials are to be retrieved, will never be null
* @param authTokenType the type of auth token to retrieve, will never be null
* @param options a Bundle of authenticator-specific options, may be null
* @return a Bundle result or null if the result is to be returned via the response. The result
* will contain either:
* <ul>
* <li> {@link AccountManager#KEY_INTENT}, or
* <li> {@link AccountManager#KEY_ACCOUNT_NAME}, {@link AccountManager#KEY_ACCOUNT_TYPE},
* and {@link AccountManager#KEY_AUTHTOKEN}, or
* <li> {@link AccountManager#KEY_ERROR_CODE} and {@link AccountManager#KEY_ERROR_MESSAGE} to
* indicate an error
* </ul>
* @throws NetworkErrorException if the authenticator could not honor the request due to a
* network error
*/
public abstract Bundle getAuthToken(AccountAuthenticatorResponse response,
Account account, String authTokenType, Bundle options)
throws NetworkErrorException;
/**
* Ask the authenticator for a localized label for the given authTokenType.
* @param authTokenType the authTokenType whose label is to be returned, will never be null
* @return the localized label of the auth token type, may be null if the type isn't known
*/
public abstract String getAuthTokenLabel(String authTokenType);
/**
* Update the locally stored credentials for an account.
* @param response to send the result back to the AccountManager, will never be null
* @param account the account whose credentials are to be updated, will never be null
* @param authTokenType the type of auth token to retrieve after updating the credentials,
* may be null
* @param options a Bundle of authenticator-specific options, may be null
* @return a Bundle result or null if the result is to be returned via the response. The result
* will contain either:
* <ul>
* <li> {@link AccountManager#KEY_INTENT}, or
* <li> {@link AccountManager#KEY_ACCOUNT_NAME} and {@link AccountManager#KEY_ACCOUNT_TYPE} of
* the account that was added, or
* <li> {@link AccountManager#KEY_ERROR_CODE} and {@link AccountManager#KEY_ERROR_MESSAGE} to
* indicate an error
* </ul>
* @throws NetworkErrorException if the authenticator could not honor the request due to a
* network error
*/
public abstract Bundle updateCredentials(AccountAuthenticatorResponse response,
Account account, String authTokenType, Bundle options) throws NetworkErrorException;
/**
* Checks if the account supports all the specified authenticator specific features.
* @param response to send the result back to the AccountManager, will never be null
* @param account the account to check, will never be null
* @param features an array of features to check, will never be null
* @return a Bundle result or null if the result is to be returned via the response. The result
* will contain either:
* <ul>
* <li> {@link AccountManager#KEY_INTENT}, or
* <li> {@link AccountManager#KEY_BOOLEAN_RESULT}, true if the account has all the features,
* false otherwise
* <li> {@link AccountManager#KEY_ERROR_CODE} and {@link AccountManager#KEY_ERROR_MESSAGE} to
* indicate an error
* </ul>
* @throws NetworkErrorException if the authenticator could not honor the request due to a
* network error
*/
public abstract Bundle hasFeatures(AccountAuthenticatorResponse response,
Account account, String[] features) throws NetworkErrorException;
/**
* Checks if the removal of this account is allowed.
* @param response to send the result back to the AccountManager, will never be null
* @param account the account to check, will never be null
* @return a Bundle result or null if the result is to be returned via the response. The result
* will contain either:
* <ul>
* <li> {@link AccountManager#KEY_INTENT}, or
* <li> {@link AccountManager#KEY_BOOLEAN_RESULT}, true if the removal of the account is
* allowed, false otherwise
* <li> {@link AccountManager#KEY_ERROR_CODE} and {@link AccountManager#KEY_ERROR_MESSAGE} to
* indicate an error
* </ul>
* @throws NetworkErrorException if the authenticator could not honor the request due to a
* network error
*/
public Bundle getAccountRemovalAllowed(AccountAuthenticatorResponse response,
Account account) throws NetworkErrorException {
final Bundle result = new Bundle();
result.putBoolean(AccountManager.KEY_BOOLEAN_RESULT, true);
return result;
}
}

View File

@ -0,0 +1,19 @@
/*
* Copyright (C) 2009 The Android Open Source Project
*
* 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 android.accounts;
parcelable Account;

View File

@ -0,0 +1,84 @@
/*
* Copyright (C) 2009 The Android Open Source Project
*
* 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 android.accounts;
import android.os.Parcelable;
import android.os.Parcel;
import android.text.TextUtils;
/**
* Value type that represents an Account in the {@link AccountManager}. This object is
* {@link Parcelable} and also overrides {@link #equals} and {@link #hashCode}, making it
* suitable for use as the key of a {@link java.util.Map}
*/
public class Account implements Parcelable {
public final String name;
public final String type;
public boolean equals(Object o) {
if (o == this) return true;
if (!(o instanceof Account)) return false;
final Account other = (Account)o;
return name.equals(other.name) && type.equals(other.type);
}
public int hashCode() {
int result = 17;
result = 31 * result + name.hashCode();
result = 31 * result + type.hashCode();
return result;
}
public Account(String name, String type) {
if (TextUtils.isEmpty(name)) {
throw new IllegalArgumentException("the name must not be empty: " + name);
}
if (TextUtils.isEmpty(type)) {
throw new IllegalArgumentException("the type must not be empty: " + type);
}
this.name = name;
this.type = type;
}
public Account(Parcel in) {
this.name = in.readString();
this.type = in.readString();
}
public int describeContents() {
return 0;
}
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(name);
dest.writeString(type);
}
public static final Creator<Account> CREATOR = new Creator<Account>() {
public Account createFromParcel(Parcel source) {
return new Account(source);
}
public Account[] newArray(int size) {
return new Account[size];
}
};
public String toString() {
return "Account {name=" + name + ", type=" + type + "}";
}
}

View File

@ -0,0 +1,83 @@
/*
* Copyright (C) 2009 The Android Open Source Project
*
* 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 android.accounts;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
/**
* Base class for implementing an Activity that is used to help implement an
* AbstractAccountAuthenticator. If the AbstractAccountAuthenticator needs to use an activity
* to handle the request then it can have the activity extend AccountAuthenticatorActivity.
* The AbstractAccountAuthenticator passes in the response to the intent using the following:
* <pre>
* intent.putExtra(Constants.ACCOUNT_AUTHENTICATOR_RESPONSE_KEY, response);
* </pre>
* The activity then sets the result that is to be handed to the response via
* {@link #setAccountAuthenticatorResult(android.os.Bundle)}.
* This result will be sent as the result of the request when the activity finishes. If this
* is never set or if it is set to null then error {@link AccountManager#ERROR_CODE_CANCELED}
* will be called on the response.
*/
public class AccountAuthenticatorActivity extends Activity {
private AccountAuthenticatorResponse mAccountAuthenticatorResponse = null;
private Bundle mResultBundle = null;
/**
* Set the result that is to be sent as the result of the request that caused this
* Activity to be launched. If result is null or this method is never called then
* the request will be canceled.
* @param result this is returned as the result of the AbstractAccountAuthenticator request
*/
public final void setAccountAuthenticatorResult(Bundle result) {
mResultBundle = result;
}
/**
* Retreives the AccountAuthenticatorResponse from either the intent of the icicle, if the
* icicle is non-zero.
* @param icicle the save instance data of this Activity, may be null
*/
protected void onCreate(Bundle icicle) {
super.onCreate(icicle);
mAccountAuthenticatorResponse =
getIntent().getParcelableExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE);
if (mAccountAuthenticatorResponse != null) {
mAccountAuthenticatorResponse.onRequestContinued();
}
}
/**
* Sends the result or a Constants.ERROR_CODE_CANCELED error if a result isn't present.
*/
public void finish() {
if (mAccountAuthenticatorResponse != null) {
// send the result bundle back if set, otherwise send an error.
if (mResultBundle != null) {
mAccountAuthenticatorResponse.onResult(mResultBundle);
} else {
mAccountAuthenticatorResponse.onError(AccountManager.ERROR_CODE_CANCELED,
"canceled");
}
mAccountAuthenticatorResponse = null;
}
super.finish();
}
}

View File

@ -0,0 +1,121 @@
/*
* Copyright (C) 2009 The Android Open Source Project
*
* 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 android.accounts;
import android.content.pm.PackageManager;
import android.content.pm.RegisteredServicesCache;
import android.content.pm.ResolveInfo;
import android.content.pm.XmlSerializerAndParser;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.util.AttributeSet;
import android.util.Log;
import android.text.TextUtils;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlSerializer;
import org.xmlpull.v1.XmlPullParserException;
import java.io.IOException;
import java.util.List;
/**
* A cache of services that export the {@link IAccountAuthenticator} interface. This cache
* is built by interrogating the {@link PackageManager} and is updated as packages are added,
* removed and changed. The authenticators are referred to by their account type and
* are made available via the {@link RegisteredServicesCache#getServiceInfo} method.
* @hide
*/
/* package private */ class AccountAuthenticatorCache
extends RegisteredServicesCache<AuthenticatorDescription> {
private static final String TAG = "Account";
private static final MySerializer sSerializer = new MySerializer();
public AccountAuthenticatorCache(Context context) {
super(context, AccountManager.ACTION_AUTHENTICATOR_INTENT,
AccountManager.AUTHENTICATOR_META_DATA_NAME,
AccountManager.AUTHENTICATOR_ATTRIBUTES_NAME, sSerializer);
}
public AuthenticatorDescription parseServiceAttributes(Resources res,
String packageName, AttributeSet attrs) {
TypedArray sa = res.obtainAttributes(attrs,
com.android.internal.R.styleable.AccountAuthenticator);
try {
final String accountType =
sa.getString(com.android.internal.R.styleable.AccountAuthenticator_accountType);
final int labelId = sa.getResourceId(
com.android.internal.R.styleable.AccountAuthenticator_label, 0);
final int iconId = sa.getResourceId(
com.android.internal.R.styleable.AccountAuthenticator_icon, 0);
final int smallIconId = sa.getResourceId(
com.android.internal.R.styleable.AccountAuthenticator_smallIcon, 0);
final int prefId = sa.getResourceId(
com.android.internal.R.styleable.AccountAuthenticator_accountPreferences, 0);
boolean customTokens = false;
try {
// In HC this will be an attribute in authenticator.xml, this is a workaround
// using meta-data to avoid changes to the API.
// If meta-data is absent the old behavior is preserved.
// Authenticator will know if AccountManager supports customTokens or not.
PackageManager pm = mContext.getPackageManager();
List<ResolveInfo> resolveInfos = pm.queryIntentServices(
new Intent(AccountManager.ACTION_AUTHENTICATOR_INTENT),
PackageManager.GET_META_DATA);
for (ResolveInfo resolveInfo: resolveInfos) {
android.content.pm.ServiceInfo si = resolveInfo.serviceInfo;
if (!packageName.equals(si.packageName)) {
continue;
}
Object ctString = si.metaData.get(AccountManager.ACTION_AUTHENTICATOR_INTENT
+ ".customTokens");
if (ctString != null) {
customTokens = true;
}
}
} catch (Throwable t) {
// Protected against invalid data in meta or unexpected
// conditions - the authenticator will not have the new
// features.
Log.e(TAG, "Error getting customTokens metadata " + t);
}
if (TextUtils.isEmpty(accountType)) {
return null;
}
return new AuthenticatorDescription(accountType, packageName, labelId, iconId,
smallIconId, prefId, customTokens);
} finally {
sa.recycle();
}
}
private static class MySerializer implements XmlSerializerAndParser<AuthenticatorDescription> {
public void writeAsXml(AuthenticatorDescription item, XmlSerializer out)
throws IOException {
out.attribute(null, "type", item.type);
}
public AuthenticatorDescription createFromXml(XmlPullParser parser)
throws IOException, XmlPullParserException {
return AuthenticatorDescription.newKey(parser.getAttributeValue(null, "type"));
}
}
}

View File

@ -0,0 +1,98 @@
/*
* Copyright (C) 2009 The Android Open Source Project
*
* 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 android.accounts;
import android.os.Bundle;
import android.os.Parcelable;
import android.os.Parcel;
import android.os.RemoteException;
import android.util.Log;
/**
* Object used to communicate responses back to the AccountManager
*/
public class AccountAuthenticatorResponse implements Parcelable {
private static final String TAG = "AccountAuthenticator";
private IAccountAuthenticatorResponse mAccountAuthenticatorResponse;
/**
* @hide
*/
/* package private */ AccountAuthenticatorResponse(IAccountAuthenticatorResponse response) {
mAccountAuthenticatorResponse = response;
}
public AccountAuthenticatorResponse(Parcel parcel) {
mAccountAuthenticatorResponse =
IAccountAuthenticatorResponse.Stub.asInterface(parcel.readStrongBinder());
}
public void onResult(Bundle result) {
if (Log.isLoggable(TAG, Log.VERBOSE)) {
result.keySet(); // force it to be unparcelled
Log.v(TAG, "AccountAuthenticatorResponse.onResult: "
+ AccountManager.sanitizeResult(result));
}
try {
mAccountAuthenticatorResponse.onResult(result);
} catch (RemoteException e) {
// this should never happen
}
}
public void onRequestContinued() {
if (Log.isLoggable(TAG, Log.VERBOSE)) {
Log.v(TAG, "AccountAuthenticatorResponse.onRequestContinued");
}
try {
mAccountAuthenticatorResponse.onRequestContinued();
} catch (RemoteException e) {
// this should never happen
}
}
public void onError(int errorCode, String errorMessage) {
if (Log.isLoggable(TAG, Log.VERBOSE)) {
Log.v(TAG, "AccountAuthenticatorResponse.onError: " + errorCode + ", " + errorMessage);
}
try {
mAccountAuthenticatorResponse.onError(errorCode, errorMessage);
} catch (RemoteException e) {
// this should never happen
}
}
public int describeContents() {
return 0;
}
public void writeToParcel(Parcel dest, int flags) {
dest.writeStrongBinder(mAccountAuthenticatorResponse.asBinder());
}
public static final Creator<AccountAuthenticatorResponse> CREATOR =
new Creator<AccountAuthenticatorResponse>() {
public AccountAuthenticatorResponse createFromParcel(Parcel source) {
return new AccountAuthenticatorResponse(source);
}
public AccountAuthenticatorResponse[] newArray(int size) {
return new AccountAuthenticatorResponse[size];
}
};
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,20 @@
/*
* Copyright (C) 2009 The Android Open Source Project
*
* 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 android.accounts;
public interface AccountManagerCallback<V> {
void run(AccountManagerFuture<V> future);
}

View File

@ -0,0 +1,117 @@
/*
* Copyright (C) 2009 The Android Open Source Project
*
* 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 android.accounts;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeoutException;
import java.io.IOException;
/**
* A <tt>AccountManagerFuture</tt> represents the result of an asynchronous
* {@link AccountManager} call. Methods are provided to check if the computation is
* complete, to wait for its completion, and to retrieve the result of
* the computation. The result can only be retrieved using method
* <tt>get</tt> when the computation has completed, blocking if
* necessary until it is ready. Cancellation is performed by the
* <tt>cancel</tt> method. Additional methods are provided to
* determine if the task completed normally or was cancelled. Once a
* computation has completed, the computation cannot be cancelled.
* If you would like to use a <tt>Future</tt> for the sake
* of cancellability but not provide a usable result, you can
* declare types of the form <tt>Future&lt;?&gt;</tt> and
* return <tt>null</tt> as a result of the underlying task.
*/
public interface AccountManagerFuture<V> {
/**
* Attempts to cancel execution of this task. This attempt will
* fail if the task has already completed, has already been cancelled,
* or could not be cancelled for some other reason. If successful,
* and this task has not started when <tt>cancel</tt> is called,
* this task should never run. If the task has already started,
* then the <tt>mayInterruptIfRunning</tt> parameter determines
* whether the thread executing this task should be interrupted in
* an attempt to stop the task.
*
* <p>After this method returns, subsequent calls to {@link #isDone} will
* always return <tt>true</tt>. Subsequent calls to {@link #isCancelled}
* will always return <tt>true</tt> if this method returned <tt>true</tt>.
*
* @param mayInterruptIfRunning <tt>true</tt> if the thread executing this
* task should be interrupted; otherwise, in-progress tasks are allowed
* to complete
* @return <tt>false</tt> if the task could not be cancelled,
* typically because it has already completed normally;
* <tt>true</tt> otherwise
*/
boolean cancel(boolean mayInterruptIfRunning);
/**
* Returns <tt>true</tt> if this task was cancelled before it completed
* normally.
*
* @return <tt>true</tt> if this task was cancelled before it completed
*/
boolean isCancelled();
/**
* Returns <tt>true</tt> if this task completed.
*
* Completion may be due to normal termination, an exception, or
* cancellation -- in all of these cases, this method will return
* <tt>true</tt>.
*
* @return <tt>true</tt> if this task completed
*/
boolean isDone();
/**
* Accessor for the future result the {@link AccountManagerFuture} represents. This
* call will block until the result is available. In order to check if the result is
* available without blocking, one may call {@link #isDone()} and {@link #isCancelled()}.
* If the request that generated this result fails or is canceled then an exception
* will be thrown rather than the call returning normally.
* @return the actual result
* @throws android.accounts.OperationCanceledException if the request was canceled for any
* reason
* @throws android.accounts.AuthenticatorException if there was an error communicating with
* the authenticator or if the authenticator returned an invalid response
* @throws java.io.IOException if the authenticator returned an error response that indicates
* that it encountered an IOException while communicating with the authentication server
*/
V getResult() throws OperationCanceledException, IOException, AuthenticatorException;
/**
* Accessor for the future result the {@link AccountManagerFuture} represents. This
* call will block until the result is available. In order to check if the result is
* available without blocking, one may call {@link #isDone()} and {@link #isCancelled()}.
* If the request that generated this result fails or is canceled then an exception
* will be thrown rather than the call returning normally. If a timeout is specified then
* the request will automatically be canceled if it does not complete in that amount of time.
* @param timeout the maximum time to wait
* @param unit the time unit of the timeout argument. This must not be null.
* @return the actual result
* @throws android.accounts.OperationCanceledException if the request was canceled for any
* reason
* @throws android.accounts.AuthenticatorException if there was an error communicating with
* the authenticator or if the authenticator returned an invalid response
* @throws java.io.IOException if the authenticator returned an error response that indicates
* that it encountered an IOException while communicating with the authentication server
*/
V getResult(long timeout, TimeUnit unit)
throws OperationCanceledException, IOException, AuthenticatorException;
}

View File

@ -0,0 +1,79 @@
/*
* Copyright (C) 2009 The Android Open Source Project
*
* 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 android.accounts;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.RemoteException;
/**
* Used to return a response to the AccountManager.
* @hide
*/
public class AccountManagerResponse implements Parcelable {
private IAccountManagerResponse mResponse;
/** @hide */
public AccountManagerResponse(IAccountManagerResponse response) {
mResponse = response;
}
/** @hide */
public AccountManagerResponse(Parcel parcel) {
mResponse =
IAccountManagerResponse.Stub.asInterface(parcel.readStrongBinder());
}
public void onResult(Bundle result) {
try {
mResponse.onResult(result);
} catch (RemoteException e) {
// this should never happen
}
}
public void onError(int errorCode, String errorMessage) {
try {
mResponse.onError(errorCode, errorMessage);
} catch (RemoteException e) {
// this should never happen
}
}
/** @hide */
public int describeContents() {
return 0;
}
/** @hide */
public void writeToParcel(Parcel dest, int flags) {
dest.writeStrongBinder(mResponse.asBinder());
}
/** @hide */
public static final Creator<AccountManagerResponse> CREATOR =
new Creator<AccountManagerResponse>() {
public AccountManagerResponse createFromParcel(Parcel source) {
return new AccountManagerResponse(source);
}
public AccountManagerResponse[] newArray(int size) {
return new AccountManagerResponse[size];
}
};
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,32 @@
/*
* Copyright (C) 2009 The Android Open Source Project
*
* 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 android.accounts;
public class AccountsException extends Exception {
public AccountsException() {
super();
}
public AccountsException(String message) {
super(message);
}
public AccountsException(String message, Throwable cause) {
super(message, cause);
}
public AccountsException(Throwable cause) {
super(cause);
}
}

View File

@ -0,0 +1,19 @@
/*
* Copyright (C) 2009 The Android Open Source Project
*
* 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 android.accounts;
parcelable AuthenticatorDescription;

View File

@ -0,0 +1,149 @@
/*
* Copyright (C) 2009 The Android Open Source Project
*
* 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 android.accounts;
import android.os.Parcelable;
import android.os.Parcel;
/**
* A {@link Parcelable} value type that contains information about an account authenticator.
*/
public class AuthenticatorDescription implements Parcelable {
/** The string that uniquely identifies an authenticator */
final public String type;
/** A resource id of a label for the authenticator that is suitable for displaying */
final public int labelId;
/** A resource id of a icon for the authenticator */
final public int iconId;
/** A resource id of a smaller icon for the authenticator */
final public int smallIconId;
/**
* A resource id for a hierarchy of PreferenceScreen to be added to the settings page for the
* account. See {@link AbstractAccountAuthenticator} for an example.
*/
final public int accountPreferencesId;
/** The package name that can be used to lookup the resources from above. */
final public String packageName;
/** Authenticator handles its own token caching and permission screen
* @hide
*/
final public boolean customTokens;
/** A constructor for a full AuthenticatorDescription
* @hide
*/
public AuthenticatorDescription(String type, String packageName, int labelId, int iconId,
int smallIconId, int prefId, boolean customTokens) {
if (type == null) throw new IllegalArgumentException("type cannot be null");
if (packageName == null) throw new IllegalArgumentException("packageName cannot be null");
this.type = type;
this.packageName = packageName;
this.labelId = labelId;
this.iconId = iconId;
this.smallIconId = smallIconId;
this.accountPreferencesId = prefId;
this.customTokens = customTokens;
}
public AuthenticatorDescription(String type, String packageName, int labelId, int iconId,
int smallIconId, int prefId) {
this(type, packageName, labelId, iconId, smallIconId, prefId, false);
}
/**
* A factory method for creating an AuthenticatorDescription that can be used as a key
* to identify the authenticator by its type.
*/
public static AuthenticatorDescription newKey(String type) {
if (type == null) throw new IllegalArgumentException("type cannot be null");
return new AuthenticatorDescription(type);
}
private AuthenticatorDescription(String type) {
this.type = type;
this.packageName = null;
this.labelId = 0;
this.iconId = 0;
this.smallIconId = 0;
this.accountPreferencesId = 0;
this.customTokens = false;
}
private AuthenticatorDescription(Parcel source) {
this.type = source.readString();
this.packageName = source.readString();
this.labelId = source.readInt();
this.iconId = source.readInt();
this.smallIconId = source.readInt();
this.accountPreferencesId = source.readInt();
this.customTokens = source.readByte() == 1;
}
/** @inheritDoc */
public int describeContents() {
return 0;
}
/** Returns the hashcode of the type only. */
public int hashCode() {
return type.hashCode();
}
/** Compares the type only, suitable for key comparisons. */
public boolean equals(Object o) {
if (o == this) return true;
if (!(o instanceof AuthenticatorDescription)) return false;
final AuthenticatorDescription other = (AuthenticatorDescription) o;
return type.equals(other.type);
}
public String toString() {
return "AuthenticatorDescription {type=" + type + "}";
}
/** @inheritDoc */
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(type);
dest.writeString(packageName);
dest.writeInt(labelId);
dest.writeInt(iconId);
dest.writeInt(smallIconId);
dest.writeInt(accountPreferencesId);
dest.writeByte((byte) (customTokens ? 1 : 0));
}
/** Used to create the object from a parcel. */
public static final Creator<AuthenticatorDescription> CREATOR =
new Creator<AuthenticatorDescription>() {
/** @inheritDoc */
public AuthenticatorDescription createFromParcel(Parcel source) {
return new AuthenticatorDescription(source);
}
/** @inheritDoc */
public AuthenticatorDescription[] newArray(int size) {
return new AuthenticatorDescription[size];
}
};
}

View File

@ -0,0 +1,32 @@
/*
* Copyright (C) 2009 The Android Open Source Project
*
* 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 android.accounts;
public class AuthenticatorException extends AccountsException {
public AuthenticatorException() {
super();
}
public AuthenticatorException(String message) {
super(message);
}
public AuthenticatorException(String message, Throwable cause) {
super(message, cause);
}
public AuthenticatorException(Throwable cause) {
super(cause);
}
}

View File

@ -0,0 +1,82 @@
/*
* Copyright (C) 2009 The Android Open Source Project
*
* 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 android.accounts;
import android.app.ListActivity;
import android.os.Bundle;
import android.os.Parcelable;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.view.View;
import android.util.Log;
/**
* @hide
*/
public class ChooseAccountActivity extends ListActivity {
private static final String TAG = "AccountManager";
private Parcelable[] mAccounts = null;
private AccountManagerResponse mAccountManagerResponse = null;
private Bundle mResult;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mAccounts = getIntent().getParcelableArrayExtra(AccountManager.KEY_ACCOUNTS);
mAccountManagerResponse =
getIntent().getParcelableExtra(AccountManager.KEY_ACCOUNT_MANAGER_RESPONSE);
// KEY_ACCOUNTS is a required parameter
if (mAccounts == null) {
setResult(RESULT_CANCELED);
finish();
return;
}
String[] mAccountNames = new String[mAccounts.length];
for (int i = 0; i < mAccounts.length; i++) {
mAccountNames[i] = ((Account) mAccounts[i]).name;
}
// Use an existing ListAdapter that will map an array
// of strings to TextViews
setListAdapter(new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, mAccountNames));
getListView().setTextFilterEnabled(true);
}
protected void onListItemClick(ListView l, View v, int position, long id) {
Account account = (Account) mAccounts[position];
Log.d(TAG, "selected account " + account);
Bundle bundle = new Bundle();
bundle.putString(AccountManager.KEY_ACCOUNT_NAME, account.name);
bundle.putString(AccountManager.KEY_ACCOUNT_TYPE, account.type);
mResult = bundle;
finish();
}
public void finish() {
if (mAccountManagerResponse != null) {
if (mResult != null) {
mAccountManagerResponse.onResult(mResult);
} else {
mAccountManagerResponse.onError(AccountManager.ERROR_CODE_CANCELED, "canceled");
}
}
super.finish();
}
}

View File

@ -0,0 +1,170 @@
/*
* Copyright (C) 2009 The Android Open Source Project
*
* 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 android.accounts;
import android.app.Activity;
import android.os.Bundle;
import android.os.RemoteException;
import android.widget.TextView;
import android.widget.LinearLayout;
import android.widget.ImageView;
import android.view.View;
import android.view.LayoutInflater;
import android.view.Window;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.RegisteredServicesCache;
import android.text.TextUtils;
import android.graphics.drawable.Drawable;
import com.android.internal.R;
/**
* @hide
*/
public class GrantCredentialsPermissionActivity extends Activity implements View.OnClickListener {
public static final String EXTRAS_ACCOUNT = "account";
public static final String EXTRAS_AUTH_TOKEN_LABEL = "authTokenLabel";
public static final String EXTRAS_AUTH_TOKEN_TYPE = "authTokenType";
public static final String EXTRAS_RESPONSE = "response";
public static final String EXTRAS_ACCOUNT_TYPE_LABEL = "accountTypeLabel";
public static final String EXTRAS_PACKAGES = "application";
public static final String EXTRAS_REQUESTING_UID = "uid";
private Account mAccount;
private String mAuthTokenType;
private int mUid;
private Bundle mResultBundle = null;
protected LayoutInflater mInflater;
private final AccountManagerService accountManagerService = AccountManagerService.getSingleton();
protected void onCreate(Bundle savedInstanceState) {
requestWindowFeature(Window.FEATURE_NO_TITLE);
super.onCreate(savedInstanceState);
setContentView(R.layout.grant_credentials_permission);
mInflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
final Bundle extras = getIntent().getExtras();
// Grant 'account'/'type' to mUID
mAccount = extras.getParcelable(EXTRAS_ACCOUNT);
mAuthTokenType = extras.getString(EXTRAS_AUTH_TOKEN_TYPE);
mUid = extras.getInt(EXTRAS_REQUESTING_UID);
final PackageManager pm = getPackageManager();
final String[] packages = pm.getPackagesForUid(mUid);
if (mAccount == null || mAuthTokenType == null || packages == null) {
// we were somehow started with bad parameters. abort the activity.
setResult(Activity.RESULT_CANCELED);
finish();
return;
}
final String accountTypeLabel = accountManagerService.getAccountLabel(mAccount.type);
final TextView authTokenTypeView = (TextView) findViewById(R.id.authtoken_type);
authTokenTypeView.setVisibility(View.GONE);
/** Handles the responses from the AccountManager */
IAccountManagerResponse response = new IAccountManagerResponse.Stub() {
public void onResult(Bundle bundle) {
final String authTokenLabel =
bundle.getString(AccountManager.KEY_AUTH_TOKEN_LABEL);
if (!TextUtils.isEmpty(authTokenLabel)) {
runOnUiThread(new Runnable() {
public void run() {
if (!isFinishing()) {
authTokenTypeView.setText(authTokenLabel);
authTokenTypeView.setVisibility(View.VISIBLE);
}
}
});
}
}
public void onError(int code, String message) {
}
};
accountManagerService.getAuthTokenLabel(
response, mAccount, mAuthTokenType);
findViewById(R.id.allow_button).setOnClickListener(this);
findViewById(R.id.deny_button).setOnClickListener(this);
LinearLayout packagesListView = (LinearLayout) findViewById(R.id.packages_list);
for (String pkg : packages) {
String packageLabel;
try {
packageLabel = pm.getApplicationLabel(pm.getApplicationInfo(pkg, 0)).toString();
} catch (PackageManager.NameNotFoundException e) {
packageLabel = pkg;
}
packagesListView.addView(newPackageView(packageLabel));
}
((TextView) findViewById(R.id.account_name)).setText(mAccount.name);
((TextView) findViewById(R.id.account_type)).setText(accountTypeLabel);
}
private View newPackageView(String packageLabel) {
View view = mInflater.inflate(R.layout.permissions_package_list_item, null);
((TextView) view.findViewById(R.id.package_label)).setText(packageLabel);
return view;
}
public void onClick(View v) {
switch (v.getId()) {
case R.id.allow_button:
accountManagerService.grantAppPermission(mAccount, mAuthTokenType, mUid);
Intent result = new Intent();
result.putExtra("retry", true);
setResult(RESULT_OK, result);
setAccountAuthenticatorResult(result.getExtras());
break;
case R.id.deny_button:
accountManagerService.revokeAppPermission(mAccount, mAuthTokenType, mUid);
setResult(RESULT_CANCELED);
break;
}
finish();
}
public final void setAccountAuthenticatorResult(Bundle result) {
mResultBundle = result;
}
/**
* Sends the result or a {@link AccountManager#ERROR_CODE_CANCELED} error if a
* result isn't present.
*/
public void finish() {
Intent intent = getIntent();
AccountAuthenticatorResponse response = intent.getParcelableExtra(EXTRAS_RESPONSE);
if (response != null) {
// send the result bundle back if set, otherwise send an error.
if (mResultBundle != null) {
response.onResult(mResultBundle);
} else {
response.onError(AccountManager.ERROR_CODE_CANCELED, "canceled");
}
}
super.finish();
}
}

View File

@ -0,0 +1,73 @@
/*
* Copyright (C) 2009 The Android Open Source Project
*
* 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 android.accounts;
import android.accounts.IAccountAuthenticatorResponse;
import android.accounts.Account;
import android.os.Bundle;
/**
* Service that allows the interaction with an authentication server.
* @hide
*/
oneway interface IAccountAuthenticator {
/**
* prompts the user for account information and adds the result to the IAccountManager
*/
void addAccount(in IAccountAuthenticatorResponse response, String accountType,
String authTokenType, in String[] requiredFeatures, in Bundle options);
/**
* prompts the user for the credentials of the account
*/
void confirmCredentials(in IAccountAuthenticatorResponse response, in Account account,
in Bundle options);
/**
* gets the password by either prompting the user or querying the IAccountManager
*/
void getAuthToken(in IAccountAuthenticatorResponse response, in Account account,
String authTokenType, in Bundle options);
/**
* Gets the user-visible label of the given authtoken type.
*/
void getAuthTokenLabel(in IAccountAuthenticatorResponse response, String authTokenType);
/**
* prompts the user for a new password and writes it to the IAccountManager
*/
void updateCredentials(in IAccountAuthenticatorResponse response, in Account account,
String authTokenType, in Bundle options);
/**
* launches an activity that lets the user edit and set the properties for an authenticator
*/
void editProperties(in IAccountAuthenticatorResponse response, String accountType);
/**
* returns a Bundle where the boolean value BOOLEAN_RESULT_KEY is set if the account has the
* specified features
*/
void hasFeatures(in IAccountAuthenticatorResponse response, in Account account,
in String[] features);
/**
* Gets whether or not the account is allowed to be removed.
*/
void getAccountRemovalAllowed(in IAccountAuthenticatorResponse response, in Account account);
}

View File

@ -0,0 +1,28 @@
/*
* Copyright (C) 2009 The Android Open Source Project
*
* 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 android.accounts;
import android.os.Bundle;
/**
* The interface used to return responses from an {@link IAccountAuthenticator}
* @hide
*/
oneway interface IAccountAuthenticatorResponse {
void onResult(in Bundle value);
void onRequestContinued();
void onError(int errorCode, String errorMessage);
}

View File

@ -0,0 +1,57 @@
/*
* Copyright (C) 2009 The Android Open Source Project
*
* 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 android.accounts;
import android.accounts.IAccountManagerResponse;
import android.accounts.Account;
import android.accounts.AuthenticatorDescription;
import android.os.Bundle;
/**
* Central application service that provides account management.
* @hide
*/
interface IAccountManager {
String getPassword(in Account account);
String getUserData(in Account account, String key);
AuthenticatorDescription[] getAuthenticatorTypes();
Account[] getAccounts(String accountType);
void hasFeatures(in IAccountManagerResponse response, in Account account, in String[] features);
void getAccountsByFeatures(in IAccountManagerResponse response, String accountType, in String[] features);
boolean addAccount(in Account account, String password, in Bundle extras);
void removeAccount(in IAccountManagerResponse response, in Account account);
void invalidateAuthToken(String accountType, String authToken);
String peekAuthToken(in Account account, String authTokenType);
void setAuthToken(in Account account, String authTokenType, String authToken);
void setPassword(in Account account, String password);
void clearPassword(in Account account);
void setUserData(in Account account, String key, String value);
void getAuthToken(in IAccountManagerResponse response, in Account account,
String authTokenType, boolean notifyOnAuthFailure, boolean expectActivityLaunch,
in Bundle options);
void addAcount(in IAccountManagerResponse response, String accountType,
String authTokenType, in String[] requiredFeatures, boolean expectActivityLaunch,
in Bundle options);
void updateCredentials(in IAccountManagerResponse response, in Account account,
String authTokenType, boolean expectActivityLaunch, in Bundle options);
void editProperties(in IAccountManagerResponse response, String accountType,
boolean expectActivityLaunch);
void confirmCredentials(in IAccountManagerResponse response, in Account account,
in Bundle options, boolean expectActivityLaunch);
}

View File

@ -0,0 +1,27 @@
/*
* Copyright (C) 2009 The Android Open Source Project
*
* 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 android.accounts;
import android.os.Bundle;
/**
* The interface used to return responses for asynchronous calls to the {@link IAccountManager}
* @hide
*/
oneway interface IAccountManagerResponse {
void onResult(in Bundle value);
void onError(int errorCode, String errorMessage);
}

View File

@ -0,0 +1,31 @@
/*
* Copyright (C) 2009 The Android Open Source Project
*
* 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 android.accounts;
public class NetworkErrorException extends AccountsException {
public NetworkErrorException() {
super();
}
public NetworkErrorException(String message) {
super(message);
}
public NetworkErrorException(String message, Throwable cause) {
super(message, cause);
}
public NetworkErrorException(Throwable cause) {
super(cause);
}
}

View File

@ -0,0 +1,29 @@
/*
* Copyright (C) 2007 The Android Open Source Project
*
* 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 android.accounts;
/**
* An interface that contains the callback used by the AccountMonitor
*/
public interface OnAccountsUpdateListener {
/**
* This invoked when the AccountMonitor starts up and whenever the account
* set changes.
* @param accounts the current accounts
*/
void onAccountsUpdated(Account[] accounts);
}

View File

@ -0,0 +1,31 @@
/*
* Copyright (C) 2009 The Android Open Source Project
*
* 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 android.accounts;
public class OperationCanceledException extends AccountsException {
public OperationCanceledException() {
super();
}
public OperationCanceledException(String message) {
super(message);
}
public OperationCanceledException(String message, Throwable cause) {
super(message, cause);
}
public OperationCanceledException(Throwable cause) {
super(cause);
}
}