Handle forwarded intents from a managed user in AccountSyncSettings

Bug: 15466880
Change-Id: I4041b69f237033dbe5b78c8eb52f5e6ebb6ff7f7
This commit is contained in:
Alexandra Gherghina
2014-06-10 14:01:10 +01:00
parent a5792eb9a4
commit 1eb3f316bd
3 changed files with 63 additions and 19 deletions

View File

@@ -20,6 +20,7 @@ import android.app.ActivityManager;
import android.app.AlertDialog; import android.app.AlertDialog;
import android.app.Dialog; import android.app.Dialog;
import android.app.Fragment; import android.app.Fragment;
import android.app.IActivityManager;
import android.content.ContentResolver; import android.content.ContentResolver;
import android.content.Context; import android.content.Context;
import android.content.DialogInterface; import android.content.DialogInterface;
@@ -40,6 +41,8 @@ import android.net.LinkProperties;
import android.net.Uri; import android.net.Uri;
import android.os.BatteryManager; import android.os.BatteryManager;
import android.os.Bundle; import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.os.UserHandle; import android.os.UserHandle;
import android.os.UserManager; import android.os.UserManager;
import android.preference.Preference; import android.preference.Preference;
@@ -52,6 +55,7 @@ import android.provider.ContactsContract.Profile;
import android.provider.ContactsContract.RawContacts; import android.provider.ContactsContract.RawContacts;
import android.telephony.TelephonyManager; import android.telephony.TelephonyManager;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.Log;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.ListView; import android.widget.ListView;
@@ -63,13 +67,12 @@ import com.android.settings.dashboard.DashboardTile;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.net.InetAddress; import java.net.InetAddress;
import java.util.ArrayList;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
public final class Utils { public final class Utils {
private static final String TAG = "Settings";
/** /**
* Set the preference's title to the matching activity's label. * Set the preference's title to the matching activity's label.
*/ */
@@ -608,4 +611,29 @@ public final class Utils {
UserInfo currentUser = userManager.getUserInfo(userManager.getUserHandle()); UserInfo currentUser = userManager.getUserInfo(userManager.getUserHandle());
return currentUser.isManagedProfile(); return currentUser.isManagedProfile();
} }
/**
* Returns the {@link UserHandle} of the profile that a settings screen should refer to.
*
* <p> This takes into account the id of the user that triggered the settings screen.
*/
public static UserHandle getProfileToDisplay(IActivityManager am, IBinder activityToken,
Bundle arguments) {
int currentUser = UserHandle.getCallingUserId();
// Check to see if it was called from a different user
try {
int launchedFromUser = UserHandle.getUserId(am.getLaunchedFromUid(activityToken));
if (launchedFromUser != currentUser) {
// This is a forwarded intent
return new UserHandle(launchedFromUser);
}
} catch (RemoteException e) {
// Should not happen
Log.v(TAG, "Could not get launching user.");
}
// TODO: Check fragment arguments. See: http://b/15466880
// Default to current profile
return new UserHandle(currentUser);
}
} }

View File

@@ -20,6 +20,7 @@ import com.google.android.collect.Maps;
import android.accounts.AuthenticatorDescription; import android.accounts.AuthenticatorDescription;
import android.app.Activity; import android.app.Activity;
import android.app.ActivityManagerNative;
import android.content.ContentResolver; import android.content.ContentResolver;
import android.content.Context; import android.content.Context;
import android.content.SyncAdapterType; import android.content.SyncAdapterType;
@@ -38,6 +39,7 @@ import android.util.Log;
import android.view.ContextThemeWrapper; import android.view.ContextThemeWrapper;
import com.android.settings.SettingsPreferenceFragment; import com.android.settings.SettingsPreferenceFragment;
import com.android.settings.Utils;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date; import java.util.Date;
@@ -47,23 +49,28 @@ class AccountPreferenceBase extends SettingsPreferenceFragment
implements AuthenticatorHelper.OnAccountsUpdateListener { implements AuthenticatorHelper.OnAccountsUpdateListener {
protected static final String TAG = "AccountSettings"; protected static final String TAG = "AccountSettings";
public static final String AUTHORITIES_FILTER_KEY = "authorities"; public static final String AUTHORITIES_FILTER_KEY = "authorities";
public static final String ACCOUNT_TYPES_FILTER_KEY = "account_types"; public static final String ACCOUNT_TYPES_FILTER_KEY = "account_types";
private final Handler mHandler = new Handler(); private final Handler mHandler = new Handler();
private UserManager mUm; private UserManager mUm;
private Object mStatusChangeListenerHandle; private Object mStatusChangeListenerHandle;
private HashMap<String, ArrayList<String>> mAccountTypeToAuthorities = null; private HashMap<String, ArrayList<String>> mAccountTypeToAuthorities = null;
protected AuthenticatorHelper mAuthenticatorHelper; protected AuthenticatorHelper mAuthenticatorHelper;
protected UserHandle mUserHandle;
private java.text.DateFormat mDateFormat; private java.text.DateFormat mDateFormat;
private java.text.DateFormat mTimeFormat; private java.text.DateFormat mTimeFormat;
@Override @Override
public void onCreate(Bundle icicle) { public void onCreate(Bundle icicle) {
super.onCreate(icicle); super.onCreate(icicle);
// TODO: This needs to handle different users, get the user id from the intent
mUm = (UserManager) getSystemService(Context.USER_SERVICE); mUm = (UserManager) getSystemService(Context.USER_SERVICE);
mAuthenticatorHelper = new AuthenticatorHelper( mUserHandle = Utils.getProfileToDisplay(ActivityManagerNative.getDefault(),
getActivity(), UserHandle.getCallingUserHandle(), mUm, this); getActivity().getActivityToken(), icicle);
mAuthenticatorHelper = new AuthenticatorHelper(getActivity(), mUserHandle, mUm, this);
} }
/** /**

View File

@@ -181,9 +181,9 @@ public class AccountSyncSettings extends AccountPreferenceBase {
Bundle arguments = getArguments(); Bundle arguments = getArguments();
if (arguments == null) { if (arguments == null) {
Log.e(TAG, "No arguments provided when starting intent. ACCOUNT_KEY needed."); Log.e(TAG, "No arguments provided when starting intent. ACCOUNT_KEY needed.");
finish();
return; return;
} }
mAccount = (Account) arguments.getParcelable(ACCOUNT_KEY); mAccount = (Account) arguments.getParcelable(ACCOUNT_KEY);
if (mAccount != null) { if (mAccount != null) {
if (Log.isLoggable(TAG, Log.VERBOSE)) Log.v(TAG, "Got account: " + mAccount); if (Log.isLoggable(TAG, Log.VERBOSE)) Log.v(TAG, "Got account: " + mAccount);
@@ -211,7 +211,8 @@ public class AccountSyncSettings extends AccountPreferenceBase {
SyncStateCheckBoxPreference item = SyncStateCheckBoxPreference item =
new SyncStateCheckBoxPreference(getActivity(), account, authority); new SyncStateCheckBoxPreference(getActivity(), account, authority);
item.setPersistent(false); item.setPersistent(false);
final ProviderInfo providerInfo = getPackageManager().resolveContentProvider(authority, 0); final ProviderInfo providerInfo = getPackageManager().resolveContentProviderAsUser(
authority, 0, mUserHandle.getIdentifier());
if (providerInfo == null) { if (providerInfo == null) {
return; return;
} }
@@ -235,7 +236,6 @@ public class AccountSyncSettings extends AccountPreferenceBase {
MenuItem syncCancel = menu.add(0, MENU_SYNC_CANCEL_ID, 0, MenuItem syncCancel = menu.add(0, MENU_SYNC_CANCEL_ID, 0,
getString(R.string.sync_menu_sync_cancel)) getString(R.string.sync_menu_sync_cancel))
.setIcon(com.android.internal.R.drawable.ic_menu_close_clear_cancel); .setIcon(com.android.internal.R.drawable.ic_menu_close_clear_cancel);
final UserManager um = (UserManager) getSystemService(Context.USER_SERVICE); final UserManager um = (UserManager) getSystemService(Context.USER_SERVICE);
if (!um.hasUserRestriction(UserManager.DISALLOW_MODIFY_ACCOUNTS)) { if (!um.hasUserRestriction(UserManager.DISALLOW_MODIFY_ACCOUNTS)) {
MenuItem removeAccount = menu.add(0, MENU_REMOVE_ACCOUNT_ID, 0, MenuItem removeAccount = menu.add(0, MENU_REMOVE_ACCOUNT_ID, 0,
@@ -255,7 +255,9 @@ public class AccountSyncSettings extends AccountPreferenceBase {
@Override @Override
public void onPrepareOptionsMenu(Menu menu) { public void onPrepareOptionsMenu(Menu menu) {
super.onPrepareOptionsMenu(menu); super.onPrepareOptionsMenu(menu);
boolean syncActive = ContentResolver.getCurrentSync() != null; // Note that this also counts accounts that are not currently displayed
boolean syncActive = ContentResolver.getCurrentSyncsAsUser(
mUserHandle.getIdentifier()).isEmpty();
menu.findItem(MENU_SYNC_NOW_ID).setVisible(!syncActive); menu.findItem(MENU_SYNC_NOW_ID).setVisible(!syncActive);
menu.findItem(MENU_SYNC_CANCEL_ID).setVisible(syncActive); menu.findItem(MENU_SYNC_CANCEL_ID).setVisible(syncActive);
} }
@@ -344,9 +346,10 @@ public class AccountSyncSettings extends AccountPreferenceBase {
if (flag) { if (flag) {
Bundle extras = new Bundle(); Bundle extras = new Bundle();
extras.putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, true); extras.putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, true);
ContentResolver.requestSync(account, authority, extras); ContentResolver.requestSyncAsUser(account, authority, mUserHandle.getIdentifier(),
extras);
} else { } else {
ContentResolver.cancelSync(account, authority); ContentResolver.cancelSyncAsUser(account, authority, mUserHandle.getIdentifier());
} }
} }
@@ -368,7 +371,8 @@ public class AccountSyncSettings extends AccountPreferenceBase {
private void setFeedsState() { private void setFeedsState() {
// iterate over all the preferences, setting the state properly for each // iterate over all the preferences, setting the state properly for each
Date date = new Date(); Date date = new Date();
List<SyncInfo> currentSyncs = ContentResolver.getCurrentSyncs(); final int userId = mUserHandle.getIdentifier();
List<SyncInfo> currentSyncs = ContentResolver.getCurrentSyncsAsUser(userId);
boolean syncIsFailing = false; boolean syncIsFailing = false;
// Refresh the sync status checkboxes - some syncs may have become active. // Refresh the sync status checkboxes - some syncs may have become active.
@@ -384,8 +388,9 @@ public class AccountSyncSettings extends AccountPreferenceBase {
String authority = syncPref.getAuthority(); String authority = syncPref.getAuthority();
Account account = syncPref.getAccount(); Account account = syncPref.getAccount();
SyncStatusInfo status = ContentResolver.getSyncStatus(account, authority); SyncStatusInfo status = ContentResolver.getSyncStatusAsUser(account, authority, userId);
boolean syncEnabled = ContentResolver.getSyncAutomatically(account, authority); boolean syncEnabled = ContentResolver.getSyncAutomaticallyAsUser(account, authority,
userId);
boolean authorityIsPending = status == null ? false : status.pending; boolean authorityIsPending = status == null ? false : status.pending;
boolean initialSync = status == null ? false : status.initialize; boolean initialSync = status == null ? false : status.initialize;
@@ -415,7 +420,7 @@ public class AccountSyncSettings extends AccountPreferenceBase {
} else { } else {
syncPref.setSummary(""); syncPref.setSummary("");
} }
int syncState = ContentResolver.getIsSyncable(account, authority); int syncState = ContentResolver.getIsSyncableAsUser(account, authority, userId);
syncPref.setActive(activelySyncing && (syncState >= 0) && syncPref.setActive(activelySyncing && (syncState >= 0) &&
!initialSync); !initialSync);
@@ -425,7 +430,8 @@ public class AccountSyncSettings extends AccountPreferenceBase {
syncPref.setFailed(lastSyncFailed); syncPref.setFailed(lastSyncFailed);
ConnectivityManager connManager = ConnectivityManager connManager =
(ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
final boolean masterSyncAutomatically = ContentResolver.getMasterSyncAutomatically(); final boolean masterSyncAutomatically =
ContentResolver.getMasterSyncAutomaticallyAsUser(userId);
final boolean backgroundDataEnabled = connManager.getBackgroundDataSetting(); final boolean backgroundDataEnabled = connManager.getBackgroundDataSetting();
final boolean oneTimeSyncMode = !masterSyncAutomatically || !backgroundDataEnabled; final boolean oneTimeSyncMode = !masterSyncAutomatically || !backgroundDataEnabled;
syncPref.setOneTimeSyncMode(oneTimeSyncMode); syncPref.setOneTimeSyncMode(oneTimeSyncMode);
@@ -438,7 +444,8 @@ public class AccountSyncSettings extends AccountPreferenceBase {
@Override @Override
public void onAccountsUpdate(final UserHandle userHandle) { public void onAccountsUpdate(final UserHandle userHandle) {
super.onAccountsUpdate(userHandle); super.onAccountsUpdate(userHandle);
mAccounts = AccountManager.get(getActivity()).getAccounts(); mAccounts = AccountManager.get(getActivity()).getAccountsAsUser(
mUserHandle.getIdentifier());
updateAccountCheckboxes(mAccounts); updateAccountCheckboxes(mAccounts);
onSyncStateUpdated(); onSyncStateUpdated();
} }
@@ -446,7 +453,8 @@ public class AccountSyncSettings extends AccountPreferenceBase {
private void updateAccountCheckboxes(Account[] accounts) { private void updateAccountCheckboxes(Account[] accounts) {
mInvisibleAdapters.clear(); mInvisibleAdapters.clear();
SyncAdapterType[] syncAdapters = ContentResolver.getSyncAdapterTypes(); SyncAdapterType[] syncAdapters = ContentResolver.getSyncAdapterTypesAsUser(
mUserHandle.getIdentifier());
HashMap<String, ArrayList<String>> accountTypeToAuthorities = HashMap<String, ArrayList<String>> accountTypeToAuthorities =
Maps.newHashMap(); Maps.newHashMap();
for (int i = 0, n = syncAdapters.length; i < n; i++) { for (int i = 0, n = syncAdapters.length; i < n; i++) {
@@ -484,7 +492,8 @@ public class AccountSyncSettings extends AccountPreferenceBase {
for (int j = 0, m = authorities.size(); j < m; j++) { for (int j = 0, m = authorities.size(); j < m; j++) {
final String authority = authorities.get(j); final String authority = authorities.get(j);
// We could check services here.... // We could check services here....
int syncState = ContentResolver.getIsSyncable(account, authority); int syncState = ContentResolver.getIsSyncableAsUser(account, authority,
mUserHandle.getIdentifier());
if (Log.isLoggable(TAG, Log.VERBOSE)) { if (Log.isLoggable(TAG, Log.VERBOSE)) {
Log.d(TAG, " found authority " + authority + " " + syncState); Log.d(TAG, " found authority " + authority + " " + syncState);
} }