diff options
37 files changed, 279 insertions, 111 deletions
diff --git a/Android.bp b/Android.bp index b072087362d1..f5c0b6d416b8 100644 --- a/Android.bp +++ b/Android.bp @@ -413,13 +413,25 @@ java_defaults { ], } +// Collection of non updatable unbundled jars. The list here should match +// |non_updatable_modules| variable in frameworks/base/api/api.go. +java_library { + name: "framework-non-updatable-unbundled-impl-libs", + static_libs: [ + "framework-location.impl", + "framework-nfc.impl", + ], + sdk_version: "core_platform", + installable: false, +} + // Separated so framework-minus-apex-defaults can be used without the libs dependency java_defaults { name: "framework-minus-apex-with-libs-defaults", defaults: ["framework-minus-apex-defaults"], libs: [ "framework-virtualization.stubs.module_lib", - "framework-location.impl", + "framework-non-updatable-unbundled-impl-libs", ], } @@ -450,7 +462,7 @@ java_library { stem: "framework", apex_available: ["//apex_available:platform"], visibility: [ - "//frameworks/base/location", + "//frameworks/base:__subpackages__", ], compile_dex: false, headers_only: true, @@ -513,8 +525,8 @@ java_library { installable: false, // this lib is a build-only library static_libs: [ "app-compat-annotations", - "framework-location.impl", "framework-minus-apex", + "framework-non-updatable-unbundled-impl-libs", "framework-updatable-stubs-module_libs_api", ], sdk_version: "core_platform", diff --git a/api/Android.bp b/api/Android.bp index cbcbbbec1ace..68babc3660d9 100644 --- a/api/Android.bp +++ b/api/Android.bp @@ -89,6 +89,7 @@ combined_apis { "framework-location", "framework-media", "framework-mediaprovider", + "framework-nfc", "framework-ondevicepersonalization", "framework-pdf", "framework-permission", @@ -398,7 +399,10 @@ java_defaults { stub_only_libs: ["framework-protos"], impl_only_libs: ["framework-minus-apex-headers"], // the framework, including hidden API impl_library_visibility: ["//frameworks/base"], - defaults_visibility: ["//frameworks/base/location"], + defaults_visibility: [ + "//frameworks/base/location", + "//frameworks/base/nfc", + ], plugins: ["error_prone_android_framework"], errorprone: { javacflags: [ diff --git a/api/StubLibraries.bp b/api/StubLibraries.bp index f6f69291ce0e..28b2d4b5e3ee 100644 --- a/api/StubLibraries.bp +++ b/api/StubLibraries.bp @@ -635,6 +635,7 @@ java_defaults { api_contributions: [ "framework-virtualization.stubs.source.test.api.contribution", "framework-location.stubs.source.test.api.contribution", + "framework-nfc.stubs.source.test.api.contribution", ], } diff --git a/api/api.go b/api/api.go index 8df6dab715ef..71b1e10d2f47 100644 --- a/api/api.go +++ b/api/api.go @@ -32,6 +32,7 @@ const conscrypt = "conscrypt.module.public.api" const i18n = "i18n.module.public.api" const virtualization = "framework-virtualization" const location = "framework-location" +const nfc = "framework-nfc" var core_libraries_modules = []string{art, conscrypt, i18n} @@ -43,7 +44,7 @@ var core_libraries_modules = []string{art, conscrypt, i18n} // APIs. // In addition, the modules in this list are allowed to contribute to test APIs // stubs. -var non_updatable_modules = []string{virtualization, location} +var non_updatable_modules = []string{virtualization, location, nfc} // The intention behind this soong plugin is to generate a number of "merged" // API-related modules that would otherwise require a large amount of very diff --git a/core/java/android/security/OWNERS b/core/java/android/security/OWNERS index 33a67aed6023..533d459e532b 100644 --- a/core/java/android/security/OWNERS +++ b/core/java/android/security/OWNERS @@ -8,4 +8,4 @@ per-file *NetworkSecurityPolicy.java = file:net/OWNERS per-file Confirmation*.java = file:/keystore/OWNERS per-file FileIntegrityManager.java = file:platform/system/security:/fsverity/OWNERS per-file IFileIntegrityService.aidl = file:platform/system/security:/fsverity/OWNERS -per-file *.aconfig = victorhsieh@google.com +per-file *.aconfig = victorhsieh@google.com,eranm@google.com diff --git a/core/java/android/security/flags.aconfig b/core/java/android/security/flags.aconfig index 5aa309753cc4..e94f23a6f4ce 100644 --- a/core/java/android/security/flags.aconfig +++ b/core/java/android/security/flags.aconfig @@ -8,7 +8,7 @@ flag { } flag { - name: "fix_unlocked_device_required_keys" + name: "fix_unlocked_device_required_keys_v2" namespace: "hardware_backed_security" description: "Fix bugs in behavior of UnlockedDeviceRequired keystore keys" bug: "296464083" diff --git a/libs/hwui/Mesh.cpp b/libs/hwui/Mesh.cpp index e59bc9565a59..37a7d74330e9 100644 --- a/libs/hwui/Mesh.cpp +++ b/libs/hwui/Mesh.cpp @@ -90,8 +90,8 @@ std::tuple<bool, SkString> Mesh::validate() { FAIL_MESH_VALIDATE("%s mode requires at least %zu vertices but vertex count is %zu.", modeToStr(meshMode), min_vcount_for_mode(meshMode), mVertexCount); } - SkASSERT(!fICount); - SkASSERT(!fIOffset); + LOG_ALWAYS_FATAL_IF(mIndexCount != 0); + LOG_ALWAYS_FATAL_IF(mIndexOffset != 0); } if (!sm.ok()) { diff --git a/media/java/android/media/MediaCas.java b/media/java/android/media/MediaCas.java index 0a0a6263686a..ab7c27f70e05 100644 --- a/media/java/android/media/MediaCas.java +++ b/media/java/android/media/MediaCas.java @@ -272,7 +272,7 @@ public final class MediaCas implements AutoCloseable { Log.d(TAG, "Trying to get AIDL service"); IMediaCasService serviceAidl = IMediaCasService.Stub.asInterface( - ServiceManager.getService( + ServiceManager.waitForDeclaredService( IMediaCasService.DESCRIPTOR + "/default")); if (serviceAidl != null) { return serviceAidl; diff --git a/nfc/Android.bp b/nfc/Android.bp new file mode 100644 index 000000000000..bf9f47ceb0a7 --- /dev/null +++ b/nfc/Android.bp @@ -0,0 +1,51 @@ +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "frameworks_base_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["frameworks_base_license"], +} + +filegroup { + name: "framework-nfc-non-updatable-sources", + path: "java", + srcs: [], +} + +filegroup { + name: "framework-nfc-updatable-sources", + path: "java", + srcs: [ + "java/**/*.java", + "java/**/*.aidl", + ], + exclude_srcs: [ + ":framework-nfc-non-updatable-sources", + ], +} + +java_sdk_library { + name: "framework-nfc", + libs: [ + "unsupportedappusage", // for android.compat.annotation.UnsupportedAppUsage + ], + srcs: [ + ":framework-nfc-updatable-sources", + ], + defaults: ["framework-non-updatable-unbundled-defaults"], + permitted_packages: [ + "android.nfc", + "com.android.nfc", + ], + hidden_api_packages: [ + "com.android.nfc", + ], + aidl: { + include_dirs: [ + // TODO (b/303286040): Remove these when we change to |framework-module-defaults| + "frameworks/base/nfc/java", + "frameworks/base/core/java", + ], + }, +} diff --git a/nfc/OWNERS b/nfc/OWNERS new file mode 100644 index 000000000000..35e9713f5715 --- /dev/null +++ b/nfc/OWNERS @@ -0,0 +1,2 @@ +# Bug component: 48448 +include platform/packages/apps/Nfc:/OWNERS diff --git a/nfc/TEST_MAPPING b/nfc/TEST_MAPPING new file mode 100644 index 000000000000..5b5ea3790010 --- /dev/null +++ b/nfc/TEST_MAPPING @@ -0,0 +1,10 @@ +{ + "presubmit": [ + { + "name": "NfcManagerTests" + }, + { + "name": "CtsNfcTestCases" + } + ] +} diff --git a/nfc/api/current.txt b/nfc/api/current.txt new file mode 100644 index 000000000000..d802177e249b --- /dev/null +++ b/nfc/api/current.txt @@ -0,0 +1 @@ +// Signature format: 2.0 diff --git a/nfc/api/module-lib-current.txt b/nfc/api/module-lib-current.txt new file mode 100644 index 000000000000..d802177e249b --- /dev/null +++ b/nfc/api/module-lib-current.txt @@ -0,0 +1 @@ +// Signature format: 2.0 diff --git a/nfc/api/module-lib-removed.txt b/nfc/api/module-lib-removed.txt new file mode 100644 index 000000000000..d802177e249b --- /dev/null +++ b/nfc/api/module-lib-removed.txt @@ -0,0 +1 @@ +// Signature format: 2.0 diff --git a/nfc/api/removed.txt b/nfc/api/removed.txt new file mode 100644 index 000000000000..d802177e249b --- /dev/null +++ b/nfc/api/removed.txt @@ -0,0 +1 @@ +// Signature format: 2.0 diff --git a/nfc/api/system-current.txt b/nfc/api/system-current.txt new file mode 100644 index 000000000000..d802177e249b --- /dev/null +++ b/nfc/api/system-current.txt @@ -0,0 +1 @@ +// Signature format: 2.0 diff --git a/nfc/api/system-removed.txt b/nfc/api/system-removed.txt new file mode 100644 index 000000000000..d802177e249b --- /dev/null +++ b/nfc/api/system-removed.txt @@ -0,0 +1 @@ +// Signature format: 2.0 diff --git a/nfc/api/test-current.txt b/nfc/api/test-current.txt new file mode 100644 index 000000000000..d802177e249b --- /dev/null +++ b/nfc/api/test-current.txt @@ -0,0 +1 @@ +// Signature format: 2.0 diff --git a/nfc/api/test-removed.txt b/nfc/api/test-removed.txt new file mode 100644 index 000000000000..d802177e249b --- /dev/null +++ b/nfc/api/test-removed.txt @@ -0,0 +1 @@ +// Signature format: 2.0 diff --git a/nfc/java/android/nfc/Placeholder.java b/nfc/java/android/nfc/Placeholder.java new file mode 100644 index 000000000000..3509644ac106 --- /dev/null +++ b/nfc/java/android/nfc/Placeholder.java @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2023 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.nfc; + +/** + * Placeholder class so new framework-nfc module isn't empty, will be removed once module is + * populated. + * + * @hide + * + */ +public class Placeholder { +} diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/InstallInstalling.java b/packages/PackageInstaller/src/com/android/packageinstaller/InstallInstalling.java index 1088acef0fb0..4992ef1e1c00 100644 --- a/packages/PackageInstaller/src/com/android/packageinstaller/InstallInstalling.java +++ b/packages/PackageInstaller/src/com/android/packageinstaller/InstallInstalling.java @@ -290,7 +290,14 @@ public class InstallInstalling extends AlertActivity { broadcastIntent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_MUTABLE); - session.commit(pendingIntent.getIntentSender()); + try { + session.commit(pendingIntent.getIntentSender()); + } catch (Exception e) { + Log.e(LOG_TAG, "Cannot install package: ", e); + launchFailure(PackageInstaller.STATUS_FAILURE, + PackageManager.INSTALL_FAILED_INTERNAL_ERROR, null); + return; + } mCancelButton.setEnabled(false); setFinishOnTouchOutside(false); } else { diff --git a/services/core/Android.bp b/services/core/Android.bp index 77b8b026097d..37976b58a4e0 100644 --- a/services/core/Android.bp +++ b/services/core/Android.bp @@ -133,7 +133,6 @@ java_library_static { "android.hardware.light-V2.0-java", "android.hardware.gnss-V2-java", "android.hardware.vibrator-V2-java", - "android.nfc.flags-aconfig-java", "app-compat-annotations", "framework-tethering.stubs.module_lib", "service-art.stubs.system_server", diff --git a/services/core/java/com/android/server/adb/AdbDebuggingManager.java b/services/core/java/com/android/server/adb/AdbDebuggingManager.java index 6794f750c82d..3280afdf6703 100644 --- a/services/core/java/com/android/server/adb/AdbDebuggingManager.java +++ b/services/core/java/com/android/server/adb/AdbDebuggingManager.java @@ -1797,8 +1797,13 @@ public class AdbDebuggingManager { mFingerprints); try { - dump.write("user_keys", AdbDebuggingManagerProto.USER_KEYS, - FileUtils.readTextFile(new File("/data/misc/adb/adb_keys"), 0, null)); + File userKeys = new File("/data/misc/adb/adb_keys"); + if (userKeys.exists()) { + dump.write("user_keys", AdbDebuggingManagerProto.USER_KEYS, + FileUtils.readTextFile(userKeys, 0, null)); + } else { + Slog.i(TAG, "No user keys on this device"); + } } catch (IOException e) { Slog.i(TAG, "Cannot read user keys", e); } diff --git a/services/core/java/com/android/server/appop/AppOpsCheckingServiceImpl.java b/services/core/java/com/android/server/appop/AppOpsCheckingServiceImpl.java index 4dfd9b076354..f0dd23ce832a 100644 --- a/services/core/java/com/android/server/appop/AppOpsCheckingServiceImpl.java +++ b/services/core/java/com/android/server/appop/AppOpsCheckingServiceImpl.java @@ -221,20 +221,24 @@ public class AppOpsCheckingServiceImpl implements AppOpsCheckingServiceInterface synchronized (mLock) { SparseIntArray opModes = mUidModes.get(uid, null); if (opModes == null) { - if (mode != defaultMode) { - opModes = new SparseIntArray(); - mUidModes.put(uid, opModes); - opModes.put(op, mode); - scheduleWriteLocked(); + if (mode == defaultMode) { + return false; } + opModes = new SparseIntArray(); + mUidModes.put(uid, opModes); + opModes.put(op, mode); + scheduleWriteLocked(); } else { - if (opModes.indexOfKey(op) >= 0 && opModes.get(op) == mode) { + if (opModes.indexOfKey(op) >= 0) { + if (opModes.get(op) == mode) { + return false; + } + } else if (mode == defaultMode) { return false; } if (mode == defaultMode) { opModes.delete(op); if (opModes.size() <= 0) { - opModes = null; mUidModes.delete(uid); } } else { diff --git a/services/core/java/com/android/server/audio/SpatializerHelper.java b/services/core/java/com/android/server/audio/SpatializerHelper.java index 18f24db8b307..f46586779f4c 100644 --- a/services/core/java/com/android/server/audio/SpatializerHelper.java +++ b/services/core/java/com/android/server/audio/SpatializerHelper.java @@ -965,6 +965,11 @@ public class SpatializerHelper { if (mSpat == null) { mSpatCallback = new SpatializerCallback(); mSpat = AudioSystem.getSpatializer(mSpatCallback); + if (mSpat == null) { + Log.e(TAG, "createSpat(): No Spatializer found"); + postReset(); + return; + } try { //TODO: register heatracking callback only when sensors are registered if (mIsHeadTrackingSupported) { diff --git a/services/core/java/com/android/server/camera/CameraServiceProxy.java b/services/core/java/com/android/server/camera/CameraServiceProxy.java index 3c885a145315..3b18f0c76d25 100644 --- a/services/core/java/com/android/server/camera/CameraServiceProxy.java +++ b/services/core/java/com/android/server/camera/CameraServiceProxy.java @@ -52,7 +52,6 @@ import android.hardware.display.DisplayManager; import android.hardware.usb.UsbDevice; import android.hardware.usb.UsbManager; import android.media.AudioManager; -import android.nfc.INfcAdapter; import android.nfc.NfcAdapter; import android.nfc.NfcManager; import android.os.Binder; @@ -1252,45 +1251,19 @@ public class CameraServiceProxy extends SystemService } } - // TODO(b/303286040): Remove the raw INfcAdapter usage once |ENABLE_NFC_MAINLINE_FLAG| is - // rolled out. - private static final String NFC_SERVICE_BINDER_NAME = "nfc"; - // Flags arguments to NFC adapter to enable/disable NFC - public static final int DISABLE_POLLING_FLAGS = 0x1000; - public static final int ENABLE_POLLING_FLAGS = 0x0000; - private void setNfcReaderModeUsingINfcAdapter(boolean enablePolling) { - IBinder nfcServiceBinder = getBinderService(NFC_SERVICE_BINDER_NAME); - if (nfcServiceBinder == null) { + private void notifyNfcService(boolean enablePolling) { + NfcManager nfcManager = mContext.getSystemService(NfcManager.class); + if (nfcManager == null) { Slog.w(TAG, "Could not connect to NFC service to notify it of camera state"); return; } - INfcAdapter nfcAdapterRaw = INfcAdapter.Stub.asInterface(nfcServiceBinder); - int flags = enablePolling ? ENABLE_POLLING_FLAGS : DISABLE_POLLING_FLAGS; - if (DEBUG) Slog.v(TAG, "Setting NFC reader mode to flags " + flags); - try { - nfcAdapterRaw.setReaderMode(nfcInterfaceToken, null, flags, null); - } catch (RemoteException e) { - Slog.w(TAG, "Could not notify NFC service, remote exception: " + e); - } - } - - private void notifyNfcService(boolean enablePolling) { - if (android.nfc.Flags.enableNfcMainline()) { - NfcManager nfcManager = mContext.getSystemService(NfcManager.class); - if (nfcManager == null) { - Slog.w(TAG, "Could not connect to NFC service to notify it of camera state"); - return; - } - NfcAdapter nfcAdapter = nfcManager.getDefaultAdapter(); - if (nfcAdapter == null) { - Slog.w(TAG, "Could not connect to NFC service to notify it of camera state"); - return; - } - if (DEBUG) Slog.v(TAG, "Setting NFC reader mode. enablePolling: " + enablePolling); - nfcAdapter.setReaderMode(enablePolling); - } else { - setNfcReaderModeUsingINfcAdapter(enablePolling); + NfcAdapter nfcAdapter = nfcManager.getDefaultAdapter(); + if (nfcAdapter == null) { + Slog.w(TAG, "Could not connect to NFC service to notify it of camera state"); + return; } + if (DEBUG) Slog.v(TAG, "Setting NFC reader mode. enablePolling: " + enablePolling); + nfcAdapter.setReaderMode(enablePolling); } private static int[] toArray(Collection<Integer> c) { diff --git a/services/core/java/com/android/server/locksettings/LockSettingsService.java b/services/core/java/com/android/server/locksettings/LockSettingsService.java index ec7f561bd9da..b4c39972dcaa 100644 --- a/services/core/java/com/android/server/locksettings/LockSettingsService.java +++ b/services/core/java/com/android/server/locksettings/LockSettingsService.java @@ -246,7 +246,7 @@ public class LockSettingsService extends ILockSettings.Stub { private static final String MIGRATED_SP_FULL = "migrated_all_users_to_sp_and_bound_keys"; private static final boolean FIX_UNLOCKED_DEVICE_REQUIRED_KEYS = - android.security.Flags.fixUnlockedDeviceRequiredKeys(); + android.security.Flags.fixUnlockedDeviceRequiredKeysV2(); // Duration that LockSettingsService will store the gatekeeper password for. This allows // multiple biometric enrollments without prompting the user to enter their password via diff --git a/services/core/java/com/android/server/locksettings/LockSettingsShellCommand.java b/services/core/java/com/android/server/locksettings/LockSettingsShellCommand.java index 4bac872dbaa9..17f2fcc5b9d8 100644 --- a/services/core/java/com/android/server/locksettings/LockSettingsShellCommand.java +++ b/services/core/java/com/android/server/locksettings/LockSettingsShellCommand.java @@ -155,43 +155,45 @@ class LockSettingsShellCommand extends ShellCommand { try (final PrintWriter pw = getOutPrintWriter();) { pw.println("lockSettings service commands:"); pw.println(""); - pw.println("NOTE: when lock screen is set, all commands require the --old <CREDENTIAL>" - + " argument."); + pw.println("NOTE: when a secure lock screen is set, most commands require the"); + pw.println("--old <CREDENTIAL> option."); pw.println(""); pw.println(" help"); pw.println(" Prints this help text."); pw.println(""); - pw.println(" get-disabled [--old <CREDENTIAL>] [--user USER_ID]"); - pw.println(" Checks whether lock screen is disabled."); + pw.println(" get-disabled [--user USER_ID]"); + pw.println(" Prints true if the lock screen is completely disabled, i.e. set to None."); + pw.println(" Otherwise prints false."); pw.println(""); - pw.println(" set-disabled [--old <CREDENTIAL>] [--user USER_ID] <true|false>"); - pw.println(" When true, disables lock screen."); + pw.println(" set-disabled [--user USER_ID] <true|false>"); + pw.println(" Sets whether the lock screen is disabled. If the lock screen is secure, this"); + pw.println(" has no immediate effect. I.e. this can only change between Swipe and None."); pw.println(""); pw.println(" set-pattern [--old <CREDENTIAL>] [--user USER_ID] <PATTERN>"); - pw.println(" Sets the lock screen as pattern, using the given PATTERN to unlock."); + pw.println(" Sets a secure lock screen that uses the given PATTERN. PATTERN is a series"); + pw.println(" of digits 1-9 that identify the cells of the pattern."); pw.println(""); pw.println(" set-pin [--old <CREDENTIAL>] [--user USER_ID] <PIN>"); - pw.println(" Sets the lock screen as PIN, using the given PIN to unlock."); + pw.println(" Sets a secure lock screen that uses the given PIN."); pw.println(""); pw.println(" set-password [--old <CREDENTIAL>] [--user USER_ID] <PASSWORD>"); - pw.println(" Sets the lock screen as password, using the given PASSWORD to unlock."); + pw.println(" Sets a secure lock screen that uses the given PASSWORD."); pw.println(""); pw.println(" clear [--old <CREDENTIAL>] [--user USER_ID]"); - pw.println(" Clears the lock credentials."); + pw.println(" Clears the lock credential."); pw.println(""); pw.println(" verify [--old <CREDENTIAL>] [--user USER_ID]"); - pw.println(" Verifies the lock credentials."); + pw.println(" Verifies the lock credential."); pw.println(""); pw.println(" remove-cache [--user USER_ID]"); pw.println(" Removes cached unified challenge for the managed profile."); pw.println(""); pw.println(" set-resume-on-reboot-provider-package <package_name>"); - pw.println(" Sets the package name for server based resume on reboot service " - + "provider."); + pw.println(" Sets the package name for server based resume on reboot service provider."); pw.println(""); pw.println(" require-strong-auth [--user USER_ID] <reason>"); - pw.println(" Requires the strong authentication. The current supported reasons: " - + "STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN."); + pw.println(" Requires strong authentication. The current supported reasons:"); + pw.println(" STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN."); pw.println(""); } } diff --git a/services/core/java/com/android/server/pm/DumpHelper.java b/services/core/java/com/android/server/pm/DumpHelper.java index fcaaa90dbc8a..c33af9b28b62 100644 --- a/services/core/java/com/android/server/pm/DumpHelper.java +++ b/services/core/java/com/android/server/pm/DumpHelper.java @@ -160,7 +160,7 @@ final class DumpHelper { pkg = snapshot.resolveInternalPackageName(pkg, PackageManager.VERSION_CODE_HIGHEST); - pw.println(mPermissionManager.checkPermission(perm, pkg, user)); + pw.println(mPermissionManager.checkPermission(pkg, perm, user)); return; } else if ("l".equals(cmd) || "libraries".equals(cmd)) { dumpState.setDump(DumpState.DUMP_LIBS); diff --git a/services/core/java/com/android/server/pm/UserDataPreparer.java b/services/core/java/com/android/server/pm/UserDataPreparer.java index 6d58d3401675..8adb5661ad1d 100644 --- a/services/core/java/com/android/server/pm/UserDataPreparer.java +++ b/services/core/java/com/android/server/pm/UserDataPreparer.java @@ -23,10 +23,10 @@ import android.content.pm.UserInfo; import android.os.Environment; import android.os.FileUtils; import android.os.RecoverySystem; -import android.os.storage.StorageManager; -import android.os.storage.VolumeInfo; import android.os.SystemProperties; import android.os.UserHandle; +import android.os.storage.StorageManager; +import android.os.storage.VolumeInfo; import android.system.ErrnoException; import android.system.Os; import android.system.OsConstants; @@ -35,6 +35,7 @@ import android.util.Slog; import android.util.SparseArray; import com.android.internal.annotations.VisibleForTesting; +import com.android.server.utils.Slogf; import java.io.File; import java.io.IOException; @@ -43,7 +44,6 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Objects; -import java.util.Set; /** * Helper class for preparing and destroying user storage @@ -65,31 +65,37 @@ class UserDataPreparer { /** * Prepare storage areas for given user on all mounted devices. */ - void prepareUserData(int userId, int userSerial, int flags) { + void prepareUserData(UserInfo userInfo, int flags) { synchronized (mInstallLock) { final StorageManager storage = mContext.getSystemService(StorageManager.class); /* * Internal storage must be prepared before adoptable storage, since the user's volume * keys are stored in their internal storage. */ - prepareUserDataLI(null /* internal storage */, userId, userSerial, flags, true); + prepareUserDataLI(null /* internal storage */, userInfo, flags, true); for (VolumeInfo vol : storage.getWritablePrivateVolumes()) { final String volumeUuid = vol.getFsUuid(); if (volumeUuid != null) { - prepareUserDataLI(volumeUuid, userId, userSerial, flags, true); + prepareUserDataLI(volumeUuid, userInfo, flags, true); } } } } - private void prepareUserDataLI(String volumeUuid, int userId, int userSerial, int flags, + private void prepareUserDataLI(String volumeUuid, UserInfo userInfo, int flags, boolean allowRecover) { - // Prepare storage and verify that serial numbers are consistent; if - // there's a mismatch we need to destroy to avoid leaking data + final int userId = userInfo.id; + final int userSerial = userInfo.serialNumber; final StorageManager storage = mContext.getSystemService(StorageManager.class); + final boolean isNewUser = userInfo.lastLoggedInTime == 0; + Slogf.d(TAG, "Preparing user data; volumeUuid=%s, userId=%d, flags=0x%x, isNewUser=%s", + volumeUuid, userId, flags, isNewUser); try { + // Prepare CE and/or DE storage. storage.prepareUserStorage(volumeUuid, userId, userSerial, flags); + // Ensure that the data directories of a removed user with the same ID are not being + // reused. New users must get fresh data directories, to avoid leaking data. if ((flags & StorageManager.FLAG_STORAGE_DE) != 0) { enforceSerialNumber(getDataUserDeDirectory(volumeUuid, userId), userSerial); if (Objects.equals(volumeUuid, StorageManager.UUID_PRIVATE_INTERNAL)) { @@ -103,9 +109,10 @@ class UserDataPreparer { } } + // Prepare the app data directories. mInstaller.createUserData(volumeUuid, userId, userSerial, flags); - // CE storage is available after they are prepared. + // If applicable, record that the system user's CE storage has been prepared. if ((flags & StorageManager.FLAG_STORAGE_CE) != 0 && (userId == UserHandle.USER_SYSTEM)) { String propertyName = "sys.user." + userId + ".ce_available"; @@ -113,20 +120,31 @@ class UserDataPreparer { SystemProperties.set(propertyName, "true"); } } catch (Exception e) { - logCriticalInfo(Log.WARN, "Destroying user " + userId + " on volume " + volumeUuid - + " because we failed to prepare: " + e); - destroyUserDataLI(volumeUuid, userId, flags); - + // Failed to prepare user data. For new users, specifically users that haven't ever + // been unlocked, destroy the user data, and try again (if not already retried). This + // might be effective at resolving some errors, such as stale directories from a reused + // user ID. Don't auto-destroy data for existing users, since issues with existing + // users might be fixable via an OTA without having to wipe the user's data. + if (isNewUser) { + logCriticalInfo(Log.ERROR, "Destroying user " + userId + " on volume " + volumeUuid + + " because we failed to prepare: " + e); + destroyUserDataLI(volumeUuid, userId, flags); + } else { + logCriticalInfo(Log.ERROR, "Failed to prepare user " + userId + " on volume " + + volumeUuid + ": " + e); + } if (allowRecover) { // Try one last time; if we fail again we're really in trouble - prepareUserDataLI(volumeUuid, userId, userSerial, - flags | StorageManager.FLAG_STORAGE_DE, false); + prepareUserDataLI(volumeUuid, userInfo, flags | StorageManager.FLAG_STORAGE_DE, + false); } else { + // If internal storage of the system user fails to prepare on first boot, then + // things are *really* broken, so we might as well reboot to recovery right away. try { Log.wtf(TAG, "prepareUserData failed for user " + userId, e); - if (userId == UserHandle.USER_SYSTEM) { + if (isNewUser && userId == UserHandle.USER_SYSTEM && volumeUuid == null) { RecoverySystem.rebootPromptAndWipeUserData(mContext, - "prepareUserData failed for system user"); + "failed to prepare internal storage for system user"); } } catch (IOException e2) { throw new RuntimeException("error rebooting into recovery", e2); diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java index e11e226054e3..68148482c68a 100644 --- a/services/core/java/com/android/server/pm/UserManagerService.java +++ b/services/core/java/com/android/server/pm/UserManagerService.java @@ -4914,8 +4914,7 @@ public class UserManagerService extends IUserManager.Stub { // unlocked. We do this to ensure that CE storage isn't prepared before the CE key is // saved to disk. This also matches what is done for user 0. t.traceBegin("prepareUserData"); - mUserDataPreparer.prepareUserData(userId, userInfo.serialNumber, - StorageManager.FLAG_STORAGE_DE); + mUserDataPreparer.prepareUserData(userInfo, StorageManager.FLAG_STORAGE_DE); t.traceEnd(); t.traceBegin("LSS.createNewUser"); @@ -6199,12 +6198,11 @@ public class UserManagerService extends IUserManager.Stub { } TimingsTraceAndSlog t = new TimingsTraceAndSlog(); t.traceBegin("onBeforeStartUser-" + userId); - final int userSerial = userInfo.serialNumber; // Migrate only if build fingerprints mismatch boolean migrateAppsData = !PackagePartitions.FINGERPRINT.equals( userInfo.lastLoggedInFingerprint); t.traceBegin("prepareUserData"); - mUserDataPreparer.prepareUserData(userId, userSerial, StorageManager.FLAG_STORAGE_DE); + mUserDataPreparer.prepareUserData(userInfo, StorageManager.FLAG_STORAGE_DE); t.traceEnd(); t.traceBegin("reconcileAppsData"); getPackageManagerInternal().reconcileAppsData(userId, StorageManager.FLAG_STORAGE_DE, @@ -6230,14 +6228,13 @@ public class UserManagerService extends IUserManager.Stub { if (userInfo == null) { return; } - final int userSerial = userInfo.serialNumber; // Migrate only if build fingerprints mismatch boolean migrateAppsData = !PackagePartitions.FINGERPRINT.equals( userInfo.lastLoggedInFingerprint); final TimingsTraceAndSlog t = new TimingsTraceAndSlog(); t.traceBegin("prepareUserData-" + userId); - mUserDataPreparer.prepareUserData(userId, userSerial, StorageManager.FLAG_STORAGE_CE); + mUserDataPreparer.prepareUserData(userInfo, StorageManager.FLAG_STORAGE_CE); t.traceEnd(); StorageManagerInternal smInternal = LocalServices.getService(StorageManagerInternal.class); diff --git a/services/core/java/com/android/server/pm/dex/ArtStatsLogUtils.java b/services/core/java/com/android/server/pm/dex/ArtStatsLogUtils.java index d0c346a63889..57f4a5ddb2bd 100644 --- a/services/core/java/com/android/server/pm/dex/ArtStatsLogUtils.java +++ b/services/core/java/com/android/server/pm/dex/ArtStatsLogUtils.java @@ -337,7 +337,8 @@ public class ArtStatsLogUtils { 0, // deprecated, used to be durationIncludingSleepMs 0, // optimizedPackagesCount 0, // packagesDependingOnBootClasspathCount - 0); // totalPackagesCount + 0, // totalPackagesCount + ArtStatsLog.BACKGROUND_DEXOPT_JOB_ENDED__PASS__PASS_UNKNOWN); } } } diff --git a/services/core/java/com/android/server/trust/TrustManagerService.java b/services/core/java/com/android/server/trust/TrustManagerService.java index 635e11be3a16..24c971c678c0 100644 --- a/services/core/java/com/android/server/trust/TrustManagerService.java +++ b/services/core/java/com/android/server/trust/TrustManagerService.java @@ -829,7 +829,7 @@ public class TrustManagerService extends SystemService { } final boolean trusted; - if (android.security.Flags.fixUnlockedDeviceRequiredKeys()) { + if (android.security.Flags.fixUnlockedDeviceRequiredKeysV2()) { trusted = getUserTrustStateInner(id) == TrustState.TRUSTED; } else { trusted = aggregateIsTrusted(id); @@ -1647,8 +1647,22 @@ public class TrustManagerService extends SystemService { fout.printf(" User \"%s\" (id=%d, flags=%#x)", user.name, user.id, user.flags); if (!user.supportsSwitchToByUser()) { - fout.println("(managed profile)"); - fout.println(" disabled because switching to this user is not possible."); + final boolean locked; + if (user.isProfile()) { + if (mLockPatternUtils.isSeparateProfileChallengeEnabled(user.id)) { + fout.print(" (profile with separate challenge)"); + locked = isDeviceLockedInner(user.id); + } else { + fout.print(" (profile with unified challenge)"); + locked = isDeviceLockedInner(resolveProfileParent(user.id)); + } + } else { + fout.println(" (user that cannot be switched to)"); + locked = isDeviceLockedInner(user.id); + } + fout.println(": deviceLocked=" + dumpBool(locked)); + fout.println( + " Trust agents disabled because switching to this user is not possible."); return; } if (isCurrent) { diff --git a/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/UserDataPreparerTest.java b/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/UserDataPreparerTest.java index afbe352ad676..e5be4d9aa755 100644 --- a/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/UserDataPreparerTest.java +++ b/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/UserDataPreparerTest.java @@ -21,6 +21,8 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.mockito.Matchers.eq; import static org.mockito.Matchers.isNull; +import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -56,6 +58,7 @@ public class UserDataPreparerTest { private static final int TEST_USER_SERIAL = 1000; private static final int TEST_USER_ID = 10; + private static final UserInfo TEST_USER = new UserInfo(); private TestUserDataPreparer mUserDataPreparer; @@ -72,6 +75,8 @@ public class UserDataPreparerTest { @Before public void setup() { + TEST_USER.id = TEST_USER_ID; + TEST_USER.serialNumber = TEST_USER_SERIAL; Context ctx = InstrumentationRegistry.getContext(); FileUtils.deleteContents(ctx.getCacheDir()); mInstallLock = new Object(); @@ -92,8 +97,7 @@ public class UserDataPreparerTest { userDeDir.mkdirs(); File systemDeDir = mUserDataPreparer.getDataSystemDeDirectory(TEST_USER_ID); systemDeDir.mkdirs(); - mUserDataPreparer - .prepareUserData(TEST_USER_ID, TEST_USER_SERIAL, StorageManager.FLAG_STORAGE_DE); + mUserDataPreparer.prepareUserData(TEST_USER, StorageManager.FLAG_STORAGE_DE); verify(mStorageManagerMock).prepareUserStorage(isNull(String.class), eq(TEST_USER_ID), eq(TEST_USER_SERIAL), eq(StorageManager.FLAG_STORAGE_DE)); verify(mInstaller).createUserData(isNull(String.class), eq(TEST_USER_ID), @@ -110,8 +114,7 @@ public class UserDataPreparerTest { userCeDir.mkdirs(); File systemCeDir = mUserDataPreparer.getDataSystemCeDirectory(TEST_USER_ID); systemCeDir.mkdirs(); - mUserDataPreparer - .prepareUserData(TEST_USER_ID, TEST_USER_SERIAL, StorageManager.FLAG_STORAGE_CE); + mUserDataPreparer.prepareUserData(TEST_USER, StorageManager.FLAG_STORAGE_CE); verify(mStorageManagerMock).prepareUserStorage(isNull(String.class), eq(TEST_USER_ID), eq(TEST_USER_SERIAL), eq(StorageManager.FLAG_STORAGE_CE)); verify(mInstaller).createUserData(isNull(String.class), eq(TEST_USER_ID), @@ -123,6 +126,28 @@ public class UserDataPreparerTest { } @Test + public void testPrepareUserData_forNewUser_destroysOnFailure() throws Exception { + TEST_USER.lastLoggedInTime = 0; + doThrow(new IllegalStateException("expected exception for test")).when(mStorageManagerMock) + .prepareUserStorage(isNull(String.class), eq(TEST_USER_ID), eq(TEST_USER_SERIAL), + eq(StorageManager.FLAG_STORAGE_CE)); + mUserDataPreparer.prepareUserData(TEST_USER, StorageManager.FLAG_STORAGE_CE); + verify(mStorageManagerMock).destroyUserStorage(isNull(String.class), eq(TEST_USER_ID), + eq(StorageManager.FLAG_STORAGE_CE)); + } + + @Test + public void testPrepareUserData_forExistingUser_doesNotDestroyOnFailure() throws Exception { + TEST_USER.lastLoggedInTime = System.currentTimeMillis(); + doThrow(new IllegalStateException("expected exception for test")).when(mStorageManagerMock) + .prepareUserStorage(isNull(String.class), eq(TEST_USER_ID), eq(TEST_USER_SERIAL), + eq(StorageManager.FLAG_STORAGE_CE)); + mUserDataPreparer.prepareUserData(TEST_USER, StorageManager.FLAG_STORAGE_CE); + verify(mStorageManagerMock, never()).destroyUserStorage(isNull(String.class), + eq(TEST_USER_ID), eq(StorageManager.FLAG_STORAGE_CE)); + } + + @Test public void testDestroyUserData_De_DoesNotDestroyCe() throws Exception { // Add file in CE storage File systemCeDir = mUserDataPreparer.getDataSystemCeDirectory(TEST_USER_ID); diff --git a/tests/NetworkSecurityConfigTest/OWNERS b/tests/NetworkSecurityConfigTest/OWNERS index aa87958f1d53..90e1bed9fb26 100644 --- a/tests/NetworkSecurityConfigTest/OWNERS +++ b/tests/NetworkSecurityConfigTest/OWNERS @@ -1 +1,2 @@ include /services/core/java/com/android/server/net/OWNERS +include /core/java/android/security/net/OWNERS diff --git a/tests/TrustTests/src/android/trust/test/GrantAndRevokeTrustTest.kt b/tests/TrustTests/src/android/trust/test/GrantAndRevokeTrustTest.kt index 1dfd5c06167b..d0e56268a27d 100644 --- a/tests/TrustTests/src/android/trust/test/GrantAndRevokeTrustTest.kt +++ b/tests/TrustTests/src/android/trust/test/GrantAndRevokeTrustTest.kt @@ -93,7 +93,7 @@ class GrantAndRevokeTrustTest { } @Test - @RequiresFlagsEnabled(android.security.Flags.FLAG_FIX_UNLOCKED_DEVICE_REQUIRED_KEYS) + @RequiresFlagsEnabled(android.security.Flags.FLAG_FIX_UNLOCKED_DEVICE_REQUIRED_KEYS_V2) fun grantCannotActivelyUnlockDevice() { // On automotive, trust agents can actively unlock the device. assumeFalse(packageManager.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)) @@ -120,7 +120,7 @@ class GrantAndRevokeTrustTest { } @Test - @RequiresFlagsDisabled(android.security.Flags.FLAG_FIX_UNLOCKED_DEVICE_REQUIRED_KEYS) + @RequiresFlagsDisabled(android.security.Flags.FLAG_FIX_UNLOCKED_DEVICE_REQUIRED_KEYS_V2) fun grantCouldCauseWrongDeviceLockedStateDueToBug() { // On automotive, trust agents can actively unlock the device. assumeFalse(packageManager.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)) diff --git a/tests/TrustTests/src/android/trust/test/lib/LockStateTrackingRule.kt b/tests/TrustTests/src/android/trust/test/lib/LockStateTrackingRule.kt index 5a8f82827253..01218099f34c 100644 --- a/tests/TrustTests/src/android/trust/test/lib/LockStateTrackingRule.kt +++ b/tests/TrustTests/src/android/trust/test/lib/LockStateTrackingRule.kt @@ -36,7 +36,8 @@ import org.junit.runners.model.Statement class LockStateTrackingRule : TestRule { private val context: Context = getApplicationContext() private val windowManager = checkNotNull(WindowManagerGlobal.getWindowManagerService()) - private val keyguardManager = context.getSystemService(KeyguardManager::class.java) as KeyguardManager + private val keyguardManager = + context.getSystemService(KeyguardManager::class.java) as KeyguardManager @Volatile lateinit var trustState: TrustState private set @@ -63,7 +64,7 @@ class LockStateTrackingRule : TestRule { wait("not trusted") { trustState.trusted == false } } - // TODO(b/299298338) remove this when removing FLAG_FIX_UNLOCKED_DEVICE_REQUIRED_KEYS + // TODO(b/299298338) remove this when removing FLAG_FIX_UNLOCKED_DEVICE_REQUIRED_KEYS_V2 fun assertUnlockedButNotReally() { wait("device unlocked") { !keyguardManager.isDeviceLocked } wait("not trusted") { trustState.trusted == false } @@ -87,7 +88,7 @@ class LockStateTrackingRule : TestRule { trustGrantedMessages: MutableList<String> ) { Log.d(TAG, "Device became trusted=$enabled") - trustState = trustState.copy(trusted=enabled) + trustState = trustState.copy(trusted = enabled) } } |