Merge "Fixes and additions to VDM unit tests" into main
diff --git a/core/api/current.txt b/core/api/current.txt
index 955858b..c9f0639 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -6749,7 +6749,6 @@
method public android.app.Notification.WearableExtender clone();
method public android.app.Notification.Builder extend(android.app.Notification.Builder);
method public java.util.List<android.app.Notification.Action> getActions();
- method @Deprecated public android.graphics.Bitmap getBackground();
method public String getBridgeTag();
method public int getContentAction();
method @Deprecated public int getContentIcon();
@@ -6768,7 +6767,6 @@
method @Deprecated public boolean getHintShowBackgroundOnly();
method @Deprecated public java.util.List<android.app.Notification> getPages();
method public boolean getStartScrollBottom();
- method @Deprecated public android.app.Notification.WearableExtender setBackground(android.graphics.Bitmap);
method public android.app.Notification.WearableExtender setBridgeTag(String);
method public android.app.Notification.WearableExtender setContentAction(int);
method @Deprecated public android.app.Notification.WearableExtender setContentIcon(int);
diff --git a/core/api/removed.txt b/core/api/removed.txt
index 8b3696a..57e2e73 100644
--- a/core/api/removed.txt
+++ b/core/api/removed.txt
@@ -23,6 +23,11 @@
method @Deprecated public android.app.Notification.Builder setTimeout(long);
}
+ public static final class Notification.WearableExtender implements android.app.Notification.Extender {
+ method @Deprecated public android.graphics.Bitmap getBackground();
+ method @Deprecated public android.app.Notification.WearableExtender setBackground(android.graphics.Bitmap);
+ }
+
}
package android.app.slice {
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 25c48e6..183783b 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -62,7 +62,7 @@
import android.app.servertransaction.ActivityRelaunchItem;
import android.app.servertransaction.ActivityResultItem;
import android.app.servertransaction.ClientTransaction;
-import android.app.servertransaction.ClientTransactionItem;
+import android.app.servertransaction.DestroyActivityItem;
import android.app.servertransaction.PauseActivityItem;
import android.app.servertransaction.PendingTransactionActions;
import android.app.servertransaction.PendingTransactionActions.StopInfo;
@@ -375,8 +375,8 @@
@GuardedBy("mPendingOverrideConfigs")
private final ArrayMap<IBinder, Configuration> mPendingOverrideConfigs = new ArrayMap<>();
/** The activities to be truly destroyed (not include relaunch). */
- final Map<IBinder, ClientTransactionItem> mActivitiesToBeDestroyed =
- Collections.synchronizedMap(new ArrayMap<IBinder, ClientTransactionItem>());
+ final Map<IBinder, DestroyActivityItem> mActivitiesToBeDestroyed =
+ Collections.synchronizedMap(new ArrayMap<>());
// List of new activities that should be reported when next we idle.
final ArrayList<ActivityClientRecord> mNewActivities = new ArrayList<>();
// Number of activities that are currently visible on-screen.
@@ -5799,7 +5799,7 @@
}
@Override
- public Map<IBinder, ClientTransactionItem> getActivitiesToBeDestroyed() {
+ public Map<IBinder, DestroyActivityItem> getActivitiesToBeDestroyed() {
return mActivitiesToBeDestroyed;
}
diff --git a/core/java/android/app/ClientTransactionHandler.java b/core/java/android/app/ClientTransactionHandler.java
index 98020ff..25075e9 100644
--- a/core/java/android/app/ClientTransactionHandler.java
+++ b/core/java/android/app/ClientTransactionHandler.java
@@ -19,7 +19,7 @@
import android.annotation.Nullable;
import android.app.ActivityThread.ActivityClientRecord;
import android.app.servertransaction.ClientTransaction;
-import android.app.servertransaction.ClientTransactionItem;
+import android.app.servertransaction.DestroyActivityItem;
import android.app.servertransaction.PendingTransactionActions;
import android.app.servertransaction.TransactionExecutor;
import android.content.Context;
@@ -108,7 +108,7 @@
// and deliver callbacks.
/** Get activity and its corresponding transaction item which are going to destroy. */
- public abstract Map<IBinder, ClientTransactionItem> getActivitiesToBeDestroyed();
+ public abstract Map<IBinder, DestroyActivityItem> getActivitiesToBeDestroyed();
/** Destroy the activity. */
public abstract void handleDestroyActivity(@NonNull ActivityClientRecord r, boolean finishing,
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 2c42df3..93c2b5a 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -44,6 +44,9 @@
import android.annotation.SystemApi;
import android.annotation.TestApi;
import android.app.admin.DevicePolicyManager;
+import android.app.compat.CompatChanges;
+import android.compat.annotation.ChangeId;
+import android.compat.annotation.EnabledSince;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.Context;
import android.content.Intent;
@@ -296,6 +299,15 @@
public static final String EXTRA_REMOTE_INPUT_DRAFT = "android.remoteInputDraft";
/**
+ * The call to WearableExtender#setBackground(Bitmap) will have no effect and the passed
+ * Bitmap will not be retained in memory.
+ */
+ @ChangeId
+ @EnabledSince(targetSdkVersion = Build.VERSION_CODES.VANILLA_ICE_CREAM)
+ @VisibleForTesting
+ static final long WEARABLE_EXTENDER_BACKGROUND_BLOCKED = 270551184L;
+
+ /**
* A timestamp related to this notification, in milliseconds since the epoch.
*
* Default value: {@link System#currentTimeMillis() Now}.
@@ -11148,9 +11160,20 @@
wearableBundle.putParcelableArray(KEY_PAGES, mPages.toArray(
new Notification[mPages.size()]));
}
+
if (mBackground != null) {
- wearableBundle.putParcelable(KEY_BACKGROUND, mBackground);
+ // Keeping WearableExtender backgrounds in memory despite them being deprecated has
+ // added noticeable increase in system server and system ui memory usage. After
+ // target VERSION_CODE#VANILLA_ICE_CREAM the background will not be populated
+ // anymore.
+ if (CompatChanges.isChangeEnabled(WEARABLE_EXTENDER_BACKGROUND_BLOCKED)) {
+ Log.d(TAG, "Use of background in WearableExtenders has been deprecated and "
+ + "will not be populated anymore.");
+ } else {
+ wearableBundle.putParcelable(KEY_BACKGROUND, mBackground);
+ }
}
+
if (mContentIcon != 0) {
wearableBundle.putInt(KEY_CONTENT_ICON, mContentIcon);
}
@@ -11369,12 +11392,21 @@
*
* @param background the background bitmap
* @return this object for method chaining
- * @see android.app.Notification.WearableExtender#getBackground
- * @deprecated Background images are no longer supported.
+ * @removed Not functional since {@link Build.VERSION_CODES#VANILLA_ICE_CREAM}.
+ * The wearable background is not used by wearables anymore and uses up
+ * unnecessary memory.
*/
@Deprecated
public WearableExtender setBackground(Bitmap background) {
- mBackground = background;
+ // Keeping WearableExtender backgrounds in memory despite them being deprecated has
+ // added noticeable increase in system server and system ui memory usage. After
+ // target VERSION_CODE#VANILLA_ICE_CREAM the background will not be populated anymore.
+ if (CompatChanges.isChangeEnabled(WEARABLE_EXTENDER_BACKGROUND_BLOCKED)) {
+ Log.d(TAG, "Use of background in WearableExtenders has been deprecated and "
+ + "will not be populated anymore.");
+ } else {
+ mBackground = background;
+ }
return this;
}
@@ -11384,11 +11416,13 @@
* will work with any notification style.
*
* @return the background image
- * @see android.app.Notification.WearableExtender#setBackground
- * @deprecated Background images are no longer supported.
+ * @removed Not functional since {@link Build.VERSION_CODES#VANILLA_ICE_CREAM}. The
+ * wearable background is not used by wearables anymore and uses up
+ * unnecessary memory.
*/
@Deprecated
public Bitmap getBackground() {
+ Log.w(TAG, "Use of background in WearableExtender has been removed, returning null.");
return mBackground;
}
diff --git a/core/java/android/app/servertransaction/ClientTransaction.java b/core/java/android/app/servertransaction/ClientTransaction.java
index a5b0f18..8617386 100644
--- a/core/java/android/app/servertransaction/ClientTransaction.java
+++ b/core/java/android/app/servertransaction/ClientTransaction.java
@@ -23,7 +23,6 @@
import android.app.ClientTransactionHandler;
import android.app.IApplicationThread;
import android.compat.annotation.UnsupportedAppUsage;
-import android.os.IBinder;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.RemoteException;
@@ -83,23 +82,6 @@
return mActivityCallbacks;
}
- /** Get the target activity. */
- @Nullable
- @UnsupportedAppUsage
- public IBinder getActivityToken() {
- // TODO(b/260873529): remove after we allow multiple activity items in one transaction.
- if (mLifecycleStateRequest != null) {
- return mLifecycleStateRequest.getActivityToken();
- }
- for (int i = mActivityCallbacks.size() - 1; i >= 0; i--) {
- final IBinder token = mActivityCallbacks.get(i).getActivityToken();
- if (token != null) {
- return token;
- }
- }
- return null;
- }
-
/** Get the target state lifecycle request. */
@VisibleForTesting(visibility = PACKAGE)
@UnsupportedAppUsage
diff --git a/core/java/android/app/servertransaction/DestroyActivityItem.java b/core/java/android/app/servertransaction/DestroyActivityItem.java
index ddb6df1..f9cf075 100644
--- a/core/java/android/app/servertransaction/DestroyActivityItem.java
+++ b/core/java/android/app/servertransaction/DestroyActivityItem.java
@@ -50,6 +50,13 @@
}
@Override
+ public void postExecute(@NonNull ClientTransactionHandler client,
+ @NonNull PendingTransactionActions pendingActions) {
+ // Cleanup after execution.
+ client.getActivitiesToBeDestroyed().remove(getActivityToken());
+ }
+
+ @Override
public int getTargetState() {
return ON_DESTROY;
}
diff --git a/core/java/android/app/servertransaction/TransactionExecutor.java b/core/java/android/app/servertransaction/TransactionExecutor.java
index 4433673..066f9fe 100644
--- a/core/java/android/app/servertransaction/TransactionExecutor.java
+++ b/core/java/android/app/servertransaction/TransactionExecutor.java
@@ -47,7 +47,6 @@
import com.android.internal.annotations.VisibleForTesting;
import java.util.List;
-import java.util.Map;
/**
* Class that manages transaction execution in the correct order.
@@ -75,34 +74,14 @@
* either remain in the initial state, or last state needed by a callback.
*/
public void execute(@NonNull ClientTransaction transaction) {
- if (DEBUG_RESOLVER) Slog.d(TAG, tId(transaction) + "Start resolving transaction");
-
- final IBinder token = transaction.getActivityToken();
- if (token != null) {
- final Map<IBinder, ClientTransactionItem> activitiesToBeDestroyed =
- mTransactionHandler.getActivitiesToBeDestroyed();
- final ClientTransactionItem destroyItem = activitiesToBeDestroyed.get(token);
- if (destroyItem != null) {
- if (transaction.getLifecycleStateRequest() == destroyItem) {
- // It is going to execute the transaction that will destroy activity with the
- // token, so the corresponding to-be-destroyed record can be removed.
- activitiesToBeDestroyed.remove(token);
- }
- if (mTransactionHandler.getActivityClient(token) == null) {
- // The activity has not been created but has been requested to destroy, so all
- // transactions for the token are just like being cancelled.
- Slog.w(TAG, tId(transaction) + "Skip pre-destroyed transaction:\n"
- + transactionToString(transaction, mTransactionHandler));
- return;
- }
- }
+ if (DEBUG_RESOLVER) {
+ Slog.d(TAG, tId(transaction) + "Start resolving transaction");
+ Slog.d(TAG, transactionToString(transaction, mTransactionHandler));
}
- if (DEBUG_RESOLVER) Slog.d(TAG, transactionToString(transaction, mTransactionHandler));
-
executeCallbacks(transaction);
-
executeLifecycleState(transaction);
+
mPendingActions.clear();
if (DEBUG_RESOLVER) Slog.d(TAG, tId(transaction) + "End resolving transaction");
}
@@ -135,6 +114,14 @@
final IBinder token = item.getActivityToken();
ActivityClientRecord r = mTransactionHandler.getActivityClient(token);
+ if (token != null && r == null
+ && mTransactionHandler.getActivitiesToBeDestroyed().containsKey(token)) {
+ // The activity has not been created but has been requested to destroy, so all
+ // transactions for the token are just like being cancelled.
+ Slog.w(TAG, "Skip pre-destroyed transaction item:\n" + item);
+ continue;
+ }
+
if (DEBUG_RESOLVER) Slog.d(TAG, tId(transaction) + "Resolving callback: " + item);
final int postExecutionState = item.getPostExecutionState();
@@ -211,6 +198,10 @@
}
if (r == null) {
+ if (mTransactionHandler.getActivitiesToBeDestroyed().get(token) == lifecycleItem) {
+ // Always cleanup for destroy item.
+ lifecycleItem.postExecute(mTransactionHandler, mPendingActions);
+ }
// Ignore requests for non-existent client records for now.
return;
}
diff --git a/core/java/android/hardware/radio/ProgramSelector.java b/core/java/android/hardware/radio/ProgramSelector.java
index 727716e..12442ba 100644
--- a/core/java/android/hardware/radio/ProgramSelector.java
+++ b/core/java/android/hardware/radio/ProgramSelector.java
@@ -147,8 +147,8 @@
*
* <p>Consists of (from the LSB):
* <li>
- * <ul>132bit: Station ID number.
- * <ul>14bit: HD_SUBCHANNEL.
+ * <ul>32bit: Station ID number.
+ * <ul>4bit: HD_SUBCHANNEL.
* <ul>18bit: AMFM_FREQUENCY.
* </li>
*
diff --git a/core/java/android/net/metrics/WakeupEvent.java b/core/java/android/net/metrics/WakeupEvent.java
index af9a73c..53a3ea5 100644
--- a/core/java/android/net/metrics/WakeupEvent.java
+++ b/core/java/android/net/metrics/WakeupEvent.java
@@ -29,7 +29,7 @@
public String iface;
public int uid;
public int ethertype;
- public MacAddress dstHwAddr;
+ public MacAddress dstHwAddr; // actually used to store a src mac address
public String srcIp;
public String dstIp;
public int ipNextHeader;
@@ -44,7 +44,7 @@
j.add(iface);
j.add("uid: " + Integer.toString(uid));
j.add("eth=0x" + Integer.toHexString(ethertype));
- j.add("dstHw=" + dstHwAddr);
+ j.add("srcMac=" + dstHwAddr); // really!! http://b/292404319#comment11
if (ipNextHeader > 0) {
j.add("ipNxtHdr=" + ipNextHeader);
j.add("srcIp=" + srcIp);
diff --git a/core/java/android/permission/flags.aconfig b/core/java/android/permission/flags.aconfig
index 77be5d4..1294f98 100644
--- a/core/java/android/permission/flags.aconfig
+++ b/core/java/android/permission/flags.aconfig
@@ -6,3 +6,10 @@
description: "enable device aware permission APIs"
bug: "274852670"
}
+
+flag {
+ name: "voice_activation_permission_apis"
+ namespace: "permissions"
+ description: "enable voice activation permission APIs"
+ bug: "287264308"
+}
\ No newline at end of file
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index e829ca2..f40232b 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -9908,6 +9908,48 @@
*/
public static final String DOCK_SETUP_STATE = "dock_setup_state";
+
+ /**
+ * Default, indicates that the user has not yet started the hub mode tutorial.
+ *
+ * @hide
+ */
+ public static final int HUB_MODE_TUTORIAL_NOT_STARTED = 0;
+
+ /**
+ * Indicates that the user has started but not yet completed the hub mode tutorial.
+ * One of the possible states for {@link #HUB_MODE_TUTORIAL_STATE}.
+ *
+ * @hide
+ */
+ public static final int HUB_MODE_TUTORIAL_STARTED = 1;
+
+ /**
+ * Indicates that the user has completed the hub mode tutorial.
+ * One of the possible states for {@link #HUB_MODE_TUTORIAL_STATE}.
+ *
+ * @hide
+ */
+ public static final int HUB_MODE_TUTORIAL_COMPLETED = 10;
+
+ /** @hide */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef({
+ HUB_MODE_TUTORIAL_NOT_STARTED,
+ HUB_MODE_TUTORIAL_STARTED,
+ HUB_MODE_TUTORIAL_COMPLETED
+ })
+ public @interface HubModeTutorialState {
+ }
+
+ /**
+ * Defines the user's current state of navigating through the hub mode tutorial.
+ * The possible states are defined in {@link HubModeTutorialState}.
+ *
+ * @hide
+ */
+ public static final String HUB_MODE_TUTORIAL_STATE = "hub_mode_tutorial_state";
+
/**
* The default NFC payment component
* @hide
@@ -11105,6 +11147,12 @@
public static final String BLUETOOTH_ON_WHILE_DRIVING = "bluetooth_on_while_driving";
/**
+ * Volume dialog timeout in ms.
+ * @hide
+ */
+ public static final String VOLUME_DIALOG_DISMISS_TIMEOUT = "volume_dialog_dismiss_timeout";
+
+ /**
* What behavior should be invoked when the volume hush gesture is triggered
* One of VOLUME_HUSH_OFF, VOLUME_HUSH_VIBRATE, VOLUME_HUSH_MUTE.
*
diff --git a/core/java/android/view/TextureView.java b/core/java/android/view/TextureView.java
index 969b6a512..e4e8b7b5b 100644
--- a/core/java/android/view/TextureView.java
+++ b/core/java/android/view/TextureView.java
@@ -54,9 +54,9 @@
* <th style="text-align: center;">SurfaceView</th>
* </tr>
* <tr>
- * <td>Supports alpha</td>
+ * <td>Supports View alpha</td>
* <td style="text-align: center;">X</td>
- * <td style="text-align: center;"> </td>
+ * <td style="text-align: center;">U+</td>
* </tr>
* <tr>
* <td>Supports rotations</td>
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 55374b9..5eaded2 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -8562,6 +8562,15 @@
* announcements every time a View is updated.
*
* <p>
+ * For notifying users about errors, such as in a login screen with text that displays an
+ * "incorrect password" notification, that view should send an AccessibilityEvent of type
+ * {@link AccessibilityEvent#CONTENT_CHANGE_TYPE_ERROR} and set
+ * {@link AccessibilityNodeInfo#setError(CharSequence)} instead. Custom widgets should expose
+ * error-setting methods that support accessibility automatically. For example, instead of
+ * explicitly sending this event when using a TextView, use
+ * {@link android.widget.TextView#setError(CharSequence)}.
+ *
+ * <p>
* Use {@link #setStateDescription(CharSequence)} to convey state changes to views within the
* user interface. While a live region may send different types of events generated by the view,
* state description will send {@link AccessibilityEvent#TYPE_WINDOW_CONTENT_CHANGED} events of
diff --git a/core/java/com/android/internal/display/BrightnessSynchronizer.java b/core/java/com/android/internal/display/BrightnessSynchronizer.java
index 7a87c3a..d503904 100644
--- a/core/java/com/android/internal/display/BrightnessSynchronizer.java
+++ b/core/java/com/android/internal/display/BrightnessSynchronizer.java
@@ -16,11 +16,9 @@
package com.android.internal.display;
-import android.annotation.SuppressLint;
import android.content.ContentResolver;
import android.content.Context;
import android.database.ContentObserver;
-import android.hardware.display.BrightnessInfo;
import android.hardware.display.DisplayManager;
import android.hardware.display.DisplayManager.DisplayListener;
import android.net.Uri;
@@ -56,7 +54,8 @@
private static final int MSG_RUN_UPDATE = 1;
// The tolerance within which we consider brightness values approximately equal to eachother.
- public static final float EPSILON = 0.0001f;
+ // This value is approximately 1/3 of the smallest possible brightness value.
+ public static final float EPSILON = 0.001f;
private static int sBrightnessUpdateCount = 1;
@@ -285,74 +284,6 @@
}
/**
- * Converts between the int brightness setting and the float brightness system. The int
- * brightness setting is between 0-255 and matches the brightness slider - e.g. 128 is 50% on
- * the slider. Accounts for special values such as OFF and invalid values. Accounts for
- * brightness limits; the maximum value here represents the max value allowed on the slider.
- */
- @VisibleForTesting
- @SuppressLint("AndroidFrameworkRequiresPermission")
- public float brightnessIntSettingToFloat(int brightnessInt) {
- if (brightnessInt == PowerManager.BRIGHTNESS_OFF) {
- return PowerManager.BRIGHTNESS_OFF_FLOAT;
- } else if (brightnessInt == PowerManager.BRIGHTNESS_INVALID) {
- return PowerManager.BRIGHTNESS_INVALID_FLOAT;
- } else {
- final float minInt = PowerManager.BRIGHTNESS_OFF + 1;
- final float maxInt = PowerManager.BRIGHTNESS_ON;
-
- // Normalize to the range [0, 1]
- float userPerceptionBrightness = MathUtils.norm(minInt, maxInt, brightnessInt);
-
- // Convert from user-perception to linear scale
- float linearBrightness = BrightnessUtils.convertGammaToLinear(userPerceptionBrightness);
-
- // Interpolate to the range [0, currentlyAllowedMax]
- final Display display = mContext.getDisplay();
- if (display == null) {
- return PowerManager.BRIGHTNESS_INVALID_FLOAT;
- }
- final BrightnessInfo info = display.getBrightnessInfo();
- return MathUtils.lerp(info.brightnessMinimum, info.brightnessMaximum, linearBrightness);
- }
- }
-
- /**
- * Translates specified value from the float brightness system to the setting int brightness
- * system. The value returned is between 0-255 and matches the brightness slider - e.g. 128 is
- * 50% on the slider. Accounts for special values such as OFF and invalid values. Accounts for
- * brightness limits; the maximum value here represents the max value currently allowed on
- * the slider.
- */
- @VisibleForTesting
- @SuppressLint("AndroidFrameworkRequiresPermission")
- public int brightnessFloatToIntSetting(float brightnessFloat) {
- if (floatEquals(brightnessFloat, PowerManager.BRIGHTNESS_OFF_FLOAT)) {
- return PowerManager.BRIGHTNESS_OFF;
- } else if (Float.isNaN(brightnessFloat)) {
- return PowerManager.BRIGHTNESS_INVALID;
- } else {
- // Normalize to the range [0, 1]
- final Display display = mContext.getDisplay();
- if (display == null) {
- return PowerManager.BRIGHTNESS_INVALID;
- }
- final BrightnessInfo info = display.getBrightnessInfo();
- float linearBrightness =
- MathUtils.norm(info.brightnessMinimum, info.brightnessMaximum, brightnessFloat);
-
- // Convert from linear to user-perception scale
- float userPerceptionBrightness = BrightnessUtils.convertLinearToGamma(linearBrightness);
-
- // Interpolate to the range [0, 255]
- final float minInt = PowerManager.BRIGHTNESS_OFF + 1;
- final float maxInt = PowerManager.BRIGHTNESS_ON;
- float intBrightness = MathUtils.lerp(minInt, maxInt, userPerceptionBrightness);
- return Math.round(intBrightness);
- }
- }
-
- /**
* Encapsulates a brightness change event and contains logic for synchronizing the appropriate
* settings for the specified brightness change.
*/
@@ -490,14 +421,14 @@
if (mSourceType == TYPE_INT) {
return (int) mBrightness;
}
- return brightnessFloatToIntSetting(mBrightness);
+ return brightnessFloatToInt(mBrightness);
}
private float getBrightnessAsFloat() {
if (mSourceType == TYPE_FLOAT) {
return mBrightness;
}
- return brightnessIntSettingToFloat((int) mBrightness);
+ return brightnessIntToFloat((int) mBrightness);
}
private String toStringLabel(int type, float brightness) {
diff --git a/core/java/com/android/internal/net/OWNERS b/core/java/com/android/internal/net/OWNERS
index 71f997b..7157683 100644
--- a/core/java/com/android/internal/net/OWNERS
+++ b/core/java/com/android/internal/net/OWNERS
@@ -1,4 +1,4 @@
set noparent
-file:platform/packages/modules/Connectivity:master:/OWNERS_core_networking
+file:platform/packages/modules/Connectivity:main:/OWNERS_core_networking
jsharkey@android.com
diff --git a/core/java/com/android/server/net/OWNERS b/core/java/com/android/server/net/OWNERS
index 62c5737..c24680e9 100644
--- a/core/java/com/android/server/net/OWNERS
+++ b/core/java/com/android/server/net/OWNERS
@@ -1,2 +1,2 @@
set noparent
-file:platform/packages/modules/Connectivity:master:/OWNERS_core_networking
+file:platform/packages/modules/Connectivity:main:/OWNERS_core_networking
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index c00a776f..4e073ca 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -4830,7 +4830,7 @@
<string translatable="false" name="config_deviceSpecificInputMethodManagerService"></string>
<!-- Component name of media projection permission dialog -->
- <string name="config_mediaProjectionPermissionDialogComponent" translatable="false">com.android.systemui/com.android.systemui.media.MediaProjectionPermissionActivity</string>
+ <string name="config_mediaProjectionPermissionDialogComponent" translatable="false">com.android.systemui/com.android.systemui.mediaprojection.permission.MediaProjectionPermissionActivity</string>
<!-- Corner radius of system dialogs -->
<dimen name="config_dialogCornerRadius">28dp</dimen>
diff --git a/core/tests/coretests/src/android/app/NotificationTest.java b/core/tests/coretests/src/android/app/NotificationTest.java
index 48dc167..7f3e014 100644
--- a/core/tests/coretests/src/android/app/NotificationTest.java
+++ b/core/tests/coretests/src/android/app/NotificationTest.java
@@ -69,6 +69,7 @@
import static org.mockito.Mockito.when;
import android.annotation.Nullable;
+import android.compat.testing.PlatformCompatChangeRule;
import android.content.Context;
import android.content.Intent;
import android.content.LocusId;
@@ -95,16 +96,20 @@
import android.widget.RemoteViews;
import androidx.test.InstrumentationRegistry;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
import com.android.internal.R;
import com.android.internal.util.ContrastColorUtil;
import junit.framework.Assert;
+import libcore.junit.util.compat.CoreCompatChangeRule;
+
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
+import org.junit.rules.TestRule;
import org.junit.runner.RunWith;
import java.util.List;
@@ -116,6 +121,9 @@
private Context mContext;
+ @Rule
+ public TestRule compatChangeRule = new PlatformCompatChangeRule();
+
@Before
public void setUp() {
mContext = InstrumentationRegistry.getContext();
@@ -1777,6 +1785,42 @@
assertThat(recoveredExtender.getColor()).isEqualTo(1234);
}
+ @Test
+ @CoreCompatChangeRule.EnableCompatChanges({Notification.WEARABLE_EXTENDER_BACKGROUND_BLOCKED})
+ public void wearableBackgroundBlockEnabled_wearableBackgroundSet_valueRemainsNull() {
+ Notification.WearableExtender extender = new Notification.WearableExtender();
+ Bitmap bitmap = Bitmap.createBitmap(200, 200, Bitmap.Config.ARGB_8888);
+ extender.setBackground(bitmap);
+ Notification notif =
+ new Notification.Builder(mContext, "test id")
+ .setSmallIcon(1)
+ .setContentTitle("test_title")
+ .extend(extender)
+ .build();
+
+ Notification.WearableExtender result = new Notification.WearableExtender(notif);
+ Assert.assertNull(result.getBackground());
+ }
+
+ @Test
+ @CoreCompatChangeRule.DisableCompatChanges({Notification.WEARABLE_EXTENDER_BACKGROUND_BLOCKED})
+ public void wearableBackgroundBlockDisabled_wearableBackgroundSet_valueKeepsBitmap() {
+ Notification.WearableExtender extender = new Notification.WearableExtender();
+ Bitmap bitmap = Bitmap.createBitmap(200, 200, Bitmap.Config.ARGB_8888);
+ extender.setBackground(bitmap);
+ Notification notif =
+ new Notification.Builder(mContext, "test id")
+ .setSmallIcon(1)
+ .setContentTitle("test_title")
+ .extend(extender)
+ .build();
+
+ Notification.WearableExtender result = new Notification.WearableExtender(notif);
+ Bitmap resultBitmap = result.getBackground();
+ assertNotNull(resultBitmap);
+ Assert.assertEquals(bitmap, resultBitmap);
+ }
+
private void assertValid(Notification.Colors c) {
// Assert that all colors are populated
assertThat(c.getBackgroundColor()).isNotEqualTo(Notification.COLOR_INVALID);
diff --git a/core/tests/coretests/src/android/app/servertransaction/DestroyActivityItemTest.java b/core/tests/coretests/src/android/app/servertransaction/DestroyActivityItemTest.java
new file mode 100644
index 0000000..ecd75a8
--- /dev/null
+++ b/core/tests/coretests/src/android/app/servertransaction/DestroyActivityItemTest.java
@@ -0,0 +1,99 @@
+/*
+ * 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 android.app.servertransaction;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.verify;
+
+import android.app.ActivityThread.ActivityClientRecord;
+import android.app.ClientTransactionHandler;
+import android.os.IBinder;
+import android.platform.test.annotations.Presubmit;
+import android.util.ArrayMap;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+/**
+ * Tests for {@link DestroyActivityItem}.
+ *
+ * Build/Install/Run:
+ * atest FrameworksCoreTests:DestroyActivityItemTest
+ */
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+@Presubmit
+public class DestroyActivityItemTest {
+
+ @Mock
+ private ClientTransactionHandler mHandler;
+ @Mock
+ private PendingTransactionActions mPendingActions;
+ @Mock
+ private IBinder mActivityToken;
+
+ // Can't mock final class.
+ private ActivityClientRecord mActivityClientRecord;
+
+ private ArrayMap<IBinder, DestroyActivityItem> mActivitiesToBeDestroyed;
+ private DestroyActivityItem mItem;
+
+ @Before
+ public void setup() {
+ MockitoAnnotations.initMocks(this);
+ mItem = DestroyActivityItem.obtain(
+ mActivityToken, false /* finished */, 123 /* configChanges */);
+ mActivityClientRecord = new ActivityClientRecord();
+ mActivitiesToBeDestroyed = new ArrayMap<>();
+
+ doReturn(mActivitiesToBeDestroyed).when(mHandler).getActivitiesToBeDestroyed();
+ }
+
+ @Test
+ public void testPreExecute() {
+ mItem.preExecute(mHandler);
+
+ assertEquals(1, mActivitiesToBeDestroyed.size());
+ assertEquals(mItem, mActivitiesToBeDestroyed.get(mActivityToken));
+ }
+
+ @Test
+ public void testPostExecute() {
+ mItem.preExecute(mHandler);
+ mItem.postExecute(mHandler, mPendingActions);
+
+ assertTrue(mActivitiesToBeDestroyed.isEmpty());
+ }
+
+ @Test
+ public void testExecute() {
+ mItem.execute(mHandler, mActivityClientRecord, mPendingActions);
+
+ verify(mHandler).handleDestroyActivity(eq(mActivityClientRecord), eq(false) /* finishing */,
+ eq(123) /* configChanges */, eq(false) /* getNonConfigInstance */, any());
+ }
+}
diff --git a/core/tests/coretests/src/android/app/servertransaction/TransactionExecutorTests.java b/core/tests/coretests/src/android/app/servertransaction/TransactionExecutorTests.java
index a1a2bdb..44a4d58 100644
--- a/core/tests/coretests/src/android/app/servertransaction/TransactionExecutorTests.java
+++ b/core/tests/coretests/src/android/app/servertransaction/TransactionExecutorTests.java
@@ -28,6 +28,7 @@
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.inOrder;
@@ -247,7 +248,7 @@
@Test
public void testDoNotLaunchDestroyedActivity() {
- final Map<IBinder, ClientTransactionItem> activitiesToBeDestroyed = new ArrayMap<>();
+ final Map<IBinder, DestroyActivityItem> activitiesToBeDestroyed = new ArrayMap<>();
when(mTransactionHandler.getActivitiesToBeDestroyed()).thenReturn(activitiesToBeDestroyed);
// Assume launch transaction is still in queue, so there is no client record.
when(mTransactionHandler.getActivityClient(any())).thenReturn(null);
@@ -259,7 +260,7 @@
DestroyActivityItem.obtain(token, false /* finished */, 0 /* configChanges */));
destroyTransaction.preExecute(mTransactionHandler);
// The activity should be added to to-be-destroyed container.
- assertEquals(1, mTransactionHandler.getActivitiesToBeDestroyed().size());
+ assertEquals(1, activitiesToBeDestroyed.size());
// A previous queued launch transaction runs on main thread (execute).
final ClientTransaction launchTransaction = ClientTransaction.obtain(null /* client */);
@@ -274,7 +275,7 @@
// After the destroy transaction has been executed, the token should be removed.
mExecutor.execute(destroyTransaction);
- assertEquals(0, mTransactionHandler.getActivitiesToBeDestroyed().size());
+ assertTrue(activitiesToBeDestroyed.isEmpty());
}
@Test
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/CopyContentInSplitGesturalNavLandscape.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/CopyContentInSplitGesturalNavLandscape.kt
index b444bad..b0e847f 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/CopyContentInSplitGesturalNavLandscape.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/CopyContentInSplitGesturalNavLandscape.kt
@@ -26,7 +26,7 @@
open class CopyContentInSplitGesturalNavLandscape : CopyContentInSplit(Rotation.ROTATION_90) {
@get:Rule
- val flickerServiceRule = FlickerServiceRule(enabled = true, failTestOnFaasFailure = false)
+ val flickerServiceRule = FlickerServiceRule(enabled = true, failTestOnFlicker = false)
@PlatinumTest(focusArea = "sysui")
@Presubmit
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/CopyContentInSplitGesturalNavPortrait.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/CopyContentInSplitGesturalNavPortrait.kt
index e2ab989..f847e40 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/CopyContentInSplitGesturalNavPortrait.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/CopyContentInSplitGesturalNavPortrait.kt
@@ -26,7 +26,7 @@
open class CopyContentInSplitGesturalNavPortrait : CopyContentInSplit(Rotation.ROTATION_0) {
@get:Rule
- val flickerServiceRule = FlickerServiceRule(enabled = true, failTestOnFaasFailure = false)
+ val flickerServiceRule = FlickerServiceRule(enabled = true, failTestOnFlicker = false)
@PlatinumTest(focusArea = "sysui")
@Presubmit
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/DismissSplitScreenByDividerGesturalNavLandscape.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/DismissSplitScreenByDividerGesturalNavLandscape.kt
index 22b8102..31e52e2 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/DismissSplitScreenByDividerGesturalNavLandscape.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/DismissSplitScreenByDividerGesturalNavLandscape.kt
@@ -27,7 +27,7 @@
open class DismissSplitScreenByDividerGesturalNavLandscape :
DismissSplitScreenByDivider(Rotation.ROTATION_90) {
@get:Rule
- val flickerServiceRule = FlickerServiceRule(enabled = true, failTestOnFaasFailure = false)
+ val flickerServiceRule = FlickerServiceRule(enabled = true, failTestOnFlicker = false)
@PlatinumTest(focusArea = "sysui")
@Presubmit
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/DismissSplitScreenByDividerGesturalNavPortrait.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/DismissSplitScreenByDividerGesturalNavPortrait.kt
index 3fb014f..0870073 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/DismissSplitScreenByDividerGesturalNavPortrait.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/DismissSplitScreenByDividerGesturalNavPortrait.kt
@@ -27,7 +27,7 @@
open class DismissSplitScreenByDividerGesturalNavPortrait :
DismissSplitScreenByDivider(Rotation.ROTATION_0) {
@get:Rule
- val flickerServiceRule = FlickerServiceRule(enabled = true, failTestOnFaasFailure = false)
+ val flickerServiceRule = FlickerServiceRule(enabled = true, failTestOnFlicker = false)
@PlatinumTest(focusArea = "sysui")
@Presubmit
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/DismissSplitScreenByGoHomeGesturalNavLandscape.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/DismissSplitScreenByGoHomeGesturalNavLandscape.kt
index ea1f942..1bb6c45 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/DismissSplitScreenByGoHomeGesturalNavLandscape.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/DismissSplitScreenByGoHomeGesturalNavLandscape.kt
@@ -27,7 +27,7 @@
open class DismissSplitScreenByGoHomeGesturalNavLandscape :
DismissSplitScreenByGoHome(Rotation.ROTATION_90) {
@get:Rule
- val flickerServiceRule = FlickerServiceRule(enabled = true, failTestOnFaasFailure = false)
+ val flickerServiceRule = FlickerServiceRule(enabled = true, failTestOnFlicker = false)
@PlatinumTest(focusArea = "sysui")
@Presubmit
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/DismissSplitScreenByGoHomeGesturalNavPortrait.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/DismissSplitScreenByGoHomeGesturalNavPortrait.kt
index 8f23a79..bb084d6 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/DismissSplitScreenByGoHomeGesturalNavPortrait.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/DismissSplitScreenByGoHomeGesturalNavPortrait.kt
@@ -27,7 +27,7 @@
open class DismissSplitScreenByGoHomeGesturalNavPortrait :
DismissSplitScreenByGoHome(Rotation.ROTATION_0) {
@get:Rule
- val flickerServiceRule = FlickerServiceRule(enabled = true, failTestOnFaasFailure = false)
+ val flickerServiceRule = FlickerServiceRule(enabled = true, failTestOnFlicker = false)
@PlatinumTest(focusArea = "sysui")
@Presubmit
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/DragDividerToResizeGesturalNavLandscape.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/DragDividerToResizeGesturalNavLandscape.kt
index b0f39e5..bc5857f 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/DragDividerToResizeGesturalNavLandscape.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/DragDividerToResizeGesturalNavLandscape.kt
@@ -26,7 +26,7 @@
open class DragDividerToResizeGesturalNavLandscape : DragDividerToResize(Rotation.ROTATION_90) {
@get:Rule
- val flickerServiceRule = FlickerServiceRule(enabled = true, failTestOnFaasFailure = false)
+ val flickerServiceRule = FlickerServiceRule(enabled = true, failTestOnFlicker = false)
@PlatinumTest(focusArea = "sysui")
@Presubmit
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/DragDividerToResizeGesturalNavPortrait.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/DragDividerToResizeGesturalNavPortrait.kt
index 6ce8746..e4faa4a 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/DragDividerToResizeGesturalNavPortrait.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/DragDividerToResizeGesturalNavPortrait.kt
@@ -26,7 +26,7 @@
open class DragDividerToResizeGesturalNavPortrait : DragDividerToResize(Rotation.ROTATION_0) {
@get:Rule
- val flickerServiceRule = FlickerServiceRule(enabled = true, failTestOnFaasFailure = false)
+ val flickerServiceRule = FlickerServiceRule(enabled = true, failTestOnFlicker = false)
@PlatinumTest(focusArea = "sysui")
@Presubmit
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromAllAppsGesturalNavLandscape.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromAllAppsGesturalNavLandscape.kt
index 9f74edf..7431974 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromAllAppsGesturalNavLandscape.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromAllAppsGesturalNavLandscape.kt
@@ -27,7 +27,7 @@
open class EnterSplitScreenByDragFromAllAppsGesturalNavLandscape :
EnterSplitScreenByDragFromAllApps(Rotation.ROTATION_90) {
@get:Rule
- val flickerServiceRule = FlickerServiceRule(enabled = true, failTestOnFaasFailure = false)
+ val flickerServiceRule = FlickerServiceRule(enabled = true, failTestOnFlicker = false)
@PlatinumTest(focusArea = "sysui")
@Presubmit
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromAllAppsGesturalNavPortrait.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromAllAppsGesturalNavPortrait.kt
index 1e4055e..c2b0609 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromAllAppsGesturalNavPortrait.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromAllAppsGesturalNavPortrait.kt
@@ -27,7 +27,7 @@
open class EnterSplitScreenByDragFromAllAppsGesturalNavPortrait :
EnterSplitScreenByDragFromAllApps(Rotation.ROTATION_0) {
@get:Rule
- val flickerServiceRule = FlickerServiceRule(enabled = true, failTestOnFaasFailure = false)
+ val flickerServiceRule = FlickerServiceRule(enabled = true, failTestOnFlicker = false)
@PlatinumTest(focusArea = "sysui")
@Presubmit
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromNotificationGesturalNavLandscape.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromNotificationGesturalNavLandscape.kt
index c3b8132..7d1072d 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromNotificationGesturalNavLandscape.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromNotificationGesturalNavLandscape.kt
@@ -27,7 +27,7 @@
open class EnterSplitScreenByDragFromNotificationGesturalNavLandscape :
EnterSplitScreenByDragFromNotification(Rotation.ROTATION_90) {
@get:Rule
- val flickerServiceRule = FlickerServiceRule(enabled = true, failTestOnFaasFailure = false)
+ val flickerServiceRule = FlickerServiceRule(enabled = true, failTestOnFlicker = false)
@PlatinumTest(focusArea = "sysui")
@Presubmit
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromNotificationGesturalNavPortrait.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromNotificationGesturalNavPortrait.kt
index 7756d04..79760d1 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromNotificationGesturalNavPortrait.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromNotificationGesturalNavPortrait.kt
@@ -27,7 +27,7 @@
open class EnterSplitScreenByDragFromNotificationGesturalNavPortrait :
EnterSplitScreenByDragFromNotification(Rotation.ROTATION_0) {
@get:Rule
- val flickerServiceRule = FlickerServiceRule(enabled = true, failTestOnFaasFailure = false)
+ val flickerServiceRule = FlickerServiceRule(enabled = true, failTestOnFlicker = false)
@PlatinumTest(focusArea = "sysui")
@Presubmit
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromShortcutGesturalNavLandscape.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromShortcutGesturalNavLandscape.kt
index c72aa5a..ff3729a 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromShortcutGesturalNavLandscape.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromShortcutGesturalNavLandscape.kt
@@ -27,7 +27,7 @@
open class EnterSplitScreenByDragFromShortcutGesturalNavLandscape :
EnterSplitScreenByDragFromShortcut(Rotation.ROTATION_90) {
@get:Rule
- val flickerServiceRule = FlickerServiceRule(enabled = true, failTestOnFaasFailure = false)
+ val flickerServiceRule = FlickerServiceRule(enabled = true, failTestOnFlicker = false)
@PlatinumTest(focusArea = "sysui")
@Presubmit
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromShortcutGesturalNavPortrait.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromShortcutGesturalNavPortrait.kt
index cc88f27..ffbcfe4 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromShortcutGesturalNavPortrait.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromShortcutGesturalNavPortrait.kt
@@ -27,7 +27,7 @@
open class EnterSplitScreenByDragFromShortcutGesturalNavPortrait :
EnterSplitScreenByDragFromShortcut(Rotation.ROTATION_0) {
@get:Rule
- val flickerServiceRule = FlickerServiceRule(enabled = true, failTestOnFaasFailure = false)
+ val flickerServiceRule = FlickerServiceRule(enabled = true, failTestOnFlicker = false)
@PlatinumTest(focusArea = "sysui")
@Presubmit
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromTaskbarGesturalNavLandscape.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromTaskbarGesturalNavLandscape.kt
index 87b38b1..5e937c0 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromTaskbarGesturalNavLandscape.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromTaskbarGesturalNavLandscape.kt
@@ -27,7 +27,7 @@
open class EnterSplitScreenByDragFromTaskbarGesturalNavLandscape :
EnterSplitScreenByDragFromTaskbar(Rotation.ROTATION_90) {
@get:Rule
- val flickerServiceRule = FlickerServiceRule(enabled = true, failTestOnFaasFailure = false)
+ val flickerServiceRule = FlickerServiceRule(enabled = true, failTestOnFlicker = false)
@PlatinumTest(focusArea = "sysui")
@Presubmit
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromTaskbarGesturalNavPortrait.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromTaskbarGesturalNavPortrait.kt
index ca347ed..89db8a0 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromTaskbarGesturalNavPortrait.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromTaskbarGesturalNavPortrait.kt
@@ -27,7 +27,7 @@
open class EnterSplitScreenByDragFromTaskbarGesturalNavPortrait :
EnterSplitScreenByDragFromTaskbar(Rotation.ROTATION_0) {
@get:Rule
- val flickerServiceRule = FlickerServiceRule(enabled = true, failTestOnFaasFailure = false)
+ val flickerServiceRule = FlickerServiceRule(enabled = true, failTestOnFlicker = false)
@PlatinumTest(focusArea = "sysui")
@Presubmit
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenFromOverviewGesturalNavLandscape.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenFromOverviewGesturalNavLandscape.kt
index 6597819..bf4ee7a 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenFromOverviewGesturalNavLandscape.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenFromOverviewGesturalNavLandscape.kt
@@ -27,7 +27,7 @@
open class EnterSplitScreenFromOverviewGesturalNavLandscape :
EnterSplitScreenFromOverview(Rotation.ROTATION_90) {
@get:Rule
- val flickerServiceRule = FlickerServiceRule(enabled = true, failTestOnFaasFailure = false)
+ val flickerServiceRule = FlickerServiceRule(enabled = true, failTestOnFlicker = false)
@PlatinumTest(focusArea = "sysui")
@Presubmit
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenFromOverviewGesturalNavPortrait.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenFromOverviewGesturalNavPortrait.kt
index 6df31fc..7e96f06 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenFromOverviewGesturalNavPortrait.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenFromOverviewGesturalNavPortrait.kt
@@ -27,7 +27,7 @@
open class EnterSplitScreenFromOverviewGesturalNavPortrait :
EnterSplitScreenFromOverview(Rotation.ROTATION_0) {
@get:Rule
- val flickerServiceRule = FlickerServiceRule(enabled = true, failTestOnFaasFailure = false)
+ val flickerServiceRule = FlickerServiceRule(enabled = true, failTestOnFlicker = false)
@PlatinumTest(focusArea = "sysui")
@Presubmit
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchAppByDoubleTapDividerGesturalNavLandscape.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchAppByDoubleTapDividerGesturalNavLandscape.kt
index 02596c5..a84deac 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchAppByDoubleTapDividerGesturalNavLandscape.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchAppByDoubleTapDividerGesturalNavLandscape.kt
@@ -27,7 +27,7 @@
open class SwitchAppByDoubleTapDividerGesturalNavLandscape :
SwitchAppByDoubleTapDivider(Rotation.ROTATION_90) {
@get:Rule
- val flickerServiceRule = FlickerServiceRule(enabled = true, failTestOnFaasFailure = false)
+ val flickerServiceRule = FlickerServiceRule(enabled = true, failTestOnFlicker = false)
@PlatinumTest(focusArea = "sysui")
@Presubmit
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchAppByDoubleTapDividerGesturalNavPortrait.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchAppByDoubleTapDividerGesturalNavPortrait.kt
index 9d579f6..afcc743 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchAppByDoubleTapDividerGesturalNavPortrait.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchAppByDoubleTapDividerGesturalNavPortrait.kt
@@ -27,7 +27,7 @@
open class SwitchAppByDoubleTapDividerGesturalNavPortrait :
SwitchAppByDoubleTapDivider(Rotation.ROTATION_0) {
@get:Rule
- val flickerServiceRule = FlickerServiceRule(enabled = true, failTestOnFaasFailure = false)
+ val flickerServiceRule = FlickerServiceRule(enabled = true, failTestOnFlicker = false)
@PlatinumTest(focusArea = "sysui")
@Presubmit
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBackToSplitFromAnotherAppGesturalNavLandscape.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBackToSplitFromAnotherAppGesturalNavLandscape.kt
index da85342..2f96f5f 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBackToSplitFromAnotherAppGesturalNavLandscape.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBackToSplitFromAnotherAppGesturalNavLandscape.kt
@@ -27,7 +27,7 @@
open class SwitchBackToSplitFromAnotherAppGesturalNavLandscape :
SwitchBackToSplitFromAnotherApp(Rotation.ROTATION_90) {
@get:Rule
- val flickerServiceRule = FlickerServiceRule(enabled = true, failTestOnFaasFailure = false)
+ val flickerServiceRule = FlickerServiceRule(enabled = true, failTestOnFlicker = false)
@PlatinumTest(focusArea = "sysui")
@Presubmit
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBackToSplitFromAnotherAppGesturalNavPortrait.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBackToSplitFromAnotherAppGesturalNavPortrait.kt
index 1ae2c9e..efbeb76 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBackToSplitFromAnotherAppGesturalNavPortrait.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBackToSplitFromAnotherAppGesturalNavPortrait.kt
@@ -27,7 +27,7 @@
open class SwitchBackToSplitFromAnotherAppGesturalNavPortrait :
SwitchBackToSplitFromAnotherApp(Rotation.ROTATION_0) {
@get:Rule
- val flickerServiceRule = FlickerServiceRule(enabled = true, failTestOnFaasFailure = false)
+ val flickerServiceRule = FlickerServiceRule(enabled = true, failTestOnFlicker = false)
@PlatinumTest(focusArea = "sysui")
@Presubmit
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBackToSplitFromHomeGesturalNavLandscape.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBackToSplitFromHomeGesturalNavLandscape.kt
index b1b56257..232fccc 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBackToSplitFromHomeGesturalNavLandscape.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBackToSplitFromHomeGesturalNavLandscape.kt
@@ -27,7 +27,7 @@
open class SwitchBackToSplitFromHomeGesturalNavLandscape :
SwitchBackToSplitFromHome(Rotation.ROTATION_90) {
@get:Rule
- val flickerServiceRule = FlickerServiceRule(enabled = true, failTestOnFaasFailure = false)
+ val flickerServiceRule = FlickerServiceRule(enabled = true, failTestOnFlicker = false)
@PlatinumTest(focusArea = "sysui")
@Presubmit
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBackToSplitFromHomeGesturalNavPortrait.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBackToSplitFromHomeGesturalNavPortrait.kt
index 08c437e..d7f2845 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBackToSplitFromHomeGesturalNavPortrait.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBackToSplitFromHomeGesturalNavPortrait.kt
@@ -27,7 +27,7 @@
open class SwitchBackToSplitFromHomeGesturalNavPortrait :
SwitchBackToSplitFromHome(Rotation.ROTATION_0) {
@get:Rule
- val flickerServiceRule = FlickerServiceRule(enabled = true, failTestOnFaasFailure = false)
+ val flickerServiceRule = FlickerServiceRule(enabled = true, failTestOnFlicker = false)
@PlatinumTest(focusArea = "sysui")
@Presubmit
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBackToSplitFromRecentGesturalNavLandscape.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBackToSplitFromRecentGesturalNavLandscape.kt
index efbf86d..019c946 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBackToSplitFromRecentGesturalNavLandscape.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBackToSplitFromRecentGesturalNavLandscape.kt
@@ -27,7 +27,7 @@
open class SwitchBackToSplitFromRecentGesturalNavLandscape :
SwitchBackToSplitFromRecent(Rotation.ROTATION_90) {
@get:Rule
- val flickerServiceRule = FlickerServiceRule(enabled = true, failTestOnFaasFailure = false)
+ val flickerServiceRule = FlickerServiceRule(enabled = true, failTestOnFlicker = false)
@PlatinumTest(focusArea = "sysui")
@Presubmit
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBackToSplitFromRecentGesturalNavPortrait.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBackToSplitFromRecentGesturalNavPortrait.kt
index f7072fa..5678861 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBackToSplitFromRecentGesturalNavPortrait.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBackToSplitFromRecentGesturalNavPortrait.kt
@@ -27,7 +27,7 @@
open class SwitchBackToSplitFromRecentGesturalNavPortrait :
SwitchBackToSplitFromRecent(Rotation.ROTATION_0) {
@get:Rule
- val flickerServiceRule = FlickerServiceRule(enabled = true, failTestOnFaasFailure = false)
+ val flickerServiceRule = FlickerServiceRule(enabled = true, failTestOnFlicker = false)
@PlatinumTest(focusArea = "sysui")
@Presubmit
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBetweenSplitPairsGesturalNavLandscape.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBetweenSplitPairsGesturalNavLandscape.kt
index d80d112..b3c4ea2 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBetweenSplitPairsGesturalNavLandscape.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBetweenSplitPairsGesturalNavLandscape.kt
@@ -27,7 +27,7 @@
open class SwitchBetweenSplitPairsGesturalNavLandscape :
SwitchBetweenSplitPairs(Rotation.ROTATION_90) {
@get:Rule
- val flickerServiceRule = FlickerServiceRule(enabled = true, failTestOnFaasFailure = false)
+ val flickerServiceRule = FlickerServiceRule(enabled = true, failTestOnFlicker = false)
@PlatinumTest(focusArea = "sysui")
@Presubmit
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBetweenSplitPairsGesturalNavPortrait.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBetweenSplitPairsGesturalNavPortrait.kt
index 30ec37a..f88180f 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBetweenSplitPairsGesturalNavPortrait.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBetweenSplitPairsGesturalNavPortrait.kt
@@ -27,7 +27,7 @@
open class SwitchBetweenSplitPairsGesturalNavPortrait :
SwitchBetweenSplitPairs(Rotation.ROTATION_0) {
@get:Rule
- val flickerServiceRule = FlickerServiceRule(enabled = true, failTestOnFaasFailure = false)
+ val flickerServiceRule = FlickerServiceRule(enabled = true, failTestOnFlicker = false)
@PlatinumTest(focusArea = "sysui")
@Presubmit
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/UnlockKeyguardToSplitScreenGesturalNavLandscape.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/UnlockKeyguardToSplitScreenGesturalNavLandscape.kt
index 1e086d2..391cb9b7 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/UnlockKeyguardToSplitScreenGesturalNavLandscape.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/UnlockKeyguardToSplitScreenGesturalNavLandscape.kt
@@ -28,7 +28,7 @@
@RunWith(BlockJUnit4ClassRunner::class)
open class UnlockKeyguardToSplitScreenGesturalNavLandscape : UnlockKeyguardToSplitScreen() {
@get:Rule
- val flickerServiceRule = FlickerServiceRule(enabled = true, failTestOnFaasFailure = false)
+ val flickerServiceRule = FlickerServiceRule(enabled = true, failTestOnFlicker = false)
@PlatinumTest(focusArea = "sysui")
@Presubmit
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/UnlockKeyguardToSplitScreenGesturalNavPortrait.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/UnlockKeyguardToSplitScreenGesturalNavPortrait.kt
index 932f892..4af133d 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/UnlockKeyguardToSplitScreenGesturalNavPortrait.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/UnlockKeyguardToSplitScreenGesturalNavPortrait.kt
@@ -28,7 +28,7 @@
@RunWith(BlockJUnit4ClassRunner::class)
open class UnlockKeyguardToSplitScreenGesturalNavPortrait : UnlockKeyguardToSplitScreen() {
@get:Rule
- val flickerServiceRule = FlickerServiceRule(enabled = true, failTestOnFaasFailure = false)
+ val flickerServiceRule = FlickerServiceRule(enabled = true, failTestOnFlicker = false)
@PlatinumTest(focusArea = "sysui")
@Presubmit
diff --git a/media/java/android/media/AudioAttributes.java b/media/java/android/media/AudioAttributes.java
index b0cdb05..230fb07 100644
--- a/media/java/android/media/AudioAttributes.java
+++ b/media/java/android/media/AudioAttributes.java
@@ -1167,7 +1167,10 @@
streamType);
if (attributes != null) {
mUsage = attributes.mUsage;
- mContentType = attributes.mContentType;
+ // on purpose ignoring the content type: stream types are deprecated for
+ // playback, making assumptions about the content type is prone to
+ // interpretation errors for ambiguous types such as STREAM_TTS and STREAM_MUSIC
+ //mContentType = attributes.mContentType;
mFlags = attributes.getAllFlags();
mMuteHapticChannels = attributes.areHapticChannelsMuted();
mIsContentSpatialized = attributes.isContentSpatialized();
@@ -1177,49 +1180,47 @@
mSource = attributes.mSource;
}
}
- if (mContentType == CONTENT_TYPE_UNKNOWN) {
- switch (streamType) {
- case AudioSystem.STREAM_VOICE_CALL:
- mContentType = CONTENT_TYPE_SPEECH;
- break;
- case AudioSystem.STREAM_SYSTEM_ENFORCED:
- mFlags |= FLAG_AUDIBILITY_ENFORCED;
- // intended fall through, attributes in common with STREAM_SYSTEM
- case AudioSystem.STREAM_SYSTEM:
- mContentType = CONTENT_TYPE_SONIFICATION;
- break;
- case AudioSystem.STREAM_RING:
- mContentType = CONTENT_TYPE_SONIFICATION;
- break;
- case AudioSystem.STREAM_MUSIC:
- mContentType = CONTENT_TYPE_MUSIC;
- break;
- case AudioSystem.STREAM_ALARM:
- mContentType = CONTENT_TYPE_SONIFICATION;
- break;
- case AudioSystem.STREAM_NOTIFICATION:
- mContentType = CONTENT_TYPE_SONIFICATION;
- break;
- case AudioSystem.STREAM_BLUETOOTH_SCO:
- mContentType = CONTENT_TYPE_SPEECH;
- mFlags |= FLAG_SCO;
- break;
- case AudioSystem.STREAM_DTMF:
- mContentType = CONTENT_TYPE_SONIFICATION;
- break;
- case AudioSystem.STREAM_TTS:
- mContentType = CONTENT_TYPE_SONIFICATION;
- mFlags |= FLAG_BEACON;
- break;
- case AudioSystem.STREAM_ACCESSIBILITY:
- mContentType = CONTENT_TYPE_SPEECH;
- break;
- case AudioSystem.STREAM_ASSISTANT:
- mContentType = CONTENT_TYPE_SPEECH;
- break;
- default:
- Log.e(TAG, "Invalid stream type " + streamType + " for AudioAttributes");
- }
+ switch (streamType) {
+ case AudioSystem.STREAM_VOICE_CALL:
+ mContentType = CONTENT_TYPE_SPEECH;
+ break;
+ case AudioSystem.STREAM_SYSTEM_ENFORCED:
+ mFlags |= FLAG_AUDIBILITY_ENFORCED;
+ // intended fall through, attributes in common with STREAM_SYSTEM
+ case AudioSystem.STREAM_SYSTEM:
+ mContentType = CONTENT_TYPE_SONIFICATION;
+ break;
+ case AudioSystem.STREAM_RING:
+ mContentType = CONTENT_TYPE_SONIFICATION;
+ break;
+ case AudioSystem.STREAM_ALARM:
+ mContentType = CONTENT_TYPE_SONIFICATION;
+ break;
+ case AudioSystem.STREAM_NOTIFICATION:
+ mContentType = CONTENT_TYPE_SONIFICATION;
+ break;
+ case AudioSystem.STREAM_BLUETOOTH_SCO:
+ mContentType = CONTENT_TYPE_SPEECH;
+ mFlags |= FLAG_SCO;
+ break;
+ case AudioSystem.STREAM_DTMF:
+ mContentType = CONTENT_TYPE_SONIFICATION;
+ break;
+ case AudioSystem.STREAM_TTS:
+ mContentType = CONTENT_TYPE_SONIFICATION;
+ mFlags |= FLAG_BEACON;
+ break;
+ case AudioSystem.STREAM_ACCESSIBILITY:
+ mContentType = CONTENT_TYPE_SPEECH;
+ break;
+ case AudioSystem.STREAM_ASSISTANT:
+ mContentType = CONTENT_TYPE_SPEECH;
+ break;
+ case AudioSystem.STREAM_MUSIC:
+ // leaving as CONTENT_TYPE_UNKNOWN
+ break;
+ default:
+ Log.e(TAG, "Invalid stream type " + streamType + " for AudioAttributes");
}
if (mUsage == USAGE_UNKNOWN) {
mUsage = usageForStreamType(streamType);
diff --git a/packages/SettingsLib/tests/integ/AndroidManifest.xml b/packages/SettingsLib/tests/integ/AndroidManifest.xml
index a95da303..32048ca 100644
--- a/packages/SettingsLib/tests/integ/AndroidManifest.xml
+++ b/packages/SettingsLib/tests/integ/AndroidManifest.xml
@@ -41,7 +41,7 @@
</application>
<instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
- android:targetPackage="com.android.settingslib"
+ android:targetPackage="com.android.settingslib.tests.integ"
android:label="Tests for SettingsLib">
</instrumentation>
</manifest>
diff --git a/packages/SettingsLib/tests/integ/AndroidTest.xml b/packages/SettingsLib/tests/integ/AndroidTest.xml
index b5d0947..d0aee88 100644
--- a/packages/SettingsLib/tests/integ/AndroidTest.xml
+++ b/packages/SettingsLib/tests/integ/AndroidTest.xml
@@ -21,7 +21,7 @@
<option name="test-suite-tag" value="apct" />
<option name="test-tag" value="SettingsLibTests" />
<test class="com.android.tradefed.testtype.AndroidJUnitTest" >
- <option name="package" value="com.android.settingslib" />
+ <option name="package" value="com.android.settingslib.tests.integ" />
<option name="runner" value="androidx.test.runner.AndroidJUnitRunner" />
<option name="hidden-api-checks" value="false"/>
</test>
diff --git a/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java b/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
index 1c33544..f6f75de 100644
--- a/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
+++ b/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
@@ -143,6 +143,7 @@
Settings.Secure.SCREENSAVER_ACTIVATE_ON_SLEEP,
Settings.Secure.SCREENSAVER_HOME_CONTROLS_ENABLED,
Settings.Secure.SHOW_FIRST_CRASH_DIALOG_DEV_OPTION,
+ Settings.Secure.VOLUME_DIALOG_DISMISS_TIMEOUT,
Settings.Secure.VOLUME_HUSH_GESTURE,
Settings.Secure.MANUAL_RINGER_TOGGLE_COUNT,
Settings.Secure.LOW_POWER_WARNING_ACKNOWLEDGED,
@@ -243,6 +244,7 @@
Settings.Secure.HEARING_AID_SYSTEM_SOUNDS_ROUTING,
Settings.Secure.ACCESSIBILITY_FONT_SCALING_HAS_BEEN_CHANGED,
Settings.Secure.SEARCH_PRESS_HOLD_NAV_HANDLE_ENABLED,
- Settings.Secure.SEARCH_LONG_PRESS_HOME_ENABLED
+ Settings.Secure.SEARCH_LONG_PRESS_HOME_ENABLED,
+ Settings.Secure.HUB_MODE_TUTORIAL_STATE
};
}
diff --git a/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java b/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
index 301fd6f..8d13f01 100644
--- a/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
+++ b/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
@@ -212,6 +212,7 @@
VALIDATORS.put(Secure.SCREENSAVER_ACTIVATE_ON_SLEEP, BOOLEAN_VALIDATOR);
VALIDATORS.put(Secure.SCREENSAVER_HOME_CONTROLS_ENABLED, BOOLEAN_VALIDATOR);
VALIDATORS.put(Secure.SHOW_FIRST_CRASH_DIALOG_DEV_OPTION, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(Secure.VOLUME_DIALOG_DISMISS_TIMEOUT, NON_NEGATIVE_INTEGER_VALIDATOR);
VALIDATORS.put(Secure.VOLUME_HUSH_GESTURE, NON_NEGATIVE_INTEGER_VALIDATOR);
VALIDATORS.put(
Secure.ENABLED_NOTIFICATION_LISTENERS,
@@ -389,5 +390,6 @@
VALIDATORS.put(Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_EDGE_HAPTIC_ENABLED,
BOOLEAN_VALIDATOR);
VALIDATORS.put(Secure.DND_CONFIGS_MIGRATED, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(Secure.HUB_MODE_TUTORIAL_STATE, NON_NEGATIVE_INTEGER_VALIDATOR);
}
}
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index b5b873c..9bfc4be 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -634,7 +634,7 @@
<!-- started from MediaProjectionManager -->
<activity
- android:name=".media.MediaProjectionPermissionActivity"
+ android:name=".mediaprojection.permission.MediaProjectionPermissionActivity"
android:exported="true"
android:theme="@style/Theme.SystemUI.MediaProjectionAlertDialog"
android:finishOnCloseSystemDialogs="true"
@@ -643,7 +643,7 @@
android:visibleToInstantApps="true"/>
<activity
- android:name=".media.MediaProjectionAppSelectorActivity"
+ android:name=".mediaprojection.appselector.MediaProjectionAppSelectorActivity"
android:theme="@style/Theme.SystemUI.MediaProjectionAppSelector"
android:finishOnCloseSystemDialogs="true"
android:excludeFromRecents="true"
diff --git a/packages/SystemUI/compose/core/src/com/android/compose/animation/scene/Element.kt b/packages/SystemUI/compose/core/src/com/android/compose/animation/scene/Element.kt
index 0cc259a..a62c984 100644
--- a/packages/SystemUI/compose/core/src/com/android/compose/animation/scene/Element.kt
+++ b/packages/SystemUI/compose/core/src/com/android/compose/animation/scene/Element.kt
@@ -151,7 +151,7 @@
element.lastAlpha = alpha
}
}
- .testTag(key.name)
+ .testTag(key.testTag)
}
private fun shouldDrawElement(
@@ -167,7 +167,8 @@
state.fromScene == state.toScene ||
!layoutImpl.isTransitionReady(state) ||
state.fromScene !in element.sceneValues ||
- state.toScene !in element.sceneValues
+ state.toScene !in element.sceneValues ||
+ !isSharedElementEnabled(layoutImpl, state, element.key)
) {
return true
}
@@ -191,6 +192,26 @@
}
}
+private fun isSharedElementEnabled(
+ layoutImpl: SceneTransitionLayoutImpl,
+ transition: TransitionState.Transition,
+ element: ElementKey,
+): Boolean {
+ val spec = layoutImpl.transitions.transitionSpec(transition.fromScene, transition.toScene)
+ val sharedInFromScene = spec.transformations(element, transition.fromScene).shared
+ val sharedInToScene = spec.transformations(element, transition.toScene).shared
+
+ // The sharedElement() transformation must either be null or be the same in both scenes.
+ if (sharedInFromScene != sharedInToScene) {
+ error(
+ "Different sharedElement() transformations matched $element (from=$sharedInFromScene " +
+ "to=$sharedInToScene)"
+ )
+ }
+
+ return sharedInFromScene?.enabled ?: true
+}
+
/**
* Chain the [com.android.compose.animation.scene.transformation.ModifierTransformation] applied
* throughout the current transition, if any.
@@ -213,7 +234,7 @@
return layoutImpl.transitions
.transitionSpec(fromScene, state.toScene)
- .transformations(element.key)
+ .transformations(element.key, scene.key)
.modifier
.fold(this) { modifier, transformation ->
with(transformation) {
@@ -407,17 +428,20 @@
// The element is shared: interpolate between the value in fromScene and the value in toScene.
// TODO(b/290184746): Support non linear shared paths as well as a way to make sure that shared
// elements follow the finger direction.
- if (fromValues != null && toValues != null) {
+ val isSharedElement = fromValues != null && toValues != null
+ if (isSharedElement && isSharedElementEnabled(layoutImpl, state, element.key)) {
return lerp(
- sceneValue(fromValues),
- sceneValue(toValues),
+ sceneValue(fromValues!!),
+ sceneValue(toValues!!),
transitionProgress,
)
}
val transformation =
transformation(
- layoutImpl.transitions.transitionSpec(fromScene, toScene).transformations(element.key)
+ layoutImpl.transitions
+ .transitionSpec(fromScene, toScene)
+ .transformations(element.key, scene.key)
)
// If there is no transformation explicitly associated to this element value, let's use
// the value given by the system (like the current position and size given by the layout
@@ -426,12 +450,21 @@
// Get the transformed value, i.e. the target value at the beginning (for entering elements) or
// end (for leaving elements) of the transition.
+ val sceneValues =
+ checkNotNull(
+ when {
+ isSharedElement && scene.key == fromScene -> fromValues
+ isSharedElement -> toValues
+ else -> fromValues ?: toValues
+ }
+ )
+
val targetValue =
transformation.transform(
layoutImpl,
scene,
element,
- fromValues ?: toValues!!,
+ sceneValues,
state,
idleValue,
)
@@ -440,7 +473,7 @@
val rangeProgress = transformation.range?.progress(transitionProgress) ?: transitionProgress
// Interpolate between the value at rest and the value before entering/after leaving.
- val isEntering = fromValues == null
+ val isEntering = scene.key == toScene
return if (isEntering) {
lerp(targetValue, idleValue, rangeProgress)
} else {
diff --git a/packages/SystemUI/compose/core/src/com/android/compose/animation/scene/ElementMatcher.kt b/packages/SystemUI/compose/core/src/com/android/compose/animation/scene/ElementMatcher.kt
new file mode 100644
index 0000000..98dbb67
--- /dev/null
+++ b/packages/SystemUI/compose/core/src/com/android/compose/animation/scene/ElementMatcher.kt
@@ -0,0 +1,37 @@
+/*
+ * 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.compose.animation.scene
+
+/** An interface to match one or more elements. */
+interface ElementMatcher {
+ /** Whether the element with key [key] in scene [scene] matches this matcher. */
+ fun matches(key: ElementKey, scene: SceneKey): Boolean
+}
+
+/**
+ * Returns an [ElementMatcher] that matches elements in [scene] also matching [this]
+ * [ElementMatcher].
+ */
+fun ElementMatcher.inScene(scene: SceneKey): ElementMatcher {
+ val delegate = this
+ val matcherScene = scene
+ return object : ElementMatcher {
+ override fun matches(key: ElementKey, scene: SceneKey): Boolean {
+ return scene == matcherScene && delegate.matches(key, scene)
+ }
+ }
+}
diff --git a/packages/SystemUI/compose/core/src/com/android/compose/animation/scene/Key.kt b/packages/SystemUI/compose/core/src/com/android/compose/animation/scene/Key.kt
index f7ebe2f..b7acc48 100644
--- a/packages/SystemUI/compose/core/src/com/android/compose/animation/scene/Key.kt
+++ b/packages/SystemUI/compose/core/src/com/android/compose/animation/scene/Key.kt
@@ -16,6 +16,8 @@
package com.android.compose.animation.scene
+import androidx.annotation.VisibleForTesting
+
/**
* A base class to create unique keys, associated to an [identity] that is used to check the
* equality of two key instances.
@@ -41,6 +43,7 @@
name: String,
identity: Any = Object(),
) : Key(name, identity) {
+ @VisibleForTesting val testTag: String = "scene:$name"
/** The unique [ElementKey] identifying this scene's root element. */
val rootElementKey = ElementKey(name, identity)
@@ -61,7 +64,9 @@
*/
val isBackground: Boolean = false,
) : Key(name, identity), ElementMatcher {
- override fun matches(key: ElementKey): Boolean {
+ @VisibleForTesting val testTag: String = "element:$name"
+
+ override fun matches(key: ElementKey, scene: SceneKey): Boolean {
return key == this
}
@@ -73,7 +78,9 @@
/** Matches any element whose [key identity][ElementKey.identity] matches [predicate]. */
fun withIdentity(predicate: (Any) -> Boolean): ElementMatcher {
return object : ElementMatcher {
- override fun matches(key: ElementKey): Boolean = predicate(key.identity)
+ override fun matches(key: ElementKey, scene: SceneKey): Boolean {
+ return predicate(key.identity)
+ }
}
}
}
diff --git a/packages/SystemUI/compose/core/src/com/android/compose/animation/scene/Scene.kt b/packages/SystemUI/compose/core/src/com/android/compose/animation/scene/Scene.kt
index b44c8ef..3985233 100644
--- a/packages/SystemUI/compose/core/src/com/android/compose/animation/scene/Scene.kt
+++ b/packages/SystemUI/compose/core/src/com/android/compose/animation/scene/Scene.kt
@@ -25,6 +25,7 @@
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.onPlaced
+import androidx.compose.ui.platform.testTag
import androidx.compose.ui.unit.IntSize
import androidx.compose.ui.zIndex
@@ -45,7 +46,9 @@
@Composable
fun Content(modifier: Modifier = Modifier) {
- Box(modifier.zIndex(zIndex).onPlaced { size = it.size }) { scope.content() }
+ Box(modifier.zIndex(zIndex).onPlaced { size = it.size }.testTag(key.testTag)) {
+ scope.content()
+ }
}
override fun toString(): String {
diff --git a/packages/SystemUI/compose/core/src/com/android/compose/animation/scene/SceneTransitions.kt b/packages/SystemUI/compose/core/src/com/android/compose/animation/scene/SceneTransitions.kt
index f4e3902..75dcb2e 100644
--- a/packages/SystemUI/compose/core/src/com/android/compose/animation/scene/SceneTransitions.kt
+++ b/packages/SystemUI/compose/core/src/com/android/compose/animation/scene/SceneTransitions.kt
@@ -16,6 +16,7 @@
package com.android.compose.animation.scene
+import androidx.annotation.VisibleForTesting
import androidx.compose.animation.core.AnimationSpec
import androidx.compose.animation.core.snap
import androidx.compose.ui.geometry.Offset
@@ -28,6 +29,7 @@
import com.android.compose.animation.scene.transformation.PropertyTransformation
import com.android.compose.animation.scene.transformation.RangedPropertyTransformation
import com.android.compose.animation.scene.transformation.ScaleSize
+import com.android.compose.animation.scene.transformation.SharedElementTransformation
import com.android.compose.animation.scene.transformation.Transformation
import com.android.compose.animation.scene.transformation.Translate
import com.android.compose.ui.util.fastForEach
@@ -35,11 +37,12 @@
/** The transitions configuration of a [SceneTransitionLayout]. */
class SceneTransitions(
- private val transitionSpecs: List<TransitionSpec>,
+ @get:VisibleForTesting val transitionSpecs: List<TransitionSpec>,
) {
private val cache = mutableMapOf<SceneKey, MutableMap<SceneKey, TransitionSpec>>()
- internal fun transitionSpec(from: SceneKey, to: SceneKey): TransitionSpec {
+ @VisibleForTesting
+ fun transitionSpec(from: SceneKey, to: SceneKey): TransitionSpec {
return cache.getOrPut(from) { mutableMapOf() }.getOrPut(to) { findSpec(from, to) }
}
@@ -97,7 +100,8 @@
val transformations: List<Transformation>,
val spec: AnimationSpec<Float>,
) {
- private val cache = mutableMapOf<ElementKey, ElementTransformations>()
+ // TODO(b/302300957): Make sure this cache does not infinitely grow.
+ private val cache = mutableMapOf<ElementKey, MutableMap<SceneKey, ElementTransformations>>()
internal fun reverse(): TransitionSpec {
return copy(
@@ -107,12 +111,18 @@
)
}
- internal fun transformations(element: ElementKey): ElementTransformations {
- return cache.getOrPut(element) { computeTransformations(element) }
+ internal fun transformations(element: ElementKey, scene: SceneKey): ElementTransformations {
+ return cache
+ .getOrPut(element) { mutableMapOf() }
+ .getOrPut(scene) { computeTransformations(element, scene) }
}
/** Filter [transformations] to compute the [ElementTransformations] of [element]. */
- private fun computeTransformations(element: ElementKey): ElementTransformations {
+ private fun computeTransformations(
+ element: ElementKey,
+ scene: SceneKey,
+ ): ElementTransformations {
+ var shared: SharedElementTransformation? = null
val modifier = mutableListOf<ModifierTransformation>()
var offset: PropertyTransformation<Offset>? = null
var size: PropertyTransformation<IntSize>? = null
@@ -126,16 +136,16 @@
is Translate,
is EdgeTranslate,
is AnchoredTranslate -> {
- throwIfNotNull(offset, element, property = "offset")
+ throwIfNotNull(offset, element, name = "offset")
offset = root as PropertyTransformation<Offset>
}
is ScaleSize,
is AnchoredSize -> {
- throwIfNotNull(size, element, property = "size")
+ throwIfNotNull(size, element, name = "size")
size = root as PropertyTransformation<IntSize>
}
is Fade -> {
- throwIfNotNull(alpha, element, property = "alpha")
+ throwIfNotNull(alpha, element, name = "alpha")
alpha = root as PropertyTransformation<Float>
}
is RangedPropertyTransformation -> onPropertyTransformation(root, current.delegate)
@@ -143,32 +153,37 @@
}
transformations.fastForEach { transformation ->
- if (!transformation.matcher.matches(element)) {
+ if (!transformation.matcher.matches(element, scene)) {
return@fastForEach
}
when (transformation) {
+ is SharedElementTransformation -> {
+ throwIfNotNull(shared, element, name = "shared")
+ shared = transformation
+ }
is ModifierTransformation -> modifier.add(transformation)
is PropertyTransformation<*> -> onPropertyTransformation(transformation)
}
}
- return ElementTransformations(modifier, offset, size, alpha)
+ return ElementTransformations(shared, modifier, offset, size, alpha)
}
private fun throwIfNotNull(
- previous: PropertyTransformation<*>?,
+ previous: Transformation?,
element: ElementKey,
- property: String,
+ name: String,
) {
if (previous != null) {
- error("$element has multiple transformations for its $property property")
+ error("$element has multiple $name transformations")
}
}
}
/** The transformations of an element during a transition. */
internal class ElementTransformations(
+ val shared: SharedElementTransformation?,
val modifier: List<ModifierTransformation>,
val offset: PropertyTransformation<Offset>?,
val size: PropertyTransformation<IntSize>?,
diff --git a/packages/SystemUI/compose/core/src/com/android/compose/animation/scene/TransitionDsl.kt b/packages/SystemUI/compose/core/src/com/android/compose/animation/scene/TransitionDsl.kt
index fb12b90..4966977 100644
--- a/packages/SystemUI/compose/core/src/com/android/compose/animation/scene/TransitionDsl.kt
+++ b/packages/SystemUI/compose/core/src/com/android/compose/animation/scene/TransitionDsl.kt
@@ -116,6 +116,14 @@
)
/**
+ * Configure the shared transition when [matcher] is shared between two scenes.
+ *
+ * @param enabled whether the matched element(s) should actually be shared in this transition.
+ * Defaults to true.
+ */
+ fun sharedElement(matcher: ElementMatcher, enabled: Boolean = true)
+
+ /**
* Punch a hole in the element(s) matching [matcher] that has the same bounds as [bounds] and
* using the given [shape].
*
@@ -127,6 +135,13 @@
* the result.
*/
fun punchHole(matcher: ElementMatcher, bounds: ElementKey, shape: Shape = RectangleShape)
+
+ /**
+ * Adds the transformations in [builder] but in reversed order. This allows you to partially
+ * reuse the definition of the transition from scene `Foo` to scene `Bar` inside the definition
+ * of the transition from scene `Bar` to scene `Foo`.
+ */
+ fun reversed(builder: TransitionBuilder.() -> Unit)
}
@TransitionDsl
@@ -179,12 +194,6 @@
fun anchoredSize(matcher: ElementMatcher, anchor: ElementKey)
}
-/** An interface to match one or more elements. */
-interface ElementMatcher {
- /** Whether the element with key [key] matches this matcher. */
- fun matches(key: ElementKey): Boolean
-}
-
/** The edge of a [SceneTransitionLayout]. */
enum class Edge {
Left,
diff --git a/packages/SystemUI/compose/core/src/com/android/compose/animation/scene/TransitionDslImpl.kt b/packages/SystemUI/compose/core/src/com/android/compose/animation/scene/TransitionDslImpl.kt
index 48d5638e8b..f1c2717 100644
--- a/packages/SystemUI/compose/core/src/com/android/compose/animation/scene/TransitionDslImpl.kt
+++ b/packages/SystemUI/compose/core/src/com/android/compose/animation/scene/TransitionDslImpl.kt
@@ -31,6 +31,7 @@
import com.android.compose.animation.scene.transformation.PunchHole
import com.android.compose.animation.scene.transformation.RangedPropertyTransformation
import com.android.compose.animation.scene.transformation.ScaleSize
+import com.android.compose.animation.scene.transformation.SharedElementTransformation
import com.android.compose.animation.scene.transformation.Transformation
import com.android.compose.animation.scene.transformation.TransformationRange
import com.android.compose.animation.scene.transformation.Translate
@@ -80,6 +81,7 @@
override var spec: AnimationSpec<Float> = spring(stiffness = Spring.StiffnessLow)
private var range: TransformationRange? = null
+ private var reversed = false
private val durationMillis: Int by lazy {
val spec = spec
if (spec !is DurationBasedAnimationSpec) {
@@ -93,6 +95,12 @@
transformations.add(PunchHole(matcher, bounds, shape))
}
+ override fun reversed(builder: TransitionBuilder.() -> Unit) {
+ reversed = true
+ builder()
+ reversed = false
+ }
+
override fun fractionRange(
start: Float?,
end: Float?,
@@ -103,6 +111,10 @@
range = null
}
+ override fun sharedElement(matcher: ElementMatcher, enabled: Boolean) {
+ transformations.add(SharedElementTransformation(matcher, enabled))
+ }
+
override fun timestampRange(
startMillis: Int?,
endMillis: Int?,
@@ -122,11 +134,20 @@
}
private fun transformation(transformation: PropertyTransformation<*>) {
- if (range != null) {
- transformations.add(RangedPropertyTransformation(transformation, range!!))
- } else {
- transformations.add(transformation)
- }
+ val transformation =
+ if (range != null) {
+ RangedPropertyTransformation(transformation, range!!)
+ } else {
+ transformation
+ }
+
+ transformations.add(
+ if (reversed) {
+ transformation.reverse()
+ } else {
+ transformation
+ }
+ )
}
override fun fade(matcher: ElementMatcher) {
diff --git a/packages/SystemUI/compose/core/src/com/android/compose/animation/scene/transformation/Transformation.kt b/packages/SystemUI/compose/core/src/com/android/compose/animation/scene/transformation/Transformation.kt
index ce6749d..a650254 100644
--- a/packages/SystemUI/compose/core/src/com/android/compose/animation/scene/transformation/Transformation.kt
+++ b/packages/SystemUI/compose/core/src/com/android/compose/animation/scene/transformation/Transformation.kt
@@ -30,6 +30,14 @@
*/
val matcher: ElementMatcher
+ /**
+ * The range during which the transformation is applied. If it is `null`, then the
+ * transformation will be applied throughout the whole scene transition.
+ */
+ // TODO(b/240432457): Move this back to PropertyTransformation.
+ val range: TransformationRange?
+ get() = null
+
/*
* Reverse this transformation. This is called when we use Transition(from = A, to = B) when
* animating from B to A and there is no Transition(from = B, to = A) defined.
@@ -37,6 +45,11 @@
fun reverse(): Transformation = this
}
+internal class SharedElementTransformation(
+ override val matcher: ElementMatcher,
+ internal val enabled: Boolean,
+) : Transformation
+
/** A transformation that is applied on the element during the whole transition. */
internal interface ModifierTransformation : Transformation {
/** Apply the transformation to [element]. */
@@ -53,13 +66,6 @@
/** A transformation that changes the value of an element property, like its size or offset. */
internal sealed interface PropertyTransformation<T> : Transformation {
/**
- * The range during which the transformation is applied. If it is `null`, then the
- * transformation will be applied throughout the whole scene transition.
- */
- val range: TransformationRange?
- get() = null
-
- /**
* Transform [value], i.e. the value of the transformed property without this transformation.
*/
// TODO(b/290184746): Figure out a public API for custom transformations that don't have access
@@ -92,8 +98,7 @@
}
/** The progress-based range of a [PropertyTransformation]. */
-data class TransformationRange
-private constructor(
+data class TransformationRange(
val start: Float,
val end: Float,
) {
@@ -133,6 +138,6 @@
}
companion object {
- private const val BoundUnspecified = Float.MIN_VALUE
+ const val BoundUnspecified = Float.MIN_VALUE
}
}
diff --git a/packages/SystemUI/compose/core/tests/src/com/android/compose/animation/scene/SceneTransitionLayoutTest.kt b/packages/SystemUI/compose/core/tests/src/com/android/compose/animation/scene/SceneTransitionLayoutTest.kt
index 8bd6545..328866e 100644
--- a/packages/SystemUI/compose/core/tests/src/com/android/compose/animation/scene/SceneTransitionLayoutTest.kt
+++ b/packages/SystemUI/compose/core/tests/src/com/android/compose/animation/scene/SceneTransitionLayoutTest.kt
@@ -224,7 +224,7 @@
// In scene A, the shared element SharedFoo() is at the top end of the layout and has a size
// of 50.dp.
- var sharedFoo = rule.onNodeWithTag(TestElements.Foo.name, useUnmergedTree = true)
+ var sharedFoo = rule.onNodeWithTag(TestElements.Foo.testTag, useUnmergedTree = true)
sharedFoo.assertWidthIsEqualTo(50.dp)
sharedFoo.assertHeightIsEqualTo(50.dp)
sharedFoo.assertPositionInRootIsEqualTo(
@@ -250,7 +250,7 @@
// We need to use onAllNodesWithTag().onFirst() here given that shared elements are
// composed and laid out in both scenes (but drawn only in one).
- sharedFoo = rule.onAllNodesWithTag(TestElements.Foo.name).onFirst()
+ sharedFoo = rule.onAllNodesWithTag(TestElements.Foo.testTag).onFirst()
// In scene B, foo is at the top start (x = 0, y = 0) of the layout and has a size of
// 100.dp. We pause at the middle of the transition, so it should now be 75.dp given that we
@@ -284,7 +284,7 @@
val expectedLeft = 0.dp
val expectedSize = 100.dp + (150.dp - 100.dp) * interpolatedProgress
- sharedFoo = rule.onAllNodesWithTag(TestElements.Foo.name).onFirst()
+ sharedFoo = rule.onAllNodesWithTag(TestElements.Foo.testTag).onFirst()
assertThat((layoutState.transitionState as TransitionState.Transition).progress)
.isEqualTo(interpolatedProgress)
sharedFoo.assertWidthIsEqualTo(expectedSize)
diff --git a/packages/SystemUI/compose/core/tests/src/com/android/compose/animation/scene/TestTransition.kt b/packages/SystemUI/compose/core/tests/src/com/android/compose/animation/scene/TestTransition.kt
index 275149a0..268057f 100644
--- a/packages/SystemUI/compose/core/tests/src/com/android/compose/animation/scene/TestTransition.kt
+++ b/packages/SystemUI/compose/core/tests/src/com/android/compose/animation/scene/TestTransition.kt
@@ -23,7 +23,11 @@
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.test.SemanticsNodeInteraction
+import androidx.compose.ui.test.SemanticsNodeInteractionCollection
+import androidx.compose.ui.test.hasParent
+import androidx.compose.ui.test.hasTestTag
import androidx.compose.ui.test.junit4.ComposeContentTestRule
+import androidx.compose.ui.test.onAllNodesWithTag
import androidx.compose.ui.test.onNodeWithTag
@DslMarker annotation class TransitionTestDsl
@@ -59,8 +63,21 @@
@TransitionTestDsl
interface TransitionTestAssertionScope {
- /** Assert on [element]. */
- fun onElement(element: ElementKey): SemanticsNodeInteraction
+ /**
+ * Assert on [element].
+ *
+ * Note that presence/value assertions on the returned [SemanticsNodeInteraction] will fail if 0
+ * or more than 1 elements matched [element]. If you need to assert on a shared element that
+ * will be present multiple times in the layout during transitions, either specify the [scene]
+ * in which you are matching or use [onSharedElement] instead.
+ */
+ fun onElement(element: ElementKey, scene: SceneKey? = null): SemanticsNodeInteraction
+
+ /**
+ * Assert on a shared [element]. This will throw if [element] is not shared and present only in
+ * one scene during a transition.
+ */
+ fun onSharedElement(element: ElementKey): SemanticsNodeInteractionCollection
}
/**
@@ -73,20 +90,22 @@
toSceneContent: @Composable SceneScope.() -> Unit,
transition: TransitionBuilder.() -> Unit,
layoutModifier: Modifier = Modifier,
+ fromScene: SceneKey = TestScenes.SceneA,
+ toScene: SceneKey = TestScenes.SceneB,
builder: TransitionTestBuilder.() -> Unit,
) {
testTransition(
- from = TestScenes.SceneA,
- to = TestScenes.SceneB,
+ from = fromScene,
+ to = toScene,
transitionLayout = { currentScene, onChangeScene ->
SceneTransitionLayout(
currentScene,
onChangeScene,
- transitions { from(TestScenes.SceneA, to = TestScenes.SceneB, transition) },
+ transitions { from(fromScene, to = toScene, transition) },
layoutModifier.fillMaxSize(),
) {
- scene(TestScenes.SceneA, content = fromSceneContent)
- scene(TestScenes.SceneB, content = toSceneContent)
+ scene(fromScene, content = fromSceneContent)
+ scene(toScene, content = toSceneContent)
}
},
builder,
@@ -111,8 +130,24 @@
val test = transitionTest(builder)
val assertionScope =
object : TransitionTestAssertionScope {
- override fun onElement(element: ElementKey): SemanticsNodeInteraction {
- return this@testTransition.onNodeWithTag(element.name)
+ override fun onElement(
+ element: ElementKey,
+ scene: SceneKey?
+ ): SemanticsNodeInteraction {
+ return if (scene == null) {
+ onNodeWithTag(element.testTag)
+ } else {
+ onNode(hasTestTag(element.testTag) and hasParent(hasTestTag(scene.testTag)))
+ }
+ }
+
+ override fun onSharedElement(element: ElementKey): SemanticsNodeInteractionCollection {
+ val interaction = onAllNodesWithTag(element.testTag)
+ val matches = interaction.fetchSemanticsNodes(atLeastOneRootRequired = false).size
+ if (matches < 2) {
+ error("Element $element is not shared ($matches matches)")
+ }
+ return interaction
}
}
diff --git a/packages/SystemUI/compose/core/tests/src/com/android/compose/animation/scene/TransitionDslTest.kt b/packages/SystemUI/compose/core/tests/src/com/android/compose/animation/scene/TransitionDslTest.kt
new file mode 100644
index 0000000..fa94b250
--- /dev/null
+++ b/packages/SystemUI/compose/core/tests/src/com/android/compose/animation/scene/TransitionDslTest.kt
@@ -0,0 +1,190 @@
+/*
+ * 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.compose.animation.scene
+
+import androidx.compose.animation.core.SpringSpec
+import androidx.compose.animation.core.TweenSpec
+import androidx.compose.animation.core.tween
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import com.android.compose.animation.scene.transformation.Transformation
+import com.android.compose.animation.scene.transformation.TransformationRange
+import com.google.common.truth.Correspondence
+import com.google.common.truth.Truth.assertThat
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(AndroidJUnit4::class)
+class TransitionDslTest {
+ @Test
+ fun emptyTransitions() {
+ val transitions = transitions {}
+ assertThat(transitions.transitionSpecs).isEmpty()
+ }
+
+ @Test
+ fun manyTransitions() {
+ val transitions = transitions {
+ from(TestScenes.SceneA, to = TestScenes.SceneB)
+ from(TestScenes.SceneB, to = TestScenes.SceneC)
+ from(TestScenes.SceneC, to = TestScenes.SceneA)
+ }
+ assertThat(transitions.transitionSpecs).hasSize(3)
+ }
+
+ @Test
+ fun toFromBuilders() {
+ val transitions = transitions {
+ from(TestScenes.SceneA, to = TestScenes.SceneB)
+ from(TestScenes.SceneB)
+ to(TestScenes.SceneC)
+ }
+
+ assertThat(transitions.transitionSpecs)
+ .comparingElementsUsing(
+ Correspondence.transforming<TransitionSpec, Pair<SceneKey?, SceneKey?>>(
+ { it?.from to it?.to },
+ "has (from, to) equal to"
+ )
+ )
+ .containsExactly(
+ TestScenes.SceneA to TestScenes.SceneB,
+ TestScenes.SceneB to null,
+ null to TestScenes.SceneC,
+ )
+ }
+
+ @Test
+ fun defaultTransitionSpec() {
+ val transitions = transitions { from(TestScenes.SceneA, to = TestScenes.SceneB) }
+ val transition = transitions.transitionSpecs.single()
+ assertThat(transition.spec).isInstanceOf(SpringSpec::class.java)
+ }
+
+ @Test
+ fun customTransitionSpec() {
+ val transitions = transitions {
+ from(TestScenes.SceneA, to = TestScenes.SceneB) { spec = tween(durationMillis = 42) }
+ }
+ val transition = transitions.transitionSpecs.single()
+ assertThat(transition.spec).isInstanceOf(TweenSpec::class.java)
+ assertThat((transition.spec as TweenSpec).durationMillis).isEqualTo(42)
+ }
+
+ @Test
+ fun defaultRange() {
+ val transitions = transitions {
+ from(TestScenes.SceneA, to = TestScenes.SceneB) { fade(TestElements.Foo) }
+ }
+
+ val transition = transitions.transitionSpecs.single()
+ assertThat(transition.transformations.size).isEqualTo(1)
+ assertThat(transition.transformations.single().range).isEqualTo(null)
+ }
+
+ @Test
+ fun fractionRange() {
+ val transitions = transitions {
+ from(TestScenes.SceneA, to = TestScenes.SceneB) {
+ fractionRange(start = 0.1f, end = 0.8f) { fade(TestElements.Foo) }
+ fractionRange(start = 0.2f) { fade(TestElements.Foo) }
+ fractionRange(end = 0.9f) { fade(TestElements.Foo) }
+ }
+ }
+
+ val transition = transitions.transitionSpecs.single()
+ assertThat(transition.transformations)
+ .comparingElementsUsing(TRANSFORMATION_RANGE)
+ .containsExactly(
+ TransformationRange(start = 0.1f, end = 0.8f),
+ TransformationRange(start = 0.2f, end = TransformationRange.BoundUnspecified),
+ TransformationRange(start = TransformationRange.BoundUnspecified, end = 0.9f),
+ )
+ }
+
+ @Test
+ fun timestampRange() {
+ val transitions = transitions {
+ from(TestScenes.SceneA, to = TestScenes.SceneB) {
+ spec = tween(500)
+
+ timestampRange(startMillis = 100, endMillis = 300) { fade(TestElements.Foo) }
+ timestampRange(startMillis = 200) { fade(TestElements.Foo) }
+ timestampRange(endMillis = 400) { fade(TestElements.Foo) }
+ }
+ }
+
+ val transition = transitions.transitionSpecs.single()
+ assertThat(transition.transformations)
+ .comparingElementsUsing(TRANSFORMATION_RANGE)
+ .containsExactly(
+ TransformationRange(start = 100 / 500f, end = 300 / 500f),
+ TransformationRange(start = 200 / 500f, end = TransformationRange.BoundUnspecified),
+ TransformationRange(start = TransformationRange.BoundUnspecified, end = 400 / 500f),
+ )
+ }
+
+ @Test
+ fun reversed() {
+ val transitions = transitions {
+ from(TestScenes.SceneA, to = TestScenes.SceneB) {
+ spec = tween(500)
+ reversed {
+ fractionRange(start = 0.1f, end = 0.8f) { fade(TestElements.Foo) }
+ timestampRange(startMillis = 100, endMillis = 300) { fade(TestElements.Foo) }
+ }
+ }
+ }
+
+ val transition = transitions.transitionSpecs.single()
+ assertThat(transition.transformations)
+ .comparingElementsUsing(TRANSFORMATION_RANGE)
+ .containsExactly(
+ TransformationRange(start = 1f - 0.8f, end = 1f - 0.1f),
+ TransformationRange(start = 1f - 300 / 500f, end = 1f - 100 / 500f),
+ )
+ }
+
+ @Test
+ fun defaultReversed() {
+ val transitions = transitions {
+ from(TestScenes.SceneA, to = TestScenes.SceneB) {
+ spec = tween(500)
+ fractionRange(start = 0.1f, end = 0.8f) { fade(TestElements.Foo) }
+ timestampRange(startMillis = 100, endMillis = 300) { fade(TestElements.Foo) }
+ }
+ }
+
+ // Fetch the transition from B to A, which will automatically reverse the transition from A
+ // to B we defined.
+ val transition =
+ transitions.transitionSpec(from = TestScenes.SceneB, to = TestScenes.SceneA)
+ assertThat(transition.transformations)
+ .comparingElementsUsing(TRANSFORMATION_RANGE)
+ .containsExactly(
+ TransformationRange(start = 1f - 0.8f, end = 1f - 0.1f),
+ TransformationRange(start = 1f - 300 / 500f, end = 1f - 100 / 500f),
+ )
+ }
+
+ companion object {
+ private val TRANSFORMATION_RANGE =
+ Correspondence.transforming<Transformation, TransformationRange?>(
+ { it?.range },
+ "has range equal to"
+ )
+ }
+}
diff --git a/packages/SystemUI/compose/core/tests/src/com/android/compose/animation/scene/transformation/SharedElementTest.kt b/packages/SystemUI/compose/core/tests/src/com/android/compose/animation/scene/transformation/SharedElementTest.kt
new file mode 100644
index 0000000..2af3638
--- /dev/null
+++ b/packages/SystemUI/compose/core/tests/src/com/android/compose/animation/scene/transformation/SharedElementTest.kt
@@ -0,0 +1,157 @@
+/*
+ * 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.compose.animation.scene.transformation
+
+import androidx.compose.animation.core.LinearEasing
+import androidx.compose.animation.core.tween
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.offset
+import androidx.compose.foundation.layout.size
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.test.assertPositionInRootIsEqualTo
+import androidx.compose.ui.test.junit4.createComposeRule
+import androidx.compose.ui.unit.dp
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import com.android.compose.animation.scene.Edge
+import com.android.compose.animation.scene.TestElements
+import com.android.compose.animation.scene.TestScenes
+import com.android.compose.animation.scene.inScene
+import com.android.compose.animation.scene.testTransition
+import com.android.compose.modifiers.size
+import com.android.compose.test.assertSizeIsEqualTo
+import com.android.compose.test.onEach
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(AndroidJUnit4::class)
+class SharedElementTest {
+ @get:Rule val rule = createComposeRule()
+
+ @Test
+ fun testSharedElement() {
+ rule.testTransition(
+ fromSceneContent = {
+ // Foo is at (10, 50) with a size of (20, 80).
+ Box(Modifier.offset(10.dp, 50.dp).element(TestElements.Foo).size(20.dp, 80.dp))
+ },
+ toSceneContent = {
+ // Foo is at (50, 70) with a size of (10, 40).
+ Box(Modifier.offset(50.dp, 70.dp).element(TestElements.Foo).size(10.dp, 40.dp))
+ },
+ transition = {
+ spec = tween(16 * 4, easing = LinearEasing)
+ // Elements should be shared by default.
+ }
+ ) {
+ before {
+ onElement(TestElements.Foo).assertPositionInRootIsEqualTo(10.dp, 50.dp)
+ onElement(TestElements.Foo).assertSizeIsEqualTo(20.dp, 80.dp)
+ }
+ at(0) {
+ onSharedElement(TestElements.Foo).onEach {
+ assertPositionInRootIsEqualTo(10.dp, 50.dp)
+ assertSizeIsEqualTo(20.dp, 80.dp)
+ }
+ }
+ at(16) {
+ onSharedElement(TestElements.Foo).onEach {
+ assertPositionInRootIsEqualTo(20.dp, 55.dp)
+ assertSizeIsEqualTo(17.5.dp, 70.dp)
+ }
+ }
+ at(32) {
+ onSharedElement(TestElements.Foo).onEach {
+ assertPositionInRootIsEqualTo(30.dp, 60.dp)
+ assertSizeIsEqualTo(15.dp, 60.dp)
+ }
+ }
+ at(48) {
+ onSharedElement(TestElements.Foo).onEach {
+ assertPositionInRootIsEqualTo(40.dp, 65.dp)
+ assertSizeIsEqualTo(12.5.dp, 50.dp)
+ }
+ }
+ after {
+ onElement(TestElements.Foo).assertPositionInRootIsEqualTo(50.dp, 70.dp)
+ onElement(TestElements.Foo).assertSizeIsEqualTo(10.dp, 40.dp)
+ }
+ }
+ }
+
+ @Test
+ fun testSharedElementDisabled() {
+ rule.testTransition(
+ fromScene = TestScenes.SceneA,
+ toScene = TestScenes.SceneB,
+ // The full layout is 100x100.
+ layoutModifier = Modifier.size(100.dp),
+ fromSceneContent = {
+ Box(Modifier.fillMaxSize()) {
+ // Foo is at (10, 50).
+ Box(Modifier.offset(10.dp, 50.dp).element(TestElements.Foo))
+ }
+ },
+ toSceneContent = {
+ Box(Modifier.fillMaxSize()) {
+ // Foo is at (50, 60).
+ Box(Modifier.offset(50.dp, 60.dp).element(TestElements.Foo))
+ }
+ },
+ transition = {
+ spec = tween(16 * 4, easing = LinearEasing)
+
+ // Disable the shared element animation.
+ sharedElement(TestElements.Foo, enabled = false)
+
+ // In SceneA, Foo leaves to the left edge.
+ translate(TestElements.Foo.inScene(TestScenes.SceneA), Edge.Left)
+
+ // In SceneB, Foo comes from the bottom edge.
+ translate(TestElements.Foo.inScene(TestScenes.SceneB), Edge.Bottom)
+ },
+ ) {
+ before { onElement(TestElements.Foo).assertPositionInRootIsEqualTo(10.dp, 50.dp) }
+ at(0) {
+ onElement(TestElements.Foo, scene = TestScenes.SceneA)
+ .assertPositionInRootIsEqualTo(10.dp, 50.dp)
+ onElement(TestElements.Foo, scene = TestScenes.SceneB)
+ .assertPositionInRootIsEqualTo(50.dp, 100.dp)
+ }
+ at(16) {
+ onElement(TestElements.Foo, scene = TestScenes.SceneA)
+ .assertPositionInRootIsEqualTo(7.5.dp, 50.dp)
+ onElement(TestElements.Foo, scene = TestScenes.SceneB)
+ .assertPositionInRootIsEqualTo(50.dp, 90.dp)
+ }
+ at(32) {
+ onElement(TestElements.Foo, scene = TestScenes.SceneA)
+ .assertPositionInRootIsEqualTo(5.dp, 50.dp)
+ onElement(TestElements.Foo, scene = TestScenes.SceneB)
+ .assertPositionInRootIsEqualTo(50.dp, 80.dp)
+ }
+ at(48) {
+ onElement(TestElements.Foo, scene = TestScenes.SceneA)
+ .assertPositionInRootIsEqualTo(2.5.dp, 50.dp)
+ onElement(TestElements.Foo, scene = TestScenes.SceneB)
+ .assertPositionInRootIsEqualTo(50.dp, 70.dp)
+ }
+ after { onElement(TestElements.Foo).assertPositionInRootIsEqualTo(50.dp, 60.dp) }
+ }
+ }
+}
diff --git a/packages/SystemUI/compose/core/tests/src/com/android/compose/test/Selectors.kt b/packages/SystemUI/compose/core/tests/src/com/android/compose/test/Selectors.kt
new file mode 100644
index 0000000..d6f64bf
--- /dev/null
+++ b/packages/SystemUI/compose/core/tests/src/com/android/compose/test/Selectors.kt
@@ -0,0 +1,27 @@
+/*
+ * 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.compose.test
+
+import androidx.compose.ui.test.SemanticsNodeInteraction
+import androidx.compose.ui.test.SemanticsNodeInteractionCollection
+
+/** Assert [assert] on each element of [this] [SemanticsNodeInteractionCollection]. */
+fun SemanticsNodeInteractionCollection.onEach(assert: SemanticsNodeInteraction.() -> Unit) {
+ for (i in 0 until this.fetchSemanticsNodes().size) {
+ get(i).assert()
+ }
+}
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockRegistry.kt b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockRegistry.kt
index c41dc53..cb76ad7 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockRegistry.kt
+++ b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockRegistry.kt
@@ -507,9 +507,10 @@
}
}
- private var isVerifying = AtomicBoolean(false)
+ private var isQueued = AtomicBoolean(false)
fun verifyLoadedProviders() {
- val shouldSchedule = isVerifying.compareAndSet(false, true)
+ Log.i(TAG, Thread.currentThread().getStackTrace().toString())
+ val shouldSchedule = isQueued.compareAndSet(false, true)
if (!shouldSchedule) {
logger.tryLog(
TAG,
@@ -521,48 +522,54 @@
}
scope.launch(bgDispatcher) {
- if (keepAllLoaded) {
+ // TODO(b/267372164): Use better threading approach when converting to flows
+ synchronized(availableClocks) {
+ isQueued.set(false)
+ if (keepAllLoaded) {
+ logger.tryLog(
+ TAG,
+ LogLevel.INFO,
+ {},
+ { "verifyLoadedProviders: keepAllLoaded=true" }
+ )
+ // Enforce that all plugins are loaded if requested
+ for ((_, info) in availableClocks) {
+ info.manager?.loadPlugin()
+ }
+ return@launch
+ }
+
+ val currentClock = availableClocks[currentClockId]
+ if (currentClock == null) {
+ logger.tryLog(
+ TAG,
+ LogLevel.INFO,
+ {},
+ { "verifyLoadedProviders: currentClock=null" }
+ )
+ // Current Clock missing, load no plugins and use default
+ for ((_, info) in availableClocks) {
+ info.manager?.unloadPlugin()
+ }
+ return@launch
+ }
+
logger.tryLog(
TAG,
LogLevel.INFO,
{},
- { "verifyLoadedProviders: keepAllLoaded=true" }
+ { "verifyLoadedProviders: load currentClock" }
)
- // Enforce that all plugins are loaded if requested
+ val currentManager = currentClock.manager
+ currentManager?.loadPlugin()
+
for ((_, info) in availableClocks) {
- info.manager?.loadPlugin()
- }
- isVerifying.set(false)
- return@launch
- }
-
- val currentClock = availableClocks[currentClockId]
- if (currentClock == null) {
- logger.tryLog(
- TAG,
- LogLevel.INFO,
- {},
- { "verifyLoadedProviders: currentClock=null" }
- )
- // Current Clock missing, load no plugins and use default
- for ((_, info) in availableClocks) {
- info.manager?.unloadPlugin()
- }
- isVerifying.set(false)
- return@launch
- }
-
- logger.tryLog(TAG, LogLevel.INFO, {}, { "verifyLoadedProviders: load currentClock" })
- val currentManager = currentClock.manager
- currentManager?.loadPlugin()
-
- for ((_, info) in availableClocks) {
- val manager = info.manager
- if (manager != null && currentManager != manager) {
- manager.unloadPlugin()
+ val manager = info.manager
+ if (manager != null && currentManager != manager) {
+ manager.unloadPlugin()
+ }
}
}
- isVerifying.set(false)
}
}
diff --git a/packages/SystemUI/res/values/ids.xml b/packages/SystemUI/res/values/ids.xml
index 21696fe..6cdd15e 100644
--- a/packages/SystemUI/res/values/ids.xml
+++ b/packages/SystemUI/res/values/ids.xml
@@ -233,6 +233,11 @@
<item type="id" name="pin_pad"/>
<!--
+ Tag used to store pending intent registration listeners in NotificationTemplateViewWrapper
+ -->
+ <item type="id" name="pending_intent_listener_tag" />
+
+ <!--
Used to tag views programmatically added to the smartspace area so they can be more easily
removed later.
-->
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java
index ba8e427..f6a0563 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java
@@ -184,6 +184,10 @@
}
}
+ public boolean getSplitShadeCentered() {
+ return mSplitShadeCentered;
+ }
+
@Override
protected void onFinishInflate() {
super.onFinishInflate();
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java
index 29414ea..5646abe 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java
@@ -234,6 +234,10 @@
}
}
+ public KeyguardClockSwitch getView() {
+ return mView;
+ }
+
private void hideSliceViewAndNotificationIconContainer() {
View ksv = mView.findViewById(R.id.keyguard_slice_view);
ksv.setVisibility(View.GONE);
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
index d848602..f9cc03ee 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
@@ -18,6 +18,7 @@
import static java.util.Collections.emptySet;
+import android.animation.LayoutTransition;
import android.content.Context;
import android.graphics.Canvas;
import android.os.Build;
@@ -78,6 +79,14 @@
mKeyguardSlice = findViewById(R.id.keyguard_slice_view);
mMediaHostContainer = findViewById(R.id.status_view_media_container);
+ if (mMediaHostContainer != null) {
+ LayoutTransition mediaLayoutTransition = new LayoutTransition();
+ ((ViewGroup) mMediaHostContainer).setLayoutTransition(mediaLayoutTransition);
+ mediaLayoutTransition.disableTransitionType(LayoutTransition.CHANGE_APPEARING);
+ mediaLayoutTransition.disableTransitionType(LayoutTransition.CHANGE_DISAPPEARING);
+ mediaLayoutTransition.disableTransitionType(LayoutTransition.APPEARING);
+ mediaLayoutTransition.disableTransitionType(LayoutTransition.DISAPPEARING);
+ }
updateDark();
}
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java
index 8d0d299..931ba6d 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java
@@ -23,6 +23,7 @@
import static com.android.systemui.util.kotlin.JavaAdapterKt.collectFlow;
import android.animation.Animator;
+import android.animation.LayoutTransition;
import android.animation.ValueAnimator;
import android.annotation.Nullable;
import android.content.res.Configuration;
@@ -101,6 +102,7 @@
private final Rect mClipBounds = new Rect();
private final KeyguardInteractor mKeyguardInteractor;
+ private Boolean mSplitShadeEnabled = false;
private Boolean mStatusViewCentered = true;
private DumpManager mDumpManager;
@@ -150,6 +152,48 @@
@Override
public void onInit() {
mKeyguardClockSwitchController.init();
+ final View mediaHostContainer = mView.findViewById(R.id.status_view_media_container);
+ if (mediaHostContainer != null) {
+ mKeyguardClockSwitchController.getView().addOnLayoutChangeListener(
+ (v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) -> {
+ if (!mSplitShadeEnabled
+ || mKeyguardClockSwitchController.getView().getSplitShadeCentered()
+ // Note: isKeyguardVisible() returns false after Launcher -> AOD.
+ || !mKeyguardUpdateMonitor.isKeyguardVisible()) {
+ return;
+ }
+
+ int oldHeight = oldBottom - oldTop;
+ if (v.getHeight() == oldHeight) return;
+
+ if (mediaHostContainer.getVisibility() != View.VISIBLE
+ // If the media is appearing, also don't do the transition.
+ || mediaHostContainer.getHeight() == 0) {
+ return;
+ }
+
+ final LayoutTransition mediaLayoutTransition =
+ ((ViewGroup) mediaHostContainer).getLayoutTransition();
+ if (mediaLayoutTransition == null) return;
+
+ mediaLayoutTransition.enableTransitionType(LayoutTransition.CHANGING);
+ });
+
+ mediaHostContainer.addOnLayoutChangeListener(
+ (v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) -> {
+ final LayoutTransition mediaLayoutTransition =
+ ((ViewGroup) mediaHostContainer).getLayoutTransition();
+ if (mediaLayoutTransition == null) return;
+ if (!mediaLayoutTransition.isTransitionTypeEnabled(
+ LayoutTransition.CHANGING)) {
+ return;
+ }
+ // Note: when this is called, the LayoutTransition is already been set up.
+ // Disables the LayoutTransition until it's explicitly enabled again.
+ mediaLayoutTransition.disableTransitionType(LayoutTransition.CHANGING);
+ }
+ );
+ }
mDumpManager.registerDumpable(getInstanceName(), this);
if (mFeatureFlags.isEnabled(Flags.MIGRATE_KEYGUARD_STATUS_VIEW)) {
@@ -385,6 +429,7 @@
*/
public void setSplitShadeEnabled(boolean enabled) {
mKeyguardClockSwitchController.setSplitShadeEnabled(enabled);
+ mSplitShadeEnabled = enabled;
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaProjectionCaptureTarget.kt b/packages/SystemUI/src/com/android/systemui/mediaprojection/MediaProjectionCaptureTarget.kt
similarity index 80%
rename from packages/SystemUI/src/com/android/systemui/media/MediaProjectionCaptureTarget.kt
rename to packages/SystemUI/src/com/android/systemui/mediaprojection/MediaProjectionCaptureTarget.kt
index fbf9294..11d0be5 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaProjectionCaptureTarget.kt
+++ b/packages/SystemUI/src/com/android/systemui/mediaprojection/MediaProjectionCaptureTarget.kt
@@ -14,20 +14,17 @@
* limitations under the License.
*/
-package com.android.systemui.media
+package com.android.systemui.mediaprojection
import android.os.IBinder
import android.os.Parcel
import android.os.Parcelable
/**
- * Class that represents an area that should be captured.
- * Currently it has only a launch cookie that represents a task but
- * we potentially could add more identifiers e.g. for a pair of tasks.
+ * Class that represents an area that should be captured. Currently it has only a launch cookie that
+ * represents a task but we potentially could add more identifiers e.g. for a pair of tasks.
*/
-data class MediaProjectionCaptureTarget(
- val launchCookie: IBinder?
-): Parcelable {
+data class MediaProjectionCaptureTarget(val launchCookie: IBinder?) : Parcelable {
constructor(parcel: Parcel) : this(parcel.readStrongBinder())
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaProjectionServiceHelper.kt b/packages/SystemUI/src/com/android/systemui/mediaprojection/MediaProjectionServiceHelper.kt
similarity index 98%
rename from packages/SystemUI/src/com/android/systemui/media/MediaProjectionServiceHelper.kt
rename to packages/SystemUI/src/com/android/systemui/mediaprojection/MediaProjectionServiceHelper.kt
index 9e616e2..f1cade7 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaProjectionServiceHelper.kt
+++ b/packages/SystemUI/src/com/android/systemui/mediaprojection/MediaProjectionServiceHelper.kt
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.media
+package com.android.systemui.mediaprojection
import android.content.Context
import android.media.projection.IMediaProjection
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaProjectionAppSelectorActivity.kt b/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/MediaProjectionAppSelectorActivity.kt
similarity index 97%
rename from packages/SystemUI/src/com/android/systemui/media/MediaProjectionAppSelectorActivity.kt
rename to packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/MediaProjectionAppSelectorActivity.kt
index 88bc064..b5d3e91 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaProjectionAppSelectorActivity.kt
+++ b/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/MediaProjectionAppSelectorActivity.kt
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.android.systemui.media
+package com.android.systemui.mediaprojection.appselector
import android.app.ActivityOptions
import android.content.Intent
@@ -46,13 +46,11 @@
import com.android.internal.widget.RecyclerView
import com.android.internal.widget.RecyclerViewAccessibilityDelegate
import com.android.internal.widget.ResolverDrawerLayout
-import com.android.systemui.res.R
-import com.android.systemui.mediaprojection.appselector.MediaProjectionAppSelectorComponent
-import com.android.systemui.mediaprojection.appselector.MediaProjectionAppSelectorController
-import com.android.systemui.mediaprojection.appselector.MediaProjectionAppSelectorResultHandler
-import com.android.systemui.mediaprojection.appselector.MediaProjectionAppSelectorView
+import com.android.systemui.mediaprojection.MediaProjectionCaptureTarget
+import com.android.systemui.mediaprojection.MediaProjectionServiceHelper
import com.android.systemui.mediaprojection.appselector.data.RecentTask
import com.android.systemui.mediaprojection.appselector.view.MediaProjectionRecentsViewController
+import com.android.systemui.res.R
import com.android.systemui.statusbar.policy.ConfigurationController
import com.android.systemui.util.AsyncActivityLauncher
import javax.inject.Inject
diff --git a/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/MediaProjectionAppSelectorComponent.kt b/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/MediaProjectionAppSelectorComponent.kt
index 33d9cc3..72aea04 100644
--- a/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/MediaProjectionAppSelectorComponent.kt
+++ b/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/MediaProjectionAppSelectorComponent.kt
@@ -23,8 +23,6 @@
import androidx.lifecycle.DefaultLifecycleObserver
import com.android.launcher3.icons.IconFactory
import com.android.systemui.dagger.qualifiers.Application
-import com.android.systemui.media.MediaProjectionAppSelectorActivity
-import com.android.systemui.media.MediaProjectionPermissionActivity
import com.android.systemui.mediaprojection.appselector.data.ActivityTaskManagerLabelLoader
import com.android.systemui.mediaprojection.appselector.data.ActivityTaskManagerThumbnailLoader
import com.android.systemui.mediaprojection.appselector.data.AppIconLoader
@@ -37,6 +35,7 @@
import com.android.systemui.mediaprojection.appselector.view.TaskPreviewSizeProvider
import com.android.systemui.mediaprojection.devicepolicy.MediaProjectionDevicePolicyModule
import com.android.systemui.mediaprojection.devicepolicy.PersonalProfile
+import com.android.systemui.mediaprojection.permission.MediaProjectionPermissionActivity
import com.android.systemui.statusbar.phone.ConfigurationControllerImpl
import com.android.systemui.statusbar.policy.ConfigurationController
import dagger.Binds
diff --git a/packages/SystemUI/src/com/android/systemui/screenrecord/BaseScreenSharePermissionDialog.kt b/packages/SystemUI/src/com/android/systemui/mediaprojection/permission/BaseScreenSharePermissionDialog.kt
similarity index 98%
rename from packages/SystemUI/src/com/android/systemui/screenrecord/BaseScreenSharePermissionDialog.kt
rename to packages/SystemUI/src/com/android/systemui/mediaprojection/permission/BaseScreenSharePermissionDialog.kt
index 64006fe..8b437c3 100644
--- a/packages/SystemUI/src/com/android/systemui/screenrecord/BaseScreenSharePermissionDialog.kt
+++ b/packages/SystemUI/src/com/android/systemui/mediaprojection/permission/BaseScreenSharePermissionDialog.kt
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.android.systemui.screenrecord
+package com.android.systemui.mediaprojection.permission
import android.content.Context
import android.os.Bundle
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaProjectionPermissionActivity.java b/packages/SystemUI/src/com/android/systemui/mediaprojection/permission/MediaProjectionPermissionActivity.java
similarity index 97%
rename from packages/SystemUI/src/com/android/systemui/media/MediaProjectionPermissionActivity.java
rename to packages/SystemUI/src/com/android/systemui/mediaprojection/permission/MediaProjectionPermissionActivity.java
index 4de6278..2b56d0c 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaProjectionPermissionActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/mediaprojection/permission/MediaProjectionPermissionActivity.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.media;
+package com.android.systemui.mediaprojection.permission;
import static android.media.projection.IMediaProjectionManager.EXTRA_PACKAGE_REUSING_GRANTED_CONSENT;
import static android.media.projection.IMediaProjectionManager.EXTRA_USER_REVIEW_GRANTED_CONSENT;
@@ -22,8 +22,8 @@
import static android.media.projection.ReviewGrantedConsentResult.RECORD_CONTENT_DISPLAY;
import static android.view.WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS;
-import static com.android.systemui.screenrecord.ScreenShareOptionKt.ENTIRE_SCREEN;
-import static com.android.systemui.screenrecord.ScreenShareOptionKt.SINGLE_APP;
+import static com.android.systemui.mediaprojection.permission.ScreenShareOptionKt.ENTIRE_SCREEN;
+import static com.android.systemui.mediaprojection.permission.ScreenShareOptionKt.SINGLE_APP;
import android.annotation.Nullable;
import android.app.Activity;
@@ -51,13 +51,13 @@
import android.util.Log;
import android.view.Window;
-import com.android.systemui.res.R;
import com.android.systemui.flags.FeatureFlags;
import com.android.systemui.flags.Flags;
+import com.android.systemui.mediaprojection.MediaProjectionServiceHelper;
+import com.android.systemui.mediaprojection.appselector.MediaProjectionAppSelectorActivity;
import com.android.systemui.mediaprojection.devicepolicy.ScreenCaptureDevicePolicyResolver;
import com.android.systemui.mediaprojection.devicepolicy.ScreenCaptureDisabledDialog;
-import com.android.systemui.screenrecord.MediaProjectionPermissionDialog;
-import com.android.systemui.screenrecord.ScreenShareOption;
+import com.android.systemui.res.R;
import com.android.systemui.statusbar.phone.SystemUIDialog;
import com.android.systemui.util.Utils;
diff --git a/packages/SystemUI/src/com/android/systemui/screenrecord/MediaProjectionPermissionDialog.kt b/packages/SystemUI/src/com/android/systemui/mediaprojection/permission/MediaProjectionPermissionDialog.kt
similarity index 98%
rename from packages/SystemUI/src/com/android/systemui/screenrecord/MediaProjectionPermissionDialog.kt
rename to packages/SystemUI/src/com/android/systemui/mediaprojection/permission/MediaProjectionPermissionDialog.kt
index 47e28d8..2f10ad3 100644
--- a/packages/SystemUI/src/com/android/systemui/screenrecord/MediaProjectionPermissionDialog.kt
+++ b/packages/SystemUI/src/com/android/systemui/mediaprojection/permission/MediaProjectionPermissionDialog.kt
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.android.systemui.screenrecord
+package com.android.systemui.mediaprojection.permission
import android.content.Context
import android.media.projection.MediaProjectionConfig
diff --git a/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenShareOption.kt b/packages/SystemUI/src/com/android/systemui/mediaprojection/permission/ScreenShareOption.kt
similarity index 94%
rename from packages/SystemUI/src/com/android/systemui/screenrecord/ScreenShareOption.kt
rename to packages/SystemUI/src/com/android/systemui/mediaprojection/permission/ScreenShareOption.kt
index ebf0dd2..37e8d9f 100644
--- a/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenShareOption.kt
+++ b/packages/SystemUI/src/com/android/systemui/mediaprojection/permission/ScreenShareOption.kt
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.android.systemui.screenrecord
+package com.android.systemui.mediaprojection.permission
import androidx.annotation.IntDef
import androidx.annotation.StringRes
diff --git a/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingService.java b/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingService.java
index 7cdb655..3501b6b 100644
--- a/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingService.java
+++ b/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingService.java
@@ -41,10 +41,10 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.logging.UiEventLogger;
-import com.android.systemui.res.R;
import com.android.systemui.dagger.qualifiers.LongRunning;
import com.android.systemui.dagger.qualifiers.Main;
-import com.android.systemui.media.MediaProjectionCaptureTarget;
+import com.android.systemui.mediaprojection.MediaProjectionCaptureTarget;
+import com.android.systemui.res.R;
import com.android.systemui.screenrecord.ScreenMediaRecorder.ScreenMediaRecorderListener;
import com.android.systemui.settings.UserContextProvider;
import com.android.systemui.statusbar.phone.KeyguardDismissUtil;
diff --git a/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenMediaRecorder.java b/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenMediaRecorder.java
index b80a01212..3aab3bf 100644
--- a/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenMediaRecorder.java
+++ b/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenMediaRecorder.java
@@ -51,7 +51,7 @@
import android.view.Surface;
import android.view.WindowManager;
-import com.android.systemui.media.MediaProjectionCaptureTarget;
+import com.android.systemui.mediaprojection.MediaProjectionCaptureTarget;
import java.io.Closeable;
import java.io.File;
diff --git a/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordDialog.java b/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordDialog.java
index f0ce8a4..f2e94e9 100644
--- a/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordDialog.java
@@ -18,7 +18,7 @@
import static android.app.Activity.RESULT_OK;
-import static com.android.systemui.media.MediaProjectionAppSelectorActivity.KEY_CAPTURE_TARGET;
+import static com.android.systemui.mediaprojection.appselector.MediaProjectionAppSelectorActivity.KEY_CAPTURE_TARGET;
import static com.android.systemui.screenrecord.ScreenRecordingAudioSource.INTERNAL;
import static com.android.systemui.screenrecord.ScreenRecordingAudioSource.MIC;
import static com.android.systemui.screenrecord.ScreenRecordingAudioSource.MIC_AND_INTERNAL;
@@ -41,8 +41,8 @@
import androidx.annotation.Nullable;
+import com.android.systemui.mediaprojection.MediaProjectionCaptureTarget;
import com.android.systemui.res.R;
-import com.android.systemui.media.MediaProjectionCaptureTarget;
import com.android.systemui.settings.UserContextProvider;
import com.android.systemui.statusbar.phone.SystemUIDialog;
diff --git a/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordPermissionDialog.kt b/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordPermissionDialog.kt
index b5b7043..a1d5d98 100644
--- a/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordPermissionDialog.kt
+++ b/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordPermissionDialog.kt
@@ -32,10 +32,14 @@
import android.widget.Spinner
import android.widget.Switch
import androidx.annotation.LayoutRes
-import com.android.systemui.res.R
-import com.android.systemui.media.MediaProjectionAppSelectorActivity
-import com.android.systemui.media.MediaProjectionCaptureTarget
+import com.android.systemui.mediaprojection.MediaProjectionCaptureTarget
+import com.android.systemui.mediaprojection.appselector.MediaProjectionAppSelectorActivity
+import com.android.systemui.mediaprojection.permission.BaseScreenSharePermissionDialog
+import com.android.systemui.mediaprojection.permission.ENTIRE_SCREEN
+import com.android.systemui.mediaprojection.permission.SINGLE_APP
+import com.android.systemui.mediaprojection.permission.ScreenShareOption
import com.android.systemui.plugins.ActivityStarter
+import com.android.systemui.res.R
import com.android.systemui.settings.UserContextProvider
/** Dialog to select screen recording options */
@@ -58,6 +62,7 @@
private lateinit var tapsView: View
private lateinit var audioSwitch: Switch
private lateinit var options: Spinner
+
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setDialogTitle(R.string.screenrecord_permission_dialog_title)
@@ -177,6 +182,7 @@
)
private const val DELAY_MS: Long = 3000
private const val INTERVAL_MS: Long = 1000
+
private fun createOptionList(): List<ScreenShareOption> {
return listOf(
ScreenShareOption(
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
index 8baab25..f616b91 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
@@ -244,12 +244,16 @@
}
final float scaledImageWidth = drawableWidth * scaleToFitIconView;
final float scaledImageHeight = drawableHeight * scaleToFitIconView;
- // if the scaled image size <= mOriginalStatusBarIconSize, we don't need to enlarge it
scaleToOriginalDrawingSize = Math.min(
(float) mOriginalStatusBarIconSize / scaledImageWidth,
(float) mOriginalStatusBarIconSize / scaledImageHeight);
if (scaleToOriginalDrawingSize > 1.0f) {
- scaleToOriginalDrawingSize = 1.0f;
+ // per b/296026932, if the scaled image size <= mOriginalStatusBarIconSize, we need
+ // to scale up the scaled image to fit in mOriginalStatusBarIconSize. But if both
+ // the raw drawable intrinsic width/height are less than mOriginalStatusBarIconSize,
+ // then we just scale up the scaled image back to the raw drawable size.
+ scaleToOriginalDrawingSize = Math.min(
+ scaleToOriginalDrawingSize, 1f / scaleToFitIconView);
}
}
iconScale = scaleToOriginalDrawingSize;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/CallLayoutSetDataAsyncFactory.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/CallLayoutSetDataAsyncFactory.kt
new file mode 100644
index 0000000..4deebdb
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/CallLayoutSetDataAsyncFactory.kt
@@ -0,0 +1,37 @@
+/*
+ * 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.row
+
+import android.content.Context
+import android.util.AttributeSet
+import android.view.View
+import com.android.internal.widget.CallLayout
+import javax.inject.Inject
+
+class CallLayoutSetDataAsyncFactory @Inject constructor() : NotifRemoteViewsFactory {
+ override fun instantiate(
+ row: ExpandableNotificationRow,
+ @NotificationRowContentBinder.InflationFlag layoutType: Int,
+ parent: View?,
+ name: String,
+ context: Context,
+ attrs: AttributeSet
+ ): View? =
+ if (name == CallLayout::class.java.name)
+ CallLayout(context, attrs).apply { setSetDataAsyncEnabled(true) }
+ else null
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowModule.java
index 0239afc..3a59978 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowModule.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowModule.java
@@ -61,7 +61,8 @@
static Set<NotifRemoteViewsFactory> provideNotifRemoteViewsFactories(
FeatureFlags featureFlags,
PrecomputedTextViewFactory precomputedTextViewFactory,
- BigPictureLayoutInflaterFactory bigPictureLayoutInflaterFactory
+ BigPictureLayoutInflaterFactory bigPictureLayoutInflaterFactory,
+ CallLayoutSetDataAsyncFactory callLayoutSetDataAsyncFactory
) {
final Set<NotifRemoteViewsFactory> replacementFactories = new HashSet<>();
if (featureFlags.isEnabled(Flags.PRECOMPUTED_TEXT)) {
@@ -70,6 +71,9 @@
if (featureFlags.isEnabled(Flags.BIGPICTURE_NOTIFICATION_LAZY_LOADING)) {
replacementFactories.add(bigPictureLayoutInflaterFactory);
}
+ if (featureFlags.isEnabled(Flags.CALL_LAYOUT_ASYNC_SET_DATA)) {
+ replacementFactories.add(callLayoutSetDataAsyncFactory);
+ }
return replacementFactories;
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationTemplateViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationTemplateViewWrapper.java
index 875a409..91b12cc 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationTemplateViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationTemplateViewWrapper.java
@@ -20,6 +20,9 @@
import static com.android.systemui.statusbar.notification.row.ExpandableNotificationRow.DEFAULT_HEADER_VISIBLE_AMOUNT;
+import android.annotation.MainThread;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.app.Notification;
import android.app.PendingIntent;
import android.content.Context;
@@ -34,8 +37,7 @@
import android.widget.ProgressBar;
import android.widget.TextView;
-import androidx.annotation.Nullable;
-
+import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.ContrastColorUtil;
import com.android.internal.widget.NotificationActionListLayout;
import com.android.systemui.Dependency;
@@ -49,6 +51,8 @@
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import com.android.systemui.statusbar.notification.row.HybridNotificationView;
+import java.util.function.Consumer;
+
/**
* Wraps a notification view inflated from a template.
*/
@@ -66,9 +70,13 @@
private int mContentHeight;
private int mMinHeightHint;
+ @Nullable
private NotificationActionListLayout mActions;
- private ArraySet<PendingIntent> mCancelledPendingIntents = new ArraySet<>();
- private UiOffloadThread mUiOffloadThread;
+ // Holds list of pending intents that have been cancelled by now - we only keep hash codes
+ // to avoid holding full binder proxies for intents that may have been removed by now.
+ @NonNull
+ @VisibleForTesting
+ final ArraySet<Integer> mCancelledPendingIntents = new ArraySet<>();
private View mRemoteInputHistory;
private boolean mCanHideHeader;
private float mHeaderTranslation;
@@ -147,6 +155,7 @@
com.android.internal.R.dimen.notification_content_margin_top);
}
+ @MainThread
private void resolveTemplateViews(StatusBarNotification sbn) {
mRightIcon = mView.findViewById(com.android.internal.R.id.right_icon);
if (mRightIcon != null) {
@@ -195,34 +204,57 @@
return getLargeIcon(n);
}
+ @MainThread
private void updatePendingIntentCancellations() {
if (mActions != null) {
int numActions = mActions.getChildCount();
+ final ArraySet<Integer> currentlyActivePendingIntents = new ArraySet<>(numActions);
for (int i = 0; i < numActions; i++) {
Button action = (Button) mActions.getChildAt(i);
- performOnPendingIntentCancellation(action, () -> {
- if (action.isEnabled()) {
- action.setEnabled(false);
- // The visual appearance doesn't look disabled enough yet, let's add the
- // alpha as well. Since Alpha doesn't play nicely right now with the
- // transformation, we rather blend it manually with the background color.
- ColorStateList textColors = action.getTextColors();
- int[] colors = textColors.getColors();
- int[] newColors = new int[colors.length];
- float disabledAlpha = mView.getResources().getFloat(
- com.android.internal.R.dimen.notification_action_disabled_alpha);
- for (int j = 0; j < colors.length; j++) {
- int color = colors[j];
- color = blendColorWithBackground(color, disabledAlpha);
- newColors[j] = color;
- }
- ColorStateList newColorStateList = new ColorStateList(
- textColors.getStates(), newColors);
- action.setTextColor(newColorStateList);
+ PendingIntent pendingIntent = getPendingIntentForAction(action);
+ // Check if passed intent has already been cancelled in this class and immediately
+ // disable the action to avoid temporary race with enable/disable.
+ if (pendingIntent != null) {
+ int pendingIntentHashCode = getHashCodeForPendingIntent(pendingIntent);
+ currentlyActivePendingIntents.add(pendingIntentHashCode);
+ if (mCancelledPendingIntents.contains(pendingIntentHashCode)) {
+ disableActionView(action);
}
- });
+ }
+ updatePendingIntentCancellationListener(action, pendingIntent);
+ }
+
+ // This cleanup ensures that the size of this set doesn't grow into unreasonable sizes.
+ // There are scenarios where applications updated notifications with different
+ // PendingIntents which could cause this Set to grow to 1000+ elements.
+ mCancelledPendingIntents.retainAll(currentlyActivePendingIntents);
+ }
+ }
+
+ @MainThread
+ private void updatePendingIntentCancellationListener(Button action,
+ @Nullable PendingIntent pendingIntent) {
+ ActionPendingIntentCancellationHandler cancellationHandler = null;
+ if (pendingIntent != null) {
+ // Attach listeners to handle intent cancellation to this view.
+ cancellationHandler = new ActionPendingIntentCancellationHandler(pendingIntent, action,
+ this::disableActionViewWithIntent);
+ action.addOnAttachStateChangeListener(cancellationHandler);
+ // Immediately fire the event if the view is already attached to register
+ // pending intent cancellation listener.
+ if (action.isAttachedToWindow()) {
+ cancellationHandler.onViewAttachedToWindow(action);
}
}
+
+ // If the view has an old attached listener, remove it to avoid leaking intents.
+ ActionPendingIntentCancellationHandler previousHandler =
+ (ActionPendingIntentCancellationHandler) action.getTag(
+ R.id.pending_intent_listener_tag);
+ if (previousHandler != null) {
+ previousHandler.remove();
+ }
+ action.setTag(R.id.pending_intent_listener_tag, cancellationHandler);
}
private int blendColorWithBackground(int color, float alpha) {
@@ -231,42 +263,6 @@
Color.red(color), Color.green(color), Color.blue(color)), resolveBackgroundColor());
}
- private void performOnPendingIntentCancellation(View view, Runnable cancellationRunnable) {
- PendingIntent pendingIntent = (PendingIntent) view.getTag(
- com.android.internal.R.id.pending_intent_tag);
- if (pendingIntent == null) {
- return;
- }
- if (mCancelledPendingIntents.contains(pendingIntent)) {
- cancellationRunnable.run();
- } else {
- PendingIntent.CancelListener listener = (PendingIntent intent) -> {
- mView.post(() -> {
- mCancelledPendingIntents.add(pendingIntent);
- cancellationRunnable.run();
- });
- };
- if (mUiOffloadThread == null) {
- mUiOffloadThread = Dependency.get(UiOffloadThread.class);
- }
- if (view.isAttachedToWindow()) {
- mUiOffloadThread.execute(() -> pendingIntent.registerCancelListener(listener));
- }
- view.addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() {
- @Override
- public void onViewAttachedToWindow(View v) {
- mUiOffloadThread.execute(() -> pendingIntent.registerCancelListener(listener));
- }
-
- @Override
- public void onViewDetachedFromWindow(View v) {
- mUiOffloadThread.execute(
- () -> pendingIntent.unregisterCancelListener(listener));
- }
- });
- }
- }
-
@Override
public void onContentUpdated(ExpandableNotificationRow row) {
// Reinspect the notification. Before the super call, because the super call also updates
@@ -364,4 +360,141 @@
}
return extra + super.getExtraMeasureHeight();
}
+
+ /**
+ * This finds Action view with a given intent and disables it.
+ * With maximum of 3 views, this is sufficiently fast to iterate on main thread every time.
+ */
+ @MainThread
+ private void disableActionViewWithIntent(PendingIntent intent) {
+ mCancelledPendingIntents.add(getHashCodeForPendingIntent(intent));
+ if (mActions != null) {
+ int numActions = mActions.getChildCount();
+ for (int i = 0; i < numActions; i++) {
+ Button action = (Button) mActions.getChildAt(i);
+ PendingIntent pendingIntent = getPendingIntentForAction(action);
+ if (intent.equals(pendingIntent)) {
+ disableActionView(action);
+ }
+ }
+ }
+ }
+
+ /**
+ * Disables Action view when, e.g., its PendingIntent is disabled.
+ */
+ @MainThread
+ private void disableActionView(Button action) {
+ if (action.isEnabled()) {
+ action.setEnabled(false);
+ // The visual appearance doesn't look disabled enough yet, let's add the
+ // alpha as well. Since Alpha doesn't play nicely right now with the
+ // transformation, we rather blend it manually with the background color.
+ ColorStateList textColors = action.getTextColors();
+ int[] colors = textColors.getColors();
+ int[] newColors = new int[colors.length];
+ float disabledAlpha = mView.getResources().getFloat(
+ com.android.internal.R.dimen.notification_action_disabled_alpha);
+ for (int j = 0; j < colors.length; j++) {
+ int color = colors[j];
+ color = blendColorWithBackground(color, disabledAlpha);
+ newColors[j] = color;
+ }
+ ColorStateList newColorStateList = new ColorStateList(
+ textColors.getStates(), newColors);
+ action.setTextColor(newColorStateList);
+ }
+ }
+
+ /**
+ * Returns the hashcode of underlying target of PendingIntent. We can get multiple
+ * Java PendingIntent wrapper objects pointing to the same cancelled PI in system_server.
+ * This makes sure we treat them equally.
+ */
+ private static int getHashCodeForPendingIntent(PendingIntent pendingIntent) {
+ return System.identityHashCode(pendingIntent.getTarget().asBinder());
+ }
+
+ /**
+ * Returns PendingIntent contained in the action tag. May be null.
+ */
+ @Nullable
+ private static PendingIntent getPendingIntentForAction(View action) {
+ return (PendingIntent) action.getTag(com.android.internal.R.id.pending_intent_tag);
+ }
+
+ /**
+ * Registers listeners for pending intent cancellation when Action views are attached
+ * to window.
+ * It calls onCancelPendingIntentForActionView when a PendingIntent is cancelled.
+ */
+ @VisibleForTesting
+ static final class ActionPendingIntentCancellationHandler
+ implements View.OnAttachStateChangeListener {
+
+ @Nullable
+ private static UiOffloadThread sUiOffloadThread = null;
+
+ @NonNull
+ private static UiOffloadThread getUiOffloadThread() {
+ if (sUiOffloadThread == null) {
+ sUiOffloadThread = Dependency.get(UiOffloadThread.class);
+ }
+ return sUiOffloadThread;
+ }
+
+ private final View mView;
+ private final Consumer<PendingIntent> mOnCancelledCallback;
+
+ private final PendingIntent mPendingIntent;
+
+ ActionPendingIntentCancellationHandler(PendingIntent pendingIntent, View actionView,
+ Consumer<PendingIntent> onCancelled) {
+ this.mPendingIntent = pendingIntent;
+ this.mView = actionView;
+ this.mOnCancelledCallback = onCancelled;
+ }
+
+ private final PendingIntent.CancelListener mCancelListener =
+ new PendingIntent.CancelListener() {
+ @Override
+ public void onCanceled(PendingIntent pendingIntent) {
+ mView.post(() -> {
+ mOnCancelledCallback.accept(pendingIntent);
+ // We don't need this listener anymore once the intent was cancelled.
+ remove();
+ });
+ }
+ };
+
+ @MainThread
+ @Override
+ public void onViewAttachedToWindow(View view) {
+ // This is safe to call multiple times with the same listener instance.
+ getUiOffloadThread().execute(() -> {
+ mPendingIntent.registerCancelListener(mCancelListener);
+ });
+ }
+
+ @MainThread
+ @Override
+ public void onViewDetachedFromWindow(View view) {
+ // This is safe to call multiple times with the same listener instance.
+ getUiOffloadThread().execute(() ->
+ mPendingIntent.unregisterCancelListener(mCancelListener));
+ }
+
+ /**
+ * Removes this listener from callbacks and releases the held PendingIntent.
+ */
+ @MainThread
+ public void remove() {
+ mView.removeOnAttachStateChangeListener(this);
+ if (mView.getTag(R.id.pending_intent_listener_tag) == this) {
+ mView.setTag(R.id.pending_intent_listener_tag, null);
+ }
+ getUiOffloadThread().execute(() ->
+ mPendingIntent.unregisterCancelListener(mCancelListener));
+ }
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
index 727d649..3c6d90d 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
@@ -135,6 +135,7 @@
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
import com.android.systemui.util.AlphaTintDrawableWrapper;
import com.android.systemui.util.RoundedCornerProgressDrawable;
+import com.android.systemui.util.settings.SecureSettings;
import java.io.PrintWriter;
import java.util.ArrayList;
@@ -304,6 +305,8 @@
private @DevicePostureController.DevicePostureInt int mDevicePosture;
private int mOrientation;
private final FeatureFlags mFeatureFlags;
+ private final SecureSettings mSecureSettings;
+ private int mDialogTimeoutMillis;
public VolumeDialogImpl(
Context context,
@@ -320,7 +323,8 @@
DevicePostureController devicePostureController,
Looper looper,
DumpManager dumpManager,
- FeatureFlags featureFlags) {
+ FeatureFlags featureFlags,
+ SecureSettings secureSettings) {
mFeatureFlags = featureFlags;
mContext =
new ContextThemeWrapper(context, R.style.volume_dialog_theme);
@@ -351,6 +355,8 @@
mUseBackgroundBlur =
mContext.getResources().getBoolean(R.bool.config_volumeDialogUseBackgroundBlur);
mInteractionJankMonitor = interactionJankMonitor;
+ mSecureSettings = secureSettings;
+ mDialogTimeoutMillis = DIALOG_TIMEOUT_MILLIS;
dumpManager.registerDumpable("VolumeDialogImpl", this);
@@ -515,6 +521,8 @@
mDialog.setContentView(R.layout.volume_dialog);
mDialogView = mDialog.findViewById(R.id.volume_dialog);
mDialogView.setAlpha(0);
+ mDialogTimeoutMillis = mSecureSettings.getInt(Settings.Secure.VOLUME_DIALOG_DISMISS_TIMEOUT,
+ DIALOG_TIMEOUT_MILLIS);
mDialog.setCanceledOnTouchOutside(true);
mDialog.setOnShowListener(dialog -> {
mDialogView.getViewTreeObserver().addOnComputeInternalInsetsListener(this);
@@ -527,7 +535,7 @@
.alpha(1)
.translationX(0)
.setDuration(mDialogShowAnimationDurationMs)
- .setListener(getJankListener(getDialogView(), TYPE_SHOW, DIALOG_TIMEOUT_MILLIS))
+ .setListener(getJankListener(getDialogView(), TYPE_SHOW, mDialogTimeoutMillis))
.setInterpolator(new SystemUIInterpolators.LogDecelerateInterpolator())
.withEndAction(() -> {
if (!Prefs.getBoolean(mContext, Prefs.Key.TOUCHED_RINGER_TOGGLE, false)) {
@@ -1514,7 +1522,7 @@
AccessibilityManager.FLAG_CONTENT_TEXT
| AccessibilityManager.FLAG_CONTENT_CONTROLS);
}
- return mAccessibilityMgr.getRecommendedTimeoutMillis(DIALOG_TIMEOUT_MILLIS,
+ return mAccessibilityMgr.getRecommendedTimeoutMillis(mDialogTimeoutMillis,
AccessibilityManager.FLAG_CONTENT_CONTROLS);
}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/dagger/VolumeModule.java b/packages/SystemUI/src/com/android/systemui/volume/dagger/VolumeModule.java
index cc9f3e1..624691b 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/dagger/VolumeModule.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/dagger/VolumeModule.java
@@ -31,6 +31,7 @@
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.DevicePostureController;
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
+import com.android.systemui.util.settings.SecureSettings;
import com.android.systemui.volume.CsdWarningDialog;
import com.android.systemui.volume.VolumeComponent;
import com.android.systemui.volume.VolumeDialogComponent;
@@ -63,7 +64,8 @@
CsdWarningDialog.Factory csdFactory,
DevicePostureController devicePostureController,
DumpManager dumpManager,
- FeatureFlags featureFlags) {
+ FeatureFlags featureFlags,
+ SecureSettings secureSettings) {
VolumeDialogImpl impl = new VolumeDialogImpl(
context,
volumeDialogController,
@@ -79,7 +81,8 @@
devicePostureController,
Looper.getMainLooper(),
dumpManager,
- featureFlags);
+ featureFlags,
+ secureSettings);
impl.setStreamImportant(AudioManager.STREAM_SYSTEM, false);
impl.setAutomute(true);
impl.setSilentMode(false);
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewControllerBaseTest.java
index ba3dbf0..484b119 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewControllerBaseTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewControllerBaseTest.java
@@ -20,8 +20,10 @@
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import android.animation.LayoutTransition;
import android.view.View;
import android.view.ViewTreeObserver;
+import android.widget.FrameLayout;
import com.android.internal.jank.InteractionJankMonitor;
import com.android.keyguard.logging.KeyguardLogger;
@@ -44,6 +46,7 @@
public class KeyguardStatusViewControllerBaseTest extends SysuiTestCase {
@Mock protected KeyguardStatusView mKeyguardStatusView;
+
@Mock protected KeyguardSliceViewController mKeyguardSliceViewController;
@Mock protected KeyguardClockSwitchController mKeyguardClockSwitchController;
@Mock protected KeyguardStateController mKeyguardStateController;
@@ -61,6 +64,10 @@
protected KeyguardStatusViewController mController;
+ @Mock protected KeyguardClockSwitch mKeyguardClockSwitch;
+ @Mock protected FrameLayout mMediaHostContainer;
+ @Mock protected LayoutTransition mMediaLayoutTransition;
+
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
@@ -93,6 +100,8 @@
};
when(mKeyguardStatusView.getViewTreeObserver()).thenReturn(mViewTreeObserver);
+
+ when(mKeyguardClockSwitchController.getView()).thenReturn(mKeyguardClockSwitch);
}
protected void givenViewAttached() {
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewControllerTest.java
index b8b0198..e4e2b0a 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewControllerTest.java
@@ -18,14 +18,18 @@
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import android.animation.LayoutTransition;
import android.test.suitebuilder.annotation.SmallTest;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
+import android.view.View;
+import com.android.systemui.res.R;
import com.android.systemui.plugins.ClockConfig;
import com.android.systemui.plugins.ClockController;
import com.android.systemui.statusbar.notification.AnimatableProperty;
@@ -124,4 +128,112 @@
mController.onDestroy();
verify(mDumpManager, times(1)).unregisterDumpable(eq(mController.getInstanceName()));
}
+
+ @Test
+ public void onInit_addsOnLayoutChangeListenerToClockSwitch() {
+ when(mKeyguardStatusView.findViewById(R.id.status_view_media_container)).thenReturn(
+ mMediaHostContainer);
+
+ mController.onInit();
+
+ ArgumentCaptor<View.OnLayoutChangeListener> captor =
+ ArgumentCaptor.forClass(View.OnLayoutChangeListener.class);
+ verify(mKeyguardClockSwitch).addOnLayoutChangeListener(captor.capture());
+ }
+
+ @Test
+ public void onInit_addsOnLayoutChangeListenerToMediaHostContainer() {
+ when(mKeyguardStatusView.findViewById(R.id.status_view_media_container)).thenReturn(
+ mMediaHostContainer);
+
+ mController.onInit();
+
+ ArgumentCaptor<View.OnLayoutChangeListener> captor =
+ ArgumentCaptor.forClass(View.OnLayoutChangeListener.class);
+ verify(mMediaHostContainer).addOnLayoutChangeListener(captor.capture());
+ }
+
+ @Test
+ public void clockSwitchHeightChanged_mediaChangingLayoutTransitionEnabled() {
+ when(mKeyguardStatusView.findViewById(R.id.status_view_media_container)).thenReturn(
+ mMediaHostContainer);
+
+ mController.onInit();
+
+ ArgumentCaptor<View.OnLayoutChangeListener> captor =
+ ArgumentCaptor.forClass(View.OnLayoutChangeListener.class);
+ verify(mKeyguardClockSwitch).addOnLayoutChangeListener(captor.capture());
+
+ // Above here is the same as `onInit_addsOnLayoutChangeListenerToClockSwitch`.
+ // Below here is the actual test.
+
+ View.OnLayoutChangeListener listener = captor.getValue();
+
+ mController.setSplitShadeEnabled(true);
+ when(mKeyguardClockSwitch.getSplitShadeCentered()).thenReturn(false);
+ when(mKeyguardUpdateMonitor.isKeyguardVisible()).thenReturn(true);
+ when(mMediaHostContainer.getVisibility()).thenReturn(View.VISIBLE);
+ when(mMediaHostContainer.getHeight()).thenReturn(200);
+ when(mMediaHostContainer.getLayoutTransition()).thenReturn(mMediaLayoutTransition);
+
+ when(mKeyguardClockSwitch.getHeight()).thenReturn(0);
+ listener.onLayoutChange(mKeyguardClockSwitch, /* left= */ 0, /* top= */ 0, /* right= */
+ 0, /* bottom= */ 0, /* oldLeft= */ 0, /* oldTop= */ 0, /* oldRight= */
+ 0, /* oldBottom = */ 200);
+ verify(mMediaLayoutTransition).enableTransitionType(LayoutTransition.CHANGING);
+ }
+
+ @Test
+ public void clockSwitchHeightNotChanged_mediaChangingLayoutTransitionNotEnabled() {
+ when(mKeyguardStatusView.findViewById(R.id.status_view_media_container)).thenReturn(
+ mMediaHostContainer);
+
+ mController.onInit();
+
+ ArgumentCaptor<View.OnLayoutChangeListener> captor =
+ ArgumentCaptor.forClass(View.OnLayoutChangeListener.class);
+ verify(mKeyguardClockSwitch).addOnLayoutChangeListener(captor.capture());
+
+ // Above here is the same as `onInit_addsOnLayoutChangeListenerToClockSwitch`.
+ // Below here is the actual test.
+
+ View.OnLayoutChangeListener listener = captor.getValue();
+
+ mController.setSplitShadeEnabled(true);
+ when(mKeyguardClockSwitch.getSplitShadeCentered()).thenReturn(false);
+ when(mKeyguardUpdateMonitor.isKeyguardVisible()).thenReturn(true);
+ when(mMediaHostContainer.getVisibility()).thenReturn(View.VISIBLE);
+ when(mMediaHostContainer.getHeight()).thenReturn(200);
+ when(mMediaHostContainer.getLayoutTransition()).thenReturn(mMediaLayoutTransition);
+
+ when(mKeyguardClockSwitch.getHeight()).thenReturn(200);
+ listener.onLayoutChange(mKeyguardClockSwitch, /* left= */ 0, /* top= */ 0, /* right= */
+ 0, /* bottom= */ 0, /* oldLeft= */ 0, /* oldTop= */ 0, /* oldRight= */
+ 0, /* oldBottom = */ 200);
+ verify(mMediaLayoutTransition, never()).enableTransitionType(LayoutTransition.CHANGING);
+ }
+
+ @Test
+ public void onMediaHostContainerLayout_disablesChangingLayoutTransition() {
+ when(mKeyguardStatusView.findViewById(R.id.status_view_media_container)).thenReturn(
+ mMediaHostContainer);
+
+ mController.onInit();
+
+ ArgumentCaptor<View.OnLayoutChangeListener> captor =
+ ArgumentCaptor.forClass(View.OnLayoutChangeListener.class);
+ verify(mMediaHostContainer).addOnLayoutChangeListener(captor.capture());
+
+ // Above here is the same as `onInit_addsOnLayoutChangeListenerToMediaHostContainer`.
+ // Below here is the actual test.
+
+ View.OnLayoutChangeListener listener = captor.getValue();
+
+ when(mMediaHostContainer.getLayoutTransition()).thenReturn(mMediaLayoutTransition);
+
+ when(mMediaLayoutTransition.isTransitionTypeEnabled(LayoutTransition.CHANGING)).thenReturn(
+ true);
+ listener.onLayoutChange(mMediaHostContainer, 1, 2, 3, 4, 1, 2, 3, 4);
+ verify(mMediaLayoutTransition).disableTransitionType(LayoutTransition.CHANGING);
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewTest.kt
index 86439e5..58d372c 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewTest.kt
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewTest.kt
@@ -1,5 +1,6 @@
package com.android.keyguard
+import android.animation.LayoutTransition
import android.test.suitebuilder.annotation.SmallTest
import android.testing.AndroidTestingRunner
import android.testing.TestableLooper.RunWithLooper
@@ -35,6 +36,20 @@
}
@Test
+ fun mediaViewHasLayoutTransitionInDisabledState() {
+ val layoutTransition = (mediaView as ViewGroup).layoutTransition
+ assertThat(layoutTransition).isNotNull()
+ assertThat(layoutTransition.isTransitionTypeEnabled(LayoutTransition.CHANGE_APPEARING))
+ .isFalse()
+ assertThat(layoutTransition.isTransitionTypeEnabled(LayoutTransition.CHANGE_DISAPPEARING))
+ .isFalse()
+ assertThat(layoutTransition.isTransitionTypeEnabled(LayoutTransition.APPEARING)).isFalse()
+ assertThat(layoutTransition.isTransitionTypeEnabled(LayoutTransition.DISAPPEARING))
+ .isFalse()
+ assertThat(layoutTransition.isTransitionTypeEnabled(LayoutTransition.CHANGING)).isFalse()
+ }
+
+ @Test
fun setChildrenTranslationYExcludingMediaView_mediaViewIsNotTranslated() {
val translationY = 1234f
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/interactor/RestoreReconciliationInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/interactor/RestoreReconciliationInteractorTest.kt
index 5630b9d..2e6b50b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/interactor/RestoreReconciliationInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/interactor/RestoreReconciliationInteractorTest.kt
@@ -1,6 +1,6 @@
package com.android.systemui.qs.pipeline.domain.interactor
-import android.testing.AndroidTestingRunner
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.RoboPilotTest
import com.android.systemui.SysuiTestCase
@@ -21,7 +21,7 @@
import org.mockito.MockitoAnnotations
@RoboPilotTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
@SmallTest
class RestoreReconciliationInteractorTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenrecord/RecordingServiceTest.java b/packages/SystemUI/tests/src/com/android/systemui/screenrecord/RecordingServiceTest.java
index 59b5953..a2aed98 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/screenrecord/RecordingServiceTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/screenrecord/RecordingServiceTest.java
@@ -41,7 +41,7 @@
import com.android.internal.logging.UiEventLogger;
import com.android.systemui.SysuiTestCase;
-import com.android.systemui.media.MediaProjectionCaptureTarget;
+import com.android.systemui.mediaprojection.MediaProjectionCaptureTarget;
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.settings.UserContextProvider;
import com.android.systemui.statusbar.SysuiStatusBarStateController;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenrecord/ScreenRecordPermissionDialogTest.kt b/packages/SystemUI/tests/src/com/android/systemui/screenrecord/ScreenRecordPermissionDialogTest.kt
index d470d24..3ae1f35 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/screenrecord/ScreenRecordPermissionDialogTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/screenrecord/ScreenRecordPermissionDialogTest.kt
@@ -22,11 +22,13 @@
import android.view.View
import android.widget.Spinner
import androidx.test.filters.SmallTest
-import com.android.systemui.res.R
import com.android.systemui.SysuiTestCase
import com.android.systemui.flags.FeatureFlags
import com.android.systemui.flags.Flags
+import com.android.systemui.mediaprojection.permission.ENTIRE_SCREEN
+import com.android.systemui.mediaprojection.permission.SINGLE_APP
import com.android.systemui.plugins.ActivityStarter
+import com.android.systemui.res.R
import com.android.systemui.settings.UserContextProvider
import com.android.systemui.util.mockito.mock
import com.google.common.truth.Truth.assertThat
@@ -35,8 +37,8 @@
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mock
-import org.mockito.MockitoAnnotations
import org.mockito.Mockito.`when` as whenever
+import org.mockito.MockitoAnnotations
@SmallTest
@RunWith(AndroidTestingRunner::class)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shared/clocks/ClockRegistryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shared/clocks/ClockRegistryTest.kt
index 48665fe..e714736 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shared/clocks/ClockRegistryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shared/clocks/ClockRegistryTest.kt
@@ -15,6 +15,7 @@
*/
package com.android.systemui.shared.clocks
+import android.content.ComponentName
import android.content.ContentResolver
import android.content.Context
import android.graphics.drawable.Drawable
@@ -28,12 +29,11 @@
import com.android.systemui.plugins.ClockMetadata
import com.android.systemui.plugins.ClockProviderPlugin
import com.android.systemui.plugins.ClockSettings
-import com.android.systemui.plugins.PluginListener
import com.android.systemui.plugins.PluginLifecycleManager
+import com.android.systemui.plugins.PluginListener
import com.android.systemui.plugins.PluginManager
import com.android.systemui.util.mockito.argumentCaptor
import com.android.systemui.util.mockito.eq
-import com.android.systemui.util.mockito.mock
import junit.framework.Assert.assertEquals
import junit.framework.Assert.fail
import kotlinx.coroutines.CoroutineDispatcher
@@ -46,6 +46,7 @@
import org.junit.runner.RunWith
import org.mockito.Mock
import org.mockito.Mockito.never
+import org.mockito.Mockito.spy
import org.mockito.Mockito.times
import org.mockito.Mockito.verify
import org.mockito.Mockito.`when` as whenever
@@ -66,7 +67,6 @@
@Mock private lateinit var mockDefaultClock: ClockController
@Mock private lateinit var mockThumbnail: Drawable
@Mock private lateinit var mockContentResolver: ContentResolver
- @Mock private lateinit var mockPluginLifecycle: PluginLifecycleManager<ClockProviderPlugin>
private lateinit var fakeDefaultProvider: FakeClockPlugin
private lateinit var pluginListener: PluginListener<ClockProviderPlugin>
private lateinit var registry: ClockRegistry
@@ -84,6 +84,41 @@
}
}
+ private class FakeLifecycle(
+ private val tag: String,
+ private val plugin: ClockProviderPlugin?,
+ ) : PluginLifecycleManager<ClockProviderPlugin> {
+ var onLoad: (() -> Unit)? = null
+ var onUnload: (() -> Unit)? = null
+
+ private var mIsLoaded: Boolean = true
+ override fun isLoaded() = mIsLoaded
+ override fun getPlugin(): ClockProviderPlugin? = if (isLoaded) plugin else null
+
+ var mComponentName = ComponentName("Package[$tag]", "Class[$tag]")
+ override fun toString() = "Manager[$tag]"
+ override fun getPackage(): String = mComponentName.getPackageName()
+ override fun getComponentName(): ComponentName = mComponentName
+
+ private var isDebug: Boolean = false
+ override fun getIsDebug(): Boolean = isDebug
+ override fun setIsDebug(value: Boolean) { isDebug = value }
+
+ override fun loadPlugin() {
+ if (!mIsLoaded) {
+ mIsLoaded = true
+ onLoad?.invoke()
+ }
+ }
+
+ override fun unloadPlugin() {
+ if (mIsLoaded) {
+ mIsLoaded = false
+ onUnload?.invoke()
+ }
+ }
+ }
+
private class FakeClockPlugin : ClockProviderPlugin {
private val metadata = mutableListOf<ClockMetadata>()
private val createCallbacks = mutableMapOf<ClockId, (ClockId) -> ClockController>()
@@ -150,13 +185,15 @@
val plugin1 = FakeClockPlugin()
.addClock("clock_1", "clock 1")
.addClock("clock_2", "clock 2")
+ val lifecycle1 = FakeLifecycle("1", plugin1)
val plugin2 = FakeClockPlugin()
.addClock("clock_3", "clock 3")
.addClock("clock_4", "clock 4")
+ val lifecycle2 = FakeLifecycle("2", plugin2)
- pluginListener.onPluginLoaded(plugin1, mockContext, mockPluginLifecycle)
- pluginListener.onPluginLoaded(plugin2, mockContext, mockPluginLifecycle)
+ pluginListener.onPluginLoaded(plugin1, mockContext, lifecycle1)
+ pluginListener.onPluginLoaded(plugin2, mockContext, lifecycle2)
val list = registry.getClocks()
assertEquals(
list.toSet(),
@@ -178,18 +215,18 @@
@Test
fun clockIdConflict_ErrorWithoutCrash_unloadDuplicate() {
- val mockPluginLifecycle1 = mock<PluginLifecycleManager<ClockProviderPlugin>>()
val plugin1 = FakeClockPlugin()
.addClock("clock_1", "clock 1", { mockClock }, { mockThumbnail })
.addClock("clock_2", "clock 2", { mockClock }, { mockThumbnail })
+ val lifecycle1 = spy(FakeLifecycle("1", plugin1))
- val mockPluginLifecycle2 = mock<PluginLifecycleManager<ClockProviderPlugin>>()
val plugin2 = FakeClockPlugin()
.addClock("clock_1", "clock 1")
.addClock("clock_2", "clock 2")
+ val lifecycle2 = spy(FakeLifecycle("2", plugin2))
- pluginListener.onPluginLoaded(plugin1, mockContext, mockPluginLifecycle1)
- pluginListener.onPluginLoaded(plugin2, mockContext, mockPluginLifecycle2)
+ pluginListener.onPluginLoaded(plugin1, mockContext, lifecycle1)
+ pluginListener.onPluginLoaded(plugin2, mockContext, lifecycle2)
val list = registry.getClocks()
assertEquals(
list.toSet(),
@@ -204,8 +241,8 @@
assertEquals(registry.createExampleClock("clock_2"), mockClock)
assertEquals(registry.getClockThumbnail("clock_1"), mockThumbnail)
assertEquals(registry.getClockThumbnail("clock_2"), mockThumbnail)
- verify(mockPluginLifecycle1, never()).unloadPlugin()
- verify(mockPluginLifecycle2, times(2)).unloadPlugin()
+ verify(lifecycle1, never()).unloadPlugin()
+ verify(lifecycle2, times(2)).unloadPlugin()
}
@Test
@@ -213,14 +250,16 @@
val plugin1 = FakeClockPlugin()
.addClock("clock_1", "clock 1")
.addClock("clock_2", "clock 2")
+ val lifecycle1 = spy(FakeLifecycle("1", plugin1))
val plugin2 = FakeClockPlugin()
.addClock("clock_3", "clock 3", { mockClock })
.addClock("clock_4", "clock 4")
+ val lifecycle2 = spy(FakeLifecycle("2", plugin2))
registry.applySettings(ClockSettings("clock_3", null))
- pluginListener.onPluginLoaded(plugin1, mockContext, mockPluginLifecycle)
- pluginListener.onPluginLoaded(plugin2, mockContext, mockPluginLifecycle)
+ pluginListener.onPluginLoaded(plugin1, mockContext, lifecycle1)
+ pluginListener.onPluginLoaded(plugin2, mockContext, lifecycle2)
val clock = registry.createCurrentClock()
assertEquals(mockClock, clock)
@@ -231,17 +270,19 @@
val plugin1 = FakeClockPlugin()
.addClock("clock_1", "clock 1")
.addClock("clock_2", "clock 2")
+ val lifecycle1 = spy(FakeLifecycle("1", plugin1))
val plugin2 = FakeClockPlugin()
.addClock("clock_3", "clock 3", { mockClock })
.addClock("clock_4", "clock 4")
+ val lifecycle2 = spy(FakeLifecycle("2", plugin2))
registry.applySettings(ClockSettings("clock_3", null))
- pluginListener.onPluginLoaded(plugin1, mockContext, mockPluginLifecycle)
+ pluginListener.onPluginLoaded(plugin1, mockContext, lifecycle1)
assertEquals(DEFAULT_CLOCK_ID, registry.activeClockId)
- pluginListener.onPluginLoaded(plugin2, mockContext, mockPluginLifecycle)
+ pluginListener.onPluginLoaded(plugin2, mockContext, lifecycle2)
assertEquals("clock_3", registry.activeClockId)
}
@@ -250,15 +291,17 @@
val plugin1 = FakeClockPlugin()
.addClock("clock_1", "clock 1")
.addClock("clock_2", "clock 2")
+ val lifecycle1 = spy(FakeLifecycle("1", plugin1))
val plugin2 = FakeClockPlugin()
.addClock("clock_3", "clock 3")
.addClock("clock_4", "clock 4")
+ val lifecycle2 = spy(FakeLifecycle("2", plugin2))
registry.applySettings(ClockSettings("clock_3", null))
- pluginListener.onPluginLoaded(plugin1, mockContext, mockPluginLifecycle)
- pluginListener.onPluginLoaded(plugin2, mockContext, mockPluginLifecycle)
- pluginListener.onPluginUnloaded(plugin2, mockPluginLifecycle)
+ pluginListener.onPluginLoaded(plugin1, mockContext, lifecycle1)
+ pluginListener.onPluginLoaded(plugin2, mockContext, lifecycle2)
+ pluginListener.onPluginUnloaded(plugin2, lifecycle2)
val clock = registry.createCurrentClock()
assertEquals(clock, mockDefaultClock)
@@ -266,15 +309,15 @@
@Test
fun pluginRemoved_clockAndListChanged() {
- val mockPluginLifecycle1 = mock<PluginLifecycleManager<ClockProviderPlugin>>()
val plugin1 = FakeClockPlugin()
.addClock("clock_1", "clock 1")
.addClock("clock_2", "clock 2")
+ val lifecycle1 = spy(FakeLifecycle("1", plugin1))
- val mockPluginLifecycle2 = mock<PluginLifecycleManager<ClockProviderPlugin>>()
val plugin2 = FakeClockPlugin()
.addClock("clock_3", "clock 3", { mockClock })
.addClock("clock_4", "clock 4")
+ val lifecycle2 = spy(FakeLifecycle("2", plugin2))
var changeCallCount = 0
var listChangeCallCount = 0
@@ -288,32 +331,32 @@
assertEquals(1, changeCallCount)
assertEquals(0, listChangeCallCount)
- pluginListener.onPluginLoaded(plugin1, mockContext, mockPluginLifecycle1)
+ pluginListener.onPluginLoaded(plugin1, mockContext, lifecycle1)
scheduler.runCurrent()
assertEquals(1, changeCallCount)
assertEquals(1, listChangeCallCount)
- pluginListener.onPluginLoaded(plugin2, mockContext, mockPluginLifecycle2)
+ pluginListener.onPluginLoaded(plugin2, mockContext, lifecycle2)
scheduler.runCurrent()
assertEquals(2, changeCallCount)
assertEquals(2, listChangeCallCount)
- pluginListener.onPluginUnloaded(plugin1, mockPluginLifecycle1)
+ pluginListener.onPluginUnloaded(plugin1, lifecycle1)
scheduler.runCurrent()
assertEquals(2, changeCallCount)
assertEquals(2, listChangeCallCount)
- pluginListener.onPluginUnloaded(plugin2, mockPluginLifecycle2)
+ pluginListener.onPluginUnloaded(plugin2, lifecycle2)
scheduler.runCurrent()
assertEquals(3, changeCallCount)
assertEquals(2, listChangeCallCount)
- pluginListener.onPluginDetached(mockPluginLifecycle1)
+ pluginListener.onPluginDetached(lifecycle1)
scheduler.runCurrent()
assertEquals(3, changeCallCount)
assertEquals(3, listChangeCallCount)
- pluginListener.onPluginDetached(mockPluginLifecycle2)
+ pluginListener.onPluginDetached(lifecycle2)
scheduler.runCurrent()
assertEquals(3, changeCallCount)
assertEquals(4, listChangeCallCount)
@@ -321,8 +364,9 @@
@Test
fun unknownPluginAttached_clockAndListUnchanged_loadRequested() {
- val mockPluginLifecycle = mock<PluginLifecycleManager<ClockProviderPlugin>>()
- whenever(mockPluginLifecycle.getPackage()).thenReturn("some.other.package")
+ val lifecycle = FakeLifecycle("", null).apply {
+ mComponentName = ComponentName("some.other.package", "SomeClass")
+ }
var changeCallCount = 0
var listChangeCallCount = 0
@@ -331,7 +375,7 @@
override fun onAvailableClocksChanged() { listChangeCallCount++ }
})
- assertEquals(true, pluginListener.onPluginAttached(mockPluginLifecycle))
+ assertEquals(true, pluginListener.onPluginAttached(lifecycle))
scheduler.runCurrent()
assertEquals(0, changeCallCount)
assertEquals(0, listChangeCallCount)
@@ -339,10 +383,12 @@
@Test
fun knownPluginAttached_clockAndListChanged_notLoaded() {
- val mockPluginLifecycle1 = mock<PluginLifecycleManager<ClockProviderPlugin>>()
- whenever(mockPluginLifecycle1.getPackage()).thenReturn("com.android.systemui.clocks.metro")
- val mockPluginLifecycle2 = mock<PluginLifecycleManager<ClockProviderPlugin>>()
- whenever(mockPluginLifecycle2.getPackage()).thenReturn("com.android.systemui.clocks.bignum")
+ val lifecycle1 = FakeLifecycle("Metro", null).apply {
+ mComponentName = ComponentName("com.android.systemui.clocks.metro", "MetroClock")
+ }
+ val lifecycle2 = FakeLifecycle("BigNum", null).apply {
+ mComponentName = ComponentName("com.android.systemui.clocks.bignum", "BigNumClock")
+ }
var changeCallCount = 0
var listChangeCallCount = 0
@@ -356,12 +402,12 @@
assertEquals(1, changeCallCount)
assertEquals(0, listChangeCallCount)
- assertEquals(false, pluginListener.onPluginAttached(mockPluginLifecycle1))
+ assertEquals(false, pluginListener.onPluginAttached(lifecycle1))
scheduler.runCurrent()
assertEquals(1, changeCallCount)
assertEquals(1, listChangeCallCount)
- assertEquals(false, pluginListener.onPluginAttached(mockPluginLifecycle2))
+ assertEquals(false, pluginListener.onPluginAttached(lifecycle2))
scheduler.runCurrent()
assertEquals(1, changeCallCount)
assertEquals(2, listChangeCallCount)
@@ -369,18 +415,14 @@
@Test
fun pluginAddRemove_concurrentModification() {
- val mockPluginLifecycle1 = mock<PluginLifecycleManager<ClockProviderPlugin>>()
- val mockPluginLifecycle2 = mock<PluginLifecycleManager<ClockProviderPlugin>>()
- val mockPluginLifecycle3 = mock<PluginLifecycleManager<ClockProviderPlugin>>()
- val mockPluginLifecycle4 = mock<PluginLifecycleManager<ClockProviderPlugin>>()
val plugin1 = FakeClockPlugin().addClock("clock_1", "clock 1")
+ val lifecycle1 = FakeLifecycle("1", plugin1)
val plugin2 = FakeClockPlugin().addClock("clock_2", "clock 2")
+ val lifecycle2 = FakeLifecycle("2", plugin2)
val plugin3 = FakeClockPlugin().addClock("clock_3", "clock 3")
+ val lifecycle3 = FakeLifecycle("3", plugin3)
val plugin4 = FakeClockPlugin().addClock("clock_4", "clock 4")
- whenever(mockPluginLifecycle1.isLoaded).thenReturn(true)
- whenever(mockPluginLifecycle2.isLoaded).thenReturn(true)
- whenever(mockPluginLifecycle3.isLoaded).thenReturn(true)
- whenever(mockPluginLifecycle4.isLoaded).thenReturn(true)
+ val lifecycle4 = FakeLifecycle("4", plugin4)
// Set the current clock to the final clock to load
registry.applySettings(ClockSettings("clock_4", null))
@@ -390,15 +432,15 @@
// unload other plugins. This causes ClockRegistry to modify the list of available clock
// plugins while it is being iterated over. In production this happens as a result of a
// thread race, instead of synchronously like it does here.
- whenever(mockPluginLifecycle2.unloadPlugin()).then {
- pluginListener.onPluginDetached(mockPluginLifecycle1)
- pluginListener.onPluginLoaded(plugin4, mockContext, mockPluginLifecycle4)
+ lifecycle2.onUnload = {
+ pluginListener.onPluginDetached(lifecycle1)
+ pluginListener.onPluginLoaded(plugin4, mockContext, lifecycle4)
}
// Load initial plugins
- pluginListener.onPluginLoaded(plugin1, mockContext, mockPluginLifecycle1)
- pluginListener.onPluginLoaded(plugin2, mockContext, mockPluginLifecycle2)
- pluginListener.onPluginLoaded(plugin3, mockContext, mockPluginLifecycle3)
+ pluginListener.onPluginLoaded(plugin1, mockContext, lifecycle1)
+ pluginListener.onPluginLoaded(plugin2, mockContext, lifecycle2)
+ pluginListener.onPluginLoaded(plugin3, mockContext, lifecycle3)
// Repeatedly verify the loaded providers to get final state
registry.verifyLoadedProviders()
@@ -484,11 +526,11 @@
private fun testTransitClockFlag(flag: Boolean) {
featureFlags.set(TRANSIT_CLOCK, flag)
registry.isTransitClockEnabled = featureFlags.isEnabled(TRANSIT_CLOCK)
- val mockPluginLifecycle = mock<PluginLifecycleManager<ClockProviderPlugin>>()
val plugin = FakeClockPlugin()
.addClock("clock_1", "clock 1")
.addClock("DIGITAL_CLOCK_METRO", "metro clock")
- pluginListener.onPluginLoaded(plugin, mockContext, mockPluginLifecycle)
+ val lifecycle = FakeLifecycle("metro", plugin)
+ pluginListener.onPluginLoaded(plugin, mockContext, lifecycle)
val list = registry.getClocks()
if (flag) {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/StatusBarIconViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/StatusBarIconViewTest.java
index 1592c30..a6180ec 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/StatusBarIconViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/StatusBarIconViewTest.java
@@ -248,7 +248,7 @@
}
@Test
- public void testUpdateIconScale_smallerFontAndConstrainedDrawableSizeLessThanDpIconSize() {
+ public void testUpdateIconScale_smallerFontAndRawDrawableSizeLessThanDpIconSize() {
int dpIconSize = 60;
int dpDrawingSize = 30;
// smaller font scaling causes the spIconSize < dpIconSize
@@ -262,12 +262,42 @@
setIconDrawableWithSize(/* width= */ 50, /* height= */ 50);
mIconView.maybeUpdateIconScaleDimens();
- // WHEN both the constrained drawable width/height are less than dpIconSize,
+ // WHEN both the raw/constrained drawable width/height are less than dpIconSize,
+ // THEN the icon is scaled up from constrained drawable size to the raw drawable size
+ float scaleToBackRawDrawableSize = (float) 50 / 40;
// THEN the icon is scaled down from dpIconSize to fit the dpDrawingSize
float scaleToFitDrawingSize = (float) dpDrawingSize / dpIconSize;
// THEN the scaled icon should be scaled down further to fit spIconSize
float scaleToFitSpIconSize = (float) spIconSize / dpIconSize;
- assertEquals(scaleToFitDrawingSize * scaleToFitSpIconSize, mIconView.getIconScale(), 0.01f);
+ assertEquals(scaleToBackRawDrawableSize * scaleToFitDrawingSize * scaleToFitSpIconSize,
+ mIconView.getIconScale(), 0.01f);
+ }
+
+ @Test
+ public void testUpdateIconScale_smallerFontAndConstrainedDrawableSizeLessThanDpIconSize() {
+ int dpIconSize = 60;
+ int dpDrawingSize = 30;
+ // smaller font scaling causes the spIconSize < dpIconSize
+ int spIconSize = 40;
+ // the icon view layout size would be 40x150
+ // (the height is always 150 due to TEST_STATUS_BAR_HEIGHT)
+ setUpIconView(dpIconSize, dpDrawingSize, spIconSize);
+ mIconView.setNotification(mock(StatusBarNotification.class));
+ // the raw drawable size is 70x70. When put the drawable into iconView whose
+ // layout size is 40x150, the drawable size would be constrained to 40x40
+ setIconDrawableWithSize(/* width= */ 70, /* height= */ 70);
+ mIconView.maybeUpdateIconScaleDimens();
+
+ // WHEN the raw drawable width/height are larger than dpIconSize,
+ // but the constrained drawable width/height are less than dpIconSize,
+ // THEN the icon is scaled up from constrained drawable size to fit dpIconSize
+ float scaleToFitDpIconSize = (float) dpIconSize / 40;
+ // THEN the icon is scaled down from dpIconSize to fit the dpDrawingSize
+ float scaleToFitDrawingSize = (float) dpDrawingSize / dpIconSize;
+ // THEN the scaled icon should be scaled down further to fit spIconSize
+ float scaleToFitSpIconSize = (float) spIconSize / dpIconSize;
+ assertEquals(scaleToFitDpIconSize * scaleToFitDrawingSize * scaleToFitSpIconSize,
+ mIconView.getIconScale(), 0.01f);
}
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationTemplateViewWrapperTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationTemplateViewWrapperTest.kt
new file mode 100644
index 0000000..8c3bfd5
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationTemplateViewWrapperTest.kt
@@ -0,0 +1,254 @@
+/*
+ * 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.row.wrapper
+
+import android.app.PendingIntent
+import android.app.PendingIntent.CancelListener
+import android.content.Intent
+import android.testing.AndroidTestingRunner
+import android.testing.TestableLooper
+import android.testing.TestableLooper.RunWithLooper
+import android.testing.ViewUtils
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.FrameLayout
+import androidx.test.filters.SmallTest
+import com.android.internal.R
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
+import com.android.systemui.statusbar.notification.row.NotificationTestHelper
+import com.android.systemui.statusbar.notification.row.wrapper.NotificationTemplateViewWrapper.ActionPendingIntentCancellationHandler
+import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.ArgumentCaptor
+import org.mockito.Mockito
+import org.mockito.Mockito.times
+import org.mockito.Mockito.verify
+
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+@RunWithLooper
+class NotificationTemplateViewWrapperTest : SysuiTestCase() {
+
+ private lateinit var helper: NotificationTestHelper
+
+ private lateinit var root: ViewGroup
+ private lateinit var view: ViewGroup
+ private lateinit var row: ExpandableNotificationRow
+ private lateinit var actions: ViewGroup
+
+ private lateinit var looper: TestableLooper
+
+ @Before
+ fun setUp() {
+ looper = TestableLooper.get(this)
+ allowTestableLooperAsMainThread()
+ helper = NotificationTestHelper(mContext, mDependency, looper)
+ row = helper.createRow()
+ // Some code in the view iterates through parents so we need some extra containers around
+ // it.
+ root = FrameLayout(mContext)
+ val root2 = FrameLayout(mContext)
+ root.addView(root2)
+ view =
+ (LayoutInflater.from(mContext)
+ .inflate(R.layout.notification_template_material_big_text, root2) as ViewGroup)
+ actions = view.findViewById(R.id.actions)!!
+ ViewUtils.attachView(root)
+ }
+
+ @Test
+ fun noActionsPresent_noCrash() {
+ view.removeView(actions)
+ val wrapper = NotificationTemplateViewWrapper(mContext, view, row)
+ wrapper.onContentUpdated(row)
+ }
+
+ @Test
+ fun actionPendingIntentCancelled_actionDisabled() {
+ val wrapper = NotificationTemplateViewWrapper(mContext, view, row)
+ val action1 = createActionWithPendingIntent()
+ val action2 = createActionWithPendingIntent()
+ val action3 = createActionWithPendingIntent()
+ wrapper.onContentUpdated(row)
+ waitForUiOffloadThread() // Wait for cancellation registration to execute.
+
+ val pi3 = getPendingIntent(action3)
+ pi3.cancel()
+ looper.processAllMessages() // Wait for listener callbacks to execute
+
+ assertThat(action1.isEnabled).isTrue()
+ assertThat(action2.isEnabled).isTrue()
+ assertThat(action3.isEnabled).isFalse()
+ assertThat(wrapper.mCancelledPendingIntents)
+ .doesNotContain(getPendingIntent(action1).hashCode())
+ assertThat(wrapper.mCancelledPendingIntents)
+ .doesNotContain(getPendingIntent(action2).hashCode())
+ assertThat(wrapper.mCancelledPendingIntents).contains(pi3.hashCode())
+ }
+
+ @Test
+ fun newActionWithSamePendingIntentPosted_actionDisabled() {
+ val wrapper = NotificationTemplateViewWrapper(mContext, view, row)
+ val action = createActionWithPendingIntent()
+ wrapper.onContentUpdated(row)
+ waitForUiOffloadThread() // Wait for cancellation registration to execute.
+
+ // Cancel the intent and check action is now false.
+ val pi = getPendingIntent(action)
+ pi.cancel()
+ looper.processAllMessages() // Wait for listener callbacks to execute
+ assertThat(action.isEnabled).isFalse()
+
+ // Create a NEW action and make sure that one will also be cancelled with same PI.
+ actions.removeView(action)
+ val newAction = createActionWithPendingIntent(pi)
+ wrapper.onContentUpdated(row)
+ looper.processAllMessages() // Wait for listener callbacks to execute
+
+ assertThat(newAction.isEnabled).isFalse()
+ assertThat(wrapper.mCancelledPendingIntents).containsExactly(pi.hashCode())
+ }
+
+ @Test
+ fun twoActionsWithSameCancelledIntent_bothActionsDisabled() {
+ val wrapper = NotificationTemplateViewWrapper(mContext, view, row)
+ val action1 = createActionWithPendingIntent()
+ val action2 = createActionWithPendingIntent()
+ val action3 = createActionWithPendingIntent(getPendingIntent(action2))
+ wrapper.onContentUpdated(row)
+ waitForUiOffloadThread() // Wait for cancellation registration to execute.
+
+ val pi = getPendingIntent(action2)
+ pi.cancel()
+ looper.processAllMessages() // Wait for listener callbacks to execute
+
+ assertThat(action1.isEnabled).isTrue()
+ assertThat(action2.isEnabled).isFalse()
+ assertThat(action3.isEnabled).isFalse()
+ }
+
+ @Test
+ fun actionPendingIntentCancelled_whileDetached_actionDisabled() {
+ ViewUtils.detachView(root)
+ val wrapper = NotificationTemplateViewWrapper(mContext, view, row)
+ val action = createActionWithPendingIntent()
+ wrapper.onContentUpdated(row)
+ getPendingIntent(action).cancel()
+ ViewUtils.attachView(root)
+ waitForUiOffloadThread()
+ looper.processAllMessages()
+
+ assertThat(action.isEnabled).isFalse()
+ }
+
+ @Test
+ fun actionViewDetached_pendingIntentListenersDeregistered() {
+ val pi =
+ PendingIntent.getActivity(
+ mContext,
+ System.currentTimeMillis().toInt(),
+ Intent(Intent.ACTION_VIEW),
+ PendingIntent.FLAG_IMMUTABLE
+ )
+ val spy = Mockito.spy(pi)
+ createActionWithPendingIntent(spy)
+ val wrapper = NotificationTemplateViewWrapper(mContext, view, row)
+ wrapper.onContentUpdated(row)
+ ViewUtils.detachView(root)
+ waitForUiOffloadThread()
+ looper.processAllMessages()
+
+ val captor = ArgumentCaptor.forClass(CancelListener::class.java)
+ verify(spy, times(1)).registerCancelListener(captor.capture())
+ verify(spy, times(1)).unregisterCancelListener(captor.value)
+ }
+
+ @Test
+ fun actionViewUpdated_oldPendingIntentListenersRemoved() {
+ val pi =
+ PendingIntent.getActivity(
+ mContext,
+ System.currentTimeMillis().toInt(),
+ Intent(Intent.ACTION_VIEW),
+ PendingIntent.FLAG_IMMUTABLE
+ )
+ val spy = Mockito.spy(pi)
+ val action = createActionWithPendingIntent(spy)
+ val wrapper = NotificationTemplateViewWrapper(mContext, view, row)
+ wrapper.onContentUpdated(row)
+ waitForUiOffloadThread()
+ looper.processAllMessages()
+
+ // Grab set attach listener
+ val attachListener =
+ Mockito.spy(action.getTag(com.android.systemui.res.R.id.pending_intent_listener_tag))
+ as ActionPendingIntentCancellationHandler
+ action.setTag(com.android.systemui.res.R.id.pending_intent_listener_tag, attachListener)
+
+ // Update pending intent in the existing action
+ val newPi =
+ PendingIntent.getActivity(
+ mContext,
+ System.currentTimeMillis().toInt(),
+ Intent(Intent.ACTION_ALARM_CHANGED),
+ PendingIntent.FLAG_IMMUTABLE
+ )
+ action.setTagInternal(R.id.pending_intent_tag, newPi)
+ wrapper.onContentUpdated(row)
+ waitForUiOffloadThread()
+ looper.processAllMessages()
+
+ // Listeners for original pending intent need to be cleaned up now.
+ val captor = ArgumentCaptor.forClass(CancelListener::class.java)
+ verify(spy, times(1)).registerCancelListener(captor.capture())
+ verify(spy, times(1)).unregisterCancelListener(captor.value)
+ // Attach listener has to be replaced with a new one.
+ assertThat(action.getTag(com.android.systemui.res.R.id.pending_intent_listener_tag))
+ .isNotEqualTo(attachListener)
+ verify(attachListener).remove()
+ }
+
+ private fun createActionWithPendingIntent(): View {
+ val pi =
+ PendingIntent.getActivity(
+ mContext,
+ System.currentTimeMillis().toInt(),
+ Intent(Intent.ACTION_VIEW),
+ PendingIntent.FLAG_IMMUTABLE
+ )
+ return createActionWithPendingIntent(pi)
+ }
+
+ private fun createActionWithPendingIntent(pi: PendingIntent): View {
+ val view =
+ LayoutInflater.from(mContext)
+ .inflate(R.layout.notification_material_action, null, false)
+ view.setTagInternal(R.id.pending_intent_tag, pi)
+ actions.addView(view)
+ return view
+ }
+
+ private fun getPendingIntent(action: View): PendingIntent {
+ val pendingIntent = action.getTag(R.id.pending_intent_tag) as PendingIntent
+ assertThat(pendingIntent).isNotNull()
+ return pendingIntent
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogImplTest.java
index 8e57dc1..daf8877 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogImplTest.java
@@ -41,8 +41,8 @@
import android.app.KeyguardManager;
import android.content.res.Configuration;
import android.media.AudioManager;
-import android.os.Handler;
import android.os.SystemClock;
+import android.provider.Settings;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.util.Log;
@@ -71,6 +71,7 @@
import com.android.systemui.statusbar.policy.DevicePostureController;
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
import com.android.systemui.statusbar.policy.FakeConfigurationController;
+import com.android.systemui.util.settings.FakeSettings;
import org.junit.After;
import org.junit.Before;
@@ -135,6 +136,8 @@
private FakeFeatureFlags mFeatureFlags;
private int mLongestHideShowAnimationDuration = 250;
+ private FakeSettings mSecureSettings;
+
@Rule
public final AnimatorTestRule mAnimatorTestRule = new AnimatorTestRule();
@@ -147,10 +150,6 @@
mTestableLooper = TestableLooper.get(this);
allowTestableLooperAsMainThread();
- // Ensure previous tests have not left messages on main looper
- Handler localHandler = new Handler(mTestableLooper.getLooper());
- localHandler.removeCallbacksAndMessages(null);
-
when(mPostureController.getDevicePosture())
.thenReturn(DevicePostureController.DEVICE_POSTURE_CLOSED);
@@ -167,6 +166,8 @@
mFeatureFlags = new FakeFeatureFlags();
+ mSecureSettings = new FakeSettings();
+
mDialog = new VolumeDialogImpl(
getContext(),
mVolumeDialogController,
@@ -182,7 +183,8 @@
mPostureController,
mTestableLooper.getLooper(),
mDumpManager,
- mFeatureFlags);
+ mFeatureFlags,
+ mSecureSettings);
mDialog.init(0, null);
State state = createShellState();
mDialog.onStateChangedH(state);
@@ -247,6 +249,18 @@
}
@Test
+ public void testSetTimeoutValue_ComputeTimeout() {
+ mSecureSettings.putInt(Settings.Secure.VOLUME_DIALOG_DISMISS_TIMEOUT, 7000);
+ Mockito.reset(mAccessibilityMgr);
+ mDialog.init(0, null);
+ mDialog.rescheduleTimeoutH();
+ verify(mAccessibilityMgr).getRecommendedTimeoutMillis(
+ 7000,
+ AccessibilityManager.FLAG_CONTENT_CONTROLS);
+ }
+
+
+ @Test
public void testComputeTimeout_tooltip() {
Mockito.reset(mAccessibilityMgr);
mDialog.showCaptionsTooltip();
diff --git a/services/core/java/com/android/server/connectivity/OWNERS b/services/core/java/com/android/server/connectivity/OWNERS
index 62c5737..c24680e9 100644
--- a/services/core/java/com/android/server/connectivity/OWNERS
+++ b/services/core/java/com/android/server/connectivity/OWNERS
@@ -1,2 +1,2 @@
set noparent
-file:platform/packages/modules/Connectivity:master:/OWNERS_core_networking
+file:platform/packages/modules/Connectivity:main:/OWNERS_core_networking
diff --git a/services/core/java/com/android/server/display/BrightnessMappingStrategy.java b/services/core/java/com/android/server/display/BrightnessMappingStrategy.java
index debf828..99a5398 100644
--- a/services/core/java/com/android/server/display/BrightnessMappingStrategy.java
+++ b/services/core/java/com/android/server/display/BrightnessMappingStrategy.java
@@ -33,7 +33,6 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.display.BrightnessSynchronizer;
-import com.android.internal.display.BrightnessUtils;
import com.android.internal.util.Preconditions;
import com.android.server.display.utils.Plog;
import com.android.server.display.whitebalance.DisplayWhiteBalanceController;
diff --git a/core/java/com/android/internal/display/BrightnessUtils.java b/services/core/java/com/android/server/display/BrightnessUtils.java
similarity index 96%
rename from core/java/com/android/internal/display/BrightnessUtils.java
rename to services/core/java/com/android/server/display/BrightnessUtils.java
index 82b506b..84fa0cc 100644
--- a/core/java/com/android/internal/display/BrightnessUtils.java
+++ b/services/core/java/com/android/server/display/BrightnessUtils.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2023 The Android Open Source Project
+ * Copyright (C) 2022 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.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.internal.display;
+package com.android.server.display;
import android.util.MathUtils;
diff --git a/services/core/java/com/android/server/display/RampAnimator.java b/services/core/java/com/android/server/display/RampAnimator.java
index e38c2c5..5ba042c 100644
--- a/services/core/java/com/android/server/display/RampAnimator.java
+++ b/services/core/java/com/android/server/display/RampAnimator.java
@@ -20,8 +20,6 @@
import android.util.FloatProperty;
import android.view.Choreographer;
-import com.android.internal.display.BrightnessUtils;
-
/**
* A custom animator that progressively updates a property value at
* a given variable rate until it reaches a particular target value.
diff --git a/services/core/java/com/android/server/net/OWNERS b/services/core/java/com/android/server/net/OWNERS
index 9c96d46f..d0e95dd 100644
--- a/services/core/java/com/android/server/net/OWNERS
+++ b/services/core/java/com/android/server/net/OWNERS
@@ -1,5 +1,5 @@
set noparent
-file:platform/packages/modules/Connectivity:master:/OWNERS_core_networking
+file:platform/packages/modules/Connectivity:main:/OWNERS_core_networking
jsharkey@android.com
sudheersai@google.com
diff --git a/services/core/java/com/android/server/pm/TEST_MAPPING b/services/core/java/com/android/server/pm/TEST_MAPPING
index 04d1da6..390c45b 100644
--- a/services/core/java/com/android/server/pm/TEST_MAPPING
+++ b/services/core/java/com/android/server/pm/TEST_MAPPING
@@ -145,6 +145,19 @@
"include-filter": "android.content.pm.cts.PackageManagerShellCommandMultiUserTest"
}
]
+ },
+ {
+ "file_patterns": [
+ "(/|^)InstallPackageHelper\\.java",
+ "services/core/java/com/android/server/pm/parsing/.*",
+ "services/core/java/com/android/server/pm/pkg/parsing/.*"
+ ],
+ "name": "SdkSandboxManagerServiceUnitTests",
+ "options": [
+ {
+ "exclude-annotation": "androidx.test.filters.FlakyTest"
+ }
+ ]
}
],
"imports": [
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index dfc9b8b..097656c 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -198,7 +198,6 @@
import com.android.internal.accessibility.util.AccessibilityUtils;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.app.AssistUtils;
-import com.android.internal.display.BrightnessUtils;
import com.android.internal.inputmethod.SoftInputShowHideReason;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto;
@@ -218,6 +217,7 @@
import com.android.server.LocalServices;
import com.android.server.SystemServiceManager;
import com.android.server.UiThread;
+import com.android.server.display.BrightnessUtils;
import com.android.server.input.InputManagerInternal;
import com.android.server.input.KeyboardMetricsCollector;
import com.android.server.input.KeyboardMetricsCollector.KeyboardLogEvent;
diff --git a/services/core/java/com/android/server/security/rkp/OWNERS b/services/core/java/com/android/server/security/rkp/OWNERS
index 348f940..ea6dc72 100644
--- a/services/core/java/com/android/server/security/rkp/OWNERS
+++ b/services/core/java/com/android/server/security/rkp/OWNERS
@@ -1 +1 @@
-file:platform/frameworks/base:master:/core/java/android/security/rkp/OWNERS
+file:platform/frameworks/base:main:/core/java/android/security/rkp/OWNERS
diff --git a/services/core/java/com/android/server/wm/RecentTasks.java b/services/core/java/com/android/server/wm/RecentTasks.java
index 184de58..442269a 100644
--- a/services/core/java/com/android/server/wm/RecentTasks.java
+++ b/services/core/java/com/android/server/wm/RecentTasks.java
@@ -64,6 +64,7 @@
import android.os.Environment;
import android.os.IBinder;
import android.os.RemoteException;
+import android.os.SystemClock;
import android.os.SystemProperties;
import android.os.UserHandle;
import android.text.TextUtils;
@@ -506,6 +507,16 @@
Slog.i(TAG, "Loading recents for user " + userId + " into memory.");
List<Task> tasks = mTaskPersister.restoreTasksForUserLocked(userId, preaddedTasks);
+
+ // Tasks are ordered from most recent to least recent. Update the last active time to be
+ // in sync with task recency when device reboots, so the most recent task has the
+ // highest last active time
+ long currentElapsedTime = SystemClock.elapsedRealtime();
+ for (int i = 0; i < tasks.size(); i++) {
+ Task task = tasks.get(i);
+ task.lastActiveTime = currentElapsedTime - i;
+ }
+
mTasks.addAll(tasks);
cleanupLocked(userId);
mUsersWithRecentsLoaded.put(userId, true);
diff --git a/services/net/OWNERS b/services/net/OWNERS
index 62c5737..c24680e9 100644
--- a/services/net/OWNERS
+++ b/services/net/OWNERS
@@ -1,2 +1,2 @@
set noparent
-file:platform/packages/modules/Connectivity:master:/OWNERS_core_networking
+file:platform/packages/modules/Connectivity:main:/OWNERS_core_networking
diff --git a/services/tests/PermissionServiceMockingTests/src/com/android/server/permission/test/AppIdPermissionPolicyPermissionResetTest.kt b/services/tests/PermissionServiceMockingTests/src/com/android/server/permission/test/AppIdPermissionPolicyPermissionResetTest.kt
index 823ce45..0547719 100644
--- a/services/tests/PermissionServiceMockingTests/src/com/android/server/permission/test/AppIdPermissionPolicyPermissionResetTest.kt
+++ b/services/tests/PermissionServiceMockingTests/src/com/android/server/permission/test/AppIdPermissionPolicyPermissionResetTest.kt
@@ -112,4 +112,4 @@
@JvmStatic
fun data(): Array<Action> = Action.values()
}
-}
\ No newline at end of file
+}
diff --git a/services/tests/PermissionServiceMockingTests/src/com/android/server/permission/test/AppIdPermissionPolicyPermissionStatesTest.kt b/services/tests/PermissionServiceMockingTests/src/com/android/server/permission/test/AppIdPermissionPolicyPermissionStatesTest.kt
index f085bd7..c44b2c5 100644
--- a/services/tests/PermissionServiceMockingTests/src/com/android/server/permission/test/AppIdPermissionPolicyPermissionStatesTest.kt
+++ b/services/tests/PermissionServiceMockingTests/src/com/android/server/permission/test/AppIdPermissionPolicyPermissionStatesTest.kt
@@ -43,8 +43,7 @@
@Parameterized.Parameter(0) lateinit var action: Action
@Before
- override fun setUp() {
- super.setUp()
+ fun setUp() {
if (action == Action.ON_USER_ADDED) {
createUserState(USER_ID_NEW)
}
@@ -881,4 +880,4 @@
@JvmStatic
fun data(): Array<Action> = Action.values()
}
-}
\ No newline at end of file
+}
diff --git a/services/tests/PermissionServiceMockingTests/src/com/android/server/permission/test/AppIdPermissionPolicyTest.kt b/services/tests/PermissionServiceMockingTests/src/com/android/server/permission/test/AppIdPermissionPolicyTest.kt
new file mode 100644
index 0000000..e4e3368
--- /dev/null
+++ b/services/tests/PermissionServiceMockingTests/src/com/android/server/permission/test/AppIdPermissionPolicyTest.kt
@@ -0,0 +1,430 @@
+/*
+ * 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.server.permission.test
+
+import android.content.pm.PermissionGroupInfo
+import android.content.pm.PermissionInfo
+import com.android.server.permission.access.GetStateScope
+import com.android.server.permission.access.immutable.* // ktlint-disable no-wildcard-imports
+import com.android.server.permission.access.permission.AppIdPermissionPolicy
+import com.android.server.permission.access.permission.Permission
+import com.android.server.permission.access.permission.PermissionFlags
+import com.android.server.testutils.mock
+import com.google.common.truth.Truth.assertThat
+import com.google.common.truth.Truth.assertWithMessage
+import org.junit.Test
+import org.mockito.Mockito.times
+import org.mockito.Mockito.verify
+
+class AppIdPermissionPolicyTest : BaseAppIdPermissionPolicyTest() {
+ @Test
+ fun testOnAppIdRemoved_appIdIsRemoved_permissionFlagsCleared() {
+ val parsedPermission = mockParsedPermission(PERMISSION_NAME_0, PACKAGE_NAME_0)
+ val permissionOwnerPackageState = mockPackageState(
+ APP_ID_0,
+ mockAndroidPackage(PACKAGE_NAME_0, permissions = listOf(parsedPermission))
+ )
+ val requestingPackageState = mockPackageState(
+ APP_ID_1,
+ mockAndroidPackage(PACKAGE_NAME_1, requestedPermissions = setOf(PERMISSION_NAME_0))
+ )
+ addPackageState(permissionOwnerPackageState)
+ addPackageState(requestingPackageState)
+ addPermission(parsedPermission)
+ setPermissionFlags(APP_ID_1, USER_ID_0, PERMISSION_NAME_0, PermissionFlags.INSTALL_GRANTED)
+
+ mutateState {
+ with(appIdPermissionPolicy) {
+ onAppIdRemoved(APP_ID_1)
+ }
+ }
+
+ val actualFlags = getPermissionFlags(APP_ID_1, USER_ID_0, PERMISSION_NAME_0)
+ val expectedNewFlags = 0
+ assertWithMessage(
+ "After onAppIdRemoved() is called for appId $APP_ID_1 that requests a permission" +
+ " owns by appId $APP_ID_0 with existing permission flags. The actual permission" +
+ " flags $actualFlags should be null"
+ )
+ .that(actualFlags)
+ .isEqualTo(expectedNewFlags)
+ }
+
+ @Test
+ fun testOnStorageVolumeMounted_nonSystemAppAfterNonSystemUpdate_remainsRevoked() {
+ val permissionOwnerPackageState = mockPackageState(APP_ID_0, mockSimpleAndroidPackage())
+ val installedPackageState = mockPackageState(
+ APP_ID_1,
+ mockAndroidPackage(PACKAGE_NAME_1, requestedPermissions = setOf(PERMISSION_NAME_0))
+ )
+ addPackageState(permissionOwnerPackageState)
+ addPackageState(installedPackageState)
+ addPermission(defaultPermission)
+ val oldFlags = PermissionFlags.INSTALL_REVOKED
+ setPermissionFlags(APP_ID_1, USER_ID_0, PERMISSION_NAME_0, oldFlags)
+
+ mutateState {
+ with(appIdPermissionPolicy) {
+ onStorageVolumeMounted(null, listOf(installedPackageState.packageName), false)
+ }
+ }
+
+ val actualFlags = getPermissionFlags(APP_ID_1, USER_ID_0, PERMISSION_NAME_0)
+ val expectedNewFlags = oldFlags
+ assertWithMessage(
+ "After onStorageVolumeMounted() is called for a non-system app that requests a normal" +
+ " permission with existing INSTALL_REVOKED flag after a non-system-update" +
+ " (such as an OTA update), the actual permission flags should remain revoked." +
+ " The actual permission flags $actualFlags should match the expected flags" +
+ " $expectedNewFlags"
+ )
+ .that(actualFlags)
+ .isEqualTo(expectedNewFlags)
+ }
+
+ @Test
+ fun testOnPackageRemoved_packageIsRemoved_permissionDefinitionsAndStatesAreUpdated() {
+ val permissionOwnerPackageState = mockPackageState(
+ APP_ID_0,
+ mockAndroidPackage(
+ PACKAGE_NAME_0,
+ requestedPermissions = setOf(PERMISSION_NAME_0),
+ permissions = listOf(defaultPermission)
+ )
+ )
+ val requestingPackageState = mockPackageState(
+ APP_ID_1,
+ mockAndroidPackage(PACKAGE_NAME_1, requestedPermissions = setOf(PERMISSION_NAME_0))
+ )
+ addPackageState(permissionOwnerPackageState)
+ addPackageState(requestingPackageState)
+ addPermission(defaultPermission)
+ val oldFlags = PermissionFlags.INSTALL_GRANTED
+ setPermissionFlags(APP_ID_0, USER_ID_0, PERMISSION_NAME_0, oldFlags)
+ setPermissionFlags(APP_ID_1, USER_ID_0, PERMISSION_NAME_0, oldFlags)
+
+ mutateState {
+ removePackageState(permissionOwnerPackageState)
+ with(appIdPermissionPolicy) {
+ onPackageRemoved(PACKAGE_NAME_0, APP_ID_0)
+ }
+ }
+
+ assertWithMessage(
+ "After onPackageRemoved() is called for a permission owner, the permission" +
+ " definitions owned by this package should be removed"
+ )
+ .that(getPermission(PERMISSION_NAME_0))
+ .isNull()
+
+ val app0ActualFlags = getPermissionFlags(APP_ID_0, USER_ID_0, PERMISSION_NAME_0)
+ val app0ExpectedNewFlags = 0
+ assertWithMessage(
+ "After onPackageRemoved() is called for a permission owner, the permission states of" +
+ " this app should be trimmed. The actual permission flags $app0ActualFlags should" +
+ " match the expected flags $app0ExpectedNewFlags"
+ )
+ .that(app0ActualFlags)
+ .isEqualTo(app0ExpectedNewFlags)
+
+ val app1ActualFlags = getPermissionFlags(APP_ID_1, USER_ID_0, PERMISSION_NAME_0)
+ val app1ExpectedNewFlags = PermissionFlags.INSTALL_REVOKED
+ assertWithMessage(
+ "After onPackageRemoved() is called for a permission owner, the permission states of" +
+ " the permission requester should remain unchanged. The actual permission flags" +
+ " $app1ActualFlags should match the expected flags $app1ExpectedNewFlags"
+ )
+ .that(app1ActualFlags)
+ .isEqualTo(app1ExpectedNewFlags)
+ }
+
+ @Test
+ fun testOnPackageInstalled_nonSystemAppIsInstalled_upgradeExemptFlagIsCleared() {
+ val oldFlags = PermissionFlags.SOFT_RESTRICTED or PermissionFlags.UPGRADE_EXEMPT
+ testOnPackageInstalled(
+ oldFlags,
+ permissionInfoFlags = PermissionInfo.FLAG_SOFT_RESTRICTED
+ ) {}
+ val actualFlags = getPermissionFlags(APP_ID_1, USER_ID_0, PERMISSION_NAME_0)
+ val expectedNewFlags = PermissionFlags.SOFT_RESTRICTED
+ assertWithMessage(
+ "After onPackageInstalled() is called for a non-system app that requests a runtime" +
+ " soft restricted permission, UPGRADE_EXEMPT flag should be removed. The actual" +
+ " permission flags $actualFlags should match the expected flags $expectedNewFlags"
+ )
+ .that(actualFlags)
+ .isEqualTo(expectedNewFlags)
+ }
+
+ @Test
+ fun testOnPackageInstalled_systemAppIsInstalled_upgradeExemptFlagIsRetained() {
+ val oldFlags = PermissionFlags.SOFT_RESTRICTED or PermissionFlags.UPGRADE_EXEMPT
+ testOnPackageInstalled(
+ oldFlags,
+ permissionInfoFlags = PermissionInfo.FLAG_SOFT_RESTRICTED,
+ isInstalledPackageSystem = true
+ ) {}
+ val actualFlags = getPermissionFlags(APP_ID_1, USER_ID_0, PERMISSION_NAME_0)
+ val expectedNewFlags = oldFlags
+ assertWithMessage(
+ "After onPackageInstalled() is called for a system app that requests a runtime" +
+ " soft restricted permission, UPGRADE_EXEMPT flag should be retained. The actual" +
+ " permission flags $actualFlags should match the expected flags $expectedNewFlags"
+ )
+ .that(actualFlags)
+ .isEqualTo(expectedNewFlags)
+ }
+
+ @Test
+ fun testOnPackageInstalled_requestedPermissionAlsoRequestedBySystemApp_exemptFlagIsRetained() {
+ val oldFlags = PermissionFlags.SOFT_RESTRICTED or PermissionFlags.UPGRADE_EXEMPT
+ testOnPackageInstalled(
+ oldFlags,
+ permissionInfoFlags = PermissionInfo.FLAG_SOFT_RESTRICTED
+ ) {
+ val systemAppPackageState = mockPackageState(
+ APP_ID_1,
+ mockAndroidPackage(PACKAGE_NAME_2, requestedPermissions = setOf(PERMISSION_NAME_0)),
+ isSystem = true
+ )
+ addPackageState(systemAppPackageState)
+ }
+ val actualFlags = getPermissionFlags(APP_ID_1, USER_ID_0, PERMISSION_NAME_0)
+ val expectedNewFlags = oldFlags
+ assertWithMessage(
+ "After onPackageInstalled() is called for a non-system app that requests a runtime" +
+ " soft restricted permission, and that permission is also requested by a system" +
+ " app in the same appId, UPGRADE_EXEMPT flag should be retained. The actual" +
+ " permission flags $actualFlags should match the expected flags $expectedNewFlags"
+ )
+ .that(actualFlags)
+ .isEqualTo(expectedNewFlags)
+ }
+
+ @Test
+ fun testOnPackageInstalled_restrictedPermissionsNotExempt_getsRestrictionFlags() {
+ val oldFlags = PermissionFlags.RESTRICTION_REVOKED
+ testOnPackageInstalled(
+ oldFlags,
+ permissionInfoFlags = PermissionInfo.FLAG_HARD_RESTRICTED
+ ) {}
+ val actualFlags = getPermissionFlags(APP_ID_1, USER_ID_0, PERMISSION_NAME_0)
+ val expectedNewFlags = oldFlags
+ assertWithMessage(
+ "After onPackageInstalled() is called for a non-system app that requests a runtime" +
+ " hard restricted permission that is not exempted. The actual permission flags" +
+ " $actualFlags should match the expected flags $expectedNewFlags"
+ )
+ .that(actualFlags)
+ .isEqualTo(expectedNewFlags)
+ }
+
+ @Test
+ fun testOnPackageInstalled_restrictedPermissionsIsExempted_clearsRestrictionFlags() {
+ val oldFlags = PermissionFlags.SOFT_RESTRICTED or PermissionFlags.INSTALLER_EXEMPT
+ testOnPackageInstalled(
+ oldFlags,
+ permissionInfoFlags = PermissionInfo.FLAG_SOFT_RESTRICTED
+ ) {}
+ val actualFlags = getPermissionFlags(APP_ID_1, USER_ID_0, PERMISSION_NAME_0)
+ val expectedNewFlags = PermissionFlags.INSTALLER_EXEMPT
+ assertWithMessage(
+ "After onPackageInstalled() is called for a non-system app that requests a runtime" +
+ " soft restricted permission that is exempted. The actual permission flags" +
+ " $actualFlags should match the expected flags $expectedNewFlags"
+ )
+ .that(actualFlags)
+ .isEqualTo(expectedNewFlags)
+ }
+
+ private fun testOnPackageInstalled(
+ oldFlags: Int,
+ permissionInfoFlags: Int = 0,
+ isInstalledPackageSystem: Boolean = false,
+ additionalSetup: () -> Unit
+ ) {
+ val parsedPermission = mockParsedPermission(
+ PERMISSION_NAME_0,
+ PACKAGE_NAME_0,
+ protectionLevel = PermissionInfo.PROTECTION_DANGEROUS,
+ flags = permissionInfoFlags
+ )
+ val permissionOwnerPackageState = mockPackageState(
+ APP_ID_0,
+ mockAndroidPackage(PACKAGE_NAME_0, permissions = listOf(parsedPermission))
+ )
+ addPackageState(permissionOwnerPackageState)
+ addPermission(parsedPermission)
+
+ additionalSetup()
+
+ mutateState {
+ val installedPackageState = mockPackageState(
+ APP_ID_1,
+ mockAndroidPackage(
+ PACKAGE_NAME_1,
+ requestedPermissions = setOf(PERMISSION_NAME_0),
+ ),
+ isSystem = isInstalledPackageSystem,
+ )
+ addPackageState(installedPackageState, newState)
+ setPermissionFlags(APP_ID_1, USER_ID_0, PERMISSION_NAME_0, oldFlags, newState)
+ with(appIdPermissionPolicy) {
+ onPackageInstalled(installedPackageState, USER_ID_0)
+ }
+ }
+ }
+
+ @Test
+ fun testOnStateMutated_notEmpty_isCalledForEachListener() {
+ val mockListener = mock<AppIdPermissionPolicy.OnPermissionFlagsChangedListener> {}
+ appIdPermissionPolicy.addOnPermissionFlagsChangedListener(mockListener)
+
+ GetStateScope(oldState).apply {
+ with(appIdPermissionPolicy) {
+ onStateMutated()
+ }
+ }
+
+ verify(mockListener, times(1)).onStateMutated()
+ }
+
+ @Test
+ fun testGetPermissionTrees() {
+ val permissionTrees: IndexedMap<String, Permission>
+ GetStateScope(oldState).apply {
+ with(appIdPermissionPolicy) {
+ permissionTrees = getPermissionTrees()
+ }
+ }
+
+ assertThat(oldState.systemState.permissionTrees).isEqualTo(permissionTrees)
+ }
+
+ @Test
+ fun testFindPermissionTree() {
+ val permissionTree = createSimplePermission(isTree = true)
+ val actualPermissionTree: Permission?
+ oldState.mutateSystemState().mutatePermissionTrees()[PERMISSION_TREE_NAME] = permissionTree
+
+ GetStateScope(oldState).apply {
+ with(appIdPermissionPolicy) {
+ actualPermissionTree = findPermissionTree(PERMISSION_BELONGS_TO_A_TREE)
+ }
+ }
+
+ assertThat(actualPermissionTree).isEqualTo(permissionTree)
+ }
+
+ @Test
+ fun testAddPermissionTree() {
+ val permissionTree = createSimplePermission(isTree = true)
+
+ mutateState {
+ with(appIdPermissionPolicy) {
+ addPermissionTree(permissionTree)
+ }
+ }
+
+ assertThat(newState.systemState.permissionTrees[PERMISSION_TREE_NAME])
+ .isEqualTo(permissionTree)
+ }
+
+ @Test
+ fun testGetPermissionGroups() {
+ val permissionGroups: IndexedMap<String, PermissionGroupInfo>
+ GetStateScope(oldState).apply {
+ with(appIdPermissionPolicy) {
+ permissionGroups = getPermissionGroups()
+ }
+ }
+
+ assertThat(oldState.systemState.permissionGroups).isEqualTo(permissionGroups)
+ }
+
+ @Test
+ fun testGetPermissions() {
+ val permissions: IndexedMap<String, Permission>
+ GetStateScope(oldState).apply {
+ with(appIdPermissionPolicy) {
+ permissions = getPermissions()
+ }
+ }
+
+ assertThat(oldState.systemState.permissions).isEqualTo(permissions)
+ }
+
+ @Test
+ fun testAddPermission() {
+ val permission = createSimplePermission()
+
+ mutateState {
+ with(appIdPermissionPolicy) {
+ addPermission(permission)
+ }
+ }
+
+ assertThat(newState.systemState.permissions[PERMISSION_NAME_0]).isEqualTo(permission)
+ }
+
+ @Test
+ fun testRemovePermission() {
+ val permission = createSimplePermission()
+
+ mutateState {
+ with(appIdPermissionPolicy) {
+ addPermission(permission)
+ removePermission(permission)
+ }
+ }
+
+ assertThat(newState.systemState.permissions[PERMISSION_NAME_0]).isNull()
+ }
+
+ @Test
+ fun testGetUidPermissionFlags() {
+ val uidPermissionFlags: IndexedMap<String, Int>?
+ GetStateScope(oldState).apply {
+ with(appIdPermissionPolicy) {
+ uidPermissionFlags = getUidPermissionFlags(APP_ID_0, USER_ID_0)
+ }
+ }
+
+ assertThat(oldState.userStates[USER_ID_0]!!.appIdPermissionFlags[APP_ID_0])
+ .isEqualTo(uidPermissionFlags)
+ }
+
+ @Test
+ fun testUpdateAndGetPermissionFlags() {
+ val flags = PermissionFlags.INSTALL_GRANTED
+ var actualFlags = 0
+ mutateState {
+ with(appIdPermissionPolicy) {
+ updatePermissionFlags(
+ APP_ID_0,
+ USER_ID_0,
+ PERMISSION_NAME_0,
+ PermissionFlags.MASK_ALL,
+ flags
+ )
+ actualFlags = getPermissionFlags(APP_ID_0, USER_ID_0, PERMISSION_NAME_0)
+ }
+ }
+
+ assertThat(actualFlags).isEqualTo(flags)
+ }
+}
diff --git a/services/tests/PermissionServiceMockingTests/src/com/android/server/permission/test/BaseAppIdPermissionPolicyTest.kt b/services/tests/PermissionServiceMockingTests/src/com/android/server/permission/test/BaseAppIdPermissionPolicyTest.kt
index 7966c5c..ec84bc3 100644
--- a/services/tests/PermissionServiceMockingTests/src/com/android/server/permission/test/BaseAppIdPermissionPolicyTest.kt
+++ b/services/tests/PermissionServiceMockingTests/src/com/android/server/permission/test/BaseAppIdPermissionPolicyTest.kt
@@ -34,7 +34,6 @@
import com.android.server.permission.access.immutable.* // ktlint-disable no-wildcard-imports
import com.android.server.permission.access.permission.AppIdPermissionPolicy
import com.android.server.permission.access.permission.Permission
-import com.android.server.permission.access.permission.PermissionFlags
import com.android.server.permission.access.util.hasBits
import com.android.server.pm.parsing.PackageInfoUtils
import com.android.server.pm.pkg.AndroidPackage
@@ -45,10 +44,8 @@
import com.android.server.testutils.any
import com.android.server.testutils.mock
import com.android.server.testutils.whenever
-import com.google.common.truth.Truth.assertWithMessage
import org.junit.Before
import org.junit.Rule
-import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.ArgumentMatchers.anyLong
@@ -56,7 +53,7 @@
* Mocking unit test for AppIdPermissionPolicy.
*/
@RunWith(AndroidJUnit4::class)
-open class BaseAppIdPermissionPolicyTest {
+abstract class BaseAppIdPermissionPolicyTest {
protected lateinit var oldState: MutableAccessState
protected lateinit var newState: MutableAccessState
@@ -80,7 +77,7 @@
.build()
@Before
- open fun setUp() {
+ fun baseSetUp() {
oldState = MutableAccessState()
createUserState(USER_ID_0)
oldState.mutateExternalState().setPackageStates(ArrayMap())
@@ -139,78 +136,6 @@
}
}
- @Test
- fun testOnAppIdRemoved_appIdIsRemoved_permissionFlagsCleared() {
- val parsedPermission = mockParsedPermission(PERMISSION_NAME_0, PACKAGE_NAME_0)
- val permissionOwnerPackageState = mockPackageState(
- APP_ID_0,
- mockAndroidPackage(PACKAGE_NAME_0, permissions = listOf(parsedPermission))
- )
- val requestingPackageState = mockPackageState(
- APP_ID_1,
- mockAndroidPackage(PACKAGE_NAME_1, requestedPermissions = setOf(PERMISSION_NAME_0))
- )
- addPackageState(permissionOwnerPackageState)
- addPackageState(requestingPackageState)
- addPermission(parsedPermission)
- setPermissionFlags(APP_ID_1, USER_ID_0, PERMISSION_NAME_0, PermissionFlags.INSTALL_GRANTED)
-
- mutateState {
- with(appIdPermissionPolicy) {
- onAppIdRemoved(APP_ID_1)
- }
- }
-
- val actualFlags = getPermissionFlags(APP_ID_1, USER_ID_0, PERMISSION_NAME_0)
- val expectedNewFlags = 0
- assertWithMessage(
- "After onAppIdRemoved() is called for appId $APP_ID_1 that requests a permission" +
- " owns by appId $APP_ID_0 with existing permission flags. The actual permission" +
- " flags $actualFlags should be null"
- )
- .that(actualFlags)
- .isEqualTo(expectedNewFlags)
- }
-
- @Test
- fun testOnPackageRemoved_packageIsRemoved_permissionsAreTrimmedAndStatesAreEvaluated() {
- // TODO
- // shouldn't reuse test cases because it's really different despite it's also for
- // trim permission states. It's different because it's package removal
- }
-
- @Test
- fun testOnPackageInstalled_nonSystemAppIsInstalled_upgradeExemptFlagIsCleared() {
- // TODO
- // should be fine for it to be its own test cases and not to re-use
- // clearRestrictedPermissionImplicitExemption
- }
-
- @Test
- fun testOnPackageInstalled_systemAppIsInstalled_upgradeExemptFlagIsRetained() {
- // TODO
- }
-
- @Test
- fun testOnPackageInstalled_requestedPermissionAlsoRequestedBySystemApp_exemptFlagIsRetained() {
- // TODO
- }
-
- @Test
- fun testOnPackageInstalled_restrictedPermissionsNotExempt_getsRestrictionFlags() {
- // TODO
- }
-
- @Test
- fun testOnPackageInstalled_restrictedPermissionsIsExempted_clearsRestrictionFlags() {
- // TODO
- }
-
- @Test
- fun testOnStateMutated_notEmpty_isCalledForEachListener() {
- // TODO
- }
-
/**
* Mock an AndroidPackage with PACKAGE_NAME_0, PERMISSION_NAME_0 and PERMISSION_GROUP_NAME_0
*/
@@ -221,6 +146,15 @@
permissions = listOf(defaultPermissionTree, defaultPermission)
)
+ protected fun createSimplePermission(isTree: Boolean = false): Permission {
+ val parsedPermission = if (isTree) { defaultPermissionTree } else { defaultPermission }
+ val permissionInfo = PackageInfoUtils.generatePermissionInfo(
+ parsedPermission,
+ PackageManager.GET_META_DATA.toLong()
+ )!!
+ return Permission(permissionInfo, true, Permission.TYPE_MANIFEST, APP_ID_0)
+ }
+
protected inline fun mutateState(action: MutateStateScope.() -> Unit) {
newState = oldState.toMutable()
MutateStateScope(oldState, newState).action()
@@ -330,15 +264,26 @@
) {
state.mutateExternalState().apply {
setPackageStates(
- packageStates.toMutableMap().apply {
- put(packageState.packageName, packageState)
- }
+ packageStates.toMutableMap().apply { put(packageState.packageName, packageState) }
)
mutateAppIdPackageNames().mutateOrPut(packageState.appId) { MutableIndexedListSet() }
.add(packageState.packageName)
}
}
+ protected fun removePackageState(
+ packageState: PackageState,
+ state: MutableAccessState = oldState
+ ) {
+ state.mutateExternalState().apply {
+ setPackageStates(
+ packageStates.toMutableMap().apply { remove(packageState.packageName) }
+ )
+ mutateAppIdPackageNames().mutateOrPut(packageState.appId) { MutableIndexedListSet() }
+ .remove(packageState.packageName)
+ }
+ }
+
protected fun addDisabledSystemPackageState(
packageState: PackageState,
state: MutableAccessState = oldState
@@ -429,6 +374,7 @@
@JvmStatic protected val PERMISSION_NAME_0 = "permissionName0"
@JvmStatic protected val PERMISSION_NAME_1 = "permissionName1"
@JvmStatic protected val PERMISSION_NAME_2 = "permissionName2"
+ @JvmStatic protected val PERMISSION_BELONGS_TO_A_TREE = "permissionTree.permission"
@JvmStatic protected val PERMISSION_READ_EXTERNAL_STORAGE =
Manifest.permission.READ_EXTERNAL_STORAGE
@JvmStatic protected val PERMISSION_POST_NOTIFICATIONS =
diff --git a/services/tests/RemoteProvisioningServiceTests/OWNERS b/services/tests/RemoteProvisioningServiceTests/OWNERS
index 348f940..ea6dc72 100644
--- a/services/tests/RemoteProvisioningServiceTests/OWNERS
+++ b/services/tests/RemoteProvisioningServiceTests/OWNERS
@@ -1 +1 @@
-file:platform/frameworks/base:master:/core/java/android/security/rkp/OWNERS
+file:platform/frameworks/base:main:/core/java/android/security/rkp/OWNERS
diff --git a/services/tests/displayservicetests/src/com/android/server/display/BrightnessSynchronizerTest.java b/services/tests/displayservicetests/src/com/android/server/display/BrightnessSynchronizerTest.java
index 7a4327c..2fd6e5f 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/BrightnessSynchronizerTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/BrightnessSynchronizerTest.java
@@ -19,7 +19,6 @@
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.isA;
-import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
@@ -28,18 +27,15 @@
import android.content.Context;
import android.content.ContextWrapper;
import android.database.ContentObserver;
-import android.hardware.display.BrightnessInfo;
import android.hardware.display.DisplayManager;
import android.hardware.display.DisplayManager.DisplayListener;
import android.net.Uri;
import android.os.Handler;
-import android.os.PowerManager;
import android.os.UserHandle;
import android.os.test.TestLooper;
import android.provider.Settings;
import android.test.mock.MockContentResolver;
import android.view.Display;
-import android.view.DisplayAdjustments;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.filters.SmallTest;
@@ -63,7 +59,6 @@
private static final float EPSILON = 0.00001f;
private static final Uri BRIGHTNESS_URI =
Settings.System.getUriFor(Settings.System.SCREEN_BRIGHTNESS);
- private static final float BRIGHTNESS_MAX = 0.6f;
private Context mContext;
private MockContentResolver mContentResolverSpy;
@@ -71,7 +66,6 @@
private DisplayListener mDisplayListener;
private ContentObserver mContentObserver;
private TestLooper mTestLooper;
- private BrightnessSynchronizer mSynchronizer;
@Mock private DisplayManager mDisplayManagerMock;
@Captor private ArgumentCaptor<DisplayListener> mDisplayListenerCaptor;
@@ -80,17 +74,7 @@
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
-
- Display display = mock(Display.class);
- when(display.getDisplayAdjustments()).thenReturn(new DisplayAdjustments());
- BrightnessInfo info = new BrightnessInfo(PowerManager.BRIGHTNESS_INVALID_FLOAT,
- PowerManager.BRIGHTNESS_MIN, BRIGHTNESS_MAX,
- BrightnessInfo.HIGH_BRIGHTNESS_MODE_OFF, BRIGHTNESS_MAX,
- BrightnessInfo.BRIGHTNESS_MAX_REASON_NONE);
- when(display.getBrightnessInfo()).thenReturn(info);
-
- mContext = spy(new ContextWrapper(
- ApplicationProvider.getApplicationContext().createDisplayContext(display)));
+ mContext = spy(new ContextWrapper(ApplicationProvider.getApplicationContext()));
mContentResolverSpy = spy(new MockContentResolver(mContext));
mContentResolverSpy.addProvider(Settings.AUTHORITY, new FakeSettingsProvider());
when(mContext.getContentResolver()).thenReturn(mContentResolverSpy);
@@ -144,12 +128,13 @@
@Test
public void testSetSameIntValue_nothingUpdated() {
putFloatSetting(0.5f);
+ putIntSetting(128);
start();
- putIntSetting(fToI(0.5f));
+ putIntSetting(128);
advanceTime(10);
verify(mDisplayManagerMock, times(0)).setBrightness(
- eq(Display.DEFAULT_DISPLAY), eq(0.5f));
+ eq(Display.DEFAULT_DISPLAY), eq(iToF(128)));
}
@Test
@@ -169,13 +154,14 @@
// Verify that this update did not get sent to float, because synchronizer
// is still waiting for confirmation of its first value.
verify(mDisplayManagerMock, times(0)).setBrightness(
- Display.DEFAULT_DISPLAY, iToF(20));
+ eq(Display.DEFAULT_DISPLAY), eq(iToF(20)));
// Send the confirmation of the initial change. This should trigger the new value to
// finally be processed and we can verify that the new value (20) is sent.
putIntSetting(fToI(0.4f));
advanceTime(10);
- verify(mDisplayManagerMock).setBrightness(Display.DEFAULT_DISPLAY, iToF(20));
+ verify(mDisplayManagerMock).setBrightness(
+ eq(Display.DEFAULT_DISPLAY), eq(iToF(20)));
}
@@ -197,7 +183,8 @@
advanceTime(200);
// Verify that the new value gets sent because the timeout expired.
- verify(mDisplayManagerMock).setBrightness(Display.DEFAULT_DISPLAY, iToF(20));
+ verify(mDisplayManagerMock).setBrightness(
+ eq(Display.DEFAULT_DISPLAY), eq(iToF(20)));
// Send a confirmation of the initial event, BrightnessSynchronizer should treat this as a
// new event because the timeout had already expired
@@ -209,14 +196,14 @@
// Verify we sent what would have been the confirmation as a new event to displaymanager.
// We do both fToI and iToF because the conversions are not symmetric.
- verify(mDisplayManagerMock).setBrightness(Display.DEFAULT_DISPLAY,
- iToF(fToI(0.4f)));
+ verify(mDisplayManagerMock).setBrightness(
+ eq(Display.DEFAULT_DISPLAY), eq(iToF(fToI(0.4f))));
}
- private void start() {
- mSynchronizer = new BrightnessSynchronizer(mContext, mTestLooper.getLooper(),
+ private BrightnessSynchronizer start() {
+ BrightnessSynchronizer bs = new BrightnessSynchronizer(mContext, mTestLooper.getLooper(),
mClock::now);
- mSynchronizer.startSynchronizing();
+ bs.startSynchronizing();
verify(mDisplayManagerMock).registerDisplayListener(mDisplayListenerCaptor.capture(),
isA(Handler.class), eq(DisplayManager.EVENT_FLAG_DISPLAY_BRIGHTNESS));
mDisplayListener = mDisplayListenerCaptor.getValue();
@@ -224,6 +211,7 @@
verify(mContentResolverSpy).registerContentObserver(eq(BRIGHTNESS_URI), eq(false),
mContentObserverCaptor.capture(), eq(UserHandle.USER_ALL));
mContentObserver = mContentObserverCaptor.getValue();
+ return bs;
}
private int getIntSetting() throws Exception {
@@ -253,11 +241,11 @@
}
private int fToI(float brightness) {
- return mSynchronizer.brightnessFloatToIntSetting(brightness);
+ return BrightnessSynchronizer.brightnessFloatToInt(brightness);
}
private float iToF(int brightness) {
- return mSynchronizer.brightnessIntSettingToFloat(brightness);
+ return BrightnessSynchronizer.brightnessIntToFloat(brightness);
}
private void advanceTime(long timeMs) {
diff --git a/services/tests/displayservicetests/src/com/android/server/display/DisplayManagerServiceTest.java b/services/tests/displayservicetests/src/com/android/server/display/DisplayManagerServiceTest.java
index 306de52..2396905 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/DisplayManagerServiceTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/DisplayManagerServiceTest.java
@@ -71,7 +71,6 @@
import android.hardware.Sensor;
import android.hardware.SensorManager;
import android.hardware.display.BrightnessConfiguration;
-import android.hardware.display.BrightnessInfo;
import android.hardware.display.Curve;
import android.hardware.display.DisplayManager;
import android.hardware.display.DisplayManagerGlobal;
@@ -95,7 +94,6 @@
import android.os.RemoteException;
import android.view.ContentRecordingSession;
import android.view.Display;
-import android.view.DisplayAdjustments;
import android.view.DisplayCutout;
import android.view.DisplayEventReceiver;
import android.view.DisplayInfo;
@@ -103,6 +101,7 @@
import android.view.SurfaceControl;
import android.window.DisplayWindowPolicyController;
+import androidx.test.InstrumentationRegistry;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.filters.FlakyTest;
import androidx.test.filters.SmallTest;
@@ -333,11 +332,7 @@
LocalServices.removeServiceForTest(UserManagerInternal.class);
LocalServices.addService(UserManagerInternal.class, mMockUserManagerInternal);
// TODO: b/287945043
- Display display = mock(Display.class);
- when(display.getDisplayAdjustments()).thenReturn(new DisplayAdjustments());
- when(display.getBrightnessInfo()).thenReturn(mock(BrightnessInfo.class));
- mContext = spy(new ContextWrapper(
- ApplicationProvider.getApplicationContext().createDisplayContext(display)));
+ mContext = spy(new ContextWrapper(ApplicationProvider.getApplicationContext()));
mResources = Mockito.spy(mContext.getResources());
manageDisplaysPermission(/* granted= */ false);
when(mContext.getResources()).thenReturn(mResources);
@@ -1912,6 +1907,7 @@
@Test
public void testSettingTwoBrightnessConfigurationsOnMultiDisplay() {
+ Context mContext = InstrumentationRegistry.getInstrumentation().getContext();
DisplayManager displayManager = mContext.getSystemService(DisplayManager.class);
// get the first two internal displays
diff --git a/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java b/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java
index 25619b9..4c25a4b 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java
@@ -91,6 +91,7 @@
import java.util.Random;
import java.util.Set;
import java.util.function.Function;
+import java.util.stream.Collectors;
/**
* Build/Install/Run:
@@ -563,6 +564,38 @@
}
@Test
+ public void testTasksWithCorrectOrderOfLastActiveTime() {
+ mRecentTasks.setOnlyTestVisibleRange();
+ mRecentTasks.unloadUserDataFromMemoryLocked(TEST_USER_0_ID);
+
+ // Setup some tasks for the user
+ mTaskPersister.mUserTaskIdsOverride = new SparseBooleanArray();
+ mTaskPersister.mUserTaskIdsOverride.put(1, true);
+ mTaskPersister.mUserTaskIdsOverride.put(2, true);
+ mTaskPersister.mUserTaskIdsOverride.put(3, true);
+ mTaskPersister.mUserTasksOverride = new ArrayList<>();
+ mTaskPersister.mUserTasksOverride.add(createTaskBuilder(".UserTask1").build());
+ mTaskPersister.mUserTasksOverride.add(createTaskBuilder(".UserTask2").build());
+ mTaskPersister.mUserTasksOverride.add(createTaskBuilder(".UserTask3").build());
+
+ // Assert no user tasks are initially loaded
+ assertThat(mRecentTasks.usersWithRecentsLoadedLocked()).hasLength(0);
+
+ // Load tasks
+ mRecentTasks.loadUserRecentsLocked(TEST_USER_0_ID);
+ assertThat(mRecentTasks.usersWithRecentsLoadedLocked()).asList().contains(TEST_USER_0_ID);
+
+ // Sort the time descendingly so the order should be in-sync with task recency (most
+ // recent to least recent)
+ List<Task> tasksSortedByTime = mRecentTasks.getRawTasks().stream()
+ .sorted((o1, o2) -> Long.compare(o2.lastActiveTime, o1.lastActiveTime))
+ .collect(Collectors.toList());
+
+ assertTrue("Task order is not in sync with its recency",
+ mRecentTasks.getRawTasks().equals(tasksSortedByTime));
+ }
+
+ @Test
public void testOrderedIteration() {
mRecentTasks.setOnlyTestVisibleRange();
Task task1 = createTaskBuilder(".Task1").build();
diff --git a/tools/hoststubgen/hoststubgen/helper-runtime-src/com/android/hoststubgen/hosthelper/HostTestUtils.java b/tools/hoststubgen/hoststubgen/helper-runtime-src/com/android/hoststubgen/hosthelper/HostTestUtils.java
index f7719a6..95cbff9 100644
--- a/tools/hoststubgen/hoststubgen/helper-runtime-src/com/android/hoststubgen/hosthelper/HostTestUtils.java
+++ b/tools/hoststubgen/hoststubgen/helper-runtime-src/com/android/hoststubgen/hosthelper/HostTestUtils.java
@@ -38,6 +38,10 @@
private static final boolean SKIP_METHOD_LOG = "1".equals(System.getenv(
"HOSTTEST_SKIP_METHOD_LOG"));
+ /** If true, we won't print class load log. */
+ private static final boolean SKIP_CLASS_LOG = "1".equals(System.getenv(
+ "HOSTTEST_SKIP_CLASS_LOG"));
+
/** If true, we won't perform non-stub method direct call check. */
private static final boolean SKIP_NON_STUB_METHOD_CHECK = "1".equals(System.getenv(
"HOSTTEST_SKIP_NON_STUB_METHOD_CHECK"));
@@ -57,17 +61,34 @@
}
/**
- * Called from methods with FilterPolicy.Log.
+ * Trampoline method for method-call-hook.
+ */
+ public static void callMethodCallHook(
+ Class<?> methodClass,
+ String methodName,
+ String methodDescriptor,
+ String callbackMethod
+ ) {
+ callStaticMethodByName(callbackMethod, methodClass, methodName, methodDescriptor);
+ }
+
+ /**
+ * I can be used as
+ * {@code --default-method-call-hook
+ * com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall}.
+ *
+ * It logs every single methods called.
*/
public static void logMethodCall(
- String methodClass,
+ Class<?> methodClass,
String methodName,
String methodDescriptor
) {
if (SKIP_METHOD_LOG) {
return;
}
- logPrintStream.println("# " + methodClass + "." + methodName + methodDescriptor);
+ logPrintStream.println("# method called: " + methodClass.getCanonicalName() + "."
+ + methodName + methodDescriptor);
}
private static final StackWalker sStackWalker =
@@ -146,15 +167,19 @@
logPrintStream.println("! Class loaded: " + loadedClass.getCanonicalName()
+ " calling hook " + callbackMethod);
+ callStaticMethodByName(callbackMethod, loadedClass);
+ }
+
+ private static void callStaticMethodByName(String classAndMethodName, Object... args) {
// Forward the call to callbackMethod.
- final int lastPeriod = callbackMethod.lastIndexOf(".");
- final String className = callbackMethod.substring(0, lastPeriod);
- final String methodName = callbackMethod.substring(lastPeriod + 1);
+ final int lastPeriod = classAndMethodName.lastIndexOf(".");
+ final String className = classAndMethodName.substring(0, lastPeriod);
+ final String methodName = classAndMethodName.substring(lastPeriod + 1);
if (lastPeriod < 0 || className.isEmpty() || methodName.isEmpty()) {
throw new HostTestException(String.format(
"Unable to find class load hook: malformed method name \"%s\"",
- callbackMethod));
+ classAndMethodName));
}
Class<?> clazz = null;
@@ -169,13 +194,19 @@
"Unable to find class load hook: Class %s must be public", className));
}
+ Class<?>[] argTypes = new Class[args.length];
+ for (int i = 0; i < args.length; i++) {
+ argTypes[i] = args[i].getClass();
+ }
+
Method method = null;
try {
- method = clazz.getMethod(methodName, Class.class);
+ method = clazz.getMethod(methodName, argTypes);
} catch (Exception e) {
throw new HostTestException(String.format(
"Unable to find class load hook: class %s doesn't have method %s"
- + " (method must take exactly one parameter of type Class, and public static)",
+ + " (method must take exactly one parameter of type Class,"
+ + " and public static)",
className,
methodName), e);
}
@@ -186,7 +217,7 @@
methodName, className));
}
try {
- method.invoke(null, loadedClass);
+ method.invoke(null, args);
} catch (Exception e) {
throw new HostTestException(String.format(
"Unable to invoke class load hook %s.%s",
@@ -194,4 +225,18 @@
methodName), e);
}
}
+
+ /**
+ * I can be used as
+ * {@code --default-class-load-hook
+ * com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded}.
+ *
+ * It logs every loaded class.
+ */
+ public static void logClassLoaded(Class<?> clazz) {
+ if (SKIP_CLASS_LOG) {
+ return;
+ }
+ logPrintStream.println("# class loaded: " + clazz.getCanonicalName());
+ }
}
diff --git a/tools/hoststubgen/hoststubgen/hoststubgen-standard-options.txt b/tools/hoststubgen/hoststubgen/hoststubgen-standard-options.txt
index 828d2a3..3f87527 100644
--- a/tools/hoststubgen/hoststubgen/hoststubgen-standard-options.txt
+++ b/tools/hoststubgen/hoststubgen/hoststubgen-standard-options.txt
@@ -6,8 +6,10 @@
--enable-non-stub-method-check
# --no-non-stub-method-check
-# --enable-method-logging
-
+#--default-method-call-hook
+# com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+#--default-class-load-hook
+# com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
# Standard annotations.
# Note, each line is a single argument, so we need newlines after each `--xxx-annotation`.
diff --git a/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/HostStubGen.kt b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/HostStubGen.kt
index 8db4b69..7531759 100644
--- a/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/HostStubGen.kt
+++ b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/HostStubGen.kt
@@ -17,6 +17,7 @@
import com.android.hoststubgen.asm.ClassNodes
import com.android.hoststubgen.filters.AnnotationBasedFilter
+import com.android.hoststubgen.filters.DefaultHookInjectingFilter
import com.android.hoststubgen.filters.ClassWidePolicyPropagatingFilter
import com.android.hoststubgen.filters.ConstantFilter
import com.android.hoststubgen.filters.FilterPolicy
@@ -156,22 +157,29 @@
// This is used when a member (methods, fields, nested classes) don't get any polices
// from upper filters. e.g. when a method has no annotations, then this filter will apply
// the class-wide policy, if any. (if not, we'll fall back to the above filter.)
- val classWidePropagator = ClassWidePolicyPropagatingFilter(filter)
+ filter = ClassWidePolicyPropagatingFilter(filter)
+
+ // Inject default hooks from options.
+ filter = DefaultHookInjectingFilter(
+ options.defaultClassLoadHook,
+ options.defaultMethodCallHook,
+ filter
+ )
// Next, Java annotation based filter.
filter = AnnotationBasedFilter(
- errors,
- allClasses,
- options.stubAnnotations,
- options.keepAnnotations,
- options.stubClassAnnotations,
- options.keepClassAnnotations,
- options.throwAnnotations,
- options.removeAnnotations,
- options.substituteAnnotations,
- options.nativeSubstituteAnnotations,
- options.classLoadHookAnnotations,
- classWidePropagator
+ errors,
+ allClasses,
+ options.stubAnnotations,
+ options.keepAnnotations,
+ options.stubClassAnnotations,
+ options.keepClassAnnotations,
+ options.throwAnnotations,
+ options.removeAnnotations,
+ options.substituteAnnotations,
+ options.nativeSubstituteAnnotations,
+ options.classLoadHookAnnotations,
+ filter
)
// Next, "text based" filter, which allows to override polices without touching
diff --git a/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/HostStubGenOptions.kt b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/HostStubGenOptions.kt
index 9a54ecf..bbb7dab 100644
--- a/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/HostStubGenOptions.kt
+++ b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/HostStubGenOptions.kt
@@ -48,6 +48,9 @@
var nativeSubstituteAnnotations: MutableSet<String> = mutableSetOf(),
var classLoadHookAnnotations: MutableSet<String> = mutableSetOf(),
+ var defaultClassLoadHook: String? = null,
+ var defaultMethodCallHook: String? = null,
+
var intersectStubJars: MutableSet<String> = mutableSetOf(),
var policyOverrideFile: String? = null,
@@ -63,8 +66,6 @@
var enablePreTrace: Boolean = false,
var enablePostTrace: Boolean = false,
- var enableMethodLogging: Boolean = false,
-
var enableNonStubMethodCallDetection: Boolean = true,
) {
companion object {
@@ -151,6 +152,12 @@
ret.classLoadHookAnnotations +=
ensureUniqueAnnotation(ai.nextArgRequired(arg))
+ "--default-class-load-hook" ->
+ ret.defaultClassLoadHook = ai.nextArgRequired(arg)
+
+ "--default-method-call-hook" ->
+ ret.defaultMethodCallHook = ai.nextArgRequired(arg)
+
"--intersect-stub-jar" ->
ret.intersectStubJars += ai.nextArgRequired(arg).ensureFileExists()
@@ -167,9 +174,6 @@
"--enable-post-trace" -> ret.enablePostTrace = true
"--no-post-trace" -> ret.enablePostTrace = false
- "--enable-method-logging" -> ret.enableMethodLogging = true
- "--no-method-logging" -> ret.enableMethodLogging = false
-
"--enable-non-stub-method-check" -> ret.enableNonStubMethodCallDetection = true
"--no-non-stub-method-check" -> ret.enableNonStubMethodCallDetection = false
@@ -290,6 +294,8 @@
substituteAnnotations=$substituteAnnotations,
nativeSubstituteAnnotations=$nativeSubstituteAnnotations,
classLoadHookAnnotations=$classLoadHookAnnotations,
+ defaultClassLoadHook=$defaultClassLoadHook,
+ defaultMethodCallHook=$defaultMethodCallHook,
intersectStubJars=$intersectStubJars,
policyOverrideFile=$policyOverrideFile,
defaultPolicy=$defaultPolicy,
@@ -299,7 +305,6 @@
enableClassChecker=$enableClassChecker,
enablePreTrace=$enablePreTrace,
enablePostTrace=$enablePostTrace,
- enableMethodLogging=$enableMethodLogging,
enableNonStubMethodCallDetection=$enableNonStubMethodCallDetection,
}
""".trimIndent()
diff --git a/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/Utils.kt b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/Utils.kt
index 9fbd6d0..7d7852a 100644
--- a/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/Utils.kt
+++ b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/Utils.kt
@@ -31,3 +31,23 @@
// Remove surrounding whitespace.
return uncommented.trim()
}
+
+fun <T> addLists(a: List<T>, b: List<T>): List<T> {
+ if (a.isEmpty()) {
+ return b
+ }
+ if (b.isEmpty()) {
+ return a
+ }
+ return a + b
+}
+
+fun <T> addNonNullElement(a: List<T>, b: T?): List<T> {
+ if (b == null) {
+ return a
+ }
+ if (a.isEmpty()) {
+ return listOf(b)
+ }
+ return a + b
+}
\ No newline at end of file
diff --git a/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/AnnotationBasedFilter.kt b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/AnnotationBasedFilter.kt
index 454569d..3f492e8 100644
--- a/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/AnnotationBasedFilter.kt
+++ b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/AnnotationBasedFilter.kt
@@ -19,6 +19,7 @@
import com.android.hoststubgen.HostStubGenErrors
import com.android.hoststubgen.HostStubGenInternalException
import com.android.hoststubgen.InvalidAnnotationException
+import com.android.hoststubgen.addNonNullElement
import com.android.hoststubgen.asm.ClassNodes
import com.android.hoststubgen.asm.findAnnotationValueAsString
import com.android.hoststubgen.asm.findAnyAnnotation
@@ -253,14 +254,14 @@
return null
}
- override fun getClassLoadHook(className: String): String? {
- classes.getClass(className).let { cn ->
+ override fun getClassLoadHooks(className: String): List<String> {
+ val e = classes.getClass(className).let { cn ->
findAnyAnnotation(classLoadHookAnnotations,
cn.visibleAnnotations, cn.invisibleAnnotations)?.let { an ->
- return getAnnotationField(an, "value")?.toHumanReadableMethodName()
+ getAnnotationField(an, "value")?.toHumanReadableMethodName()
}
}
- return null
+ return addNonNullElement(super.getClassLoadHooks(className), e)
}
private data class MethodKey(val name: String, val desc: String)
diff --git a/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/DefaultHookInjectingFilter.kt b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/DefaultHookInjectingFilter.kt
new file mode 100644
index 0000000..d771003
--- /dev/null
+++ b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/DefaultHookInjectingFilter.kt
@@ -0,0 +1,53 @@
+/*
+ * 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.hoststubgen.filters
+
+import com.android.hoststubgen.addLists
+
+class DefaultHookInjectingFilter(
+ defaultClassLoadHook: String?,
+ defaultMethodCallHook: String?,
+ fallback: OutputFilter
+) : DelegatingFilter(fallback) {
+ /**
+ * Create a List containing a single element [e], if e != null. Otherwise, returns
+ * an empty list.
+ */
+ private fun toSingleList(e: String?): List<String> {
+ if (e == null) {
+ return emptyList()
+ }
+ return listOf(e)
+ }
+
+ private val defaultClassLoadHookAsList: List<String> = toSingleList(defaultClassLoadHook)
+ private val defaultMethodCallHookAsList: List<String> = toSingleList(defaultMethodCallHook)
+
+ override fun getClassLoadHooks(className: String): List<String> {
+ return addLists(super.getClassLoadHooks(className), defaultClassLoadHookAsList)
+ }
+
+ override fun getMethodCallHooks(
+ className: String,
+ methodName: String,
+ descriptor: String
+ ): List<String> {
+ return addLists(
+ super.getMethodCallHooks(className, methodName, descriptor),
+ defaultMethodCallHookAsList,
+ )
+ }
+}
\ No newline at end of file
diff --git a/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/DelegatingFilter.kt b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/DelegatingFilter.kt
index f0763c4..45f61c5 100644
--- a/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/DelegatingFilter.kt
+++ b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/DelegatingFilter.kt
@@ -66,7 +66,15 @@
return fallback.getNativeSubstitutionClass(className)
}
- override fun getClassLoadHook(className: String): String? {
- return fallback.getClassLoadHook(className)
+ override fun getClassLoadHooks(className: String): List<String> {
+ return fallback.getClassLoadHooks(className)
+ }
+
+ override fun getMethodCallHooks(
+ className: String,
+ methodName: String,
+ descriptor: String
+ ): List<String> {
+ return fallback.getMethodCallHooks(className, methodName, descriptor)
}
}
diff --git a/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/InMemoryOutputFilter.kt b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/InMemoryOutputFilter.kt
index f3551d4..5659a35 100644
--- a/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/InMemoryOutputFilter.kt
+++ b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/InMemoryOutputFilter.kt
@@ -16,6 +16,7 @@
package com.android.hoststubgen.filters
import com.android.hoststubgen.UnknownApiException
+import com.android.hoststubgen.addNonNullElement
import com.android.hoststubgen.asm.ClassNodes
import com.android.hoststubgen.asm.toHumanReadableClassName
import com.android.hoststubgen.asm.toHumanReadableMethodName
@@ -127,9 +128,9 @@
mNativeSubstitutionClasses[getClassKey(from)] = to.toHumanReadableClassName()
}
- override fun getClassLoadHook(className: String): String? {
- return mClassLoadHooks[getClassKey(className)]
- ?: super.getClassLoadHook(className)
+ override fun getClassLoadHooks(className: String): List<String> {
+ return addNonNullElement(super.getClassLoadHooks(className),
+ mClassLoadHooks[getClassKey(className)])
}
fun setClassLoadHook(className: String, methodName: String) {
diff --git a/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/OutputFilter.kt b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/OutputFilter.kt
index 392ee4b..3df16ff 100644
--- a/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/OutputFilter.kt
+++ b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/OutputFilter.kt
@@ -71,11 +71,22 @@
}
/**
- * Return a "class load hook" method name for a given class.
+ * Return a "class load hook" class name for a given class.
*
* (which corresponds to @HostSideTestClassLoadHook of the standard annotations.)
*/
- open fun getClassLoadHook(className: String): String? {
- return null
+ open fun getClassLoadHooks(className: String): List<String> {
+ return emptyList()
+ }
+
+ /**
+ * Return the "method call hook" class name.
+ *
+ * The class has to have a function with the following signature:
+ * `public static void onMethodCalled(Class<?> clazz, String name, String descriptor)`.
+ */
+ open fun getMethodCallHooks(className: String, methodName: String, descriptor: String):
+ List<String> {
+ return emptyList()
}
}
\ No newline at end of file
diff --git a/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/visitors/ImplGeneratingAdapter.kt b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/visitors/ImplGeneratingAdapter.kt
index ac06886..57b6689 100644
--- a/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/visitors/ImplGeneratingAdapter.kt
+++ b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/visitors/ImplGeneratingAdapter.kt
@@ -45,7 +45,7 @@
return policy.needsInImpl
}
- private var classLoadHookMethod: String? = null
+ private var classLoadHooks: List<String> = emptyList()
override fun visit(
version: Int,
@@ -57,22 +57,22 @@
) {
super.visit(version, access, name, signature, superName, interfaces)
- classLoadHookMethod = filter.getClassLoadHook(currentClassName)
+ classLoadHooks = filter.getClassLoadHooks(currentClassName)
// classLoadHookMethod is non-null, then we need to inject code to call it
// in the class initializer.
// If the target class already has a class initializer, then we need to inject code to it.
// Otherwise, we need to create one.
- classLoadHookMethod?.let { callback ->
- log.d(" ClassLoadHook: $callback")
+ if (classLoadHooks.isNotEmpty()) {
+ log.d(" ClassLoadHooks: $classLoadHooks")
if (!classes.hasClassInitializer(currentClassName)) {
- injectClassLoadHook(callback)
+ injectClassLoadHook()
}
}
}
- private fun injectClassLoadHook(callback: String) {
+ private fun injectClassLoadHook() {
writeRawMembers {
// Create a class initializer to call onClassLoaded().
// Each class can only have at most one class initializer, but the base class
@@ -87,7 +87,7 @@
// Method prologue
mv.visitCode()
- writeClassLoadHookCall(mv)
+ writeClassLoadHookCalls(mv)
mv.visitInsn(Opcodes.RETURN)
// Method epilogue
@@ -97,21 +97,23 @@
}
}
- private fun writeClassLoadHookCall(mv: MethodVisitor) {
- // First argument: the class type.
- mv.visitLdcInsn(Type.getType("L" + currentClassName + ";"))
+ private fun writeClassLoadHookCalls(mv: MethodVisitor) {
+ classLoadHooks.forEach { classLoadHook ->
+ // First argument: the class type.
+ mv.visitLdcInsn(Type.getType("L" + currentClassName + ";"))
- // Second argument: method name
- mv.visitLdcInsn(classLoadHookMethod)
+ // Second argument: method name
+ mv.visitLdcInsn(classLoadHook)
- // Call HostTestUtils.onClassLoaded().
- mv.visitMethodInsn(
- Opcodes.INVOKESTATIC,
- HostTestUtils.CLASS_INTERNAL_NAME,
- "onClassLoaded",
- "(Ljava/lang/Class;Ljava/lang/String;)V",
- false
- )
+ // Call HostTestUtils.onClassLoaded().
+ mv.visitMethodInsn(
+ Opcodes.INVOKESTATIC,
+ HostTestUtils.CLASS_INTERNAL_NAME,
+ "onClassLoaded",
+ "(Ljava/lang/Class;Ljava/lang/String;)V",
+ false
+ )
+ }
}
override fun updateAccessFlags(
@@ -138,20 +140,22 @@
var innerVisitor = superVisitor
// If method logging is enabled, inject call to the logging method.
- if (options.enableMethodLogging) {
- innerVisitor = LogInjectingMethodAdapter(
- access,
- name,
- descriptor,
- signature,
- exceptions,
- innerVisitor,
- )
+ val methodCallHooks = filter.getMethodCallHooks(currentClassName, name, descriptor)
+ if (methodCallHooks.isNotEmpty()) {
+ innerVisitor = MethodCallHookInjectingAdapter(
+ access,
+ name,
+ descriptor,
+ signature,
+ exceptions,
+ innerVisitor,
+ methodCallHooks,
+ )
}
// If this class already has a class initializer and a class load hook is needed, then
// we inject code.
- if (classLoadHookMethod != null &&
+ if (classLoadHooks.isNotEmpty() &&
name == CLASS_INITIALIZER_NAME &&
descriptor == CLASS_INITIALIZER_DESC) {
innerVisitor = ClassLoadHookInjectingMethodAdapter(
@@ -283,29 +287,37 @@
}
/**
- * A method adapter that injects a call to HostTestUtils.logMethodCall() to every method.
+ * Inject calls to the method call hooks.
*
* Note, when the target method is a constructor, it may contain calls to `super(...)` or
* `this(...)`. The logging code will be injected *before* such calls.
*/
- private inner class LogInjectingMethodAdapter(
+ private inner class MethodCallHookInjectingAdapter(
access: Int,
val name: String,
val descriptor: String,
signature: String?,
exceptions: Array<String>?,
- next: MethodVisitor?
+ next: MethodVisitor?,
+ val hooks: List<String>,
) : MethodVisitor(OPCODE_VERSION, next) {
override fun visitCode() {
super.visitCode()
- visitLdcInsn(currentClassName)
- visitLdcInsn(name)
- visitLdcInsn(descriptor)
- visitMethodInsn(Opcodes.INVOKESTATIC,
+
+ hooks.forEach { hook ->
+ mv.visitLdcInsn(Type.getType("L" + currentClassName + ";"))
+ visitLdcInsn(name)
+ visitLdcInsn(descriptor)
+ visitLdcInsn(hook)
+
+ visitMethodInsn(
+ Opcodes.INVOKESTATIC,
HostTestUtils.CLASS_INTERNAL_NAME,
- "logMethodCall",
- "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V",
- false)
+ "callMethodCallHook",
+ "(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V",
+ false
+ )
+ }
}
}
@@ -323,7 +335,7 @@
override fun visitCode() {
super.visitCode()
- writeClassLoadHookCall(this)
+ writeClassLoadHookCalls(this)
}
}
diff --git a/tools/hoststubgen/hoststubgen/test-tiny-framework/Android.bp b/tools/hoststubgen/hoststubgen/test-tiny-framework/Android.bp
index 8c76a61..05d6a43 100644
--- a/tools/hoststubgen/hoststubgen/test-tiny-framework/Android.bp
+++ b/tools/hoststubgen/hoststubgen/test-tiny-framework/Android.bp
@@ -53,6 +53,46 @@
],
}
+// Same as "hoststubgen-test-tiny-framework-host", but with more options, to test more hoststubgen
+// features.
+java_genrule_host {
+ name: "hoststubgen-test-tiny-framework-host-ext",
+ defaults: ["hoststubgen-command-defaults"],
+ cmd: hoststubgen_common_options +
+ "--in-jar $(location :hoststubgen-test-tiny-framework) " +
+ "--policy-override-file $(location policy-override-tiny-framework.txt) " +
+
+ // More options.
+ "--default-method-call-hook com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall " +
+ "--default-class-load-hook com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded ",
+ srcs: [
+ ":hoststubgen-test-tiny-framework",
+ "policy-override-tiny-framework.txt",
+ ],
+}
+
+java_genrule_host {
+ name: "hoststubgen-test-tiny-framework-host-ext-stub",
+ cmd: "cp $(in) $(out)",
+ srcs: [
+ ":hoststubgen-test-tiny-framework-host-ext{host_stub.jar}",
+ ],
+ out: [
+ "host_stub.jar",
+ ],
+}
+
+java_genrule_host {
+ name: "hoststubgen-test-tiny-framework-host-ext-impl",
+ cmd: "cp $(in) $(out)",
+ srcs: [
+ ":hoststubgen-test-tiny-framework-host-ext{host_impl.jar}",
+ ],
+ out: [
+ "host_impl.jar",
+ ],
+}
+
// Compile the test jar, using 2 rules.
// 1. Build the test against the stub.
java_library_host {
@@ -123,6 +163,30 @@
visibility: ["//visibility:private"],
}
+java_genrule_host {
+ name: "hoststubgen-test-tiny-framework-host-ext-stub-dump",
+ defaults: ["hoststubgen-jar-dump-defaults"],
+ srcs: [
+ ":hoststubgen-test-tiny-framework-host-ext-stub",
+ ],
+ out: [
+ "12-hoststubgen-test-tiny-framework-host-ext-stub-dump.txt",
+ ],
+ visibility: ["//visibility:private"],
+}
+
+java_genrule_host {
+ name: "hoststubgen-test-tiny-framework-host-ext-impl-dump",
+ defaults: ["hoststubgen-jar-dump-defaults"],
+ srcs: [
+ ":hoststubgen-test-tiny-framework-host-ext-impl",
+ ],
+ out: [
+ "13-hoststubgen-test-tiny-framework-host-ext-impl-dump.txt",
+ ],
+ visibility: ["//visibility:private"],
+}
+
// Run it with `atest`. Compare the dump of the jar files to the golden output.
python_test_host {
name: "tiny-framework-dump-test",
@@ -136,6 +200,8 @@
"hoststubgen-test-tiny-framework-host-stub-dump",
"hoststubgen-test-tiny-framework-host-impl-dump",
"hoststubgen-test-tiny-framework-orig-dump",
+ "hoststubgen-test-tiny-framework-host-ext-stub-dump",
+ "hoststubgen-test-tiny-framework-host-ext-impl-dump",
],
test_suites: ["general-tests"],
}
diff --git a/tools/hoststubgen/hoststubgen/test-tiny-framework/diff-and-update-golden.sh b/tools/hoststubgen/hoststubgen/test-tiny-framework/diff-and-update-golden.sh
index 4d58869..639fb16 100755
--- a/tools/hoststubgen/hoststubgen/test-tiny-framework/diff-and-update-golden.sh
+++ b/tools/hoststubgen/hoststubgen/test-tiny-framework/diff-and-update-golden.sh
@@ -112,7 +112,7 @@
if (( $three_way )) ; then
echo "# Running 3-way diff with meld..."
- run meld ${files[*]} &
+ run meld ${files[0]} ${files[1]} ${files[2]} &
fi
if (( $two_way )) ; then
diff --git a/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/12-hoststubgen-test-tiny-framework-host-ext-stub-dump.txt b/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/12-hoststubgen-test-tiny-framework-host-ext-stub-dump.txt
new file mode 100644
index 0000000..43ceec4
--- /dev/null
+++ b/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/12-hoststubgen-test-tiny-framework-host-ext-stub-dump.txt
@@ -0,0 +1,837 @@
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck$Impl.class
+ Compiled from "TinyFrameworkCallerCheck.java"
+class com.android.hoststubgen.test.tinyframework.TinyFrameworkCallerCheck$Impl
+ minor version: 0
+ major version: 61
+ flags: (0x0020) ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck$Impl
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 0, methods: 2, attributes: 4
+ private com.android.hoststubgen.test.tinyframework.TinyFrameworkCallerCheck$Impl();
+ descriptor: ()V
+ flags: (0x0002) ACC_PRIVATE
+ Code:
+ stack=3, locals=1, args_size=1
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+
+ public static int getOneStub();
+ descriptor: ()I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=3, locals=0, args_size=0
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+}
+InnerClasses:
+ private static #x= #x of #x; // Impl=class com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck$Impl of class com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck
+SourceFile: "TinyFrameworkCallerCheck.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedStubClass
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck.class
+ Compiled from "TinyFrameworkCallerCheck.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkCallerCheck
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 0, methods: 3, attributes: 5
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkCallerCheck();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=1, args_size=1
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+
+ public static int getOne_withCheck();
+ descriptor: ()I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=3, locals=0, args_size=0
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+
+ public static int getOne_noCheck();
+ descriptor: ()I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=3, locals=0, args_size=0
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+}
+InnerClasses:
+ private static #x= #x of #x; // Impl=class com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck$Impl of class com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck
+SourceFile: "TinyFrameworkCallerCheck.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedStubClass
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestWholeClassStub
+NestMembers:
+ com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck$Impl
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkClassAnnotations.class
+ Compiled from "TinyFrameworkClassAnnotations.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassAnnotations
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkClassAnnotations
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 1, methods: 5, attributes: 3
+ public int stub;
+ descriptor: I
+ flags: (0x0001) ACC_PUBLIC
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkClassAnnotations();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=1, args_size=1
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+
+ public int addOne(int);
+ descriptor: (I)I
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=2, args_size=2
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+
+ public int addTwo(int);
+ descriptor: (I)I
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=2, args_size=2
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+
+ public static int nativeAddThree(int);
+ descriptor: (I)I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=3, locals=1, args_size=1
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+
+ public java.lang.String visibleButUsesUnsupportedMethod();
+ descriptor: ()Ljava/lang/String;
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=1, args_size=1
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+}
+SourceFile: "TinyFrameworkClassAnnotations.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedStubClass
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+ x: #x(#x=s#x)
+ android.hosttest.annotation.HostSideTestClassLoadHook(
+ value="com.android.hoststubgen.test.tinyframework.TinyFrameworkClassLoadHook.onClassLoaded"
+ )
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkClassClassWideAnnotations.class
+ Compiled from "TinyFrameworkClassClassWideAnnotations.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassClassWideAnnotations
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkClassClassWideAnnotations
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 3, methods: 8, attributes: 3
+ public int stub;
+ descriptor: I
+ flags: (0x0001) ACC_PUBLIC
+
+ public int keep;
+ descriptor: I
+ flags: (0x0001) ACC_PUBLIC
+
+ public int remove;
+ descriptor: I
+ flags: (0x0001) ACC_PUBLIC
+
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkClassClassWideAnnotations();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=1, args_size=1
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+
+ public int addOne(int);
+ descriptor: (I)I
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=2, args_size=2
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+
+ public int addOneInner(int);
+ descriptor: (I)I
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=2, args_size=2
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+
+ public void toBeRemoved(java.lang.String);
+ descriptor: (Ljava/lang/String;)V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=2, args_size=2
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+
+ public int addTwo(int);
+ descriptor: (I)I
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=2, args_size=2
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+
+ public static int nativeAddThree(int);
+ descriptor: (I)I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=3, locals=1, args_size=1
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+
+ public java.lang.String unsupportedMethod();
+ descriptor: ()Ljava/lang/String;
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=1, args_size=1
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+
+ public java.lang.String visibleButUsesUnsupportedMethod();
+ descriptor: ()Ljava/lang/String;
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=1, args_size=1
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+}
+SourceFile: "TinyFrameworkClassClassWideAnnotations.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedStubClass
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestWholeClassStub
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkClassLoadHook.class
+ Compiled from "TinyFrameworkClassLoadHook.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassLoadHook
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkClassLoadHook
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 1, methods: 3, attributes: 3
+ public static final java.util.Set<java.lang.Class<?>> sLoadedClasses;
+ descriptor: Ljava/util/Set;
+ flags: (0x0019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL
+ Signature: #x // Ljava/util/Set<Ljava/lang/Class<*>;>;
+
+ private com.android.hoststubgen.test.tinyframework.TinyFrameworkClassLoadHook();
+ descriptor: ()V
+ flags: (0x0002) ACC_PRIVATE
+ Code:
+ stack=3, locals=1, args_size=1
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+
+ public static void onClassLoaded(java.lang.Class<?>);
+ descriptor: (Ljava/lang/Class;)V
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=3, locals=1, args_size=1
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+ Signature: #x // (Ljava/lang/Class<*>;)V
+
+ static {};
+ descriptor: ()V
+ flags: (0x0008) ACC_STATIC
+ Code:
+ stack=3, locals=0, args_size=0
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+}
+SourceFile: "TinyFrameworkClassLoadHook.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedStubClass
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestWholeClassStub
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWithInitializer.class
+ Compiled from "TinyFrameworkClassWithInitializer.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassWithInitializer
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWithInitializer
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 1, methods: 2, attributes: 3
+ public static boolean sInitialized;
+ descriptor: Z
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkClassWithInitializer();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=1, args_size=1
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+
+ static {};
+ descriptor: ()V
+ flags: (0x0008) ACC_STATIC
+ Code:
+ stack=3, locals=0, args_size=0
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+}
+SourceFile: "TinyFrameworkClassWithInitializer.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedStubClass
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+RuntimeInvisibleAnnotations:
+ x: #x(#x=s#x)
+ android.hosttest.annotation.HostSideTestClassLoadHook(
+ value="com.android.hoststubgen.test.tinyframework.TinyFrameworkClassLoadHook.onClassLoaded"
+ )
+ x: #x()
+ android.hosttest.annotation.HostSideTestWholeClassStub
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkExceptionTester.class
+ Compiled from "TinyFrameworkExceptionTester.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkExceptionTester
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkExceptionTester
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 0, methods: 2, attributes: 3
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkExceptionTester();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=1, args_size=1
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+
+ public static int testException();
+ descriptor: ()I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=3, locals=0, args_size=0
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+}
+SourceFile: "TinyFrameworkExceptionTester.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedStubClass
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestWholeClassStub
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy.class
+ Compiled from "TinyFrameworkForTextPolicy.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkForTextPolicy
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 1, methods: 5, attributes: 2
+ public int stub;
+ descriptor: I
+ flags: (0x0001) ACC_PUBLIC
+
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkForTextPolicy();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=1, args_size=1
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+
+ public int addOne(int);
+ descriptor: (I)I
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=2, args_size=2
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+
+ public int addTwo(int);
+ descriptor: (I)I
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=2, args_size=2
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+
+ public static int nativeAddThree(int);
+ descriptor: (I)I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=3, locals=1, args_size=1
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+
+ public java.lang.String visibleButUsesUnsupportedMethod();
+ descriptor: ()Ljava/lang/String;
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=1, args_size=1
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+}
+SourceFile: "TinyFrameworkForTextPolicy.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedStubClass
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNative.class
+ Compiled from "TinyFrameworkNative.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNative
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNative
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 0, methods: 5, attributes: 3
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkNative();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=1, args_size=1
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+
+ public static native int nativeAddTwo(int);
+ descriptor: (I)I
+ flags: (0x0109) ACC_PUBLIC, ACC_STATIC, ACC_NATIVE
+
+ public static int nativeAddTwo_should_be_like_this(int);
+ descriptor: (I)I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=3, locals=1, args_size=1
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+
+ public static native long nativeLongPlus(long, long);
+ descriptor: (JJ)J
+ flags: (0x0109) ACC_PUBLIC, ACC_STATIC, ACC_NATIVE
+
+ public static long nativeLongPlus_should_be_like_this(long, long);
+ descriptor: (JJ)J
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=3, locals=4, args_size=2
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+}
+SourceFile: "TinyFrameworkNative.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedStubClass
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestWholeClassStub
+ x: #x(#x=s#x)
+ android.hosttest.annotation.HostSideTestNativeSubstitutionClass(
+ value="TinyFrameworkNative_host"
+ )
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass.class
+ Compiled from "TinyFrameworkNestedClasses.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$BaseClass
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 1, methods: 1, attributes: 4
+ public int value;
+ descriptor: I
+ flags: (0x0001) ACC_PUBLIC
+
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$BaseClass(int);
+ descriptor: (I)V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=2, args_size=2
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+}
+InnerClasses:
+ public static #x= #x of #x; // BaseClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+SourceFile: "TinyFrameworkNestedClasses.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedStubClass
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$InnerClass.class
+ Compiled from "TinyFrameworkNestedClasses.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$InnerClass
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$InnerClass
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 2, methods: 1, attributes: 5
+ public int value;
+ descriptor: I
+ flags: (0x0001) ACC_PUBLIC
+
+ final com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses this$0;
+ descriptor: Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;
+ flags: (0x1010) ACC_FINAL, ACC_SYNTHETIC
+
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$InnerClass(com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses);
+ descriptor: (Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;)V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=2, args_size=2
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+}
+InnerClasses:
+ public #x= #x of #x; // InnerClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$InnerClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+SourceFile: "TinyFrameworkNestedClasses.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedStubClass
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestWholeClassStub
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass.class
+ Compiled from "TinyFrameworkNestedClasses.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$StaticNestedClass
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 1, methods: 2, attributes: 5
+ public int value;
+ descriptor: I
+ flags: (0x0001) ACC_PUBLIC
+
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$StaticNestedClass();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=1, args_size=1
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+
+ public static java.util.function.Supplier<java.lang.Integer> getSupplier_static();
+ descriptor: ()Ljava/util/function/Supplier;
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=3, locals=0, args_size=0
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+ Signature: #x // ()Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+}
+InnerClasses:
+ public static #x= #x of #x; // StaticNestedClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+ #x; // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1
+SourceFile: "TinyFrameworkNestedClasses.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedStubClass
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestWholeClassStub
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$SubClass.class
+ Compiled from "TinyFrameworkNestedClasses.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$SubClass extends com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$BaseClass
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$SubClass
+ super_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass
+ interfaces: 0, fields: 0, methods: 1, attributes: 4
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$SubClass(int);
+ descriptor: (I)V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=2, args_size=2
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+}
+InnerClasses:
+ public static #x= #x of #x; // BaseClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+ public static #x= #x of #x; // SubClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$SubClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+SourceFile: "TinyFrameworkNestedClasses.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedStubClass
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses.class
+ Compiled from "TinyFrameworkNestedClasses.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 2, methods: 4, attributes: 5
+ public final java.util.function.Supplier<java.lang.Integer> mSupplier;
+ descriptor: Ljava/util/function/Supplier;
+ flags: (0x0011) ACC_PUBLIC, ACC_FINAL
+ Signature: #x // Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+
+ public static final java.util.function.Supplier<java.lang.Integer> sSupplier;
+ descriptor: Ljava/util/function/Supplier;
+ flags: (0x0019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL
+ Signature: #x // Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=1, args_size=1
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+
+ public java.util.function.Supplier<java.lang.Integer> getSupplier();
+ descriptor: ()Ljava/util/function/Supplier;
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=1, args_size=1
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+ Signature: #x // ()Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+
+ public static java.util.function.Supplier<java.lang.Integer> getSupplier_static();
+ descriptor: ()Ljava/util/function/Supplier;
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=3, locals=0, args_size=0
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+ Signature: #x // ()Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+
+ static {};
+ descriptor: ()V
+ flags: (0x0008) ACC_STATIC
+ Code:
+ stack=3, locals=0, args_size=0
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+}
+InnerClasses:
+ #x; // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1
+ #x; // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3
+ #x; // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4
+ #x; // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$2
+ public static #x= #x of #x; // SubClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$SubClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+ public static #x= #x of #x; // BaseClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+ public static #x= #x of #x; // StaticNestedClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+ public #x= #x of #x; // InnerClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$InnerClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+ #x; // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1
+SourceFile: "TinyFrameworkNestedClasses.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedStubClass
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestWholeClassStub
+NestMembers:
+ com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$SubClass
+ com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass
+ com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass
+ com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1
+ com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$InnerClass
+ com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4
+ com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3
+ com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$2
+ com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1
diff --git a/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/13-hoststubgen-test-tiny-framework-host-ext-impl-dump.txt b/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/13-hoststubgen-test-tiny-framework-host-ext-impl-dump.txt
new file mode 100644
index 0000000..874789e
--- /dev/null
+++ b/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/13-hoststubgen-test-tiny-framework-host-ext-impl-dump.txt
@@ -0,0 +1,2348 @@
+## Class: android/hosttest/annotation/HostSideTestClassLoadHook.class
+ Compiled from "HostSideTestClassLoadHook.java"
+public interface android.hosttest.annotation.HostSideTestClassLoadHook extends java.lang.annotation.Annotation
+ minor version: 0
+ major version: 61
+ flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
+ this_class: #x // android/hosttest/annotation/HostSideTestClassLoadHook
+ super_class: #x // java/lang/Object
+ interfaces: 1, fields: 0, methods: 2, attributes: 2
+ private static {};
+ descriptor: ()V
+ flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+ Code:
+ stack=2, locals=0, args_size=0
+ x: ldc #x // class android/hosttest/annotation/HostSideTestClassLoadHook
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+ x: return
+
+ public abstract java.lang.String value();
+ descriptor: ()Ljava/lang/String;
+ flags: (0x0401) ACC_PUBLIC, ACC_ABSTRACT
+}
+SourceFile: "HostSideTestClassLoadHook.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+ x: #x(#x=[e#x.#x])
+ java.lang.annotation.Target(
+ value=[Ljava/lang/annotation/ElementType;.TYPE]
+ )
+ x: #x(#x=e#x.#x)
+ java.lang.annotation.Retention(
+ value=Ljava/lang/annotation/RetentionPolicy;.CLASS
+ )
+## Class: android/hosttest/annotation/HostSideTestKeep.class
+ Compiled from "HostSideTestKeep.java"
+public interface android.hosttest.annotation.HostSideTestKeep extends java.lang.annotation.Annotation
+ minor version: 0
+ major version: 61
+ flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
+ this_class: #x // android/hosttest/annotation/HostSideTestKeep
+ super_class: #x // java/lang/Object
+ interfaces: 1, fields: 0, methods: 1, attributes: 2
+ private static {};
+ descriptor: ()V
+ flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+ Code:
+ stack=2, locals=0, args_size=0
+ x: ldc #x // class android/hosttest/annotation/HostSideTestKeep
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+ x: return
+}
+SourceFile: "HostSideTestKeep.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+ x: #x(#x=[e#x.#x,e#x.#x,e#x.#x,e#x.#x])
+ java.lang.annotation.Target(
+ value=[Ljava/lang/annotation/ElementType;.TYPE,Ljava/lang/annotation/ElementType;.FIELD,Ljava/lang/annotation/ElementType;.METHOD,Ljava/lang/annotation/ElementType;.CONSTRUCTOR]
+ )
+ x: #x(#x=e#x.#x)
+ java.lang.annotation.Retention(
+ value=Ljava/lang/annotation/RetentionPolicy;.CLASS
+ )
+## Class: android/hosttest/annotation/HostSideTestNativeSubstitutionClass.class
+ Compiled from "HostSideTestNativeSubstitutionClass.java"
+public interface android.hosttest.annotation.HostSideTestNativeSubstitutionClass extends java.lang.annotation.Annotation
+ minor version: 0
+ major version: 61
+ flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
+ this_class: #x // android/hosttest/annotation/HostSideTestNativeSubstitutionClass
+ super_class: #x // java/lang/Object
+ interfaces: 1, fields: 0, methods: 2, attributes: 2
+ private static {};
+ descriptor: ()V
+ flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+ Code:
+ stack=2, locals=0, args_size=0
+ x: ldc #x // class android/hosttest/annotation/HostSideTestNativeSubstitutionClass
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+ x: return
+
+ public abstract java.lang.String value();
+ descriptor: ()Ljava/lang/String;
+ flags: (0x0401) ACC_PUBLIC, ACC_ABSTRACT
+}
+SourceFile: "HostSideTestNativeSubstitutionClass.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+ x: #x(#x=[e#x.#x])
+ java.lang.annotation.Target(
+ value=[Ljava/lang/annotation/ElementType;.TYPE]
+ )
+ x: #x(#x=e#x.#x)
+ java.lang.annotation.Retention(
+ value=Ljava/lang/annotation/RetentionPolicy;.CLASS
+ )
+## Class: android/hosttest/annotation/HostSideTestRemove.class
+ Compiled from "HostSideTestRemove.java"
+public interface android.hosttest.annotation.HostSideTestRemove extends java.lang.annotation.Annotation
+ minor version: 0
+ major version: 61
+ flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
+ this_class: #x // android/hosttest/annotation/HostSideTestRemove
+ super_class: #x // java/lang/Object
+ interfaces: 1, fields: 0, methods: 1, attributes: 2
+ private static {};
+ descriptor: ()V
+ flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+ Code:
+ stack=2, locals=0, args_size=0
+ x: ldc #x // class android/hosttest/annotation/HostSideTestRemove
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+ x: return
+}
+SourceFile: "HostSideTestRemove.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+ x: #x(#x=[e#x.#x,e#x.#x,e#x.#x,e#x.#x])
+ java.lang.annotation.Target(
+ value=[Ljava/lang/annotation/ElementType;.TYPE,Ljava/lang/annotation/ElementType;.FIELD,Ljava/lang/annotation/ElementType;.METHOD,Ljava/lang/annotation/ElementType;.CONSTRUCTOR]
+ )
+ x: #x(#x=e#x.#x)
+ java.lang.annotation.Retention(
+ value=Ljava/lang/annotation/RetentionPolicy;.CLASS
+ )
+## Class: android/hosttest/annotation/HostSideTestStub.class
+ Compiled from "HostSideTestStub.java"
+public interface android.hosttest.annotation.HostSideTestStub extends java.lang.annotation.Annotation
+ minor version: 0
+ major version: 61
+ flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
+ this_class: #x // android/hosttest/annotation/HostSideTestStub
+ super_class: #x // java/lang/Object
+ interfaces: 1, fields: 0, methods: 1, attributes: 2
+ private static {};
+ descriptor: ()V
+ flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+ Code:
+ stack=2, locals=0, args_size=0
+ x: ldc #x // class android/hosttest/annotation/HostSideTestStub
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+ x: return
+}
+SourceFile: "HostSideTestStub.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+ x: #x(#x=[e#x.#x,e#x.#x,e#x.#x,e#x.#x])
+ java.lang.annotation.Target(
+ value=[Ljava/lang/annotation/ElementType;.TYPE,Ljava/lang/annotation/ElementType;.FIELD,Ljava/lang/annotation/ElementType;.METHOD,Ljava/lang/annotation/ElementType;.CONSTRUCTOR]
+ )
+ x: #x(#x=e#x.#x)
+ java.lang.annotation.Retention(
+ value=Ljava/lang/annotation/RetentionPolicy;.CLASS
+ )
+## Class: android/hosttest/annotation/HostSideTestSubstitute.class
+ Compiled from "HostSideTestSubstitute.java"
+public interface android.hosttest.annotation.HostSideTestSubstitute extends java.lang.annotation.Annotation
+ minor version: 0
+ major version: 61
+ flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
+ this_class: #x // android/hosttest/annotation/HostSideTestSubstitute
+ super_class: #x // java/lang/Object
+ interfaces: 1, fields: 0, methods: 2, attributes: 2
+ private static {};
+ descriptor: ()V
+ flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+ Code:
+ stack=2, locals=0, args_size=0
+ x: ldc #x // class android/hosttest/annotation/HostSideTestSubstitute
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+ x: return
+
+ public abstract java.lang.String suffix();
+ descriptor: ()Ljava/lang/String;
+ flags: (0x0401) ACC_PUBLIC, ACC_ABSTRACT
+}
+SourceFile: "HostSideTestSubstitute.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+ x: #x(#x=[e#x.#x])
+ java.lang.annotation.Target(
+ value=[Ljava/lang/annotation/ElementType;.METHOD]
+ )
+ x: #x(#x=e#x.#x)
+ java.lang.annotation.Retention(
+ value=Ljava/lang/annotation/RetentionPolicy;.CLASS
+ )
+## Class: android/hosttest/annotation/HostSideTestThrow.class
+ Compiled from "HostSideTestThrow.java"
+public interface android.hosttest.annotation.HostSideTestThrow extends java.lang.annotation.Annotation
+ minor version: 0
+ major version: 61
+ flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
+ this_class: #x // android/hosttest/annotation/HostSideTestThrow
+ super_class: #x // java/lang/Object
+ interfaces: 1, fields: 0, methods: 1, attributes: 2
+ private static {};
+ descriptor: ()V
+ flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+ Code:
+ stack=2, locals=0, args_size=0
+ x: ldc #x // class android/hosttest/annotation/HostSideTestThrow
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+ x: return
+}
+SourceFile: "HostSideTestThrow.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+ x: #x(#x=[e#x.#x,e#x.#x])
+ java.lang.annotation.Target(
+ value=[Ljava/lang/annotation/ElementType;.METHOD,Ljava/lang/annotation/ElementType;.CONSTRUCTOR]
+ )
+ x: #x(#x=e#x.#x)
+ java.lang.annotation.Retention(
+ value=Ljava/lang/annotation/RetentionPolicy;.CLASS
+ )
+## Class: android/hosttest/annotation/HostSideTestWholeClassKeep.class
+ Compiled from "HostSideTestWholeClassKeep.java"
+public interface android.hosttest.annotation.HostSideTestWholeClassKeep extends java.lang.annotation.Annotation
+ minor version: 0
+ major version: 61
+ flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
+ this_class: #x // android/hosttest/annotation/HostSideTestWholeClassKeep
+ super_class: #x // java/lang/Object
+ interfaces: 1, fields: 0, methods: 1, attributes: 2
+ private static {};
+ descriptor: ()V
+ flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+ Code:
+ stack=2, locals=0, args_size=0
+ x: ldc #x // class android/hosttest/annotation/HostSideTestWholeClassKeep
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+ x: return
+}
+SourceFile: "HostSideTestWholeClassKeep.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+ x: #x(#x=[e#x.#x])
+ java.lang.annotation.Target(
+ value=[Ljava/lang/annotation/ElementType;.TYPE]
+ )
+ x: #x(#x=e#x.#x)
+ java.lang.annotation.Retention(
+ value=Ljava/lang/annotation/RetentionPolicy;.CLASS
+ )
+## Class: android/hosttest/annotation/HostSideTestWholeClassStub.class
+ Compiled from "HostSideTestWholeClassStub.java"
+public interface android.hosttest.annotation.HostSideTestWholeClassStub extends java.lang.annotation.Annotation
+ minor version: 0
+ major version: 61
+ flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
+ this_class: #x // android/hosttest/annotation/HostSideTestWholeClassStub
+ super_class: #x // java/lang/Object
+ interfaces: 1, fields: 0, methods: 1, attributes: 2
+ private static {};
+ descriptor: ()V
+ flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+ Code:
+ stack=2, locals=0, args_size=0
+ x: ldc #x // class android/hosttest/annotation/HostSideTestWholeClassStub
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+ x: return
+}
+SourceFile: "HostSideTestWholeClassStub.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+ x: #x(#x=[e#x.#x])
+ java.lang.annotation.Target(
+ value=[Ljava/lang/annotation/ElementType;.TYPE]
+ )
+ x: #x(#x=e#x.#x)
+ java.lang.annotation.Retention(
+ value=Ljava/lang/annotation/RetentionPolicy;.CLASS
+ )
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck$Impl.class
+ Compiled from "TinyFrameworkCallerCheck.java"
+class com.android.hoststubgen.test.tinyframework.TinyFrameworkCallerCheck$Impl
+ minor version: 0
+ major version: 61
+ flags: (0x0020) ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck$Impl
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 0, methods: 4, attributes: 4
+ private static {};
+ descriptor: ()V
+ flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+ Code:
+ stack=2, locals=0, args_size=0
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck$Impl
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+ x: return
+
+ private com.android.hoststubgen.test.tinyframework.TinyFrameworkCallerCheck$Impl();
+ descriptor: ()V
+ flags: (0x0002) ACC_PRIVATE
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck$Impl
+ x: ldc #x // String <init>
+ x: ldc #x // String ()V
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck$Impl;
+
+ public static int getOneKeep();
+ descriptor: ()I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=4, locals=0, args_size=0
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck$Impl
+ x: ldc #x // String getOneKeep
+ x: ldc #x // String ()I
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: ldc #x // String com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck$Impl
+ x: ldc #x // String getOneKeep
+ x: ldc #x // String ()I
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.getStackWalker:()Ljava/lang/StackWalker;
+ x: invokevirtual #x // Method java/lang/StackWalker.getCallerClass:()Ljava/lang/Class;
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onNonStubMethodCalled:(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Class;)V
+ x: iconst_1
+ x: ireturn
+ LineNumberTable:
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+
+ public static int getOneStub();
+ descriptor: ()I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=4, locals=0, args_size=0
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck$Impl
+ x: ldc #x // String getOneStub
+ x: ldc #x // String ()I
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: iconst_1
+ x: ireturn
+ LineNumberTable:
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+}
+InnerClasses:
+ private static #x= #x of #x; // Impl=class com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck$Impl of class com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck
+SourceFile: "TinyFrameworkCallerCheck.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedStubClass
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck.class
+ Compiled from "TinyFrameworkCallerCheck.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkCallerCheck
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 0, methods: 4, attributes: 5
+ private static {};
+ descriptor: ()V
+ flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+ Code:
+ stack=2, locals=0, args_size=0
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+ x: return
+
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkCallerCheck();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck
+ x: ldc #x // String <init>
+ x: ldc #x // String ()V
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck;
+
+ public static int getOne_withCheck();
+ descriptor: ()I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=4, locals=0, args_size=0
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck
+ x: ldc #x // String getOne_withCheck
+ x: ldc #x // String ()I
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: invokestatic #x // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck$Impl.getOneKeep:()I
+ x: ireturn
+ LineNumberTable:
+
+ public static int getOne_noCheck();
+ descriptor: ()I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=4, locals=0, args_size=0
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck
+ x: ldc #x // String getOne_noCheck
+ x: ldc #x // String ()I
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: invokestatic #x // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck$Impl.getOneStub:()I
+ x: ireturn
+ LineNumberTable:
+}
+InnerClasses:
+ private static #x= #x of #x; // Impl=class com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck$Impl of class com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck
+SourceFile: "TinyFrameworkCallerCheck.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedStubClass
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestWholeClassStub
+NestMembers:
+ com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck$Impl
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkClassAnnotations.class
+ Compiled from "TinyFrameworkClassAnnotations.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassAnnotations
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkClassAnnotations
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 2, methods: 8, attributes: 3
+ public int stub;
+ descriptor: I
+ flags: (0x0001) ACC_PUBLIC
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+
+ public int keep;
+ descriptor: I
+ flags: (0x0001) ACC_PUBLIC
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+
+ private static {};
+ descriptor: ()V
+ flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+ Code:
+ stack=2, locals=0, args_size=0
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkClassAnnotations
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkClassAnnotations
+ x: ldc #x // String com.android.hoststubgen.test.tinyframework.TinyFrameworkClassLoadHook.onClassLoaded
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+ x: return
+
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkClassAnnotations();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkClassAnnotations
+ x: ldc #x // String <init>
+ x: ldc #x // String ()V
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: aload_0
+ x: iconst_1
+ x: putfield #x // Field stub:I
+ x: aload_0
+ x: iconst_2
+ x: putfield #x // Field keep:I
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 15 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassAnnotations;
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+
+ public int addOne(int);
+ descriptor: (I)I
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=2, args_size=2
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkClassAnnotations
+ x: ldc #x // String addOne
+ x: ldc #x // String (I)I
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: aload_0
+ x: iload_1
+ x: invokevirtual #x // Method addOneInner:(I)I
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 6 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassAnnotations;
+ 11 6 1 value I
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+
+ public int addOneInner(int);
+ descriptor: (I)I
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=2, args_size=2
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkClassAnnotations
+ x: ldc #x // String addOneInner
+ x: ldc #x // String (I)I
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: ldc #x // String com/android/hoststubgen/test/tinyframework/TinyFrameworkClassAnnotations
+ x: ldc #x // String addOneInner
+ x: ldc #x // String (I)I
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.getStackWalker:()Ljava/lang/StackWalker;
+ x: invokevirtual #x // Method java/lang/StackWalker.getCallerClass:()Ljava/lang/Class;
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onNonStubMethodCalled:(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Class;)V
+ x: iload_1
+ x: iconst_1
+ x: iadd
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 26 4 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassAnnotations;
+ 26 4 1 value I
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+
+ public int addTwo(int);
+ descriptor: (I)I
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=2, args_size=2
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkClassAnnotations
+ x: ldc #x // String addTwo
+ x: ldc #x // String (I)I
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: iload_1
+ x: iconst_2
+ x: iadd
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 4 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassAnnotations;
+ 11 4 1 value I
+
+ public static int nativeAddThree(int);
+ descriptor: (I)I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkClassAnnotations
+ x: ldc #x // String nativeAddThree
+ x: ldc #x // String (I)I
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: iload_0
+ x: iconst_3
+ x: iadd
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 4 0 value I
+
+ public java.lang.String unsupportedMethod();
+ descriptor: ()Ljava/lang/String;
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkClassAnnotations
+ x: ldc #x // String unsupportedMethod
+ x: ldc #x // String ()Ljava/lang/String;
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: ldc #x // String com/android/hoststubgen/test/tinyframework/TinyFrameworkClassAnnotations
+ x: ldc #x // String unsupportedMethod
+ x: ldc #x // String ()Ljava/lang/String;
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.getStackWalker:()Ljava/lang/StackWalker;
+ x: invokevirtual #x // Method java/lang/StackWalker.getCallerClass:()Ljava/lang/Class;
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onNonStubMethodCalled:(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Class;)V
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onThrowMethodCalled:()V
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Unreachable
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestThrow
+
+ public java.lang.String visibleButUsesUnsupportedMethod();
+ descriptor: ()Ljava/lang/String;
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkClassAnnotations
+ x: ldc #x // String visibleButUsesUnsupportedMethod
+ x: ldc #x // String ()Ljava/lang/String;
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: aload_0
+ x: invokevirtual #x // Method unsupportedMethod:()Ljava/lang/String;
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassAnnotations;
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+}
+SourceFile: "TinyFrameworkClassAnnotations.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedStubClass
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+ x: #x(#x=s#x)
+ android.hosttest.annotation.HostSideTestClassLoadHook(
+ value="com.android.hoststubgen.test.tinyframework.TinyFrameworkClassLoadHook.onClassLoaded"
+ )
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkClassClassWideAnnotations.class
+ Compiled from "TinyFrameworkClassClassWideAnnotations.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassClassWideAnnotations
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkClassClassWideAnnotations
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 3, methods: 9, attributes: 3
+ public int stub;
+ descriptor: I
+ flags: (0x0001) ACC_PUBLIC
+
+ public int keep;
+ descriptor: I
+ flags: (0x0001) ACC_PUBLIC
+
+ public int remove;
+ descriptor: I
+ flags: (0x0001) ACC_PUBLIC
+
+ private static {};
+ descriptor: ()V
+ flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+ Code:
+ stack=2, locals=0, args_size=0
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkClassClassWideAnnotations
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+ x: return
+
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkClassClassWideAnnotations();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkClassClassWideAnnotations
+ x: ldc #x // String <init>
+ x: ldc #x // String ()V
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: aload_0
+ x: iconst_1
+ x: putfield #x // Field stub:I
+ x: aload_0
+ x: iconst_2
+ x: putfield #x // Field keep:I
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 15 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassClassWideAnnotations;
+
+ public int addOne(int);
+ descriptor: (I)I
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=2, args_size=2
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkClassClassWideAnnotations
+ x: ldc #x // String addOne
+ x: ldc #x // String (I)I
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: aload_0
+ x: iload_1
+ x: invokevirtual #x // Method addOneInner:(I)I
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 6 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassClassWideAnnotations;
+ 11 6 1 value I
+
+ public int addOneInner(int);
+ descriptor: (I)I
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=2, args_size=2
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkClassClassWideAnnotations
+ x: ldc #x // String addOneInner
+ x: ldc #x // String (I)I
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: iload_1
+ x: iconst_1
+ x: iadd
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 4 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassClassWideAnnotations;
+ 11 4 1 value I
+
+ public void toBeRemoved(java.lang.String);
+ descriptor: (Ljava/lang/String;)V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=2, args_size=2
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkClassClassWideAnnotations
+ x: ldc #x // String toBeRemoved
+ x: ldc #x // String (Ljava/lang/String;)V
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":()V
+ x: athrow
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 8 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassClassWideAnnotations;
+ 11 8 1 foo Ljava/lang/String;
+
+ public int addTwo(int);
+ descriptor: (I)I
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=2, args_size=2
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkClassClassWideAnnotations
+ x: ldc #x // String addTwo
+ x: ldc #x // String (I)I
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: iload_1
+ x: iconst_2
+ x: iadd
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 4 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassClassWideAnnotations;
+ 11 4 1 value I
+
+ public static int nativeAddThree(int);
+ descriptor: (I)I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkClassClassWideAnnotations
+ x: ldc #x // String nativeAddThree
+ x: ldc #x // String (I)I
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: iload_0
+ x: iconst_3
+ x: iadd
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 4 0 value I
+
+ public java.lang.String unsupportedMethod();
+ descriptor: ()Ljava/lang/String;
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkClassClassWideAnnotations
+ x: ldc #x // String unsupportedMethod
+ x: ldc #x // String ()Ljava/lang/String;
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: ldc #x // String This value shouldn\'t be seen on the host side.
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 3 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassClassWideAnnotations;
+
+ public java.lang.String visibleButUsesUnsupportedMethod();
+ descriptor: ()Ljava/lang/String;
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkClassClassWideAnnotations
+ x: ldc #x // String visibleButUsesUnsupportedMethod
+ x: ldc #x // String ()Ljava/lang/String;
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: aload_0
+ x: invokevirtual #x // Method unsupportedMethod:()Ljava/lang/String;
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassClassWideAnnotations;
+}
+SourceFile: "TinyFrameworkClassClassWideAnnotations.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedStubClass
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestWholeClassStub
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkClassLoadHook.class
+ Compiled from "TinyFrameworkClassLoadHook.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassLoadHook
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkClassLoadHook
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 1, methods: 3, attributes: 3
+ public static final java.util.Set<java.lang.Class<?>> sLoadedClasses;
+ descriptor: Ljava/util/Set;
+ flags: (0x0019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL
+ Signature: #x // Ljava/util/Set<Ljava/lang/Class<*>;>;
+
+ private com.android.hoststubgen.test.tinyframework.TinyFrameworkClassLoadHook();
+ descriptor: ()V
+ flags: (0x0002) ACC_PRIVATE
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkClassLoadHook
+ x: ldc #x // String <init>
+ x: ldc #x // String ()V
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassLoadHook;
+
+ public static void onClassLoaded(java.lang.Class<?>);
+ descriptor: (Ljava/lang/Class;)V
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkClassLoadHook
+ x: ldc #x // String onClassLoaded
+ x: ldc #x // String (Ljava/lang/Class;)V
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: getstatic #x // Field sLoadedClasses:Ljava/util/Set;
+ x: aload_0
+ x: invokeinterface #x, 2 // InterfaceMethod java/util/Set.add:(Ljava/lang/Object;)Z
+ x: pop
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 11 0 clazz Ljava/lang/Class;
+ LocalVariableTypeTable:
+ Start Length Slot Name Signature
+ 11 11 0 clazz Ljava/lang/Class<*>;
+ Signature: #x // (Ljava/lang/Class<*>;)V
+
+ static {};
+ descriptor: ()V
+ flags: (0x0008) ACC_STATIC
+ Code:
+ stack=4, locals=0, args_size=0
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkClassLoadHook
+ x: ldc #x // String <clinit>
+ x: ldc #x // String ()V
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkClassLoadHook
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+ x: new #x // class java/util/HashSet
+ x: dup
+ x: invokespecial #x // Method java/util/HashSet."<init>":()V
+ x: putstatic #x // Field sLoadedClasses:Ljava/util/Set;
+ x: return
+ LineNumberTable:
+}
+SourceFile: "TinyFrameworkClassLoadHook.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedStubClass
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestWholeClassStub
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWithInitializer.class
+ Compiled from "TinyFrameworkClassWithInitializer.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassWithInitializer
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWithInitializer
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 1, methods: 2, attributes: 3
+ public static boolean sInitialized;
+ descriptor: Z
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkClassWithInitializer();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWithInitializer
+ x: ldc #x // String <init>
+ x: ldc #x // String ()V
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassWithInitializer;
+
+ static {};
+ descriptor: ()V
+ flags: (0x0008) ACC_STATIC
+ Code:
+ stack=4, locals=0, args_size=0
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWithInitializer
+ x: ldc #x // String <clinit>
+ x: ldc #x // String ()V
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWithInitializer
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWithInitializer
+ x: ldc #x // String com.android.hoststubgen.test.tinyframework.TinyFrameworkClassLoadHook.onClassLoaded
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+ x: iconst_1
+ x: putstatic #x // Field sInitialized:Z
+ x: return
+ LineNumberTable:
+}
+SourceFile: "TinyFrameworkClassWithInitializer.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedStubClass
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+RuntimeInvisibleAnnotations:
+ x: #x(#x=s#x)
+ android.hosttest.annotation.HostSideTestClassLoadHook(
+ value="com.android.hoststubgen.test.tinyframework.TinyFrameworkClassLoadHook.onClassLoaded"
+ )
+ x: #x()
+ android.hosttest.annotation.HostSideTestWholeClassStub
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkExceptionTester.class
+ Compiled from "TinyFrameworkExceptionTester.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkExceptionTester
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkExceptionTester
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 0, methods: 3, attributes: 3
+ private static {};
+ descriptor: ()V
+ flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+ Code:
+ stack=2, locals=0, args_size=0
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkExceptionTester
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+ x: return
+
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkExceptionTester();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkExceptionTester
+ x: ldc #x // String <init>
+ x: ldc #x // String ()V
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkExceptionTester;
+
+ public static int testException();
+ descriptor: ()I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=4, locals=1, args_size=0
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkExceptionTester
+ x: ldc #x // String testException
+ x: ldc #x // String ()I
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: new #x // class java/lang/IllegalStateException
+ x: dup
+ x: ldc #x // String Inner exception
+ x: invokespecial #x // Method java/lang/IllegalStateException."<init>":(Ljava/lang/String;)V
+ x: athrow
+ x: astore_0
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Outer exception
+ x: aload_0
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;Ljava/lang/Throwable;)V
+ x: athrow
+ Exception table:
+ from to target type
+ 11 21 21 Class java/lang/Exception
+ StackMapTable: number_of_entries = 1
+ frame_type = 85 /* same_locals_1_stack_item */
+ stack = [ class java/lang/Exception ]
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 22 11 0 e Ljava/lang/Exception;
+}
+SourceFile: "TinyFrameworkExceptionTester.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedStubClass
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestWholeClassStub
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy.class
+ Compiled from "TinyFrameworkForTextPolicy.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkForTextPolicy
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 2, methods: 8, attributes: 2
+ public int stub;
+ descriptor: I
+ flags: (0x0001) ACC_PUBLIC
+
+ public int keep;
+ descriptor: I
+ flags: (0x0001) ACC_PUBLIC
+
+ private static {};
+ descriptor: ()V
+ flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+ Code:
+ stack=2, locals=0, args_size=0
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy
+ x: ldc #x // String com.android.hoststubgen.test.tinyframework.TinyFrameworkClassLoadHook.onClassLoaded
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+ x: return
+
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkForTextPolicy();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy
+ x: ldc #x // String <init>
+ x: ldc #x // String ()V
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: aload_0
+ x: iconst_1
+ x: putfield #x // Field stub:I
+ x: aload_0
+ x: iconst_2
+ x: putfield #x // Field keep:I
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 15 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy;
+
+ public int addOne(int);
+ descriptor: (I)I
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=2, args_size=2
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy
+ x: ldc #x // String addOne
+ x: ldc #x // String (I)I
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: aload_0
+ x: iload_1
+ x: invokevirtual #x // Method addOneInner:(I)I
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 6 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy;
+ 11 6 1 value I
+
+ public int addOneInner(int);
+ descriptor: (I)I
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=2, args_size=2
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy
+ x: ldc #x // String addOneInner
+ x: ldc #x // String (I)I
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: ldc #x // String com/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy
+ x: ldc #x // String addOneInner
+ x: ldc #x // String (I)I
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.getStackWalker:()Ljava/lang/StackWalker;
+ x: invokevirtual #x // Method java/lang/StackWalker.getCallerClass:()Ljava/lang/Class;
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onNonStubMethodCalled:(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Class;)V
+ x: iload_1
+ x: iconst_1
+ x: iadd
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 26 4 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy;
+ 26 4 1 value I
+
+ public int addTwo(int);
+ descriptor: (I)I
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=2, args_size=2
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy
+ x: ldc #x // String addTwo
+ x: ldc #x // String (I)I
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: iload_1
+ x: iconst_2
+ x: iadd
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 4 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy;
+ 11 4 1 value I
+
+ public static int nativeAddThree(int);
+ descriptor: (I)I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy
+ x: ldc #x // String nativeAddThree
+ x: ldc #x // String (I)I
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: iload_0
+ x: iconst_3
+ x: iadd
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 4 0 value I
+
+ public java.lang.String unsupportedMethod();
+ descriptor: ()Ljava/lang/String;
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy
+ x: ldc #x // String unsupportedMethod
+ x: ldc #x // String ()Ljava/lang/String;
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: ldc #x // String com/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy
+ x: ldc #x // String unsupportedMethod
+ x: ldc #x // String ()Ljava/lang/String;
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.getStackWalker:()Ljava/lang/StackWalker;
+ x: invokevirtual #x // Method java/lang/StackWalker.getCallerClass:()Ljava/lang/Class;
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onNonStubMethodCalled:(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Class;)V
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onThrowMethodCalled:()V
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Unreachable
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+
+ public java.lang.String visibleButUsesUnsupportedMethod();
+ descriptor: ()Ljava/lang/String;
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy
+ x: ldc #x // String visibleButUsesUnsupportedMethod
+ x: ldc #x // String ()Ljava/lang/String;
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: aload_0
+ x: invokevirtual #x // Method unsupportedMethod:()Ljava/lang/String;
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy;
+}
+SourceFile: "TinyFrameworkForTextPolicy.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedStubClass
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNative.class
+ Compiled from "TinyFrameworkNative.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNative
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNative
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 0, methods: 6, attributes: 3
+ private static {};
+ descriptor: ()V
+ flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+ Code:
+ stack=2, locals=0, args_size=0
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNative
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+ x: return
+
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkNative();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNative
+ x: ldc #x // String <init>
+ x: ldc #x // String ()V
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNative;
+
+ public static int nativeAddTwo(int);
+ descriptor: (I)I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=1, locals=1, args_size=1
+ x: iload_0
+ x: invokestatic #x // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host.nativeAddTwo:(I)I
+ x: ireturn
+
+ public static int nativeAddTwo_should_be_like_this(int);
+ descriptor: (I)I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNative
+ x: ldc #x // String nativeAddTwo_should_be_like_this
+ x: ldc #x // String (I)I
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: iload_0
+ x: invokestatic #x // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host.nativeAddTwo:(I)I
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 5 0 arg I
+
+ public static long nativeLongPlus(long, long);
+ descriptor: (JJ)J
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=4, locals=4, args_size=2
+ x: lload_0
+ x: lload_2
+ x: invokestatic #x // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host.nativeLongPlus:(JJ)J
+ x: lreturn
+
+ public static long nativeLongPlus_should_be_like_this(long, long);
+ descriptor: (JJ)J
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=4, locals=4, args_size=2
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNative
+ x: ldc #x // String nativeLongPlus_should_be_like_this
+ x: ldc #x // String (JJ)J
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: lload_0
+ x: lload_2
+ x: invokestatic #x // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host.nativeLongPlus:(JJ)J
+ x: lreturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 6 0 arg1 J
+ 11 6 2 arg2 J
+}
+SourceFile: "TinyFrameworkNative.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedStubClass
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestWholeClassStub
+ x: #x(#x=s#x)
+ android.hosttest.annotation.HostSideTestNativeSubstitutionClass(
+ value="TinyFrameworkNative_host"
+ )
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host.class
+ Compiled from "TinyFrameworkNative_host.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNative_host
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 0, methods: 4, attributes: 3
+ private static {};
+ descriptor: ()V
+ flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+ Code:
+ stack=2, locals=0, args_size=0
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+ x: return
+
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkNative_host();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host
+ x: ldc #x // String <init>
+ x: ldc #x // String ()V
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: ldc #x // String com/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host
+ x: ldc #x // String <init>
+ x: ldc #x // String ()V
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.getStackWalker:()Ljava/lang/StackWalker;
+ x: invokevirtual #x // Method java/lang/StackWalker.getCallerClass:()Ljava/lang/Class;
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onNonStubMethodCalled:(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Class;)V
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 26 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host;
+
+ public static int nativeAddTwo(int);
+ descriptor: (I)I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host
+ x: ldc #x // String nativeAddTwo
+ x: ldc #x // String (I)I
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: ldc #x // String com/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host
+ x: ldc #x // String nativeAddTwo
+ x: ldc #x // String (I)I
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.getStackWalker:()Ljava/lang/StackWalker;
+ x: invokevirtual #x // Method java/lang/StackWalker.getCallerClass:()Ljava/lang/Class;
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onNonStubMethodCalled:(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Class;)V
+ x: iload_0
+ x: iconst_2
+ x: iadd
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 26 4 0 arg I
+
+ public static long nativeLongPlus(long, long);
+ descriptor: (JJ)J
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=4, locals=4, args_size=2
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host
+ x: ldc #x // String nativeLongPlus
+ x: ldc #x // String (JJ)J
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: ldc #x // String com/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host
+ x: ldc #x // String nativeLongPlus
+ x: ldc #x // String (JJ)J
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.getStackWalker:()Ljava/lang/StackWalker;
+ x: invokevirtual #x // Method java/lang/StackWalker.getCallerClass:()Ljava/lang/Class;
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onNonStubMethodCalled:(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Class;)V
+ x: lload_0
+ x: lload_2
+ x: ladd
+ x: lreturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 26 4 0 arg1 J
+ 26 4 2 arg2 J
+}
+SourceFile: "TinyFrameworkNative_host.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestWholeClassKeep
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1.class
+ Compiled from "TinyFrameworkNestedClasses.java"
+class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$1 extends java.lang.Object implements java.util.function.Supplier<java.lang.Integer>
+ minor version: 0
+ major version: 61
+ flags: (0x0020) ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1
+ super_class: #x // java/lang/Object
+ interfaces: 1, fields: 1, methods: 4, attributes: 6
+ final com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses this$0;
+ descriptor: Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;
+ flags: (0x1010) ACC_FINAL, ACC_SYNTHETIC
+
+ private static {};
+ descriptor: ()V
+ flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+ Code:
+ stack=2, locals=0, args_size=0
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+ x: return
+
+ com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$1(com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses);
+ descriptor: (Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;)V
+ flags: (0x0000)
+ Code:
+ stack=4, locals=2, args_size=2
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1
+ x: ldc #x // String <init>
+ x: ldc #x // String (Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;)V
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: aload_0
+ x: aload_1
+ x: putfield #x // Field this$0:Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 10 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1;
+ 11 10 1 this$0 Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;
+
+ public java.lang.Integer get();
+ descriptor: ()Ljava/lang/Integer;
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1
+ x: ldc #x // String get
+ x: ldc #x // String ()Ljava/lang/Integer;
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: ldc #x // String com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1
+ x: ldc #x // String get
+ x: ldc #x // String ()Ljava/lang/Integer;
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.getStackWalker:()Ljava/lang/StackWalker;
+ x: invokevirtual #x // Method java/lang/StackWalker.getCallerClass:()Ljava/lang/Class;
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onNonStubMethodCalled:(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Class;)V
+ x: iconst_1
+ x: invokestatic #x // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 26 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1;
+
+ public java.lang.Object get();
+ descriptor: ()Ljava/lang/Object;
+ flags: (0x1041) ACC_PUBLIC, ACC_BRIDGE, ACC_SYNTHETIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1
+ x: ldc #x // String get
+ x: ldc #x // String ()Ljava/lang/Object;
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: ldc #x // String com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1
+ x: ldc #x // String get
+ x: ldc #x // String ()Ljava/lang/Object;
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.getStackWalker:()Ljava/lang/StackWalker;
+ x: invokevirtual #x // Method java/lang/StackWalker.getCallerClass:()Ljava/lang/Class;
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onNonStubMethodCalled:(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Class;)V
+ x: aload_0
+ x: invokevirtual #x // Method get:()Ljava/lang/Integer;
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 26 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1;
+}
+InnerClasses:
+ #x; // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1
+EnclosingMethod: #x.#x // com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses
+Signature: #x // Ljava/lang/Object;Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+SourceFile: "TinyFrameworkNestedClasses.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$2.class
+ Compiled from "TinyFrameworkNestedClasses.java"
+class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$2 extends java.lang.Object implements java.util.function.Supplier<java.lang.Integer>
+ minor version: 0
+ major version: 61
+ flags: (0x0020) ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$2
+ super_class: #x // java/lang/Object
+ interfaces: 1, fields: 0, methods: 4, attributes: 6
+ private static {};
+ descriptor: ()V
+ flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+ Code:
+ stack=2, locals=0, args_size=0
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$2
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+ x: return
+
+ com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$2();
+ descriptor: ()V
+ flags: (0x0000)
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$2
+ x: ldc #x // String <init>
+ x: ldc #x // String ()V
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$2;
+
+ public java.lang.Integer get();
+ descriptor: ()Ljava/lang/Integer;
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$2
+ x: ldc #x // String get
+ x: ldc #x // String ()Ljava/lang/Integer;
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: ldc #x // String com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$2
+ x: ldc #x // String get
+ x: ldc #x // String ()Ljava/lang/Integer;
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.getStackWalker:()Ljava/lang/StackWalker;
+ x: invokevirtual #x // Method java/lang/StackWalker.getCallerClass:()Ljava/lang/Class;
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onNonStubMethodCalled:(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Class;)V
+ x: iconst_2
+ x: invokestatic #x // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 26 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$2;
+
+ public java.lang.Object get();
+ descriptor: ()Ljava/lang/Object;
+ flags: (0x1041) ACC_PUBLIC, ACC_BRIDGE, ACC_SYNTHETIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$2
+ x: ldc #x // String get
+ x: ldc #x // String ()Ljava/lang/Object;
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: ldc #x // String com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$2
+ x: ldc #x // String get
+ x: ldc #x // String ()Ljava/lang/Object;
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.getStackWalker:()Ljava/lang/StackWalker;
+ x: invokevirtual #x // Method java/lang/StackWalker.getCallerClass:()Ljava/lang/Class;
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onNonStubMethodCalled:(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Class;)V
+ x: aload_0
+ x: invokevirtual #x // Method get:()Ljava/lang/Integer;
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 26 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$2;
+}
+InnerClasses:
+ #x; // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$2
+EnclosingMethod: #x.#x // com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses
+Signature: #x // Ljava/lang/Object;Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+SourceFile: "TinyFrameworkNestedClasses.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3.class
+ Compiled from "TinyFrameworkNestedClasses.java"
+class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$3 extends java.lang.Object implements java.util.function.Supplier<java.lang.Integer>
+ minor version: 0
+ major version: 61
+ flags: (0x0020) ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3
+ super_class: #x // java/lang/Object
+ interfaces: 1, fields: 1, methods: 4, attributes: 6
+ final com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses this$0;
+ descriptor: Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;
+ flags: (0x1010) ACC_FINAL, ACC_SYNTHETIC
+
+ private static {};
+ descriptor: ()V
+ flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+ Code:
+ stack=2, locals=0, args_size=0
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+ x: return
+
+ com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$3(com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses);
+ descriptor: (Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;)V
+ flags: (0x0000)
+ Code:
+ stack=4, locals=2, args_size=2
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3
+ x: ldc #x // String <init>
+ x: ldc #x // String (Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;)V
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: aload_0
+ x: aload_1
+ x: putfield #x // Field this$0:Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 10 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3;
+ 11 10 1 this$0 Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;
+
+ public java.lang.Integer get();
+ descriptor: ()Ljava/lang/Integer;
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3
+ x: ldc #x // String get
+ x: ldc #x // String ()Ljava/lang/Integer;
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: ldc #x // String com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3
+ x: ldc #x // String get
+ x: ldc #x // String ()Ljava/lang/Integer;
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.getStackWalker:()Ljava/lang/StackWalker;
+ x: invokevirtual #x // Method java/lang/StackWalker.getCallerClass:()Ljava/lang/Class;
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onNonStubMethodCalled:(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Class;)V
+ x: iconst_3
+ x: invokestatic #x // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 26 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3;
+
+ public java.lang.Object get();
+ descriptor: ()Ljava/lang/Object;
+ flags: (0x1041) ACC_PUBLIC, ACC_BRIDGE, ACC_SYNTHETIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3
+ x: ldc #x // String get
+ x: ldc #x // String ()Ljava/lang/Object;
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: ldc #x // String com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3
+ x: ldc #x // String get
+ x: ldc #x // String ()Ljava/lang/Object;
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.getStackWalker:()Ljava/lang/StackWalker;
+ x: invokevirtual #x // Method java/lang/StackWalker.getCallerClass:()Ljava/lang/Class;
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onNonStubMethodCalled:(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Class;)V
+ x: aload_0
+ x: invokevirtual #x // Method get:()Ljava/lang/Integer;
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 26 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3;
+}
+InnerClasses:
+ #x; // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3
+EnclosingMethod: #x.#x // com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses.getSupplier
+Signature: #x // Ljava/lang/Object;Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+SourceFile: "TinyFrameworkNestedClasses.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4.class
+ Compiled from "TinyFrameworkNestedClasses.java"
+class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$4 extends java.lang.Object implements java.util.function.Supplier<java.lang.Integer>
+ minor version: 0
+ major version: 61
+ flags: (0x0020) ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4
+ super_class: #x // java/lang/Object
+ interfaces: 1, fields: 0, methods: 4, attributes: 6
+ private static {};
+ descriptor: ()V
+ flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+ Code:
+ stack=2, locals=0, args_size=0
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+ x: return
+
+ com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$4();
+ descriptor: ()V
+ flags: (0x0000)
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4
+ x: ldc #x // String <init>
+ x: ldc #x // String ()V
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4;
+
+ public java.lang.Integer get();
+ descriptor: ()Ljava/lang/Integer;
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4
+ x: ldc #x // String get
+ x: ldc #x // String ()Ljava/lang/Integer;
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: ldc #x // String com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4
+ x: ldc #x // String get
+ x: ldc #x // String ()Ljava/lang/Integer;
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.getStackWalker:()Ljava/lang/StackWalker;
+ x: invokevirtual #x // Method java/lang/StackWalker.getCallerClass:()Ljava/lang/Class;
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onNonStubMethodCalled:(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Class;)V
+ x: iconst_4
+ x: invokestatic #x // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 26 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4;
+
+ public java.lang.Object get();
+ descriptor: ()Ljava/lang/Object;
+ flags: (0x1041) ACC_PUBLIC, ACC_BRIDGE, ACC_SYNTHETIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4
+ x: ldc #x // String get
+ x: ldc #x // String ()Ljava/lang/Object;
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: ldc #x // String com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4
+ x: ldc #x // String get
+ x: ldc #x // String ()Ljava/lang/Object;
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.getStackWalker:()Ljava/lang/StackWalker;
+ x: invokevirtual #x // Method java/lang/StackWalker.getCallerClass:()Ljava/lang/Class;
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onNonStubMethodCalled:(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Class;)V
+ x: aload_0
+ x: invokevirtual #x // Method get:()Ljava/lang/Integer;
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 26 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4;
+}
+InnerClasses:
+ #x; // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4
+EnclosingMethod: #x.#x // com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses.getSupplier_static
+Signature: #x // Ljava/lang/Object;Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+SourceFile: "TinyFrameworkNestedClasses.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass.class
+ Compiled from "TinyFrameworkNestedClasses.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$BaseClass
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 1, methods: 2, attributes: 4
+ public int value;
+ descriptor: I
+ flags: (0x0001) ACC_PUBLIC
+
+ private static {};
+ descriptor: ()V
+ flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+ Code:
+ stack=2, locals=0, args_size=0
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+ x: return
+
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$BaseClass(int);
+ descriptor: (I)V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=2, args_size=2
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass
+ x: ldc #x // String <init>
+ x: ldc #x // String (I)V
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: aload_0
+ x: iload_1
+ x: putfield #x // Field value:I
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 10 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass;
+ 11 10 1 x I
+}
+InnerClasses:
+ public static #x= #x of #x; // BaseClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+SourceFile: "TinyFrameworkNestedClasses.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedStubClass
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$InnerClass.class
+ Compiled from "TinyFrameworkNestedClasses.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$InnerClass
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$InnerClass
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 2, methods: 2, attributes: 5
+ public int value;
+ descriptor: I
+ flags: (0x0001) ACC_PUBLIC
+
+ final com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses this$0;
+ descriptor: Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;
+ flags: (0x1010) ACC_FINAL, ACC_SYNTHETIC
+
+ private static {};
+ descriptor: ()V
+ flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+ Code:
+ stack=2, locals=0, args_size=0
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$InnerClass
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+ x: return
+
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$InnerClass(com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses);
+ descriptor: (Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;)V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=2, args_size=2
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$InnerClass
+ x: ldc #x // String <init>
+ x: ldc #x // String (Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;)V
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: aload_0
+ x: aload_1
+ x: putfield #x // Field this$0:Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: aload_0
+ x: iconst_5
+ x: putfield #x // Field value:I
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 15 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$InnerClass;
+ 11 15 1 this$0 Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;
+}
+InnerClasses:
+ public #x= #x of #x; // InnerClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$InnerClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+SourceFile: "TinyFrameworkNestedClasses.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedStubClass
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestWholeClassStub
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1.class
+ Compiled from "TinyFrameworkNestedClasses.java"
+class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$StaticNestedClass$1 extends java.lang.Object implements java.util.function.Supplier<java.lang.Integer>
+ minor version: 0
+ major version: 61
+ flags: (0x0020) ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1
+ super_class: #x // java/lang/Object
+ interfaces: 1, fields: 0, methods: 4, attributes: 6
+ private static {};
+ descriptor: ()V
+ flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+ Code:
+ stack=2, locals=0, args_size=0
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+ x: return
+
+ com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$StaticNestedClass$1();
+ descriptor: ()V
+ flags: (0x0000)
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1
+ x: ldc #x // String <init>
+ x: ldc #x // String ()V
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1;
+
+ public java.lang.Integer get();
+ descriptor: ()Ljava/lang/Integer;
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1
+ x: ldc #x // String get
+ x: ldc #x // String ()Ljava/lang/Integer;
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: ldc #x // String com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1
+ x: ldc #x // String get
+ x: ldc #x // String ()Ljava/lang/Integer;
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.getStackWalker:()Ljava/lang/StackWalker;
+ x: invokevirtual #x // Method java/lang/StackWalker.getCallerClass:()Ljava/lang/Class;
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onNonStubMethodCalled:(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Class;)V
+ x: bipush 7
+ x: invokestatic #x // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 26 6 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1;
+
+ public java.lang.Object get();
+ descriptor: ()Ljava/lang/Object;
+ flags: (0x1041) ACC_PUBLIC, ACC_BRIDGE, ACC_SYNTHETIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1
+ x: ldc #x // String get
+ x: ldc #x // String ()Ljava/lang/Object;
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: ldc #x // String com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1
+ x: ldc #x // String get
+ x: ldc #x // String ()Ljava/lang/Object;
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.getStackWalker:()Ljava/lang/StackWalker;
+ x: invokevirtual #x // Method java/lang/StackWalker.getCallerClass:()Ljava/lang/Class;
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onNonStubMethodCalled:(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Class;)V
+ x: aload_0
+ x: invokevirtual #x // Method get:()Ljava/lang/Integer;
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 26 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1;
+}
+InnerClasses:
+ public static #x= #x of #x; // StaticNestedClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+ #x; // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1
+EnclosingMethod: #x.#x // com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$StaticNestedClass.getSupplier_static
+Signature: #x // Ljava/lang/Object;Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+SourceFile: "TinyFrameworkNestedClasses.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass.class
+ Compiled from "TinyFrameworkNestedClasses.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$StaticNestedClass
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 1, methods: 3, attributes: 5
+ public int value;
+ descriptor: I
+ flags: (0x0001) ACC_PUBLIC
+
+ private static {};
+ descriptor: ()V
+ flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+ Code:
+ stack=2, locals=0, args_size=0
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+ x: return
+
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$StaticNestedClass();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass
+ x: ldc #x // String <init>
+ x: ldc #x // String ()V
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: aload_0
+ x: bipush 6
+ x: putfield #x // Field value:I
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 11 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass;
+
+ public static java.util.function.Supplier<java.lang.Integer> getSupplier_static();
+ descriptor: ()Ljava/util/function/Supplier;
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=4, locals=0, args_size=0
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass
+ x: ldc #x // String getSupplier_static
+ x: ldc #x // String ()Ljava/util/function/Supplier;
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: new #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1
+ x: dup
+ x: invokespecial #x // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1."<init>":()V
+ x: areturn
+ LineNumberTable:
+ Signature: #x // ()Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+}
+InnerClasses:
+ public static #x= #x of #x; // StaticNestedClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+ #x; // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1
+SourceFile: "TinyFrameworkNestedClasses.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedStubClass
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestWholeClassStub
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$SubClass.class
+ Compiled from "TinyFrameworkNestedClasses.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$SubClass extends com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$BaseClass
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$SubClass
+ super_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass
+ interfaces: 0, fields: 0, methods: 2, attributes: 4
+ private static {};
+ descriptor: ()V
+ flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+ Code:
+ stack=2, locals=0, args_size=0
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$SubClass
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+ x: return
+
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$SubClass(int);
+ descriptor: (I)V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=2, args_size=2
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$SubClass
+ x: ldc #x // String <init>
+ x: ldc #x // String (I)V
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: aload_0
+ x: iload_1
+ x: invokespecial #x // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass."<init>":(I)V
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 6 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$SubClass;
+ 11 6 1 x I
+}
+InnerClasses:
+ public static #x= #x of #x; // BaseClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+ public static #x= #x of #x; // SubClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$SubClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+SourceFile: "TinyFrameworkNestedClasses.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedStubClass
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses.class
+ Compiled from "TinyFrameworkNestedClasses.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 2, methods: 4, attributes: 5
+ public final java.util.function.Supplier<java.lang.Integer> mSupplier;
+ descriptor: Ljava/util/function/Supplier;
+ flags: (0x0011) ACC_PUBLIC, ACC_FINAL
+ Signature: #x // Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+
+ public static final java.util.function.Supplier<java.lang.Integer> sSupplier;
+ descriptor: Ljava/util/function/Supplier;
+ flags: (0x0019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL
+ Signature: #x // Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+ x: ldc #x // String <init>
+ x: ldc #x // String ()V
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: aload_0
+ x: new #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1
+ x: dup
+ x: aload_0
+ x: invokespecial #x // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1."<init>":(Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;)V
+ x: putfield #x // Field mSupplier:Ljava/util/function/Supplier;
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 17 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;
+
+ public java.util.function.Supplier<java.lang.Integer> getSupplier();
+ descriptor: ()Ljava/util/function/Supplier;
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+ x: ldc #x // String getSupplier
+ x: ldc #x // String ()Ljava/util/function/Supplier;
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: new #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3
+ x: dup
+ x: aload_0
+ x: invokespecial #x // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3."<init>":(Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;)V
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 9 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;
+ Signature: #x // ()Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+
+ public static java.util.function.Supplier<java.lang.Integer> getSupplier_static();
+ descriptor: ()Ljava/util/function/Supplier;
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=4, locals=0, args_size=0
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+ x: ldc #x // String getSupplier_static
+ x: ldc #x // String ()Ljava/util/function/Supplier;
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: new #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4
+ x: dup
+ x: invokespecial #x // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4."<init>":()V
+ x: areturn
+ LineNumberTable:
+ Signature: #x // ()Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+
+ static {};
+ descriptor: ()V
+ flags: (0x0008) ACC_STATIC
+ Code:
+ stack=4, locals=0, args_size=0
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+ x: ldc #x // String <clinit>
+ x: ldc #x // String ()V
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+ x: new #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$2
+ x: dup
+ x: invokespecial #x // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$2."<init>":()V
+ x: putstatic #x // Field sSupplier:Ljava/util/function/Supplier;
+ x: return
+ LineNumberTable:
+}
+InnerClasses:
+ #x; // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1
+ #x; // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3
+ #x; // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4
+ #x; // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$2
+ public static #x= #x of #x; // SubClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$SubClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+ public static #x= #x of #x; // BaseClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+ public static #x= #x of #x; // StaticNestedClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+ public #x= #x of #x; // InnerClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$InnerClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+ #x; // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1
+SourceFile: "TinyFrameworkNestedClasses.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedStubClass
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestWholeClassStub
+NestMembers:
+ com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$SubClass
+ com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass
+ com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass
+ com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1
+ com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$InnerClass
+ com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4
+ com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3
+ com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$2
+ com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1
diff --git a/tools/hoststubgen/scripts/run-all-tests.sh b/tools/hoststubgen/scripts/run-all-tests.sh
index 6bc0ddb..7600942 100755
--- a/tools/hoststubgen/scripts/run-all-tests.sh
+++ b/tools/hoststubgen/scripts/run-all-tests.sh
@@ -34,6 +34,7 @@
run ./hoststubgen/test-framework/run-test-without-atest.sh
run ./hoststubgen/test-tiny-framework/run-test-manually.sh
+run atest tiny-framework-dump-test
run ./scripts/build-framework-hostside-jars-and-extract.sh
# This script is already broken on goog/master
diff --git a/tools/lint/global/checks/src/main/java/com/google/android/lint/aidl/EnforcePermissionHelperDetector.kt b/tools/lint/global/checks/src/main/java/com/google/android/lint/aidl/EnforcePermissionHelperDetector.kt
index cbbf91b4..758de4d 100644
--- a/tools/lint/global/checks/src/main/java/com/google/android/lint/aidl/EnforcePermissionHelperDetector.kt
+++ b/tools/lint/global/checks/src/main/java/com/google/android/lint/aidl/EnforcePermissionHelperDetector.kt
@@ -131,7 +131,7 @@
priority = 6,
severity = Severity.ERROR,
implementation = Implementation(
- EnforcePermissionDetector::class.java,
+ EnforcePermissionHelperDetector::class.java,
EnumSet.of(Scope.JAVA_FILE, Scope.TEST_SOURCES)
)
)