summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/api/current.txt6
-rw-r--r--core/api/module-lib-current.txt13
-rw-r--r--core/java/android/app/KeyguardManager.java96
-rw-r--r--core/java/android/app/keyguard.aconfig10
-rw-r--r--core/java/android/app/trust/ITrustManager.aidl5
-rw-r--r--core/java/android/app/trust/TrustManager.java31
-rw-r--r--core/java/android/content/pm/PackageManager.java31
-rw-r--r--core/java/android/content/pm/SigningInfo.java66
-rw-r--r--core/java/android/content/pm/SigningInfoException.java50
-rw-r--r--core/java/com/android/internal/os/Zygote.java3
-rw-r--r--core/java/com/android/internal/policy/IDeviceLockedStateListener.aidl21
-rw-r--r--core/jni/com_android_internal_os_Zygote.cpp8
-rw-r--r--core/res/AndroidManifest.xml3
-rw-r--r--core/tests/coretests/src/android/window/OWNERS3
-rw-r--r--services/core/java/com/android/server/trust/TrustManagerService.java52
-rw-r--r--services/core/java/com/android/server/wm/OWNERS1
16 files changed, 397 insertions, 2 deletions
diff --git a/core/api/current.txt b/core/api/current.txt
index eb769cea651f..1f1067849d47 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -6198,6 +6198,7 @@ package android.app {
}
public class KeyguardManager {
+ method @FlaggedApi("android.app.device_unlock_listener") @RequiresPermission(android.Manifest.permission.SUBSCRIBE_TO_KEYGUARD_LOCKED_STATE) public void addDeviceLockedStateListener(@NonNull java.util.concurrent.Executor, @NonNull android.app.KeyguardManager.DeviceLockedStateListener);
method @RequiresPermission(android.Manifest.permission.SUBSCRIBE_TO_KEYGUARD_LOCKED_STATE) public void addKeyguardLockedStateListener(@NonNull java.util.concurrent.Executor, @NonNull android.app.KeyguardManager.KeyguardLockedStateListener);
method @Deprecated public android.content.Intent createConfirmDeviceCredentialIntent(CharSequence, CharSequence);
method @Deprecated @RequiresPermission(android.Manifest.permission.DISABLE_KEYGUARD) public void exitKeyguardSecurely(android.app.KeyguardManager.OnKeyguardExitResult);
@@ -6207,10 +6208,15 @@ package android.app {
method public boolean isKeyguardLocked();
method public boolean isKeyguardSecure();
method @Deprecated public android.app.KeyguardManager.KeyguardLock newKeyguardLock(String);
+ method @FlaggedApi("android.app.device_unlock_listener") @RequiresPermission(android.Manifest.permission.SUBSCRIBE_TO_KEYGUARD_LOCKED_STATE) public void removeDeviceLockedStateListener(@NonNull android.app.KeyguardManager.DeviceLockedStateListener);
method @RequiresPermission(android.Manifest.permission.SUBSCRIBE_TO_KEYGUARD_LOCKED_STATE) public void removeKeyguardLockedStateListener(@NonNull android.app.KeyguardManager.KeyguardLockedStateListener);
method public void requestDismissKeyguard(@NonNull android.app.Activity, @Nullable android.app.KeyguardManager.KeyguardDismissCallback);
}
+ @FlaggedApi("android.app.device_unlock_listener") @java.lang.FunctionalInterface public static interface KeyguardManager.DeviceLockedStateListener {
+ method public void onDeviceLockedStateChanged(boolean);
+ }
+
public abstract static class KeyguardManager.KeyguardDismissCallback {
ctor public KeyguardManager.KeyguardDismissCallback();
method public void onDismissCancelled();
diff --git a/core/api/module-lib-current.txt b/core/api/module-lib-current.txt
index 529e7f9b0bd3..149e474055be 100644
--- a/core/api/module-lib-current.txt
+++ b/core/api/module-lib-current.txt
@@ -129,6 +129,7 @@ package android.content.pm {
public abstract class PackageManager {
method @NonNull public String getSdkSandboxPackageName();
+ method @FlaggedApi("android.content.pm.cloud_compilation_pm") @NonNull public static android.content.pm.SigningInfo getVerifiedSigningInfo(@NonNull String, int) throws android.content.pm.SigningInfoException;
method @RequiresPermission(android.Manifest.permission.MAKE_UID_VISIBLE) public void makeUidVisible(int, int);
field public static final String EXTRA_VERIFICATION_ROOT_HASH = "android.content.pm.extra.VERIFICATION_ROOT_HASH";
field public static final int MATCH_STATIC_SHARED_AND_SDK_LIBRARIES = 67108864; // 0x4000000
@@ -139,6 +140,18 @@ package android.content.pm {
method @NonNull public String getPackageName();
}
+ public final class SigningInfo implements android.os.Parcelable {
+ method @FlaggedApi("android.content.pm.cloud_compilation_pm") public boolean signersMatchExactly(@NonNull android.content.pm.SigningInfo);
+ field @FlaggedApi("android.content.pm.cloud_compilation_pm") public static final int VERSION_JAR = 1; // 0x1
+ field @FlaggedApi("android.content.pm.cloud_compilation_pm") public static final int VERSION_SIGNING_BLOCK_V2 = 2; // 0x2
+ field @FlaggedApi("android.content.pm.cloud_compilation_pm") public static final int VERSION_SIGNING_BLOCK_V3 = 3; // 0x3
+ field @FlaggedApi("android.content.pm.cloud_compilation_pm") public static final int VERSION_SIGNING_BLOCK_V4 = 4; // 0x4
+ }
+
+ @FlaggedApi("android.content.pm.cloud_compilation_pm") public class SigningInfoException extends java.lang.Exception {
+ method @FlaggedApi("android.content.pm.cloud_compilation_pm") public int getCode();
+ }
+
}
package android.hardware.usb {
diff --git a/core/java/android/app/KeyguardManager.java b/core/java/android/app/KeyguardManager.java
index 62820ad5a4d6..67f7bee4028e 100644
--- a/core/java/android/app/KeyguardManager.java
+++ b/core/java/android/app/KeyguardManager.java
@@ -18,6 +18,7 @@ package android.app;
import android.Manifest;
import android.annotation.CallbackExecutor;
+import android.annotation.FlaggedApi;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -52,7 +53,9 @@ import android.view.IOnKeyguardExitResult;
import android.view.IWindowManager;
import android.view.WindowManagerGlobal;
+import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.policy.IDeviceLockedStateListener;
import com.android.internal.policy.IKeyguardDismissCallback;
import com.android.internal.policy.IKeyguardLockedStateListener;
import com.android.internal.util.Preconditions;
@@ -253,6 +256,26 @@ public class KeyguardManager {
private final ArrayMap<KeyguardLockedStateListener, Executor>
mKeyguardLockedStateListeners = new ArrayMap<>();
+ private final IDeviceLockedStateListener mIDeviceLockedStateListener =
+ new IDeviceLockedStateListener.Stub() {
+ @Override
+ public void onDeviceLockedStateChanged(boolean isDeviceLocked) {
+ if (!Flags.deviceUnlockListener()) {
+ return;
+ }
+ synchronized (mDeviceLockedStateListeners) {
+ mDeviceLockedStateListeners.forEach((listener, executor) -> {
+ executor.execute(
+ () -> listener.onDeviceLockedStateChanged(isDeviceLocked));
+ });
+ }
+ }
+ };
+
+ @GuardedBy("mDeviceLockedStateListeners")
+ private final ArrayMap<DeviceLockedStateListener, Executor>
+ mDeviceLockedStateListeners = new ArrayMap<>();
+
/**
* Get an intent to prompt the user to confirm credentials (pin, pattern, password or biometrics
* if enrolled) for the current user of the device. The caller is expected to launch this
@@ -1370,4 +1393,77 @@ public class KeyguardManager {
}
}
}
+
+
+ /**
+ * Listener for device locked state changes.
+ */
+ @FunctionalInterface
+ @FlaggedApi(Flags.FLAG_DEVICE_UNLOCK_LISTENER)
+ public interface DeviceLockedStateListener {
+ /**
+ * Callback function that executes when the device locked state changes.
+ */
+ void onDeviceLockedStateChanged(boolean isDeviceLocked);
+ }
+
+
+ /**
+ * Registers a listener to execute when the device locked state changes.
+ *
+ * @param executor The {@link Executor} where the {@code listener} will be invoked
+ * @param listener The listener to add to receive device locked state changes.
+ *
+ * @see #isDeviceLocked()
+ * @see #removeDeviceLockedStateListener(DeviceLockedStateListener)
+ */
+ @RequiresPermission(Manifest.permission.SUBSCRIBE_TO_KEYGUARD_LOCKED_STATE)
+ @FlaggedApi(Flags.FLAG_DEVICE_UNLOCK_LISTENER)
+ public void addDeviceLockedStateListener(@NonNull @CallbackExecutor Executor executor,
+ @NonNull DeviceLockedStateListener listener) {
+ if (!Flags.deviceUnlockListener()) {
+ return;
+ }
+
+ synchronized (mDeviceLockedStateListeners) {
+ mDeviceLockedStateListeners.put(listener, executor);
+ if (mDeviceLockedStateListeners.size() > 1) {
+ return;
+ }
+ try {
+ mTrustManager.registerDeviceLockedStateListener(mIDeviceLockedStateListener,
+ mContext.getDeviceId());
+ } catch (RemoteException re) {
+ Log.d(TAG, "TrustManager service died", re);
+ }
+ }
+ }
+
+ /**
+ * Unregisters a listener that executes when the device locked state changes.
+ *
+ * @param listener The listener to remove.
+ *
+ * @see #isDeviceLocked()
+ * @see #addDeviceLockedStateListener(Executor, DeviceLockedStateListener)
+ */
+ @RequiresPermission(Manifest.permission.SUBSCRIBE_TO_KEYGUARD_LOCKED_STATE)
+ @FlaggedApi(Flags.FLAG_DEVICE_UNLOCK_LISTENER)
+ public void removeDeviceLockedStateListener(@NonNull DeviceLockedStateListener listener) {
+ if (!Flags.deviceUnlockListener()) {
+ return;
+ }
+
+ synchronized (mDeviceLockedStateListeners) {
+ mDeviceLockedStateListeners.remove(listener);
+ if (!mDeviceLockedStateListeners.isEmpty()) {
+ return;
+ }
+ try {
+ mTrustManager.unregisterDeviceLockedStateListener(mIDeviceLockedStateListener);
+ } catch (RemoteException re) {
+ Log.d(TAG, "TrustManager service died", re);
+ }
+ }
+ }
}
diff --git a/core/java/android/app/keyguard.aconfig b/core/java/android/app/keyguard.aconfig
new file mode 100644
index 000000000000..9cd1c1579416
--- /dev/null
+++ b/core/java/android/app/keyguard.aconfig
@@ -0,0 +1,10 @@
+package: "android.app"
+container: "system"
+
+flag {
+ namespace: "wallet_integration"
+ name: "device_unlock_listener"
+ is_exported: true
+ description: "Enable listener API for device unlock."
+ bug: "296195355"
+} \ No newline at end of file
diff --git a/core/java/android/app/trust/ITrustManager.aidl b/core/java/android/app/trust/ITrustManager.aidl
index 740f5932f902..7cef2eff8767 100644
--- a/core/java/android/app/trust/ITrustManager.aidl
+++ b/core/java/android/app/trust/ITrustManager.aidl
@@ -18,6 +18,7 @@ package android.app.trust;
import android.app.trust.ITrustListener;
import android.hardware.biometrics.BiometricSourceType;
+import com.android.internal.policy.IDeviceLockedStateListener;
/**
* System private API to comunicate with trust service.
@@ -42,4 +43,8 @@ interface ITrustManager {
void clearAllBiometricRecognized(in BiometricSourceType target, int unlockedUser);
boolean isActiveUnlockRunning(int userId);
boolean isInSignificantPlace();
+ @EnforcePermission("SUBSCRIBE_TO_KEYGUARD_LOCKED_STATE")
+ void registerDeviceLockedStateListener(in IDeviceLockedStateListener listener, int deviceId);
+ @EnforcePermission("SUBSCRIBE_TO_KEYGUARD_LOCKED_STATE")
+ void unregisterDeviceLockedStateListener(in IDeviceLockedStateListener listener);
}
diff --git a/core/java/android/app/trust/TrustManager.java b/core/java/android/app/trust/TrustManager.java
index 88d4d691cd97..75acac462427 100644
--- a/core/java/android/app/trust/TrustManager.java
+++ b/core/java/android/app/trust/TrustManager.java
@@ -31,6 +31,8 @@ import android.os.Message;
import android.os.RemoteException;
import android.util.ArrayMap;
+import com.android.internal.policy.IDeviceLockedStateListener;
+
import java.util.ArrayList;
import java.util.List;
@@ -259,6 +261,35 @@ public class TrustManager {
}
/**
+ * Registers a listener for device lock state events.
+ *
+ * Requires the {@link android.Manifest.permission#SUBSCRIBE_TO_KEYGUARD_LOCKED_STATE}
+ * permission.
+ */
+ public void registerDeviceLockedStateListener(final IDeviceLockedStateListener listener,
+ int deviceId) {
+ try {
+ mService.registerDeviceLockedStateListener(listener, deviceId);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Unregisters a listener for device lock state events.
+ *
+ * Requires the {@link android.Manifest.permission#SUBSCRIBE_TO_KEYGUARD_LOCKED_STATE}
+ * permission.
+ */
+ public void unregisterDeviceLockedStateListener(final IDeviceLockedStateListener listener) {
+ try {
+ mService.unregisterDeviceLockedStateListener(listener);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
* @return whether {@param userId} has enabled and configured trust agents. Ignores short-term
* unavailability of trust due to {@link LockPatternUtils.StrongAuthTracker}.
*/
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 0ed9c87e3d51..3971e98442bc 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -16,6 +16,7 @@
package android.content.pm;
+import static android.content.pm.SigningInfo.AppSigningSchemeVersion;
import static android.media.audio.Flags.FLAG_FEATURE_SPATIAL_AUDIO_HEADTRACKING_LOW_LATENCY;
import static com.android.internal.pm.pkg.parsing.ParsingPackageUtils.PARSE_COLLECT_CERTIFICATES;
@@ -59,6 +60,8 @@ import android.content.IntentFilter;
import android.content.IntentSender;
import android.content.pm.PackageInstaller.SessionParams;
import android.content.pm.dex.ArtManager;
+import android.content.pm.parsing.result.ParseResult;
+import android.content.pm.parsing.result.ParseTypeImpl;
import android.content.pm.verify.domain.DomainVerificationManager;
import android.content.res.Configuration;
import android.content.res.Resources;
@@ -94,6 +97,7 @@ import android.telephony.ims.RcsUceAdapter;
import android.telephony.ims.SipDelegateManager;
import android.util.AndroidException;
import android.util.Log;
+import android.util.apk.ApkSignatureVerifier;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.pm.parsing.PackageInfoCommonUtils;
@@ -11838,4 +11842,31 @@ public abstract class PackageManager {
throw new UnsupportedOperationException(
"parseServiceMetadata not implemented in subclass");
}
+
+ /**
+ * Verifies and returns the
+ * <a href="https://source.android.com/docs/security/features/apksigning">app signing</a>
+ * information of the file at the given path. This operation takes a few milliseconds.
+ *
+ * Unlike {@link #getPackageArchiveInfo(String, PackageInfoFlags)} with {@link
+ * #GET_SIGNING_CERTIFICATES}, this method does not require the file to be a package archive
+ * file.
+ *
+ * @throws SigningInfoException if the verification fails
+ *
+ * @hide
+ */
+ @FlaggedApi(android.content.pm.Flags.FLAG_CLOUD_COMPILATION_PM)
+ @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+ public static @NonNull SigningInfo getVerifiedSigningInfo(@NonNull String path,
+ @AppSigningSchemeVersion int minAppSigningSchemeVersion) throws SigningInfoException {
+ ParseTypeImpl input = ParseTypeImpl.forDefaultParsing();
+ ParseResult<SigningDetails> result =
+ ApkSignatureVerifier.verify(input, path, minAppSigningSchemeVersion);
+ if (result.isError()) {
+ throw new SigningInfoException(
+ result.getErrorCode(), result.getErrorMessage(), result.getException());
+ }
+ return new SigningInfo(result.getResult());
+ }
}
diff --git a/core/java/android/content/pm/SigningInfo.java b/core/java/android/content/pm/SigningInfo.java
index 23daaf2d4138..e4fbd1f28dbb 100644
--- a/core/java/android/content/pm/SigningInfo.java
+++ b/core/java/android/content/pm/SigningInfo.java
@@ -16,14 +16,20 @@
package android.content.pm;
+import static android.content.pm.SigningDetails.SignatureSchemeVersion;
+
import android.annotation.FlaggedApi;
+import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.SystemApi;
import android.content.pm.SigningDetails.SignatureSchemeVersion;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.ArraySet;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
import java.security.PublicKey;
import java.util.Collection;
@@ -31,6 +37,55 @@ import java.util.Collection;
* Information pertaining to the signing certificates used to sign a package.
*/
public final class SigningInfo implements Parcelable {
+ /**
+ * JAR signing (v1 scheme).
+ * See https://source.android.com/docs/security/features/apksigning#v1.
+ *
+ * @hide
+ */
+ @FlaggedApi(Flags.FLAG_CLOUD_COMPILATION_PM)
+ @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+ public static final int VERSION_JAR = SignatureSchemeVersion.JAR;
+
+ /**
+ * APK signature scheme v2.
+ * See https://source.android.com/docs/security/features/apksigning/v2.
+ *
+ * @hide
+ */
+ @FlaggedApi(Flags.FLAG_CLOUD_COMPILATION_PM)
+ @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+ public static final int VERSION_SIGNING_BLOCK_V2 = SignatureSchemeVersion.SIGNING_BLOCK_V2;
+
+ /**
+ * APK signature scheme v3.
+ * See https://source.android.com/docs/security/features/apksigning/v3.
+ *
+ * @hide
+ */
+ @FlaggedApi(Flags.FLAG_CLOUD_COMPILATION_PM)
+ @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+ public static final int VERSION_SIGNING_BLOCK_V3 = SignatureSchemeVersion.SIGNING_BLOCK_V3;
+
+ /**
+ * APK signature scheme v4.
+ * See https://source.android.com/docs/security/features/apksigning/v4.
+ *
+ * @hide
+ */
+ @FlaggedApi(Flags.FLAG_CLOUD_COMPILATION_PM)
+ @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+ public static final int VERSION_SIGNING_BLOCK_V4 = SignatureSchemeVersion.SIGNING_BLOCK_V4;
+
+ /** @hide */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(prefix = {"VERSION_"}, value = {
+ VERSION_JAR,
+ VERSION_SIGNING_BLOCK_V2,
+ VERSION_SIGNING_BLOCK_V3,
+ VERSION_SIGNING_BLOCK_V4,
+ })
+ public @interface AppSigningSchemeVersion {}
@NonNull
private final SigningDetails mSigningDetails;
@@ -198,6 +253,17 @@ public final class SigningInfo implements Parcelable {
return mSigningDetails;
}
+ /**
+ * Returns true if the signing certificates in this and other match exactly.
+ *
+ * @hide
+ */
+ @FlaggedApi(Flags.FLAG_CLOUD_COMPILATION_PM)
+ @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+ public boolean signersMatchExactly(@NonNull SigningInfo other) {
+ return mSigningDetails.signaturesMatchExactly(other.mSigningDetails);
+ }
+
public static final @android.annotation.NonNull Parcelable.Creator<SigningInfo> CREATOR =
new Parcelable.Creator<SigningInfo>() {
@Override
diff --git a/core/java/android/content/pm/SigningInfoException.java b/core/java/android/content/pm/SigningInfoException.java
new file mode 100644
index 000000000000..a81e07e73685
--- /dev/null
+++ b/core/java/android/content/pm/SigningInfoException.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2024 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.
+ */
+
+package android.content.pm;
+
+import android.annotation.FlaggedApi;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+
+/**
+ * Indicates an error when verifying the
+ * <a href="https://source.android.com/docs/security/features/apksigning">app signing</a>
+ * information.
+ *
+ * @hide
+ */
+@FlaggedApi(Flags.FLAG_CLOUD_COMPILATION_PM)
+@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+public class SigningInfoException extends Exception {
+ private final int mCode;
+
+ /** @hide */
+ public SigningInfoException(int code, @NonNull String message, @Nullable Throwable cause) {
+ super(message, cause);
+ mCode = code;
+ }
+
+ /**
+ * Returns a code representing the cause, in one of the installation parse return codes in
+ * {@link PackageManager}.
+ */
+ @FlaggedApi(Flags.FLAG_CLOUD_COMPILATION_PM)
+ public int getCode() {
+ return mCode;
+ }
+}
diff --git a/core/java/com/android/internal/os/Zygote.java b/core/java/com/android/internal/os/Zygote.java
index cab84bb01f70..d1ef7bcfc1e5 100644
--- a/core/java/com/android/internal/os/Zygote.java
+++ b/core/java/com/android/internal/os/Zygote.java
@@ -201,6 +201,9 @@ public final class Zygote {
*/
public static final int DEBUG_ENABLE_PTRACE = 1 << 25;
+ /** Load 4KB ELF files on 16KB device using appcompat mode */
+ public static final int ENABLE_PAGE_SIZE_APP_COMPAT = 1 << 26;
+
/** No external storage should be mounted. */
public static final int MOUNT_EXTERNAL_NONE = IVold.REMOUNT_MODE_NONE;
/** Default external storage should be mounted. */
diff --git a/core/java/com/android/internal/policy/IDeviceLockedStateListener.aidl b/core/java/com/android/internal/policy/IDeviceLockedStateListener.aidl
new file mode 100644
index 000000000000..cc626f699d43
--- /dev/null
+++ b/core/java/com/android/internal/policy/IDeviceLockedStateListener.aidl
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2024 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.
+ */
+
+package com.android.internal.policy;
+
+oneway interface IDeviceLockedStateListener {
+ void onDeviceLockedStateChanged(boolean isDeviceLocked);
+} \ No newline at end of file
diff --git a/core/jni/com_android_internal_os_Zygote.cpp b/core/jni/com_android_internal_os_Zygote.cpp
index 284c2997f9a9..aeaeeca3e845 100644
--- a/core/jni/com_android_internal_os_Zygote.cpp
+++ b/core/jni/com_android_internal_os_Zygote.cpp
@@ -89,6 +89,7 @@
#if defined(__BIONIC__)
extern "C" void android_reset_stack_guards();
+extern "C" void android_set_16kb_appcompat_mode(bool enable_app_compat);
#endif
namespace {
@@ -350,6 +351,7 @@ enum RuntimeFlags : uint32_t {
NATIVE_HEAP_ZERO_INIT_ENABLED = 1 << 23,
PROFILEABLE = 1 << 24,
DEBUG_ENABLE_PTRACE = 1 << 25,
+ ENABLE_PAGE_SIZE_APP_COMPAT = 1 << 26,
};
enum UnsolicitedZygoteMessageTypes : uint32_t {
@@ -2117,6 +2119,12 @@ static void SpecializeCommon(JNIEnv* env, uid_t uid, gid_t gid, jintArray gids,
SetCapabilities(permitted_capabilities, effective_capabilities, permitted_capabilities,
fail_fn);
+ if ((runtime_flags & RuntimeFlags::ENABLE_PAGE_SIZE_APP_COMPAT) != 0) {
+ android_set_16kb_appcompat_mode(true);
+ // Now that we've used the flag, clear it so that we don't pass unknown flags to the ART
+ // runtime.
+ runtime_flags &= ~RuntimeFlags::ENABLE_PAGE_SIZE_APP_COMPAT;
+ }
__android_log_close();
AStatsSocket_close();
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 101ba119b496..d74065589361 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -5428,7 +5428,8 @@
<permission android:name="android.permission.BIND_VISUAL_QUERY_DETECTION_SERVICE"
android:protectionLevel="signature" />
- <!-- Allows an application to subscribe to keyguard locked (i.e., showing) state.
+ <!-- Allows an application to subscribe to device locked and keyguard locked (i.e., showing)
+ state.
<p>Protection level: signature|role
<p>Intended for use by ROLE_ASSISTANT and signature apps only.
-->
diff --git a/core/tests/coretests/src/android/window/OWNERS b/core/tests/coretests/src/android/window/OWNERS
index 6c80cf9e5945..b3fcea2907a1 100644
--- a/core/tests/coretests/src/android/window/OWNERS
+++ b/core/tests/coretests/src/android/window/OWNERS
@@ -1,2 +1,3 @@
include /services/core/java/com/android/server/wm/OWNERS
-charlesccchen@google.com
+
+# Bug component: 1519745 = per-file WindowContext*,WindowMetrics*,WindowProvider*,WindowTokenClient* \ No newline at end of file
diff --git a/services/core/java/com/android/server/trust/TrustManagerService.java b/services/core/java/com/android/server/trust/TrustManagerService.java
index 953aae9588dd..585870bc1d6a 100644
--- a/services/core/java/com/android/server/trust/TrustManagerService.java
+++ b/services/core/java/com/android/server/trust/TrustManagerService.java
@@ -21,6 +21,7 @@ import static android.service.trust.GrantTrustResult.STATUS_UNLOCKED_BY_GRANT;
import static android.service.trust.TrustAgentService.FLAG_GRANT_TRUST_TEMPORARY_AND_RENEWABLE;
import android.Manifest;
+import android.annotation.EnforcePermission;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.UserIdInt;
@@ -60,6 +61,7 @@ import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.os.PersistableBundle;
+import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.os.SystemClock;
import android.os.UserHandle;
@@ -83,6 +85,7 @@ import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.content.PackageMonitor;
import com.android.internal.infra.AndroidFuture;
+import com.android.internal.policy.IDeviceLockedStateListener;
import com.android.internal.util.DumpUtils;
import com.android.internal.widget.LockPatternUtils;
import com.android.internal.widget.LockSettingsInternal;
@@ -103,6 +106,7 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Objects;
+import java.util.stream.IntStream;
/**
* Manages trust agents and trust listeners.
@@ -250,6 +254,10 @@ public class TrustManagerService extends SystemService {
new SparseArray<>();
private final SparseArray<TrustableTimeoutAlarmListener>
mIdleTrustableTimeoutAlarmListenerForUser = new SparseArray<>();
+
+ private final RemoteCallbackList<IDeviceLockedStateListener>
+ mDeviceLockedStateListeners = new RemoteCallbackList<>();
+
private AlarmManager mAlarmManager;
private final Object mAlarmLock = new Object();
@@ -1085,6 +1093,7 @@ public class TrustManagerService extends SystemService {
if (changed) {
notifyTrustAgentsOfDeviceLockState(userId, locked);
notifyKeystoreOfDeviceLockState(userId, locked);
+ notifyDeviceLockedListenersForUser(userId, locked);
// Also update the user's profiles who have unified challenge, since they
// share the same unlocked state (see {@link #isDeviceLocked(int)})
for (int profileHandle : mUserManager.getEnabledProfileIds(userId)) {
@@ -1892,6 +1901,26 @@ public class TrustManagerService extends SystemService {
return mIsInSignificantPlace;
}
+ @EnforcePermission(Manifest.permission.SUBSCRIBE_TO_KEYGUARD_LOCKED_STATE)
+ @Override
+ public void registerDeviceLockedStateListener(IDeviceLockedStateListener listener,
+ int deviceId) {
+ super.registerDeviceLockedStateListener_enforcePermission();
+ if (deviceId != Context.DEVICE_ID_DEFAULT) {
+ // Virtual devices are considered insecure.
+ return;
+ }
+ mDeviceLockedStateListeners.register(listener,
+ Integer.valueOf(UserHandle.getUserId(Binder.getCallingUid())));
+ }
+
+ @EnforcePermission(Manifest.permission.SUBSCRIBE_TO_KEYGUARD_LOCKED_STATE)
+ @Override
+ public void unregisterDeviceLockedStateListener(IDeviceLockedStateListener listener) {
+ super.unregisterDeviceLockedStateListener_enforcePermission();
+ mDeviceLockedStateListeners.unregister(listener);
+ }
+
private void enforceReportPermission() {
mContext.enforceCallingOrSelfPermission(
Manifest.permission.ACCESS_KEYGUARD_SECURE_STORAGE, "reporting trust events");
@@ -2013,6 +2042,7 @@ public class TrustManagerService extends SystemService {
}
notifyKeystoreOfDeviceLockState(userId, locked);
+ notifyDeviceLockedListenersForUser(userId, locked);
if (locked) {
try {
@@ -2479,4 +2509,26 @@ public class TrustManagerService extends SystemService {
updateTrust(mUserId, 0 /* flags */);
}
}
+
+ private void notifyDeviceLockedListenersForUser(int userId, boolean locked) {
+ synchronized (mDeviceLockedStateListeners) {
+ int numListeners = mDeviceLockedStateListeners.beginBroadcast();
+ try {
+ IntStream.range(0, numListeners).forEach(i -> {
+ try {
+ Integer uid = (Integer) mDeviceLockedStateListeners.getBroadcastCookie(i);
+ if (userId == uid.intValue()) {
+ mDeviceLockedStateListeners.getBroadcastItem(i)
+ .onDeviceLockedStateChanged(locked);
+ }
+ } catch (RemoteException re) {
+ Log.i(TAG, "Service died", re);
+ }
+ });
+
+ } finally {
+ mDeviceLockedStateListeners.finishBroadcast();
+ }
+ }
+ }
}
diff --git a/services/core/java/com/android/server/wm/OWNERS b/services/core/java/com/android/server/wm/OWNERS
index 63cd59e45ea6..dcad8b03a64c 100644
--- a/services/core/java/com/android/server/wm/OWNERS
+++ b/services/core/java/com/android/server/wm/OWNERS
@@ -19,6 +19,7 @@ yunfanc@google.com
wilsonshih@google.com
jiamingliu@google.com
pdwilliams@google.com
+charlesccchen@google.com
# Files related to background activity launches
per-file Background*Start* = set noparent