Merge "Add ability to test supported content types to MediaDrm" into klp-dev
diff --git a/camera/Camera.cpp b/camera/Camera.cpp
index fd78572..22199fa 100644
--- a/camera/Camera.cpp
+++ b/camera/Camera.cpp
@@ -39,6 +39,9 @@
{
}
+CameraTraits<Camera>::TCamConnectService CameraTraits<Camera>::fnConnectService =
+ &ICameraService::connect;
+
// construct a camera client from an existing camera remote
sp<Camera> Camera::create(const sp<ICamera>& camera)
{
@@ -97,13 +100,13 @@
}
// pass the buffered IGraphicBufferProducer to the camera service
-status_t Camera::setPreviewTexture(const sp<IGraphicBufferProducer>& bufferProducer)
+status_t Camera::setPreviewTarget(const sp<IGraphicBufferProducer>& bufferProducer)
{
- ALOGV("setPreviewTexture(%p)", bufferProducer.get());
+ ALOGV("setPreviewTarget(%p)", bufferProducer.get());
sp <ICamera> c = mCamera;
if (c == 0) return NO_INIT;
ALOGD_IF(bufferProducer == 0, "app passed NULL surface");
- return c->setPreviewTexture(bufferProducer);
+ return c->setPreviewTarget(bufferProducer);
}
// start preview mode
@@ -124,7 +127,7 @@
return c->storeMetaDataInBuffers(enabled);
}
-// start recording mode, must call setPreviewDisplay first
+// start recording mode, must call setPreviewTarget first
status_t Camera::startRecording()
{
ALOGV("startRecording");
diff --git a/camera/CameraBase.cpp b/camera/CameraBase.cpp
index c25c5fd..55376b0 100644
--- a/camera/CameraBase.cpp
+++ b/camera/CameraBase.cpp
@@ -92,20 +92,25 @@
template <typename TCam, typename TCamTraits>
sp<TCam> CameraBase<TCam, TCamTraits>::connect(int cameraId,
- const String16& clientPackageName,
+ const String16& clientPackageName,
int clientUid)
{
ALOGV("%s: connect", __FUNCTION__);
sp<TCam> c = new TCam(cameraId);
sp<TCamCallbacks> cl = c;
+ status_t status = NO_ERROR;
const sp<ICameraService>& cs = getCameraService();
+
if (cs != 0) {
- c->mCamera = cs->connect(cl, cameraId, clientPackageName, clientUid);
+ TCamConnectService fnConnectService = TCamTraits::fnConnectService;
+ status = (cs.get()->*fnConnectService)(cl, cameraId, clientPackageName, clientUid,
+ /*out*/ c->mCamera);
}
- if (c->mCamera != 0) {
+ if (status == OK && c->mCamera != 0) {
c->mCamera->asBinder()->linkToDeath(c);
c->mStatus = NO_ERROR;
} else {
+ ALOGW("An error occurred while connecting to camera: %d", cameraId);
c.clear();
}
return c;
diff --git a/camera/ICamera.cpp b/camera/ICamera.cpp
index 12356f0..8c6e1f7 100644
--- a/camera/ICamera.cpp
+++ b/camera/ICamera.cpp
@@ -29,7 +29,7 @@
enum {
DISCONNECT = IBinder::FIRST_CALL_TRANSACTION,
- SET_PREVIEW_TEXTURE,
+ SET_PREVIEW_TARGET,
SET_PREVIEW_CALLBACK_FLAG,
SET_PREVIEW_CALLBACK_TARGET,
START_PREVIEW,
@@ -70,14 +70,14 @@
}
// pass the buffered IGraphicBufferProducer to the camera service
- status_t setPreviewTexture(const sp<IGraphicBufferProducer>& bufferProducer)
+ status_t setPreviewTarget(const sp<IGraphicBufferProducer>& bufferProducer)
{
- ALOGV("setPreviewTexture");
+ ALOGV("setPreviewTarget");
Parcel data, reply;
data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
sp<IBinder> b(bufferProducer->asBinder());
data.writeStrongBinder(b);
- remote()->transact(SET_PREVIEW_TEXTURE, data, &reply);
+ remote()->transact(SET_PREVIEW_TARGET, data, &reply);
return reply.readInt32();
}
@@ -104,7 +104,7 @@
return reply.readInt32();
}
- // start preview mode, must call setPreviewDisplay first
+ // start preview mode, must call setPreviewTarget first
status_t startPreview()
{
ALOGV("startPreview");
@@ -114,7 +114,7 @@
return reply.readInt32();
}
- // start recording mode, must call setPreviewDisplay first
+ // start recording mode, must call setPreviewTarget first
status_t startRecording()
{
ALOGV("startRecording");
@@ -285,12 +285,12 @@
reply->writeNoException();
return NO_ERROR;
} break;
- case SET_PREVIEW_TEXTURE: {
- ALOGV("SET_PREVIEW_TEXTURE");
+ case SET_PREVIEW_TARGET: {
+ ALOGV("SET_PREVIEW_TARGET");
CHECK_INTERFACE(ICamera, data, reply);
sp<IGraphicBufferProducer> st =
interface_cast<IGraphicBufferProducer>(data.readStrongBinder());
- reply->writeInt32(setPreviewTexture(st));
+ reply->writeInt32(setPreviewTarget(st));
return NO_ERROR;
} break;
case SET_PREVIEW_CALLBACK_FLAG: {
diff --git a/camera/ICameraService.cpp b/camera/ICameraService.cpp
index 876a2df..3debe22 100644
--- a/camera/ICameraService.cpp
+++ b/camera/ICameraService.cpp
@@ -120,8 +120,10 @@
}
// connect to camera service (android.hardware.Camera)
- virtual sp<ICamera> connect(const sp<ICameraClient>& cameraClient, int cameraId,
- const String16 &clientPackageName, int clientUid)
+ virtual status_t connect(const sp<ICameraClient>& cameraClient, int cameraId,
+ const String16 &clientPackageName, int clientUid,
+ /*out*/
+ sp<ICamera>& device)
{
Parcel data, reply;
data.writeInterfaceToken(ICameraService::getInterfaceDescriptor());
@@ -131,13 +133,19 @@
data.writeInt32(clientUid);
remote()->transact(BnCameraService::CONNECT, data, &reply);
- if (readExceptionCode(reply)) return NULL;
- return interface_cast<ICamera>(reply.readStrongBinder());
+ if (readExceptionCode(reply)) return -EPROTO;
+ status_t status = reply.readInt32();
+ if (reply.readInt32() != 0) {
+ device = interface_cast<ICamera>(reply.readStrongBinder());
+ }
+ return status;
}
// connect to camera service (pro client)
- virtual sp<IProCameraUser> connect(const sp<IProCameraCallbacks>& cameraCb, int cameraId,
- const String16 &clientPackageName, int clientUid)
+ virtual status_t connectPro(const sp<IProCameraCallbacks>& cameraCb, int cameraId,
+ const String16 &clientPackageName, int clientUid,
+ /*out*/
+ sp<IProCameraUser>& device)
{
Parcel data, reply;
data.writeInterfaceToken(ICameraService::getInterfaceDescriptor());
@@ -147,16 +155,22 @@
data.writeInt32(clientUid);
remote()->transact(BnCameraService::CONNECT_PRO, data, &reply);
- if (readExceptionCode(reply)) return NULL;
- return interface_cast<IProCameraUser>(reply.readStrongBinder());
+ if (readExceptionCode(reply)) return -EPROTO;
+ status_t status = reply.readInt32();
+ if (reply.readInt32() != 0) {
+ device = interface_cast<IProCameraUser>(reply.readStrongBinder());
+ }
+ return status;
}
// connect to camera service (android.hardware.camera2.CameraDevice)
- virtual sp<ICameraDeviceUser> connect(
+ virtual status_t connectDevice(
const sp<ICameraDeviceCallbacks>& cameraCb,
int cameraId,
const String16& clientPackageName,
- int clientUid)
+ int clientUid,
+ /*out*/
+ sp<ICameraDeviceUser>& device)
{
Parcel data, reply;
data.writeInterfaceToken(ICameraService::getInterfaceDescriptor());
@@ -166,8 +180,12 @@
data.writeInt32(clientUid);
remote()->transact(BnCameraService::CONNECT_DEVICE, data, &reply);
- if (readExceptionCode(reply)) return NULL;
- return interface_cast<ICameraDeviceUser>(reply.readStrongBinder());
+ if (readExceptionCode(reply)) return -EPROTO;
+ status_t status = reply.readInt32();
+ if (reply.readInt32() != 0) {
+ device = interface_cast<ICameraDeviceUser>(reply.readStrongBinder());
+ }
+ return status;
}
virtual status_t addListener(const sp<ICameraServiceListener>& listener)
@@ -228,10 +246,17 @@
int32_t cameraId = data.readInt32();
const String16 clientName = data.readString16();
int32_t clientUid = data.readInt32();
- sp<ICamera> camera = connect(cameraClient, cameraId,
- clientName, clientUid);
+ sp<ICamera> camera;
+ status_t status = connect(cameraClient, cameraId,
+ clientName, clientUid, /*out*/ camera);
reply->writeNoException();
- reply->writeStrongBinder(camera->asBinder());
+ reply->writeInt32(status);
+ if (camera != NULL) {
+ reply->writeInt32(1);
+ reply->writeStrongBinder(camera->asBinder());
+ } else {
+ reply->writeInt32(0);
+ }
return NO_ERROR;
} break;
case CONNECT_PRO: {
@@ -241,10 +266,17 @@
int32_t cameraId = data.readInt32();
const String16 clientName = data.readString16();
int32_t clientUid = data.readInt32();
- sp<IProCameraUser> camera = connect(cameraClient, cameraId,
- clientName, clientUid);
+ sp<IProCameraUser> camera;
+ status_t status = connectPro(cameraClient, cameraId,
+ clientName, clientUid, /*out*/ camera);
reply->writeNoException();
- reply->writeStrongBinder(camera->asBinder());
+ reply->writeInt32(status);
+ if (camera != NULL) {
+ reply->writeInt32(1);
+ reply->writeStrongBinder(camera->asBinder());
+ } else {
+ reply->writeInt32(0);
+ }
return NO_ERROR;
} break;
case CONNECT_DEVICE: {
@@ -254,10 +286,17 @@
int32_t cameraId = data.readInt32();
const String16 clientName = data.readString16();
int32_t clientUid = data.readInt32();
- sp<ICameraDeviceUser> camera = connect(cameraClient, cameraId,
- clientName, clientUid);
+ sp<ICameraDeviceUser> camera;
+ status_t status = connectDevice(cameraClient, cameraId,
+ clientName, clientUid, /*out*/ camera);
reply->writeNoException();
- reply->writeStrongBinder(camera->asBinder());
+ reply->writeInt32(status);
+ if (camera != NULL) {
+ reply->writeInt32(1);
+ reply->writeStrongBinder(camera->asBinder());
+ } else {
+ reply->writeInt32(0);
+ }
return NO_ERROR;
} break;
case ADD_LISTENER: {
diff --git a/camera/ProCamera.cpp b/camera/ProCamera.cpp
index f6c9ca1..577c760 100644
--- a/camera/ProCamera.cpp
+++ b/camera/ProCamera.cpp
@@ -26,7 +26,6 @@
#include <binder/IMemory.h>
#include <camera/ProCamera.h>
-#include <camera/ICameraService.h>
#include <camera/IProCameraUser.h>
#include <camera/IProCameraCallbacks.h>
@@ -47,6 +46,9 @@
{
}
+CameraTraits<ProCamera>::TCamConnectService CameraTraits<ProCamera>::fnConnectService =
+ &ICameraService::connectPro;
+
ProCamera::~ProCamera()
{
diff --git a/include/camera/Camera.h b/include/camera/Camera.h
index c34b3ea..79682b8 100644
--- a/include/camera/Camera.h
+++ b/include/camera/Camera.h
@@ -51,8 +51,14 @@
typedef CameraListener TCamListener;
typedef ICamera TCamUser;
typedef ICameraClient TCamCallbacks;
+ typedef status_t (ICameraService::*TCamConnectService)(const sp<ICameraClient>&,
+ int, const String16&, int,
+ /*out*/
+ sp<ICamera>&);
+ static TCamConnectService fnConnectService;
};
+
class Camera :
public CameraBase<Camera>,
public BnCameraClient
@@ -75,9 +81,9 @@
status_t unlock();
// pass the buffered IGraphicBufferProducer to the camera service
- status_t setPreviewTexture(const sp<IGraphicBufferProducer>& bufferProducer);
+ status_t setPreviewTarget(const sp<IGraphicBufferProducer>& bufferProducer);
- // start preview mode, must call setPreviewDisplay first
+ // start preview mode, must call setPreviewTarget first
status_t startPreview();
// stop preview mode
@@ -86,7 +92,7 @@
// get preview state
bool previewEnabled();
- // start recording mode, must call setPreviewDisplay first
+ // start recording mode, must call setPreviewTarget first
status_t startRecording();
// stop recording mode
diff --git a/include/camera/CameraBase.h b/include/camera/CameraBase.h
index 9b08c0f..1b93157 100644
--- a/include/camera/CameraBase.h
+++ b/include/camera/CameraBase.h
@@ -54,9 +54,10 @@
class CameraBase : public IBinder::DeathRecipient
{
public:
- typedef typename TCamTraits::TCamListener TCamListener;
- typedef typename TCamTraits::TCamUser TCamUser;
- typedef typename TCamTraits::TCamCallbacks TCamCallbacks;
+ typedef typename TCamTraits::TCamListener TCamListener;
+ typedef typename TCamTraits::TCamUser TCamUser;
+ typedef typename TCamTraits::TCamCallbacks TCamCallbacks;
+ typedef typename TCamTraits::TCamConnectService TCamConnectService;
static sp<TCam> connect(int cameraId,
const String16& clientPackageName,
diff --git a/include/camera/ICamera.h b/include/camera/ICamera.h
index f3a186e..b025735 100644
--- a/include/camera/ICamera.h
+++ b/include/camera/ICamera.h
@@ -50,7 +50,7 @@
virtual status_t unlock() = 0;
// pass the buffered IGraphicBufferProducer to the camera service
- virtual status_t setPreviewTexture(
+ virtual status_t setPreviewTarget(
const sp<IGraphicBufferProducer>& bufferProducer) = 0;
// set the preview callback flag to affect how the received frames from
@@ -64,7 +64,7 @@
virtual status_t setPreviewCallbackTarget(
const sp<IGraphicBufferProducer>& callbackProducer) = 0;
- // start preview mode, must call setPreviewDisplay first
+ // start preview mode, must call setPreviewTarget first
virtual status_t startPreview() = 0;
// stop preview mode
diff --git a/include/camera/ICameraService.h b/include/camera/ICameraService.h
index fa715b7..0e10699 100644
--- a/include/camera/ICameraService.h
+++ b/include/camera/ICameraService.h
@@ -71,21 +71,27 @@
* clientUid == USE_CALLING_UID, then the calling UID is used instead. Only
* trusted callers can set a clientUid other than USE_CALLING_UID.
*/
- virtual sp<ICamera> connect(const sp<ICameraClient>& cameraClient,
+ virtual status_t connect(const sp<ICameraClient>& cameraClient,
int cameraId,
const String16& clientPackageName,
- int clientUid) = 0;
+ int clientUid,
+ /*out*/
+ sp<ICamera>& device) = 0;
- virtual sp<IProCameraUser> connect(const sp<IProCameraCallbacks>& cameraCb,
+ virtual status_t connectPro(const sp<IProCameraCallbacks>& cameraCb,
int cameraId,
const String16& clientPackageName,
- int clientUid) = 0;
+ int clientUid,
+ /*out*/
+ sp<IProCameraUser>& device) = 0;
- virtual sp<ICameraDeviceUser> connect(
+ virtual status_t connectDevice(
const sp<ICameraDeviceCallbacks>& cameraCb,
int cameraId,
const String16& clientPackageName,
- int clientUid) = 0;
+ int clientUid,
+ /*out*/
+ sp<ICameraDeviceUser>& device) = 0;
};
// ----------------------------------------------------------------------------
diff --git a/include/camera/ProCamera.h b/include/camera/ProCamera.h
index 3d1652f..d9ee662 100644
--- a/include/camera/ProCamera.h
+++ b/include/camera/ProCamera.h
@@ -25,6 +25,7 @@
#include <camera/IProCameraUser.h>
#include <camera/Camera.h>
#include <camera/CameraMetadata.h>
+#include <camera/ICameraService.h>
#include <gui/CpuConsumer.h>
#include <gui/Surface.h>
@@ -87,8 +88,14 @@
typedef ProCameraListener TCamListener;
typedef IProCameraUser TCamUser;
typedef IProCameraCallbacks TCamCallbacks;
+ typedef status_t (ICameraService::*TCamConnectService)(const sp<IProCameraCallbacks>&,
+ int, const String16&, int,
+ /*out*/
+ sp<IProCameraUser>&);
+ static TCamConnectService fnConnectService;
};
+
class ProCamera :
public CameraBase<ProCamera>,
public BnProCameraCallbacks
diff --git a/include/media/AudioSystem.h b/include/media/AudioSystem.h
index 006af08..225ef76 100644
--- a/include/media/AudioSystem.h
+++ b/include/media/AudioSystem.h
@@ -252,6 +252,9 @@
// bit rate, duration, video and streaming or offload property is enabled
static bool isOffloadSupported(const audio_offload_info_t& info);
+ // check presence of audio flinger service.
+ // returns NO_ERROR if binding to service succeeds, DEAD_OBJECT otherwise
+ static status_t checkAudioFlinger();
// ----------------------------------------------------------------------------
private:
diff --git a/include/media/mediaplayer.h b/include/media/mediaplayer.h
index 14381c7..1afd7f7 100644
--- a/include/media/mediaplayer.h
+++ b/include/media/mediaplayer.h
@@ -42,6 +42,9 @@
MEDIA_BUFFERING_UPDATE = 3,
MEDIA_SEEK_COMPLETE = 4,
MEDIA_SET_VIDEO_SIZE = 5,
+ MEDIA_STARTED = 6,
+ MEDIA_PAUSED = 7,
+ MEDIA_STOPPED = 8,
MEDIA_TIMED_TEXT = 99,
MEDIA_ERROR = 100,
MEDIA_INFO = 200,
diff --git a/media/libmedia/AudioSystem.cpp b/media/libmedia/AudioSystem.cpp
index a571fe4..8033c2c 100644
--- a/media/libmedia/AudioSystem.cpp
+++ b/media/libmedia/AudioSystem.cpp
@@ -76,6 +76,14 @@
return gAudioFlinger;
}
+/* static */ status_t AudioSystem::checkAudioFlinger()
+{
+ if (defaultServiceManager()->checkService(String16("media.audio_flinger")) != 0) {
+ return NO_ERROR;
+ }
+ return DEAD_OBJECT;
+}
+
status_t AudioSystem::muteMicrophone(bool state) {
const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
if (af == 0) return PERMISSION_DENIED;
diff --git a/media/libmediaplayerservice/MidiFile.cpp b/media/libmediaplayerservice/MidiFile.cpp
index 270b872..0a6aa90 100644
--- a/media/libmediaplayerservice/MidiFile.cpp
+++ b/media/libmediaplayerservice/MidiFile.cpp
@@ -220,6 +220,9 @@
}
mRender = true;
+ if (mState == EAS_STATE_PLAY) {
+ sendEvent(MEDIA_STARTED);
+ }
// wake up render thread
ALOGV(" wakeup render thread");
@@ -242,6 +245,7 @@
}
}
mPaused = false;
+ sendEvent(MEDIA_STOPPED);
return NO_ERROR;
}
@@ -279,6 +283,7 @@
return ERROR_EAS_FAILURE;
}
mPaused = true;
+ sendEvent(MEDIA_PAUSED);
return NO_ERROR;
}
@@ -382,6 +387,7 @@
status_t MidiFile::reset_nosync()
{
ALOGV("MidiFile::reset_nosync");
+ sendEvent(MEDIA_STOPPED);
// close file
if (mEasHandle) {
EAS_CloseFile(mEasData, mEasHandle);
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
index 7e81035..b411f34 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
@@ -731,6 +731,9 @@
ALOGV("renderer %s flush completed.", audio ? "audio" : "video");
} else if (what == Renderer::kWhatVideoRenderingStart) {
notifyListener(MEDIA_INFO, MEDIA_INFO_RENDERING_START, 0);
+ } else if (what == Renderer::kWhatMediaRenderingStart) {
+ ALOGV("media rendering started");
+ notifyListener(MEDIA_STARTED, 0, 0);
}
break;
}
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
index 68b9623..cf0373c 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
@@ -255,6 +255,7 @@
return OK;
case STATE_RUNNING:
+ notifyListener(MEDIA_PAUSED);
mPlayer->pause();
break;
@@ -287,6 +288,8 @@
case STATE_PAUSED:
{
mAtEOS = false;
+ // seeks can take a while, so we essentially paused
+ notifyListener(MEDIA_PAUSED);
mPlayer->seekToAsync(seekTimeUs);
break;
}
@@ -345,6 +348,8 @@
break;
}
+ notifyListener(MEDIA_STOPPED);
+
mState = STATE_RESET_IN_PROGRESS;
mPlayer->resetAsync();
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
index b543d9d..3b2784b 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
@@ -50,6 +50,8 @@
mSyncQueues(false),
mPaused(false),
mVideoRenderingStarted(false),
+ mVideoRenderingStartGeneration(0),
+ mAudioRenderingStartGeneration(0),
mLastPositionUpdateUs(-1ll),
mVideoLateByUs(0ll) {
}
@@ -220,6 +222,23 @@
(new AMessage(kWhatAudioSinkChanged, id()))->post();
}
+void NuPlayer::Renderer::prepareForMediaRenderingStart() {
+ mAudioRenderingStartGeneration = mAudioQueueGeneration;
+ mVideoRenderingStartGeneration = mVideoQueueGeneration;
+}
+
+void NuPlayer::Renderer::notifyIfMediaRenderingStarted() {
+ if (mVideoRenderingStartGeneration == mVideoQueueGeneration &&
+ mAudioRenderingStartGeneration == mAudioQueueGeneration) {
+ mVideoRenderingStartGeneration = -1;
+ mAudioRenderingStartGeneration = -1;
+
+ sp<AMessage> notify = mNotify->dup();
+ notify->setInt32("what", kWhatMediaRenderingStart);
+ notify->post();
+ }
+}
+
bool NuPlayer::Renderer::onDrainAudioQueue() {
uint32_t numFramesPlayed;
if (mAudioSink->getPosition(&numFramesPlayed) != OK) {
@@ -299,6 +318,8 @@
numBytesAvailableToWrite -= copy;
size_t copiedFrames = copy / mAudioSink->frameSize();
mNumFramesWritten += copiedFrames;
+
+ notifyIfMediaRenderingStarted();
}
notifyPosition();
@@ -405,6 +426,8 @@
notifyVideoRenderingStart();
}
+ notifyIfMediaRenderingStarted();
+
notifyPosition();
}
@@ -552,6 +575,7 @@
// is flushed.
syncQueuesDone();
+ ALOGV("flushing %s", audio ? "audio" : "video");
if (audio) {
flushQueue(&mAudioQueue);
@@ -560,6 +584,8 @@
mDrainAudioQueuePending = false;
++mAudioQueueGeneration;
+
+ prepareForMediaRenderingStart();
} else {
flushQueue(&mVideoQueue);
@@ -568,6 +594,8 @@
mDrainVideoQueuePending = false;
++mVideoQueueGeneration;
+
+ prepareForMediaRenderingStart();
}
notifyFlushComplete(audio);
@@ -658,6 +686,8 @@
mDrainVideoQueuePending = false;
++mVideoQueueGeneration;
+ prepareForMediaRenderingStart();
+
if (mHasAudio) {
mAudioSink->pause();
}
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h
index c9796e2..94a05ea 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h
@@ -53,6 +53,7 @@
kWhatFlushComplete = 'fluC',
kWhatPosition = 'posi',
kWhatVideoRenderingStart = 'vdrd',
+ kWhatMediaRenderingStart = 'mdrd',
};
protected:
@@ -106,6 +107,8 @@
bool mPaused;
bool mVideoRenderingStarted;
+ int32_t mVideoRenderingStartGeneration;
+ int32_t mAudioRenderingStartGeneration;
int64_t mLastPositionUpdateUs;
int64_t mVideoLateByUs;
@@ -116,6 +119,9 @@
void onDrainVideoQueue();
void postDrainVideoQueue();
+ void prepareForMediaRenderingStart();
+ void notifyIfMediaRenderingStarted();
+
void onQueueBuffer(const sp<AMessage> &msg);
void onQueueEOS(const sp<AMessage> &msg);
void onFlush(const sp<AMessage> &msg);
diff --git a/media/libstagefright/AwesomePlayer.cpp b/media/libstagefright/AwesomePlayer.cpp
index 79f2c91..52e178e 100644
--- a/media/libstagefright/AwesomePlayer.cpp
+++ b/media/libstagefright/AwesomePlayer.cpp
@@ -191,6 +191,8 @@
mTimeSource(NULL),
mVideoRenderingStarted(false),
mVideoRendererIsPreview(false),
+ mMediaRenderingStartGeneration(0),
+ mStartGeneration(0),
mAudioPlayer(NULL),
mDisplayWidth(0),
mDisplayHeight(0),
@@ -491,6 +493,8 @@
mDisplayWidth = 0;
mDisplayHeight = 0;
+ notifyListener_l(MEDIA_STOPPED);
+
if (mDecryptHandle != NULL) {
mDrmManagerClient->setPlaybackStatus(mDecryptHandle,
Playback::STOP, 0);
@@ -1025,6 +1029,13 @@
seekAudioIfNecessary_l();
}
+void AwesomePlayer::notifyIfMediaStarted_l() {
+ if (mMediaRenderingStartGeneration == mStartGeneration) {
+ mMediaRenderingStartGeneration = -1;
+ notifyListener_l(MEDIA_STARTED);
+ }
+}
+
status_t AwesomePlayer::startAudioPlayer_l(bool sendErrorNotification) {
CHECK(!(mFlags & AUDIO_RUNNING));
status_t err = OK;
@@ -1061,6 +1072,8 @@
// We will have finished the seek while starting the audio player.
postAudioSeekComplete();
+ } else {
+ notifyIfMediaStarted_l();
}
} else {
err = mAudioPlayer->resume();
@@ -1201,6 +1214,9 @@
return OK;
}
+ notifyListener_l(MEDIA_PAUSED);
+ mMediaRenderingStartGeneration = ++mStartGeneration;
+
cancelPlayerEvents(true /* keepNotifications */);
if (mAudioPlayer != NULL && (mFlags & AUDIO_RUNNING)) {
@@ -1389,6 +1405,9 @@
mSeekTimeUs = timeUs;
modifyFlags((AT_EOS | AUDIO_AT_EOS | VIDEO_AT_EOS), CLEAR);
+ notifyListener_l(MEDIA_PAUSED);
+ mMediaRenderingStartGeneration = ++mStartGeneration;
+
seekAudioIfNecessary_l();
if (mFlags & TEXTPLAYER_INITIALIZED) {
@@ -1903,6 +1922,7 @@
notifyListener_l(MEDIA_INFO, MEDIA_INFO_RENDERING_START);
}
+ notifyIfMediaStarted_l();
}
mVideoBuffer->release();
@@ -1998,6 +2018,8 @@
}
mSeeking = NO_SEEK;
+
+ notifyIfMediaStarted_l();
}
status_t finalStatus;
diff --git a/media/libstagefright/CameraSource.cpp b/media/libstagefright/CameraSource.cpp
index 5a26b06..3017fe7 100644
--- a/media/libstagefright/CameraSource.cpp
+++ b/media/libstagefright/CameraSource.cpp
@@ -536,7 +536,7 @@
if (mSurface != NULL) {
// This CHECK is good, since we just passed the lock/unlock
// check earlier by calling mCamera->setParameters().
- CHECK_EQ((status_t)OK, mCamera->setPreviewTexture(mSurface));
+ CHECK_EQ((status_t)OK, mCamera->setPreviewTarget(mSurface));
}
// By default, do not store metadata in video buffers
diff --git a/media/libstagefright/include/AwesomePlayer.h b/media/libstagefright/include/AwesomePlayer.h
index d3c74e2..b001cf4 100644
--- a/media/libstagefright/include/AwesomePlayer.h
+++ b/media/libstagefright/include/AwesomePlayer.h
@@ -169,6 +169,8 @@
sp<AwesomeRenderer> mVideoRenderer;
bool mVideoRenderingStarted;
bool mVideoRendererIsPreview;
+ int32_t mMediaRenderingStartGeneration;
+ int32_t mStartGeneration;
ssize_t mActiveAudioTrackIndex;
sp<MediaSource> mAudioTrack;
@@ -294,6 +296,7 @@
void finishSeekIfNecessary(int64_t videoTimeUs);
void ensureCacheIsFetching_l();
+ void notifyIfMediaStarted_l();
void createAudioPlayer_l();
status_t startAudioPlayer_l(bool sendErrorNotification = true);
diff --git a/media/libstagefright/wifi-display/wfd.cpp b/media/libstagefright/wifi-display/wfd.cpp
index 4607606..04cb319 100644
--- a/media/libstagefright/wifi-display/wfd.cpp
+++ b/media/libstagefright/wifi-display/wfd.cpp
@@ -138,28 +138,6 @@
}
}
-static status_t enableAudioSubmix(bool enable) {
- status_t err = AudioSystem::setDeviceConnectionState(
- AUDIO_DEVICE_IN_REMOTE_SUBMIX,
- enable
- ? AUDIO_POLICY_DEVICE_STATE_AVAILABLE
- : AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
- NULL /* device_address */);
-
- if (err != OK) {
- return err;
- }
-
- err = AudioSystem::setDeviceConnectionState(
- AUDIO_DEVICE_OUT_REMOTE_SUBMIX,
- enable
- ? AUDIO_POLICY_DEVICE_STATE_AVAILABLE
- : AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
- NULL /* device_address */);
-
- return err;
-}
-
static void createSource(const AString &addr, int32_t port) {
sp<IServiceManager> sm = defaultServiceManager();
sp<IBinder> binder = sm->getService(String16("media.player"));
@@ -168,8 +146,6 @@
CHECK(service.get() != NULL);
- enableAudioSubmix(true /* enable */);
-
String8 iface;
iface.append(addr.c_str());
iface.append(StringPrintf(":%d", port).c_str());
@@ -182,8 +158,6 @@
display->dispose();
display.clear();
-
- enableAudioSubmix(false /* enable */);
}
static void createFileSource(
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 3d65c44..b8a6b37 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -1206,6 +1206,10 @@
// ----------------------------------------------------------------------------
+static bool deviceRequiresCaptureAudioOutputPermission(audio_devices_t inDevice) {
+ return audio_is_remote_submix_device(inDevice);
+}
+
sp<IAudioRecord> AudioFlinger::openRecord(
audio_io_handle_t input,
uint32_t sampleRate,
@@ -1246,6 +1250,12 @@
goto Exit;
}
+ if (deviceRequiresCaptureAudioOutputPermission(thread->inDevice())
+ && !captureAudioOutputAllowed()) {
+ lStatus = PERMISSION_DENIED;
+ goto Exit;
+ }
+
pid_t pid = IPCThreadState::self()->getCallingPid();
client = registerPid_l(pid);
diff --git a/services/audioflinger/ServiceUtilities.cpp b/services/audioflinger/ServiceUtilities.cpp
index d15bd04..9ee513b 100644
--- a/services/audioflinger/ServiceUtilities.cpp
+++ b/services/audioflinger/ServiceUtilities.cpp
@@ -34,6 +34,15 @@
return ok;
}
+bool captureAudioOutputAllowed() {
+ if (getpid_cached == IPCThreadState::self()->getCallingPid()) return true;
+ static const String16 sCaptureAudioOutput("android.permission.CAPTURE_AUDIO_OUTPUT");
+ // don't use PermissionCache; this is not a system permission
+ bool ok = checkCallingPermission(sCaptureAudioOutput);
+ if (!ok) ALOGE("Request requires android.permission.CAPTURE_AUDIO_OUTPUT");
+ return ok;
+}
+
bool settingsAllowed() {
if (getpid_cached == IPCThreadState::self()->getCallingPid()) return true;
static const String16 sAudioSettings("android.permission.MODIFY_AUDIO_SETTINGS");
diff --git a/services/audioflinger/ServiceUtilities.h b/services/audioflinger/ServiceUtilities.h
index 80cecba..175cd28 100644
--- a/services/audioflinger/ServiceUtilities.h
+++ b/services/audioflinger/ServiceUtilities.h
@@ -21,6 +21,7 @@
extern pid_t getpid_cached;
bool recordingAllowed();
+bool captureAudioOutputAllowed();
bool settingsAllowed();
bool dumpAllowed();
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index 359b3ca..bf9bc71 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -211,7 +211,7 @@
status_t CameraService::getCameraInfo(int cameraId,
struct CameraInfo* cameraInfo) {
if (!mModule) {
- return NO_INIT;
+ return -ENODEV;
}
if (cameraId < 0 || cameraId >= mNumberOfCameras) {
@@ -262,7 +262,7 @@
return false;
}
-bool CameraService::validateConnect(int cameraId,
+status_t CameraService::validateConnect(int cameraId,
/*inout*/
int& clientUid) const {
@@ -275,19 +275,19 @@
if (callingPid != getpid()) {
ALOGE("CameraService::connect X (pid %d) rejected (don't trust clientUid)",
callingPid);
- return false;
+ return PERMISSION_DENIED;
}
}
if (!mModule) {
ALOGE("Camera HAL module not loaded");
- return false;
+ return -ENODEV;
}
if (cameraId < 0 || cameraId >= mNumberOfCameras) {
ALOGE("CameraService::connect X (pid %d) rejected (invalid cameraId %d).",
callingPid, cameraId);
- return false;
+ return -ENODEV;
}
char value[PROPERTY_VALUE_MAX];
@@ -295,23 +295,23 @@
if (strcmp(value, "1") == 0) {
// Camera is disabled by DevicePolicyManager.
ALOGI("Camera is disabled. connect X (pid %d) rejected", callingPid);
- return false;
+ return -EACCES;
}
ICameraServiceListener::Status currentStatus = getStatus(cameraId);
if (currentStatus == ICameraServiceListener::STATUS_NOT_PRESENT) {
ALOGI("Camera is not plugged in,"
" connect X (pid %d) rejected", callingPid);
- return false;
+ return -ENODEV;
} else if (currentStatus == ICameraServiceListener::STATUS_ENUMERATING) {
ALOGI("Camera is enumerating,"
" connect X (pid %d) rejected", callingPid);
- return false;
+ return -EBUSY;
}
// Else don't check for STATUS_NOT_AVAILABLE.
// -- It's done implicitly in canConnectUnsafe /w the mBusy array
- return true;
+ return OK;
}
bool CameraService::canConnectUnsafe(int cameraId,
@@ -358,11 +358,13 @@
return true;
}
-sp<ICamera> CameraService::connect(
+status_t CameraService::connect(
const sp<ICameraClient>& cameraClient,
int cameraId,
const String16& clientPackageName,
- int clientUid) {
+ int clientUid,
+ /*out*/
+ sp<ICamera>& device) {
String8 clientName8(clientPackageName);
int callingPid = getCallingPid();
@@ -370,8 +372,9 @@
LOG1("CameraService::connect E (pid %d \"%s\", id %d)", callingPid,
clientName8.string(), cameraId);
- if (!validateConnect(cameraId, /*inout*/clientUid)) {
- return NULL;
+ status_t status = validateConnect(cameraId, /*inout*/clientUid);
+ if (status != OK) {
+ return status;
}
@@ -382,9 +385,10 @@
if (!canConnectUnsafe(cameraId, clientPackageName,
cameraClient->asBinder(),
/*out*/clientTmp)) {
- return NULL;
+ return -EBUSY;
} else if (client.get() != NULL) {
- return static_cast<Client*>(clientTmp.get());
+ device = static_cast<Client*>(clientTmp.get());
+ return OK;
}
int facing = -1;
@@ -414,19 +418,18 @@
break;
case -1:
ALOGE("Invalid camera id %d", cameraId);
- return NULL;
+ return BAD_VALUE;
default:
ALOGE("Unknown camera device HAL version: %d", deviceVersion);
- return NULL;
+ return INVALID_OPERATION;
}
- if (!connectFinishUnsafe(client,
- client->getRemote())) {
+ status_t status = connectFinishUnsafe(client, client->getRemote());
+ if (status != OK) {
// this is probably not recoverable.. maybe the client can try again
// OK: we can only get here if we were originally in PRESENT state
updateStatus(ICameraServiceListener::STATUS_PRESENT, cameraId);
-
- return NULL;
+ return status;
}
mClient[cameraId] = client;
@@ -436,34 +439,38 @@
// important: release the mutex here so the client can call back
// into the service from its destructor (can be at the end of the call)
- return client;
+ device = client;
+ return OK;
}
-bool CameraService::connectFinishUnsafe(const sp<BasicClient>& client,
- const sp<IBinder>& remoteCallback) {
- if (client->initialize(mModule) != OK) {
- return false;
+status_t CameraService::connectFinishUnsafe(const sp<BasicClient>& client,
+ const sp<IBinder>& remoteCallback) {
+ status_t status = client->initialize(mModule);
+ if (status != OK) {
+ return status;
}
remoteCallback->linkToDeath(this);
- return true;
+ return OK;
}
-sp<IProCameraUser> CameraService::connect(
+status_t CameraService::connectPro(
const sp<IProCameraCallbacks>& cameraCb,
int cameraId,
const String16& clientPackageName,
- int clientUid)
+ int clientUid,
+ /*out*/
+ sp<IProCameraUser>& device)
{
String8 clientName8(clientPackageName);
int callingPid = getCallingPid();
LOG1("CameraService::connectPro E (pid %d \"%s\", id %d)", callingPid,
clientName8.string(), cameraId);
-
- if (!validateConnect(cameraId, /*inout*/clientUid)) {
- return NULL;
+ status_t status = validateConnect(cameraId, /*inout*/clientUid);
+ if (status != OK) {
+ return status;
}
sp<ProClient> client;
@@ -474,7 +481,7 @@
if (!canConnectUnsafe(cameraId, clientPackageName,
cameraCb->asBinder(),
/*out*/client)) {
- return NULL;
+ return -EBUSY;
}
}
@@ -485,7 +492,7 @@
case CAMERA_DEVICE_API_VERSION_1_0:
ALOGE("Camera id %d uses HALv1, doesn't support ProCamera",
cameraId);
- return NULL;
+ return -ENOTSUP;
break;
case CAMERA_DEVICE_API_VERSION_2_0:
case CAMERA_DEVICE_API_VERSION_2_1:
@@ -495,14 +502,15 @@
break;
case -1:
ALOGE("Invalid camera id %d", cameraId);
- return NULL;
+ return BAD_VALUE;
default:
ALOGE("Unknown camera device HAL version: %d", deviceVersion);
- return NULL;
+ return INVALID_OPERATION;
}
- if (!connectFinishUnsafe(client, client->getRemote())) {
- return NULL;
+ status_t status = connectFinishUnsafe(client, client->getRemote());
+ if (status != OK) {
+ return status;
}
mProClientList[cameraId].push(client);
@@ -512,18 +520,18 @@
}
// important: release the mutex here so the client can call back
// into the service from its destructor (can be at the end of the call)
-
- return client;
+ device = client;
+ return OK;
}
-sp<ICameraDeviceUser> CameraService::connect(
+status_t CameraService::connectDevice(
const sp<ICameraDeviceCallbacks>& cameraCb,
int cameraId,
const String16& clientPackageName,
- int clientUid)
+ int clientUid,
+ /*out*/
+ sp<ICameraDeviceUser>& device)
{
- // TODO: this function needs to return status_t
- // so that we have an error code when things go wrong and the client is NULL
String8 clientName8(clientPackageName);
int callingPid = getCallingPid();
@@ -531,8 +539,9 @@
LOG1("CameraService::connectDevice E (pid %d \"%s\", id %d)", callingPid,
clientName8.string(), cameraId);
- if (!validateConnect(cameraId, /*inout*/clientUid)) {
- return NULL;
+ status_t status = validateConnect(cameraId, /*inout*/clientUid);
+ if (status != OK) {
+ return status;
}
sp<CameraDeviceClient> client;
@@ -543,7 +552,7 @@
if (!canConnectUnsafe(cameraId, clientPackageName,
cameraCb->asBinder(),
/*out*/client)) {
- return NULL;
+ return -EBUSY;
}
}
@@ -560,10 +569,8 @@
switch(deviceVersion) {
case CAMERA_DEVICE_API_VERSION_1_0:
- ALOGE("Camera id %d uses old HAL, doesn't support CameraDevice",
- cameraId);
- return NULL;
- break;
+ ALOGW("Camera using old HAL version: %d", deviceVersion);
+ return -ENOTSUP;
// TODO: don't allow 2.0 Only allow 2.1 and higher
case CAMERA_DEVICE_API_VERSION_2_0:
case CAMERA_DEVICE_API_VERSION_2_1:
@@ -573,17 +580,18 @@
break;
case -1:
ALOGE("Invalid camera id %d", cameraId);
- return NULL;
+ return BAD_VALUE;
default:
ALOGE("Unknown camera device HAL version: %d", deviceVersion);
- return NULL;
+ return INVALID_OPERATION;
}
- if (!connectFinishUnsafe(client, client->getRemote())) {
+ status_t status = connectFinishUnsafe(client, client->getRemote());
+ if (status != OK) {
// this is probably not recoverable.. maybe the client can try again
// OK: we can only get here if we were originally in PRESENT state
updateStatus(ICameraServiceListener::STATUS_PRESENT, cameraId);
- return NULL;
+ return status;
}
LOG1("CameraService::connectDevice X (id %d, this pid is %d)", cameraId,
@@ -594,7 +602,8 @@
// important: release the mutex here so the client can call back
// into the service from its destructor (can be at the end of the call)
- return client;
+ device = client;
+ return OK;
}
diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h
index 980eb97..b34a0f6 100644
--- a/services/camera/libcameraservice/CameraService.h
+++ b/services/camera/libcameraservice/CameraService.h
@@ -72,15 +72,23 @@
virtual status_t getCameraInfo(int cameraId,
struct CameraInfo* cameraInfo);
- virtual sp<ICamera> connect(const sp<ICameraClient>& cameraClient, int cameraId,
- const String16& clientPackageName, int clientUid);
- virtual sp<IProCameraUser> connect(const sp<IProCameraCallbacks>& cameraCb,
- int cameraId, const String16& clientPackageName, int clientUid);
- virtual sp<ICameraDeviceUser> connect(
+ virtual status_t connect(const sp<ICameraClient>& cameraClient, int cameraId,
+ const String16& clientPackageName, int clientUid,
+ /*out*/
+ sp<ICamera>& device);
+
+ virtual status_t connectPro(const sp<IProCameraCallbacks>& cameraCb,
+ int cameraId, const String16& clientPackageName, int clientUid,
+ /*out*/
+ sp<IProCameraUser>& device);
+
+ virtual status_t connectDevice(
const sp<ICameraDeviceCallbacks>& cameraCb,
int cameraId,
const String16& clientPackageName,
- int clientUid);
+ int clientUid,
+ /*out*/
+ sp<ICameraDeviceUser>& device);
virtual status_t addListener(const sp<ICameraServiceListener>& listener);
virtual status_t removeListener(
@@ -204,8 +212,7 @@
virtual status_t connect(const sp<ICameraClient>& client) = 0;
virtual status_t lock() = 0;
virtual status_t unlock() = 0;
- virtual status_t setPreviewDisplay(const sp<Surface>& surface) = 0;
- virtual status_t setPreviewTexture(const sp<IGraphicBufferProducer>& bufferProducer)=0;
+ virtual status_t setPreviewTarget(const sp<IGraphicBufferProducer>& bufferProducer)=0;
virtual void setPreviewCallbackFlag(int flag) = 0;
virtual status_t setPreviewCallbackTarget(
const sp<IGraphicBufferProducer>& callbackProducer) = 0;
@@ -308,7 +315,7 @@
virtual void onFirstRef();
// Step 1. Check if we can connect, before we acquire the service lock.
- bool validateConnect(int cameraId,
+ status_t validateConnect(int cameraId,
/*inout*/
int& clientUid) const;
@@ -320,7 +327,7 @@
sp<BasicClient> &client);
// When connection is successful, initialize client and track its death
- bool connectFinishUnsafe(const sp<BasicClient>& client,
+ status_t connectFinishUnsafe(const sp<BasicClient>& client,
const sp<IBinder>& remoteCallback);
virtual sp<BasicClient> getClientByRemote(const wp<IBinder>& cameraClient);
diff --git a/services/camera/libcameraservice/api1/Camera2Client.cpp b/services/camera/libcameraservice/api1/Camera2Client.cpp
index 46aa60c..3d9fe01 100644
--- a/services/camera/libcameraservice/api1/Camera2Client.cpp
+++ b/services/camera/libcameraservice/api1/Camera2Client.cpp
@@ -491,25 +491,7 @@
return EBUSY;
}
-status_t Camera2Client::setPreviewDisplay(
- const sp<Surface>& surface) {
- ATRACE_CALL();
- ALOGV("%s: E", __FUNCTION__);
- Mutex::Autolock icl(mBinderSerializationLock);
- status_t res;
- if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
-
- sp<IBinder> binder;
- sp<ANativeWindow> window;
- if (surface != 0) {
- binder = surface->getIGraphicBufferProducer()->asBinder();
- window = surface;
- }
-
- return setPreviewWindowL(binder,window);
-}
-
-status_t Camera2Client::setPreviewTexture(
+status_t Camera2Client::setPreviewTarget(
const sp<IGraphicBufferProducer>& bufferProducer) {
ATRACE_CALL();
ALOGV("%s: E", __FUNCTION__);
@@ -521,7 +503,10 @@
sp<ANativeWindow> window;
if (bufferProducer != 0) {
binder = bufferProducer->asBinder();
- window = new Surface(bufferProducer);
+ // Using controlledByApp flag to ensure that the buffer queue remains in
+ // async mode for the old camera API, where many applications depend
+ // on that behavior.
+ window = new Surface(bufferProducer, /*controlledByApp*/ true);
}
return setPreviewWindowL(binder, window);
}
diff --git a/services/camera/libcameraservice/api1/Camera2Client.h b/services/camera/libcameraservice/api1/Camera2Client.h
index ed448f3..53629a1 100644
--- a/services/camera/libcameraservice/api1/Camera2Client.h
+++ b/services/camera/libcameraservice/api1/Camera2Client.h
@@ -57,8 +57,7 @@
virtual status_t connect(const sp<ICameraClient>& client);
virtual status_t lock();
virtual status_t unlock();
- virtual status_t setPreviewDisplay(const sp<Surface>& surface);
- virtual status_t setPreviewTexture(
+ virtual status_t setPreviewTarget(
const sp<IGraphicBufferProducer>& bufferProducer);
virtual void setPreviewCallbackFlag(int flag);
virtual status_t setPreviewCallbackTarget(
diff --git a/services/camera/libcameraservice/api1/CameraClient.cpp b/services/camera/libcameraservice/api1/CameraClient.cpp
index ad8856b..bd6805d 100644
--- a/services/camera/libcameraservice/api1/CameraClient.cpp
+++ b/services/camera/libcameraservice/api1/CameraClient.cpp
@@ -308,26 +308,20 @@
return result;
}
-// set the Surface that the preview will use
-status_t CameraClient::setPreviewDisplay(const sp<Surface>& surface) {
- LOG1("setPreviewDisplay(%p) (pid %d)", surface.get(), getCallingPid());
-
- sp<IBinder> binder(surface != 0 ? surface->getIGraphicBufferProducer()->asBinder() : 0);
- sp<ANativeWindow> window(surface);
- return setPreviewWindow(binder, window);
-}
-
-// set the SurfaceTextureClient that the preview will use
-status_t CameraClient::setPreviewTexture(
+// set the buffer consumer that the preview will use
+status_t CameraClient::setPreviewTarget(
const sp<IGraphicBufferProducer>& bufferProducer) {
- LOG1("setPreviewTexture(%p) (pid %d)", bufferProducer.get(),
+ LOG1("setPreviewTarget(%p) (pid %d)", bufferProducer.get(),
getCallingPid());
sp<IBinder> binder;
sp<ANativeWindow> window;
if (bufferProducer != 0) {
binder = bufferProducer->asBinder();
- window = new Surface(bufferProducer);
+ // Using controlledByApp flag to ensure that the buffer queue remains in
+ // async mode for the old camera API, where many applications depend
+ // on that behavior.
+ window = new Surface(bufferProducer, /*controlledByApp*/ true);
}
return setPreviewWindow(binder, window);
}
diff --git a/services/camera/libcameraservice/api1/CameraClient.h b/services/camera/libcameraservice/api1/CameraClient.h
index abde75a..4b89564 100644
--- a/services/camera/libcameraservice/api1/CameraClient.h
+++ b/services/camera/libcameraservice/api1/CameraClient.h
@@ -37,8 +37,7 @@
virtual status_t connect(const sp<ICameraClient>& client);
virtual status_t lock();
virtual status_t unlock();
- virtual status_t setPreviewDisplay(const sp<Surface>& surface);
- virtual status_t setPreviewTexture(const sp<IGraphicBufferProducer>& bufferProducer);
+ virtual status_t setPreviewTarget(const sp<IGraphicBufferProducer>& bufferProducer);
virtual void setPreviewCallbackFlag(int flag);
virtual status_t setPreviewCallbackTarget(
const sp<IGraphicBufferProducer>& callbackProducer);