Merge "[DO NOT MERGE] Use tokens instead of account access trackers" into nyc-mr1-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
5c07d0c2ee
@@ -63,7 +63,6 @@ LOCAL_SRC_FILES += \
|
|||||||
core/java/android/accessibilityservice/IAccessibilityServiceClient.aidl \
|
core/java/android/accessibilityservice/IAccessibilityServiceClient.aidl \
|
||||||
core/java/android/accounts/IAccountManager.aidl \
|
core/java/android/accounts/IAccountManager.aidl \
|
||||||
core/java/android/accounts/IAccountManagerResponse.aidl \
|
core/java/android/accounts/IAccountManagerResponse.aidl \
|
||||||
core/java/android/accounts/IAccountAccessTracker.aidl \
|
|
||||||
core/java/android/accounts/IAccountAuthenticator.aidl \
|
core/java/android/accounts/IAccountAuthenticator.aidl \
|
||||||
core/java/android/accounts/IAccountAuthenticatorResponse.aidl \
|
core/java/android/accounts/IAccountAuthenticatorResponse.aidl \
|
||||||
core/java/android/app/IActivityContainer.aidl \
|
core/java/android/app/IActivityContainer.aidl \
|
||||||
|
|||||||
@@ -18,9 +18,11 @@ package android.accounts;
|
|||||||
|
|
||||||
import android.annotation.NonNull;
|
import android.annotation.NonNull;
|
||||||
import android.annotation.Nullable;
|
import android.annotation.Nullable;
|
||||||
|
import android.content.Context;
|
||||||
import android.os.Parcelable;
|
import android.os.Parcelable;
|
||||||
import android.os.Parcel;
|
import android.os.Parcel;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
|
import android.os.ServiceManager;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.util.ArraySet;
|
import android.util.ArraySet;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
@@ -41,7 +43,7 @@ public class Account implements Parcelable {
|
|||||||
|
|
||||||
public final String name;
|
public final String name;
|
||||||
public final String type;
|
public final String type;
|
||||||
private final @Nullable IAccountAccessTracker mAccessTracker;
|
private final @Nullable String accessId;
|
||||||
|
|
||||||
public boolean equals(Object o) {
|
public boolean equals(Object o) {
|
||||||
if (o == this) return true;
|
if (o == this) return true;
|
||||||
@@ -64,14 +66,14 @@ public class Account implements Parcelable {
|
|||||||
/**
|
/**
|
||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
public Account(@NonNull Account other, @Nullable IAccountAccessTracker accessTracker) {
|
public Account(@NonNull Account other, @NonNull String accessId) {
|
||||||
this(other.name, other.type, accessTracker);
|
this(other.name, other.type, accessId);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
public Account(String name, String type, IAccountAccessTracker accessTracker) {
|
public Account(String name, String type, String accessId) {
|
||||||
if (TextUtils.isEmpty(name)) {
|
if (TextUtils.isEmpty(name)) {
|
||||||
throw new IllegalArgumentException("the name must not be empty: " + name);
|
throw new IllegalArgumentException("the name must not be empty: " + name);
|
||||||
}
|
}
|
||||||
@@ -80,18 +82,20 @@ public class Account implements Parcelable {
|
|||||||
}
|
}
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.type = type;
|
this.type = type;
|
||||||
this.mAccessTracker = accessTracker;
|
this.accessId = accessId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Account(Parcel in) {
|
public Account(Parcel in) {
|
||||||
this.name = in.readString();
|
this.name = in.readString();
|
||||||
this.type = in.readString();
|
this.type = in.readString();
|
||||||
this.mAccessTracker = IAccountAccessTracker.Stub.asInterface(in.readStrongBinder());
|
this.accessId = in.readString();
|
||||||
if (mAccessTracker != null) {
|
if (accessId != null) {
|
||||||
synchronized (sAccessedAccounts) {
|
synchronized (sAccessedAccounts) {
|
||||||
if (sAccessedAccounts.add(this)) {
|
if (sAccessedAccounts.add(this)) {
|
||||||
try {
|
try {
|
||||||
mAccessTracker.onAccountAccessed();
|
IAccountManager accountManager = IAccountManager.Stub.asInterface(
|
||||||
|
ServiceManager.getService(Context.ACCOUNT_SERVICE));
|
||||||
|
accountManager.onAccountAccessed(accessId);
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
Log.e(TAG, "Error noting account access", e);
|
Log.e(TAG, "Error noting account access", e);
|
||||||
}
|
}
|
||||||
@@ -101,8 +105,8 @@ public class Account implements Parcelable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** @hide */
|
/** @hide */
|
||||||
public IAccountAccessTracker getAccessTracker() {
|
public String getAccessId() {
|
||||||
return mAccessTracker;
|
return accessId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int describeContents() {
|
public int describeContents() {
|
||||||
@@ -112,7 +116,7 @@ public class Account implements Parcelable {
|
|||||||
public void writeToParcel(Parcel dest, int flags) {
|
public void writeToParcel(Parcel dest, int flags) {
|
||||||
dest.writeString(name);
|
dest.writeString(name);
|
||||||
dest.writeString(type);
|
dest.writeString(type);
|
||||||
dest.writeStrongInterface(mAccessTracker);
|
dest.writeString(accessId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final Creator<Account> CREATOR = new Creator<Account>() {
|
public static final Creator<Account> CREATOR = new Creator<Account>() {
|
||||||
|
|||||||
@@ -179,12 +179,12 @@ public class AccountManager {
|
|||||||
public static final String KEY_ACCOUNT_TYPE = "accountType";
|
public static final String KEY_ACCOUNT_TYPE = "accountType";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Bundle key used for the {@link IAccountAccessTracker} account access tracker
|
* Bundle key used for the account access id used for noting the
|
||||||
* used for noting the account was accessed when unmarshalled from a parcel.
|
* account was accessed when unmarshalled from a parcel.
|
||||||
*
|
*
|
||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
public static final String KEY_ACCOUNT_ACCESS_TRACKER = "accountAccessTracker";
|
public static final String KEY_ACCOUNT_ACCESS_ID = "accountAccessId";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Bundle key used for the auth token value in results
|
* Bundle key used for the auth token value in results
|
||||||
@@ -821,9 +821,8 @@ public class AccountManager {
|
|||||||
public Account bundleToResult(Bundle bundle) throws AuthenticatorException {
|
public Account bundleToResult(Bundle bundle) throws AuthenticatorException {
|
||||||
String name = bundle.getString(KEY_ACCOUNT_NAME);
|
String name = bundle.getString(KEY_ACCOUNT_NAME);
|
||||||
String type = bundle.getString(KEY_ACCOUNT_TYPE);
|
String type = bundle.getString(KEY_ACCOUNT_TYPE);
|
||||||
IAccountAccessTracker tracker = IAccountAccessTracker.Stub.asInterface(
|
String accessId = bundle.getString(KEY_ACCOUNT_ACCESS_ID);
|
||||||
bundle.getBinder(KEY_ACCOUNT_ACCESS_TRACKER));
|
return new Account(name, type, accessId);
|
||||||
return new Account(name, type, tracker);
|
|
||||||
}
|
}
|
||||||
}.start();
|
}.start();
|
||||||
}
|
}
|
||||||
@@ -2279,7 +2278,7 @@ public class AccountManager {
|
|||||||
result.putString(KEY_ACCOUNT_NAME, null);
|
result.putString(KEY_ACCOUNT_NAME, null);
|
||||||
result.putString(KEY_ACCOUNT_TYPE, null);
|
result.putString(KEY_ACCOUNT_TYPE, null);
|
||||||
result.putString(KEY_AUTHTOKEN, null);
|
result.putString(KEY_AUTHTOKEN, null);
|
||||||
result.putBinder(KEY_ACCOUNT_ACCESS_TRACKER, null);
|
result.putBinder(KEY_ACCOUNT_ACCESS_ID, null);
|
||||||
try {
|
try {
|
||||||
mResponse.onResult(result);
|
mResponse.onResult(result);
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
@@ -2306,9 +2305,7 @@ public class AccountManager {
|
|||||||
Account account = new Account(
|
Account account = new Account(
|
||||||
value.getString(KEY_ACCOUNT_NAME),
|
value.getString(KEY_ACCOUNT_NAME),
|
||||||
value.getString(KEY_ACCOUNT_TYPE),
|
value.getString(KEY_ACCOUNT_TYPE),
|
||||||
IAccountAccessTracker.Stub.asInterface(
|
value.getString(KEY_ACCOUNT_ACCESS_ID));
|
||||||
value.getBinder(
|
|
||||||
KEY_ACCOUNT_ACCESS_TRACKER)));
|
|
||||||
mFuture = getAuthToken(account, mAuthTokenType,
|
mFuture = getAuthToken(account, mAuthTokenType,
|
||||||
mLoginOptions, mActivity, mMyCallback,
|
mLoginOptions, mActivity, mMyCallback,
|
||||||
mHandler);
|
mHandler);
|
||||||
@@ -2358,9 +2355,8 @@ public class AccountManager {
|
|||||||
setException(new AuthenticatorException("account not in result"));
|
setException(new AuthenticatorException("account not in result"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final IAccountAccessTracker tracker = IAccountAccessTracker.Stub.asInterface(
|
final String accessId = result.getString(KEY_ACCOUNT_ACCESS_ID);
|
||||||
result.getBinder(KEY_ACCOUNT_ACCESS_TRACKER));
|
final Account account = new Account(accountName, accountType, accessId);
|
||||||
final Account account = new Account(accountName, accountType, tracker);
|
|
||||||
mNumAccounts = 1;
|
mNumAccounts = 1;
|
||||||
getAuthToken(account, mAuthTokenType, null /* options */, mActivity,
|
getAuthToken(account, mAuthTokenType, null /* options */, mActivity,
|
||||||
mMyCallback, mHandler);
|
mMyCallback, mHandler);
|
||||||
|
|||||||
@@ -1,26 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2016 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;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Interface to track which apps accessed an account
|
|
||||||
*
|
|
||||||
* @hide
|
|
||||||
*/
|
|
||||||
oneway interface IAccountAccessTracker {
|
|
||||||
void onAccountAccessed();
|
|
||||||
}
|
|
||||||
@@ -110,4 +110,6 @@ interface IAccountManager {
|
|||||||
/* Crate an intent to request account access for package and a given user id */
|
/* Crate an intent to request account access for package and a given user id */
|
||||||
IntentSender createRequestAccountAccessIntentSenderAsUser(in Account account,
|
IntentSender createRequestAccountAccessIntentSenderAsUser(in Account account,
|
||||||
String packageName, in UserHandle userHandle);
|
String packageName, in UserHandle userHandle);
|
||||||
|
|
||||||
|
void onAccountAccessed(String token);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,7 +26,6 @@ import android.accounts.AccountManagerInternal;
|
|||||||
import android.accounts.AuthenticatorDescription;
|
import android.accounts.AuthenticatorDescription;
|
||||||
import android.accounts.CantAddAccountActivity;
|
import android.accounts.CantAddAccountActivity;
|
||||||
import android.accounts.GrantCredentialsPermissionActivity;
|
import android.accounts.GrantCredentialsPermissionActivity;
|
||||||
import android.accounts.IAccountAccessTracker;
|
|
||||||
import android.accounts.IAccountAuthenticator;
|
import android.accounts.IAccountAuthenticator;
|
||||||
import android.accounts.IAccountAuthenticatorResponse;
|
import android.accounts.IAccountAuthenticatorResponse;
|
||||||
import android.accounts.IAccountManager;
|
import android.accounts.IAccountManager;
|
||||||
@@ -89,7 +88,6 @@ import android.os.UserManager;
|
|||||||
import android.os.storage.StorageManager;
|
import android.os.storage.StorageManager;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.util.PackageUtils;
|
|
||||||
import android.util.Pair;
|
import android.util.Pair;
|
||||||
import android.util.Slog;
|
import android.util.Slog;
|
||||||
import android.util.SparseArray;
|
import android.util.SparseArray;
|
||||||
@@ -128,6 +126,8 @@ import java.util.LinkedHashMap;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.UUID;
|
||||||
import java.util.concurrent.CopyOnWriteArrayList;
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
@@ -692,7 +692,7 @@ public class AccountManagerService
|
|||||||
final Account[] accountsForType = new Account[accountNames.size()];
|
final Account[] accountsForType = new Account[accountNames.size()];
|
||||||
for (int i = 0; i < accountsForType.length; i++) {
|
for (int i = 0; i < accountsForType.length; i++) {
|
||||||
accountsForType[i] = new Account(accountNames.get(i), accountType,
|
accountsForType[i] = new Account(accountNames.get(i), accountType,
|
||||||
new AccountAccessTracker());
|
UUID.randomUUID().toString());
|
||||||
}
|
}
|
||||||
accounts.accountCache.put(accountType, accountsForType);
|
accounts.accountCache.put(accountType, accountsForType);
|
||||||
}
|
}
|
||||||
@@ -1502,8 +1502,8 @@ public class AccountManagerService
|
|||||||
Bundle result = new Bundle();
|
Bundle result = new Bundle();
|
||||||
result.putString(AccountManager.KEY_ACCOUNT_NAME, resultingAccount.name);
|
result.putString(AccountManager.KEY_ACCOUNT_NAME, resultingAccount.name);
|
||||||
result.putString(AccountManager.KEY_ACCOUNT_TYPE, resultingAccount.type);
|
result.putString(AccountManager.KEY_ACCOUNT_TYPE, resultingAccount.type);
|
||||||
result.putBinder(AccountManager.KEY_ACCOUNT_ACCESS_TRACKER,
|
result.putString(AccountManager.KEY_ACCOUNT_ACCESS_ID,
|
||||||
resultingAccount.getAccessTracker().asBinder());
|
resultingAccount.getAccessId());
|
||||||
try {
|
try {
|
||||||
response.onResult(result);
|
response.onResult(result);
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
@@ -4079,6 +4079,30 @@ public class AccountManagerService
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAccountAccessed(String token) throws RemoteException {
|
||||||
|
final int uid = Binder.getCallingUid();
|
||||||
|
if (UserHandle.getAppId(uid) == Process.SYSTEM_UID) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final int userId = UserHandle.getCallingUserId();
|
||||||
|
final long identity = Binder.clearCallingIdentity();
|
||||||
|
try {
|
||||||
|
for (Account account : getAccounts(userId, mContext.getOpPackageName())) {
|
||||||
|
if (Objects.equals(account.getAccessId(), token)) {
|
||||||
|
// An app just accessed the account. At this point it knows about
|
||||||
|
// it and there is not need to hide this account from the app.
|
||||||
|
if (!hasAccountAccess(account, null, uid)) {
|
||||||
|
updateAppPermission(account, AccountManager.ACCOUNT_ACCESS_TOKEN_TYPE,
|
||||||
|
uid, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
Binder.restoreCallingIdentity(identity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private abstract class Session extends IAccountAuthenticatorResponse.Stub
|
private abstract class Session extends IAccountAuthenticatorResponse.Stub
|
||||||
implements IBinder.DeathRecipient, ServiceConnection {
|
implements IBinder.DeathRecipient, ServiceConnection {
|
||||||
IAccountManagerResponse mResponse;
|
IAccountManagerResponse mResponse;
|
||||||
@@ -5714,9 +5738,9 @@ public class AccountManagerService
|
|||||||
if (accountsForType != null) {
|
if (accountsForType != null) {
|
||||||
System.arraycopy(accountsForType, 0, newAccountsForType, 0, oldLength);
|
System.arraycopy(accountsForType, 0, newAccountsForType, 0, oldLength);
|
||||||
}
|
}
|
||||||
IAccountAccessTracker accessTracker = account.getAccessTracker() != null
|
String token = account.getAccessId() != null ? account.getAccessId()
|
||||||
? account.getAccessTracker() : new AccountAccessTracker();
|
: UUID.randomUUID().toString();
|
||||||
newAccountsForType[oldLength] = new Account(account, accessTracker);
|
newAccountsForType[oldLength] = new Account(account, token);
|
||||||
accounts.accountCache.put(account.type, newAccountsForType);
|
accounts.accountCache.put(account.type, newAccountsForType);
|
||||||
return newAccountsForType[oldLength];
|
return newAccountsForType[oldLength];
|
||||||
}
|
}
|
||||||
@@ -5961,33 +5985,6 @@ public class AccountManagerService
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private final class AccountAccessTracker extends IAccountAccessTracker.Stub {
|
|
||||||
@Override
|
|
||||||
public void onAccountAccessed() throws RemoteException {
|
|
||||||
final int uid = Binder.getCallingUid();
|
|
||||||
if (UserHandle.getAppId(uid) == Process.SYSTEM_UID) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
final int userId = UserHandle.getCallingUserId();
|
|
||||||
final long identity = Binder.clearCallingIdentity();
|
|
||||||
try {
|
|
||||||
for (Account account : getAccounts(userId, mContext.getOpPackageName())) {
|
|
||||||
IAccountAccessTracker accountTracker = account.getAccessTracker();
|
|
||||||
if (accountTracker != null && asBinder() == accountTracker.asBinder()) {
|
|
||||||
// An app just accessed the account. At this point it knows about
|
|
||||||
// it and there is not need to hide this account from the app.
|
|
||||||
if (!hasAccountAccess(account, null, uid)) {
|
|
||||||
updateAppPermission(account, AccountManager.ACCOUNT_ACCESS_TOKEN_TYPE,
|
|
||||||
uid, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
Binder.restoreCallingIdentity(identity);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private final class AccountManagerInternalImpl extends AccountManagerInternal {
|
private final class AccountManagerInternalImpl extends AccountManagerInternal {
|
||||||
private final Object mLock = new Object();
|
private final Object mLock = new Object();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user