1 /*
2  * Copyright (c) 2021-2024 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 "app_state_callback_host.h"
17 
18 #include "appexecfwk_errors.h"
19 #include "configuration.h"
20 #include "hitrace_meter.h"
21 #include "hilog_tag_wrapper.h"
22 #include "ipc_types.h"
23 #include "iremote_object.h"
24 
25 #include "app_state_callback_proxy.h"
26 
27 namespace OHOS {
28 namespace AppExecFwk {
29 constexpr int32_t CYCLE_LIMIT = 1000;
AppStateCallbackHost()30 AppStateCallbackHost::AppStateCallbackHost() {}
31 
~AppStateCallbackHost()32 AppStateCallbackHost::~AppStateCallbackHost() {}
33 
OnRemoteRequest(uint32_t code,MessageParcel & data,MessageParcel & reply,MessageOption & option)34 int AppStateCallbackHost::OnRemoteRequest(
35     uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option)
36 {
37     TAG_LOGD(AAFwkTag::APPMGR, "AppStateCallbackHost::OnReceived, code = %{public}u, flags= %{public}d.", code,
38         option.GetFlags());
39     std::u16string descriptor = AppStateCallbackHost::GetDescriptor();
40     std::u16string remoteDescriptor = data.ReadInterfaceToken();
41     if (descriptor != remoteDescriptor) {
42         TAG_LOGE(AAFwkTag::APPMGR, "local descriptor is not equal to remote");
43         return ERR_INVALID_STATE;
44     }
45 
46     switch (code) {
47         case static_cast<uint32_t>(IAppStateCallback::Message::TRANSACT_ON_APP_STATE_CHANGED):
48             return HandleOnAppStateChanged(data, reply);
49         case static_cast<uint32_t>(IAppStateCallback::Message::TRANSACT_ON_ABILITY_REQUEST_DONE):
50             return HandleOnAbilityRequestDone(data, reply);
51         case static_cast<uint32_t>(IAppStateCallback::Message::TRANSACT_ON_NOTIFY_CONFIG_CHANGE):
52             return HandleNotifyConfigurationChange(data, reply);
53         case static_cast<uint32_t>(IAppStateCallback::Message::TRANSACT_ON_NOTIFY_START_RESIDENT_PROCESS):
54             return HandleNotifyStartResidentProcess(data, reply);
55         case static_cast<uint32_t>(IAppStateCallback::Message::TRANSACT_ON_APP_REMOTE_DIED):
56             return HandleOnAppRemoteDied(data, reply);
57         case static_cast<uint32_t>(IAppStateCallback::Message::TRANSACT_ON_APP_PRE_CACHE):
58             return HandleNotifyAppPreCache(data, reply);
59     }
60 
61     TAG_LOGD(AAFwkTag::APPMGR, "AppStateCallbackHost::OnRemoteRequest end");
62     return IPCObjectStub::OnRemoteRequest(code, data, reply, option);
63 }
64 
OnAbilityRequestDone(const sptr<IRemoteObject> &,const AbilityState)65 void AppStateCallbackHost::OnAbilityRequestDone(const sptr<IRemoteObject> &, const AbilityState)
66 {
67     TAG_LOGD(AAFwkTag::APPMGR, "called");
68 }
69 
OnAppStateChanged(const AppProcessData &)70 void AppStateCallbackHost::OnAppStateChanged(const AppProcessData &)
71 {
72     TAG_LOGD(AAFwkTag::APPMGR, "called");
73 }
74 
NotifyAppPreCache(int32_t pid,int32_t userId)75 void AppStateCallbackHost::NotifyAppPreCache(int32_t pid, int32_t userId)
76 {
77     TAG_LOGD(AAFwkTag::APPMGR, "called");
78 }
79 
NotifyConfigurationChange(const AppExecFwk::Configuration & config,int32_t userId)80 void AppStateCallbackHost::NotifyConfigurationChange(const AppExecFwk::Configuration &config, int32_t userId)
81 {
82 }
83 
NotifyStartResidentProcess(std::vector<AppExecFwk::BundleInfo> & bundleInfos)84 void AppStateCallbackHost::NotifyStartResidentProcess(std::vector<AppExecFwk::BundleInfo> &bundleInfos)
85 {
86     TAG_LOGD(AAFwkTag::APPMGR, "called");
87 }
88 
OnAppRemoteDied(const std::vector<sptr<IRemoteObject>> & abilityTokens)89 void AppStateCallbackHost::OnAppRemoteDied(const std::vector<sptr<IRemoteObject>> &abilityTokens)
90 {
91     TAG_LOGD(AAFwkTag::APPMGR, "called");
92 }
93 
HandleOnAppStateChanged(MessageParcel & data,MessageParcel & reply)94 int32_t AppStateCallbackHost::HandleOnAppStateChanged(MessageParcel &data, MessageParcel &reply)
95 {
96     HITRACE_METER(HITRACE_TAG_APP);
97     std::unique_ptr<AppProcessData> processData(data.ReadParcelable<AppProcessData>());
98     if (!processData) {
99         TAG_LOGE(AAFwkTag::APPMGR, "ReadParcelable<AppProcessData> failed");
100         return ERR_APPEXECFWK_PARCEL_ERROR;
101     }
102 
103     OnAppStateChanged(*processData);
104     return NO_ERROR;
105 }
106 
HandleOnAbilityRequestDone(MessageParcel & data,MessageParcel & reply)107 int32_t AppStateCallbackHost::HandleOnAbilityRequestDone(MessageParcel &data, MessageParcel &reply)
108 {
109     HITRACE_METER(HITRACE_TAG_APP);
110     sptr<IRemoteObject> obj = nullptr;
111     if (data.ReadBool()) {
112         obj = data.ReadRemoteObject();
113     }
114     int32_t state = data.ReadInt32();
115     OnAbilityRequestDone(obj, static_cast<AbilityState>(state));
116     return NO_ERROR;
117 }
118 
HandleNotifyConfigurationChange(MessageParcel & data,MessageParcel & reply)119 int32_t AppStateCallbackHost::HandleNotifyConfigurationChange(MessageParcel &data, MessageParcel &reply)
120 {
121     std::unique_ptr<AppExecFwk::Configuration> config(data.ReadParcelable<AppExecFwk::Configuration>());
122     if (config == nullptr) {
123         TAG_LOGE(AAFwkTag::APPMGR, "To read config failed.");
124         return ERR_DEAD_OBJECT;
125     }
126     auto userId = data.ReadInt32();
127     NotifyConfigurationChange(*config, userId);
128     return NO_ERROR;
129 }
130 
HandleNotifyStartResidentProcess(MessageParcel & data,MessageParcel & reply)131 int32_t AppStateCallbackHost::HandleNotifyStartResidentProcess(MessageParcel &data, MessageParcel &reply)
132 {
133     std::vector<AppExecFwk::BundleInfo> bundleInfos;
134     int32_t infoSize = data.ReadInt32();
135     if (infoSize > CYCLE_LIMIT) {
136         TAG_LOGE(AAFwkTag::APPMGR, "infoSize is too large");
137         return ERR_INVALID_VALUE;
138     }
139     for (int32_t i = 0; i < infoSize; i++) {
140         std::unique_ptr<AppExecFwk::BundleInfo> bundleInfo(data.ReadParcelable<AppExecFwk::BundleInfo>());
141         if (!bundleInfo) {
142             TAG_LOGE(AAFwkTag::APPMGR, "Read Parcelable infos failed.");
143             return ERR_INVALID_VALUE;
144         }
145         bundleInfos.emplace_back(*bundleInfo);
146     }
147     NotifyStartResidentProcess(bundleInfos);
148     return NO_ERROR;
149 }
150 
HandleOnAppRemoteDied(MessageParcel & data,MessageParcel & reply)151 int32_t AppStateCallbackHost::HandleOnAppRemoteDied(MessageParcel &data, MessageParcel &reply)
152 {
153     std::vector<sptr<IRemoteObject>> abilityTokens;
154     int32_t infoSize = data.ReadInt32();
155     if (infoSize > CYCLE_LIMIT) {
156         TAG_LOGE(AAFwkTag::APPMGR, "infoSize is too large");
157         return ERR_INVALID_VALUE;
158     }
159     for (int32_t i = 0; i < infoSize; i++) {
160         sptr<IRemoteObject> obj = data.ReadRemoteObject();
161         if (!obj) {
162             TAG_LOGE(AAFwkTag::APPMGR, "Read token failed.");
163             return ERR_INVALID_VALUE;
164         }
165         abilityTokens.emplace_back(obj);
166     }
167     OnAppRemoteDied(abilityTokens);
168     return NO_ERROR;
169 }
170 
HandleNotifyAppPreCache(MessageParcel & data,MessageParcel & reply)171 int32_t AppStateCallbackHost::HandleNotifyAppPreCache(MessageParcel &data, MessageParcel &reply)
172 {
173     int32_t pid = data.ReadInt32();
174     if (pid <= 0) {
175         TAG_LOGE(AAFwkTag::APPMGR, "pid is illegal");
176         return ERR_INVALID_VALUE;
177     }
178     int32_t userId = data.ReadInt32();
179     if (userId < 0) {
180         TAG_LOGE(AAFwkTag::APPMGR, "userId is illegal");
181         return ERR_INVALID_VALUE;
182     }
183     NotifyAppPreCache(pid, userId);
184     return NO_ERROR;
185 }
186 }  // namespace AppExecFwk
187 }  // namespace OHOS
188