• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 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 package com.android.permissioncontroller.privacysources
17 
18 import android.content.ComponentName
19 import android.content.Context
20 import android.provider.Settings
21 import android.text.TextUtils
22 import android.util.Log
23 import kotlinx.coroutines.sync.Mutex
24 import kotlinx.coroutines.sync.withLock
25 
26 /**
27  * Code reference from https://source.corp.google.com/android/frameworks/base/packages/SettingsLib/
28  * src/com/android/settingslib/accessibility/AccessibilityUtils.java
29  */
30 object AccessibilitySettingsUtil {
31     private const val ENABLED_ACCESSIBILITY_SERVICES_SEPARATOR = ':'
32     private val LOG_TAG = AccessibilitySettingsUtil::class.java.simpleName
33     private val lock = Mutex()
34 
35     /**
36      * Changes an accessibility component's state.
37      */
disableAccessibilityServicenull38     suspend fun disableAccessibilityService(context: Context, serviceToBeDisabled: ComponentName) {
39         lock.withLock {
40             val settingsEnabledA11yServices = getEnabledServicesFromSettings(context)
41             if (settingsEnabledA11yServices.isEmpty() ||
42                 !settingsEnabledA11yServices.contains(serviceToBeDisabled)
43             ) {
44                 Log.w(LOG_TAG, "${serviceToBeDisabled.toShortString()} is already disabled " +
45                     "or not installed.")
46                 return
47             }
48 
49             settingsEnabledA11yServices.remove(serviceToBeDisabled)
50 
51             val updatedEnabledServices = settingsEnabledA11yServices.map { it.flattenToString() }
52                 .joinToString(separator = ENABLED_ACCESSIBILITY_SERVICES_SEPARATOR.toString())
53 
54             Settings.Secure.putString(
55                 context.contentResolver,
56                 Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES,
57                 updatedEnabledServices
58             )
59         }
60     }
61 
62     /**
63      * @return the mutable set of enabled accessibility services.
64      */
getEnabledServicesFromSettingsnull65     fun getEnabledServicesFromSettings(context: Context): MutableSet<ComponentName> {
66         val enabledServicesSetting = Settings.Secure.getString(
67             context.contentResolver, Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES
68         )
69         val enabledServices = mutableSetOf<ComponentName>()
70         if (TextUtils.isEmpty(enabledServicesSetting)) {
71             return enabledServices
72         }
73 
74         val colonSplitter: TextUtils.StringSplitter = TextUtils.SimpleStringSplitter(
75             ENABLED_ACCESSIBILITY_SERVICES_SEPARATOR
76         )
77         colonSplitter.setString(enabledServicesSetting)
78 
79         for (componentNameString in colonSplitter) {
80             val enabledService = ComponentName.unflattenFromString(
81                 componentNameString
82             )
83             if (enabledService != null) {
84                 enabledServices.add(enabledService)
85             } else {
86                 Log.e(LOG_TAG, "unable to parse accessibility service $componentNameString")
87             }
88         }
89 
90         return enabledServices
91     }
92 }
93