diff options
10 files changed, 109 insertions, 11 deletions
diff --git a/camera/ICameraServiceProxy.cpp b/camera/ICameraServiceProxy.cpp index 06a5afb..694e9c3 100644 --- a/camera/ICameraServiceProxy.cpp +++ b/camera/ICameraServiceProxy.cpp @@ -29,11 +29,21 @@ public: BpCameraServiceProxy(const sp<IBinder>& impl) : BpInterface<ICameraServiceProxy>(impl) {} virtual void pingForUserUpdate() { - Parcel data, reply; + Parcel data; data.writeInterfaceToken(ICameraServiceProxy::getInterfaceDescriptor()); - remote()->transact(BnCameraServiceProxy::PING_FOR_USER_UPDATE, data, &reply, + remote()->transact(BnCameraServiceProxy::PING_FOR_USER_UPDATE, data, nullptr, IBinder::FLAG_ONEWAY); } + + virtual void notifyCameraState(String16 cameraId, CameraState newCameraState) { + Parcel data; + data.writeInterfaceToken(ICameraServiceProxy::getInterfaceDescriptor()); + data.writeString16(cameraId); + data.writeInt32(newCameraState); + remote()->transact(BnCameraServiceProxy::NOTIFY_CAMERA_STATE, data, nullptr, + IBinder::FLAG_ONEWAY); + } + }; @@ -47,9 +57,16 @@ status_t BnCameraServiceProxy::onTransact(uint32_t code, const Parcel& data, Par pingForUserUpdate(); return NO_ERROR; } break; + case NOTIFY_CAMERA_STATE: { + CHECK_INTERFACE(ICameraServiceProxy, data, reply); + String16 cameraId = data.readString16(); + CameraState newCameraState = + static_cast<CameraState>(data.readInt32()); + notifyCameraState(cameraId, newCameraState); + return NO_ERROR; + } break; default: return BBinder::onTransact(code, data, reply, flags); } } }; // namespace android - diff --git a/include/camera/ICameraServiceProxy.h b/include/camera/ICameraServiceProxy.h index 12a555f..2613c01 100644 --- a/include/camera/ICameraServiceProxy.h +++ b/include/camera/ICameraServiceProxy.h @@ -23,15 +23,30 @@ namespace android { +/** + * Interface from native camera service to managed-side camera service proxy. + * + * Keep in sync with frameworks/base/core/java/android/hardware/ICameraServiceProxy.aidl + * + */ class ICameraServiceProxy : public IInterface { public: enum { PING_FOR_USER_UPDATE = IBinder::FIRST_CALL_TRANSACTION, + NOTIFY_CAMERA_STATE + }; + + enum CameraState { + CAMERA_STATE_OPEN, + CAMERA_STATE_ACTIVE, + CAMERA_STATE_IDLE, + CAMERA_STATE_CLOSED }; DECLARE_META_INTERFACE(CameraServiceProxy); virtual void pingForUserUpdate() = 0; + virtual void notifyCameraState(String16 cameraId, CameraState newCameraState) = 0; }; class BnCameraServiceProxy: public BnInterface<ICameraServiceProxy> @@ -48,5 +63,3 @@ public: }; // namespace android #endif // ANDROID_HARDWARE_ICAMERASERVICEPROXY_H - - diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp index 43a8ec4..7128df7 100644 --- a/services/camera/libcameraservice/CameraService.cpp +++ b/services/camera/libcameraservice/CameraService.cpp @@ -33,7 +33,6 @@ #include <binder/MemoryBase.h> #include <binder/MemoryHeapBase.h> #include <binder/ProcessInfoService.h> -#include <camera/ICameraServiceProxy.h> #include <cutils/atomic.h> #include <cutils/properties.h> #include <gui/Surface.h> @@ -250,13 +249,19 @@ void CameraService::onFirstRef() CameraService::pingCameraServiceProxy(); } -void CameraService::pingCameraServiceProxy() { +sp<ICameraServiceProxy> CameraService::getCameraServiceProxy() { sp<IServiceManager> sm = defaultServiceManager(); sp<IBinder> binder = sm->getService(String16("media.camera.proxy")); if (binder == nullptr) { - return; + return nullptr; } sp<ICameraServiceProxy> proxyBinder = interface_cast<ICameraServiceProxy>(binder); + return proxyBinder; +} + +void CameraService::pingCameraServiceProxy() { + sp<ICameraServiceProxy> proxyBinder = getCameraServiceProxy(); + if (proxyBinder == nullptr) return; proxyBinder->pingForUserUpdate(); } @@ -1948,6 +1953,10 @@ status_t CameraService::BasicClient::startCameraOps() { mCameraService->updateStatus(ICameraServiceListener::STATUS_NOT_AVAILABLE, String8::format("%d", mCameraId)); + // Transition device state to OPEN + mCameraService->updateProxyDeviceState(ICameraServiceProxy::CAMERA_STATE_OPEN, + String8::format("%d", mCameraId)); + return OK; } @@ -1966,6 +1975,10 @@ status_t CameraService::BasicClient::finishCameraOps() { mCameraService->updateStatus(ICameraServiceListener::STATUS_PRESENT, String8::format("%d", mCameraId), rejected); + // Transition device state to CLOSED + mCameraService->updateProxyDeviceState(ICameraServiceProxy::CAMERA_STATE_CLOSED, + String8::format("%d", mCameraId)); + // Notify flashlight that a camera device is closed. mCameraService->mFlashlight->deviceClosed( String8::format("%d", mCameraId)); @@ -2466,6 +2479,14 @@ void CameraService::updateStatus(ICameraServiceListener::Status status, const St }); } +void CameraService::updateProxyDeviceState(ICameraServiceProxy::CameraState newState, + const String8& cameraId) { + sp<ICameraServiceProxy> proxyBinder = getCameraServiceProxy(); + if (proxyBinder == nullptr) return; + String16 id(cameraId); + proxyBinder->notifyCameraState(id, newState); +} + status_t CameraService::getTorchStatusLocked( const String8& cameraId, ICameraServiceListener::TorchStatus *status) const { diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h index 7f4d43f..894767a 100644 --- a/services/camera/libcameraservice/CameraService.h +++ b/services/camera/libcameraservice/CameraService.h @@ -24,6 +24,7 @@ #include <binder/BinderService.h> #include <binder/IAppOpsCallback.h> #include <camera/ICameraService.h> +#include <camera/ICameraServiceProxy.h> #include <hardware/camera.h> #include <camera/ICamera.h> @@ -164,6 +165,14 @@ public: void playSound(sound_kind kind); void releaseSound(); + /** + * Update the state of a given camera device (open/close/active/idle) with + * the camera proxy service in the system service + */ + static void updateProxyDeviceState( + ICameraServiceProxy::CameraState newState, + const String8& cameraId); + ///////////////////////////////////////////////////////////////////// // CameraDeviceFactory functionality int getDeviceVersion(int cameraId, int* facing = NULL); @@ -728,6 +737,7 @@ private: static String8 toString(std::set<userid_t> intSet); + static sp<ICameraServiceProxy> getCameraServiceProxy(); static void pingCameraServiceProxy(); }; diff --git a/services/camera/libcameraservice/api1/Camera2Client.cpp b/services/camera/libcameraservice/api1/Camera2Client.cpp index 36e99dd..48b5a26 100644 --- a/services/camera/libcameraservice/api1/Camera2Client.cpp +++ b/services/camera/libcameraservice/api1/Camera2Client.cpp @@ -1912,6 +1912,8 @@ void Camera2Client::notifyShutter(const CaptureResultExtras& resultExtras, ALOGV("%s: Shutter notification for request id %" PRId32 " at time %" PRId64, __FUNCTION__, resultExtras.requestId, timestamp); mCaptureSequencer->notifyShutter(resultExtras, timestamp); + + Camera2ClientBase::notifyShutter(resultExtras, timestamp); } camera2::SharedParameters& Camera2Client::getParameters() { diff --git a/services/camera/libcameraservice/api1/CameraClient.cpp b/services/camera/libcameraservice/api1/CameraClient.cpp index e552633..38e35cd 100644 --- a/services/camera/libcameraservice/api1/CameraClient.cpp +++ b/services/camera/libcameraservice/api1/CameraClient.cpp @@ -251,6 +251,9 @@ void CameraClient::disconnect() { // Turn off all messages. disableMsgType(CAMERA_MSG_ALL_MSGS); mHardware->stopPreview(); + mCameraService->updateProxyDeviceState( + ICameraServiceProxy::CAMERA_STATE_IDLE, + String8::format("%d", mCameraId)); mHardware->cancelPicture(); // Release the hardware resources. mHardware->release(); @@ -409,7 +412,11 @@ status_t CameraClient::startPreviewMode() { } mHardware->setPreviewWindow(mPreviewWindow); result = mHardware->startPreview(); - + if (result == NO_ERROR) { + mCameraService->updateProxyDeviceState( + ICameraServiceProxy::CAMERA_STATE_ACTIVE, + String8::format("%d", mCameraId)); + } return result; } @@ -449,7 +456,9 @@ void CameraClient::stopPreview() { disableMsgType(CAMERA_MSG_PREVIEW_FRAME); mHardware->stopPreview(); - + mCameraService->updateProxyDeviceState( + ICameraServiceProxy::CAMERA_STATE_IDLE, + String8::format("%d", mCameraId)); mPreviewBuffer.clear(); } @@ -790,6 +799,12 @@ void CameraClient::handleShutter(void) { } disableMsgType(CAMERA_MSG_SHUTTER); + // Shutters only happen in response to takePicture, so mark device as + // idle now, until preview is restarted + mCameraService->updateProxyDeviceState( + ICameraServiceProxy::CAMERA_STATE_IDLE, + String8::format("%d", mCameraId)); + mLock.unlock(); } diff --git a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp index f6a0221..0c531c3 100644 --- a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp +++ b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp @@ -836,6 +836,7 @@ void CameraDeviceClient::notifyIdle() { if (remoteCb != 0) { remoteCb->onDeviceIdle(); } + Camera2ClientBase::notifyIdle(); } void CameraDeviceClient::notifyShutter(const CaptureResultExtras& resultExtras, @@ -845,6 +846,7 @@ void CameraDeviceClient::notifyShutter(const CaptureResultExtras& resultExtras, if (remoteCb != 0) { remoteCb->onCaptureStarted(resultExtras, timestamp); } + Camera2ClientBase::notifyShutter(resultExtras, timestamp); } void CameraDeviceClient::notifyPrepared(int streamId) { diff --git a/services/camera/libcameraservice/api2/CameraDeviceClient.h b/services/camera/libcameraservice/api2/CameraDeviceClient.h index 0b73f6c..d1e692c 100644 --- a/services/camera/libcameraservice/api2/CameraDeviceClient.h +++ b/services/camera/libcameraservice/api2/CameraDeviceClient.h @@ -192,6 +192,7 @@ private: Vector<int> mStreamingRequestList; int32_t mRequestIdCounter; + }; }; // namespace android diff --git a/services/camera/libcameraservice/common/Camera2ClientBase.cpp b/services/camera/libcameraservice/common/Camera2ClientBase.cpp index ba0b264..5732f80 100644 --- a/services/camera/libcameraservice/common/Camera2ClientBase.cpp +++ b/services/camera/libcameraservice/common/Camera2ClientBase.cpp @@ -55,7 +55,8 @@ Camera2ClientBase<TClientBase>::Camera2ClientBase( TClientBase(cameraService, remoteCallback, clientPackageName, cameraId, cameraFacing, clientPid, clientUid, servicePid), mSharedCameraCallbacks(remoteCallback), - mDeviceVersion(cameraService->getDeviceVersion(cameraId)) + mDeviceVersion(cameraService->getDeviceVersion(cameraId)), + mDeviceActive(false) { ALOGI("Camera %d: Opened. Client: %s (PID %d, UID %d)", cameraId, String8(clientPackageName).string(), clientPid, clientUid); @@ -235,6 +236,13 @@ void Camera2ClientBase<TClientBase>::notifyError( template <typename TClientBase> void Camera2ClientBase<TClientBase>::notifyIdle() { + if (mDeviceActive) { + getCameraService()->updateProxyDeviceState( + ICameraServiceProxy::CAMERA_STATE_IDLE, + String8::format("%d", TClientBase::mCameraId)); + } + mDeviceActive = false; + ALOGV("Camera device is now idle"); } @@ -244,6 +252,13 @@ void Camera2ClientBase<TClientBase>::notifyShutter(const CaptureResultExtras& re (void)resultExtras; (void)timestamp; + if (!mDeviceActive) { + getCameraService()->updateProxyDeviceState( + ICameraServiceProxy::CAMERA_STATE_ACTIVE, + String8::format("%d", TClientBase::mCameraId)); + } + mDeviceActive = true; + ALOGV("%s: Shutter notification for request id %" PRId32 " at time %" PRId64, __FUNCTION__, resultExtras.requestId, timestamp); } diff --git a/services/camera/libcameraservice/common/Camera2ClientBase.h b/services/camera/libcameraservice/common/Camera2ClientBase.h index f1cacdf..220c5ad 100644 --- a/services/camera/libcameraservice/common/Camera2ClientBase.h +++ b/services/camera/libcameraservice/common/Camera2ClientBase.h @@ -136,6 +136,8 @@ protected: status_t checkPid(const char *checkLocation) const; virtual void detachDevice(); + + bool mDeviceActive; }; }; // namespace android |