1 /*
2  * Copyright (c) 2022 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 #include "ability_manager_access_client.h"
16 #include "access_token_error.h"
17 #include "accesstoken_log.h"
18 #include "iservice_registry.h"
19 #include "system_ability_definition.h"
20 
21 namespace OHOS {
22 namespace Security {
23 namespace AccessToken {
24 namespace {
25 static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {
26     LOG_CORE, SECURITY_DOMAIN_ACCESSTOKEN, "AbilityManagerAccessClient"
27 };
28 std::recursive_mutex g_instanceMutex;
29 } // namespace
30 
GetInstance()31 AbilityManagerAccessClient& AbilityManagerAccessClient::GetInstance()
32 {
33     static AbilityManagerAccessClient* instance = nullptr;
34     if (instance == nullptr) {
35         std::lock_guard<std::recursive_mutex> lock(g_instanceMutex);
36         if (instance == nullptr) {
37             instance = new AbilityManagerAccessClient();
38         }
39     }
40     return *instance;
41 }
42 
AbilityManagerAccessClient()43 AbilityManagerAccessClient::AbilityManagerAccessClient()
44 {}
45 
~AbilityManagerAccessClient()46 AbilityManagerAccessClient::~AbilityManagerAccessClient()
47 {
48     std::lock_guard<std::mutex> lock(proxyMutex_);
49     ReleaseProxy();
50 }
51 
StartAbility(const AAFwk::Want & want,const sptr<IRemoteObject> & callerToken,int requestCode,int32_t userId)52 int32_t AbilityManagerAccessClient::StartAbility(
53     const AAFwk::Want &want, const sptr<IRemoteObject> &callerToken, int requestCode, int32_t userId)
54 {
55     auto proxy = GetProxy();
56     if (proxy == nullptr) {
57         ACCESSTOKEN_LOG_ERROR(LABEL, "Proxy is null");
58         return AccessTokenError::ERR_SERVICE_ABNORMAL;
59     }
60     ACCESSTOKEN_LOG_INFO(LABEL, "Start ability %{public}s, userId:%{public}d",
61         want.GetElement().GetAbilityName().c_str(), userId);
62     return proxy->StartAbility(want, callerToken, userId, requestCode);
63 }
64 
InitProxy()65 void AbilityManagerAccessClient::InitProxy()
66 {
67     auto sam = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
68     if (sam == nullptr) {
69         ACCESSTOKEN_LOG_ERROR(LABEL, "GetSystemAbilityManager is null");
70         return;
71     }
72     auto abilityManagerSa = sam->GetSystemAbility(ABILITY_MGR_SERVICE_ID);
73     if (abilityManagerSa == nullptr) {
74         ACCESSTOKEN_LOG_ERROR(LABEL, "GetSystemAbility %{public}d is null", ABILITY_MGR_SERVICE_ID);
75         return;
76     }
77 
78     serviceDeathObserver_ = sptr<AbilityManagerAccessDeathRecipient>::MakeSptr();
79     if (serviceDeathObserver_ == nullptr) {
80         ACCESSTOKEN_LOG_ERROR(LABEL, "Create AbilityManagerAccessDeathRecipient failed");
81         return;
82     }
83 
84     if (!abilityManagerSa->IsProxyObject()) {
85         ACCESSTOKEN_LOG_ERROR(LABEL, "Not proxy object");
86         return;
87     }
88     if (!abilityManagerSa->AddDeathRecipient(serviceDeathObserver_)) {
89         ACCESSTOKEN_LOG_ERROR(LABEL, "Add death recipient failed");
90         return;
91     }
92 
93     proxy_ = new AbilityManagerAccessProxy(abilityManagerSa);
94     if (proxy_ == nullptr) {
95         ACCESSTOKEN_LOG_ERROR(LABEL, "Iface_cast get null");
96     }
97 }
98 
OnRemoteDiedHandle()99 void AbilityManagerAccessClient::OnRemoteDiedHandle()
100 {
101     std::lock_guard<std::mutex> lock(proxyMutex_);
102     ReleaseProxy();
103 }
104 
GetProxy()105 sptr<IAbilityManager> AbilityManagerAccessClient::GetProxy()
106 {
107     std::lock_guard<std::mutex> lock(proxyMutex_);
108     if (proxy_ == nullptr) {
109         InitProxy();
110     }
111     return proxy_;
112 }
113 
ReleaseProxy()114 void AbilityManagerAccessClient::ReleaseProxy()
115 {
116     if (proxy_ != nullptr && serviceDeathObserver_ != nullptr) {
117         proxy_->AsObject()->RemoveDeathRecipient(serviceDeathObserver_);
118     }
119     proxy_ = nullptr;
120     serviceDeathObserver_ = nullptr;
121 }
122 } // namespace AccessToken
123 } // namespace Security
124 } // namespace OHOS
125 
126