/* * Copyright (C) 2020 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "chre/core/settings.h" #include #include "chre/core/event_loop_manager.h" #include "chre/platform/log.h" #include "chre/util/macros.h" #include "chre/util/nested_data_ptr.h" #include "chre_api/chre/user_settings.h" namespace chre { namespace { /** * @param setting The setting to get the index for. * @param index A non-null pointer to store the index. * * @return false if the setting was invalid. */ bool getIndexForSetting(Setting setting, size_t *index) { if (setting < Setting::SETTING_MAX) { *index = static_cast(setting); return true; } return false; } void sendSettingChangedNotification(Setting setting, bool enabled) { auto *eventData = memoryAlloc(); auto settingAsInt = static_cast(setting); uint16_t eventType = CHRE_EVENT_SETTING_CHANGED_FIRST_EVENT + settingAsInt; if (eventData != nullptr) { eventData->setting = settingAsInt; eventData->settingState = enabled ? CHRE_USER_SETTING_STATE_ENABLED : CHRE_USER_SETTING_STATE_DISABLED; EventLoopManagerSingleton::get()->getEventLoop().postEventOrDie( eventType, eventData, freeEventDataCallback, kBroadcastInstanceId); } else { LOG_OOM(); } } } // anonymous namespace SettingManager::SettingManager() { // Default most settings to true until the host tells us otherwise so // nanoapps can begin work during boot which will get canceled if the user has // disabled the feature. for (size_t i = 0; i < ARRAY_SIZE(mSettingStateList); ++i) { mSettingStateList[i] = true; } // Airplane mode should be disabled since it being enabled causes API usage // restrictions. auto airplaneIndex = static_cast(Setting::AIRPLANE_MODE); mSettingStateList[airplaneIndex] = false; } void SettingManager::postSettingChange(Setting setting, bool enabled) { LOGD("Posting setting change: setting type %" PRIu8 " enabled %d", static_cast(setting), enabled); EventLoopManagerSingleton::get()->deferCallback( SystemCallbackType::SettingChangeEvent, NestedDataPtr(setting), settingChangedCallback, NestedDataPtr(enabled)); } bool SettingManager::getSettingEnabled(Setting setting) { size_t index; if (getIndexForSetting(setting, &index)) { return mSettingStateList[index]; } LOGE("Unknown setting %" PRIu8, static_cast(setting)); return false; } int8_t SettingManager::getSettingStateAsInt8(uint8_t setting) { int8_t state = CHRE_USER_SETTING_STATE_UNKNOWN; if (setting < static_cast(Setting::SETTING_MAX)) { auto settingEnum = static_cast(setting); state = static_cast(getSettingEnabled(settingEnum)); } return state; } void SettingManager::logStateToBuffer(DebugDumpWrapper &debugDump) { debugDump.print("\nSettings:"); debugDump.print("\n Location %s", getSettingEnabledString(Setting::LOCATION)); debugDump.print("\n WiFi available %s", getSettingEnabledString(Setting::WIFI_AVAILABLE)); debugDump.print("\n Airplane mode %s", getSettingEnabledString(Setting::AIRPLANE_MODE)); debugDump.print("\n Microphone Access %s", getSettingEnabledString(Setting::MICROPHONE)); debugDump.print("\n BLE available %s", getSettingEnabledString(Setting::BLE_AVAILABLE)); } void SettingManager::settingChangedCallback(uint16_t /* type */, void *data, void *extraData) { Setting setting = NestedDataPtr(data); bool settingEnabled = NestedDataPtr(extraData); EventLoopManagerSingleton::get()->getSettingManager().setSettingState( setting, settingEnabled); LOGD("Setting changed callback called for setting %u enabled %d", static_cast(setting), settingEnabled); #ifdef CHRE_GNSS_SUPPORT_ENABLED EventLoopManagerSingleton::get()->getGnssManager().onSettingChanged( setting, settingEnabled); #endif // CHRE_GNSS_SUPPORT_ENABLED #ifdef CHRE_AUDIO_SUPPORT_ENABLED EventLoopManagerSingleton::get()->getAudioRequestManager().onSettingChanged( setting, settingEnabled); #endif // CHRE_AUDIO_SUPPORT_ENABLED #ifdef CHRE_BLE_SUPPORT_ENABLED EventLoopManagerSingleton::get()->getBleRequestManager().onSettingChanged( setting, settingEnabled); #endif // CHRE_BLE_SUPPORT_ENABLED #ifdef CHRE_WIFI_SUPPORT_ENABLED EventLoopManagerSingleton::get()->getWifiRequestManager().onSettingChanged( setting, settingEnabled); #endif // CHRE_WIFI_SUPPORT_ENABLED sendSettingChangedNotification(setting, settingEnabled); } void SettingManager::setSettingState(Setting setting, bool enabled) { size_t index; if (!getIndexForSetting(setting, &index)) { LOGE("Unknown setting %" PRId8, static_cast(setting)); } else { mSettingStateList[index] = enabled; } } const char *SettingManager::getSettingEnabledString(Setting setting) { if (getSettingEnabled(setting)) { return "enabled"; } else { return "disabled"; } } } // namespace chre