diff options
Diffstat (limited to 'services')
-rw-r--r-- | services/audioflinger/AudioFlinger.cpp | 25 | ||||
-rw-r--r-- | services/audioflinger/AudioFlinger.h | 3 | ||||
-rw-r--r-- | services/audioflinger/Threads.cpp | 89 | ||||
-rw-r--r-- | services/audioflinger/Threads.h | 28 | ||||
-rw-r--r-- | services/camera/libcameraservice/CameraService.cpp | 136 | ||||
-rw-r--r-- | services/camera/libcameraservice/CameraService.h | 31 | ||||
-rw-r--r-- | services/camera/libcameraservice/common/Camera2ClientBase.cpp | 2 |
7 files changed, 185 insertions, 129 deletions
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp index 3c14e1f..485e320 100644 --- a/services/audioflinger/AudioFlinger.cpp +++ b/services/audioflinger/AudioFlinger.cpp @@ -1268,11 +1268,11 @@ void AudioFlinger::registerClient(const sp<IAudioFlingerClient>& client) // the config change is always sent from playback or record threads to avoid deadlock // with AudioSystem::gLock for (size_t i = 0; i < mPlaybackThreads.size(); i++) { - mPlaybackThreads.valueAt(i)->sendIoConfigEvent(AudioSystem::OUTPUT_OPENED); + mPlaybackThreads.valueAt(i)->sendIoConfigEvent(AUDIO_OUTPUT_OPENED); } for (size_t i = 0; i < mRecordThreads.size(); i++) { - mRecordThreads.valueAt(i)->sendIoConfigEvent(AudioSystem::INPUT_OPENED); + mRecordThreads.valueAt(i)->sendIoConfigEvent(AUDIO_INPUT_OPENED); } } } @@ -1306,14 +1306,13 @@ void AudioFlinger::removeNotificationClient(pid_t pid) } } -void AudioFlinger::audioConfigChanged(int event, audio_io_handle_t ioHandle, const void *param2) +void AudioFlinger::ioConfigChanged(audio_io_config_event event, + const sp<AudioIoDescriptor>& ioDesc) { Mutex::Autolock _l(mClientLock); size_t size = mNotificationClients.size(); for (size_t i = 0; i < size; i++) { - mNotificationClients.valueAt(i)->audioFlingerClient()->ioConfigChanged(event, - ioHandle, - param2); + mNotificationClients.valueAt(i)->audioFlingerClient()->ioConfigChanged(event, ioDesc); } } @@ -1832,7 +1831,7 @@ status_t AudioFlinger::openOutput(audio_module_handle_t module, *latencyMs = thread->latency(); // notify client processes of the new output creation - thread->audioConfigChanged(AudioSystem::OUTPUT_OPENED); + thread->ioConfigChanged(AUDIO_OUTPUT_OPENED); // the first primary output opened designates the primary hw device if ((mPrimaryHardwareDev == NULL) && (flags & AUDIO_OUTPUT_FLAG_PRIMARY)) { @@ -1870,7 +1869,7 @@ audio_io_handle_t AudioFlinger::openDuplicateOutput(audio_io_handle_t output1, thread->addOutputTrack(thread2); mPlaybackThreads.add(id, thread); // notify client processes of the new output creation - thread->audioConfigChanged(AudioSystem::OUTPUT_OPENED); + thread->ioConfigChanged(AUDIO_OUTPUT_OPENED); return id; } @@ -1920,7 +1919,9 @@ status_t AudioFlinger::closeOutput_nonvirtual(audio_io_handle_t output) } } } - audioConfigChanged(AudioSystem::OUTPUT_CLOSED, output, NULL); + const sp<AudioIoDescriptor> ioDesc = new AudioIoDescriptor(); + ioDesc->mIoHandle = output; + ioConfigChanged(AUDIO_OUTPUT_CLOSED, ioDesc); } thread->exit(); // The thread entity (active unit of execution) is no longer running here, @@ -1998,7 +1999,7 @@ status_t AudioFlinger::openInput(audio_module_handle_t module, if (thread != 0) { // notify client processes of the new input creation - thread->audioConfigChanged(AudioSystem::INPUT_OPENED); + thread->ioConfigChanged(AUDIO_INPUT_OPENED); return NO_ERROR; } return NO_INIT; @@ -2181,7 +2182,9 @@ status_t AudioFlinger::closeInput_nonvirtual(audio_io_handle_t input) putOrphanEffectChain_l(chain); } } - audioConfigChanged(AudioSystem::INPUT_CLOSED, input, NULL); + const sp<AudioIoDescriptor> ioDesc = new AudioIoDescriptor(); + ioDesc->mIoHandle = input; + ioConfigChanged(AUDIO_INPUT_CLOSED, ioDesc); mRecordThreads.removeItem(input); } // FIXME: calling thread->exit() without mLock held should not be needed anymore now that diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h index 72db62b..51b2610 100644 --- a/services/audioflinger/AudioFlinger.h +++ b/services/audioflinger/AudioFlinger.h @@ -546,7 +546,8 @@ private: // no range check, doesn't check per-thread stream volume, AudioFlinger::mLock held float streamVolume_l(audio_stream_type_t stream) const { return mStreamTypes[stream].volume; } - void audioConfigChanged(int event, audio_io_handle_t ioHandle, const void *param2); + void ioConfigChanged(audio_io_config_event event, + const sp<AudioIoDescriptor>& ioDesc); // Allocate an audio_io_handle_t, session ID, effect ID, or audio_module_handle_t. // They all share the same ID space, but the namespaces are actually independent diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp index 234e45f..8b8dd78 100644 --- a/services/audioflinger/Threads.cpp +++ b/services/audioflinger/Threads.cpp @@ -584,16 +584,16 @@ status_t AudioFlinger::ThreadBase::sendConfigEvent_l(sp<ConfigEvent>& event) return status; } -void AudioFlinger::ThreadBase::sendIoConfigEvent(int event, int param) +void AudioFlinger::ThreadBase::sendIoConfigEvent(audio_io_config_event event) { Mutex::Autolock _l(mLock); - sendIoConfigEvent_l(event, param); + sendIoConfigEvent_l(event); } // sendIoConfigEvent_l() must be called with ThreadBase::mLock held -void AudioFlinger::ThreadBase::sendIoConfigEvent_l(int event, int param) +void AudioFlinger::ThreadBase::sendIoConfigEvent_l(audio_io_config_event event) { - sp<ConfigEvent> configEvent = (ConfigEvent *)new IoConfigEvent(event, param); + sp<ConfigEvent> configEvent = (ConfigEvent *)new IoConfigEvent(event); sendConfigEvent_l(configEvent); } @@ -657,7 +657,7 @@ void AudioFlinger::ThreadBase::processConfigEvents_l() } break; case CFG_EVENT_IO: { IoConfigEventData *data = (IoConfigEventData *)event->mData.get(); - audioConfigChanged(data->mEvent, data->mParam); + ioConfigChanged(data->mEvent); } break; case CFG_EVENT_SET_PARAMETER: { SetParameterConfigEventData *data = (SetParameterConfigEventData *)event->mData.get(); @@ -1921,32 +1921,28 @@ String8 AudioFlinger::PlaybackThread::getParameters(const String8& keys) return out_s8; } -void AudioFlinger::PlaybackThread::audioConfigChanged(int event, int param) { - AudioSystem::OutputDescriptor desc; - void *param2 = NULL; +void AudioFlinger::PlaybackThread::ioConfigChanged(audio_io_config_event event) { + sp<AudioIoDescriptor> desc = new AudioIoDescriptor(); + ALOGV("PlaybackThread::ioConfigChanged, thread %p, event %d", this, event); - ALOGV("PlaybackThread::audioConfigChanged, thread %p, event %d, param %d", this, event, - param); + desc->mIoHandle = mId; switch (event) { - case AudioSystem::OUTPUT_OPENED: - case AudioSystem::OUTPUT_CONFIG_CHANGED: - desc.channelMask = mChannelMask; - desc.samplingRate = mSampleRate; - desc.format = mFormat; - desc.frameCount = mNormalFrameCount; // FIXME see + case AUDIO_OUTPUT_OPENED: + case AUDIO_OUTPUT_CONFIG_CHANGED: + desc->mChannelMask = mChannelMask; + desc->mSamplingRate = mSampleRate; + desc->mFormat = mFormat; + desc->mFrameCount = mNormalFrameCount; // FIXME see // AudioFlinger::frameCount(audio_io_handle_t) - desc.latency = latency_l(); - param2 = &desc; + desc->mLatency = latency_l(); break; - case AudioSystem::STREAM_CONFIG_CHANGED: - param2 = ¶m; - case AudioSystem::OUTPUT_CLOSED: + case AUDIO_OUTPUT_CLOSED: default: break; } - mAudioFlinger->audioConfigChanged(event, mId, param2); + mAudioFlinger->ioConfigChanged(event, desc); } void AudioFlinger::PlaybackThread::writeCallback() @@ -2055,6 +2051,9 @@ void AudioFlinger::PlaybackThread::readOutputParameters_l() ALOGW("direct output implements resume but not pause"); } } + if (!mHwSupportsPause && mOutput->flags & AUDIO_OUTPUT_FLAG_HW_AV_SYNC) { + LOG_ALWAYS_FATAL("HW_AV_SYNC requested but HAL does not implement pause and resume"); + } if (mType == DUPLICATING && mMixerBufferEnabled && mEffectBufferEnabled) { // For best precision, we use float instead of the associated output @@ -4203,7 +4202,7 @@ bool AudioFlinger::MixerThread::checkForNewParameter_l(const String8& keyValuePa } mTracks[i]->mName = name; } - sendIoConfigEvent_l(AudioSystem::OUTPUT_CONFIG_CHANGED); + sendIoConfigEvent_l(AUDIO_OUTPUT_CONFIG_CHANGED); } } @@ -4375,9 +4374,9 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::DirectOutputThread::prep sp<Track> l = mLatestActiveTrack.promote(); bool last = l.get() == track; - if (mHwSupportsPause && track->isPausing()) { + if (track->isPausing()) { track->setPaused(); - if (last && !mHwPaused) { + if (mHwSupportsPause && last && !mHwPaused) { doHwPause = true; mHwPaused = true; } @@ -4387,13 +4386,11 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::DirectOutputThread::prep if (last) { flushPending = true; } - } else if (mHwSupportsPause && track->isResumePending()){ + } else if (track->isResumePending()) { track->resumeAck(); - if (last) { - if (mHwPaused) { - doHwResume = true; - mHwPaused = false; - } + if (last && mHwPaused) { + doHwResume = true; + mHwPaused = false; } } @@ -4655,7 +4652,7 @@ bool AudioFlinger::DirectOutputThread::checkForNewParameter_l(const String8& key } if (status == NO_ERROR && reconfig) { readOutputParameters_l(); - sendIoConfigEvent_l(AudioSystem::OUTPUT_CONFIG_CHANGED); + sendIoConfigEvent_l(AUDIO_OUTPUT_CONFIG_CHANGED); } } @@ -6701,7 +6698,7 @@ bool AudioFlinger::RecordThread::checkForNewParameter_l(const String8& keyValueP } if (status == NO_ERROR) { readInputParameters_l(); - sendIoConfigEvent_l(AudioSystem::INPUT_CONFIG_CHANGED); + sendIoConfigEvent_l(AUDIO_INPUT_CONFIG_CHANGED); } } } @@ -6722,26 +6719,26 @@ String8 AudioFlinger::RecordThread::getParameters(const String8& keys) return out_s8; } -void AudioFlinger::RecordThread::audioConfigChanged(int event, int param __unused) { - AudioSystem::OutputDescriptor desc; - const void *param2 = NULL; +void AudioFlinger::RecordThread::ioConfigChanged(audio_io_config_event event) { + sp<AudioIoDescriptor> desc = new AudioIoDescriptor(); + + desc->mIoHandle = mId; switch (event) { - case AudioSystem::INPUT_OPENED: - case AudioSystem::INPUT_CONFIG_CHANGED: - desc.channelMask = mChannelMask; - desc.samplingRate = mSampleRate; - desc.format = mFormat; - desc.frameCount = mFrameCount; - desc.latency = 0; - param2 = &desc; + case AUDIO_INPUT_OPENED: + case AUDIO_INPUT_CONFIG_CHANGED: + desc->mChannelMask = mChannelMask; + desc->mSamplingRate = mSampleRate; + desc->mFormat = mFormat; + desc->mFrameCount = mFrameCount; + desc->mLatency = 0; break; - case AudioSystem::INPUT_CLOSED: + case AUDIO_INPUT_CLOSED: default: break; } - mAudioFlinger->audioConfigChanged(event, mId, param2); + mAudioFlinger->ioConfigChanged(event, desc); } void AudioFlinger::RecordThread::readInputParameters_l() diff --git a/services/audioflinger/Threads.h b/services/audioflinger/Threads.h index 2c514f8..8167bd1 100644 --- a/services/audioflinger/Threads.h +++ b/services/audioflinger/Threads.h @@ -100,22 +100,21 @@ public: class IoConfigEventData : public ConfigEventData { public: - IoConfigEventData(int event, int param) : - mEvent(event), mParam(param) {} + IoConfigEventData(audio_io_config_event event) : + mEvent(event) {} virtual void dump(char *buffer, size_t size) { - snprintf(buffer, size, "IO event: event %d, param %d\n", mEvent, mParam); + snprintf(buffer, size, "IO event: event %d\n", mEvent); } - const int mEvent; - const int mParam; + const audio_io_config_event mEvent; }; class IoConfigEvent : public ConfigEvent { public: - IoConfigEvent(int event, int param) : + IoConfigEvent(audio_io_config_event event) : ConfigEvent(CFG_EVENT_IO) { - mData = new IoConfigEventData(event, param); + mData = new IoConfigEventData(event); } virtual ~IoConfigEvent() {} }; @@ -250,13 +249,13 @@ public: status_t& status) = 0; virtual status_t setParameters(const String8& keyValuePairs); virtual String8 getParameters(const String8& keys) = 0; - virtual void audioConfigChanged(int event, int param = 0) = 0; + virtual void ioConfigChanged(audio_io_config_event event) = 0; // sendConfigEvent_l() must be called with ThreadBase::mLock held // Can temporarily release the lock if waiting for a reply from // processConfigEvents_l(). status_t sendConfigEvent_l(sp<ConfigEvent>& event); - void sendIoConfigEvent(int event, int param = 0); - void sendIoConfigEvent_l(int event, int param = 0); + void sendIoConfigEvent(audio_io_config_event event); + void sendIoConfigEvent_l(audio_io_config_event event); void sendPrioConfigEvent_l(pid_t pid, pid_t tid, int32_t prio); status_t sendSetParameterConfigEvent_l(const String8& keyValuePair); status_t sendCreateAudioPatchConfigEvent(const struct audio_patch *patch, @@ -560,7 +559,7 @@ public: { return android_atomic_acquire_load(&mSuspended) > 0; } virtual String8 getParameters(const String8& keys); - virtual void audioConfigChanged(int event, int param = 0); + virtual void ioConfigChanged(audio_io_config_event event); status_t getRenderPosition(uint32_t *halFrames, uint32_t *dspFrames); // FIXME rename mixBuffer() to sinkBuffer() and remove int16_t* dependency. // Consider also removing and passing an explicit mMainBuffer initialization @@ -713,8 +712,9 @@ protected: audio_patch_handle_t *handle); virtual status_t releaseAudioPatch_l(const audio_patch_handle_t handle); - bool usesHwAvSync() const { return (mType == DIRECT) && (mOutput != NULL) && - (mOutput->flags & AUDIO_OUTPUT_FLAG_HW_AV_SYNC); } + bool usesHwAvSync() const { return (mType == DIRECT) && (mOutput != NULL) + && mHwSupportsPause + && (mOutput->flags & AUDIO_OUTPUT_FLAG_HW_AV_SYNC); } private: @@ -1230,7 +1230,7 @@ public: status_t& status); virtual void cacheParameters_l() {} virtual String8 getParameters(const String8& keys); - virtual void audioConfigChanged(int event, int param = 0); + virtual void ioConfigChanged(audio_io_config_event event); virtual status_t createAudioPatch_l(const struct audio_patch *patch, audio_patch_handle_t *handle); virtual status_t releaseAudioPatch_l(const audio_patch_handle_t handle); diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp index 8c5c43a..3f80faf 100644 --- a/services/camera/libcameraservice/CameraService.cpp +++ b/services/camera/libcameraservice/CameraService.cpp @@ -890,9 +890,12 @@ status_t CameraService::handleEvictionsLocked(const String8& cameraId, int clien if (current != nullptr) { auto clientSp = current->getValue(); if (clientSp.get() != nullptr) { // should never be needed - if (clientSp->getRemote() == remoteCallback) { + if (!clientSp->canCastToApiClient(effectiveApiLevel)) { + ALOGW("CameraService connect called from same client, but with a different" + " API level, evicting prior client..."); + } else if (clientSp->getRemote() == remoteCallback) { ALOGI("CameraService::connect X (PID %d) (second call from same" - "app binder, returning the same client)", clientPid); + " app binder, returning the same client)", clientPid); *client = clientSp; return NO_ERROR; } @@ -1054,19 +1057,24 @@ status_t CameraService::handleEvictionsLocked(const String8& cameraId, int clien status_t CameraService::connect( const sp<ICameraClient>& cameraClient, int cameraId, - const String16& clientPackageName, + const String16& opPackageName, int clientUid, /*out*/ sp<ICamera>& device) { + const status_t result = checkCameraAccess(opPackageName); + if (result != NO_ERROR) { + return result; + } + status_t ret = NO_ERROR; String8 id = String8::format("%d", cameraId); sp<Client> client = nullptr; ret = connectHelper<ICameraClient,Client>(cameraClient, id, CAMERA_HAL_API_VERSION_UNSPECIFIED, - clientPackageName, clientUid, API_1, false, false, /*out*/client); + opPackageName, clientUid, API_1, false, false, /*out*/client); if(ret != NO_ERROR) { - logRejected(id, getCallingPid(), String8(clientPackageName), + logRejected(id, getCallingPid(), String8(opPackageName), String8::format("%s (%d)", strerror(-ret), ret)); return ret; } @@ -1078,11 +1086,16 @@ status_t CameraService::connect( status_t CameraService::connectLegacy( const sp<ICameraClient>& cameraClient, int cameraId, int halVersion, - const String16& clientPackageName, + const String16& opPackageName, int clientUid, /*out*/ sp<ICamera>& device) { + const status_t result = checkCameraAccess(opPackageName); + if (result != NO_ERROR) { + return result; + } + String8 id = String8::format("%d", cameraId); int apiVersion = mModule->getModuleApiVersion(); if (halVersion != CAMERA_HAL_API_VERSION_UNSPECIFIED && @@ -1095,18 +1108,18 @@ status_t CameraService::connectLegacy( */ ALOGE("%s: camera HAL module version %x doesn't support connecting to legacy HAL devices!", __FUNCTION__, apiVersion); - logRejected(id, getCallingPid(), String8(clientPackageName), + logRejected(id, getCallingPid(), String8(opPackageName), String8("HAL module version doesn't support legacy HAL connections")); return INVALID_OPERATION; } status_t ret = NO_ERROR; sp<Client> client = nullptr; - ret = connectHelper<ICameraClient,Client>(cameraClient, id, halVersion, clientPackageName, + ret = connectHelper<ICameraClient,Client>(cameraClient, id, halVersion, opPackageName, clientUid, API_1, true, false, /*out*/client); if(ret != NO_ERROR) { - logRejected(id, getCallingPid(), String8(clientPackageName), + logRejected(id, getCallingPid(), String8(opPackageName), String8::format("%s (%d)", strerror(-ret), ret)); return ret; } @@ -1118,20 +1131,25 @@ status_t CameraService::connectLegacy( status_t CameraService::connectDevice( const sp<ICameraDeviceCallbacks>& cameraCb, int cameraId, - const String16& clientPackageName, + const String16& opPackageName, int clientUid, /*out*/ sp<ICameraDeviceUser>& device) { + const status_t result = checkCameraAccess(opPackageName); + if (result != NO_ERROR) { + return result; + } + status_t ret = NO_ERROR; String8 id = String8::format("%d", cameraId); sp<CameraDeviceClient> client = nullptr; ret = connectHelper<ICameraDeviceCallbacks,CameraDeviceClient>(cameraCb, id, - CAMERA_HAL_API_VERSION_UNSPECIFIED, clientPackageName, clientUid, API_2, false, false, + CAMERA_HAL_API_VERSION_UNSPECIFIED, opPackageName, clientUid, API_2, false, false, /*out*/client); if(ret != NO_ERROR) { - logRejected(id, getCallingPid(), String8(clientPackageName), + logRejected(id, getCallingPid(), String8(opPackageName), String8::format("%s (%d)", strerror(-ret), ret)); return ret; } @@ -1526,24 +1544,24 @@ void CameraService::logEvent(const char* event) { } void CameraService::logDisconnected(const char* cameraId, int clientPid, - const char* clientPackage) { + const char* opPackageName) { // Log the clients evicted logEvent(String8::format("DISCONNECT device %s client for package %s (PID %d)", cameraId, - clientPackage, clientPid)); + opPackageName, clientPid)); } void CameraService::logConnected(const char* cameraId, int clientPid, - const char* clientPackage) { + const char* opPackageName) { // Log the clients evicted logEvent(String8::format("CONNECT device %s client for package %s (PID %d)", cameraId, - clientPackage, clientPid)); + opPackageName, clientPid)); } void CameraService::logRejected(const char* cameraId, int clientPid, - const char* clientPackage, const char* reason) { + const char* opPackageName, const char* reason) { // Log the client rejected logEvent(String8::format("REJECT device %s client for package %s (PID %d), reason: (%s)", - cameraId, clientPackage, clientPid, reason)); + cameraId, opPackageName, clientPid, reason)); } void CameraService::logUserSwitch(int oldUserId, int newUserId) { @@ -1580,21 +1598,6 @@ status_t CameraService::onTransact(uint32_t code, const Parcel& data, Parcel* re // Permission checks switch (code) { - case BnCameraService::CONNECT: - case BnCameraService::CONNECT_DEVICE: - case BnCameraService::CONNECT_LEGACY: { - if (pid != selfPid) { - // we're called from a different process, do the real check - if (!checkCallingPermission( - String16("android.permission.CAMERA"))) { - const int uid = getCallingUid(); - ALOGE("Permission Denial: " - "can't use the camera pid=%d, uid=%d", pid, uid); - return PERMISSION_DENIED; - } - } - break; - } case BnCameraService::NOTIFY_SYSTEM_EVENT: { if (pid != selfPid) { // Ensure we're being called by system_server, or similar process with @@ -1614,6 +1617,38 @@ status_t CameraService::onTransact(uint32_t code, const Parcel& data, Parcel* re return BnCameraService::onTransact(code, data, reply, flags); } +status_t CameraService::checkCameraAccess(const String16& opPackageName) { + const int pid = getCallingPid(); + + if (pid == getpid()) { + return NO_ERROR; + } + + const int uid = getCallingUid(); + + if (!checkCallingPermission(String16("android.permission.CAMERA"))) { + ALOGE("Permission Denial: can't use the camera pid=%d, uid=%d", pid, uid); + return PERMISSION_DENIED; + } + + AppOpsManager appOps; + const int32_t result = appOps.noteOp(AppOpsManager::OP_CAMERA, uid, opPackageName); + + switch (result) { + case AppOpsManager::MODE_ERRORED: { + ALOGE("App op OP_CAMERA errored: can't use the camera pid=%d, uid=%d", pid, uid); + return PERMISSION_DENIED; + } break; + + case AppOpsManager::MODE_IGNORED: { + ALOGE("App op OP_CAMERA ignored: can't use the camera pid=%d, uid=%d", pid, uid); + return INVALID_OPERATION; + } break; + } + + return NO_ERROR; +} + // We share the media players for shutter and recording sound for all clients. // A reference count is kept to determine when we will actually release the // media players. @@ -1666,13 +1701,13 @@ void CameraService::playSound(sound_kind kind) { CameraService::Client::Client(const sp<CameraService>& cameraService, const sp<ICameraClient>& cameraClient, - const String16& clientPackageName, + const String16& opPackageName, int cameraId, int cameraFacing, int clientPid, uid_t clientUid, int servicePid) : CameraService::BasicClient(cameraService, IInterface::asBinder(cameraClient), - clientPackageName, + opPackageName, cameraId, cameraFacing, clientPid, clientUid, servicePid) @@ -1699,11 +1734,11 @@ CameraService::Client::~Client() { CameraService::BasicClient::BasicClient(const sp<CameraService>& cameraService, const sp<IBinder>& remoteCallback, - const String16& clientPackageName, + const String16& opPackageName, int cameraId, int cameraFacing, int clientPid, uid_t clientUid, int servicePid): - mClientPackageName(clientPackageName), mDisconnected(false) + mOpPackageName(opPackageName), mDisconnected(false) { mCameraService = cameraService; mRemoteBinder = remoteCallback; @@ -1731,7 +1766,7 @@ void CameraService::BasicClient::disconnect() { mCameraService->removeByClient(this); mCameraService->logDisconnected(String8::format("%d", mCameraId), mClientPid, - String8(mClientPackageName)); + String8(mOpPackageName)); sp<IBinder> remote = getRemote(); if (remote != nullptr) { @@ -1746,7 +1781,7 @@ void CameraService::BasicClient::disconnect() { } String16 CameraService::BasicClient::getPackageName() const { - return mClientPackageName; + return mOpPackageName; } @@ -1754,6 +1789,11 @@ int CameraService::BasicClient::getClientPid() const { return mClientPid; } +bool CameraService::BasicClient::canCastToApiClient(apiLevel level) const { + // Defaults to API2. + return level == API_2; +} + status_t CameraService::BasicClient::startCameraOps() { int32_t res; // Notify app ops that the camera is not available @@ -1761,17 +1801,17 @@ status_t CameraService::BasicClient::startCameraOps() { { ALOGV("%s: Start camera ops, package name = %s, client UID = %d", - __FUNCTION__, String8(mClientPackageName).string(), mClientUid); + __FUNCTION__, String8(mOpPackageName).string(), mClientUid); } mAppOpsManager.startWatchingMode(AppOpsManager::OP_CAMERA, - mClientPackageName, mOpsCallback); + mOpPackageName, mOpsCallback); res = mAppOpsManager.startOp(AppOpsManager::OP_CAMERA, - mClientUid, mClientPackageName); + mClientUid, mOpPackageName); if (res != AppOpsManager::MODE_ALLOWED) { ALOGI("Camera %d: Access for \"%s\" has been revoked", - mCameraId, String8(mClientPackageName).string()); + mCameraId, String8(mOpPackageName).string()); return PERMISSION_DENIED; } @@ -1789,7 +1829,7 @@ status_t CameraService::BasicClient::finishCameraOps() { if (mOpsActive) { // Notify app ops that the camera is available again mAppOpsManager.finishOp(AppOpsManager::OP_CAMERA, mClientUid, - mClientPackageName); + mOpPackageName); mOpsActive = false; auto rejected = {ICameraServiceListener::STATUS_NOT_PRESENT, @@ -1814,7 +1854,7 @@ status_t CameraService::BasicClient::finishCameraOps() { void CameraService::BasicClient::opChanged(int32_t op, const String16& packageName) { String8 name(packageName); - String8 myName(mClientPackageName); + String8 myName(mOpPackageName); if (op != AppOpsManager::OP_CAMERA) { ALOGW("Unexpected app ops notification received: %d", op); @@ -1823,7 +1863,7 @@ void CameraService::BasicClient::opChanged(int32_t op, const String16& packageNa int32_t res; res = mAppOpsManager.checkOp(AppOpsManager::OP_CAMERA, - mClientUid, mClientPackageName); + mClientUid, mOpPackageName); ALOGV("checkOp returns: %d, %s ", res, res == AppOpsManager::MODE_ALLOWED ? "ALLOWED" : res == AppOpsManager::MODE_IGNORED ? "IGNORED" : @@ -1866,6 +1906,10 @@ void CameraService::Client::disconnect() { BasicClient::disconnect(); } +bool CameraService::Client::canCastToApiClient(apiLevel level) const { + return level == API_1; +} + CameraService::Client::OpsCallback::OpsCallback(wp<BasicClient> client): mClient(client) { } diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h index 84e61c5..502fcfa 100644 --- a/services/camera/libcameraservice/CameraService.h +++ b/services/camera/libcameraservice/CameraService.h @@ -65,6 +65,7 @@ public: class Client; class BasicClient; + // The effective API level. The Camera2 API running in LEGACY mode counts as API_1. enum apiLevel { API_1 = 1, API_2 = 2 @@ -125,19 +126,19 @@ public: virtual status_t getCameraVendorTagDescriptor(/*out*/ sp<VendorTagDescriptor>& desc); virtual status_t connect(const sp<ICameraClient>& cameraClient, int cameraId, - const String16& clientPackageName, int clientUid, + const String16& opPackageName, int clientUid, /*out*/ sp<ICamera>& device); virtual status_t connectLegacy(const sp<ICameraClient>& cameraClient, int cameraId, - int halVersion, const String16& clientPackageName, int clientUid, + int halVersion, const String16& opPackageName, int clientUid, /*out*/ sp<ICamera>& device); virtual status_t connectDevice( const sp<ICameraDeviceCallbacks>& cameraCb, int cameraId, - const String16& clientPackageName, + const String16& opPackageName, int clientUid, /*out*/ sp<ICameraDeviceUser>& device); @@ -215,10 +216,14 @@ public: // Get the PID of the application client using this virtual int getClientPid() const; + + // Check what API level is used for this client. This is used to determine which + // superclass this can be cast to. + virtual bool canCastToApiClient(apiLevel level) const; protected: BasicClient(const sp<CameraService>& cameraService, const sp<IBinder>& remoteCallback, - const String16& clientPackageName, + const String16& opPackageName, int cameraId, int cameraFacing, int clientPid, @@ -237,7 +242,7 @@ public: sp<CameraService> mCameraService; // immutable after constructor int mCameraId; // immutable after constructor int mCameraFacing; // immutable after constructor - const String16 mClientPackageName; + const String16 mOpPackageName; pid_t mClientPid; uid_t mClientUid; // immutable after constructor pid_t mServicePid; // immutable after constructor @@ -304,7 +309,7 @@ public: // Interface used by CameraService Client(const sp<CameraService>& cameraService, const sp<ICameraClient>& cameraClient, - const String16& clientPackageName, + const String16& opPackageName, int cameraId, int cameraFacing, int clientPid, @@ -323,6 +328,10 @@ public: virtual void notifyError(ICameraDeviceCallbacks::CameraErrorCode errorCode, const CaptureResultExtras& resultExtras); + + // Check what API level is used for this client. This is used to determine which + // superclass this can be cast to. + virtual bool canCastToApiClient(apiLevel level) const; protected: // Convert client from cookie. static sp<CameraService::Client> getClientFromCookie(void* user); @@ -471,7 +480,7 @@ private: // Single implementation shared between the various connect calls template<class CALLBACK, class CLIENT> status_t connectHelper(const sp<CALLBACK>& cameraCb, const String8& cameraId, int halVersion, - const String16& clientPackageName, int clientUid, apiLevel effectiveApiLevel, + const String16& opPackageName, int clientUid, apiLevel effectiveApiLevel, bool legacyMode, bool shimUpdateOnly, /*out*/sp<CLIENT>& device); @@ -704,6 +713,8 @@ private: int facing, int clientPid, uid_t clientUid, int servicePid, bool legacyMode, int halVersion, int deviceVersion, apiLevel effectiveApiLevel, /*out*/sp<BasicClient>* client); + + status_t checkCameraAccess(const String16& opPackageName); }; template<class Func> @@ -752,11 +763,11 @@ void CameraService::CameraState::updateStatus(ICameraServiceListener::Status sta template<class CALLBACK, class CLIENT> status_t CameraService::connectHelper(const sp<CALLBACK>& cameraCb, const String8& cameraId, - int halVersion, const String16& clientPackageName, int clientUid, + int halVersion, const String16& opPackageName, int clientUid, apiLevel effectiveApiLevel, bool legacyMode, bool shimUpdateOnly, /*out*/sp<CLIENT>& device) { status_t ret = NO_ERROR; - String8 clientName8(clientPackageName); + String8 clientName8(opPackageName); int clientPid = getCallingPid(); ALOGI("CameraService::connect call (PID %d \"%s\", camera ID %s) for HAL version %s and " @@ -827,7 +838,7 @@ status_t CameraService::connectHelper(const sp<CALLBACK>& cameraCb, const String int facing = -1; int deviceVersion = getDeviceVersion(id, /*out*/&facing); sp<BasicClient> tmp = nullptr; - if((ret = makeClient(this, cameraCb, clientPackageName, cameraId, facing, clientPid, + if((ret = makeClient(this, cameraCb, opPackageName, cameraId, facing, clientPid, clientUid, getpid(), legacyMode, halVersion, deviceVersion, effectiveApiLevel, /*out*/&tmp)) != NO_ERROR) { return ret; diff --git a/services/camera/libcameraservice/common/Camera2ClientBase.cpp b/services/camera/libcameraservice/common/Camera2ClientBase.cpp index ba0b264..9b2e143 100644 --- a/services/camera/libcameraservice/common/Camera2ClientBase.cpp +++ b/services/camera/libcameraservice/common/Camera2ClientBase.cpp @@ -118,7 +118,7 @@ Camera2ClientBase<TClientBase>::~Camera2ClientBase() { ALOGI("Closed Camera %d. Client was: %s (PID %d, UID %u)", TClientBase::mCameraId, - String8(TClientBase::mClientPackageName).string(), + String8(TClientBase::mOpPackageName).string(), mInitialClientPid, TClientBase::mClientUid); } |