Merge "Mark ShowImeOnAppStartWhenLaunchingAppFromFixedOrientationTest#snapshotStartingWindowLayerCoversExactlyOnApp as flaky" into main
diff --git a/TEST_MAPPING b/TEST_MAPPING
index 1b5795f..122e627 100644
--- a/TEST_MAPPING
+++ b/TEST_MAPPING
@@ -74,7 +74,15 @@
]
},
{
- "name": "ExtServicesUnitTests",
+ "name": "ExtServicesUnitTests-tplus",
+ "options": [
+ {
+ "exclude-annotation": "androidx.test.filters.FlakyTest"
+ }
+ ]
+ },
+ {
+ "name": "ExtServicesUnitTests-sminus",
"options": [
{
"exclude-annotation": "androidx.test.filters.FlakyTest"
@@ -142,7 +150,15 @@
]
},
{
- "name": "ExtServicesUnitTests",
+ "name": "ExtServicesUnitTests-tplus",
+ "options": [
+ {
+ "exclude-annotation": "androidx.test.filters.FlakyTest"
+ }
+ ]
+ },
+ {
+ "name": "ExtServicesUnitTests-sminus",
"options": [
{
"exclude-annotation": "androidx.test.filters.FlakyTest"
diff --git a/core/api/current.txt b/core/api/current.txt
index 0d73695..df8f581 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -4616,7 +4616,9 @@
public class ActivityManager {
method public int addAppTask(@NonNull android.app.Activity, @NonNull android.content.Intent, @Nullable android.app.ActivityManager.TaskDescription, @NonNull android.graphics.Bitmap);
+ method public void addStartInfoTimestamp(@IntRange(from=android.app.ApplicationStartInfo.START_TIMESTAMP_RESERVED_RANGE_DEVELOPER_START, to=android.app.ApplicationStartInfo.START_TIMESTAMP_RESERVED_RANGE_DEVELOPER) int, long);
method public void appNotResponding(@NonNull String);
+ method public void clearApplicationStartInfoCompletionListener();
method public boolean clearApplicationUserData();
method public void clearWatchHeapLimit();
method @RequiresPermission(android.Manifest.permission.DUMP) public void dumpPackageState(java.io.FileDescriptor, String);
@@ -4624,6 +4626,7 @@
method public java.util.List<android.app.ActivityManager.AppTask> getAppTasks();
method public android.content.pm.ConfigurationInfo getDeviceConfigurationInfo();
method @NonNull public java.util.List<android.app.ApplicationExitInfo> getHistoricalProcessExitReasons(@Nullable String, @IntRange(from=0) int, @IntRange(from=0) int);
+ method @NonNull public java.util.List<android.app.ApplicationStartInfo> getHistoricalProcessStartReasons(@IntRange(from=0) int);
method public int getLargeMemoryClass();
method public int getLauncherLargeIconDensity();
method public int getLauncherLargeIconSize();
@@ -4650,6 +4653,7 @@
method @RequiresPermission(android.Manifest.permission.REORDER_TASKS) public void moveTaskToFront(int, int);
method @RequiresPermission(android.Manifest.permission.REORDER_TASKS) public void moveTaskToFront(int, int, android.os.Bundle);
method @Deprecated public void restartPackage(String);
+ method public void setApplicationStartInfoCompletionListener(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<android.app.ApplicationStartInfo>);
method public void setProcessStateSummary(@Nullable byte[]);
method public static void setVrThread(int);
method public void setWatchHeapLimit(long);
@@ -5230,6 +5234,57 @@
field public static final int REASON_USER_STOPPED = 11; // 0xb
}
+ public final class ApplicationStartInfo implements android.os.Parcelable {
+ method public int describeContents();
+ method public int getDefiningUid();
+ method @Nullable public android.content.Intent getIntent();
+ method public int getLaunchMode();
+ method public int getPackageUid();
+ method public int getPid();
+ method @NonNull public String getProcessName();
+ method public int getRealUid();
+ method public int getReason();
+ method public int getStartType();
+ method public int getStartupState();
+ method @NonNull public java.util.Map<java.lang.Integer,java.lang.Long> getStartupTimestamps();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.app.ApplicationStartInfo> CREATOR;
+ field public static final int LAUNCH_MODE_SINGLE_INSTANCE = 2; // 0x2
+ field public static final int LAUNCH_MODE_SINGLE_INSTANCE_PER_TASK = 4; // 0x4
+ field public static final int LAUNCH_MODE_SINGLE_TASK = 3; // 0x3
+ field public static final int LAUNCH_MODE_SINGLE_TOP = 1; // 0x1
+ field public static final int LAUNCH_MODE_STANDARD = 0; // 0x0
+ field public static final int STARTUP_STATE_ERROR = 1; // 0x1
+ field public static final int STARTUP_STATE_FIRST_FRAME_DRAWN = 2; // 0x2
+ field public static final int STARTUP_STATE_STARTED = 0; // 0x0
+ field public static final int START_REASON_ALARM = 0; // 0x0
+ field public static final int START_REASON_BACKUP = 1; // 0x1
+ field public static final int START_REASON_BOOT_COMPLETE = 2; // 0x2
+ field public static final int START_REASON_BROADCAST = 3; // 0x3
+ field public static final int START_REASON_CONTENT_PROVIDER = 4; // 0x4
+ field public static final int START_REASON_JOB = 5; // 0x5
+ field public static final int START_REASON_LAUNCHER = 6; // 0x6
+ field public static final int START_REASON_LAUNCHER_RECENTS = 7; // 0x7
+ field public static final int START_REASON_OTHER = 8; // 0x8
+ field public static final int START_REASON_PUSH = 9; // 0x9
+ field public static final int START_REASON_SERVICE = 10; // 0xa
+ field public static final int START_REASON_START_ACTIVITY = 11; // 0xb
+ field public static final int START_TIMESTAMP_APPLICATION_ONCREATE = 2; // 0x2
+ field public static final int START_TIMESTAMP_BIND_APPLICATION = 3; // 0x3
+ field public static final int START_TIMESTAMP_FIRST_FRAME = 4; // 0x4
+ field public static final int START_TIMESTAMP_FORK = 1; // 0x1
+ field public static final int START_TIMESTAMP_FULLY_DRAWN = 5; // 0x5
+ field public static final int START_TIMESTAMP_INITIAL_RENDERTHREAD_FRAME = 6; // 0x6
+ field public static final int START_TIMESTAMP_LAUNCH = 0; // 0x0
+ field public static final int START_TIMESTAMP_RESERVED_RANGE_DEVELOPER = 30; // 0x1e
+ field public static final int START_TIMESTAMP_RESERVED_RANGE_DEVELOPER_START = 21; // 0x15
+ field public static final int START_TIMESTAMP_RESERVED_RANGE_SYSTEM = 20; // 0x14
+ field public static final int START_TIMESTAMP_SURFACEFLINGER_COMPOSITION_COMPLETE = 7; // 0x7
+ field public static final int START_TYPE_COLD = 0; // 0x0
+ field public static final int START_TYPE_HOT = 2; // 0x2
+ field public static final int START_TYPE_WARM = 1; // 0x1
+ }
+
public final class AsyncNotedAppOp implements android.os.Parcelable {
method public int describeContents();
method @Nullable public String getAttributionTag();
@@ -12764,6 +12819,7 @@
field public static final String FEATURE_TELEPHONY_RADIO_ACCESS = "android.hardware.telephony.radio.access";
field public static final String FEATURE_TELEPHONY_SUBSCRIPTION = "android.hardware.telephony.subscription";
field @Deprecated public static final String FEATURE_TELEVISION = "android.hardware.type.television";
+ field public static final String FEATURE_THREADNETWORK = "android.hardware.threadnetwork";
field public static final String FEATURE_TOUCHSCREEN = "android.hardware.touchscreen";
field public static final String FEATURE_TOUCHSCREEN_MULTITOUCH = "android.hardware.touchscreen.multitouch";
field public static final String FEATURE_TOUCHSCREEN_MULTITOUCH_DISTINCT = "android.hardware.touchscreen.multitouch.distinct";
@@ -42154,6 +42210,7 @@
method public android.telecom.GatewayInfo getGatewayInfo();
method public android.net.Uri getHandle();
method public int getHandlePresentation();
+ method @NonNull public String getId();
method public android.os.Bundle getIntentExtras();
method public final int getState();
method public android.telecom.StatusHints getStatusHints();
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index b18584b..77168e3 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -535,6 +535,7 @@
method @RequiresPermission(android.Manifest.permission.PACKAGE_USAGE_STATS) public void addOnUidImportanceListener(android.app.ActivityManager.OnUidImportanceListener, int);
method @RequiresPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) public void forceStopPackage(String);
method @RequiresPermission(anyOf={"android.permission.INTERACT_ACROSS_USERS", "android.permission.INTERACT_ACROSS_USERS_FULL"}) public static int getCurrentUser();
+ method @NonNull @RequiresPermission(android.Manifest.permission.DUMP) public java.util.List<android.app.ApplicationStartInfo> getExternalHistoricalProcessStartReasons(@NonNull String, @IntRange(from=0) int);
method @RequiresPermission(android.Manifest.permission.PACKAGE_USAGE_STATS) public int getPackageImportance(String);
method @NonNull public java.util.Collection<java.util.Locale> getSupportedLocales();
method @RequiresPermission(android.Manifest.permission.PACKAGE_USAGE_STATS) public int getUidImportance(int);
@@ -13730,6 +13731,7 @@
method public void requestStreamingState(int);
method public void writeToParcel(@NonNull android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator<android.telecom.StreamingCall> CREATOR;
+ field public static final String EXTRA_CALL_ID = "android.telecom.extra.CALL_ID";
field public static final int STATE_DISCONNECTED = 3; // 0x3
field public static final int STATE_HOLDING = 2; // 0x2
field public static final int STATE_STREAMING = 1; // 0x1
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index 37a1e62..b4f6d6f 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -72,6 +72,7 @@
import android.os.Process;
import android.os.RemoteException;
import android.os.ServiceManager;
+import android.os.SystemClock;
import android.os.SystemProperties;
import android.os.UserHandle;
import android.os.UserManager;
@@ -107,6 +108,7 @@
import java.util.List;
import java.util.Locale;
import java.util.concurrent.Executor;
+import java.util.function.Consumer;
/**
* <p>
@@ -3978,8 +3980,6 @@
*
* @return a list of {@link ApplicationStartInfo} records matching the criteria, sorted in
* the order from most recent to least recent.
- *
- * @hide
*/
@NonNull
public List<ApplicationStartInfo> getHistoricalProcessStartReasons(
@@ -4011,6 +4011,7 @@
* @hide
*/
@NonNull
+ @SystemApi
@RequiresPermission(Manifest.permission.DUMP)
public List<ApplicationStartInfo> getExternalHistoricalProcessStartReasons(
@NonNull String packageName, @IntRange(from = 0) int maxNum) {
@@ -4024,18 +4025,6 @@
}
/**
- * Callback to receive {@link ApplicationStartInfo} object once recording of startup related
- * metrics is complete.
- * Use with {@link #setApplicationStartInfoCompleteListener}.
- *
- * @hide
- */
- public interface ApplicationStartInfoCompleteListener {
- /** {@link ApplicationStartInfo} is complete, no more info will be added. */
- void onApplicationStartInfoComplete(@NonNull ApplicationStartInfo applicationStartInfo);
- }
-
- /**
* Sets a callback to be notified when the {@link ApplicationStartInfo} records of this startup
* are complete.
*
@@ -4054,19 +4043,16 @@
* complete. Will replace existing listener if one is already attached.
*
* @throws IllegalArgumentException if executor or listener are null.
- *
- * @hide
*/
- public void setApplicationStartInfoCompleteListener(@NonNull final Executor executor,
- @NonNull final ApplicationStartInfoCompleteListener listener) {
+ public void setApplicationStartInfoCompletionListener(@NonNull final Executor executor,
+ @NonNull final Consumer<ApplicationStartInfo> listener) {
Preconditions.checkNotNull(executor, "executor cannot be null");
Preconditions.checkNotNull(listener, "listener cannot be null");
IApplicationStartInfoCompleteListener callback =
new IApplicationStartInfoCompleteListener.Stub() {
@Override
public void onApplicationStartInfoComplete(ApplicationStartInfo applicationStartInfo) {
- executor.execute(() ->
- listener.onApplicationStartInfoComplete(applicationStartInfo));
+ executor.execute(() -> listener.accept(applicationStartInfo));
}
};
try {
@@ -4077,13 +4063,42 @@
}
/**
- * Removes the callback set by {@link #setApplicationStartInfoCompleteListener} if there is one.
- *
- * @hide
+ * Removes the callback set by {@link #setApplicationStartInfoCompletionListener} if there is one.
*/
- public void removeApplicationStartInfoCompleteListener() {
+ public void clearApplicationStartInfoCompletionListener() {
try {
- getService().removeApplicationStartInfoCompleteListener(mContext.getUserId());
+ getService().clearApplicationStartInfoCompleteListener(mContext.getUserId());
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Adds an optional developer supplied timestamp to the calling apps most recent
+ * {@link ApplicationStartInfo}. This is in addition to system recorded timestamps.
+ *
+ * <p class="note"> Note: timestamps added after {@link Activity#reportFullyDrawn} is called
+ * will be discarded.</p>
+ *
+ * <p class="note"> Note: will overwrite existing timestamp if called with same key.</p>
+ *
+ * @param key Unique key for timestamp. Must be greater than
+ * {@link ApplicationStartInfo#START_TIMESTAMP_RESERVED_RANGE_SYSTEM} and
+ * less than or equal to
+ * {@link ApplicationStartInfo#START_TIMESTAMP_RESERVED_RANGE_DEVELOPER}.
+ * Will thow {@link java.lang.IllegalArgumentException} if not in range.
+ * @param timestampNs Clock monotonic time in nanoseconds of event to be recorded.
+ */
+ public void addStartInfoTimestamp(@IntRange(
+ from = ApplicationStartInfo.START_TIMESTAMP_RESERVED_RANGE_DEVELOPER_START,
+ to = ApplicationStartInfo.START_TIMESTAMP_RESERVED_RANGE_DEVELOPER) int key,
+ long timestampNs) {
+ if (key <= ApplicationStartInfo.START_TIMESTAMP_RESERVED_RANGE_SYSTEM
+ || key > ApplicationStartInfo.START_TIMESTAMP_RESERVED_RANGE_DEVELOPER) {
+ throw new IllegalArgumentException("Key not in allowed range.");
+ }
+ try {
+ getService().addStartInfoTimestamp(key, timestampNs, mContext.getUserId());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
diff --git a/core/java/android/app/ApplicationStartInfo.java b/core/java/android/app/ApplicationStartInfo.java
index 5e2a4ca..f5fb6ed 100644
--- a/core/java/android/app/ApplicationStartInfo.java
+++ b/core/java/android/app/ApplicationStartInfo.java
@@ -21,20 +21,21 @@
import android.annotation.Nullable;
import android.annotation.SuppressLint;
import android.content.Intent;
+import android.icu.text.SimpleDateFormat;
import android.os.Parcel;
import android.os.Parcelable;
+import android.os.UserHandle;
+import android.util.ArrayMap;
-import java.lang.annotation.ElementType;
+import java.io.PrintWriter;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-import java.util.HashMap;
+import java.util.Iterator;
import java.util.Map;
+import java.util.Set;
/**
* Provide information related to a processes startup.
- *
- * @hide
*/
public final class ApplicationStartInfo implements Parcelable {
@@ -78,14 +79,14 @@
/** Process started due to click app icon or widget from launcher. */
public static final int START_REASON_LAUNCHER = 6;
+ /** Process started from launcher recents. */
+ public static final int START_REASON_LAUNCHER_RECENTS = 7;
+
/** Process started not for any of the listed reasons. */
- public static final int START_REASON_OTHER = 7;
+ public static final int START_REASON_OTHER = 8;
/** Process started due to push message. */
- public static final int START_REASON_PUSH = 8;
-
- /** Process started to resume activity. */
- public static final int START_REASON_RESUMED_ACTIVITY = 9;
+ public static final int START_REASON_PUSH = 9;
/** Process service started. */
public static final int START_REASON_SERVICE = 10;
@@ -136,11 +137,21 @@
*/
public static final int LAUNCH_MODE_SINGLE_INSTANCE_PER_TASK = 4;
+ /** The end of the range, beginning with 0, reserved for system timestamps.*/
+ public static final int START_TIMESTAMP_RESERVED_RANGE_SYSTEM = 20;
+
+ /** The beginning of the range reserved for developer supplied timestamps.*/
+ public static final int START_TIMESTAMP_RESERVED_RANGE_DEVELOPER_START =
+ START_TIMESTAMP_RESERVED_RANGE_SYSTEM + 1;
+
+ /** The end of the range reserved for developer supplied timestamps.*/
+ public static final int START_TIMESTAMP_RESERVED_RANGE_DEVELOPER = 30;
+
/** Clock monotonic timestamp of launch started. */
public static final int START_TIMESTAMP_LAUNCH = 0;
- /** Clock monotonic timestamp of finish java classloading. */
- public static final int START_TIMESTAMP_JAVA_CLASSLOADING_COMPLETE = 1;
+ /** Clock monotonic timestamp of process fork. */
+ public static final int START_TIMESTAMP_FORK = 1;
/** Clock monotonic timestamp of Application onCreate called. */
public static final int START_TIMESTAMP_APPLICATION_ONCREATE = 2;
@@ -154,6 +165,12 @@
/** Clock monotonic timestamp of reportFullyDrawn called by application. */
public static final int START_TIMESTAMP_FULLY_DRAWN = 5;
+ /** Clock monotonic timestamp of initial renderthread frame. */
+ public static final int START_TIMESTAMP_INITIAL_RENDERTHREAD_FRAME = 6;
+
+ /** Clock monotonic timestamp of surfaceflinger composition complete. */
+ public static final int START_TIMESTAMP_SURFACEFLINGER_COMPOSITION_COMPLETE = 7;
+
/**
* @see #getStartupState
*/
@@ -192,7 +209,7 @@
/**
* @see #getStartupTimestamps
*/
- private Map<@StartupTimestamp Integer, Long> mStartupTimestampsNs;
+ private ArrayMap<Integer, Long> mStartupTimestampsNs;
/**
* @see #getStartType
@@ -235,9 +252,9 @@
START_REASON_CONTENT_PROVIDER,
START_REASON_JOB,
START_REASON_LAUNCHER,
+ START_REASON_LAUNCHER_RECENTS,
START_REASON_OTHER,
START_REASON_PUSH,
- START_REASON_RESUMED_ACTIVITY,
START_REASON_SERVICE,
START_REASON_START_ACTIVITY,
})
@@ -273,22 +290,6 @@
public @interface LaunchMode {}
/**
- * @hide *
- */
- @IntDef(
- prefix = {"START_TIMESTAMP_"},
- value = {
- START_TIMESTAMP_LAUNCH,
- START_TIMESTAMP_JAVA_CLASSLOADING_COMPLETE,
- START_TIMESTAMP_APPLICATION_ONCREATE,
- START_TIMESTAMP_BIND_APPLICATION,
- START_TIMESTAMP_FULLY_DRAWN,
- })
- @Retention(RetentionPolicy.SOURCE)
- @Target({ElementType.TYPE_PARAMETER, ElementType.TYPE_USE})
- public @interface StartupTimestamp {}
-
- /**
* @see #getStartupState
* @hide
*/
@@ -348,9 +349,12 @@
* @see #getStartupTimestamps
* @hide
*/
- public void addStartupTimestamp(@StartupTimestamp int key, long timestampNs) {
+ public void addStartupTimestamp(int key, long timestampNs) {
+ if (key < 0 || key > START_TIMESTAMP_RESERVED_RANGE_DEVELOPER) {
+ return;
+ }
if (mStartupTimestampsNs == null) {
- mStartupTimestampsNs = new HashMap<@StartupTimestamp Integer, Long>();
+ mStartupTimestampsNs = new ArrayMap<Integer, Long>();
}
mStartupTimestampsNs.put(key, timestampNs);
}
@@ -475,9 +479,9 @@
* dependant on devloper calling {@link Activity#reportFullyDrawn}.
* </p>
*/
- public @NonNull Map<@StartupTimestamp Integer, Long> getStartupTimestamps() {
+ public @NonNull Map<Integer, Long> getStartupTimestamps() {
if (mStartupTimestampsNs == null) {
- mStartupTimestampsNs = new HashMap<@StartupTimestamp Integer, Long>();
+ mStartupTimestampsNs = new ArrayMap<Integer, Long>();
}
return mStartupTimestampsNs;
}
@@ -536,9 +540,12 @@
dest.writeString(mProcessName);
dest.writeInt(mReason);
dest.writeInt(mStartupTimestampsNs.size());
- for (@StartupTimestamp int key : mStartupTimestampsNs.keySet()) {
- dest.writeInt(key);
- dest.writeLong(mStartupTimestampsNs.get(key));
+ Set<Map.Entry<Integer, Long>> timestampEntrySet = mStartupTimestampsNs.entrySet();
+ Iterator<Map.Entry<Integer, Long>> iter = timestampEntrySet.iterator();
+ while (iter.hasNext()) {
+ Map.Entry<Integer, Long> entry = iter.next();
+ dest.writeInt(entry.getKey());
+ dest.writeLong(entry.getValue());
}
dest.writeInt(mStartType);
dest.writeParcelable(mStartIntent, flags);
@@ -599,4 +606,67 @@
return new ApplicationStartInfo[size];
}
};
+
+ /** @hide */
+ public void dump(@NonNull PrintWriter pw, @Nullable String prefix, @Nullable String seqSuffix,
+ @NonNull SimpleDateFormat sdf) {
+ StringBuilder sb = new StringBuilder();
+ sb.append(prefix)
+ .append("ApplicationStartInfo ").append(seqSuffix).append(':')
+ .append('\n')
+ .append(" pid=").append(mPid)
+ .append(" realUid=").append(mRealUid)
+ .append(" packageUid=").append(mPackageUid)
+ .append(" definingUid=").append(mDefiningUid)
+ .append(" user=").append(UserHandle.getUserId(mPackageUid))
+ .append('\n')
+ .append(" process=").append(mProcessName)
+ .append(" startupState=").append(mStartupState)
+ .append(" reason=").append(reasonToString(mReason))
+ .append(" startType=").append(startTypeToString(mStartType))
+ .append(" launchMode=").append(mLaunchMode)
+ .append('\n');
+ if (mStartIntent != null) {
+ sb.append(" intent=").append(mStartIntent.toString())
+ .append('\n');
+ }
+ if (mStartupTimestampsNs.size() > 0) {
+ sb.append(" timestamps: ");
+ Set<Map.Entry<Integer, Long>> timestampEntrySet = mStartupTimestampsNs.entrySet();
+ Iterator<Map.Entry<Integer, Long>> iter = timestampEntrySet.iterator();
+ while (iter.hasNext()) {
+ Map.Entry<Integer, Long> entry = iter.next();
+ sb.append(entry.getKey()).append("=").append(entry.getValue()).append(" ");
+ }
+ sb.append('\n');
+ }
+ pw.print(sb.toString());
+ }
+
+ private static String reasonToString(@StartReason int reason) {
+ return switch (reason) {
+ case START_REASON_ALARM -> "ALARM";
+ case START_REASON_BACKUP -> "BACKUP";
+ case START_REASON_BOOT_COMPLETE -> "BOOT COMPLETE";
+ case START_REASON_BROADCAST -> "BROADCAST";
+ case START_REASON_CONTENT_PROVIDER -> "CONTENT PROVIDER";
+ case START_REASON_JOB -> "JOB";
+ case START_REASON_LAUNCHER -> "LAUNCHER";
+ case START_REASON_LAUNCHER_RECENTS -> "LAUNCHER RECENTS";
+ case START_REASON_OTHER -> "OTHER";
+ case START_REASON_PUSH -> "PUSH";
+ case START_REASON_SERVICE -> "SERVICE";
+ case START_REASON_START_ACTIVITY -> "START ACTIVITY";
+ default -> "";
+ };
+ }
+
+ private static String startTypeToString(@StartType int startType) {
+ return switch (startType) {
+ case START_TYPE_COLD -> "COLD";
+ case START_TYPE_WARM -> "WARM";
+ case START_TYPE_HOT -> "HOT";
+ default -> "";
+ };
+ }
}
diff --git a/core/java/android/app/IActivityManager.aidl b/core/java/android/app/IActivityManager.aidl
index a8b1688..03baf26 100644
--- a/core/java/android/app/IActivityManager.aidl
+++ b/core/java/android/app/IActivityManager.aidl
@@ -724,7 +724,20 @@
*
* @param userId The userId in the multi-user environment.
*/
- void removeApplicationStartInfoCompleteListener(int userId);
+ void clearApplicationStartInfoCompleteListener(int userId);
+
+
+ /**
+ * Adds a timestamp of the moment called to the calling apps most recent
+ * {@link ApplicationStartInfo}.
+ *
+ *
+ * @param key Unique key for timestamp.
+ * @param timestampNs Clock monotonic time in nanoseconds of event to be
+ * recorded.
+ * @param userId The userId in the multi-user environment.
+ */
+ void addStartInfoTimestamp(int key, long timestampNs, int userId);
/**
* Return a list of {@link ApplicationExitInfo} records.
diff --git a/core/java/android/app/TEST_MAPPING b/core/java/android/app/TEST_MAPPING
index 8da8442..394f9e7 100644
--- a/core/java/android/app/TEST_MAPPING
+++ b/core/java/android/app/TEST_MAPPING
@@ -59,7 +59,7 @@
"file_patterns": ["INotificationManager\\.aidl"]
},
{
- "name": "CtsWindowManagerDeviceTestCases",
+ "name": "CtsWindowManagerDeviceWindow",
"options": [
{
"include-filter": "android.server.wm.window.ToastWindowTest"
@@ -244,8 +244,143 @@
"(/|^)DeviceFeature[^/]*", "(/|^)Hdmi[^/]*"
]
},
+{
+ "name": "CtsWindowManagerDeviceActivity",
+ "options": [
+ {
+ "exclude-annotation": "androidx.test.filters.FlakyTest"
+ },
+ {
+ "exclude-annotation": "org.junit.Ignore"
+ },
+ {
+ "include-filter": "android.content.wm.cts"
+ }
+ ],
+ "file_patterns": ["(/|^)ContextImpl.java"]
+ },
{
- "name": "CtsWindowManagerTestCases",
+ "name": "CtsWindowManagerDeviceAm",
+ "options": [
+ {
+ "exclude-annotation": "androidx.test.filters.FlakyTest"
+ },
+ {
+ "exclude-annotation": "org.junit.Ignore"
+ },
+ {
+ "include-filter": "android.content.wm.cts"
+ }
+ ],
+ "file_patterns": ["(/|^)ContextImpl.java"]
+ },
+ {
+ "name": "CtsWindowManagerDeviceBackNavigation",
+ "options": [
+ {
+ "exclude-annotation": "androidx.test.filters.FlakyTest"
+ },
+ {
+ "exclude-annotation": "org.junit.Ignore"
+ },
+ {
+ "include-filter": "android.content.wm.cts"
+ }
+ ],
+ "file_patterns": ["(/|^)ContextImpl.java"]
+ },
+ {
+ "name": "CtsWindowManagerDeviceDisplay",
+ "options": [
+ {
+ "exclude-annotation": "androidx.test.filters.FlakyTest"
+ },
+ {
+ "exclude-annotation": "org.junit.Ignore"
+ },
+ {
+ "include-filter": "android.content.wm.cts"
+ }
+ ],
+ "file_patterns": ["(/|^)ContextImpl.java"]
+ },
+ {
+ "name": "CtsWindowManagerDeviceKeyguard",
+ "options": [
+ {
+ "exclude-annotation": "androidx.test.filters.FlakyTest"
+ },
+ {
+ "exclude-annotation": "org.junit.Ignore"
+ },
+ {
+ "include-filter": "android.content.wm.cts"
+ }
+ ],
+ "file_patterns": ["(/|^)ContextImpl.java"]
+ },
+ {
+ "name": "CtsWindowManagerDeviceInsets",
+ "options": [
+ {
+ "exclude-annotation": "androidx.test.filters.FlakyTest"
+ },
+ {
+ "exclude-annotation": "org.junit.Ignore"
+ },
+ {
+ "include-filter": "android.content.wm.cts"
+ }
+ ],
+ "file_patterns": ["(/|^)ContextImpl.java"]
+ },
+ {
+ "name": "CtsWindowManagerDeviceTaskFragment",
+ "options": [
+ {
+ "exclude-annotation": "androidx.test.filters.FlakyTest"
+ },
+ {
+ "exclude-annotation": "org.junit.Ignore"
+ },
+ {
+ "include-filter": "android.content.wm.cts"
+ }
+ ],
+ "file_patterns": ["(/|^)ContextImpl.java"]
+ },
+ {
+ "name": "CtsWindowManagerDeviceScvh",
+ "options": [
+ {
+ "exclude-annotation": "androidx.test.filters.FlakyTest"
+ },
+ {
+ "exclude-annotation": "org.junit.Ignore"
+ },
+ {
+ "include-filter": "android.content.wm.cts"
+ }
+ ],
+ "file_patterns": ["(/|^)ContextImpl.java"]
+ },
+ {
+ "name": "CtsWindowManagerDeviceWindow",
+ "options": [
+ {
+ "exclude-annotation": "androidx.test.filters.FlakyTest"
+ },
+ {
+ "exclude-annotation": "org.junit.Ignore"
+ },
+ {
+ "include-filter": "android.content.wm.cts"
+ }
+ ],
+ "file_patterns": ["(/|^)ContextImpl.java"]
+ },
+ {
+ "name": "CtsWindowManagerDeviceOther",
"options": [
{
"exclude-annotation": "androidx.test.filters.FlakyTest"
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 289519d..d9a61ae 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -3692,6 +3692,14 @@
/**
* Feature for {@link #getSystemAvailableFeatures} and
* {@link #hasSystemFeature}: The device is capable of communicating with
+ * other devices via Thread network.
+ */
+ @SdkConstant(SdkConstantType.FEATURE)
+ public static final String FEATURE_THREADNETWORK = "android.hardware.threadnetwork";
+
+ /**
+ * Feature for {@link #getSystemAvailableFeatures} and
+ * {@link #hasSystemFeature}: The device is capable of communicating with
* other devices via ultra wideband.
*/
@SdkConstant(SdkConstantType.FEATURE)
diff --git a/core/java/android/widget/TEST_MAPPING b/core/java/android/widget/TEST_MAPPING
index 49c4093..107cac2 100644
--- a/core/java/android/widget/TEST_MAPPING
+++ b/core/java/android/widget/TEST_MAPPING
@@ -10,10 +10,10 @@
"file_patterns": ["Toast\\.java"]
},
{
- "name": "CtsWindowManagerDeviceTestCases",
+ "name": "CtsWindowManagerDeviceWindow",
"options": [
{
- "include-filter": "android.server.wm.ToastWindowTest"
+ "include-filter": "android.server.wm.window.ToastWindowTest"
}
],
"file_patterns": ["Toast\\.java"]
diff --git a/packages/SystemUI/src/com/android/systemui/CoreStartable.java b/packages/SystemUI/src/com/android/systemui/CoreStartable.java
index becf5b3..c07a4d2 100644
--- a/packages/SystemUI/src/com/android/systemui/CoreStartable.java
+++ b/packages/SystemUI/src/com/android/systemui/CoreStartable.java
@@ -53,6 +53,11 @@
default void dump(@NonNull PrintWriter pw, @NonNull String[] args) {
}
+ /** Called to determine if the dumpable should be registered as critical or normal priority */
+ default boolean isDumpCritical() {
+ return true;
+ }
+
/** Called immediately after the system broadcasts
* {@link android.content.Intent#ACTION_LOCKED_BOOT_COMPLETED} or during SysUI startup if the
* property {@code sys.boot_completed} is already set to 1. The latter typically occurs when
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java b/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
index 522b397..38298cf 100644
--- a/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
@@ -254,11 +254,16 @@
}
for (i = 0; i < mServices.length; i++) {
+ final CoreStartable service = mServices[i];
if (mBootCompleteCache.isBootComplete()) {
- notifyBootCompleted(mServices[i]);
+ notifyBootCompleted(service);
}
- dumpManager.registerDumpable(mServices[i].getClass().getSimpleName(), mServices[i]);
+ if (service.isDumpCritical()) {
+ dumpManager.registerCriticalDumpable(service);
+ } else {
+ dumpManager.registerNormalDumpable(service);
+ }
}
mSysUIComponent.getInitController().executePostInitTasks();
log.traceEnd();
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/ReferenceSysUIComponent.java b/packages/SystemUI/src/com/android/systemui/dagger/ReferenceSysUIComponent.java
index 94b2ab1..046ccf16 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/ReferenceSysUIComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/ReferenceSysUIComponent.java
@@ -18,7 +18,6 @@
import com.android.systemui.globalactions.ShutdownUiModule;
import com.android.systemui.keyguard.CustomizationProvider;
-import com.android.systemui.scene.startable.SceneContainerStartableModule;
import com.android.systemui.shade.ShadeModule;
import com.android.systemui.statusbar.NotificationInsetsModule;
import com.android.systemui.statusbar.QsFrameTranslateModule;
@@ -36,7 +35,6 @@
QsFrameTranslateModule.class,
ShadeModule.class,
ShutdownUiModule.class,
- SceneContainerStartableModule.class,
SystemUIBinder.class,
SystemUIModule.class,
SystemUICoreStartableModule.class,
diff --git a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
index c11e485..66813f9 100644
--- a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
+++ b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
@@ -112,6 +112,12 @@
default = true
)
+ /** Only notify group expansion listeners when a change happens. */
+ // TODO(b/292213543): Tracking Bug
+ @JvmField
+ val NOTIFICATION_GROUP_EXPANSION_CHANGE =
+ unreleasedFlag(292213543, "notification_group_expansion_change", teamfood = false)
+
// 200 - keyguard/lockscreen
// ** Flag retired **
// public static final BooleanFlag KEYGUARD_LAYOUT =
diff --git a/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskController.kt b/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskController.kt
index 48790c2..2adc211 100644
--- a/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskController.kt
+++ b/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskController.kt
@@ -41,6 +41,8 @@
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.devicepolicy.areKeyguardShortcutsDisabled
import com.android.systemui.log.DebugLogger.debugLog
+import com.android.systemui.notetask.NoteTaskEntryPoint.QUICK_AFFORDANCE
+import com.android.systemui.notetask.NoteTaskEntryPoint.TAIL_BUTTON
import com.android.systemui.notetask.NoteTaskRoleManagerExt.createNoteShortcutInfoAsUser
import com.android.systemui.notetask.NoteTaskRoleManagerExt.getDefaultRoleHolderAsUser
import com.android.systemui.notetask.shortcut.CreateNoteTaskShortcutActivity
@@ -121,23 +123,26 @@
/**
* Returns the [UserHandle] of an android user that should handle the notes taking [entryPoint].
- *
- * On company owned personally enabled (COPE) devices, if the given [entryPoint] is in the
- * [FORCE_WORK_NOTE_APPS_ENTRY_POINTS_ON_COPE_DEVICES] list, the default notes app in the work
- * profile user will always be launched.
- *
- * On non managed devices or devices with other management modes, the current [UserHandle] is
- * returned.
+ * 1. tail button entry point: In COPE or work profile devices, the user can select whether the
+ * work or main profile notes app should be launched in the Settings app. In non-management
+ * or device owner devices, the user can only select main profile notes app.
+ * 2. lock screen quick affordance: since there is no user setting, the main profile notes app
+ * is used as default for work profile devices while the work profile notes app is used for
+ * COPE devices.
+ * 3. Other entry point: the current user from [UserTracker.userHandle].
*/
fun getUserForHandlingNotesTaking(entryPoint: NoteTaskEntryPoint): UserHandle =
- if (
- entryPoint in FORCE_WORK_NOTE_APPS_ENTRY_POINTS_ON_COPE_DEVICES &&
- devicePolicyManager.isOrganizationOwnedDeviceWithManagedProfile
- ) {
- userTracker.userProfiles.firstOrNull { userManager.isManagedProfile(it.id) }?.userHandle
- ?: userTracker.userHandle
- } else {
- secureSettings.preferredUser
+ when {
+ entryPoint == TAIL_BUTTON -> secureSettings.preferredUser
+ devicePolicyManager.isOrganizationOwnedDeviceWithManagedProfile &&
+ entryPoint == QUICK_AFFORDANCE -> {
+ userTracker.userProfiles
+ .firstOrNull { userManager.isManagedProfile(it.id) }
+ ?.userHandle
+ ?: userTracker.userHandle
+ }
+ // On work profile devices, SysUI always run in the main user.
+ else -> userTracker.userHandle
}
/**
@@ -267,15 +272,7 @@
PackageManager.COMPONENT_ENABLED_STATE_DISABLED
}
- // If the required user matches the tracking user, the injected context is already a context
- // of the required user. Avoid calling #createContextAsUser because creating a context for
- // a user takes time.
- val userContext =
- if (user == userTracker.userHandle) {
- context
- } else {
- context.createContextAsUser(user, /* flags= */ 0)
- }
+ val userContext = context.createContextAsUser(user, /* flags= */ 0)
userContext.packageManager.setComponentEnabledSetting(
componentName,
@@ -283,7 +280,7 @@
PackageManager.DONT_KILL_APP,
)
- debugLog { "setNoteTaskShortcutEnabled - completed: $isEnabled" }
+ debugLog { "setNoteTaskShortcutEnabled for user $user- completed: $enabledState" }
}
/**
@@ -359,10 +356,12 @@
private val SecureSettings.preferredUser: UserHandle
get() {
+ val trackingUserId = userTracker.userHandle.identifier
val userId =
- secureSettings.getInt(
- Settings.Secure.DEFAULT_NOTE_TASK_PROFILE,
- userTracker.userHandle.identifier,
+ secureSettings.getIntForUser(
+ /* name= */ Settings.Secure.DEFAULT_NOTE_TASK_PROFILE,
+ /* def= */ trackingUserId,
+ /* userHandle= */ trackingUserId,
)
return UserHandle.of(userId)
}
@@ -381,16 +380,6 @@
* @see com.android.launcher3.icons.IconCache.EXTRA_SHORTCUT_BADGE_OVERRIDE_PACKAGE
*/
const val EXTRA_SHORTCUT_BADGE_OVERRIDE_PACKAGE = "extra_shortcut_badge_override_package"
-
- /**
- * A list of entry points which should be redirected to the work profile default notes app
- * on company owned personally enabled (COPE) devices.
- *
- * Entry points in this list don't let users / admin to select the work or personal default
- * notes app to be launched.
- */
- val FORCE_WORK_NOTE_APPS_ENTRY_POINTS_ON_COPE_DEVICES =
- listOf(NoteTaskEntryPoint.TAIL_BUTTON, NoteTaskEntryPoint.QUICK_AFFORDANCE)
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/scene/SceneContainerFrameworkModule.kt b/packages/SystemUI/src/com/android/systemui/scene/SceneContainerFrameworkModule.kt
index 26c5219..0a9839e 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/SceneContainerFrameworkModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/SceneContainerFrameworkModule.kt
@@ -16,7 +16,6 @@
package com.android.systemui.scene
-import com.android.systemui.scene.domain.startable.SceneContainerStartableModule
import com.android.systemui.scene.shared.model.SceneContainerConfigModule
import com.android.systemui.scene.ui.composable.SceneModule
import com.android.systemui.scene.ui.viewmodel.SceneContainerViewModelModule
@@ -26,7 +25,6 @@
includes =
[
SceneContainerConfigModule::class,
- SceneContainerStartableModule::class,
SceneContainerViewModelModule::class,
SceneModule::class,
],
diff --git a/packages/SystemUI/src/com/android/systemui/scene/startable/SceneContainerStartable.kt b/packages/SystemUI/src/com/android/systemui/scene/startable/SceneContainerStartable.kt
deleted file mode 100644
index a29e92a..0000000
--- a/packages/SystemUI/src/com/android/systemui/scene/startable/SceneContainerStartable.kt
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.scene.startable
-
-import com.android.systemui.CoreStartable
-import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.scene.shared.model.Scene
-import com.android.systemui.scene.shared.model.SceneContainerConfig
-import com.android.systemui.scene.shared.model.SceneContainerNames
-import com.android.systemui.scene.ui.view.SceneWindowRootView
-import com.android.systemui.scene.ui.view.WindowRootView
-import com.android.systemui.scene.ui.viewmodel.SceneContainerViewModel
-import dagger.Binds
-import dagger.Module
-import dagger.multibindings.ClassKey
-import dagger.multibindings.IntoMap
-import javax.inject.Inject
-import javax.inject.Named
-
-@SysUISingleton
-class SceneContainerStartable
-@Inject
-constructor(
- private val view: WindowRootView,
- @Named(SceneContainerNames.SYSTEM_UI_DEFAULT) private val viewModel: SceneContainerViewModel,
- @Named(SceneContainerNames.SYSTEM_UI_DEFAULT) private val containerConfig: SceneContainerConfig,
- @Named(SceneContainerNames.SYSTEM_UI_DEFAULT)
- private val scenes: Set<@JvmSuppressWildcards Scene>,
-) : CoreStartable {
-
- override fun start() {
- (view as? SceneWindowRootView)?.init(
- viewModel = viewModel,
- containerConfig = containerConfig,
- scenes = scenes,
- )
- }
-}
-
-@Module
-interface SceneContainerStartableModule {
- @Binds
- @IntoMap
- @ClassKey(SceneContainerStartable::class)
- fun bind(impl: SceneContainerStartable): CoreStartable
-}
diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
index e428976..ed7cbff 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
@@ -28,6 +28,7 @@
import static com.android.systemui.classifier.Classifier.GENERIC;
import static com.android.systemui.classifier.Classifier.QUICK_SETTINGS;
import static com.android.systemui.classifier.Classifier.UNLOCK;
+import static com.android.systemui.flags.Flags.ONE_WAY_HAPTICS_API_MIGRATION;
import static com.android.systemui.navigationbar.gestural.Utilities.isTrackpadScroll;
import static com.android.systemui.navigationbar.gestural.Utilities.isTrackpadThreeFingerSwipe;
import static com.android.systemui.shade.ShadeExpansionStateManagerKt.STATE_CLOSED;
@@ -70,6 +71,7 @@
import android.util.IndentingPrintWriter;
import android.util.Log;
import android.util.MathUtils;
+import android.view.HapticFeedbackConstants;
import android.view.InputDevice;
import android.view.LayoutInflater;
import android.view.MotionEvent;
@@ -2632,12 +2634,16 @@
}
if (!mStatusBarStateController.isDozing()) {
- mVibratorHelper.vibrate(
- Process.myUid(),
- mView.getContext().getPackageName(),
- ADDITIONAL_TAP_REQUIRED_VIBRATION_EFFECT,
- "falsing-additional-tap-required",
- TOUCH_VIBRATION_ATTRIBUTES);
+ if (mFeatureFlags.isEnabled(ONE_WAY_HAPTICS_API_MIGRATION)) {
+ mVibratorHelper.performHapticFeedback(mView, HapticFeedbackConstants.REJECT);
+ } else {
+ mVibratorHelper.vibrate(
+ Process.myUid(),
+ mView.getContext().getPackageName(),
+ ADDITIONAL_TAP_REQUIRED_VIBRATION_EFFECT,
+ "falsing-additional-tap-required",
+ TOUCH_VIBRATION_ATTRIBUTES);
+ }
}
}
@@ -3504,7 +3510,14 @@
private void maybeVibrateOnOpening(boolean openingWithTouch) {
if (mVibrateOnOpening && mBarState != KEYGUARD && mBarState != SHADE_LOCKED) {
if (!openingWithTouch || !mHasVibratedOnOpen) {
- mVibratorHelper.vibrate(VibrationEffect.EFFECT_TICK);
+ if (mFeatureFlags.isEnabled(ONE_WAY_HAPTICS_API_MIGRATION)) {
+ mVibratorHelper.performHapticFeedback(
+ mView,
+ HapticFeedbackConstants.GESTURE_START
+ );
+ } else {
+ mVibratorHelper.vibrate(VibrationEffect.EFFECT_TICK);
+ }
mHasVibratedOnOpen = true;
mShadeLog.v("Vibrating on opening, mHasVibratedOnOpen=true");
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/NetworkControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/NetworkControllerImpl.java
index 93b9ac6..f381b37 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/NetworkControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/NetworkControllerImpl.java
@@ -83,8 +83,6 @@
import com.android.systemui.telephony.TelephonyListenerManager;
import com.android.systemui.util.CarrierConfigTracker;
-import kotlin.Unit;
-
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
@@ -99,6 +97,8 @@
import javax.inject.Inject;
+import kotlin.Unit;
+
/** Platform implementation of the network controller. **/
@SysUISingleton
public class NetworkControllerImpl extends BroadcastReceiver
@@ -465,7 +465,7 @@
mDemoModeController.addCallback(this);
- mDumpManager.registerDumpable(TAG, this);
+ mDumpManager.registerNormalDumpable(TAG, this);
}
private final Runnable mClearForceValidated = () -> {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/GroupExpansionManagerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/GroupExpansionManagerImpl.java
index 4568c0c..46af03a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/GroupExpansionManagerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/GroupExpansionManagerImpl.java
@@ -21,6 +21,8 @@
import com.android.systemui.Dumpable;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dump.DumpManager;
+import com.android.systemui.flags.FeatureFlags;
+import com.android.systemui.flags.Flags;
import com.android.systemui.statusbar.notification.collection.GroupEntry;
import com.android.systemui.statusbar.notification.collection.ListEntry;
import com.android.systemui.statusbar.notification.collection.NotifPipeline;
@@ -44,14 +46,21 @@
private final GroupMembershipManager mGroupMembershipManager;
private final Set<OnGroupExpansionChangeListener> mOnGroupChangeListeners = new HashSet<>();
- // Set of summary keys whose groups are expanded
+ /**
+ * Set of summary keys whose groups are expanded.
+ * NOTE: This should not be modified without notifying listeners, so prefer using
+ * {@code setGroupExpanded} when making changes.
+ */
private final Set<NotificationEntry> mExpandedGroups = new HashSet<>();
+ private final FeatureFlags mFeatureFlags;
+
@Inject
public GroupExpansionManagerImpl(DumpManager dumpManager,
- GroupMembershipManager groupMembershipManager) {
+ GroupMembershipManager groupMembershipManager, FeatureFlags featureFlags) {
mDumpManager = dumpManager;
mGroupMembershipManager = groupMembershipManager;
+ mFeatureFlags = featureFlags;
}
/**
@@ -85,13 +94,17 @@
@Override
public void setGroupExpanded(NotificationEntry entry, boolean expanded) {
final NotificationEntry groupSummary = mGroupMembershipManager.getGroupSummary(entry);
+ boolean changed;
if (expanded) {
- mExpandedGroups.add(groupSummary);
+ changed = mExpandedGroups.add(groupSummary);
} else {
- mExpandedGroups.remove(groupSummary);
+ changed = mExpandedGroups.remove(groupSummary);
}
- sendOnGroupExpandedChange(entry, expanded);
+ // Only notify listeners if something changed.
+ if (!mFeatureFlags.isEnabled(Flags.NOTIFICATION_GROUP_EXPANSION_CHANGE) || changed) {
+ sendOnGroupExpandedChange(entry, expanded);
+ }
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java b/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java
index 943e906..6fafcd5 100644
--- a/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java
+++ b/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java
@@ -352,6 +352,13 @@
}
@Override
+ public boolean isDumpCritical() {
+ // Dump can't be critical because the shell has to dump on the main thread for
+ // synchronization reasons, which isn't reliably fast.
+ return false;
+ }
+
+ @Override
public void dump(PrintWriter pw, String[] args) {
// Handle commands if provided
if (mShell.handleCommand(args, pw)) {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/notetask/NoteTaskControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/notetask/NoteTaskControllerTest.kt
index a76af8e..c65a2d3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/notetask/NoteTaskControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/notetask/NoteTaskControllerTest.kt
@@ -118,6 +118,7 @@
whenever(context.getString(eq(R.string.note_task_shortcut_long_label), any()))
.thenReturn(NOTE_TASK_LONG_LABEL)
whenever(context.packageManager).thenReturn(packageManager)
+ whenever(context.createContextAsUser(any(), any())).thenReturn(context)
whenever(packageManager.getApplicationInfo(any(), any<Int>())).thenReturn(mock())
whenever(packageManager.getApplicationLabel(any())).thenReturn(NOTE_TASK_LONG_LABEL)
whenever(resolver.resolveInfo(any(), any(), any())).thenReturn(NOTE_TASK_INFO)
@@ -353,7 +354,13 @@
@Test
fun showNoteTask_defaultUserSet_shouldStartActivityWithExpectedUserAndLogUiEvent() {
- whenever(secureSettings.getInt(eq(Settings.Secure.DEFAULT_NOTE_TASK_PROFILE), any()))
+ whenever(
+ secureSettings.getIntForUser(
+ /* name= */ eq(Settings.Secure.DEFAULT_NOTE_TASK_PROFILE),
+ /* def= */ any(),
+ /* userHandle= */ any()
+ )
+ )
.thenReturn(10)
val user10 = UserHandle.of(/* userId= */ 10)
@@ -615,13 +622,21 @@
}
@Test
- fun showNoteTask_copeDevices_tailButtonEntryPoint_shouldStartBubbleInWorkProfile() {
+ fun showNoteTask_copeDevices_tailButtonEntryPoint_shouldStartBubbleInTheUserSelectedUser() {
+ whenever(
+ secureSettings.getIntForUser(
+ /* name= */ eq(Settings.Secure.DEFAULT_NOTE_TASK_PROFILE),
+ /* def= */ any(),
+ /* userHandle= */ any()
+ )
+ )
+ .thenReturn(mainUserInfo.id)
whenever(devicePolicyManager.isOrganizationOwnedDeviceWithManagedProfile).thenReturn(true)
userTracker.set(mainAndWorkProfileUsers, mainAndWorkProfileUsers.indexOf(mainUserInfo))
createNoteTaskController().showNoteTask(entryPoint = TAIL_BUTTON)
- verifyNoteTaskOpenInBubbleInUser(workUserInfo.userHandle)
+ verifyNoteTaskOpenInBubbleInUser(mainUserInfo.userHandle)
}
@Test
@@ -813,7 +828,15 @@
}
@Test
- fun getUserForHandlingNotesTaking_cope_tailButton_shouldReturnWorkProfileUser() {
+ fun getUserForHandlingNotesTaking_cope_userSelectedWorkProfile_tailButton_shouldReturnWorkProfileUser() { // ktlint-disable max-line-length
+ whenever(
+ secureSettings.getIntForUser(
+ /* name= */ eq(Settings.Secure.DEFAULT_NOTE_TASK_PROFILE),
+ /* def= */ any(),
+ /* userHandle= */ any()
+ )
+ )
+ .thenReturn(workUserInfo.id)
whenever(devicePolicyManager.isOrganizationOwnedDeviceWithManagedProfile).thenReturn(true)
userTracker.set(mainAndWorkProfileUsers, mainAndWorkProfileUsers.indexOf(mainUserInfo))
@@ -823,6 +846,24 @@
}
@Test
+ fun getUserForHandlingNotesTaking_cope_userSelectedMainProfile_tailButton_shouldReturnMainProfileUser() { // ktlint-disable max-line-length
+ whenever(
+ secureSettings.getIntForUser(
+ /* name= */ eq(Settings.Secure.DEFAULT_NOTE_TASK_PROFILE),
+ /* def= */ any(),
+ /* userHandle= */ any()
+ )
+ )
+ .thenReturn(mainUserInfo.id)
+ whenever(devicePolicyManager.isOrganizationOwnedDeviceWithManagedProfile).thenReturn(true)
+ userTracker.set(mainAndWorkProfileUsers, mainAndWorkProfileUsers.indexOf(mainUserInfo))
+
+ val user = createNoteTaskController().getUserForHandlingNotesTaking(TAIL_BUTTON)
+
+ assertThat(user).isEqualTo(UserHandle.of(mainUserInfo.id))
+ }
+
+ @Test
fun getUserForHandlingNotesTaking_cope_appClip_shouldReturnCurrentUser() {
whenever(devicePolicyManager.isOrganizationOwnedDeviceWithManagedProfile).thenReturn(true)
userTracker.set(mainAndWorkProfileUsers, mainAndWorkProfileUsers.indexOf(mainUserInfo))
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerWithCoroutinesTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerWithCoroutinesTest.kt
index 0c046e9..c68095c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerWithCoroutinesTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerWithCoroutinesTest.kt
@@ -16,17 +16,23 @@
package com.android.systemui.shade
+import android.os.VibrationEffect
import android.testing.AndroidTestingRunner
import android.testing.TestableLooper
+import android.view.HapticFeedbackConstants
import android.view.View
import android.view.ViewStub
import androidx.test.filters.SmallTest
import com.android.internal.util.CollectionUtils
import com.android.keyguard.KeyguardClockSwitch.LARGE
import com.android.systemui.R
+import com.android.systemui.flags.Flags.ONE_WAY_HAPTICS_API_MIGRATION
import com.android.systemui.statusbar.StatusBarState.KEYGUARD
import com.android.systemui.statusbar.StatusBarState.SHADE
import com.android.systemui.statusbar.StatusBarState.SHADE_LOCKED
+import com.android.systemui.statusbar.VibratorHelper
+import com.android.systemui.util.mockito.any
+import com.android.systemui.util.mockito.eq
import com.android.systemui.util.mockito.whenever
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.Dispatchers
@@ -55,6 +61,9 @@
override fun getMainDispatcher() = Dispatchers.Main.immediate
+ private val ADDITIONAL_TAP_REQUIRED_VIBRATION_EFFECT =
+ VibrationEffect.get(VibrationEffect.EFFECT_STRENGTH_MEDIUM, false)
+
@Test
fun testDisableUserSwitcherAfterEnabling_returnsViewStubToTheViewHierarchy() = runTest {
launch(Dispatchers.Main.immediate) { givenViewAttached() }
@@ -148,6 +157,43 @@
}
@Test
+ fun doubleTapRequired_onKeyguard_oneWayHapticsDisabled_usesOldVibrate() = runTest {
+ launch(Dispatchers.Main.immediate) {
+ whenever(mFeatureFlags.isEnabled(ONE_WAY_HAPTICS_API_MIGRATION)).thenReturn(false)
+ val listener = getFalsingTapListener()
+ mStatusBarStateController.setState(KEYGUARD)
+
+ listener.onAdditionalTapRequired()
+ val packageName = mView.context.packageName
+ verify(mKeyguardIndicationController).showTransientIndication(anyInt())
+ verify(mVibratorHelper)
+ .vibrate(
+ any(),
+ eq(packageName),
+ eq(ADDITIONAL_TAP_REQUIRED_VIBRATION_EFFECT),
+ eq("falsing-additional-tap-required"),
+ eq(VibratorHelper.TOUCH_VIBRATION_ATTRIBUTES)
+ )
+ }
+ advanceUntilIdle()
+ }
+
+ @Test
+ fun doubleTapRequired_onKeyguard_oneWayHapticsEnabled_usesPerformHapticFeedback() = runTest {
+ launch(Dispatchers.Main.immediate) {
+ whenever(mFeatureFlags.isEnabled(ONE_WAY_HAPTICS_API_MIGRATION)).thenReturn(true)
+ val listener = getFalsingTapListener()
+ mStatusBarStateController.setState(KEYGUARD)
+
+ listener.onAdditionalTapRequired()
+ verify(mKeyguardIndicationController).showTransientIndication(anyInt())
+ verify(mVibratorHelper)
+ .performHapticFeedback(eq(mView), eq(HapticFeedbackConstants.REJECT))
+ }
+ advanceUntilIdle()
+ }
+
+ @Test
fun testDoubleTapRequired_ShadeLocked() = runTest {
launch(Dispatchers.Main.immediate) {
val listener = getFalsingTapListener()
@@ -161,6 +207,45 @@
}
@Test
+ fun doubleTapRequired_shadeLocked_oneWayHapticsDisabled_usesOldVibrate() = runTest {
+ launch(Dispatchers.Main.immediate) {
+ whenever(mFeatureFlags.isEnabled(ONE_WAY_HAPTICS_API_MIGRATION)).thenReturn(false)
+ val listener = getFalsingTapListener()
+ val packageName = mView.context.packageName
+ mStatusBarStateController.setState(SHADE_LOCKED)
+
+ listener.onAdditionalTapRequired()
+ verify(mVibratorHelper)
+ .vibrate(
+ any(),
+ eq(packageName),
+ eq(ADDITIONAL_TAP_REQUIRED_VIBRATION_EFFECT),
+ eq("falsing-additional-tap-required"),
+ eq(VibratorHelper.TOUCH_VIBRATION_ATTRIBUTES)
+ )
+
+ verify(mTapAgainViewController).show()
+ }
+ advanceUntilIdle()
+ }
+
+ @Test
+ fun doubleTapRequired_shadeLocked_oneWayHapticsEnabled_usesPerformHapticFeedback() = runTest {
+ launch(Dispatchers.Main.immediate) {
+ whenever(mFeatureFlags.isEnabled(ONE_WAY_HAPTICS_API_MIGRATION)).thenReturn(true)
+ val listener = getFalsingTapListener()
+ mStatusBarStateController.setState(SHADE_LOCKED)
+
+ listener.onAdditionalTapRequired()
+ verify(mVibratorHelper)
+ .performHapticFeedback(eq(mView), eq(HapticFeedbackConstants.REJECT))
+
+ verify(mTapAgainViewController).show()
+ }
+ advanceUntilIdle()
+ }
+
+ @Test
fun testOnAttachRefreshStatusBarState() = runTest {
launch(Dispatchers.Main.immediate) {
mStatusBarStateController.setState(KEYGUARD)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/render/GroupExpansionManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/render/GroupExpansionManagerTest.kt
new file mode 100644
index 0000000..4a94dc8
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/render/GroupExpansionManagerTest.kt
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.notification.collection.render
+
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.dump.DumpManager
+import com.android.systemui.flags.FakeFeatureFlags
+import com.android.systemui.flags.Flags
+import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder
+import com.android.systemui.util.mockito.mock
+import org.junit.Assert
+import org.junit.Before
+import org.junit.Test
+import org.mockito.Mockito.`when` as whenever
+
+@SmallTest
+class GroupExpansionManagerTest : SysuiTestCase() {
+ private lateinit var gem: GroupExpansionManagerImpl
+
+ private val dumpManager: DumpManager = mock()
+ private val groupMembershipManager: GroupMembershipManager = mock()
+ private val featureFlags = FakeFeatureFlags()
+
+ private val entry1 = NotificationEntryBuilder().build()
+ private val entry2 = NotificationEntryBuilder().build()
+
+ @Before
+ fun setUp() {
+ whenever(groupMembershipManager.getGroupSummary(entry1)).thenReturn(entry1)
+ whenever(groupMembershipManager.getGroupSummary(entry2)).thenReturn(entry2)
+
+ gem = GroupExpansionManagerImpl(dumpManager, groupMembershipManager, featureFlags)
+ }
+
+ @Test
+ fun testNotifyOnlyOnChange_enabled() {
+ featureFlags.set(Flags.NOTIFICATION_GROUP_EXPANSION_CHANGE, true)
+
+ var listenerCalledCount = 0
+ gem.registerGroupExpansionChangeListener { _, _ -> listenerCalledCount++ }
+
+ gem.setGroupExpanded(entry1, false)
+ Assert.assertEquals(0, listenerCalledCount)
+ gem.setGroupExpanded(entry1, true)
+ Assert.assertEquals(1, listenerCalledCount)
+ gem.setGroupExpanded(entry2, true)
+ Assert.assertEquals(2, listenerCalledCount)
+ gem.setGroupExpanded(entry1, true)
+ Assert.assertEquals(2, listenerCalledCount)
+ gem.setGroupExpanded(entry2, false)
+ Assert.assertEquals(3, listenerCalledCount)
+ }
+
+ @Test
+ fun testNotifyOnlyOnChange_disabled() {
+ featureFlags.set(Flags.NOTIFICATION_GROUP_EXPANSION_CHANGE, false)
+
+ var listenerCalledCount = 0
+ gem.registerGroupExpansionChangeListener { _, _ -> listenerCalledCount++ }
+
+ gem.setGroupExpanded(entry1, false)
+ Assert.assertEquals(1, listenerCalledCount)
+ gem.setGroupExpanded(entry1, true)
+ Assert.assertEquals(2, listenerCalledCount)
+ gem.setGroupExpanded(entry2, true)
+ Assert.assertEquals(3, listenerCalledCount)
+ gem.setGroupExpanded(entry1, true)
+ Assert.assertEquals(4, listenerCalledCount)
+ gem.setGroupExpanded(entry2, false)
+ Assert.assertEquals(5, listenerCalledCount)
+ }
+}
diff --git a/services/core/java/com/android/server/TEST_MAPPING b/services/core/java/com/android/server/TEST_MAPPING
index 7a95d77..41cca49 100644
--- a/services/core/java/com/android/server/TEST_MAPPING
+++ b/services/core/java/com/android/server/TEST_MAPPING
@@ -14,7 +14,7 @@
"file_patterns": ["NotificationManagerService\\.java"]
},
{
- "name": "CtsWindowManagerDeviceTestCases",
+ "name": "CtsWindowManagerDeviceWindow",
"options": [
{
"include-filter": "android.server.wm.window.ToastWindowTest"
diff --git a/services/core/java/com/android/server/am/ActivityManagerConstants.java b/services/core/java/com/android/server/am/ActivityManagerConstants.java
index 03e8691..bef53c7 100644
--- a/services/core/java/com/android/server/am/ActivityManagerConstants.java
+++ b/services/core/java/com/android/server/am/ActivityManagerConstants.java
@@ -287,10 +287,6 @@
*/
private static final String KEY_LOW_SWAP_THRESHOLD_PERCENT = "low_swap_threshold_percent";
- /** Default value for mFlagApplicationStartInfoEnabled. Defaults to false. */
- private static final String KEY_DEFAULT_APPLICATION_START_INFO_ENABLED =
- "enable_app_start_info";
-
/**
* Default value for mFlagBackgroundActivityStartsEnabled if not explicitly set in
* Settings.Global. This allows it to be set experimentally unless it has been
@@ -596,9 +592,6 @@
// Controlled by Settings.Global.ACTIVITY_STARTS_LOGGING_ENABLED
volatile boolean mFlagActivityStartsLoggingEnabled;
- // Indicates whether ApplicationStartInfo is enabled.
- volatile boolean mFlagApplicationStartInfoEnabled;
-
// Indicates whether the background activity starts is enabled.
// Controlled by Settings.Global.BACKGROUND_ACTIVITY_STARTS_ENABLED.
// If not set explicitly the default is controlled by DeviceConfig.
@@ -1070,9 +1063,6 @@
case KEY_MAX_CACHED_PROCESSES:
updateMaxCachedProcesses();
break;
- case KEY_DEFAULT_APPLICATION_START_INFO_ENABLED:
- updateApplicationStartInfoEnabled();
- break;
case KEY_DEFAULT_BACKGROUND_ACTIVITY_STARTS_ENABLED:
updateBackgroundActivityStarts();
break;
@@ -1493,14 +1483,6 @@
Settings.Global.ACTIVITY_STARTS_LOGGING_ENABLED, 1) == 1;
}
- private void updateApplicationStartInfoEnabled() {
- mFlagApplicationStartInfoEnabled =
- DeviceConfig.getBoolean(
- DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
- KEY_DEFAULT_APPLICATION_START_INFO_ENABLED,
- /*defaultValue*/ false);
- }
-
private void updateBackgroundActivityStarts() {
mFlagBackgroundActivityStartsEnabled = DeviceConfig.getBoolean(
DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
@@ -2125,10 +2107,6 @@
pw.println(mFgToBgFgsGraceDuration);
pw.print(" "); pw.print(KEY_FGS_START_FOREGROUND_TIMEOUT); pw.print("=");
pw.println(mFgsStartForegroundTimeoutMs);
- pw.print(" ");
- pw.print(KEY_DEFAULT_APPLICATION_START_INFO_ENABLED);
- pw.print("=");
- pw.println(mFlagApplicationStartInfoEnabled);
pw.print(" "); pw.print(KEY_DEFAULT_BACKGROUND_ACTIVITY_STARTS_ENABLED); pw.print("=");
pw.println(mFlagBackgroundActivityStartsEnabled);
pw.print(" "); pw.print(KEY_DEFAULT_BACKGROUND_FGS_STARTS_RESTRICTION_ENABLED);
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 132d6a9..a0fae26 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -9563,14 +9563,9 @@
return retList;
}
- /* @hide */
@Override
public ParceledListSlice<ApplicationStartInfo> getHistoricalProcessStartReasons(
String packageName, int maxNum, int userId) {
- if (!mConstants.mFlagApplicationStartInfoEnabled) {
- return new ParceledListSlice<ApplicationStartInfo>(
- new ArrayList<ApplicationStartInfo>());
- }
enforceNotIsolatedCaller("getHistoricalProcessStartReasons");
final ArrayList<ApplicationStartInfo> results = new ArrayList<ApplicationStartInfo>();
@@ -9579,24 +9574,28 @@
}
- /* @hide */
@Override
public void setApplicationStartInfoCompleteListener(
IApplicationStartInfoCompleteListener listener, int userId) {
- if (!mConstants.mFlagApplicationStartInfoEnabled) {
- return;
- }
enforceNotIsolatedCaller("setApplicationStartInfoCompleteListener");
}
- /* @hide */
@Override
- public void removeApplicationStartInfoCompleteListener(int userId) {
- if (!mConstants.mFlagApplicationStartInfoEnabled) {
- return;
+ public void clearApplicationStartInfoCompleteListener(int userId) {
+ enforceNotIsolatedCaller("clearApplicationStartInfoCompleteListener");
+
+ // For the simplification, we don't support USER_ALL nor USER_CURRENT here.
+ if (userId == UserHandle.USER_ALL || userId == UserHandle.USER_CURRENT) {
+ throw new IllegalArgumentException("Unsupported userId");
}
- enforceNotIsolatedCaller("removeApplicationStartInfoCompleteListener");
+
+ final int callingUid = Binder.getCallingUid();
+ }
+
+ @Override
+ public void addStartInfoTimestamp(int key, long timestampNs, int userId) {
+ enforceNotIsolatedCaller("addStartInfoTimestamp");
}
@Override
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index 5a050ac..75fcca5 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -5583,7 +5583,7 @@
private void recordReferenceLocked(String id) {
LongArray times = mOpenReferenceTimes.get(id);
if (times == null) {
- times = new LongArray();
+ times = new LongArray(2);
mOpenReferenceTimes.put(id, times);
}
times.add(System.currentTimeMillis());
@@ -5593,6 +5593,9 @@
LongArray times = mOpenReferenceTimes.get(id);
if (times != null && times.size() > 0) {
times.remove(times.size() - 1);
+ if (times.size() == 0) {
+ mOpenReferenceTimes.remove(id);
+ }
}
}
}
diff --git a/services/core/java/com/android/server/uri/TEST_MAPPING b/services/core/java/com/android/server/uri/TEST_MAPPING
index 6c36af5..b42d154 100644
--- a/services/core/java/com/android/server/uri/TEST_MAPPING
+++ b/services/core/java/com/android/server/uri/TEST_MAPPING
@@ -39,10 +39,10 @@
]
},
{
- "name": "CtsWindowManagerDeviceTestCases",
+ "name": "CtsWindowManagerDeviceWindow",
"options": [
{
- "include-filter": "android.server.wm.CrossAppDragAndDropTests"
+ "include-filter": "android.server.wm.window.CrossAppDragAndDropTests"
}
]
}
diff --git a/services/tests/wmtests/AndroidManifest.xml b/services/tests/wmtests/AndroidManifest.xml
index 554b0f4..85d0473c 100644
--- a/services/tests/wmtests/AndroidManifest.xml
+++ b/services/tests/wmtests/AndroidManifest.xml
@@ -90,7 +90,7 @@
<activity android:name="com.android.server.wm.SurfaceControlViewHostTests$TestActivity" />
- <activity android:name="android.server.wm.scvh.SurfaceSyncGroupActivity"
+ <activity android:name="com.android.server.wm.SurfaceSyncGroupTests$TestActivity"
android:screenOrientation="locked"
android:turnScreenOn="true"
android:theme="@style/WhiteBackgroundTheme"
diff --git a/services/tests/wmtests/src/com/android/server/wm/SurfaceSyncGroupTests.java b/services/tests/wmtests/src/com/android/server/wm/SurfaceSyncGroupTests.java
index 89d7252..abaa776 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SurfaceSyncGroupTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SurfaceSyncGroupTests.java
@@ -23,22 +23,27 @@
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
+import android.app.Activity;
import android.app.Instrumentation;
+import android.app.KeyguardManager;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.PixelFormat;
import android.graphics.Rect;
+import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.platform.test.annotations.Presubmit;
-import android.server.wm.scvh.SurfaceSyncGroupActivity;
import android.view.SurfaceControl;
import android.view.View;
+import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.view.WindowManager;
import android.view.cts.surfacevalidator.BitmapPixelChecker;
+import android.widget.FrameLayout;
import android.window.SurfaceSyncGroup;
+import androidx.annotation.Nullable;
import androidx.test.InstrumentationRegistry;
import androidx.test.rule.ActivityTestRule;
@@ -56,10 +61,10 @@
private static final long TIMEOUT_S = HW_TIMEOUT_MULTIPLIER * 5L;
@Rule
- public ActivityTestRule<SurfaceSyncGroupActivity> mActivityRule = new ActivityTestRule<>(
- SurfaceSyncGroupActivity.class);
+ public ActivityTestRule<TestActivity> mActivityRule = new ActivityTestRule<>(
+ TestActivity.class);
- private SurfaceSyncGroupActivity mActivity;
+ private TestActivity mActivity;
Instrumentation mInstrumentation;
@@ -187,4 +192,24 @@
swBitmap.recycle();
}
+
+ public static class TestActivity extends Activity {
+ private ViewGroup mParentView;
+
+ @Override
+ public void onCreate(@Nullable Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+
+ mParentView = new FrameLayout(this);
+ setContentView(mParentView);
+
+ KeyguardManager km = getSystemService(KeyguardManager.class);
+ km.requestDismissKeyguard(this, null);
+ }
+
+ public View getBackgroundView() {
+ return mParentView;
+ }
+ }
}
diff --git a/telecomm/java/android/telecom/Call.java b/telecomm/java/android/telecom/Call.java
index 1da4ea9..78b86d3 100644
--- a/telecomm/java/android/telecom/Call.java
+++ b/telecomm/java/android/telecom/Call.java
@@ -936,6 +936,12 @@
return mState;
}
+ /**
+ * @return the Telecom identifier associated with this {@link Call} . This is not a stable
+ * identifier and is not guaranteed to be unique across device reboots.
+ */
+ public @NonNull String getId() { return mTelecomCallId; }
+
/** {@hide} */
@TestApi
public String getTelecomCallId() {
diff --git a/telecomm/java/android/telecom/StreamingCall.java b/telecomm/java/android/telecom/StreamingCall.java
index 3319fc1..29f436d 100644
--- a/telecomm/java/android/telecom/StreamingCall.java
+++ b/telecomm/java/android/telecom/StreamingCall.java
@@ -56,7 +56,6 @@
/**
* The ID associated with this call. This is the same value as {@link CallControl#getCallId()}.
- * @hide
*/
public static final String EXTRA_CALL_ID = "android.telecom.extra.CALL_ID";