Merge "Switch media fw hotword permission check to PermissionChecker (av)" into sc-dev
diff --git a/media/codecs/m4v_h263/dec/test/Android.bp b/media/codecs/m4v_h263/dec/test/Android.bp
index 6eed66f..d8de569 100644
--- a/media/codecs/m4v_h263/dec/test/Android.bp
+++ b/media/codecs/m4v_h263/dec/test/Android.bp
@@ -47,6 +47,10 @@
},
},
+ // this unit test also runs within the mainline tests (MTS),
+ // so it must be compatible back to Android Q/10 (sdk 29)
+ min_sdk_version: "29",
+
srcs: [
"Mpeg4H263DecoderTest.cpp",
],
diff --git a/media/libaaudio/src/core/AAudioStreamParameters.cpp b/media/libaaudio/src/core/AAudioStreamParameters.cpp
index 0d60120..acfac24 100644
--- a/media/libaaudio/src/core/AAudioStreamParameters.cpp
+++ b/media/libaaudio/src/core/AAudioStreamParameters.cpp
@@ -25,8 +25,7 @@
// TODO These defines should be moved to a central place in audio.
#define SAMPLES_PER_FRAME_MIN 1
-// TODO Remove 8 channel limitation.
-#define SAMPLES_PER_FRAME_MAX FCC_8
+#define SAMPLES_PER_FRAME_MAX FCC_LIMIT
#define SAMPLE_RATE_HZ_MIN 8000
// HDMI supports up to 32 channels at 1536000 Hz.
#define SAMPLE_RATE_HZ_MAX 1600000
diff --git a/media/libaaudio/src/core/AudioStreamBuilder.cpp b/media/libaaudio/src/core/AudioStreamBuilder.cpp
index 2135c54..e015592 100644
--- a/media/libaaudio/src/core/AudioStreamBuilder.cpp
+++ b/media/libaaudio/src/core/AudioStreamBuilder.cpp
@@ -43,8 +43,7 @@
// on the edge of being ridiculous.
// TODO These defines should be moved to a central place in audio.
#define SAMPLES_PER_FRAME_MIN 1
-// TODO Remove 8 channel limitation.
-#define SAMPLES_PER_FRAME_MAX FCC_8
+#define SAMPLES_PER_FRAME_MAX FCC_LIMIT
#define SAMPLE_RATE_HZ_MIN 8000
// HDMI supports up to 32 channels at 1536000 Hz.
#define SAMPLE_RATE_HZ_MAX 1600000
diff --git a/media/libaudioprocessing/AudioMixerOps.h b/media/libaudioprocessing/AudioMixerOps.h
index 8d374c9..a56d9cb 100644
--- a/media/libaudioprocessing/AudioMixerOps.h
+++ b/media/libaudioprocessing/AudioMixerOps.h
@@ -17,6 +17,8 @@
#ifndef ANDROID_AUDIO_MIXER_OPS_H
#define ANDROID_AUDIO_MIXER_OPS_H
+#include <system/audio.h>
+
namespace android {
// Hack to make static_assert work in a constexpr
@@ -231,7 +233,7 @@
typename TO, typename TI, typename TV,
typename F>
void stereoVolumeHelper(TO*& out, const TI*& in, const TV *vol, F f) {
- static_assert(NCHAN > 0 && NCHAN <= 8);
+ static_assert(NCHAN > 0 && NCHAN <= FCC_LIMIT);
static_assert(MIXTYPE == MIXTYPE_MULTI_STEREOVOL
|| MIXTYPE == MIXTYPE_MULTI_SAVEONLY_STEREOVOL
|| MIXTYPE == MIXTYPE_STEREOEXPAND
diff --git a/media/libaudioprocessing/AudioResampler.cpp b/media/libaudioprocessing/AudioResampler.cpp
index c761b38..51673d7 100644
--- a/media/libaudioprocessing/AudioResampler.cpp
+++ b/media/libaudioprocessing/AudioResampler.cpp
@@ -268,7 +268,7 @@
mPhaseFraction(0),
mQuality(quality) {
- const int maxChannels = quality < DYN_LOW_QUALITY ? 2 : 8;
+ const int maxChannels = quality < DYN_LOW_QUALITY ? FCC_2 : FCC_LIMIT;
if (inChannelCount < 1
|| inChannelCount > maxChannels) {
LOG_ALWAYS_FATAL("Unsupported sample format %d quality %d channels",
diff --git a/media/libaudioprocessing/AudioResamplerDyn.cpp b/media/libaudioprocessing/AudioResamplerDyn.cpp
index 1aacfd1..21d3d36 100644
--- a/media/libaudioprocessing/AudioResamplerDyn.cpp
+++ b/media/libaudioprocessing/AudioResamplerDyn.cpp
@@ -545,8 +545,8 @@
// Note: A stride of 2 is achieved with non-SIMD processing.
int stride = ((c.mHalfNumCoefs & 7) == 0) ? 16 : 2;
LOG_ALWAYS_FATAL_IF(stride < 16, "Resampler stride must be 16 or more");
- LOG_ALWAYS_FATAL_IF(mChannelCount < 1 || mChannelCount > 8,
- "Resampler channels(%d) must be between 1 to 8", mChannelCount);
+ LOG_ALWAYS_FATAL_IF(mChannelCount < 1 || mChannelCount > FCC_LIMIT,
+ "Resampler channels(%d) must be between 1 to %d", mChannelCount, FCC_LIMIT);
// stride 16 (falls back to stride 2 for machines that do not support NEON)
if (locked) {
switch (mChannelCount) {
diff --git a/media/libaudioprocessing/include/media/AudioMixerBase.h b/media/libaudioprocessing/include/media/AudioMixerBase.h
index cf84b83..3419816 100644
--- a/media/libaudioprocessing/include/media/AudioMixerBase.h
+++ b/media/libaudioprocessing/include/media/AudioMixerBase.h
@@ -45,8 +45,7 @@
{
public:
// Do not change these unless underlying code changes.
- // This mixer has a hard-coded upper limit of 8 channels for output.
- static constexpr uint32_t MAX_NUM_CHANNELS = FCC_8;
+ static constexpr uint32_t MAX_NUM_CHANNELS = FCC_LIMIT;
static constexpr uint32_t MAX_NUM_VOLUMES = FCC_2; // stereo volume only
static const uint16_t UNITY_GAIN_INT = 0x1000;
diff --git a/media/libeffects/visualizer/EffectVisualizer.cpp b/media/libeffects/visualizer/EffectVisualizer.cpp
index f838892..1551e33 100644
--- a/media/libeffects/visualizer/EffectVisualizer.cpp
+++ b/media/libeffects/visualizer/EffectVisualizer.cpp
@@ -157,7 +157,7 @@
if (pConfig->inputCfg.format != pConfig->outputCfg.format) return -EINVAL;
const uint32_t channelCount = audio_channel_count_from_out_mask(pConfig->inputCfg.channels);
#ifdef SUPPORT_MC
- if (channelCount < 1 || channelCount > FCC_8) return -EINVAL;
+ if (channelCount < 1 || channelCount > FCC_LIMIT) return -EINVAL;
#else
if (channelCount != FCC_2) return -EINVAL;
#endif
diff --git a/media/libmediametrics/MediaMetricsItem.cpp b/media/libmediametrics/MediaMetricsItem.cpp
index a8350ea..d597a4d 100644
--- a/media/libmediametrics/MediaMetricsItem.cpp
+++ b/media/libmediametrics/MediaMetricsItem.cpp
@@ -308,6 +308,17 @@
switch (uid) {
case AID_RADIO: // telephony subsystem, RIL
return false;
+ default:
+ // Some isolated processes can access the audio system; see
+ // AudioSystem::setAudioFlingerBinder (currently only the HotwordDetectionService). Instead
+ // of also allowing access to the MediaMetrics service, it's simpler to just disable it for
+ // now.
+ // TODO(b/190151205): Either allow the HotwordDetectionService to access MediaMetrics or
+ // make this disabling specific to that process.
+ if (uid >= AID_ISOLATED_START && uid <= AID_ISOLATED_END) {
+ return false;
+ }
+ break;
}
int enabled = property_get_int32(Item::EnabledProperty, -1);
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index a89088a..54a6425 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -2896,8 +2896,8 @@
audio_is_linear_pcm(config->format) &&
audio_is_linear_pcm(halconfig.format) &&
(halconfig.sample_rate <= AUDIO_RESAMPLER_DOWN_RATIO_MAX * config->sample_rate) &&
- (audio_channel_count_from_in_mask(halconfig.channel_mask) <= FCC_8) &&
- (audio_channel_count_from_in_mask(config->channel_mask) <= FCC_8)) {
+ (audio_channel_count_from_in_mask(halconfig.channel_mask) <= FCC_LIMIT) &&
+ (audio_channel_count_from_in_mask(config->channel_mask) <= FCC_LIMIT)) {
// FIXME describe the change proposed by HAL (save old values so we can log them here)
ALOGV("openInput_l() reopening with proposed sampling rate and channel mask");
inStream.clear();
@@ -3996,7 +3996,7 @@
// if the move request is not received from audio policy manager, the effect must be
// re-registered with the new strategy and output
if (dstChain == 0) {
- dstChain = effect->callback()->chain().promote();
+ dstChain = effect->getCallback()->chain().promote();
if (dstChain == 0) {
ALOGW("moveEffectChain_l() cannot get chain from effect %p", effect.get());
status = NO_INIT;
@@ -4046,7 +4046,7 @@
goto Exit;
}
- dstChain = effect->callback()->chain().promote();
+ dstChain = effect->getCallback()->chain().promote();
if (dstChain == 0) {
thread->addEffect_l(effect);
status = INVALID_OPERATION;
diff --git a/services/audioflinger/Effects.cpp b/services/audioflinger/Effects.cpp
index d75b13b..d3492d9 100644
--- a/services/audioflinger/Effects.cpp
+++ b/services/audioflinger/Effects.cpp
@@ -152,12 +152,12 @@
if (fromHandle) {
if (enabled) {
if (status != NO_ERROR) {
- mCallback->checkSuspendOnEffectEnabled(this, false, false /*threadLocked*/);
+ getCallback()->checkSuspendOnEffectEnabled(this, false, false /*threadLocked*/);
} else {
- mCallback->onEffectEnable(this);
+ getCallback()->onEffectEnable(this);
}
} else {
- mCallback->onEffectDisable(this);
+ getCallback()->onEffectDisable(this);
}
}
return status;
@@ -247,8 +247,9 @@
doRegister = true;
mPolicyRegistered = mHandles.size() > 0;
if (mPolicyRegistered) {
- io = mCallback->io();
- strategy = mCallback->strategy();
+ const auto callback = getCallback();
+ io = callback->io();
+ strategy = callback->strategy();
}
}
// enable effect when registered according to enable state requested by controlling handle
@@ -349,8 +350,9 @@
// unsafe method called when the effect parent thread has been destroyed
ssize_t AudioFlinger::EffectBase::disconnectHandle(EffectHandle *handle, bool unpinIfLast)
{
+ const auto callback = getCallback();
ALOGV("disconnect() %p handle %p", this, handle);
- if (mCallback->disconnectEffectHandle(handle, unpinIfLast)) {
+ if (callback->disconnectEffectHandle(handle, unpinIfLast)) {
return mHandles.size();
}
@@ -358,7 +360,7 @@
ssize_t numHandles = removeHandle_l(handle);
if ((numHandles == 0) && (!mPinned || unpinIfLast)) {
mLock.unlock();
- mCallback->updateOrphanEffectChains(this);
+ callback->updateOrphanEffectChains(this);
mLock.lock();
}
return numHandles;
@@ -377,7 +379,7 @@
}
void AudioFlinger::EffectBase::checkSuspendOnEffectEnabled(bool enabled, bool threadLocked) {
- mCallback->checkSuspendOnEffectEnabled(this, enabled, threadLocked);
+ getCallback()->checkSuspendOnEffectEnabled(this, enabled, threadLocked);
}
static String8 effectFlagsToString(uint32_t flags) {
@@ -835,7 +837,7 @@
mConfig.inputCfg.buffer.raw != mConfig.outputCfg.buffer.raw) {
// If an insert effect is idle and input buffer is different from output buffer,
// accumulate input onto output
- if (mCallback->activeTrackCnt() != 0) {
+ if (getCallback()->activeTrackCnt() != 0) {
// similar handling with data_bypass above.
if (mConfig.outputCfg.accessMode == EFFECT_BUFFER_ACCESS_ACCUMULATE) {
accumulateInputToOutput();
@@ -860,6 +862,7 @@
status_t status;
uint32_t size;
audio_channel_mask_t channelMask;
+ sp<EffectCallbackInterface> callback;
if (mEffectInterface == 0) {
status = NO_INIT;
@@ -870,7 +873,8 @@
// TODO: handle configuration of input (record) SW effects above the HAL,
// similar to output EFFECT_FLAG_TYPE_INSERT/REPLACE,
// in which case input channel masks should be used here.
- channelMask = mCallback->channelMask();
+ callback = getCallback();
+ channelMask = callback->channelMask();
mConfig.inputCfg.channels = channelMask;
mConfig.outputCfg.channels = channelMask;
@@ -899,7 +903,7 @@
#endif
}
if (isHapticGenerator()) {
- audio_channel_mask_t hapticChannelMask = mCallback->hapticChannelMask();
+ audio_channel_mask_t hapticChannelMask = callback->hapticChannelMask();
mConfig.inputCfg.channels |= hapticChannelMask;
mConfig.outputCfg.channels |= hapticChannelMask;
}
@@ -912,11 +916,11 @@
mConfig.outputCfg.format = EFFECT_BUFFER_FORMAT;
// Don't use sample rate for thread if effect isn't offloadable.
- if (mCallback->isOffloadOrDirect() && !isOffloaded()) {
+ if (callback->isOffloadOrDirect() && !isOffloaded()) {
mConfig.inputCfg.samplingRate = DEFAULT_OUTPUT_SAMPLE_RATE;
ALOGV("Overriding effect input as 48kHz");
} else {
- mConfig.inputCfg.samplingRate = mCallback->sampleRate();
+ mConfig.inputCfg.samplingRate = callback->sampleRate();
}
mConfig.outputCfg.samplingRate = mConfig.inputCfg.samplingRate;
mConfig.inputCfg.bufferProvider.cookie = NULL;
@@ -942,11 +946,11 @@
}
mConfig.inputCfg.mask = EFFECT_CONFIG_ALL;
mConfig.outputCfg.mask = EFFECT_CONFIG_ALL;
- mConfig.inputCfg.buffer.frameCount = mCallback->frameCount();
+ mConfig.inputCfg.buffer.frameCount = callback->frameCount();
mConfig.outputCfg.buffer.frameCount = mConfig.inputCfg.buffer.frameCount;
ALOGV("configure() %p chain %p buffer %p framecount %zu",
- this, mCallback->chain().promote().get(),
+ this, callback->chain().promote().get(),
mConfig.inputCfg.buffer.raw, mConfig.inputCfg.buffer.frameCount);
status_t cmdStatus;
@@ -962,7 +966,7 @@
#ifdef MULTICHANNEL_EFFECT_CHAIN
if (status != NO_ERROR &&
- mCallback->isOutput() &&
+ callback->isOutput() &&
(mConfig.inputCfg.channels != AUDIO_CHANNEL_OUT_STEREO
|| mConfig.outputCfg.channels != AUDIO_CHANNEL_OUT_STEREO)) {
// Older effects may require exact STEREO position mask.
@@ -1029,7 +1033,7 @@
size = sizeof(int);
*(int32_t *)p->data = VISUALIZER_PARAM_LATENCY;
- uint32_t latency = mCallback->latency();
+ uint32_t latency = callback->latency();
*((int32_t *)p->data + 1)= latency;
mEffectInterface->command(EFFECT_CMD_SET_PARAM,
@@ -1076,7 +1080,7 @@
{
if ((mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_PRE_PROC ||
(mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_POST_PROC) {
- (void)mCallback->addEffectToHal(mEffectInterface);
+ (void)getCallback()->addEffectToHal(mEffectInterface);
}
}
@@ -1089,7 +1093,7 @@
status = start_l();
}
if (status == NO_ERROR) {
- mCallback->resetVolume();
+ getCallback()->resetVolume();
}
return status;
}
@@ -1139,7 +1143,7 @@
// We have the EffectChain and EffectModule lock, permit a reentrant call to setVolume:
// resetVolume_l --> setVolume_l --> EffectModule::setVolume
mSetVolumeReentrantTid = gettid();
- mCallback->resetVolume();
+ getCallback()->resetVolume();
mSetVolumeReentrantTid = INVALID_PID;
}
@@ -1172,7 +1176,7 @@
{
if ((mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_PRE_PROC ||
(mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_POST_PROC) {
- mCallback->removeEffectFromHal(mEffectInterface);
+ getCallback()->removeEffectFromHal(mEffectInterface);
}
return NO_ERROR;
}
@@ -1288,7 +1292,7 @@
bool AudioFlinger::EffectModule::isOffloadedOrDirect() const
{
- return mCallback->isOffloadOrDirect();
+ return getCallback()->isOffloadOrDirect();
}
bool AudioFlinger::EffectModule::isVolumeControlEnabled() const
@@ -1332,7 +1336,7 @@
|| size > mInConversionBuffer->getSize())) {
mInConversionBuffer.clear();
ALOGV("%s: allocating mInConversionBuffer %zu", __func__, size);
- (void)mCallback->allocateHalBuffer(size, &mInConversionBuffer);
+ (void)getCallback()->allocateHalBuffer(size, &mInConversionBuffer);
}
if (mInConversionBuffer != nullptr) {
mInConversionBuffer->setFrameCount(inFrameCount);
@@ -1376,7 +1380,7 @@
|| size > mOutConversionBuffer->getSize())) {
mOutConversionBuffer.clear();
ALOGV("%s: allocating mOutConversionBuffer %zu", __func__, size);
- (void)mCallback->allocateHalBuffer(size, &mOutConversionBuffer);
+ (void)getCallback()->allocateHalBuffer(size, &mOutConversionBuffer);
}
if (mOutConversionBuffer != nullptr) {
mOutConversionBuffer->setFrameCount(outFrameCount);
diff --git a/services/audioflinger/Effects.h b/services/audioflinger/Effects.h
index 9da95bc..661881e 100644
--- a/services/audioflinger/Effects.h
+++ b/services/audioflinger/Effects.h
@@ -138,8 +138,9 @@
int32_t __unused,
std::vector<uint8_t>* __unused) { return NO_ERROR; };
+ // mCallback is atomic so this can be lock-free.
void setCallback(const sp<EffectCallbackInterface>& callback) { mCallback = callback; }
- sp<EffectCallbackInterface>& callback() { return mCallback; }
+ sp<EffectCallbackInterface> getCallback() const { return mCallback.load(); }
status_t addHandle(EffectHandle *handle);
ssize_t disconnectHandle(EffectHandle *handle, bool unpinIfLast);
@@ -170,7 +171,7 @@
DISALLOW_COPY_AND_ASSIGN(EffectBase);
mutable Mutex mLock; // mutex for process, commands and handles list protection
- sp<EffectCallbackInterface> mCallback; // parent effect chain
+ mediautils::atomic_sp<EffectCallbackInterface> mCallback; // parent effect chain
const int mId; // this instance unique ID
const audio_session_t mSessionId; // audio session ID
const effect_descriptor_t mDescriptor;// effect descriptor received from effect engine
diff --git a/services/audioflinger/FastCapture.cpp b/services/audioflinger/FastCapture.cpp
index d6d6e25..2963202 100644
--- a/services/audioflinger/FastCapture.cpp
+++ b/services/audioflinger/FastCapture.cpp
@@ -107,7 +107,7 @@
mSampleRate = Format_sampleRate(mFormat);
#if !LOG_NDEBUG
unsigned channelCount = Format_channelCount(mFormat);
- ALOG_ASSERT(channelCount >= 1 && channelCount <= FCC_8);
+ ALOG_ASSERT(channelCount >= 1 && channelCount <= FCC_LIMIT);
#endif
}
dumpState->mSampleRate = mSampleRate;
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index 47b4b18..f62082e 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -1638,7 +1638,7 @@
detachAuxEffect_l(effect->id());
}
- sp<EffectChain> chain = effect->callback()->chain().promote();
+ sp<EffectChain> chain = effect->getCallback()->chain().promote();
if (chain != 0) {
// remove effect chain if removing last effect
if (chain->removeEffect_l(effect, release) == 0) {
@@ -8573,7 +8573,7 @@
if (param.getInt(String8(AudioParameter::keyChannels), value) == NO_ERROR) {
audio_channel_mask_t mask = (audio_channel_mask_t) value;
if (!audio_is_input_channel(mask) ||
- audio_channel_count_from_in_mask(mask) > FCC_8) {
+ audio_channel_count_from_in_mask(mask) > FCC_LIMIT) {
status = BAD_VALUE;
} else {
channelMask = mask;
@@ -8610,7 +8610,7 @@
if (mInput->stream->getAudioProperties(&config) == OK &&
audio_is_linear_pcm(config.format) && audio_is_linear_pcm(reqFormat) &&
config.sample_rate <= (AUDIO_RESAMPLER_DOWN_RATIO_MAX * samplingRate) &&
- audio_channel_count_from_in_mask(config.channel_mask) <= FCC_8) {
+ audio_channel_count_from_in_mask(config.channel_mask) <= FCC_LIMIT) {
status = NO_ERROR;
}
}
@@ -8672,10 +8672,10 @@
mFormat = mHALFormat;
mChannelCount = audio_channel_count_from_in_mask(mChannelMask);
if (audio_is_linear_pcm(mFormat)) {
- LOG_ALWAYS_FATAL_IF(mChannelCount > FCC_8, "HAL channel count %d > %d",
- mChannelCount, FCC_8);
+ LOG_ALWAYS_FATAL_IF(mChannelCount > FCC_LIMIT, "HAL channel count %d > %d",
+ mChannelCount, FCC_LIMIT);
} else {
- // Can have more that FCC_8 channels in encoded streams.
+ // Can have more that FCC_LIMIT channels in encoded streams.
ALOGI("HAL format %#x is not linear pcm", mFormat);
}
result = mInput->stream->getFrameSize(&mFrameSize);
diff --git a/services/audiopolicy/common/include/policy.h b/services/audiopolicy/common/include/policy.h
index 552919d..577f641 100644
--- a/services/audiopolicy/common/include/policy.h
+++ b/services/audiopolicy/common/include/policy.h
@@ -42,7 +42,7 @@
// For mixed output and inputs, the policy will use max mixer channel count.
// Do not limit channel count otherwise
-#define MAX_MIXER_CHANNEL_COUNT FCC_8
+#define MAX_MIXER_CHANNEL_COUNT FCC_LIMIT
/**
* Alias to AUDIO_DEVICE_OUT_DEFAULT defined for clarification when this value is used by volume
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index 83d2bc9..9c7b506 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -131,6 +131,8 @@
"android.permission.CAMERA_OPEN_CLOSE_LISTENER");
static const String16
sCameraInjectExternalCameraPermission("android.permission.CAMERA_INJECT_EXTERNAL_CAMERA");
+static int sMemFd = -1;
+const char *sFileName = "lastOpenSessionDumpFile";
static constexpr int32_t kVendorClientScore = resource_policy::PERCEPTIBLE_APP_ADJ;
static constexpr int32_t kVendorClientState = ActivityManager::PROCESS_STATE_PERSISTENT_UI;
@@ -148,6 +150,11 @@
mAudioRestriction(hardware::camera2::ICameraDeviceUser::AUDIO_RESTRICTION_NONE) {
ALOGI("CameraService started (pid=%d)", getpid());
mServiceLockWrapper = std::make_shared<WaitableMutexWrapper>(&mServiceLock);
+
+ sMemFd = memfd_create(sFileName, MFD_ALLOW_SEALING);
+ if (sMemFd == -1) {
+ ALOGE("%s:Error while creating the file:%s", __FUNCTION__, sFileName);
+ }
}
void CameraService::onFirstRef()
@@ -1637,6 +1644,21 @@
}
*device = client;
+
+ Mutex::Autolock lock(mServiceLock);
+
+ // Clear the previous cached logs and reposition the
+ // file offset to beginning of the file to log new data.
+ // If either truncate or lseek fails, close the previous file and create a new one.
+ if ((ftruncate(sMemFd, 0) == -1) || (lseek(sMemFd, 0, SEEK_SET) == -1)) {
+ ALOGE("%s: Error while truncating the file:%s", __FUNCTION__, sFileName);
+ // Close the previous memfd.
+ close(sMemFd);
+ // If failure to wipe the data, then create a new file and
+ // assign the new value to sMemFd.
+ sMemFd = memfd_create(sFileName, MFD_ALLOW_SEALING);
+ }
+
return ret;
}
@@ -3832,6 +3854,27 @@
return locked;
}
+void CameraService::cacheDump() {
+ const Vector<String16>& args = Vector<String16>();
+ ATRACE_CALL();
+
+ Mutex::Autolock lock(mServiceLock);
+
+ Mutex::Autolock l(mCameraStatesLock);
+
+ // Start collecting the info for open sessions and store it in temp file.
+ for (const auto& state : mCameraStates) {
+ String8 cameraId = state.first;
+
+ auto clientDescriptor = mActiveClientManager.get(cameraId);
+ if (clientDescriptor != nullptr) {
+ dprintf(sMemFd, "== Camera device %s dynamic info: ==\n", cameraId.string());
+ // Log the current open session info before device is disconnected.
+ dumpOpenSessionClientLogs(sMemFd, args, cameraId);
+ }
+ }
+}
+
status_t CameraService::dump(int fd, const Vector<String16>& args) {
ATRACE_CALL();
@@ -3898,21 +3941,10 @@
auto clientDescriptor = mActiveClientManager.get(cameraId);
if (clientDescriptor != nullptr) {
- dprintf(fd, " Device %s is open. Client instance dump:\n",
- cameraId.string());
- dprintf(fd, " Client priority score: %d state: %d\n",
- clientDescriptor->getPriority().getScore(),
- clientDescriptor->getPriority().getState());
- dprintf(fd, " Client PID: %d\n", clientDescriptor->getOwnerId());
-
- auto client = clientDescriptor->getValue();
- dprintf(fd, " Client package: %s\n",
- String8(client->getPackageName()).string());
-
- client->dumpClient(fd, args);
+ // log the current open session info
+ dumpOpenSessionClientLogs(fd, args, cameraId);
} else {
- dprintf(fd, " Device %s is closed, no client instance\n",
- cameraId.string());
+ dumpClosedSessionClientLogs(fd, cameraId);
}
}
@@ -3969,9 +4001,53 @@
}
}
}
+
+ Mutex::Autolock lock(mServiceLock);
+
+ // Dump info from previous open sessions.
+ // Reposition the offset to beginning of the file before reading
+
+ if ((sMemFd >= 0) && (lseek(sMemFd, 0, SEEK_SET) != -1)) {
+ dprintf(fd, "\n**********Dumpsys from previous open session**********\n");
+ ssize_t size_read;
+ char buf[4096];
+ while ((size_read = read(sMemFd, buf, (sizeof(buf) - 1))) > 0) {
+ // Read data from file to a small buffer and write it to fd.
+ write(fd, buf, size_read);
+ if (size_read == -1){
+ ALOGE("%s: Error during reading the file:%s", __FUNCTION__, sFileName);
+ break;
+ }
+ }
+ dprintf(fd, "\n**********End of Dumpsys from previous open session**********\n");
+ } else {
+ ALOGE("%s: Error during reading the file:%s", __FUNCTION__, sFileName);
+ }
return NO_ERROR;
}
+void CameraService::dumpOpenSessionClientLogs(int fd,
+ const Vector<String16>& args, const String8& cameraId) {
+ auto clientDescriptor = mActiveClientManager.get(cameraId);
+ dprintf(fd, " Device %s is open. Client instance dump:\n",
+ cameraId.string());
+ dprintf(fd, " Client priority score: %d state: %d\n",
+ clientDescriptor->getPriority().getScore(),
+ clientDescriptor->getPriority().getState());
+ dprintf(fd, " Client PID: %d\n", clientDescriptor->getOwnerId());
+
+ auto client = clientDescriptor->getValue();
+ dprintf(fd, " Client package: %s\n",
+ String8(client->getPackageName()).string());
+
+ client->dumpClient(fd, args);
+}
+
+void CameraService::dumpClosedSessionClientLogs(int fd, const String8& cameraId) {
+ dprintf(fd, " Device %s is closed, no client instance\n",
+ cameraId.string());
+}
+
void CameraService::dumpEventLog(int fd) {
dprintf(fd, "\n== Camera service events log (most recent at top): ==\n");
diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h
index d1ed59a..7b0037e 100644
--- a/services/camera/libcameraservice/CameraService.h
+++ b/services/camera/libcameraservice/CameraService.h
@@ -202,6 +202,8 @@
std::vector<hardware::CameraStatus>* cameraStatuses, bool isVendor = false,
bool isProcessLocalTest = false);
+ void cacheDump();
+
// Monitored UIDs availability notification
void notifyMonitoredUids();
@@ -785,6 +787,12 @@
// Return NO_ERROR if the device with a give ID can be connected to
status_t checkIfDeviceIsUsable(const String8& cameraId) const;
+ // Adds client logs during open session to the file pointed by fd.
+ void dumpOpenSessionClientLogs(int fd, const Vector<String16>& args, const String8& cameraId);
+
+ // Adds client logs during closed session to the file pointed by fd.
+ void dumpClosedSessionClientLogs(int fd, const String8& cameraId);
+
// Container for managing currently active application-layer clients
CameraClientManager mActiveClientManager;
diff --git a/services/camera/libcameraservice/common/Camera2ClientBase.cpp b/services/camera/libcameraservice/common/Camera2ClientBase.cpp
index ce479a1..56e5ae1 100644
--- a/services/camera/libcameraservice/common/Camera2ClientBase.cpp
+++ b/services/camera/libcameraservice/common/Camera2ClientBase.cpp
@@ -195,6 +195,8 @@
ALOGV("Camera %s: Shutting down", TClientBase::mCameraIdStr.string());
+ // Before detaching the device, cache the info from current open session
+ Camera2ClientBase::getCameraService()->cacheDump();
detachDevice();
CameraService::BasicClient::disconnect();