Loading apex/media/framework/Android.bp +1 −1 Original line number Diff line number Diff line Loading @@ -120,7 +120,7 @@ filegroup { srcs: [ "java/android/media/ApplicationMediaCapabilities.java", "java/android/media/MediaFeature.java", "java/android/media/MediaTranscodeManager.java", "java/android/media/MediaTranscodingManager.java", ], path: "java", } Loading apex/media/framework/api/system-current.txt +19 −19 Original line number Diff line number Diff line // Signature format: 2.0 package android.media { public final class MediaTranscodeManager { method @Nullable public android.media.MediaTranscodeManager.TranscodingSession enqueueRequest(@NonNull android.media.MediaTranscodeManager.TranscodingRequest, @NonNull java.util.concurrent.Executor, @NonNull android.media.MediaTranscodeManager.OnTranscodingFinishedListener); public final class MediaTranscodingManager { method @Nullable public android.media.MediaTranscodingManager.TranscodingSession enqueueRequest(@NonNull android.media.MediaTranscodingManager.TranscodingRequest, @NonNull java.util.concurrent.Executor, @NonNull android.media.MediaTranscodingManager.OnTranscodingFinishedListener); } @java.lang.FunctionalInterface public static interface MediaTranscodeManager.OnTranscodingFinishedListener { method public void onTranscodingFinished(@NonNull android.media.MediaTranscodeManager.TranscodingSession); @java.lang.FunctionalInterface public static interface MediaTranscodingManager.OnTranscodingFinishedListener { method public void onTranscodingFinished(@NonNull android.media.MediaTranscodingManager.TranscodingSession); } public abstract static class MediaTranscodeManager.TranscodingRequest { public abstract static class MediaTranscodingManager.TranscodingRequest { method public int getClientPid(); method public int getClientUid(); method @Nullable public android.os.ParcelFileDescriptor getDestinationFileDescriptor(); Loading @@ -18,13 +18,13 @@ package android.media { method @NonNull public android.net.Uri getSourceUri(); } public static class MediaTranscodeManager.TranscodingRequest.VideoFormatResolver { ctor public MediaTranscodeManager.TranscodingRequest.VideoFormatResolver(@NonNull android.media.ApplicationMediaCapabilities, @NonNull android.media.MediaFormat); public static class MediaTranscodingManager.TranscodingRequest.VideoFormatResolver { ctor public MediaTranscodingManager.TranscodingRequest.VideoFormatResolver(@NonNull android.media.ApplicationMediaCapabilities, @NonNull android.media.MediaFormat); method @Nullable public android.media.MediaFormat resolveVideoFormat(); method public boolean shouldTranscode(); } public static final class MediaTranscodeManager.TranscodingSession { public static final class MediaTranscodingManager.TranscodingSession { method public boolean addClientUid(int); method public void cancel(); method @NonNull public java.util.List<java.lang.Integer> getClientUids(); Loading @@ -33,7 +33,7 @@ package android.media { method public int getResult(); method public int getSessionId(); method public int getStatus(); method public void setOnProgressUpdateListener(@NonNull java.util.concurrent.Executor, @Nullable android.media.MediaTranscodeManager.TranscodingSession.OnProgressUpdateListener); method public void setOnProgressUpdateListener(@NonNull java.util.concurrent.Executor, @Nullable android.media.MediaTranscodingManager.TranscodingSession.OnProgressUpdateListener); field public static final int ERROR_DROPPED_BY_SERVICE = 1; // 0x1 field public static final int ERROR_NONE = 0; // 0x0 field public static final int ERROR_SERVICE_DIED = 2; // 0x2 Loading @@ -47,21 +47,21 @@ package android.media { field public static final int STATUS_RUNNING = 2; // 0x2 } @java.lang.FunctionalInterface public static interface MediaTranscodeManager.TranscodingSession.OnProgressUpdateListener { method public void onProgressUpdate(@NonNull android.media.MediaTranscodeManager.TranscodingSession, @IntRange(from=0, to=100) int); @java.lang.FunctionalInterface public static interface MediaTranscodingManager.TranscodingSession.OnProgressUpdateListener { method public void onProgressUpdate(@NonNull android.media.MediaTranscodingManager.TranscodingSession, @IntRange(from=0, to=100) int); } public static final class MediaTranscodeManager.VideoTranscodingRequest extends android.media.MediaTranscodeManager.TranscodingRequest { public static final class MediaTranscodingManager.VideoTranscodingRequest extends android.media.MediaTranscodingManager.TranscodingRequest { method @NonNull public android.media.MediaFormat getVideoTrackFormat(); } public static final class MediaTranscodeManager.VideoTranscodingRequest.Builder { ctor public MediaTranscodeManager.VideoTranscodingRequest.Builder(@NonNull android.net.Uri, @NonNull android.net.Uri, @NonNull android.media.MediaFormat); method @NonNull public android.media.MediaTranscodeManager.VideoTranscodingRequest build(); method @NonNull public android.media.MediaTranscodeManager.VideoTranscodingRequest.Builder setClientPid(int); method @NonNull public android.media.MediaTranscodeManager.VideoTranscodingRequest.Builder setClientUid(int); method @NonNull public android.media.MediaTranscodeManager.VideoTranscodingRequest.Builder setDestinationFileDescriptor(@NonNull android.os.ParcelFileDescriptor); method @NonNull public android.media.MediaTranscodeManager.VideoTranscodingRequest.Builder setSourceFileDescriptor(@NonNull android.os.ParcelFileDescriptor); public static final class MediaTranscodingManager.VideoTranscodingRequest.Builder { ctor public MediaTranscodingManager.VideoTranscodingRequest.Builder(@NonNull android.net.Uri, @NonNull android.net.Uri, @NonNull android.media.MediaFormat); method @NonNull public android.media.MediaTranscodingManager.VideoTranscodingRequest build(); method @NonNull public android.media.MediaTranscodingManager.VideoTranscodingRequest.Builder setClientPid(int); method @NonNull public android.media.MediaTranscodingManager.VideoTranscodingRequest.Builder setClientUid(int); method @NonNull public android.media.MediaTranscodingManager.VideoTranscodingRequest.Builder setDestinationFileDescriptor(@NonNull android.os.ParcelFileDescriptor); method @NonNull public android.media.MediaTranscodingManager.VideoTranscodingRequest.Builder setSourceFileDescriptor(@NonNull android.os.ParcelFileDescriptor); } } Loading apex/media/framework/java/android/media/MediaFrameworkInitializer.java +2 −2 Original line number Diff line number Diff line Loading @@ -75,8 +75,8 @@ public class MediaFrameworkInitializer { public static void registerServiceWrappers() { SystemServiceRegistry.registerContextAwareService( Context.MEDIA_TRANSCODING_SERVICE, MediaTranscodeManager.class, context -> new MediaTranscodeManager(context) MediaTranscodingManager.class, context -> new MediaTranscodingManager(context) ); if (SdkLevel.isAtLeastS()) { SystemServiceRegistry.registerContextAwareService( Loading apex/media/framework/java/android/media/MediaTranscodeManager.java→apex/media/framework/java/android/media/MediaTranscodingManager.java +11 −11 Original line number Diff line number Diff line Loading @@ -54,7 +54,7 @@ import java.util.concurrent.Executors; /** Android 12 introduces Compatible media transcoding feature. See <a href="https://developer.android.com/about/versions/12/features#compatible_media_transcoding"> Compatible media transcoding</a>. MediaTranscodeManager provides an interface to the system's media Compatible media transcoding</a>. MediaTranscodingManager provides an interface to the system's media transcoding service and can be used to transcode media files, e.g. transcoding a video from HEVC to AVC. Loading @@ -69,7 +69,7 @@ import java.util.concurrent.Executors; <p> To transcode a media file, first create a {@link TranscodingRequest} through its builder class {@link VideoTranscodingRequest.Builder}. Transcode requests are then enqueue to the manager through {@link MediaTranscodeManager#enqueueRequest( {@link MediaTranscodingManager#enqueueRequest( TranscodingRequest, Executor, OnTranscodingFinishedListener)} TranscodeRequest are processed based on client process's priority and request priority. When a transcode operation is completed the caller is notified via its Loading @@ -87,8 +87,8 @@ import java.util.concurrent.Executors; */ @MinSdk(Build.VERSION_CODES.S) @SystemApi public final class MediaTranscodeManager { private static final String TAG = "MediaTranscodeManager"; public final class MediaTranscodingManager { private static final String TAG = "MediaTranscodingManager"; /** Maximum number of retry to connect to the service. */ private static final int CONNECT_SERVICE_RETRY_COUNT = 100; Loading Loading @@ -127,7 +127,7 @@ public final class MediaTranscodeManager { private final Object mLock = new Object(); @GuardedBy("mLock") @NonNull private ITranscodingClient mTranscodingClient = null; private static MediaTranscodeManager sMediaTranscodeManager; private static MediaTranscodingManager sMediaTranscodingManager; private void handleTranscodingFinished(int sessionId, TranscodingResultParcel result) { synchronized (mPendingTranscodingSessions) { Loading Loading @@ -306,7 +306,7 @@ public final class MediaTranscodeManager { } try { // Do not set hasRetried for retry initiated by MediaTranscodeManager. // Do not set hasRetried for retry initiated by MediaTranscodingManager. session.retryInternal(false /*setHasRetried*/); } catch (Exception re) { // TODO(hkuang): Return correct error code to the client. Loading Loading @@ -423,7 +423,7 @@ public final class MediaTranscodeManager { /** * @hide */ public MediaTranscodeManager(@NonNull Context context) { public MediaTranscodingManager(@NonNull Context context) { mContext = context; mContentResolver = mContext.getContentResolver(); mPackageName = mContext.getPackageName(); Loading Loading @@ -1348,7 +1348,7 @@ public final class MediaTranscodeManager { @IntRange(from = 0, to = 100) int progress); } private final MediaTranscodeManager mManager; private final MediaTranscodingManager mManager; private Executor mListenerExecutor; private OnTranscodingFinishedListener mListener; private int mSessionId = -1; Loading @@ -1374,7 +1374,7 @@ public final class MediaTranscodeManager { private final TranscodingRequest mRequest; private TranscodingSession( @NonNull MediaTranscodeManager manager, @NonNull MediaTranscodingManager manager, @NonNull TranscodingRequest request, @NonNull TranscodingSessionParcel parcel, @NonNull @CallbackExecutor Executor executor, Loading Loading @@ -1675,10 +1675,10 @@ public final class MediaTranscodeManager { /** * Enqueues a TranscodingRequest for execution. * <p> Upon successfully accepting the request, MediaTranscodeManager will return a * <p> Upon successfully accepting the request, MediaTranscodingManager will return a * {@link TranscodingSession} to the client. Client should use {@link TranscodingSession} to * track the progress and get the result. * <p> MediaTranscodeManager will return null if fails to accept the request due to service * <p> MediaTranscodingManager will return null if fails to accept the request due to service * rebooting. Client could retry again after receiving null. * * @param transcodingRequest The TranscodingRequest to enqueue. Loading core/java/android/bluetooth/BluetoothAdapter.java +124 −60 Original line number Diff line number Diff line Loading @@ -64,6 +64,8 @@ import android.os.SystemProperties; import android.util.Log; import android.util.Pair; import com.android.internal.annotations.GuardedBy; import java.io.IOException; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; Loading @@ -78,6 +80,7 @@ import java.util.Map; import java.util.Objects; import java.util.Set; import java.util.UUID; import java.util.WeakHashMap; import java.util.concurrent.Executor; import java.util.concurrent.TimeoutException; import java.util.concurrent.locks.ReentrantReadWriteLock; Loading Loading @@ -715,10 +718,21 @@ public final class BluetoothAdapter { private final IBluetoothManager mManagerService; private final AttributionSource mAttributionSource; // Yeah, keeping both mService and sService isn't pretty, but it's too late // in the current release for a major refactoring, so we leave them both // intact until this can be cleaned up in a future release @UnsupportedAppUsage @GuardedBy("mServiceLock") private IBluetooth mService; private final ReentrantReadWriteLock mServiceLock = new ReentrantReadWriteLock(); @GuardedBy("sServiceLock") private static boolean sServiceRegistered; @GuardedBy("sServiceLock") private static IBluetooth sService; private static final Object sServiceLock = new Object(); private final Object mLock = new Object(); private final Map<LeScanCallback, ScanCallback> mLeScanClients; private final Map<BluetoothDevice, List<Pair<OnMetadataChangedListener, Executor>>> Loading Loading @@ -792,19 +806,11 @@ public final class BluetoothAdapter { * Use {@link #getDefaultAdapter} to get the BluetoothAdapter instance. */ BluetoothAdapter(IBluetoothManager managerService, AttributionSource attributionSource) { if (managerService == null) { throw new IllegalArgumentException("bluetooth manager service is null"); } try { mServiceLock.writeLock().lock(); mService = managerService.registerAdapter(mManagerCallback); } catch (RemoteException e) { Log.e(TAG, "", e); } finally { mServiceLock.writeLock().unlock(); } mManagerService = Objects.requireNonNull(managerService); mAttributionSource = Objects.requireNonNull(attributionSource); synchronized (mServiceLock.writeLock()) { mService = getBluetoothService(mManagerCallback); } mLeScanClients = new HashMap<LeScanCallback, ScanCallback>(); mToken = new Binder(DESCRIPTOR); } Loading Loading @@ -3171,21 +3177,16 @@ public final class BluetoothAdapter { } } @SuppressLint("AndroidFrameworkBluetoothPermission") private final IBluetoothManagerCallback mManagerCallback = private static final IBluetoothManagerCallback sManagerCallback = new IBluetoothManagerCallback.Stub() { @SuppressLint("AndroidFrameworkRequiresPermission") public void onBluetoothServiceUp(IBluetooth bluetoothService) { if (DBG) { Log.d(TAG, "onBluetoothServiceUp: " + bluetoothService); } mServiceLock.writeLock().lock(); mService = bluetoothService; mServiceLock.writeLock().unlock(); synchronized (mProxyServiceStateCallbacks) { for (IBluetoothManagerCallback cb : mProxyServiceStateCallbacks) { synchronized (sServiceLock) { sService = bluetoothService; for (IBluetoothManagerCallback cb : sProxyServiceStateCallbacks.keySet()) { try { if (cb != null) { cb.onBluetoothServiceUp(bluetoothService); Loading @@ -3197,6 +3198,56 @@ public final class BluetoothAdapter { } } } } public void onBluetoothServiceDown() { if (DBG) { Log.d(TAG, "onBluetoothServiceDown"); } synchronized (sServiceLock) { sService = null; for (IBluetoothManagerCallback cb : sProxyServiceStateCallbacks.keySet()) { try { if (cb != null) { cb.onBluetoothServiceDown(); } else { Log.d(TAG, "onBluetoothServiceDown: cb is null!"); } } catch (Exception e) { Log.e(TAG, "", e); } } } } public void onBrEdrDown() { if (VDBG) { Log.i(TAG, "onBrEdrDown"); } synchronized (sServiceLock) { for (IBluetoothManagerCallback cb : sProxyServiceStateCallbacks.keySet()) { try { if (cb != null) { cb.onBrEdrDown(); } else { Log.d(TAG, "onBrEdrDown: cb is null!"); } } catch (Exception e) { Log.e(TAG, "", e); } } } } }; private final IBluetoothManagerCallback mManagerCallback = new IBluetoothManagerCallback.Stub() { public void onBluetoothServiceUp(IBluetooth bluetoothService) { synchronized (mServiceLock.writeLock()) { mService = bluetoothService; } synchronized (mMetadataListeners) { mMetadataListeners.forEach((device, pair) -> { try { Loading @@ -3221,12 +3272,7 @@ public final class BluetoothAdapter { } public void onBluetoothServiceDown() { if (DBG) { Log.d(TAG, "onBluetoothServiceDown: " + mService); } try { mServiceLock.writeLock().lock(); synchronized (mServiceLock.writeLock()) { mService = null; if (mLeScanClients != null) { mLeScanClients.clear(); Loading @@ -3237,29 +3283,10 @@ public final class BluetoothAdapter { if (mBluetoothLeScanner != null) { mBluetoothLeScanner.cleanup(); } } finally { mServiceLock.writeLock().unlock(); } synchronized (mProxyServiceStateCallbacks) { for (IBluetoothManagerCallback cb : mProxyServiceStateCallbacks) { try { if (cb != null) { cb.onBluetoothServiceDown(); } else { Log.d(TAG, "onBluetoothServiceDown: cb is null!"); } } catch (Exception e) { Log.e(TAG, "", e); } } } } public void onBrEdrDown() { if (VDBG) { Log.i(TAG, "onBrEdrDown: " + mService); } } }; Loading Loading @@ -3494,15 +3521,12 @@ public final class BluetoothAdapter { protected void finalize() throws Throwable { try { mManagerService.unregisterAdapter(mManagerCallback); } catch (RemoteException e) { Log.e(TAG, "", e); removeServiceStateCallback(mManagerCallback); } finally { super.finalize(); } } /** * Validate a String Bluetooth address, such as "00:43:A8:23:10:F0" * <p>Alphabetic characters must be uppercase to be valid. Loading Loading @@ -3566,24 +3590,64 @@ public final class BluetoothAdapter { return mAttributionSource; } private final ArrayList<IBluetoothManagerCallback> mProxyServiceStateCallbacks = new ArrayList<IBluetoothManagerCallback>(); @GuardedBy("sServiceLock") private static final WeakHashMap<IBluetoothManagerCallback, Void> sProxyServiceStateCallbacks = new WeakHashMap<>(); /*package*/ IBluetooth getBluetoothService() { synchronized (sServiceLock) { if (sProxyServiceStateCallbacks.isEmpty()) { throw new IllegalStateException( "Anonymous service access requires at least one lifecycle in process"); } return sService; } } @UnsupportedAppUsage /*package*/ IBluetooth getBluetoothService(IBluetoothManagerCallback cb) { synchronized (mProxyServiceStateCallbacks) { if (cb == null) { Log.w(TAG, "getBluetoothService() called with no BluetoothManagerCallback"); } else if (!mProxyServiceStateCallbacks.contains(cb)) { mProxyServiceStateCallbacks.add(cb); } Objects.requireNonNull(cb); synchronized (sServiceLock) { sProxyServiceStateCallbacks.put(cb, null); registerOrUnregisterAdapterLocked(); return sService; } return mService; } /*package*/ void removeServiceStateCallback(IBluetoothManagerCallback cb) { synchronized (mProxyServiceStateCallbacks) { mProxyServiceStateCallbacks.remove(cb); Objects.requireNonNull(cb); synchronized (sServiceLock) { sProxyServiceStateCallbacks.remove(cb); registerOrUnregisterAdapterLocked(); } } /** * Handle registering (or unregistering) a single process-wide * {@link IBluetoothManagerCallback} based on the presence of local * {@link #sProxyServiceStateCallbacks} clients. */ @GuardedBy("sServiceLock") private void registerOrUnregisterAdapterLocked() { final boolean isRegistered = sServiceRegistered; final boolean wantRegistered = !sProxyServiceStateCallbacks.isEmpty(); if (isRegistered != wantRegistered) { if (wantRegistered) { try { sService = mManagerService.registerAdapter(sManagerCallback); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } else { try { mManagerService.unregisterAdapter(sManagerCallback); sService = null; } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } sServiceRegistered = wantRegistered; } } Loading Loading
apex/media/framework/Android.bp +1 −1 Original line number Diff line number Diff line Loading @@ -120,7 +120,7 @@ filegroup { srcs: [ "java/android/media/ApplicationMediaCapabilities.java", "java/android/media/MediaFeature.java", "java/android/media/MediaTranscodeManager.java", "java/android/media/MediaTranscodingManager.java", ], path: "java", } Loading
apex/media/framework/api/system-current.txt +19 −19 Original line number Diff line number Diff line // Signature format: 2.0 package android.media { public final class MediaTranscodeManager { method @Nullable public android.media.MediaTranscodeManager.TranscodingSession enqueueRequest(@NonNull android.media.MediaTranscodeManager.TranscodingRequest, @NonNull java.util.concurrent.Executor, @NonNull android.media.MediaTranscodeManager.OnTranscodingFinishedListener); public final class MediaTranscodingManager { method @Nullable public android.media.MediaTranscodingManager.TranscodingSession enqueueRequest(@NonNull android.media.MediaTranscodingManager.TranscodingRequest, @NonNull java.util.concurrent.Executor, @NonNull android.media.MediaTranscodingManager.OnTranscodingFinishedListener); } @java.lang.FunctionalInterface public static interface MediaTranscodeManager.OnTranscodingFinishedListener { method public void onTranscodingFinished(@NonNull android.media.MediaTranscodeManager.TranscodingSession); @java.lang.FunctionalInterface public static interface MediaTranscodingManager.OnTranscodingFinishedListener { method public void onTranscodingFinished(@NonNull android.media.MediaTranscodingManager.TranscodingSession); } public abstract static class MediaTranscodeManager.TranscodingRequest { public abstract static class MediaTranscodingManager.TranscodingRequest { method public int getClientPid(); method public int getClientUid(); method @Nullable public android.os.ParcelFileDescriptor getDestinationFileDescriptor(); Loading @@ -18,13 +18,13 @@ package android.media { method @NonNull public android.net.Uri getSourceUri(); } public static class MediaTranscodeManager.TranscodingRequest.VideoFormatResolver { ctor public MediaTranscodeManager.TranscodingRequest.VideoFormatResolver(@NonNull android.media.ApplicationMediaCapabilities, @NonNull android.media.MediaFormat); public static class MediaTranscodingManager.TranscodingRequest.VideoFormatResolver { ctor public MediaTranscodingManager.TranscodingRequest.VideoFormatResolver(@NonNull android.media.ApplicationMediaCapabilities, @NonNull android.media.MediaFormat); method @Nullable public android.media.MediaFormat resolveVideoFormat(); method public boolean shouldTranscode(); } public static final class MediaTranscodeManager.TranscodingSession { public static final class MediaTranscodingManager.TranscodingSession { method public boolean addClientUid(int); method public void cancel(); method @NonNull public java.util.List<java.lang.Integer> getClientUids(); Loading @@ -33,7 +33,7 @@ package android.media { method public int getResult(); method public int getSessionId(); method public int getStatus(); method public void setOnProgressUpdateListener(@NonNull java.util.concurrent.Executor, @Nullable android.media.MediaTranscodeManager.TranscodingSession.OnProgressUpdateListener); method public void setOnProgressUpdateListener(@NonNull java.util.concurrent.Executor, @Nullable android.media.MediaTranscodingManager.TranscodingSession.OnProgressUpdateListener); field public static final int ERROR_DROPPED_BY_SERVICE = 1; // 0x1 field public static final int ERROR_NONE = 0; // 0x0 field public static final int ERROR_SERVICE_DIED = 2; // 0x2 Loading @@ -47,21 +47,21 @@ package android.media { field public static final int STATUS_RUNNING = 2; // 0x2 } @java.lang.FunctionalInterface public static interface MediaTranscodeManager.TranscodingSession.OnProgressUpdateListener { method public void onProgressUpdate(@NonNull android.media.MediaTranscodeManager.TranscodingSession, @IntRange(from=0, to=100) int); @java.lang.FunctionalInterface public static interface MediaTranscodingManager.TranscodingSession.OnProgressUpdateListener { method public void onProgressUpdate(@NonNull android.media.MediaTranscodingManager.TranscodingSession, @IntRange(from=0, to=100) int); } public static final class MediaTranscodeManager.VideoTranscodingRequest extends android.media.MediaTranscodeManager.TranscodingRequest { public static final class MediaTranscodingManager.VideoTranscodingRequest extends android.media.MediaTranscodingManager.TranscodingRequest { method @NonNull public android.media.MediaFormat getVideoTrackFormat(); } public static final class MediaTranscodeManager.VideoTranscodingRequest.Builder { ctor public MediaTranscodeManager.VideoTranscodingRequest.Builder(@NonNull android.net.Uri, @NonNull android.net.Uri, @NonNull android.media.MediaFormat); method @NonNull public android.media.MediaTranscodeManager.VideoTranscodingRequest build(); method @NonNull public android.media.MediaTranscodeManager.VideoTranscodingRequest.Builder setClientPid(int); method @NonNull public android.media.MediaTranscodeManager.VideoTranscodingRequest.Builder setClientUid(int); method @NonNull public android.media.MediaTranscodeManager.VideoTranscodingRequest.Builder setDestinationFileDescriptor(@NonNull android.os.ParcelFileDescriptor); method @NonNull public android.media.MediaTranscodeManager.VideoTranscodingRequest.Builder setSourceFileDescriptor(@NonNull android.os.ParcelFileDescriptor); public static final class MediaTranscodingManager.VideoTranscodingRequest.Builder { ctor public MediaTranscodingManager.VideoTranscodingRequest.Builder(@NonNull android.net.Uri, @NonNull android.net.Uri, @NonNull android.media.MediaFormat); method @NonNull public android.media.MediaTranscodingManager.VideoTranscodingRequest build(); method @NonNull public android.media.MediaTranscodingManager.VideoTranscodingRequest.Builder setClientPid(int); method @NonNull public android.media.MediaTranscodingManager.VideoTranscodingRequest.Builder setClientUid(int); method @NonNull public android.media.MediaTranscodingManager.VideoTranscodingRequest.Builder setDestinationFileDescriptor(@NonNull android.os.ParcelFileDescriptor); method @NonNull public android.media.MediaTranscodingManager.VideoTranscodingRequest.Builder setSourceFileDescriptor(@NonNull android.os.ParcelFileDescriptor); } } Loading
apex/media/framework/java/android/media/MediaFrameworkInitializer.java +2 −2 Original line number Diff line number Diff line Loading @@ -75,8 +75,8 @@ public class MediaFrameworkInitializer { public static void registerServiceWrappers() { SystemServiceRegistry.registerContextAwareService( Context.MEDIA_TRANSCODING_SERVICE, MediaTranscodeManager.class, context -> new MediaTranscodeManager(context) MediaTranscodingManager.class, context -> new MediaTranscodingManager(context) ); if (SdkLevel.isAtLeastS()) { SystemServiceRegistry.registerContextAwareService( Loading
apex/media/framework/java/android/media/MediaTranscodeManager.java→apex/media/framework/java/android/media/MediaTranscodingManager.java +11 −11 Original line number Diff line number Diff line Loading @@ -54,7 +54,7 @@ import java.util.concurrent.Executors; /** Android 12 introduces Compatible media transcoding feature. See <a href="https://developer.android.com/about/versions/12/features#compatible_media_transcoding"> Compatible media transcoding</a>. MediaTranscodeManager provides an interface to the system's media Compatible media transcoding</a>. MediaTranscodingManager provides an interface to the system's media transcoding service and can be used to transcode media files, e.g. transcoding a video from HEVC to AVC. Loading @@ -69,7 +69,7 @@ import java.util.concurrent.Executors; <p> To transcode a media file, first create a {@link TranscodingRequest} through its builder class {@link VideoTranscodingRequest.Builder}. Transcode requests are then enqueue to the manager through {@link MediaTranscodeManager#enqueueRequest( {@link MediaTranscodingManager#enqueueRequest( TranscodingRequest, Executor, OnTranscodingFinishedListener)} TranscodeRequest are processed based on client process's priority and request priority. When a transcode operation is completed the caller is notified via its Loading @@ -87,8 +87,8 @@ import java.util.concurrent.Executors; */ @MinSdk(Build.VERSION_CODES.S) @SystemApi public final class MediaTranscodeManager { private static final String TAG = "MediaTranscodeManager"; public final class MediaTranscodingManager { private static final String TAG = "MediaTranscodingManager"; /** Maximum number of retry to connect to the service. */ private static final int CONNECT_SERVICE_RETRY_COUNT = 100; Loading Loading @@ -127,7 +127,7 @@ public final class MediaTranscodeManager { private final Object mLock = new Object(); @GuardedBy("mLock") @NonNull private ITranscodingClient mTranscodingClient = null; private static MediaTranscodeManager sMediaTranscodeManager; private static MediaTranscodingManager sMediaTranscodingManager; private void handleTranscodingFinished(int sessionId, TranscodingResultParcel result) { synchronized (mPendingTranscodingSessions) { Loading Loading @@ -306,7 +306,7 @@ public final class MediaTranscodeManager { } try { // Do not set hasRetried for retry initiated by MediaTranscodeManager. // Do not set hasRetried for retry initiated by MediaTranscodingManager. session.retryInternal(false /*setHasRetried*/); } catch (Exception re) { // TODO(hkuang): Return correct error code to the client. Loading Loading @@ -423,7 +423,7 @@ public final class MediaTranscodeManager { /** * @hide */ public MediaTranscodeManager(@NonNull Context context) { public MediaTranscodingManager(@NonNull Context context) { mContext = context; mContentResolver = mContext.getContentResolver(); mPackageName = mContext.getPackageName(); Loading Loading @@ -1348,7 +1348,7 @@ public final class MediaTranscodeManager { @IntRange(from = 0, to = 100) int progress); } private final MediaTranscodeManager mManager; private final MediaTranscodingManager mManager; private Executor mListenerExecutor; private OnTranscodingFinishedListener mListener; private int mSessionId = -1; Loading @@ -1374,7 +1374,7 @@ public final class MediaTranscodeManager { private final TranscodingRequest mRequest; private TranscodingSession( @NonNull MediaTranscodeManager manager, @NonNull MediaTranscodingManager manager, @NonNull TranscodingRequest request, @NonNull TranscodingSessionParcel parcel, @NonNull @CallbackExecutor Executor executor, Loading Loading @@ -1675,10 +1675,10 @@ public final class MediaTranscodeManager { /** * Enqueues a TranscodingRequest for execution. * <p> Upon successfully accepting the request, MediaTranscodeManager will return a * <p> Upon successfully accepting the request, MediaTranscodingManager will return a * {@link TranscodingSession} to the client. Client should use {@link TranscodingSession} to * track the progress and get the result. * <p> MediaTranscodeManager will return null if fails to accept the request due to service * <p> MediaTranscodingManager will return null if fails to accept the request due to service * rebooting. Client could retry again after receiving null. * * @param transcodingRequest The TranscodingRequest to enqueue. Loading
core/java/android/bluetooth/BluetoothAdapter.java +124 −60 Original line number Diff line number Diff line Loading @@ -64,6 +64,8 @@ import android.os.SystemProperties; import android.util.Log; import android.util.Pair; import com.android.internal.annotations.GuardedBy; import java.io.IOException; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; Loading @@ -78,6 +80,7 @@ import java.util.Map; import java.util.Objects; import java.util.Set; import java.util.UUID; import java.util.WeakHashMap; import java.util.concurrent.Executor; import java.util.concurrent.TimeoutException; import java.util.concurrent.locks.ReentrantReadWriteLock; Loading Loading @@ -715,10 +718,21 @@ public final class BluetoothAdapter { private final IBluetoothManager mManagerService; private final AttributionSource mAttributionSource; // Yeah, keeping both mService and sService isn't pretty, but it's too late // in the current release for a major refactoring, so we leave them both // intact until this can be cleaned up in a future release @UnsupportedAppUsage @GuardedBy("mServiceLock") private IBluetooth mService; private final ReentrantReadWriteLock mServiceLock = new ReentrantReadWriteLock(); @GuardedBy("sServiceLock") private static boolean sServiceRegistered; @GuardedBy("sServiceLock") private static IBluetooth sService; private static final Object sServiceLock = new Object(); private final Object mLock = new Object(); private final Map<LeScanCallback, ScanCallback> mLeScanClients; private final Map<BluetoothDevice, List<Pair<OnMetadataChangedListener, Executor>>> Loading Loading @@ -792,19 +806,11 @@ public final class BluetoothAdapter { * Use {@link #getDefaultAdapter} to get the BluetoothAdapter instance. */ BluetoothAdapter(IBluetoothManager managerService, AttributionSource attributionSource) { if (managerService == null) { throw new IllegalArgumentException("bluetooth manager service is null"); } try { mServiceLock.writeLock().lock(); mService = managerService.registerAdapter(mManagerCallback); } catch (RemoteException e) { Log.e(TAG, "", e); } finally { mServiceLock.writeLock().unlock(); } mManagerService = Objects.requireNonNull(managerService); mAttributionSource = Objects.requireNonNull(attributionSource); synchronized (mServiceLock.writeLock()) { mService = getBluetoothService(mManagerCallback); } mLeScanClients = new HashMap<LeScanCallback, ScanCallback>(); mToken = new Binder(DESCRIPTOR); } Loading Loading @@ -3171,21 +3177,16 @@ public final class BluetoothAdapter { } } @SuppressLint("AndroidFrameworkBluetoothPermission") private final IBluetoothManagerCallback mManagerCallback = private static final IBluetoothManagerCallback sManagerCallback = new IBluetoothManagerCallback.Stub() { @SuppressLint("AndroidFrameworkRequiresPermission") public void onBluetoothServiceUp(IBluetooth bluetoothService) { if (DBG) { Log.d(TAG, "onBluetoothServiceUp: " + bluetoothService); } mServiceLock.writeLock().lock(); mService = bluetoothService; mServiceLock.writeLock().unlock(); synchronized (mProxyServiceStateCallbacks) { for (IBluetoothManagerCallback cb : mProxyServiceStateCallbacks) { synchronized (sServiceLock) { sService = bluetoothService; for (IBluetoothManagerCallback cb : sProxyServiceStateCallbacks.keySet()) { try { if (cb != null) { cb.onBluetoothServiceUp(bluetoothService); Loading @@ -3197,6 +3198,56 @@ public final class BluetoothAdapter { } } } } public void onBluetoothServiceDown() { if (DBG) { Log.d(TAG, "onBluetoothServiceDown"); } synchronized (sServiceLock) { sService = null; for (IBluetoothManagerCallback cb : sProxyServiceStateCallbacks.keySet()) { try { if (cb != null) { cb.onBluetoothServiceDown(); } else { Log.d(TAG, "onBluetoothServiceDown: cb is null!"); } } catch (Exception e) { Log.e(TAG, "", e); } } } } public void onBrEdrDown() { if (VDBG) { Log.i(TAG, "onBrEdrDown"); } synchronized (sServiceLock) { for (IBluetoothManagerCallback cb : sProxyServiceStateCallbacks.keySet()) { try { if (cb != null) { cb.onBrEdrDown(); } else { Log.d(TAG, "onBrEdrDown: cb is null!"); } } catch (Exception e) { Log.e(TAG, "", e); } } } } }; private final IBluetoothManagerCallback mManagerCallback = new IBluetoothManagerCallback.Stub() { public void onBluetoothServiceUp(IBluetooth bluetoothService) { synchronized (mServiceLock.writeLock()) { mService = bluetoothService; } synchronized (mMetadataListeners) { mMetadataListeners.forEach((device, pair) -> { try { Loading @@ -3221,12 +3272,7 @@ public final class BluetoothAdapter { } public void onBluetoothServiceDown() { if (DBG) { Log.d(TAG, "onBluetoothServiceDown: " + mService); } try { mServiceLock.writeLock().lock(); synchronized (mServiceLock.writeLock()) { mService = null; if (mLeScanClients != null) { mLeScanClients.clear(); Loading @@ -3237,29 +3283,10 @@ public final class BluetoothAdapter { if (mBluetoothLeScanner != null) { mBluetoothLeScanner.cleanup(); } } finally { mServiceLock.writeLock().unlock(); } synchronized (mProxyServiceStateCallbacks) { for (IBluetoothManagerCallback cb : mProxyServiceStateCallbacks) { try { if (cb != null) { cb.onBluetoothServiceDown(); } else { Log.d(TAG, "onBluetoothServiceDown: cb is null!"); } } catch (Exception e) { Log.e(TAG, "", e); } } } } public void onBrEdrDown() { if (VDBG) { Log.i(TAG, "onBrEdrDown: " + mService); } } }; Loading Loading @@ -3494,15 +3521,12 @@ public final class BluetoothAdapter { protected void finalize() throws Throwable { try { mManagerService.unregisterAdapter(mManagerCallback); } catch (RemoteException e) { Log.e(TAG, "", e); removeServiceStateCallback(mManagerCallback); } finally { super.finalize(); } } /** * Validate a String Bluetooth address, such as "00:43:A8:23:10:F0" * <p>Alphabetic characters must be uppercase to be valid. Loading Loading @@ -3566,24 +3590,64 @@ public final class BluetoothAdapter { return mAttributionSource; } private final ArrayList<IBluetoothManagerCallback> mProxyServiceStateCallbacks = new ArrayList<IBluetoothManagerCallback>(); @GuardedBy("sServiceLock") private static final WeakHashMap<IBluetoothManagerCallback, Void> sProxyServiceStateCallbacks = new WeakHashMap<>(); /*package*/ IBluetooth getBluetoothService() { synchronized (sServiceLock) { if (sProxyServiceStateCallbacks.isEmpty()) { throw new IllegalStateException( "Anonymous service access requires at least one lifecycle in process"); } return sService; } } @UnsupportedAppUsage /*package*/ IBluetooth getBluetoothService(IBluetoothManagerCallback cb) { synchronized (mProxyServiceStateCallbacks) { if (cb == null) { Log.w(TAG, "getBluetoothService() called with no BluetoothManagerCallback"); } else if (!mProxyServiceStateCallbacks.contains(cb)) { mProxyServiceStateCallbacks.add(cb); } Objects.requireNonNull(cb); synchronized (sServiceLock) { sProxyServiceStateCallbacks.put(cb, null); registerOrUnregisterAdapterLocked(); return sService; } return mService; } /*package*/ void removeServiceStateCallback(IBluetoothManagerCallback cb) { synchronized (mProxyServiceStateCallbacks) { mProxyServiceStateCallbacks.remove(cb); Objects.requireNonNull(cb); synchronized (sServiceLock) { sProxyServiceStateCallbacks.remove(cb); registerOrUnregisterAdapterLocked(); } } /** * Handle registering (or unregistering) a single process-wide * {@link IBluetoothManagerCallback} based on the presence of local * {@link #sProxyServiceStateCallbacks} clients. */ @GuardedBy("sServiceLock") private void registerOrUnregisterAdapterLocked() { final boolean isRegistered = sServiceRegistered; final boolean wantRegistered = !sProxyServiceStateCallbacks.isEmpty(); if (isRegistered != wantRegistered) { if (wantRegistered) { try { sService = mManagerService.registerAdapter(sManagerCallback); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } else { try { mManagerService.unregisterAdapter(sManagerCallback); sService = null; } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } sServiceRegistered = wantRegistered; } } Loading