am 42bc734b
: Merge "Block access to accounts for limited users." into jb-mr2-dev
* commit '42bc734b302f1fe68c031e013513535bed4c24f1': Block access to accounts for limited users.
This commit is contained in:
@ -16984,6 +16984,7 @@ package android.os {
|
||||
}
|
||||
|
||||
public class UserManager {
|
||||
method public static synchronized android.os.UserManager get(android.content.Context);
|
||||
method public long getSerialNumberForUser(android.os.UserHandle);
|
||||
method public int getUserCount();
|
||||
method public android.os.UserHandle getUserForSerialNumber(long);
|
||||
|
@ -387,6 +387,23 @@ public class AccountManager {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
* For use by internal activities. Returns the list of accounts that the calling package
|
||||
* is authorized to use, particularly for shared accounts.
|
||||
* @param packageName package name of the calling app.
|
||||
* @param uid the uid of the calling app.
|
||||
* @return the accounts that are available to this package and user.
|
||||
*/
|
||||
public Account[] getAccountsForPackage(String packageName, int uid) {
|
||||
try {
|
||||
return mService.getAccountsForPackage(packageName, uid);
|
||||
} catch (RemoteException re) {
|
||||
// possible security exception
|
||||
throw new RuntimeException(re);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Lists all accounts of a particular type. The account type is a
|
||||
* string token corresponding to the authenticator and useful domain
|
||||
@ -575,7 +592,7 @@ public class AccountManager {
|
||||
public boolean addAccountExplicitly(Account account, String password, Bundle userdata) {
|
||||
if (account == null) throw new IllegalArgumentException("account is null");
|
||||
try {
|
||||
return mService.addAccount(account, password, userdata);
|
||||
return mService.addAccountExplicitly(account, password, userdata);
|
||||
} catch (RemoteException e) {
|
||||
// won't ever happen
|
||||
throw new RuntimeException(e);
|
||||
@ -1123,7 +1140,7 @@ public class AccountManager {
|
||||
|
||||
return new AmsTask(activity, handler, callback) {
|
||||
public void doWork() throws RemoteException {
|
||||
mService.addAcount(mResponse, accountType, authTokenType,
|
||||
mService.addAccount(mResponse, accountType, authTokenType,
|
||||
requiredFeatures, activity != null, optionsIn);
|
||||
}
|
||||
}.start();
|
||||
|
@ -18,9 +18,14 @@ package android.accounts;
|
||||
import com.google.android.collect.Sets;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.ActivityManagerNative;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.os.IBinder;
|
||||
import android.os.Parcelable;
|
||||
import android.os.RemoteException;
|
||||
import android.os.UserHandle;
|
||||
import android.os.UserManager;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
@ -29,6 +34,7 @@ import android.widget.ArrayAdapter;
|
||||
import android.widget.Button;
|
||||
import android.widget.ListView;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.android.internal.R;
|
||||
|
||||
@ -119,6 +125,9 @@ public class ChooseTypeAndAccountActivity extends Activity
|
||||
private Parcelable[] mExistingAccounts = null;
|
||||
private int mSelectedItemIndex;
|
||||
private Button mOkButton;
|
||||
private int mCallingUid;
|
||||
private String mCallingPackage;
|
||||
private boolean mDisallowAddAccounts;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
@ -128,6 +137,24 @@ public class ChooseTypeAndAccountActivity extends Activity
|
||||
+ savedInstanceState + ")");
|
||||
}
|
||||
|
||||
String message = null;
|
||||
|
||||
try {
|
||||
IBinder activityToken = getActivityToken();
|
||||
mCallingUid = ActivityManagerNative.getDefault().getLaunchedFromUid(activityToken);
|
||||
mCallingPackage = ActivityManagerNative.getDefault().getLaunchedFromPackage(
|
||||
activityToken);
|
||||
if (mCallingUid != 0 && mCallingPackage != null) {
|
||||
Bundle restrictions = UserManager.get(this)
|
||||
.getUserRestrictions(new UserHandle(UserHandle.getUserId(mCallingUid)));
|
||||
mDisallowAddAccounts =
|
||||
restrictions.getBoolean(UserManager.DISALLOW_MODIFY_ACCOUNTS, false);
|
||||
}
|
||||
} catch (RemoteException re) {
|
||||
// Couldn't figure out caller details
|
||||
Log.w(getClass().getSimpleName(), "Unable to get caller identity \n" + re);
|
||||
}
|
||||
|
||||
// save some items we use frequently
|
||||
final Intent intent = getIntent();
|
||||
|
||||
@ -179,6 +206,11 @@ public class ChooseTypeAndAccountActivity extends Activity
|
||||
// If there are no relevant accounts and only one relevant account type go directly to
|
||||
// add account. Otherwise let the user choose.
|
||||
if (mAccounts.isEmpty()) {
|
||||
if (mDisallowAddAccounts) {
|
||||
setContentView(R.layout.app_not_authorized);
|
||||
setTitle(R.string.error_message_title);
|
||||
return;
|
||||
}
|
||||
if (mSetOfRelevantAccountTypes.size() == 1) {
|
||||
runAddAccountForAuthenticator(mSetOfRelevantAccountTypes.iterator().next());
|
||||
} else {
|
||||
@ -296,7 +328,8 @@ public class ChooseTypeAndAccountActivity extends Activity
|
||||
}
|
||||
|
||||
if (accountName == null || accountType == null) {
|
||||
Account[] currentAccounts = AccountManager.get(this).getAccounts();
|
||||
Account[] currentAccounts = AccountManager.get(this).getAccountsForPackage(
|
||||
mCallingPackage, mCallingUid);
|
||||
Set<Account> preExistingAccounts = new HashSet<Account>();
|
||||
for (Parcelable accountParcel : mExistingAccounts) {
|
||||
preExistingAccounts.add((Account) accountParcel);
|
||||
@ -347,7 +380,8 @@ public class ChooseTypeAndAccountActivity extends Activity
|
||||
AccountManager.KEY_INTENT);
|
||||
if (intent != null) {
|
||||
mPendingRequest = REQUEST_ADD_ACCOUNT;
|
||||
mExistingAccounts = AccountManager.get(this).getAccounts();
|
||||
mExistingAccounts = AccountManager.get(this).getAccountsForPackage(mCallingPackage,
|
||||
mCallingUid);
|
||||
intent.setFlags(intent.getFlags() & ~Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
startActivityForResult(intent, REQUEST_ADD_ACCOUNT);
|
||||
return;
|
||||
@ -424,12 +458,14 @@ public class ChooseTypeAndAccountActivity extends Activity
|
||||
private String[] getListOfDisplayableOptions(ArrayList<Account> accounts) {
|
||||
// List of options includes all accounts found together with "Add new account" as the
|
||||
// last item in the list.
|
||||
String[] listItems = new String[accounts.size() + 1];
|
||||
String[] listItems = new String[accounts.size() + (mDisallowAddAccounts ? 0 : 1)];
|
||||
for (int i = 0; i < accounts.size(); i++) {
|
||||
listItems[i] = accounts.get(i).name;
|
||||
}
|
||||
listItems[accounts.size()] = getResources().getString(
|
||||
R.string.add_account_button_label);
|
||||
if (!mDisallowAddAccounts) {
|
||||
listItems[accounts.size()] = getResources().getString(
|
||||
R.string.add_account_button_label);
|
||||
}
|
||||
return listItems;
|
||||
}
|
||||
|
||||
@ -439,7 +475,8 @@ public class ChooseTypeAndAccountActivity extends Activity
|
||||
* allowable accounts, if provided.
|
||||
*/
|
||||
private ArrayList<Account> getAcceptableAccountChoices(AccountManager accountManager) {
|
||||
final Account[] accounts = accountManager.getAccounts();
|
||||
final Account[] accounts = accountManager.getAccountsForPackage(mCallingPackage,
|
||||
mCallingUid);
|
||||
ArrayList<Account> accountsToPopulate = new ArrayList<Account>(accounts.length);
|
||||
for (Account account : accounts) {
|
||||
if (mSetOfAllowableAccounts != null
|
||||
|
@ -31,10 +31,11 @@ interface IAccountManager {
|
||||
String getUserData(in Account account, String key);
|
||||
AuthenticatorDescription[] getAuthenticatorTypes();
|
||||
Account[] getAccounts(String accountType);
|
||||
Account[] getAccountsForPackage(String packageName, int uid);
|
||||
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);
|
||||
boolean addAccount(in Account account, String password, in Bundle extras);
|
||||
boolean addAccountExplicitly(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);
|
||||
@ -47,7 +48,7 @@ interface IAccountManager {
|
||||
void getAuthToken(in IAccountManagerResponse response, in Account account,
|
||||
String authTokenType, boolean notifyOnAuthFailure, boolean expectActivityLaunch,
|
||||
in Bundle options);
|
||||
void addAcount(in IAccountManagerResponse response, String accountType,
|
||||
void addAccount(in IAccountManagerResponse response, String accountType,
|
||||
String authTokenType, in String[] requiredFeatures, boolean expectActivityLaunch,
|
||||
in Bundle options);
|
||||
void updateCredentials(in IAccountManagerResponse response, in Account account,
|
||||
|
@ -121,6 +121,14 @@ public class UserManager {
|
||||
*/
|
||||
public static final String DISALLOW_USB_FILE_TRANSFER = "no_usb_file_transfer";
|
||||
|
||||
private static UserManager sInstance = null;
|
||||
|
||||
public synchronized static UserManager get(Context context) {
|
||||
if (sInstance == null) {
|
||||
sInstance = (UserManager) context.getSystemService(Context.USER_SERVICE);
|
||||
}
|
||||
return sInstance;
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
public UserManager(Context context, IUserManager service) {
|
||||
|
56
core/res/res/layout/app_not_authorized.xml
Normal file
56
core/res/res/layout/app_not_authorized.xml
Normal file
@ -0,0 +1,56 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
/*
|
||||
**
|
||||
** Copyright 2013, 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.
|
||||
*/
|
||||
-->
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<!-- Customizable description text -->
|
||||
<TextView android:id="@+id/description"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="?android:attr/textAppearanceMedium"
|
||||
android:layout_gravity="start|center_vertical"
|
||||
android:paddingTop="16dip"
|
||||
android:paddingBottom="16dip"
|
||||
android:paddingStart="16dip"
|
||||
android:paddingEnd="16dip"
|
||||
android:text="@string/app_no_restricted_accounts"
|
||||
/>
|
||||
|
||||
<!-- Horizontal divider line -->
|
||||
<View android:layout_height="1dip"
|
||||
android:layout_width="match_parent"
|
||||
android:background="?android:attr/dividerHorizontal" />
|
||||
|
||||
<!-- Alert dialog style buttons along the bottom. -->
|
||||
<LinearLayout android:id="@+id/button_bar"
|
||||
style="?android:attr/buttonBarStyle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:measureWithLargestChild="true">
|
||||
<Button android:id="@android:id/button1"
|
||||
style="?android:attr/buttonBarButtonStyle"
|
||||
android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:text="@android:string/yes"
|
||||
android:onClick="onCancelButtonClicked" />
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
@ -4063,5 +4063,10 @@
|
||||
<string name="user_switched">Current user <xliff:g id="name" example="Bob">%1$s</xliff:g>.</string>
|
||||
<!-- Default name of the owner user [CHAR LIMIT=20] -->
|
||||
<string name="owner_name" msgid="3879126011135546571">Owner</string>
|
||||
|
||||
<!-- Error message title [CHAR LIMIT=35] -->
|
||||
<string name="error_message_title">Error</string>
|
||||
<!-- Message informing user that app is not permitted to access accounts. [CHAR LIMIT=none] -->
|
||||
<string name="app_no_restricted_accounts">This application does not support accounts for limited users</string>
|
||||
<!-- Message informing user that the requested activity could not be found [CHAR LIMIT=none] -->
|
||||
<string name="app_not_found">No application found to handle this action</string>
|
||||
</resources>
|
||||
|
@ -869,7 +869,7 @@
|
||||
<java-symbol type="string" name="config_chooseAccountActivity" />
|
||||
<java-symbol type="string" name="config_chooseTypeAndAccountActivity" />
|
||||
<java-symbol type="string" name="config_appsAuthorizedForSharedAccounts" />
|
||||
|
||||
<java-symbol type="string" name="error_message_title" />
|
||||
|
||||
<java-symbol type="plurals" name="abbrev_in_num_days" />
|
||||
<java-symbol type="plurals" name="abbrev_in_num_hours" />
|
||||
@ -1121,6 +1121,7 @@
|
||||
<java-symbol type="layout" name="sms_short_code_confirmation_dialog" />
|
||||
<java-symbol type="layout" name="keyguard_add_widget" />
|
||||
<java-symbol type="layout" name="action_bar_up_container" />
|
||||
<java-symbol type="layout" name="app_not_authorized" />
|
||||
|
||||
<java-symbol type="anim" name="slide_in_child_bottom" />
|
||||
<java-symbol type="anim" name="slide_in_right" />
|
||||
|
@ -322,7 +322,7 @@ public class SettingsProvider extends ContentProvider {
|
||||
@Override
|
||||
public boolean onCreate() {
|
||||
mBackupManager = new BackupManager(getContext());
|
||||
mUserManager = (UserManager) getContext().getSystemService(Context.USER_SERVICE);
|
||||
mUserManager = UserManager.get(getContext());
|
||||
|
||||
setAppOps(AppOpsManager.OP_NONE, AppOpsManager.OP_WRITE_SETTINGS);
|
||||
establishDbTracking(UserHandle.USER_OWNER);
|
||||
|
@ -206,8 +206,7 @@ class QuickSettings {
|
||||
mUserInfoTask = new AsyncTask<Void, Void, Pair<String, Drawable>>() {
|
||||
@Override
|
||||
protected Pair<String, Drawable> doInBackground(Void... params) {
|
||||
final UserManager um =
|
||||
(UserManager) mContext.getSystemService(Context.USER_SERVICE);
|
||||
final UserManager um = UserManager.get(mContext);
|
||||
|
||||
// Fall back to the UserManager nickname if we can't read the name from the local
|
||||
// profile below.
|
||||
@ -292,8 +291,7 @@ class QuickSettings {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
mBar.collapseAllPanels(true);
|
||||
final UserManager um =
|
||||
(UserManager) mContext.getSystemService(Context.USER_SERVICE);
|
||||
final UserManager um = UserManager.get(mContext);
|
||||
if (um.getUsers(true).size() > 1) {
|
||||
try {
|
||||
WindowManagerGlobal.getWindowManagerService().lockNow(null);
|
||||
|
@ -58,6 +58,7 @@ import android.os.HandlerThread;
|
||||
import android.os.IBinder;
|
||||
import android.os.Looper;
|
||||
import android.os.Message;
|
||||
import android.os.Process;
|
||||
import android.os.RemoteException;
|
||||
import android.os.SystemClock;
|
||||
import android.os.UserHandle;
|
||||
@ -270,7 +271,7 @@ public class AccountManagerService
|
||||
|
||||
private UserManager getUserManager() {
|
||||
if (mUserManager == null) {
|
||||
mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
|
||||
mUserManager = UserManager.get(mContext);
|
||||
}
|
||||
return mUserManager;
|
||||
}
|
||||
@ -542,9 +543,9 @@ public class AccountManagerService
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addAccount(Account account, String password, Bundle extras) {
|
||||
public boolean addAccountExplicitly(Account account, String password, Bundle extras) {
|
||||
if (Log.isLoggable(TAG, Log.VERBOSE)) {
|
||||
Log.v(TAG, "addAccount: " + account
|
||||
Log.v(TAG, "addAccountExplicitly: " + account
|
||||
+ ", caller's uid " + Binder.getCallingUid()
|
||||
+ ", pid " + Binder.getCallingPid());
|
||||
}
|
||||
@ -1167,7 +1168,7 @@ public class AccountManagerService
|
||||
|
||||
final int callingUid = getCallingUid();
|
||||
clearCallingIdentity();
|
||||
if (callingUid != android.os.Process.SYSTEM_UID) {
|
||||
if (callingUid != Process.SYSTEM_UID) {
|
||||
throw new SecurityException("can only call from system");
|
||||
}
|
||||
UserAccounts accounts = getUserAccounts(UserHandle.getUserId(callingUid));
|
||||
@ -1395,7 +1396,7 @@ public class AccountManagerService
|
||||
return id;
|
||||
}
|
||||
|
||||
public void addAcount(final IAccountManagerResponse response, final String accountType,
|
||||
public void addAccount(final IAccountManagerResponse response, final String accountType,
|
||||
final String authTokenType, final String[] requiredFeatures,
|
||||
final boolean expectActivityLaunch, final Bundle optionsIn) {
|
||||
if (Log.isLoggable(TAG, Log.VERBOSE)) {
|
||||
@ -1412,7 +1413,7 @@ public class AccountManagerService
|
||||
checkManageAccountsPermission();
|
||||
|
||||
// Is user disallowed from modifying accounts?
|
||||
if (getUserManager().hasUserRestriction(UserManager.DISALLOW_MODIFY_ACCOUNTS)) {
|
||||
if (!canUserModifyAccounts(Binder.getCallingUid())) {
|
||||
try {
|
||||
response.onError(AccountManager.ERROR_CODE_USER_RESTRICTED,
|
||||
"User is not allowed to add an account!");
|
||||
@ -1457,7 +1458,7 @@ public class AccountManagerService
|
||||
int userId) {
|
||||
// Only allow the system process to read accounts of other users
|
||||
if (userId != UserHandle.getCallingUserId()
|
||||
&& Binder.getCallingUid() != android.os.Process.myUid()) {
|
||||
&& Binder.getCallingUid() != Process.myUid()) {
|
||||
throw new SecurityException("User " + UserHandle.getCallingUserId()
|
||||
+ " trying to confirm account credentials for " + userId);
|
||||
}
|
||||
@ -1573,7 +1574,8 @@ public class AccountManagerService
|
||||
|
||||
public void run() throws RemoteException {
|
||||
synchronized (mAccounts.cacheLock) {
|
||||
mAccountsOfType = getAccountsFromCacheLocked(mAccounts, mAccountType, mCallingUid);
|
||||
mAccountsOfType = getAccountsFromCacheLocked(mAccounts, mAccountType, mCallingUid,
|
||||
null);
|
||||
}
|
||||
// check whether each account matches the requested features
|
||||
mAccountsWithFeatures = new ArrayList<Account>(mAccountsOfType.length);
|
||||
@ -1662,7 +1664,7 @@ public class AccountManagerService
|
||||
long identityToken = clearCallingIdentity();
|
||||
try {
|
||||
synchronized (accounts.cacheLock) {
|
||||
return getAccountsFromCacheLocked(accounts, null, callingUid);
|
||||
return getAccountsFromCacheLocked(accounts, null, callingUid, null);
|
||||
}
|
||||
} finally {
|
||||
restoreCallingIdentity(identityToken);
|
||||
@ -1703,7 +1705,7 @@ public class AccountManagerService
|
||||
if (userAccounts == null) continue;
|
||||
synchronized (userAccounts.cacheLock) {
|
||||
Account[] accounts = getAccountsFromCacheLocked(userAccounts, null,
|
||||
Binder.getCallingUid());
|
||||
Binder.getCallingUid(), null);
|
||||
for (int a = 0; a < accounts.length; a++) {
|
||||
runningAccounts.add(new AccountAndUser(accounts[a], userId));
|
||||
}
|
||||
@ -1717,10 +1719,15 @@ public class AccountManagerService
|
||||
|
||||
@Override
|
||||
public Account[] getAccountsAsUser(String type, int userId) {
|
||||
final int callingUid = Binder.getCallingUid();
|
||||
return getAccountsAsUser(type, userId, null, -1);
|
||||
}
|
||||
|
||||
private Account[] getAccountsAsUser(String type, int userId, String callingPackage,
|
||||
int packageUid) {
|
||||
int callingUid = Binder.getCallingUid();
|
||||
// Only allow the system process to read accounts of other users
|
||||
if (userId != UserHandle.getCallingUserId()
|
||||
&& callingUid != android.os.Process.myUid()) {
|
||||
&& callingUid != Process.myUid()) {
|
||||
throw new SecurityException("User " + UserHandle.getCallingUserId()
|
||||
+ " trying to get account for " + userId);
|
||||
}
|
||||
@ -1730,12 +1737,17 @@ public class AccountManagerService
|
||||
+ ", caller's uid " + Binder.getCallingUid()
|
||||
+ ", pid " + Binder.getCallingPid());
|
||||
}
|
||||
// If the original calling app was using the framework account chooser activity, we'll
|
||||
// be passed in the original caller's uid here, which is what should be used for filtering.
|
||||
if (packageUid != -1 && UserHandle.isSameApp(callingUid, Process.myUid())) {
|
||||
callingUid = packageUid;
|
||||
}
|
||||
checkReadAccountsPermission();
|
||||
UserAccounts accounts = getUserAccounts(userId);
|
||||
long identityToken = clearCallingIdentity();
|
||||
try {
|
||||
synchronized (accounts.cacheLock) {
|
||||
return getAccountsFromCacheLocked(accounts, type, callingUid);
|
||||
return getAccountsFromCacheLocked(accounts, type, callingUid, callingPackage);
|
||||
}
|
||||
} finally {
|
||||
restoreCallingIdentity(identityToken);
|
||||
@ -1806,6 +1818,16 @@ public class AccountManagerService
|
||||
return getAccountsAsUser(type, UserHandle.getCallingUserId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Account[] getAccountsForPackage(String packageName, int uid) {
|
||||
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);
|
||||
}
|
||||
|
||||
public void getAccountsByFeatures(IAccountManagerResponse response,
|
||||
String type, String[] features) {
|
||||
if (Log.isLoggable(TAG, Log.VERBOSE)) {
|
||||
@ -1825,7 +1847,7 @@ public class AccountManagerService
|
||||
if (features == null || features.length == 0) {
|
||||
Account[] accounts;
|
||||
synchronized (userAccounts.cacheLock) {
|
||||
accounts = getAccountsFromCacheLocked(userAccounts, type, callingUid);
|
||||
accounts = getAccountsFromCacheLocked(userAccounts, type, callingUid, null);
|
||||
}
|
||||
Bundle result = new Bundle();
|
||||
result.putParcelableArray(AccountManager.KEY_ACCOUNTS, accounts);
|
||||
@ -2348,7 +2370,7 @@ public class AccountManagerService
|
||||
}
|
||||
} else {
|
||||
Account[] accounts = getAccountsFromCacheLocked(userAccounts, null /* type */,
|
||||
android.os.Process.myUid());
|
||||
Process.myUid(), null);
|
||||
fout.println("Accounts: " + accounts.length);
|
||||
for (Account account : accounts) {
|
||||
fout.println(" " + account);
|
||||
@ -2501,7 +2523,7 @@ public class AccountManagerService
|
||||
|
||||
private boolean hasExplicitlyGrantedPermission(Account account, String authTokenType,
|
||||
int callerUid) {
|
||||
if (callerUid == android.os.Process.SYSTEM_UID) {
|
||||
if (callerUid == Process.SYSTEM_UID) {
|
||||
return true;
|
||||
}
|
||||
UserAccounts accounts = getUserAccountsForCaller();
|
||||
@ -2554,8 +2576,10 @@ public class AccountManagerService
|
||||
}
|
||||
|
||||
private boolean canUserModifyAccounts(int callingUid) {
|
||||
if (callingUid != android.os.Process.myUid()) {
|
||||
if (getUserManager().hasUserRestriction(UserManager.DISALLOW_MODIFY_ACCOUNTS)) {
|
||||
if (callingUid != Process.myUid()) {
|
||||
if (getUserManager().getUserRestrictions(
|
||||
new UserHandle(UserHandle.getUserId(callingUid)))
|
||||
.getBoolean(UserManager.DISALLOW_MODIFY_ACCOUNTS)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -2566,7 +2590,7 @@ public class AccountManagerService
|
||||
throws RemoteException {
|
||||
final int callingUid = getCallingUid();
|
||||
|
||||
if (callingUid != android.os.Process.SYSTEM_UID) {
|
||||
if (callingUid != Process.SYSTEM_UID) {
|
||||
throw new SecurityException();
|
||||
}
|
||||
|
||||
@ -2686,9 +2710,9 @@ public class AccountManagerService
|
||||
}
|
||||
|
||||
private Account[] filterSharedAccounts(UserAccounts userAccounts, Account[] unfiltered,
|
||||
int callingUid) {
|
||||
int callingUid, String callingPackage) {
|
||||
if (getUserManager() == null || userAccounts == null || userAccounts.userId < 0
|
||||
|| callingUid == android.os.Process.myUid()) {
|
||||
|| callingUid == Process.myUid()) {
|
||||
return unfiltered;
|
||||
}
|
||||
if (mUserManager.getUserInfo(userAccounts.userId).isRestricted()) {
|
||||
@ -2712,6 +2736,10 @@ public class AccountManagerService
|
||||
PackageInfo pi = mPackageManager.getPackageInfo(packageName, 0);
|
||||
if (pi != null && pi.restrictedAccountType != null) {
|
||||
requiredAccountType = pi.restrictedAccountType;
|
||||
// If it matches the package name of the original caller, use this choice.
|
||||
if (callingPackage != null && packageName.equals(callingPackage)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (NameNotFoundException nnfe) {
|
||||
@ -2740,15 +2768,19 @@ public class AccountManagerService
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* packageName can be null. If not null, it should be used to filter out restricted accounts
|
||||
* that the package is not allowed to access.
|
||||
*/
|
||||
protected Account[] getAccountsFromCacheLocked(UserAccounts userAccounts, String accountType,
|
||||
int callingUid) {
|
||||
int callingUid, String callingPackage) {
|
||||
if (accountType != null) {
|
||||
final Account[] accounts = userAccounts.accountCache.get(accountType);
|
||||
if (accounts == null) {
|
||||
return EMPTY_ACCOUNT_ARRAY;
|
||||
} else {
|
||||
return filterSharedAccounts(userAccounts, Arrays.copyOf(accounts, accounts.length),
|
||||
callingUid);
|
||||
callingUid, callingPackage);
|
||||
}
|
||||
} else {
|
||||
int totalLength = 0;
|
||||
@ -2765,7 +2797,7 @@ public class AccountManagerService
|
||||
accountsOfType.length);
|
||||
totalLength += accountsOfType.length;
|
||||
}
|
||||
return filterSharedAccounts(userAccounts, accounts, callingUid);
|
||||
return filterSharedAccounts(userAccounts, accounts, callingUid, callingPackage);
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user