summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java17
-rw-r--r--apex/statsd/aidl/Android.bp1
-rw-r--r--cmds/statsd/Android.bp9
-rw-r--r--core/java/android/app/QueuedWork.java6
-rw-r--r--core/java/android/view/ImeFocusController.java10
-rw-r--r--core/java/android/view/inputmethod/InputMethodManager.java57
-rw-r--r--core/java/android/window/DisplayAreaOrganizer.java8
-rw-r--r--core/java/com/android/internal/inputmethod/InputMethodDebug.java8
-rw-r--r--core/java/com/android/internal/inputmethod/StartInputReason.java8
-rw-r--r--libs/WindowManager/Shell/res/layout/pip_menu_activity.xml42
-rw-r--r--libs/WindowManager/Shell/res/values/dimen.xml3
-rw-r--r--packages/SystemUI/src/com/android/systemui/bubbles/Bubble.java16
-rw-r--r--packages/SystemUI/src/com/android/systemui/bubbles/BubbleData.java27
-rw-r--r--packages/SystemUI/src/com/android/systemui/bubbles/BubbleLoggerImpl.java49
-rw-r--r--packages/SystemUI/src/com/android/systemui/bubbles/BubbleOverflow.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java24
-rw-r--r--packages/SystemUI/src/com/android/systemui/bubbles/BubbleViewProvider.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/dagger/SystemUIRootComponent.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java19
-rw-r--r--packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivityController.java16
-rw-r--r--packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuIconsAlgorithm.java90
-rw-r--r--packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java10
-rw-r--r--packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java2
-rw-r--r--services/core/java/com/android/server/net/NetworkPolicyManagerService.java3
-rw-r--r--services/core/java/com/android/server/policy/WindowManagerPolicy.java8
-rw-r--r--services/core/java/com/android/server/wm/ActivityRecord.java16
-rw-r--r--services/core/java/com/android/server/wm/ActivityStack.java10
-rw-r--r--services/core/java/com/android/server/wm/BarController.java17
-rw-r--r--services/core/java/com/android/server/wm/DisplayAreaPolicy.java25
-rw-r--r--services/core/java/com/android/server/wm/DisplayPolicy.java35
-rw-r--r--services/core/java/com/android/server/wm/Letterbox.java33
-rw-r--r--services/core/java/com/android/server/wm/RootWindowContainer.java15
-rw-r--r--services/core/java/com/android/server/wm/WindowState.java9
-rw-r--r--services/core/java/com/android/server/wm/WindowStateAnimator.java6
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/am/ApplicationExitInfoTest.java71
-rw-r--r--services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java4
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java34
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/DisplayAreaPolicyBuilderTest.java35
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/LetterboxTest.java99
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/RootActivityContainerTests.java24
-rw-r--r--tools/stats_log_api_gen/Android.bp20
-rw-r--r--tools/stats_log_api_gen/native_writer.cpp190
-rw-r--r--tools/stats_log_api_gen/utils.cpp4
-rw-r--r--tools/stats_log_api_gen/utils.h2
45 files changed, 773 insertions, 326 deletions
diff --git a/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java b/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java
index 24436ea5180b..f40f244e69e5 100644
--- a/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java
+++ b/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java
@@ -488,7 +488,7 @@ public class AppStandbyController implements AppStandbyInternal {
mSystemServicesReady = true;
// Offload to handler thread to avoid boot time impact.
- mHandler.post(mInjector::updatePowerWhitelistCache);
+ mHandler.post(AppStandbyController.this::updatePowerWhitelistCache);
boolean userFileExists;
synchronized (mAppIdleLock) {
@@ -1716,6 +1716,14 @@ public class AppStandbyController implements AppStandbyInternal {
}
}
+ private void updatePowerWhitelistCache() {
+ if (mInjector.getBootPhase() < PHASE_SYSTEM_SERVICES_READY) {
+ return;
+ }
+ mInjector.updatePowerWhitelistCache();
+ postCheckIdleStates(UserHandle.USER_ALL);
+ }
+
private class PackageReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
@@ -2029,10 +2037,7 @@ public class AppStandbyController implements AppStandbyInternal {
}
}
- private void updatePowerWhitelistCache() {
- if (mBootPhase < PHASE_SYSTEM_SERVICES_READY) {
- return;
- }
+ void updatePowerWhitelistCache() {
try {
// Don't call out to DeviceIdleController with the lock held.
final String[] whitelistedPkgs =
@@ -2232,7 +2237,7 @@ public class AppStandbyController implements AppStandbyInternal {
break;
case PowerManager.ACTION_POWER_SAVE_WHITELIST_CHANGED:
if (mSystemServicesReady) {
- mHandler.post(mInjector::updatePowerWhitelistCache);
+ mHandler.post(AppStandbyController.this::updatePowerWhitelistCache);
}
break;
}
diff --git a/apex/statsd/aidl/Android.bp b/apex/statsd/aidl/Android.bp
index f66cf7c9e23c..04339e67d799 100644
--- a/apex/statsd/aidl/Android.bp
+++ b/apex/statsd/aidl/Android.bp
@@ -30,7 +30,6 @@ aidl_interface {
"android/os/StatsDimensionsValueParcel.aidl",
"android/util/StatsEventParcel.aidl",
],
- host_supported: true,
backend: {
java: {
enabled: false, // framework-statsd and service-statsd use framework-statsd-aidl-sources
diff --git a/cmds/statsd/Android.bp b/cmds/statsd/Android.bp
index 1579715727ac..124f815f51f0 100644
--- a/cmds/statsd/Android.bp
+++ b/cmds/statsd/Android.bp
@@ -171,8 +171,7 @@ cc_library_static {
export_generated_headers: ["statslog_statsdtest.h"],
shared_libs: [
"libstatssocket",
- "libstatspull",
- ],
+ ]
}
cc_library_static {
@@ -186,11 +185,7 @@ cc_library_static {
],
shared_libs: [
"libstatssocket",
- "libstatspull",
- ],
- export_shared_lib_headers: [
- "libstatspull",
- ],
+ ]
}
// =========
diff --git a/core/java/android/app/QueuedWork.java b/core/java/android/app/QueuedWork.java
index 82cc2c4daa0b..a1fcf53a2c37 100644
--- a/core/java/android/app/QueuedWork.java
+++ b/core/java/android/app/QueuedWork.java
@@ -80,7 +80,7 @@ public class QueuedWork {
/** Work queued via {@link #queue} */
@GuardedBy("sLock")
- private static final LinkedList<Runnable> sWork = new LinkedList<>();
+ private static LinkedList<Runnable> sWork = new LinkedList<>();
/** If new work can be delayed or not */
@GuardedBy("sLock")
@@ -252,8 +252,8 @@ public class QueuedWork {
LinkedList<Runnable> work;
synchronized (sLock) {
- work = (LinkedList<Runnable>) sWork.clone();
- sWork.clear();
+ work = sWork;
+ sWork = new LinkedList<>();
// Remove all msg-s as all work will be processed now
getHandler().removeMessages(QueuedWorkHandler.MSG_RUN);
diff --git a/core/java/android/view/ImeFocusController.java b/core/java/android/view/ImeFocusController.java
index ad43f9556d8d..92772c1d7a44 100644
--- a/core/java/android/view/ImeFocusController.java
+++ b/core/java/android/view/ImeFocusController.java
@@ -125,10 +125,10 @@ public final class ImeFocusController {
final View viewForWindowFocus = focusedView != null ? focusedView : mViewRootImpl.mView;
onViewFocusChanged(viewForWindowFocus, true);
- // Starting new input when the next focused view is same as served view but the
- // editor is not aligned with the same editor or editor is inactive.
- final boolean nextFocusIsServedView = mServedView != null && mServedView == focusedView;
- if (nextFocusIsServedView && !immDelegate.isSameEditorAndAcceptingText(focusedView)) {
+ // Starting new input when the next focused view is same as served view but the currently
+ // active connection (if any) is not associated with it.
+ final boolean nextFocusIsServedView = mServedView == viewForWindowFocus;
+ if (nextFocusIsServedView && !immDelegate.hasActiveConnection(viewForWindowFocus)) {
forceFocus = true;
}
@@ -254,7 +254,7 @@ public final class ImeFocusController {
void setCurrentRootView(ViewRootImpl rootView);
boolean isCurrentRootView(ViewRootImpl rootView);
boolean isRestartOnNextWindowFocus(boolean reset);
- boolean isSameEditorAndAcceptingText(View view);
+ boolean hasActiveConnection(View view);
}
public View getServedView() {
diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java
index 599a7c24e8aa..793d94097862 100644
--- a/core/java/android/view/inputmethod/InputMethodManager.java
+++ b/core/java/android/view/inputmethod/InputMethodManager.java
@@ -19,8 +19,8 @@ package android.view.inputmethod;
import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
import static android.Manifest.permission.WRITE_SECURE_SETTINGS;
-import static com.android.internal.inputmethod.StartInputReason.WINDOW_FOCUS_GAIN_REPORT_WITHOUT_EDITOR;
-import static com.android.internal.inputmethod.StartInputReason.WINDOW_FOCUS_GAIN_REPORT_WITH_SAME_EDITOR;
+import static com.android.internal.inputmethod.StartInputReason.WINDOW_FOCUS_GAIN_REPORT_WITHOUT_CONNECTION;
+import static com.android.internal.inputmethod.StartInputReason.WINDOW_FOCUS_GAIN_REPORT_WITH_CONNECTION;
import android.annotation.DrawableRes;
import android.annotation.NonNull;
@@ -89,6 +89,7 @@ import com.android.internal.view.InputBindResult;
import java.io.FileDescriptor;
import java.io.PrintWriter;
+import java.lang.ref.WeakReference;
import java.lang.reflect.Proxy;
import java.util.Arrays;
import java.util.Collections;
@@ -610,14 +611,13 @@ public final class InputMethodManager {
@Override
public void startInputAsyncOnWindowFocusGain(View focusedView,
@SoftInputModeFlags int softInputMode, int windowFlags, boolean forceNewFocus) {
- final boolean forceNewFocus1 = forceNewFocus;
final int startInputFlags = getStartInputFlags(focusedView, 0);
final ImeFocusController controller = getFocusController();
if (controller == null) {
return;
}
- if (controller.checkFocus(forceNewFocus1, false)) {
+ if (controller.checkFocus(forceNewFocus, false)) {
// We need to restart input on the current focus view. This
// should be done in conjunction with telling the system service
// about the window gaining focus, to help make the transition
@@ -633,15 +633,15 @@ public final class InputMethodManager {
// we'll just do a window focus gain and call it a day.
try {
View servedView = controller.getServedView();
- boolean nextFocusSameEditor = servedView != null && servedView == focusedView
- && isSameEditorAndAcceptingText(focusedView);
+ boolean nextFocusHasConnection = servedView != null && servedView == focusedView
+ && hasActiveConnection(focusedView);
if (DEBUG) {
Log.v(TAG, "Reporting focus gain, without startInput"
- + ", nextFocusIsServedView=" + nextFocusSameEditor);
+ + ", nextFocusIsServedView=" + nextFocusHasConnection);
}
final int startInputReason =
- nextFocusSameEditor ? WINDOW_FOCUS_GAIN_REPORT_WITH_SAME_EDITOR
- : WINDOW_FOCUS_GAIN_REPORT_WITHOUT_EDITOR;
+ nextFocusHasConnection ? WINDOW_FOCUS_GAIN_REPORT_WITH_CONNECTION
+ : WINDOW_FOCUS_GAIN_REPORT_WITHOUT_CONNECTION;
mService.startInputOrWindowGainedFocus(
startInputReason, mClient,
focusedView.getWindowToken(), startInputFlags, softInputMode,
@@ -701,33 +701,24 @@ public final class InputMethodManager {
}
/**
- * For {@link ImeFocusController} to check if the given focused view aligns with the same
- * editor and the editor is active to accept the text input.
+ * Checks whether the active input connection (if any) is for the given view.
*
- * TODO(b/160968797): Remove this method and move mCurrentTextBoxAttritube to
+ * TODO(b/160968797): Remove this method and move mServedInputConnectionWrapper to
* ImeFocusController.
- * In the long-term, we should make mCurrentTextBoxAtrtribue as per-window base instance,
- * so that we we can directly check if the current focused view aligned with the same editor
- * in the window without using this checking.
*
- * Note that this method is only use for fixing start new input may ignored issue
+ * Note that this method is only intended for restarting input after focus gain
* (e.g. b/160391516), DO NOT leverage this method to do another check.
*/
- public boolean isSameEditorAndAcceptingText(View view) {
+ @Override
+ public boolean hasActiveConnection(View view) {
synchronized (mH) {
- if (!hasServedByInputMethodLocked(view) || mCurrentTextBoxAttribute == null) {
+ if (!hasServedByInputMethodLocked(view)) {
return false;
}
- final EditorInfo ic = mCurrentTextBoxAttribute;
- // This sameEditor checking is based on using object hash comparison to check if
- // some fields of the current EditorInfo (e.g. autoFillId, OpPackageName) the
- // hash code is same as the given focused view.
- final boolean sameEditor = view.onCheckIsTextEditor() && view.getId() == ic.fieldId
- && view.getAutofillId() == ic.autofillId
- && view.getContext().getOpPackageName() == ic.packageName;
- return sameEditor && mServedInputConnectionWrapper != null
- && mServedInputConnectionWrapper.isActive();
+ return mServedInputConnectionWrapper != null
+ && mServedInputConnectionWrapper.isActive()
+ && mServedInputConnectionWrapper.mServedView.get() == view;
}
}
}
@@ -980,11 +971,13 @@ public final class InputMethodManager {
private static class ControlledInputConnectionWrapper extends IInputConnectionWrapper {
private final InputMethodManager mParentInputMethodManager;
+ private final WeakReference<View> mServedView;
- public ControlledInputConnectionWrapper(final Looper mainLooper, final InputConnection conn,
- final InputMethodManager inputMethodManager) {
+ ControlledInputConnectionWrapper(Looper mainLooper, InputConnection conn,
+ InputMethodManager inputMethodManager, View servedView) {
super(mainLooper, conn);
mParentInputMethodManager = inputMethodManager;
+ mServedView = new WeakReference<>(servedView);
}
@Override
@@ -1007,6 +1000,7 @@ public final class InputMethodManager {
+ "connection=" + getInputConnection()
+ " finished=" + isFinished()
+ " mParentInputMethodManager.mActive=" + mParentInputMethodManager.mActive
+ + " mServedView=" + mServedView.get()
+ "}";
}
}
@@ -1187,7 +1181,8 @@ public final class InputMethodManager {
mMainLooper = looper;
mH = new H(looper);
mDisplayId = displayId;
- mIInputContext = new ControlledInputConnectionWrapper(looper, mDummyInputConnection, this);
+ mIInputContext = new ControlledInputConnectionWrapper(looper, mDummyInputConnection, this,
+ null);
}
/**
@@ -1970,7 +1965,7 @@ public final class InputMethodManager {
icHandler = ic.getHandler();
}
servedContext = new ControlledInputConnectionWrapper(
- icHandler != null ? icHandler.getLooper() : vh.getLooper(), ic, this);
+ icHandler != null ? icHandler.getLooper() : vh.getLooper(), ic, this, view);
} else {
servedContext = null;
missingMethodFlags = 0;
diff --git a/core/java/android/window/DisplayAreaOrganizer.java b/core/java/android/window/DisplayAreaOrganizer.java
index 3daf6d371450..f035d36a0f71 100644
--- a/core/java/android/window/DisplayAreaOrganizer.java
+++ b/core/java/android/window/DisplayAreaOrganizer.java
@@ -68,6 +68,14 @@ public class DisplayAreaOrganizer extends WindowOrganizer {
public static final int FEATURE_WINDOWED_MAGNIFICATION = FEATURE_SYSTEM_FIRST + 4;
/**
+ * Display area that can be magnified in
+ * {@link Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN}. This is different from
+ * {@link #FEATURE_WINDOWED_MAGNIFICATION} that the whole display will be magnified.
+ * @hide
+ */
+ public static final int FEATURE_FULLSCREEN_MAGNIFICATION = FEATURE_SYSTEM_FIRST + 5;
+
+ /**
* The last boundary of display area for system features
*/
public static final int FEATURE_SYSTEM_LAST = 10_000;
diff --git a/core/java/com/android/internal/inputmethod/InputMethodDebug.java b/core/java/com/android/internal/inputmethod/InputMethodDebug.java
index 085cdfcf9462..37f68233db53 100644
--- a/core/java/com/android/internal/inputmethod/InputMethodDebug.java
+++ b/core/java/com/android/internal/inputmethod/InputMethodDebug.java
@@ -46,10 +46,10 @@ public final class InputMethodDebug {
return "UNSPECIFIED";
case StartInputReason.WINDOW_FOCUS_GAIN:
return "WINDOW_FOCUS_GAIN";
- case StartInputReason.WINDOW_FOCUS_GAIN_REPORT_WITH_SAME_EDITOR:
- return "WINDOW_FOCUS_GAIN_REPORT_WITH_SAME_EDITOR";
- case StartInputReason.WINDOW_FOCUS_GAIN_REPORT_WITHOUT_EDITOR:
- return "WINDOW_FOCUS_GAIN_REPORT_WITHOUT_EDITOR";
+ case StartInputReason.WINDOW_FOCUS_GAIN_REPORT_WITH_CONNECTION:
+ return "WINDOW_FOCUS_GAIN_REPORT_WITH_CONNECTION";
+ case StartInputReason.WINDOW_FOCUS_GAIN_REPORT_WITHOUT_CONNECTION:
+ return "WINDOW_FOCUS_GAIN_REPORT_WITHOUT_CONNECTION";
case StartInputReason.APP_CALLED_RESTART_INPUT_API:
return "APP_CALLED_RESTART_INPUT_API";
case StartInputReason.CHECK_FOCUS:
diff --git a/core/java/com/android/internal/inputmethod/StartInputReason.java b/core/java/com/android/internal/inputmethod/StartInputReason.java
index 946ce858c12d..2ba708dd9312 100644
--- a/core/java/com/android/internal/inputmethod/StartInputReason.java
+++ b/core/java/com/android/internal/inputmethod/StartInputReason.java
@@ -30,8 +30,8 @@ import java.lang.annotation.Retention;
@IntDef(value = {
StartInputReason.UNSPECIFIED,
StartInputReason.WINDOW_FOCUS_GAIN,
- StartInputReason.WINDOW_FOCUS_GAIN_REPORT_WITH_SAME_EDITOR,
- StartInputReason.WINDOW_FOCUS_GAIN_REPORT_WITHOUT_EDITOR,
+ StartInputReason.WINDOW_FOCUS_GAIN_REPORT_WITH_CONNECTION,
+ StartInputReason.WINDOW_FOCUS_GAIN_REPORT_WITHOUT_CONNECTION,
StartInputReason.APP_CALLED_RESTART_INPUT_API,
StartInputReason.CHECK_FOCUS,
StartInputReason.BOUND_TO_IMMS,
@@ -54,13 +54,13 @@ public @interface StartInputReason {
* view and its input connection remains. {@link android.view.inputmethod.InputMethodManager}
* just reports this window focus change event to sync IME input target for system.
*/
- int WINDOW_FOCUS_GAIN_REPORT_WITH_SAME_EDITOR = 2;
+ int WINDOW_FOCUS_GAIN_REPORT_WITH_CONNECTION = 2;
/**
* {@link android.view.Window} gained focus but there is no {@link android.view.View} that is
* eligible to have IME focus. {@link android.view.inputmethod.InputMethodManager} just reports
* this window focus change event for logging.
*/
- int WINDOW_FOCUS_GAIN_REPORT_WITHOUT_EDITOR = 3;
+ int WINDOW_FOCUS_GAIN_REPORT_WITHOUT_CONNECTION = 3;
/**
* {@link android.view.inputmethod.InputMethodManager#restartInput(android.view.View)} is
* either explicitly called by the application or indirectly called by some Framework class
diff --git a/libs/WindowManager/Shell/res/layout/pip_menu_activity.xml b/libs/WindowManager/Shell/res/layout/pip_menu_activity.xml
index 18064b547d4d..2e0a5e09e34f 100644
--- a/libs/WindowManager/Shell/res/layout/pip_menu_activity.xml
+++ b/libs/WindowManager/Shell/res/layout/pip_menu_activity.xml
@@ -62,25 +62,30 @@
</FrameLayout>
</FrameLayout>
- <ImageButton
- android:id="@+id/settings"
- android:layout_width="@dimen/pip_action_size"
- android:layout_height="@dimen/pip_action_size"
- android:layout_gravity="top|start"
- android:padding="@dimen/pip_action_padding"
- android:contentDescription="@string/pip_phone_settings"
- android:src="@drawable/pip_ic_settings"
- android:background="?android:selectableItemBackgroundBorderless" />
-
- <ImageButton
- android:id="@+id/dismiss"
- android:layout_width="@dimen/pip_action_size"
- android:layout_height="@dimen/pip_action_size"
+ <LinearLayout
+ android:id="@+id/top_end_container"
android:layout_gravity="top|end"
- android:padding="@dimen/pip_action_padding"
- android:contentDescription="@string/pip_phone_close"
- android:src="@drawable/pip_ic_close_white"
- android:background="?android:selectableItemBackgroundBorderless" />
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal">
+ <ImageButton
+ android:id="@+id/settings"
+ android:layout_width="@dimen/pip_action_size"
+ android:layout_height="@dimen/pip_action_size"
+ android:padding="@dimen/pip_action_padding"
+ android:contentDescription="@string/pip_phone_settings"
+ android:src="@drawable/pip_ic_settings"
+ android:background="?android:selectableItemBackgroundBorderless" />
+
+ <ImageButton
+ android:id="@+id/dismiss"
+ android:layout_width="@dimen/pip_action_size"
+ android:layout_height="@dimen/pip_action_size"
+ android:padding="@dimen/pip_action_padding"
+ android:contentDescription="@string/pip_phone_close"
+ android:src="@drawable/pip_ic_close_white"
+ android:background="?android:selectableItemBackgroundBorderless" />
+ </LinearLayout>
<!--TODO (b/156917828): Add content description for a11y purposes?-->
<ImageButton
@@ -89,6 +94,7 @@
android:layout_height="@dimen/pip_resize_handle_size"
android:layout_gravity="top|start"
android:layout_margin="@dimen/pip_resize_handle_margin"
+ android:padding="@dimen/pip_resize_handle_padding"
android:src="@drawable/pip_resize_handle"
android:background="?android:selectableItemBackgroundBorderless" />
</FrameLayout>
diff --git a/libs/WindowManager/Shell/res/values/dimen.xml b/libs/WindowManager/Shell/res/values/dimen.xml
index 48c3cad596f1..1c1217681b9f 100644
--- a/libs/WindowManager/Shell/res/values/dimen.xml
+++ b/libs/WindowManager/Shell/res/values/dimen.xml
@@ -52,7 +52,8 @@
<!-- The touchable/draggable edge size for PIP resize. -->
<dimen name="pip_resize_edge_size">48dp</dimen>
- <!-- PIP Resize handle size and margin. -->
+ <!-- PIP Resize handle size, margin and padding. -->
<dimen name="pip_resize_handle_size">12dp</dimen>
<dimen name="pip_resize_handle_margin">4dp</dimen>
+ <dimen name="pip_resize_handle_padding">0dp</dimen>
</resources>
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/Bubble.java b/packages/SystemUI/src/com/android/systemui/bubbles/Bubble.java
index c6d128631930..87489262a420 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/Bubble.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/Bubble.java
@@ -712,22 +712,6 @@ class Bubble implements BubbleViewProvider {
return Objects.hash(mKey);
}
- @Override
- public void logUIEvent(int bubbleCount, int action, float normalX, float normalY, int index) {
- SysUiStatsLog.write(SysUiStatsLog.BUBBLE_UI_CHANGED,
- mPackageName,
- mChannelId,
- mNotificationId,
- index,
- bubbleCount,
- action,
- normalX,
- normalY,
- showInShade(),
- false /* isOngoing (unused) */,
- false /* isAppForeground (unused) */);
- }
-
@Nullable
private static String getTitle(@NonNull final NotificationEntry e) {
final CharSequence titleCharSeq = e.getSbn().getNotification().extras.getCharSequence(
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleData.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleData.java
index d2dc506c8e5c..10f4385ed443 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleData.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleData.java
@@ -34,6 +34,7 @@ import androidx.annotation.Nullable;
import com.android.internal.annotations.VisibleForTesting;
import com.android.systemui.R;
import com.android.systemui.bubbles.BubbleController.DismissReason;
+import com.android.systemui.shared.system.SysUiStatsLog;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
@@ -59,7 +60,7 @@ import javax.inject.Singleton;
@Singleton
public class BubbleData {
- private BubbleLogger mLogger = new BubbleLoggerImpl();
+ private BubbleLoggerImpl mLogger = new BubbleLoggerImpl();
private static final String TAG = TAG_WITH_CLASS_NAME ? "BubbleData" : TAG_BUBBLES;
@@ -611,6 +612,30 @@ public class BubbleData {
}
/**
+ * Logs the bubble UI event.
+ *
+ * @param provider The bubble view provider that is being interacted on. Null value indicates
+ * that the user interaction is not specific to one bubble.
+ * @param action The user interaction enum
+ * @param packageName SystemUI package
+ * @param bubbleCount Number of bubbles in the stack
+ * @param bubbleIndex Index of bubble in the stack
+ * @param normalX Normalized x position of the stack
+ * @param normalY Normalized y position of the stack
+ */
+ void logBubbleEvent(@Nullable BubbleViewProvider provider, int action, String packageName,
+ int bubbleCount, int bubbleIndex, float normalX, float normalY) {
+ if (provider == null) {
+ mLogger.logStackUiChanged(packageName, action, bubbleCount, normalX, normalY);
+ } else if (provider.getKey().equals(BubbleOverflow.KEY)) {
+ mLogger.logShowOverflow(packageName, action, bubbleCount, normalX, normalY);
+ } else {
+ mLogger.logBubbleUiChanged((Bubble) provider, packageName, action, bubbleCount, normalX,
+ normalY, bubbleIndex);
+ }
+ }
+
+ /**
* Requests a change to the expanded state.
*
* @param shouldExpand the new requested state
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleLoggerImpl.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleLoggerImpl.java
index c1dd8c36ff6f..d702cc4e0062 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleLoggerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleLoggerImpl.java
@@ -17,6 +17,7 @@
package com.android.systemui.bubbles;
import com.android.internal.logging.UiEventLoggerImpl;
+import com.android.systemui.shared.system.SysUiStatsLog;
/**
* Implementation of UiEventLogger for logging bubble UI events.
@@ -64,4 +65,52 @@ public class BubbleLoggerImpl extends UiEventLoggerImpl implements BubbleLogger
log(b, Event.BUBBLE_OVERFLOW_ADD_USER_GESTURE);
}
}
+
+ void logStackUiChanged(String packageName, int action, int bubbleCount, float normalX,
+ float normalY) {
+ SysUiStatsLog.write(SysUiStatsLog.BUBBLE_UI_CHANGED,
+ packageName,
+ null /* notification channel */,
+ 0 /* notification ID */,
+ 0 /* bubble position */,
+ bubbleCount,
+ action,
+ normalX,
+ normalY,
+ false /* unread bubble */,
+ false /* on-going bubble */,
+ false /* isAppForeground (unused) */);
+ }
+
+ void logShowOverflow(String packageName, int action, int bubbleCount, float normalX,
+ float normalY) {
+ SysUiStatsLog.write(SysUiStatsLog.BUBBLE_UI_CHANGED,
+ packageName,
+ BubbleOverflow.KEY /* notification channel */,
+ 0 /* notification ID */,
+ 0 /* bubble position */,
+ bubbleCount,
+ action,
+ normalX,
+ normalY,
+ false /* unread bubble */,
+ false /* on-going bubble */,
+ false /* isAppForeground (unused) */);
+ }
+
+ void logBubbleUiChanged(Bubble bubble, String packageName, int action, int bubbleCount,
+ float normalX, float normalY, int index) {
+ SysUiStatsLog.write(SysUiStatsLog.BUBBLE_UI_CHANGED,
+ packageName,
+ bubble.getChannelId() /* notification channel */,
+ bubble.getNotificationId() /* notification ID */,
+ index,
+ bubbleCount,
+ action,
+ normalX,
+ normalY,
+ bubble.showInShade() /* isUnread */,
+ false /* isOngoing (unused) */,
+ false /* isAppForeground (unused) */);
+ }
} \ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleOverflow.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleOverflow.java
index dadcb3a3a7c4..bb9d1095a37a 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleOverflow.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleOverflow.java
@@ -163,12 +163,6 @@ public class BubbleOverflow implements BubbleViewProvider {
}
@Override
- public void logUIEvent(int bubbleCount, int action, float normalX, float normalY,
- int index) {
- // TODO(b/149133814) Log overflow UI events.
- }
-
- @Override
public View getIconView() {
return mOverflowBtn;
}
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java
index b328f62e067e..f02945ef843a 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java
@@ -2891,23 +2891,13 @@ public class BubbleStackView extends FrameLayout
* @param action the user interaction enum.
*/
private void logBubbleEvent(@Nullable BubbleViewProvider provider, int action) {
- if (provider == null || provider.getKey().equals(BubbleOverflow.KEY)) {
- SysUiStatsLog.write(SysUiStatsLog.BUBBLE_UI_CHANGED,
- mContext.getApplicationInfo().packageName,
- provider == null ? null : BubbleOverflow.KEY /* notification channel */,
- 0 /* notification ID */,
- 0 /* bubble position */,
- getBubbleCount(),
- action,
- getNormalizedXPosition(),
- getNormalizedYPosition(),
- false /* unread bubble */,
- false /* on-going bubble */,
- false /* isAppForeground (unused) */);
- return;
- }
- provider.logUIEvent(getBubbleCount(), action, getNormalizedXPosition(),
- getNormalizedYPosition(), getBubbleIndex(provider));
+ mBubbleData.logBubbleEvent(provider,
+ action,
+ mContext.getApplicationInfo().packageName,
+ getBubbleCount(),
+ getBubbleIndex(provider),
+ getNormalizedXPosition(),
+ getNormalizedYPosition());
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleViewProvider.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleViewProvider.java
index ca3e2e27fa9a..f1a01be48397 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleViewProvider.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleViewProvider.java
@@ -32,8 +32,6 @@ interface BubbleViewProvider {
@Nullable View getIconView();
- void logUIEvent(int bubbleCount, int action, float normalX, float normalY, int index);
-
String getKey();
Bitmap getBadgedImage();
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIRootComponent.java b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIRootComponent.java
index 6b8fcd562e6f..e5cc1384efa4 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIRootComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIRootComponent.java
@@ -29,6 +29,7 @@ import com.android.systemui.dump.DumpManager;
import com.android.systemui.fragments.FragmentService;
import com.android.systemui.keyguard.KeyguardSliceProvider;
import com.android.systemui.onehanded.dagger.OneHandedModule;
+import com.android.systemui.pip.phone.PipMenuActivity;
import com.android.systemui.pip.phone.dagger.PipModule;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.util.InjectionInflationController;
@@ -121,4 +122,9 @@ public interface SystemUIRootComponent {
* Member injection into the supplied argument.
*/
void inject(KeyguardSliceProvider keyguardSliceProvider);
+
+ /**
+ * Member injection into the supplied argument.
+ */
+ void inject(PipMenuActivity pipMenuActivity);
}
diff --git a/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java b/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java
index 0d6b522046f7..35e56ee87967 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java
@@ -178,6 +178,9 @@ public class PipTaskOrganizer extends TaskOrganizer implements
Rect startBounds = (Rect) args.arg2;
Rect toBounds = (Rect) args.arg3;
userResizePip(startBounds, toBounds);
+ if (updateBoundsCallback != null) {
+ updateBoundsCallback.accept(toBounds);
+ }
break;
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java
index ad5a13e78cb4..d6f3e163ad70 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java
@@ -76,12 +76,15 @@ import android.widget.ImageButton;
import android.widget.LinearLayout;
import com.android.systemui.Interpolators;
+import com.android.systemui.SystemUIFactory;
import com.android.wm.shell.R;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
+import javax.inject.Inject;
+
/**
* Translucent activity that gets started on top of a task in PIP to allow the user to control it.
*/
@@ -100,6 +103,7 @@ public class PipMenuActivity extends Activity {
public static final int MESSAGE_POINTER_EVENT = 7;
public static final int MESSAGE_MENU_EXPANDED = 8;
public static final int MESSAGE_FADE_OUT_MENU = 9;
+ public static final int MESSAGE_UPDATE_MENU_LAYOUT = 10;
private static final int INITIAL_DISMISS_DELAY = 3500;
private static final int POST_INTERACTION_DISMISS_DELAY = 2000;
@@ -129,8 +133,12 @@ public class PipMenuActivity extends Activity {
private View mSettingsButton;
private View mDismissButton;
private View mResizeHandle;
+ private View mTopEndContainer;
private int mBetweenActionPaddingLand;
+ @Inject
+ PipMenuIconsAlgorithm mPipMenuIconsAlgorithm;
+
private AnimatorSet mMenuContainerAnimator;
private ValueAnimator.AnimatorUpdateListener mMenuBgUpdateListener =
@@ -193,6 +201,11 @@ public class PipMenuActivity extends Activity {
fadeOutMenu();
break;
}
+ case MESSAGE_UPDATE_MENU_LAYOUT: {
+ final Rect bounds = (Rect) msg.obj;
+ mPipMenuIconsAlgorithm.onBoundsChanged(bounds);
+ break;
+ }
}
}
};
@@ -208,6 +221,9 @@ public class PipMenuActivity extends Activity {
getWindow().addFlags(LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH);
super.onCreate(savedInstanceState);
+
+ SystemUIFactory.getInstance().getRootComponent().inject(this);
+
setContentView(R.layout.pip_menu_activity);
mAccessibilityManager = getSystemService(AccessibilityManager.class);
@@ -217,6 +233,7 @@ public class PipMenuActivity extends Activity {
mViewRoot.setBackground(mBackgroundDrawable);
mMenuContainer = findViewById(R.id.menu_container);
mMenuContainer.setAlpha(0);
+ mTopEndContainer = findViewById(R.id.top_end_container);
mSettingsButton = findViewById(R.id.settings);
mSettingsButton.setAlpha(0);
mSettingsButton.setOnClickListener((v) -> {
@@ -238,6 +255,8 @@ public class PipMenuActivity extends Activity {
mBetweenActionPaddingLand = getResources().getDimensionPixelSize(
R.dimen.pip_between_action_padding_land);
+ mPipMenuIconsAlgorithm.bindViews((ViewGroup) mViewRoot, (ViewGroup) mTopEndContainer,
+ mResizeHandle, mSettingsButton, mDismissButton);
updateFromIntent(getIntent());
setTitle(R.string.pip_menu_title);
setDisablePreviewScreenshots(true);
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivityController.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivityController.java
index 87e66fdc375c..267c5eacd139 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivityController.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivityController.java
@@ -574,6 +574,22 @@ public class PipMenuActivityController {
}
}
+ /**
+ * Tell the PIP Menu to recalculate its layout given its current position on the display.
+ */
+ public void updateMenuLayout(Rect bounds) {
+ if (mToActivityMessenger != null) {
+ Message m = Message.obtain();
+ m.what = PipMenuActivity.MESSAGE_UPDATE_MENU_LAYOUT;
+ m.obj = bounds;
+ try {
+ mToActivityMessenger.send(m);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Could not dispatch touch event", e);
+ }
+ }
+ }
+
public void dump(PrintWriter pw, String prefix) {
final String innerPrefix = prefix + " ";
pw.println(prefix + TAG);
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuIconsAlgorithm.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuIconsAlgorithm.java
new file mode 100644
index 000000000000..69a04d8d3e22
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuIconsAlgorithm.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2020 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.systemui.pip.phone;
+
+import android.content.Context;
+import android.graphics.Rect;
+import android.util.Log;
+import android.view.Gravity;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.FrameLayout;
+
+import javax.inject.Inject;
+
+/**
+ * Helper class to calculate and place the menu icons on the PIP Menu.
+ */
+public class PipMenuIconsAlgorithm {
+
+ private static final String TAG = "PipMenuIconsAlgorithm";
+
+ private boolean mFinishedLayout = false;
+ protected ViewGroup mViewRoot;
+ protected ViewGroup mTopEndContainer;
+ protected View mDragHandle;
+ protected View mSettingsButton;
+ protected View mDismissButton;
+
+ @Inject
+ public PipMenuIconsAlgorithm(Context context) {
+ }
+
+ /**
+ * Bind the necessary views.
+ */
+ public void bindViews(ViewGroup viewRoot, ViewGroup topEndContainer, View dragHandle,
+ View settingsButton, View dismissButton) {
+ mViewRoot = viewRoot;
+ mTopEndContainer = topEndContainer;
+ mDragHandle = dragHandle;
+ mSettingsButton = settingsButton;
+ mDismissButton = dismissButton;
+ }
+
+
+ /**
+ * Updates the position of the drag handle based on where the PIP window is on the screen.
+ */
+ public void onBoundsChanged(Rect bounds) {
+ if (mViewRoot == null || mTopEndContainer == null || mDragHandle == null
+ || mSettingsButton == null || mDismissButton == null) {
+ Log.e(TAG, "One if the required views is null.");
+ }
+
+ //We only need to calculate the layout once since it does not change.
+ if (!mFinishedLayout) {
+ mTopEndContainer.removeView(mSettingsButton);
+ mViewRoot.addView(mSettingsButton);
+
+ setLayoutGravity(mDragHandle, Gravity.START | Gravity.TOP);
+ setLayoutGravity(mSettingsButton, Gravity.START | Gravity.TOP);
+ mFinishedLayout = true;
+ }
+ }
+
+ /**
+ * Set the gravity on the given view.
+ */
+ protected static void setLayoutGravity(View v, int gravity) {
+ if (v.getLayoutParams() instanceof FrameLayout.LayoutParams) {
+ FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) v.getLayoutParams();
+ params.gravity = gravity;
+ v.setLayoutParams(params);
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java
index 9f0b1de21b52..ca3ef2465498 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java
@@ -127,7 +127,10 @@ public class PipMotionHelper implements PipAppOpsListener.Callback,
new PhysicsAnimator.SpringConfig(
SpringForce.STIFFNESS_LOW, SpringForce.DAMPING_RATIO_LOW_BOUNCY);
- private final Consumer<Rect> mUpdateBoundsCallback = mBounds::set;
+ private final Consumer<Rect> mUpdateBoundsCallback = (Rect newBounds) -> {
+ mMenuController.updateMenuLayout(newBounds);
+ mBounds.set(newBounds);
+ };
/**
* Whether we're springing to the touch event location (vs. moving it to that position
@@ -248,7 +251,10 @@ public class PipMotionHelper implements PipAppOpsListener.Callback,
mBounds.set(toBounds);
} else {
mTemporaryBounds.set(toBounds);
- mPipTaskOrganizer.scheduleUserResizePip(mBounds, mTemporaryBounds, null);
+ mPipTaskOrganizer.scheduleUserResizePip(mBounds, mTemporaryBounds,
+ (Rect newBounds) -> {
+ mMenuController.updateMenuLayout(newBounds);
+ });
}
} else {
// If PIP is 'catching up' after being stuck in the dismiss target, update the animation
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
index f4553fd3d716..bd9ddc57ca19 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
@@ -348,7 +348,7 @@ public class PipTouchHandler {
}
private boolean shouldShowResizeHandle() {
- return !mPipBoundsHandler.hasSaveReentryBounds();
+ return false;
}
public void setTouchGesture(PipTouchGesture gesture) {
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index ea047888caff..d6557f6410ec 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -5288,6 +5288,9 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
@Override
public void onTempPowerSaveWhitelistChange(int appId, boolean added) {
synchronized (mUidRulesFirstLock) {
+ if (!mSystemReady) {
+ return;
+ }
mLogger.tempPowerSaveWlChanged(appId, added);
if (added) {
mPowerSaveTempWhitelistAppIds.put(appId, true);
diff --git a/services/core/java/com/android/server/policy/WindowManagerPolicy.java b/services/core/java/com/android/server/policy/WindowManagerPolicy.java
index 6e48cbbb3b5b..651eafd77fe7 100644
--- a/services/core/java/com/android/server/policy/WindowManagerPolicy.java
+++ b/services/core/java/com/android/server/policy/WindowManagerPolicy.java
@@ -399,14 +399,6 @@ public interface WindowManagerPolicy extends WindowManagerPolicyConstants {
return false;
}
- /**
- * Returns true if the window has a letterbox and any part of that letterbox overlaps with
- * the given {@code rect}.
- */
- default boolean isLetterboxedOverlappingWith(Rect rect) {
- return false;
- }
-
/** @return the current windowing mode of this window. */
int getWindowingMode();
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index bec0ce944e3f..a3acc1d90862 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -658,6 +658,11 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
// TODO: Have a WindowContainer state for tracking exiting/deferred removal.
boolean mIsExiting;
+ // Force an app transition to be ran in the case the visibility of the app did not change.
+ // We use this for the case of moving a Root Task to the back with multiple activities, and the
+ // top activity enters PIP; the bottom activity's visibility stays the same, but we need to
+ // run the transition.
+ boolean mRequestForceTransition;
boolean mEnteringAnimation;
@@ -1394,6 +1399,13 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
}
/**
+ * @see Letterbox#notIntersectsOrFullyContains(Rect)
+ */
+ boolean letterboxNotIntersectsOrFullyContains(Rect rect) {
+ return mLetterbox == null || mLetterbox.notIntersectsOrFullyContains(rect);
+ }
+
+ /**
* @return {@code true} if there is a letterbox and any part of that letterbox overlaps with
* the given {@code rect}.
*/
@@ -4199,6 +4211,8 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
if (mUseTransferredAnimation) {
return false;
}
+ // If it was set to true, reset the last request to force the transition.
+ mRequestForceTransition = false;
return super.applyAnimation(lp, transit, enter, isVoiceInteraction, sources);
}
@@ -4342,7 +4356,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
// transition animation
// * or this is an opening app and windows are being replaced (e.g. freeform window to
// normal window).
- return isVisible() != visible || (!isVisible() && mIsExiting)
+ return isVisible() != visible || mRequestForceTransition || (!isVisible() && mIsExiting)
|| (visible && forAllWindows(WindowState::waitingForReplacement, true));
}
diff --git a/services/core/java/com/android/server/wm/ActivityStack.java b/services/core/java/com/android/server/wm/ActivityStack.java
index 686e016f1d35..9f0bf052ecad 100644
--- a/services/core/java/com/android/server/wm/ActivityStack.java
+++ b/services/core/java/com/android/server/wm/ActivityStack.java
@@ -2489,15 +2489,13 @@ class ActivityStack extends Task {
return true;
}
+ mRootWindowContainer.ensureVisibilityAndConfig(null /* starting */,
+ getDisplay().mDisplayId, false /* markFrozenIfConfigChanged */,
+ false /* deferResume */);
+
ActivityRecord topActivity = getDisplayArea().topRunningActivity();
ActivityStack topStack = topActivity.getRootTask();
if (topStack != null && topStack != this && topActivity.isState(RESUMED)) {
- // The new top activity is already resumed, so there's a good chance that nothing will
- // get resumed below. So, update visibility now in case the transition is closed
- // prematurely.
- mRootWindowContainer.ensureVisibilityAndConfig(null /* starting */,
- getDisplay().mDisplayId, false /* markFrozenIfConfigChanged */,
- false /* deferResume */);
// Usually resuming a top activity triggers the next app transition, but nothing's got
// resumed in this case, so we need to execute it explicitly.
getDisplay().mDisplayContent.executeAppTransition();
diff --git a/services/core/java/com/android/server/wm/BarController.java b/services/core/java/com/android/server/wm/BarController.java
index 123fb6c9d8e3..c1447553ba31 100644
--- a/services/core/java/com/android/server/wm/BarController.java
+++ b/services/core/java/com/android/server/wm/BarController.java
@@ -19,6 +19,7 @@ package com.android.server.wm;
import static com.android.server.wm.BarControllerProto.STATE;
import static com.android.server.wm.BarControllerProto.TRANSIENT_STATE;
+import android.annotation.NonNull;
import android.app.StatusBarManager;
import android.graphics.Rect;
import android.os.Handler;
@@ -169,13 +170,23 @@ public class BarController {
return vis;
}
+ private Rect getContentFrame(@NonNull WindowState win) {
+ final Rect rotatedContentFrame = win.mToken.getFixedRotationBarContentFrame(mWindowType);
+ return rotatedContentFrame != null ? rotatedContentFrame : mContentFrame;
+ }
+
+ boolean isLightAppearanceAllowed(WindowState win) {
+ if (win == null) {
+ return true;
+ }
+ return !win.isLetterboxedOverlappingWith(getContentFrame(win));
+ }
+
boolean isTransparentAllowed(WindowState win) {
if (win == null) {
return true;
}
- final Rect rotatedContentFrame = win.mToken.getFixedRotationBarContentFrame(mWindowType);
- final Rect contentFrame = rotatedContentFrame != null ? rotatedContentFrame : mContentFrame;
- return !win.isLetterboxedOverlappingWith(contentFrame);
+ return win.letterboxNotIntersectsOrFullyContains(getContentFrame(win));
}
boolean setBarShowingLw(final boolean show) {
diff --git a/services/core/java/com/android/server/wm/DisplayAreaPolicy.java b/services/core/java/com/android/server/wm/DisplayAreaPolicy.java
index 59c32045000b..33eb3ce57373 100644
--- a/services/core/java/com/android/server/wm/DisplayAreaPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayAreaPolicy.java
@@ -17,12 +17,19 @@
package com.android.server.wm;
import static android.view.WindowManager.LayoutParams.TYPE_ACCESSIBILITY_MAGNIFICATION_OVERLAY;
+import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
+import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG;
+import static android.view.WindowManager.LayoutParams.TYPE_MAGNIFICATION_OVERLAY;
import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR;
import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL;
import static android.window.DisplayAreaOrganizer.FEATURE_DEFAULT_TASK_CONTAINER;
+import static android.window.DisplayAreaOrganizer.FEATURE_FULLSCREEN_MAGNIFICATION;
import static android.window.DisplayAreaOrganizer.FEATURE_ONE_HANDED;
import static android.window.DisplayAreaOrganizer.FEATURE_WINDOWED_MAGNIFICATION;
+import static com.android.server.wm.DisplayAreaPolicyBuilder.Feature;
+import static com.android.server.wm.DisplayAreaPolicyBuilder.HierarchyBuilder;
+
import android.content.res.Resources;
import android.text.TextUtils;
@@ -81,21 +88,27 @@ public abstract class DisplayAreaPolicy {
// Define the features that will be supported under the root of the whole logical
// display. The policy will build the DisplayArea hierarchy based on this.
- DisplayAreaPolicyBuilder.HierarchyBuilder rootHierarchy =
- new DisplayAreaPolicyBuilder.HierarchyBuilder(root)
- .addFeature(new DisplayAreaPolicyBuilder.Feature.Builder(wmService.mPolicy,
- "WindowedMagnification", FEATURE_WINDOWED_MAGNIFICATION)
+ HierarchyBuilder rootHierarchy = new HierarchyBuilder(root)
+ .addFeature(new Feature.Builder(wmService.mPolicy, "WindowedMagnification",
+ FEATURE_WINDOWED_MAGNIFICATION)
.upTo(TYPE_ACCESSIBILITY_MAGNIFICATION_OVERLAY)
.except(TYPE_ACCESSIBILITY_MAGNIFICATION_OVERLAY)
// Make the DA dimmable so that the magnify window also mirrors the dim
// layer
.setNewDisplayAreaSupplier(DisplayArea.Dimmable::new)
.build())
- .addFeature(new DisplayAreaPolicyBuilder.Feature.Builder(wmService.mPolicy,
- "OneHanded", FEATURE_ONE_HANDED)
+ .addFeature(new Feature.Builder(wmService.mPolicy, "OneHanded",
+ FEATURE_ONE_HANDED)
.all()
.except(TYPE_NAVIGATION_BAR, TYPE_NAVIGATION_BAR_PANEL)
.build())
+ .addFeature(new Feature.Builder(wmService.mPolicy, "FullscreenMagnification",
+ FEATURE_FULLSCREEN_MAGNIFICATION)
+ .all()
+ .except(TYPE_ACCESSIBILITY_MAGNIFICATION_OVERLAY, TYPE_INPUT_METHOD,
+ TYPE_INPUT_METHOD_DIALOG, TYPE_MAGNIFICATION_OVERLAY,
+ TYPE_NAVIGATION_BAR, TYPE_NAVIGATION_BAR_PANEL)
+ .build())
.setImeContainer(imeContainer)
.setTaskDisplayAreas(tdaList);
diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java
index 82277511ef79..53f16a7241fc 100644
--- a/services/core/java/com/android/server/wm/DisplayPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayPolicy.java
@@ -3428,7 +3428,7 @@ public class DisplayPolicy {
// keys, we let it keep controlling the visibility.
final boolean lastFocusCanReceiveKeys =
(mLastFocusedWindow != null && mLastFocusedWindow.canReceiveKeys());
- winCandidate = isKeyguardShowing() ? mNotificationShade
+ winCandidate = isKeyguardShowing() && !isKeyguardOccluded() ? mNotificationShade
: lastFocusCanReceiveKeys ? mLastFocusedWindow
: mTopFullscreenOpaqueWindowState;
if (winCandidate == null) {
@@ -3573,17 +3573,22 @@ public class DisplayPolicy {
WindowState opaqueOrDimming) {
final boolean onKeyguard = isKeyguardShowing() && !isKeyguardOccluded();
final WindowState statusColorWin = onKeyguard ? mNotificationShade : opaqueOrDimming;
- if (statusColorWin != null && (statusColorWin == opaque || onKeyguard)) {
- // If the top fullscreen-or-dimming window is also the top fullscreen, respect
- // its light flag.
- appearance &= ~APPEARANCE_LIGHT_STATUS_BARS;
- final int legacyAppearance = InsetsFlags.getAppearance(
- PolicyControl.getSystemUiVisibility(statusColorWin, null));
- appearance |= (statusColorWin.mAttrs.insetsFlags.appearance | legacyAppearance)
- & APPEARANCE_LIGHT_STATUS_BARS;
- } else if (statusColorWin != null && statusColorWin.isDimming()) {
- // Otherwise if it's dimming, clear the light flag.
- appearance &= ~APPEARANCE_LIGHT_STATUS_BARS;
+ if (statusColorWin != null) {
+ if (statusColorWin == opaque || onKeyguard) {
+ // If the top fullscreen-or-dimming window is also the top fullscreen, respect
+ // its light flag.
+ appearance &= ~APPEARANCE_LIGHT_STATUS_BARS;
+ final int legacyAppearance = InsetsFlags.getAppearance(
+ PolicyControl.getSystemUiVisibility(statusColorWin, null));
+ appearance |= (statusColorWin.mAttrs.insetsFlags.appearance | legacyAppearance)
+ & APPEARANCE_LIGHT_STATUS_BARS;
+ } else if (statusColorWin.isDimming()) {
+ // Otherwise if it's dimming, clear the light flag.
+ appearance &= ~APPEARANCE_LIGHT_STATUS_BARS;
+ }
+ if (!mStatusBarController.isLightAppearanceAllowed(statusColorWin)) {
+ appearance &= ~APPEARANCE_LIGHT_STATUS_BARS;
+ }
}
return appearance;
}
@@ -3648,8 +3653,7 @@ public class DisplayPolicy {
return vis;
}
- @VisibleForTesting
- static int updateLightNavigationBarAppearanceLw(int appearance, WindowState opaque,
+ private int updateLightNavigationBarAppearanceLw(int appearance, WindowState opaque,
WindowState opaqueOrDimming, WindowState imeWindow, WindowState navColorWin) {
if (navColorWin != null) {
@@ -3662,6 +3666,9 @@ public class DisplayPolicy {
// Clear the light flag for dimming window.
appearance &= ~APPEARANCE_LIGHT_NAVIGATION_BARS;
}
+ if (!mNavigationBarController.isLightAppearanceAllowed(navColorWin)) {
+ appearance &= ~APPEARANCE_LIGHT_NAVIGATION_BARS;
+ }
}
return appearance;
}
diff --git a/services/core/java/com/android/server/wm/Letterbox.java b/services/core/java/com/android/server/wm/Letterbox.java
index a685886da032..28dcbcdf3cc7 100644
--- a/services/core/java/com/android/server/wm/Letterbox.java
+++ b/services/core/java/com/android/server/wm/Letterbox.java
@@ -77,10 +77,10 @@ public class Letterbox {
mOuter.set(outer);
mInner.set(inner);
- mTop.layout(outer.left, outer.top, inner.right, inner.top, surfaceOrigin);
- mLeft.layout(outer.left, inner.top, inner.left, outer.bottom, surfaceOrigin);
- mBottom.layout(inner.left, inner.bottom, outer.right, outer.bottom, surfaceOrigin);
- mRight.layout(inner.right, outer.top, outer.right, inner.bottom, surfaceOrigin);
+ mTop.layout(outer.left, outer.top, outer.right, inner.top, surfaceOrigin);
+ mLeft.layout(outer.left, outer.top, inner.left, outer.bottom, surfaceOrigin);
+ mBottom.layout(outer.left, inner.bottom, outer.right, outer.bottom, surfaceOrigin);
+ mRight.layout(inner.right, outer.top, outer.right, outer.bottom, surfaceOrigin);
}
@@ -101,6 +101,31 @@ public class Letterbox {
}
/**
+ * Returns {@code true} if the letterbox does not overlap with the bar, or the letterbox can
+ * fully cover the window frame.
+ *
+ * @param rect The area of the window frame.
+ */
+ boolean notIntersectsOrFullyContains(Rect rect) {
+ int emptyCount = 0;
+ int noOverlappingCount = 0;
+ for (LetterboxSurface surface : mSurfaces) {
+ final Rect surfaceRect = surface.mLayoutFrameGlobal;
+ if (surfaceRect.isEmpty()) {
+ // empty letterbox
+ emptyCount++;
+ } else if (!Rect.intersects(surfaceRect, rect)) {
+ // no overlapping
+ noOverlappingCount++;
+ } else if (surfaceRect.contains(rect)) {
+ // overlapping and covered
+ return true;
+ }
+ }
+ return (emptyCount + noOverlappingCount) == mSurfaces.length;
+ }
+
+ /**
* Returns true if any part of the letterbox overlaps with the given {@code rect}.
*/
public boolean isOverlappingWith(Rect rect) {
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index f3e23169fee0..50ae4ea2f627 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -39,6 +39,7 @@ import static android.view.WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG;
import static android.view.WindowManager.TRANSIT_CRASHING_ACTIVITY_CLOSE;
import static android.view.WindowManager.TRANSIT_NONE;
import static android.view.WindowManager.TRANSIT_SHOW_SINGLE_TASK_DISPLAY;
+import static android.view.WindowManager.TRANSIT_TASK_TO_BACK;
import static com.android.server.policy.PhoneWindowManager.SYSTEM_DIALOG_REASON_ASSIST;
import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT;
@@ -2156,6 +2157,20 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
// On the other hand, ActivityRecord#onParentChanged takes care of setting the
// up-to-dated pinned stack information on this newly created stack.
r.reparent(stack, MAX_VALUE, reason);
+
+ // In the case of this activity entering PIP due to it being moved to the back,
+ // the old activity would have a TRANSIT_TASK_TO_BACK transition that needs to be
+ // ran. But, since its visibility did not change (note how it was STOPPED/not
+ // visible, and with it now at the back stack, it remains not visible), the logic to
+ // add the transition is automatically skipped. We then add this activity manually
+ // to the list of apps being closed, and request its transition to be ran.
+ final ActivityRecord oldTopActivity = task.getTopMostActivity();
+ if (oldTopActivity != null && oldTopActivity.isState(STOPPED)
+ && task.getDisplayContent().mAppTransition.getAppTransition()
+ == TRANSIT_TASK_TO_BACK) {
+ task.getDisplayContent().mClosingApps.add(oldTopActivity);
+ oldTopActivity.mRequestForceTransition = true;
+ }
}
// The intermediate windowing mode to be set on the ActivityRecord later.
// This needs to happen before the re-parenting, otherwise we will always set the
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 7afed3ccc6ca..fd4fdfccdea8 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -3822,7 +3822,14 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
return mActivityRecord.getBounds().equals(mTmpRect);
}
- @Override
+ /**
+ * @see Letterbox#notIntersectsOrFullyContains(Rect)
+ */
+ boolean letterboxNotIntersectsOrFullyContains(Rect rect) {
+ return mActivityRecord == null
+ || mActivityRecord.letterboxNotIntersectsOrFullyContains(rect);
+ }
+
public boolean isLetterboxedOverlappingWith(Rect rect) {
return mActivityRecord != null && mActivityRecord.isLetterboxOverlappingWith(rect);
}
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index 508d2d477067..da45300ed318 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -1592,12 +1592,6 @@ class WindowStateAnimator {
if (mSurfaceController != null) {
mSurfaceController.detachChildren();
}
- // If the children are detached, it means the app is exiting. We don't want to tear the
- // content down too early, otherwise we could end up with a flicker. By preserving the
- // current surface, we ensure the content remains on screen until the window is completely
- // removed. It also ensures that the old surface is cleaned up when started again since it
- // forces mSurfaceController to be set to null.
- preserveSurfaceLocked();
}
void setOffsetPositionForStackResize(boolean offsetPositionForStackResize) {
diff --git a/services/tests/mockingservicestests/src/com/android/server/am/ApplicationExitInfoTest.java b/services/tests/mockingservicestests/src/com/android/server/am/ApplicationExitInfoTest.java
index 23381ffd4eaa..8db09b4f156c 100644
--- a/services/tests/mockingservicestests/src/com/android/server/am/ApplicationExitInfoTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/am/ApplicationExitInfoTest.java
@@ -192,6 +192,7 @@ public class ApplicationExitInfoTest {
final int app1Uid = 10123;
final int app1Pid1 = 12345;
final int app1Pid2 = 12346;
+ final int app1sPid1 = 13456;
final int app1DefiningUid = 23456;
final int app1ConnectiongGroup = 10;
final int app1UidUser2 = 1010123;
@@ -202,8 +203,12 @@ public class ApplicationExitInfoTest {
final long app1Rss2 = 45679;
final long app1Pss3 = 34569;
final long app1Rss3 = 45680;
+ final long app1sPss1 = 56789;
+ final long app1sRss1 = 67890;
final String app1ProcessName = "com.android.test.stub1:process";
final String app1PackageName = "com.android.test.stub1";
+ final String app1sProcessName = "com.android.test.stub_shared:process";
+ final String app1sPackageName = "com.android.test.stub_shared";
final byte[] app1Cookie1 = {(byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x04,
(byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08};
final byte[] app1Cookie2 = {(byte) 0x08, (byte) 0x07, (byte) 0x06, (byte) 0x05,
@@ -262,6 +267,29 @@ public class ApplicationExitInfoTest {
app1Cookie1.length));
assertEquals(info.getTraceInputStream(), null);
+ // Now create a process record from a different package but shared UID.
+ sleep(1);
+ final long now1s = System.currentTimeMillis();
+ app = makeProcessRecord(
+ app1sPid1, // pid
+ app1Uid, // uid
+ app1Uid, // packageUid
+ null, // definingUid
+ 0, // connectionGroup
+ PROCESS_STATE_BOUND_TOP, // procstate
+ app1sPss1, // pss
+ app1sRss1, // rss
+ app1sProcessName, // processName
+ app1sPackageName); // packageName
+ doReturn(new Pair<Long, Object>(now1s, Integer.valueOf(0)))
+ .when(mAppExitInfoTracker.mAppExitInfoSourceZygote)
+ .remove(anyInt(), anyInt());
+ doReturn(null)
+ .when(mAppExitInfoTracker.mAppExitInfoSourceLmkd)
+ .remove(anyInt(), anyInt());
+ noteAppKill(app, ApplicationExitInfo.REASON_USER_REQUESTED,
+ ApplicationExitInfo.SUBREASON_UNKNOWN, null);
+
// Case 2: create another app1 process record with a different pid
sleep(1);
final long now2 = System.currentTimeMillis();
@@ -290,8 +318,8 @@ public class ApplicationExitInfoTest {
list.clear();
// Get all the records for app1Uid
- mAppExitInfoTracker.getExitInfo(app1PackageName, app1Uid, 0, 0, list);
- assertEquals(2, list.size());
+ mAppExitInfoTracker.getExitInfo(null, app1Uid, 0, 0, list);
+ assertEquals(3, list.size());
info = list.get(0);
@@ -315,7 +343,26 @@ public class ApplicationExitInfoTest {
assertTrue(ArrayUtils.equals(info.getProcessStateSummary(), app1Cookie2,
app1Cookie2.length));
+
info = list.get(1);
+ verifyApplicationExitInfo(
+ info, // info
+ now1s, // timestamp
+ app1sPid1, // pid
+ app1Uid, // uid
+ app1Uid, // packageUid
+ null, // definingUid
+ app1sProcessName, // processName
+ 0, // connectionGroup
+ ApplicationExitInfo.REASON_USER_REQUESTED, // reason
+ null, // subReason
+ null, // status
+ app1sPss1, // pss
+ app1sRss1, // rss
+ IMPORTANCE_FOREGROUND, // importance
+ null); // description
+
+ info = list.get(2);
assertTrue(ArrayUtils.equals(info.getProcessStateSummary(), app1Cookie1,
app1Cookie1.length));
@@ -808,7 +855,7 @@ public class ApplicationExitInfoTest {
list.clear();
mAppExitInfoTracker.getExitInfo(null, app1Uid, 0, 0, list);
- assertEquals(2, list.size());
+ assertEquals(3, list.size());
info = list.get(0);
@@ -831,6 +878,24 @@ public class ApplicationExitInfoTest {
null); // description
info = list.get(1);
+ verifyApplicationExitInfo(
+ info, // info
+ now1s, // timestamp
+ app1sPid1, // pid
+ app1Uid, // uid
+ app1Uid, // packageUid
+ null, // definingUid
+ app1sProcessName, // processName
+ 0, // connectionGroup
+ ApplicationExitInfo.REASON_USER_REQUESTED, // reason
+ null, // subReason
+ null, // status
+ app1sPss1, // pss
+ app1sRss1, // rss
+ IMPORTANCE_FOREGROUND, // importance
+ null); // description
+
+ info = list.get(2);
exitCode = 5;
verifyApplicationExitInfo(
info, // info
diff --git a/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java b/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java
index 1a04d2ff8c29..4dec7a1a0ab9 100644
--- a/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java
+++ b/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java
@@ -218,6 +218,10 @@ public class AppStandbyControllerTests {
}
@Override
+ void updatePowerWhitelistCache() {
+ }
+
+ @Override
boolean isRestrictedBucketEnabled() {
return mIsRestrictedBucketEnabled;
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java
index 6b613cad4b82..f2a553906095 100644
--- a/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java
@@ -199,6 +199,40 @@ public class AppTransitionControllerTest extends WindowTestsBase {
}
@Test
+ public void testGetAnimationTargets_visibilityAlreadyUpdated_butForcedTransitionRequested() {
+ // [DisplayContent] -+- [TaskStack1] - [Task1] - [ActivityRecord1] (closing, invisible)
+ // +- [TaskStack2] - [Task2] - [ActivityRecord2] (opening, visible)
+ final ActivityStack stack1 = createTaskStackOnDisplay(mDisplayContent);
+ final ActivityRecord activity1 = WindowTestUtils.createTestActivityRecord(stack1);
+ activity1.setVisible(true);
+ activity1.mVisibleRequested = true;
+ activity1.mRequestForceTransition = true;
+
+ final ActivityStack stack2 = createTaskStackOnDisplay(mDisplayContent);
+ final ActivityRecord activity2 = WindowTestUtils.createTestActivityRecord(stack2);
+ activity2.setVisible(false);
+ activity2.mVisibleRequested = false;
+ activity2.mRequestForceTransition = true;
+
+ final ArraySet<ActivityRecord> opening = new ArraySet<>();
+ opening.add(activity1);
+ final ArraySet<ActivityRecord> closing = new ArraySet<>();
+ closing.add(activity2);
+
+ // The visibility are already updated, but since forced transition is requested, it will
+ // be included.
+ WindowManagerService.sHierarchicalAnimations = false;
+ assertEquals(
+ new ArraySet<>(new WindowContainer[]{activity1}),
+ AppTransitionController.getAnimationTargets(
+ opening, closing, true /* visible */));
+ assertEquals(
+ new ArraySet<>(new WindowContainer[]{activity2}),
+ AppTransitionController.getAnimationTargets(
+ opening, closing, false /* visible */));
+ }
+
+ @Test
public void testGetAnimationTargets_exitingBeforeTransition() {
// Create another non-empty task so the animation target won't promote to task display area.
WindowTestUtils.createTestActivityRecord(
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayAreaPolicyBuilderTest.java b/services/tests/wmtests/src/com/android/server/wm/DisplayAreaPolicyBuilderTest.java
index a8fc66da9bd0..ce0aa79f2d89 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayAreaPolicyBuilderTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayAreaPolicyBuilderTest.java
@@ -26,9 +26,11 @@ import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR;
import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
import static android.view.WindowManagerPolicyConstants.APPLICATION_LAYER;
import static android.window.DisplayAreaOrganizer.FEATURE_DEFAULT_TASK_CONTAINER;
+import static android.window.DisplayAreaOrganizer.FEATURE_FULLSCREEN_MAGNIFICATION;
import static android.window.DisplayAreaOrganizer.FEATURE_ONE_HANDED;
import static android.window.DisplayAreaOrganizer.FEATURE_ROOT;
import static android.window.DisplayAreaOrganizer.FEATURE_VENDOR_FIRST;
+import static android.window.DisplayAreaOrganizer.FEATURE_WINDOWED_MAGNIFICATION;
import static com.android.server.wm.DisplayArea.Type.ABOVE_TASKS;
import static com.android.server.wm.DisplayAreaPolicyBuilder.Feature;
@@ -178,6 +180,39 @@ public class DisplayAreaPolicyBuilderTest {
}
@Test
+ public void testBuilder_defaultPolicy_hasWindowedMagnificationFeature() {
+ final DisplayAreaPolicy.Provider defaultProvider = DisplayAreaPolicy.Provider.fromResources(
+ resourcesWithProvider(""));
+ final DisplayAreaPolicyBuilder.Result defaultPolicy =
+ (DisplayAreaPolicyBuilder.Result) defaultProvider.instantiate(mWms, mDisplayContent,
+ mRoot, mImeContainer);
+ final List<Feature> features = defaultPolicy.getFeatures();
+ boolean hasWindowedMagnificationFeature = false;
+ for (Feature feature : features) {
+ hasWindowedMagnificationFeature |= feature.getId() == FEATURE_WINDOWED_MAGNIFICATION;
+ }
+
+ assertThat(hasWindowedMagnificationFeature).isTrue();
+ }
+
+ @Test
+ public void testBuilder_defaultPolicy_hasFullscreenMagnificationFeature() {
+ final DisplayAreaPolicy.Provider defaultProvider = DisplayAreaPolicy.Provider.fromResources(
+ resourcesWithProvider(""));
+ final DisplayAreaPolicyBuilder.Result defaultPolicy =
+ (DisplayAreaPolicyBuilder.Result) defaultProvider.instantiate(mWms, mDisplayContent,
+ mRoot, mImeContainer);
+ final List<Feature> features = defaultPolicy.getFeatures();
+ boolean hasFullscreenMagnificationFeature = false;
+ for (Feature feature : features) {
+ hasFullscreenMagnificationFeature |=
+ feature.getId() == FEATURE_FULLSCREEN_MAGNIFICATION;
+ }
+
+ assertThat(hasFullscreenMagnificationFeature).isTrue();
+ }
+
+ @Test
public void testBuilder_createCustomizedDisplayAreaForFeature() {
final Feature dimmable;
final Feature other;
diff --git a/services/tests/wmtests/src/com/android/server/wm/LetterboxTest.java b/services/tests/wmtests/src/com/android/server/wm/LetterboxTest.java
index bf84aecdb6a0..2f3004bf6832 100644
--- a/services/tests/wmtests/src/com/android/server/wm/LetterboxTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/LetterboxTest.java
@@ -16,8 +16,8 @@
package com.android.server.wm;
+import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
-import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.doAnswer;
@@ -60,6 +60,103 @@ public class LetterboxTest {
assertTrue(mLetterbox.isOverlappingWith(new Rect(0, 0, 1, 1)));
}
+ private static final int TOP_BAR = 0x1;
+ private static final int BOTTOM_BAR = 0x2;
+ private static final int LEFT_BAR = 0x4;
+ private static final int RIGHT_BAR = 0x8;
+ @Test
+ public void testNotIntersectsOrFullyContains_usesGlobalCoordinates() {
+ final Rect outer = new Rect(0, 0, 10, 50);
+ final Point surfaceOrig = new Point(1000, 2000);
+
+ final Rect topBar = new Rect(0, 0, 10, 2);
+ final Rect bottomBar = new Rect(0, 45, 10, 50);
+ final Rect leftBar = new Rect(0, 0, 2, 50);
+ final Rect rightBar = new Rect(8, 0, 10, 50);
+
+ final LetterboxLayoutVerifier verifier =
+ new LetterboxLayoutVerifier(outer, surfaceOrig, mLetterbox);
+ verifier.setBarRect(topBar, bottomBar, leftBar, rightBar);
+
+ // top
+ verifier.setInner(0, 2, 10, 50).verifyPositions(TOP_BAR | BOTTOM_BAR, BOTTOM_BAR);
+ // bottom
+ verifier.setInner(0, 0, 10, 45).verifyPositions(TOP_BAR | BOTTOM_BAR, TOP_BAR);
+ // left
+ verifier.setInner(2, 0, 10, 50).verifyPositions(LEFT_BAR | RIGHT_BAR, RIGHT_BAR);
+ // right
+ verifier.setInner(0, 0, 8, 50).verifyPositions(LEFT_BAR | RIGHT_BAR, LEFT_BAR);
+ // top + bottom
+ verifier.setInner(0, 2, 10, 45).verifyPositions(TOP_BAR | BOTTOM_BAR, 0);
+ // left + right
+ verifier.setInner(2, 0, 8, 50).verifyPositions(LEFT_BAR | RIGHT_BAR, 0);
+ // top + left
+ verifier.setInner(2, 2, 10, 50).verifyPositions(TOP_BAR | LEFT_BAR, 0);
+ // top + left + right
+ verifier.setInner(2, 2, 8, 50).verifyPositions(TOP_BAR | LEFT_BAR | RIGHT_BAR, 0);
+ // left + right + bottom
+ verifier.setInner(2, 0, 8, 45).verifyPositions(LEFT_BAR | RIGHT_BAR | BOTTOM_BAR, 0);
+ // all
+ verifier.setInner(2, 2, 8, 45)
+ .verifyPositions(TOP_BAR | BOTTOM_BAR | LEFT_BAR | RIGHT_BAR, 0);
+ }
+
+ private static class LetterboxLayoutVerifier {
+ final Rect mOuter;
+ final Rect mInner = new Rect();
+ final Point mSurfaceOrig;
+ final Letterbox mLetterbox;
+ final Rect mTempRect = new Rect();
+
+ final Rect mTop = new Rect();
+ final Rect mBottom = new Rect();
+ final Rect mLeft = new Rect();
+ final Rect mRight = new Rect();
+
+ LetterboxLayoutVerifier(Rect outer, Point surfaceOrig, Letterbox letterbox) {
+ mOuter = new Rect(outer);
+ mSurfaceOrig = new Point(surfaceOrig);
+ mLetterbox = letterbox;
+ }
+
+ LetterboxLayoutVerifier setInner(int left, int top, int right, int bottom) {
+ mInner.set(left, top, right, bottom);
+ mLetterbox.layout(mOuter, mInner, mSurfaceOrig);
+ return this;
+ }
+
+ void setBarRect(Rect top, Rect bottom, Rect left, Rect right) {
+ mTop.set(top);
+ mBottom.set(bottom);
+ mLeft.set(left);
+ mRight.set(right);
+ }
+
+ void verifyPositions(int allowedPos, int noOverlapPos) {
+ assertEquals(mLetterbox.notIntersectsOrFullyContains(mTop),
+ (allowedPos & TOP_BAR) != 0);
+ assertEquals(mLetterbox.notIntersectsOrFullyContains(mBottom),
+ (allowedPos & BOTTOM_BAR) != 0);
+ assertEquals(mLetterbox.notIntersectsOrFullyContains(mLeft),
+ (allowedPos & LEFT_BAR) != 0);
+ assertEquals(mLetterbox.notIntersectsOrFullyContains(mRight),
+ (allowedPos & RIGHT_BAR) != 0);
+
+ mTempRect.set(mTop.left, mTop.top, mTop.right, mTop.bottom + 1);
+ assertEquals(mLetterbox.notIntersectsOrFullyContains(mTempRect),
+ (noOverlapPos & TOP_BAR) != 0);
+ mTempRect.set(mLeft.left, mLeft.top, mLeft.right + 1, mLeft.bottom);
+ assertEquals(mLetterbox.notIntersectsOrFullyContains(mTempRect),
+ (noOverlapPos & LEFT_BAR) != 0);
+ mTempRect.set(mRight.left - 1, mRight.top, mRight.right, mRight.bottom);
+ assertEquals(mLetterbox.notIntersectsOrFullyContains(mTempRect),
+ (noOverlapPos & RIGHT_BAR) != 0);
+ mTempRect.set(mBottom.left, mBottom.top - 1, mBottom.right, mBottom.bottom);
+ assertEquals(mLetterbox.notIntersectsOrFullyContains(mTempRect),
+ (noOverlapPos & BOTTOM_BAR) != 0);
+ }
+ }
+
@Test
public void testSurfaceOrigin_applied() {
mLetterbox.layout(new Rect(0, 0, 10, 10), new Rect(0, 1, 10, 10), new Point(1000, 2000));
diff --git a/services/tests/wmtests/src/com/android/server/wm/RootActivityContainerTests.java b/services/tests/wmtests/src/com/android/server/wm/RootActivityContainerTests.java
index 4aac47cf006a..d53c89628d93 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RootActivityContainerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RootActivityContainerTests.java
@@ -37,6 +37,7 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.spy;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.times;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
+import static com.android.server.wm.ActivityStack.ActivityState.STOPPED;
import static com.android.server.wm.ActivityStackSupervisor.ON_TOP;
import static com.android.server.wm.RootWindowContainer.MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE;
@@ -148,6 +149,29 @@ public class RootActivityContainerTests extends ActivityTestsBase {
ensureStackPlacement(mFullscreenStack, firstActivity);
}
+ @Test
+ public void testMovingBottomMostStackActivityToPinnedStack() {
+ final ActivityRecord firstActivity = new ActivityBuilder(mService).setCreateTask(true)
+ .setStack(mFullscreenStack).build();
+ final Task task = firstActivity.getTask();
+
+ final ActivityRecord secondActivity = new ActivityBuilder(mService).setTask(task)
+ .setStack(mFullscreenStack).build();
+
+ mFullscreenStack.moveTaskToBack(task);
+
+ // Ensure full screen stack has both tasks.
+ ensureStackPlacement(mFullscreenStack, firstActivity, secondActivity);
+ assertEquals(task.getTopMostActivity(), secondActivity);
+ firstActivity.setState(STOPPED, "testMovingBottomMostStackActivityToPinnedStack");
+
+
+ // Move first activity to pinned stack.
+ mRootWindowContainer.moveActivityToPinnedStack(secondActivity, "initialMove");
+
+ assertTrue(firstActivity.mRequestForceTransition);
+ }
+
private static void ensureStackPlacement(ActivityStack stack, ActivityRecord... activities) {
final Task task = stack.getBottomMostTask();
final ArrayList<ActivityRecord> stackActivities = new ArrayList<>();
diff --git a/tools/stats_log_api_gen/Android.bp b/tools/stats_log_api_gen/Android.bp
index 43387fc054b5..e3b6db08c503 100644
--- a/tools/stats_log_api_gen/Android.bp
+++ b/tools/stats_log_api_gen/Android.bp
@@ -121,26 +121,10 @@ cc_library {
],
target: {
android: {
- shared_libs: [
- "libstatssocket",
- "libstatspull",
- ],
- export_shared_lib_headers: [
- "libstatssocket",
- "libstatspull",
- ],
+ shared_libs: ["libstatssocket"],
},
host: {
- static_libs: [
- "libstatssocket",
- "libstatspull",
- "statsd-aidl-ndk_platform",
- ],
- shared_libs: ["libbinder_ndk"],
- export_static_lib_headers: [
- "libstatssocket",
- "libstatspull",
- ],
+ static_libs: ["libstatssocket"],
},
},
}
diff --git a/tools/stats_log_api_gen/native_writer.cpp b/tools/stats_log_api_gen/native_writer.cpp
index 21e88b360dcd..0c6c0099e459 100644
--- a/tools/stats_log_api_gen/native_writer.cpp
+++ b/tools/stats_log_api_gen/native_writer.cpp
@@ -82,77 +82,21 @@ static void write_annotations(FILE* out, int argIndex,
}
}
-static int write_native_method_body(FILE* out, vector<java_type_t>& signature,
- const FieldNumberToAtomDeclSet& fieldNumberToAtomDeclSet,
- const AtomDecl& attributionDecl) {
- int argIndex = 1;
- fprintf(out, " AStatsEvent_setAtomId(event, code);\n");
- write_annotations(out, ATOM_ID_FIELD_NUMBER, fieldNumberToAtomDeclSet, "AStatsEvent_",
- "event, ");
- for (vector<java_type_t>::const_iterator arg = signature.begin();
- arg != signature.end(); arg++) {
- switch (*arg) {
- case JAVA_TYPE_ATTRIBUTION_CHAIN: {
- const char* uidName = attributionDecl.fields.front().name.c_str();
- const char* tagName = attributionDecl.fields.back().name.c_str();
- fprintf(out,
- " AStatsEvent_writeAttributionChain(event, "
- "reinterpret_cast<const uint32_t*>(%s), %s.data(), "
- "static_cast<uint8_t>(%s_length));\n",
- uidName, tagName, uidName);
- break;
- }
- case JAVA_TYPE_BYTE_ARRAY:
- fprintf(out,
- " AStatsEvent_writeByteArray(event, "
- "reinterpret_cast<const uint8_t*>(arg%d.arg), "
- "arg%d.arg_length);\n",
- argIndex, argIndex);
- break;
- case JAVA_TYPE_BOOLEAN:
- fprintf(out, " AStatsEvent_writeBool(event, arg%d);\n", argIndex);
- break;
- case JAVA_TYPE_INT: // Fall through.
- case JAVA_TYPE_ENUM:
- fprintf(out, " AStatsEvent_writeInt32(event, arg%d);\n", argIndex);
- break;
- case JAVA_TYPE_FLOAT:
- fprintf(out, " AStatsEvent_writeFloat(event, arg%d);\n", argIndex);
- break;
- case JAVA_TYPE_LONG:
- fprintf(out, " AStatsEvent_writeInt64(event, arg%d);\n", argIndex);
- break;
- case JAVA_TYPE_STRING:
- fprintf(out, " AStatsEvent_writeString(event, arg%d);\n", argIndex);
- break;
- default:
- // Unsupported types: OBJECT, DOUBLE, KEY_VALUE_PAIRS
- fprintf(stderr, "Encountered unsupported type.");
- return 1;
- }
- write_annotations(out, argIndex, fieldNumberToAtomDeclSet, "AStatsEvent_",
- "event, ");
- argIndex++;
- }
- return 0;
-}
-
-static int write_native_stats_write_methods(FILE* out, const SignatureInfoMap& signatureInfoMap,
+static int write_native_stats_write_methods(FILE* out, const Atoms& atoms,
const AtomDecl& attributionDecl, const bool supportQ) {
fprintf(out, "\n");
- for (auto signatureInfoMapIt = signatureInfoMap.begin();
- signatureInfoMapIt != signatureInfoMap.end(); signatureInfoMapIt++) {
+ for (auto signatureInfoMapIt = atoms.signatureInfoMap.begin();
+ signatureInfoMapIt != atoms.signatureInfoMap.end(); signatureInfoMapIt++) {
vector<java_type_t> signature = signatureInfoMapIt->first;
const FieldNumberToAtomDeclSet& fieldNumberToAtomDeclSet = signatureInfoMapIt->second;
// Key value pairs not supported in native.
if (find(signature.begin(), signature.end(), JAVA_TYPE_KEY_VALUE_PAIR) != signature.end()) {
continue;
}
- write_native_method_signature(out, "int stats_write(", signature, attributionDecl, " {");
+ write_native_method_signature(out, "int stats_write", signature, attributionDecl, " {");
- // Write method body.
+ int argIndex = 1;
if (supportQ) {
- int argIndex = 1;
fprintf(out, " StatsEventCompat event;\n");
fprintf(out, " event.setAtomId(code);\n");
write_annotations(out, ATOM_ID_FIELD_NUMBER, fieldNumberToAtomDeclSet, "event.", "");
@@ -194,36 +138,78 @@ static int write_native_stats_write_methods(FILE* out, const SignatureInfoMap& s
write_annotations(out, argIndex, fieldNumberToAtomDeclSet, "event.", "");
argIndex++;
}
- fprintf(out, " return event.writeToSocket();\n"); // end method body.
+ fprintf(out, " return event.writeToSocket();\n");
} else {
fprintf(out, " AStatsEvent* event = AStatsEvent_obtain();\n");
- int ret = write_native_method_body(out, signature, fieldNumberToAtomDeclSet,
- attributionDecl);
- if (ret != 0) {
- return ret;
+ fprintf(out, " AStatsEvent_setAtomId(event, code);\n");
+ write_annotations(out, ATOM_ID_FIELD_NUMBER, fieldNumberToAtomDeclSet, "AStatsEvent_",
+ "event, ");
+ for (vector<java_type_t>::const_iterator arg = signature.begin();
+ arg != signature.end(); arg++) {
+ switch (*arg) {
+ case JAVA_TYPE_ATTRIBUTION_CHAIN: {
+ const char* uidName = attributionDecl.fields.front().name.c_str();
+ const char* tagName = attributionDecl.fields.back().name.c_str();
+ fprintf(out,
+ " AStatsEvent_writeAttributionChain(event, "
+ "reinterpret_cast<const uint32_t*>(%s), %s.data(), "
+ "static_cast<uint8_t>(%s_length));\n",
+ uidName, tagName, uidName);
+ break;
+ }
+ case JAVA_TYPE_BYTE_ARRAY:
+ fprintf(out,
+ " AStatsEvent_writeByteArray(event, "
+ "reinterpret_cast<const uint8_t*>(arg%d.arg), "
+ "arg%d.arg_length);\n",
+ argIndex, argIndex);
+ break;
+ case JAVA_TYPE_BOOLEAN:
+ fprintf(out, " AStatsEvent_writeBool(event, arg%d);\n", argIndex);
+ break;
+ case JAVA_TYPE_INT: // Fall through.
+ case JAVA_TYPE_ENUM:
+ fprintf(out, " AStatsEvent_writeInt32(event, arg%d);\n", argIndex);
+ break;
+ case JAVA_TYPE_FLOAT:
+ fprintf(out, " AStatsEvent_writeFloat(event, arg%d);\n", argIndex);
+ break;
+ case JAVA_TYPE_LONG:
+ fprintf(out, " AStatsEvent_writeInt64(event, arg%d);\n", argIndex);
+ break;
+ case JAVA_TYPE_STRING:
+ fprintf(out, " AStatsEvent_writeString(event, arg%d);\n", argIndex);
+ break;
+ default:
+ // Unsupported types: OBJECT, DOUBLE, KEY_VALUE_PAIRS
+ fprintf(stderr, "Encountered unsupported type.");
+ return 1;
+ }
+ write_annotations(out, argIndex, fieldNumberToAtomDeclSet, "AStatsEvent_",
+ "event, ");
+ argIndex++;
}
fprintf(out, " const int ret = AStatsEvent_write(event);\n");
fprintf(out, " AStatsEvent_release(event);\n");
- fprintf(out, " return ret;\n"); // end method body.
+ fprintf(out, " return ret;\n");
}
- fprintf(out, "}\n\n"); // end method.
+ fprintf(out, "}\n\n");
}
return 0;
}
-static void write_native_stats_write_non_chained_methods(FILE* out,
- const SignatureInfoMap& signatureInfoMap,
+static void write_native_stats_write_non_chained_methods(FILE* out, const Atoms& atoms,
const AtomDecl& attributionDecl) {
fprintf(out, "\n");
- for (auto signature_it = signatureInfoMap.begin();
- signature_it != signatureInfoMap.end(); signature_it++) {
+ for (auto signature_it = atoms.nonChainedSignatureInfoMap.begin();
+ signature_it != atoms.nonChainedSignatureInfoMap.end(); signature_it++) {
vector<java_type_t> signature = signature_it->first;
// Key value pairs not supported in native.
if (find(signature.begin(), signature.end(), JAVA_TYPE_KEY_VALUE_PAIR) != signature.end()) {
continue;
}
- write_native_method_signature(out, "int stats_write_non_chained(", signature,
+ write_native_method_signature(out, "int stats_write_non_chained", signature,
attributionDecl, " {");
vector<java_type_t> newSignature;
@@ -249,34 +235,6 @@ static void write_native_stats_write_non_chained_methods(FILE* out,
}
}
-static int write_native_build_stats_event_methods(FILE* out,
- const SignatureInfoMap& signatureInfoMap,
- const AtomDecl& attributionDecl) {
- fprintf(out, "\n");
- for (auto signatureInfoMapIt = signatureInfoMap.begin();
- signatureInfoMapIt != signatureInfoMap.end(); signatureInfoMapIt++) {
- vector<java_type_t> signature = signatureInfoMapIt->first;
- const FieldNumberToAtomDeclSet& fieldNumberToAtomDeclSet = signatureInfoMapIt->second;
- // Key value pairs not supported in native.
- if (find(signature.begin(), signature.end(), JAVA_TYPE_KEY_VALUE_PAIR) != signature.end()) {
- continue;
- }
- write_native_method_signature(out, "void addAStatsEvent(AStatsEventList* pulled_data, ",
- signature, attributionDecl, " {");
-
- fprintf(out, " AStatsEvent* event = AStatsEventList_addStatsEvent(pulled_data);\n");
- int ret = write_native_method_body(out, signature, fieldNumberToAtomDeclSet,
- attributionDecl);
- if (ret != 0) {
- return ret;
- }
- fprintf(out, " AStatsEvent_build(event);\n"); // end method body.
-
- fprintf(out, "}\n\n"); // end method.
- }
- return 0;
-}
-
static void write_native_method_header(FILE* out, const string& methodName,
const SignatureInfoMap& signatureInfoMap,
const AtomDecl& attributionDecl) {
@@ -304,22 +262,13 @@ int write_stats_log_cpp(FILE* out, const Atoms& atoms, const AtomDecl& attributi
fprintf(out, "#include <StatsEventCompat.h>\n");
} else {
fprintf(out, "#include <stats_event.h>\n");
-
- if (!atoms.pulledAtomsSignatureInfoMap.empty()) {
- fprintf(out, "#include <stats_pull_atom_callback.h>\n");
- }
}
-
-
fprintf(out, "\n");
write_namespace(out, cppNamespace);
- write_native_stats_write_methods(out, atoms.signatureInfoMap, attributionDecl, supportQ);
- write_native_stats_write_non_chained_methods(out, atoms.nonChainedSignatureInfoMap,
- attributionDecl);
- write_native_build_stats_event_methods(out, atoms.pulledAtomsSignatureInfoMap,
- attributionDecl);
+ write_native_stats_write_methods(out, atoms, attributionDecl, supportQ);
+ write_native_stats_write_non_chained_methods(out, atoms, attributionDecl);
// Print footer
fprintf(out, "\n");
@@ -339,9 +288,6 @@ int write_stats_log_header(FILE* out, const Atoms& atoms, const AtomDecl& attrib
fprintf(out, "#include <vector>\n");
fprintf(out, "#include <map>\n");
fprintf(out, "#include <set>\n");
- if (!atoms.pulledAtomsSignatureInfoMap.empty()) {
- fprintf(out, "#include <stats_pull_atom_callback.h>\n");
- }
fprintf(out, "\n");
write_namespace(out, cppNamespace);
@@ -391,22 +337,12 @@ int write_stats_log_header(FILE* out, const Atoms& atoms, const AtomDecl& attrib
fprintf(out, "//\n");
fprintf(out, "// Write methods\n");
fprintf(out, "//\n");
- write_native_method_header(out, "int stats_write(", atoms.signatureInfoMap, attributionDecl);
- fprintf(out, "\n");
+ write_native_method_header(out, "int stats_write", atoms.signatureInfoMap, attributionDecl);
fprintf(out, "//\n");
fprintf(out, "// Write flattened methods\n");
fprintf(out, "//\n");
- write_native_method_header(out, "int stats_write_non_chained(", atoms.nonChainedSignatureInfoMap,
- attributionDecl);
- fprintf(out, "\n");
-
- // Print pulled atoms methods.
- fprintf(out, "//\n");
- fprintf(out, "// Add AStatsEvent methods\n");
- fprintf(out, "//\n");
- write_native_method_header(out, "void addAStatsEvent(AStatsEventList* pulled_data, ",
- atoms.pulledAtomsSignatureInfoMap,
+ write_native_method_header(out, "int stats_write_non_chained", atoms.nonChainedSignatureInfoMap,
attributionDecl);
fprintf(out, "\n");
diff --git a/tools/stats_log_api_gen/utils.cpp b/tools/stats_log_api_gen/utils.cpp
index 4b3734053421..abb89133e58e 100644
--- a/tools/stats_log_api_gen/utils.cpp
+++ b/tools/stats_log_api_gen/utils.cpp
@@ -182,10 +182,10 @@ void write_native_atom_constants(FILE* out, const Atoms& atoms, const AtomDecl&
fprintf(out, "\n");
}
-void write_native_method_signature(FILE* out, const string& signaturePrefix,
+void write_native_method_signature(FILE* out, const string& methodName,
const vector<java_type_t>& signature,
const AtomDecl& attributionDecl, const string& closer) {
- fprintf(out, "%sint32_t code", signaturePrefix.c_str());
+ fprintf(out, "%s(int32_t code", methodName.c_str());
int argIndex = 1;
for (vector<java_type_t>::const_iterator arg = signature.begin(); arg != signature.end();
arg++) {
diff --git a/tools/stats_log_api_gen/utils.h b/tools/stats_log_api_gen/utils.h
index 42dc90eb79dc..73e0cb838227 100644
--- a/tools/stats_log_api_gen/utils.h
+++ b/tools/stats_log_api_gen/utils.h
@@ -59,7 +59,7 @@ void write_closing_namespace(FILE* out, const string& cppNamespaces);
void write_native_atom_constants(FILE* out, const Atoms& atoms, const AtomDecl& attributionDecl);
-void write_native_method_signature(FILE* out, const string& signaturePrefix,
+void write_native_method_signature(FILE* out, const string& methodName,
const vector<java_type_t>& signature,
const AtomDecl& attributionDecl, const string& closer);