1 /* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file 5 * except in compliance with the License. You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software distributed under the 10 * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 11 * KIND, either express or implied. See the License for the specific language governing 12 * permissions and limitations under the License. 13 */ 14 15 package com.android.systemui.tuner; 16 17 18 import android.app.AlertDialog; 19 import android.app.Dialog; 20 import android.app.DialogFragment; 21 import android.content.DialogInterface; 22 import android.os.Bundle; 23 import android.provider.Settings; 24 import android.provider.Settings.Secure; 25 import android.support.v14.preference.PreferenceFragment; 26 import android.support.v7.preference.Preference; 27 import android.view.LayoutInflater; 28 import android.view.View; 29 import android.widget.SeekBar; 30 31 import com.android.internal.logging.MetricsLogger; 32 import com.android.internal.logging.MetricsProto.MetricsEvent; 33 import com.android.systemui.R; 34 import com.android.systemui.statusbar.policy.NightModeController; 35 36 public class ColorAndAppearanceFragment extends PreferenceFragment { 37 38 private static final String KEY_CALIBRATE = "calibrate"; 39 40 private static final long RESET_DELAY = 10000; 41 private static final CharSequence KEY_NIGHT_MODE = "night_mode"; 42 43 private NightModeController mNightModeController; 44 45 @Override onCreate(Bundle savedInstanceState)46 public void onCreate(Bundle savedInstanceState) { 47 super.onCreate(savedInstanceState); 48 mNightModeController = new NightModeController(getContext()); 49 } 50 51 @Override onCreatePreferences(Bundle savedInstanceState, String rootKey)52 public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { 53 addPreferencesFromResource(R.xml.color_and_appearance); 54 } 55 56 @Override onResume()57 public void onResume() { 58 super.onResume(); 59 MetricsLogger.visibility(getContext(), MetricsEvent.TUNER_COLOR_AND_APPEARANCE, true); 60 // TODO: Figure out better title model for Tuner, to avoid any more of this. 61 getActivity().setTitle(R.string.color_and_appearance); 62 63 Preference nightMode = findPreference(KEY_NIGHT_MODE); 64 nightMode.setSummary(mNightModeController.isEnabled() 65 ? R.string.night_mode_on : R.string.night_mode_off); 66 } 67 68 @Override onPause()69 public void onPause() { 70 super.onPause(); 71 MetricsLogger.visibility(getContext(), MetricsEvent.TUNER_COLOR_AND_APPEARANCE, false); 72 } 73 74 @Override onDisplayPreferenceDialog(Preference preference)75 public void onDisplayPreferenceDialog(Preference preference) { 76 if (preference instanceof CalibratePreference) { 77 CalibrateDialog.show(this); 78 } else { 79 super.onDisplayPreferenceDialog(preference); 80 } 81 } 82 startRevertTimer()83 private void startRevertTimer() { 84 getView().postDelayed(mResetColorMatrix, RESET_DELAY); 85 } 86 onApply()87 private void onApply() { 88 MetricsLogger.action(getContext(), MetricsEvent.ACTION_TUNER_CALIBRATE_DISPLAY_CHANGED); 89 mNightModeController.setCustomValues(Settings.Secure.getString( 90 getContext().getContentResolver(), Secure.ACCESSIBILITY_DISPLAY_COLOR_MATRIX)); 91 getView().removeCallbacks(mResetColorMatrix); 92 } 93 onRevert()94 private void onRevert() { 95 getView().removeCallbacks(mResetColorMatrix); 96 mResetColorMatrix.run(); 97 } 98 99 private final Runnable mResetColorMatrix = new Runnable() { 100 @Override 101 public void run() { 102 ((DialogFragment) getFragmentManager().findFragmentByTag("RevertWarning")).dismiss(); 103 Settings.Secure.putString(getContext().getContentResolver(), 104 Settings.Secure.ACCESSIBILITY_DISPLAY_COLOR_MATRIX, null); 105 } 106 }; 107 108 public static class CalibrateDialog extends DialogFragment implements 109 DialogInterface.OnClickListener { 110 private float[] mValues; 111 private NightModeController mNightModeController; 112 show(ColorAndAppearanceFragment fragment)113 public static void show(ColorAndAppearanceFragment fragment) { 114 CalibrateDialog dialog = new CalibrateDialog(); 115 dialog.setTargetFragment(fragment, 0); 116 dialog.show(fragment.getFragmentManager(), "Calibrate"); 117 } 118 119 @Override onCreate(Bundle savedInstanceState)120 public void onCreate(Bundle savedInstanceState) { 121 super.onCreate(savedInstanceState); 122 mNightModeController = new NightModeController(getContext()); 123 String customValues = mNightModeController.getCustomValues(); 124 if (customValues == null) { 125 // Generate this as a string because its the easiest way to generate a copy of the 126 // identity. 127 customValues = NightModeController.toString(NightModeController.IDENTITY_MATRIX); 128 } 129 mValues = NightModeController.toValues(customValues); 130 } 131 132 @Override onCreateDialog(Bundle savedInstanceState)133 public Dialog onCreateDialog(Bundle savedInstanceState) { 134 View v = LayoutInflater.from(getContext()).inflate(R.layout.calibrate_sliders, null); 135 bindView(v.findViewById(R.id.r_group), 0); 136 bindView(v.findViewById(R.id.g_group), 5); 137 bindView(v.findViewById(R.id.b_group), 10); 138 MetricsLogger.visible(getContext(), MetricsEvent.TUNER_CALIBRATE_DISPLAY); 139 return new AlertDialog.Builder(getContext()) 140 .setTitle(R.string.calibrate_display) 141 .setView(v) 142 .setPositiveButton(R.string.color_apply, this) 143 .setNegativeButton(android.R.string.cancel, null) 144 .create(); 145 } 146 147 @Override onDismiss(DialogInterface dialog)148 public void onDismiss(DialogInterface dialog) { 149 super.onDismiss(dialog); 150 MetricsLogger.hidden(getContext(), MetricsEvent.TUNER_CALIBRATE_DISPLAY); 151 } 152 bindView(View view, final int index)153 private void bindView(View view, final int index) { 154 SeekBar seekBar = (SeekBar) view.findViewById(com.android.internal.R.id.seekbar); 155 seekBar.setMax(1000); 156 seekBar.setProgress((int) (1000 * mValues[index])); 157 seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { 158 @Override 159 public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { 160 mValues[index] = progress / 1000f; 161 } 162 163 @Override 164 public void onStartTrackingTouch(SeekBar seekBar) { 165 } 166 167 @Override 168 public void onStopTrackingTouch(SeekBar seekBar) { 169 } 170 }); 171 } 172 173 @Override onClick(DialogInterface dialog, int which)174 public void onClick(DialogInterface dialog, int which) { 175 if (mValues[0] == 1 && mValues[5] == 1 && mValues[10] == 1) { 176 // Allow removal of matrix by all values set to highest. 177 mNightModeController.setCustomValues(null); 178 return; 179 } 180 ((ColorAndAppearanceFragment) getTargetFragment()).startRevertTimer(); 181 Settings.Secure.putString(getContext().getContentResolver(), 182 Settings.Secure.ACCESSIBILITY_DISPLAY_COLOR_MATRIX, 183 NightModeController.toString(mValues)); 184 RevertWarning.show((ColorAndAppearanceFragment) getTargetFragment()); 185 } 186 } 187 188 public static class RevertWarning extends DialogFragment 189 implements DialogInterface.OnClickListener { 190 show(ColorAndAppearanceFragment fragment)191 public static void show(ColorAndAppearanceFragment fragment) { 192 RevertWarning warning = new RevertWarning(); 193 warning.setTargetFragment(fragment, 0); 194 warning.show(fragment.getFragmentManager(), "RevertWarning"); 195 } 196 197 @Override onCreateDialog(Bundle savedInstanceState)198 public Dialog onCreateDialog(Bundle savedInstanceState) { 199 AlertDialog alertDialog = new AlertDialog.Builder(getContext()) 200 .setTitle(R.string.color_revert_title) 201 .setMessage(R.string.color_revert_message) 202 .setPositiveButton(R.string.ok, this) 203 .create(); 204 alertDialog.setCanceledOnTouchOutside(true); 205 return alertDialog; 206 } 207 208 @Override onCancel(DialogInterface dialog)209 public void onCancel(DialogInterface dialog) { 210 super.onCancel(dialog); 211 ((ColorAndAppearanceFragment) getTargetFragment()).onRevert(); 212 } 213 214 @Override onClick(DialogInterface dialog, int which)215 public void onClick(DialogInterface dialog, int which) { 216 ((ColorAndAppearanceFragment) getTargetFragment()).onApply(); 217 } 218 } 219 } 220