diff options
17 files changed, 697 insertions, 888 deletions
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java index cbbe7856178d..6dd0a9077a67 100644 --- a/core/java/android/view/SurfaceControl.java +++ b/core/java/android/view/SurfaceControl.java @@ -1247,7 +1247,7 @@ public final class SurfaceControl implements Parcelable { * surface has no buffer or crop, the surface is boundless and only constrained * by the size of its parent bounds. * - * @param session The surface session, must not be null. + * @param session The surface session. * @param name The surface name, must not be null. * @param w The surface initial width. * @param h The surface initial height. diff --git a/packages/CrashRecovery/services/java/com/android/server/PackageWatchdog.java b/packages/CrashRecovery/services/java/com/android/server/PackageWatchdog.java index a8d8f9a1a55d..6f20adf74ee2 100644 --- a/packages/CrashRecovery/services/java/com/android/server/PackageWatchdog.java +++ b/packages/CrashRecovery/services/java/com/android/server/PackageWatchdog.java @@ -39,15 +39,15 @@ import android.text.TextUtils; import android.util.ArrayMap; import android.util.ArraySet; import android.util.AtomicFile; +import android.util.LongArrayQueue; import android.util.Slog; import android.util.Xml; -import android.utils.BackgroundThread; -import android.utils.LongArrayQueue; -import android.utils.XmlUtils; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; +import com.android.internal.os.BackgroundThread; import com.android.internal.util.IndentingPrintWriter; +import com.android.internal.util.XmlUtils; import com.android.modules.utils.TypedXmlPullParser; import com.android.modules.utils.TypedXmlSerializer; @@ -137,17 +137,6 @@ public class PackageWatchdog { static final int DEFAULT_BOOT_LOOP_TRIGGER_COUNT = 5; static final long DEFAULT_BOOT_LOOP_TRIGGER_WINDOW_MS = TimeUnit.MINUTES.toMillis(10); - // Boot loop at which packageWatchdog starts first mitigation - private static final String BOOT_LOOP_THRESHOLD = - "persist.device_config.configuration.boot_loop_threshold"; - @VisibleForTesting - static final int DEFAULT_BOOT_LOOP_THRESHOLD = 15; - // Once boot_loop_threshold is surpassed next mitigation would be triggered after - // specified number of reboots. - private static final String BOOT_LOOP_MITIGATION_INCREMENT = - "persist.device_config.configuration..boot_loop_mitigation_increment"; - @VisibleForTesting - static final int DEFAULT_BOOT_LOOP_MITIGATION_INCREMENT = 2; // Threshold level at which or above user might experience significant disruption. private static final String MAJOR_USER_IMPACT_LEVEL_THRESHOLD = @@ -253,15 +242,8 @@ public class PackageWatchdog { mConnectivityModuleConnector = connectivityModuleConnector; mSystemClock = clock; mNumberOfNativeCrashPollsRemaining = NUMBER_OF_NATIVE_CRASH_POLLS; - if (Flags.recoverabilityDetection()) { - mBootThreshold = new BootThreshold(DEFAULT_BOOT_LOOP_TRIGGER_COUNT, - DEFAULT_BOOT_LOOP_TRIGGER_WINDOW_MS, - SystemProperties.getInt(BOOT_LOOP_MITIGATION_INCREMENT, - DEFAULT_BOOT_LOOP_MITIGATION_INCREMENT)); - } else { - mBootThreshold = new BootThreshold(DEFAULT_BOOT_LOOP_TRIGGER_COUNT, - DEFAULT_BOOT_LOOP_TRIGGER_WINDOW_MS); - } + mBootThreshold = new BootThreshold(DEFAULT_BOOT_LOOP_TRIGGER_COUNT, + DEFAULT_BOOT_LOOP_TRIGGER_WINDOW_MS); loadFromFile(); sPackageWatchdog = this; @@ -526,10 +508,16 @@ public class PackageWatchdog { /** * Called when the system server boots. If the system server is detected to be in a boot loop, * query each observer and perform the mitigation action with the lowest user impact. + * + * Note: PackageWatchdog considers system_server restart loop as bootloop. Full reboots + * are not counted in bootloop. */ @SuppressWarnings("GuardedBy") public void noteBoot() { synchronized (mLock) { + // if boot count has reached threshold, start mitigation. + // We wait until threshold number of restarts only for the first time. Perform + // mitigations for every restart after that. boolean mitigate = mBootThreshold.incrementAndTest(); if (mitigate) { if (!Flags.recoverabilityDetection()) { @@ -557,17 +545,13 @@ public class PackageWatchdog { } if (currentObserverToNotify != null) { if (Flags.recoverabilityDetection()) { - if (currentObserverImpact < getUserImpactLevelLimit() - || (currentObserverImpact >= getUserImpactLevelLimit() - && mBootThreshold.getCount() >= getBootLoopThreshold())) { - int currentObserverMitigationCount = - currentObserverInternal.getBootMitigationCount() + 1; - currentObserverInternal.setBootMitigationCount( - currentObserverMitigationCount); - saveAllObserversBootMitigationCountToMetadata(METADATA_FILE); - currentObserverToNotify.executeBootLoopMitigation( - currentObserverMitigationCount); - } + int currentObserverMitigationCount = + currentObserverInternal.getBootMitigationCount() + 1; + currentObserverInternal.setBootMitigationCount( + currentObserverMitigationCount); + saveAllObserversBootMitigationCountToMetadata(METADATA_FILE); + currentObserverToNotify.executeBootLoopMitigation( + currentObserverMitigationCount); } else { mBootThreshold.setMitigationCount(mitigationCount); mBootThreshold.saveMitigationCountToMetadata(); @@ -647,11 +631,6 @@ public class PackageWatchdog { DEFAULT_MAJOR_USER_IMPACT_LEVEL_THRESHOLD); } - private int getBootLoopThreshold() { - return SystemProperties.getInt(BOOT_LOOP_THRESHOLD, - DEFAULT_BOOT_LOOP_THRESHOLD); - } - /** Possible severity values of the user impact of a {@link PackageHealthObserver#execute}. */ @Retention(SOURCE) @IntDef(value = {PackageHealthObserverImpact.USER_IMPACT_LEVEL_0, @@ -1827,16 +1806,10 @@ public class PackageWatchdog { private final int mBootTriggerCount; private final long mTriggerWindow; - private final int mBootMitigationIncrement; BootThreshold(int bootTriggerCount, long triggerWindow) { - this(bootTriggerCount, triggerWindow, /*bootMitigationIncrement=*/ 1); - } - - BootThreshold(int bootTriggerCount, long triggerWindow, int bootMitigationIncrement) { this.mBootTriggerCount = bootTriggerCount; this.mTriggerWindow = triggerWindow; - this.mBootMitigationIncrement = bootMitigationIncrement; } public void reset() { @@ -1915,6 +1888,7 @@ public class PackageWatchdog { } else { readMitigationCountFromMetadataIfNecessary(); } + final long now = mSystemClock.uptimeMillis(); if (now - getStart() < 0) { Slog.e(TAG, "Window was less than zero. Resetting start to current time."); @@ -1939,20 +1913,32 @@ public class PackageWatchdog { setCount(count); EventLogTags.writeRescueNote(Process.ROOT_UID, count, window); if (Flags.recoverabilityDetection()) { - boolean mitigate = (count >= mBootTriggerCount) - && (count - mBootTriggerCount) % mBootMitigationIncrement == 0; - return mitigate; + // After a reboot (e.g. by WARM_REBOOT or mainline rollback) we apply + // mitigations without waiting for DEFAULT_BOOT_LOOP_TRIGGER_COUNT. + return (count >= mBootTriggerCount) + || (performedMitigationsDuringWindow() && count > 1); } return count >= mBootTriggerCount; } } @GuardedBy("mLock") + private boolean performedMitigationsDuringWindow() { + for (ObserverInternal observerInternal: mAllObservers.values()) { + if (observerInternal.getBootMitigationCount() > 0) { + return true; + } + } + return false; + } + + @GuardedBy("mLock") private void resetAllObserversBootMitigationCount() { for (int i = 0; i < mAllObservers.size(); i++) { final ObserverInternal observer = mAllObservers.valueAt(i); observer.setBootMitigationCount(0); } + saveAllObserversBootMitigationCountToMetadata(METADATA_FILE); } @GuardedBy("mLock") diff --git a/packages/CrashRecovery/services/java/com/android/server/RescueParty.java b/packages/CrashRecovery/services/java/com/android/server/RescueParty.java index 7093ba42f40d..271d552fc574 100644 --- a/packages/CrashRecovery/services/java/com/android/server/RescueParty.java +++ b/packages/CrashRecovery/services/java/com/android/server/RescueParty.java @@ -31,6 +31,7 @@ import android.content.pm.VersionedPackage; import android.crashrecovery.flags.Flags; import android.os.Build; import android.os.Environment; +import android.os.FileUtils; import android.os.PowerManager; import android.os.RecoverySystem; import android.os.SystemClock; @@ -43,11 +44,10 @@ import android.text.TextUtils; import android.util.ArraySet; import android.util.Log; import android.util.Slog; -import android.utils.ArrayUtils; -import android.utils.FileUtils; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; +import com.android.internal.util.ArrayUtils; import com.android.server.PackageWatchdog.FailureReasons; import com.android.server.PackageWatchdog.PackageHealthObserver; import com.android.server.PackageWatchdog.PackageHealthObserverImpact; @@ -139,7 +139,7 @@ public class RescueParty { static final String NAMESPACE_TO_PACKAGE_MAPPING_FLAG = "namespace_to_package_mapping"; @VisibleForTesting - static final long DEFAULT_FACTORY_RESET_THROTTLE_DURATION_MIN = 10; + static final long DEFAULT_FACTORY_RESET_THROTTLE_DURATION_MIN = 1440; private static final String NAME = "rescue-party-observer"; diff --git a/packages/CrashRecovery/services/java/com/android/utils/ArrayUtils.java b/packages/CrashRecovery/services/java/com/android/utils/ArrayUtils.java deleted file mode 100644 index fa4d6afc03d3..000000000000 --- a/packages/CrashRecovery/services/java/com/android/utils/ArrayUtils.java +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright (C) 2024 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.utils; - -import android.annotation.NonNull; -import android.annotation.Nullable; - -import java.io.File; -import java.util.List; -import java.util.Objects; - -/** - * Copied over from frameworks/base/core/java/com/android/internal/util/ArrayUtils.java - * - * @hide - */ -public class ArrayUtils { - private ArrayUtils() { /* cannot be instantiated */ } - public static final File[] EMPTY_FILE = new File[0]; - - - /** - * Return first index of {@code value} in {@code array}, or {@code -1} if - * not found. - */ - public static <T> int indexOf(@Nullable T[] array, T value) { - if (array == null) return -1; - for (int i = 0; i < array.length; i++) { - if (Objects.equals(array[i], value)) return i; - } - return -1; - } - - /** @hide */ - public static @NonNull File[] defeatNullable(@Nullable File[] val) { - return (val != null) ? val : EMPTY_FILE; - } - - /** - * Checks if given array is null or has zero elements. - */ - public static boolean isEmpty(@Nullable int[] array) { - return array == null || array.length == 0; - } - - /** - * True if the byte array is null or has length 0. - */ - public static boolean isEmpty(@Nullable byte[] array) { - return array == null || array.length == 0; - } - - /** - * Converts from List of bytes to byte array - * @param list - * @return byte[] - */ - public static byte[] toPrimitive(List<byte[]> list) { - if (list.size() == 0) { - return new byte[0]; - } - int byteLen = list.get(0).length; - byte[] array = new byte[list.size() * byteLen]; - for (int i = 0; i < list.size(); i++) { - for (int j = 0; j < list.get(i).length; j++) { - array[i * byteLen + j] = list.get(i)[j]; - } - } - return array; - } - - /** - * Adds value to given array if not already present, providing set-like - * behavior. - */ - public static @NonNull int[] appendInt(@Nullable int[] cur, int val) { - return appendInt(cur, val, false); - } - - /** - * Adds value to given array. - */ - public static @NonNull int[] appendInt(@Nullable int[] cur, int val, - boolean allowDuplicates) { - if (cur == null) { - return new int[] { val }; - } - final int n = cur.length; - if (!allowDuplicates) { - for (int i = 0; i < n; i++) { - if (cur[i] == val) { - return cur; - } - } - } - int[] ret = new int[n + 1]; - System.arraycopy(cur, 0, ret, 0, n); - ret[n] = val; - return ret; - } -} diff --git a/packages/CrashRecovery/services/java/com/android/utils/BackgroundThread.java b/packages/CrashRecovery/services/java/com/android/utils/BackgroundThread.java deleted file mode 100644 index afcf6895fd0d..000000000000 --- a/packages/CrashRecovery/services/java/com/android/utils/BackgroundThread.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * * Copyright (C) 2024 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.utils; - -import android.annotation.NonNull; -import android.os.Handler; -import android.os.HandlerThread; - -import com.android.internal.annotations.GuardedBy; - -import java.util.concurrent.Executor; - -/** - * Thread for asynchronous event processing. This thread is configured as - * {@link android.os.Process#THREAD_PRIORITY_BACKGROUND}, which means fewer CPU - * resources will be dedicated to it, and it will "have less chance of impacting - * the responsiveness of the user interface." - * <p> - * This thread is best suited for tasks that the user is not actively waiting - * for, or for tasks that the user expects to be executed eventually. - * - * @see com.android.internal.os.BackgroundThread - * - * TODO: b/326916057 depend on modules-utils-backgroundthread instead - * @hide - */ -public final class BackgroundThread extends HandlerThread { - private static final Object sLock = new Object(); - - @GuardedBy("sLock") - private static BackgroundThread sInstance; - @GuardedBy("sLock") - private static Handler sHandler; - @GuardedBy("sLock") - private static HandlerExecutor sHandlerExecutor; - - private BackgroundThread() { - super(BackgroundThread.class.getName(), android.os.Process.THREAD_PRIORITY_BACKGROUND); - } - - @GuardedBy("sLock") - private static void ensureThreadLocked() { - if (sInstance == null) { - sInstance = new BackgroundThread(); - sInstance.start(); - sHandler = new Handler(sInstance.getLooper()); - sHandlerExecutor = new HandlerExecutor(sHandler); - } - } - - /** - * Get the singleton instance of this class. - * - * @return the singleton instance of this class - */ - @NonNull - public static BackgroundThread get() { - synchronized (sLock) { - ensureThreadLocked(); - return sInstance; - } - } - - /** - * Get the singleton {@link Handler} for this class. - * - * @return the singleton {@link Handler} for this class. - */ - @NonNull - public static Handler getHandler() { - synchronized (sLock) { - ensureThreadLocked(); - return sHandler; - } - } - - /** - * Get the singleton {@link Executor} for this class. - * - * @return the singleton {@link Executor} for this class. - */ - @NonNull - public static Executor getExecutor() { - synchronized (sLock) { - ensureThreadLocked(); - return sHandlerExecutor; - } - } -} diff --git a/packages/CrashRecovery/services/java/com/android/utils/FileUtils.java b/packages/CrashRecovery/services/java/com/android/utils/FileUtils.java deleted file mode 100644 index e4923bfc4ecb..000000000000 --- a/packages/CrashRecovery/services/java/com/android/utils/FileUtils.java +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Copyright (C) 2024 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.utils; - -import android.annotation.NonNull; -import android.annotation.Nullable; - -import java.io.BufferedInputStream; -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; - -/** - * Bits and pieces copied from hidden API of android.os.FileUtils. - * - * @hide - */ -public class FileUtils { - /** - * Read a text file into a String, optionally limiting the length. - * - * @param file to read (will not seek, so things like /proc files are OK) - * @param max length (positive for head, negative of tail, 0 for no limit) - * @param ellipsis to add of the file was truncated (can be null) - * @return the contents of the file, possibly truncated - * @throws IOException if something goes wrong reading the file - * @hide - */ - public static @Nullable String readTextFile(@Nullable File file, @Nullable int max, - @Nullable String ellipsis) throws IOException { - InputStream input = new FileInputStream(file); - // wrapping a BufferedInputStream around it because when reading /proc with unbuffered - // input stream, bytes read not equal to buffer size is not necessarily the correct - // indication for EOF; but it is true for BufferedInputStream due to its implementation. - BufferedInputStream bis = new BufferedInputStream(input); - try { - long size = file.length(); - if (max > 0 || (size > 0 && max == 0)) { // "head" mode: read the first N bytes - if (size > 0 && (max == 0 || size < max)) max = (int) size; - byte[] data = new byte[max + 1]; - int length = bis.read(data); - if (length <= 0) return ""; - if (length <= max) return new String(data, 0, length); - if (ellipsis == null) return new String(data, 0, max); - return new String(data, 0, max) + ellipsis; - } else if (max < 0) { // "tail" mode: keep the last N - int len; - boolean rolled = false; - byte[] last = null; - byte[] data = null; - do { - if (last != null) rolled = true; - byte[] tmp = last; - last = data; - data = tmp; - if (data == null) data = new byte[-max]; - len = bis.read(data); - } while (len == data.length); - - if (last == null && len <= 0) return ""; - if (last == null) return new String(data, 0, len); - if (len > 0) { - rolled = true; - System.arraycopy(last, len, last, 0, last.length - len); - System.arraycopy(data, 0, last, last.length - len, len); - } - if (ellipsis == null || !rolled) return new String(last); - return ellipsis + new String(last); - } else { // "cat" mode: size unknown, read it all in streaming fashion - ByteArrayOutputStream contents = new ByteArrayOutputStream(); - int len; - byte[] data = new byte[1024]; - do { - len = bis.read(data); - if (len > 0) contents.write(data, 0, len); - } while (len == data.length); - return contents.toString(); - } - } finally { - bis.close(); - input.close(); - } - } - - /** - * Perform an fsync on the given FileOutputStream. The stream at this - * point must be flushed but not yet closed. - * - * @hide - */ - public static boolean sync(FileOutputStream stream) { - try { - if (stream != null) { - stream.getFD().sync(); - } - return true; - } catch (IOException e) { - } - return false; - } - - /** - * List the files in the directory or return empty file. - * - * @hide - */ - public static @NonNull File[] listFilesOrEmpty(@Nullable File dir) { - return (dir != null) ? ArrayUtils.defeatNullable(dir.listFiles()) - : ArrayUtils.EMPTY_FILE; - } -} diff --git a/packages/CrashRecovery/services/java/com/android/utils/HandlerExecutor.java b/packages/CrashRecovery/services/java/com/android/utils/HandlerExecutor.java deleted file mode 100644 index fdb15e2333d5..000000000000 --- a/packages/CrashRecovery/services/java/com/android/utils/HandlerExecutor.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (C) 2024 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.utils; - -import android.annotation.NonNull; -import android.os.Handler; - -import java.util.Objects; -import java.util.concurrent.Executor; -import java.util.concurrent.RejectedExecutionException; - -/** - * An adapter {@link Executor} that posts all executed tasks onto the given - * {@link Handler}. - * - * TODO: b/326916057 depend on modules-utils-backgroundthread instead - * @hide - */ -public class HandlerExecutor implements Executor { - private final Handler mHandler; - - public HandlerExecutor(@NonNull Handler handler) { - mHandler = Objects.requireNonNull(handler); - } - - @Override - public void execute(Runnable command) { - if (!mHandler.post(command)) { - throw new RejectedExecutionException(mHandler + " is shutting down"); - } - } -} diff --git a/packages/CrashRecovery/services/java/com/android/utils/LongArrayQueue.java b/packages/CrashRecovery/services/java/com/android/utils/LongArrayQueue.java deleted file mode 100644 index 5cdc2536129a..000000000000 --- a/packages/CrashRecovery/services/java/com/android/utils/LongArrayQueue.java +++ /dev/null @@ -1,188 +0,0 @@ -/* - * Copyright (C) 2024 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.utils; - -import libcore.util.EmptyArray; - -import java.util.NoSuchElementException; - -/** - * Copied from frameworks/base/core/java/android/util/LongArrayQueue.java - * - * @hide - */ -public class LongArrayQueue { - - private long[] mValues; - private int mSize; - private int mHead; - private int mTail; - - private long[] newUnpaddedLongArray(int num) { - return new long[num]; - } - /** - * Initializes a queue with the given starting capacity. - * - * @param initialCapacity the capacity. - */ - public LongArrayQueue(int initialCapacity) { - if (initialCapacity == 0) { - mValues = EmptyArray.LONG; - } else { - mValues = newUnpaddedLongArray(initialCapacity); - } - mSize = 0; - mHead = mTail = 0; - } - - /** - * Initializes a queue with default starting capacity. - */ - public LongArrayQueue() { - this(16); - } - - /** @hide */ - public static int growSize(int currentSize) { - return currentSize <= 4 ? 8 : currentSize * 2; - } - - private void grow() { - if (mSize < mValues.length) { - throw new IllegalStateException("Queue not full yet!"); - } - final int newSize = growSize(mSize); - final long[] newArray = newUnpaddedLongArray(newSize); - final int r = mValues.length - mHead; // Number of elements on and to the right of head. - System.arraycopy(mValues, mHead, newArray, 0, r); - System.arraycopy(mValues, 0, newArray, r, mHead); - mValues = newArray; - mHead = 0; - mTail = mSize; - } - - /** - * Returns the number of elements in the queue. - */ - public int size() { - return mSize; - } - - /** - * Removes all elements from this queue. - */ - public void clear() { - mSize = 0; - mHead = mTail = 0; - } - - /** - * Adds a value to the tail of the queue. - * - * @param value the value to be added. - */ - public void addLast(long value) { - if (mSize == mValues.length) { - grow(); - } - mValues[mTail] = value; - mTail = (mTail + 1) % mValues.length; - mSize++; - } - - /** - * Removes an element from the head of the queue. - * - * @return the element at the head of the queue. - * @throws NoSuchElementException if the queue is empty. - */ - public long removeFirst() { - if (mSize == 0) { - throw new NoSuchElementException("Queue is empty!"); - } - final long ret = mValues[mHead]; - mHead = (mHead + 1) % mValues.length; - mSize--; - return ret; - } - - /** - * Returns the element at the given position from the head of the queue, where 0 represents the - * head of the queue. - * - * @param position the position from the head of the queue. - * @return the element found at the given position. - * @throws IndexOutOfBoundsException if {@code position} < {@code 0} or - * {@code position} >= {@link #size()} - */ - public long get(int position) { - if (position < 0 || position >= mSize) { - throw new IndexOutOfBoundsException("Index " + position - + " not valid for a queue of size " + mSize); - } - final int index = (mHead + position) % mValues.length; - return mValues[index]; - } - - /** - * Returns the element at the head of the queue, without removing it. - * - * @return the element at the head of the queue. - * @throws NoSuchElementException if the queue is empty - */ - public long peekFirst() { - if (mSize == 0) { - throw new NoSuchElementException("Queue is empty!"); - } - return mValues[mHead]; - } - - /** - * Returns the element at the tail of the queue. - * - * @return the element at the tail of the queue. - * @throws NoSuchElementException if the queue is empty. - */ - public long peekLast() { - if (mSize == 0) { - throw new NoSuchElementException("Queue is empty!"); - } - final int index = (mTail == 0) ? mValues.length - 1 : mTail - 1; - return mValues[index]; - } - - /** - * {@inheritDoc} - */ - @Override - public String toString() { - if (mSize <= 0) { - return "{}"; - } - - final StringBuilder buffer = new StringBuilder(mSize * 64); - buffer.append('{'); - buffer.append(get(0)); - for (int i = 1; i < mSize; i++) { - buffer.append(", "); - buffer.append(get(i)); - } - buffer.append('}'); - return buffer.toString(); - } -} diff --git a/packages/CrashRecovery/services/java/com/android/utils/XmlUtils.java b/packages/CrashRecovery/services/java/com/android/utils/XmlUtils.java deleted file mode 100644 index dbbef61f6777..000000000000 --- a/packages/CrashRecovery/services/java/com/android/utils/XmlUtils.java +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Copyright (C) 2024 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.utils; - -import android.annotation.NonNull; -import android.system.ErrnoException; -import android.system.Os; - -import com.android.modules.utils.TypedXmlPullParser; - -import libcore.util.XmlObjectFactory; - -import org.xmlpull.v1.XmlPullParser; -import org.xmlpull.v1.XmlPullParserException; - -import java.io.BufferedInputStream; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; - -/** - * Copied over partly from frameworks/base/core/java/com/android/internal/util/XmlUtils.java - * - * @hide - */ -public class XmlUtils { - - private static final String STRING_ARRAY_SEPARATOR = ":"; - - /** @hide */ - public static final void beginDocument(XmlPullParser parser, String firstElementName) - throws XmlPullParserException, IOException { - int type; - while ((type = parser.next()) != parser.START_TAG - && type != parser.END_DOCUMENT) { - // Do nothing - } - - if (type != parser.START_TAG) { - throw new XmlPullParserException("No start tag found"); - } - - if (!parser.getName().equals(firstElementName)) { - throw new XmlPullParserException("Unexpected start tag: found " + parser.getName() - + ", expected " + firstElementName); - } - } - - /** @hide */ - public static boolean nextElementWithin(XmlPullParser parser, int outerDepth) - throws IOException, XmlPullParserException { - for (;;) { - int type = parser.next(); - if (type == XmlPullParser.END_DOCUMENT - || (type == XmlPullParser.END_TAG && parser.getDepth() == outerDepth)) { - return false; - } - if (type == XmlPullParser.START_TAG - && parser.getDepth() == outerDepth + 1) { - return true; - } - } - } - - private static XmlPullParser newPullParser() { - try { - XmlPullParser parser = XmlObjectFactory.newXmlPullParser(); - parser.setFeature(XmlPullParser.FEATURE_PROCESS_DOCDECL, true); - parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true); - return parser; - } catch (XmlPullParserException e) { - throw new AssertionError(); - } - } - - /** @hide */ - public static @NonNull TypedXmlPullParser resolvePullParser(@NonNull InputStream in) - throws IOException { - final byte[] magic = new byte[4]; - if (in instanceof FileInputStream) { - try { - Os.pread(((FileInputStream) in).getFD(), magic, 0, magic.length, 0); - } catch (ErrnoException e) { - throw e.rethrowAsIOException(); - } - } else { - if (!in.markSupported()) { - in = new BufferedInputStream(in); - } - in.mark(8); - in.read(magic); - in.reset(); - } - - final TypedXmlPullParser xml; - xml = (TypedXmlPullParser) newPullParser(); - try { - xml.setInput(in, "UTF_8"); - } catch (XmlPullParserException e) { - throw new IOException(e); - } - return xml; - } -} diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java index e876527fc513..4dfa71b7ad36 100644 --- a/services/core/java/com/android/server/am/ProcessList.java +++ b/services/core/java/com/android/server/am/ProcessList.java @@ -350,6 +350,7 @@ public final class ProcessList { // LMK_UPDATE_PROPS // LMK_KILL_OCCURRED // LMK_START_MONITORING + // LMK_BOOT_COMPLETED static final byte LMK_TARGET = 0; static final byte LMK_PROCPRIO = 1; static final byte LMK_PROCREMOVE = 2; @@ -360,6 +361,7 @@ public final class ProcessList { static final byte LMK_UPDATE_PROPS = 7; static final byte LMK_KILL_OCCURRED = 8; // Msg to subscribed clients on kill occurred event static final byte LMK_START_MONITORING = 9; // Start monitoring if delayed earlier + static final byte LMK_BOOT_COMPLETED = 10; // Low Memory Killer Daemon command codes. // These must be kept in sync with async_event_type definitions in lmkd.h diff --git a/services/core/java/com/android/server/graphics/fonts/UpdatableFontDir.java b/services/core/java/com/android/server/graphics/fonts/UpdatableFontDir.java index 0f40ca082663..2783fefa5b71 100644 --- a/services/core/java/com/android/server/graphics/fonts/UpdatableFontDir.java +++ b/services/core/java/com/android/server/graphics/fonts/UpdatableFontDir.java @@ -198,8 +198,7 @@ final class UpdatableFontDir { File signatureFile = new File(dir, FONT_SIGNATURE_FILE); if (!signatureFile.exists()) { Slog.i(TAG, "The signature file is missing."); - FileUtils.deleteContentsAndDir(dir); - continue; + return; } byte[] signature; try { @@ -224,10 +223,36 @@ final class UpdatableFontDir { FontFileInfo fontFileInfo = validateFontFile(fontFile, signature); if (fontConfig == null) { - fontConfig = getSystemFontConfig(); + // Use preinstalled font config for checking revision number. + fontConfig = mConfigSupplier.apply(Collections.emptyMap()); } addFileToMapIfSameOrNewer(fontFileInfo, fontConfig, true /* deleteOldFile */); } + + // Treat as error if post script name of font family was not installed. + for (int i = 0; i < config.fontFamilies.size(); ++i) { + FontUpdateRequest.Family family = config.fontFamilies.get(i); + for (int j = 0; j < family.getFonts().size(); ++j) { + FontUpdateRequest.Font font = family.getFonts().get(j); + if (mFontFileInfoMap.containsKey(font.getPostScriptName())) { + continue; + } + + if (fontConfig == null) { + fontConfig = mConfigSupplier.apply(Collections.emptyMap()); + } + + if (getFontByPostScriptName(font.getPostScriptName(), fontConfig) != null) { + continue; + } + + Slog.e(TAG, "Unknown font that has PostScript name " + + font.getPostScriptName() + " is requested in FontFamily " + + family.getName()); + return; + } + } + success = true; } catch (Throwable t) { // If something happened during loading system fonts, clear all contents in finally @@ -239,6 +264,7 @@ final class UpdatableFontDir { mFontFileInfoMap.clear(); mLastModifiedMillis = 0; FileUtils.deleteContents(mFilesDir); + mConfigFile.delete(); } } } @@ -487,8 +513,7 @@ final class UpdatableFontDir { return shouldAddToMap; } - private long getPreinstalledFontRevision(FontFileInfo info, FontConfig fontConfig) { - String psName = info.getPostScriptName(); + private FontConfig.Font getFontByPostScriptName(String psName, FontConfig fontConfig) { FontConfig.Font targetFont = null; for (int i = 0; i < fontConfig.getFontFamilies().size(); i++) { FontConfig.FontFamily family = fontConfig.getFontFamilies().get(i); @@ -513,6 +538,13 @@ final class UpdatableFontDir { } } } + return targetFont; + } + + private long getPreinstalledFontRevision(FontFileInfo info, FontConfig fontConfig) { + String psName = info.getPostScriptName(); + FontConfig.Font targetFont = getFontByPostScriptName(psName, fontConfig); + if (targetFont == null) { return -1; } diff --git a/services/tests/mockingservicestests/src/com/android/server/RescuePartyTest.java b/services/tests/mockingservicestests/src/com/android/server/RescuePartyTest.java index 682569f1d9ab..697548cbe2b4 100644 --- a/services/tests/mockingservicestests/src/com/android/server/RescuePartyTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/RescuePartyTest.java @@ -1111,16 +1111,9 @@ public class RescuePartyTest { // mock properties in BootThreshold try { - if (Flags.recoverabilityDetection()) { - mSpyBootThreshold = spy(watchdog.new BootThreshold( - PackageWatchdog.DEFAULT_BOOT_LOOP_TRIGGER_COUNT, - PackageWatchdog.DEFAULT_BOOT_LOOP_TRIGGER_WINDOW_MS, - PackageWatchdog.DEFAULT_BOOT_LOOP_MITIGATION_INCREMENT)); - } else { - mSpyBootThreshold = spy(watchdog.new BootThreshold( + mSpyBootThreshold = spy(watchdog.new BootThreshold( PackageWatchdog.DEFAULT_BOOT_LOOP_TRIGGER_COUNT, PackageWatchdog.DEFAULT_BOOT_LOOP_TRIGGER_WINDOW_MS)); - } mCrashRecoveryPropertiesMap = new HashMap<>(); doAnswer((Answer<Integer>) invocationOnMock -> { diff --git a/services/tests/servicestests/src/com/android/server/graphics/fonts/UpdatableFontDirTest.java b/services/tests/servicestests/src/com/android/server/graphics/fonts/UpdatableFontDirTest.java index 3de167e72ba0..5fb15e9c4df0 100644 --- a/services/tests/servicestests/src/com/android/server/graphics/fonts/UpdatableFontDirTest.java +++ b/services/tests/servicestests/src/com/android/server/graphics/fonts/UpdatableFontDirTest.java @@ -1001,6 +1001,563 @@ public final class UpdatableFontDirTest { assertThat(mUpdatableFontFilesDir.list()).hasLength(0); } + private UpdatableFontDir createNewUpdateDir() { + UpdatableFontDir dir = new UpdatableFontDir( + mUpdatableFontFilesDir, mParser, mFakeFsverityUtil, + mConfigFile, mCurrentTimeSupplier, mConfigSupplier); + dir.loadFontFileMap(); + return dir; + } + + private UpdatableFontDir installTestFontFamilies(int version) { + UpdatableFontDir dir = createNewUpdateDir(); + try { + dir.update(Arrays.asList( + newFontUpdateRequest("foo.ttf," + version + ",foo", GOOD_SIGNATURE), + newFontUpdateRequest("bar.ttf," + version + ",bar", GOOD_SIGNATURE), + newAddFontFamilyRequest("<family name='foobar'>" + + " <font>foo.ttf</font>" + + " <font>bar.ttf</font>" + + "</family>"))); + } catch (Exception e) { + throw new RuntimeException(e); + } + return dir; + } + + private UpdatableFontDir installTestFontFile(int numFonts, int version) { + UpdatableFontDir dir = createNewUpdateDir(); + List<FontUpdateRequest> requests = new ArrayList<>(); + if (numFonts <= 0 || numFonts > 3) { + throw new IllegalArgumentException("numFont must be 1, 2 or 3"); + } + try { + requests.add(newFontUpdateRequest("foo.ttf," + version + ",foo", GOOD_SIGNATURE)); + if (numFonts >= 2) { + requests.add(newFontUpdateRequest("bar.ttf," + version + ",bar", GOOD_SIGNATURE)); + } + if (numFonts == 3) { + requests.add(newFontUpdateRequest("baz.ttf," + version + ",baz", GOOD_SIGNATURE)); + } + dir.update(requests); + } catch (Exception e) { + throw new RuntimeException(e); + } + return dir; + } + + private List<File> collectSignatureFiles() { + return Arrays.stream(mUpdatableFontFilesDir.listFiles()) + .map((file) -> file.listFiles((unused, s) -> s.endsWith(".fsv_sig"))) + .flatMap(Arrays::stream) + .toList(); + } + + private List<File> collectFontFiles() { + return Arrays.stream(mUpdatableFontFilesDir.listFiles()) + .map((file) -> file.listFiles((unused, s) -> s.endsWith(".ttf"))) + .flatMap(Arrays::stream) + .toList(); + } + + private void removeAll(List<File> files) { + files.forEach((File file) -> { + if (file.isDirectory()) { + removeAll(List.of(file.listFiles())); + } else { + assertThat(file.delete()).isTrue(); + } + }); + } + + private void assertTestFontFamilyInstalled(UpdatableFontDir dir, int version) { + try { + assertNamedFamilyExists(dir.getSystemFontConfig(), "foobar"); + assertThat(dir.getFontFamilyMap()).containsKey("foobar"); + assertThat(dir.getFontFamilyMap().get("foobar").getFamilies().size()).isEqualTo(1); + FontConfig.FontFamily foobar = dir.getFontFamilyMap().get("foobar").getFamilies() + .get(0); + assertThat(foobar.getFontList()).hasSize(2); + assertThat(foobar.getFontList().get(0).getFile()) + .isEqualTo(dir.getPostScriptMap().get("foo")); + assertThat(mParser.getRevision(dir.getPostScriptMap().get("foo"))).isEqualTo(version); + assertThat(foobar.getFontList().get(1).getFile()) + .isEqualTo(dir.getPostScriptMap().get("bar")); + assertThat(mParser.getRevision(dir.getPostScriptMap().get("bar"))).isEqualTo(version); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + private void assertTestFontInstalled(UpdatableFontDir dir, int version) { + try { + assertThat(dir.getPostScriptMap().containsKey("foo")).isTrue(); + assertThat(mParser.getRevision(dir.getPostScriptMap().get("foo"))).isEqualTo(version); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + @Test + public void signatureMissingCase_fontFamilyInstalled_fontFamilyInstallLater() { + // Install font families, foo.ttf, bar.ttf. + installTestFontFamilies(1 /* version */); + + // Delete one signature file + assertThat(collectSignatureFiles().get(0).delete()).isTrue(); + + // New instance of UpdatableFontDir, this emulate a device reboot. + UpdatableFontDir dir = installTestFontFamilies(2 /* version */); + + // Make sure the font installation succeeds. + assertTestFontFamilyInstalled(dir, 2 /* version */); + + // Make sure after the reboot, the configuration remains. + UpdatableFontDir nextDir = createNewUpdateDir(); + assertTestFontFamilyInstalled(nextDir, 2 /* version */); + } + + @Test + public void signatureMissingCase_fontFamilyInstalled_fontInstallLater() { + // Install font families, foo.ttf, bar.ttf. + installTestFontFamilies(1); + + // Delete one signature file + assertThat(collectSignatureFiles().get(0).delete()).isTrue(); + + // New instance of UpdatableFontDir, this emulate a device reboot. + UpdatableFontDir dir = installTestFontFile(1 /* numFonts */, 2 /* version */); + + // Make sure the font installation succeeds. + assertTestFontInstalled(dir, 2 /* version */); + + // Make sure after the reboot, the configuration remains. + UpdatableFontDir nextDir = createNewUpdateDir(); + assertTestFontInstalled(nextDir, 2 /* version */); + } + + @Test + public void signatureMissingCase_fontFileInstalled_fontFamilyInstallLater() { + // Install font file, foo.ttf and bar.ttf + installTestFontFile(2 /* numFonts */, 1 /* version */); + + // Delete one signature file + assertThat(collectSignatureFiles().get(0).delete()).isTrue(); + + // New instance of UpdatableFontDir, this emulate a device reboot. + UpdatableFontDir dir = installTestFontFamilies(2 /* version */); + + // Make sure the font installation succeeds. + assertTestFontFamilyInstalled(dir, 2 /* version */); + + // Make sure after the reboot, the configuration remains. + UpdatableFontDir nextDir = createNewUpdateDir(); + assertTestFontFamilyInstalled(nextDir, 2 /* version */); + } + + @Test + public void signatureMissingCase_fontFileInstalled_fontFileInstallLater() { + // Install font file, foo.ttf and bar.ttf + installTestFontFile(2 /* numFonts */, 1 /* version */); + + // Delete one signature file + assertThat(collectSignatureFiles().get(0).delete()).isTrue(); + + // New instance of UpdatableFontDir, this emulate a device reboot. + UpdatableFontDir dir = installTestFontFile(2 /* numFonts */, 2 /* version */); + + // Make sure the font installation succeeds. + assertTestFontInstalled(dir, 2 /* version */); + + // Make sure after the reboot, the configuration remains. + UpdatableFontDir nextDir = createNewUpdateDir(); + assertTestFontInstalled(nextDir, 2 /* version */); + } + + @Test + public void signatureAllMissingCase_fontFamilyInstalled_fontFamilyInstallLater() { + // Install font families, foo.ttf, bar.ttf. + installTestFontFamilies(1 /* version */); + + // Delete all signature files + removeAll(collectSignatureFiles()); + + // New instance of UpdatableFontDir, this emulate a device reboot. + UpdatableFontDir dir = installTestFontFamilies(2 /* version */); + + // Make sure the font installation succeeds. + assertTestFontFamilyInstalled(dir, 2 /* version */); + + // Make sure after the reboot, the configuration remains. + UpdatableFontDir nextDir = createNewUpdateDir(); + assertTestFontFamilyInstalled(nextDir, 2 /* version */); + } + + @Test + public void signatureAllMissingCase_fontFamilyInstalled_fontInstallLater() { + // Install font families, foo.ttf, bar.ttf. + installTestFontFamilies(1 /* version */); + + // Delete all signature files + removeAll(collectSignatureFiles()); + + // New instance of UpdatableFontDir, this emulate a device reboot. + UpdatableFontDir dir = installTestFontFile(1 /* numFonts */, 2 /* version */); + + // Make sure the font installation succeeds. + assertTestFontInstalled(dir, 2 /* version */); + + // Make sure after the reboot, the configuration remains. + UpdatableFontDir nextDir = createNewUpdateDir(); + assertTestFontInstalled(nextDir, 2 /* version */); + } + + @Test + public void signatureAllMissingCase_fontFileInstalled_fontFamilyInstallLater() { + // Install font file, foo.ttf + installTestFontFile(1 /* numFonts */, 1 /* version */); + + // Delete all signature files + removeAll(collectSignatureFiles()); + + // New instance of UpdatableFontDir, this emulate a device reboot. + UpdatableFontDir dir = installTestFontFamilies(2 /* version */); + + // Make sure the font installation succeeds. + assertTestFontFamilyInstalled(dir, 2 /* version */); + + // Make sure after the reboot, the configuration remains. + UpdatableFontDir nextDir = createNewUpdateDir(); + assertTestFontFamilyInstalled(nextDir, 2 /* version */); + } + + @Test + public void signatureAllMissingCase_fontFileInstalled_fontFileInstallLater() { + // Install font file, foo.ttf + installTestFontFile(1 /* numFonts */, 1 /* version */); + + // Delete all signature files + removeAll(collectSignatureFiles()); + + // New instance of UpdatableFontDir, this emulate a device reboot. + UpdatableFontDir dir = installTestFontFile(1 /* numFonts */, 2 /* version */); + + // Make sure the font installation succeeds. + assertTestFontInstalled(dir, 2 /* version */); + + // Make sure after the reboot, the configuration remains. + UpdatableFontDir nextDir = createNewUpdateDir(); + assertTestFontInstalled(nextDir, 2 /* version */); + } + + @Test + public void fontMissingCase_fontFamilyInstalled_fontFamilyInstallLater() { + // Install font families, foo.ttf, bar.ttf. + installTestFontFamilies(1 /* version */); + + // Delete one font file + assertThat(collectFontFiles().get(0).delete()).isTrue(); + + // New instance of UpdatableFontDir, this emulate a device reboot. + UpdatableFontDir dir = installTestFontFamilies(2 /* version */); + + // Make sure the font installation succeeds. + assertTestFontFamilyInstalled(dir, 2 /* version */); + + // Make sure after the reboot, the configuration remains. + UpdatableFontDir nextDir = createNewUpdateDir(); + assertTestFontFamilyInstalled(nextDir, 2 /* version */); + } + + @Test + public void fontMissingCase_fontFamilyInstalled_fontInstallLater() { + // Install font families, foo.ttf, bar.ttf. + installTestFontFamilies(1); + + // Delete one font file + assertThat(collectFontFiles().get(0).delete()).isTrue(); + + // New instance of UpdatableFontDir, this emulate a device reboot. + UpdatableFontDir dir = installTestFontFile(1 /* numFonts */, 2 /* version */); + + // Make sure the font installation succeeds. + assertTestFontInstalled(dir, 2 /* version */); + + // Make sure after the reboot, the configuration remains. + UpdatableFontDir nextDir = createNewUpdateDir(); + assertTestFontInstalled(nextDir, 2 /* version */); + } + + @Test + public void fontMissingCase_fontFileInstalled_fontFamilyInstallLater() { + // Install font file, foo.ttf and bar.ttf + installTestFontFile(2 /* numFonts */, 1 /* version */); + + // Delete one font file + assertThat(collectFontFiles().get(0).delete()).isTrue(); + + // New instance of UpdatableFontDir, this emulate a device reboot. + UpdatableFontDir dir = installTestFontFamilies(2 /* version */); + + // Make sure the font installation succeeds. + assertTestFontFamilyInstalled(dir, 2 /* version */); + + // Make sure after the reboot, the configuration remains. + UpdatableFontDir nextDir = createNewUpdateDir(); + assertTestFontFamilyInstalled(nextDir, 2 /* version */); + } + + @Test + public void fontMissingCase_fontFileInstalled_fontFileInstallLater() { + // Install font file, foo.ttf and bar.ttf + installTestFontFile(2 /* numFonts */, 1 /* version */); + + // Delete one font file + assertThat(collectFontFiles().get(0).delete()).isTrue(); + + // New instance of UpdatableFontDir, this emulate a device reboot. + UpdatableFontDir dir = installTestFontFile(2 /* numFonts */, 2 /* version */); + + // Make sure the font installation succeeds. + assertTestFontInstalled(dir, 2 /* version */); + + // Make sure after the reboot, the configuration remains. + UpdatableFontDir nextDir = createNewUpdateDir(); + assertTestFontInstalled(nextDir, 2 /* version */); + } + + @Test + public void fontAllMissingCase_fontFamilyInstalled_fontFamilyInstallLater() { + // Install font families, foo.ttf, bar.ttf. + installTestFontFamilies(1 /* version */); + + // Delete all font files + removeAll(collectFontFiles()); + + // New instance of UpdatableFontDir, this emulate a device reboot. + UpdatableFontDir dir = installTestFontFamilies(2 /* version */); + + // Make sure the font installation succeeds. + assertTestFontFamilyInstalled(dir, 2 /* version */); + + // Make sure after the reboot, the configuration remains. + UpdatableFontDir nextDir = createNewUpdateDir(); + assertTestFontFamilyInstalled(nextDir, 2 /* version */); + } + + @Test + public void fontAllMissingCase_fontFamilyInstalled_fontInstallLater() { + // Install font families, foo.ttf, bar.ttf. + installTestFontFamilies(1 /* version */); + + // Delete all font files + removeAll(collectFontFiles()); + + // New instance of UpdatableFontDir, this emulate a device reboot. + UpdatableFontDir dir = installTestFontFile(1 /* numFonts */, 2 /* version */); + + // Make sure the font installation succeeds. + assertTestFontInstalled(dir, 2 /* version */); + + // Make sure after the reboot, the configuration remains. + UpdatableFontDir nextDir = createNewUpdateDir(); + assertTestFontInstalled(nextDir, 2 /* version */); + } + + @Test + public void fontAllMissingCase_fontFileInstalled_fontFamilyInstallLater() { + // Install font file, foo.ttf + installTestFontFile(1 /* numFonts */, 1 /* version */); + + // Delete all font files + removeAll(collectFontFiles()); + + // New instance of UpdatableFontDir, this emulate a device reboot. + UpdatableFontDir dir = installTestFontFamilies(2 /* version */); + + // Make sure the font installation succeeds. + assertTestFontFamilyInstalled(dir, 2 /* version */); + + // Make sure after the reboot, the configuration remains. + UpdatableFontDir nextDir = createNewUpdateDir(); + assertTestFontFamilyInstalled(nextDir, 2 /* version */); + } + + @Test + public void fontAllMissingCase_fontFileInstalled_fontFileInstallLater() { + // Install font file, foo.ttf + installTestFontFile(1 /* numFonts */, 1 /* version */); + + // Delete all font files + removeAll(collectFontFiles()); + + // New instance of UpdatableFontDir, this emulate a device reboot. + UpdatableFontDir dir = installTestFontFile(1 /* numFonts */, 2 /* version */); + + // Make sure the font installation succeeds. + assertTestFontInstalled(dir, 2 /* version */); + + // Make sure after the reboot, the configuration remains. + UpdatableFontDir nextDir = createNewUpdateDir(); + assertTestFontInstalled(nextDir, 2 /* version */); + } + + @Test + public void fontDirAllMissingCase_fontFamilyInstalled_fontFamilyInstallLater() { + // Install font families, foo.ttf, bar.ttf. + installTestFontFamilies(1 /* version */); + + // Delete all font files + removeAll(List.of(mUpdatableFontFilesDir.listFiles())); + + // New instance of UpdatableFontDir, this emulate a device reboot. + UpdatableFontDir dir = installTestFontFamilies(2 /* version */); + + // Make sure the font installation succeeds. + assertTestFontFamilyInstalled(dir, 2 /* version */); + + // Make sure after the reboot, the configuration remains. + UpdatableFontDir nextDir = createNewUpdateDir(); + assertTestFontFamilyInstalled(nextDir, 2 /* version */); + } + + @Test + public void fontDirAllMissingCase_fontFamilyInstalled_fontInstallLater() { + // Install font families, foo.ttf, bar.ttf. + installTestFontFamilies(1 /* version */); + + // Delete all font files + removeAll(List.of(mUpdatableFontFilesDir.listFiles())); + + // New instance of UpdatableFontDir, this emulate a device reboot. + UpdatableFontDir dir = installTestFontFile(1 /* numFonts */, 2 /* version */); + + // Make sure the font installation succeeds. + assertTestFontInstalled(dir, 2 /* version */); + + // Make sure after the reboot, the configuration remains. + UpdatableFontDir nextDir = createNewUpdateDir(); + assertTestFontInstalled(nextDir, 2 /* version */); + } + + @Test + public void fontDirAllMissingCase_fontFileInstalled_fontFamilyInstallLater() { + // Install font file, foo.ttf + installTestFontFile(1 /* numFonts */, 1 /* version */); + + // Delete all font files + removeAll(List.of(mUpdatableFontFilesDir.listFiles())); + + // New instance of UpdatableFontDir, this emulate a device reboot. + UpdatableFontDir dir = installTestFontFamilies(2 /* version */); + + // Make sure the font installation succeeds. + assertTestFontFamilyInstalled(dir, 2 /* version */); + + // Make sure after the reboot, the configuration remains. + UpdatableFontDir nextDir = createNewUpdateDir(); + assertTestFontFamilyInstalled(nextDir, 2 /* version */); + } + + @Test + public void fontDirAllMissingCase_fontFileInstalled_fontFileInstallLater() { + // Install font file, foo.ttf + installTestFontFile(1 /* numFonts */, 1 /* version */); + + // Delete all font files + removeAll(List.of(mUpdatableFontFilesDir.listFiles())); + + // New instance of UpdatableFontDir, this emulate a device reboot. + UpdatableFontDir dir = installTestFontFile(1 /* numFonts */, 2 /* version */); + + // Make sure the font installation succeeds. + assertTestFontInstalled(dir, 2 /* version */); + + // Make sure after the reboot, the configuration remains. + UpdatableFontDir nextDir = createNewUpdateDir(); + assertTestFontInstalled(nextDir, 2 /* version */); + } + + @Test + public void dirContentAllMissingCase_fontFamilyInstalled_fontFamilyInstallLater() { + // Install font families, foo.ttf, bar.ttf. + installTestFontFamilies(1 /* version */); + + // Delete all font files + removeAll(collectFontFiles()); + removeAll(collectSignatureFiles()); + + // New instance of UpdatableFontDir, this emulate a device reboot. + UpdatableFontDir dir = installTestFontFamilies(2 /* version */); + + // Make sure the font installation succeeds. + assertTestFontFamilyInstalled(dir, 2 /* version */); + + // Make sure after the reboot, the configuration remains. + UpdatableFontDir nextDir = createNewUpdateDir(); + assertTestFontFamilyInstalled(nextDir, 2 /* version */); + } + + @Test + public void dirContentAllMissingCase_fontFamilyInstalled_fontInstallLater() { + // Install font families, foo.ttf, bar.ttf. + installTestFontFamilies(1 /* version */); + + // Delete all font files + removeAll(collectFontFiles()); + removeAll(collectSignatureFiles()); + + // New instance of UpdatableFontDir, this emulate a device reboot. + UpdatableFontDir dir = installTestFontFile(1 /* numFonts */, 2 /* version */); + + // Make sure the font installation succeeds. + assertTestFontInstalled(dir, 2 /* version */); + + // Make sure after the reboot, the configuration remains. + UpdatableFontDir nextDir = createNewUpdateDir(); + assertTestFontInstalled(nextDir, 2 /* version */); + } + + @Test + public void dirContentAllMissingCase_fontFileInstalled_fontFamilyInstallLater() { + // Install font file, foo.ttf + installTestFontFile(1 /* numFonts */, 1 /* version */); + + // Delete all font files + removeAll(collectFontFiles()); + removeAll(collectSignatureFiles()); + + // New instance of UpdatableFontDir, this emulate a device reboot. + UpdatableFontDir dir = installTestFontFamilies(2 /* version */); + + // Make sure the font installation succeeds. + assertTestFontFamilyInstalled(dir, 2 /* version */); + + // Make sure after the reboot, the configuration remains. + UpdatableFontDir nextDir = createNewUpdateDir(); + assertTestFontFamilyInstalled(nextDir, 2 /* version */); + } + + @Test + public void dirContentAllMissingCase_fontFileInstalled_fontFileInstallLater() { + // Install font file, foo.ttf + installTestFontFile(1 /* numFonts */, 1 /* version */); + + // Delete all font files + removeAll(collectFontFiles()); + removeAll(collectSignatureFiles()); + + // New instance of UpdatableFontDir, this emulate a device reboot. + UpdatableFontDir dir = installTestFontFile(1 /* numFonts */, 2 /* version */); + + // Make sure the font installation succeeds. + assertTestFontInstalled(dir, 2 /* version */); + + // Make sure after the reboot, the configuration remains. + UpdatableFontDir nextDir = createNewUpdateDir(); + assertTestFontInstalled(nextDir, 2 /* version */); + } + private FontUpdateRequest newFontUpdateRequest(String content, String signature) throws Exception { File file = File.createTempFile("font", "ttf", mCacheDir); diff --git a/tests/PackageWatchdog/src/com/android/server/CrashRecoveryTest.java b/tests/PackageWatchdog/src/com/android/server/CrashRecoveryTest.java index 081da11f2aa8..489ef4444e1d 100644 --- a/tests/PackageWatchdog/src/com/android/server/CrashRecoveryTest.java +++ b/tests/PackageWatchdog/src/com/android/server/CrashRecoveryTest.java @@ -66,6 +66,7 @@ import org.mockito.Answers; import org.mockito.ArgumentCaptor; import org.mockito.Captor; import org.mockito.Mock; +import org.mockito.Mockito; import org.mockito.MockitoAnnotations; import org.mockito.MockitoSession; import org.mockito.quality.Strictness; @@ -220,43 +221,36 @@ public class CrashRecoveryTest { RescuePartyObserver rescuePartyObserver = setUpRescuePartyObserver(watchdog); verify(rescuePartyObserver, never()).executeBootLoopMitigation(1); - int bootCounter = 0; + for (int i = 0; i < PackageWatchdog.DEFAULT_BOOT_LOOP_TRIGGER_COUNT; i++) { watchdog.noteBoot(); - bootCounter += 1; } + verify(rescuePartyObserver).executeBootLoopMitigation(1); verify(rescuePartyObserver, never()).executeBootLoopMitigation(2); - for (int i = 0; i < PackageWatchdog.DEFAULT_BOOT_LOOP_MITIGATION_INCREMENT; i++) { - watchdog.noteBoot(); - bootCounter += 1; - } + watchdog.noteBoot(); + verify(rescuePartyObserver).executeBootLoopMitigation(2); verify(rescuePartyObserver, never()).executeBootLoopMitigation(3); - int bootLoopThreshold = PackageWatchdog.DEFAULT_BOOT_LOOP_THRESHOLD - bootCounter; - for (int i = 0; i < bootLoopThreshold; i++) { - watchdog.noteBoot(); - } + watchdog.noteBoot(); + verify(rescuePartyObserver).executeBootLoopMitigation(3); verify(rescuePartyObserver, never()).executeBootLoopMitigation(4); - for (int i = 0; i < PackageWatchdog.DEFAULT_BOOT_LOOP_MITIGATION_INCREMENT; i++) { - watchdog.noteBoot(); - } + watchdog.noteBoot(); + verify(rescuePartyObserver).executeBootLoopMitigation(4); verify(rescuePartyObserver, never()).executeBootLoopMitigation(5); - for (int i = 0; i < PackageWatchdog.DEFAULT_BOOT_LOOP_MITIGATION_INCREMENT; i++) { - watchdog.noteBoot(); - } + watchdog.noteBoot(); + verify(rescuePartyObserver).executeBootLoopMitigation(5); verify(rescuePartyObserver, never()).executeBootLoopMitigation(6); - for (int i = 0; i < PackageWatchdog.DEFAULT_BOOT_LOOP_MITIGATION_INCREMENT; i++) { - watchdog.noteBoot(); - } + watchdog.noteBoot(); + verify(rescuePartyObserver).executeBootLoopMitigation(6); verify(rescuePartyObserver, never()).executeBootLoopMitigation(7); } @@ -268,11 +262,11 @@ public class CrashRecoveryTest { setUpRollbackPackageHealthObserver(watchdog); verify(rollbackObserver, never()).executeBootLoopMitigation(1); - int bootCounter = 0; + for (int i = 0; i < PackageWatchdog.DEFAULT_BOOT_LOOP_TRIGGER_COUNT; i++) { watchdog.noteBoot(); - bootCounter += 1; } + verify(rollbackObserver).executeBootLoopMitigation(1); verify(rollbackObserver, never()).executeBootLoopMitigation(2); @@ -280,19 +274,16 @@ public class CrashRecoveryTest { when(mRollbackManager.getAvailableRollbacks()).thenReturn(List.of(ROLLBACK_INFO_HIGH, ROLLBACK_INFO_MANUAL)); - int bootLoopThreshold = PackageWatchdog.DEFAULT_BOOT_LOOP_THRESHOLD - bootCounter; - for (int i = 0; i < bootLoopThreshold; i++) { - watchdog.noteBoot(); - } + watchdog.noteBoot(); + verify(rollbackObserver).executeBootLoopMitigation(2); verify(rollbackObserver, never()).executeBootLoopMitigation(3); // Update the list of available rollbacks after executing bootloop mitigation once when(mRollbackManager.getAvailableRollbacks()).thenReturn(List.of(ROLLBACK_INFO_MANUAL)); - for (int i = 0; i < PackageWatchdog.DEFAULT_BOOT_LOOP_MITIGATION_INCREMENT; i++) { - watchdog.noteBoot(); - } + watchdog.noteBoot(); + verify(rollbackObserver, never()).executeBootLoopMitigation(3); } @@ -305,27 +296,21 @@ public class CrashRecoveryTest { verify(rescuePartyObserver, never()).executeBootLoopMitigation(1); verify(rollbackObserver, never()).executeBootLoopMitigation(1); - int bootCounter = 0; for (int i = 0; i < PackageWatchdog.DEFAULT_BOOT_LOOP_TRIGGER_COUNT; i++) { watchdog.noteBoot(); - bootCounter += 1; } verify(rescuePartyObserver).executeBootLoopMitigation(1); verify(rescuePartyObserver, never()).executeBootLoopMitigation(2); verify(rollbackObserver, never()).executeBootLoopMitigation(1); - for (int i = 0; i < PackageWatchdog.DEFAULT_BOOT_LOOP_MITIGATION_INCREMENT; i++) { - watchdog.noteBoot(); - bootCounter += 1; - } + watchdog.noteBoot(); + verify(rescuePartyObserver).executeBootLoopMitigation(2); verify(rescuePartyObserver, never()).executeBootLoopMitigation(3); verify(rollbackObserver, never()).executeBootLoopMitigation(2); - for (int i = 0; i < PackageWatchdog.DEFAULT_BOOT_LOOP_MITIGATION_INCREMENT; i++) { - watchdog.noteBoot(); - bootCounter += 1; - } + watchdog.noteBoot(); + verify(rescuePartyObserver, never()).executeBootLoopMitigation(3); verify(rollbackObserver).executeBootLoopMitigation(1); verify(rollbackObserver, never()).executeBootLoopMitigation(2); @@ -333,43 +318,46 @@ public class CrashRecoveryTest { when(mRollbackManager.getAvailableRollbacks()).thenReturn(List.of(ROLLBACK_INFO_HIGH, ROLLBACK_INFO_MANUAL)); - int bootLoopThreshold = PackageWatchdog.DEFAULT_BOOT_LOOP_THRESHOLD - bootCounter; - for (int i = 0; i < bootLoopThreshold; i++) { - watchdog.noteBoot(); - } + watchdog.noteBoot(); + verify(rescuePartyObserver).executeBootLoopMitigation(3); verify(rescuePartyObserver, never()).executeBootLoopMitigation(4); verify(rollbackObserver, never()).executeBootLoopMitigation(2); - for (int i = 0; i < PackageWatchdog.DEFAULT_BOOT_LOOP_MITIGATION_INCREMENT; i++) { - watchdog.noteBoot(); - } + watchdog.noteBoot(); + verify(rescuePartyObserver).executeBootLoopMitigation(4); verify(rescuePartyObserver, never()).executeBootLoopMitigation(5); verify(rollbackObserver, never()).executeBootLoopMitigation(2); - for (int i = 0; i < PackageWatchdog.DEFAULT_BOOT_LOOP_MITIGATION_INCREMENT; i++) { - watchdog.noteBoot(); - } + watchdog.noteBoot(); + verify(rescuePartyObserver).executeBootLoopMitigation(5); verify(rescuePartyObserver, never()).executeBootLoopMitigation(6); verify(rollbackObserver, never()).executeBootLoopMitigation(2); - for (int i = 0; i < PackageWatchdog.DEFAULT_BOOT_LOOP_MITIGATION_INCREMENT; i++) { - watchdog.noteBoot(); - } + watchdog.noteBoot(); + verify(rescuePartyObserver, never()).executeBootLoopMitigation(6); verify(rollbackObserver).executeBootLoopMitigation(2); verify(rollbackObserver, never()).executeBootLoopMitigation(3); // Update the list of available rollbacks after executing bootloop mitigation when(mRollbackManager.getAvailableRollbacks()).thenReturn(List.of(ROLLBACK_INFO_MANUAL)); - for (int i = 0; i < PackageWatchdog.DEFAULT_BOOT_LOOP_MITIGATION_INCREMENT; i++) { - watchdog.noteBoot(); - } + watchdog.noteBoot(); + verify(rescuePartyObserver).executeBootLoopMitigation(6); verify(rescuePartyObserver, never()).executeBootLoopMitigation(7); verify(rollbackObserver, never()).executeBootLoopMitigation(3); + + moveTimeForwardAndDispatch(PackageWatchdog.DEFAULT_DEESCALATION_WINDOW_MS + 1); + Mockito.reset(rescuePartyObserver); + + for (int i = 0; i < PackageWatchdog.DEFAULT_BOOT_LOOP_TRIGGER_COUNT; i++) { + watchdog.noteBoot(); + } + verify(rescuePartyObserver).executeBootLoopMitigation(1); + verify(rescuePartyObserver, never()).executeBootLoopMitigation(2); } RollbackPackageHealthObserver setUpRollbackPackageHealthObserver(PackageWatchdog watchdog) { @@ -506,16 +494,9 @@ public class CrashRecoveryTest { } try { - if (Flags.recoverabilityDetection()) { - mSpyBootThreshold = spy(watchdog.new BootThreshold( - PackageWatchdog.DEFAULT_BOOT_LOOP_TRIGGER_COUNT, - PackageWatchdog.DEFAULT_BOOT_LOOP_TRIGGER_WINDOW_MS, - PackageWatchdog.DEFAULT_BOOT_LOOP_MITIGATION_INCREMENT)); - } else { - mSpyBootThreshold = spy(watchdog.new BootThreshold( + mSpyBootThreshold = spy(watchdog.new BootThreshold( PackageWatchdog.DEFAULT_BOOT_LOOP_TRIGGER_COUNT, PackageWatchdog.DEFAULT_BOOT_LOOP_TRIGGER_WINDOW_MS)); - } doAnswer((Answer<Integer>) invocationOnMock -> { String storedValue = mCrashRecoveryPropertiesMap @@ -640,5 +621,16 @@ public class CrashRecoveryTest { public long uptimeMillis() { return mUpTimeMillis; } + public void moveTimeForward(long milliSeconds) { + mUpTimeMillis += milliSeconds; + } + } + + private void moveTimeForwardAndDispatch(long milliSeconds) { + // Exhaust all due runnables now which shouldn't be executed after time-leap + mTestLooper.dispatchAll(); + mTestClock.moveTimeForward(milliSeconds); + mTestLooper.moveTimeForward(milliSeconds); + mTestLooper.dispatchAll(); } } diff --git a/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java b/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java index 4f27e06083ba..093923f3ed53 100644 --- a/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java +++ b/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java @@ -45,13 +45,13 @@ import android.os.test.TestLooper; import android.platform.test.flag.junit.SetFlagsRule; import android.provider.DeviceConfig; import android.util.AtomicFile; +import android.util.LongArrayQueue; import android.util.Xml; -import android.utils.LongArrayQueue; -import android.utils.XmlUtils; import androidx.test.InstrumentationRegistry; import com.android.dx.mockito.inline.extended.ExtendedMockito; +import com.android.internal.util.XmlUtils; import com.android.modules.utils.TypedXmlPullParser; import com.android.modules.utils.TypedXmlSerializer; import com.android.server.PackageWatchdog.HealthCheckState; @@ -1224,7 +1224,7 @@ public class PackageWatchdogTest { PackageWatchdog watchdog = createWatchdog(); TestObserver bootObserver = new TestObserver(OBSERVER_NAME_1); watchdog.registerHealthObserver(bootObserver); - for (int i = 0; i < PackageWatchdog.DEFAULT_BOOT_LOOP_THRESHOLD; i++) { + for (int i = 0; i < 15; i++) { watchdog.noteBoot(); } assertThat(bootObserver.mitigatedBootLoop()).isTrue(); @@ -1262,22 +1262,6 @@ public class PackageWatchdogTest { } /** - * Ensure that boot loop mitigation is not done when the number of boots does not meet the - * threshold. - */ - @Test - public void testBootLoopDetection_doesNotMeetThresholdRecoverabilityHighImpact() { - PackageWatchdog watchdog = createWatchdog(); - TestObserver bootObserver = new TestObserver(OBSERVER_NAME_1, - PackageHealthObserverImpact.USER_IMPACT_LEVEL_80); - watchdog.registerHealthObserver(bootObserver); - for (int i = 0; i < PackageWatchdog.DEFAULT_BOOT_LOOP_THRESHOLD - 1; i++) { - watchdog.noteBoot(); - } - assertThat(bootObserver.mitigatedBootLoop()).isFalse(); - } - - /** * Ensure that boot loop mitigation is done for the observer with the lowest user impact */ @Test @@ -1306,7 +1290,7 @@ public class PackageWatchdogTest { bootObserver2.setImpact(PackageHealthObserverImpact.USER_IMPACT_LEVEL_30); watchdog.registerHealthObserver(bootObserver1); watchdog.registerHealthObserver(bootObserver2); - for (int i = 0; i < PackageWatchdog.DEFAULT_BOOT_LOOP_THRESHOLD; i++) { + for (int i = 0; i < 15; i++) { watchdog.noteBoot(); } assertThat(bootObserver1.mitigatedBootLoop()).isTrue(); @@ -1349,9 +1333,7 @@ public class PackageWatchdogTest { watchdog.noteBoot(); } for (int i = 0; i < 4; i++) { - for (int j = 0; j < PackageWatchdog.DEFAULT_BOOT_LOOP_MITIGATION_INCREMENT; j++) { watchdog.noteBoot(); - } } moveTimeForwardAndDispatch(PackageWatchdog.DEFAULT_DEESCALATION_WINDOW_MS + 1); @@ -1360,38 +1342,7 @@ public class PackageWatchdogTest { watchdog.noteBoot(); } for (int i = 0; i < 4; i++) { - for (int j = 0; j < PackageWatchdog.DEFAULT_BOOT_LOOP_MITIGATION_INCREMENT; j++) { watchdog.noteBoot(); - } - } - - assertThat(bootObserver.mBootMitigationCounts).isEqualTo(List.of(1, 2, 3, 4, 1, 2, 3, 4)); - } - - @Test - public void testMultipleBootLoopMitigationRecoverabilityHighImpact() { - PackageWatchdog watchdog = createWatchdog(); - TestObserver bootObserver = new TestObserver(OBSERVER_NAME_1, - PackageHealthObserverImpact.USER_IMPACT_LEVEL_80); - watchdog.registerHealthObserver(bootObserver); - for (int j = 0; j < PackageWatchdog.DEFAULT_BOOT_LOOP_THRESHOLD - 1; j++) { - watchdog.noteBoot(); - } - for (int i = 0; i < 4; i++) { - for (int j = 0; j < PackageWatchdog.DEFAULT_BOOT_LOOP_MITIGATION_INCREMENT; j++) { - watchdog.noteBoot(); - } - } - - moveTimeForwardAndDispatch(PackageWatchdog.DEFAULT_DEESCALATION_WINDOW_MS + 1); - - for (int j = 0; j < PackageWatchdog.DEFAULT_BOOT_LOOP_THRESHOLD - 1; j++) { - watchdog.noteBoot(); - } - for (int i = 0; i < 4; i++) { - for (int j = 0; j < PackageWatchdog.DEFAULT_BOOT_LOOP_MITIGATION_INCREMENT; j++) { - watchdog.noteBoot(); - } } assertThat(bootObserver.mBootMitigationCounts).isEqualTo(List.of(1, 2, 3, 4, 1, 2, 3, 4)); @@ -1642,8 +1593,7 @@ public class PackageWatchdogTest { mSpyBootThreshold = spy(watchdog.new BootThreshold( PackageWatchdog.DEFAULT_BOOT_LOOP_TRIGGER_COUNT, - PackageWatchdog.DEFAULT_BOOT_LOOP_TRIGGER_WINDOW_MS, - PackageWatchdog.DEFAULT_BOOT_LOOP_MITIGATION_INCREMENT)); + PackageWatchdog.DEFAULT_BOOT_LOOP_TRIGGER_WINDOW_MS)); watchdog.saveAllObserversBootMitigationCountToMetadata(filePath); @@ -1798,16 +1748,9 @@ public class PackageWatchdogTest { mCrashRecoveryPropertiesMap = new HashMap<>(); try { - if (Flags.recoverabilityDetection()) { - mSpyBootThreshold = spy(watchdog.new BootThreshold( - PackageWatchdog.DEFAULT_BOOT_LOOP_TRIGGER_COUNT, - PackageWatchdog.DEFAULT_BOOT_LOOP_TRIGGER_WINDOW_MS, - PackageWatchdog.DEFAULT_BOOT_LOOP_MITIGATION_INCREMENT)); - } else { - mSpyBootThreshold = spy(watchdog.new BootThreshold( + mSpyBootThreshold = spy(watchdog.new BootThreshold( PackageWatchdog.DEFAULT_BOOT_LOOP_TRIGGER_COUNT, PackageWatchdog.DEFAULT_BOOT_LOOP_TRIGGER_WINDOW_MS)); - } doAnswer((Answer<Integer>) invocationOnMock -> { String storedValue = mCrashRecoveryPropertiesMap diff --git a/tests/UsbManagerTests/Android.bp b/tests/UsbManagerTests/Android.bp index c02d8e96abb0..a0bb84d09664 100644 --- a/tests/UsbManagerTests/Android.bp +++ b/tests/UsbManagerTests/Android.bp @@ -21,6 +21,7 @@ package { // to get the below license kinds: // SPDX-license-identifier-Apache-2.0 default_applicable_licenses: ["frameworks_base_license"], + default_team: "trendy_team_android_usb", } android_test { diff --git a/tests/UsbTests/Android.bp b/tests/UsbTests/Android.bp index 92c271165ad7..c4ebdecae735 100644 --- a/tests/UsbTests/Android.bp +++ b/tests/UsbTests/Android.bp @@ -21,6 +21,7 @@ package { // to get the below license kinds: // SPDX-license-identifier-Apache-2.0 default_applicable_licenses: ["frameworks_base_license"], + default_team: "trendy_team_android_usb", } android_test { |