diff options
-rw-r--r-- | camera/libcameraservice/CameraService.cpp | 186 | ||||
-rw-r--r-- | camera/libcameraservice/CameraService.h | 5 | ||||
-rw-r--r-- | include/private/opengles/gl_context.h | 2 | ||||
-rw-r--r-- | include/ui/Camera.h | 37 | ||||
-rw-r--r-- | include/utils/BackupHelpers.h | 5 | ||||
-rw-r--r-- | include/utils/ResourceTypes.h | 26 | ||||
-rw-r--r-- | libs/ui/Camera.cpp | 131 | ||||
-rw-r--r-- | libs/utils/BackupData.cpp | 21 | ||||
-rw-r--r-- | libs/utils/BackupHelpers.cpp | 164 | ||||
-rw-r--r-- | libs/utils/ResourceTypes.cpp | 22 | ||||
-rw-r--r-- | opengl/libagl/texture.cpp | 9 | ||||
-rw-r--r-- | opengl/tests/angeles/Android.mk | 4 | ||||
-rw-r--r-- | opengl/tests/filter/Android.mk | 2 | ||||
-rw-r--r-- | opengl/tests/finish/Android.mk | 2 | ||||
-rw-r--r-- | opengl/tests/textures/Android.mk | 2 | ||||
-rw-r--r-- | opengl/tests/tritex/Android.mk | 2 |
16 files changed, 351 insertions, 269 deletions
diff --git a/camera/libcameraservice/CameraService.cpp b/camera/libcameraservice/CameraService.cpp index 81639ad..2f4a1c9 100644 --- a/camera/libcameraservice/CameraService.cpp +++ b/camera/libcameraservice/CameraService.cpp @@ -32,6 +32,7 @@ #include <media/AudioSystem.h> #include "CameraService.h" +#include <cutils/atomic.h> #include <cutils/properties.h> namespace android { @@ -42,6 +43,7 @@ extern "C" { #include <sys/stat.h> #include <fcntl.h> #include <pthread.h> +#include <signal.h> } // When you enable this, as well as DEBUG_REFS=1 and @@ -63,6 +65,10 @@ extern "C" { static int debug_frame_cnt; #endif +static int getCallingPid() { + return IPCThreadState::self()->getCallingPid(); +} + // ---------------------------------------------------------------------------- void CameraService::instantiate() { @@ -76,6 +82,7 @@ CameraService::CameraService() : BnCameraService() { LOGI("CameraService started: pid=%d", getpid()); + mUsers = 0; } CameraService::~CameraService() @@ -87,7 +94,9 @@ CameraService::~CameraService() sp<ICamera> CameraService::connect(const sp<ICameraClient>& cameraClient) { - LOGD("Connect E from ICameraClient %p", cameraClient->asBinder().get()); + int callingPid = getCallingPid(); + LOGD("CameraService::connect E (pid %d, client %p)", callingPid, + cameraClient->asBinder().get()); Mutex::Autolock lock(mLock); sp<Client> client; @@ -96,36 +105,50 @@ sp<ICamera> CameraService::connect(const sp<ICameraClient>& cameraClient) if (currentClient != 0) { sp<ICameraClient> currentCameraClient(currentClient->getCameraClient()); if (cameraClient->asBinder() == currentCameraClient->asBinder()) { - // this is the same client reconnecting... - LOGD("Connect X same client (%p) is reconnecting...", cameraClient->asBinder().get()); + // This is the same client reconnecting... + LOGD("CameraService::connect X (pid %d, same client %p) is reconnecting...", + callingPid, cameraClient->asBinder().get()); return currentClient; } else { - // it's another client... reject it - LOGD("new client (%p) attempting to connect - rejected", cameraClient->asBinder().get()); + // It's another client... reject it + LOGD("CameraService::connect X (pid %d, new client %p) rejected. " + "(old pid %d, old client %p)", + callingPid, cameraClient->asBinder().get(), + currentClient->mClientPid, currentCameraClient->asBinder().get()); + if (kill(currentClient->mClientPid, 0) == -1 && errno == ESRCH) { + LOGD("The old client is dead!"); + } return client; } } else { // can't promote, the previous client has died... - LOGD("new client connecting, old reference was dangling..."); + LOGD("New client (pid %d) connecting, old reference was dangling...", + callingPid); mClient.clear(); + if (mUsers > 0) { + LOGD("Still have client, rejected"); + return client; + } } } // create a new Client object - client = new Client(this, cameraClient, IPCThreadState::self()->getCallingPid()); + client = new Client(this, cameraClient, callingPid); mClient = client; #if DEBUG_CLIENT_REFERENCES // Enable tracking for this object, and track increments and decrements of // the refcount. client->trackMe(true, true); #endif - LOGD("Connect X"); + LOGD("CameraService::connect X"); return client; } void CameraService::removeClient(const sp<ICameraClient>& cameraClient) { - // declar this outside the lock to make absolutely sure the + int callingPid = getCallingPid(); + + // Declare this outside the lock to make absolutely sure the // destructor won't be called with the lock held. sp<Client> client; @@ -133,26 +156,42 @@ void CameraService::removeClient(const sp<ICameraClient>& cameraClient) if (mClient == 0) { // This happens when we have already disconnected. - LOGV("mClient is null."); + LOGD("removeClient (pid %d): already disconnected", callingPid); return; } - // Promote mClient. It should never fail because we're called from - // a binder call, so someone has to have a strong reference. + // Promote mClient. It can fail if we are called from this path: + // Client::~Client() -> disconnect() -> removeClient(). client = mClient.promote(); if (client == 0) { - LOGW("can't get a strong reference on mClient!"); + LOGD("removeClient (pid %d): no more strong reference", callingPid); mClient.clear(); return; } if (cameraClient->asBinder() != client->getCameraClient()->asBinder()) { // ugh! that's not our client!! - LOGW("removeClient() called, but mClient doesn't match!"); + LOGW("removeClient (pid %d): mClient doesn't match!", callingPid); } else { // okay, good, forget about mClient mClient.clear(); } + + LOGD("removeClient (pid %d) done", callingPid); +} + +// The reason we need this count is a new CameraService::connect() request may +// come in while the previous Client's destructor has not been run or is still +// running. If the last strong reference of the previous Client is gone but +// destructor has not been run, we should not allow the new Client to be created +// because we need to wait for the previous Client to tear down the hardware +// first. +void CameraService::incUsers() { + android_atomic_inc(&mUsers); +} + +void CameraService::decUsers() { + android_atomic_dec(&mUsers); } static sp<MediaPlayer> newMediaPlayer(const char *file) @@ -177,7 +216,8 @@ static sp<MediaPlayer> newMediaPlayer(const char *file) CameraService::Client::Client(const sp<CameraService>& cameraService, const sp<ICameraClient>& cameraClient, pid_t clientPid) { - LOGD("Client E constructor"); + int callingPid = getCallingPid(); + LOGD("Client::Client E (pid %d)", callingPid); mCameraService = cameraService; mCameraClient = cameraClient; mClientPid = clientPid; @@ -189,22 +229,28 @@ CameraService::Client::Client(const sp<CameraService>& cameraService, // Callback is disabled by default mPreviewCallbackFlag = FRAME_CALLBACK_FLAG_NOOP; - LOGD("Client X constructor"); + cameraService->incUsers(); + LOGD("Client::Client X (pid %d)", callingPid); } status_t CameraService::Client::checkPid() { - if (mClientPid == IPCThreadState::self()->getCallingPid()) return NO_ERROR; - LOGW("Attempt to use locked camera (%p) from different process", getCameraClient()->asBinder().get()); + int callingPid = getCallingPid(); + if (mClientPid == callingPid) return NO_ERROR; + LOGW("Attempt to use locked camera (client %p) from different process " + " (old pid %d, new pid %d)", + getCameraClient()->asBinder().get(), mClientPid, callingPid); return -EBUSY; } status_t CameraService::Client::lock() { + int callingPid = getCallingPid(); + LOGD("lock from pid %d (mClientPid %d)", callingPid, mClientPid); Mutex::Autolock _l(mLock); // lock camera to this client if the the camera is unlocked if (mClientPid == 0) { - mClientPid = IPCThreadState::self()->getCallingPid(); + mClientPid = callingPid; return NO_ERROR; } // returns NO_ERROR if the client already owns the camera, -EBUSY otherwise @@ -213,13 +259,14 @@ status_t CameraService::Client::lock() status_t CameraService::Client::unlock() { + int callingPid = getCallingPid(); + LOGD("unlock from pid %d (mClientPid %d)", callingPid, mClientPid); Mutex::Autolock _l(mLock); // allow anyone to use camera - LOGD("unlock (%p)", getCameraClient()->asBinder().get()); status_t result = checkPid(); if (result == NO_ERROR) { mClientPid = 0; - + LOGD("clear mCameraClient (pid %d)", callingPid); // we need to remove the reference so that when app goes // away, the reference count goes to 0. mCameraClient.clear(); @@ -229,15 +276,17 @@ status_t CameraService::Client::unlock() status_t CameraService::Client::connect(const sp<ICameraClient>& client) { + int callingPid = getCallingPid(); + // connect a new process to the camera - LOGD("connect (%p)", client->asBinder().get()); + LOGD("Client::connect E (pid %d, client %p)", callingPid, client->asBinder().get()); // I hate this hack, but things get really ugly when the media recorder // service is handing back the camera to the app. The ICameraClient // destructor will be called during the same IPC, making it look like // the remote client is trying to disconnect. This hack temporarily // sets the mClientPid to an invalid pid to prevent the hardware from - // being torn down. + // being torn down. { // hold a reference to the old client or we will deadlock if the client is @@ -246,24 +295,29 @@ status_t CameraService::Client::connect(const sp<ICameraClient>& client) { Mutex::Autolock _l(mLock); if (mClientPid != 0 && checkPid() != NO_ERROR) { - LOGW("Tried to connect to locked camera"); + LOGW("Tried to connect to locked camera (old pid %d, new pid %d)", + mClientPid, callingPid); return -EBUSY; } oldClient = mCameraClient; // did the client actually change? - if (client->asBinder() == mCameraClient->asBinder()) return NO_ERROR; + if (client->asBinder() == mCameraClient->asBinder()) { + LOGD("Connect to the same client"); + return NO_ERROR; + } mCameraClient = client; mClientPid = -1; mPreviewCallbackFlag = FRAME_CALLBACK_FLAG_NOOP; - LOGD("connect new process (%d) to existing camera client", mClientPid); + LOGD("Connect to the new client (pid %d, client %p)", + callingPid, mCameraClient->asBinder().get()); } } // the old client destructor is called when oldClient goes out of scope // now we set the new PID to lock the interface again - mClientPid = IPCThreadState::self()->getCallingPid(); + mClientPid = callingPid; return NO_ERROR; } @@ -280,8 +334,11 @@ static void *unregister_surface(void *arg) CameraService::Client::~Client() { + int callingPid = getCallingPid(); + // tear down client - LOGD("Client (%p) E destructor", getCameraClient()->asBinder().get()); + LOGD("Client::~Client E (pid %d, client %p)", + callingPid, getCameraClient()->asBinder().get()); if (mSurface != 0 && !mUseOverlay) { #if HAVE_ANDROID_OS pthread_t thr; @@ -307,19 +364,21 @@ CameraService::Client::~Client() } // make sure we tear down the hardware - mClientPid = IPCThreadState::self()->getCallingPid(); + mClientPid = callingPid; disconnect(); - LOGD("Client X destructor"); + LOGD("Client::~Client X (pid %d)", mClientPid); } void CameraService::Client::disconnect() { - LOGD("Client (%p) E disconnect from (%d)", - getCameraClient()->asBinder().get(), - IPCThreadState::self()->getCallingPid()); + int callingPid = getCallingPid(); + + LOGD("Client::disconnect() E (pid %d client %p)", + callingPid, getCameraClient()->asBinder().get()); + Mutex::Autolock lock(mLock); if (mClientPid <= 0) { - LOGD("camera is unlocked, don't tear down hardware"); + LOGD("camera is unlocked (mClientPid = %d), don't tear down hardware", mClientPid); return; } if (checkPid() != NO_ERROR) { @@ -327,25 +386,31 @@ void CameraService::Client::disconnect() return; } + // Make sure disconnect() is done once and once only, whether it is called + // from the user directly, or called by the destructor. + if (mHardware == 0) return; + mCameraService->removeClient(mCameraClient); - if (mHardware != 0) { - LOGD("hardware teardown"); - // Before destroying mHardware, we must make sure it's in the - // idle state. - mHardware->stopPreview(); - // Cancel all picture callbacks. - mHardware->cancelPicture(true, true, true); - // Release the hardware resources. - mHardware->release(); - } + + LOGD("hardware teardown"); + // Before destroying mHardware, we must make sure it's in the + // idle state. + mHardware->stopPreview(); + // Cancel all picture callbacks. + mHardware->cancelPicture(true, true, true); + // Release the hardware resources. + mHardware->release(); mHardware.clear(); - LOGD("Client X disconnect"); + + mCameraService->decUsers(); + + LOGD("Client::disconnect() X (pid %d)", callingPid); } // pass the buffered ISurface to the camera service status_t CameraService::Client::setPreviewDisplay(const sp<ISurface>& surface) { - LOGD("setPreviewDisplay(%p)", surface.get()); + LOGD("setPreviewDisplay(%p) (pid %d)", surface.get(), getCallingPid()); Mutex::Autolock lock(mLock); status_t result = checkPid(); if (result != NO_ERROR) return result; @@ -365,7 +430,7 @@ status_t CameraService::Client::setPreviewDisplay(const sp<ISurface>& surface) // preview are handled. void CameraService::Client::setPreviewCallbackFlag(int callback_flag) { - LOGV("setPreviewCallbackFlag"); + LOGV("setPreviewCallbackFlag (pid %d)", getCallingPid()); Mutex::Autolock lock(mLock); if (checkPid() != NO_ERROR) return; mPreviewCallbackFlag = callback_flag; @@ -374,7 +439,9 @@ void CameraService::Client::setPreviewCallbackFlag(int callback_flag) // start preview mode, must call setPreviewDisplay first status_t CameraService::Client::startCameraMode(camera_mode mode) { - LOGD("startCameraMode(%d)", mode); + int callingPid = getCallingPid(); + + LOGD("startCameraMode(%d) (pid %d)", mode, callingPid); /* we cannot call into mHardware with mLock held because * mHardware has callbacks onto us which acquire this lock @@ -405,7 +472,7 @@ status_t CameraService::Client::startCameraMode(camera_mode mode) status_t CameraService::Client::startRecordingMode() { - LOGV("startRecordingMode"); + LOGD("startRecordingMode (pid %d)", getCallingPid()); status_t ret = UNKNOWN_ERROR; @@ -433,7 +500,7 @@ status_t CameraService::Client::startRecordingMode() status_t CameraService::Client::startPreviewMode() { - LOGV("startPreviewMode"); + LOGD("startPreviewMode (pid %d)", getCallingPid()); // if preview has been enabled, nothing needs to be done if (mHardware->previewEnabled()) { @@ -500,11 +567,15 @@ status_t CameraService::Client::startPreviewMode() status_t CameraService::Client::startPreview() { + LOGD("startPreview (pid %d)", getCallingPid()); + return startCameraMode(CAMERA_PREVIEW_MODE); } status_t CameraService::Client::startRecording() { + LOGD("startRecording (pid %d)", getCallingPid()); + if (mMediaPlayerBeep.get() != NULL) { mMediaPlayerBeep->seekTo(0); mMediaPlayerBeep->start(); @@ -515,7 +586,7 @@ status_t CameraService::Client::startRecording() // stop preview mode void CameraService::Client::stopPreview() { - LOGD("stopPreview()"); + LOGD("stopPreview (pid %d)", getCallingPid()); Mutex::Autolock lock(mLock); if (checkPid() != NO_ERROR) return; @@ -537,7 +608,7 @@ void CameraService::Client::stopPreview() // stop recording mode void CameraService::Client::stopRecording() { - LOGV("stopRecording()"); + LOGD("stopRecording (pid %d)", getCallingPid()); Mutex::Autolock lock(mLock); if (checkPid() != NO_ERROR) return; @@ -552,15 +623,13 @@ void CameraService::Client::stopRecording() mMediaPlayerBeep->start(); } mHardware->stopRecording(); - LOGV("stopRecording(), hardware stopped OK"); + LOGD("stopRecording(), hardware stopped OK"); mPreviewBuffer.clear(); } // release a recording frame void CameraService::Client::releaseRecordingFrame(const sp<IMemory>& mem) { - LOGV("releaseRecordingFrame()"); - Mutex::Autolock lock(mLock); if (checkPid() != NO_ERROR) return; @@ -704,7 +773,7 @@ void CameraService::Client::recordingCallback(const sp<IMemory>& mem, void* user // take a picture - image is returned in callback status_t CameraService::Client::autoFocus() { - LOGV("autoFocus"); + LOGD("autoFocus (pid %d)", getCallingPid()); Mutex::Autolock lock(mLock); status_t result = checkPid(); @@ -722,7 +791,7 @@ status_t CameraService::Client::autoFocus() // take a picture - image is returned in callback status_t CameraService::Client::takePicture() { - LOGD("takePicture"); + LOGD("takePicture (pid %d)", getCallingPid()); Mutex::Autolock lock(mLock); status_t result = checkPid(); @@ -920,6 +989,7 @@ void CameraService::Client::postAutoFocus(bool focused) void CameraService::Client::postShutter() { + LOGD("postShutter"); mCameraClient->notifyCallback(CAMERA_MSG_SHUTTER, 0, 0); } @@ -1029,7 +1099,7 @@ status_t CameraService::dump(int fd, const Vector<String16>& args) if (checkCallingPermission(String16("android.permission.DUMP")) == false) { snprintf(buffer, SIZE, "Permission Denial: " "can't dump CameraService from pid=%d, uid=%d\n", - IPCThreadState::self()->getCallingPid(), + getCallingPid(), IPCThreadState::self()->getCallingUid()); result.append(buffer); write(fd, result.string(), result.size()); diff --git a/camera/libcameraservice/CameraService.h b/camera/libcameraservice/CameraService.h index a421fd3..729e539 100644 --- a/camera/libcameraservice/CameraService.h +++ b/camera/libcameraservice/CameraService.h @@ -194,6 +194,11 @@ private: CameraService(); virtual ~CameraService(); + // We use a count for number of clients (shoule only be 0 or 1). + volatile int32_t mUsers; + virtual void incUsers(); + virtual void decUsers(); + mutable Mutex mLock; wp<Client> mClient; diff --git a/include/private/opengles/gl_context.h b/include/private/opengles/gl_context.h index 3b40677..523aed0 100644 --- a/include/private/opengles/gl_context.h +++ b/include/private/opengles/gl_context.h @@ -458,7 +458,7 @@ struct matrix_stack_t { void validate(); matrixf_t& top() { return stack[depth]; } const matrixf_t& top() const { return stack[depth]; } - const uint32_t top_ops() const { return ops[depth]; } + uint32_t top_ops() const { return ops[depth]; } inline bool isRigidBody() const { return !(ops[depth] & ~(OP_TRANSLATE|OP_UNIFORM_SCALE|OP_ROTATE)); } diff --git a/include/ui/Camera.h b/include/ui/Camera.h index 048bdd5..bbc21c4 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 c78b99a..b1f5045 100644 --- a/include/utils/BackupHelpers.h +++ b/include/utils/BackupHelpers.h @@ -43,6 +43,7 @@ struct SnapshotHeader { struct FileState { int modTime_sec; int modTime_nsec; + int mode; int size; int crc32; int nameLen; @@ -71,6 +72,8 @@ public: status_t WriteEntityHeader(const String8& key, size_t dataSize); status_t WriteEntityData(const void* data, size_t size); + void SetKeyPrefix(const String8& keyPrefix); + private: explicit BackupDataWriter(); status_t write_padding_for(int n); @@ -79,6 +82,7 @@ private: status_t m_status; ssize_t m_pos; int m_entityCount; + String8 m_keyPrefix; }; /** @@ -133,6 +137,7 @@ public: private: void* m_buf; + bool m_loggedUnknownMetadata; KeyedVector<String8,FileRec> m_files; }; diff --git a/include/utils/ResourceTypes.h b/include/utils/ResourceTypes.h index 68f9233..f1029b7 100644 --- a/include/utils/ResourceTypes.h +++ b/include/utils/ResourceTypes.h @@ -71,7 +71,7 @@ namespace android { * The relative sizes of the stretchy segments indicates the relative * amount of stretchiness of the regions bordered by the segments. For * example, regions 3, 7 and 11 above will take up more horizontal space - * than regions 1, 5 and 9 since the horizonal segment associated with + * than regions 1, 5 and 9 since the horizontal segment associated with * the first set of regions is larger than the other set of regions. The * ratios of the amount of horizontal (or vertical) space taken by any * two stretchable slices is exactly the ratio of their corresponding @@ -87,7 +87,7 @@ namespace android { * the leftmost slices always start at x=0 and the rightmost slices * always end at the end of the image. So, for example, the regions 0, * 4 and 8 (which are fixed along the X axis) start at x value 0 and - * go to xDiv[0] amd slices 2, 6 and 10 start at xDiv[1] and end at + * go to xDiv[0] and slices 2, 6 and 10 start at xDiv[1] and end at * xDiv[2]. * * The array pointed to by the colors field lists contains hints for @@ -626,25 +626,25 @@ public: event_code_t next(); // These are available for all nodes: - const int32_t getCommentID() const; + int32_t getCommentID() const; const uint16_t* getComment(size_t* outLen) const; - const uint32_t getLineNumber() const; + uint32_t getLineNumber() const; // This is available for TEXT: - const int32_t getTextID() const; + int32_t getTextID() const; const uint16_t* getText(size_t* outLen) const; ssize_t getTextValue(Res_value* outValue) const; // These are available for START_NAMESPACE and END_NAMESPACE: - const int32_t getNamespacePrefixID() const; + int32_t getNamespacePrefixID() const; const uint16_t* getNamespacePrefix(size_t* outLen) const; - const int32_t getNamespaceUriID() const; + int32_t getNamespaceUriID() const; const uint16_t* getNamespaceUri(size_t* outLen) const; // These are available for START_TAG and END_TAG: - const int32_t getElementNamespaceID() const; + int32_t getElementNamespaceID() const; const uint16_t* getElementNamespace(size_t* outLen) const; - const int32_t getElementNameID() const; + int32_t getElementNameID() const; const uint16_t* getElementName(size_t* outLen) const; // Remaining methods are for retrieving information about attributes @@ -653,14 +653,14 @@ public: size_t getAttributeCount() const; // Returns -1 if no namespace, -2 if idx out of range. - const int32_t getAttributeNamespaceID(size_t idx) const; + int32_t getAttributeNamespaceID(size_t idx) const; const uint16_t* getAttributeNamespace(size_t idx, size_t* outLen) const; - const int32_t getAttributeNameID(size_t idx) const; + int32_t getAttributeNameID(size_t idx) const; const uint16_t* getAttributeName(size_t idx, size_t* outLen) const; - const uint32_t getAttributeNameResID(size_t idx) const; + uint32_t getAttributeNameResID(size_t idx) const; - const int32_t getAttributeValueStringID(size_t idx) const; + int32_t getAttributeValueStringID(size_t idx) const; const uint16_t* getAttributeStringValue(size_t idx, size_t* outLen) const; int32_t getAttributeDataType(size_t idx) const; diff --git a/libs/ui/Camera.cpp b/libs/ui/Camera.cpp index 4228300..33b99b9 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/BackupData.cpp b/libs/utils/BackupData.cpp index 6a7f056..0868cff 100644 --- a/libs/utils/BackupData.cpp +++ b/libs/utils/BackupData.cpp @@ -99,10 +99,20 @@ BackupDataWriter::WriteEntityHeader(const String8& key, size_t dataSize) return amt; } + String8 k; + if (m_keyPrefix.length() > 0) { + k = m_keyPrefix; + k += ":"; + k += key; + } else { + k = key; + } + LOGD("m_keyPrefix=%s key=%s k=%s", m_keyPrefix.string(), key.string(), k.string()); + entity_header_v1 header; ssize_t keyLen; - keyLen = key.length(); + keyLen = k.length(); header.type = tolel(BACKUP_HEADER_ENTITY_V1); header.keyLen = tolel(keyLen); @@ -115,7 +125,7 @@ BackupDataWriter::WriteEntityHeader(const String8& key, size_t dataSize) } m_pos += amt; - amt = write(m_fd, key.string(), keyLen+1); + amt = write(m_fd, k.string(), keyLen+1); if (amt != keyLen+1) { m_status = errno; return m_status; @@ -148,6 +158,11 @@ BackupDataWriter::WriteEntityData(const void* data, size_t size) return NO_ERROR; } +void +BackupDataWriter::SetKeyPrefix(const String8& keyPrefix) +{ + m_keyPrefix = keyPrefix; +} BackupDataReader::BackupDataReader(int fd) @@ -298,7 +313,7 @@ BackupDataReader::ReadEntityData(void* data, size_t size) if (remaining <= 0) { return 0; } - if (size > remaining) { + if (((int)size) > remaining) { size = remaining; } //LOGD(" reading %d bytes", size); diff --git a/libs/utils/BackupHelpers.cpp b/libs/utils/BackupHelpers.cpp index d65a457..99a4abc 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; } @@ -302,6 +356,7 @@ back_up_files(int oldSnapshotFD, BackupDataWriter* dataStream, int newSnapshotFD r.s.modTime_sec = st.st_mtime; r.s.modTime_nsec = 0; // workaround sim breakage //r.s.modTime_nsec = st.st_mtime_nsec; + r.s.mode = st.st_mode; r.s.size = st.st_size; // we compute the crc32 later down below, when we already have the file open. @@ -349,13 +404,13 @@ back_up_files(int oldSnapshotFD, BackupDataWriter* dataStream, int newSnapshotFD g.s.crc32 = compute_crc32(fd); LOGP("%s", q.string()); - LOGP(" new: modTime=%d,%d size=%-3d crc32=0x%08x", - f.modTime_sec, f.modTime_nsec, f.size, f.crc32); - LOGP(" old: modTime=%d,%d size=%-3d crc32=0x%08x", - g.s.modTime_sec, g.s.modTime_nsec, g.s.size, g.s.crc32); + LOGP(" new: modTime=%d,%d mode=%04o size=%-3d crc32=0x%08x", + f.modTime_sec, f.modTime_nsec, f.mode, f.size, f.crc32); + LOGP(" old: modTime=%d,%d mode=%04o size=%-3d crc32=0x%08x", + 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.size != g.s.size || f.crc32 != g.s.crc32) { - write_update_file(dataStream, fd, p, g.file.string()); + || f.mode != g.s.mode || f.size != g.s.size || f.crc32 != g.s.crc32) { + write_update_file(dataStream, fd, g.s.mode, p, g.file.string()); } close(fd); @@ -389,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() @@ -415,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); @@ -450,6 +523,7 @@ RestoreHelperBase::WriteFile(const String8& filename, BackupDataReader* in) r.s.modTime_sec = st.st_mtime; r.s.modTime_nsec = 0; // workaround sim breakage //r.s.modTime_nsec = st.st_mtime_nsec; + r.s.mode = st.st_mode; r.s.size = st.st_size; r.s.crc32 = crc; @@ -536,6 +610,7 @@ compare_file(const char* path, const unsigned char* data, int len) } } + free(contents); return contentsMatch && sizesMatch ? 0 : 1; } @@ -623,6 +698,7 @@ backup_helper_test_four() states[0].modTime_sec = 0xfedcba98; states[0].modTime_nsec = 0xdeadbeef; + states[0].mode = 0777; // decimal 511, hex 0x000001ff states[0].size = 0xababbcbc; states[0].crc32 = 0x12345678; states[0].nameLen = -12; @@ -632,6 +708,7 @@ backup_helper_test_four() states[1].modTime_sec = 0x93400031; states[1].modTime_nsec = 0xdeadbeef; + states[1].mode = 0666; // decimal 438, hex 0x000001b6 states[1].size = 0x88557766; states[1].crc32 = 0x22334422; states[1].nameLen = -1; @@ -641,6 +718,7 @@ backup_helper_test_four() states[2].modTime_sec = 0x33221144; states[2].modTime_nsec = 0xdeadbeef; + states[2].mode = 0744; // decimal 484, hex 0x000001e4 states[2].size = 0x11223344; states[2].crc32 = 0x01122334; states[2].nameLen = 0; @@ -650,6 +728,7 @@ backup_helper_test_four() states[3].modTime_sec = 0x33221144; states[3].modTime_nsec = 0xdeadbeef; + states[3].mode = 0755; // decimal 493, hex 0x000001ed states[3].size = 0x11223344; states[3].crc32 = 0x01122334; states[3].nameLen = 0; @@ -669,35 +748,38 @@ backup_helper_test_four() static const unsigned char correct_data[] = { // header 0x53, 0x6e, 0x61, 0x70, 0x04, 0x00, 0x00, 0x00, - 0x46, 0x69, 0x6c, 0x65, 0xac, 0x00, 0x00, 0x00, + 0x46, 0x69, 0x6c, 0x65, 0xbc, 0x00, 0x00, 0x00, // bytes_of_padding 0x98, 0xba, 0xdc, 0xfe, 0xef, 0xbe, 0xad, 0xde, - 0xbc, 0xbc, 0xab, 0xab, 0x78, 0x56, 0x34, 0x12, - 0x10, 0x00, 0x00, 0x00, 0x62, 0x79, 0x74, 0x65, - 0x73, 0x5f, 0x6f, 0x66, 0x5f, 0x70, 0x61, 0x64, - 0x64, 0x69, 0x6e, 0x67, + 0xff, 0x01, 0x00, 0x00, 0xbc, 0xbc, 0xab, 0xab, + 0x78, 0x56, 0x34, 0x12, 0x10, 0x00, 0x00, 0x00, + 0x62, 0x79, 0x74, 0x65, 0x73, 0x5f, 0x6f, 0x66, + 0x5f, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, // bytes_of_padding3 0x31, 0x00, 0x40, 0x93, 0xef, 0xbe, 0xad, 0xde, - 0x66, 0x77, 0x55, 0x88, 0x22, 0x44, 0x33, 0x22, - 0x11, 0x00, 0x00, 0x00, 0x62, 0x79, 0x74, 0x65, - 0x73, 0x5f, 0x6f, 0x66, 0x5f, 0x70, 0x61, 0x64, - 0x64, 0x69, 0x6e, 0x67, 0x33, 0xab, 0xab, 0xab, + 0xb6, 0x01, 0x00, 0x00, 0x66, 0x77, 0x55, 0x88, + 0x22, 0x44, 0x33, 0x22, 0x11, 0x00, 0x00, 0x00, + 0x62, 0x79, 0x74, 0x65, 0x73, 0x5f, 0x6f, 0x66, + 0x5f, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, + 0x33, 0xab, 0xab, 0xab, // bytes of padding2 0x44, 0x11, 0x22, 0x33, 0xef, 0xbe, 0xad, 0xde, - 0x44, 0x33, 0x22, 0x11, 0x34, 0x23, 0x12, 0x01, - 0x12, 0x00, 0x00, 0x00, 0x62, 0x79, 0x74, 0x65, - 0x73, 0x5f, 0x6f, 0x66, 0x5f, 0x70, 0x61, 0x64, - 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x32, 0xab, 0xab, + 0xe4, 0x01, 0x00, 0x00, 0x44, 0x33, 0x22, 0x11, + 0x34, 0x23, 0x12, 0x01, 0x12, 0x00, 0x00, 0x00, + 0x62, 0x79, 0x74, 0x65, 0x73, 0x5f, 0x6f, 0x66, + 0x5f, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, + 0x5f, 0x32, 0xab, 0xab, // bytes of padding3 0x44, 0x11, 0x22, 0x33, 0xef, 0xbe, 0xad, 0xde, - 0x44, 0x33, 0x22, 0x11, 0x34, 0x23, 0x12, 0x01, - 0x13, 0x00, 0x00, 0x00, 0x62, 0x79, 0x74, 0x65, - 0x73, 0x5f, 0x6f, 0x66, 0x5f, 0x70, 0x61, 0x64, - 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x5f, 0x31, 0xab + 0xed, 0x01, 0x00, 0x00, 0x44, 0x33, 0x22, 0x11, + 0x34, 0x23, 0x12, 0x01, 0x13, 0x00, 0x00, 0x00, + 0x62, 0x79, 0x74, 0x65, 0x73, 0x5f, 0x6f, 0x66, + 0x5f, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, + 0x5f, 0x5f, 0x31, 0xab }; err = compare_file(filename, correct_data, sizeof(correct_data)); @@ -731,14 +813,14 @@ backup_helper_test_four() const FileState state = readSnapshot.valueAt(i); if (name != filenames[i] || states[i].modTime_sec != state.modTime_sec - || states[i].modTime_nsec != state.modTime_nsec + || states[i].modTime_nsec != state.modTime_nsec || states[i].mode != state.mode || states[i].size != state.size || states[i].crc32 != states[i].crc32) { - fprintf(stderr, "state %d expected={%d/%d, 0x%08x, 0x%08x, %3d} '%s'\n" - " actual={%d/%d, 0x%08x, 0x%08x, %3d} '%s'\n", i, - states[i].modTime_sec, states[i].modTime_nsec, states[i].size, states[i].crc32, - name.length(), filenames[i].string(), - state.modTime_sec, state.modTime_nsec, state.size, state.crc32, state.nameLen, - name.string()); + fprintf(stderr, "state %d expected={%d/%d, 0x%08x, %04o, 0x%08x, %3d} '%s'\n" + " actual={%d/%d, 0x%08x, %04o, 0x%08x, %3d} '%s'\n", i, + states[i].modTime_sec, states[i].modTime_nsec, states[i].mode, states[i].size, + states[i].crc32, name.length(), filenames[i].string(), + state.modTime_sec, state.modTime_nsec, state.mode, state.size, state.crc32, + state.nameLen, name.string()); matched = false; } } @@ -839,6 +921,7 @@ test_read_header_and_entity(BackupDataReader& reader, const char* str) size_t actualSize; bool done; int type; + ssize_t nRead; // printf("\n\n---------- test_read_header_and_entity -- %s\n\n", str); @@ -873,8 +956,9 @@ test_read_header_and_entity(BackupDataReader& reader, const char* str) goto finished; } - err = reader.ReadEntityData(buf, bufSize); - if (err != NO_ERROR) { + nRead = reader.ReadEntityData(buf, bufSize); + if (nRead < 0) { + err = reader.Status(); fprintf(stderr, "ReadEntityData failed with %s\n", strerror(err)); goto finished; } diff --git a/libs/utils/ResourceTypes.cpp b/libs/utils/ResourceTypes.cpp index 69d47f0..e4f9f0f 100644 --- a/libs/utils/ResourceTypes.cpp +++ b/libs/utils/ResourceTypes.cpp @@ -544,7 +544,7 @@ ResXMLParser::event_code_t ResXMLParser::next() return mEventCode; } -const int32_t ResXMLParser::getCommentID() const +int32_t ResXMLParser::getCommentID() const { return mCurNode != NULL ? dtohl(mCurNode->comment.index) : -1; } @@ -555,12 +555,12 @@ const uint16_t* ResXMLParser::getComment(size_t* outLen) const return id >= 0 ? mTree.mStrings.stringAt(id, outLen) : NULL; } -const uint32_t ResXMLParser::getLineNumber() const +uint32_t ResXMLParser::getLineNumber() const { return mCurNode != NULL ? dtohl(mCurNode->lineNumber) : -1; } -const int32_t ResXMLParser::getTextID() const +int32_t ResXMLParser::getTextID() const { if (mEventCode == TEXT) { return dtohl(((const ResXMLTree_cdataExt*)mCurExt)->data.index); @@ -583,7 +583,7 @@ ssize_t ResXMLParser::getTextValue(Res_value* outValue) const return BAD_TYPE; } -const int32_t ResXMLParser::getNamespacePrefixID() const +int32_t ResXMLParser::getNamespacePrefixID() const { if (mEventCode == START_NAMESPACE || mEventCode == END_NAMESPACE) { return dtohl(((const ResXMLTree_namespaceExt*)mCurExt)->prefix.index); @@ -598,7 +598,7 @@ const uint16_t* ResXMLParser::getNamespacePrefix(size_t* outLen) const return id >= 0 ? mTree.mStrings.stringAt(id, outLen) : NULL; } -const int32_t ResXMLParser::getNamespaceUriID() const +int32_t ResXMLParser::getNamespaceUriID() const { if (mEventCode == START_NAMESPACE || mEventCode == END_NAMESPACE) { return dtohl(((const ResXMLTree_namespaceExt*)mCurExt)->uri.index); @@ -613,7 +613,7 @@ const uint16_t* ResXMLParser::getNamespaceUri(size_t* outLen) const return id >= 0 ? mTree.mStrings.stringAt(id, outLen) : NULL; } -const int32_t ResXMLParser::getElementNamespaceID() const +int32_t ResXMLParser::getElementNamespaceID() const { if (mEventCode == START_TAG) { return dtohl(((const ResXMLTree_attrExt*)mCurExt)->ns.index); @@ -630,7 +630,7 @@ const uint16_t* ResXMLParser::getElementNamespace(size_t* outLen) const return id >= 0 ? mTree.mStrings.stringAt(id, outLen) : NULL; } -const int32_t ResXMLParser::getElementNameID() const +int32_t ResXMLParser::getElementNameID() const { if (mEventCode == START_TAG) { return dtohl(((const ResXMLTree_attrExt*)mCurExt)->name.index); @@ -655,7 +655,7 @@ size_t ResXMLParser::getAttributeCount() const return 0; } -const int32_t ResXMLParser::getAttributeNamespaceID(size_t idx) const +int32_t ResXMLParser::getAttributeNamespaceID(size_t idx) const { if (mEventCode == START_TAG) { const ResXMLTree_attrExt* tag = (const ResXMLTree_attrExt*)mCurExt; @@ -678,7 +678,7 @@ const uint16_t* ResXMLParser::getAttributeNamespace(size_t idx, size_t* outLen) return id >= 0 ? mTree.mStrings.stringAt(id, outLen) : NULL; } -const int32_t ResXMLParser::getAttributeNameID(size_t idx) const +int32_t ResXMLParser::getAttributeNameID(size_t idx) const { if (mEventCode == START_TAG) { const ResXMLTree_attrExt* tag = (const ResXMLTree_attrExt*)mCurExt; @@ -701,7 +701,7 @@ const uint16_t* ResXMLParser::getAttributeName(size_t idx, size_t* outLen) const return id >= 0 ? mTree.mStrings.stringAt(id, outLen) : NULL; } -const uint32_t ResXMLParser::getAttributeNameResID(size_t idx) const +uint32_t ResXMLParser::getAttributeNameResID(size_t idx) const { int32_t id = getAttributeNameID(idx); if (id >= 0 && (size_t)id < mTree.mNumResIds) { @@ -710,7 +710,7 @@ const uint32_t ResXMLParser::getAttributeNameResID(size_t idx) const return 0; } -const int32_t ResXMLParser::getAttributeValueStringID(size_t idx) const +int32_t ResXMLParser::getAttributeValueStringID(size_t idx) const { if (mEventCode == START_TAG) { const ResXMLTree_attrExt* tag = (const ResXMLTree_attrExt*)mCurExt; diff --git a/opengl/libagl/texture.cpp b/opengl/libagl/texture.cpp index 05fd46e..d767c31 100644 --- a/opengl/libagl/texture.cpp +++ b/opengl/libagl/texture.cpp @@ -997,7 +997,7 @@ void glTexParameteriv( memcpy(textureObject->crop_rect, params, 4*sizeof(GLint)); break; default: - ogles_error(c, GL_INVALID_ENUM); + texParameterx(target, pname, GLfixed(params[0]), c); return; } } @@ -1016,6 +1016,13 @@ void glTexParameterx( texParameterx(target, pname, param, c); } +void glTexParameteri( + GLenum target, GLenum pname, GLint param) +{ + ogles_context_t* c = ogles_context_t::get(); + texParameterx(target, pname, GLfixed(param), c); +} + // ---------------------------------------------------------------------------- #if 0 #pragma mark - diff --git a/opengl/tests/angeles/Android.mk b/opengl/tests/angeles/Android.mk index 46958d3..e193483 100644 --- a/opengl/tests/angeles/Android.mk +++ b/opengl/tests/angeles/Android.mk @@ -5,7 +5,7 @@ include $(CLEAR_VARS) LOCAL_SRC_FILES:= app-linux.c demo.c.arm LOCAL_SHARED_LIBRARIES := libEGL libGLESv1_CM libui LOCAL_MODULE:= angeles -LOCAL_MODULE_TAGS := tests +LOCAL_MODULE_TAGS := optional include $(BUILD_EXECUTABLE) @@ -13,5 +13,5 @@ include $(CLEAR_VARS) LOCAL_SRC_FILES:= gpustate.c LOCAL_SHARED_LIBRARIES := libEGL libGLESv1_CM LOCAL_MODULE:= gpustate -LOCAL_MODULE_TAGS := tests +LOCAL_MODULE_TAGS := optional include $(BUILD_EXECUTABLE) diff --git a/opengl/tests/filter/Android.mk b/opengl/tests/filter/Android.mk index a448f0d..31b7d9a 100644 --- a/opengl/tests/filter/Android.mk +++ b/opengl/tests/filter/Android.mk @@ -12,6 +12,6 @@ LOCAL_SHARED_LIBRARIES := \ LOCAL_MODULE:= test-opengl-filter -LOCAL_MODULE_TAGS := tests +LOCAL_MODULE_TAGS := optional include $(BUILD_EXECUTABLE) diff --git a/opengl/tests/finish/Android.mk b/opengl/tests/finish/Android.mk index 26836c1..8b46cd7 100644 --- a/opengl/tests/finish/Android.mk +++ b/opengl/tests/finish/Android.mk @@ -12,6 +12,6 @@ LOCAL_SHARED_LIBRARIES := \ LOCAL_MODULE:= test-opengl-finish -LOCAL_MODULE_TAGS := tests +LOCAL_MODULE_TAGS := optional include $(BUILD_EXECUTABLE) diff --git a/opengl/tests/textures/Android.mk b/opengl/tests/textures/Android.mk index a8c6220..8d5f56d 100644 --- a/opengl/tests/textures/Android.mk +++ b/opengl/tests/textures/Android.mk @@ -12,6 +12,6 @@ LOCAL_SHARED_LIBRARIES := \ LOCAL_MODULE:= test-opengl-textures -LOCAL_MODULE_TAGS := tests +LOCAL_MODULE_TAGS := optional include $(BUILD_EXECUTABLE) diff --git a/opengl/tests/tritex/Android.mk b/opengl/tests/tritex/Android.mk index 5cd1f04..76fd8dd 100644 --- a/opengl/tests/tritex/Android.mk +++ b/opengl/tests/tritex/Android.mk @@ -12,6 +12,6 @@ LOCAL_SHARED_LIBRARIES := \ LOCAL_MODULE:= test-opengl-tritex -LOCAL_MODULE_TAGS := tests +LOCAL_MODULE_TAGS := optional include $(BUILD_EXECUTABLE) |