• 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/nested_data_ptr.h"
24 
25 #include "chre_api/chre/user_settings.h"
26 
27 namespace chre {
28 
29 namespace {
30 
31 constexpr size_t kNumSettings = static_cast<size_t>(Setting::SETTING_MAX);
32 
33 //! The current state for each setting.
34 SettingState gSettingStateList[kNumSettings];
35 
36 /**
37  * @param setting The setting to get the index for.
38  * @param index A non-null pointer to store the index.
39  *
40  * @return false if the setting was invalid.
41  */
getIndexForSetting(Setting setting,size_t * index)42 bool getIndexForSetting(Setting setting, size_t *index) {
43   if (setting < Setting::SETTING_MAX) {
44     *index = static_cast<size_t>(setting);
45     return true;
46   }
47 
48   return false;
49 }
50 
setSettingState(Setting setting,SettingState state)51 void setSettingState(Setting setting, SettingState state) {
52   size_t index;
53   if (!getIndexForSetting(setting, &index)) {
54     LOGE("Unknown setting %" PRId8, static_cast<int8_t>(setting));
55   } else {
56     gSettingStateList[index] = state;
57   }
58 }
59 
getSettingStateString(Setting setting)60 const char *getSettingStateString(Setting setting) {
61   switch (getSettingState(setting)) {
62     case SettingState::ENABLED:
63       return "enabled";
64       break;
65     case SettingState::DISABLED:
66       return "disabled";
67       break;
68     default:
69       break;
70   }
71 
72   return "unknown";
73 }
74 
sendSettingChangedNotification(Setting setting,SettingState state)75 void sendSettingChangedNotification(Setting setting, SettingState state) {
76   auto *eventData = memoryAlloc<struct chreUserSettingChangedEvent>();
77   auto settingAsInt = static_cast<uint8_t>(setting);
78   uint16_t eventType = CHRE_EVENT_SETTING_CHANGED_FIRST_EVENT + settingAsInt;
79 
80   if (eventData != nullptr) {
81     eventData->setting = settingAsInt;
82     eventData->settingState = static_cast<int8_t>(state);
83 
84     EventLoopManagerSingleton::get()->getEventLoop().postEventOrDie(
85         eventType, eventData, freeEventDataCallback, kBroadcastInstanceId);
86   } else {
87     LOG_OOM();
88   }
89 }
90 
settingChangedCallback(uint16_t,void * data,void * extraData)91 void settingChangedCallback(uint16_t /* type */, void *data, void *extraData) {
92   Setting setting = NestedDataPtr<Setting>(data);
93   SettingState settingState = NestedDataPtr<SettingState>(extraData);
94 
95   setSettingState(setting, settingState);
96 
97   LOGD("Setting changed callback called for setting %u state %u",
98        static_cast<uint8_t>(setting), static_cast<uint8_t>(settingState));
99 
100 #ifdef CHRE_GNSS_SUPPORT_ENABLED
101   EventLoopManagerSingleton::get()->getGnssManager().onSettingChanged(
102       setting, settingState);
103 #endif  // CHRE_GNSS_SUPPORT_ENABLED
104 
105 #ifdef CHRE_AUDIO_SUPPORT_ENABLED
106   EventLoopManagerSingleton::get()->getAudioRequestManager().onSettingChanged(
107       setting, settingState);
108 #endif  // CHRE_AUDIO_SUPPORT_ENABLED
109 
110   sendSettingChangedNotification(setting, settingState);
111 }
112 
113 }  // anonymous namespace
114 
postSettingChange(Setting setting,SettingState state)115 void postSettingChange(Setting setting, SettingState state) {
116   LOGD("Posting setting change: setting type %" PRIu8 " state %" PRIu8,
117        static_cast<uint8_t>(setting), static_cast<uint8_t>(state));
118 
119   EventLoopManagerSingleton::get()->deferCallback(
120       SystemCallbackType::SettingChangeEvent, NestedDataPtr<Setting>(setting),
121       settingChangedCallback, NestedDataPtr<SettingState>(state));
122 }
123 
getSettingState(Setting setting)124 SettingState getSettingState(Setting setting) {
125   size_t index;
126   if (getIndexForSetting(setting, &index)) {
127     return gSettingStateList[index];
128   }
129 
130   LOGE("Unknown setting %" PRIu8, static_cast<uint8_t>(setting));
131   return SettingState::UNKNOWN;
132 }
133 
getSettingStateAsInt8(uint8_t setting)134 int8_t getSettingStateAsInt8(uint8_t setting) {
135   int8_t state = CHRE_USER_SETTING_STATE_UNKNOWN;
136   if (setting < static_cast<uint8_t>(Setting::SETTING_MAX)) {
137     auto settingEnum = static_cast<Setting>(setting);
138     state = static_cast<int8_t>(getSettingState(settingEnum));
139   }
140   return state;
141 }
142 
logSettingStateToBuffer(DebugDumpWrapper & debugDump)143 void logSettingStateToBuffer(DebugDumpWrapper &debugDump) {
144   debugDump.print("\nSettings:");
145   debugDump.print("\n Location %s", getSettingStateString(Setting::LOCATION));
146   debugDump.print("\n WiFi available %s",
147                   getSettingStateString(Setting::WIFI_AVAILABLE));
148   debugDump.print("\n Airplane mode %s",
149                   getSettingStateString(Setting::AIRPLANE_MODE));
150   debugDump.print("\n Microphone Access %s",
151                   getSettingStateString(Setting::MICROPHONE));
152 }
153 
154 }  // namespace chre
155