Merge commit '79edadcea74151b573d5b973d5a421baee693ec1' from
oc-mr1-dev-plus-aosp into stage-aosp-master
Change-Id: I04234f284e3117e8343e7c888646400c81f5a131
Merged-In: Icf228c701afe37dd3c7f00ea9e6fb740b0d450f1
diff --git a/Android.bp b/Android.bp
index a3679b1..e4f12c8 100644
--- a/Android.bp
+++ b/Android.bp
@@ -2,5 +2,6 @@
"camera",
"drm/*",
"media/*",
+ "services/*",
"soundtrigger",
]
diff --git a/camera/ndk/impl/ACameraDevice.cpp b/camera/ndk/impl/ACameraDevice.cpp
index af977b8..907802c 100644
--- a/camera/ndk/impl/ACameraDevice.cpp
+++ b/camera/ndk/impl/ACameraDevice.cpp
@@ -59,7 +59,8 @@
mWrapper(wrapper),
mInError(false),
mError(ACAMERA_OK),
- mIdle(true) {
+ mIdle(true),
+ mCurrentSession(nullptr) {
mClosing = false;
// Setup looper thread to perfrom device callbacks to app
mCbLooper = new ALooper;
@@ -98,18 +99,30 @@
// Device close implementaiton
CameraDevice::~CameraDevice() {
- Mutex::Autolock _l(mDeviceLock);
- if (!isClosed()) {
- disconnectLocked();
- }
- if (mCbLooper != nullptr) {
- mCbLooper->unregisterHandler(mHandler->id());
- mCbLooper->stop();
+ sp<ACameraCaptureSession> session = mCurrentSession.promote();
+ {
+ Mutex::Autolock _l(mDeviceLock);
+ if (!isClosed()) {
+ disconnectLocked(session);
+ }
+ mCurrentSession = nullptr;
+ if (mCbLooper != nullptr) {
+ mCbLooper->unregisterHandler(mHandler->id());
+ mCbLooper->stop();
+ }
}
mCbLooper.clear();
mHandler.clear();
}
+void
+CameraDevice::postSessionMsgAndCleanup(sp<AMessage>& msg) {
+ msg->post();
+ msg.clear();
+ sp<AMessage> cleanupMsg = new AMessage(kWhatCleanUpSessions, mHandler);
+ cleanupMsg->post();
+}
+
// TODO: cached created request?
camera_status_t
CameraDevice::createCaptureRequest(
@@ -146,14 +159,15 @@
const ACaptureSessionOutputContainer* outputs,
const ACameraCaptureSession_stateCallbacks* callbacks,
/*out*/ACameraCaptureSession** session) {
+ sp<ACameraCaptureSession> currentSession = mCurrentSession.promote();
Mutex::Autolock _l(mDeviceLock);
camera_status_t ret = checkCameraClosedOrErrorLocked();
if (ret != ACAMERA_OK) {
return ret;
}
- if (mCurrentSession != nullptr) {
- mCurrentSession->closeByDevice();
+ if (currentSession != nullptr) {
+ currentSession->closeByDevice();
stopRepeatingLocked();
}
@@ -264,7 +278,7 @@
msg->setPointer(kContextKey, session->mUserSessionCallback.context);
msg->setObject(kSessionSpKey, session);
msg->setPointer(kCallbackFpKey, (void*) session->mUserSessionCallback.onActive);
- msg->post();
+ postSessionMsgAndCleanup(msg);
}
mIdle = false;
mBusySession = session;
@@ -328,7 +342,7 @@
return;
}
- if (session != mCurrentSession) {
+ if (mCurrentSession != session) {
// Session has been replaced by other seesion or device is closed
return;
}
@@ -349,7 +363,7 @@
}
void
-CameraDevice::disconnectLocked() {
+CameraDevice::disconnectLocked(sp<ACameraCaptureSession>& session) {
if (mClosing.exchange(true)) {
// Already closing, just return
ALOGW("Camera device %s is already closing.", getId());
@@ -361,9 +375,8 @@
}
mRemote = nullptr;
- if (mCurrentSession != nullptr) {
- mCurrentSession->closeByDevice();
- mCurrentSession = nullptr;
+ if (session != nullptr) {
+ session->closeByDevice();
}
}
@@ -404,7 +417,7 @@
// This should never happen because creating a new session will close
// previous one and thus reject any API call from previous session.
// But still good to check here in case something unexpected happen.
- if (session != mCurrentSession) {
+ if (mCurrentSession != session) {
ALOGE("Camera %s session %p is not current active session!", getId(), session);
return ACAMERA_ERROR_INVALID_OPERATION;
}
@@ -415,12 +428,13 @@
}
mFlushing = true;
+
// Send onActive callback to guarantee there is always active->ready transition
sp<AMessage> msg = new AMessage(kWhatSessionStateCb, mHandler);
msg->setPointer(kContextKey, session->mUserSessionCallback.context);
msg->setObject(kSessionSpKey, session);
msg->setPointer(kCallbackFpKey, (void*) session->mUserSessionCallback.onActive);
- msg->post();
+ postSessionMsgAndCleanup(msg);
// If device is already idling, send callback and exit early
if (mIdle) {
@@ -428,7 +442,7 @@
msg->setPointer(kContextKey, session->mUserSessionCallback.context);
msg->setObject(kSessionSpKey, session);
msg->setPointer(kCallbackFpKey, (void*) session->mUserSessionCallback.onReady);
- msg->post();
+ postSessionMsgAndCleanup(msg);
mFlushing = false;
return ACAMERA_OK;
}
@@ -568,7 +582,7 @@
msg->setObject(kSessionSpKey, mBusySession);
msg->setPointer(kCallbackFpKey, (void*) mBusySession->mUserSessionCallback.onReady);
mBusySession.clear();
- msg->post();
+ postSessionMsgAndCleanup(msg);
}
mIdle = true;
@@ -728,7 +742,7 @@
msg->setObject(kCaptureRequestKey, request);
msg->setPointer(kAnwKey, (void*) anw);
msg->setInt64(kFrameNumberKey, frameNumber);
- msg->post();
+ postSessionMsgAndCleanup(msg);
} else { // Handle other capture failures
// Fire capture failure callback if there is one registered
ACameraCaptureSession_captureCallback_failed onError = cbh.mCallbacks.onCaptureFailed;
@@ -746,7 +760,7 @@
msg->setPointer(kCallbackFpKey, (void*) onError);
msg->setObject(kCaptureRequestKey, request);
msg->setObject(kCaptureFailureKey, failure);
- msg->post();
+ postSessionMsgAndCleanup(msg);
// Update tracker
mFrameNumberTracker.updateTracker(frameNumber, /*isError*/true);
@@ -769,6 +783,9 @@
case kWhatCaptureBufferLost:
ALOGV("%s: Received msg %d", __FUNCTION__, msg->what());
break;
+ case kWhatCleanUpSessions:
+ mCachedSessions.clear();
+ return;
default:
ALOGE("%s:Error: unknown device callback %d", __FUNCTION__, msg->what());
return;
@@ -842,6 +859,7 @@
return;
}
sp<ACameraCaptureSession> session(static_cast<ACameraCaptureSession*>(obj.get()));
+ mCachedSessions.push(session);
sp<CaptureRequest> requestSp = nullptr;
switch (msg->what()) {
case kWhatCaptureStart:
@@ -1053,7 +1071,7 @@
msg->setObject(kSessionSpKey, cbh.mSession);
msg->setPointer(kCallbackFpKey, (void*) cbh.mCallbacks.onCaptureSequenceAborted);
msg->setInt32(kSequenceIdKey, sequenceId);
- msg->post();
+ postSessionMsgAndCleanup(msg);
} else {
// Use mSequenceLastFrameNumberMap to track
mSequenceLastFrameNumberMap.insert(std::make_pair(sequenceId, lastFrameNumber));
@@ -1110,7 +1128,7 @@
// before cbh goes out of scope and causing we call the session
// destructor while holding device lock
cbh.mSession.clear();
- msg->post();
+ postSessionMsgAndCleanup(msg);
}
// No need to track sequence complete if there is no callback registered
@@ -1137,6 +1155,7 @@
return ret; // device has been closed
}
+ sp<ACameraCaptureSession> session = dev->mCurrentSession.promote();
Mutex::Autolock _l(dev->mDeviceLock);
if (dev->mRemote == nullptr) {
return ret; // device has been closed
@@ -1145,10 +1164,10 @@
case ERROR_CAMERA_DISCONNECTED:
{
// Camera is disconnected, close the session and expect no more callbacks
- if (dev->mCurrentSession != nullptr) {
- dev->mCurrentSession->closeByDevice();
- dev->mCurrentSession = nullptr;
+ if (session != nullptr) {
+ session->closeByDevice();
}
+ dev->mCurrentSession = nullptr;
sp<AMessage> msg = new AMessage(kWhatOnDisconnected, dev->mHandler);
msg->setPointer(kContextKey, dev->mAppCallbacks.context);
msg->setPointer(kDeviceKey, (void*) dev->getWrapper());
@@ -1216,6 +1235,7 @@
dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
return ret;
}
+
sp<AMessage> msg = new AMessage(kWhatSessionStateCb, dev->mHandler);
msg->setPointer(kContextKey, dev->mBusySession->mUserSessionCallback.context);
msg->setObject(kSessionSpKey, dev->mBusySession);
@@ -1223,7 +1243,7 @@
// Make sure we clear the sp first so the session destructor can
// only happen on handler thread (where we don't hold device/session lock)
dev->mBusySession.clear();
- msg->post();
+ dev->postSessionMsgAndCleanup(msg);
}
dev->mIdle = true;
dev->mFlushing = false;
@@ -1265,7 +1285,7 @@
msg->setPointer(kCallbackFpKey, (void*) onStart);
msg->setObject(kCaptureRequestKey, request);
msg->setInt64(kTimeStampKey, timestamp);
- msg->post();
+ dev->postSessionMsgAndCleanup(msg);
}
return ret;
}
@@ -1328,7 +1348,7 @@
msg->setPointer(kCallbackFpKey, (void*) onResult);
msg->setObject(kCaptureRequestKey, request);
msg->setObject(kCaptureResultKey, result);
- msg->post();
+ dev->postSessionMsgAndCleanup(msg);
}
if (!isPartialResult) {
diff --git a/camera/ndk/impl/ACameraDevice.h b/camera/ndk/impl/ACameraDevice.h
index 78a7891..6ed3881 100644
--- a/camera/ndk/impl/ACameraDevice.h
+++ b/camera/ndk/impl/ACameraDevice.h
@@ -96,7 +96,7 @@
// device goes into fatal error state after this
void setCameraDeviceErrorLocked(camera_status_t error);
- void disconnectLocked(); // disconnect from camera service
+ void disconnectLocked(sp<ACameraCaptureSession>& session); // disconnect from camera service
camera_status_t stopRepeatingLocked();
@@ -138,6 +138,9 @@
camera_status_t configureStreamsLocked(const ACaptureSessionOutputContainer* outputs);
+ // Input message will be posted and cleared after this returns
+ void postSessionMsgAndCleanup(sp<AMessage>& msg);
+
static camera_status_t getIGBPfromAnw(
ANativeWindow* anw, sp<IGraphicBufferProducer>& out);
@@ -185,7 +188,9 @@
kWhatCaptureFail, // onCaptureFailed
kWhatCaptureSeqEnd, // onCaptureSequenceCompleted
kWhatCaptureSeqAbort, // onCaptureSequenceAborted
- kWhatCaptureBufferLost // onCaptureBufferLost
+ kWhatCaptureBufferLost,// onCaptureBufferLost
+ // Internal cleanup
+ kWhatCleanUpSessions // Cleanup cached sp<ACameraCaptureSession>
};
static const char* kContextKey;
static const char* kDeviceKey;
@@ -199,10 +204,16 @@
static const char* kSequenceIdKey;
static const char* kFrameNumberKey;
static const char* kAnwKey;
+
class CallbackHandler : public AHandler {
public:
- CallbackHandler() {}
void onMessageReceived(const sp<AMessage> &msg) override;
+
+ private:
+ // This handler will cache all capture session sp until kWhatCleanUpSessions
+ // is processed. This is used to guarantee the last session reference is always
+ // being removed in callback thread without holding camera device lock
+ Vector<sp<ACameraCaptureSession>> mCachedSessions;
};
sp<CallbackHandler> mHandler;
@@ -210,7 +221,7 @@
* Capture session related members *
***********************************/
// The current active session
- ACameraCaptureSession* mCurrentSession = nullptr;
+ wp<ACameraCaptureSession> mCurrentSession;
bool mFlushing = false;
int mNextSessionId = 0;
diff --git a/camera/ndk/include/camera/NdkCameraDevice.h b/camera/ndk/include/camera/NdkCameraDevice.h
index 9b7f6f4..6c9e85a 100644
--- a/camera/ndk/include/camera/NdkCameraDevice.h
+++ b/camera/ndk/include/camera/NdkCameraDevice.h
@@ -90,18 +90,18 @@
};
/**
- * Camera device state callbacks to be used in {@link ACameraDevice_stateCallbacks}.
+ * Camera device state callbacks to be used in {@link ACameraDevice_StateCallbacks}.
*
- * @param context The optional context in {@link ACameraDevice_stateCallbacks} will be
+ * @param context The optional context in {@link ACameraDevice_StateCallbacks} will be
* passed to this callback.
* @param device The {@link ACameraDevice} that is being disconnected.
*/
typedef void (*ACameraDevice_StateCallback)(void* context, ACameraDevice* device);
/**
- * Camera device error state callbacks to be used in {@link ACameraDevice_stateCallbacks}.
+ * Camera device error state callbacks to be used in {@link ACameraDevice_StateCallbacks}.
*
- * @param context The optional context in {@link ACameraDevice_stateCallbacks} will be
+ * @param context The optional context in {@link ACameraDevice_StateCallbacks} will be
* passed to this callback.
* @param device The {@link ACameraDevice} that is being disconnected.
* @param error The error code describes the cause of this error callback. See the folowing
@@ -150,7 +150,7 @@
*
*/
ACameraDevice_ErrorStateCallback onError;
-} ACameraDevice_stateCallbacks;
+} ACameraDevice_StateCallbacks;
/**
* Close the connection and free this ACameraDevice synchronously. Access to the ACameraDevice
diff --git a/camera/ndk/include/camera/NdkCameraManager.h b/camera/ndk/include/camera/NdkCameraManager.h
index 5b5c98b..e5b3ad8 100644
--- a/camera/ndk/include/camera/NdkCameraManager.h
+++ b/camera/ndk/include/camera/NdkCameraManager.h
@@ -232,18 +232,18 @@
* priority when accessing the camera, and this method will succeed even if the camera device is
* in use by another camera API client. Any lower-priority application that loses control of the
* camera in this way will receive an
- * {@link ACameraDevice_stateCallbacks#onDisconnected} callback.</p>
+ * {@link ACameraDevice_StateCallbacks#onDisconnected} callback.</p>
*
* <p>Once the camera is successfully opened,the ACameraDevice can then be set up
* for operation by calling {@link ACameraDevice_createCaptureSession} and
* {@link ACameraDevice_createCaptureRequest}.</p>
*
* <p>If the camera becomes disconnected after this function call returns,
- * {@link ACameraDevice_stateCallbacks#onDisconnected} with a
+ * {@link ACameraDevice_StateCallbacks#onDisconnected} with a
* ACameraDevice in the disconnected state will be called.</p>
*
* <p>If the camera runs into error after this function call returns,
- * {@link ACameraDevice_stateCallbacks#onError} with a
+ * {@link ACameraDevice_StateCallbacks#onError} with a
* ACameraDevice in the error state will be called.</p>
*
* @param manager the {@link ACameraManager} of interest.
diff --git a/drm/common/Android.bp b/drm/common/Android.bp
index 0098c89..1552c3f 100644
--- a/drm/common/Android.bp
+++ b/drm/common/Android.bp
@@ -33,6 +33,8 @@
"ReadWriteUtils.cpp",
],
+ cflags: ["-Wall", "-Werror"],
+
static_libs: ["libbinder"],
export_include_dirs: ["include"],
diff --git a/drm/libdrmframework/plugins/common/util/Android.bp b/drm/libdrmframework/plugins/common/util/Android.bp
index 0c0b6f2..7372eb7 100644
--- a/drm/libdrmframework/plugins/common/util/Android.bp
+++ b/drm/libdrmframework/plugins/common/util/Android.bp
@@ -19,5 +19,7 @@
srcs: ["src/MimeTypeUtil.cpp"],
+ cflags: ["-Wall", "-Werror"],
+
export_include_dirs: ["include"],
}
diff --git a/drm/libdrmframework/plugins/forward-lock/FwdLockEngine/Android.bp b/drm/libdrmframework/plugins/forward-lock/FwdLockEngine/Android.bp
index 3f0f5f7..28a78aa 100644
--- a/drm/libdrmframework/plugins/forward-lock/FwdLockEngine/Android.bp
+++ b/drm/libdrmframework/plugins/forward-lock/FwdLockEngine/Android.bp
@@ -21,6 +21,9 @@
"-DUSE_64BIT_DRM_API",
// The flag below turns on local debug printouts
//"-DDRM_OMA_FL_ENGINE_DEBUG",
+ "-Wall",
+ "-Werror",
+ "-Wno-unused-variable",
],
srcs: ["src/FwdLockEngine.cpp"],
diff --git a/drm/libdrmframework/plugins/forward-lock/internal-format/common/Android.bp b/drm/libdrmframework/plugins/forward-lock/internal-format/common/Android.bp
index 698f278..3be327a 100644
--- a/drm/libdrmframework/plugins/forward-lock/internal-format/common/Android.bp
+++ b/drm/libdrmframework/plugins/forward-lock/internal-format/common/Android.bp
@@ -19,6 +19,8 @@
srcs: ["FwdLockGlue.c"],
+ cflags: ["-Wall", "-Werror"],
+
shared_libs: ["libcrypto"],
export_include_dirs: ["."],
diff --git a/drm/libdrmframework/plugins/forward-lock/internal-format/converter/Android.bp b/drm/libdrmframework/plugins/forward-lock/internal-format/converter/Android.bp
index 33f2fe0..d4e04b8 100644
--- a/drm/libdrmframework/plugins/forward-lock/internal-format/converter/Android.bp
+++ b/drm/libdrmframework/plugins/forward-lock/internal-format/converter/Android.bp
@@ -19,6 +19,8 @@
srcs: ["FwdLockConv.c"],
+ cflags: ["-Wall", "-Werror"],
+
shared_libs: ["libcrypto"],
static_libs: ["libfwdlock-common"],
diff --git a/drm/libdrmframework/plugins/forward-lock/internal-format/decoder/Android.bp b/drm/libdrmframework/plugins/forward-lock/internal-format/decoder/Android.bp
index b6d7a06..0bf2737 100644
--- a/drm/libdrmframework/plugins/forward-lock/internal-format/decoder/Android.bp
+++ b/drm/libdrmframework/plugins/forward-lock/internal-format/decoder/Android.bp
@@ -19,6 +19,8 @@
srcs: ["FwdLockFile.c"],
+ cflags: ["-Wall", "-Werror"],
+
shared_libs: ["libcrypto"],
static_libs: ["libfwdlock-common"],
diff --git a/drm/libdrmframework/plugins/passthru/Android.bp b/drm/libdrmframework/plugins/passthru/Android.bp
index 1dcf89c..05b6440 100644
--- a/drm/libdrmframework/plugins/passthru/Android.bp
+++ b/drm/libdrmframework/plugins/passthru/Android.bp
@@ -32,5 +32,7 @@
cflags: [
// Set the following flag to enable the decryption passthru flow
//"-DENABLE_PASSTHRU_DECRYPTION",
+ "-Wall",
+ "-Werror",
],
}
diff --git a/drm/libmediadrm/Android.bp b/drm/libmediadrm/Android.bp
index f906564..0c14201 100644
--- a/drm/libmediadrm/Android.bp
+++ b/drm/libmediadrm/Android.bp
@@ -34,8 +34,8 @@
"libstagefright_foundation",
"libutils",
"android.hardware.drm@1.0",
+ "libhidlallocatorutils",
"libhidlbase",
- "libhidlmemory",
"libhidltransport",
],
diff --git a/drm/libmediadrm/CryptoHal.cpp b/drm/libmediadrm/CryptoHal.cpp
index d613a5b..b9b3685 100644
--- a/drm/libmediadrm/CryptoHal.cpp
+++ b/drm/libmediadrm/CryptoHal.cpp
@@ -29,6 +29,7 @@
#include <media/stagefright/foundation/AString.h>
#include <media/stagefright/foundation/hexdump.h>
#include <media/stagefright/MediaErrors.h>
+#include <hidlmemory/FrameworkUtils.h>
using ::android::hardware::drm::V1_0::BufferType;
using ::android::hardware::drm::V1_0::DestinationBuffer;
@@ -227,6 +228,9 @@
* are sent by providing an offset into the heap and a buffer size.
*/
int32_t CryptoHal::setHeapBase(const sp<IMemoryHeap>& heap) {
+ using ::android::hardware::fromHeap;
+ using ::android::hardware::HidlMemory;
+
if (heap == NULL) {
ALOGE("setHeapBase(): heap is NULL");
return -1;
@@ -240,12 +244,9 @@
Mutex::Autolock autoLock(mLock);
int32_t seqNum = mHeapSeqNum++;
- int fd = heap->getHeapID();
- nativeHandle->data[0] = fd;
- auto hidlHandle = hidl_handle(nativeHandle);
- auto hidlMemory = hidl_memory("ashmem", hidlHandle, heap->getSize());
+ sp<HidlMemory> hidlMemory = fromHeap(heap);
mHeapBases.add(seqNum, mNextBufferId);
- Return<void> hResult = mPlugin->setSharedBufferBase(hidlMemory, mNextBufferId++);
+ Return<void> hResult = mPlugin->setSharedBufferBase(*hidlMemory, mNextBufferId++);
ALOGE_IF(!hResult.isOk(), "setSharedBufferBase(): remote call failed");
return seqNum;
}
diff --git a/drm/mediadrm/plugins/clearkey/Android.bp b/drm/mediadrm/plugins/clearkey/Android.bp
index 2973fcf..385815c 100644
--- a/drm/mediadrm/plugins/clearkey/Android.bp
+++ b/drm/mediadrm/plugins/clearkey/Android.bp
@@ -35,6 +35,8 @@
vendor: true,
relative_install_path: "mediadrm",
+ cflags: ["-Wall", "-Werror"],
+
shared_libs: [
"libcrypto",
"liblog",
diff --git a/drm/mediadrm/plugins/clearkey/tests/Android.bp b/drm/mediadrm/plugins/clearkey/tests/Android.bp
index 0fcfc64..ea17bbb 100644
--- a/drm/mediadrm/plugins/clearkey/tests/Android.bp
+++ b/drm/mediadrm/plugins/clearkey/tests/Android.bp
@@ -21,6 +21,8 @@
name: "ClearKeyDrmUnitTest",
vendor: true,
+ cflags: ["-Wall", "-Werror"],
+
srcs: [
"AesCtrDecryptorUnittest.cpp",
"InitDataParserUnittest.cpp",
diff --git a/drm/mediadrm/plugins/mock/Android.bp b/drm/mediadrm/plugins/mock/Android.bp
index abd1884..dd2ad7b 100644
--- a/drm/mediadrm/plugins/mock/Android.bp
+++ b/drm/mediadrm/plugins/mock/Android.bp
@@ -32,5 +32,7 @@
cflags: [
// Set the following flag to enable the decryption passthru flow
//"-DENABLE_PASSTHRU_DECRYPTION",
+ "-Wall",
+ "-Werror",
],
}
diff --git a/media/libaaudio/Android.bp b/media/libaaudio/Android.bp
index 6e60f24..f00f7a8 100644
--- a/media/libaaudio/Android.bp
+++ b/media/libaaudio/Android.bp
@@ -28,3 +28,10 @@
first_version: "26",
unversioned_until: "current",
}
+
+cc_library_headers {
+ name: "libaaudio_headers",
+ export_include_dirs: ["include"],
+}
+
+subdirs = ["*"]
diff --git a/media/libaaudio/Android.mk b/media/libaaudio/Android.mk
deleted file mode 100644
index 5053e7d..0000000
--- a/media/libaaudio/Android.mk
+++ /dev/null
@@ -1 +0,0 @@
-include $(call all-subdir-makefiles)
diff --git a/media/libaaudio/examples/Android.bp b/media/libaaudio/examples/Android.bp
new file mode 100644
index 0000000..f2e00a7
--- /dev/null
+++ b/media/libaaudio/examples/Android.bp
@@ -0,0 +1,4 @@
+cc_library_headers {
+ name: "libaaudio_example_utils",
+ export_include_dirs: ["."],
+}
diff --git a/media/libaaudio/examples/Android.mk b/media/libaaudio/examples/Android.mk
deleted file mode 100644
index 5053e7d..0000000
--- a/media/libaaudio/examples/Android.mk
+++ /dev/null
@@ -1 +0,0 @@
-include $(call all-subdir-makefiles)
diff --git a/media/libaaudio/examples/input_monitor/Android.mk b/media/libaaudio/examples/input_monitor/Android.mk
deleted file mode 100644
index 5053e7d..0000000
--- a/media/libaaudio/examples/input_monitor/Android.mk
+++ /dev/null
@@ -1 +0,0 @@
-include $(call all-subdir-makefiles)
diff --git a/media/libaaudio/examples/input_monitor/jni/Android.mk b/media/libaaudio/examples/input_monitor/jni/Android.mk
index 9b1ce2c..a0b981c 100644
--- a/media/libaaudio/examples/input_monitor/jni/Android.mk
+++ b/media/libaaudio/examples/input_monitor/jni/Android.mk
@@ -10,6 +10,7 @@
# NDK recommends using this kind of relative path instead of an absolute path.
LOCAL_SRC_FILES:= ../src/input_monitor.cpp
+LOCAL_CFLAGS := -Wall -Werror
LOCAL_SHARED_LIBRARIES := libaaudio
LOCAL_MODULE := input_monitor
include $(BUILD_EXECUTABLE)
@@ -22,6 +23,7 @@
frameworks/av/media/libaaudio/examples/utils
LOCAL_SRC_FILES:= ../src/input_monitor_callback.cpp
+LOCAL_CFLAGS := -Wall -Werror
LOCAL_SHARED_LIBRARIES := libaaudio
LOCAL_MODULE := input_monitor_callback
include $(BUILD_EXECUTABLE)
diff --git a/media/libaaudio/examples/input_monitor/src/input_monitor.cpp b/media/libaaudio/examples/input_monitor/src/input_monitor.cpp
index 9feb118..e5ad2d9 100644
--- a/media/libaaudio/examples/input_monitor/src/input_monitor.cpp
+++ b/media/libaaudio/examples/input_monitor/src/input_monitor.cpp
@@ -40,7 +40,6 @@
int actualSamplesPerFrame;
int actualSampleRate;
aaudio_format_t actualDataFormat;
- aaudio_sharing_mode_t actualSharingMode;
AAudioStream *aaudioStream = nullptr;
aaudio_stream_state_t state;
@@ -54,7 +53,6 @@
int64_t previousFramePosition = -1;
int16_t *data = nullptr;
float peakLevel = 0.0;
- int loopCounter = 0;
int32_t deviceId;
// Make printf print immediately so that debug info is not stuck
diff --git a/media/libaaudio/examples/loopback/Android.mk b/media/libaaudio/examples/loopback/Android.mk
deleted file mode 100644
index 5053e7d..0000000
--- a/media/libaaudio/examples/loopback/Android.mk
+++ /dev/null
@@ -1 +0,0 @@
-include $(call all-subdir-makefiles)
diff --git a/media/libaaudio/examples/loopback/jni/Android.mk b/media/libaaudio/examples/loopback/jni/Android.mk
index d78f286..1fe3def 100644
--- a/media/libaaudio/examples/loopback/jni/Android.mk
+++ b/media/libaaudio/examples/loopback/jni/Android.mk
@@ -9,6 +9,7 @@
# NDK recommends using this kind of relative path instead of an absolute path.
LOCAL_SRC_FILES:= ../src/loopback.cpp
+LOCAL_CFLAGS := -Wall -Werror
LOCAL_SHARED_LIBRARIES := libaaudio
LOCAL_MODULE := aaudio_loopback
include $(BUILD_EXECUTABLE)
diff --git a/media/libaaudio/examples/loopback/src/LoopbackAnalyzer.h b/media/libaaudio/examples/loopback/src/LoopbackAnalyzer.h
index 21cf341..276b45f 100644
--- a/media/libaaudio/examples/loopback/src/LoopbackAnalyzer.h
+++ b/media/libaaudio/examples/loopback/src/LoopbackAnalyzer.h
@@ -432,9 +432,7 @@
int needleSize = (int) (sizeof(s_Impulse) / sizeof(float));
float *haystack = audioRecorder.getData();
int haystackSize = audioRecorder.size();
- int result = measureLatencyFromEchos(haystack, haystackSize,
- needle, needleSize,
- &latencyReport);
+ measureLatencyFromEchos(haystack, haystackSize, needle, needleSize, &latencyReport);
if (latencyReport.confidence < 0.01) {
printf(" ERROR - confidence too low = %f\n", latencyReport.confidence);
} else {
@@ -580,7 +578,6 @@
int mDownCounter = 500;
int mLoopCounter = 0;
- int mLoopStart = 1000;
float mPulseThreshold = 0.02f;
float mSilenceThreshold = 0.002f;
float mMeasuredLoopGain = 0.0f;
@@ -651,7 +648,6 @@
void process(float *inputData, int inputChannelCount,
float *outputData, int outputChannelCount,
int numFrames) override {
- float sample;
float peak = measurePeakAmplitude(inputData, inputChannelCount, numFrames);
if (peak > mPeakAmplitude) {
mPeakAmplitude = peak;
@@ -779,8 +775,6 @@
int32_t mFrameCounter = 0;
float mOutputAmplitude = 0.75;
- int32_t mZeroCrossings = 0;
-
PseudoRandom mWhiteNoise;
float mNoiseAmplitude = 0.00; // Used to experiment with warbling caused by DRC.
diff --git a/media/libaaudio/examples/loopback/src/loopback.cpp b/media/libaaudio/examples/loopback/src/loopback.cpp
index be833e6..b678d8a 100644
--- a/media/libaaudio/examples/loopback/src/loopback.cpp
+++ b/media/libaaudio/examples/loopback/src/loopback.cpp
@@ -257,24 +257,17 @@
aaudio_result_t result = AAUDIO_OK;
aaudio_sharing_mode_t requestedInputSharingMode = AAUDIO_SHARING_MODE_SHARED;
int requestedInputChannelCount = NUM_INPUT_CHANNELS;
- const int requestedOutputChannelCount = AAUDIO_UNSPECIFIED;
- int actualSampleRate = 0;
const aaudio_format_t requestedInputFormat = AAUDIO_FORMAT_PCM_I16;
const aaudio_format_t requestedOutputFormat = AAUDIO_FORMAT_PCM_FLOAT;
aaudio_format_t actualInputFormat;
aaudio_format_t actualOutputFormat;
- aaudio_performance_mode_t outputPerformanceLevel = AAUDIO_PERFORMANCE_MODE_LOW_LATENCY;
aaudio_performance_mode_t inputPerformanceLevel = AAUDIO_PERFORMANCE_MODE_LOW_LATENCY;
int testMode = TEST_ECHO_LATENCY;
double gain = 1.0;
- aaudio_stream_state_t state = AAUDIO_STREAM_STATE_UNINITIALIZED;
int32_t framesPerBurst = 0;
float *outputData = NULL;
- double deviation;
- double latency;
- int32_t burstsPerBuffer = 1; // single buffered
// Make printf print immediately so that debug info is not stuck
// in a buffer if we hang or crash.
diff --git a/media/libaaudio/examples/utils/AAudioExampleUtils.h b/media/libaaudio/examples/utils/AAudioExampleUtils.h
index d817664..f608589 100644
--- a/media/libaaudio/examples/utils/AAudioExampleUtils.h
+++ b/media/libaaudio/examples/utils/AAudioExampleUtils.h
@@ -86,7 +86,8 @@
time->tv_nsec = nanoseconds - (time->tv_sec * NANOS_PER_SECOND);
}
-static int64_t getNanoseconds(clockid_t clockId = CLOCK_MONOTONIC) {
+template <class T = clockid_t>
+int64_t getNanoseconds(clockid_t clockId = CLOCK_MONOTONIC) {
struct timespec time;
int result = clock_gettime(clockId, &time);
if (result < 0) {
@@ -95,7 +96,7 @@
return (time.tv_sec * NANOS_PER_SECOND) + time.tv_nsec;
}
-static void displayPeakLevel(float peakLevel) {
+void displayPeakLevel(float peakLevel) {
printf("%5.3f ", peakLevel);
const int maxStars = 50; // arbitrary, fits on one line
int numStars = (int) (peakLevel * maxStars);
@@ -113,7 +114,7 @@
* @param sampleRate
* @return latency in milliseconds
*/
-static double calculateLatencyMillis(int64_t position1, int64_t nanoseconds1,
+double calculateLatencyMillis(int64_t position1, int64_t nanoseconds1,
int64_t position2, int64_t nanoseconds2,
int64_t sampleRate) {
int64_t deltaFrames = position2 - position1;
diff --git a/media/libaaudio/examples/write_sine/Android.mk b/media/libaaudio/examples/write_sine/Android.mk
deleted file mode 100644
index 5053e7d..0000000
--- a/media/libaaudio/examples/write_sine/Android.mk
+++ /dev/null
@@ -1 +0,0 @@
-include $(call all-subdir-makefiles)
diff --git a/media/libaaudio/examples/write_sine/jni/Android.mk b/media/libaaudio/examples/write_sine/jni/Android.mk
index d630e76..1a1bd43 100644
--- a/media/libaaudio/examples/write_sine/jni/Android.mk
+++ b/media/libaaudio/examples/write_sine/jni/Android.mk
@@ -10,6 +10,7 @@
# NDK recommends using this kind of relative path instead of an absolute path.
LOCAL_SRC_FILES:= ../src/write_sine.cpp
+LOCAL_CFLAGS := -Wall -Werror
LOCAL_SHARED_LIBRARIES := libaaudio
LOCAL_MODULE := write_sine
include $(BUILD_EXECUTABLE)
@@ -22,6 +23,7 @@
frameworks/av/media/libaaudio/examples/utils
LOCAL_SRC_FILES:= ../src/write_sine_callback.cpp
+LOCAL_CFLAGS := -Wall -Werror
LOCAL_SHARED_LIBRARIES := libaaudio
LOCAL_MODULE := write_sine_callback
include $(BUILD_EXECUTABLE)
diff --git a/media/libaaudio/examples/write_sine/src/write_sine.cpp b/media/libaaudio/examples/write_sine/src/write_sine.cpp
index 677fb6c..8c6f783 100644
--- a/media/libaaudio/examples/write_sine/src/write_sine.cpp
+++ b/media/libaaudio/examples/write_sine/src/write_sine.cpp
@@ -44,7 +44,6 @@
AAudioStream *aaudioStream = nullptr;
int32_t framesPerBurst = 0;
int32_t framesPerWrite = 0;
- int32_t bufferCapacity = 0;
int32_t framesToPlay = 0;
int32_t framesLeft = 0;
int32_t xRunCount = 0;
diff --git a/media/libaaudio/src/Android.bp b/media/libaaudio/src/Android.bp
new file mode 100644
index 0000000..788833b
--- /dev/null
+++ b/media/libaaudio/src/Android.bp
@@ -0,0 +1,66 @@
+cc_library {
+ name: "libaaudio",
+
+ local_include_dirs: [
+ "binding",
+ "client",
+ "core",
+ "fifo",
+ "legacy",
+ "utility",
+ ],
+ export_include_dirs: ["."],
+ header_libs: ["libaaudio_headers"],
+ export_header_lib_headers: ["libaaudio_headers"],
+
+ srcs: [
+ "core/AudioStream.cpp",
+ "core/AudioStreamBuilder.cpp",
+ "core/AAudioAudio.cpp",
+ "core/AAudioStreamParameters.cpp",
+ "legacy/AudioStreamLegacy.cpp",
+ "legacy/AudioStreamRecord.cpp",
+ "legacy/AudioStreamTrack.cpp",
+ "utility/AAudioUtilities.cpp",
+ "utility/FixedBlockAdapter.cpp",
+ "utility/FixedBlockReader.cpp",
+ "utility/FixedBlockWriter.cpp",
+ "utility/LinearRamp.cpp",
+ "fifo/FifoBuffer.cpp",
+ "fifo/FifoControllerBase.cpp",
+ "client/AudioEndpoint.cpp",
+ "client/AudioStreamInternal.cpp",
+ "client/AudioStreamInternalCapture.cpp",
+ "client/AudioStreamInternalPlay.cpp",
+ "client/IsochronousClockModel.cpp",
+ "binding/AudioEndpointParcelable.cpp",
+ "binding/AAudioBinderClient.cpp",
+ "binding/AAudioStreamRequest.cpp",
+ "binding/AAudioStreamConfiguration.cpp",
+ "binding/IAAudioClient.cpp",
+ "binding/IAAudioService.cpp",
+ "binding/RingBufferParcelable.cpp",
+ "binding/SharedMemoryParcelable.cpp",
+ "binding/SharedRegionParcelable.cpp",
+ ],
+
+ cflags: [
+ "-Wno-unused-parameter",
+ "-Wall",
+ "-Werror",
+
+ // By default, all symbols are hidden.
+ // "-fvisibility=hidden",
+ // AAUDIO_API is used to explicitly export a function or a variable as a visible symbol.
+ "-DAAUDIO_API=__attribute__((visibility(\"default\")))",
+ ],
+
+ shared_libs: [
+ "libaudioclient",
+ "liblog",
+ "libcutils",
+ "libutils",
+ "libbinder",
+ "libaudiomanager",
+ ],
+}
diff --git a/media/libaaudio/src/Android.mk b/media/libaaudio/src/Android.mk
deleted file mode 100644
index 6861248..0000000
--- a/media/libaaudio/src/Android.mk
+++ /dev/null
@@ -1,128 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-
-# ======================= STATIC LIBRARY ==========================
-# This is being built because it make AAudio testing very easy with a complete executable.
-# TODO Remove this target later, when not needed.
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := libaaudio
-LOCAL_MODULE_TAGS := optional
-
-LIBAAUDIO_DIR := $(TOP)/frameworks/av/media/libaaudio
-LIBAAUDIO_SRC_DIR := $(LIBAAUDIO_DIR)/src
-
-LOCAL_C_INCLUDES := \
- $(call include-path-for, audio-utils) \
- frameworks/native/include \
- system/core/base/include \
- frameworks/native/media/libaaudio/include/include \
- frameworks/av/media/libaaudio/include \
- frameworks/native/include \
- frameworks/av/media/libaudioclient/include \
- $(LOCAL_PATH) \
- $(LOCAL_PATH)/binding \
- $(LOCAL_PATH)/client \
- $(LOCAL_PATH)/core \
- $(LOCAL_PATH)/fifo \
- $(LOCAL_PATH)/legacy \
- $(LOCAL_PATH)/utility
-
-# If you add a file here then also add it below in the SHARED target
-LOCAL_SRC_FILES = \
- core/AudioStream.cpp \
- core/AudioStreamBuilder.cpp \
- core/AAudioAudio.cpp \
- core/AAudioStreamParameters.cpp \
- legacy/AudioStreamLegacy.cpp \
- legacy/AudioStreamRecord.cpp \
- legacy/AudioStreamTrack.cpp \
- utility/AAudioUtilities.cpp \
- utility/FixedBlockAdapter.cpp \
- utility/FixedBlockReader.cpp \
- utility/FixedBlockWriter.cpp \
- utility/LinearRamp.cpp \
- fifo/FifoBuffer.cpp \
- fifo/FifoControllerBase.cpp \
- client/AudioEndpoint.cpp \
- client/AudioStreamInternal.cpp \
- client/AudioStreamInternalCapture.cpp \
- client/AudioStreamInternalPlay.cpp \
- client/IsochronousClockModel.cpp \
- binding/AudioEndpointParcelable.cpp \
- binding/AAudioBinderClient.cpp \
- binding/AAudioStreamRequest.cpp \
- binding/AAudioStreamConfiguration.cpp \
- binding/IAAudioClient.cpp \
- binding/IAAudioService.cpp \
- binding/RingBufferParcelable.cpp \
- binding/SharedMemoryParcelable.cpp \
- binding/SharedRegionParcelable.cpp
-
-LOCAL_CFLAGS += -Wno-unused-parameter -Wall -Werror
-
-# By default, all symbols are hidden.
-# LOCAL_CFLAGS += -fvisibility=hidden
-# AAUDIO_API is used to explicitly export a function or a variable as a visible symbol.
-LOCAL_CFLAGS += -DAAUDIO_API='__attribute__((visibility("default")))'
-
-include $(BUILD_STATIC_LIBRARY)
-
-# ======================= SHARED LIBRARY ==========================
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := libaaudio
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_C_INCLUDES := \
- $(call include-path-for, audio-utils) \
- frameworks/native/include \
- system/core/base/include \
- frameworks/native/media/libaaudio/include/include \
- frameworks/av/media/libaaudio/include \
- $(LOCAL_PATH) \
- $(LOCAL_PATH)/binding \
- $(LOCAL_PATH)/client \
- $(LOCAL_PATH)/core \
- $(LOCAL_PATH)/fifo \
- $(LOCAL_PATH)/legacy \
- $(LOCAL_PATH)/utility
-
-LOCAL_SRC_FILES = core/AudioStream.cpp \
- core/AudioStreamBuilder.cpp \
- core/AAudioAudio.cpp \
- core/AAudioStreamParameters.cpp \
- legacy/AudioStreamLegacy.cpp \
- legacy/AudioStreamRecord.cpp \
- legacy/AudioStreamTrack.cpp \
- utility/AAudioUtilities.cpp \
- utility/FixedBlockAdapter.cpp \
- utility/FixedBlockReader.cpp \
- utility/FixedBlockWriter.cpp \
- utility/LinearRamp.cpp \
- fifo/FifoBuffer.cpp \
- fifo/FifoControllerBase.cpp \
- client/AudioEndpoint.cpp \
- client/AudioStreamInternal.cpp \
- client/AudioStreamInternalCapture.cpp \
- client/AudioStreamInternalPlay.cpp \
- client/IsochronousClockModel.cpp \
- binding/AudioEndpointParcelable.cpp \
- binding/AAudioBinderClient.cpp \
- binding/AAudioStreamRequest.cpp \
- binding/AAudioStreamConfiguration.cpp \
- binding/IAAudioClient.cpp \
- binding/IAAudioService.cpp \
- binding/RingBufferParcelable.cpp \
- binding/SharedMemoryParcelable.cpp \
- binding/SharedRegionParcelable.cpp
-
-LOCAL_CFLAGS += -Wno-unused-parameter -Wall -Werror
-
-# By default, all symbols are hidden.
-# LOCAL_CFLAGS += -fvisibility=hidden
-# AAUDIO_API is used to explicitly export a function or a variable as a visible symbol.
-LOCAL_CFLAGS += -DAAUDIO_API='__attribute__((visibility("default")))'
-
-LOCAL_SHARED_LIBRARIES := libaudioclient liblog libcutils libutils libbinder libaudiomanager
-
-include $(BUILD_SHARED_LIBRARY)
diff --git a/media/libaaudio/tests/Android.bp b/media/libaaudio/tests/Android.bp
new file mode 100644
index 0000000..19c56d3
--- /dev/null
+++ b/media/libaaudio/tests/Android.bp
@@ -0,0 +1,88 @@
+cc_defaults {
+ name: "libaaudio_tests_defaults",
+ cflags: [
+ "-Wall",
+ "-Werror",
+ ],
+}
+
+cc_test {
+ name: "test_aaudio_marshalling",
+ defaults: ["libaaudio_tests_defaults"],
+ srcs: ["test_marshalling.cpp"],
+ shared_libs: [
+ "libaaudio",
+ "libbinder",
+ "libcutils",
+ "libutils",
+ ],
+}
+
+cc_test {
+ name: "test_block_adapter",
+ defaults: ["libaaudio_tests_defaults"],
+ srcs: ["test_block_adapter.cpp"],
+ shared_libs: ["libaaudio"],
+}
+
+cc_test {
+ name: "test_timestamps",
+ srcs: ["test_timestamps.cpp"],
+ header_libs: ["libaaudio_example_utils"],
+ shared_libs: ["libaaudio"],
+}
+
+cc_test {
+ name: "test_linear_ramp",
+ defaults: ["libaaudio_tests_defaults"],
+ srcs: ["test_linear_ramp.cpp"],
+ shared_libs: ["libaaudio"],
+}
+
+cc_test {
+ name: "test_open_params",
+ defaults: ["libaaudio_tests_defaults"],
+ srcs: ["test_open_params.cpp"],
+ shared_libs: [
+ "libaaudio",
+ "libbinder",
+ "libcutils",
+ "libutils",
+ ],
+}
+
+cc_test {
+ name: "test_no_close",
+ defaults: ["libaaudio_tests_defaults"],
+ srcs: ["test_no_close.cpp"],
+ shared_libs: [
+ "libaaudio",
+ "libbinder",
+ "libcutils",
+ "libutils",
+ ],
+}
+
+cc_test {
+ name: "test_aaudio_recovery",
+ defaults: ["libaaudio_tests_defaults"],
+ srcs: ["test_recovery.cpp"],
+ shared_libs: [
+ "libaaudio",
+ "libbinder",
+ "libcutils",
+ "libutils",
+ ],
+}
+
+cc_test {
+ name: "test_n_streams",
+ defaults: ["libaaudio_tests_defaults"],
+ srcs: ["test_n_streams.cpp"],
+ shared_libs: [
+ "libaaudio",
+ "libbinder",
+ "libcutils",
+ "libutils",
+ ],
+}
diff --git a/media/libaaudio/tests/Android.mk b/media/libaaudio/tests/Android.mk
deleted file mode 100644
index 37b010d..0000000
--- a/media/libaaudio/tests/Android.mk
+++ /dev/null
@@ -1,82 +0,0 @@
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-LOCAL_C_INCLUDES := \
- $(call include-path-for, audio-utils) \
- frameworks/av/media/libaaudio/include \
- frameworks/av/media/libaaudio/src
-LOCAL_SRC_FILES:= test_marshalling.cpp
-LOCAL_SHARED_LIBRARIES := libaaudio libbinder libcutils libutils
-LOCAL_MODULE := test_aaudio_marshalling
-include $(BUILD_NATIVE_TEST)
-
-include $(CLEAR_VARS)
-LOCAL_C_INCLUDES := \
- $(call include-path-for, audio-utils) \
- frameworks/av/media/libaaudio/include \
- frameworks/av/media/libaaudio/src
-LOCAL_SRC_FILES:= test_block_adapter.cpp
-LOCAL_SHARED_LIBRARIES := libaaudio
-LOCAL_MODULE := test_block_adapter
-include $(BUILD_NATIVE_TEST)
-
-include $(CLEAR_VARS)
-LOCAL_C_INCLUDES := \
- $(call include-path-for, audio-utils) \
- frameworks/av/media/libaaudio/include \
- frameworks/av/media/libaaudio/src \
- frameworks/av/media/libaaudio/examples
-LOCAL_SRC_FILES:= test_timestamps.cpp
-LOCAL_SHARED_LIBRARIES := libaaudio
-LOCAL_MODULE := test_timestamps
-include $(BUILD_NATIVE_TEST)
-
-include $(CLEAR_VARS)
-LOCAL_C_INCLUDES := \
- $(call include-path-for, audio-utils) \
- frameworks/av/media/libaaudio/include \
- frameworks/av/media/libaaudio/src
-LOCAL_SRC_FILES:= test_linear_ramp.cpp
-LOCAL_SHARED_LIBRARIES := libaaudio
-LOCAL_MODULE := test_linear_ramp
-include $(BUILD_NATIVE_TEST)
-
-include $(CLEAR_VARS)
-LOCAL_C_INCLUDES := \
- $(call include-path-for, audio-utils) \
- frameworks/av/media/libaaudio/include \
- frameworks/av/media/libaaudio/src
-LOCAL_SRC_FILES:= test_open_params.cpp
-LOCAL_SHARED_LIBRARIES := libaaudio libbinder libcutils libutils
-LOCAL_MODULE := test_open_params
-include $(BUILD_NATIVE_TEST)
-
-include $(CLEAR_VARS)
-LOCAL_C_INCLUDES := \
- $(call include-path-for, audio-utils) \
- frameworks/av/media/libaaudio/include \
- frameworks/av/media/libaaudio/src
-LOCAL_SRC_FILES:= test_no_close.cpp
-LOCAL_SHARED_LIBRARIES := libaaudio libbinder libcutils libutils
-LOCAL_MODULE := test_no_close
-include $(BUILD_NATIVE_TEST)
-
-include $(CLEAR_VARS)
-LOCAL_C_INCLUDES := \
- $(call include-path-for, audio-utils) \
- frameworks/av/media/libaaudio/include \
- frameworks/av/media/libaaudio/src
-LOCAL_SRC_FILES:= test_recovery.cpp
-LOCAL_SHARED_LIBRARIES := libaaudio libbinder libcutils libutils
-LOCAL_MODULE := test_aaudio_recovery
-include $(BUILD_NATIVE_TEST)
-
-include $(CLEAR_VARS)
-LOCAL_C_INCLUDES := \
- $(call include-path-for, audio-utils) \
- frameworks/av/media/libaaudio/include \
- frameworks/av/media/libaaudio/src
-LOCAL_SRC_FILES:= test_n_streams.cpp
-LOCAL_SHARED_LIBRARIES := libaaudio libbinder libcutils libutils
-LOCAL_MODULE := test_n_streams
-include $(BUILD_NATIVE_TEST)
diff --git a/media/libaaudio/tests/test_n_streams.cpp b/media/libaaudio/tests/test_n_streams.cpp
index 271d024..e2d4a82 100644
--- a/media/libaaudio/tests/test_n_streams.cpp
+++ b/media/libaaudio/tests/test_n_streams.cpp
@@ -71,7 +71,6 @@
AAudioStreamBuilder_delete(aaudioBuilder);
-finish:
return result;
}
diff --git a/media/libaaudio/tests/test_open_params.cpp b/media/libaaudio/tests/test_open_params.cpp
index 01b8799..3451242 100644
--- a/media/libaaudio/tests/test_open_params.cpp
+++ b/media/libaaudio/tests/test_open_params.cpp
@@ -25,21 +25,6 @@
#include <gtest/gtest.h>
-static const char *getSharingModeText(aaudio_sharing_mode_t mode) {
- const char *modeText = "unknown";
- switch (mode) {
- case AAUDIO_SHARING_MODE_EXCLUSIVE:
- modeText = "EXCLUSIVE";
- break;
- case AAUDIO_SHARING_MODE_SHARED:
- modeText = "SHARED";
- break;
- default:
- break;
- }
- return modeText;
-}
-
// Callback function that fills the audio output buffer.
aaudio_data_callback_result_t MyDataCallbackProc(
AAudioStream *stream,
@@ -67,7 +52,6 @@
int32_t actualChannelCount = 0;
int32_t actualSampleRate = 0;
aaudio_format_t actualDataFormat = AAUDIO_FORMAT_UNSPECIFIED;
- aaudio_sharing_mode_t actualSharingMode = AAUDIO_SHARING_MODE_SHARED;
aaudio_direction_t actualDirection;
AAudioStreamBuilder *aaudioBuilder = nullptr;
diff --git a/media/libaaudio/tests/test_recovery.cpp b/media/libaaudio/tests/test_recovery.cpp
index 7268a30..6e89f83 100644
--- a/media/libaaudio/tests/test_recovery.cpp
+++ b/media/libaaudio/tests/test_recovery.cpp
@@ -23,24 +23,9 @@
#define DEFAULT_TIMEOUT_NANOS ((int64_t)1000000000)
-static const char *getSharingModeText(aaudio_sharing_mode_t mode) {
- const char *modeText = "unknown";
- switch (mode) {
- case AAUDIO_SHARING_MODE_EXCLUSIVE:
- modeText = "EXCLUSIVE";
- break;
- case AAUDIO_SHARING_MODE_SHARED:
- modeText = "SHARED";
- break;
- default:
- break;
- }
- return modeText;
-}
-
int main(int argc, char **argv) {
(void) argc;
- (void *)argv;
+ (void) argv;
aaudio_result_t result = AAUDIO_OK;
@@ -52,7 +37,6 @@
int32_t actualChannelCount = 0;
int32_t actualSampleRate = 0;
aaudio_format_t actualDataFormat = AAUDIO_FORMAT_PCM_FLOAT;
- aaudio_sharing_mode_t actualSharingMode = AAUDIO_SHARING_MODE_SHARED;
AAudioStreamBuilder *aaudioBuilder = nullptr;
AAudioStream *aaudioStream = nullptr;
diff --git a/media/libaudioclient/AudioTrack.cpp b/media/libaudioclient/AudioTrack.cpp
index 3529d2c..c6622cd 100644
--- a/media/libaudioclient/AudioTrack.cpp
+++ b/media/libaudioclient/AudioTrack.cpp
@@ -1391,14 +1391,14 @@
bool useCaseAllowed = sharedBuffer || transferAllowed;
if (!useCaseAllowed) {
- ALOGW("AUDIO_OUTPUT_FLAG_FAST denied, not shared buffer and transfer = %s",
+ ALOGW("AUDIO_OUTPUT_FLAG_FAST denied by client, not shared buffer and transfer = %s",
convertTransferToText(mTransfer));
}
// sample rates must also match
bool sampleRateAllowed = mSampleRate == mAfSampleRate;
if (!sampleRateAllowed) {
- ALOGW("AUDIO_OUTPUT_FLAG_FAST denied, rates do not match %u Hz, require %u Hz",
+ ALOGW("AUDIO_OUTPUT_FLAG_FAST denied by client, sample rate %u Hz but HAL needs %u Hz",
mSampleRate, mAfSampleRate);
}
@@ -1576,6 +1576,15 @@
// or at least triple-buffering if there is sample rate conversion
const int nBuffering = mOriginalSampleRate == mAfSampleRate ? 2 : 3;
maxNotificationFrames = frameCount / nBuffering;
+ // If client requested a fast track but this was denied, then use the smaller maximum.
+ // FMS_20 is the minimum task wakeup period in ms for which CFS operates reliably.
+#define FMS_20 20 // FIXME share a common declaration with the same symbol in Threads.cpp
+ if (mOrigFlags & AUDIO_OUTPUT_FLAG_FAST) {
+ size_t maxNotificationFramesFastDenied = FMS_20 * mSampleRate / 1000;
+ if (maxNotificationFrames > maxNotificationFramesFastDenied) {
+ maxNotificationFrames = maxNotificationFramesFastDenied;
+ }
+ }
}
if (mNotificationFramesAct == 0 || mNotificationFramesAct > maxNotificationFrames) {
if (mNotificationFramesAct == 0) {
diff --git a/media/libmedia/IMediaExtractor.cpp b/media/libmedia/IMediaExtractor.cpp
index 3c43a72..a8a7b82 100644
--- a/media/libmedia/IMediaExtractor.cpp
+++ b/media/libmedia/IMediaExtractor.cpp
@@ -23,6 +23,7 @@
#include <binder/IPCThreadState.h>
#include <binder/Parcel.h>
+#include <binder/PermissionCache.h>
#include <media/IMediaExtractor.h>
#include <media/stagefright/MetaData.h>
@@ -323,13 +324,21 @@
status_t dumpExtractors(int fd, const Vector<String16>&) {
String8 out;
- out.append("Recent extractors, most recent first:\n");
- {
- Mutex::Autolock lock(sExtractorsLock);
- for (size_t i = 0; i < sExtractors.size(); i++) {
- const ExtractorInstance &instance = sExtractors.itemAt(i);
- out.append(" ");
- out.append(instance.toString());
+ const IPCThreadState* ipc = IPCThreadState::self();
+ const int pid = ipc->getCallingPid();
+ const int uid = ipc->getCallingUid();
+ if (!PermissionCache::checkPermission(String16("android.permission.DUMP"), pid, uid)) {
+ out.appendFormat("Permission Denial: "
+ "can't dump MediaExtractor from pid=%d, uid=%d\n", pid, uid);
+ } else {
+ out.append("Recent extractors, most recent first:\n");
+ {
+ Mutex::Autolock lock(sExtractorsLock);
+ for (size_t i = 0; i < sExtractors.size(); i++) {
+ const ExtractorInstance &instance = sExtractors.itemAt(i);
+ out.append(" ");
+ out.append(instance.toString());
+ }
}
}
write(fd, out.string(), out.size());
diff --git a/media/libstagefright/codecs/amrnb/dec/Android.bp b/media/libstagefright/codecs/amrnb/dec/Android.bp
index d266dc2..b493e21 100644
--- a/media/libstagefright/codecs/amrnb/dec/Android.bp
+++ b/media/libstagefright/codecs/amrnb/dec/Android.bp
@@ -114,6 +114,8 @@
srcs: ["test/amrnbdec_test.cpp"],
+ cflags: ["-Wall", "-Werror"],
+
local_include_dirs: ["src"],
static_libs: [
diff --git a/media/libstagefright/codecs/amrnb/enc/Android.bp b/media/libstagefright/codecs/amrnb/enc/Android.bp
index 6dc2dc1..1e8fd31 100644
--- a/media/libstagefright/codecs/amrnb/enc/Android.bp
+++ b/media/libstagefright/codecs/amrnb/enc/Android.bp
@@ -126,6 +126,8 @@
srcs: ["test/amrnb_enc_test.cpp"],
+ cflags: ["-Wall", "-Werror"],
+
local_include_dirs: ["src"],
static_libs: ["libstagefright_amrnbenc"],
diff --git a/media/libstagefright/codecs/amrwb/Android.bp b/media/libstagefright/codecs/amrwb/Android.bp
index b932ccc..14a73d6 100644
--- a/media/libstagefright/codecs/amrwb/Android.bp
+++ b/media/libstagefright/codecs/amrwb/Android.bp
@@ -69,6 +69,8 @@
srcs: ["test/amrwbdec_test.cpp"],
+ cflags: ["-Wall", "-Werror"],
+
static_libs: [
"libstagefright_amrwbdec",
"libsndfile",
diff --git a/media/libstagefright/codecs/amrwbenc/SampleCode/Android.bp b/media/libstagefright/codecs/amrwbenc/SampleCode/Android.bp
index d52fed3..81b3f69 100644
--- a/media/libstagefright/codecs/amrwbenc/SampleCode/Android.bp
+++ b/media/libstagefright/codecs/amrwbenc/SampleCode/Android.bp
@@ -4,6 +4,8 @@
srcs: ["AMRWB_E_SAMPLE.c"],
+ cflags: ["-Wall", "-Werror"],
+
arch: {
arm: {
instruction_set: "arm",
diff --git a/media/libstagefright/codecs/avcdec/Android.bp b/media/libstagefright/codecs/avcdec/Android.bp
index 1f43803..34db19b 100644
--- a/media/libstagefright/codecs/avcdec/Android.bp
+++ b/media/libstagefright/codecs/avcdec/Android.bp
@@ -8,6 +8,12 @@
static_libs: ["libavcdec"],
srcs: ["SoftAVCDec.cpp"],
+ cflags: [
+ "-Wall",
+ "-Werror",
+ "-Wno-unused-variable",
+ ],
+
include_dirs: [
"external/libavc/decoder",
"external/libavc/common",
diff --git a/media/libstagefright/codecs/avcenc/Android.bp b/media/libstagefright/codecs/avcenc/Android.bp
index 66507a7..5203126 100644
--- a/media/libstagefright/codecs/avcenc/Android.bp
+++ b/media/libstagefright/codecs/avcenc/Android.bp
@@ -33,6 +33,11 @@
},
},
+ cflags: [
+ "-Wall",
+ "-Werror",
+ "-Wno-unused-variable",
+ ],
ldflags: ["-Wl,-Bsymbolic"],
compile_multilib: "32",
}
diff --git a/media/libstagefright/codecs/hevcdec/Android.bp b/media/libstagefright/codecs/hevcdec/Android.bp
index 7fa74d4..d9a5ee3 100644
--- a/media/libstagefright/codecs/hevcdec/Android.bp
+++ b/media/libstagefright/codecs/hevcdec/Android.bp
@@ -8,6 +8,12 @@
static_libs: ["libhevcdec"],
srcs: ["SoftHEVC.cpp"],
+ cflags: [
+ "-Wall",
+ "-Werror",
+ "-Wno-unused-variable",
+ ],
+
include_dirs: [
"external/libhevc/decoder",
"external/libhevc/common",
diff --git a/media/libstagefright/codecs/m4v_h263/enc/Android.bp b/media/libstagefright/codecs/m4v_h263/enc/Android.bp
index 640718d..a95b807 100644
--- a/media/libstagefright/codecs/m4v_h263/enc/Android.bp
+++ b/media/libstagefright/codecs/m4v_h263/enc/Android.bp
@@ -112,6 +112,8 @@
"-DOSCL_EXPORT_REF=",
"-DOSCL_IMPORT_REF=",
"-DBX_RC",
+ "-Wall",
+ "-Werror",
],
sanitize: {
diff --git a/media/libstagefright/codecs/mp3dec/Android.bp b/media/libstagefright/codecs/mp3dec/Android.bp
index 273fa31..c554a99 100644
--- a/media/libstagefright/codecs/mp3dec/Android.bp
+++ b/media/libstagefright/codecs/mp3dec/Android.bp
@@ -128,6 +128,8 @@
"test/mp3reader.cpp",
],
+ cflags: ["-Wall", "-Werror"],
+
local_include_dirs: [
"src",
"include",
diff --git a/media/libstagefright/codecs/mpeg2dec/Android.bp b/media/libstagefright/codecs/mpeg2dec/Android.bp
index 15fdde7..9590e9f 100644
--- a/media/libstagefright/codecs/mpeg2dec/Android.bp
+++ b/media/libstagefright/codecs/mpeg2dec/Android.bp
@@ -8,6 +8,12 @@
static_libs: ["libmpeg2dec"],
srcs: ["SoftMPEG2.cpp"],
+ cflags: [
+ "-Wall",
+ "-Werror",
+ "-Wno-unused-variable",
+ ],
+
include_dirs: [
"external/libmpeg2/decoder",
"external/libmpeg2/common",
diff --git a/media/libstagefright/codecs/on2/enc/Android.bp b/media/libstagefright/codecs/on2/enc/Android.bp
index 741774c..5a52225 100644
--- a/media/libstagefright/codecs/on2/enc/Android.bp
+++ b/media/libstagefright/codecs/on2/enc/Android.bp
@@ -11,6 +11,8 @@
"SoftVP9Encoder.cpp",
],
+ cflags: ["-Wall", "-Werror"],
+
include_dirs: [
"frameworks/av/media/libstagefright/include",
"frameworks/native/include/media/openmax",
diff --git a/media/libstagefright/codecs/on2/h264dec/Android.bp b/media/libstagefright/codecs/on2/h264dec/Android.bp
index 6d558b6..0984283 100644
--- a/media/libstagefright/codecs/on2/h264dec/Android.bp
+++ b/media/libstagefright/codecs/on2/h264dec/Android.bp
@@ -96,6 +96,8 @@
},
},
+ cflags: ["-Wall", "-Werror"],
+
include_dirs: [
"frameworks/av/media/libstagefright/include",
"frameworks/native/include/media/openmax",
@@ -133,5 +135,7 @@
srcs: ["source/DecTestBench.c"],
+ cflags: ["-Wall", "-Werror"],
+
shared_libs: ["libstagefright_soft_h264dec"],
}
diff --git a/media/libstagefright/matroska/MatroskaExtractor.cpp b/media/libstagefright/matroska/MatroskaExtractor.cpp
index 4b38906..462eff6 100644
--- a/media/libstagefright/matroska/MatroskaExtractor.cpp
+++ b/media/libstagefright/matroska/MatroskaExtractor.cpp
@@ -1434,6 +1434,14 @@
continue;
}
+ const char *language = track->GetLanguage();
+ if (language != NULL) {
+ char lang[4];
+ strncpy(lang, language, 3);
+ lang[3] = '\0';
+ meta->setCString(kKeyMediaLanguage, lang);
+ }
+
if (err != OK) {
ALOGE("skipping track, codec specific data was malformed.");
continue;
diff --git a/media/libstagefright/omx/Android.bp b/media/libstagefright/omx/Android.bp
index d4cdf69..bd3c1c6 100644
--- a/media/libstagefright/omx/Android.bp
+++ b/media/libstagefright/omx/Android.bp
@@ -124,6 +124,7 @@
cfi: true,
},
},
+ cflags: ["-Wall", "-Werror"],
}
//###############################################################################
diff --git a/media/mtp/Android.bp b/media/mtp/Android.bp
index 543ad5c..acea373 100644
--- a/media/mtp/Android.bp
+++ b/media/mtp/Android.bp
@@ -19,6 +19,7 @@
srcs: [
"MtpDataPacket.cpp",
"MtpDebug.cpp",
+ "MtpDescriptors.cpp",
"MtpDevHandle.cpp",
"MtpDevice.cpp",
"MtpDeviceInfo.cpp",
diff --git a/media/mtp/MtpDatabase.h b/media/mtp/MtpDatabase.h
index c7021df..2395f4f 100644
--- a/media/mtp/MtpDatabase.h
+++ b/media/mtp/MtpDatabase.h
@@ -104,7 +104,7 @@
virtual MtpProperty* getDevicePropertyDesc(MtpDeviceProperty property) = 0;
virtual MtpResponseCode moveObject(MtpObjectHandle handle, MtpObjectHandle newParent,
- MtpString& newPath) = 0;
+ MtpStorageID newStorage, MtpString& newPath) = 0;
virtual void sessionStarted() = 0;
diff --git a/media/mtp/MtpDescriptors.cpp b/media/mtp/MtpDescriptors.cpp
new file mode 100644
index 0000000..d9b6060
--- /dev/null
+++ b/media/mtp/MtpDescriptors.cpp
@@ -0,0 +1,260 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "MtpDescriptors.h"
+
+namespace android {
+
+const struct usb_interface_descriptor mtp_interface_desc = {
+ .bLength = USB_DT_INTERFACE_SIZE,
+ .bDescriptorType = USB_DT_INTERFACE,
+ .bInterfaceNumber = 0,
+ .bNumEndpoints = 3,
+ .bInterfaceClass = USB_CLASS_STILL_IMAGE,
+ .bInterfaceSubClass = 1,
+ .bInterfaceProtocol = 1,
+ .iInterface = 1,
+};
+
+const struct usb_interface_descriptor ptp_interface_desc = {
+ .bLength = USB_DT_INTERFACE_SIZE,
+ .bDescriptorType = USB_DT_INTERFACE,
+ .bInterfaceNumber = 0,
+ .bNumEndpoints = 3,
+ .bInterfaceClass = USB_CLASS_STILL_IMAGE,
+ .bInterfaceSubClass = 1,
+ .bInterfaceProtocol = 1,
+};
+
+const struct usb_endpoint_descriptor_no_audio fs_sink = {
+ .bLength = USB_DT_ENDPOINT_SIZE,
+ .bDescriptorType = USB_DT_ENDPOINT,
+ .bEndpointAddress = 1 | USB_DIR_IN,
+ .bmAttributes = USB_ENDPOINT_XFER_BULK,
+ .wMaxPacketSize = MAX_PACKET_SIZE_FS,
+};
+
+const struct usb_endpoint_descriptor_no_audio fs_source = {
+ .bLength = USB_DT_ENDPOINT_SIZE,
+ .bDescriptorType = USB_DT_ENDPOINT,
+ .bEndpointAddress = 2 | USB_DIR_OUT,
+ .bmAttributes = USB_ENDPOINT_XFER_BULK,
+ .wMaxPacketSize = MAX_PACKET_SIZE_FS,
+};
+
+const struct usb_endpoint_descriptor_no_audio intr = {
+ .bLength = USB_DT_ENDPOINT_SIZE,
+ .bDescriptorType = USB_DT_ENDPOINT,
+ .bEndpointAddress = 3 | USB_DIR_IN,
+ .bmAttributes = USB_ENDPOINT_XFER_INT,
+ .wMaxPacketSize = MAX_PACKET_SIZE_EV,
+ .bInterval = 6,
+};
+
+const struct usb_endpoint_descriptor_no_audio hs_sink = {
+ .bLength = USB_DT_ENDPOINT_SIZE,
+ .bDescriptorType = USB_DT_ENDPOINT,
+ .bEndpointAddress = 1 | USB_DIR_IN,
+ .bmAttributes = USB_ENDPOINT_XFER_BULK,
+ .wMaxPacketSize = MAX_PACKET_SIZE_HS,
+};
+
+const struct usb_endpoint_descriptor_no_audio hs_source = {
+ .bLength = USB_DT_ENDPOINT_SIZE,
+ .bDescriptorType = USB_DT_ENDPOINT,
+ .bEndpointAddress = 2 | USB_DIR_OUT,
+ .bmAttributes = USB_ENDPOINT_XFER_BULK,
+ .wMaxPacketSize = MAX_PACKET_SIZE_HS,
+};
+
+const struct usb_endpoint_descriptor_no_audio ss_sink = {
+ .bLength = USB_DT_ENDPOINT_SIZE,
+ .bDescriptorType = USB_DT_ENDPOINT,
+ .bEndpointAddress = 1 | USB_DIR_IN,
+ .bmAttributes = USB_ENDPOINT_XFER_BULK,
+ .wMaxPacketSize = MAX_PACKET_SIZE_SS,
+};
+
+const struct usb_endpoint_descriptor_no_audio ss_source = {
+ .bLength = USB_DT_ENDPOINT_SIZE,
+ .bDescriptorType = USB_DT_ENDPOINT,
+ .bEndpointAddress = 2 | USB_DIR_OUT,
+ .bmAttributes = USB_ENDPOINT_XFER_BULK,
+ .wMaxPacketSize = MAX_PACKET_SIZE_SS,
+};
+
+const struct usb_ss_ep_comp_descriptor ss_sink_comp = {
+ .bLength = sizeof(ss_sink_comp),
+ .bDescriptorType = USB_DT_SS_ENDPOINT_COMP,
+ .bMaxBurst = 6,
+};
+
+const struct usb_ss_ep_comp_descriptor ss_source_comp = {
+ .bLength = sizeof(ss_source_comp),
+ .bDescriptorType = USB_DT_SS_ENDPOINT_COMP,
+ .bMaxBurst = 6,
+};
+
+const struct usb_ss_ep_comp_descriptor ss_intr_comp = {
+ .bLength = sizeof(ss_intr_comp),
+ .bDescriptorType = USB_DT_SS_ENDPOINT_COMP,
+};
+
+const struct func_desc mtp_fs_descriptors = {
+ .intf = mtp_interface_desc,
+ .sink = fs_sink,
+ .source = fs_source,
+ .intr = intr,
+};
+
+const struct func_desc mtp_hs_descriptors = {
+ .intf = mtp_interface_desc,
+ .sink = hs_sink,
+ .source = hs_source,
+ .intr = intr,
+};
+
+const struct ss_func_desc mtp_ss_descriptors = {
+ .intf = mtp_interface_desc,
+ .sink = ss_sink,
+ .sink_comp = ss_sink_comp,
+ .source = ss_source,
+ .source_comp = ss_source_comp,
+ .intr = intr,
+ .intr_comp = ss_intr_comp,
+};
+
+const struct func_desc ptp_fs_descriptors = {
+ .intf = ptp_interface_desc,
+ .sink = fs_sink,
+ .source = fs_source,
+ .intr = intr,
+};
+
+const struct func_desc ptp_hs_descriptors = {
+ .intf = ptp_interface_desc,
+ .sink = hs_sink,
+ .source = hs_source,
+ .intr = intr,
+};
+
+const struct ss_func_desc ptp_ss_descriptors = {
+ .intf = ptp_interface_desc,
+ .sink = ss_sink,
+ .sink_comp = ss_sink_comp,
+ .source = ss_source,
+ .source_comp = ss_source_comp,
+ .intr = intr,
+ .intr_comp = ss_intr_comp,
+};
+
+const struct functionfs_strings mtp_strings = {
+ .header = {
+ .magic = htole32(FUNCTIONFS_STRINGS_MAGIC),
+ .length = htole32(sizeof(mtp_strings)),
+ .str_count = htole32(1),
+ .lang_count = htole32(1),
+ },
+ .lang0 = {
+ .code = htole16(0x0409),
+ .str1 = STR_INTERFACE,
+ },
+};
+
+const struct usb_os_desc_header mtp_os_desc_header = {
+ .interface = htole32(1),
+ .dwLength = htole32(sizeof(usb_os_desc_header) + sizeof(usb_ext_compat_desc)),
+ .bcdVersion = htole16(1),
+ .wIndex = htole16(4),
+ .bCount = htole16(1),
+ .Reserved = htole16(0),
+};
+
+const struct usb_ext_compat_desc mtp_os_desc_compat = {
+ .bFirstInterfaceNumber = 0,
+ .Reserved1 = htole32(1),
+ .CompatibleID = { 'M', 'T', 'P' },
+ .SubCompatibleID = {0},
+ .Reserved2 = {0},
+};
+
+const struct usb_ext_compat_desc ptp_os_desc_compat = {
+ .bFirstInterfaceNumber = 0,
+ .Reserved1 = htole32(1),
+ .CompatibleID = { 'P', 'T', 'P' },
+ .SubCompatibleID = {0},
+ .Reserved2 = {0},
+};
+
+const struct desc_v2 mtp_desc_v2 = {
+ .header = {
+ .magic = htole32(FUNCTIONFS_DESCRIPTORS_MAGIC_V2),
+ .length = htole32(sizeof(struct desc_v2)),
+ .flags = FUNCTIONFS_HAS_FS_DESC | FUNCTIONFS_HAS_HS_DESC |
+ FUNCTIONFS_HAS_SS_DESC | FUNCTIONFS_HAS_MS_OS_DESC,
+ },
+ .fs_count = 4,
+ .hs_count = 4,
+ .ss_count = 7,
+ .os_count = 1,
+ .fs_descs = mtp_fs_descriptors,
+ .hs_descs = mtp_hs_descriptors,
+ .ss_descs = mtp_ss_descriptors,
+ .os_header = mtp_os_desc_header,
+ .os_desc = mtp_os_desc_compat,
+};
+
+const struct desc_v2 ptp_desc_v2 = {
+ .header = {
+ .magic = htole32(FUNCTIONFS_DESCRIPTORS_MAGIC_V2),
+ .length = htole32(sizeof(struct desc_v2)),
+ .flags = FUNCTIONFS_HAS_FS_DESC | FUNCTIONFS_HAS_HS_DESC |
+ FUNCTIONFS_HAS_SS_DESC | FUNCTIONFS_HAS_MS_OS_DESC,
+ },
+ .fs_count = 4,
+ .hs_count = 4,
+ .ss_count = 7,
+ .os_count = 1,
+ .fs_descs = ptp_fs_descriptors,
+ .hs_descs = ptp_hs_descriptors,
+ .ss_descs = ptp_ss_descriptors,
+ .os_header = mtp_os_desc_header,
+ .os_desc = ptp_os_desc_compat,
+};
+
+const struct desc_v1 mtp_desc_v1 = {
+ .header = {
+ .magic = htole32(FUNCTIONFS_DESCRIPTORS_MAGIC),
+ .length = htole32(sizeof(struct desc_v1)),
+ .fs_count = 4,
+ .hs_count = 4,
+ },
+ .fs_descs = mtp_fs_descriptors,
+ .hs_descs = mtp_hs_descriptors,
+};
+
+const struct desc_v1 ptp_desc_v1 = {
+ .header = {
+ .magic = htole32(FUNCTIONFS_DESCRIPTORS_MAGIC),
+ .length = htole32(sizeof(struct desc_v1)),
+ .fs_count = 4,
+ .hs_count = 4,
+ },
+ .fs_descs = ptp_fs_descriptors,
+ .hs_descs = ptp_hs_descriptors,
+};
+
+}; // namespace android
diff --git a/media/mtp/MtpDescriptors.h b/media/mtp/MtpDescriptors.h
new file mode 100644
index 0000000..cfc3930
--- /dev/null
+++ b/media/mtp/MtpDescriptors.h
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MTP_DESCRIPTORS_H
+#define MTP_DESCRIPTORS_H
+
+#include <linux/usb/ch9.h>
+#include <linux/usb/functionfs.h>
+#include <sys/endian.h>
+
+namespace android {
+
+constexpr int MAX_PACKET_SIZE_FS = 64;
+constexpr int MAX_PACKET_SIZE_HS = 512;
+constexpr int MAX_PACKET_SIZE_SS = 1024;
+constexpr int MAX_PACKET_SIZE_EV = 28;
+
+struct func_desc {
+ struct usb_interface_descriptor intf;
+ struct usb_endpoint_descriptor_no_audio sink;
+ struct usb_endpoint_descriptor_no_audio source;
+ struct usb_endpoint_descriptor_no_audio intr;
+} __attribute__((packed));
+
+struct ss_func_desc {
+ struct usb_interface_descriptor intf;
+ struct usb_endpoint_descriptor_no_audio sink;
+ struct usb_ss_ep_comp_descriptor sink_comp;
+ struct usb_endpoint_descriptor_no_audio source;
+ struct usb_ss_ep_comp_descriptor source_comp;
+ struct usb_endpoint_descriptor_no_audio intr;
+ struct usb_ss_ep_comp_descriptor intr_comp;
+} __attribute__((packed));
+
+struct desc_v1 {
+ struct usb_functionfs_descs_head_v1 {
+ __le32 magic;
+ __le32 length;
+ __le32 fs_count;
+ __le32 hs_count;
+ } __attribute__((packed)) header;
+ struct func_desc fs_descs, hs_descs;
+} __attribute__((packed));
+
+struct desc_v2 {
+ struct usb_functionfs_descs_head_v2 header;
+ // The rest of the structure depends on the flags in the header.
+ __le32 fs_count;
+ __le32 hs_count;
+ __le32 ss_count;
+ __le32 os_count;
+ struct func_desc fs_descs, hs_descs;
+ struct ss_func_desc ss_descs;
+ struct usb_os_desc_header os_header;
+ struct usb_ext_compat_desc os_desc;
+} __attribute__((packed));
+
+// OS descriptor contents should not be changed. See b/64790536.
+static_assert(sizeof(struct desc_v2) == sizeof(usb_functionfs_descs_head_v2) +
+ 16 + 2 * sizeof(struct func_desc) + sizeof(struct ss_func_desc) +
+ sizeof(usb_os_desc_header) + sizeof(usb_ext_compat_desc),
+ "Size of mtp descriptor is incorrect!");
+
+#define STR_INTERFACE "MTP"
+struct functionfs_lang {
+ __le16 code;
+ char str1[sizeof(STR_INTERFACE)];
+} __attribute__((packed));
+
+struct functionfs_strings {
+ struct usb_functionfs_strings_head header;
+ struct functionfs_lang lang0;
+} __attribute__((packed));
+
+extern const struct desc_v2 mtp_desc_v2;
+extern const struct desc_v2 ptp_desc_v2;
+extern const struct desc_v1 mtp_desc_v1;
+extern const struct desc_v1 ptp_desc_v1;
+extern const struct functionfs_strings mtp_strings;
+
+}; // namespace android
+
+#endif // MTP_DESCRIPTORS_H
diff --git a/media/mtp/MtpFfsHandle.cpp b/media/mtp/MtpFfsHandle.cpp
index 965985d..217e0c9 100644
--- a/media/mtp/MtpFfsHandle.cpp
+++ b/media/mtp/MtpFfsHandle.cpp
@@ -20,13 +20,10 @@
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
-#include <linux/usb/ch9.h>
-#include <linux/usb/functionfs.h>
#include <memory>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <sys/endian.h>
#include <sys/eventfd.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
@@ -36,6 +33,7 @@
#include <unistd.h>
#include "PosixAsyncIO.h"
+#include "MtpDescriptors.h"
#include "MtpFfsHandle.h"
#include "mtp.h"
@@ -45,11 +43,6 @@
constexpr char FFS_MTP_EP_OUT[] = "/dev/usb-ffs/mtp/ep2";
constexpr char FFS_MTP_EP_INTR[] = "/dev/usb-ffs/mtp/ep3";
-constexpr int MAX_PACKET_SIZE_FS = 64;
-constexpr int MAX_PACKET_SIZE_HS = 512;
-constexpr int MAX_PACKET_SIZE_SS = 1024;
-constexpr int MAX_PACKET_SIZE_EV = 28;
-
constexpr unsigned AIO_BUFS_MAX = 128;
constexpr unsigned AIO_BUF_LEN = 16384;
@@ -61,234 +54,6 @@
struct timespec ZERO_TIMEOUT = { 0, 0 };
-struct func_desc {
- struct usb_interface_descriptor intf;
- struct usb_endpoint_descriptor_no_audio sink;
- struct usb_endpoint_descriptor_no_audio source;
- struct usb_endpoint_descriptor_no_audio intr;
-} __attribute__((packed));
-
-struct ss_func_desc {
- struct usb_interface_descriptor intf;
- struct usb_endpoint_descriptor_no_audio sink;
- struct usb_ss_ep_comp_descriptor sink_comp;
- struct usb_endpoint_descriptor_no_audio source;
- struct usb_ss_ep_comp_descriptor source_comp;
- struct usb_endpoint_descriptor_no_audio intr;
- struct usb_ss_ep_comp_descriptor intr_comp;
-} __attribute__((packed));
-
-struct desc_v1 {
- struct usb_functionfs_descs_head_v1 {
- __le32 magic;
- __le32 length;
- __le32 fs_count;
- __le32 hs_count;
- } __attribute__((packed)) header;
- struct func_desc fs_descs, hs_descs;
-} __attribute__((packed));
-
-struct desc_v2 {
- struct usb_functionfs_descs_head_v2 header;
- // The rest of the structure depends on the flags in the header.
- __le32 fs_count;
- __le32 hs_count;
- __le32 ss_count;
- __le32 os_count;
- struct func_desc fs_descs, hs_descs;
- struct ss_func_desc ss_descs;
- struct usb_os_desc_header os_header;
- struct usb_ext_compat_desc os_desc;
-} __attribute__((packed));
-
-const struct usb_interface_descriptor mtp_interface_desc = {
- .bLength = USB_DT_INTERFACE_SIZE,
- .bDescriptorType = USB_DT_INTERFACE,
- .bInterfaceNumber = 0,
- .bNumEndpoints = 3,
- .bInterfaceClass = USB_CLASS_STILL_IMAGE,
- .bInterfaceSubClass = 1,
- .bInterfaceProtocol = 1,
- .iInterface = 1,
-};
-
-const struct usb_interface_descriptor ptp_interface_desc = {
- .bLength = USB_DT_INTERFACE_SIZE,
- .bDescriptorType = USB_DT_INTERFACE,
- .bInterfaceNumber = 0,
- .bNumEndpoints = 3,
- .bInterfaceClass = USB_CLASS_STILL_IMAGE,
- .bInterfaceSubClass = 1,
- .bInterfaceProtocol = 1,
-};
-
-const struct usb_endpoint_descriptor_no_audio fs_sink = {
- .bLength = USB_DT_ENDPOINT_SIZE,
- .bDescriptorType = USB_DT_ENDPOINT,
- .bEndpointAddress = 1 | USB_DIR_IN,
- .bmAttributes = USB_ENDPOINT_XFER_BULK,
- .wMaxPacketSize = MAX_PACKET_SIZE_FS,
-};
-
-const struct usb_endpoint_descriptor_no_audio fs_source = {
- .bLength = USB_DT_ENDPOINT_SIZE,
- .bDescriptorType = USB_DT_ENDPOINT,
- .bEndpointAddress = 2 | USB_DIR_OUT,
- .bmAttributes = USB_ENDPOINT_XFER_BULK,
- .wMaxPacketSize = MAX_PACKET_SIZE_FS,
-};
-
-const struct usb_endpoint_descriptor_no_audio intr = {
- .bLength = USB_DT_ENDPOINT_SIZE,
- .bDescriptorType = USB_DT_ENDPOINT,
- .bEndpointAddress = 3 | USB_DIR_IN,
- .bmAttributes = USB_ENDPOINT_XFER_INT,
- .wMaxPacketSize = MAX_PACKET_SIZE_EV,
- .bInterval = 6,
-};
-
-const struct usb_endpoint_descriptor_no_audio hs_sink = {
- .bLength = USB_DT_ENDPOINT_SIZE,
- .bDescriptorType = USB_DT_ENDPOINT,
- .bEndpointAddress = 1 | USB_DIR_IN,
- .bmAttributes = USB_ENDPOINT_XFER_BULK,
- .wMaxPacketSize = MAX_PACKET_SIZE_HS,
-};
-
-const struct usb_endpoint_descriptor_no_audio hs_source = {
- .bLength = USB_DT_ENDPOINT_SIZE,
- .bDescriptorType = USB_DT_ENDPOINT,
- .bEndpointAddress = 2 | USB_DIR_OUT,
- .bmAttributes = USB_ENDPOINT_XFER_BULK,
- .wMaxPacketSize = MAX_PACKET_SIZE_HS,
-};
-
-const struct usb_endpoint_descriptor_no_audio ss_sink = {
- .bLength = USB_DT_ENDPOINT_SIZE,
- .bDescriptorType = USB_DT_ENDPOINT,
- .bEndpointAddress = 1 | USB_DIR_IN,
- .bmAttributes = USB_ENDPOINT_XFER_BULK,
- .wMaxPacketSize = MAX_PACKET_SIZE_SS,
-};
-
-const struct usb_endpoint_descriptor_no_audio ss_source = {
- .bLength = USB_DT_ENDPOINT_SIZE,
- .bDescriptorType = USB_DT_ENDPOINT,
- .bEndpointAddress = 2 | USB_DIR_OUT,
- .bmAttributes = USB_ENDPOINT_XFER_BULK,
- .wMaxPacketSize = MAX_PACKET_SIZE_SS,
-};
-
-const struct usb_ss_ep_comp_descriptor ss_sink_comp = {
- .bLength = sizeof(ss_sink_comp),
- .bDescriptorType = USB_DT_SS_ENDPOINT_COMP,
- .bMaxBurst = 6,
-};
-
-const struct usb_ss_ep_comp_descriptor ss_source_comp = {
- .bLength = sizeof(ss_source_comp),
- .bDescriptorType = USB_DT_SS_ENDPOINT_COMP,
- .bMaxBurst = 6,
-};
-
-const struct usb_ss_ep_comp_descriptor ss_intr_comp = {
- .bLength = sizeof(ss_intr_comp),
- .bDescriptorType = USB_DT_SS_ENDPOINT_COMP,
-};
-
-const struct func_desc mtp_fs_descriptors = {
- .intf = mtp_interface_desc,
- .sink = fs_sink,
- .source = fs_source,
- .intr = intr,
-};
-
-const struct func_desc mtp_hs_descriptors = {
- .intf = mtp_interface_desc,
- .sink = hs_sink,
- .source = hs_source,
- .intr = intr,
-};
-
-const struct ss_func_desc mtp_ss_descriptors = {
- .intf = mtp_interface_desc,
- .sink = ss_sink,
- .sink_comp = ss_sink_comp,
- .source = ss_source,
- .source_comp = ss_source_comp,
- .intr = intr,
- .intr_comp = ss_intr_comp,
-};
-
-const struct func_desc ptp_fs_descriptors = {
- .intf = ptp_interface_desc,
- .sink = fs_sink,
- .source = fs_source,
- .intr = intr,
-};
-
-const struct func_desc ptp_hs_descriptors = {
- .intf = ptp_interface_desc,
- .sink = hs_sink,
- .source = hs_source,
- .intr = intr,
-};
-
-const struct ss_func_desc ptp_ss_descriptors = {
- .intf = ptp_interface_desc,
- .sink = ss_sink,
- .sink_comp = ss_sink_comp,
- .source = ss_source,
- .source_comp = ss_source_comp,
- .intr = intr,
- .intr_comp = ss_intr_comp,
-};
-
-#define STR_INTERFACE "MTP"
-const struct {
- struct usb_functionfs_strings_head header;
- struct {
- __le16 code;
- const char str1[sizeof(STR_INTERFACE)];
- } __attribute__((packed)) lang0;
-} __attribute__((packed)) strings = {
- .header = {
- .magic = htole32(FUNCTIONFS_STRINGS_MAGIC),
- .length = htole32(sizeof(strings)),
- .str_count = htole32(1),
- .lang_count = htole32(1),
- },
- .lang0 = {
- .code = htole16(0x0409),
- .str1 = STR_INTERFACE,
- },
-};
-
-struct usb_os_desc_header mtp_os_desc_header = {
- .interface = htole32(1),
- .dwLength = htole32(sizeof(usb_os_desc_header) + sizeof(usb_ext_compat_desc)),
- .bcdVersion = htole16(1),
- .wIndex = htole16(4),
- .bCount = htole16(1),
- .Reserved = htole16(0),
-};
-
-struct usb_ext_compat_desc mtp_os_desc_compat = {
- .bFirstInterfaceNumber = 0,
- .Reserved1 = htole32(1),
- .CompatibleID = { 'M', 'T', 'P' },
- .SubCompatibleID = {0},
- .Reserved2 = {0},
-};
-
-struct usb_ext_compat_desc ptp_os_desc_compat = {
- .bFirstInterfaceNumber = 0,
- .Reserved1 = htole32(1),
- .CompatibleID = { 'P', 'T', 'P' },
- .SubCompatibleID = {0},
- .Reserved2 = {0},
-};
-
struct mtp_device_status {
uint16_t wLength;
uint16_t wCode;
@@ -357,58 +122,38 @@
}
bool MtpFfsHandle::initFunctionfs() {
- ssize_t ret;
- struct desc_v1 v1_descriptor;
- struct desc_v2 v2_descriptor;
-
- v2_descriptor.header.magic = htole32(FUNCTIONFS_DESCRIPTORS_MAGIC_V2);
- v2_descriptor.header.length = htole32(sizeof(v2_descriptor));
- v2_descriptor.header.flags = FUNCTIONFS_HAS_FS_DESC | FUNCTIONFS_HAS_HS_DESC |
- FUNCTIONFS_HAS_SS_DESC | FUNCTIONFS_HAS_MS_OS_DESC;
- v2_descriptor.fs_count = 4;
- v2_descriptor.hs_count = 4;
- v2_descriptor.ss_count = 7;
- v2_descriptor.os_count = 1;
- v2_descriptor.fs_descs = mPtp ? ptp_fs_descriptors : mtp_fs_descriptors;
- v2_descriptor.hs_descs = mPtp ? ptp_hs_descriptors : mtp_hs_descriptors;
- v2_descriptor.ss_descs = mPtp ? ptp_ss_descriptors : mtp_ss_descriptors;
- v2_descriptor.os_header = mtp_os_desc_header;
- v2_descriptor.os_desc = mPtp ? ptp_os_desc_compat : mtp_os_desc_compat;
-
if (mControl < 0) { // might have already done this before
mControl.reset(TEMP_FAILURE_RETRY(open(FFS_MTP_EP0, O_RDWR)));
if (mControl < 0) {
PLOG(ERROR) << FFS_MTP_EP0 << ": cannot open control endpoint";
- goto err;
+ return false;
}
-
- ret = TEMP_FAILURE_RETRY(::write(mControl, &v2_descriptor, sizeof(v2_descriptor)));
- if (ret < 0) {
- v1_descriptor.header.magic = htole32(FUNCTIONFS_DESCRIPTORS_MAGIC);
- v1_descriptor.header.length = htole32(sizeof(v1_descriptor));
- v1_descriptor.header.fs_count = 4;
- v1_descriptor.header.hs_count = 4;
- v1_descriptor.fs_descs = mPtp ? ptp_fs_descriptors : mtp_fs_descriptors;
- v1_descriptor.hs_descs = mPtp ? ptp_hs_descriptors : mtp_hs_descriptors;
- PLOG(ERROR) << FFS_MTP_EP0 << "Switching to V1 descriptor format";
- ret = TEMP_FAILURE_RETRY(::write(mControl, &v1_descriptor, sizeof(v1_descriptor)));
- if (ret < 0) {
- PLOG(ERROR) << FFS_MTP_EP0 << "Writing descriptors failed";
- goto err;
- }
- }
- ret = TEMP_FAILURE_RETRY(::write(mControl, &strings, sizeof(strings)));
- if (ret < 0) {
- PLOG(ERROR) << FFS_MTP_EP0 << "Writing strings failed";
- goto err;
+ if (!writeDescriptors()) {
+ closeConfig();
+ return false;
}
}
-
return true;
+}
-err:
- closeConfig();
- return false;
+bool MtpFfsHandle::writeDescriptors() {
+ ssize_t ret = TEMP_FAILURE_RETRY(::write(mControl,
+ &(mPtp ? ptp_desc_v2 : mtp_desc_v2), sizeof(desc_v2)));
+ if (ret < 0) {
+ PLOG(ERROR) << FFS_MTP_EP0 << "Switching to V1 descriptor format";
+ ret = TEMP_FAILURE_RETRY(::write(mControl,
+ &(mPtp ? ptp_desc_v1 : mtp_desc_v1), sizeof(desc_v1)));
+ if (ret < 0) {
+ PLOG(ERROR) << FFS_MTP_EP0 << "Writing descriptors failed";
+ return false;
+ }
+ }
+ ret = TEMP_FAILURE_RETRY(::write(mControl, &mtp_strings, sizeof(mtp_strings)));
+ if (ret < 0) {
+ PLOG(ERROR) << FFS_MTP_EP0 << "Writing strings failed";
+ return false;
+ }
+ return true;
}
void MtpFfsHandle::closeConfig() {
@@ -566,7 +311,7 @@
int MtpFfsHandle::configure(bool usePtp) {
// Wait till previous server invocation has closed
- if (!mLock.try_lock_for(std::chrono::milliseconds(1000))) {
+ if (!mLock.try_lock_for(std::chrono::milliseconds(300))) {
LOG(ERROR) << "MtpServer was unable to get configure lock";
return -1;
}
diff --git a/media/mtp/MtpFfsHandle.h b/media/mtp/MtpFfsHandle.h
index 2f90bd1..2347000 100644
--- a/media/mtp/MtpFfsHandle.h
+++ b/media/mtp/MtpFfsHandle.h
@@ -42,11 +42,14 @@
};
template <class T> class MtpFfsHandleTest;
+template <class T> class MtpFfsHandleTest_testControl_Test;
class MtpFfsHandle : public IMtpHandle {
- template <class T> friend class android::MtpFfsHandleTest;
+ template <class T> friend class MtpFfsHandleTest;
+ template <class T> friend class MtpFfsHandleTest_testControl_Test;
protected:
bool initFunctionfs();
+ bool writeDescriptors();
void closeConfig();
void closeEndpoints();
void advise(int fd);
diff --git a/media/mtp/MtpServer.cpp b/media/mtp/MtpServer.cpp
index 236f3a9..6080868 100644
--- a/media/mtp/MtpServer.cpp
+++ b/media/mtp/MtpServer.cpp
@@ -14,6 +14,7 @@
* limitations under the License.
*/
+#include <android-base/logging.h>
#include <android-base/properties.h>
#include <chrono>
#include <dirent.h>
@@ -99,16 +100,12 @@
};
MtpServer::MtpServer(MtpDatabase* database, bool ptp,
- int fileGroup, int filePerm, int directoryPerm,
const MtpString& deviceInfoManufacturer,
const MtpString& deviceInfoModel,
const MtpString& deviceInfoDeviceVersion,
const MtpString& deviceInfoSerialNumber)
: mDatabase(database),
mPtp(ptp),
- mFileGroup(fileGroup),
- mFilePermission(filePerm),
- mDirectoryPermission(directoryPerm),
mDeviceInfoManufacturer(deviceInfoManufacturer),
mDeviceInfoModel(deviceInfoModel),
mDeviceInfoDeviceVersion(deviceInfoDeviceVersion),
@@ -137,12 +134,11 @@
sHandle = new MtpDevHandle();
}
}
- if (sHandle->configure(usePtp)) {
- ALOGE("Failed to configure Mtp driver!");
- return -1;
- }
+
+ int ret = sHandle->configure(usePtp);
+ if (ret) ALOGE("Failed to configure MTP driver!");
android::base::SetProperty("sys.usb.ffs.mtp.ready", "1");
- return 0;
+ return ret;
}
void MtpServer::addStorage(MtpStorage* storage) {
@@ -1002,12 +998,9 @@
}
if (format == MTP_FORMAT_ASSOCIATION) {
- mode_t mask = umask(0);
- int ret = mkdir((const char *)path, mDirectoryPermission);
- umask(mask);
- if (ret && ret != -EEXIST)
+ int ret = makeFolder((const char *)path);
+ if (ret)
return MTP_RESPONSE_GENERAL_ERROR;
- chown((const char *)path, getuid(), mFileGroup);
// SendObject does not get sent for directories, so call endSendObject here instead
mDatabase->endSendObject(path, handle, MTP_FORMAT_ASSOCIATION, MTP_RESPONSE_OK);
@@ -1068,29 +1061,34 @@
path += "/";
path += info.mName;
- result = mDatabase->moveObject(objectHandle, parent, path);
- if (result != MTP_RESPONSE_OK)
- return result;
-
if (info.mStorageID == storageID) {
ALOGV("Moving file from %s to %s", (const char*)fromPath, (const char*)path);
if (rename(fromPath, path)) {
- ALOGE("rename() failed from %s to %s", (const char*)fromPath, (const char*)path);
+ PLOG(ERROR) << "rename() failed from " << fromPath << " to " << path;
result = MTP_RESPONSE_GENERAL_ERROR;
}
} else {
ALOGV("Moving across storages from %s to %s", (const char*)fromPath, (const char*)path);
- if (copyFile(fromPath, path)) {
- result = MTP_RESPONSE_GENERAL_ERROR;
+ if (format == MTP_FORMAT_ASSOCIATION) {
+ int ret = makeFolder((const char *)path);
+ ret += copyRecursive(fromPath, path);
+ if (ret) {
+ result = MTP_RESPONSE_GENERAL_ERROR;
+ } else {
+ deletePath(fromPath);
+ }
} else {
- deletePath(fromPath);
+ if (copyFile(fromPath, path)) {
+ result = MTP_RESPONSE_GENERAL_ERROR;
+ } else {
+ deletePath(fromPath);
+ }
}
}
// If the move failed, undo the database change
- if (result != MTP_RESPONSE_OK)
- if (mDatabase->moveObject(objectHandle, info.mParent, fromPath) != MTP_RESPONSE_OK)
- ALOGE("Couldn't undo failed move");
+ if (result == MTP_RESPONSE_OK)
+ result = mDatabase->moveObject(objectHandle, parent, storageID, path);
return result;
}
@@ -1148,8 +1146,15 @@
}
ALOGV("Copying file from %s to %s", (const char*)fromPath, (const char*)path);
- if (copyFile(fromPath, path)) {
- result = MTP_RESPONSE_GENERAL_ERROR;
+ if (format == MTP_FORMAT_ASSOCIATION) {
+ int ret = makeFolder((const char *)path);
+ if (ret) {
+ result = MTP_RESPONSE_GENERAL_ERROR;
+ }
+ } else {
+ if (copyFile(fromPath, path)) {
+ result = MTP_RESPONSE_GENERAL_ERROR;
+ }
}
mDatabase->endSendObject(path, handle, format, result);
@@ -1188,10 +1193,10 @@
result = MTP_RESPONSE_GENERAL_ERROR;
goto done;
}
- fchown(mfr.fd, getuid(), mFileGroup);
+ fchown(mfr.fd, getuid(), FILE_GROUP);
// set permissions
mask = umask(0);
- fchmod(mfr.fd, mFilePermission);
+ fchmod(mfr.fd, FILE_PERM);
umask(mask);
if (initialData > 0) {
diff --git a/media/mtp/MtpServer.h b/media/mtp/MtpServer.h
index aafc753..0204b09 100644
--- a/media/mtp/MtpServer.h
+++ b/media/mtp/MtpServer.h
@@ -43,12 +43,6 @@
// appear as a PTP device
bool mPtp;
- // group to own new files and folders
- int mFileGroup;
- // permissions for new files and directories
- int mFilePermission;
- int mDirectoryPermission;
-
// Manufacturer to report in DeviceInfo
MtpString mDeviceInfoManufacturer;
// Model to report in DeviceInfo
@@ -105,7 +99,6 @@
public:
MtpServer(MtpDatabase* database, bool ptp,
- int fileGroup, int filePerm, int directoryPerm,
const MtpString& deviceInfoManufacturer,
const MtpString& deviceInfoModel,
const MtpString& deviceInfoDeviceVersion,
diff --git a/media/mtp/MtpUtils.cpp b/media/mtp/MtpUtils.cpp
index 036ffe7..3f5648b 100644
--- a/media/mtp/MtpUtils.cpp
+++ b/media/mtp/MtpUtils.cpp
@@ -20,6 +20,7 @@
#include <android-base/unique_fd.h>
#include <dirent.h>
#include <fcntl.h>
+#include <string>
#include <sys/sendfile.h>
#include <sys/stat.h>
#include <sys/types.h>
@@ -29,6 +30,8 @@
#include "MtpUtils.h"
+using namespace std;
+
namespace android {
constexpr unsigned long FILE_COPY_SIZE = 262144;
@@ -88,6 +91,60 @@
tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec);
}
+int makeFolder(const char *path) {
+ mode_t mask = umask(0);
+ int ret = mkdir((const char *)path, DIR_PERM);
+ umask(mask);
+ if (ret && ret != -EEXIST) {
+ PLOG(ERROR) << "Failed to create folder " << path;
+ ret = -1;
+ } else {
+ chown((const char *)path, getuid(), FILE_GROUP);
+ }
+ return ret;
+}
+
+/**
+ * Copies target path and all children to destination path.
+ *
+ * Returns 0 on success or a negative value indicating number of failures
+ */
+int copyRecursive(const char *fromPath, const char *toPath) {
+ int ret = 0;
+ string fromPathStr(fromPath);
+ string toPathStr(toPath);
+
+ DIR* dir = opendir(fromPath);
+ if (!dir) {
+ PLOG(ERROR) << "opendir " << fromPath << " failed";
+ return -1;
+ }
+ if (fromPathStr[fromPathStr.size()-1] != '/')
+ fromPathStr += '/';
+ if (toPathStr[toPathStr.size()-1] != '/')
+ toPathStr += '/';
+
+ struct dirent* entry;
+ while ((entry = readdir(dir))) {
+ const char* name = entry->d_name;
+
+ // ignore "." and ".."
+ if (name[0] == '.' && (name[1] == 0 || (name[1] == '.' && name[2] == 0))) {
+ continue;
+ }
+ string oldFile = fromPathStr + name;
+ string newFile = toPathStr + name;
+
+ if (entry->d_type == DT_DIR) {
+ ret += makeFolder(newFile.c_str());
+ ret += copyRecursive(oldFile.c_str(), newFile.c_str());
+ } else {
+ ret += copyFile(oldFile.c_str(), newFile.c_str());
+ }
+ }
+ return ret;
+}
+
int copyFile(const char *fromPath, const char *toPath) {
auto start = std::chrono::steady_clock::now();
@@ -96,7 +153,7 @@
PLOG(ERROR) << "Failed to open copy from " << fromPath;
return -1;
}
- android::base::unique_fd toFd(open(toPath, O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR));
+ android::base::unique_fd toFd(open(toPath, O_CREAT | O_WRONLY, FILE_PERM));
if (toFd == -1) {
PLOG(ERROR) << "Failed to open copy to " << toPath;
return -1;
@@ -121,23 +178,17 @@
}
auto end = std::chrono::steady_clock::now();
std::chrono::duration<double> diff = end - start;
- LOG(INFO) << "Copied a file with MTP. Time: " << diff.count() << " s, Size: " << length <<
+ LOG(DEBUG) << "Copied a file with MTP. Time: " << diff.count() << " s, Size: " << length <<
", Rate: " << ((double) length) / diff.count() << " bytes/s";
+ chown(toPath, getuid(), FILE_GROUP);
return ret == -1 ? -1 : 0;
}
void deleteRecursive(const char* path) {
- char pathbuf[PATH_MAX];
- size_t pathLength = strlen(path);
- if (pathLength >= sizeof(pathbuf) - 1) {
- LOG(ERROR) << "path too long: " << path;
+ string pathStr(path);
+ if (pathStr[pathStr.size()-1] != '/') {
+ pathStr += '/';
}
- strcpy(pathbuf, path);
- if (pathbuf[pathLength - 1] != '/') {
- pathbuf[pathLength++] = '/';
- }
- char* fileSpot = pathbuf + pathLength;
- int pathRemaining = sizeof(pathbuf) - pathLength - 1;
DIR* dir = opendir(path);
if (!dir) {
@@ -153,19 +204,12 @@
if (name[0] == '.' && (name[1] == 0 || (name[1] == '.' && name[2] == 0))) {
continue;
}
-
- int nameLength = strlen(name);
- if (nameLength > pathRemaining) {
- LOG(ERROR) << "path " << path << "/" << name << " too long";
- continue;
- }
- strcpy(fileSpot, name);
-
+ pathStr.append(name);
if (entry->d_type == DT_DIR) {
- deleteRecursive(pathbuf);
- rmdir(pathbuf);
+ deleteRecursive(pathStr.c_str());
+ rmdir(pathStr.c_str());
} else {
- unlink(pathbuf);
+ unlink(pathStr.c_str());
}
}
closedir(dir);
diff --git a/media/mtp/MtpUtils.h b/media/mtp/MtpUtils.h
index a2bb7e1..b7c72f5 100644
--- a/media/mtp/MtpUtils.h
+++ b/media/mtp/MtpUtils.h
@@ -17,13 +17,21 @@
#ifndef _MTP_UTILS_H
#define _MTP_UTILS_H
+#include "private/android_filesystem_config.h"
+
#include <stdint.h>
namespace android {
+constexpr int FILE_GROUP = AID_MEDIA_RW;
+constexpr int FILE_PERM = 0664;
+constexpr int DIR_PERM = 0775;
+
bool parseDateTime(const char* dateTime, time_t& outSeconds);
void formatDateTime(time_t seconds, char* buffer, int bufferLength);
+int makeFolder(const char *path);
+int copyRecursive(const char *fromPath, const char *toPath);
int copyFile(const char *fromPath, const char *toPath);
void deleteRecursive(const char* path);
void deletePath(const char* path);
diff --git a/media/mtp/OWNERS b/media/mtp/OWNERS
new file mode 100644
index 0000000..219307b
--- /dev/null
+++ b/media/mtp/OWNERS
@@ -0,0 +1 @@
+zhangjerry@google.com
diff --git a/media/mtp/tests/MtpFfsHandle_test.cpp b/media/mtp/tests/MtpFfsHandle_test.cpp
index 8d7301d..9c916b7 100644
--- a/media/mtp/tests/MtpFfsHandle_test.cpp
+++ b/media/mtp/tests/MtpFfsHandle_test.cpp
@@ -25,6 +25,7 @@
#include <unistd.h>
#include <utils/Log.h>
+#include "MtpDescriptors.h"
#include "MtpFfsHandle.h"
#include "MtpFfsCompatHandle.h"
@@ -66,8 +67,8 @@
handle = std::make_unique<T>();
EXPECT_EQ(pipe(fd), 0);
- handle->mControl.reset(fd[0]);
- control.reset(fd[1]);
+ control.reset(fd[0]);
+ handle->mControl.reset(fd[1]);
EXPECT_EQ(pipe(fd), 0);
EXPECT_EQ(fcntl(fd[0], F_SETPIPE_SZ, 1048576), 1048576);
@@ -83,7 +84,7 @@
intr.reset(fd[0]);
handle->mIntr.reset(fd[1]);
- handle->start();
+ EXPECT_EQ(handle->start(), 0);
}
~MtpFfsHandleTest() {
@@ -94,6 +95,16 @@
typedef ::testing::Types<MtpFfsHandle, MtpFfsCompatHandle> mtpHandles;
TYPED_TEST_CASE(MtpFfsHandleTest, mtpHandles);
+TYPED_TEST(MtpFfsHandleTest, testControl) {
+ EXPECT_TRUE(this->handle->writeDescriptors());
+ struct desc_v2 desc;
+ struct functionfs_strings strings;
+ EXPECT_EQ(read(this->control, &desc, sizeof(desc)), (long)sizeof(desc));
+ EXPECT_EQ(read(this->control, &strings, sizeof(strings)), (long)sizeof(strings));
+ EXPECT_TRUE(std::memcmp(&desc, &mtp_desc_v2, sizeof(desc)) == 0);
+ EXPECT_TRUE(std::memcmp(&strings, &mtp_strings, sizeof(strings)) == 0);
+}
+
TYPED_TEST(MtpFfsHandleTest, testRead) {
EXPECT_EQ(write(this->bulk_out, dummyDataStr.c_str(), TEST_PACKET_SIZE), TEST_PACKET_SIZE);
char buf[TEST_PACKET_SIZE + 1];
diff --git a/services/mediaextractor/seccomp_policy/mediaextractor-arm64.policy b/services/mediaextractor/seccomp_policy/mediaextractor-arm64.policy
index d1278a9..eed804a 100644
--- a/services/mediaextractor/seccomp_policy/mediaextractor-arm64.policy
+++ b/services/mediaextractor/seccomp_policy/mediaextractor-arm64.policy
@@ -19,6 +19,7 @@
setpriority: 1
sigaltstack: 1
clone: 1
+sched_setscheduler: 1
lseek: 1
newfstatat: 1
faccessat: 1
diff --git a/services/medialog/Android.bp b/services/medialog/Android.bp
new file mode 100644
index 0000000..1f811d3
--- /dev/null
+++ b/services/medialog/Android.bp
@@ -0,0 +1,21 @@
+cc_library_shared {
+ name: "libmedialogservice",
+
+ srcs: [
+ "IMediaLogService.cpp",
+ "MediaLogService.cpp",
+ ],
+
+ shared_libs: [
+ "libaudioutils",
+ "libbinder",
+ "liblog",
+ "libnbaio",
+ "libutils",
+ ],
+
+ cflags: [
+ "-Werror",
+ "-Wall",
+ ],
+}
diff --git a/services/medialog/Android.mk b/services/medialog/Android.mk
deleted file mode 100644
index 423b186..0000000
--- a/services/medialog/Android.mk
+++ /dev/null
@@ -1,17 +0,0 @@
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := MediaLogService.cpp IMediaLogService.cpp
-
-LOCAL_SHARED_LIBRARIES := libbinder libutils liblog libnbaio libaudioutils
-
-LOCAL_MULTILIB := $(AUDIOSERVER_MULTILIB)
-
-LOCAL_MODULE:= libmedialogservice
-
-LOCAL_C_INCLUDES := $(call include-path-for, audio-utils)
-
-LOCAL_CFLAGS := -Werror -Wall
-
-include $(BUILD_SHARED_LIBRARY)
diff --git a/services/minijail/Android.mk b/services/minijail/Android.mk
index 6b35d91..67055a8 100644
--- a/services/minijail/Android.mk
+++ b/services/minijail/Android.mk
@@ -1,9 +1,12 @@
LOCAL_PATH := $(call my-dir)
+minijail_common_cflags := -Wall -Werror
+
# Small library for media.extractor and media.codec sandboxing.
include $(CLEAR_VARS)
LOCAL_MODULE := libavservices_minijail
LOCAL_SRC_FILES := minijail.cpp
+LOCAL_CFLAGS := $(minijail_common_cflags)
LOCAL_SHARED_LIBRARIES := libbase libminijail
LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)
include $(BUILD_SHARED_LIBRARY)
@@ -13,6 +16,7 @@
LOCAL_MODULE := libavservices_minijail_vendor
LOCAL_VENDOR_MODULE := true
LOCAL_SRC_FILES := minijail.cpp
+LOCAL_CFLAGS := $(minijail_common_cflags)
LOCAL_SHARED_LIBRARIES := libbase libminijail
LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)
include $(BUILD_SHARED_LIBRARY)
@@ -21,5 +25,6 @@
include $(CLEAR_VARS)
LOCAL_MODULE := libavservices_minijail_unittest
LOCAL_SRC_FILES := minijail.cpp av_services_minijail_unittest.cpp
+LOCAL_CFLAGS := $(minijail_common_cflags)
LOCAL_SHARED_LIBRARIES := libbase libminijail
include $(BUILD_NATIVE_TEST)