Merge "Permissions: Get rid of GET_ACCOUNTS" into nyc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
658e4c5ece
@@ -68,7 +68,7 @@ package android {
|
||||
field public static final java.lang.String DUMP = "android.permission.DUMP";
|
||||
field public static final java.lang.String EXPAND_STATUS_BAR = "android.permission.EXPAND_STATUS_BAR";
|
||||
field public static final java.lang.String FACTORY_TEST = "android.permission.FACTORY_TEST";
|
||||
field public static final java.lang.String GET_ACCOUNTS = "android.permission.GET_ACCOUNTS";
|
||||
field public static final deprecated java.lang.String GET_ACCOUNTS = "android.permission.GET_ACCOUNTS";
|
||||
field public static final java.lang.String GET_ACCOUNTS_PRIVILEGED = "android.permission.GET_ACCOUNTS_PRIVILEGED";
|
||||
field public static final java.lang.String GET_PACKAGE_SIZE = "android.permission.GET_PACKAGE_SIZE";
|
||||
field public static final deprecated java.lang.String GET_TASKS = "android.permission.GET_TASKS";
|
||||
|
||||
@@ -97,7 +97,7 @@ package android {
|
||||
field public static final java.lang.String FACTORY_TEST = "android.permission.FACTORY_TEST";
|
||||
field public static final java.lang.String FORCE_BACK = "android.permission.FORCE_BACK";
|
||||
field public static final java.lang.String FORCE_STOP_PACKAGES = "android.permission.FORCE_STOP_PACKAGES";
|
||||
field public static final java.lang.String GET_ACCOUNTS = "android.permission.GET_ACCOUNTS";
|
||||
field public static final deprecated java.lang.String GET_ACCOUNTS = "android.permission.GET_ACCOUNTS";
|
||||
field public static final java.lang.String GET_ACCOUNTS_PRIVILEGED = "android.permission.GET_ACCOUNTS_PRIVILEGED";
|
||||
field public static final java.lang.String GET_APP_OPS_STATS = "android.permission.GET_APP_OPS_STATS";
|
||||
field public static final java.lang.String GET_PACKAGE_IMPORTANCE = "android.permission.GET_PACKAGE_IMPORTANCE";
|
||||
|
||||
@@ -68,7 +68,7 @@ package android {
|
||||
field public static final java.lang.String DUMP = "android.permission.DUMP";
|
||||
field public static final java.lang.String EXPAND_STATUS_BAR = "android.permission.EXPAND_STATUS_BAR";
|
||||
field public static final java.lang.String FACTORY_TEST = "android.permission.FACTORY_TEST";
|
||||
field public static final java.lang.String GET_ACCOUNTS = "android.permission.GET_ACCOUNTS";
|
||||
field public static final deprecated java.lang.String GET_ACCOUNTS = "android.permission.GET_ACCOUNTS";
|
||||
field public static final java.lang.String GET_ACCOUNTS_PRIVILEGED = "android.permission.GET_ACCOUNTS_PRIVILEGED";
|
||||
field public static final java.lang.String GET_PACKAGE_SIZE = "android.permission.GET_PACKAGE_SIZE";
|
||||
field public static final deprecated java.lang.String GET_TASKS = "android.permission.GET_TASKS";
|
||||
|
||||
@@ -426,46 +426,46 @@ public class AccountManager {
|
||||
}
|
||||
|
||||
/**
|
||||
* Lists all accounts of any type registered on the device.
|
||||
* Equivalent to getAccountsByType(null).
|
||||
* List every {@link Account} registered on the device that are managed by
|
||||
* applications whose signatures match the caller.
|
||||
*
|
||||
* <p>It is safe to call this method from the main thread.
|
||||
* <p>This method can be called safely from the main thread. It is
|
||||
* equivalent to calling <code>getAccountsByType(null)</code>.
|
||||
*
|
||||
* <p>Clients of this method that have not been granted the
|
||||
* {@link android.Manifest.permission#GET_ACCOUNTS} permission,
|
||||
* will only see those accounts managed by AbstractAccountAuthenticators whose
|
||||
* signature matches the client.
|
||||
* <p><b>NOTE:</b> Apps declaring a {@code targetSdkVersion<=23} in their
|
||||
* manifests will continue to behave as they did on devices that support
|
||||
* API level 23. In particular the GET_ACCOUNTS permission is required to
|
||||
* see all the Accounts registered with the AccountManager. See docs for
|
||||
* this function in API level 23 for more information.
|
||||
*
|
||||
* @return An array of {@link Account}, one for each account. Empty
|
||||
* (never null) if no accounts have been added.
|
||||
* @return Array of Accounts. The array may be empty if no accounts are
|
||||
* available to the caller.
|
||||
*/
|
||||
@NonNull
|
||||
@RequiresPermission(GET_ACCOUNTS)
|
||||
public Account[] getAccounts() {
|
||||
try {
|
||||
return mService.getAccounts(null, mContext.getOpPackageName());
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
return getAccountsByType(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
* Lists all accounts of any type registered on the device for a given
|
||||
* user id. Equivalent to getAccountsByType(null).
|
||||
* List every {@link Account} registered on the device for a specific User
|
||||
* that are managed by applications whose signatures match the caller.
|
||||
*
|
||||
* <p>It is safe to call this method from the main thread.
|
||||
* <p><b>NOTE:</b> Apps declaring a {@code targetSdkVersion<=23} in their
|
||||
* manifests will continue to behave as they did on devices that support
|
||||
* API level 23. In particular the GET_ACCOUNTS permission is required to
|
||||
* see all the Accounts registered with the AccountManager for the
|
||||
* specified userId. See docs for this function in API level 23 for more
|
||||
* information.
|
||||
*
|
||||
* <p>Clients of this method that have not been granted the
|
||||
* {@link android.Manifest.permission#GET_ACCOUNTS} permission,
|
||||
* will only see those accounts managed by AbstractAccountAuthenticators whose
|
||||
* signature matches the client.
|
||||
* <p>This method can be called safely from the main thread.
|
||||
*
|
||||
* @return An array of {@link Account}, one for each account. Empty
|
||||
* (never null) if no accounts have been added.
|
||||
* @param int userId associated with the User whose accounts should be
|
||||
* queried.
|
||||
* @return Array of Accounts. The array may be empty if no accounts are
|
||||
* available to the caller.
|
||||
*/
|
||||
@NonNull
|
||||
@RequiresPermission(GET_ACCOUNTS)
|
||||
public Account[] getAccountsAsUser(int userId) {
|
||||
try {
|
||||
return mService.getAccountsAsUser(null, userId, mContext.getOpPackageName());
|
||||
@@ -494,10 +494,11 @@ public class AccountManager {
|
||||
/**
|
||||
* Returns the accounts visible to the specified package, in an environment where some apps
|
||||
* are not authorized to view all accounts. This method can only be called by system apps.
|
||||
*
|
||||
* @param type The type of accounts to return, null to retrieve all accounts
|
||||
* @param packageName The package name of the app for which the accounts are to be returned
|
||||
* @return An array of {@link Account}, one per matching account. Empty
|
||||
* (never null) if no accounts of the specified type have been added.
|
||||
* @return Array of Accounts. The array may be empty if no accounts of th
|
||||
* specified type are visible to the caller.
|
||||
*/
|
||||
@NonNull
|
||||
public Account[] getAccountsByTypeForPackage(String type, String packageName) {
|
||||
@@ -510,29 +511,22 @@ public class AccountManager {
|
||||
}
|
||||
|
||||
/**
|
||||
* Lists all accounts of a particular type. The account type is a
|
||||
* string token corresponding to the authenticator and useful domain
|
||||
* of the account. For example, there are types corresponding to Google
|
||||
* and Facebook. The exact string token to use will be published somewhere
|
||||
* associated with the authenticator in question.
|
||||
* List every {@link Account} of a specified type managed by applications
|
||||
* whose signatures match the caller.
|
||||
*
|
||||
* <p>It is safe to call this method from the main thread.
|
||||
* <p><b>NOTE:</b> Apps declaring a {@code targetSdkVersion<=23} in their
|
||||
* manifests will continue to behave as they did on devices that support
|
||||
* API level 23. See docs for this function in API level 23 for more
|
||||
* information.
|
||||
*
|
||||
* <p>Clients of this method that have not been granted the
|
||||
* {@link android.Manifest.permission#GET_ACCOUNTS} permission,
|
||||
* will only see those accounts managed by AbstractAccountAuthenticators whose
|
||||
* signature matches the client.
|
||||
* <p>This method can be called safely from the main thread.
|
||||
*
|
||||
* <p><b>NOTE:</b> If targeting your app to work on API level 22 and before,
|
||||
* GET_ACCOUNTS permission is needed for those platforms, irrespective of uid
|
||||
* or signature match. See docs for this function in API level 22.
|
||||
*
|
||||
* @param type The type of accounts to return, null to retrieve all accounts
|
||||
* @return An array of {@link Account}, one per matching account. Empty
|
||||
* (never null) if no accounts of the specified type have been added.
|
||||
* @param type String denoting the type of the accounts to return,
|
||||
* {@code null} to retrieve all accounts visible to the caller.
|
||||
* @return An array of Accounts. Empty (never null) if no accounts
|
||||
* are available to the caller.
|
||||
*/
|
||||
@NonNull
|
||||
@RequiresPermission(GET_ACCOUNTS)
|
||||
public Account[] getAccountsByType(String type) {
|
||||
return getAccountsByTypeAsUser(type, Process.myUserHandle());
|
||||
}
|
||||
@@ -576,6 +570,7 @@ public class AccountManager {
|
||||
* @return a future containing the label string
|
||||
* @hide
|
||||
*/
|
||||
@NonNull
|
||||
public AccountManagerFuture<String> getAuthTokenLabel(
|
||||
final String accountType, final String authTokenType,
|
||||
AccountManagerCallback<String> callback, Handler handler) {
|
||||
@@ -608,9 +603,13 @@ public class AccountManager {
|
||||
* <p>This method may be called from any thread, but the returned
|
||||
* {@link AccountManagerFuture} must not be used on the main thread.
|
||||
*
|
||||
* <p>This method requires the caller to hold the permission
|
||||
* {@link android.Manifest.permission#GET_ACCOUNTS} or be a signature
|
||||
* match with the AbstractAccountAuthenticator that manages the account.
|
||||
* <p><b>Note:</b>The specified account must be managed by an application
|
||||
* whose signature matches the caller.
|
||||
*
|
||||
* <p><b>Further note:</b>Apps targeting API level 23 or earlier will continue to
|
||||
* behave as they did on devices that support API level 23. In particular
|
||||
* they may still require the GET_ACCOUNTS permission. See docs for this
|
||||
* function in API level 23.
|
||||
*
|
||||
* @param account The {@link Account} to test
|
||||
* @param features An array of the account features to check
|
||||
@@ -619,9 +618,11 @@ public class AccountManager {
|
||||
* @param handler {@link Handler} identifying the callback thread,
|
||||
* null for the main thread
|
||||
* @return An {@link AccountManagerFuture} which resolves to a Boolean,
|
||||
* true if the account exists and has all of the specified features.
|
||||
* true if the account exists and has all of the specified features.
|
||||
* @throws SecurityException if the specified account is managed by an
|
||||
* application whose signature doesn't match the caller's signature.
|
||||
*/
|
||||
@RequiresPermission(GET_ACCOUNTS)
|
||||
@NonNull
|
||||
public AccountManagerFuture<Boolean> hasFeatures(final Account account,
|
||||
final String[] features,
|
||||
AccountManagerCallback<Boolean> callback, Handler handler) {
|
||||
@@ -644,9 +645,10 @@ public class AccountManager {
|
||||
|
||||
/**
|
||||
* Lists all accounts of a type which have certain features. The account
|
||||
* type identifies the authenticator (see {@link #getAccountsByType}).
|
||||
* Account features are authenticator-specific string tokens identifying
|
||||
* boolean account properties (see {@link #hasFeatures}).
|
||||
* type identifies the authenticator (see {@link #getAccountsByType}). Said
|
||||
* authenticator must be in a package whose signature matches the callers
|
||||
* package signature. Account features are authenticator-specific string tokens
|
||||
* identifying boolean account properties (see {@link #hasFeatures}).
|
||||
*
|
||||
* <p>Unlike {@link #getAccountsByType}, this method calls the authenticator,
|
||||
* which may contact the server or do other work to check account features,
|
||||
@@ -655,19 +657,14 @@ public class AccountManager {
|
||||
* <p>This method may be called from any thread, but the returned
|
||||
* {@link AccountManagerFuture} must not be used on the main thread.
|
||||
*
|
||||
* <p>Clients of this method that have not been granted the
|
||||
* {@link android.Manifest.permission#GET_ACCOUNTS} permission,
|
||||
* will only see those accounts managed by AbstractAccountAuthenticators whose
|
||||
* signature matches the client.
|
||||
* <p><b>NOTE:</b> Apps targeting API level 23 or earlier will continue to
|
||||
* behave as they did on devices that support API level 23. In particular
|
||||
* they may still require the GET_ACCOUNTS permission. See docs for this
|
||||
* function in API level 23.
|
||||
*
|
||||
* @param type The type of accounts to return, must not be null
|
||||
* @param features An array of the account features to require,
|
||||
* may be null or empty
|
||||
*
|
||||
* <p><b>NOTE:</b> If targeting your app to work on API level 22 and before,
|
||||
* GET_ACCOUNTS permission is needed for those platforms, irrespective of uid
|
||||
* or signature match. See docs for this function in API level 22.
|
||||
*
|
||||
* @param callback Callback to invoke when the request completes,
|
||||
* null for no callback
|
||||
* @param handler {@link Handler} identifying the callback thread,
|
||||
@@ -676,7 +673,7 @@ public class AccountManager {
|
||||
* {@link Account}, one per account of the specified type which
|
||||
* matches the requested features.
|
||||
*/
|
||||
@RequiresPermission(GET_ACCOUNTS)
|
||||
@NonNull
|
||||
public AccountManagerFuture<Account[]> getAccountsByTypeAndFeatures(
|
||||
final String type, final String[] features,
|
||||
AccountManagerCallback<Account[]> callback, Handler handler) {
|
||||
|
||||
@@ -1240,7 +1240,8 @@
|
||||
<eat-comment />
|
||||
|
||||
<!-- Allows access to the list of accounts in the Accounts Service.
|
||||
<p>Protection level: normal
|
||||
<p>Protection level: dangerous
|
||||
@deprecated Not operative for apps apps with targetSdkVersion >= 24.
|
||||
-->
|
||||
<permission android:name="android.permission.GET_ACCOUNTS"
|
||||
android:permissionGroup="android.permission-group.CONTACTS"
|
||||
|
||||
@@ -160,20 +160,21 @@ page.image=images/cards/card-support_16-9_2x.png
|
||||
still perform BTLE and WiFi scans, but only when they are in the foreground. While in the background, those apps will get no results from BTLE and WiFi scans.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>Permission changes
|
||||
<li>Accessing accounts
|
||||
<ul>
|
||||
<li>Updated the user interface for permissions and enhanced some of the permissions
|
||||
behaviors.</li>
|
||||
<li>The {@link android.Manifest.permission#GET_ACCOUNTS} permission is now a member of the
|
||||
{@link android.Manifest.permission_group#CONTACTS} permission group and it has a
|
||||
{@code android:protectionLevel} of {@code dangerous}. This change means that when
|
||||
targeting Android 6.0 (API level 23), you must check for and request this permission if
|
||||
your app requires it.
|
||||
<li>Updated the behavior of {@link android.accounts.AccountManager} account
|
||||
discovery methods.
|
||||
</li>
|
||||
|
||||
<li>The {@code android.permission.READ_PROFILE} and {@code android.permission.WRITE_PROFILE}
|
||||
permissions have been removed from the {@link android.Manifest.permission_group#CONTACTS}
|
||||
permission group.
|
||||
<li>The GET_ACCOUNTS permission has been deprecated.
|
||||
</li>
|
||||
<li>Apps targeting API level 24 should start the intent returned by
|
||||
newChooseAccountIntent(...) and await the result to acquire a reference
|
||||
to the user's selected account. AccountManager methods like getAccounts and
|
||||
related methods will only return those accounts managed by
|
||||
authenticators that match the signatures of the calling app.
|
||||
</li>
|
||||
<li>Apps targeting API level 23 or earlier will continue to behave as
|
||||
before.
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
@@ -15,8 +15,7 @@ next.link=authenticate.html
|
||||
<ol>
|
||||
<li><a href="#ForYou">Determine if AccountManager is for You</a></li>
|
||||
<li><a href="#TaskTwo">Decide What Type of Account to Use</a></li>
|
||||
<li><a href="#GetPermission">Request GET_ACCOUNT permission</a></li>
|
||||
<li><a href="#TaskFive">Query AccountManager for a List of Accounts</a></li>
|
||||
<li><a href="#QueryAccounts">Query the user for an Account</a></li>
|
||||
<li><a href="#IdentifyUser">Use the Account Object to Personalize Your App</a></li>
|
||||
<li><a href="#IdIsEnough">Decide Whether an Account Name is Enough</a></li>
|
||||
</ol>
|
||||
@@ -71,48 +70,46 @@ UI.</p>
|
||||
<h2 id="TaskTwo">Decide What Type of Account to Use</h2>
|
||||
|
||||
<p>Android devices can store multiple accounts from many different providers.
|
||||
When you query {@link android.accounts.AccountManager} for account names, you can choose to filter
|
||||
by
|
||||
account type. The account type is a string that uniquely identifies the entity
|
||||
that issued the account. For instance, Google accounts have type "com.google,"
|
||||
while Twitter uses "com.twitter.android.auth.login."</p>
|
||||
When you query {@link android.accounts.AccountManager} for account names, you
|
||||
can choose to filter by account type. The account type is a string that
|
||||
uniquely identifies the entity that issued the account. For instance, Google
|
||||
accounts have type "com.google," while Twitter uses
|
||||
"com.twitter.android.auth.login."</p>
|
||||
|
||||
<h2 id="QueryAccounts">Query the user for an Account</h2>
|
||||
|
||||
<h2 id="GetPermission">Request GET_ACCOUNT permission</h2>
|
||||
|
||||
<p>In order to get a list of accounts on the device, your app needs the {@link
|
||||
android.Manifest.permission#GET_ACCOUNTS}
|
||||
permission. Add a <a href="{@docRoot}guide/topics/manifest/uses-permission-element.html">{@code
|
||||
<uses-permission>}</a> tag in your manifest file to request
|
||||
this permission:</p>
|
||||
<p>Once an account type has been determined, you can prompt the user with an
|
||||
account chooser as follows:
|
||||
|
||||
<pre>
|
||||
<manifest ... >
|
||||
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
|
||||
...
|
||||
</manifest>
|
||||
AccountManager am = AccountManager.get(this); // "this" reference the current Context
|
||||
Intent chooserIntent = am.newChooseAccountIntent(
|
||||
null, // currently select account
|
||||
null, // list of accounts that are allowed to be shown
|
||||
new String[] { "com.google" }, // Only allow the user to select Google accounts
|
||||
false,
|
||||
null, // description text
|
||||
null, // add account auth token type
|
||||
null, // required features for added accounts
|
||||
null); // options for adding an account
|
||||
this.startActivityForResult(chooserIntent, MY_REQUEST_CODE);
|
||||
</pre>
|
||||
|
||||
|
||||
<h2 id="TaskFive">Query AccountManager for a List of Accounts</h2>
|
||||
|
||||
<p>Once you decide what account type you're interested in, you need to query for accounts of that
|
||||
type. Get an instance of {@link android.accounts.AccountManager} by calling {@link
|
||||
android.accounts.AccountManager#get(android.content.Context) AccountManager.get()}. Then use that
|
||||
instance to call {@link android.accounts.AccountManager#getAccountsByType(java.lang.String)
|
||||
getAccountsByType()}.</p>
|
||||
<p>Once the chooser intent is started, the user will be presented with a list of
|
||||
appropriately typed accounts. From this list they will select one which will be
|
||||
returned to your app upon onActivityResult as follows:
|
||||
|
||||
<pre>
|
||||
AccountManager am = AccountManager.get(this); // "this" references the current Context
|
||||
|
||||
Account[] accounts = am.getAccountsByType("com.google");
|
||||
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
if (requestCode == MY_REQUEST_CODE && resultCode == RESULT_OK) {
|
||||
String name = data.getStringExtra(AccountManage.KEY_ACCOUNT_NAME);
|
||||
String type = data.getStringExtra(AccountManage.KEY_ACCOUNT_TYPE);
|
||||
Account selectedAccount = new Account(name, type);
|
||||
doSomethingWithSelectedAccount(selectedAccount);
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
|
||||
<p>This returns an array of {@link android.accounts.Account} objects. If there's more than one
|
||||
{@link android.accounts.Account} in
|
||||
the array, you should present a dialog asking the user to select one.</p>
|
||||
|
||||
|
||||
<h2 id="IdentifyUser">Use the Account Object to Personalize Your App</h2>
|
||||
|
||||
<p>The {@link android.accounts.Account} object contains an account name, which for Google accounts
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
<uses-sdk android:minSdkVersion="10" android:targetSdkVersion="17"/>
|
||||
<uses-permission android:name="android.permission.VIBRATE" />
|
||||
<uses-permission android:name="android.permission.MODIFY_PHONE_STATE" />
|
||||
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
|
||||
<uses-permission android:name="android.permission.GET_ACCOUNTS_PRIVILEDGED" />
|
||||
<uses-permission android:name="android.permission.MANAGE_ACCOUNTS" />
|
||||
<uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL" />
|
||||
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
||||
|
||||
@@ -93,7 +93,7 @@
|
||||
<uses-permission android:name="android.permission.MANAGE_USERS" />
|
||||
<uses-permission android:name="android.permission.MANAGE_DEVICE_ADMINS" />
|
||||
<uses-permission android:name="android.permission.BLUETOOTH_STACK" />
|
||||
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
|
||||
<uses-permission android:name="android.permission.GET_ACCOUNTS_PRIVILEDGED" />
|
||||
<uses-permission android:name="android.permission.RETRIEVE_WINDOW_TOKEN" />
|
||||
<uses-permission android:name="android.permission.FRAME_STATS" />
|
||||
<uses-permission android:name="android.permission.BIND_APPWIDGET" />
|
||||
|
||||
@@ -103,7 +103,7 @@
|
||||
<!-- Keyguard -->
|
||||
<uses-permission android:name="android.permission.CONTROL_KEYGUARD" />
|
||||
<uses-permission android:name="android.permission.MODIFY_PHONE_STATE" />
|
||||
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
|
||||
<uses-permission android:name="android.permission.GET_ACCOUNTS_PRIVILEDGED" />
|
||||
<uses-permission android:name="android.permission.MANAGE_ACCOUNTS" />
|
||||
<uses-permission android:name="android.permission.BIND_DEVICE_ADMIN" />
|
||||
<uses-permission android:name="android.permission.CHANGE_COMPONENT_ENABLED_STATE" />
|
||||
|
||||
@@ -1327,8 +1327,9 @@ public class AccountManagerService
|
||||
* arbitrary applications (like competing authenticators).
|
||||
*/
|
||||
UserHandle user = new UserHandle(userId);
|
||||
if (!isAccountManagedByCaller(account.type, callingUid, user.getIdentifier())
|
||||
&& !isSystemUid(callingUid)) {
|
||||
|
||||
if (!isSystemUid(callingUid)
|
||||
&& !isAccountManagedByCaller(account.type, callingUid, user.getIdentifier())) {
|
||||
String msg = String.format(
|
||||
"uid %s cannot remove accounts of type: %s",
|
||||
callingUid,
|
||||
@@ -4356,21 +4357,6 @@ public class AccountManagerService
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
final int opCode = AppOpsManager.permissionToOpCode(perm);
|
||||
if (opCode == AppOpsManager.OP_NONE || mAppOpsManager.noteOp(
|
||||
opCode, callingUid, opPackageName) == AppOpsManager.MODE_ALLOWED) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private int handleIncomingUser(int userId) {
|
||||
try {
|
||||
@@ -4445,12 +4431,53 @@ public class AccountManagerService
|
||||
|
||||
private List<String> getTypesVisibleToCaller(int callingUid, int userId,
|
||||
String opPackageName) {
|
||||
boolean isPermitted =
|
||||
isPermitted(opPackageName, callingUid, Manifest.permission.GET_ACCOUNTS,
|
||||
Manifest.permission.GET_ACCOUNTS_PRIVILEGED);
|
||||
List<String> permissionsToCheck = new ArrayList<String>(2);
|
||||
permissionsToCheck.add(Manifest.permission.GET_ACCOUNTS_PRIVILEGED);
|
||||
long id = Binder.clearCallingIdentity();
|
||||
try {
|
||||
ApplicationInfo appInfo = mPackageManager.getApplicationInfo(
|
||||
opPackageName, 0 /* flags */);
|
||||
/*
|
||||
* At or before SDK 23, clients discover all the accounts in their
|
||||
* user profile (via AccountManager.getAccounts(...)) by declaring
|
||||
* the GET_ACCOUNTS permission.
|
||||
*
|
||||
* After SDK 23 the GET_ACCOUNTS permission is deprecated. Instead
|
||||
* apps will be able to retrieve those accounts managed by
|
||||
* authenticators sharing a package signature without any special
|
||||
* permissions. The only clients able to discover all the accounts
|
||||
* on the device will be those with the GET_ACCOUNTS_PRVILEGED
|
||||
* system permission.
|
||||
*/
|
||||
if (23 >= appInfo.targetSdkVersion) {
|
||||
permissionsToCheck.add(Manifest.permission.GET_ACCOUNTS);
|
||||
}
|
||||
} catch (NameNotFoundException e) {
|
||||
// No application associated with the specified package.
|
||||
Log.w(TAG, "No application associated with package: " + opPackageName);
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(id);
|
||||
}
|
||||
boolean isPermitted = isPermitted(opPackageName, callingUid, permissionsToCheck);
|
||||
return getTypesForCaller(callingUid, userId, isPermitted);
|
||||
}
|
||||
|
||||
private boolean isPermitted(String opPackageName, int callingUid, List<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);
|
||||
}
|
||||
final int opCode = AppOpsManager.permissionToOpCode(perm);
|
||||
if (opCode == AppOpsManager.OP_NONE || mAppOpsManager.noteOp(
|
||||
opCode, callingUid, opPackageName) == AppOpsManager.MODE_ALLOWED) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private List<String> getTypesManagedByCaller(int callingUid, int userId) {
|
||||
return getTypesForCaller(callingUid, userId, false);
|
||||
}
|
||||
@@ -4472,6 +4499,10 @@ public class AccountManagerService
|
||||
managedAccountTypes.add(serviceInfo.type.type);
|
||||
}
|
||||
}
|
||||
if (managedAccountTypes.isEmpty()) {
|
||||
throw new SecurityException("The calling uid " + callingUid +
|
||||
" is not permitted access any types of accounts!");
|
||||
}
|
||||
return managedAccountTypes;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user