Loading core/java/android/app/ActivityManagerInternal.java +7 −0 Original line number Diff line number Diff line Loading @@ -45,6 +45,7 @@ import android.os.TransactionTooLargeException; import android.os.WorkSource; import android.util.ArraySet; import android.util.Pair; import android.util.StatsEvent; import com.android.internal.os.TimeoutRecord; Loading Loading @@ -1217,4 +1218,10 @@ public abstract class ActivityManagerInternal { */ public abstract void notifyMediaProjectionEvent(int uid, @NonNull IBinder projectionToken, @MediaProjectionTokenEvent int event); /** * @return The stats event for the cached apps high watermark since last pull. */ @NonNull public abstract StatsEvent getCachedAppsHighWatermarkStats(int atomTag, boolean resetAfterPull); } core/java/com/android/internal/util/QuickSelect.java 0 → 100644 +256 −0 Original line number Diff line number Diff line /* * Copyright (C) 2023 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.internal.util; import android.annotation.NonNull; import android.annotation.Nullable; import java.util.Comparator; import java.util.List; /** * An implementation of the quick selection algorithm as described in * http://en.wikipedia.org/wiki/Quickselect. * * @hide */ public final class QuickSelect { private static <T> int selectImpl(@NonNull List<T> list, int left, int right, int k, @NonNull Comparator<? super T> comparator) { while (true) { if (left == right) { return left; } final int pivotIndex = partition(list, left, right, (left + right) >> 1, comparator); if (k == pivotIndex) { return k; } else if (k < pivotIndex) { right = pivotIndex - 1; } else { left = pivotIndex + 1; } } } private static int selectImpl(@NonNull int[] array, int left, int right, int k) { while (true) { if (left == right) { return left; } final int pivotIndex = partition(array, left, right, (left + right) >> 1); if (k == pivotIndex) { return k; } else if (k < pivotIndex) { right = pivotIndex - 1; } else { left = pivotIndex + 1; } } } private static int selectImpl(@NonNull long[] array, int left, int right, int k) { while (true) { if (left == right) { return left; } final int pivotIndex = partition(array, left, right, (left + right) >> 1); if (k == pivotIndex) { return k; } else if (k < pivotIndex) { right = pivotIndex - 1; } else { left = pivotIndex + 1; } } } private static <T> int selectImpl(@NonNull T[] array, int left, int right, int k, @NonNull Comparator<? super T> comparator) { while (true) { if (left == right) { return left; } final int pivotIndex = partition(array, left, right, (left + right) >> 1, comparator); if (k == pivotIndex) { return k; } else if (k < pivotIndex) { right = pivotIndex - 1; } else { left = pivotIndex + 1; } } } private static <T> int partition(@NonNull List<T> list, int left, int right, int pivotIndex, @NonNull Comparator<? super T> comparator) { final T pivotValue = list.get(pivotIndex); swap(list, right, pivotIndex); int storeIndex = left; for (int i = left; i < right; i++) { if (comparator.compare(list.get(i), pivotValue) < 0) { swap(list, storeIndex, i); storeIndex++; } } swap(list, right, storeIndex); return storeIndex; } private static int partition(@NonNull int[] array, int left, int right, int pivotIndex) { final int pivotValue = array[pivotIndex]; swap(array, right, pivotIndex); int storeIndex = left; for (int i = left; i < right; i++) { if (array[i] < pivotValue) { swap(array, storeIndex, i); storeIndex++; } } swap(array, right, storeIndex); return storeIndex; } private static int partition(@NonNull long[] array, int left, int right, int pivotIndex) { final long pivotValue = array[pivotIndex]; swap(array, right, pivotIndex); int storeIndex = left; for (int i = left; i < right; i++) { if (array[i] < pivotValue) { swap(array, storeIndex, i); storeIndex++; } } swap(array, right, storeIndex); return storeIndex; } private static <T> int partition(@NonNull T[] array, int left, int right, int pivotIndex, @NonNull Comparator<? super T> comparator) { final T pivotValue = array[pivotIndex]; swap(array, right, pivotIndex); int storeIndex = left; for (int i = left; i < right; i++) { if (comparator.compare(array[i], pivotValue) < 0) { swap(array, storeIndex, i); storeIndex++; } } swap(array, right, storeIndex); return storeIndex; } private static <T> void swap(@NonNull List<T> list, int left, int right) { final T tmp = list.get(left); list.set(left, list.get(right)); list.set(right, tmp); } private static void swap(@NonNull int[] array, int left, int right) { final int tmp = array[left]; array[left] = array[right]; array[right] = tmp; } private static void swap(@NonNull long[] array, int left, int right) { final long tmp = array[left]; array[left] = array[right]; array[right] = tmp; } private static <T> void swap(@NonNull T[] array, int left, int right) { final T tmp = array[left]; array[left] = array[right]; array[right] = tmp; } /** * Return the kth(0-based) smallest element from the given unsorted list. * * @param list The input list, it <b>will</b> be modified by the algorithm here. * @param start The start offset of the list, inclusive. * @param length The length of the sub list to be searched in. * @param k The 0-based index. * @param comparator The comparator which knows how to compare the elements in the list. * @return The kth smallest element from the given list, * or IllegalArgumentException will be thrown if not found. */ @Nullable public static <T> T select(@NonNull List<T> list, int start, int length, int k, @NonNull Comparator<? super T> comparator) { if (list == null || start < 0 || length <= 0 || list.size() < start + length || k < 0 || length <= k) { throw new IllegalArgumentException(); } return list.get(selectImpl(list, start, start + length - 1, k + start, comparator)); } /** * Return the kth(0-based) smallest element from the given unsorted array. * * @param array The input array, it <b>will</b> be modified by the algorithm here. * @param start The start offset of the array, inclusive. * @param length The length of the sub array to be searched in. * @param k The 0-based index to search for. * @return The kth smallest element from the given array, * or IllegalArgumentException will be thrown if not found. */ public static int select(@NonNull int[] array, int start, int length, int k) { if (array == null || start < 0 || length <= 0 || array.length < start + length || k < 0 || length <= k) { throw new IllegalArgumentException(); } return array[selectImpl(array, start, start + length - 1, k + start)]; } /** * Return the kth(0-based) smallest element from the given unsorted array. * * @param array The input array, it <b>will</b> be modified by the algorithm here. * @param start The start offset of the array, inclusive. * @param length The length of the sub array to be searched in. * @param k The 0-based index to search for. * @return The kth smallest element from the given array, * or IllegalArgumentException will be thrown if not found. */ public static long select(@NonNull long[] array, int start, int length, int k) { if (array == null || start < 0 || length <= 0 || array.length < start + length || k < 0 || length <= k) { throw new IllegalArgumentException(); } return array[selectImpl(array, start, start + length - 1, k + start)]; } /** * Return the kth(0-based) smallest element from the given unsorted array. * * @param array The input array, it <b>will</b> be modified by the algorithm here. * @param start The start offset of the array, inclusive. * @param length The length of the sub array to be searched in. * @param k The 0-based index to search for. * @param comparator The comparator which knows how to compare the elements in the list. * @return The kth smallest element from the given array, * or IllegalArgumentException will be thrown if not found. */ public static <T> T select(@NonNull T[] array, int start, int length, int k, @NonNull Comparator<? super T> comparator) { if (array == null || start < 0 || length <= 0 || array.length < start + length || k < 0 || length <= k) { throw new IllegalArgumentException(); } return array[selectImpl(array, start, start + length - 1, k + start, comparator)]; } } core/tests/utiltests/src/com/android/internal/util/QuickSelectTest.java 0 → 100644 +152 −0 Original line number Diff line number Diff line /* * Copyright (C) 2023 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.internal.util; import junit.framework.TestCase; import java.util.Arrays; import java.util.List; /** * Tests for {@link QuickSelect}. */ public final class QuickSelectTest extends TestCase { public void testQuickSelect() throws Exception { test((List<Integer>) null, 0, null); test(Arrays.asList(), -1, null); test(Arrays.asList(), 0, null); test(Arrays.asList(), 1, null); test(Arrays.asList(1), -1, 1, 0, null); test(Arrays.asList(1), 1, -1, 0, null); test(Arrays.asList(1), 0, 1, -1, null); test(Arrays.asList(1), 1, 1, 0, null); test(Arrays.asList(1), 0, 1); test(Arrays.asList(1), 1, null); test(Arrays.asList(1, 2, 3, 4, 5), 0, 1); test(Arrays.asList(1, 2, 3, 4, 5), 1, 2); test(Arrays.asList(1, 2, 3, 4, 5), 2, 3); test(Arrays.asList(1, 2, 3, 4, 5), 3, 4); test(Arrays.asList(1, 2, 3, 4, 5), 4, 5); test(Arrays.asList(1, 2, 3, 4, 5), 5, null); test(Arrays.asList(7, 10, 4, 3, 20, 15, 8, 9), 2, 7); test(Arrays.asList(7, 10, 4, 3, 20, 15, 8, 9), 4, 9); test(Arrays.asList(7, 10, 4, 3, 20, 15, 8, 9), 7, 20); test(Arrays.asList(7, 10, 4, 3, 20, 15, 8, 9), 8, null); test(Arrays.asList(7, 10, 4, 3, 20, 15, 8, 9), 1, 3, 0, 3); test(Arrays.asList(7, 10, 4, 3, 20, 15, 8, 9), 1, 3, 1, 4); test(Arrays.asList(7, 10, 4, 3, 20, 15, 8, 9), 1, 3, 2, 10); test(Arrays.asList(7, 10, 4, 3, 20, 15, 8, 9), 1, 3, 3, null); test((int[]) null, 0, null); test(new int[0], -1, null); test(new int[0], 0, null); test(new int[0], 1, null); test(new int[] {1}, -1, 1, 0, null); test(new int[] {1}, 1, -1, 0, null); test(new int[] {1}, 1, 0, -1, null); test(new int[] {1}, 1, 1, 0, null); test(new int[] {1}, 0, 1); test(new int[] {1}, 1, null); test(new int[] {1, 2, 3, 4, 5}, 0, 1); test(new int[] {1, 2, 3, 4, 5}, 1, 2); test(new int[] {1, 2, 3, 4, 5}, 2, 3); test(new int[] {1, 2, 3, 4, 5}, 3, 4); test(new int[] {1, 2, 3, 4, 5}, 4, 5); test(new int[] {1, 2, 3, 4, 5}, 5, null); test(new int[] {7, 10, 4, 3, 20, 15, 8, 9}, 2, 7); test(new int[] {7, 10, 4, 3, 20, 15, 8, 9}, 4, 9); test(new int[] {7, 10, 4, 3, 20, 15, 8, 9}, 7, 20); test(new int[] {7, 10, 4, 3, 20, 15, 8, 9}, 8, null); test(new int[] {7, 10, 4, 3, 20, 15, 8, 9}, 1, 3, 0, 3); test(new int[] {7, 10, 4, 3, 20, 15, 8, 9}, 1, 3, 1, 4); test(new int[] {7, 10, 4, 3, 20, 15, 8, 9}, 1, 3, 2, 10); test(new int[] {7, 10, 4, 3, 20, 15, 8, 9}, 1, 3, 3, null); test((long[]) null, 0, null); test(new long[0], -1, null); test(new long[0], 0, null); test(new long[0], 1, null); test(new long[] {1}, -1, 1, 0, null); test(new long[] {1}, 1, -1, 0, null); test(new long[] {1}, 1, 0, -1, null); test(new long[] {1}, 1, 1, 0, null); test(new long[] {1}, 0, 1L); test(new long[] {1}, 1, null); test(new long[] {1, 2, 3, 4, 5}, 0, 1L); test(new long[] {1, 2, 3, 4, 5}, 1, 2L); test(new long[] {1, 2, 3, 4, 5}, 2, 3L); test(new long[] {1, 2, 3, 4, 5}, 3, 4L); test(new long[] {1, 2, 3, 4, 5}, 4, 5L); test(new long[] {1, 2, 3, 4, 5}, 5, null); test(new long[] {7, 10, 4, 3, 20, 15, 8, 9}, 2, 7L); test(new long[] {7, 10, 4, 3, 20, 15, 8, 9}, 4, 9L); test(new long[] {7, 10, 4, 3, 20, 15, 8, 9}, 7, 20L); test(new long[] {7, 10, 4, 3, 20, 15, 8, 9}, 8, null); test(new long[] {7, 10, 4, 3, 20, 15, 8, 9}, 1, 3, 0, 3L); test(new long[] {7, 10, 4, 3, 20, 15, 8, 9}, 1, 3, 1, 4L); test(new long[] {7, 10, 4, 3, 20, 15, 8, 9}, 1, 3, 2, 10L); test(new long[] {7, 10, 4, 3, 20, 15, 8, 9}, 1, 3, 3, null); } private void test(List<Integer> input, int k, Integer expected) throws Exception { test(input, 0, input == null ? 0 : input.size(), k, expected); } private void test(List<Integer> input, int start, int length, int k, Integer expected) throws Exception { try { final Integer result = QuickSelect.select(input, start, length, k, Integer::compare); assertEquals(expected, result); } catch (IllegalArgumentException e) { if (expected != null) { throw new Exception(e); } } } private void test(int[] input, int k, Integer expected) throws Exception { test(input, 0, input == null ? 0 : input.length, k, expected); } private void test(int[] input, int start, int length, int k, Integer expected) throws Exception { try { final int result = QuickSelect.select(input, start, length, k); assertEquals((int) expected, result); } catch (IllegalArgumentException e) { if (expected != null) { throw new Exception(e); } } } private void test(long[] input, int k, Long expected) throws Exception { test(input, 0, input == null ? 0 : input.length, k, expected); } private void test(long[] input, int start, int length, int k, Long expected) throws Exception { try { final long result = QuickSelect.select(input, start, length, k); assertEquals((long) expected, result); } catch (IllegalArgumentException e) { if (expected != null) { throw new Exception(e); } } } } services/core/java/com/android/server/am/ActivityManagerService.java +12 −0 Original line number Diff line number Diff line Loading @@ -382,6 +382,7 @@ import android.util.PrintWriterPrinter; import android.util.Slog; import android.util.SparseArray; import android.util.SparseIntArray; import android.util.StatsEvent; import android.util.TimeUtils; import android.util.proto.ProtoOutputStream; import android.util.proto.ProtoUtils; Loading Loading @@ -1595,6 +1596,7 @@ public class ActivityManagerService extends IActivityManager.Stub static final int SERVICE_SHORT_FGS_TIMEOUT_MSG = 76; static final int SERVICE_SHORT_FGS_PROCSTATE_TIMEOUT_MSG = 77; static final int SERVICE_SHORT_FGS_ANR_TIMEOUT_MSG = 78; static final int UPDATE_CACHED_APP_HIGH_WATERMARK = 79; static final int FIRST_BROADCAST_QUEUE_MSG = 200; Loading Loading @@ -1938,6 +1940,9 @@ public class ActivityManagerService extends IActivityManager.Stub case SERVICE_SHORT_FGS_ANR_TIMEOUT_MSG: { mServices.onShortFgsAnrTimeout((ServiceRecord) msg.obj); } break; case UPDATE_CACHED_APP_HIGH_WATERMARK: { mAppProfiler.mCachedAppsWatermarkData.updateCachedAppsSnapshot((long) msg.obj); } break; } } } Loading Loading @@ -18598,6 +18603,13 @@ public class ActivityManagerService extends IActivityManager.Stub @MediaProjectionTokenEvent int event) { ActivityManagerService.this.notifyMediaProjectionEvent(uid, projectionToken, event); } @Override @NonNull public StatsEvent getCachedAppsHighWatermarkStats(int atomTag, boolean resetAfterPull) { return mAppProfiler.mCachedAppsWatermarkData.getCachedAppsHighWatermarkStats( atomTag, resetAfterPull); } } long inputDispatchingTimedOut(int pid, final boolean aboveSystem, TimeoutRecord timeoutRecord) { services/core/java/com/android/server/am/AppProfiler.java +198 −4 File changed.Preview size limit exceeded, changes collapsed. Show changes Loading
core/java/android/app/ActivityManagerInternal.java +7 −0 Original line number Diff line number Diff line Loading @@ -45,6 +45,7 @@ import android.os.TransactionTooLargeException; import android.os.WorkSource; import android.util.ArraySet; import android.util.Pair; import android.util.StatsEvent; import com.android.internal.os.TimeoutRecord; Loading Loading @@ -1217,4 +1218,10 @@ public abstract class ActivityManagerInternal { */ public abstract void notifyMediaProjectionEvent(int uid, @NonNull IBinder projectionToken, @MediaProjectionTokenEvent int event); /** * @return The stats event for the cached apps high watermark since last pull. */ @NonNull public abstract StatsEvent getCachedAppsHighWatermarkStats(int atomTag, boolean resetAfterPull); }
core/java/com/android/internal/util/QuickSelect.java 0 → 100644 +256 −0 Original line number Diff line number Diff line /* * Copyright (C) 2023 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.internal.util; import android.annotation.NonNull; import android.annotation.Nullable; import java.util.Comparator; import java.util.List; /** * An implementation of the quick selection algorithm as described in * http://en.wikipedia.org/wiki/Quickselect. * * @hide */ public final class QuickSelect { private static <T> int selectImpl(@NonNull List<T> list, int left, int right, int k, @NonNull Comparator<? super T> comparator) { while (true) { if (left == right) { return left; } final int pivotIndex = partition(list, left, right, (left + right) >> 1, comparator); if (k == pivotIndex) { return k; } else if (k < pivotIndex) { right = pivotIndex - 1; } else { left = pivotIndex + 1; } } } private static int selectImpl(@NonNull int[] array, int left, int right, int k) { while (true) { if (left == right) { return left; } final int pivotIndex = partition(array, left, right, (left + right) >> 1); if (k == pivotIndex) { return k; } else if (k < pivotIndex) { right = pivotIndex - 1; } else { left = pivotIndex + 1; } } } private static int selectImpl(@NonNull long[] array, int left, int right, int k) { while (true) { if (left == right) { return left; } final int pivotIndex = partition(array, left, right, (left + right) >> 1); if (k == pivotIndex) { return k; } else if (k < pivotIndex) { right = pivotIndex - 1; } else { left = pivotIndex + 1; } } } private static <T> int selectImpl(@NonNull T[] array, int left, int right, int k, @NonNull Comparator<? super T> comparator) { while (true) { if (left == right) { return left; } final int pivotIndex = partition(array, left, right, (left + right) >> 1, comparator); if (k == pivotIndex) { return k; } else if (k < pivotIndex) { right = pivotIndex - 1; } else { left = pivotIndex + 1; } } } private static <T> int partition(@NonNull List<T> list, int left, int right, int pivotIndex, @NonNull Comparator<? super T> comparator) { final T pivotValue = list.get(pivotIndex); swap(list, right, pivotIndex); int storeIndex = left; for (int i = left; i < right; i++) { if (comparator.compare(list.get(i), pivotValue) < 0) { swap(list, storeIndex, i); storeIndex++; } } swap(list, right, storeIndex); return storeIndex; } private static int partition(@NonNull int[] array, int left, int right, int pivotIndex) { final int pivotValue = array[pivotIndex]; swap(array, right, pivotIndex); int storeIndex = left; for (int i = left; i < right; i++) { if (array[i] < pivotValue) { swap(array, storeIndex, i); storeIndex++; } } swap(array, right, storeIndex); return storeIndex; } private static int partition(@NonNull long[] array, int left, int right, int pivotIndex) { final long pivotValue = array[pivotIndex]; swap(array, right, pivotIndex); int storeIndex = left; for (int i = left; i < right; i++) { if (array[i] < pivotValue) { swap(array, storeIndex, i); storeIndex++; } } swap(array, right, storeIndex); return storeIndex; } private static <T> int partition(@NonNull T[] array, int left, int right, int pivotIndex, @NonNull Comparator<? super T> comparator) { final T pivotValue = array[pivotIndex]; swap(array, right, pivotIndex); int storeIndex = left; for (int i = left; i < right; i++) { if (comparator.compare(array[i], pivotValue) < 0) { swap(array, storeIndex, i); storeIndex++; } } swap(array, right, storeIndex); return storeIndex; } private static <T> void swap(@NonNull List<T> list, int left, int right) { final T tmp = list.get(left); list.set(left, list.get(right)); list.set(right, tmp); } private static void swap(@NonNull int[] array, int left, int right) { final int tmp = array[left]; array[left] = array[right]; array[right] = tmp; } private static void swap(@NonNull long[] array, int left, int right) { final long tmp = array[left]; array[left] = array[right]; array[right] = tmp; } private static <T> void swap(@NonNull T[] array, int left, int right) { final T tmp = array[left]; array[left] = array[right]; array[right] = tmp; } /** * Return the kth(0-based) smallest element from the given unsorted list. * * @param list The input list, it <b>will</b> be modified by the algorithm here. * @param start The start offset of the list, inclusive. * @param length The length of the sub list to be searched in. * @param k The 0-based index. * @param comparator The comparator which knows how to compare the elements in the list. * @return The kth smallest element from the given list, * or IllegalArgumentException will be thrown if not found. */ @Nullable public static <T> T select(@NonNull List<T> list, int start, int length, int k, @NonNull Comparator<? super T> comparator) { if (list == null || start < 0 || length <= 0 || list.size() < start + length || k < 0 || length <= k) { throw new IllegalArgumentException(); } return list.get(selectImpl(list, start, start + length - 1, k + start, comparator)); } /** * Return the kth(0-based) smallest element from the given unsorted array. * * @param array The input array, it <b>will</b> be modified by the algorithm here. * @param start The start offset of the array, inclusive. * @param length The length of the sub array to be searched in. * @param k The 0-based index to search for. * @return The kth smallest element from the given array, * or IllegalArgumentException will be thrown if not found. */ public static int select(@NonNull int[] array, int start, int length, int k) { if (array == null || start < 0 || length <= 0 || array.length < start + length || k < 0 || length <= k) { throw new IllegalArgumentException(); } return array[selectImpl(array, start, start + length - 1, k + start)]; } /** * Return the kth(0-based) smallest element from the given unsorted array. * * @param array The input array, it <b>will</b> be modified by the algorithm here. * @param start The start offset of the array, inclusive. * @param length The length of the sub array to be searched in. * @param k The 0-based index to search for. * @return The kth smallest element from the given array, * or IllegalArgumentException will be thrown if not found. */ public static long select(@NonNull long[] array, int start, int length, int k) { if (array == null || start < 0 || length <= 0 || array.length < start + length || k < 0 || length <= k) { throw new IllegalArgumentException(); } return array[selectImpl(array, start, start + length - 1, k + start)]; } /** * Return the kth(0-based) smallest element from the given unsorted array. * * @param array The input array, it <b>will</b> be modified by the algorithm here. * @param start The start offset of the array, inclusive. * @param length The length of the sub array to be searched in. * @param k The 0-based index to search for. * @param comparator The comparator which knows how to compare the elements in the list. * @return The kth smallest element from the given array, * or IllegalArgumentException will be thrown if not found. */ public static <T> T select(@NonNull T[] array, int start, int length, int k, @NonNull Comparator<? super T> comparator) { if (array == null || start < 0 || length <= 0 || array.length < start + length || k < 0 || length <= k) { throw new IllegalArgumentException(); } return array[selectImpl(array, start, start + length - 1, k + start, comparator)]; } }
core/tests/utiltests/src/com/android/internal/util/QuickSelectTest.java 0 → 100644 +152 −0 Original line number Diff line number Diff line /* * Copyright (C) 2023 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.internal.util; import junit.framework.TestCase; import java.util.Arrays; import java.util.List; /** * Tests for {@link QuickSelect}. */ public final class QuickSelectTest extends TestCase { public void testQuickSelect() throws Exception { test((List<Integer>) null, 0, null); test(Arrays.asList(), -1, null); test(Arrays.asList(), 0, null); test(Arrays.asList(), 1, null); test(Arrays.asList(1), -1, 1, 0, null); test(Arrays.asList(1), 1, -1, 0, null); test(Arrays.asList(1), 0, 1, -1, null); test(Arrays.asList(1), 1, 1, 0, null); test(Arrays.asList(1), 0, 1); test(Arrays.asList(1), 1, null); test(Arrays.asList(1, 2, 3, 4, 5), 0, 1); test(Arrays.asList(1, 2, 3, 4, 5), 1, 2); test(Arrays.asList(1, 2, 3, 4, 5), 2, 3); test(Arrays.asList(1, 2, 3, 4, 5), 3, 4); test(Arrays.asList(1, 2, 3, 4, 5), 4, 5); test(Arrays.asList(1, 2, 3, 4, 5), 5, null); test(Arrays.asList(7, 10, 4, 3, 20, 15, 8, 9), 2, 7); test(Arrays.asList(7, 10, 4, 3, 20, 15, 8, 9), 4, 9); test(Arrays.asList(7, 10, 4, 3, 20, 15, 8, 9), 7, 20); test(Arrays.asList(7, 10, 4, 3, 20, 15, 8, 9), 8, null); test(Arrays.asList(7, 10, 4, 3, 20, 15, 8, 9), 1, 3, 0, 3); test(Arrays.asList(7, 10, 4, 3, 20, 15, 8, 9), 1, 3, 1, 4); test(Arrays.asList(7, 10, 4, 3, 20, 15, 8, 9), 1, 3, 2, 10); test(Arrays.asList(7, 10, 4, 3, 20, 15, 8, 9), 1, 3, 3, null); test((int[]) null, 0, null); test(new int[0], -1, null); test(new int[0], 0, null); test(new int[0], 1, null); test(new int[] {1}, -1, 1, 0, null); test(new int[] {1}, 1, -1, 0, null); test(new int[] {1}, 1, 0, -1, null); test(new int[] {1}, 1, 1, 0, null); test(new int[] {1}, 0, 1); test(new int[] {1}, 1, null); test(new int[] {1, 2, 3, 4, 5}, 0, 1); test(new int[] {1, 2, 3, 4, 5}, 1, 2); test(new int[] {1, 2, 3, 4, 5}, 2, 3); test(new int[] {1, 2, 3, 4, 5}, 3, 4); test(new int[] {1, 2, 3, 4, 5}, 4, 5); test(new int[] {1, 2, 3, 4, 5}, 5, null); test(new int[] {7, 10, 4, 3, 20, 15, 8, 9}, 2, 7); test(new int[] {7, 10, 4, 3, 20, 15, 8, 9}, 4, 9); test(new int[] {7, 10, 4, 3, 20, 15, 8, 9}, 7, 20); test(new int[] {7, 10, 4, 3, 20, 15, 8, 9}, 8, null); test(new int[] {7, 10, 4, 3, 20, 15, 8, 9}, 1, 3, 0, 3); test(new int[] {7, 10, 4, 3, 20, 15, 8, 9}, 1, 3, 1, 4); test(new int[] {7, 10, 4, 3, 20, 15, 8, 9}, 1, 3, 2, 10); test(new int[] {7, 10, 4, 3, 20, 15, 8, 9}, 1, 3, 3, null); test((long[]) null, 0, null); test(new long[0], -1, null); test(new long[0], 0, null); test(new long[0], 1, null); test(new long[] {1}, -1, 1, 0, null); test(new long[] {1}, 1, -1, 0, null); test(new long[] {1}, 1, 0, -1, null); test(new long[] {1}, 1, 1, 0, null); test(new long[] {1}, 0, 1L); test(new long[] {1}, 1, null); test(new long[] {1, 2, 3, 4, 5}, 0, 1L); test(new long[] {1, 2, 3, 4, 5}, 1, 2L); test(new long[] {1, 2, 3, 4, 5}, 2, 3L); test(new long[] {1, 2, 3, 4, 5}, 3, 4L); test(new long[] {1, 2, 3, 4, 5}, 4, 5L); test(new long[] {1, 2, 3, 4, 5}, 5, null); test(new long[] {7, 10, 4, 3, 20, 15, 8, 9}, 2, 7L); test(new long[] {7, 10, 4, 3, 20, 15, 8, 9}, 4, 9L); test(new long[] {7, 10, 4, 3, 20, 15, 8, 9}, 7, 20L); test(new long[] {7, 10, 4, 3, 20, 15, 8, 9}, 8, null); test(new long[] {7, 10, 4, 3, 20, 15, 8, 9}, 1, 3, 0, 3L); test(new long[] {7, 10, 4, 3, 20, 15, 8, 9}, 1, 3, 1, 4L); test(new long[] {7, 10, 4, 3, 20, 15, 8, 9}, 1, 3, 2, 10L); test(new long[] {7, 10, 4, 3, 20, 15, 8, 9}, 1, 3, 3, null); } private void test(List<Integer> input, int k, Integer expected) throws Exception { test(input, 0, input == null ? 0 : input.size(), k, expected); } private void test(List<Integer> input, int start, int length, int k, Integer expected) throws Exception { try { final Integer result = QuickSelect.select(input, start, length, k, Integer::compare); assertEquals(expected, result); } catch (IllegalArgumentException e) { if (expected != null) { throw new Exception(e); } } } private void test(int[] input, int k, Integer expected) throws Exception { test(input, 0, input == null ? 0 : input.length, k, expected); } private void test(int[] input, int start, int length, int k, Integer expected) throws Exception { try { final int result = QuickSelect.select(input, start, length, k); assertEquals((int) expected, result); } catch (IllegalArgumentException e) { if (expected != null) { throw new Exception(e); } } } private void test(long[] input, int k, Long expected) throws Exception { test(input, 0, input == null ? 0 : input.length, k, expected); } private void test(long[] input, int start, int length, int k, Long expected) throws Exception { try { final long result = QuickSelect.select(input, start, length, k); assertEquals((long) expected, result); } catch (IllegalArgumentException e) { if (expected != null) { throw new Exception(e); } } } }
services/core/java/com/android/server/am/ActivityManagerService.java +12 −0 Original line number Diff line number Diff line Loading @@ -382,6 +382,7 @@ import android.util.PrintWriterPrinter; import android.util.Slog; import android.util.SparseArray; import android.util.SparseIntArray; import android.util.StatsEvent; import android.util.TimeUtils; import android.util.proto.ProtoOutputStream; import android.util.proto.ProtoUtils; Loading Loading @@ -1595,6 +1596,7 @@ public class ActivityManagerService extends IActivityManager.Stub static final int SERVICE_SHORT_FGS_TIMEOUT_MSG = 76; static final int SERVICE_SHORT_FGS_PROCSTATE_TIMEOUT_MSG = 77; static final int SERVICE_SHORT_FGS_ANR_TIMEOUT_MSG = 78; static final int UPDATE_CACHED_APP_HIGH_WATERMARK = 79; static final int FIRST_BROADCAST_QUEUE_MSG = 200; Loading Loading @@ -1938,6 +1940,9 @@ public class ActivityManagerService extends IActivityManager.Stub case SERVICE_SHORT_FGS_ANR_TIMEOUT_MSG: { mServices.onShortFgsAnrTimeout((ServiceRecord) msg.obj); } break; case UPDATE_CACHED_APP_HIGH_WATERMARK: { mAppProfiler.mCachedAppsWatermarkData.updateCachedAppsSnapshot((long) msg.obj); } break; } } } Loading Loading @@ -18598,6 +18603,13 @@ public class ActivityManagerService extends IActivityManager.Stub @MediaProjectionTokenEvent int event) { ActivityManagerService.this.notifyMediaProjectionEvent(uid, projectionToken, event); } @Override @NonNull public StatsEvent getCachedAppsHighWatermarkStats(int atomTag, boolean resetAfterPull) { return mAppProfiler.mCachedAppsWatermarkData.getCachedAppsHighWatermarkStats( atomTag, resetAfterPull); } } long inputDispatchingTimedOut(int pid, final boolean aboveSystem, TimeoutRecord timeoutRecord) {
services/core/java/com/android/server/am/AppProfiler.java +198 −4 File changed.Preview size limit exceeded, changes collapsed. Show changes