summaryrefslogtreecommitdiff
path: root/media
diff options
context:
space:
mode:
authorScott Lobdell <slobdell@google.com>2021-07-27 17:02:32 +0000
committerScott Lobdell <slobdell@google.com>2021-07-27 17:02:32 +0000
commitcb84bc77bfeb89a940d8439f7458fe5d9bef7bef (patch)
treed6e70908803e918eb485e058341ce55d0a957188 /media
parentdc5ea9d31ab76ba378da9c550813e6b7d8be1e69 (diff)
parent6aa393b52cd7362100a2b3e9b0b1dece473cf6dd (diff)
Merge SP1A.210723.002
Change-Id: I220cdfc5cb9db40162fd33f400a54591018d54cf
Diffstat (limited to 'media')
-rw-r--r--media/java/android/media/AudioDeviceInfo.java25
-rw-r--r--media/java/android/media/AudioManager.java26
-rwxr-xr-xmedia/java/android/media/IAudioService.aidl4
-rw-r--r--media/java/android/media/MediaCodec.java31
-rw-r--r--media/java/android/media/MediaRecorder.java7
-rw-r--r--media/java/android/media/tv/tuner/Lnb.java21
-rw-r--r--media/java/android/media/tv/tuner/Tuner.java223
-rw-r--r--media/java/android/media/tv/tuner/dvr/DvrPlayback.java13
-rw-r--r--media/java/android/media/tv/tuner/dvr/DvrRecorder.java13
-rw-r--r--media/java/android/media/tv/tuner/filter/Filter.java23
-rw-r--r--media/jni/android_mtp_MtpDevice.cpp14
11 files changed, 244 insertions, 156 deletions
diff --git a/media/java/android/media/AudioDeviceInfo.java b/media/java/android/media/AudioDeviceInfo.java
index 09b382ee46d0..a186566aec0b 100644
--- a/media/java/android/media/AudioDeviceInfo.java
+++ b/media/java/android/media/AudioDeviceInfo.java
@@ -25,7 +25,6 @@ import android.util.SparseIntArray;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
-import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.TreeSet;
@@ -515,29 +514,7 @@ public final class AudioDeviceInfo {
* For forward compatibility, applications should ignore entries it does not recognize.
*/
public @NonNull int[] getEncodings() {
- final int[] encodings = AudioFormat.filterPublicFormats(mPort.formats());
- boolean hasFloat = false;
- boolean hasExtendedIntegerPrecision = false;
-
- for (int encoding : encodings) {
- if (AudioFormat.isEncodingLinearPcm(encoding)) {
- if (encoding == AudioFormat.ENCODING_PCM_FLOAT) {
- hasFloat = true;
- } else if (AudioFormat.getBytesPerSample(encoding) > 2) {
- hasExtendedIntegerPrecision = true;
- }
- }
- }
- if (hasExtendedIntegerPrecision && !hasFloat) {
- // R and earlier compatibility - add ENCODING_PCM_FLOAT to the end
- // (replacing the zero pad). This ensures pre-S apps that look
- // for ENCODING_PCM_FLOAT continue to see that encoding if the device supports
- // extended precision integers.
- int[] encodingsPlusFloat = Arrays.copyOf(encodings, encodings.length + 1);
- encodingsPlusFloat[encodings.length] = AudioFormat.ENCODING_PCM_FLOAT;
- return encodingsPlusFloat;
- }
- return encodings;
+ return AudioFormat.filterPublicFormats(mPort.formats());
}
/**
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index cdc1964b7f4f..054a7183e67e 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -7118,14 +7118,11 @@ public class AudioManager {
@TestApi
@NonNull
public Map<Integer, Boolean> getSurroundFormats() {
- Map<Integer, Boolean> surroundFormats = new HashMap<>();
- int status = AudioSystem.getSurroundFormats(surroundFormats);
- if (status != AudioManager.SUCCESS) {
- // fail and bail!
- Log.e(TAG, "getSurroundFormats failed:" + status);
- return new HashMap<Integer, Boolean>(); // Always return a map.
+ try {
+ return getService().getSurroundFormats();
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
}
- return surroundFormats;
}
/**
@@ -7172,15 +7169,14 @@ public class AudioManager {
*
* @return a list of surround formats
*/
- public ArrayList<Integer> getReportedSurroundFormats() {
- ArrayList<Integer> reportedSurroundFormats = new ArrayList<>();
- int status = AudioSystem.getReportedSurroundFormats(reportedSurroundFormats);
- if (status != AudioManager.SUCCESS) {
- // fail and bail!
- Log.e(TAG, "getReportedSurroundFormats failed:" + status);
- return new ArrayList<Integer>(); // Always return a list.
+ @TestApi
+ @NonNull
+ public List<Integer> getReportedSurroundFormats() {
+ try {
+ return getService().getReportedSurroundFormats();
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
}
- return reportedSurroundFormats;
}
/**
diff --git a/media/java/android/media/IAudioService.aidl b/media/java/android/media/IAudioService.aidl
index a83b93494e30..268419f8db8f 100755
--- a/media/java/android/media/IAudioService.aidl
+++ b/media/java/android/media/IAudioService.aidl
@@ -159,6 +159,10 @@ interface IAudioService {
oneway void reloadAudioSettings();
+ Map getSurroundFormats();
+
+ List getReportedSurroundFormats();
+
boolean setSurroundFormatEnabled(int audioFormat, boolean enabled);
boolean isSurroundFormatEnabled(int audioFormat);
diff --git a/media/java/android/media/MediaCodec.java b/media/java/android/media/MediaCodec.java
index cc05ecd3f18e..8b9153621165 100644
--- a/media/java/android/media/MediaCodec.java
+++ b/media/java/android/media/MediaCodec.java
@@ -72,6 +72,37 @@ import java.util.concurrent.locks.ReentrantLock;
Finally, you request (or receive) a filled output buffer, consume its contents and release it
back to the codec.
+ <h3 id=qualityFloor><a name="qualityFloor">Minimum Quality Floor for Video Encoding</h3>
+ <p>
+ Beginning with {@link android.os.Build.VERSION_CODES#S}, Android's Video MediaCodecs enforce a
+ minimum quality floor. The intent is to eliminate poor quality video encodings. This quality
+ floor is applied when the codec is in Variable Bitrate (VBR) mode; it is not applied when
+ the codec is in Constant Bitrate (CBR) mode. The quality floor enforcement is also restricted
+ to a particular size range; this size range is currently for video resolutions
+ larger than 320x240 up through 1920x1080.
+
+ <p>
+ When this quality floor is in effect, the codec and supporting framework code will work to
+ ensure that the generated video is of at least a "fair" or "good" quality. The metric
+ used to choose these targets is the VMAF (Video Multi-method Assessment Function) with a
+ target score of 70 for selected test sequences.
+
+ <p>
+ The typical effect is that
+ some videos will generate a higher bitrate than originally configured. This will be most
+ notable for videos which were configured with very low bitrates; the codec will use a bitrate
+ that is determined to be more likely to generate an "fair" or "good" quality video. Another
+ situation is where a video includes very complicated content (lots of motion and detail);
+ in such configurations, the codec will use extra bitrate as needed to avoid losing all of
+ the content's finer detail.
+
+ <p>
+ This quality floor will not impact content captured at high bitrates (a high bitrate should
+ already provide the codec with sufficient capacity to encode all of the detail).
+ The quality floor does not operate on CBR encodings.
+ The quality floor currently does not operate on resolutions of 320x240 or lower, nor on
+ videos with resolution above 1920x1080.
+
<h3>Data Types</h3>
<p>
Codecs operate on three kinds of data: compressed data, raw audio data and raw video data.
diff --git a/media/java/android/media/MediaRecorder.java b/media/java/android/media/MediaRecorder.java
index 5936700ed742..74d55e5eda3f 100644
--- a/media/java/android/media/MediaRecorder.java
+++ b/media/java/android/media/MediaRecorder.java
@@ -1110,6 +1110,13 @@ public class MediaRecorder implements AudioRouting,
* clipped internally to ensure the video recording can proceed smoothly based on
* the capabilities of the platform.
*
+ * <p>
+ * NB: the actual bitrate and other encoding characteristics may be affected by
+ * the minimum quality floor behavior introduced in
+ * {@link android.os.Build.VERSION_CODES#S}. More detail on how and where this
+ * impacts video encoding can be found in the
+ * {@link MediaCodec} page and looking for "quality floor" (near the top of the page).
+ *
* @param bitRate the video encoding bit rate in bits per second.
*/
public void setVideoEncodingBitRate(int bitRate) {
diff --git a/media/java/android/media/tv/tuner/Lnb.java b/media/java/android/media/tv/tuner/Lnb.java
index 59ef4b890320..8b69d33722c5 100644
--- a/media/java/android/media/tv/tuner/Lnb.java
+++ b/media/java/android/media/tv/tuner/Lnb.java
@@ -148,6 +148,7 @@ public class Lnb implements AutoCloseable {
LnbCallback mCallback;
Executor mExecutor;
Tuner mTuner;
+ private final Object mCallbackLock = new Object();
private native int nativeSetVoltage(int voltage);
@@ -164,20 +165,26 @@ public class Lnb implements AutoCloseable {
private Lnb() {}
void setCallback(Executor executor, @Nullable LnbCallback callback, Tuner tuner) {
- mCallback = callback;
- mExecutor = executor;
- mTuner = tuner;
+ synchronized (mCallbackLock) {
+ mCallback = callback;
+ mExecutor = executor;
+ mTuner = tuner;
+ }
}
private void onEvent(int eventType) {
- if (mExecutor != null && mCallback != null) {
- mExecutor.execute(() -> mCallback.onEvent(eventType));
+ synchronized (mCallbackLock) {
+ if (mExecutor != null && mCallback != null) {
+ mExecutor.execute(() -> mCallback.onEvent(eventType));
+ }
}
}
private void onDiseqcMessage(byte[] diseqcMessage) {
- if (mExecutor != null && mCallback != null) {
- mExecutor.execute(() -> mCallback.onDiseqcMessage(diseqcMessage));
+ synchronized (mCallbackLock) {
+ if (mExecutor != null && mCallback != null) {
+ mExecutor.execute(() -> mCallback.onDiseqcMessage(diseqcMessage));
+ }
}
}
diff --git a/media/java/android/media/tv/tuner/Tuner.java b/media/java/android/media/tv/tuner/Tuner.java
index 2ea745b44288..325436648e63 100644
--- a/media/java/android/media/tv/tuner/Tuner.java
+++ b/media/java/android/media/tv/tuner/Tuner.java
@@ -291,7 +291,7 @@ public class Tuner implements AutoCloseable {
@Nullable
private OnTuneEventListener mOnTuneEventListener;
@Nullable
- private Executor mOnTunerEventExecutor;
+ private Executor mOnTuneEventExecutor;
@Nullable
private ScanCallback mScanCallback;
@Nullable
@@ -301,6 +301,10 @@ public class Tuner implements AutoCloseable {
@Nullable
private Executor mOnResourceLostListenerExecutor;
+ private final Object mOnTuneEventLock = new Object();
+ private final Object mScanCallbackLock = new Object();
+ private final Object mOnResourceLostListenerLock = new Object();
+
private Integer mDemuxHandle;
private Integer mFrontendCiCamHandle;
private Integer mFrontendCiCamId;
@@ -398,18 +402,22 @@ public class Tuner implements AutoCloseable {
*/
public void setResourceLostListener(@NonNull @CallbackExecutor Executor executor,
@NonNull OnResourceLostListener listener) {
- Objects.requireNonNull(executor, "OnResourceLostListener must not be null");
- Objects.requireNonNull(listener, "executor must not be null");
- mOnResourceLostListener = listener;
- mOnResourceLostListenerExecutor = executor;
+ synchronized (mOnResourceLostListenerLock) {
+ Objects.requireNonNull(executor, "OnResourceLostListener must not be null");
+ Objects.requireNonNull(listener, "executor must not be null");
+ mOnResourceLostListener = listener;
+ mOnResourceLostListenerExecutor = executor;
+ }
}
/**
* Removes the listener for resource lost.
*/
public void clearResourceLostListener() {
- mOnResourceLostListener = null;
- mOnResourceLostListenerExecutor = null;
+ synchronized (mOnResourceLostListenerLock) {
+ mOnResourceLostListener = null;
+ mOnResourceLostListenerExecutor = null;
+ }
}
/**
@@ -618,10 +626,12 @@ public class Tuner implements AutoCloseable {
break;
}
case MSG_RESOURCE_LOST: {
- if (mOnResourceLostListener != null
+ synchronized (mOnResourceLostListenerLock) {
+ if (mOnResourceLostListener != null
&& mOnResourceLostListenerExecutor != null) {
- mOnResourceLostListenerExecutor.execute(
- () -> mOnResourceLostListener.onResourceLost(Tuner.this));
+ mOnResourceLostListenerExecutor.execute(
+ () -> mOnResourceLostListener.onResourceLost(Tuner.this));
+ }
}
break;
}
@@ -652,8 +662,10 @@ public class Tuner implements AutoCloseable {
*/
public void setOnTuneEventListener(@NonNull @CallbackExecutor Executor executor,
@NonNull OnTuneEventListener eventListener) {
- mOnTuneEventListener = eventListener;
- mOnTunerEventExecutor = executor;
+ synchronized (mOnTuneEventLock) {
+ mOnTuneEventListener = eventListener;
+ mOnTuneEventExecutor = executor;
+ }
}
/**
@@ -663,9 +675,10 @@ public class Tuner implements AutoCloseable {
* @see #setOnTuneEventListener(Executor, OnTuneEventListener)
*/
public void clearOnTuneEventListener() {
- mOnTuneEventListener = null;
- mOnTunerEventExecutor = null;
-
+ synchronized (mOnTuneEventLock) {
+ mOnTuneEventListener = null;
+ mOnTuneEventExecutor = null;
+ }
}
/**
@@ -747,32 +760,34 @@ public class Tuner implements AutoCloseable {
@Result
public int scan(@NonNull FrontendSettings settings, @ScanType int scanType,
@NonNull @CallbackExecutor Executor executor, @NonNull ScanCallback scanCallback) {
- /**
- * Scan can be called again for blink scan if scanCallback and executor are same as before.
- */
- if (((mScanCallback != null) && (mScanCallback != scanCallback))
+ synchronized (mScanCallbackLock) {
+ // Scan can be called again for blink scan if scanCallback and executor are same as
+ //before.
+ if (((mScanCallback != null) && (mScanCallback != scanCallback))
|| ((mScanCallbackExecutor != null) && (mScanCallbackExecutor != executor))) {
- throw new IllegalStateException(
+ throw new IllegalStateException(
"Different Scan session already in progress. stopScan must be called "
+ "before a new scan session can be " + "started.");
- }
- mFrontendType = settings.getType();
- if (mFrontendType == FrontendSettings.TYPE_DTMB) {
- if (!TunerVersionChecker.checkHigherOrEqualVersionTo(
- TunerVersionChecker.TUNER_VERSION_1_1, "Scan with DTMB Frontend")) {
- return RESULT_UNAVAILABLE;
}
- }
- if (checkResource(TunerResourceManager.TUNER_RESOURCE_TYPE_FRONTEND)) {
- mScanCallback = scanCallback;
- mScanCallbackExecutor = executor;
- mFrontendInfo = null;
- FrameworkStatsLog
+ mFrontendType = settings.getType();
+ if (mFrontendType == FrontendSettings.TYPE_DTMB) {
+ if (!TunerVersionChecker.checkHigherOrEqualVersionTo(
+ TunerVersionChecker.TUNER_VERSION_1_1,
+ "Scan with DTMB Frontend")) {
+ return RESULT_UNAVAILABLE;
+ }
+ }
+ if (checkResource(TunerResourceManager.TUNER_RESOURCE_TYPE_FRONTEND)) {
+ mScanCallback = scanCallback;
+ mScanCallbackExecutor = executor;
+ mFrontendInfo = null;
+ FrameworkStatsLog
.write(FrameworkStatsLog.TV_TUNER_STATE_CHANGED, mUserId,
FrameworkStatsLog.TV_TUNER_STATE_CHANGED__STATE__SCANNING);
- return nativeScan(settings.getType(), settings, scanType);
+ return nativeScan(settings.getType(), settings, scanType);
+ }
+ return RESULT_UNAVAILABLE;
}
- return RESULT_UNAVAILABLE;
}
/**
@@ -788,14 +803,15 @@ public class Tuner implements AutoCloseable {
*/
@Result
public int cancelScanning() {
- FrameworkStatsLog
- .write(FrameworkStatsLog.TV_TUNER_STATE_CHANGED, mUserId,
+ synchronized (mScanCallbackLock) {
+ FrameworkStatsLog.write(FrameworkStatsLog.TV_TUNER_STATE_CHANGED, mUserId,
FrameworkStatsLog.TV_TUNER_STATE_CHANGED__STATE__SCAN_STOPPED);
- int retVal = nativeStopScan();
- mScanCallback = null;
- mScanCallbackExecutor = null;
- return retVal;
+ int retVal = nativeStopScan();
+ mScanCallback = null;
+ mScanCallbackExecutor = null;
+ return retVal;
+ }
}
private boolean requestFrontend() {
@@ -1050,8 +1066,10 @@ public class Tuner implements AutoCloseable {
private void onFrontendEvent(int eventType) {
Log.d(TAG, "Got event from tuning. Event type: " + eventType);
- if (mOnTunerEventExecutor != null && mOnTuneEventListener != null) {
- mOnTunerEventExecutor.execute(() -> mOnTuneEventListener.onTuneEvent(eventType));
+ synchronized (mOnTuneEventLock) {
+ if (mOnTuneEventExecutor != null && mOnTuneEventListener != null) {
+ mOnTuneEventExecutor.execute(() -> mOnTuneEventListener.onTuneEvent(eventType));
+ }
}
Log.d(TAG, "Wrote Stats Log for the events from tuning.");
@@ -1072,114 +1090,149 @@ public class Tuner implements AutoCloseable {
private void onLocked() {
Log.d(TAG, "Wrote Stats Log for locked event from scanning.");
- FrameworkStatsLog
- .write(FrameworkStatsLog.TV_TUNER_STATE_CHANGED, mUserId,
- FrameworkStatsLog.TV_TUNER_STATE_CHANGED__STATE__LOCKED);
+ FrameworkStatsLog.write(
+ FrameworkStatsLog.TV_TUNER_STATE_CHANGED, mUserId,
+ FrameworkStatsLog.TV_TUNER_STATE_CHANGED__STATE__LOCKED);
- if (mScanCallbackExecutor != null && mScanCallback != null) {
- mScanCallbackExecutor.execute(() -> mScanCallback.onLocked());
+ synchronized (mScanCallbackLock) {
+ if (mScanCallbackExecutor != null && mScanCallback != null) {
+ mScanCallbackExecutor.execute(() -> mScanCallback.onLocked());
+ }
}
}
private void onScanStopped() {
- if (mScanCallbackExecutor != null && mScanCallback != null) {
- mScanCallbackExecutor.execute(() -> mScanCallback.onScanStopped());
+ synchronized (mScanCallbackLock) {
+ if (mScanCallbackExecutor != null && mScanCallback != null) {
+ mScanCallbackExecutor.execute(() -> mScanCallback.onScanStopped());
+ }
}
}
private void onProgress(int percent) {
- if (mScanCallbackExecutor != null && mScanCallback != null) {
- mScanCallbackExecutor.execute(() -> mScanCallback.onProgress(percent));
+ synchronized (mScanCallbackLock) {
+ if (mScanCallbackExecutor != null && mScanCallback != null) {
+ mScanCallbackExecutor.execute(() -> mScanCallback.onProgress(percent));
+ }
}
}
private void onFrequenciesReport(int[] frequency) {
- if (mScanCallbackExecutor != null && mScanCallback != null) {
- mScanCallbackExecutor.execute(() -> mScanCallback.onFrequenciesReported(frequency));
+ synchronized (mScanCallbackLock) {
+ if (mScanCallbackExecutor != null && mScanCallback != null) {
+ mScanCallbackExecutor.execute(() -> mScanCallback.onFrequenciesReported(frequency));
+ }
}
}
private void onSymbolRates(int[] rate) {
- if (mScanCallbackExecutor != null && mScanCallback != null) {
- mScanCallbackExecutor.execute(() -> mScanCallback.onSymbolRatesReported(rate));
+ synchronized (mScanCallbackLock) {
+ if (mScanCallbackExecutor != null && mScanCallback != null) {
+ mScanCallbackExecutor.execute(() -> mScanCallback.onSymbolRatesReported(rate));
+ }
}
}
private void onHierarchy(int hierarchy) {
- if (mScanCallbackExecutor != null && mScanCallback != null) {
- mScanCallbackExecutor.execute(() -> mScanCallback.onHierarchyReported(hierarchy));
+ synchronized (mScanCallbackLock) {
+ if (mScanCallbackExecutor != null && mScanCallback != null) {
+ mScanCallbackExecutor.execute(() -> mScanCallback.onHierarchyReported(hierarchy));
+ }
}
}
private void onSignalType(int signalType) {
- if (mScanCallbackExecutor != null && mScanCallback != null) {
- mScanCallbackExecutor.execute(() -> mScanCallback.onSignalTypeReported(signalType));
+ synchronized (mScanCallbackLock) {
+ if (mScanCallbackExecutor != null && mScanCallback != null) {
+ mScanCallbackExecutor.execute(() -> mScanCallback.onSignalTypeReported(signalType));
+ }
}
}
private void onPlpIds(int[] plpIds) {
- if (mScanCallbackExecutor != null && mScanCallback != null) {
- mScanCallbackExecutor.execute(() -> mScanCallback.onPlpIdsReported(plpIds));
+ synchronized (mScanCallbackLock) {
+ if (mScanCallbackExecutor != null && mScanCallback != null) {
+ mScanCallbackExecutor.execute(() -> mScanCallback.onPlpIdsReported(plpIds));
+ }
}
}
private void onGroupIds(int[] groupIds) {
- if (mScanCallbackExecutor != null && mScanCallback != null) {
- mScanCallbackExecutor.execute(() -> mScanCallback.onGroupIdsReported(groupIds));
+ synchronized (mScanCallbackLock) {
+ if (mScanCallbackExecutor != null && mScanCallback != null) {
+ mScanCallbackExecutor.execute(() -> mScanCallback.onGroupIdsReported(groupIds));
+ }
}
}
private void onInputStreamIds(int[] inputStreamIds) {
- if (mScanCallbackExecutor != null && mScanCallback != null) {
- mScanCallbackExecutor.execute(
- () -> mScanCallback.onInputStreamIdsReported(inputStreamIds));
+ synchronized (mScanCallbackLock) {
+ if (mScanCallbackExecutor != null && mScanCallback != null) {
+ mScanCallbackExecutor.execute(
+ () -> mScanCallback.onInputStreamIdsReported(inputStreamIds));
+ }
}
}
private void onDvbsStandard(int dvbsStandandard) {
- if (mScanCallbackExecutor != null && mScanCallback != null) {
- mScanCallbackExecutor.execute(
- () -> mScanCallback.onDvbsStandardReported(dvbsStandandard));
+ synchronized (mScanCallbackLock) {
+ if (mScanCallbackExecutor != null && mScanCallback != null) {
+ mScanCallbackExecutor.execute(
+ () -> mScanCallback.onDvbsStandardReported(dvbsStandandard));
+ }
}
}
private void onDvbtStandard(int dvbtStandard) {
- if (mScanCallbackExecutor != null && mScanCallback != null) {
- mScanCallbackExecutor.execute(() -> mScanCallback.onDvbtStandardReported(dvbtStandard));
+ synchronized (mScanCallbackLock) {
+ if (mScanCallbackExecutor != null && mScanCallback != null) {
+ mScanCallbackExecutor.execute(
+ () -> mScanCallback.onDvbtStandardReported(dvbtStandard));
+ }
}
}
private void onAnalogSifStandard(int sif) {
- if (mScanCallbackExecutor != null && mScanCallback != null) {
- mScanCallbackExecutor.execute(() -> mScanCallback.onAnalogSifStandardReported(sif));
+ synchronized (mScanCallbackLock) {
+ if (mScanCallbackExecutor != null && mScanCallback != null) {
+ mScanCallbackExecutor.execute(() -> mScanCallback.onAnalogSifStandardReported(sif));
+ }
}
}
private void onAtsc3PlpInfos(Atsc3PlpInfo[] atsc3PlpInfos) {
- if (mScanCallbackExecutor != null && mScanCallback != null) {
- mScanCallbackExecutor.execute(
- () -> mScanCallback.onAtsc3PlpInfosReported(atsc3PlpInfos));
+ synchronized (mScanCallbackLock) {
+ if (mScanCallbackExecutor != null && mScanCallback != null) {
+ mScanCallbackExecutor.execute(
+ () -> mScanCallback.onAtsc3PlpInfosReported(atsc3PlpInfos));
+ }
}
}
private void onModulationReported(int modulation) {
- if (mScanCallbackExecutor != null && mScanCallback != null) {
- mScanCallbackExecutor.execute(
- () -> mScanCallback.onModulationReported(modulation));
+ synchronized (mScanCallbackLock) {
+ if (mScanCallbackExecutor != null && mScanCallback != null) {
+ mScanCallbackExecutor.execute(
+ () -> mScanCallback.onModulationReported(modulation));
+ }
}
}
private void onPriorityReported(boolean isHighPriority) {
- if (mScanCallbackExecutor != null && mScanCallback != null) {
- mScanCallbackExecutor.execute(
- () -> mScanCallback.onPriorityReported(isHighPriority));
+ synchronized (mScanCallbackLock) {
+ if (mScanCallbackExecutor != null && mScanCallback != null) {
+ mScanCallbackExecutor.execute(
+ () -> mScanCallback.onPriorityReported(isHighPriority));
+ }
}
}
private void onDvbcAnnexReported(int dvbcAnnex) {
- if (mScanCallbackExecutor != null && mScanCallback != null) {
- mScanCallbackExecutor.execute(
- () -> mScanCallback.onDvbcAnnexReported(dvbcAnnex));
+ synchronized (mScanCallbackLock) {
+ if (mScanCallbackExecutor != null && mScanCallback != null) {
+ mScanCallbackExecutor.execute(
+ () -> mScanCallback.onDvbcAnnexReported(dvbcAnnex));
+ }
}
}
diff --git a/media/java/android/media/tv/tuner/dvr/DvrPlayback.java b/media/java/android/media/tv/tuner/dvr/DvrPlayback.java
index d70b8c29622e..1f805d761d49 100644
--- a/media/java/android/media/tv/tuner/dvr/DvrPlayback.java
+++ b/media/java/android/media/tv/tuner/dvr/DvrPlayback.java
@@ -85,6 +85,7 @@ public class DvrPlayback implements AutoCloseable {
private static int sInstantId = 0;
private int mSegmentId = 0;
private int mUnderflow;
+ private final Object mListenerLock = new Object();
private native int nativeAttachFilter(Filter filter);
private native int nativeDetachFilter(Filter filter);
@@ -106,16 +107,20 @@ public class DvrPlayback implements AutoCloseable {
/** @hide */
public void setListener(
@NonNull Executor executor, @NonNull OnPlaybackStatusChangedListener listener) {
- mExecutor = executor;
- mListener = listener;
+ synchronized (mListenerLock) {
+ mExecutor = executor;
+ mListener = listener;
+ }
}
private void onPlaybackStatusChanged(int status) {
if (status == PLAYBACK_STATUS_EMPTY) {
mUnderflow++;
}
- if (mExecutor != null && mListener != null) {
- mExecutor.execute(() -> mListener.onPlaybackStatusChanged(status));
+ synchronized (mListenerLock) {
+ if (mExecutor != null && mListener != null) {
+ mExecutor.execute(() -> mListener.onPlaybackStatusChanged(status));
+ }
}
}
diff --git a/media/java/android/media/tv/tuner/dvr/DvrRecorder.java b/media/java/android/media/tv/tuner/dvr/DvrRecorder.java
index 0f9f2e7f89a1..2b694668eb03 100644
--- a/media/java/android/media/tv/tuner/dvr/DvrRecorder.java
+++ b/media/java/android/media/tv/tuner/dvr/DvrRecorder.java
@@ -48,6 +48,7 @@ public class DvrRecorder implements AutoCloseable {
private int mSegmentId = 0;
private int mOverflow;
private Boolean mIsStopped = true;
+ private final Object mListenerLock = new Object();
private native int nativeAttachFilter(Filter filter);
private native int nativeDetachFilter(Filter filter);
@@ -69,16 +70,20 @@ public class DvrRecorder implements AutoCloseable {
/** @hide */
public void setListener(
@NonNull Executor executor, @NonNull OnRecordStatusChangedListener listener) {
- mExecutor = executor;
- mListener = listener;
+ synchronized (mListenerLock) {
+ mExecutor = executor;
+ mListener = listener;
+ }
}
private void onRecordStatusChanged(int status) {
if (status == Filter.STATUS_OVERFLOW) {
mOverflow++;
}
- if (mExecutor != null && mListener != null) {
- mExecutor.execute(() -> mListener.onRecordStatusChanged(status));
+ synchronized (mListenerLock) {
+ if (mExecutor != null && mListener != null) {
+ mExecutor.execute(() -> mListener.onRecordStatusChanged(status));
+ }
}
}
diff --git a/media/java/android/media/tv/tuner/filter/Filter.java b/media/java/android/media/tv/tuner/filter/Filter.java
index 2f3e2d8d5dd9..33742ffd99bf 100644
--- a/media/java/android/media/tv/tuner/filter/Filter.java
+++ b/media/java/android/media/tv/tuner/filter/Filter.java
@@ -227,6 +227,7 @@ public class Filter implements AutoCloseable {
private long mNativeContext;
private FilterCallback mCallback;
private Executor mExecutor;
+ private final Object mCallbackLock = new Object();
private final long mId;
private int mMainType;
private int mSubtype;
@@ -253,14 +254,18 @@ public class Filter implements AutoCloseable {
}
private void onFilterStatus(int status) {
- if (mCallback != null && mExecutor != null) {
- mExecutor.execute(() -> mCallback.onFilterStatusChanged(this, status));
+ synchronized (mCallbackLock) {
+ if (mCallback != null && mExecutor != null) {
+ mExecutor.execute(() -> mCallback.onFilterStatusChanged(this, status));
+ }
}
}
private void onFilterEvent(FilterEvent[] events) {
- if (mCallback != null && mExecutor != null) {
- mExecutor.execute(() -> mCallback.onFilterEvent(this, events));
+ synchronized (mCallbackLock) {
+ if (mCallback != null && mExecutor != null) {
+ mExecutor.execute(() -> mCallback.onFilterEvent(this, events));
+ }
}
}
@@ -272,13 +277,17 @@ public class Filter implements AutoCloseable {
/** @hide */
public void setCallback(FilterCallback cb, Executor executor) {
- mCallback = cb;
- mExecutor = executor;
+ synchronized (mCallbackLock) {
+ mCallback = cb;
+ mExecutor = executor;
+ }
}
/** @hide */
public FilterCallback getCallback() {
- return mCallback;
+ synchronized (mCallbackLock) {
+ return mCallback;
+ }
}
/**
diff --git a/media/jni/android_mtp_MtpDevice.cpp b/media/jni/android_mtp_MtpDevice.cpp
index ac89fecd9150..8436ba412b2d 100644
--- a/media/jni/android_mtp_MtpDevice.cpp
+++ b/media/jni/android_mtp_MtpDevice.cpp
@@ -416,20 +416,14 @@ android_mtp_MtpDevice_set_device_property_init_version(JNIEnv *env, jobject thiz
return -1;
}
- MtpProperty* property = new MtpProperty(MTP_DEVICE_PROPERTY_SESSION_INITIATOR_VERSION_INFO,
- MTP_TYPE_STR, true);
- if (!property) {
- env->ThrowNew(clazz_io_exception, "Failed to obtain property.");
- return -1;
- }
-
- if (property->getDataType() != MTP_TYPE_STR) {
+ MtpProperty property(MTP_DEVICE_PROPERTY_SESSION_INITIATOR_VERSION_INFO, MTP_TYPE_STR, true);
+ if (property.getDataType() != MTP_TYPE_STR) {
env->ThrowNew(clazz_io_exception, "Unexpected property data type.");
return -1;
}
- property->setCurrentValue(propertyStr);
- if (!device->setDevicePropValueStr(property)) {
+ property.setCurrentValue(propertyStr);
+ if (!device->setDevicePropValueStr(&property)) {
env->ThrowNew(clazz_io_exception, "Failed to obtain property value.");
return -1;
}