diff options
119 files changed, 4892 insertions, 3014 deletions
diff --git a/core/api/current.txt b/core/api/current.txt index ed8ab06810f9..4e6dacff290e 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -8756,6 +8756,8 @@ package android.app.appfunctions { method public int getResultCode(); method @NonNull public android.app.appsearch.GenericDocument getResultDocument(); method public boolean isSuccess(); + method @FlaggedApi("android.app.appfunctions.flags.enable_app_function_manager") @NonNull public static android.app.appfunctions.ExecuteAppFunctionResponse newFailure(int, @Nullable String, @Nullable android.os.Bundle); + method @FlaggedApi("android.app.appfunctions.flags.enable_app_function_manager") @NonNull public static android.app.appfunctions.ExecuteAppFunctionResponse newSuccess(@NonNull android.app.appsearch.GenericDocument, @Nullable android.os.Bundle); method public void writeToParcel(@NonNull android.os.Parcel, int); field @NonNull public static final android.os.Parcelable.Creator<android.app.appfunctions.ExecuteAppFunctionResponse> CREATOR; field public static final String PROPERTY_RETURN_VALUE = "returnValue"; @@ -8767,13 +8769,6 @@ package android.app.appfunctions { field public static final int RESULT_TIMED_OUT = 5; // 0x5 } - @FlaggedApi("android.app.appfunctions.flags.enable_app_function_manager") public static final class ExecuteAppFunctionResponse.Builder { - ctor public ExecuteAppFunctionResponse.Builder(@NonNull android.app.appsearch.GenericDocument); - ctor public ExecuteAppFunctionResponse.Builder(int, @NonNull String); - method @NonNull public android.app.appfunctions.ExecuteAppFunctionResponse build(); - method @NonNull public android.app.appfunctions.ExecuteAppFunctionResponse.Builder setExtras(@NonNull android.os.Bundle); - } - } package android.app.assist { diff --git a/core/api/system-current.txt b/core/api/system-current.txt index f26522b9b919..3637ca763e0a 100644 --- a/core/api/system-current.txt +++ b/core/api/system-current.txt @@ -6746,6 +6746,14 @@ package android.hardware.soundtrigger { field public static final int STATUS_OK = 0; // 0x0 } + @FlaggedApi("android.media.soundtrigger.generic_model_api") public static final class SoundTrigger.GenericSoundModel extends android.hardware.soundtrigger.SoundTrigger.SoundModel implements android.os.Parcelable { + ctor public SoundTrigger.GenericSoundModel(@NonNull java.util.UUID, @NonNull java.util.UUID, @Nullable byte[], int); + ctor public SoundTrigger.GenericSoundModel(@NonNull java.util.UUID, @NonNull java.util.UUID, @Nullable byte[]); + method public int describeContents(); + method public void writeToParcel(@NonNull android.os.Parcel, int); + field @NonNull public static final android.os.Parcelable.Creator<android.hardware.soundtrigger.SoundTrigger.GenericSoundModel> CREATOR; + } + public static final class SoundTrigger.Keyphrase implements android.os.Parcelable { ctor public SoundTrigger.Keyphrase(int, int, @NonNull java.util.Locale, @NonNull String, @Nullable int[]); method public int describeContents(); diff --git a/core/java/android/app/appfunctions/AppFunctionManager.java b/core/java/android/app/appfunctions/AppFunctionManager.java index b6240a79dda8..0ee902632f5f 100644 --- a/core/java/android/app/appfunctions/AppFunctionManager.java +++ b/core/java/android/app/appfunctions/AppFunctionManager.java @@ -50,8 +50,7 @@ public final class AppFunctionManager { * Creates an instance. * * @param mService An interface to the backing service. - * @param context A {@link Context}. - * + * @param context A {@link Context}. * @hide */ public AppFunctionManager(IAppFunctionManager service, Context context) { @@ -108,8 +107,8 @@ public final class AppFunctionManager { } catch (RuntimeException e) { // Ideally shouldn't happen since errors are wrapped into the // response, but we catch it here for additional safety. - callback.accept(new ExecuteAppFunctionResponse.Builder( - getResultCode(e), e.getMessage()).build()); + callback.accept(ExecuteAppFunctionResponse.newFailure( + getResultCode(e), e.getMessage(), /*extras=*/ null)); } } }); diff --git a/core/java/android/app/appfunctions/AppFunctionService.java b/core/java/android/app/appfunctions/AppFunctionService.java index 6259d165d132..22bc9088f5e4 100644 --- a/core/java/android/app/appfunctions/AppFunctionService.java +++ b/core/java/android/app/appfunctions/AppFunctionService.java @@ -81,8 +81,9 @@ public abstract class AppFunctionService extends Service { // Apps should handle exceptions. But if they don't, report the error on // behalf of them. safeCallback.onResult( - new ExecuteAppFunctionResponse.Builder( - getResultCode(ex), getExceptionMessage(ex)).build()); + ExecuteAppFunctionResponse.newFailure( + getResultCode(ex), + ex.getMessage(), /*extras=*/ null)); } } }; @@ -117,8 +118,4 @@ public abstract class AppFunctionService extends Service { public abstract void onExecuteFunction( @NonNull ExecuteAppFunctionRequest request, @NonNull Consumer<ExecuteAppFunctionResponse> callback); - - private String getExceptionMessage(Exception exception) { - return exception.getMessage() == null ? "" : exception.getMessage(); - } } diff --git a/core/java/android/app/appfunctions/ExecuteAppFunctionResponse.java b/core/java/android/app/appfunctions/ExecuteAppFunctionResponse.java index 9fb3375a2446..58d4088f733e 100644 --- a/core/java/android/app/appfunctions/ExecuteAppFunctionResponse.java +++ b/core/java/android/app/appfunctions/ExecuteAppFunctionResponse.java @@ -162,6 +162,55 @@ public final class ExecuteAppFunctionResponse implements Parcelable { } /** + * Returns a successful response. + * + * @param resultDocument The return value of the executed function. + * @param extras The additional metadata data relevant to this function execution + * response. + */ + @NonNull + @FlaggedApi(FLAG_ENABLE_APP_FUNCTION_MANAGER) + public static ExecuteAppFunctionResponse newSuccess(@NonNull GenericDocument resultDocument, + @Nullable Bundle extras) { + Objects.requireNonNull(resultDocument); + Bundle actualExtras = getActualExtras(extras); + GenericDocumentWrapper resultDocumentWrapper = new GenericDocumentWrapper(resultDocument); + + return new ExecuteAppFunctionResponse( + resultDocumentWrapper, actualExtras, RESULT_OK, /*errorMessage=*/null); + } + + /** + * Returns a failure response. + * + * @param resultCode The result code of the app function execution. + * @param extras The additional metadata data relevant to this function execution + * response. + * @param errorMessage The error message associated with the result, if any. + */ + @NonNull + @FlaggedApi(FLAG_ENABLE_APP_FUNCTION_MANAGER) + public static ExecuteAppFunctionResponse newFailure(@ResultCode int resultCode, + @Nullable String errorMessage, + @Nullable Bundle extras) { + if (resultCode == RESULT_OK) { + throw new IllegalArgumentException("resultCode must not be RESULT_OK"); + } + Bundle actualExtras = getActualExtras(extras); + GenericDocumentWrapper emptyWrapper = new GenericDocumentWrapper( + new GenericDocument.Builder<>("", "", "").build()); + return new ExecuteAppFunctionResponse( + emptyWrapper, actualExtras, resultCode, errorMessage); + } + + private static Bundle getActualExtras(@Nullable Bundle extras) { + if (extras == null) { + return Bundle.EMPTY; + } + return extras; + } + + /** * Returns a generic document containing the return value of the executed function. * * <p>The {@link #PROPERTY_RETURN_VALUE} key can be used to obtain the return value.</p> @@ -250,64 +299,4 @@ public final class ExecuteAppFunctionResponse implements Parcelable { @Retention(RetentionPolicy.SOURCE) public @interface ResultCode { } - - /** - * The builder for creating {@link ExecuteAppFunctionResponse} instances. - */ - @FlaggedApi(FLAG_ENABLE_APP_FUNCTION_MANAGER) - public static final class Builder { - @NonNull - private GenericDocument mResultDocument = - new GenericDocument.Builder<>("", "", "").build(); - @NonNull - private Bundle mExtras = Bundle.EMPTY; - private int mResultCode; - @Nullable - private String mErrorMessage; - - /** - * Creates a new builder for {@link ExecuteAppFunctionResponse}. - */ - private Builder() { - } - - /** - * Creates a new builder for {@link ExecuteAppFunctionResponse} to build a success response - * with a result code of {@link #RESULT_OK} and a resultDocument. - */ - public Builder(@NonNull GenericDocument resultDocument) { - Objects.requireNonNull(resultDocument); - mResultDocument = resultDocument; - mResultCode = RESULT_OK; - } - - /** - * Creates a new builder for {@link ExecuteAppFunctionResponse} to build an error response - * with a result code and an error message. - */ - public Builder(@ResultCode int resultCode, - @NonNull String errorMessage) { - mResultCode = resultCode; - mErrorMessage = Objects.requireNonNull(errorMessage); - } - - /** - * Sets the extras of the app function execution. - */ - @NonNull - public Builder setExtras(@NonNull Bundle extras) { - mExtras = Objects.requireNonNull(extras); - return this; - } - - /** - * Builds the {@link ExecuteAppFunctionResponse} instance. - */ - @NonNull - public ExecuteAppFunctionResponse build() { - return new ExecuteAppFunctionResponse( - new GenericDocumentWrapper(mResultDocument), - mExtras, mResultCode, mErrorMessage); - } - } } diff --git a/core/java/android/hardware/input/InputManagerGlobal.java b/core/java/android/hardware/input/InputManagerGlobal.java index 03cf7c5f926c..2a362381a003 100644 --- a/core/java/android/hardware/input/InputManagerGlobal.java +++ b/core/java/android/hardware/input/InputManagerGlobal.java @@ -567,7 +567,7 @@ public final class InputManagerGlobal { Objects.requireNonNull(listener, "listener must not be null"); synchronized (mOnTabletModeChangedListeners) { - if (mOnTabletModeChangedListeners == null) { + if (mOnTabletModeChangedListeners.isEmpty()) { initializeTabletModeListenerLocked(); } int idx = findOnTabletModeChangedListenerLocked(listener); diff --git a/core/java/android/hardware/soundtrigger/SoundTrigger.java b/core/java/android/hardware/soundtrigger/SoundTrigger.java index bfff4dbdd627..9f3e3ad8c01e 100644 --- a/core/java/android/hardware/soundtrigger/SoundTrigger.java +++ b/core/java/android/hardware/soundtrigger/SoundTrigger.java @@ -29,6 +29,7 @@ import static android.system.OsConstants.EPIPE; import static java.util.Objects.requireNonNull; import android.annotation.ElapsedRealtimeLong; +import android.annotation.FlaggedApi; import android.annotation.IntDef; import android.annotation.IntRange; import android.annotation.NonNull; @@ -874,10 +875,9 @@ public class SoundTrigger { /***************************************************************************** * A GenericSoundModel is a specialized {@link SoundModel} for non-voice sound * patterns. - * - * @hide ****************************************************************************/ - public static class GenericSoundModel extends SoundModel implements Parcelable { + @FlaggedApi(android.media.soundtrigger.Flags.FLAG_GENERIC_MODEL_API) + public static final class GenericSoundModel extends SoundModel implements Parcelable { public static final @android.annotation.NonNull Parcelable.Creator<GenericSoundModel> CREATOR = new Parcelable.Creator<GenericSoundModel>() { @@ -890,11 +890,26 @@ public class SoundTrigger { } }; + /** + * Constructor for {@link GenericSoundModel} with version. + * + * @param uuid Unique identifier for this sound model. + * @param vendorUuid Unique vendor identifier for this sound model. + * @param data Opaque data for this sound model. + * @param version Vendor-specific version number of this sound model. + */ public GenericSoundModel(@NonNull UUID uuid, @NonNull UUID vendorUuid, @Nullable byte[] data, int version) { super(uuid, vendorUuid, TYPE_GENERIC_SOUND, data, version); } + /** + * Constructor for {@link GenericSoundModel} without version. The version is set to -1. + * + * @param uuid Unique identifier for this sound model. + * @param vendorUuid Unique vendor identifier for this sound model. + * @param data Opaque data for this sound model. + */ @UnsupportedAppUsage public GenericSoundModel(@NonNull UUID uuid, @NonNull UUID vendorUuid, @Nullable byte[] data) { @@ -919,7 +934,7 @@ public class SoundTrigger { } @Override - public void writeToParcel(Parcel dest, int flags) { + public void writeToParcel(@NonNull Parcel dest, int flags) { dest.writeString(getUuid().toString()); if (getVendorUuid() == null) { dest.writeInt(-1); diff --git a/core/java/android/os/Handler.java b/core/java/android/os/Handler.java index bd81fb9b891d..80f39bfbdc21 100644 --- a/core/java/android/os/Handler.java +++ b/core/java/android/os/Handler.java @@ -798,6 +798,12 @@ public class Handler { /** * Remove any pending posts of messages with code 'what' that are in the * message queue. + * + * Note that `Message#what` is 0 unless otherwise set. + * When calling `postMessage(Runnable)` or `postAtTime(Runnable, long)`, + * the `Runnable` is internally wrapped with a `Message` whose `what` is 0. + * Calling `removeMessages(0)` will remove all messages without a `what`, + * including posted `Runnable`s. */ public final void removeMessages(int what) { mQueue.removeMessages(this, what, null); diff --git a/core/java/android/os/Message.java b/core/java/android/os/Message.java index a1db9be0b693..702fdc2bbaa6 100644 --- a/core/java/android/os/Message.java +++ b/core/java/android/os/Message.java @@ -41,6 +41,9 @@ public final class Message implements Parcelable { * what this message is about. Each {@link Handler} has its own name-space * for message codes, so you do not need to worry about yours conflicting * with other handlers. + * + * If not specified, this value is 0. + * Use values other than 0 to indicate custom message codes. */ public int what; diff --git a/core/java/android/os/SharedMemory.java b/core/java/android/os/SharedMemory.java index a15b3bbd9b4e..46ae9d8682ee 100644 --- a/core/java/android/os/SharedMemory.java +++ b/core/java/android/os/SharedMemory.java @@ -381,9 +381,11 @@ public final class SharedMemory implements Parcelable, Closeable { private MemoryRegistration(int size) { // Round up to the nearest page size final int PAGE_SIZE = OsConstants._SC_PAGE_SIZE; - final int remainder = size % PAGE_SIZE; - if (remainder != 0) { - size += PAGE_SIZE - remainder; + if (PAGE_SIZE > 0) { + final int remainder = size % PAGE_SIZE; + if (remainder != 0) { + size += PAGE_SIZE - remainder; + } } mSize = size; mReferenceCount = 1; diff --git a/core/java/android/util/Half.java b/core/java/android/util/Half.java index fe536a6e4e68..22583acb75ce 100644 --- a/core/java/android/util/Half.java +++ b/core/java/android/util/Half.java @@ -19,6 +19,7 @@ package android.util; import android.annotation.HalfFloat; import android.annotation.NonNull; import android.annotation.Nullable; +import android.ravenwood.annotation.RavenwoodKeepWholeClass; import libcore.util.FP16; @@ -92,6 +93,7 @@ import libcore.util.FP16; * <p>This table shows that numbers higher than 1024 lose all fractional precision.</p> */ @SuppressWarnings("SimplifiableIfStatement") +@RavenwoodKeepWholeClass public final class Half extends Number implements Comparable<Half> { /** * The number of bits used to represent a half-precision float value. diff --git a/core/java/android/view/accessibility/AccessibilityManager.java b/core/java/android/view/accessibility/AccessibilityManager.java index a4cea3364998..ab29df357268 100644 --- a/core/java/android/view/accessibility/AccessibilityManager.java +++ b/core/java/android/view/accessibility/AccessibilityManager.java @@ -1051,6 +1051,52 @@ public final class AccessibilityManager { } /** + * Registers callback for when user initialization has completed. + * Does nothing if the same callback is already registered. + * + * @param callback The callback to be registered + * @hide + */ + public void registerUserInitializationCompleteCallback( + @NonNull IUserInitializationCompleteCallback callback) { + IAccessibilityManager service; + synchronized (mLock) { + service = getServiceLocked(); + if (service == null) { + return; + } + } + try { + service.registerUserInitializationCompleteCallback(callback); + } catch (RemoteException re) { + Log.e(LOG_TAG, "Error while registering userInitializationCompleteCallback. ", re); + } + } + + /** + * Unregisters callback for when user initialization has completed. + * + * @param callback The callback to be unregistered + * @hide + */ + public void unregisterUserInitializationCompleteCallback( + @NonNull IUserInitializationCompleteCallback callback) { + IAccessibilityManager service; + synchronized (mLock) { + service = getServiceLocked(); + if (service == null) { + return; + } + } + try { + service.unregisterUserInitializationCompleteCallback(callback); + } catch (RemoteException re) { + Log.e(LOG_TAG, + "Error while unregistering userInitializationCompleteCallback. ", re); + } + } + + /** * Whether the current accessibility request comes from an * {@link AccessibilityService} with the {@link AccessibilityServiceInfo#isAccessibilityTool} * property set to true. diff --git a/core/java/android/view/accessibility/IAccessibilityManager.aidl b/core/java/android/view/accessibility/IAccessibilityManager.aidl index 72a1fe424906..bf79a2c6c6ea 100644 --- a/core/java/android/view/accessibility/IAccessibilityManager.aidl +++ b/core/java/android/view/accessibility/IAccessibilityManager.aidl @@ -29,6 +29,7 @@ import android.view.accessibility.IAccessibilityInteractionConnection; import android.view.accessibility.IAccessibilityManagerClient; import android.view.accessibility.AccessibilityWindowAttributes; import android.view.accessibility.IMagnificationConnection; +import android.view.accessibility.IUserInitializationCompleteCallback; import android.view.InputEvent; import android.view.IWindow; import android.view.MagnificationSpec; @@ -192,4 +193,10 @@ interface IAccessibilityManager { @EnforcePermission("MANAGE_ACCESSIBILITY") Bundle getA11yFeatureToTileMap(int userId); + + @RequiresNoPermission + void registerUserInitializationCompleteCallback(IUserInitializationCompleteCallback callback); + + @RequiresNoPermission + void unregisterUserInitializationCompleteCallback(IUserInitializationCompleteCallback callback); } diff --git a/core/java/android/view/accessibility/IUserInitializationCompleteCallback.aidl b/core/java/android/view/accessibility/IUserInitializationCompleteCallback.aidl new file mode 100644 index 000000000000..fe6c8e25dd00 --- /dev/null +++ b/core/java/android/view/accessibility/IUserInitializationCompleteCallback.aidl @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.view.accessibility; + +/** + * A callback for when a new user finishes initializing + * NOTE: Must remain a oneway interface, as it is called from system_server while holding a lock. + * oneway allows it to return immediately and not hold the lock for longer than is necessary. + * @hide + */ + +oneway interface IUserInitializationCompleteCallback { + + /** + * Called when a user initialization completes. + * + * @param userId the id of the initialized user + */ + @RequiresNoPermission + void onUserInitializationComplete(int userId); +} diff --git a/core/java/com/android/internal/statusbar/StatusBarIcon.java b/core/java/com/android/internal/statusbar/StatusBarIcon.java index f8a143693c83..1938cdb0ba84 100644 --- a/core/java/com/android/internal/statusbar/StatusBarIcon.java +++ b/core/java/com/android/internal/statusbar/StatusBarIcon.java @@ -51,6 +51,19 @@ public class StatusBarIcon implements Parcelable { ResourceIcon } + public enum Shape { + /** + * Icon view should use WRAP_CONTENT -- so that the horizontal space occupied depends on the + * icon's shape (skinny/fat icons take less/more). Most icons will want to use this option + * for a nicer-looking overall spacing in the status bar, as long as the icon is "known" + * (i.e. not coming from a 3P package). + */ + WRAP_CONTENT, + + /** Icon should always be displayed in a space as wide as the status bar is tall. */ + FIXED_SPACE, + } + public UserHandle user; public String pkg; public Icon icon; @@ -59,6 +72,7 @@ public class StatusBarIcon implements Parcelable { public int number; public CharSequence contentDescription; public Type type; + public Shape shape; /** * Optional {@link Drawable} corresponding to {@link #icon}. This field is not parcelable, so @@ -68,7 +82,7 @@ public class StatusBarIcon implements Parcelable { @Nullable public Drawable preloadedIcon; public StatusBarIcon(UserHandle user, String resPackage, Icon icon, int iconLevel, int number, - CharSequence contentDescription, Type type) { + CharSequence contentDescription, Type type, Shape shape) { if (icon.getType() == Icon.TYPE_RESOURCE && TextUtils.isEmpty(icon.getResPackage())) { // This is an odd situation where someone's managed to hand us an icon without a @@ -83,6 +97,13 @@ public class StatusBarIcon implements Parcelable { this.number = number; this.contentDescription = contentDescription; this.type = type; + this.shape = shape; + } + + public StatusBarIcon(UserHandle user, String resPackage, Icon icon, int iconLevel, int number, + CharSequence contentDescription, Type type) { + this(user, resPackage, icon, iconLevel, number, contentDescription, type, + Shape.WRAP_CONTENT); } public StatusBarIcon(String iconPackage, UserHandle user, @@ -107,7 +128,7 @@ public class StatusBarIcon implements Parcelable { @Override public StatusBarIcon clone() { StatusBarIcon that = new StatusBarIcon(this.user, this.pkg, this.icon, - this.iconLevel, this.number, this.contentDescription, this.type); + this.iconLevel, this.number, this.contentDescription, this.type, this.shape); that.visible = this.visible; that.preloadedIcon = this.preloadedIcon; return that; @@ -129,6 +150,7 @@ public class StatusBarIcon implements Parcelable { this.number = in.readInt(); this.contentDescription = in.readCharSequence(); this.type = Type.valueOf(in.readString()); + this.shape = Shape.valueOf(in.readString()); } public void writeToParcel(Parcel out, int flags) { @@ -140,6 +162,7 @@ public class StatusBarIcon implements Parcelable { out.writeInt(this.number); out.writeCharSequence(this.contentDescription); out.writeString(this.type.name()); + out.writeString(this.shape.name()); } public int describeContents() { diff --git a/core/tests/coretests/src/com/android/internal/statusbar/StatusBarIconTest.java b/core/tests/coretests/src/com/android/internal/statusbar/StatusBarIconTest.java index b183ecb50591..149e132a0df4 100644 --- a/core/tests/coretests/src/com/android/internal/statusbar/StatusBarIconTest.java +++ b/core/tests/coretests/src/com/android/internal/statusbar/StatusBarIconTest.java @@ -20,6 +20,7 @@ import static com.google.common.truth.Truth.assertThat; import android.graphics.Color; import android.graphics.drawable.ColorDrawable; +import android.graphics.drawable.Icon; import android.os.Parcel; import android.os.UserHandle; @@ -69,22 +70,22 @@ public class StatusBarIconTest { assertThat(copy.preloadedIcon).isEqualTo(original.preloadedIcon); } - private static StatusBarIcon newStatusBarIcon() { final UserHandle dummyUserHandle = UserHandle.of(100); final String dummyIconPackageName = "com.android.internal.statusbar.test"; - final int dummyIconId = 123; + final Icon dummyIcon = Icon.createWithResource(dummyIconPackageName, 123); final int dummyIconLevel = 1; final int dummyIconNumber = 2; final CharSequence dummyIconContentDescription = "dummyIcon"; return new StatusBarIcon( - dummyIconPackageName, dummyUserHandle, - dummyIconId, + dummyIconPackageName, + dummyIcon, dummyIconLevel, dummyIconNumber, dummyIconContentDescription, - StatusBarIcon.Type.SystemIcon); + StatusBarIcon.Type.SystemIcon, + StatusBarIcon.Shape.FIXED_SPACE); } private static void assertSerializableFieldsEqual(StatusBarIcon copy, StatusBarIcon original) { @@ -96,6 +97,7 @@ public class StatusBarIconTest { assertThat(copy.number).isEqualTo(original.number); assertThat(copy.contentDescription).isEqualTo(original.contentDescription); assertThat(copy.type).isEqualTo(original.type); + assertThat(copy.shape).isEqualTo(original.shape); } private static StatusBarIcon parcelAndUnparcel(StatusBarIcon original) { diff --git a/graphics/java/android/graphics/Matrix44.java b/graphics/java/android/graphics/Matrix44.java index a99e20101c3b..683f6149a203 100644 --- a/graphics/java/android/graphics/Matrix44.java +++ b/graphics/java/android/graphics/Matrix44.java @@ -19,6 +19,7 @@ package android.graphics; import android.annotation.FlaggedApi; import android.annotation.IntRange; import android.annotation.NonNull; +import android.ravenwood.annotation.RavenwoodKeepWholeClass; import com.android.graphics.hwui.flags.Flags; @@ -30,6 +31,7 @@ import java.util.Arrays; * in row-major order. The values and operations are treated as column vectors. */ @FlaggedApi(Flags.FLAG_MATRIX_44) +@RavenwoodKeepWholeClass public class Matrix44 { final float[] mBackingArray; /** diff --git a/graphics/java/android/graphics/Outline.java b/graphics/java/android/graphics/Outline.java index 618e6dcc4433..c7b89412cc47 100644 --- a/graphics/java/android/graphics/Outline.java +++ b/graphics/java/android/graphics/Outline.java @@ -21,6 +21,7 @@ import android.annotation.IntDef; import android.annotation.NonNull; import android.compat.annotation.UnsupportedAppUsage; import android.graphics.drawable.Drawable; +import android.ravenwood.annotation.RavenwoodKeepWholeClass; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -35,6 +36,7 @@ import java.lang.annotation.RetentionPolicy; * @see android.view.View#setOutlineProvider(android.view.ViewOutlineProvider) * @see Drawable#getOutline(Outline) */ +@RavenwoodKeepWholeClass public final class Outline { private static final float RADIUS_UNDEFINED = Float.NEGATIVE_INFINITY; diff --git a/graphics/java/android/graphics/ParcelableColorSpace.java b/graphics/java/android/graphics/ParcelableColorSpace.java index 748d66cb5f6c..76c1715475ae 100644 --- a/graphics/java/android/graphics/ParcelableColorSpace.java +++ b/graphics/java/android/graphics/ParcelableColorSpace.java @@ -20,6 +20,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.os.Parcel; import android.os.Parcelable; +import android.ravenwood.annotation.RavenwoodKeepWholeClass; /** * A {@link Parcelable} wrapper for a {@link ColorSpace}. In order to enable parceling, the @@ -27,6 +28,7 @@ import android.os.Parcelable; * {@link ColorSpace.Rgb} instance that has an ICC parametric transfer function as returned by * {@link ColorSpace.Rgb#getTransferParameters()}. */ +@RavenwoodKeepWholeClass public final class ParcelableColorSpace implements Parcelable { private final ColorSpace mColorSpace; diff --git a/graphics/java/android/graphics/PixelFormat.java b/graphics/java/android/graphics/PixelFormat.java index 3ec5b9cc7dae..a872e03db3b5 100644 --- a/graphics/java/android/graphics/PixelFormat.java +++ b/graphics/java/android/graphics/PixelFormat.java @@ -17,10 +17,12 @@ package android.graphics; import android.annotation.IntDef; +import android.ravenwood.annotation.RavenwoodKeepWholeClass; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; +@RavenwoodKeepWholeClass public class PixelFormat { /** @hide */ @IntDef({UNKNOWN, TRANSLUCENT, TRANSPARENT, OPAQUE}) diff --git a/packages/SettingsLib/src/com/android/settingslib/notification/modes/ZenIconLoader.java b/packages/SettingsLib/src/com/android/settingslib/notification/modes/ZenIconLoader.java index fe0f98af1186..43c6c5050850 100644 --- a/packages/SettingsLib/src/com/android/settingslib/notification/modes/ZenIconLoader.java +++ b/packages/SettingsLib/src/com/android/settingslib/notification/modes/ZenIconLoader.java @@ -31,7 +31,6 @@ import android.util.LruCache; import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import androidx.annotation.VisibleForTesting; import com.google.common.util.concurrent.FluentFuture; import com.google.common.util.concurrent.ListenableFuture; @@ -53,25 +52,22 @@ public class ZenIconLoader { private final LruCache<ZenIcon.Key, Drawable> mCache; private final ListeningExecutorService mBackgroundExecutor; + /** Obtains the singleton {@link ZenIconLoader}. */ public static ZenIconLoader getInstance() { if (sInstance == null) { - sInstance = new ZenIconLoader(); + sInstance = new ZenIconLoader(Executors.newFixedThreadPool(4)); } return sInstance; } - /** Replaces the singleton instance of {@link ZenIconLoader} by the provided one. */ - @VisibleForTesting(otherwise = VisibleForTesting.NONE) - public static void setInstance(@Nullable ZenIconLoader instance) { - sInstance = instance; - } - - private ZenIconLoader() { - this(Executors.newFixedThreadPool(4)); - } - - @VisibleForTesting - public ZenIconLoader(ExecutorService backgroundExecutor) { + /** + * Constructs a ZenIconLoader with the specified {@code backgroundExecutor}. + * + * <p>ZenIconLoader <em>should be a singleton</em>, so this should only be used to instantiate + * and provide the singleton instance in a module. If the app doesn't support dependency + * injection, use {@link #getInstance} instead. + */ + public ZenIconLoader(@NonNull ExecutorService backgroundExecutor) { mCache = new LruCache<>(50); mBackgroundExecutor = MoreExecutors.listeningDecorator(backgroundExecutor); diff --git a/packages/SystemUI/multivalentTests/src/com/android/keyguard/KeyguardPasswordViewControllerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/keyguard/KeyguardPasswordViewControllerTest.kt index 7707a600c691..fe9105ed195e 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/keyguard/KeyguardPasswordViewControllerTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/keyguard/KeyguardPasswordViewControllerTest.kt @@ -29,6 +29,7 @@ import com.android.internal.util.LatencyTracker import com.android.internal.widget.LockPatternUtils import com.android.internal.widget.LockscreenCredential import com.android.keyguard.domain.interactor.KeyguardKeyboardInteractor +import com.android.systemui.Flags as AconfigFlags import com.android.systemui.SysuiTestCase import com.android.systemui.classifier.FalsingCollector import com.android.systemui.flags.FakeFeatureFlags @@ -56,7 +57,6 @@ import org.mockito.Mockito.never import org.mockito.Mockito.verify import org.mockito.Mockito.`when` import org.mockito.MockitoAnnotations -import com.android.systemui.Flags as AconfigFlags @SmallTest @RunWith(AndroidJUnit4::class) @@ -66,8 +66,7 @@ import com.android.systemui.Flags as AconfigFlags class KeyguardPasswordViewControllerTest : SysuiTestCase() { @Mock private lateinit var keyguardPasswordView: KeyguardPasswordView @Mock private lateinit var passwordEntry: EditText - private var passwordEntryLayoutParams = - ViewGroup.LayoutParams(/* width = */ 0, /* height = */ 0) + private var passwordEntryLayoutParams = ViewGroup.LayoutParams(/* width= */ 0, /* height= */ 0) @Mock lateinit var keyguardUpdateMonitor: KeyguardUpdateMonitor @Mock lateinit var securityMode: KeyguardSecurityModel.SecurityMode @Mock lateinit var lockPatternUtils: LockPatternUtils @@ -106,6 +105,8 @@ class KeyguardPasswordViewControllerTest : SysuiTestCase() { whenever(keyguardPasswordView.findViewById<ImageView>(R.id.switch_ime_button)) .thenReturn(mock(ImageView::class.java)) `when`(keyguardPasswordView.resources).thenReturn(context.resources) + // TODO(b/362362385): No need to mock keyguardPasswordView.context once this bug is fixed. + `when`(keyguardPasswordView.context).thenReturn(context) whenever(passwordEntry.layoutParams).thenReturn(passwordEntryLayoutParams) val keyguardKeyboardInteractor = KeyguardKeyboardInteractor(FakeKeyboardRepository()) val fakeFeatureFlags = FakeFeatureFlags() @@ -187,9 +188,11 @@ class KeyguardPasswordViewControllerTest : SysuiTestCase() { verify(passwordEntry).setOnKeyListener(keyListenerArgumentCaptor.capture()) val eventHandled = - keyListenerArgumentCaptor.value.onKey(keyguardPasswordView, + keyListenerArgumentCaptor.value.onKey( + keyguardPasswordView, KeyEvent.KEYCODE_SPACE, - KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_SPACE)) + KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_SPACE) + ) assertFalse("Unlock attempted.", eventHandled) } @@ -204,9 +207,11 @@ class KeyguardPasswordViewControllerTest : SysuiTestCase() { verify(passwordEntry).setOnKeyListener(keyListenerArgumentCaptor.capture()) val eventHandled = - keyListenerArgumentCaptor.value.onKey(keyguardPasswordView, + keyListenerArgumentCaptor.value.onKey( + keyguardPasswordView, KeyEvent.KEYCODE_ENTER, - KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_ENTER)) + KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_ENTER) + ) assertTrue("Unlock not attempted.", eventHandled) } diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesTileDataInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesTileDataInteractorTest.kt index 5925819f27a7..5fd3a242e195 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesTileDataInteractorTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesTileDataInteractorTest.kt @@ -24,9 +24,10 @@ import android.platform.test.annotations.DisableFlags import android.platform.test.annotations.EnableFlags import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest -import com.android.settingslib.notification.modes.ZenIconLoader +import com.android.internal.R import com.android.systemui.SysuiTestCase import com.android.systemui.common.shared.model.asIcon +import com.android.systemui.coroutines.collectLastValue import com.android.systemui.coroutines.collectValues import com.android.systemui.kosmos.testDispatcher import com.android.systemui.kosmos.testScope @@ -36,7 +37,6 @@ import com.android.systemui.statusbar.policy.data.repository.fakeZenModeReposito import com.android.systemui.statusbar.policy.domain.interactor.zenModeInteractor import com.android.systemui.testKosmos import com.google.common.truth.Truth.assertThat -import com.google.common.util.concurrent.MoreExecutors import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.flow.toCollection @@ -60,10 +60,10 @@ class ModesTileDataInteractorTest : SysuiTestCase() { @Before fun setUp() { context.orCreateTestableResources.apply { - addOverride(com.android.internal.R.drawable.ic_zen_mode_type_bedtime, BEDTIME_DRAWABLE) - addOverride(com.android.internal.R.drawable.ic_zen_mode_type_driving, DRIVING_DRAWABLE) + addOverride(MODES_DRAWABLE_ID, MODES_DRAWABLE) + addOverride(R.drawable.ic_zen_mode_type_bedtime, BEDTIME_DRAWABLE) + addOverride(R.drawable.ic_zen_mode_type_driving, DRIVING_DRAWABLE) } - ZenIconLoader.setInstance(ZenIconLoader(MoreExecutors.newDirectExecutorService())) } @EnableFlags(Flags.FLAG_MODES_UI) @@ -128,28 +128,34 @@ class ModesTileDataInteractorTest : SysuiTestCase() { @Test @EnableFlags(Flags.FLAG_MODES_UI, Flags.FLAG_MODES_UI_ICONS) - fun changesIconWhenActiveModesChange() = + fun tileData_iconsFlagEnabled_changesIconWhenActiveModesChange() = testScope.runTest { - val dataList: List<ModesTileModel> by - collectValues( + val tileData by + collectLastValue( underTest.tileData(TEST_USER, flowOf(DataUpdateTrigger.InitialRequest)) ) + + // Tile starts with the generic Modes icon. runCurrent() - assertThat(dataList.map { it.icon }).containsExactly(null).inOrder() + assertThat(tileData?.icon).isEqualTo(MODES_ICON) + assertThat(tileData?.iconResId).isEqualTo(MODES_DRAWABLE_ID) - // Add an inactive mode: state hasn't changed, so this shouldn't cause another emission + // Add an inactive mode -> Still modes icon zenModeRepository.addMode(id = "Mode", active = false) runCurrent() - assertThat(dataList.map { it.icon }).containsExactly(null).inOrder() + assertThat(tileData?.icon).isEqualTo(MODES_ICON) + assertThat(tileData?.iconResId).isEqualTo(MODES_DRAWABLE_ID) - // Add an active mode: icon should be the mode icon + // Add an active mode: icon should be the mode icon. No iconResId, because we don't + // really know that it's a system icon. zenModeRepository.addMode( id = "Bedtime", type = AutomaticZenRule.TYPE_BEDTIME, active = true ) runCurrent() - assertThat(dataList.map { it.icon }).containsExactly(null, BEDTIME_ICON).inOrder() + assertThat(tileData?.icon).isEqualTo(BEDTIME_ICON) + assertThat(tileData?.iconResId).isNull() // Add another, less-prioritized mode: icon should remain the first mode icon zenModeRepository.addMode( @@ -158,29 +164,58 @@ class ModesTileDataInteractorTest : SysuiTestCase() { active = true ) runCurrent() - assertThat(dataList.map { it.icon }) - .containsExactly(null, BEDTIME_ICON, BEDTIME_ICON) - .inOrder() + assertThat(tileData?.icon).isEqualTo(BEDTIME_ICON) + assertThat(tileData?.iconResId).isNull() - // Deactivate more important mode: icon should be the less important, still active mode. + // Deactivate more important mode: icon should be the less important, still active mode zenModeRepository.deactivateMode("Bedtime") runCurrent() - assertThat(dataList.map { it.icon }) - .containsExactly(null, BEDTIME_ICON, BEDTIME_ICON, DRIVING_ICON) - .inOrder() + assertThat(tileData?.icon).isEqualTo(DRIVING_ICON) + assertThat(tileData?.iconResId).isNull() - // Deactivate remaining mode: no icon + // Deactivate remaining mode: back to the default modes icon zenModeRepository.deactivateMode("Driving") runCurrent() - assertThat(dataList.map { it.icon }) - .containsExactly(null, BEDTIME_ICON, BEDTIME_ICON, DRIVING_ICON, null) - .inOrder() + assertThat(tileData?.icon).isEqualTo(MODES_ICON) + assertThat(tileData?.iconResId).isEqualTo(MODES_DRAWABLE_ID) + } + + @Test + @EnableFlags(Flags.FLAG_MODES_UI) + @DisableFlags(Flags.FLAG_MODES_UI_ICONS) + fun tileData_iconsFlagDisabled_hasPriorityModesIcon() = + testScope.runTest { + val tileData by + collectLastValue( + underTest.tileData(TEST_USER, flowOf(DataUpdateTrigger.InitialRequest)) + ) + + runCurrent() + assertThat(tileData?.icon).isEqualTo(MODES_ICON) + assertThat(tileData?.iconResId).isEqualTo(MODES_DRAWABLE_ID) + + // Activate a Mode -> Icon doesn't change. + zenModeRepository.addMode(id = "Mode", active = true) + runCurrent() + assertThat(tileData?.icon).isEqualTo(MODES_ICON) + assertThat(tileData?.iconResId).isEqualTo(MODES_DRAWABLE_ID) + + zenModeRepository.deactivateMode(id = "Mode") + runCurrent() + assertThat(tileData?.icon).isEqualTo(MODES_ICON) + assertThat(tileData?.iconResId).isEqualTo(MODES_DRAWABLE_ID) } private companion object { val TEST_USER = UserHandle.of(1)!! + + val MODES_DRAWABLE_ID = com.android.systemui.res.R.drawable.qs_dnd_icon_off + + val MODES_DRAWABLE = TestStubDrawable("modes_icon") val BEDTIME_DRAWABLE = TestStubDrawable("bedtime") val DRIVING_DRAWABLE = TestStubDrawable("driving") + + val MODES_ICON = MODES_DRAWABLE.asIcon() val BEDTIME_ICON = BEDTIME_DRAWABLE.asIcon() val DRIVING_ICON = DRIVING_DRAWABLE.asIcon() } diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesTileUserActionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesTileUserActionInteractorTest.kt index 4b7564981855..cd5812710292 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesTileUserActionInteractorTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesTileUserActionInteractorTest.kt @@ -16,12 +16,14 @@ package com.android.systemui.qs.tiles.impl.modes.domain.interactor +import android.graphics.drawable.TestStubDrawable import android.platform.test.annotations.EnableFlags import android.provider.Settings import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.animation.Expandable +import com.android.systemui.common.shared.model.asIcon import com.android.systemui.qs.tiles.base.actions.QSTileIntentUserInputHandlerSubject import com.android.systemui.qs.tiles.base.actions.qsTileIntentUserInputHandler import com.android.systemui.qs.tiles.base.interactor.QSTileInputTestKtx @@ -54,10 +56,7 @@ class ModesTileUserActionInteractorTest : SysuiTestCase() { fun handleClick_active() = runTest { val expandable = mock<Expandable>() underTest.handleInput( - QSTileInputTestKtx.click( - data = ModesTileModel(true, listOf("DND")), - expandable = expandable - ) + QSTileInputTestKtx.click(data = modelOf(true, listOf("DND")), expandable = expandable) ) verify(mockDialogDelegate).showDialog(eq(expandable)) @@ -67,10 +66,7 @@ class ModesTileUserActionInteractorTest : SysuiTestCase() { fun handleClick_inactive() = runTest { val expandable = mock<Expandable>() underTest.handleInput( - QSTileInputTestKtx.click( - data = ModesTileModel(false, emptyList()), - expandable = expandable - ) + QSTileInputTestKtx.click(data = modelOf(false, emptyList()), expandable = expandable) ) verify(mockDialogDelegate).showDialog(eq(expandable)) @@ -78,7 +74,7 @@ class ModesTileUserActionInteractorTest : SysuiTestCase() { @Test fun handleLongClick_active() = runTest { - underTest.handleInput(QSTileInputTestKtx.longClick(ModesTileModel(true, listOf("DND")))) + underTest.handleInput(QSTileInputTestKtx.longClick(modelOf(true, listOf("DND")))) QSTileIntentUserInputHandlerSubject.assertThat(inputHandler).handledOneIntentInput { assertThat(it.intent.action).isEqualTo(Settings.ACTION_ZEN_MODE_SETTINGS) @@ -87,10 +83,14 @@ class ModesTileUserActionInteractorTest : SysuiTestCase() { @Test fun handleLongClick_inactive() = runTest { - underTest.handleInput(QSTileInputTestKtx.longClick(ModesTileModel(false, emptyList()))) + underTest.handleInput(QSTileInputTestKtx.longClick(modelOf(false, emptyList()))) QSTileIntentUserInputHandlerSubject.assertThat(inputHandler).handledOneIntentInput { assertThat(it.intent.action).isEqualTo(Settings.ACTION_ZEN_MODE_SETTINGS) } } + + private fun modelOf(isActivated: Boolean, activeModeNames: List<String>): ModesTileModel { + return ModesTileModel(isActivated, activeModeNames, TestStubDrawable("icon").asIcon(), 123) + } } diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/modes/ui/ModesTileMapperTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/modes/ui/ModesTileMapperTest.kt index a41f15d8ff82..f7bdcb8086ef 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/modes/ui/ModesTileMapperTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/modes/ui/ModesTileMapperTest.kt @@ -18,11 +18,12 @@ package com.android.systemui.qs.tiles.impl.modes.ui import android.app.Flags import android.graphics.drawable.TestStubDrawable +import android.platform.test.annotations.DisableFlags import android.platform.test.annotations.EnableFlags import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase -import com.android.systemui.common.shared.model.Icon +import com.android.systemui.common.shared.model.asIcon import com.android.systemui.qs.tiles.impl.modes.domain.model.ModesTileModel import com.android.systemui.qs.tiles.viewmodel.QSTileConfigTestBuilder import com.android.systemui.qs.tiles.viewmodel.QSTileState @@ -58,47 +59,88 @@ class ModesTileMapperTest : SysuiTestCase() { @Test fun inactiveState() { - val model = ModesTileModel(isActivated = false, activeModes = emptyList()) + val icon = TestStubDrawable("res123").asIcon() + val model = + ModesTileModel( + isActivated = false, + activeModes = emptyList(), + icon = icon, + ) val state = underTest.map(config, model) assertThat(state.activationState).isEqualTo(QSTileState.ActivationState.INACTIVE) - assertThat(state.iconRes).isEqualTo(R.drawable.qs_dnd_icon_off) + assertThat(state.icon()).isEqualTo(icon) assertThat(state.secondaryLabel).isEqualTo("No active modes") } @Test fun activeState_oneMode() { - val model = ModesTileModel(isActivated = true, activeModes = listOf("DND")) + val icon = TestStubDrawable("res123").asIcon() + val model = + ModesTileModel( + isActivated = true, + activeModes = listOf("DND"), + icon = icon, + ) val state = underTest.map(config, model) assertThat(state.activationState).isEqualTo(QSTileState.ActivationState.ACTIVE) - assertThat(state.iconRes).isEqualTo(R.drawable.qs_dnd_icon_on) + assertThat(state.icon()).isEqualTo(icon) assertThat(state.secondaryLabel).isEqualTo("DND is active") } @Test fun activeState_multipleModes() { + val icon = TestStubDrawable("res123").asIcon() val model = - ModesTileModel(isActivated = true, activeModes = listOf("Mode 1", "Mode 2", "Mode 3")) + ModesTileModel( + isActivated = true, + activeModes = listOf("Mode 1", "Mode 2", "Mode 3"), + icon = icon, + ) val state = underTest.map(config, model) assertThat(state.activationState).isEqualTo(QSTileState.ActivationState.ACTIVE) - assertThat(state.iconRes).isEqualTo(R.drawable.qs_dnd_icon_on) + assertThat(state.icon()).isEqualTo(icon) assertThat(state.secondaryLabel).isEqualTo("3 modes are active") } @Test @EnableFlags(Flags.FLAG_MODES_UI_ICONS) - fun activeState_withIcon() { - val icon = Icon.Resource(1234, contentDescription = null) - val model = ModesTileModel(isActivated = true, activeModes = listOf("DND"), icon = icon) + fun state_withEnabledFlag_noIconResId() { + val icon = TestStubDrawable("res123").asIcon() + val model = + ModesTileModel( + isActivated = false, + activeModes = emptyList(), + icon = icon, + iconResId = 123 // Should not be populated, but is ignored even if present + ) val state = underTest.map(config, model) + assertThat(state.icon()).isEqualTo(icon) assertThat(state.iconRes).isNull() + } + + @Test + @DisableFlags(Flags.FLAG_MODES_UI_ICONS) + fun state_withDisabledFlag_includesIconResId() { + val icon = TestStubDrawable("res123").asIcon() + val model = + ModesTileModel( + isActivated = false, + activeModes = emptyList(), + icon = icon, + iconResId = 123 + ) + + val state = underTest.map(config, model) + assertThat(state.icon()).isEqualTo(icon) + assertThat(state.iconRes).isEqualTo(123) } } diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/domain/interactor/ZenModeInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/domain/interactor/ZenModeInteractorTest.kt index 20d3a7b6b7b5..639d34d5e74d 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/domain/interactor/ZenModeInteractorTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/domain/interactor/ZenModeInteractorTest.kt @@ -22,8 +22,10 @@ import android.provider.Settings import android.provider.Settings.Secure.ZEN_DURATION import android.provider.Settings.Secure.ZEN_DURATION_FOREVER import android.provider.Settings.Secure.ZEN_DURATION_PROMPT +import android.service.notification.SystemZenRules import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest +import com.android.internal.R import com.android.settingslib.notification.data.repository.updateNotificationPolicy import com.android.settingslib.notification.modes.TestModeBuilder import com.android.systemui.SysuiTestCase @@ -220,30 +222,86 @@ class ZenModeInteractorTest : SysuiTestCase() { } @Test - fun mainActiveMode_returnsMainActiveMode() = + fun activeModes_computesMainActiveMode() = testScope.runTest { - val mainActiveMode by collectLastValue(underTest.mainActiveMode) + val activeModes by collectLastValue(underTest.activeModes) zenModeRepository.addMode(id = "Bedtime", type = AutomaticZenRule.TYPE_BEDTIME) zenModeRepository.addMode(id = "Other", type = AutomaticZenRule.TYPE_OTHER) runCurrent() + assertThat(activeModes?.modeNames).hasSize(0) + assertThat(activeModes?.mainMode).isNull() + + zenModeRepository.activateMode("Other") + runCurrent() + assertThat(activeModes?.modeNames).containsExactly("Mode Other") + assertThat(activeModes?.mainMode?.name).isEqualTo("Mode Other") + + zenModeRepository.activateMode("Bedtime") + runCurrent() + assertThat(activeModes?.modeNames) + .containsExactly("Mode Bedtime", "Mode Other") + .inOrder() + assertThat(activeModes?.mainMode?.name).isEqualTo("Mode Bedtime") + + zenModeRepository.deactivateMode("Other") + runCurrent() + assertThat(activeModes?.modeNames).containsExactly("Mode Bedtime") + assertThat(activeModes?.mainMode?.name).isEqualTo("Mode Bedtime") + + zenModeRepository.deactivateMode("Bedtime") + runCurrent() + assertThat(activeModes?.modeNames).hasSize(0) + assertThat(activeModes?.mainMode).isNull() + } + + @Test + fun mainActiveMode_flows() = + testScope.runTest { + val mainActiveMode by collectLastValue(underTest.mainActiveMode) + + zenModeRepository.addModes( + listOf( + TestModeBuilder() + .setId("Bedtime") + .setName("Mode Bedtime") + .setType(AutomaticZenRule.TYPE_BEDTIME) + .setActive(false) + .setPackage(mContext.packageName) + .setIconResId(R.drawable.ic_zen_mode_type_bedtime) + .build(), + TestModeBuilder() + .setId("Other") + .setName("Mode Other") + .setType(AutomaticZenRule.TYPE_OTHER) + .setActive(false) + .setPackage(SystemZenRules.PACKAGE_ANDROID) + .setIconResId(R.drawable.ic_zen_mode_type_other) + .build(), + ) + ) + + runCurrent() assertThat(mainActiveMode).isNull() zenModeRepository.activateMode("Other") runCurrent() - assertThat(mainActiveMode).isNotNull() - assertThat(mainActiveMode!!.id).isEqualTo("Other") + assertThat(mainActiveMode?.name).isEqualTo("Mode Other") + assertThat(mainActiveMode?.icon?.key?.resId) + .isEqualTo(R.drawable.ic_zen_mode_type_other) zenModeRepository.activateMode("Bedtime") runCurrent() - assertThat(mainActiveMode).isNotNull() - assertThat(mainActiveMode!!.id).isEqualTo("Bedtime") + assertThat(mainActiveMode?.name).isEqualTo("Mode Bedtime") + assertThat(mainActiveMode?.icon?.key?.resId) + .isEqualTo(R.drawable.ic_zen_mode_type_bedtime) zenModeRepository.deactivateMode("Other") runCurrent() - assertThat(mainActiveMode).isNotNull() - assertThat(mainActiveMode!!.id).isEqualTo("Bedtime") + assertThat(mainActiveMode?.name).isEqualTo("Mode Bedtime") + assertThat(mainActiveMode?.icon?.key?.resId) + .isEqualTo(R.drawable.ic_zen_mode_type_bedtime) zenModeRepository.deactivateMode("Bedtime") runCurrent() diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/ui/dialog/viewmodel/ModesDialogViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/ui/dialog/viewmodel/ModesDialogViewModelTest.kt index 33f379d020b7..d2bc54e09944 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/ui/dialog/viewmodel/ModesDialogViewModelTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/ui/dialog/viewmodel/ModesDialogViewModelTest.kt @@ -23,7 +23,6 @@ import android.provider.Settings import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.settingslib.notification.modes.TestModeBuilder -import com.android.settingslib.notification.modes.ZenIconLoader import com.android.settingslib.notification.modes.ZenMode import com.android.systemui.SysuiTestCase import com.android.systemui.coroutines.collectLastValue @@ -35,12 +34,10 @@ import com.android.systemui.statusbar.policy.ui.dialog.mockModesDialogDelegate import com.android.systemui.statusbar.policy.ui.dialog.mockModesDialogEventLogger import com.android.systemui.testKosmos import com.google.common.truth.Truth.assertThat -import com.google.common.util.concurrent.MoreExecutors import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.Job import kotlinx.coroutines.test.runCurrent import kotlinx.coroutines.test.runTest -import org.junit.Before import org.junit.Test import org.junit.runner.RunWith import org.mockito.Mockito.clearInvocations @@ -67,11 +64,6 @@ class ModesDialogViewModelTest : SysuiTestCase() { mockDialogEventLogger ) - @Before - fun setUp() { - ZenIconLoader.setInstance(ZenIconLoader(MoreExecutors.newDirectExecutorService())) - } - @Test fun tiles_filtersOutUserDisabledModes() = testScope.runTest { diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordViewController.java index 490ad5c4136d..3ad73bc17704 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordViewController.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordViewController.java @@ -19,9 +19,12 @@ package com.android.keyguard; import static com.android.systemui.flags.Flags.LOCKSCREEN_ENABLE_LANDSCAPE; import static com.android.systemui.util.kotlin.JavaAdapterKt.collectFlow; +import android.content.Context; +import android.content.pm.PackageManager; import android.content.res.Resources; import android.graphics.drawable.Drawable; import android.os.UserHandle; +import android.os.UserManager; import android.text.Editable; import android.text.InputType; import android.text.TextUtils; @@ -170,8 +173,33 @@ public class KeyguardPasswordViewController mPasswordEntry.setOnEditorActionListener(mOnEditorActionListener); mPasswordEntry.setOnKeyListener(mKeyListener); mPasswordEntry.addTextChangedListener(mTextWatcher); + // Poke the wakelock any time the text is selected or modified - mPasswordEntry.setOnClickListener(v -> mKeyguardSecurityCallback.userActivity()); + // TODO(b/362362385): Revert to the previous onClickListener implementation once this bug is + // fixed. + mPasswordEntry.setOnClickListener(new View.OnClickListener() { + + private final boolean mAutomotiveAndVisibleBackgroundUsers = + isAutomotiveAndVisibleBackgroundUsers(); + + @Override + public void onClick(View v) { + if (mAutomotiveAndVisibleBackgroundUsers) { + mInputMethodManager.restartInput(v); + } + mKeyguardSecurityCallback.userActivity(); + } + + private boolean isAutomotiveAndVisibleBackgroundUsers() { + final Context context = getContext(); + return context.getPackageManager().hasSystemFeature( + PackageManager.FEATURE_AUTOMOTIVE) + && UserManager.isVisibleBackgroundUsersEnabled() + && context.getResources().getBoolean( + android.R.bool.config_perDisplayFocusEnabled); + } + }); + mSwitchImeButton.setOnClickListener(v -> { mKeyguardSecurityCallback.userActivity(); // Leave the screen on a bit longer // Do not show auxiliary subtypes in password lock screen. diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationSettings.java b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationSettings.java index 9b6501eb1e57..2f0ca6e6bf9d 100644 --- a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationSettings.java +++ b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationSettings.java @@ -482,6 +482,10 @@ class WindowMagnificationSettings implements MagnificationGestureDetector.OnGest } else { // mode = ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW mEditButton.setVisibility(View.VISIBLE); mAllowDiagonalScrollingView.setVisibility(View.VISIBLE); + if (Flags.saveAndRestoreMagnificationSettingsButtons()) { + selectedButtonIndex = + windowMagnificationFrameSizePrefs.getIndexForCurrentDensity(); + } } break; diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuController.java b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuController.java index e4b7b7e69c61..275147e6694c 100644 --- a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuController.java +++ b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuController.java @@ -21,11 +21,13 @@ import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL; import android.content.Context; import android.hardware.display.DisplayManager; +import android.os.Handler; import android.os.UserHandle; import android.text.TextUtils; import android.view.Display; import android.view.WindowManager; import android.view.accessibility.AccessibilityManager; +import android.view.accessibility.IUserInitializationCompleteCallback; import androidx.annotation.MainThread; @@ -68,6 +70,9 @@ public class AccessibilityFloatingMenuController implements private int mBtnMode; private String mBtnTargets; private boolean mIsKeyguardVisible; + private boolean mIsUserInInitialization; + @VisibleForTesting + Handler mHandler; @VisibleForTesting final KeyguardUpdateMonitorCallback mKeyguardCallback = new KeyguardUpdateMonitorCallback() { @@ -86,18 +91,14 @@ public class AccessibilityFloatingMenuController implements @Override public void onUserSwitching(int userId) { destroyFloatingMenu(); - } - - @Override - public void onUserSwitchComplete(int userId) { - mContext = mContext.createContextAsUser(UserHandle.of(userId), /* flags= */ 0); - mBtnMode = mAccessibilityButtonModeObserver.getCurrentAccessibilityButtonMode(); - mBtnTargets = - mAccessibilityButtonTargetsObserver.getCurrentAccessibilityButtonTargets(); - handleFloatingMenuVisibility(mIsKeyguardVisible, mBtnMode, mBtnTargets); + mIsUserInInitialization = true; } }; + @VisibleForTesting + final UserInitializationCompleteCallback mUserInitializationCompleteCallback = + new UserInitializationCompleteCallback(); + @Inject public AccessibilityFloatingMenuController(Context context, WindowManager windowManager, @@ -109,7 +110,8 @@ public class AccessibilityFloatingMenuController implements KeyguardUpdateMonitor keyguardUpdateMonitor, SecureSettings secureSettings, DisplayTracker displayTracker, - NavigationModeController navigationModeController) { + NavigationModeController navigationModeController, + Handler handler) { mContext = context; mWindowManager = windowManager; mViewCaptureAwareWindowManager = viewCaptureAwareWindowManager; @@ -121,6 +123,7 @@ public class AccessibilityFloatingMenuController implements mSecureSettings = secureSettings; mDisplayTracker = displayTracker; mNavigationModeController = navigationModeController; + mHandler = handler; mIsKeyguardVisible = false; } @@ -159,6 +162,8 @@ public class AccessibilityFloatingMenuController implements mAccessibilityButtonModeObserver.addListener(this); mAccessibilityButtonTargetsObserver.addListener(this); mKeyguardUpdateMonitor.registerCallback(mKeyguardCallback); + mAccessibilityManager.registerUserInitializationCompleteCallback( + mUserInitializationCompleteCallback); } /** @@ -172,7 +177,7 @@ public class AccessibilityFloatingMenuController implements */ private void handleFloatingMenuVisibility(boolean keyguardVisible, @AccessibilityButtonMode int mode, String targets) { - if (keyguardVisible) { + if (keyguardVisible || mIsUserInInitialization) { destroyFloatingMenu(); return; } @@ -210,4 +215,18 @@ public class AccessibilityFloatingMenuController implements mFloatingMenu.hide(); mFloatingMenu = null; } + + class UserInitializationCompleteCallback + extends IUserInitializationCompleteCallback.Stub { + @Override + public void onUserInitializationComplete(int userId) { + mIsUserInInitialization = false; + mContext = mContext.createContextAsUser(UserHandle.of(userId), /* flags= */ 0); + mBtnMode = mAccessibilityButtonModeObserver.getCurrentAccessibilityButtonMode(); + mBtnTargets = + mAccessibilityButtonTargetsObserver.getCurrentAccessibilityButtonTargets(); + mHandler.post( + () -> handleFloatingMenuVisibility(mIsKeyguardVisible, mBtnMode, mBtnTargets)); + } + } } diff --git a/packages/SystemUI/src/com/android/systemui/common/shared/model/Icon.kt b/packages/SystemUI/src/com/android/systemui/common/shared/model/Icon.kt index 3cdb57318e8d..aef5f1f422d1 100644 --- a/packages/SystemUI/src/com/android/systemui/common/shared/model/Icon.kt +++ b/packages/SystemUI/src/com/android/systemui/common/shared/model/Icon.kt @@ -38,5 +38,5 @@ sealed class Icon { } /** Creates [Icon.Loaded] for a given drawable with an optional [contentDescription]. */ -fun Drawable.asIcon(contentDescription: ContentDescription? = null): Icon = +fun Drawable.asIcon(contentDescription: ContentDescription? = null): Icon.Loaded = Icon.Loaded(this, contentDescription) diff --git a/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryFaceAuthInteractor.kt b/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryFaceAuthInteractor.kt index dff391a32d6b..f5914104d87f 100644 --- a/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryFaceAuthInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryFaceAuthInteractor.kt @@ -60,14 +60,23 @@ interface DeviceEntryFaceAuthInteractor : CoreStartable { fun unregisterListener(listener: FaceAuthenticationListener) fun onUdfpsSensorTouched() + fun onAssistantTriggeredOnLockScreen() + fun onDeviceLifted() - fun onQsExpansionStared() + + fun onQsExpansionStarted() + fun onNotificationPanelClicked() + fun onSwipeUpOnBouncer() + fun onPrimaryBouncerUserInput() + fun onAccessibilityAction() + fun onWalletLaunched() + fun onDeviceUnfolded() /** Whether face auth is considered class 3 */ diff --git a/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/NoopDeviceEntryFaceAuthInteractor.kt b/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/NoopDeviceEntryFaceAuthInteractor.kt index de5d0aa5aad7..b7d2a57d9a41 100644 --- a/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/NoopDeviceEntryFaceAuthInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/NoopDeviceEntryFaceAuthInteractor.kt @@ -47,6 +47,7 @@ class NoopDeviceEntryFaceAuthInteractor @Inject constructor() : DeviceEntryFaceA override fun isFaceAuthEnabledAndEnrolled(): Boolean = false override fun isFaceAuthStrong(): Boolean = false + override fun start() = Unit override fun registerListener(listener: FaceAuthenticationListener) {} @@ -59,13 +60,17 @@ class NoopDeviceEntryFaceAuthInteractor @Inject constructor() : DeviceEntryFaceA override fun onDeviceLifted() {} - override fun onQsExpansionStared() {} + override fun onQsExpansionStarted() {} override fun onNotificationPanelClicked() {} override fun onSwipeUpOnBouncer() {} + override fun onPrimaryBouncerUserInput() {} + override fun onAccessibilityAction() {} + override fun onWalletLaunched() = Unit + override fun onDeviceUnfolded() {} } diff --git a/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/SystemUIDeviceEntryFaceAuthInteractor.kt b/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/SystemUIDeviceEntryFaceAuthInteractor.kt index 183e0e96e765..5ef63d9b856c 100644 --- a/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/SystemUIDeviceEntryFaceAuthInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/SystemUIDeviceEntryFaceAuthInteractor.kt @@ -60,6 +60,7 @@ import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.filter import kotlinx.coroutines.flow.filterNotNull import kotlinx.coroutines.flow.flowOn @@ -214,6 +215,16 @@ constructor( } } .launchIn(applicationScope) + + if (SceneContainerFlag.isEnabled) { + sceneInteractor + .get() + .transitionState + .filter { it.isTransitioning(from = Scenes.QuickSettings, to = Scenes.Shade) } + .distinctUntilChanged() + .onEach { onQsExpansionStarted() } + .launchIn(applicationScope) + } } private val isBouncerVisible: Flow<Boolean> by lazy { @@ -239,7 +250,7 @@ constructor( runFaceAuth(FaceAuthUiEvent.FACE_AUTH_TRIGGERED_NOTIFICATION_PANEL_CLICKED, true) } - override fun onQsExpansionStared() { + override fun onQsExpansionStarted() { runFaceAuth(FaceAuthUiEvent.FACE_AUTH_TRIGGERED_QS_EXPANDED, true) } diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/InfiniteGridLayout.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/InfiniteGridLayout.kt index d948dfd7d3b9..c75b601ab4a8 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/InfiniteGridLayout.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/InfiniteGridLayout.kt @@ -16,7 +16,6 @@ package com.android.systemui.qs.panels.ui.compose -import androidx.compose.foundation.layout.height import androidx.compose.foundation.lazy.grid.GridCells import androidx.compose.foundation.lazy.grid.GridItemSpan import androidx.compose.runtime.Composable @@ -24,7 +23,6 @@ import androidx.compose.runtime.DisposableEffect import androidx.compose.runtime.getValue import androidx.compose.runtime.remember import androidx.compose.ui.Modifier -import androidx.compose.ui.res.dimensionResource import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.android.systemui.dagger.SysUISingleton import com.android.systemui.qs.panels.shared.model.SizedTileImpl @@ -33,7 +31,6 @@ import com.android.systemui.qs.panels.ui.viewmodel.FixedColumnsSizeViewModel import com.android.systemui.qs.panels.ui.viewmodel.IconTilesViewModel import com.android.systemui.qs.panels.ui.viewmodel.TileViewModel import com.android.systemui.qs.pipeline.shared.TileSpec -import com.android.systemui.res.R import javax.inject.Inject @SysUISingleton @@ -64,7 +61,7 @@ constructor( Tile( tile = sizedTiles[index].tile, iconOnly = iconTilesViewModel.isIconTile(sizedTiles[index].tile.spec), - modifier = Modifier.height(dimensionResource(id = R.dimen.qs_tile_height)) + modifier = Modifier ) } } diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/QuickQuickSettings.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/QuickQuickSettings.kt index a9027ff92996..eeb55ca19bc3 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/QuickQuickSettings.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/QuickQuickSettings.kt @@ -16,18 +16,15 @@ package com.android.systemui.qs.panels.ui.compose -import androidx.compose.foundation.layout.height import androidx.compose.foundation.lazy.grid.GridCells import androidx.compose.foundation.lazy.grid.GridItemSpan import androidx.compose.runtime.Composable import androidx.compose.runtime.DisposableEffect import androidx.compose.runtime.getValue import androidx.compose.ui.Modifier -import androidx.compose.ui.res.dimensionResource import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.android.systemui.compose.modifiers.sysuiResTag import com.android.systemui.qs.panels.ui.viewmodel.QuickQuickSettingsViewModel -import com.android.systemui.res.R @Composable fun QuickQuickSettings( @@ -54,11 +51,7 @@ fun QuickQuickSettings( key = { index -> sizedTiles[index].tile.spec.spec }, span = { index -> GridItemSpan(sizedTiles[index].width) } ) { index -> - Tile( - tile = tiles[index], - iconOnly = sizedTiles[index].isIcon, - modifier = Modifier.height(dimensionResource(id = R.dimen.qs_tile_height)) - ) + Tile(tile = tiles[index], iconOnly = sizedTiles[index].isIcon, modifier = Modifier) } } } diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/Tile.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/Tile.kt index 79c2eb90af20..24af09d62313 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/Tile.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/Tile.kt @@ -44,7 +44,6 @@ import androidx.compose.foundation.layout.BoxScope import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer -import androidx.compose.foundation.layout.aspectRatio import androidx.compose.foundation.layout.fillMaxHeight import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth @@ -136,23 +135,23 @@ fun Tile( // TODO(b/361789146): Draw the shapes instead of clipping val tileShape = TileDefaults.animateTileShape(uiState.state) - val iconShape = TileDefaults.animateIconShape(uiState.state) TileContainer( colors = colors, showLabels = showLabels, label = uiState.label, iconOnly = iconOnly, - shape = if (iconOnly) iconShape else tileShape, + shape = tileShape, clickEnabled = true, onClick = tile::onClick, onLongClick = tile::onLongClick, - modifier = modifier, + modifier = modifier.height(tileHeight()), ) { val icon = getTileIcon(icon = uiState.icon) if (iconOnly) { TileIcon(icon = icon, color = colors.icon, modifier = Modifier.align(Alignment.Center)) } else { + val iconShape = TileDefaults.animateIconShape(uiState.state) LargeTileContent( label = uiState.label, secondaryLabel = uiState.secondaryLabel, @@ -199,7 +198,7 @@ private fun TileContainer( Expandable( color = backgroundColor, shape = shape, - modifier = Modifier.height(dimensionResource(id = R.dimen.qs_tile_height)).clip(shape) + modifier = Modifier.height(tileHeight()).clip(shape) ) { Box( modifier = @@ -246,7 +245,7 @@ private fun LargeTileContent( // Icon Box( modifier = - Modifier.fillMaxHeight().aspectRatio(1f).thenIf(toggleClickSupported) { + Modifier.size(TileDefaults.ToggleTargetSize).thenIf(toggleClickSupported) { Modifier.clip(iconShape) .background(colors.iconBackground, { 1f }) .combinedClickable(onClick = onClick, onLongClick = onLongClick) @@ -673,7 +672,7 @@ private fun TileIcon( animateToEnd: Boolean = false, modifier: Modifier = Modifier, ) { - val iconModifier = modifier.size(dimensionResource(id = R.dimen.qs_icon_size)) + val iconModifier = modifier.size(TileDefaults.IconSize) val context = LocalContext.current val loadedDrawable = remember(icon, context) { @@ -710,17 +709,12 @@ private fun TileIcon( } } -@Composable private fun Modifier.tilePadding(): Modifier { - return padding(dimensionResource(id = R.dimen.qs_label_container_margin)) + return padding(TileDefaults.TilePadding) } -@Composable private fun tileHorizontalArrangement(): Arrangement.Horizontal { - return spacedBy( - space = dimensionResource(id = R.dimen.qs_label_container_margin), - alignment = Alignment.Start - ) + return spacedBy(space = TileDefaults.TileArrangementPadding, alignment = Alignment.Start) } @Composable @@ -728,7 +722,7 @@ fun tileHeight(iconWithLabel: Boolean = false): Dp { return if (iconWithLabel) { TileDefaults.IconTileWithLabelHeight } else { - dimensionResource(id = R.dimen.qs_tile_height) + TileDefaults.TileHeight } } @@ -749,6 +743,14 @@ private object TileDefaults { val InactiveCornerRadius = 50.dp val ActiveIconCornerRadius = 16.dp val ActiveTileCornerRadius = 24.dp + + val ToggleTargetSize = 56.dp + val IconSize = 24.dp + + val TilePadding = 8.dp + val TileArrangementPadding = 6.dp + + val TileHeight = 72.dp val IconTileWithLabelHeight = 140.dp /** An active tile without dual target uses the active color as background */ @@ -812,7 +814,7 @@ private object TileDefaults { fun animateIconShape(state: Int): Shape { return animateShape( state = state, - activeCornerRadius = ActiveTileCornerRadius, + activeCornerRadius = ActiveIconCornerRadius, label = "QSTileCornerRadius", ) } @@ -821,7 +823,7 @@ private object TileDefaults { fun animateTileShape(state: Int): Shape { return animateShape( state = state, - activeCornerRadius = ActiveIconCornerRadius, + activeCornerRadius = ActiveTileCornerRadius, label = "QSTileIconCornerRadius", ) } diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogDelegate.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogDelegate.java index 71f8639c1e22..89b9eee52f2a 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogDelegate.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogDelegate.java @@ -306,6 +306,8 @@ public class InternetDialogDelegate implements mInternetDialogController.isAirplaneModeEnabled() ? View.VISIBLE : View.GONE); mWifiRecyclerView.setLayoutManager(new LinearLayoutManager(context)); mWifiRecyclerView.setAdapter(mAdapter); + + updateDialogUI(getWifiNetworkContent()); } @Override @@ -315,6 +317,7 @@ public class InternetDialogDelegate implements } mLifecycleRegistry.setCurrentState(Lifecycle.State.RESUMED); + mInternetDialogController.onStart(this, mCanConfigWifi); if (!mCanConfigWifi) { hideWifiViews(); @@ -402,10 +405,12 @@ public class InternetDialogDelegate implements internetContent.mShouldUpdateMobileNetwork = shouldUpdateMobileNetwork; internetContent.mInternetDialogTitleString = getDialogTitleText(); internetContent.mInternetDialogSubTitle = getSubtitleText(); - internetContent.mActiveNetworkIsCellular = - mInternetDialogController.activeNetworkIsCellular(); - internetContent.mIsCarrierNetworkActive = - mInternetDialogController.isCarrierNetworkActive(); + if (shouldUpdateMobileNetwork) { + internetContent.mActiveNetworkIsCellular = + mInternetDialogController.activeNetworkIsCellular(); + internetContent.mIsCarrierNetworkActive = + mInternetDialogController.isCarrierNetworkActive(); + } internetContent.mIsAirplaneModeEnabled = mInternetDialogController.isAirplaneModeEnabled(); internetContent.mHasEthernet = mInternetDialogController.hasEthernet(); internetContent.mIsWifiEnabled = mInternetDialogController.isWifiEnabled(); @@ -416,6 +421,15 @@ public class InternetDialogDelegate implements return internetContent; } + private InternetContent getWifiNetworkContent() { + InternetContent internetContent = new InternetContent(); + internetContent.mInternetDialogTitleString = getDialogTitleText(); + internetContent.mInternetDialogSubTitle = getSubtitleText(); + internetContent.mIsWifiEnabled = mInternetDialogController.isWifiEnabled(); + internetContent.mIsDeviceLocked = mInternetDialogController.isDeviceLocked(); + return internetContent; + } + private void setOnClickListener(SystemUIDialog dialog) { mMobileNetworkLayout.setOnClickListener(v -> { int autoSwitchNonDdsSubId = mInternetDialogController.getActiveAutoSwitchNonDdsSubId(); diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesTileDataInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesTileDataInteractor.kt index 3f18fc2066eb..664951d199a7 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesTileDataInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesTileDataInteractor.kt @@ -20,10 +20,12 @@ import android.app.Flags import android.content.Context import android.os.UserHandle import com.android.app.tracing.coroutines.flow.map +import com.android.systemui.common.shared.model.asIcon import com.android.systemui.dagger.qualifiers.Background import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger import com.android.systemui.qs.tiles.base.interactor.QSTileDataInteractor import com.android.systemui.qs.tiles.impl.modes.domain.model.ModesTileModel +import com.android.systemui.res.R import com.android.systemui.statusbar.policy.domain.interactor.ZenModeInteractor import javax.inject.Inject import kotlinx.coroutines.CoroutineDispatcher @@ -52,18 +54,32 @@ constructor( */ fun tileData() = zenModeInteractor.activeModes - .map { modes -> - ModesTileModel( - isActivated = modes.isNotEmpty(), - icon = - if (Flags.modesApi() && Flags.modesUi() && Flags.modesUiIcons()) - zenModeInteractor.getActiveModeIcon(modes) - else null, - activeModes = modes.map { it.name } - ) + .map { activeModes -> + val modesIconResId = R.drawable.qs_dnd_icon_off + + if (usesModeIcons()) { + val mainModeDrawable = activeModes.mainMode?.icon?.drawable + val iconResId = if (mainModeDrawable == null) modesIconResId else null + + ModesTileModel( + isActivated = activeModes.isAnyActive(), + icon = (mainModeDrawable ?: context.getDrawable(modesIconResId)!!).asIcon(), + iconResId = iconResId, + activeModes = activeModes.modeNames + ) + } else { + ModesTileModel( + isActivated = activeModes.isAnyActive(), + icon = context.getDrawable(modesIconResId)!!.asIcon(), + iconResId = modesIconResId, + activeModes = activeModes.modeNames + ) + } } .flowOn(bgDispatcher) .distinctUntilChanged() override fun availability(user: UserHandle): Flow<Boolean> = flowOf(Flags.modesUi()) + + private fun usesModeIcons() = Flags.modesApi() && Flags.modesUi() && Flags.modesUiIcons() } diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/modes/domain/model/ModesTileModel.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/modes/domain/model/ModesTileModel.kt index 904ff3aaad26..db4812342050 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/modes/domain/model/ModesTileModel.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/modes/domain/model/ModesTileModel.kt @@ -21,5 +21,12 @@ import com.android.systemui.common.shared.model.Icon data class ModesTileModel( val isActivated: Boolean, val activeModes: List<String>, - val icon: Icon? = null + val icon: Icon.Loaded, + + /** + * Resource id corresponding to [icon]. Will only be present if it's know to correspond to a + * resource with a known id in SystemUI (such as resources from `android.R`, + * `com.android.internal.R`, or `com.android.systemui.res` itself). + */ + val iconResId: Int? = null ) diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/modes/ui/ModesTileMapper.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/modes/ui/ModesTileMapper.kt index 83c3335ebffb..7f571b135fc8 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/modes/ui/ModesTileMapper.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/modes/ui/ModesTileMapper.kt @@ -16,11 +16,9 @@ package com.android.systemui.qs.tiles.impl.modes.ui -import android.app.Flags import android.content.res.Resources import android.icu.text.MessageFormat import android.widget.Button -import com.android.systemui.common.shared.model.asIcon import com.android.systemui.dagger.qualifiers.Main import com.android.systemui.qs.tiles.base.interactor.QSTileDataToStateMapper import com.android.systemui.qs.tiles.impl.modes.domain.model.ModesTileModel @@ -38,15 +36,10 @@ constructor( ) : QSTileDataToStateMapper<ModesTileModel> { override fun map(config: QSTileConfig, data: ModesTileModel): QSTileState = QSTileState.build(resources, theme, config.uiConfig) { - if (Flags.modesApi() && Flags.modesUi() && Flags.modesUiIcons() && data.icon != null) { - icon = { data.icon } - } else { - val iconRes = - if (data.isActivated) R.drawable.qs_dnd_icon_on else R.drawable.qs_dnd_icon_off - val icon = resources.getDrawable(iconRes, theme).asIcon() - this.iconRes = iconRes - this.icon = { icon } + if (!android.app.Flags.modesUiIcons()) { + iconRes = data.iconResId } + icon = { data.icon } activationState = if (data.isActivated) { QSTileState.ActivationState.ACTIVE diff --git a/packages/SystemUI/src/com/android/systemui/shade/QuickSettingsControllerImpl.java b/packages/SystemUI/src/com/android/systemui/shade/QuickSettingsControllerImpl.java index 16aef6586ee9..34c0cb7c7a31 100644 --- a/packages/SystemUI/src/com/android/systemui/shade/QuickSettingsControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/shade/QuickSettingsControllerImpl.java @@ -1005,7 +1005,7 @@ public class QuickSettingsControllerImpl implements QuickSettingsController, Dum // When expanding QS, let's authenticate the user if possible, // this will speed up notification actions. if (height == 0 && !mKeyguardStateController.canDismissLockScreen()) { - mDeviceEntryFaceAuthInteractor.onQsExpansionStared(); + mDeviceEntryFaceAuthInteractor.onQsExpansionStarted(); } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java index 6eadd2627399..2b44c2f9ea7f 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java @@ -58,6 +58,7 @@ import androidx.core.graphics.ColorUtils; import com.android.app.animation.Interpolators; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.statusbar.StatusBarIcon; +import com.android.internal.statusbar.StatusBarIcon.Shape; import com.android.internal.util.ContrastColorUtil; import com.android.systemui.Flags; import com.android.systemui.res.R; @@ -211,16 +212,19 @@ public class StatusBarIconView extends AnimatedImageView implements StatusIconDi /** Should always be preceded by {@link #reloadDimens()} */ @VisibleForTesting public void maybeUpdateIconScaleDimens() { - // We do not resize and scale system icons (on the right), only notification icons (on the - // left). - if (isNotification()) { - updateIconScaleForNotifications(); + // We scale notification icons (on the left) plus icons on the right that explicitly + // want FIXED_SPACE. + boolean useNonSystemIconScaling = isNotification() + || (usesModeIcons() && mIcon != null && mIcon.shape == Shape.FIXED_SPACE); + + if (useNonSystemIconScaling) { + updateIconScaleForNonSystemIcons(); } else { updateIconScaleForSystemIcons(); } } - private void updateIconScaleForNotifications() { + private void updateIconScaleForNonSystemIcons() { float iconScale; // we need to scale the image size to be same as the original size // (fit mOriginalStatusBarIconSize), then we can scale it with mScaleToFitNewIconSize @@ -411,7 +415,9 @@ public class StatusBarIconView extends AnimatedImageView implements StatusIconDi if (!levelEquals) { setImageLevel(icon.iconLevel); } - + if (usesModeIcons()) { + setScaleType(icon.shape == Shape.FIXED_SPACE ? ScaleType.FIT_CENTER : ScaleType.CENTER); + } if (!visibilityEquals) { setVisibility(icon.visible && !mBlocked ? VISIBLE : GONE); } @@ -501,7 +507,12 @@ public class StatusBarIconView extends AnimatedImageView implements StatusIconDi @Nullable private Drawable loadDrawable(Context context, StatusBarIcon statusBarIcon) { if (usesModeIcons() && statusBarIcon.preloadedIcon != null) { - return statusBarIcon.preloadedIcon.mutate(); + Drawable.ConstantState cached = statusBarIcon.preloadedIcon.getConstantState(); + if (cached != null) { + return cached.newDrawable(mContext.getResources()).mutate(); + } else { + return statusBarIcon.preloadedIcon.mutate(); + } } else { int userId = statusBarIcon.user.getIdentifier(); if (userId == UserHandle.USER_ALL) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java index 05bd1a7676ae..ba39c3bb4124 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java @@ -44,7 +44,7 @@ import android.view.View; import androidx.lifecycle.Observer; -import com.android.settingslib.notification.modes.ZenMode; +import com.android.internal.statusbar.StatusBarIcon; import com.android.systemui.Flags; import com.android.systemui.broadcast.BroadcastDispatcher; import com.android.systemui.dagger.qualifiers.DisplayId; @@ -80,6 +80,7 @@ import com.android.systemui.statusbar.policy.SensorPrivacyController; import com.android.systemui.statusbar.policy.UserInfoController; import com.android.systemui.statusbar.policy.ZenModeController; import com.android.systemui.statusbar.policy.domain.interactor.ZenModeInteractor; +import com.android.systemui.statusbar.policy.domain.model.ZenModeInfo; import com.android.systemui.util.RingerModeTracker; import com.android.systemui.util.kotlin.JavaAdapter; import com.android.systemui.util.time.DateFormatUtil; @@ -363,7 +364,7 @@ public class PhoneStatusBarPolicy // Note that we're not fully replacing ZenModeController with ZenModeInteractor, so // we listen for the extra event here but still add the ZMC callback. mJavaAdapter.alwaysCollectFlow(mZenModeInteractor.getMainActiveMode(), - this::onActiveModeChanged); + this::onMainActiveModeChanged); } mZenController.addCallback(mZenControllerCallback); if (!Flags.statusBarScreenSharingChips()) { @@ -395,20 +396,23 @@ public class PhoneStatusBarPolicy () -> mResources.getString(R.string.accessibility_managed_profile)); } - private void onActiveModeChanged(@Nullable ZenMode mode) { + private void onMainActiveModeChanged(@Nullable ZenModeInfo mainActiveMode) { if (!usesModeIcons()) { - Log.wtf(TAG, "onActiveModeChanged shouldn't be called if MODES_UI_ICONS is disabled"); + Log.wtf(TAG, "onMainActiveModeChanged shouldn't run if MODES_UI_ICONS is disabled"); return; } - boolean visible = mode != null; - if (visible) { - // TODO: b/360399800 - Get the resource id, package, and cached drawable from the mode; - // this is a shortcut for testing. - String resPackage = mode.getIconKey().resPackage(); - int iconResId = mode.getIconKey().resId(); - mIconController.setResourceIcon(mSlotZen, resPackage, iconResId, - /* preloadedIcon= */ null, mode.getName()); + boolean visible = mainActiveMode != null; + if (visible) { + // Shape=FIXED_SPACE because mode icons can be from 3P packages and may not be square; + // we don't want to allow apps to set incredibly wide icons and take up too much space + // in the status bar. + mIconController.setResourceIcon(mSlotZen, + mainActiveMode.getIcon().key().resPackage(), + mainActiveMode.getIcon().key().resId(), + mainActiveMode.getIcon().drawable(), + mainActiveMode.getName(), + StatusBarIcon.Shape.FIXED_SPACE); } if (visible != mZenVisible) { mIconController.setIconVisibility(mSlotZen, visible); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ui/DarkIconManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ui/DarkIconManager.java index 8871dae3c620..6c303303c8f8 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ui/DarkIconManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ui/DarkIconManager.java @@ -16,7 +16,6 @@ package com.android.systemui.statusbar.phone.ui; -import android.view.ViewGroup; import android.widget.LinearLayout; import com.android.internal.statusbar.StatusBarIcon; @@ -64,9 +63,8 @@ public class DarkIconManager extends IconManager { } @Override - protected LinearLayout.LayoutParams onCreateLayoutParams() { - LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams( - ViewGroup.LayoutParams.WRAP_CONTENT, mIconSize); + protected LinearLayout.LayoutParams onCreateLayoutParams(StatusBarIcon.Shape shape) { + LinearLayout.LayoutParams lp = super.onCreateLayoutParams(shape); lp.setMargins(mIconHorizontalMargin, 0, mIconHorizontalMargin, 0); return lp; } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ui/IconManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ui/IconManager.java index 5ad737684ca1..91ead614ffa4 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ui/IconManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ui/IconManager.java @@ -20,6 +20,7 @@ import static com.android.systemui.statusbar.phone.StatusBarIconHolder.TYPE_BIND import static com.android.systemui.statusbar.phone.StatusBarIconHolder.TYPE_ICON; import static com.android.systemui.statusbar.phone.StatusBarIconHolder.TYPE_MOBILE_NEW; import static com.android.systemui.statusbar.phone.StatusBarIconHolder.TYPE_WIFI_NEW; +import static com.android.systemui.statusbar.phone.ui.StatusBarIconControllerImpl.usesModeIcons; import android.annotation.Nullable; import android.content.Context; @@ -27,9 +28,8 @@ import android.os.Bundle; import android.view.ViewGroup; import android.widget.LinearLayout; -import androidx.annotation.VisibleForTesting; - import com.android.internal.statusbar.StatusBarIcon; +import com.android.internal.statusbar.StatusBarIcon.Shape; import com.android.systemui.demomode.DemoModeCommandReceiver; import com.android.systemui.statusbar.BaseStatusBarFrameLayout; import com.android.systemui.statusbar.StatusBarIconView; @@ -155,12 +155,11 @@ public class IconManager implements DemoModeCommandReceiver { }; } - @VisibleForTesting protected StatusBarIconView addIcon(int index, String slot, boolean blocked, StatusBarIcon icon) { StatusBarIconView view = onCreateStatusBarIconView(slot, blocked); view.set(icon); - mGroup.addView(view, index, onCreateLayoutParams()); + mGroup.addView(view, index, onCreateLayoutParams(icon.shape)); return view; } @@ -174,7 +173,7 @@ public class IconManager implements DemoModeCommandReceiver { int index) { mBindableIcons.put(holder.getSlot(), holder); ModernStatusBarView view = holder.getInitializer().createAndBind(mContext); - mGroup.addView(view, index, onCreateLayoutParams()); + mGroup.addView(view, index, onCreateLayoutParams(Shape.WRAP_CONTENT)); if (mIsInDemoMode) { mDemoStatusIcons.addBindableIcon(holder); } @@ -183,7 +182,7 @@ public class IconManager implements DemoModeCommandReceiver { protected StatusIconDisplayable addNewWifiIcon(int index, String slot) { ModernStatusBarWifiView view = onCreateModernStatusBarWifiView(slot); - mGroup.addView(view, index, onCreateLayoutParams()); + mGroup.addView(view, index, onCreateLayoutParams(Shape.WRAP_CONTENT)); if (mIsInDemoMode) { mDemoStatusIcons.addModernWifiView(mWifiViewModel); @@ -199,7 +198,7 @@ public class IconManager implements DemoModeCommandReceiver { int subId ) { BaseStatusBarFrameLayout view = onCreateModernStatusBarMobileView(slot, subId); - mGroup.addView(view, index, onCreateLayoutParams()); + mGroup.addView(view, index, onCreateLayoutParams(Shape.WRAP_CONTENT)); if (mIsInDemoMode) { Context mobileContext = mMobileContextProvider @@ -233,8 +232,12 @@ public class IconManager implements DemoModeCommandReceiver { ); } - protected LinearLayout.LayoutParams onCreateLayoutParams() { - return new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, mIconSize); + protected LinearLayout.LayoutParams onCreateLayoutParams(Shape shape) { + int width = usesModeIcons() && shape == StatusBarIcon.Shape.FIXED_SPACE + ? mIconSize + : ViewGroup.LayoutParams.WRAP_CONTENT; + + return new LinearLayout.LayoutParams(width, mIconSize); } protected void destroy() { @@ -256,6 +259,13 @@ public class IconManager implements DemoModeCommandReceiver { /** Called once an icon has been set. */ public void onSetIcon(int viewIndex, StatusBarIcon icon) { StatusBarIconView view = (StatusBarIconView) mGroup.getChildAt(viewIndex); + if (usesModeIcons()) { + ViewGroup.LayoutParams current = view.getLayoutParams(); + ViewGroup.LayoutParams desired = onCreateLayoutParams(icon.shape); + if (desired.width != current.width || desired.height != current.height) { + view.setLayoutParams(desired); + } + } view.set(icon); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ui/StatusBarIconController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ui/StatusBarIconController.java index ee528e915079..0459b9749e0a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ui/StatusBarIconController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ui/StatusBarIconController.java @@ -70,7 +70,8 @@ public interface StatusBarIconController { * @param preloadedIcon optional drawable corresponding to {@code iconResId}, if known */ void setResourceIcon(String slot, @Nullable String resPackage, @DrawableRes int iconResId, - @Nullable Drawable preloadedIcon, CharSequence contentDescription); + @Nullable Drawable preloadedIcon, CharSequence contentDescription, + StatusBarIcon.Shape shape); /** * Sets up a wifi icon using the new data pipeline. No effect if the wifi icon has already been diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ui/StatusBarIconControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ui/StatusBarIconControllerImpl.java index ad3a9e350c4b..9b6d32bd179d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ui/StatusBarIconControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ui/StatusBarIconControllerImpl.java @@ -234,13 +234,14 @@ public class StatusBarIconControllerImpl implements Tunable, Icon.createWithResource(mContext, resourceId), /* preloadedIcon= */ null, contentDescription, - StatusBarIcon.Type.SystemIcon); + StatusBarIcon.Type.SystemIcon, + StatusBarIcon.Shape.WRAP_CONTENT); } @Override public void setResourceIcon(String slot, @Nullable String resPackage, @DrawableRes int iconResId, @Nullable Drawable preloadedIcon, - CharSequence contentDescription) { + CharSequence contentDescription, StatusBarIcon.Shape shape) { if (!usesModeIcons()) { Log.wtf("TAG", "StatusBarIconController.setResourceIcon() should not be called without " @@ -260,12 +261,13 @@ public class StatusBarIconControllerImpl implements Tunable, icon, preloadedIcon, contentDescription, - StatusBarIcon.Type.ResourceIcon); + StatusBarIcon.Type.ResourceIcon, + shape); } private void setResourceIconInternal(String slot, Icon resourceIcon, @Nullable Drawable preloadedIcon, CharSequence contentDescription, - StatusBarIcon.Type type) { + StatusBarIcon.Type type, StatusBarIcon.Shape shape) { checkArgument(resourceIcon.getType() == Icon.TYPE_RESOURCE, "Expected Icon of TYPE_RESOURCE, but got " + resourceIcon.getType()); String resPackage = resourceIcon.getResPackage(); @@ -277,7 +279,7 @@ public class StatusBarIconControllerImpl implements Tunable, if (holder == null) { StatusBarIcon icon = new StatusBarIcon(UserHandle.SYSTEM, resPackage, resourceIcon, /* iconLevel= */ 0, /* number=*/ 0, - contentDescription, type); + contentDescription, type, shape); icon.preloadedIcon = preloadedIcon; holder = StatusBarIconHolder.fromIcon(icon); setIcon(slot, holder); @@ -286,6 +288,7 @@ public class StatusBarIconControllerImpl implements Tunable, holder.getIcon().icon = resourceIcon; holder.getIcon().contentDescription = contentDescription; holder.getIcon().type = type; + holder.getIcon().shape = shape; holder.getIcon().preloadedIcon = preloadedIcon; handleSet(slot, holder); } @@ -578,7 +581,7 @@ public class StatusBarIconControllerImpl implements Tunable, } } - private static boolean usesModeIcons() { + static boolean usesModeIcons() { return android.app.Flags.modesApi() && android.app.Flags.modesUi() && android.app.Flags.modesUiIcons(); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileConnectionsRepository.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileConnectionsRepository.kt index 5ad8bf1652b6..32e9c85bea81 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileConnectionsRepository.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileConnectionsRepository.kt @@ -21,7 +21,6 @@ import android.telephony.SubscriptionManager import com.android.settingslib.SignalIcon.MobileIconGroup import com.android.settingslib.mobile.MobileMappings import com.android.settingslib.mobile.MobileMappings.Config -import com.android.systemui.statusbar.pipeline.mobile.data.model.ServiceStateModel import com.android.systemui.statusbar.pipeline.mobile.data.model.SubscriptionModel import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.StateFlow @@ -93,17 +92,15 @@ interface MobileConnectionsRepository { val defaultMobileIconGroup: Flow<MobileIconGroup> /** - * [deviceServiceState] is equivalent to the last [Intent.ACTION_SERVICE_STATE] broadcast with a - * subscriptionId of -1 (aka [SubscriptionManager.INVALID_SUBSCRIPTION_ID]). + * Can the device make emergency calls using the device-based service state? This field is only + * useful when all known active subscriptions are OOS and not emergency call capable. * - * While each [MobileConnectionsRepository] listens for the service state of each subscription, - * there is potentially a service state associated with the device itself. This value can be - * used to calculate e.g., the emergency calling capability of the device (as opposed to the - * emergency calling capability of an individual mobile connection) + * Specifically, this checks every [ServiceState] of the device, and looks for any that report + * [ServiceState.isEmergencyOnly]. * - * Note: this is a [StateFlow] using an eager sharing strategy. + * This is an eager flow, and re-evaluates whenever ACTION_SERVICE_STATE is sent for subId = -1. */ - val deviceServiceState: StateFlow<ServiceStateModel?> + val isDeviceEmergencyCallCapable: StateFlow<Boolean> /** * If any active SIM on the device is in diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileRepositorySwitcher.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileRepositorySwitcher.kt index b0681525a137..b247da4f4219 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileRepositorySwitcher.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileRepositorySwitcher.kt @@ -25,7 +25,6 @@ import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.demomode.DemoMode import com.android.systemui.demomode.DemoModeController -import com.android.systemui.statusbar.pipeline.mobile.data.model.ServiceStateModel import com.android.systemui.statusbar.pipeline.mobile.data.model.SubscriptionModel import com.android.systemui.statusbar.pipeline.mobile.data.repository.demo.DemoMobileConnectionsRepository import com.android.systemui.statusbar.pipeline.mobile.data.repository.prod.MobileConnectionsRepositoryImpl @@ -152,16 +151,17 @@ constructor( override val defaultMobileIconGroup: Flow<SignalIcon.MobileIconGroup> = activeRepo.flatMapLatest { it.defaultMobileIconGroup } - override val deviceServiceState: StateFlow<ServiceStateModel?> = + override val isDeviceEmergencyCallCapable: StateFlow<Boolean> = activeRepo - .flatMapLatest { it.deviceServiceState } + .flatMapLatest { it.isDeviceEmergencyCallCapable } .stateIn( scope, SharingStarted.WhileSubscribed(), - realRepository.deviceServiceState.value + realRepository.isDeviceEmergencyCallCapable.value ) override val isAnySimSecure: Flow<Boolean> = activeRepo.flatMapLatest { it.isAnySimSecure } + override fun getIsAnySimSecure(): Boolean = activeRepo.value.getIsAnySimSecure() override val defaultDataSubId: StateFlow<Int> = diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionsRepository.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionsRepository.kt index a944e9133a31..3a79f3fb3573 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionsRepository.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionsRepository.kt @@ -27,7 +27,6 @@ import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.log.table.TableLogBufferFactory import com.android.systemui.statusbar.pipeline.mobile.data.model.ResolvedNetworkType import com.android.systemui.statusbar.pipeline.mobile.data.model.ResolvedNetworkType.DefaultNetworkType -import com.android.systemui.statusbar.pipeline.mobile.data.model.ServiceStateModel import com.android.systemui.statusbar.pipeline.mobile.data.model.SubscriptionModel import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionRepository import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionsRepository @@ -137,10 +136,11 @@ constructor( override val defaultMobileIconGroup = flowOf(TelephonyIcons.THREE_G) - // TODO(b/339023069): demo command for device-based connectivity state - override val deviceServiceState: StateFlow<ServiceStateModel?> = MutableStateFlow(null) + // TODO(b/339023069): demo command for device-based emergency calls state + override val isDeviceEmergencyCallCapable: StateFlow<Boolean> = MutableStateFlow(false) override val isAnySimSecure: Flow<Boolean> = flowOf(getIsAnySimSecure()) + override fun getIsAnySimSecure(): Boolean = false override val defaultMobileIconMapping = MutableStateFlow(TelephonyIcons.ICON_NAME_TO_ICON) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryImpl.kt index 261258a58914..b756a05da182 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryImpl.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryImpl.kt @@ -21,7 +21,6 @@ import android.content.Context import android.content.Intent import android.content.IntentFilter import android.telephony.CarrierConfigManager -import android.telephony.ServiceState import android.telephony.SubscriptionInfo import android.telephony.SubscriptionManager import android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID @@ -49,7 +48,6 @@ import com.android.systemui.statusbar.pipeline.airplane.data.repository.Airplane import com.android.systemui.statusbar.pipeline.dagger.MobileSummaryLog import com.android.systemui.statusbar.pipeline.mobile.data.MobileInputLogger import com.android.systemui.statusbar.pipeline.mobile.data.model.NetworkNameModel -import com.android.systemui.statusbar.pipeline.mobile.data.model.ServiceStateModel import com.android.systemui.statusbar.pipeline.mobile.data.model.SubscriptionModel import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionsRepository import com.android.systemui.statusbar.pipeline.mobile.util.MobileMappingsProxy @@ -72,7 +70,6 @@ import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.distinctUntilChanged -import kotlinx.coroutines.flow.filterNotNull import kotlinx.coroutines.flow.flowOn import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.mapLatest @@ -175,8 +172,8 @@ constructor( } .flowOn(bgDispatcher) - /** Note that this flow is eager, so we don't miss any state */ - override val deviceServiceState: StateFlow<ServiceStateModel?> = + /** Turn ACTION_SERVICE_STATE (for subId = -1) into an event */ + private val serviceStateChangedEvent: Flow<Unit> = broadcastDispatcher .broadcastFlow(IntentFilter(Intent.ACTION_SERVICE_STATE)) { intent, _ -> val subId = @@ -185,24 +182,34 @@ constructor( INVALID_SUBSCRIPTION_ID ) - val extras = intent.extras - if (extras == null) { - logger.logTopLevelServiceStateBroadcastMissingExtras(subId) - return@broadcastFlow null - } - - val serviceState = ServiceState.newFromBundle(extras) - logger.logTopLevelServiceStateBroadcastEmergencyOnly(subId, serviceState) + // Only emit if the subId is not associated with an active subscription if (subId == INVALID_SUBSCRIPTION_ID) { - // Assume that -1 here is the device's service state. We don't care about - // other ones. - ServiceStateModel.fromServiceState(serviceState) - } else { - null + Unit } } - .filterNotNull() - .stateIn(scope, SharingStarted.Eagerly, null) + // Emit on start so that we always check the state at least once + .onStart { emit(Unit) } + + /** Eager flow to determine the device-based emergency calls only state */ + override val isDeviceEmergencyCallCapable: StateFlow<Boolean> = + serviceStateChangedEvent + .mapLatest { + val modems = telephonyManager.activeModemCount + // Check the service state for every modem. If any state reports emergency calling + // capable, then consider the device to have emergency call capabilities + (0..<modems) + .map { telephonyManager.getServiceStateForSlot(it) } + .any { it?.isEmergencyOnly == true } + } + .flowOn(bgDispatcher) + .distinctUntilChanged() + .logDiffsForTable( + tableLogger, + columnPrefix = LOGGING_PREFIX, + columnName = "deviceEmergencyOnly", + initialValue = false, + ) + .stateIn(scope, SharingStarted.Eagerly, false) /** * State flow that emits the set of mobile data subscriptions, each represented by its own diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconsInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconsInteractor.kt index 26553e66ac5c..28fff4e68935 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconsInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconsInteractor.kt @@ -385,15 +385,7 @@ constructor( .stateIn(scope, SharingStarted.WhileSubscribed(), false) override val isDeviceInEmergencyCallsOnlyMode: Flow<Boolean> = - mobileConnectionsRepo.deviceServiceState - .map { it?.isEmergencyOnly ?: false } - .distinctUntilChanged() - .logDiffsForTable( - tableLogger, - columnPrefix = LOGGING_PREFIX, - columnName = "deviceEmergencyOnly", - initialValue = false, - ) + mobileConnectionsRepo.isDeviceEmergencyCallCapable /** Vends out new [MobileIconInteractor] for a particular subId */ override fun getMobileConnectionInteractorForSubId(subId: Int): MobileIconInteractor = diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/dagger/StatusBarPolicyModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/dagger/StatusBarPolicyModule.java index 71bcdfcba049..6cebcbd2731a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/dagger/StatusBarPolicyModule.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/dagger/StatusBarPolicyModule.java @@ -22,8 +22,10 @@ import android.os.UserManager; import com.android.internal.R; import com.android.settingslib.devicestate.DeviceStateRotationLockSettingsManager; +import com.android.settingslib.notification.modes.ZenIconLoader; import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.dagger.qualifiers.Main; +import com.android.systemui.dagger.qualifiers.UiBackground; import com.android.systemui.log.LogBuffer; import com.android.systemui.log.LogBufferFactory; import com.android.systemui.settings.UserTracker; @@ -79,6 +81,7 @@ import dagger.Module; import dagger.Provides; import java.util.concurrent.Executor; +import java.util.concurrent.ExecutorService; import javax.inject.Named; @@ -236,4 +239,12 @@ public interface StatusBarPolicyModule { static LogBuffer provideCastControllerLog(LogBufferFactory factory) { return factory.create("CastControllerLog", 50); } + + /** Provides a {@link ZenIconLoader} that fetches icons in a background thread. */ + @Provides + @SysUISingleton + static ZenIconLoader provideZenIconLoader( + @UiBackground ExecutorService backgroundExecutorService) { + return new ZenIconLoader(backgroundExecutorService); + } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/domain/interactor/ZenModeInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/policy/domain/interactor/ZenModeInteractor.kt index a67b47a9a0c9..93c631f65df7 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/domain/interactor/ZenModeInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/domain/interactor/ZenModeInteractor.kt @@ -23,16 +23,20 @@ import android.provider.Settings.Secure.ZEN_DURATION_PROMPT import android.util.Log import androidx.concurrent.futures.await import com.android.settingslib.notification.data.repository.ZenModeRepository +import com.android.settingslib.notification.modes.ZenIcon import com.android.settingslib.notification.modes.ZenIconLoader import com.android.settingslib.notification.modes.ZenMode -import com.android.systemui.common.shared.model.Icon -import com.android.systemui.common.shared.model.asIcon +import com.android.systemui.dagger.qualifiers.Background import com.android.systemui.shared.notifications.data.repository.NotificationSettingsRepository +import com.android.systemui.statusbar.policy.domain.model.ActiveZenModes +import com.android.systemui.statusbar.policy.domain.model.ZenModeInfo import java.time.Duration import javax.inject.Inject +import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.distinctUntilChanged +import kotlinx.coroutines.flow.flowOn import kotlinx.coroutines.flow.map /** @@ -45,9 +49,9 @@ constructor( private val context: Context, private val zenModeRepository: ZenModeRepository, private val notificationSettingsRepository: NotificationSettingsRepository, + @Background private val bgDispatcher: CoroutineDispatcher, + private val iconLoader: ZenIconLoader, ) { - private val iconLoader: ZenIconLoader = ZenIconLoader.getInstance() - val isZenModeEnabled: Flow<Boolean> = zenModeRepository.globalZenMode .map { @@ -76,34 +80,27 @@ constructor( val modes: Flow<List<ZenMode>> = zenModeRepository.modes - val activeModes: Flow<List<ZenMode>> = - modes.map { modes -> modes.filter { mode -> mode.isActive } }.distinctUntilChanged() - - /** Flow returning the most prioritized of the active modes, if any. */ - val mainActiveMode: Flow<ZenMode?> = - activeModes.map { modes -> getMainActiveMode(modes) }.distinctUntilChanged() - - /** - * Given the list of modes (which may include zero or more currently active modes), returns the - * most prioritized of the active modes, if any. - */ - private fun getMainActiveMode(modes: List<ZenMode>): ZenMode? { - return modes.sortedWith(ZenMode.PRIORITIZING_COMPARATOR).firstOrNull { it.isActive } - } + /** Flow returning the currently active mode(s), if any. */ + val activeModes: Flow<ActiveZenModes> = + modes + .map { modes -> + val activeModesList = + modes + .filter { mode -> mode.isActive } + .sortedWith(ZenMode.PRIORITIZING_COMPARATOR) + val mainActiveMode = + activeModesList.firstOrNull()?.let { ZenModeInfo(it.name, getModeIcon(it)) } + + ActiveZenModes(activeModesList.map { m -> m.name }, mainActiveMode) + } + .flowOn(bgDispatcher) + .distinctUntilChanged() - suspend fun getModeIcon(mode: ZenMode): Icon { - return iconLoader.getIcon(context, mode).await().drawable().asIcon() - } + val mainActiveMode: Flow<ZenModeInfo?> = + activeModes.map { a -> a.mainMode }.distinctUntilChanged() - /** - * Given the list of modes (which may include zero or more currently active modes), returns an - * icon representing the active mode, if any (or, if multiple modes are active, to the most - * prioritized one). This icon is suitable for use in the status bar or lockscreen (uses the - * standard DND icon for implicit modes, instead of the launcher icon of the associated - * package). - */ - suspend fun getActiveModeIcon(modes: List<ZenMode>): Icon? { - return getMainActiveMode(modes)?.let { m -> getModeIcon(m) } + suspend fun getModeIcon(mode: ZenMode): ZenIcon { + return iconLoader.getIcon(context, mode).await() } fun activateMode(zenMode: ZenMode) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/domain/model/ActiveZenModes.kt b/packages/SystemUI/src/com/android/systemui/statusbar/policy/domain/model/ActiveZenModes.kt new file mode 100644 index 000000000000..569e517d6ed5 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/domain/model/ActiveZenModes.kt @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.statusbar.policy.domain.model + +import com.android.settingslib.notification.modes.ZenMode + +/** + * Represents the list of [ZenMode] instances that are currently active. + * + * @property modeNames Names of all the active modes, sorted by their priority. + * @property mainMode The most prioritized active mode, if any modes active. Guaranteed to be + * non-null if [modeNames] is not empty. + */ +data class ActiveZenModes(val modeNames: List<String>, val mainMode: ZenModeInfo?) { + fun isAnyActive(): Boolean = modeNames.isNotEmpty() +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/model/ServiceStateModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/policy/domain/model/ZenModeInfo.kt index cce3eb02023b..5004f4c21371 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/model/ServiceStateModel.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/domain/model/ZenModeInfo.kt @@ -14,18 +14,10 @@ * limitations under the License. */ -package com.android.systemui.statusbar.pipeline.mobile.data.model +package com.android.systemui.statusbar.policy.domain.model -import android.telephony.ServiceState +import com.android.settingslib.notification.modes.ZenIcon +import com.android.settingslib.notification.modes.ZenMode -/** - * Simplified representation of a [ServiceState] for use in SystemUI. Add any fields that we need to - * extract from service state here for consumption downstream - */ -data class ServiceStateModel(val isEmergencyOnly: Boolean) { - companion object { - fun fromServiceState(serviceState: ServiceState): ServiceStateModel { - return ServiceStateModel(isEmergencyOnly = serviceState.isEmergencyOnly) - } - } -} +/** Name and icon of a [ZenMode] */ +data class ZenModeInfo(val name: String, val icon: ZenIcon) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/ui/dialog/viewmodel/ModesDialogViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/policy/ui/dialog/viewmodel/ModesDialogViewModel.kt index be90bec03e52..841071347c08 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/ui/dialog/viewmodel/ModesDialogViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/ui/dialog/viewmodel/ModesDialogViewModel.kt @@ -23,6 +23,7 @@ import android.provider.Settings.ACTION_AUTOMATIC_ZEN_RULE_SETTINGS import android.provider.Settings.EXTRA_AUTOMATIC_ZEN_RULE_ID import com.android.settingslib.notification.modes.EnableZenModeDialog import com.android.settingslib.notification.modes.ZenMode +import com.android.systemui.common.shared.model.asIcon import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Background import com.android.systemui.qs.tiles.dialog.QSZenModeDialogMetricsLogger @@ -88,7 +89,7 @@ constructor( modesList.map { mode -> ModeTileViewModel( id = mode.id, - icon = zenModeInteractor.getModeIcon(mode), + icon = zenModeInteractor.getModeIcon(mode).drawable().asIcon(), text = mode.name, subtext = getTileSubtext(mode), enabled = mode.isActive, diff --git a/packages/SystemUI/src/com/android/systemui/util/concurrency/GlobalConcurrencyModule.java b/packages/SystemUI/src/com/android/systemui/util/concurrency/GlobalConcurrencyModule.java index ecf1165566dc..70774f13fe6b 100644 --- a/packages/SystemUI/src/com/android/systemui/util/concurrency/GlobalConcurrencyModule.java +++ b/packages/SystemUI/src/com/android/systemui/util/concurrency/GlobalConcurrencyModule.java @@ -28,6 +28,7 @@ import dagger.Module; import dagger.Provides; import java.util.concurrent.Executor; +import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import javax.inject.Singleton; @@ -81,6 +82,18 @@ public abstract class GlobalConcurrencyModule { @Singleton @UiBackground public static Executor provideUiBackgroundExecutor() { + return provideUiBackgroundExecutorService(); + } + + /** + * Provide an ExecutorService specifically for running UI operations on a separate thread. + * + * <p>Keep submitted runnables short and to the point, just as with any other UI code. + */ + @Provides + @Singleton + @UiBackground + public static ExecutorService provideUiBackgroundExecutorService() { return Executors.newSingleThreadExecutor(); } diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuControllerTest.java index 113a8c05ee66..5e37d4cd1faf 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuControllerTest.java @@ -28,6 +28,7 @@ import static org.mockito.Mockito.when; import android.content.Context; import android.content.ContextWrapper; import android.hardware.display.DisplayManager; +import android.os.Handler; import android.os.UserHandle; import android.provider.Settings; import android.testing.TestableLooper; @@ -80,6 +81,7 @@ public class AccessibilityFloatingMenuControllerTest extends SysuiTestCase { private AccessibilityManager mAccessibilityManager; private KeyguardUpdateMonitor mKeyguardUpdateMonitor; private AccessibilityFloatingMenuController mController; + private TestableLooper mTestableLooper; @Mock private AccessibilityButtonTargetsObserver mTargetsObserver; @Mock @@ -108,6 +110,7 @@ public class AccessibilityFloatingMenuControllerTest extends SysuiTestCase { mViewCaptureAwareWindowManager = new ViewCaptureAwareWindowManager(mWindowManager, mLazyViewCapture, /* isViewCaptureEnabled= */ false); mAccessibilityManager = mContext.getSystemService(AccessibilityManager.class); + mTestableLooper = TestableLooper.get(this); when(mTargetsObserver.getCurrentAccessibilityButtonTargets()) .thenReturn(Settings.Secure.getStringForUser(mContextWrapper.getContentResolver(), @@ -231,7 +234,8 @@ public class AccessibilityFloatingMenuControllerTest extends SysuiTestCase { mKeyguardCallback.onKeyguardVisibilityChanged(false); mKeyguardCallback.onUserSwitching(fakeUserId); - mKeyguardCallback.onUserSwitchComplete(fakeUserId); + mController.mUserInitializationCompleteCallback.onUserInitializationComplete(1); + mTestableLooper.processAllMessages(); assertThat(mController.mFloatingMenu).isNotNull(); } @@ -346,7 +350,8 @@ public class AccessibilityFloatingMenuControllerTest extends SysuiTestCase { new AccessibilityFloatingMenuController(mContextWrapper, windowManager, viewCaptureAwareWindowManager, displayManager, mAccessibilityManager, mTargetsObserver, mModeObserver, mKeyguardUpdateMonitor, mSecureSettings, - displayTracker, mNavigationModeController); + displayTracker, mNavigationModeController, new Handler( + mTestableLooper.getLooper())); controller.init(); return controller; diff --git a/packages/SystemUI/tests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryFaceAuthInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryFaceAuthInteractorTest.kt index 6aecc0e2b8fc..4883d1bb9400 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryFaceAuthInteractorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryFaceAuthInteractorTest.kt @@ -63,6 +63,7 @@ import com.android.systemui.util.mockito.eq import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.test.TestScope import kotlinx.coroutines.test.runCurrent import kotlinx.coroutines.test.runTest @@ -365,7 +366,7 @@ class DeviceEntryFaceAuthInteractorTest : SysuiTestCase() { testScope.runTest { underTest.start() - underTest.onQsExpansionStared() + underTest.onQsExpansionStarted() runCurrent() assertThat(faceAuthRepository.runningAuthRequest.value) @@ -373,6 +374,79 @@ class DeviceEntryFaceAuthInteractorTest : SysuiTestCase() { } @Test + @EnableSceneContainer + fun faceAuthIsRequestedWhenQuickSettingsIsExpandedToTheShade() = + testScope.runTest { + underTest.start() + faceAuthRepository.canRunFaceAuth.value = true + kosmos.sceneInteractor.snapToScene(toScene = Scenes.QuickSettings, "for-test") + runCurrent() + + kosmos.sceneInteractor.changeScene(toScene = Scenes.Shade, loggingReason = "for-test") + kosmos.sceneInteractor.setTransitionState( + MutableStateFlow( + ObservableTransitionState.Transition( + fromScene = Scenes.QuickSettings, + toScene = Scenes.Shade, + currentScene = flowOf(Scenes.QuickSettings), + progress = MutableStateFlow(0.2f), + isInitiatedByUserInput = true, + isUserInputOngoing = flowOf(false), + ) + ) + ) + + runCurrent() + assertThat(faceAuthRepository.runningAuthRequest.value) + .isEqualTo(Pair(FaceAuthUiEvent.FACE_AUTH_TRIGGERED_QS_EXPANDED, true)) + } + + @Test + @EnableSceneContainer + fun faceAuthIsRequestedOnlyOnceWhenQuickSettingsIsExpandedToTheShade() = + testScope.runTest { + underTest.start() + faceAuthRepository.canRunFaceAuth.value = true + kosmos.sceneInteractor.snapToScene(toScene = Scenes.QuickSettings, "for-test") + runCurrent() + + kosmos.sceneInteractor.changeScene(toScene = Scenes.Shade, loggingReason = "for-test") + kosmos.sceneInteractor.setTransitionState( + MutableStateFlow( + ObservableTransitionState.Transition( + fromScene = Scenes.QuickSettings, + toScene = Scenes.Shade, + currentScene = flowOf(Scenes.QuickSettings), + progress = MutableStateFlow(0.2f), + isInitiatedByUserInput = true, + isUserInputOngoing = flowOf(false), + ) + ) + ) + + runCurrent() + assertThat(faceAuthRepository.runningAuthRequest.value) + .isEqualTo(Pair(FaceAuthUiEvent.FACE_AUTH_TRIGGERED_QS_EXPANDED, true)) + faceAuthRepository.runningAuthRequest.value = null + + // expansion progress shouldn't trigger face auth again + kosmos.sceneInteractor.setTransitionState( + MutableStateFlow( + ObservableTransitionState.Transition( + fromScene = Scenes.QuickSettings, + toScene = Scenes.Shade, + currentScene = flowOf(Scenes.QuickSettings), + progress = MutableStateFlow(0.5f), + isInitiatedByUserInput = true, + isUserInputOngoing = flowOf(false), + ) + ) + ) + + assertThat(faceAuthRepository.runningAuthRequest.value).isNull() + } + + @Test fun faceAuthIsRequestedWhenNotificationPanelClicked() = testScope.runTest { underTest.start() diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/ModesTileTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/ModesTileTest.kt index 19735e29834e..8435b1cb71dc 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/ModesTileTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/ModesTileTest.kt @@ -25,9 +25,10 @@ import android.testing.TestableLooper.RunWithLooper import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.internal.logging.MetricsLogger -import com.android.settingslib.notification.data.repository.FakeZenModeRepository import com.android.systemui.SysuiTestCase import com.android.systemui.classifier.FalsingManagerFake +import com.android.systemui.kosmos.testDispatcher +import com.android.systemui.kosmos.testScope import com.android.systemui.plugins.ActivityStarter import com.android.systemui.plugins.statusbar.StatusBarStateController import com.android.systemui.qs.QSHost @@ -41,16 +42,15 @@ import com.android.systemui.qs.tiles.viewmodel.QSTileConfigProvider import com.android.systemui.qs.tiles.viewmodel.QSTileConfigTestBuilder import com.android.systemui.qs.tiles.viewmodel.QSTileUIConfig import com.android.systemui.res.R -import com.android.systemui.shared.notifications.data.repository.NotificationSettingsRepository -import com.android.systemui.statusbar.policy.domain.interactor.ZenModeInteractor +import com.android.systemui.statusbar.policy.data.repository.zenModeRepository +import com.android.systemui.statusbar.policy.domain.interactor.zenModeInteractor import com.android.systemui.statusbar.policy.ui.dialog.ModesDialogDelegate +import com.android.systemui.testKosmos import com.android.systemui.util.mockito.any import com.android.systemui.util.settings.FakeSettings import com.android.systemui.util.settings.SecureSettings import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.ExperimentalCoroutinesApi -import kotlinx.coroutines.test.TestScope -import kotlinx.coroutines.test.UnconfinedTestDispatcher import kotlinx.coroutines.test.runCurrent import kotlinx.coroutines.test.runTest import org.junit.After @@ -59,7 +59,6 @@ import org.junit.Test import org.junit.runner.RunWith import org.mockito.Mock import org.mockito.MockitoAnnotations -import org.mockito.kotlin.mock import org.mockito.kotlin.whenever @OptIn(ExperimentalCoroutinesApi::class) @@ -68,6 +67,9 @@ import org.mockito.kotlin.whenever @RunWith(AndroidJUnit4::class) @RunWithLooper(setAsMainLooper = true) class ModesTileTest : SysuiTestCase() { + private val kosmos = testKosmos() + private val testScope = kosmos.testScope + private val testDispatcher = kosmos.testDispatcher @Mock private lateinit var qsHost: QSHost @@ -85,17 +87,10 @@ class ModesTileTest : SysuiTestCase() { @Mock private lateinit var dialogDelegate: ModesDialogDelegate - private val testDispatcher = UnconfinedTestDispatcher() - private val testScope = TestScope(testDispatcher) - private val inputHandler = FakeQSTileIntentUserInputHandler() - private val zenModeRepository = FakeZenModeRepository() + private val zenModeRepository = kosmos.zenModeRepository private val tileDataInteractor = - ModesTileDataInteractor( - context, - ZenModeInteractor(context, zenModeRepository, mock<NotificationSettingsRepository>()), - testDispatcher - ) + ModesTileDataInteractor(context, kosmos.zenModeInteractor, testDispatcher) private val mapper = ModesTileMapper( context.orCreateTestableResources diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/GlanceableHubContainerControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/GlanceableHubContainerControllerTest.kt index c8ff52ade049..3ba1447eb406 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/shade/GlanceableHubContainerControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/shade/GlanceableHubContainerControllerTest.kt @@ -61,7 +61,6 @@ import com.android.systemui.log.logcatLogBuffer import com.android.systemui.media.controls.controller.keyguardMediaController import com.android.systemui.res.R import com.android.systemui.scene.shared.model.sceneDataSourceDelegator -import com.android.systemui.shade.data.repository.fakeShadeRepository import com.android.systemui.shade.domain.interactor.shadeInteractor import com.android.systemui.statusbar.lockscreen.lockscreenSmartspaceController import com.android.systemui.statusbar.notification.stack.notificationStackScrollLayoutController @@ -706,7 +705,7 @@ class GlanceableHubContainerControllerTest : SysuiTestCase() { verify(containerView).onTouchEvent(DOWN_EVENT) // User is interacting with shade on lockscreen. - fakeShadeRepository.setLegacyLockscreenShadeTracking(true) + shadeTestUtil.setLockscreenShadeTracking(true) testableLooper.processAllMessages() // A move event is ignored while the user is already interacting. @@ -734,7 +733,7 @@ class GlanceableHubContainerControllerTest : SysuiTestCase() { .thenReturn(true) // Shade is open slightly. - fakeShadeRepository.setLegacyShadeExpansion(0.01f) + shadeTestUtil.setShadeExpansion(0.01f) testableLooper.processAllMessages() // Touches are not consumed. diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicyTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicyTest.kt index 76dc65cbc915..2ed34735db1f 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicyTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicyTest.kt @@ -34,6 +34,7 @@ import android.testing.TestableLooper import android.testing.TestableLooper.RunWithLooper import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest +import com.android.internal.statusbar.StatusBarIcon import com.android.settingslib.notification.modes.TestModeBuilder import com.android.systemui.Flags import com.android.systemui.SysuiTestCase @@ -41,6 +42,7 @@ import com.android.systemui.broadcast.BroadcastDispatcher import com.android.systemui.display.domain.interactor.ConnectedDisplayInteractor import com.android.systemui.display.domain.interactor.ConnectedDisplayInteractor.PendingDisplay import com.android.systemui.display.domain.interactor.ConnectedDisplayInteractor.State +import com.android.systemui.kosmos.testScope import com.android.systemui.privacy.PrivacyItemController import com.android.systemui.privacy.logging.PrivacyLogger import com.android.systemui.screenrecord.RecordingController @@ -71,9 +73,7 @@ import com.android.systemui.util.time.DateFormatUtil import com.android.systemui.util.time.FakeSystemClock import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.MutableSharedFlow -import kotlinx.coroutines.test.TestScope -import kotlinx.coroutines.test.UnconfinedTestDispatcher +import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.test.runCurrent import kotlinx.coroutines.test.runTest import org.junit.Before @@ -145,7 +145,7 @@ class PhoneStatusBarPolicyTest : SysuiTestCase() { private lateinit var alarmCallbackCaptor: ArgumentCaptor<NextAlarmController.NextAlarmChangeCallback> - private val testScope = TestScope(UnconfinedTestDispatcher()) + private val testScope = kosmos.testScope private val fakeConnectedDisplayStateProvider = FakeConnectedDisplayStateProvider() private val zenModeController = FakeZenModeController() @@ -249,7 +249,7 @@ class PhoneStatusBarPolicyTest : SysuiTestCase() { statusBarPolicy.init() clearInvocations(iconController) - fakeConnectedDisplayStateProvider.emit(State.CONNECTED) + fakeConnectedDisplayStateProvider.setState(State.CONNECTED) runCurrent() verify(iconController).setIconVisibility(CONNECTED_DISPLAY_SLOT, true) @@ -261,7 +261,8 @@ class PhoneStatusBarPolicyTest : SysuiTestCase() { statusBarPolicy.init() clearInvocations(iconController) - fakeConnectedDisplayStateProvider.emit(State.DISCONNECTED) + fakeConnectedDisplayStateProvider.setState(State.DISCONNECTED) + runCurrent() verify(iconController).setIconVisibility(CONNECTED_DISPLAY_SLOT, false) } @@ -272,9 +273,12 @@ class PhoneStatusBarPolicyTest : SysuiTestCase() { statusBarPolicy.init() clearInvocations(iconController) - fakeConnectedDisplayStateProvider.emit(State.CONNECTED) - fakeConnectedDisplayStateProvider.emit(State.DISCONNECTED) - fakeConnectedDisplayStateProvider.emit(State.CONNECTED) + fakeConnectedDisplayStateProvider.setState(State.CONNECTED) + runCurrent() + fakeConnectedDisplayStateProvider.setState(State.DISCONNECTED) + runCurrent() + fakeConnectedDisplayStateProvider.setState(State.CONNECTED) + runCurrent() inOrder(iconController).apply { verify(iconController).setIconVisibility(CONNECTED_DISPLAY_SLOT, true) @@ -289,7 +293,8 @@ class PhoneStatusBarPolicyTest : SysuiTestCase() { statusBarPolicy.init() clearInvocations(iconController) - fakeConnectedDisplayStateProvider.emit(State.CONNECTED_SECURE) + fakeConnectedDisplayStateProvider.setState(State.CONNECTED_SECURE) + runCurrent() verify(iconController).setIconVisibility(CONNECTED_DISPLAY_SLOT, true) } @@ -390,7 +395,7 @@ class PhoneStatusBarPolicyTest : SysuiTestCase() { } @Test - @EnableFlags(android.app.Flags.FLAG_MODES_UI_ICONS) + @EnableFlags(android.app.Flags.FLAG_MODES_UI, android.app.Flags.FLAG_MODES_UI_ICONS) fun zenModeInteractorActiveModeChanged_showsModeIcon() = testScope.runTest { statusBarPolicy.init() @@ -403,8 +408,8 @@ class PhoneStatusBarPolicyTest : SysuiTestCase() { .setName("Bedtime Mode") .setType(AutomaticZenRule.TYPE_BEDTIME) .setActive(true) - .setPackage("some.package") - .setIconResId(123) + .setPackage(mContext.packageName) + .setIconResId(android.R.drawable.ic_lock_lock) .build(), TestModeBuilder() .setId("other") @@ -412,7 +417,7 @@ class PhoneStatusBarPolicyTest : SysuiTestCase() { .setType(AutomaticZenRule.TYPE_OTHER) .setActive(true) .setPackage(SystemZenRules.PACKAGE_ANDROID) - .setIconResId(456) + .setIconResId(android.R.drawable.ic_media_play) .build(), ) ) @@ -422,17 +427,25 @@ class PhoneStatusBarPolicyTest : SysuiTestCase() { verify(iconController) .setResourceIcon( eq(ZEN_SLOT), - eq("some.package"), - eq(123), - eq(null), - eq("Bedtime Mode") + eq(mContext.packageName), + eq(android.R.drawable.ic_lock_lock), + any(), // non-null + eq("Bedtime Mode"), + eq(StatusBarIcon.Shape.FIXED_SPACE) ) zenModeRepository.deactivateMode("bedtime") runCurrent() verify(iconController) - .setResourceIcon(eq(ZEN_SLOT), eq(null), eq(456), eq(null), eq("Other Mode")) + .setResourceIcon( + eq(ZEN_SLOT), + eq(null), + eq(android.R.drawable.ic_media_play), + any(), // non-null + eq("Other Mode"), + eq(StatusBarIcon.Shape.FIXED_SPACE) + ) zenModeRepository.deactivateMode("other") runCurrent() @@ -441,7 +454,7 @@ class PhoneStatusBarPolicyTest : SysuiTestCase() { } @Test - @EnableFlags(android.app.Flags.FLAG_MODES_UI_ICONS) + @EnableFlags(android.app.Flags.FLAG_MODES_UI, android.app.Flags.FLAG_MODES_UI_ICONS) fun zenModeControllerOnGlobalZenChanged_doesNotUpdateDndIcon() { statusBarPolicy.init() reset(iconController) @@ -450,7 +463,8 @@ class PhoneStatusBarPolicyTest : SysuiTestCase() { verify(iconController, never()).setIconVisibility(eq(ZEN_SLOT), any()) verify(iconController, never()).setIcon(eq(ZEN_SLOT), anyInt(), any()) - verify(iconController, never()).setResourceIcon(eq(ZEN_SLOT), any(), any(), any(), any()) + verify(iconController, never()) + .setResourceIcon(eq(ZEN_SLOT), any(), any(), any(), any(), any()) } @Test @@ -466,7 +480,7 @@ class PhoneStatusBarPolicyTest : SysuiTestCase() { verify(iconController, never()).setIconVisibility(eq(ZEN_SLOT), any()) verify(iconController, never()).setIcon(eq(ZEN_SLOT), anyInt(), any()) verify(iconController, never()) - .setResourceIcon(eq(ZEN_SLOT), any(), any(), any(), any()) + .setResourceIcon(eq(ZEN_SLOT), any(), any(), any(), any(), any()) } @Test @@ -529,9 +543,11 @@ class PhoneStatusBarPolicyTest : SysuiTestCase() { } private class FakeConnectedDisplayStateProvider : ConnectedDisplayInteractor { - private val flow = MutableSharedFlow<State>() + private val flow = MutableStateFlow(State.DISCONNECTED) - suspend fun emit(value: State) = flow.emit(value) + fun setState(value: State) { + flow.value = value + } override val connectedDisplayState: Flow<State> get() = flow diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ui/IconManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ui/IconManagerTest.kt new file mode 100644 index 000000000000..90732d0183d2 --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ui/IconManagerTest.kt @@ -0,0 +1,122 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.statusbar.phone.ui + +import android.app.Flags +import android.graphics.drawable.Icon +import android.os.UserHandle +import android.platform.test.annotations.DisableFlags +import android.platform.test.annotations.EnableFlags +import android.view.ViewGroup +import android.widget.ImageView +import android.widget.LinearLayout +import androidx.test.ext.junit.runners.AndroidJUnit4 +import androidx.test.filters.SmallTest +import com.android.internal.statusbar.StatusBarIcon +import com.android.systemui.SysuiTestCase +import com.android.systemui.statusbar.StatusBarIconView +import com.android.systemui.statusbar.connectivity.ui.MobileContextProvider +import com.android.systemui.statusbar.phone.StatusBarLocation +import com.android.systemui.statusbar.pipeline.mobile.ui.MobileUiAdapter +import com.android.systemui.statusbar.pipeline.wifi.ui.WifiUiAdapter +import com.android.systemui.util.Assert +import com.google.common.truth.Truth.assertThat +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.Mockito.RETURNS_DEEP_STUBS +import org.mockito.kotlin.mock + +@SmallTest +@RunWith(AndroidJUnit4::class) +class IconManagerTest : SysuiTestCase() { + + private lateinit var underTest: IconManager + private lateinit var viewGroup: ViewGroup + + @Before + fun setUp() { + Assert.setTestThread(Thread.currentThread()) + viewGroup = LinearLayout(context) + underTest = + IconManager( + viewGroup, + StatusBarLocation.HOME, + mock<WifiUiAdapter>(defaultAnswer = RETURNS_DEEP_STUBS), + mock<MobileUiAdapter>(defaultAnswer = RETURNS_DEEP_STUBS), + mock<MobileContextProvider>(defaultAnswer = RETURNS_DEEP_STUBS), + ) + } + + @Test + @EnableFlags(Flags.FLAG_MODES_UI, Flags.FLAG_MODES_UI_ICONS) + fun addIcon_shapeWrapContent_addsIconViewWithVariableWidth() { + val sbIcon = newStatusBarIcon(StatusBarIcon.Shape.WRAP_CONTENT) + + underTest.addIcon(0, "slot", false, sbIcon) + + assertThat(viewGroup.childCount).isEqualTo(1) + val iconView = viewGroup.getChildAt(0) as StatusBarIconView + assertThat(iconView).isNotNull() + + assertThat(iconView.layoutParams.width).isEqualTo(ViewGroup.LayoutParams.WRAP_CONTENT) + assertThat(iconView.scaleType).isEqualTo(ImageView.ScaleType.CENTER) + } + + @Test + @EnableFlags(Flags.FLAG_MODES_UI, Flags.FLAG_MODES_UI_ICONS) + fun addIcon_shapeFixedSpace_addsIconViewWithFixedWidth() { + val sbIcon = newStatusBarIcon(StatusBarIcon.Shape.FIXED_SPACE) + + underTest.addIcon(0, "slot", false, sbIcon) + + assertThat(viewGroup.childCount).isEqualTo(1) + val iconView = viewGroup.getChildAt(0) as StatusBarIconView + assertThat(iconView).isNotNull() + + assertThat(iconView.layoutParams.width).isNotEqualTo(ViewGroup.LayoutParams.WRAP_CONTENT) + assertThat(iconView.layoutParams.width).isEqualTo(iconView.layoutParams.height) + assertThat(iconView.scaleType).isEqualTo(ImageView.ScaleType.FIT_CENTER) + } + + @Test + @DisableFlags(Flags.FLAG_MODES_UI_ICONS) + fun addIcon_iconsFlagOff_addsIconViewWithVariableWidth() { + val sbIcon = newStatusBarIcon(StatusBarIcon.Shape.FIXED_SPACE) + + underTest.addIcon(0, "slot", false, sbIcon) + + assertThat(viewGroup.childCount).isEqualTo(1) + val iconView = viewGroup.getChildAt(0) as StatusBarIconView + assertThat(iconView).isNotNull() + + assertThat(iconView.layoutParams.width).isEqualTo(ViewGroup.LayoutParams.WRAP_CONTENT) + assertThat(iconView.scaleType).isEqualTo(ImageView.ScaleType.CENTER) + } + + private fun newStatusBarIcon(shape: StatusBarIcon.Shape) = + StatusBarIcon( + UserHandle.CURRENT, + context.packageName, + Icon.createWithResource(context, android.R.drawable.ic_media_next), + 0, + 0, + "", + StatusBarIcon.Type.ResourceIcon, + shape, + ) +} diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ui/StatusBarIconControllerImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ui/StatusBarIconControllerImplTest.kt index 26a57e4c1ca9..50a13b93ea15 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ui/StatusBarIconControllerImplTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ui/StatusBarIconControllerImplTest.kt @@ -424,7 +424,14 @@ class StatusBarIconControllerImplTest : SysuiTestCase() { @EnableFlags(android.app.Flags.FLAG_MODES_UI, android.app.Flags.FLAG_MODES_UI_ICONS) fun setResourceIcon_setsIconAndPreloadedIconInHolder() { val drawable = ColorDrawable(1) - underTest.setResourceIcon("slot", "some.package", 123, drawable, "description") + underTest.setResourceIcon( + "slot", + "some.package", + 123, + drawable, + "description", + StatusBarIcon.Shape.FIXED_SPACE + ) val iconHolder = iconList.getIconHolder("slot", 0) assertThat(iconHolder).isNotNull() @@ -432,6 +439,7 @@ class StatusBarIconControllerImplTest : SysuiTestCase() { assertThat(iconHolder?.icon?.icon?.resId).isEqualTo(123) assertThat(iconHolder?.icon?.icon?.resPackage).isEqualTo("some.package") assertThat(iconHolder?.icon?.contentDescription).isEqualTo("description") + assertThat(iconHolder?.icon?.shape).isEqualTo(StatusBarIcon.Shape.FIXED_SPACE) assertThat(iconHolder?.icon?.preloadedIcon).isEqualTo(drawable) } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryTest.kt index 76982ae12516..6de2caa59dd3 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryTest.kt @@ -28,7 +28,6 @@ import android.net.NetworkCapabilities.TRANSPORT_WIFI import android.net.vcn.VcnTransportInfo import android.net.wifi.WifiInfo import android.net.wifi.WifiManager -import android.os.Bundle import android.os.ParcelUuid import android.telephony.CarrierConfigManager import android.telephony.ServiceState @@ -56,7 +55,6 @@ import com.android.systemui.log.table.TableLogBufferFactory import com.android.systemui.statusbar.connectivity.WifiPickerTrackerFactory import com.android.systemui.statusbar.pipeline.airplane.data.repository.FakeAirplaneModeRepository import com.android.systemui.statusbar.pipeline.mobile.data.MobileInputLogger -import com.android.systemui.statusbar.pipeline.mobile.data.model.ServiceStateModel import com.android.systemui.statusbar.pipeline.mobile.data.model.SubscriptionModel import com.android.systemui.statusbar.pipeline.mobile.data.repository.CarrierConfigRepository import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionRepository @@ -74,7 +72,6 @@ import com.android.systemui.util.mockito.argumentCaptor import com.android.systemui.util.mockito.capture import com.android.systemui.util.mockito.eq import com.android.systemui.util.mockito.mock -import com.android.systemui.util.mockito.whenever import com.android.systemui.util.time.FakeSystemClock import com.android.wifitrackerlib.MergedCarrierEntry import com.android.wifitrackerlib.WifiEntry @@ -98,6 +95,7 @@ import org.mockito.ArgumentMatchers.anyString import org.mockito.Mock import org.mockito.Mockito.verify import org.mockito.MockitoAnnotations +import org.mockito.kotlin.whenever @Suppress("EXPERIMENTAL_IS_NOT_ENABLED") @OptIn(ExperimentalCoroutinesApi::class) @@ -602,47 +600,85 @@ class MobileConnectionsRepositoryTest : SysuiTestCase() { @SuppressLint("UnspecifiedRegisterReceiverFlag") @Test - fun testDeviceServiceStateFromBroadcast_eagerlyWatchesBroadcast() = + fun testDeviceEmergencyCallState_eagerlyChecksState() = testScope.runTest { - // Value starts out empty (null) - assertThat(underTest.deviceServiceState.value).isNull() + // Value starts out false + assertThat(underTest.isDeviceEmergencyCallCapable.value).isFalse() + whenever(telephonyManager.activeModemCount).thenReturn(1) + whenever(telephonyManager.getServiceStateForSlot(any())).thenAnswer { _ -> + ServiceState().apply { isEmergencyOnly = true } + } // WHEN an appropriate intent gets sent out - val intent = serviceStateIntent(subId = -1, emergencyOnly = false) + val intent = serviceStateIntent(subId = -1) fakeBroadcastDispatcher.sendIntentToMatchingReceiversOnly( context, intent, ) runCurrent() - // THEN the repo's state is updated - val expected = ServiceStateModel(isEmergencyOnly = false) - assertThat(underTest.deviceServiceState.value).isEqualTo(expected) + // THEN the repo's state is updated despite no listeners + assertThat(underTest.isDeviceEmergencyCallCapable.value).isEqualTo(true) } @Test - fun testDeviceServiceStateFromBroadcast_followsSubIdNegativeOne() = + fun testDeviceEmergencyCallState_aggregatesAcrossSlots_oneTrue() = testScope.runTest { - // device based state tracks -1 - val intent = serviceStateIntent(subId = -1, emergencyOnly = false) + val latest by collectLastValue(underTest.isDeviceEmergencyCallCapable) + + // GIVEN there are multiple slots + whenever(telephonyManager.activeModemCount).thenReturn(4) + // GIVEN only one of them reports ECM + whenever(telephonyManager.getServiceStateForSlot(any())).thenAnswer { invocation -> + when (invocation.getArgument(0) as Int) { + 0 -> ServiceState().apply { isEmergencyOnly = false } + 1 -> ServiceState().apply { isEmergencyOnly = false } + 2 -> ServiceState().apply { isEmergencyOnly = true } + 3 -> ServiceState().apply { isEmergencyOnly = false } + else -> null + } + } + + // GIVEN a broadcast goes out for the appropriate subID + val intent = serviceStateIntent(subId = -1) fakeBroadcastDispatcher.sendIntentToMatchingReceiversOnly( context, intent, ) runCurrent() - val deviceBasedState = ServiceStateModel(isEmergencyOnly = false) - assertThat(underTest.deviceServiceState.value).isEqualTo(deviceBasedState) + // THEN the device is in ECM, because one of the service states is + assertThat(latest).isTrue() + } + + @Test + fun testDeviceEmergencyCallState_aggregatesAcrossSlots_allFalse() = + testScope.runTest { + val latest by collectLastValue(underTest.isDeviceEmergencyCallCapable) + + // GIVEN there are multiple slots + whenever(telephonyManager.activeModemCount).thenReturn(4) + // GIVEN only one of them reports ECM + whenever(telephonyManager.getServiceStateForSlot(any())).thenAnswer { invocation -> + when (invocation.getArgument(0) as Int) { + 0 -> ServiceState().apply { isEmergencyOnly = false } + 1 -> ServiceState().apply { isEmergencyOnly = false } + 2 -> ServiceState().apply { isEmergencyOnly = false } + 3 -> ServiceState().apply { isEmergencyOnly = false } + else -> null + } + } - // ... and ignores any other subId - val intent2 = serviceStateIntent(subId = 1, emergencyOnly = true) + // GIVEN a broadcast goes out for the appropriate subID + val intent = serviceStateIntent(subId = -1) fakeBroadcastDispatcher.sendIntentToMatchingReceiversOnly( context, - intent2, + intent, ) runCurrent() - assertThat(underTest.deviceServiceState.value).isEqualTo(deviceBasedState) + // THEN the device is in ECM, because one of the service states is + assertThat(latest).isFalse() } @Test @@ -1549,15 +1585,8 @@ class MobileConnectionsRepositoryTest : SysuiTestCase() { */ private fun serviceStateIntent( subId: Int, - emergencyOnly: Boolean = false, ): Intent { - val serviceState = ServiceState().apply { isEmergencyOnly = emergencyOnly } - - val bundle = Bundle() - serviceState.fillInNotifierBundle(bundle) - return Intent(Intent.ACTION_SERVICE_STATE).apply { - putExtras(bundle) putExtra(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX, subId) } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconsInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconsInteractorTest.kt index cc0eae7e6fea..e218fba1d07a 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconsInteractorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconsInteractorTest.kt @@ -29,7 +29,6 @@ import com.android.systemui.coroutines.collectLastValue import com.android.systemui.flags.FakeFeatureFlagsClassic import com.android.systemui.flags.Flags import com.android.systemui.log.table.TableLogBuffer -import com.android.systemui.statusbar.pipeline.mobile.data.model.ServiceStateModel import com.android.systemui.statusbar.pipeline.mobile.data.model.SubscriptionModel import com.android.systemui.statusbar.pipeline.mobile.data.repository.FakeMobileConnectionRepository import com.android.systemui.statusbar.pipeline.mobile.data.repository.FakeMobileConnectionsRepository @@ -897,13 +896,11 @@ class MobileIconsInteractorTest : SysuiTestCase() { testScope.runTest { val latest by collectLastValue(underTest.isDeviceInEmergencyCallsOnlyMode) - connectionsRepository.deviceServiceState.value = - ServiceStateModel(isEmergencyOnly = true) + connectionsRepository.isDeviceEmergencyCallCapable.value = true assertThat(latest).isTrue() - connectionsRepository.deviceServiceState.value = - ServiceStateModel(isEmergencyOnly = false) + connectionsRepository.isDeviceEmergencyCallCapable.value = false assertThat(latest).isFalse() } diff --git a/packages/SystemUI/tests/utils/src/com/android/settingslib/notification/modes/ZenIconLoaderKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/settingslib/notification/modes/ZenIconLoaderKosmos.kt new file mode 100644 index 000000000000..8541d7704517 --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/settingslib/notification/modes/ZenIconLoaderKosmos.kt @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settingslib.notification.modes + +import com.android.systemui.kosmos.Kosmos +import com.android.systemui.kosmos.Kosmos.Fixture +import com.google.common.util.concurrent.MoreExecutors + +val Kosmos.zenIconLoader by Fixture { ZenIconLoader(MoreExecutors.newDirectExecutorService()) } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeDeviceEntryFaceAuthRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeDeviceEntryFaceAuthRepository.kt index e96aeada0212..5753c6c6e8ea 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeDeviceEntryFaceAuthRepository.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeDeviceEntryFaceAuthRepository.kt @@ -27,7 +27,6 @@ import javax.inject.Inject import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow -import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.filterNotNull @SysUISingleton @@ -37,38 +36,41 @@ class FakeDeviceEntryFaceAuthRepository @Inject constructor() : DeviceEntryFaceA private val _authenticationStatus = MutableStateFlow<FaceAuthenticationStatus?>(null) override val authenticationStatus: Flow<FaceAuthenticationStatus> = _authenticationStatus.filterNotNull() + fun setAuthenticationStatus(status: FaceAuthenticationStatus) { _authenticationStatus.value = status } + private val _detectionStatus = MutableStateFlow<FaceDetectionStatus?>(null) override val detectionStatus: Flow<FaceDetectionStatus> get() = _detectionStatus.filterNotNull() + fun setDetectionStatus(status: FaceDetectionStatus) { _detectionStatus.value = status } private val _isLockedOut = MutableStateFlow(false) override val isLockedOut = _isLockedOut - private val _runningAuthRequest = MutableStateFlow<Pair<FaceAuthUiEvent, Boolean>?>(null) - val runningAuthRequest: StateFlow<Pair<FaceAuthUiEvent, Boolean>?> = - _runningAuthRequest.asStateFlow() + val runningAuthRequest: MutableStateFlow<Pair<FaceAuthUiEvent, Boolean>?> = + MutableStateFlow(null) private val _isAuthRunning = MutableStateFlow(false) override val isAuthRunning: StateFlow<Boolean> = _isAuthRunning override val isBypassEnabled = MutableStateFlow(false) + override fun setLockedOut(isLockedOut: Boolean) { _isLockedOut.value = isLockedOut } override fun requestAuthenticate(uiEvent: FaceAuthUiEvent, fallbackToDetection: Boolean) { - _runningAuthRequest.value = uiEvent to fallbackToDetection + runningAuthRequest.value = uiEvent to fallbackToDetection _isAuthRunning.value = true } override fun cancel() { _isAuthRunning.value = false - _runningAuthRequest.value = null + runningAuthRequest.value = null } } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/FakeMobileConnectionsRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/FakeMobileConnectionsRepository.kt index 8229575a128f..e7be639cf92a 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/FakeMobileConnectionsRepository.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/FakeMobileConnectionsRepository.kt @@ -23,7 +23,6 @@ import com.android.settingslib.SignalIcon import com.android.settingslib.mobile.MobileMappings import com.android.settingslib.mobile.TelephonyIcons import com.android.systemui.log.table.TableLogBuffer -import com.android.systemui.statusbar.pipeline.mobile.data.model.ServiceStateModel import com.android.systemui.statusbar.pipeline.mobile.data.model.SubscriptionModel import com.android.systemui.statusbar.pipeline.mobile.util.FakeMobileMappingsProxy import com.android.systemui.statusbar.pipeline.mobile.util.MobileMappingsProxy @@ -94,9 +93,10 @@ class FakeMobileConnectionsRepository( private val _defaultMobileIconGroup = MutableStateFlow(DEFAULT_ICON) override val defaultMobileIconGroup = _defaultMobileIconGroup - override val deviceServiceState = MutableStateFlow<ServiceStateModel?>(null) + override val isDeviceEmergencyCallCapable = MutableStateFlow(false) override val isAnySimSecure = MutableStateFlow(false) + override fun getIsAnySimSecure(): Boolean = isAnySimSecure.value private var isInEcmMode: Boolean = false diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/policy/domain/interactor/ZenModeInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/policy/domain/interactor/ZenModeInteractorKosmos.kt index 66be7e7a7a7e..61b53c9a2067 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/policy/domain/interactor/ZenModeInteractorKosmos.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/policy/domain/interactor/ZenModeInteractorKosmos.kt @@ -17,8 +17,10 @@ package com.android.systemui.statusbar.policy.domain.interactor import android.content.testableContext +import com.android.settingslib.notification.modes.zenIconLoader import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.Kosmos.Fixture +import com.android.systemui.kosmos.testDispatcher import com.android.systemui.shared.notifications.data.repository.notificationSettingsRepository import com.android.systemui.statusbar.policy.data.repository.zenModeRepository @@ -27,5 +29,7 @@ val Kosmos.zenModeInteractor by Fixture { context = testableContext, zenModeRepository = zenModeRepository, notificationSettingsRepository = notificationSettingsRepository, + bgDispatcher = testDispatcher, + iconLoader = zenIconLoader, ) } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakeStatusBarIconController.java b/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakeStatusBarIconController.java index 2dbac670b298..0089199cfb88 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakeStatusBarIconController.java +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakeStatusBarIconController.java @@ -64,7 +64,8 @@ public class FakeStatusBarIconController extends BaseLeakChecker<IconManager> @Override public void setResourceIcon(String slot, @Nullable String resPackage, int iconResId, - @Nullable Drawable preloadedIcon, CharSequence contentDescription) { + @Nullable Drawable preloadedIcon, CharSequence contentDescription, + StatusBarIcon.Shape shape) { } @Override diff --git a/ravenwood/TEST_MAPPING b/ravenwood/TEST_MAPPING index b73f2359f909..469759bc4b40 100644 --- a/ravenwood/TEST_MAPPING +++ b/ravenwood/TEST_MAPPING @@ -2,13 +2,11 @@ "presubmit": [ { "name": "tiny-framework-dump-test" }, { "name": "hoststubgentest" }, + { "name": "hoststubgen-test-tiny-test" }, { "name": "hoststubgen-invoke-test" }, - { - "name": "RavenwoodMockitoTest_device" - }, - { - "name": "RavenwoodBivalentTest_device" - }, + { "name": "RavenwoodMockitoTest_device" }, + { "name": "RavenwoodBivalentTest_device" }, + // The sysui tests should match vendor/unbundled_google/packages/SystemUIGoogle/TEST_MAPPING { "name": "SystemUIGoogleTests", diff --git a/ravenwood/bivalenttest/test/com/android/ravenwoodtest/bivalenttest/ravenizer/CallTracker.java b/ravenwood/bivalenttest/test/com/android/ravenwoodtest/bivalenttest/ravenizer/CallTracker.java index 8dadd398ad55..09a0aa8dbaa2 100644 --- a/ravenwood/bivalenttest/test/com/android/ravenwoodtest/bivalenttest/ravenizer/CallTracker.java +++ b/ravenwood/bivalenttest/test/com/android/ravenwoodtest/bivalenttest/ravenizer/CallTracker.java @@ -64,7 +64,7 @@ public class CallTracker { /** * Check the number of calls stored in {@link #mNumCalled}. */ - protected void assertCalls(Object... methodNameAndCountPairs) { + public void assertCalls(Object... methodNameAndCountPairs) { // Create a local copy HashMap<String, Integer> counts = new HashMap<>(mNumCalled); for (int i = 0; i < methodNameAndCountPairs.length - 1; i += 2) { @@ -95,7 +95,7 @@ public class CallTracker { * Same as {@link #assertCalls(Object...)} but it kills the process if it fails. * Only use in @AfterClass. */ - protected void assertCallsOrDie(Object... methodNameAndCountPairs) { + public void assertCallsOrDie(Object... methodNameAndCountPairs) { try { assertCalls(methodNameAndCountPairs); } catch (Throwable th) { diff --git a/ravenwood/bivalenttest/test/com/android/ravenwoodtest/bivalenttest/ravenizer/RavenwoodNoRavenizerTest.java b/ravenwood/bivalenttest/test/com/android/ravenwoodtest/bivalenttest/ravenizer/RavenwoodNoRavenizerTest.java new file mode 100644 index 000000000000..9d878f444e5e --- /dev/null +++ b/ravenwood/bivalenttest/test/com/android/ravenwoodtest/bivalenttest/ravenizer/RavenwoodNoRavenizerTest.java @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.ravenwoodtest.bivalenttest.ravenizer; + +import android.platform.test.annotations.NoRavenizer; +import android.platform.test.ravenwood.RavenwoodAwareTestRunner.RavenwoodTestRunnerInitializing; + +import org.junit.Test; + +/** + * Test for {@link android.platform.test.annotations.NoRavenizer} + */ +@NoRavenizer +public class RavenwoodNoRavenizerTest { + public static final String TAG = "RavenwoodNoRavenizerTest"; + + private static final CallTracker sCallTracker = new CallTracker(); + + /** + * With @NoRavenizer, this method shouldn't be called. + */ + @RavenwoodTestRunnerInitializing + public static void ravenwoodRunnerInitializing() { + sCallTracker.incrementMethodCallCount(); + } + + /** + * Make sure ravenwoodRunnerInitializing() wasn't called. + */ + @Test + public void testNotRavenized() { + sCallTracker.assertCalls( + "ravenwoodRunnerInitializing", 0 + ); + } +} diff --git a/ravenwood/bivalenttest/test/com/android/ravenwoodtest/bivalenttest/ravenizer/RavenwoodSuiteTest.java b/ravenwood/bivalenttest/test/com/android/ravenwoodtest/bivalenttest/ravenizer/RavenwoodSuiteTest.java new file mode 100644 index 000000000000..7e396c2080eb --- /dev/null +++ b/ravenwood/bivalenttest/test/com/android/ravenwoodtest/bivalenttest/ravenizer/RavenwoodSuiteTest.java @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.ravenwoodtest.bivalenttest.ravenizer; + +import android.util.Log; + +import org.junit.AfterClass; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Suite; + +/** + * Test to make sure {@link Suite} works with the ravenwood test runner. + */ +@RunWith(Suite.class) +@Suite.SuiteClasses({ + RavenwoodSuiteTest.Test1.class, + RavenwoodSuiteTest.Test2.class +}) +public class RavenwoodSuiteTest { + public static final String TAG = "RavenwoodSuiteTest"; + + private static final CallTracker sCallTracker = new CallTracker(); + + @AfterClass + public static void afterClass() { + Log.i(TAG, "afterClass called"); + + sCallTracker.assertCallsOrDie( + "test1", 1, + "test2", 1 + ); + } + + /** + * Workaround for the issue where tradefed won't think a class is a test class + * if it has a @RunWith but no @Test methods, even if it is a Suite. + */ + @Test + public void testEmpty() { + } + + public static class Test1 { + @Test + public void test1() { + sCallTracker.incrementMethodCallCount(); + } + } + + public static class Test2 { + @Test + public void test2() { + sCallTracker.incrementMethodCallCount(); + } + } +} diff --git a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodAwareTestRunnerHook.java b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodAwareTestRunnerHook.java index 1da93eba94f7..f237ba908507 100644 --- a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodAwareTestRunnerHook.java +++ b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodAwareTestRunnerHook.java @@ -57,7 +57,8 @@ public class RavenwoodAwareTestRunnerHook { */ public static void onRunnerInitializing(Runner runner, TestClass testClass) { // This log call also ensures the framework JNI is loaded. - Log.i(TAG, "onRunnerInitializing: testClass=" + testClass + " runner=" + runner); + Log.i(TAG, "onRunnerInitializing: testClass=" + testClass.getJavaClass() + + " runner=" + runner); // TODO: Move the initialization code to a better place. diff --git a/ravenwood/junit-src/android/platform/test/annotations/NoRavenizer.java b/ravenwood/junit-src/android/platform/test/annotations/NoRavenizer.java new file mode 100644 index 000000000000..a84f16f619d3 --- /dev/null +++ b/ravenwood/junit-src/android/platform/test/annotations/NoRavenizer.java @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.platform.test.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Inherited; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Disable the ravenizer preprocessor for a class. This should be only used for testing + * ravenizer itself, or to workaround issues with the preprocessor. A test class probably won't run + * properly if it's not preprocessed. + * + * @hide + */ +@Inherited +@Target({ElementType.TYPE}) +@Retention(RetentionPolicy.RUNTIME) +public @interface NoRavenizer { +} diff --git a/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodAwareTestRunner.java b/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodAwareTestRunner.java index 2b55ac52ab75..7d991663f4b1 100644 --- a/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodAwareTestRunner.java +++ b/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodAwareTestRunner.java @@ -21,10 +21,13 @@ import static com.android.ravenwood.common.RavenwoodCommonUtils.isOnRavenwood; import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.ElementType.TYPE; +import android.util.Log; + import com.android.ravenwood.common.RavenwoodCommonUtils; import com.android.ravenwood.common.SneakyThrow; import org.junit.Assume; +import org.junit.internal.builders.AllDefaultPossibilitiesBuilder; import org.junit.rules.TestRule; import org.junit.runner.Description; import org.junit.runner.Runner; @@ -36,8 +39,10 @@ import org.junit.runner.manipulation.Orderable; import org.junit.runner.manipulation.Orderer; import org.junit.runner.manipulation.Sortable; import org.junit.runner.manipulation.Sorter; +import org.junit.runner.notification.Failure; import org.junit.runner.notification.RunNotifier; import org.junit.runners.BlockJUnit4ClassRunner; +import org.junit.runners.model.RunnerBuilder; import org.junit.runners.model.Statement; import org.junit.runners.model.TestClass; @@ -51,8 +56,6 @@ import java.lang.reflect.InvocationTargetException; /** * A test runner used for Ravenwood. * - * TODO: Handle ENABLE_PROBE_IGNORED - * * It will delegate to another runner specified with {@link InnerRunner} * (default = {@link BlockJUnit4ClassRunner}) with the following features. * - Add a {@link RavenwoodAwareTestRunnerHook#onRunnerInitializing} hook, which is called before @@ -134,12 +137,15 @@ public class RavenwoodAwareTestRunner extends Runner implements Filterable, Orde return runner; } - private final TestClass mTestClsas; - private final Runner mRealRunner; + private TestClass mTestClass = null; + private Runner mRealRunner = null; + private Description mDescription = null; + private Throwable mExceptionInConstructor = null; /** Simple logging method. */ private void log(String message) { - RavenwoodCommonUtils.log(TAG, "[" + getTestClass() + " @" + this + "] " + message); + RavenwoodCommonUtils.log(TAG, "[" + getTestClass().getJavaClass() + " @" + this + "] " + + message); } private Error logAndFail(String message, Throwable innerException) { @@ -149,45 +155,76 @@ public class RavenwoodAwareTestRunner extends Runner implements Filterable, Orde } public TestClass getTestClass() { - return mTestClsas; + return mTestClass; } /** * Constructor. */ public RavenwoodAwareTestRunner(Class<?> testClass) { - mTestClsas = new TestClass(testClass); - - /* - * If the class has @DisabledOnRavenwood, then we'll delegate to ClassSkippingTestRunner, - * which simply skips it. - */ - if (isOnRavenwood() && !RavenwoodAwareTestRunnerHook.shouldRunClassOnRavenwood( - mTestClsas.getJavaClass())) { - mRealRunner = new ClassSkippingTestRunner(mTestClsas); - return; - } + try { + mTestClass = new TestClass(testClass); + + /* + * If the class has @DisabledOnRavenwood, then we'll delegate to + * ClassSkippingTestRunner, which simply skips it. + */ + if (isOnRavenwood() && !RavenwoodAwareTestRunnerHook.shouldRunClassOnRavenwood( + mTestClass.getJavaClass())) { + mRealRunner = new ClassSkippingTestRunner(mTestClass); + mDescription = mRealRunner.getDescription(); + return; + } - // Find the real runner. - final Class<? extends Runner> realRunner; - final InnerRunner innerRunnerAnnotation = mTestClsas.getAnnotation(InnerRunner.class); - if (innerRunnerAnnotation != null) { - realRunner = innerRunnerAnnotation.value(); - } else { - // Default runner. - realRunner = BlockJUnit4ClassRunner.class; - } + // Find the real runner. + final Class<? extends Runner> realRunnerClass; + final InnerRunner innerRunnerAnnotation = mTestClass.getAnnotation(InnerRunner.class); + if (innerRunnerAnnotation != null) { + realRunnerClass = innerRunnerAnnotation.value(); + } else { + // Default runner. + realRunnerClass = BlockJUnit4ClassRunner.class; + } - onRunnerInitializing(); + onRunnerInitializing(); - try { - log("Initializing the inner runner: " + realRunner); + try { + log("Initializing the inner runner: " + realRunnerClass); - mRealRunner = realRunner.getConstructor(Class.class).newInstance(testClass); + mRealRunner = instantiateRealRunner(realRunnerClass, testClass); + mDescription = mRealRunner.getDescription(); - } catch (InstantiationException | IllegalAccessException - | InvocationTargetException | NoSuchMethodException e) { - throw logAndFail("Failed to instantiate " + realRunner, e); + } catch (InstantiationException | IllegalAccessException + | InvocationTargetException | NoSuchMethodException e) { + throw logAndFail("Failed to instantiate " + realRunnerClass, e); + } + } catch (Throwable th) { + // If we throw in the constructor, Tradefed may not report it and just ignore the class, + // so record it and throw it when the test actually started. + log("Fatal: Exception detected in constructor: " + th.getMessage() + "\n" + + Log.getStackTraceString(th)); + mExceptionInConstructor = new RuntimeException("Exception detected in constructor", + th); + mDescription = Description.createTestDescription(testClass, "Constructor"); + + // This is for testing if tradefed is fixed. + if ("1".equals(System.getenv("RAVENWOOD_THROW_EXCEPTION_IN_TEST_RUNNER"))) { + throw th; + } + } + } + + private static Runner instantiateRealRunner( + Class<? extends Runner> realRunnerClass, + Class<?> testClass) + throws NoSuchMethodException, InvocationTargetException, InstantiationException, + IllegalAccessException { + try { + return realRunnerClass.getConstructor(Class.class).newInstance(testClass); + } catch (NoSuchMethodException e) { + var runnerBuilder = new AllDefaultPossibilitiesBuilder(); + return realRunnerClass.getConstructor(Class.class, + RunnerBuilder.class).newInstance(testClass, runnerBuilder); } } @@ -202,7 +239,7 @@ public class RavenwoodAwareTestRunner extends Runner implements Filterable, Orde log("onRunnerInitializing"); - RavenwoodAwareTestRunnerHook.onRunnerInitializing(this, mTestClsas); + RavenwoodAwareTestRunnerHook.onRunnerInitializing(this, mTestClass); // Hook point to allow more customization. runAnnotatedMethodsOnRavenwood(RavenwoodTestRunnerInitializing.class, null); @@ -230,7 +267,7 @@ public class RavenwoodAwareTestRunner extends Runner implements Filterable, Orde @Override public Description getDescription() { - return mRealRunner.getDescription(); + return mDescription; } @Override @@ -241,6 +278,10 @@ public class RavenwoodAwareTestRunner extends Runner implements Filterable, Orde return; } + if (maybeReportExceptionFromConstructor(notifier)) { + return; + } + sCurrentRunner.set(this); try { runWithHooks(getDescription(), Scope.Runner, Order.First, @@ -250,6 +291,18 @@ public class RavenwoodAwareTestRunner extends Runner implements Filterable, Orde } } + /** Throw the exception detected in the constructor, if any. */ + private boolean maybeReportExceptionFromConstructor(RunNotifier notifier) { + if (mExceptionInConstructor == null) { + return false; + } + notifier.fireTestStarted(mDescription); + notifier.fireTestFailure(new Failure(mDescription, mExceptionInConstructor)); + notifier.fireTestFinished(mDescription); + + return true; + } + @Override public void filter(Filter filter) throws NoTestsRemainException { if (mRealRunner instanceof Filterable r) { diff --git a/ravenwood/runtime-helper-src/libcore-fake/libcore/util/FP16.java b/ravenwood/runtime-helper-src/libcore-fake/libcore/util/FP16.java new file mode 100644 index 000000000000..478503b699a0 --- /dev/null +++ b/ravenwood/runtime-helper-src/libcore-fake/libcore/util/FP16.java @@ -0,0 +1,814 @@ +/* + * Copyright (C) 2019 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 libcore.util; + +/** + * <p>The {@code FP16} class is a wrapper and a utility class to manipulate half-precision 16-bit + * <a href="https://en.wikipedia.org/wiki/Half-precision_floating-point_format">IEEE 754</a> + * floating point data types (also called fp16 or binary16). A half-precision float can be + * created from or converted to single-precision floats, and is stored in a short data type. + * + * <p>The IEEE 754 standard specifies an fp16 as having the following format:</p> + * <ul> + * <li>Sign bit: 1 bit</li> + * <li>Exponent width: 5 bits</li> + * <li>Significand: 10 bits</li> + * </ul> + * + * <p>The format is laid out as follows:</p> + * <pre> + * 1 11111 1111111111 + * ^ --^-- -----^---- + * sign | |_______ significand + * | + * -- exponent + * </pre> + * + * <p>Half-precision floating points can be useful to save memory and/or + * bandwidth at the expense of range and precision when compared to single-precision + * floating points (fp32).</p> + * <p>To help you decide whether fp16 is the right storage type for you need, please + * refer to the table below that shows the available precision throughout the range of + * possible values. The <em>precision</em> column indicates the step size between two + * consecutive numbers in a specific part of the range.</p> + * + * <table summary="Precision of fp16 across the range"> + * <tr><th>Range start</th><th>Precision</th></tr> + * <tr><td>0</td><td>1 ⁄ 16,777,216</td></tr> + * <tr><td>1 ⁄ 16,384</td><td>1 ⁄ 16,777,216</td></tr> + * <tr><td>1 ⁄ 8,192</td><td>1 ⁄ 8,388,608</td></tr> + * <tr><td>1 ⁄ 4,096</td><td>1 ⁄ 4,194,304</td></tr> + * <tr><td>1 ⁄ 2,048</td><td>1 ⁄ 2,097,152</td></tr> + * <tr><td>1 ⁄ 1,024</td><td>1 ⁄ 1,048,576</td></tr> + * <tr><td>1 ⁄ 512</td><td>1 ⁄ 524,288</td></tr> + * <tr><td>1 ⁄ 256</td><td>1 ⁄ 262,144</td></tr> + * <tr><td>1 ⁄ 128</td><td>1 ⁄ 131,072</td></tr> + * <tr><td>1 ⁄ 64</td><td>1 ⁄ 65,536</td></tr> + * <tr><td>1 ⁄ 32</td><td>1 ⁄ 32,768</td></tr> + * <tr><td>1 ⁄ 16</td><td>1 ⁄ 16,384</td></tr> + * <tr><td>1 ⁄ 8</td><td>1 ⁄ 8,192</td></tr> + * <tr><td>1 ⁄ 4</td><td>1 ⁄ 4,096</td></tr> + * <tr><td>1 ⁄ 2</td><td>1 ⁄ 2,048</td></tr> + * <tr><td>1</td><td>1 ⁄ 1,024</td></tr> + * <tr><td>2</td><td>1 ⁄ 512</td></tr> + * <tr><td>4</td><td>1 ⁄ 256</td></tr> + * <tr><td>8</td><td>1 ⁄ 128</td></tr> + * <tr><td>16</td><td>1 ⁄ 64</td></tr> + * <tr><td>32</td><td>1 ⁄ 32</td></tr> + * <tr><td>64</td><td>1 ⁄ 16</td></tr> + * <tr><td>128</td><td>1 ⁄ 8</td></tr> + * <tr><td>256</td><td>1 ⁄ 4</td></tr> + * <tr><td>512</td><td>1 ⁄ 2</td></tr> + * <tr><td>1,024</td><td>1</td></tr> + * <tr><td>2,048</td><td>2</td></tr> + * <tr><td>4,096</td><td>4</td></tr> + * <tr><td>8,192</td><td>8</td></tr> + * <tr><td>16,384</td><td>16</td></tr> + * <tr><td>32,768</td><td>32</td></tr> + * </table> + * + * <p>This table shows that numbers higher than 1024 lose all fractional precision.</p> + * + * @hide + */ + +public final class FP16 { + /** + * The number of bits used to represent a half-precision float value. + * + * @hide + */ + public static final int SIZE = 16; + + /** + * Epsilon is the difference between 1.0 and the next value representable + * by a half-precision floating-point. + * + * @hide + */ + public static final short EPSILON = (short) 0x1400; + + /** + * Maximum exponent a finite half-precision float may have. + * + * @hide + */ + public static final int MAX_EXPONENT = 15; + /** + * Minimum exponent a normalized half-precision float may have. + * + * @hide + */ + public static final int MIN_EXPONENT = -14; + + /** + * Smallest negative value a half-precision float may have. + * + * @hide + */ + public static final short LOWEST_VALUE = (short) 0xfbff; + /** + * Maximum positive finite value a half-precision float may have. + * + * @hide + */ + public static final short MAX_VALUE = (short) 0x7bff; + /** + * Smallest positive normal value a half-precision float may have. + * + * @hide + */ + public static final short MIN_NORMAL = (short) 0x0400; + /** + * Smallest positive non-zero value a half-precision float may have. + * + * @hide + */ + public static final short MIN_VALUE = (short) 0x0001; + /** + * A Not-a-Number representation of a half-precision float. + * + * @hide + */ + public static final short NaN = (short) 0x7e00; + /** + * Negative infinity of type half-precision float. + * + * @hide + */ + public static final short NEGATIVE_INFINITY = (short) 0xfc00; + /** + * Negative 0 of type half-precision float. + * + * @hide + */ + public static final short NEGATIVE_ZERO = (short) 0x8000; + /** + * Positive infinity of type half-precision float. + * + * @hide + */ + public static final short POSITIVE_INFINITY = (short) 0x7c00; + /** + * Positive 0 of type half-precision float. + * + * @hide + */ + public static final short POSITIVE_ZERO = (short) 0x0000; + + /** + * The offset to shift by to obtain the sign bit. + * + * @hide + */ + public static final int SIGN_SHIFT = 15; + + /** + * The offset to shift by to obtain the exponent bits. + * + * @hide + */ + public static final int EXPONENT_SHIFT = 10; + + /** + * The bitmask to AND a number with to obtain the sign bit. + * + * @hide + */ + public static final int SIGN_MASK = 0x8000; + + /** + * The bitmask to AND a number shifted by {@link #EXPONENT_SHIFT} right, to obtain exponent bits. + * + * @hide + */ + public static final int SHIFTED_EXPONENT_MASK = 0x1f; + + /** + * The bitmask to AND a number with to obtain significand bits. + * + * @hide + */ + public static final int SIGNIFICAND_MASK = 0x3ff; + + /** + * The bitmask to AND with to obtain exponent and significand bits. + * + * @hide + */ + public static final int EXPONENT_SIGNIFICAND_MASK = 0x7fff; + + /** + * The offset of the exponent from the actual value. + * + * @hide + */ + public static final int EXPONENT_BIAS = 15; + + private static final int FP32_SIGN_SHIFT = 31; + private static final int FP32_EXPONENT_SHIFT = 23; + private static final int FP32_SHIFTED_EXPONENT_MASK = 0xff; + private static final int FP32_SIGNIFICAND_MASK = 0x7fffff; + private static final int FP32_EXPONENT_BIAS = 127; + private static final int FP32_QNAN_MASK = 0x400000; + private static final int FP32_DENORMAL_MAGIC = 126 << 23; + private static final float FP32_DENORMAL_FLOAT = Float.intBitsToFloat(FP32_DENORMAL_MAGIC); + + /** Hidden constructor to prevent instantiation. */ + private FP16() {} + + /** + * <p>Compares the two specified half-precision float values. The following + * conditions apply during the comparison:</p> + * + * <ul> + * <li>{@link #NaN} is considered by this method to be equal to itself and greater + * than all other half-precision float values (including {@code #POSITIVE_INFINITY})</li> + * <li>{@link #POSITIVE_ZERO} is considered by this method to be greater than + * {@link #NEGATIVE_ZERO}.</li> + * </ul> + * + * @param x The first half-precision float value to compare. + * @param y The second half-precision float value to compare + * + * @return The value {@code 0} if {@code x} is numerically equal to {@code y}, a + * value less than {@code 0} if {@code x} is numerically less than {@code y}, + * and a value greater than {@code 0} if {@code x} is numerically greater + * than {@code y} + * + * @hide + */ + public static int compare(short x, short y) { + if (less(x, y)) return -1; + if (greater(x, y)) return 1; + + // Collapse NaNs, akin to halfToIntBits(), but we want to keep + // (signed) short value types to preserve the ordering of -0.0 + // and +0.0 + short xBits = isNaN(x) ? NaN : x; + short yBits = isNaN(y) ? NaN : y; + + return (xBits == yBits ? 0 : (xBits < yBits ? -1 : 1)); + } + + /** + * Returns the closest integral half-precision float value to the specified + * half-precision float value. Special values are handled in the + * following ways: + * <ul> + * <li>If the specified half-precision float is NaN, the result is NaN</li> + * <li>If the specified half-precision float is infinity (negative or positive), + * the result is infinity (with the same sign)</li> + * <li>If the specified half-precision float is zero (negative or positive), + * the result is zero (with the same sign)</li> + * </ul> + * + * @param h A half-precision float value + * @return The value of the specified half-precision float rounded to the nearest + * half-precision float value + * + * @hide + */ + public static short rint(short h) { + int bits = h & 0xffff; + int abs = bits & EXPONENT_SIGNIFICAND_MASK; + int result = bits; + + if (abs < 0x3c00) { + result &= SIGN_MASK; + if (abs > 0x3800){ + result |= 0x3c00; + } + } else if (abs < 0x6400) { + int exp = 25 - (abs >> 10); + int mask = (1 << exp) - 1; + result += ((1 << (exp - 1)) - (~(abs >> exp) & 1)); + result &= ~mask; + } + if (isNaN((short) result)) { + // if result is NaN mask with qNaN + // (i.e. mask the most significant mantissa bit with 1) + // to comply with hardware implementations (ARM64, Intel, etc). + result |= NaN; + } + + return (short) result; + } + + /** + * Returns the smallest half-precision float value toward negative infinity + * greater than or equal to the specified half-precision float value. + * Special values are handled in the following ways: + * <ul> + * <li>If the specified half-precision float is NaN, the result is NaN</li> + * <li>If the specified half-precision float is infinity (negative or positive), + * the result is infinity (with the same sign)</li> + * <li>If the specified half-precision float is zero (negative or positive), + * the result is zero (with the same sign)</li> + * </ul> + * + * @param h A half-precision float value + * @return The smallest half-precision float value toward negative infinity + * greater than or equal to the specified half-precision float value + * + * @hide + */ + public static short ceil(short h) { + int bits = h & 0xffff; + int abs = bits & EXPONENT_SIGNIFICAND_MASK; + int result = bits; + + if (abs < 0x3c00) { + result &= SIGN_MASK; + result |= 0x3c00 & -(~(bits >> 15) & (abs != 0 ? 1 : 0)); + } else if (abs < 0x6400) { + abs = 25 - (abs >> 10); + int mask = (1 << abs) - 1; + result += mask & ((bits >> 15) - 1); + result &= ~mask; + } + if (isNaN((short) result)) { + // if result is NaN mask with qNaN + // (i.e. mask the most significant mantissa bit with 1) + // to comply with hardware implementations (ARM64, Intel, etc). + result |= NaN; + } + + return (short) result; + } + + /** + * Returns the largest half-precision float value toward positive infinity + * less than or equal to the specified half-precision float value. + * Special values are handled in the following ways: + * <ul> + * <li>If the specified half-precision float is NaN, the result is NaN</li> + * <li>If the specified half-precision float is infinity (negative or positive), + * the result is infinity (with the same sign)</li> + * <li>If the specified half-precision float is zero (negative or positive), + * the result is zero (with the same sign)</li> + * </ul> + * + * @param h A half-precision float value + * @return The largest half-precision float value toward positive infinity + * less than or equal to the specified half-precision float value + * + * @hide + */ + public static short floor(short h) { + int bits = h & 0xffff; + int abs = bits & EXPONENT_SIGNIFICAND_MASK; + int result = bits; + + if (abs < 0x3c00) { + result &= SIGN_MASK; + result |= 0x3c00 & (bits > 0x8000 ? 0xffff : 0x0); + } else if (abs < 0x6400) { + abs = 25 - (abs >> 10); + int mask = (1 << abs) - 1; + result += mask & -(bits >> 15); + result &= ~mask; + } + if (isNaN((short) result)) { + // if result is NaN mask with qNaN + // i.e. (Mask the most significant mantissa bit with 1) + result |= NaN; + } + + return (short) result; + } + + /** + * Returns the truncated half-precision float value of the specified + * half-precision float value. Special values are handled in the following ways: + * <ul> + * <li>If the specified half-precision float is NaN, the result is NaN</li> + * <li>If the specified half-precision float is infinity (negative or positive), + * the result is infinity (with the same sign)</li> + * <li>If the specified half-precision float is zero (negative or positive), + * the result is zero (with the same sign)</li> + * </ul> + * + * @param h A half-precision float value + * @return The truncated half-precision float value of the specified + * half-precision float value + * + * @hide + */ + public static short trunc(short h) { + int bits = h & 0xffff; + int abs = bits & EXPONENT_SIGNIFICAND_MASK; + int result = bits; + + if (abs < 0x3c00) { + result &= SIGN_MASK; + } else if (abs < 0x6400) { + abs = 25 - (abs >> 10); + int mask = (1 << abs) - 1; + result &= ~mask; + } + + return (short) result; + } + + /** + * Returns the smaller of two half-precision float values (the value closest + * to negative infinity). Special values are handled in the following ways: + * <ul> + * <li>If either value is NaN, the result is NaN</li> + * <li>{@link #NEGATIVE_ZERO} is smaller than {@link #POSITIVE_ZERO}</li> + * </ul> + * + * @param x The first half-precision value + * @param y The second half-precision value + * @return The smaller of the two specified half-precision values + * + * @hide + */ + public static short min(short x, short y) { + if (isNaN(x)) return NaN; + if (isNaN(y)) return NaN; + + if ((x & EXPONENT_SIGNIFICAND_MASK) == 0 && (y & EXPONENT_SIGNIFICAND_MASK) == 0) { + return (x & SIGN_MASK) != 0 ? x : y; + } + + return ((x & SIGN_MASK) != 0 ? 0x8000 - (x & 0xffff) : x & 0xffff) < + ((y & SIGN_MASK) != 0 ? 0x8000 - (y & 0xffff) : y & 0xffff) ? x : y; + } + + /** + * Returns the larger of two half-precision float values (the value closest + * to positive infinity). Special values are handled in the following ways: + * <ul> + * <li>If either value is NaN, the result is NaN</li> + * <li>{@link #POSITIVE_ZERO} is greater than {@link #NEGATIVE_ZERO}</li> + * </ul> + * + * @param x The first half-precision value + * @param y The second half-precision value + * + * @return The larger of the two specified half-precision values + * + * @hide + */ + public static short max(short x, short y) { + if (isNaN(x)) return NaN; + if (isNaN(y)) return NaN; + + if ((x & EXPONENT_SIGNIFICAND_MASK) == 0 && (y & EXPONENT_SIGNIFICAND_MASK) == 0) { + return (x & SIGN_MASK) != 0 ? y : x; + } + + return ((x & SIGN_MASK) != 0 ? 0x8000 - (x & 0xffff) : x & 0xffff) > + ((y & SIGN_MASK) != 0 ? 0x8000 - (y & 0xffff) : y & 0xffff) ? x : y; + } + + /** + * Returns true if the first half-precision float value is less (smaller + * toward negative infinity) than the second half-precision float value. + * If either of the values is NaN, the result is false. + * + * @param x The first half-precision value + * @param y The second half-precision value + * + * @return True if x is less than y, false otherwise + * + * @hide + */ + public static boolean less(short x, short y) { + if (isNaN(x)) return false; + if (isNaN(y)) return false; + + return ((x & SIGN_MASK) != 0 ? 0x8000 - (x & 0xffff) : x & 0xffff) < + ((y & SIGN_MASK) != 0 ? 0x8000 - (y & 0xffff) : y & 0xffff); + } + + /** + * Returns true if the first half-precision float value is less (smaller + * toward negative infinity) than or equal to the second half-precision + * float value. If either of the values is NaN, the result is false. + * + * @param x The first half-precision value + * @param y The second half-precision value + * + * @return True if x is less than or equal to y, false otherwise + * + * @hide + */ + public static boolean lessEquals(short x, short y) { + if (isNaN(x)) return false; + if (isNaN(y)) return false; + + return ((x & SIGN_MASK) != 0 ? 0x8000 - (x & 0xffff) : x & 0xffff) <= + ((y & SIGN_MASK) != 0 ? 0x8000 - (y & 0xffff) : y & 0xffff); + } + + /** + * Returns true if the first half-precision float value is greater (larger + * toward positive infinity) than the second half-precision float value. + * If either of the values is NaN, the result is false. + * + * @param x The first half-precision value + * @param y The second half-precision value + * + * @return True if x is greater than y, false otherwise + * + * @hide + */ + public static boolean greater(short x, short y) { + if (isNaN(x)) return false; + if (isNaN(y)) return false; + + return ((x & SIGN_MASK) != 0 ? 0x8000 - (x & 0xffff) : x & 0xffff) > + ((y & SIGN_MASK) != 0 ? 0x8000 - (y & 0xffff) : y & 0xffff); + } + + /** + * Returns true if the first half-precision float value is greater (larger + * toward positive infinity) than or equal to the second half-precision float + * value. If either of the values is NaN, the result is false. + * + * @param x The first half-precision value + * @param y The second half-precision value + * + * @return True if x is greater than y, false otherwise + * + * @hide + */ + public static boolean greaterEquals(short x, short y) { + if (isNaN(x)) return false; + if (isNaN(y)) return false; + + return ((x & SIGN_MASK) != 0 ? 0x8000 - (x & 0xffff) : x & 0xffff) >= + ((y & SIGN_MASK) != 0 ? 0x8000 - (y & 0xffff) : y & 0xffff); + } + + /** + * Returns true if the two half-precision float values are equal. + * If either of the values is NaN, the result is false. {@link #POSITIVE_ZERO} + * and {@link #NEGATIVE_ZERO} are considered equal. + * + * @param x The first half-precision value + * @param y The second half-precision value + * + * @return True if x is equal to y, false otherwise + * + * @hide + */ + public static boolean equals(short x, short y) { + if (isNaN(x)) return false; + if (isNaN(y)) return false; + + return x == y || ((x | y) & EXPONENT_SIGNIFICAND_MASK) == 0; + } + + /** + * Returns true if the specified half-precision float value represents + * infinity, false otherwise. + * + * @param h A half-precision float value + * @return True if the value is positive infinity or negative infinity, + * false otherwise + * + * @hide + */ + public static boolean isInfinite(short h) { + return (h & EXPONENT_SIGNIFICAND_MASK) == POSITIVE_INFINITY; + } + + /** + * Returns true if the specified half-precision float value represents + * a Not-a-Number, false otherwise. + * + * @param h A half-precision float value + * @return True if the value is a NaN, false otherwise + * + * @hide + */ + public static boolean isNaN(short h) { + return (h & EXPONENT_SIGNIFICAND_MASK) > POSITIVE_INFINITY; + } + + /** + * Returns true if the specified half-precision float value is normalized + * (does not have a subnormal representation). If the specified value is + * {@link #POSITIVE_INFINITY}, {@link #NEGATIVE_INFINITY}, + * {@link #POSITIVE_ZERO}, {@link #NEGATIVE_ZERO}, NaN or any subnormal + * number, this method returns false. + * + * @param h A half-precision float value + * @return True if the value is normalized, false otherwise + * + * @hide + */ + public static boolean isNormalized(short h) { + return (h & POSITIVE_INFINITY) != 0 && (h & POSITIVE_INFINITY) != POSITIVE_INFINITY; + } + + /** + * <p>Converts the specified half-precision float value into a + * single-precision float value. The following special cases are handled:</p> + * <ul> + * <li>If the input is {@link #NaN}, the returned value is {@link Float#NaN}</li> + * <li>If the input is {@link #POSITIVE_INFINITY} or + * {@link #NEGATIVE_INFINITY}, the returned value is respectively + * {@link Float#POSITIVE_INFINITY} or {@link Float#NEGATIVE_INFINITY}</li> + * <li>If the input is 0 (positive or negative), the returned value is +/-0.0f</li> + * <li>Otherwise, the returned value is a normalized single-precision float value</li> + * </ul> + * + * @param h The half-precision float value to convert to single-precision + * @return A normalized single-precision float value + * + * @hide + */ + public static float toFloat(short h) { + int bits = h & 0xffff; + int s = bits & SIGN_MASK; + int e = (bits >>> EXPONENT_SHIFT) & SHIFTED_EXPONENT_MASK; + int m = (bits ) & SIGNIFICAND_MASK; + + int outE = 0; + int outM = 0; + + if (e == 0) { // Denormal or 0 + if (m != 0) { + // Convert denorm fp16 into normalized fp32 + float o = Float.intBitsToFloat(FP32_DENORMAL_MAGIC + m); + o -= FP32_DENORMAL_FLOAT; + return s == 0 ? o : -o; + } + } else { + outM = m << 13; + if (e == 0x1f) { // Infinite or NaN + outE = 0xff; + if (outM != 0) { // SNaNs are quieted + outM |= FP32_QNAN_MASK; + } + } else { + outE = e - EXPONENT_BIAS + FP32_EXPONENT_BIAS; + } + } + + int out = (s << 16) | (outE << FP32_EXPONENT_SHIFT) | outM; + return Float.intBitsToFloat(out); + } + + /** + * <p>Converts the specified single-precision float value into a + * half-precision float value. The following special cases are handled:</p> + * <ul> + * <li>If the input is NaN (see {@link Float#isNaN(float)}), the returned + * value is {@link #NaN}</li> + * <li>If the input is {@link Float#POSITIVE_INFINITY} or + * {@link Float#NEGATIVE_INFINITY}, the returned value is respectively + * {@link #POSITIVE_INFINITY} or {@link #NEGATIVE_INFINITY}</li> + * <li>If the input is 0 (positive or negative), the returned value is + * {@link #POSITIVE_ZERO} or {@link #NEGATIVE_ZERO}</li> + * <li>If the input is a less than {@link #MIN_VALUE}, the returned value + * is flushed to {@link #POSITIVE_ZERO} or {@link #NEGATIVE_ZERO}</li> + * <li>If the input is a less than {@link #MIN_NORMAL}, the returned value + * is a denorm half-precision float</li> + * <li>Otherwise, the returned value is rounded to the nearest + * representable half-precision float value</li> + * </ul> + * + * @param f The single-precision float value to convert to half-precision + * @return A half-precision float value + * + * @hide + */ + public static short toHalf(float f) { + int bits = Float.floatToRawIntBits(f); + int s = (bits >>> FP32_SIGN_SHIFT ); + int e = (bits >>> FP32_EXPONENT_SHIFT) & FP32_SHIFTED_EXPONENT_MASK; + int m = (bits ) & FP32_SIGNIFICAND_MASK; + + int outE = 0; + int outM = 0; + + if (e == 0xff) { // Infinite or NaN + outE = 0x1f; + outM = m != 0 ? 0x200 : 0; + } else { + e = e - FP32_EXPONENT_BIAS + EXPONENT_BIAS; + if (e >= 0x1f) { // Overflow + outE = 0x1f; + } else if (e <= 0) { // Underflow + if (e < -10) { + // The absolute fp32 value is less than MIN_VALUE, flush to +/-0 + } else { + // The fp32 value is a normalized float less than MIN_NORMAL, + // we convert to a denorm fp16 + m = m | 0x800000; + int shift = 14 - e; + outM = m >> shift; + + int lowm = m & ((1 << shift) - 1); + int hway = 1 << (shift - 1); + // if above halfway or exactly halfway and outM is odd + if (lowm + (outM & 1) > hway){ + // Round to nearest even + // Can overflow into exponent bit, which surprisingly is OK. + // This increment relies on the +outM in the return statement below + outM++; + } + } + } else { + outE = e; + outM = m >> 13; + // if above halfway or exactly halfway and outM is odd + if ((m & 0x1fff) + (outM & 0x1) > 0x1000) { + // Round to nearest even + // Can overflow into exponent bit, which surprisingly is OK. + // This increment relies on the +outM in the return statement below + outM++; + } + } + } + // The outM is added here as the +1 increments for outM above can + // cause an overflow in the exponent bit which is OK. + return (short) ((s << SIGN_SHIFT) | (outE << EXPONENT_SHIFT) + outM); + } + + /** + * <p>Returns a hexadecimal string representation of the specified half-precision + * float value. If the value is a NaN, the result is <code>"NaN"</code>, + * otherwise the result follows this format:</p> + * <ul> + * <li>If the sign is positive, no sign character appears in the result</li> + * <li>If the sign is negative, the first character is <code>'-'</code></li> + * <li>If the value is inifinity, the string is <code>"Infinity"</code></li> + * <li>If the value is 0, the string is <code>"0x0.0p0"</code></li> + * <li>If the value has a normalized representation, the exponent and + * significand are represented in the string in two fields. The significand + * starts with <code>"0x1."</code> followed by its lowercase hexadecimal + * representation. Trailing zeroes are removed unless all digits are 0, then + * a single zero is used. The significand representation is followed by the + * exponent, represented by <code>"p"</code>, itself followed by a decimal + * string of the unbiased exponent</li> + * <li>If the value has a subnormal representation, the significand starts + * with <code>"0x0."</code> followed by its lowercase hexadecimal + * representation. Trailing zeroes are removed unless all digits are 0, then + * a single zero is used. The significand representation is followed by the + * exponent, represented by <code>"p-14"</code></li> + * </ul> + * + * @param h A half-precision float value + * @return A hexadecimal string representation of the specified value + * + * @hide + */ + public static String toHexString(short h) { + StringBuilder o = new StringBuilder(); + + int bits = h & 0xffff; + int s = (bits >>> SIGN_SHIFT ); + int e = (bits >>> EXPONENT_SHIFT) & SHIFTED_EXPONENT_MASK; + int m = (bits ) & SIGNIFICAND_MASK; + + if (e == 0x1f) { // Infinite or NaN + if (m == 0) { + if (s != 0) o.append('-'); + o.append("Infinity"); + } else { + o.append("NaN"); + } + } else { + if (s == 1) o.append('-'); + if (e == 0) { + if (m == 0) { + o.append("0x0.0p0"); + } else { + o.append("0x0."); + String significand = Integer.toHexString(m); + o.append(significand.replaceFirst("0{2,}$", "")); + o.append("p-14"); + } + } else { + o.append("0x1."); + String significand = Integer.toHexString(m); + o.append(significand.replaceFirst("0{2,}$", "")); + o.append('p'); + o.append(Integer.toString(e - EXPONENT_BIAS)); + } + } + + return o.toString(); + } +} diff --git a/ravenwood/scripts/remove-ravenizer-output.sh b/ravenwood/scripts/remove-ravenizer-output.sh new file mode 100755 index 000000000000..be15b711b980 --- /dev/null +++ b/ravenwood/scripts/remove-ravenizer-output.sh @@ -0,0 +1,25 @@ +#!/bin/bash +# Copyright (C) 2024 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Delete all the ravenizer output jar files from Soong's intermediate directory. + +# `-a -prune` is needed because otherwise find would be confused if the directory disappears. + +find "${ANDROID_BUILD_TOP:?}/out/soong/.intermediates/" \ + -type d \ + -name 'ravenizer' \ + -print \ + -exec rm -fr \{\} \; \ + -a -prune diff --git a/ravenwood/texts/ravenwood-annotation-allowed-classes.txt b/ravenwood/texts/ravenwood-annotation-allowed-classes.txt index d8366c58c50d..34239b826c67 100644 --- a/ravenwood/texts/ravenwood-annotation-allowed-classes.txt +++ b/ravenwood/texts/ravenwood-annotation-allowed-classes.txt @@ -46,6 +46,7 @@ android.util.EmptyArray android.util.EventLog android.util.FloatProperty android.util.FloatMath +android.util.Half android.util.IndentingPrintWriter android.util.IntArray android.util.IntProperty @@ -277,7 +278,11 @@ android.graphics.ColorSpace android.graphics.Insets android.graphics.Interpolator android.graphics.Matrix +android.graphics.Matrix44 +android.graphics.Outline +android.graphics.ParcelableColorSpace android.graphics.Path +android.graphics.PixelFormat android.graphics.Point android.graphics.PointF android.graphics.Rect diff --git a/ravenwood/tools/ravenizer/src/com/android/platform/test/ravenwood/ravenizer/Exceptions.kt b/ravenwood/tools/ravenizer/src/com/android/platform/test/ravenwood/ravenizer/Exceptions.kt index 3a7fab39e4ac..0dcd271562d1 100644 --- a/ravenwood/tools/ravenizer/src/com/android/platform/test/ravenwood/ravenizer/Exceptions.kt +++ b/ravenwood/tools/ravenizer/src/com/android/platform/test/ravenwood/ravenizer/Exceptions.kt @@ -17,7 +17,14 @@ package com.android.platform.test.ravenwood.ravenizer +import com.android.hoststubgen.UserErrorException + /** * Use it for internal exception that really shouldn't happen. */ class RavenizerInternalException(message: String) : Exception(message) + +/** + * Thrown when an invalid test is detected in the target jar. (e.g. JUni3 tests) + */ +class RavenizerInvalidTestException(message: String) : Exception(message), UserErrorException diff --git a/ravenwood/tools/ravenizer/src/com/android/platform/test/ravenwood/ravenizer/Ravenizer.kt b/ravenwood/tools/ravenizer/src/com/android/platform/test/ravenwood/ravenizer/Ravenizer.kt index e92ef7216e25..a38512ec9f2d 100644 --- a/ravenwood/tools/ravenizer/src/com/android/platform/test/ravenwood/ravenizer/Ravenizer.kt +++ b/ravenwood/tools/ravenizer/src/com/android/platform/test/ravenwood/ravenizer/Ravenizer.kt @@ -44,6 +44,9 @@ data class RavenizerStats( /** Time took to build [ClasNodes] */ var loadStructureTime: Double = .0, + /** Time took to validate the classes */ + var validationTime: Double = .0, + /** Total real time spent for converting the jar file */ var totalProcessTime: Double = .0, @@ -67,6 +70,7 @@ data class RavenizerStats( RavenizerStats{ totalTime=$totalTime, loadStructureTime=$loadStructureTime, + validationTime=$validationTime, totalProcessTime=$totalProcessTime, totalConversionTime=$totalConversionTime, totalCopyTime=$totalCopyTime, @@ -84,16 +88,44 @@ data class RavenizerStats( class Ravenizer(val options: RavenizerOptions) { fun run() { val stats = RavenizerStats() + + val fatalValidation = options.fatalValidation.get + stats.totalTime = log.nTime { - process(options.inJar.get, options.outJar.get, stats) + process( + options.inJar.get, + options.outJar.get, + options.enableValidation.get, + fatalValidation, + stats, + ) } log.i(stats.toString()) } - private fun process(inJar: String, outJar: String, stats: RavenizerStats) { + private fun process( + inJar: String, + outJar: String, + enableValidation: Boolean, + fatalValidation: Boolean, + stats: RavenizerStats, + ) { var allClasses = ClassNodes.loadClassStructures(inJar) { time -> stats.loadStructureTime = time } + if (enableValidation) { + stats.validationTime = log.iTime("Validating classes") { + if (!validateClasses(allClasses)) { + var message = "Invalid test class(es) detected." + + " See error log for details." + if (fatalValidation) { + throw RavenizerInvalidTestException(message) + } else { + log.w("Warning: $message") + } + } + } + } stats.totalProcessTime = log.iTime("$executableName processing $inJar") { ZipFile(inJar).use { inZip -> diff --git a/ravenwood/tools/ravenizer/src/com/android/platform/test/ravenwood/ravenizer/RavenizerOptions.kt b/ravenwood/tools/ravenizer/src/com/android/platform/test/ravenwood/ravenizer/RavenizerOptions.kt index e85e3be31b77..e8341e5ceb06 100644 --- a/ravenwood/tools/ravenizer/src/com/android/platform/test/ravenwood/ravenizer/RavenizerOptions.kt +++ b/ravenwood/tools/ravenizer/src/com/android/platform/test/ravenwood/ravenizer/RavenizerOptions.kt @@ -27,6 +27,12 @@ class RavenizerOptions( /** Output jar file */ var outJar: SetOnce<String> = SetOnce(""), + + /** Whether to enable test validation. */ + var enableValidation: SetOnce<Boolean> = SetOnce(true), + + /** Whether the validation failure is fatal or not. */ + var fatalValidation: SetOnce<Boolean> = SetOnce(false), ) { companion object { fun parseArgs(args: Array<String>): RavenizerOptions { @@ -52,6 +58,12 @@ class RavenizerOptions( "--in-jar" -> ret.inJar.set(nextArg()).ensureFileExists() "--out-jar" -> ret.outJar.set(nextArg()) + "--enable-validation" -> ret.enableValidation.set(true) + "--disable-validation" -> ret.enableValidation.set(false) + + "--fatal-validation" -> ret.fatalValidation.set(true) + "--no-fatal-validation" -> ret.fatalValidation.set(false) + else -> throw ArgumentsException("Unknown option: $arg") } } catch (e: SetOnce.SetMoreThanOnceException) { @@ -74,6 +86,8 @@ class RavenizerOptions( RavenizerOptions{ inJar=$inJar, outJar=$outJar, + enableValidation=$enableValidation, + fatalValidation=$fatalValidation, } """.trimIndent() } diff --git a/ravenwood/tools/ravenizer/src/com/android/platform/test/ravenwood/ravenizer/Utils.kt b/ravenwood/tools/ravenizer/src/com/android/platform/test/ravenwood/ravenizer/Utils.kt index e026e7ab3679..1aa70c08c254 100644 --- a/ravenwood/tools/ravenizer/src/com/android/platform/test/ravenwood/ravenizer/Utils.kt +++ b/ravenwood/tools/ravenizer/src/com/android/platform/test/ravenwood/ravenizer/Utils.kt @@ -15,10 +15,12 @@ */ package com.android.platform.test.ravenwood.ravenizer +import android.platform.test.annotations.NoRavenizer import android.platform.test.ravenwood.RavenwoodAwareTestRunner import com.android.hoststubgen.asm.ClassNodes import com.android.hoststubgen.asm.findAnyAnnotation import com.android.hoststubgen.asm.startsWithAny +import com.android.hoststubgen.asm.toHumanReadableClassName import org.junit.rules.TestRule import org.junit.runner.RunWith import org.objectweb.asm.Type @@ -30,6 +32,7 @@ data class TypeHolder( val desc = type.descriptor val descAsSet = setOf<String>(desc) val internlName = type.internalName + val humanReadableName = type.internalName.toHumanReadableClassName() } val testAnotType = TypeHolder(org.junit.Test::class.java) @@ -37,6 +40,7 @@ val ruleAnotType = TypeHolder(org.junit.Rule::class.java) val classRuleAnotType = TypeHolder(org.junit.ClassRule::class.java) val runWithAnotType = TypeHolder(RunWith::class.java) val innerRunnerAnotType = TypeHolder(RavenwoodAwareTestRunner.InnerRunner::class.java) +val noRavenizerAnotType = TypeHolder(NoRavenizer::class.java) val testRuleType = TypeHolder(TestRule::class.java) val ravenwoodTestRunnerType = TypeHolder(RavenwoodAwareTestRunner::class.java) @@ -87,9 +91,12 @@ fun String.shouldByBypassed(): Boolean { return this.startsWithAny( "java/", // just in case... "javax/", + "junit/", "org/junit/", "org/mockito/", "kotlin/", + "androidx/", + "android/support/", // TODO -- anything else? ) } diff --git a/ravenwood/tools/ravenizer/src/com/android/platform/test/ravenwood/ravenizer/Validator.kt b/ravenwood/tools/ravenizer/src/com/android/platform/test/ravenwood/ravenizer/Validator.kt new file mode 100644 index 000000000000..27092d28ae5e --- /dev/null +++ b/ravenwood/tools/ravenizer/src/com/android/platform/test/ravenwood/ravenizer/Validator.kt @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.platform.test.ravenwood.ravenizer + +import com.android.hoststubgen.asm.ClassNodes +import com.android.hoststubgen.asm.startsWithAny +import com.android.hoststubgen.asm.toHumanReadableClassName +import com.android.hoststubgen.log +import org.objectweb.asm.tree.ClassNode + +fun validateClasses(classes: ClassNodes): Boolean { + var allOk = true + classes.forEach { allOk = checkClass(it, classes) && allOk } + + return allOk +} + +/** + * Validate a class. + * + * - A test class shouldn't extend + * + */ +fun checkClass(cn: ClassNode, classes: ClassNodes): Boolean { + if (cn.name.shouldByBypassed()) { + // Class doesn't need to be checked. + return true + } + var allOk = true + + // See if there's any class that extends a legacy base class. + // But ignore the base classes in android.test. + if (!cn.name.startsWithAny("android/test/")) { + allOk = checkSuperClass(cn, cn, classes) && allOk + } + return allOk +} + +fun checkSuperClass(targetClass: ClassNode, currentClass: ClassNode, classes: ClassNodes): Boolean { + if (currentClass.superName == null || currentClass.superName == "java/lang/Object") { + return true // No parent class + } + if (currentClass.superName.isLegacyTestBaseClass()) { + log.e("Error: Class ${targetClass.name.toHumanReadableClassName()} extends" + + " a legacy test class ${currentClass.superName.toHumanReadableClassName()}.") + return false + } + classes.findClass(currentClass.superName)?.let { + return checkSuperClass(targetClass, it, classes) + } + // Super class not found. + // log.w("Class ${currentClass.superName} not found.") + return true +} + +/** + * Check if a class internal name is a known legacy test base class. + */ +fun String.isLegacyTestBaseClass(): Boolean { + return this.startsWithAny( + "junit/framework/TestCase", + + // In case the test doesn't statically include JUnit, we need + "android/test/AndroidTestCase", + "android/test/InstrumentationTestCase", + "android/test/InstrumentationTestSuite", + ) +} diff --git a/ravenwood/tools/ravenizer/src/com/android/platform/test/ravenwood/ravenizer/adapter/RunnerRewritingAdapter.kt b/ravenwood/tools/ravenizer/src/com/android/platform/test/ravenwood/ravenizer/adapter/RunnerRewritingAdapter.kt index 25cad0213b72..eaef2cf6a956 100644 --- a/ravenwood/tools/ravenizer/src/com/android/platform/test/ravenwood/ravenizer/adapter/RunnerRewritingAdapter.kt +++ b/ravenwood/tools/ravenizer/src/com/android/platform/test/ravenwood/ravenizer/adapter/RunnerRewritingAdapter.kt @@ -30,6 +30,7 @@ import com.android.platform.test.ravenwood.ravenizer.RavenizerInternalException import com.android.platform.test.ravenwood.ravenizer.classRuleAnotType import com.android.platform.test.ravenwood.ravenizer.isTestLookingClass import com.android.platform.test.ravenwood.ravenizer.innerRunnerAnotType +import com.android.platform.test.ravenwood.ravenizer.noRavenizerAnotType import com.android.platform.test.ravenwood.ravenizer.ravenwoodTestRunnerType import com.android.platform.test.ravenwood.ravenizer.ruleAnotType import com.android.platform.test.ravenwood.ravenizer.runWithAnotType @@ -183,7 +184,7 @@ class RunnerRewritingAdapter private constructor( av.visit("value", ravenwoodTestRunnerType.type) av.visitEnd() } - log.d("Processed ${classInternalName.toHumanReadableClassName()}") + log.i("Update the @RunWith: ${classInternalName.toHumanReadableClassName()}") } /* @@ -435,7 +436,19 @@ class RunnerRewritingAdapter private constructor( companion object { fun shouldProcess(classes: ClassNodes, className: String): Boolean { - return isTestLookingClass(classes, className) + if (!isTestLookingClass(classes, className)) { + return false + } + // Don't process a class if it has a @NoRavenizer annotation. + classes.findClass(className)?.let { cn -> + if (cn.findAnyAnnotation(noRavenizerAnotType.descAsSet) != null) { + log.w("Class ${className.toHumanReadableClassName()} has" + + " @${noRavenizerAnotType.humanReadableName}. Skipping." + ) + return false + } + } + return true } fun maybeApply( diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java index 7cbb97e56b01..f1a8b5a96080 100644 --- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java +++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java @@ -163,6 +163,7 @@ import android.view.accessibility.IAccessibilityInteractionConnectionCallback; import android.view.accessibility.IAccessibilityManager; import android.view.accessibility.IAccessibilityManagerClient; import android.view.accessibility.IMagnificationConnection; +import android.view.accessibility.IUserInitializationCompleteCallback; import android.view.inputmethod.EditorInfo; import com.android.internal.R; @@ -366,6 +367,11 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub private final List<SendWindowStateChangedEventRunnable> mSendWindowStateChangedEventRunnables = new ArrayList<>(); + @VisibleForTesting + final HashSet<IUserInitializationCompleteCallback> + mUserInitializationCompleteCallbacks = + new HashSet<IUserInitializationCompleteCallback>(); + @GuardedBy("mLock") private @UserIdInt int mCurrentUserId = UserHandle.USER_SYSTEM; @@ -2034,6 +2040,17 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub obtainMessage(AccessibilityManagerService::announceNewUserIfNeeded, this), WAIT_FOR_USER_STATE_FULLY_INITIALIZED_MILLIS); } + + for (IUserInitializationCompleteCallback callback + : mUserInitializationCompleteCallbacks) { + try { + callback.onUserInitializationComplete(mCurrentUserId); + } catch (RemoteException re) { + Log.e("AccessibilityManagerService", + "Error while dispatching userInitializationComplete callback: ", + re); + } + } } } @@ -6251,6 +6268,24 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub } @Override + @RequiresNoPermission + public void registerUserInitializationCompleteCallback( + IUserInitializationCompleteCallback callback) { + synchronized (mLock) { + mUserInitializationCompleteCallbacks.add(callback); + } + } + + @Override + @RequiresNoPermission + public void unregisterUserInitializationCompleteCallback( + IUserInitializationCompleteCallback callback) { + synchronized (mLock) { + mUserInitializationCompleteCallbacks.remove(callback); + } + } + + @Override @EnforcePermission(INJECT_EVENTS) public void injectInputEventToInputFilter(InputEvent event) { injectInputEventToInputFilter_enforcePermission(); diff --git a/services/appfunctions/java/com/android/server/appfunctions/AppFunctionManagerServiceImpl.java b/services/appfunctions/java/com/android/server/appfunctions/AppFunctionManagerServiceImpl.java index 53885fc5799e..f5d07ef850c8 100644 --- a/services/appfunctions/java/com/android/server/appfunctions/AppFunctionManagerServiceImpl.java +++ b/services/appfunctions/java/com/android/server/appfunctions/AppFunctionManagerServiceImpl.java @@ -94,36 +94,39 @@ public class AppFunctionManagerServiceImpl extends IAppFunctionManager.Stub { targetUser = mCallerValidator.verifyTargetUserHandle( requestInternal.getUserHandle(), validatedCallingPackage); } catch (SecurityException exception) { - safeExecuteAppFunctionCallback.onResult(new ExecuteAppFunctionResponse - .Builder(ExecuteAppFunctionResponse.RESULT_DENIED, - getExceptionMessage(exception)).build()); + safeExecuteAppFunctionCallback.onResult(ExecuteAppFunctionResponse + .newFailure(ExecuteAppFunctionResponse.RESULT_DENIED, + exception.getMessage(), + /*extras=*/ null)); return; } // TODO(b/354956319): Add and honor the new enterprise policies. if (mCallerValidator.isUserOrganizationManaged(targetUser)) { - safeExecuteAppFunctionCallback.onResult(new ExecuteAppFunctionResponse.Builder( + safeExecuteAppFunctionCallback.onResult(ExecuteAppFunctionResponse.newFailure( ExecuteAppFunctionResponse.RESULT_INTERNAL_ERROR, - "Cannot run on a device with a device owner or from the managed profile." - ).build()); + "Cannot run on a device with a device owner or from the managed profile.", + /*extras=*/ null + )); return; } String targetPackageName = requestInternal.getClientRequest().getTargetPackageName(); if (TextUtils.isEmpty(targetPackageName)) { - safeExecuteAppFunctionCallback.onResult(new ExecuteAppFunctionResponse.Builder( + safeExecuteAppFunctionCallback.onResult(ExecuteAppFunctionResponse.newFailure( ExecuteAppFunctionResponse.RESULT_INVALID_ARGUMENT, - "Target package name cannot be empty." - ).build()); + "Target package name cannot be empty.", + /*extras=*/ null + )); return; } if (!mCallerValidator.verifyCallerCanExecuteAppFunction( validatedCallingPackage, targetPackageName)) { - safeExecuteAppFunctionCallback.onResult(new ExecuteAppFunctionResponse - .Builder(ExecuteAppFunctionResponse.RESULT_DENIED, - "Caller does not have permission to execute the appfunction") - .build()); + safeExecuteAppFunctionCallback.onResult(ExecuteAppFunctionResponse + .newFailure(ExecuteAppFunctionResponse.RESULT_DENIED, + "Caller does not have permission to execute the appfunction", + /*extras=*/ null)); return; } @@ -131,10 +134,11 @@ public class AppFunctionManagerServiceImpl extends IAppFunctionManager.Stub { targetPackageName, targetUser); if (serviceIntent == null) { - safeExecuteAppFunctionCallback.onResult(new ExecuteAppFunctionResponse.Builder( + safeExecuteAppFunctionCallback.onResult(ExecuteAppFunctionResponse.newFailure( ExecuteAppFunctionResponse.RESULT_INTERNAL_ERROR, - "Cannot find the target service." - ).build()); + "Cannot find the target service.", + /*extras=*/ null + )); return; } bindAppFunctionServiceUnchecked(requestInternal, serviceIntent, targetUser, @@ -171,9 +175,10 @@ public class AppFunctionManagerServiceImpl extends IAppFunctionManager.Stub { } ); } catch (Exception e) { - safeExecuteAppFunctionCallback.onResult(new ExecuteAppFunctionResponse - .Builder(ExecuteAppFunctionResponse.RESULT_APP_UNKNOWN_ERROR, - getExceptionMessage(e)).build()); + safeExecuteAppFunctionCallback.onResult(ExecuteAppFunctionResponse + .newFailure(ExecuteAppFunctionResponse.RESULT_APP_UNKNOWN_ERROR, + e.getMessage(), + /*extras=*/ null)); serviceUsageCompleteListener.onCompleted(); } } @@ -181,33 +186,32 @@ public class AppFunctionManagerServiceImpl extends IAppFunctionManager.Stub { @Override public void onFailedToConnect() { Slog.e(TAG, "Failed to connect to service"); - safeExecuteAppFunctionCallback.onResult(new ExecuteAppFunctionResponse - .Builder(ExecuteAppFunctionResponse.RESULT_APP_UNKNOWN_ERROR, - "Failed to connect to AppFunctionService").build()); + safeExecuteAppFunctionCallback.onResult(ExecuteAppFunctionResponse + .newFailure(ExecuteAppFunctionResponse.RESULT_APP_UNKNOWN_ERROR, + "Failed to connect to AppFunctionService", + /*extras=*/ null)); } @Override public void onTimedOut() { Slog.e(TAG, "Timed out"); safeExecuteAppFunctionCallback.onResult( - new ExecuteAppFunctionResponse.Builder( + ExecuteAppFunctionResponse.newFailure( ExecuteAppFunctionResponse.RESULT_TIMED_OUT, - "Binding to AppFunctionService timed out." - ).build()); + "Binding to AppFunctionService timed out.", + /*extras=*/ null + )); } } ); if (!bindServiceResult) { Slog.e(TAG, "Failed to bind to the AppFunctionService"); - safeExecuteAppFunctionCallback.onResult(new ExecuteAppFunctionResponse.Builder( + safeExecuteAppFunctionCallback.onResult(ExecuteAppFunctionResponse.newFailure( ExecuteAppFunctionResponse.RESULT_TIMED_OUT, - "Failed to bind the AppFunctionService." - ).build()); + "Failed to bind the AppFunctionService.", + /*extras=*/ null + )); } } - - private String getExceptionMessage(Exception exception) { - return exception.getMessage() == null ? "" : exception.getMessage(); - } } diff --git a/services/core/java/com/android/server/pm/permission/AccessCheckDelegate.java b/services/core/java/com/android/server/pm/permission/AccessCheckDelegate.java index f518769bdb35..e9cb279439a6 100644 --- a/services/core/java/com/android/server/pm/permission/AccessCheckDelegate.java +++ b/services/core/java/com/android/server/pm/permission/AccessCheckDelegate.java @@ -375,24 +375,34 @@ public interface AccessCheckDelegate extends CheckPermissionDelegate, CheckOpsDe @Nullable String message, boolean shouldCollectMessage, boolean skiProxyOperation, @NonNull HexFunction<Integer, AttributionSource, Boolean, String, Boolean, Boolean, SyncNotedAppOp> superImpl) { - if (attributionSource.getUid() == mDelegateAndOwnerUid && isDelegateOp(code)) { - final int shellUid = UserHandle.getUid( - UserHandle.getUserId(attributionSource.getUid()), Process.SHELL_UID); - final long identity = Binder.clearCallingIdentity(); - try { - return superImpl.apply(code, - new AttributionSource(shellUid, Process.INVALID_PID, SHELL_PKG, - attributionSource.getAttributionTag(), - attributionSource.getToken(), /*renouncedPermissions*/ null, - attributionSource.getDeviceId(), attributionSource.getNext()), - shouldCollectAsyncNotedOp, message, shouldCollectMessage, - skiProxyOperation); - } finally { - Binder.restoreCallingIdentity(identity); - } + if (!isDelegateOp(code)) { + return superImpl.apply(code, attributionSource, shouldCollectAsyncNotedOp, + message, shouldCollectMessage, skiProxyOperation); + } + + final int shellUid = UserHandle.getUid( + UserHandle.getUserId(attributionSource.getUid()), Process.SHELL_UID); + AttributionSource next = attributionSource.getNext(); + if (next != null && next.getUid() == mDelegateAndOwnerUid) { + next = new AttributionSource(shellUid, Process.INVALID_PID, SHELL_PKG, + next.getAttributionTag(), next.getToken(), /*renouncedPermissions*/ null, + next.getDeviceId(), next.getNext()); + attributionSource = new AttributionSource(attributionSource, next); + } + if (attributionSource.getUid() == mDelegateAndOwnerUid) { + attributionSource = new AttributionSource(shellUid, Process.INVALID_PID, SHELL_PKG, + attributionSource.getAttributionTag(), + attributionSource.getToken(), /*renouncedPermissions*/ null, + attributionSource.getDeviceId(), attributionSource.getNext()); + } + final long identity = Binder.clearCallingIdentity(); + try { + return superImpl.apply(code, attributionSource, + shouldCollectAsyncNotedOp, message, shouldCollectMessage, + skiProxyOperation); + } finally { + Binder.restoreCallingIdentity(identity); } - return superImpl.apply(code, attributionSource, shouldCollectAsyncNotedOp, - message, shouldCollectMessage, skiProxyOperation); } @Override diff --git a/services/core/java/com/android/server/tv/tunerresourcemanager/CasResource.java b/services/core/java/com/android/server/tv/tunerresourcemanager/CasResource.java index 440d2514537c..eb5361c84b89 100644 --- a/services/core/java/com/android/server/tv/tunerresourcemanager/CasResource.java +++ b/services/core/java/com/android/server/tv/tunerresourcemanager/CasResource.java @@ -26,6 +26,11 @@ import java.util.Set; * @hide */ public class CasResource { + /** + * Handle of the current resource. Should not be changed and should be aligned with the driver + * level implementation. + */ + final int mHandle; private final int mSystemId; @@ -39,11 +44,16 @@ public class CasResource { private Map<Integer, Integer> mOwnerClientIdsToSessionNum = new HashMap<>(); CasResource(Builder builder) { + this.mHandle = builder.mHandle; this.mSystemId = builder.mSystemId; this.mMaxSessionNum = builder.mMaxSessionNum; this.mAvailableSessionNum = builder.mMaxSessionNum; } + public int getHandle() { + return mHandle; + } + public int getSystemId() { return mSystemId; } @@ -136,10 +146,12 @@ public class CasResource { */ public static class Builder { + private final int mHandle; private int mSystemId; protected int mMaxSessionNum; - Builder(int systemId) { + Builder(int handle, int systemId) { + this.mHandle = handle; this.mSystemId = systemId; } diff --git a/services/core/java/com/android/server/tv/tunerresourcemanager/CiCamResource.java b/services/core/java/com/android/server/tv/tunerresourcemanager/CiCamResource.java index 31149f3590b8..5cef729627f0 100644 --- a/services/core/java/com/android/server/tv/tunerresourcemanager/CiCamResource.java +++ b/services/core/java/com/android/server/tv/tunerresourcemanager/CiCamResource.java @@ -42,8 +42,8 @@ public final class CiCamResource extends CasResource { * Builder class for {@link CiCamResource}. */ public static class Builder extends CasResource.Builder { - Builder(int systemId) { - super(systemId); + Builder(int handle, int systemId) { + super(handle, systemId); } /** diff --git a/services/core/java/com/android/server/tv/tunerresourcemanager/TunerResourceManagerService.java b/services/core/java/com/android/server/tv/tunerresourcemanager/TunerResourceManagerService.java index 0afb049d31c7..9229f7f016bc 100644 --- a/services/core/java/com/android/server/tv/tunerresourcemanager/TunerResourceManagerService.java +++ b/services/core/java/com/android/server/tv/tunerresourcemanager/TunerResourceManagerService.java @@ -203,13 +203,7 @@ public class TunerResourceManagerService extends SystemService implements IBinde @Override public void unregisterClientProfile(int clientId) throws RemoteException { enforceTrmAccessPermission("unregisterClientProfile"); - synchronized (mLock) { - if (!checkClientExists(clientId)) { - Slog.e(TAG, "Unregistering non exists client:" + clientId); - return; - } - unregisterClientProfileInternal(clientId); - } + unregisterClientProfileInternal(clientId); } @Override @@ -291,20 +285,7 @@ public class TunerResourceManagerService extends SystemService implements IBinde Slog.e(TAG, "frontendHandle can't be null"); return false; } - synchronized (mLock) { - if (!checkClientExists(request.clientId)) { - Slog.e(TAG, "Request frontend from unregistered client: " - + request.clientId); - return false; - } - // If the request client is holding or sharing a frontend, throw an exception. - if (!getClientProfile(request.clientId).getInUseFrontendHandles().isEmpty()) { - Slog.e(TAG, "Release frontend before requesting another one. Client id: " - + request.clientId); - return false; - } - return requestFrontendInternal(request, frontendHandle); - } + return requestFrontendInternal(request, frontendHandle); } @Override @@ -376,13 +357,7 @@ public class TunerResourceManagerService extends SystemService implements IBinde if (demuxHandle == null) { throw new RemoteException("demuxHandle can't be null"); } - synchronized (mLock) { - if (!checkClientExists(request.clientId)) { - throw new RemoteException("Request demux from unregistered client:" - + request.clientId); - } - return requestDemuxInternal(request, demuxHandle); - } + return requestDemuxInternal(request, demuxHandle); } @Override @@ -409,13 +384,7 @@ public class TunerResourceManagerService extends SystemService implements IBinde if (casSessionHandle == null) { throw new RemoteException("casSessionHandle can't be null"); } - synchronized (mLock) { - if (!checkClientExists(request.clientId)) { - throw new RemoteException("Request cas from unregistered client:" - + request.clientId); - } - return requestCasSessionInternal(request, casSessionHandle); - } + return requestCasSessionInternal(request, casSessionHandle); } @Override @@ -425,13 +394,7 @@ public class TunerResourceManagerService extends SystemService implements IBinde if (ciCamHandle == null) { throw new RemoteException("ciCamHandle can't be null"); } - synchronized (mLock) { - if (!checkClientExists(request.clientId)) { - throw new RemoteException("Request ciCam from unregistered client:" - + request.clientId); - } - return requestCiCamInternal(request, ciCamHandle); - } + return requestCiCamInternal(request, ciCamHandle); } @Override @@ -442,42 +405,14 @@ public class TunerResourceManagerService extends SystemService implements IBinde if (lnbHandle == null) { throw new RemoteException("lnbHandle can't be null"); } - synchronized (mLock) { - if (!checkClientExists(request.clientId)) { - throw new RemoteException("Request lnb from unregistered client:" - + request.clientId); - } - return requestLnbInternal(request, lnbHandle); - } + return requestLnbInternal(request, lnbHandle); } @Override public void releaseFrontend(int frontendHandle, int clientId) throws RemoteException { enforceTunerAccessPermission("releaseFrontend"); enforceTrmAccessPermission("releaseFrontend"); - if (!validateResourceHandle(TunerResourceManager.TUNER_RESOURCE_TYPE_FRONTEND, - frontendHandle)) { - throw new RemoteException("frontendHandle can't be invalid"); - } - synchronized (mLock) { - if (!checkClientExists(clientId)) { - throw new RemoteException("Release frontend from unregistered client:" - + clientId); - } - FrontendResource fe = getFrontendResource(frontendHandle); - if (fe == null) { - throw new RemoteException("Releasing frontend does not exist."); - } - int ownerClientId = fe.getOwnerClientId(); - ClientProfile ownerProfile = getClientProfile(ownerClientId); - if (ownerClientId != clientId - && (ownerProfile != null - && !ownerProfile.getShareFeClientIds().contains(clientId))) { - throw new RemoteException( - "Client is not the current owner of the releasing fe."); - } - releaseFrontendInternal(fe, clientId); - } + releaseFrontendInternal(frontendHandle, clientId); } @Override @@ -746,17 +681,23 @@ public class TunerResourceManagerService extends SystemService implements IBinde @VisibleForTesting protected void unregisterClientProfileInternal(int clientId) { - if (DEBUG) { - Slog.d(TAG, "unregisterClientProfile(clientId=" + clientId + ")"); - } - removeClientProfile(clientId); - // Remove the Media Resource Manager callingPid to tvAppId mapping - if (mMediaResourceManager != null) { - try { - mMediaResourceManager.overridePid(Binder.getCallingPid(), -1); - } catch (RemoteException e) { - Slog.e(TAG, "Could not overridePid in resourceManagerSercice when unregister," - + " remote exception: " + e); + synchronized (mLock) { + if (!checkClientExists(clientId)) { + Slog.e(TAG, "Unregistering non exists client:" + clientId); + return; + } + if (DEBUG) { + Slog.d(TAG, "unregisterClientProfile(clientId=" + clientId + ")"); + } + removeClientProfile(clientId); + // Remove the Media Resource Manager callingPid to tvAppId mapping + if (mMediaResourceManager != null) { + try { + mMediaResourceManager.overridePid(Binder.getCallingPid(), -1); + } catch (RemoteException e) { + Slog.e(TAG, "Could not overridePid in resourceManagerSercice when unregister," + + " remote exception: " + e); + } } } } @@ -992,10 +933,14 @@ public class TunerResourceManagerService extends SystemService implements IBinde return; } // Add the new Cas Resource. - cas = new CasResource.Builder(casSystemId) + int casSessionHandle = generateResourceHandle( + TunerResourceManager.TUNER_RESOURCE_TYPE_CAS_SESSION, casSystemId); + cas = new CasResource.Builder(casSessionHandle, casSystemId) .maxSessionNum(maxSessionNum) .build(); - ciCam = new CiCamResource.Builder(casSystemId) + int ciCamHandle = generateResourceHandle( + TunerResourceManager.TUNER_RESOURCE_TYPE_FRONTEND_CICAM, casSystemId); + ciCam = new CiCamResource.Builder(ciCamHandle, casSystemId) .maxSessionNum(maxSessionNum) .build(); addCasResource(cas); @@ -1007,86 +952,120 @@ public class TunerResourceManagerService extends SystemService implements IBinde if (DEBUG) { Slog.d(TAG, "requestFrontend(request=" + request + ")"); } - - frontendHandle[0] = TunerResourceManager.INVALID_RESOURCE_HANDLE; - ClientProfile requestClient = getClientProfile(request.clientId); - // TODO: check if this is really needed - if (requestClient == null) { + int[] reclaimOwnerId = new int[1]; + if (!claimFrontend(request, frontendHandle, reclaimOwnerId)) { return false; } - clientPriorityUpdateOnRequest(requestClient); - int grantingFrontendHandle = TunerResourceManager.INVALID_RESOURCE_HANDLE; - int inUseLowestPriorityFrHandle = TunerResourceManager.INVALID_RESOURCE_HANDLE; - // Priority max value is 1000 - int currentLowestPriority = MAX_CLIENT_PRIORITY + 1; - boolean isRequestFromSameProcess = false; - // If the desired frontend id was specified, we only need to check the frontend. - boolean hasDesiredFrontend = request.desiredId != TunerFrontendRequest.DEFAULT_DESIRED_ID; - for (FrontendResource fr : getFrontendResources().values()) { - int frontendId = getResourceIdFromHandle(fr.getHandle()); - if (fr.getType() == request.frontendType - && (!hasDesiredFrontend || frontendId == request.desiredId)) { - if (!fr.isInUse()) { - // Unused resource cannot be acquired if the max is already reached, but - // TRM still has to look for the reclaim candidate - if (isFrontendMaxNumUseReached(request.frontendType)) { - continue; - } - // Grant unused frontend with no exclusive group members first. - if (fr.getExclusiveGroupMemberFeHandles().isEmpty()) { - grantingFrontendHandle = fr.getHandle(); - break; - } else if (grantingFrontendHandle - == TunerResourceManager.INVALID_RESOURCE_HANDLE) { - // Grant the unused frontend with lower id first if all the unused - // frontends have exclusive group members. - grantingFrontendHandle = fr.getHandle(); - } - } else if (grantingFrontendHandle == TunerResourceManager.INVALID_RESOURCE_HANDLE) { - // Record the frontend id with the lowest client priority among all the - // in use frontends when no available frontend has been found. - int priority = getFrontendHighestClientPriority(fr.getOwnerClientId()); - if (currentLowestPriority > priority) { - // we need to check the max used num if the target frontend type is not - // currently in primary use (and simply blocked due to exclusive group) - ClientProfile targetOwnerProfile = getClientProfile(fr.getOwnerClientId()); - int primaryFeId = targetOwnerProfile.getPrimaryFrontend(); - FrontendResource primaryFe = getFrontendResource(primaryFeId); - if (fr.getType() != primaryFe.getType() - && isFrontendMaxNumUseReached(fr.getType())) { + if (frontendHandle[0] == TunerResourceManager.INVALID_RESOURCE_HANDLE) { + return false; + } + if (reclaimOwnerId[0] != INVALID_CLIENT_ID) { + if (!reclaimResource(reclaimOwnerId[0], TunerResourceManager + .TUNER_RESOURCE_TYPE_FRONTEND)) { + return false; + } + synchronized (mLock) { + if (getFrontendResource(frontendHandle[0]).isInUse()) { + Slog.e(TAG, "Reclaimed frontend still in use"); + return false; + } + updateFrontendClientMappingOnNewGrant(frontendHandle[0], request.clientId); + } + } + return true; + } + + protected boolean claimFrontend( + TunerFrontendRequest request, + int[] frontendHandle, + int[] reclaimOwnerId + ) { + frontendHandle[0] = TunerResourceManager.INVALID_RESOURCE_HANDLE; + reclaimOwnerId[0] = INVALID_CLIENT_ID; + synchronized (mLock) { + if (!checkClientExists(request.clientId)) { + Slog.e(TAG, "Request frontend from unregistered client: " + + request.clientId); + return false; + } + // If the request client is holding or sharing a frontend, throw an exception. + if (!getClientProfile(request.clientId).getInUseFrontendHandles().isEmpty()) { + Slog.e(TAG, "Release frontend before requesting another one. Client id: " + + request.clientId); + return false; + } + ClientProfile requestClient = getClientProfile(request.clientId); + clientPriorityUpdateOnRequest(requestClient); + FrontendResource grantingFrontend = null; + FrontendResource inUseLowestPriorityFrontend = null; + // Priority max value is 1000 + int currentLowestPriority = MAX_CLIENT_PRIORITY + 1; + boolean isRequestFromSameProcess = false; + // If the desired frontend id was specified, we only need to check the frontend. + boolean hasDesiredFrontend = request.desiredId != TunerFrontendRequest + .DEFAULT_DESIRED_ID; + for (FrontendResource fr : getFrontendResources().values()) { + int frontendId = getResourceIdFromHandle(fr.getHandle()); + if (fr.getType() == request.frontendType + && (!hasDesiredFrontend || frontendId == request.desiredId)) { + if (!fr.isInUse()) { + // Unused resource cannot be acquired if the max is already reached, but + // TRM still has to look for the reclaim candidate + if (isFrontendMaxNumUseReached(request.frontendType)) { continue; } - // update the target frontend - inUseLowestPriorityFrHandle = fr.getHandle(); - currentLowestPriority = priority; - isRequestFromSameProcess = (requestClient.getProcessId() - == (getClientProfile(fr.getOwnerClientId())).getProcessId()); + // Grant unused frontend with no exclusive group members first. + if (fr.getExclusiveGroupMemberFeHandles().isEmpty()) { + grantingFrontend = fr; + break; + } else if (grantingFrontend == null) { + // Grant the unused frontend with lower id first if all the unused + // frontends have exclusive group members. + grantingFrontend = fr; + } + } else if (grantingFrontend == null) { + // Record the frontend id with the lowest client priority among all the + // in use frontends when no available frontend has been found. + int priority = getFrontendHighestClientPriority(fr.getOwnerClientId()); + if (currentLowestPriority > priority) { + // we need to check the max used num if the target frontend type is not + // currently in primary use (and simply blocked due to exclusive group) + ClientProfile targetOwnerProfile = + getClientProfile(fr.getOwnerClientId()); + int primaryFeId = targetOwnerProfile.getPrimaryFrontend(); + FrontendResource primaryFe = getFrontendResource(primaryFeId); + if (fr.getType() != primaryFe.getType() + && isFrontendMaxNumUseReached(fr.getType())) { + continue; + } + // update the target frontend + inUseLowestPriorityFrontend = fr; + currentLowestPriority = priority; + isRequestFromSameProcess = (requestClient.getProcessId() + == (getClientProfile(fr.getOwnerClientId())).getProcessId()); + } } } } - } - // Grant frontend when there is unused resource. - if (grantingFrontendHandle != TunerResourceManager.INVALID_RESOURCE_HANDLE) { - frontendHandle[0] = grantingFrontendHandle; - updateFrontendClientMappingOnNewGrant(grantingFrontendHandle, request.clientId); - return true; - } + // Grant frontend when there is unused resource. + if (grantingFrontend != null) { + updateFrontendClientMappingOnNewGrant(grantingFrontend.getHandle(), + request.clientId); + frontendHandle[0] = grantingFrontend.getHandle(); + return true; + } - // When all the resources are occupied, grant the lowest priority resource if the - // request client has higher priority. - if (inUseLowestPriorityFrHandle != TunerResourceManager.INVALID_RESOURCE_HANDLE - && ((requestClient.getPriority() > currentLowestPriority) || ( - (requestClient.getPriority() == currentLowestPriority) && isRequestFromSameProcess))) { - if (!reclaimResource( - getFrontendResource(inUseLowestPriorityFrHandle).getOwnerClientId(), - TunerResourceManager.TUNER_RESOURCE_TYPE_FRONTEND)) { - return false; + // When all the resources are occupied, grant the lowest priority resource if the + // request client has higher priority. + if (inUseLowestPriorityFrontend != null + && ((requestClient.getPriority() > currentLowestPriority) + || ((requestClient.getPriority() == currentLowestPriority) + && isRequestFromSameProcess))) { + frontendHandle[0] = inUseLowestPriorityFrontend.getHandle(); + reclaimOwnerId[0] = inUseLowestPriorityFrontend.getOwnerClientId(); + return true; } - frontendHandle[0] = inUseLowestPriorityFrHandle; - updateFrontendClientMappingOnNewGrant( - inUseLowestPriorityFrHandle, request.clientId); - return true; } return false; @@ -1192,165 +1171,257 @@ public class TunerResourceManagerService extends SystemService implements IBinde } @VisibleForTesting - protected boolean requestLnbInternal(TunerLnbRequest request, int[] lnbHandle) { + protected boolean requestLnbInternal(TunerLnbRequest request, int[] lnbHandle) + throws RemoteException { if (DEBUG) { Slog.d(TAG, "requestLnb(request=" + request + ")"); } + int[] reclaimOwnerId = new int[1]; + if (!claimLnb(request, lnbHandle, reclaimOwnerId)) { + return false; + } + if (lnbHandle[0] == TunerResourceManager.INVALID_RESOURCE_HANDLE) { + return false; + } + if (reclaimOwnerId[0] != INVALID_CLIENT_ID) { + if (!reclaimResource(reclaimOwnerId[0], + TunerResourceManager.TUNER_RESOURCE_TYPE_LNB)) { + return false; + } + synchronized (mLock) { + if (getLnbResource(lnbHandle[0]).isInUse()) { + Slog.e(TAG, "Reclaimed lnb still in use"); + return false; + } + updateLnbClientMappingOnNewGrant(lnbHandle[0], request.clientId); + } + } + return true; + } + protected boolean claimLnb(TunerLnbRequest request, int[] lnbHandle, int[] reclaimOwnerId) + throws RemoteException { lnbHandle[0] = TunerResourceManager.INVALID_RESOURCE_HANDLE; - ClientProfile requestClient = getClientProfile(request.clientId); - clientPriorityUpdateOnRequest(requestClient); - int grantingLnbHandle = TunerResourceManager.INVALID_RESOURCE_HANDLE; - int inUseLowestPriorityLnbHandle = TunerResourceManager.INVALID_RESOURCE_HANDLE; - // Priority max value is 1000 - int currentLowestPriority = MAX_CLIENT_PRIORITY + 1; - boolean isRequestFromSameProcess = false; - for (LnbResource lnb : getLnbResources().values()) { - if (!lnb.isInUse()) { - // Grant the unused lnb with lower handle first - grantingLnbHandle = lnb.getHandle(); - break; - } else { - // Record the lnb id with the lowest client priority among all the - // in use lnb when no available lnb has been found. - int priority = updateAndGetOwnerClientPriority(lnb.getOwnerClientId()); - if (currentLowestPriority > priority) { - inUseLowestPriorityLnbHandle = lnb.getHandle(); - currentLowestPriority = priority; - isRequestFromSameProcess = (requestClient.getProcessId() - == (getClientProfile(lnb.getOwnerClientId())).getProcessId()); + reclaimOwnerId[0] = INVALID_CLIENT_ID; + synchronized (mLock) { + if (!checkClientExists(request.clientId)) { + throw new RemoteException("Request lnb from unregistered client:" + + request.clientId); + } + ClientProfile requestClient = getClientProfile(request.clientId); + clientPriorityUpdateOnRequest(requestClient); + LnbResource grantingLnb = null; + LnbResource inUseLowestPriorityLnb = null; + // Priority max value is 1000 + int currentLowestPriority = MAX_CLIENT_PRIORITY + 1; + boolean isRequestFromSameProcess = false; + for (LnbResource lnb : getLnbResources().values()) { + if (!lnb.isInUse()) { + // Grant the unused lnb with lower handle first + grantingLnb = lnb; + break; + } else { + // Record the lnb id with the lowest client priority among all the + // in use lnb when no available lnb has been found. + int priority = updateAndGetOwnerClientPriority(lnb.getOwnerClientId()); + if (currentLowestPriority > priority) { + inUseLowestPriorityLnb = lnb; + currentLowestPriority = priority; + isRequestFromSameProcess = (requestClient.getProcessId() + == (getClientProfile(lnb.getOwnerClientId())).getProcessId()); + } } } - } - // Grant Lnb when there is unused resource. - if (grantingLnbHandle > -1) { - lnbHandle[0] = grantingLnbHandle; - updateLnbClientMappingOnNewGrant(grantingLnbHandle, request.clientId); - return true; - } + // Grant Lnb when there is unused resource. + if (grantingLnb != null) { + updateLnbClientMappingOnNewGrant(grantingLnb.getHandle(), request.clientId); + lnbHandle[0] = grantingLnb.getHandle(); + return true; + } - // When all the resources are occupied, grant the lowest priority resource if the - // request client has higher priority. - if (inUseLowestPriorityLnbHandle > TunerResourceManager.INVALID_RESOURCE_HANDLE - && ((requestClient.getPriority() > currentLowestPriority) || ( - (requestClient.getPriority() == currentLowestPriority) && isRequestFromSameProcess))) { - if (!reclaimResource(getLnbResource(inUseLowestPriorityLnbHandle).getOwnerClientId(), - TunerResourceManager.TUNER_RESOURCE_TYPE_LNB)) { - return false; + // When all the resources are occupied, grant the lowest priority resource if the + // request client has higher priority. + if (inUseLowestPriorityLnb != null + && ((requestClient.getPriority() > currentLowestPriority) || ( + (requestClient.getPriority() == currentLowestPriority) + && isRequestFromSameProcess))) { + lnbHandle[0] = inUseLowestPriorityLnb.getHandle(); + reclaimOwnerId[0] = inUseLowestPriorityLnb.getOwnerClientId(); + return true; } - lnbHandle[0] = inUseLowestPriorityLnbHandle; - updateLnbClientMappingOnNewGrant(inUseLowestPriorityLnbHandle, request.clientId); - return true; } return false; } @VisibleForTesting - protected boolean requestCasSessionInternal(CasSessionRequest request, int[] casSessionHandle) { + protected boolean requestCasSessionInternal(CasSessionRequest request, int[] casSessionHandle) + throws RemoteException { if (DEBUG) { Slog.d(TAG, "requestCasSession(request=" + request + ")"); } - CasResource cas = getCasResource(request.casSystemId); - // Unregistered Cas System is treated as having unlimited sessions. - if (cas == null) { - cas = new CasResource.Builder(request.casSystemId) - .maxSessionNum(Integer.MAX_VALUE) - .build(); - addCasResource(cas); + int[] reclaimOwnerId = new int[1]; + if (!claimCasSession(request, casSessionHandle, reclaimOwnerId)) { + return false; } - casSessionHandle[0] = TunerResourceManager.INVALID_RESOURCE_HANDLE; - ClientProfile requestClient = getClientProfile(request.clientId); - clientPriorityUpdateOnRequest(requestClient); - int lowestPriorityOwnerId = -1; - // Priority max value is 1000 - int currentLowestPriority = MAX_CLIENT_PRIORITY + 1; - boolean isRequestFromSameProcess = false; - if (!cas.isFullyUsed()) { - casSessionHandle[0] = generateResourceHandle( - TunerResourceManager.TUNER_RESOURCE_TYPE_CAS_SESSION, cas.getSystemId()); - updateCasClientMappingOnNewGrant(request.casSystemId, request.clientId); - return true; + if (casSessionHandle[0] == TunerResourceManager.INVALID_RESOURCE_HANDLE) { + return false; } - for (int ownerId : cas.getOwnerClientIds()) { - // Record the client id with lowest priority that is using the current Cas system. - int priority = updateAndGetOwnerClientPriority(ownerId); - if (currentLowestPriority > priority) { - lowestPriorityOwnerId = ownerId; - currentLowestPriority = priority; - isRequestFromSameProcess = (requestClient.getProcessId() - == (getClientProfile(ownerId)).getProcessId()); + if (reclaimOwnerId[0] != INVALID_CLIENT_ID) { + if (!reclaimResource(reclaimOwnerId[0], + TunerResourceManager.TUNER_RESOURCE_TYPE_CAS_SESSION)) { + return false; + } + synchronized (mLock) { + if (getCasResource(request.casSystemId).isFullyUsed()) { + Slog.e(TAG, "Reclaimed cas still fully used"); + return false; + } + updateCasClientMappingOnNewGrant(request.casSystemId, request.clientId); } } + return true; + } - // When all the Cas sessions are occupied, reclaim the lowest priority client if the - // request client has higher priority. - if (lowestPriorityOwnerId > -1 && ((requestClient.getPriority() > currentLowestPriority) - || ((requestClient.getPriority() == currentLowestPriority) && isRequestFromSameProcess))) { - if (!reclaimResource(lowestPriorityOwnerId, - TunerResourceManager.TUNER_RESOURCE_TYPE_CAS_SESSION)) { - return false; + protected boolean claimCasSession(CasSessionRequest request, int[] casSessionHandle, + int[] reclaimOwnerId) throws RemoteException { + casSessionHandle[0] = TunerResourceManager.INVALID_RESOURCE_HANDLE; + reclaimOwnerId[0] = INVALID_CLIENT_ID; + synchronized (mLock) { + if (!checkClientExists(request.clientId)) { + throw new RemoteException("Request cas from unregistered client:" + + request.clientId); + } + CasResource cas = getCasResource(request.casSystemId); + // Unregistered Cas System is treated as having unlimited sessions. + if (cas == null) { + int resourceHandle = generateResourceHandle( + TunerResourceManager.TUNER_RESOURCE_TYPE_CAS_SESSION, request.clientId); + cas = new CasResource.Builder(resourceHandle, request.casSystemId) + .maxSessionNum(Integer.MAX_VALUE) + .build(); + addCasResource(cas); + } + ClientProfile requestClient = getClientProfile(request.clientId); + clientPriorityUpdateOnRequest(requestClient); + int lowestPriorityOwnerId = INVALID_CLIENT_ID; + // Priority max value is 1000 + int currentLowestPriority = MAX_CLIENT_PRIORITY + 1; + boolean isRequestFromSameProcess = false; + if (!cas.isFullyUsed()) { + updateCasClientMappingOnNewGrant(request.casSystemId, request.clientId); + casSessionHandle[0] = cas.getHandle(); + return true; + } + for (int ownerId : cas.getOwnerClientIds()) { + // Record the client id with lowest priority that is using the current Cas system. + int priority = updateAndGetOwnerClientPriority(ownerId); + if (currentLowestPriority > priority) { + lowestPriorityOwnerId = ownerId; + currentLowestPriority = priority; + isRequestFromSameProcess = (requestClient.getProcessId() + == (getClientProfile(ownerId)).getProcessId()); + } + } + + // When all the Cas sessions are occupied, reclaim the lowest priority client if the + // request client has higher priority. + if (lowestPriorityOwnerId != INVALID_CLIENT_ID + && ((requestClient.getPriority() > currentLowestPriority) + || ((requestClient.getPriority() == currentLowestPriority) + && isRequestFromSameProcess))) { + casSessionHandle[0] = cas.getHandle(); + reclaimOwnerId[0] = lowestPriorityOwnerId; + return true; } - casSessionHandle[0] = generateResourceHandle( - TunerResourceManager.TUNER_RESOURCE_TYPE_CAS_SESSION, cas.getSystemId()); - updateCasClientMappingOnNewGrant(request.casSystemId, request.clientId); - return true; } + return false; } @VisibleForTesting - protected boolean requestCiCamInternal(TunerCiCamRequest request, int[] ciCamHandle) { + protected boolean requestCiCamInternal(TunerCiCamRequest request, int[] ciCamHandle) + throws RemoteException { if (DEBUG) { Slog.d(TAG, "requestCiCamInternal(TunerCiCamRequest=" + request + ")"); } - CiCamResource ciCam = getCiCamResource(request.ciCamId); - // Unregistered Cas System is treated as having unlimited sessions. - if (ciCam == null) { - ciCam = new CiCamResource.Builder(request.ciCamId) - .maxSessionNum(Integer.MAX_VALUE) - .build(); - addCiCamResource(ciCam); + int[] reclaimOwnerId = new int[1]; + if (!claimCiCam(request, ciCamHandle, reclaimOwnerId)) { + return false; } - ciCamHandle[0] = TunerResourceManager.INVALID_RESOURCE_HANDLE; - ClientProfile requestClient = getClientProfile(request.clientId); - clientPriorityUpdateOnRequest(requestClient); - int lowestPriorityOwnerId = -1; - // Priority max value is 1000 - int currentLowestPriority = MAX_CLIENT_PRIORITY + 1; - boolean isRequestFromSameProcess = false; - if (!ciCam.isFullyUsed()) { - ciCamHandle[0] = generateResourceHandle( - TunerResourceManager.TUNER_RESOURCE_TYPE_FRONTEND_CICAM, ciCam.getCiCamId()); - updateCiCamClientMappingOnNewGrant(request.ciCamId, request.clientId); - return true; + if (ciCamHandle[0] == TunerResourceManager.INVALID_RESOURCE_HANDLE) { + return false; } - for (int ownerId : ciCam.getOwnerClientIds()) { - // Record the client id with lowest priority that is using the current Cas system. - int priority = updateAndGetOwnerClientPriority(ownerId); - if (currentLowestPriority > priority) { - lowestPriorityOwnerId = ownerId; - currentLowestPriority = priority; - isRequestFromSameProcess = (requestClient.getProcessId() - == (getClientProfile(ownerId)).getProcessId()); - } - } - - // When all the CiCam sessions are occupied, reclaim the lowest priority client if the - // request client has higher priority. - if (lowestPriorityOwnerId > -1 && ((requestClient.getPriority() > currentLowestPriority) - || ((requestClient.getPriority() == currentLowestPriority) - && isRequestFromSameProcess))) { - if (!reclaimResource(lowestPriorityOwnerId, + if (reclaimOwnerId[0] != INVALID_CLIENT_ID) { + if (!reclaimResource(reclaimOwnerId[0], TunerResourceManager.TUNER_RESOURCE_TYPE_FRONTEND_CICAM)) { return false; } - ciCamHandle[0] = generateResourceHandle( - TunerResourceManager.TUNER_RESOURCE_TYPE_FRONTEND_CICAM, ciCam.getCiCamId()); - updateCiCamClientMappingOnNewGrant(request.ciCamId, request.clientId); - return true; + synchronized (mLock) { + if (getCiCamResource(request.ciCamId).isFullyUsed()) { + Slog.e(TAG, "Reclaimed ciCam still fully used"); + return false; + } + updateCiCamClientMappingOnNewGrant(request.ciCamId, request.clientId); + } + } + return true; + } + + protected boolean claimCiCam(TunerCiCamRequest request, int[] ciCamHandle, + int[] reclaimOwnerId) throws RemoteException { + ciCamHandle[0] = TunerResourceManager.INVALID_RESOURCE_HANDLE; + reclaimOwnerId[0] = INVALID_CLIENT_ID; + synchronized (mLock) { + if (!checkClientExists(request.clientId)) { + throw new RemoteException("Request ciCam from unregistered client:" + + request.clientId); + } + CiCamResource ciCam = getCiCamResource(request.ciCamId); + // Unregistered CiCam is treated as having unlimited sessions. + if (ciCam == null) { + int resourceHandle = generateResourceHandle( + TunerResourceManager.TUNER_RESOURCE_TYPE_FRONTEND_CICAM, request.ciCamId); + ciCam = new CiCamResource.Builder(resourceHandle, request.ciCamId) + .maxSessionNum(Integer.MAX_VALUE) + .build(); + addCiCamResource(ciCam); + } + ClientProfile requestClient = getClientProfile(request.clientId); + clientPriorityUpdateOnRequest(requestClient); + int lowestPriorityOwnerId = INVALID_CLIENT_ID; + // Priority max value is 1000 + int currentLowestPriority = MAX_CLIENT_PRIORITY + 1; + boolean isRequestFromSameProcess = false; + if (!ciCam.isFullyUsed()) { + updateCiCamClientMappingOnNewGrant(request.ciCamId, request.clientId); + ciCamHandle[0] = ciCam.getHandle(); + return true; + } + for (int ownerId : ciCam.getOwnerClientIds()) { + // Record the client id with lowest priority that is using the current CiCam. + int priority = updateAndGetOwnerClientPriority(ownerId); + if (currentLowestPriority > priority) { + lowestPriorityOwnerId = ownerId; + currentLowestPriority = priority; + isRequestFromSameProcess = (requestClient.getProcessId() + == (getClientProfile(ownerId)).getProcessId()); + } + } + + // When all the CiCam sessions are occupied, reclaim the lowest priority client if the + // request client has higher priority. + if (lowestPriorityOwnerId != INVALID_CLIENT_ID + && ((requestClient.getPriority() > currentLowestPriority) + || ((requestClient.getPriority() == currentLowestPriority) + && isRequestFromSameProcess))) { + ciCamHandle[0] = ciCam.getHandle(); + reclaimOwnerId[0] = lowestPriorityOwnerId; + return true; + } } + return false; } @@ -1383,20 +1454,49 @@ public class TunerResourceManagerService extends SystemService implements IBinde } @VisibleForTesting - protected void releaseFrontendInternal(FrontendResource fe, int clientId) { + protected void releaseFrontendInternal(int frontendHandle, int clientId) + throws RemoteException { if (DEBUG) { - Slog.d(TAG, "releaseFrontend(id=" + fe.getHandle() + ", clientId=" + clientId + " )"); + Slog.d(TAG, "releaseFrontend(id=" + frontendHandle + ", clientId=" + clientId + " )"); } - if (clientId == fe.getOwnerClientId()) { - ClientProfile ownerClient = getClientProfile(fe.getOwnerClientId()); - if (ownerClient != null) { - for (int shareOwnerId : ownerClient.getShareFeClientIds()) { - reclaimResource(shareOwnerId, - TunerResourceManager.TUNER_RESOURCE_TYPE_FRONTEND); + if (!validateResourceHandle(TunerResourceManager.TUNER_RESOURCE_TYPE_FRONTEND, + frontendHandle)) { + throw new RemoteException("frontendHandle can't be invalid"); + } + Set<Integer> reclaimedResourceOwnerIds = unclaimFrontend(frontendHandle, clientId); + if (reclaimedResourceOwnerIds != null) { + for (int shareOwnerId : reclaimedResourceOwnerIds) { + reclaimResource(shareOwnerId, + TunerResourceManager.TUNER_RESOURCE_TYPE_FRONTEND); + } + } + synchronized (mLock) { + clearFrontendAndClientMapping(getClientProfile(clientId)); + } + } + + private Set<Integer> unclaimFrontend(int frontendHandle, int clientId) throws RemoteException { + Set<Integer> reclaimedResourceOwnerIds = null; + synchronized (mLock) { + if (!checkClientExists(clientId)) { + throw new RemoteException("Release frontend from unregistered client:" + + clientId); + } + FrontendResource fe = getFrontendResource(frontendHandle); + if (fe == null) { + throw new RemoteException("Releasing frontend does not exist."); + } + int ownerClientId = fe.getOwnerClientId(); + ClientProfile ownerProfile = getClientProfile(ownerClientId); + if (ownerClientId == clientId) { + reclaimedResourceOwnerIds = ownerProfile.getShareFeClientIds(); + } else { + if (!ownerProfile.getShareFeClientIds().contains(clientId)) { + throw new RemoteException("Client is not a sharee of the releasing fe."); } } } - clearFrontendAndClientMapping(getClientProfile(clientId)); + return reclaimedResourceOwnerIds; } @VisibleForTesting @@ -1432,103 +1532,129 @@ public class TunerResourceManagerService extends SystemService implements IBinde } @VisibleForTesting - protected boolean requestDemuxInternal(TunerDemuxRequest request, int[] demuxHandle) { + public boolean requestDemuxInternal(@NonNull TunerDemuxRequest request, + @NonNull int[] demuxHandle) throws RemoteException { if (DEBUG) { Slog.d(TAG, "requestDemux(request=" + request + ")"); } - - // For Tuner 2.0 and below or any HW constraint devices that are unable to support - // ITuner.openDemuxById(), demux resources are not really managed under TRM and - // mDemuxResources.size() will be zero - if (mDemuxResources.size() == 0) { - // There are enough Demux resources, so we don't manage Demux in R. - demuxHandle[0] = - generateResourceHandle(TunerResourceManager.TUNER_RESOURCE_TYPE_DEMUX, 0); - return true; + int[] reclaimOwnerId = new int[1]; + if (!claimDemux(request, demuxHandle, reclaimOwnerId)) { + return false; } - - demuxHandle[0] = TunerResourceManager.INVALID_RESOURCE_HANDLE; - ClientProfile requestClient = getClientProfile(request.clientId); - - if (requestClient == null) { + if (demuxHandle[0] == TunerResourceManager.INVALID_RESOURCE_HANDLE) { return false; } + if (reclaimOwnerId[0] != INVALID_CLIENT_ID) { + if (!reclaimResource(reclaimOwnerId[0], + TunerResourceManager.TUNER_RESOURCE_TYPE_DEMUX)) { + return false; + } + synchronized (mLock) { + if (getDemuxResource(demuxHandle[0]).isInUse()) { + Slog.e(TAG, "Reclaimed demux still in use"); + return false; + } + updateDemuxClientMappingOnNewGrant(demuxHandle[0], request.clientId); + } + } + return true; + } - clientPriorityUpdateOnRequest(requestClient); - int grantingDemuxHandle = TunerResourceManager.INVALID_RESOURCE_HANDLE; - int inUseLowestPriorityDrHandle = TunerResourceManager.INVALID_RESOURCE_HANDLE; - // Priority max value is 1000 - int currentLowestPriority = MAX_CLIENT_PRIORITY + 1; - boolean isRequestFromSameProcess = false; - // If the desired demux id was specified, we only need to check the demux. - boolean hasDesiredDemuxCap = request.desiredFilterTypes - != DemuxFilterMainType.UNDEFINED; - int smallestNumOfSupportedCaps = Integer.SIZE + 1; - int smallestNumOfSupportedCapsInUse = Integer.SIZE + 1; - for (DemuxResource dr : getDemuxResources().values()) { - if (!hasDesiredDemuxCap || dr.hasSufficientCaps(request.desiredFilterTypes)) { - if (!dr.isInUse()) { - int numOfSupportedCaps = dr.getNumOfCaps(); - - // look for the demux with minimum caps supporting the desired caps - if (smallestNumOfSupportedCaps > numOfSupportedCaps) { - smallestNumOfSupportedCaps = numOfSupportedCaps; - grantingDemuxHandle = dr.getHandle(); - } - } else if (grantingDemuxHandle == TunerResourceManager.INVALID_RESOURCE_HANDLE) { - // Record the demux id with the lowest client priority among all the - // in use demuxes when no availabledemux has been found. - int priority = updateAndGetOwnerClientPriority(dr.getOwnerClientId()); - if (currentLowestPriority >= priority) { - int numOfSupportedCaps = dr.getNumOfCaps(); - boolean shouldUpdate = false; - // update lowest priority - if (currentLowestPriority > priority) { - currentLowestPriority = priority; - isRequestFromSameProcess = (requestClient.getProcessId() - == (getClientProfile(dr.getOwnerClientId())).getProcessId()); + protected boolean claimDemux(TunerDemuxRequest request, int[] demuxHandle, int[] reclaimOwnerId) + throws RemoteException { + demuxHandle[0] = TunerResourceManager.INVALID_RESOURCE_HANDLE; + reclaimOwnerId[0] = INVALID_CLIENT_ID; + synchronized (mLock) { + if (!checkClientExists(request.clientId)) { + throw new RemoteException("Request demux from unregistered client:" + + request.clientId); + } + + // For Tuner 2.0 and below or any HW constraint devices that are unable to support + // ITuner.openDemuxById(), demux resources are not really managed under TRM and + // mDemuxResources.size() will be zero + if (mDemuxResources.size() == 0) { + // There are enough Demux resources, so we don't manage Demux in R. + demuxHandle[0] = + generateResourceHandle(TunerResourceManager.TUNER_RESOURCE_TYPE_DEMUX, 0); + return true; + } - // reset the smallest caps when lower priority resource is found - smallestNumOfSupportedCapsInUse = numOfSupportedCaps; + ClientProfile requestClient = getClientProfile(request.clientId); + if (requestClient == null) { + return false; + } + clientPriorityUpdateOnRequest(requestClient); + DemuxResource grantingDemux = null; + DemuxResource inUseLowestPriorityDemux = null; + // Priority max value is 1000 + int currentLowestPriority = MAX_CLIENT_PRIORITY + 1; + boolean isRequestFromSameProcess = false; + // If the desired demux id was specified, we only need to check the demux. + boolean hasDesiredDemuxCap = request.desiredFilterTypes + != DemuxFilterMainType.UNDEFINED; + int smallestNumOfSupportedCaps = Integer.SIZE + 1; + int smallestNumOfSupportedCapsInUse = Integer.SIZE + 1; + for (DemuxResource dr : getDemuxResources().values()) { + if (!hasDesiredDemuxCap || dr.hasSufficientCaps(request.desiredFilterTypes)) { + if (!dr.isInUse()) { + int numOfSupportedCaps = dr.getNumOfCaps(); - shouldUpdate = true; - } else { - // This is the case when the priority is the same as previously found - // one. Update smallest caps when priority. - if (smallestNumOfSupportedCapsInUse > numOfSupportedCaps) { + // look for the demux with minimum caps supporting the desired caps + if (smallestNumOfSupportedCaps > numOfSupportedCaps) { + smallestNumOfSupportedCaps = numOfSupportedCaps; + grantingDemux = dr; + } + } else if (grantingDemux == null) { + // Record the demux id with the lowest client priority among all the + // in use demuxes when no availabledemux has been found. + int priority = updateAndGetOwnerClientPriority(dr.getOwnerClientId()); + if (currentLowestPriority >= priority) { + int numOfSupportedCaps = dr.getNumOfCaps(); + boolean shouldUpdate = false; + // update lowest priority + if (currentLowestPriority > priority) { + currentLowestPriority = priority; + isRequestFromSameProcess = (requestClient.getProcessId() + == (getClientProfile(dr.getOwnerClientId())).getProcessId()); + + // reset the smallest caps when lower priority resource is found smallestNumOfSupportedCapsInUse = numOfSupportedCaps; + shouldUpdate = true; + } else { + // This is the case when the priority is the same as previously + // found one. Update smallest caps when priority. + if (smallestNumOfSupportedCapsInUse > numOfSupportedCaps) { + smallestNumOfSupportedCapsInUse = numOfSupportedCaps; + shouldUpdate = true; + } + } + if (shouldUpdate) { + inUseLowestPriorityDemux = dr; } - } - if (shouldUpdate) { - inUseLowestPriorityDrHandle = dr.getHandle(); } } } } - } - // Grant demux when there is unused resource. - if (grantingDemuxHandle != TunerResourceManager.INVALID_RESOURCE_HANDLE) { - demuxHandle[0] = grantingDemuxHandle; - updateDemuxClientMappingOnNewGrant(grantingDemuxHandle, request.clientId); - return true; - } + // Grant demux when there is unused resource. + if (grantingDemux != null) { + updateDemuxClientMappingOnNewGrant(grantingDemux.getHandle(), request.clientId); + demuxHandle[0] = grantingDemux.getHandle(); + return true; + } - // When all the resources are occupied, grant the lowest priority resource if the - // request client has higher priority. - if (inUseLowestPriorityDrHandle != TunerResourceManager.INVALID_RESOURCE_HANDLE - && ((requestClient.getPriority() > currentLowestPriority) || ( - (requestClient.getPriority() == currentLowestPriority) && isRequestFromSameProcess))) { - if (!reclaimResource( - getDemuxResource(inUseLowestPriorityDrHandle).getOwnerClientId(), - TunerResourceManager.TUNER_RESOURCE_TYPE_DEMUX)) { - return false; + // When all the resources are occupied, grant the lowest priority resource if the + // request client has higher priority. + if (inUseLowestPriorityDemux != null + && ((requestClient.getPriority() > currentLowestPriority) || ( + (requestClient.getPriority() == currentLowestPriority) + && isRequestFromSameProcess))) { + demuxHandle[0] = inUseLowestPriorityDemux.getHandle(); + reclaimOwnerId[0] = inUseLowestPriorityDemux.getOwnerClientId(); + return true; } - demuxHandle[0] = inUseLowestPriorityDrHandle; - updateDemuxClientMappingOnNewGrant( - inUseLowestPriorityDrHandle, request.clientId); - return true; } return false; @@ -1792,7 +1918,9 @@ public class TunerResourceManagerService extends SystemService implements IBinde return; } - mListeners.put(clientId, record); + synchronized (mLock) { + mListeners.put(clientId, record); + } } @VisibleForTesting @@ -1808,33 +1936,44 @@ public class TunerResourceManagerService extends SystemService implements IBinde // Reclaim all the resources of the share owners of the frontend that is used by the current // resource reclaimed client. - ClientProfile profile = getClientProfile(reclaimingClientId); - // TODO: check if this check is really needed. - if (profile == null) { - return true; + Set<Integer> shareFeClientIds; + synchronized (mLock) { + ClientProfile profile = getClientProfile(reclaimingClientId); + if (profile == null) { + return true; + } + shareFeClientIds = profile.getShareFeClientIds(); } - Set<Integer> shareFeClientIds = profile.getShareFeClientIds(); + ResourcesReclaimListenerRecord listenerRecord = null; for (int clientId : shareFeClientIds) { - try { - mListeners.get(clientId).getListener().onReclaimResources(); - } catch (RemoteException e) { - Slog.e(TAG, "Failed to reclaim resources on client " + clientId, e); - return false; + synchronized (mLock) { + listenerRecord = mListeners.get(clientId); + } + if (listenerRecord != null) { + try { + listenerRecord.getListener().onReclaimResources(); + } catch (RemoteException e) { + Slog.e(TAG, "Failed to reclaim resources on client " + clientId, e); + } } - clearAllResourcesAndClientMapping(getClientProfile(clientId)); } if (DEBUG) { Slog.d(TAG, "Reclaiming resources because higher priority client request resource type " + resourceType + ", clientId:" + reclaimingClientId); } - try { - mListeners.get(reclaimingClientId).getListener().onReclaimResources(); - } catch (RemoteException e) { - Slog.e(TAG, "Failed to reclaim resources on client " + reclaimingClientId, e); - return false; + + synchronized (mLock) { + listenerRecord = mListeners.get(reclaimingClientId); + } + if (listenerRecord != null) { + try { + listenerRecord.getListener().onReclaimResources(); + } catch (RemoteException e) { + Slog.e(TAG, "Failed to reclaim resources on client " + reclaimingClientId, e); + } } - clearAllResourcesAndClientMapping(profile); + return true; } @@ -2258,6 +2397,7 @@ public class TunerResourceManagerService extends SystemService implements IBinde addResourcesReclaimListener(clientId, listener); } + @SuppressWarnings("GuardedBy") // Lock is held on mListeners private void removeClientProfile(int clientId) { for (int shareOwnerId : getClientProfile(clientId).getShareFeClientIds()) { clearFrontendAndClientMapping(getClientProfile(shareOwnerId)); @@ -2265,12 +2405,9 @@ public class TunerResourceManagerService extends SystemService implements IBinde clearAllResourcesAndClientMapping(getClientProfile(clientId)); mClientProfiles.remove(clientId); - // it may be called by unregisterClientProfileInternal under test - synchronized (mLock) { - ResourcesReclaimListenerRecord record = mListeners.remove(clientId); - if (record != null) { - record.getListener().asBinder().unlinkToDeath(record, 0); - } + ResourcesReclaimListenerRecord record = mListeners.remove(clientId); + if (record != null) { + record.getListener().asBinder().unlinkToDeath(record, 0); } } @@ -2304,7 +2441,8 @@ public class TunerResourceManagerService extends SystemService implements IBinde profile.releaseFrontend(); } - private void clearAllResourcesAndClientMapping(ClientProfile profile) { + @VisibleForTesting + protected void clearAllResourcesAndClientMapping(ClientProfile profile) { // TODO: check if this check is really needed. Maybe needed for reclaimResource path. if (profile == null) { return; diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java index 235a2115a964..ebdf52cc9037 100644 --- a/services/core/java/com/android/server/wm/ActivityRecord.java +++ b/services/core/java/com/android/server/wm/ActivityRecord.java @@ -813,6 +813,8 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A /** The last set {@link DropInputMode} for this activity surface. */ @DropInputMode private int mLastDropInputMode = DropInputMode.NONE; + /** Whether the input to this activity will be dropped during the current playing animation. */ + private boolean mIsInputDroppedForAnimation; /** * Whether the application has desk mode resources. Calculated and cached when @@ -1647,6 +1649,15 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A } } + /** Sets if all input will be dropped as a protection during the client-driven animation. */ + void setDropInputForAnimation(boolean isInputDroppedForAnimation) { + if (mIsInputDroppedForAnimation == isInputDroppedForAnimation) { + return; + } + mIsInputDroppedForAnimation = isInputDroppedForAnimation; + updateUntrustedEmbeddingInputProtection(); + } + /** * Sets to drop input when obscured to activity if it is embedded in untrusted mode. * @@ -1659,7 +1670,10 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A if (getSurfaceControl() == null) { return; } - if (isEmbeddedInUntrustedMode()) { + if (mIsInputDroppedForAnimation) { + // Disable all input during the animation. + setDropInputMode(DropInputMode.ALL); + } else if (isEmbeddedInUntrustedMode()) { // Set drop input to OBSCURED when untrusted embedded. setDropInputMode(DropInputMode.OBSCURED); } else { diff --git a/services/core/java/com/android/server/wm/RemoteAnimationController.java b/services/core/java/com/android/server/wm/RemoteAnimationController.java index f8665c70c61d..432089ff2fcf 100644 --- a/services/core/java/com/android/server/wm/RemoteAnimationController.java +++ b/services/core/java/com/android/server/wm/RemoteAnimationController.java @@ -53,6 +53,7 @@ import com.android.server.wm.SurfaceAnimator.OnAnimationFinishedCallback; import java.io.PrintWriter; import java.io.StringWriter; import java.util.ArrayList; +import java.util.function.Consumer; /** * Helper class to run app animations in a remote process. @@ -348,6 +349,10 @@ class RemoteAnimationController implements DeathRecipient { } finally { mIsFinishing = false; } + // Reset input for all activities when the remote animation is finished. + final Consumer<ActivityRecord> updateActivities = + activity -> activity.setDropInputForAnimation(false); + mDisplayContent.forAllActivities(updateActivities); } setRunningRemoteAnimation(false); ProtoLog.i(WM_DEBUG_REMOTE_ANIMATIONS, "Finishing remote animation"); diff --git a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java index c8cbbb5957ec..2e6c93cb92aa 100644 --- a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java @@ -102,6 +102,7 @@ import android.view.WindowManager; import android.view.accessibility.AccessibilityManager; import android.view.accessibility.AccessibilityWindowAttributes; import android.view.accessibility.IAccessibilityManager; +import android.view.accessibility.IUserInitializationCompleteCallback; import androidx.test.core.app.ApplicationProvider; import androidx.test.filters.SmallTest; @@ -137,6 +138,7 @@ import org.mockito.ArgumentMatchers; import org.mockito.Captor; import org.mockito.Mock; import org.mockito.MockitoAnnotations; +import org.mockito.Spy; import org.mockito.internal.util.reflection.FieldReader; import org.mockito.internal.util.reflection.FieldSetter; import org.mockito.stubbing.Answer; @@ -209,6 +211,7 @@ public class AccessibilityManagerServiceTest { @Mock private FullScreenMagnificationController mMockFullScreenMagnificationController; @Mock private ProxyManager mProxyManager; @Mock private StatusBarManagerInternal mStatusBarManagerInternal; + @Spy private IUserInitializationCompleteCallback mUserInitializationCompleteCallback; @Captor private ArgumentCaptor<Intent> mIntentArgumentCaptor; private IAccessibilityManager mA11yManagerServiceOnDevice; private AccessibilityServiceConnection mAccessibilityServiceConnection; @@ -2042,6 +2045,36 @@ public class AccessibilityManagerServiceTest { .isEqualTo(ACCESSIBILITY_BUTTON_MODE_NAVIGATION_BAR); } + @Test + public void registerUserInitializationCompleteCallback_isRegistered() { + mA11yms.mUserInitializationCompleteCallbacks.clear(); + + mA11yms.registerUserInitializationCompleteCallback(mUserInitializationCompleteCallback); + + assertThat(mA11yms.mUserInitializationCompleteCallbacks).containsExactly( + mUserInitializationCompleteCallback); + } + + @Test + public void unregisterUserInitializationCompleteCallback_isUnregistered() { + mA11yms.mUserInitializationCompleteCallbacks.clear(); + mA11yms.mUserInitializationCompleteCallbacks.add(mUserInitializationCompleteCallback); + + mA11yms.unregisterUserInitializationCompleteCallback(mUserInitializationCompleteCallback); + + assertThat(mA11yms.mUserInitializationCompleteCallbacks).isEmpty(); + } + + @Test + public void switchUser_callsUserInitializationCompleteCallback() throws RemoteException { + mA11yms.mUserInitializationCompleteCallbacks.add(mUserInitializationCompleteCallback); + + mA11yms.switchUser(UserHandle.MIN_SECONDARY_USER_ID); + + verify(mUserInitializationCompleteCallback).onUserInitializationComplete( + UserHandle.MIN_SECONDARY_USER_ID); + } + private Set<String> readStringsFromSetting(String setting) { final Set<String> result = new ArraySet<>(); mA11yms.readColonDelimitedSettingToSet( diff --git a/services/tests/servicestests/src/com/android/server/tv/tunerresourcemanager/TunerResourceManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/tv/tunerresourcemanager/TunerResourceManagerServiceTest.java index 963b27e010fa..bf58443194e5 100644 --- a/services/tests/servicestests/src/com/android/server/tv/tunerresourcemanager/TunerResourceManagerServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/tv/tunerresourcemanager/TunerResourceManagerServiceTest.java @@ -38,6 +38,7 @@ import android.media.tv.tunerresourcemanager.TunerFrontendInfo; import android.media.tv.tunerresourcemanager.TunerFrontendRequest; import android.media.tv.tunerresourcemanager.TunerLnbRequest; import android.media.tv.tunerresourcemanager.TunerResourceManager; +import android.os.RemoteException; import android.platform.test.annotations.Presubmit; import androidx.test.InstrumentationRegistry; @@ -69,6 +70,61 @@ public class TunerResourceManagerServiceTest { private TunerResourceManagerService mTunerResourceManagerService; private boolean mIsForeground; + private final class TunerClient extends IResourcesReclaimListener.Stub { + int[] mClientId; + ClientProfile mProfile; + boolean mReclaimed; + + TunerClient() { + mClientId = new int[1]; + mClientId[0] = TunerResourceManagerService.INVALID_CLIENT_ID; + } + + public void register(String sessionId, int useCase) { + ResourceClientProfile profile = new ResourceClientProfile(); + profile.tvInputSessionId = sessionId; + profile.useCase = useCase; + mTunerResourceManagerService.registerClientProfileInternal( + profile, this, mClientId); + assertThat(mClientId[0]).isNotEqualTo(TunerResourceManagerService.INVALID_CLIENT_ID); + mProfile = mTunerResourceManagerService.getClientProfile(mClientId[0]); + } + + public void register(String sessionId, int useCase, int priority, int niceValue) { + register(sessionId, useCase); + mTunerResourceManagerService.updateClientPriorityInternal( + mClientId[0], priority, niceValue); + } + + public void register(String sessionId, int useCase, int priority) { + register(sessionId, useCase, priority, 0); + } + + public void unregister() { + mTunerResourceManagerService.unregisterClientProfileInternal(mClientId[0]); + mClientId[0] = TunerResourceManagerService.INVALID_CLIENT_ID; + mReclaimed = false; + } + + public int getId() { + return mClientId[0]; + } + + public ClientProfile getProfile() { + return mProfile; + } + + @Override + public void onReclaimResources() { + mTunerResourceManagerService.clearAllResourcesAndClientMapping(mProfile); + mReclaimed = true; + } + + public boolean isReclaimed() { + return mReclaimed; + } + } + private static final class TestResourcesReclaimListener extends IResourcesReclaimListener.Stub { boolean mReclaimed; @@ -247,13 +303,11 @@ public class TunerResourceManagerServiceTest { } @Test - public void requestFrontendTest_NoFrontendWithGiveTypeAvailable() { - ResourceClientProfile profile = resourceClientProfile("0" /*sessionId*/, - TvInputService.PRIORITY_HINT_USE_CASE_TYPE_PLAYBACK); - int[] clientId = new int[1]; - mTunerResourceManagerService.registerClientProfileInternal( - profile, null /*listener*/, clientId); - assertThat(clientId[0]).isNotEqualTo(TunerResourceManagerService.INVALID_CLIENT_ID); + public void requestFrontendTest_NoFrontendWithGiveTypeAvailable() throws RemoteException { + // Register clients + TunerClient client0 = new TunerClient(); + client0.register("0" /*sessionId*/, + TvInputService.PRIORITY_HINT_USE_CASE_TYPE_PLAYBACK); // Init frontend resources. TunerFrontendInfo[] infos = new TunerFrontendInfo[1]; @@ -262,21 +316,20 @@ public class TunerResourceManagerServiceTest { mTunerResourceManagerService.setFrontendInfoListInternal(infos); TunerFrontendRequest request = - tunerFrontendRequest(clientId[0] /*clientId*/, FrontendSettings.TYPE_DVBT); + tunerFrontendRequest(client0.getId() /*clientId*/, FrontendSettings.TYPE_DVBT); int[] frontendHandle = new int[1]; assertThat(mTunerResourceManagerService .requestFrontendInternal(request, frontendHandle)).isFalse(); assertThat(frontendHandle[0]).isEqualTo(TunerResourceManager.INVALID_RESOURCE_HANDLE); + client0.unregister(); } @Test - public void requestFrontendTest_FrontendWithNoExclusiveGroupAvailable() { - ResourceClientProfile profile = resourceClientProfile("0" /*sessionId*/, - TvInputService.PRIORITY_HINT_USE_CASE_TYPE_PLAYBACK); - int[] clientId = new int[1]; - mTunerResourceManagerService.registerClientProfileInternal( - profile, null /*listener*/, clientId); - assertThat(clientId[0]).isNotEqualTo(TunerResourceManagerService.INVALID_CLIENT_ID); + public void requestFrontendTest_FrontendWithNoExclusiveGroupAvailable() throws RemoteException { + // Register clients + TunerClient client0 = new TunerClient(); + client0.register("0" /*sessionId*/, + TvInputService.PRIORITY_HINT_USE_CASE_TYPE_PLAYBACK); // Init frontend resources. TunerFrontendInfo[] infos = new TunerFrontendInfo[3]; @@ -295,27 +348,23 @@ public class TunerResourceManagerServiceTest { mTunerResourceManagerService.setFrontendInfoListInternal(infos); TunerFrontendRequest request = - tunerFrontendRequest(clientId[0] /*clientId*/, FrontendSettings.TYPE_DVBT); + tunerFrontendRequest(client0.getId() /*clientId*/, FrontendSettings.TYPE_DVBT); int[] frontendHandle = new int[1]; assertThat(mTunerResourceManagerService .requestFrontendInternal(request, frontendHandle)).isTrue(); assertThat(frontendHandle[0]).isEqualTo(0); + client0.unregister(); } @Test - public void requestFrontendTest_FrontendWithExclusiveGroupAvailable() { - ResourceClientProfile profile0 = resourceClientProfile("0" /*sessionId*/, - TvInputService.PRIORITY_HINT_USE_CASE_TYPE_PLAYBACK); - ResourceClientProfile profile1 = resourceClientProfile("1" /*sessionId*/, - TvInputService.PRIORITY_HINT_USE_CASE_TYPE_PLAYBACK); - int[] clientId0 = new int[1]; - int[] clientId1 = new int[1]; - mTunerResourceManagerService.registerClientProfileInternal( - profile0, null /*listener*/, clientId0); - mTunerResourceManagerService.registerClientProfileInternal( - profile1, null /*listener*/, clientId1); - assertThat(clientId0[0]).isNotEqualTo(TunerResourceManagerService.INVALID_CLIENT_ID); - assertThat(clientId1[0]).isNotEqualTo(TunerResourceManagerService.INVALID_CLIENT_ID); + public void requestFrontendTest_FrontendWithExclusiveGroupAvailable() throws RemoteException { + // Register clients + TunerClient client0 = new TunerClient(); + TunerClient client1 = new TunerClient(); + client0.register("0" /*sessionId*/, + TvInputService.PRIORITY_HINT_USE_CASE_TYPE_PLAYBACK); + client1.register("1" /*sessionId*/, + TvInputService.PRIORITY_HINT_USE_CASE_TYPE_PLAYBACK); // Init frontend resources. TunerFrontendInfo[] infos = new TunerFrontendInfo[3]; @@ -335,13 +384,13 @@ public class TunerResourceManagerServiceTest { int[] frontendHandle = new int[1]; TunerFrontendRequest request = - tunerFrontendRequest(clientId1[0] /*clientId*/, FrontendSettings.TYPE_DVBT); + tunerFrontendRequest(client1.getId() /*clientId*/, FrontendSettings.TYPE_DVBT); assertThat(mTunerResourceManagerService .requestFrontendInternal(request, frontendHandle)).isTrue(); assertThat(frontendHandle[0]).isEqualTo(infos[0].handle); request = - tunerFrontendRequest(clientId0[0] /*clientId*/, FrontendSettings.TYPE_DVBT); + tunerFrontendRequest(client0.getId() /*clientId*/, FrontendSettings.TYPE_DVBT); assertThat(mTunerResourceManagerService .requestFrontendInternal(request, frontendHandle)).isTrue(); assertThat(frontendHandle[0]).isEqualTo(infos[1].handle); @@ -349,31 +398,20 @@ public class TunerResourceManagerServiceTest { .isTrue(); assertThat(mTunerResourceManagerService.getFrontendResource(infos[2].handle).isInUse()) .isTrue(); + client0.unregister(); + client1.unregister(); } @Test - public void requestFrontendTest_NoFrontendAvailable_RequestWithLowerPriority() { + public void requestFrontendTest_NoFrontendAvailable_RequestWithLowerPriority() + throws RemoteException { // Register clients - ResourceClientProfile[] profiles = new ResourceClientProfile[2]; - profiles[0] = resourceClientProfile("0" /*sessionId*/, - TvInputService.PRIORITY_HINT_USE_CASE_TYPE_PLAYBACK); - profiles[1] = resourceClientProfile("1" /*sessionId*/, - TvInputService.PRIORITY_HINT_USE_CASE_TYPE_PLAYBACK); - int[] clientPriorities = {100, 50}; - int[] clientId0 = new int[1]; - int[] clientId1 = new int[1]; - TestResourcesReclaimListener listener = new TestResourcesReclaimListener(); - - mTunerResourceManagerService.registerClientProfileInternal( - profiles[0], listener, clientId0); - assertThat(clientId0[0]).isNotEqualTo(TunerResourceManagerService.INVALID_CLIENT_ID); - mTunerResourceManagerService.updateClientPriorityInternal( - clientId0[0], clientPriorities[0], 0/*niceValue*/); - mTunerResourceManagerService.registerClientProfileInternal( - profiles[1], new TestResourcesReclaimListener(), clientId1); - assertThat(clientId1[0]).isNotEqualTo(TunerResourceManagerService.INVALID_CLIENT_ID); - mTunerResourceManagerService.updateClientPriorityInternal( - clientId1[0], clientPriorities[1], 0/*niceValue*/); + TunerClient client0 = new TunerClient(); + TunerClient client1 = new TunerClient(); + client0.register("0" /*sessionId*/, + TvInputService.PRIORITY_HINT_USE_CASE_TYPE_PLAYBACK, 100); + client1.register("1" /*sessionId*/, + TvInputService.PRIORITY_HINT_USE_CASE_TYPE_PLAYBACK, 50); // Init frontend resources. TunerFrontendInfo[] infos = new TunerFrontendInfo[2]; @@ -384,46 +422,36 @@ public class TunerResourceManagerServiceTest { mTunerResourceManagerService.setFrontendInfoListInternal(infos); TunerFrontendRequest request = - tunerFrontendRequest(clientId0[0] /*clientId*/, FrontendSettings.TYPE_DVBT); + tunerFrontendRequest(client0.getId() /*clientId*/, FrontendSettings.TYPE_DVBT); int[] frontendHandle = new int[1]; assertThat(mTunerResourceManagerService .requestFrontendInternal(request, frontendHandle)).isTrue(); request = - tunerFrontendRequest(clientId1[0] /*clientId*/, FrontendSettings.TYPE_DVBT); + tunerFrontendRequest(client1.getId() /*clientId*/, FrontendSettings.TYPE_DVBT); assertThat(mTunerResourceManagerService .requestFrontendInternal(request, frontendHandle)).isFalse(); - assertThat(listener.isReclaimed()).isFalse(); + assertThat(client0.isReclaimed()).isFalse(); request = - tunerFrontendRequest(clientId1[0] /*clientId*/, FrontendSettings.TYPE_DVBS); + tunerFrontendRequest(client1.getId() /*clientId*/, FrontendSettings.TYPE_DVBS); assertThat(mTunerResourceManagerService .requestFrontendInternal(request, frontendHandle)).isFalse(); - assertThat(listener.isReclaimed()).isFalse(); + assertThat(client0.isReclaimed()).isFalse(); + client0.unregister(); + client1.unregister(); } @Test - public void requestFrontendTest_NoFrontendAvailable_RequestWithHigherPriority() { + public void requestFrontendTest_NoFrontendAvailable_RequestWithHigherPriority() + throws RemoteException { // Register clients - ResourceClientProfile[] profiles = new ResourceClientProfile[2]; - profiles[0] = resourceClientProfile("0" /*sessionId*/, - TvInputService.PRIORITY_HINT_USE_CASE_TYPE_PLAYBACK); - profiles[1] = resourceClientProfile("1" /*sessionId*/, - TvInputService.PRIORITY_HINT_USE_CASE_TYPE_PLAYBACK); - int[] clientPriorities = {100, 500}; - int[] clientId0 = new int[1]; - int[] clientId1 = new int[1]; - TestResourcesReclaimListener listener = new TestResourcesReclaimListener(); - mTunerResourceManagerService.registerClientProfileInternal( - profiles[0], listener, clientId0); - assertThat(clientId0[0]).isNotEqualTo(TunerResourceManagerService.INVALID_CLIENT_ID); - mTunerResourceManagerService.updateClientPriorityInternal( - clientId0[0], clientPriorities[0], 0/*niceValue*/); - mTunerResourceManagerService.registerClientProfileInternal( - profiles[1], new TestResourcesReclaimListener(), clientId1); - assertThat(clientId1[0]).isNotEqualTo(TunerResourceManagerService.INVALID_CLIENT_ID); - mTunerResourceManagerService.updateClientPriorityInternal( - clientId1[0], clientPriorities[1], 0/*niceValue*/); + TunerClient client0 = new TunerClient(); + TunerClient client1 = new TunerClient(); + client0.register("0" /*sessionId*/, + TvInputService.PRIORITY_HINT_USE_CASE_TYPE_PLAYBACK, 100); + client1.register("1" /*sessionId*/, + TvInputService.PRIORITY_HINT_USE_CASE_TYPE_PLAYBACK, 500); // Init frontend resources. TunerFrontendInfo[] infos = new TunerFrontendInfo[2]; @@ -434,17 +462,16 @@ public class TunerResourceManagerServiceTest { mTunerResourceManagerService.setFrontendInfoListInternal(infos); TunerFrontendRequest request = - tunerFrontendRequest(clientId0[0] /*clientId*/, FrontendSettings.TYPE_DVBT); + tunerFrontendRequest(client0.getId() /*clientId*/, FrontendSettings.TYPE_DVBT); int[] frontendHandle = new int[1]; assertThat(mTunerResourceManagerService .requestFrontendInternal(request, frontendHandle)).isTrue(); assertThat(frontendHandle[0]).isEqualTo(infos[0].handle); - assertThat(mTunerResourceManagerService.getClientProfile(clientId0[0]) - .getInUseFrontendHandles()).isEqualTo(new HashSet<Integer>(Arrays.asList( - infos[0].handle, infos[1].handle))); + assertThat(client0.getProfile().getInUseFrontendHandles()) + .isEqualTo(new HashSet<Integer>(Arrays.asList(infos[0].handle, infos[1].handle))); request = - tunerFrontendRequest(clientId1[0] /*clientId*/, FrontendSettings.TYPE_DVBS); + tunerFrontendRequest(client1.getId() /*clientId*/, FrontendSettings.TYPE_DVBS); assertThat(mTunerResourceManagerService .requestFrontendInternal(request, frontendHandle)).isTrue(); assertThat(frontendHandle[0]).isEqualTo(infos[1].handle); @@ -453,22 +480,20 @@ public class TunerResourceManagerServiceTest { assertThat(mTunerResourceManagerService.getFrontendResource(infos[1].handle) .isInUse()).isTrue(); assertThat(mTunerResourceManagerService.getFrontendResource(infos[0].handle) - .getOwnerClientId()).isEqualTo(clientId1[0]); + .getOwnerClientId()).isEqualTo(client1.getId()); assertThat(mTunerResourceManagerService.getFrontendResource(infos[1].handle) - .getOwnerClientId()).isEqualTo(clientId1[0]); - assertThat(listener.isReclaimed()).isTrue(); + .getOwnerClientId()).isEqualTo(client1.getId()); + assertThat(client0.isReclaimed()).isTrue(); + client0.unregister(); + client1.unregister(); } @Test - public void releaseFrontendTest_UnderTheSameExclusiveGroup() { + public void releaseFrontendTest_UnderTheSameExclusiveGroup() throws RemoteException { // Register clients - ResourceClientProfile[] profiles = new ResourceClientProfile[1]; - profiles[0] = resourceClientProfile("0" /*sessionId*/, - TvInputService.PRIORITY_HINT_USE_CASE_TYPE_PLAYBACK); - int[] clientId = new int[1]; - TestResourcesReclaimListener listener = new TestResourcesReclaimListener(); - mTunerResourceManagerService.registerClientProfileInternal(profiles[0], listener, clientId); - assertThat(clientId[0]).isNotEqualTo(TunerResourceManagerService.INVALID_CLIENT_ID); + TunerClient client0 = new TunerClient(); + client0.register("0" /*sessionId*/, + TvInputService.PRIORITY_HINT_USE_CASE_TYPE_PLAYBACK); // Init frontend resources. TunerFrontendInfo[] infos = new TunerFrontendInfo[2]; @@ -479,7 +504,7 @@ public class TunerResourceManagerServiceTest { mTunerResourceManagerService.setFrontendInfoListInternal(infos); TunerFrontendRequest request = - tunerFrontendRequest(clientId[0] /*clientId*/, FrontendSettings.TYPE_DVBT); + tunerFrontendRequest(client0.getId() /*clientId*/, FrontendSettings.TYPE_DVBT); int[] frontendHandle = new int[1]; assertThat(mTunerResourceManagerService .requestFrontendInternal(request, frontendHandle)).isTrue(); @@ -488,43 +513,29 @@ public class TunerResourceManagerServiceTest { .getFrontendResource(infos[1].handle).isInUse()).isTrue(); // Release frontend - mTunerResourceManagerService.releaseFrontendInternal(mTunerResourceManagerService - .getFrontendResource(frontendHandle[0]), clientId[0]); + mTunerResourceManagerService.releaseFrontendInternal(frontendHandle[0], client0.getId()); assertThat(mTunerResourceManagerService .getFrontendResource(frontendHandle[0]).isInUse()).isFalse(); assertThat(mTunerResourceManagerService .getFrontendResource(infos[1].handle).isInUse()).isFalse(); - assertThat(mTunerResourceManagerService - .getClientProfile(clientId[0]).getInUseFrontendHandles().size()).isEqualTo(0); + assertThat(client0.getProfile().getInUseFrontendHandles().size()).isEqualTo(0); + client0.unregister(); } @Test - public void requestCasTest_NoCasAvailable_RequestWithHigherPriority() { + public void requestCasTest_NoCasAvailable_RequestWithHigherPriority() throws RemoteException { // Register clients - ResourceClientProfile[] profiles = new ResourceClientProfile[2]; - profiles[0] = resourceClientProfile("0" /*sessionId*/, - TvInputService.PRIORITY_HINT_USE_CASE_TYPE_PLAYBACK); - profiles[1] = resourceClientProfile("1" /*sessionId*/, - TvInputService.PRIORITY_HINT_USE_CASE_TYPE_PLAYBACK); - int[] clientPriorities = {100, 500}; - int[] clientId0 = new int[1]; - int[] clientId1 = new int[1]; - TestResourcesReclaimListener listener = new TestResourcesReclaimListener(); - mTunerResourceManagerService.registerClientProfileInternal( - profiles[0], listener, clientId0); - assertThat(clientId0[0]).isNotEqualTo(TunerResourceManagerService.INVALID_CLIENT_ID); - mTunerResourceManagerService.updateClientPriorityInternal( - clientId0[0], clientPriorities[0], 0/*niceValue*/); - mTunerResourceManagerService.registerClientProfileInternal( - profiles[1], new TestResourcesReclaimListener(), clientId1); - assertThat(clientId1[0]).isNotEqualTo(TunerResourceManagerService.INVALID_CLIENT_ID); - mTunerResourceManagerService.updateClientPriorityInternal( - clientId1[0], clientPriorities[1], 0/*niceValue*/); + TunerClient client0 = new TunerClient(); + TunerClient client1 = new TunerClient(); + client0.register("0" /*sessionId*/, + TvInputService.PRIORITY_HINT_USE_CASE_TYPE_PLAYBACK, 100); + client1.register("1" /*sessionId*/, + TvInputService.PRIORITY_HINT_USE_CASE_TYPE_PLAYBACK, 500); // Init cas resources. mTunerResourceManagerService.updateCasInfoInternal(1 /*casSystemId*/, 2 /*maxSessionNum*/); - CasSessionRequest request = casSessionRequest(clientId0[0], 1 /*casSystemId*/); + CasSessionRequest request = casSessionRequest(client0.getId(), 1 /*casSystemId*/); int[] casSessionHandle = new int[1]; // Request for 2 cas sessions. assertThat(mTunerResourceManagerService @@ -533,54 +544,45 @@ public class TunerResourceManagerServiceTest { .requestCasSessionInternal(request, casSessionHandle)).isTrue(); assertThat(mTunerResourceManagerService.getResourceIdFromHandle(casSessionHandle[0])) .isEqualTo(1); - assertThat(mTunerResourceManagerService.getClientProfile(clientId0[0]) - .getInUseCasSystemId()).isEqualTo(1); + assertThat(client0.getProfile().getInUseCasSystemId()) + .isEqualTo(1); assertThat(mTunerResourceManagerService.getCasResource(1) - .getOwnerClientIds()).isEqualTo(new HashSet<Integer>(Arrays.asList(clientId0[0]))); + .getOwnerClientIds()).isEqualTo( + new HashSet<Integer>(Arrays.asList(client0.getId()))); assertThat(mTunerResourceManagerService.getCasResource(1).isFullyUsed()).isTrue(); - request = casSessionRequest(clientId1[0], 1); + request = casSessionRequest(client1.getId(), 1); assertThat(mTunerResourceManagerService .requestCasSessionInternal(request, casSessionHandle)).isTrue(); assertThat(mTunerResourceManagerService.getResourceIdFromHandle(casSessionHandle[0])) .isEqualTo(1); - assertThat(mTunerResourceManagerService.getClientProfile(clientId1[0]) - .getInUseCasSystemId()).isEqualTo(1); - assertThat(mTunerResourceManagerService.getClientProfile(clientId0[0]) - .getInUseCasSystemId()).isEqualTo(ClientProfile.INVALID_RESOURCE_ID); + assertThat(client1.getProfile().getInUseCasSystemId()).isEqualTo(1); + assertThat(client0.getProfile().getInUseCasSystemId()) + .isEqualTo(ClientProfile.INVALID_RESOURCE_ID); assertThat(mTunerResourceManagerService.getCasResource(1) - .getOwnerClientIds()).isEqualTo(new HashSet<Integer>(Arrays.asList(clientId1[0]))); + .getOwnerClientIds()).isEqualTo( + new HashSet<Integer>(Arrays.asList(client1.getId()))); assertThat(mTunerResourceManagerService.getCasResource(1).isFullyUsed()).isFalse(); - assertThat(listener.isReclaimed()).isTrue(); + assertThat(client0.isReclaimed()).isTrue(); + client0.unregister(); + client1.unregister(); } @Test - public void requestCiCamTest_NoCiCamAvailable_RequestWithHigherPriority() { + public void requestCiCamTest_NoCiCamAvailable_RequestWithHigherPriority() + throws RemoteException { // Register clients - ResourceClientProfile[] profiles = new ResourceClientProfile[2]; - profiles[0] = resourceClientProfile("0" /*sessionId*/, - TvInputService.PRIORITY_HINT_USE_CASE_TYPE_PLAYBACK); - profiles[1] = resourceClientProfile("1" /*sessionId*/, - TvInputService.PRIORITY_HINT_USE_CASE_TYPE_PLAYBACK); - int[] clientPriorities = {100, 500}; - int[] clientId0 = new int[1]; - int[] clientId1 = new int[1]; - TestResourcesReclaimListener listener = new TestResourcesReclaimListener(); - mTunerResourceManagerService.registerClientProfileInternal( - profiles[0], listener, clientId0); - assertThat(clientId0[0]).isNotEqualTo(TunerResourceManagerService.INVALID_CLIENT_ID); - mTunerResourceManagerService.updateClientPriorityInternal( - clientId0[0], clientPriorities[0], 0/*niceValue*/); - mTunerResourceManagerService.registerClientProfileInternal( - profiles[1], new TestResourcesReclaimListener(), clientId1); - assertThat(clientId1[0]).isNotEqualTo(TunerResourceManagerService.INVALID_CLIENT_ID); - mTunerResourceManagerService.updateClientPriorityInternal( - clientId1[0], clientPriorities[1], 0/*niceValue*/); + TunerClient client0 = new TunerClient(); + TunerClient client1 = new TunerClient(); + client0.register("0" /*sessionId*/, + TvInputService.PRIORITY_HINT_USE_CASE_TYPE_PLAYBACK, 100); + client1.register("1" /*sessionId*/, + TvInputService.PRIORITY_HINT_USE_CASE_TYPE_PLAYBACK, 500); // Init cicam/cas resources. mTunerResourceManagerService.updateCasInfoInternal(1 /*casSystemId*/, 2 /*maxSessionNum*/); - TunerCiCamRequest request = tunerCiCamRequest(clientId0[0], 1 /*ciCamId*/); + TunerCiCamRequest request = tunerCiCamRequest(client0.getId(), 1 /*ciCamId*/); int[] ciCamHandle = new int[1]; // Request for 2 ciCam sessions. assertThat(mTunerResourceManagerService @@ -589,139 +591,125 @@ public class TunerResourceManagerServiceTest { .requestCiCamInternal(request, ciCamHandle)).isTrue(); assertThat(mTunerResourceManagerService.getResourceIdFromHandle(ciCamHandle[0])) .isEqualTo(1); - assertThat(mTunerResourceManagerService.getClientProfile(clientId0[0]) - .getInUseCiCamId()).isEqualTo(1); + assertThat(client0.getProfile().getInUseCiCamId()).isEqualTo(1); assertThat(mTunerResourceManagerService.getCiCamResource(1) - .getOwnerClientIds()).isEqualTo(new HashSet<Integer>(Arrays.asList(clientId0[0]))); + .getOwnerClientIds()).isEqualTo( + new HashSet<Integer>(Arrays.asList(client0.getId()))); assertThat(mTunerResourceManagerService.getCiCamResource(1).isFullyUsed()).isTrue(); - request = tunerCiCamRequest(clientId1[0], 1); + request = tunerCiCamRequest(client1.getId(), 1); assertThat(mTunerResourceManagerService .requestCiCamInternal(request, ciCamHandle)).isTrue(); assertThat(mTunerResourceManagerService.getResourceIdFromHandle(ciCamHandle[0])) .isEqualTo(1); - assertThat(mTunerResourceManagerService.getClientProfile(clientId1[0]) - .getInUseCiCamId()).isEqualTo(1); - assertThat(mTunerResourceManagerService.getClientProfile(clientId0[0]) - .getInUseCiCamId()).isEqualTo(ClientProfile.INVALID_RESOURCE_ID); + assertThat(client1.getProfile().getInUseCiCamId()).isEqualTo(1); + assertThat(client0.getProfile().getInUseCiCamId()) + .isEqualTo(ClientProfile.INVALID_RESOURCE_ID); assertThat(mTunerResourceManagerService.getCiCamResource(1) - .getOwnerClientIds()).isEqualTo(new HashSet<Integer>(Arrays.asList(clientId1[0]))); - assertThat(mTunerResourceManagerService.getCiCamResource(1).isFullyUsed()).isFalse(); - assertThat(listener.isReclaimed()).isTrue(); + .getOwnerClientIds()).isEqualTo( + new HashSet<Integer>(Arrays.asList(client1.getId()))); + assertThat(mTunerResourceManagerService + .getCiCamResource(1).isFullyUsed()).isFalse(); + assertThat(client0.isReclaimed()).isTrue(); + client0.unregister(); + client1.unregister(); } @Test - public void releaseCasTest() { + public void releaseCasTest() throws RemoteException { // Register clients - ResourceClientProfile[] profiles = new ResourceClientProfile[1]; - profiles[0] = resourceClientProfile("0" /*sessionId*/, - TvInputService.PRIORITY_HINT_USE_CASE_TYPE_PLAYBACK); - int[] clientId = new int[1]; - TestResourcesReclaimListener listener = new TestResourcesReclaimListener(); - mTunerResourceManagerService.registerClientProfileInternal(profiles[0], listener, clientId); - assertThat(clientId[0]).isNotEqualTo(TunerResourceManagerService.INVALID_CLIENT_ID); + TunerClient client0 = new TunerClient(); + client0.register("0" /*sessionId*/, + TvInputService.PRIORITY_HINT_USE_CASE_TYPE_PLAYBACK); // Init cas resources. mTunerResourceManagerService.updateCasInfoInternal(1 /*casSystemId*/, 2 /*maxSessionNum*/); - CasSessionRequest request = casSessionRequest(clientId[0], 1 /*casSystemId*/); + CasSessionRequest request = casSessionRequest(client0.getId(), 1 /*casSystemId*/); int[] casSessionHandle = new int[1]; // Request for 1 cas sessions. assertThat(mTunerResourceManagerService .requestCasSessionInternal(request, casSessionHandle)).isTrue(); assertThat(mTunerResourceManagerService.getResourceIdFromHandle(casSessionHandle[0])) .isEqualTo(1); - assertThat(mTunerResourceManagerService.getClientProfile(clientId[0]) - .getInUseCasSystemId()).isEqualTo(1); + assertThat(client0.getProfile().getInUseCasSystemId()).isEqualTo(1); assertThat(mTunerResourceManagerService.getCasResource(1) - .getOwnerClientIds()).isEqualTo(new HashSet<Integer>(Arrays.asList(clientId[0]))); + .getOwnerClientIds()).isEqualTo( + new HashSet<Integer>(Arrays.asList(client0.getId()))); assertThat(mTunerResourceManagerService.getCasResource(1).isFullyUsed()).isFalse(); // Release cas mTunerResourceManagerService.releaseCasSessionInternal(mTunerResourceManagerService - .getCasResource(1), clientId[0]); - assertThat(mTunerResourceManagerService.getClientProfile(clientId[0]) - .getInUseCasSystemId()).isEqualTo(ClientProfile.INVALID_RESOURCE_ID); + .getCasResource(1), client0.getId()); + assertThat(client0.getProfile().getInUseCasSystemId()) + .isEqualTo(ClientProfile.INVALID_RESOURCE_ID); assertThat(mTunerResourceManagerService.getCasResource(1).isFullyUsed()).isFalse(); assertThat(mTunerResourceManagerService.getCasResource(1) .getOwnerClientIds()).isEmpty(); + client0.unregister(); } @Test - public void releaseCiCamTest() { + public void releaseCiCamTest() throws RemoteException { // Register clients - ResourceClientProfile[] profiles = new ResourceClientProfile[1]; - profiles[0] = resourceClientProfile("0" /*sessionId*/, - TvInputService.PRIORITY_HINT_USE_CASE_TYPE_PLAYBACK); - int[] clientId = new int[1]; - TestResourcesReclaimListener listener = new TestResourcesReclaimListener(); - mTunerResourceManagerService.registerClientProfileInternal(profiles[0], listener, clientId); - assertThat(clientId[0]).isNotEqualTo(TunerResourceManagerService.INVALID_CLIENT_ID); + TunerClient client0 = new TunerClient(); + client0.register("0" /*sessionId*/, + TvInputService.PRIORITY_HINT_USE_CASE_TYPE_PLAYBACK); // Init cas resources. mTunerResourceManagerService.updateCasInfoInternal(1 /*casSystemId*/, 2 /*maxSessionNum*/); - TunerCiCamRequest request = tunerCiCamRequest(clientId[0], 1 /*ciCamId*/); + TunerCiCamRequest request = tunerCiCamRequest(client0.getId(), 1 /*ciCamId*/); int[] ciCamHandle = new int[1]; // Request for 1 ciCam sessions. assertThat(mTunerResourceManagerService .requestCiCamInternal(request, ciCamHandle)).isTrue(); assertThat(mTunerResourceManagerService.getResourceIdFromHandle(ciCamHandle[0])) .isEqualTo(1); - assertThat(mTunerResourceManagerService.getClientProfile(clientId[0]) - .getInUseCiCamId()).isEqualTo(1); + assertThat(client0.getProfile().getInUseCiCamId()).isEqualTo(1); assertThat(mTunerResourceManagerService.getCiCamResource(1) - .getOwnerClientIds()).isEqualTo(new HashSet<Integer>(Arrays.asList(clientId[0]))); - assertThat(mTunerResourceManagerService.getCiCamResource(1).isFullyUsed()).isFalse(); + .getOwnerClientIds()).isEqualTo( + new HashSet<Integer>(Arrays.asList(client0.getId()))); + assertThat(mTunerResourceManagerService + .getCiCamResource(1).isFullyUsed()).isFalse(); // Release ciCam mTunerResourceManagerService.releaseCiCamInternal(mTunerResourceManagerService - .getCiCamResource(1), clientId[0]); - assertThat(mTunerResourceManagerService.getClientProfile(clientId[0]) - .getInUseCiCamId()).isEqualTo(ClientProfile.INVALID_RESOURCE_ID); - assertThat(mTunerResourceManagerService.getCiCamResource(1).isFullyUsed()).isFalse(); + .getCiCamResource(1), client0.getId()); + assertThat(client0.getProfile().getInUseCiCamId()) + .isEqualTo(ClientProfile.INVALID_RESOURCE_ID); + assertThat(mTunerResourceManagerService + .getCiCamResource(1).isFullyUsed()).isFalse(); assertThat(mTunerResourceManagerService.getCiCamResource(1) .getOwnerClientIds()).isEmpty(); + client0.unregister(); } @Test - public void requestLnbTest_NoLnbAvailable_RequestWithHigherPriority() { + public void requestLnbTest_NoLnbAvailable_RequestWithHigherPriority() throws RemoteException { // Register clients - ResourceClientProfile[] profiles = new ResourceClientProfile[2]; - profiles[0] = resourceClientProfile("0" /*sessionId*/, - TvInputService.PRIORITY_HINT_USE_CASE_TYPE_PLAYBACK); - profiles[1] = resourceClientProfile("1" /*sessionId*/, - TvInputService.PRIORITY_HINT_USE_CASE_TYPE_PLAYBACK); - int[] clientPriorities = {100, 500}; - int[] clientId0 = new int[1]; - int[] clientId1 = new int[1]; - TestResourcesReclaimListener listener = new TestResourcesReclaimListener(); - mTunerResourceManagerService.registerClientProfileInternal( - profiles[0], listener, clientId0); - assertThat(clientId0[0]).isNotEqualTo(TunerResourceManagerService.INVALID_CLIENT_ID); - mTunerResourceManagerService.updateClientPriorityInternal( - clientId0[0], clientPriorities[0], 0/*niceValue*/); - mTunerResourceManagerService.registerClientProfileInternal( - profiles[1], new TestResourcesReclaimListener(), clientId1); - assertThat(clientId1[0]).isNotEqualTo(TunerResourceManagerService.INVALID_CLIENT_ID); - mTunerResourceManagerService.updateClientPriorityInternal( - clientId1[0], clientPriorities[1], 0/*niceValue*/); + TunerClient client0 = new TunerClient(); + TunerClient client1 = new TunerClient(); + client0.register("0" /*sessionId*/, + TvInputService.PRIORITY_HINT_USE_CASE_TYPE_PLAYBACK, 100); + client1.register("1" /*sessionId*/, + TvInputService.PRIORITY_HINT_USE_CASE_TYPE_PLAYBACK, 500); // Init lnb resources. int[] lnbHandles = {1}; mTunerResourceManagerService.setLnbInfoListInternal(lnbHandles); TunerLnbRequest request = new TunerLnbRequest(); - request.clientId = clientId0[0]; + request.clientId = client0.getId(); int[] lnbHandle = new int[1]; assertThat(mTunerResourceManagerService .requestLnbInternal(request, lnbHandle)).isTrue(); assertThat(lnbHandle[0]).isEqualTo(lnbHandles[0]); - assertThat(mTunerResourceManagerService.getClientProfile(clientId0[0]).getInUseLnbHandles()) + assertThat(client0.getProfile().getInUseLnbHandles()) .isEqualTo(new HashSet<Integer>(Arrays.asList(lnbHandles[0]))); request = new TunerLnbRequest(); - request.clientId = clientId1[0]; + request.clientId = client1.getId(); assertThat(mTunerResourceManagerService .requestLnbInternal(request, lnbHandle)).isTrue(); @@ -729,29 +717,26 @@ public class TunerResourceManagerServiceTest { assertThat(mTunerResourceManagerService.getLnbResource(lnbHandles[0]) .isInUse()).isTrue(); assertThat(mTunerResourceManagerService.getLnbResource(lnbHandles[0]) - .getOwnerClientId()).isEqualTo(clientId1[0]); - assertThat(listener.isReclaimed()).isTrue(); - assertThat(mTunerResourceManagerService.getClientProfile(clientId0[0]) - .getInUseLnbHandles().size()).isEqualTo(0); + .getOwnerClientId()).isEqualTo(client1.getId()); + assertThat(client0.isReclaimed()).isTrue(); + assertThat(client0.getProfile().getInUseLnbHandles().size()).isEqualTo(0); + client0.unregister(); + client1.unregister(); } @Test - public void releaseLnbTest() { + public void releaseLnbTest() throws RemoteException { // Register clients - ResourceClientProfile[] profiles = new ResourceClientProfile[1]; - profiles[0] = resourceClientProfile("0" /*sessionId*/, - TvInputService.PRIORITY_HINT_USE_CASE_TYPE_PLAYBACK); - int[] clientId = new int[1]; - TestResourcesReclaimListener listener = new TestResourcesReclaimListener(); - mTunerResourceManagerService.registerClientProfileInternal(profiles[0], listener, clientId); - assertThat(clientId[0]).isNotEqualTo(TunerResourceManagerService.INVALID_CLIENT_ID); + TunerClient client0 = new TunerClient(); + client0.register("0" /*sessionId*/, + TvInputService.PRIORITY_HINT_USE_CASE_TYPE_PLAYBACK); // Init lnb resources. int[] lnbHandles = {0}; mTunerResourceManagerService.setLnbInfoListInternal(lnbHandles); TunerLnbRequest request = new TunerLnbRequest(); - request.clientId = clientId[0]; + request.clientId = client0.getId(); int[] lnbHandle = new int[1]; assertThat(mTunerResourceManagerService .requestLnbInternal(request, lnbHandle)).isTrue(); @@ -762,19 +747,16 @@ public class TunerResourceManagerServiceTest { .getLnbResource(lnbHandle[0])); assertThat(mTunerResourceManagerService .getLnbResource(lnbHandle[0]).isInUse()).isFalse(); - assertThat(mTunerResourceManagerService - .getClientProfile(clientId[0]).getInUseLnbHandles().size()).isEqualTo(0); + assertThat(client0.getProfile().getInUseLnbHandles().size()).isEqualTo(0); + client0.unregister(); } @Test - public void unregisterClientTest_usingFrontend() { - // Register client - ResourceClientProfile profile = resourceClientProfile("0" /*sessionId*/, - TvInputService.PRIORITY_HINT_USE_CASE_TYPE_PLAYBACK); - int[] clientId = new int[1]; - mTunerResourceManagerService.registerClientProfileInternal( - profile, null /*listener*/, clientId); - assertThat(clientId[0]).isNotEqualTo(TunerResourceManagerService.INVALID_CLIENT_ID); + public void unregisterClientTest_usingFrontend() throws RemoteException { + // Register clients + TunerClient client0 = new TunerClient(); + client0.register("0" /*sessionId*/, + TvInputService.PRIORITY_HINT_USE_CASE_TYPE_PLAYBACK); // Init frontend resources. TunerFrontendInfo[] infos = new TunerFrontendInfo[2]; @@ -785,7 +767,7 @@ public class TunerResourceManagerServiceTest { mTunerResourceManagerService.setFrontendInfoListInternal(infos); TunerFrontendRequest request = - tunerFrontendRequest(clientId[0] /*clientId*/, FrontendSettings.TYPE_DVBT); + tunerFrontendRequest(client0.getId() /*clientId*/, FrontendSettings.TYPE_DVBT); int[] frontendHandle = new int[1]; assertThat(mTunerResourceManagerService .requestFrontendInternal(request, frontendHandle)).isTrue(); @@ -796,26 +778,20 @@ public class TunerResourceManagerServiceTest { .isInUse()).isTrue(); // Unregister client when using frontend - mTunerResourceManagerService.unregisterClientProfileInternal(clientId[0]); + client0.unregister(); assertThat(mTunerResourceManagerService.getFrontendResource(infos[0].handle) .isInUse()).isFalse(); assertThat(mTunerResourceManagerService.getFrontendResource(infos[1].handle) .isInUse()).isFalse(); - assertThat(mTunerResourceManagerService.checkClientExists(clientId[0])).isFalse(); - + assertThat(mTunerResourceManagerService.checkClientExists(client0.getId())).isFalse(); } @Test - public void requestDemuxTest() { - // Register client - ResourceClientProfile profile0 = resourceClientProfile("0" /*sessionId*/, - TvInputService.PRIORITY_HINT_USE_CASE_TYPE_PLAYBACK); - ResourceClientProfile profile1 = resourceClientProfile("1" /*sessionId*/, - TvInputService.PRIORITY_HINT_USE_CASE_TYPE_PLAYBACK); - int[] clientId0 = new int[1]; - mTunerResourceManagerService.registerClientProfileInternal( - profile0, null /*listener*/, clientId0); - assertThat(clientId0[0]).isNotEqualTo(TunerResourceManagerService.INVALID_CLIENT_ID); + public void requestDemuxTest() throws RemoteException { + // Register clients + TunerClient client0 = new TunerClient(); + client0.register("0" /*sessionId*/, + TvInputService.PRIORITY_HINT_USE_CASE_TYPE_PLAYBACK); TunerDemuxInfo[] infos = new TunerDemuxInfo[3]; infos[0] = tunerDemuxInfo(0 /* handle */, Filter.TYPE_TS | Filter.TYPE_IP); @@ -825,7 +801,7 @@ public class TunerResourceManagerServiceTest { int[] demuxHandle0 = new int[1]; // first with undefined type (should be the first one with least # of caps) - TunerDemuxRequest request = tunerDemuxRequest(clientId0[0], Filter.TYPE_UNDEFINED); + TunerDemuxRequest request = tunerDemuxRequest(client0.getId(), Filter.TYPE_UNDEFINED); assertThat(mTunerResourceManagerService.requestDemuxInternal(request, demuxHandle0)) .isTrue(); assertThat(demuxHandle0[0]).isEqualTo(1); @@ -846,16 +822,16 @@ public class TunerResourceManagerServiceTest { assertThat(demuxHandle0[0]).isEqualTo(2); // request for another TS - int[] clientId1 = new int[1]; - mTunerResourceManagerService.registerClientProfileInternal( - profile1, null /*listener*/, clientId1); - assertThat(clientId1[0]).isNotEqualTo(TunerResourceManagerService.INVALID_CLIENT_ID); + TunerClient client1 = new TunerClient(); + client1.register("1" /*sessionId*/, + TvInputService.PRIORITY_HINT_USE_CASE_TYPE_PLAYBACK); + int[] demuxHandle1 = new int[1]; - TunerDemuxRequest request1 = tunerDemuxRequest(clientId1[0], Filter.TYPE_TS); + TunerDemuxRequest request1 = tunerDemuxRequest(client1.getId(), Filter.TYPE_TS); assertThat(mTunerResourceManagerService.requestDemuxInternal(request1, demuxHandle1)) .isTrue(); assertThat(demuxHandle1[0]).isEqualTo(0); - assertThat(mTunerResourceManagerService.getResourceIdFromHandle(demuxHandle1[0])) + assertThat(mTunerResourceManagerService.getResourceIdFromHandle(client1.getId())) .isEqualTo(0); // release demuxes @@ -863,33 +839,23 @@ public class TunerResourceManagerServiceTest { mTunerResourceManagerService.releaseDemuxInternal(dr); dr = mTunerResourceManagerService.getDemuxResource(demuxHandle1[0]); mTunerResourceManagerService.releaseDemuxInternal(dr); + + client0.unregister(); + client1.unregister(); } @Test - public void requestDemuxTest_ResourceReclaim() { + public void requestDemuxTest_ResourceReclaim() throws RemoteException { // Register clients - ResourceClientProfile profile0 = resourceClientProfile("0" /*sessionId*/, - TvInputService.PRIORITY_HINT_USE_CASE_TYPE_PLAYBACK); - ResourceClientProfile profile1 = resourceClientProfile("1" /*sessionId*/, - TvInputService.PRIORITY_HINT_USE_CASE_TYPE_SCAN); - ResourceClientProfile profile2 = resourceClientProfile("2" /*sessionId*/, - TvInputService.PRIORITY_HINT_USE_CASE_TYPE_SCAN); - int[] clientId0 = new int[1]; - int[] clientId1 = new int[1]; - int[] clientId2 = new int[1]; - TestResourcesReclaimListener listener0 = new TestResourcesReclaimListener(); - TestResourcesReclaimListener listener1 = new TestResourcesReclaimListener(); - TestResourcesReclaimListener listener2 = new TestResourcesReclaimListener(); - - mTunerResourceManagerService.registerClientProfileInternal( - profile0, listener0, clientId0); - assertThat(clientId0[0]).isNotEqualTo(TunerResourceManagerService.INVALID_CLIENT_ID); - mTunerResourceManagerService.registerClientProfileInternal( - profile1, listener1, clientId1); - assertThat(clientId1[0]).isNotEqualTo(TunerResourceManagerService.INVALID_CLIENT_ID); - mTunerResourceManagerService.registerClientProfileInternal( - profile2, listener2, clientId1); - assertThat(clientId2[0]).isNotEqualTo(TunerResourceManagerService.INVALID_CLIENT_ID); + TunerClient client0 = new TunerClient(); + TunerClient client1 = new TunerClient(); + TunerClient client2 = new TunerClient(); + client0.register("0" /*sessionId*/, + TvInputService.PRIORITY_HINT_USE_CASE_TYPE_PLAYBACK); + client1.register("1" /*sessionId*/, + TvInputService.PRIORITY_HINT_USE_CASE_TYPE_SCAN); + client2.register("2" /*sessionId*/, + TvInputService.PRIORITY_HINT_USE_CASE_TYPE_SCAN); // Init demux resources. TunerDemuxInfo[] infos = new TunerDemuxInfo[2]; @@ -897,66 +863,67 @@ public class TunerResourceManagerServiceTest { infos[1] = tunerDemuxInfo(1 /*handle*/, Filter.TYPE_TS); mTunerResourceManagerService.setDemuxInfoListInternal(infos); - // let clientId0(prio:100) request for IP - should succeed - TunerDemuxRequest request0 = tunerDemuxRequest(clientId0[0], Filter.TYPE_IP); + // let client0(prio:100) request for IP - should succeed + TunerDemuxRequest request0 = tunerDemuxRequest(client0.getId(), Filter.TYPE_IP); int[] demuxHandle0 = new int[1]; assertThat(mTunerResourceManagerService .requestDemuxInternal(request0, demuxHandle0)).isTrue(); assertThat(demuxHandle0[0]).isEqualTo(0); - // let clientId1(prio:50) request for IP - should fail - TunerDemuxRequest request1 = tunerDemuxRequest(clientId1[0], Filter.TYPE_IP); + // let client1(prio:50) request for IP - should fail + TunerDemuxRequest request1 = tunerDemuxRequest(client1.getId(), Filter.TYPE_IP); int[] demuxHandle1 = new int[1]; demuxHandle1[0] = -1; assertThat(mTunerResourceManagerService .requestDemuxInternal(request1, demuxHandle1)).isFalse(); - assertThat(listener0.isReclaimed()).isFalse(); + assertThat(client0.isReclaimed()).isFalse(); assertThat(demuxHandle1[0]).isEqualTo(-1); - // let clientId1(prio:50) request for TS - should succeed + // let client1(prio:50) request for TS - should succeed request1.desiredFilterTypes = Filter.TYPE_TS; assertThat(mTunerResourceManagerService .requestDemuxInternal(request1, demuxHandle1)).isTrue(); assertThat(demuxHandle1[0]).isEqualTo(1); - assertThat(listener0.isReclaimed()).isFalse(); + assertThat(client0.isReclaimed()).isFalse(); - // now release demux for the clientId0 (higher priority) and request demux + // now release demux for the client0 (higher priority) and request demux DemuxResource dr = mTunerResourceManagerService.getDemuxResource(demuxHandle0[0]); mTunerResourceManagerService.releaseDemuxInternal(dr); - // let clientId2(prio:50) request for TS - should succeed - TunerDemuxRequest request2 = tunerDemuxRequest(clientId2[0], Filter.TYPE_TS); + // let client2(prio:50) request for TS - should succeed + TunerDemuxRequest request2 = tunerDemuxRequest(client2.getId(), Filter.TYPE_TS); int[] demuxHandle2 = new int[1]; assertThat(mTunerResourceManagerService .requestDemuxInternal(request2, demuxHandle2)).isTrue(); assertThat(demuxHandle2[0]).isEqualTo(0); - assertThat(listener1.isReclaimed()).isFalse(); + assertThat(client1.isReclaimed()).isFalse(); - // let clientId0(prio:100) request for TS - should reclaim from clientId2 + // let client0(prio:100) request for TS - should reclaim from client1 // , who has the smaller caps request0.desiredFilterTypes = Filter.TYPE_TS; assertThat(mTunerResourceManagerService .requestDemuxInternal(request0, demuxHandle0)).isTrue(); - assertThat(listener1.isReclaimed()).isFalse(); - assertThat(listener2.isReclaimed()).isTrue(); + assertThat(client1.isReclaimed()).isTrue(); + assertThat(client2.isReclaimed()).isFalse(); + client0.unregister(); + client1.unregister(); + client2.unregister(); } @Test public void requestDescramblerTest() { - // Register client - ResourceClientProfile profile = resourceClientProfile("0" /*sessionId*/, - TvInputService.PRIORITY_HINT_USE_CASE_TYPE_PLAYBACK); - int[] clientId = new int[1]; - mTunerResourceManagerService.registerClientProfileInternal( - profile, null /*listener*/, clientId); - assertThat(clientId[0]).isNotEqualTo(TunerResourceManagerService.INVALID_CLIENT_ID); + // Register clients + TunerClient client0 = new TunerClient(); + client0.register("0" /*sessionId*/, + TvInputService.PRIORITY_HINT_USE_CASE_TYPE_PLAYBACK); int[] desHandle = new int[1]; TunerDescramblerRequest request = new TunerDescramblerRequest(); - request.clientId = clientId[0]; + request.clientId = client0.getId(); assertThat(mTunerResourceManagerService.requestDescramblerInternal(request, desHandle)) .isTrue(); assertThat(mTunerResourceManagerService.getResourceIdFromHandle(desHandle[0])).isEqualTo(0); + client0.unregister(); } @Test @@ -978,74 +945,26 @@ public class TunerResourceManagerServiceTest { } @Test - public void shareFrontendTest_FrontendWithExclusiveGroupReadyToShare() { + public void shareFrontendTest_FrontendWithExclusiveGroupReadyToShare() throws RemoteException { /**** Register Clients and Set Priority ****/ + TunerClient ownerClient0 = new TunerClient(); + TunerClient ownerClient1 = new TunerClient(); + TunerClient shareClient0 = new TunerClient(); + TunerClient shareClient1 = new TunerClient(); + ownerClient0.register("0" /*sessionId*/, + TvInputService.PRIORITY_HINT_USE_CASE_TYPE_LIVE, 100); + ownerClient1.register("1" /*sessionId*/, + TvInputService.PRIORITY_HINT_USE_CASE_TYPE_LIVE, 300); + shareClient0.register("2" /*sessionId*/, + TvInputService.PRIORITY_HINT_USE_CASE_TYPE_RECORD, 200); + shareClient1.register("3" /*sessionId*/, + TvInputService.PRIORITY_HINT_USE_CASE_TYPE_RECORD, 400); - // Int array to save the returned client ids - int[] ownerClientId0 = new int[1]; - int[] ownerClientId1 = new int[1]; - int[] shareClientId0 = new int[1]; - int[] shareClientId1 = new int[1]; - - // Predefined client profiles - ResourceClientProfile[] ownerProfiles = new ResourceClientProfile[2]; - ResourceClientProfile[] shareProfiles = new ResourceClientProfile[2]; - ownerProfiles[0] = resourceClientProfile( - "0" /*sessionId*/, - TvInputService.PRIORITY_HINT_USE_CASE_TYPE_LIVE); - ownerProfiles[1] = resourceClientProfile( - "1" /*sessionId*/, - TvInputService.PRIORITY_HINT_USE_CASE_TYPE_LIVE); - shareProfiles[0] = resourceClientProfile( - "2" /*sessionId*/, - TvInputService.PRIORITY_HINT_USE_CASE_TYPE_RECORD); - shareProfiles[1] = resourceClientProfile( - "3" /*sessionId*/, - TvInputService.PRIORITY_HINT_USE_CASE_TYPE_RECORD); - - // Predefined client reclaim listeners - TestResourcesReclaimListener ownerListener0 = new TestResourcesReclaimListener(); - TestResourcesReclaimListener shareListener0 = new TestResourcesReclaimListener(); - TestResourcesReclaimListener ownerListener1 = new TestResourcesReclaimListener(); - TestResourcesReclaimListener shareListener1 = new TestResourcesReclaimListener(); - // Register clients and validate the returned client ids - mTunerResourceManagerService - .registerClientProfileInternal(ownerProfiles[0], ownerListener0, ownerClientId0); - mTunerResourceManagerService - .registerClientProfileInternal(shareProfiles[0], shareListener0, shareClientId0); - mTunerResourceManagerService - .registerClientProfileInternal(ownerProfiles[1], ownerListener1, ownerClientId1); - mTunerResourceManagerService - .registerClientProfileInternal(shareProfiles[1], shareListener1, shareClientId1); - assertThat(ownerClientId0[0]).isNotEqualTo(TunerResourceManagerService.INVALID_CLIENT_ID); - assertThat(shareClientId0[0]).isNotEqualTo(TunerResourceManagerService.INVALID_CLIENT_ID); - assertThat(ownerClientId1[0]).isNotEqualTo(TunerResourceManagerService.INVALID_CLIENT_ID); - assertThat(shareClientId1[0]).isNotEqualTo(TunerResourceManagerService.INVALID_CLIENT_ID); - - mTunerResourceManagerService.updateClientPriorityInternal( - ownerClientId0[0], - 100/*priority*/, - 0/*niceValue*/); - mTunerResourceManagerService.updateClientPriorityInternal( - shareClientId0[0], - 200/*priority*/, - 0/*niceValue*/); - mTunerResourceManagerService.updateClientPriorityInternal( - ownerClientId1[0], - 300/*priority*/, - 0/*niceValue*/); - mTunerResourceManagerService.updateClientPriorityInternal( - shareClientId1[0], - 400/*priority*/, - 0/*niceValue*/); mTunerResourceManagerService.updateClientPriorityInternal( - shareClientId1[0], + shareClient1.getId(), -1/*invalid priority*/, 0/*niceValue*/); - assertThat(mTunerResourceManagerService - .getClientProfile(shareClientId1[0]) - .getPriority()) - .isEqualTo(400); + assertThat(shareClient1.getProfile().getPriority()).isEqualTo(400); /**** Init Frontend Resources ****/ @@ -1072,7 +991,7 @@ public class TunerResourceManagerServiceTest { // Predefined frontend request and array to save returned frontend handle int[] frontendHandle = new int[1]; TunerFrontendRequest request = tunerFrontendRequest( - ownerClientId0[0] /*clientId*/, + ownerClient0.getId() /*clientId*/, FrontendSettings.TYPE_DVBT); // Request call and validate granted resource and internal mapping @@ -1080,9 +999,7 @@ public class TunerResourceManagerServiceTest { .requestFrontendInternal(request, frontendHandle)) .isTrue(); assertThat(frontendHandle[0]).isEqualTo(infos[0].handle); - assertThat(mTunerResourceManagerService - .getClientProfile(ownerClientId0[0]) - .getInUseFrontendHandles()) + assertThat(ownerClient0.getProfile().getInUseFrontendHandles()) .isEqualTo(new HashSet<Integer>(Arrays.asList( infos[0].handle, infos[1].handle))); @@ -1091,11 +1008,11 @@ public class TunerResourceManagerServiceTest { // Share frontend call and validate the internal mapping mTunerResourceManagerService.shareFrontendInternal( - shareClientId0[0]/*selfClientId*/, - ownerClientId0[0]/*targetClientId*/); + shareClient0.getId()/*selfClientId*/, + ownerClient0.getId()/*targetClientId*/); mTunerResourceManagerService.shareFrontendInternal( - shareClientId1[0]/*selfClientId*/, - ownerClientId0[0]/*targetClientId*/); + shareClient1.getId()/*selfClientId*/, + ownerClient0.getId()/*targetClientId*/); // Verify fe in use status assertThat(mTunerResourceManagerService.getFrontendResource(infos[0].handle) .isInUse()).isTrue(); @@ -1103,31 +1020,24 @@ public class TunerResourceManagerServiceTest { .isInUse()).isTrue(); // Verify fe owner status assertThat(mTunerResourceManagerService.getFrontendResource(infos[0].handle) - .getOwnerClientId()).isEqualTo(ownerClientId0[0]); + .getOwnerClientId()).isEqualTo(ownerClient0.getId()); assertThat(mTunerResourceManagerService.getFrontendResource(infos[1].handle) - .getOwnerClientId()).isEqualTo(ownerClientId0[0]); + .getOwnerClientId()).isEqualTo(ownerClient0.getId()); // Verify share fe client status in the primary owner client - assertThat(mTunerResourceManagerService.getClientProfile(ownerClientId0[0]) - .getShareFeClientIds()) + assertThat(ownerClient0.getProfile().getShareFeClientIds()) .isEqualTo(new HashSet<Integer>(Arrays.asList( - shareClientId0[0], - shareClientId1[0]))); + shareClient0.getId(), + shareClient1.getId()))); // Verify in use frontend list in all the primary owner and share owner clients - assertThat(mTunerResourceManagerService - .getClientProfile(ownerClientId0[0]) - .getInUseFrontendHandles()) + assertThat(ownerClient0.getProfile().getInUseFrontendHandles()) .isEqualTo(new HashSet<Integer>(Arrays.asList( infos[0].handle, infos[1].handle))); - assertThat(mTunerResourceManagerService - .getClientProfile(shareClientId0[0]) - .getInUseFrontendHandles()) + assertThat(shareClient0.getProfile().getInUseFrontendHandles()) .isEqualTo(new HashSet<Integer>(Arrays.asList( infos[0].handle, infos[1].handle))); - assertThat(mTunerResourceManagerService - .getClientProfile(shareClientId1[0]) - .getInUseFrontendHandles()) + assertThat(shareClient1.getProfile().getInUseFrontendHandles()) .isEqualTo(new HashSet<Integer>(Arrays.asList( infos[0].handle, infos[1].handle))); @@ -1135,21 +1045,17 @@ public class TunerResourceManagerServiceTest { /**** Remove Frontend Share Owner ****/ // Unregister the second share fe client - mTunerResourceManagerService.unregisterClientProfileInternal(shareClientId1[0]); + shareClient1.unregister(); // Validate the internal mapping - assertThat(mTunerResourceManagerService.getClientProfile(ownerClientId0[0]) - .getShareFeClientIds()) + assertThat(ownerClient0.getProfile().getShareFeClientIds()) .isEqualTo(new HashSet<Integer>(Arrays.asList( - shareClientId0[0]))); - assertThat(mTunerResourceManagerService - .getClientProfile(ownerClientId0[0]) - .getInUseFrontendHandles()) + shareClient0.getId()))); + assertThat(ownerClient0.getProfile().getInUseFrontendHandles()) .isEqualTo(new HashSet<Integer>(Arrays.asList( infos[0].handle, infos[1].handle))); - assertThat(mTunerResourceManagerService - .getClientProfile(shareClientId0[0]) + assertThat(shareClient0.getProfile() .getInUseFrontendHandles()) .isEqualTo(new HashSet<Integer>(Arrays.asList( infos[0].handle, @@ -1159,7 +1065,7 @@ public class TunerResourceManagerServiceTest { // Predefined second frontend request request = tunerFrontendRequest( - ownerClientId1[0] /*clientId*/, + ownerClient1.getId() /*clientId*/, FrontendSettings.TYPE_DVBT); // Second request call @@ -1170,43 +1076,35 @@ public class TunerResourceManagerServiceTest { // Validate granted resource and internal mapping assertThat(frontendHandle[0]).isEqualTo(infos[0].handle); assertThat(mTunerResourceManagerService.getFrontendResource(infos[0].handle) - .getOwnerClientId()).isEqualTo(ownerClientId1[0]); + .getOwnerClientId()).isEqualTo(ownerClient1.getId()); assertThat(mTunerResourceManagerService.getFrontendResource(infos[1].handle) - .getOwnerClientId()).isEqualTo(ownerClientId1[0]); - assertThat(mTunerResourceManagerService - .getClientProfile(ownerClientId1[0]) - .getInUseFrontendHandles()) + .getOwnerClientId()).isEqualTo(ownerClient1.getId()); + assertThat(ownerClient1.getProfile().getInUseFrontendHandles()) .isEqualTo(new HashSet<Integer>(Arrays.asList( infos[0].handle, infos[1].handle))); - assertThat(mTunerResourceManagerService - .getClientProfile(ownerClientId0[0]) - .getInUseFrontendHandles() + assertThat(ownerClient0.getProfile().getInUseFrontendHandles() .isEmpty()) .isTrue(); - assertThat(mTunerResourceManagerService - .getClientProfile(shareClientId0[0]) - .getInUseFrontendHandles() + assertThat(shareClient0.getProfile().getInUseFrontendHandles() .isEmpty()) .isTrue(); - assertThat(mTunerResourceManagerService - .getClientProfile(ownerClientId0[0]) - .getShareFeClientIds() + assertThat(ownerClient0.getProfile().getShareFeClientIds() .isEmpty()) .isTrue(); - assertThat(ownerListener0.isReclaimed()).isTrue(); - assertThat(shareListener0.isReclaimed()).isTrue(); + assertThat(ownerClient0.isReclaimed()).isTrue(); + assertThat(shareClient0.isReclaimed()).isTrue(); /**** Release Frontend Resource From Primary Owner ****/ // Reshare the frontend mTunerResourceManagerService.shareFrontendInternal( - shareClientId0[0]/*selfClientId*/, - ownerClientId1[0]/*targetClientId*/); + shareClient0.getId()/*selfClientId*/, + ownerClient1.getId()/*targetClientId*/); // Release the frontend resource from the primary owner - mTunerResourceManagerService.releaseFrontendInternal(mTunerResourceManagerService - .getFrontendResource(infos[0].handle), ownerClientId1[0]); + mTunerResourceManagerService.releaseFrontendInternal(infos[0].handle, + ownerClient1.getId()); // Validate the internal mapping assertThat(mTunerResourceManagerService.getFrontendResource(infos[0].handle) @@ -1214,19 +1112,13 @@ public class TunerResourceManagerServiceTest { assertThat(mTunerResourceManagerService.getFrontendResource(infos[1].handle) .isInUse()).isFalse(); // Verify client status - assertThat(mTunerResourceManagerService - .getClientProfile(ownerClientId1[0]) - .getInUseFrontendHandles() + assertThat(ownerClient1.getProfile().getInUseFrontendHandles() .isEmpty()) .isTrue(); - assertThat(mTunerResourceManagerService - .getClientProfile(shareClientId0[0]) - .getInUseFrontendHandles() + assertThat(shareClient0.getProfile().getInUseFrontendHandles() .isEmpty()) .isTrue(); - assertThat(mTunerResourceManagerService - .getClientProfile(ownerClientId1[0]) - .getShareFeClientIds() + assertThat(ownerClient1.getProfile().getShareFeClientIds() .isEmpty()) .isTrue(); @@ -1234,7 +1126,7 @@ public class TunerResourceManagerServiceTest { // Predefined Lnb request and handle array TunerLnbRequest requestLnb = new TunerLnbRequest(); - requestLnb.clientId = shareClientId0[0]; + requestLnb.clientId = shareClient0.getId(); int[] lnbHandle = new int[1]; // Request for an Lnb @@ -1247,11 +1139,11 @@ public class TunerResourceManagerServiceTest { .requestFrontendInternal(request, frontendHandle)) .isTrue(); mTunerResourceManagerService.shareFrontendInternal( - shareClientId0[0]/*selfClientId*/, - ownerClientId1[0]/*targetClientId*/); + shareClient0.getId()/*selfClientId*/, + ownerClient1.getId()/*targetClientId*/); // Unregister the primary owner of the shared frontend - mTunerResourceManagerService.unregisterClientProfileInternal(ownerClientId1[0]); + ownerClient1.unregister(); // Validate the internal mapping assertThat(mTunerResourceManagerService.getFrontendResource(infos[0].handle) @@ -1259,16 +1151,15 @@ public class TunerResourceManagerServiceTest { assertThat(mTunerResourceManagerService.getFrontendResource(infos[1].handle) .isInUse()).isFalse(); // Verify client status - assertThat(mTunerResourceManagerService - .getClientProfile(shareClientId0[0]) - .getInUseFrontendHandles() + assertThat(shareClient0.getProfile().getInUseFrontendHandles() .isEmpty()) .isTrue(); - assertThat(mTunerResourceManagerService - .getClientProfile(shareClientId0[0]) - .getInUseLnbHandles()) + assertThat(shareClient0.getProfile().getInUseLnbHandles()) .isEqualTo(new HashSet<Integer>(Arrays.asList( lnbHandles[0]))); + + ownerClient0.unregister(); + shareClient0.unregister(); } private TunerFrontendInfo tunerFrontendInfo( diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java index cba2eeae5c9f..13bd5eb67e44 100644 --- a/telephony/java/android/telephony/CarrierConfigManager.java +++ b/telephony/java/android/telephony/CarrierConfigManager.java @@ -10014,6 +10014,19 @@ public class CarrierConfigManager { public static final String KEY_SATELLITE_NIDD_APN_NAME_STRING = "satellite_nidd_apn_name_string"; + /** + * Default value {@code true}, meaning when an emergency call request comes in, if the device is + * in emergency satellite mode but hasn't sent the first satellite datagram, then exits + * satellite mode to allow the emergency call to go through. + * + * If {@code false}, the emergency call is always blocked if device is in emergency satellite + * mode. Note if device is NOT in emergency satellite mode, emergency call is always allowed. + * + * @hide + */ + public static final String KEY_SATELLITE_ROAMING_TURN_OFF_SESSION_FOR_EMERGENCY_CALL_BOOL = + "satellite_roaming_turn_off_session_for_emergency_call_bool"; + /** @hide */ @IntDef({ CARRIER_ROAMING_NTN_CONNECT_AUTOMATIC, @@ -11276,6 +11289,7 @@ public class CarrierConfigManager { sDefaults.putBoolean(KEY_SATELLITE_ESOS_SUPPORTED_BOOL, false); sDefaults.putBoolean(KEY_SATELLITE_ROAMING_P2P_SMS_SUPPORTED_BOOL, false); sDefaults.putString(KEY_SATELLITE_NIDD_APN_NAME_STRING, ""); + sDefaults.putBoolean(KEY_SATELLITE_ROAMING_TURN_OFF_SESSION_FOR_EMERGENCY_CALL_BOOL, true); sDefaults.putInt(KEY_CARRIER_ROAMING_NTN_CONNECT_TYPE_INT, 0); sDefaults.putInt(KEY_CARRIER_ROAMING_NTN_EMERGENCY_CALL_TO_SATELLITE_HANDOVER_TYPE_INT, SatelliteManager.EMERGENCY_CALL_TO_SATELLITE_HANDOVER_TYPE_T911); diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java index 7481daa8e396..bc709abbe76e 100644 --- a/telephony/java/android/telephony/TelephonyManager.java +++ b/telephony/java/android/telephony/TelephonyManager.java @@ -132,6 +132,7 @@ import com.android.internal.telephony.OperatorInfo; import com.android.internal.telephony.PhoneConstants; import com.android.internal.telephony.RILConstants; import com.android.internal.telephony.flags.Flags; +import com.android.internal.telephony.util.TelephonyUtils; import com.android.telephony.Rlog; import java.io.IOException; @@ -9975,6 +9976,7 @@ public class TelephonyManager { ALLOWED_NETWORK_TYPES_REASON_POWER, ALLOWED_NETWORK_TYPES_REASON_CARRIER, ALLOWED_NETWORK_TYPES_REASON_ENABLE_2G, + ALLOWED_NETWORK_TYPES_REASON_TEST, }) @Retention(RetentionPolicy.SOURCE) public @interface AllowedNetworkTypesReason { @@ -10013,6 +10015,14 @@ public class TelephonyManager { public static final int ALLOWED_NETWORK_TYPES_REASON_ENABLE_2G = 3; /** + * To indicate allowed network type change is requested by Testing purpose, should be default to + * {@link #getAllNetworkTypesBitmask} when done testing. + * + * @hide + */ + public static final int ALLOWED_NETWORK_TYPES_REASON_TEST = 4; + + /** * Set the allowed network types of the device and provide the reason triggering the allowed * network change. * <p>Requires permission: {@link android.Manifest.permission#MODIFY_PHONE_STATE} or @@ -10118,6 +10128,8 @@ public class TelephonyManager { case TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_CARRIER: case TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_ENABLE_2G: return true; + case TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_TEST: + return TelephonyUtils.IS_DEBUGGABLE; } return false; } diff --git a/telephony/java/android/telephony/satellite/SatelliteManager.java b/telephony/java/android/telephony/satellite/SatelliteManager.java index c5934a70610f..83fc0dcfe790 100644 --- a/telephony/java/android/telephony/satellite/SatelliteManager.java +++ b/telephony/java/android/telephony/satellite/SatelliteManager.java @@ -592,7 +592,7 @@ public final class SatelliteManager { () -> resultListener.accept(result))); } }; - telephony.requestSatelliteEnabled(mSubId, attributes.isEnabled(), + telephony.requestSatelliteEnabled(attributes.isEnabled(), attributes.isDemoMode(), attributes.isEmergencyMode(), errorCallback); } else { Rlog.e(TAG, "requestEnabled() invalid telephony"); @@ -650,7 +650,7 @@ public final class SatelliteManager { } } }; - telephony.requestIsSatelliteEnabled(mSubId, receiver); + telephony.requestIsSatelliteEnabled(receiver); } else { loge("requestIsEnabled() invalid telephony"); executor.execute(() -> Binder.withCleanCallingIdentity(() -> callback.onError( @@ -707,7 +707,7 @@ public final class SatelliteManager { } } }; - telephony.requestIsDemoModeEnabled(mSubId, receiver); + telephony.requestIsDemoModeEnabled(receiver); } else { loge("requestIsDemoModeEnabled() invalid telephony"); executor.execute(() -> Binder.withCleanCallingIdentity(() -> callback.onError( @@ -764,7 +764,7 @@ public final class SatelliteManager { } } }; - telephony.requestIsEmergencyModeEnabled(mSubId, receiver); + telephony.requestIsEmergencyModeEnabled(receiver); } else { executor.execute(() -> Binder.withCleanCallingIdentity(() -> callback.onError( new SatelliteException(SATELLITE_RESULT_ILLEGAL_STATE)))); @@ -821,7 +821,7 @@ public final class SatelliteManager { } } }; - telephony.requestIsSatelliteSupported(mSubId, receiver); + telephony.requestIsSatelliteSupported(receiver); } else { loge("requestIsSupported() invalid telephony"); executor.execute(() -> Binder.withCleanCallingIdentity(() -> callback.onError( @@ -878,7 +878,7 @@ public final class SatelliteManager { } } }; - telephony.requestSatelliteCapabilities(mSubId, receiver); + telephony.requestSatelliteCapabilities(receiver); } else { loge("requestCapabilities() invalid telephony"); executor.execute(() -> Binder.withCleanCallingIdentity(() -> callback.onError( @@ -1204,8 +1204,7 @@ public final class SatelliteManager { } }; sSatelliteTransmissionUpdateCallbackMap.put(callback, internalCallback); - telephony.startSatelliteTransmissionUpdates(mSubId, errorCallback, - internalCallback); + telephony.startSatelliteTransmissionUpdates(errorCallback, internalCallback); } else { loge("startTransmissionUpdates() invalid telephony"); executor.execute(() -> Binder.withCleanCallingIdentity( @@ -1255,8 +1254,7 @@ public final class SatelliteManager { () -> resultListener.accept(result))); } }; - telephony.stopSatelliteTransmissionUpdates(mSubId, errorCallback, - internalCallback); + telephony.stopSatelliteTransmissionUpdates(errorCallback, internalCallback); // TODO: Notify SmsHandler that pointing UI stopped } else { loge("stopSatelliteTransmissionUpdates: No internal callback."); @@ -1312,7 +1310,7 @@ public final class SatelliteManager { () -> resultListener.accept(result))); } }; - cancelRemote = telephony.provisionSatelliteService(mSubId, token, provisionData, + cancelRemote = telephony.provisionSatelliteService(token, provisionData, errorCallback); } else { loge("provisionService() invalid telephony"); @@ -1364,7 +1362,7 @@ public final class SatelliteManager { () -> resultListener.accept(result))); } }; - telephony.deprovisionSatelliteService(mSubId, token, errorCallback); + telephony.deprovisionSatelliteService(token, errorCallback); } else { loge("deprovisionService() invalid telephony"); executor.execute(() -> Binder.withCleanCallingIdentity( @@ -1419,8 +1417,7 @@ public final class SatelliteManager { } }; sSatelliteProvisionStateCallbackMap.put(callback, internalCallback); - return telephony.registerForSatelliteProvisionStateChanged( - mSubId, internalCallback); + return telephony.registerForSatelliteProvisionStateChanged(internalCallback); } else { throw new IllegalStateException("telephony service is null."); } @@ -1453,7 +1450,7 @@ public final class SatelliteManager { ITelephony telephony = getITelephony(); if (telephony != null) { if (internalCallback != null) { - telephony.unregisterForSatelliteProvisionStateChanged(mSubId, internalCallback); + telephony.unregisterForSatelliteProvisionStateChanged(internalCallback); } else { loge("unregisterForProvisionStateChanged: No internal callback."); } @@ -1510,7 +1507,7 @@ public final class SatelliteManager { } } }; - telephony.requestIsSatelliteProvisioned(mSubId, receiver); + telephony.requestIsSatelliteProvisioned(receiver); } else { loge("requestIsProvisioned() invalid telephony"); executor.execute(() -> Binder.withCleanCallingIdentity(() -> callback.onError( @@ -1560,7 +1557,7 @@ public final class SatelliteManager { } }; sSatelliteModemStateCallbackMap.put(callback, internalCallback); - return telephony.registerForSatelliteModemStateChanged(mSubId, internalCallback); + return telephony.registerForSatelliteModemStateChanged(internalCallback); } else { throw new IllegalStateException("telephony service is null."); } @@ -1593,7 +1590,7 @@ public final class SatelliteManager { ITelephony telephony = getITelephony(); if (telephony != null) { if (internalCallback != null) { - telephony.unregisterForModemStateChanged(mSubId, internalCallback); + telephony.unregisterForModemStateChanged(internalCallback); } else { loge("unregisterForModemStateChanged: No internal callback."); } @@ -1656,7 +1653,7 @@ public final class SatelliteManager { } }; sSatelliteDatagramCallbackMap.put(callback, internalCallback); - return telephony.registerForIncomingDatagram(mSubId, internalCallback); + return telephony.registerForIncomingDatagram(internalCallback); } else { throw new IllegalStateException("telephony service is null."); } @@ -1688,7 +1685,7 @@ public final class SatelliteManager { ITelephony telephony = getITelephony(); if (telephony != null) { if (internalCallback != null) { - telephony.unregisterForIncomingDatagram(mSubId, internalCallback); + telephony.unregisterForIncomingDatagram(internalCallback); } else { loge("unregisterForIncomingDatagram: No internal callback."); } @@ -1732,7 +1729,7 @@ public final class SatelliteManager { () -> resultListener.accept(result))); } }; - telephony.pollPendingDatagrams(mSubId, internalCallback); + telephony.pollPendingDatagrams(internalCallback); } else { loge("pollPendingDatagrams() invalid telephony"); executor.execute(() -> Binder.withCleanCallingIdentity( @@ -1790,7 +1787,7 @@ public final class SatelliteManager { () -> resultListener.accept(result))); } }; - telephony.sendDatagram(mSubId, datagramType, datagram, + telephony.sendDatagram(datagramType, datagram, needFullScreenPointingUI, internalCallback); } else { loge("sendDatagram() invalid telephony"); @@ -1908,7 +1905,7 @@ public final class SatelliteManager { } } }; - telephony.requestTimeForNextSatelliteVisibility(mSubId, receiver); + telephony.requestTimeForNextSatelliteVisibility(receiver); } else { loge("requestTimeForNextSatelliteVisibility() invalid telephony"); executor.execute(() -> Binder.withCleanCallingIdentity(() -> callback.onError( @@ -1939,7 +1936,7 @@ public final class SatelliteManager { try { ITelephony telephony = getITelephony(); if (telephony != null) { - telephony.setDeviceAlignedWithSatellite(mSubId, isAligned); + telephony.setDeviceAlignedWithSatellite(isAligned); } else { throw new IllegalStateException("telephony service is null."); } @@ -2203,7 +2200,7 @@ public final class SatelliteManager { } } }; - telephony.requestNtnSignalStrength(mSubId, receiver); + telephony.requestNtnSignalStrength(receiver); } else { loge("requestNtnSignalStrength() invalid telephony"); executor.execute(() -> Binder.withCleanCallingIdentity(() -> callback.onError( @@ -2254,7 +2251,7 @@ public final class SatelliteManager { ntnSignalStrength))); } }; - telephony.registerForNtnSignalStrengthChanged(mSubId, internalCallback); + telephony.registerForNtnSignalStrengthChanged(internalCallback); sNtnSignalStrengthCallbackMap.put(callback, internalCallback); } else { throw new IllegalStateException("Telephony service is null."); @@ -2294,7 +2291,7 @@ public final class SatelliteManager { ITelephony telephony = getITelephony(); if (telephony != null) { if (internalCallback != null) { - telephony.unregisterForNtnSignalStrengthChanged(mSubId, internalCallback); + telephony.unregisterForNtnSignalStrengthChanged(internalCallback); } else { loge("unregisterForNtnSignalStrengthChanged: No internal callback."); throw new IllegalArgumentException("callback is not valid"); @@ -2339,7 +2336,7 @@ public final class SatelliteManager { } }; sSatelliteCapabilitiesCallbackMap.put(callback, internalCallback); - return telephony.registerForCapabilitiesChanged(mSubId, internalCallback); + return telephony.registerForCapabilitiesChanged(internalCallback); } else { throw new IllegalStateException("Telephony service is null."); } @@ -2372,7 +2369,7 @@ public final class SatelliteManager { ITelephony telephony = getITelephony(); if (telephony != null) { if (internalCallback != null) { - telephony.unregisterForCapabilitiesChanged(mSubId, internalCallback); + telephony.unregisterForCapabilitiesChanged(internalCallback); } else { loge("unregisterForCapabilitiesChanged: No internal callback."); } @@ -2448,7 +2445,7 @@ public final class SatelliteManager { }; sSatelliteSupportedStateCallbackMap.put(callback, internalCallback); return telephony.registerForSatelliteSupportedStateChanged( - mSubId, internalCallback); + internalCallback); } else { throw new IllegalStateException("telephony service is null."); } @@ -2483,7 +2480,7 @@ public final class SatelliteManager { ITelephony telephony = getITelephony(); if (telephony != null) { if (internalCallback != null) { - telephony.unregisterForSatelliteSupportedStateChanged(mSubId, internalCallback); + telephony.unregisterForSatelliteSupportedStateChanged(internalCallback); } else { loge("unregisterForSupportedStateChanged: No internal callback."); } diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl index 0c5f30f96360..e852e6bbb756 100644 --- a/telephony/java/com/android/internal/telephony/ITelephony.aidl +++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl @@ -2743,7 +2743,6 @@ interface ITelephony { /** * Request to enable or disable the satellite modem. * - * @param subId The subId of the subscription to enable or disable the satellite modem for. * @param enableSatellite True to enable the satellite modem and false to disable. * @param enableDemoMode True if demo mode is enabled and false otherwise. When * disabling satellite, {@code enableDemoMode} is always considered as @@ -2755,93 +2754,83 @@ interface ITelephony { */ @JavaPassthrough(annotation="@android.annotation.RequiresPermission(" + "android.Manifest.permission.SATELLITE_COMMUNICATION)") - void requestSatelliteEnabled(int subId, boolean enableSatellite, boolean enableDemoMode, + void requestSatelliteEnabled(boolean enableSatellite, boolean enableDemoMode, boolean isEmergency, in IIntegerConsumer callback); /** * Request to get whether the satellite modem is enabled. * - * @param subId The subId of the subscription to request whether satellite is enabled for. * @param receiver Result receiver to get the error code of the request and whether the * satellite modem is enabled. */ @JavaPassthrough(annotation="@android.annotation.RequiresPermission(" + "android.Manifest.permission.SATELLITE_COMMUNICATION)") - void requestIsSatelliteEnabled(int subId, in ResultReceiver receiver); + void requestIsSatelliteEnabled(in ResultReceiver receiver); /** * Request to get whether the satellite service demo mode is enabled. * - * @param subId The subId of the subscription to request whether the satellite demo mode is - * enabled for. * @param receiver Result receiver to get the error code of the request and whether the * satellite demo mode is enabled. */ @JavaPassthrough(annotation="@android.annotation.RequiresPermission(" + "android.Manifest.permission.SATELLITE_COMMUNICATION)") - void requestIsDemoModeEnabled(int subId, in ResultReceiver receiver); + void requestIsDemoModeEnabled(in ResultReceiver receiver); /** * Request to get whether the satellite service is enabled with emergency mode. * - * @param subId The subId of the subscription to request whether the satellite demo mode is - * enabled for. * @param receiver Result receiver to get the error code of the request and whether the * satellite is enabled with emergency mode. */ @JavaPassthrough(annotation="@android.annotation.RequiresPermission(" + "android.Manifest.permission.SATELLITE_COMMUNICATION)") - void requestIsEmergencyModeEnabled(int subId, in ResultReceiver receiver); + void requestIsEmergencyModeEnabled(in ResultReceiver receiver); /** * Request to get whether the satellite service is supported on the device. * - * @param subId The subId of the subscription to check whether satellite is supported for. * @param receiver Result receiver to get the error code of the request and whether the * satellite service is supported on the device. */ - void requestIsSatelliteSupported(int subId, in ResultReceiver receiver); + void requestIsSatelliteSupported(in ResultReceiver receiver); /** * Request to get the capabilities of the satellite service. * - * @param subId The subId of the subscription to get the capabilities for. * @param receiver Result receiver to get the error code of the request and the requested * capabilities of the satellite service. */ @JavaPassthrough(annotation="@android.annotation.RequiresPermission(" + "android.Manifest.permission.SATELLITE_COMMUNICATION)") - void requestSatelliteCapabilities(int subId, in ResultReceiver receiver); + void requestSatelliteCapabilities(in ResultReceiver receiver); /** * Start receiving satellite transmission updates. * - * @param subId The subId of the subscription to stop satellite transmission updates for. * @param resultCallback The callback to get the result of the request. * @param callback The callback to handle transmission updates. */ @JavaPassthrough(annotation="@android.annotation.RequiresPermission(" + "android.Manifest.permission.SATELLITE_COMMUNICATION)") - void startSatelliteTransmissionUpdates(int subId, in IIntegerConsumer resultCallback, + void startSatelliteTransmissionUpdates(in IIntegerConsumer resultCallback, in ISatelliteTransmissionUpdateCallback callback); /** * Stop receiving satellite transmission updates. * - * @param subId The subId of the subscritpion to stop satellite transmission updates for. * @param resultCallback The callback to get the result of the request. * @param callback The callback that was passed to startSatelliteTransmissionUpdates. */ @JavaPassthrough(annotation="@android.annotation.RequiresPermission(" + "android.Manifest.permission.SATELLITE_COMMUNICATION)") - void stopSatelliteTransmissionUpdates(int subId, in IIntegerConsumer resultCallback, + void stopSatelliteTransmissionUpdates(in IIntegerConsumer resultCallback, in ISatelliteTransmissionUpdateCallback callback); /** * Register the subscription with a satellite provider. * This is needed to register the subscription if the provider allows dynamic registration. * - * @param subId The subId of the subscription to be provisioned. * @param token The token to be used as a unique identifier for provisioning with satellite * gateway. * @provisionData Data from the provisioning app that can be used by provisioning server @@ -2851,7 +2840,7 @@ interface ITelephony { */ @JavaPassthrough(annotation="@android.annotation.RequiresPermission(" + "android.Manifest.permission.SATELLITE_COMMUNICATION)") - ICancellationSignal provisionSatelliteService(int subId, in String token, + ICancellationSignal provisionSatelliteService(in String token, in byte[] provisionData, in IIntegerConsumer callback); /** @@ -2861,110 +2850,99 @@ interface ITelephony { * {@link SatelliteCallback.SatelliteProvisionStateListener#onSatelliteProvisionStateChanged} * should report as deprovisioned. * - * @param subId The subId of the subscription to be deprovisioned. * @param token The token of the device/subscription to be deprovisioned. * @param callback The callback to get the result of the request. */ @JavaPassthrough(annotation="@android.annotation.RequiresPermission(" + "android.Manifest.permission.SATELLITE_COMMUNICATION)") - void deprovisionSatelliteService(int subId, in String token, in IIntegerConsumer callback); + void deprovisionSatelliteService(in String token, in IIntegerConsumer callback); /** * Registers for provision state changed from satellite modem. * - * @param subId The subId of the subscription to register for provision state changed. * @param callback The callback to handle the satellite provision state changed event. * * @return The {@link SatelliteError} result of the operation. */ @JavaPassthrough(annotation="@android.annotation.RequiresPermission(" + "android.Manifest.permission.SATELLITE_COMMUNICATION)") - int registerForSatelliteProvisionStateChanged(int subId, - in ISatelliteProvisionStateCallback callback); + int registerForSatelliteProvisionStateChanged(in ISatelliteProvisionStateCallback callback); /** * Unregisters for provision state changed from satellite modem. * If callback was not registered before, the request will be ignored. * - * @param subId The subId of the subscription to unregister for provision state changed. * @param callback The callback that was passed to registerForSatelliteProvisionStateChanged. */ @JavaPassthrough(annotation="@android.annotation.RequiresPermission(" + "android.Manifest.permission.SATELLITE_COMMUNICATION)") - void unregisterForSatelliteProvisionStateChanged(int subId, + void unregisterForSatelliteProvisionStateChanged( in ISatelliteProvisionStateCallback callback); /** * Request to get whether the device is provisioned with a satellite provider. * - * @param subId The subId of the subscription to get whether the device is provisioned for. * @param receiver Result receiver to get the error code of the request and whether the * device is provisioned with a satellite provider. */ @JavaPassthrough(annotation="@android.annotation.RequiresPermission(" + "android.Manifest.permission.SATELLITE_COMMUNICATION)") - void requestIsSatelliteProvisioned(int subId, in ResultReceiver receiver); + void requestIsSatelliteProvisioned(in ResultReceiver receiver); /** * Registers for modem state changed from satellite modem. * - * @param subId The subId of the subscription to register for satellite modem state changed. * @param callback The callback to handle the satellite modem state changed event. * * @return The {@link SatelliteError} result of the operation. */ @JavaPassthrough(annotation="@android.annotation.RequiresPermission(" + "android.Manifest.permission.SATELLITE_COMMUNICATION)") - int registerForSatelliteModemStateChanged(int subId, ISatelliteModemStateCallback callback); + int registerForSatelliteModemStateChanged(ISatelliteModemStateCallback callback); /** * Unregisters for modem state changed from satellite modem. * If callback was not registered before, the request will be ignored. * - * @param subId The subId of the subscription to unregister for satellite modem state changed. * @param callback The callback that was passed to registerForSatelliteStateChanged. */ @JavaPassthrough(annotation="@android.annotation.RequiresPermission(" + "android.Manifest.permission.SATELLITE_COMMUNICATION)") - void unregisterForModemStateChanged(int subId, ISatelliteModemStateCallback callback); + void unregisterForModemStateChanged(ISatelliteModemStateCallback callback); /** * Register to receive incoming datagrams over satellite. * - * @param subId The subId of the subscription to register for incoming satellite datagrams. * @param callback The callback to handle the incoming datagrams. * * @return The {@link SatelliteError} result of the operation. */ @JavaPassthrough(annotation="@android.annotation.RequiresPermission(" + "android.Manifest.permission.SATELLITE_COMMUNICATION)") - int registerForIncomingDatagram(int subId, ISatelliteDatagramCallback callback); + int registerForIncomingDatagram(ISatelliteDatagramCallback callback); /** * Unregister to stop receiving incoming datagrams over satellite. * If callback was not registered before, the request will be ignored. * - * @param subId The subId of the subscription to unregister for incoming satellite datagrams. * @param callback The callback that was passed to registerForIncomingDatagram. */ @JavaPassthrough(annotation="@android.annotation.RequiresPermission(" + "android.Manifest.permission.SATELLITE_COMMUNICATION)") - void unregisterForIncomingDatagram(int subId, ISatelliteDatagramCallback callback); + void unregisterForIncomingDatagram(ISatelliteDatagramCallback callback); /** * Poll pending satellite datagrams over satellite. * - * @param subId The subId of the subscription used for receiving datagrams. * @param callback The callback to get the result of the request. */ @JavaPassthrough(annotation="@android.annotation.RequiresPermission(" + "android.Manifest.permission.SATELLITE_COMMUNICATION)") - void pollPendingDatagrams(int subId, IIntegerConsumer callback); + void pollPendingDatagrams(IIntegerConsumer callback); /** * Send datagram over satellite. * - * @param subId The subId of the subscription to send satellite datagrams for. * @param datagramType Type of datagram. * @param datagram Datagram to send over satellite. * @param needFullScreenPointingUI this is used to indicate pointingUI app to open in @@ -2973,7 +2951,7 @@ interface ITelephony { */ @JavaPassthrough(annotation="@android.annotation.RequiresPermission(" + "android.Manifest.permission.SATELLITE_COMMUNICATION)") - void sendDatagram(int subId, int datagramType, in SatelliteDatagram datagram, + void sendDatagram(int datagramType, in SatelliteDatagram datagram, in boolean needFullScreenPointingUI, IIntegerConsumer callback); /** @@ -2991,13 +2969,12 @@ interface ITelephony { /** * Request to get the time after which the satellite will be visible. * - * @param subId The subId to get the time after which the satellite will be visible for. * @param receiver Result receiver to get the error code of the request and the requested * time after which the satellite will be visible. */ @JavaPassthrough(annotation="@android.annotation.RequiresPermission(" + "android.Manifest.permission.SATELLITE_COMMUNICATION)") - void requestTimeForNextSatelliteVisibility(int subId, in ResultReceiver receiver); + void requestTimeForNextSatelliteVisibility(in ResultReceiver receiver); /** * Inform whether the device is aligned with the satellite within in margin for demo mode. @@ -3007,7 +2984,7 @@ interface ITelephony { */ @JavaPassthrough(annotation="@android.annotation.RequiresPermission(" + "android.Manifest.permission.SATELLITE_COMMUNICATION)") - void setDeviceAlignedWithSatellite(int subId, boolean isAligned); + void setDeviceAlignedWithSatellite(boolean isAligned); /** * This API can be used by only CTS to update satellite vendor service package name. @@ -3163,20 +3140,18 @@ interface ITelephony { /** * Request to get the signal strength of the satellite connection. * - * @param subId The subId of the subscription to request for. * @param receiver Result receiver to get the error code of the request and the current signal * strength of the satellite connection. */ @JavaPassthrough(annotation="@android.annotation.RequiresPermission(" + "android.Manifest.permission.SATELLITE_COMMUNICATION)") - void requestNtnSignalStrength(int subId, in ResultReceiver receiver); + void requestNtnSignalStrength(in ResultReceiver receiver); /** * Registers for NTN signal strength changed from satellite modem. If the registration operation * is not successful, a {@link SatelliteException} that contains {@link SatelliteResult} will be * thrown. * - * @param subId The subId of the subscription to request for. * @param callback The callback to handle the NTN signal strength changed event. If the * operation is successful, {@link NtnSignalStrengthCallback#onNtnSignalStrengthChanged( * NtnSignalStrength)} will return an instance of {@link NtnSignalStrength} with a value of @@ -3185,30 +3160,27 @@ interface ITelephony { */ @JavaPassthrough(annotation="@android.annotation.RequiresPermission(" + "android.Manifest.permission.SATELLITE_COMMUNICATION)") - void registerForNtnSignalStrengthChanged(int subId, - in INtnSignalStrengthCallback callback); + void registerForNtnSignalStrengthChanged(in INtnSignalStrengthCallback callback); /** * Unregisters for NTN signal strength changed from satellite modem. * If callback was not registered before, the request will be ignored. * - * @param subId The subId of the subscription to unregister for provision state changed. * @param callback The callback that was passed to * {@link #registerForNtnSignalStrengthChanged(Executor, NtnSignalStrengthCallback)}. */ @JavaPassthrough(annotation="@android.annotation.RequiresPermission(" + "android.Manifest.permission.SATELLITE_COMMUNICATION)") - void unregisterForNtnSignalStrengthChanged(int subId, in INtnSignalStrengthCallback callback); + void unregisterForNtnSignalStrengthChanged(in INtnSignalStrengthCallback callback); /** * Registers for satellite capabilities change event from the satellite service. * - * @param executor The executor on which the callback will be called. * @param callback The callback to handle the satellite capabilities changed event. */ @JavaPassthrough(annotation="@android.annotation.RequiresPermission(" + "android.Manifest.permission.SATELLITE_COMMUNICATION)") - int registerForCapabilitiesChanged(int subId, in ISatelliteCapabilitiesCallback callback); + int registerForCapabilitiesChanged(in ISatelliteCapabilitiesCallback callback); /** * Unregisters for satellite capabilities change event from the satellite service. @@ -3219,8 +3191,7 @@ interface ITelephony { */ @JavaPassthrough(annotation="@android.annotation.RequiresPermission(" + "android.Manifest.permission.SATELLITE_COMMUNICATION)") - void unregisterForCapabilitiesChanged(int subId, - in ISatelliteCapabilitiesCallback callback); + void unregisterForCapabilitiesChanged(in ISatelliteCapabilitiesCallback callback); /** * This API can be used by only CTS to override the cached value for the device overlay config @@ -3329,26 +3300,24 @@ interface ITelephony { /** * Registers for supported state changed from satellite modem. * - * @param subId The subId of the subscription to register for supported state changed. * @param callback The callback to handle the satellite supported state changed event. * * @return The {@link SatelliteError} result of the operation. */ @JavaPassthrough(annotation="@android.annotation.RequiresPermission(" + "android.Manifest.permission.SATELLITE_COMMUNICATION)") - int registerForSatelliteSupportedStateChanged(int subId, + int registerForSatelliteSupportedStateChanged( in ISatelliteSupportedStateCallback callback); /** * Unregisters for supported state changed from satellite modem. * If callback was not registered before, the request will be ignored. * - * @param subId The subId of the subscription to unregister for supported state changed. * @param callback The callback that was passed to registerForSatelliteSupportedStateChanged. */ @JavaPassthrough(annotation="@android.annotation.RequiresPermission(" + "android.Manifest.permission.SATELLITE_COMMUNICATION)") - void unregisterForSatelliteSupportedStateChanged(int subId, + void unregisterForSatelliteSupportedStateChanged( in ISatelliteSupportedStateCallback callback); /** diff --git a/tools/hoststubgen/hoststubgen/invoketest/hoststubgen-invoke-test.sh b/tools/hoststubgen/hoststubgen/invoketest/hoststubgen-invoke-test.sh index d97dd7c18045..5c5421a9151a 100755 --- a/tools/hoststubgen/hoststubgen/invoketest/hoststubgen-invoke-test.sh +++ b/tools/hoststubgen/hoststubgen/invoketest/hoststubgen-invoke-test.sh @@ -213,9 +213,9 @@ com.unsupported.* " run_hoststubgen_for_failure "One specific class disallowed" \ - "TinyFrameworkClassAnnotations is not allowed to have Ravenwood annotations" \ + "TinyFrameworkAnnotations is not allowed to have Ravenwood annotations" \ " -!com.android.hoststubgen.test.tinyframework.TinyFrameworkClassAnnotations +!com.android.hoststubgen.test.tinyframework.TinyFrameworkAnnotations * # All other classes allowed " diff --git a/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/asm/AsmUtils.kt b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/asm/AsmUtils.kt index 6cf214300b43..7dd4fdd078a2 100644 --- a/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/asm/AsmUtils.kt +++ b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/asm/AsmUtils.kt @@ -202,18 +202,6 @@ fun isAnonymousInnerClass(cn: ClassNode): Boolean { } /** - * Take a class name. If it's a nested class, then return the name of its direct outer class name. - * Otherwise, return null. - */ -fun getDirectOuterClassName(className: String): String? { - val pos = className.lastIndexOf('$') - if (pos < 0) { - return null - } - return className.substring(0, pos) -} - -/** * Write bytecode to push all the method arguments to the stack. * The number of arguments and their type are taken from [methodDescriptor]. */ diff --git a/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/ClassWidePolicyPropagatingFilter.kt b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/ClassWidePolicyPropagatingFilter.kt index 47790b10782a..37048d9c7c60 100644 --- a/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/ClassWidePolicyPropagatingFilter.kt +++ b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/ClassWidePolicyPropagatingFilter.kt @@ -16,7 +16,6 @@ package com.android.hoststubgen.filters import com.android.hoststubgen.asm.ClassNodes -import com.android.hoststubgen.asm.getDirectOuterClassName /** * This is used as the second last fallback filter. This filter propagates the class-wide policy @@ -24,72 +23,69 @@ import com.android.hoststubgen.asm.getDirectOuterClassName */ class ClassWidePolicyPropagatingFilter( private val classes: ClassNodes, - fallback: OutputFilter, - ) : DelegatingFilter(fallback) { + fallback: OutputFilter +) : DelegatingFilter(fallback) { - private fun getClassWidePolicy(className: String, resolve: Boolean): FilterPolicyWithReason? { + /** + * We don't use ClassNode.outerClass, because it gives as the top-level + * outer class (A$B$C -> A), not the direct outer class (A$B$C -> A$B). + * + * Sometimes a class name includes `$`, but is not as a nested class name separator + * (e.g. a class name like `MyClass$$`). In this case, `MyClass$` is not actually a class. + * + * So before getting the class policy on a nonexistent class, which may cause an + * incorrect result, we make sure the class actually exists. + */ + private fun getDirectOuterClass(className: String): String? { var currentClass = className - - - // If the class name is `a.b.c.A$B$C`, then we try to get the class wide policy - // from a.b.c.A$B$C, then a.b.c.A$B, and then a.b.c.A. while (true) { - // Sometimes a class name has a `$` in it but not as a nest class name separator -- - // e.g. class name like "MyClass$$". In this case, `MyClass$` may not actually be - // a class name. - // So before getting the class policy on a nonexistent class, which may cause an - // incorrect result, we make sure if className actually exists. - if (classes.hasClass(className)) { - outermostFilter.getPolicyForClass(className).let { policy -> - if (policy.policy.isClassWidePolicy) { - val p = if (resolve) { - policy.policy.resolveClassWidePolicy() - } else { - policy.policy - } - - return p.withReason(policy.reason) - .wrapReason("class-wide in $currentClass") - } - // If the class's policy is remove, then remove it. - if (policy.policy == FilterPolicy.Remove) { - return FilterPolicy.Remove.withReason("class-wide in $currentClass") - } - } - } - - // Next, look at the outer class... - val outer = getDirectOuterClassName(currentClass) - if (outer == null) { + val pos = currentClass.lastIndexOf('$') + if (pos < 0) { return null } - currentClass = outer + currentClass = currentClass.substring(0, pos) + if (classes.hasClass(currentClass)) { + return currentClass + } } } - override fun getPolicyForClass(className: String): FilterPolicyWithReason { - // If it's a nested class, use the outer class's policy. - getDirectOuterClassName(className)?.let { outerName -> - getClassWidePolicy(outerName, resolve = false)?.let { policy -> - return policy + private fun getClassWidePolicy(className: String, resolve: Boolean): FilterPolicyWithReason? { + outermostFilter.getPolicyForClass(className).let { policy -> + if (policy.policy.isClassWidePolicy) { + val p = if (resolve) { + policy.policy.resolveClassWidePolicy() + } else { + policy.policy + } + + return p.withReason(policy.reason) + .wrapReason("class-wide in $className") + } + // If the class's policy is remove, then remove it. + if (policy.policy == FilterPolicy.Remove) { + return FilterPolicy.Remove.withReason("class-wide in $className") } } + return null + } - return super.getPolicyForClass(className) + override fun getPolicyForClass(className: String): FilterPolicyWithReason { + // If the class name is `a.b.c.A$B$C`, then we try to get the class wide policy + // from a.b.c.A$B$C, then a.b.c.A$B, and then a.b.c.A, recursively + return getDirectOuterClass(className)?.let { getClassWidePolicy(it, resolve = false) } + ?: super.getPolicyForClass(className) } - override fun getPolicyForField( - className: String, - fieldName: String - ): FilterPolicyWithReason { + override fun getPolicyForField(className: String, fieldName: String): FilterPolicyWithReason { return getClassWidePolicy(className, resolve = true) ?: super.getPolicyForField(className, fieldName) } override fun getPolicyForMethod( - className: String, - methodName: String, - descriptor: String + className: String, + methodName: String, + descriptor: String ): FilterPolicyWithReason { return getClassWidePolicy(className, resolve = true) ?: super.getPolicyForMethod(className, methodName, descriptor) diff --git a/tools/hoststubgen/hoststubgen/test-tiny-framework/annotation-allowed-classes-tiny-framework.txt b/tools/hoststubgen/hoststubgen/test-tiny-framework/annotation-allowed-classes-tiny-framework.txt index bd9e85e17890..de4cb0c536c1 100644 --- a/tools/hoststubgen/hoststubgen/test-tiny-framework/annotation-allowed-classes-tiny-framework.txt +++ b/tools/hoststubgen/hoststubgen/test-tiny-framework/annotation-allowed-classes-tiny-framework.txt @@ -6,10 +6,10 @@ # To allow a specific class to use annotations: -# com.android.hoststubgen.test.tinyframework.TinyFrameworkClassAnnotations +# com.android.hoststubgen.test.tinyframework.TinyFrameworkAnnotations # To disallow a specific class to use annotations: -# !com.android.hoststubgen.test.tinyframework.TinyFrameworkClassAnnotations +# !com.android.hoststubgen.test.tinyframework.TinyFrameworkAnnotations # To allow a specific package to use annotations: # com.android.hoststubgen.test.* diff --git a/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/01-hoststubgen-test-tiny-framework-orig-dump.txt b/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/01-hoststubgen-test-tiny-framework-orig-dump.txt index c2f593cf5ae3..845e1d08ce92 100644 --- a/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/01-hoststubgen-test-tiny-framework-orig-dump.txt +++ b/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/01-hoststubgen-test-tiny-framework-orig-dump.txt @@ -394,111 +394,13 @@ NestMembers: com/android/hoststubgen/test/tinyframework/R$Nested InnerClasses: public static #x= #x of #x; // Nested=class com/android/hoststubgen/test/tinyframework/R$Nested of class com/android/hoststubgen/test/tinyframework/R -## 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: 3, attributes: 3 - private com.android.hoststubgen.test.tinyframework.TinyFrameworkCallerCheck$Impl(); - descriptor: ()V - flags: (0x0002) ACC_PRIVATE - Code: - stack=1, locals=1, args_size=1 - x: aload_0 - x: invokespecial #x // Method java/lang/Object."<init>":()V - x: return - LineNumberTable: - LocalVariableTable: - Start Length Slot Name Signature - 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck$Impl; - - public static int getOneKeep(); - descriptor: ()I - flags: (0x0009) ACC_PUBLIC, ACC_STATIC - Code: - stack=1, locals=0, args_size=0 - 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=1, locals=0, args_size=0 - x: iconst_1 - x: ireturn - LineNumberTable: - RuntimeInvisibleAnnotations: - x: #x() - android.hosttest.annotation.HostSideTestStub -} -SourceFile: "TinyFrameworkCallerCheck.java" -NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck -InnerClasses: - private static #x= #x of #x; // Impl=class com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck$Impl of 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: 4 - public com.android.hoststubgen.test.tinyframework.TinyFrameworkCallerCheck(); - descriptor: ()V - flags: (0x0001) ACC_PUBLIC - Code: - stack=1, locals=1, args_size=1 - x: aload_0 - x: invokespecial #x // Method java/lang/Object."<init>":()V - x: return - LineNumberTable: - LocalVariableTable: - Start Length Slot Name Signature - 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck; - - public static int getOne_withCheck(); - descriptor: ()I - flags: (0x0009) ACC_PUBLIC, ACC_STATIC - Code: - stack=1, locals=0, args_size=0 - 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=1, locals=0, args_size=0 - x: invokestatic #x // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck$Impl.getOneStub:()I - x: ireturn - LineNumberTable: -} -SourceFile: "TinyFrameworkCallerCheck.java" -RuntimeInvisibleAnnotations: - x: #x() - android.hosttest.annotation.HostSideTestWholeClassStub -NestMembers: - com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck$Impl -InnerClasses: - private static #x= #x of #x; // Impl=class com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck$Impl of class com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck -## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkClassAnnotations.class - Compiled from "TinyFrameworkClassAnnotations.java" -public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassAnnotations +## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkAnnotations.class + Compiled from "TinyFrameworkAnnotations.java" +public class com.android.hoststubgen.test.tinyframework.TinyFrameworkAnnotations minor version: 0 major version: 61 flags: (0x0021) ACC_PUBLIC, ACC_SUPER - this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkClassAnnotations + this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkAnnotations super_class: #x // java/lang/Object interfaces: 0, fields: 3, methods: 10, attributes: 2 public int stub; @@ -519,7 +421,7 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassAnnota descriptor: I flags: (0x0001) ACC_PUBLIC - public com.android.hoststubgen.test.tinyframework.TinyFrameworkClassAnnotations(); + public com.android.hoststubgen.test.tinyframework.TinyFrameworkAnnotations(); descriptor: ()V flags: (0x0001) ACC_PUBLIC Code: @@ -536,7 +438,7 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassAnnota LineNumberTable: LocalVariableTable: Start Length Slot Name Signature - 0 15 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassAnnotations; + 0 15 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkAnnotations; RuntimeInvisibleAnnotations: x: #x() android.hosttest.annotation.HostSideTestStub @@ -553,7 +455,7 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassAnnota LineNumberTable: LocalVariableTable: Start Length Slot Name Signature - 0 6 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassAnnotations; + 0 6 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkAnnotations; 0 6 1 value I RuntimeInvisibleAnnotations: x: #x() @@ -571,7 +473,7 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassAnnota LineNumberTable: LocalVariableTable: Start Length Slot Name Signature - 0 4 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassAnnotations; + 0 4 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkAnnotations; 0 4 1 value I RuntimeInvisibleAnnotations: x: #x() @@ -589,7 +491,7 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassAnnota LineNumberTable: LocalVariableTable: Start Length Slot Name Signature - 0 8 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassAnnotations; + 0 8 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkAnnotations; 0 8 1 foo Ljava/lang/String; RuntimeInvisibleAnnotations: x: #x() @@ -608,7 +510,7 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassAnnota LineNumberTable: LocalVariableTable: Start Length Slot Name Signature - 0 10 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassAnnotations; + 0 10 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkAnnotations; 0 10 1 value I RuntimeInvisibleAnnotations: x: #x() @@ -630,7 +532,7 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassAnnota LineNumberTable: LocalVariableTable: Start Length Slot Name Signature - 0 4 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassAnnotations; + 0 4 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkAnnotations; 0 4 1 value I public static native int nativeAddThree(int); @@ -668,7 +570,7 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassAnnota LineNumberTable: LocalVariableTable: Start Length Slot Name Signature - 0 3 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassAnnotations; + 0 3 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkAnnotations; RuntimeInvisibleAnnotations: x: #x() android.hosttest.annotation.HostSideTestThrow @@ -684,12 +586,12 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassAnnota LineNumberTable: LocalVariableTable: Start Length Slot Name Signature - 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassAnnotations; + 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkAnnotations; RuntimeInvisibleAnnotations: x: #x() android.hosttest.annotation.HostSideTestStub } -SourceFile: "TinyFrameworkClassAnnotations.java" +SourceFile: "TinyFrameworkAnnotations.java" RuntimeInvisibleAnnotations: x: #x() android.hosttest.annotation.HostSideTestStub @@ -697,183 +599,104 @@ RuntimeInvisibleAnnotations: 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 +## 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: (0x0021) ACC_PUBLIC, ACC_SUPER - this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkClassClassWideAnnotations + flags: (0x0020) ACC_SUPER + this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck$Impl super_class: #x // java/lang/Object - interfaces: 0, fields: 3, methods: 10, attributes: 2 - 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(); + interfaces: 0, fields: 0, methods: 3, attributes: 3 + private com.android.hoststubgen.test.tinyframework.TinyFrameworkCallerCheck$Impl(); descriptor: ()V - flags: (0x0001) ACC_PUBLIC + flags: (0x0002) ACC_PRIVATE Code: - stack=2, locals=1, args_size=1 + stack=1, locals=1, args_size=1 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 + x: return LineNumberTable: LocalVariableTable: Start Length Slot Name Signature - 0 15 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassClassWideAnnotations; + 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck$Impl; - public int addOne(int); - descriptor: (I)I - flags: (0x0001) ACC_PUBLIC + public static int getOneKeep(); + descriptor: ()I + flags: (0x0009) ACC_PUBLIC, ACC_STATIC Code: - stack=2, locals=2, args_size=2 - x: aload_0 - x: iload_1 - x: invokevirtual #x // Method addOneInner:(I)I + stack=1, locals=0, args_size=0 + x: iconst_1 x: ireturn LineNumberTable: - LocalVariableTable: - Start Length Slot Name Signature - 0 6 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassClassWideAnnotations; - 0 6 1 value I + RuntimeInvisibleAnnotations: + x: #x() + android.hosttest.annotation.HostSideTestKeep - public int addOneInner(int); - descriptor: (I)I - flags: (0x0001) ACC_PUBLIC + public static int getOneStub(); + descriptor: ()I + flags: (0x0009) ACC_PUBLIC, ACC_STATIC Code: - stack=2, locals=2, args_size=2 - x: iload_1 + stack=1, locals=0, args_size=0 x: iconst_1 - x: iadd x: ireturn LineNumberTable: - LocalVariableTable: - Start Length Slot Name Signature - 0 4 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassClassWideAnnotations; - 0 4 1 value I - - public void toBeRemoved(java.lang.String); - descriptor: (Ljava/lang/String;)V - flags: (0x0001) ACC_PUBLIC - Code: - stack=2, locals=2, args_size=2 - 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 - 0 8 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassClassWideAnnotations; - 0 8 1 foo Ljava/lang/String; - - 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 not supported on host side - x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V - x: athrow - LineNumberTable: - LocalVariableTable: - Start Length Slot Name Signature - 0 10 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassClassWideAnnotations; - 0 10 1 value I RuntimeInvisibleAnnotations: x: #x() android.hosttest.annotation.HostSideTestStub - x: #x(#x=s#x) - android.hosttest.annotation.HostSideTestSubstitute( - suffix="_host" - ) - - public int addTwo_host(int); - descriptor: (I)I +} +SourceFile: "TinyFrameworkCallerCheck.java" +NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck +InnerClasses: + private static #x= #x of #x; // Impl=class com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck$Impl of 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: 4 + public com.android.hoststubgen.test.tinyframework.TinyFrameworkCallerCheck(); + descriptor: ()V flags: (0x0001) ACC_PUBLIC Code: - stack=2, locals=2, args_size=2 - x: iload_1 - x: iconst_2 - x: iadd - x: ireturn + stack=1, locals=1, args_size=1 + x: aload_0 + x: invokespecial #x // Method java/lang/Object."<init>":()V + x: return LineNumberTable: LocalVariableTable: Start Length Slot Name Signature - 0 4 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassClassWideAnnotations; - 0 4 1 value I - - public static native int nativeAddThree(int); - descriptor: (I)I - flags: (0x0109) ACC_PUBLIC, ACC_STATIC, ACC_NATIVE - RuntimeInvisibleAnnotations: - x: #x() - android.hosttest.annotation.HostSideTestStub - x: #x(#x=s#x) - android.hosttest.annotation.HostSideTestSubstitute( - suffix="_host" - ) + 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck; - public static int nativeAddThree_host(int); - descriptor: (I)I + public static int getOne_withCheck(); + descriptor: ()I flags: (0x0009) ACC_PUBLIC, ACC_STATIC Code: - stack=2, locals=1, args_size=1 - x: iload_0 - x: iconst_3 - x: iadd + stack=1, locals=0, args_size=0 + x: invokestatic #x // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck$Impl.getOneKeep:()I x: ireturn LineNumberTable: - LocalVariableTable: - Start Length Slot Name Signature - 0 4 0 value I - - public java.lang.String unsupportedMethod(); - descriptor: ()Ljava/lang/String; - flags: (0x0001) ACC_PUBLIC - Code: - stack=1, locals=1, args_size=1 - x: ldc #x // String This value shouldn\'t be seen on the host side. - x: areturn - LineNumberTable: - LocalVariableTable: - Start Length Slot Name Signature - 0 3 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassClassWideAnnotations; - public java.lang.String visibleButUsesUnsupportedMethod(); - descriptor: ()Ljava/lang/String; - flags: (0x0001) ACC_PUBLIC + public static int getOne_noCheck(); + descriptor: ()I + flags: (0x0009) ACC_PUBLIC, ACC_STATIC Code: - stack=1, locals=1, args_size=1 - x: aload_0 - x: invokevirtual #x // Method unsupportedMethod:()Ljava/lang/String; - x: areturn + stack=1, locals=0, args_size=0 + x: invokestatic #x // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck$Impl.getOneStub:()I + x: ireturn LineNumberTable: - LocalVariableTable: - Start Length Slot Name Signature - 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassClassWideAnnotations; } -SourceFile: "TinyFrameworkClassClassWideAnnotations.java" +SourceFile: "TinyFrameworkCallerCheck.java" RuntimeInvisibleAnnotations: x: #x() android.hosttest.annotation.HostSideTestWholeClassStub +NestMembers: + com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck$Impl +InnerClasses: + private static #x= #x of #x; // Impl=class com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck$Impl of class com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck ## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkClassLoadHook.class Compiled from "TinyFrameworkClassLoadHook.java" public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassLoadHook @@ -936,6 +759,118 @@ SourceFile: "TinyFrameworkClassLoadHook.java" RuntimeInvisibleAnnotations: x: #x() android.hosttest.annotation.HostSideTestWholeClassStub +## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWideAnnotations.class + Compiled from "TinyFrameworkClassWideAnnotations.java" +public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassWideAnnotations + minor version: 0 + major version: 61 + flags: (0x0021) ACC_PUBLIC, ACC_SUPER + this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWideAnnotations + super_class: #x // java/lang/Object + interfaces: 0, fields: 1, methods: 6, attributes: 2 + public int stub; + descriptor: I + flags: (0x0001) ACC_PUBLIC + + public com.android.hoststubgen.test.tinyframework.TinyFrameworkClassWideAnnotations(); + descriptor: ()V + flags: (0x0001) ACC_PUBLIC + Code: + stack=2, locals=1, args_size=1 + 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: return + LineNumberTable: + LocalVariableTable: + Start Length Slot Name Signature + 0 10 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassWideAnnotations; + + public int addOne(int); + descriptor: (I)I + flags: (0x0001) ACC_PUBLIC + Code: + stack=2, locals=2, args_size=2 + x: iload_1 + x: iconst_1 + x: iadd + x: ireturn + LineNumberTable: + LocalVariableTable: + Start Length Slot Name Signature + 0 4 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassWideAnnotations; + 0 4 1 value I + + 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 not supported on host side + x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V + x: athrow + LineNumberTable: + LocalVariableTable: + Start Length Slot Name Signature + 0 10 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassWideAnnotations; + 0 10 1 value I + RuntimeInvisibleAnnotations: + x: #x(#x=s#x) + android.hosttest.annotation.HostSideTestSubstitute( + suffix="_host" + ) + + public int addTwo_host(int); + descriptor: (I)I + flags: (0x0001) ACC_PUBLIC + Code: + stack=2, locals=2, args_size=2 + x: iload_1 + x: iconst_2 + x: iadd + x: ireturn + LineNumberTable: + LocalVariableTable: + Start Length Slot Name Signature + 0 4 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassWideAnnotations; + 0 4 1 value I + + public java.lang.String unsupportedMethod(); + descriptor: ()Ljava/lang/String; + flags: (0x0001) ACC_PUBLIC + Code: + stack=1, locals=1, args_size=1 + x: ldc #x // String This value shouldn\'t be seen on the host side. + x: areturn + LineNumberTable: + LocalVariableTable: + Start Length Slot Name Signature + 0 3 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassWideAnnotations; + RuntimeInvisibleAnnotations: + x: #x() + android.hosttest.annotation.HostSideTestThrow + + public java.lang.String visibleButUsesUnsupportedMethod(); + descriptor: ()Ljava/lang/String; + flags: (0x0001) ACC_PUBLIC + Code: + stack=1, locals=1, args_size=1 + x: aload_0 + x: invokevirtual #x // Method unsupportedMethod:()Ljava/lang/String; + x: areturn + LineNumberTable: + LocalVariableTable: + Start Length Slot Name Signature + 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassWideAnnotations; +} +SourceFile: "TinyFrameworkClassWideAnnotations.java" +RuntimeInvisibleAnnotations: + x: #x() + android.hosttest.annotation.HostSideTestWholeClassStub ## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWithInitializerDefault.class Compiled from "TinyFrameworkClassWithInitializerDefault.java" public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassWithInitializerDefault @@ -2684,7 +2619,7 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClass 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: 4 + interfaces: 0, fields: 2, methods: 1, attributes: 3 public int value; descriptor: I flags: (0x0001) ACC_PUBLIC @@ -2717,9 +2652,6 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClass <no name> final mandated } SourceFile: "TinyFrameworkNestedClasses.java" -RuntimeInvisibleAnnotations: - x: #x() - android.hosttest.annotation.HostSideTestWholeClassStub NestHost: class com/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 @@ -2778,6 +2710,40 @@ NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedCl 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 +## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$Double$NestedClass.class + Compiled from "TinyFrameworkNestedClasses.java" +public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$StaticNestedClass$Double$NestedClass + minor version: 0 + major version: 61 + flags: (0x0021) ACC_PUBLIC, ACC_SUPER + this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$Double$NestedClass + super_class: #x // java/lang/Object + interfaces: 0, fields: 1, methods: 1, attributes: 3 + public int value; + descriptor: I + flags: (0x0001) ACC_PUBLIC + + public com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$StaticNestedClass$Double$NestedClass(); + descriptor: ()V + flags: (0x0001) ACC_PUBLIC + Code: + stack=2, locals=1, args_size=1 + x: aload_0 + x: invokespecial #x // Method java/lang/Object."<init>":()V + x: aload_0 + x: bipush 8 + x: putfield #x // Field value:I + x: return + LineNumberTable: + LocalVariableTable: + Start Length Slot Name Signature + 0 11 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$Double$NestedClass; +} +SourceFile: "TinyFrameworkNestedClasses.java" +NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses +InnerClasses: + public static #x= #x of #x; // StaticNestedClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses + public static #x= #x of #x; // Double$NestedClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$Double$NestedClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass ## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass.class Compiled from "TinyFrameworkNestedClasses.java" public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$StaticNestedClass @@ -2786,7 +2752,7 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClass 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: 4 + interfaces: 0, fields: 1, methods: 2, attributes: 3 public int value; descriptor: I flags: (0x0001) ACC_PUBLIC @@ -2820,13 +2786,11 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClass Signature: #x // ()Ljava/util/function/Supplier<Ljava/lang/Integer;>; } SourceFile: "TinyFrameworkNestedClasses.java" -RuntimeInvisibleAnnotations: - x: #x() - android.hosttest.annotation.HostSideTestWholeClassStub NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses 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 + public static #x= #x of #x; // Double$NestedClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$Double$NestedClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass ## 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 @@ -2942,6 +2906,7 @@ 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$Double$NestedClass com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1 com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$InnerClass com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4 @@ -2957,6 +2922,7 @@ 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; // 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 + public static #x= #x of #x; // Double$NestedClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$Double$NestedClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass #x; // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1 ## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkPackageRedirect.class Compiled from "TinyFrameworkPackageRedirect.java" diff --git a/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/02-hoststubgen-test-tiny-framework-host-stub-dump.txt b/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/02-hoststubgen-test-tiny-framework-host-stub-dump.txt index 1b83d244c55c..86a9c65f59b4 100644 --- a/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/02-hoststubgen-test-tiny-framework-host-stub-dump.txt +++ b/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/02-hoststubgen-test-tiny-framework-host-stub-dump.txt @@ -216,136 +216,13 @@ RuntimeVisibleAnnotations: com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl NestMembers: com/android/hoststubgen/test/tinyframework/R$Nested -## 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 - RuntimeVisibleAnnotations: - x: #x() - com.android.hoststubgen.hosthelper.HostStubGenKeptInStub - x: #x() - com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl - - 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 - RuntimeVisibleAnnotations: - x: #x() - com.android.hoststubgen.hosthelper.HostStubGenKeptInStub - x: #x() - com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl - 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.HostStubGenKeptInStub - x: #x() - com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl -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 +## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkAnnotations.class + Compiled from "TinyFrameworkAnnotations.java" +public class com.android.hoststubgen.test.tinyframework.TinyFrameworkAnnotations 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 - RuntimeVisibleAnnotations: - x: #x() - com.android.hoststubgen.hosthelper.HostStubGenKeptInStub - x: #x() - com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl - - 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 - RuntimeVisibleAnnotations: - x: #x() - com.android.hoststubgen.hosthelper.HostStubGenKeptInStub - x: #x() - com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl - - 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 - RuntimeVisibleAnnotations: - x: #x() - com.android.hoststubgen.hosthelper.HostStubGenKeptInStub - x: #x() - com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl -} -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.HostStubGenKeptInStub - x: #x() - com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl -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 + this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkAnnotations super_class: #x // java/lang/Object interfaces: 0, fields: 1, methods: 5, attributes: 3 public int stub; @@ -360,7 +237,7 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassAnnota x: #x() android.hosttest.annotation.HostSideTestStub - public com.android.hoststubgen.test.tinyframework.TinyFrameworkClassAnnotations(); + public com.android.hoststubgen.test.tinyframework.TinyFrameworkAnnotations(); descriptor: ()V flags: (0x0001) ACC_PUBLIC Code: @@ -449,7 +326,7 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassAnnota x: #x() android.hosttest.annotation.HostSideTestStub } -SourceFile: "TinyFrameworkClassAnnotations.java" +SourceFile: "TinyFrameworkAnnotations.java" RuntimeVisibleAnnotations: x: #x() com.android.hoststubgen.hosthelper.HostStubGenKeptInStub @@ -462,45 +339,18 @@ RuntimeInvisibleAnnotations: 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 +## 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: (0x0021) ACC_PUBLIC, ACC_SUPER - this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkClassClassWideAnnotations + flags: (0x0020) ACC_SUPER + this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck$Impl super_class: #x // java/lang/Object - interfaces: 0, fields: 3, methods: 8, attributes: 3 - public int stub; - descriptor: I - flags: (0x0001) ACC_PUBLIC - RuntimeVisibleAnnotations: - x: #x() - com.android.hoststubgen.hosthelper.HostStubGenKeptInStub - x: #x() - com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl - - public int keep; - descriptor: I - flags: (0x0001) ACC_PUBLIC - RuntimeVisibleAnnotations: - x: #x() - com.android.hoststubgen.hosthelper.HostStubGenKeptInStub - x: #x() - com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl - - public int remove; - descriptor: I - flags: (0x0001) ACC_PUBLIC - RuntimeVisibleAnnotations: - x: #x() - com.android.hoststubgen.hosthelper.HostStubGenKeptInStub - x: #x() - com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl - - public com.android.hoststubgen.test.tinyframework.TinyFrameworkClassClassWideAnnotations(); + interfaces: 0, fields: 0, methods: 2, attributes: 4 + private com.android.hoststubgen.test.tinyframework.TinyFrameworkCallerCheck$Impl(); descriptor: ()V - flags: (0x0001) ACC_PUBLIC + flags: (0x0002) ACC_PRIVATE Code: stack=3, locals=1, args_size=1 x: new #x // class java/lang/RuntimeException @@ -514,11 +364,11 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassClassW x: #x() com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl - public int addOne(int); - descriptor: (I)I - flags: (0x0001) ACC_PUBLIC + public static int getOneStub(); + descriptor: ()I + flags: (0x0009) ACC_PUBLIC, ACC_STATIC Code: - stack=3, locals=2, args_size=2 + stack=3, locals=0, args_size=0 x: new #x // class java/lang/RuntimeException x: dup x: ldc #x // String Stub! @@ -529,12 +379,33 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassClassW com.android.hoststubgen.hosthelper.HostStubGenKeptInStub x: #x() com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl - - public int addOneInner(int); - descriptor: (I)I + 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.HostStubGenKeptInStub + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl +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=2, args_size=2 + stack=3, locals=1, args_size=1 x: new #x // class java/lang/RuntimeException x: dup x: ldc #x // String Stub! @@ -546,11 +417,11 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassClassW x: #x() com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl - public void toBeRemoved(java.lang.String); - descriptor: (Ljava/lang/String;)V - flags: (0x0001) ACC_PUBLIC + public static int getOne_withCheck(); + descriptor: ()I + flags: (0x0009) ACC_PUBLIC, ACC_STATIC Code: - stack=3, locals=2, args_size=2 + stack=3, locals=0, args_size=0 x: new #x // class java/lang/RuntimeException x: dup x: ldc #x // String Stub! @@ -562,11 +433,11 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassClassW x: #x() com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl - public int addTwo(int); - descriptor: (I)I - flags: (0x0001) ACC_PUBLIC + public static int getOne_noCheck(); + descriptor: ()I + flags: (0x0009) ACC_PUBLIC, ACC_STATIC Code: - stack=3, locals=2, args_size=2 + stack=3, locals=0, args_size=0 x: new #x // class java/lang/RuntimeException x: dup x: ldc #x // String Stub! @@ -577,10 +448,42 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassClassW com.android.hoststubgen.hosthelper.HostStubGenKeptInStub x: #x() com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl +} +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.HostStubGenKeptInStub + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl +RuntimeInvisibleAnnotations: + x: #x() + android.hosttest.annotation.HostSideTestWholeClassStub +NestMembers: + com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck$Impl +## 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<*>;>; + RuntimeVisibleAnnotations: + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInStub + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl - public static int nativeAddThree(int); - descriptor: (I)I - flags: (0x0009) ACC_PUBLIC, ACC_STATIC + 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 @@ -594,9 +497,9 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassClassW x: #x() com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl - public java.lang.String unsupportedMethod(); - descriptor: ()Ljava/lang/String; - flags: (0x0001) ACC_PUBLIC + 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 @@ -604,17 +507,18 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassClassW 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 RuntimeVisibleAnnotations: x: #x() com.android.hoststubgen.hosthelper.HostStubGenKeptInStub x: #x() com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl - public java.lang.String visibleButUsesUnsupportedMethod(); - descriptor: ()Ljava/lang/String; - flags: (0x0001) ACC_PUBLIC + static {}; + descriptor: ()V + flags: (0x0008) ACC_STATIC Code: - stack=3, locals=1, args_size=1 + stack=3, locals=0, args_size=0 x: new #x // class java/lang/RuntimeException x: dup x: ldc #x // String Stub! @@ -626,7 +530,7 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassClassW x: #x() com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl } -SourceFile: "TinyFrameworkClassClassWideAnnotations.java" +SourceFile: "TinyFrameworkClassLoadHook.java" RuntimeVisibleAnnotations: x: #x() com.android.hoststubgen.hosthelper.HostStubGenKeptInStub @@ -635,28 +539,27 @@ RuntimeVisibleAnnotations: 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 +## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWideAnnotations.class + Compiled from "TinyFrameworkClassWideAnnotations.java" +public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassWideAnnotations minor version: 0 major version: 61 flags: (0x0021) ACC_PUBLIC, ACC_SUPER - this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkClassLoadHook + this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWideAnnotations 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<*>;>; + interfaces: 0, fields: 1, methods: 4, attributes: 3 + public int stub; + descriptor: I + flags: (0x0001) ACC_PUBLIC RuntimeVisibleAnnotations: x: #x() com.android.hoststubgen.hosthelper.HostStubGenKeptInStub x: #x() com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl - private com.android.hoststubgen.test.tinyframework.TinyFrameworkClassLoadHook(); + public com.android.hoststubgen.test.tinyframework.TinyFrameworkClassWideAnnotations(); descriptor: ()V - flags: (0x0002) ACC_PRIVATE + flags: (0x0001) ACC_PUBLIC Code: stack=3, locals=1, args_size=1 x: new #x // class java/lang/RuntimeException @@ -670,28 +573,43 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassLoadHo x: #x() com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl - public static void onClassLoaded(java.lang.Class<?>); - descriptor: (Ljava/lang/Class;)V - flags: (0x0009) ACC_PUBLIC, ACC_STATIC + public int addOne(int); + descriptor: (I)I + flags: (0x0001) ACC_PUBLIC Code: - stack=3, locals=1, args_size=1 + 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 - Signature: #x // (Ljava/lang/Class<*>;)V RuntimeVisibleAnnotations: x: #x() com.android.hoststubgen.hosthelper.HostStubGenKeptInStub x: #x() com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl - static {}; - descriptor: ()V - flags: (0x0008) ACC_STATIC + public int addTwo(int); + descriptor: (I)I + flags: (0x0001) ACC_PUBLIC Code: - stack=3, locals=0, args_size=0 + 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 + RuntimeVisibleAnnotations: + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInStub + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl + + 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! @@ -703,7 +621,7 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassLoadHo x: #x() com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl } -SourceFile: "TinyFrameworkClassLoadHook.java" +SourceFile: "TinyFrameworkClassWideAnnotations.java" RuntimeVisibleAnnotations: x: #x() com.android.hoststubgen.hosthelper.HostStubGenKeptInStub @@ -2153,7 +2071,7 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClass 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 + interfaces: 0, fields: 2, methods: 1, attributes: 4 public int value; descriptor: I flags: (0x0001) ACC_PUBLIC @@ -2199,9 +2117,50 @@ RuntimeVisibleAnnotations: com.android.hoststubgen.hosthelper.HostStubGenKeptInStub x: #x() com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl -RuntimeInvisibleAnnotations: +NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses +## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$Double$NestedClass.class + Compiled from "TinyFrameworkNestedClasses.java" +public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$StaticNestedClass$Double$NestedClass + minor version: 0 + major version: 61 + flags: (0x0021) ACC_PUBLIC, ACC_SUPER + this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$Double$NestedClass + super_class: #x // java/lang/Object + interfaces: 0, fields: 1, methods: 1, attributes: 4 + public int value; + descriptor: I + flags: (0x0001) ACC_PUBLIC + RuntimeVisibleAnnotations: + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInStub + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl + + public com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$StaticNestedClass$Double$NestedClass(); + 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 + RuntimeVisibleAnnotations: + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInStub + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl +} +InnerClasses: + public static #x= #x of #x; // StaticNestedClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses + public static #x= #x of #x; // Double$NestedClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$Double$NestedClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass +SourceFile: "TinyFrameworkNestedClasses.java" +RuntimeVisibleAnnotations: x: #x() - android.hosttest.annotation.HostSideTestWholeClassStub + com.android.hoststubgen.hosthelper.HostStubGenKeptInStub + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses ## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass.class Compiled from "TinyFrameworkNestedClasses.java" @@ -2211,7 +2170,7 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClass 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 + interfaces: 0, fields: 1, methods: 2, attributes: 4 public int value; descriptor: I flags: (0x0001) ACC_PUBLIC @@ -2257,15 +2216,13 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClass 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 + public static #x= #x of #x; // Double$NestedClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$Double$NestedClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass SourceFile: "TinyFrameworkNestedClasses.java" RuntimeVisibleAnnotations: x: #x() com.android.hoststubgen.hosthelper.HostStubGenKeptInStub x: #x() com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl -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" @@ -2406,6 +2363,7 @@ 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; // 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 + public static #x= #x of #x; // Double$NestedClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$Double$NestedClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass #x; // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1 SourceFile: "TinyFrameworkNestedClasses.java" RuntimeVisibleAnnotations: @@ -2420,6 +2378,7 @@ 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$Double$NestedClass com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1 com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$InnerClass com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4 diff --git a/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/03-hoststubgen-test-tiny-framework-host-impl-dump.txt b/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/03-hoststubgen-test-tiny-framework-host-impl-dump.txt index d23b450c4076..c6b9c7a9e4f1 100644 --- a/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/03-hoststubgen-test-tiny-framework-host-impl-dump.txt +++ b/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/03-hoststubgen-test-tiny-framework-host-impl-dump.txt @@ -450,155 +450,13 @@ RuntimeVisibleAnnotations: com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl NestMembers: com/android/hoststubgen/test/tinyframework/R$Nested -## 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: 3, attributes: 4 - private com.android.hoststubgen.test.tinyframework.TinyFrameworkCallerCheck$Impl(); - descriptor: ()V - flags: (0x0002) ACC_PRIVATE - Code: - stack=1, locals=1, args_size=1 - x: aload_0 - x: invokespecial #x // Method java/lang/Object."<init>":()V - x: return - LineNumberTable: - LocalVariableTable: - Start Length Slot Name Signature - 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck$Impl; - RuntimeVisibleAnnotations: - x: #x() - com.android.hoststubgen.hosthelper.HostStubGenKeptInStub - x: #x() - com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl - - public static int getOneKeep(); - descriptor: ()I - flags: (0x0009) ACC_PUBLIC, ACC_STATIC - Code: - stack=4, locals=0, args_size=0 - 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: - RuntimeVisibleAnnotations: - x: #x() - com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl - RuntimeInvisibleAnnotations: - x: #x() - android.hosttest.annotation.HostSideTestKeep - - public static int getOneStub(); - descriptor: ()I - flags: (0x0009) ACC_PUBLIC, ACC_STATIC - Code: - stack=1, locals=0, args_size=0 - x: iconst_1 - x: ireturn - LineNumberTable: - RuntimeVisibleAnnotations: - x: #x() - com.android.hoststubgen.hosthelper.HostStubGenKeptInStub - x: #x() - com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl - 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.HostStubGenKeptInStub - x: #x() - com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl -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 +## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkAnnotations.class + Compiled from "TinyFrameworkAnnotations.java" +public class com.android.hoststubgen.test.tinyframework.TinyFrameworkAnnotations 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=1, locals=1, args_size=1 - x: aload_0 - x: invokespecial #x // Method java/lang/Object."<init>":()V - x: return - LineNumberTable: - LocalVariableTable: - Start Length Slot Name Signature - 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck; - RuntimeVisibleAnnotations: - x: #x() - com.android.hoststubgen.hosthelper.HostStubGenKeptInStub - x: #x() - com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl - - public static int getOne_withCheck(); - descriptor: ()I - flags: (0x0009) ACC_PUBLIC, ACC_STATIC - Code: - stack=1, locals=0, args_size=0 - x: invokestatic #x // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck$Impl.getOneKeep:()I - x: ireturn - LineNumberTable: - RuntimeVisibleAnnotations: - x: #x() - com.android.hoststubgen.hosthelper.HostStubGenKeptInStub - x: #x() - com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl - - public static int getOne_noCheck(); - descriptor: ()I - flags: (0x0009) ACC_PUBLIC, ACC_STATIC - Code: - stack=1, locals=0, args_size=0 - x: invokestatic #x // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck$Impl.getOneStub:()I - x: ireturn - LineNumberTable: - RuntimeVisibleAnnotations: - x: #x() - com.android.hoststubgen.hosthelper.HostStubGenKeptInStub - x: #x() - com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl -} -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.HostStubGenKeptInStub - x: #x() - com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl -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 + this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkAnnotations super_class: #x // java/lang/Object interfaces: 0, fields: 2, methods: 8, attributes: 3 public int stub; @@ -628,12 +486,12 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassAnnota 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 // class com/android/hoststubgen/test/tinyframework/TinyFrameworkAnnotations 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(); + public com.android.hoststubgen.test.tinyframework.TinyFrameworkAnnotations(); descriptor: ()V flags: (0x0001) ACC_PUBLIC Code: @@ -650,7 +508,7 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassAnnota LineNumberTable: LocalVariableTable: Start Length Slot Name Signature - 0 15 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassAnnotations; + 0 15 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkAnnotations; RuntimeVisibleAnnotations: x: #x() com.android.hoststubgen.hosthelper.HostStubGenKeptInStub @@ -672,7 +530,7 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassAnnota LineNumberTable: LocalVariableTable: Start Length Slot Name Signature - 0 6 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassAnnotations; + 0 6 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkAnnotations; 0 6 1 value I RuntimeVisibleAnnotations: x: #x() @@ -688,7 +546,7 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassAnnota flags: (0x0001) ACC_PUBLIC Code: stack=4, locals=2, args_size=2 - x: ldc #x // String com/android/hoststubgen/test/tinyframework/TinyFrameworkClassAnnotations + x: ldc #x // String com/android/hoststubgen/test/tinyframework/TinyFrameworkAnnotations x: ldc #x // String addOneInner x: ldc #x // String (I)I x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.getStackWalker:()Ljava/lang/StackWalker; @@ -701,7 +559,7 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassAnnota LineNumberTable: LocalVariableTable: Start Length Slot Name Signature - 15 4 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassAnnotations; + 15 4 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkAnnotations; 15 4 1 value I RuntimeVisibleAnnotations: x: #x() @@ -722,7 +580,7 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassAnnota LineNumberTable: LocalVariableTable: Start Length Slot Name Signature - 0 4 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassAnnotations; + 0 4 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkAnnotations; 0 4 1 value I RuntimeVisibleAnnotations: x: #x() @@ -758,7 +616,7 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassAnnota flags: (0x0001) ACC_PUBLIC Code: stack=4, locals=1, args_size=1 - x: ldc #x // String com/android/hoststubgen/test/tinyframework/TinyFrameworkClassAnnotations + x: ldc #x // String com/android/hoststubgen/test/tinyframework/TinyFrameworkAnnotations 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; @@ -790,7 +648,7 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassAnnota LineNumberTable: LocalVariableTable: Start Length Slot Name Signature - 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassAnnotations; + 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkAnnotations; RuntimeVisibleAnnotations: x: #x() com.android.hoststubgen.hosthelper.HostStubGenKeptInStub @@ -800,7 +658,7 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassAnnota x: #x() android.hosttest.annotation.HostSideTestStub } -SourceFile: "TinyFrameworkClassAnnotations.java" +SourceFile: "TinyFrameworkAnnotations.java" RuntimeVisibleAnnotations: x: #x() com.android.hoststubgen.hosthelper.HostStubGenKeptInStub @@ -813,205 +671,138 @@ RuntimeInvisibleAnnotations: 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 +## 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: (0x0021) ACC_PUBLIC, ACC_SUPER - this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkClassClassWideAnnotations + flags: (0x0020) ACC_SUPER + this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck$Impl super_class: #x // java/lang/Object - interfaces: 0, fields: 3, methods: 8, attributes: 3 - public int stub; - descriptor: I - flags: (0x0001) ACC_PUBLIC - RuntimeVisibleAnnotations: - x: #x() - com.android.hoststubgen.hosthelper.HostStubGenKeptInStub - x: #x() - com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl - - public int keep; - descriptor: I - flags: (0x0001) ACC_PUBLIC - RuntimeVisibleAnnotations: - x: #x() - com.android.hoststubgen.hosthelper.HostStubGenKeptInStub - x: #x() - com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl - - public int remove; - descriptor: I - flags: (0x0001) ACC_PUBLIC - RuntimeVisibleAnnotations: - x: #x() - com.android.hoststubgen.hosthelper.HostStubGenKeptInStub - x: #x() - com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl - - public com.android.hoststubgen.test.tinyframework.TinyFrameworkClassClassWideAnnotations(); + interfaces: 0, fields: 0, methods: 3, attributes: 4 + private com.android.hoststubgen.test.tinyframework.TinyFrameworkCallerCheck$Impl(); descriptor: ()V - flags: (0x0001) ACC_PUBLIC + flags: (0x0002) ACC_PRIVATE Code: - stack=2, locals=1, args_size=1 + stack=1, locals=1, args_size=1 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 + x: return LineNumberTable: LocalVariableTable: Start Length Slot Name Signature - 0 15 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassClassWideAnnotations; + 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck$Impl; RuntimeVisibleAnnotations: x: #x() com.android.hoststubgen.hosthelper.HostStubGenKeptInStub x: #x() com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl - public int addOne(int); - descriptor: (I)I - flags: (0x0001) ACC_PUBLIC + public static int getOneKeep(); + descriptor: ()I + flags: (0x0009) ACC_PUBLIC, ACC_STATIC Code: - stack=2, locals=2, args_size=2 - x: aload_0 - x: iload_1 - x: invokevirtual #x // Method addOneInner:(I)I - x: ireturn + stack=4, locals=0, args_size=0 + 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: - LocalVariableTable: - Start Length Slot Name Signature - 0 6 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassClassWideAnnotations; - 0 6 1 value I RuntimeVisibleAnnotations: x: #x() - com.android.hoststubgen.hosthelper.HostStubGenKeptInStub - x: #x() com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl + RuntimeInvisibleAnnotations: + x: #x() + android.hosttest.annotation.HostSideTestKeep - public int addOneInner(int); - descriptor: (I)I - flags: (0x0001) ACC_PUBLIC + public static int getOneStub(); + descriptor: ()I + flags: (0x0009) ACC_PUBLIC, ACC_STATIC Code: - stack=2, locals=2, args_size=2 - x: iload_1 + stack=1, locals=0, args_size=0 x: iconst_1 - x: iadd x: ireturn LineNumberTable: - LocalVariableTable: - Start Length Slot Name Signature - 0 4 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassClassWideAnnotations; - 0 4 1 value I RuntimeVisibleAnnotations: x: #x() com.android.hoststubgen.hosthelper.HostStubGenKeptInStub x: #x() com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl - - public void toBeRemoved(java.lang.String); - descriptor: (Ljava/lang/String;)V - flags: (0x0001) ACC_PUBLIC - Code: - stack=2, locals=2, args_size=2 - 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 - 0 8 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassClassWideAnnotations; - 0 8 1 foo Ljava/lang/String; - RuntimeVisibleAnnotations: - x: #x() - com.android.hoststubgen.hosthelper.HostStubGenKeptInStub + RuntimeInvisibleAnnotations: x: #x() - com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl - - public int addTwo(int); - descriptor: (I)I + 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.HostStubGenKeptInStub + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl +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=2, locals=2, args_size=2 - x: iload_1 - x: iconst_2 - x: iadd - x: ireturn + stack=1, locals=1, args_size=1 + x: aload_0 + x: invokespecial #x // Method java/lang/Object."<init>":()V + x: return LineNumberTable: LocalVariableTable: Start Length Slot Name Signature - 0 4 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassClassWideAnnotations; - 0 4 1 value I + 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck; RuntimeVisibleAnnotations: x: #x() - com.android.hoststubgen.hosthelper.HostStubGenProcessedAsSubstitute - x: #x() com.android.hoststubgen.hosthelper.HostStubGenKeptInStub x: #x() com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl - public static int nativeAddThree(int); - descriptor: (I)I + public static int getOne_withCheck(); + descriptor: ()I flags: (0x0009) ACC_PUBLIC, ACC_STATIC Code: - stack=2, locals=1, args_size=1 - x: iload_0 - x: iconst_3 - x: iadd + stack=1, locals=0, args_size=0 + x: invokestatic #x // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck$Impl.getOneKeep:()I x: ireturn LineNumberTable: - LocalVariableTable: - Start Length Slot Name Signature - 0 4 0 value I - RuntimeVisibleAnnotations: - x: #x() - com.android.hoststubgen.hosthelper.HostStubGenProcessedAsSubstitute - x: #x() - com.android.hoststubgen.hosthelper.HostStubGenKeptInStub - x: #x() - com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl - - public java.lang.String unsupportedMethod(); - descriptor: ()Ljava/lang/String; - flags: (0x0001) ACC_PUBLIC - Code: - stack=1, locals=1, args_size=1 - x: ldc #x // String This value shouldn\'t be seen on the host side. - x: areturn - LineNumberTable: - LocalVariableTable: - Start Length Slot Name Signature - 0 3 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassClassWideAnnotations; RuntimeVisibleAnnotations: x: #x() com.android.hoststubgen.hosthelper.HostStubGenKeptInStub x: #x() com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl - public java.lang.String visibleButUsesUnsupportedMethod(); - descriptor: ()Ljava/lang/String; - flags: (0x0001) ACC_PUBLIC + public static int getOne_noCheck(); + descriptor: ()I + flags: (0x0009) ACC_PUBLIC, ACC_STATIC Code: - stack=1, locals=1, args_size=1 - x: aload_0 - x: invokevirtual #x // Method unsupportedMethod:()Ljava/lang/String; - x: areturn + stack=1, locals=0, args_size=0 + x: invokestatic #x // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck$Impl.getOneStub:()I + x: ireturn LineNumberTable: - LocalVariableTable: - Start Length Slot Name Signature - 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassClassWideAnnotations; RuntimeVisibleAnnotations: x: #x() com.android.hoststubgen.hosthelper.HostStubGenKeptInStub x: #x() com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl } -SourceFile: "TinyFrameworkClassClassWideAnnotations.java" +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.HostStubGenKeptInStub @@ -1020,6 +811,8 @@ RuntimeVisibleAnnotations: RuntimeInvisibleAnnotations: x: #x() android.hosttest.annotation.HostSideTestWholeClassStub +NestMembers: + com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck$Impl ## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkClassLoadHook.class Compiled from "TinyFrameworkClassLoadHook.java" public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassLoadHook @@ -1107,6 +900,140 @@ RuntimeVisibleAnnotations: RuntimeInvisibleAnnotations: x: #x() android.hosttest.annotation.HostSideTestWholeClassStub +## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWideAnnotations.class + Compiled from "TinyFrameworkClassWideAnnotations.java" +public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassWideAnnotations + minor version: 0 + major version: 61 + flags: (0x0021) ACC_PUBLIC, ACC_SUPER + this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWideAnnotations + super_class: #x // java/lang/Object + interfaces: 0, fields: 1, methods: 5, attributes: 3 + public int stub; + descriptor: I + flags: (0x0001) ACC_PUBLIC + RuntimeVisibleAnnotations: + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInStub + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl + + public com.android.hoststubgen.test.tinyframework.TinyFrameworkClassWideAnnotations(); + descriptor: ()V + flags: (0x0001) ACC_PUBLIC + Code: + stack=2, locals=1, args_size=1 + 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: return + LineNumberTable: + LocalVariableTable: + Start Length Slot Name Signature + 0 10 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassWideAnnotations; + RuntimeVisibleAnnotations: + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInStub + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl + + public int addOne(int); + descriptor: (I)I + flags: (0x0001) ACC_PUBLIC + Code: + stack=2, locals=2, args_size=2 + x: iload_1 + x: iconst_1 + x: iadd + x: ireturn + LineNumberTable: + LocalVariableTable: + Start Length Slot Name Signature + 0 4 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassWideAnnotations; + 0 4 1 value I + RuntimeVisibleAnnotations: + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInStub + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl + + public int addTwo(int); + descriptor: (I)I + flags: (0x0001) ACC_PUBLIC + Code: + stack=2, locals=2, args_size=2 + x: iload_1 + x: iconst_2 + x: iadd + x: ireturn + LineNumberTable: + LocalVariableTable: + Start Length Slot Name Signature + 0 4 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassWideAnnotations; + 0 4 1 value I + RuntimeVisibleAnnotations: + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenProcessedAsSubstitute + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInStub + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl + + public java.lang.String unsupportedMethod(); + descriptor: ()Ljava/lang/String; + flags: (0x0001) ACC_PUBLIC + Code: + stack=4, locals=1, args_size=1 + x: ldc #x // String com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWideAnnotations + 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 + RuntimeVisibleAnnotations: + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenProcessedAsThrow + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl + RuntimeInvisibleAnnotations: + x: #x() + android.hosttest.annotation.HostSideTestThrow + + public java.lang.String visibleButUsesUnsupportedMethod(); + descriptor: ()Ljava/lang/String; + flags: (0x0001) ACC_PUBLIC + Code: + stack=1, locals=1, args_size=1 + x: aload_0 + x: invokevirtual #x // Method unsupportedMethod:()Ljava/lang/String; + x: areturn + LineNumberTable: + LocalVariableTable: + Start Length Slot Name Signature + 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassWideAnnotations; + RuntimeVisibleAnnotations: + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInStub + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl +} +SourceFile: "TinyFrameworkClassWideAnnotations.java" +RuntimeVisibleAnnotations: + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInStub + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl +RuntimeInvisibleAnnotations: + x: #x() + android.hosttest.annotation.HostSideTestWholeClassStub ## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWithInitializerDefault.class Compiled from "TinyFrameworkClassWithInitializerDefault.java" public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassWithInitializerDefault @@ -3430,7 +3357,7 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClass 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 + interfaces: 0, fields: 2, methods: 1, attributes: 4 public int value; descriptor: I flags: (0x0001) ACC_PUBLIC @@ -3485,9 +3412,6 @@ RuntimeVisibleAnnotations: com.android.hoststubgen.hosthelper.HostStubGenKeptInStub x: #x() com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl -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" @@ -3568,6 +3492,55 @@ RuntimeVisibleAnnotations: x: #x() com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses +## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$Double$NestedClass.class + Compiled from "TinyFrameworkNestedClasses.java" +public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$StaticNestedClass$Double$NestedClass + minor version: 0 + major version: 61 + flags: (0x0021) ACC_PUBLIC, ACC_SUPER + this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$Double$NestedClass + super_class: #x // java/lang/Object + interfaces: 0, fields: 1, methods: 1, attributes: 4 + public int value; + descriptor: I + flags: (0x0001) ACC_PUBLIC + RuntimeVisibleAnnotations: + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInStub + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl + + public com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$StaticNestedClass$Double$NestedClass(); + descriptor: ()V + flags: (0x0001) ACC_PUBLIC + Code: + stack=2, locals=1, args_size=1 + x: aload_0 + x: invokespecial #x // Method java/lang/Object."<init>":()V + x: aload_0 + x: bipush 8 + x: putfield #x // Field value:I + x: return + LineNumberTable: + LocalVariableTable: + Start Length Slot Name Signature + 0 11 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$Double$NestedClass; + RuntimeVisibleAnnotations: + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInStub + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl +} +InnerClasses: + public static #x= #x of #x; // StaticNestedClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses + public static #x= #x of #x; // Double$NestedClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$Double$NestedClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass +SourceFile: "TinyFrameworkNestedClasses.java" +RuntimeVisibleAnnotations: + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInStub + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl +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 @@ -3576,7 +3549,7 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClass 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 + interfaces: 0, fields: 1, methods: 2, attributes: 4 public int value; descriptor: I flags: (0x0001) ACC_PUBLIC @@ -3627,15 +3600,13 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClass 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 + public static #x= #x of #x; // Double$NestedClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$Double$NestedClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass SourceFile: "TinyFrameworkNestedClasses.java" RuntimeVisibleAnnotations: x: #x() com.android.hoststubgen.hosthelper.HostStubGenKeptInStub x: #x() com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl -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" @@ -3793,6 +3764,7 @@ 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; // 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 + public static #x= #x of #x; // Double$NestedClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$Double$NestedClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass #x; // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1 SourceFile: "TinyFrameworkNestedClasses.java" RuntimeVisibleAnnotations: @@ -3807,6 +3779,7 @@ 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$Double$NestedClass com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1 com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$InnerClass com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4 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 index 1b83d244c55c..86a9c65f59b4 100644 --- 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 @@ -216,136 +216,13 @@ RuntimeVisibleAnnotations: com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl NestMembers: com/android/hoststubgen/test/tinyframework/R$Nested -## 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 - RuntimeVisibleAnnotations: - x: #x() - com.android.hoststubgen.hosthelper.HostStubGenKeptInStub - x: #x() - com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl - - 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 - RuntimeVisibleAnnotations: - x: #x() - com.android.hoststubgen.hosthelper.HostStubGenKeptInStub - x: #x() - com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl - 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.HostStubGenKeptInStub - x: #x() - com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl -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 +## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkAnnotations.class + Compiled from "TinyFrameworkAnnotations.java" +public class com.android.hoststubgen.test.tinyframework.TinyFrameworkAnnotations 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 - RuntimeVisibleAnnotations: - x: #x() - com.android.hoststubgen.hosthelper.HostStubGenKeptInStub - x: #x() - com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl - - 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 - RuntimeVisibleAnnotations: - x: #x() - com.android.hoststubgen.hosthelper.HostStubGenKeptInStub - x: #x() - com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl - - 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 - RuntimeVisibleAnnotations: - x: #x() - com.android.hoststubgen.hosthelper.HostStubGenKeptInStub - x: #x() - com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl -} -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.HostStubGenKeptInStub - x: #x() - com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl -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 + this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkAnnotations super_class: #x // java/lang/Object interfaces: 0, fields: 1, methods: 5, attributes: 3 public int stub; @@ -360,7 +237,7 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassAnnota x: #x() android.hosttest.annotation.HostSideTestStub - public com.android.hoststubgen.test.tinyframework.TinyFrameworkClassAnnotations(); + public com.android.hoststubgen.test.tinyframework.TinyFrameworkAnnotations(); descriptor: ()V flags: (0x0001) ACC_PUBLIC Code: @@ -449,7 +326,7 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassAnnota x: #x() android.hosttest.annotation.HostSideTestStub } -SourceFile: "TinyFrameworkClassAnnotations.java" +SourceFile: "TinyFrameworkAnnotations.java" RuntimeVisibleAnnotations: x: #x() com.android.hoststubgen.hosthelper.HostStubGenKeptInStub @@ -462,45 +339,18 @@ RuntimeInvisibleAnnotations: 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 +## 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: (0x0021) ACC_PUBLIC, ACC_SUPER - this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkClassClassWideAnnotations + flags: (0x0020) ACC_SUPER + this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck$Impl super_class: #x // java/lang/Object - interfaces: 0, fields: 3, methods: 8, attributes: 3 - public int stub; - descriptor: I - flags: (0x0001) ACC_PUBLIC - RuntimeVisibleAnnotations: - x: #x() - com.android.hoststubgen.hosthelper.HostStubGenKeptInStub - x: #x() - com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl - - public int keep; - descriptor: I - flags: (0x0001) ACC_PUBLIC - RuntimeVisibleAnnotations: - x: #x() - com.android.hoststubgen.hosthelper.HostStubGenKeptInStub - x: #x() - com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl - - public int remove; - descriptor: I - flags: (0x0001) ACC_PUBLIC - RuntimeVisibleAnnotations: - x: #x() - com.android.hoststubgen.hosthelper.HostStubGenKeptInStub - x: #x() - com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl - - public com.android.hoststubgen.test.tinyframework.TinyFrameworkClassClassWideAnnotations(); + interfaces: 0, fields: 0, methods: 2, attributes: 4 + private com.android.hoststubgen.test.tinyframework.TinyFrameworkCallerCheck$Impl(); descriptor: ()V - flags: (0x0001) ACC_PUBLIC + flags: (0x0002) ACC_PRIVATE Code: stack=3, locals=1, args_size=1 x: new #x // class java/lang/RuntimeException @@ -514,11 +364,11 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassClassW x: #x() com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl - public int addOne(int); - descriptor: (I)I - flags: (0x0001) ACC_PUBLIC + public static int getOneStub(); + descriptor: ()I + flags: (0x0009) ACC_PUBLIC, ACC_STATIC Code: - stack=3, locals=2, args_size=2 + stack=3, locals=0, args_size=0 x: new #x // class java/lang/RuntimeException x: dup x: ldc #x // String Stub! @@ -529,12 +379,33 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassClassW com.android.hoststubgen.hosthelper.HostStubGenKeptInStub x: #x() com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl - - public int addOneInner(int); - descriptor: (I)I + 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.HostStubGenKeptInStub + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl +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=2, args_size=2 + stack=3, locals=1, args_size=1 x: new #x // class java/lang/RuntimeException x: dup x: ldc #x // String Stub! @@ -546,11 +417,11 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassClassW x: #x() com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl - public void toBeRemoved(java.lang.String); - descriptor: (Ljava/lang/String;)V - flags: (0x0001) ACC_PUBLIC + public static int getOne_withCheck(); + descriptor: ()I + flags: (0x0009) ACC_PUBLIC, ACC_STATIC Code: - stack=3, locals=2, args_size=2 + stack=3, locals=0, args_size=0 x: new #x // class java/lang/RuntimeException x: dup x: ldc #x // String Stub! @@ -562,11 +433,11 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassClassW x: #x() com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl - public int addTwo(int); - descriptor: (I)I - flags: (0x0001) ACC_PUBLIC + public static int getOne_noCheck(); + descriptor: ()I + flags: (0x0009) ACC_PUBLIC, ACC_STATIC Code: - stack=3, locals=2, args_size=2 + stack=3, locals=0, args_size=0 x: new #x // class java/lang/RuntimeException x: dup x: ldc #x // String Stub! @@ -577,10 +448,42 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassClassW com.android.hoststubgen.hosthelper.HostStubGenKeptInStub x: #x() com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl +} +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.HostStubGenKeptInStub + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl +RuntimeInvisibleAnnotations: + x: #x() + android.hosttest.annotation.HostSideTestWholeClassStub +NestMembers: + com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck$Impl +## 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<*>;>; + RuntimeVisibleAnnotations: + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInStub + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl - public static int nativeAddThree(int); - descriptor: (I)I - flags: (0x0009) ACC_PUBLIC, ACC_STATIC + 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 @@ -594,9 +497,9 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassClassW x: #x() com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl - public java.lang.String unsupportedMethod(); - descriptor: ()Ljava/lang/String; - flags: (0x0001) ACC_PUBLIC + 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 @@ -604,17 +507,18 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassClassW 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 RuntimeVisibleAnnotations: x: #x() com.android.hoststubgen.hosthelper.HostStubGenKeptInStub x: #x() com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl - public java.lang.String visibleButUsesUnsupportedMethod(); - descriptor: ()Ljava/lang/String; - flags: (0x0001) ACC_PUBLIC + static {}; + descriptor: ()V + flags: (0x0008) ACC_STATIC Code: - stack=3, locals=1, args_size=1 + stack=3, locals=0, args_size=0 x: new #x // class java/lang/RuntimeException x: dup x: ldc #x // String Stub! @@ -626,7 +530,7 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassClassW x: #x() com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl } -SourceFile: "TinyFrameworkClassClassWideAnnotations.java" +SourceFile: "TinyFrameworkClassLoadHook.java" RuntimeVisibleAnnotations: x: #x() com.android.hoststubgen.hosthelper.HostStubGenKeptInStub @@ -635,28 +539,27 @@ RuntimeVisibleAnnotations: 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 +## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWideAnnotations.class + Compiled from "TinyFrameworkClassWideAnnotations.java" +public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassWideAnnotations minor version: 0 major version: 61 flags: (0x0021) ACC_PUBLIC, ACC_SUPER - this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkClassLoadHook + this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWideAnnotations 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<*>;>; + interfaces: 0, fields: 1, methods: 4, attributes: 3 + public int stub; + descriptor: I + flags: (0x0001) ACC_PUBLIC RuntimeVisibleAnnotations: x: #x() com.android.hoststubgen.hosthelper.HostStubGenKeptInStub x: #x() com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl - private com.android.hoststubgen.test.tinyframework.TinyFrameworkClassLoadHook(); + public com.android.hoststubgen.test.tinyframework.TinyFrameworkClassWideAnnotations(); descriptor: ()V - flags: (0x0002) ACC_PRIVATE + flags: (0x0001) ACC_PUBLIC Code: stack=3, locals=1, args_size=1 x: new #x // class java/lang/RuntimeException @@ -670,28 +573,43 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassLoadHo x: #x() com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl - public static void onClassLoaded(java.lang.Class<?>); - descriptor: (Ljava/lang/Class;)V - flags: (0x0009) ACC_PUBLIC, ACC_STATIC + public int addOne(int); + descriptor: (I)I + flags: (0x0001) ACC_PUBLIC Code: - stack=3, locals=1, args_size=1 + 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 - Signature: #x // (Ljava/lang/Class<*>;)V RuntimeVisibleAnnotations: x: #x() com.android.hoststubgen.hosthelper.HostStubGenKeptInStub x: #x() com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl - static {}; - descriptor: ()V - flags: (0x0008) ACC_STATIC + public int addTwo(int); + descriptor: (I)I + flags: (0x0001) ACC_PUBLIC Code: - stack=3, locals=0, args_size=0 + 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 + RuntimeVisibleAnnotations: + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInStub + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl + + 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! @@ -703,7 +621,7 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassLoadHo x: #x() com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl } -SourceFile: "TinyFrameworkClassLoadHook.java" +SourceFile: "TinyFrameworkClassWideAnnotations.java" RuntimeVisibleAnnotations: x: #x() com.android.hoststubgen.hosthelper.HostStubGenKeptInStub @@ -2153,7 +2071,7 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClass 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 + interfaces: 0, fields: 2, methods: 1, attributes: 4 public int value; descriptor: I flags: (0x0001) ACC_PUBLIC @@ -2199,9 +2117,50 @@ RuntimeVisibleAnnotations: com.android.hoststubgen.hosthelper.HostStubGenKeptInStub x: #x() com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl -RuntimeInvisibleAnnotations: +NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses +## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$Double$NestedClass.class + Compiled from "TinyFrameworkNestedClasses.java" +public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$StaticNestedClass$Double$NestedClass + minor version: 0 + major version: 61 + flags: (0x0021) ACC_PUBLIC, ACC_SUPER + this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$Double$NestedClass + super_class: #x // java/lang/Object + interfaces: 0, fields: 1, methods: 1, attributes: 4 + public int value; + descriptor: I + flags: (0x0001) ACC_PUBLIC + RuntimeVisibleAnnotations: + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInStub + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl + + public com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$StaticNestedClass$Double$NestedClass(); + 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 + RuntimeVisibleAnnotations: + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInStub + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl +} +InnerClasses: + public static #x= #x of #x; // StaticNestedClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses + public static #x= #x of #x; // Double$NestedClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$Double$NestedClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass +SourceFile: "TinyFrameworkNestedClasses.java" +RuntimeVisibleAnnotations: x: #x() - android.hosttest.annotation.HostSideTestWholeClassStub + com.android.hoststubgen.hosthelper.HostStubGenKeptInStub + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses ## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass.class Compiled from "TinyFrameworkNestedClasses.java" @@ -2211,7 +2170,7 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClass 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 + interfaces: 0, fields: 1, methods: 2, attributes: 4 public int value; descriptor: I flags: (0x0001) ACC_PUBLIC @@ -2257,15 +2216,13 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClass 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 + public static #x= #x of #x; // Double$NestedClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$Double$NestedClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass SourceFile: "TinyFrameworkNestedClasses.java" RuntimeVisibleAnnotations: x: #x() com.android.hoststubgen.hosthelper.HostStubGenKeptInStub x: #x() com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl -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" @@ -2406,6 +2363,7 @@ 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; // 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 + public static #x= #x of #x; // Double$NestedClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$Double$NestedClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass #x; // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1 SourceFile: "TinyFrameworkNestedClasses.java" RuntimeVisibleAnnotations: @@ -2420,6 +2378,7 @@ 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$Double$NestedClass com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1 com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$InnerClass com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4 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 index d12a23d3d68f..da434a615c81 100644 --- 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 @@ -611,205 +611,13 @@ RuntimeVisibleAnnotations: com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl NestMembers: com/android/hoststubgen/test/tinyframework/R$Nested -## 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; - RuntimeVisibleAnnotations: - x: #x() - com.android.hoststubgen.hosthelper.HostStubGenKeptInStub - x: #x() - com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl - - 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: - RuntimeVisibleAnnotations: - x: #x() - com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl - 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: - RuntimeVisibleAnnotations: - x: #x() - com.android.hoststubgen.hosthelper.HostStubGenKeptInStub - x: #x() - com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl - 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.HostStubGenKeptInStub - x: #x() - com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl -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; - RuntimeVisibleAnnotations: - x: #x() - com.android.hoststubgen.hosthelper.HostStubGenKeptInStub - x: #x() - com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl - - 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: - RuntimeVisibleAnnotations: - x: #x() - com.android.hoststubgen.hosthelper.HostStubGenKeptInStub - x: #x() - com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl - - 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: - RuntimeVisibleAnnotations: - x: #x() - com.android.hoststubgen.hosthelper.HostStubGenKeptInStub - x: #x() - com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl -} -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.HostStubGenKeptInStub - x: #x() - com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl -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 +## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkAnnotations.class + Compiled from "TinyFrameworkAnnotations.java" +public class com.android.hoststubgen.test.tinyframework.TinyFrameworkAnnotations minor version: 0 major version: 61 flags: (0x0021) ACC_PUBLIC, ACC_SUPER - this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkClassAnnotations + this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkAnnotations super_class: #x // java/lang/Object interfaces: 0, fields: 2, methods: 8, attributes: 3 public int stub; @@ -839,20 +647,20 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassAnnota 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 // class com/android/hoststubgen/test/tinyframework/TinyFrameworkAnnotations 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 // class com/android/hoststubgen/test/tinyframework/TinyFrameworkAnnotations 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(); + public com.android.hoststubgen.test.tinyframework.TinyFrameworkAnnotations(); 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 // class com/android/hoststubgen/test/tinyframework/TinyFrameworkAnnotations x: ldc #x // String <init> x: ldc #x // String ()V x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall @@ -869,7 +677,7 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassAnnota LineNumberTable: LocalVariableTable: Start Length Slot Name Signature - 11 15 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassAnnotations; + 11 15 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkAnnotations; RuntimeVisibleAnnotations: x: #x() com.android.hoststubgen.hosthelper.HostStubGenKeptInStub @@ -884,7 +692,7 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassAnnota 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 // class com/android/hoststubgen/test/tinyframework/TinyFrameworkAnnotations x: ldc #x // String addOne x: ldc #x // String (I)I x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall @@ -896,7 +704,7 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassAnnota LineNumberTable: LocalVariableTable: Start Length Slot Name Signature - 11 6 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassAnnotations; + 11 6 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkAnnotations; 11 6 1 value I RuntimeVisibleAnnotations: x: #x() @@ -912,12 +720,12 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassAnnota 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 // class com/android/hoststubgen/test/tinyframework/TinyFrameworkAnnotations 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 com/android/hoststubgen/test/tinyframework/TinyFrameworkAnnotations x: ldc #x // String addOneInner x: ldc #x // String (I)I x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.getStackWalker:()Ljava/lang/StackWalker; @@ -930,7 +738,7 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassAnnota LineNumberTable: LocalVariableTable: Start Length Slot Name Signature - 26 4 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassAnnotations; + 26 4 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkAnnotations; 26 4 1 value I RuntimeVisibleAnnotations: x: #x() @@ -944,7 +752,7 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassAnnota 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 // class com/android/hoststubgen/test/tinyframework/TinyFrameworkAnnotations x: ldc #x // String addTwo x: ldc #x // String (I)I x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall @@ -956,7 +764,7 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassAnnota LineNumberTable: LocalVariableTable: Start Length Slot Name Signature - 11 4 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassAnnotations; + 11 4 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkAnnotations; 11 4 1 value I RuntimeVisibleAnnotations: x: #x() @@ -971,7 +779,7 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassAnnota 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 // class com/android/hoststubgen/test/tinyframework/TinyFrameworkAnnotations x: ldc #x // String nativeAddThree x: ldc #x // String (I)I x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall @@ -997,12 +805,12 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassAnnota 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 // class com/android/hoststubgen/test/tinyframework/TinyFrameworkAnnotations 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 com/android/hoststubgen/test/tinyframework/TinyFrameworkAnnotations 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; @@ -1028,7 +836,7 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassAnnota 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 // class com/android/hoststubgen/test/tinyframework/TinyFrameworkAnnotations x: ldc #x // String visibleButUsesUnsupportedMethod x: ldc #x // String ()Ljava/lang/String; x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall @@ -1039,7 +847,7 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassAnnota LineNumberTable: LocalVariableTable: Start Length Slot Name Signature - 11 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassAnnotations; + 11 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkAnnotations; RuntimeVisibleAnnotations: x: #x() com.android.hoststubgen.hosthelper.HostStubGenKeptInStub @@ -1049,7 +857,7 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassAnnota x: #x() android.hosttest.annotation.HostSideTestStub } -SourceFile: "TinyFrameworkClassAnnotations.java" +SourceFile: "TinyFrameworkAnnotations.java" RuntimeVisibleAnnotations: x: #x() com.android.hoststubgen.hosthelper.HostStubGenKeptInStub @@ -1062,255 +870,188 @@ RuntimeInvisibleAnnotations: 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 +## 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: (0x0021) ACC_PUBLIC, ACC_SUPER - this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkClassClassWideAnnotations + flags: (0x0020) ACC_SUPER + this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck$Impl super_class: #x // java/lang/Object - interfaces: 0, fields: 3, methods: 9, attributes: 3 - public int stub; - descriptor: I - flags: (0x0001) ACC_PUBLIC - RuntimeVisibleAnnotations: - x: #x() - com.android.hoststubgen.hosthelper.HostStubGenKeptInStub - x: #x() - com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl - - public int keep; - descriptor: I - flags: (0x0001) ACC_PUBLIC - RuntimeVisibleAnnotations: - x: #x() - com.android.hoststubgen.hosthelper.HostStubGenKeptInStub - x: #x() - com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl - - public int remove; - descriptor: I - flags: (0x0001) ACC_PUBLIC - RuntimeVisibleAnnotations: - x: #x() - com.android.hoststubgen.hosthelper.HostStubGenKeptInStub - x: #x() - com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl - + 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/TinyFrameworkClassClassWideAnnotations + 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 - public com.android.hoststubgen.test.tinyframework.TinyFrameworkClassClassWideAnnotations(); + private com.android.hoststubgen.test.tinyframework.TinyFrameworkCallerCheck$Impl(); descriptor: ()V - flags: (0x0001) ACC_PUBLIC + flags: (0x0002) ACC_PRIVATE Code: stack=4, locals=1, args_size=1 - x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkClassClassWideAnnotations + 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: 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; + 11 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck$Impl; RuntimeVisibleAnnotations: x: #x() com.android.hoststubgen.hosthelper.HostStubGenKeptInStub x: #x() com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl - public int addOne(int); - descriptor: (I)I - flags: (0x0001) ACC_PUBLIC + public static int getOneKeep(); + descriptor: ()I + flags: (0x0009) ACC_PUBLIC, ACC_STATIC 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 + 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: aload_0 - x: iload_1 - x: invokevirtual #x // Method addOneInner:(I)I + 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: - LocalVariableTable: - Start Length Slot Name Signature - 11 6 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassClassWideAnnotations; - 11 6 1 value I RuntimeVisibleAnnotations: x: #x() - com.android.hoststubgen.hosthelper.HostStubGenKeptInStub - x: #x() com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl + RuntimeInvisibleAnnotations: + x: #x() + android.hosttest.annotation.HostSideTestKeep - public int addOneInner(int); - descriptor: (I)I - flags: (0x0001) ACC_PUBLIC + public static int getOneStub(); + descriptor: ()I + flags: (0x0009) ACC_PUBLIC, ACC_STATIC 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 + 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: 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 RuntimeVisibleAnnotations: x: #x() com.android.hoststubgen.hosthelper.HostStubGenKeptInStub x: #x() com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl - - 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; - RuntimeVisibleAnnotations: - x: #x() - com.android.hoststubgen.hosthelper.HostStubGenKeptInStub + RuntimeInvisibleAnnotations: x: #x() - com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl + 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.HostStubGenKeptInStub + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl +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 int addTwo(int); - descriptor: (I)I + public com.android.hoststubgen.test.tinyframework.TinyFrameworkCallerCheck(); + descriptor: ()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 addTwo - x: ldc #x // String (I)I + 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: iload_1 - x: iconst_2 - x: iadd - x: ireturn + x: aload_0 + x: invokespecial #x // Method java/lang/Object."<init>":()V + x: return LineNumberTable: LocalVariableTable: Start Length Slot Name Signature - 11 4 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassClassWideAnnotations; - 11 4 1 value I + 11 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck; RuntimeVisibleAnnotations: x: #x() - com.android.hoststubgen.hosthelper.HostStubGenProcessedAsSubstitute - x: #x() com.android.hoststubgen.hosthelper.HostStubGenKeptInStub x: #x() com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl - public static int nativeAddThree(int); - descriptor: (I)I + public static int getOne_withCheck(); + descriptor: ()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 + 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: iload_0 - x: iconst_3 - x: iadd + x: invokestatic #x // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck$Impl.getOneKeep:()I x: ireturn LineNumberTable: - LocalVariableTable: - Start Length Slot Name Signature - 11 4 0 value I RuntimeVisibleAnnotations: x: #x() - com.android.hoststubgen.hosthelper.HostStubGenProcessedAsSubstitute - x: #x() com.android.hoststubgen.hosthelper.HostStubGenKeptInStub x: #x() com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl - 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; - RuntimeVisibleAnnotations: - x: #x() - com.android.hoststubgen.hosthelper.HostStubGenKeptInStub - x: #x() - com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl - - public java.lang.String visibleButUsesUnsupportedMethod(); - descriptor: ()Ljava/lang/String; - flags: (0x0001) ACC_PUBLIC + public static int getOne_noCheck(); + descriptor: ()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 visibleButUsesUnsupportedMethod - x: ldc #x // String ()Ljava/lang/String; + 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: aload_0 - x: invokevirtual #x // Method unsupportedMethod:()Ljava/lang/String; - x: areturn + x: invokestatic #x // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck$Impl.getOneStub:()I + x: ireturn LineNumberTable: - LocalVariableTable: - Start Length Slot Name Signature - 11 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassClassWideAnnotations; RuntimeVisibleAnnotations: x: #x() com.android.hoststubgen.hosthelper.HostStubGenKeptInStub x: #x() com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl } -SourceFile: "TinyFrameworkClassClassWideAnnotations.java" +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.HostStubGenKeptInStub @@ -1319,6 +1060,8 @@ RuntimeVisibleAnnotations: RuntimeInvisibleAnnotations: x: #x() android.hosttest.annotation.HostSideTestWholeClassStub +NestMembers: + com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck$Impl ## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkClassLoadHook.class Compiled from "TinyFrameworkClassLoadHook.java" public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassLoadHook @@ -1424,6 +1167,175 @@ RuntimeVisibleAnnotations: RuntimeInvisibleAnnotations: x: #x() android.hosttest.annotation.HostSideTestWholeClassStub +## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWideAnnotations.class + Compiled from "TinyFrameworkClassWideAnnotations.java" +public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassWideAnnotations + minor version: 0 + major version: 61 + flags: (0x0021) ACC_PUBLIC, ACC_SUPER + this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWideAnnotations + super_class: #x // java/lang/Object + interfaces: 0, fields: 1, methods: 6, attributes: 3 + public int stub; + descriptor: I + flags: (0x0001) ACC_PUBLIC + RuntimeVisibleAnnotations: + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInStub + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl + + 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/TinyFrameworkClassWideAnnotations + 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.TinyFrameworkClassWideAnnotations(); + descriptor: ()V + flags: (0x0001) ACC_PUBLIC + Code: + stack=4, locals=1, args_size=1 + x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWideAnnotations + 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: return + LineNumberTable: + LocalVariableTable: + Start Length Slot Name Signature + 11 10 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassWideAnnotations; + RuntimeVisibleAnnotations: + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInStub + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl + + 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/TinyFrameworkClassWideAnnotations + 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: 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/TinyFrameworkClassWideAnnotations; + 11 4 1 value I + RuntimeVisibleAnnotations: + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInStub + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl + + 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/TinyFrameworkClassWideAnnotations + 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/TinyFrameworkClassWideAnnotations; + 11 4 1 value I + RuntimeVisibleAnnotations: + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenProcessedAsSubstitute + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInStub + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl + + 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/TinyFrameworkClassWideAnnotations + 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/TinyFrameworkClassWideAnnotations + 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 + RuntimeVisibleAnnotations: + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenProcessedAsThrow + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl + 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/TinyFrameworkClassWideAnnotations + 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/TinyFrameworkClassWideAnnotations; + RuntimeVisibleAnnotations: + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInStub + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl +} +SourceFile: "TinyFrameworkClassWideAnnotations.java" +RuntimeVisibleAnnotations: + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInStub + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl +RuntimeInvisibleAnnotations: + x: #x() + android.hosttest.annotation.HostSideTestWholeClassStub ## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWithInitializerDefault.class Compiled from "TinyFrameworkClassWithInitializerDefault.java" public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassWithInitializerDefault @@ -4280,7 +4192,7 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClass 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 + interfaces: 0, fields: 2, methods: 2, attributes: 4 public int value; descriptor: I flags: (0x0001) ACC_PUBLIC @@ -4350,9 +4262,6 @@ RuntimeVisibleAnnotations: com.android.hoststubgen.hosthelper.HostStubGenKeptInStub x: #x() com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl -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" @@ -4458,6 +4367,70 @@ RuntimeVisibleAnnotations: x: #x() com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses +## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$Double$NestedClass.class + Compiled from "TinyFrameworkNestedClasses.java" +public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$StaticNestedClass$Double$NestedClass + minor version: 0 + major version: 61 + flags: (0x0021) ACC_PUBLIC, ACC_SUPER + this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$Double$NestedClass + super_class: #x // java/lang/Object + interfaces: 0, fields: 1, methods: 2, attributes: 4 + public int value; + descriptor: I + flags: (0x0001) ACC_PUBLIC + RuntimeVisibleAnnotations: + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInStub + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl + + 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$Double$NestedClass + 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$Double$NestedClass(); + 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$Double$NestedClass + 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 8 + 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$Double$NestedClass; + RuntimeVisibleAnnotations: + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInStub + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl +} +InnerClasses: + public static #x= #x of #x; // StaticNestedClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses + public static #x= #x of #x; // Double$NestedClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$Double$NestedClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass +SourceFile: "TinyFrameworkNestedClasses.java" +RuntimeVisibleAnnotations: + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInStub + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl +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 @@ -4466,7 +4439,7 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClass 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 + interfaces: 0, fields: 1, methods: 3, attributes: 4 public int value; descriptor: I flags: (0x0001) ACC_PUBLIC @@ -4537,15 +4510,13 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClass 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 + public static #x= #x of #x; // Double$NestedClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$Double$NestedClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass SourceFile: "TinyFrameworkNestedClasses.java" RuntimeVisibleAnnotations: x: #x() com.android.hoststubgen.hosthelper.HostStubGenKeptInStub x: #x() com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl -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" @@ -4741,6 +4712,7 @@ 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; // 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 + public static #x= #x of #x; // Double$NestedClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$Double$NestedClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass #x; // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1 SourceFile: "TinyFrameworkNestedClasses.java" RuntimeVisibleAnnotations: @@ -4755,6 +4727,7 @@ 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$Double$NestedClass com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1 com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$InnerClass com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4 diff --git a/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkClassAnnotations.java b/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkAnnotations.java index 6d8a48a37fea..30dfc80fc60b 100644 --- a/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkClassAnnotations.java +++ b/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkAnnotations.java @@ -28,9 +28,9 @@ import android.hosttest.annotation.HostSideTestThrow; @HostSideTestStub @HostSideTestClassLoadHook( "com.android.hoststubgen.test.tinyframework.TinyFrameworkClassLoadHook.onClassLoaded") -public class TinyFrameworkClassAnnotations { +public class TinyFrameworkAnnotations { @HostSideTestStub - public TinyFrameworkClassAnnotations() { + public TinyFrameworkAnnotations() { } @HostSideTestStub diff --git a/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkClassClassWideAnnotations.java b/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWideAnnotations.java index 145b65a98d7b..a626bc943018 100644 --- a/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkClassClassWideAnnotations.java +++ b/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWideAnnotations.java @@ -15,38 +15,21 @@ */ package com.android.hoststubgen.test.tinyframework; -import android.hosttest.annotation.HostSideTestStub; import android.hosttest.annotation.HostSideTestSubstitute; +import android.hosttest.annotation.HostSideTestThrow; import android.hosttest.annotation.HostSideTestWholeClassStub; @HostSideTestWholeClassStub -public class TinyFrameworkClassClassWideAnnotations { - public TinyFrameworkClassClassWideAnnotations() { +public class TinyFrameworkClassWideAnnotations { + public TinyFrameworkClassWideAnnotations() { } public int stub = 1; - public int keep = 2; - - // Cannot have an initial value, because otherwise .ctor will fail to set it at runtime. - public int remove; - - // @Stub public int addOne(int value) { - return addOneInner(value); - } - - // @Keep - public int addOneInner(int value) { return value + 1; } - // @Remove - public void toBeRemoved(String foo) { - throw new RuntimeException(); - } - - @HostSideTestStub @HostSideTestSubstitute(suffix = "_host") public int addTwo(int value) { throw new RuntimeException("not supported on host side"); @@ -56,14 +39,7 @@ public class TinyFrameworkClassClassWideAnnotations { return value + 2; } - @HostSideTestStub - @HostSideTestSubstitute(suffix = "_host") - public static native int nativeAddThree(int value); - - public static int nativeAddThree_host(int value) { - return value + 3; - } - + @HostSideTestThrow public String unsupportedMethod() { return "This value shouldn't be seen on the host side."; } diff --git a/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses.java b/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses.java index e1c48bb85563..fec307a3db25 100644 --- a/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses.java +++ b/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses.java @@ -34,6 +34,7 @@ public class TinyFrameworkNestedClasses { return 2; } }; + public Supplier<Integer> getSupplier() { return new Supplier<Integer>() { @Override @@ -52,12 +53,10 @@ public class TinyFrameworkNestedClasses { }; } - @HostSideTestWholeClassStub public class InnerClass { public int value = 5; } - @HostSideTestWholeClassStub public static class StaticNestedClass { public int value = 6; @@ -70,6 +69,10 @@ public class TinyFrameworkNestedClasses { } }; } + + public static class Double$NestedClass { + public int value = 8; + } } public static class BaseClass { diff --git a/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-test/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWithAnnotTest.java b/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-test/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkAnnotationsTest.java index 288c7162aa58..181902a41ec9 100644 --- a/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-test/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWithAnnotTest.java +++ b/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-test/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkAnnotationsTest.java @@ -21,20 +21,20 @@ import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; -public class TinyFrameworkClassWithAnnotTest { +public class TinyFrameworkAnnotationsTest { @Rule public ExpectedException thrown = ExpectedException.none(); @Test public void testSimple() { - TinyFrameworkClassAnnotations tfc = new TinyFrameworkClassAnnotations(); + TinyFrameworkAnnotations tfc = new TinyFrameworkAnnotations(); assertThat(tfc.addOne(1)).isEqualTo(2); assertThat(tfc.stub).isEqualTo(1); } // @Test // public void testDoesntCompile() { -// TinyFrameworkClassWithAnnot tfc = new TinyFrameworkClassWithAnnot(); +// TinyFrameworkAnnotations tfc = new TinyFrameworkAnnotations(); // // tfc.addOneInner(1); // Shouldn't compile. // tfc.toBeRemoved("abc"); // Shouldn't compile. @@ -45,19 +45,19 @@ public class TinyFrameworkClassWithAnnotTest { @Test public void testSubstitute() { - TinyFrameworkClassAnnotations tfc = new TinyFrameworkClassAnnotations(); + TinyFrameworkAnnotations tfc = new TinyFrameworkAnnotations(); assertThat(tfc.addTwo(1)).isEqualTo(3); } @Test public void testSubstituteNative() { - TinyFrameworkClassAnnotations tfc = new TinyFrameworkClassAnnotations(); + TinyFrameworkAnnotations tfc = new TinyFrameworkAnnotations(); assertThat(tfc.nativeAddThree(1)).isEqualTo(4); } @Test public void testVisibleButUsesUnsupportedMethod() { - TinyFrameworkClassAnnotations tfc = new TinyFrameworkClassAnnotations(); + TinyFrameworkAnnotations tfc = new TinyFrameworkAnnotations(); thrown.expect(RuntimeException.class); thrown.expectMessage("not yet supported"); diff --git a/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-test/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkClassTest.java b/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-test/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkClassTest.java index 1692c6e89e8c..dda5a0529278 100644 --- a/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-test/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkClassTest.java +++ b/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-test/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkClassTest.java @@ -20,7 +20,6 @@ import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.fail; import com.android.hoststubgen.test.tinyframework.R.Nested; -import com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses.SubClass; import org.junit.Rule; import org.junit.Test; @@ -88,42 +87,6 @@ public class TinyFrameworkClassTest { } @Test - public void testNestedClass1() { - assertThat(new TinyFrameworkNestedClasses().mSupplier.get()).isEqualTo(1); - } - - @Test - public void testNestedClass2() { - assertThat(TinyFrameworkNestedClasses.sSupplier.get()).isEqualTo(2); - } - - @Test - public void testNestedClass3() { - assertThat(new TinyFrameworkNestedClasses().getSupplier().get()).isEqualTo(3); - } - - @Test - public void testNestedClass4() { - assertThat(TinyFrameworkNestedClasses.getSupplier_static().get()).isEqualTo(4); - } - - @Test - public void testNestedClass5() { - assertThat((new TinyFrameworkNestedClasses()).new InnerClass().value).isEqualTo(5); - } - - @Test - public void testNestedClass6() { - assertThat(new TinyFrameworkNestedClasses.StaticNestedClass().value).isEqualTo(6); - } - - @Test - public void testNestedClass7() { - assertThat(TinyFrameworkNestedClasses.StaticNestedClass.getSupplier_static().get()) - .isEqualTo(7); - } - - @Test public void testLambda1() { assertThat(new TinyFrameworkLambdas().mSupplier.get()).isEqualTo(1); } @@ -220,18 +183,13 @@ public class TinyFrameworkClassTest { } @Test - public void testMethodCallBeforeSuperCall() { - assertThat(new SubClass(3).value).isEqualTo(3); - } - - @Test public void testClassLoadHook() { assertThat(TinyFrameworkClassWithInitializerStub.sInitialized).isTrue(); // Having this line before assertThat() will ensure these class are already loaded. var classes = new Class[]{ TinyFrameworkClassWithInitializerStub.class, - TinyFrameworkClassAnnotations.class, + TinyFrameworkAnnotations.class, TinyFrameworkForTextPolicy.class, }; diff --git a/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-test/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWideAnnotationsTest.java b/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-test/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWideAnnotationsTest.java new file mode 100644 index 000000000000..83753b5b1fb2 --- /dev/null +++ b/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-test/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWideAnnotationsTest.java @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.hoststubgen.test.tinyframework; + +import static com.google.common.truth.Truth.assertThat; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; + +public class TinyFrameworkClassWideAnnotationsTest { + @Rule + public ExpectedException thrown = ExpectedException.none(); + + @Test + public void testSimple() { + var tfc = new TinyFrameworkClassWideAnnotations(); + assertThat(tfc.addOne(1)).isEqualTo(2); + assertThat(tfc.stub).isEqualTo(1); + } + + @Test + public void testSubstitute() { + var tfc = new TinyFrameworkClassWideAnnotations(); + assertThat(tfc.addTwo(1)).isEqualTo(3); + } + + @Test + public void testVisibleButUsesUnsupportedMethod() { + var tfc = new TinyFrameworkClassWideAnnotations(); + + thrown.expect(RuntimeException.class); + thrown.expectMessage("not yet supported"); + tfc.visibleButUsesUnsupportedMethod(); + } + + @Test + public void testMethodCallBeforeSuperCall() { + assertThat(new TinyFrameworkNestedClasses.SubClass(3).value).isEqualTo(3); + } + + @Test + public void testNestedClass1() { + assertThat(new TinyFrameworkNestedClasses().mSupplier.get()).isEqualTo(1); + } + + @Test + public void testNestedClass2() { + assertThat(TinyFrameworkNestedClasses.sSupplier.get()).isEqualTo(2); + } + + @Test + public void testNestedClass3() { + assertThat(new TinyFrameworkNestedClasses().getSupplier().get()).isEqualTo(3); + } + + @Test + public void testNestedClass4() { + assertThat(TinyFrameworkNestedClasses.getSupplier_static().get()).isEqualTo(4); + } + + @Test + public void testNestedClass5() { + assertThat((new TinyFrameworkNestedClasses()).new InnerClass().value).isEqualTo(5); + } + + @Test + public void testNestedClass6() { + assertThat(new TinyFrameworkNestedClasses.StaticNestedClass().value).isEqualTo(6); + } + + @Test + public void testNestedClass7() { + assertThat(TinyFrameworkNestedClasses.StaticNestedClass.getSupplier_static().get()) + .isEqualTo(7); + } + + @Test + public void testNestedClass8() { + assertThat(new TinyFrameworkNestedClasses.StaticNestedClass.Double$NestedClass().value) + .isEqualTo(8); + } +} diff --git a/tools/hoststubgen/hoststubgen/test/com/android/hoststubgen/asm/AsmUtilsTest.kt b/tools/hoststubgen/hoststubgen/test/com/android/hoststubgen/asm/AsmUtilsTest.kt index 6b46c84bd0bb..5b2795c4cff2 100644 --- a/tools/hoststubgen/hoststubgen/test/com/android/hoststubgen/asm/AsmUtilsTest.kt +++ b/tools/hoststubgen/hoststubgen/test/com/android/hoststubgen/asm/AsmUtilsTest.kt @@ -23,18 +23,6 @@ import org.objectweb.asm.Opcodes.ACC_PUBLIC import org.objectweb.asm.Opcodes.ACC_STATIC class AsmUtilsTest { - private fun checkGetDirectOuterClassName(input: String, expected: String?) { - assertThat(getDirectOuterClassName(input)).isEqualTo(expected) - } - - @Test - fun testGetDirectOuterClassName() { - checkGetDirectOuterClassName("a", null) - checkGetDirectOuterClassName("a\$x", "a") - checkGetDirectOuterClassName("a.b.c\$x", "a.b.c") - checkGetDirectOuterClassName("a.b.c\$x\$y", "a.b.c\$x") - } - @Test fun testVisibility() { fun test(access: Int, expected: Visibility) { |