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#include "startup_manager.h" 17 18#include "if_system_ability_manager.h" 19#include "iservice_registry.h" 20#include "system_ability_definition.h" 21 22#include "access_factory.h" 23#include "constant.h" 24#include "firmware_preferences_utils.h" 25#include "schedule_config.h" 26#include "string_utils.h" 27#include "time_utils.h" 28#include "update_log.h" 29 30namespace OHOS { 31namespace UpdateEngine { 32StartupManager::StartupManager() 33{ 34 ENGINE_LOGD("StartupManager constructor"); 35 scheduleManager_ = std::make_shared<ScheduleManager>( 36 DelayedSingleton<AccessManager>::GetInstance(), DelayedSingleton<StartupSchedule>::GetInstance()); 37 lastIdleCheckTime_ = TimeUtils::GetTimestamp(); 38 ENGINE_LOGI("init lastIdleCheckTime is %{public}s", TimeUtils::GetPrintTimeStr(lastIdleCheckTime_).c_str()); 39} 40 41StartupManager::~StartupManager() 42{ 43 ENGINE_LOGD("StartupManager deConstructor"); 44} 45 46void StartupManager::Start() 47{ 48 ENGINE_LOGI("Start"); 49 Init(); 50 IdleLoop(); 51} 52 53void StartupManager::Init() const 54{ 55 ENGINE_LOGI("Init"); 56 ScheduleConfig::InitConfig(); 57 StartupReason startupReason = GetStartupReason(); 58 ENGINE_LOGI("startupReason is %{public}d", CAST_INT(startupReason)); 59 60 if (startupReason == StartupReason::PROCESS_ENV_RESET) { 61 FileUtils::DestroyBaseDirectory(BASE_DIR_INFOS); 62 } 63 FileUtils::InitAndCreateBaseDirs(BASE_DIR_INFOS); 64 65 for (auto &type : Startup::ACCESS_TYPES) { 66 AccessFactory::GetInstance(type)->Init(startupReason); 67 } 68} 69 70void StartupManager::IdleLoop() 71{ 72 ENGINE_LOGI("IdleLoop"); 73 DelayedSingleton<StartupSchedule>::GetInstance()->RegisterLooper([=]() { 74 if (!IdleCheck()) { 75 ENGINE_LOGD("IdleLoop not idle"); 76 return; 77 } 78 79 if (!PreExit()) { 80 ENGINE_LOGI("IdleLoop pre exit fail"); 81 return; 82 } 83 84 SAExit(); 85 }); 86} 87 88bool StartupManager::IdleCheck() 89{ 90 if (scheduleManager_ == nullptr) { 91 ENGINE_LOGE("IdleCheck scheduleManager is null, return idle"); 92 return true; 93 } 94 95 if (abs(TimeUtils::GetTimestamp() - lastIdleCheckTime_) < 96 static_cast<int64_t>(ScheduleConfig::GetIdleCheckInterval())) { 97 ENGINE_LOGD("IdleCheck check time not arrive: lastIdleCheckTime is %{public}s", 98 TimeUtils::GetPrintTimeStr(lastIdleCheckTime_).c_str()); 99 return false; 100 } 101 102 lastIdleCheckTime_ = TimeUtils::GetTimestamp(); 103 ENGINE_LOGI( 104 "IdleCheck update lastIdleCheckTime: %{public}s", TimeUtils::GetPrintTimeStr(lastIdleCheckTime_).c_str()); 105 106 bool isIdle = scheduleManager_->IdleCheck(); 107 ENGINE_LOGI("IdleCheck idleState is %{public}s", StringUtils::GetBoolStr(isIdle).c_str()); 108 return isIdle; 109} 110 111bool StartupManager::PreExit() 112{ 113 if (scheduleManager_ == nullptr) { 114 ENGINE_LOGE("IdleCheck PreExit is null, return true"); 115 return true; 116 } 117 return scheduleManager_->Exit(); 118} 119 120void StartupManager::SAExit() const 121{ 122 ENGINE_LOGI("SAExit"); 123 sptr<ISystemAbilityManager> sm = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); 124 if (sm == nullptr) { 125 ENGINE_LOGE("GetSystemAbilityManager samgr object null!"); 126 return; 127 } 128 int32_t res = sm->UnloadSystemAbility(UPDATE_DISTRIBUTED_SERVICE_ID); 129 ENGINE_LOGI("UnloadSystemAbility res is %{public}d", res); 130} 131 132StartupReason StartupManager::GetStartupReason() const 133{ 134 if (TimeUtils::IsInRebootDuration()) { 135 return StartupReason::DEVICE_REBOOT; 136 } 137 // 由于SaMgr暂不支持记录启动原因,因此临时从SP文件中读取启动原因 138 auto preferenceUtil = DelayedSingleton<FirmwarePreferencesUtil>::GetInstance(); 139 auto reasonFromSp = static_cast<StartupReason>( 140 preferenceUtil->ObtainInt(Constant::PROCESS_RESTART_REASON, CAST_INT(StartupReason::UNKNOWN))); 141 if (reasonFromSp == StartupReason::UNKNOWN) { 142 return StartupReason::SCHEDULE_TASK; 143 } 144 // 读取后清除SP文件中记录的标记 145 preferenceUtil->Remove(Constant::PROCESS_RESTART_REASON); 146 return reasonFromSp; 147} 148} // namespace UpdateEngine 149} // namespace OHOS