Merge "Merge SP1A.210812.016" into stage-aosp-master
diff --git a/apex/media/framework/Android.bp b/apex/media/framework/Android.bp
index 1bf732b..d963e68 100644
--- a/apex/media/framework/Android.bp
+++ b/apex/media/framework/Android.bp
@@ -120,7 +120,7 @@
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 ce68447..6eea769 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 @@
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 @@
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 @@
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 de2924e..75a56b72 100644
--- a/apex/media/framework/java/android/media/MediaFrameworkInitializer.java
+++ b/apex/media/framework/java/android/media/MediaFrameworkInitializer.java
@@ -75,8 +75,8 @@
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
similarity index 98%
rename from apex/media/framework/java/android/media/MediaTranscodeManager.java
rename to apex/media/framework/java/android/media/MediaTranscodingManager.java
index 5742d43..93d58d0 100644
--- a/apex/media/framework/java/android/media/MediaTranscodeManager.java
+++ b/apex/media/framework/java/android/media/MediaTranscodingManager.java
@@ -54,7 +54,7 @@
/**
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 @@
<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 @@
*/
@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 @@
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 @@
}
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 @@
/**
* @hide
*/
- public MediaTranscodeManager(@NonNull Context context) {
+ public MediaTranscodingManager(@NonNull Context context) {
mContext = context;
mContentResolver = mContext.getContentResolver();
mPackageName = mContext.getPackageName();
@@ -1348,7 +1348,7 @@
@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 @@
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 @@
/**
* 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 1c96b8b..77abbe9 100644
--- a/core/java/android/bluetooth/BluetoothAdapter.java
+++ b/core/java/android/bluetooth/BluetoothAdapter.java
@@ -64,6 +64,8 @@
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.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 @@
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 @@
* 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);
}
@@ -3171,21 +3177,16 @@
}
}
- @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);
@@ -3197,6 +3198,56 @@
}
}
}
+ }
+
+ 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 {
@@ -3221,12 +3272,7 @@
}
public void onBluetoothServiceDown() {
- if (DBG) {
- Log.d(TAG, "onBluetoothServiceDown: " + mService);
- }
-
- try {
- mServiceLock.writeLock().lock();
+ synchronized (mServiceLock.writeLock()) {
mService = null;
if (mLeScanClients != null) {
mLeScanClients.clear();
@@ -3237,29 +3283,10 @@
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);
- }
}
};
@@ -3494,15 +3521,12 @@
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.
@@ -3566,24 +3590,64 @@
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 bb409d5..1655b62 100644
--- a/core/java/android/bluetooth/BluetoothSocket.java
+++ b/core/java/android/bluetooth/BluetoothSocket.java
@@ -399,7 +399,7 @@
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 @@
/*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 @@
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 c02dcfd..2702772 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -4464,11 +4464,11 @@
/**
* 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 af48b71..3c1ec3e 100644
--- a/core/java/android/hardware/camera2/CameraDevice.java
+++ b/core/java/android/hardware/camera2/CameraDevice.java
@@ -807,6 +807,23 @@
* 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 @@
* <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 d9fa56e..4b35294 100644
--- a/core/java/android/hardware/camera2/CameraMetadata.java
+++ b/core/java/android/hardware/camera2/CameraMetadata.java
@@ -1138,10 +1138,14 @@
* <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 52595a8..88b03a47 100644
--- a/core/java/android/hardware/camera2/extension/IRequestProcessorImpl.aidl
+++ b/core/java/android/hardware/camera2/extension/IRequestProcessorImpl.aidl
@@ -24,9 +24,9 @@
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 02245e4..8da6551 100644
--- a/core/java/android/hardware/camera2/impl/CameraAdvancedExtensionSessionImpl.java
+++ b/core/java/android/hardware/camera2/impl/CameraAdvancedExtensionSessionImpl.java
@@ -864,14 +864,15 @@
}
@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 @@
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 ecd2491..71047af 100644
--- a/core/java/android/hardware/camera2/impl/CameraExtensionSessionImpl.java
+++ b/core/java/android/hardware/camera2/impl/CameraExtensionSessionImpl.java
@@ -251,6 +251,7 @@
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/core/java/android/hardware/face/FaceManager.java b/core/java/android/hardware/face/FaceManager.java
index 3c3ba59..385ad2d 100644
--- a/core/java/android/hardware/face/FaceManager.java
+++ b/core/java/android/hardware/face/FaceManager.java
@@ -790,6 +790,11 @@
}
}
}
+
+ // This is used as a last resort in case a vendor string is missing
+ // It should not happen for anything other than FACE_ERROR_VENDOR, but
+ // warn and use the default if all else fails.
+ // TODO(b/196639965): update string
Slog.w(TAG, "Invalid error message: " + errMsg + ", " + vendorCode);
return "";
}
diff --git a/core/java/android/hardware/fingerprint/FingerprintManager.java b/core/java/android/hardware/fingerprint/FingerprintManager.java
index dc1a50f..87d45b9 100644
--- a/core/java/android/hardware/fingerprint/FingerprintManager.java
+++ b/core/java/android/hardware/fingerprint/FingerprintManager.java
@@ -1386,8 +1386,13 @@
}
}
}
+
+ // This is used as a last resort in case a vendor string is missing
+ // It should not happen for anything other than FINGERPRINT_ERROR_VENDOR, but
+ // warn and use the default if all else fails.
+ // TODO(b/196639965): update string
Slog.w(TAG, "Invalid error message: " + errMsg + ", " + vendorCode);
- return null;
+ return "";
}
/**
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index ca6e735..f5c1bcf 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -11857,6 +11857,15 @@
if (text != null) {
if (expandedTopChar > 0 || expandedBottomChar < text.length()) {
+ // Cap the offsets to avoid an OOB exception. That can happen if the
+ // displayed/layout text, on which these offsets are calculated, is longer
+ // than the original text (such as when the view is translated by the
+ // platform intelligence).
+ // TODO(b/196433694): Figure out how to better handle the offset
+ // calculations for this case (so we don't unnecessarily cutoff the original
+ // text, for example).
+ expandedTopChar = Math.min(expandedTopChar, text.length());
+ expandedBottomChar = Math.min(expandedBottomChar, text.length());
text = text.subSequence(expandedTopChar, expandedBottomChar);
}
diff --git a/core/java/com/android/ims/internal/uce/common/CapInfo.java b/core/java/com/android/ims/internal/uce/common/CapInfo.java
index bca647a..f5c4b1f 100644
--- a/core/java/com/android/ims/internal/uce/common/CapInfo.java
+++ b/core/java/com/android/ims/internal/uce/common/CapInfo.java
@@ -20,6 +20,10 @@
import android.os.Build;
import android.os.Parcel;
import android.os.Parcelable;
+import android.os.Bundle;
+
+import java.util.Map;
+import java.util.HashMap;
/** Class for capability discovery information.
* @hide */
@@ -88,6 +92,95 @@
/** Time used to compute when to query again. */
private long mCapTimestamp = 0;
+ private Map<String, String> mCapInfoMap = new HashMap<String, String>();
+
+ /** IM session feature tag key. */
+ public static final String INSTANT_MSG =
+ "+g.3gpp.iari-ref=\"urn%3Aurn-7%3A3gpp-application.ims.iari.rcse.im\"";
+ /** File transfer feature tag key. */
+ public static final String FILE_TRANSFER =
+ "+g.3gpp.iari-ref=\"urn%3Aurn-7%3A3gpp-application.ims.iari.rcse.ft\"";
+ /** File transfer Thumbnail feature tag key. */
+ public static final String FILE_TRANSFER_THUMBNAIL =
+ "+g.3gpp.iari-ref=\"urn%3Aurn-7%3A3gpp-application.ims.iari.rcs.ftthumb\"";
+ /** File transfer Store and forward feature tag key. */
+ public static final String FILE_TRANSFER_SNF =
+ "+g.3gpp.iari-ref=\"urn%3Aurn-7%3A3gpp-application.ims.iari.rcs.ftstandfw\"";
+ /** File transfer HTTP feature tag key. */
+ public static final String FILE_TRANSFER_HTTP =
+ "+g.3gpp.iari-ref=\"urn%3Aurn-7%3A3gpp-application.ims.iari.rcs.fthttp\"";
+ /** Image sharing feature tag key. */
+ public static final String IMAGE_SHARE =
+ "+g.3gpp.iari-ref=\"urn%3Aurn-7%3A3gpp-application.ims.iari.gsma-is\"";
+ /** Video sharing during a CS call feature tag key-- IR-74. */
+ public static final String VIDEO_SHARE_DURING_CS = "+g.3gpp.cs-voice";
+ /** Video sharing outside of voice call feature tag key-- IR-84. */
+ public static final String VIDEO_SHARE =
+ "+g.3gpp.iari-ref=\"urn%3Aurn-7%3A3gpp-application.ims.iari.gsma-vs\"";
+ /** Social presence feature tag key. */
+ public static final String SOCIAL_PRESENCE =
+ "+g.3gpp.iari-ref=\"urn%3Aurn-7%3A3gpp-application.ims.iari.rcse.sp\"";
+ /** Presence discovery feature tag key. */
+ public static final String CAPDISC_VIA_PRESENCE =
+ "+g.3gpp.iari-ref=\"urn%3Aurn-7%3A3gpp-application.ims.iari.rcse.dp\"";
+ /** IP voice call feature tag key (IR-92/IR-58). */
+ public static final String IP_VOICE =
+ "+g.3gpp.icsi-ref=\"urn%3Aurn-7%3A3gpp-service.ims.icsi.mmtel\"";
+ /** IP video call feature tag key (IR-92/IR-58). */
+ public static final String IP_VIDEO =
+ "+g.3gpp.icsi-ref=\"urn%3Aurn-7%3A3gpp-service.ims.icsi.mmtel\";video";
+ /** IP Geo location Pull using File Transfer feature tag key. */
+ public static final String GEOPULL_FT =
+ "+g.3gpp.iari-ref=\"urn%3Aurn-7%3A3gpp-application.ims.iari.rcs.geopullft\"";
+ /** IP Geo location Pull feature tag key. */
+ public static final String GEOPULL =
+ "+g.3gpp.iari-ref=\"urn%3Aurn-7%3A3gpp-application.ims.iari.rcs.geopull\"";
+ /** IP Geo location Push feature tag key. */
+ public static final String GEOPUSH =
+ "+g.3gpp.iari-ref=\"urn%3Aurn-7%3A3gpp-application.ims.iari.rcs.geopush\"";
+ /** Standalone messaging feature tag key. */
+ public static final String STANDALONE_MSG =
+ "+g.3gpp.icsi-ref=\"urn%3Aurn-7%3A3gpp-service.ims.icsi.oma.cpm.msg;" +
+ "urn%3Aurn-7%3A3gpp-service.ims.icsi.oma.cpm.largemsg\"";
+ /** Full Store and Forward Group Chat information feature tag key. */
+ public static final String FULL_SNF_GROUPCHAT =
+ "+g.3gpp.iari-ref=\"urn%3Aurn-7%3A3gpp-application.ims.iari.rcs.fullsfgroupchat\"";
+ /** RCS IP Voice call feature tag key. */
+ public static final String RCS_IP_VOICE_CALL =
+ "+g.gsma.rcs.ipcall";
+ /** RCS IP Video call feature tag key. */
+ public static final String RCS_IP_VIDEO_CALL =
+ "+g.gsma.rcs.ipvideocall";
+ /** RCS IP Video only call feature tag key. */
+ public static final String RCS_IP_VIDEO_ONLY_CALL =
+ "+g.gsma.rcs.ipvideoonlycall";
+ /** IP Geo location Push using SMS feature tag key. */
+ public static final String GEOSMS =
+ "+g.3gpp.iari-ref=\"urn%3Aurn-7%3A3gppapplication.ims.iari.rcs.geosms\"";
+ /** RCS call composer feature tag key. */
+ public static final String CALLCOMPOSER =
+ "+g.3gpp.icsi-ref=\"urn%3Aurn-7%3A3gppservice.ims.icsi.gsma.callcomposer\"";
+ /** RCS post-call feature tag key. */
+ public static final String POSTCALL =
+ "+g.3gpp.icsi-ref=\"urn%3Aurn-7%3A3gppservice.ims.icsi.gsma.callunanswered\"";
+ /** Shared map feature tag key. */
+ public static final String SHAREDMAP =
+ "+g.3gpp.icsi-ref=\"urn%3Aurn-7%3A3gppservice.ims.icsi.gsma.sharedmap\"";
+ /** Shared Sketch feature tag key. */
+ public static final String SHAREDSKETCH =
+ "+g.3gpp.icsi-ref=\"urn%3Aurn-7%3A3gppservice.ims.icsi.gsma.sharedsketch\"";
+ /** Chatbot communication feature tag key. */
+ public static final String CHATBOT =
+ "+g.3gpp.iari-ref=\"urn%3Aurn-7%3A3gppapplication.ims.iari.rcs.chatbot\"";
+ /** Chatbot role feature tag key. */
+ public static final String CHATBOTROLE = "+g.gsma.rcs.isbot";
+ /** Standalone Chatbot communication feature tag key. */
+ public static final String STANDALONE_CHATBOT =
+ "+g.3gpp.iari-ref=\"urn%3Aurn-7%3A3gpp-application.ims.iari.rcs.chatbot.sa\"";
+ /** MMtel based call composer feature tag key. */
+ public static final String MMTEL_CALLCOMPOSER = "+g.gsma.callcomposer";
+
+
/**
* Constructor for the CapInfo class.
@@ -99,6 +192,7 @@
/**
* Checks whether IM is supported.
+ * @deprecated Use {@link #isCapabilitySupported(String)} instead.
*/
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
public boolean isImSupported() {
@@ -107,6 +201,7 @@
/**
* Sets IM as supported or not supported.
+ * @deprecated Use {@link #addCapability(String, String)} instead.
*/
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
public void setImSupported(boolean imSupported) {
@@ -115,6 +210,7 @@
/**
* Checks whether FT Thumbnail is supported.
+ * @deprecated Use {@link #isCapabilitySupported(String)} instead.
*/
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
public boolean isFtThumbSupported() {
@@ -123,16 +219,16 @@
/**
* Sets FT thumbnail as supported or not supported.
+ * @deprecated Use {@link #addCapability(String, String)} instead.
*/
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
public void setFtThumbSupported(boolean ftThumbSupported) {
this.mFtThumbSupported = ftThumbSupported;
}
-
-
/**
* Checks whether FT Store and Forward is supported
+ * @deprecated Use {@link #isCapabilitySupported(String)} instead.
*/
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
public boolean isFtSnFSupported() {
@@ -141,6 +237,7 @@
/**
* Sets FT Store and Forward as supported or not supported.
+ * @deprecated Use {@link #addCapability(String, String)} instead.
*/
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
public void setFtSnFSupported(boolean ftSnFSupported) {
@@ -149,6 +246,7 @@
/**
* Checks whether File transfer HTTP is supported.
+ * @deprecated Use {@link #isCapabilitySupported(String)} instead.
*/
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
public boolean isFtHttpSupported() {
@@ -157,6 +255,7 @@
/**
* Sets File transfer HTTP as supported or not supported.
+ * @deprecated Use {@link #addCapability(String, String)} instead.
*/
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
public void setFtHttpSupported(boolean ftHttpSupported) {
@@ -165,6 +264,7 @@
/**
* Checks whether FT is supported.
+ * @deprecated Use {@link #isCapabilitySupported(String)} instead.
*/
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
public boolean isFtSupported() {
@@ -173,6 +273,7 @@
/**
* Sets FT as supported or not supported.
+ * @deprecated Use {@link #addCapability(String, String)} instead.
*/
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
public void setFtSupported(boolean ftSupported) {
@@ -181,6 +282,7 @@
/**
* Checks whether IS is supported.
+ * @deprecated Use {@link #isCapabilitySupported(String)} instead.
*/
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
public boolean isIsSupported() {
@@ -189,6 +291,7 @@
/**
* Sets IS as supported or not supported.
+ * @deprecated Use {@link #addCapability(String, String)} instead.
*/
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
public void setIsSupported(boolean isSupported) {
@@ -197,6 +300,7 @@
/**
* Checks whether video sharing is supported during a CS call.
+ * @deprecated Use {@link #isCapabilitySupported(String)} instead.
*/
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
public boolean isVsDuringCSSupported() {
@@ -204,8 +308,9 @@
}
/**
- * Sets video sharing as supported or not supported during a CS
- * call.
+ * Sets video sharing as supported or not supported during a CS
+ * call.
+ * @deprecated Use {@link #addCapability(String, String)} instead.
*/
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
public void setVsDuringCSSupported(boolean vsDuringCSSupported) {
@@ -213,8 +318,9 @@
}
/**
- * Checks whether video sharing outside a voice call is
- * supported.
+ * Checks whether video sharing outside a voice call is
+ * supported.
+ * @deprecated Use {@link #isCapabilitySupported(String)} instead.
*/
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
public boolean isVsSupported() {
@@ -223,6 +329,7 @@
/**
* Sets video sharing as supported or not supported.
+ * @deprecated Use {@link #addCapability(String, String)} instead.
*/
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
public void setVsSupported(boolean vsSupported) {
@@ -231,6 +338,7 @@
/**
* Checks whether social presence is supported.
+ * @deprecated Use {@link #isCapabilitySupported(String)} instead.
*/
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
public boolean isSpSupported() {
@@ -239,6 +347,7 @@
/**
* Sets social presence as supported or not supported.
+ * @deprecated Use {@link #addCapability(String, String)} instead.
*/
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
public void setSpSupported(boolean spSupported) {
@@ -248,6 +357,7 @@
/**
* Checks whether capability discovery via presence is
* supported.
+ * @deprecated Use {@link #isCapabilitySupported(String)} instead.
*/
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
public boolean isCdViaPresenceSupported() {
@@ -257,6 +367,7 @@
/**
* Sets capability discovery via presence as supported or not
* supported.
+ * @deprecated Use {@link #addCapability(String, String)} instead.
*/
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
public void setCdViaPresenceSupported(boolean cdViaPresenceSupported) {
@@ -265,6 +376,7 @@
/**
* Checks whether IP voice call is supported.
+ * @deprecated Use {@link #isCapabilitySupported(String)} instead.
*/
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
public boolean isIpVoiceSupported() {
@@ -273,6 +385,7 @@
/**
* Sets IP voice call as supported or not supported.
+ * @deprecated Use {@link #addCapability(String, String)} instead.
*/
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
public void setIpVoiceSupported(boolean ipVoiceSupported) {
@@ -281,6 +394,7 @@
/**
* Checks whether IP video call is supported.
+ * @deprecated Use {@link #isCapabilitySupported(String)} instead.
*/
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
public boolean isIpVideoSupported() {
@@ -289,6 +403,7 @@
/**
* Sets IP video call as supported or not supported.
+ * @deprecated Use {@link #addCapability(String, String)} instead.
*/
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
public void setIpVideoSupported(boolean ipVideoSupported) {
@@ -298,6 +413,7 @@
/**
* Checks whether Geo location Pull using File Transfer is
* supported.
+ * @deprecated Use {@link #isCapabilitySupported(String)} instead.
*/
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
public boolean isGeoPullFtSupported() {
@@ -307,6 +423,7 @@
/**
* Sets Geo location Pull using File Transfer as supported or
* not supported.
+ * @deprecated Use {@link #addCapability(String, String)} instead.
*/
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
public void setGeoPullFtSupported(boolean geoPullFtSupported) {
@@ -315,6 +432,7 @@
/**
* Checks whether Geo Pull is supported.
+ * @deprecated Use {@link #isCapabilitySupported(String)} instead.
*/
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
public boolean isGeoPullSupported() {
@@ -323,6 +441,7 @@
/**
* Sets Geo Pull as supported or not supported.
+ * @deprecated Use {@link #addCapability(String, String)} instead.
*/
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
public void setGeoPullSupported(boolean geoPullSupported) {
@@ -331,6 +450,7 @@
/**
* Checks whether Geo Push is supported.
+ * @deprecated Use {@link #isCapabilitySupported(String)} instead.
*/
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
public boolean isGeoPushSupported() {
@@ -339,6 +459,7 @@
/**
* Sets Geo Push as supported or not supported.
+ * @deprecated Use {@link #addCapability(String, String)} instead.
*/
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
public void setGeoPushSupported(boolean geoPushSupported) {
@@ -347,6 +468,7 @@
/**
* Checks whether short messaging is supported.
+ * @deprecated Use {@link #isCapabilitySupported(String)} instead.
*/
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
public boolean isSmSupported() {
@@ -355,6 +477,7 @@
/**
* Sets short messaging as supported or not supported.
+ * @deprecated Use {@link #addCapability(String, String)} instead.
*/
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
public void setSmSupported(boolean smSupported) {
@@ -363,22 +486,32 @@
/**
* Checks whether store/forward and group chat are supported.
+ * @deprecated Use {@link #isCapabilitySupported(String)} instead.
*/
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
public boolean isFullSnFGroupChatSupported() {
return mFullSnFGroupChatSupported;
}
+ /**
+ * @deprecated Use {@link #isCapabilitySupported(String)} instead.
+ */
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
public boolean isRcsIpVoiceCallSupported() {
return mRcsIpVoiceCallSupported;
}
+ /**
+ * @deprecated Use {@link #isCapabilitySupported(String)} instead.
+ */
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
public boolean isRcsIpVideoCallSupported() {
return mRcsIpVideoCallSupported;
}
+ /**
+ * @deprecated Use {@link #isCapabilitySupported(String)} instead.
+ */
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
public boolean isRcsIpVideoOnlyCallSupported() {
return mRcsIpVideoOnlyCallSupported;
@@ -386,20 +519,32 @@
/**
* Sets store/forward and group chat supported or not supported.
+ * @deprecated Use {@link #addCapability(String, String)} instead.
*/
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
public void setFullSnFGroupChatSupported(boolean fullSnFGroupChatSupported) {
this.mFullSnFGroupChatSupported = fullSnFGroupChatSupported;
}
+ /**
+ * @deprecated Use {@link #addCapability(String, String)} instead.
+ */
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
public void setRcsIpVoiceCallSupported(boolean rcsIpVoiceCallSupported) {
this.mRcsIpVoiceCallSupported = rcsIpVoiceCallSupported;
}
+
+ /**
+ * @deprecated Use {@link #addCapability(String, String)} instead.
+ */
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
public void setRcsIpVideoCallSupported(boolean rcsIpVideoCallSupported) {
this.mRcsIpVideoCallSupported = rcsIpVideoCallSupported;
}
+
+ /**
+ * @deprecated Use {@link #addCapability(String, String)} instead.
+ */
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
public void setRcsIpVideoOnlyCallSupported(boolean rcsIpVideoOnlyCallSupported) {
this.mRcsIpVideoOnlyCallSupported = rcsIpVideoOnlyCallSupported;
@@ -407,6 +552,7 @@
/**
* Checks whether Geo Push via SMS is supported.
+ * @deprecated Use {@link #isCapabilitySupported(String)} instead.
*/
public boolean isGeoSmsSupported() {
return mGeoSmsSupported;
@@ -414,6 +560,7 @@
/**
* Sets Geolocation Push via SMS as supported or not supported.
+ * @deprecated Use {@link #addCapability(String, String)} instead.
*/
public void setGeoSmsSupported(boolean geoSmsSupported) {
this.mGeoSmsSupported = geoSmsSupported;
@@ -421,6 +568,7 @@
/**
* Checks whether RCS call composer is supported.
+ * @deprecated Use {@link #isCapabilitySupported(String)} instead.
*/
public boolean isCallComposerSupported() {
return mCallComposerSupported;
@@ -428,6 +576,7 @@
/**
* Sets call composer as supported or not supported.
+ * @deprecated Use {@link #addCapability(String, String)} instead.
*/
public void setCallComposerSupported(boolean callComposerSupported) {
this.mCallComposerSupported = callComposerSupported;
@@ -435,6 +584,7 @@
/**
* Checks whether post call is supported.
+ * @deprecated Use {@link #isCapabilitySupported(String)} instead.
*/
public boolean isPostCallSupported(){
return mPostCallSupported;
@@ -442,13 +592,15 @@
/**
* Sets post call as supported or not supported.
+ * @deprecated Use {@link #addCapability(String, String)} instead.
*/
- public void setPostCallSupported(boolean postCallSupported) {
- this.mPostCallSupported = postCallSupported;
- }
+ public void setPostCallSupported(boolean postCallSupported) {
+ this.mPostCallSupported = postCallSupported;
+ }
/**
* Checks whether shared map is supported.
+ * @deprecated Use {@link #isCapabilitySupported(String)} instead.
*/
public boolean isSharedMapSupported() {
return mSharedMapSupported;
@@ -456,6 +608,7 @@
/**
* Sets shared map as supported or not supported.
+ * @deprecated Use {@link #addCapability(String, String)} instead.
*/
public void setSharedMapSupported(boolean sharedMapSupported) {
this.mSharedMapSupported = sharedMapSupported;
@@ -463,6 +616,7 @@
/**
* Checks whether shared sketch is supported.
+ * @deprecated Use {@link #isCapabilitySupported(String)} instead.
*/
public boolean isSharedSketchSupported() {
return mSharedSketchSupported;
@@ -470,6 +624,7 @@
/**
* Sets shared sketch as supported or not supported.
+ * @deprecated Use {@link #addCapability(String, String)} instead.
*/
public void setSharedSketchSupported(boolean sharedSketchSupported) {
this.mSharedSketchSupported = sharedSketchSupported;
@@ -477,6 +632,7 @@
/**
* Checks whether chatbot communication is supported.
+ * @deprecated Use {@link #isCapabilitySupported(String)} instead.
*/
public boolean isChatbotSupported() {
return mChatbotSupported;
@@ -484,6 +640,7 @@
/**
* Sets chatbot communication as supported or not supported.
+ * @deprecated Use {@link #addCapability(String, String)} instead.
*/
public void setChatbotSupported(boolean chatbotSupported) {
this.mChatbotSupported = chatbotSupported;
@@ -491,6 +648,7 @@
/**
* Checks whether chatbot role is supported.
+ * @deprecated Use {@link #isCapabilitySupported(String)} instead.
*/
public boolean isChatbotRoleSupported() {
return mChatbotRoleSupported;
@@ -498,6 +656,7 @@
/**
* Sets chatbot role as supported or not supported.
+ * @deprecated Use {@link #addCapability(String, String)} instead.
*/
public void setChatbotRoleSupported(boolean chatbotRoleSupported) {
this.mChatbotRoleSupported = chatbotRoleSupported;
@@ -505,6 +664,7 @@
/**
* Checks whether standalone chatbot communication is supported.
+ * @deprecated Use {@link #isCapabilitySupported(String)} instead.
*/
public boolean isSmChatbotSupported() {
return mSmChatbotSupported;
@@ -512,6 +672,7 @@
/**
* Sets standalone chatbot communication as supported or not supported.
+ * @deprecated Use {@link #addCapability(String, String)} instead.
*/
public void setSmChatbotSupported(boolean smChatbotSupported) {
this.mSmChatbotSupported = smChatbotSupported;
@@ -519,6 +680,7 @@
/**
* Checks whether Mmtel based call composer is supported.
+ * @deprecated Use {@link #isCapabilitySupported(String)} instead.
*/
public boolean isMmtelCallComposerSupported() {
return mMmtelCallComposerSupported;
@@ -526,6 +688,7 @@
/**
* Sets Mmtel based call composer as supported or not supported.
+ * @deprecated Use {@link #addCapability(String, String)} instead.
*/
public void setMmtelCallComposerSupported(boolean mmtelCallComposerSupported) {
this.mMmtelCallComposerSupported = mmtelCallComposerSupported;
@@ -555,6 +718,84 @@
this.mCapTimestamp = capTimestamp;
}
+ /**
+ * Adds the feature tag string with supported versions to
+ * the mCapInfoMap.
+ * Map<String featureType, String versions>
+ * Versions format:
+ * "+g.gsma.rcs.botversion=\"#=1" -> Version 1 supported
+ * "+g.gsma.rcs.botversion=\"#=1,#=2\"" -> Versions 1 and 2 are supported
+ *
+ * Example #1: Add standard feature tag with one version support
+ * addCapability(CapInfo.STANDALONE_CHATBOT, "+g.gsma.rcs.botversion=\"#=1");
+ * The above example indicates standalone chatbot feature tag is supported
+ * in version 1.
+ *
+ * Example #2: Add standard feature tag with multiple version support
+ * addCapability(CapInfo.CHATBOT, "+g.gsma.rcs.botversion=\"#=1,#=2\"");
+ * The above example indicates session based chatbot feature tag is supported
+ * in versions 1 and 2.
+ *
+ * Example #3: Add standard feature tag with no version support
+ * addCapability(CapInfo.INSTANT_MSG, "");
+ * The above example indicates im feature tag does not have version support.
+ *
+ * Example #4: Add custom/extension feature tag with no version support
+ * addCapability("+g.3gpp.iari-ref=\"urn%3Aurn-7%3A3gpp-application.ims.iari.rcse.custom_im\"",
+ * "");
+ * Call setNewFeatureTag(int presenceServiceHdl, String featureTag,
+ * in PresServiceInfo serviceInfo, int userData) API
+ * in IPresenceService.aidl before calling addCapability() API
+ */
+ public void addCapability(String featureTagName, String versions) {
+ this.mCapInfoMap.put(featureTagName, versions);
+ }
+
+ /**
+ * Returns String of versions of the feature tag passed.
+ * Returns "" if versioning support is not present for the feature tag passed.
+ * Returns null if feature tag is not present.
+ *
+ * Example # 1:
+ * getCapabilityVersions(CapInfo.STANDALONE_CHATBOT);
+ * The above returns String in this format "+g.gsma.rcs.botversion=\"#=1,#=2\"",
+ * indicating more than one versions are supported for standalone chatbot feature tag
+ *
+ * Example # 2:
+ * getCapabilityVersions(CapInfo.INSTANT_MSG);
+ * The above returns empty String in this format "",
+ * indicating versions support is not present for im feature tag
+ *
+ * Example #3:
+ * getCapabilityVersions(
+ * "+g.3gpp.iari-ref=\"urn%3Aurn-7%3A3gpp-application.ims.iari.rcse.custom_im\");
+ * The above returns String "",
+ * indicating version supported is not present for the custom feature tag passed.
+ */
+ public String getCapabilityVersions(String featureTagName) {
+ return mCapInfoMap.get(featureTagName);
+ }
+
+ /** Removes the entry of the feature tag passed, from the Map. */
+ public void removeCapability(String featureTagName) {
+ this.mCapInfoMap.remove(featureTagName);
+ }
+
+ /** Sets Map of feature tag string and string of supported versions. */
+ public void setCapInfoMap(Map<String, String> capInfoMap) {
+ this.mCapInfoMap = capInfoMap;
+ }
+
+ /** Gets Map of feature tag string and string of supported versions. */
+ public Map<String, String> getCapInfoMap() {
+ return mCapInfoMap;
+ }
+
+ /** Checks whether the featureTag is supported or not. */
+ public boolean isCapabilitySupported(String featureTag) {
+ return mCapInfoMap.containsKey(featureTag);
+ }
+
public int describeContents() {
// TODO Auto-generated method stub
return 0;
@@ -594,6 +835,12 @@
dest.writeInt(mRcsIpVideoOnlyCallSupported ? 1 : 0);
dest.writeStringArray(mExts);
dest.writeLong(mCapTimestamp);
+
+ Bundle capInfoBundle = new Bundle();
+ for (Map.Entry<String, String> entry : mCapInfoMap.entrySet()) {
+ capInfoBundle.putString(entry.getKey(), entry.getValue());
+ }
+ dest.writeBundle(capInfoBundle);
}
public static final Parcelable.Creator<CapInfo> CREATOR = new Parcelable.Creator<CapInfo>() {
@@ -646,5 +893,10 @@
mExts = source.createStringArray();
mCapTimestamp = source.readLong();
+
+ Bundle capInfoBundle = source.readBundle();
+ for (String key: capInfoBundle.keySet()) {
+ mCapInfoMap.put(key, capInfoBundle.getString(key));
+ }
}
}
diff --git a/core/java/com/android/ims/internal/uce/options/OptionsSipResponse.java b/core/java/com/android/ims/internal/uce/options/OptionsSipResponse.java
index acea0f0..3242081 100644
--- a/core/java/com/android/ims/internal/uce/options/OptionsSipResponse.java
+++ b/core/java/com/android/ims/internal/uce/options/OptionsSipResponse.java
@@ -30,6 +30,7 @@
private int mSipResponseCode = 0;
private int mRetryAfter = 0;
private String mReasonPhrase = "";
+ private String mReasonHeader = "";
/**
* Gets the Options command ID.
@@ -117,6 +118,22 @@
}
/**
+ * Gets the reason header associated with the SIP response code.
+ * @hide
+ */
+ public String getReasonHeader() {
+ return mReasonHeader;
+ }
+
+ /**
+ * Sets the SIP response code reason phrase.
+ * @hide
+ */
+ public void setReasonHeader(String reasonHeader) {
+ this.mReasonHeader = reasonHeader;
+ }
+
+ /**
* Constructor for the OptionsSipResponse class.
* @hide
*/
@@ -138,6 +155,7 @@
dest.writeString(mReasonPhrase);
dest.writeParcelable(mCmdId, flags);
dest.writeInt(mRetryAfter);
+ dest.writeString(mReasonHeader);
}
/** @hide */
@@ -164,5 +182,6 @@
mReasonPhrase = source.readString();
mCmdId = source.readParcelable(OptionsCmdId.class.getClassLoader());
mRetryAfter = source.readInt();
+ mReasonHeader = source.readString();
}
}
diff --git a/core/java/com/android/ims/internal/uce/presence/PresSipResponse.java b/core/java/com/android/ims/internal/uce/presence/PresSipResponse.java
index 9549152..5e394ef 100644
--- a/core/java/com/android/ims/internal/uce/presence/PresSipResponse.java
+++ b/core/java/com/android/ims/internal/uce/presence/PresSipResponse.java
@@ -29,6 +29,7 @@
private int mSipResponseCode = 0;
private int mRetryAfter = 0;
private String mReasonPhrase = "";
+ private String mReasonHeader = "";
/**
* Gets the Presence command ID.
@@ -123,6 +124,23 @@
}
/**
+ * Gets the reason header associated with the SIP response
+ * code.
+ * @hide
+ */
+ public String getReasonHeader() {
+ return mReasonHeader;
+ }
+
+ /**
+ * Sets the SIP response code reason header.
+ * @hide
+ */
+ public void setReasonHeader(String reasonHeader) {
+ this.mReasonHeader = reasonHeader;
+ }
+
+ /**
* Constructor for the PresSipResponse class.
* @hide
*/
@@ -141,6 +159,7 @@
dest.writeString(mReasonPhrase);
dest.writeParcelable(mCmdId, flags);
dest.writeInt(mRetryAfter);
+ dest.writeString(mReasonHeader);
}
/** @hide */
@@ -168,5 +187,6 @@
mReasonPhrase = source.readString();
mCmdId = source.readParcelable(PresCmdId.class.getClassLoader());
mRetryAfter = source.readInt();
+ mReasonHeader = source.readString();
}
}
\ No newline at end of file
diff --git a/core/java/com/android/ims/internal/uce/presence/PresTupleInfo.java b/core/java/com/android/ims/internal/uce/presence/PresTupleInfo.java
index 34a7b1e..ce3d568 100644
--- a/core/java/com/android/ims/internal/uce/presence/PresTupleInfo.java
+++ b/core/java/com/android/ims/internal/uce/presence/PresTupleInfo.java
@@ -27,6 +27,7 @@
private String mFeatureTag = "";
private String mContactUri = "";
private String mTimestamp = "";
+ private String mVersion = "";
/**
@@ -80,6 +81,22 @@
}
/**
+ * Gets the version.
+ * @hide
+ */
+ public String getVersion() {
+ return mVersion;
+ }
+
+ /**
+ * Sets the version.
+ * @hide
+ */
+ public void setVersion(String version) {
+ this.mVersion = version;
+ }
+
+ /**
* Constructor for the PresTupleInfo class.
* @hide
*/
@@ -96,6 +113,7 @@
dest.writeString(mFeatureTag);
dest.writeString(mContactUri);
dest.writeString(mTimestamp);
+ dest.writeString(mVersion);
}
/** @hide */
@@ -121,5 +139,6 @@
mFeatureTag = source.readString();
mContactUri = source.readString();
mTimestamp = source.readString();
+ mVersion = source.readString();
}
}
\ No newline at end of file
diff --git a/core/res/res/values/colors.xml b/core/res/res/values/colors.xml
index 55ed83b..b191584 100644
--- a/core/res/res/values/colors.xml
+++ b/core/res/res/values/colors.xml
@@ -248,37 +248,37 @@
<color name="system_accent1_0">#ffffff</color>
<!-- Shade of the accent system color at 99% lightness.
This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_accent1_10">#F1FFFC</color>
+ <color name="system_accent1_10">#F9FCFF</color>
<!-- Shade of the accent system color at 95% lightness.
This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_accent1_50">#9CFFF2</color>
+ <color name="system_accent1_50">#E0F3FF</color>
<!-- Shade of the accent system color at 90% lightness.
This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_accent1_100">#8DF5E3</color>
+ <color name="system_accent1_100">#C1E8FF</color>
<!-- Shade of the accent system color at 80% lightness.
This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_accent1_200">#71D8C7</color>
+ <color name="system_accent1_200">#76D1FF</color>
<!-- Shade of the accent system color at 70% lightness.
This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_accent1_300">#53BCAC</color>
+ <color name="system_accent1_300">#4BB6E8</color>
<!-- Shade of the accent system color at 60% lightness.
This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_accent1_400">#34A192</color>
+ <color name="system_accent1_400">#219BCC</color>
<!-- Shade of the accent system color at 49% lightness.
This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_accent1_500">#008375</color>
+ <color name="system_accent1_500">#007FAC</color>
<!-- Shade of the accent system color at 40% lightness.
This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_accent1_600">#006C5F</color>
+ <color name="system_accent1_600">#00668B</color>
<!-- Shade of the accent system color at 30% lightness.
This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_accent1_700">#005747</color>
+ <color name="system_accent1_700">#004C69</color>
<!-- Shade of the accent system color at 20% lightness.
This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_accent1_800">#003E31</color>
+ <color name="system_accent1_800">#003549</color>
<!-- Shade of the accent system color at 10% lightness.
This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_accent1_900">#002214</color>
+ <color name="system_accent1_900">#001E2C</color>
<!-- Darkest shade of the accent color used by the system. Black.
This value can be overlaid at runtime by OverlayManager RROs. -->
<color name="system_accent1_1000">#000000</color>
@@ -288,37 +288,37 @@
<color name="system_accent2_0">#ffffff</color>
<!-- Shade of the secondary accent system color at 99% lightness.
This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_accent2_10">#F0FFFC</color>
+ <color name="system_accent2_10">#F9FCFF</color>
<!-- Shade of the secondary accent system color at 95% lightness.
This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_accent2_50">#CDFAF1</color>
+ <color name="system_accent2_50">#E0F3FF</color>
<!-- Shade of the secondary accent system color at 90% lightness.
This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_accent2_100">#BFEBE3</color>
+ <color name="system_accent2_100">#D1E5F4</color>
<!-- Shade of the secondary accent system color at 80% lightness.
This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_accent2_200">#A4CFC7</color>
+ <color name="system_accent2_200">#B5CAD7</color>
<!-- Shade of the secondary accent system color at 70% lightness.
This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_accent2_300">#89B4AC</color>
+ <color name="system_accent2_300">#9AAEBB</color>
<!-- Shade of the secondary accent system color at 60% lightness.
This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_accent2_400">#6F9991</color>
+ <color name="system_accent2_400">#8094A0</color>
<!-- Shade of the secondary accent system color at 49% lightness.
This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_accent2_500">#537C75</color>
+ <color name="system_accent2_500">#657985</color>
<!-- Shade of the secondary accent system color at 40% lightness.
This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_accent2_600">#3D665F</color>
+ <color name="system_accent2_600">#4E616C</color>
<!-- Shade of the secondary accent system color at 30% lightness.
This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_accent2_700">#254E47</color>
+ <color name="system_accent2_700">#374955</color>
<!-- Shade of the secondary accent system color at 20% lightness.
This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_accent2_800">#0C3731</color>
+ <color name="system_accent2_800">#20333D</color>
<!-- Shade of the secondary accent system color at 10% lightness.
This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_accent2_900">#00211C</color>
+ <color name="system_accent2_900">#091E28</color>
<!-- Darkest shade of the secondary accent color used by the system. Black.
This value can be overlaid at runtime by OverlayManager RROs. -->
<color name="system_accent2_1000">#000000</color>
@@ -331,34 +331,34 @@
<color name="system_accent3_10">#FFFBFF</color>
<!-- Shade of the tertiary accent system color at 95% lightness.
This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_accent3_50">#F9EAFF</color>
+ <color name="system_accent3_50">#F5EEFF</color>
<!-- Shade of the tertiary accent system color at 90% lightness.
This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_accent3_100">#ECDBFF</color>
+ <color name="system_accent3_100">#E6DEFF</color>
<!-- Shade of the tertiary accent system color at 80% lightness.
This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_accent3_200">#CFBFEB</color>
+ <color name="system_accent3_200">#CAC1EA</color>
<!-- Shade of the tertiary accent system color at 70% lightness.
This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_accent3_300">#B3A4CF</color>
+ <color name="system_accent3_300">#AEA6CE</color>
<!-- Shade of the tertiary accent system color at 60% lightness.
This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_accent3_400">#988AB3</color>
+ <color name="system_accent3_400">#938CB1</color>
<!-- Shade of the tertiary accent system color at 49% lightness.
This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_accent3_500">#7B6E96</color>
+ <color name="system_accent3_500">#787296</color>
<!-- Shade of the tertiary accent system color at 40% lightness.
This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_accent3_600">#64587F</color>
+ <color name="system_accent3_600">#605A7C</color>
<!-- Shade of the tertiary accent system color at 30% lightness.
This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_accent3_700">#4C4165</color>
+ <color name="system_accent3_700">#484264</color>
<!-- Shade of the tertiary accent system color at 20% lightness.
This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_accent3_800">#352B4D</color>
+ <color name="system_accent3_800">#322C4C</color>
<!-- Shade of the tertiary accent system color at 10% lightness.
This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_accent3_900">#1E1636</color>
+ <color name="system_accent3_900">#1D1736</color>
<!-- Darkest shade of the tertiary accent color used by the system. Black.
This value can be overlaid at runtime by OverlayManager RROs. -->
<color name="system_accent3_1000">#000000</color>
@@ -368,37 +368,37 @@
<color name="system_neutral1_0">#ffffff</color>
<!-- Shade of the neutral system color at 99% lightness.
This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_neutral1_10">#fbfbfb</color>
+ <color name="system_neutral1_10">#FCFCFF</color>
<!-- Shade of the neutral system color at 95% lightness.
This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_neutral1_50">#f0f0f0</color>
+ <color name="system_neutral1_50">#F0F0F3</color>
<!-- Shade of the neutral system color at 90% lightness.
This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_neutral1_100">#e2e2e2</color>
+ <color name="system_neutral1_100">#E1E3E5</color>
<!-- Shade of the neutral system color at 80% lightness.
This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_neutral1_200">#c6c6c6</color>
+ <color name="system_neutral1_200">#C5C7C9</color>
<!-- Shade of the neutral system color at 70% lightness.
This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_neutral1_300">#ababab</color>
+ <color name="system_neutral1_300">#AAABAE</color>
<!-- Shade of the neutral system color at 60% lightness.
This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_neutral1_400">#909090</color>
+ <color name="system_neutral1_400">#8F9193</color>
<!-- Shade of the neutral system color at 49% lightness.
This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_neutral1_500">#757575</color>
+ <color name="system_neutral1_500">#747679</color>
<!-- Shade of the neutral system color at 40% lightness.
This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_neutral1_600">#5e5e5e</color>
+ <color name="system_neutral1_600">#5C5F61</color>
<!-- Shade of the neutral system color at 30% lightness.
This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_neutral1_700">#464646</color>
+ <color name="system_neutral1_700">#454749</color>
<!-- Shade of the neutral system color at 20% lightness.
This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_neutral1_800">#303030</color>
+ <color name="system_neutral1_800">#2E3133</color>
<!-- Shade of the neutral system color at 10% lightness.
This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_neutral1_900">#1b1b1b</color>
+ <color name="system_neutral1_900">#191C1E</color>
<!-- Darkest shade of the neutral color used by the system. Black.
This value can be overlaid at runtime by OverlayManager RROs. -->
<color name="system_neutral1_1000">#000000</color>
@@ -408,37 +408,37 @@
<color name="system_neutral2_0">#ffffff</color>
<!-- Shade of the secondary neutral system color at 99% lightness.
This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_neutral2_10">#fbfbfb</color>
+ <color name="system_neutral2_10">#F9FCFF</color>
<!-- Shade of the secondary neutral system color at 95% lightness.
This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_neutral2_50">#f0f0f0</color>
+ <color name="system_neutral2_50">#EBF1F8</color>
<!-- Shade of the secondary neutral system color at 90% lightness.
This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_neutral2_100">#e2e2e2</color>
+ <color name="system_neutral2_100">#DCE3E9</color>
<!-- Shade of the secondary neutral system color at 80% lightness.
This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_neutral2_200">#c6c6c6</color>
+ <color name="system_neutral2_200">#C0C7CD</color>
<!-- Shade of the secondary neutral system color at 70% lightness.
This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_neutral2_300">#ababab</color>
+ <color name="system_neutral2_300">#A5ACB2</color>
<!-- Shade of the secondary neutral system color at 60% lightness.
This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_neutral2_400">#909090</color>
+ <color name="system_neutral2_400">#8A9297</color>
<!-- Shade of the secondary neutral system color at 49% lightness.
This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_neutral2_500">#757575</color>
+ <color name="system_neutral2_500">#70777C</color>
<!-- Shade of the secondary neutral system color at 40% lightness.
This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_neutral2_600">#5e5e5e</color>
+ <color name="system_neutral2_600">#585F65</color>
<!-- Shade of the secondary neutral system color at 30% lightness.
This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_neutral2_700">#464646</color>
+ <color name="system_neutral2_700">#40484D</color>
<!-- Shade of the secondary neutral system color at 20% lightness.
This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_neutral2_800">#303030</color>
+ <color name="system_neutral2_800">#2A3136</color>
<!-- Shade of the secondary neutral system color at 10% lightness.
This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_neutral2_900">#1b1b1b</color>
+ <color name="system_neutral2_900">#161C20</color>
<!-- Darkest shade of the secondary neutral color used by the system. Black.
This value can be overlaid at runtime by OverlayManager RROs. -->
<color name="system_neutral2_1000">#000000</color>
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedBackgroundPanelOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedBackgroundPanelOrganizer.java
index 97461e6..d327470 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedBackgroundPanelOrganizer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedBackgroundPanelOrganizer.java
@@ -16,6 +16,8 @@
package com.android.wm.shell.onehanded;
+import static com.android.wm.shell.onehanded.OneHandedState.STATE_ACTIVE;
+
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Color;
@@ -46,7 +48,7 @@
* the screen has entered one handed mode.
*/
public class OneHandedBackgroundPanelOrganizer extends DisplayAreaOrganizer
- implements OneHandedAnimationCallback {
+ implements OneHandedAnimationCallback, OneHandedState.OnStateChangedListener {
private static final String TAG = "OneHandedBackgroundPanelOrganizer";
private static final int THEME_COLOR_OFFSET = 10;
private static final int ALPHA_ANIMATION_DURATION = 200;
@@ -56,6 +58,7 @@
private final OneHandedSurfaceTransactionHelper.SurfaceControlTransactionFactory
mTransactionFactory;
+ private @OneHandedState.State int mCurrentState;
private ValueAnimator mAlphaAnimator;
private float mTranslationFraction;
@@ -180,6 +183,9 @@
* Called when transition finished.
*/
public void onStopFinished() {
+ if (mAlphaAnimator == null) {
+ return;
+ }
mAlphaAnimator.start();
}
@@ -224,6 +230,10 @@
*/
public void onConfigurationChanged() {
updateThemeColors();
+
+ if (mCurrentState != STATE_ACTIVE) {
+ return;
+ }
showBackgroundPanelLayer();
}
@@ -242,6 +252,11 @@
return Math.max(origColor - THEME_COLOR_OFFSET, 0) / 255.0f;
}
+ @Override
+ public void onStateChanged(int newState) {
+ mCurrentState = newState;
+ }
+
void dump(@NonNull PrintWriter pw) {
final String innerPrefix = " ";
pw.println(TAG);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedController.java
index b0fe856..954ca14 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedController.java
@@ -307,6 +307,7 @@
mAccessibilityManager.addAccessibilityStateChangeListener(
mAccessibilityStateChangeListener);
+ mState.addSListeners(mBackgroundPanelOrganizer);
mState.addSListeners(mTutorialHandler);
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedBackgroundPanelOrganizerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedBackgroundPanelOrganizerTest.java
index 99c6107..7b9553c 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedBackgroundPanelOrganizerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedBackgroundPanelOrganizerTest.java
@@ -19,6 +19,9 @@
import static android.view.Display.DEFAULT_DISPLAY;
import static android.window.DisplayAreaOrganizer.FEATURE_ONE_HANDED_BACKGROUND_PANEL;
+import static com.android.wm.shell.onehanded.OneHandedState.STATE_ACTIVE;
+import static com.android.wm.shell.onehanded.OneHandedState.STATE_NONE;
+
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.anyInt;
@@ -109,4 +112,20 @@
assertThat(mSpiedBackgroundPanelOrganizer.mBackgroundSurface).isNull();
}
+
+ @Test
+ public void testStateNone_onConfigurationChanged() {
+ mSpiedBackgroundPanelOrganizer.onStateChanged(STATE_NONE);
+ mSpiedBackgroundPanelOrganizer.onConfigurationChanged();
+
+ verify(mSpiedBackgroundPanelOrganizer, never()).showBackgroundPanelLayer();
+ }
+
+ @Test
+ public void testStateActivate_onConfigurationChanged() {
+ mSpiedBackgroundPanelOrganizer.onStateChanged(STATE_ACTIVE);
+ mSpiedBackgroundPanelOrganizer.onConfigurationChanged();
+
+ verify(mSpiedBackgroundPanelOrganizer).showBackgroundPanelLayer();
+ }
}
diff --git a/location/java/android/location/CorrelationVector.java b/location/java/android/location/CorrelationVector.java
index 718977f..5493e25 100644
--- a/location/java/android/location/CorrelationVector.java
+++ b/location/java/android/location/CorrelationVector.java
@@ -94,8 +94,6 @@
"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/ActionBarShadow/Android.bp b/packages/SettingsLib/ActionBarShadow/Android.bp
index 800ab67..4a07d49 100644
--- a/packages/SettingsLib/ActionBarShadow/Android.bp
+++ b/packages/SettingsLib/ActionBarShadow/Android.bp
@@ -19,5 +19,5 @@
],
sdk_version: "system_current",
- min_sdk_version: "21",
+ min_sdk_version: "28",
}
diff --git a/packages/SettingsLib/ActionBarShadow/lint-baseline.xml b/packages/SettingsLib/ActionBarShadow/lint-baseline.xml
deleted file mode 100644
index 4d5de5f..0000000
--- a/packages/SettingsLib/ActionBarShadow/lint-baseline.xml
+++ /dev/null
@@ -1,37 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.1.0" client="cli" variant="all" version="4.1.0">
-
- <issue
- id="NewApi"
- message="Call requires API level 23 (current min is 21): `android.view.View#setOnScrollChangeListener`"
- errorLine1=" mScrollView.setOnScrollChangeListener(mScrollChangeWatcher);"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~">
- <location
- file="frameworks/base/packages/SettingsLib/ActionBarShadow/src/com/android/settingslib/widget/ActionBarShadowController.java"
- line="81"
- column="25"/>
- </issue>
-
- <issue
- id="NewApi"
- message="Call requires API level 23 (current min is 21): `android.view.View#setOnScrollChangeListener`"
- errorLine1=" mScrollView.setOnScrollChangeListener(null);"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~">
- <location
- file="frameworks/base/packages/SettingsLib/ActionBarShadow/src/com/android/settingslib/widget/ActionBarShadowController.java"
- line="88"
- column="21"/>
- </issue>
-
- <issue
- id="NewApi"
- message="Class requires API level 23 (current min is 21): `android.view.View.OnScrollChangeListener`"
- errorLine1=" final class ScrollChangeWatcher implements View.OnScrollChangeListener {"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~">
- <location
- file="frameworks/base/packages/SettingsLib/ActionBarShadow/src/com/android/settingslib/widget/ActionBarShadowController.java"
- line="95"
- column="48"/>
- </issue>
-
-</issues>
diff --git a/packages/SettingsLib/ActionButtonsPreference/lint-baseline.xml b/packages/SettingsLib/ActionButtonsPreference/lint-baseline.xml
deleted file mode 100644
index 95b7e3b..0000000
--- a/packages/SettingsLib/ActionButtonsPreference/lint-baseline.xml
+++ /dev/null
@@ -1,81 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.1.0" client="cli" variant="all" version="4.1.0">
-
- <issue
- id="NewApi"
- message="`android:Widget.DeviceDefault.Button.Borderless.Colored` requires API level 28 (current min is 21)"
- errorLine1=" <style name="SettingsActionButton" parent="android:Widget.DeviceDefault.Button.Borderless.Colored">"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
- <location
- file="frameworks/base/packages/SettingsLib/ActionButtonsPreference/res/values/styles.xml"
- line="19"
- column="40"/>
- </issue>
-
- <issue
- id="NewApi"
- message="`android:drawableTint` requires API level 23 (current min is 21)"
- errorLine1=" <item name="android:drawableTint">@*android:color/btn_colored_borderless_text_material</item>"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~">
- <location
- file="frameworks/base/packages/SettingsLib/ActionButtonsPreference/res/values/styles.xml"
- line="21"
- column="15"/>
- </issue>
-
- <issue
- id="NewApi"
- message="`?android:attr/dialogCornerRadius` requires API level 28 (current min is 21)"
- errorLine1=" android:topLeftRadius="?android:attr/dialogCornerRadius""
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~">
- <location
- file="frameworks/base/packages/SettingsLib/ActionButtonsPreference/res/drawable/half_rounded_left_bk.xml"
- line="23"
- column="9"/>
- </issue>
-
- <issue
- id="NewApi"
- message="`?android:attr/dialogCornerRadius` requires API level 28 (current min is 21)"
- errorLine1=" android:bottomLeftRadius="?android:attr/dialogCornerRadius""
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~">
- <location
- file="frameworks/base/packages/SettingsLib/ActionButtonsPreference/res/drawable/half_rounded_left_bk.xml"
- line="25"
- column="9"/>
- </issue>
-
- <issue
- id="NewApi"
- message="`?android:attr/dialogCornerRadius` requires API level 28 (current min is 21)"
- errorLine1=" android:topRightRadius="?android:attr/dialogCornerRadius""
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~">
- <location
- file="frameworks/base/packages/SettingsLib/ActionButtonsPreference/res/drawable/half_rounded_right_bk.xml"
- line="24"
- column="9"/>
- </issue>
-
- <issue
- id="NewApi"
- message="`?android:attr/dialogCornerRadius` requires API level 28 (current min is 21)"
- errorLine1=" android:bottomRightRadius="?android:attr/dialogCornerRadius""
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~">
- <location
- file="frameworks/base/packages/SettingsLib/ActionButtonsPreference/res/drawable/half_rounded_right_bk.xml"
- line="26"
- column="9"/>
- </issue>
-
- <issue
- id="NewApi"
- message="`?android:attr/dialogCornerRadius` requires API level 28 (current min is 21)"
- errorLine1=" android:bottomRightRadius="?android:attr/dialogCornerRadius""
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~">
- <location
- file="frameworks/base/packages/SettingsLib/ActionButtonsPreference/res/drawable/rounded_bk.xml"
- line="23"
- column="9"/>
- </issue>
-
-</issues>
diff --git a/packages/SettingsLib/ActionButtonsPreference/res/drawable/half_rounded_left_bk.xml b/packages/SettingsLib/ActionButtonsPreference/res/drawable/half_rounded_left_bk.xml
index 16a85d6..8a25726 100644
--- a/packages/SettingsLib/ActionButtonsPreference/res/drawable/half_rounded_left_bk.xml
+++ b/packages/SettingsLib/ActionButtonsPreference/res/drawable/half_rounded_left_bk.xml
@@ -17,6 +17,8 @@
<shape xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ tools:targetApi="28"
android:shape="rectangle">
<solid android:color="?androidprv:attr/colorSurface" />
<corners
diff --git a/packages/SettingsLib/ActionButtonsPreference/res/drawable/half_rounded_right_bk.xml b/packages/SettingsLib/ActionButtonsPreference/res/drawable/half_rounded_right_bk.xml
index 1b9f68f..7e626e5 100644
--- a/packages/SettingsLib/ActionButtonsPreference/res/drawable/half_rounded_right_bk.xml
+++ b/packages/SettingsLib/ActionButtonsPreference/res/drawable/half_rounded_right_bk.xml
@@ -1,22 +1,24 @@
<?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.
+ 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.
-->
<shape xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ tools:targetApi="28"
android:shape="rectangle">
<solid android:color="?androidprv:attr/colorSurface" />
<corners
diff --git a/packages/SettingsLib/ActionButtonsPreference/res/drawable/rounded_bk.xml b/packages/SettingsLib/ActionButtonsPreference/res/drawable/rounded_bk.xml
index a884ef1..9f4980b 100644
--- a/packages/SettingsLib/ActionButtonsPreference/res/drawable/rounded_bk.xml
+++ b/packages/SettingsLib/ActionButtonsPreference/res/drawable/rounded_bk.xml
@@ -1,22 +1,24 @@
<?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.
+ 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.
-->
<shape xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ tools:targetApi="28"
android:shape="rectangle">
<solid android:color="?androidprv:attr/colorSurface" />
<corners
diff --git a/packages/SettingsLib/ActionButtonsPreference/res/values/styles.xml b/packages/SettingsLib/ActionButtonsPreference/res/values/styles.xml
index 42c7d76..8a449cf 100644
--- a/packages/SettingsLib/ActionButtonsPreference/res/values/styles.xml
+++ b/packages/SettingsLib/ActionButtonsPreference/res/values/styles.xml
@@ -15,7 +15,9 @@
limitations under the License.
-->
-<resources>
+<resources
+ xmlns:tools="http://schemas.android.com/tools"
+ tools:targetApi="28">
<style name="SettingsLibActionButton" parent="android:Widget.DeviceDefault.Button.Borderless.Colored">
<item name="android:drawablePadding">4dp</item>
<item name="android:drawableTint">@*android:color/btn_colored_borderless_text_material</item>
diff --git a/packages/SettingsLib/BarChartPreference/Android.bp b/packages/SettingsLib/BarChartPreference/Android.bp
index ae26066..4f65373 100644
--- a/packages/SettingsLib/BarChartPreference/Android.bp
+++ b/packages/SettingsLib/BarChartPreference/Android.bp
@@ -14,7 +14,7 @@
resource_dirs: ["res"],
static_libs: [
- "androidx.preference_preference",
+ "androidx.preference_preference",
],
sdk_version: "system_current",
diff --git a/packages/SettingsLib/BarChartPreference/lint-baseline.xml b/packages/SettingsLib/BarChartPreference/lint-baseline.xml
deleted file mode 100644
index f1043bb..0000000
--- a/packages/SettingsLib/BarChartPreference/lint-baseline.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.1.0" client="cli" variant="all" version="4.1.0">
-
- <issue
- id="NewApi"
- message="`@android:style/Widget.DeviceDefault.Button.Borderless.Colored` requires API level 28 (current min is 21)"
- errorLine1=" parent="@android:style/Widget.DeviceDefault.Button.Borderless.Colored">"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
- <location
- file="frameworks/base/packages/SettingsLib/BarChartPreference/res/values/styles.xml"
- line="35"
- column="12"/>
- </issue>
-
-</issues>
diff --git a/packages/SettingsLib/BarChartPreference/res/values/styles.xml b/packages/SettingsLib/BarChartPreference/res/values/styles.xml
index 7a3fb7d..92514ad 100644
--- a/packages/SettingsLib/BarChartPreference/res/values/styles.xml
+++ b/packages/SettingsLib/BarChartPreference/res/values/styles.xml
@@ -15,7 +15,9 @@
limitations under the License.
-->
-<resources>
+<resources
+ xmlns:tools="http://schemas.android.com/tools"
+ tools:targetApi="28">
<style name="SettingsBarChart">
<item name="android:layout_marginStart">10dp</item>
diff --git a/packages/SettingsLib/HelpUtils/lint-baseline.xml b/packages/SettingsLib/HelpUtils/lint-baseline.xml
deleted file mode 100644
index 940f027..0000000
--- a/packages/SettingsLib/HelpUtils/lint-baseline.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.1.0" client="cli" variant="all" version="4.1.0">
-
- <issue
- id="NewApi"
- message="Call requires API level 28 (current min is 21): `android.content.pm.PackageInfo#getLongVersionCode`"
- errorLine1=" sCachedVersionCode = Long.toString(info.getLongVersionCode());"
- errorLine2=" ~~~~~~~~~~~~~~~~~~">
- <location
- file="frameworks/base/packages/SettingsLib/HelpUtils/src/com/android/settingslib/HelpUtils.java"
- line="239"
- column="57"/>
- </issue>
-
-</issues>
diff --git a/packages/SettingsLib/HelpUtils/src/com/android/settingslib/HelpUtils.java b/packages/SettingsLib/HelpUtils/src/com/android/settingslib/HelpUtils.java
index 541a246..70c8658 100644
--- a/packages/SettingsLib/HelpUtils/src/com/android/settingslib/HelpUtils.java
+++ b/packages/SettingsLib/HelpUtils/src/com/android/settingslib/HelpUtils.java
@@ -25,6 +25,7 @@
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.Resources;
import android.net.Uri;
+import android.os.Build;
import android.provider.Settings.Global;
import android.text.TextUtils;
import android.util.Log;
@@ -32,6 +33,7 @@
import android.view.MenuItem;
import android.view.MenuItem.OnMenuItemClickListener;
+import androidx.annotation.RequiresApi;
import androidx.annotation.VisibleForTesting;
import com.android.settingslib.widget.R;
@@ -73,6 +75,15 @@
private HelpUtils() {
}
+ /**
+ * Prepares the help menu item by doing the following.
+ * - If the helpUrlString is empty or null, the help menu item is made invisible.
+ * - Otherwise, this makes the help menu item visible and sets the intent for the help menu
+ * item to view the URL.
+ *
+ * @return returns whether the help menu item has been made visible.
+ */
+ @RequiresApi(Build.VERSION_CODES.P)
public static boolean prepareHelpMenuItem(Activity activity, Menu menu, String helpUri,
String backupContext) {
// menu contains help item, skip it
@@ -84,6 +95,15 @@
return prepareHelpMenuItem(activity, helpItem, helpUri, backupContext);
}
+ /**
+ * Prepares the help menu item by doing the following.
+ * - If the helpUrlString is empty or null, the help menu item is made invisible.
+ * - Otherwise, this makes the help menu item visible and sets the intent for the help menu
+ * item to view the URL.
+ *
+ * @return returns whether the help menu item has been made visible.
+ */
+ @RequiresApi(Build.VERSION_CODES.P)
public static boolean prepareHelpMenuItem(Activity activity, Menu menu, int helpUriResource,
String backupContext) {
// menu contains help item, skip it
@@ -105,6 +125,7 @@
* @return returns whether the help menu item has been made visible.
*/
@VisibleForTesting
+ @RequiresApi(Build.VERSION_CODES.P)
static boolean prepareHelpMenuItem(final Activity activity, MenuItem helpMenuItem,
String helpUriString, String backupContext) {
if (Global.getInt(activity.getContentResolver(), Global.DEVICE_PROVISIONED, 0) == 0) {
@@ -152,6 +173,10 @@
}
}
+ /**
+ * Get the help intent from helpUriString.
+ */
+ @RequiresApi(Build.VERSION_CODES.P)
public static Intent getHelpIntent(Context context, String helpUriString,
String backupContext) {
if (Global.getInt(context.getContentResolver(), Global.DEVICE_PROVISIONED, 0) == 0) {
@@ -223,7 +248,8 @@
*
* @return the uri with added query parameters
*/
- private static Uri uriWithAddedParameters(Context context, Uri baseUri) {
+ @RequiresApi(Build.VERSION_CODES.P)
+ public static Uri uriWithAddedParameters(Context context, Uri baseUri) {
Uri.Builder builder = baseUri.buildUpon();
// Add in the preferred language
diff --git a/packages/SettingsLib/ProgressBar/lint-baseline.xml b/packages/SettingsLib/ProgressBar/lint-baseline.xml
deleted file mode 100644
index 03d0f3f..0000000
--- a/packages/SettingsLib/ProgressBar/lint-baseline.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.1.0" client="cli" variant="all" version="4.1.0">
-
- <issue
- id="NewApi"
- message="`?android:attr/colorSecondary` requires API level 25 (current min is 21)"
- errorLine1=" android:background="?android:attr/colorSecondary" />"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
- <location
- file="frameworks/base/packages/SettingsLib/ProgressBar/res/layout/progress_header.xml"
- line="27"
- column="9"/>
- </issue>
-
-</issues>
diff --git a/packages/SettingsLib/ProgressBar/res/layout/progress_header.xml b/packages/SettingsLib/ProgressBar/res/layout/progress_header.xml
index 268858b..52ff42c 100644
--- a/packages/SettingsLib/ProgressBar/res/layout/progress_header.xml
+++ b/packages/SettingsLib/ProgressBar/res/layout/progress_header.xml
@@ -17,6 +17,8 @@
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ tools:targetApi="25"
android:layout_width="match_parent"
android:layout_height="3dp">
<View
diff --git a/packages/SettingsLib/RestrictedLockUtils/lint-baseline.xml b/packages/SettingsLib/RestrictedLockUtils/lint-baseline.xml
deleted file mode 100644
index 173c735..0000000
--- a/packages/SettingsLib/RestrictedLockUtils/lint-baseline.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.1.0" client="cli" variant="all" version="4.1.0">
-
- <issue
- id="NewApi"
- message="Call requires API level 23 (current min is 21): `android.content.Context#getSystemService`"
- errorLine1=" ComponentName adminComponent = userContext.getSystemService("
- errorLine2=" ~~~~~~~~~~~~~~~~">
- <location
- file="frameworks/base/packages/SettingsLib/RestrictedLockUtils/src/com/android/settingslib/RestrictedLockUtils.java"
- line="59"
- column="52"/>
- </issue>
-
- <issue
- id="NewApi"
- message="Call requires API level 23 (current min is 21): `android.content.Context#getSystemService`"
- errorLine1=" UserManager um = context.getSystemService(UserManager.class);"
- errorLine2=" ~~~~~~~~~~~~~~~~">
- <location
- file="frameworks/base/packages/SettingsLib/RestrictedLockUtils/src/com/android/settingslib/RestrictedLockUtils.java"
- line="101"
- column="34"/>
- </issue>
-
-</issues>
diff --git a/packages/SettingsLib/RestrictedLockUtils/src/com/android/settingslib/RestrictedLockUtils.java b/packages/SettingsLib/RestrictedLockUtils/src/com/android/settingslib/RestrictedLockUtils.java
index a77e34b..80f02b4 100644
--- a/packages/SettingsLib/RestrictedLockUtils/src/com/android/settingslib/RestrictedLockUtils.java
+++ b/packages/SettingsLib/RestrictedLockUtils/src/com/android/settingslib/RestrictedLockUtils.java
@@ -21,11 +21,13 @@
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
+import android.os.Build;
import android.os.UserHandle;
import android.os.UserManager;
import android.provider.Settings;
import androidx.annotation.Nullable;
+import androidx.annotation.RequiresApi;
import java.util.Objects;
@@ -34,10 +36,18 @@
* support message dialog.
*/
public class RestrictedLockUtils {
+ /**
+ * Get EnforcedAdmin from DevicePolicyManager
+ */
+ @RequiresApi(Build.VERSION_CODES.M)
public static EnforcedAdmin getProfileOrDeviceOwner(Context context, UserHandle user) {
return getProfileOrDeviceOwner(context, null, user);
}
+ /**
+ * Get EnforcedAdmin from DevicePolicyManager
+ */
+ @RequiresApi(Build.VERSION_CODES.M)
public static EnforcedAdmin getProfileOrDeviceOwner(
Context context, String enforcedRestriction, UserHandle user) {
if (user == null) {
@@ -73,6 +83,7 @@
/**
* Send the intent to trigger the {@code android.settings.ShowAdminSupportDetailsDialog}.
*/
+ @RequiresApi(Build.VERSION_CODES.M)
public static void sendShowAdminSupportDetailsIntent(Context context, EnforcedAdmin admin) {
final Intent intent = getShowAdminSupportDetailsIntent(context, admin);
int targetUserId = UserHandle.myUserId();
@@ -97,6 +108,10 @@
return intent;
}
+ /**
+ * Check if current user is profile or not
+ */
+ @RequiresApi(Build.VERSION_CODES.M)
public static boolean isCurrentUserOrProfile(Context context, int userId) {
UserManager um = context.getSystemService(UserManager.class);
return um.getUserProfiles().contains(UserHandle.of(userId));
diff --git a/packages/SettingsLib/SettingsSpinner/lint-baseline.xml b/packages/SettingsLib/SettingsSpinner/lint-baseline.xml
deleted file mode 100644
index ae1ed38e..0000000
--- a/packages/SettingsLib/SettingsSpinner/lint-baseline.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.1.0" client="cli" variant="all" version="4.1.0">
-
- <issue
- id="NewApi"
- message="Call requires API level 23 (current min is 21): `new android.widget.Spinner`"
- errorLine1=" super(context, attrs, defStyleAttr, defStyleRes, mode, null);"
- errorLine2=" ~~~~~">
- <location
- file="frameworks/base/packages/SettingsLib/SettingsSpinner/src/com/android/settingslib/widget/settingsspinner/SettingsSpinner.java"
- line="122"
- column="9"/>
- </issue>
-
-</issues>
diff --git a/packages/SettingsLib/SettingsSpinner/src/com/android/settingslib/widget/settingsspinner/SettingsSpinner.java b/packages/SettingsLib/SettingsSpinner/src/com/android/settingslib/widget/settingsspinner/SettingsSpinner.java
index 0be80a9f..14286fa 100644
--- a/packages/SettingsLib/SettingsSpinner/src/com/android/settingslib/widget/settingsspinner/SettingsSpinner.java
+++ b/packages/SettingsLib/SettingsSpinner/src/com/android/settingslib/widget/settingsspinner/SettingsSpinner.java
@@ -17,9 +17,12 @@
package com.android.settingslib.widget.settingsspinner;
import android.content.Context;
+import android.os.Build;
import android.util.AttributeSet;
import android.widget.Spinner;
+import androidx.annotation.RequiresApi;
+
import com.android.settingslib.widget.R;
/**
@@ -117,6 +120,7 @@
* @see Spinner#MODE_DIALOG
* @see Spinner#MODE_DROPDOWN
*/
+ @RequiresApi(Build.VERSION_CODES.M)
public SettingsSpinner(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes,
int mode) {
super(context, attrs, defStyleAttr, defStyleRes, mode, null);
diff --git a/packages/SettingsLib/src/com/android/settingslib/enterprise/BiometricActionDisabledByAdminController.java b/packages/SettingsLib/src/com/android/settingslib/enterprise/BiometricActionDisabledByAdminController.java
index e0339da..d205eaa 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 @@
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/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java
index 632919a..f4a3fb2 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java
@@ -97,6 +97,8 @@
private final KeyguardUnlockAnimationController mKeyguardUnlockAnimationController;
private SmartspaceTransitionController mSmartspaceTransitionController;
+ private boolean mOnlyClock = false;
+
@Inject
public KeyguardClockSwitchController(
KeyguardClockSwitch keyguardClockSwitch,
@@ -129,6 +131,13 @@
}
/**
+ * Mostly used for alternate displays, limit the information shown
+ */
+ public void setOnlyClock(boolean onlyClock) {
+ mOnlyClock = onlyClock;
+ }
+
+ /**
* Attach the controller to the view it relates to.
*/
@Override
@@ -166,6 +175,16 @@
}
mColorExtractor.addOnColorsChangedListener(mColorsListener);
mView.updateColors(getGradientColors());
+
+ if (mOnlyClock) {
+ View ksa = mView.findViewById(R.id.keyguard_status_area);
+ ksa.setVisibility(View.GONE);
+
+ View nic = mView.findViewById(
+ R.id.left_aligned_notification_icon_container);
+ nic.setVisibility(View.GONE);
+ return;
+ }
updateAodIcons();
if (mSmartspaceController.isEnabled()) {
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardDisplayManager.java b/packages/SystemUI/src/com/android/keyguard/KeyguardDisplayManager.java
index 76a7473..cac90ea 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardDisplayManager.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardDisplayManager.java
@@ -332,6 +332,7 @@
.build(findViewById(R.id.clock))
.getKeyguardClockSwitchController();
+ mKeyguardClockSwitchController.setOnlyClock(true);
mKeyguardClockSwitchController.init();
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeaderController.java b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeaderController.java
index b8b7f42..da75c9e 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeaderController.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeaderController.java
@@ -178,6 +178,8 @@
// Ignore privacy icons because they show in the space above QQS
updatePrivacyIconSlots();
+ mIconContainer.addIgnoredSlot(
+ getResources().getString(com.android.internal.R.string.status_bar_managed_profile));
mIconContainer.setShouldRestrictIcons(false);
mStatusBarIconController.addIconGroup(mIconManager);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/events/PrivacyDotViewController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/events/PrivacyDotViewController.kt
index 29cfb07..1037e57 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/events/PrivacyDotViewController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/events/PrivacyDotViewController.kt
@@ -497,7 +497,12 @@
}
if (state.designatedCorner != currentViewState.designatedCorner) {
+ currentViewState.designatedCorner?.contentDescription = null
+ state.designatedCorner?.contentDescription = state.contentDescription
+
updateDesignatedCorner(state.designatedCorner, state.shouldShowDot())
+ } else if (state.contentDescription != currentViewState.contentDescription) {
+ state.designatedCorner?.contentDescription = state.contentDescription
}
val shouldShow = state.shouldShowDot()
@@ -514,9 +519,13 @@
private val systemStatusAnimationCallback: SystemStatusAnimationCallback =
object : SystemStatusAnimationCallback {
- override fun onSystemStatusAnimationTransitionToPersistentDot(): Animator? {
+ override fun onSystemStatusAnimationTransitionToPersistentDot(
+ contentDescr: String?
+ ): Animator? {
synchronized(lock) {
- nextViewState = nextViewState.copy(systemPrivacyEventIsActive = true)
+ nextViewState = nextViewState.copy(
+ systemPrivacyEventIsActive = true,
+ contentDescription = contentDescr)
}
return null
@@ -620,7 +629,9 @@
val rotation: Int = 0,
val height: Int = 0,
val cornerIndex: Int = -1,
- val designatedCorner: View? = null
+ val designatedCorner: View? = null,
+
+ val contentDescription: String? = null
) {
fun shouldShowDot(): Boolean {
return systemPrivacyEventIsActive && !shadeExpanded && !qsExpanded
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/events/StatusEvent.kt b/packages/SystemUI/src/com/android/systemui/statusbar/events/StatusEvent.kt
index 539020d..d4d84c1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/events/StatusEvent.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/events/StatusEvent.kt
@@ -34,6 +34,7 @@
// Whether or not to show an animation for this event
val showAnimation: Boolean
val viewCreator: (context: Context) -> View
+ var contentDescription: String?
// Update this event with values from another event.
fun updateFromEvent(other: StatusEvent?) {
@@ -50,6 +51,7 @@
override val priority = 50
override val forceVisible = false
override val showAnimation = true
+ override var contentDescription: String? = ""
override val viewCreator: (context: Context) -> View = { context ->
val iv = ImageView(context)
@@ -62,7 +64,9 @@
return javaClass.simpleName
}
}
+
class PrivacyEvent(override val showAnimation: Boolean = true) : StatusEvent {
+ override var contentDescription: String? = null
override val priority = 100
override val forceVisible = true
var privacyItems: List<PrivacyItem> = listOf()
@@ -72,6 +76,7 @@
val v = LayoutInflater.from(context)
.inflate(R.layout.ongoing_privacy_chip, null) as OngoingPrivacyChip
v.privacyList = privacyItems
+ v.contentDescription = contentDescription
privacyChip = v
v
}
@@ -81,7 +86,9 @@
}
override fun shouldUpdateFromEvent(other: StatusEvent?): Boolean {
- return other is PrivacyEvent && other.privacyItems != privacyItems
+ return other is PrivacyEvent &&
+ (other.privacyItems != privacyItems ||
+ other.contentDescription != contentDescription)
}
override fun updateFromEvent(other: StatusEvent?) {
@@ -90,6 +97,9 @@
}
privacyItems = other.privacyItems
+ contentDescription = other.contentDescription
+
+ privacyChip?.contentDescription = other.contentDescription
privacyChip?.privacyList = other.privacyItems
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemEventChipAnimationController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemEventChipAnimationController.kt
index b861c1d..7291b5a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemEventChipAnimationController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemEventChipAnimationController.kt
@@ -34,8 +34,7 @@
import javax.inject.Inject
/**
- * //TODO: this _probably_ doesn't control a window anymore
- * Controls the window for system event animations.
+ * Controls the view for system event animations.
*/
class SystemEventChipAnimationController @Inject constructor(
private val context: Context,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemEventCoordinator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemEventCoordinator.kt
index ba50659..04f7492 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemEventCoordinator.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemEventCoordinator.kt
@@ -16,9 +16,12 @@
package com.android.systemui.statusbar.events
+import android.content.Context
import android.provider.DeviceConfig
import android.provider.DeviceConfig.NAMESPACE_PRIVACY
+import com.android.systemui.R
import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.privacy.PrivacyChipBuilder
import com.android.systemui.privacy.PrivacyItem
import com.android.systemui.privacy.PrivacyItemController
import com.android.systemui.statusbar.policy.BatteryController
@@ -33,7 +36,8 @@
class SystemEventCoordinator @Inject constructor(
private val systemClock: SystemClock,
private val batteryController: BatteryController,
- private val privacyController: PrivacyItemController
+ private val privacyController: PrivacyItemController,
+ private val context: Context
) {
private lateinit var scheduler: SystemStatusAnimationScheduler
@@ -66,6 +70,11 @@
fun notifyPrivacyItemsChanged(showAnimation: Boolean = true) {
val event = PrivacyEvent(showAnimation)
event.privacyItems = privacyStateListener.currentPrivacyItems
+ event.contentDescription = {
+ val items = PrivacyChipBuilder(context, event.privacyItems).joinTypes()
+ context.getString(
+ R.string.ongoing_privacy_chip_content_multiple_apps, items)
+ }()
scheduler.onStatusEvent(event)
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemStatusAnimationScheduler.kt b/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemStatusAnimationScheduler.kt
index f30010c..dcf8e73 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemStatusAnimationScheduler.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemStatusAnimationScheduler.kt
@@ -100,14 +100,21 @@
// Don't deal with threading for now (no need let's be honest)
Assert.isMainThread()
- if (event.priority > scheduledEvent?.priority ?: -1 ||
- scheduledEvent?.shouldUpdateFromEvent(event) == true) {
+ if ((event.priority > scheduledEvent?.priority ?: -1) &&
+ animationState != ANIMATING_OUT &&
+ (animationState != SHOWING_PERSISTENT_DOT && event.forceVisible)) {
+ // events can only be scheduled if a higher priority or no other event is in progress
if (DEBUG) {
Log.d(TAG, "scheduling event $event")
}
- if (event.showAnimation) {
- scheduleEvent(event)
- } else if (event.forceVisible) {
+
+ scheduleEvent(event)
+ } else if (scheduledEvent?.shouldUpdateFromEvent(event) == true) {
+ if (DEBUG) {
+ Log.d(TAG, "updating current event from: $event")
+ }
+ scheduledEvent?.updateFromEvent(event)
+ if (event.forceVisible) {
hasPersistentDot = true
notifyTransitionToPersistentDot()
}
@@ -142,24 +149,19 @@
* Clear the scheduled event (if any) and schedule a new one
*/
private fun scheduleEvent(event: StatusEvent) {
- if (animationState == ANIMATING_OUT ||
- (animationState == SHOWING_PERSISTENT_DOT && event.forceVisible)) {
- // do not schedule an event or change the current one
- return
- }
+ scheduledEvent = event
- // If we are showing the chip, possibly update the current event, rather than replacing
- if (scheduledEvent?.shouldUpdateFromEvent(event) == true) {
- scheduledEvent?.updateFromEvent(event)
- return
- } else {
- scheduledEvent = event
- }
-
- if (scheduledEvent!!.forceVisible) {
+ if (event.forceVisible) {
hasPersistentDot = true
}
+ // If animations are turned off, we'll transition directly to the dot
+ if (!event.showAnimation && event.forceVisible) {
+ notifyTransitionToPersistentDot()
+ scheduledEvent = null
+ return
+ }
+
// Schedule the animation to start after a debounce period
cancelExecutionRunnable = executor.executeDelayed({
cancelExecutionRunnable = null
@@ -218,7 +220,7 @@
private fun notifyTransitionToPersistentDot(): Animator? {
val anims: List<Animator> = listeners.mapNotNull {
- it.onSystemStatusAnimationTransitionToPersistentDot()
+ it.onSystemStatusAnimationTransitionToPersistentDot(scheduledEvent?.contentDescription)
}
if (anims.isNotEmpty()) {
val aSet = AnimatorSet()
@@ -346,7 +348,10 @@
@JvmDefault fun onSystemChromeAnimationEnd() {}
// Best method name, change my mind
- @JvmDefault fun onSystemStatusAnimationTransitionToPersistentDot(): Animator? { return null }
+ @JvmDefault
+ fun onSystemStatusAnimationTransitionToPersistentDot(contentDescription: String?): Animator? {
+ return null
+ }
@JvmDefault fun onHidePersistentDot(): Animator? { return null }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
index fa61115..c49de7a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
@@ -70,6 +70,7 @@
import com.android.systemui.dagger.qualifiers.Background;
import com.android.systemui.demomode.DemoMode;
import com.android.systemui.demomode.DemoModeController;
+import com.android.systemui.dump.DumpManager;
import com.android.systemui.settings.CurrentUserTracker;
import com.android.systemui.statusbar.FeatureFlags;
import com.android.systemui.statusbar.policy.DeviceProvisionedController.DeviceProvisionedListener;
@@ -126,6 +127,7 @@
private Config mConfig;
private final CarrierConfigTracker mCarrierConfigTracker;
private final FeatureFlags mFeatureFlags;
+ private final DumpManager mDumpManager;
private TelephonyCallback.ActiveDataSubscriptionIdListener mPhoneStateListener;
private int mActiveMobileDataSubscription = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
@@ -218,7 +220,8 @@
AccessPointControllerImpl accessPointController,
DemoModeController demoModeController,
CarrierConfigTracker carrierConfigTracker,
- FeatureFlags featureFlags) {
+ FeatureFlags featureFlags,
+ DumpManager dumpManager) {
this(context, connectivityManager,
telephonyManager,
telephonyListenerManager,
@@ -236,7 +239,8 @@
broadcastDispatcher,
demoModeController,
carrierConfigTracker,
- featureFlags);
+ featureFlags,
+ dumpManager);
mReceiverHandler.post(mRegisterListeners);
}
@@ -256,7 +260,8 @@
BroadcastDispatcher broadcastDispatcher,
DemoModeController demoModeController,
CarrierConfigTracker carrierConfigTracker,
- FeatureFlags featureFlags
+ FeatureFlags featureFlags,
+ DumpManager dumpManager
) {
mContext = context;
mTelephonyListenerManager = telephonyListenerManager;
@@ -275,6 +280,7 @@
mDemoModeController = demoModeController;
mCarrierConfigTracker = carrierConfigTracker;
mFeatureFlags = featureFlags;
+ mDumpManager = dumpManager;
// telephony
mPhone = telephonyManager;
@@ -425,6 +431,8 @@
mDemoModeController.addCallback(this);
mProviderModelBehavior = mFeatureFlags.isCombinedStatusBarSignalIconsEnabled();
mProviderModelSetting = mFeatureFlags.isProviderModelSettingEnabled();
+
+ mDumpManager.registerDumpable(TAG, this);
}
private final Runnable mClearForceValidated = () -> {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java
index f2de26c..6c4ec22 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java
@@ -70,6 +70,7 @@
import com.android.systemui.SysuiTestCase;
import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.demomode.DemoModeController;
+import com.android.systemui.dump.DumpManager;
import com.android.systemui.statusbar.FeatureFlags;
import com.android.systemui.statusbar.policy.DeviceProvisionedController.DeviceProvisionedListener;
import com.android.systemui.statusbar.policy.NetworkController.IconState;
@@ -241,7 +242,9 @@
mMockBd,
mDemoModeController,
mCarrierConfigTracker,
- mFeatureFlags);
+ mFeatureFlags,
+ mock(DumpManager.class)
+ );
setupNetworkController();
// Trigger blank callbacks to always get the current state (some tests don't trigger
@@ -309,7 +312,8 @@
mock(AccessPointControllerImpl.class),
mock(DataUsageController.class), mMockSubDefaults,
mock(DeviceProvisionedController.class), mMockBd, mDemoModeController,
- mCarrierConfigTracker, mFeatureFlags);
+ mCarrierConfigTracker, mFeatureFlags,
+ mock(DumpManager.class));
setupNetworkController();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java
index bc4c2b6..3433a14 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java
@@ -21,6 +21,7 @@
import com.android.settingslib.mobile.TelephonyIcons;
import com.android.settingslib.net.DataUsageController;
+import com.android.systemui.dump.DumpManager;
import com.android.systemui.util.CarrierConfigTracker;
import org.junit.Test;
@@ -113,7 +114,7 @@
mock(AccessPointControllerImpl.class),
mock(DataUsageController.class), mMockSubDefaults,
mock(DeviceProvisionedController.class), mMockBd, mDemoModeController,
- mock(CarrierConfigTracker.class), mFeatureFlags);
+ mock(CarrierConfigTracker.class), mFeatureFlags, mock(DumpManager.class));
setupNetworkController();
setupDefaultSignal();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java
index 5090b0d..4ff1301 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java
@@ -41,6 +41,7 @@
import com.android.settingslib.mobile.TelephonyIcons;
import com.android.settingslib.net.DataUsageController;
import com.android.systemui.R;
+import com.android.systemui.dump.DumpManager;
import com.android.systemui.util.CarrierConfigTracker;
import org.junit.Test;
@@ -67,7 +68,8 @@
Looper.getMainLooper(), mFakeExecutor, mCallbackHandler,
mock(AccessPointControllerImpl.class), mock(DataUsageController.class),
mMockSubDefaults, mock(DeviceProvisionedController.class), mMockBd,
- mDemoModeController, mock(CarrierConfigTracker.class), mFeatureFlags);
+ mDemoModeController, mock(CarrierConfigTracker.class), mFeatureFlags,
+ mock(DumpManager.class));
setupNetworkController();
verifyLastMobileDataIndicators(false, -1, 0);
@@ -87,7 +89,8 @@
Looper.getMainLooper(), mFakeExecutor, mCallbackHandler,
mock(AccessPointControllerImpl.class), mock(DataUsageController.class),
mMockSubDefaults, mock(DeviceProvisionedController.class), mMockBd,
- mDemoModeController, mock(CarrierConfigTracker.class), mFeatureFlags);
+ mDemoModeController, mock(CarrierConfigTracker.class), mFeatureFlags,
+ mock(DumpManager.class));
mNetworkController.registerListeners();
// Wait for the main looper to execute the previous command
@@ -155,7 +158,8 @@
Looper.getMainLooper(), mFakeExecutor, mCallbackHandler,
mock(AccessPointControllerImpl.class), mock(DataUsageController.class),
mMockSubDefaults, mock(DeviceProvisionedController.class), mMockBd,
- mDemoModeController, mock(CarrierConfigTracker.class), mFeatureFlags);
+ mDemoModeController, mock(CarrierConfigTracker.class), mFeatureFlags,
+ mock(DumpManager.class));
setupNetworkController();
// No Subscriptions.
diff --git a/packages/services/CameraExtensionsProxy/src/com/android/cameraextensions/CameraExtensionsProxyService.java b/packages/services/CameraExtensionsProxy/src/com/android/cameraextensions/CameraExtensionsProxyService.java
index 561d079..b0893cc 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 @@
}
@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 @@
} 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 @@
Log.e(TAG, "Failed to submit repeating request due to remote exception!");
}
- return false;
+ return -1;
}
@Override
diff --git a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
index a56b1db..c32543a 100644
--- a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
+++ b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
@@ -3306,11 +3306,12 @@
Slog.w(TAG, "Failed to retrieve app info for " + packageName
+ " userId=" + userId, e);
}
- if (newAppInfo == null) {
+ if (newAppInfo == null || provider.info == null
+ || provider.info.providerInfo == null) {
continue;
}
ApplicationInfo oldAppInfo = provider.info.providerInfo.applicationInfo;
- if (!newAppInfo.sourceDir.equals(oldAppInfo.sourceDir)) {
+ if (oldAppInfo == null || !newAppInfo.sourceDir.equals(oldAppInfo.sourceDir)) {
// Overlay paths are generated against a particular version of an application.
// The overlays paths of a newly upgraded application are incompatible with the
// old version of the application.
diff --git a/services/core/java/com/android/server/SensorPrivacyService.java b/services/core/java/com/android/server/SensorPrivacyService.java
index 422e8ae..91b2440 100644
--- a/services/core/java/com/android/server/SensorPrivacyService.java
+++ b/services/core/java/com/android/server/SensorPrivacyService.java
@@ -1021,7 +1021,15 @@
}
}
- 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 @@
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 f41036c..a2fec27 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 @@
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 ac0a198..eeb41a3 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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java
index 1108937..abbe13a 100644
--- a/services/core/java/com/android/server/display/DisplayPowerController.java
+++ b/services/core/java/com/android/server/display/DisplayPowerController.java
@@ -2122,7 +2122,6 @@
private void ignoreProximitySensorUntilChangedInternal() {
if (!mIgnoreProximityUntilChanged
- && mPowerRequest.useProximitySensor
&& mProximity == PROXIMITY_POSITIVE) {
// Only ignore if it is still reporting positive (near)
mIgnoreProximityUntilChanged = true;
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 0d75dc8..f6acad0 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -22530,7 +22530,7 @@
UserManagerInternal umInternal = mInjector.getUserManagerInternal();
final int flags;
- if (StorageManager.isUserKeyUnlocked(userId)) {
+ if (umInternal.isUserUnlockingOrUnlocked(userId)) {
flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
} else if (umInternal.isUserRunning(userId)) {
flags = StorageManager.FLAG_STORAGE_DE;
@@ -25397,7 +25397,7 @@
UserManagerInternal umInternal = mInjector.getUserManagerInternal();
for (UserInfo user : mUserManager.getUsers(false /* includeDying */)) {
final int flags;
- if (StorageManager.isUserKeyUnlocked(user.id)) {
+ if (umInternal.isUserUnlockingOrUnlocked(user.id)) {
flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
} else if (umInternal.isUserRunning(user.id)) {
flags = StorageManager.FLAG_STORAGE_DE;
@@ -25737,7 +25737,7 @@
StorageManagerInternal smInternal = mInjector.getLocalService(StorageManagerInternal.class);
for (UserInfo user : mUserManager.getUsers(false /*excludeDying*/)) {
final int flags;
- if (StorageManager.isUserKeyUnlocked(user.id)) {
+ if (umInternal.isUserUnlockingOrUnlocked(user.id)) {
flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
} else if (umInternal.isUserRunning(user.id)) {
flags = StorageManager.FLAG_STORAGE_DE;
@@ -25751,7 +25751,7 @@
// Note: this code block is executed with the Installer lock
// already held, since it's invoked as a side-effect of
// executeBatchLI()
- if (StorageManager.isUserKeyUnlocked(user.id)) {
+ if (umInternal.isUserUnlockingOrUnlocked(user.id)) {
// Prepare app data on external storage; currently this is used to
// setup any OBB dirs that were created by the installer correctly.
int uid = UserHandle.getUid(user.id, UserHandle.getAppId(pkg.getUid()));
diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
index 08a67d7f..1133faa 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
@@ -217,6 +217,8 @@
/** All storage permissions */
private static final List<String> STORAGE_PERMISSIONS = new ArrayList<>();
+ /** All nearby devices permissions */
+ private static final List<String> NEARBY_DEVICES_PERMISSIONS = new ArrayList<>();
/** If the permission of the value is granted, so is the key */
private static final Map<String, String> FULLER_PERMISSION_MAP = new HashMap<>();
@@ -233,6 +235,9 @@
STORAGE_PERMISSIONS.add(Manifest.permission.READ_EXTERNAL_STORAGE);
STORAGE_PERMISSIONS.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
STORAGE_PERMISSIONS.add(Manifest.permission.ACCESS_MEDIA_LOCATION);
+ NEARBY_DEVICES_PERMISSIONS.add(Manifest.permission.BLUETOOTH_ADVERTISE);
+ NEARBY_DEVICES_PERMISSIONS.add(Manifest.permission.BLUETOOTH_CONNECT);
+ NEARBY_DEVICES_PERMISSIONS.add(Manifest.permission.BLUETOOTH_SCAN);
}
/** Set of source package names for Privileged Permission Allowlist */
@@ -3076,13 +3081,26 @@
Permission bp = mRegistry.getPermission(permission);
if (bp != null && bp.isRuntime()) {
int flags = ps.getPermissionFlags(permission);
-
if ((flags & FLAG_PERMISSION_REVOKE_WHEN_REQUESTED) != 0) {
-
int flagsToRemove = FLAG_PERMISSION_REVOKE_WHEN_REQUESTED;
+ // We're willing to preserve an implicit "Nearby devices"
+ // permission grant if this app was already able to interact
+ // with nearby devices via background location access
+ boolean preserveGrant = false;
+ if (ArrayUtils.contains(NEARBY_DEVICES_PERMISSIONS, permission)
+ && ps.isPermissionGranted(
+ android.Manifest.permission.ACCESS_BACKGROUND_LOCATION)
+ && (ps.getPermissionFlags(
+ android.Manifest.permission.ACCESS_BACKGROUND_LOCATION)
+ & (FLAG_PERMISSION_REVOKE_WHEN_REQUESTED
+ | FLAG_PERMISSION_REVOKED_COMPAT)) == 0) {
+ preserveGrant = true;
+ }
+
if ((flags & BLOCKING_PERMISSION_FLAGS) == 0
- && supportsRuntimePermissions) {
+ && supportsRuntimePermissions
+ && !preserveGrant) {
if (ps.revokePermission(bp)) {
if (DEBUG_PERMISSIONS) {
Slog.i(TAG, "Revoking runtime permission "
diff --git a/services/core/java/com/android/server/policy/AppOpsPolicy.java b/services/core/java/com/android/server/policy/AppOpsPolicy.java
index 18c45e4..8b46906 100644
--- a/services/core/java/com/android/server/policy/AppOpsPolicy.java
+++ b/services/core/java/com/android/server/policy/AppOpsPolicy.java
@@ -196,9 +196,8 @@
}
private static boolean isHotwordDetectionServiceRequired(PackageManager pm) {
- // The HotwordDetectionService APIs aren't ready yet for Auto or TV.
- return !(pm.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)
- || pm.hasSystemFeature(PackageManager.FEATURE_LEANBACK));
+ // Usage of the HotwordDetectionService won't be enforced until a later release.
+ return false;
}
@Override
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index fa12acd..d982336 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -532,6 +532,11 @@
// True if the proximity sensor reads a positive result.
private boolean mProximityPositive;
+ // Indicates that we have already intercepted the power key to temporarily ignore the proximity
+ // wake lock and turn the screen back on. This should get reset when prox reads 'far' again
+ // (when {@link #mProximityPositive} is set to false).
+ private boolean mInterceptedPowerKeyForProximity;
+
// Screen brightness setting limits.
public final float mScreenBrightnessMinimum;
public final float mScreenBrightnessMaximum;
@@ -3313,6 +3318,7 @@
public void onProximityNegative() {
synchronized (mLock) {
mProximityPositive = false;
+ mInterceptedPowerKeyForProximity = false;
mDirty |= DIRTY_PROXIMITY_POSITIVE;
userActivityNoUpdateLocked(Display.DEFAULT_DISPLAY_GROUP, mClock.uptimeMillis(),
PowerManager.USER_ACTIVITY_EVENT_OTHER, 0, Process.SYSTEM_UID);
@@ -4156,6 +4162,8 @@
}
pw.println();
pw.println(" mRequestWaitForNegativeProximity=" + mRequestWaitForNegativeProximity);
+ pw.println(" mInterceptedPowerKeyForProximity="
+ + mInterceptedPowerKeyForProximity);
pw.println(" mSandmanScheduled=" + mSandmanScheduled);
pw.println(" mBatteryLevelLow=" + mBatteryLevelLow);
pw.println(" mLightDeviceIdleMode=" + mLightDeviceIdleMode);
@@ -5987,8 +5995,9 @@
final DisplayPowerRequest displayPowerRequest =
mDisplayGroupPowerStateMapper.getPowerRequestLocked(
Display.DEFAULT_DISPLAY_GROUP);
- if (displayPowerRequest.useProximitySensor && mProximityPositive) {
+ if (mProximityPositive && !mInterceptedPowerKeyForProximity) {
mDisplayManagerInternal.ignoreProximitySensorUntilChanged();
+ mInterceptedPowerKeyForProximity = true;
return true;
}
}
diff --git a/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerMiddlewarePermission.java b/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerMiddlewarePermission.java
index 9999aff..2b03fe8 100644
--- a/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerMiddlewarePermission.java
+++ b/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerMiddlewarePermission.java
@@ -125,16 +125,25 @@
* originator temporarily doesn't have the right permissions to use this service.
*/
private void enforcePermissionsForPreflight(@NonNull Identity identity) {
- enforcePermissionForPreflight(mContext, identity, RECORD_AUDIO);
- enforcePermissionForPreflight(mContext, identity, CAPTURE_AUDIO_HOTWORD);
+ enforcePermissionForPreflight(mContext, identity, RECORD_AUDIO,
+ /* allowSoftDenial= */ true);
+ enforcePermissionForPreflight(mContext, identity, CAPTURE_AUDIO_HOTWORD,
+ /* allowSoftDenial= */ true);
}
/**
* Throws a {@link SecurityException} iff the originator has permission to receive data.
*/
void enforcePermissionsForDataDelivery(@NonNull Identity identity, @NonNull String reason) {
- enforcePermissionForDataDelivery(mContext, identity, RECORD_AUDIO,
- reason);
+ // SoundTrigger data is treated the same as Hotword-source audio. This should incur the
+ // HOTWORD op instead of the RECORD_AUDIO op. The RECORD_AUDIO permission is still required,
+ // and since this is a data delivery check, soft denials aren't accepted.
+ enforcePermissionForPreflight(mContext, identity, RECORD_AUDIO,
+ /* allowSoftDenial= */ false);
+ int hotwordOp = AppOpsManager.strOpToOp(AppOpsManager.OPSTR_RECORD_AUDIO_HOTWORD);
+ mContext.getSystemService(AppOpsManager.class).noteOpNoThrow(hotwordOp, identity.uid,
+ identity.packageName, identity.attributionTag, reason);
+
enforcePermissionForDataDelivery(mContext, identity, CAPTURE_AUDIO_HOTWORD,
reason);
}
@@ -163,20 +172,25 @@
/**
* Throws a {@link SecurityException} if originator permanently doesn't have the given
* permission.
- * Soft (temporary) denials are considered OK for preflight purposes.
*
- * @param context A {@link Context}, used for permission checks.
- * @param identity The identity to check.
- * @param permission The identifier of the permission we want to check.
+ * @param context A {@link Context}, used for permission checks.
+ * @param identity The identity to check.
+ * @param permission The identifier of the permission we want to check.
+ * @param allowSoftDenial If true, the operation succeeds even for soft (temporary) denials.
*/
+ // TODO: Consider splitting up this method instead of using `allowSoftDenial`, to make it
+ // clearer when soft denials are not allowed.
private static void enforcePermissionForPreflight(@NonNull Context context,
- @NonNull Identity identity, @NonNull String permission) {
+ @NonNull Identity identity, @NonNull String permission, boolean allowSoftDenial) {
final int status = PermissionUtil.checkPermissionForPreflight(context, identity,
permission);
switch (status) {
case PermissionChecker.PERMISSION_GRANTED:
- case PermissionChecker.PERMISSION_SOFT_DENIED:
return;
+ case PermissionChecker.PERMISSION_SOFT_DENIED:
+ if (allowSoftDenial) {
+ return;
+ } // else fall through
case PermissionChecker.PERMISSION_HARD_DENIED:
throw new SecurityException(
String.format("Failed to obtain permission %s for identity %s", permission,
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 0000000..b3c14228
--- /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 844687f..ba79a76 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 @@
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 @@
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 @@
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 5874b4b..7b6ccd3 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.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.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.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 @@
*/
@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 @@
*/
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 @@
}
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 @@
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;
- }
}
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java
index 734172f..a9aeb98 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java
@@ -23,11 +23,8 @@
import static android.service.voice.HotwordDetectionService.INITIALIZATION_STATUS_UNKNOWN;
import static android.service.voice.HotwordDetectionService.KEY_INITIALIZATION_STATUS;
-import static com.android.server.voiceinteraction.SoundTriggerSessionPermissionsDecorator.enforcePermissionForPreflight;
-
import android.annotation.NonNull;
import android.annotation.Nullable;
-import android.app.AppOpsManager;
import android.content.ComponentName;
import android.content.ContentCaptureOptions;
import android.content.Context;
@@ -935,11 +932,12 @@
// TODO: Share this code with SoundTriggerMiddlewarePermission.
private void enforcePermissionsForDataDelivery() {
Binder.withCleanCallingIdentity(() -> {
- enforcePermissionForPreflight(mContext, mVoiceInteractorIdentity, RECORD_AUDIO);
- int hotwordOp = AppOpsManager.strOpToOp(AppOpsManager.OPSTR_RECORD_AUDIO_HOTWORD);
- mContext.getSystemService(AppOpsManager.class).noteOpNoThrow(hotwordOp,
- mVoiceInteractorIdentity.uid, mVoiceInteractorIdentity.packageName,
- mVoiceInteractorIdentity.attributionTag, OP_MESSAGE);
+ // Hack to make sure we show the mic privacy-indicator since the Trusted Hotword
+ // requirement isn't being enforced for now. Normally, we would note the HOTWORD op here
+ // instead.
+ enforcePermissionForDataDelivery(mContext, mVoiceInteractorIdentity,
+ RECORD_AUDIO, OP_MESSAGE);
+
enforcePermissionForDataDelivery(mContext, mVoiceInteractorIdentity,
CAPTURE_AUDIO_HOTWORD, OP_MESSAGE);
});