diff options
| -rw-r--r-- | core/api/current.txt | 6 | ||||
| -rw-r--r-- | core/api/module-lib-current.txt | 13 | ||||
| -rw-r--r-- | core/java/android/app/KeyguardManager.java | 96 | ||||
| -rw-r--r-- | core/java/android/app/keyguard.aconfig | 10 | ||||
| -rw-r--r-- | core/java/android/app/trust/ITrustManager.aidl | 5 | ||||
| -rw-r--r-- | core/java/android/app/trust/TrustManager.java | 31 | ||||
| -rw-r--r-- | core/java/android/content/pm/PackageManager.java | 31 | ||||
| -rw-r--r-- | core/java/android/content/pm/SigningInfo.java | 66 | ||||
| -rw-r--r-- | core/java/android/content/pm/SigningInfoException.java | 50 | ||||
| -rw-r--r-- | core/java/com/android/internal/os/Zygote.java | 3 | ||||
| -rw-r--r-- | core/java/com/android/internal/policy/IDeviceLockedStateListener.aidl | 21 | ||||
| -rw-r--r-- | core/jni/com_android_internal_os_Zygote.cpp | 8 | ||||
| -rw-r--r-- | core/res/AndroidManifest.xml | 3 | ||||
| -rw-r--r-- | core/tests/coretests/src/android/window/OWNERS | 3 | ||||
| -rw-r--r-- | services/core/java/com/android/server/trust/TrustManagerService.java | 52 | ||||
| -rw-r--r-- | services/core/java/com/android/server/wm/OWNERS | 1 |
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 |