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 namespace chre {
26 
27 namespace {
28 
29 //! The current state for each setting.
30 SettingState gSettingStateList[static_cast<size_t>(Setting::SETTING_MAX)];
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  */
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 
47 void setSettingState(Setting setting, SettingState state) {
48   size_t index;
49   if (!getIndexForSetting(setting, &index)) {
50     LOGE("Unknown setting %" PRIu8, static_cast<uint8_t>(setting));
51   } else {
52     gSettingStateList[index] = state;
53   }
54 }
55 
56 const char *getSettingStateString(Setting setting) {
57   switch (getSettingState(Setting::LOCATION)) {
58     case SettingState::ENABLED:
59       return "enabled";
60       break;
61     case SettingState::DISABLED:
62       return "disabled";
63       break;
64     default:
65       break;
66   }
67 
68   return "unknown";
69 }
70 
71 }  // anonymous namespace
72 
73 void postSettingChange(Setting setting, SettingState state) {
74   LOGD("Posting setting change: setting type %" PRIu8 " state %" PRIu8,
75        static_cast<uint8_t>(setting), static_cast<uint8_t>(state));
76   struct SettingChange {
77     Setting setting;
78     SettingState state;
79 
80     SettingChange(Setting setting, SettingState state) {
81       this->setting = setting;
82       this->state = state;
83     }
84   };
85 
86   NestedDataPtr<SettingChange> nestedPtr(SettingChange(setting, state));
87 
88   auto callback = [](uint16_t /* type */, void *data) {
89     NestedDataPtr<SettingChange> setting;
90     setting.dataPtr = data;
91     setSettingState(setting.data.setting, setting.data.state);
92 #ifdef CHRE_GNSS_SUPPORT_ENABLED
93     EventLoopManagerSingleton::get()->getGnssManager().onSettingChanged(
94         setting.data.setting, setting.data.state);
95 #endif  // CHRE_GNSS_SUPPORT_ENABLED
96   };
97 
98   EventLoopManagerSingleton::get()->deferCallback(
99       SystemCallbackType::SettingChangeEvent, nestedPtr.dataPtr, callback);
100 }
101 
102 SettingState getSettingState(Setting setting) {
103   size_t index;
104   if (getIndexForSetting(setting, &index)) {
105     return gSettingStateList[index];
106   }
107 
108   LOGE("Unknown setting %" PRIu8, static_cast<uint8_t>(setting));
109   return SettingState::SETTING_STATE_MAX;
110 }
111 
112 void logSettingStateToBuffer(DebugDumpWrapper &debugDump) {
113   debugDump.print("\nSettings:");
114   debugDump.print("\n Location %s", getSettingStateString(Setting::LOCATION));
115 }
116 
117 }  // namespace chre
118