Merge "Record MediaCodec video playback duration" into sc-dev
diff --git a/apex/Android.bp b/apex/Android.bp
index 6c45749..dc22628 100644
--- a/apex/Android.bp
+++ b/apex/Android.bp
@@ -24,10 +24,8 @@
apex_defaults {
name: "com.android.media-defaults",
updatable: true,
- java_libs: [
- "updatable-media",
- "service-media-s",
- ],
+ bootclasspath_fragments: ["com.android.media-bootclasspath-fragment"],
+ systemserverclasspath_fragments: ["com.android.media-systemserverclasspath-fragment"],
multilib: {
first: {
// Extractor process runs only with the primary ABI.
@@ -94,6 +92,20 @@
installable: false,
}
+// Encapsulate the contributions made by the com.android.media to the bootclasspath.
+bootclasspath_fragment {
+ name: "com.android.media-bootclasspath-fragment",
+ contents: ["updatable-media"],
+ apex_available: ["com.android.media"],
+}
+
+// Encapsulate the contributions made by the com.android.media to the systemserverclasspath.
+systemserverclasspath_fragment {
+ name: "com.android.media-systemserverclasspath-fragment",
+ contents: ["service-media-s"],
+ apex_available: ["com.android.media"],
+}
+
filegroup {
name: "com.android.media-androidManifest",
srcs: ["AndroidManifest-media.xml"],
diff --git a/apex/mediatranscoding.rc b/apex/mediatranscoding.rc
index ae9f8ba..24306a2 100644
--- a/apex/mediatranscoding.rc
+++ b/apex/mediatranscoding.rc
@@ -8,5 +8,4 @@
ioprio rt 4
# Restrict to little cores only with system-background cpuset.
writepid /dev/cpuset/system-background/tasks
- interface aidl media.transcoding
disabled
diff --git a/camera/aidl/android/hardware/ICameraService.aidl b/camera/aidl/android/hardware/ICameraService.aidl
index 873d738..6e82968 100644
--- a/camera/aidl/android/hardware/ICameraService.aidl
+++ b/camera/aidl/android/hardware/ICameraService.aidl
@@ -92,7 +92,7 @@
String cameraId,
String opPackageName,
@nullable String featureId,
- int clientUid);
+ int clientUid, int oomScoreOffset);
/**
* Add listener for changes to camera device and flashlight state.
diff --git a/camera/ndk/impl/ACameraManager.cpp b/camera/ndk/impl/ACameraManager.cpp
index 73cabbf..a03c69c 100644
--- a/camera/ndk/impl/ACameraManager.cpp
+++ b/camera/ndk/impl/ACameraManager.cpp
@@ -739,7 +739,7 @@
// Send a zero length package name and let camera service figure it out from UID
binder::Status serviceRet = cs->connectDevice(
callbacks, String16(cameraId), String16(""), {},
- hardware::ICameraService::USE_CALLING_UID, /*out*/&deviceRemote);
+ hardware::ICameraService::USE_CALLING_UID, /*oomScoreOffset*/0, /*out*/&deviceRemote);
if (!serviceRet.isOk()) {
ALOGE("%s: connect camera device failed: %s", __FUNCTION__, serviceRet.toString8().string());
diff --git a/camera/tests/CameraBinderTests.cpp b/camera/tests/CameraBinderTests.cpp
index 0cf390f..a0773a2 100644
--- a/camera/tests/CameraBinderTests.cpp
+++ b/camera/tests/CameraBinderTests.cpp
@@ -378,7 +378,7 @@
sp<TestCameraDeviceCallbacks> callbacks(new TestCameraDeviceCallbacks());
sp<hardware::camera2::ICameraDeviceUser> device;
res = service->connectDevice(callbacks, cameraId, String16("meeeeeeeee!"),
- {}, hardware::ICameraService::USE_CALLING_UID,
+ {}, hardware::ICameraService::USE_CALLING_UID, /*oomScoreOffset*/ 0,
/*out*/&device);
EXPECT_TRUE(res.isOk()) << res;
ASSERT_NE(nullptr, device.get());
@@ -421,7 +421,7 @@
{
SCOPED_TRACE("openNewDevice");
binder::Status res = service->connectDevice(callbacks, deviceId, String16("meeeeeeeee!"),
- {}, hardware::ICameraService::USE_CALLING_UID,
+ {}, hardware::ICameraService::USE_CALLING_UID, /*oomScoreOffset*/ 0,
/*out*/&device);
EXPECT_TRUE(res.isOk()) << res;
}
diff --git a/drm/mediadrm/plugins/clearkey/hidl/CryptoPlugin.cpp b/drm/mediadrm/plugins/clearkey/hidl/CryptoPlugin.cpp
index b92f236..3a675f6 100644
--- a/drm/mediadrm/plugins/clearkey/hidl/CryptoPlugin.cpp
+++ b/drm/mediadrm/plugins/clearkey/hidl/CryptoPlugin.cpp
@@ -235,6 +235,21 @@
return Status::OK;
}
+Return<void> CryptoPlugin::getLogMessages(
+ getLogMessages_cb _hidl_cb) {
+ using std::chrono::duration_cast;
+ using std::chrono::milliseconds;
+ using std::chrono::system_clock;
+
+ auto timeMillis = duration_cast<milliseconds>(
+ system_clock::now().time_since_epoch()).count();
+
+ std::vector<LogMessage> logs = {
+ { timeMillis, LogPriority::ERROR, std::string("Not implemented") }};
+ _hidl_cb(drm::V1_4::Status::OK, toHidlVec(logs));
+ return Void();
+}
+
} // namespace clearkey
} // namespace V1_4.
} // namespace drm
diff --git a/drm/mediadrm/plugins/clearkey/hidl/DrmPlugin.cpp b/drm/mediadrm/plugins/clearkey/hidl/DrmPlugin.cpp
index 4318af4..6a374f9 100644
--- a/drm/mediadrm/plugins/clearkey/hidl/DrmPlugin.cpp
+++ b/drm/mediadrm/plugins/clearkey/hidl/DrmPlugin.cpp
@@ -645,22 +645,17 @@
auto timeMillis = duration_cast<milliseconds>(
system_clock::now().time_since_epoch()).count();
- //TODO(b/182525516) Stub out for now
std::vector<LogMessage> logs = {
- { timeMillis, LogPriority::DEFAULT, std::string() }};
+ { timeMillis, LogPriority::ERROR, std::string("Not implemented") }};
_hidl_cb(drm::V1_4::Status::OK, toHidlVec(logs));
return Void();
}
Return<bool> DrmPlugin::requiresSecureDecoder(
const hidl_string& mime, SecurityLevel level) {
- if (!strncasecmp(mime.c_str(), "video/", 6)) {
- // Type is video, so check level to see if we require a secure decoder.
- return level == SecurityLevel::HW_SECURE_DECODE;
- } else {
- // Type is not video, so never require a secure decoder.
- return false;
- }
+ UNUSED(mime);
+ UNUSED(level);
+ return false;
}
Return<bool> DrmPlugin::requiresSecureDecoderDefault(const hidl_string& mime) {
@@ -679,22 +674,7 @@
}
std::vector<uint8_t> sid = toVector(sessionId);
- sp<Session> session = mSessionLibrary->findSession(sid);
- if (!session.get()) {
- return Status::ERROR_DRM_SESSION_NOT_OPENED;
- }
-
- std::map<std::vector<uint8_t>, std::string>::iterator itr =
- mPlaybackId.find(sid);
- if (itr != mPlaybackId.end()) {
- mPlaybackId[sid] = playbackId;
- } else {
- if (!mPlaybackId.insert(
- std::pair<std::vector<uint8_t>, std::string>(sid, playbackId)).second) {
- ALOGE("Failed to set playback Id");
- return Status::ERROR_DRM_UNKNOWN;
- }
- }
+ mPlaybackId[sid] = playbackId;
return Status::OK;
}
@@ -766,21 +746,24 @@
};
// Set the setPlaybackId metric.
- DrmMetricGroup::Attribute setPlaybackIdOKAttribute = {
- "status", DrmMetricGroup::ValueType::INT64_TYPE,
- (int64_t) Status::OK, 0.0, ""
- };
- std::string playbackId = mPlaybackId.begin()->second;
- DrmMetricGroup::Value setPlaybackIdMetricValue = {
- "value", DrmMetricGroup::ValueType::STRING_TYPE, 0, 0, playbackId.c_str()
- };
+ std::vector<DrmMetricGroup::Attribute> sids;
+ std::vector<DrmMetricGroup::Value> playbackIds;
+ for (const auto&[key, value] : mPlaybackId) {
+ std::string sid(key.begin(), key.end());
+ DrmMetricGroup::Attribute sessionIdAttribute = {
+ "sid", DrmMetricGroup::ValueType::STRING_TYPE, 0, 0, sid };
+ sids.push_back(sessionIdAttribute);
+
+ DrmMetricGroup::Value playbackIdMetricValue = {
+ "playbackId", DrmMetricGroup::ValueType::STRING_TYPE, 0, 0, value };
+ playbackIds.push_back(playbackIdMetricValue);
+ }
DrmMetricGroup::Metric setPlaybackIdMetric = {
- "set_playback_id", { setPlaybackIdOKAttribute }, { setPlaybackIdMetricValue }
- };
+ "set_playback_id", { sids }, { playbackIds }};
- DrmMetricGroup metrics = {{ openSessionMetric, closeSessionMetric,
- closeSessionNotOpenedMetric, setPlaybackIdMetric }};
-
+ DrmMetricGroup metrics = {
+ { openSessionMetric, closeSessionMetric,
+ closeSessionNotOpenedMetric, setPlaybackIdMetric }};
_hidl_cb(Status::OK, hidl_vec<DrmMetricGroup>({metrics}));
return Void();
}
diff --git a/drm/mediadrm/plugins/clearkey/hidl/include/CryptoPlugin.h b/drm/mediadrm/plugins/clearkey/hidl/include/CryptoPlugin.h
index a7b2427..b272a83 100644
--- a/drm/mediadrm/plugins/clearkey/hidl/include/CryptoPlugin.h
+++ b/drm/mediadrm/plugins/clearkey/hidl/include/CryptoPlugin.h
@@ -17,7 +17,7 @@
#ifndef CLEARKEY_CRYPTO_PLUGIN_H_
#define CLEARKEY_CRYPTO_PLUGIN_H_
-#include <android/hardware/drm/1.2/ICryptoPlugin.h>
+#include <android/hardware/drm/1.4/ICryptoPlugin.h>
#include <android/hidl/memory/1.0/IMemory.h>
#include <mutex>
@@ -56,7 +56,7 @@
typedef drm::V1_2::Status Status_V1_2;
-struct CryptoPlugin : public drm::V1_2::ICryptoPlugin {
+struct CryptoPlugin : public drm::V1_4::ICryptoPlugin {
explicit CryptoPlugin(const hidl_vec<uint8_t>& sessionId) {
mInitStatus = setMediaDrmSession(sessionId);
}
@@ -104,6 +104,8 @@
Return<Status> getInitStatus() const { return mInitStatus; }
+ Return<void> getLogMessages(
+ getLogMessages_cb _hidl_cb);
private:
CLEARKEY_DISALLOW_COPY_AND_ASSIGN(CryptoPlugin);
diff --git a/media/codec2/sfplugin/CCodec.cpp b/media/codec2/sfplugin/CCodec.cpp
index 051e9cf..ce15a30 100644
--- a/media/codec2/sfplugin/CCodec.cpp
+++ b/media/codec2/sfplugin/CCodec.cpp
@@ -2688,7 +2688,11 @@
*maxUsage = 0;
continue;
}
- *minUsage |= supported.values[0].u64;
+ if (supported.values.size() > 1) {
+ *minUsage |= supported.values[1].u64;
+ } else {
+ *minUsage |= supported.values[0].u64;
+ }
int64_t currentMaxUsage = 0;
for (const C2Value::Primitive &flags : supported.values) {
currentMaxUsage |= flags.u64;
diff --git a/media/libaaudio/include/aaudio/AAudio.h b/media/libaaudio/include/aaudio/AAudio.h
index 3333925..6ca5fc8 100644
--- a/media/libaaudio/include/aaudio/AAudio.h
+++ b/media/libaaudio/include/aaudio/AAudio.h
@@ -635,13 +635,14 @@
AAUDIO_API void AAudioStreamBuilder_setDeviceId(AAudioStreamBuilder* builder,
int32_t deviceId) __INTRODUCED_IN(26);
-// TODO b/182392769: reexamine if Identity can be used
/**
* Declare the name of the package creating the stream.
*
* This is usually {@code Context#getPackageName()}.
*
* The default, if you do not call this function, is a random package in the calling uid.
+ * The vast majority of apps have only one package per calling UID. If the package
+ * name does not match the calling UID, then requests will be rejected.
*
* Available since API level 31.
*
@@ -656,7 +657,7 @@
*
* This is usually {@code Context#getAttributionTag()}.
*
- * The default, if you do not call this function, is the default attribution tag.
+ * The default, if you do not call this function, is null.
*
* Available since API level 31.
*
diff --git a/media/libmediaplayerservice/MediaRecorderClient.cpp b/media/libmediaplayerservice/MediaRecorderClient.cpp
index e2c8f8f..daa923e 100644
--- a/media/libmediaplayerservice/MediaRecorderClient.cpp
+++ b/media/libmediaplayerservice/MediaRecorderClient.cpp
@@ -127,7 +127,7 @@
if ((as == AUDIO_SOURCE_FM_TUNER
&& !(captureAudioOutputAllowed(mIdentity) || captureTunerAudioInputAllowed(mIdentity)))
- || !recordingAllowed(mIdentity)) {
+ || !recordingAllowed(mIdentity, (audio_source_t)as)) {
return PERMISSION_DENIED;
}
Mutex::Autolock lock(mLock);
diff --git a/media/mediaserver/Android.bp b/media/mediaserver/Android.bp
index a9617ec..3e4e4932 100644
--- a/media/mediaserver/Android.bp
+++ b/media/mediaserver/Android.bp
@@ -35,6 +35,7 @@
"android.hardware.media.omx@1.0",
"libandroidicu",
"libfmq",
+ "libbase",
"libbinder",
"libhidlbase",
"liblog",
diff --git a/media/mediaserver/main_mediaserver.cpp b/media/mediaserver/main_mediaserver.cpp
index 58e2d2a..dc1b9b8 100644
--- a/media/mediaserver/main_mediaserver.cpp
+++ b/media/mediaserver/main_mediaserver.cpp
@@ -18,6 +18,7 @@
#define LOG_TAG "mediaserver"
//#define LOG_NDEBUG 0
+#include <android-base/properties.h>
#include <binder/IPCThreadState.h>
#include <binder/ProcessState.h>
#include <binder/IServiceManager.h>
@@ -42,6 +43,12 @@
ResourceManagerService::instantiate();
registerExtensions();
::android::hardware::configureRpcThreadpool(16, false);
+
+ if (!android::base::GetBoolProperty("ro.config.low_ram", false)) {
+ // Start the media.transcoding service if the device is not low ram
+ // device.
+ android::base::SetProperty("ctl.start", "media.transcoding");
+ }
ProcessState::self()->startThreadPool();
IPCThreadState::self()->joinThreadPool();
::android::hardware::joinRpcThreadpool();
diff --git a/media/utils/ServiceUtilities.cpp b/media/utils/ServiceUtilities.cpp
index e3931b1..214a174 100644
--- a/media/utils/ServiceUtilities.cpp
+++ b/media/utils/ServiceUtilities.cpp
@@ -67,7 +67,7 @@
return packages[0];
}
-static int32_t getOpForSource(audio_source_t source) {
+int32_t getOpForSource(audio_source_t source) {
switch (source) {
case AUDIO_SOURCE_HOTWORD:
return AppOpsManager::OP_RECORD_AUDIO_HOTWORD;
@@ -133,8 +133,8 @@
return true;
}
-bool recordingAllowed(const Identity& identity) {
- return checkRecordingInternal(identity, String16(), /*start*/ false, AUDIO_SOURCE_DEFAULT);
+bool recordingAllowed(const Identity& identity, audio_source_t source) {
+ return checkRecordingInternal(identity, String16(), /*start*/ false, source);
}
bool startRecording(const Identity& identity, const String16& msg, audio_source_t source) {
diff --git a/media/utils/include/mediautils/ServiceUtilities.h b/media/utils/include/mediautils/ServiceUtilities.h
index 6e75746..e7132b8 100644
--- a/media/utils/include/mediautils/ServiceUtilities.h
+++ b/media/utils/include/mediautils/ServiceUtilities.h
@@ -80,7 +80,8 @@
}
}
-bool recordingAllowed(const media::permission::Identity& identity);
+bool recordingAllowed(const media::permission::Identity& identity,
+ audio_source_t source = AUDIO_SOURCE_DEFAULT);
bool startRecording(const media::permission::Identity& identity,
const String16& msg, audio_source_t source);
void finishRecording(const media::permission::Identity& identity, audio_source_t source);
@@ -98,6 +99,7 @@
bool modifyPhoneStateAllowed(const media::permission::Identity& identity);
bool bypassInterruptionPolicyAllowed(const media::permission::Identity& identity);
void purgePermissionCache();
+int32_t getOpForSource(audio_source_t source);
media::permission::Identity getCallingIdentity();
diff --git a/services/audioflinger/PlaybackTracks.h b/services/audioflinger/PlaybackTracks.h
index 2436248..0af4c7b 100644
--- a/services/audioflinger/PlaybackTracks.h
+++ b/services/audioflinger/PlaybackTracks.h
@@ -148,14 +148,6 @@
void setFinalVolume(float volume);
float getFinalVolume() const { return mFinalVolume; }
- /** @return true if the track has changed (metadata or volume) since
- * the last time this function was called,
- * true if this function was never called since the track creation,
- * false otherwise.
- * Thread safe.
- */
- bool readAndClearHasChanged() { return !mChangeNotified.test_and_set(); }
-
using SourceMetadatas = std::vector<playback_track_metadata_v7_t>;
using MetadataInserter = std::back_insert_iterator<SourceMetadatas>;
/** Copy the track metadata in the provided iterator. Thread safe. */
@@ -234,8 +226,6 @@
bool presentationComplete(int64_t framesWritten, size_t audioHalFrames);
void signalClientFlag(int32_t flag);
- /** Set that a metadata has changed and needs to be notified to backend. Thread safe. */
- void setMetadataHasChanged() { mChangeNotified.clear(); }
public:
void triggerEvents(AudioSystem::sync_event_t type);
virtual void invalidate();
@@ -320,8 +310,6 @@
bool mFlushHwPending; // track requests for thread flush
bool mPauseHwPending = false; // direct/offload track request for thread pause
audio_output_flags_t mFlags;
- // If the last track change was notified to the client with readAndClearHasChanged
- std::atomic_flag mChangeNotified = ATOMIC_FLAG_INIT;
TeePatches mTeePatches;
}; // end of Track
diff --git a/services/audioflinger/RecordTracks.h b/services/audioflinger/RecordTracks.h
index 451c198..a1c2de7 100644
--- a/services/audioflinger/RecordTracks.h
+++ b/services/audioflinger/RecordTracks.h
@@ -19,17 +19,18 @@
#error This header file should only be included from AudioFlinger.h
#endif
-// Checks and monitors OP_RECORD_AUDIO
+// Checks and monitors app ops for audio record
class OpRecordAudioMonitor : public RefBase {
public:
~OpRecordAudioMonitor() override;
- bool hasOpRecordAudio() const;
+ bool hasOp() const;
+ int32_t getOp() const { return mAppOp; }
static sp<OpRecordAudioMonitor> createIfNeeded
(const media::permission::Identity& identity, const audio_attributes_t& attr);
private:
- explicit OpRecordAudioMonitor(const media::permission::Identity& identity);
+ OpRecordAudioMonitor(const media::permission::Identity& identity, int32_t appOp);
void onFirstRef() override;
AppOpsManager mAppOpsManager;
@@ -44,12 +45,13 @@
};
sp<RecordAudioOpCallback> mOpCallback;
- // called by RecordAudioOpCallback when OP_RECORD_AUDIO is updated in AppOp callback
- // and in onFirstRef()
- void checkRecordAudio();
+ // called by RecordAudioOpCallback when the app op for this OpRecordAudioMonitor is updated
+ // in AppOp callback and in onFirstRef()
+ void checkOp();
- std::atomic_bool mHasOpRecordAudio;
+ std::atomic_bool mHasOp;
const media::permission::Identity mIdentity;
+ const int32_t mAppOp;
};
// record track
@@ -149,7 +151,7 @@
bool mSilenced;
- // used to enforce OP_RECORD_AUDIO
+ // used to enforce the audio record app op corresponding to this track's audio source
sp<OpRecordAudioMonitor> mOpRecordAudioMonitor;
std::string mSharedAudioPackageName = {};
int32_t mStartFrames = -1;
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index d42a6ca..d878611 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -1798,8 +1798,14 @@
template <typename T>
bool AudioFlinger::ThreadBase::ActiveTracks<T>::readAndClearHasChanged() {
- const bool hasChanged = mHasChanged;
+ bool hasChanged = mHasChanged;
mHasChanged = false;
+
+ for (const sp<T> &track : mActiveTracks) {
+ // Do not short-circuit as all hasChanged states must be reset
+ // as all the metadata are going to be sent
+ hasChanged |= track->readAndClearHasChanged();
+ }
return hasChanged;
}
@@ -1986,7 +1992,7 @@
void AudioFlinger::PlaybackThread::onFirstRef()
{
- if (mOutput == nullptr || mOutput->stream == nullptr) {
+ if (!isStreamInitialized()) {
ALOGE("The stream is not open yet"); // This should not happen.
} else {
// setEventCallback will need a strong pointer as a parameter. Calling it
@@ -2695,7 +2701,7 @@
status_t AudioFlinger::DirectOutputThread::selectPresentation(int presentationId, int programId) {
Mutex::Autolock _l(mLock);
- if (mOutput == nullptr || mOutput->stream == nullptr) {
+ if (!isStreamInitialized()) {
return NO_INIT;
}
return mOutput->stream->selectPresentation(presentationId, programId);
@@ -2992,16 +2998,7 @@
void AudioFlinger::PlaybackThread::updateMetadata_l()
{
- if (mOutput == nullptr || mOutput->stream == nullptr ) {
- return; // That should not happen
- }
- bool hasChanged = mActiveTracks.readAndClearHasChanged();
- for (const sp<Track> &track : mActiveTracks) {
- // Do not short-circuit as all hasChanged states must be reset
- // as all the metadata are going to be sent
- hasChanged |= track->readAndClearHasChanged();
- }
- if (!hasChanged) {
+ if (!isStreamInitialized() || !mActiveTracks.readAndClearHasChanged()) {
return; // nothing to do
}
StreamOutHalInterface::SourceMetadata metadata;
@@ -8186,7 +8183,7 @@
{
ALOGV("RecordThread::getActiveMicrophones");
AutoMutex _l(mLock);
- if (mInput == nullptr || mInput->stream == nullptr) {
+ if (!isStreamInitialized()) {
return NO_INIT;
}
status_t status = mInput->stream->getActiveMicrophones(activeMicrophones);
@@ -8198,7 +8195,7 @@
{
ALOGV("setPreferredMicrophoneDirection(%d)", direction);
AutoMutex _l(mLock);
- if (mInput == nullptr || mInput->stream == nullptr) {
+ if (!isStreamInitialized()) {
return NO_INIT;
}
return mInput->stream->setPreferredMicrophoneDirection(direction);
@@ -8208,7 +8205,7 @@
{
ALOGV("setPreferredMicrophoneFieldDimension(%f)", zoom);
AutoMutex _l(mLock);
- if (mInput == nullptr || mInput->stream == nullptr) {
+ if (!isStreamInitialized()) {
return NO_INIT;
}
return mInput->stream->setPreferredMicrophoneFieldDimension(zoom);
@@ -8259,9 +8256,8 @@
void AudioFlinger::RecordThread::updateMetadata_l()
{
- if (mInput == nullptr || mInput->stream == nullptr ||
- !mActiveTracks.readAndClearHasChanged()) {
- return;
+ if (!isStreamInitialized() || !mActiveTracks.readAndClearHasChanged()) {
+ return; // nothing to do
}
StreamInHalInterface::SinkMetadata metadata;
for (const sp<RecordTrack> &track : mActiveTracks) {
@@ -9959,14 +9955,16 @@
}
}
}
+ for (const sp<MmapTrack> &track : mActiveTracks) {
+ track->setMetadataHasChanged();
+ }
}
}
void AudioFlinger::MmapPlaybackThread::updateMetadata_l()
{
- if (mOutput == nullptr || mOutput->stream == nullptr ||
- !mActiveTracks.readAndClearHasChanged()) {
- return;
+ if (!isStreamInitialized() || !mActiveTracks.readAndClearHasChanged()) {
+ return; // nothing to do
}
StreamOutHalInterface::SourceMetadata metadata;
for (const sp<MmapTrack> &track : mActiveTracks) {
@@ -10093,9 +10091,8 @@
void AudioFlinger::MmapCaptureThread::updateMetadata_l()
{
- if (mInput == nullptr || mInput->stream == nullptr ||
- !mActiveTracks.readAndClearHasChanged()) {
- return;
+ if (!isStreamInitialized() || !mActiveTracks.readAndClearHasChanged()) {
+ return; // nothing to do
}
StreamInHalInterface::SinkMetadata metadata;
for (const sp<MmapTrack> &track : mActiveTracks) {
diff --git a/services/audioflinger/Threads.h b/services/audioflinger/Threads.h
index 65db986..17acb16 100644
--- a/services/audioflinger/Threads.h
+++ b/services/audioflinger/Threads.h
@@ -527,6 +527,8 @@
}
}
+ virtual bool isStreamInitialized() = 0;
+
protected:
// entry describing an effect being suspended in mSuspendedSessions keyed vector
@@ -741,7 +743,9 @@
void updatePowerState(sp<ThreadBase> thread, bool force = false);
/** @return true if one or move active tracks was added or removed since the
- * last time this function was called or the vector was created. */
+ * last time this function was called or the vector was created.
+ * true if volume of one of active tracks was changed.
+ */
bool readAndClearHasChanged();
private:
@@ -993,6 +997,10 @@
&& outDeviceTypes().count(mTimestampCorrectedDevice) != 0;
}
+ virtual bool isStreamInitialized() {
+ return !(mOutput == nullptr || mOutput->stream == nullptr);
+ }
+
audio_channel_mask_t hapticChannelMask() const override {
return mHapticChannelMask;
}
@@ -1780,6 +1788,10 @@
audio_session_t sharedSessionId = AUDIO_SESSION_NONE,
int64_t sharedAudioStartMs = -1);
+ virtual bool isStreamInitialized() {
+ return !(mInput == nullptr || mInput->stream == nullptr);
+ }
+
protected:
void dumpInternals_l(int fd, const Vector<String16>& args) override;
void dumpTracks_l(int fd, const Vector<String16>& args) override;
@@ -1949,6 +1961,8 @@
virtual void setRecordSilenced(audio_port_handle_t portId __unused,
bool silenced __unused) {}
+ virtual bool isStreamInitialized() { return false; }
+
protected:
void dumpInternals_l(int fd, const Vector<String16>& args) override;
void dumpTracks_l(int fd, const Vector<String16>& args) override;
@@ -2011,6 +2025,10 @@
status_t getExternalPosition(uint64_t *position, int64_t *timeNanos) override;
+ virtual bool isStreamInitialized() {
+ return !(mOutput == nullptr || mOutput->stream == nullptr);
+ }
+
protected:
void dumpInternals_l(int fd, const Vector<String16>& args) override;
@@ -2043,6 +2061,10 @@
status_t getExternalPosition(uint64_t *position, int64_t *timeNanos) override;
+ virtual bool isStreamInitialized() {
+ return !(mInput == nullptr || mInput->stream == nullptr);
+ }
+
protected:
AudioStreamIn* mInput;
diff --git a/services/audioflinger/TrackBase.h b/services/audioflinger/TrackBase.h
index 38dab5b..92f129c 100644
--- a/services/audioflinger/TrackBase.h
+++ b/services/audioflinger/TrackBase.h
@@ -255,6 +255,17 @@
audio_channel_mask_t channelMask() const { return mChannelMask; }
+ /** @return true if the track has changed (metadata or volume) since
+ * the last time this function was called,
+ * true if this function was never called since the track creation,
+ * false otherwise.
+ * Thread safe.
+ */
+ bool readAndClearHasChanged() { return !mChangeNotified.test_and_set(); }
+
+ /** Set that a metadata has changed and needs to be notified to backend. Thread safe. */
+ void setMetadataHasChanged() { mChangeNotified.clear(); }
+
protected:
DISALLOW_COPY_AND_ASSIGN(TrackBase);
@@ -391,6 +402,9 @@
std::atomic<FrameTime> mKernelFrameTime{}; // last frame time on kernel side.
const pid_t mCreatorPid; // can be different from mclient->pid() for instance
// when created by NuPlayer on behalf of a client
+
+ // If the last track change was notified to the client with readAndClearHasChanged
+ std::atomic_flag mChangeNotified = ATOMIC_FLAG_INIT;
};
// PatchProxyBufferProvider interface is implemented by PatchTrack and PatchRecord.
diff --git a/services/audioflinger/Tracks.cpp b/services/audioflinger/Tracks.cpp
index 3e04804..8be7c86 100644
--- a/services/audioflinger/Tracks.cpp
+++ b/services/audioflinger/Tracks.cpp
@@ -1065,6 +1065,8 @@
reset();
}
+ // clear mPauseHwPending because of pause (and possibly flush) during underrun.
+ mPauseHwPending = false;
if (state == PAUSED || state == PAUSING) {
if (mResumeToStopping) {
// happened we need to resume to STOPPING_1
@@ -2213,7 +2215,7 @@
return nullptr;
}
- // Capturing from FM TUNER output is not controlled by OP_RECORD_AUDIO
+ // Capturing from FM TUNER output is not controlled by an app op
// because it does not affect users privacy as does capturing from an actual microphone.
if (attr.source == AUDIO_SOURCE_FM_TUNER) {
ALOGV("not muting FM TUNER capture for uid %d", identity.uid);
@@ -2225,12 +2227,12 @@
|| checkedIdentity.packageName.value().size() == 0) {
return nullptr;
}
- return new OpRecordAudioMonitor(checkedIdentity);
+ return new OpRecordAudioMonitor(checkedIdentity, getOpForSource(attr.source));
}
AudioFlinger::RecordThread::OpRecordAudioMonitor::OpRecordAudioMonitor(
- const Identity& identity)
- : mHasOpRecordAudio(true), mIdentity(identity)
+ const Identity& identity, int32_t appOp)
+ : mHasOp(true), mIdentity(identity), mAppOp(appOp)
{
}
@@ -2244,36 +2246,36 @@
void AudioFlinger::RecordThread::OpRecordAudioMonitor::onFirstRef()
{
- checkRecordAudio();
+ checkOp();
mOpCallback = new RecordAudioOpCallback(this);
- ALOGV("start watching OP_RECORD_AUDIO for %s", mIdentity.toString().c_str());
- mAppOpsManager.startWatchingMode(AppOpsManager::OP_RECORD_AUDIO,
+ ALOGV("start watching op %d for %s", mAppOp, mIdentity.toString().c_str());
+ mAppOpsManager.startWatchingMode(mAppOp,
VALUE_OR_FATAL(aidl2legacy_string_view_String16(mIdentity.packageName.value_or(""))),
mOpCallback);
}
-bool AudioFlinger::RecordThread::OpRecordAudioMonitor::hasOpRecordAudio() const {
- return mHasOpRecordAudio.load();
+bool AudioFlinger::RecordThread::OpRecordAudioMonitor::hasOp() const {
+ return mHasOp.load();
}
-// Called by RecordAudioOpCallback when OP_RECORD_AUDIO is updated in AppOp callback
-// and in onFirstRef()
+// Called by RecordAudioOpCallback when the app op corresponding to this OpRecordAudioMonitor
+// is updated in AppOp callback and in onFirstRef()
// Note this method is never called (and never to be) for audio server / root track
// due to the UID in createIfNeeded(). As a result for those record track, it's:
// - not called from constructor,
// - not called from RecordAudioOpCallback because the callback is not installed in this case
-void AudioFlinger::RecordThread::OpRecordAudioMonitor::checkRecordAudio()
+void AudioFlinger::RecordThread::OpRecordAudioMonitor::checkOp()
{
- const int32_t mode = mAppOpsManager.checkOp(AppOpsManager::OP_RECORD_AUDIO,
+ const int32_t mode = mAppOpsManager.checkOp(mAppOp,
mIdentity.uid, VALUE_OR_FATAL(aidl2legacy_string_view_String16(
mIdentity.packageName.value_or(""))));
const bool hasIt = (mode == AppOpsManager::MODE_ALLOWED);
// verbose logging only log when appOp changed
- ALOGI_IF(hasIt != mHasOpRecordAudio.load(),
- "OP_RECORD_AUDIO missing, %ssilencing record %s",
- hasIt ? "un" : "", mIdentity.toString().c_str());
- mHasOpRecordAudio.store(hasIt);
+ ALOGI_IF(hasIt != mHasOp.load(),
+ "App op %d missing, %ssilencing record %s",
+ mAppOp, hasIt ? "un" : "", mIdentity.toString().c_str());
+ mHasOp.store(hasIt);
}
@@ -2284,12 +2286,12 @@
void AudioFlinger::RecordThread::OpRecordAudioMonitor::RecordAudioOpCallback::opChanged(int32_t op,
const String16& packageName) {
UNUSED(packageName);
- if (op != AppOpsManager::OP_RECORD_AUDIO) {
- return;
- }
sp<OpRecordAudioMonitor> monitor = mMonitor.promote();
if (monitor != NULL) {
- monitor->checkRecordAudio();
+ if (op != monitor->getOp()) {
+ return;
+ }
+ monitor->checkOp();
}
}
@@ -2659,7 +2661,7 @@
return true;
}
// The monitor is only created for record tracks that can be silenced.
- return mOpRecordAudioMonitor ? !mOpRecordAudioMonitor->hasOpRecordAudio() : false;
+ return mOpRecordAudioMonitor ? !mOpRecordAudioMonitor->hasOp() : false;
}
status_t AudioFlinger::RecordThread::RecordTrack::getActiveMicrophones(
diff --git a/services/audiopolicy/enginedefault/src/Engine.cpp b/services/audiopolicy/enginedefault/src/Engine.cpp
index f67ffc1..ca8e96c 100644
--- a/services/audiopolicy/enginedefault/src/Engine.cpp
+++ b/services/audiopolicy/enginedefault/src/Engine.cpp
@@ -186,6 +186,14 @@
(primaryOutput->getPolicyAudioPort()->getModuleVersionMajor() < 3))) {
availableOutputDevices = availPrimaryOutputDevices;
}
+
+ }
+ // Do not use A2DP devices when in call but use them when not in call
+ // (e.g for voice mail playback)
+ if (isInCall()) {
+ availableOutputDevices.remove(availableOutputDevices.getDevicesFromTypes({
+ AUDIO_DEVICE_OUT_BLUETOOTH_A2DP, AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES,
+ AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER, }));
}
} break;
case STRATEGY_ACCESSIBILITY: {
diff --git a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
index 551013f..b9c715e 100644
--- a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
+++ b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
@@ -580,7 +580,7 @@
// Capturing from FM_TUNER source is controlled by captureTunerAudioInputAllowed() and
// captureAudioOutputAllowed() (deprecated) as this does not affect users privacy
// as does capturing from an actual microphone.
- if (!(recordingAllowed(adjIdentity) || attr.source == AUDIO_SOURCE_FM_TUNER)) {
+ if (!(recordingAllowed(adjIdentity, attr.source) || attr.source == AUDIO_SOURCE_FM_TUNER)) {
ALOGE("%s permission denied: recording not allowed for %s",
__func__, adjIdentity.toString().c_str());
return binderStatusFromStatusT(PERMISSION_DENIED);
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index a0448b4..329400d 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -945,7 +945,7 @@
if (!(ret = connectHelper<ICameraClient,Client>(
sp<ICameraClient>{nullptr}, id, cameraId,
internalPackageName, {}, uid, USE_CALLING_PID,
- API_1, /*shimUpdateOnly*/ true, /*out*/ tmp)
+ API_1, /*shimUpdateOnly*/ true, /*oomScoreOffset*/ 0, /*out*/ tmp)
).isOk()) {
ALOGE("%s: Error initializing shim metadata: %s", __FUNCTION__, ret.toString8().string());
}
@@ -1217,10 +1217,12 @@
}
void CameraService::finishConnectLocked(const sp<BasicClient>& client,
- const CameraService::DescriptorPtr& desc) {
+ const CameraService::DescriptorPtr& desc, int oomScoreOffset) {
// Make a descriptor for the incoming client
- auto clientDescriptor = CameraService::CameraClientManager::makeClientDescriptor(client, desc);
+ auto clientDescriptor =
+ CameraService::CameraClientManager::makeClientDescriptor(client, desc,
+ oomScoreOffset);
auto evicted = mActiveClientManager.addAndEvict(clientDescriptor);
logConnected(desc->getKey(), static_cast<int>(desc->getOwnerId()),
@@ -1250,6 +1252,7 @@
status_t CameraService::handleEvictionsLocked(const String8& cameraId, int clientPid,
apiLevel effectiveApiLevel, const sp<IBinder>& remoteCallback, const String8& packageName,
+ int oomScoreOffset,
/*out*/
sp<BasicClient>* client,
std::shared_ptr<resource_policy::ClientDescriptor<String8, sp<BasicClient>>>* partial) {
@@ -1301,7 +1304,8 @@
for (size_t i = 0; i < ownerPids.size() - 1; i++) {
pidToPriorityMap.emplace(ownerPids[i],
resource_policy::ClientPriority(priorityScores[i], states[i],
- /* isVendorClient won't get copied over*/ false));
+ /* isVendorClient won't get copied over*/ false,
+ /* oomScoreOffset won't get copied over*/ 0));
}
mActiveClientManager.updatePriorities(pidToPriorityMap);
@@ -1314,13 +1318,16 @@
return BAD_VALUE;
}
- // Make descriptor for incoming client
+ int32_t actualScore = priorityScores[priorityScores.size() - 1];
+ int32_t actualState = states[states.size() - 1];
+
+ // Make descriptor for incoming client. We store the oomScoreOffset
+ // since we might need it later on new handleEvictionsLocked and
+ // ProcessInfoService would not take that into account.
clientDescriptor = CameraClientManager::makeClientDescriptor(cameraId,
sp<BasicClient>{nullptr}, static_cast<int32_t>(state->getCost()),
- state->getConflicting(),
- priorityScores[priorityScores.size() - 1],
- clientPid,
- states[states.size() - 1]);
+ state->getConflicting(), actualScore, clientPid, actualState,
+ oomScoreOffset);
resource_policy::ClientPriority clientPriority = clientDescriptor->getPriority();
@@ -1463,7 +1470,7 @@
sp<Client> client = nullptr;
ret = connectHelper<ICameraClient,Client>(cameraClient, id, api1CameraId,
clientPackageName, {}, clientUid, clientPid, API_1,
- /*shimUpdateOnly*/ false, /*out*/client);
+ /*shimUpdateOnly*/ false, /*oomScoreOffset*/ 0, /*out*/client);
if(!ret.isOk()) {
logRejected(id, CameraThreadState::getCallingPid(), String8(clientPackageName),
@@ -1539,7 +1546,7 @@
const String16& cameraId,
const String16& clientPackageName,
const std::optional<String16>& clientFeatureId,
- int clientUid,
+ int clientUid, int oomScoreOffset,
/*out*/
sp<hardware::camera2::ICameraDeviceUser>* device) {
@@ -1548,19 +1555,41 @@
String8 id = String8(cameraId);
sp<CameraDeviceClient> client = nullptr;
String16 clientPackageNameAdj = clientPackageName;
+ int callingPid = CameraThreadState::getCallingPid();
if (getCurrentServingCall() == BinderCallType::HWBINDER) {
std::string vendorClient =
StringPrintf("vendor.client.pid<%d>", CameraThreadState::getCallingPid());
clientPackageNameAdj = String16(vendorClient.c_str());
}
+
+ if (oomScoreOffset < 0) {
+ String8 msg =
+ String8::format("Cannot increase the priority of a client %s pid %d for "
+ "camera id %s", String8(clientPackageNameAdj).string(), callingPid,
+ id.string());
+ ALOGE("%s: %s", __FUNCTION__, msg.string());
+ return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT, msg.string());
+ }
+
+ // enforce system camera permissions
+ if (oomScoreOffset > 0 &&
+ !hasPermissionsForSystemCamera(callingPid, CameraThreadState::getCallingUid())) {
+ String8 msg =
+ String8::format("Cannot change the priority of a client %s pid %d for "
+ "camera id %s without SYSTEM_CAMERA permissions",
+ String8(clientPackageNameAdj).string(), callingPid, id.string());
+ ALOGE("%s: %s", __FUNCTION__, msg.string());
+ return STATUS_ERROR(ERROR_PERMISSION_DENIED, msg.string());
+ }
+
ret = connectHelper<hardware::camera2::ICameraDeviceCallbacks,CameraDeviceClient>(cameraCb, id,
/*api1CameraId*/-1, clientPackageNameAdj, clientFeatureId,
- clientUid, USE_CALLING_PID, API_2, /*shimUpdateOnly*/ false, /*out*/client);
+ clientUid, USE_CALLING_PID, API_2, /*shimUpdateOnly*/ false, oomScoreOffset,
+ /*out*/client);
if(!ret.isOk()) {
- logRejected(id, CameraThreadState::getCallingPid(), String8(clientPackageNameAdj),
- ret.toString8());
+ logRejected(id, callingPid, String8(clientPackageNameAdj), ret.toString8());
return ret;
}
@@ -1572,7 +1601,7 @@
Status CameraService::connectHelper(const sp<CALLBACK>& cameraCb, const String8& cameraId,
int api1CameraId, const String16& clientPackageName,
const std::optional<String16>& clientFeatureId, int clientUid, int clientPid,
- apiLevel effectiveApiLevel, bool shimUpdateOnly,
+ apiLevel effectiveApiLevel, bool shimUpdateOnly, int oomScoreOffset,
/*out*/sp<CLIENT>& device) {
binder::Status ret = binder::Status::ok();
@@ -1623,7 +1652,7 @@
sp<BasicClient> clientTmp = nullptr;
std::shared_ptr<resource_policy::ClientDescriptor<String8, sp<BasicClient>>> partial;
if ((err = handleEvictionsLocked(cameraId, originalClientPid, effectiveApiLevel,
- IInterface::asBinder(cameraCb), clientName8, /*out*/&clientTmp,
+ IInterface::asBinder(cameraCb), clientName8, oomScoreOffset, /*out*/&clientTmp,
/*out*/&partial)) != NO_ERROR) {
switch (err) {
case -ENODEV:
@@ -1741,7 +1770,7 @@
mServiceLock.lock();
} else {
// Otherwise, add client to active clients list
- finishConnectLocked(client, partial);
+ finishConnectLocked(client, partial, oomScoreOffset);
}
client->setImageDumpMask(mImageDumpMask);
@@ -1788,7 +1817,8 @@
auto offlineClientDesc = CameraClientManager::makeClientDescriptor(
kOfflineDevice + onlineClientDesc->getKey(), offlineClient, /*cost*/ 0,
/*conflictingKeys*/ std::set<String8>(), onlinePriority.getScore(),
- onlineClientDesc->getOwnerId(), onlinePriority.getState());
+ onlineClientDesc->getOwnerId(), onlinePriority.getState(),
+ /*ommScoreOffset*/ 0);
// Allow only one offline device per camera
auto incompatibleClients = mActiveClientManager.getIncompatibleClients(offlineClientDesc);
@@ -3662,21 +3692,23 @@
CameraService::DescriptorPtr CameraService::CameraClientManager::makeClientDescriptor(
const String8& key, const sp<BasicClient>& value, int32_t cost,
const std::set<String8>& conflictingKeys, int32_t score, int32_t ownerId,
- int32_t state) {
+ int32_t state, int32_t oomScoreOffset) {
bool isVendorClient = getCurrentServingCall() == BinderCallType::HWBINDER;
int32_t score_adj = isVendorClient ? kVendorClientScore : score;
int32_t state_adj = isVendorClient ? kVendorClientState: state;
return std::make_shared<resource_policy::ClientDescriptor<String8, sp<BasicClient>>>(
- key, value, cost, conflictingKeys, score_adj, ownerId, state_adj, isVendorClient);
+ key, value, cost, conflictingKeys, score_adj, ownerId, state_adj, isVendorClient,
+ oomScoreOffset);
}
CameraService::DescriptorPtr CameraService::CameraClientManager::makeClientDescriptor(
- const sp<BasicClient>& value, const CameraService::DescriptorPtr& partial) {
+ const sp<BasicClient>& value, const CameraService::DescriptorPtr& partial,
+ int32_t oomScoreOffset) {
return makeClientDescriptor(partial->getKey(), value, partial->getCost(),
partial->getConflicting(), partial->getPriority().getScore(),
- partial->getOwnerId(), partial->getPriority().getState());
+ partial->getOwnerId(), partial->getPriority().getState(), oomScoreOffset);
}
// ----------------------------------------------------------------------------
diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h
index 10e1748..22dd0db 100644
--- a/services/camera/libcameraservice/CameraService.h
+++ b/services/camera/libcameraservice/CameraService.h
@@ -138,7 +138,7 @@
virtual binder::Status connectDevice(
const sp<hardware::camera2::ICameraDeviceCallbacks>& cameraCb, const String16& cameraId,
const String16& clientPackageName, const std::optional<String16>& clientFeatureId,
- int32_t clientUid,
+ int32_t clientUid, int scoreOffset,
/*out*/
sp<hardware::camera2::ICameraDeviceUser>* device);
@@ -510,14 +510,14 @@
*/
static DescriptorPtr makeClientDescriptor(const String8& key, const sp<BasicClient>& value,
int32_t cost, const std::set<String8>& conflictingKeys, int32_t score,
- int32_t ownerId, int32_t state);
+ int32_t ownerId, int32_t state, int oomScoreOffset);
/**
* Make a ClientDescriptor object wrapping the given BasicClient strong pointer with
* values intialized from a prior ClientDescriptor.
*/
static DescriptorPtr makeClientDescriptor(const sp<BasicClient>& value,
- const CameraService::DescriptorPtr& partial);
+ const CameraService::DescriptorPtr& partial, int oomScoreOffset);
}; // class CameraClientManager
@@ -739,6 +739,7 @@
// Only call with with mServiceLock held.
status_t handleEvictionsLocked(const String8& cameraId, int clientPid,
apiLevel effectiveApiLevel, const sp<IBinder>& remoteCallback, const String8& packageName,
+ int scoreOffset,
/*out*/
sp<BasicClient>* client,
std::shared_ptr<resource_policy::ClientDescriptor<String8, sp<BasicClient>>>* partial);
@@ -772,7 +773,8 @@
binder::Status connectHelper(const sp<CALLBACK>& cameraCb, const String8& cameraId,
int api1CameraId, const String16& clientPackageName,
const std::optional<String16>& clientFeatureId, int clientUid, int clientPid,
- apiLevel effectiveApiLevel, bool shimUpdateOnly, /*out*/sp<CLIENT>& device);
+ apiLevel effectiveApiLevel, bool shimUpdateOnly, int scoreOffset,
+ /*out*/sp<CLIENT>& device);
// Lock guarding camera service state
Mutex mServiceLock;
@@ -831,7 +833,8 @@
*
* This method must be called with mServiceLock held.
*/
- void finishConnectLocked(const sp<BasicClient>& client, const DescriptorPtr& desc);
+ void finishConnectLocked(const sp<BasicClient>& client, const DescriptorPtr& desc,
+ int oomScoreOffset);
/**
* Returns the underlying camera Id string mapped to a camera id int
diff --git a/services/camera/libcameraservice/hidl/HidlCameraService.cpp b/services/camera/libcameraservice/hidl/HidlCameraService.cpp
index aa1e95a..88d2f72 100644
--- a/services/camera/libcameraservice/hidl/HidlCameraService.cpp
+++ b/services/camera/libcameraservice/hidl/HidlCameraService.cpp
@@ -104,7 +104,7 @@
sp<hardware::camera2::ICameraDeviceCallbacks> callbacks = hybridCallbacks;
binder::Status serviceRet = mAidlICameraService->connectDevice(
callbacks, String16(cameraId.c_str()), String16(""), {},
- hardware::ICameraService::USE_CALLING_UID, /*out*/&deviceRemote);
+ hardware::ICameraService::USE_CALLING_UID, 0/*oomScoreOffset*/, /*out*/&deviceRemote);
HStatus status = HStatus::NO_ERROR;
if (!serviceRet.isOk()) {
ALOGE("%s: Unable to connect to camera device", __FUNCTION__);
diff --git a/services/camera/libcameraservice/libcameraservice_fuzzer/camera_service_fuzzer.cpp b/services/camera/libcameraservice/libcameraservice_fuzzer/camera_service_fuzzer.cpp
index 985b2f8..8bd4ed7 100644
--- a/services/camera/libcameraservice/libcameraservice_fuzzer/camera_service_fuzzer.cpp
+++ b/services/camera/libcameraservice/libcameraservice_fuzzer/camera_service_fuzzer.cpp
@@ -526,7 +526,7 @@
sp<TestCameraDeviceCallbacks> callbacks(new TestCameraDeviceCallbacks());
sp<hardware::camera2::ICameraDeviceUser> device;
mCameraService->connectDevice(callbacks, String16(s.cameraId), String16(), {},
- android::CameraService::USE_CALLING_UID, &device);
+ android::CameraService::USE_CALLING_UID, 0/*oomScoreDiff*/, &device);
if (device == nullptr) {
continue;
}
diff --git a/services/camera/libcameraservice/tests/ClientManagerTest.cpp b/services/camera/libcameraservice/tests/ClientManagerTest.cpp
index 037c5c2..c79ef45 100644
--- a/services/camera/libcameraservice/tests/ClientManagerTest.cpp
+++ b/services/camera/libcameraservice/tests/ClientManagerTest.cpp
@@ -44,7 +44,7 @@
TestDescriptorPtr makeDescFromTestClient(const TestClient& tc) {
return std::make_shared<TestClientDescriptor>(/*ID*/tc.mId, tc, tc.mCost, tc.mConflictingKeys,
- tc.mScore, tc.mOwnerId, tc.mState, tc.mIsVendorClient);
+ tc.mScore, tc.mOwnerId, tc.mState, tc.mIsVendorClient, /*oomScoreOffset*/0);
}
class TestClientManager : public ClientManager<int, TestClient> {
diff --git a/services/camera/libcameraservice/utils/ClientManager.h b/services/camera/libcameraservice/utils/ClientManager.h
index 09258ef..d164885 100644
--- a/services/camera/libcameraservice/utils/ClientManager.h
+++ b/services/camera/libcameraservice/utils/ClientManager.h
@@ -64,20 +64,26 @@
* case where the construction is offloaded to another thread which isn't a
* hwbinder thread.
*/
- ClientPriority(int32_t score, int32_t state, bool isVendorClient) :
- mScore((score == INVALID_ADJ) ? UNKNOWN_ADJ : score),
- mState(state),
- mIsVendorClient(isVendorClient) { }
+ ClientPriority(int32_t score, int32_t state, bool isVendorClient, int32_t scoreOffset = 0) :
+ mIsVendorClient(isVendorClient), mScoreOffset(scoreOffset) {
+ setScore(score);
+ setState(state);
+ }
int32_t getScore() const { return mScore; }
int32_t getState() const { return mState; }
+ int32_t isVendorClient() const { return mIsVendorClient; }
void setScore(int32_t score) {
// For vendor clients, the score is set once and for all during
// construction. Otherwise, it can get reset each time cameraserver
// queries ActivityManagerService for oom_adj scores / states .
- if (!mIsVendorClient) {
- mScore = (score == INVALID_ADJ) ? UNKNOWN_ADJ : score;
+ // For clients where the score offset is set by the app, add it to the
+ // score provided by ActivityManagerService.
+ if (score == INVALID_ADJ) {
+ mScore = UNKNOWN_ADJ;
+ } else {
+ mScore = mScoreOffset + score;
}
}
@@ -87,9 +93,7 @@
// queries ActivityManagerService for oom_adj scores / states
// (ActivityManagerService returns a vendor process' state as
// PROCESS_STATE_NONEXISTENT.
- if (!mIsVendorClient) {
- mState = state;
- }
+ mState = state;
}
bool operator==(const ClientPriority& rhs) const {
@@ -120,6 +124,7 @@
int32_t mScore;
int32_t mState;
bool mIsVendorClient = false;
+ int32_t mScoreOffset = 0;
};
// --------------------------------------------------------------------------------
@@ -137,9 +142,10 @@
public:
ClientDescriptor(const KEY& key, const VALUE& value, int32_t cost,
const std::set<KEY>& conflictingKeys, int32_t score, int32_t ownerId, int32_t state,
- bool isVendorClient);
+ bool isVendorClient, int32_t oomScoreOffset);
ClientDescriptor(KEY&& key, VALUE&& value, int32_t cost, std::set<KEY>&& conflictingKeys,
- int32_t score, int32_t ownerId, int32_t state, bool isVendorClient);
+ int32_t score, int32_t ownerId, int32_t state, bool isVendorClient,
+ int32_t oomScoreOffset);
~ClientDescriptor();
@@ -204,18 +210,18 @@
template<class KEY, class VALUE>
ClientDescriptor<KEY, VALUE>::ClientDescriptor(const KEY& key, const VALUE& value, int32_t cost,
const std::set<KEY>& conflictingKeys, int32_t score, int32_t ownerId, int32_t state,
- bool isVendorClient) :
+ bool isVendorClient, int32_t scoreOffset) :
mKey{key}, mValue{value}, mCost{cost}, mConflicting{conflictingKeys},
- mPriority(score, state, isVendorClient),
+ mPriority(score, state, isVendorClient, scoreOffset),
mOwnerId{ownerId} {}
template<class KEY, class VALUE>
ClientDescriptor<KEY, VALUE>::ClientDescriptor(KEY&& key, VALUE&& value, int32_t cost,
std::set<KEY>&& conflictingKeys, int32_t score, int32_t ownerId, int32_t state,
- bool isVendorClient) :
+ bool isVendorClient, int32_t scoreOffset) :
mKey{std::forward<KEY>(key)}, mValue{std::forward<VALUE>(value)}, mCost{cost},
mConflicting{std::forward<std::set<KEY>>(conflictingKeys)},
- mPriority(score, state, isVendorClient), mOwnerId{ownerId} {}
+ mPriority(score, state, isVendorClient, scoreOffset), mOwnerId{ownerId} {}
template<class KEY, class VALUE>
ClientDescriptor<KEY, VALUE>::~ClientDescriptor() {}
@@ -266,6 +272,9 @@
// off in the incoming priority argument since an AIDL thread might have
// called getCurrentServingCall() == BinderCallType::HWBINDER after refreshing
// priorities for old clients through ProcessInfoService::getProcessStatesScoresFromPids().
+ if (mPriority.isVendorClient()) {
+ return;
+ }
mPriority.setScore(priority.getScore());
mPriority.setState(priority.getState());
}
diff --git a/services/mediatranscoding/MediaTranscodingService.cpp b/services/mediatranscoding/MediaTranscodingService.cpp
index b80fe57..8b64134 100644
--- a/services/mediatranscoding/MediaTranscodingService.cpp
+++ b/services/mediatranscoding/MediaTranscodingService.cpp
@@ -131,10 +131,10 @@
void MediaTranscodingService::instantiate() {
std::shared_ptr<MediaTranscodingService> service =
::ndk::SharedRefBase::make<MediaTranscodingService>();
- if (__builtin_available(android __TRANSCODING_MIN_API__, *)) {
- // Once service is started, we want it to stay even is client side perished.
- AServiceManager_forceLazyServicesPersist(true /*persist*/);
- (void)AServiceManager_registerLazyService(service->asBinder().get(), getServiceName());
+ binder_status_t status =
+ AServiceManager_addService(service->asBinder().get(), getServiceName());
+ if (status != STATUS_OK) {
+ return;
}
}
diff --git a/services/mediatranscoding/tests/MediaTranscodingServiceTestHelper.h b/services/mediatranscoding/tests/MediaTranscodingServiceTestHelper.h
index 0cb2fad..20e4bfb 100644
--- a/services/mediatranscoding/tests/MediaTranscodingServiceTestHelper.h
+++ b/services/mediatranscoding/tests/MediaTranscodingServiceTestHelper.h
@@ -481,7 +481,7 @@
// Need thread pool to receive callbacks, otherwise oneway callbacks are
// silently ignored.
ABinderProcess_startThreadPool();
- ::ndk::SpAIBinder binder(AServiceManager_waitForService("media.transcoding"));
+ ::ndk::SpAIBinder binder(AServiceManager_getService("media.transcoding"));
mService = IMediaTranscodingService::fromBinder(binder);
if (mService == nullptr) {
ALOGE("Failed to connect to the media.trascoding service.");