Merge "audioflinger: keep wakelock during offload playback" into nyc-dev
diff --git a/camera/ndk/NdkCameraCaptureSession.cpp b/camera/ndk/NdkCameraCaptureSession.cpp
index ab93bd6..d6eff24 100644
--- a/camera/ndk/NdkCameraCaptureSession.cpp
+++ b/camera/ndk/NdkCameraCaptureSession.cpp
@@ -122,7 +122,16 @@
 }
 
 EXPORT
-camera_status_t ACameraCaptureSession_abortCaptures(ACameraCaptureSession*) {
+camera_status_t ACameraCaptureSession_abortCaptures(ACameraCaptureSession* session) {
     ATRACE_CALL();
-    return ACAMERA_OK;
+    if (session == nullptr) {
+        ALOGE("%s: Error: session is null", __FUNCTION__);
+        return ACAMERA_ERROR_INVALID_PARAMETER;
+    }
+
+    if (session->isClosed()) {
+        ALOGE("%s: session %p is already closed", __FUNCTION__, session);
+        return ACAMERA_ERROR_SESSION_CLOSED;
+    }
+    return session->abortCaptures();
 }
diff --git a/camera/ndk/impl/ACameraCaptureSession.cpp b/camera/ndk/impl/ACameraCaptureSession.cpp
index b741e46..b9c159d 100644
--- a/camera/ndk/impl/ACameraCaptureSession.cpp
+++ b/camera/ndk/impl/ACameraCaptureSession.cpp
@@ -90,6 +90,24 @@
 }
 
 camera_status_t
+ACameraCaptureSession::abortCaptures() {
+    sp<CameraDevice> dev = getDeviceSp();
+    if (dev == nullptr) {
+        ALOGE("Error: Device associated with session %p has been closed!", this);
+        return ACAMERA_ERROR_SESSION_CLOSED;
+    }
+
+    camera_status_t ret;
+    dev->lockDeviceForSessionOps();
+    {
+        Mutex::Autolock _l(mSessionLock);
+        ret = dev->flushLocked(this);
+    }
+    dev->unlockDevice();
+    return ret;
+}
+
+camera_status_t
 ACameraCaptureSession::setRepeatingRequest(
         /*optional*/ACameraCaptureSession_captureCallbacks* cbs,
         int numRequests, ACaptureRequest** requests,
diff --git a/camera/ndk/impl/ACameraCaptureSession.h b/camera/ndk/impl/ACameraCaptureSession.h
index f20b324..58428e6 100644
--- a/camera/ndk/impl/ACameraCaptureSession.h
+++ b/camera/ndk/impl/ACameraCaptureSession.h
@@ -77,6 +77,8 @@
 
     camera_status_t stopRepeating();
 
+    camera_status_t abortCaptures();
+
     camera_status_t setRepeatingRequest(
             /*optional*/ACameraCaptureSession_captureCallbacks* cbs,
             int numRequests, ACaptureRequest** requests,
@@ -104,7 +106,6 @@
     const wp<CameraDevice> mDevice;
     bool  mIsClosed = false;
     bool  mClosedByApp = false;
-    bool  mIdle = true;
     Mutex mSessionLock;
 };
 
diff --git a/camera/ndk/impl/ACameraDevice.cpp b/camera/ndk/impl/ACameraDevice.cpp
index 6bca692..8f1115a 100644
--- a/camera/ndk/impl/ACameraDevice.cpp
+++ b/camera/ndk/impl/ACameraDevice.cpp
@@ -170,6 +170,7 @@
     // set new session as current session
     newSession->incStrong((void *) ACameraDevice_createCaptureSession);
     mCurrentSession = newSession;
+    mFlushing = false;
     *session = newSession;
     return ACAMERA_OK;
 }
@@ -389,6 +390,58 @@
 }
 
 camera_status_t
+CameraDevice::flushLocked(ACameraCaptureSession* session) {
+    camera_status_t ret = checkCameraClosedOrErrorLocked();
+    if (ret != ACAMERA_OK) {
+        ALOGE("Camera %s abort captures failed! ret %d", getId(), ret);
+        return ret;
+    }
+
+    // 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) {
+        ALOGE("Camera %s session %p is not current active session!", getId(), session);
+        return ACAMERA_ERROR_INVALID_OPERATION;
+    }
+
+    if (mFlushing) {
+        ALOGW("Camera %s is already aborting captures", getId());
+        return ACAMERA_OK;
+    }
+
+    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();
+
+    // If device is already idling, send callback and exit early
+    if (mIdle) {
+        sp<AMessage> msg = new AMessage(kWhatSessionStateCb, mHandler);
+        msg->setPointer(kContextKey, session->mUserSessionCallback.context);
+        msg->setObject(kSessionSpKey, session);
+        msg->setPointer(kCallbackFpKey, (void*) session->mUserSessionCallback.onReady);
+        msg->post();
+        mFlushing = false;
+        return ACAMERA_OK;
+    }
+
+    int64_t lastFrameNumber;
+    binder::Status remoteRet = mRemote->flush(&lastFrameNumber);
+    if (!remoteRet.isOk()) {
+        ALOGE("Abort captures fails in remote: %s", remoteRet.toString8().string());
+        return ACAMERA_ERROR_UNKNOWN;
+    }
+    if (mRepeatingSequenceId != REQUEST_ID_NONE) {
+        checkRepeatingSequenceCompleteLocked(mRepeatingSequenceId, lastFrameNumber);
+    }
+    return ACAMERA_OK;
+}
+
+camera_status_t
 CameraDevice::waitUntilIdleLocked() {
     camera_status_t ret = checkCameraClosedOrErrorLocked();
     if (ret != ACAMERA_OK) {
@@ -1109,6 +1162,7 @@
         msg->post();
     }
     dev->mIdle = true;
+    dev->mFlushing = false;
     return ret;
 }
 
diff --git a/camera/ndk/impl/ACameraDevice.h b/camera/ndk/impl/ACameraDevice.h
index 46243b9..fd51a81 100644
--- a/camera/ndk/impl/ACameraDevice.h
+++ b/camera/ndk/impl/ACameraDevice.h
@@ -96,6 +96,8 @@
 
     camera_status_t stopRepeatingLocked();
 
+    camera_status_t flushLocked(ACameraCaptureSession*);
+
     camera_status_t waitUntilIdleLocked();
 
 
@@ -152,13 +154,13 @@
     std::atomic_bool mClosing;
     inline bool isClosed() { return mClosing; }
 
-    bool mInError;
-    camera_status_t mError;
+    bool mInError = false;
+    camera_status_t mError = ACAMERA_OK;
     void onCaptureErrorLocked(
             int32_t errorCode,
             const CaptureResultExtras& resultExtras);
 
-    bool mIdle;
+    bool mIdle = true;
     // This will avoid a busy session being deleted before it's back to idle state
     sp<ACameraCaptureSession> mBusySession;
 
@@ -203,6 +205,7 @@
      ***********************************/
     // The current active session
     ACameraCaptureSession* mCurrentSession = nullptr;
+    bool mFlushing = false;
 
     int mNextSessionId = 0;
     // TODO: might need another looper/handler to handle callbacks from service
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp
index d6a9f53..aebe479 100644
--- a/media/libstagefright/ACodec.cpp
+++ b/media/libstagefright/ACodec.cpp
@@ -3945,15 +3945,14 @@
 
         h264type.eProfile = static_cast<OMX_VIDEO_AVCPROFILETYPE>(profile);
         h264type.eLevel = static_cast<OMX_VIDEO_AVCLEVELTYPE>(level);
-    }
-
-    // XXX
-    if (h264type.eProfile != OMX_VIDEO_AVCProfileBaseline) {
-        ALOGW("Use baseline profile instead of %d for AVC recording",
-            h264type.eProfile);
+    } else {
+        // Use baseline profile for AVC recording if profile is not specified.
         h264type.eProfile = OMX_VIDEO_AVCProfileBaseline;
     }
 
+    ALOGI("setupAVCEncoderParameters with [profile: %s] [level: %s]",
+            asString(h264type.eProfile), asString(h264type.eLevel));
+
     if (h264type.eProfile == OMX_VIDEO_AVCProfileBaseline) {
         h264type.nSliceHeaderSpacing = 0;
         h264type.bUseHadamard = OMX_TRUE;
@@ -3971,6 +3970,23 @@
         h264type.bDirect8x8Inference = OMX_FALSE;
         h264type.bDirectSpatialTemporal = OMX_FALSE;
         h264type.nCabacInitIdc = 0;
+    } else if (h264type.eProfile == OMX_VIDEO_AVCProfileMain ||
+            h264type.eProfile == OMX_VIDEO_AVCProfileHigh) {
+        h264type.nSliceHeaderSpacing = 0;
+        h264type.bUseHadamard = OMX_TRUE;
+        h264type.nRefFrames = 2;
+        h264type.nBFrames = 1;
+        h264type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
+        h264type.nAllowedPictureTypes =
+            OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP | OMX_VIDEO_PictureTypeB;
+        h264type.nRefIdx10ActiveMinus1 = 0;
+        h264type.nRefIdx11ActiveMinus1 = 0;
+        h264type.bEntropyCodingCABAC = OMX_TRUE;
+        h264type.bWeightedPPrediction = OMX_TRUE;
+        h264type.bconstIpred = OMX_TRUE;
+        h264type.bDirect8x8Inference = OMX_TRUE;
+        h264type.bDirectSpatialTemporal = OMX_TRUE;
+        h264type.nCabacInitIdc = 1;
     }
 
     if (h264type.nBFrames != 0) {
diff --git a/media/libstagefright/MPEG4Writer.cpp b/media/libstagefright/MPEG4Writer.cpp
index 58bfa67..7a8f4c0 100644
--- a/media/libstagefright/MPEG4Writer.cpp
+++ b/media/libstagefright/MPEG4Writer.cpp
@@ -2550,8 +2550,8 @@
             ((timestampUs * mTimeScale + 500000LL) / 1000000LL -
                 (lastTimestampUs * mTimeScale + 500000LL) / 1000000LL);
         if (currDurationTicks < 0ll) {
-            ALOGE("timestampUs %" PRId64 " < lastTimestampUs %" PRId64 " for %s track",
-                timestampUs, lastTimestampUs, trackName);
+            ALOGE("do not support out of order frames (timestamp: %lld < last: %lld for %s track",
+                    (long long)timestampUs, (long long)lastTimestampUs, trackName);
             copy->release();
             mSource->stop();
             return UNKNOWN_ERROR;
diff --git a/media/libstagefright/codecs/amrwbenc/src/voAMRWBEnc.c b/media/libstagefright/codecs/amrwbenc/src/voAMRWBEnc.c
index 4cafb01..3bdf93a 100644
--- a/media/libstagefright/codecs/amrwbenc/src/voAMRWBEnc.c
+++ b/media/libstagefright/codecs/amrwbenc/src/voAMRWBEnc.c
@@ -1301,10 +1301,10 @@
 
             for (i = 0; i < L_SUBFR; i++)
             {
-                L_tmp = (code2[i] * gain_code)<<1;
-                L_tmp = (L_tmp << 5);
-                L_tmp += (exc2[i] * gain_pit)<<1;
-                L_tmp = (L_tmp << 1);
+                L_tmp = L_mult(code2[i], gain_code);
+                L_tmp = L_shl(L_tmp, 5);
+                L_tmp = L_add(L_tmp, L_mult(exc2[i], gain_pit));
+                L_tmp = L_shl(L_tmp, 1);
                 exc2[i] = voround(L_tmp);
             }
 
diff --git a/media/libstagefright/codecs/opus/dec/SoftOpus.cpp b/media/libstagefright/codecs/opus/dec/SoftOpus.cpp
index 2afa0ed..ad122de 100644
--- a/media/libstagefright/codecs/opus/dec/SoftOpus.cpp
+++ b/media/libstagefright/codecs/opus/dec/SoftOpus.cpp
@@ -458,12 +458,17 @@
 
         const uint8_t *data = inHeader->pBuffer + inHeader->nOffset;
         const uint32_t size = inHeader->nFilledLen;
+        size_t frameSize = kMaxOpusOutputPacketSizeSamples;
+        if (frameSize > outHeader->nAllocLen / sizeof(int16_t) / mHeader->channels) {
+            frameSize = outHeader->nAllocLen / sizeof(int16_t) / mHeader->channels;
+            android_errorWriteLog(0x534e4554, "27887390");
+        }
 
         int numFrames = opus_multistream_decode(mDecoder,
                                                 data,
                                                 size,
                                                 (int16_t *)outHeader->pBuffer,
-                                                kMaxOpusOutputPacketSizeSamples,
+                                                frameSize,
                                                 0);
         if (numFrames < 0) {
             ALOGE("opus_multistream_decode returned %d", numFrames);
diff --git a/media/libstagefright/codecs/vorbis/dec/SoftVorbis.cpp b/media/libstagefright/codecs/vorbis/dec/SoftVorbis.cpp
index 6a689c4..e1af9b9 100644
--- a/media/libstagefright/codecs/vorbis/dec/SoftVorbis.cpp
+++ b/media/libstagefright/codecs/vorbis/dec/SoftVorbis.cpp
@@ -274,6 +274,13 @@
 
         const uint8_t *data = header->pBuffer + header->nOffset;
         size_t size = header->nFilledLen;
+        if (size < 7) {
+            ALOGE("Too small input buffer: %zu bytes", size);
+            android_errorWriteLog(0x534e4554, "27887390");
+            notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
+            mSignalledError = true;
+            return;
+        }
 
         ogg_buffer buf;
         ogg_reference ref;
@@ -395,9 +402,14 @@
             ALOGW("vorbis_dsp_synthesis returned %d", err);
 #endif
         } else {
+            size_t numSamplesPerBuffer = kMaxNumSamplesPerBuffer;
+            if (numSamplesPerBuffer > outHeader->nAllocLen / sizeof(int16_t)) {
+                numSamplesPerBuffer = outHeader->nAllocLen / sizeof(int16_t);
+                android_errorWriteLog(0x534e4554, "27887390");
+            }
             numFrames = vorbis_dsp_pcmout(
                     mState, (int16_t *)outHeader->pBuffer,
-                    (kMaxNumSamplesPerBuffer / mVi->channels));
+                    (numSamplesPerBuffer / mVi->channels));
 
             if (numFrames < 0) {
                 ALOGE("vorbis_dsp_pcmout returned %d", numFrames);
diff --git a/media/mediaserver/Android.mk b/media/mediaserver/Android.mk
index 2cec5d2..1738df8 100644
--- a/media/mediaserver/Android.mk
+++ b/media/mediaserver/Android.mk
@@ -5,6 +5,7 @@
 LOCAL_SRC_FILES := register.cpp
 LOCAL_MODULE := libregistermsext
 LOCAL_MODULE_TAGS := optional
+LOCAL_CFLAGS := -Werror -Wall
 include $(BUILD_STATIC_LIBRARY)
 endif
 
@@ -39,4 +40,6 @@
 
 LOCAL_INIT_RC := mediaserver.rc
 
+LOCAL_CFLAGS := -Werror -Wall
+
 include $(BUILD_EXECUTABLE)
diff --git a/radio/Android.mk b/radio/Android.mk
index ecbb8fd..0377328 100644
--- a/radio/Android.mk
+++ b/radio/Android.mk
@@ -36,4 +36,6 @@
 
 LOCAL_MODULE:= libradio
 
+LOCAL_CFLAGS := -Werror -Wall
+
 include $(BUILD_SHARED_LIBRARY)
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index 68339d0..b82682d 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -2531,6 +2531,10 @@
 {
     if (!mMasterMute) {
         char value[PROPERTY_VALUE_MAX];
+        if (mOutDevice == AUDIO_DEVICE_OUT_REMOTE_SUBMIX) {
+            ALOGD("ro.audio.silent will be ignored for threads on AUDIO_DEVICE_OUT_REMOTE_SUBMIX");
+            return;
+        }
         if (property_get("ro.audio.silent", value, "0") > 0) {
             char *endptr;
             unsigned long ul = strtoul(value, &endptr, 0);
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index d25dabd..7913adc 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -3678,7 +3678,7 @@
                     mpClientInterface->setParameters(output, String8(param));
                     free(param);
                 }
-                updateAudioProfiles(output, profile->getAudioProfiles());
+                updateAudioProfiles(device, output, profile->getAudioProfiles());
                 if (!profile->hasValidAudioProfile()) {
                     ALOGW("checkOutputsForDevice() missing param");
                     mpClientInterface->closeOutput(output);
@@ -3916,7 +3916,7 @@
                     mpClientInterface->setParameters(input, String8(param));
                     free(param);
                 }
-                updateAudioProfiles(input, profile->getAudioProfiles());
+                updateAudioProfiles(device, input, profile->getAudioProfiles());
                 if (!profile->hasValidAudioProfile()) {
                     ALOGW("checkInputsForDevice() direct input missing param");
                     mpClientInterface->closeInput(input);
@@ -4936,7 +4936,7 @@
             voiceVolume = 1.0;
         }
 
-        if (voiceVolume != mLastVoiceVolume && outputDesc == mPrimaryOutput) {
+        if (voiceVolume != mLastVoiceVolume) {
             mpClientInterface->setVoiceVolume(voiceVolume, delayMs);
             mLastVoiceVolume = voiceVolume;
         }
@@ -5306,7 +5306,8 @@
             __FUNCTION__, supportsAC3, supportsOtherSurround, supportsIEC61937);
 }
 
-void AudioPolicyManager::updateAudioProfiles(audio_io_handle_t ioHandle,
+void AudioPolicyManager::updateAudioProfiles(audio_devices_t device,
+                                             audio_io_handle_t ioHandle,
                                              AudioProfileVector &profiles)
 {
     String8 reply;
@@ -5323,7 +5324,9 @@
             return;
         }
         FormatVector formats = formatsFromString(reply.string());
-        filterSurroundFormats(formats);
+        if (device == AUDIO_DEVICE_OUT_HDMI) {
+            filterSurroundFormats(formats);
+        }
         profiles.setFormats(formats);
     }
     const FormatVector &supportedFormats = profiles.getSupportedFormats();
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.h b/services/audiopolicy/managerdefault/AudioPolicyManager.h
index 1ef896f..1302cb5 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.h
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.h
@@ -589,7 +589,8 @@
         void filterSurroundFormats(FormatVector &formats);
 
         // If any, resolve any "dynamic" fields of an Audio Profiles collection
-        void updateAudioProfiles(audio_io_handle_t ioHandle, AudioProfileVector &profiles);
+        void updateAudioProfiles(audio_devices_t device, audio_io_handle_t ioHandle,
+                AudioProfileVector &profiles);
 
         // updates device caching and output for streams that can influence the
         //    routing of notifications
diff --git a/services/mediaextractor/minijail/seccomp_policy/mediaextractor-seccomp-arm.policy b/services/mediaextractor/minijail/seccomp_policy/mediaextractor-seccomp-arm.policy
index cc9a580..165694c 100644
--- a/services/mediaextractor/minijail/seccomp_policy/mediaextractor-seccomp-arm.policy
+++ b/services/mediaextractor/minijail/seccomp_policy/mediaextractor-seccomp-arm.policy
@@ -33,6 +33,10 @@
 rt_sigprocmask: 1
 sched_yield: 1
 ugetrlimit: 1
+geteuid32: 1
+getgid32: 1
+getegid32: 1
+getgroups32: 1
 
 # for attaching to debuggerd on process crash
 sigaction: 1
diff --git a/services/mediaextractor/minijail/seccomp_policy/mediaextractor-seccomp-x86.policy b/services/mediaextractor/minijail/seccomp_policy/mediaextractor-seccomp-x86.policy
index 516ca60..67976ff 100644
--- a/services/mediaextractor/minijail/seccomp_policy/mediaextractor-seccomp-x86.policy
+++ b/services/mediaextractor/minijail/seccomp_policy/mediaextractor-seccomp-x86.policy
@@ -31,6 +31,10 @@
 sched_setscheduler: 1
 ugetrlimit: 1
 getrlimit: 1
+geteuid32: 1
+getgid32: 1
+getegid32: 1
+getgroups32: 1
 
 # for attaching to debuggerd on process crash
 socketcall: 1
diff --git a/services/soundtrigger/SoundTriggerHwService.cpp b/services/soundtrigger/SoundTriggerHwService.cpp
index 66310b5..8f37bed 100644
--- a/services/soundtrigger/SoundTriggerHwService.cpp
+++ b/services/soundtrigger/SoundTriggerHwService.cpp
@@ -70,7 +70,8 @@
               SOUND_TRIGGER_HARDWARE_MODULE_ID, HW_MODULE_PREFIX, strerror(-rc));
         return;
     }
-    if (dev->common.version != SOUND_TRIGGER_DEVICE_API_VERSION_CURRENT) {
+    if (dev->common.version < SOUND_TRIGGER_DEVICE_API_VERSION_1_0 ||
+        dev->common.version > SOUND_TRIGGER_DEVICE_API_VERSION_CURRENT) {
         ALOGE("wrong sound trigger hw device version %04x", dev->common.version);
         return;
     }
@@ -808,10 +809,20 @@
             goto exit;
         }
 
+        const bool supports_stop_all =
+            (mHwDevice->common.version >= SOUND_TRIGGER_DEVICE_API_VERSION_1_1 &&
+             mHwDevice->stop_all_recognitions);
+
+        if (supports_stop_all) {
+            mHwDevice->stop_all_recognitions(mHwDevice);
+        }
+
         for (size_t i = 0; i < mModels.size(); i++) {
             sp<Model> model = mModels.valueAt(i);
             if (model->mState == Model::STATE_ACTIVE) {
-                mHwDevice->stop_recognition(mHwDevice, model->mHandle);
+                if (!supports_stop_all) {
+                    mHwDevice->stop_recognition(mHwDevice, model->mHandle);
+                }
                 // keep model in ACTIVE state so that event is processed by onCallbackEvent()
                 if (model->mType == SOUND_MODEL_TYPE_KEYPHRASE) {
                     struct sound_trigger_phrase_recognition_event event;
diff --git a/soundtrigger/Android.mk b/soundtrigger/Android.mk
index d91c4c2..c794cc1 100644
--- a/soundtrigger/Android.mk
+++ b/soundtrigger/Android.mk
@@ -35,4 +35,6 @@
 
 LOCAL_MODULE:= libsoundtrigger
 
+LOCAL_CFLAGS := -Werror -Wall
+
 include $(BUILD_SHARED_LIBRARY)
diff --git a/tools/resampler_tools/Android.mk b/tools/resampler_tools/Android.mk
index b58e4cd..bba5199 100644
--- a/tools/resampler_tools/Android.mk
+++ b/tools/resampler_tools/Android.mk
@@ -12,6 +12,6 @@
 
 LOCAL_MODULE := fir
 
+LOCAL_CFLAGS := -Werror -Wall
+
 include $(BUILD_HOST_EXECUTABLE)
-
-