Loading Android.mk +1 −0 Original line number Diff line number Diff line Loading @@ -63,6 +63,7 @@ LOCAL_SRC_FILES += \ core/java/android/accessibilityservice/IAccessibilityServiceClient.aidl \ core/java/android/accounts/IAccountManager.aidl \ core/java/android/accounts/IAccountManagerResponse.aidl \ core/java/android/accounts/IAccountAccessTracker.aidl \ core/java/android/accounts/IAccountAuthenticator.aidl \ core/java/android/accounts/IAccountAuthenticatorResponse.aidl \ core/java/android/app/IActivityContainer.aidl \ Loading core/java/android/accounts/Account.java +47 −0 Original line number Diff line number Diff line Loading @@ -16,9 +16,17 @@ package android.accounts; import android.annotation.NonNull; import android.annotation.Nullable; import android.os.Parcelable; import android.os.Parcel; import android.os.RemoteException; import android.text.TextUtils; import android.util.ArraySet; import android.util.Log; import com.android.internal.annotations.GuardedBy; import java.util.Set; /** * Value type that represents an Account in the {@link AccountManager}. This object is Loading @@ -26,8 +34,14 @@ import android.text.TextUtils; * suitable for use as the key of a {@link java.util.Map} */ public class Account implements Parcelable { private static final String TAG = "Account"; @GuardedBy("sAccessedAccounts") private static final Set<Account> sAccessedAccounts = new ArraySet<>(); public final String name; public final String type; private final @Nullable IAccountAccessTracker mAccessTracker; public boolean equals(Object o) { if (o == this) return true; Loading @@ -44,6 +58,20 @@ public class Account implements Parcelable { } public Account(String name, String type) { this(name, type, null); } /** * @hide */ public Account(@NonNull Account other, @Nullable IAccountAccessTracker accessTracker) { this(other.name, other.type, accessTracker); } /** * @hide */ public Account(String name, String type, IAccountAccessTracker accessTracker) { if (TextUtils.isEmpty(name)) { throw new IllegalArgumentException("the name must not be empty: " + name); } Loading @@ -52,11 +80,29 @@ public class Account implements Parcelable { } this.name = name; this.type = type; this.mAccessTracker = accessTracker; } public Account(Parcel in) { this.name = in.readString(); this.type = in.readString(); this.mAccessTracker = IAccountAccessTracker.Stub.asInterface(in.readStrongBinder()); if (mAccessTracker != null) { synchronized (sAccessedAccounts) { if (sAccessedAccounts.add(this)) { try { mAccessTracker.onAccountAccessed(); } catch (RemoteException e) { Log.e(TAG, "Error noting account access", e); } } } } } /** @hide */ public IAccountAccessTracker getAccessTracker() { return mAccessTracker; } public int describeContents() { Loading @@ -66,6 +112,7 @@ public class Account implements Parcelable { public void writeToParcel(Parcel dest, int flags) { dest.writeString(name); dest.writeString(type); dest.writeStrongInterface(mAccessTracker); } public static final Creator<Account> CREATOR = new Creator<Account>() { Loading core/java/android/accounts/AccountManager.java +26 −10 Original line number Diff line number Diff line Loading @@ -18,7 +18,6 @@ package android.accounts; import static android.Manifest.permission.GET_ACCOUNTS; import android.annotation.IntRange; import android.annotation.NonNull; import android.annotation.RequiresPermission; import android.annotation.Size; Loading Loading @@ -179,6 +178,14 @@ public class AccountManager { */ public static final String KEY_ACCOUNT_TYPE = "accountType"; /** * Bundle key used for the {@link IAccountAccessTracker} account access tracker * used for noting the account was accessed when unmarshalled from a parcel. * * @hide */ public static final String KEY_ACCOUNT_ACCESS_TRACKER = "accountAccessTracker"; /** * Bundle key used for the auth token value in results * from {@link #getAuthToken} and friends. Loading Loading @@ -268,13 +275,13 @@ public class AccountManager { public static final String AUTHENTICATOR_ATTRIBUTES_NAME = "account-authenticator"; /** * Token for the special case where a UID has access only to an account * but no authenticator specific auth tokens. * Token type for the special case where a UID has access only to an account * but no authenticator specific auth token types. * * @hide */ public static final String ACCOUNT_ACCESS_TOKEN = "com.android.abbfd278-af8b-415d-af8b-7571d5dab133"; public static final String ACCOUNT_ACCESS_TOKEN_TYPE = "com.android.AccountManager.ACCOUNT_ACCESS_TOKEN_TYPE"; private final Context mContext; private final IAccountManager mService; Loading Loading @@ -814,7 +821,9 @@ public class AccountManager { public Account bundleToResult(Bundle bundle) throws AuthenticatorException { String name = bundle.getString(KEY_ACCOUNT_NAME); String type = bundle.getString(KEY_ACCOUNT_TYPE); return new Account(name, type); IAccountAccessTracker tracker = IAccountAccessTracker.Stub.asInterface( bundle.getBinder(KEY_ACCOUNT_ACCESS_TRACKER)); return new Account(name, type, tracker); } }.start(); } Loading Loading @@ -2270,6 +2279,7 @@ public class AccountManager { result.putString(KEY_ACCOUNT_NAME, null); result.putString(KEY_ACCOUNT_TYPE, null); result.putString(KEY_AUTHTOKEN, null); result.putBinder(KEY_ACCOUNT_ACCESS_TRACKER, null); try { mResponse.onResult(result); } catch (RemoteException e) { Loading @@ -2295,9 +2305,13 @@ public class AccountManager { public void onResult(Bundle value) throws RemoteException { Account account = new Account( value.getString(KEY_ACCOUNT_NAME), value.getString(KEY_ACCOUNT_TYPE)); mFuture = getAuthToken(account, mAuthTokenType, mLoginOptions, mActivity, mMyCallback, mHandler); value.getString(KEY_ACCOUNT_TYPE), IAccountAccessTracker.Stub.asInterface( value.getBinder( KEY_ACCOUNT_ACCESS_TRACKER))); mFuture = getAuthToken(account, mAuthTokenType, mLoginOptions, mActivity, mMyCallback, mHandler); } @Override Loading Loading @@ -2344,7 +2358,9 @@ public class AccountManager { setException(new AuthenticatorException("account not in result")); return; } final Account account = new Account(accountName, accountType); final IAccountAccessTracker tracker = IAccountAccessTracker.Stub.asInterface( result.getBinder(KEY_ACCOUNT_ACCESS_TRACKER)); final Account account = new Account(accountName, accountType, tracker); mNumAccounts = 1; getAuthToken(account, mAuthTokenType, null /* options */, mActivity, mMyCallback, mHandler); Loading core/java/android/accounts/AccountManagerInternal.java +33 −1 Original line number Diff line number Diff line Loading @@ -27,6 +27,21 @@ import android.os.RemoteCallback; */ public abstract class AccountManagerInternal { /** * Listener for explicit UID account access grant changes. */ public interface OnAppPermissionChangeListener { /** * Called when the explicit grant state for a given UID to * access an account changes. * * @param account The account * @param uid The UID for which the grant changed */ public void onAppPermissionChanged(Account account, int uid); } /** * Requests that a given package is given access to an account. * The provided callback will be invoked with a {@link android.os.Bundle} Loading @@ -41,4 +56,21 @@ public abstract class AccountManagerInternal { public abstract void requestAccountAccess(@NonNull Account account, @NonNull String packageName, @IntRange(from = 0) int userId, @NonNull RemoteCallback callback); /** * Check whether the given UID has access to the account. * * @param account The account * @param uid The UID * @return Whether the UID can access the account */ public abstract boolean hasAccountAccess(@NonNull Account account, @IntRange(from = 0) int uid); /** * Adds a listener for explicit UID account access grant changes. * * @param listener The listener */ public abstract void addOnAppPermissionChangeListener( @NonNull OnAppPermissionChangeListener listener); } core/java/android/accounts/GrantCredentialsPermissionActivity.java +1 −1 Original line number Diff line number Diff line Loading @@ -108,7 +108,7 @@ public class GrantCredentialsPermissionActivity extends Activity implements View } }; if (!AccountManager.ACCOUNT_ACCESS_TOKEN.equals(mAuthTokenType)) { if (!AccountManager.ACCOUNT_ACCESS_TOKEN_TYPE.equals(mAuthTokenType)) { AccountManager.get(this).getAuthTokenLabel(mAccount.type, mAuthTokenType, callback, null); } Loading Loading
Android.mk +1 −0 Original line number Diff line number Diff line Loading @@ -63,6 +63,7 @@ LOCAL_SRC_FILES += \ core/java/android/accessibilityservice/IAccessibilityServiceClient.aidl \ core/java/android/accounts/IAccountManager.aidl \ core/java/android/accounts/IAccountManagerResponse.aidl \ core/java/android/accounts/IAccountAccessTracker.aidl \ core/java/android/accounts/IAccountAuthenticator.aidl \ core/java/android/accounts/IAccountAuthenticatorResponse.aidl \ core/java/android/app/IActivityContainer.aidl \ Loading
core/java/android/accounts/Account.java +47 −0 Original line number Diff line number Diff line Loading @@ -16,9 +16,17 @@ package android.accounts; import android.annotation.NonNull; import android.annotation.Nullable; import android.os.Parcelable; import android.os.Parcel; import android.os.RemoteException; import android.text.TextUtils; import android.util.ArraySet; import android.util.Log; import com.android.internal.annotations.GuardedBy; import java.util.Set; /** * Value type that represents an Account in the {@link AccountManager}. This object is Loading @@ -26,8 +34,14 @@ import android.text.TextUtils; * suitable for use as the key of a {@link java.util.Map} */ public class Account implements Parcelable { private static final String TAG = "Account"; @GuardedBy("sAccessedAccounts") private static final Set<Account> sAccessedAccounts = new ArraySet<>(); public final String name; public final String type; private final @Nullable IAccountAccessTracker mAccessTracker; public boolean equals(Object o) { if (o == this) return true; Loading @@ -44,6 +58,20 @@ public class Account implements Parcelable { } public Account(String name, String type) { this(name, type, null); } /** * @hide */ public Account(@NonNull Account other, @Nullable IAccountAccessTracker accessTracker) { this(other.name, other.type, accessTracker); } /** * @hide */ public Account(String name, String type, IAccountAccessTracker accessTracker) { if (TextUtils.isEmpty(name)) { throw new IllegalArgumentException("the name must not be empty: " + name); } Loading @@ -52,11 +80,29 @@ public class Account implements Parcelable { } this.name = name; this.type = type; this.mAccessTracker = accessTracker; } public Account(Parcel in) { this.name = in.readString(); this.type = in.readString(); this.mAccessTracker = IAccountAccessTracker.Stub.asInterface(in.readStrongBinder()); if (mAccessTracker != null) { synchronized (sAccessedAccounts) { if (sAccessedAccounts.add(this)) { try { mAccessTracker.onAccountAccessed(); } catch (RemoteException e) { Log.e(TAG, "Error noting account access", e); } } } } } /** @hide */ public IAccountAccessTracker getAccessTracker() { return mAccessTracker; } public int describeContents() { Loading @@ -66,6 +112,7 @@ public class Account implements Parcelable { public void writeToParcel(Parcel dest, int flags) { dest.writeString(name); dest.writeString(type); dest.writeStrongInterface(mAccessTracker); } public static final Creator<Account> CREATOR = new Creator<Account>() { Loading
core/java/android/accounts/AccountManager.java +26 −10 Original line number Diff line number Diff line Loading @@ -18,7 +18,6 @@ package android.accounts; import static android.Manifest.permission.GET_ACCOUNTS; import android.annotation.IntRange; import android.annotation.NonNull; import android.annotation.RequiresPermission; import android.annotation.Size; Loading Loading @@ -179,6 +178,14 @@ public class AccountManager { */ public static final String KEY_ACCOUNT_TYPE = "accountType"; /** * Bundle key used for the {@link IAccountAccessTracker} account access tracker * used for noting the account was accessed when unmarshalled from a parcel. * * @hide */ public static final String KEY_ACCOUNT_ACCESS_TRACKER = "accountAccessTracker"; /** * Bundle key used for the auth token value in results * from {@link #getAuthToken} and friends. Loading Loading @@ -268,13 +275,13 @@ public class AccountManager { public static final String AUTHENTICATOR_ATTRIBUTES_NAME = "account-authenticator"; /** * Token for the special case where a UID has access only to an account * but no authenticator specific auth tokens. * Token type for the special case where a UID has access only to an account * but no authenticator specific auth token types. * * @hide */ public static final String ACCOUNT_ACCESS_TOKEN = "com.android.abbfd278-af8b-415d-af8b-7571d5dab133"; public static final String ACCOUNT_ACCESS_TOKEN_TYPE = "com.android.AccountManager.ACCOUNT_ACCESS_TOKEN_TYPE"; private final Context mContext; private final IAccountManager mService; Loading Loading @@ -814,7 +821,9 @@ public class AccountManager { public Account bundleToResult(Bundle bundle) throws AuthenticatorException { String name = bundle.getString(KEY_ACCOUNT_NAME); String type = bundle.getString(KEY_ACCOUNT_TYPE); return new Account(name, type); IAccountAccessTracker tracker = IAccountAccessTracker.Stub.asInterface( bundle.getBinder(KEY_ACCOUNT_ACCESS_TRACKER)); return new Account(name, type, tracker); } }.start(); } Loading Loading @@ -2270,6 +2279,7 @@ public class AccountManager { result.putString(KEY_ACCOUNT_NAME, null); result.putString(KEY_ACCOUNT_TYPE, null); result.putString(KEY_AUTHTOKEN, null); result.putBinder(KEY_ACCOUNT_ACCESS_TRACKER, null); try { mResponse.onResult(result); } catch (RemoteException e) { Loading @@ -2295,9 +2305,13 @@ public class AccountManager { public void onResult(Bundle value) throws RemoteException { Account account = new Account( value.getString(KEY_ACCOUNT_NAME), value.getString(KEY_ACCOUNT_TYPE)); mFuture = getAuthToken(account, mAuthTokenType, mLoginOptions, mActivity, mMyCallback, mHandler); value.getString(KEY_ACCOUNT_TYPE), IAccountAccessTracker.Stub.asInterface( value.getBinder( KEY_ACCOUNT_ACCESS_TRACKER))); mFuture = getAuthToken(account, mAuthTokenType, mLoginOptions, mActivity, mMyCallback, mHandler); } @Override Loading Loading @@ -2344,7 +2358,9 @@ public class AccountManager { setException(new AuthenticatorException("account not in result")); return; } final Account account = new Account(accountName, accountType); final IAccountAccessTracker tracker = IAccountAccessTracker.Stub.asInterface( result.getBinder(KEY_ACCOUNT_ACCESS_TRACKER)); final Account account = new Account(accountName, accountType, tracker); mNumAccounts = 1; getAuthToken(account, mAuthTokenType, null /* options */, mActivity, mMyCallback, mHandler); Loading
core/java/android/accounts/AccountManagerInternal.java +33 −1 Original line number Diff line number Diff line Loading @@ -27,6 +27,21 @@ import android.os.RemoteCallback; */ public abstract class AccountManagerInternal { /** * Listener for explicit UID account access grant changes. */ public interface OnAppPermissionChangeListener { /** * Called when the explicit grant state for a given UID to * access an account changes. * * @param account The account * @param uid The UID for which the grant changed */ public void onAppPermissionChanged(Account account, int uid); } /** * Requests that a given package is given access to an account. * The provided callback will be invoked with a {@link android.os.Bundle} Loading @@ -41,4 +56,21 @@ public abstract class AccountManagerInternal { public abstract void requestAccountAccess(@NonNull Account account, @NonNull String packageName, @IntRange(from = 0) int userId, @NonNull RemoteCallback callback); /** * Check whether the given UID has access to the account. * * @param account The account * @param uid The UID * @return Whether the UID can access the account */ public abstract boolean hasAccountAccess(@NonNull Account account, @IntRange(from = 0) int uid); /** * Adds a listener for explicit UID account access grant changes. * * @param listener The listener */ public abstract void addOnAppPermissionChangeListener( @NonNull OnAppPermissionChangeListener listener); }
core/java/android/accounts/GrantCredentialsPermissionActivity.java +1 −1 Original line number Diff line number Diff line Loading @@ -108,7 +108,7 @@ public class GrantCredentialsPermissionActivity extends Activity implements View } }; if (!AccountManager.ACCOUNT_ACCESS_TOKEN.equals(mAuthTokenType)) { if (!AccountManager.ACCOUNT_ACCESS_TOKEN_TYPE.equals(mAuthTokenType)) { AccountManager.get(this).getAuthTokenLabel(mAccount.type, mAuthTokenType, callback, null); } Loading