1 /*
2  * Copyright 2015 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 PERSISTENT_SURFACE_H_
18 
19 #define PERSISTENT_SURFACE_H_
20 
21 #include <android/binder_auto_utils.h>
22 #include <android/binder_libbinder.h>
23 #include <binder/Parcel.h>
24 #include <hidl/HidlSupport.h>
25 #include <hidl/HybridInterface.h>
26 #include <gui/IGraphicBufferProducer.h>
27 #include <media/stagefright/foundation/ABase.h>
28 
29 namespace android {
30 
31 struct PersistentSurface : public RefBase {
PersistentSurfacePersistentSurface32     PersistentSurface() {}
33 
34     // create a persistent surface in HIDL
PersistentSurfacePersistentSurface35     PersistentSurface(
36             const sp<IGraphicBufferProducer>& bufferProducer,
37             const sp<hidl::base::V1_0::IBase>& hidlTarget) :
38         mBufferProducer(bufferProducer),
39         mHidlTarget(hidlTarget),
40         mAidlTarget(nullptr),
41         mAidl(false) { }
42 
43     // create a persistent surface in AIDL
PersistentSurfacePersistentSurface44     PersistentSurface(
45             const sp<IGraphicBufferProducer>& bufferProducer,
46             const ::ndk::SpAIBinder& aidlTarget) :
47         mBufferProducer(bufferProducer),
48         mHidlTarget(nullptr),
49         mAidlTarget(aidlTarget),
50         mAidl(true) { }
51 
getBufferProducerPersistentSurface52     sp<IGraphicBufferProducer> getBufferProducer() const {
53         return mBufferProducer;
54     }
55 
isTargetAidlPersistentSurface56     bool isTargetAidl() const {
57         return mAidl;
58     }
59 
getHidlTargetPersistentSurface60     sp<hidl::base::V1_0::IBase> getHidlTarget() const {
61         return mAidl ? nullptr : mHidlTarget;
62     }
63 
getAidlTargetPersistentSurface64     ::ndk::SpAIBinder getAidlTarget() const {
65         return mAidl ? mAidlTarget : nullptr;
66     }
67 
writeToParcelPersistentSurface68     status_t writeToParcel(Parcel *parcel) const {
69         parcel->writeStrongBinder(IInterface::asBinder(mBufferProducer));
70         // write hidl target if available
71         if (mHidlTarget != nullptr) {
72             HalToken token;
73             bool result = createHalToken(mHidlTarget, &token);
74             parcel->writeBool(result);
75             if (result) {
76                 parcel->writeByteArray(token.size(), token.data());
77             }
78         } else {
79             parcel->writeBool(false);
80         }
81         // write aidl target if available
82         if (mAidl) {
83             AIBinder *binder = mAidlTarget.get();
84             if (binder != nullptr) {
85                 ::android::sp<::android::IBinder> intf =
86                         AIBinder_toPlatformBinder(binder);
87                 if (intf) {
88                     parcel->writeBool(true);
89                     parcel->writeStrongBinder(intf);
90                 } else {
91                     parcel->writeBool(false);
92                 }
93             } else {
94                 parcel->writeBool(false);
95             }
96         }
97         return NO_ERROR;
98     }
99 
readFromParcelPersistentSurface100     status_t readFromParcel(const Parcel *parcel) {
101         mBufferProducer = interface_cast<IGraphicBufferProducer>(
102                 parcel->readStrongBinder());
103         // read hidl target
104         bool haveHidlTarget = parcel->readBool();
105         mAidl = false;
106         if (haveHidlTarget) {
107             std::vector<uint8_t> tokenVector;
108             parcel->readByteVector(&tokenVector);
109             HalToken token = HalToken(tokenVector);
110             mHidlTarget = retrieveHalInterface(token);
111             deleteHalToken(token);
112             return NO_ERROR;
113         } else {
114             mHidlTarget.clear();
115         }
116 
117         // read aidl target
118         bool haveAidlTarget = false;
119         if (parcel->readBool(&haveAidlTarget) != NO_ERROR) {
120             return NO_ERROR;
121         }
122         mAidl = true;
123         if (haveAidlTarget) {
124             ::android::sp<::android::IBinder> intf = parcel->readStrongBinder();
125             AIBinder *ndkBinder = AIBinder_fromPlatformBinder(intf);
126             if (ndkBinder) {
127                 mAidlTarget.set(ndkBinder);
128             } else {
129                 mAidlTarget.set(nullptr);
130             }
131         } else {
132             mAidlTarget.set(nullptr);
133         }
134         return NO_ERROR;
135     }
136 
137 private:
138     sp<IGraphicBufferProducer> mBufferProducer;
139     sp<hidl::base::V1_0::IBase> mHidlTarget;
140     ::ndk::SpAIBinder mAidlTarget;
141     bool mAidl;
142 
143     DISALLOW_EVIL_CONSTRUCTORS(PersistentSurface);
144 };
145 
146 }  // namespace android
147 
148 #endif  // PERSISTENT_SURFACE_H_
149