diff options
Diffstat (limited to 'src/com/android/settings')
21 files changed, 273 insertions, 144 deletions
diff --git a/src/com/android/settings/DeviceInfoSettings.java b/src/com/android/settings/DeviceInfoSettings.java index ac74221..7e94741 100644 --- a/src/com/android/settings/DeviceInfoSettings.java +++ b/src/com/android/settings/DeviceInfoSettings.java @@ -37,7 +37,7 @@ import java.io.IOException; import java.util.regex.Matcher; import java.util.regex.Pattern; -public class DeviceInfoSettings extends SettingsPreferenceFragment { +public class DeviceInfoSettings extends RestrictedSettingsFragment { private static final String LOG_TAG = "DeviceInfoSettings"; @@ -70,12 +70,20 @@ public class DeviceInfoSettings extends SettingsPreferenceFragment { int mDevHitCountdown; Toast mDevHitToast; + public DeviceInfoSettings() { + super(null /* Don't PIN protect the entire screen */); + } + @Override public void onCreate(Bundle icicle) { super.onCreate(icicle); addPreferencesFromResource(R.xml.device_info_settings); + // We only call ensurePinRestrictedPreference() when mDevHitCountdown == 0. + // This will keep us from entering developer mode without a PIN. + protectByRestrictions(KEY_BUILD_NUMBER); + setStringSummary(KEY_FIRMWARE_VERSION, Build.VERSION.RELEASE); findPreference(KEY_FIRMWARE_VERSION).setEnabled(true); setValueSummary(KEY_BASEBAND_VERSION, "gsm.version.baseband"); @@ -178,6 +186,11 @@ public class DeviceInfoSettings extends SettingsPreferenceFragment { if (UserHandle.myUserId() != UserHandle.USER_OWNER) return true; if (mDevHitCountdown > 0) { + if (mDevHitCountdown == 1) { + if (super.ensurePinRestrictedPreference(preference)) { + return true; + } + } mDevHitCountdown--; if (mDevHitCountdown == 0) { getActivity().getSharedPreferences(DevelopmentSettings.PREF_FILE, diff --git a/src/com/android/settings/RegulatoryInfoDisplayActivity.java b/src/com/android/settings/RegulatoryInfoDisplayActivity.java index 8adecf1..171059c 100644 --- a/src/com/android/settings/RegulatoryInfoDisplayActivity.java +++ b/src/com/android/settings/RegulatoryInfoDisplayActivity.java @@ -22,7 +22,11 @@ import android.content.DialogInterface; import android.content.res.Resources; import android.graphics.drawable.Drawable; import android.os.Bundle; +import android.os.SystemProperties; +import android.text.TextUtils; import android.view.Gravity; +import android.view.View; +import android.widget.ImageView; import android.widget.TextView; /** @@ -30,11 +34,14 @@ import android.widget.TextView; * preference item, and when "*#07#" is dialed on the Phone keypad. To enable this feature, * set the "config_show_regulatory_info" boolean to true in a device overlay resource, and in the * same overlay, either add a drawable named "regulatory_info.png" containing a graphical version - * of the required regulatory info, or add a string resource named "regulatory_info_text" with - * an HTML version of the required information (text will be centered in the dialog). + * of the required regulatory info (If ro.bootloader.hardware.sku property is set use + * "regulatory_info_<sku>.png where sku is ro.bootloader.hardware.sku property value in lowercase"), + * or add a string resource named "regulatory_info_text" with an HTML version of the required + * information (text will be centered in the dialog). */ public class RegulatoryInfoDisplayActivity extends Activity implements DialogInterface.OnDismissListener { + private final String REGULATORY_INFO_RESOURCE = "regulatory_info"; /** * Display the regulatory info graphic in a dialog window. @@ -52,21 +59,27 @@ public class RegulatoryInfoDisplayActivity extends Activity implements .setTitle(R.string.regulatory_information) .setOnDismissListener(this); - boolean regulatoryInfoDrawableExists; - try { - Drawable d = resources.getDrawable(R.drawable.regulatory_info); - // set to false if the width or height is <= 2 - // (missing PNG can return an empty 2x2 pixel Drawable) - regulatoryInfoDrawableExists = (d.getIntrinsicWidth() > 2 - && d.getIntrinsicHeight() > 2); - } catch (Resources.NotFoundException ignored) { - regulatoryInfoDrawableExists = false; + boolean regulatoryInfoDrawableExists = false; + int resId = getResourceId(); + if (resId != 0) { + try { + Drawable d = resources.getDrawable(resId); + // set to false if the width or height is <= 2 + // (missing PNG can return an empty 2x2 pixel Drawable) + regulatoryInfoDrawableExists = (d.getIntrinsicWidth() > 2 + && d.getIntrinsicHeight() > 2); + } catch (Resources.NotFoundException ignored) { + regulatoryInfoDrawableExists = false; + } } CharSequence regulatoryText = resources.getText(R.string.regulatory_info_text); if (regulatoryInfoDrawableExists) { - builder.setView(getLayoutInflater().inflate(R.layout.regulatory_info, null)); + View view = getLayoutInflater().inflate(R.layout.regulatory_info, null); + ImageView image = (ImageView) view.findViewById(R.id.regulatoryInfo); + image.setImageResource(resId); + builder.setView(view); builder.show(); } else if (regulatoryText.length() > 0) { builder.setMessage(regulatoryText); @@ -80,6 +93,24 @@ public class RegulatoryInfoDisplayActivity extends Activity implements } } + private int getResourceId() { + // Use regulatory_info by default. + int resId = getResources().getIdentifier( + REGULATORY_INFO_RESOURCE, "drawable", getPackageName()); + + // When hardware sku property exists, use regulatory_info_<sku> resource if valid. + String sku = SystemProperties.get("ro.boot.hardware.sku", ""); + if (!TextUtils.isEmpty(sku)) { + String regulatory_info_res = REGULATORY_INFO_RESOURCE + "_" + sku.toLowerCase(); + int id = getResources().getIdentifier( + regulatory_info_res, "drawable", getPackageName()); + if (id != 0) { + resId = id; + } + } + return resId; + } + @Override public void onDismiss(DialogInterface dialog) { finish(); // close the activity diff --git a/src/com/android/settings/Settings.java b/src/com/android/settings/Settings.java index 35fe885..febb5b6 100644 --- a/src/com/android/settings/Settings.java +++ b/src/com/android/settings/Settings.java @@ -66,6 +66,7 @@ import com.android.settings.deviceinfo.Memory; import com.android.settings.deviceinfo.UsbSettings; import com.android.settings.fuelgauge.PowerUsageSummary; import com.android.settings.inputmethod.InputMethodAndLanguageSettings; +import com.android.settings.inputmethod.KeyboardLayoutPickerFragment; import com.android.settings.inputmethod.SpellCheckersSettings; import com.android.settings.inputmethod.UserDictionaryList; import com.android.settings.location.LocationSettings; @@ -332,7 +333,8 @@ public class Settings extends PreferenceActivity ManageAccountsSettings.class.getName(), PrintSettingsFragment.class.getName(), TrustedCredentialsSettings.class.getName(), - PaymentSettings.class.getName() + PaymentSettings.class.getName(), + KeyboardLayoutPickerFragment.class.getName() }; @Override diff --git a/src/com/android/settings/UserDictionarySettings.java b/src/com/android/settings/UserDictionarySettings.java index 9f6df50..da12004 100644 --- a/src/com/android/settings/UserDictionarySettings.java +++ b/src/com/android/settings/UserDictionarySettings.java @@ -16,6 +16,9 @@ package com.android.settings; +import com.android.settings.inputmethod.UserDictionaryAddWordContents; +import com.android.settings.inputmethod.UserDictionarySettingsUtils; + import android.app.ListFragment; import android.content.ContentResolver; import android.content.Context; @@ -37,9 +40,6 @@ import android.widget.SectionIndexer; import android.widget.SimpleCursorAdapter; import android.widget.TextView; -import com.android.settings.inputmethod.UserDictionaryAddWordContents; -import com.android.settings.inputmethod.UserDictionarySettingsUtils; - import java.util.Locale; public class UserDictionarySettings extends ListFragment { @@ -165,7 +165,7 @@ public class UserDictionarySettings extends ListFragment { public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { MenuItem actionItem = menu.add(0, OPTIONS_MENU_ADD, 0, R.string.user_dict_settings_add_menu_title) - .setIcon(R.drawable.ic_menu_add); + .setIcon(R.drawable.ic_menu_add_dark); actionItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM | MenuItem.SHOW_AS_ACTION_WITH_TEXT); } @@ -236,8 +236,9 @@ public class UserDictionarySettings extends ListFragment { private AlphabetIndexer mIndexer; - private ViewBinder mViewBinder = new ViewBinder() { + private final ViewBinder mViewBinder = new ViewBinder() { + @Override public boolean setViewValue(View v, Cursor c, int columnIndex) { if (columnIndex == INDEX_SHORTCUT) { final String shortcut = c.getString(INDEX_SHORTCUT); @@ -268,14 +269,17 @@ public class UserDictionarySettings extends ListFragment { setViewBinder(mViewBinder); } + @Override public int getPositionForSection(int section) { return null == mIndexer ? 0 : mIndexer.getPositionForSection(section); } + @Override public int getSectionForPosition(int position) { return null == mIndexer ? 0 : mIndexer.getSectionForPosition(position); } + @Override public Object[] getSections() { return null == mIndexer ? null : mIndexer.getSections(); } diff --git a/src/com/android/settings/fuelgauge/BatteryStatsHelper.java b/src/com/android/settings/fuelgauge/BatteryStatsHelper.java index 3b1ea93..953ff3d 100644 --- a/src/com/android/settings/fuelgauge/BatteryStatsHelper.java +++ b/src/com/android/settings/fuelgauge/BatteryStatsHelper.java @@ -320,7 +320,12 @@ public class BatteryStatsHelper { R.string.details_title, null, null, 0); } - public void refreshStats() { + /** + * Refreshes the power usage list. + * @param includeZeroConsumption whether includes those applications which have consumed very + * little power up till now. + */ + public void refreshStats(boolean includeZeroConsumption) { // Initialize mStats if necessary. getStats(); @@ -336,7 +341,7 @@ public class BatteryStatsHelper { mUserSippers.clear(); mUserPower.clear(); - processAppUsage(); + processAppUsage(includeZeroConsumption); processMiscUsage(); Collections.sort(mUsageList); @@ -356,7 +361,7 @@ public class BatteryStatsHelper { } } - private void processAppUsage() { + private void processAppUsage(boolean includeZeroConsumption) { SensorManager sensorManager = (SensorManager) mActivity.getSystemService( Context.SENSOR_SERVICE); final int which = mStatsType; @@ -522,7 +527,7 @@ public class BatteryStatsHelper { // Add the app to the list if it is consuming power boolean isOtherUser = false; final int userId = UserHandle.getUserId(u.getUid()); - if (power != 0 || u.getUid() == 0) { + if (power != 0 || includeZeroConsumption || u.getUid() == 0) { BatterySipper app = new BatterySipper(mActivity, mRequestQueue, mHandler, packageWithHighestDrain, DrainType.APP, 0, u, new double[] {power}); diff --git a/src/com/android/settings/fuelgauge/PowerUsageDetail.java b/src/com/android/settings/fuelgauge/PowerUsageDetail.java index e9b8106..ca159dc 100644 --- a/src/com/android/settings/fuelgauge/PowerUsageDetail.java +++ b/src/com/android/settings/fuelgauge/PowerUsageDetail.java @@ -36,6 +36,7 @@ import android.graphics.drawable.Drawable; import android.net.Uri; import android.os.Bundle; import android.os.Process; +import android.os.UserHandle; import android.preference.PreferenceActivity; import android.provider.Settings; import android.text.TextUtils; @@ -470,7 +471,7 @@ public class PowerUsageDetail extends Fragment implements Button.OnClickListener Uri.fromParts("package", mPackages[0], null)); intent.putExtra(Intent.EXTRA_PACKAGES, mPackages); intent.putExtra(Intent.EXTRA_UID, mUid); - intent.putExtra(Intent.EXTRA_USER_HANDLE, mUid); + intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(mUid)); getActivity().sendOrderedBroadcast(intent, null, mCheckKillProcessesReceiver, null, Activity.RESULT_CANCELED, null, null); } diff --git a/src/com/android/settings/fuelgauge/PowerUsageSummary.java b/src/com/android/settings/fuelgauge/PowerUsageSummary.java index 480bb4e..740fdb5 100644 --- a/src/com/android/settings/fuelgauge/PowerUsageSummary.java +++ b/src/com/android/settings/fuelgauge/PowerUsageSummary.java @@ -210,7 +210,7 @@ public class PowerUsageSummary extends PreferenceFragment { addNotAvailableMessage(); return; } - mStatsHelper.refreshStats(); + mStatsHelper.refreshStats(false); List<BatterySipper> usageList = mStatsHelper.getUsageList(); for (BatterySipper sipper : usageList) { if (sipper.getSortValue() < MIN_POWER_THRESHOLD) continue; diff --git a/src/com/android/settings/location/LocationSettings.java b/src/com/android/settings/location/LocationSettings.java index 815be41..6dceea9 100644 --- a/src/com/android/settings/location/LocationSettings.java +++ b/src/com/android/settings/location/LocationSettings.java @@ -55,7 +55,7 @@ public class LocationSettings extends LocationSettingsBase /** Key for preference category "Recent location requests" */ private static final String KEY_RECENT_LOCATION_REQUESTS = "recent_location_requests"; /** Key for preference category "Location services" */ - private static final String KEY_LOCATION_SERVICES = "location_services"; + private static final String KEY_APP_SETTINGS = "app_settings"; private Switch mSwitch; private boolean mValidListener; @@ -165,10 +165,10 @@ public class LocationSettings extends LocationSettingsBase categoryRecentLocationRequests.addPreference(banner); } - PreferenceCategory categoryLocationServices = - (PreferenceCategory) root.findPreference(KEY_LOCATION_SERVICES); + PreferenceCategory categoryAppSettings = + (PreferenceCategory) root.findPreference(KEY_APP_SETTINGS); final SettingsInjector injector = new SettingsInjector(activity); - List<Preference> locationServices = injector.getInjectedSettings(); + List<Preference> appSettings = injector.getInjectedSettings(); mReceiver = new BroadcastReceiver() { @Override @@ -182,11 +182,11 @@ public class LocationSettings extends LocationSettingsBase activity.registerReceiver(mReceiver, new IntentFilter(SettingInjectorService.ACTION_INJECTED_SETTING_CHANGED)); - if (locationServices.size() > 0) { - addPreferencesSorted(locationServices, categoryLocationServices); + if (appSettings.size() > 0) { + addPreferencesSorted(appSettings, categoryAppSettings); } else { // If there's no item to display, remove the whole category. - root.removePreference(categoryLocationServices); + root.removePreference(categoryAppSettings); } // Only show the master switch when we're not in multi-pane mode, and not being used as @@ -233,9 +233,12 @@ public class LocationSettings extends LocationSettingsBase break; } - boolean enabled = (mode != Settings.Secure.LOCATION_MODE_OFF) && !restricted; + // 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 != Settings.Secure.LOCATION_MODE_OFF); mSwitch.setEnabled(!restricted); - mLocationMode.setEnabled(enabled); + mLocationMode.setEnabled(enabled && !restricted); if (enabled != mSwitch.isChecked()) { // set listener to null so that that code below doesn't trigger onCheckedChanged() diff --git a/src/com/android/settings/location/LocationSettingsBase.java b/src/com/android/settings/location/LocationSettingsBase.java index 81e841a..9ceefe7 100644 --- a/src/com/android/settings/location/LocationSettingsBase.java +++ b/src/com/android/settings/location/LocationSettingsBase.java @@ -38,12 +38,29 @@ public abstract class LocationSettingsBase extends SettingsPreferenceFragment private static final int LOADER_ID_LOCATION_MODE = 1; + /** + * Whether the fragment is actively running. + */ + private boolean mActive = false; + @Override public void onCreate(Bundle icicle) { super.onCreate(icicle); getLoaderManager().initLoader(LOADER_ID_LOCATION_MODE, null, this); } + @Override + public void onResume() { + super.onResume(); + mActive = true; + } + + @Override + public void onPause() { + super.onPause(); + mActive = false; + } + /** Called when location mode has changed. */ public abstract void onModeChanged(int mode, boolean restricted); @@ -61,7 +78,9 @@ public abstract class LocationSettingsBase extends SettingsPreferenceFragment } mode = Settings.Secure.getInt(getContentResolver(), Settings.Secure.LOCATION_MODE, Settings.Secure.LOCATION_MODE_OFF); - onModeChanged(mode, true); + if (mActive) { + onModeChanged(mode, true); + } return; } Settings.Secure.putInt(getContentResolver(), Settings.Secure.LOCATION_MODE, mode); @@ -69,9 +88,11 @@ public abstract class LocationSettingsBase extends SettingsPreferenceFragment } public void refreshLocationMode() { - int mode = Settings.Secure.getInt(getContentResolver(), Settings.Secure.LOCATION_MODE, - Settings.Secure.LOCATION_MODE_OFF); - onModeChanged(mode, isRestricted()); + if (mActive) { + int mode = Settings.Secure.getInt(getContentResolver(), Settings.Secure.LOCATION_MODE, + Settings.Secure.LOCATION_MODE_OFF); + onModeChanged(mode, isRestricted()); + } } @Override diff --git a/src/com/android/settings/location/RecentLocationApps.java b/src/com/android/settings/location/RecentLocationApps.java index 23e6dcf..1fa8aac 100644 --- a/src/com/android/settings/location/RecentLocationApps.java +++ b/src/com/android/settings/location/RecentLocationApps.java @@ -140,7 +140,7 @@ public class RecentLocationApps { public List<Preference> getAppList() { // Retrieve Uid-based battery blaming info and generate a package to BatterySipper HashMap // for later faster looking up. - mStatsHelper.refreshStats(); + mStatsHelper.refreshStats(true); List<BatterySipper> usageList = mStatsHelper.getUsageList(); // Key: package Uid. Value: BatterySipperWrapper. HashMap<Integer, BatterySipperWrapper> sipperMap = @@ -243,11 +243,22 @@ public class RecentLocationApps { try { ApplicationInfo appInfo = mPackageManager.getApplicationInfo( packageName, PackageManager.GET_META_DATA); - pref = createRecentLocationEntry( - mPackageManager.getApplicationIcon(appInfo), - mPackageManager.getApplicationLabel(appInfo), - highBattery, - new PackageEntryClickedListener(packageName)); + // Multiple users can install the same package. Each user gets a different Uid for + // the same package. + // + // Here we retrieve the Uid with package name, that will be the Uid for that package + // associated with the current active user. If the Uid differs from the Uid in ops, + // that means this entry belongs to another inactive user and we should ignore that. + if (appInfo.uid == ops.getUid()) { + pref = createRecentLocationEntry( + mPackageManager.getApplicationIcon(appInfo), + mPackageManager.getApplicationLabel(appInfo), + highBattery, + new PackageEntryClickedListener(packageName)); + } else if (Log.isLoggable(TAG, Log.VERBOSE)) { + Log.v(TAG, "package " + packageName + " with Uid " + ops.getUid() + + " belongs to another inactive account, ignored."); + } } catch (PackageManager.NameNotFoundException e) { Log.wtf(TAG, "Package not found: " + packageName); } diff --git a/src/com/android/settings/location/SettingsInjector.java b/src/com/android/settings/location/SettingsInjector.java index 7bd190c..5929466 100644 --- a/src/com/android/settings/location/SettingsInjector.java +++ b/src/com/android/settings/location/SettingsInjector.java @@ -30,6 +30,7 @@ import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.os.Messenger; +import android.os.SystemClock; import android.preference.Preference; import android.util.AttributeSet; import android.util.Log; @@ -42,7 +43,6 @@ import java.io.IOException; import java.util.ArrayList; import java.util.HashSet; import java.util.Iterator; -import java.util.LinkedHashSet; import java.util.List; import java.util.Set; @@ -67,22 +67,6 @@ class SettingsInjector { private static final long INJECTED_STATUS_UPDATE_TIMEOUT_MILLIS = 1000; /** - * Intent action marking the receiver as injecting a setting - */ - public static final String RECEIVER_INTENT = "com.android.settings.InjectedLocationSetting"; - - /** - * Name of the meta-data tag used to specify the resource file that includes the settings - * attributes. - */ - public static final String META_DATA_NAME = "com.android.settings.InjectedLocationSetting"; - - /** - * Name of the XML tag that includes the attributes for the setting. - */ - public static final String ATTRIBUTES_NAME = "injected-location-setting"; - - /** * {@link Message#what} value for starting to load status values * in case we aren't already in the process of loading them. */ @@ -115,7 +99,8 @@ class SettingsInjector { /** * Returns a list with one {@link InjectedSetting} object for each {@link android.app.Service} - * that responds to {@link #RECEIVER_INTENT} and provides the expected setting metadata. + * that responds to {@link SettingInjectorService#ACTION_SERVICE_INTENT} and provides the + * expected setting metadata. * * Duplicates some code from {@link android.content.pm.RegisteredServicesCache}. * @@ -123,37 +108,38 @@ class SettingsInjector { */ private List<InjectedSetting> getSettings() { PackageManager pm = mContext.getPackageManager(); - Intent receiverIntent = new Intent(RECEIVER_INTENT); + Intent intent = new Intent(SettingInjectorService.ACTION_SERVICE_INTENT); List<ResolveInfo> resolveInfos = - pm.queryIntentServices(receiverIntent, PackageManager.GET_META_DATA); + pm.queryIntentServices(intent, PackageManager.GET_META_DATA); if (Log.isLoggable(TAG, Log.DEBUG)) { Log.d(TAG, "Found services: " + resolveInfos); } List<InjectedSetting> settings = new ArrayList<InjectedSetting>(resolveInfos.size()); - for (ResolveInfo receiver : resolveInfos) { + for (ResolveInfo resolveInfo : resolveInfos) { try { - InjectedSetting info = parseServiceInfo(receiver, pm); - if (info == null) { - Log.w(TAG, "Unable to load service info " + receiver); + InjectedSetting setting = parseServiceInfo(resolveInfo, pm); + if (setting == null) { + Log.w(TAG, "Unable to load service info " + resolveInfo); } else { - if (Log.isLoggable(TAG, Log.INFO)) { - Log.i(TAG, "Loaded service info: " + info); - } - settings.add(info); + settings.add(setting); } } catch (XmlPullParserException e) { - Log.w(TAG, "Unable to load service info " + receiver, e); + Log.w(TAG, "Unable to load service info " + resolveInfo, e); } catch (IOException e) { - Log.w(TAG, "Unable to load service info " + receiver, e); + Log.w(TAG, "Unable to load service info " + resolveInfo, e); } } + if (Log.isLoggable(TAG, Log.DEBUG)) { + Log.d(TAG, "Loaded settings: " + settings); + } return settings; } /** - * Parses {@link InjectedSetting} from the attributes of the {@link #META_DATA_NAME} tag. + * Parses {@link InjectedSetting} from the attributes of the + * {@link SettingInjectorService#META_DATA_NAME} tag. * * Duplicates some code from {@link android.content.pm.RegisteredServicesCache}. */ @@ -164,9 +150,9 @@ class SettingsInjector { XmlResourceParser parser = null; try { - parser = si.loadXmlMetaData(pm, META_DATA_NAME); + parser = si.loadXmlMetaData(pm, SettingInjectorService.META_DATA_NAME); if (parser == null) { - throw new XmlPullParserException("No " + META_DATA_NAME + throw new XmlPullParserException("No " + SettingInjectorService.META_DATA_NAME + " meta-data for " + service + ": " + si); } @@ -178,9 +164,9 @@ class SettingsInjector { } String nodeName = parser.getName(); - if (!ATTRIBUTES_NAME.equals(nodeName)) { + if (!SettingInjectorService.ATTRIBUTES_NAME.equals(nodeName)) { throw new XmlPullParserException("Meta-data does not start with " - + ATTRIBUTES_NAME + " tag"); + + SettingInjectorService.ATTRIBUTES_NAME + " tag"); } Resources res = pm.getResourcesForApplication(si.applicationInfo); @@ -201,15 +187,15 @@ class SettingsInjector { private static InjectedSetting parseAttributes( String packageName, String className, Resources res, AttributeSet attrs) { - TypedArray sa = res.obtainAttributes(attrs, android.R.styleable.InjectedLocationSetting); + TypedArray sa = res.obtainAttributes(attrs, android.R.styleable.SettingInjectorService); 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.InjectedLocationSetting_label); + final String label = sa.getString(android.R.styleable.SettingInjectorService_title); final int iconId = sa.getResourceId( - android.R.styleable.InjectedLocationSetting_icon, 0); + android.R.styleable.SettingInjectorService_icon, 0); final String settingsActivity = - sa.getString(android.R.styleable.InjectedLocationSetting_settingsActivity); + sa.getString(android.R.styleable.SettingInjectorService_settingsActivity); if (Log.isLoggable(TAG, Log.DEBUG)) { Log.d(TAG, "parsed label: " + label + ", iconId: " + iconId + ", settingsActivity: " + settingsActivity); @@ -306,6 +292,7 @@ class SettingsInjector { break; case WHAT_RECEIVED_STATUS: final Setting receivedSetting = (Setting) msg.obj; + receivedSetting.maybeLogElapsedTime(); mSettingsBeingLoaded.remove(receivedSetting); mTimedOutSettings.remove(receivedSetting); removeMessages(WHAT_TIMEOUT, receivedSetting); @@ -357,8 +344,7 @@ class SettingsInjector { iter.remove(); // Request the status value - Intent intent = setting.createUpdatingIntent(); - mContext.startService(intent); + setting.startService(); mSettingsBeingLoaded.add(setting); // Ensure that if receiving the status value takes too long, we start loading the @@ -390,6 +376,7 @@ class SettingsInjector { public final InjectedSetting setting; public final Preference preference; + public long startMillis; private Setting(InjectedSetting setting, Preference preference) { this.setting = setting; @@ -406,7 +393,7 @@ class SettingsInjector { /** * Returns true if they both have the same {@link #setting} value. Ignores mutable - * preference so that it's safe to use in sets. + * {@link #preference} and {@link #startMillis} so that it's safe to use in sets. */ @Override public boolean equals(Object o) { @@ -419,11 +406,10 @@ class SettingsInjector { } /** - * Creates an Intent to ask the receiver for the current status for the setting, and display - * it when it replies. + * Starts the service to fetch for the current status for the setting, and updates the + * preference when the service replies. */ - public Intent createUpdatingIntent() { - final Intent receiverIntent = setting.getServiceIntent(); + public void startService() { Handler handler = new Handler() { @Override public void handleMessage(Message msg) { @@ -440,12 +426,25 @@ class SettingsInjector { } }; Messenger messenger = new Messenger(handler); - receiverIntent.putExtra(SettingInjectorService.MESSENGER_KEY, messenger); + + Intent intent = setting.getServiceIntent(); + intent.putExtra(SettingInjectorService.MESSENGER_KEY, messenger); + if (Log.isLoggable(TAG, Log.DEBUG)) { - Log.d(TAG, setting + ": sending rcv-intent: " + receiverIntent + Log.d(TAG, setting + ": sending update intent: " + intent + ", handler: " + handler); + startMillis = SystemClock.elapsedRealtime(); + } else { + startMillis = 0; + } + mContext.startService(intent); + } + + public void maybeLogElapsedTime() { + if (Log.isLoggable(TAG, Log.DEBUG) && startMillis != 0) { + long end = SystemClock.elapsedRealtime(); + Log.d(TAG, this + " update took " + (end - startMillis) + " millis"); } - return receiverIntent; } } } diff --git a/src/com/android/settings/nfc/PaymentBackend.java b/src/com/android/settings/nfc/PaymentBackend.java index 3c2c3ce..e2f110f 100644 --- a/src/com/android/settings/nfc/PaymentBackend.java +++ b/src/com/android/settings/nfc/PaymentBackend.java @@ -22,7 +22,7 @@ import android.content.pm.PackageManager; import android.graphics.drawable.Drawable; import android.nfc.NfcAdapter; import android.nfc.cardemulation.ApduServiceInfo; -import android.nfc.cardemulation.CardEmulationManager; +import android.nfc.cardemulation.CardEmulation; import android.provider.Settings; import java.util.ArrayList; @@ -40,19 +40,19 @@ public class PaymentBackend { private final Context mContext; private final NfcAdapter mAdapter; - private final CardEmulationManager mCardEmuManager; + private final CardEmulation mCardEmuManager; public PaymentBackend(Context context) { mContext = context; mAdapter = NfcAdapter.getDefaultAdapter(context); - mCardEmuManager = CardEmulationManager.getInstance(mAdapter); + mCardEmuManager = CardEmulation.getInstance(mAdapter); } public List<PaymentAppInfo> getPaymentAppInfos() { PackageManager pm = mContext.getPackageManager(); List<ApduServiceInfo> serviceInfos = - mCardEmuManager.getServices(CardEmulationManager.CATEGORY_PAYMENT); + mCardEmuManager.getServices(CardEmulation.CATEGORY_PAYMENT); List<PaymentAppInfo> appInfos = new ArrayList<PaymentAppInfo>(); if (serviceInfos == null) return appInfos; diff --git a/src/com/android/settings/nfc/PaymentDefaultDialog.java b/src/com/android/settings/nfc/PaymentDefaultDialog.java index a6887a3..ae2f4c1 100644 --- a/src/com/android/settings/nfc/PaymentDefaultDialog.java +++ b/src/com/android/settings/nfc/PaymentDefaultDialog.java @@ -22,7 +22,7 @@ import android.content.Intent; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; -import android.nfc.cardemulation.CardEmulationManager; +import android.nfc.cardemulation.CardEmulation; import android.os.Bundle; import android.util.Log; @@ -47,8 +47,8 @@ public final class PaymentDefaultDialog extends AlertActivity implements mBackend = new PaymentBackend(this); Intent intent = getIntent(); ComponentName component = intent.getParcelableExtra( - CardEmulationManager.EXTRA_SERVICE_COMPONENT); - String category = intent.getStringExtra(CardEmulationManager.EXTRA_CATEGORY); + CardEmulation.EXTRA_SERVICE_COMPONENT); + String category = intent.getStringExtra(CardEmulation.EXTRA_CATEGORY); setResult(RESULT_CANCELED); if (!buildDialog(component, category)) { @@ -75,7 +75,7 @@ public final class PaymentDefaultDialog extends AlertActivity implements return false; } - if (!CardEmulationManager.CATEGORY_PAYMENT.equals(category)) { + if (!CardEmulation.CATEGORY_PAYMENT.equals(category)) { Log.e(TAG, "Don't support defaults for category " + category); return false; } diff --git a/src/com/android/settings/nfc/PaymentSettings.java b/src/com/android/settings/nfc/PaymentSettings.java index 41bcc2c..af569ac 100644 --- a/src/com/android/settings/nfc/PaymentSettings.java +++ b/src/com/android/settings/nfc/PaymentSettings.java @@ -55,23 +55,10 @@ public class PaymentSettings extends SettingsPreferenceFragment implements for (PaymentAppInfo appInfo : appInfos) { PaymentAppPreference preference = new PaymentAppPreference(getActivity(), appInfo, this); - // If for some reason isAuto gets out of sync, clear out app default preference.setIcon(appInfo.icon); preference.setTitle(appInfo.caption); screen.addPreference(preference); } - if (appInfos.size() > 1) { - PaymentAppInfo appInfo = new PaymentAppInfo(); - appInfo.icon = null; - appInfo.componentName = null; - appInfo.isDefault = !(mPaymentBackend.getDefaultPaymentApp() != null); - // Add "Ask every time" option - PaymentAppPreference preference = - new PaymentAppPreference(getActivity(), appInfo, this); - preference.setIcon(null); - preference.setTitle(R.string.nfc_payment_ask); - screen.addPreference(preference); - } } setPreferenceScreen(screen); } @@ -82,8 +69,6 @@ public class PaymentSettings extends SettingsPreferenceFragment implements PaymentAppInfo appInfo = (PaymentAppInfo) v.getTag(); if (appInfo.componentName != null) { mPaymentBackend.setDefaultPaymentApp(appInfo.componentName); - } else { - mPaymentBackend.setDefaultPaymentApp(null); } refresh(); } diff --git a/src/com/android/settings/wfd/WifiDisplaySettings.java b/src/com/android/settings/wfd/WifiDisplaySettings.java index 7f560b3..6ec79f3 100755 --- a/src/com/android/settings/wfd/WifiDisplaySettings.java +++ b/src/com/android/settings/wfd/WifiDisplaySettings.java @@ -33,6 +33,7 @@ import android.net.Uri; import android.net.wifi.p2p.WifiP2pManager; import android.net.wifi.p2p.WifiP2pManager.ActionListener; import android.net.wifi.p2p.WifiP2pManager.Channel; +import android.net.wifi.WpsInfo; import android.os.Bundle; import android.os.Handler; import android.os.Looper; @@ -94,6 +95,7 @@ public final class WifiDisplaySettings extends SettingsPreferenceFragment { private PreferenceGroup mCertCategory; private boolean mListen; private boolean mAutoGO; + private int mWpsConfig = WpsInfo.INVALID; private int mListenChannel; private int mOperatingChannel; @@ -160,6 +162,8 @@ public final class WifiDisplaySettings extends SettingsPreferenceFragment { Settings.Global.WIFI_DISPLAY_ON), false, mSettingsObserver); getContentResolver().registerContentObserver(Settings.Global.getUriFor( Settings.Global.WIFI_DISPLAY_CERTIFICATION_ON), false, mSettingsObserver); + getContentResolver().registerContentObserver(Settings.Global.getUriFor( + Settings.Global.WIFI_DISPLAY_WPS_CONFIG), false, mSettingsObserver); mDisplayManager.scanWifiDisplays(); @@ -222,6 +226,8 @@ public final class WifiDisplaySettings extends SettingsPreferenceFragment { Settings.Global.WIFI_DISPLAY_ON, 0) != 0; mWifiDisplayCertificationOn = Settings.Global.getInt(getContentResolver(), Settings.Global.WIFI_DISPLAY_CERTIFICATION_ON, 0) != 0; + mWpsConfig = Settings.Global.getInt(getContentResolver(), + Settings.Global.WIFI_DISPLAY_WPS_CONFIG, WpsInfo.INVALID); mWifiDisplayStatus = mDisplayManager.getWifiDisplayStatus(); applyState(); @@ -367,12 +373,41 @@ public final class WifiDisplaySettings extends SettingsPreferenceFragment { cbp.setChecked(mAutoGO); mCertCategory.addPreference(cbp); - // Drop down list for choosing listen channel + // Drop down list for choosing WPS method (PBC/KEYPAD/DISPLAY) ListPreference lp = new ListPreference(getActivity()) { @Override protected void onDialogClosed(boolean positiveResult) { super.onDialogClosed(positiveResult); if (positiveResult) { + mWpsConfig = Integer.parseInt(getValue()); + setSummary("%1$s"); + getActivity().invalidateOptionsMenu(); + Settings.Global.putInt(getActivity().getContentResolver(), + Settings.Global.WIFI_DISPLAY_WPS_CONFIG, mWpsConfig); + } + } + }; + mWpsConfig = Settings.Global.getInt(getActivity().getContentResolver(), + Settings.Global.WIFI_DISPLAY_WPS_CONFIG, WpsInfo.INVALID); + String[] wpsEntries = { "Default", "PBC", "KEYPAD", "DISPLAY" }; + String[] wpsValues = { + "" + WpsInfo.INVALID, + "" + WpsInfo.PBC, + "" + WpsInfo.KEYPAD, + "" + WpsInfo.DISPLAY }; + lp.setTitle(R.string.wifi_display_wps_config); + lp.setEntries(wpsEntries); + lp.setEntryValues(wpsValues); + lp.setValue("" + mWpsConfig); + lp.setSummary("%1$s"); + mCertCategory.addPreference(lp); + + // Drop down list for choosing listen channel + lp = new ListPreference(getActivity()) { + @Override + protected void onDialogClosed(boolean positiveResult) { + super.onDialogClosed(positiveResult); + if (positiveResult) { mListenChannel = Integer.parseInt(getValue()); setSummary("%1$s"); getActivity().invalidateOptionsMenu(); diff --git a/src/com/android/settings/widget/SettingsAppWidgetProvider.java b/src/com/android/settings/widget/SettingsAppWidgetProvider.java index bf3f497..85a0494 100644 --- a/src/com/android/settings/widget/SettingsAppWidgetProvider.java +++ b/src/com/android/settings/widget/SettingsAppWidgetProvider.java @@ -800,7 +800,7 @@ public class SettingsAppWidgetProvider extends AppWidgetProvider { sWifiState.onActualStateChange(context, intent); } else if (BluetoothAdapter.ACTION_STATE_CHANGED.equals(action)) { sBluetoothState.onActualStateChange(context, intent); - } else if (LocationManager.PROVIDERS_CHANGED_ACTION.equals(action)) { + } else if (LocationManager.MODE_CHANGED_ACTION.equals(action)) { sLocationState.onActualStateChange(context, intent); } else if (ContentResolver.ACTION_SYNC_CONN_STATUS_CHANGED.equals(action)) { sSyncState.onActualStateChange(context, intent); diff --git a/src/com/android/settings/wifi/AccessPoint.java b/src/com/android/settings/wifi/AccessPoint.java index 20146eb..c4d1f7c 100644 --- a/src/com/android/settings/wifi/AccessPoint.java +++ b/src/com/android/settings/wifi/AccessPoint.java @@ -16,6 +16,8 @@ package com.android.settings.wifi; +import com.android.settings.R; + import android.content.Context; import android.net.NetworkInfo.DetailedState; import android.net.wifi.ScanResult; @@ -29,8 +31,6 @@ import android.util.Log; import android.view.View; import android.widget.ImageView; -import com.android.settings.R; - class AccessPoint extends Preference { static final String TAG = "Settings.AccessPoint"; @@ -211,7 +211,8 @@ class AccessPoint extends Preference { signal.setImageDrawable(null); } else { signal.setImageLevel(getLevel()); - signal.setImageResource(R.drawable.wifi_signal); + signal.setImageDrawable(getContext().getTheme().obtainStyledAttributes( + new int[] {R.attr.wifi_signal}).getDrawable(0)); signal.setImageState((security != SECURITY_NONE) ? STATE_SECURED : STATE_NONE, true); } diff --git a/src/com/android/settings/wifi/WifiDialog.java b/src/com/android/settings/wifi/WifiDialog.java index 82b0cc6..f1720c1 100644 --- a/src/com/android/settings/wifi/WifiDialog.java +++ b/src/com/android/settings/wifi/WifiDialog.java @@ -38,7 +38,7 @@ class WifiDialog extends AlertDialog implements WifiConfigUiBase { public WifiDialog(Context context, DialogInterface.OnClickListener listener, AccessPoint accessPoint, boolean edit) { - super(context, R.style.Theme_WifiDialog); + super(context); mEdit = edit; mListener = listener; mAccessPoint = accessPoint; diff --git a/src/com/android/settings/wifi/WifiSettings.java b/src/com/android/settings/wifi/WifiSettings.java index 9fc1010..1caf58b 100644 --- a/src/com/android/settings/wifi/WifiSettings.java +++ b/src/com/android/settings/wifi/WifiSettings.java @@ -19,12 +19,9 @@ package com.android.settings.wifi; import static android.net.wifi.WifiConfiguration.INVALID_NETWORK_ID; import static android.os.UserManager.DISALLOW_CONFIG_WIFI; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.concurrent.atomic.AtomicBoolean; +import com.android.settings.R; +import com.android.settings.RestrictedSettingsFragment; +import com.android.settings.wifi.p2p.WifiP2pSettings; import android.app.ActionBar; import android.app.Activity; @@ -37,6 +34,7 @@ import android.content.Intent; import android.content.IntentFilter; import android.content.pm.PackageManager; import android.content.res.Resources; +import android.content.res.TypedArray; import android.location.LocationManager; import android.net.ConnectivityManager; import android.net.NetworkInfo; @@ -76,9 +74,12 @@ import android.widget.Switch; import android.widget.TextView; import android.widget.Toast; -import com.android.settings.R; -import com.android.settings.RestrictedSettingsFragment; -import com.android.settings.wifi.p2p.WifiP2pSettings; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.concurrent.atomic.AtomicBoolean; /** * Two types of UI are provided here. @@ -134,7 +135,7 @@ public class WifiSettings extends RestrictedSettingsFragment private DetailedState mLastState; private WifiInfo mLastInfo; - private AtomicBoolean mConnected = new AtomicBoolean(false); + private final AtomicBoolean mConnected = new AtomicBoolean(false); private WifiDialog mDialog; @@ -447,10 +448,11 @@ public class WifiSettings extends RestrictedSettingsFragment if (isRestrictedAndNotPinProtected()) return; final boolean wifiIsEnabled = mWifiManager.isWifiEnabled(); + TypedArray ta = getActivity().getTheme().obtainStyledAttributes( + new int[] {R.attr.ic_menu_add, R.attr.ic_wps}); if (mSetupWizardMode) { - // FIXME: add setIcon() when graphics are available menu.add(Menu.NONE, MENU_ID_WPS_PBC, 0, R.string.wifi_menu_wps_pbc) - .setIcon(R.drawable.ic_wps) + .setIcon(ta.getDrawable(1)) .setEnabled(wifiIsEnabled) .setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS); menu.add(Menu.NONE, MENU_ID_ADD_NETWORK, 0, R.string.wifi_add_network) @@ -458,11 +460,11 @@ public class WifiSettings extends RestrictedSettingsFragment .setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS); } else { menu.add(Menu.NONE, MENU_ID_WPS_PBC, 0, R.string.wifi_menu_wps_pbc) - .setIcon(R.drawable.ic_wps) + .setIcon(ta.getDrawable(1)) .setEnabled(wifiIsEnabled) .setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM); menu.add(Menu.NONE, MENU_ID_ADD_NETWORK, 0, R.string.wifi_add_network) - .setIcon(R.drawable.ic_menu_add) + .setIcon(ta.getDrawable(0)) .setEnabled(wifiIsEnabled) .setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM); menu.add(Menu.NONE, MENU_ID_SCAN, 0, R.string.wifi_menu_scan) @@ -481,6 +483,7 @@ public class WifiSettings extends RestrictedSettingsFragment //.setIcon(android.R.drawable.ic_menu_manage) .setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER); } + ta.recycle(); super.onCreateOptionsMenu(menu, inflater); } @@ -808,7 +811,7 @@ public class WifiSettings extends RestrictedSettingsFragment /** A restricted multimap for use in constructAccessPoints */ private class Multimap<K,V> { - private HashMap<K,List<V>> store = new HashMap<K,List<V>>(); + private final HashMap<K,List<V>> store = new HashMap<K,List<V>>(); /** retrieve a non-null list of values with key K */ List<V> getAll(K key) { List<V> values = store.get(key); diff --git a/src/com/android/settings/wifi/WifiSetupActivity.java b/src/com/android/settings/wifi/WifiSetupActivity.java index 8415954..1739750 100644 --- a/src/com/android/settings/wifi/WifiSetupActivity.java +++ b/src/com/android/settings/wifi/WifiSetupActivity.java @@ -17,7 +17,25 @@ package com.android.settings.wifi; import com.android.settings.ButtonBarHandler; -// dummy class for setup wizard theme +import android.content.res.Resources; + public class WifiSetupActivity extends WifiPickerActivity implements ButtonBarHandler { + // Extra containing the resource name of the theme to be used + private static final String EXTRA_THEME = "theme"; + private static final String THEME_HOLO = "holo"; + private static final String THEME_HOLO_LIGHT = "holo_light"; + + // Style resources containing theme settings + private static final String RESOURCE_THEME_DARK = "SetupWizardWifiTheme"; + private static final String RESOURCE_THEME_LIGHT = "SetupWizardWifiTheme.Light"; -}
\ No newline at end of file + @Override + protected void onApplyThemeResource(Resources.Theme theme, int resid, boolean first) { + String themeName = getIntent().getStringExtra(EXTRA_THEME); + if (themeName != null && themeName.equalsIgnoreCase(THEME_HOLO_LIGHT)) { + resid = getResources().getIdentifier(RESOURCE_THEME_LIGHT, "style", + getPackageName()); + } + super.onApplyThemeResource(theme, resid, first); + } +} diff --git a/src/com/android/settings/wifi/p2p/WifiP2pPeer.java b/src/com/android/settings/wifi/p2p/WifiP2pPeer.java index 1eb810e..a364021 100644 --- a/src/com/android/settings/wifi/p2p/WifiP2pPeer.java +++ b/src/com/android/settings/wifi/p2p/WifiP2pPeer.java @@ -20,21 +20,18 @@ import com.android.settings.R; import android.content.Context; import android.net.wifi.WifiManager; -import android.net.wifi.p2p.WifiP2pManager; import android.net.wifi.p2p.WifiP2pDevice; import android.preference.Preference; import android.text.TextUtils; import android.view.View; import android.widget.ImageView; -import java.util.Comparator; - public class WifiP2pPeer extends Preference { private static final int[] STATE_SECURED = {R.attr.state_encrypted}; public WifiP2pDevice device; - private int mRssi; + private final int mRssi; private ImageView mSignal; private static final int SIGNAL_LEVELS = 4; @@ -57,7 +54,7 @@ public class WifiP2pPeer extends Preference { if (mRssi == Integer.MAX_VALUE) { mSignal.setImageDrawable(null); } else { - mSignal.setImageResource(R.drawable.wifi_signal); + mSignal.setImageResource(R.drawable.wifi_signal_dark); mSignal.setImageState(STATE_SECURED, true); } refresh(); |