summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--camera/libcameraservice/CameraService.cpp20
-rw-r--r--camera/libcameraservice/CameraService.h2
-rw-r--r--include/ui/Camera.h37
-rw-r--r--include/utils/BackupHelpers.h1
-rw-r--r--libs/ui/Camera.cpp131
-rw-r--r--libs/utils/BackupHelpers.cpp91
6 files changed, 126 insertions, 156 deletions
diff --git a/camera/libcameraservice/CameraService.cpp b/camera/libcameraservice/CameraService.cpp
index e945056c34..105d4d2020 100644
--- a/camera/libcameraservice/CameraService.cpp
+++ b/camera/libcameraservice/CameraService.cpp
@@ -98,7 +98,7 @@ sp<ICamera> CameraService::connect(const sp<ICameraClient>& cameraClient)
LOGD("CameraService::connect E (pid %d, client %p)", callingPid,
cameraClient->asBinder().get());
- Mutex::Autolock lock(mLock);
+ Mutex::Autolock lock(mServiceLock);
sp<Client> client;
if (mClient != 0) {
sp<Client> currentClient = mClient.promote();
@@ -125,13 +125,14 @@ sp<ICamera> CameraService::connect(const sp<ICameraClient>& cameraClient)
LOGD("New client (pid %d) connecting, old reference was dangling...",
callingPid);
mClient.clear();
- if (mUsers > 0) {
- LOGD("Still have client, rejected");
- return client;
- }
}
}
+ if (mUsers > 0) {
+ LOGD("Still have client, rejected");
+ return client;
+ }
+
// create a new Client object
client = new Client(this, cameraClient, callingPid);
mClient = client;
@@ -152,7 +153,7 @@ void CameraService::removeClient(const sp<ICameraClient>& cameraClient)
// destructor won't be called with the lock held.
sp<Client> client;
- Mutex::Autolock lock(mLock);
+ Mutex::Autolock lock(mServiceLock);
if (mClient == 0) {
// This happens when we have already disconnected.
@@ -390,8 +391,6 @@ void CameraService::Client::disconnect()
// from the user directly, or called by the destructor.
if (mHardware == 0) return;
- mCameraService->removeClient(mCameraClient);
-
LOGD("hardware teardown");
// Before destroying mHardware, we must make sure it's in the
// idle state.
@@ -402,6 +401,7 @@ void CameraService::Client::disconnect()
mHardware->release();
mHardware.clear();
+ mCameraService->removeClient(mCameraClient);
mCameraService->decUsers();
LOGD("Client::disconnect() X (pid %d)", callingPid);
@@ -661,7 +661,7 @@ sp<CameraService::Client> CameraService::Client::getClientFromCookie(void* user)
sp<Client> client = 0;
CameraService *service = static_cast<CameraService*>(user);
if (service != NULL) {
- Mutex::Autolock ourLock(service->mLock);
+ Mutex::Autolock ourLock(service->mServiceLock);
if (service->mClient != 0) {
client = service->mClient.promote();
if (client == 0) {
@@ -1104,7 +1104,7 @@ status_t CameraService::dump(int fd, const Vector<String16>& args)
result.append(buffer);
write(fd, result.string(), result.size());
} else {
- AutoMutex lock(&mLock);
+ AutoMutex lock(&mServiceLock);
if (mClient != 0) {
sp<Client> currentClient = mClient.promote();
sprintf(buffer, "Client (%p) PID: %d\n",
diff --git a/camera/libcameraservice/CameraService.h b/camera/libcameraservice/CameraService.h
index 729e5392d7..8b8b54cd36 100644
--- a/camera/libcameraservice/CameraService.h
+++ b/camera/libcameraservice/CameraService.h
@@ -199,7 +199,7 @@ private:
virtual void incUsers();
virtual void decUsers();
- mutable Mutex mLock;
+ mutable Mutex mServiceLock;
wp<Client> mClient;
#if DEBUG_HEAP_LEAKS
diff --git a/include/ui/Camera.h b/include/ui/Camera.h
index 048bdd560b..bbc21c4910 100644
--- a/include/ui/Camera.h
+++ b/include/ui/Camera.h
@@ -86,10 +86,13 @@ class Surface;
class Mutex;
class String8;
-typedef void (*shutter_callback)(void *cookie);
-typedef void (*frame_callback)(const sp<IMemory>& mem, void *cookie);
-typedef void (*autofocus_callback)(bool focused, void *cookie);
-typedef void (*error_callback)(status_t err, void *cookie);
+// ref-counted object for callbacks
+class CameraListener: virtual public RefBase
+{
+public:
+ virtual void notify(int32_t msgType, int32_t ext1, int32_t ext2) = 0;
+ virtual void postData(int32_t msgType, const sp<IMemory>& dataPtr) = 0;
+};
class Camera : public BnCameraClient, public IBinder::DeathRecipient
{
@@ -144,13 +147,8 @@ public:
// get preview/capture parameters - key/value pairs
String8 getParameters() const;
- void setShutterCallback(shutter_callback cb, void *cookie);
- void setRawCallback(frame_callback cb, void *cookie);
- void setJpegCallback(frame_callback cb, void *cookie);
- void setRecordingCallback(frame_callback cb, void *cookie);
- void setPreviewCallback(frame_callback cb, void *cookie, int preview_callback_flag = FRAME_CALLBACK_FLAG_NOOP);
- void setErrorCallback(error_callback cb, void *cookie);
- void setAutoFocusCallback(autofocus_callback cb, void *cookie);
+ void setListener(const sp<CameraListener>& listener);
+ void setPreviewCallbackFlags(int preview_callback_flag);
// ICameraClient interface
virtual void notifyCallback(int32_t msgType, int32_t ext, int32_t ext2);
@@ -160,6 +158,8 @@ public:
private:
Camera();
+ Camera(const Camera&);
+ Camera& operator=(const Camera);
virtual void binderDied(const wp<IBinder>& who);
class DeathNotifier: public IBinder::DeathRecipient
@@ -179,20 +179,7 @@ private:
sp<ICamera> mCamera;
status_t mStatus;
- shutter_callback mShutterCallback;
- void *mShutterCallbackCookie;
- frame_callback mRawCallback;
- void *mRawCallbackCookie;
- frame_callback mJpegCallback;
- void *mJpegCallbackCookie;
- frame_callback mPreviewCallback;
- void *mPreviewCallbackCookie;
- frame_callback mRecordingCallback;
- void *mRecordingCallbackCookie;
- error_callback mErrorCallback;
- void *mErrorCallbackCookie;
- autofocus_callback mAutoFocusCallback;
- void *mAutoFocusCallbackCookie;
+ sp<CameraListener> mListener;
friend class DeathNotifier;
diff --git a/include/utils/BackupHelpers.h b/include/utils/BackupHelpers.h
index 759a0cc6d5..b1f504512f 100644
--- a/include/utils/BackupHelpers.h
+++ b/include/utils/BackupHelpers.h
@@ -137,6 +137,7 @@ public:
private:
void* m_buf;
+ bool m_loggedUnknownMetadata;
KeyedVector<String8,FileRec> m_files;
};
diff --git a/libs/ui/Camera.cpp b/libs/ui/Camera.cpp
index 661370040e..bb22dabbb5 100644
--- a/libs/ui/Camera.cpp
+++ b/libs/ui/Camera.cpp
@@ -85,20 +85,6 @@ sp<Camera> Camera::create(const sp<ICamera>& camera)
void Camera::init()
{
mStatus = UNKNOWN_ERROR;
- mShutterCallback = 0;
- mShutterCallbackCookie = 0;
- mRawCallback = 0;
- mRawCallbackCookie = 0;
- mJpegCallback = 0;
- mJpegCallbackCookie = 0;
- mPreviewCallback = 0;
- mPreviewCallbackCookie = 0;
- mRecordingCallback = 0;
- mRecordingCallbackCookie = 0;
- mErrorCallback = 0;
- mErrorCallbackCookie = 0;
- mAutoFocusCallback = 0;
- mAutoFocusCallbackCookie = 0;
}
Camera::~Camera()
@@ -127,7 +113,6 @@ void Camera::disconnect()
{
LOGV("disconnect");
if (mCamera != 0) {
- mErrorCallback = 0;
mCamera->disconnect();
mCamera = 0;
}
@@ -285,125 +270,49 @@ String8 Camera::getParameters() const
return params;
}
-void Camera::setAutoFocusCallback(autofocus_callback cb, void *cookie)
+void Camera::setListener(const sp<CameraListener>& listener)
{
- LOGV("setAutoFocusCallback");
- mAutoFocusCallback = cb;
- mAutoFocusCallbackCookie = cookie;
-}
-
-void Camera::setShutterCallback(shutter_callback cb, void *cookie)
-{
- LOGV("setShutterCallback");
- mShutterCallback = cb;
- mShutterCallbackCookie = cookie;
-}
-
-void Camera::setRawCallback(frame_callback cb, void *cookie)
-{
- LOGV("setRawCallback");
- mRawCallback = cb;
- mRawCallbackCookie = cookie;
-}
-
-void Camera::setJpegCallback(frame_callback cb, void *cookie)
-{
- LOGV("setJpegCallback");
- mJpegCallback = cb;
- mJpegCallbackCookie = cookie;
+ Mutex::Autolock _l(mLock);
+ mListener = listener;
}
-void Camera::setPreviewCallback(frame_callback cb, void *cookie, int flag)
+void Camera::setPreviewCallbackFlags(int flag)
{
- LOGV("setPreviewCallback");
- mPreviewCallback = cb;
- mPreviewCallbackCookie = cookie;
+ LOGV("setPreviewCallbackFlags");
sp <ICamera> c = mCamera;
if (c == 0) return;
mCamera->setPreviewCallbackFlag(flag);
}
-void Camera::setRecordingCallback(frame_callback cb, void *cookie)
-{
- LOGV("setRecordingCallback");
- mRecordingCallback = cb;
- mRecordingCallbackCookie = cookie;
-}
-
-void Camera::setErrorCallback(error_callback cb, void *cookie)
-{
- LOGV("setErrorCallback");
- mErrorCallback = cb;
- mErrorCallbackCookie = cookie;
-}
-
// callback from camera service
void Camera::notifyCallback(int32_t msgType, int32_t ext1, int32_t ext2)
{
- switch(msgType) {
- case CAMERA_MSG_ERROR:
- LOGV("errorCallback");
- if (mErrorCallback) {
- mErrorCallback((status_t)ext1, mErrorCallbackCookie);
- }
- break;
- case CAMERA_MSG_FOCUS:
- LOGV("autoFocusCallback");
- if (mAutoFocusCallback) {
- mAutoFocusCallback((bool)ext1, mAutoFocusCallbackCookie);
- }
- break;
- case CAMERA_MSG_SHUTTER:
- LOGV("shutterCallback");
- if (mShutterCallback) {
- mShutterCallback(mShutterCallbackCookie);
- }
- break;
- default:
- LOGV("notifyCallback(%d, %d, %d)", msgType, ext1, ext2);
- break;
+ sp<CameraListener> listener;
+ {
+ Mutex::Autolock _l(mLock);
+ listener = mListener;
+ }
+ if (listener != NULL) {
+ listener->notify(msgType, ext1, ext2);
}
}
// callback from camera service when frame or image is ready
void Camera::dataCallback(int32_t msgType, const sp<IMemory>& dataPtr)
{
- switch(msgType) {
- case CAMERA_MSG_PREVIEW_FRAME:
- LOGV("previewCallback");
- if (mPreviewCallback) {
- mPreviewCallback(dataPtr, mPreviewCallbackCookie);
- }
- break;
- case CAMERA_MSG_VIDEO_FRAME:
- LOGV("recordingCallback");
- if (mRecordingCallback) {
- mRecordingCallback(dataPtr, mRecordingCallbackCookie);
- }
- break;
- case CAMERA_MSG_RAW_IMAGE:
- LOGV("rawCallback");
- if (mRawCallback) {
- mRawCallback(dataPtr, mRawCallbackCookie);
- }
- break;
- case CAMERA_MSG_COMPRESSED_IMAGE:
- LOGV("jpegCallback");
- if (mJpegCallback) {
- mJpegCallback(dataPtr, mJpegCallbackCookie);
- }
- break;
- default:
- LOGV("dataCallback(%d, %p)", msgType, dataPtr.get());
- break;
+ sp<CameraListener> listener;
+ {
+ Mutex::Autolock _l(mLock);
+ listener = mListener;
+ }
+ if (listener != NULL) {
+ listener->postData(msgType, dataPtr);
}
}
void Camera::binderDied(const wp<IBinder>& who) {
LOGW("ICamera died");
- if (mErrorCallback) {
- mErrorCallback(DEAD_OBJECT, mErrorCallbackCookie);
- }
+ notifyCallback(CAMERA_MSG_ERROR, DEAD_OBJECT, 0);
}
void Camera::DeathNotifier::binderDied(const wp<IBinder>& who) {
diff --git a/libs/utils/BackupHelpers.cpp b/libs/utils/BackupHelpers.cpp
index 67d07fed85..99a4abcb6e 100644
--- a/libs/utils/BackupHelpers.cpp
+++ b/libs/utils/BackupHelpers.cpp
@@ -41,6 +41,33 @@ namespace android {
#define MAGIC0 0x70616e53 // Snap
#define MAGIC1 0x656c6946 // File
+/*
+ * File entity data format (v1):
+ *
+ * - 4-byte version number of the metadata, little endian (0x00000001 for v1)
+ * - 12 bytes of metadata
+ * - the file data itself
+ *
+ * i.e. a 16-byte metadata header followed by the raw file data. If the
+ * restore code does not recognize the metadata version, it can still
+ * interpret the file data itself correctly.
+ *
+ * file_metadata_v1:
+ *
+ * - 4 byte version number === 0x00000001 (little endian)
+ * - 4-byte access mode (little-endian)
+ * - undefined (8 bytes)
+ */
+
+struct file_metadata_v1 {
+ int version;
+ int mode;
+ int undefined_1;
+ int undefined_2;
+};
+
+const static int CURRENT_METADATA_VERSION = 1;
+
#if 1 // TEST_BACKUP_HELPERS
#define LOGP(f, x...) printf(f "\n", x)
#else
@@ -181,29 +208,48 @@ write_delete_file(BackupDataWriter* dataStream, const String8& key)
}
static int
-write_update_file(BackupDataWriter* dataStream, int fd, const String8& key,
+write_update_file(BackupDataWriter* dataStream, int fd, int mode, const String8& key,
char const* realFilename)
{
- LOGP("write_update_file %s (%s)\n", realFilename, key.string());
+ LOGP("write_update_file %s (%s) : mode 0%o\n", realFilename, key.string(), mode);
const int bufsize = 4*1024;
int err;
int amt;
int fileSize;
int bytesLeft;
+ file_metadata_v1 metadata;
char* buf = (char*)malloc(bufsize);
int crc = crc32(0L, Z_NULL, 0);
- bytesLeft = fileSize = lseek(fd, 0, SEEK_END);
+ fileSize = lseek(fd, 0, SEEK_END);
lseek(fd, 0, SEEK_SET);
+ if (sizeof(metadata) != 16) {
+ LOGE("ERROR: metadata block is the wrong size!");
+ }
+
+ bytesLeft = fileSize + sizeof(metadata);
err = dataStream->WriteEntityHeader(key, bytesLeft);
if (err != 0) {
+ free(buf);
return err;
}
+ // store the file metadata first
+ metadata.version = tolel(CURRENT_METADATA_VERSION);
+ metadata.mode = tolel(mode);
+ metadata.undefined_1 = metadata.undefined_2 = 0;
+ err = dataStream->WriteEntityData(&metadata, sizeof(metadata));
+ if (err != 0) {
+ free(buf);
+ return err;
+ }
+ bytesLeft -= sizeof(metadata); // bytesLeft should == fileSize now
+
+ // now store the file content
while ((amt = read(fd, buf, bufsize)) != 0 && bytesLeft > 0) {
bytesLeft -= amt;
if (bytesLeft < 0) {
@@ -211,6 +257,7 @@ write_update_file(BackupDataWriter* dataStream, int fd, const String8& key,
}
err = dataStream->WriteEntityData(buf, amt);
if (err != 0) {
+ free(buf);
return err;
}
}
@@ -224,6 +271,7 @@ write_update_file(BackupDataWriter* dataStream, int fd, const String8& key,
bytesLeft -= amt;
err = dataStream->WriteEntityData(buf, amt);
if (err != 0) {
+ free(buf);
return err;
}
}
@@ -233,7 +281,6 @@ write_update_file(BackupDataWriter* dataStream, int fd, const String8& key,
}
free(buf);
-
return NO_ERROR;
}
@@ -241,11 +288,19 @@ static int
write_update_file(BackupDataWriter* dataStream, const String8& key, char const* realFilename)
{
int err;
+ struct stat st;
+
+ err = stat(realFilename, &st);
+ if (err < 0) {
+ return errno;
+ }
+
int fd = open(realFilename, O_RDONLY);
if (fd == -1) {
return errno;
}
- err = write_update_file(dataStream, fd, key, realFilename);
+
+ err = write_update_file(dataStream, fd, st.st_mode, key, realFilename);
close(fd);
return err;
}
@@ -266,7 +321,6 @@ compute_crc32(int fd)
}
free(buf);
-
return crc;
}
@@ -356,7 +410,7 @@ back_up_files(int oldSnapshotFD, BackupDataWriter* dataStream, int newSnapshotFD
g.s.modTime_sec, g.s.modTime_nsec, g.s.mode, g.s.size, g.s.crc32);
if (f.modTime_sec != g.s.modTime_sec || f.modTime_nsec != g.s.modTime_nsec
|| f.mode != g.s.mode || f.size != g.s.size || f.crc32 != g.s.crc32) {
- write_update_file(dataStream, fd, p, g.file.string());
+ write_update_file(dataStream, fd, g.s.mode, p, g.file.string());
}
close(fd);
@@ -390,6 +444,7 @@ back_up_files(int oldSnapshotFD, BackupDataWriter* dataStream, int newSnapshotFD
RestoreHelperBase::RestoreHelperBase()
{
m_buf = malloc(RESTORE_BUF_SIZE);
+ m_loggedUnknownMetadata = false;
}
RestoreHelperBase::~RestoreHelperBase()
@@ -416,8 +471,25 @@ RestoreHelperBase::WriteFile(const String8& filename, BackupDataReader* in)
return err;
}
- // TODO: World readable/writable for now.
- mode = 0666;
+ // Get the metadata block off the head of the file entity and use that to
+ // set up the output file
+ file_metadata_v1 metadata;
+ amt = in->ReadEntityData(&metadata, sizeof(metadata));
+ if (amt != sizeof(metadata)) {
+ LOGW("Could not read metadata for %s -- %ld / %s", filename.string(),
+ (long)amt, strerror(errno));
+ return EIO;
+ }
+ metadata.version = fromlel(metadata.version);
+ metadata.mode = fromlel(metadata.mode);
+ if (metadata.version > CURRENT_METADATA_VERSION) {
+ if (!m_loggedUnknownMetadata) {
+ m_loggedUnknownMetadata = true;
+ LOGW("Restoring file with unsupported metadata version %d (currently %d)",
+ metadata.version, CURRENT_METADATA_VERSION);
+ }
+ }
+ mode = metadata.mode;
// Write the file and compute the crc
crc = crc32(0L, Z_NULL, 0);
@@ -538,6 +610,7 @@ compare_file(const char* path, const unsigned char* data, int len)
}
}
+ free(contents);
return contentsMatch && sizesMatch ? 0 : 1;
}