1 /*
2  * Copyright (c) 2021-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 
16 #include "dcamera_sink_handler_ipc.h"
17 
18 #include <cstdint>
19 #include <new>
20 
21 #include "dcamera_sink_handler.h"
22 #include "distributed_camera_constants.h"
23 #include "distributed_hardware_log.h"
24 #include "if_system_ability_manager.h"
25 #include "iservice_registry.h"
26 #include "iremote_broker.h"
27 
28 namespace OHOS {
29 namespace DistributedHardware {
DCameraSinkHandlerIpc()30 DCameraSinkHandlerIpc::DCameraSinkHandlerIpc() : isInit_(false)
31 {
32     DHLOGI("Create");
33 }
34 
~DCameraSinkHandlerIpc()35 DCameraSinkHandlerIpc::~DCameraSinkHandlerIpc()
36 {
37     DHLOGI("Delete");
38     UnInit();
39 }
40 
41 IMPLEMENT_SINGLE_INSTANCE(DCameraSinkHandlerIpc);
42 
Init()43 void DCameraSinkHandlerIpc::Init()
44 {
45     std::lock_guard<std::mutex> autoLock(initCamSrvLock_);
46     DHLOGI("Start");
47     if (isInit_) {
48         DHLOGI("DCameraSinkHandlerIpc has already init");
49         return;
50     }
51     sinkLocalRecipient_ = sptr<SinkLocalRecipient>(new SinkLocalRecipient());
52     isInit_ = true;
53     DHLOGI("End");
54 }
55 
UnInit()56 void DCameraSinkHandlerIpc::UnInit()
57 {
58     std::lock_guard<std::mutex> autoLock(initCamSrvLock_);
59     DHLOGI("Start");
60     if (!isInit_) {
61         DHLOGI("DCameraSinkHandlerIpc has already UnInit");
62         return;
63     }
64     DeleteSinkLocalCamSrv();
65     DHLOGI("DCameraSinkHandlerIpc Start free recipient");
66     sinkLocalRecipient_ = nullptr;
67     isInit_ = false;
68     DHLOGI("End");
69 }
70 
GetSinkLocalCamSrv()71 sptr<IDistributedCameraSink> DCameraSinkHandlerIpc::GetSinkLocalCamSrv()
72 {
73     {
74         std::lock_guard<std::mutex> autoLock(sinkLocalCamSrvLock_);
75         if (localSink_ != nullptr) {
76             DHLOGI("DCameraSinkHandlerIpc GetSinkLocalCamSrv from cache");
77             return localSink_;
78         }
79     }
80     DHLOGI("Start");
81     sptr<ISystemAbilityManager> sm = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
82     if (sm == nullptr) {
83         DHLOGE("GetSystemAbilityManager failed");
84         return nullptr;
85     }
86 
87     sptr<IRemoteObject> object = sm->GetSystemAbility(DISTRIBUTED_HARDWARE_CAMERA_SINK_SA_ID);
88     if (object == nullptr) {
89         DHLOGE("GetSystemAbility failed");
90         return nullptr;
91     }
92     int32_t ret = object->AddDeathRecipient(sinkLocalRecipient_);
93     sptr<IDistributedCameraSink> localSink = iface_cast<IDistributedCameraSink>(object);
94     if (localSink == nullptr) {
95         DHLOGI("GetSinkLocalCamSrv failed, localSink is null ret: %{public}d", ret);
96         return nullptr;
97     }
98     {
99         std::lock_guard<std::mutex> autoLock(sinkLocalCamSrvLock_);
100         if (localSink_ != nullptr) {
101             localSink_->AsObject()->RemoveDeathRecipient(sinkLocalRecipient_);
102         }
103         localSink_ = localSink;
104     }
105     DHLOGI("GetSinkLocalCamSrv success, AddDeathRecipient ret: %{public}d", ret);
106     return localSink;
107 }
108 
DeleteSinkLocalCamSrv()109 void DCameraSinkHandlerIpc::DeleteSinkLocalCamSrv()
110 {
111     DHLOGI("start");
112     std::lock_guard<std::mutex> autoLock(sinkLocalCamSrvLock_);
113     if (localSink_ != nullptr) {
114         localSink_->AsObject()->RemoveDeathRecipient(sinkLocalRecipient_);
115     }
116     localSink_ = nullptr;
117     DHLOGI("end");
118 }
119 
OnRemoteDied(const wptr<IRemoteObject> & remote)120 void DCameraSinkHandlerIpc::SinkLocalRecipient::OnRemoteDied(const wptr<IRemoteObject>& remote)
121 {
122     DHLOGI("SinkLocalRecipient OnRemoteDied received died notify!");
123     DCameraSinkHandlerIpc::GetInstance().OnSinkLocalCamSrvDied(remote);
124 }
125 
OnSinkLocalCamSrvDied(const wptr<IRemoteObject> & remote)126 void DCameraSinkHandlerIpc::OnSinkLocalCamSrvDied(const wptr<IRemoteObject>& remote)
127 {
128     DHLOGI("OnSinkLocalCamSrvDied delete diedRemoted");
129     std::lock_guard<std::mutex> autoLock(sinkLocalCamSrvLock_);
130     if (localSink_ == nullptr) {
131         DHLOGE("localSink is null.");
132         return;
133     }
134     sptr<IRemoteObject> diedRemoted = remote.promote();
135     if (diedRemoted == nullptr) {
136         DHLOGE("OnSinkLocalCamSrvDied promote failed!");
137         return;
138     }
139     if (localSink_->AsObject() != diedRemoted) {
140         DHLOGI("OnSinkLocalCamSrvDied not found remote object.");
141         return;
142     }
143 
144     DHLOGI("OnSinkLocalCamSrvDied Clear");
145     localSink_->AsObject()->RemoveDeathRecipient(sinkLocalRecipient_);
146     localSink_ = nullptr;
147     DCameraSinkHandler::GetInstance().SetSAState();
148 }
149 } // namespace DistributedHardware
150 } // namespace OHOS
151