diff options
Diffstat (limited to 'src/com/android/settings/notificationlight/NotificationLightSettings.java')
-rw-r--r-- | src/com/android/settings/notificationlight/NotificationLightSettings.java | 567 |
1 files changed, 567 insertions, 0 deletions
diff --git a/src/com/android/settings/notificationlight/NotificationLightSettings.java b/src/com/android/settings/notificationlight/NotificationLightSettings.java new file mode 100644 index 0000000..95a354d --- /dev/null +++ b/src/com/android/settings/notificationlight/NotificationLightSettings.java @@ -0,0 +1,567 @@ +/* + * Copyright (C) 2012 The CyanogenMod 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.notificationlight; + +import android.app.AlertDialog; +import android.app.Dialog; +import android.content.ContentResolver; +import android.content.Context; +import android.content.DialogInterface; +import android.content.pm.PackageInfo; +import android.content.pm.PackageManager; +import android.content.pm.PackageManager.NameNotFoundException; +import android.content.res.Resources; +import android.graphics.drawable.Drawable; +import android.os.Bundle; +import android.preference.Preference; +import android.preference.PreferenceGroup; +import android.preference.PreferenceScreen; +import android.provider.Settings; +import android.telephony.TelephonyManager; +import android.text.TextUtils; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; +import android.view.View; +import android.widget.AdapterView; +import android.widget.AdapterView.OnItemClickListener; +import android.widget.ListView; + +import com.android.settings.R; +import com.android.settings.SettingsPreferenceFragment; +import com.android.settings.cyanogenmod.CMSystemSettingSwitchPreference; +import com.android.settings.cyanogenmod.PackageListAdapter; +import com.android.settings.cyanogenmod.PackageListAdapter.PackageItem; +import com.android.settings.cyanogenmod.SystemSettingSwitchPreference; + +import org.cyanogenmod.internal.logging.CMMetricsLogger; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import cyanogenmod.providers.CMSettings; +import cyanogenmod.util.ColorUtils; + +public class NotificationLightSettings extends SettingsPreferenceFragment implements + Preference.OnPreferenceChangeListener, AdapterView.OnItemLongClickListener { + private static final String TAG = "NotificationLightSettings"; + private static final String DEFAULT_PREF = "default"; + private static final String MISSED_CALL_PREF = "missed_call"; + private static final String VOICEMAIL_PREF = "voicemail"; + public static final int ACTION_TEST = 0; + public static final int ACTION_DELETE = 1; + private static final int MENU_ADD = 0; + private static final int DIALOG_APPS = 0; + + private int mDefaultColor; + private int mDefaultLedOn; + private int mDefaultLedOff; + private PackageManager mPackageManager; + private PreferenceGroup mApplicationPrefList; + private PreferenceScreen mNotificationLedBrightnessPref; + private SystemSettingSwitchPreference mEnabledPref; + private CMSystemSettingSwitchPreference mCustomEnabledPref; + private CMSystemSettingSwitchPreference mMultipleLedsEnabledPref; + private CMSystemSettingSwitchPreference mScreenOnLightsPref; + private CMSystemSettingSwitchPreference mAutoGenerateColors; + private ApplicationLightPreference mDefaultPref; + private ApplicationLightPreference mCallPref; + private ApplicationLightPreference mVoicemailPref; + private Menu mMenu; + private PackageListAdapter mPackageAdapter; + private String mPackageList; + private Map<String, Package> mPackages; + private boolean mMultiColorLed; + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + addPreferencesFromResource(R.xml.notification_light_settings); + + PreferenceScreen prefSet = getPreferenceScreen(); + Resources resources = getResources(); + + PreferenceGroup mAdvancedPrefs = (PreferenceGroup) prefSet.findPreference("advanced_section"); + + // Get the system defined default notification color + mDefaultColor = + resources.getColor(com.android.internal.R.color.config_defaultNotificationColor, null); + + mDefaultLedOn = resources.getInteger( + com.android.internal.R.integer.config_defaultNotificationLedOn); + mDefaultLedOff = resources.getInteger( + com.android.internal.R.integer.config_defaultNotificationLedOff); + + mEnabledPref = (SystemSettingSwitchPreference) + findPreference(Settings.System.NOTIFICATION_LIGHT_PULSE); + mEnabledPref.setOnPreferenceChangeListener(this); + + mDefaultPref = (ApplicationLightPreference) findPreference(DEFAULT_PREF); + mDefaultPref.setOnPreferenceChangeListener(this); + + mAutoGenerateColors = (CMSystemSettingSwitchPreference) + findPreference(CMSettings.System.NOTIFICATION_LIGHT_COLOR_AUTO); + + // Advanced light settings + mNotificationLedBrightnessPref = (PreferenceScreen) + findPreference(CMSettings.System.NOTIFICATION_LIGHT_BRIGHTNESS_LEVEL); + mMultipleLedsEnabledPref = (CMSystemSettingSwitchPreference) + findPreference(CMSettings.System.NOTIFICATION_LIGHT_MULTIPLE_LEDS_ENABLE); + mScreenOnLightsPref = (CMSystemSettingSwitchPreference) + findPreference(CMSettings.System.NOTIFICATION_LIGHT_SCREEN_ON); + mScreenOnLightsPref.setOnPreferenceChangeListener(this); + mCustomEnabledPref = (CMSystemSettingSwitchPreference) + findPreference(CMSettings.System.NOTIFICATION_LIGHT_PULSE_CUSTOM_ENABLE); + mCustomEnabledPref.setOnPreferenceChangeListener(this); + if (!resources.getBoolean( + org.cyanogenmod.platform.internal.R.bool.config_adjustableNotificationLedBrightness)) { + mAdvancedPrefs.removePreference(mNotificationLedBrightnessPref); + } else { + mNotificationLedBrightnessPref.setOnPreferenceChangeListener(this); + } + if (!resources.getBoolean( + org.cyanogenmod.platform.internal.R.bool.config_multipleNotificationLeds)) { + mAdvancedPrefs.removePreference(mMultipleLedsEnabledPref); + } else { + mMultipleLedsEnabledPref.setOnPreferenceChangeListener(this); + } + + // Missed call and Voicemail preferences should only show on devices with a voice capabilities + TelephonyManager tm = (TelephonyManager) getActivity().getSystemService(Context.TELEPHONY_SERVICE); + if (tm.getPhoneType() == TelephonyManager.PHONE_TYPE_NONE) { + removePreference("phone_list"); + } else { + mCallPref = (ApplicationLightPreference) findPreference(MISSED_CALL_PREF); + mCallPref.setOnPreferenceChangeListener(this); + + mVoicemailPref = (ApplicationLightPreference) findPreference(VOICEMAIL_PREF); + mVoicemailPref.setOnPreferenceChangeListener(this); + } + + mApplicationPrefList = (PreferenceGroup) findPreference("applications_list"); + mApplicationPrefList.setOrderingAsAdded(false); + + // Get launch-able applications + mPackageManager = getPackageManager(); + mPackageAdapter = new PackageListAdapter(getActivity()); + + mPackages = new HashMap<String, Package>(); + setHasOptionsMenu(true); + + mMultiColorLed = resources.getBoolean(com.android.internal.R.bool.config_multiColorNotificationLed); + if (!mMultiColorLed) { + resetColors(); + PreferenceGroup mGeneralPrefs = (PreferenceGroup) prefSet.findPreference("general_section"); + mGeneralPrefs.removePreference(mAutoGenerateColors); + } else { + mAutoGenerateColors.setOnPreferenceChangeListener(this); + } + } + + @Override + protected int getMetricsCategory() { + return CMMetricsLogger.NOTIFICATION_LIGHT_SETTINGS; + } + + @Override + public void onResume() { + super.onResume(); + refreshDefault(); + refreshCustomApplicationPrefs(); + getListView().setOnItemLongClickListener(this); + getActivity().invalidateOptionsMenu(); + } + + @Override + public void onStart() { + super.onStart(); + setChildrenStarted(getPreferenceScreen(), true); + } + + @Override + public void onStop() { + super.onStop(); + setChildrenStarted(getPreferenceScreen(), false); + } + + private void setChildrenStarted(PreferenceGroup group, boolean started) { + final int count = group.getPreferenceCount(); + for (int i = 0; i < count; i++) { + Preference pref = group.getPreference(i); + if (pref instanceof ApplicationLightPreference) { + ApplicationLightPreference ap = (ApplicationLightPreference) pref; + if (started) { + ap.onStart(); + } else { + ap.onStop(); + } + } else if (pref instanceof PreferenceGroup) { + setChildrenStarted((PreferenceGroup) pref, started); + } + } + } + + private void refreshDefault() { + ContentResolver resolver = getContentResolver(); + int color = CMSettings.System.getInt(resolver, + CMSettings.System.NOTIFICATION_LIGHT_PULSE_DEFAULT_COLOR, mDefaultColor); + int timeOn = CMSettings.System.getInt(resolver, + CMSettings.System.NOTIFICATION_LIGHT_PULSE_DEFAULT_LED_ON, mDefaultLedOn); + int timeOff = CMSettings.System.getInt(resolver, + CMSettings.System.NOTIFICATION_LIGHT_PULSE_DEFAULT_LED_OFF, mDefaultLedOff); + + mDefaultPref.setAllValues(color, timeOn, timeOff); + + // Get Missed call and Voicemail values + if (mCallPref != null) { + int callColor = CMSettings.System.getInt(resolver, + CMSettings.System.NOTIFICATION_LIGHT_PULSE_CALL_COLOR, mDefaultColor); + int callTimeOn = CMSettings.System.getInt(resolver, + CMSettings.System.NOTIFICATION_LIGHT_PULSE_CALL_LED_ON, mDefaultLedOn); + int callTimeOff = CMSettings.System.getInt(resolver, + CMSettings.System.NOTIFICATION_LIGHT_PULSE_CALL_LED_OFF, mDefaultLedOff); + + mCallPref.setAllValues(callColor, callTimeOn, callTimeOff); + } + + if (mVoicemailPref != null) { + int vmailColor = CMSettings.System.getInt(resolver, + CMSettings.System.NOTIFICATION_LIGHT_PULSE_VMAIL_COLOR, mDefaultColor); + int vmailTimeOn = CMSettings.System.getInt(resolver, + CMSettings.System.NOTIFICATION_LIGHT_PULSE_VMAIL_LED_ON, mDefaultLedOn); + int vmailTimeOff = CMSettings.System.getInt(resolver, + CMSettings.System.NOTIFICATION_LIGHT_PULSE_VMAIL_LED_OFF, mDefaultLedOff); + + mVoicemailPref.setAllValues(vmailColor, vmailTimeOn, vmailTimeOff); + } + + mApplicationPrefList = (PreferenceGroup) findPreference("applications_list"); + mApplicationPrefList.setOrderingAsAdded(false); + } + + private void refreshCustomApplicationPrefs() { + Context context = getActivity(); + + if (!parsePackageList()) { + return; + } + + // Add the Application Preferences + if (mApplicationPrefList != null) { + mApplicationPrefList.removeAll(); + + for (Package pkg : mPackages.values()) { + try { + PackageInfo info = mPackageManager.getPackageInfo(pkg.name, + PackageManager.GET_META_DATA); + ApplicationLightPreference pref = + new ApplicationLightPreference(context, pkg.color, pkg.timeon, pkg.timeoff); + + pref.setKey(pkg.name); + pref.setTitle(info.applicationInfo.loadLabel(mPackageManager)); + pref.setIcon(info.applicationInfo.loadIcon(mPackageManager)); + pref.setPersistent(false); + pref.setOnPreferenceChangeListener(this); + + mApplicationPrefList.addPreference(pref); + } catch (NameNotFoundException e) { + // Do nothing + } + } + } + } + + private int getInitialColorForPackage(String packageName) { + boolean autoColor = CMSettings.System.getInt(getContentResolver(), + CMSettings.System.NOTIFICATION_LIGHT_COLOR_AUTO, mMultiColorLed ? 1 : 0) == 1; + int color = mDefaultColor; + if (autoColor) { + try { + Drawable icon = mPackageManager.getApplicationIcon(packageName); + color = ColorUtils.generateAlertColorFromDrawable(icon); + } catch (NameNotFoundException e) { + // shouldn't happen, but just return default + } + } + return color; + } + + private void addCustomApplicationPref(String packageName) { + Package pkg = mPackages.get(packageName); + if (pkg == null) { + int color = getInitialColorForPackage(packageName); + pkg = new Package(packageName, color, mDefaultLedOn, mDefaultLedOff); + mPackages.put(packageName, pkg); + savePackageList(false); + refreshCustomApplicationPrefs(); + } + } + + private void removeCustomApplicationPref(String packageName) { + if (mPackages.remove(packageName) != null) { + savePackageList(false); + refreshCustomApplicationPrefs(); + } + } + + private boolean parsePackageList() { + final String baseString = CMSettings.System.getString(getContentResolver(), + CMSettings.System.NOTIFICATION_LIGHT_PULSE_CUSTOM_VALUES); + + if (TextUtils.equals(mPackageList, baseString)) { + return false; + } + + mPackageList = baseString; + mPackages.clear(); + + if (baseString != null) { + final String[] array = TextUtils.split(baseString, "\\|"); + for (String item : array) { + if (TextUtils.isEmpty(item)) { + continue; + } + Package pkg = Package.fromString(item); + if (pkg != null) { + mPackages.put(pkg.name, pkg); + } + } + } + + return true; + } + + private void savePackageList(boolean preferencesUpdated) { + List<String> settings = new ArrayList<String>(); + for (Package app : mPackages.values()) { + settings.add(app.toString()); + } + final String value = TextUtils.join("|", settings); + if (preferencesUpdated) { + mPackageList = value; + } + CMSettings.System.putString(getContentResolver(), + CMSettings.System.NOTIFICATION_LIGHT_PULSE_CUSTOM_VALUES, value); + } + + /** + * Updates the default or package specific notification settings. + * + * @param packageName Package name of application specific settings to update + * @param color + * @param timeon + * @param timeoff + */ + protected void updateValues(String packageName, Integer color, Integer timeon, Integer timeoff) { + ContentResolver resolver = getContentResolver(); + + if (packageName.equals(DEFAULT_PREF)) { + CMSettings.System.putInt(resolver, CMSettings.System.NOTIFICATION_LIGHT_PULSE_DEFAULT_COLOR, color); + CMSettings.System.putInt(resolver, CMSettings.System.NOTIFICATION_LIGHT_PULSE_DEFAULT_LED_ON, timeon); + CMSettings.System.putInt(resolver, CMSettings.System.NOTIFICATION_LIGHT_PULSE_DEFAULT_LED_OFF, timeoff); + refreshDefault(); + return; + } else if (packageName.equals(MISSED_CALL_PREF)) { + CMSettings.System.putInt(resolver, CMSettings.System.NOTIFICATION_LIGHT_PULSE_CALL_COLOR, color); + CMSettings.System.putInt(resolver, CMSettings.System.NOTIFICATION_LIGHT_PULSE_CALL_LED_ON, timeon); + CMSettings.System.putInt(resolver, CMSettings.System.NOTIFICATION_LIGHT_PULSE_CALL_LED_OFF, timeoff); + refreshDefault(); + return; + } else if (packageName.equals(VOICEMAIL_PREF)) { + CMSettings.System.putInt(resolver, CMSettings.System.NOTIFICATION_LIGHT_PULSE_VMAIL_COLOR, color); + CMSettings.System.putInt(resolver, CMSettings.System.NOTIFICATION_LIGHT_PULSE_VMAIL_LED_ON, timeon); + CMSettings.System.putInt(resolver, CMSettings.System.NOTIFICATION_LIGHT_PULSE_VMAIL_LED_OFF, timeoff); + refreshDefault(); + return; + } + + // Find the custom package and sets its new values + Package app = mPackages.get(packageName); + if (app != null) { + app.color = color; + app.timeon = timeon; + app.timeoff = timeoff; + savePackageList(true); + } + } + + protected void resetColors() { + ContentResolver resolver = getContentResolver(); + + // Reset to the framework default colors + CMSettings.System.putInt(resolver, CMSettings.System.NOTIFICATION_LIGHT_PULSE_DEFAULT_COLOR, mDefaultColor); + CMSettings.System.putInt(resolver, CMSettings.System.NOTIFICATION_LIGHT_PULSE_CALL_COLOR, mDefaultColor); + CMSettings.System.putInt(resolver, CMSettings.System.NOTIFICATION_LIGHT_PULSE_VMAIL_COLOR, mDefaultColor); + + refreshDefault(); + } + + public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) { + final Preference pref = (Preference) getPreferenceScreen().getRootAdapter().getItem(position); + + if (mApplicationPrefList.findPreference(pref.getKey()) != pref) { + return false; + } + + AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()) + .setTitle(R.string.dialog_delete_title) + .setMessage(R.string.dialog_delete_message) + .setIconAttribute(android.R.attr.alertDialogIcon) + .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + removeCustomApplicationPref(pref.getKey()); + } + }) + .setNegativeButton(android.R.string.cancel, null); + + builder.show(); + return true; + } + + public boolean onPreferenceChange(Preference preference, Object objValue) { + if (preference == mEnabledPref || preference == mCustomEnabledPref || + preference == mMultipleLedsEnabledPref || + preference == mNotificationLedBrightnessPref || + preference == mScreenOnLightsPref || + preference == mAutoGenerateColors) { + getActivity().invalidateOptionsMenu(); + } else { + ApplicationLightPreference lightPref = (ApplicationLightPreference) preference; + updateValues(lightPref.getKey(), lightPref.getColor(), + lightPref.getOnValue(), lightPref.getOffValue()); + } + + return true; + } + + @Override + public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { + mMenu = menu; + mMenu.add(0, MENU_ADD, 0, R.string.profiles_add) + .setIcon(R.drawable.ic_menu_add_white) + .setShowAsActionFlags(MenuItem.SHOW_AS_ACTION_ALWAYS | MenuItem.SHOW_AS_ACTION_WITH_TEXT); + } + + @Override + public void onPrepareOptionsMenu(Menu menu) { + boolean enableAddButton = mEnabledPref.isChecked() && mCustomEnabledPref.isChecked(); + menu.findItem(MENU_ADD).setVisible(enableAddButton); + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case MENU_ADD: + showDialog(DIALOG_APPS); + return true; + } + return false; + } + + /** + * Utility classes and supporting methods + */ + @Override + public Dialog onCreateDialog(int id) { + AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); + final Dialog dialog; + switch (id) { + case DIALOG_APPS: + final ListView list = new ListView(getActivity()); + list.setAdapter(mPackageAdapter); + + builder.setTitle(R.string.profile_choose_app); + builder.setView(list); + dialog = builder.create(); + + list.setOnItemClickListener(new OnItemClickListener() { + @Override + public void onItemClick(AdapterView<?> parent, View view, int position, long id) { + // Add empty application definition, the user will be able to edit it later + PackageItem info = (PackageItem) parent.getItemAtPosition(position); + addCustomApplicationPref(info.packageName); + dialog.cancel(); + } + }); + break; + default: + dialog = null; + } + return dialog; + } + + /** + * Application class + */ + private static class Package { + public String name; + public Integer color; + public Integer timeon; + public Integer timeoff; + + /** + * Stores all the application values in one call + * @param name + * @param color + * @param timeon + * @param timeoff + */ + public Package(String name, Integer color, Integer timeon, Integer timeoff) { + this.name = name; + this.color = color; + this.timeon = timeon; + this.timeoff = timeoff; + } + + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append(name); + builder.append("="); + builder.append(color); + builder.append(";"); + builder.append(timeon); + builder.append(";"); + builder.append(timeoff); + return builder.toString(); + } + + public static Package fromString(String value) { + if (TextUtils.isEmpty(value)) { + return null; + } + String[] app = value.split("=", -1); + if (app.length != 2) + return null; + + String[] values = app[1].split(";", -1); + if (values.length != 3) + return null; + + try { + Package item = new Package(app[0], Integer.parseInt(values[0]), Integer + .parseInt(values[1]), Integer.parseInt(values[2])); + return item; + } catch (NumberFormatException e) { + return null; + } + } + + } +} |