summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--api/system-current.txt6
-rw-r--r--core/java/android/app/ActivityOptions.java4
-rw-r--r--core/java/android/app/AppComponentFactory.java19
-rw-r--r--core/java/android/content/Context.java5
-rw-r--r--core/java/android/hardware/biometrics/CryptoObject.java4
-rw-r--r--core/java/android/provider/Settings.java16
-rw-r--r--core/java/android/service/contentsuggestions/ContentSuggestionsService.java4
-rw-r--r--core/java/android/view/SurfaceControl.java5
-rw-r--r--core/java/com/android/internal/infra/AbstractRemoteService.java19
-rw-r--r--core/java/com/android/internal/os/RoSystemProperties.java2
-rw-r--r--graphics/java/android/graphics/Bitmap.java12
-rw-r--r--keystore/java/android/security/keystore/KeyGenParameterSpec.java45
-rw-r--r--keystore/java/android/security/keystore/KeyProtection.java51
-rw-r--r--media/java/android/media/AudioManager.java4
-rw-r--r--packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/ThumbnailData.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java9
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/DataSaverTile.java3
-rw-r--r--services/core/java/com/android/server/pm/permission/PermissionManagerService.java187
-rw-r--r--services/core/java/com/android/server/policy/PermissionPolicyService.java315
-rw-r--r--services/core/java/com/android/server/wm/ActivityRecord.java11
-rw-r--r--services/core/java/com/android/server/wm/DisplayContent.java14
-rw-r--r--services/core/java/com/android/server/wm/KeyguardController.java37
-rw-r--r--services/core/java/com/android/server/wm/TaskSnapshotPersister.java4
-rw-r--r--services/core/java/com/android/server/wm/WallpaperController.java4
24 files changed, 432 insertions, 353 deletions
diff --git a/api/system-current.txt b/api/system-current.txt
index c0da879241ab..282f6f749128 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -3499,9 +3499,9 @@ package android.media {
method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public int dispatchAudioFocusChange(@NonNull android.media.AudioFocusInfo, int, @NonNull android.media.audiopolicy.AudioPolicy);
method @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public android.media.audiopolicy.AudioProductStrategies getAudioProductStrategies();
method @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public android.media.audiopolicy.AudioVolumeGroups getAudioVolumeGroups();
- method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public int getMaxVolumeIndexForAttributes(@NonNull android.media.AudioAttributes);
- method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public int getMinVolumeIndexForAttributes(@NonNull android.media.AudioAttributes);
- method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public int getVolumeIndexForAttributes(@NonNull android.media.AudioAttributes);
+ method @IntRange(from=0) @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public int getMaxVolumeIndexForAttributes(@NonNull android.media.AudioAttributes);
+ method @IntRange(from=0) @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public int getMinVolumeIndexForAttributes(@NonNull android.media.AudioAttributes);
+ method @IntRange(from=0) @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public int getVolumeIndexForAttributes(@NonNull android.media.AudioAttributes);
method public boolean isAudioServerRunning();
method public boolean isHdmiSystemAudioSupported();
method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public int registerAudioPolicy(@NonNull android.media.audiopolicy.AudioPolicy);
diff --git a/core/java/android/app/ActivityOptions.java b/core/java/android/app/ActivityOptions.java
index da9ea8359854..926044bffdd0 100644
--- a/core/java/android/app/ActivityOptions.java
+++ b/core/java/android/app/ActivityOptions.java
@@ -33,7 +33,6 @@ import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.GraphicBuffer;
import android.graphics.Rect;
-import android.hardware.HardwareBuffer;
import android.os.Bundle;
import android.os.Handler;
import android.os.IRemoteCallback;
@@ -925,8 +924,7 @@ public class ActivityOptions {
// Unpackage the GraphicBuffer from the parceled thumbnail
final GraphicBuffer buffer = opts.getParcelable(KEY_ANIM_THUMBNAIL);
if (buffer != null) {
- mThumbnail = Bitmap.wrapHardwareBuffer(
- HardwareBuffer.createFromGraphicBuffer(buffer), null);
+ mThumbnail = Bitmap.wrapHardwareBuffer(buffer, null);
}
mStartX = opts.getInt(KEY_ANIM_START_X, 0);
mStartY = opts.getInt(KEY_ANIM_START_Y, 0);
diff --git a/core/java/android/app/AppComponentFactory.java b/core/java/android/app/AppComponentFactory.java
index 2cec7f0fc323..5b02817b7bfb 100644
--- a/core/java/android/app/AppComponentFactory.java
+++ b/core/java/android/app/AppComponentFactory.java
@@ -35,11 +35,22 @@ import android.content.pm.ApplicationInfo;
public class AppComponentFactory {
/**
- * Allows application to override the creation of the default class loader.
- * This can be used to perform things such as dependency injection or setting up
- * a custom class loader hierarchy.
+ * Selects the class loader which will be used by the platform to instantiate app components.
+ * <p>
+ * The default implementation of this method returns the {@code cl} parameter unchanged.
+ * Applications can override this method to set up a custom class loader or a custom class
+ * loader hierarchy and return it to the platform.
+ * <p>
+ * The method is a hook invoked before any application components are instantiated or the
+ * application Context is initialized. It is intended to allow the application's classes to
+ * be loaded from a different source than the base/split APK(s).
+ * <p>
+ * The default class loader {@code cl} is created by the platform and used to load the
+ * application's base or split APK(s). Its parent is typically the boot class loader, unless
+ * running under instrumentation. Its classname is configurable using the
+ * {@link android.R.attr#classLoader} manifest attribute.
*
- * @param cl The default classloader instantiated by platform.
+ * @param cl The default class loader created by the platform.
* @param aInfo Information about the application being loaded.
*/
public @NonNull ClassLoader instantiateClassLoader(@NonNull ClassLoader cl,
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index af738da20621..b97ea5f2a475 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -3820,10 +3820,7 @@ public abstract class Context {
/**
* Use with {@link #getSystemService(String)} to retrieve a {@link
- * android.net.wifi.rtt.WifiRttManager} for ranging devices with wifi
- *
- * Note: this is a replacement for WIFI_RTT_SERVICE above. It will
- * be renamed once final implementation in place.
+ * android.net.wifi.rtt.WifiRttManager} for ranging devices with wifi.
*
* @see #getSystemService(String)
* @see android.net.wifi.rtt.WifiRttManager
diff --git a/core/java/android/hardware/biometrics/CryptoObject.java b/core/java/android/hardware/biometrics/CryptoObject.java
index 496d9c57f252..787dc6696cd3 100644
--- a/core/java/android/hardware/biometrics/CryptoObject.java
+++ b/core/java/android/hardware/biometrics/CryptoObject.java
@@ -25,8 +25,8 @@ import javax.crypto.Cipher;
import javax.crypto.Mac;
/**
- * A wrapper class for the crypto objects supported by FingerprintManager. Currently the
- * framework supports {@link Signature}, {@link Cipher} and {@link Mac} objects.
+ * A wrapper class for the crypto objects supported by BiometricPrompt and FingerprintManager.
+ * Currently the framework supports {@link Signature}, {@link Cipher} and {@link Mac} objects.
* @hide
*/
public class CryptoObject {
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index e3b2d898f9b6..6326f2e6b2bb 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -1075,6 +1075,22 @@ public final class Settings {
"android.settings.ADD_ACCOUNT_SETTINGS";
/**
+ * Activity Action: Show settings for enabling or disabling data saver
+ * <p></p>
+ * In some cases, a matching Activity may not exist, so ensure you
+ * safeguard against this.
+ * <p>
+ * Input: Nothing.
+ * <p>
+ * Output: Nothing.
+ *
+ * @hide
+ */
+ @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
+ public static final String ACTION_DATA_SAVER_SETTINGS =
+ "android.settings.DATA_SAVER_SETTINGS";
+
+ /**
* Activity Action: Show settings for selecting the network operator.
* <p>
* In some cases, a matching Activity may not exist, so ensure you
diff --git a/core/java/android/service/contentsuggestions/ContentSuggestionsService.java b/core/java/android/service/contentsuggestions/ContentSuggestionsService.java
index 45a8466bfca1..55e61410b9e2 100644
--- a/core/java/android/service/contentsuggestions/ContentSuggestionsService.java
+++ b/core/java/android/service/contentsuggestions/ContentSuggestionsService.java
@@ -31,7 +31,6 @@ import android.app.contentsuggestions.SelectionsRequest;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.GraphicBuffer;
-import android.hardware.HardwareBuffer;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
@@ -67,8 +66,7 @@ public abstract class ContentSuggestionsService extends Service {
Bitmap wrappedBuffer = null;
if (contextImage != null) {
- wrappedBuffer = Bitmap.wrapHardwareBuffer(
- HardwareBuffer.createFromGraphicBuffer(contextImage), null);
+ wrappedBuffer = Bitmap.wrapHardwareBuffer(contextImage, null);
}
mHandler.sendMessage(
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index 79363edb0955..b5ad908e5ea5 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -41,7 +41,6 @@ import android.graphics.PixelFormat;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.Region;
-import android.hardware.HardwareBuffer;
import android.hardware.display.DisplayedContentSample;
import android.hardware.display.DisplayedContentSamplingAttributes;
import android.os.Build;
@@ -1917,9 +1916,7 @@ public final class SurfaceControl implements Parcelable {
Log.w(TAG, "Failed to take screenshot");
return null;
}
- return Bitmap.wrapHardwareBuffer(
- HardwareBuffer.createFromGraphicBuffer(buffer.getGraphicBuffer()),
- buffer.getColorSpace());
+ return Bitmap.wrapHardwareBuffer(buffer.getGraphicBuffer(), buffer.getColorSpace());
}
/**
diff --git a/core/java/com/android/internal/infra/AbstractRemoteService.java b/core/java/com/android/internal/infra/AbstractRemoteService.java
index ef5178aca40a..65a63a05f666 100644
--- a/core/java/com/android/internal/infra/AbstractRemoteService.java
+++ b/core/java/com/android/internal/infra/AbstractRemoteService.java
@@ -344,13 +344,21 @@ public abstract class AbstractRemoteService<S extends AbstractRemoteService<S, I
* {@link #getTimeoutIdleBindMillis() idle timeout} expires.
*/
protected void scheduleUnbind() {
- final long unbindDelay = getTimeoutIdleBindMillis();
+ scheduleUnbind(true);
+ }
+
+ private void scheduleUnbind(boolean delay) {
+ long unbindDelay = getTimeoutIdleBindMillis();
- if (unbindDelay <= 0) {
+ if (unbindDelay <= PERMANENT_BOUND_TIMEOUT_MS) {
if (mVerbose) Slog.v(mTag, "not scheduling unbind when value is " + unbindDelay);
return;
}
+ if (!delay) {
+ unbindDelay = 0;
+ }
+
cancelScheduledUnbind();
// TODO(b/117779333): make sure it's unbound if the service settings changing (right now
// it's not)
@@ -462,9 +470,16 @@ public abstract class AbstractRemoteService<S extends AbstractRemoteService<S, I
@Override
public void onServiceDisconnected(ComponentName name) {
+ if (mVerbose) Slog.v(mTag, "onServiceDisconnected()");
mBinding = true;
mService = null;
}
+
+ @Override
+ public void onBindingDied(ComponentName name) {
+ if (mVerbose) Slog.v(mTag, "onBindingDied()");
+ scheduleUnbind(false);
+ }
}
private boolean checkIfDestroyed() {
diff --git a/core/java/com/android/internal/os/RoSystemProperties.java b/core/java/com/android/internal/os/RoSystemProperties.java
index 1aef573f5189..b0855f494ffd 100644
--- a/core/java/com/android/internal/os/RoSystemProperties.java
+++ b/core/java/com/android/internal/os/RoSystemProperties.java
@@ -60,7 +60,7 @@ public class RoSystemProperties {
public static final boolean FW_SYSTEM_USER_SPLIT =
SystemProperties.getBoolean("ro.fw.system_user_split", false);
public static final boolean MULTIUSER_HEADLESS_SYSTEM_USER =
- SystemProperties.getBoolean("ro.fw.multiuser.headless_system_user", true);
+ SystemProperties.getBoolean("ro.fw.multiuser.headless_system_user", false);
// ------ ro.crypto.* -------- //
public static final CryptoProperties.state_values CRYPTO_STATE =
diff --git a/graphics/java/android/graphics/Bitmap.java b/graphics/java/android/graphics/Bitmap.java
index 170dec26f361..07f81c18e1ca 100644
--- a/graphics/java/android/graphics/Bitmap.java
+++ b/graphics/java/android/graphics/Bitmap.java
@@ -763,6 +763,18 @@ public final class Bitmap implements Parcelable {
}
/**
+ * Utility method to create a hardware backed bitmap using the graphics buffer.
+ * @hide
+ */
+ @Nullable
+ public static Bitmap wrapHardwareBuffer(@NonNull GraphicBuffer graphicBuffer,
+ @Nullable ColorSpace colorSpace) {
+ try (HardwareBuffer hb = HardwareBuffer.createFromGraphicBuffer(graphicBuffer)) {
+ return wrapHardwareBuffer(hb, colorSpace);
+ }
+ }
+
+ /**
* Creates a new bitmap, scaled from an existing bitmap, when possible. If the
* specified width and height are the same as the current width and height of
* the source bitmap, the source bitmap is returned and no new bitmap is
diff --git a/keystore/java/android/security/keystore/KeyGenParameterSpec.java b/keystore/java/android/security/keystore/KeyGenParameterSpec.java
index c4df2744eed9..bd6ce7ec6a3b 100644
--- a/keystore/java/android/security/keystore/KeyGenParameterSpec.java
+++ b/keystore/java/android/security/keystore/KeyGenParameterSpec.java
@@ -22,7 +22,8 @@ import android.annotation.Nullable;
import android.annotation.TestApi;
import android.annotation.UnsupportedAppUsage;
import android.app.KeyguardManager;
-import android.hardware.fingerprint.FingerprintManager;
+import android.hardware.biometrics.BiometricManager;
+import android.hardware.biometrics.BiometricPrompt;
import android.security.GateKeeper;
import android.security.KeyStore;
import android.text.TextUtils;
@@ -670,9 +671,9 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu
}
/**
- * Returns {@code true} if the key is irreversibly invalidated when a new fingerprint is
- * enrolled or all enrolled fingerprints are removed. This has effect only for keys that
- * require fingerprint user authentication for every use.
+ * Returns {@code true} if the key is irreversibly invalidated when a new biometric is
+ * enrolled or all enrolled biometrics are removed. This has effect only for keys that
+ * require biometric user authentication for every use.
*
* @see #isUserAuthenticationRequired()
* @see #getUserAuthenticationValidityDurationSeconds()
@@ -1098,19 +1099,19 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu
* <li>The key can only be generated if secure lock screen is set up (see
* {@link KeyguardManager#isDeviceSecure()}). Additionally, if the key requires that user
* authentication takes place for every use of the key (see
- * {@link #setUserAuthenticationValidityDurationSeconds(int)}), at least one fingerprint
- * must be enrolled (see {@link FingerprintManager#hasEnrolledFingerprints()}).</li>
+ * {@link #setUserAuthenticationValidityDurationSeconds(int)}), at least one biometric
+ * must be enrolled (see {@link BiometricManager#canAuthenticate()}).</li>
* <li>The use of the key must be authorized by the user by authenticating to this Android
* device using a subset of their secure lock screen credentials such as
- * password/PIN/pattern or fingerprint.
+ * password/PIN/pattern or biometric.
* <a href="{@docRoot}training/articles/keystore.html#UserAuthentication">More
* information</a>.
* <li>The key will become <em>irreversibly invalidated</em> once the secure lock screen is
* disabled (reconfigured to None, Swipe or other mode which does not authenticate the user)
* or when the secure lock screen is forcibly reset (e.g., by a Device Administrator).
* Additionally, if the key requires that user authentication takes place for every use of
- * the key, it is also irreversibly invalidated once a new fingerprint is enrolled or once\
- * no more fingerprints are enrolled, unless {@link
+ * the key, it is also irreversibly invalidated once a new biometric is enrolled or once\
+ * no more biometrics are enrolled, unless {@link
* #setInvalidatedByBiometricEnrollment(boolean)} is used to allow validity after
* enrollment. Attempts to initialize cryptographic operations using such keys will throw
* {@link KeyPermanentlyInvalidatedException}.</li>
@@ -1121,7 +1122,7 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu
*
* @see #setUserAuthenticationValidityDurationSeconds(int)
* @see KeyguardManager#isDeviceSecure()
- * @see FingerprintManager#hasEnrolledFingerprints()
+ * @see BiometricManager#canAuthenticate()
*/
@NonNull
public Builder setUserAuthenticationRequired(boolean required) {
@@ -1161,10 +1162,10 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu
* the key.
*
* <p>Cryptographic operations involving keys which require user authentication to take
- * place for every operation can only use fingerprint authentication. This is achieved by
+ * place for every operation can only use biometric authentication. This is achieved by
* initializing a cryptographic operation ({@link Signature}, {@link Cipher}, {@link Mac})
- * with the key, wrapping it into a {@link FingerprintManager.CryptoObject}, invoking
- * {@code FingerprintManager.authenticate} with {@code CryptoObject}, and proceeding with
+ * with the key, wrapping it into a {@link BiometricPrompt.CryptoObject}, invoking
+ * {@code BiometricPrompt.authenticate} with {@code CryptoObject}, and proceeding with
* the cryptographic operation only if the authentication flow succeeds.
*
* <p>Cryptographic operations involving keys which are authorized to be used for a duration
@@ -1183,8 +1184,8 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu
* for every use of the key.
*
* @see #setUserAuthenticationRequired(boolean)
- * @see FingerprintManager
- * @see FingerprintManager.CryptoObject
+ * @see BiometricPrompt
+ * @see BiometricPrompt.CryptoObject
* @see KeyguardManager
*/
@NonNull
@@ -1286,20 +1287,20 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu
}
/**
- * Sets whether this key should be invalidated on fingerprint enrollment. This
+ * Sets whether this key should be invalidated on biometric enrollment. This
* applies only to keys which require user authentication (see {@link
* #setUserAuthenticationRequired(boolean)}) and if no positive validity duration has been
* set (see {@link #setUserAuthenticationValidityDurationSeconds(int)}, meaning the key is
- * valid for fingerprint authentication only.
+ * valid for biometric authentication only.
*
* <p>By default, {@code invalidateKey} is {@code true}, so keys that are valid for
- * fingerprint authentication only are <em>irreversibly invalidated</em> when a new
- * fingerprint is enrolled, or when all existing fingerprints are deleted. That may be
+ * biometric authentication only are <em>irreversibly invalidated</em> when a new
+ * biometric is enrolled, or when all existing biometrics are deleted. That may be
* changed by calling this method with {@code invalidateKey} set to {@code false}.
*
- * <p>Invalidating keys on enrollment of a new finger or unenrollment of all fingers
+ * <p>Invalidating keys on enrollment of a new biometric or unenrollment of all biometrics
* improves security by ensuring that an unauthorized person who obtains the password can't
- * gain the use of fingerprint-authenticated keys by enrolling their own finger. However,
+ * gain the use of biometric-authenticated keys by enrolling their own biometric. However,
* invalidating keys makes key-dependent operations impossible, requiring some fallback
* procedure to authenticate the user and set up a new key.
*/
@@ -1322,7 +1323,7 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu
* Sets whether the keystore requires the screen to be unlocked before allowing decryption
* using this key. If this is set to {@code true}, any attempt to decrypt or sign using this
* key while the screen is locked will fail. A locked device requires a PIN, password,
- * fingerprint, or other trusted factor to access. While the screen is locked, the key can
+ * biometric, or other trusted factor to access. While the screen is locked, the key can
* still be used for encryption or signature verification.
*/
@NonNull
diff --git a/keystore/java/android/security/keystore/KeyProtection.java b/keystore/java/android/security/keystore/KeyProtection.java
index 3357fdf46e20..26181a65dc1d 100644
--- a/keystore/java/android/security/keystore/KeyProtection.java
+++ b/keystore/java/android/security/keystore/KeyProtection.java
@@ -21,12 +21,13 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.TestApi;
import android.app.KeyguardManager;
-import android.hardware.fingerprint.FingerprintManager;
+import android.hardware.biometrics.BiometricManager;
+import android.hardware.biometrics.BiometricPrompt;
import android.security.GateKeeper;
import java.security.Key;
-import java.security.Signature;
import java.security.KeyStore.ProtectionParameter;
+import java.security.Signature;
import java.security.cert.Certificate;
import java.util.Date;
@@ -479,9 +480,9 @@ public final class KeyProtection implements ProtectionParameter, UserAuthArgs {
}
/**
- * Returns {@code true} if the key is irreversibly invalidated when a new fingerprint is
- * enrolled or all enrolled fingerprints are removed. This has effect only for keys that
- * require fingerprint user authentication for every use.
+ * Returns {@code true} if the key is irreversibly invalidated when a new biometric is
+ * enrolled or all enrolled biometrics are removed. This has effect only for keys that
+ * require biometric user authentication for every use.
*
* @see #isUserAuthenticationRequired()
* @see #getUserAuthenticationValidityDurationSeconds()
@@ -496,7 +497,7 @@ public final class KeyProtection implements ProtectionParameter, UserAuthArgs {
*
* Normally an authentication-bound key is tied to the secure user id of the current user
* (either the root SID from GateKeeper for auth-bound keys with a timeout, or the authenticator
- * id of the current fingerprint set for keys requiring explicit fingerprint authorization).
+ * id of the current biometric set for keys requiring explicit biometric authorization).
* If this parameter is set (this method returning non-zero value), the key should be tied to
* the specified secure user id, overriding the logic above.
*
@@ -762,19 +763,19 @@ public final class KeyProtection implements ProtectionParameter, UserAuthArgs {
* <li>The key can only be import if secure lock screen is set up (see
* {@link KeyguardManager#isDeviceSecure()}). Additionally, if the key requires that user
* authentication takes place for every use of the key (see
- * {@link #setUserAuthenticationValidityDurationSeconds(int)}), at least one fingerprint
- * must be enrolled (see {@link FingerprintManager#hasEnrolledFingerprints()}).</li>
+ * {@link #setUserAuthenticationValidityDurationSeconds(int)}), at least one biometric
+ * must be enrolled (see {@link BiometricManager#canAuthenticate()}).</li>
* <li>The use of the key must be authorized by the user by authenticating to this Android
* device using a subset of their secure lock screen credentials such as
- * password/PIN/pattern or fingerprint.
+ * password/PIN/pattern or biometric.
* <a href="{@docRoot}training/articles/keystore.html#UserAuthentication">More
* information</a>.
* <li>The key will become <em>irreversibly invalidated</em> once the secure lock screen is
* disabled (reconfigured to None, Swipe or other mode which does not authenticate the user)
* or when the secure lock screen is forcibly reset (e.g., by a Device Administrator).
* Additionally, if the key requires that user authentication takes place for every use of
- * the key, it is also irreversibly invalidated once a new fingerprint is enrolled or once\
- * no more fingerprints are enrolled, unless {@link
+ * the key, it is also irreversibly invalidated once a new biometric is enrolled or once\
+ * no more biometrics are enrolled, unless {@link
* #setInvalidatedByBiometricEnrollment(boolean)} is used to allow validity after
* enrollment. Attempts to initialize cryptographic operations using such keys will throw
* {@link KeyPermanentlyInvalidatedException}.</li> </ul>
@@ -784,7 +785,7 @@ public final class KeyProtection implements ProtectionParameter, UserAuthArgs {
*
* @see #setUserAuthenticationValidityDurationSeconds(int)
* @see KeyguardManager#isDeviceSecure()
- * @see FingerprintManager#hasEnrolledFingerprints()
+ * @see BiometricManager#canAuthenticate()
*/
@NonNull
public Builder setUserAuthenticationRequired(boolean required) {
@@ -824,10 +825,10 @@ public final class KeyProtection implements ProtectionParameter, UserAuthArgs {
* the key.
*
* <p>Cryptographic operations involving keys which require user authentication to take
- * place for every operation can only use fingerprint authentication. This is achieved by
+ * place for every operation can only use biometric authentication. This is achieved by
* initializing a cryptographic operation ({@link Signature}, {@link Cipher}, {@link Mac})
- * with the key, wrapping it into a {@link FingerprintManager.CryptoObject}, invoking
- * {@code FingerprintManager.authenticate} with {@code CryptoObject}, and proceeding with
+ * with the key, wrapping it into a {@link BiometricPrompt.CryptoObject}, invoking
+ * {@code BiometricPrompt.authenticate} with {@code CryptoObject}, and proceeding with
* the cryptographic operation only if the authentication flow succeeds.
*
* <p>Cryptographic operations involving keys which are authorized to be used for a duration
@@ -846,8 +847,8 @@ public final class KeyProtection implements ProtectionParameter, UserAuthArgs {
* for every use of the key.
*
* @see #setUserAuthenticationRequired(boolean)
- * @see FingerprintManager
- * @see FingerprintManager.CryptoObject
+ * @see BiometricPrompt
+ * @see BiometricPrompt.CryptoObject
* @see KeyguardManager
*/
@NonNull
@@ -902,20 +903,20 @@ public final class KeyProtection implements ProtectionParameter, UserAuthArgs {
}
/**
- * Sets whether this key should be invalidated on fingerprint enrollment. This
+ * Sets whether this key should be invalidated on biometric enrollment. This
* applies only to keys which require user authentication (see {@link
* #setUserAuthenticationRequired(boolean)}) and if no positive validity duration has been
* set (see {@link #setUserAuthenticationValidityDurationSeconds(int)}, meaning the key is
- * valid for fingerprint authentication only.
+ * valid for biometric authentication only.
*
* <p>By default, {@code invalidateKey} is {@code true}, so keys that are valid for
- * fingerprint authentication only are <em>irreversibly invalidated</em> when a new
- * fingerprint is enrolled, or when all existing fingerprints are deleted. That may be
+ * biometric authentication only are <em>irreversibly invalidated</em> when a new
+ * biometric is enrolled, or when all existing biometrics are deleted. That may be
* changed by calling this method with {@code invalidateKey} set to {@code false}.
*
- * <p>Invalidating keys on enrollment of a new finger or unenrollment of all fingers
+ * <p>Invalidating keys on enrollment of a new biometric or unenrollment of all biometrics
* improves security by ensuring that an unauthorized person who obtains the password can't
- * gain the use of fingerprint-authenticated keys by enrolling their own finger. However,
+ * gain the use of biometric-authenticated keys by enrolling their own biometric. However,
* invalidating keys makes key-dependent operations impossible, requiring some fallback
* procedure to authenticate the user and set up a new key.
*/
@@ -930,7 +931,7 @@ public final class KeyProtection implements ProtectionParameter, UserAuthArgs {
*
* Normally an authentication-bound key is tied to the secure user id of the current user
* (either the root SID from GateKeeper for auth-bound keys with a timeout, or the
- * authenticator id of the current fingerprint set for keys requiring explicit fingerprint
+ * authenticator id of the current biometric set for keys requiring explicit biometric
* authorization). If this parameter is set (this method returning non-zero value), the key
* should be tied to the specified secure user id, overriding the logic above.
*
@@ -964,7 +965,7 @@ public final class KeyProtection implements ProtectionParameter, UserAuthArgs {
* Sets whether the keystore requires the screen to be unlocked before allowing decryption
* using this key. If this is set to {@code true}, any attempt to decrypt or sign using this
* key while the screen is locked will fail. A locked device requires a PIN, password,
- * fingerprint, or other trusted factor to access. While the screen is locked, the key can
+ * biometric, or other trusted factor to access. While the screen is locked, the key can
* still be used for encryption or signature verification.
*/
@NonNull
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index dc5c6639375b..a5a409286754 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -17,6 +17,7 @@
package android.media;
import android.annotation.IntDef;
+import android.annotation.IntRange;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
@@ -1204,6 +1205,7 @@ public class AudioManager {
* @hide
*/
@SystemApi
+ @IntRange(from = 0)
@RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
public int getVolumeIndexForAttributes(@NonNull AudioAttributes attr) {
Preconditions.checkNotNull(attr, "attr must not be null");
@@ -1224,6 +1226,7 @@ public class AudioManager {
* @hide
*/
@SystemApi
+ @IntRange(from = 0)
@RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
public int getMaxVolumeIndexForAttributes(@NonNull AudioAttributes attr) {
Preconditions.checkNotNull(attr, "attr must not be null");
@@ -1244,6 +1247,7 @@ public class AudioManager {
* @hide
*/
@SystemApi
+ @IntRange(from = 0)
@RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
public int getMinVolumeIndexForAttributes(@NonNull AudioAttributes attr) {
Preconditions.checkNotNull(attr, "attr must not be null");
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/ThumbnailData.java b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/ThumbnailData.java
index 1413ac1433f1..98a8110209e6 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/ThumbnailData.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/ThumbnailData.java
@@ -23,7 +23,6 @@ import static com.android.systemui.shared.system.WindowManagerWrapper.WINDOWING_
import android.app.ActivityManager.TaskSnapshot;
import android.graphics.Bitmap;
import android.graphics.Rect;
-import android.hardware.HardwareBuffer;
/**
* Data for a single thumbnail.
@@ -53,9 +52,7 @@ public class ThumbnailData {
}
public ThumbnailData(TaskSnapshot snapshot) {
- thumbnail = Bitmap.wrapHardwareBuffer(
- HardwareBuffer.createFromGraphicBuffer(snapshot.getSnapshot()),
- snapshot.getColorSpace());
+ thumbnail = Bitmap.wrapHardwareBuffer(snapshot.getSnapshot(), snapshot.getColorSpace());
insets = new Rect(snapshot.getContentInsets());
orientation = snapshot.getOrientation();
reducedResolution = snapshot.isReducedResolution();
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
index 38962eb14705..20e002edfe02 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
@@ -25,6 +25,7 @@ import android.content.Intent;
import android.content.res.Resources;
import android.provider.Settings;
import android.service.quicksettings.Tile;
+import android.telephony.SubscriptionManager;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
@@ -285,7 +286,13 @@ public class CellularTile extends QSTileImpl<SignalState> {
}
static Intent getCellularSettingIntent() {
- return new Intent(Settings.ACTION_DATA_USAGE_SETTINGS);
+ Intent intent = new Intent(Settings.ACTION_NETWORK_OPERATOR_SETTINGS);
+ int dataSub = SubscriptionManager.getDefaultDataSubscriptionId();
+ if (dataSub != SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
+ intent.putExtra(Settings.EXTRA_SUB_ID,
+ SubscriptionManager.getDefaultDataSubscriptionId());
+ }
+ return intent;
}
private final class CellularDetailAdapter implements DetailAdapter {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/DataSaverTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/DataSaverTile.java
index c6c6f877ac9b..79996bcfa808 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/DataSaverTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/DataSaverTile.java
@@ -16,6 +16,7 @@ package com.android.systemui.qs.tiles;
import android.content.DialogInterface.OnClickListener;
import android.content.Intent;
+import android.provider.Settings;
import android.service.quicksettings.Tile;
import android.widget.Switch;
@@ -54,7 +55,7 @@ public class DataSaverTile extends QSTileImpl<BooleanState> implements
@Override
public Intent getLongClickIntent() {
- return CellularTile.getCellularSettingIntent();
+ return new Intent(Settings.ACTION_DATA_SAVER_SETTINGS);
}
@Override
protected void handleClick() {
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 c75a462d5bc1..dd63e3ca290e 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
@@ -18,12 +18,6 @@ package com.android.server.pm.permission;
import static android.Manifest.permission.READ_EXTERNAL_STORAGE;
import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE;
-import static android.app.AppOpsManager.MODE_ALLOWED;
-import static android.app.AppOpsManager.MODE_ERRORED;
-import static android.app.AppOpsManager.MODE_FOREGROUND;
-import static android.app.AppOpsManager.OP_NONE;
-import static android.app.AppOpsManager.permissionToOp;
-import static android.app.AppOpsManager.permissionToOpCode;
import static android.content.pm.PackageManager.FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT;
import static android.content.pm.PackageManager.FLAG_PERMISSION_APPLY_RESTRICTION;
import static android.content.pm.PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
@@ -40,8 +34,6 @@ import static android.content.pm.PackageManager.FLAG_PERMISSION_WHITELIST_UPGRAD
import static android.content.pm.PackageManager.MASK_PERMISSION_FLAGS_ALL;
import static android.content.pm.PackageManager.RESTRICTED_PERMISSIONS_ENABLED;
import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER;
-import static android.os.UserHandle.getAppId;
-import static android.os.UserHandle.getUid;
import static com.android.server.pm.PackageManagerService.DEBUG_INSTALL;
import static com.android.server.pm.PackageManagerService.DEBUG_PACKAGE_SCANNING;
@@ -56,8 +48,6 @@ import android.Manifest;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.UserIdInt;
-import android.app.AppOpsManager;
-import android.app.AppOpsManagerInternal;
import android.content.Context;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.PermissionWhitelistFlags;
@@ -1309,9 +1299,6 @@ public class PermissionManagerService {
updatedUserIds);
updatedUserIds = setInitialGrantForNewImplicitPermissionsLocked(origPermissions,
permissionsState, pkg, updatedUserIds);
-
- // TODO: Move to PermissionPolicyService
- setAppOpsLocked(permissionsState, pkg);
}
// Persist the runtime permissions state for users with changes. If permissions
@@ -1327,23 +1314,6 @@ public class PermissionManagerService {
}
/**
- * Set app op for a app-op related to a permission.
- *
- * @param permission The permission the app-op belongs to
- * @param pkg The package the permission belongs to
- * @param userId The user to be changed
- * @param mode The new mode to set
- */
- private void setAppOpMode(@NonNull String permission, @NonNull PackageParser.Package pkg,
- @UserIdInt int userId, int mode) {
- AppOpsManagerInternal appOpsInternal = LocalServices.getService(
- AppOpsManagerInternal.class);
-
- appOpsInternal.setUidMode(permissionToOpCode(permission),
- getUid(userId, getAppId(pkg.applicationInfo.uid)), mode);
- }
-
- /**
* Revoke permissions that are not implicit anymore and that have
* {@link PackageManager#FLAG_PERMISSION_REVOKE_WHEN_REQUESTED} set.
*
@@ -1357,8 +1327,6 @@ public class PermissionManagerService {
private @NonNull int[] revokePermissionsNoLongerImplicitLocked(
@NonNull PermissionsState ps, @NonNull PackageParser.Package pkg,
@NonNull int[] updatedUserIds) {
- AppOpsManager appOpsManager = mContext.getSystemService(AppOpsManager.class);
-
String pkgName = pkg.packageName;
boolean supportsRuntimePermissions = pkg.applicationInfo.targetSdkVersion
>= Build.VERSION_CODES.M;
@@ -1390,23 +1358,6 @@ public class PermissionManagerService {
}
flagsToRemove |= USER_PERMISSION_FLAGS;
-
- List<String> fgPerms = mBackgroundPermissions.get(permission);
- if (fgPerms != null) {
- int numFgPerms = fgPerms.size();
- for (int fgPermNum = 0; fgPermNum < numFgPerms; fgPermNum++) {
- String fgPerm = fgPerms.get(fgPermNum);
-
- int mode = appOpsManager.unsafeCheckOpRaw(
- permissionToOp(fgPerm),
- getUid(userId, getAppId(pkg.applicationInfo.uid)),
- pkgName);
-
- if (mode == MODE_ALLOWED) {
- setAppOpMode(fgPerm, pkg, userId, MODE_FOREGROUND);
- }
- }
- }
}
ps.updatePermissionFlags(bp, userId, flagsToRemove, 0);
@@ -1438,91 +1389,39 @@ public class PermissionManagerService {
@NonNull ArraySet<String> sourcePerms, @NonNull String newPerm,
@NonNull PermissionsState ps, @NonNull PackageParser.Package pkg,
@UserIdInt int userId) {
- AppOpsManagerInternal appOpsManager = LocalServices.getService(AppOpsManagerInternal.class);
String pkgName = pkg.packageName;
+ boolean isGranted = false;
+ int flags = 0;
- if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
- if (permissionToOp(newPerm) != null) {
- int mostLenientSourceMode = MODE_ERRORED;
- int flags = 0;
-
- // Find most lenient source permission state.
- int numSourcePerms = sourcePerms.size();
- for (int i = 0; i < numSourcePerms; i++) {
- String sourcePerm = sourcePerms.valueAt(i);
-
- if (ps.hasRuntimePermission(sourcePerm, userId)) {
- int sourceOp = permissionToOpCode(sourcePerm);
-
- if (sourceOp != OP_NONE) {
- int mode = appOpsManager.checkOperationUnchecked(sourceOp,
- getUid(userId, getAppId(pkg.applicationInfo.uid)), pkgName);
-
- if (mode == MODE_FOREGROUND || mode == MODE_ERRORED) {
- Log.wtf(TAG, "split permission" + sourcePerm + " has app-op state "
- + AppOpsManager.MODE_NAMES[mode]);
-
- continue;
- }
-
- // Leniency order: allowed < ignored < default
- if (mode < mostLenientSourceMode) {
- mostLenientSourceMode = mode;
- flags = ps.getPermissionFlags(sourcePerm, userId);
- } else if (mode == mostLenientSourceMode) {
- flags |= ps.getPermissionFlags(sourcePerm, userId);
- }
- }
- }
+ int numSourcePerm = sourcePerms.size();
+ for (int i = 0; i < numSourcePerm; i++) {
+ String sourcePerm = sourcePerms.valueAt(i);
+ if ((ps.hasRuntimePermission(sourcePerm, userId))
+ || ps.hasInstallPermission(sourcePerm)) {
+ if (!isGranted) {
+ flags = 0;
}
- if (mostLenientSourceMode != MODE_ERRORED) {
- if (DEBUG_PERMISSIONS) {
- Slog.i(TAG, newPerm + " inherits app-ops state " + mostLenientSourceMode
- + " from " + sourcePerms + " for " + pkgName);
- }
-
- setAppOpMode(newPerm, pkg, userId, mostLenientSourceMode);
-
- // Add permission flags
- ps.updatePermissionFlags(mSettings.getPermission(newPerm), userId, flags,
- flags);
- }
- }
- } else {
- boolean isGranted = false;
- int flags = 0;
-
- int numSourcePerm = sourcePerms.size();
- for (int i = 0; i < numSourcePerm; i++) {
- String sourcePerm = sourcePerms.valueAt(i);
- if ((ps.hasRuntimePermission(sourcePerm, userId))
- || ps.hasInstallPermission(sourcePerm)) {
- if (!isGranted) {
- flags = 0;
- }
-
- isGranted = true;
+ isGranted = true;
+ flags |= ps.getPermissionFlags(sourcePerm, userId);
+ } else {
+ if (!isGranted) {
flags |= ps.getPermissionFlags(sourcePerm, userId);
- } else {
- if (!isGranted) {
- flags |= ps.getPermissionFlags(sourcePerm, userId);
- }
}
}
+ }
- if (isGranted) {
- if (DEBUG_PERMISSIONS) {
- Slog.i(TAG, newPerm + " inherits runtime perm grant from " + sourcePerms
- + " for " + pkgName);
- }
-
- ps.grantRuntimePermission(mSettings.getPermissionLocked(newPerm), userId);
+ if (isGranted) {
+ if (DEBUG_PERMISSIONS) {
+ Slog.i(TAG, newPerm + " inherits runtime perm grant from " + sourcePerms
+ + " for " + pkgName);
}
- // Add permission flags
- ps.updatePermissionFlags(mSettings.getPermission(newPerm), userId, flags, flags);
+ ps.grantRuntimePermission(mSettings.getPermissionLocked(newPerm), userId);
}
+
+ // Add permission flags
+ ps.updatePermissionFlags(mSettings.getPermission(newPerm), userId, flags, flags);
}
/**
@@ -1632,48 +1531,6 @@ public class PermissionManagerService {
return updatedUserIds;
}
- /**
- * Fix app-op modes for runtime permissions.
- *
- * @param permsState The state of the permissions of the package
- * @param pkg The package information
- */
- private void setAppOpsLocked(@NonNull PermissionsState permsState,
- @NonNull PackageParser.Package pkg) {
- for (int userId : UserManagerService.getInstance().getUserIds()) {
- int numPerms = pkg.requestedPermissions.size();
- for (int i = 0; i < numPerms; i++) {
- String permission = pkg.requestedPermissions.get(i);
-
- // For pre-M apps the runtime permission do not store the state
- if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
- continue;
- }
-
- PermissionState state = permsState.getRuntimePermissionState(permission, userId);
- if (state == null) {
- continue;
- }
-
- // Adjust app-op mods for foreground/background permissions. If an package used to
- // have both fg and bg permission granted and it lost the bg permission during an
- // upgrade the app-op mode should get downgraded to foreground.
- if (state.isGranted()) {
- BasePermission bp = mSettings.getPermission(permission);
-
- if (bp != null && bp.perm != null && bp.perm.info != null
- && bp.perm.info.backgroundPermission != null) {
- PermissionState bgState = permsState.getRuntimePermissionState(
- bp.perm.info.backgroundPermission, userId);
-
- setAppOpMode(permission, pkg, userId, bgState != null && bgState.isGranted()
- ? MODE_ALLOWED : MODE_FOREGROUND);
- }
- }
- }
- }
- }
-
private boolean isNewPlatformPermissionForPackage(String perm, PackageParser.Package pkg) {
boolean allowed = false;
final int NP = PackageParser.NEW_PERMISSIONS.length;
diff --git a/services/core/java/com/android/server/policy/PermissionPolicyService.java b/services/core/java/com/android/server/policy/PermissionPolicyService.java
index 67f30dc2e9fc..1fd8b711d348 100644
--- a/services/core/java/com/android/server/policy/PermissionPolicyService.java
+++ b/services/core/java/com/android/server/policy/PermissionPolicyService.java
@@ -17,8 +17,10 @@
package com.android.server.policy;
import static android.content.pm.PackageManager.FLAG_PERMISSION_APPLY_RESTRICTION;
+import static android.content.pm.PackageManager.GET_PERMISSIONS;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.annotation.UserIdInt;
import android.app.AppOpsManager;
import android.content.Context;
@@ -29,6 +31,7 @@ import android.content.pm.PackageManagerInternal;
import android.content.pm.PackageManagerInternal.PackageListObserver;
import android.content.pm.PackageParser;
import android.content.pm.PermissionInfo;
+import android.os.Build;
import android.os.Process;
import android.os.UserHandle;
import android.permission.PermissionControllerManager;
@@ -158,37 +161,59 @@ public final class PermissionPolicyService extends SystemService {
});
}
+ private static @Nullable Context getUserContext(@NonNull Context context,
+ @NonNull UserHandle user) {
+ if (context.getUser().equals(user)) {
+ return context;
+ } else {
+ try {
+ return context.createPackageContextAsUser(context.getPackageName(), 0, user);
+ } catch (NameNotFoundException e) {
+ Slog.e(LOG_TAG, "Cannot create context for user " + user, e);
+ return null;
+ }
+ }
+ }
+
+ /**
+ * Synchronize a single package.
+ */
private static void synchronizePackagePermissionsAndAppOpsForUser(@NonNull Context context,
@NonNull String packageName, @UserIdInt int userId) {
final PackageManagerInternal packageManagerInternal = LocalServices.getService(
PackageManagerInternal.class);
- final PackageParser.Package pkg = packageManagerInternal.getPackage(packageName);
+ final PackageInfo pkg = packageManagerInternal.getPackageInfo(packageName, 0,
+ Process.SYSTEM_UID, userId);
if (pkg == null) {
return;
}
- final PermissionToOpSynchroniser synchroniser = new PermissionToOpSynchroniser(context);
- synchroniser.addPackage(context, pkg, userId);
+ final PermissionToOpSynchroniser synchroniser = new PermissionToOpSynchroniser(
+ getUserContext(context, UserHandle.of(userId)));
+ synchroniser.addPackage(pkg.packageName);
final String[] sharedPkgNames = packageManagerInternal.getPackagesForSharedUserId(
- pkg.mSharedUserId, userId);
+ pkg.sharedUserId, userId);
if (sharedPkgNames != null) {
for (String sharedPkgName : sharedPkgNames) {
final PackageParser.Package sharedPkg = packageManagerInternal
.getPackage(sharedPkgName);
if (sharedPkg != null) {
- synchroniser.addPackage(context, sharedPkg, userId);
+ synchroniser.addPackage(sharedPkg.packageName);
}
}
}
synchroniser.syncPackages();
}
+ /**
+ * Synchronize all packages
+ */
private static void synchronizePermissionsAndAppOpsForUser(@NonNull Context context,
@UserIdInt int userId) {
final PackageManagerInternal packageManagerInternal = LocalServices.getService(
PackageManagerInternal.class);
- final PermissionToOpSynchroniser synchronizer = new PermissionToOpSynchroniser(context);
- packageManagerInternal.forEachPackage((pkg) ->
- synchronizer.addPackage(context, pkg, userId));
+ final PermissionToOpSynchroniser synchronizer = new PermissionToOpSynchroniser(
+ getUserContext(context, UserHandle.of(userId)));
+ packageManagerInternal.forEachPackage((pkg) -> synchronizer.addPackage(pkg.packageName));
synchronizer.syncPackages();
}
@@ -198,17 +223,47 @@ public final class PermissionPolicyService extends SystemService {
*/
private static class PermissionToOpSynchroniser {
private final @NonNull Context mContext;
-
- private final @NonNull SparseIntArray mUids = new SparseIntArray();
- private final @NonNull SparseArray<String> mPackageNames = new SparseArray<>();
- private final @NonNull SparseIntArray mAllowedUidOps = new SparseIntArray();
- private final @NonNull SparseIntArray mDefaultUidOps = new SparseIntArray();
+ private final @NonNull PackageManager mPackageManager;
+ private final @NonNull AppOpsManager mAppOpsManager;
+
+ /** All uid that need to be synchronized */
+ private final @NonNull SparseIntArray mAllUids = new SparseIntArray();
+
+ /**
+ * All ops that need to be restricted
+ *
+ * @see #syncRestrictedOps
+ */
+ private final @NonNull ArrayList<OpToRestrict> mOpsToRestrict = new ArrayList<>();
+
+ /**
+ * All ops that need to be unrestricted
+ *
+ * @see #syncRestrictedOps
+ */
+ private final @NonNull ArrayList<OpToUnrestrict> mOpsToUnrestrict = new ArrayList<>();
+
+ /**
+ * All foreground permissions
+ *
+ * @see #syncOpsOfFgPermissions()
+ */
+ private final @NonNull ArrayList<FgPermission> mFgPermOps = new ArrayList<>();
PermissionToOpSynchroniser(@NonNull Context context) {
mContext = context;
+ mPackageManager = context.getPackageManager();
+ mAppOpsManager = context.getSystemService(AppOpsManager.class);
}
- void syncPackages() {
+ /**
+ * Set app ops that belong to restricted permissions.
+ *
+ * <p>This processes ops previously added by {@link #addOpIfRestricted}
+ */
+ private void syncRestrictedOps() {
+ final SparseIntArray unprocessedUids = mAllUids.clone();
+
// TRICKY: we set the app op for a restricted permission to allow if the app
// requesting the permission is whitelisted and to deny if the app requesting
// the permission is not whitelisted. However, there is another case where an
@@ -222,52 +277,48 @@ public final class PermissionPolicyService extends SystemService {
final SparseArray<List<String>> unrequestedRestrictedPermissionsForUid =
new SparseArray<>();
- final AppOpsManager appOpsManager = mContext.getSystemService(AppOpsManager.class);
- final int allowedCount = mAllowedUidOps.size();
- for (int i = 0; i < allowedCount; i++) {
- final int opCode = mAllowedUidOps.keyAt(i);
- final int uid = mAllowedUidOps.valueAt(i);
- final String packageName = mPackageNames.valueAt(i);
- setUidModeAllowed(appOpsManager, opCode, uid, packageName);
+ final int unrestrictCount = mOpsToUnrestrict.size();
+ for (int i = 0; i < unrestrictCount; i++) {
+ final OpToUnrestrict op = mOpsToUnrestrict.get(i);
+ setUidModeAllowed(op.code, op.uid, op.packageName);
// Keep track this permission was requested by the UID.
List<String> unrequestedRestrictedPermissions =
- unrequestedRestrictedPermissionsForUid.get(uid);
+ unrequestedRestrictedPermissionsForUid.get(op.uid);
if (unrequestedRestrictedPermissions == null) {
unrequestedRestrictedPermissions = new ArrayList<>(sAllRestrictedPermissions);
- unrequestedRestrictedPermissionsForUid.put(uid,
+ unrequestedRestrictedPermissionsForUid.put(op.uid,
unrequestedRestrictedPermissions);
}
- unrequestedRestrictedPermissions.remove(AppOpsManager.opToPermission(opCode));
+ unrequestedRestrictedPermissions.remove(AppOpsManager.opToPermission(op.code));
- mUids.delete(uid);
+ unprocessedUids.delete(op.uid);
}
- final int defaultCount = mDefaultUidOps.size();
- for (int i = 0; i < defaultCount; i++) {
- final int opCode = mDefaultUidOps.keyAt(i);
- final int uid = mDefaultUidOps.valueAt(i);
- setUidModeDefault(appOpsManager, opCode, uid);
+ final int restrictCount = mOpsToRestrict.size();
+ for (int i = 0; i < restrictCount; i++) {
+ final OpToRestrict op = mOpsToRestrict.get(i);
+ setUidModeDefault(op.code, op.uid);
// Keep track this permission was requested by the UID.
List<String> unrequestedRestrictedPermissions =
- unrequestedRestrictedPermissionsForUid.get(uid);
+ unrequestedRestrictedPermissionsForUid.get(op.uid);
if (unrequestedRestrictedPermissions == null) {
unrequestedRestrictedPermissions = new ArrayList<>(sAllRestrictedPermissions);
- unrequestedRestrictedPermissionsForUid.put(uid,
+ unrequestedRestrictedPermissionsForUid.put(op.uid,
unrequestedRestrictedPermissions);
}
- unrequestedRestrictedPermissions.remove(AppOpsManager.opToPermission(opCode));
+ unrequestedRestrictedPermissions.remove(AppOpsManager.opToPermission(op.code));
- mUids.delete(uid);
+ unprocessedUids.delete(op.uid);
}
// Give root access
- mUids.put(Process.ROOT_UID, Process.ROOT_UID);
+ unprocessedUids.put(Process.ROOT_UID, Process.ROOT_UID);
// Add records for UIDs that don't use any restricted permissions.
- final int uidCount = mUids.size();
+ final int uidCount = unprocessedUids.size();
for (int i = 0; i < uidCount; i++) {
- final int uid = mUids.keyAt(i);
+ final int uid = unprocessedUids.keyAt(i);
unrequestedRestrictedPermissionsForUid.put(uid,
new ArrayList<>(sAllRestrictedPermissions));
}
@@ -280,7 +331,7 @@ public final class PermissionPolicyService extends SystemService {
if (unrequestedRestrictedPermissions != null) {
final int uid = unrequestedRestrictedPermissionsForUid.keyAt(i);
final String[] packageNames = (uid != Process.ROOT_UID)
- ? mContext.getPackageManager().getPackagesForUid(uid)
+ ? mPackageManager.getPackagesForUid(uid)
: new String[] {"root"};
if (packageNames == null) {
continue;
@@ -289,8 +340,7 @@ public final class PermissionPolicyService extends SystemService {
for (int j = 0; j < permissionCount; j++) {
final String permission = unrequestedRestrictedPermissions.get(j);
for (String packageName : packageNames) {
- setUidModeAllowed(appOpsManager,
- AppOpsManager.permissionToOpCode(permission), uid,
+ setUidModeAllowed(AppOpsManager.permissionToOpCode(permission), uid,
packageName);
}
}
@@ -298,19 +348,115 @@ public final class PermissionPolicyService extends SystemService {
}
}
- private void addPackage(@NonNull Context context,
- @NonNull PackageParser.Package pkg, @UserIdInt int userId) {
- final PackageManager packageManager = context.getPackageManager();
+ /**
+ * Set app ops that belong to restricted permissions.
+ *
+ * <p>This processed ops previously added by {@link #addOpIfRestricted}
+ */
+ private void syncOpsOfFgPermissions() {
+ int numFgPermOps = mFgPermOps.size();
+ for (int i = 0; i < numFgPermOps; i++) {
+ FgPermission perm = mFgPermOps.get(i);
+
+ if (mPackageManager.checkPermission(perm.fgPermissionName, perm.packageName)
+ == PackageManager.PERMISSION_GRANTED) {
+ if (mPackageManager.checkPermission(perm.bgPermissionName, perm.packageName)
+ == PackageManager.PERMISSION_GRANTED) {
+ mAppOpsManager.setUidMode(
+ AppOpsManager.permissionToOpCode(perm.fgPermissionName), perm.uid,
+ AppOpsManager.MODE_ALLOWED);
+ } else {
+ mAppOpsManager.setUidMode(
+ AppOpsManager.permissionToOpCode(perm.fgPermissionName), perm.uid,
+ AppOpsManager.MODE_FOREGROUND);
+ }
+ } else {
+ mAppOpsManager.setUidMode(
+ AppOpsManager.permissionToOpCode(perm.fgPermissionName), perm.uid,
+ AppOpsManager.MODE_IGNORED);
+ }
+ }
+ }
+
+ /**
+ * Synchronize all previously {@link #addPackage added} packages.
+ */
+ void syncPackages() {
+ syncRestrictedOps();
+ syncOpsOfFgPermissions();
+ }
+
+ /**
+ * Add op that belong to a restricted permission for later processing in
+ * {@link #syncRestrictedOps}.
+ *
+ * <p>Note: Called with the package lock held. Do <u>not</u> call into app-op manager.
+ *
+ * @param permissionInfo The permission that is currently looked at
+ * @param pkg The package looked at
+ */
+ private void addOpIfRestricted(@NonNull PermissionInfo permissionInfo,
+ @NonNull PackageInfo pkg) {
+ final String permission = permissionInfo.name;
+ final int opCode = AppOpsManager.permissionToOpCode(permission);
+ final int uid = pkg.applicationInfo.uid;
+
+ if (!permissionInfo.isRestricted()) {
+ return;
+ }
+
+ final boolean applyRestriction = PackageManager.RESTRICTED_PERMISSIONS_ENABLED
+ && (mPackageManager.getPermissionFlags(permission, pkg.packageName,
+ mContext.getUser()) & FLAG_PERMISSION_APPLY_RESTRICTION) != 0;
+
+ if (permissionInfo.isHardRestricted()) {
+ if (applyRestriction) {
+ mOpsToRestrict.add(new OpToRestrict(uid, opCode));
+ } else {
+ mOpsToUnrestrict.add(new OpToUnrestrict(uid, pkg.packageName, opCode));
+ }
+ } else if (permissionInfo.isSoftRestricted()) {
+ //TODO: Implement soft restrictions like storage here.
+ }
+ }
+
+ private void addOpIfFgPermissions(@NonNull PermissionInfo permissionInfo,
+ @NonNull PackageInfo pkg) {
+ if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
+ // Pre-M apps do not store their fg/bg state in the permissions
+ return;
+ }
+
+ if (permissionInfo.backgroundPermission == null) {
+ return;
+ }
- final int uid = UserHandle.getUid(userId, UserHandle.getAppId(pkg.applicationInfo.uid));
- final UserHandle userHandle = UserHandle.of(userId);
+ mFgPermOps.add(new FgPermission(pkg.applicationInfo.uid, pkg.packageName,
+ permissionInfo.name, permissionInfo.backgroundPermission));
+ }
+
+ /**
+ * Add a package for {@link #syncPackages() processing} later.
+ *
+ * <p>Note: Called with the package lock held. Do <u>not</u> call into app-op manager.
+ *
+ * @param pkgName The package to add for later processing.
+ */
+ void addPackage(@NonNull String pkgName) {
+ final PackageInfo pkg;
+ try {
+ pkg = mPackageManager.getPackageInfo(pkgName, GET_PERMISSIONS);
+ } catch (NameNotFoundException e) {
+ return;
+ }
- mUids.put(uid, uid);
+ mAllUids.put(pkg.applicationInfo.uid, pkg.applicationInfo.uid);
- final int permissionCount = pkg.requestedPermissions.size();
- for (int i = 0; i < permissionCount; i++) {
- final String permission = pkg.requestedPermissions.get(i);
+ if (pkg.requestedPermissions == null) {
+ return;
+ }
+ for (String permission : pkg.requestedPermissions) {
final int opCode = AppOpsManager.permissionToOpCode(permission);
if (opCode == AppOpsManager.OP_NONE) {
continue;
@@ -318,44 +464,63 @@ public final class PermissionPolicyService extends SystemService {
final PermissionInfo permissionInfo;
try {
- permissionInfo = packageManager.getPermissionInfo(permission, 0);
+ permissionInfo = mPackageManager.getPermissionInfo(permission, 0);
} catch (PackageManager.NameNotFoundException e) {
continue;
}
- if (!permissionInfo.isRestricted()) {
- continue;
- }
-
- final boolean applyRestriction = PackageManager.RESTRICTED_PERMISSIONS_ENABLED
- && (packageManager.getPermissionFlags(permission, pkg.packageName,
- userHandle) & FLAG_PERMISSION_APPLY_RESTRICTION) != 0;
-
- if (permissionInfo.isHardRestricted()) {
- if (applyRestriction) {
- mDefaultUidOps.put(opCode, uid);
- } else {
- mPackageNames.put(opCode, pkg.packageName);
- mAllowedUidOps.put(opCode, uid);
- }
- } else if (permissionInfo.isSoftRestricted()) {
- //TODO: Implement soft restrictions like storage here.
- }
+ addOpIfRestricted(permissionInfo, pkg);
+ addOpIfFgPermissions(permissionInfo, pkg);
}
}
- private static void setUidModeAllowed(@NonNull AppOpsManager appOpsManager,
- int opCode, int uid, @NonNull String packageName) {
- final int currentMode = appOpsManager.unsafeCheckOpRaw(AppOpsManager
+ private void setUidModeAllowed(int opCode, int uid, @NonNull String packageName) {
+ final int currentMode = mAppOpsManager.unsafeCheckOpRaw(AppOpsManager
.opToPublicName(opCode), uid, packageName);
if (currentMode == AppOpsManager.MODE_DEFAULT) {
- appOpsManager.setUidMode(opCode, uid, AppOpsManager.MODE_ALLOWED);
+ mAppOpsManager.setUidMode(opCode, uid, AppOpsManager.MODE_ALLOWED);
}
}
- private static void setUidModeDefault(@NonNull AppOpsManager appOpsManager,
- int opCode, int uid) {
- appOpsManager.setUidMode(opCode, uid, AppOpsManager.MODE_DEFAULT);
+ private void setUidModeDefault(int opCode, int uid) {
+ mAppOpsManager.setUidMode(opCode, uid, AppOpsManager.MODE_DEFAULT);
+ }
+
+ private class OpToRestrict {
+ final int uid;
+ final int code;
+
+ OpToRestrict(int uid, int code) {
+ this.uid = uid;
+ this.code = code;
+ }
+ }
+
+ private class OpToUnrestrict {
+ final int uid;
+ final @NonNull String packageName;
+ final int code;
+
+ OpToUnrestrict(int uid, @NonNull String packageName, int code) {
+ this.uid = uid;
+ this.packageName = packageName;
+ this.code = code;
+ }
+ }
+
+ private class FgPermission {
+ final int uid;
+ final @NonNull String packageName;
+ final @NonNull String fgPermissionName;
+ final @NonNull String bgPermissionName;
+
+ private FgPermission(int uid, @NonNull String packageName,
+ @NonNull String fgPermissionName, @NonNull String bgPermissionName) {
+ this.uid = uid;
+ this.packageName = packageName;
+ this.fgPermissionName = fgPermissionName;
+ this.bgPermissionName = bgPermissionName;
+ }
}
}
}
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index 6cf36d692520..ed3ec94ea3dd 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -87,6 +87,7 @@ import static android.content.res.Configuration.UI_MODE_TYPE_VR_HEADSET;
import static android.os.Build.VERSION_CODES.HONEYCOMB;
import static android.os.Build.VERSION_CODES.O;
import static android.os.Process.SYSTEM_UID;
+import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.Display.INVALID_DISPLAY;
import static android.view.Surface.ROTATION_270;
import static android.view.Surface.ROTATION_90;
@@ -1948,14 +1949,20 @@ final class ActivityRecord extends ConfigurationContainer {
return false;
}
+ // Whether the activity is on the sleeping display.
+ // TODO(b/129750406): This should be applied for the default display, too.
+ final boolean isDisplaySleeping = getDisplay().isSleeping()
+ && getDisplayId() != DEFAULT_DISPLAY;
// Whether this activity is the top activity of this stack.
final boolean isTop = this == stack.getTopActivity();
// Exclude the case where this is the top activity in a pinned stack.
final boolean isTopNotPinnedStack = stack.isAttached()
&& stack.getDisplay().isTopNotPinnedStack(stack);
- // Now check whether it's really visible depending on Keyguard state.
- return stack.checkKeyguardVisibility(this,
+ // Now check whether it's really visible depending on Keyguard state, and update
+ // {@link ActivityStack} internal states.
+ final boolean visibleIgnoringDisplayStatus = stack.checkKeyguardVisibility(this,
visibleIgnoringKeyguard, isTop && isTopNotPinnedStack);
+ return visibleIgnoringDisplayStatus && !isDisplaySleeping;
}
boolean shouldBeVisible() {
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 0f4e123923b0..ee4e33e4cfaa 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -250,8 +250,8 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
// on the IME target. We mainly have this container grouping so we can keep track of all the IME
// window containers together and move them in-sync if/when needed. We use a subclass of
// WindowContainer which is omitted from screen magnification, as the IME is never magnified.
- private final NonMagnifiableWindowContainers mImeWindowsContainers =
- new NonMagnifiableWindowContainers("mImeWindowsContainers", mWmService);
+ private final NonAppWindowContainers mImeWindowsContainers =
+ new NonAppWindowContainers("mImeWindowsContainers", mWmService);
private WindowState mTmpWindow;
private WindowState mTmpWindow2;
@@ -4642,16 +4642,6 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
}
}
- private class NonMagnifiableWindowContainers extends NonAppWindowContainers {
- NonMagnifiableWindowContainers(String name, WindowManagerService service) {
- super(name, service);
- }
-
- @Override
- void applyMagnificationSpec(Transaction t, MagnificationSpec spec) {
- }
- };
-
SurfaceControl.Builder makeSurface(SurfaceSession s) {
return mWmService.makeSurfaceBuilder(s)
.setParent(mWindowingLayer);
diff --git a/services/core/java/com/android/server/wm/KeyguardController.java b/services/core/java/com/android/server/wm/KeyguardController.java
index 432d75e9a4e3..363db5439f27 100644
--- a/services/core/java/com/android/server/wm/KeyguardController.java
+++ b/services/core/java/com/android/server/wm/KeyguardController.java
@@ -294,7 +294,16 @@ class KeyguardController {
/**
* Called when occluded state changed.
*/
- private void handleOccludedChanged() {
+ private void handleOccludedChanged(int displayId) {
+ // TODO(b/113840485): Handle app transition for individual display, and apply occluded
+ // state change to secondary displays.
+ // For now, only default display fully supports occluded change. Other displays only
+ // updates keygaurd sleep token on that display.
+ if (displayId != DEFAULT_DISPLAY) {
+ updateKeyguardSleepToken(displayId);
+ return;
+ }
+
mWindowManager.onKeyguardOccludedChanged(isDisplayOccluded(DEFAULT_DISPLAY));
if (isKeyguardLocked()) {
mWindowManager.deferSurfaceLayout();
@@ -303,7 +312,7 @@ class KeyguardController {
.prepareAppTransition(resolveOccludeTransit(),
false /* alwaysKeepCurrent */, 0 /* flags */,
true /* forceOverride */);
- updateKeyguardSleepToken();
+ updateKeyguardSleepToken(DEFAULT_DISPLAY);
mRootActivityContainer.ensureActivitiesVisible(null, 0, !PRESERVE_WINDOWS);
mWindowManager.executeAppTransition();
} finally {
@@ -395,13 +404,16 @@ class KeyguardController {
for (int displayNdx = mRootActivityContainer.getChildCount() - 1;
displayNdx >= 0; displayNdx--) {
final ActivityDisplay display = mRootActivityContainer.getChildAt(displayNdx);
- final int displayId = display.mDisplayId;
- final KeyguardDisplayState state = getDisplay(displayId);
- if (isKeyguardUnoccludedOrAodShowing(displayId) && state.mSleepToken == null) {
- state.acquiredSleepToken();
- } else if (!isKeyguardUnoccludedOrAodShowing(displayId) && state.mSleepToken != null) {
- state.releaseSleepToken();
- }
+ updateKeyguardSleepToken(display.mDisplayId);
+ }
+ }
+
+ private void updateKeyguardSleepToken(int displayId) {
+ final KeyguardDisplayState state = getDisplay(displayId);
+ if (isKeyguardUnoccludedOrAodShowing(displayId) && state.mSleepToken == null) {
+ state.acquiredSleepToken();
+ } else if (!isKeyguardUnoccludedOrAodShowing(displayId) && state.mSleepToken != null) {
+ state.releaseSleepToken();
}
}
@@ -483,11 +495,8 @@ class KeyguardController {
mOccluded |= controller.mWindowManager.isShowingDream();
}
- // TODO(b/113840485): Handle app transition for individual display, and apply occluded
- // state change to secondary displays.
- // For now, only default display can change occluded.
- if (lastOccluded != mOccluded && mDisplayId == DEFAULT_DISPLAY) {
- controller.handleOccludedChanged();
+ if (lastOccluded != mOccluded) {
+ controller.handleOccludedChanged(mDisplayId);
}
if (lastDismissActivity != mDismissingKeyguardActivity && !mOccluded
&& mDismissingKeyguardActivity != null
diff --git a/services/core/java/com/android/server/wm/TaskSnapshotPersister.java b/services/core/java/com/android/server/wm/TaskSnapshotPersister.java
index 3c9a46b43a2f..0b63f484c8e2 100644
--- a/services/core/java/com/android/server/wm/TaskSnapshotPersister.java
+++ b/services/core/java/com/android/server/wm/TaskSnapshotPersister.java
@@ -26,7 +26,6 @@ import android.app.ActivityManager;
import android.app.ActivityManager.TaskSnapshot;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
-import android.hardware.HardwareBuffer;
import android.os.Process;
import android.os.SystemClock;
import android.util.ArraySet;
@@ -363,8 +362,7 @@ class TaskSnapshotPersister {
// TODO(b/116112787) TaskSnapshot needs bookkeep the ColorSpace of the
// hardware bitmap when created.
final Bitmap bitmap = Bitmap.wrapHardwareBuffer(
- HardwareBuffer.createFromGraphicBuffer(mSnapshot.getSnapshot()),
- mSnapshot.getColorSpace());
+ mSnapshot.getSnapshot(), mSnapshot.getColorSpace());
if (bitmap == null) {
Slog.e(TAG, "Invalid task snapshot hw bitmap");
return false;
diff --git a/services/core/java/com/android/server/wm/WallpaperController.java b/services/core/java/com/android/server/wm/WallpaperController.java
index 166a33d7a560..da873b8bc308 100644
--- a/services/core/java/com/android/server/wm/WallpaperController.java
+++ b/services/core/java/com/android/server/wm/WallpaperController.java
@@ -35,7 +35,6 @@ import static com.android.server.wm.WindowManagerService.H.WALLPAPER_DRAW_PENDIN
import android.graphics.Bitmap;
import android.graphics.Rect;
-import android.hardware.HardwareBuffer;
import android.os.Bundle;
import android.os.Debug;
import android.os.IBinder;
@@ -744,8 +743,7 @@ class WallpaperController {
return null;
}
return Bitmap.wrapHardwareBuffer(
- HardwareBuffer.createFromGraphicBuffer(wallpaperBuffer.getGraphicBuffer()),
- wallpaperBuffer.getColorSpace());
+ wallpaperBuffer.getGraphicBuffer(), wallpaperBuffer.getColorSpace());
}
private WindowState getTopVisibleWallpaper() {