Merge "Create DefaultAppsIconProvider" into main
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/composable/ShortcutHelper.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/composable/ShortcutHelper.kt
index 5b9d30e..b703892 100644
--- a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/composable/ShortcutHelper.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/composable/ShortcutHelper.kt
@@ -227,7 +227,7 @@
get() =
when (type) {
ShortcutCategoryType.SYSTEM -> R.string.shortcut_helper_category_system
- ShortcutCategoryType.MULTI_TASKING -> R.string.shortcut_helper_category_system
+ ShortcutCategoryType.MULTI_TASKING -> R.string.shortcut_helper_category_multitasking
ShortcutCategoryType.IME -> R.string.shortcut_helper_category_input
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/view/ShortcutHelperActivity.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/view/ShortcutHelperActivity.kt
index 646db40..d0e3ab4 100644
--- a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/view/ShortcutHelperActivity.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/view/ShortcutHelperActivity.kt
@@ -34,7 +34,6 @@
import androidx.lifecycle.lifecycleScope
import com.android.compose.theme.PlatformTheme
import com.android.systemui.keyboard.shortcut.ui.composable.ShortcutHelper
-import com.android.systemui.keyboard.shortcut.ui.model.ShortcutsUiState
import com.android.systemui.keyboard.shortcut.ui.viewmodel.ShortcutHelperViewModel
import com.android.systemui.res.R
import com.google.android.material.bottomsheet.BottomSheetBehavior
@@ -81,10 +80,7 @@
requireViewById<ComposeView>(R.id.shortcut_helper_compose_container).apply {
setContent {
PlatformTheme {
- val shortcutsUiState by
- viewModel.shortcutsUiState.collectAsStateWithLifecycle(
- initialValue = ShortcutsUiState.Inactive
- )
+ val shortcutsUiState by viewModel.shortcutsUiState.collectAsStateWithLifecycle()
ShortcutHelper(
shortcutsUiState = shortcutsUiState,
onKeyboardSettingsClicked = ::onKeyboardSettingsClicked,
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/viewmodel/ShortcutHelperViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/viewmodel/ShortcutHelperViewModel.kt
index 3759b0c..e602cad 100644
--- a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/viewmodel/ShortcutHelperViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/viewmodel/ShortcutHelperViewModel.kt
@@ -23,13 +23,17 @@
import com.android.systemui.keyboard.shortcut.ui.model.ShortcutsUiState
import javax.inject.Inject
import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.stateIn
class ShortcutHelperViewModel
@Inject
constructor(
+ @Background private val backgroundScope: CoroutineScope,
@Background private val backgroundDispatcher: CoroutineDispatcher,
private val stateInteractor: ShortcutHelperStateInteractor,
categoriesInteractor: ShortcutHelperCategoriesInteractor,
@@ -42,16 +46,22 @@
.flowOn(backgroundDispatcher)
val shortcutsUiState =
- categoriesInteractor.shortcutCategories.map {
- if (it.isEmpty()) {
- ShortcutsUiState.Inactive
- } else {
- ShortcutsUiState.Active(
- shortcutCategories = it,
- defaultSelectedCategory = it.first().type,
- )
+ categoriesInteractor.shortcutCategories
+ .map {
+ if (it.isEmpty()) {
+ ShortcutsUiState.Inactive
+ } else {
+ ShortcutsUiState.Active(
+ shortcutCategories = it,
+ defaultSelectedCategory = it.first().type,
+ )
+ }
}
- }
+ .stateIn(
+ scope = backgroundScope,
+ started = SharingStarted.Lazily,
+ initialValue = ShortcutsUiState.Inactive
+ )
fun onViewClosed() {
stateInteractor.onViewClosed()
diff --git a/packages/SystemUI/src/com/android/systemui/util/settings/SettingsProxy.kt b/packages/SystemUI/src/com/android/systemui/util/settings/SettingsProxy.kt
index 160ae86..fe54044 100644
--- a/packages/SystemUI/src/com/android/systemui/util/settings/SettingsProxy.kt
+++ b/packages/SystemUI/src/com/android/systemui/util/settings/SettingsProxy.kt
@@ -19,6 +19,7 @@
import android.database.ContentObserver
import android.net.Uri
import android.provider.Settings.SettingNotFoundException
+import androidx.annotation.WorkerThread
import com.android.app.tracing.TraceUtils.trace
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
@@ -59,10 +60,13 @@
fun getUriFor(name: String): Uri
/**
- * Convenience wrapper around [ContentResolver.registerContentObserver].'
- *
+ * Registers listener for a given content observer <b>while blocking the current thread</b>.
* Implicitly calls [getUriFor] on the passed in name.
+ *
+ * This should not be called from the main thread, use [registerContentObserver] or
+ * [registerContentObserverAsync] instead.
*/
+ @WorkerThread
fun registerContentObserverSync(name: String, settingsObserver: ContentObserver) {
registerContentObserverSync(getUriFor(name), settingsObserver)
}
@@ -90,7 +94,13 @@
registerContentObserverSync(getUriFor(name), settingsObserver)
}
- /** Convenience wrapper around [ContentResolver.registerContentObserver].' */
+ /**
+ * Registers listener for a given content observer <b>while blocking the current thread</b>.
+ *
+ * This should not be called from the main thread, use [registerContentObserver] or
+ * [registerContentObserverAsync] instead.
+ */
+ @WorkerThread
fun registerContentObserverSync(uri: Uri, settingsObserver: ContentObserver) =
registerContentObserverSync(uri, false, settingsObserver)
@@ -157,7 +167,13 @@
registerContentObserverSync(getUriFor(name), notifyForDescendants, settingsObserver)
}
- /** Convenience wrapper around [ContentResolver.registerContentObserver].' */
+ /**
+ * Registers listener for a given content observer <b>while blocking the current thread</b>.
+ *
+ * This should not be called from the main thread, use [registerContentObserver] or
+ * [registerContentObserverAsync] instead.
+ */
+ @WorkerThread
fun registerContentObserverSync(
uri: Uri,
notifyForDescendants: Boolean,
@@ -200,7 +216,13 @@
registerContentObserverSync(uri, notifyForDescendants, settingsObserver)
}
- /** See [ContentResolver.unregisterContentObserver]. */
+ /**
+ * Unregisters the given content observer <b>while blocking the current thread</b>.
+ *
+ * This should not be called from the main thread, use [unregisterContentObserver] or
+ * [unregisterContentObserverAsync] instead.
+ */
+ @WorkerThread
fun unregisterContentObserverSync(settingsObserver: ContentObserver) {
trace({ "SP#unregisterObserver" }) {
getContentResolver().unregisterContentObserver(settingsObserver)
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyboard/shortcut/KeyboardShortcutHelperKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyboard/shortcut/KeyboardShortcutHelperKosmos.kt
index 55c803a..a1021f6 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyboard/shortcut/KeyboardShortcutHelperKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyboard/shortcut/KeyboardShortcutHelperKosmos.kt
@@ -100,6 +100,7 @@
val Kosmos.shortcutHelperViewModel by
Kosmos.Fixture {
ShortcutHelperViewModel(
+ applicationCoroutineScope,
testDispatcher,
shortcutHelperStateInteractor,
shortcutHelperCategoriesInteractor
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
index fbb6ccf..b0d734d 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
@@ -70,7 +70,6 @@
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.ContentProvider;
-import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
@@ -80,7 +79,6 @@
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
import android.content.res.Resources;
-import android.database.ContentObserver;
import android.hardware.input.InputManager;
import android.inputmethodservice.InputMethodService;
import android.media.AudioManagerInternal;
@@ -195,7 +193,6 @@
import java.security.InvalidParameterException;
import java.util.ArrayList;
import java.util.Arrays;
-import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
@@ -349,8 +346,6 @@
@GuardedBy("ImfLock.class")
private UserDataRepository mUserDataRepository;
- @MultiUserUnawareField
- final SettingsObserver mSettingsObserver;
final WindowManagerInternal mWindowManagerInternal;
private final ActivityManagerInternal mActivityManagerInternal;
final PackageManagerInternal mPackageManagerInternal;
@@ -570,82 +565,52 @@
@NonNull
private final ImeTrackerService mImeTrackerService;
- class SettingsObserver extends ContentObserver {
-
- /**
- * <em>This constructor must be called within the lock.</em>
- */
- SettingsObserver(Handler handler) {
- super(handler);
+ @GuardedBy("ImfLock.class")
+ private void onSecureSettingsChangedLocked(@NonNull String key, @UserIdInt int userId) {
+ if (!mConcurrentMultiUserModeEnabled && userId != mCurrentUserId) {
+ return;
}
-
- void registerContentObserverForAllUsers() {
- ContentResolver resolver = mContext.getContentResolver();
- resolver.registerContentObserverAsUser(Settings.Secure.getUriFor(
- Settings.Secure.DEFAULT_INPUT_METHOD), false, this, UserHandle.ALL);
- resolver.registerContentObserverAsUser(Settings.Secure.getUriFor(
- Settings.Secure.ENABLED_INPUT_METHODS), false, this, UserHandle.ALL);
- resolver.registerContentObserverAsUser(Settings.Secure.getUriFor(
- Settings.Secure.SELECTED_INPUT_METHOD_SUBTYPE), false, this, UserHandle.ALL);
- resolver.registerContentObserverAsUser(Settings.Secure.getUriFor(
- Settings.Secure.SHOW_IME_WITH_HARD_KEYBOARD), false, this, UserHandle.ALL);
- resolver.registerContentObserverAsUser(Settings.Secure.getUriFor(
- Settings.Secure.ACCESSIBILITY_SOFT_KEYBOARD_MODE), false, this, UserHandle.ALL);
- resolver.registerContentObserverAsUser(Settings.Secure.getUriFor(
- STYLUS_HANDWRITING_ENABLED), false, this, UserHandle.ALL);
- }
-
- @Override
- public void onChange(boolean selfChange, @NonNull Collection<Uri> uris, int flags,
- @UserIdInt int userId) {
- uris.forEach(uri -> onChangeInternal(uri, userId));
- }
-
- private void onChangeInternal(@NonNull Uri uri, @UserIdInt int userId) {
- final Uri showImeUri = Settings.Secure.getUriFor(
- Settings.Secure.SHOW_IME_WITH_HARD_KEYBOARD);
- final Uri accessibilityRequestingNoImeUri = Settings.Secure.getUriFor(
- Settings.Secure.ACCESSIBILITY_SOFT_KEYBOARD_MODE);
- final Uri stylusHandwritingEnabledUri = Settings.Secure.getUriFor(
- STYLUS_HANDWRITING_ENABLED);
- synchronized (ImfLock.class) {
- if (!mConcurrentMultiUserModeEnabled && mCurrentUserId != userId) {
- return;
+ switch (key) {
+ case Settings.Secure.SHOW_IME_WITH_HARD_KEYBOARD: {
+ mMenuController.updateKeyboardFromSettingsLocked();
+ break;
+ }
+ case Settings.Secure.ACCESSIBILITY_SOFT_KEYBOARD_MODE: {
+ final int accessibilitySoftKeyboardSetting = Settings.Secure.getIntForUser(
+ mContext.getContentResolver(),
+ Settings.Secure.ACCESSIBILITY_SOFT_KEYBOARD_MODE, 0, userId);
+ mVisibilityStateComputer.getImePolicy().setA11yRequestNoSoftKeyboard(
+ accessibilitySoftKeyboardSetting);
+ final var userData = getUserData(userId);
+ if (mVisibilityStateComputer.getImePolicy().isA11yRequestNoSoftKeyboard()) {
+ hideCurrentInputLocked(userData.mImeBindingState.mFocusedWindow,
+ 0 /* flags */, SoftInputShowHideReason.HIDE_SETTINGS_ON_CHANGE, userId);
+ } else if (isShowRequestedForCurrentWindow(userId)) {
+ showCurrentInputLocked(userData.mImeBindingState.mFocusedWindow,
+ InputMethodManager.SHOW_IMPLICIT,
+ SoftInputShowHideReason.SHOW_SETTINGS_ON_CHANGE, userId);
}
-
- if (showImeUri.equals(uri)) {
- mMenuController.updateKeyboardFromSettingsLocked();
- } else if (accessibilityRequestingNoImeUri.equals(uri)) {
- final int accessibilitySoftKeyboardSetting = Settings.Secure.getIntForUser(
- mContext.getContentResolver(),
- Settings.Secure.ACCESSIBILITY_SOFT_KEYBOARD_MODE, 0, userId);
- mVisibilityStateComputer.getImePolicy().setA11yRequestNoSoftKeyboard(
- accessibilitySoftKeyboardSetting);
- final var userData = getUserData(userId);
- if (mVisibilityStateComputer.getImePolicy().isA11yRequestNoSoftKeyboard()) {
- hideCurrentInputLocked(userData.mImeBindingState.mFocusedWindow,
- 0 /* flags */, SoftInputShowHideReason.HIDE_SETTINGS_ON_CHANGE,
- userId);
- } else if (isShowRequestedForCurrentWindow(userId)) {
- showCurrentInputLocked(userData.mImeBindingState.mFocusedWindow,
- InputMethodManager.SHOW_IMPLICIT,
- SoftInputShowHideReason.SHOW_SETTINGS_ON_CHANGE, userId);
- }
- } else if (stylusHandwritingEnabledUri.equals(uri)) {
- InputMethodManager.invalidateLocalStylusHandwritingAvailabilityCaches();
- InputMethodManager
- .invalidateLocalConnectionlessStylusHandwritingAvailabilityCaches();
- } else {
- boolean enabledChanged = false;
- String newEnabled = InputMethodSettingsRepository.get(userId)
- .getEnabledInputMethodsStr();
- final var userData = getUserData(userId);
- if (!userData.mLastEnabledInputMethodsStr.equals(newEnabled)) {
- userData.mLastEnabledInputMethodsStr = newEnabled;
- enabledChanged = true;
- }
- updateInputMethodsFromSettingsLocked(enabledChanged, userId);
+ break;
+ }
+ case STYLUS_HANDWRITING_ENABLED: {
+ InputMethodManager.invalidateLocalStylusHandwritingAvailabilityCaches();
+ InputMethodManager
+ .invalidateLocalConnectionlessStylusHandwritingAvailabilityCaches();
+ break;
+ }
+ case Settings.Secure.DEFAULT_INPUT_METHOD:
+ case Settings.Secure.ENABLED_INPUT_METHODS:
+ case Settings.Secure.SELECTED_INPUT_METHOD_SUBTYPE: {
+ boolean enabledChanged = false;
+ String newEnabled = InputMethodSettingsRepository.get(userId)
+ .getEnabledInputMethodsStr();
+ final var userData = getUserData(userId);
+ if (!userData.mLastEnabledInputMethodsStr.equals(newEnabled)) {
+ userData.mLastEnabledInputMethodsStr = newEnabled;
+ enabledChanged = true;
}
+ updateInputMethodsFromSettingsLocked(enabledChanged, userId);
+ break;
}
}
}
@@ -1118,8 +1083,6 @@
}
SystemLocaleWrapper.onStart(context, this::onActionLocaleChanged, mHandler);
mImeTrackerService = new ImeTrackerService(mHandler);
- // Note: SettingsObserver doesn't register observers in its constructor.
- mSettingsObserver = new SettingsObserver(mHandler);
mWindowManagerInternal = LocalServices.getService(WindowManagerInternal.class);
mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class);
mPackageManagerInternal = LocalServices.getService(PackageManagerInternal.class);
@@ -1389,7 +1352,19 @@
}, "Lazily initialize IMMS#mImeDrawsImeNavBarRes");
mMyPackageMonitor.register(mContext, UserHandle.ALL, mIoHandler);
- mSettingsObserver.registerContentObserverForAllUsers();
+ SecureSettingsChangeCallback.register(mHandler, mContext.getContentResolver(),
+ new String[] {
+ Settings.Secure.ACCESSIBILITY_SOFT_KEYBOARD_MODE,
+ Settings.Secure.DEFAULT_INPUT_METHOD,
+ Settings.Secure.ENABLED_INPUT_METHODS,
+ Settings.Secure.SELECTED_INPUT_METHOD_SUBTYPE,
+ Settings.Secure.SHOW_IME_WITH_HARD_KEYBOARD,
+ Settings.Secure.STYLUS_HANDWRITING_ENABLED,
+ }, (key, flags, userId) -> {
+ synchronized (ImfLock.class) {
+ onSecureSettingsChangedLocked(key, userId);
+ }
+ });
final IntentFilter broadcastFilterForAllUsers = new IntentFilter();
broadcastFilterForAllUsers.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
diff --git a/services/core/java/com/android/server/inputmethod/SecureSettingsChangeCallback.java b/services/core/java/com/android/server/inputmethod/SecureSettingsChangeCallback.java
new file mode 100644
index 0000000..328d7c6
--- /dev/null
+++ b/services/core/java/com/android/server/inputmethod/SecureSettingsChangeCallback.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.inputmethod;
+
+import android.annotation.NonNull;
+import android.annotation.UserIdInt;
+import android.content.ContentResolver;
+import android.database.ContentObserver;
+import android.net.Uri;
+import android.os.Handler;
+import android.os.UserHandle;
+import android.provider.Settings;
+import android.util.ArrayMap;
+
+import java.util.Collection;
+
+/**
+ * A wrapper interface to monitor the given set of {@link Settings.Secure}.
+ */
+@FunctionalInterface
+interface SecureSettingsChangeCallback {
+ /**
+ * Called back when the value associated with {@code key} is updated.
+ *
+ * @param key a key defined in {@link Settings.Secure}
+ * @param flags flags defined in {@link ContentResolver.NotifyFlags}
+ * @param userId the user ID with which the value is associated
+ */
+ void onChange(@NonNull String key, @ContentResolver.NotifyFlags int flags,
+ @UserIdInt int userId);
+
+ /**
+ * Registers {@link SecureSettingsChangeCallback} to the given set of {@link Settings.Secure}.
+ *
+ * @param handler {@link Handler} to be used to call back {@link #onChange(String, int, int)}
+ * @param resolver {@link ContentResolver} with which {@link Settings.Secure} will be retrieved
+ * @param keys A set of {@link Settings.Secure} to be monitored
+ * @param callback {@link SecureSettingsChangeCallback} to be called back
+ */
+ @NonNull
+ static void register(@NonNull Handler handler, @NonNull ContentResolver resolver,
+ @NonNull String[] keys, @NonNull SecureSettingsChangeCallback callback) {
+ final ArrayMap<Uri, String> uriMapper = new ArrayMap<>();
+ for (String key : keys) {
+ uriMapper.put(Settings.Secure.getUriFor(key), key);
+ }
+ final ContentObserver observer = new ContentObserver(handler) {
+ @Override
+ public void onChange(boolean selfChange, @NonNull Collection<Uri> uris, int flags,
+ @UserIdInt int userId) {
+ uris.forEach(uri -> {
+ final String key = uriMapper.get(uri);
+ if (key != null) {
+ callback.onChange(key, flags, userId);
+ }
+ });
+ }
+ };
+ for (Uri uri : uriMapper.keySet()) {
+ resolver.registerContentObserverAsUser(uri, false /* notifyForDescendants */, observer,
+ UserHandle.ALL);
+ }
+ }
+}
diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java
index edd118d..1d02f1c 100644
--- a/services/core/java/com/android/server/wm/WindowContainer.java
+++ b/services/core/java/com/android/server/wm/WindowContainer.java
@@ -179,7 +179,7 @@
// List of children for this window container. List is in z-order as the children appear on
// screen with the top-most window container at the tail of the list.
- protected final WindowList<E> mChildren = new WindowList<E>();
+ protected final ArrayList<E> mChildren = new ArrayList<E>();
// The specified orientation for this window container.
// Shouldn't be accessed directly since subclasses can override getOverrideOrientation.
@@ -855,7 +855,7 @@
mSurfaceFreezer.unfreeze(getSyncTransaction());
}
while (!mChildren.isEmpty()) {
- final E child = mChildren.peekLast();
+ final E child = mChildren.getLast();
child.removeImmediately();
// Need to do this after calling remove on the child because the child might try to
// remove/detach itself from its parent which will cause an exception if we remove
@@ -979,7 +979,7 @@
switch (position) {
case POSITION_TOP:
- if (mChildren.peekLast() != child) {
+ if (getTopChild() != child) {
mChildren.remove(child);
mChildren.add(child);
onChildPositionChanged(child);
@@ -990,7 +990,7 @@
}
break;
case POSITION_BOTTOM:
- if (mChildren.peekFirst() != child) {
+ if (getBottomChild() != child) {
mChildren.remove(child);
mChildren.addFirst(child);
onChildPositionChanged(child);
@@ -1445,7 +1445,13 @@
/** Returns the top child container. */
E getTopChild() {
- return mChildren.peekLast();
+ final int n = mChildren.size();
+ return n == 0 ? null : mChildren.get(n - 1);
+ }
+
+ E getBottomChild() {
+ final int n = mChildren.size();
+ return n == 0 ? null : mChildren.get(0);
}
/**
@@ -2550,7 +2556,7 @@
}
if (mParent != null && mParent == other.mParent) {
- final WindowList<WindowContainer> list = mParent.mChildren;
+ final ArrayList<WindowContainer> list = mParent.mChildren;
return list.indexOf(this) > list.indexOf(other) ? 1 : -1;
}
@@ -2587,7 +2593,7 @@
// The position of the first non-common ancestor in the common ancestor list determines
// which is greater the which.
- final WindowList<WindowContainer> list = commonAncestor.mChildren;
+ final ArrayList<WindowContainer> list = commonAncestor.mChildren;
return list.indexOf(thisParentChain.peekLast()) > list.indexOf(otherParentChain.peekLast())
? 1 : -1;
} finally {
diff --git a/services/core/java/com/android/server/wm/WindowList.java b/services/core/java/com/android/server/wm/WindowList.java
deleted file mode 100644
index 1e888f5..0000000
--- a/services/core/java/com/android/server/wm/WindowList.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 2017 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.server.wm;
-
-import java.util.ArrayList;
-
-/**
- * An {@link ArrayList} with extended functionality to be used as the children data structure in
- * {@link WindowContainer}.
- */
-class WindowList<E> extends ArrayList<E> {
-
- public void addFirst(E e) {
- add(0, e);
- }
-
- E peekLast() {
- return size() > 0 ? get(size() - 1) : null;
- }
-
- E peekFirst() {
- return size() > 0 ? get(0) : null;
- }
-}
diff --git a/services/core/java/com/android/server/wm/WindowOrganizerController.java b/services/core/java/com/android/server/wm/WindowOrganizerController.java
index deb7098..e900488 100644
--- a/services/core/java/com/android/server/wm/WindowOrganizerController.java
+++ b/services/core/java/com/android/server/wm/WindowOrganizerController.java
@@ -1596,7 +1596,7 @@
case OP_TYPE_REORDER_TO_BOTTOM_OF_TASK: {
final Task task = taskFragment.getTask();
if (task != null) {
- if (task.mChildren.peekFirst() != taskFragment) {
+ if (task.getBottomChild() != taskFragment) {
task.mChildren.remove(taskFragment);
task.mChildren.add(0, taskFragment);
if (!taskFragment.hasChild()) {
@@ -1612,7 +1612,7 @@
case OP_TYPE_REORDER_TO_TOP_OF_TASK: {
final Task task = taskFragment.getTask();
if (task != null) {
- if (task.mChildren.peekLast() != taskFragment) {
+ if (task.getTopChild() != taskFragment) {
task.mChildren.remove(taskFragment);
task.mChildren.add(taskFragment);
if (!taskFragment.hasChild()) {
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
index ef3df6c..2e9726f 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
@@ -2482,10 +2482,10 @@
assertTrue(activity.mChildren.contains(win4));
// The starting window should be on-top of all other windows.
- assertEquals(startingWin, activity.mChildren.peekLast());
+ assertEquals(startingWin, activity.getTopChild());
// The base application window should be below all other windows.
- assertEquals(baseWin, activity.mChildren.peekFirst());
+ assertEquals(baseWin, activity.getBottomChild());
activity.removeImmediately();
}