1 /*
2  * Copyright (C) 2018 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.slices;
18 
19 import static android.provider.SettingsSlicesContract.KEY_LOCATION;
20 import static android.provider.SettingsSlicesContract.KEY_WIFI;
21 
22 import android.content.ContentResolver;
23 import android.net.Uri;
24 import android.provider.SettingsSlicesContract;
25 import android.util.ArrayMap;
26 
27 import androidx.annotation.VisibleForTesting;
28 
29 import com.android.settings.display.AlwaysOnDisplaySlice;
30 import com.android.settings.display.ScreenTimeoutPreferenceController;
31 import com.android.settings.flashlight.FlashlightSlice;
32 import com.android.settings.homepage.contextualcards.slices.BluetoothDevicesSlice;
33 import com.android.settings.homepage.contextualcards.slices.ContextualAdaptiveSleepSlice;
34 import com.android.settings.homepage.contextualcards.slices.DarkThemeSlice;
35 import com.android.settings.homepage.contextualcards.slices.FaceSetupSlice;
36 import com.android.settings.homepage.contextualcards.slices.LowStorageSlice;
37 import com.android.settings.location.LocationSlice;
38 import com.android.settings.media.MediaOutputIndicatorSlice;
39 import com.android.settings.media.RemoteMediaSlice;
40 import com.android.settings.network.ProviderModelSlice;
41 import com.android.settings.network.telephony.MobileDataSlice;
42 import com.android.settings.notification.zen.ZenModeButtonPreferenceController;
43 import com.android.settings.wifi.calling.WifiCallingSliceHelper;
44 import com.android.settings.wifi.slice.WifiSlice;
45 import com.android.settingslib.media.MediaOutputConstants;
46 
47 import java.util.Map;
48 
49 /**
50  * A registry of custom slice Uris.
51  */
52 public class CustomSliceRegistry {
53 
54     /**
55      * Uri for Contextual Adaptive Sleep Slice
56      */
57     public static final Uri CONTEXTUAL_ADAPTIVE_SLEEP_URI = new Uri.Builder()
58             .scheme(ContentResolver.SCHEME_CONTENT)
59             .authority(SettingsSliceProvider.SLICE_AUTHORITY)
60             .appendPath(SettingsSlicesContract.PATH_SETTING_INTENT)
61             .appendPath(ScreenTimeoutPreferenceController.PREF_NAME)
62             .build();
63 
64     /**
65      * Backing Uri for the Bluetooth Slice.
66      */
67     public static final Uri BLUETOOTH_URI = new Uri.Builder()
68             .scheme(ContentResolver.SCHEME_CONTENT)
69             .authority(SettingsSlicesContract.AUTHORITY)
70             .appendPath(SettingsSlicesContract.PATH_SETTING_ACTION)
71             .appendPath(SettingsSlicesContract.KEY_BLUETOOTH)
72             .build();
73 
74     /**
75      * Backing Uri for Bluetooth devices Slice.
76      */
77     public static final Uri BLUETOOTH_DEVICES_SLICE_URI = new Uri.Builder()
78             .scheme(ContentResolver.SCHEME_CONTENT)
79             .authority(SettingsSliceProvider.SLICE_AUTHORITY)
80             .appendPath(SettingsSlicesContract.PATH_SETTING_ACTION)
81             .appendPath("bluetooth_devices")
82             .build();
83 
84     /**
85      * Slice Uri for Enhanced 4G slice
86      */
87     public static final Uri ENHANCED_4G_SLICE_URI = new Uri.Builder()
88             .scheme(ContentResolver.SCHEME_CONTENT)
89             .authority(SettingsSliceProvider.SLICE_AUTHORITY)
90             .appendPath(SettingsSlicesContract.PATH_SETTING_ACTION)
91             .appendPath("enhanced_4g_lte")
92             .build();
93     /**
94      * Slice Uri for Face Enrollment
95      */
96     public static final Uri FACE_ENROLL_SLICE_URI = new Uri.Builder()
97             .scheme(ContentResolver.SCHEME_CONTENT)
98             .authority(SettingsSliceProvider.SLICE_AUTHORITY)
99             .appendPath(SettingsSlicesContract.PATH_SETTING_ACTION)
100             .appendPath("face_unlock_greeting_card")
101             .build();
102     /**
103      * Backing Uri for the Flashlight Slice.
104      */
105     public static final Uri FLASHLIGHT_SLICE_URI = new Uri.Builder()
106             .scheme(ContentResolver.SCHEME_CONTENT)
107             .authority(SettingsSliceProvider.SLICE_AUTHORITY)
108             .appendPath(SettingsSlicesContract.PATH_SETTING_ACTION)
109             .appendPath("flashlight")
110             .build();
111     /**
112      * Backing Uri for the Location Slice.
113      */
114     public static final Uri LOCATION_SLICE_URI = new Uri.Builder()
115             .scheme(ContentResolver.SCHEME_CONTENT)
116             .authority(SettingsSlicesContract.AUTHORITY)
117             .appendPath(SettingsSlicesContract.PATH_SETTING_ACTION)
118             .appendPath(KEY_LOCATION)
119             .build();
120     /**
121      * Backing Uri for Low storage Slice.
122      */
123     public static final Uri LOW_STORAGE_SLICE_URI = new Uri.Builder()
124             .scheme(ContentResolver.SCHEME_CONTENT)
125             .authority(SettingsSliceProvider.SLICE_AUTHORITY)
126             .appendEncodedPath(SettingsSlicesContract.PATH_SETTING_INTENT)
127             .appendPath("low_storage")
128             .build();
129     /**
130      * Backing Uri for NFC Slice
131      */
132     public static final Uri NFC_SLICE_URI = new Uri.Builder()
133             .scheme(ContentResolver.SCHEME_CONTENT)
134             .authority(SettingsSliceProvider.SLICE_AUTHORITY)
135             .appendPath(SettingsSlicesContract.PATH_SETTING_ACTION)
136             .appendPath("toggle_nfc")
137             .build();
138 
139     /**
140      * Backing Uri for Mobile Data Slice.
141      */
142     public static final Uri MOBILE_DATA_SLICE_URI = new Uri.Builder()
143             .scheme(ContentResolver.SCHEME_CONTENT)
144             .authority(SettingsSliceProvider.SLICE_AUTHORITY)
145             .appendEncodedPath(SettingsSlicesContract.PATH_SETTING_ACTION)
146             .appendPath("mobile_data")
147             .build();
148 
149     /**
150      * Full {@link Uri} for the Provider Model Slice.
151      */
152     public static final Uri PROVIDER_MODEL_SLICE_URI = new Uri.Builder()
153             .scheme(ContentResolver.SCHEME_CONTENT)
154             .authority(SettingsSliceProvider.SLICE_AUTHORITY)
155             .appendEncodedPath(SettingsSlicesContract.PATH_SETTING_ACTION)
156             .appendPath("provider_model")
157             .build();
158 
159     /**
160      * Full {@link Uri} for the Alarm volume Slice.
161      */
162     public static final Uri VOLUME_ALARM_URI = new Uri.Builder()
163             .scheme(ContentResolver.SCHEME_CONTENT)
164             .authority(SettingsSliceProvider.SLICE_AUTHORITY)
165             .appendPath(SettingsSlicesContract.PATH_SETTING_ACTION)
166             .appendPath("alarm_volume")
167             .build();
168 
169     /**
170      * Full {@link Uri} for the Call Volume Slice.
171      */
172     public static final Uri VOLUME_CALL_URI = new Uri.Builder()
173             .scheme(ContentResolver.SCHEME_CONTENT)
174             .authority(SettingsSliceProvider.SLICE_AUTHORITY)
175             .appendPath(SettingsSlicesContract.PATH_SETTING_ACTION)
176             .appendPath("call_volume")
177             .build();
178     /**
179      * Full {@link Uri} for the Media Volume Slice.
180      */
181     public static final Uri VOLUME_MEDIA_URI = new Uri.Builder()
182             .scheme(ContentResolver.SCHEME_CONTENT)
183             .authority(SettingsSliceProvider.SLICE_AUTHORITY)
184             .appendPath(SettingsSlicesContract.PATH_SETTING_ACTION)
185             .appendPath("media_volume")
186             .build();
187 
188     /**
189      * Full {@link Uri} for the Separate Ring volume Slice.
190      */
191     public static final Uri VOLUME_SEPARATE_RING_URI = new Uri.Builder()
192             .scheme(ContentResolver.SCHEME_CONTENT)
193             .authority(SettingsSliceProvider.SLICE_AUTHORITY)
194             .appendPath(SettingsSlicesContract.PATH_SETTING_ACTION)
195             .appendPath("separate_ring_volume")
196             .build();
197 
198     /**
199      * Full {@link Uri} for the Notification volume Slice.
200      */
201     public static final Uri VOLUME_NOTIFICATION_URI = new Uri.Builder()
202             .scheme(ContentResolver.SCHEME_CONTENT)
203             .authority(SettingsSliceProvider.SLICE_AUTHORITY)
204             .appendPath(SettingsSlicesContract.PATH_SETTING_ACTION)
205             .appendPath("notification_volume")
206             .build();
207 
208     /**
209      * Full {@link Uri} for the all volume Slices.
210      */
211     public static final Uri VOLUME_SLICES_URI = new Uri.Builder()
212             .scheme(ContentResolver.SCHEME_CONTENT)
213             .authority(SettingsSliceProvider.SLICE_AUTHORITY)
214             .appendPath(SettingsSlicesContract.PATH_SETTING_ACTION)
215             .appendPath("volume_slices")
216             .build();
217 
218     /**
219      * Full {@link Uri} for the Wifi Calling Slice.
220      */
221     public static final Uri WIFI_CALLING_URI = new Uri.Builder()
222             .scheme(ContentResolver.SCHEME_CONTENT)
223             .authority(SettingsSliceProvider.SLICE_AUTHORITY)
224             .appendPath(SettingsSlicesContract.PATH_SETTING_INTENT)
225             .appendPath(WifiCallingSliceHelper.PATH_WIFI_CALLING)
226             .build();
227     /**
228      * Full {@link Uri} for the Wifi Calling Preference Slice.
229      */
230     public static final Uri WIFI_CALLING_PREFERENCE_URI = new Uri.Builder()
231             .scheme(ContentResolver.SCHEME_CONTENT)
232             .authority(SettingsSliceProvider.SLICE_AUTHORITY)
233             .appendPath(SettingsSlicesContract.PATH_SETTING_ACTION)
234             .appendPath(WifiCallingSliceHelper.PATH_WIFI_CALLING_PREFERENCE)
235             .build();
236     /**
237      * Backing Uri for the Wifi Slice.
238      */
239     public static final Uri WIFI_SLICE_URI = new Uri.Builder()
240             .scheme(ContentResolver.SCHEME_CONTENT)
241             .authority(SettingsSlicesContract.AUTHORITY)
242             .appendPath(SettingsSlicesContract.PATH_SETTING_ACTION)
243             .appendPath(KEY_WIFI)
244             .build();
245 
246     /**
247      * Backing Uri for the Zen Mode Slice.
248      */
249     public static final Uri ZEN_MODE_SLICE_URI = new Uri.Builder()
250             .scheme(ContentResolver.SCHEME_CONTENT)
251             .authority(SettingsSliceProvider.SLICE_AUTHORITY)
252             .appendPath(SettingsSlicesContract.PATH_SETTING_ACTION)
253             .appendPath(ZenModeButtonPreferenceController.KEY)
254             .build();
255 
256     /**
257      * Backing Uri for the Media output indicator Slice.
258      */
259     public static Uri MEDIA_OUTPUT_INDICATOR_SLICE_URI = new Uri.Builder()
260             .scheme(ContentResolver.SCHEME_CONTENT)
261             .authority(SettingsSliceProvider.SLICE_AUTHORITY)
262             .appendPath(SettingsSlicesContract.PATH_SETTING_INTENT)
263             .appendPath("media_output_indicator")
264             .build();
265 
266     /**
267      * Backing Uri for the Dark theme Slice.
268      */
269     public static final Uri DARK_THEME_SLICE_URI = new Uri.Builder()
270             .scheme(ContentResolver.SCHEME_CONTENT)
271             .authority(SettingsSliceProvider.SLICE_AUTHORITY)
272             .appendPath(SettingsSlicesContract.PATH_SETTING_ACTION)
273             .appendPath("dark_theme")
274             .build();
275 
276     /**
277      * Backing Uri for the Remote Media Slice.
278      */
279     public static Uri REMOTE_MEDIA_SLICE_URI = new Uri.Builder()
280             .scheme(ContentResolver.SCHEME_CONTENT)
281             .authority(SettingsSliceProvider.SLICE_AUTHORITY)
282             .appendPath(SettingsSlicesContract.PATH_SETTING_ACTION)
283             .appendPath(MediaOutputConstants.KEY_REMOTE_MEDIA)
284             .build();
285 
286     /**
287      * Backing Uri for the Always On Slice.
288      */
289     public static final Uri ALWAYS_ON_SLICE_URI = new Uri.Builder()
290             .scheme(ContentResolver.SCHEME_CONTENT)
291             .authority(SettingsSliceProvider.SLICE_AUTHORITY)
292             .appendPath(SettingsSlicesContract.PATH_SETTING_ACTION)
293             .appendPath("always_on_display")
294             .build();
295 
296     @VisibleForTesting
297     static final Map<Uri, Class<? extends CustomSliceable>> sUriToSlice;
298 
299     static {
300         sUriToSlice = new ArrayMap<>();
sUriToSlice.put(FLASHLIGHT_SLICE_URI, FlashlightSlice.class)301         sUriToSlice.put(FLASHLIGHT_SLICE_URI, FlashlightSlice.class);
sUriToSlice.put(LOCATION_SLICE_URI, LocationSlice.class)302         sUriToSlice.put(LOCATION_SLICE_URI, LocationSlice.class);
sUriToSlice.put(MOBILE_DATA_SLICE_URI, MobileDataSlice.class)303         sUriToSlice.put(MOBILE_DATA_SLICE_URI, MobileDataSlice.class);
sUriToSlice.put(PROVIDER_MODEL_SLICE_URI, ProviderModelSlice.class)304         sUriToSlice.put(PROVIDER_MODEL_SLICE_URI, ProviderModelSlice.class);
sUriToSlice.put(WIFI_SLICE_URI, WifiSlice.class)305         sUriToSlice.put(WIFI_SLICE_URI, WifiSlice.class);
sUriToSlice.put(DARK_THEME_SLICE_URI, DarkThemeSlice.class)306         sUriToSlice.put(DARK_THEME_SLICE_URI, DarkThemeSlice.class);
sUriToSlice.put(ALWAYS_ON_SLICE_URI, AlwaysOnDisplaySlice.class)307         sUriToSlice.put(ALWAYS_ON_SLICE_URI, AlwaysOnDisplaySlice.class);
sUriToSlice.put(MEDIA_OUTPUT_INDICATOR_SLICE_URI, MediaOutputIndicatorSlice.class)308         sUriToSlice.put(MEDIA_OUTPUT_INDICATOR_SLICE_URI, MediaOutputIndicatorSlice.class);
sUriToSlice.put(REMOTE_MEDIA_SLICE_URI, RemoteMediaSlice.class)309         sUriToSlice.put(REMOTE_MEDIA_SLICE_URI, RemoteMediaSlice.class);
310 
311         // Slices for contextual card.
sUriToSlice.put(FACE_ENROLL_SLICE_URI, FaceSetupSlice.class)312         sUriToSlice.put(FACE_ENROLL_SLICE_URI, FaceSetupSlice.class);
sUriToSlice.put(CONTEXTUAL_ADAPTIVE_SLEEP_URI, ContextualAdaptiveSleepSlice.class)313         sUriToSlice.put(CONTEXTUAL_ADAPTIVE_SLEEP_URI, ContextualAdaptiveSleepSlice.class);
sUriToSlice.put(LOW_STORAGE_SLICE_URI, LowStorageSlice.class)314         sUriToSlice.put(LOW_STORAGE_SLICE_URI, LowStorageSlice.class);
sUriToSlice.put(BLUETOOTH_DEVICES_SLICE_URI, BluetoothDevicesSlice.class)315         sUriToSlice.put(BLUETOOTH_DEVICES_SLICE_URI, BluetoothDevicesSlice.class);
316     }
317 
getSliceClassByUri(Uri uri)318     public static Class<? extends CustomSliceable> getSliceClassByUri(Uri uri) {
319         return sUriToSlice.get(removeParameterFromUri(uri));
320     }
321 
removeParameterFromUri(Uri uri)322     public static Uri removeParameterFromUri(Uri uri) {
323         return uri != null ? uri.buildUpon().clearQuery().build() : null;
324     }
325 
326     /**
327      * Returns {@code true} if {@param uri} is a valid Slice Uri handled by
328      * {@link CustomSliceRegistry}.
329      */
isValidUri(Uri uri)330     public static boolean isValidUri(Uri uri) {
331         return sUriToSlice.containsKey(removeParameterFromUri(uri));
332     }
333 
334     /**
335      * Returns {@code true} if {@param action} is a valid intent action handled by
336      * {@link CustomSliceRegistry}.
337      */
isValidAction(String action)338     public static boolean isValidAction(String action) {
339         return isValidUri(Uri.parse(action));
340     }
341 }
342