IProCameraCallbacks.cpp revision a91537e268f2b35f9f0dfdc0c4f84655c93285ae
1/*
2**
3** Copyright 2013, The Android Open Source Project
4**
5** Licensed under the Apache License, Version 2.0 (the "License");
6** you may not use this file except in compliance with the License.
7** You may obtain a copy of the License at
8**
9**     http://www.apache.org/licenses/LICENSE-2.0
10**
11** Unless required by applicable law or agreed to in writing, software
12** distributed under the License is distributed on an "AS IS" BASIS,
13** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14** See the License for the specific language governing permissions and
15** limitations under the License.
16*/
17
18//#define LOG_NDEBUG 0
19#define LOG_TAG "IProCameraCallbacks"
20#include <utils/Log.h>
21#include <stdint.h>
22#include <sys/types.h>
23
24#include <binder/Parcel.h>
25#include <gui/IGraphicBufferProducer.h>
26#include <gui/Surface.h>
27#include <utils/Mutex.h>
28
29#include <camera/IProCameraCallbacks.h>
30
31#include <system/camera_metadata.h>
32
33namespace android {
34
35enum {
36    NOTIFY_CALLBACK = IBinder::FIRST_CALL_TRANSACTION,
37    DATA_CALLBACK,
38    DATA_CALLBACK_TIMESTAMP,
39    LOCK_STATUS_CHANGED,
40    RESULT_RECEIVED,
41};
42
43void readMetadata(const Parcel& data, camera_metadata_t** out);
44void writeMetadata(Parcel& data, camera_metadata_t* metadata);
45
46class BpProCameraCallbacks: public BpInterface<IProCameraCallbacks>
47{
48public:
49    BpProCameraCallbacks(const sp<IBinder>& impl)
50        : BpInterface<IProCameraCallbacks>(impl)
51    {
52    }
53
54    // generic callback from camera service to app
55    void notifyCallback(int32_t msgType, int32_t ext1, int32_t ext2)
56    {
57        ALOGV("notifyCallback");
58        Parcel data, reply;
59        data.writeInterfaceToken(IProCameraCallbacks::getInterfaceDescriptor());
60        data.writeInt32(msgType);
61        data.writeInt32(ext1);
62        data.writeInt32(ext2);
63        remote()->transact(NOTIFY_CALLBACK, data, &reply, IBinder::FLAG_ONEWAY);
64    }
65
66    // generic data callback from camera service to app with image data
67    void dataCallback(int32_t msgType, const sp<IMemory>& imageData,
68                      camera_frame_metadata_t *metadata)
69    {
70        ALOGV("dataCallback");
71        Parcel data, reply;
72        data.writeInterfaceToken(IProCameraCallbacks::getInterfaceDescriptor());
73        data.writeInt32(msgType);
74        data.writeStrongBinder(imageData->asBinder());
75        if (metadata) {
76            data.writeInt32(metadata->number_of_faces);
77            data.write(metadata->faces,
78                            sizeof(camera_face_t) * metadata->number_of_faces);
79        }
80        remote()->transact(DATA_CALLBACK, data, &reply, IBinder::FLAG_ONEWAY);
81    }
82
83    // generic data callback from camera service to app with image data
84    void dataCallbackTimestamp(nsecs_t timestamp, int32_t msgType,
85                                                  const sp<IMemory>& imageData)
86    {
87        ALOGV("dataCallback");
88        Parcel data, reply;
89        data.writeInterfaceToken(IProCameraCallbacks::getInterfaceDescriptor());
90        data.writeInt64(timestamp);
91        data.writeInt32(msgType);
92        data.writeStrongBinder(imageData->asBinder());
93        remote()->transact(DATA_CALLBACK_TIMESTAMP, data, &reply,
94                                                          IBinder::FLAG_ONEWAY);
95    }
96
97    void onLockStatusChanged(LockStatus newLockStatus) {
98        ALOGV("onLockStatusChanged");
99        Parcel data, reply;
100        data.writeInterfaceToken(IProCameraCallbacks::getInterfaceDescriptor());
101        data.writeInt32(newLockStatus);
102        remote()->transact(LOCK_STATUS_CHANGED, data, &reply,
103                           IBinder::FLAG_ONEWAY);
104    }
105
106    void onResultReceived(int32_t frameId, camera_metadata* result) {
107        ALOGV("onResultReceived");
108        Parcel data, reply;
109        data.writeInterfaceToken(IProCameraCallbacks::getInterfaceDescriptor());
110        data.writeInt32(frameId);
111        writeMetadata(data, result);
112        remote()->transact(RESULT_RECEIVED, data, &reply, IBinder::FLAG_ONEWAY);
113    }
114};
115
116IMPLEMENT_META_INTERFACE(ProCameraCallbacks,
117                                        "android.hardware.IProCameraCallbacks");
118
119// ----------------------------------------------------------------------
120
121status_t BnProCameraCallbacks::onTransact(
122    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
123{
124    ALOGV("onTransact - code = %d", code);
125    switch(code) {
126        case NOTIFY_CALLBACK: {
127            ALOGV("NOTIFY_CALLBACK");
128            CHECK_INTERFACE(IProCameraCallbacks, data, reply);
129            int32_t msgType = data.readInt32();
130            int32_t ext1 = data.readInt32();
131            int32_t ext2 = data.readInt32();
132            notifyCallback(msgType, ext1, ext2);
133            return NO_ERROR;
134        } break;
135        case DATA_CALLBACK: {
136            ALOGV("DATA_CALLBACK");
137            CHECK_INTERFACE(IProCameraCallbacks, data, reply);
138            int32_t msgType = data.readInt32();
139            sp<IMemory> imageData = interface_cast<IMemory>(
140                                                       data.readStrongBinder());
141            camera_frame_metadata_t *metadata = NULL;
142            if (data.dataAvail() > 0) {
143                metadata = new camera_frame_metadata_t;
144                metadata->number_of_faces = data.readInt32();
145                metadata->faces = (camera_face_t *) data.readInplace(
146                        sizeof(camera_face_t) * metadata->number_of_faces);
147            }
148            dataCallback(msgType, imageData, metadata);
149            if (metadata) delete metadata;
150            return NO_ERROR;
151        } break;
152        case DATA_CALLBACK_TIMESTAMP: {
153            ALOGV("DATA_CALLBACK_TIMESTAMP");
154            CHECK_INTERFACE(IProCameraCallbacks, data, reply);
155            nsecs_t timestamp = data.readInt64();
156            int32_t msgType = data.readInt32();
157            sp<IMemory> imageData = interface_cast<IMemory>(
158                                                       data.readStrongBinder());
159            dataCallbackTimestamp(timestamp, msgType, imageData);
160            return NO_ERROR;
161        } break;
162        case LOCK_STATUS_CHANGED: {
163            ALOGV("LOCK_STATUS_CHANGED");
164            CHECK_INTERFACE(IProCameraCallbacks, data, reply);
165            LockStatus newLockStatus
166                                 = static_cast<LockStatus>(data.readInt32());
167            onLockStatusChanged(newLockStatus);
168            return NO_ERROR;
169        } break;
170        case RESULT_RECEIVED: {
171            ALOGV("RESULT_RECEIVED");
172            CHECK_INTERFACE(IProCameraCallbacks, data, reply);
173            int32_t frameId = data.readInt32();
174            camera_metadata_t *result = NULL;
175            readMetadata(data, &result);
176            onResultReceived(frameId, result);
177            return NO_ERROR;
178            break;
179        }
180        default:
181            return BBinder::onTransact(code, data, reply, flags);
182    }
183}
184
185// ----------------------------------------------------------------------------
186
187}; // namespace android
188
189