diff options
| author | 2015-09-09 01:51:37 +0000 | |
|---|---|---|
| committer | 2015-09-09 01:51:37 +0000 | |
| commit | db4efcfa8dd996841eb50cf2594bea641b4f217a (patch) | |
| tree | ed31c68d5afb47aec117e18cc6a53a14de514c2f | |
| parent | 6d8bdb50b0cd26629a18ae3124fb29673069493b (diff) | |
| parent | f57d98564b26953b722ab0e14222f50e6515f36d (diff) | |
am f57d9856: am 4f7d0bc7: Merge "Add get_accounts app op" into mnc-dev
* commit 'f57d98564b26953b722ab0e14222f50e6515f36d':
  Add get_accounts app op
6 files changed, 86 insertions, 58 deletions
diff --git a/core/java/android/accounts/AccountManager.java b/core/java/android/accounts/AccountManager.java index 8c84b4d203ee..9ef13de6d444 100644 --- a/core/java/android/accounts/AccountManager.java +++ b/core/java/android/accounts/AccountManager.java @@ -426,7 +426,7 @@ public class AccountManager {      @RequiresPermission(GET_ACCOUNTS)      public Account[] getAccounts() {          try { -            return mService.getAccounts(null); +            return mService.getAccounts(null, mContext.getOpPackageName());          } catch (RemoteException e) {              // won't ever happen              throw new RuntimeException(e); @@ -451,7 +451,7 @@ public class AccountManager {      @RequiresPermission(GET_ACCOUNTS)      public Account[] getAccountsAsUser(int userId) {          try { -            return mService.getAccountsAsUser(null, userId); +            return mService.getAccountsAsUser(null, userId, mContext.getOpPackageName());          } catch (RemoteException e) {              // won't ever happen              throw new RuntimeException(e); @@ -468,7 +468,7 @@ public class AccountManager {       */      public Account[] getAccountsForPackage(String packageName, int uid) {          try { -            return mService.getAccountsForPackage(packageName, uid); +            return mService.getAccountsForPackage(packageName, uid, mContext.getOpPackageName());          } catch (RemoteException re) {              // won't ever happen              throw new RuntimeException(re); @@ -485,7 +485,8 @@ public class AccountManager {       */      public Account[] getAccountsByTypeForPackage(String type, String packageName) {          try { -            return mService.getAccountsByTypeForPackage(type, packageName); +            return mService.getAccountsByTypeForPackage(type, packageName, +                    mContext.getOpPackageName());          } catch (RemoteException re) {              // won't ever happen              throw new RuntimeException(re); @@ -522,7 +523,8 @@ public class AccountManager {      /** @hide Same as {@link #getAccountsByType(String)} but for a specific user. */      public Account[] getAccountsByTypeAsUser(String type, UserHandle userHandle) {          try { -            return mService.getAccountsAsUser(type, userHandle.getIdentifier()); +            return mService.getAccountsAsUser(type, userHandle.getIdentifier(), +                    mContext.getOpPackageName());          } catch (RemoteException e) {              // won't ever happen              throw new RuntimeException(e); @@ -610,7 +612,7 @@ public class AccountManager {          if (features == null) throw new IllegalArgumentException("features is null");          return new Future2Task<Boolean>(handler, callback) {              public void doWork() throws RemoteException { -                mService.hasFeatures(mResponse, account, features); +                mService.hasFeatures(mResponse, account, features, mContext.getOpPackageName());              }              public Boolean bundleToResult(Bundle bundle) throws AuthenticatorException {                  if (!bundle.containsKey(KEY_BOOLEAN_RESULT)) { @@ -662,7 +664,8 @@ public class AccountManager {          if (type == null) throw new IllegalArgumentException("type is null");          return new Future2Task<Account[]>(handler, callback) {              public void doWork() throws RemoteException { -                mService.getAccountsByFeatures(mResponse, type, features); +                mService.getAccountsByFeatures(mResponse, type, features, +                        mContext.getOpPackageName());              }              public Account[] bundleToResult(Bundle bundle) throws AuthenticatorException {                  if (!bundle.containsKey(KEY_ACCOUNTS)) { diff --git a/core/java/android/accounts/IAccountManager.aidl b/core/java/android/accounts/IAccountManager.aidl index 04b3c8864375..4378df408d10 100644 --- a/core/java/android/accounts/IAccountManager.aidl +++ b/core/java/android/accounts/IAccountManager.aidl @@ -30,12 +30,14 @@ interface IAccountManager {      String getPassword(in Account account);      String getUserData(in Account account, String key);      AuthenticatorDescription[] getAuthenticatorTypes(int userId); -    Account[] getAccounts(String accountType); -    Account[] getAccountsForPackage(String packageName, int uid); -    Account[] getAccountsByTypeForPackage(String type, String packageName); -    Account[] getAccountsAsUser(String accountType, int userId); -    void hasFeatures(in IAccountManagerResponse response, in Account account, in String[] features); -    void getAccountsByFeatures(in IAccountManagerResponse response, String accountType, in String[] features); +    Account[] getAccounts(String accountType, String opPackageName); +    Account[] getAccountsForPackage(String packageName, int uid, String opPackageName); +    Account[] getAccountsByTypeForPackage(String type, String packageName, String opPackageName); +    Account[] getAccountsAsUser(String accountType, int userId, String opPackageName); +    void hasFeatures(in IAccountManagerResponse response, in Account account, in String[] features, +        String opPackageName); +    void getAccountsByFeatures(in IAccountManagerResponse response, String accountType, +        in String[] features, String opPackageName);      boolean addAccountExplicitly(in Account account, String password, in Bundle extras);      void removeAccount(in IAccountManagerResponse response, in Account account,          boolean expectActivityLaunch); diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java index 42ac67c7ae44..09c0a6e3ae46 100644 --- a/core/java/android/app/AppOpsManager.java +++ b/core/java/android/app/AppOpsManager.java @@ -235,8 +235,10 @@ public class AppOpsManager {      public static final int OP_WRITE_EXTERNAL_STORAGE = 60;      /** @hide Turned on the screen. */      public static final int OP_TURN_SCREEN_ON = 61; +    /** @hide Get device accounts. */ +    public static final int OP_GET_ACCOUNTS = 62;      /** @hide */ -    public static final int _NUM_OP = 62; +    public static final int _NUM_OP = 63;      /** Access to coarse location information. */      public static final String OPSTR_COARSE_LOCATION = "android:coarse_location"; @@ -331,6 +333,9 @@ public class AppOpsManager {      /** Required to write/modify/update system settingss. */      public static final String OPSTR_WRITE_SETTINGS              = "android:write_settings"; +    /** @hide Get device accounts. */ +    public static final String OPSTR_GET_ACCOUNTS +            = "android:get_accounts";      /**       * This maps each operation to the operation that serves as the @@ -403,6 +408,7 @@ public class AppOpsManager {              OP_READ_EXTERNAL_STORAGE,              OP_WRITE_EXTERNAL_STORAGE,              OP_TURN_SCREEN_ON, +            OP_GET_ACCOUNTS,      };      /** @@ -472,6 +478,7 @@ public class AppOpsManager {              OPSTR_READ_EXTERNAL_STORAGE,              OPSTR_WRITE_EXTERNAL_STORAGE,              null, +            OPSTR_GET_ACCOUNTS      };      /** @@ -541,6 +548,7 @@ public class AppOpsManager {              "READ_EXTERNAL_STORAGE",              "WRITE_EXTERNAL_STORAGE",              "TURN_ON_SCREEN", +            "GET_ACCOUNTS",      };      /** @@ -610,6 +618,7 @@ public class AppOpsManager {              Manifest.permission.READ_EXTERNAL_STORAGE,              Manifest.permission.WRITE_EXTERNAL_STORAGE,              null, // no permission for turning the screen on +            Manifest.permission.GET_ACCOUNTS      };      /** @@ -680,6 +689,7 @@ public class AppOpsManager {              null, // READ_EXTERNAL_STORAGE              null, // WRITE_EXTERNAL_STORAGE              null, // TURN_ON_SCREEN +            null, // GET_ACCOUNTS      };      /** @@ -749,6 +759,7 @@ public class AppOpsManager {              false, // READ_EXTERNAL_STORAGE              false, // WRITE_EXTERNAL_STORAGE              false, // TURN_ON_SCREEN +            false, // GET_ACCOUNTS      };      /** @@ -817,6 +828,7 @@ public class AppOpsManager {              AppOpsManager.MODE_ALLOWED,              AppOpsManager.MODE_ALLOWED,              AppOpsManager.MODE_ALLOWED,  // OP_TURN_ON_SCREEN +            AppOpsManager.MODE_ALLOWED,      };      /** @@ -889,6 +901,7 @@ public class AppOpsManager {              false,              false,              false, +            false      };      /** diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java index 8b0e6f2c3fa4..d590d7aaf3dd 100644 --- a/services/core/java/com/android/server/accounts/AccountManagerService.java +++ b/services/core/java/com/android/server/accounts/AccountManagerService.java @@ -32,6 +32,7 @@ import android.accounts.IAccountManagerResponse;  import android.app.ActivityManager;  import android.app.ActivityManagerNative;  import android.app.AppGlobals; +import android.app.AppOpsManager;  import android.app.Notification;  import android.app.NotificationManager;  import android.app.PendingIntent; @@ -122,6 +123,7 @@ public class AccountManagerService      private final Context mContext;      private final PackageManager mPackageManager; +    private final AppOpsManager mAppOpsManager;      private UserManager mUserManager;      private final MessageHandler mMessageHandler; @@ -266,6 +268,7 @@ public class AccountManagerService              IAccountAuthenticatorCache authenticatorCache) {          mContext = context;          mPackageManager = packageManager; +        mAppOpsManager = mContext.getSystemService(AppOpsManager.class);          mMessageHandler = new MessageHandler(FgThread.get().getLooper()); @@ -510,7 +513,7 @@ public class AccountManagerService          // Check if there's a shared account that needs to be created as an account          Account[] sharedAccounts = getSharedAccountsAsUser(userId);          if (sharedAccounts == null || sharedAccounts.length == 0) return; -        Account[] accounts = getAccountsAsUser(null, userId); +        Account[] accounts = getAccountsAsUser(null, userId, mContext.getOpPackageName());          for (Account sa : sharedAccounts) {              if (ArrayUtils.contains(accounts, sa)) continue;              // Account doesn't exist. Copy it now. @@ -868,7 +871,8 @@ public class AccountManagerService                      // Confirm that the owner's account still exists before this step.                      UserAccounts owner = getUserAccounts(UserHandle.USER_OWNER);                      synchronized (owner.cacheLock) { -                        for (Account acc : getAccounts(UserHandle.USER_OWNER)) { +                        for (Account acc : getAccounts(UserHandle.USER_OWNER, +                                mContext.getOpPackageName())) {                              if (acc.equals(account)) {                                  mAuthenticator.addAccountFromCredentials(                                          this, account, accountCredentials); @@ -988,7 +992,7 @@ public class AccountManagerService      @Override      public void hasFeatures(IAccountManagerResponse response, -            Account account, String[] features) { +            Account account, String[] features, String opPackageName) {          int callingUid = Binder.getCallingUid();          if (Log.isLoggable(TAG, Log.VERBOSE)) {              Log.v(TAG, "hasFeatures: " + account @@ -1001,7 +1005,8 @@ public class AccountManagerService          if (account == null) throw new IllegalArgumentException("account is null");          if (features == null) throw new IllegalArgumentException("features is null");          int userId = UserHandle.getCallingUserId(); -        checkReadAccountsPermitted(callingUid, account.type, userId); +        checkReadAccountsPermitted(callingUid, account.type, userId, +                opPackageName);          long identityToken = clearCallingIdentity();          try { @@ -2507,9 +2512,10 @@ public class AccountManagerService       * Returns the accounts visible to the client within the context of a specific user       * @hide       */ -    public Account[] getAccounts(int userId) { +    public Account[] getAccounts(int userId, String opPackageName) {          int callingUid = Binder.getCallingUid(); -        List<String> visibleAccountTypes = getTypesVisibleToCaller(callingUid, userId); +        List<String> visibleAccountTypes = getTypesVisibleToCaller(callingUid, userId, +                opPackageName);          if (visibleAccountTypes.isEmpty()) {              return new Account[0];          } @@ -2571,15 +2577,16 @@ public class AccountManagerService      }      @Override -    public Account[] getAccountsAsUser(String type, int userId) { -        return getAccountsAsUser(type, userId, null, -1); +    public Account[] getAccountsAsUser(String type, int userId, String opPackageName) { +        return getAccountsAsUser(type, userId, null, -1, opPackageName);      }      private Account[] getAccountsAsUser(              String type,              int userId,              String callingPackage, -            int packageUid) { +            int packageUid, +            String opPackageName) {          int callingUid = Binder.getCallingUid();          // Only allow the system process to read accounts of other users          if (userId != UserHandle.getCallingUserId() @@ -2602,7 +2609,8 @@ public class AccountManagerService              callingUid = packageUid;          } -        List<String> visibleAccountTypes = getTypesVisibleToCaller(callingUid, userId); +        List<String> visibleAccountTypes = getTypesVisibleToCaller(callingUid, userId, +                opPackageName);          if (visibleAccountTypes.isEmpty()                  || (type != null && !visibleAccountTypes.contains(type))) {              return new Account[0]; @@ -2741,22 +2749,24 @@ public class AccountManagerService      }      @Override -    public Account[] getAccounts(String type) { -        return getAccountsAsUser(type, UserHandle.getCallingUserId()); +    public Account[] getAccounts(String type, String opPackageName) { +        return getAccountsAsUser(type, UserHandle.getCallingUserId(), opPackageName);      }      @Override -    public Account[] getAccountsForPackage(String packageName, int uid) { +    public Account[] getAccountsForPackage(String packageName, int uid, String opPackageName) {          int callingUid = Binder.getCallingUid();          if (!UserHandle.isSameApp(callingUid, Process.myUid())) {              throw new SecurityException("getAccountsForPackage() called from unauthorized uid "                      + callingUid + " with uid=" + uid);          } -        return getAccountsAsUser(null, UserHandle.getCallingUserId(), packageName, uid); +        return getAccountsAsUser(null, UserHandle.getCallingUserId(), packageName, uid, +                opPackageName);      }      @Override -    public Account[] getAccountsByTypeForPackage(String type, String packageName) { +    public Account[] getAccountsByTypeForPackage(String type, String packageName, +            String opPackageName) {          int packageUid = -1;          try {              packageUid = AppGlobals.getPackageManager().getPackageUid( @@ -2765,14 +2775,16 @@ public class AccountManagerService              Slog.e(TAG, "Couldn't determine the packageUid for " + packageName + re);              return new Account[0];          } -        return getAccountsAsUser(type, UserHandle.getCallingUserId(), packageName, packageUid); +        return getAccountsAsUser(type, UserHandle.getCallingUserId(), packageName, +                packageUid, opPackageName);      }      @Override      public void getAccountsByFeatures(              IAccountManagerResponse response,              String type, -            String[] features) { +            String[] features, +            String opPackageName) {          int callingUid = Binder.getCallingUid();          if (Log.isLoggable(TAG, Log.VERBOSE)) {              Log.v(TAG, "getAccounts: accountType " + type @@ -2785,7 +2797,8 @@ public class AccountManagerService          if (type == null) throw new IllegalArgumentException("accountType is null");          int userId = UserHandle.getCallingUserId(); -        List<String> visibleAccountTypes = getTypesVisibleToCaller(callingUid, userId); +        List<String> visibleAccountTypes = getTypesVisibleToCaller(callingUid, userId, +                opPackageName);          if (!visibleAccountTypes.contains(type)) {              Bundle result = new Bundle();              // Need to return just the accounts that are from matching signatures. @@ -3685,31 +3698,22 @@ public class AccountManagerService          }      } -    private boolean isPermitted(int callingUid, String... permissions) { +    private boolean isPermitted(String opPackageName, int callingUid, String... permissions) {          for (String perm : permissions) {              if (mContext.checkCallingOrSelfPermission(perm) == PackageManager.PERMISSION_GRANTED) {                  if (Log.isLoggable(TAG, Log.VERBOSE)) {                      Log.v(TAG, "  caller uid " + callingUid + " has " + perm);                  } -                return true; +                final int opCode = AppOpsManager.permissionToOpCode(perm); +                if (opCode == AppOpsManager.OP_NONE || mAppOpsManager.noteOp( +                        opCode, callingUid, opPackageName) == AppOpsManager.MODE_ALLOWED) { +                    return true; +                }              }          }          return false;      } -    /** Succeeds if any of the specified permissions are granted. */ -    private void checkBinderPermission(String... permissions) { -        final int callingUid = Binder.getCallingUid(); -        if (isPermitted(callingUid, permissions)) { -            String msg = String.format( -                    "caller uid %s  lacks any of %s", -                    callingUid, -                    TextUtils.join(",", permissions)); -            Log.w(TAG, "  " + msg); -            throw new SecurityException(msg); -        } -    } -      private int handleIncomingUser(int userId) {          try {              return ActivityManagerNative.getDefault().handleIncomingUser( @@ -3763,11 +3767,13 @@ public class AccountManagerService          return fromAuthenticator || hasExplicitGrants || isPrivileged;      } -    private boolean isAccountVisibleToCaller(String accountType, int callingUid, int userId) { +    private boolean isAccountVisibleToCaller(String accountType, int callingUid, int userId, +            String opPackageName) {          if (accountType == null) {              return false;          } else { -            return getTypesVisibleToCaller(callingUid, userId).contains(accountType); +            return getTypesVisibleToCaller(callingUid, userId, +                    opPackageName).contains(accountType);          }      } @@ -3779,9 +3785,10 @@ public class AccountManagerService          }      } -    private List<String> getTypesVisibleToCaller(int callingUid, int userId) { +    private List<String> getTypesVisibleToCaller(int callingUid, int userId, +            String opPackageName) {          boolean isPermitted = -                isPermitted(callingUid, Manifest.permission.GET_ACCOUNTS, +                isPermitted(opPackageName, callingUid, Manifest.permission.GET_ACCOUNTS,                          Manifest.permission.GET_ACCOUNTS_PRIVILEGED);          Log.i(TAG, String.format("getTypesVisibleToCaller: isPermitted? %s", isPermitted));          return getTypesForCaller(callingUid, userId, isPermitted); @@ -3877,8 +3884,9 @@ public class AccountManagerService      private void checkReadAccountsPermitted(              int callingUid,              String accountType, -            int userId) { -        if (!isAccountVisibleToCaller(accountType, callingUid, userId)) { +            int userId, +            String opPackageName) { +        if (!isAccountVisibleToCaller(accountType, callingUid, userId, opPackageName)) {              String msg = String.format(                      "caller uid %s cannot access %s accounts",                      callingUid, diff --git a/services/core/java/com/android/server/content/SyncManager.java b/services/core/java/com/android/server/content/SyncManager.java index c998c2c28aac..334bc18b82f2 100644 --- a/services/core/java/com/android/server/content/SyncManager.java +++ b/services/core/java/com/android/server/content/SyncManager.java @@ -340,7 +340,8 @@ public class SyncManager {          for (UserInfo user : mUserManager.getUsers(true)) {              // Skip any partially created/removed users              if (user.partial) continue; -            Account[] accountsForUser = AccountManagerService.getSingleton().getAccounts(user.id); +            Account[] accountsForUser = AccountManagerService.getSingleton().getAccounts( +                    user.id, mContext.getOpPackageName());              mSyncStorageEngine.doDatabaseCleanup(accountsForUser, user.id);          }      } @@ -1232,7 +1233,8 @@ public class SyncManager {          }          // Schedule sync for any accounts under started user -        final Account[] accounts = AccountManagerService.getSingleton().getAccounts(userId); +        final Account[] accounts = AccountManagerService.getSingleton().getAccounts(userId, +                mContext.getOpPackageName());          for (Account account : accounts) {              scheduleSync(account, userId, SyncOperation.REASON_USER_START, null, null,                      0 /* no delay */, 0 /* No flex */, diff --git a/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java index 0f20dde23c0c..f9aa124e2bc4 100644 --- a/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java @@ -82,7 +82,7 @@ public class AccountManagerServiceTest extends AndroidTestCase {          mAms.addAccountExplicitly(a31, "p31", null);          mAms.addAccountExplicitly(a32, "p32", null); -        Account[] accounts = mAms.getAccounts(null); +        Account[] accounts = mAms.getAccounts(null, mContext.getOpPackageName());          Arrays.sort(accounts, new AccountSorter());          assertEquals(6, accounts.length);          assertEquals(a11, accounts[0]); @@ -92,7 +92,7 @@ public class AccountManagerServiceTest extends AndroidTestCase {          assertEquals(a22, accounts[4]);          assertEquals(a32, accounts[5]); -        accounts = mAms.getAccounts("type1" ); +        accounts = mAms.getAccounts("type1", mContext.getOpPackageName());          Arrays.sort(accounts, new AccountSorter());          assertEquals(3, accounts.length);          assertEquals(a11, accounts[0]); @@ -101,7 +101,7 @@ public class AccountManagerServiceTest extends AndroidTestCase {          mAms.removeAccountInternal(a21); -        accounts = mAms.getAccounts("type1" ); +        accounts = mAms.getAccounts("type1", mContext.getOpPackageName());          Arrays.sort(accounts, new AccountSorter());          assertEquals(2, accounts.length);          assertEquals(a11, accounts[0]);  |