1 /* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 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 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 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. 15 */ 16 17 package com.android.settings.gestures; 18 19 import android.content.Context; 20 import android.content.res.Resources; 21 import android.hardware.Sensor; 22 import android.hardware.SensorManager; 23 import android.os.Bundle; 24 import android.provider.SearchIndexableResource; 25 import android.provider.Settings.Secure; 26 import android.support.v7.preference.Preference; 27 import android.support.v7.widget.RecyclerView; 28 import android.text.TextUtils; 29 import android.view.LayoutInflater; 30 import android.view.View; 31 import android.view.ViewGroup; 32 33 import com.android.internal.logging.MetricsProto.MetricsEvent; 34 import com.android.settings.R; 35 import com.android.settings.search.BaseSearchIndexProvider; 36 import com.android.settings.search.Indexable; 37 import com.android.settings.SettingsPreferenceFragment; 38 39 import java.util.ArrayList; 40 import java.util.List; 41 42 /** 43 * Top level fragment for gesture settings. 44 * This will create individual switch preference for each gesture and handle updates when each 45 * preference is updated 46 */ 47 public class GestureSettings extends SettingsPreferenceFragment implements 48 Preference.OnPreferenceChangeListener, Indexable { 49 50 private static final String TAG = "GestureSettings"; 51 private static final String PREF_KEY_DOUBLE_TAP_POWER = "gesture_double_tap_power"; 52 private static final String PREF_KEY_DOUBLE_TWIST = "gesture_double_twist"; 53 private static final String PREF_KEY_SWIPE_DOWN_FINGERPRINT = "gesture_swipe_down_fingerprint"; 54 private static final int PREF_ID_DOUBLE_TAP_POWER = 0; 55 private static final int PREF_ID_DOUBLE_TWIST = 1; 56 private static final int PREF_ID_SWIPE_DOWN_FINGERPRINT = 2; 57 58 private List<GesturePreference> mPreferences; 59 60 @Override onCreate(Bundle savedInstanceState)61 public void onCreate(Bundle savedInstanceState) { 62 super.onCreate(savedInstanceState); 63 addPreferencesFromResource(R.xml.gesture_settings); 64 Context context = getActivity(); 65 mPreferences = new ArrayList(); 66 67 // Double tap power for camera 68 if (isCameraDoubleTapPowerGestureAvailable(getResources())) { 69 int cameraDisabled = Secure.getInt( 70 getContentResolver(), Secure.CAMERA_DOUBLE_TAP_POWER_GESTURE_DISABLED, 0); 71 addPreference(PREF_KEY_DOUBLE_TAP_POWER, cameraDisabled == 0, PREF_ID_DOUBLE_TAP_POWER); 72 } else { 73 removePreference(PREF_KEY_DOUBLE_TAP_POWER); 74 } 75 76 // Fingerprint slide for notifications 77 if (isSystemUINavigationAvailable(context)) { 78 addPreference(PREF_KEY_SWIPE_DOWN_FINGERPRINT, isSystemUINavigationEnabled(context), 79 PREF_ID_SWIPE_DOWN_FINGERPRINT); 80 } else { 81 removePreference(PREF_KEY_SWIPE_DOWN_FINGERPRINT); 82 } 83 84 // Double twist for camera mode 85 if (isDoubleTwistAvailable(context)) { 86 int doubleTwistEnabled = Secure.getInt( 87 getContentResolver(), Secure.CAMERA_DOUBLE_TWIST_TO_FLIP_ENABLED, 1); 88 addPreference(PREF_KEY_DOUBLE_TWIST, doubleTwistEnabled != 0, PREF_ID_DOUBLE_TWIST); 89 } else { 90 removePreference(PREF_KEY_DOUBLE_TWIST); 91 } 92 93 } 94 95 @Override onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)96 public View onCreateView(LayoutInflater inflater, ViewGroup container, 97 Bundle savedInstanceState) { 98 View view = super.onCreateView(inflater, container, savedInstanceState); 99 RecyclerView listview = getListView(); 100 listview.addOnScrollListener(new RecyclerView.OnScrollListener() { 101 @Override 102 public void onScrollStateChanged(RecyclerView recyclerView, int newState) { 103 if (newState == RecyclerView.SCROLL_STATE_DRAGGING) { 104 for (GesturePreference pref : mPreferences) { 105 pref.setScrolling(true); 106 } 107 } else if (newState == RecyclerView.SCROLL_STATE_IDLE) { 108 for (GesturePreference pref : mPreferences) { 109 pref.setScrolling(false); 110 } 111 } 112 } 113 114 @Override 115 public void onScrolled(RecyclerView recyclerView, int dx, int dy) { 116 } 117 }); 118 return view; 119 } 120 121 @Override onStart()122 public void onStart() { 123 super.onStart(); 124 for (GesturePreference preference : mPreferences) { 125 preference.onViewVisible(); 126 } 127 } 128 129 @Override onPreferenceChange(Preference preference, Object newValue)130 public boolean onPreferenceChange(Preference preference, Object newValue) { 131 boolean enabled = (boolean) newValue; 132 String key = preference.getKey(); 133 if (PREF_KEY_DOUBLE_TAP_POWER.equals(key)) { 134 Secure.putInt(getContentResolver(), 135 Secure.CAMERA_DOUBLE_TAP_POWER_GESTURE_DISABLED, enabled ? 0 : 1); 136 } else if (PREF_KEY_SWIPE_DOWN_FINGERPRINT.equals(key)) { 137 Secure.putInt(getContentResolver(), 138 Secure.SYSTEM_NAVIGATION_KEYS_ENABLED, enabled ? 1 : 0); 139 } else if (PREF_KEY_DOUBLE_TWIST.equals(key)) { 140 Secure.putInt(getContentResolver(), 141 Secure.CAMERA_DOUBLE_TWIST_TO_FLIP_ENABLED, enabled ? 1 : 0); 142 } 143 return true; 144 } 145 146 @Override getHelpResource()147 protected int getHelpResource() { 148 return R.string.help_url_gestures; 149 } 150 151 @Override getMetricsCategory()152 protected int getMetricsCategory() { 153 return MetricsEvent.SETTINGS_GESTURES; 154 } 155 isCameraDoubleTapPowerGestureAvailable(Resources res)156 private static boolean isCameraDoubleTapPowerGestureAvailable(Resources res) { 157 return res.getBoolean( 158 com.android.internal.R.bool.config_cameraDoubleTapPowerGestureEnabled); 159 } 160 isSystemUINavigationAvailable(Context context)161 private static boolean isSystemUINavigationAvailable(Context context) { 162 return context.getResources().getBoolean( 163 com.android.internal.R.bool.config_supportSystemNavigationKeys); 164 } 165 isSystemUINavigationEnabled(Context context)166 private static boolean isSystemUINavigationEnabled(Context context) { 167 return Secure.getInt(context.getContentResolver(), Secure.SYSTEM_NAVIGATION_KEYS_ENABLED, 0) 168 == 1; 169 } 170 isDoubleTwistAvailable(Context context)171 private static boolean isDoubleTwistAvailable(Context context) { 172 Resources resources = context.getResources(); 173 String name = resources.getString(R.string.gesture_double_twist_sensor_name); 174 String vendor = resources.getString(R.string.gesture_double_twist_sensor_vendor); 175 if (!TextUtils.isEmpty(name) && !TextUtils.isEmpty(vendor)) { 176 SensorManager sensorManager = 177 (SensorManager) context.getSystemService(Context.SENSOR_SERVICE); 178 for (Sensor s : sensorManager.getSensorList(Sensor.TYPE_ALL)) { 179 if (name.equals(s.getName()) && vendor.equals(s.getVendor())) { 180 return true; 181 } 182 } 183 } 184 return false; 185 } 186 addPreference(String key, boolean enabled, int id)187 private void addPreference(String key, boolean enabled, int id) { 188 GesturePreference preference = (GesturePreference) findPreference(key); 189 preference.setChecked(enabled); 190 preference.setOnPreferenceChangeListener(this); 191 preference.loadPreview(getLoaderManager(), id); 192 mPreferences.add(preference); 193 } 194 195 public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER = 196 new BaseSearchIndexProvider() { 197 @Override 198 public List<SearchIndexableResource> getXmlResourcesToIndex(Context context, 199 boolean enabled) { 200 ArrayList<SearchIndexableResource> result = 201 new ArrayList<SearchIndexableResource>(); 202 203 SearchIndexableResource sir = new SearchIndexableResource(context); 204 sir.xmlResId = R.xml.gesture_settings; 205 result.add(sir); 206 207 return result; 208 } 209 210 @Override 211 public List<String> getNonIndexableKeys(Context context) { 212 ArrayList<String> result = new ArrayList<String>(); 213 if (!isCameraDoubleTapPowerGestureAvailable(context.getResources())) { 214 result.add(PREF_KEY_DOUBLE_TAP_POWER); 215 } 216 if (!isSystemUINavigationAvailable(context)) { 217 result.add(PREF_KEY_SWIPE_DOWN_FINGERPRINT); 218 } 219 if (!isDoubleTwistAvailable(context)) { 220 result.add(PREF_KEY_DOUBLE_TWIST); 221 } 222 return result; 223 } 224 }; 225 226 }