2 * Copyright (C) 2012 The CyanogenMod Project
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 package com.android.settings.notificationlight;
19 import android.app.AlertDialog;
20 import android.app.Dialog;
21 import android.content.ContentResolver;
22 import android.content.Context;
23 import android.content.DialogInterface;
24 import android.content.pm.PackageInfo;
25 import android.content.pm.PackageManager;
26 import android.content.pm.PackageManager.NameNotFoundException;
27 import android.content.res.Resources;
28 import android.graphics.drawable.Drawable;
29 import android.os.Bundle;
30 import android.preference.Preference;
31 import android.preference.PreferenceGroup;
32 import android.preference.PreferenceScreen;
33 import android.provider.Settings;
34 import android.telephony.TelephonyManager;
35 import android.text.TextUtils;
36 import android.view.Menu;
37 import android.view.MenuInflater;
38 import android.view.MenuItem;
39 import android.view.View;
40 import android.widget.AdapterView;
41 import android.widget.AdapterView.OnItemClickListener;
42 import android.widget.ListView;
44 import com.android.settings.R;
45 import com.android.settings.SettingsPreferenceFragment;
46 import com.android.settings.cyanogenmod.CMSystemSettingSwitchPreference;
47 import com.android.settings.cyanogenmod.PackageListAdapter;
48 import com.android.settings.cyanogenmod.PackageListAdapter.PackageItem;
49 import com.android.settings.cyanogenmod.SystemSettingSwitchPreference;
51 import org.cyanogenmod.internal.logging.CMMetricsLogger;
53 import java.util.ArrayList;
54 import java.util.HashMap;
55 import java.util.List;
58 import cyanogenmod.providers.CMSettings;
59 import cyanogenmod.util.ColorUtils;
61 public class NotificationLightSettings extends SettingsPreferenceFragment implements
62 Preference.OnPreferenceChangeListener, AdapterView.OnItemLongClickListener {
63 private static final String TAG = "NotificationLightSettings";
64 private static final String DEFAULT_PREF = "default";
65 private static final String MISSED_CALL_PREF = "missed_call";
66 private static final String VOICEMAIL_PREF = "voicemail";
67 public static final int ACTION_TEST = 0;
68 public static final int ACTION_DELETE = 1;
69 private static final int MENU_ADD = 0;
70 private static final int DIALOG_APPS = 0;
72 private int mDefaultColor;
73 private int mDefaultLedOn;
74 private int mDefaultLedOff;
75 private PackageManager mPackageManager;
76 private PreferenceGroup mApplicationPrefList;
77 private PreferenceScreen mNotificationLedBrightnessPref;
78 private SystemSettingSwitchPreference mEnabledPref;
79 private CMSystemSettingSwitchPreference mCustomEnabledPref;
80 private CMSystemSettingSwitchPreference mMultipleLedsEnabledPref;
81 private CMSystemSettingSwitchPreference mScreenOnLightsPref;
82 private CMSystemSettingSwitchPreference mAutoGenerateColors;
83 private ApplicationLightPreference mDefaultPref;
84 private ApplicationLightPreference mCallPref;
85 private ApplicationLightPreference mVoicemailPref;
87 private PackageListAdapter mPackageAdapter;
88 private String mPackageList;
89 private Map<String, Package> mPackages;
90 private boolean mMultiColorLed;
93 public void onCreate(Bundle savedInstanceState) {
94 super.onCreate(savedInstanceState);
95 addPreferencesFromResource(R.xml.notification_light_settings);
97 PreferenceScreen prefSet = getPreferenceScreen();
98 Resources resources = getResources();
100 PreferenceGroup mAdvancedPrefs = (PreferenceGroup) prefSet.findPreference("advanced_section");
102 // Get the system defined default notification color
104 resources.getColor(com.android.internal.R.color.config_defaultNotificationColor, null);
106 mDefaultLedOn = resources.getInteger(
107 com.android.internal.R.integer.config_defaultNotificationLedOn);
108 mDefaultLedOff = resources.getInteger(
109 com.android.internal.R.integer.config_defaultNotificationLedOff);
111 mEnabledPref = (SystemSettingSwitchPreference)
112 findPreference(Settings.System.NOTIFICATION_LIGHT_PULSE);
113 mEnabledPref.setOnPreferenceChangeListener(this);
115 mDefaultPref = (ApplicationLightPreference) findPreference(DEFAULT_PREF);
116 mDefaultPref.setOnPreferenceChangeListener(this);
118 mAutoGenerateColors = (CMSystemSettingSwitchPreference)
119 findPreference(CMSettings.System.NOTIFICATION_LIGHT_COLOR_AUTO);
121 // Advanced light settings
122 mNotificationLedBrightnessPref = (PreferenceScreen)
123 findPreference(CMSettings.System.NOTIFICATION_LIGHT_BRIGHTNESS_LEVEL);
124 mMultipleLedsEnabledPref = (CMSystemSettingSwitchPreference)
125 findPreference(CMSettings.System.NOTIFICATION_LIGHT_MULTIPLE_LEDS_ENABLE);
126 mScreenOnLightsPref = (CMSystemSettingSwitchPreference)
127 findPreference(CMSettings.System.NOTIFICATION_LIGHT_SCREEN_ON);
128 mScreenOnLightsPref.setOnPreferenceChangeListener(this);
129 mCustomEnabledPref = (CMSystemSettingSwitchPreference)
130 findPreference(CMSettings.System.NOTIFICATION_LIGHT_PULSE_CUSTOM_ENABLE);
131 mCustomEnabledPref.setOnPreferenceChangeListener(this);
132 if (!resources.getBoolean(
133 org.cyanogenmod.platform.internal.R.bool.config_adjustableNotificationLedBrightness)) {
134 mAdvancedPrefs.removePreference(mNotificationLedBrightnessPref);
136 mNotificationLedBrightnessPref.setOnPreferenceChangeListener(this);
138 if (!resources.getBoolean(
139 org.cyanogenmod.platform.internal.R.bool.config_multipleNotificationLeds)) {
140 mAdvancedPrefs.removePreference(mMultipleLedsEnabledPref);
142 mMultipleLedsEnabledPref.setOnPreferenceChangeListener(this);
145 // Missed call and Voicemail preferences should only show on devices with a voice capabilities
146 TelephonyManager tm = (TelephonyManager) getActivity().getSystemService(Context.TELEPHONY_SERVICE);
147 if (tm.getPhoneType() == TelephonyManager.PHONE_TYPE_NONE) {
148 removePreference("phone_list");
150 mCallPref = (ApplicationLightPreference) findPreference(MISSED_CALL_PREF);
151 mCallPref.setOnPreferenceChangeListener(this);
153 mVoicemailPref = (ApplicationLightPreference) findPreference(VOICEMAIL_PREF);
154 mVoicemailPref.setOnPreferenceChangeListener(this);
157 mApplicationPrefList = (PreferenceGroup) findPreference("applications_list");
158 mApplicationPrefList.setOrderingAsAdded(false);
160 // Get launch-able applications
161 mPackageManager = getPackageManager();
162 mPackageAdapter = new PackageListAdapter(getActivity());
164 mPackages = new HashMap<String, Package>();
165 setHasOptionsMenu(true);
167 mMultiColorLed = resources.getBoolean(com.android.internal.R.bool.config_multiColorNotificationLed);
168 if (!mMultiColorLed) {
170 PreferenceGroup mGeneralPrefs = (PreferenceGroup) prefSet.findPreference("general_section");
171 mGeneralPrefs.removePreference(mAutoGenerateColors);
173 mAutoGenerateColors.setOnPreferenceChangeListener(this);
178 protected int getMetricsCategory() {
179 return CMMetricsLogger.NOTIFICATION_LIGHT_SETTINGS;
183 public void onResume() {
186 refreshCustomApplicationPrefs();
187 getListView().setOnItemLongClickListener(this);
188 getActivity().invalidateOptionsMenu();
192 public void onStart() {
194 setChildrenStarted(getPreferenceScreen(), true);
198 public void onStop() {
200 setChildrenStarted(getPreferenceScreen(), false);
203 private void setChildrenStarted(PreferenceGroup group, boolean started) {
204 final int count = group.getPreferenceCount();
205 for (int i = 0; i < count; i++) {
206 Preference pref = group.getPreference(i);
207 if (pref instanceof ApplicationLightPreference) {
208 ApplicationLightPreference ap = (ApplicationLightPreference) pref;
214 } else if (pref instanceof PreferenceGroup) {
215 setChildrenStarted((PreferenceGroup) pref, started);
220 private void refreshDefault() {
221 ContentResolver resolver = getContentResolver();
222 int color = CMSettings.System.getInt(resolver,
223 CMSettings.System.NOTIFICATION_LIGHT_PULSE_DEFAULT_COLOR, mDefaultColor);
224 int timeOn = CMSettings.System.getInt(resolver,
225 CMSettings.System.NOTIFICATION_LIGHT_PULSE_DEFAULT_LED_ON, mDefaultLedOn);
226 int timeOff = CMSettings.System.getInt(resolver,
227 CMSettings.System.NOTIFICATION_LIGHT_PULSE_DEFAULT_LED_OFF, mDefaultLedOff);
229 mDefaultPref.setAllValues(color, timeOn, timeOff);
231 // Get Missed call and Voicemail values
232 if (mCallPref != null) {
233 int callColor = CMSettings.System.getInt(resolver,
234 CMSettings.System.NOTIFICATION_LIGHT_PULSE_CALL_COLOR, mDefaultColor);
235 int callTimeOn = CMSettings.System.getInt(resolver,
236 CMSettings.System.NOTIFICATION_LIGHT_PULSE_CALL_LED_ON, mDefaultLedOn);
237 int callTimeOff = CMSettings.System.getInt(resolver,
238 CMSettings.System.NOTIFICATION_LIGHT_PULSE_CALL_LED_OFF, mDefaultLedOff);
240 mCallPref.setAllValues(callColor, callTimeOn, callTimeOff);
243 if (mVoicemailPref != null) {
244 int vmailColor = CMSettings.System.getInt(resolver,
245 CMSettings.System.NOTIFICATION_LIGHT_PULSE_VMAIL_COLOR, mDefaultColor);
246 int vmailTimeOn = CMSettings.System.getInt(resolver,
247 CMSettings.System.NOTIFICATION_LIGHT_PULSE_VMAIL_LED_ON, mDefaultLedOn);
248 int vmailTimeOff = CMSettings.System.getInt(resolver,
249 CMSettings.System.NOTIFICATION_LIGHT_PULSE_VMAIL_LED_OFF, mDefaultLedOff);
251 mVoicemailPref.setAllValues(vmailColor, vmailTimeOn, vmailTimeOff);
254 mApplicationPrefList = (PreferenceGroup) findPreference("applications_list");
255 mApplicationPrefList.setOrderingAsAdded(false);
258 private void refreshCustomApplicationPrefs() {
259 Context context = getActivity();
261 if (!parsePackageList()) {
265 // Add the Application Preferences
266 if (mApplicationPrefList != null) {
267 mApplicationPrefList.removeAll();
269 for (Package pkg : mPackages.values()) {
271 PackageInfo info = mPackageManager.getPackageInfo(pkg.name,
272 PackageManager.GET_META_DATA);
273 ApplicationLightPreference pref =
274 new ApplicationLightPreference(context, pkg.color, pkg.timeon, pkg.timeoff);
276 pref.setKey(pkg.name);
277 pref.setTitle(info.applicationInfo.loadLabel(mPackageManager));
278 pref.setIcon(info.applicationInfo.loadIcon(mPackageManager));
279 pref.setPersistent(false);
280 pref.setOnPreferenceChangeListener(this);
282 mApplicationPrefList.addPreference(pref);
283 } catch (NameNotFoundException e) {
290 private int getInitialColorForPackage(String packageName) {
291 boolean autoColor = CMSettings.System.getInt(getContentResolver(),
292 CMSettings.System.NOTIFICATION_LIGHT_COLOR_AUTO, mMultiColorLed ? 1 : 0) == 1;
293 int color = mDefaultColor;
296 Drawable icon = mPackageManager.getApplicationIcon(packageName);
297 color = ColorUtils.generateAlertColorFromDrawable(icon);
298 } catch (NameNotFoundException e) {
299 // shouldn't happen, but just return default
305 private void addCustomApplicationPref(String packageName) {
306 Package pkg = mPackages.get(packageName);
308 int color = getInitialColorForPackage(packageName);
309 pkg = new Package(packageName, color, mDefaultLedOn, mDefaultLedOff);
310 mPackages.put(packageName, pkg);
311 savePackageList(false);
312 refreshCustomApplicationPrefs();
316 private void removeCustomApplicationPref(String packageName) {
317 if (mPackages.remove(packageName) != null) {
318 savePackageList(false);
319 refreshCustomApplicationPrefs();
323 private boolean parsePackageList() {
324 final String baseString = CMSettings.System.getString(getContentResolver(),
325 CMSettings.System.NOTIFICATION_LIGHT_PULSE_CUSTOM_VALUES);
327 if (TextUtils.equals(mPackageList, baseString)) {
331 mPackageList = baseString;
334 if (baseString != null) {
335 final String[] array = TextUtils.split(baseString, "\\|");
336 for (String item : array) {
337 if (TextUtils.isEmpty(item)) {
340 Package pkg = Package.fromString(item);
342 mPackages.put(pkg.name, pkg);
350 private void savePackageList(boolean preferencesUpdated) {
351 List<String> settings = new ArrayList<String>();
352 for (Package app : mPackages.values()) {
353 settings.add(app.toString());
355 final String value = TextUtils.join("|", settings);
356 if (preferencesUpdated) {
357 mPackageList = value;
359 CMSettings.System.putString(getContentResolver(),
360 CMSettings.System.NOTIFICATION_LIGHT_PULSE_CUSTOM_VALUES, value);
364 * Updates the default or package specific notification settings.
366 * @param packageName Package name of application specific settings to update
371 protected void updateValues(String packageName, Integer color, Integer timeon, Integer timeoff) {
372 ContentResolver resolver = getContentResolver();
374 if (packageName.equals(DEFAULT_PREF)) {
375 CMSettings.System.putInt(resolver, CMSettings.System.NOTIFICATION_LIGHT_PULSE_DEFAULT_COLOR, color);
376 CMSettings.System.putInt(resolver, CMSettings.System.NOTIFICATION_LIGHT_PULSE_DEFAULT_LED_ON, timeon);
377 CMSettings.System.putInt(resolver, CMSettings.System.NOTIFICATION_LIGHT_PULSE_DEFAULT_LED_OFF, timeoff);
380 } else if (packageName.equals(MISSED_CALL_PREF)) {
381 CMSettings.System.putInt(resolver, CMSettings.System.NOTIFICATION_LIGHT_PULSE_CALL_COLOR, color);
382 CMSettings.System.putInt(resolver, CMSettings.System.NOTIFICATION_LIGHT_PULSE_CALL_LED_ON, timeon);
383 CMSettings.System.putInt(resolver, CMSettings.System.NOTIFICATION_LIGHT_PULSE_CALL_LED_OFF, timeoff);
386 } else if (packageName.equals(VOICEMAIL_PREF)) {
387 CMSettings.System.putInt(resolver, CMSettings.System.NOTIFICATION_LIGHT_PULSE_VMAIL_COLOR, color);
388 CMSettings.System.putInt(resolver, CMSettings.System.NOTIFICATION_LIGHT_PULSE_VMAIL_LED_ON, timeon);
389 CMSettings.System.putInt(resolver, CMSettings.System.NOTIFICATION_LIGHT_PULSE_VMAIL_LED_OFF, timeoff);
394 // Find the custom package and sets its new values
395 Package app = mPackages.get(packageName);
399 app.timeoff = timeoff;
400 savePackageList(true);
404 protected void resetColors() {
405 ContentResolver resolver = getContentResolver();
407 // Reset to the framework default colors
408 CMSettings.System.putInt(resolver, CMSettings.System.NOTIFICATION_LIGHT_PULSE_DEFAULT_COLOR, mDefaultColor);
409 CMSettings.System.putInt(resolver, CMSettings.System.NOTIFICATION_LIGHT_PULSE_CALL_COLOR, mDefaultColor);
410 CMSettings.System.putInt(resolver, CMSettings.System.NOTIFICATION_LIGHT_PULSE_VMAIL_COLOR, mDefaultColor);
415 public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
416 final Preference pref = (Preference) getPreferenceScreen().getRootAdapter().getItem(position);
418 if (mApplicationPrefList.findPreference(pref.getKey()) != pref) {
422 AlertDialog.Builder builder = new AlertDialog.Builder(getActivity())
423 .setTitle(R.string.dialog_delete_title)
424 .setMessage(R.string.dialog_delete_message)
425 .setIconAttribute(android.R.attr.alertDialogIcon)
426 .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
428 public void onClick(DialogInterface dialog, int which) {
429 removeCustomApplicationPref(pref.getKey());
432 .setNegativeButton(android.R.string.cancel, null);
438 public boolean onPreferenceChange(Preference preference, Object objValue) {
439 if (preference == mEnabledPref || preference == mCustomEnabledPref ||
440 preference == mMultipleLedsEnabledPref ||
441 preference == mNotificationLedBrightnessPref ||
442 preference == mScreenOnLightsPref ||
443 preference == mAutoGenerateColors) {
444 getActivity().invalidateOptionsMenu();
446 ApplicationLightPreference lightPref = (ApplicationLightPreference) preference;
447 updateValues(lightPref.getKey(), lightPref.getColor(),
448 lightPref.getOnValue(), lightPref.getOffValue());
455 public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
457 mMenu.add(0, MENU_ADD, 0, R.string.profiles_add)
458 .setIcon(R.drawable.ic_menu_add_white)
459 .setShowAsActionFlags(MenuItem.SHOW_AS_ACTION_ALWAYS | MenuItem.SHOW_AS_ACTION_WITH_TEXT);
463 public void onPrepareOptionsMenu(Menu menu) {
464 boolean enableAddButton = mEnabledPref.isChecked() && mCustomEnabledPref.isChecked();
465 menu.findItem(MENU_ADD).setVisible(enableAddButton);
469 public boolean onOptionsItemSelected(MenuItem item) {
470 switch (item.getItemId()) {
472 showDialog(DIALOG_APPS);
479 * Utility classes and supporting methods
482 public Dialog onCreateDialog(int id) {
483 AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
487 final ListView list = new ListView(getActivity());
488 list.setAdapter(mPackageAdapter);
490 builder.setTitle(R.string.profile_choose_app);
491 builder.setView(list);
492 dialog = builder.create();
494 list.setOnItemClickListener(new OnItemClickListener() {
496 public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
497 // Add empty application definition, the user will be able to edit it later
498 PackageItem info = (PackageItem) parent.getItemAtPosition(position);
499 addCustomApplicationPref(info.packageName);
513 private static class Package {
515 public Integer color;
516 public Integer timeon;
517 public Integer timeoff;
520 * Stores all the application values in one call
526 public Package(String name, Integer color, Integer timeon, Integer timeoff) {
529 this.timeon = timeon;
530 this.timeoff = timeoff;
533 public String toString() {
534 StringBuilder builder = new StringBuilder();
535 builder.append(name);
537 builder.append(color);
539 builder.append(timeon);
541 builder.append(timeoff);
542 return builder.toString();
545 public static Package fromString(String value) {
546 if (TextUtils.isEmpty(value)) {
549 String[] app = value.split("=", -1);
553 String[] values = app[1].split(";", -1);
554 if (values.length != 3)
558 Package item = new Package(app[0], Integer.parseInt(values[0]), Integer
559 .parseInt(values[1]), Integer.parseInt(values[2]));
561 } catch (NumberFormatException e) {