Handle forwarded intents from a managed user in AccountSyncSettings
Bug: 15466880 Change-Id: I4041b69f237033dbe5b78c8eb52f5e6ebb6ff7f7
This commit is contained in:
@@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -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);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user