• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2024 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.inputmethod;
18 
19 import static com.android.settings.inputmethod.PhysicalKeyboardFragment.getHardKeyboards;
20 
21 import android.app.settings.SettingsEnums;
22 import android.content.ContentResolver;
23 import android.content.Context;
24 import android.database.ContentObserver;
25 import android.hardware.input.InputManager;
26 import android.hardware.input.InputSettings;
27 import android.net.Uri;
28 import android.os.Bundle;
29 import android.os.Handler;
30 import android.os.UserHandle;
31 import android.provider.Settings;
32 
33 import androidx.annotation.NonNull;
34 import androidx.annotation.Nullable;
35 
36 import com.android.internal.util.Preconditions;
37 import com.android.settings.R;
38 import com.android.settings.dashboard.DashboardFragment;
39 import com.android.settings.keyboard.Flags;
40 import com.android.settings.search.BaseSearchIndexProvider;
41 import com.android.settings.widget.LabeledSeekBarPreference;
42 import com.android.settingslib.utils.ThreadUtils;
43 
44 import java.util.List;
45 
46 public class KeyboardRepeatKeysMainFragment extends DashboardFragment
47         implements InputManager.InputDeviceListener {
48     private static final String TAG = "RepeatKeysMainFragment";
49     private static final String TIME_OUT_KEY = "repeat_keys_timeout_preference";
50     private static final String DELAY_KEY = "repeat_keys_delay_preference";
51 
52     private final Uri mRepeatKeyUri = Settings.Secure.getUriFor(
53             Settings.Secure.KEY_REPEAT_ENABLED);
54     private final ContentObserver mContentObserver = new ContentObserver(new Handler(true)) {
55         @Override
56         public void onChange(boolean selfChange, Uri uri) {
57             if (mRepeatKeyUri.equals(uri)) {
58                 updatePreferencesState();
59             }
60         }
61     };
62     private InputManager mInputManager;
63     private ContentResolver mContentResolver;
64     @Nullable
65     private LabeledSeekBarPreference mRepeatTimeoutPreference;
66     @Nullable
67     private LabeledSeekBarPreference mRepeatDelayPreference;
68 
69     @Override
getMetricsCategory()70     public int getMetricsCategory() {
71         return SettingsEnums.PHYSICAL_KEYBOARD_REPEAT_KEYS;
72     }
73 
74     @Override
onAttach(@onNull Context context)75     public void onAttach(@NonNull Context context) {
76         super.onAttach(context);
77         mInputManager = Preconditions.checkNotNull(getActivity()
78                 .getSystemService(InputManager.class));
79         mContentResolver = context.getContentResolver();
80     }
81 
82     @Override
onCreatePreferences(Bundle bundle, String s)83     public void onCreatePreferences(Bundle bundle, String s) {
84         super.onCreatePreferences(bundle, s);
85         mRepeatTimeoutPreference = findPreference(TIME_OUT_KEY);
86         mRepeatDelayPreference = findPreference(DELAY_KEY);
87         updatePreferencesState();
88     }
89 
90     @Override
onResume()91     public void onResume() {
92         super.onResume();
93         finishEarlyIfNeeded();
94         mInputManager.registerInputDeviceListener(this, null);
95         registerSettingsObserver();
96     }
97 
98     @Override
onPause()99     public void onPause() {
100         super.onPause();
101         mInputManager.unregisterInputDeviceListener(this);
102         unregisterSettingsObserver();
103     }
104 
105     @Override
getLogTag()106     protected String getLogTag() {
107         return TAG;
108     }
109 
110     @Override
getPreferenceScreenResId()111     protected int getPreferenceScreenResId() {
112         return R.xml.repeat_key_main_page;
113     }
114 
updatePreferencesState()115     private void updatePreferencesState() {
116         boolean isRepeatKeyEnabled = InputSettings.isRepeatKeysEnabled(getContext());
117         if (mRepeatTimeoutPreference != null && mRepeatDelayPreference != null) {
118             mRepeatTimeoutPreference.setEnabled(isRepeatKeyEnabled);
119             mRepeatDelayPreference.setEnabled(isRepeatKeyEnabled);
120         }
121     }
122 
registerSettingsObserver()123     private void registerSettingsObserver() {
124         unregisterSettingsObserver();
125         mContentResolver.registerContentObserver(
126                 mRepeatKeyUri,
127                 false,
128                 mContentObserver,
129                 UserHandle.myUserId());
130     }
131 
unregisterSettingsObserver()132     private void unregisterSettingsObserver() {
133         mContentResolver.unregisterContentObserver(mContentObserver);
134     }
135 
136     @Override
onInputDeviceAdded(int deviceId)137     public void onInputDeviceAdded(int deviceId) {
138         finishEarlyIfNeeded();
139     }
140 
141     @Override
onInputDeviceRemoved(int deviceId)142     public void onInputDeviceRemoved(int deviceId) {
143         finishEarlyIfNeeded();
144     }
145 
146     @Override
onInputDeviceChanged(int deviceId)147     public void onInputDeviceChanged(int deviceId) {
148         finishEarlyIfNeeded();
149     }
150 
finishEarlyIfNeeded()151     private void finishEarlyIfNeeded() {
152         final Context context = getContext();
153         ThreadUtils.postOnBackgroundThread(() -> {
154             final List<PhysicalKeyboardFragment.HardKeyboardDeviceInfo> newHardKeyboards =
155                     getHardKeyboards(context);
156             if (newHardKeyboards.isEmpty()) {
157                 getActivity().finish();
158             }
159         });
160     }
161 
162     public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
163             new BaseSearchIndexProvider(R.xml.repeat_key_main_page) {
164                 @Override
165                 protected boolean isPageSearchEnabled(Context context) {
166                     return Flags.keyboardAndTouchpadA11yNewPageEnabled()
167                             && !getHardKeyboards(context).isEmpty();
168                 }
169             };
170 }
171