• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2 **
3 ** Copyright (C) 2008, 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_TAG "CameraService"
19 //#define LOG_NDEBUG 0
20 
21 #include <stdio.h>
22 #include <sys/types.h>
23 #include <pthread.h>
24 
25 #include <binder/IPCThreadState.h>
26 #include <binder/IServiceManager.h>
27 #include <binder/MemoryBase.h>
28 #include <binder/MemoryHeapBase.h>
29 #include <cutils/atomic.h>
30 #include <cutils/properties.h>
31 #include <gui/SurfaceTextureClient.h>
32 #include <hardware/hardware.h>
33 #include <media/AudioSystem.h>
34 #include <media/mediaplayer.h>
35 #include <surfaceflinger/ISurface.h>
36 #include <utils/Errors.h>
37 #include <utils/Log.h>
38 #include <utils/String16.h>
39 
40 #include "CameraService.h"
41 #include "CameraHardwareInterface.h"
42 
43 namespace android {
44 
45 // ----------------------------------------------------------------------------
46 // Logging support -- this is for debugging only
47 // Use "adb shell dumpsys media.camera -v 1" to change it.
48 static volatile int32_t gLogLevel = 0;
49 
50 #define LOG1(...) LOGD_IF(gLogLevel >= 1, __VA_ARGS__);
51 #define LOG2(...) LOGD_IF(gLogLevel >= 2, __VA_ARGS__);
52 
setLogLevel(int level)53 static void setLogLevel(int level) {
54     android_atomic_write(level, &gLogLevel);
55 }
56 
57 // ----------------------------------------------------------------------------
58 
getCallingPid()59 static int getCallingPid() {
60     return IPCThreadState::self()->getCallingPid();
61 }
62 
getCallingUid()63 static int getCallingUid() {
64     return IPCThreadState::self()->getCallingUid();
65 }
66 
67 // ----------------------------------------------------------------------------
68 
69 // This is ugly and only safe if we never re-create the CameraService, but
70 // should be ok for now.
71 static CameraService *gCameraService;
72 
CameraService()73 CameraService::CameraService()
74 :mSoundRef(0), mModule(0)
75 {
76     LOGI("CameraService started (pid=%d)", getpid());
77     gCameraService = this;
78 }
79 
onFirstRef()80 void CameraService::onFirstRef()
81 {
82     BnCameraService::onFirstRef();
83 
84     if (hw_get_module(CAMERA_HARDWARE_MODULE_ID,
85                 (const hw_module_t **)&mModule) < 0) {
86         LOGE("Could not load camera HAL module");
87         mNumberOfCameras = 0;
88     }
89     else {
90         mNumberOfCameras = mModule->get_number_of_cameras();
91         if (mNumberOfCameras > MAX_CAMERAS) {
92             LOGE("Number of cameras(%d) > MAX_CAMERAS(%d).",
93                     mNumberOfCameras, MAX_CAMERAS);
94             mNumberOfCameras = MAX_CAMERAS;
95         }
96         for (int i = 0; i < mNumberOfCameras; i++) {
97             setCameraFree(i);
98         }
99     }
100 
101     // Read the system property to determine if we have to use the
102     // AUDIO_STREAM_ENFORCED_AUDIBLE type.
103     char value[PROPERTY_VALUE_MAX];
104     property_get("ro.camera.sound.forced", value, "0");
105     if (strcmp(value, "0") != 0) {
106         mAudioStreamType = AUDIO_STREAM_ENFORCED_AUDIBLE;
107     } else {
108         mAudioStreamType = AUDIO_STREAM_MUSIC;
109     }
110 }
111 
~CameraService()112 CameraService::~CameraService() {
113     for (int i = 0; i < mNumberOfCameras; i++) {
114         if (mBusy[i]) {
115             LOGE("camera %d is still in use in destructor!", i);
116         }
117     }
118 
119     gCameraService = NULL;
120 }
121 
getNumberOfCameras()122 int32_t CameraService::getNumberOfCameras() {
123     return mNumberOfCameras;
124 }
125 
getCameraInfo(int cameraId,struct CameraInfo * cameraInfo)126 status_t CameraService::getCameraInfo(int cameraId,
127                                       struct CameraInfo* cameraInfo) {
128     if (!mModule) {
129         return NO_INIT;
130     }
131 
132     if (cameraId < 0 || cameraId >= mNumberOfCameras) {
133         return BAD_VALUE;
134     }
135 
136     struct camera_info info;
137     status_t rc = mModule->get_camera_info(cameraId, &info);
138     cameraInfo->facing = info.facing;
139     cameraInfo->orientation = info.orientation;
140     return rc;
141 }
142 
connect(const sp<ICameraClient> & cameraClient,int cameraId)143 sp<ICamera> CameraService::connect(
144         const sp<ICameraClient>& cameraClient, int cameraId) {
145     int callingPid = getCallingPid();
146     sp<CameraHardwareInterface> hardware = NULL;
147 
148     LOG1("CameraService::connect E (pid %d, id %d)", callingPid, cameraId);
149 
150     if (!mModule) {
151         LOGE("Camera HAL module not loaded");
152         return NULL;
153     }
154 
155     sp<Client> client;
156     if (cameraId < 0 || cameraId >= mNumberOfCameras) {
157         LOGE("CameraService::connect X (pid %d) rejected (invalid cameraId %d).",
158             callingPid, cameraId);
159         return NULL;
160     }
161 
162     char value[PROPERTY_VALUE_MAX];
163     property_get("sys.secpolicy.camera.disabled", value, "0");
164     if (strcmp(value, "1") == 0) {
165         // Camera is disabled by DevicePolicyManager.
166         LOGI("Camera is disabled. connect X (pid %d) rejected", callingPid);
167         return NULL;
168     }
169 
170     Mutex::Autolock lock(mServiceLock);
171     if (mClient[cameraId] != 0) {
172         client = mClient[cameraId].promote();
173         if (client != 0) {
174             if (cameraClient->asBinder() == client->getCameraClient()->asBinder()) {
175                 LOG1("CameraService::connect X (pid %d) (the same client)",
176                     callingPid);
177                 return client;
178             } else {
179                 LOGW("CameraService::connect X (pid %d) rejected (existing client).",
180                     callingPid);
181                 return NULL;
182             }
183         }
184         mClient[cameraId].clear();
185     }
186 
187     if (mBusy[cameraId]) {
188         LOGW("CameraService::connect X (pid %d) rejected"
189              " (camera %d is still busy).", callingPid, cameraId);
190         return NULL;
191     }
192 
193     struct camera_info info;
194     if (mModule->get_camera_info(cameraId, &info) != OK) {
195         LOGE("Invalid camera id %d", cameraId);
196         return NULL;
197     }
198 
199     char camera_device_name[10];
200     snprintf(camera_device_name, sizeof(camera_device_name), "%d", cameraId);
201 
202     hardware = new CameraHardwareInterface(camera_device_name);
203     if (hardware->initialize(&mModule->common) != OK) {
204         hardware.clear();
205         return NULL;
206     }
207 
208     client = new Client(this, cameraClient, hardware, cameraId, info.facing, callingPid);
209     mClient[cameraId] = client;
210     LOG1("CameraService::connect X");
211     return client;
212 }
213 
removeClient(const sp<ICameraClient> & cameraClient)214 void CameraService::removeClient(const sp<ICameraClient>& cameraClient) {
215     int callingPid = getCallingPid();
216     LOG1("CameraService::removeClient E (pid %d)", callingPid);
217 
218     for (int i = 0; i < mNumberOfCameras; i++) {
219         // Declare this before the lock to make absolutely sure the
220         // destructor won't be called with the lock held.
221         sp<Client> client;
222 
223         Mutex::Autolock lock(mServiceLock);
224 
225         // This happens when we have already disconnected (or this is
226         // just another unused camera).
227         if (mClient[i] == 0) continue;
228 
229         // Promote mClient. It can fail if we are called from this path:
230         // Client::~Client() -> disconnect() -> removeClient().
231         client = mClient[i].promote();
232 
233         if (client == 0) {
234             mClient[i].clear();
235             continue;
236         }
237 
238         if (cameraClient->asBinder() == client->getCameraClient()->asBinder()) {
239             // Found our camera, clear and leave.
240             LOG1("removeClient: clear camera %d", i);
241             mClient[i].clear();
242             break;
243         }
244     }
245 
246     LOG1("CameraService::removeClient X (pid %d)", callingPid);
247 }
248 
getClientById(int cameraId)249 sp<CameraService::Client> CameraService::getClientById(int cameraId) {
250     if (cameraId < 0 || cameraId >= mNumberOfCameras) return NULL;
251     return mClient[cameraId].promote();
252 }
253 
onTransact(uint32_t code,const Parcel & data,Parcel * reply,uint32_t flags)254 status_t CameraService::onTransact(
255     uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) {
256     // Permission checks
257     switch (code) {
258         case BnCameraService::CONNECT:
259             const int pid = getCallingPid();
260             const int self_pid = getpid();
261             if (pid != self_pid) {
262                 // we're called from a different process, do the real check
263                 if (!checkCallingPermission(
264                         String16("android.permission.CAMERA"))) {
265                     const int uid = getCallingUid();
266                     LOGE("Permission Denial: "
267                          "can't use the camera pid=%d, uid=%d", pid, uid);
268                     return PERMISSION_DENIED;
269                 }
270             }
271             break;
272     }
273 
274     return BnCameraService::onTransact(code, data, reply, flags);
275 }
276 
277 // The reason we need this busy bit is a new CameraService::connect() request
278 // may come in while the previous Client's destructor has not been run or is
279 // still running. If the last strong reference of the previous Client is gone
280 // but the destructor has not been finished, we should not allow the new Client
281 // to be created because we need to wait for the previous Client to tear down
282 // the hardware first.
setCameraBusy(int cameraId)283 void CameraService::setCameraBusy(int cameraId) {
284     android_atomic_write(1, &mBusy[cameraId]);
285 }
286 
setCameraFree(int cameraId)287 void CameraService::setCameraFree(int cameraId) {
288     android_atomic_write(0, &mBusy[cameraId]);
289 }
290 
291 // We share the media players for shutter and recording sound for all clients.
292 // A reference count is kept to determine when we will actually release the
293 // media players.
294 
newMediaPlayer(const char * file)295 MediaPlayer* CameraService::newMediaPlayer(const char *file) {
296     MediaPlayer* mp = new MediaPlayer();
297     if (mp->setDataSource(file, NULL) == NO_ERROR) {
298         mp->setAudioStreamType(mAudioStreamType);
299         mp->prepare();
300     } else {
301         LOGE("Failed to load CameraService sounds: %s", file);
302         return NULL;
303     }
304     return mp;
305 }
306 
loadSound()307 void CameraService::loadSound() {
308     Mutex::Autolock lock(mSoundLock);
309     LOG1("CameraService::loadSound ref=%d", mSoundRef);
310     if (mSoundRef++) return;
311 
312     mSoundPlayer[SOUND_SHUTTER] = newMediaPlayer("/system/media/audio/ui/camera_click.ogg");
313     mSoundPlayer[SOUND_RECORDING] = newMediaPlayer("/system/media/audio/ui/VideoRecord.ogg");
314 }
315 
releaseSound()316 void CameraService::releaseSound() {
317     Mutex::Autolock lock(mSoundLock);
318     LOG1("CameraService::releaseSound ref=%d", mSoundRef);
319     if (--mSoundRef) return;
320 
321     for (int i = 0; i < NUM_SOUNDS; i++) {
322         if (mSoundPlayer[i] != 0) {
323             mSoundPlayer[i]->disconnect();
324             mSoundPlayer[i].clear();
325         }
326     }
327 }
328 
playSound(sound_kind kind)329 void CameraService::playSound(sound_kind kind) {
330     LOG1("playSound(%d)", kind);
331     Mutex::Autolock lock(mSoundLock);
332     sp<MediaPlayer> player = mSoundPlayer[kind];
333     if (player != 0) {
334         player->seekTo(0);
335         player->start();
336     }
337 }
338 
339 // ----------------------------------------------------------------------------
340 
Client(const sp<CameraService> & cameraService,const sp<ICameraClient> & cameraClient,const sp<CameraHardwareInterface> & hardware,int cameraId,int cameraFacing,int clientPid)341 CameraService::Client::Client(const sp<CameraService>& cameraService,
342         const sp<ICameraClient>& cameraClient,
343         const sp<CameraHardwareInterface>& hardware,
344         int cameraId, int cameraFacing, int clientPid) {
345     int callingPid = getCallingPid();
346     LOG1("Client::Client E (pid %d)", callingPid);
347 
348     mCameraService = cameraService;
349     mCameraClient = cameraClient;
350     mHardware = hardware;
351     mCameraId = cameraId;
352     mCameraFacing = cameraFacing;
353     mClientPid = clientPid;
354     mMsgEnabled = 0;
355     mSurface = 0;
356     mPreviewWindow = 0;
357     mHardware->setCallbacks(notifyCallback,
358                             dataCallback,
359                             dataCallbackTimestamp,
360                             (void *)cameraId);
361 
362     // Enable zoom, error, focus, and metadata messages by default
363     enableMsgType(CAMERA_MSG_ERROR | CAMERA_MSG_ZOOM | CAMERA_MSG_FOCUS |
364                   CAMERA_MSG_PREVIEW_METADATA);
365 
366     // Callback is disabled by default
367     mPreviewCallbackFlag = CAMERA_FRAME_CALLBACK_FLAG_NOOP;
368     mOrientation = getOrientation(0, mCameraFacing == CAMERA_FACING_FRONT);
369     mPlayShutterSound = true;
370     cameraService->setCameraBusy(cameraId);
371     cameraService->loadSound();
372     LOG1("Client::Client X (pid %d)", callingPid);
373 }
374 
375 // tear down the client
~Client()376 CameraService::Client::~Client() {
377     int callingPid = getCallingPid();
378     LOG1("Client::~Client E (pid %d, this %p)", callingPid, this);
379 
380     // set mClientPid to let disconnet() tear down the hardware
381     mClientPid = callingPid;
382     disconnect();
383     mCameraService->releaseSound();
384     LOG1("Client::~Client X (pid %d, this %p)", callingPid, this);
385 }
386 
387 // ----------------------------------------------------------------------------
388 
checkPid() const389 status_t CameraService::Client::checkPid() const {
390     int callingPid = getCallingPid();
391     if (callingPid == mClientPid) return NO_ERROR;
392 
393     LOGW("attempt to use a locked camera from a different process"
394          " (old pid %d, new pid %d)", mClientPid, callingPid);
395     return EBUSY;
396 }
397 
checkPidAndHardware() const398 status_t CameraService::Client::checkPidAndHardware() const {
399     status_t result = checkPid();
400     if (result != NO_ERROR) return result;
401     if (mHardware == 0) {
402         LOGE("attempt to use a camera after disconnect() (pid %d)", getCallingPid());
403         return INVALID_OPERATION;
404     }
405     return NO_ERROR;
406 }
407 
lock()408 status_t CameraService::Client::lock() {
409     int callingPid = getCallingPid();
410     LOG1("lock (pid %d)", callingPid);
411     Mutex::Autolock lock(mLock);
412 
413     // lock camera to this client if the the camera is unlocked
414     if (mClientPid == 0) {
415         mClientPid = callingPid;
416         return NO_ERROR;
417     }
418 
419     // returns NO_ERROR if the client already owns the camera, EBUSY otherwise
420     return checkPid();
421 }
422 
unlock()423 status_t CameraService::Client::unlock() {
424     int callingPid = getCallingPid();
425     LOG1("unlock (pid %d)", callingPid);
426     Mutex::Autolock lock(mLock);
427 
428     // allow anyone to use camera (after they lock the camera)
429     status_t result = checkPid();
430     if (result == NO_ERROR) {
431         if (mHardware->recordingEnabled()) {
432             LOGE("Not allowed to unlock camera during recording.");
433             return INVALID_OPERATION;
434         }
435         mClientPid = 0;
436         LOG1("clear mCameraClient (pid %d)", callingPid);
437         // we need to remove the reference to ICameraClient so that when the app
438         // goes away, the reference count goes to 0.
439         mCameraClient.clear();
440     }
441     return result;
442 }
443 
444 // connect a new client to the camera
connect(const sp<ICameraClient> & client)445 status_t CameraService::Client::connect(const sp<ICameraClient>& client) {
446     int callingPid = getCallingPid();
447     LOG1("connect E (pid %d)", callingPid);
448     Mutex::Autolock lock(mLock);
449 
450     if (mClientPid != 0 && checkPid() != NO_ERROR) {
451         LOGW("Tried to connect to a locked camera (old pid %d, new pid %d)",
452                 mClientPid, callingPid);
453         return EBUSY;
454     }
455 
456     if (mCameraClient != 0 && (client->asBinder() == mCameraClient->asBinder())) {
457         LOG1("Connect to the same client");
458         return NO_ERROR;
459     }
460 
461     mPreviewCallbackFlag = CAMERA_FRAME_CALLBACK_FLAG_NOOP;
462     mClientPid = callingPid;
463     mCameraClient = client;
464 
465     LOG1("connect X (pid %d)", callingPid);
466     return NO_ERROR;
467 }
468 
disconnectWindow(const sp<ANativeWindow> & window)469 static void disconnectWindow(const sp<ANativeWindow>& window) {
470     if (window != 0) {
471         status_t result = native_window_api_disconnect(window.get(),
472                 NATIVE_WINDOW_API_CAMERA);
473         if (result != NO_ERROR) {
474             LOGW("native_window_api_disconnect failed: %s (%d)", strerror(-result),
475                     result);
476         }
477     }
478 }
479 
disconnect()480 void CameraService::Client::disconnect() {
481     int callingPid = getCallingPid();
482     LOG1("disconnect E (pid %d)", callingPid);
483     Mutex::Autolock lock(mLock);
484 
485     if (checkPid() != NO_ERROR) {
486         LOGW("different client - don't disconnect");
487         return;
488     }
489 
490     if (mClientPid <= 0) {
491         LOG1("camera is unlocked (mClientPid = %d), don't tear down hardware", mClientPid);
492         return;
493     }
494 
495     // Make sure disconnect() is done once and once only, whether it is called
496     // from the user directly, or called by the destructor.
497     if (mHardware == 0) return;
498 
499     LOG1("hardware teardown");
500     // Before destroying mHardware, we must make sure it's in the
501     // idle state.
502     // Turn off all messages.
503     disableMsgType(CAMERA_MSG_ALL_MSGS);
504     mHardware->stopPreview();
505     mHardware->cancelPicture();
506     // Release the hardware resources.
507     mHardware->release();
508 
509     // Release the held ANativeWindow resources.
510     if (mPreviewWindow != 0) {
511         disconnectWindow(mPreviewWindow);
512         mPreviewWindow = 0;
513         mHardware->setPreviewWindow(mPreviewWindow);
514     }
515     mHardware.clear();
516 
517     mCameraService->removeClient(mCameraClient);
518     mCameraService->setCameraFree(mCameraId);
519 
520     LOG1("disconnect X (pid %d)", callingPid);
521 }
522 
523 // ----------------------------------------------------------------------------
524 
setPreviewWindow(const sp<IBinder> & binder,const sp<ANativeWindow> & window)525 status_t CameraService::Client::setPreviewWindow(const sp<IBinder>& binder,
526         const sp<ANativeWindow>& window) {
527     Mutex::Autolock lock(mLock);
528     status_t result = checkPidAndHardware();
529     if (result != NO_ERROR) return result;
530 
531     // return if no change in surface.
532     if (binder == mSurface) {
533         return NO_ERROR;
534     }
535 
536     if (window != 0) {
537         result = native_window_api_connect(window.get(), NATIVE_WINDOW_API_CAMERA);
538         if (result != NO_ERROR) {
539             LOGE("native_window_api_connect failed: %s (%d)", strerror(-result),
540                     result);
541             return result;
542         }
543     }
544 
545     // If preview has been already started, register preview buffers now.
546     if (mHardware->previewEnabled()) {
547         if (window != 0) {
548             native_window_set_scaling_mode(window.get(),
549                     NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
550             native_window_set_buffers_transform(window.get(), mOrientation);
551             result = mHardware->setPreviewWindow(window);
552         }
553     }
554 
555     if (result == NO_ERROR) {
556         // Everything has succeeded.  Disconnect the old window and remember the
557         // new window.
558         disconnectWindow(mPreviewWindow);
559         mSurface = binder;
560         mPreviewWindow = window;
561     } else {
562         // Something went wrong after we connected to the new window, so
563         // disconnect here.
564         disconnectWindow(window);
565     }
566 
567     return result;
568 }
569 
570 // set the Surface that the preview will use
setPreviewDisplay(const sp<Surface> & surface)571 status_t CameraService::Client::setPreviewDisplay(const sp<Surface>& surface) {
572     LOG1("setPreviewDisplay(%p) (pid %d)", surface.get(), getCallingPid());
573 
574     sp<IBinder> binder(surface != 0 ? surface->asBinder() : 0);
575     sp<ANativeWindow> window(surface);
576     return setPreviewWindow(binder, window);
577 }
578 
579 // set the SurfaceTexture that the preview will use
setPreviewTexture(const sp<ISurfaceTexture> & surfaceTexture)580 status_t CameraService::Client::setPreviewTexture(
581         const sp<ISurfaceTexture>& surfaceTexture) {
582     LOG1("setPreviewTexture(%p) (pid %d)", surfaceTexture.get(),
583             getCallingPid());
584 
585     sp<IBinder> binder;
586     sp<ANativeWindow> window;
587     if (surfaceTexture != 0) {
588         binder = surfaceTexture->asBinder();
589         window = new SurfaceTextureClient(surfaceTexture);
590     }
591     return setPreviewWindow(binder, window);
592 }
593 
594 // set the preview callback flag to affect how the received frames from
595 // preview are handled.
setPreviewCallbackFlag(int callback_flag)596 void CameraService::Client::setPreviewCallbackFlag(int callback_flag) {
597     LOG1("setPreviewCallbackFlag(%d) (pid %d)", callback_flag, getCallingPid());
598     Mutex::Autolock lock(mLock);
599     if (checkPidAndHardware() != NO_ERROR) return;
600 
601     mPreviewCallbackFlag = callback_flag;
602     if (mPreviewCallbackFlag & CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK) {
603         enableMsgType(CAMERA_MSG_PREVIEW_FRAME);
604     } else {
605         disableMsgType(CAMERA_MSG_PREVIEW_FRAME);
606     }
607 }
608 
609 // start preview mode
startPreview()610 status_t CameraService::Client::startPreview() {
611     LOG1("startPreview (pid %d)", getCallingPid());
612     return startCameraMode(CAMERA_PREVIEW_MODE);
613 }
614 
615 // start recording mode
startRecording()616 status_t CameraService::Client::startRecording() {
617     LOG1("startRecording (pid %d)", getCallingPid());
618     return startCameraMode(CAMERA_RECORDING_MODE);
619 }
620 
621 // start preview or recording
startCameraMode(camera_mode mode)622 status_t CameraService::Client::startCameraMode(camera_mode mode) {
623     LOG1("startCameraMode(%d)", mode);
624     Mutex::Autolock lock(mLock);
625     status_t result = checkPidAndHardware();
626     if (result != NO_ERROR) return result;
627 
628     switch(mode) {
629         case CAMERA_PREVIEW_MODE:
630             if (mSurface == 0 && mPreviewWindow == 0) {
631                 LOG1("mSurface is not set yet.");
632                 // still able to start preview in this case.
633             }
634             return startPreviewMode();
635         case CAMERA_RECORDING_MODE:
636             if (mSurface == 0 && mPreviewWindow == 0) {
637                 LOGE("mSurface or mPreviewWindow must be set before startRecordingMode.");
638                 return INVALID_OPERATION;
639             }
640             return startRecordingMode();
641         default:
642             return UNKNOWN_ERROR;
643     }
644 }
645 
startPreviewMode()646 status_t CameraService::Client::startPreviewMode() {
647     LOG1("startPreviewMode");
648     status_t result = NO_ERROR;
649 
650     // if preview has been enabled, nothing needs to be done
651     if (mHardware->previewEnabled()) {
652         return NO_ERROR;
653     }
654 
655     if (mPreviewWindow != 0) {
656         native_window_set_scaling_mode(mPreviewWindow.get(),
657                 NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
658         native_window_set_buffers_transform(mPreviewWindow.get(),
659                 mOrientation);
660     }
661     mHardware->setPreviewWindow(mPreviewWindow);
662     result = mHardware->startPreview();
663 
664     return result;
665 }
666 
startRecordingMode()667 status_t CameraService::Client::startRecordingMode() {
668     LOG1("startRecordingMode");
669     status_t result = NO_ERROR;
670 
671     // if recording has been enabled, nothing needs to be done
672     if (mHardware->recordingEnabled()) {
673         return NO_ERROR;
674     }
675 
676     // if preview has not been started, start preview first
677     if (!mHardware->previewEnabled()) {
678         result = startPreviewMode();
679         if (result != NO_ERROR) {
680             return result;
681         }
682     }
683 
684     // start recording mode
685     enableMsgType(CAMERA_MSG_VIDEO_FRAME);
686     mCameraService->playSound(SOUND_RECORDING);
687     result = mHardware->startRecording();
688     if (result != NO_ERROR) {
689         LOGE("mHardware->startRecording() failed with status %d", result);
690     }
691     return result;
692 }
693 
694 // stop preview mode
stopPreview()695 void CameraService::Client::stopPreview() {
696     LOG1("stopPreview (pid %d)", getCallingPid());
697     Mutex::Autolock lock(mLock);
698     if (checkPidAndHardware() != NO_ERROR) return;
699 
700 
701     disableMsgType(CAMERA_MSG_PREVIEW_FRAME);
702     mHardware->stopPreview();
703 
704     mPreviewBuffer.clear();
705 }
706 
707 // stop recording mode
stopRecording()708 void CameraService::Client::stopRecording() {
709     LOG1("stopRecording (pid %d)", getCallingPid());
710     Mutex::Autolock lock(mLock);
711     if (checkPidAndHardware() != NO_ERROR) return;
712 
713     mCameraService->playSound(SOUND_RECORDING);
714     disableMsgType(CAMERA_MSG_VIDEO_FRAME);
715     mHardware->stopRecording();
716 
717     mPreviewBuffer.clear();
718 }
719 
720 // release a recording frame
releaseRecordingFrame(const sp<IMemory> & mem)721 void CameraService::Client::releaseRecordingFrame(const sp<IMemory>& mem) {
722     Mutex::Autolock lock(mLock);
723     if (checkPidAndHardware() != NO_ERROR) return;
724     mHardware->releaseRecordingFrame(mem);
725 }
726 
storeMetaDataInBuffers(bool enabled)727 status_t CameraService::Client::storeMetaDataInBuffers(bool enabled)
728 {
729     LOG1("storeMetaDataInBuffers: %s", enabled? "true": "false");
730     Mutex::Autolock lock(mLock);
731     if (checkPidAndHardware() != NO_ERROR) {
732         return UNKNOWN_ERROR;
733     }
734     return mHardware->storeMetaDataInBuffers(enabled);
735 }
736 
previewEnabled()737 bool CameraService::Client::previewEnabled() {
738     LOG1("previewEnabled (pid %d)", getCallingPid());
739 
740     Mutex::Autolock lock(mLock);
741     if (checkPidAndHardware() != NO_ERROR) return false;
742     return mHardware->previewEnabled();
743 }
744 
recordingEnabled()745 bool CameraService::Client::recordingEnabled() {
746     LOG1("recordingEnabled (pid %d)", getCallingPid());
747 
748     Mutex::Autolock lock(mLock);
749     if (checkPidAndHardware() != NO_ERROR) return false;
750     return mHardware->recordingEnabled();
751 }
752 
autoFocus()753 status_t CameraService::Client::autoFocus() {
754     LOG1("autoFocus (pid %d)", getCallingPid());
755 
756     Mutex::Autolock lock(mLock);
757     status_t result = checkPidAndHardware();
758     if (result != NO_ERROR) return result;
759 
760     return mHardware->autoFocus();
761 }
762 
cancelAutoFocus()763 status_t CameraService::Client::cancelAutoFocus() {
764     LOG1("cancelAutoFocus (pid %d)", getCallingPid());
765 
766     Mutex::Autolock lock(mLock);
767     status_t result = checkPidAndHardware();
768     if (result != NO_ERROR) return result;
769 
770     return mHardware->cancelAutoFocus();
771 }
772 
773 // take a picture - image is returned in callback
takePicture(int msgType)774 status_t CameraService::Client::takePicture(int msgType) {
775     LOG1("takePicture (pid %d): 0x%x", getCallingPid(), msgType);
776 
777     Mutex::Autolock lock(mLock);
778     status_t result = checkPidAndHardware();
779     if (result != NO_ERROR) return result;
780 
781     if ((msgType & CAMERA_MSG_RAW_IMAGE) &&
782         (msgType & CAMERA_MSG_RAW_IMAGE_NOTIFY)) {
783         LOGE("CAMERA_MSG_RAW_IMAGE and CAMERA_MSG_RAW_IMAGE_NOTIFY"
784                 " cannot be both enabled");
785         return BAD_VALUE;
786     }
787 
788     // We only accept picture related message types
789     // and ignore other types of messages for takePicture().
790     int picMsgType = msgType
791                         & (CAMERA_MSG_SHUTTER |
792                            CAMERA_MSG_POSTVIEW_FRAME |
793                            CAMERA_MSG_RAW_IMAGE |
794                            CAMERA_MSG_RAW_IMAGE_NOTIFY |
795                            CAMERA_MSG_COMPRESSED_IMAGE);
796 
797     enableMsgType(picMsgType);
798 
799     return mHardware->takePicture();
800 }
801 
802 // set preview/capture parameters - key/value pairs
setParameters(const String8 & params)803 status_t CameraService::Client::setParameters(const String8& params) {
804     LOG1("setParameters (pid %d) (%s)", getCallingPid(), params.string());
805 
806     Mutex::Autolock lock(mLock);
807     status_t result = checkPidAndHardware();
808     if (result != NO_ERROR) return result;
809 
810     CameraParameters p(params);
811     return mHardware->setParameters(p);
812 }
813 
814 // get preview/capture parameters - key/value pairs
getParameters() const815 String8 CameraService::Client::getParameters() const {
816     Mutex::Autolock lock(mLock);
817     if (checkPidAndHardware() != NO_ERROR) return String8();
818 
819     String8 params(mHardware->getParameters().flatten());
820     LOG1("getParameters (pid %d) (%s)", getCallingPid(), params.string());
821     return params;
822 }
823 
824 // enable shutter sound
enableShutterSound(bool enable)825 status_t CameraService::Client::enableShutterSound(bool enable) {
826     LOG1("enableShutterSound (pid %d)", getCallingPid());
827 
828     status_t result = checkPidAndHardware();
829     if (result != NO_ERROR) return result;
830 
831     if (enable) {
832         mPlayShutterSound = true;
833         return OK;
834     }
835 
836     // Disabling shutter sound may not be allowed. In that case only
837     // allow the mediaserver process to disable the sound.
838     char value[PROPERTY_VALUE_MAX];
839     property_get("ro.camera.sound.forced", value, "0");
840     if (strcmp(value, "0") != 0) {
841         // Disabling shutter sound is not allowed. Deny if the current
842         // process is not mediaserver.
843         if (getCallingPid() != getpid()) {
844             LOGE("Failed to disable shutter sound. Permission denied (pid %d)", getCallingPid());
845             return PERMISSION_DENIED;
846         }
847     }
848 
849     mPlayShutterSound = false;
850     return OK;
851 }
852 
sendCommand(int32_t cmd,int32_t arg1,int32_t arg2)853 status_t CameraService::Client::sendCommand(int32_t cmd, int32_t arg1, int32_t arg2) {
854     LOG1("sendCommand (pid %d)", getCallingPid());
855     int orientation;
856     Mutex::Autolock lock(mLock);
857     status_t result = checkPidAndHardware();
858     if (result != NO_ERROR) return result;
859 
860     if (cmd == CAMERA_CMD_SET_DISPLAY_ORIENTATION) {
861         // Mirror the preview if the camera is front-facing.
862         orientation = getOrientation(arg1, mCameraFacing == CAMERA_FACING_FRONT);
863         if (orientation == -1) return BAD_VALUE;
864 
865         if (mOrientation != orientation) {
866             mOrientation = orientation;
867             if (mPreviewWindow != 0) {
868                 native_window_set_buffers_transform(mPreviewWindow.get(),
869                         mOrientation);
870             }
871         }
872         return OK;
873     } else if (cmd == CAMERA_CMD_ENABLE_SHUTTER_SOUND) {
874         switch (arg1) {
875             case 0:
876                 enableShutterSound(false);
877                 break;
878             case 1:
879                 enableShutterSound(true);
880                 break;
881             default:
882                 return BAD_VALUE;
883         }
884         return OK;
885     } else if (cmd == CAMERA_CMD_PLAY_RECORDING_SOUND) {
886         mCameraService->playSound(SOUND_RECORDING);
887     }
888 
889     return mHardware->sendCommand(cmd, arg1, arg2);
890 }
891 
892 // ----------------------------------------------------------------------------
893 
enableMsgType(int32_t msgType)894 void CameraService::Client::enableMsgType(int32_t msgType) {
895     android_atomic_or(msgType, &mMsgEnabled);
896     mHardware->enableMsgType(msgType);
897 }
898 
disableMsgType(int32_t msgType)899 void CameraService::Client::disableMsgType(int32_t msgType) {
900     android_atomic_and(~msgType, &mMsgEnabled);
901     mHardware->disableMsgType(msgType);
902 }
903 
904 #define CHECK_MESSAGE_INTERVAL 10 // 10ms
lockIfMessageWanted(int32_t msgType)905 bool CameraService::Client::lockIfMessageWanted(int32_t msgType) {
906     int sleepCount = 0;
907     while (mMsgEnabled & msgType) {
908         if (mLock.tryLock() == NO_ERROR) {
909             if (sleepCount > 0) {
910                 LOG1("lockIfMessageWanted(%d): waited for %d ms",
911                     msgType, sleepCount * CHECK_MESSAGE_INTERVAL);
912             }
913             return true;
914         }
915         if (sleepCount++ == 0) {
916             LOG1("lockIfMessageWanted(%d): enter sleep", msgType);
917         }
918         usleep(CHECK_MESSAGE_INTERVAL * 1000);
919     }
920     LOGW("lockIfMessageWanted(%d): dropped unwanted message", msgType);
921     return false;
922 }
923 
924 // ----------------------------------------------------------------------------
925 
926 // Converts from a raw pointer to the client to a strong pointer during a
927 // hardware callback. This requires the callbacks only happen when the client
928 // is still alive.
getClientFromCookie(void * user)929 sp<CameraService::Client> CameraService::Client::getClientFromCookie(void* user) {
930     sp<Client> client = gCameraService->getClientById((int) user);
931 
932     // This could happen if the Client is in the process of shutting down (the
933     // last strong reference is gone, but the destructor hasn't finished
934     // stopping the hardware).
935     if (client == 0) return NULL;
936 
937     // The checks below are not necessary and are for debugging only.
938     if (client->mCameraService.get() != gCameraService) {
939         LOGE("mismatch service!");
940         return NULL;
941     }
942 
943     if (client->mHardware == 0) {
944         LOGE("mHardware == 0: callback after disconnect()?");
945         return NULL;
946     }
947 
948     return client;
949 }
950 
951 // Callback messages can be dispatched to internal handlers or pass to our
952 // client's callback functions, depending on the message type.
953 //
954 // notifyCallback:
955 //      CAMERA_MSG_SHUTTER              handleShutter
956 //      (others)                        c->notifyCallback
957 // dataCallback:
958 //      CAMERA_MSG_PREVIEW_FRAME        handlePreviewData
959 //      CAMERA_MSG_POSTVIEW_FRAME       handlePostview
960 //      CAMERA_MSG_RAW_IMAGE            handleRawPicture
961 //      CAMERA_MSG_COMPRESSED_IMAGE     handleCompressedPicture
962 //      (others)                        c->dataCallback
963 // dataCallbackTimestamp
964 //      (others)                        c->dataCallbackTimestamp
965 //
966 // NOTE: the *Callback functions grab mLock of the client before passing
967 // control to handle* functions. So the handle* functions must release the
968 // lock before calling the ICameraClient's callbacks, so those callbacks can
969 // invoke methods in the Client class again (For example, the preview frame
970 // callback may want to releaseRecordingFrame). The handle* functions must
971 // release the lock after all accesses to member variables, so it must be
972 // handled very carefully.
973 
notifyCallback(int32_t msgType,int32_t ext1,int32_t ext2,void * user)974 void CameraService::Client::notifyCallback(int32_t msgType, int32_t ext1,
975         int32_t ext2, void* user) {
976     LOG2("notifyCallback(%d)", msgType);
977 
978     sp<Client> client = getClientFromCookie(user);
979     if (client == 0) return;
980     if (!client->lockIfMessageWanted(msgType)) return;
981 
982     switch (msgType) {
983         case CAMERA_MSG_SHUTTER:
984             // ext1 is the dimension of the yuv picture.
985             client->handleShutter();
986             break;
987         default:
988             client->handleGenericNotify(msgType, ext1, ext2);
989             break;
990     }
991 }
992 
dataCallback(int32_t msgType,const sp<IMemory> & dataPtr,camera_frame_metadata_t * metadata,void * user)993 void CameraService::Client::dataCallback(int32_t msgType,
994         const sp<IMemory>& dataPtr, camera_frame_metadata_t *metadata, void* user) {
995     LOG2("dataCallback(%d)", msgType);
996 
997     sp<Client> client = getClientFromCookie(user);
998     if (client == 0) return;
999     if (!client->lockIfMessageWanted(msgType)) return;
1000 
1001     if (dataPtr == 0 && metadata == NULL) {
1002         LOGE("Null data returned in data callback");
1003         client->handleGenericNotify(CAMERA_MSG_ERROR, UNKNOWN_ERROR, 0);
1004         return;
1005     }
1006 
1007     switch (msgType & ~CAMERA_MSG_PREVIEW_METADATA) {
1008         case CAMERA_MSG_PREVIEW_FRAME:
1009             client->handlePreviewData(msgType, dataPtr, metadata);
1010             break;
1011         case CAMERA_MSG_POSTVIEW_FRAME:
1012             client->handlePostview(dataPtr);
1013             break;
1014         case CAMERA_MSG_RAW_IMAGE:
1015             client->handleRawPicture(dataPtr);
1016             break;
1017         case CAMERA_MSG_COMPRESSED_IMAGE:
1018             client->handleCompressedPicture(dataPtr);
1019             break;
1020         default:
1021             client->handleGenericData(msgType, dataPtr, metadata);
1022             break;
1023     }
1024 }
1025 
dataCallbackTimestamp(nsecs_t timestamp,int32_t msgType,const sp<IMemory> & dataPtr,void * user)1026 void CameraService::Client::dataCallbackTimestamp(nsecs_t timestamp,
1027         int32_t msgType, const sp<IMemory>& dataPtr, void* user) {
1028     LOG2("dataCallbackTimestamp(%d)", msgType);
1029 
1030     sp<Client> client = getClientFromCookie(user);
1031     if (client == 0) return;
1032     if (!client->lockIfMessageWanted(msgType)) return;
1033 
1034     if (dataPtr == 0) {
1035         LOGE("Null data returned in data with timestamp callback");
1036         client->handleGenericNotify(CAMERA_MSG_ERROR, UNKNOWN_ERROR, 0);
1037         return;
1038     }
1039 
1040     client->handleGenericDataTimestamp(timestamp, msgType, dataPtr);
1041 }
1042 
1043 // snapshot taken callback
handleShutter(void)1044 void CameraService::Client::handleShutter(void) {
1045     if (mPlayShutterSound) {
1046         mCameraService->playSound(SOUND_SHUTTER);
1047     }
1048 
1049     sp<ICameraClient> c = mCameraClient;
1050     if (c != 0) {
1051         mLock.unlock();
1052         c->notifyCallback(CAMERA_MSG_SHUTTER, 0, 0);
1053         if (!lockIfMessageWanted(CAMERA_MSG_SHUTTER)) return;
1054     }
1055     disableMsgType(CAMERA_MSG_SHUTTER);
1056 
1057     mLock.unlock();
1058 }
1059 
1060 // preview callback - frame buffer update
handlePreviewData(int32_t msgType,const sp<IMemory> & mem,camera_frame_metadata_t * metadata)1061 void CameraService::Client::handlePreviewData(int32_t msgType,
1062                                               const sp<IMemory>& mem,
1063                                               camera_frame_metadata_t *metadata) {
1064     ssize_t offset;
1065     size_t size;
1066     sp<IMemoryHeap> heap = mem->getMemory(&offset, &size);
1067 
1068     // local copy of the callback flags
1069     int flags = mPreviewCallbackFlag;
1070 
1071     // is callback enabled?
1072     if (!(flags & CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK)) {
1073         // If the enable bit is off, the copy-out and one-shot bits are ignored
1074         LOG2("frame callback is disabled");
1075         mLock.unlock();
1076         return;
1077     }
1078 
1079     // hold a strong pointer to the client
1080     sp<ICameraClient> c = mCameraClient;
1081 
1082     // clear callback flags if no client or one-shot mode
1083     if (c == 0 || (mPreviewCallbackFlag & CAMERA_FRAME_CALLBACK_FLAG_ONE_SHOT_MASK)) {
1084         LOG2("Disable preview callback");
1085         mPreviewCallbackFlag &= ~(CAMERA_FRAME_CALLBACK_FLAG_ONE_SHOT_MASK |
1086                                   CAMERA_FRAME_CALLBACK_FLAG_COPY_OUT_MASK |
1087                                   CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK);
1088         disableMsgType(CAMERA_MSG_PREVIEW_FRAME);
1089     }
1090 
1091     if (c != 0) {
1092         // Is the received frame copied out or not?
1093         if (flags & CAMERA_FRAME_CALLBACK_FLAG_COPY_OUT_MASK) {
1094             LOG2("frame is copied");
1095             copyFrameAndPostCopiedFrame(msgType, c, heap, offset, size, metadata);
1096         } else {
1097             LOG2("frame is forwarded");
1098             mLock.unlock();
1099             c->dataCallback(msgType, mem, metadata);
1100         }
1101     } else {
1102         mLock.unlock();
1103     }
1104 }
1105 
1106 // picture callback - postview image ready
handlePostview(const sp<IMemory> & mem)1107 void CameraService::Client::handlePostview(const sp<IMemory>& mem) {
1108     disableMsgType(CAMERA_MSG_POSTVIEW_FRAME);
1109 
1110     sp<ICameraClient> c = mCameraClient;
1111     mLock.unlock();
1112     if (c != 0) {
1113         c->dataCallback(CAMERA_MSG_POSTVIEW_FRAME, mem, NULL);
1114     }
1115 }
1116 
1117 // picture callback - raw image ready
handleRawPicture(const sp<IMemory> & mem)1118 void CameraService::Client::handleRawPicture(const sp<IMemory>& mem) {
1119     disableMsgType(CAMERA_MSG_RAW_IMAGE);
1120 
1121     ssize_t offset;
1122     size_t size;
1123     sp<IMemoryHeap> heap = mem->getMemory(&offset, &size);
1124 
1125     sp<ICameraClient> c = mCameraClient;
1126     mLock.unlock();
1127     if (c != 0) {
1128         c->dataCallback(CAMERA_MSG_RAW_IMAGE, mem, NULL);
1129     }
1130 }
1131 
1132 // picture callback - compressed picture ready
handleCompressedPicture(const sp<IMemory> & mem)1133 void CameraService::Client::handleCompressedPicture(const sp<IMemory>& mem) {
1134     disableMsgType(CAMERA_MSG_COMPRESSED_IMAGE);
1135 
1136     sp<ICameraClient> c = mCameraClient;
1137     mLock.unlock();
1138     if (c != 0) {
1139         c->dataCallback(CAMERA_MSG_COMPRESSED_IMAGE, mem, NULL);
1140     }
1141 }
1142 
1143 
handleGenericNotify(int32_t msgType,int32_t ext1,int32_t ext2)1144 void CameraService::Client::handleGenericNotify(int32_t msgType,
1145     int32_t ext1, int32_t ext2) {
1146     sp<ICameraClient> c = mCameraClient;
1147     mLock.unlock();
1148     if (c != 0) {
1149         c->notifyCallback(msgType, ext1, ext2);
1150     }
1151 }
1152 
handleGenericData(int32_t msgType,const sp<IMemory> & dataPtr,camera_frame_metadata_t * metadata)1153 void CameraService::Client::handleGenericData(int32_t msgType,
1154     const sp<IMemory>& dataPtr, camera_frame_metadata_t *metadata) {
1155     sp<ICameraClient> c = mCameraClient;
1156     mLock.unlock();
1157     if (c != 0) {
1158         c->dataCallback(msgType, dataPtr, metadata);
1159     }
1160 }
1161 
handleGenericDataTimestamp(nsecs_t timestamp,int32_t msgType,const sp<IMemory> & dataPtr)1162 void CameraService::Client::handleGenericDataTimestamp(nsecs_t timestamp,
1163     int32_t msgType, const sp<IMemory>& dataPtr) {
1164     sp<ICameraClient> c = mCameraClient;
1165     mLock.unlock();
1166     if (c != 0) {
1167         c->dataCallbackTimestamp(timestamp, msgType, dataPtr);
1168     }
1169 }
1170 
copyFrameAndPostCopiedFrame(int32_t msgType,const sp<ICameraClient> & client,const sp<IMemoryHeap> & heap,size_t offset,size_t size,camera_frame_metadata_t * metadata)1171 void CameraService::Client::copyFrameAndPostCopiedFrame(
1172         int32_t msgType, const sp<ICameraClient>& client,
1173         const sp<IMemoryHeap>& heap, size_t offset, size_t size,
1174         camera_frame_metadata_t *metadata) {
1175     LOG2("copyFrameAndPostCopiedFrame");
1176     // It is necessary to copy out of pmem before sending this to
1177     // the callback. For efficiency, reuse the same MemoryHeapBase
1178     // provided it's big enough. Don't allocate the memory or
1179     // perform the copy if there's no callback.
1180     // hold the preview lock while we grab a reference to the preview buffer
1181     sp<MemoryHeapBase> previewBuffer;
1182 
1183     if (mPreviewBuffer == 0) {
1184         mPreviewBuffer = new MemoryHeapBase(size, 0, NULL);
1185     } else if (size > mPreviewBuffer->virtualSize()) {
1186         mPreviewBuffer.clear();
1187         mPreviewBuffer = new MemoryHeapBase(size, 0, NULL);
1188     }
1189     if (mPreviewBuffer == 0) {
1190         LOGE("failed to allocate space for preview buffer");
1191         mLock.unlock();
1192         return;
1193     }
1194     previewBuffer = mPreviewBuffer;
1195 
1196     memcpy(previewBuffer->base(), (uint8_t *)heap->base() + offset, size);
1197 
1198     sp<MemoryBase> frame = new MemoryBase(previewBuffer, 0, size);
1199     if (frame == 0) {
1200         LOGE("failed to allocate space for frame callback");
1201         mLock.unlock();
1202         return;
1203     }
1204 
1205     mLock.unlock();
1206     client->dataCallback(msgType, frame, metadata);
1207 }
1208 
getOrientation(int degrees,bool mirror)1209 int CameraService::Client::getOrientation(int degrees, bool mirror) {
1210     if (!mirror) {
1211         if (degrees == 0) return 0;
1212         else if (degrees == 90) return HAL_TRANSFORM_ROT_90;
1213         else if (degrees == 180) return HAL_TRANSFORM_ROT_180;
1214         else if (degrees == 270) return HAL_TRANSFORM_ROT_270;
1215     } else {  // Do mirror (horizontal flip)
1216         if (degrees == 0) {           // FLIP_H and ROT_0
1217             return HAL_TRANSFORM_FLIP_H;
1218         } else if (degrees == 90) {   // FLIP_H and ROT_90
1219             return HAL_TRANSFORM_FLIP_H | HAL_TRANSFORM_ROT_90;
1220         } else if (degrees == 180) {  // FLIP_H and ROT_180
1221             return HAL_TRANSFORM_FLIP_V;
1222         } else if (degrees == 270) {  // FLIP_H and ROT_270
1223             return HAL_TRANSFORM_FLIP_V | HAL_TRANSFORM_ROT_90;
1224         }
1225     }
1226     LOGE("Invalid setDisplayOrientation degrees=%d", degrees);
1227     return -1;
1228 }
1229 
1230 
1231 // ----------------------------------------------------------------------------
1232 
1233 static const int kDumpLockRetries = 50;
1234 static const int kDumpLockSleep = 60000;
1235 
tryLock(Mutex & mutex)1236 static bool tryLock(Mutex& mutex)
1237 {
1238     bool locked = false;
1239     for (int i = 0; i < kDumpLockRetries; ++i) {
1240         if (mutex.tryLock() == NO_ERROR) {
1241             locked = true;
1242             break;
1243         }
1244         usleep(kDumpLockSleep);
1245     }
1246     return locked;
1247 }
1248 
dump(int fd,const Vector<String16> & args)1249 status_t CameraService::dump(int fd, const Vector<String16>& args) {
1250     static const char* kDeadlockedString = "CameraService may be deadlocked\n";
1251 
1252     const size_t SIZE = 256;
1253     char buffer[SIZE];
1254     String8 result;
1255     if (checkCallingPermission(String16("android.permission.DUMP")) == false) {
1256         snprintf(buffer, SIZE, "Permission Denial: "
1257                 "can't dump CameraService from pid=%d, uid=%d\n",
1258                 getCallingPid(),
1259                 getCallingUid());
1260         result.append(buffer);
1261         write(fd, result.string(), result.size());
1262     } else {
1263         bool locked = tryLock(mServiceLock);
1264         // failed to lock - CameraService is probably deadlocked
1265         if (!locked) {
1266             String8 result(kDeadlockedString);
1267             write(fd, result.string(), result.size());
1268         }
1269 
1270         bool hasClient = false;
1271         for (int i = 0; i < mNumberOfCameras; i++) {
1272             sp<Client> client = mClient[i].promote();
1273             if (client == 0) continue;
1274             hasClient = true;
1275             sprintf(buffer, "Client[%d] (%p) PID: %d\n",
1276                     i,
1277                     client->getCameraClient()->asBinder().get(),
1278                     client->mClientPid);
1279             result.append(buffer);
1280             write(fd, result.string(), result.size());
1281             client->mHardware->dump(fd, args);
1282         }
1283         if (!hasClient) {
1284             result.append("No camera client yet.\n");
1285             write(fd, result.string(), result.size());
1286         }
1287 
1288         if (locked) mServiceLock.unlock();
1289 
1290         // change logging level
1291         int n = args.size();
1292         for (int i = 0; i + 1 < n; i++) {
1293             if (args[i] == String16("-v")) {
1294                 String8 levelStr(args[i+1]);
1295                 int level = atoi(levelStr.string());
1296                 sprintf(buffer, "Set Log Level to %d", level);
1297                 result.append(buffer);
1298                 setLogLevel(level);
1299             }
1300         }
1301     }
1302     return NO_ERROR;
1303 }
1304 
1305 }; // namespace android
1306