diff options
75 files changed, 1594 insertions, 541 deletions
diff --git a/Android.bp b/Android.bp index ea6a6319718f..980aa045dc79 100644 --- a/Android.bp +++ b/Android.bp @@ -600,7 +600,7 @@ java_defaults { "telephony/java/com/android/internal/telephony/IPhoneSubInfo.aidl", "telephony/java/com/android/internal/telephony/ISms.aidl", "telephony/java/com/android/internal/telephony/ISub.aidl", - "telephony/java/com/android/internal/telephony/IAns.aidl", + "telephony/java/com/android/internal/telephony/IOns.aidl", "telephony/java/com/android/internal/telephony/ITelephony.aidl", "telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl", "telephony/java/com/android/internal/telephony/IWapPushManager.aidl", diff --git a/api/current.txt b/api/current.txt index 0ff1743c2a39..8ee83daeb1dc 100644 --- a/api/current.txt +++ b/api/current.txt @@ -7379,7 +7379,9 @@ package android.app.role { method public boolean isRoleHeld(java.lang.String); field public static final java.lang.String ROLE_BROWSER = "android.app.role.BROWSER"; field public static final java.lang.String ROLE_DIALER = "android.app.role.DIALER"; + field public static final java.lang.String ROLE_EMERGENCY = "android.app.role.EMERGENCY"; field public static final java.lang.String ROLE_GALLERY = "android.app.role.GALLERY"; + field public static final java.lang.String ROLE_HOME = "android.app.role.HOME"; field public static final java.lang.String ROLE_MUSIC = "android.app.role.MUSIC"; field public static final java.lang.String ROLE_SMS = "android.app.role.SMS"; } diff --git a/api/system-current.txt b/api/system-current.txt index b190e9f5971f..a4b39782433f 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -1283,6 +1283,7 @@ package android.content { field public static final java.lang.String EXTRA_ORIGINATING_UID = "android.intent.extra.ORIGINATING_UID"; field public static final java.lang.String EXTRA_PACKAGES = "android.intent.extra.PACKAGES"; field public static final java.lang.String EXTRA_PERMISSION_NAME = "android.intent.extra.PERMISSION_NAME"; + field public static final java.lang.String EXTRA_PERMISSION_GROUP_NAME = "android.intent.extra.PERMISSION_GROUP_NAME"; field public static final java.lang.String EXTRA_REASON = "android.intent.extra.REASON"; field public static final java.lang.String EXTRA_REMOTE_CALLBACK = "android.intent.extra.REMOTE_CALLBACK"; field public static final java.lang.String EXTRA_RESULT_NEEDED = "android.intent.extra.RESULT_NEEDED"; @@ -6343,6 +6344,18 @@ package android.telephony { field public static final int WIFI_LOST = 59; // 0x3b } + public final class LteVopsSupportInfo implements android.os.Parcelable { + ctor public LteVopsSupportInfo(int, int); + method public int describeContents(); + method public int getEmcBearerSupport(); + method public int getVopsSupport(); + method public void writeToParcel(android.os.Parcel, int); + field public static final android.os.Parcelable.Creator<android.telephony.LteVopsSupportInfo> CREATOR; + field public static final int LTE_STATUS_NOT_AVAILABLE = 1; // 0x1 + field public static final int LTE_STATUS_NOT_SUPPORTED = 3; // 0x3 + field public static final int LTE_STATUS_SUPPORTED = 2; // 0x2 + } + public class MbmsDownloadSession implements java.lang.AutoCloseable { field public static final java.lang.String MBMS_DOWNLOAD_SERVICE_ACTION = "android.telephony.action.EmbmsDownload"; } diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto index fa3be26a96f7..f3478673cb49 100644 --- a/cmds/statsd/src/atoms.proto +++ b/cmds/statsd/src/atoms.proto @@ -216,7 +216,7 @@ message Atom { NumFingerprints num_fingerprints = 10031; DiskIo disk_io = 10032; PowerProfile power_profile = 10033; - ProcStats proc_stats_pkg_proc = 10034; + ProcStatsPkgProc proc_stats_pkg_proc = 10034; ProcessCpuTime process_cpu_time = 10035; NativeProcessMemoryState native_process_memory_state = 10036; CpuTimePerThreadFreq cpu_time_per_thread_freq = 10037; @@ -3272,6 +3272,13 @@ message ProcStats { optional ProcessStatsSectionProto proc_stats_section = 1; } +/** + * Pulled from ProcessStatsService.java + */ +message ProcStatsPkgProc { + optional ProcessStatsSectionProto proc_stats_section = 1; +} + message PowerProfileProto { optional double cpu_suspend = 1; diff --git a/core/java/android/app/ActivityManagerInternal.java b/core/java/android/app/ActivityManagerInternal.java index 9d44e58112c5..c90e40411240 100644 --- a/core/java/android/app/ActivityManagerInternal.java +++ b/core/java/android/app/ActivityManagerInternal.java @@ -258,8 +258,8 @@ public abstract class ActivityManagerInternal { Bundle resultExtras, String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky, int userId, boolean allowBackgroundActivityStarts); public abstract ComponentName startServiceInPackage(int uid, Intent service, - String resolvedType, boolean fgRequired, String callingPackage, int userId) - throws TransactionTooLargeException; + String resolvedType, boolean fgRequired, String callingPackage, int userId, + boolean allowBackgroundActivityStarts) throws TransactionTooLargeException; public abstract void disconnectActivityFromServices(Object connectionHolder); public abstract void cleanUpServices(int userId, ComponentName component, Intent baseIntent); diff --git a/core/java/android/app/role/RoleManager.java b/core/java/android/app/role/RoleManager.java index f14c56892807..27581fc0088a 100644 --- a/core/java/android/app/role/RoleManager.java +++ b/core/java/android/app/role/RoleManager.java @@ -68,57 +68,9 @@ public final class RoleManager { private static final String LOG_TAG = RoleManager.class.getSimpleName(); /** - * The name of the proxy calling role. - * <p> - * A proxy calling app implements the {@link android.telecom.CallRedirectionService} API and - * provides a means to re-write the phone number for an outgoing call to place the call through - * a proxy calling service. - * <p> - * A single app may fill this role at any one time. - * @hide - */ - public static final String ROLE_PROXY_CALLING_APP = "android.app.role.PROXY_CALLING_APP"; - - /** - * The name of the call screening and caller id role. - * <p> - * A call screening and caller id app implements the - * {@link android.telecom.CallScreeningService} API. - * <p> - * A single app may fill this role at any one time. - * @hide - */ - public static final String ROLE_CALL_SCREENING_APP = "android.app.role.CALL_SCREENING_APP"; - - /** - * The name of the call companion app role. - * <p> - * A call companion app provides no user interface for calls, but will be bound to by Telecom - * when there are active calls on the device. Companion apps for wearable devices are an - * acceptable use-case. A call companion app implements the - * {@link android.telecom.InCallService} API. - * <p> - * Multiple apps app may fill this role at any one time. - * @hide - */ - public static final String ROLE_CALL_COMPANION_APP = "android.app.role.CALL_COMPANION_APP"; - - /** - * The name of the car mode dialer app role. - * <p> - * Similar to the {@link #ROLE_DIALER} role, this role determines which app is responsible for - * showing the user interface for ongoing calls on the device. This app filling this role is - * only used when the device is in car mode (see - * {@link android.app.UiModeManager#ACTION_ENTER_CAR_MODE} for more information). An app - * filling this role must implement the {@link android.telecom.InCallService} API. - * <p> - * A single app may fill this role at any one time. - * @hide - */ - public static final String ROLE_CAR_MODE_DIALER_APP = "android.app.role.CAR_MODE_DIALER_APP"; - - /** * The name of the dialer role. + * + * @see Intent#ACTION_DIAL */ public static final String ROLE_DIALER = "android.app.role.DIALER"; @@ -151,6 +103,75 @@ public final class RoleManager { public static final String ROLE_MUSIC = "android.app.role.MUSIC"; /** + * The name of the home role. + * + * @see Intent#CATEGORY_HOME + */ + public static final String ROLE_HOME = "android.app.role.HOME"; + + /** + * The name of the emergency role + * + * @see android.telephony.TelephonyManager#ACTION_EMERGENCY_ASSISTANCE + */ + public static final String ROLE_EMERGENCY = "android.app.role.EMERGENCY"; + + /** + * The name of the car mode dialer app role. + * <p> + * Similar to the {@link #ROLE_DIALER dialer} role, this role determines which app is + * responsible for showing the user interface for ongoing calls on the device. It is only used + * when the device is in car mode. + * + * @see #ROLE_DIALER + * @see android.app.UiModeManager#ACTION_ENTER_CAR_MODE + * @see android.telecom.InCallService + * + * TODO: STOPSHIP: Make name of required roles public API + * @hide + */ + public static final String ROLE_CAR_MODE_DIALER_APP = "android.app.role.CAR_MODE_DIALER_APP"; + + /** + * The name of the proxy calling role. + * <p> + * A proxy calling app provides a means to re-write the phone number for an outgoing call to + * place the call through a proxy calling service. + * + * @see android.telecom.CallRedirectionService + * + * TODO: STOPSHIP: Make name of required roles public API + * @hide + */ + public static final String ROLE_PROXY_CALLING_APP = "android.app.role.PROXY_CALLING_APP"; + + /** + * The name of the call screening and caller id role. + * + * @see android.telecom.CallScreeningService + * + * TODO: STOPSHIP: Make name of required roles public API + * @hide + */ + public static final String ROLE_CALL_SCREENING_APP = "android.app.role.CALL_SCREENING_APP"; + + /** + * The name of the call companion app role. + * <p> + * A call companion app provides no user interface for calls, but will be bound to by Telecom + * when there are active calls on the device. Companion apps for wearable devices are an + * acceptable use-case. + * <p> + * Multiple apps may hold this role at the same time. + * + * @see android.telecom.InCallService + * + * TODO: STOPSHIP: Make name of required roles public API + * @hide + */ + public static final String ROLE_CALL_COMPANION_APP = "android.app.role.CALL_COMPANION_APP"; + + /** * The action used to request user approval of a role for an application. * * @hide diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java index de810e8a02e7..e37126b8c2e7 100644 --- a/core/java/android/content/Intent.java +++ b/core/java/android/content/Intent.java @@ -1953,16 +1953,35 @@ public class Intent implements Parcelable, Cloneable { public static final String EXTRA_PERMISSION_NAME = "android.intent.extra.PERMISSION_NAME"; /** + * Intent extra: The name of a permission group. + * <p> + * Type: String + * </p> + * + * @hide + */ + @SystemApi + public static final String EXTRA_PERMISSION_GROUP_NAME = + "android.intent.extra.PERMISSION_GROUP_NAME"; + + /** * Activity action: Launch UI to review app uses of permissions. * <p> * Input: {@link #EXTRA_PERMISSION_NAME} specifies the permission name - * that will be displayed by the launched UI. + * that will be displayed by the launched UI. Do not pass both this and + * {@link #EXTRA_PERMISSION_GROUP_NAME} . + * </p> + * <p> + * Input: {@link #EXTRA_PERMISSION_GROUP_NAME} specifies the permission group name + * that will be displayed by the launched UI. Do not pass both this and + * {@link #EXTRA_PERMISSION_NAME}. * </p> * <p> * Output: Nothing. * </p> * * @see #EXTRA_PERMISSION_NAME + * @see #EXTRA_PERMISSION_GROUP_NAME * * @hide */ diff --git a/core/java/android/hardware/face/FaceManager.java b/core/java/android/hardware/face/FaceManager.java index 1630b0603f3a..c9a7830d50f5 100644 --- a/core/java/android/hardware/face/FaceManager.java +++ b/core/java/android/hardware/face/FaceManager.java @@ -163,8 +163,8 @@ public class FaceManager implements BiometricAuthenticator, BiometricFaceConstan mAuthenticationCallback = callback; mCryptoObject = crypto; long sessionId = crypto != null ? crypto.getOpId() : 0; - mService.authenticate(mToken, sessionId, mServiceReceiver, flags, - mContext.getOpPackageName()); + mService.authenticate(mToken, sessionId, mContext.getUserId(), mServiceReceiver, + flags, mContext.getOpPackageName()); } catch (RemoteException e) { Log.w(TAG, "Remote exception while authenticating: ", e); if (callback != null) { diff --git a/core/java/android/hardware/face/IFaceService.aidl b/core/java/android/hardware/face/IFaceService.aidl index a1c88f81e3e7..f67760a8fafc 100644 --- a/core/java/android/hardware/face/IFaceService.aidl +++ b/core/java/android/hardware/face/IFaceService.aidl @@ -27,7 +27,7 @@ import android.hardware.face.Face; */ interface IFaceService { // Authenticate the given sessionId with a face - void authenticate(IBinder token, long sessionId, + void authenticate(IBinder token, long sessionId, int userid, IFaceServiceReceiver receiver, int flags, String opPackageName); // This method prepares the service to start authenticating, but doesn't start authentication. diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index 4649776b3d50..574ccaf8d1cc 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -9369,8 +9369,7 @@ public final class Settings { "hdmi_control_auto_wakeup_enabled"; /** - * Whether TV or Audio System will also turn off other CEC devices when it goes to standby - * mode. + * Whether TV will also turn off other CEC devices when it goes to standby mode. * (0 = false, 1 = true) * * @hide @@ -9379,15 +9378,6 @@ public final class Settings { "hdmi_control_auto_device_off_enabled"; /** - * Whether Audio System will also turn off TV when it goes to standby mode. - * (0 = false, 1 = true) - * - * @hide - */ - public static final String HDMI_CONTROL_AUTO_TV_OFF_ENABLED = - "hdmi_control_auto_tv_off_enabled"; - - /** * If <b>true</b>, enables out-of-the-box execution for priv apps. * Default: false * Values: 0 = false, 1 = true diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java index acad5d76f0b5..ff5120d09e25 100644 --- a/core/java/android/view/SurfaceControl.java +++ b/core/java/android/view/SurfaceControl.java @@ -58,7 +58,7 @@ import java.io.Closeable; /** * SurfaceControl - * @hide + * @hide */ public class SurfaceControl implements Parcelable { private static final String TAG = "SurfaceControl"; @@ -186,6 +186,7 @@ public class SurfaceControl implements Parcelable { /** * Surface creation flag: Surface is created hidden + * @hide */ @UnsupportedAppUsage public static final int HIDDEN = 0x00000004; @@ -196,7 +197,7 @@ public class SurfaceControl implements Parcelable { * from another process. In particular, screenshots and VNC servers will * be disabled, but other measures can take place, for instance the * surface might not be hardware accelerated. - * + * @hide */ public static final int SECURE = 0x00000080; @@ -220,7 +221,7 @@ public class SurfaceControl implements Parcelable { * pixel. * <p> * In some rare situations, a non pre-multiplied surface is preferable. - * + * @hide */ public static final int NON_PREMULTIPLIED = 0x00000100; @@ -240,6 +241,7 @@ public class SurfaceControl implements Parcelable { * </ul> * If the underlying buffer lacks an alpha channel, the OPAQUE flag is effectively * set automatically. + * @hide */ public static final int OPAQUE = 0x00000400; @@ -248,6 +250,7 @@ public class SurfaceControl implements Parcelable { * external display sink. If a hardware-protected path is not available, * then this surface will not be displayed on the external sink. * + * @hide */ public static final int PROTECTED_APP = 0x00000800; @@ -255,6 +258,7 @@ public class SurfaceControl implements Parcelable { /** * Surface creation flag: Window represents a cursor glyph. + * @hide */ public static final int CURSOR_WINDOW = 0x00002000; @@ -262,6 +266,7 @@ public class SurfaceControl implements Parcelable { * Surface creation flag: Creates a normal surface. * This is the default. * + * @hide */ public static final int FX_SURFACE_NORMAL = 0x00000000; @@ -271,6 +276,7 @@ public class SurfaceControl implements Parcelable { * in {@link #setAlpha}. It is an error to lock a Dim surface, since it * doesn't have a backing store. * + * @hide */ public static final int FX_SURFACE_DIM = 0x00020000; @@ -278,12 +284,14 @@ public class SurfaceControl implements Parcelable { * Surface creation flag: Creates a container surface. * This surface will have no buffers and will only be used * as a container for other surfaces, or for its InputInfo. + * @hide */ public static final int FX_SURFACE_CONTAINER = 0x00080000; /** * Mask used for FX values above. * + * @hide */ public static final int FX_SURFACE_MASK = 0x000F0000; @@ -309,12 +317,14 @@ public class SurfaceControl implements Parcelable { /** * Built-in physical display id: Main display. * Use only with {@link SurfaceControl#getBuiltInDisplay(int)}. + * @hide */ public static final int BUILT_IN_DISPLAY_ID_MAIN = 0; /** * Built-in physical display id: Attached HDMI display. * Use only with {@link SurfaceControl#getBuiltInDisplay(int)}. + * @hide */ public static final int BUILT_IN_DISPLAY_ID_HDMI = 1; @@ -323,30 +333,35 @@ public class SurfaceControl implements Parcelable { /** * Display power mode off: used while blanking the screen. * Use only with {@link SurfaceControl#setDisplayPowerMode}. + * @hide */ public static final int POWER_MODE_OFF = 0; /** * Display power mode doze: used while putting the screen into low power mode. * Use only with {@link SurfaceControl#setDisplayPowerMode}. + * @hide */ public static final int POWER_MODE_DOZE = 1; /** * Display power mode normal: used while unblanking the screen. * Use only with {@link SurfaceControl#setDisplayPowerMode}. + * @hide */ public static final int POWER_MODE_NORMAL = 2; /** * Display power mode doze: used while putting the screen into a suspended * low power mode. Use only with {@link SurfaceControl#setDisplayPowerMode}. + * @hide */ public static final int POWER_MODE_DOZE_SUSPEND = 3; /** * Display power mode on: used while putting the screen into a suspended * full power mode. Use only with {@link SurfaceControl#setDisplayPowerMode}. + * @hide */ public static final int POWER_MODE_ON_SUSPEND = 4; @@ -366,6 +381,9 @@ public class SurfaceControl implements Parcelable { mNativeObject = nativeObject; } + /** + * @hide + */ public void copyFrom(SurfaceControl other) { mName = other.mName; mWidth = other.mWidth; @@ -375,6 +393,7 @@ public class SurfaceControl implements Parcelable { /** * Builder class for {@link SurfaceControl} objects. + * @hide */ public static class Builder { private SurfaceSession mSession; @@ -391,6 +410,7 @@ public class SurfaceControl implements Parcelable { * Begin building a SurfaceControl with a given {@link SurfaceSession}. * * @param session The {@link SurfaceSession} with which to eventually construct the surface. + * @hide */ public Builder(SurfaceSession session) { mSession = session; @@ -398,6 +418,7 @@ public class SurfaceControl implements Parcelable { /** * Construct a new {@link SurfaceControl} with the set parameters. + * @hide */ public SurfaceControl build() { if (mWidth < 0 || mHeight < 0) { @@ -416,6 +437,7 @@ public class SurfaceControl implements Parcelable { * Set a debugging-name for the SurfaceControl. * * @param name A name to identify the Surface in debugging. + * @hide */ public Builder setName(String name) { mName = name; @@ -427,6 +449,7 @@ public class SurfaceControl implements Parcelable { * * @param width The buffer width in pixels. * @param height The buffer height in pixels. + * @hide */ public Builder setBufferSize(int width, int height) { if (width < 0 || height < 0) { @@ -441,6 +464,7 @@ public class SurfaceControl implements Parcelable { /** * Set the pixel format of the controlled surface's buffers, using constants from * {@link android.graphics.PixelFormat}. + * @hide */ public Builder setFormat(@PixelFormat.Format int format) { mFormat = format; @@ -454,6 +478,7 @@ public class SurfaceControl implements Parcelable { * not be displayed. * * @param protectedContent Whether to require a protected sink. + * @hide */ public Builder setProtected(boolean protectedContent) { if (protectedContent) { @@ -469,6 +494,7 @@ public class SurfaceControl implements Parcelable { * will prevent the surfaces content from being copied by another process. In * particular screenshots and VNC servers will be disabled. This is however * not a complete prevention of readback as {@link #setProtected}. + * @hide */ public Builder setSecure(boolean secure) { if (secure) { @@ -501,6 +527,7 @@ public class SurfaceControl implements Parcelable { * If the underlying buffer lacks an alpha channel, it is as if setOpaque(true) * were set automatically. * @param opaque Whether the Surface is OPAQUE. + * @hide */ public Builder setOpaque(boolean opaque) { if (opaque) { @@ -519,6 +546,7 @@ public class SurfaceControl implements Parcelable { * of the parent. * * @param parent The parent control. + * @hide */ public Builder setParent(SurfaceControl parent) { mParent = parent; @@ -534,6 +562,7 @@ public class SurfaceControl implements Parcelable { * * @param windowType A window-type * @param ownerUid UID of the window owner. + * @hide */ public Builder setMetadata(int windowType, int ownerUid) { if (UserHandle.getAppId(Process.myUid()) != Process.SYSTEM_UID) { @@ -552,6 +581,7 @@ public class SurfaceControl implements Parcelable { * solid color (that is, solid before plane alpha). Currently that color is black. * * @param isColorLayer Whether to create a color layer. + * @hide */ public Builder setColorLayer(boolean isColorLayer) { if (isColorLayer) { @@ -573,6 +603,7 @@ public class SurfaceControl implements Parcelable { * as a parent of renderable layers. * * @param isContainerLayer Whether to create a container layer. + * @hide */ public Builder setContainerLayer(boolean isContainerLayer) { if (isContainerLayer) { @@ -592,6 +623,7 @@ public class SurfaceControl implements Parcelable { * * TODO: Finish conversion to individual builder methods? * @param flags The combined flags + * @hide */ public Builder setFlags(int flags) { mFlags = flags; @@ -660,9 +692,11 @@ public class SurfaceControl implements Parcelable { mCloseGuard.open("release"); } - // This is a transfer constructor, useful for transferring a live SurfaceControl native - // object to another Java wrapper which could have some different behavior, e.g. - // event logging. + /** This is a transfer constructor, useful for transferring a live SurfaceControl native + * object to another Java wrapper which could have some different behavior, e.g. + * event logging. + * @hide + */ public SurfaceControl(SurfaceControl other) { mName = other.mName; mWidth = other.mWidth; @@ -678,10 +712,16 @@ public class SurfaceControl implements Parcelable { mCloseGuard.open("release"); } + /** + * @hide + */ public SurfaceControl() { mCloseGuard.open("release"); } + /** + * @hide + */ public void readFromParcel(Parcel in) { if (in == null) { throw new IllegalArgumentException("source must not be null"); @@ -698,11 +738,17 @@ public class SurfaceControl implements Parcelable { assignNativeObject(object); } + /** + * @hide + */ @Override public int describeContents() { return 0; } + /** + * @hide + */ @Override public void writeToParcel(Parcel dest, int flags) { dest.writeString(mName); @@ -735,6 +781,9 @@ public class SurfaceControl implements Parcelable { proto.end(token); } + /** + * @hide + */ public static final Creator<SurfaceControl> CREATOR = new Creator<SurfaceControl>() { public SurfaceControl createFromParcel(Parcel in) { @@ -746,6 +795,9 @@ public class SurfaceControl implements Parcelable { } }; + /** + * @hide + */ @Override protected void finalize() throws Throwable { try { @@ -764,6 +816,7 @@ public class SurfaceControl implements Parcelable { * Release the local reference to the server-side surface. * Always call release() when you're done with a Surface. * This will make the surface invalid. + * @hide */ public void release() { if (mNativeObject != 0) { @@ -777,6 +830,7 @@ public class SurfaceControl implements Parcelable { * Free all server-side state associated with this surface and * release this object's reference. This method can only be * called from the process that created the service. + * @hide */ public void destroy() { if (mNativeObject != 0) { @@ -788,6 +842,7 @@ public class SurfaceControl implements Parcelable { /** * Disconnect any client still connected to the surface. + * @hide */ public void disconnect() { if (mNativeObject != 0) { @@ -800,6 +855,9 @@ public class SurfaceControl implements Parcelable { "mNativeObject is null. Have you called release() already?"); } + /** + * @hide + */ public boolean isValid() { return mNativeObject != 0; } @@ -809,7 +867,9 @@ public class SurfaceControl implements Parcelable { * needs to be inside open/closeTransaction block */ - /** start a transaction */ + /** start a transaction + * @hide + */ @UnsupportedAppUsage public static void openTransaction() { synchronized (SurfaceControl.class) { @@ -838,6 +898,7 @@ public class SurfaceControl implements Parcelable { * This clears the supplied transaction in an identical fashion to {@link Transaction#merge}. * <p> * This is a utility for interop with legacy-code and will go away with the Global Transaction. + * @hide */ @Deprecated public static void mergeToGlobalTransaction(Transaction t) { @@ -846,46 +907,69 @@ public class SurfaceControl implements Parcelable { } } - /** end a transaction */ + /** end a transaction + * @hide + */ @UnsupportedAppUsage public static void closeTransaction() { closeTransaction(false); } + /** + * @hide + */ public static void closeTransactionSync() { closeTransaction(true); } + /** + * @hide + */ public void deferTransactionUntil(IBinder handle, long frame) { synchronized(SurfaceControl.class) { sGlobalTransaction.deferTransactionUntil(this, handle, frame); } } + /** + * @hide + */ public void deferTransactionUntil(Surface barrier, long frame) { synchronized(SurfaceControl.class) { sGlobalTransaction.deferTransactionUntilSurface(this, barrier, frame); } } + /** + * @hide + */ public void reparentChildren(IBinder newParentHandle) { synchronized(SurfaceControl.class) { sGlobalTransaction.reparentChildren(this, newParentHandle); } } + /** + * @hide + */ public void reparent(IBinder newParentHandle) { synchronized(SurfaceControl.class) { sGlobalTransaction.reparent(this, newParentHandle); } } + /** + * @hide + */ public void detachChildren() { synchronized(SurfaceControl.class) { sGlobalTransaction.detachChildren(this); } } + /** + * @hide + */ public void setOverrideScalingMode(int scalingMode) { checkNotReleased(); synchronized(SurfaceControl.class) { @@ -893,16 +977,25 @@ public class SurfaceControl implements Parcelable { } } + /** + * @hide + */ public IBinder getHandle() { return nativeGetHandle(mNativeObject); } + /** + * @hide + */ public static void setAnimationTransaction() { synchronized (SurfaceControl.class) { sGlobalTransaction.setAnimationTransaction(); } } + /** + * @hide + */ @UnsupportedAppUsage public void setLayer(int zorder) { checkNotReleased(); @@ -911,6 +1004,9 @@ public class SurfaceControl implements Parcelable { } } + /** + * @hide + */ public void setRelativeLayer(SurfaceControl relativeTo, int zorder) { checkNotReleased(); synchronized(SurfaceControl.class) { @@ -918,6 +1014,9 @@ public class SurfaceControl implements Parcelable { } } + /** + * @hide + */ @UnsupportedAppUsage public void setPosition(float x, float y) { checkNotReleased(); @@ -926,6 +1025,9 @@ public class SurfaceControl implements Parcelable { } } + /** + * @hide + */ public void setGeometryAppliesWithResize() { checkNotReleased(); synchronized(SurfaceControl.class) { @@ -933,6 +1035,9 @@ public class SurfaceControl implements Parcelable { } } + /** + * @hide + */ public void setBufferSize(int w, int h) { checkNotReleased(); synchronized(SurfaceControl.class) { @@ -940,6 +1045,9 @@ public class SurfaceControl implements Parcelable { } } + /** + * @hide + */ @UnsupportedAppUsage public void hide() { checkNotReleased(); @@ -948,6 +1056,9 @@ public class SurfaceControl implements Parcelable { } } + /** + * @hide + */ @UnsupportedAppUsage public void show() { checkNotReleased(); @@ -956,6 +1067,9 @@ public class SurfaceControl implements Parcelable { } } + /** + * @hide + */ public void setTransparentRegionHint(Region region) { checkNotReleased(); synchronized(SurfaceControl.class) { @@ -963,24 +1077,39 @@ public class SurfaceControl implements Parcelable { } } + /** + * @hide + */ public boolean clearContentFrameStats() { checkNotReleased(); return nativeClearContentFrameStats(mNativeObject); } + /** + * @hide + */ public boolean getContentFrameStats(WindowContentFrameStats outStats) { checkNotReleased(); return nativeGetContentFrameStats(mNativeObject, outStats); } + /** + * @hide + */ public static boolean clearAnimationFrameStats() { return nativeClearAnimationFrameStats(); } + /** + * @hide + */ public static boolean getAnimationFrameStats(WindowAnimationFrameStats outStats) { return nativeGetAnimationFrameStats(outStats); } + /** + * @hide + */ public void setAlpha(float alpha) { checkNotReleased(); synchronized(SurfaceControl.class) { @@ -988,6 +1117,9 @@ public class SurfaceControl implements Parcelable { } } + /** + * @hide + */ public void setColor(@Size(3) float[] color) { checkNotReleased(); synchronized (SurfaceControl.class) { @@ -995,6 +1127,9 @@ public class SurfaceControl implements Parcelable { } } + /** + * @hide + */ public void setMatrix(float dsdx, float dtdx, float dtdy, float dsdy) { checkNotReleased(); synchronized(SurfaceControl.class) { @@ -1007,6 +1142,7 @@ public class SurfaceControl implements Parcelable { * * @param matrix The matrix to apply. * @param float9 An array of 9 floats to be used to extract the values from the matrix. + * @hide */ public void setMatrix(Matrix matrix, float[] float9) { checkNotReleased(); @@ -1022,6 +1158,7 @@ public class SurfaceControl implements Parcelable { * Sets the color transform for the Surface. * @param matrix A float array with 9 values represents a 3x3 transform matrix * @param translation A float array with 3 values represents a translation vector + * @hide */ public void setColorTransform(@Size(9) float[] matrix, @Size(3) float[] translation) { checkNotReleased(); @@ -1037,6 +1174,7 @@ public class SurfaceControl implements Parcelable { * constrained by the size of its parent bounds. * * @param crop Bounds of the crop to apply. + * @hide */ public void setWindowCrop(Rect crop) { checkNotReleased(); @@ -1050,6 +1188,7 @@ public class SurfaceControl implements Parcelable { * * @param width width of crop rect * @param height height of crop rect + * @hide */ public void setWindowCrop(int width, int height) { checkNotReleased(); @@ -1062,6 +1201,7 @@ public class SurfaceControl implements Parcelable { * Sets the corner radius of a {@link SurfaceControl}. * * @param cornerRadius Corner radius in pixels. + * @hide */ public void setCornerRadius(float cornerRadius) { checkNotReleased(); @@ -1070,6 +1210,9 @@ public class SurfaceControl implements Parcelable { } } + /** + * @hide + */ public void setLayerStack(int layerStack) { checkNotReleased(); synchronized(SurfaceControl.class) { @@ -1077,6 +1220,9 @@ public class SurfaceControl implements Parcelable { } } + /** + * @hide + */ public void setOpaque(boolean isOpaque) { checkNotReleased(); @@ -1085,6 +1231,9 @@ public class SurfaceControl implements Parcelable { } } + /** + * @hide + */ public void setSecure(boolean isSecure) { checkNotReleased(); @@ -1093,18 +1242,27 @@ public class SurfaceControl implements Parcelable { } } + /** + * @hide + */ public int getWidth() { synchronized (mSizeLock) { return mWidth; } } + /** + * @hide + */ public int getHeight() { synchronized (mSizeLock) { return mHeight; } } + /** + * @hide + */ @Override public String toString() { return "Surface(name=" + mName + ")/@0x" + @@ -1120,38 +1278,85 @@ public class SurfaceControl implements Parcelable { * Describes the properties of a physical display known to surface flinger. */ public static final class PhysicalDisplayInfo { + /** + * @hide + */ @UnsupportedAppUsage public int width; + + /** + * @hide + */ @UnsupportedAppUsage public int height; + + /** + * @hide + */ @UnsupportedAppUsage public float refreshRate; + + /** + * @hide + */ @UnsupportedAppUsage public float density; + + /** + * @hide + */ @UnsupportedAppUsage public float xDpi; + + /** + * @hide + */ @UnsupportedAppUsage public float yDpi; + + /** + * @hide + */ @UnsupportedAppUsage public boolean secure; + + /** + * @hide + */ @UnsupportedAppUsage public long appVsyncOffsetNanos; + + /** + * @hide + */ @UnsupportedAppUsage public long presentationDeadlineNanos; + /** + * @hide + */ @UnsupportedAppUsage public PhysicalDisplayInfo() { } + /** + * @hide + */ public PhysicalDisplayInfo(PhysicalDisplayInfo other) { copyFrom(other); } + /** + * @hide + */ @Override public boolean equals(Object o) { return o instanceof PhysicalDisplayInfo && equals((PhysicalDisplayInfo)o); } + /** + * @hide + */ public boolean equals(PhysicalDisplayInfo other) { return other != null && width == other.width @@ -1165,11 +1370,17 @@ public class SurfaceControl implements Parcelable { && presentationDeadlineNanos == other.presentationDeadlineNanos; } + /** + * @hide + */ @Override public int hashCode() { return 0; // don't care } + /** + * @hide + */ public void copyFrom(PhysicalDisplayInfo other) { width = other.width; height = other.height; @@ -1182,7 +1393,9 @@ public class SurfaceControl implements Parcelable { presentationDeadlineNanos = other.presentationDeadlineNanos; } - // For debugging purposes + /** + * @hide + */ @Override public String toString() { return "PhysicalDisplayInfo{" + width + " x " + height + ", " + refreshRate + " fps, " @@ -1192,6 +1405,9 @@ public class SurfaceControl implements Parcelable { } } + /** + * @hide + */ public static void setDisplayPowerMode(IBinder displayToken, int mode) { if (displayToken == null) { throw new IllegalArgumentException("displayToken must not be null"); @@ -1199,6 +1415,9 @@ public class SurfaceControl implements Parcelable { nativeSetDisplayPowerMode(displayToken, mode); } + /** + * @hide + */ @UnsupportedAppUsage public static SurfaceControl.PhysicalDisplayInfo[] getDisplayConfigs(IBinder displayToken) { if (displayToken == null) { @@ -1207,6 +1426,9 @@ public class SurfaceControl implements Parcelable { return nativeGetDisplayConfigs(displayToken); } + /** + * @hide + */ public static int getActiveConfig(IBinder displayToken) { if (displayToken == null) { throw new IllegalArgumentException("displayToken must not be null"); @@ -1253,6 +1475,9 @@ public class SurfaceControl implements Parcelable { } + /** + * @hide + */ public static boolean setActiveConfig(IBinder displayToken, int id) { if (displayToken == null) { throw new IllegalArgumentException("displayToken must not be null"); @@ -1260,6 +1485,9 @@ public class SurfaceControl implements Parcelable { return nativeSetActiveConfig(displayToken, id); } + /** + * @hide + */ public static int[] getDisplayColorModes(IBinder displayToken) { if (displayToken == null) { throw new IllegalArgumentException("displayToken must not be null"); @@ -1267,6 +1495,9 @@ public class SurfaceControl implements Parcelable { return nativeGetDisplayColorModes(displayToken); } + /** + * @hide + */ public static int getActiveColorMode(IBinder displayToken) { if (displayToken == null) { throw new IllegalArgumentException("displayToken must not be null"); @@ -1274,6 +1505,9 @@ public class SurfaceControl implements Parcelable { return nativeGetActiveColorMode(displayToken); } + /** + * @hide + */ public static boolean setActiveColorMode(IBinder displayToken, int colorMode) { if (displayToken == null) { throw new IllegalArgumentException("displayToken must not be null"); @@ -1281,6 +1515,9 @@ public class SurfaceControl implements Parcelable { return nativeSetActiveColorMode(displayToken, colorMode); } + /** + * @hide + */ @UnsupportedAppUsage public static void setDisplayProjection(IBinder displayToken, int orientation, Rect layerStackRect, Rect displayRect) { @@ -1290,6 +1527,9 @@ public class SurfaceControl implements Parcelable { } } + /** + * @hide + */ @UnsupportedAppUsage public static void setDisplayLayerStack(IBinder displayToken, int layerStack) { synchronized (SurfaceControl.class) { @@ -1297,6 +1537,9 @@ public class SurfaceControl implements Parcelable { } } + /** + * @hide + */ @UnsupportedAppUsage public static void setDisplaySurface(IBinder displayToken, Surface surface) { synchronized (SurfaceControl.class) { @@ -1304,12 +1547,18 @@ public class SurfaceControl implements Parcelable { } } + /** + * @hide + */ public static void setDisplaySize(IBinder displayToken, int width, int height) { synchronized (SurfaceControl.class) { sGlobalTransaction.setDisplaySize(displayToken, width, height); } } + /** + * @hide + */ public static Display.HdrCapabilities getHdrCapabilities(IBinder displayToken) { if (displayToken == null) { throw new IllegalArgumentException("displayToken must not be null"); @@ -1317,6 +1566,9 @@ public class SurfaceControl implements Parcelable { return nativeGetHdrCapabilities(displayToken); } + /** + * @hide + */ @UnsupportedAppUsage public static IBinder createDisplay(String name, boolean secure) { if (name == null) { @@ -1325,6 +1577,9 @@ public class SurfaceControl implements Parcelable { return nativeCreateDisplay(name, secure); } + /** + * @hide + */ @UnsupportedAppUsage public static void destroyDisplay(IBinder displayToken) { if (displayToken == null) { @@ -1333,6 +1588,9 @@ public class SurfaceControl implements Parcelable { nativeDestroyDisplay(displayToken); } + /** + * @hide + */ @UnsupportedAppUsage public static IBinder getBuiltInDisplay(int builtInDisplayId) { return nativeGetBuiltInDisplay(builtInDisplayId); @@ -1340,6 +1598,7 @@ public class SurfaceControl implements Parcelable { /** * @see SurfaceControl#screenshot(IBinder, Surface, Rect, int, int, boolean, int) + * @hide */ public static void screenshot(IBinder display, Surface consumer) { screenshot(display, consumer, new Rect(), 0, 0, false, 0); @@ -1350,6 +1609,7 @@ public class SurfaceControl implements Parcelable { * * @param consumer The {@link Surface} to take the screenshot into. * @see SurfaceControl#screenshotToBuffer(IBinder, Rect, int, int, boolean, int) + * @hide */ public static void screenshot(IBinder display, Surface consumer, Rect sourceCrop, int width, int height, boolean useIdentityTransform, int rotation) { @@ -1368,6 +1628,7 @@ public class SurfaceControl implements Parcelable { /** * @see SurfaceControl#screenshot(Rect, int, int, boolean, int)} + * @hide */ @UnsupportedAppUsage public static Bitmap screenshot(Rect sourceCrop, int width, int height, int rotation) { @@ -1385,6 +1646,7 @@ public class SurfaceControl implements Parcelable { * {@link SurfaceControl#screenshotToBuffer(IBinder, Rect, int, int, boolean, int)}. * * @see SurfaceControl#screenshotToBuffer(IBinder, Rect, int, int, boolean, int)} + * @hide */ @UnsupportedAppUsage public static Bitmap screenshot(Rect sourceCrop, int width, int height, @@ -1428,6 +1690,7 @@ public class SurfaceControl implements Parcelable { * this is useful for returning screenshots that are independent of * device orientation. * @return Returns a GraphicBuffer that contains the captured content. + * @hide */ public static GraphicBuffer screenshotToBuffer(IBinder display, Rect sourceCrop, int width, int height, boolean useIdentityTransform, int rotation) { @@ -1459,12 +1722,16 @@ public class SurfaceControl implements Parcelable { * screen will be scaled up/down. * * @return Returns a GraphicBuffer that contains the layer capture. + * @hide */ public static GraphicBuffer captureLayers(IBinder layerHandleToken, Rect sourceCrop, float frameScale) { return nativeCaptureLayers(layerHandleToken, sourceCrop, frameScale); } + /** + * @hide + */ public static class Transaction implements Closeable { public static final NativeAllocationRegistry sRegistry = new NativeAllocationRegistry( Transaction.class.getClassLoader(), @@ -1474,6 +1741,9 @@ public class SurfaceControl implements Parcelable { private final ArrayMap<SurfaceControl, Point> mResizedSurfaces = new ArrayMap<>(); Runnable mFreeNativeResources; + /** + * @hide + */ @UnsupportedAppUsage public Transaction() { mNativeObject = nativeCreateTransaction(); @@ -1484,6 +1754,7 @@ public class SurfaceControl implements Parcelable { /** * Apply the transaction, clearing it's state, and making it usable * as a new transaction. + * @hide */ @UnsupportedAppUsage public void apply() { @@ -1493,6 +1764,7 @@ public class SurfaceControl implements Parcelable { /** * Close the transaction, if the transaction was not already applied this will cancel the * transaction. + * @hide */ @Override public void close() { @@ -1502,6 +1774,7 @@ public class SurfaceControl implements Parcelable { /** * Jankier version of apply. Avoid use (b/28068298). + * @hide */ public void apply(boolean sync) { applyResizedSurfaces(); @@ -1520,6 +1793,9 @@ public class SurfaceControl implements Parcelable { mResizedSurfaces.clear(); } + /** + * @hide + */ @UnsupportedAppUsage public Transaction show(SurfaceControl sc) { sc.checkNotReleased(); @@ -1527,6 +1803,9 @@ public class SurfaceControl implements Parcelable { return this; } + /** + * @hide + */ @UnsupportedAppUsage public Transaction hide(SurfaceControl sc) { sc.checkNotReleased(); @@ -1534,6 +1813,9 @@ public class SurfaceControl implements Parcelable { return this; } + /** + * @hide + */ @UnsupportedAppUsage public Transaction setPosition(SurfaceControl sc, float x, float y) { sc.checkNotReleased(); @@ -1541,6 +1823,9 @@ public class SurfaceControl implements Parcelable { return this; } + /** + * @hide + */ @UnsupportedAppUsage public Transaction setBufferSize(SurfaceControl sc, int w, int h) { sc.checkNotReleased(); @@ -1549,6 +1834,9 @@ public class SurfaceControl implements Parcelable { return this; } + /** + * @hide + */ @UnsupportedAppUsage public Transaction setLayer(SurfaceControl sc, int z) { sc.checkNotReleased(); @@ -1556,6 +1844,9 @@ public class SurfaceControl implements Parcelable { return this; } + /** + * @hide + */ public Transaction setRelativeLayer(SurfaceControl sc, SurfaceControl relativeTo, int z) { sc.checkNotReleased(); nativeSetRelativeLayer(mNativeObject, sc.mNativeObject, @@ -1563,6 +1854,9 @@ public class SurfaceControl implements Parcelable { return this; } + /** + * @hide + */ public Transaction setTransparentRegionHint(SurfaceControl sc, Region transparentRegion) { sc.checkNotReleased(); nativeSetTransparentRegionHint(mNativeObject, @@ -1570,6 +1864,9 @@ public class SurfaceControl implements Parcelable { return this; } + /** + * @hide + */ @UnsupportedAppUsage public Transaction setAlpha(SurfaceControl sc, float alpha) { sc.checkNotReleased(); @@ -1577,6 +1874,9 @@ public class SurfaceControl implements Parcelable { return this; } + /** + * @hide + */ public Transaction setInputWindowInfo(SurfaceControl sc, InputWindowHandle handle) { sc.checkNotReleased(); nativeSetInputWindowInfo(mNativeObject, sc.mNativeObject, handle); @@ -1592,12 +1892,16 @@ public class SurfaceControl implements Parcelable { * @param fromToken The token of a window that currently has touch focus. * @param toToken The token of the window that should receive touch focus in * place of the first. + * @hide */ public Transaction transferTouchFocus(IBinder fromToken, IBinder toToken) { nativeTransferTouchFocus(mNativeObject, fromToken, toToken); return this; } + /** + * @hide + */ @UnsupportedAppUsage public Transaction setMatrix(SurfaceControl sc, float dsdx, float dtdx, float dtdy, float dsdy) { @@ -1607,6 +1911,9 @@ public class SurfaceControl implements Parcelable { return this; } + /** + * @hide + */ @UnsupportedAppUsage public Transaction setMatrix(SurfaceControl sc, Matrix matrix, float[] float9) { matrix.getValues(float9); @@ -1620,6 +1927,7 @@ public class SurfaceControl implements Parcelable { * Sets the color transform for the Surface. * @param matrix A float array with 9 values represents a 3x3 transform matrix * @param translation A float array with 3 values represents a translation vector + * @hide */ public Transaction setColorTransform(SurfaceControl sc, @Size(9) float[] matrix, @Size(3) float[] translation) { @@ -1628,6 +1936,9 @@ public class SurfaceControl implements Parcelable { return this; } + /** + * @hide + */ @UnsupportedAppUsage public Transaction setWindowCrop(SurfaceControl sc, Rect crop) { sc.checkNotReleased(); @@ -1641,6 +1952,9 @@ public class SurfaceControl implements Parcelable { return this; } + /** + * @hide + */ public Transaction setWindowCrop(SurfaceControl sc, int width, int height) { sc.checkNotReleased(); nativeSetWindowCrop(mNativeObject, sc.mNativeObject, 0, 0, width, height); @@ -1652,6 +1966,7 @@ public class SurfaceControl implements Parcelable { * @param sc SurfaceControl * @param cornerRadius Corner radius in pixels. * @return Itself. + * @hide */ @UnsupportedAppUsage public Transaction setCornerRadius(SurfaceControl sc, float cornerRadius) { @@ -1662,6 +1977,9 @@ public class SurfaceControl implements Parcelable { } @UnsupportedAppUsage + /** + * @hide + */ public Transaction setLayerStack(SurfaceControl sc, int layerStack) { sc.checkNotReleased(); nativeSetLayerStack(mNativeObject, sc.mNativeObject, layerStack); @@ -1669,6 +1987,9 @@ public class SurfaceControl implements Parcelable { } @UnsupportedAppUsage + /** + * @hide + */ public Transaction deferTransactionUntil(SurfaceControl sc, IBinder handle, long frameNumber) { if (frameNumber < 0) { @@ -1680,6 +2001,9 @@ public class SurfaceControl implements Parcelable { } @UnsupportedAppUsage + /** + * @hide + */ public Transaction deferTransactionUntilSurface(SurfaceControl sc, Surface barrierSurface, long frameNumber) { if (frameNumber < 0) { @@ -1691,13 +2015,18 @@ public class SurfaceControl implements Parcelable { return this; } + /** + * @hide + */ public Transaction reparentChildren(SurfaceControl sc, IBinder newParentHandle) { sc.checkNotReleased(); nativeReparentChildren(mNativeObject, sc.mNativeObject, newParentHandle); return this; } - /** Re-parents a specific child layer to a new parent */ + /** Re-parents a specific child layer to a new parent + * @hide + */ public Transaction reparent(SurfaceControl sc, IBinder newParentHandle) { sc.checkNotReleased(); nativeReparent(mNativeObject, sc.mNativeObject, @@ -1705,12 +2034,18 @@ public class SurfaceControl implements Parcelable { return this; } + /** + * @hide + */ public Transaction detachChildren(SurfaceControl sc) { sc.checkNotReleased(); nativeSeverChildren(mNativeObject, sc.mNativeObject); return this; } + /** + * @hide + */ public Transaction setOverrideScalingMode(SurfaceControl sc, int overrideScalingMode) { sc.checkNotReleased(); nativeSetOverrideScalingMode(mNativeObject, sc.mNativeObject, @@ -1721,6 +2056,7 @@ public class SurfaceControl implements Parcelable { /** * Sets a color for the Surface. * @param color A float array with three values to represent r, g, b in range [0..1] + * @hide */ @UnsupportedAppUsage public Transaction setColor(SurfaceControl sc, @Size(3) float[] color) { @@ -1735,6 +2071,7 @@ public class SurfaceControl implements Parcelable { * arrives. As transform matrix and size are already frozen in this fashion, * this enables totally freezing the surface until the resize has completed * (at which point the geometry influencing aspects of this transaction will then occur) + * @hide */ public Transaction setGeometryAppliesWithResize(SurfaceControl sc) { sc.checkNotReleased(); @@ -1745,6 +2082,7 @@ public class SurfaceControl implements Parcelable { /** * Sets the security of the surface. Setting the flag is equivalent to creating the * Surface with the {@link #SECURE} flag. + * @hide */ public Transaction setSecure(SurfaceControl sc, boolean isSecure) { sc.checkNotReleased(); @@ -1759,6 +2097,7 @@ public class SurfaceControl implements Parcelable { /** * Sets the opacity of the surface. Setting the flag is equivalent to creating the * Surface with the {@link #OPAQUE} flag. + * @hide */ public Transaction setOpaque(SurfaceControl sc, boolean isOpaque) { sc.checkNotReleased(); @@ -1770,6 +2109,9 @@ public class SurfaceControl implements Parcelable { return this; } + /** + * @hide + */ public Transaction setDisplaySurface(IBinder displayToken, Surface surface) { if (displayToken == null) { throw new IllegalArgumentException("displayToken must not be null"); @@ -1785,6 +2127,9 @@ public class SurfaceControl implements Parcelable { return this; } + /** + * @hide + */ public Transaction setDisplayLayerStack(IBinder displayToken, int layerStack) { if (displayToken == null) { throw new IllegalArgumentException("displayToken must not be null"); @@ -1793,6 +2138,9 @@ public class SurfaceControl implements Parcelable { return this; } + /** + * @hide + */ public Transaction setDisplayProjection(IBinder displayToken, int orientation, Rect layerStackRect, Rect displayRect) { if (displayToken == null) { @@ -1810,6 +2158,9 @@ public class SurfaceControl implements Parcelable { return this; } + /** + * @hide + */ public Transaction setDisplaySize(IBinder displayToken, int width, int height) { if (displayToken == null) { throw new IllegalArgumentException("displayToken must not be null"); @@ -1822,7 +2173,9 @@ public class SurfaceControl implements Parcelable { return this; } - /** flag the transaction as an animation */ + /** flag the transaction as an animation + * @hide + */ public Transaction setAnimationTransaction() { nativeSetAnimationTransaction(mNativeObject); return this; @@ -1835,6 +2188,7 @@ public class SurfaceControl implements Parcelable { * order not to miss frame deadlines. * <p> * Corresponds to setting ISurfaceComposer::eEarlyWakeup + * @hide */ public Transaction setEarlyWakeup() { nativeSetEarlyWakeup(mNativeObject); @@ -1844,6 +2198,7 @@ public class SurfaceControl implements Parcelable { /** * Merge the other transaction into this transaction, clearing the * other transaction as if it had been applied. + * @hide */ public Transaction merge(Transaction other) { mResizedSurfaces.putAll(other.mResizedSurfaces); diff --git a/core/java/android/view/accessibility/AccessibilityNodeInfo.java b/core/java/android/view/accessibility/AccessibilityNodeInfo.java index d7c8aed8caec..793c31523023 100644 --- a/core/java/android/view/accessibility/AccessibilityNodeInfo.java +++ b/core/java/android/view/accessibility/AccessibilityNodeInfo.java @@ -43,6 +43,7 @@ import android.text.style.ClickableSpan; import android.text.style.URLSpan; import android.util.ArrayMap; import android.util.ArraySet; +import android.util.Log; import android.util.LongArray; import android.util.Pools.SynchronizedPool; import android.view.TouchDelegate; @@ -91,6 +92,8 @@ public class AccessibilityNodeInfo implements Parcelable { private static final boolean DEBUG = false; + private static final String TAG = "AccessibilityNodeInfo"; + /** @hide */ public static final int UNDEFINED_CONNECTION_ID = -1; @@ -990,6 +993,7 @@ public class AccessibilityNodeInfo implements Parcelable { * <strong>Note:</strong> Cannot be called from an * {@link android.accessibilityservice.AccessibilityService}. * This class is made immutable before being delivered to an AccessibilityService. + * Note that a view cannot be made its own child. * </p> * * @param child The child. @@ -1037,6 +1041,7 @@ public class AccessibilityNodeInfo implements Parcelable { * hierarchy for accessibility purposes. This enables custom views that draw complex * content to report them selves as a tree of virtual views, thus conveying their * logical structure. + * Note that a view cannot be made its own child. * </p> * * @param root The root of the virtual subtree. @@ -1054,6 +1059,11 @@ public class AccessibilityNodeInfo implements Parcelable { final int rootAccessibilityViewId = (root != null) ? root.getAccessibilityViewId() : UNDEFINED_ITEM_ID; final long childNodeId = makeNodeId(rootAccessibilityViewId, virtualDescendantId); + if (childNodeId == mSourceNodeId) { + Log.e(TAG, "Rejecting attempt to make a View its own child"); + return; + } + // If we're checking uniqueness and the ID already exists, abort. if (checked && mChildNodeIds.indexOf(childNodeId) >= 0) { return; diff --git a/core/jni/android_os_HwBinder.cpp b/core/jni/android_os_HwBinder.cpp index 163b86b29030..42e3942eb350 100644 --- a/core/jni/android_os_HwBinder.cpp +++ b/core/jni/android_os_HwBinder.cpp @@ -329,7 +329,7 @@ static jobject JHwBinder_native_getService( return NULL; } - LOG(INFO) << "HwBinder: Starting thread pool for " << serviceName << "::" << ifaceName; + LOG(INFO) << "HwBinder: Starting thread pool for getting: " << ifaceName << "/" << serviceName; ::android::hardware::ProcessState::self()->startThreadPool(); return JHwRemoteBinder::NewObject(env, service); diff --git a/core/tests/coretests/src/android/provider/SettingsBackupTest.java b/core/tests/coretests/src/android/provider/SettingsBackupTest.java index 4e405cab19b8..1ed5ce4a3929 100644 --- a/core/tests/coretests/src/android/provider/SettingsBackupTest.java +++ b/core/tests/coretests/src/android/provider/SettingsBackupTest.java @@ -271,7 +271,6 @@ public class SettingsBackupTest { Settings.Global.GNSS_SATELLITE_BLACKLIST, Settings.Global.GPRS_REGISTER_CHECK_PERIOD_MS, Settings.Global.HDMI_CONTROL_AUTO_DEVICE_OFF_ENABLED, - Settings.Global.HDMI_CONTROL_AUTO_TV_OFF_ENABLED, Settings.Global.HDMI_CONTROL_AUTO_WAKEUP_ENABLED, Settings.Global.HDMI_CONTROL_ENABLED, Settings.Global.HDMI_SYSTEM_AUDIO_CONTROL_ENABLED, diff --git a/core/tests/hosttests/test-apps/MultiDexLegacyAndException/Android.mk b/core/tests/hosttests/test-apps/MultiDexLegacyAndException/Android.mk index 80ab4eae689b..d161059ed024 100644 --- a/core/tests/hosttests/test-apps/MultiDexLegacyAndException/Android.mk +++ b/core/tests/hosttests/test-apps/MultiDexLegacyAndException/Android.mk @@ -18,7 +18,7 @@ LOCAL_PATH:= $(call my-dir) ## The application with a minimal main dex include $(CLEAR_VARS) -LOCAL_STATIC_JAVA_LIBRARIES := android-support-multidex android-support-multidex-instrumentation android-support-test +LOCAL_STATIC_JAVA_LIBRARIES := android-support-multidex android-support-multidex-instrumentation androidx.test.rules LOCAL_MODULE_TAGS := tests LOCAL_SRC_FILES := $(call all-java-files-under, src) diff --git a/core/tests/hosttests/test-apps/MultiDexLegacyAndException/AndroidManifest.xml b/core/tests/hosttests/test-apps/MultiDexLegacyAndException/AndroidManifest.xml index 98d8f27179fd..d9d9eb20e632 100644 --- a/core/tests/hosttests/test-apps/MultiDexLegacyAndException/AndroidManifest.xml +++ b/core/tests/hosttests/test-apps/MultiDexLegacyAndException/AndroidManifest.xml @@ -30,7 +30,7 @@ android:targetPackage="com.android.multidexlegacyandexception" android:label="Test for MultiDexLegacyAndException" /> - <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner" + <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner" android:targetPackage="com.android.multidexlegacyandexception" android:label="Test for MultiDexLegacyAndException" /> </manifest> diff --git a/core/tests/hosttests/test-apps/MultiDexLegacyAndException/src/com/android/multidexlegacyandexception/tests/MultiDexAndroidJUnitRunner.java b/core/tests/hosttests/test-apps/MultiDexLegacyAndException/src/com/android/multidexlegacyandexception/tests/MultiDexAndroidJUnitRunner.java index 92a3b0c0f7c3..fae345f982b7 100644 --- a/core/tests/hosttests/test-apps/MultiDexLegacyAndException/src/com/android/multidexlegacyandexception/tests/MultiDexAndroidJUnitRunner.java +++ b/core/tests/hosttests/test-apps/MultiDexLegacyAndException/src/com/android/multidexlegacyandexception/tests/MultiDexAndroidJUnitRunner.java @@ -17,8 +17,9 @@ package com.android.multidexlegacyandexception.tests; import android.os.Bundle; + import androidx.multidex.MultiDex; -import android.support.test.runner.AndroidJUnitRunner; +import androidx.test.runner.AndroidJUnitRunner; public class MultiDexAndroidJUnitRunner extends AndroidJUnitRunner { diff --git a/core/tests/hosttests/test-apps/MultiDexLegacyAndException/src/com/android/multidexlegacyandexception/tests/NoActivityJUnit4Test.java b/core/tests/hosttests/test-apps/MultiDexLegacyAndException/src/com/android/multidexlegacyandexception/tests/NoActivityJUnit4Test.java index 94a5b7fa66f2..f4b02d0dc68e 100644 --- a/core/tests/hosttests/test-apps/MultiDexLegacyAndException/src/com/android/multidexlegacyandexception/tests/NoActivityJUnit4Test.java +++ b/core/tests/hosttests/test-apps/MultiDexLegacyAndException/src/com/android/multidexlegacyandexception/tests/NoActivityJUnit4Test.java @@ -16,7 +16,8 @@ package com.android.multidexlegacyandexception.tests; -import android.support.test.runner.AndroidJUnit4; +import androidx.test.runner.AndroidJUnit4; + import org.junit.runner.RunWith; /** diff --git a/media/java/android/media/soundtrigger/SoundTriggerManager.java b/media/java/android/media/soundtrigger/SoundTriggerManager.java index fa69062c34df..ada77c53bb34 100644 --- a/media/java/android/media/soundtrigger/SoundTriggerManager.java +++ b/media/java/android/media/soundtrigger/SoundTriggerManager.java @@ -372,6 +372,7 @@ public final class SoundTriggerManager { * @hide */ @RequiresPermission(android.Manifest.permission.MANAGE_SOUND_TRIGGER) + @UnsupportedAppUsage public int getModelState(UUID soundModelId) { if (soundModelId == null) { return STATUS_ERROR; diff --git a/packages/SystemUI/res/layout/quick_qs_status_icons.xml b/packages/SystemUI/res/layout/quick_qs_status_icons.xml index 2000104ad0cd..74002ac38c02 100644 --- a/packages/SystemUI/res/layout/quick_qs_status_icons.xml +++ b/packages/SystemUI/res/layout/quick_qs_status_icons.xml @@ -51,11 +51,4 @@ android:layout_width="wrap_content" android:paddingEnd="2dp" /> - <TextView - android:id="@+id/batteryRemainingText" - android:textAppearance="@style/TextAppearance.QS.TileLabel" - android:layout_height="match_parent" - android:layout_width="wrap_content" - android:gravity="center_vertical" /> - </LinearLayout> diff --git a/packages/SystemUI/res/layout/quick_status_bar_header_system_icons.xml b/packages/SystemUI/res/layout/quick_status_bar_header_system_icons.xml index 4b65b6a013f8..cd9f780ca249 100644 --- a/packages/SystemUI/res/layout/quick_status_bar_header_system_icons.xml +++ b/packages/SystemUI/res/layout/quick_status_bar_header_system_icons.xml @@ -64,11 +64,5 @@ <include layout="@layout/ongoing_privacy_chip" /> - <com.android.systemui.BatteryMeterView - android:id="@+id/battery" - android:layout_height="match_parent" - android:layout_width="wrap_content" - android:gravity="center_vertical|end" - android:layout_gravity="center_vertical|end" /> </LinearLayout> </LinearLayout> diff --git a/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java b/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java index 8e273efb6171..200679432200 100644 --- a/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java +++ b/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java @@ -69,11 +69,12 @@ public class BatteryMeterView extends LinearLayout implements @Retention(SOURCE) - @IntDef({MODE_DEFAULT, MODE_ON, MODE_OFF}) + @IntDef({MODE_DEFAULT, MODE_ON, MODE_OFF, MODE_ESTIMATE}) public @interface BatteryPercentMode {} public static final int MODE_DEFAULT = 0; public static final int MODE_ON = 1; public static final int MODE_OFF = 2; + public static final int MODE_ESTIMATE = 3; private final BatteryMeterDrawableBase mDrawable; private final String mSlotBattery; @@ -91,6 +92,7 @@ public class BatteryMeterView extends LinearLayout implements // Some places may need to show the battery conditionally, and not obey the tuner private boolean mIgnoreTunerUpdates; private boolean mIsSubscribedForTunerUpdates; + private boolean mCharging; private int mDarkModeBackgroundColor; private int mDarkModeFillColor; @@ -303,6 +305,7 @@ public class BatteryMeterView extends LinearLayout implements public void onBatteryLevelChanged(int level, boolean pluggedIn, boolean charging) { mDrawable.setBatteryLevel(level); mDrawable.setCharging(pluggedIn); + mCharging = pluggedIn; mLevel = level; updatePercentText(); setContentDescription( @@ -332,9 +335,19 @@ public class BatteryMeterView extends LinearLayout implements } private void updatePercentText() { + if (mBatteryController == null) { + return; + } + if (mBatteryPercentView != null) { - mBatteryPercentView.setText( - NumberFormat.getPercentInstance().format(mLevel / 100f)); + if (mShowPercentMode == MODE_ESTIMATE && !mCharging) { + mBatteryController.getEstimatedTimeRemainingString((String estimate) -> { + mBatteryPercentView.setText(estimate); + }); + } else { + mBatteryPercentView.setText( + NumberFormat.getPercentInstance().format(mLevel / 100f)); + } } } @@ -345,7 +358,7 @@ public class BatteryMeterView extends LinearLayout implements SHOW_BATTERY_PERCENT, 0, mUser); if ((mShowPercentAvailable && systemSetting && mShowPercentMode != MODE_OFF) - || mShowPercentMode == MODE_ON) { + || mShowPercentMode == MODE_ON || mShowPercentMode == MODE_ESTIMATE) { if (!showing) { mBatteryPercentView = loadPercentView(); if (mTextColor != 0) mBatteryPercentView.setTextColor(mTextColor); diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/BiometricDialogView.java b/packages/SystemUI/src/com/android/systemui/biometrics/BiometricDialogView.java index b8c69c8003c4..c92767763cb4 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/BiometricDialogView.java +++ b/packages/SystemUI/src/com/android/systemui/biometrics/BiometricDialogView.java @@ -77,7 +77,6 @@ public abstract class BiometricDialogView extends LinearLayout { private final DevicePolicyManager mDevicePolicyManager; private final float mAnimationTranslationOffset; private final int mErrorColor; - private final int mTextColor; private final float mDialogWidth; private final DialogViewCallback mCallback; @@ -92,6 +91,8 @@ public abstract class BiometricDialogView extends LinearLayout { protected final Button mNegativeButton; protected final Button mTryAgainButton; + protected final int mTextColor; + private Bundle mBundle; private int mLastState; @@ -108,6 +109,7 @@ public abstract class BiometricDialogView extends LinearLayout { protected abstract boolean shouldAnimateForTransition(int oldState, int newState); protected abstract int getDelayAfterAuthenticatedDurationMs(); protected abstract boolean shouldGrayAreaDismissDialog(); + protected abstract void handleClearMessage(boolean requireTryAgain); private final Runnable mShowAnimationRunnable = new Runnable() { @Override @@ -421,20 +423,6 @@ public abstract class BiometricDialogView extends LinearLayout { return mLayout; } - // Clears the temporary message and shows the help message. If requireTryAgain is true, - // we will start the authenticating state again. - private void handleClearMessage(boolean requireTryAgain) { - if (!requireTryAgain) { - updateState(STATE_AUTHENTICATING); - mErrorText.setText(getHintStringResourceId()); - mErrorText.setTextColor(mTextColor); - mErrorText.setVisibility(View.VISIBLE); - } else { - updateState(STATE_IDLE); - mErrorText.setVisibility(View.INVISIBLE); - } - } - // Shows an error/help message private void showTemporaryMessage(String message, boolean requireTryAgain) { mHandler.removeMessages(MSG_CLEAR_MESSAGE); @@ -475,11 +463,6 @@ public abstract class BiometricDialogView extends LinearLayout { } public void showTryAgainButton(boolean show) { - if (show) { - mTryAgainButton.setVisibility(View.VISIBLE); - } else { - mTryAgainButton.setVisibility(View.GONE); - } } public void restoreState(Bundle bundle) { diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/FaceDialogView.java b/packages/SystemUI/src/com/android/systemui/biometrics/FaceDialogView.java index 359cb047c84d..9fba44b76863 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/FaceDialogView.java +++ b/packages/SystemUI/src/com/android/systemui/biometrics/FaceDialogView.java @@ -210,6 +210,22 @@ public class FaceDialogView extends BiometricDialogView { bundle.putInt(KEY_DIALOG_SIZE, mSize); } + + @Override + protected void handleClearMessage(boolean requireTryAgain) { + // Clears the temporary message and shows the help message. If requireTryAgain is true, + // we will start the authenticating state again. + if (!requireTryAgain) { + updateState(STATE_AUTHENTICATING); + mErrorText.setText(getHintStringResourceId()); + mErrorText.setTextColor(mTextColor); + mErrorText.setVisibility(View.VISIBLE); + } else { + updateState(STATE_IDLE); + mErrorText.setVisibility(View.INVISIBLE); + } + } + @Override public void restoreState(Bundle bundle) { super.restoreState(bundle); @@ -271,7 +287,11 @@ public class FaceDialogView extends BiometricDialogView { // of the elements in here. updateSize(SIZE_BIG); } else { - super.showTryAgainButton(show); + if (show) { + mTryAgainButton.setVisibility(View.VISIBLE); + } else { + mTryAgainButton.setVisibility(View.GONE); + } } } diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/FingerprintDialogView.java b/packages/SystemUI/src/com/android/systemui/biometrics/FingerprintDialogView.java index d63836b2207e..c9b30ba3ce8d 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/FingerprintDialogView.java +++ b/packages/SystemUI/src/com/android/systemui/biometrics/FingerprintDialogView.java @@ -32,6 +32,14 @@ public class FingerprintDialogView extends BiometricDialogView { DialogViewCallback callback) { super(context, callback); } + + @Override + protected void handleClearMessage(boolean requireTryAgain) { + updateState(STATE_AUTHENTICATING); + mErrorText.setText(getHintStringResourceId()); + mErrorText.setTextColor(mTextColor); + } + @Override protected int getHintStringResourceId() { return R.string.fingerprint_dialog_touch_sensor; diff --git a/packages/SystemUI/src/com/android/systemui/privacy/OngoingPrivacyDialog.kt b/packages/SystemUI/src/com/android/systemui/privacy/OngoingPrivacyDialog.kt index 4388200709fc..6ed1ebad8e51 100644 --- a/packages/SystemUI/src/com/android/systemui/privacy/OngoingPrivacyDialog.kt +++ b/packages/SystemUI/src/com/android/systemui/privacy/OngoingPrivacyDialog.kt @@ -119,12 +119,13 @@ class OngoingPrivacyDialog constructor( appName.text = app.applicationName if (showIcons) { - dialogBuilder.generateIconsForApp(types).forEach { + dialogBuilder.generateIconsForApp(types).forEachIndexed { index, it -> it.setBounds(0, 0, iconSize, iconSize) val image = ImageView(context).apply { imageTintList = ColorStateList.valueOf(iconColor) setImageDrawable(it) } + image.contentDescription = types[index].getName(context) icons.addView(image, lp) } icons.visibility = View.VISIBLE diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java index 28285e14ef4b..75ab5dfd2977 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java @@ -141,14 +141,11 @@ public class QuickStatusBarHeader extends RelativeLayout implements private View mStatusSeparator; private ImageView mRingerModeIcon; private TextView mRingerModeTextView; - private BatteryMeterView mBatteryMeterView; private Clock mClockView; private DateView mDateView; private OngoingPrivacyChip mPrivacyChip; private Space mSpace; private BatteryMeterView mBatteryRemainingIcon; - private TextView mBatteryRemainingText; - private boolean mShowBatteryPercentAndEstimate; private PrivacyItemController mPrivacyItemController; /** Counts how many times the long press tooltip has been shown to the user. */ @@ -229,13 +226,6 @@ public class QuickStatusBarHeader extends RelativeLayout implements // Set the correct tint for the status icons so they contrast mIconManager.setTint(fillColor); - mShowBatteryPercentAndEstimate = mContext.getResources().getBoolean( - com.android.internal.R.bool.config_battery_percentage_setting_available); - - mBatteryMeterView = findViewById(R.id.battery); - mBatteryMeterView.setPercentShowMode(mShowBatteryPercentAndEstimate - ? BatteryMeterView.MODE_ON : BatteryMeterView.MODE_OFF); - mBatteryMeterView.setOnClickListener(this); mClockView = findViewById(R.id.clock); mClockView.setOnClickListener(this); mDateView = findViewById(R.id.date); @@ -245,13 +235,8 @@ public class QuickStatusBarHeader extends RelativeLayout implements // Tint for the battery icons are handled in setupHost() mBatteryRemainingIcon = findViewById(R.id.batteryRemainingIcon); - mBatteryRemainingIcon.setPercentShowMode(BatteryMeterView.MODE_OFF); // Don't need to worry about tuner settings for this icon mBatteryRemainingIcon.setIgnoreTunerUpdates(true); - - mBatteryRemainingText = findViewById(R.id.batteryRemainingText); - mBatteryRemainingText.setTextColor(fillColor); - updateShowPercent(); } @@ -268,10 +253,8 @@ public class QuickStatusBarHeader extends RelativeLayout implements } private void setChipVisibility(boolean chipVisible) { - mBatteryMeterView.setVisibility(View.VISIBLE); if (chipVisible) { mPrivacyChip.setVisibility(View.VISIBLE); - if (mHasTopCutout) mBatteryMeterView.setVisibility(View.GONE); } else { mPrivacyChip.setVisibility(View.GONE); } @@ -339,7 +322,6 @@ public class QuickStatusBarHeader extends RelativeLayout implements // Update color schemes in landscape to use wallpaperTextColor boolean shouldUseWallpaperTextColor = newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE; - mBatteryMeterView.useWallpaperTextColor(shouldUseWallpaperTextColor); mClockView.useWallpaperTextColor(shouldUseWallpaperTextColor); } @@ -415,13 +397,6 @@ public class QuickStatusBarHeader extends RelativeLayout implements .build(); } - private void updateBatteryRemainingText() { - if (!mShowBatteryPercentAndEstimate) { - return; - } - mBatteryRemainingText.setText(mBatteryController.getEstimatedTimeRemainingString()); - } - public void setExpanded(boolean expanded) { if (mExpanded == expanded) return; mExpanded = expanded; @@ -519,7 +494,6 @@ public class QuickStatusBarHeader extends RelativeLayout implements } } mSpace.setLayoutParams(lp); - // Decide whether to show BatteryMeterView setChipVisibility(mPrivacyChip.getVisibility() == View.VISIBLE); return super.onApplyWindowInsets(insets); } @@ -546,7 +520,6 @@ public class QuickStatusBarHeader extends RelativeLayout implements mAlarmController.addCallback(this); mContext.registerReceiver(mRingerReceiver, new IntentFilter(AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION)); - updateBatteryRemainingText(); } else { mZenController.removeCallback(this); mAlarmController.removeCallback(this); @@ -559,9 +532,6 @@ public class QuickStatusBarHeader extends RelativeLayout implements if (v == mClockView) { mActivityStarter.postStartActivityDismissingKeyguard(new Intent( AlarmClock.ACTION_SHOW_ALARMS),0); - } else if (v == mBatteryMeterView) { - mActivityStarter.postStartActivityDismissingKeyguard(new Intent( - Intent.ACTION_POWER_USAGE_SUMMARY),0); } else if (v == mPrivacyChip) { Handler mUiHandler = new Handler(Looper.getMainLooper()); mUiHandler.post(() -> { @@ -713,9 +683,6 @@ public class QuickStatusBarHeader extends RelativeLayout implements mHeaderQsPanel.setQSPanelAndHeader(mQsPanel, this); mHeaderQsPanel.setHost(host, null /* No customization in header */); - // Use SystemUI context to get battery meter colors, and let it use the default tint (white) - mBatteryMeterView.setColorsFromContext(mHost.getContext()); - mBatteryMeterView.onDarkChanged(new Rect(), 0, DarkIconDispatcher.DEFAULT_ICON_TINT); Rect tintArea = new Rect(0, 0, 0, 0); int colorForeground = Utils.getColorAttrDefaultColor(getContext(), @@ -763,22 +730,8 @@ public class QuickStatusBarHeader extends RelativeLayout implements .getIntForUser(getContext().getContentResolver(), SHOW_BATTERY_PERCENT, 0, ActivityManager.getCurrentUser()); - mShowBatteryPercentAndEstimate = systemSetting; - - updateBatteryViews(); - } - - private void updateBatteryViews() { - if (mShowBatteryPercentAndEstimate) { - mBatteryMeterView.setPercentShowMode(BatteryMeterView.MODE_ON); - mBatteryRemainingIcon.setVisibility(View.VISIBLE); - mBatteryRemainingText.setVisibility(View.VISIBLE); - updateBatteryRemainingText(); - } else { - mBatteryMeterView.setPercentShowMode(BatteryMeterView.MODE_OFF); - mBatteryRemainingIcon.setVisibility(View.GONE); - mBatteryRemainingText.setVisibility(View.GONE); - } + mBatteryRemainingIcon.setPercentShowMode(systemSetting + ? BatteryMeterView.MODE_ESTIMATE : BatteryMeterView.MODE_ON); } private final class PercentSettingObserver extends ContentObserver { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java index 80db6c11e324..99b0cd2a7dfd 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java @@ -430,7 +430,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd private int mHeadsUpInset; private HeadsUpAppearanceController mHeadsUpAppearanceController; private NotificationIconAreaController mIconAreaController; - private float mVerticalPanelTranslation; + private float mHorizontalPanelTranslation; private final NotificationLockscreenUserManager mLockscreenUserManager = Dependency.get(NotificationLockscreenUserManager.class); protected final NotificationGutsManager mGutsManager = @@ -4377,12 +4377,12 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd @ShadeViewRefactor(RefactorComponent.SHADE_VIEW) private void updatePanelTranslation() { - setTranslationX(mVerticalPanelTranslation + mAntiBurnInOffsetX * mInterpolatedDarkAmount); + setTranslationX(mHorizontalPanelTranslation + mAntiBurnInOffsetX * mInterpolatedDarkAmount); } @ShadeViewRefactor(RefactorComponent.SHADE_VIEW) - public void setVerticalPanelTranslation(float verticalPanelTranslation) { - mVerticalPanelTranslation = verticalPanelTranslation; + public void setHorizontalPanelTranslation(float verticalPanelTranslation) { + mHorizontalPanelTranslation = verticalPanelTranslation; updatePanelTranslation(); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationAssistantAction.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationAssistantAction.java new file mode 100644 index 000000000000..ebcd39b99778 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationAssistantAction.java @@ -0,0 +1,49 @@ +/* + * 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 com.android.systemui.statusbar.phone; + +import android.annotation.NonNull; +import android.os.Bundle; +import android.view.MotionEvent; + +import com.android.systemui.assist.AssistManager; +import com.android.systemui.recents.OverviewProxyService; + +/** + * Assistant is triggered with this action + */ +public class NavigationAssistantAction extends NavigationGestureAction { + private static final String TAG = "NavigationAssistantActions"; + + private final AssistManager mAssistManager; + + public NavigationAssistantAction(@NonNull NavigationBarView navigationBarView, + @NonNull OverviewProxyService service, AssistManager assistManager) { + super(navigationBarView, service); + mAssistManager = assistManager; + } + + @Override + public boolean isEnabled() { + return true; + } + + @Override + public void onGestureStart(MotionEvent event) { + mAssistManager.startAssist(new Bundle()); + } +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBackAction.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBackAction.java index 9c8b1b1e5227..93605adf4589 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBackAction.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBackAction.java @@ -67,7 +67,7 @@ public class NavigationBackAction extends NavigationGestureAction { @Override public boolean isEnabled() { - return !getGlobalBoolean(NavigationPrototypeController.NAVBAR_EXPERIMENTS_DISABLED); + return true; } @Override @@ -102,8 +102,7 @@ public class NavigationBackAction extends NavigationGestureAction { } private boolean shouldExecuteBackOnUp() { - return !getGlobalBoolean(NavigationPrototypeController.NAVBAR_EXPERIMENTS_DISABLED) - && getGlobalBoolean(BACK_AFTER_END_PROP); + return getGlobalBoolean(BACK_AFTER_END_PROP); } private void sendEvent(int action, int code) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java index 6d97d6724d40..d3c6a1d8ee74 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java @@ -269,7 +269,7 @@ public class NavigationBarFragment extends LifecycleFragment implements Callback mIsOnDefaultDisplay = mDisplayId == Display.DEFAULT_DISPLAY; } - mNavigationBarView.setComponents(mStatusBar.getPanel()); + mNavigationBarView.setComponents(mStatusBar.getPanel(), mAssistManager); mNavigationBarView.setDisabledFlags(mDisabledFlags1); mNavigationBarView.setOnVerticalChangedListener(this::onVerticalChanged); mNavigationBarView.setOnTouchListener(this::onNavigationTouch); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java index 2fc7b78c0ca3..8bf1c58df699 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java @@ -69,6 +69,7 @@ import com.android.systemui.DockedStackExistsListener; import com.android.systemui.Interpolators; import com.android.systemui.R; import com.android.systemui.SysUiServiceProvider; +import com.android.systemui.assist.AssistManager; import com.android.systemui.plugins.PluginListener; import com.android.systemui.plugins.statusbar.phone.NavGesture; import com.android.systemui.plugins.statusbar.phone.NavGesture.GestureHelper; @@ -156,6 +157,7 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav private QuickStepAction mQuickStepAction; private NavigationBackAction mBackAction; private QuickSwitchAction mQuickSwitchAction; + private NavigationAssistantAction mAssistantAction; /** * Helper that is responsible for showing the right toast when a disallowed activity operation @@ -366,8 +368,12 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav return mBarTransitions.getLightTransitionsController(); } - public void setComponents(NotificationPanelView panel) { + public void setComponents(NotificationPanelView panel, AssistManager assistManager) { mPanelView = panel; + if (mAssistantAction == null) { + mAssistantAction = new NavigationAssistantAction(this, mOverviewProxyService, + assistManager); + } if (mGestureHelper instanceof QuickStepController) { ((QuickStepController) mGestureHelper).setComponents(this); updateNavigationGestures(); @@ -398,6 +404,10 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav return mBackAction; case NavigationPrototypeController.ACTION_QUICKSWITCH: return mQuickSwitchAction; + case NavigationPrototypeController.ACTION_ASSISTANT: + return mAssistantAction; + case NavigationPrototypeController.ACTION_NOTHING: + return null; default: return defaultAction; } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationGestureAction.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationGestureAction.java index 8c57fc31c3b4..a5d938216f5c 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationGestureAction.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationGestureAction.java @@ -24,6 +24,7 @@ import static com.android.systemui.shared.system.NavigationBarCompat.HIT_TARGET_ import android.annotation.NonNull; import android.content.Context; import android.graphics.Canvas; +import android.provider.Settings; import android.view.MotionEvent; import com.android.systemui.recents.OverviewProxyService; @@ -32,6 +33,9 @@ import com.android.systemui.recents.OverviewProxyService; * A gesture action that would be triggered and reassigned by {@link QuickStepController} */ public abstract class NavigationGestureAction { + private static final String ENABLE_TASK_STABILIZER_FLAG = "ENABLE_TASK_STABILIZER"; + + static private boolean sLastTaskStabilizationFlag; protected final NavigationBarView mNavigationBarView; protected final OverviewProxyService mProxySender; @@ -45,6 +49,9 @@ public abstract class NavigationGestureAction { @NonNull OverviewProxyService service) { mNavigationBarView = navigationBarView; mProxySender = service; + sLastTaskStabilizationFlag = Settings.Global.getInt( + mNavigationBarView.getContext().getContentResolver(), + ENABLE_TASK_STABILIZER_FLAG, 0) != 0; } /** @@ -74,6 +81,15 @@ public abstract class NavigationGestureAction { */ public void startGesture(MotionEvent event) { mIsActive = true; + + // Tell launcher that this action requires a stable task list or not + boolean flag = requiresStableTaskList(); + if (flag != sLastTaskStabilizationFlag) { + Settings.Global.putInt(mNavigationBarView.getContext().getContentResolver(), + ENABLE_TASK_STABILIZER_FLAG, flag ? 1 : 0); + sLastTaskStabilizationFlag = flag; + } + onGestureStart(event); } @@ -146,6 +162,13 @@ public abstract class NavigationGestureAction { */ public abstract boolean isEnabled(); + /** + * @return action requires a stable task list from launcher + */ + protected boolean requiresStableTaskList() { + return false; + } + protected void onDarkIntensityChange(float intensity) { } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationPrototypeController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationPrototypeController.java index fb6254b0e4be..a09e5858d576 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationPrototypeController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationPrototypeController.java @@ -22,7 +22,6 @@ import android.database.ContentObserver; import android.net.Uri; import android.os.Handler; import android.provider.Settings; -import android.provider.Settings.SettingNotFoundException; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -36,18 +35,20 @@ public class NavigationPrototypeController extends ContentObserver { private static final String HIDE_BACK_BUTTON_SETTING = "quickstepcontroller_hideback"; private static final String HIDE_HOME_BUTTON_SETTING = "quickstepcontroller_hidehome"; - static final String NAVBAR_EXPERIMENTS_DISABLED = "navbarexperiments_disabled"; private final String GESTURE_MATCH_SETTING = "quickstepcontroller_gesture_match_map"; public static final String NAV_COLOR_ADAPT_ENABLE_SETTING = "navbar_color_adapt_enable"; @Retention(RetentionPolicy.SOURCE) - @IntDef({ACTION_DEFAULT, ACTION_QUICKSTEP, ACTION_QUICKSCRUB, ACTION_BACK}) + @IntDef({ACTION_DEFAULT, ACTION_QUICKSTEP, ACTION_QUICKSCRUB, ACTION_BACK, + ACTION_QUICKSWITCH, ACTION_NOTHING, ACTION_ASSISTANT}) @interface GestureAction {} static final int ACTION_DEFAULT = 0; static final int ACTION_QUICKSTEP = 1; static final int ACTION_QUICKSCRUB = 2; static final int ACTION_BACK = 3; static final int ACTION_QUICKSWITCH = 4; + static final int ACTION_NOTHING = 5; + static final int ACTION_ASSISTANT = 6; private OnPrototypeChangedListener mListener; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java index 75adf50c092e..512f56dafc11 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java @@ -1233,7 +1233,7 @@ public class NotificationPanelView extends PanelView implements updateDozingVisibilities(false /* animate */); } - resetVerticalPanelPosition(); + resetHorizontalPanelPosition(); updateQsState(); } @@ -2043,7 +2043,7 @@ public class NotificationPanelView extends PanelView implements super.onConfigurationChanged(newConfig); mAffordanceHelper.onConfigurationChanged(); if (newConfig.orientation != mLastOrientation) { - resetVerticalPanelPosition(); + resetHorizontalPanelPosition(); } mLastOrientation = newConfig.orientation; } @@ -2529,7 +2529,7 @@ public class NotificationPanelView extends PanelView implements @Override protected void onClosingFinished() { super.onClosingFinished(); - resetVerticalPanelPosition(); + resetHorizontalPanelPosition(); setClosingWithAlphaFadeout(false); } @@ -2546,7 +2546,7 @@ public class NotificationPanelView extends PanelView implements */ protected void updateVerticalPanelPosition(float x) { if (mNotificationStackScroller.getWidth() * 1.75f > getWidth()) { - resetVerticalPanelPosition(); + resetHorizontalPanelPosition(); return; } float leftMost = mPositionMinSideMargin + mNotificationStackScroller.getWidth() / 2; @@ -2556,16 +2556,17 @@ public class NotificationPanelView extends PanelView implements x = getWidth() / 2; } x = Math.min(rightMost, Math.max(leftMost, x)); - setVerticalPanelTranslation(x - - (mNotificationStackScroller.getLeft() + mNotificationStackScroller.getWidth() / 2)); + float center = + mNotificationStackScroller.getLeft() + mNotificationStackScroller.getWidth() / 2; + setHorizontalPanelTranslation(x - center); } - private void resetVerticalPanelPosition() { - setVerticalPanelTranslation(0f); + private void resetHorizontalPanelPosition() { + setHorizontalPanelTranslation(0f); } - protected void setVerticalPanelTranslation(float translation) { - mNotificationStackScroller.setVerticalPanelTranslation(translation); + protected void setHorizontalPanelTranslation(float translation) { + mNotificationStackScroller.setHorizontalPanelTranslation(translation); mQsFrame.setTranslationX(translation); int size = mVerticalTranslationListener.size(); for (int i = 0; i < size; i++) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStepAction.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStepAction.java index b18b79e0e6d6..1999f9a8e04d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStepAction.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStepAction.java @@ -47,6 +47,10 @@ public class QuickStepAction extends NavigationGestureAction { return mNavigationBarView.isQuickStepSwipeUpEnabled(); } + protected boolean requiresStableTaskList() { + return true; + } + @Override public void onGestureStart(MotionEvent event) { try { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java index f65f8261dcfb..5e94152e7eab 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java @@ -48,18 +48,36 @@ public interface BatteryController extends DemoMode, Dumpable, } /** - * A listener that will be notified whenever a change in battery level or power save mode - * has occurred. + * A listener that will be notified whenever a change in battery level or power save mode has + * occurred. */ interface BatteryStateChangeCallback { - default void onBatteryLevelChanged(int level, boolean pluggedIn, boolean charging) {} - default void onPowerSaveChanged(boolean isPowerSave) {} + + default void onBatteryLevelChanged(int level, boolean pluggedIn, boolean charging) { + } + + default void onPowerSaveChanged(boolean isPowerSave) { + } } /** - * If available, get the estimated battery time remaining as a string + * If available, get the estimated battery time remaining as a string. + * + * @param completion A lambda that will be called with the result of fetching the estimate. The + * first time this method is called may need to be dispatched to a background thread. The + * completion is called on the main thread + */ + default void getEstimatedTimeRemainingString(EstimateFetchCompletion completion) {} + + /** + * Callback called when the estimated time remaining text is fetched. */ - default String getEstimatedTimeRemainingString() { - return null; + public interface EstimateFetchCompletion { + + /** + * The callback + * @param estimate the estimate + */ + void onBatteryRemainingEstimateRetrieved(String estimate); } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java index 6190c8fff8cc..af3c96f73642 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java @@ -27,9 +27,12 @@ import android.os.PowerManager; import android.os.PowerSaveState; import android.util.Log; +import androidx.annotation.Nullable; + import com.android.internal.annotations.VisibleForTesting; import com.android.settingslib.fuelgauge.BatterySaverUtils; import com.android.settingslib.utils.PowerUtil; +import com.android.systemui.Dependency; import com.android.systemui.power.EnhancedEstimates; import com.android.systemui.power.Estimate; @@ -56,6 +59,7 @@ public class BatteryControllerImpl extends BroadcastReceiver implements BatteryC private final EnhancedEstimates mEstimates; private final ArrayList<BatteryController.BatteryStateChangeCallback> mChangeCallbacks = new ArrayList<>(); + private final ArrayList<EstimateFetchCompletion> mFetchCallbacks = new ArrayList<>(); private final PowerManager mPowerManager; private final Handler mHandler; private final Context mContext; @@ -70,6 +74,7 @@ public class BatteryControllerImpl extends BroadcastReceiver implements BatteryC private boolean mHasReceivedBattery = false; private Estimate mEstimate; private long mLastEstimateTimestamp = -1; + private boolean mFetchingEstimate = false; @Inject public BatteryControllerImpl(Context context, EnhancedEstimates enhancedEstimates) { @@ -197,20 +202,61 @@ public class BatteryControllerImpl extends BroadcastReceiver implements BatteryC } @Override - public String getEstimatedTimeRemainingString() { - if (mEstimate == null - || System.currentTimeMillis() > mLastEstimateTimestamp + UPDATE_GRANULARITY_MSEC) { - updateEstimate(); + public void getEstimatedTimeRemainingString(EstimateFetchCompletion completion) { + if (mEstimate != null + && mLastEstimateTimestamp > System.currentTimeMillis() - UPDATE_GRANULARITY_MSEC) { + String percentage = generateTimeRemainingString(); + completion.onBatteryRemainingEstimateRetrieved(percentage); + return; + } + + // Need to fetch or refresh the estimate, but it may involve binder calls so offload the + // work + synchronized (mFetchCallbacks) { + mFetchCallbacks.add(completion); } - // Estimates may not exist yet even if we've checked + updateEstimateInBackground(); + } + + @Nullable + private String generateTimeRemainingString() { if (mEstimate == null) { return null; } - final String percentage = NumberFormat.getPercentInstance().format((double) mLevel / 100.0); + + String percentage = NumberFormat.getPercentInstance().format((double) mLevel / 100.0); return PowerUtil.getBatteryRemainingShortStringFormatted( mContext, mEstimate.estimateMillis); } + private void updateEstimateInBackground() { + if (mFetchingEstimate) { + // Already dispatched a fetch. It will notify all listeners when finished + return; + } + + mFetchingEstimate = true; + Dependency.get(Dependency.BG_HANDLER).post(() -> { + mEstimate = mEstimates.getEstimate(); + mLastEstimateTimestamp = System.currentTimeMillis(); + mFetchingEstimate = false; + + Dependency.get(Dependency.MAIN_HANDLER).post(this::notifyEstimateFetchCallbacks); + }); + } + + private void notifyEstimateFetchCallbacks() { + String estimate = generateTimeRemainingString(); + + synchronized (mFetchCallbacks) { + for (EstimateFetchCompletion completion : mFetchCallbacks) { + completion.onBatteryRemainingEstimateRetrieved(estimate); + } + + mFetchCallbacks.clear(); + } + } + private void updateEstimate() { mEstimate = mEstimates.getEstimate(); mLastEstimateTimestamp = System.currentTimeMillis(); diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/QuickStepControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/QuickStepControllerTest.java index 2805908d114a..382dde9ce043 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/QuickStepControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/QuickStepControllerTest.java @@ -97,6 +97,7 @@ public class QuickStepControllerTest extends SysuiTestCase { doReturn(HIT_TARGET_NONE).when(mNavigationBarView).getDownHitTarget(); doReturn(backButton).when(mNavigationBarView).getBackButton(); doReturn(mResources).when(mNavigationBarView).getResources(); + doReturn(mContext).when(mNavigationBarView).getContext(); mController = new QuickStepController(mContext); mController.setComponents(mNavigationBarView); diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java index 8ca4193a064f..bab9a6535376 100644 --- a/services/core/java/com/android/server/am/ActiveServices.java +++ b/services/core/java/com/android/server/am/ActiveServices.java @@ -130,6 +130,9 @@ public final class ActiveServices { // calling startForeground() before we ANR + stop it. static final int SERVICE_START_FOREGROUND_TIMEOUT = 10*1000; + // For how long after a whitelisted service's start its process can start a background activity + private static final int SERVICE_BG_ACTIVITY_START_TIMEOUT_MS = 10*1000; + final ActivityManagerService mAm; // Maximum number of services that we allow to start in the background @@ -398,6 +401,14 @@ public final class ActiveServices { ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType, int callingPid, int callingUid, boolean fgRequired, String callingPackage, final int userId) throws TransactionTooLargeException { + return startServiceLocked(caller, service, resolvedType, callingPid, callingUid, fgRequired, + callingPackage, userId, false); + } + + ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType, + int callingPid, int callingUid, boolean fgRequired, String callingPackage, + final int userId, boolean allowBackgroundActivityStarts) + throws TransactionTooLargeException { if (DEBUG_DELAYED_STARTS) Slog.v(TAG_SERVICE, "startService: " + service + " type=" + resolvedType + " args=" + service.getExtras()); @@ -622,10 +633,28 @@ public final class ActiveServices { } } + if (allowBackgroundActivityStarts) { + ProcessRecord proc = mAm.getProcessRecordLocked(r.processName, r.appInfo.uid, false); + if (proc != null) { + proc.addAllowBackgroundActivityStartsToken(r); + // schedule removal of the whitelisting token after the timeout + removeAllowBackgroundActivityStartsServiceToken(proc, r, + SERVICE_BG_ACTIVITY_START_TIMEOUT_MS); + } + } ComponentName cmp = startServiceInnerLocked(smap, service, r, callerFg, addToStarting); return cmp; } + private void removeAllowBackgroundActivityStartsServiceToken(ProcessRecord proc, + ServiceRecord r, int delayMillis) { + mAm.mHandler.postDelayed(() -> { + if (proc != null) { + proc.removeAllowBackgroundActivityStartsToken(r); + } + }, delayMillis); + } + private boolean requestStartTargetPermissionsReviewIfNeededLocked(ServiceRecord r, String callingPackage, int callingUid, Intent service, boolean callerFg, final int userId) { @@ -752,6 +781,9 @@ public final class ActiveServices { if (r.record != null) { final long origId = Binder.clearCallingIdentity(); try { + // immediately remove bg activity whitelisting token if there was one + removeAllowBackgroundActivityStartsServiceToken(callerApp, r.record, + 0 /* delayMillis */); stopServiceLocked(r.record); } finally { Binder.restoreCallingIdentity(origId); diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index bb239acb5c60..26141f7d7066 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -19495,8 +19495,8 @@ public class ActivityManagerService extends IActivityManager.Stub @Override public ComponentName startServiceInPackage(int uid, Intent service, String resolvedType, - boolean fgRequired, String callingPackage, int userId) - throws TransactionTooLargeException { + boolean fgRequired, String callingPackage, int userId, + boolean allowBackgroundActivityStarts) throws TransactionTooLargeException { synchronized(ActivityManagerService.this) { if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "startServiceInPackage: " + service + " type=" + resolvedType); @@ -19504,7 +19504,8 @@ public class ActivityManagerService extends IActivityManager.Stub ComponentName res; try { res = mServices.startServiceLocked(null, service, - resolvedType, -1, uid, fgRequired, callingPackage, userId); + resolvedType, -1, uid, fgRequired, callingPackage, userId, + allowBackgroundActivityStarts); } finally { Binder.restoreCallingIdentity(origId); } diff --git a/services/core/java/com/android/server/am/PendingIntentRecord.java b/services/core/java/com/android/server/am/PendingIntentRecord.java index b675d9d4f9cf..98c9ad66bc5c 100644 --- a/services/core/java/com/android/server/am/PendingIntentRecord.java +++ b/services/core/java/com/android/server/am/PendingIntentRecord.java @@ -51,6 +51,7 @@ public final class PendingIntentRecord extends IIntentSender.Stub { public static final int FLAG_ACTIVITY_SENDER = 1 << 0; public static final int FLAG_BROADCAST_SENDER = 1 << 1; + public static final int FLAG_SERVICE_SENDER = 1 << 2; final PendingIntentController controller; final Key key; @@ -62,6 +63,7 @@ public final class PendingIntentRecord extends IIntentSender.Stub { private RemoteCallbackList<IResultReceiver> mCancelCallbacks; private ArraySet<IBinder> mAllowBgActivityStartsForActivitySender = new ArraySet<>(); private ArraySet<IBinder> mAllowBgActivityStartsForBroadcastSender = new ArraySet<>(); + private ArraySet<IBinder> mAllowBgActivityStartsForServiceSender = new ArraySet<>(); String stringName; String lastTagPrefix; @@ -228,6 +230,9 @@ public final class PendingIntentRecord extends IIntentSender.Stub { if ((flags & FLAG_BROADCAST_SENDER) != 0) { mAllowBgActivityStartsForBroadcastSender.add(token); } + if ((flags & FLAG_SERVICE_SENDER) != 0) { + mAllowBgActivityStartsForServiceSender.add(token); + } } public void registerCancelListenerLocked(IResultReceiver receiver) { @@ -426,7 +431,8 @@ public final class PendingIntentRecord extends IIntentSender.Stub { try { controller.mAmInternal.startServiceInPackage(uid, finalIntent, resolvedType, key.type == ActivityManager.INTENT_SENDER_FOREGROUND_SERVICE, - key.packageName, userId); + key.packageName, userId, + mAllowBgActivityStartsForServiceSender.contains(whitelistToken)); } catch (RuntimeException e) { Slog.w(TAG, "Unable to send startService intent", e); } catch (TransactionTooLargeException e) { diff --git a/services/core/java/com/android/server/am/ProcessRecord.java b/services/core/java/com/android/server/am/ProcessRecord.java index 0d0824a74cdd..054c83080d98 100644 --- a/services/core/java/com/android/server/am/ProcessRecord.java +++ b/services/core/java/com/android/server/am/ProcessRecord.java @@ -1142,11 +1142,13 @@ final class ProcessRecord implements WindowProcessListener { } void addAllowBackgroundActivityStartsToken(Binder entity) { + if (entity == null) return; mAllowBackgroundActivityStartsTokens.add(entity); mWindowProcessController.setAllowBackgroundActivityStarts(true); } void removeAllowBackgroundActivityStartsToken(Binder entity) { + if (entity == null) return; mAllowBackgroundActivityStartsTokens.remove(entity); mWindowProcessController.setAllowBackgroundActivityStarts( !mAllowBackgroundActivityStartsTokens.isEmpty()); diff --git a/services/core/java/com/android/server/appop/TEST_MAPPING b/services/core/java/com/android/server/appop/TEST_MAPPING deleted file mode 100644 index 4901d3a8b06f..000000000000 --- a/services/core/java/com/android/server/appop/TEST_MAPPING +++ /dev/null @@ -1,7 +0,0 @@ -{ - "presubmit": [ - { - "name": "CtsAppOpsTestCases", - } - ] -} diff --git a/services/core/java/com/android/server/biometrics/BiometricService.java b/services/core/java/com/android/server/biometrics/BiometricService.java index fc1e32691c5b..41fedc5fab45 100644 --- a/services/core/java/com/android/server/biometrics/BiometricService.java +++ b/services/core/java/com/android/server/biometrics/BiometricService.java @@ -351,10 +351,7 @@ public class BiometricService extends SystemService { if (!runningTasks.isEmpty()) { final String topPackage = runningTasks.get(0).topActivity.getPackageName(); if (mCurrentAuthSession != null - && !topPackage.contentEquals(mCurrentAuthSession.mOpPackageName) - && mCurrentAuthSession.mState != STATE_AUTH_STARTED) { - // We only care about this state, since <Biometric>Service will - // cancel any client that's still in STATE_AUTH_STARTED + && !topPackage.contentEquals(mCurrentAuthSession.mOpPackageName)) { mStatusBarService.hideBiometricDialog(); mActivityTaskManager.unregisterTaskStackListener(mTaskStackListener); mCurrentAuthSession.mClientReceiver.onError( @@ -464,8 +461,9 @@ public class BiometricService extends SystemService { if (mCurrentAuthSession != null && mCurrentAuthSession.containsCookie(cookie)) { if (mCurrentAuthSession.mState == STATE_AUTH_STARTED) { mStatusBarService.onBiometricError(message); - mActivityTaskManager.unregisterTaskStackListener(mTaskStackListener); if (error == BiometricConstants.BIOMETRIC_ERROR_CANCELED) { + mActivityTaskManager.unregisterTaskStackListener( + mTaskStackListener); mCurrentAuthSession.mClientReceiver.onError(error, message); mCurrentAuthSession.mState = STATE_AUTH_IDLE; mCurrentAuthSession = null; @@ -474,9 +472,14 @@ public class BiometricService extends SystemService { // Send errors after the dialog is dismissed. mHandler.postDelayed(() -> { try { - mCurrentAuthSession.mClientReceiver.onError(error, message); - mCurrentAuthSession.mState = STATE_AUTH_IDLE; - mCurrentAuthSession = null; + if (mCurrentAuthSession != null) { + mActivityTaskManager.unregisterTaskStackListener( + mTaskStackListener); + mCurrentAuthSession.mClientReceiver.onError(error, + message); + mCurrentAuthSession.mState = STATE_AUTH_IDLE; + mCurrentAuthSession = null; + } } catch (RemoteException e) { Slog.e(TAG, "Remote exception", e); } @@ -540,6 +543,11 @@ public class BiometricService extends SystemService { @Override public void onDialogDismissed(int reason) throws RemoteException { + if (mCurrentAuthSession == null) { + Slog.e(TAG, "onDialogDismissed: " + reason + ", auth session null"); + return; + } + if (reason != BiometricPrompt.DISMISSED_REASON_POSITIVE) { // Positive button is used by passive modalities as a "confirm" button, // do not send to client diff --git a/services/core/java/com/android/server/biometrics/BiometricServiceBase.java b/services/core/java/com/android/server/biometrics/BiometricServiceBase.java index 32219aa5955f..ecc3d2da8226 100644 --- a/services/core/java/com/android/server/biometrics/BiometricServiceBase.java +++ b/services/core/java/com/android/server/biometrics/BiometricServiceBase.java @@ -819,8 +819,6 @@ public abstract class BiometricServiceBase extends SystemService // Should be done on a handler thread - not on the Binder's thread. private void startAuthentication(AuthenticationClientImpl client, String opPackageName) { - updateActiveGroup(client.getGroupId(), opPackageName); - if (DEBUG) Slog.v(getTag(), "startAuthentication(" + opPackageName + ")"); int lockoutMode = getLockoutMode(); diff --git a/services/core/java/com/android/server/biometrics/face/FaceService.java b/services/core/java/com/android/server/biometrics/face/FaceService.java index f4d8d4bdec83..5a9c1aca081a 100644 --- a/services/core/java/com/android/server/biometrics/face/FaceService.java +++ b/services/core/java/com/android/server/biometrics/face/FaceService.java @@ -133,10 +133,11 @@ public class FaceService extends BiometricServiceBase { } @Override // Binder call - public void authenticate(final IBinder token, final long opId, + public void authenticate(final IBinder token, final long opId, int userId, final IFaceServiceReceiver receiver, final int flags, final String opPackageName) { checkPermission(USE_BIOMETRIC_INTERNAL); + updateActiveGroup(userId, opPackageName); final boolean restricted = isRestricted(); final AuthenticationClientImpl client = new FaceAuthClient(getContext(), mDaemonWrapper, mHalDeviceId, token, new ServiceListenerImpl(receiver), diff --git a/services/core/java/com/android/server/biometrics/fingerprint/FingerprintService.java b/services/core/java/com/android/server/biometrics/fingerprint/FingerprintService.java index 3895ef78b357..1613dc97225b 100644 --- a/services/core/java/com/android/server/biometrics/fingerprint/FingerprintService.java +++ b/services/core/java/com/android/server/biometrics/fingerprint/FingerprintService.java @@ -159,6 +159,7 @@ public class FingerprintService extends BiometricServiceBase { public void authenticate(final IBinder token, final long opId, final int groupId, final IFingerprintServiceReceiver receiver, final int flags, final String opPackageName) { + updateActiveGroup(groupId, opPackageName); final boolean restricted = isRestricted(); final AuthenticationClientImpl client = new FingerprintAuthClient(getContext(), mDaemonWrapper, mHalDeviceId, token, new ServiceListenerImpl(receiver), diff --git a/services/core/java/com/android/server/hdmi/ArcInitiationActionFromAvr.java b/services/core/java/com/android/server/hdmi/ArcInitiationActionFromAvr.java index ed17de5e8c35..18d328d3f971 100644 --- a/services/core/java/com/android/server/hdmi/ArcInitiationActionFromAvr.java +++ b/services/core/java/com/android/server/hdmi/ArcInitiationActionFromAvr.java @@ -21,14 +21,15 @@ import android.hardware.tv.cec.V1_0.SendMessageResult; * Feature action that handles Audio Return Channel initiated by AVR devices. */ public class ArcInitiationActionFromAvr extends HdmiCecFeatureAction { - // TODO(shubang): add tests - // State in which waits for ARC response. private static final int STATE_WAITING_FOR_INITIATE_ARC_RESPONSE = 1; private static final int STATE_ARC_INITIATED = 2; // the required maximum response time specified in CEC 9.2 private static final int TIMEOUT_MS = 1000; + private static final int MAX_RETRY_COUNT = 5; + + private int mSendRequestActiveSourceRetryCount = 0; ArcInitiationActionFromAvr(HdmiCecLocalDevice source) { super(source); @@ -56,7 +57,12 @@ public class ArcInitiationActionFromAvr extends HdmiCecFeatureAction { return true; case Constants.MESSAGE_REPORT_ARC_INITIATED: mState = STATE_ARC_INITIATED; - finish(); + if (audioSystem().getActiveSource().physicalAddress != getSourcePath() + && audioSystem().isSystemAudioActivated()) { + sendRequestActiveSource(); + } else { + finish(); + } return true; } return false; @@ -91,4 +97,19 @@ public class ArcInitiationActionFromAvr extends HdmiCecFeatureAction { finish(); } + protected void sendRequestActiveSource() { + sendCommand(HdmiCecMessageBuilder.buildRequestActiveSource(getSourceAddress()), + result -> { + if (result != SendMessageResult.SUCCESS) { + if (mSendRequestActiveSourceRetryCount < MAX_RETRY_COUNT) { + mSendRequestActiveSourceRetryCount++; + sendRequestActiveSource(); + } else { + finish(); + } + } else { + finish(); + } + }); + } } diff --git a/services/core/java/com/android/server/hdmi/ArcTerminationActionFromAvr.java b/services/core/java/com/android/server/hdmi/ArcTerminationActionFromAvr.java index 7e7332180f8a..eb7c0cd61132 100644 --- a/services/core/java/com/android/server/hdmi/ArcTerminationActionFromAvr.java +++ b/services/core/java/com/android/server/hdmi/ArcTerminationActionFromAvr.java @@ -50,6 +50,9 @@ public class ArcTerminationActionFromAvr extends HdmiCecFeatureAction { case Constants.MESSAGE_REPORT_ARC_TERMINATED: mState = STATE_ARC_TERMINATED; audioSystem().setArcStatus(false); + if (audioSystem().getLocalActivePort() == Constants.CEC_SWITCH_ARC) { + audioSystem().routeToInputFromPortId(audioSystem().getRoutingPort()); + } finish(); return true; } diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java index 528e0a4e4940..6e1b0181adbf 100755 --- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java +++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java @@ -18,10 +18,12 @@ package com.android.server.hdmi; import android.annotation.Nullable; import android.hardware.hdmi.HdmiDeviceInfo; +import android.hardware.hdmi.IHdmiControlCallback; import android.hardware.input.InputManager; import android.os.Handler; import android.os.Looper; import android.os.Message; +import android.os.RemoteException; import android.os.SystemClock; import android.util.Slog; import android.view.InputDevice; @@ -133,9 +135,6 @@ abstract class HdmiCecLocalDevice { return s.toString(); } } - // Logical address of the active source. - @GuardedBy("mLock") - protected final ActiveSource mActiveSource = new ActiveSource(); // Active routing path. Physical address of the active source but not all the time, such as // when the new active source does not claim itself to be one. Note that we don't keep @@ -867,9 +866,7 @@ abstract class HdmiCecLocalDevice { } ActiveSource getActiveSource() { - synchronized (mLock) { - return mActiveSource; - } + return mService.getActiveSource(); } void setActiveSource(ActiveSource newActive) { @@ -881,10 +878,7 @@ abstract class HdmiCecLocalDevice { } void setActiveSource(int logicalAddress, int physicalAddress) { - synchronized (mLock) { - mActiveSource.logicalAddress = logicalAddress; - mActiveSource.physicalAddress = physicalAddress; - } + mService.setActiveSource(logicalAddress, physicalAddress); mService.setLastInputForMhl(Constants.INVALID_PORT_ID); } @@ -1029,6 +1023,19 @@ abstract class HdmiCecLocalDevice { return Constants.ADDR_INVALID; } + @ServiceThreadOnly + void invokeCallback(IHdmiControlCallback callback, int result) { + assertRunOnServiceThread(); + if (callback == null) { + return; + } + try { + callback.onComplete(result); + } catch (RemoteException e) { + Slog.e(TAG, "Invoking callback failed:" + e); + } + } + void sendUserControlPressedAndReleased(int targetAddress, int cecKeycode) { mService.sendCecCommand( HdmiCecMessageBuilder.buildUserControlPressed(mAddress, targetAddress, cecKeycode)); @@ -1042,7 +1049,7 @@ abstract class HdmiCecLocalDevice { pw.println("mAddress: " + mAddress); pw.println("mPreferredAddress: " + mPreferredAddress); pw.println("mDeviceInfo: " + mDeviceInfo); - pw.println("mActiveSource: " + mActiveSource); + pw.println("mActiveSource: " + getActiveSource()); pw.println(String.format("mActiveRoutingPath: 0x%04x", mActiveRoutingPath)); } diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java index 048a0e413a9b..8cfe47f3d75e 100644 --- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java +++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java @@ -21,13 +21,14 @@ import static com.android.server.hdmi.Constants.USE_LAST_STATE_SYSTEM_AUDIO_CONT import android.annotation.Nullable; import android.content.Intent; +import android.hardware.hdmi.HdmiControlManager; import android.hardware.hdmi.HdmiDeviceInfo; +import android.hardware.hdmi.IHdmiControlCallback; import android.media.AudioDeviceInfo; import android.media.AudioManager; import android.media.AudioSystem; import android.media.tv.TvContract; import android.os.SystemProperties; -import android.provider.Settings.Global; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; @@ -55,11 +56,6 @@ public class HdmiCecLocalDeviceAudioSystem extends HdmiCecLocalDeviceSource { private boolean mTvSystemAudioModeSupport; - // Whether the auido system will turn TV off when it's powering off - private boolean mAutoTvOff; - // Whether the auido system will broadcast standby to the system when it's powering off - private boolean mAutoDeviceOff; - // Whether ARC is available or not. "true" means that ARC is established between TV and // AVR as audio receiver. @ServiceThreadOnly private boolean mArcEstablished = false; @@ -81,10 +77,6 @@ public class HdmiCecLocalDeviceAudioSystem extends HdmiCecLocalDeviceSource { // TODO(amyjojo) make System Audio Control controllable by users /*mSystemAudioControlFeatureEnabled = mService.readBooleanSetting(Global.HDMI_SYSTEM_AUDIO_CONTROL_ENABLED, true);*/ - mAutoDeviceOff = mService.readBooleanSetting( - Global.HDMI_CONTROL_AUTO_DEVICE_OFF_ENABLED, true); - mAutoTvOff = mService.readBooleanSetting( - Global.HDMI_CONTROL_AUTO_TV_OFF_ENABLED, true); // TODO(amyjojo): make the map ro property. mTvInputs.put(Constants.CEC_SWITCH_HDMI1, "com.droidlogic.tvinput/.services.Hdmi1InputService/HW5"); @@ -106,21 +98,6 @@ public class HdmiCecLocalDeviceAudioSystem extends HdmiCecLocalDeviceSource { mSystemAudioActivated ? "true" : "false"); } terminateSystemAudioMode(); - - HdmiLogger.debug(TAG + " onStandby, initiatedByCec:" + initiatedByCec - + ", mAutoDeviceOff: " + mAutoDeviceOff + ", mAutoTvOff: " + mAutoTvOff); - if (!mService.isControlEnabled() || initiatedByCec) { - return; - } - if (mAutoDeviceOff) { - mService.sendCecCommand( - HdmiCecMessageBuilder.buildStandby(mAddress, Constants.ADDR_BROADCAST)); - } else if (mAutoTvOff) { - mService.sendCecCommand( - HdmiCecMessageBuilder.buildStandby(mAddress, Constants.ADDR_TV)); - } - return; - } @Override @@ -232,6 +209,7 @@ public class HdmiCecLocalDeviceAudioSystem extends HdmiCecLocalDeviceSource { @ServiceThreadOnly protected boolean handleRequestArcInitiate(HdmiCecMessage message) { assertRunOnServiceThread(); + removeAction(ArcInitiationActionFromAvr.class); if (!SystemProperties.getBoolean(Constants.PROPERTY_ARC_SUPPORT, true)) { mService.maySendFeatureAbortCommand(message, Constants.ABORT_UNRECOGNIZED_OPCODE); } else if (!isDirectConnectToTv()) { @@ -253,6 +231,7 @@ public class HdmiCecLocalDeviceAudioSystem extends HdmiCecLocalDeviceSource { HdmiLogger.debug("ARC is not established between TV and AVR device"); mService.maySendFeatureAbortCommand(message, Constants.ABORT_NOT_IN_CORRECT_MODE); } else { + removeAction(ArcTerminationActionFromAvr.class); addAndStartAction(new ArcTerminationActionFromAvr(this)); } return true; @@ -471,11 +450,17 @@ public class HdmiCecLocalDeviceAudioSystem extends HdmiCecLocalDeviceSource { } } // Init arc whenever System Audio Mode is on - // Since some TV like LG don't request ARC on with System Audio Mode on request - if (newSystemAudioMode - && SystemProperties.getBoolean(Constants.PROPERTY_ARC_SUPPORT, true) - && !isArcEnabled() && isDirectConnectToTv()) { - addAndStartAction(new ArcInitiationActionFromAvr(this)); + // Terminate arc when System Audio Mode is off + // Since some TVs don't request ARC on with System Audio Mode on request + if (SystemProperties.getBoolean(Constants.PROPERTY_ARC_SUPPORT, true) + && isDirectConnectToTv()) { + if (newSystemAudioMode && !isArcEnabled()) { + removeAction(ArcInitiationActionFromAvr.class); + addAndStartAction(new ArcInitiationActionFromAvr(this)); + } else if (!newSystemAudioMode && isArcEnabled()) { + removeAction(ArcTerminationActionFromAvr.class); + addAndStartAction(new ArcTerminationActionFromAvr(this)); + } } } @@ -501,6 +486,33 @@ public class HdmiCecLocalDeviceAudioSystem extends HdmiCecLocalDeviceSource { } } + @ServiceThreadOnly + void doManualPortSwitching(int portId, IHdmiControlCallback callback) { + assertRunOnServiceThread(); + // TODO: validate port ID + if (portId == getLocalActivePort()) { + invokeCallback(callback, HdmiControlManager.RESULT_SUCCESS); + return; + } + getActiveSource().invalidate(); + if (!mService.isControlEnabled()) { + setLocalActivePort(portId); + invokeCallback(callback, HdmiControlManager.RESULT_INCORRECT_MODE); + return; + } + int oldPath = getLocalActivePort() != Constants.CEC_SWITCH_HOME + ? getActivePathOnSwitchFromActivePortId(getLocalActivePort()) + : getDeviceInfo().getPhysicalAddress(); + int newPath = getActivePathOnSwitchFromActivePortId(portId); + if (oldPath == newPath) { + return; + } + setLocalActivePort(portId); + HdmiCecMessage routingChange = + HdmiCecMessageBuilder.buildRoutingChange(mAddress, oldPath, newPath); + mService.sendCecCommand(routingChange); + } + boolean isSystemAudioControlFeatureEnabled() { synchronized (mLock) { return mSystemAudioControlFeatureEnabled; @@ -594,28 +606,9 @@ public class HdmiCecLocalDeviceAudioSystem extends HdmiCecLocalDeviceSource { } } - @ServiceThreadOnly - protected void setAutoTvOff(boolean autoTvOff) { - assertRunOnServiceThread(); - mAutoTvOff = autoTvOff; - } - - @Override - @ServiceThreadOnly - void setAutoDeviceOff(boolean autoDeviceOff) { - assertRunOnServiceThread(); - mAutoDeviceOff = autoDeviceOff; - } - @Override protected void switchInputOnReceivingNewActivePath(int physicalAddress) { int port = getLocalPortFromPhysicalAddress(physicalAddress); - // Wake up if the new Active Source is the current device or under it - // or if System Audio Control is enabled. - if ((isSystemAudioActivated() || port >= 0) && mService.isPowerStandbyOrTransient()) { - mService.wakeUp(); - } - if (isSystemAudioActivated() && port < 0) { // If system audio mode is on and the new active source is not under the current device, // Will switch to ARC input. @@ -641,11 +634,15 @@ public class HdmiCecLocalDeviceAudioSystem extends HdmiCecLocalDeviceSource { HdmiLogger.debug("Invalid port number for Tv Input switching."); return; } - // TODO(amyjojo): handle if switching to the current input + // Wake up if the current device if ready to route. + if (mService.isPowerStandbyOrTransient()) { + mService.wakeUp(); + } if (portId == Constants.CEC_SWITCH_HOME && mService.isPlaybackDevice()) { switchToHomeTvInput(); } else if (portId == Constants.CEC_SWITCH_ARC) { switchToTvInput(SystemProperties.get(Constants.PROPERTY_SYSTEM_AUDIO_DEVICE_ARC_PORT)); + setLocalActivePort(portId); return; } else { String uri = mTvInputs.get(portId); @@ -658,6 +655,7 @@ public class HdmiCecLocalDeviceAudioSystem extends HdmiCecLocalDeviceSource { } setLocalActivePort(portId); + setRoutingPort(portId); } // For device to switch to specific TvInput with corresponding URI. @@ -700,31 +698,21 @@ public class HdmiCecLocalDeviceAudioSystem extends HdmiCecLocalDeviceSource { // Handle the system audio(ARC) part of the logic on receiving routing change or information. private void handleRoutingChangeAndInformationForSystemAudio() { - if (mService.isPowerStandbyOrTransient()) { - mService.wakeUp(); - } // TODO(b/115637145): handle system aduio without ARC routeToInputFromPortId(Constants.CEC_SWITCH_ARC); } // Handle the routing control part of the logic on receiving routing change or information. private void handleRoutingChangeAndInformationForSwitch(HdmiCecMessage message) { - if (mService.isPowerStandbyOrTransient()) { - mService.wakeUp(); - } - if (getLocalActivePort() == Constants.CEC_SWITCH_HOME && mService.isPlaybackDevice()) { + if (getRoutingPort() == Constants.CEC_SWITCH_HOME && mService.isPlaybackDevice()) { routeToInputFromPortId(Constants.CEC_SWITCH_HOME); - if (mService.playback() != null) { - mService.playback().setAndBroadcastActiveSource( - message, mService.getPhysicalAddress()); - } else { - setAndBroadcastActiveSource(message, mService.getPhysicalAddress()); - } + mService.setAndBroadcastActiveSourceFromOneDeviceType( + message.getSource(), mService.getPhysicalAddress()); return; } int routingInformationPath = - getActivePathOnSwitchFromActivePortId(getLocalActivePort()); + getActivePathOnSwitchFromActivePortId(getRoutingPort()); // If current device is already the leaf of the whole HDMI system, will do nothing. if (routingInformationPath == mService.getPhysicalAddress()) { HdmiLogger.debug("Current device can't assign valid physical address" @@ -735,6 +723,6 @@ public class HdmiCecLocalDeviceAudioSystem extends HdmiCecLocalDeviceSource { // Otherwise will switch to the current active port and broadcast routing information. mService.sendCecCommand(HdmiCecMessageBuilder.buildRoutingInformation( mAddress, routingInformationPath)); - routeToInputFromPortId(getLocalActivePort()); + routeToInputFromPortId(getRoutingPort()); } } diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java index 379cc1610197..07db9716497c 100644 --- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java +++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java @@ -21,7 +21,6 @@ import android.hardware.hdmi.HdmiDeviceInfo; import android.hardware.hdmi.IHdmiControlCallback; import android.os.PowerManager; import android.os.PowerManager.WakeLock; -import android.os.RemoteException; import android.os.SystemProperties; import android.provider.Settings.Global; import android.util.Slog; @@ -39,7 +38,7 @@ import java.util.Locale; /** * Represent a logical device of type Playback residing in Android system. */ -final class HdmiCecLocalDevicePlayback extends HdmiCecLocalDeviceSource { +public class HdmiCecLocalDevicePlayback extends HdmiCecLocalDeviceSource { private static final String TAG = "HdmiCecLocalDevicePlayback"; private static final boolean WAKE_ON_HOTPLUG = @@ -48,8 +47,6 @@ final class HdmiCecLocalDevicePlayback extends HdmiCecLocalDeviceSource { private static final boolean SET_MENU_LANGUAGE = SystemProperties.getBoolean(Constants.PROPERTY_SET_MENU_LANGUAGE, false); - private boolean mIsActiveSource = false; - // Used to keep the device awake while it is the active source. For devices that // cannot wake up via CEC commands, this address the inconvenience of having to // turn them on. True by default, and can be disabled (i.e. device can go to sleep @@ -122,16 +119,6 @@ final class HdmiCecLocalDevicePlayback extends HdmiCecLocalDeviceSource { addAndStartAction(action); } - @ServiceThreadOnly - private void invokeCallback(IHdmiControlCallback callback, int result) { - assertRunOnServiceThread(); - try { - callback.onComplete(result); - } catch (RemoteException e) { - Slog.e(TAG, "Invoking callback failed:" + e); - } - } - @Override @ServiceThreadOnly void onHotplug(int portId, boolean connected) { @@ -174,6 +161,7 @@ final class HdmiCecLocalDevicePlayback extends HdmiCecLocalDeviceSource { } @ServiceThreadOnly + @VisibleForTesting void setIsActiveSource(boolean on) { assertRunOnServiceThread(); mIsActiveSource = on; @@ -220,53 +208,6 @@ final class HdmiCecLocalDevicePlayback extends HdmiCecLocalDeviceSource { } @Override - @ServiceThreadOnly - protected boolean handleSetStreamPath(HdmiCecMessage message) { - assertRunOnServiceThread(); - int physicalAddress = HdmiUtils.twoBytesToInt(message.getParams()); - // If current device is the target path, set to Active Source. - // If the path is under the current device, should switch - int port = getLocalPortFromPhysicalAddress(physicalAddress); - if (port == 0) { - setIsActiveSource(true); - maySendActiveSource(message.getSource()); - wakeUpIfActiveSource(); - } else if (port > 0) { - // Wake up the device if the power is in standby mode for routing - if (mService.isPowerStandbyOrTransient()) { - mService.wakeUp(); - } - routeToPort(port); - } - return true; - } - - // Samsung model we tested sends <Routing Change> and <Request Active Source> - // in a row, and then changes the input to the internal source if there is no - // <Active Source> in response. To handle this, we'll set ActiveSource aggressively. - @Override - @ServiceThreadOnly - protected boolean handleRoutingChange(HdmiCecMessage message) { - assertRunOnServiceThread(); - int newPath = HdmiUtils.twoBytesToInt(message.getParams(), 2); - maySetActiveSource(newPath); - return true; // Broadcast message. - } - - @Override - @ServiceThreadOnly - protected boolean handleRoutingInformation(HdmiCecMessage message) { - assertRunOnServiceThread(); - int physicalAddress = HdmiUtils.twoBytesToInt(message.getParams()); - maySetActiveSource(physicalAddress); - return true; // Broadcast message. - } - - private void maySetActiveSource(int physicalAddress) { - setIsActiveSource(physicalAddress == mService.getPhysicalAddress()); - } - - @Override protected void wakeUpIfActiveSource() { if (!mIsActiveSource) { return; diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceSource.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceSource.java index 8d55299243b2..6532e16cffe5 100644 --- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceSource.java +++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceSource.java @@ -18,7 +18,6 @@ package com.android.server.hdmi; import android.hardware.hdmi.HdmiControlManager; import android.hardware.hdmi.IHdmiControlCallback; -import android.os.RemoteException; import android.os.SystemProperties; import android.util.Slog; @@ -37,21 +36,32 @@ abstract class HdmiCecLocalDeviceSource extends HdmiCecLocalDevice { private static final String TAG = "HdmiCecLocalDeviceSource"; // Indicate if current device is Active Source or not - private boolean mIsActiveSource = false; + @VisibleForTesting + protected boolean mIsActiveSource = false; // Device has cec switch functionality or not. // Default is false. protected boolean mIsSwitchDevice = SystemProperties.getBoolean( Constants.PROPERTY_HDMI_IS_DEVICE_HDMI_CEC_SWITCH, false); - // Local active port number used for Routing Control. - // This records the default active port or the previous valid active port. + // Routing port number used for Routing Control. + // This records the default routing port or the previous valid routing port. // Default is HOME input. // Note that we don't save active path here because for source device, - // new Active Source physical address might not match the local active path + // new Active Source physical address might not match the active path + @GuardedBy("mLock") + @LocalActivePort + private int mRoutingPort = Constants.CEC_SWITCH_HOME; + + // This records the current input of the device. + // When device is switched to ARC input, mRoutingPort does not record it + // since it's not an HDMI port used for Routing Control. + // mLocalActivePort will record whichever input we switch to to keep tracking on + // the current input status of the device. + // This can help prevent duplicate switching and provide status information. @GuardedBy("mLock") @LocalActivePort - private int mLocalActivePort = Constants.CEC_SWITCH_HOME; + protected int mLocalActivePort = Constants.CEC_SWITCH_HOME; protected HdmiCecLocalDeviceSource(HdmiControlService service, int deviceType) { super(service, deviceType); @@ -98,22 +108,12 @@ abstract class HdmiCecLocalDeviceSource extends HdmiCecLocalDevice { } @ServiceThreadOnly - private void invokeCallback(IHdmiControlCallback callback, int result) { - assertRunOnServiceThread(); - try { - callback.onComplete(result); - } catch (RemoteException e) { - Slog.e(TAG, "Invoking callback failed:" + e); - } - } - - @ServiceThreadOnly protected boolean handleActiveSource(HdmiCecMessage message) { assertRunOnServiceThread(); int logicalAddress = message.getSource(); int physicalAddress = HdmiUtils.twoBytesToInt(message.getParams()); ActiveSource activeSource = ActiveSource.of(logicalAddress, physicalAddress); - if (!mActiveSource.equals(activeSource)) { + if (!getActiveSource().equals(activeSource)) { setActiveSource(activeSource); } setIsActiveSource(physicalAddress == mService.getPhysicalAddress()); @@ -185,24 +185,13 @@ abstract class HdmiCecLocalDeviceSource extends HdmiCecLocalDevice { // do nothing } - // Active source claiming needs to be handled in the parent class - // since we decide who will be the active source when the device supports + // Active source claiming needs to be handled in Service + // since service can decide who will be the active source when the device supports // multiple device types in this method. // This method should only be called when the device can be the active source. protected void setAndBroadcastActiveSource(HdmiCecMessage message, int physicalAddress) { - // If the device has both playback and audio system logical addresses, - // playback will claim active source. Otherwise audio system will. - HdmiCecLocalDevice deviceToBeActiveSource = mService.playback(); - if (deviceToBeActiveSource == null) { - deviceToBeActiveSource = mService.audioSystem(); - } - if (this == deviceToBeActiveSource) { - ActiveSource activeSource = ActiveSource.of(mAddress, physicalAddress); - setIsActiveSource(true); - setActiveSource(activeSource); - wakeUpIfActiveSource(); - maySendActiveSource(message.getSource()); - } + mService.setAndBroadcastActiveSource( + message, physicalAddress, getDeviceInfo().getDeviceType()); } @ServiceThreadOnly @@ -211,13 +200,6 @@ abstract class HdmiCecLocalDeviceSource extends HdmiCecLocalDevice { mIsActiveSource = on; } - @ServiceThreadOnly - // Check if current device is the Active Source - boolean isActiveSource() { - assertRunOnServiceThread(); - return mIsActiveSource; - } - protected void wakeUpIfActiveSource() { if (!mIsActiveSource) { return; @@ -236,19 +218,59 @@ abstract class HdmiCecLocalDeviceSource extends HdmiCecLocalDevice { } } + /** + * Set {@link #mRoutingPort} to a specific {@link LocalActivePort} to record the current active + * CEC Routing Control related port. + * + * @param portId The portId of the new routing port. + */ @VisibleForTesting - protected void setLocalActivePort(@LocalActivePort int portId) { + protected void setRoutingPort(@LocalActivePort int portId) { + synchronized (mLock) { + mRoutingPort = portId; + } + } + + /** + * Get {@link #mRoutingPort}. This is useful when the device needs to route to the last valid + * routing port. + */ + @LocalActivePort + protected int getRoutingPort() { synchronized (mLock) { - mLocalActivePort = portId; + return mRoutingPort; } } - // To get the local active port to switch to - // when receivng routing change or information. + /** + * Get {@link #mLocalActivePort}. This is useful when device needs to know the current active + * port. + */ @LocalActivePort protected int getLocalActivePort() { synchronized (mLock) { return mLocalActivePort; } } + + /** + * Set {@link #mLocalActivePort} to a specific {@link LocalActivePort} to record the current + * active port. + * + * <p>It does not have to be a Routing Control related port. For example it can be + * set to {@link Constants#CEC_SWITCH_ARC} but this port is System Audio related. + * + * @param activePort The portId of the new active port. + */ + protected void setLocalActivePort(@LocalActivePort int activePort) { + synchronized (mLock) { + mLocalActivePort = activePort; + } + } + + // Check if the device is trying to switch to the same input that is active right now. + // This can help avoid redundant port switching. + protected boolean isSwitchingToTheSameInput(@LocalActivePort int activePort) { + return activePort == getLocalActivePort(); + } } diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java index 25ca27836aa7..b91d8c637c79 100644 --- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java +++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java @@ -41,17 +41,18 @@ import android.media.AudioManager; import android.media.AudioSystem; import android.media.tv.TvInputInfo; import android.media.tv.TvInputManager.TvInputCallback; -import android.os.RemoteException; import android.provider.Settings.Global; import android.util.ArraySet; import android.util.Slog; import android.util.SparseArray; import android.util.SparseBooleanArray; + import com.android.internal.annotations.GuardedBy; import com.android.internal.util.IndentingPrintWriter; import com.android.server.hdmi.DeviceDiscoveryAction.DeviceDiscoveryCallback; import com.android.server.hdmi.HdmiAnnotations.ServiceThreadOnly; import com.android.server.hdmi.HdmiControlService.SendMessageCallback; + import java.io.UnsupportedEncodingException; import java.util.ArrayList; import java.util.Arrays; @@ -307,7 +308,7 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice { private void handleSelectInternalSource() { assertRunOnServiceThread(); // Seq #18 - if (mService.isControlEnabled() && mActiveSource.logicalAddress != mAddress) { + if (mService.isControlEnabled() && getActiveSource().logicalAddress != mAddress) { updateActiveSource(mAddress, mService.getPhysicalAddress()); if (mSkipRoutingControl) { mSkipRoutingControl = false; @@ -329,7 +330,7 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice { void updateActiveSource(ActiveSource newActive) { assertRunOnServiceThread(); // Seq #14 - if (mActiveSource.equals(newActive)) { + if (getActiveSource().equals(newActive)) { return; } setActiveSource(newActive); @@ -402,7 +403,7 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice { invokeCallback(callback, HdmiControlManager.RESULT_SUCCESS); return; } - mActiveSource.invalidate(); + getActiveSource().invalidate(); if (!mService.isControlEnabled()) { setActivePortId(portId); invokeCallback(callback, HdmiControlManager.RESULT_INCORRECT_MODE); @@ -452,17 +453,6 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice { return Constants.ADDR_INVALID; } - private static void invokeCallback(IHdmiControlCallback callback, int result) { - if (callback == null) { - return; - } - try { - callback.onComplete(result); - } catch (RemoteException e) { - Slog.e(TAG, "Invoking callback failed:" + e); - } - } - @Override @ServiceThreadOnly protected boolean handleActiveSource(HdmiCecMessage message) { @@ -518,7 +508,7 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice { } else { // No HDMI port to switch to was found. Notify the input change listers to // switch to the lastly shown internal input. - mActiveSource.invalidate(); + getActiveSource().invalidate(); setActivePath(Constants.INVALID_PHYSICAL_ADDRESS); mService.invokeInputChangeListener(HdmiDeviceInfo.INACTIVE_DEVICE); } @@ -685,7 +675,7 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice { byte[] params = message.getParams(); int currentPath = HdmiUtils.twoBytesToInt(params); if (HdmiUtils.isAffectingActiveRoutingPath(getActivePath(), currentPath)) { - mActiveSource.invalidate(); + getActiveSource().invalidate(); removeAction(RoutingControlAction.class); int newPath = HdmiUtils.twoBytesToInt(params, 2); addAndStartAction(new RoutingControlAction(this, newPath, true, null)); diff --git a/services/core/java/com/android/server/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java index 903045d9b68f..833091df5f1c 100644 --- a/services/core/java/com/android/server/hdmi/HdmiControlService.java +++ b/services/core/java/com/android/server/hdmi/HdmiControlService.java @@ -140,6 +140,10 @@ public class HdmiControlService extends SystemService { static final int STANDBY_SCREEN_OFF = 0; static final int STANDBY_SHUTDOWN = 1; + // Logical address of the active source. + @GuardedBy("mLock") + protected final ActiveSource mActiveSource = new ActiveSource(); + private static final boolean isHdmiCecNeverClaimPlaybackLogicAddr = SystemProperties.getBoolean( Constants.PROPERTY_HDMI_CEC_NEVER_CLAIM_PLAYBACK_LOGICAL_ADDRESS, false); @@ -596,11 +600,6 @@ public class HdmiControlService extends SystemService { } // No need to propagate to HAL. break; - case Global.HDMI_CONTROL_AUTO_TV_OFF_ENABLED: - if (isAudioSystemDevice()) { - audioSystem().setAutoTvOff(enabled); - } - break; case Global.HDMI_SYSTEM_AUDIO_CONTROL_ENABLED: if (isTvDeviceEnabled()) { tv().setSystemAudioControlFeatureEnabled(enabled); @@ -1009,6 +1008,10 @@ public class HdmiControlService extends SystemService { assertRunOnServiceThread(); if (connected && !isTvDevice()) { + if (getPortInfo(portId).getType() == HdmiPortInfo.PORT_OUTPUT && isSwitchDevice()) { + initPortInfo(); + HdmiLogger.debug("initPortInfo for switch device when onHotplug from tx."); + } ArrayList<HdmiCecLocalDevice> localDevices = new ArrayList<>(); for (int type : mLocalDevices) { if (type == HdmiDeviceInfo.DEVICE_PLAYBACK @@ -1394,17 +1397,24 @@ public class HdmiControlService extends SystemService { return; } HdmiCecLocalDeviceTv tv = tv(); - if (tv == null) { - if (!mAddressAllocated) { - mSelectRequestBuffer.set(SelectRequestBuffer.newPortSelect( - HdmiControlService.this, portId, callback)); - return; - } - Slog.w(TAG, "Local tv device not available"); - invokeCallback(callback, HdmiControlManager.RESULT_SOURCE_NOT_AVAILABLE); + if (tv != null) { + tv.doManualPortSwitching(portId, callback); return; } - tv.doManualPortSwitching(portId, callback); + HdmiCecLocalDeviceAudioSystem audioSystem = audioSystem(); + if (audioSystem != null) { + audioSystem.doManualPortSwitching(portId, callback); + return; + } + + if (!mAddressAllocated) { + mSelectRequestBuffer.set(SelectRequestBuffer.newPortSelect( + HdmiControlService.this, portId, callback)); + return; + } + Slog.w(TAG, "Local device not available"); + invokeCallback(callback, HdmiControlManager.RESULT_SOURCE_NOT_AVAILABLE); + return; } }); } @@ -2118,6 +2128,11 @@ public class HdmiControlService extends SystemService { return mLocalDevices.contains(HdmiDeviceInfo.DEVICE_PLAYBACK); } + boolean isSwitchDevice() { + return SystemProperties.getBoolean( + Constants.PROPERTY_HDMI_IS_DEVICE_HDMI_CEC_SWITCH, false); + } + boolean isTvDeviceEnabled() { return isTvDevice() && tv() != null; } @@ -2493,6 +2508,77 @@ public class HdmiControlService extends SystemService { setLastInputForMhl(Constants.INVALID_PORT_ID); } + ActiveSource getActiveSource() { + synchronized (mLock) { + return mActiveSource; + } + } + + void setActiveSource(int logicalAddress, int physicalAddress) { + synchronized (mLock) { + mActiveSource.logicalAddress = logicalAddress; + mActiveSource.physicalAddress = physicalAddress; + } + } + + // This method should only be called when the device can be the active source + // and all the device types call into this method. + // For example, when receiving broadcast messages, all the device types will call this + // method but only one of them will be the Active Source. + protected void setAndBroadcastActiveSource( + HdmiCecMessage message, int physicalAddress, int deviceType) { + // If the device has both playback and audio system logical addresses, + // playback will claim active source. Otherwise audio system will. + if (deviceType == HdmiDeviceInfo.DEVICE_PLAYBACK) { + HdmiCecLocalDevicePlayback playback = playback(); + playback.setIsActiveSource(true); + playback.wakeUpIfActiveSource(); + playback.maySendActiveSource(message.getSource()); + setActiveSource(playback.mAddress, physicalAddress); + } + + if (deviceType == HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM) { + HdmiCecLocalDeviceAudioSystem audioSystem = audioSystem(); + if (playback() != null) { + audioSystem.setIsActiveSource(false); + } else { + audioSystem.setIsActiveSource(true); + audioSystem.wakeUpIfActiveSource(); + audioSystem.maySendActiveSource(message.getSource()); + setActiveSource(audioSystem.mAddress, physicalAddress); + } + } + } + + // This method should only be called when the device can be the active source + // and only one of the device types calls into this method. + // For example, when receiving One Touch Play, only playback device handles it + // and this method updates Active Source in all the device types sharing the same + // Physical Address. + protected void setAndBroadcastActiveSourceFromOneDeviceType( + int sourceAddress, int physicalAddress) { + // If the device has both playback and audio system logical addresses, + // playback will claim active source. Otherwise audio system will. + HdmiCecLocalDevicePlayback playback = playback(); + HdmiCecLocalDeviceAudioSystem audioSystem = audioSystem(); + if (playback != null) { + playback.setIsActiveSource(true); + playback.wakeUpIfActiveSource(); + playback.maySendActiveSource(sourceAddress); + if (audioSystem != null) { + audioSystem.setIsActiveSource(false); + } + setActiveSource(playback.mAddress, physicalAddress); + } else { + if (audioSystem != null) { + audioSystem.setIsActiveSource(true); + audioSystem.wakeUpIfActiveSource(); + audioSystem.maySendActiveSource(sourceAddress); + setActiveSource(audioSystem.mAddress, physicalAddress); + } + } + } + @ServiceThreadOnly void setLastInputForMhl(int portId) { assertRunOnServiceThread(); diff --git a/services/core/java/com/android/server/hdmi/OneTouchPlayAction.java b/services/core/java/com/android/server/hdmi/OneTouchPlayAction.java index 46611dd1b66e..41bf01f842cd 100644 --- a/services/core/java/com/android/server/hdmi/OneTouchPlayAction.java +++ b/services/core/java/com/android/server/hdmi/OneTouchPlayAction.java @@ -83,12 +83,16 @@ final class OneTouchPlayAction extends HdmiCecFeatureAction { } private void broadcastActiveSource() { - sendCommand(HdmiCecMessageBuilder.buildActiveSource(getSourceAddress(), getSourcePath())); // Because only source device can create this action, it's safe to cast. HdmiCecLocalDeviceSource source = source(); - source.setIsActiveSource(true); - source.setActiveSource(getSourceAddress(), getSourcePath()); + source.mService.setAndBroadcastActiveSourceFromOneDeviceType( + mTargetAddress, getSourcePath()); // Set local active port to HOME when One Touch Play. + // Active Port and Current Input are handled by the switch functionality device. + if (source.mService.audioSystem() != null) { + source = source.mService.audioSystem(); + } + source.setRoutingPort(Constants.CEC_SWITCH_HOME); source.setLocalActivePort(Constants.CEC_SWITCH_HOME); } diff --git a/services/core/java/com/android/server/hdmi/SelectRequestBuffer.java b/services/core/java/com/android/server/hdmi/SelectRequestBuffer.java index 75986c7ba1c1..ba16260bbfb7 100644 --- a/services/core/java/com/android/server/hdmi/SelectRequestBuffer.java +++ b/services/core/java/com/android/server/hdmi/SelectRequestBuffer.java @@ -56,6 +56,10 @@ public class SelectRequestBuffer { return mService.tv(); } + protected HdmiCecLocalDeviceAudioSystem audioSystem() { + return mService.audioSystem(); + } + protected boolean isLocalDeviceReady() { if (tv() == null) { Slog.e(TAG, "Local tv device not available"); @@ -105,7 +109,15 @@ public class SelectRequestBuffer { public void process() { if (isLocalDeviceReady()) { Slog.v(TAG, "calling delayed portSelect id:" + mId); - tv().doManualPortSwitching(mId, mCallback); + HdmiCecLocalDeviceTv tv = tv(); + if (tv != null) { + tv.doManualPortSwitching(mId, mCallback); + return; + } + HdmiCecLocalDeviceAudioSystem audioSystem = audioSystem(); + if (audioSystem != null) { + audioSystem.doManualPortSwitching(mId, mCallback); + } } } } diff --git a/services/core/java/com/android/server/hdmi/SystemAudioInitiationActionFromAvr.java b/services/core/java/com/android/server/hdmi/SystemAudioInitiationActionFromAvr.java index a6e69656a956..b6ebcd7c3ec2 100644 --- a/services/core/java/com/android/server/hdmi/SystemAudioInitiationActionFromAvr.java +++ b/services/core/java/com/android/server/hdmi/SystemAudioInitiationActionFromAvr.java @@ -41,7 +41,7 @@ public class SystemAudioInitiationActionFromAvr extends HdmiCecFeatureAction { @Override boolean start() { - if (audioSystem().mActiveSource.physicalAddress == Constants.INVALID_PHYSICAL_ADDRESS) { + if (audioSystem().getActiveSource().physicalAddress == Constants.INVALID_PHYSICAL_ADDRESS) { mState = STATE_WAITING_FOR_ACTIVE_SOURCE; addTimer(mState, HdmiConfig.TIMEOUT_MS); sendRequestActiveSource(); @@ -60,10 +60,8 @@ public class SystemAudioInitiationActionFromAvr extends HdmiCecFeatureAction { return false; } mActionTimer.clearTimerMessage(); - int physicalAddress = HdmiUtils.twoBytesToInt(cmd.getParams()); - if (physicalAddress != getSourcePath()) { - audioSystem().setActiveSource(cmd.getSource(), physicalAddress); - } + // Broadcast message is also handled by other device types + audioSystem().handleActiveSource(cmd); mState = STATE_WAITING_FOR_TV_SUPPORT; queryTvSystemAudioModeSupport(); return true; @@ -116,7 +114,16 @@ public class SystemAudioInitiationActionFromAvr extends HdmiCecFeatureAction { private void handleActiveSourceTimeout() { HdmiLogger.debug("Cannot get active source."); - audioSystem().checkSupportAndSetSystemAudioMode(false); + // If not able to find Active Source and the current device has playbcak functionality, + // claim Active Source and start to query TV system audio mode support. + if (audioSystem().mService.isPlaybackDevice()) { + audioSystem().mService.setAndBroadcastActiveSourceFromOneDeviceType( + Constants.ADDR_BROADCAST, getSourcePath()); + mState = STATE_WAITING_FOR_TV_SUPPORT; + queryTvSystemAudioModeSupport(); + } else { + audioSystem().checkSupportAndSetSystemAudioMode(false); + } finish(); } diff --git a/services/core/java/com/android/server/input/InputManagerService.java b/services/core/java/com/android/server/input/InputManagerService.java index 45a9bc01223c..df28f30d9127 100644 --- a/services/core/java/com/android/server/input/InputManagerService.java +++ b/services/core/java/com/android/server/input/InputManagerService.java @@ -1760,14 +1760,14 @@ public class InputManagerService extends IInputManager.Stub } // Native callback - private void notifyFocusChanged(IBinder token) { - if (mFocusedWindow.asBinder() == token) { + private void notifyFocusChanged(IBinder oldToken, IBinder newToken) { + if (mFocusedWindow.asBinder() == newToken) { Log.w(TAG, "notifyFocusChanged called with unchanged mFocusedWindow=" + mFocusedWindow); return; } setPointerCapture(false); - mFocusedWindow = IWindow.Stub.asInterface(token); + mFocusedWindow = IWindow.Stub.asInterface(newToken); } // Native callback. diff --git a/services/core/java/com/android/server/location/LocationRequestStatistics.java b/services/core/java/com/android/server/location/LocationRequestStatistics.java index b7934d978bac..b7ccb26da64b 100644 --- a/services/core/java/com/android/server/location/LocationRequestStatistics.java +++ b/services/core/java/com/android/server/location/LocationRequestStatistics.java @@ -123,6 +123,9 @@ public class LocationRequestStatistics { // in foreground. private long mForegroundDurationMs; + // Time when package last went dormant (stopped requesting location) + private long mLastStopElapsedTimeMs; + private PackageStatistics() { mInitialElapsedTimeMs = SystemClock.elapsedRealtime(); mNumActiveRequests = 0; @@ -131,6 +134,7 @@ public class LocationRequestStatistics { mSlowestIntervalMs = 0; mForegroundDurationMs = 0; mLastForegroundElapsedTimeMs = 0; + mLastStopElapsedTimeMs = 0; } private void startRequesting(long intervalMs) { @@ -167,8 +171,8 @@ public class LocationRequestStatistics { mNumActiveRequests--; if (mNumActiveRequests == 0) { - long lastDurationMs - = SystemClock.elapsedRealtime() - mLastActivitationElapsedTimeMs; + mLastStopElapsedTimeMs = SystemClock.elapsedRealtime(); + long lastDurationMs = mLastStopElapsedTimeMs - mLastActivitationElapsedTimeMs; mTotalDurationMs += lastDurationMs; updateForeground(false); } @@ -206,6 +210,13 @@ public class LocationRequestStatistics { } /** + * Returns the time since the last request stopped in ms. + */ + public long getTimeSinceLastRequestStoppedMs() { + return SystemClock.elapsedRealtime() - mLastStopElapsedTimeMs; + } + + /** * Returns the fastest interval that has been tracked. */ public long getFastestIntervalMs() { @@ -244,6 +255,10 @@ public class LocationRequestStatistics { .append(" minutes"); if (isActive()) { s.append(": Currently active"); + } else { + s.append(": Last active ") + .append((getTimeSinceLastRequestStoppedMs() / 1000) / 60) + .append(" minutes ago"); } return s.toString(); } diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index c68e0f98325e..7ecdad27c505 100644 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -77,6 +77,7 @@ import static android.view.WindowManager.LayoutParams.TYPE_TOAST; import static com.android.server.am.PendingIntentRecord.FLAG_ACTIVITY_SENDER; import static com.android.server.am.PendingIntentRecord.FLAG_BROADCAST_SENDER; +import static com.android.server.am.PendingIntentRecord.FLAG_SERVICE_SENDER; import static com.android.server.utils.PriorityDump.PRIORITY_ARG; import static com.android.server.utils.PriorityDump.PRIORITY_ARG_CRITICAL; import static com.android.server.utils.PriorityDump.PRIORITY_ARG_NORMAL; @@ -4452,7 +4453,8 @@ public class NotificationManagerService extends SystemService { am.setPendingIntentWhitelistDuration(pendingIntent.getTarget(), WHITELIST_TOKEN, duration); am.setPendingIntentAllowBgActivityStarts(pendingIntent.getTarget(), - WHITELIST_TOKEN, (FLAG_ACTIVITY_SENDER | FLAG_BROADCAST_SENDER)); + WHITELIST_TOKEN, (FLAG_ACTIVITY_SENDER | FLAG_BROADCAST_SENDER + | FLAG_SERVICE_SENDER)); } } } diff --git a/services/core/jni/com_android_server_input_InputManagerService.cpp b/services/core/jni/com_android_server_input_InputManagerService.cpp index 6f105ec90836..641200769cf0 100644 --- a/services/core/jni/com_android_server_input_InputManagerService.cpp +++ b/services/core/jni/com_android_server_input_InputManagerService.cpp @@ -244,7 +244,7 @@ public: const sp<IBinder>& token, const std::string& reason); virtual void notifyInputChannelBroken(const sp<IBinder>& token); - virtual void notifyFocusChanged(const sp<IBinder>& token); + virtual void notifyFocusChanged(const sp<IBinder>& oldToken, const sp<IBinder>& newToken); virtual bool filterInputEvent(const InputEvent* inputEvent, uint32_t policyFlags); virtual void getDispatcherConfiguration(InputDispatcherConfiguration* outConfig); virtual void interceptKeyBeforeQueueing(const KeyEvent* keyEvent, uint32_t& policyFlags); @@ -738,7 +738,8 @@ void NativeInputManager::notifyInputChannelBroken(const sp<IBinder>& token) { } } -void NativeInputManager::notifyFocusChanged(const sp<IBinder>& token) { +void NativeInputManager::notifyFocusChanged(const sp<IBinder>& oldToken, + const sp<IBinder>& newToken) { #if DEBUG_INPUT_DISPATCHER_POLICY ALOGD("notifyFocusChanged"); #endif @@ -746,12 +747,11 @@ void NativeInputManager::notifyFocusChanged(const sp<IBinder>& token) { JNIEnv* env = jniEnv(); - jobject tokenObj = javaObjectForIBinder(env, token); - if (tokenObj) { - env->CallVoidMethod(mServiceObj, gServiceClassInfo.notifyFocusChanged, - tokenObj); - checkAndClearExceptionFromCallback(env, "notifyFocusChanged"); - } + jobject oldTokenObj = javaObjectForIBinder(env, oldToken); + jobject newTokenObj = javaObjectForIBinder(env, newToken); + env->CallVoidMethod(mServiceObj, gServiceClassInfo.notifyFocusChanged, + oldTokenObj, newTokenObj); + checkAndClearExceptionFromCallback(env, "notifyFocusChanged"); } void NativeInputManager::getDispatcherConfiguration(InputDispatcherConfiguration* outConfig) { @@ -1762,7 +1762,7 @@ int register_android_server_InputManager(JNIEnv* env) { "notifyInputChannelBroken", "(Landroid/os/IBinder;)V"); GET_METHOD_ID(gServiceClassInfo.notifyFocusChanged, clazz, - "notifyFocusChanged", "(Landroid/os/IBinder;)V"); + "notifyFocusChanged", "(Landroid/os/IBinder;Landroid/os/IBinder;)V"); GET_METHOD_ID(gServiceClassInfo.notifyANR, clazz, "notifyANR", diff --git a/services/tests/servicestests/src/com/android/server/hdmi/ArcInitiationActionFromAvrTest.java b/services/tests/servicestests/src/com/android/server/hdmi/ArcInitiationActionFromAvrTest.java new file mode 100644 index 000000000000..8b0e8abf069d --- /dev/null +++ b/services/tests/servicestests/src/com/android/server/hdmi/ArcInitiationActionFromAvrTest.java @@ -0,0 +1,163 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.server.hdmi; + +import static com.android.server.hdmi.HdmiControlService.INITIATED_BY_ENABLE_CEC; + +import static com.google.common.truth.Truth.assertThat; + +import android.annotation.Nullable; +import android.app.Instrumentation; +import android.hardware.hdmi.HdmiDeviceInfo; +import android.hardware.tv.cec.V1_0.SendMessageResult; +import android.os.Looper; +import android.os.test.TestLooper; + +import androidx.test.InstrumentationRegistry; +import androidx.test.filters.SmallTest; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +import java.util.ArrayList; + +/** Tests for {@link ArcInitiationActionFromAvrTest} */ +@SmallTest +@RunWith(JUnit4.class) +public class ArcInitiationActionFromAvrTest { + + private HdmiDeviceInfo mDeviceInfoForTests; + private HdmiCecLocalDeviceAudioSystem mHdmiCecLocalDeviceAudioSystem; + private HdmiCecController mHdmiCecController; + private HdmiControlService mHdmiControlService; + private FakeNativeWrapper mNativeWrapper; + private ArcInitiationActionFromAvr mAction; + + private TestLooper mTestLooper = new TestLooper(); + private boolean mSendCecCommandSuccess; + private boolean mShouldDispatchARCInitiated; + private boolean mArcInitSent; + private boolean mRequestActiveSourceSent; + private Instrumentation mInstrumentation; + private ArrayList<HdmiCecLocalDevice> mLocalDevices = new ArrayList<>(); + + @Before + public void setUp() { + mDeviceInfoForTests = new HdmiDeviceInfo(1000, 1); + + mInstrumentation = InstrumentationRegistry.getInstrumentation(); + + mHdmiControlService = + new HdmiControlService(mInstrumentation.getTargetContext()) { + @Override + void sendCecCommand( + HdmiCecMessage command, @Nullable SendMessageCallback callback) { + switch (command.getOpcode()) { + case Constants.MESSAGE_REQUEST_ACTIVE_SOURCE: + if (callback != null) { + callback.onSendCompleted( + mSendCecCommandSuccess + ? SendMessageResult.SUCCESS + : SendMessageResult.NACK); + } + mRequestActiveSourceSent = true; + break; + case Constants.MESSAGE_INITIATE_ARC: + if (callback != null) { + callback.onSendCompleted( + mSendCecCommandSuccess + ? SendMessageResult.SUCCESS + : SendMessageResult.NACK); + } + mArcInitSent = true; + if (mShouldDispatchARCInitiated) { + mHdmiCecLocalDeviceAudioSystem.dispatchMessage( + HdmiCecMessageBuilder.buildReportArcInitiated( + Constants.ADDR_TV, + Constants.ADDR_AUDIO_SYSTEM)); + } + break; + default: + } + } + + @Override + boolean isPowerStandby() { + return false; + } + + @Override + boolean isAddressAllocated() { + return true; + } + + @Override + Looper getServiceLooper() { + return mTestLooper.getLooper(); + } + }; + + mHdmiCecLocalDeviceAudioSystem = + new HdmiCecLocalDeviceAudioSystem(mHdmiControlService) { + @Override + HdmiDeviceInfo getDeviceInfo() { + return mDeviceInfoForTests; + } + + @Override + void setArcStatus(boolean enabled) { + // do nothing + } + + @Override + protected boolean isSystemAudioActivated() { + return true; + } + }; + + mHdmiCecLocalDeviceAudioSystem.init(); + Looper looper = mTestLooper.getLooper(); + mHdmiControlService.setIoLooper(looper); + mNativeWrapper = new FakeNativeWrapper(); + mHdmiCecController = + HdmiCecController.createWithNativeWrapper(this.mHdmiControlService, mNativeWrapper); + mHdmiControlService.setCecController(mHdmiCecController); + mHdmiControlService.setHdmiMhlController(HdmiMhlControllerStub.create(mHdmiControlService)); + mHdmiControlService.setMessageValidator(new HdmiCecMessageValidator(mHdmiControlService)); + mHdmiControlService.initPortInfo(); + mAction = new ArcInitiationActionFromAvr(mHdmiCecLocalDeviceAudioSystem); + + mLocalDevices.add(mHdmiCecLocalDeviceAudioSystem); + mHdmiControlService.allocateLogicalAddress(mLocalDevices, INITIATED_BY_ENABLE_CEC); + mTestLooper.dispatchAll(); + } + + @Test + public void arcInitiation_requestActiveSource() { + mSendCecCommandSuccess = true; + mShouldDispatchARCInitiated = true; + mRequestActiveSourceSent = false; + mArcInitSent = false; + + mHdmiCecLocalDeviceAudioSystem.addAndStartAction(mAction); + mTestLooper.dispatchAll(); + + assertThat(mArcInitSent).isTrue(); + assertThat(mRequestActiveSourceSent).isTrue(); + } +} diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecControllerTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecControllerTest.java index da840be9bca7..93a09dc3ff04 100644 --- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecControllerTest.java +++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecControllerTest.java @@ -18,6 +18,7 @@ package com.android.server.hdmi; import static android.hardware.hdmi.HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM; import static android.hardware.hdmi.HdmiDeviceInfo.DEVICE_PLAYBACK; import static android.hardware.hdmi.HdmiDeviceInfo.DEVICE_TV; + import static com.android.server.hdmi.Constants.ADDR_AUDIO_SYSTEM; import static com.android.server.hdmi.Constants.ADDR_PLAYBACK_1; import static com.android.server.hdmi.Constants.ADDR_PLAYBACK_2; @@ -25,16 +26,21 @@ import static com.android.server.hdmi.Constants.ADDR_PLAYBACK_3; import static com.android.server.hdmi.Constants.ADDR_SPECIFIC_USE; import static com.android.server.hdmi.Constants.ADDR_TV; import static com.android.server.hdmi.Constants.ADDR_UNREGISTERED; + import static junit.framework.Assert.assertEquals; import android.content.Context; import android.hardware.tv.cec.V1_0.SendMessageResult; import android.os.Looper; import android.os.test.TestLooper; + import androidx.test.InstrumentationRegistry; import androidx.test.filters.SmallTest; + import com.android.server.hdmi.HdmiCecController.AllocateAddressCallback; + import org.junit.Before; +import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; @@ -136,6 +142,7 @@ public class HdmiCecControllerTest { assertEquals(ADDR_UNREGISTERED, mLogicalAddress); } + @Ignore("b/110413065 Support multiple device types 4 and 5.") @Test public void testAllocatLogicalAddress_PlaybackPreferredNotOccupied() { mHdmiCecController.allocateLogicalAddress(DEVICE_PLAYBACK, ADDR_PLAYBACK_1, mCallback); @@ -151,6 +158,7 @@ public class HdmiCecControllerTest { assertEquals(ADDR_PLAYBACK_2, mLogicalAddress); } + @Ignore("b/110413065 Support multiple device types 4 and 5.") @Test public void testAllocatLogicalAddress_PlaybackNoPreferredNotOcuppied() { mHdmiCecController.allocateLogicalAddress(DEVICE_PLAYBACK, ADDR_UNREGISTERED, mCallback); diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystemTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystemTest.java index c442ae845d4b..b47f269bc721 100644 --- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystemTest.java +++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystemTest.java @@ -36,6 +36,7 @@ import androidx.test.filters.SmallTest; import com.android.server.hdmi.HdmiCecLocalDevice.ActiveSource; import org.junit.Before; +import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; @@ -126,16 +127,16 @@ public class HdmiCecLocalDeviceAudioSystemTest { @Override void wakeUp() {} - - @Override - boolean isControlEnabled() { - return true; - } }; mMyLooper = mTestLooper.getLooper(); mHdmiCecLocalDeviceAudioSystem = new HdmiCecLocalDeviceAudioSystem(mHdmiControlService); - mHdmiCecLocalDevicePlayback = new HdmiCecLocalDevicePlayback(mHdmiControlService); + mHdmiCecLocalDevicePlayback = new HdmiCecLocalDevicePlayback(mHdmiControlService) { + @Override + void setIsActiveSource(boolean on) { + mIsActiveSource = on; + } + }; mHdmiCecLocalDeviceAudioSystem.init(); mHdmiCecLocalDevicePlayback.init(); mHdmiControlService.setIoLooper(mMyLooper); @@ -297,8 +298,6 @@ public class HdmiCecLocalDeviceAudioSystemTest { @Test public void onStandbyAudioSystem_currentSystemAudioControlOn() throws Exception { - mHdmiCecLocalDeviceAudioSystem.setAutoDeviceOff(false); - mHdmiCecLocalDeviceAudioSystem.setAutoTvOff(false); // Set system audio control on first mHdmiCecLocalDeviceAudioSystem.checkSupportAndSetSystemAudioMode(true); // Check if standby correctly turns off the feature @@ -518,17 +517,6 @@ public class HdmiCecLocalDeviceAudioSystemTest { assertThat(mNativeWrapper.getOnlyResultMessage()).isEqualTo(expectedMessage); } - @Test - public void onStandby_setAutoDeviceOff_true() throws Exception { - HdmiCecMessage expectedMessage = - HdmiCecMessageBuilder.buildStandby(ADDR_AUDIO_SYSTEM, ADDR_BROADCAST); - mHdmiCecLocalDeviceAudioSystem.setAutoDeviceOff(true); - mHdmiCecLocalDeviceAudioSystem.onStandby(false, STANDBY_SCREEN_OFF); - - mTestLooper.dispatchAll(); - assertThat(mNativeWrapper.getOnlyResultMessage()).isEqualTo(expectedMessage); - } - public void handleSystemAudioModeRequest_fromNonTV_tVNotSupport() { HdmiCecMessage message = HdmiCecMessageBuilder.buildSystemAudioModeRequest( @@ -577,30 +565,31 @@ public class HdmiCecLocalDeviceAudioSystemTest { .isEqualTo(expectedActiveSource); } + @Ignore("b/110413065 Support multiple device types 4 and 5.") @Test public void handleRoutingChange_currentActivePortIsHome() { HdmiCecMessage message = HdmiCecMessageBuilder.buildRoutingChange(ADDR_TV, 0x3000, mAvrPhysicalAddress); HdmiCecMessage expectedMessage = - HdmiCecMessageBuilder.buildActiveSource(ADDR_AUDIO_SYSTEM, mAvrPhysicalAddress); - ActiveSource expectedActiveSource = ActiveSource.of(ADDR_AUDIO_SYSTEM, mAvrPhysicalAddress); + HdmiCecMessageBuilder.buildActiveSource(ADDR_PLAYBACK_1, mAvrPhysicalAddress); + ActiveSource expectedActiveSource = ActiveSource.of(ADDR_PLAYBACK_1, mAvrPhysicalAddress); int expectedLocalActivePort = Constants.CEC_SWITCH_HOME; assertThat(mHdmiCecLocalDeviceAudioSystem.handleRoutingChange(message)).isTrue(); mTestLooper.dispatchAll(); assertThat(mHdmiCecLocalDeviceAudioSystem.getActiveSource()) .isEqualTo(expectedActiveSource); - assertThat(mHdmiCecLocalDeviceAudioSystem.getLocalActivePort()) + assertThat(mHdmiCecLocalDeviceAudioSystem.getRoutingPort()) .isEqualTo(expectedLocalActivePort); - assertThat(mNativeWrapper.getOnlyResultMessage()).isEqualTo(expectedMessage); + assertThat(mNativeWrapper.getResultMessages()).contains(expectedMessage); } @Test public void handleRoutingInformation_currentActivePortIsHDMI1() { HdmiCecMessage message = HdmiCecMessageBuilder.buildRoutingInformation(ADDR_TV, 0x2000); - mHdmiCecLocalDeviceAudioSystem.setLocalActivePort(Constants.CEC_SWITCH_HDMI1); + mHdmiCecLocalDeviceAudioSystem.setRoutingPort(Constants.CEC_SWITCH_HDMI1); HdmiCecMessage expectedMessage = HdmiCecMessageBuilder.buildRoutingInformation(ADDR_AUDIO_SYSTEM, 0x2100); @@ -609,6 +598,7 @@ public class HdmiCecLocalDeviceAudioSystemTest { assertThat(mNativeWrapper.getOnlyResultMessage()).isEqualTo(expectedMessage); } + @Ignore("b/110413065 Support multiple device types 4 and 5.") @Test public void handleRoutingChange_homeIsActive_playbackSendActiveSource() { HdmiCecMessage message = @@ -619,6 +609,6 @@ public class HdmiCecLocalDeviceAudioSystemTest { assertThat(mHdmiCecLocalDeviceAudioSystem.handleRoutingChange(message)).isTrue(); mTestLooper.dispatchAll(); - assertThat(mNativeWrapper.getOnlyResultMessage()).isEqualTo(expectedMessage); + assertThat(mNativeWrapper.getResultMessages()).contains(expectedMessage); } } diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java index 76f638cb4351..792c617b99ea 100644 --- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java +++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java @@ -27,6 +27,7 @@ import androidx.test.InstrumentationRegistry; import androidx.test.filters.SmallTest; import org.junit.Before; +import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; @@ -80,12 +81,14 @@ public class HdmiCecLocalDevicePlaybackTest { mNativeWrapper.setPhysicalAddress(mPlaybackPhysicalAddress); } + @Ignore @Test public void handleSetStreamPath_underCurrentDevice() { assertThat(mHdmiCecLocalDevicePlayback.getLocalActivePath()).isEqualTo(0); HdmiCecMessage message = HdmiCecMessageBuilder.buildSetStreamPath(ADDR_TV, 0x2100); assertThat(mHdmiCecLocalDevicePlayback.handleSetStreamPath(message)).isTrue(); + // TODO(amyjojo): Move set and get LocalActivePath to Control Service. assertThat(mHdmiCecLocalDevicePlayback.getLocalActivePath()).isEqualTo(1); } } diff --git a/services/tests/servicestests/src/com/android/server/hdmi/SystemAudioInitiationActionFromAvrTest.java b/services/tests/servicestests/src/com/android/server/hdmi/SystemAudioInitiationActionFromAvrTest.java index d914b9a090a2..bd297eecf25c 100644 --- a/services/tests/servicestests/src/com/android/server/hdmi/SystemAudioInitiationActionFromAvrTest.java +++ b/services/tests/servicestests/src/com/android/server/hdmi/SystemAudioInitiationActionFromAvrTest.java @@ -26,8 +26,10 @@ import android.hardware.tv.cec.V1_0.SendMessageResult; import android.media.AudioManager; import android.os.Looper; import android.os.test.TestLooper; + import androidx.test.InstrumentationRegistry; import androidx.test.filters.SmallTest; + import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -49,6 +51,9 @@ public class SystemAudioInitiationActionFromAvrTest { private int mMsgRequestActiveSourceCount; private int mMsgSetSystemAudioModeCount; private int mQueryTvSystemAudioModeSupportCount; + private boolean mArcEnabled; + private boolean mIsPlaybackDevice; + private boolean mBroadcastActiveSource; @Before public void SetUp() { @@ -80,6 +85,8 @@ public class SystemAudioInitiationActionFromAvrTest { callback.onSendCompleted(SendMessageResult.NACK); } break; + case Constants.MESSAGE_INITIATE_ARC: + break; default: throw new IllegalArgumentException("Unexpected message"); } @@ -132,6 +139,17 @@ public class SystemAudioInitiationActionFromAvrTest { int getPhysicalAddress() { return 0; } + + @Override + boolean isPlaybackDevice() { + return mIsPlaybackDevice; + } + + @Override + public void setAndBroadcastActiveSourceFromOneDeviceType( + int sourceAddress, int physicalAddress) { + mBroadcastActiveSource = true; + } }; mHdmiCecLocalDeviceAudioSystem = new HdmiCecLocalDeviceAudioSystem(hdmiControlService) { @@ -148,6 +166,11 @@ public class SystemAudioInitiationActionFromAvrTest { HdmiDeviceInfo getDeviceInfo() { return mDeviceInfoForTests; } + + @Override + void setArcStatus(boolean enabled) { + mArcEnabled = enabled; + } }; mHdmiCecLocalDeviceAudioSystem.init(); Looper looper = mTestLooper.getLooper(); @@ -159,7 +182,7 @@ public class SystemAudioInitiationActionFromAvrTest { resetTestVariables(); mShouldDispatchActiveSource = false; - assertThat(mHdmiCecLocalDeviceAudioSystem.mActiveSource.physicalAddress) + assertThat(mHdmiCecLocalDeviceAudioSystem.getActiveSource().physicalAddress) .isEqualTo(Constants.INVALID_PHYSICAL_ADDRESS); mHdmiCecLocalDeviceAudioSystem.addAndStartAction( @@ -171,7 +194,7 @@ public class SystemAudioInitiationActionFromAvrTest { assertThat(mQueryTvSystemAudioModeSupportCount).isEqualTo(0); assertFalse(mHdmiCecLocalDeviceAudioSystem.isSystemAudioActivated()); - assertThat(mHdmiCecLocalDeviceAudioSystem.mActiveSource.physicalAddress) + assertThat(mHdmiCecLocalDeviceAudioSystem.getActiveSource().physicalAddress) .isEqualTo(Constants.INVALID_PHYSICAL_ADDRESS); } @@ -206,14 +229,15 @@ public class SystemAudioInitiationActionFromAvrTest { assertThat(mQueryTvSystemAudioModeSupportCount).isEqualTo(1); assertTrue(mHdmiCecLocalDeviceAudioSystem.isSystemAudioActivated()); - assertThat(mHdmiCecLocalDeviceAudioSystem.mActiveSource.physicalAddress).isEqualTo(1002); + assertThat(mHdmiCecLocalDeviceAudioSystem.getActiveSource().physicalAddress) + .isEqualTo(1002); } @Test public void testKnownActiveSource() { resetTestVariables(); mTvSystemAudioModeSupport = true; - mHdmiCecLocalDeviceAudioSystem.mActiveSource.physicalAddress = 1001; + mHdmiCecLocalDeviceAudioSystem.getActiveSource().physicalAddress = 1001; mHdmiCecLocalDeviceAudioSystem.addAndStartAction( new SystemAudioInitiationActionFromAvr(mHdmiCecLocalDeviceAudioSystem)); @@ -233,7 +257,7 @@ public class SystemAudioInitiationActionFromAvrTest { mTryCountBeforeSucceed = 3; assertThat(mTryCountBeforeSucceed) .isAtMost(SystemAudioInitiationActionFromAvr.MAX_RETRY_COUNT); - assertThat(mHdmiCecLocalDeviceAudioSystem.mActiveSource.physicalAddress) + assertThat(mHdmiCecLocalDeviceAudioSystem.getActiveSource().physicalAddress) .isEqualTo(Constants.INVALID_PHYSICAL_ADDRESS); mHdmiCecLocalDeviceAudioSystem.addAndStartAction( @@ -246,12 +270,32 @@ public class SystemAudioInitiationActionFromAvrTest { assertTrue(mHdmiCecLocalDeviceAudioSystem.isSystemAudioActivated()); } + @Test + public void testIsPlaybackDevice_cannotReceiveActiveSource() { + resetTestVariables(); + mIsPlaybackDevice = true; + assertThat(mHdmiCecLocalDeviceAudioSystem.getActiveSource().physicalAddress) + .isEqualTo(Constants.INVALID_PHYSICAL_ADDRESS); + + mHdmiCecLocalDeviceAudioSystem.addAndStartAction( + new SystemAudioInitiationActionFromAvr(mHdmiCecLocalDeviceAudioSystem)); + mTestLooper.dispatchAll(); + + assertThat(mMsgRequestActiveSourceCount).isEqualTo(1); + assertThat(mMsgSetSystemAudioModeCount).isEqualTo(1); + assertThat(mQueryTvSystemAudioModeSupportCount).isEqualTo(1); + assertThat(mHdmiCecLocalDeviceAudioSystem.isSystemAudioActivated()).isTrue(); + assertThat(mBroadcastActiveSource).isTrue(); + } + private void resetTestVariables() { mMsgRequestActiveSourceCount = 0; mMsgSetSystemAudioModeCount = 0; mQueryTvSystemAudioModeSupportCount = 0; mTryCountBeforeSucceed = 0; - mHdmiCecLocalDeviceAudioSystem.mActiveSource.physicalAddress = + mIsPlaybackDevice = false; + mBroadcastActiveSource = false; + mHdmiCecLocalDeviceAudioSystem.getActiveSource().physicalAddress = Constants.INVALID_PHYSICAL_ADDRESS; } } diff --git a/telephony/java/android/telephony/DataSpecificRegistrationStates.java b/telephony/java/android/telephony/DataSpecificRegistrationStates.java index 5d809d0b7c36..d6a8065feabe 100644 --- a/telephony/java/android/telephony/DataSpecificRegistrationStates.java +++ b/telephony/java/android/telephony/DataSpecificRegistrationStates.java @@ -44,13 +44,19 @@ public class DataSpecificRegistrationStates implements Parcelable{ */ public final boolean isEnDcAvailable; + /** + * Provides network support info for LTE VoPS and LTE Emergency bearer support + */ + public final LteVopsSupportInfo lteVopsSupportInfo; + DataSpecificRegistrationStates( int maxDataCalls, boolean isDcNrRestricted, boolean isNrAvailable, - boolean isEnDcAvailable) { + boolean isEnDcAvailable, LteVopsSupportInfo lteVops) { this.maxDataCalls = maxDataCalls; this.isDcNrRestricted = isDcNrRestricted; this.isNrAvailable = isNrAvailable; this.isEnDcAvailable = isEnDcAvailable; + this.lteVopsSupportInfo = lteVops; } private DataSpecificRegistrationStates(Parcel source) { @@ -58,6 +64,7 @@ public class DataSpecificRegistrationStates implements Parcelable{ isDcNrRestricted = source.readBoolean(); isNrAvailable = source.readBoolean(); isEnDcAvailable = source.readBoolean(); + lteVopsSupportInfo = LteVopsSupportInfo.CREATOR.createFromParcel(source); } @Override @@ -66,6 +73,7 @@ public class DataSpecificRegistrationStates implements Parcelable{ dest.writeBoolean(isDcNrRestricted); dest.writeBoolean(isNrAvailable); dest.writeBoolean(isEnDcAvailable); + lteVopsSupportInfo.writeToParcel(dest, flags); } @Override @@ -81,13 +89,15 @@ public class DataSpecificRegistrationStates implements Parcelable{ .append(" isDcNrRestricted = " + isDcNrRestricted) .append(" isNrAvailable = " + isNrAvailable) .append(" isEnDcAvailable = " + isEnDcAvailable) + .append(lteVopsSupportInfo.toString()) .append(" }") .toString(); } @Override public int hashCode() { - return Objects.hash(maxDataCalls, isDcNrRestricted, isNrAvailable, isEnDcAvailable); + return Objects.hash(maxDataCalls, isDcNrRestricted, isNrAvailable, isEnDcAvailable, + lteVopsSupportInfo); } @Override @@ -100,7 +110,8 @@ public class DataSpecificRegistrationStates implements Parcelable{ return this.maxDataCalls == other.maxDataCalls && this.isDcNrRestricted == other.isDcNrRestricted && this.isNrAvailable == other.isNrAvailable - && this.isEnDcAvailable == other.isEnDcAvailable; + && this.isEnDcAvailable == other.isEnDcAvailable + && this.lteVopsSupportInfo.equals(other.lteVopsSupportInfo); } public static final Parcelable.Creator<DataSpecificRegistrationStates> CREATOR = @@ -115,4 +126,4 @@ public class DataSpecificRegistrationStates implements Parcelable{ return new DataSpecificRegistrationStates[size]; } }; -}
\ No newline at end of file +} diff --git a/telephony/java/android/telephony/LteVopsSupportInfo.aidl b/telephony/java/android/telephony/LteVopsSupportInfo.aidl new file mode 100644 index 000000000000..598459853d1c --- /dev/null +++ b/telephony/java/android/telephony/LteVopsSupportInfo.aidl @@ -0,0 +1,19 @@ +/* + * Copyright 2018 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.telephony; + +parcelable LteVopsSupportInfo; diff --git a/telephony/java/android/telephony/LteVopsSupportInfo.java b/telephony/java/android/telephony/LteVopsSupportInfo.java new file mode 100644 index 000000000000..0ae85c0dfa6c --- /dev/null +++ b/telephony/java/android/telephony/LteVopsSupportInfo.java @@ -0,0 +1,137 @@ +/* + * Copyright (C) 2018 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.telephony; + +import android.annotation.IntDef; +import android.annotation.SystemApi; +import android.os.Parcel; +import android.os.Parcelable; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.util.Objects; + +/** + * Class stores information related to LTE network VoPS support + * @hide + */ +@SystemApi +public final class LteVopsSupportInfo implements Parcelable { + + /**@hide*/ + @Retention(RetentionPolicy.SOURCE) + @IntDef( + value = {LTE_STATUS_NOT_AVAILABLE, LTE_STATUS_SUPPORTED, + LTE_STATUS_NOT_SUPPORTED}, prefix = "LTE_STATUS_") + public @interface LteVopsStatus {} + /** + * Indicates information not available from modem. + */ + public static final int LTE_STATUS_NOT_AVAILABLE = 1; + + /** + * Indicates network support the feature. + */ + public static final int LTE_STATUS_SUPPORTED = 2; + + /** + * Indicates network does not support the feature. + */ + public static final int LTE_STATUS_NOT_SUPPORTED = 3; + + @LteVopsStatus + private final int mVopsSupport; + @LteVopsStatus + private final int mEmcBearerSupport; + + public LteVopsSupportInfo(@LteVopsStatus int vops, @LteVopsStatus int emergency) { + mVopsSupport = vops; + mEmcBearerSupport = emergency; + } + + /** + * Provides the LTE VoPS support capability as described in: + * 3GPP 24.301 EPS network feature support -> IMS VoPS + */ + public @LteVopsStatus int getVopsSupport() { + return mVopsSupport; + } + + /** + * Provides the LTE Emergency bearer support capability as described in: + * 3GPP 24.301 EPS network feature support -> EMC BS + * 25.331 LTE RRC SIB1 : ims-EmergencySupport-r9 + */ + public @LteVopsStatus int getEmcBearerSupport() { + return mEmcBearerSupport; + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel out, int flags) { + out.writeInt(mVopsSupport); + out.writeInt(mEmcBearerSupport); + } + + @Override + public boolean equals(Object o) { + if (o == null || !(o instanceof LteVopsSupportInfo)) { + return false; + } + if (this == o) return true; + LteVopsSupportInfo other = (LteVopsSupportInfo) o; + return mVopsSupport == other.mVopsSupport + && mEmcBearerSupport == other.mEmcBearerSupport; + } + + @Override + public int hashCode() { + return Objects.hash(mVopsSupport, mEmcBearerSupport); + } + + /** + * @return string representation. + */ + @Override + public String toString() { + return ("LteVopsSupportInfo : " + + " mVopsSupport = " + mVopsSupport + + " mEmcBearerSupport = " + mEmcBearerSupport); + } + + public static final Creator<LteVopsSupportInfo> CREATOR = + new Creator<LteVopsSupportInfo>() { + @Override + public LteVopsSupportInfo createFromParcel(Parcel in) { + return new LteVopsSupportInfo(in); + } + + @Override + public LteVopsSupportInfo[] newArray(int size) { + return new LteVopsSupportInfo[size]; + } + }; + + private LteVopsSupportInfo(Parcel in) { + mVopsSupport = in.readInt(); + mEmcBearerSupport = in.readInt(); + } +} diff --git a/telephony/java/android/telephony/NetworkRegistrationState.java b/telephony/java/android/telephony/NetworkRegistrationState.java index b00665e26ff2..ceb76b57ae0c 100644 --- a/telephony/java/android/telephony/NetworkRegistrationState.java +++ b/telephony/java/android/telephony/NetworkRegistrationState.java @@ -219,12 +219,13 @@ public class NetworkRegistrationState implements Parcelable { public NetworkRegistrationState(int domain, int transportType, int regState, int accessNetworkTechnology, int rejectCause, boolean emergencyOnly, int[] availableServices, @Nullable CellIdentity cellIdentity, int maxDataCalls, - boolean isDcNrRestricted, boolean isNrAvailable, boolean isEndcAvailable) { + boolean isDcNrRestricted, boolean isNrAvailable, boolean isEndcAvailable, + LteVopsSupportInfo lteVopsSupportInfo) { this(domain, transportType, regState, accessNetworkTechnology, rejectCause, emergencyOnly, availableServices, cellIdentity); mDataSpecificStates = new DataSpecificRegistrationStates( - maxDataCalls, isDcNrRestricted, isNrAvailable, isEndcAvailable); + maxDataCalls, isDcNrRestricted, isNrAvailable, isEndcAvailable, lteVopsSupportInfo); updateNrStatus(mDataSpecificStates); } diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java index 648400509bac..b48a1ced61a4 100644 --- a/telephony/java/android/telephony/TelephonyManager.java +++ b/telephony/java/android/telephony/TelephonyManager.java @@ -76,8 +76,8 @@ import com.android.ims.internal.IImsServiceFeatureCallback; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.telecom.ITelecomService; import com.android.internal.telephony.CellNetworkScanResult; -import com.android.internal.telephony.IAns; import com.android.internal.telephony.INumberVerificationCallback; +import com.android.internal.telephony.IOns; import com.android.internal.telephony.IPhoneSubInfo; import com.android.internal.telephony.ITelephony; import com.android.internal.telephony.ITelephonyRegistry; @@ -4651,8 +4651,8 @@ public class TelephonyManager { return ITelephonyRegistry.Stub.asInterface(ServiceManager.getService("telephony.registry")); } - private IAns getIAns() { - return IAns.Stub.asInterface(ServiceManager.getService("ians")); + private IOns getIOns() { + return IOns.Stub.asInterface(ServiceManager.getService("ions")); } // @@ -9456,10 +9456,10 @@ public class TelephonyManager { } /** - * Enable or disable AlternativeNetworkService. + * Enable or disable OpportunisticNetworkService. * * This method should be called to enable or disable - * AlternativeNetwork service on the device. + * OpportunisticNetwork service on the device. * * <p> * Requires Permission: @@ -9470,25 +9470,25 @@ public class TelephonyManager { * @hide */ @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) - public boolean setAlternativeNetworkState(boolean enable) { + public boolean setOpportunisticNetworkState(boolean enable) { String pkgForDebug = mContext != null ? mContext.getOpPackageName() : "<unknown>"; boolean ret = false; try { - IAns iAlternativeNetworkService = getIAns(); - if (iAlternativeNetworkService != null) { - ret = iAlternativeNetworkService.setEnable(enable, pkgForDebug); + IOns iOpportunisticNetworkService = getIOns(); + if (iOpportunisticNetworkService != null) { + ret = iOpportunisticNetworkService.setEnable(enable, pkgForDebug); } } catch (RemoteException ex) { - Rlog.e(TAG, "enableAlternativeNetwork RemoteException", ex); + Rlog.e(TAG, "enableOpportunisticNetwork RemoteException", ex); } return ret; } /** - * is AlternativeNetworkService enabled + * is OpportunisticNetworkService enabled * - * This method should be called to determine if the AlternativeNetworkService is + * This method should be called to determine if the OpportunisticNetworkService is * enabled * * <p> @@ -9497,17 +9497,17 @@ public class TelephonyManager { * @hide */ @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) - public boolean isAlternativeNetworkEnabled() { + public boolean isOpportunisticNetworkEnabled() { String pkgForDebug = mContext != null ? mContext.getOpPackageName() : "<unknown>"; boolean isEnabled = false; try { - IAns iAlternativeNetworkService = getIAns(); - if (iAlternativeNetworkService != null) { - isEnabled = iAlternativeNetworkService.isEnabled(pkgForDebug); + IOns iOpportunisticNetworkService = getIOns(); + if (iOpportunisticNetworkService != null) { + isEnabled = iOpportunisticNetworkService.isEnabled(pkgForDebug); } } catch (RemoteException ex) { - Rlog.e(TAG, "enableAlternativeNetwork RemoteException", ex); + Rlog.e(TAG, "enableOpportunisticNetwork RemoteException", ex); } return isEnabled; @@ -9862,9 +9862,9 @@ public class TelephonyManager { public boolean setPreferredOpportunisticDataSubscription(int subId) { String pkgForDebug = mContext != null ? mContext.getOpPackageName() : "<unknown>"; try { - IAns iAlternativeNetworkService = getIAns(); - if (iAlternativeNetworkService != null) { - return iAlternativeNetworkService.setPreferredData(subId, pkgForDebug); + IOns iOpportunisticNetworkService = getIOns(); + if (iOpportunisticNetworkService != null) { + return iOpportunisticNetworkService.setPreferredData(subId, pkgForDebug); } } catch (RemoteException ex) { Rlog.e(TAG, "setPreferredData RemoteException", ex); @@ -9886,9 +9886,9 @@ public class TelephonyManager { String pkgForDebug = mContext != null ? mContext.getOpPackageName() : "<unknown>"; int subId = SubscriptionManager.INVALID_SUBSCRIPTION_ID; try { - IAns iAlternativeNetworkService = getIAns(); - if (iAlternativeNetworkService != null) { - subId = iAlternativeNetworkService.getPreferredData(pkgForDebug); + IOns iOpportunisticNetworkService = getIOns(); + if (iOpportunisticNetworkService != null) { + subId = iOpportunisticNetworkService.getPreferredData(pkgForDebug); } } catch (RemoteException ex) { Rlog.e(TAG, "getPreferredData RemoteException", ex); @@ -9899,8 +9899,8 @@ public class TelephonyManager { /** * Update availability of a list of networks in the current location. * - * This api should be called to inform AlternativeNetwork Service about the availability - * of a network at the current location. This information will be used by AlternativeNetwork + * This api should be called to inform OpportunisticNetwork Service about the availability + * of a network at the current location. This information will be used by OpportunisticNetwork * service to decide to attach to the network opportunistically. If an empty list is passed, * it is assumed that no network is available. * Requires that the calling app has carrier privileges on both primary and @@ -9915,9 +9915,9 @@ public class TelephonyManager { String pkgForDebug = mContext != null ? mContext.getOpPackageName() : "<unknown>"; boolean ret = false; try { - IAns iAlternativeNetworkService = getIAns(); - if (iAlternativeNetworkService != null) { - ret = iAlternativeNetworkService.updateAvailableNetworks(availableNetworks, + IOns iOpportunisticNetworkService = getIOns(); + if (iOpportunisticNetworkService != null) { + ret = iOpportunisticNetworkService.updateAvailableNetworks(availableNetworks, pkgForDebug); } } catch (RemoteException ex) { diff --git a/telephony/java/com/android/internal/telephony/IAns.aidl b/telephony/java/com/android/internal/telephony/IOns.aidl index 98bcd415a1ca..d6779f1fb334 100755 --- a/telephony/java/com/android/internal/telephony/IAns.aidl +++ b/telephony/java/com/android/internal/telephony/IOns.aidl @@ -18,13 +18,13 @@ package com.android.internal.telephony; import android.telephony.AvailableNetworkInfo; -interface IAns { +interface IOns { /** - * Enable or disable Alternative Network service. + * Enable or disable Opportunistic Network service. * * This method should be called to enable or disable - * AlternativeNetwork service on the device. + * OpportunisticNetwork service on the device. * * <p> * Requires Permission: @@ -38,9 +38,9 @@ interface IAns { boolean setEnable(boolean enable, String callingPackage); /** - * is Alternative Network service enabled + * is Opportunistic Network service enabled * - * This method should be called to determine if the Alternative Network service is enabled + * This method should be called to determine if the Opportunistic Network service is enabled * * <p> * Requires Permission: @@ -84,7 +84,7 @@ interface IAns { * Update availability of a list of networks in the current location. * * This api should be called if the caller is aware of the availability of a network - * at the current location. This information will be used by AlternativeNetwork service + * at the current location. This information will be used by OpportunisticNetwork service * to decide to attach to the network. If an empty list is passed, * it is assumed that no network is available. * Requires that the calling app has carrier privileges on both primary and diff --git a/tools/aapt2/Android.bp b/tools/aapt2/Android.bp index c42a8889e373..0580df60f32a 100644 --- a/tools/aapt2/Android.bp +++ b/tools/aapt2/Android.bp @@ -58,6 +58,7 @@ cc_defaults { "libprotobuf-cpp-lite", "libz", ], + stl: "libc++_static", group_static_libs: true, } |