Merge "Import translations. DO NOT MERGE"
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 807d011..faa20b4 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -1727,7 +1727,8 @@
<activity android:name="RegulatoryInfoDisplayActivity"
android:label="@string/regulatory_information"
android:taskAffinity=""
- android:excludeFromRecents="true">
+ android:excludeFromRecents="true"
+ android:enabled="@bool/config_show_regulatory_info">
<intent-filter>
<action android:name="android.settings.SHOW_REGULATORY_INFO" />
<category android:name="android.intent.category.DEFAULT" />
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 99f6664..c025a94 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -3279,27 +3279,6 @@
<!-- Used to show an amount of time in the form "m minutes, s seconds" in BatteryHistory -->
<string name="battery_history_minutes_no_seconds"><xliff:g id="minutes">%1$d</xliff:g>m</string>
- <!-- [CHAR LIMIT=20] Used to show an amount of time in the form "d days" in BatteryHistory -->
- <string name="battery_history_days_only"><xliff:g id="days">%1$d</xliff:g>d</string>
-
- <!-- [CHAR LIMIT=20] Used to show an amount of time in the form "d days, h hours" in BatteryHistory -->
- <string name="battery_history_days_and_hours"><xliff:g id="days">%1$d</xliff:g>d
- <xliff:g id="hours">%2$d</xliff:g>h</string>
-
- <!-- [CHAR LIMIT=20] Used to show an amount of time in the form "h hours" in BatteryHistory -->
- <string name="battery_history_hours_only"><xliff:g id="hours">%1$d</xliff:g>h</string>
-
- <!-- [CHAR LIMIT=20] Used to show an amount of time in the form "h hours, m minutes" in BatteryHistory -->
- <string name="battery_history_hours_and_minutes"><xliff:g id="hours">%1$d</xliff:g>h
- <xliff:g id="minutes">%2$d</xliff:g>m</string>
-
- <!-- [CHAR LIMIT=20] Used to show an amount of time in the form "m minutes" in BatteryHistory -->
- <string name="battery_history_minutes_only"><xliff:g id="minutes">%1$d</xliff:g>m</string>
-
- <!-- [CHAR LIMIT=20] Used to show an amount of time in the form "m minutes, s seconds" in BatteryHistory -->
- <string name="battery_history_minutes_and_seconds"><xliff:g id="minutes">%1$d</xliff:g>m
- <xliff:g id="seconds">%2$d</xliff:g>s</string>
-
<!-- XXX remove? Strings used for displaying usage statistics -->
<string name="usage_stats_label">Usage statistics</string>
@@ -3590,6 +3569,18 @@
<string name="power_discharge_remaining"><xliff:g id="remain">%1$s</xliff:g> remaining</string>
<!-- Display time remaining until battery is charged [CHAR_LIMIT=60] -->
<string name="power_charge_remaining"><xliff:g id="until_charged">%1$s</xliff:g> to charge</string>
+ <!-- [CHAR_LIMIT=40] Label for battery level chart when discharging -->
+ <string name="power_discharging"><xliff:g id="level">%1$d</xliff:g>%%</string>
+ <!-- [CHAR_LIMIT=40] Label for battery level chart when discharging with duration -->
+ <string name="power_discharging_duration"><xliff:g id="level">%1$d</xliff:g>%%
+ - approx. <xliff:g id="time">%2$s</xliff:g> left</string>
+ <!-- [CHAR_LIMIT=40] Label for battery level chart when charging -->
+ <string name="power_charging"><xliff:g id="level">%1$d</xliff:g>%% -
+ <xliff:g id="state">%2$s</xliff:g></string>
+ <!-- [CHAR_LIMIT=40] Label for battery level chart when charging with duration -->
+ <string name="power_charging_duration"><xliff:g id="level">%1$d</xliff:g>%% -
+ <xliff:g id="state">%2$s</xliff:g>
+ (<xliff:g id="time">%3$s</xliff:g> until full)</string>
<!-- Battery usage since unplugged -->
<string name="battery_since_unplugged">Battery use since unplugged</string>
<!-- Battery usage since user reset the stats -->
@@ -3833,6 +3824,17 @@
<string name="keyboard_settings_title">Android keyboard</string>
<!-- Title for the 'voice input' category of voice input/output settings -->
<string name="voice_category">Speech</string>
+ <!-- Title for the voice interactor setting in voice input/output settings -->
+ <string name="voice_interactor_title">Voice input</string>
+ <!-- Title for the link to settings for the chosen voice interactor in voice input/output
+ settings -->
+ <string name="voice_interactor_settings_title">Voice input</string>
+ <!-- Summary for the link to settings for the chosen voice interactor in voice input/output
+ settings. Would say something like, e.g., "Settings for 'Google'". -->
+ <string name="voice_interactor_settings_summary">Settings for
+ \'<xliff:g id="interactor_name">%s</xliff:g>\'</string>
+ <!-- Label to show for no voice interactor selector -->
+ <string name="no_voice_interactor">None</string>
<!-- Title for the voice recognizer setting in voice input/output settings -->
<string name="recognizer_title">Voice recognizer</string>
<!-- Title for the link to settings for the chosen voice recognizer in voice input/output settings -->
@@ -5145,6 +5147,9 @@
<!-- [CHAR LIMIT=20] Zen mode settings: Master switch option title, on -->
<string name="zen_mode_option_on">On</string>
+ <!-- [CHAR LIMIT=30] Zen mode settings: Exit condition selection dialog, default option -->
+ <string name="zen_mode_default_option">Until you turn this off</string>
+
<!-- [CHAR LIMIT=40] Zen mode settings: General category text -->
<string name="zen_mode_general_category">Block all interruptions except</string>
diff --git a/res/xml/language_settings.xml b/res/xml/language_settings.xml
index 3e7fdb5..c210312 100644
--- a/res/xml/language_settings.xml
+++ b/res/xml/language_settings.xml
@@ -73,6 +73,16 @@
<!-- entries, entryValues, and defaultValue will be populated programmatically. -->
<ListPreference
+ android:key="voice_interactor"
+ android:title="@string/voice_interactor_title"
+ android:dialogTitle="@string/voice_interactor_title" />
+
+ <!-- An intent for this preference will be populated programmatically. -->
+ <PreferenceScreen android:key="voice_interactor_settings"
+ android:title="@string/voice_interactor_settings_title" />
+
+ <!-- entries, entryValues, and defaultValue will be populated programmatically. -->
+ <ListPreference
android:key="recognizer"
android:title="@string/recognizer_title"
android:dialogTitle="@string/recognizer_title" />
diff --git a/src/com/android/settings/ActiveNetworkScorerDialog.java b/src/com/android/settings/ActiveNetworkScorerDialog.java
index 66c9f3f..35d35d1 100644
--- a/src/com/android/settings/ActiveNetworkScorerDialog.java
+++ b/src/com/android/settings/ActiveNetworkScorerDialog.java
@@ -94,7 +94,7 @@
}
newName = pm.getApplicationInfo(mNewPackageName, 0).loadLabel(pm);
} catch (NameNotFoundException e) {
- Log.e(TAG, "Unable to look up package info for scorers", e);
+ Log.e(TAG, "Unable to find package info for scorers", e);
return false;
}
diff --git a/src/com/android/settings/DeviceInfoSettings.java b/src/com/android/settings/DeviceInfoSettings.java
index 7e94741..1e3b9a8 100644
--- a/src/com/android/settings/DeviceInfoSettings.java
+++ b/src/com/android/settings/DeviceInfoSettings.java
@@ -28,6 +28,7 @@
import android.preference.Preference;
import android.preference.PreferenceGroup;
import android.preference.PreferenceScreen;
+import android.provider.Settings;
import android.util.Log;
import android.widget.Toast;
@@ -152,9 +153,14 @@
removePreferenceIfBoolFalse(KEY_UPDATE_SETTING,
R.bool.config_additional_system_update_setting_enable);
- // Remove regulatory information if not enabled.
- removePreferenceIfBoolFalse(KEY_REGULATORY_INFO,
- R.bool.config_show_regulatory_info);
+ // Remove regulatory information if none present.
+ final Intent intent = new Intent(Settings.ACTION_SHOW_REGULATORY_INFO);
+ if (getPackageManager().queryIntentActivities(intent, 0).isEmpty()) {
+ Preference pref = findPreference(KEY_REGULATORY_INFO);
+ if (pref != null) {
+ getPreferenceScreen().removePreference(pref);
+ }
+ }
}
@Override
diff --git a/src/com/android/settings/Utils.java b/src/com/android/settings/Utils.java
index 8abe30d..e3335b8 100644
--- a/src/com/android/settings/Utils.java
+++ b/src/com/android/settings/Utils.java
@@ -444,9 +444,13 @@
}
public static String getBatteryPercentage(Intent batteryChangedIntent) {
+ return String.valueOf(getBatteryLevel(batteryChangedIntent)) + "%";
+ }
+
+ public static int getBatteryLevel(Intent batteryChangedIntent) {
int level = batteryChangedIntent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0);
int scale = batteryChangedIntent.getIntExtra(BatteryManager.EXTRA_SCALE, 100);
- return String.valueOf(level * 100 / scale) + "%";
+ return (level * 100) / scale;
}
public static String getBatteryStatus(Resources res, Intent batteryChangedIntent) {
diff --git a/src/com/android/settings/VoiceInputOutputSettings.java b/src/com/android/settings/VoiceInputOutputSettings.java
index b499deda..64f8a09 100644
--- a/src/com/android/settings/VoiceInputOutputSettings.java
+++ b/src/com/android/settings/VoiceInputOutputSettings.java
@@ -16,6 +16,7 @@
package com.android.settings;
+import android.Manifest;
import android.content.ComponentName;
import android.content.Intent;
import android.content.pm.PackageManager;
@@ -32,6 +33,7 @@
import android.preference.PreferenceScreen;
import android.preference.Preference.OnPreferenceChangeListener;
import android.provider.Settings;
+import android.service.voice.VoiceInteractionService;
import android.speech.RecognitionService;
import android.speech.tts.TtsEngines;
import android.util.AttributeSet;
@@ -53,19 +55,24 @@
private static final String TAG = "VoiceInputOutputSettings";
private static final String KEY_VOICE_CATEGORY = "voice_category";
+ private static final String KEY_VOICE_INTERACTOR = "voice_interactor";
+ private static final String KEY_VOICE_INTERACTOR_SETTINGS = "voice_interactor_settings";
private static final String KEY_RECOGNIZER = "recognizer";
private static final String KEY_RECOGNIZER_SETTINGS = "recognizer_settings";
private static final String KEY_TTS_SETTINGS = "tts_settings";
private PreferenceGroup mParent;
+ private ListPreference mVoiceInteractionPref;
+ private PreferenceScreen mVoiceInteractionSettingsPref;
private PreferenceCategory mVoiceCategory;
private ListPreference mRecognizerPref;
- private Preference mRecognizerSettingsPref;
+ private PreferenceScreen mRecognizerSettingsPref;
private Preference mTtsSettingsPref;
- private PreferenceScreen mSettingsPref;
private final SettingsPreferenceFragment mFragment;
private final TtsEngines mTtsEngines;
+ private HashMap<String, ResolveInfo> mAvailableVoiceInteractionsMap;
+
private HashMap<String, ResolveInfo> mAvailableRecognizersMap;
public VoiceInputOutputSettings(SettingsPreferenceFragment fragment) {
@@ -77,22 +84,28 @@
mParent = mFragment.getPreferenceScreen();
mVoiceCategory = (PreferenceCategory) mParent.findPreference(KEY_VOICE_CATEGORY);
+ mVoiceInteractionPref = (ListPreference) mVoiceCategory.findPreference(
+ KEY_VOICE_INTERACTOR);
+ mVoiceInteractionPref.setOnPreferenceChangeListener(this);
+ mVoiceInteractionSettingsPref = (PreferenceScreen)mVoiceCategory.findPreference(
+ KEY_VOICE_INTERACTOR_SETTINGS);
mRecognizerPref = (ListPreference) mVoiceCategory.findPreference(KEY_RECOGNIZER);
- mRecognizerSettingsPref = mVoiceCategory.findPreference(KEY_RECOGNIZER_SETTINGS);
- mTtsSettingsPref = mVoiceCategory.findPreference(KEY_TTS_SETTINGS);
- mRecognizerPref.setOnPreferenceChangeListener(this);
- mSettingsPref = (PreferenceScreen)
+ mRecognizerSettingsPref = (PreferenceScreen)
mVoiceCategory.findPreference(KEY_RECOGNIZER_SETTINGS);
+ mRecognizerPref.setOnPreferenceChangeListener(this);
+ mTtsSettingsPref = mVoiceCategory.findPreference(KEY_TTS_SETTINGS);
+ mAvailableVoiceInteractionsMap = new HashMap<String, ResolveInfo>();
mAvailableRecognizersMap = new HashMap<String, ResolveInfo>();
populateOrRemovePreferences();
}
private void populateOrRemovePreferences() {
+ boolean hasVoiceInteractionPrefs = populateOrRemoveVoiceInteractionPrefs();
boolean hasRecognizerPrefs = populateOrRemoveRecognizerPrefs();
boolean hasTtsPrefs = populateOrRemoveTtsPrefs();
- if (!hasRecognizerPrefs && !hasTtsPrefs) {
+ if (!hasVoiceInteractionPrefs && !hasRecognizerPrefs && !hasTtsPrefs) {
// There were no TTS settings and no recognizer settings,
// so it should be safe to hide the preference category
// entirely.
@@ -100,6 +113,32 @@
}
}
+ private boolean populateOrRemoveVoiceInteractionPrefs() {
+ List<ResolveInfo> availableVoiceServices =
+ mFragment.getPackageManager().queryIntentServices(
+ new Intent(VoiceInteractionService.SERVICE_INTERFACE),
+ PackageManager.GET_META_DATA);
+ for (int i=0; i<availableVoiceServices.size(); i++) {
+ ResolveInfo ri = availableVoiceServices.get(i);
+ if (!Manifest.permission.BIND_VOICE_INTERACTION.equals(ri.serviceInfo.permission)) {
+ availableVoiceServices.remove(i);
+ }
+ }
+ int numAvailable = availableVoiceServices.size();
+
+ if (numAvailable == 0) {
+ mVoiceCategory.removePreference(mVoiceInteractionPref);
+ mVoiceCategory.removePreference(mVoiceInteractionSettingsPref);
+ return false;
+ }
+
+ populateVoiceInteractionPreference(availableVoiceServices);
+
+ // In this case, there was at least one available recognizer so
+ // we populated the settings.
+ return true;
+ }
+
private boolean populateOrRemoveRecognizerPrefs() {
List<ResolveInfo> availableRecognitionServices =
mFragment.getPackageManager().queryIntentServices(
@@ -128,7 +167,7 @@
String currentSetting = Settings.Secure.getString(
mFragment.getContentResolver(), Settings.Secure.VOICE_RECOGNITION_SERVICE);
- updateSettingsLink(currentSetting);
+ updateRecognizerSettingsLink(currentSetting);
} else {
// Multiple recognizers available, so show the full list of choices.
populateRecognizerPreference(availableRecognitionServices);
@@ -148,6 +187,106 @@
return true;
}
+ private void populateVoiceInteractionPreference(List<ResolveInfo> voiceInteractors) {
+ int size = voiceInteractors.size();
+ CharSequence[] entries = new CharSequence[size+1];
+ CharSequence[] values = new CharSequence[size+1];
+
+ // Get the current value from the secure setting.
+ String currentSetting = Settings.Secure.getString(
+ mFragment.getContentResolver(), Settings.Secure.VOICE_INTERACTION_SERVICE);
+
+ // Iterate through all the available recognizers and load up their info to show
+ // in the preference. Also build up a map of recognizer component names to their
+ // ResolveInfos - we'll need that a little later.
+ for (int i = 0; i < size; i++) {
+ ResolveInfo resolveInfo = voiceInteractors.get(i);
+ String recognizerComponent =
+ new ComponentName(resolveInfo.serviceInfo.packageName,
+ resolveInfo.serviceInfo.name).flattenToShortString();
+
+ mAvailableVoiceInteractionsMap.put(recognizerComponent, resolveInfo);
+
+ entries[i] = resolveInfo.loadLabel(mFragment.getPackageManager());
+ values[i] = recognizerComponent;
+ }
+
+ entries[size] = mFragment.getString(R.string.no_voice_interactor);
+ values[size] = "";
+
+ mVoiceInteractionPref.setEntries(entries);
+ mVoiceInteractionPref.setEntryValues(values);
+
+ mVoiceInteractionPref.setDefaultValue(currentSetting);
+ mVoiceInteractionPref.setValue(currentSetting);
+
+ updateVoiceInteractionSettingsLink(currentSetting);
+ }
+
+ private void updateVoiceInteractionSettingsLink(String currentSetting) {
+ ResolveInfo currentRecognizer = mAvailableVoiceInteractionsMap.get(currentSetting);
+ if (currentRecognizer == null) {
+ mVoiceInteractionPref.setSummary(mFragment.getString(R.string.no_voice_interactor));
+ mVoiceInteractionPref.setValue("");
+ return;
+ }
+
+ ServiceInfo si = currentRecognizer.serviceInfo;
+ XmlResourceParser parser = null;
+ String settingsActivity = null;
+ try {
+ parser = si.loadXmlMetaData(mFragment.getPackageManager(),
+ VoiceInteractionService.SERVICE_META_DATA);
+ if (parser == null) {
+ throw new XmlPullParserException("No " + VoiceInteractionService.SERVICE_META_DATA +
+ " meta-data for " + si.packageName);
+ }
+
+ Resources res = mFragment.getPackageManager().getResourcesForApplication(
+ si.applicationInfo);
+
+ AttributeSet attrs = Xml.asAttributeSet(parser);
+
+ int type;
+ while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
+ && type != XmlPullParser.START_TAG) {
+ }
+
+ String nodeName = parser.getName();
+ if (!"voice-interaction-service".equals(nodeName)) {
+ throw new XmlPullParserException(
+ "Meta-data does not start with voice-interaction-service tag");
+ }
+
+ TypedArray array = res.obtainAttributes(attrs,
+ com.android.internal.R.styleable.VoiceInteractionService);
+ settingsActivity = array.getString(
+ com.android.internal.R.styleable.VoiceInteractionService_settingsActivity);
+ array.recycle();
+ } catch (XmlPullParserException e) {
+ Log.e(TAG, "error parsing recognition service meta-data", e);
+ } catch (IOException e) {
+ Log.e(TAG, "error parsing recognition service meta-data", e);
+ } catch (NameNotFoundException e) {
+ Log.e(TAG, "error parsing recognition service meta-data", e);
+ } finally {
+ if (parser != null) parser.close();
+ }
+
+ mVoiceInteractionPref.setSummary(currentRecognizer.loadLabel(
+ mFragment.getPackageManager()));
+ mVoiceInteractionPref.setValue(currentSetting);
+
+ if (settingsActivity == null) {
+ // No settings preference available - hide the preference.
+ Log.w(TAG, "no recognizer settings available for " + si.packageName);
+ } else {
+ Intent i = new Intent(Intent.ACTION_MAIN);
+ i.setComponent(new ComponentName(si.packageName, settingsActivity));
+ mVoiceInteractionSettingsPref.setIntent(i);
+ }
+ }
+
private void populateRecognizerPreference(List<ResolveInfo> recognizers) {
int size = recognizers.size();
CharSequence[] entries = new CharSequence[size];
@@ -178,10 +317,10 @@
mRecognizerPref.setDefaultValue(currentSetting);
mRecognizerPref.setValue(currentSetting);
- updateSettingsLink(currentSetting);
+ updateRecognizerSettingsLink(currentSetting);
}
-
- private void updateSettingsLink(String currentSetting) {
+
+ private void updateRecognizerSettingsLink(String currentSetting) {
ResolveInfo currentRecognizer = mAvailableRecognizersMap.get(currentSetting);
if (currentRecognizer == null) return;
@@ -230,18 +369,29 @@
if (settingsActivity == null) {
// No settings preference available - hide the preference.
Log.w(TAG, "no recognizer settings available for " + si.packageName);
- mSettingsPref.setIntent(null);
- mVoiceCategory.removePreference(mSettingsPref);
+ mRecognizerSettingsPref.setIntent(null);
+ mVoiceCategory.removePreference(mRecognizerSettingsPref);
} else {
Intent i = new Intent(Intent.ACTION_MAIN);
i.setComponent(new ComponentName(si.packageName, settingsActivity));
- mSettingsPref.setIntent(i);
+ mRecognizerSettingsPref.setIntent(i);
mRecognizerPref.setSummary(currentRecognizer.loadLabel(mFragment.getPackageManager()));
}
}
-
+
public boolean onPreferenceChange(Preference preference, Object newValue) {
- if (preference == mRecognizerPref) {
+ if (preference == mVoiceInteractionPref) {
+ String setting = (String) newValue;
+
+ // Put the new value back into secure settings.
+ Settings.Secure.putString(mFragment.getContentResolver(),
+ Settings.Secure.VOICE_INTERACTION_SERVICE,
+ setting);
+
+ // Update the settings item so it points to the right settings.
+ updateVoiceInteractionSettingsLink(setting);
+
+ } else if (preference == mRecognizerPref) {
String setting = (String) newValue;
// Put the new value back into secure settings.
@@ -250,7 +400,7 @@
setting);
// Update the settings item so it points to the right settings.
- updateSettingsLink(setting);
+ updateRecognizerSettingsLink(setting);
}
return true;
}
diff --git a/src/com/android/settings/fuelgauge/BatteryHistoryChart.java b/src/com/android/settings/fuelgauge/BatteryHistoryChart.java
index 58471a3..da6729c 100644
--- a/src/com/android/settings/fuelgauge/BatteryHistoryChart.java
+++ b/src/com/android/settings/fuelgauge/BatteryHistoryChart.java
@@ -18,6 +18,7 @@
import android.content.Intent;
import android.os.BatteryManager;
+import android.text.format.Formatter;
import com.android.settings.R;
import android.content.Context;
@@ -413,24 +414,36 @@
//mDurationString = getContext().getString(R.string.battery_stats_on_battery,
// durationString);
mDurationString = Utils.formatElapsedTime(getContext(), mHistEnd - mHistStart, true);
- mDrainString = com.android.settings.Utils.getBatteryPercentage(mBatteryBroadcast);
- mChargeLabelString = com.android.settings.Utils.getBatteryStatus(getResources(),
- mBatteryBroadcast);
- final long drainTime = mStats.computeBatteryTimeRemaining(elapsedRealtimeUs);
- final long chargeTime = mStats.computeChargeTimeRemaining(elapsedRealtimeUs);
+ int batteryLevel = com.android.settings.Utils.getBatteryLevel(mBatteryBroadcast);
final int status = mBatteryBroadcast.getIntExtra(BatteryManager.EXTRA_STATUS,
BatteryManager.BATTERY_STATUS_UNKNOWN);
- if (drainTime > 0) {
- String timeString = Utils.formatShortElapsedTime(getContext(),drainTime / 1000);
- mChargeDurationString = getContext().getResources().getString(
- R.string.power_discharge_remaining, timeString);
- } else if (chargeTime > 0 && status != BatteryManager.BATTERY_STATUS_FULL) {
- String timeString = Utils.formatShortElapsedTime(getContext(), chargeTime / 1000);
- mChargeDurationString = getContext().getResources().getString(
- R.string.power_charge_remaining, timeString);
+ if (status == BatteryManager.BATTERY_STATUS_DISCHARGING) {
+ final long drainTime = mStats.computeBatteryTimeRemaining(elapsedRealtimeUs);
+ if (drainTime > 0) {
+ String timeString = Formatter.formatShortElapsedTime(getContext(),
+ drainTime / 1000);
+ mChargeLabelString = getContext().getResources().getString(
+ R.string.power_discharging_duration, batteryLevel, timeString);
+ } else {
+ mChargeLabelString = getContext().getResources().getString(
+ R.string.power_discharging, batteryLevel);
+ }
} else {
- mChargeDurationString = "";
+ final long chargeTime = mStats.computeChargeTimeRemaining(elapsedRealtimeUs);
+ final String statusLabel = com.android.settings.Utils.getBatteryStatus(getResources(),
+ mBatteryBroadcast);
+ if (chargeTime > 0 && status != BatteryManager.BATTERY_STATUS_FULL) {
+ String timeString = Formatter.formatShortElapsedTime(getContext(),
+ chargeTime / 1000);
+ mChargeLabelString = getContext().getResources().getString(
+ R.string.power_charging_duration, batteryLevel, statusLabel, timeString);
+ } else {
+ mChargeLabelString = getContext().getResources().getString(
+ R.string.power_charging, batteryLevel, statusLabel);
+ }
}
+ mDrainString = "";
+ mChargeDurationString = "";
}
@Override
diff --git a/src/com/android/settings/fuelgauge/Utils.java b/src/com/android/settings/fuelgauge/Utils.java
index c88b0d2..9a06c9f 100644
--- a/src/com/android/settings/fuelgauge/Utils.java
+++ b/src/com/android/settings/fuelgauge/Utils.java
@@ -81,45 +81,4 @@
}
return sb.toString();
}
-
- /**
- * Returns elapsed time for the given millis, in the following format:
- * 2d 5h; will include at most two units, can go down to seconds precision.
- * @param context the application context
- * @param millis the elapsed time in milli seconds
- * @return the formatted elapsed time
- */
- public static String formatShortElapsedTime(Context context, double millis) {
- int seconds = (int) Math.floor(millis / 1000);
-
- int days = 0, hours = 0, minutes = 0;
- if (seconds >= SECONDS_PER_DAY) {
- days = seconds / SECONDS_PER_DAY;
- seconds -= days * SECONDS_PER_DAY;
- }
- if (seconds >= SECONDS_PER_HOUR) {
- hours = seconds / SECONDS_PER_HOUR;
- seconds -= hours * SECONDS_PER_HOUR;
- }
- if (seconds >= SECONDS_PER_MINUTE) {
- minutes = seconds / SECONDS_PER_MINUTE;
- seconds -= minutes * SECONDS_PER_MINUTE;
- }
- if (days >= 4) {
- return context.getString(R.string.battery_history_days_only, days);
- } else if (days > 0) {
- return context.getString(R.string.battery_history_days_and_hours, days, hours);
- } else if (hours >= 12) {
- return context.getString(R.string.battery_history_hours_only, hours);
- } else if (hours > 0) {
- return context.getString(R.string.battery_history_hours_and_minutes, hours, minutes);
- } else if (minutes >= 10) {
- return context.getString(R.string.battery_history_minutes_only, minutes);
- } else if (minutes > 0) {
- return context.getString(R.string.battery_history_minutes_and_seconds, minutes,
- seconds);
- } else {
- return context.getString(R.string.battery_history_seconds, seconds);
- }
- }
}
diff --git a/src/com/android/settings/notification/AppNotificationSettings.java b/src/com/android/settings/notification/AppNotificationSettings.java
index 172557d..c63ae63 100644
--- a/src/com/android/settings/notification/AppNotificationSettings.java
+++ b/src/com/android/settings/notification/AppNotificationSettings.java
@@ -114,6 +114,12 @@
}
@Override
+ public void onDestroyView() {
+ super.onDestroyView();
+ mListViewState = null; // you're dead to me
+ }
+
+ @Override
public void onResume() {
super.onResume();
loadAppsList();
diff --git a/src/com/android/settings/notification/ZenModeConditionSelection.java b/src/com/android/settings/notification/ZenModeConditionSelection.java
new file mode 100644
index 0000000..031d785
--- /dev/null
+++ b/src/com/android/settings/notification/ZenModeConditionSelection.java
@@ -0,0 +1,133 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.notification;
+
+import android.animation.LayoutTransition;
+import android.app.INotificationManager;
+import android.content.Context;
+import android.net.Uri;
+import android.os.Handler;
+import android.os.Message;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.service.notification.Condition;
+import android.service.notification.IConditionListener;
+import android.util.Log;
+import android.widget.CompoundButton;
+import android.widget.RadioButton;
+import android.widget.RadioGroup;
+
+import com.android.settings.R;
+
+public class ZenModeConditionSelection extends RadioGroup {
+ private static final String TAG = "ZenModeConditionSelection";
+ private static final boolean DEBUG = true;
+
+ private final INotificationManager mNoMan;
+ private final H mHandler = new H();
+ private final Context mContext;
+
+ public ZenModeConditionSelection(Context context) {
+ super(context);
+ mContext = context;
+ setLayoutTransition(new LayoutTransition());
+ final int p = mContext.getResources().getDimensionPixelSize(R.dimen.content_margin_left);
+ setPadding(p, p, p, 0);
+ mNoMan = INotificationManager.Stub.asInterface(
+ ServiceManager.getService(Context.NOTIFICATION_SERVICE));
+ final RadioButton b = newRadioButton(null);
+ b.setText(R.string.zen_mode_default_option);
+ b.setChecked(true);
+ }
+
+ private RadioButton newRadioButton(Object tag) {
+ final RadioButton button = new RadioButton(mContext);
+ button.setTag(tag);
+ button.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
+ @Override
+ public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+ if (isChecked) {
+ handleSubscribe((Uri)button.getTag());
+ }
+ }
+ });
+ addView(button);
+ return button;
+ }
+
+ @Override
+ protected void onAttachedToWindow() {
+ super.onAttachedToWindow();
+ requestZenModeConditions(true);
+ }
+
+ @Override
+ protected void onDetachedFromWindow() {
+ super.onDetachedFromWindow();
+ requestZenModeConditions(false);
+ }
+
+ protected void requestZenModeConditions(boolean requested) {
+ if (DEBUG) Log.d(TAG, "requestZenModeConditions " + requested);
+ try {
+ mNoMan.requestZenModeConditions(mListener, requested);
+ } catch (RemoteException e) {
+ // noop
+ }
+ }
+
+ protected void handleConditions(Condition[] conditions) {
+ for (final Condition c : conditions) {
+ RadioButton v = (RadioButton) findViewWithTag(c.id);
+ if (c.state == Condition.STATE_FALSE || c.state == Condition.STATE_UNKNOWN) {
+ if (v == null) {
+ v = newRadioButton(c.id);
+ }
+ }
+ if (v != null) {
+ v.setText(c.caption);
+ v.setEnabled(c.state == Condition.STATE_FALSE);
+ }
+ }
+ }
+
+ protected void handleSubscribe(Uri id) {
+ if (DEBUG) Log.d(TAG, "handleSubscribe " + id);
+ try {
+ mNoMan.setZenModeCondition(id);
+ } catch (RemoteException e) {
+ // noop
+ }
+ }
+
+ private final IConditionListener mListener = new IConditionListener.Stub() {
+ @Override
+ public void onConditionsReceived(Condition[] conditions) {
+ if (conditions == null || conditions.length == 0) return;
+ mHandler.obtainMessage(H.CONDITIONS, conditions).sendToTarget();
+ }
+ };
+
+ private final class H extends Handler {
+ private static final int CONDITIONS = 1;
+
+ @Override
+ public void handleMessage(Message msg) {
+ if (msg.what == CONDITIONS) handleConditions((Condition[])msg.obj);
+ }
+ }
+}
diff --git a/src/com/android/settings/notification/ZenModeSettings.java b/src/com/android/settings/notification/ZenModeSettings.java
index 26fa539..a5c720f 100644
--- a/src/com/android/settings/notification/ZenModeSettings.java
+++ b/src/com/android/settings/notification/ZenModeSettings.java
@@ -16,12 +16,14 @@
package com.android.settings.notification;
+import android.app.AlertDialog;
import android.app.Dialog;
import android.app.DialogFragment;
import android.app.FragmentManager;
import android.app.INotificationManager;
import android.app.TimePickerDialog;
import android.content.Context;
+import android.content.DialogInterface;
import android.content.res.Resources;
import android.database.ContentObserver;
import android.graphics.Typeface;
@@ -80,6 +82,7 @@
private DropDownPreference mWhen;
private TimePickerPreference mStart;
private TimePickerPreference mEnd;
+ private AlertDialog mDialog;
@Override
public void onCreate(Bundle icicle) {
@@ -292,6 +295,46 @@
}
}
+ protected void putZenModeSetting(int value) {
+ Global.putInt(getContentResolver(), Global.ZEN_MODE, value);
+ }
+
+ protected ZenModeConditionSelection newConditionSelection() {
+ return new ZenModeConditionSelection(mContext);
+ }
+
+ private final Runnable mHideDialog = new Runnable() {
+ @Override
+ public void run() {
+ if (mDialog != null) {
+ mDialog.dismiss();
+ mDialog = null;
+ }
+ }
+ };
+
+ private final Runnable mShowDialog = new Runnable() {
+ @Override
+ public void run() {
+ mDialog = new AlertDialog.Builder(mContext)
+ .setTitle(R.string.zen_mode_settings_title)
+ .setView(newConditionSelection())
+ .setNegativeButton(R.string.dlg_cancel, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ putZenModeSetting(Global.ZEN_MODE_OFF);
+ }
+ })
+ .setPositiveButton(R.string.dlg_ok, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ // noop
+ }
+ })
+ .show();
+ }
+ };
+
private final OnPreferenceChangeListener mSwitchListener = new OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
@@ -300,7 +343,8 @@
@Override
public void run() {
final int v = isChecked ? Global.ZEN_MODE_ON : Global.ZEN_MODE_OFF;
- Global.putInt(getContentResolver(), Global.ZEN_MODE, v);
+ putZenModeSetting(v);
+ mHandler.post(isChecked ? mShowDialog : mHideDialog);
}
});
return true;