summaryrefslogtreecommitdiff
path: root/media/java
diff options
context:
space:
mode:
Diffstat (limited to 'media/java')
-rw-r--r--media/java/Android.bp12
-rw-r--r--media/java/android/media/AudioSystem.java9
-rw-r--r--media/java/android/media/ExifInterface.java30
-rw-r--r--media/java/android/media/IMediaRouterClient.aidl2
-rw-r--r--media/java/android/media/IMediaRouterService.aidl1
-rw-r--r--media/java/android/media/MediaCodec.java26
-rw-r--r--media/java/android/media/MediaDrm.java11
-rw-r--r--media/java/android/media/MediaFormat.java20
-rw-r--r--media/java/android/media/MediaMetadataRetriever.java5
-rw-r--r--media/java/android/media/MediaPlayer.java6
-rw-r--r--media/java/android/media/MediaRouter.java20
-rw-r--r--media/java/android/media/MediaRouter2.java16
-rw-r--r--media/java/android/media/PlayerBase.java147
-rw-r--r--media/java/android/media/tv/tuner/frontend/FrontendStatus.java82
-rwxr-xr-xmedia/java/android/mtp/MtpDatabase.java18
15 files changed, 172 insertions, 233 deletions
diff --git a/media/java/Android.bp b/media/java/Android.bp
index aea63a073e95..eeaf6e9015ac 100644
--- a/media/java/Android.bp
+++ b/media/java/Android.bp
@@ -8,6 +8,18 @@ package {
}
filegroup {
+ name: "framework-media-sources",
+ srcs: [
+ "**/*.java",
+ "**/*.aidl",
+ ],
+ exclude_srcs: [
+ ":framework-media-tv-tunerresourcemanager-sources-aidl",
+ ],
+ visibility: ["//frameworks/base"],
+}
+
+filegroup {
name: "IMidiDeviceServer.aidl",
srcs: ["android/media/midi/IMidiDeviceServer.aidl"],
}
diff --git a/media/java/android/media/AudioSystem.java b/media/java/android/media/AudioSystem.java
index 9a13953c4a62..329399103984 100644
--- a/media/java/android/media/AudioSystem.java
+++ b/media/java/android/media/AudioSystem.java
@@ -27,6 +27,7 @@ import android.content.pm.PackageManager;
import android.media.audiofx.AudioEffect;
import android.media.audiopolicy.AudioMix;
import android.os.Build;
+import android.os.Vibrator;
import android.telephony.TelephonyManager;
import android.util.Log;
import android.util.Pair;
@@ -1962,6 +1963,14 @@ public class AudioSystem
public static native int getDevicesForRoleAndCapturePreset(
int capturePreset, int role, @NonNull List<AudioDeviceAttributes> devices);
+ /**
+ * @hide
+ * Set the vibrators' information. The value will be used to initialize HapticGenerator.
+ * @param vibrators a list of all available vibrators
+ * @return command completion status
+ */
+ public static native int setVibratorInfos(@NonNull List<Vibrator> vibrators);
+
// Items shared with audio service
/**
diff --git a/media/java/android/media/ExifInterface.java b/media/java/android/media/ExifInterface.java
index 21f8623b1953..d746c850a018 100644
--- a/media/java/android/media/ExifInterface.java
+++ b/media/java/android/media/ExifInterface.java
@@ -32,6 +32,7 @@ import android.content.res.AssetManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.FileUtils;
+import android.os.ParcelFileDescriptor;
import android.system.ErrnoException;
import android.system.Os;
import android.system.OsConstants;
@@ -1531,16 +1532,24 @@ public class ExifInterface {
if (fileDescriptor == null) {
throw new NullPointerException("fileDescriptor cannot be null");
}
- FileDescriptor modernFd = FileUtils.convertToModernFd(fileDescriptor);
+ // If a file descriptor has a modern file descriptor, this means that the file can be
+ // transcoded and not using the modern file descriptor will trigger the transcoding
+ // operation. Thus, to avoid unnecessary transcoding, need to convert to modern file
+ // descriptor if it exists. As of Android S, transcoding is not supported for image files,
+ // so this is for protecting against non-image files sent to ExifInterface, but support may
+ // be added in the future.
+ ParcelFileDescriptor modernFd = FileUtils.convertToModernFd(fileDescriptor);
if (modernFd != null) {
- fileDescriptor = modernFd;
+ fileDescriptor = modernFd.getFileDescriptor();
}
mAssetInputStream = null;
mFilename = null;
boolean isFdDuped = false;
- if (isSeekableFD(fileDescriptor)) {
+ // Can't save attributes to files with transcoding because apps get a different copy of
+ // that file when they're not using it through framework libraries like ExifInterface.
+ if (isSeekableFD(fileDescriptor) && modernFd == null) {
mSeekableFileDescriptor = fileDescriptor;
// Keep the original file descriptor in order to save attributes when it's seekable.
// Otherwise, just close the given file descriptor after reading it because the save
@@ -2545,27 +2554,22 @@ public class ExifInterface {
private void initForFilename(String filename) throws IOException {
FileInputStream in = null;
- FileInputStream legacyInputStream = null;
mAssetInputStream = null;
mFilename = filename;
mIsInputStream = false;
try {
in = new FileInputStream(filename);
- FileDescriptor modernFd = FileUtils.convertToModernFd(in.getFD());
+ ParcelFileDescriptor modernFd = FileUtils.convertToModernFd(in.getFD());
if (modernFd != null) {
- legacyInputStream = in;
- in = new FileInputStream(modernFd);
- }
-
- if (isSeekableFD(in.getFD())) {
- mSeekableFileDescriptor = in.getFD();
- } else {
+ closeQuietly(in);
+ in = new FileInputStream(modernFd.getFileDescriptor());
mSeekableFileDescriptor = null;
+ } else if (isSeekableFD(in.getFD())) {
+ mSeekableFileDescriptor = in.getFD();
}
loadAttributes(in);
} finally {
closeQuietly(in);
- closeQuietly(legacyInputStream);
}
}
diff --git a/media/java/android/media/IMediaRouterClient.aidl b/media/java/android/media/IMediaRouterClient.aidl
index 53122bb990d6..6b754e157cfb 100644
--- a/media/java/android/media/IMediaRouterClient.aidl
+++ b/media/java/android/media/IMediaRouterClient.aidl
@@ -22,6 +22,6 @@ package android.media;
oneway interface IMediaRouterClient {
void onStateChanged();
void onRestoreRoute();
- void onSelectedRouteChanged(String routeId);
+ void onGroupRouteSelected(String routeId);
void onGlobalA2dpChanged(boolean a2dpOn);
}
diff --git a/media/java/android/media/IMediaRouterService.aidl b/media/java/android/media/IMediaRouterService.aidl
index 4b8a8adade1f..f817a3c3c353 100644
--- a/media/java/android/media/IMediaRouterService.aidl
+++ b/media/java/android/media/IMediaRouterService.aidl
@@ -48,6 +48,7 @@ interface IMediaRouterService {
// MediaRouterService.java for readability.
// Methods for MediaRouter2
+ void checkModifyAudioRoutingPermission();
List<MediaRoute2Info> getSystemRoutes();
RoutingSessionInfo getSystemSessionInfo();
diff --git a/media/java/android/media/MediaCodec.java b/media/java/android/media/MediaCodec.java
index b51777c3135a..4968bd1e0ce7 100644
--- a/media/java/android/media/MediaCodec.java
+++ b/media/java/android/media/MediaCodec.java
@@ -1684,7 +1684,6 @@ final public class MediaCodec {
private MediaCodecInfo mCodecInfo;
private final Object mCodecInfoLock = new Object();
private MediaCrypto mCrypto;
- private String mPlaybackId;
private static final int EVENT_CALLBACK = 1;
private static final int EVENT_SET_CALLBACK = 2;
@@ -4499,14 +4498,25 @@ final public class MediaCodec {
int i = 0;
for (final String key: params.keySet()) {
- keys[i] = key;
- Object value = params.get(key);
-
- // Bundle's byte array is a byte[], JNI layer only takes ByteBuffer
- if (value instanceof byte[]) {
- values[i] = ByteBuffer.wrap((byte[])value);
+ if (key.equals(MediaFormat.KEY_AUDIO_SESSION_ID)) {
+ int sessionId = 0;
+ try {
+ sessionId = (Integer)params.get(key);
+ } catch (Exception e) {
+ throw new IllegalArgumentException("Wrong Session ID Parameter!");
+ }
+ keys[i] = "audio-hw-sync";
+ values[i] = AudioSystem.getAudioHwSyncForSession(sessionId);
} else {
- values[i] = value;
+ keys[i] = key;
+ Object value = params.get(key);
+
+ // Bundle's byte array is a byte[], JNI layer only takes ByteBuffer
+ if (value instanceof byte[]) {
+ values[i] = ByteBuffer.wrap((byte[])value);
+ } else {
+ values[i] = value;
+ }
}
++i;
}
diff --git a/media/java/android/media/MediaDrm.java b/media/java/android/media/MediaDrm.java
index 10b99dce53b0..864350e25929 100644
--- a/media/java/android/media/MediaDrm.java
+++ b/media/java/android/media/MediaDrm.java
@@ -2991,13 +2991,16 @@ public final class MediaDrm implements AutoCloseable {
* A {@link LogMessage} records an event in the {@link MediaDrm} framework
* or vendor plugin.
*/
- public static class LogMessage {
+ public static final class LogMessage {
+ private final long timestampMillis;
+ private final int priority;
+ private final String message;
/**
* Timing of the recorded event measured in milliseconds since the Epoch,
* 1970-01-01 00:00:00 +0000 (UTC).
*/
- public final long timestampMillis;
+ public final long getTimestampMillis() { return timestampMillis; }
/**
* Priority of the recorded event.
@@ -3013,13 +3016,13 @@ public final class MediaDrm implements AutoCloseable {
* </ul>
*/
@Log.Level
- public final int priority;
+ public final int getPriority() { return priority; }
/**
* Description of the recorded event.
*/
@NonNull
- public final String message;
+ public final String getMessage() { return message; }
private LogMessage(long timestampMillis, int priority, String message) {
this.timestampMillis = timestampMillis;
diff --git a/media/java/android/media/MediaFormat.java b/media/java/android/media/MediaFormat.java
index af0a9cf2481e..50a326e9a595 100644
--- a/media/java/android/media/MediaFormat.java
+++ b/media/java/android/media/MediaFormat.java
@@ -219,6 +219,15 @@ public final class MediaFormat {
private Map<String, Object> mMap;
/**
+ * A key describing the log session ID for MediaCodec. The log session ID is a random 32-byte
+ * hexadecimal string that is used to associate metrics from multiple media codec instances
+ * to the same playback or recording session.
+ * The associated value is a string.
+ * @hide
+ */
+ public static final String LOG_SESSION_ID = "log-session-id";
+
+ /**
* A key describing the mime type of the MediaFormat.
* The associated value is a string.
*/
@@ -1069,6 +1078,17 @@ public final class MediaFormat {
public static final String KEY_AUDIO_SESSION_ID = "audio-session-id";
/**
+ * A key describing the audio hardware sync ID of the AudioTrack associated
+ * to a tunneled video codec. The associated value is an integer.
+ *
+ * @hide
+ *
+ * @see MediaCodecInfo.CodecCapabilities#FEATURE_TunneledPlayback
+ * @see AudioManager#getAudioHwSyncForSession
+ */
+ public static final String KEY_AUDIO_HW_SYNC = "audio-hw-sync";
+
+ /**
* A key for boolean AUTOSELECT behavior for the track. Tracks with AUTOSELECT=true
* are considered when automatically selecting a track without specific user
* choice, based on the current locale.
diff --git a/media/java/android/media/MediaMetadataRetriever.java b/media/java/android/media/MediaMetadataRetriever.java
index c13f610a908c..2943eee5b1da 100644
--- a/media/java/android/media/MediaMetadataRetriever.java
+++ b/media/java/android/media/MediaMetadataRetriever.java
@@ -33,6 +33,7 @@ import android.os.Build;
import android.os.Bundle;
import android.os.FileUtils;
import android.os.IBinder;
+import android.os.ParcelFileDescriptor;
import android.os.SystemProperties;
import android.text.TextUtils;
@@ -300,11 +301,11 @@ public class MediaMetadataRetriever implements AutoCloseable {
*/
public void setDataSource(FileDescriptor fd, long offset, long length)
throws IllegalArgumentException {
- FileDescriptor modernFd = FileUtils.convertToModernFd(fd);
+ ParcelFileDescriptor modernFd = FileUtils.convertToModernFd(fd);
if (modernFd == null) {
_setDataSource(fd, offset, length);
} else {
- _setDataSource(modernFd, offset, length);
+ _setDataSource(modernFd.getFileDescriptor(), offset, length);
}
}
diff --git a/media/java/android/media/MediaPlayer.java b/media/java/android/media/MediaPlayer.java
index 644afb79814f..2d8babdc9f94 100644
--- a/media/java/android/media/MediaPlayer.java
+++ b/media/java/android/media/MediaPlayer.java
@@ -46,6 +46,7 @@ import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.os.Parcel;
+import android.os.ParcelFileDescriptor;
import android.os.Parcelable;
import android.os.PersistableBundle;
import android.os.PowerManager;
@@ -97,7 +98,6 @@ import java.util.UUID;
import java.util.Vector;
import java.util.concurrent.Executor;
-
/**
* MediaPlayer class can be used to control playback of audio/video files and streams.
*
@@ -1268,11 +1268,11 @@ public class MediaPlayer extends PlayerBase
*/
public void setDataSource(FileDescriptor fd, long offset, long length)
throws IOException, IllegalArgumentException, IllegalStateException {
- FileDescriptor modernFd = FileUtils.convertToModernFd(fd);
+ ParcelFileDescriptor modernFd = FileUtils.convertToModernFd(fd);
if (modernFd == null) {
_setDataSource(fd, offset, length);
} else {
- _setDataSource(modernFd, offset, length);
+ _setDataSource(modernFd.getFileDescriptor(), offset, length);
}
}
diff --git a/media/java/android/media/MediaRouter.java b/media/java/android/media/MediaRouter.java
index dc43ad342725..480e2eaaf40f 100644
--- a/media/java/android/media/MediaRouter.java
+++ b/media/java/android/media/MediaRouter.java
@@ -122,6 +122,8 @@ public class MediaRouter {
mIsBluetoothA2dpOn = mAudioService.isBluetoothA2dpOn();
} catch (RemoteException e) {
Log.e(TAG, "Error querying Bluetooth A2DP state", e);
+ //TODO: When we reach here, mIsBluetoothA2dpOn may not be synced with
+ // mBluetoothA2dpRoute.
}
mHandler.post(new Runnable() {
@Override public void run() {
@@ -403,18 +405,18 @@ public class MediaRouter {
}
}
- void updateSelectedRouteForId(String routeId) {
- RouteInfo selectedRoute = isBluetoothA2dpOn()
+ void handleGroupRouteSelected(String routeId) {
+ RouteInfo routeToSelect = isBluetoothA2dpOn()
? mBluetoothA2dpRoute : mDefaultAudioVideo;
final int count = mRoutes.size();
for (int i = 0; i < count; i++) {
final RouteInfo route = mRoutes.get(i);
if (TextUtils.equals(route.mGlobalRouteId, routeId)) {
- selectedRoute = route;
+ routeToSelect = route;
}
}
- if (selectedRoute != mSelectedRoute) {
- selectRouteStatic(selectedRoute.mSupportedTypes, selectedRoute, false);
+ if (routeToSelect != mSelectedRoute) {
+ selectRouteStatic(routeToSelect.mSupportedTypes, routeToSelect, /*explicit=*/false);
}
}
@@ -675,10 +677,10 @@ public class MediaRouter {
}
@Override
- public void onSelectedRouteChanged(String routeId) {
+ public void onGroupRouteSelected(String groupRouteId) {
mHandler.post(() -> {
if (Client.this == mClient) {
- updateSelectedRouteForId(routeId);
+ handleGroupRouteSelected(groupRouteId);
}
});
}
@@ -689,9 +691,9 @@ public class MediaRouter {
public void onGlobalA2dpChanged(boolean a2dpOn) {
mHandler.post(() -> {
if (mSelectedRoute == mDefaultAudioVideo && a2dpOn) {
- setSelectedRoute(mBluetoothA2dpRoute, false);
+ setSelectedRoute(mBluetoothA2dpRoute, /*explicit=*/false);
} else if (mSelectedRoute == mBluetoothA2dpRoute && !a2dpOn) {
- setSelectedRoute(mDefaultAudioVideo, false);
+ setSelectedRoute(mDefaultAudioVideo, /*explicit=*/false);
}
});
}
diff --git a/media/java/android/media/MediaRouter2.java b/media/java/android/media/MediaRouter2.java
index 1f6855a4ae8e..90fa9a52f5cf 100644
--- a/media/java/android/media/MediaRouter2.java
+++ b/media/java/android/media/MediaRouter2.java
@@ -21,6 +21,7 @@ import static com.android.internal.util.function.pooled.PooledLambda.obtainMessa
import android.annotation.CallbackExecutor;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
import android.annotation.TestApi;
import android.content.Context;
@@ -159,9 +160,11 @@ public final class MediaRouter2 {
* Finally, it will have no effect to call {@link #setOnGetControllerHintsListener}.
*
* @param clientPackageName the package name of the app to control
+ * @throws SecurityException if the caller doesn't have MODIFY_AUDIO_ROUTING permission.
* @hide
*/
@SystemApi
+ @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
@Nullable
public static MediaRouter2 getInstance(@NonNull Context context,
@NonNull String clientPackageName) {
@@ -179,13 +182,20 @@ public final class MediaRouter2 {
synchronized (sSystemRouterLock) {
MediaRouter2 instance = sSystemMediaRouter2Map.get(clientPackageName);
if (instance == null) {
- // TODO: Add permission check here using MODIFY_AUDIO_ROUTING.
if (sManager == null) {
+ IMediaRouterService serviceBinder = IMediaRouterService.Stub.asInterface(
+ ServiceManager.getService(Context.MEDIA_ROUTER_SERVICE));
+ try {
+ // MediaRouterService will throw a SecurityException if the caller
+ // doesn't have MODIFY_AUDIO_ROUTING permission.
+ serviceBinder.checkModifyAudioRoutingPermission();
+ } catch (RemoteException e) {
+ e.rethrowAsRuntimeException();
+ }
sManager = MediaRouter2Manager.getInstance(context.getApplicationContext());
}
instance = new MediaRouter2(context, clientPackageName);
sSystemMediaRouter2Map.put(clientPackageName, instance);
- // TODO: Remove router instance once it is not needed.
instance.registerManagerCallbackForSystemRouter();
}
return instance;
@@ -281,9 +291,9 @@ public final class MediaRouter2 {
mDiscoveryPreference = new RouteDiscoveryPreference.Builder(
sManager.getPreferredFeatures(clientPackageName), true).build();
updateAllRoutesFromManager();
- mMediaRouterService = null; // TODO: Make this non-null and check permission.
// Only used by non-system MediaRouter2.
+ mMediaRouterService = null;
mPackageName = null;
}
diff --git a/media/java/android/media/PlayerBase.java b/media/java/android/media/PlayerBase.java
index 5d0f0aa8a921..86ed50bacb63 100644
--- a/media/java/android/media/PlayerBase.java
+++ b/media/java/android/media/PlayerBase.java
@@ -19,12 +19,10 @@ package android.media;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.ActivityThread;
-import android.app.AppOpsManager;
import android.content.Context;
import android.os.IBinder;
import android.os.Parcel;
import android.os.Parcelable;
-import android.os.Process;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.text.TextUtils;
@@ -51,10 +49,6 @@ public abstract class PlayerBase {
private static final boolean DEBUG = DEBUG_APP_OPS || false;
private static IAudioService sService; //lazy initialization, use getService()
- /** if true, only use OP_PLAY_AUDIO monitoring for logging, and rely on muting to happen
- * in AudioFlinger */
- private static final boolean USE_AUDIOFLINGER_MUTING_FOR_OP = true;
-
// parameters of the player that affect AppOps
protected AudioAttributes mAttributes;
@@ -112,21 +106,6 @@ public abstract class PlayerBase {
* Call from derived class when instantiation / initialization is successful
*/
protected void baseRegisterPlayer(int sessionId) {
- if (!USE_AUDIOFLINGER_MUTING_FOR_OP) {
- IBinder b = ServiceManager.getService(Context.APP_OPS_SERVICE);
- mAppOps = IAppOpsService.Stub.asInterface(b);
- // initialize mHasAppOpsPlayAudio
- updateAppOpsPlayAudio();
- // register a callback to monitor whether the OP_PLAY_AUDIO is still allowed
- mAppOpsCallback = new IAppOpsCallbackWrapper(this);
- try {
- mAppOps.startWatchingMode(AppOpsManager.OP_PLAY_AUDIO,
- ActivityThread.currentPackageName(), mAppOpsCallback);
- } catch (RemoteException e) {
- Log.e(TAG, "Error registering appOps callback", e);
- mHasAppOpsPlayAudio = false;
- }
- }
try {
mPlayerIId = getService().trackPlayer(
new PlayerIdCard(mImplType, mAttributes, new IPlayerWrapper(this),
@@ -150,9 +129,7 @@ public abstract class PlayerBase {
Log.e(TAG, "Error talking to audio service, audio attributes will not be updated", e);
}
synchronized (mLock) {
- boolean attributesChanged = (mAttributes != attr);
mAttributes = attr;
- updateAppOpsPlayAudio_sync(attributesChanged);
}
}
@@ -209,11 +186,6 @@ public abstract class PlayerBase {
Log.v(TAG, "baseStart() piid=" + mPlayerIId + " deviceId=" + deviceId);
}
updateState(AudioPlaybackConfiguration.PLAYER_STATE_STARTED, deviceId);
- synchronized (mLock) {
- if (isRestricted_sync()) {
- playerSetVolume(true/*muting*/,0, 0);
- }
- }
}
void baseSetStartDelayMs(int delayMs) {
@@ -254,13 +226,11 @@ public abstract class PlayerBase {
private void updatePlayerVolume() {
final float finalLeftVol, finalRightVol;
- final boolean isRestricted;
synchronized (mLock) {
finalLeftVol = mVolMultiplier * mLeftVolume * mPanMultiplierL;
finalRightVol = mVolMultiplier * mRightVolume * mPanMultiplierR;
- isRestricted = isRestricted_sync();
}
- playerSetVolume(isRestricted /*muting*/, finalLeftVol, finalRightVol);
+ playerSetVolume(false /*muting*/, finalLeftVol, finalRightVol);
}
void setVolumeMultiplier(float vol) {
@@ -281,9 +251,6 @@ public abstract class PlayerBase {
int baseSetAuxEffectSendLevel(float level) {
synchronized (mLock) {
mAuxEffectSendLevel = level;
- if (isRestricted_sync()) {
- return AudioSystem.SUCCESS;
- }
}
return playerSetAuxEffectSendLevel(false/*muting*/, level);
}
@@ -317,98 +284,6 @@ public abstract class PlayerBase {
}
}
- private void updateAppOpsPlayAudio() {
- synchronized (mLock) {
- updateAppOpsPlayAudio_sync(false);
- }
- }
-
- /**
- * To be called whenever a condition that might affect audibility of this player is updated.
- * Must be called synchronized on mLock.
- */
- void updateAppOpsPlayAudio_sync(boolean attributesChanged) {
- if (USE_AUDIOFLINGER_MUTING_FOR_OP) {
- return;
- }
- boolean oldHasAppOpsPlayAudio = mHasAppOpsPlayAudio;
- try {
- int mode = AppOpsManager.MODE_IGNORED;
- if (mAppOps != null) {
- mode = mAppOps.checkAudioOperation(AppOpsManager.OP_PLAY_AUDIO,
- mAttributes.getUsage(),
- Process.myUid(), ActivityThread.currentPackageName());
- }
- mHasAppOpsPlayAudio = (mode == AppOpsManager.MODE_ALLOWED);
- } catch (RemoteException e) {
- mHasAppOpsPlayAudio = false;
- }
-
- // AppsOps alters a player's volume; when the restriction changes, reflect it on the actual
- // volume used by the player
- try {
- if (oldHasAppOpsPlayAudio != mHasAppOpsPlayAudio ||
- attributesChanged) {
- getService().playerHasOpPlayAudio(mPlayerIId, mHasAppOpsPlayAudio);
- if (!isRestricted_sync()) {
- if (DEBUG_APP_OPS) {
- Log.v(TAG, "updateAppOpsPlayAudio: unmuting player, vol=" + mLeftVolume
- + "/" + mRightVolume);
- }
- playerSetVolume(false/*muting*/,
- mLeftVolume * mPanMultiplierL, mRightVolume * mPanMultiplierR);
- playerSetAuxEffectSendLevel(false/*muting*/, mAuxEffectSendLevel);
- } else {
- if (DEBUG_APP_OPS) {
- Log.v(TAG, "updateAppOpsPlayAudio: muting player");
- }
- playerSetVolume(true/*muting*/, 0.0f, 0.0f);
- playerSetAuxEffectSendLevel(true/*muting*/, 0.0f);
- }
- }
- } catch (Exception e) {
- // failing silently, player might not be in right state
- }
- }
-
- /**
- * To be called by the subclass whenever an operation is potentially restricted.
- * As the media player-common behavior are incorporated into this class, the subclass's need
- * to call this method should be removed, and this method could become private.
- * FIXME can this method be private so subclasses don't have to worry about when to check
- * the restrictions.
- * @return
- */
- boolean isRestricted_sync() {
- if (USE_AUDIOFLINGER_MUTING_FOR_OP) {
- return false;
- }
- // check app ops
- if (mHasAppOpsPlayAudio) {
- return false;
- }
- // check bypass flag
- if ((mAttributes.getAllFlags() & AudioAttributes.FLAG_BYPASS_INTERRUPTION_POLICY) != 0) {
- return false;
- }
- // check force audibility flag and camera restriction
- if (((mAttributes.getAllFlags() & AudioAttributes.FLAG_AUDIBILITY_ENFORCED) != 0)
- && (mAttributes.getUsage() == AudioAttributes.USAGE_ASSISTANCE_SONIFICATION)) {
- boolean cameraSoundForced = false;
- try {
- cameraSoundForced = getService().isCameraSoundForced();
- } catch (RemoteException e) {
- Log.e(TAG, "Cannot access AudioService in isRestricted_sync()");
- } catch (NullPointerException e) {
- Log.e(TAG, "Null AudioService in isRestricted_sync()");
- }
- if (cameraSoundForced) {
- return false;
- }
- }
- return true;
- }
-
private static IAudioService getService()
{
if (sService != null) {
@@ -478,26 +353,6 @@ public abstract class PlayerBase {
abstract void playerStop();
//=====================================================================
- private static class IAppOpsCallbackWrapper extends IAppOpsCallback.Stub {
- private final WeakReference<PlayerBase> mWeakPB;
-
- public IAppOpsCallbackWrapper(PlayerBase pb) {
- mWeakPB = new WeakReference<PlayerBase>(pb);
- }
-
- @Override
- public void opChanged(int op, int uid, String packageName) {
- if (op == AppOpsManager.OP_PLAY_AUDIO) {
- if (DEBUG_APP_OPS) { Log.v(TAG, "opChanged: op=PLAY_AUDIO pack=" + packageName); }
- final PlayerBase pb = mWeakPB.get();
- if (pb != null) {
- pb.updateAppOpsPlayAudio();
- }
- }
- }
- }
-
- //=====================================================================
/**
* Wrapper around an implementation of IPlayer for all subclasses of PlayerBase
* that doesn't keep a strong reference on PlayerBase
diff --git a/media/java/android/media/tv/tuner/frontend/FrontendStatus.java b/media/java/android/media/tv/tuner/frontend/FrontendStatus.java
index 4acaa58a1842..b82a5a914da8 100644
--- a/media/java/android/media/tv/tuner/frontend/FrontendStatus.java
+++ b/media/java/android/media/tv/tuner/frontend/FrontendStatus.java
@@ -52,8 +52,8 @@ public class FrontendStatus {
FRONTEND_STATUS_TYPE_T2_SYSTEM_ID, FRONTEND_STATUS_TYPE_INTERLEAVINGS,
FRONTEND_STATUS_TYPE_ISDBT_SEGMENTS, FRONTEND_STATUS_TYPE_TS_DATA_RATES,
FRONTEND_STATUS_TYPE_MODULATIONS_EXT, FRONTEND_STATUS_TYPE_ROLL_OFF,
- FRONTEND_STATUS_TYPE_IS_MISO, FRONTEND_STATUS_TYPE_IS_LINEAR,
- FRONTEND_STATUS_TYPE_IS_SHORT_FRAMES})
+ FRONTEND_STATUS_TYPE_IS_MISO_ENABLED, FRONTEND_STATUS_TYPE_IS_LINEAR,
+ FRONTEND_STATUS_TYPE_IS_SHORT_FRAMES_ENABLED})
@Retention(RetentionPolicy.SOURCE)
public @interface FrontendStatusType {}
@@ -218,7 +218,7 @@ public class FrontendStatus {
/**
* If the frontend currently supports MISO or not. Only supported in Tuner HAL 1.1 or higher.
*/
- public static final int FRONTEND_STATUS_TYPE_IS_MISO =
+ public static final int FRONTEND_STATUS_TYPE_IS_MISO_ENABLED =
android.hardware.tv.tuner.V1_1.Constants.FrontendStatusTypeExt1_1.IS_MISO;
/**
* If the frontend code rate is linear or not. Only supported in Tuner HAL 1.1 or higher.
@@ -228,7 +228,7 @@ public class FrontendStatus {
/**
* If short frames is enabled or not. Only supported in Tuner HAL 1.1 or higher.
*/
- public static final int FRONTEND_STATUS_TYPE_IS_SHORT_FRAMES =
+ public static final int FRONTEND_STATUS_TYPE_IS_SHORT_FRAMES_ENABLED =
android.hardware.tv.tuner.V1_1.Constants.FrontendStatusTypeExt1_1.IS_SHORT_FRAMES;
/** @hide */
@@ -465,7 +465,7 @@ public class FrontendStatus {
*/
public boolean isDemodLocked() {
if (mIsDemodLocked == null) {
- throw new IllegalStateException();
+ throw new IllegalStateException("DemodLocked status is empty");
}
return mIsDemodLocked;
}
@@ -474,7 +474,7 @@ public class FrontendStatus {
*/
public int getSnr() {
if (mSnr == null) {
- throw new IllegalStateException();
+ throw new IllegalStateException("Snr status is empty");
}
return mSnr;
}
@@ -485,7 +485,7 @@ public class FrontendStatus {
*/
public int getBer() {
if (mBer == null) {
- throw new IllegalStateException();
+ throw new IllegalStateException("Ber status is empty");
}
return mBer;
}
@@ -497,7 +497,7 @@ public class FrontendStatus {
*/
public int getPer() {
if (mPer == null) {
- throw new IllegalStateException();
+ throw new IllegalStateException("Per status is empty");
}
return mPer;
}
@@ -508,7 +508,7 @@ public class FrontendStatus {
*/
public int getPerBer() {
if (mPerBer == null) {
- throw new IllegalStateException();
+ throw new IllegalStateException("PerBer status is empty");
}
return mPerBer;
}
@@ -517,7 +517,7 @@ public class FrontendStatus {
*/
public int getSignalQuality() {
if (mSignalQuality == null) {
- throw new IllegalStateException();
+ throw new IllegalStateException("SignalQuality status is empty");
}
return mSignalQuality;
}
@@ -526,7 +526,7 @@ public class FrontendStatus {
*/
public int getSignalStrength() {
if (mSignalStrength == null) {
- throw new IllegalStateException();
+ throw new IllegalStateException("SignalStrength status is empty");
}
return mSignalStrength;
}
@@ -535,7 +535,7 @@ public class FrontendStatus {
*/
public int getSymbolRate() {
if (mSymbolRate == null) {
- throw new IllegalStateException();
+ throw new IllegalStateException("SymbolRate status is empty");
}
return mSymbolRate;
}
@@ -546,7 +546,7 @@ public class FrontendStatus {
@FrontendSettings.InnerFec
public long getInnerFec() {
if (mInnerFec == null) {
- throw new IllegalStateException();
+ throw new IllegalStateException("InnerFec status is empty");
}
return mInnerFec;
}
@@ -556,7 +556,7 @@ public class FrontendStatus {
@FrontendModulation
public int getModulation() {
if (mModulation == null) {
- throw new IllegalStateException();
+ throw new IllegalStateException("Modulation status is empty");
}
return mModulation;
}
@@ -566,7 +566,7 @@ public class FrontendStatus {
@FrontendSettings.FrontendSpectralInversion
public int getSpectralInversion() {
if (mInversion == null) {
- throw new IllegalStateException();
+ throw new IllegalStateException("SpectralInversion status is empty");
}
return mInversion;
}
@@ -576,7 +576,7 @@ public class FrontendStatus {
@Lnb.Voltage
public int getLnbVoltage() {
if (mLnbVoltage == null) {
- throw new IllegalStateException();
+ throw new IllegalStateException("LnbVoltage status is empty");
}
return mLnbVoltage;
}
@@ -585,7 +585,7 @@ public class FrontendStatus {
*/
public int getPlpId() {
if (mPlpId == null) {
- throw new IllegalStateException();
+ throw new IllegalStateException("PlpId status is empty");
}
return mPlpId;
}
@@ -594,7 +594,7 @@ public class FrontendStatus {
*/
public boolean isEwbs() {
if (mIsEwbs == null) {
- throw new IllegalStateException();
+ throw new IllegalStateException("Ewbs status is empty");
}
return mIsEwbs;
}
@@ -603,7 +603,7 @@ public class FrontendStatus {
*/
public int getAgc() {
if (mAgc == null) {
- throw new IllegalStateException();
+ throw new IllegalStateException("Agc status is empty");
}
return mAgc;
}
@@ -612,7 +612,7 @@ public class FrontendStatus {
*/
public boolean isLnaOn() {
if (mIsLnaOn == null) {
- throw new IllegalStateException();
+ throw new IllegalStateException("LnaOn status is empty");
}
return mIsLnaOn;
}
@@ -622,7 +622,7 @@ public class FrontendStatus {
@NonNull
public boolean[] getLayerErrors() {
if (mIsLayerErrors == null) {
- throw new IllegalStateException();
+ throw new IllegalStateException("LayerErrors status is empty");
}
return mIsLayerErrors;
}
@@ -631,7 +631,7 @@ public class FrontendStatus {
*/
public int getMer() {
if (mMer == null) {
- throw new IllegalStateException();
+ throw new IllegalStateException("Mer status is empty");
}
return mMer;
}
@@ -642,7 +642,7 @@ public class FrontendStatus {
*/
public int getFreqOffset() {
if (mFreqOffset == null) {
- throw new IllegalStateException();
+ throw new IllegalStateException("FreqOffset status is empty");
}
return mFreqOffset;
}
@@ -652,7 +652,7 @@ public class FrontendStatus {
@DvbtFrontendSettings.Hierarchy
public int getHierarchy() {
if (mHierarchy == null) {
- throw new IllegalStateException();
+ throw new IllegalStateException("Hierarchy status is empty");
}
return mHierarchy;
}
@@ -661,7 +661,7 @@ public class FrontendStatus {
*/
public boolean isRfLocked() {
if (mIsRfLocked == null) {
- throw new IllegalStateException();
+ throw new IllegalStateException("isRfLocked status is empty");
}
return mIsRfLocked;
}
@@ -671,7 +671,7 @@ public class FrontendStatus {
@NonNull
public Atsc3PlpTuningInfo[] getAtsc3PlpTuningInfo() {
if (mPlpInfo == null) {
- throw new IllegalStateException();
+ throw new IllegalStateException("Atsc3PlpTuningInfo status is empty");
}
return mPlpInfo;
}
@@ -687,7 +687,7 @@ public class FrontendStatus {
TunerVersionChecker.checkHigherOrEqualVersionTo(
TunerVersionChecker.TUNER_VERSION_1_1, "getBers status");
if (mBers == null) {
- throw new IllegalStateException();
+ throw new IllegalStateException("Bers status is empty");
}
return mBers;
}
@@ -704,7 +704,7 @@ public class FrontendStatus {
TunerVersionChecker.checkHigherOrEqualVersionTo(
TunerVersionChecker.TUNER_VERSION_1_1, "getCodeRates status");
if (mCodeRates == null) {
- throw new IllegalStateException();
+ throw new IllegalStateException("CodeRates status is empty");
}
return mCodeRates;
}
@@ -720,7 +720,7 @@ public class FrontendStatus {
TunerVersionChecker.checkHigherOrEqualVersionTo(
TunerVersionChecker.TUNER_VERSION_1_1, "getBandwidth status");
if (mBandwidth == null) {
- throw new IllegalStateException();
+ throw new IllegalStateException("Bandwidth status is empty");
}
return mBandwidth;
}
@@ -736,7 +736,7 @@ public class FrontendStatus {
TunerVersionChecker.checkHigherOrEqualVersionTo(
TunerVersionChecker.TUNER_VERSION_1_1, "getGuardInterval status");
if (mGuardInterval == null) {
- throw new IllegalStateException();
+ throw new IllegalStateException("GuardInterval status is empty");
}
return mGuardInterval;
}
@@ -752,7 +752,7 @@ public class FrontendStatus {
TunerVersionChecker.checkHigherOrEqualVersionTo(
TunerVersionChecker.TUNER_VERSION_1_1, "getTransmissionMode status");
if (mTransmissionMode == null) {
- throw new IllegalStateException();
+ throw new IllegalStateException("TransmissionMode status is empty");
}
return mTransmissionMode;
}
@@ -768,7 +768,7 @@ public class FrontendStatus {
TunerVersionChecker.checkHigherOrEqualVersionTo(
TunerVersionChecker.TUNER_VERSION_1_1, "getUec status");
if (mUec == null) {
- throw new IllegalStateException();
+ throw new IllegalStateException("Uec status is empty");
}
return mUec;
}
@@ -784,7 +784,7 @@ public class FrontendStatus {
TunerVersionChecker.checkHigherOrEqualVersionTo(
TunerVersionChecker.TUNER_VERSION_1_1, "getSystemId status");
if (mSystemId == null) {
- throw new IllegalStateException();
+ throw new IllegalStateException("SystemId status is empty");
}
return mSystemId;
}
@@ -801,7 +801,7 @@ public class FrontendStatus {
TunerVersionChecker.checkHigherOrEqualVersionTo(
TunerVersionChecker.TUNER_VERSION_1_1, "getInterleaving status");
if (mInterleaving == null) {
- throw new IllegalStateException();
+ throw new IllegalStateException("Interleaving status is empty");
}
return mInterleaving;
}
@@ -819,7 +819,7 @@ public class FrontendStatus {
TunerVersionChecker.checkHigherOrEqualVersionTo(
TunerVersionChecker.TUNER_VERSION_1_1, "getIsdbtSegment status");
if (mIsdbtSegment == null) {
- throw new IllegalStateException();
+ throw new IllegalStateException("IsdbtSegment status is empty");
}
return mIsdbtSegment;
}
@@ -835,7 +835,7 @@ public class FrontendStatus {
TunerVersionChecker.checkHigherOrEqualVersionTo(
TunerVersionChecker.TUNER_VERSION_1_1, "getTsDataRate status");
if (mTsDataRate == null) {
- throw new IllegalStateException();
+ throw new IllegalStateException("TsDataRate status is empty");
}
return mTsDataRate;
}
@@ -852,7 +852,7 @@ public class FrontendStatus {
TunerVersionChecker.checkHigherOrEqualVersionTo(
TunerVersionChecker.TUNER_VERSION_1_1, "getExtendedModulations status");
if (mModulationsExt == null) {
- throw new IllegalStateException();
+ throw new IllegalStateException("ExtendedModulations status is empty");
}
return mModulationsExt;
}
@@ -868,7 +868,7 @@ public class FrontendStatus {
TunerVersionChecker.checkHigherOrEqualVersionTo(
TunerVersionChecker.TUNER_VERSION_1_1, "getRollOff status");
if (mRollOff == null) {
- throw new IllegalStateException();
+ throw new IllegalStateException("RollOff status is empty");
}
return mRollOff;
}
@@ -883,7 +883,7 @@ public class FrontendStatus {
TunerVersionChecker.checkHigherOrEqualVersionTo(
TunerVersionChecker.TUNER_VERSION_1_1, "isMisoEnabled status");
if (mIsMisoEnabled == null) {
- throw new IllegalStateException();
+ throw new IllegalStateException("isMisoEnabled status is empty");
}
return mIsMisoEnabled;
}
@@ -898,7 +898,7 @@ public class FrontendStatus {
TunerVersionChecker.checkHigherOrEqualVersionTo(
TunerVersionChecker.TUNER_VERSION_1_1, "isLinear status");
if (mIsLinear == null) {
- throw new IllegalStateException();
+ throw new IllegalStateException("isLinear status is empty");
}
return mIsLinear;
}
@@ -913,7 +913,7 @@ public class FrontendStatus {
TunerVersionChecker.checkHigherOrEqualVersionTo(
TunerVersionChecker.TUNER_VERSION_1_1, "isShortFramesEnabled status");
if (mIsShortFrames == null) {
- throw new IllegalStateException();
+ throw new IllegalStateException("isShortFramesEnabled status is empty");
}
return mIsShortFrames;
}
diff --git a/media/java/android/mtp/MtpDatabase.java b/media/java/android/mtp/MtpDatabase.java
index 6141b7fc7463..860d88afe4a2 100755
--- a/media/java/android/mtp/MtpDatabase.java
+++ b/media/java/android/mtp/MtpDatabase.java
@@ -805,8 +805,10 @@ public class MtpDatabase implements AutoCloseable {
ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, byteStream);
- if (byteStream.size() > MAX_THUMB_SIZE)
+ if (byteStream.size() > MAX_THUMB_SIZE) {
+ Log.w(TAG, "getThumbnailProcess: size=" + byteStream.size());
return null;
+ }
byte[] byteArray = byteStream.toByteArray();
@@ -836,7 +838,15 @@ public class MtpDatabase implements AutoCloseable {
outLongs[0] = thumbOffsetAndSize != null ? thumbOffsetAndSize[1] : 0;
outLongs[1] = exif.getAttributeInt(ExifInterface.TAG_PIXEL_X_DIMENSION, 0);
outLongs[2] = exif.getAttributeInt(ExifInterface.TAG_PIXEL_Y_DIMENSION, 0);
- return true;
+ if (exif.getThumbnailRange() != null) {
+ if ((outLongs[0] == 0) || (outLongs[1] == 0) || (outLongs[2] == 0)) {
+ Log.d(TAG, "getThumbnailInfo: check thumb info:"
+ + thumbOffsetAndSize[0] + "," + thumbOffsetAndSize[1]
+ + "," + outLongs[1] + "," + outLongs[2]);
+ }
+
+ return true;
+ }
} catch (IOException e) {
// ignore and fall through
}
@@ -869,7 +879,9 @@ public class MtpDatabase implements AutoCloseable {
case MtpConstants.FORMAT_JFIF:
try {
ExifInterface exif = new ExifInterface(path);
- return exif.getThumbnail();
+
+ if (exif.getThumbnailRange() != null)
+ return exif.getThumbnail();
} catch (IOException e) {
// ignore and fall through
}