diff options
| author | Tom O'Neill <tomo@google.com> | 2013-09-06 10:38:26 -0700 |
|---|---|---|
| committer | Tom O'Neill <tomo@google.com> | 2013-09-06 10:38:26 -0700 |
| commit | 421dccd5dd8cdec03bbc704b142f3ca2396f7e40 (patch) | |
| tree | 97ecb224b802212ee279373830bfeb7d21acc2ca | |
| parent | f1e0c65efb0c1f070d4202170843bec26743fd31 (diff) | |
| download | packages_apps_Settings-421dccd5dd8cdec03bbc704b142f3ca2396f7e40.tar.gz packages_apps_Settings-421dccd5dd8cdec03bbc704b142f3ca2396f7e40.tar.bz2 packages_apps_Settings-421dccd5dd8cdec03bbc704b142f3ca2396f7e40.zip | |
Restrict Settings injection to system-signed apps
- Also: reload the injected settings status values on mode changes
- b/10461474
Change-Id: I58c817ab8ab253aa19fa02c3cb511f26c807dc2a
| -rw-r--r-- | src/com/android/settings/location/LocationSettings.java | 62 | ||||
| -rw-r--r-- | src/com/android/settings/location/SettingsInjector.java | 26 |
2 files changed, 58 insertions, 30 deletions
diff --git a/src/com/android/settings/location/LocationSettings.java b/src/com/android/settings/location/LocationSettings.java index 6dceea955..def5af876 100644 --- a/src/com/android/settings/location/LocationSettings.java +++ b/src/com/android/settings/location/LocationSettings.java @@ -22,6 +22,7 @@ import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; +import android.location.LocationManager; import android.location.SettingInjectorService; import android.os.Bundle; import android.preference.Preference; @@ -165,9 +166,42 @@ public class LocationSettings extends LocationSettingsBase categoryRecentLocationRequests.addPreference(banner); } + addAppSettings(activity, root); + + // Only show the master switch when we're not in multi-pane mode, and not being used as + // Setup Wizard. + if (activity.onIsHidingHeaders() || !activity.onIsMultiPane()) { + final int padding = activity.getResources().getDimensionPixelSize( + R.dimen.action_bar_switch_padding); + mSwitch.setPaddingRelative(0, 0, padding, 0); + activity.getActionBar().setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM, + ActionBar.DISPLAY_SHOW_CUSTOM); + activity.getActionBar().setCustomView(mSwitch, new ActionBar.LayoutParams( + ActionBar.LayoutParams.WRAP_CONTENT, + ActionBar.LayoutParams.WRAP_CONTENT, + Gravity.CENTER_VERTICAL | Gravity.END)); + } + + setHasOptionsMenu(true); + + refreshLocationMode(); + return root; + } + + /** + * Add the settings injected by external apps into the "App Settings" category. Hides the + * category if there are no injected settings. + * + * Reloads the settings whenever receives + * {@link SettingInjectorService#ACTION_INJECTED_SETTING_CHANGED}. As a safety measure, + * also reloads on {@link LocationManager#MODE_CHANGED_ACTION} to ensure the settings are + * up-to-date after mode changes even if an affected app doesn't send the setting changed + * broadcast. + */ + private void addAppSettings(Context context, PreferenceScreen root) { PreferenceCategory categoryAppSettings = (PreferenceCategory) root.findPreference(KEY_APP_SETTINGS); - final SettingsInjector injector = new SettingsInjector(activity); + final SettingsInjector injector = new SettingsInjector(context); List<Preference> appSettings = injector.getInjectedSettings(); mReceiver = new BroadcastReceiver() { @@ -179,8 +213,11 @@ public class LocationSettings extends LocationSettingsBase injector.reloadStatusMessages(); } }; - activity.registerReceiver(mReceiver, - new IntentFilter(SettingInjectorService.ACTION_INJECTED_SETTING_CHANGED)); + + IntentFilter filter = new IntentFilter(); + filter.addAction(SettingInjectorService.ACTION_INJECTED_SETTING_CHANGED); + filter.addAction(LocationManager.MODE_CHANGED_ACTION); + context.registerReceiver(mReceiver, filter); if (appSettings.size() > 0) { addPreferencesSorted(appSettings, categoryAppSettings); @@ -188,25 +225,6 @@ public class LocationSettings extends LocationSettingsBase // If there's no item to display, remove the whole category. root.removePreference(categoryAppSettings); } - - // Only show the master switch when we're not in multi-pane mode, and not being used as - // Setup Wizard. - if (activity.onIsHidingHeaders() || !activity.onIsMultiPane()) { - final int padding = activity.getResources().getDimensionPixelSize( - R.dimen.action_bar_switch_padding); - mSwitch.setPaddingRelative(0, 0, padding, 0); - activity.getActionBar().setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM, - ActionBar.DISPLAY_SHOW_CUSTOM); - activity.getActionBar().setCustomView(mSwitch, new ActionBar.LayoutParams( - ActionBar.LayoutParams.WRAP_CONTENT, - ActionBar.LayoutParams.WRAP_CONTENT, - Gravity.CENTER_VERTICAL | Gravity.END)); - } - - setHasOptionsMenu(true); - - refreshLocationMode(); - return root; } @Override diff --git a/src/com/android/settings/location/SettingsInjector.java b/src/com/android/settings/location/SettingsInjector.java index 592946653..12bf38fec 100644 --- a/src/com/android/settings/location/SettingsInjector.java +++ b/src/com/android/settings/location/SettingsInjector.java @@ -18,6 +18,7 @@ package com.android.settings.location; import android.content.Context; import android.content.Intent; +import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.content.pm.ServiceInfo; @@ -138,8 +139,8 @@ class SettingsInjector { } /** - * Parses {@link InjectedSetting} from the attributes of the - * {@link SettingInjectorService#META_DATA_NAME} tag. + * Returns the settings parsed from the attributes of the + * {@link SettingInjectorService#META_DATA_NAME} tag, or null. * * Duplicates some code from {@link android.content.pm.RegisteredServicesCache}. */ @@ -147,6 +148,15 @@ class SettingsInjector { throws XmlPullParserException, IOException { ServiceInfo si = service.serviceInfo; + ApplicationInfo ai = si.applicationInfo; + + if ((ai.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { + if (Log.isLoggable(TAG, Log.WARN)) { + Log.w(TAG, "Ignoring attempt to inject setting from app not in system image: " + + service); + return null; + } + } XmlResourceParser parser = null; try { @@ -169,7 +179,7 @@ class SettingsInjector { + SettingInjectorService.ATTRIBUTES_NAME + " tag"); } - Resources res = pm.getResourcesForApplication(si.applicationInfo); + Resources res = pm.getResourcesForApplication(ai); return parseAttributes(si.packageName, si.name, res, attrs); } catch (PackageManager.NameNotFoundException e) { throw new XmlPullParserException( @@ -191,17 +201,17 @@ class SettingsInjector { try { // Note that to help guard against malicious string injection, we do not allow dynamic // specification of the label (setting title) - final String label = sa.getString(android.R.styleable.SettingInjectorService_title); - final int iconId = sa.getResourceId( - android.R.styleable.SettingInjectorService_icon, 0); + final String title = sa.getString(android.R.styleable.SettingInjectorService_title); + final int iconId = + sa.getResourceId(android.R.styleable.SettingInjectorService_icon, 0); final String settingsActivity = sa.getString(android.R.styleable.SettingInjectorService_settingsActivity); if (Log.isLoggable(TAG, Log.DEBUG)) { - Log.d(TAG, "parsed label: " + label + ", iconId: " + iconId + Log.d(TAG, "parsed title: " + title + ", iconId: " + iconId + ", settingsActivity: " + settingsActivity); } return InjectedSetting.newInstance(packageName, className, - label, iconId, settingsActivity); + title, iconId, settingsActivity); } finally { sa.recycle(); } |
