Merge "Import translations. DO NOT MERGE"
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index bb9bd52..c821774 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -3531,8 +3531,8 @@
}
}
- @VisibleForTesting
- public class SuggestionsPopupWindow extends PinnedPopupWindow implements OnItemClickListener {
+ private final class SuggestionsPopupWindow extends PinnedPopupWindow
+ implements OnItemClickListener {
private static final int MAX_NUMBER_SUGGESTIONS = SuggestionSpan.SUGGESTIONS_MAX_SIZE;
// Key of intent extras for inserting new word into user dictionary.
@@ -3734,11 +3734,6 @@
}
}
- @VisibleForTesting
- public ViewGroup getContentViewForTesting() {
- return mContentView;
- }
-
@Override
public void show() {
if (!(mTextView.getText() instanceof Editable)) return;
@@ -6460,11 +6455,6 @@
return 0 <= start && start <= end && end <= text.length();
}
- @VisibleForTesting
- public SuggestionsPopupWindow getSuggestionsPopupWindowForTesting() {
- return mSuggestionsPopupWindow;
- }
-
/**
* An InputFilter that monitors text input to maintain undo history. It does not modify the
* text being typed (and hence always returns null from the filter() method).
diff --git a/core/jni/android_util_Process.cpp b/core/jni/android_util_Process.cpp
index 26a474c..2d7069c 100644
--- a/core/jni/android_util_Process.cpp
+++ b/core/jni/android_util_Process.cpp
@@ -355,30 +355,34 @@
static void get_cpuset_cores_for_policy(SchedPolicy policy, cpu_set_t *cpu_set)
{
FILE *file;
- const char *filename;
+ std::string filename;
CPU_ZERO(cpu_set);
switch (policy) {
case SP_BACKGROUND:
- filename = "/dev/cpuset/background/cpus";
+ if (!CgroupGetAttributePath("LowCapacityCPUs", &filename)) {
+ return;
+ }
break;
case SP_FOREGROUND:
case SP_AUDIO_APP:
case SP_AUDIO_SYS:
case SP_RT_APP:
- filename = "/dev/cpuset/foreground/cpus";
+ if (!CgroupGetAttributePath("HighCapacityCPUs", &filename)) {
+ return;
+ }
break;
case SP_TOP_APP:
- filename = "/dev/cpuset/top-app/cpus";
+ if (!CgroupGetAttributePath("MaxCapacityCPUs", &filename)) {
+ return;
+ }
break;
default:
- filename = NULL;
+ return;
}
- if (!filename) return;
-
- file = fopen(filename, "re");
+ file = fopen(filename.c_str(), "re");
if (file != NULL) {
// Parse cpus string
char *line = NULL;
@@ -388,7 +392,7 @@
if (num_read > 0) {
parse_cpuset_cpus(line, cpu_set);
} else {
- ALOGE("Failed to read %s", filename);
+ ALOGE("Failed to read %s", filename.c_str());
}
free(line);
}
diff --git a/core/jni/com_android_internal_os_Zygote.cpp b/core/jni/com_android_internal_os_Zygote.cpp
index b7837ef..5a65028 100644
--- a/core/jni/com_android_internal_os_Zygote.cpp
+++ b/core/jni/com_android_internal_os_Zygote.cpp
@@ -1534,15 +1534,12 @@
RuntimeAbort(env, __LINE__, "System server process has died. Restarting Zygote!");
}
- bool low_ram_device = GetBoolProperty("ro.config.low_ram", false);
- bool per_app_memcg = GetBoolProperty("ro.config.per_app_memcg", low_ram_device);
- if (per_app_memcg) {
+ if (UsePerAppMemcg()) {
// Assign system_server to the correct memory cgroup.
- // Not all devices mount /dev/memcg so check for the file first
+ // Not all devices mount memcg so check if it is mounted first
// to avoid unnecessarily printing errors and denials in the logs.
- if (!access("/dev/memcg/system/tasks", F_OK) &&
- !WriteStringToFile(StringPrintf("%d", pid), "/dev/memcg/system/tasks")) {
- ALOGE("couldn't write %d to /dev/memcg/system/tasks", pid);
+ if (!SetTaskProfiles(pid, std::vector<std::string>{"SystemMemoryProcess"})) {
+ ALOGE("couldn't add process %d into system memcg group", pid);
}
}
}
diff --git a/core/res/res/values/colors_car.xml b/core/res/res/values/colors_car.xml
index f4aeff7..82caa26 100644
--- a/core/res/res/values/colors_car.xml
+++ b/core/res/res/values/colors_car.xml
@@ -137,8 +137,8 @@
<color name="car_toast_background">#E6282a2d</color>
<!-- Misc colors -->
- <color name="car_highlight_light">@color/car_teal_200</color>
- <color name="car_highlight_dark">@color/car_teal_200</color>
+ <color name="car_highlight_light">#ff66b5ff</color>
+ <color name="car_highlight_dark">#ff60a8f0</color>
<color name="car_highlight">@color/car_highlight_dark</color>
<color name="car_accent_light">@color/car_highlight_light</color>
<color name="car_accent_dark">@color/car_highlight_dark</color>
diff --git a/media/jni/Android.bp b/media/jni/Android.bp
index f1bb13d..8ed265d 100644
--- a/media/jni/Android.bp
+++ b/media/jni/Android.bp
@@ -48,6 +48,7 @@
"libmtp",
"libexif",
"libpiex",
+ "libprocessgroup",
"libandroidfw",
"libhidlallocatorutils",
"libhidlbase",
@@ -123,6 +124,7 @@
"libbase",
"libcrypto",
"libcutils",
+ "libjsoncpp",
"libmedia_helper",
"libmedia_player2_util",
"libmediaplayer2",
diff --git a/services/core/java/com/android/server/wm/ActivityDisplay.java b/services/core/java/com/android/server/wm/ActivityDisplay.java
index e817dd4..5b3a2fe 100644
--- a/services/core/java/com/android/server/wm/ActivityDisplay.java
+++ b/services/core/java/com/android/server/wm/ActivityDisplay.java
@@ -1267,6 +1267,15 @@
positionChildAt(stack, Math.max(0, insertIndex));
}
+ void ensureActivitiesVisible(ActivityRecord starting, int configChanges,
+ boolean preserveWindows, boolean notifyClients) {
+ for (int stackNdx = getChildCount() - 1; stackNdx >= 0; --stackNdx) {
+ final ActivityStack stack = getChildAt(stackNdx);
+ stack.ensureActivitiesVisibleLocked(starting, configChanges, preserveWindows,
+ notifyClients);
+ }
+ }
+
void moveHomeStackToFront(String reason) {
if (mHomeStack != null) {
mHomeStack.moveToFront(reason);
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index 38e8785..ad76af6 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -3401,6 +3401,16 @@
stack.checkKeyguardVisibility(this, true /* shouldBeVisible */, true /* isTop */);
}
+ /**
+ * Check if this activity is able to resume. For pre-Q apps, only the topmost activities of each
+ * process are allowed to be resumed.
+ *
+ * @return true if this activity can be resumed.
+ */
+ boolean canResumeByCompat() {
+ return app == null || app.updateTopResumingActivityInProcessIfNeeded(this);
+ }
+
boolean getTurnScreenOnFlag() {
return mTurnScreenOn;
}
diff --git a/services/core/java/com/android/server/wm/ActivityStack.java b/services/core/java/com/android/server/wm/ActivityStack.java
index 16c44aa..6fc2014 100644
--- a/services/core/java/com/android/server/wm/ActivityStack.java
+++ b/services/core/java/com/android/server/wm/ActivityStack.java
@@ -2597,6 +2597,10 @@
return false;
}
+ if (!next.canResumeByCompat()) {
+ return false;
+ }
+
// If we are sleeping, and there is no resumed activity, and the top
// activity is paused, well that is the state we want.
if (shouldSleepOrShutDownActivities()
diff --git a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
index c8a150b..c0fe6e9 100644
--- a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
@@ -720,6 +720,11 @@
r.setProcess(proc);
+ // Ensure activity is allowed to be resumed after process has set.
+ if (andResume && !r.canResumeByCompat()) {
+ andResume = false;
+ }
+
if (getKeyguardController().isKeyguardLocked()) {
r.notifyUnknownVisibilityLaunched();
}
diff --git a/services/core/java/com/android/server/wm/RootActivityContainer.java b/services/core/java/com/android/server/wm/RootActivityContainer.java
index 624fdc2..ecab1f1 100644
--- a/services/core/java/com/android/server/wm/RootActivityContainer.java
+++ b/services/core/java/com/android/server/wm/RootActivityContainer.java
@@ -777,11 +777,8 @@
// First the front stacks. In case any are not fullscreen and are in front of home.
for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
final ActivityDisplay display = mActivityDisplays.get(displayNdx);
- for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
- final ActivityStack stack = display.getChildAt(stackNdx);
- stack.ensureActivitiesVisibleLocked(starting, configChanges, preserveWindows,
- notifyClients);
- }
+ display.ensureActivitiesVisible(starting, configChanges, preserveWindows,
+ notifyClients);
}
} finally {
mStackSupervisor.getKeyguardController().endActivityVisibilityUpdate();
diff --git a/services/core/java/com/android/server/wm/TaskTapPointerEventListener.java b/services/core/java/com/android/server/wm/TaskTapPointerEventListener.java
index dd94af6..4ff552e 100644
--- a/services/core/java/com/android/server/wm/TaskTapPointerEventListener.java
+++ b/services/core/java/com/android/server/wm/TaskTapPointerEventListener.java
@@ -22,6 +22,8 @@
import static android.view.PointerIcon.TYPE_TOP_RIGHT_DIAGONAL_DOUBLE_ARROW;
import static android.view.PointerIcon.TYPE_VERTICAL_DOUBLE_ARROW;
+import static com.android.server.wm.ActivityStackSupervisor.PRESERVE_WINDOWS;
+
import android.graphics.Rect;
import android.graphics.Region;
import android.hardware.input.InputManager;
@@ -86,6 +88,16 @@
if (parent != null && parent.getTopChild() != mDisplayContent) {
parent.positionChildAt(WindowContainer.POSITION_TOP, mDisplayContent,
true /* includingParents */);
+ // For compatibility, only the topmost activity is allowed to be resumed for
+ // pre-Q app. Ensure the topmost activities are resumed whenever a display is
+ // moved to top.
+ // TODO(b/123761773): Investigate whether we can move this into
+ // RootActivityContainer#updateTopResumedActivityIfNeeded(). Currently, it is
+ // risky to do so because it seems possible to resume activities as part of a
+ // larger transaction and it's too early to resume based on current order
+ // when performing updateTopResumedActivityIfNeeded().
+ mDisplayContent.mAcitvityDisplay.ensureActivitiesVisible(null /* starting */,
+ 0 /* configChanges */, !PRESERVE_WINDOWS, true /* notifyClients */);
}
}
};
diff --git a/services/core/java/com/android/server/wm/WindowProcessController.java b/services/core/java/com/android/server/wm/WindowProcessController.java
index 37e2200..0fb900a 100644
--- a/services/core/java/com/android/server/wm/WindowProcessController.java
+++ b/services/core/java/com/android/server/wm/WindowProcessController.java
@@ -17,6 +17,7 @@
package com.android.server.wm;
import static android.app.ActivityManager.PROCESS_STATE_NONEXISTENT;
+import static android.os.Build.VERSION_CODES.Q;
import static android.view.Display.INVALID_DISPLAY;
import static com.android.server.am.ActivityManagerService.MY_PID;
@@ -32,11 +33,11 @@
import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_RELEASE;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
-import static com.android.server.wm.ActivityTaskManagerService
- .INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT_MS;
+import static com.android.server.wm.ActivityTaskManagerService.INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT_MS;
import static com.android.server.wm.ActivityTaskManagerService.KEY_DISPATCHING_TIMEOUT_MS;
import static com.android.server.wm.ActivityTaskManagerService.RELAUNCH_REASON_NONE;
+import android.annotation.NonNull;
import android.app.Activity;
import android.app.ActivityThread;
import android.app.IApplicationThread;
@@ -155,6 +156,8 @@
private final ArrayList<ActivityRecord> mActivities = new ArrayList<>();
// any tasks this process had run root activities in
private final ArrayList<TaskRecord> mRecentTasks = new ArrayList<>();
+ // The most recent top-most activity that was resumed in the process for pre-Q app.
+ private ActivityRecord mPreQTopResumedActivity = null;
// Last configuration that was reported to the process.
private final Configuration mLastReportedConfiguration;
@@ -462,6 +465,59 @@
}
}
+ /**
+ * Update the top resuming activity in process for pre-Q apps, only the top-most visible
+ * activities are allowed to be resumed per process.
+ * @return {@code true} if the activity is allowed to be resumed by compatibility
+ * restrictions, which the activity was the topmost visible activity in process or the app is
+ * targeting after Q.
+ */
+ boolean updateTopResumingActivityInProcessIfNeeded(@NonNull ActivityRecord activity) {
+ if (mInfo.targetSdkVersion >= Q || mPreQTopResumedActivity == activity) {
+ return true;
+ }
+
+ final ActivityDisplay display = activity.getDisplay();
+ if (display == null) {
+ // No need to update if the activity hasn't attach to any display.
+ return false;
+ }
+
+ boolean canUpdate = false;
+ final ActivityDisplay topDisplay =
+ mPreQTopResumedActivity != null ? mPreQTopResumedActivity.getDisplay() : null;
+ // Update the topmost activity if current top activity was not on any display or no
+ // longer visible.
+ if (topDisplay == null || !mPreQTopResumedActivity.visible) {
+ canUpdate = true;
+ }
+
+ // Update the topmost activity if the current top activity wasn't on top of the other one.
+ if (!canUpdate && topDisplay.mDisplayContent.compareTo(display.mDisplayContent) < 0) {
+ canUpdate = true;
+ }
+
+ // Compare the z-order of ActivityStacks if both activities landed on same display.
+ if (display == topDisplay
+ && mPreQTopResumedActivity.getActivityStack().mTaskStack.compareTo(
+ activity.getActivityStack().mTaskStack) <= 0) {
+ canUpdate = true;
+ }
+
+ if (canUpdate) {
+ // Make sure the previous top activity in the process no longer be resumed.
+ if (mPreQTopResumedActivity != null && mPreQTopResumedActivity.isState(RESUMED)) {
+ final ActivityStack stack = mPreQTopResumedActivity.getActivityStack();
+ if (stack != null) {
+ stack.startPausingLocked(false /* userLeaving */, false /* uiSleeping */,
+ null /* resuming */, false /* pauseImmediately */);
+ }
+ }
+ mPreQTopResumedActivity = activity;
+ }
+ return canUpdate;
+ }
+
public void stopFreezingActivities() {
synchronized (mAtm.mGlobalLock) {
int i = mActivities.size();