1 /* 2 * Copyright (C) 2023 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 //! Implementation of FusionFrameworks. 17 18 #![allow(dead_code)] 19 #![allow(unused_variables)] 20 21 use std::sync::{ Mutex, Once }; 22 use std::ffi::{ c_char, CString }; 23 24 use hilog_rust::{ error, info, hilog, HiLogLabel, LogType }; 25 use ipc_rust::FileDesc; 26 use fusion_utils_rust::{ call_debug_enter, FusionResult, FusionErrorCode }; 27 use fusion_ipc_client_rust::FusionIpcClient; 28 use fusion_data_rust::{ AllocSocketPairParam, DragData }; 29 use fusion_basic_client_rust::FusionBasicClient; 30 use fusion_drag_client_rust::DragClient; 31 use fusion_coordination_client_rust::FusionCoordinationClient; 32 33 const LOG_LABEL: HiLogLabel = HiLogLabel { 34 log_type: LogType::LogCore, 35 domain: 0xD002220, 36 tag: "FusionFrameworks" 37 }; 38 39 #[derive(Default)] 40 struct Client { 41 ipc_client: Option<FusionIpcClient>, 42 basic: FusionBasicClient, 43 drag: DragClient, 44 coordination: FusionCoordinationClient, 45 } 46 47 impl Client { 48 /// Connect service. connect(&mut self)49 fn connect(&mut self) 50 { 51 if self.ipc_client.is_some() { 52 return; 53 } 54 info!(LOG_LABEL, "Trying to connect server"); 55 match FusionIpcClient::connect() { 56 Ok(client) => { 57 info!(LOG_LABEL, "Connect to server successfully"); 58 self.ipc_client = Some(client); 59 } 60 Err(_) => { 61 error!(LOG_LABEL, "Can not connect to server"); 62 } 63 } 64 } 65 alloc_socket_pair(&self, param: &AllocSocketPairParam) -> FusionResult<(FileDesc, i32)>66 fn alloc_socket_pair(&self, param: &AllocSocketPairParam) -> FusionResult<(FileDesc, i32)> 67 { 68 match self.ipc_client.as_ref() { 69 Some(ipc_client_ref) => { 70 info!(LOG_LABEL, "Call basic.start_drag()"); 71 self.basic.alloc_socket_pair(param, ipc_client_ref) 72 } 73 None => { 74 error!(LOG_LABEL, "ipc_client is none"); 75 Err(FusionErrorCode::Fail) 76 } 77 } 78 } 79 start_drag(&self, drag_data: &DragData) -> FusionResult<i32>80 fn start_drag(&self, drag_data: &DragData) -> FusionResult<i32> 81 { 82 match self.ipc_client.as_ref() { 83 Some(ipc_client_ref) => { 84 info!(LOG_LABEL, "Call drag.start_drag()"); 85 self.drag.start_drag(drag_data, ipc_client_ref) 86 } 87 None => { 88 error!(LOG_LABEL, "ipc_client is none"); 89 Err(FusionErrorCode::Fail) 90 } 91 } 92 } 93 register_coordination_listener(&self) -> FusionResult<()>94 fn register_coordination_listener(&self) -> FusionResult<()> 95 { 96 call_debug_enter!("FusionFrameworks::register_coordination_listener"); 97 match self.ipc_client.as_ref() { 98 Some(ipc_client_ref) => { 99 self.coordination.register_coordination_listener(ipc_client_ref) 100 } 101 None => { 102 error!(LOG_LABEL, "ipc_client is none"); 103 Err(FusionErrorCode::Fail) 104 } 105 } 106 } 107 unregister_coordination_listener(&self) -> FusionResult<()>108 fn unregister_coordination_listener(&self) -> FusionResult<()> 109 { 110 call_debug_enter!("FusionFrameworks::unregister_coordination_listener"); 111 match self.ipc_client.as_ref() { 112 Some(ipc_client_ref) => { 113 self.coordination.unregister_coordination_listener(ipc_client_ref) 114 } 115 None => { 116 error!(LOG_LABEL, "ipc_client is none"); 117 Err(FusionErrorCode::Fail) 118 } 119 } 120 } 121 enable_coordination(&self, user_data: i32) -> FusionResult<()>122 fn enable_coordination(&self, user_data: i32) -> FusionResult<()> 123 { 124 call_debug_enter!("FusionFrameworks::enable_coordination"); 125 match self.ipc_client.as_ref() { 126 Some(ipc_client_ref) => { 127 self.coordination.enable_coordination(user_data, ipc_client_ref) 128 } 129 None => { 130 error!(LOG_LABEL, "ipc_client is none"); 131 Err(FusionErrorCode::Fail) 132 } 133 } 134 } 135 disable_coordination(&self, user_data: i32) -> FusionResult<()>136 fn disable_coordination(&self, user_data: i32) -> FusionResult<()> 137 { 138 call_debug_enter!("FusionFrameworks::disable_coordination"); 139 match self.ipc_client.as_ref() { 140 Some(ipc_client_ref) => { 141 self.coordination.disable_coordination(user_data, ipc_client_ref) 142 } 143 None => { 144 error!(LOG_LABEL, "ipc_client is none"); 145 Err(FusionErrorCode::Fail) 146 } 147 } 148 } 149 start_coordination(&self, user_data: i32, remote_network_id: &str, start_device_id: i32) -> FusionResult<()>150 fn start_coordination(&self, user_data: i32, 151 remote_network_id: &str, 152 start_device_id: i32) -> FusionResult<()> 153 { 154 call_debug_enter!("FusionFrameworks::start_coordination"); 155 match self.ipc_client.as_ref() { 156 Some(ipc_client_ref) => { 157 info!(LOG_LABEL, "Call coordination.start_coordination"); 158 self.coordination.start_coordination(user_data, remote_network_id, 159 start_device_id, ipc_client_ref) 160 } 161 None => { 162 error!(LOG_LABEL, "ipc_client is none"); 163 Err(FusionErrorCode::Fail) 164 } 165 } 166 } 167 stop_coordination(&self, user_data: i32, is_unchained: i32) -> FusionResult<()>168 fn stop_coordination(&self, user_data: i32, is_unchained: i32) -> FusionResult<()> 169 { 170 call_debug_enter!("FusionFrameworks::stop_coordination"); 171 match self.ipc_client.as_ref() { 172 Some(ipc_client_ref) => { 173 self.coordination.stop_coordination(user_data, is_unchained, ipc_client_ref) 174 } 175 None => { 176 error!(LOG_LABEL, "ipc_client is none"); 177 Err(FusionErrorCode::Fail) 178 } 179 } 180 } 181 get_coordination_state(&self, user_data: i32, device_id: &str) -> FusionResult<i32>182 fn get_coordination_state(&self, user_data: i32, device_id: &str) -> FusionResult<i32> 183 { 184 call_debug_enter!("FusionFrameworks::get_coordination_state"); 185 match self.ipc_client.as_ref() { 186 Some(ipc_client_ref) => { 187 self.coordination.get_coordination_state(user_data, device_id, ipc_client_ref) 188 } 189 None => { 190 error!(LOG_LABEL, "ipc_client is none"); 191 Err(FusionErrorCode::Fail) 192 } 193 } 194 } 195 } 196 197 /// struct FusionFrameworks 198 #[derive(Default)] 199 pub struct FusionFrameworks(Mutex<Client>); 200 201 impl FusionFrameworks { 202 /// Get a reference to the single instance of `FusionFrameworks`. get_instance() -> Option<&'static FusionFrameworks>203 pub fn get_instance() -> Option<&'static FusionFrameworks> 204 { 205 static mut FRAMEWORKS: Option<FusionFrameworks> = None; 206 static INIT_ONCE: Once = Once::new(); 207 unsafe { 208 INIT_ONCE.call_once(|| { 209 FRAMEWORKS = Some(FusionFrameworks::default()); 210 }); 211 FRAMEWORKS.as_ref() 212 } 213 } 214 215 /// Request connection of service via socket. alloc_socket_pair(&self, param: &AllocSocketPairParam) -> FusionResult<(FileDesc, i32)>216 pub fn alloc_socket_pair(&self, param: &AllocSocketPairParam) -> FusionResult<(FileDesc, i32)> 217 { 218 let mut guard = self.0.lock().unwrap(); 219 guard.connect(); 220 guard.alloc_socket_pair(param) 221 } 222 223 /// Request service to change to [`DRAG`] mode. start_drag(&self, drag_data: &DragData) -> FusionResult<i32>224 pub fn start_drag(&self, drag_data: &DragData) -> FusionResult<i32> 225 { 226 let mut guard = self.0.lock().unwrap(); 227 guard.connect(); 228 guard.start_drag(drag_data) 229 } 230 231 /// Request to listen for events of multi-device cooperation. register_coordination_listener(&self) -> FusionResult<()>232 pub fn register_coordination_listener(&self) -> FusionResult<()> 233 { 234 let mut guard = self.0.lock().unwrap(); 235 guard.connect(); 236 guard.register_coordination_listener() 237 } 238 239 /// Request to stop listening for events of multi-device cooperation. unregister_coordination_listener(&self) -> FusionResult<()>240 pub fn unregister_coordination_listener(&self) -> FusionResult<()> 241 { 242 let mut guard = self.0.lock().unwrap(); 243 guard.connect(); 244 guard.unregister_coordination_listener() 245 } 246 247 /// Request to enable multi-device cooperation. enable_coordination(&self, user_data: i32) -> FusionResult<()>248 pub fn enable_coordination(&self, user_data: i32) -> FusionResult<()> 249 { 250 let mut guard = self.0.lock().unwrap(); 251 guard.connect(); 252 guard.enable_coordination(user_data) 253 } 254 255 /// Request to disable multi-device cooperation. disable_coordination(&self, user_data: i32) -> FusionResult<()>256 pub fn disable_coordination(&self, user_data: i32) -> FusionResult<()> 257 { 258 let mut guard = self.0.lock().unwrap(); 259 guard.connect(); 260 guard.disable_coordination(user_data) 261 } 262 263 /// Request to start multi-device cooperation. start_coordination(&self, user_data: i32, remote_network_id: &str, start_device_id: i32) -> FusionResult<()>264 pub fn start_coordination(&self, user_data: i32, 265 remote_network_id: &str, 266 start_device_id: i32) -> FusionResult<()> 267 { 268 let mut guard = self.0.lock().unwrap(); 269 guard.connect(); 270 guard.start_coordination(user_data, remote_network_id, start_device_id) 271 } 272 273 /// Request to stop multi-device cooperation. stop_coordination(&self, user_data: i32, is_unchained: i32) -> FusionResult<()>274 pub fn stop_coordination(&self, user_data: i32, is_unchained: i32) -> FusionResult<()> 275 { 276 let mut guard = self.0.lock().unwrap(); 277 guard.connect(); 278 guard.stop_coordination(user_data, is_unchained) 279 } 280 281 /// Request for current switch status of multi-device cooperation. get_coordination_state(&self, user_data: i32, device_id: &str) -> FusionResult<i32>282 pub fn get_coordination_state(&self, user_data: i32, device_id: &str) -> FusionResult<i32> 283 { 284 let mut guard = self.0.lock().unwrap(); 285 guard.connect(); 286 guard.get_coordination_state(user_data, device_id) 287 } 288 } 289