• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2013 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 #define LOG_TAG "ProCamera2Client"
18 #define ATRACE_TAG ATRACE_TAG_CAMERA
19 //#define LOG_NDEBUG 0
20 
21 #include <utils/Log.h>
22 #include <utils/Trace.h>
23 
24 #include <cutils/properties.h>
25 #include <gui/Surface.h>
26 #include <gui/Surface.h>
27 #include "camera2/Parameters.h"
28 #include "ProCamera2Client.h"
29 #include "camera2/ProFrameProcessor.h"
30 #include "CameraDeviceBase.h"
31 
32 namespace android {
33 using namespace camera2;
34 
35 // Interface used by CameraService
36 
ProCamera2Client(const sp<CameraService> & cameraService,const sp<IProCameraCallbacks> & remoteCallback,const String16 & clientPackageName,int cameraId,int cameraFacing,int clientPid,uid_t clientUid,int servicePid)37 ProCamera2Client::ProCamera2Client(const sp<CameraService>& cameraService,
38                                    const sp<IProCameraCallbacks>& remoteCallback,
39                                    const String16& clientPackageName,
40                                    int cameraId,
41                                    int cameraFacing,
42                                    int clientPid,
43                                    uid_t clientUid,
44                                    int servicePid) :
45     Camera2ClientBase(cameraService, remoteCallback, clientPackageName,
46                 cameraId, cameraFacing, clientPid, clientUid, servicePid)
47 {
48     ATRACE_CALL();
49     ALOGI("ProCamera %d: Opened", cameraId);
50 
51     mExclusiveLock = false;
52 }
53 
initialize(camera_module_t * module)54 status_t ProCamera2Client::initialize(camera_module_t *module)
55 {
56     ATRACE_CALL();
57     status_t res;
58 
59     res = Camera2ClientBase::initialize(module);
60     if (res != OK) {
61         return res;
62     }
63 
64     String8 threadName;
65     mFrameProcessor = new ProFrameProcessor(mDevice);
66     threadName = String8::format("PC2-%d-FrameProc", mCameraId);
67     mFrameProcessor->run(threadName.string());
68 
69     mFrameProcessor->registerListener(FRAME_PROCESSOR_LISTENER_MIN_ID,
70                                       FRAME_PROCESSOR_LISTENER_MAX_ID,
71                                       /*listener*/this);
72 
73     return OK;
74 }
75 
~ProCamera2Client()76 ProCamera2Client::~ProCamera2Client() {
77 }
78 
exclusiveTryLock()79 status_t ProCamera2Client::exclusiveTryLock() {
80     ATRACE_CALL();
81     ALOGV("%s", __FUNCTION__);
82 
83     Mutex::Autolock icl(mBinderSerializationLock);
84     SharedCameraCallbacks::Lock l(mSharedCameraCallbacks);
85 
86     if (!mDevice.get()) return PERMISSION_DENIED;
87 
88     if (!mExclusiveLock) {
89         mExclusiveLock = true;
90 
91         if (mRemoteCallback != NULL) {
92             mRemoteCallback->onLockStatusChanged(
93                               IProCameraCallbacks::LOCK_ACQUIRED);
94         }
95 
96         ALOGV("%s: exclusive lock acquired", __FUNCTION__);
97 
98         return OK;
99     }
100 
101     // TODO: have a PERMISSION_DENIED case for when someone else owns the lock
102 
103     // don't allow recursive locking
104     ALOGW("%s: exclusive lock already exists - recursive locking is not"
105           "allowed", __FUNCTION__);
106 
107     return ALREADY_EXISTS;
108 }
109 
exclusiveLock()110 status_t ProCamera2Client::exclusiveLock() {
111     ATRACE_CALL();
112     ALOGV("%s", __FUNCTION__);
113 
114     Mutex::Autolock icl(mBinderSerializationLock);
115     SharedCameraCallbacks::Lock l(mSharedCameraCallbacks);
116 
117     if (!mDevice.get()) return PERMISSION_DENIED;
118 
119     /**
120      * TODO: this should asynchronously 'wait' until the lock becomes available
121      * if another client already has an exclusive lock.
122      *
123      * once we have proper sharing support this will need to do
124      * more than just return immediately
125      */
126     if (!mExclusiveLock) {
127         mExclusiveLock = true;
128 
129         if (mRemoteCallback != NULL) {
130             mRemoteCallback->onLockStatusChanged(IProCameraCallbacks::LOCK_ACQUIRED);
131         }
132 
133         ALOGV("%s: exclusive lock acquired", __FUNCTION__);
134 
135         return OK;
136     }
137 
138     // don't allow recursive locking
139     ALOGW("%s: exclusive lock already exists - recursive locking is not allowed"
140                                                                 , __FUNCTION__);
141     return ALREADY_EXISTS;
142 }
143 
exclusiveUnlock()144 status_t ProCamera2Client::exclusiveUnlock() {
145     ATRACE_CALL();
146     ALOGV("%s", __FUNCTION__);
147 
148     Mutex::Autolock icl(mBinderSerializationLock);
149     SharedCameraCallbacks::Lock l(mSharedCameraCallbacks);
150 
151     // don't allow unlocking if we have no lock
152     if (!mExclusiveLock) {
153         ALOGW("%s: cannot unlock, no lock was held in the first place",
154               __FUNCTION__);
155         return BAD_VALUE;
156     }
157 
158     mExclusiveLock = false;
159     if (mRemoteCallback != NULL ) {
160         mRemoteCallback->onLockStatusChanged(
161                                        IProCameraCallbacks::LOCK_RELEASED);
162     }
163     ALOGV("%s: exclusive lock released", __FUNCTION__);
164 
165     return OK;
166 }
167 
hasExclusiveLock()168 bool ProCamera2Client::hasExclusiveLock() {
169     Mutex::Autolock icl(mBinderSerializationLock);
170     return mExclusiveLock;
171 }
172 
onExclusiveLockStolen()173 void ProCamera2Client::onExclusiveLockStolen() {
174     ALOGV("%s: ProClient lost exclusivity (id %d)",
175           __FUNCTION__, mCameraId);
176 
177     Mutex::Autolock icl(mBinderSerializationLock);
178     SharedCameraCallbacks::Lock l(mSharedCameraCallbacks);
179 
180     if (mExclusiveLock && mRemoteCallback.get() != NULL) {
181         mRemoteCallback->onLockStatusChanged(
182                                        IProCameraCallbacks::LOCK_STOLEN);
183     }
184 
185     mExclusiveLock = false;
186 
187     //TODO: we should not need to detach the device, merely reset it.
188     detachDevice();
189 }
190 
submitRequest(camera_metadata_t * request,bool streaming)191 status_t ProCamera2Client::submitRequest(camera_metadata_t* request,
192                                          bool streaming) {
193     ATRACE_CALL();
194     ALOGV("%s", __FUNCTION__);
195 
196     Mutex::Autolock icl(mBinderSerializationLock);
197 
198     if (!mDevice.get()) return DEAD_OBJECT;
199 
200     if (!mExclusiveLock) {
201         return PERMISSION_DENIED;
202     }
203 
204     CameraMetadata metadata(request);
205 
206     if (!enforceRequestPermissions(metadata)) {
207         return PERMISSION_DENIED;
208     }
209 
210     if (streaming) {
211         return mDevice->setStreamingRequest(metadata);
212     } else {
213         return mDevice->capture(metadata);
214     }
215 
216     // unreachable. thx gcc for a useless warning
217     return OK;
218 }
219 
cancelRequest(int requestId)220 status_t ProCamera2Client::cancelRequest(int requestId) {
221     ATRACE_CALL();
222     ALOGV("%s", __FUNCTION__);
223 
224     Mutex::Autolock icl(mBinderSerializationLock);
225 
226     if (!mDevice.get()) return DEAD_OBJECT;
227 
228     if (!mExclusiveLock) {
229         return PERMISSION_DENIED;
230     }
231 
232     // TODO: implement
233     ALOGE("%s: not fully implemented yet", __FUNCTION__);
234     return INVALID_OPERATION;
235 }
236 
deleteStream(int streamId)237 status_t ProCamera2Client::deleteStream(int streamId) {
238     ATRACE_CALL();
239     ALOGV("%s (streamId = 0x%x)", __FUNCTION__, streamId);
240 
241     status_t res;
242     if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
243 
244     Mutex::Autolock icl(mBinderSerializationLock);
245 
246     if (!mDevice.get()) return DEAD_OBJECT;
247     mDevice->clearStreamingRequest();
248 
249     status_t code;
250     if ((code = mDevice->waitUntilDrained()) != OK) {
251         ALOGE("%s: waitUntilDrained failed with code 0x%x", __FUNCTION__, code);
252     }
253 
254     return mDevice->deleteStream(streamId);
255 }
256 
createStream(int width,int height,int format,const sp<IGraphicBufferProducer> & bufferProducer,int * streamId)257 status_t ProCamera2Client::createStream(int width, int height, int format,
258                       const sp<IGraphicBufferProducer>& bufferProducer,
259                       /*out*/
260                       int* streamId)
261 {
262     if (streamId) {
263         *streamId = -1;
264     }
265 
266     ATRACE_CALL();
267     ALOGV("%s (w = %d, h = %d, f = 0x%x)", __FUNCTION__, width, height, format);
268 
269     status_t res;
270     if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
271 
272     Mutex::Autolock icl(mBinderSerializationLock);
273 
274     if (!mDevice.get()) return DEAD_OBJECT;
275 
276     sp<IBinder> binder;
277     sp<ANativeWindow> window;
278     if (bufferProducer != 0) {
279         binder = bufferProducer->asBinder();
280         window = new Surface(bufferProducer);
281     }
282 
283     return mDevice->createStream(window, width, height, format, /*size*/1,
284                                  streamId);
285 }
286 
287 // Create a request object from a template.
288 // -- Caller owns the newly allocated metadata
createDefaultRequest(int templateId,camera_metadata ** request)289 status_t ProCamera2Client::createDefaultRequest(int templateId,
290                              /*out*/
291                               camera_metadata** request)
292 {
293     ATRACE_CALL();
294     ALOGV("%s (templateId = 0x%x)", __FUNCTION__, templateId);
295 
296     if (request) {
297         *request = NULL;
298     }
299 
300     status_t res;
301     if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
302 
303     Mutex::Autolock icl(mBinderSerializationLock);
304 
305     if (!mDevice.get()) return DEAD_OBJECT;
306 
307     CameraMetadata metadata;
308     if ( (res = mDevice->createDefaultRequest(templateId, &metadata) ) == OK) {
309         *request = metadata.release();
310     }
311 
312     return res;
313 }
314 
getCameraInfo(int cameraId,camera_metadata ** info)315 status_t ProCamera2Client::getCameraInfo(int cameraId,
316                                          /*out*/
317                                          camera_metadata** info)
318 {
319     if (cameraId != mCameraId) {
320         return INVALID_OPERATION;
321     }
322 
323     Mutex::Autolock icl(mBinderSerializationLock);
324 
325     if (!mDevice.get()) return DEAD_OBJECT;
326 
327     CameraMetadata deviceInfo = mDevice->info();
328     *info = deviceInfo.release();
329 
330     return OK;
331 }
332 
dump(int fd,const Vector<String16> & args)333 status_t ProCamera2Client::dump(int fd, const Vector<String16>& args) {
334     String8 result;
335     result.appendFormat("ProCamera2Client[%d] (%p) PID: %d, dump:\n",
336             mCameraId,
337             getRemoteCallback()->asBinder().get(),
338             mClientPid);
339     result.append("  State: ");
340 
341     // TODO: print dynamic/request section from most recent requests
342     mFrameProcessor->dump(fd, args);
343 
344     return dumpDevice(fd, args);
345 }
346 
347 // IProCameraUser interface
348 
detachDevice()349 void ProCamera2Client::detachDevice() {
350     if (mDevice == 0) return;
351 
352     ALOGV("Camera %d: Stopping processors", mCameraId);
353 
354     mFrameProcessor->removeListener(FRAME_PROCESSOR_LISTENER_MIN_ID,
355                                     FRAME_PROCESSOR_LISTENER_MAX_ID,
356                                     /*listener*/this);
357     mFrameProcessor->requestExit();
358     ALOGV("Camera %d: Waiting for threads", mCameraId);
359     mFrameProcessor->join();
360     ALOGV("Camera %d: Disconnecting device", mCameraId);
361 
362     // WORKAROUND: HAL refuses to disconnect while there's streams in flight
363     {
364         mDevice->clearStreamingRequest();
365 
366         status_t code;
367         if ((code = mDevice->waitUntilDrained()) != OK) {
368             ALOGE("%s: waitUntilDrained failed with code 0x%x", __FUNCTION__,
369                   code);
370         }
371     }
372 
373     Camera2ClientBase::detachDevice();
374 }
375 
376 /** Device-related methods */
onFrameAvailable(int32_t frameId,const CameraMetadata & frame)377 void ProCamera2Client::onFrameAvailable(int32_t frameId,
378                                         const CameraMetadata& frame) {
379     ATRACE_CALL();
380     ALOGV("%s", __FUNCTION__);
381 
382     Mutex::Autolock icl(mBinderSerializationLock);
383     SharedCameraCallbacks::Lock l(mSharedCameraCallbacks);
384 
385     if (mRemoteCallback != NULL) {
386         CameraMetadata tmp(frame);
387         camera_metadata_t* meta = tmp.release();
388         ALOGV("%s: meta = %p ", __FUNCTION__, meta);
389         mRemoteCallback->onResultReceived(frameId, meta);
390         tmp.acquire(meta);
391     }
392 
393 }
394 
enforceRequestPermissions(CameraMetadata & metadata)395 bool ProCamera2Client::enforceRequestPermissions(CameraMetadata& metadata) {
396 
397     const int pid = IPCThreadState::self()->getCallingPid();
398     const int selfPid = getpid();
399     camera_metadata_entry_t entry;
400 
401     /**
402      * Mixin default important security values
403      * - android.led.transmit = defaulted ON
404      */
405     CameraMetadata staticInfo = mDevice->info();
406     entry = staticInfo.find(ANDROID_LED_AVAILABLE_LEDS);
407     for(size_t i = 0; i < entry.count; ++i) {
408         uint8_t led = entry.data.u8[i];
409 
410         switch(led) {
411             case ANDROID_LED_AVAILABLE_LEDS_TRANSMIT: {
412                 uint8_t transmitDefault = ANDROID_LED_TRANSMIT_ON;
413                 if (!metadata.exists(ANDROID_LED_TRANSMIT)) {
414                     metadata.update(ANDROID_LED_TRANSMIT,
415                                     &transmitDefault, 1);
416                 }
417                 break;
418             }
419         }
420     }
421 
422     // We can do anything!
423     if (pid == selfPid) {
424         return true;
425     }
426 
427     /**
428      * Permission check special fields in the request
429      * - android.led.transmit = android.permission.CAMERA_DISABLE_TRANSMIT
430      */
431     entry = metadata.find(ANDROID_LED_TRANSMIT);
432     if (entry.count > 0 && entry.data.u8[0] != ANDROID_LED_TRANSMIT_ON) {
433         String16 permissionString =
434             String16("android.permission.CAMERA_DISABLE_TRANSMIT_LED");
435         if (!checkCallingPermission(permissionString)) {
436             const int uid = IPCThreadState::self()->getCallingUid();
437             ALOGE("Permission Denial: "
438                   "can't disable transmit LED pid=%d, uid=%d", pid, uid);
439             return false;
440         }
441     }
442 
443     return true;
444 }
445 
446 } // namespace android
447