• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2020 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 #include "chre/core/settings.h"
18 
19 #include <cstddef>
20 
21 #include "chre/core/event_loop_manager.h"
22 #include "chre/platform/log.h"
23 #include "chre/util/macros.h"
24 #include "chre/util/nested_data_ptr.h"
25 
26 #include "chre_api/chre/user_settings.h"
27 
28 namespace chre {
29 
30 namespace {
31 
32 /**
33  * @param setting The setting to get the index for.
34  * @param index A non-null pointer to store the index.
35  *
36  * @return false if the setting was invalid.
37  */
getIndexForSetting(Setting setting,size_t * index)38 bool getIndexForSetting(Setting setting, size_t *index) {
39   if (setting < Setting::SETTING_MAX) {
40     *index = static_cast<size_t>(setting);
41     return true;
42   }
43 
44   return false;
45 }
46 
sendSettingChangedNotification(Setting setting,bool enabled)47 void sendSettingChangedNotification(Setting setting, bool enabled) {
48   auto *eventData = memoryAlloc<struct chreUserSettingChangedEvent>();
49   auto settingAsInt = static_cast<uint8_t>(setting);
50   uint16_t eventType = CHRE_EVENT_SETTING_CHANGED_FIRST_EVENT + settingAsInt;
51 
52   if (eventData != nullptr) {
53     eventData->setting = settingAsInt;
54     eventData->settingState = enabled ? CHRE_USER_SETTING_STATE_ENABLED
55                                       : CHRE_USER_SETTING_STATE_DISABLED;
56 
57     EventLoopManagerSingleton::get()->getEventLoop().postEventOrDie(
58         eventType, eventData, freeEventDataCallback, kBroadcastInstanceId);
59   } else {
60     LOG_OOM();
61   }
62 }
63 
64 }  // anonymous namespace
65 
SettingManager()66 SettingManager::SettingManager() {
67   // Default most settings to true until the host tells us otherwise so
68   // nanoapps can begin work during boot which will get canceled if the user has
69   // disabled the feature.
70   for (size_t i = 0; i < ARRAY_SIZE(mSettingStateList); ++i) {
71     mSettingStateList[i] = true;
72   }
73 
74   // Airplane mode should be disabled since it being enabled causes API usage
75   // restrictions.
76   auto airplaneIndex = static_cast<uint8_t>(Setting::AIRPLANE_MODE);
77   mSettingStateList[airplaneIndex] = false;
78 }
79 
postSettingChange(Setting setting,bool enabled)80 void SettingManager::postSettingChange(Setting setting, bool enabled) {
81   LOGD("Posting setting change: setting type %" PRIu8 " enabled %d",
82        static_cast<uint8_t>(setting), enabled);
83 
84   EventLoopManagerSingleton::get()->deferCallback(
85       SystemCallbackType::SettingChangeEvent, NestedDataPtr<Setting>(setting),
86       settingChangedCallback, NestedDataPtr<bool>(enabled));
87 }
88 
getSettingEnabled(Setting setting)89 bool SettingManager::getSettingEnabled(Setting setting) {
90   size_t index;
91   if (getIndexForSetting(setting, &index)) {
92     return mSettingStateList[index];
93   }
94 
95   LOGE("Unknown setting %" PRIu8, static_cast<uint8_t>(setting));
96   return false;
97 }
98 
getSettingStateAsInt8(uint8_t setting)99 int8_t SettingManager::getSettingStateAsInt8(uint8_t setting) {
100   int8_t state = CHRE_USER_SETTING_STATE_UNKNOWN;
101   if (setting < static_cast<uint8_t>(Setting::SETTING_MAX)) {
102     auto settingEnum = static_cast<Setting>(setting);
103     state = static_cast<int8_t>(getSettingEnabled(settingEnum));
104   }
105   return state;
106 }
107 
logStateToBuffer(DebugDumpWrapper & debugDump)108 void SettingManager::logStateToBuffer(DebugDumpWrapper &debugDump) {
109   debugDump.print("\nSettings:");
110   debugDump.print("\n Location %s", getSettingEnabledString(Setting::LOCATION));
111   debugDump.print("\n WiFi available %s",
112                   getSettingEnabledString(Setting::WIFI_AVAILABLE));
113   debugDump.print("\n Airplane mode %s",
114                   getSettingEnabledString(Setting::AIRPLANE_MODE));
115   debugDump.print("\n Microphone Access %s",
116                   getSettingEnabledString(Setting::MICROPHONE));
117   debugDump.print("\n BLE available %s",
118                   getSettingEnabledString(Setting::BLE_AVAILABLE));
119 }
120 
settingChangedCallback(uint16_t,void * data,void * extraData)121 void SettingManager::settingChangedCallback(uint16_t /* type */, void *data,
122                                             void *extraData) {
123   Setting setting = NestedDataPtr<Setting>(data);
124   bool settingEnabled = NestedDataPtr<bool>(extraData);
125 
126   EventLoopManagerSingleton::get()->getSettingManager().setSettingState(
127       setting, settingEnabled);
128 
129   LOGD("Setting changed callback called for setting %u enabled %d",
130        static_cast<uint8_t>(setting), settingEnabled);
131 
132 #ifdef CHRE_GNSS_SUPPORT_ENABLED
133   EventLoopManagerSingleton::get()->getGnssManager().onSettingChanged(
134       setting, settingEnabled);
135 #endif  // CHRE_GNSS_SUPPORT_ENABLED
136 
137 #ifdef CHRE_AUDIO_SUPPORT_ENABLED
138   EventLoopManagerSingleton::get()->getAudioRequestManager().onSettingChanged(
139       setting, settingEnabled);
140 #endif  // CHRE_AUDIO_SUPPORT_ENABLED
141 
142 #ifdef CHRE_BLE_SUPPORT_ENABLED
143   EventLoopManagerSingleton::get()->getBleRequestManager().onSettingChanged(
144       setting, settingEnabled);
145 #endif  // CHRE_BLE_SUPPORT_ENABLED
146 
147 #ifdef CHRE_WIFI_SUPPORT_ENABLED
148   EventLoopManagerSingleton::get()->getWifiRequestManager().onSettingChanged(
149       setting, settingEnabled);
150 #endif  // CHRE_WIFI_SUPPORT_ENABLED
151 
152   sendSettingChangedNotification(setting, settingEnabled);
153 }
154 
setSettingState(Setting setting,bool enabled)155 void SettingManager::setSettingState(Setting setting, bool enabled) {
156   size_t index;
157   if (!getIndexForSetting(setting, &index)) {
158     LOGE("Unknown setting %" PRId8, static_cast<int8_t>(setting));
159   } else {
160     mSettingStateList[index] = enabled;
161   }
162 }
163 
getSettingEnabledString(Setting setting)164 const char *SettingManager::getSettingEnabledString(Setting setting) {
165   if (getSettingEnabled(setting)) {
166     return "enabled";
167   } else {
168     return "disabled";
169   }
170 }
171 
172 }  // namespace chre
173