1 /*
2  * Copyright (C) 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.service
18 
19 import android.os.Binder
20 import android.os.OutcomeReceiver
21 import android.os.Process
22 import android.service.settings.preferences.GetValueRequest
23 import android.service.settings.preferences.GetValueResult
24 import android.service.settings.preferences.MetadataRequest
25 import android.service.settings.preferences.MetadataResult
26 import android.service.settings.preferences.SetValueRequest
27 import android.service.settings.preferences.SetValueResult
28 import android.service.settings.preferences.SettingsPreferenceService
29 import com.android.settingslib.graph.PreferenceGetterApiHandler
30 import com.android.settingslib.graph.PreferenceSetterApiHandler
31 import com.android.settingslib.ipc.ApiPermissionChecker
32 import kotlinx.coroutines.CoroutineScope
33 import kotlinx.coroutines.Dispatchers
34 import kotlinx.coroutines.Job
35 import kotlinx.coroutines.launch
36 import java.lang.Exception
37 
38 class PreferenceService : SettingsPreferenceService() {
39 
40     private val scope = CoroutineScope(Job() + Dispatchers.Main)
41 
42     private val getApiHandler = PreferenceGetterApiHandler(1, ApiPermissionChecker.alwaysAllow())
43     private val setApiHandler = PreferenceSetterApiHandler(2, ApiPermissionChecker.alwaysAllow())
44 
onGetAllPreferenceMetadatanull45     override fun onGetAllPreferenceMetadata(
46         request: MetadataRequest,
47         callback: OutcomeReceiver<MetadataResult, Exception>
48     ) {
49         // TODO(379750656): Update graph API to be usable outside SettingsLib
50         callback.onError(UnsupportedOperationException("Not yet supported"))
51     }
52 
onGetPreferenceValuenull53     override fun onGetPreferenceValue(
54         request: GetValueRequest,
55         callback: OutcomeReceiver<GetValueResult, Exception>
56     ) {
57         scope.launch(Dispatchers.IO) {
58             val apiRequest = transformFrameworkGetValueRequest(request)
59             val response = getApiHandler.invoke(application, Process.myUid(),
60                 Binder.getCallingPid(), apiRequest)
61             val result = transformCatalystGetValueResponse(
62                 this@PreferenceService,
63                 request,
64                 response
65             )
66             if (result == null) {
67                 callback.onError(IllegalStateException("No response"))
68             } else {
69                 callback.onResult(result)
70             }
71         }
72     }
73 
onSetPreferenceValuenull74     override fun onSetPreferenceValue(
75         request: SetValueRequest,
76         callback: OutcomeReceiver<SetValueResult, Exception>
77     ) {
78         scope.launch(Dispatchers.IO) {
79             val apiRequest = transformFrameworkSetValueRequest(request)
80             if (apiRequest == null) {
81                 callback.onResult(
82                     SetValueResult.Builder(SetValueResult.RESULT_INVALID_REQUEST).build()
83                 )
84             } else {
85                 val response = setApiHandler.invoke(application, Process.myUid(),
86                     Binder.getCallingPid(), apiRequest)
87 
88                 callback.onResult(transformCatalystSetValueResponse(response))
89             }
90         }
91     }
92 }
93