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