• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 use hdc::common::base::Base;
16 use hdc::common::filemanager::FileManager;
17 use hdc::common::hdctransfer::{self, HdcTransferBase};
18 use hdc::common::taskbase::TaskBase;
19 use hdc::config;
20 use hdc::config::HdcCommand;
21 use hdc::config::TaskMessage;
22 use hdc::config::TRANSFER_FUNC_NAME;
23 use hdc::serializer::serialize::Serialization;
24 use hdc::transfer;
25 use hdc::transfer::EchoLevel;
26 use hdc::utils;
27 use std::path::PathBuf;
28 
29 pub struct HostAppTask {
30     pub transfer: HdcTransferBase,
31 }
32 
33 impl HostAppTask {
new(_session_id: u32, _channel_id: u32) -> Self34     pub fn new(_session_id: u32, _channel_id: u32) -> Self {
35         Self {
36             transfer: HdcTransferBase::new(_session_id, _channel_id),
37         }
38     }
39 
get_sub_app_files_resurively(_path: &String) -> Vec<String>40     pub fn get_sub_app_files_resurively(_path: &String) -> Vec<String> {
41         let mut result = Vec::new();
42         let dir_path = PathBuf::from(_path);
43         for entry in std::fs::read_dir(dir_path).unwrap() {
44             let path = entry.unwrap().path();
45             let p = path.display().to_string();
46             if p.ends_with(".hap") || p.ends_with(".hsp") {
47                 result.push(p.clone());
48             } else {
49                 let mut sub_list = Self::get_sub_app_files_resurively(&p);
50                 result.append(&mut sub_list);
51             }
52         }
53         result.sort();
54         result
55     }
56 
init_install(&mut self, command: &String) -> bool57     pub fn init_install(&mut self, command: &String) -> bool {
58         let (argv, argc) = Base::split_command_to_args(command);
59         if argc < 1 {
60             return false;
61         }
62         let mut i = 0usize;
63         let mut options = String::from("");
64         while i < argc as usize {
65             if argv[i] == "-cwd" {
66                 if i + 1 < argc as usize {
67                     self.transfer.transfer_config.client_cwd = argv[i + 1].clone();
68                     i += 1;
69                 }
70             } else if argv[i].starts_with("-") {
71                 if !options.is_empty() {
72                     options.push(' ');
73                 }
74                 options.push_str(&mut argv[i].clone());
75             } else {
76                 let mut path = argv[i].clone() as String;
77                 path = Base::extract_relative_path(
78                     &self.transfer.transfer_config.client_cwd,
79                     path.as_str(),
80                 );
81                 if path.ends_with(".hap") || path.ends_with(".hsp") {
82                     self.transfer.task_queue.push(path.clone());
83                 } else {
84                     let mut queue = Self::get_sub_app_files_resurively(&path);
85                     self.transfer.task_queue.append(&mut queue);
86                 }
87             }
88             i += 1;
89         }
90 
91         if self.transfer.task_queue.is_empty() {
92             return false;
93         }
94 
95         self.transfer.transfer_config.options = options.clone();
96         self.transfer.transfer_config.function_name = TRANSFER_FUNC_NAME.to_string();
97 
98         self.transfer.is_master = true;
99         self.install_single();
100 
101         true
102     }
103 
install_single(&mut self)104     fn install_single(&mut self) {
105         self.transfer.local_path = self.transfer.task_queue.pop().unwrap();
106         let local_path = self.transfer.local_path.clone();
107         let mut file_manager = FileManager::new(local_path.clone());
108         let open_result = file_manager.open();
109         if open_result {
110             let config = &mut self.transfer.transfer_config;
111             config.file_size = file_manager.file_size();
112             self.transfer.file_size = config.file_size;
113             config.optional_name = utils::get_pseudo_random_u32().to_string();
114             if let Some(index) = local_path.rfind('.') {
115                 let str = local_path.as_str();
116                 config.optional_name.push_str(&str[index..]);
117             }
118             if config.hold_timestamp {}
119             config.path = self.transfer.remote_path.clone();
120         } else {
121             self.task_finish();
122         }
123     }
124 
put_app_check(&mut self)125     fn put_app_check(&mut self) {
126         let file_check_message = TaskMessage {
127             channel_id: self.transfer.channel_id,
128             command: HdcCommand::AppCheck,
129             payload: self.transfer.transfer_config.serialize(),
130         };
131         let send_msg_task = async {
132             transfer::put(self.transfer.session_id, file_check_message).await;
133         };
134         ylong_runtime::block_on(send_msg_task);
135     }
136 
do_app_finish(&mut self, _payload: &Vec<u8>) -> bool137     fn do_app_finish(&mut self, _payload: &Vec<u8>) -> bool {
138         let mode = config::AppModeType::try_from(_payload[0]);
139         if let Ok(mode_type) = mode {
140             let str = String::from_utf8(_payload[2..].to_vec()).unwrap();
141             return self.check_install_continue(mode_type, str.clone());
142         }
143         false
144     }
145 
do_app_uninstall(&mut self, _payload: &Vec<u8>)146     fn do_app_uninstall(&mut self, _payload: &Vec<u8>) {
147         let app_uninstall_message = TaskMessage {
148             channel_id: self.transfer.channel_id,
149             command: HdcCommand::AppUninstall,
150             payload: _payload.to_vec(),
151         };
152         let send_msg_task = async {
153             transfer::put(self.transfer.session_id, app_uninstall_message).await;
154         };
155         ylong_runtime::block_on(send_msg_task);
156     }
157 
check_install_continue(&mut self, mode_type: config::AppModeType, str: String) -> bool158     fn check_install_continue(&mut self, mode_type: config::AppModeType, str: String) -> bool {
159         let mut _mode_desc = String::from("");
160         match mode_type {
161             config::AppModeType::Install => _mode_desc = String::from("App install"),
162             config::AppModeType::UnInstall => _mode_desc = String::from("App uninstall"),
163         }
164         let message = format!(
165             "{}, path:{}, queuesize:{}, msg:{}",
166             _mode_desc.clone(),
167             self.transfer.local_path.clone(),
168             self.transfer.task_queue.len(),
169             str.clone()
170         );
171         self.echo_client(message);
172         if self.transfer.task_queue.is_empty() {
173             self.echo_client(String::from("AppMod finish"));
174             self.task_finish();
175             hdctransfer::close_channel(self.channel_id());
176             return false;
177         }
178         self.install_single();
179         true
180     }
181 
echo_client(&mut self, message: String)182     fn echo_client(&mut self, message: String) {
183         ylong_runtime::block_on(async {
184             let _ = transfer::send_channel_msg(self.channel_id(), EchoLevel::INFO, message).await;
185         });
186     }
187 }
188 
189 impl TaskBase for HostAppTask {
command_dispatch( &mut self, _command: HdcCommand, _payload: &[u8], _payload_size: u16, ) -> bool190     fn command_dispatch(
191         &mut self,
192         _command: HdcCommand,
193         _payload: &[u8],
194         _payload_size: u16,
195     ) -> bool {
196         match _command {
197             HdcCommand::AppInit => {
198                 let s = String::from_utf8(_payload.to_vec());
199                 match s {
200                     Ok(str) => {
201                         if self.init_install(&str) {
202                             self.put_app_check();
203                         }
204                     }
205                     Err(e) => {
206                         println!("error {}", e);
207                     }
208                 }
209             }
210             HdcCommand::AppBegin => {
211                 hdctransfer::transfer_begin(&self.transfer, HdcCommand::AppData);
212             }
213             HdcCommand::AppUninstall => {
214                 self.do_app_uninstall(&_payload.to_vec());
215             }
216             HdcCommand::AppFinish => {
217                 self.do_app_finish(&_payload.to_vec());
218             }
219             _ => {
220                 println!("other command");
221             }
222         }
223         true
224     }
225 
stop_task(&mut self)226     fn stop_task(&mut self) {}
227 
ready_for_release(&mut self) -> bool228     fn ready_for_release(&mut self) -> bool {
229         true
230     }
231 
channel_id(&self) -> u32232     fn channel_id(&self) -> u32 {
233         self.transfer.channel_id
234     }
235 
task_finish(&self)236     fn task_finish(&self) {
237         hdctransfer::transfer_task_finish(self.transfer.channel_id, self.transfer.session_id);
238     }
239 }
240