Merge "Make Location Settings multiprofile aware" into lmp-mr1-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
f84c6ee01c
@@ -26,6 +26,21 @@
|
||||
settings:keywords="@string/keywords_location_mode"
|
||||
android:summary="@string/location_mode_location_off_title" />
|
||||
|
||||
<!-- This preference category gets removed if there is no managed profile -->
|
||||
<PreferenceCategory
|
||||
android:key="managed_profile_location_category"
|
||||
android:title="@string/managed_profile_location_category">
|
||||
|
||||
<Preference
|
||||
android:key="managed_profile_location_switch"
|
||||
android:title="@string/managed_profile_location_switch_title"
|
||||
android:summary="@string/managed_profile_location_switch_lockdown"
|
||||
android:persistent="false"
|
||||
android:enabled="false"
|
||||
android:selectable="false" />
|
||||
|
||||
</PreferenceCategory>
|
||||
|
||||
<PreferenceCategory
|
||||
android:key="recent_location_requests"
|
||||
android:title="@string/location_category_recent_location_requests" />
|
||||
|
@@ -16,10 +16,14 @@
|
||||
|
||||
package com.android.settings.location;
|
||||
|
||||
import android.annotation.Nullable;
|
||||
import android.content.Context;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.preference.Preference;
|
||||
import android.text.TextUtils;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
import android.widget.TextView;
|
||||
|
||||
/**
|
||||
* A preference item that can dim the icon when it's disabled, either directly or because its parent
|
||||
@@ -29,16 +33,23 @@ public class DimmableIconPreference extends Preference {
|
||||
private static final int ICON_ALPHA_ENABLED = 255;
|
||||
private static final int ICON_ALPHA_DISABLED = 102;
|
||||
|
||||
public DimmableIconPreference(Context context, AttributeSet attrs, int defStyle) {
|
||||
private final CharSequence mContentDescription;
|
||||
|
||||
public DimmableIconPreference(Context context, AttributeSet attrs, int defStyle,
|
||||
@Nullable CharSequence contentDescription) {
|
||||
super(context, attrs, defStyle);
|
||||
mContentDescription = contentDescription;
|
||||
}
|
||||
|
||||
public DimmableIconPreference(Context context, AttributeSet attrs) {
|
||||
public DimmableIconPreference(Context context, AttributeSet attrs,
|
||||
@Nullable CharSequence contentDescription) {
|
||||
super(context, attrs);
|
||||
mContentDescription = contentDescription;
|
||||
}
|
||||
|
||||
public DimmableIconPreference(Context context) {
|
||||
public DimmableIconPreference(Context context, @Nullable CharSequence contentDescription) {
|
||||
super(context);
|
||||
mContentDescription = contentDescription;
|
||||
}
|
||||
|
||||
private void dimIcon(boolean dimmed) {
|
||||
@@ -60,4 +71,13 @@ public class DimmableIconPreference extends Preference {
|
||||
dimIcon(!enabled);
|
||||
super.setEnabled(enabled);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onBindView(View view) {
|
||||
super.onBindView(view);
|
||||
if (!TextUtils.isEmpty(mContentDescription)) {
|
||||
final TextView titleView = (TextView) view.findViewById(android.R.id.title);
|
||||
titleView.setContentDescription(mContentDescription);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -19,6 +19,7 @@ package com.android.settings.location;
|
||||
import android.content.Intent;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import android.os.UserHandle;
|
||||
import com.android.internal.annotations.Immutable;
|
||||
import com.android.internal.util.Preconditions;
|
||||
|
||||
@@ -52,6 +53,11 @@ class InjectedSetting {
|
||||
*/
|
||||
public final int iconId;
|
||||
|
||||
/**
|
||||
* The user/profile associated with this setting (e.g. managed profile)
|
||||
*/
|
||||
public final UserHandle mUserHandle;
|
||||
|
||||
/**
|
||||
* The activity to launch to allow the user to modify the settings value. Assumed to be in the
|
||||
* {@link #packageName} package.
|
||||
@@ -59,11 +65,12 @@ class InjectedSetting {
|
||||
public final String settingsActivity;
|
||||
|
||||
private InjectedSetting(String packageName, String className,
|
||||
String title, int iconId, String settingsActivity) {
|
||||
String title, int iconId, UserHandle userHandle, String settingsActivity) {
|
||||
this.packageName = Preconditions.checkNotNull(packageName, "packageName");
|
||||
this.className = Preconditions.checkNotNull(className, "className");
|
||||
this.title = Preconditions.checkNotNull(title, "title");
|
||||
this.iconId = iconId;
|
||||
this.mUserHandle = userHandle;
|
||||
this.settingsActivity = Preconditions.checkNotNull(settingsActivity);
|
||||
}
|
||||
|
||||
@@ -71,7 +78,7 @@ class InjectedSetting {
|
||||
* Returns a new instance, or null.
|
||||
*/
|
||||
public static InjectedSetting newInstance(String packageName, String className,
|
||||
String title, int iconId, String settingsActivity) {
|
||||
String title, int iconId, UserHandle userHandle, String settingsActivity) {
|
||||
if (packageName == null || className == null ||
|
||||
TextUtils.isEmpty(title) || TextUtils.isEmpty(settingsActivity)) {
|
||||
if (Log.isLoggable(SettingsInjector.TAG, Log.WARN)) {
|
||||
@@ -81,7 +88,8 @@ class InjectedSetting {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
return new InjectedSetting(packageName, className, title, iconId, settingsActivity);
|
||||
return new InjectedSetting(packageName, className, title, iconId, userHandle,
|
||||
settingsActivity);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -91,6 +99,7 @@ class InjectedSetting {
|
||||
", mClassName='" + className + '\'' +
|
||||
", label=" + title +
|
||||
", iconId=" + iconId +
|
||||
", userId=" + mUserHandle.getIdentifier() +
|
||||
", settingsActivity='" + settingsActivity + '\'' +
|
||||
'}';
|
||||
}
|
||||
@@ -113,6 +122,7 @@ class InjectedSetting {
|
||||
|
||||
return packageName.equals(that.packageName) && className.equals(that.className)
|
||||
&& title.equals(that.title) && iconId == that.iconId
|
||||
&& mUserHandle.equals(that.mUserHandle)
|
||||
&& settingsActivity.equals(that.settingsActivity);
|
||||
}
|
||||
|
||||
@@ -122,6 +132,7 @@ class InjectedSetting {
|
||||
result = 31 * result + className.hashCode();
|
||||
result = 31 * result + title.hashCode();
|
||||
result = 31 * result + iconId;
|
||||
result = 31 * result + mUserHandle.hashCode();
|
||||
result = 31 * result + settingsActivity.hashCode();
|
||||
return result;
|
||||
}
|
||||
|
@@ -21,16 +21,22 @@ import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.location.SettingInjectorService;
|
||||
import android.os.Binder;
|
||||
import android.os.Bundle;
|
||||
import android.os.UserHandle;
|
||||
import android.os.UserManager;
|
||||
import android.preference.Preference;
|
||||
import android.preference.PreferenceCategory;
|
||||
import android.preference.PreferenceGroup;
|
||||
import android.preference.PreferenceScreen;
|
||||
import android.preference.SwitchPreference;
|
||||
import android.provider.Settings;
|
||||
import android.util.Log;
|
||||
import android.widget.Switch;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.SettingsActivity;
|
||||
import com.android.settings.Utils;
|
||||
import com.android.settings.widget.SwitchBar;
|
||||
|
||||
import java.util.Collections;
|
||||
@@ -45,6 +51,17 @@ public class LocationSettings extends LocationSettingsBase
|
||||
|
||||
private static final String TAG = "LocationSettings";
|
||||
|
||||
/**
|
||||
* Key for managed profile location preference category. Category is shown only
|
||||
* if there is a managed profile
|
||||
*/
|
||||
private static final String KEY_MANAGED_PROFILE_CATEGORY = "managed_profile_location_category";
|
||||
/**
|
||||
* Key for managed profile location preference. Note it used to be a switch pref and we had to
|
||||
* keep the key as strings had been submitted for string freeze before the decision to
|
||||
* demote this to a simple preference was made. TODO: Candidate for refactoring.
|
||||
*/
|
||||
private static final String KEY_MANAGED_PROFILE_PREFERENCE = "managed_profile_location_switch";
|
||||
/** Key for preference screen "Mode" */
|
||||
private static final String KEY_LOCATION_MODE = "location_mode";
|
||||
/** Key for preference category "Recent location requests" */
|
||||
@@ -55,17 +72,21 @@ public class LocationSettings extends LocationSettingsBase
|
||||
private SwitchBar mSwitchBar;
|
||||
private Switch mSwitch;
|
||||
private boolean mValidListener = false;
|
||||
private UserHandle mManagedProfile;
|
||||
private Preference mManagedProfilePreference;
|
||||
private Preference mLocationMode;
|
||||
private PreferenceCategory mCategoryRecentLocationRequests;
|
||||
/** Receives UPDATE_INTENT */
|
||||
private BroadcastReceiver mReceiver;
|
||||
private SettingsInjector injector;
|
||||
private UserManager mUm;
|
||||
|
||||
@Override
|
||||
public void onActivityCreated(Bundle savedInstanceState) {
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
|
||||
final SettingsActivity activity = (SettingsActivity) getActivity();
|
||||
mUm = (UserManager) activity.getSystemService(Context.USER_SERVICE);
|
||||
|
||||
mSwitchBar = activity.getSwitchBar();
|
||||
mSwitch = mSwitchBar.getSwitch();
|
||||
@@ -127,6 +148,7 @@ public class LocationSettings extends LocationSettingsBase
|
||||
addPreferencesFromResource(R.xml.location_settings);
|
||||
root = getPreferenceScreen();
|
||||
|
||||
setupManagedProfileCategory(root);
|
||||
mLocationMode = root.findPreference(KEY_LOCATION_MODE);
|
||||
mLocationMode.setOnPreferenceClickListener(
|
||||
new Preference.OnPreferenceClickListener() {
|
||||
@@ -155,12 +177,42 @@ public class LocationSettings extends LocationSettingsBase
|
||||
mCategoryRecentLocationRequests.addPreference(banner);
|
||||
}
|
||||
|
||||
addLocationServices(activity, root);
|
||||
boolean lockdownOnLocationAccess = false;
|
||||
// Checking if device policy has put a location access lock-down on the managed
|
||||
// profile. If managed profile has lock-down on location access then its
|
||||
// injected location services must not be shown.
|
||||
if (mManagedProfile != null
|
||||
&& mUm.hasUserRestriction(UserManager.DISALLOW_SHARE_LOCATION, mManagedProfile)) {
|
||||
lockdownOnLocationAccess = true;
|
||||
}
|
||||
addLocationServices(activity, root, lockdownOnLocationAccess);
|
||||
|
||||
refreshLocationMode();
|
||||
return root;
|
||||
}
|
||||
|
||||
private void setupManagedProfileCategory(PreferenceScreen root) {
|
||||
// Looking for a managed profile. If there are no managed profiles then we are removing the
|
||||
// managed profile category.
|
||||
mManagedProfile = Utils.getManagedProfile(mUm);
|
||||
if (mManagedProfile == null) {
|
||||
// There is no managed profile
|
||||
root.removePreference(root.findPreference(KEY_MANAGED_PROFILE_CATEGORY));
|
||||
mManagedProfilePreference = null;
|
||||
} else {
|
||||
mManagedProfilePreference = root.findPreference(KEY_MANAGED_PROFILE_PREFERENCE);
|
||||
mManagedProfilePreference.setOnPreferenceClickListener(null);
|
||||
}
|
||||
}
|
||||
|
||||
private void changeManagedProfileLocationAccessStatus(boolean enabled, int summaryResId) {
|
||||
if (mManagedProfilePreference == null) {
|
||||
return;
|
||||
}
|
||||
mManagedProfilePreference.setEnabled(enabled);
|
||||
mManagedProfilePreference.setSummary(summaryResId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the settings injected by external apps into the "App Settings" category. Hides the
|
||||
* category if there are no injected settings.
|
||||
@@ -168,11 +220,15 @@ public class LocationSettings extends LocationSettingsBase
|
||||
* Reloads the settings whenever receives
|
||||
* {@link SettingInjectorService#ACTION_INJECTED_SETTING_CHANGED}.
|
||||
*/
|
||||
private void addLocationServices(Context context, PreferenceScreen root) {
|
||||
private void addLocationServices(Context context, PreferenceScreen root,
|
||||
boolean lockdownOnLocationAccess) {
|
||||
PreferenceCategory categoryLocationServices =
|
||||
(PreferenceCategory) root.findPreference(KEY_LOCATION_SERVICES);
|
||||
injector = new SettingsInjector(context);
|
||||
List<Preference> locationServices = injector.getInjectedSettings();
|
||||
// If location access is locked down by device policy then we only show injected settings
|
||||
// for the primary profile.
|
||||
List<Preference> locationServices = injector.getInjectedSettings(lockdownOnLocationAccess ?
|
||||
UserHandle.myUserId() : UserHandle.USER_CURRENT);
|
||||
|
||||
mReceiver = new BroadcastReceiver() {
|
||||
@Override
|
||||
@@ -223,7 +279,7 @@ public class LocationSettings extends LocationSettingsBase
|
||||
// Restricted user can't change the location mode, so disable the master switch. But in some
|
||||
// corner cases, the location might still be enabled. In such case the master switch should
|
||||
// be disabled but checked.
|
||||
boolean enabled = (mode != android.provider.Settings.Secure.LOCATION_MODE_OFF);
|
||||
final boolean enabled = (mode != android.provider.Settings.Secure.LOCATION_MODE_OFF);
|
||||
// Disable the whole switch bar instead of the switch itself. If we disabled the switch
|
||||
// only, it would be re-enabled again if the switch bar is not disabled.
|
||||
mSwitchBar.setEnabled(!restricted);
|
||||
@@ -240,6 +296,20 @@ public class LocationSettings extends LocationSettingsBase
|
||||
mSwitchBar.addOnSwitchChangeListener(this);
|
||||
}
|
||||
}
|
||||
|
||||
if (mManagedProfilePreference != null) {
|
||||
if (mUm.hasUserRestriction(UserManager.DISALLOW_SHARE_LOCATION, mManagedProfile)) {
|
||||
changeManagedProfileLocationAccessStatus(false,
|
||||
R.string.managed_profile_location_switch_lockdown);
|
||||
} else {
|
||||
if (enabled) {
|
||||
changeManagedProfileLocationAccessStatus(true, R.string.switch_on_text);
|
||||
} else {
|
||||
changeManagedProfileLocationAccessStatus(false, R.string.switch_off_text);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// As a safety measure, also reloads on location mode change to ensure the settings are
|
||||
// up-to-date even if an affected app doesn't send the setting changed broadcast.
|
||||
injector.reloadStatusMessages();
|
||||
|
@@ -77,35 +77,13 @@ public class RecentLocationApps {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Subclass of {@link Preference} to intercept views and allow content description to be set on
|
||||
* them for accessibility purposes.
|
||||
*/
|
||||
private static class AccessiblePreference extends DimmableIconPreference {
|
||||
public CharSequence mContentDescription;
|
||||
|
||||
public AccessiblePreference(Context context, CharSequence contentDescription) {
|
||||
super(context);
|
||||
mContentDescription = contentDescription;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onBindView(View view) {
|
||||
super.onBindView(view);
|
||||
if (mContentDescription != null) {
|
||||
final TextView titleView = (TextView) view.findViewById(android.R.id.title);
|
||||
titleView.setContentDescription(mContentDescription);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private AccessiblePreference createRecentLocationEntry(
|
||||
private DimmableIconPreference createRecentLocationEntry(
|
||||
Drawable icon,
|
||||
CharSequence label,
|
||||
boolean isHighBattery,
|
||||
CharSequence contentDescription,
|
||||
Preference.OnPreferenceClickListener listener) {
|
||||
AccessiblePreference pref = new AccessiblePreference(mActivity, contentDescription);
|
||||
DimmableIconPreference pref = new DimmableIconPreference(mActivity, contentDescription);
|
||||
pref.setIcon(icon);
|
||||
pref.setTitle(label);
|
||||
if (isHighBattery) {
|
||||
@@ -198,7 +176,7 @@ public class RecentLocationApps {
|
||||
int uid = ops.getUid();
|
||||
int userId = UserHandle.getUserId(uid);
|
||||
|
||||
AccessiblePreference preference = null;
|
||||
DimmableIconPreference preference = null;
|
||||
try {
|
||||
IPackageManager ipm = AppGlobals.getPackageManager();
|
||||
ApplicationInfo appInfo =
|
||||
@@ -215,6 +193,11 @@ public class RecentLocationApps {
|
||||
Drawable icon = mPackageManager.getUserBadgedIcon(appIcon, userHandle);
|
||||
CharSequence appLabel = mPackageManager.getApplicationLabel(appInfo);
|
||||
CharSequence badgedAppLabel = mPackageManager.getUserBadgedLabel(appLabel, userHandle);
|
||||
if (appLabel.toString().contentEquals(badgedAppLabel)) {
|
||||
// If badged label is not different from original then no need for it as
|
||||
// a separate content description.
|
||||
badgedAppLabel = null;
|
||||
}
|
||||
preference = createRecentLocationEntry(icon,
|
||||
appLabel, highBattery, badgedAppLabel,
|
||||
new PackageEntryClickedListener(packageName));
|
||||
|
@@ -32,11 +32,15 @@ import android.os.Handler;
|
||||
import android.os.Message;
|
||||
import android.os.Messenger;
|
||||
import android.os.SystemClock;
|
||||
import android.os.UserHandle;
|
||||
import android.os.UserManager;
|
||||
import android.preference.Preference;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.Log;
|
||||
import android.util.Xml;
|
||||
|
||||
import com.android.settings.R;
|
||||
|
||||
import org.xmlpull.v1.XmlPullParser;
|
||||
import org.xmlpull.v1.XmlPullParserException;
|
||||
|
||||
@@ -99,27 +103,29 @@ class SettingsInjector {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list with one {@link InjectedSetting} object for each {@link android.app.Service}
|
||||
* that responds to {@link SettingInjectorService#ACTION_SERVICE_INTENT} and provides the
|
||||
* expected setting metadata.
|
||||
* Returns a list for a profile with one {@link InjectedSetting} object for each
|
||||
* {@link android.app.Service} that responds to
|
||||
* {@link SettingInjectorService#ACTION_SERVICE_INTENT} and provides the expected setting
|
||||
* metadata.
|
||||
*
|
||||
* Duplicates some code from {@link android.content.pm.RegisteredServicesCache}.
|
||||
*
|
||||
* TODO: unit test
|
||||
*/
|
||||
private List<InjectedSetting> getSettings() {
|
||||
private List<InjectedSetting> getSettings(final UserHandle userHandle) {
|
||||
PackageManager pm = mContext.getPackageManager();
|
||||
Intent intent = new Intent(SettingInjectorService.ACTION_SERVICE_INTENT);
|
||||
|
||||
final int profileId = userHandle.getIdentifier();
|
||||
List<ResolveInfo> resolveInfos =
|
||||
pm.queryIntentServices(intent, PackageManager.GET_META_DATA);
|
||||
pm.queryIntentServicesAsUser(intent, PackageManager.GET_META_DATA, profileId);
|
||||
if (Log.isLoggable(TAG, Log.DEBUG)) {
|
||||
Log.d(TAG, "Found services: " + resolveInfos);
|
||||
Log.d(TAG, "Found services for profile id " + profileId + ": " + resolveInfos);
|
||||
}
|
||||
List<InjectedSetting> settings = new ArrayList<InjectedSetting>(resolveInfos.size());
|
||||
for (ResolveInfo resolveInfo : resolveInfos) {
|
||||
try {
|
||||
InjectedSetting setting = parseServiceInfo(resolveInfo, pm);
|
||||
InjectedSetting setting = parseServiceInfo(resolveInfo, userHandle, pm);
|
||||
if (setting == null) {
|
||||
Log.w(TAG, "Unable to load service info " + resolveInfo);
|
||||
} else {
|
||||
@@ -132,7 +138,7 @@ class SettingsInjector {
|
||||
}
|
||||
}
|
||||
if (Log.isLoggable(TAG, Log.DEBUG)) {
|
||||
Log.d(TAG, "Loaded settings: " + settings);
|
||||
Log.d(TAG, "Loaded settings for profile id " + profileId + ": " + settings);
|
||||
}
|
||||
|
||||
return settings;
|
||||
@@ -144,8 +150,8 @@ class SettingsInjector {
|
||||
*
|
||||
* Duplicates some code from {@link android.content.pm.RegisteredServicesCache}.
|
||||
*/
|
||||
private static InjectedSetting parseServiceInfo(ResolveInfo service, PackageManager pm)
|
||||
throws XmlPullParserException, IOException {
|
||||
private static InjectedSetting parseServiceInfo(ResolveInfo service, UserHandle userHandle,
|
||||
PackageManager pm) throws XmlPullParserException, IOException {
|
||||
|
||||
ServiceInfo si = service.serviceInfo;
|
||||
ApplicationInfo ai = si.applicationInfo;
|
||||
@@ -179,8 +185,9 @@ class SettingsInjector {
|
||||
+ SettingInjectorService.ATTRIBUTES_NAME + " tag");
|
||||
}
|
||||
|
||||
Resources res = pm.getResourcesForApplication(ai);
|
||||
return parseAttributes(si.packageName, si.name, res, attrs);
|
||||
Resources res = pm.getResourcesForApplicationAsUser(si.packageName,
|
||||
userHandle.getIdentifier());
|
||||
return parseAttributes(si.packageName, si.name, userHandle, res, attrs);
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
throw new XmlPullParserException(
|
||||
"Unable to load resources for package " + si.packageName);
|
||||
@@ -194,8 +201,8 @@ class SettingsInjector {
|
||||
/**
|
||||
* Returns an immutable representation of the static attributes for the setting, or null.
|
||||
*/
|
||||
private static InjectedSetting parseAttributes(
|
||||
String packageName, String className, Resources res, AttributeSet attrs) {
|
||||
private static InjectedSetting parseAttributes(String packageName, String className,
|
||||
UserHandle userHandle, Resources res, AttributeSet attrs) {
|
||||
|
||||
TypedArray sa = res.obtainAttributes(attrs, android.R.styleable.SettingInjectorService);
|
||||
try {
|
||||
@@ -211,7 +218,7 @@ class SettingsInjector {
|
||||
+ ", settingsActivity: " + settingsActivity);
|
||||
}
|
||||
return InjectedSetting.newInstance(packageName, className,
|
||||
title, iconId, settingsActivity);
|
||||
title, iconId, userHandle, settingsActivity);
|
||||
} finally {
|
||||
sa.recycle();
|
||||
}
|
||||
@@ -219,13 +226,24 @@ class SettingsInjector {
|
||||
|
||||
/**
|
||||
* Gets a list of preferences that other apps have injected.
|
||||
*
|
||||
* @param profileId Identifier of the user/profile to obtain the injected settings for or
|
||||
* UserHandle.USER_CURRENT for all profiles associated with current user.
|
||||
*/
|
||||
public List<Preference> getInjectedSettings() {
|
||||
Iterable<InjectedSetting> settings = getSettings();
|
||||
public List<Preference> getInjectedSettings(final int profileId) {
|
||||
final UserManager um = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
|
||||
final List<UserHandle> profiles = um.getUserProfiles();
|
||||
ArrayList<Preference> prefs = new ArrayList<Preference>();
|
||||
for (InjectedSetting setting : settings) {
|
||||
Preference pref = addServiceSetting(prefs, setting);
|
||||
mSettings.add(new Setting(setting, pref));
|
||||
final int profileCount = profiles.size();
|
||||
for (int i = 0; i < profileCount; ++i) {
|
||||
final UserHandle userHandle = profiles.get(i);
|
||||
if (profileId == UserHandle.USER_CURRENT || profileId == userHandle.getIdentifier()) {
|
||||
Iterable<InjectedSetting> settings = getSettings(userHandle);
|
||||
for (InjectedSetting setting : settings) {
|
||||
Preference pref = addServiceSetting(prefs, setting);
|
||||
mSettings.add(new Setting(setting, pref));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
reloadStatusMessages();
|
||||
@@ -247,24 +265,46 @@ class SettingsInjector {
|
||||
* Adds an injected setting to the root.
|
||||
*/
|
||||
private Preference addServiceSetting(List<Preference> prefs, InjectedSetting info) {
|
||||
Preference pref = new DimmableIconPreference(mContext);
|
||||
PackageManager pm = mContext.getPackageManager();
|
||||
Drawable appIcon = pm.getDrawable(info.packageName, info.iconId, null);
|
||||
Drawable icon = pm.getUserBadgedIcon(appIcon, info.mUserHandle);
|
||||
CharSequence badgedAppLabel = pm.getUserBadgedLabel(info.title, info.mUserHandle);
|
||||
if (info.title.contentEquals(badgedAppLabel)) {
|
||||
// If badged label is not different from original then no need for it as
|
||||
// a separate content description.
|
||||
badgedAppLabel = null;
|
||||
}
|
||||
Preference pref = new DimmableIconPreference(mContext, badgedAppLabel);
|
||||
pref.setTitle(info.title);
|
||||
pref.setSummary(null);
|
||||
PackageManager pm = mContext.getPackageManager();
|
||||
Drawable icon = pm.getDrawable(info.packageName, info.iconId, null);
|
||||
pref.setIcon(icon);
|
||||
|
||||
// Activity to start if they click on the preference. Must start in new task to ensure
|
||||
// that "android.settings.LOCATION_SOURCE_SETTINGS" brings user back to Settings > Location.
|
||||
Intent settingIntent = new Intent();
|
||||
settingIntent.setClassName(info.packageName, info.settingsActivity);
|
||||
settingIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
pref.setIntent(settingIntent);
|
||||
pref.setOnPreferenceClickListener(new ServiceSettingClickedListener(info));
|
||||
|
||||
prefs.add(pref);
|
||||
return pref;
|
||||
}
|
||||
|
||||
private class ServiceSettingClickedListener
|
||||
implements Preference.OnPreferenceClickListener {
|
||||
private InjectedSetting mInfo;
|
||||
|
||||
public ServiceSettingClickedListener(InjectedSetting info) {
|
||||
mInfo = info;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPreferenceClick(Preference preference) {
|
||||
// Activity to start if they click on the preference. Must start in new task to ensure
|
||||
// that "android.settings.LOCATION_SOURCE_SETTINGS" brings user back to
|
||||
// Settings > Location.
|
||||
Intent settingIntent = new Intent();
|
||||
settingIntent.setClassName(mInfo.packageName, mInfo.settingsActivity);
|
||||
settingIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
mContext.startActivityAsUser(settingIntent, mInfo.mUserHandle);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the setting status values one at a time. Each load starts a subclass of {@link
|
||||
* SettingInjectorService}, so to reduce memory pressure we don't want to load too many at
|
||||
@@ -451,9 +491,9 @@ class SettingsInjector {
|
||||
startMillis = 0;
|
||||
}
|
||||
|
||||
// Start the service, making sure that this is attributed to the current user rather
|
||||
// than the system user.
|
||||
mContext.startServiceAsUser(intent, android.os.Process.myUserHandle());
|
||||
// Start the service, making sure that this is attributed to the user associated with
|
||||
// the setting rather than the system user.
|
||||
mContext.startServiceAsUser(intent, setting.mUserHandle);
|
||||
}
|
||||
|
||||
public long getElapsedTime() {
|
||||
|
Reference in New Issue
Block a user