1 /*
2  * Copyright (C) 2022 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef FRAMEWORKS_AV_SERVICES_CAMERA_LIBCAMERASERVICE_AIDL_DEATHPIPE_H_
18 #define FRAMEWORKS_AV_SERVICES_CAMERA_LIBCAMERASERVICE_AIDL_DEATHPIPE_H_
19 
20 #include <android/binder_auto_utils.h>
21 #include <android/binder_ibinder.h>
22 #include <binder/Parcel.h>
23 #include <list>
24 
25 namespace android::frameworks::cameraservice::utils {
26 
27 /**
28  * This is a helper class to pipe death notifications from  VNDK {@code AIBinder} to
29  * S/NDK {@code IBinder}.
30  *
31  * To use this class, create a DeathPipe member object as a field of NDK interface
32  * implementation, and forward functions {@code BBinder::linkToDeath} and
33  * {@code BBinder::unlinkToDeath} to corresponding DeathPipe functions.
34  */
35 class DeathPipe {
36   public:
37     /**
38      * @param parent the NDK Binder object. Assumed to live longer than the DeathPipe
39      *               object
40      * @param binder the VNDK Binder object which DeathPipe with subscribe to.
41      */
42     explicit DeathPipe(IBinder* parent, const ::ndk::SpAIBinder& binder);
43     ~DeathPipe();
44 
45     status_t linkToDeath(const sp<IBinder::DeathRecipient>& recipient, void* cookie,
46                          uint32_t flags);
47     status_t unlinkToDeath(const wp<IBinder::DeathRecipient>& recipient,
48                            void* cookie, uint32_t flags, wp<IBinder::DeathRecipient>* outRecipient);
49 
50     // Static functions that will be called by VNDK binder upon death or unlinking
51     static void onDeathCallback(void* cookie);
52     static void onUnlinkedCallback(void* cookie);
53 
54   private:
55     /**
56      * {@code Obituary} is a tiny container that contains some metadata to pass VNDK binder's
57      * death notification to the NDK binder. A pointer to the Obituary is used as the
58      * {@code cookie} in VNDK binder's death notification.
59      *
60      * Theoretically, the VNDK binder might send out death notification after the DeathPipe
61      * object is destroyed, so care must be taken to ensure that Obituaries aren't accidentally
62      * destroyed before VNDK binder stops using its cookies.
63      *
64      */
65     struct Obituary: public std::enable_shared_from_this<Obituary> {
66         wp<IBinder::DeathRecipient> recipient; // NDK death recipient
67         void *cookie; // cookie sent by the NDK recipient
68         uint32_t flags; // flags sent by the NDK recipient
69         wp<IBinder> who; // NDK binder whose death 'recipient' subscribed to
70 
71         // Self ptr to ensure we don't destroy this obituary while it can still be notified by the
72         // VNDK Binder. When populated with Obituary::immortalize, this Obituary won't be
73         // garbage collected until Obituary::clear is called.
74         std::shared_ptr<Obituary> mSelfPtr;
75 
ObituaryObituary76         Obituary(const wp<IBinder::DeathRecipient>& recipient, void* cookie,
77                  uint32_t flags, IBinder* who) :
78               recipient(recipient), cookie(cookie), flags(flags),
79               who(who), mSelfPtr(nullptr) {}
80 
81         // Function to be called when the VNDK Binder dies. Pipes the notification to the relevant
82         // NDK recipient if it still exists
onDeathObituary83         void onDeath() const {
84                 sp<IBinder::DeathRecipient> r = recipient.promote();
85                 if (r == nullptr) { return; }
86                 r->binderDied(who);
87         };
88 
89         // Should be called before calling AIBinder_linkToDeath. Once this function returns this
90         // Obituary won't be garbage collected until Obituary::clear is called.
immortalizeObituary91         void immortalize() {
92             mSelfPtr = shared_from_this();
93         }
94 
95         // Should be called when this Obituary can be garbage collected.
96         // Typically, after the Obituary is no longer linked to a VNDK DeathRecipient
clearObituary97         void clear() {
98             mSelfPtr = nullptr;
99         }
100 
101         bool operator==(const Obituary& rhs) const {
102             return recipient == rhs.recipient &&
103                    cookie == rhs.cookie &&
104                    flags == rhs.flags &&
105                    who == rhs.who;
106         }
107     };
108 
109     // Parent to which the cameraservice wants to subscribe to for death notification
110     IBinder* mParent;
111 
112     // VNDK Binder object to which the death notification will be bound to. If it dies,
113     // cameraservice will be notified as if mParent died.
114     ::ndk::SpAIBinder mAIBinder;
115 
116     // Owning VNDK's deathRecipient ensures that all linked death notifications are cleaned up
117     // when this class destructs.
118     ::ndk::ScopedAIBinder_DeathRecipient mDeathRecipient;
119 
120     // Lock to protect access to fields below.
121     std::mutex mLock;
122     // List of all obituaries created by DeathPipe, used to unlink death subscription
123     std::list<std::shared_ptr<Obituary>> mObituaries;
124 
125 };
126 
127 } // namespace android::frameworks::cameraservice::utils
128 
129 #endif  // FRAMEWORKS_AV_SERVICES_CAMERA_LIBCAMERASERVICE_AIDL_DEATHPIPE_H_
130