diff options
52 files changed, 492 insertions, 223 deletions
diff --git a/apex/media/framework/Android.bp b/apex/media/framework/Android.bp index 1bf732ba33f2..d963e68d80ec 100644 --- a/apex/media/framework/Android.bp +++ b/apex/media/framework/Android.bp @@ -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", } diff --git a/apex/media/framework/api/system-current.txt b/apex/media/framework/api/system-current.txt index ce68447df051..6eea769d9f57 100644 --- a/apex/media/framework/api/system-current.txt +++ b/apex/media/framework/api/system-current.txt @@ -1,15 +1,15 @@ // 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(); @@ -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(); @@ -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 @@ -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); } } diff --git a/apex/media/framework/java/android/media/MediaFrameworkInitializer.java b/apex/media/framework/java/android/media/MediaFrameworkInitializer.java index de2924e160b6..75a56b7231d9 100644 --- a/apex/media/framework/java/android/media/MediaFrameworkInitializer.java +++ b/apex/media/framework/java/android/media/MediaFrameworkInitializer.java @@ -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( diff --git a/apex/media/framework/java/android/media/MediaTranscodeManager.java b/apex/media/framework/java/android/media/MediaTranscodingManager.java index 5742d43f83b7..93d58d07f81a 100644 --- a/apex/media/framework/java/android/media/MediaTranscodeManager.java +++ b/apex/media/framework/java/android/media/MediaTranscodingManager.java @@ -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. @@ -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 @@ -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; @@ -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) { @@ -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. @@ -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(); @@ -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; @@ -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, @@ -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. diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java index 8398be1af49a..5094498dbee5 100644 --- a/core/java/android/bluetooth/BluetoothAdapter.java +++ b/core/java/android/bluetooth/BluetoothAdapter.java @@ -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; @@ -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; @@ -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>>> @@ -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); } @@ -3154,21 +3160,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); @@ -3180,6 +3181,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 { @@ -3204,12 +3255,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(); @@ -3220,29 +3266,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); - } } }; @@ -3477,15 +3504,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. @@ -3549,24 +3573,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; } } diff --git a/core/java/android/bluetooth/BluetoothSocket.java b/core/java/android/bluetooth/BluetoothSocket.java index bb409d5360f9..1655b62bbfec 100644 --- a/core/java/android/bluetooth/BluetoothSocket.java +++ b/core/java/android/bluetooth/BluetoothSocket.java @@ -399,7 +399,7 @@ public final class BluetoothSocket implements Closeable { try { if (mSocketState == SocketState.CLOSED) throw new IOException("socket closed"); IBluetooth bluetoothProxy = - BluetoothAdapter.getDefaultAdapter().getBluetoothService(null); + BluetoothAdapter.getDefaultAdapter().getBluetoothService(); if (bluetoothProxy == null) throw new IOException("Bluetooth is off"); mPfd = bluetoothProxy.getSocketManager().connectSocket(mDevice, mType, mUuid, mPort, getSecurityFlags()); @@ -438,7 +438,7 @@ public final class BluetoothSocket implements Closeable { /*package*/ int bindListen() { int ret; if (mSocketState == SocketState.CLOSED) return EBADFD; - IBluetooth bluetoothProxy = BluetoothAdapter.getDefaultAdapter().getBluetoothService(null); + IBluetooth bluetoothProxy = BluetoothAdapter.getDefaultAdapter().getBluetoothService(); if (bluetoothProxy == null) { Log.e(TAG, "bindListen fail, reason: bluetooth is off"); return -1; @@ -706,7 +706,7 @@ public final class BluetoothSocket implements Closeable { throw new IOException("socket closed"); } IBluetooth bluetoothProxy = - BluetoothAdapter.getDefaultAdapter().getBluetoothService(null); + BluetoothAdapter.getDefaultAdapter().getBluetoothService(); if (bluetoothProxy == null) { throw new IOException("Bluetooth is off"); } diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java index c02dcfd3d681..27027721109d 100644 --- a/core/java/android/content/Context.java +++ b/core/java/android/content/Context.java @@ -4464,11 +4464,11 @@ public abstract class Context { /** * Use with {@link #getSystemService(String)} to retrieve a {@link - * android.media.MediaTranscodeManager} for transcoding media. + * android.media.MediaTranscodingManager} for transcoding media. * * @hide * @see #getSystemService(String) - * @see android.media.MediaTranscodeManager + * @see android.media.MediaTranscodingManager */ @SystemApi public static final String MEDIA_TRANSCODING_SERVICE = "media_transcoding"; diff --git a/core/java/android/hardware/camera2/CameraDevice.java b/core/java/android/hardware/camera2/CameraDevice.java index af48b71f9962..3c1ec3e629a9 100644 --- a/core/java/android/hardware/camera2/CameraDevice.java +++ b/core/java/android/hardware/camera2/CameraDevice.java @@ -807,6 +807,23 @@ public abstract class CameraDevice implements AutoCloseable { * The same logic applies to other hardware levels and capabilities. * </p> * + * <p> Devices with the ULTRA_HIGH_RESOLUTION_SENSOR capability have some additional guarantees + * which clients can take advantage of : </p> + * <table> + * <tr><th colspan="10">Additional guaranteed combinations for ULTRA_HIGH_RESOLUTION sensors</th></tr> + * <tr> <th colspan="3" id="rb">Target 1</th> <th colspan="3" id="rb">Target 2</th> <th colspan="3" id="rb">Target 3</th> <th rowspan="2">Sample use case(s)</th> </tr> + * <tr> <th>Type</th><th id="rb"> SC Map</th><th id="rb">Max size</th> <th>Type</th><th id="rb"> SC Map</th><th id="rb">Max size</th> <th>Type</th><th id="rb"> SC Map</th><th id="rb">Max size</th></tr> + * <tr> <td>{@code YUV / JPEG / RAW}</td><td id="rb">{@code MAX_RES}</td><td id="rb">{@code MAX}</td><td id="rb">{@code PRIV / YUV}</td><td id="rb">{@code DEFAULT}</td><td id="rb">{@code PREVIEW}</td><td colspan="3" id="rb"></td> <td>Ultra high res still image capture with preview</td> </tr> + * <tr> <td>{@code YUV / JPEG / RAW}</td><td id="rb">{@code MAX_RES}</td><td id="rb">{@code MAX}</td><td id="rb">{@code PRIV}</td><td id="rb">{@code DEFAULT}</td><td id="rb">{@code PREVIEW}</td><td id="rb">{@code PRIV / YUV}</td><td id="rb">{@code DEFAULT}</td><td id="rb">{@code RECORD}</td> <td>Ultra high res still capture with preview + app based RECORD size analysis</td> </tr> + * <tr> <td>{@code YUV / JPEG / RAW}</td><td id="rb">{@code MAX_RES}</td><td id="rb">{@code MAX}</td><td id="rb">{@code PRIV}</td><td id="rb">{@code DEFAULT}</td><td id="rb">{@code PREVIEW}</td><td id="rb">{@code JPEG / YUV / RAW}</td><td id="rb">{@code DEFAULT}</td><td id="rb">{@code MAX}</td> <td>Ultra high res still image capture with preview + default sensor pixel mode analysis stream</td> </tr> + * </table><br> + * + * <p> Here, SC Map, refers to the {@link StreamConfigurationMap}, the target stream sizes must + * be chosen from. {@code DEFAULT} refers to the default sensor pixel mode {@link + * StreamConfigurationMap} and {@code MAX_RES} refers to the maximum resolution {@link + * StreamConfigurationMap}. The same capture request must not mix targets from + * {@link StreamConfigurationMap}s corresponding to different sensor pixel modes. + * * <p>Since the capabilities of camera devices vary greatly, a given camera device may support * target combinations with sizes outside of these guarantees, but this can only be tested for * by calling {@link #isSessionConfigurationSupported} or attempting to create a session with @@ -989,6 +1006,16 @@ public abstract class CameraDevice implements AutoCloseable { * <tr> <td>{@code PRIV}</td><td id="rb">{@code MULTI_RES}</td> <td>{@code PRIV}</td><td id="rb">{@code MULTI_RES}</td> <td>{@code YUV}</td><td id="rb">{@code PREVIEW}</td> <td>{@code YUV}</td><td id="rb">{@code MULTI_RES}</td> <td></td><td id="rb"></td> <td>Maximum-resolution two-input ZSL in-app processing.</td> </tr> * <tr> <td>{@code PRIV}/{@code YUV}</td><td id="rb">{@code MULTI_RES}</td> <td>Same as input</td><td id="rb">{@code MULTI_RES}</td> <td>{@code PRIV}</td><td id="rb">{@code PREVIEW}</td> <td>{@code YUV}</td><td id="rb">{@code PREVIEW}</td> <td>{@code JPEG}</td><td id="rb">{@code MULTI_RES}</td> <td>ZSL still capture and in-app processing.</td> </tr> * </table><br> + * <p> Devices with the ULTRA_HIGH_RESOLUTION_SENSOR capability have some additional guarantees + * which clients can take advantage of : </p> + * <table> + * <tr><th colspan="13">Additional guaranteed combinations for ULTRA_HIGH_RESOLUTION sensors (YUV / PRIV inputs are guaranteed only if YUV / PRIVATE reprocessing are supported)</th></tr> + * <tr> <th colspan="3" id="rb">Input</th> <th colspan="3" id="rb">Target 1</th> <th colspan="3" id="rb">Target 2</th> <th colspan="3" id="rb">Target 3</th> <th rowspan="2">Sample use case(s)</th> </tr> + * <tr> <th>Type</th><th id="rb"> SC Map</th><th id="rb">Max size</th><th>Type</th><th id="rb"> SC Map</th><th id="rb">Max size</th> <th>Type</th><th id="rb"> SC Map</th><th id="rb">Max size</th> <th>Type</th><th id="rb"> SC Map</th><th id="rb">Max size</th></tr> + * <tr> <td>{@code RAW}</td><td id="rb">{@code MAX_RES}</td><td id="rb">{@code MAX}</td><td>{@code RAW}</td><td id="rb">{@code MAX_RES}</td><td id="rb">{@code MAX}</td><td id="rb">{@code PRIV / YUV}</td><td id="rb">{@code DEFAULT}</td><td id="rb">{@code PREVIEW}</td><td colspan="3" id="rb"></td> <td>RAW remosaic reprocessing with seperate preview</td> </tr> + * <tr> <td>{@code RAW}</td><td id="rb">{@code MAX_RES}</td><td id="rb">{@code MAX}</td><td>{@code RAW}</td><td id="rb">{@code MAX_RES}</td><td id="rb">{@code MAX}</td><td id="rb">{@code PRIV / YUV}</td><td id="rb">{@code DEFAULT}</td><td id="rb">{@code PREVIEW}</td><td id="rb">{@code JPEG / YUV}</td><td id="rb">{@code MAX_RES}</td><td id="rb">{@code MAX}</td> <td>Ultra high res RAW -> JPEG / YUV with seperate preview</td> </tr> + * <tr> <td>{@code YUV / PRIV}</td><td id="rb">{@code MAX_RES}</td><td id="rb">{@code MAX}</td> <td>{@code YUV / PRIV}</td><td id="rb">{@code MAX_RES}</td><td id="rb">{@code MAX}</td><td id="rb">{@code YUV / PRIV}</td><td id="rb">{@code DEFAULT}</td><td id="rb">{@code PREVIEW}</td><td id="rb">{@code JPEG }</td><td id="rb">{@code MAX_RES}</td><td id="rb">{@code MAX}</td> <td> Ultra high res PRIV / YUV -> YUV / JPEG reprocessing with seperate preview</td> </tr> + * </table><br> * No additional mandatory stream combinations for RAW capability and LEVEL-3 hardware level. * </p> * diff --git a/core/java/android/hardware/camera2/CameraMetadata.java b/core/java/android/hardware/camera2/CameraMetadata.java index d9fa56e1cbaa..4b35294826db 100644 --- a/core/java/android/hardware/camera2/CameraMetadata.java +++ b/core/java/android/hardware/camera2/CameraMetadata.java @@ -1138,10 +1138,14 @@ public abstract class CameraMetadata<TKey> { * <code>{@link CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP android.scaler.streamConfigurationMap}</code> describes the streams supported in 'default' * mode. * The stream configurations supported in 'max resolution' mode are described by - * <code>{@link CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP_MAXIMUM_RESOLUTION android.scaler.streamConfigurationMapMaximumResolution}</code>.</p> + * <code>{@link CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP_MAXIMUM_RESOLUTION android.scaler.streamConfigurationMapMaximumResolution}</code>. + * The maximum resolution mode pixel array size of a camera device + * (<code>{@link CameraCharacteristics#SENSOR_INFO_PIXEL_ARRAY_SIZE android.sensor.info.pixelArraySize}</code>) with this capability, + * will be at least 24 megapixels.</p> * * @see CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP * @see CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP_MAXIMUM_RESOLUTION + * @see CameraCharacteristics#SENSOR_INFO_PIXEL_ARRAY_SIZE * @see CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES */ public static final int REQUEST_AVAILABLE_CAPABILITIES_ULTRA_HIGH_RESOLUTION_SENSOR = 16; diff --git a/core/java/android/hardware/camera2/extension/IRequestProcessorImpl.aidl b/core/java/android/hardware/camera2/extension/IRequestProcessorImpl.aidl index 52595a8c5a2d..88b03a472c41 100644 --- a/core/java/android/hardware/camera2/extension/IRequestProcessorImpl.aidl +++ b/core/java/android/hardware/camera2/extension/IRequestProcessorImpl.aidl @@ -24,9 +24,9 @@ import android.hardware.camera2.extension.Request; interface IRequestProcessorImpl { void setImageProcessor(in OutputConfigId outputConfigId, in IImageProcessorImpl imageProcessor); - boolean submit(in Request request, in IRequestCallback callback); - boolean submitBurst(in List<Request> requests, in IRequestCallback callback); - boolean setRepeating(in Request request, in IRequestCallback callback); + int submit(in Request request, in IRequestCallback callback); + int submitBurst(in List<Request> requests, in IRequestCallback callback); + int setRepeating(in Request request, in IRequestCallback callback); void abortCaptures(); void stopRepeating(); } diff --git a/core/java/android/hardware/camera2/impl/CameraAdvancedExtensionSessionImpl.java b/core/java/android/hardware/camera2/impl/CameraAdvancedExtensionSessionImpl.java index 02245e49e611..8da6551f3d15 100644 --- a/core/java/android/hardware/camera2/impl/CameraAdvancedExtensionSessionImpl.java +++ b/core/java/android/hardware/camera2/impl/CameraAdvancedExtensionSessionImpl.java @@ -864,14 +864,15 @@ public final class CameraAdvancedExtensionSessionImpl extends CameraExtensionSes } @Override - public boolean submit(Request request, IRequestCallback callback) { + public int submit(Request request, IRequestCallback callback) { ArrayList<Request> captureList = new ArrayList<>(); captureList.add(request); return submitBurst(captureList, callback); } @Override - public boolean submitBurst(List<Request> requests, IRequestCallback callback) { + public int submitBurst(List<Request> requests, IRequestCallback callback) { + int seqId = -1; synchronized (mInterfaceLock) { try { CaptureCallbackHandler captureCallback = new CaptureCallbackHandler(callback); @@ -880,37 +881,36 @@ public final class CameraAdvancedExtensionSessionImpl extends CameraExtensionSes captureRequests.add(initializeCaptureRequest(mCameraDevice, request, mCameraConfigMap)); } - mCaptureSession.captureBurstRequests(captureRequests, + seqId = mCaptureSession.captureBurstRequests(captureRequests, new CameraExtensionUtils.HandlerExecutor(mHandler), captureCallback); } catch (CameraAccessException e) { Log.e(TAG, "Failed to submit capture requests!"); - return false; } catch (IllegalStateException e) { Log.e(TAG, "Capture session closed!"); } } - return true; + return seqId; } @Override - public boolean setRepeating(Request request, IRequestCallback callback) { + public int setRepeating(Request request, IRequestCallback callback) { + int seqId = -1; synchronized (mInterfaceLock) { try { CaptureRequest repeatingRequest = initializeCaptureRequest(mCameraDevice, request, mCameraConfigMap); CaptureCallbackHandler captureCallback = new CaptureCallbackHandler(callback); - mCaptureSession.setSingleRepeatingRequest(repeatingRequest, + seqId = mCaptureSession.setSingleRepeatingRequest(repeatingRequest, new CameraExtensionUtils.HandlerExecutor(mHandler), captureCallback); } catch (CameraAccessException e) { Log.e(TAG, "Failed to enable repeating request!"); - return false; } catch (IllegalStateException e) { Log.e(TAG, "Capture session closed!"); } } - return true; + return seqId; } @Override diff --git a/core/java/android/hardware/camera2/impl/CameraExtensionSessionImpl.java b/core/java/android/hardware/camera2/impl/CameraExtensionSessionImpl.java index ecd24914c566..71047af69b87 100644 --- a/core/java/android/hardware/camera2/impl/CameraExtensionSessionImpl.java +++ b/core/java/android/hardware/camera2/impl/CameraExtensionSessionImpl.java @@ -251,6 +251,7 @@ public final class CameraExtensionSessionImpl extends CameraExtensionSession { CameraExtensionCharacteristics.PROCESSING_INPUT_FORMAT); mPreviewImageProcessor.onResolutionUpdate(new Size(repeatingSurfaceInfo.mWidth, repeatingSurfaceInfo.mHeight)); + mPreviewImageProcessor.onOutputSurface(null, -1); mRepeatingRequestImageReader = ImageReader.newInstance(repeatingSurfaceInfo.mWidth, repeatingSurfaceInfo.mHeight, CameraExtensionCharacteristics.PROCESSING_INPUT_FORMAT, PREVIEW_QUEUE_SIZE, diff --git a/location/java/android/location/CorrelationVector.java b/location/java/android/location/CorrelationVector.java index 718977ff4296..5493e2579225 100644 --- a/location/java/android/location/CorrelationVector.java +++ b/location/java/android/location/CorrelationVector.java @@ -94,8 +94,6 @@ public final class CorrelationVector implements Parcelable { "FrequencyOffsetMetersPerSecond must be non-negative (greater than or equal to 0)"); Preconditions.checkArgument(builder.mSamplingWidthMeters > 0.0, "SamplingWidthMeters must be positive (greater than 0)"); - Preconditions.checkArgument(builder.mSamplingStartMeters >= 0.0, - "SamplingStartMeters must be non-negative (greater than or equal to 0)"); mMagnitude = builder.mMagnitude; mFrequencyOffsetMetersPerSecond = builder.mFrequencyOffsetMetersPerSecond; mSamplingWidthMeters = builder.mSamplingWidthMeters; diff --git a/packages/SettingsLib/BannerMessagePreference/res/values-v31/styles.xml b/packages/SettingsLib/BannerMessagePreference/res/values-v31/styles.xml index e74ac44ec8a4..fede44feb090 100644 --- a/packages/SettingsLib/BannerMessagePreference/res/values-v31/styles.xml +++ b/packages/SettingsLib/BannerMessagePreference/res/values-v31/styles.xml @@ -33,18 +33,18 @@ <style name="Banner.Title.SettingsLib" parent="@android:style/TextAppearance.Material.Subhead"> <item name="android:textSize">20sp</item> - <item name="android:fontFamily">@*android:string/config_headlineFontFamily</item> + <item name="android:fontFamily">@string/settingslib_config_headlineFontFamily</item> <item name="android:textColor">?android:attr/textColorPrimary</item> </style> <style name="Banner.Subtitle.SettingsLib" - parent="@*android:style/TextAppearance.DeviceDefault.Body1"> + parent="@android:style/TextAppearance.DeviceDefault"> <item name="android:textColor">?android:attr/textColorSecondary</item> <item name="android:textSize">14sp</item> </style> <style name="Banner.Summary.SettingsLib" - parent="@*android:style/TextAppearance.DeviceDefault.Body1"> + parent="@android:style/TextAppearance.DeviceDefault"> <item name="android:textColor">?android:attr/textColorSecondary</item> <item name="android:textSize">14sp</item> </style> @@ -58,4 +58,4 @@ parent="android:Widget.DeviceDefault.Button.Borderless.Colored"> <item name="android:textColor">?android:attr/colorAccent</item> </style> -</resources>
\ No newline at end of file +</resources> diff --git a/packages/SettingsLib/BannerMessagePreference/res/values/styles.xml b/packages/SettingsLib/BannerMessagePreference/res/values/styles.xml index df47c642e402..4c6ed58f4a58 100644 --- a/packages/SettingsLib/BannerMessagePreference/res/values/styles.xml +++ b/packages/SettingsLib/BannerMessagePreference/res/values/styles.xml @@ -17,14 +17,13 @@ <resources> <style name="Banner.Text.Title" - parent="@android:style/TextAppearance.Material.Subhead"> + parent="@android:style/TextAppearance.DeviceDefault.WindowTitle"> <item name="android:textSize">16sp</item> - <item name="android:fontFamily">@*android:string/config_headlineFontFamilyMedium</item> <item name="android:textColor">?android:attr/textColorPrimary</item> </style> <style name="Banner.Text.Summary" - parent="@*android:style/TextAppearance.DeviceDefault.Body1"> + parent="@android:style/TextAppearance.DeviceDefault"> <item name="android:textColor">?android:attr/textColorSecondary</item> <item name="android:textSize">14sp</item> </style> diff --git a/packages/SettingsLib/BarChartPreference/res/values/styles.xml b/packages/SettingsLib/BarChartPreference/res/values/styles.xml index 7a3fb7d9386e..d1f562b38760 100644 --- a/packages/SettingsLib/BarChartPreference/res/values/styles.xml +++ b/packages/SettingsLib/BarChartPreference/res/values/styles.xml @@ -85,9 +85,9 @@ </style> <style name="BarChart.Text" - parent="@android:style/TextAppearance.Material.Subhead"> - <item name="android:fontFamily">@*android:string/config_headlineFontFamilyMedium</item> + parent="@android:style/TextAppearance.DeviceDefault.WindowTitle"> <item name="android:textColor">?android:attr/textColorPrimary</item> + <item name="android:textSize">16sp</item> </style> <style name="BarChart.Text.HeaderTitle"> @@ -99,7 +99,7 @@ </style> <style name="BarChart.Text.Summary" - parent="@*android:style/TextAppearance.DeviceDefault.Body1"> + parent="@android:style/TextAppearance.DeviceDefault"> <item name="android:textColor">?android:attr/textColorSecondary</item> <item name="android:textSize">12sp</item> </style> diff --git a/packages/SettingsLib/CollapsingToolbarBaseActivity/Android.bp b/packages/SettingsLib/CollapsingToolbarBaseActivity/Android.bp index 2f911c4e6546..238e65ec9a3c 100644 --- a/packages/SettingsLib/CollapsingToolbarBaseActivity/Android.bp +++ b/packages/SettingsLib/CollapsingToolbarBaseActivity/Android.bp @@ -19,6 +19,7 @@ android_library { "com.google.android.material_material", "SettingsLibSettingsTransition", "SettingsLibUtils", + "SettingsLibSettingsTheme", ], sdk_version: "system_current", min_sdk_version: "29", diff --git a/packages/SettingsLib/CollapsingToolbarBaseActivity/res/layout-v31/collapsing_toolbar_base_layout.xml b/packages/SettingsLib/CollapsingToolbarBaseActivity/res/layout-v31/collapsing_toolbar_base_layout.xml index 59506564400b..907863e19972 100644 --- a/packages/SettingsLib/CollapsingToolbarBaseActivity/res/layout-v31/collapsing_toolbar_base_layout.xml +++ b/packages/SettingsLib/CollapsingToolbarBaseActivity/res/layout-v31/collapsing_toolbar_base_layout.xml @@ -16,7 +16,6 @@ --> <androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:androidprv="http://schemas.android.com/apk/prv/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/content_parent" android:layout_width="match_parent" @@ -40,7 +39,7 @@ android:clipToPadding="false" app:forceApplySystemWindowInsetTop="true" app:extraMultilineHeightEnabled="true" - app:contentScrim="?androidprv:attr/colorSurfaceHeader" + app:contentScrim="@color/settingslib_colorSurfaceHeader" app:maxLines="3" app:layout_scrollFlags="scroll|exitUntilCollapsed|snap" app:scrimAnimationDuration="50" diff --git a/packages/SettingsLib/CollapsingToolbarBaseActivity/res/values/themes.xml b/packages/SettingsLib/CollapsingToolbarBaseActivity/res/values-night-v31/themes.xml index 2e7a6a9181fe..c20beaf9bf93 100644 --- a/packages/SettingsLib/CollapsingToolbarBaseActivity/res/values/themes.xml +++ b/packages/SettingsLib/CollapsingToolbarBaseActivity/res/values-night-v31/themes.xml @@ -18,7 +18,7 @@ <style name="Theme.CollapsingToolbar.Settings" parent="@style/Theme.MaterialComponents.DayNight"> <item name="elevationOverlayEnabled">true</item> <item name="elevationOverlayColor">?attr/colorPrimary</item> - <item name="colorPrimary">@*android:color/primary_device_default_settings_light</item> - <item name="colorAccent">@*android:color/accent_device_default_light</item> + <item name="colorPrimary">@color/settingslib_primary_dark_device_default_settings</item> + <item name="colorAccent">@color/settingslib_accent_device_default_dark</item> </style> </resources>
\ No newline at end of file diff --git a/packages/SettingsLib/CollapsingToolbarBaseActivity/res/values/dimens.xml b/packages/SettingsLib/CollapsingToolbarBaseActivity/res/values-v31/dimens.xml index 15c1abbf97ba..15c1abbf97ba 100644 --- a/packages/SettingsLib/CollapsingToolbarBaseActivity/res/values/dimens.xml +++ b/packages/SettingsLib/CollapsingToolbarBaseActivity/res/values-v31/dimens.xml diff --git a/packages/SettingsLib/CollapsingToolbarBaseActivity/res/values/styles.xml b/packages/SettingsLib/CollapsingToolbarBaseActivity/res/values-v31/styles.xml index 63d397c69353..bda51b5160c8 100644 --- a/packages/SettingsLib/CollapsingToolbarBaseActivity/res/values/styles.xml +++ b/packages/SettingsLib/CollapsingToolbarBaseActivity/res/values-v31/styles.xml @@ -16,7 +16,7 @@ --> <resources> <style name="CollapsingToolbarTitle.Collapsed" parent="@android:style/TextAppearance.DeviceDefault.Widget.ActionBar.Title"> - <item name="android:fontFamily">@*android:string/config_headlineFontFamily</item> + <item name="android:fontFamily">@string/settingslib_config_headlineFontFamily</item> <item name="android:textSize">20dp</item> </style> diff --git a/packages/SettingsLib/CollapsingToolbarBaseActivity/res/values-night/themes.xml b/packages/SettingsLib/CollapsingToolbarBaseActivity/res/values-v31/themes.xml index 878275a08752..9ecc297c6d36 100644 --- a/packages/SettingsLib/CollapsingToolbarBaseActivity/res/values-night/themes.xml +++ b/packages/SettingsLib/CollapsingToolbarBaseActivity/res/values-v31/themes.xml @@ -18,7 +18,7 @@ <style name="Theme.CollapsingToolbar.Settings" parent="@style/Theme.MaterialComponents.DayNight"> <item name="elevationOverlayEnabled">true</item> <item name="elevationOverlayColor">?attr/colorPrimary</item> - <item name="colorPrimary">@*android:color/primary_dark_device_default_settings</item> - <item name="colorAccent">@*android:color/accent_device_default_dark</item> + <item name="colorPrimary">@color/settingslib_primary_device_default_settings_light</item> + <item name="colorAccent">@color/settingslib_accent_device_default_light</item> </style> </resources>
\ No newline at end of file diff --git a/packages/SettingsLib/FooterPreference/res/values/styles.xml b/packages/SettingsLib/FooterPreference/res/values/styles.xml index 08dd35991f69..5a3bada3e594 100644 --- a/packages/SettingsLib/FooterPreference/res/values/styles.xml +++ b/packages/SettingsLib/FooterPreference/res/values/styles.xml @@ -17,9 +17,8 @@ <resources> <style name="TextAppearance.Footer.Title.SettingsLib" - parent="@android:style/TextAppearance.DeviceDefault.Medium"> + parent="@android:style/TextAppearance.DeviceDefault.WindowTitle"> <item name="android:textSize">14sp</item> - <item name="android:fontFamily">@*android:string/config_headlineFontFamilyMedium</item> <item name="android:textColor">?android:attr/colorAccent</item> </style> </resources>
\ No newline at end of file diff --git a/packages/SettingsLib/LayoutPreference/res/values/styles.xml b/packages/SettingsLib/LayoutPreference/res/values/styles.xml index 4a99e845a5fc..2ffe6d91651b 100644 --- a/packages/SettingsLib/LayoutPreference/res/values/styles.xml +++ b/packages/SettingsLib/LayoutPreference/res/values/styles.xml @@ -24,14 +24,13 @@ </style> <style name="TextAppearance.EntityHeaderTitle" - parent="@android:style/TextAppearance.Material.Subhead"> - <item name="android:fontFamily">@*android:string/config_headlineFontFamilyMedium</item> + parent="@android:style/TextAppearance.DeviceDefault.WindowTitle"> <item name="android:textColor">?android:attr/textColorPrimary</item> <item name="android:textSize">20sp</item> </style> <style name="TextAppearance.EntityHeaderSummary" - parent="@*android:style/TextAppearance.DeviceDefault.Body1"> + parent="@android:style/TextAppearance.DeviceDefault"> <item name="android:textAlignment">viewStart</item> <item name="android:textColor">?android:attr/textColorSecondary</item> <item name="android:singleLine">true</item> diff --git a/packages/SettingsLib/MainSwitchPreference/res/drawable/settingslib_switch_bar_bg_disabled.xml b/packages/SettingsLib/MainSwitchPreference/res/drawable-v31/settingslib_switch_bar_bg_disabled.xml index 088e82bb4260..088e82bb4260 100644 --- a/packages/SettingsLib/MainSwitchPreference/res/drawable/settingslib_switch_bar_bg_disabled.xml +++ b/packages/SettingsLib/MainSwitchPreference/res/drawable-v31/settingslib_switch_bar_bg_disabled.xml diff --git a/packages/SettingsLib/MainSwitchPreference/res/drawable/settingslib_switch_bar_bg_off.xml b/packages/SettingsLib/MainSwitchPreference/res/drawable-v31/settingslib_switch_bar_bg_off.xml index 088e82bb4260..088e82bb4260 100644 --- a/packages/SettingsLib/MainSwitchPreference/res/drawable/settingslib_switch_bar_bg_off.xml +++ b/packages/SettingsLib/MainSwitchPreference/res/drawable-v31/settingslib_switch_bar_bg_off.xml diff --git a/packages/SettingsLib/MainSwitchPreference/res/drawable/settingslib_switch_bar_bg_on.xml b/packages/SettingsLib/MainSwitchPreference/res/drawable-v31/settingslib_switch_bar_bg_on.xml index 250188b892f4..250188b892f4 100644 --- a/packages/SettingsLib/MainSwitchPreference/res/drawable/settingslib_switch_bar_bg_on.xml +++ b/packages/SettingsLib/MainSwitchPreference/res/drawable-v31/settingslib_switch_bar_bg_on.xml diff --git a/packages/SettingsLib/MainSwitchPreference/res/layout-v31/settingslib_main_switch_bar.xml b/packages/SettingsLib/MainSwitchPreference/res/layout-v31/settingslib_main_switch_bar.xml index 6e5911cbf0a0..30748e6244cb 100644 --- a/packages/SettingsLib/MainSwitchPreference/res/layout-v31/settingslib_main_switch_bar.xml +++ b/packages/SettingsLib/MainSwitchPreference/res/layout-v31/settingslib_main_switch_bar.xml @@ -50,7 +50,7 @@ android:tint="?android:attr/colorAccent" android:layout_gravity="center_vertical" android:layout_marginEnd="@dimen/settingslib_restricted_icon_margin_end" - android:src="@*android:drawable/ic_info" + android:src="@android:drawable/ic_info" android:visibility="gone" /> <Switch diff --git a/packages/SettingsLib/MainSwitchPreference/res/layout/settingslib_main_switch_bar.xml b/packages/SettingsLib/MainSwitchPreference/res/layout/settingslib_main_switch_bar.xml index 306145a3e689..d0c2d0b5937d 100644 --- a/packages/SettingsLib/MainSwitchPreference/res/layout/settingslib_main_switch_bar.xml +++ b/packages/SettingsLib/MainSwitchPreference/res/layout/settingslib_main_switch_bar.xml @@ -28,7 +28,7 @@ android:layout_gravity="center_vertical" android:maxLines="2" android:ellipsize="end" - android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Widget.ActionBar.Title" + android:textAppearance="@android:style/TextAppearance.DeviceDefault.Widget.ActionBar.Title" android:textSize="16sp" android:textColor="?android:attr/textColorPrimaryInverse" android:layout_marginStart="@dimen/settingslib_switchbar_subsettings_margin_start" @@ -42,7 +42,7 @@ android:theme="@android:style/Theme.Material" android:layout_gravity="center_vertical" android:layout_marginEnd="@dimen/settingslib_restricted_icon_margin_end" - android:src="@*android:drawable/ic_info" + android:src="@android:drawable/ic_info" android:visibility="gone"/> <Switch diff --git a/packages/SettingsLib/MainSwitchPreference/res/values-v31/dimens.xml b/packages/SettingsLib/MainSwitchPreference/res/values-v31/dimens.xml new file mode 100644 index 000000000000..2272a375fb83 --- /dev/null +++ b/packages/SettingsLib/MainSwitchPreference/res/values-v31/dimens.xml @@ -0,0 +1,37 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright (C) 2021 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources> + + <!-- Size of layout margin --> + <dimen name="settingslib_switchbar_margin">16dp</dimen> + + <!-- Size of layout margin left --> + <dimen name="settingslib_switchbar_padding_left">24dp</dimen> + + <!-- Size of layout margin right --> + <dimen name="settingslib_switchbar_padding_right">16dp</dimen> + + <!-- Minimum width of switch --> + <dimen name="settingslib_min_switch_width">52dp</dimen> + + <!-- Minimum width of switch bar --> + <dimen name="settingslib_min_switch_bar_height">72dp</dimen> + + <!-- Radius of switch bar --> + <dimen name="settingslib_switch_bar_radius">28dp</dimen> +</resources> diff --git a/packages/SettingsLib/MainSwitchPreference/res/values-v31/styles.xml b/packages/SettingsLib/MainSwitchPreference/res/values-v31/styles.xml new file mode 100644 index 000000000000..a50fc7cc0028 --- /dev/null +++ b/packages/SettingsLib/MainSwitchPreference/res/values-v31/styles.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright (C) 2021 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources> + + <style name="MainSwitchText.Settingslib" parent="@android:style/TextAppearance.DeviceDefault.Widget.ActionBar.Title"> + <item name="android:textSize">20sp</item> + <item name="android:fontFamily">@string/settingslib_config_headlineFontFamily</item> + <item name="android:textColor">@android:color/black</item> + </style> +</resources> diff --git a/packages/SettingsLib/MainSwitchPreference/res/values/dimens.xml b/packages/SettingsLib/MainSwitchPreference/res/values/dimens.xml index 16b8af6a2dab..6362882e2332 100644 --- a/packages/SettingsLib/MainSwitchPreference/res/values/dimens.xml +++ b/packages/SettingsLib/MainSwitchPreference/res/values/dimens.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8"?> <!-- - Copyright (C) 2020 The Android Open Source Project + Copyright (C) 2021 The Android Open Source Project Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -17,30 +17,12 @@ <resources> - <!-- Size of layout margin --> - <dimen name="settingslib_switchbar_margin">16dp</dimen> - - <!-- Size of layout margin left --> - <dimen name="settingslib_switchbar_padding_left">24dp</dimen> - - <!-- Size of layout margin right --> - <dimen name="settingslib_switchbar_padding_right">16dp</dimen> - - <!-- Minimum width of switch --> - <dimen name="settingslib_min_switch_width">52dp</dimen> - - <!-- Minimum width of switch bar --> - <dimen name="settingslib_min_switch_bar_height">72dp</dimen> - <!-- Restricted icon size in switch bar --> - <dimen name="settingslib_restricted_icon_size">@*android:dimen/config_restrictedIconSize</dimen> + <dimen name="settingslib_restricted_icon_size">@android:dimen/config_restrictedIconSize</dimen> <!-- Restricted icon in switch bar --> <dimen name="settingslib_restricted_icon_margin_end">16dp</dimen> - <!-- Radius of switch bar --> - <dimen name="settingslib_switch_bar_radius">28dp</dimen> - <!-- Size of title margin --> <dimen name="settingslib_switch_title_margin">16dp</dimen> diff --git a/packages/SettingsLib/MainSwitchPreference/res/values/styles.xml b/packages/SettingsLib/MainSwitchPreference/res/values/styles.xml index 3924e301a2d3..870812ae6caf 100644 --- a/packages/SettingsLib/MainSwitchPreference/res/values/styles.xml +++ b/packages/SettingsLib/MainSwitchPreference/res/values/styles.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8"?> <!-- - Copyright (C) 2020 The Android Open Source Project + Copyright (C) 2021 The Android Open Source Project Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -17,13 +17,6 @@ <resources> - <style name="MainSwitchText.Settingslib" parent="@android:style/TextAppearance.DeviceDefault.Widget.ActionBar.Title"> - <item name="android:textSize">20sp</item> - <item name="android:fontFamily">@*android:string/config_headlineFontFamily</item> - <item name="android:textColor">@android:color/black</item> - </style> - - <style name="SwitchBar.Switch.Settingslib" parent="@android:style/Widget.Material.CompoundButton.Switch"> <item name="android:trackTint">@color/settingslib_switchbar_switch_track_tint</item> <item name="android:thumbTint">@color/settingslib_switchbar_switch_thumb_tint</item> diff --git a/packages/SettingsLib/SettingsTheme/res/color-v31/settingslib_surface_light.xml b/packages/SettingsLib/SettingsTheme/res/color-v31/settingslib_surface_light.xml new file mode 100644 index 000000000000..037b80abc6f9 --- /dev/null +++ b/packages/SettingsLib/SettingsTheme/res/color-v31/settingslib_surface_light.xml @@ -0,0 +1,18 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2021 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<selector xmlns:android="http://schemas.android.com/apk/res/android"> + <item android:color="@android:color/system_neutral1_500" android:lStar="98" /> +</selector>
\ No newline at end of file diff --git a/packages/SettingsLib/SettingsTheme/res/values-night-v31/colors.xml b/packages/SettingsLib/SettingsTheme/res/values-night-v31/colors.xml index 8c7c7ed5b120..e8fd4b24b629 100644 --- a/packages/SettingsLib/SettingsTheme/res/values-night-v31/colors.xml +++ b/packages/SettingsLib/SettingsTheme/res/values-night-v31/colors.xml @@ -36,4 +36,9 @@ <color name="settingslib_dialog_colorError">#f28b82</color> <!-- Red 300 --> <color name="settingslib_colorSurfaceVariant">@android:color/system_neutral1_700</color> + + <color name="settingslib_colorSurfaceHeader">@android:color/system_neutral1_700</color> + + <!-- copy from accent_primary_variant_dark_device_default--> + <color name="settingslib_accent_primary_variant">@android:color/system_accent1_300</color> </resources>
\ No newline at end of file diff --git a/packages/SettingsLib/SettingsTheme/res/values-v31/colors.xml b/packages/SettingsLib/SettingsTheme/res/values-v31/colors.xml index 77f1bcd17371..0f20ec326e74 100644 --- a/packages/SettingsLib/SettingsTheme/res/values-v31/colors.xml +++ b/packages/SettingsLib/SettingsTheme/res/values-v31/colors.xml @@ -37,9 +37,30 @@ <!-- Dialog accent color --> <color name="settingslib_dialog_accent">@android:color/system_accent1_600</color> <!-- Dialog background color --> - <color name="settingslib_dialog_background">@*android:color/surface_light</color> + <color name="settingslib_dialog_background">@color/settingslib_surface_light</color> <!-- Dialog error color. --> <color name="settingslib_dialog_colorError">#d93025</color> <!-- Red 600 --> <color name="settingslib_colorSurfaceVariant">@android:color/system_neutral2_100</color> + + <color name="settingslib_colorSurfaceHeader">@android:color/system_neutral1_100</color> + + <color name="settingslib_accent_device_default_dark">@android:color/system_accent1_100</color> + + <color name="settingslib_accent_device_default_light">@android:color/system_accent1_600</color> + + <color name="settingslib_primary_dark_device_default_settings">@android:color/system_neutral1_900</color> + + <color name="settingslib_primary_device_default_settings_light">@android:color/system_neutral1_50</color> + + <color name="settingslib_accent_primary_device_default">@android:color/system_accent1_100</color> + + <!-- copy from accent_primary_variant_light_device_default--> + <color name="settingslib_accent_primary_variant">@android:color/system_accent1_600</color> + + <color name="settingslib_accent_secondary_device_default">@android:color/system_accent2_100</color> + + <color name="settingslib_background_device_default_dark">@android:color/system_neutral1_900</color> + + <color name="settingslib_background_device_default_light">@android:color/system_neutral1_50</color> </resources> diff --git a/packages/SettingsLib/SettingsTheme/res/values-v31/dimens.xml b/packages/SettingsLib/SettingsTheme/res/values-v31/dimens.xml index ddcc83eee4bf..1c33f1a57ea5 100644 --- a/packages/SettingsLib/SettingsTheme/res/values-v31/dimens.xml +++ b/packages/SettingsLib/SettingsTheme/res/values-v31/dimens.xml @@ -19,4 +19,5 @@ <dimen name="app_preference_padding_start">20dp</dimen> <dimen name="app_icon_min_width">52dp</dimen> <dimen name="settingslib_preferred_minimum_touch_target">48dp</dimen> + <dimen name="settingslib_dialogCornerRadius">28dp</dimen> </resources> diff --git a/packages/SettingsLib/SettingsTheme/res/values-v31/strings.xml b/packages/SettingsLib/SettingsTheme/res/values-v31/strings.xml new file mode 100644 index 000000000000..6d072a936b15 --- /dev/null +++ b/packages/SettingsLib/SettingsTheme/res/values-v31/strings.xml @@ -0,0 +1,37 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2021 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <!-- Name of a font family to use for headlines in SettingsLib. --> + <string name="settingslib_config_headlineFontFamily" translatable="false"> + @*android:string/config_headlineFontFamily + </string> + + <!-- Name of a font family to use for headlines-medium in SettingsLib. --> + <string name="settingslib_config_headlineFontFamilyMedium" translatable="false"> + @*android:string/config_headlineFontFamilyMedium + </string> + + <!-- Name of a font family to use for body in SettingsLib. --> + <string name="settingslib_config_bodyFontFamily" translatable="false"> + @*android:string/config_bodyFontFamily + </string> + + <!-- Name of a font family to use for body-medium in SettingsLib. --> + <string name="settingslib_config_bodyFontFamilyMedium" translatable="false"> + @*android:string/config_bodyFontFamilyMedium + </string> +</resources> diff --git a/packages/SettingsLib/SettingsTheme/res/values-v31/styles.xml b/packages/SettingsLib/SettingsTheme/res/values-v31/styles.xml index 46f1e030af23..58006369988e 100644 --- a/packages/SettingsLib/SettingsTheme/res/values-v31/styles.xml +++ b/packages/SettingsLib/SettingsTheme/res/values-v31/styles.xml @@ -16,12 +16,16 @@ --> <resources> <style name="TextAppearance.PreferenceTitle.SettingsLib" - parent="@*android:style/TextAppearance.DeviceDefault.ListItem"> + parent="@android:style/TextAppearance.Material.Subhead"> + <item name="android:fontFamily">@string/settingslib_config_headlineFontFamily</item> <item name="android:textSize">20sp</item> </style> <style name="TextAppearance.CategoryTitle.SettingsLib" - parent="@*android:style/TextAppearance.DeviceDefault.Body2" /> + parent="@android:style/TextAppearance.DeviceDefault.Medium"> + <item name="android:textColor">?android:attr/textColorPrimary</item> + <item name="android:textSize">14sp</item> + </style> <style name="Switch.SettingsLib" parent="@android:style/Widget.Material.CompoundButton.Switch"> <item name="android:switchMinWidth">52dp</item> diff --git a/packages/SettingsLib/SettingsTheme/res/values-v31/themes.xml b/packages/SettingsLib/SettingsTheme/res/values-v31/themes.xml index 8034710b4341..6bf288b74d5a 100644 --- a/packages/SettingsLib/SettingsTheme/res/values-v31/themes.xml +++ b/packages/SettingsLib/SettingsTheme/res/values-v31/themes.xml @@ -50,6 +50,6 @@ <item name="android:clipToPadding">true</item> <item name="android:clipChildren">true</item> - <item name="dialogCornerRadius">@*android:dimen/config_dialogCornerRadius</item> + <item name="dialogCornerRadius">@dimen/settingslib_dialogCornerRadius</item> </style> </resources>
\ No newline at end of file diff --git a/packages/SettingsLib/SettingsTheme/res/values/dimens.xml b/packages/SettingsLib/SettingsTheme/res/values/dimens.xml index 25f9514c29b7..18af1f9c15d0 100644 --- a/packages/SettingsLib/SettingsTheme/res/values/dimens.xml +++ b/packages/SettingsLib/SettingsTheme/res/values/dimens.xml @@ -20,4 +20,5 @@ <dimen name="app_preference_padding_start">?android:attr/listPreferredItemPaddingStart</dimen> <dimen name="app_icon_min_width">56dp</dimen> <dimen name="two_target_min_width">72dp</dimen> + <dimen name="settingslib_dialogCornerRadius">8dp</dimen> </resources> diff --git a/packages/SettingsLib/SettingsTheme/res/values/themes.xml b/packages/SettingsLib/SettingsTheme/res/values/themes.xml index 6f2517746ddc..2d881d1a8a7b 100644 --- a/packages/SettingsLib/SettingsTheme/res/values/themes.xml +++ b/packages/SettingsLib/SettingsTheme/res/values/themes.xml @@ -35,7 +35,7 @@ <!-- TODO(b/189308264): fix the crash in Android R if set the attributes: <item name="colorAccent">@*android:color/accent_device_default_light</item> <item name="android:colorBackground">@color/settingslib_dialog_background</item> - <item name="dialogCornerRadius">@*android:dimen/config_dialogCornerRadius</item> + <item name="dialogCornerRadius">@dimen/settingslib_dialogCornerRadius</item> --> <item name="android:windowSoftInputMode">adjustResize</item> <item name="android:clipToPadding">true</item> diff --git a/packages/SettingsLib/TopIntroPreference/res/values/styles.xml b/packages/SettingsLib/TopIntroPreference/res/values/styles.xml index 65869b5580b5..b6ca41fb6b6d 100644 --- a/packages/SettingsLib/TopIntroPreference/res/values/styles.xml +++ b/packages/SettingsLib/TopIntroPreference/res/values/styles.xml @@ -16,8 +16,7 @@ --> <resources> <style name="TextAppearance.TopIntroText" - parent="@*android:style/TextAppearance.DeviceDefault"> - <item name="android:fontFamily">@*android:string/config_bodyFontFamily</item> + parent="@android:style/TextAppearance.DeviceDefault"> <item name="android:textSize">14sp</item> <item name="android:textColor">?android:attr/textColorSecondary</item> </style> diff --git a/packages/SettingsLib/src/com/android/settingslib/enterprise/BiometricActionDisabledByAdminController.java b/packages/SettingsLib/src/com/android/settingslib/enterprise/BiometricActionDisabledByAdminController.java index e0339dacf5ac..d205eaab6656 100644 --- a/packages/SettingsLib/src/com/android/settingslib/enterprise/BiometricActionDisabledByAdminController.java +++ b/packages/SettingsLib/src/com/android/settingslib/enterprise/BiometricActionDisabledByAdminController.java @@ -65,7 +65,6 @@ public class BiometricActionDisabledByAdminController extends BaseActionDisabled Log.d(TAG, "Positive button clicked, component: " + enforcedAdmin.component); final Intent intent = new Intent(ACTION_LEARN_MORE) .putExtra(EXTRA_SETTING_KEY, EXTRA_SETTING_VALUE) - .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) .setPackage(enforcedAdmin.component.getPackageName()); context.startActivity(intent); }; diff --git a/packages/services/CameraExtensionsProxy/src/com/android/cameraextensions/CameraExtensionsProxyService.java b/packages/services/CameraExtensionsProxy/src/com/android/cameraextensions/CameraExtensionsProxyService.java index 561d079cb984..b0893cc360b7 100644 --- a/packages/services/CameraExtensionsProxy/src/com/android/cameraextensions/CameraExtensionsProxyService.java +++ b/packages/services/CameraExtensionsProxy/src/com/android/cameraextensions/CameraExtensionsProxyService.java @@ -970,14 +970,14 @@ public class CameraExtensionsProxyService extends Service { } @Override - public boolean submit(Request request, Callback callback) { + public int submit(Request request, Callback callback) { ArrayList<Request> requests = new ArrayList<>(); requests.add(request); return submit(requests, callback); } @Override - public boolean submit(List<Request> requests, Callback callback) { + public int submit(List<Request> requests, Callback callback) { ArrayList<android.hardware.camera2.extension.Request> captureRequests = new ArrayList<>(); int requestId = 0; @@ -992,11 +992,11 @@ public class CameraExtensionsProxyService extends Service { } catch (RemoteException e) { Log.e(TAG, "Failed to submit request due to remote exception!"); } - return false; + return -1; } @Override - public boolean setRepeating(Request request, Callback callback) { + public int setRepeating(Request request, Callback callback) { try { ArrayList<Request> requests = new ArrayList<>(); requests.add(request); @@ -1007,7 +1007,7 @@ public class CameraExtensionsProxyService extends Service { Log.e(TAG, "Failed to submit repeating request due to remote exception!"); } - return false; + return -1; } @Override diff --git a/services/core/java/com/android/server/SensorPrivacyService.java b/services/core/java/com/android/server/SensorPrivacyService.java index 422e8ae14862..91b2440f71fe 100644 --- a/services/core/java/com/android/server/SensorPrivacyService.java +++ b/services/core/java/com/android/server/SensorPrivacyService.java @@ -1021,7 +1021,15 @@ public final class SensorPrivacyService extends SystemService { } } - return upgradeAndInit(version, map); + try { + return upgradeAndInit(version, map); + } catch (Exception e) { + Log.wtf(TAG, "Failed to upgrade and set sensor privacy state," + + " resetting to default.", e); + mEnabled = new SparseBooleanArray(); + mIndividualEnabled = new SparseArray<>(); + return true; + } } private boolean upgradeAndInit(int version, SparseArray map) { @@ -1037,22 +1045,22 @@ public final class SensorPrivacyService extends SystemService { final int[] users = getLocalService(UserManagerInternal.class).getUserIds(); if (version == 0) { final boolean enabled = (boolean) map.get(VER0_ENABLED); - final SparseBooleanArray individualEnabled = - (SparseBooleanArray) map.get(VER0_INDIVIDUAL_ENABLED); + final SparseArray<SensorState> individualEnabled = + (SparseArray<SensorState>) map.get(VER0_INDIVIDUAL_ENABLED); final SparseBooleanArray perUserEnabled = new SparseBooleanArray(); - final SparseArray<SparseBooleanArray> perUserIndividualEnabled = + final SparseArray<SparseArray<SensorState>> perUserIndividualEnabled = new SparseArray<>(); // Copy global state to each user for (int i = 0; i < users.length; i++) { int user = users[i]; perUserEnabled.put(user, enabled); - SparseBooleanArray userIndividualSensorEnabled = new SparseBooleanArray(); + SparseArray<SensorState> userIndividualSensorEnabled = new SparseArray<>(); perUserIndividualEnabled.put(user, userIndividualSensorEnabled); for (int j = 0; j < individualEnabled.size(); j++) { final int sensor = individualEnabled.keyAt(j); - final boolean isSensorEnabled = individualEnabled.valueAt(j); + final SensorState isSensorEnabled = individualEnabled.valueAt(j); userIndividualSensorEnabled.put(sensor, isSensorEnabled); } } diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java index f41036cde433..a2fec2753340 100644 --- a/services/core/java/com/android/server/am/ActiveServices.java +++ b/services/core/java/com/android/server/am/ActiveServices.java @@ -6314,10 +6314,17 @@ public final class ActiveServices { final String msg = "Background started FGS: " + ((r.mAllowStartForeground != REASON_DENIED) ? "Allowed " : "Disallowed ") + r.mInfoAllowStartForeground; - Slog.wtfQuiet(TAG, msg); if (r.mAllowStartForeground != REASON_DENIED) { + if (ActivityManagerUtils.shouldSamplePackageForAtom(r.packageName, + mAm.mConstants.mFgsStartAllowedLogSampleRate)) { + Slog.wtfQuiet(TAG, msg); + } Slog.i(TAG, msg); } else { + if (ActivityManagerUtils.shouldSamplePackageForAtom(r.packageName, + mAm.mConstants.mFgsStartDeniedLogSampleRate)) { + Slog.wtfQuiet(TAG, msg); + } Slog.w(TAG, msg); } r.mLoggedInfoAllowStartForeground = true; diff --git a/services/core/java/com/android/server/am/ActivityManagerConstants.java b/services/core/java/com/android/server/am/ActivityManagerConstants.java index ac0a1985ac89..eeb41a3df969 100644 --- a/services/core/java/com/android/server/am/ActivityManagerConstants.java +++ b/services/core/java/com/android/server/am/ActivityManagerConstants.java @@ -108,6 +108,8 @@ final class ActivityManagerConstants extends ContentObserver { static final String KEY_FG_TO_BG_FGS_GRACE_DURATION = "fg_to_bg_fgs_grace_duration"; static final String KEY_FGS_START_FOREGROUND_TIMEOUT = "fgs_start_foreground_timeout"; static final String KEY_FGS_ATOM_SAMPLE_RATE = "fgs_atom_sample_rate"; + static final String KEY_FGS_START_ALLOWED_LOG_SAMPLE_RATE = "fgs_start_allowed_log_sample_rate"; + static final String KEY_FGS_START_DENIED_LOG_SAMPLE_RATE = "fgs_start_denied_log_sample_rate"; static final String KEY_FGS_ALLOW_OPT_OUT = "fgs_allow_opt_out"; private static final int DEFAULT_MAX_CACHED_PROCESSES = 32; @@ -152,6 +154,8 @@ final class ActivityManagerConstants extends ContentObserver { private static final long DEFAULT_FG_TO_BG_FGS_GRACE_DURATION = 5 * 1000; private static final int DEFAULT_FGS_START_FOREGROUND_TIMEOUT_MS = 10 * 1000; private static final float DEFAULT_FGS_ATOM_SAMPLE_RATE = 1; // 100 % + private static final float DEFAULT_FGS_START_ALLOWED_LOG_SAMPLE_RATE = 0.25f; // 25% + private static final float DEFAULT_FGS_START_DENIED_LOG_SAMPLE_RATE = 1; // 100% /** * Same as {@link TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_NOT_ALLOWED} */ @@ -496,6 +500,20 @@ final class ActivityManagerConstants extends ContentObserver { volatile float mFgsAtomSampleRate = DEFAULT_FGS_ATOM_SAMPLE_RATE; /** + * Sample rate for the allowed FGS start WTF logs. + * + * If the value is 0.1, 10% of the logs would be sampled. + */ + volatile float mFgsStartAllowedLogSampleRate = DEFAULT_FGS_START_ALLOWED_LOG_SAMPLE_RATE; + + /** + * Sample rate for the denied FGS start WTF logs. + * + * If the value is 0.1, 10% of the logs would be sampled. + */ + volatile float mFgsStartDeniedLogSampleRate = DEFAULT_FGS_START_DENIED_LOG_SAMPLE_RATE; + + /** * Whether to allow "opt-out" from the foreground service restrictions. * (https://developer.android.com/about/versions/12/foreground-services) */ @@ -711,6 +729,12 @@ final class ActivityManagerConstants extends ContentObserver { case KEY_FGS_ATOM_SAMPLE_RATE: updateFgsAtomSamplePercent(); break; + case KEY_FGS_START_ALLOWED_LOG_SAMPLE_RATE: + updateFgsStartAllowedLogSamplePercent(); + break; + case KEY_FGS_START_DENIED_LOG_SAMPLE_RATE: + updateFgsStartDeniedLogSamplePercent(); + break; case KEY_FGS_ALLOW_OPT_OUT: updateFgsAllowOptOut(); break; @@ -1057,6 +1081,20 @@ final class ActivityManagerConstants extends ContentObserver { DEFAULT_FGS_ATOM_SAMPLE_RATE); } + private void updateFgsStartAllowedLogSamplePercent() { + mFgsStartAllowedLogSampleRate = DeviceConfig.getFloat( + DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, + KEY_FGS_START_ALLOWED_LOG_SAMPLE_RATE, + DEFAULT_FGS_START_ALLOWED_LOG_SAMPLE_RATE); + } + + private void updateFgsStartDeniedLogSamplePercent() { + mFgsStartDeniedLogSampleRate = DeviceConfig.getFloat( + DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, + KEY_FGS_START_DENIED_LOG_SAMPLE_RATE, + DEFAULT_FGS_START_DENIED_LOG_SAMPLE_RATE); + } + private void updateFgsAllowOptOut() { mFgsAllowOptOut = DeviceConfig.getBoolean( DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, @@ -1285,6 +1323,10 @@ final class ActivityManagerConstants extends ContentObserver { pw.print("="); pw.println(mFgsStartRestrictionCheckCallerTargetSdk); pw.print(" "); pw.print(KEY_FGS_ATOM_SAMPLE_RATE); pw.print("="); pw.println(mFgsAtomSampleRate); + pw.print(" "); pw.print(KEY_FGS_START_ALLOWED_LOG_SAMPLE_RATE); + pw.print("="); pw.println(mFgsStartAllowedLogSampleRate); + pw.print(" "); pw.print(KEY_FGS_START_DENIED_LOG_SAMPLE_RATE); + pw.print("="); pw.println(mFgsStartDeniedLogSampleRate); pw.print(" "); pw.print(KEY_PUSH_MESSAGING_OVER_QUOTA_BEHAVIOR); pw.print("="); pw.println(mPushMessagingOverQuotaBehavior); pw.print(" "); pw.print(KEY_FGS_ALLOW_OPT_OUT); diff --git a/services/core/java/com/android/server/powerstats/PowerStatsDataStorage.java b/services/core/java/com/android/server/powerstats/PowerStatsDataStorage.java index 2a95416747a6..06253a08d937 100644 --- a/services/core/java/com/android/server/powerstats/PowerStatsDataStorage.java +++ b/services/core/java/com/android/server/powerstats/PowerStatsDataStorage.java @@ -124,12 +124,8 @@ public class PowerStatsDataStorage { @Override public void read(InputStream in) throws IOException { while (in.available() > 0) { - try { - DataElement dataElement = new DataElement(in); - mCallback.onReadDataElement(dataElement.getData()); - } catch (IOException e) { - Slog.e(TAG, "Failed to read from storage. " + e.getMessage()); - } + DataElement dataElement = new DataElement(in); + mCallback.onReadDataElement(dataElement.getData()); } } } diff --git a/services/tests/mockingservicestests/assets/SensorPrivacyServiceMockingTest/persisted_file6.xml b/services/tests/mockingservicestests/assets/SensorPrivacyServiceMockingTest/persisted_file6.xml new file mode 100644 index 000000000000..b3c142285c8a --- /dev/null +++ b/services/tests/mockingservicestests/assets/SensorPrivacyServiceMockingTest/persisted_file6.xml @@ -0,0 +1,3 @@ +<?xml version='1.0' encoding='UTF-8' standalone='yes' ?> +<sensor-privacy enabled="false"> +</sensor-privacy> diff --git a/services/tests/mockingservicestests/src/com/android/server/sensorprivacy/SensorPrivacyServiceMockingTest.java b/services/tests/mockingservicestests/src/com/android/server/sensorprivacy/SensorPrivacyServiceMockingTest.java index 844687f34555..ba79a764b672 100644 --- a/services/tests/mockingservicestests/src/com/android/server/sensorprivacy/SensorPrivacyServiceMockingTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/sensorprivacy/SensorPrivacyServiceMockingTest.java @@ -60,6 +60,8 @@ public class SensorPrivacyServiceMockingTest { String.format(PERSISTENCE_FILE_PATHS_TEMPLATE, 4); public static final String PERSISTENCE_FILE5 = String.format(PERSISTENCE_FILE_PATHS_TEMPLATE, 5); + public static final String PERSISTENCE_FILE6 = + String.format(PERSISTENCE_FILE_PATHS_TEMPLATE, 6); private Context mContext; @Mock @@ -111,6 +113,7 @@ public class SensorPrivacyServiceMockingTest { initServiceWithPersistenceFile(onDeviceFile, PERSISTENCE_FILE3); initServiceWithPersistenceFile(onDeviceFile, PERSISTENCE_FILE4); initServiceWithPersistenceFile(onDeviceFile, PERSISTENCE_FILE5); + initServiceWithPersistenceFile(onDeviceFile, PERSISTENCE_FILE6); // Try all files with two known users doReturn(new int[]{0, 10}).when(mMockedUserManagerInternal).getUserIds(); @@ -124,6 +127,7 @@ public class SensorPrivacyServiceMockingTest { initServiceWithPersistenceFile(onDeviceFile, PERSISTENCE_FILE3); initServiceWithPersistenceFile(onDeviceFile, PERSISTENCE_FILE4); initServiceWithPersistenceFile(onDeviceFile, PERSISTENCE_FILE5); + initServiceWithPersistenceFile(onDeviceFile, PERSISTENCE_FILE6); } finally { mockitoSession.finishMocking(); diff --git a/services/usb/java/com/android/server/usb/UsbUserPermissionManager.java b/services/usb/java/com/android/server/usb/UsbUserPermissionManager.java index 5874b4b9fd3e..7b6ccd31adcc 100644 --- a/services/usb/java/com/android/server/usb/UsbUserPermissionManager.java +++ b/services/usb/java/com/android/server/usb/UsbUserPermissionManager.java @@ -25,12 +25,12 @@ import android.content.Context; import android.content.Intent; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; +import android.hardware.SensorPrivacyManager.Sensors; +import android.hardware.SensorPrivacyManagerInternal; import android.hardware.usb.AccessoryFilter; import android.hardware.usb.DeviceFilter; import android.hardware.usb.UsbAccessory; -import android.hardware.usb.UsbConstants; import android.hardware.usb.UsbDevice; -import android.hardware.usb.UsbInterface; import android.hardware.usb.UsbManager; import android.os.AsyncTask; import android.os.Binder; @@ -52,9 +52,9 @@ import android.util.TypedXmlSerializer; import android.util.Xml; import com.android.internal.annotations.GuardedBy; -import com.android.internal.util.FastXmlSerializer; import com.android.internal.util.XmlUtils; import com.android.internal.util.dump.DualDumpOutputStream; +import com.android.server.LocalServices; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; @@ -64,7 +64,6 @@ import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; -import java.nio.charset.StandardCharsets; /** * UsbUserPermissionManager manages usb device or accessory access permissions. @@ -110,19 +109,20 @@ class UsbUserPermissionManager { */ @GuardedBy("mLock") private boolean mIsCopyPermissionsScheduled; + private final SensorPrivacyManagerInternal mSensorPrivacyMgrInternal; UsbUserPermissionManager(@NonNull Context context, @NonNull UsbUserSettingsManager usbUserSettingsManager) { mContext = context; mUser = context.getUser(); mUsbUserSettingsManager = usbUserSettingsManager; + mSensorPrivacyMgrInternal = LocalServices.getService(SensorPrivacyManagerInternal.class); mDisablePermissionDialogs = context.getResources().getBoolean( com.android.internal.R.bool.config_disableUsbPermissionDialogs); mPermissionsFile = new AtomicFile(new File( Environment.getUserSystemDirectory(mUser.getIdentifier()), "usb_permissions.xml"), "usb-permissions"); - synchronized (mLock) { readPermissionsLocked(); } @@ -195,11 +195,27 @@ class UsbUserPermissionManager { */ boolean hasPermission(@NonNull UsbDevice device, @NonNull String packageName, int pid, int uid) { - if (isCameraDevicePresent(device)) { - if (!isCameraPermissionGranted(packageName, pid, uid)) { + if (device.getHasVideoCapture()) { + boolean isCameraPrivacyEnabled = mSensorPrivacyMgrInternal.isSensorPrivacyEnabled( + UserHandle.getUserId(uid), Sensors.CAMERA); + if (DEBUG) { + Slog.d(TAG, "isCameraPrivacyEnabled: " + isCameraPrivacyEnabled); + } + if (isCameraPrivacyEnabled || !isCameraPermissionGranted(packageName, pid, uid)) { return false; } } + // Only check for microphone privacy and not RECORD_AUDIO permission, because access to usb + // camera device with audio recording capabilities may still be granted with a warning + if (device.getHasAudioCapture() && mSensorPrivacyMgrInternal.isSensorPrivacyEnabled( + UserHandle.getUserId(uid), Sensors.MICROPHONE)) { + if (DEBUG) { + Slog.d(TAG, + "Access to device with audio recording capabilities denied because " + + "microphone privacy is enabled."); + } + return false; + } synchronized (mLock) { if (uid == Process.SYSTEM_UID || mDisablePermissionDialogs) { return true; @@ -698,7 +714,10 @@ class UsbUserPermissionManager { } return; } - if (isCameraDevicePresent(device)) { + // If the app doesn't have camera permission do not request permission to the USB device. + // Note that if the USB camera also has a microphone, a warning will be shown to the user if + // the app doesn't have RECORD_AUDIO permission. + if (device.getHasVideoCapture()) { if (!isCameraPermissionGranted(packageName, pid, uid)) { intent.putExtra(UsbManager.EXTRA_DEVICE, device); intent.putExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false); @@ -733,27 +752,4 @@ class UsbUserPermissionManager { requestPermissionDialog(null, accessory, mUsbUserSettingsManager.canBeDefault(accessory, packageName), packageName, pi, uid); } - - /** - * Check whether a particular device or any of its interfaces - * is of class VIDEO. - * - * @param device The device that needs to get scanned - * @return True in case a VIDEO device or interface is present, - * False otherwise. - */ - private boolean isCameraDevicePresent(UsbDevice device) { - if (device.getDeviceClass() == UsbConstants.USB_CLASS_VIDEO) { - return true; - } - - for (int i = 0; i < device.getInterfaceCount(); i++) { - UsbInterface iface = device.getInterface(i); - if (iface.getInterfaceClass() == UsbConstants.USB_CLASS_VIDEO) { - return true; - } - } - - return false; - } } |