diff options
110 files changed, 1210 insertions, 458 deletions
diff --git a/AconfigFlags.bp b/AconfigFlags.bp index 54baae5a886d..86bcdea1b0e7 100644 --- a/AconfigFlags.bp +++ b/AconfigFlags.bp @@ -258,6 +258,11 @@ java_aconfig_library { defaults: ["framework-minus-apex-aconfig-java-defaults"], } +cc_aconfig_library { + name: "android_security_flags_aconfig_c_lib", + aconfig_declarations: "android.security.flags-aconfig", +} + // UsageStats aconfig_declarations { name: "android.app.usage.flags-aconfig", diff --git a/Android.bp b/Android.bp index 900fba03daa7..f0f11c1b300d 100644 --- a/Android.bp +++ b/Android.bp @@ -113,7 +113,7 @@ filegroup { ":android.security.legacykeystore-java-source", ":android.security.maintenance-java-source", ":android.security.metrics-java-source", - ":android.system.keystore2-V3-java-source", + ":android.system.keystore2-V4-java-source", ":android.hardware.cas-V1-java-source", ":credstore_aidl", ":dumpstate_aidl", diff --git a/DREAM_MANAGER_OWNERS b/DREAM_MANAGER_OWNERS deleted file mode 100644 index 48bde6024cba..000000000000 --- a/DREAM_MANAGER_OWNERS +++ /dev/null @@ -1 +0,0 @@ -brycelee@google.com diff --git a/PREUPLOAD.cfg b/PREUPLOAD.cfg index b42f7bc0ca94..624a70833b03 100644 --- a/PREUPLOAD.cfg +++ b/PREUPLOAD.cfg @@ -30,4 +30,4 @@ ktfmt_hook = ${REPO_ROOT}/external/ktfmt/ktfmt.py --check -i ${REPO_ROOT}/framew ktlint_hook = ${REPO_ROOT}/prebuilts/ktlint/ktlint.py --no-verify-format -f ${PREUPLOAD_FILES} # This flag check hook runs only for "packages/SystemUI" subdirectory. If you want to include this check for other subdirectories, please modify flag_check.py. -flag_hook = ${REPO_ROOT}/frameworks/base/packages/SystemUI/flag_check.py --msg=${PREUPLOAD_COMMIT_MESSAGE} --files=${PREUPLOAD_FILES} --project=${REPO_PATH} +flag_hook = ${REPO_ROOT}/frameworks/base/packages/SystemUI/flag_check.py --msg=${PREUPLOAD_COMMIT_MESSAGE} --files=${PREUPLOAD_FILES} --project=${REPO_PROJECT} diff --git a/apct-tests/perftests/OWNERS b/apct-tests/perftests/OWNERS index 8ff3f9bc6620..f4346b150ca2 100644 --- a/apct-tests/perftests/OWNERS +++ b/apct-tests/perftests/OWNERS @@ -8,4 +8,3 @@ philipcuadra@google.com shayba@google.com shombert@google.com timmurray@google.com -wessam@google.com diff --git a/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java b/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java index 6383ed873e59..a49ad9863c5f 100644 --- a/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java +++ b/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java @@ -618,6 +618,7 @@ public class DeviceIdleController extends SystemService * List of end times for app-IDs that are temporarily marked as being allowed to access * the network and acquire wakelocks. Times are in milliseconds. */ + @GuardedBy("this") private final SparseArray<Pair<MutableLong, String>> mTempWhitelistAppIdEndTimes = new SparseArray<>(); @@ -4999,7 +5000,9 @@ public class DeviceIdleController extends SystemService if (!DumpUtils.checkDumpPermission(getContext(), TAG, pw)) { return -1; } - dumpTempWhitelistSchedule(pw, false); + synchronized (this) { + dumpTempWhitelistScheduleLocked(pw, false); + } } } else if ("except-idle-whitelist".equals(cmd)) { getContext().enforceCallingOrSelfPermission( @@ -5283,7 +5286,7 @@ public class DeviceIdleController extends SystemService pw.println(); } } - dumpTempWhitelistSchedule(pw, true); + dumpTempWhitelistScheduleLocked(pw, true); size = mTempWhitelistAppIdArray != null ? mTempWhitelistAppIdArray.length : 0; if (size > 0) { @@ -5411,7 +5414,8 @@ public class DeviceIdleController extends SystemService } } - void dumpTempWhitelistSchedule(PrintWriter pw, boolean printTitle) { + @GuardedBy("this") + void dumpTempWhitelistScheduleLocked(PrintWriter pw, boolean printTitle) { final int size = mTempWhitelistAppIdEndTimes.size(); if (size > 0) { String prefix = ""; diff --git a/apex/jobscheduler/service/java/com/android/server/job/controllers/IdleController.java b/apex/jobscheduler/service/java/com/android/server/job/controllers/IdleController.java index adee322f60cf..f722e41c6195 100644 --- a/apex/jobscheduler/service/java/com/android/server/job/controllers/IdleController.java +++ b/apex/jobscheduler/service/java/com/android/server/job/controllers/IdleController.java @@ -48,6 +48,7 @@ public final class IdleController extends RestrictingController implements Idlen private static final String TAG = "JobScheduler.IdleController"; // Policy: we decide that we're "idle" if the device has been unused / // screen off or dreaming or wireless charging dock idle for at least this long + @GuardedBy("mLock") final ArraySet<JobStatus> mTrackedTasks = new ArraySet<>(); IdlenessTracker mIdleTracker; private final FlexibilityController mFlexibilityController; @@ -118,8 +119,10 @@ public final class IdleController extends RestrictingController implements Idlen for (int i = mTrackedTasks.size()-1; i >= 0; i--) { mTrackedTasks.valueAt(i).setIdleConstraintSatisfied(nowElapsed, isIdle); } + if (!mTrackedTasks.isEmpty()) { + mStateChangedListener.onControllerStateChanged(mTrackedTasks); + } } - mStateChangedListener.onControllerStateChanged(mTrackedTasks); } /** diff --git a/api/StubLibraries.bp b/api/StubLibraries.bp index 4a73bf05e012..f77f1c638f09 100644 --- a/api/StubLibraries.bp +++ b/api/StubLibraries.bp @@ -44,8 +44,8 @@ non_updatable_exportable_droidstubs { removed_api_file: ":non-updatable-removed.txt", }, last_released: { - api_file: ":android-non-updatable.api.public.latest", - removed_api_file: ":android-non-updatable-removed.api.public.latest", + api_file: ":android-non-updatable.api.combined.public.latest", + removed_api_file: ":android-non-updatable-removed.api.combined.public.latest", baseline_file: ":android-non-updatable-incompatibilities.api.public.latest", }, api_lint: { @@ -124,8 +124,8 @@ non_updatable_exportable_droidstubs { removed_api_file: ":non-updatable-system-removed.txt", }, last_released: { - api_file: ":android-non-updatable.api.system.latest", - removed_api_file: ":android-non-updatable-removed.api.system.latest", + api_file: ":android-non-updatable.api.combined.system.latest", + removed_api_file: ":android-non-updatable-removed.api.combined.system.latest", baseline_file: ":android-non-updatable-incompatibilities.api.system.latest", }, api_lint: { @@ -263,8 +263,8 @@ non_updatable_exportable_droidstubs { removed_api_file: ":non-updatable-module-lib-removed.txt", }, last_released: { - api_file: ":android-non-updatable.api.module-lib.latest", - removed_api_file: ":android-non-updatable-removed.api.module-lib.latest", + api_file: ":android-non-updatable.api.combined.module-lib.latest", + removed_api_file: ":android-non-updatable-removed.api.combined.module-lib.latest", baseline_file: ":android-non-updatable-incompatibilities.api.module-lib.latest", }, api_lint: { diff --git a/cmds/bootanimation/Android.bp b/cmds/bootanimation/Android.bp index 98767ee733ad..3534624a58a2 100644 --- a/cmds/bootanimation/Android.bp +++ b/cmds/bootanimation/Android.bp @@ -74,7 +74,4 @@ cc_library_shared { "libGLESv2", "libgui", ], - whole_static_libs: [ - "libc++fs", - ], } diff --git a/cmds/bootanimation/BootAnimation.cpp b/cmds/bootanimation/BootAnimation.cpp index 5adcd930e341..7eb9d0f3ea91 100644 --- a/cmds/bootanimation/BootAnimation.cpp +++ b/cmds/bootanimation/BootAnimation.cpp @@ -1335,7 +1335,8 @@ bool BootAnimation::preloadZip(Animation& animation) { if (path.string() == animation.parts[j].path.c_str()) { uint16_t method; // supports only stored png files - if (zip->getEntryInfo(entry, &method, nullptr, nullptr, nullptr, nullptr, nullptr)) { + if (zip->getEntryInfo(entry, &method, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr)) { if (method == ZipFileRO::kCompressStored) { FileMap* map = zip->createEntryFileMap(entry); if (map) { diff --git a/cmds/hid/jni/com_android_commands_hid_Device.cpp b/cmds/hid/jni/com_android_commands_hid_Device.cpp index 8b8d361edbd4..a142450ac0c6 100644 --- a/cmds/hid/jni/com_android_commands_hid_Device.cpp +++ b/cmds/hid/jni/com_android_commands_hid_Device.cpp @@ -134,8 +134,9 @@ JNIEnv* DeviceCallback::getJNIEnv() { return env; } -std::unique_ptr<Device> Device::open(int32_t id, const char* name, int32_t vid, int32_t pid, - uint16_t bus, const std::vector<uint8_t>& descriptor, +std::unique_ptr<Device> Device::open(int32_t id, const char* name, const char* uniq, int32_t vid, + int32_t pid, uint16_t bus, + const std::vector<uint8_t>& descriptor, std::unique_ptr<DeviceCallback> callback) { size_t size = descriptor.size(); if (size > HID_MAX_DESCRIPTOR_SIZE) { @@ -152,8 +153,7 @@ std::unique_ptr<Device> Device::open(int32_t id, const char* name, int32_t vid, struct uhid_event ev = {}; ev.type = UHID_CREATE2; strlcpy(reinterpret_cast<char*>(ev.u.create2.name), name, sizeof(ev.u.create2.name)); - std::string uniq = android::base::StringPrintf("Id: %d", id); - strlcpy(reinterpret_cast<char*>(ev.u.create2.uniq), uniq.c_str(), sizeof(ev.u.create2.uniq)); + strlcpy(reinterpret_cast<char*>(ev.u.create2.uniq), uniq, sizeof(ev.u.create2.uniq)); memcpy(&ev.u.create2.rd_data, descriptor.data(), size * sizeof(ev.u.create2.rd_data[0])); ev.u.create2.rd_size = size; ev.u.create2.bus = bus; @@ -314,19 +314,31 @@ std::vector<uint8_t> getData(JNIEnv* env, jbyteArray javaArray) { return data; } -static jlong openDevice(JNIEnv* env, jclass /* clazz */, jstring rawName, jint id, jint vid, - jint pid, jint bus, jbyteArray rawDescriptor, jobject callback) { +static jlong openDevice(JNIEnv* env, jclass /* clazz */, jstring rawName, jstring rawUniq, jint id, + jint vid, jint pid, jint bus, jbyteArray rawDescriptor, jobject callback) { ScopedUtfChars name(env, rawName); if (name.c_str() == nullptr) { return 0; } + std::string uniq; + if (rawUniq != nullptr) { + uniq = ScopedUtfChars(env, rawUniq); + } else { + uniq = android::base::StringPrintf("Id: %d", id); + } + + if (uniq.c_str() == nullptr) { + return 0; + } + std::vector<uint8_t> desc = getData(env, rawDescriptor); std::unique_ptr<uhid::DeviceCallback> cb(new uhid::DeviceCallback(env, callback)); std::unique_ptr<uhid::Device> d = - uhid::Device::open(id, reinterpret_cast<const char*>(name.c_str()), vid, pid, bus, desc, + uhid::Device::open(id, reinterpret_cast<const char*>(name.c_str()), + reinterpret_cast<const char*>(uniq.c_str()), vid, pid, bus, desc, std::move(cb)); return reinterpret_cast<jlong>(d.release()); } @@ -370,7 +382,7 @@ static void closeDevice(JNIEnv* /* env */, jclass /* clazz */, jlong ptr) { static JNINativeMethod sMethods[] = { {"nativeOpenDevice", - "(Ljava/lang/String;IIII[B" + "(Ljava/lang/String;Ljava/lang/String;IIII[B" "Lcom/android/commands/hid/Device$DeviceCallback;)J", reinterpret_cast<void*>(openDevice)}, {"nativeSendReport", "(J[B)V", reinterpret_cast<void*>(sendReport)}, diff --git a/cmds/hid/jni/com_android_commands_hid_Device.h b/cmds/hid/jni/com_android_commands_hid_Device.h index 9c6060d837e0..bc7a9092cc4e 100644 --- a/cmds/hid/jni/com_android_commands_hid_Device.h +++ b/cmds/hid/jni/com_android_commands_hid_Device.h @@ -42,8 +42,9 @@ private: class Device { public: - static std::unique_ptr<Device> open(int32_t id, const char* name, int32_t vid, int32_t pid, - uint16_t bus, const std::vector<uint8_t>& descriptor, + static std::unique_ptr<Device> open(int32_t id, const char* name, const char* uniq, int32_t vid, + int32_t pid, uint16_t bus, + const std::vector<uint8_t>& descriptor, std::unique_ptr<DeviceCallback> callback); ~Device(); diff --git a/cmds/hid/src/com/android/commands/hid/Device.java b/cmds/hid/src/com/android/commands/hid/Device.java index 0415037cfc9f..4e8adc3af55c 100644 --- a/cmds/hid/src/com/android/commands/hid/Device.java +++ b/cmds/hid/src/com/android/commands/hid/Device.java @@ -71,6 +71,7 @@ public class Device { private static native long nativeOpenDevice( String name, + String uniq, int id, int vid, int pid, @@ -89,6 +90,7 @@ public class Device { public Device( int id, String name, + String uniq, int vid, int pid, int bus, @@ -113,8 +115,9 @@ public class Device { } else { args.arg1 = id + ":" + vid + ":" + pid; } - args.arg2 = descriptor; - args.arg3 = report; + args.arg2 = uniq; + args.arg3 = descriptor; + args.arg4 = report; mHandler.obtainMessage(MSG_OPEN_DEVICE, args).sendToTarget(); mTimeToSend = SystemClock.uptimeMillis(); } @@ -167,11 +170,12 @@ public class Device { mPtr = nativeOpenDevice( (String) args.arg1, + (String) args.arg2, args.argi1, args.argi2, args.argi3, args.argi4, - (byte[]) args.arg2, + (byte[]) args.arg3, new DeviceCallback()); pauseEvents(); break; diff --git a/cmds/hid/src/com/android/commands/hid/Event.java b/cmds/hid/src/com/android/commands/hid/Event.java index 3efb79766b94..3b022796356b 100644 --- a/cmds/hid/src/com/android/commands/hid/Event.java +++ b/cmds/hid/src/com/android/commands/hid/Event.java @@ -56,6 +56,7 @@ public class Event { private int mId; private String mCommand; private String mName; + private String mUniq; private byte[] mDescriptor; private int mVid; private int mPid; @@ -78,6 +79,10 @@ public class Event { return mName; } + public String getUniq() { + return mUniq; + } + public byte[] getDescriptor() { return mDescriptor; } @@ -116,8 +121,9 @@ public class Event { public String toString() { return "Event{id=" + mId - + ", command=" + String.valueOf(mCommand) - + ", name=" + String.valueOf(mName) + + ", command=" + mCommand + + ", name=" + mName + + ", uniq=" + mUniq + ", descriptor=" + Arrays.toString(mDescriptor) + ", vid=" + mVid + ", pid=" + mPid @@ -149,6 +155,10 @@ public class Event { mEvent.mName = name; } + public void setUniq(String uniq) { + mEvent.mUniq = uniq; + } + public void setDescriptor(byte[] descriptor) { mEvent.mDescriptor = descriptor; } @@ -247,6 +257,9 @@ public class Event { case "name": eb.setName(mReader.nextString()); break; + case "uniq": + eb.setUniq(mReader.nextString()); + break; case "vid": eb.setVid(readInt()); break; diff --git a/cmds/hid/src/com/android/commands/hid/Hid.java b/cmds/hid/src/com/android/commands/hid/Hid.java index 2db791fe90bd..5ebfd959ef33 100644 --- a/cmds/hid/src/com/android/commands/hid/Hid.java +++ b/cmds/hid/src/com/android/commands/hid/Hid.java @@ -117,8 +117,17 @@ public class Hid { "Tried to send command \"" + e.getCommand() + "\" to an unregistered device!"); } int id = e.getId(); - Device d = new Device(id, e.getName(), e.getVendorId(), e.getProductId(), e.getBus(), - e.getDescriptor(), e.getReport(), e.getFeatureReports(), e.getOutputs()); + Device d = new Device( + id, + e.getName(), + e.getUniq(), + e.getVendorId(), + e.getProductId(), + e.getBus(), + e.getDescriptor(), + e.getReport(), + e.getFeatureReports(), + e.getOutputs()); mDevices.append(id, d); } diff --git a/cmds/idmap2/Android.bp b/cmds/idmap2/Android.bp index 6e51f009f76c..58763a7f9aca 100644 --- a/cmds/idmap2/Android.bp +++ b/cmds/idmap2/Android.bp @@ -313,7 +313,6 @@ cc_binary { "libziparchive", ], static_libs: [ - "libc++fs", "libidmap2_policies", "libidmap2_protos", "libidmap2daidl", diff --git a/core/api/current.txt b/core/api/current.txt index 588396ac2140..14ebfba8a058 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -5518,7 +5518,6 @@ package android.app { method @Deprecated public void onCancel(android.content.DialogInterface); method @Deprecated public android.app.Dialog onCreateDialog(android.os.Bundle); method @Deprecated public void onDismiss(android.content.DialogInterface); - method public android.view.LayoutInflater onGetLayoutInflater(android.os.Bundle); method @Deprecated public void setCancelable(boolean); method @Deprecated public void setShowsDialog(boolean); method @Deprecated public void setStyle(int, int); diff --git a/core/java/android/animation/OWNERS b/core/java/android/animation/OWNERS index 822a35c348ed..f3b330a02116 100644 --- a/core/java/android/animation/OWNERS +++ b/core/java/android/animation/OWNERS @@ -2,5 +2,4 @@ romainguy@google.com tianliu@google.com -alanv@google.com adamp@google.com diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java index 287d2bd9e6a7..b38f76ed699f 100644 --- a/core/java/android/app/ApplicationPackageManager.java +++ b/core/java/android/app/ApplicationPackageManager.java @@ -2593,6 +2593,9 @@ public class ApplicationPackageManager extends PackageManager { try { Objects.requireNonNull(packageName); return mPM.isAppArchivable(packageName, new UserHandle(getUserId())); + } catch (ParcelableException e) { + e.maybeRethrow(NameNotFoundException.class); + throw new RuntimeException(e); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } diff --git a/core/java/android/app/OWNERS b/core/java/android/app/OWNERS index 02f00ba006d8..cb490da694ee 100644 --- a/core/java/android/app/OWNERS +++ b/core/java/android/app/OWNERS @@ -61,7 +61,7 @@ per-file ReceiverInfo* = file:/BROADCASTS_OWNERS per-file ComponentCaller.java = file:COMPONENT_CALLER_OWNERS # DreamManager -per-file DreamManager.java = file:/DREAM_MANAGER_OWNERS +per-file DreamManager.java = file:/core/java/android/service/dreams/OWNERS # GrammaticalInflectionManager per-file *GrammaticalInflection* = file:/services/core/java/com/android/server/grammaticalinflection/OWNERS diff --git a/core/java/android/app/admin/flags/flags.aconfig b/core/java/android/app/admin/flags/flags.aconfig index 6600ca9989bb..649b8126a371 100644 --- a/core/java/android/app/admin/flags/flags.aconfig +++ b/core/java/android/app/admin/flags/flags.aconfig @@ -44,6 +44,16 @@ flag { } flag { + name: "hsum_unlock_notification_fix" + namespace: "enterprise" + description: "Using the right userId when starting the work profile unlock flow " + bug: "327350831" + metadata { + purpose: PURPOSE_BUGFIX + } +} + +flag { name: "dumpsys_policy_engine_migration_enabled" namespace: "enterprise" description: "Update DumpSys to include information about migrated APIs in DPE" diff --git a/core/java/android/app/pinner/OWNERS b/core/java/android/app/pinner/OWNERS index 3e3fa66ca916..fe5da9f7f0e3 100644 --- a/core/java/android/app/pinner/OWNERS +++ b/core/java/android/app/pinner/OWNERS @@ -5,6 +5,5 @@ kevinjeon@google.com philipcuadra@google.com shombert@google.com timmurray@google.com -wessam@google.com jdduke@google.com -shayba@google.com
\ No newline at end of file +shayba@google.com diff --git a/core/java/android/content/pm/PackageInstaller.java b/core/java/android/content/pm/PackageInstaller.java index 640422359f95..b18c7bef422d 100644 --- a/core/java/android/content/pm/PackageInstaller.java +++ b/core/java/android/content/pm/PackageInstaller.java @@ -2360,6 +2360,7 @@ public class PackageInstaller { new UserHandle(mUserId), flags); } catch (ParcelableException e) { e.maybeRethrow(PackageManager.NameNotFoundException.class); + throw new RuntimeException(e); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -2396,6 +2397,7 @@ public class PackageInstaller { } catch (ParcelableException e) { e.maybeRethrow(IOException.class); e.maybeRethrow(PackageManager.NameNotFoundException.class); + throw new RuntimeException(e); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -2427,6 +2429,7 @@ public class PackageInstaller { userActionIntent, new UserHandle(mUserId)); } catch (ParcelableException e) { e.maybeRethrow(PackageManager.NameNotFoundException.class); + throw new RuntimeException(e); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } diff --git a/core/java/android/gesture/OWNERS b/core/java/android/gesture/OWNERS index b3b8775dc036..168630af6da4 100644 --- a/core/java/android/gesture/OWNERS +++ b/core/java/android/gesture/OWNERS @@ -1,7 +1,6 @@ # Bug component: 25700 romainguy@google.com -alanv@google.com adamp@google.com aurimas@google.com nduca@google.com diff --git a/core/java/android/hardware/SystemSensorManager.java b/core/java/android/hardware/SystemSensorManager.java index 40e03dbb8b34..327378097ac1 100644 --- a/core/java/android/hardware/SystemSensorManager.java +++ b/core/java/android/hardware/SystemSensorManager.java @@ -518,23 +518,25 @@ public class SystemSensorManager extends SensorManager { Handler mainHandler = new Handler(mContext.getMainLooper()); - for (Map.Entry<DynamicSensorCallback, Handler> entry : - mDynamicSensorCallbacks.entrySet()) { - final DynamicSensorCallback callback = entry.getKey(); - Handler handler = - entry.getValue() == null ? mainHandler : entry.getValue(); - - handler.post(new Runnable() { - @Override - public void run() { - for (Sensor s: addedList) { - callback.onDynamicSensorConnected(s); + synchronized (mDynamicSensorCallbacks) { + for (Map.Entry<DynamicSensorCallback, Handler> entry : + mDynamicSensorCallbacks.entrySet()) { + final DynamicSensorCallback callback = entry.getKey(); + Handler handler = + entry.getValue() == null ? mainHandler : entry.getValue(); + + handler.post(new Runnable() { + @Override + public void run() { + for (Sensor s: addedList) { + callback.onDynamicSensorConnected(s); + } + for (Sensor s: removedList) { + callback.onDynamicSensorDisconnected(s); + } } - for (Sensor s: removedList) { - callback.onDynamicSensorDisconnected(s); - } - } - }); + }); + } } for (Sensor s: removedList) { @@ -653,13 +655,15 @@ public class SystemSensorManager extends SensorManager { if (callback == null) { throw new IllegalArgumentException("callback cannot be null"); } - if (mDynamicSensorCallbacks.containsKey(callback)) { - // has been already registered, ignore - return; - } + synchronized (mDynamicSensorCallbacks) { + if (mDynamicSensorCallbacks.containsKey(callback)) { + // has been already registered, ignore + return; + } - setupDynamicSensorBroadcastReceiver(); - mDynamicSensorCallbacks.put(callback, handler); + setupDynamicSensorBroadcastReceiver(); + mDynamicSensorCallbacks.put(callback, handler); + } } /** @hide */ @@ -668,7 +672,9 @@ public class SystemSensorManager extends SensorManager { if (DEBUG_DYNAMIC_SENSOR) { Log.i(TAG, "Removing dynamic sensor listener"); } - mDynamicSensorCallbacks.remove(callback); + synchronized (mDynamicSensorCallbacks) { + mDynamicSensorCallbacks.remove(callback); + } } /* diff --git a/core/java/android/os/FileUtils.java b/core/java/android/os/FileUtils.java index 4dc32d5039b6..f3d743d51e4a 100644 --- a/core/java/android/os/FileUtils.java +++ b/core/java/android/os/FileUtils.java @@ -580,6 +580,8 @@ public final class FileUtils { ", copied:" + progress + ", read:" + (count - countToRead) + ", in pipe: " + countInPipe); + Os.close(pipes[0]); + Os.close(pipes[1]); throw new ErrnoException("splice, pipe --> fdOut", EIO); } else { progress += t; @@ -607,6 +609,8 @@ public final class FileUtils { listener.onProgress(progressSnapshot); }); } + Os.close(pipes[0]); + Os.close(pipes[1]); return progress; } diff --git a/core/java/android/os/IBinder.java b/core/java/android/os/IBinder.java index 91c2965c2505..c9f207cf26e8 100644 --- a/core/java/android/os/IBinder.java +++ b/core/java/android/os/IBinder.java @@ -305,15 +305,28 @@ public interface IBinder { /** * Interface for receiving a callback when the process hosting an IBinder * has gone away. - * + * * @see #linkToDeath */ public interface DeathRecipient { public void binderDied(); /** - * Interface for receiving a callback when the process hosting an IBinder + * The function called when the process hosting an IBinder * has gone away. + * + * This callback will be called from any binder thread like any other binder + * transaction. If the process receiving this notification is multithreaded + * then synchronization may be required because other threads may be executing + * at the same time. + * + * No locks are held in libbinder when {@link binderDied} is called. + * + * There is no need to call {@link unlinkToDeath} in the binderDied callback. + * The binder is already dead so {@link unlinkToDeath} is a no-op. + * It will be unlinked when the last local reference of that binder proxy is + * dropped. + * * @param who The IBinder that has become invalid */ default void binderDied(@NonNull IBinder who) { diff --git a/core/java/android/os/OWNERS b/core/java/android/os/OWNERS index 9f3364feda84..04d49708b6ef 100644 --- a/core/java/android/os/OWNERS +++ b/core/java/android/os/OWNERS @@ -107,4 +107,8 @@ per-file SystemConfigManager.java = file:/PACKAGE_MANAGER_OWNERS per-file ProfilingServiceManager.java = file:/PERFORMANCE_OWNERS # Memory -per-file OomKillRecord.java = file:/MEMORY_OWNERS
\ No newline at end of file +per-file OomKillRecord.java = file:/MEMORY_OWNERS + +# MessageQueue +per-file MessageQueue.java = mfasheh@google.com, shayba@google.com +per-file Message.java = mfasheh@google.com, shayba@google.com diff --git a/core/java/android/service/dreams/OWNERS b/core/java/android/service/dreams/OWNERS index 77bcee832250..119ca55f8e49 100644 --- a/core/java/android/service/dreams/OWNERS +++ b/core/java/android/service/dreams/OWNERS @@ -1,10 +1,11 @@ -# Bug component: 78010 +# Bug component: 66910 brycelee@google.com -dsandler@google.com -galinap@google.com -jjaggi@google.com lusilva@google.com -michaelwr@google.com -santoscordon@google.com wxyz@google.com +justinkoh@google.com + +rgl@google.com +santoscordon@google.com + +dsandler@google.com diff --git a/core/java/android/transition/OWNERS b/core/java/android/transition/OWNERS index eb5a58115a8f..2a8d9404dbbd 100644 --- a/core/java/android/transition/OWNERS +++ b/core/java/android/transition/OWNERS @@ -2,5 +2,4 @@ romainguy@google.com mount@google.com -alanv@google.com adamp@google.com diff --git a/core/java/android/view/OWNERS b/core/java/android/view/OWNERS index 07d05a4ff1ea..31a8dfaaf86b 100644 --- a/core/java/android/view/OWNERS +++ b/core/java/android/view/OWNERS @@ -1,7 +1,6 @@ # Bug component: 25700 romainguy@google.com -alanv@google.com adamp@google.com aurimas@google.com nduca@google.com diff --git a/core/java/android/view/accessibility/OWNERS b/core/java/android/view/accessibility/OWNERS index b0943e9cff62..f62b33f1f753 100644 --- a/core/java/android/view/accessibility/OWNERS +++ b/core/java/android/view/accessibility/OWNERS @@ -5,7 +5,6 @@ include /services/accessibility/OWNERS # Android members outside of Accessibility adamp@google.com #{LAST_RESORT_SUGGESTION} -alanv@google.com #{LAST_RESORT_SUGGESTION} aurimas@google.com #{LAST_RESORT_SUGGESTION} jjaggi@google.com #{LAST_RESORT_SUGGESTION} ogunwale@google.com #{LAST_RESORT_SUGGESTION} diff --git a/core/java/android/view/animation/OWNERS b/core/java/android/view/animation/OWNERS index 9b8f4d995975..2fa01c36ea96 100644 --- a/core/java/android/view/animation/OWNERS +++ b/core/java/android/view/animation/OWNERS @@ -2,5 +2,4 @@ romainguy@google.com tianliu@google.com -alanv@google.com adamp@google.com diff --git a/core/java/android/view/textclassifier/intent/OWNERS b/core/java/android/view/textclassifier/intent/OWNERS index ac80d9f4cdd0..3465fe62784f 100644 --- a/core/java/android/view/textclassifier/intent/OWNERS +++ b/core/java/android/view/textclassifier/intent/OWNERS @@ -4,5 +4,4 @@ mns@google.com toki@google.com svetoslavganov@android.com svetoslavganov@google.com -augale@google.com joannechung@google.com diff --git a/core/java/android/widget/OWNERS b/core/java/android/widget/OWNERS index 1dc90edbd1e5..8b8090b67133 100644 --- a/core/java/android/widget/OWNERS +++ b/core/java/android/widget/OWNERS @@ -1,7 +1,6 @@ # Bug component: 25700 romainguy@google.com -alanv@google.com adamp@google.com aurimas@google.com siyamed@google.com diff --git a/core/java/com/android/internal/policy/DecorView.java b/core/java/com/android/internal/policy/DecorView.java index 85662634c22d..e08443b00866 100644 --- a/core/java/com/android/internal/policy/DecorView.java +++ b/core/java/com/android/internal/policy/DecorView.java @@ -861,7 +861,7 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind final MenuHelper helper; final boolean isPopup = !Float.isNaN(x) && !Float.isNaN(y); if (isPopup) { - helper = mWindow.mContextMenu.showPopup(getContext(), originalView, x, y); + helper = mWindow.mContextMenu.showPopup(originalView.getContext(), originalView, x, y); } else { helper = mWindow.mContextMenu.showDialog(originalView, originalView.getWindowToken()); } diff --git a/core/jni/com_android_internal_content_FileSystemUtils.cpp b/core/jni/com_android_internal_content_FileSystemUtils.cpp index 31f4e641b69e..d426f1240a7f 100644 --- a/core/jni/com_android_internal_content_FileSystemUtils.cpp +++ b/core/jni/com_android_internal_content_FileSystemUtils.cpp @@ -88,7 +88,7 @@ bool punchHoles(const char *filePath, const uint64_t offset, ALOGD("Total number of LOAD segments %zu", programHeaders.size()); ALOGD("Size before punching holes st_blocks: %" PRIu64 - ", st_blksize: %ld, st_size: %" PRIu64 "", + ", st_blksize: %d, st_size: %" PRIu64 "", beforePunch.st_blocks, beforePunch.st_blksize, static_cast<uint64_t>(beforePunch.st_size)); } @@ -193,7 +193,7 @@ bool punchHoles(const char *filePath, const uint64_t offset, ALOGD("lstat64 failed for filePath %s, error:%d", filePath, errno); return false; } - ALOGD("Size after punching holes st_blocks: %" PRIu64 ", st_blksize: %ld, st_size: %" PRIu64 + ALOGD("Size after punching holes st_blocks: %" PRIu64 ", st_blksize: %d, st_size: %" PRIu64 "", afterPunch.st_blocks, afterPunch.st_blksize, static_cast<uint64_t>(afterPunch.st_size)); @@ -271,7 +271,7 @@ bool punchHolesInZip(const char *filePath, uint64_t offset, uint16_t extraFieldL uint64_t blockSize = beforePunch.st_blksize; IF_ALOGD() { ALOGD("Extra field length: %hu, Size before punching holes st_blocks: %" PRIu64 - ", st_blksize: %ld, st_size: %" PRIu64 "", + ", st_blksize: %d, st_size: %" PRIu64 "", extraFieldLen, beforePunch.st_blocks, beforePunch.st_blksize, static_cast<uint64_t>(beforePunch.st_size)); } @@ -346,7 +346,7 @@ bool punchHolesInZip(const char *filePath, uint64_t offset, uint16_t extraFieldL return false; } ALOGD("punchHolesInApk:: Size after punching holes st_blocks: %" PRIu64 - ", st_blksize: %ld, st_size: %" PRIu64 "", + ", st_blksize: %d, st_size: %" PRIu64 "", afterPunch.st_blocks, afterPunch.st_blksize, static_cast<uint64_t>(afterPunch.st_size)); } diff --git a/core/jni/com_android_internal_content_NativeLibraryHelper.cpp b/core/jni/com_android_internal_content_NativeLibraryHelper.cpp index 9b8dab78b342..fba0d81d431f 100644 --- a/core/jni/com_android_internal_content_NativeLibraryHelper.cpp +++ b/core/jni/com_android_internal_content_NativeLibraryHelper.cpp @@ -115,7 +115,8 @@ sumFiles(JNIEnv*, void* arg, ZipFileRO* zipFile, ZipEntryRO zipEntry, const char size_t* total = (size_t*) arg; uint32_t uncompLen; - if (!zipFile->getEntryInfo(zipEntry, nullptr, &uncompLen, nullptr, nullptr, nullptr, nullptr)) { + if (!zipFile->getEntryInfo(zipEntry, nullptr, &uncompLen, nullptr, nullptr, nullptr, nullptr, + nullptr)) { return INSTALL_FAILED_INVALID_APK; } diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index ee7baa171cf0..cf552da676a2 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -2258,6 +2258,11 @@ <permission android:name="android.permission.THREAD_NETWORK_PRIVILEGED" android:protectionLevel="signature|privileged" /> + <!-- @hide Allows access to Thread network APIs or shell commands ("cmd thread_network") which + are only for testing. --> + <permission android:name="android.permission.THREAD_NETWORK_TESTING" + android:protectionLevel="signature" /> + <!-- #SystemApi @hide Allows an app to bypass Private DNS. <p>Not for use by third-party applications. TODO: publish as system API in next API release. --> diff --git a/core/res/OWNERS b/core/res/OWNERS index dce578afe3d4..22ea9dadab34 100644 --- a/core/res/OWNERS +++ b/core/res/OWNERS @@ -66,6 +66,11 @@ per-file res/values/symbols.xml = file:/PERFORMANCE_OWNERS per-file res/xml/power_profile.xml = file:/BATTERY_STATS_OWNERS per-file res/xml/power_profile_test.xml = file:/BATTERY_STATS_OWNERS +# RemoteView color resources +per-file remote_color_resources_res/symbols.xml = pbdr@google.com +per-file remote_color_resources_res/values/public.xml = pbdr@google.com +per-file remote_color_resources_res/values/colors.xml = pbdr@google.com + # Telephony per-file res/values/config_telephony.xml = file:/platform/frameworks/opt/telephony:/OWNERS per-file res/xml/sms_short_codes.xml = file:/platform/frameworks/opt/telephony:/OWNERS @@ -79,4 +84,4 @@ per-file res/values/attrs.xml = arteiro@google.com per-file res/values/styles.xml = arteiro@google.com per-file res/values/symbols.xml = arteiro@google.com per-file res/values/themes_device_defaults.xml = arteiro@google.com -per-file res/values/styles_material.xml = arteiro@google.com
\ No newline at end of file +per-file res/values/styles_material.xml = arteiro@google.com diff --git a/core/res/res/xml/sms_short_codes.xml b/core/res/res/xml/sms_short_codes.xml index 4d7c00991798..67cceb5d5343 100644 --- a/core/res/res/xml/sms_short_codes.xml +++ b/core/res/res/xml/sms_short_codes.xml @@ -60,6 +60,9 @@ <!-- Belgium: 4 digits, plus EU: http://www.mobileweb.be/en/mobileweb/sms-numberplan.asp --> <shortcode country="be" premium="\\d{4}" free="8\\d{3}|116\\d{3}" /> + <!-- Burkina Faso: 1-4 digits (standard system default, not country specific) --> + <shortcode country="bf" pattern="\\d{1,4}" free="3558" /> + <!-- Bulgaria: 4-5 digits, plus EU --> <shortcode country="bg" pattern="\\d{4,5}" premium="18(?:16|423)|19(?:1[56]|35)" free="116\\d{3}|1988|1490" /> @@ -175,8 +178,8 @@ <!-- Israel: 1-5 digits, known premium codes listed --> <shortcode country="il" pattern="\\d{1,5}" premium="4422|4545" free="37477|6681" /> - <!-- Iran: 4-6 digits, known premium codes listed --> - <shortcode country="ir" pattern="\\d{4,6}" free="700791|700792" /> + <!-- Iran: 4-8 digits, known premium codes listed --> + <shortcode country="ir" pattern="\\d{4,8}" free="700791|700792|100016|30008360" /> <!-- Italy: 5 digits (premium=41xxx,42xxx), plus EU: https://www.itu.int/dms_pub/itu-t/oth/02/02/T020200006B0001PDFE.pdf --> @@ -352,7 +355,7 @@ <shortcode country="za" pattern="\\d{1,5}" free="44136|30791|36056|33009" /> <!-- Yemen --> - <shortcode country="ye" pattern="\\d{1,4}" free="5081" /> + <shortcode country="ye" pattern="\\d{1,4}" free="5079" /> <!-- Zimbabwe --> <shortcode country="zw" pattern="\\d{1,5}" free="33679" /> diff --git a/core/tests/coretests/Android.bp b/core/tests/coretests/Android.bp index 99909a1d3c7b..5a051adb140b 100644 --- a/core/tests/coretests/Android.bp +++ b/core/tests/coretests/Android.bp @@ -103,6 +103,7 @@ android_test { sdk_version: "core_platform", test_suites: [ "device-tests", + "device-platinum-tests", "automotive-tests", ], diff --git a/core/tests/coretests/OWNERS b/core/tests/coretests/OWNERS index b7e008b196ff..b669e3bc4f30 100644 --- a/core/tests/coretests/OWNERS +++ b/core/tests/coretests/OWNERS @@ -3,3 +3,4 @@ include platform/frameworks/base:/services/core/java/com/android/server/am/OWNER per-file BinderTest.java = file:platform/frameworks/native:/libs/binder/OWNERS per-file ParcelTest.java = file:platform/frameworks/native:/libs/binder/OWNERS per-file SurfaceControlRegistryTests.java = file:/services/core/java/com/android/server/wm/OWNERS +per-file VintfObjectTest.java = file:platform/system/libvintf:/OWNERS diff --git a/core/tests/coretests/src/android/os/BinderTest.java b/core/tests/coretests/src/android/os/BinderTest.java index 6c8b69fc9c5c..9767d677807d 100644 --- a/core/tests/coretests/src/android/os/BinderTest.java +++ b/core/tests/coretests/src/android/os/BinderTest.java @@ -20,6 +20,8 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertSame; +import static org.mockito.ArgumentMatchers.anyBoolean; +import static org.mockito.ArgumentMatchers.anyInt; import static org.testng.Assert.assertThrows; import android.platform.test.annotations.IgnoreUnderRavenwood; @@ -27,6 +29,9 @@ import android.platform.test.ravenwood.RavenwoodRule; import androidx.test.filters.SmallTest; +import com.android.internal.os.BinderInternal; + + import org.junit.Rule; import org.junit.Test; @@ -81,4 +86,27 @@ public class BinderTest { binder.setExtension(null); assertNull(binder.getExtension()); } + + @SmallTest + @Test(expected = java.lang.SecurityException.class) + public void testServiceManagerNativeSecurityException() throws RemoteException { + // Find the service manager + IServiceManager sServiceManager = ServiceManagerNative + .asInterface(Binder.allowBlocking(BinderInternal.getContextObject())); + + Binder binder = new Binder(); + sServiceManager.addService("ValidName", binder, + anyBoolean(), anyInt()); + } + + @SmallTest + @Test(expected = java.lang.NullPointerException.class) + public void testServiceManagerNativeNullptrException() throws RemoteException { + // Find the service manager + IServiceManager sServiceManager = ServiceManagerNative + .asInterface(Binder.allowBlocking(BinderInternal.getContextObject())); + + sServiceManager.addService("ValidName", null, + anyBoolean(), anyInt()); + } } diff --git a/core/tests/coretests/src/android/os/VintfObjectTest.java b/core/tests/coretests/src/android/os/VintfObjectTest.java index f34b8fd358d9..f81b31d0bd5a 100644 --- a/core/tests/coretests/src/android/os/VintfObjectTest.java +++ b/core/tests/coretests/src/android/os/VintfObjectTest.java @@ -16,16 +16,25 @@ package android.os; -import static org.junit.Assert.assertTrue; +import static com.google.common.truth.Truth.assertThat; + +import static java.util.stream.Collectors.toList; import android.platform.test.annotations.IgnoreUnderRavenwood; import android.platform.test.ravenwood.RavenwoodRule; +import android.util.Pair; import androidx.test.ext.junit.runners.AndroidJUnit4; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; +import org.xml.sax.InputSource; + +import java.io.StringReader; +import java.util.stream.Stream; + +import javax.xml.parsers.DocumentBuilderFactory; @RunWith(AndroidJUnit4.class) @IgnoreUnderRavenwood(blockedBy = VintfObject.class) @@ -39,12 +48,26 @@ public class VintfObjectTest { @Test public void testReport() { String[] xmls = VintfObject.report(); - assertTrue(xmls.length > 0); - // From /system/manifest.xml - assertTrue(String.join("", xmls).contains( - "<manifest version=\"1.0\" type=\"framework\">")); - // From /system/compatibility-matrix.xml - assertTrue(String.join("", xmls).contains( - "<compatibility-matrix version=\"1.0\" type=\"framework\"")); + + assertThat(Stream.of(xmls).map(xml -> rootAndType(xml)).collect(toList())) + .containsExactly( + Pair.create("manifest", "framework"), + Pair.create("compatibility-matrix", "framework"), + Pair.create("manifest", "device"), + Pair.create("compatibility-matrix", "device") + ); + } + + private static Pair<String, String> rootAndType(String content) { + try { + var factory = DocumentBuilderFactory.newInstance(); + var builder = factory.newDocumentBuilder(); + var inputSource = new InputSource(new StringReader(content)); + var document = builder.parse(inputSource); + var root = document.getDocumentElement(); + return Pair.create(root.getTagName(), root.getAttribute("type")); + } catch (Exception e) { + throw new RuntimeException(e); + } } } diff --git a/keystore/OWNERS b/keystore/OWNERS index 913f65586cd6..689177715711 100644 --- a/keystore/OWNERS +++ b/keystore/OWNERS @@ -1,4 +1,5 @@ # Bug component: 189335 +drysdale@google.com eranm@google.com jbires@google.com swillden@google.com diff --git a/keystore/java/android/security/AndroidProtectedConfirmation.java b/keystore/java/android/security/AndroidProtectedConfirmation.java index 268e0a54053b..dfe485ac8274 100644 --- a/keystore/java/android/security/AndroidProtectedConfirmation.java +++ b/keystore/java/android/security/AndroidProtectedConfirmation.java @@ -59,10 +59,6 @@ public class AndroidProtectedConfirmation { /** * Requests keystore call into the confirmationui HAL to display a prompt. - * @deprecated Android Protected Confirmation had a low adoption rate among Android device - * makers and developers alike. Given the lack of devices supporting the - * feature, it is deprecated. Developers can use auth-bound Keystore keys - * as a partial replacement. * * @param listener the binder to use for callbacks. * @param promptText the prompt to display. @@ -72,7 +68,6 @@ public class AndroidProtectedConfirmation { * @return one of the {@code CONFIRMATIONUI_*} constants, for * example {@code KeyStore.CONFIRMATIONUI_OK}. */ - @Deprecated public int presentConfirmationPrompt(IConfirmationCallback listener, String promptText, byte[] extraData, String locale, int uiOptionsAsFlags) { try { @@ -89,16 +84,11 @@ public class AndroidProtectedConfirmation { /** * Requests keystore call into the confirmationui HAL to cancel displaying a prompt. - * @deprecated Android Protected Confirmation had a low adoption rate among Android device - * makers and developers alike. Given the lack of devices supporting the - * feature, it is deprecated. Developers can use auth-bound Keystore keys - * as a partial replacement. * * @param listener the binder passed to the {@link #presentConfirmationPrompt} method. * @return one of the {@code CONFIRMATIONUI_*} constants, for * example {@code KeyStore.CONFIRMATIONUI_OK}. */ - @Deprecated public int cancelConfirmationPrompt(IConfirmationCallback listener) { try { getService().cancelPrompt(listener); @@ -113,14 +103,9 @@ public class AndroidProtectedConfirmation { /** * Requests keystore to check if the confirmationui HAL is available. - * @deprecated Android Protected Confirmation had a low adoption rate among Android device - * makers and developers alike. Given the lack of devices supporting the - * feature, it is deprecated. Developers can use auth-bound Keystore keys - * as a partial replacement. * * @return whether the confirmationUI HAL is available. */ - @Deprecated public boolean isConfirmationPromptSupported() { try { return getService().isSupported(); diff --git a/keystore/java/android/security/KeyStoreException.java b/keystore/java/android/security/KeyStoreException.java index 5825facee021..eea5690dddf1 100644 --- a/keystore/java/android/security/KeyStoreException.java +++ b/keystore/java/android/security/KeyStoreException.java @@ -679,6 +679,9 @@ public class KeyStoreException extends Exception { sErrorCodeToFailureInfo.put(ResponseCode.OUT_OF_KEYS_REQUIRES_SYSTEM_UPGRADE, new PublicErrorInformation(IS_SYSTEM_ERROR | IS_TRANSIENT_ERROR, ERROR_DEVICE_REQUIRES_UPGRADE_FOR_ATTESTATION)); + sErrorCodeToFailureInfo.put(ResponseCode.GET_ATTESTATION_APPLICATION_ID_FAILED, + new PublicErrorInformation(IS_SYSTEM_ERROR | IS_TRANSIENT_ERROR, + ERROR_INTERNAL_SYSTEM_ERROR)); sErrorCodeToFailureInfo.put(ResponseCode.OUT_OF_KEYS_PENDING_INTERNET_CONNECTIVITY, new PublicErrorInformation(IS_SYSTEM_ERROR | IS_TRANSIENT_ERROR, ERROR_ATTESTATION_KEYS_UNAVAILABLE)); diff --git a/keystore/java/android/security/keystore/KeyGenParameterSpec.java b/keystore/java/android/security/keystore/KeyGenParameterSpec.java index d359a9050a0f..3cff91597939 100644 --- a/keystore/java/android/security/keystore/KeyGenParameterSpec.java +++ b/keystore/java/android/security/keystore/KeyGenParameterSpec.java @@ -1149,6 +1149,8 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu /** * Sets the serial number used for the certificate of the generated key pair. + * To ensure compatibility with devices and certificate parsers, the value + * should be 20 bytes or shorter (see RFC 5280 section 4.1.2.2). * * <p>By default, the serial number is {@code 1}. */ diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/protolog/OWNERS b/libs/WindowManager/Shell/src/com/android/wm/shell/protolog/OWNERS new file mode 100644 index 000000000000..3f3308cfc75a --- /dev/null +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/protolog/OWNERS @@ -0,0 +1 @@ +include platform/development:/tools/winscope/OWNERS diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java index af69b5272ad5..54a98c1b7cba 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java @@ -1470,7 +1470,7 @@ public class Transitions implements RemoteCallable<Transitions>, public void setHomeTransitionListener(IHomeTransitionListener listener) { executeRemoteCallWithTaskPermission(mTransitions, "setHomeTransitionListener", (transitions) -> { - transitions.mHomeTransitionObserver.setHomeTransitionListener(mTransitions, + transitions.mHomeTransitionObserver.setHomeTransitionListener(transitions, listener); }); } diff --git a/libs/WindowManager/Shell/tests/flicker/service/Android.bp b/libs/WindowManager/Shell/tests/flicker/service/Android.bp index 4f1a68a1a74e..a5bc26152d16 100644 --- a/libs/WindowManager/Shell/tests/flicker/service/Android.bp +++ b/libs/WindowManager/Shell/tests/flicker/service/Android.bp @@ -65,6 +65,10 @@ android_test { package_name: "com.android.wm.shell.flicker.service", instrumentation_target_package: "com.android.wm.shell.flicker.service", test_config_template: "AndroidTestTemplate.xml", + test_suites: [ + "device-tests", + "device-platinum-tests", + ], srcs: [":WMShellFlickerServicePlatinumTests-src"], static_libs: ["WMShellFlickerTestsBase"], data: ["trace_config/*"], diff --git a/libs/androidfw/AssetManager.cpp b/libs/androidfw/AssetManager.cpp index 68befffecf2f..e6182454ad8a 100644 --- a/libs/androidfw/AssetManager.cpp +++ b/libs/androidfw/AssetManager.cpp @@ -926,8 +926,8 @@ Asset* AssetManager::openAssetFromZipLocked(const ZipFileRO* pZipFile, //printf("USING Zip '%s'\n", pEntry->getFileName()); - if (!pZipFile->getEntryInfo(entry, &method, &uncompressedLen, NULL, NULL, - NULL, NULL)) + if (!pZipFile->getEntryInfo(entry, &method, &uncompressedLen, nullptr, nullptr, + nullptr, nullptr, nullptr)) { ALOGW("getEntryInfo failed\n"); return NULL; diff --git a/libs/androidfw/ZipFileRO.cpp b/libs/androidfw/ZipFileRO.cpp index 839c7b6fef37..10651cdaff33 100644 --- a/libs/androidfw/ZipFileRO.cpp +++ b/libs/androidfw/ZipFileRO.cpp @@ -119,14 +119,6 @@ ZipEntryRO ZipFileRO::findEntryByName(const char* entryName) const * appear to be bogus. */ bool ZipFileRO::getEntryInfo(ZipEntryRO entry, uint16_t* pMethod, - uint32_t* pUncompLen, uint32_t* pCompLen, off64_t* pOffset, - uint32_t* pModWhen, uint32_t* pCrc32) const -{ - return getEntryInfo(entry, pMethod, pUncompLen, pCompLen, pOffset, pModWhen, - pCrc32, nullptr); -} - -bool ZipFileRO::getEntryInfo(ZipEntryRO entry, uint16_t* pMethod, uint32_t* pUncompLen, uint32_t* pCompLen, off64_t* pOffset, uint32_t* pModWhen, uint32_t* pCrc32, uint16_t* pExtraFieldSize) const { diff --git a/libs/androidfw/include/androidfw/ZipFileRO.h b/libs/androidfw/include/androidfw/ZipFileRO.h index f7c5007c80d2..0f3f19c91ed1 100644 --- a/libs/androidfw/include/androidfw/ZipFileRO.h +++ b/libs/androidfw/include/androidfw/ZipFileRO.h @@ -147,10 +147,6 @@ public: * Returns "false" if "entry" is bogus or if the data in the Zip file * appears to be bad. */ - bool getEntryInfo(ZipEntryRO entry, uint16_t* pMethod, uint32_t* pUncompLen, - uint32_t* pCompLen, off64_t* pOffset, uint32_t* pModWhen, - uint32_t* pCrc32) const; - bool getEntryInfo(ZipEntryRO entry, uint16_t* pMethod, uint32_t* pUncompLen, uint32_t* pCompLen, off64_t* pOffset, uint32_t* pModWhen, uint32_t* pCrc32, uint16_t* pExtraFieldSize) const; diff --git a/media/tests/AudioPolicyTest/src/com/android/audiopolicytest/AudioPolicyDeathTest.java b/media/tests/AudioPolicyTest/src/com/android/audiopolicytest/AudioPolicyDeathTest.java index 48c51af26d3a..61670e97ab3f 100644 --- a/media/tests/AudioPolicyTest/src/com/android/audiopolicytest/AudioPolicyDeathTest.java +++ b/media/tests/AudioPolicyTest/src/com/android/audiopolicytest/AudioPolicyDeathTest.java @@ -128,7 +128,7 @@ public class AudioPolicyDeathTest { res.getInt(mContext.getResources().getString(R.string.status_key))); }); - // Launch process registering a dynamic auido policy and dying after RECORD_TIME_MS ms + // Launch process registering a dynamic audio policy and dying after RECORD_TIME_MS ms // RECORD_TIME_MS must be shorter than PLAYBACK_TIME_MS Intent intent = new Intent(mContext, AudioPolicyDeathTestActivity.class); intent.putExtra(mContext.getResources().getString(R.string.capture_duration_key), diff --git a/native/graphics/jni/Android.bp b/native/graphics/jni/Android.bp index 8ea46329af58..746c280edc70 100644 --- a/native/graphics/jni/Android.bp +++ b/native/graphics/jni/Android.bp @@ -111,6 +111,7 @@ cc_defaults { "allocator_may_return_null = 1", ], }, + dictionary: "fuzz/imagedecoder_fuzzer.dict", host_supported: true, } diff --git a/native/graphics/jni/fuzz/fuzz_imagedecoder.cpp b/native/graphics/jni/fuzz/fuzz_imagedecoder.cpp index 838bf3f30a11..6743997fb152 100644 --- a/native/graphics/jni/fuzz/fuzz_imagedecoder.cpp +++ b/native/graphics/jni/fuzz/fuzz_imagedecoder.cpp @@ -15,32 +15,15 @@ */ #include <android/imagedecoder.h> - #include <binder/IPCThreadState.h> -#include <stddef.h> -#include <stdint.h> -#include <cstdlib> -#include <memory> +#include <fuzzer/FuzzedDataProvider.h> #ifdef PNG_MUTATOR_DEFINE_LIBFUZZER_CUSTOM_MUTATOR #include <fuzz/png_mutator.h> #endif -struct DecoderDeleter { - void operator()(AImageDecoder* decoder) const { AImageDecoder_delete(decoder); } -}; - -using DecoderPointer = std::unique_ptr<AImageDecoder, DecoderDeleter>; - -static DecoderPointer makeDecoder(const uint8_t* data, size_t size) { - AImageDecoder* decoder = nullptr; - int result = AImageDecoder_createFromBuffer(data, size, &decoder); - if (result != ANDROID_IMAGE_DECODER_SUCCESS) { - // This was not a valid image. - return nullptr; - } - return DecoderPointer(decoder); -} +constexpr int32_t kMaxDimension = 5000; +constexpr int32_t kMinDimension = 0; struct PixelFreer { void operator()(void* pixels) const { std::free(pixels); } @@ -48,41 +31,113 @@ struct PixelFreer { using PixelPointer = std::unique_ptr<void, PixelFreer>; -extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { - // Without this call, decoding HEIF may time out on binder IPC calls. - android::ProcessState::self()->startThreadPool(); - - DecoderPointer decoder = makeDecoder(data, size); - if (!decoder) { - return 0; +AImageDecoder* init(const uint8_t* data, size_t size, bool useFileDescriptor) { + AImageDecoder* decoder = nullptr; + if (useFileDescriptor) { + constexpr char testFd[] = "tempFd"; + int32_t fileDesc = open(testFd, O_RDWR | O_CREAT | O_TRUNC); + write(fileDesc, data, size); + AImageDecoder_createFromFd(fileDesc, &decoder); + close(fileDesc); + } else { + AImageDecoder_createFromBuffer(data, size, &decoder); } + return decoder; +} - const AImageDecoderHeaderInfo* info = AImageDecoder_getHeaderInfo(decoder.get()); - int32_t width = AImageDecoderHeaderInfo_getWidth(info); - int32_t height = AImageDecoderHeaderInfo_getHeight(info); - - // Set an arbitrary limit on the size of an image. The fuzzer runs with a - // limited amount of memory, and keeping this allocation small allows the - // fuzzer to continue running to try to find more serious problems. This - // size is large enough to hold a photo taken by a current gen phone. - constexpr int32_t kMaxDimension = 5000; - if (width > kMaxDimension || height > kMaxDimension) { +extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { + FuzzedDataProvider dataProvider = FuzzedDataProvider(data, size); + /** + * Use maximum of 80% of buffer for creating decoder and save at least + * 20% buffer for fuzzing other APIs + */ + const int32_t dataSize = dataProvider.ConsumeIntegralInRange<int32_t>(0, (size * 80) / 100); + std::vector<uint8_t> inputBuffer = dataProvider.ConsumeBytes<uint8_t>(dataSize); + AImageDecoder* decoder = + init(inputBuffer.data(), inputBuffer.size(), dataProvider.ConsumeBool()); + if (!decoder) { return 0; } - - size_t stride = AImageDecoder_getMinimumStride(decoder.get()); - size_t pixelSize = height * stride; - auto pixels = PixelPointer(std::malloc(pixelSize)); - if (!pixels.get()) { - return 0; + const AImageDecoderHeaderInfo* headerInfo = AImageDecoder_getHeaderInfo(decoder); + AImageDecoderFrameInfo* frameInfo = AImageDecoderFrameInfo_create(); + int32_t height = AImageDecoderHeaderInfo_getHeight(headerInfo); + int32_t width = AImageDecoderHeaderInfo_getWidth(headerInfo); + while (dataProvider.remaining_bytes()) { + auto invokeImageApi = dataProvider.PickValueInArray<const std::function<void()>>({ + [&]() { + int32_t testHeight = + dataProvider.ConsumeIntegralInRange<int32_t>(kMinDimension, + kMaxDimension); + int32_t testWidth = dataProvider.ConsumeIntegralInRange<int32_t>(kMinDimension, + kMaxDimension); + int32_t result = AImageDecoder_setTargetSize(decoder, testHeight, testWidth); + if (result == ANDROID_IMAGE_DECODER_SUCCESS) { + height = testHeight; + width = testWidth; + } + }, + [&]() { + const bool required = dataProvider.ConsumeBool(); + AImageDecoder_setUnpremultipliedRequired(decoder, required); + }, + [&]() { + AImageDecoder_setAndroidBitmapFormat( + decoder, + dataProvider.ConsumeIntegralInRange< + int32_t>(ANDROID_BITMAP_FORMAT_NONE, + ANDROID_BITMAP_FORMAT_RGBA_1010102) /* format */); + }, + [&]() { + AImageDecoder_setDataSpace(decoder, + dataProvider + .ConsumeIntegral<int32_t>() /* dataspace */); + }, + [&]() { + ARect rect{dataProvider.ConsumeIntegral<int32_t>() /* left */, + dataProvider.ConsumeIntegral<int32_t>() /* top */, + dataProvider.ConsumeIntegral<int32_t>() /* right */, + dataProvider.ConsumeIntegral<int32_t>() /* bottom */}; + AImageDecoder_setCrop(decoder, rect); + }, + [&]() { AImageDecoderHeaderInfo_getWidth(headerInfo); }, + [&]() { AImageDecoderHeaderInfo_getMimeType(headerInfo); }, + [&]() { AImageDecoderHeaderInfo_getAlphaFlags(headerInfo); }, + [&]() { AImageDecoderHeaderInfo_getAndroidBitmapFormat(headerInfo); }, + [&]() { + int32_t tempHeight; + int32_t tempWidth; + AImageDecoder_computeSampledSize(decoder, + dataProvider.ConsumeIntegral< + int>() /* sampleSize */, + &tempWidth, &tempHeight); + }, + [&]() { AImageDecoderHeaderInfo_getDataSpace(headerInfo); }, + [&]() { AImageDecoder_getRepeatCount(decoder); }, + [&]() { AImageDecoder_getFrameInfo(decoder, frameInfo); }, + [&]() { AImageDecoderFrameInfo_getDuration(frameInfo); }, + [&]() { AImageDecoderFrameInfo_hasAlphaWithinBounds(frameInfo); }, + [&]() { AImageDecoderFrameInfo_getDisposeOp(frameInfo); }, + [&]() { AImageDecoderFrameInfo_getBlendOp(frameInfo); }, + [&]() { + AImageDecoder_setInternallyHandleDisposePrevious( + decoder, dataProvider.ConsumeBool() /* handle */); + }, + [&]() { AImageDecoder_rewind(decoder); }, + [&]() { AImageDecoder_advanceFrame(decoder); }, + [&]() { + size_t stride = AImageDecoder_getMinimumStride(decoder); + size_t pixelSize = height * stride; + auto pixels = PixelPointer(std::malloc(pixelSize)); + if (!pixels.get()) { + return; + } + AImageDecoder_decodeImage(decoder, pixels.get(), stride, pixelSize); + }, + }); + invokeImageApi(); } - while (true) { - int result = AImageDecoder_decodeImage(decoder.get(), pixels.get(), stride, pixelSize); - if (result != ANDROID_IMAGE_DECODER_SUCCESS) break; - - result = AImageDecoder_advanceFrame(decoder.get()); - if (result != ANDROID_IMAGE_DECODER_SUCCESS) break; - } + AImageDecoderFrameInfo_delete(frameInfo); + AImageDecoder_delete(decoder); return 0; } diff --git a/native/graphics/jni/fuzz/imagedecoder_fuzzer.dict b/native/graphics/jni/fuzz/imagedecoder_fuzzer.dict new file mode 100644 index 000000000000..5b54a0ed115e --- /dev/null +++ b/native/graphics/jni/fuzz/imagedecoder_fuzzer.dict @@ -0,0 +1,7 @@ +kw1="\x89\x50\x4E\x47" +kw2="\xff\xD8\xFF" +kw4="\x52\x49\x46\x46" +kw5="\x00\x00\x01\x00" +kw6="\x47\x49\x46\x08" +kw7="ftyp" +kw8="\x04\x00\x00\x00" diff --git a/nfc/java/android/nfc/NfcActivityManager.java b/nfc/java/android/nfc/NfcActivityManager.java index f03fc0af86b3..0e40db612708 100644 --- a/nfc/java/android/nfc/NfcActivityManager.java +++ b/nfc/java/android/nfc/NfcActivityManager.java @@ -195,16 +195,25 @@ public final class NfcActivityManager extends IAppCallback.Stub Bundle extras) { boolean isResumed; Binder token; + int pollTech, listenTech; synchronized (NfcActivityManager.this) { NfcActivityState state = getActivityState(activity); state.readerCallback = callback; state.readerModeFlags = flags; state.readerModeExtras = extras; + pollTech = state.mPollTech; + listenTech = state.mListenTech; token = state.token; isResumed = state.resumed; } if (isResumed) { - setReaderMode(token, flags, extras); + if (listenTech != NfcAdapter.FLAG_USE_ALL_TECH + || pollTech != NfcAdapter.FLAG_USE_ALL_TECH) { + throw new IllegalStateException( + "Cannot be used when alternative DiscoveryTechnology is set"); + } else { + setReaderMode(token, flags, extras); + } } } @@ -385,15 +394,12 @@ public final class NfcActivityManager extends IAppCallback.Stub boolean readerModeFlagsSet; synchronized (NfcActivityManager.this) { NfcActivityState state = getActivityState(activity); - readerModeFlagsSet = state.readerModeFlags != 0; state.mListenTech = NfcAdapter.FLAG_USE_ALL_TECH; state.mPollTech = NfcAdapter.FLAG_USE_ALL_TECH; token = state.token; isResumed = state.resumed; } - if (readerModeFlagsSet) { - disableReaderMode(activity); - } else if (isResumed) { + if (isResumed) { changeDiscoveryTech(token, NfcAdapter.FLAG_USE_ALL_TECH, NfcAdapter.FLAG_USE_ALL_TECH); } diff --git a/nfc/java/android/nfc/NfcAdapter.java b/nfc/java/android/nfc/NfcAdapter.java index 7e0a1111b574..e1c18843313d 100644 --- a/nfc/java/android/nfc/NfcAdapter.java +++ b/nfc/java/android/nfc/NfcAdapter.java @@ -1846,10 +1846,7 @@ public final class NfcAdapter { throw new UnsupportedOperationException(); } } - mNfcActivityManager.enableReaderMode(activity, null, pollTechnology, null); - return; - } - if (pollTechnology == FLAG_READER_DISABLE) { + } else if (pollTechnology == FLAG_READER_DISABLE) { synchronized (sLock) { if (!sHasCeFeature) { throw new UnsupportedOperationException(); diff --git a/packages/CrashRecovery/aconfig/flags.aconfig b/packages/CrashRecovery/aconfig/flags.aconfig index 8cdef38356da..80412321d60b 100644 --- a/packages/CrashRecovery/aconfig/flags.aconfig +++ b/packages/CrashRecovery/aconfig/flags.aconfig @@ -12,15 +12,22 @@ flag { flag { name: "enable_crashrecovery" is_exported: true - namespace: "crashrecovery" + namespace: "modularization" description: "Enables various dependencies of crashrecovery module" bug: "289203818" } flag { name: "allow_rescue_party_flag_resets" - namespace: "crashrecovery" + namespace: "modularization" description: "Enables rescue party flag resets" bug: "287618292" is_fixed_read_only: true } + +flag { + name: "reenable_settings_resets" + namespace: "modularization" + description: "Re-enables settings resets only, deletes flag resets" + bug: "333847376" +} diff --git a/packages/CredentialManager/wear/src/com/android/credentialmanager/CredentialSelectorActivity.kt b/packages/CredentialManager/wear/src/com/android/credentialmanager/CredentialSelectorActivity.kt index 0df40d7adba5..a5b6aeaa4c5e 100644 --- a/packages/CredentialManager/wear/src/com/android/credentialmanager/CredentialSelectorActivity.kt +++ b/packages/CredentialManager/wear/src/com/android/credentialmanager/CredentialSelectorActivity.kt @@ -18,6 +18,7 @@ package com.android.credentialmanager import android.content.Intent import android.os.Bundle +import android.util.Log import androidx.activity.ComponentActivity import androidx.activity.compose.setContent import androidx.activity.viewModels @@ -34,6 +35,7 @@ class CredentialSelectorActivity : Hilt_CredentialSelectorActivity() { @OptIn(ExperimentalHorologistApi::class) override fun onCreate(savedInstanceState: Bundle?) { + Log.d(TAG, "onCreate, intent: $intent") super.onCreate(savedInstanceState) setTheme(android.R.style.Theme_DeviceDefault) setContent { @@ -48,6 +50,7 @@ class CredentialSelectorActivity : Hilt_CredentialSelectorActivity() { } override fun onNewIntent(intent: Intent) { + Log.d(TAG, "onNewIntent, intent: $intent") super.onNewIntent(intent) setIntent(intent) viewModel.updateRequest(intent) diff --git a/packages/DynamicSystemInstallationService/Android.bp b/packages/DynamicSystemInstallationService/Android.bp index b8f54b3faf63..ae6901917630 100644 --- a/packages/DynamicSystemInstallationService/Android.bp +++ b/packages/DynamicSystemInstallationService/Android.bp @@ -30,10 +30,6 @@ android_app { certificate: "platform", privileged: true, platform_apis: true, - - optimize: { - enabled: false, - }, } java_library { diff --git a/packages/DynamicSystemInstallationService/src/com/android/dynsystem/DynamicSystemInstallationService.java b/packages/DynamicSystemInstallationService/src/com/android/dynsystem/DynamicSystemInstallationService.java index 635dc420f18c..5a530c4deefb 100644 --- a/packages/DynamicSystemInstallationService/src/com/android/dynsystem/DynamicSystemInstallationService.java +++ b/packages/DynamicSystemInstallationService/src/com/android/dynsystem/DynamicSystemInstallationService.java @@ -60,7 +60,6 @@ import android.os.RemoteException; import android.os.image.DynamicSystemClient; import android.os.image.DynamicSystemManager; import android.text.TextUtils; -import android.util.EventLog; import android.util.Log; import android.widget.Toast; @@ -104,14 +103,6 @@ public class DynamicSystemInstallationService extends Service private static final String NOTIFICATION_CHANNEL_ID = "com.android.dynsystem"; private static final int NOTIFICATION_ID = 1; - /* - * Event log tags - */ - private static final int EVENT_DSU_PROGRESS_UPDATE = 120000; - private static final int EVENT_DSU_INSTALL_COMPLETE = 120001; - private static final int EVENT_DSU_INSTALL_FAILED = 120002; - private static final int EVENT_DSU_INSTALL_INSUFFICIENT_SPACE = 120003; - protected static void logEventProgressUpdate( String partitionName, long installedBytes, @@ -119,8 +110,7 @@ public class DynamicSystemInstallationService extends Service int partitionNumber, int totalPartitionNumber, int totalProgressPercentage) { - EventLog.writeEvent( - EVENT_DSU_PROGRESS_UPDATE, + EventLogTags.writeDsuProgressUpdate( partitionName, installedBytes, totalBytes, @@ -130,15 +120,15 @@ public class DynamicSystemInstallationService extends Service } protected static void logEventComplete() { - EventLog.writeEvent(EVENT_DSU_INSTALL_COMPLETE); + EventLogTags.writeDsuInstallComplete(); } protected static void logEventFailed(String cause) { - EventLog.writeEvent(EVENT_DSU_INSTALL_FAILED, cause); + EventLogTags.writeDsuInstallFailed(cause); } protected static void logEventInsufficientSpace() { - EventLog.writeEvent(EVENT_DSU_INSTALL_INSUFFICIENT_SPACE); + EventLogTags.writeDsuInstallInsufficientSpace(); } /* diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml index bacab0f8f1e8..00e17f50076d 100644 --- a/packages/Shell/AndroidManifest.xml +++ b/packages/Shell/AndroidManifest.xml @@ -602,6 +602,8 @@ <!-- Permission required for CTS test - CtsThreadNetworkTestCases --> <uses-permission android:name="android.permission.THREAD_NETWORK_PRIVILEGED"/> + <!-- Permission required to access Thread network shell commands for testing --> + <uses-permission android:name="android.permission.THREAD_NETWORK_TESTING"/> <!-- Permission required for CTS tests to enable/disable rate limiting toasts. --> <uses-permission android:name="android.permission.MANAGE_TOAST_RATE_LIMITING" /> diff --git a/packages/SoundPicker/src/com/android/soundpicker/RingtonePickerActivity.java b/packages/SoundPicker/src/com/android/soundpicker/RingtonePickerActivity.java index ee81813b4245..0dd9275503a9 100644 --- a/packages/SoundPicker/src/com/android/soundpicker/RingtonePickerActivity.java +++ b/packages/SoundPicker/src/com/android/soundpicker/RingtonePickerActivity.java @@ -36,6 +36,7 @@ import android.os.UserHandle; import android.os.UserManager; import android.provider.MediaStore; import android.provider.Settings; +import android.text.Html; import android.util.Log; import android.util.TypedValue; import android.view.LayoutInflater; @@ -253,6 +254,9 @@ public final class RingtonePickerActivity extends AlertActivity implements } else { p.mTitle = getString(com.android.internal.R.string.ringtone_picker_title); } + } else { + // Make sure intents don't inject HTML elements. + p.mTitle = Html.escapeHtml(p.mTitle.toString()); } setupAlert(); diff --git a/packages/SystemUI/Android.bp b/packages/SystemUI/Android.bp index b48cac58d7ba..d50b596228b7 100644 --- a/packages/SystemUI/Android.bp +++ b/packages/SystemUI/Android.bp @@ -420,7 +420,6 @@ android_app { kotlincflags: ["-Xjvm-default=all"], optimize: { shrink_resources: false, - optimized_shrink_resources: false, proguard_flags_files: ["proguard.flags"], }, @@ -478,7 +477,6 @@ systemui_optimized_java_defaults { optimize: true, shrink: true, shrink_resources: true, - optimized_shrink_resources: true, ignore_warnings: false, proguard_compatibility: false, }, diff --git a/packages/SystemUI/OWNERS b/packages/SystemUI/OWNERS index 796e3914f3c1..3a5ec92fc335 100644 --- a/packages/SystemUI/OWNERS +++ b/packages/SystemUI/OWNERS @@ -4,7 +4,6 @@ set noparent dsandler@android.com -aaronjli@google.com achalke@google.com acul@google.com adamcohen@google.com diff --git a/packages/SystemUI/flag_check.py b/packages/SystemUI/flag_check.py index bac3553e7498..a492864b11df 100755 --- a/packages/SystemUI/flag_check.py +++ b/packages/SystemUI/flag_check.py @@ -51,7 +51,7 @@ def main(): nargs='?', default='', help= - 'REPO_PATH in repo upload to determine whether the check should run for this project.') + 'REPO_PROJECT in repo upload to determine whether the check should run for this project.') # Parse the arguments args = parser.parse_args() @@ -108,16 +108,16 @@ def main(): sys.exit(0) -def should_run_path(path, files): +def should_run_path(project, files): """Returns a boolean if this check should run with these paths. If you want to check for a particular subdirectory under the path, add a check here, call should_run_files and check for a specific sub dir path in should_run_files. """ - if not path: + if not project: return False - if path == 'frameworks/base': + if project == 'platform/frameworks/base': return should_run_files(files) - # Default case, run for all other paths which calls this script. + # Default case, run for all other projects which calls this script. return True diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java index 95f7c94a235f..73eeed872b4a 100644 --- a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java +++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java @@ -619,6 +619,7 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump private int mDreamingToLockscreenTransitionTranslationY; private int mLockscreenToDreamingTransitionTranslationY; private int mGoneToDreamingTransitionTranslationY; + private boolean mForceFlingAnimationForTest = false; private SplitShadeStateController mSplitShadeStateController; private final Runnable mFlingCollapseRunnable = () -> fling(0, false /* expand */, mNextCollapseSpeedUpFactor, false /* expandBecauseOfFalsing */); @@ -2174,11 +2175,19 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump } } }); + if (!mScrimController.isScreenOn() && !mForceFlingAnimationForTest) { + animator.setDuration(1); + } setAnimator(animator); animator.start(); } @VisibleForTesting + void setForceFlingAnimationForTest(boolean force) { + mForceFlingAnimationForTest = force; + } + + @VisibleForTesting void onFlingEnd(boolean cancelled) { mIsFlinging = false; // No overshoot when the animation ends diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java index ae04eaf49b65..dd42ba99cf52 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java @@ -1588,6 +1588,10 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, Dump mScreenOn = false; } + public boolean isScreenOn() { + return mScreenOn; + } + public void setExpansionAffectsAlpha(boolean expansionAffectsAlpha) { mExpansionAffectsAlpha = expansionAffectsAlpha; } diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java index 28fe8e4e8d3a..c131c32e8ee9 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java @@ -387,6 +387,7 @@ public class NotificationPanelViewControllerTest extends NotificationPanelViewCo public void testOnTouchEvent_expansionResumesAfterBriefTouch() { mFalsingManager.setIsClassifierEnabled(true); mFalsingManager.setIsFalseTouch(false); + mNotificationPanelViewController.setForceFlingAnimationForTest(true); // Start shade collapse with swipe up onTouchEvent(MotionEvent.obtain(0L /* downTime */, 0L /* eventTime */, MotionEvent.ACTION_DOWN, 0f /* x */, 0f /* y */, @@ -415,6 +416,7 @@ public class NotificationPanelViewControllerTest extends NotificationPanelViewCo // fling should still be called after a touch that does not exceed touch slop assertThat(mNotificationPanelViewController.isClosing()).isTrue(); assertThat(mNotificationPanelViewController.isFlinging()).isTrue(); + mNotificationPanelViewController.setForceFlingAnimationForTest(false); } @Test diff --git a/packages/services/CameraExtensionsProxy/src/com/android/cameraextensions/CameraExtensionsProxyService.java b/packages/services/CameraExtensionsProxy/src/com/android/cameraextensions/CameraExtensionsProxyService.java index 7fcef9c90812..c0b354cc69d9 100644 --- a/packages/services/CameraExtensionsProxy/src/com/android/cameraextensions/CameraExtensionsProxyService.java +++ b/packages/services/CameraExtensionsProxy/src/com/android/cameraextensions/CameraExtensionsProxyService.java @@ -2373,7 +2373,7 @@ public class CameraExtensionsProxyService extends Service { public Plane[] getPlanes() { throwISEIfImageIsInvalid(); if (mPlanes == null) { - int fenceFd = mParcelImage.fence != null ? mParcelImage.fence.getFd() : -1; + int fenceFd = mParcelImage.fence != null ? mParcelImage.fence.detachFd() : -1; mGraphicBuffer = GraphicBuffer.createFromHardwareBuffer(mParcelImage.buffer); mPlanes = ImageReader.initializeImagePlanes(mParcelImage.planeCount, mGraphicBuffer, fenceFd, mParcelImage.format, mParcelImage.timestamp, diff --git a/proto/src/ondeviceintelligence/OWNERS b/proto/src/ondeviceintelligence/OWNERS new file mode 100644 index 000000000000..09774f78d712 --- /dev/null +++ b/proto/src/ondeviceintelligence/OWNERS @@ -0,0 +1 @@ +file:/core/java/android/app/ondeviceintelligence/OWNERS diff --git a/ravenwood/OWNERS b/ravenwood/OWNERS index 41fd68e6c2d9..a90328c2e8c6 100644 --- a/ravenwood/OWNERS +++ b/ravenwood/OWNERS @@ -2,4 +2,6 @@ set noparent jsharkey@google.com omakoto@google.com -jaggies@google.com + +per-file ravenwood-annotation-allowed-classes.txt = dplotnikov@google.com +per-file texts/ravenwood-annotation-allowed-classes.txt = dplotnikov@google.com diff --git a/services/autofill/java/com/android/server/autofill/ui/FillUi.java b/services/autofill/java/com/android/server/autofill/ui/FillUi.java index b2716ecc0cfc..7efc94283b1a 100644 --- a/services/autofill/java/com/android/server/autofill/ui/FillUi.java +++ b/services/autofill/java/com/android/server/autofill/ui/FillUi.java @@ -682,12 +682,20 @@ final class FillUi { Slog.v(TAG, "AutofillWindowPresenter.show(): fit=" + fitsSystemWindows + ", params=" + paramsToString(p)); } - UiThread.getHandler().post(() -> mWindow.show(p)); + UiThread.getHandler().post(() -> { + if (mWindow != null) { + mWindow.show(p); + } + }); } @Override public void hide(Rect transitionEpicenter) { - UiThread.getHandler().post(mWindow::hide); + UiThread.getHandler().post(() -> { + if (mWindow != null) { + mWindow.hide(); + } + }); } } diff --git a/services/core/java/com/android/server/BootReceiver.java b/services/core/java/com/android/server/BootReceiver.java index f69a521130ab..23cee9db2138 100644 --- a/services/core/java/com/android/server/BootReceiver.java +++ b/services/core/java/com/android/server/BootReceiver.java @@ -141,6 +141,10 @@ public class BootReceiver extends BroadcastReceiver { private static final int MAX_ERROR_REPORTS = 8; private static int sSentReports = 0; + // Max tombstone file size to add to dropbox. + private static final long MAX_TOMBSTONE_SIZE_BYTES = + DropBoxManagerService.DEFAULT_QUOTA_KB * 1024; + @Override public void onReceive(final Context context, Intent intent) { // Log boot events in the background to avoid blocking the main thread with I/O @@ -390,6 +394,12 @@ public class BootReceiver extends BroadcastReceiver { private static void addAugmentedProtoToDropbox( File tombstone, DropBoxManager db, DropboxRateLimiter.RateLimitResult rateLimitResult) throws IOException { + // Do not add proto files larger than 20Mb to DropBox as they can cause OOMs when + // processing large tombstones. The text tombstone is still added to DropBox. + if (tombstone.length() > MAX_TOMBSTONE_SIZE_BYTES) { + Slog.w(TAG, "Tombstone too large to add to DropBox: " + tombstone.toPath()); + return; + } // Read the proto tombstone file as bytes. final byte[] tombstoneBytes = Files.readAllBytes(tombstone.toPath()); diff --git a/services/core/java/com/android/server/DropBoxManagerService.java b/services/core/java/com/android/server/DropBoxManagerService.java index f82a6aabfefb..70b3bde746af 100644 --- a/services/core/java/com/android/server/DropBoxManagerService.java +++ b/services/core/java/com/android/server/DropBoxManagerService.java @@ -106,7 +106,7 @@ public final class DropBoxManagerService extends SystemService { private static final int DEFAULT_AGE_SECONDS = 3 * 86400; private static final int DEFAULT_MAX_FILES = 1000; private static final int DEFAULT_MAX_FILES_LOWRAM = 300; - private static final int DEFAULT_QUOTA_KB = 10 * 1024; + public static final int DEFAULT_QUOTA_KB = Build.IS_USERDEBUG ? 20 * 1024 : 10 * 1024; private static final int DEFAULT_QUOTA_PERCENT = 10; private static final int DEFAULT_RESERVE_PERCENT = 0; private static final int QUOTA_RESCAN_MILLIS = 5000; diff --git a/services/core/java/com/android/server/PackageWatchdog.java b/services/core/java/com/android/server/PackageWatchdog.java index a61925732256..966478e33c73 100644 --- a/services/core/java/com/android/server/PackageWatchdog.java +++ b/services/core/java/com/android/server/PackageWatchdog.java @@ -138,6 +138,12 @@ public class PackageWatchdog { static final long DEFAULT_BOOT_LOOP_TRIGGER_WINDOW_MS = TimeUnit.MINUTES.toMillis(10); + // Time needed to apply mitigation + private static final String MITIGATION_WINDOW_MS = + "persist.device_config.configuration.mitigation_window_ms"; + @VisibleForTesting + static final long DEFAULT_MITIGATION_WINDOW_MS = TimeUnit.SECONDS.toMillis(5); + // Threshold level at which or above user might experience significant disruption. private static final String MAJOR_USER_IMPACT_LEVEL_THRESHOLD = "persist.device_config.configuration.major_user_impact_level_threshold"; @@ -210,6 +216,9 @@ public class PackageWatchdog { @GuardedBy("mLock") private boolean mSyncRequired = false; + @GuardedBy("mLock") + private long mLastMitigation = -1000000; + @FunctionalInterface @VisibleForTesting interface SystemClock { @@ -400,6 +409,16 @@ public class PackageWatchdog { Slog.w(TAG, "Could not resolve a list of failing packages"); return; } + synchronized (mLock) { + final long now = mSystemClock.uptimeMillis(); + if (Flags.recoverabilityDetection()) { + if (now >= mLastMitigation + && (now - mLastMitigation) < getMitigationWindowMs()) { + Slog.i(TAG, "Skipping onPackageFailure mitigation"); + return; + } + } + } mLongTaskHandler.post(() -> { synchronized (mLock) { if (mAllObservers.isEmpty()) { @@ -500,10 +519,17 @@ public class PackageWatchdog { int currentObserverImpact, int mitigationCount) { if (currentObserverImpact < getUserImpactLevelLimit()) { + synchronized (mLock) { + mLastMitigation = mSystemClock.uptimeMillis(); + } currentObserverToNotify.execute(versionedPackage, failureReason, mitigationCount); } } + private long getMitigationWindowMs() { + return SystemProperties.getLong(MITIGATION_WINDOW_MS, DEFAULT_MITIGATION_WINDOW_MS); + } + /** * Called when the system server boots. If the system server is detected to be in a boot loop, diff --git a/services/core/java/com/android/server/dreams/OWNERS b/services/core/java/com/android/server/dreams/OWNERS index 7302f6e38af2..b9286f864031 100644 --- a/services/core/java/com/android/server/dreams/OWNERS +++ b/services/core/java/com/android/server/dreams/OWNERS @@ -1,4 +1,3 @@ -brycelee@google.com -dsandler@android.com -michaelwr@google.com -roosa@google.com +# Bug component: 66910 +include /core/java/android/service/dreams/OWNERS + diff --git a/services/core/java/com/android/server/health/HealthServiceWrapperAidl.java b/services/core/java/com/android/server/health/HealthServiceWrapperAidl.java index 1153cc37e3da..d4c205964b35 100644 --- a/services/core/java/com/android/server/health/HealthServiceWrapperAidl.java +++ b/services/core/java/com/android/server/health/HealthServiceWrapperAidl.java @@ -198,6 +198,16 @@ class HealthServiceWrapperAidl extends HealthServiceWrapper { } } + public void setChargingPolicy(int policy) throws RemoteException { + IHealth service = mLastService.get(); + if (service == null) return; + try { + service.setChargingPolicy(policy); + } catch (UnsupportedOperationException | ServiceSpecificException ex) { + return; + } + } + private static void traceBegin(String name) { Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, name); } diff --git a/services/core/java/com/android/server/health/OWNERS b/services/core/java/com/android/server/health/OWNERS index 81522fcaa09f..44ab7f75532c 100644 --- a/services/core/java/com/android/server/health/OWNERS +++ b/services/core/java/com/android/server/health/OWNERS @@ -1 +1 @@ -file:platform/hardware/interfaces:/health/aidl/OWNERS +file:platform/hardware/interfaces:/health/OWNERS diff --git a/services/core/java/com/android/server/locales/OWNERS b/services/core/java/com/android/server/locales/OWNERS index e1e946b1c51d..7e35dacd758e 100644 --- a/services/core/java/com/android/server/locales/OWNERS +++ b/services/core/java/com/android/server/locales/OWNERS @@ -1,5 +1,4 @@ roosa@google.com -pratyushmore@google.com goldmanj@google.com ankitavyas@google.com allenwtsu@google.com diff --git a/services/core/java/com/android/server/locksettings/LockSettingsService.java b/services/core/java/com/android/server/locksettings/LockSettingsService.java index ba99d2e4a950..1ad0abf45f55 100644 --- a/services/core/java/com/android/server/locksettings/LockSettingsService.java +++ b/services/core/java/com/android/server/locksettings/LockSettingsService.java @@ -581,7 +581,7 @@ public class LockSettingsService extends ILockSettings.Stub { public RebootEscrowManager getRebootEscrowManager(RebootEscrowManager.Callbacks callbacks, LockSettingsStorage storage) { return new RebootEscrowManager(mContext, callbacks, storage, - getHandler(getServiceThread())); + getHandler(getServiceThread()), getUserManagerInternal()); } public int binderGetCallingUid() { @@ -724,12 +724,13 @@ public class LockSettingsService extends ILockSettings.Stub { !mUserManager.isQuietModeEnabled(userHandle)) { // Only show notifications for managed profiles once their parent // user is unlocked. - showEncryptionNotificationForProfile(userHandle, reason); + showEncryptionNotificationForProfile(userHandle, parent.getUserHandle(), reason); } } } - private void showEncryptionNotificationForProfile(UserHandle user, String reason) { + private void showEncryptionNotificationForProfile(UserHandle user, UserHandle parent, + String reason) { CharSequence title = getEncryptionNotificationTitle(); CharSequence message = getEncryptionNotificationMessage(); CharSequence detail = getEncryptionNotificationDetail(); @@ -746,8 +747,15 @@ public class LockSettingsService extends ILockSettings.Stub { unlockIntent.setFlags( Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); - PendingIntent intent = PendingIntent.getActivity(mContext, 0, unlockIntent, - PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_MUTABLE_UNAUDITED); + PendingIntent intent; + if (android.app.admin.flags.Flags.hsumUnlockNotificationFix()) { + intent = PendingIntent.getActivityAsUser(mContext, 0, unlockIntent, + PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_MUTABLE_UNAUDITED, + null, parent); + } else { + intent = PendingIntent.getActivity(mContext, 0, unlockIntent, + PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_MUTABLE_UNAUDITED); + } Slogf.d(TAG, "Showing encryption notification for user %d; reason: %s", user.getIdentifier(), reason); diff --git a/services/core/java/com/android/server/locksettings/RebootEscrowManager.java b/services/core/java/com/android/server/locksettings/RebootEscrowManager.java index e1cd2c585146..d0b8990e37c4 100644 --- a/services/core/java/com/android/server/locksettings/RebootEscrowManager.java +++ b/services/core/java/com/android/server/locksettings/RebootEscrowManager.java @@ -51,16 +51,20 @@ import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.FrameworkStatsLog; import com.android.internal.util.IndentingPrintWriter; import com.android.internal.widget.RebootEscrowListener; +import com.android.server.pm.UserManagerInternal; import java.io.IOException; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.text.SimpleDateFormat; import java.util.ArrayList; +import java.util.Collections; import java.util.Date; +import java.util.HashSet; import java.util.List; import java.util.Locale; import java.util.Objects; +import java.util.Set; import javax.crypto.SecretKey; @@ -138,6 +142,7 @@ class RebootEscrowManager { ERROR_KEYSTORE_FAILURE, ERROR_NO_NETWORK, ERROR_TIMEOUT_EXHAUSTED, + ERROR_NO_REBOOT_ESCROW_DATA, }) @Retention(RetentionPolicy.SOURCE) @interface RebootEscrowErrorCode { @@ -153,6 +158,7 @@ class RebootEscrowManager { static final int ERROR_KEYSTORE_FAILURE = 7; static final int ERROR_NO_NETWORK = 8; static final int ERROR_TIMEOUT_EXHAUSTED = 9; + static final int ERROR_NO_REBOOT_ESCROW_DATA = 10; private @RebootEscrowErrorCode int mLoadEscrowDataErrorCode = ERROR_NONE; @@ -222,11 +228,16 @@ class RebootEscrowManager { private final RebootEscrowKeyStoreManager mKeyStoreManager; private final LockSettingsStorage mStorage; private RebootEscrowProviderInterface mRebootEscrowProvider; + private final UserManagerInternal mUserManagerInternal; - Injector(Context context, LockSettingsStorage storage) { + Injector( + Context context, + LockSettingsStorage storage, + UserManagerInternal userManagerInternal) { mContext = context; mStorage = storage; mKeyStoreManager = new RebootEscrowKeyStoreManager(); + mUserManagerInternal = userManagerInternal; } private RebootEscrowProviderInterface createRebootEscrowProvider() { @@ -326,6 +337,10 @@ class RebootEscrowManager { return (UserManager) mContext.getSystemService(Context.USER_SERVICE); } + public UserManagerInternal getUserManagerInternal() { + return mUserManagerInternal; + } + public RebootEscrowKeyStoreManager getKeyStoreManager() { return mKeyStoreManager; } @@ -402,8 +417,8 @@ class RebootEscrowManager { } RebootEscrowManager(Context context, Callbacks callbacks, LockSettingsStorage storage, - Handler handler) { - this(new Injector(context, storage), callbacks, storage, handler); + Handler handler, UserManagerInternal userManagerInternal) { + this(new Injector(context, storage, userManagerInternal), callbacks, storage, handler); } @VisibleForTesting @@ -451,18 +466,50 @@ class RebootEscrowManager { onEscrowRestoreComplete(false, attemptCount, retryHandler); } - void loadRebootEscrowDataIfAvailable(Handler retryHandler) { - List<UserInfo> users = mUserManager.getUsers(); + private List<UserInfo> getUsersToUnlock(List<UserInfo> users) { + // System user must be unlocked to unlock any other user + if (mCallbacks.isUserSecure(USER_SYSTEM) && !mStorage.hasRebootEscrow(USER_SYSTEM)) { + Slog.i(TAG, "No reboot escrow data found for system user"); + return Collections.emptyList(); + } + + Set<Integer> noEscrowDataUsers = new HashSet<>(); + for (UserInfo user : users) { + if (mCallbacks.isUserSecure(user.id) + && !mStorage.hasRebootEscrow(user.id)) { + Slog.d(TAG, "No reboot escrow data found for user " + user); + noEscrowDataUsers.add(user.id); + } + } + List<UserInfo> rebootEscrowUsers = new ArrayList<>(); for (UserInfo user : users) { - if (mCallbacks.isUserSecure(user.id) && mStorage.hasRebootEscrow(user.id)) { - rebootEscrowUsers.add(user); + // No lskf, no need to unlock. + if (!mCallbacks.isUserSecure(user.id)) { + continue; + } + // Don't unlock if user or user's parent does not have reboot data + int userId = user.id; + if (noEscrowDataUsers.contains(userId) + || noEscrowDataUsers.contains( + mInjector.getUserManagerInternal().getProfileParentId(userId))) { + continue; } + rebootEscrowUsers.add(user); } + return rebootEscrowUsers; + } + + void loadRebootEscrowDataIfAvailable(Handler retryHandler) { + List<UserInfo> users = mUserManager.getUsers(); + List<UserInfo> rebootEscrowUsers = getUsersToUnlock(users); if (rebootEscrowUsers.isEmpty()) { Slog.i(TAG, "No reboot escrow data found for users," + " skipping loading escrow data"); + setLoadEscrowDataErrorCode(ERROR_NO_REBOOT_ESCROW_DATA, retryHandler); + reportMetricOnRestoreComplete( + /* success= */ false, /* attemptCount= */ 1, retryHandler); clearMetricsStorage(); return; } diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java index a26ac615ba40..b1faa7fe60bd 100644 --- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java +++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java @@ -28,6 +28,7 @@ import static android.Manifest.permission.READ_PHONE_STATE; import static android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE; import static android.app.ActivityManager.PROCESS_CAPABILITY_POWER_RESTRICTED_NETWORK; import static android.app.ActivityManager.PROCESS_CAPABILITY_USER_RESTRICTED_NETWORK; +import static android.app.ActivityManager.PROCESS_STATE_LAST_ACTIVITY; import static android.app.ActivityManager.PROCESS_STATE_UNKNOWN; import static android.app.ActivityManager.isProcStateConsideredInteraction; import static android.app.ActivityManager.printCapabilitiesSummary; @@ -523,6 +524,12 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { */ private boolean mUseMeteredFirewallChains; + /** + * Whether or not sensitive process states and non-sensitive process-states have different + * delays before network is blocked after transitioning to background. + */ + private boolean mUseDifferentDelaysForBackgroundChain; + // See main javadoc for instructions on how to use these locks. final Object mUidRulesFirstLock = new Object(); final Object mNetworkPoliciesSecondLock = new Object(); @@ -552,10 +559,43 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { * {@link NetworkPolicyManager#BACKGROUND_THRESHOLD_STATE} will lose network access. * The delay is meant to prevent churn due to quick process-state changes. * Note that there is no delay while granting network access. + * + * This is only used when the flag {@link #mUseDifferentDelaysForBackgroundChain} is disabled. */ @VisibleForTesting long mBackgroundRestrictionDelayMs = TimeUnit.SECONDS.toMillis(5); + /** + * Short delay after which a uid going into a process state having priority equal to + * {@link NetworkPolicyManager#BACKGROUND_THRESHOLD_STATE} or lower will lose network access. + * + * This will apply to apps that should be fine with losing network access immediately. + * It is only meant as a debounce to prevent churn due to quick process-state changes. + * Note that there is no delay while granting network access. + * + * This is only used when the flag {@link #mUseDifferentDelaysForBackgroundChain} is enabled. + */ + @VisibleForTesting + long mBackgroundRestrictionShortDelayMs = TimeUnit.SECONDS.toMillis(2); + + /** + * Long delay after which a uid going into a process state having priority equal to + * {@link NetworkPolicyManager#BACKGROUND_THRESHOLD_STATE} or lower will lose network access. + * + * Unlike {@link #mBackgroundRestrictionShortDelayMs}, this is meant to be applied to apps + * in sensitive proc-states like {@link ActivityManager#PROCESS_STATE_TOP_SLEEPING} and + * {@link ActivityManager#PROCESS_STATE_LAST_ACTIVITY}, where the user may switch to this app + * before this period and any latency in granting network access before resuming app activities + * may degrade experience. + * + * This is only used when the flag {@link #mUseDifferentDelaysForBackgroundChain} is enabled. + */ + @VisibleForTesting + long mBackgroundRestrictionLongDelayMs = TimeUnit.SECONDS.toMillis(20); + + @GuardedBy("mUidRulesFirstLock") + private long mNextProcessBackgroundUidsTime = Long.MAX_VALUE; + /** Defined network policies. */ @GuardedBy("mNetworkPoliciesSecondLock") final ArrayMap<NetworkTemplate, NetworkPolicy> mNetworkPolicy = new ArrayMap<>(); @@ -1007,6 +1047,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class); mUseMeteredFirewallChains = Flags.useMeteredFirewallChains(); + mUseDifferentDelaysForBackgroundChain = Flags.useDifferentDelaysForBackgroundChain(); synchronized (mUidRulesFirstLock) { synchronized (mNetworkPoliciesSecondLock) { @@ -1241,11 +1282,21 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { // different chains may change. return true; } - if (mBackgroundNetworkRestricted && (previousProcState >= BACKGROUND_THRESHOLD_STATE) + if (mBackgroundNetworkRestricted) { + if ((previousProcState >= BACKGROUND_THRESHOLD_STATE) != (newProcState >= BACKGROUND_THRESHOLD_STATE)) { - // Proc-state change crossed BACKGROUND_THRESHOLD_STATE: Network rules for the - // BACKGROUND chain may change. - return true; + // Proc-state change crossed BACKGROUND_THRESHOLD_STATE: The network rules will + // need to be re-evaluated for the background chain. + return true; + } + if (mUseDifferentDelaysForBackgroundChain + && newProcState >= BACKGROUND_THRESHOLD_STATE + && getBackgroundTransitioningDelay(newProcState) + < getBackgroundTransitioningDelay(previousProcState)) { + // The old and new proc-state both are in the blocked state but the background + // transition delay is reduced, so we may have to update the rules sooner. + return true; + } } final int networkCapabilities = PROCESS_CAPABILITY_POWER_RESTRICTED_NETWORK | PROCESS_CAPABILITY_USER_RESTRICTED_NETWORK; @@ -4045,6 +4096,8 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { + mBackgroundNetworkRestricted); fout.println(Flags.FLAG_USE_METERED_FIREWALL_CHAINS + ": " + mUseMeteredFirewallChains); + fout.println(Flags.FLAG_USE_DIFFERENT_DELAYS_FOR_BACKGROUND_CHAIN + ": " + + mUseDifferentDelaysForBackgroundChain); fout.println(); fout.println("mRestrictBackgroundLowPowerMode: " + mRestrictBackgroundLowPowerMode); @@ -4188,20 +4241,34 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { fout.decreaseIndent(); } - size = mBackgroundTransitioningUids.size(); - if (size > 0) { - final long nowUptime = SystemClock.uptimeMillis(); - fout.println("Uids transitioning to background:"); - fout.increaseIndent(); - for (int i = 0; i < size; i++) { - fout.print("UID="); - fout.print(mBackgroundTransitioningUids.keyAt(i)); - fout.print(", "); - TimeUtils.formatDuration(mBackgroundTransitioningUids.valueAt(i), nowUptime, - fout); + if (mBackgroundNetworkRestricted) { + fout.println(); + if (mUseDifferentDelaysForBackgroundChain) { + fout.print("Background restrictions short delay: "); + TimeUtils.formatDuration(mBackgroundRestrictionShortDelayMs, fout); + fout.println(); + + fout.print("Background restrictions long delay: "); + TimeUtils.formatDuration(mBackgroundRestrictionLongDelayMs, fout); fout.println(); } - fout.decreaseIndent(); + + size = mBackgroundTransitioningUids.size(); + if (size > 0) { + final long nowUptime = SystemClock.uptimeMillis(); + fout.println("Uids transitioning to background:"); + fout.increaseIndent(); + for (int i = 0; i < size; i++) { + fout.print("UID="); + fout.print(mBackgroundTransitioningUids.keyAt(i)); + fout.print(", "); + TimeUtils.formatDuration(mBackgroundTransitioningUids.valueAt(i), + nowUptime, fout); + fout.println(); + } + fout.decreaseIndent(); + } + fout.println(); } final SparseBooleanArray knownUids = new SparseBooleanArray(); @@ -4331,6 +4398,15 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { || isProcStateAllowedNetworkWhileBackground(mUidState.get(uid)); } + private long getBackgroundTransitioningDelay(int procState) { + if (mUseDifferentDelaysForBackgroundChain) { + return procState <= PROCESS_STATE_LAST_ACTIVITY ? mBackgroundRestrictionLongDelayMs + : mBackgroundRestrictionShortDelayMs; + } else { + return mBackgroundRestrictionDelayMs; + } + } + /** * Process state of UID changed; if needed, will trigger * {@link #updateRulesForDataUsageRestrictionsUL(int)} and @@ -4381,19 +4457,41 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { mBackgroundTransitioningUids.delete(uid); updateRuleForBackgroundUL(uid); updatePowerRestrictionRules = true; - } else if (wasAllowed && !isAllowed) { + } else if (!isAllowed) { + final int transitionIdx = mBackgroundTransitioningUids.indexOfKey(uid); final long completionTimeMs = SystemClock.uptimeMillis() - + mBackgroundRestrictionDelayMs; - if (mBackgroundTransitioningUids.indexOfKey(uid) < 0) { - // This is just a defensive check in case the upstream code ever makes - // multiple calls for the same process state change. - mBackgroundTransitioningUids.put(uid, completionTimeMs); + + getBackgroundTransitioningDelay(procState); + boolean completionTimeUpdated = false; + if (wasAllowed) { + // Rules need to transition from allowed to blocked after the respective + // delay. + if (transitionIdx < 0) { + // This is just a defensive check in case the upstream code ever + // makes multiple calls for the same process state change. + mBackgroundTransitioningUids.put(uid, completionTimeMs); + completionTimeUpdated = true; + } + } else if (mUseDifferentDelaysForBackgroundChain) { + // wasAllowed was false, but the transition delay may have reduced. + // Currently, this can happen when the uid transitions from + // LAST_ACTIVITY to CACHED_ACTIVITY, for example. + if (transitionIdx >= 0 + && completionTimeMs < mBackgroundTransitioningUids.valueAt( + transitionIdx)) { + mBackgroundTransitioningUids.setValueAt(transitionIdx, + completionTimeMs); + completionTimeUpdated = true; + } } - if (!mHandler.hasMessages(MSG_PROCESS_BACKGROUND_TRANSITIONING_UIDS)) { - // Many uids may be in this "transitioning" state at the same time, so - // using one message at a time to avoid congestion in the MessageQueue. + if (completionTimeUpdated + && completionTimeMs < mNextProcessBackgroundUidsTime) { + // Many uids may be in this "transitioning" state at the same time, + // so we always keep one message to process transition completion at + // the earliest time. + mHandler.removeMessages(MSG_PROCESS_BACKGROUND_TRANSITIONING_UIDS); mHandler.sendEmptyMessageAtTime( MSG_PROCESS_BACKGROUND_TRANSITIONING_UIDS, completionTimeMs); + mNextProcessBackgroundUidsTime = completionTimeMs; } } } @@ -5744,10 +5842,11 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { updateRuleForBackgroundUL(uid); updateRulesForPowerRestrictionsUL(uid, false); } - } - if (nextCheckTime < Long.MAX_VALUE) { - mHandler.sendEmptyMessageAtTime(MSG_PROCESS_BACKGROUND_TRANSITIONING_UIDS, - nextCheckTime); + mNextProcessBackgroundUidsTime = nextCheckTime; + if (nextCheckTime < Long.MAX_VALUE) { + mHandler.sendEmptyMessageAtTime( + MSG_PROCESS_BACKGROUND_TRANSITIONING_UIDS, nextCheckTime); + } } return true; } diff --git a/services/core/java/com/android/server/net/flags.aconfig b/services/core/java/com/android/server/net/flags.aconfig index e986dd81b94b..586baf022897 100644 --- a/services/core/java/com/android/server/net/flags.aconfig +++ b/services/core/java/com/android/server/net/flags.aconfig @@ -17,3 +17,13 @@ flag { purpose: PURPOSE_BUGFIX } } + +flag { + name: "use_different_delays_for_background_chain" + namespace: "backstage_power" + description: "Grant longer grace periods for sensitive process-states before blocking network using the background chain" + bug: "323963467" + metadata { + purpose: PURPOSE_BUGFIX + } +} diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index 4d05c36cff3a..4e029fde8bf5 100755 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -2291,7 +2291,7 @@ public class NotificationManagerService extends SystemService { @VisibleForTesting void clearNotifications() { - synchronized (mNotificationList) { + synchronized (mNotificationLock) { mEnqueuedNotifications.clear(); mNotificationList.clear(); mNotificationsByKey.clear(); @@ -2301,21 +2301,27 @@ public class NotificationManagerService extends SystemService { @VisibleForTesting void addNotification(NotificationRecord r) { - mNotificationList.add(r); - mNotificationsByKey.put(r.getSbn().getKey(), r); - if (r.getSbn().isGroup()) { - mSummaryByGroupKey.put(r.getGroupKey(), r); + synchronized (mNotificationLock) { + mNotificationList.add(r); + mNotificationsByKey.put(r.getSbn().getKey(), r); + if (r.getSbn().isGroup()) { + mSummaryByGroupKey.put(r.getGroupKey(), r); + } } } @VisibleForTesting void addEnqueuedNotification(NotificationRecord r) { - mEnqueuedNotifications.add(r); + synchronized (mNotificationLock) { + mEnqueuedNotifications.add(r); + } } @VisibleForTesting NotificationRecord getNotificationRecord(String key) { - return mNotificationsByKey.get(key); + synchronized (mNotificationLock) { + return mNotificationsByKey.get(key); + } } diff --git a/services/core/java/com/android/server/notification/NotificationShellCmd.java b/services/core/java/com/android/server/notification/NotificationShellCmd.java index dc0cf4e09207..017a96ef36be 100644 --- a/services/core/java/com/android/server/notification/NotificationShellCmd.java +++ b/services/core/java/com/android/server/notification/NotificationShellCmd.java @@ -66,7 +66,7 @@ public class NotificationShellCmd extends ShellCommand { + " disallow_listener COMPONENT [user_id (current user if not specified)]\n" + " allow_assistant COMPONENT [user_id (current user if not specified)]\n" + " remove_assistant COMPONENT [user_id (current user if not specified)]\n" - + " set_dnd [on|none (same as on)|priority|alarms|all|off (same as all)]" + + " set_dnd [on|none (same as on)|priority|alarms|all|off (same as all)]\n" + " allow_dnd PACKAGE [user_id (current user if not specified)]\n" + " disallow_dnd PACKAGE [user_id (current user if not specified)]\n" + " reset_assistant_user_set [user_id (current user if not specified)]\n" diff --git a/services/core/java/com/android/server/os/NativeTombstoneManager.java b/services/core/java/com/android/server/os/NativeTombstoneManager.java index f6e7ef3d50e9..3bcaf58d0a13 100644 --- a/services/core/java/com/android/server/os/NativeTombstoneManager.java +++ b/services/core/java/com/android/server/os/NativeTombstoneManager.java @@ -56,6 +56,7 @@ import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; +import java.lang.ref.Reference; import java.util.ArrayList; import java.util.Collections; import java.util.Optional; @@ -73,6 +74,9 @@ public final class NativeTombstoneManager { private final Context mContext; private final Handler mHandler; + // TODO(b/339371242): The garbage collector is misbehaving, and we must have + // a reference to this member outside the constructor. More details in the + // corresponding comment elsewhere in this class. private final TombstoneWatcher mWatcher; private final ReentrantLock mTmpFileLock = new ReentrantLock(); @@ -139,6 +143,14 @@ public final class NativeTombstoneManager { processName = parsedTombstone.get().getProcessName(); } BootReceiver.addTombstoneToDropBox(mContext, path, isProtoFile, processName, mTmpFileLock); + + // TODO(b/339371242): An optimizer on WearOS is misbehaving and this member is being garbage + // collected as it's never referenced inside this class outside of the constructor. But, + // it's a file watcher, and needs to stay alive to do its job. So, add a cheap check here to + // force the GC to behave itself. From a technical perspective, it's possible that we need + // to add this trick to every single member function, but this seems to work correctly in + // practice and avoids polluting a lot more of this class. + Reference.reachabilityFence(mWatcher); } private Optional<TombstoneFile> handleProtoTombstone(File path, boolean addToList) { diff --git a/services/core/java/com/android/server/power/stats/BatteryStatsImpl.java b/services/core/java/com/android/server/power/stats/BatteryStatsImpl.java index 4eea8c62822e..8b286adef092 100644 --- a/services/core/java/com/android/server/power/stats/BatteryStatsImpl.java +++ b/services/core/java/com/android/server/power/stats/BatteryStatsImpl.java @@ -3377,7 +3377,7 @@ public class BatteryStatsImpl extends BatteryStats { } return mTotalTimeUs + (mNesting > 0 ? (curBatteryRealtimeUs - mUpdateTimeUs) - / (mTimerPool != null ? mTimerPool.size() : 1) + / (mTimerPool != null && mTimerPool.size() > 0 ? mTimerPool.size() : 1) : 0); } diff --git a/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java b/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java index c8bcc5128c3a..e753ce845ddc 100644 --- a/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java +++ b/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java @@ -926,7 +926,9 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub implements Rollba } Slog.i(TAG, "Enabling rollback for install of " + packageName + ", session:" + session.sessionId - + ", rollbackDataPolicy=" + rollbackDataPolicy); + + ", rollbackDataPolicy=" + rollbackDataPolicy + + ", rollbackId:" + rollback.info.getRollbackId() + + ", originalSessionId:" + rollback.getOriginalSessionId()); final String installerPackageName = session.getInstallerPackageName(); if (!enableRollbackAllowed(installerPackageName, packageName)) { diff --git a/services/core/java/com/android/server/tracing/TracingServiceProxy.java b/services/core/java/com/android/server/tracing/TracingServiceProxy.java index c1d92cffe1a7..68eb8eb1deaf 100644 --- a/services/core/java/com/android/server/tracing/TracingServiceProxy.java +++ b/services/core/java/com/android/server/tracing/TracingServiceProxy.java @@ -93,6 +93,7 @@ public class TracingServiceProxy extends SystemService { private final Context mContext; private final PackageManager mPackageManager; private final LruCache<ComponentName, ServiceConnector<IMessenger>> mCachedReporterServices; + private boolean mServicePublished = false; private final ITracingServiceProxy.Stub mTracingServiceProxy = new ITracingServiceProxy.Stub() { /** @@ -122,9 +123,12 @@ public class TracingServiceProxy extends SystemService { public void onStart() {} @Override - public void onBootPhase(int phase) { - if (phase == SystemService.PHASE_THIRD_PARTY_APPS_CAN_START) { + public void onUserUnlocking(@NonNull TargetUser user) { + // We need the device storage to be unlocked before we can accept and forward + // requests. + if (!mServicePublished) { publishBinderService(TRACING_SERVICE_PROXY_BINDER_NAME, mTracingServiceProxy); + mServicePublished = true; } } diff --git a/services/core/java/com/android/server/wm/AccessibilityWindowsPopulator.java b/services/core/java/com/android/server/wm/AccessibilityWindowsPopulator.java index 3cf19ddbd89d..dd53d32c7d85 100644 --- a/services/core/java/com/android/server/wm/AccessibilityWindowsPopulator.java +++ b/services/core/java/com/android/server/wm/AccessibilityWindowsPopulator.java @@ -561,32 +561,35 @@ public final class AccessibilityWindowsPopulator extends WindowInfosListener { } void dump(PrintWriter pw, String prefix) { - pw.print(prefix); pw.println("AccessibilityWindowsPopulator"); - String prefix2 = prefix + " "; + synchronized (mLock) { + pw.print(prefix); pw.println("AccessibilityWindowsPopulator"); + String prefix2 = prefix + " "; - pw.print(prefix2); pw.print("mWindowsNotificationEnabled: "); - pw.println(mWindowsNotificationEnabled); + pw.print(prefix2); pw.print("mWindowsNotificationEnabled: "); + pw.println(mWindowsNotificationEnabled); - if (mVisibleWindows.isEmpty()) { - pw.print(prefix2); pw.println("No visible windows"); - } else { - pw.print(prefix2); pw.print(mVisibleWindows.size()); - pw.print(" visible windows: "); pw.println(mVisibleWindows); - } - KeyDumper noKeyDumper = (i, k) -> {}; // display id is already shown on value; - KeyDumper displayDumper = (i, d) -> pw.printf("%sDisplay #%d: ", prefix, d); - // Ideally magnificationSpecDumper should use spec.dump(pw), but there is no such method - ValueDumper<MagnificationSpec> magnificationSpecDumper = spec -> pw.print(spec); - - dumpSparseArray(pw, prefix2, mDisplayInfos, "display info", noKeyDumper, d -> pw.print(d)); - dumpSparseArray(pw, prefix2, mInputWindowHandlesOnDisplays, "window handles on display", - displayDumper, list -> pw.print(list)); - dumpSparseArray(pw, prefix2, mMagnificationSpecInverseMatrix, "magnification spec matrix", - noKeyDumper, matrix -> matrix.dump(pw)); - dumpSparseArray(pw, prefix2, mCurrentMagnificationSpec, "current magnification spec", - noKeyDumper, magnificationSpecDumper); - dumpSparseArray(pw, prefix2, mPreviousMagnificationSpec, "previous magnification spec", - noKeyDumper, magnificationSpecDumper); + if (mVisibleWindows.isEmpty()) { + pw.print(prefix2); pw.println("No visible windows"); + } else { + pw.print(prefix2); pw.print(mVisibleWindows.size()); + pw.print(" visible windows: "); pw.println(mVisibleWindows); + } + KeyDumper noKeyDumper = (i, k) -> {}; // display id is already shown on value; + KeyDumper displayDumper = (i, d) -> pw.printf("%sDisplay #%d: ", prefix, d); + // Ideally magnificationSpecDumper should use spec.dump(pw), but there is no such method + ValueDumper<MagnificationSpec> magnificationSpecDumper = spec -> pw.print(spec); + + dumpSparseArray(pw, prefix2, mDisplayInfos, + "display info", noKeyDumper, d -> pw.print(d)); + dumpSparseArray(pw, prefix2, mInputWindowHandlesOnDisplays, + "window handles on display", displayDumper, list -> pw.print(list)); + dumpSparseArray(pw, prefix2, mMagnificationSpecInverseMatrix, + "magnification spec matrix", noKeyDumper, matrix -> matrix.dump(pw)); + dumpSparseArray(pw, prefix2, mCurrentMagnificationSpec, + "current magnification spec", noKeyDumper, magnificationSpecDumper); + dumpSparseArray(pw, prefix2, mPreviousMagnificationSpec, + "previous magnification spec", noKeyDumper, magnificationSpecDumper); + } } @GuardedBy("mLock") diff --git a/services/core/java/com/android/server/wm/EmbeddedWindowController.java b/services/core/java/com/android/server/wm/EmbeddedWindowController.java index b7eab085f5e3..193aacd31705 100644 --- a/services/core/java/com/android/server/wm/EmbeddedWindowController.java +++ b/services/core/java/com/android/server/wm/EmbeddedWindowController.java @@ -68,12 +68,14 @@ class EmbeddedWindowController { mWindows.put(inputToken, window); final IBinder inputTransferToken = window.getInputTransferToken(); mWindowsByInputTransferToken.put(inputTransferToken, window); - mWindowsByWindowToken.put(window.getWindowToken(), window); + final IBinder windowToken = window.getWindowToken(); + mWindowsByWindowToken.put(windowToken, window); updateProcessController(window); window.mClient.linkToDeath(()-> { synchronized (mGlobalLock) { mWindows.remove(inputToken); mWindowsByInputTransferToken.remove(inputTransferToken); + mWindowsByWindowToken.remove(windowToken); } }, 0); } catch (RemoteException e) { diff --git a/services/core/java/com/android/server/wm/TaskFragment.java b/services/core/java/com/android/server/wm/TaskFragment.java index 5d019122d52e..76be8aebb54e 100644 --- a/services/core/java/com/android/server/wm/TaskFragment.java +++ b/services/core/java/com/android/server/wm/TaskFragment.java @@ -1257,10 +1257,13 @@ class TaskFragment extends WindowContainer<WindowContainer> { // In a multi-resumed environment, like in a freeform device, the top // activity can be resumed, but it might not be the focused app. - // Set focused app when top activity is resumed - if (taskDisplayArea.inMultiWindowMode() && taskDisplayArea.mDisplayContent != null - && taskDisplayArea.mDisplayContent.mFocusedApp != next) { - taskDisplayArea.mDisplayContent.setFocusedApp(next); + // Set focused app when top activity is resumed. However, we shouldn't do it for a + // same task because it can break focused state. (e.g. activity embedding) + if (taskDisplayArea.inMultiWindowMode() && taskDisplayArea.mDisplayContent != null) { + final ActivityRecord focusedApp = taskDisplayArea.mDisplayContent.mFocusedApp; + if (focusedApp == null || focusedApp.getTask() != next.getTask()) { + taskDisplayArea.mDisplayContent.setFocusedApp(next); + } } ProtoLog.d(WM_DEBUG_STATES, "resumeTopActivity: Top activity " + "resumed %s", next); diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/NonRequiredPackageDeleteObserver.java b/services/devicepolicy/java/com/android/server/devicepolicy/NonRequiredPackageDeleteObserver.java index 0e448cdb244c..a1bf0401d001 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/NonRequiredPackageDeleteObserver.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/NonRequiredPackageDeleteObserver.java @@ -25,7 +25,6 @@ import android.util.Slog; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicInteger; /** * Awaits the deletion of all the non-required apps. @@ -33,38 +32,38 @@ import java.util.concurrent.atomic.AtomicInteger; final class NonRequiredPackageDeleteObserver extends IPackageDeleteObserver.Stub { private static final int PACKAGE_DELETE_TIMEOUT_SEC = 30; - private final AtomicInteger mPackageCount = new AtomicInteger(/* initialValue= */ 0); private final CountDownLatch mLatch; - private boolean mSuccess; + private boolean mFailed = false; NonRequiredPackageDeleteObserver(int packageCount) { this.mLatch = new CountDownLatch(packageCount); - this.mPackageCount.set(packageCount); } @Override public void packageDeleted(String packageName, int returnCode) { if (returnCode != PackageManager.DELETE_SUCCEEDED) { Slog.e(LOG_TAG, "Failed to delete package: " + packageName); - mLatch.notifyAll(); - return; - } - int currentPackageCount = mPackageCount.decrementAndGet(); - if (currentPackageCount == 0) { - mSuccess = true; - Slog.i(LOG_TAG, "All non-required system apps with launcher icon, " - + "and all disallowed apps have been uninstalled."); + mFailed = true; } mLatch.countDown(); } public boolean awaitPackagesDeletion() { try { - mLatch.await(PACKAGE_DELETE_TIMEOUT_SEC, TimeUnit.SECONDS); + if (mLatch.await(PACKAGE_DELETE_TIMEOUT_SEC, TimeUnit.SECONDS)) { + if (!mFailed) { + Slog.i(LOG_TAG, "All non-required system apps with launcher icon, " + + "and all disallowed apps have been uninstalled."); + } + return !mFailed; + } else { + Slog.i(LOG_TAG, "Waiting time elapsed before all package deletion finished"); + return false; + } } catch (InterruptedException e) { Log.w(LOG_TAG, "Interrupted while waiting for package deletion", e); Thread.currentThread().interrupt(); + return false; } - return mSuccess; } } diff --git a/services/incremental/Android.bp b/services/incremental/Android.bp index 957d7c352bdf..ce05c820cbbc 100644 --- a/services/incremental/Android.bp +++ b/services/incremental/Android.bp @@ -66,7 +66,6 @@ cc_defaults { "libprotobuf-cpp-lite", "service.incremental.proto", "libvold_binder", - "libc++fs", "libziparchive_for_incfs", ], shared_libs: [ diff --git a/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java b/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java index 54d101a3c1cf..cd70ed23a824 100644 --- a/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java +++ b/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java @@ -25,6 +25,7 @@ import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; +import android.hardware.camera2.CameraManager; import android.os.Handler; import android.os.IBinder.DeathRecipient; import android.os.Looper; @@ -58,11 +59,13 @@ import java.util.concurrent.TimeUnit; public final class ProfcollectForwardingService extends SystemService { public static final String LOG_TAG = "ProfcollectForwardingService"; - private static final boolean DEBUG = Log.isLoggable(LOG_TAG, Log.DEBUG); private static final String INTENT_UPLOAD_PROFILES = "com.android.server.profcollect.UPLOAD_PROFILES"; private static final long BG_PROCESS_INTERVAL = TimeUnit.HOURS.toMillis(4); // every 4 hours. + private int mUsageSetting; + private boolean mUploadEnabled; + private IProfCollectd mIProfcollect; private static ProfcollectForwardingService sSelfService; private final Handler mHandler = new ProfcollectdHandler(IoThread.getHandler().getLooper()); @@ -78,7 +81,7 @@ public final class ProfcollectForwardingService extends SystemService { public void onReceive(Context context, Intent intent) { if (INTENT_UPLOAD_PROFILES.equals(intent.getAction())) { Log.d(LOG_TAG, "Received broadcast to pack and upload reports"); - packAndUploadReport(); + createAndUploadReport(sSelfService); } } }; @@ -91,6 +94,17 @@ public final class ProfcollectForwardingService extends SystemService { } sSelfService = this; + // Get "Usage & diagnostics" checkbox status. 1 is for enabled, 0 is for disabled. + try { + mUsageSetting = Settings.Global.getInt(context.getContentResolver(), "multi_cb"); + } catch (SettingNotFoundException e) { + Log.e(LOG_TAG, "Usage setting not found: " + e.getMessage()); + mUsageSetting = -1; + } + + mUploadEnabled = + context.getResources().getBoolean(R.bool.config_profcollectReportUploaderEnabled); + final IntentFilter filter = new IntentFilter(); filter.addAction(INTENT_UPLOAD_PROFILES); context.registerReceiver(mBroadcastReceiver, filter, Context.RECEIVER_NOT_EXPORTED); @@ -106,9 +120,6 @@ public final class ProfcollectForwardingService extends SystemService { @Override public void onStart() { - if (DEBUG) { - Log.d(LOG_TAG, "Profcollect forwarding service start"); - } connectNativeService(); } @@ -221,7 +232,6 @@ public final class ProfcollectForwardingService extends SystemService { */ public static void schedule(Context context) { JobScheduler js = context.getSystemService(JobScheduler.class); - js.schedule(new JobInfo.Builder(JOB_IDLE_PROCESS, JOB_SERVICE_NAME) .setRequiresDeviceIdle(true) .setRequiresCharging(true) @@ -232,22 +242,7 @@ public final class ProfcollectForwardingService extends SystemService { @Override public boolean onStartJob(JobParameters params) { - if (DEBUG) { - Log.d(LOG_TAG, "Starting background process job"); - } - - BackgroundThread.get().getThreadHandler().post( - () -> { - try { - if (sSelfService.mIProfcollect == null) { - return; - } - sSelfService.mIProfcollect.process(); - } catch (RemoteException e) { - Log.e(LOG_TAG, "Failed to process profiles in background: " - + e.getMessage()); - } - }); + createAndUploadReport(sSelfService); jobFinished(params, false); return true; } @@ -264,6 +259,7 @@ public final class ProfcollectForwardingService extends SystemService { BackgroundThread.get().getThreadHandler().post( () -> { registerAppLaunchObserver(); + registerCameraOpenObserver(); registerDex2oatObserver(); registerOTAObserver(); }); @@ -288,9 +284,6 @@ public final class ProfcollectForwardingService extends SystemService { "applaunch_trace_freq", 2); int randomNum = ThreadLocalRandom.current().nextInt(100); if (randomNum < traceFrequency) { - if (DEBUG) { - Log.d(LOG_TAG, "Tracing on app launch event: " + packageName); - } BackgroundThread.get().getThreadHandler().post(() -> { try { mIProfcollect.trace_once("applaunch"); @@ -330,19 +323,14 @@ public final class ProfcollectForwardingService extends SystemService { "dex2oat_trace_freq", 25); int randomNum = ThreadLocalRandom.current().nextInt(100); if (randomNum < traceFrequency) { - if (DEBUG) { - Log.d(LOG_TAG, "Tracing on dex2oat event"); - } - BackgroundThread.get().getThreadHandler().post(() -> { + // Dex2oat could take a while before it starts. Add a short delay before start tracing. + BackgroundThread.get().getThreadHandler().postDelayed(() -> { try { - // Dex2oat could take a while before it starts. Add a short delay before start - // tracing. - Thread.sleep(1000); mIProfcollect.trace_once("dex2oat"); - } catch (RemoteException | InterruptedException e) { + } catch (RemoteException e) { Log.e(LOG_TAG, "Failed to initiate trace: " + e.getMessage()); } - }); + }, 1000); } } @@ -351,13 +339,8 @@ public final class ProfcollectForwardingService extends SystemService { updateEngine.bind(new UpdateEngineCallback() { @Override public void onStatusUpdate(int status, float percent) { - if (DEBUG) { - Log.d(LOG_TAG, "Received OTA status update, status: " + status + ", percent: " - + percent); - } - if (status == UpdateEngine.UpdateStatusConstants.UPDATED_NEED_REBOOT) { - packAndUploadReport(); + createAndUploadReport(sSelfService); } } @@ -368,41 +351,56 @@ public final class ProfcollectForwardingService extends SystemService { }); } - private void packAndUploadReport() { - if (mIProfcollect == null) { - return; - } - - Context context = getContext(); + private static void createAndUploadReport(ProfcollectForwardingService pfs) { BackgroundThread.get().getThreadHandler().post(() -> { + String reportName; try { - int usageSetting = -1; - try { - // Get "Usage & diagnostics" checkbox status. 1 is for enabled, 0 is for - // disabled. - usageSetting = Settings.Global.getInt(context.getContentResolver(), "multi_cb"); - } catch (SettingNotFoundException e) { - Log.i(LOG_TAG, "Usage setting not found: " + e.getMessage()); - } - - // Prepare profile report - String reportName = mIProfcollect.report(usageSetting) + ".zip"; + reportName = pfs.mIProfcollect.report(pfs.mUsageSetting) + ".zip"; + } catch (RemoteException e) { + Log.e(LOG_TAG, "Failed to create report: " + e.getMessage()); + return; + } + if (!pfs.mUploadEnabled) { + Log.i(LOG_TAG, "Upload is not enabled."); + return; + } + Intent intent = new Intent() + .setPackage("com.android.shell") + .setAction("com.android.shell.action.PROFCOLLECT_UPLOAD") + .putExtra("filename", reportName); + pfs.getContext().sendBroadcast(intent); + }); + } - if (!context.getResources().getBoolean( - R.bool.config_profcollectReportUploaderEnabled)) { - Log.i(LOG_TAG, "Upload is not enabled."); + private void registerCameraOpenObserver() { + CameraManager cm = getContext().getSystemService(CameraManager.class); + cm.registerAvailabilityCallback(new CameraManager.AvailabilityCallback() { + @Override + public void onCameraOpened(String cameraId, String packageId) { + Log.d(LOG_TAG, "Received camera open event from: " + packageId); + // Skip face auth and Android System Intelligence, since they trigger way too + // often. + if (packageId.startsWith("client.pid") + || packageId.equals("com.google.android.as")) { return; } - - // Upload the report - Intent intent = new Intent() - .setPackage("com.android.shell") - .setAction("com.android.shell.action.PROFCOLLECT_UPLOAD") - .putExtra("filename", reportName); - context.sendBroadcast(intent); - } catch (RemoteException e) { - Log.e(LOG_TAG, "Failed to upload report: " + e.getMessage()); + // Sample for a fraction of camera events. + final int traceFrequency = + DeviceConfig.getInt(DeviceConfig.NAMESPACE_PROFCOLLECT_NATIVE_BOOT, + "camera_trace_freq", 10); + int randomNum = ThreadLocalRandom.current().nextInt(100); + if (randomNum >= traceFrequency) { + return; + } + // Wait for 1s before starting tracing. + BackgroundThread.get().getThreadHandler().postDelayed(() -> { + try { + mIProfcollect.trace_once("camera"); + } catch (RemoteException e) { + Log.e(LOG_TAG, "Failed to initiate trace: " + e.getMessage()); + } + }, 1000); } - }); + }, null); } } diff --git a/services/tests/ondeviceintelligencetests/OWNERS b/services/tests/ondeviceintelligencetests/OWNERS new file mode 100644 index 000000000000..09774f78d712 --- /dev/null +++ b/services/tests/ondeviceintelligencetests/OWNERS @@ -0,0 +1 @@ +file:/core/java/android/app/ondeviceintelligence/OWNERS diff --git a/services/tests/servicestests/src/com/android/server/locksettings/RebootEscrowManagerTests.java b/services/tests/servicestests/src/com/android/server/locksettings/RebootEscrowManagerTests.java index 64e62369f955..17b499e112bc 100644 --- a/services/tests/servicestests/src/com/android/server/locksettings/RebootEscrowManagerTests.java +++ b/services/tests/servicestests/src/com/android/server/locksettings/RebootEscrowManagerTests.java @@ -19,6 +19,7 @@ package com.android.server.locksettings; import static android.content.pm.UserInfo.FLAG_FULL; import static android.content.pm.UserInfo.FLAG_PRIMARY; import static android.content.pm.UserInfo.FLAG_PROFILE; +import static android.content.pm.UserInfo.NO_PROFILE_GROUP_ID; import static android.os.UserHandle.USER_SYSTEM; import static com.android.internal.widget.LockSettingsInternal.ARM_REBOOT_ERROR_ESCROW_NOT_READY; @@ -32,6 +33,7 @@ import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; +import static org.mockito.ArgumentMatchers.anyByte; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.ArgumentMatchers.eq; @@ -65,6 +67,7 @@ import androidx.test.runner.AndroidJUnit4; import com.android.internal.widget.RebootEscrowListener; import com.android.server.locksettings.ResumeOnRebootServiceProvider.ResumeOnRebootServiceConnection; +import com.android.server.pm.UserManagerInternal; import org.junit.Before; import org.junit.Test; @@ -107,6 +110,7 @@ public class RebootEscrowManagerTests { private Context mContext; private UserManager mUserManager; + private UserManagerInternal mUserManagerInternal; private RebootEscrowManager.Callbacks mCallbacks; private IRebootEscrow mRebootEscrow; private ResumeOnRebootServiceConnection mServiceConnection; @@ -126,13 +130,15 @@ public class RebootEscrowManagerTests { long getCurrentTimeMillis(); void reportMetric(boolean success, int errorCode, int serviceType, int attemptCount, - int escrowDurationInSeconds, int vbmetaDigestStatus, int durationSinceBootComplete); + int escrowDurationInSeconds, int vbmetaDigestStatus, + int durationSinceBootComplete); } static class MockInjector extends RebootEscrowManager.Injector { private final IRebootEscrow mRebootEscrow; private final RebootEscrowProviderInterface mDefaultRebootEscrowProvider; private final UserManager mUserManager; + private final UserManagerInternal mUserManagerInternal; private final MockableRebootEscrowInjected mInjected; private final RebootEscrowKeyStoreManager mKeyStoreManager; private boolean mServerBased; @@ -141,12 +147,16 @@ public class RebootEscrowManagerTests { private Consumer<ConnectivityManager.NetworkCallback> mNetworkConsumer; private boolean mWaitForInternet; - MockInjector(Context context, UserManager userManager, + MockInjector( + Context context, + UserManager userManager, + UserManagerInternal userManagerInternal, IRebootEscrow rebootEscrow, RebootEscrowKeyStoreManager keyStoreManager, LockSettingsStorageTestable storage, MockableRebootEscrowInjected injected) { - super(context, storage); + // TODO: change this + super(context, storage, userManagerInternal); mRebootEscrow = rebootEscrow; mServerBased = false; mWaitForInternet = false; @@ -159,16 +169,20 @@ public class RebootEscrowManagerTests { }; mDefaultRebootEscrowProvider = new RebootEscrowProviderHalImpl(halInjector); mUserManager = userManager; + mUserManagerInternal = userManagerInternal; mKeyStoreManager = keyStoreManager; mInjected = injected; } - MockInjector(Context context, UserManager userManager, + MockInjector( + Context context, + UserManager userManager, + UserManagerInternal userManagerInternal, ResumeOnRebootServiceConnection serviceConnection, RebootEscrowKeyStoreManager keyStoreManager, LockSettingsStorageTestable storage, MockableRebootEscrowInjected injected) { - super(context, storage); + super(context, storage, userManagerInternal); mRebootEscrow = null; mServerBased = true; mWaitForInternet = false; @@ -187,6 +201,7 @@ public class RebootEscrowManagerTests { mDefaultRebootEscrowProvider = new RebootEscrowProviderServerBasedImpl( storage, injector); mUserManager = userManager; + mUserManagerInternal = userManagerInternal; mKeyStoreManager = keyStoreManager; mInjected = injected; } @@ -202,6 +217,11 @@ public class RebootEscrowManagerTests { } @Override + public UserManagerInternal getUserManagerInternal() { + return mUserManagerInternal; + } + + @Override public boolean serverBasedResumeOnReboot() { return mServerBased; } @@ -289,8 +309,8 @@ public class RebootEscrowManagerTests { @Override public void reportMetric(boolean success, int errorCode, int serviceType, int attemptCount, - int escrowDurationInSeconds, int vbmetaDigestStatus, - int durationSinceBootComplete) { + int escrowDurationInSeconds, int vbmetaDigestStatus, + int durationSinceBootComplete) { mInjected.reportMetric(success, errorCode, serviceType, attemptCount, escrowDurationInSeconds, vbmetaDigestStatus, durationSinceBootComplete); @@ -301,6 +321,7 @@ public class RebootEscrowManagerTests { public void setUp_baseServices() throws Exception { mContext = new ContextWrapper(InstrumentationRegistry.getContext()); mUserManager = mock(UserManager.class); + mUserManagerInternal = mock(UserManagerInternal.class); mCallbacks = mock(RebootEscrowManager.Callbacks.class); mRebootEscrow = mock(IRebootEscrow.class); mServiceConnection = mock(ResumeOnRebootServiceConnection.class); @@ -314,28 +335,43 @@ public class RebootEscrowManagerTests { new File(InstrumentationRegistry.getContext().getFilesDir(), "locksettings")); ArrayList<UserInfo> users = new ArrayList<>(); - users.add(new UserInfo(PRIMARY_USER_ID, "primary", FLAG_PRIMARY)); - users.add(new UserInfo(WORK_PROFILE_USER_ID, "work", FLAG_PROFILE)); - users.add(new UserInfo(NONSECURE_SECONDARY_USER_ID, "non-secure", FLAG_FULL)); - users.add(new UserInfo(SECURE_SECONDARY_USER_ID, "secure", FLAG_FULL)); + users.add(createUser(PRIMARY_USER_ID, "primary", FLAG_PRIMARY, PRIMARY_USER_ID)); + users.add(createUser(WORK_PROFILE_USER_ID, "work", FLAG_PROFILE, PRIMARY_USER_ID)); + users.add( + createUser( + NONSECURE_SECONDARY_USER_ID, "non-secure", FLAG_FULL, NO_PROFILE_GROUP_ID)); + users.add(createUser(SECURE_SECONDARY_USER_ID, "secure", FLAG_FULL, NO_PROFILE_GROUP_ID)); when(mUserManager.getUsers()).thenReturn(users); when(mCallbacks.isUserSecure(PRIMARY_USER_ID)).thenReturn(true); when(mCallbacks.isUserSecure(WORK_PROFILE_USER_ID)).thenReturn(true); when(mCallbacks.isUserSecure(NONSECURE_SECONDARY_USER_ID)).thenReturn(false); when(mCallbacks.isUserSecure(SECURE_SECONDARY_USER_ID)).thenReturn(true); mInjected = mock(MockableRebootEscrowInjected.class); - mMockInjector = new MockInjector(mContext, mUserManager, mRebootEscrow, - mKeyStoreManager, mStorage, mInjected); + mMockInjector = + new MockInjector( + mContext, + mUserManager, + mUserManagerInternal, + mRebootEscrow, + mKeyStoreManager, + mStorage, + mInjected); HandlerThread thread = new HandlerThread("RebootEscrowManagerTest"); thread.start(); mHandler = new Handler(thread.getLooper()); mService = new RebootEscrowManager(mMockInjector, mCallbacks, mStorage, mHandler); - } private void setServerBasedRebootEscrowProvider() throws Exception { - mMockInjector = new MockInjector(mContext, mUserManager, mServiceConnection, - mKeyStoreManager, mStorage, mInjected); + mMockInjector = + new MockInjector( + mContext, + mUserManager, + mUserManagerInternal, + mServiceConnection, + mKeyStoreManager, + mStorage, + mInjected); mService = new RebootEscrowManager(mMockInjector, mCallbacks, mStorage, mHandler); } @@ -352,6 +388,12 @@ public class RebootEscrowManagerTests { waitForHandler(); } + private UserInfo createUser(int id, String name, int flag, int profileGroupId) { + UserInfo user = new UserInfo(id, name, flag); + when(mUserManagerInternal.getProfileParentId(eq(id))).thenReturn(profileGroupId); + return user; + } + @Test public void prepareRebootEscrow_Success() throws Exception { RebootEscrowListener mockListener = mock(RebootEscrowListener.class); @@ -559,6 +601,172 @@ public class RebootEscrowManagerTests { } @Test + public void loadRebootEscrowDataIfAvailable_noDataPrimaryUser_Failure() throws Exception { + setServerBasedRebootEscrowProvider(); + RebootEscrowListener mockListener = mock(RebootEscrowListener.class); + mService.setRebootEscrowListener(mockListener); + mService.prepareRebootEscrow(); + + clearInvocations(mServiceConnection); + + // escrow secondary user, don't escrow primary user + callToRebootEscrowIfNeededAndWait(SECURE_SECONDARY_USER_ID); + verify(mockListener).onPreparedForReboot(eq(true)); + verify(mServiceConnection, never()).wrapBlob(any(), anyLong(), anyLong()); + + when(mServiceConnection.wrapBlob(any(), anyLong(), anyLong())) + .thenAnswer(invocation -> invocation.getArgument(0)); + assertEquals(ARM_REBOOT_ERROR_NONE, mService.armRebootEscrowIfNeeded()); + verify(mServiceConnection).wrapBlob(any(), anyLong(), anyLong()); + + assertTrue(mStorage.hasRebootEscrow(SECURE_SECONDARY_USER_ID)); + assertFalse(mStorage.hasRebootEscrow(PRIMARY_USER_ID)); + assertTrue(mStorage.hasRebootEscrowServerBlob()); + + // pretend reboot happens here + when(mInjected.getBootCount()).thenReturn(1); + ArgumentCaptor<Boolean> metricsSuccessCaptor = ArgumentCaptor.forClass(Boolean.class); + ArgumentCaptor<Integer> metricsErrorCodeCaptor = ArgumentCaptor.forClass(Integer.class); + doNothing() + .when(mInjected) + .reportMetric( + metricsSuccessCaptor.capture(), + metricsErrorCodeCaptor.capture(), + eq(2) /* Server based */, + eq(1) /* attempt count */, + anyInt(), + eq(0) /* vbmeta status */, + anyInt()); + mService.loadRebootEscrowDataIfAvailable(null); + verify(mServiceConnection, never()).unwrap(any(), anyLong()); + verify(mCallbacks, never()).onRebootEscrowRestored(anyByte(), any(), anyInt()); + assertFalse(metricsSuccessCaptor.getValue()); + assertEquals( + Integer.valueOf(RebootEscrowManager.ERROR_NO_REBOOT_ESCROW_DATA), + metricsErrorCodeCaptor.getValue()); + } + + @Test + public void loadRebootEscrowDataIfAvailable_noDataSecondaryUser_Success() throws Exception { + setServerBasedRebootEscrowProvider(); + RebootEscrowListener mockListener = mock(RebootEscrowListener.class); + mService.setRebootEscrowListener(mockListener); + mService.prepareRebootEscrow(); + + clearInvocations(mServiceConnection); + + // Setup work profile with secondary user as parent. + ArrayList<UserInfo> users = new ArrayList<>(); + users.add(createUser(PRIMARY_USER_ID, "primary", FLAG_PRIMARY, NO_PROFILE_GROUP_ID)); + users.add(createUser(WORK_PROFILE_USER_ID, "work", FLAG_PROFILE, SECURE_SECONDARY_USER_ID)); + users.add( + createUser( + SECURE_SECONDARY_USER_ID, "secure", FLAG_FULL, SECURE_SECONDARY_USER_ID)); + when(mUserManager.getUsers()).thenReturn(users); + + // escrow primary user and work profile, don't escrow secondary user + callToRebootEscrowIfNeededAndWait(PRIMARY_USER_ID); + verify(mockListener).onPreparedForReboot(eq(true)); + verify(mServiceConnection, never()).wrapBlob(any(), anyLong(), anyLong()); + callToRebootEscrowIfNeededAndWait(WORK_PROFILE_USER_ID); + verify(mockListener).onPreparedForReboot(eq(true)); + verify(mServiceConnection, never()).wrapBlob(any(), anyLong(), anyLong()); + + when(mServiceConnection.wrapBlob(any(), anyLong(), anyLong())) + .thenAnswer(invocation -> invocation.getArgument(0)); + assertEquals(ARM_REBOOT_ERROR_NONE, mService.armRebootEscrowIfNeeded()); + verify(mServiceConnection).wrapBlob(any(), anyLong(), anyLong()); + + assertTrue(mStorage.hasRebootEscrow(PRIMARY_USER_ID)); + assertFalse(mStorage.hasRebootEscrow(SECURE_SECONDARY_USER_ID)); + assertTrue(mStorage.hasRebootEscrow(WORK_PROFILE_USER_ID)); + assertTrue(mStorage.hasRebootEscrowServerBlob()); + + // pretend reboot happens here + when(mInjected.getBootCount()).thenReturn(1); + ArgumentCaptor<Boolean> metricsSuccessCaptor = ArgumentCaptor.forClass(Boolean.class); + doNothing() + .when(mInjected) + .reportMetric( + metricsSuccessCaptor.capture(), + eq(0) /* error code */, + eq(2) /* Server based */, + eq(1) /* attempt count */, + anyInt(), + eq(0) /* vbmeta status */, + anyInt()); + when(mServiceConnection.unwrap(any(), anyLong())) + .thenAnswer(invocation -> invocation.getArgument(0)); + + mService.loadRebootEscrowDataIfAvailable(null); + + verify(mServiceConnection).unwrap(any(), anyLong()); + verify(mCallbacks).onRebootEscrowRestored(anyByte(), any(), eq(PRIMARY_USER_ID)); + verify(mCallbacks, never()) + .onRebootEscrowRestored(anyByte(), any(), eq(SECURE_SECONDARY_USER_ID)); + verify(mCallbacks, never()) + .onRebootEscrowRestored(anyByte(), any(), eq(WORK_PROFILE_USER_ID)); + verify(mCallbacks, never()) + .onRebootEscrowRestored(anyByte(), any(), eq(NONSECURE_SECONDARY_USER_ID)); + assertTrue(metricsSuccessCaptor.getValue()); + } + + @Test + public void loadRebootEscrowDataIfAvailable_noDataWorkProfile_Success() throws Exception { + setServerBasedRebootEscrowProvider(); + RebootEscrowListener mockListener = mock(RebootEscrowListener.class); + mService.setRebootEscrowListener(mockListener); + mService.prepareRebootEscrow(); + + clearInvocations(mServiceConnection); + + // escrow primary user and secondary user, don't escrow work profile + callToRebootEscrowIfNeededAndWait(PRIMARY_USER_ID); + verify(mockListener).onPreparedForReboot(eq(true)); + verify(mServiceConnection, never()).wrapBlob(any(), anyLong(), anyLong()); + callToRebootEscrowIfNeededAndWait(SECURE_SECONDARY_USER_ID); + verify(mockListener).onPreparedForReboot(eq(true)); + verify(mServiceConnection, never()).wrapBlob(any(), anyLong(), anyLong()); + + when(mServiceConnection.wrapBlob(any(), anyLong(), anyLong())) + .thenAnswer(invocation -> invocation.getArgument(0)); + assertEquals(ARM_REBOOT_ERROR_NONE, mService.armRebootEscrowIfNeeded()); + verify(mServiceConnection).wrapBlob(any(), anyLong(), anyLong()); + + assertTrue(mStorage.hasRebootEscrow(PRIMARY_USER_ID)); + assertTrue(mStorage.hasRebootEscrow(SECURE_SECONDARY_USER_ID)); + assertFalse(mStorage.hasRebootEscrow(WORK_PROFILE_USER_ID)); + assertTrue(mStorage.hasRebootEscrowServerBlob()); + + // pretend reboot happens here + when(mInjected.getBootCount()).thenReturn(1); + ArgumentCaptor<Boolean> metricsSuccessCaptor = ArgumentCaptor.forClass(Boolean.class); + doNothing() + .when(mInjected) + .reportMetric( + metricsSuccessCaptor.capture(), + eq(0) /* error code */, + eq(2) /* Server based */, + eq(1) /* attempt count */, + anyInt(), + eq(0) /* vbmeta status */, + anyInt()); + when(mServiceConnection.unwrap(any(), anyLong())) + .thenAnswer(invocation -> invocation.getArgument(0)); + + mService.loadRebootEscrowDataIfAvailable(null); + + verify(mServiceConnection).unwrap(any(), anyLong()); + verify(mCallbacks).onRebootEscrowRestored(anyByte(), any(), eq(PRIMARY_USER_ID)); + verify(mCallbacks).onRebootEscrowRestored(anyByte(), any(), eq(SECURE_SECONDARY_USER_ID)); + verify(mCallbacks, never()) + .onRebootEscrowRestored(anyByte(), any(), eq(WORK_PROFILE_USER_ID)); + verify(mCallbacks, never()) + .onRebootEscrowRestored(anyByte(), any(), eq(NONSECURE_SECONDARY_USER_ID)); + assertTrue(metricsSuccessCaptor.getValue()); + } + + @Test public void loadRebootEscrowDataIfAvailable_ServerBased_Success() throws Exception { setServerBasedRebootEscrowProvider(); diff --git a/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java index bd30ef583903..7be457ee2565 100644 --- a/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java @@ -18,11 +18,13 @@ package com.android.server.net; import static android.Manifest.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS; import static android.Manifest.permission.NETWORK_STACK; +import static android.app.ActivityManager.MAX_PROCESS_STATE; import static android.app.ActivityManager.PROCESS_CAPABILITY_ALL; import static android.app.ActivityManager.PROCESS_CAPABILITY_NONE; import static android.app.ActivityManager.PROCESS_CAPABILITY_POWER_RESTRICTED_NETWORK; import static android.app.ActivityManager.PROCESS_CAPABILITY_USER_RESTRICTED_NETWORK; import static android.app.ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; +import static android.app.ActivityManager.PROCESS_STATE_LAST_ACTIVITY; import static android.app.ActivityManager.PROCESS_STATE_SERVICE; import static android.app.ActivityManager.PROCESS_STATE_TOP; import static android.net.ConnectivityManager.BLOCKED_METERED_REASON_DATA_SAVER; @@ -165,9 +167,11 @@ import android.os.PowerManagerInternal; import android.os.PowerSaveState; import android.os.RemoteException; import android.os.SimpleClock; +import android.os.SystemClock; import android.os.UserHandle; import android.os.UserManager; import android.platform.test.annotations.Presubmit; +import android.platform.test.annotations.RequiresFlagsDisabled; import android.platform.test.annotations.RequiresFlagsEnabled; import android.platform.test.flag.junit.CheckFlagsRule; import android.platform.test.flag.junit.DeviceFlagsValueProvider; @@ -2158,7 +2162,8 @@ public class NetworkPolicyManagerServiceTest { @Test @RequiresFlagsEnabled(Flags.FLAG_NETWORK_BLOCKED_FOR_TOP_SLEEPING_AND_ABOVE) - public void testBackgroundChainOnProcStateChange() throws Exception { + @RequiresFlagsDisabled(Flags.FLAG_USE_DIFFERENT_DELAYS_FOR_BACKGROUND_CHAIN) + public void testBackgroundChainOnProcStateChangeSameDelay() throws Exception { // initialization calls setFirewallChainEnabled, so we want to reset the invocations. clearInvocations(mNetworkManager); @@ -2186,6 +2191,59 @@ public class NetworkPolicyManagerServiceTest { } @Test + @RequiresFlagsEnabled({ + Flags.FLAG_NETWORK_BLOCKED_FOR_TOP_SLEEPING_AND_ABOVE, + Flags.FLAG_USE_DIFFERENT_DELAYS_FOR_BACKGROUND_CHAIN + }) + public void testBackgroundChainOnProcStateChangeDifferentDelays() throws Exception { + // The app will be blocked when there is no prior proc-state. + assertTrue(mService.isUidNetworkingBlocked(UID_A, false)); + + // Tweak delays to avoid waiting too long in tests. + mService.mBackgroundRestrictionShortDelayMs = 50; + mService.mBackgroundRestrictionLongDelayMs = 1000; + + int procStateSeq = 231; // Any arbitrary starting sequence. + for (int ps = BACKGROUND_THRESHOLD_STATE; ps <= MAX_PROCESS_STATE; ps++) { + clearInvocations(mNetworkManager); + + // Make sure app is in correct process-state to access network. + callAndWaitOnUidStateChanged(UID_A, BACKGROUND_THRESHOLD_STATE - 1, procStateSeq++); + verify(mNetworkManager).setFirewallUidRule(FIREWALL_CHAIN_BACKGROUND, UID_A, + FIREWALL_RULE_ALLOW); + assertFalse(mService.isUidNetworkingBlocked(UID_A, false)); + + // Now put the app into the background and test that it eventually loses network. + callAndWaitOnUidStateChanged(UID_A, ps, procStateSeq++); + + final long uidStateChangeTime = SystemClock.uptimeMillis(); + if (ps <= PROCESS_STATE_LAST_ACTIVITY) { + // Verify that the app is blocked after long delay but not after short delay. + waitForDelayedMessageOnHandler(mService.mBackgroundRestrictionShortDelayMs + 1); + verify(mNetworkManager, never()).setFirewallUidRule(FIREWALL_CHAIN_BACKGROUND, + UID_A, FIREWALL_RULE_DEFAULT); + assertFalse(mService.isUidNetworkingBlocked(UID_A, false)); + + final long timeUntilLongDelay = uidStateChangeTime + + mService.mBackgroundRestrictionLongDelayMs - SystemClock.uptimeMillis(); + assertTrue("No time left to verify long delay in background transition", + timeUntilLongDelay >= 0); + + waitForDelayedMessageOnHandler(timeUntilLongDelay + 1); + verify(mNetworkManager).setFirewallUidRule(FIREWALL_CHAIN_BACKGROUND, UID_A, + FIREWALL_RULE_DEFAULT); + assertTrue(mService.isUidNetworkingBlocked(UID_A, false)); + } else { + // Verify that the app is blocked after short delay. + waitForDelayedMessageOnHandler(mService.mBackgroundRestrictionShortDelayMs + 1); + verify(mNetworkManager).setFirewallUidRule(FIREWALL_CHAIN_BACKGROUND, UID_A, + FIREWALL_RULE_DEFAULT); + assertTrue(mService.isUidNetworkingBlocked(UID_A, false)); + } + } + } + + @Test @RequiresFlagsEnabled(Flags.FLAG_NETWORK_BLOCKED_FOR_TOP_SLEEPING_AND_ABOVE) public void testBackgroundChainOnAllowlistChange() throws Exception { // initialization calls setFirewallChainEnabled, so we want to reset the invocations. @@ -2881,6 +2939,11 @@ public class NetworkPolicyManagerServiceTest { } } + /** + * This posts a blocking message to the service handler with the given delayMs and waits for it + * to complete. This ensures that all messages posted before the given delayMs will also + * have been executed before this method returns and can be verified in subsequent code. + */ private void waitForDelayedMessageOnHandler(long delayMs) throws InterruptedException { final CountDownLatch latch = new CountDownLatch(1); mService.getHandlerForTesting().postDelayed(latch::countDown, delayMs); diff --git a/test-mock/api/system-current.txt b/test-mock/api/system-current.txt index f35095743738..7d891c8150fd 100644 --- a/test-mock/api/system-current.txt +++ b/test-mock/api/system-current.txt @@ -28,7 +28,7 @@ package android.test.mock { method @Deprecated public void removeOnPermissionsChangeListener(android.content.pm.PackageManager.OnPermissionsChangedListener); method @Deprecated public void revokeRuntimePermission(String, String, android.os.UserHandle); method @Deprecated public boolean setDefaultBrowserPackageNameAsUser(String, int); - method public String[] setPackagesSuspended(String[], boolean, android.os.PersistableBundle, android.os.PersistableBundle, String); + method @Deprecated public String[] setPackagesSuspended(String[], boolean, android.os.PersistableBundle, android.os.PersistableBundle, String); method @Deprecated public void setUpdateAvailable(String, boolean); method @Deprecated public boolean updateIntentVerificationStatusAsUser(String, int, int); method @Deprecated public void updatePermissionFlags(String, String, int, int, android.os.UserHandle); diff --git a/tests/BinderLeakTest/Android.bp b/tests/BinderLeakTest/Android.bp index 78b0ede76d4e..3747d049417f 100644 --- a/tests/BinderLeakTest/Android.bp +++ b/tests/BinderLeakTest/Android.bp @@ -24,6 +24,9 @@ java_defaults { "androidx.test.rules", "androidx.test.runner", ], + test_suites: [ + "general-tests", + ], } // Built with target_sdk_version: current diff --git a/tests/FlickerTests/IME/Android.bp b/tests/FlickerTests/IME/Android.bp index 1141e5f3ae2f..b10006f75a58 100644 --- a/tests/FlickerTests/IME/Android.bp +++ b/tests/FlickerTests/IME/Android.bp @@ -38,6 +38,10 @@ android_test { defaults: ["FlickerTestsDefault"], manifest: "AndroidManifest.xml", test_config_template: "AndroidTestTemplate.xml", + test_suites: [ + "device-tests", + "device-platinum-tests", + ], srcs: ["src/**/*"], static_libs: ["FlickerTestsBase"], data: ["trace_config/*"], @@ -55,6 +59,10 @@ android_test { defaults: ["FlickerTestsDefault"], manifest: "AndroidManifest.xml", test_config_template: "AndroidTestTemplate.xml", + test_suites: [ + "device-tests", + "device-platinum-tests", + ], srcs: [":FlickerTestsIme1-src"], static_libs: [ "FlickerTestsBase", diff --git a/tests/FlickerTests/Rotation/Android.bp b/tests/FlickerTests/Rotation/Android.bp index 233a27691e21..6a0d9efa91e8 100644 --- a/tests/FlickerTests/Rotation/Android.bp +++ b/tests/FlickerTests/Rotation/Android.bp @@ -28,6 +28,10 @@ android_test { defaults: ["FlickerTestsDefault"], manifest: "AndroidManifest.xml", test_config_template: "AndroidTestTemplate.xml", + test_suites: [ + "device-tests", + "device-platinum-tests", + ], srcs: ["src/**/*"], static_libs: ["FlickerTestsBase"], data: ["trace_config/*"], diff --git a/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java b/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java index 093923f3ed53..a8b383cd4274 100644 --- a/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java +++ b/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java @@ -101,8 +101,8 @@ public class PackageWatchdogTest { private static final String OBSERVER_NAME_2 = "observer2"; private static final String OBSERVER_NAME_3 = "observer3"; private static final String OBSERVER_NAME_4 = "observer4"; - private static final long SHORT_DURATION = TimeUnit.SECONDS.toMillis(1); - private static final long LONG_DURATION = TimeUnit.SECONDS.toMillis(5); + private static final long SHORT_DURATION = TimeUnit.SECONDS.toMillis(10); + private static final long LONG_DURATION = TimeUnit.SECONDS.toMillis(50); @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); @@ -1453,7 +1453,8 @@ public class PackageWatchdogTest { raiseFatalFailureAndDispatch(watchdog, Arrays.asList(new VersionedPackage(APP_A, VERSION_CODE)), PackageWatchdog.FAILURE_REASON_UNKNOWN); - moveTimeForwardAndDispatch(PackageWatchdog.DEFAULT_DEESCALATION_WINDOW_MS); + moveTimeForwardAndDispatch(PackageWatchdog.DEFAULT_DEESCALATION_WINDOW_MS + - TimeUnit.MINUTES.toMillis(1)); // The first failure will be outside the threshold. raiseFatalFailureAndDispatch(watchdog, Arrays.asList(new VersionedPackage(APP_A, @@ -1712,6 +1713,9 @@ public class PackageWatchdogTest { watchdog.onPackageFailure(packages, failureReason); } mTestLooper.dispatchAll(); + if (Flags.recoverabilityDetection()) { + moveTimeForwardAndDispatch(watchdog.DEFAULT_MITIGATION_WINDOW_MS); + } } private PackageWatchdog createWatchdog() { diff --git a/tools/hoststubgen/OWNERS b/tools/hoststubgen/OWNERS index a8c5321307d1..3d8888d83cf4 100644 --- a/tools/hoststubgen/OWNERS +++ b/tools/hoststubgen/OWNERS @@ -1,3 +1 @@ -omakoto@google.com -jsharkey@google.com -jaggies@google.com +file:platform/frameworks/base:/ravenwood/OWNERS diff --git a/tools/localedata/extract_icu_data.py b/tools/localedata/extract_icu_data.py index 81ac897deae0..8f67fa87adb5 100755 --- a/tools/localedata/extract_icu_data.py +++ b/tools/localedata/extract_icu_data.py @@ -22,6 +22,8 @@ import glob import os.path import sys +import xml.etree.ElementTree as ElementTree + def get_locale_parts(locale): """Split a locale into three parts, for langauge, script, and region.""" @@ -40,42 +42,43 @@ def get_locale_parts(locale): def read_likely_subtags(input_file_name): """Read and parse ICU's likelySubtags.txt.""" - with open(input_file_name) as input_file: - likely_script_dict = { - # Android's additions for pseudo-locales. These internal codes make - # sure that the pseudo-locales would not match other English or - # Arabic locales. (We can't use private-use ISO 15924 codes, since - # they may be used by apps for other purposes.) - "en_XA": "~~~A", - "ar_XB": "~~~B", - # Removed data from later versions of ICU - "ji": "Hebr", # Old code for Yiddish, still used in Java and Android - } - representative_locales = { - # Android's additions - "en_Latn_GB", # representative for en_Latn_001 - "es_Latn_MX", # representative for es_Latn_419 - "es_Latn_US", # representative for es_Latn_419 (not the best idea, - # but Android has been shipping with it for quite a - # while. Fortunately, MX < US, so if both exist, MX - # would be chosen.) - } - for line in input_file: - line = line.strip(u' \n\uFEFF') - if line.startswith('//'): - continue - if '{' in line and '}' in line: - from_locale = line[:line.index('{')] - to_locale = line[line.index('"')+1:line.rindex('"')] - from_lang, from_scr, from_region = get_locale_parts(from_locale) - _, to_scr, to_region = get_locale_parts(to_locale) - if from_lang == 'und': - continue # not very useful for our purposes - if from_region is None and to_region not in ['001', 'ZZ']: - representative_locales.add(to_locale) - if from_scr is None: - likely_script_dict[from_locale] = to_scr - return likely_script_dict, frozenset(representative_locales) + likely_script_dict = { + # Android's additions for pseudo-locales. These internal codes make + # sure that the pseudo-locales would not match other English or + # Arabic locales. (We can't use private-use ISO 15924 codes, since + # they may be used by apps for other purposes.) + "en_XA": "~~~A", + "ar_XB": "~~~B", + # Removed data from later versions of ICU + "ji": "Hebr", # Old code for Yiddish, still used in Java and Android + } + representative_locales = { + # Android's additions + "en_Latn_GB", # representative for en_Latn_001 + "es_Latn_MX", # representative for es_Latn_419 + "es_Latn_US", # representative for es_Latn_419 (not the best idea, + # but Android has been shipping with it for quite a + # while. Fortunately, MX < US, so if both exist, MX + # would be chosen.) + } + xml_tree = ElementTree.parse(input_file_name) + likely_subtags = xml_tree.find('likelySubtags') + for child in likely_subtags: + from_locale = child.get('from') + to_locale = child.get('to') + # print(f'from: {from_locale} to: {to_locale}') + from_lang, from_scr, from_region = get_locale_parts(from_locale) + _, to_scr, to_region = get_locale_parts(to_locale) + if to_locale == "FAIL": + continue # "FAIL" cases are not useful here. + if from_lang == 'und': + continue # not very useful for our purposes + if from_region is None and to_region not in ['001', 'ZZ']: + representative_locales.add(to_locale) + if from_scr is None: + likely_script_dict[from_locale] = to_scr + + return likely_script_dict, frozenset(representative_locales) # From packLanguageOrRegion() in ResourceTypes.cpp @@ -86,7 +89,7 @@ def pack_language_or_region(inp, base): elif len(inp) == 2: return ord(inp[0]), ord(inp[1]) else: - assert len(inp) == 3 + assert len(inp) == 3, f'Expects a 3-character string, but "{inp}" ' base = ord(base) first = ord(inp[0]) - base second = ord(inp[1]) - base @@ -161,9 +164,10 @@ def dump_representative_locales(representative_locales): print('});') -def read_and_dump_likely_data(icu_data_dir): +def read_and_dump_likely_data(cldr_source_dir): """Read and dump the likely-script data.""" - likely_subtags_txt = os.path.join(icu_data_dir, 'misc', 'likelySubtags.txt') + likely_subtags_txt = os.path.join(cldr_source_dir, + 'common', 'supplemental', 'likelySubtags.xml') likely_script_dict, representative_locales = read_likely_subtags( likely_subtags_txt) @@ -280,10 +284,11 @@ def main(): icu_data_dir = os.path.join( source_root, 'external', 'icu', 'icu4c', 'source', 'data') + cldr_source_dir = os.path.join(source_root, 'external', 'cldr') print('// Auto-generated by %s' % sys.argv[0]) print() - likely_script_dict = read_and_dump_likely_data(icu_data_dir) + likely_script_dict = read_and_dump_likely_data(cldr_source_dir) read_and_dump_parent_data(icu_data_dir, likely_script_dict) |