1*4d7e907cSAndroid Build Coastguard Worker /* 2*4d7e907cSAndroid Build Coastguard Worker * Copyright (C) 2023 The Android Open Source Project 3*4d7e907cSAndroid Build Coastguard Worker * 4*4d7e907cSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License"); 5*4d7e907cSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License. 6*4d7e907cSAndroid Build Coastguard Worker * You may obtain a copy of the License at 7*4d7e907cSAndroid Build Coastguard Worker * 8*4d7e907cSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0 9*4d7e907cSAndroid Build Coastguard Worker * 10*4d7e907cSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software 11*4d7e907cSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS, 12*4d7e907cSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*4d7e907cSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and 14*4d7e907cSAndroid Build Coastguard Worker * limitations under the License. 15*4d7e907cSAndroid Build Coastguard Worker */ 16*4d7e907cSAndroid Build Coastguard Worker //! This module implements the ILights AIDL interface. 17*4d7e907cSAndroid Build Coastguard Worker 18*4d7e907cSAndroid Build Coastguard Worker use std::collections::HashMap; 19*4d7e907cSAndroid Build Coastguard Worker use std::sync::Mutex; 20*4d7e907cSAndroid Build Coastguard Worker 21*4d7e907cSAndroid Build Coastguard Worker use log::info; 22*4d7e907cSAndroid Build Coastguard Worker 23*4d7e907cSAndroid Build Coastguard Worker use android_hardware_light::aidl::android::hardware::light::{ 24*4d7e907cSAndroid Build Coastguard Worker HwLight::HwLight, HwLightState::HwLightState, ILights::ILights, LightType::LightType, 25*4d7e907cSAndroid Build Coastguard Worker }; 26*4d7e907cSAndroid Build Coastguard Worker 27*4d7e907cSAndroid Build Coastguard Worker use binder::{ExceptionCode, Interface, Status}; 28*4d7e907cSAndroid Build Coastguard Worker 29*4d7e907cSAndroid Build Coastguard Worker struct Light { 30*4d7e907cSAndroid Build Coastguard Worker hw_light: HwLight, 31*4d7e907cSAndroid Build Coastguard Worker state: HwLightState, 32*4d7e907cSAndroid Build Coastguard Worker } 33*4d7e907cSAndroid Build Coastguard Worker 34*4d7e907cSAndroid Build Coastguard Worker const NUM_DEFAULT_LIGHTS: i32 = 3; 35*4d7e907cSAndroid Build Coastguard Worker 36*4d7e907cSAndroid Build Coastguard Worker /// Defined so we can implement the ILights AIDL interface. 37*4d7e907cSAndroid Build Coastguard Worker pub struct LightsService { 38*4d7e907cSAndroid Build Coastguard Worker lights: Mutex<HashMap<i32, Light>>, 39*4d7e907cSAndroid Build Coastguard Worker } 40*4d7e907cSAndroid Build Coastguard Worker 41*4d7e907cSAndroid Build Coastguard Worker impl Interface for LightsService {} 42*4d7e907cSAndroid Build Coastguard Worker 43*4d7e907cSAndroid Build Coastguard Worker impl LightsService { new(hw_lights: impl IntoIterator<Item = HwLight>) -> Self44*4d7e907cSAndroid Build Coastguard Worker fn new(hw_lights: impl IntoIterator<Item = HwLight>) -> Self { 45*4d7e907cSAndroid Build Coastguard Worker let mut lights_map = HashMap::new(); 46*4d7e907cSAndroid Build Coastguard Worker 47*4d7e907cSAndroid Build Coastguard Worker for hw_light in hw_lights { 48*4d7e907cSAndroid Build Coastguard Worker lights_map.insert(hw_light.id, Light { hw_light, state: Default::default() }); 49*4d7e907cSAndroid Build Coastguard Worker } 50*4d7e907cSAndroid Build Coastguard Worker 51*4d7e907cSAndroid Build Coastguard Worker Self { lights: Mutex::new(lights_map) } 52*4d7e907cSAndroid Build Coastguard Worker } 53*4d7e907cSAndroid Build Coastguard Worker } 54*4d7e907cSAndroid Build Coastguard Worker 55*4d7e907cSAndroid Build Coastguard Worker impl Default for LightsService { default() -> Self56*4d7e907cSAndroid Build Coastguard Worker fn default() -> Self { 57*4d7e907cSAndroid Build Coastguard Worker let id_mapping_closure = 58*4d7e907cSAndroid Build Coastguard Worker |light_id| HwLight { id: light_id, ordinal: light_id, r#type: LightType::BACKLIGHT }; 59*4d7e907cSAndroid Build Coastguard Worker 60*4d7e907cSAndroid Build Coastguard Worker Self::new((1..=NUM_DEFAULT_LIGHTS).map(id_mapping_closure)) 61*4d7e907cSAndroid Build Coastguard Worker } 62*4d7e907cSAndroid Build Coastguard Worker } 63*4d7e907cSAndroid Build Coastguard Worker 64*4d7e907cSAndroid Build Coastguard Worker impl ILights for LightsService { setLightState(&self, id: i32, state: &HwLightState) -> binder::Result<()>65*4d7e907cSAndroid Build Coastguard Worker fn setLightState(&self, id: i32, state: &HwLightState) -> binder::Result<()> { 66*4d7e907cSAndroid Build Coastguard Worker info!("Lights setting state for id={} to color {:x}", id, state.color); 67*4d7e907cSAndroid Build Coastguard Worker 68*4d7e907cSAndroid Build Coastguard Worker if let Some(light) = self.lights.lock().unwrap().get_mut(&id) { 69*4d7e907cSAndroid Build Coastguard Worker light.state = *state; 70*4d7e907cSAndroid Build Coastguard Worker Ok(()) 71*4d7e907cSAndroid Build Coastguard Worker } else { 72*4d7e907cSAndroid Build Coastguard Worker Err(Status::new_exception(ExceptionCode::UNSUPPORTED_OPERATION, None)) 73*4d7e907cSAndroid Build Coastguard Worker } 74*4d7e907cSAndroid Build Coastguard Worker } 75*4d7e907cSAndroid Build Coastguard Worker getLights(&self) -> binder::Result<Vec<HwLight>>76*4d7e907cSAndroid Build Coastguard Worker fn getLights(&self) -> binder::Result<Vec<HwLight>> { 77*4d7e907cSAndroid Build Coastguard Worker info!("Lights reporting supported lights"); 78*4d7e907cSAndroid Build Coastguard Worker Ok(self.lights.lock().unwrap().values().map(|light| light.hw_light).collect()) 79*4d7e907cSAndroid Build Coastguard Worker } 80*4d7e907cSAndroid Build Coastguard Worker } 81