diff options
20 files changed, 495 insertions, 80 deletions
diff --git a/PREUPLOAD.cfg b/PREUPLOAD.cfg index 9b290c6a4760..2fd2e33bbc37 100644 --- a/PREUPLOAD.cfg +++ b/PREUPLOAD.cfg @@ -12,6 +12,8 @@ clang_format = --commit ${PREUPLOAD_COMMIT} --style file --extensions c,h,cc,cpp services/incremental/ [Hook Scripts] +checkstyle_hook = ${REPO_ROOT}/prebuilts/checkstyle/checkstyle.py --sha ${PREUPLOAD_COMMIT} + strings_lint_hook = ${REPO_ROOT}/frameworks/base/tools/stringslint/stringslint_sha.sh ${PREUPLOAD_COMMIT} hidden_api_txt_checksorted_hook = ${REPO_ROOT}/frameworks/base/tools/hiddenapi/checksorted_sha.sh ${PREUPLOAD_COMMIT} ${REPO_ROOT} diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java index c498e926ba47..d642f218cb71 100644 --- a/core/java/android/app/AppOpsManager.java +++ b/core/java/android/app/AppOpsManager.java @@ -7542,6 +7542,7 @@ public class AppOpsManager { * * @hide */ + @SuppressWarnings("AndroidFrameworkClientSidePermissionCheck") public int noteProxyOpNoThrow(int op, @Nullable String proxiedPackageName, int proxiedUid, @Nullable String proxiedAttributionTag, @Nullable String message) { int myUid = Process.myUid(); diff --git a/core/java/android/os/IPowerManager.aidl b/core/java/android/os/IPowerManager.aidl index ce6c0ffbc10b..d2fc1d3be40c 100644 --- a/core/java/android/os/IPowerManager.aidl +++ b/core/java/android/os/IPowerManager.aidl @@ -32,6 +32,7 @@ interface IPowerManager @UnsupportedAppUsage void releaseWakeLock(IBinder lock, int flags); void updateWakeLockUids(IBinder lock, in int[] uids); + oneway void powerHint(int hintId, int data); oneway void setPowerBoost(int boost, int durationMs); oneway void setPowerMode(int mode, boolean enabled); diff --git a/core/java/android/os/PowerManagerInternal.java b/core/java/android/os/PowerManagerInternal.java index e30a40964992..653a5594f495 100644 --- a/core/java/android/os/PowerManagerInternal.java +++ b/core/java/android/os/PowerManagerInternal.java @@ -196,6 +196,12 @@ public abstract class PowerManagerInternal { public abstract void uidIdle(int uid); /** + * The hintId sent through this method should be in-line with the + * PowerHint defined in android/hardware/power/<version 1.0 & up>/IPower.h + */ + public abstract void powerHint(int hintId, int data); + + /** * Boost: It is sent when user interacting with the device, for example, * touchscreen events are incoming. * Defined in hardware/interfaces/power/aidl/android/hardware/power/Boost.aidl diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index b022d2af7772..f2cec250d47f 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -1816,13 +1816,19 @@ public final class ViewRootImpl implements ViewParent, /** * Called after window layout to update the bounds surface. If the surface insets have changed * or the surface has resized, update the bounds surface. + * + * @param shouldReparent Whether it should reparent the bounds layer to the main SurfaceControl. */ - private void updateBoundsLayer() { + private void updateBoundsLayer(boolean shouldReparent) { if (mBoundsLayer != null) { setBoundsLayerCrop(); - mTransaction.deferTransactionUntil(mBoundsLayer, - getRenderSurfaceControl(), mSurface.getNextFrameNumber()) - .apply(); + mTransaction.deferTransactionUntil(mBoundsLayer, getRenderSurfaceControl(), + mSurface.getNextFrameNumber()); + + if (shouldReparent) { + mTransaction.reparent(mBoundsLayer, getRenderSurfaceControl()); + } + mTransaction.apply(); } } @@ -2904,7 +2910,16 @@ public final class ViewRootImpl implements ViewParent, } if (surfaceSizeChanged || surfaceReplaced || surfaceCreated || windowAttributesChanged) { - updateBoundsLayer(); + // If the surface has been replaced, there's a chance the bounds layer is not parented + // to the new layer. When updating bounds layer, also reparent to the main VRI + // SurfaceControl to ensure it's correctly placed in the hierarchy. + // + // This needs to be done on the client side since WMS won't reparent the children to the + // new surface if it thinks the app is closing. WMS gets the signal that the app is + // stopping, but on the client side it doesn't get stopped since it's restarted quick + // enough. WMS doesn't want to keep around old children since they will leak when the + // client creates new children. + updateBoundsLayer(surfaceReplaced); } final boolean didLayout = layoutRequested && (!mStopped || mReportNextDraw); @@ -0,0 +1,25 @@ +diff --git a/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java b/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java +index fc43882..832dc91 100644 +--- a/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java ++++ b/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java +@@ -67,6 +67,7 @@ import java.util.Arrays; + import java.util.HashSet; + import java.util.List; + import java.util.Set; ++import java.util.NoSuchElementException; + + /** + * This class represents an accessibility client - either an AccessibilityService or a UiAutomation. +@@ -978,7 +979,11 @@ abstract class AbstractAccessibilityServiceConnection extends IAccessibilityServ + /* ignore */ + } + if (mService != null) { +- mService.unlinkToDeath(this, 0); ++ try { ++ mService.unlinkToDeath(this, 0); ++ }catch(NoSuchElementException e) { ++ Slog.e(LOG_TAG, "Failed unregistering death link"); ++ } + mService = null; + } + diff --git a/packages/SettingsLib/res/values-eu/strings.xml b/packages/SettingsLib/res/values-eu/strings.xml index 376c2e796f77..0042321a3654 100644 --- a/packages/SettingsLib/res/values-eu/strings.xml +++ b/packages/SettingsLib/res/values-eu/strings.xml @@ -37,7 +37,7 @@ <string name="wifi_no_internet" msgid="1774198889176926299">"Ezin da konektatu Internetera"</string> <string name="saved_network" msgid="7143698034077223645">"<xliff:g id="NAME">%1$s</xliff:g> aplikazioak gorde du"</string> <string name="connected_via_network_scorer" msgid="7665725527352893558">"%1$s bidez automatikoki konektatuta"</string> - <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Automatikoki konektatuta sareen balorazioen hornitzailearen bidez"</string> + <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Automatikoki konektatuta sare-balorazioen hornitzailearen bidez"</string> <string name="connected_via_passpoint" msgid="7735442932429075684">"%1$s bidez konektatuta"</string> <string name="connected_via_app" msgid="3532267661404276584">"<xliff:g id="NAME">%1$s</xliff:g> bidez konektatuta"</string> <string name="available_via_passpoint" msgid="1716000261192603682">"%1$s bidez erabilgarri"</string> diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java index 87df54403f50..2802702aa0b4 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java +++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java @@ -356,17 +356,8 @@ public class PipManager implements BasePipManager, PipTaskOrganizer.PipTransitio @Override public void onPipTransitionStarted(ComponentName activity, int direction) { if (isOutPipDirection(direction)) { - // On phones, the expansion animation that happens on pip tap before restoring - // to fullscreen makes it so that the bounds received here are the expanded - // bounds. We want to restore to the unexpanded bounds when re-entering pip, - // so we save the bounds before expansion (normal) instead of the current - // bounds. - mReentryBounds.set(mTouchHandler.getNormalBounds()); - // Apply the snap fraction of the current bounds to the normal bounds. - final Rect bounds = mPipTaskOrganizer.getLastReportedBounds(); - float snapFraction = mPipBoundsHandler.getSnapFraction(bounds); - mPipBoundsHandler.applySnapFraction(mReentryBounds, snapFraction); - // Save reentry bounds (normal non-expand bounds with current position applied). + // Exiting PIP, save the reentry bounds to restore to when re-entering. + updateReentryBounds(); mPipBoundsHandler.onSaveReentryBounds(activity, mReentryBounds); } // Disable touches while the animation is running @@ -380,6 +371,23 @@ public class PipManager implements BasePipManager, PipTaskOrganizer.PipTransitio } } + /** + * Update the bounds used to save the re-entry size and snap fraction when exiting PIP. + */ + public void updateReentryBounds() { + // On phones, the expansion animation that happens on pip tap before restoring + // to fullscreen makes it so that the last reported bounds are the expanded + // bounds. We want to restore to the unexpanded bounds when re-entering pip, + // so we use the bounds before expansion (normal) instead of the reported + // bounds. + Rect reentryBounds = mTouchHandler.getNormalBounds(); + // Apply the snap fraction of the current bounds to the normal bounds. + final Rect bounds = mPipTaskOrganizer.getLastReportedBounds(); + float snapFraction = mPipBoundsHandler.getSnapFraction(bounds); + mPipBoundsHandler.applySnapFraction(reentryBounds, snapFraction); + mReentryBounds.set(reentryBounds); + } + @Override public void onPipTransitionFinished(ComponentName activity, int direction) { onPipTransitionFinishedOrCanceled(direction); diff --git a/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java b/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java index a4c5a2341d77..bc441d017a7f 100644 --- a/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java +++ b/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java @@ -89,6 +89,7 @@ import java.util.Arrays; import java.util.Collections; import java.util.HashSet; import java.util.List; +import java.util.NoSuchElementException; import java.util.Set; /** @@ -1176,7 +1177,11 @@ abstract class AbstractAccessibilityServiceConnection extends IAccessibilityServ /* ignore */ } if (mService != null) { - mService.unlinkToDeath(this, 0); + try { + mService.unlinkToDeath(this, 0); + } catch (NoSuchElementException e) { + Slog.e(LOG_TAG, "Failed unregistering death link"); + } mService = null; } diff --git a/services/core/java/com/android/server/input/InputShellCommand.java b/services/core/java/com/android/server/input/InputShellCommand.java index 533392a86712..fd5f48c91867 100644 --- a/services/core/java/com/android/server/input/InputShellCommand.java +++ b/services/core/java/com/android/server/input/InputShellCommand.java @@ -199,7 +199,7 @@ public class InputShellCommand extends ShellCommand { + " (Default: touchscreen)"); out.println(" press (Default: trackball)"); out.println(" roll <dx> <dy> (Default: trackball)"); - out.println(" motionevent <DOWN|UP|MOVE> <x> <y> (Default: touchscreen)"); + out.println(" motionevent <DOWN|UP|MOVE|CANCEL> <x> <y> (Default: touchscreen)"); } } @@ -357,32 +357,50 @@ public class InputShellCommand extends ShellCommand { displayId); } + private int getAction() { + String actionString = getNextArgRequired(); + switch (actionString.toUpperCase()) { + case "DOWN": + return MotionEvent.ACTION_DOWN; + case "UP": + return MotionEvent.ACTION_UP; + case "MOVE": + return MotionEvent.ACTION_MOVE; + case "CANCEL": + return MotionEvent.ACTION_CANCEL; + default: + throw new IllegalArgumentException("Unknown action: " + actionString); + } + } + private void runMotionEvent(int inputSource, int displayId) { inputSource = getSource(inputSource, InputDevice.SOURCE_TOUCHSCREEN); - sendMotionEvent(inputSource, getNextArgRequired(), Float.parseFloat(getNextArgRequired()), - Float.parseFloat(getNextArgRequired()), displayId); + int action = getAction(); + float x = 0, y = 0; + if (action == MotionEvent.ACTION_DOWN + || action == MotionEvent.ACTION_MOVE + || action == MotionEvent.ACTION_UP) { + x = Float.parseFloat(getNextArgRequired()); + y = Float.parseFloat(getNextArgRequired()); + } else { + // For ACTION_CANCEL, the positions are optional + String xString = getNextArg(); + String yString = getNextArg(); + if (xString != null && yString != null) { + x = Float.parseFloat(xString); + y = Float.parseFloat(yString); + } + } + + sendMotionEvent(inputSource, action, x, y, displayId); } - private void sendMotionEvent(int inputSource, String motionEventType, float x, float y, + private void sendMotionEvent(int inputSource, int action, float x, float y, int displayId) { - final int action; - final float pressure; + float pressure = NO_PRESSURE; - switch (motionEventType.toUpperCase()) { - case "DOWN": - action = MotionEvent.ACTION_DOWN; - pressure = DEFAULT_PRESSURE; - break; - case "UP": - action = MotionEvent.ACTION_UP; - pressure = NO_PRESSURE; - break; - case "MOVE": - action = MotionEvent.ACTION_MOVE; - pressure = DEFAULT_PRESSURE; - break; - default: - throw new IllegalArgumentException("Unknown motionevent " + motionEventType); + if (action == MotionEvent.ACTION_DOWN || action == MotionEvent.ACTION_MOVE) { + pressure = DEFAULT_PRESSURE; } final long now = SystemClock.uptimeMillis(); diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java index 4c4680b17372..7b0675939a33 100644 --- a/services/core/java/com/android/server/power/PowerManagerService.java +++ b/services/core/java/com/android/server/power/PowerManagerService.java @@ -44,8 +44,8 @@ import android.hardware.SystemSensorManager; import android.hardware.display.AmbientDisplayConfiguration; import android.hardware.display.DisplayManagerInternal; import android.hardware.display.DisplayManagerInternal.DisplayPowerRequest; -import android.hardware.power.Boost; import android.hardware.power.Mode; +import android.hardware.power.V1_0.PowerHint; import android.net.Uri; import android.os.BatteryManager; import android.os.BatteryManagerInternal; @@ -203,6 +203,9 @@ public final class PowerManagerService extends SystemService // How long a partial wake lock must be held until we consider it a long wake lock. static final long MIN_LONG_WAKE_CHECK_INTERVAL = 60*1000; + // Power features defined in hardware/libhardware/include/hardware/power.h. + private static final int POWER_FEATURE_DOUBLE_TAP_TO_WAKE = 1; + // Default setting for double tap to wake. private static final int DEFAULT_DOUBLE_TAP_TO_WAKE = 0; @@ -322,7 +325,7 @@ public final class PowerManagerService extends SystemService private long mLastUserActivityTime; private long mLastUserActivityTimeNoChangeLights; - // Timestamp of last time power boost interaction was sent. + // Timestamp of last interactive power hint. private long mLastInteractivePowerHintTime; // Timestamp of the last screen brightness boost. @@ -716,11 +719,21 @@ public final class PowerManagerService extends SystemService PowerManagerService.nativeReleaseSuspendBlocker(name); } + /** Wrapper for PowerManager.nativeSetInteractive */ + public void nativeSetInteractive(boolean enable) { + PowerManagerService.nativeSetInteractive(enable); + } + /** Wrapper for PowerManager.nativeSetAutoSuspend */ public void nativeSetAutoSuspend(boolean enable) { PowerManagerService.nativeSetAutoSuspend(enable); } + /** Wrapper for PowerManager.nativeSendPowerHint */ + public void nativeSendPowerHint(int hintId, int data) { + PowerManagerService.nativeSendPowerHint(hintId, data); + } + /** Wrapper for PowerManager.nativeSetPowerBoost */ public void nativeSetPowerBoost(int boost, int durationMs) { PowerManagerService.nativeSetPowerBoost(boost, durationMs); @@ -731,6 +744,11 @@ public final class PowerManagerService extends SystemService return PowerManagerService.nativeSetPowerMode(mode, enabled); } + /** Wrapper for PowerManager.nativeSetFeature */ + public void nativeSetFeature(int featureId, int data) { + PowerManagerService.nativeSetFeature(featureId, data); + } + /** Wrapper for PowerManager.nativeForceSuspend */ public boolean nativeForceSuspend() { return PowerManagerService.nativeForceSuspend(); @@ -833,9 +851,12 @@ public final class PowerManagerService extends SystemService private native void nativeInit(); private static native void nativeAcquireSuspendBlocker(String name); private static native void nativeReleaseSuspendBlocker(String name); + private static native void nativeSetInteractive(boolean enable); private static native void nativeSetAutoSuspend(boolean enable); + private static native void nativeSendPowerHint(int hintId, int data); private static native void nativeSetPowerBoost(int boost, int durationMs); private static native boolean nativeSetPowerMode(int mode, boolean enabled); + private static native void nativeSetFeature(int featureId, int data); private static native boolean nativeForceSuspend(); public PowerManagerService(Context context) { @@ -979,8 +1000,8 @@ public final class PowerManagerService extends SystemService mNativeWrapper.nativeInit(this); mNativeWrapper.nativeSetAutoSuspend(false); - mNativeWrapper.nativeSetPowerMode(Mode.INTERACTIVE, true); - mNativeWrapper.nativeSetPowerMode(Mode.DOUBLE_TAP_TO_WAKE, false); + mNativeWrapper.nativeSetInteractive(true); + mNativeWrapper.nativeSetFeature(POWER_FEATURE_DOUBLE_TAP_TO_WAKE, 0); mInjector.invalidateIsInteractiveCaches(); } } @@ -1231,7 +1252,8 @@ public final class PowerManagerService extends SystemService UserHandle.USER_CURRENT) != 0; if (doubleTapWakeEnabled != mDoubleTapWakeEnabled) { mDoubleTapWakeEnabled = doubleTapWakeEnabled; - mNativeWrapper.nativeSetPowerMode(Mode.DOUBLE_TAP_TO_WAKE, mDoubleTapWakeEnabled); + mNativeWrapper.nativeSetFeature( + POWER_FEATURE_DOUBLE_TAP_TO_WAKE, mDoubleTapWakeEnabled ? 1 : 0); } } @@ -1590,7 +1612,7 @@ public final class PowerManagerService extends SystemService Trace.traceBegin(Trace.TRACE_TAG_POWER, "userActivity"); try { if (eventTime > mLastInteractivePowerHintTime) { - setPowerBoostInternal(Boost.INTERACTION, 0); + powerHintInternal(PowerHint.INTERACTION, 0); mLastInteractivePowerHintTime = eventTime; } @@ -3149,7 +3171,7 @@ public final class PowerManagerService extends SystemService mHalInteractiveModeEnabled = enable; Trace.traceBegin(Trace.TRACE_TAG_POWER, "setHalInteractive(" + enable + ")"); try { - mNativeWrapper.nativeSetPowerMode(Mode.INTERACTIVE, enable); + mNativeWrapper.nativeSetInteractive(enable); } finally { Trace.traceEnd(Trace.TRACE_TAG_POWER); } @@ -3623,6 +3645,19 @@ public final class PowerManagerService extends SystemService mIsVrModeEnabled = enabled; } + private void powerHintInternal(int hintId, int data) { + // Maybe filter the event. + switch (hintId) { + case PowerHint.LAUNCH: // 1: activate launch boost 0: deactivate. + if (data == 1 && mBatterySaverController.isLaunchBoostDisabled()) { + return; + } + break; + } + + mNativeWrapper.nativeSendPowerHint(hintId, data); + } + private void setPowerBoostInternal(int boost, int durationMs) { // Maybe filter the event. mNativeWrapper.nativeSetPowerBoost(boost, durationMs); @@ -4369,7 +4404,7 @@ public final class PowerManagerService extends SystemService private final IVrStateCallbacks mVrStateCallbacks = new IVrStateCallbacks.Stub() { @Override public void onVrStateChanged(boolean enabled) { - setPowerModeInternal(Mode.VR, enabled); + powerHintInternal(PowerHint.VR_MODE, enabled ? 1 : 0); synchronized (mLock) { if (mIsVrModeEnabled != enabled) { @@ -4680,6 +4715,16 @@ public final class PowerManagerService extends SystemService } @Override // Binder call + public void powerHint(int hintId, int data) { + if (!mSystemReady) { + // Service not ready yet, so who the heck cares about power hints, bah. + return; + } + mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null); + powerHintInternal(hintId, data); + } + + @Override // Binder call public void setPowerBoost(int boost, int durationMs) { if (!mSystemReady) { // Service not ready yet, so who the heck cares about power hints, bah. @@ -5514,6 +5559,11 @@ public final class PowerManagerService extends SystemService } @Override + public void powerHint(int hintId, int data) { + powerHintInternal(hintId, data); + } + + @Override public void setPowerBoost(int boost, int durationMs) { setPowerBoostInternal(boost, durationMs); } diff --git a/services/core/java/com/android/server/power/batterysaver/BatterySaverController.java b/services/core/java/com/android/server/power/batterysaver/BatterySaverController.java index 6ff069bd049d..2a4a69ddde4f 100644 --- a/services/core/java/com/android/server/power/batterysaver/BatterySaverController.java +++ b/services/core/java/com/android/server/power/batterysaver/BatterySaverController.java @@ -23,7 +23,7 @@ import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.pm.PackageManagerInternal; -import android.hardware.power.Mode; +import android.hardware.power.V1_0.PowerHint; import android.os.BatteryManager; import android.os.BatterySaverPolicyConfig; import android.os.Handler; @@ -474,7 +474,7 @@ public class BatterySaverController implements BatterySaverPolicyListener { final PowerManagerInternal pmi = LocalServices.getService(PowerManagerInternal.class); if (pmi != null) { - pmi.setPowerMode(Mode.LOW_POWER, isEnabled()); + pmi.powerHint(PowerHint.LOW_POWER, isEnabled() ? 1 : 0); } updateBatterySavingStats(); diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java index d2f5d2d58006..b4ead8eccf02 100644 --- a/services/core/java/com/android/server/wm/DisplayPolicy.java +++ b/services/core/java/com/android/server/wm/DisplayPolicy.java @@ -139,7 +139,7 @@ import android.graphics.PixelFormat; import android.graphics.Rect; import android.graphics.Region; import android.hardware.input.InputManager; -import android.hardware.power.Boost; +import android.hardware.power.V1_0.PowerHint; import android.os.Handler; import android.os.Looper; import android.os.Message; @@ -544,8 +544,8 @@ public class DisplayPolicy { @Override public void onFling(int duration) { if (mService.mPowerManagerInternal != null) { - mService.mPowerManagerInternal.setPowerBoost( - Boost.INTERACTION, duration); + mService.mPowerManagerInternal.powerHint( + PowerHint.INTERACTION, duration); } } diff --git a/services/core/java/com/android/server/wm/DisplayRotation.java b/services/core/java/com/android/server/wm/DisplayRotation.java index c63128c15e8d..0747e243e276 100644 --- a/services/core/java/com/android/server/wm/DisplayRotation.java +++ b/services/core/java/com/android/server/wm/DisplayRotation.java @@ -42,7 +42,7 @@ import android.content.pm.ActivityInfo.ScreenOrientation; import android.content.pm.PackageManager; import android.content.res.Resources; import android.database.ContentObserver; -import android.hardware.power.Boost; +import android.hardware.power.V1_0.PowerHint; import android.net.Uri; import android.os.Handler; import android.os.RemoteException; @@ -1473,7 +1473,7 @@ public class DisplayRotation { @Override public void run() { // Send interaction power boost to improve redraw performance. - mService.mPowerManagerInternal.setPowerBoost(Boost.INTERACTION, 0); + mService.mPowerManagerInternal.powerHint(PowerHint.INTERACTION, 0); if (isRotationChoicePossible(mCurrentAppOrientation)) { final boolean isValid = isValidRotationChoice(mRotation); sendProposedRotationChangeToStatusBarInternal(mRotation, isValid); diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java index 40f8fab510ba..ab2151974ce9 100644 --- a/services/core/java/com/android/server/wm/RootWindowContainer.java +++ b/services/core/java/com/android/server/wm/RootWindowContainer.java @@ -111,7 +111,7 @@ import android.content.res.Resources; import android.graphics.Rect; import android.hardware.display.DisplayManager; import android.hardware.display.DisplayManagerInternal; -import android.hardware.power.Mode; +import android.hardware.power.V1_0.PowerHint; import android.net.Uri; import android.os.Binder; import android.os.Debug; @@ -950,9 +950,9 @@ class RootWindowContainer extends WindowContainer<DisplayContent> if (mSustainedPerformanceModeCurrent != mSustainedPerformanceModeEnabled) { mSustainedPerformanceModeEnabled = mSustainedPerformanceModeCurrent; - mWmService.mPowerManagerInternal.setPowerMode( - Mode.SUSTAINED_PERFORMANCE, - mSustainedPerformanceModeEnabled); + mWmService.mPowerManagerInternal.powerHint( + PowerHint.SUSTAINED_PERFORMANCE, + mSustainedPerformanceModeEnabled ? 1 : 0); } if (mUpdateRotation) { @@ -3478,7 +3478,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent> } if (sendPowerModeLaunch && mService.mPowerManagerInternal != null) { - mService.mPowerManagerInternal.setPowerMode(Mode.LAUNCH, true); + mService.mPowerManagerInternal.powerHint(PowerHint.LAUNCH, 1); mPowerModeLaunchStarted = true; } } @@ -3486,7 +3486,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent> void endPowerModeLaunchIfNeeded() { // Trigger launch power mode off if activity is launched if (mPowerModeLaunchStarted && mService.mPowerManagerInternal != null) { - mService.mPowerManagerInternal.setPowerMode(Mode.LAUNCH, false); + mService.mPowerManagerInternal.powerHint(PowerHint.LAUNCH, 0); mPowerModeLaunchStarted = false; } } diff --git a/services/core/java/com/android/server/wm/SurfaceAnimationRunner.java b/services/core/java/com/android/server/wm/SurfaceAnimationRunner.java index 34d084a3f9f8..837f1b523b68 100644 --- a/services/core/java/com/android/server/wm/SurfaceAnimationRunner.java +++ b/services/core/java/com/android/server/wm/SurfaceAnimationRunner.java @@ -26,7 +26,7 @@ import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.ValueAnimator; import android.annotation.Nullable; -import android.hardware.power.Boost; +import android.hardware.power.V1_0.PowerHint; import android.os.Handler; import android.os.PowerManagerInternal; import android.util.ArrayMap; @@ -246,7 +246,7 @@ class SurfaceAnimationRunner { synchronized (mLock) { startPendingAnimationsLocked(); } - mPowerManagerInternal.setPowerBoost(Boost.INTERACTION, 0); + mPowerManagerInternal.powerHint(PowerHint.INTERACTION, 0); } private void scheduleApplyTransaction() { diff --git a/services/core/jni/com_android_server_power_PowerManagerService.cpp b/services/core/jni/com_android_server_power_PowerManagerService.cpp index d11c4bcb9872..6140531538a6 100644 --- a/services/core/jni/com_android_server_power_PowerManagerService.cpp +++ b/services/core/jni/com_android_server_power_PowerManagerService.cpp @@ -29,6 +29,7 @@ #include <nativehelper/ScopedUtfChars.h> #include <powermanager/PowerHalController.h> +#include <powermanager/PowerHalLoader.h> #include <limits.h> @@ -47,13 +48,17 @@ #include "com_android_server_power_PowerManagerService.h" +using android::String8; +using android::hardware::Return; +using android::hardware::Void; using android::hardware::power::Boost; using android::hardware::power::Mode; -using android::String8; +using android::hardware::power::V1_0::Feature; +using android::hardware::power::V1_0::PowerHint; +using android::system::suspend::ISuspendControlService; using android::system::suspend::V1_0::ISystemSuspend; using android::system::suspend::V1_0::IWakeLock; using android::system::suspend::V1_0::WakeLockType; -using android::system::suspend::ISuspendControlService; using IPowerV1_1 = android::hardware::power::V1_1::IPower; using IPowerV1_0 = android::hardware::power::V1_0::IPower; using IPowerAidl = android::hardware::power::IPower; @@ -69,7 +74,18 @@ static struct { // ---------------------------------------------------------------------------- static jobject gPowerManagerServiceObj; -static power::PowerHalController gPowerHalController; +static sp<IPowerV1_0> gPowerHalHidlV1_0_ = nullptr; +static sp<IPowerV1_1> gPowerHalHidlV1_1_ = nullptr; +static sp<IPowerAidl> gPowerHalAidl_ = nullptr; +static std::mutex gPowerHalMutex; + +enum class HalVersion { + NONE, + HIDL_1_0, + HIDL_1_1, + AIDL, +}; + static nsecs_t gLastEventTime[USER_ACTIVITY_EVENT_LAST + 1]; // Throttling interval for user activity calls. @@ -87,19 +103,208 @@ static bool checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodNa return false; } +// Check validity of current handle to the power HAL service, and connect to it if necessary. +// The caller must be holding gPowerHalMutex. +static HalVersion connectPowerHalLocked() { + static bool gPowerHalHidlExists = true; + static bool gPowerHalAidlExists = true; + if (!gPowerHalHidlExists && !gPowerHalAidlExists) { + return HalVersion::NONE; + } + if (gPowerHalAidlExists) { + if (!gPowerHalAidl_) { + gPowerHalAidl_ = waitForVintfService<IPowerAidl>(); + } + if (gPowerHalAidl_) { + ALOGV("Successfully connected to Power HAL AIDL service."); + return HalVersion::AIDL; + } else { + gPowerHalAidlExists = false; + } + } + if (gPowerHalHidlExists && gPowerHalHidlV1_0_ == nullptr) { + gPowerHalHidlV1_0_ = IPowerV1_0::getService(); + if (gPowerHalHidlV1_0_) { + ALOGV("Successfully connected to Power HAL HIDL 1.0 service."); + // Try cast to powerHAL HIDL V1_1 + gPowerHalHidlV1_1_ = IPowerV1_1::castFrom(gPowerHalHidlV1_0_); + if (gPowerHalHidlV1_1_) { + ALOGV("Successfully connected to Power HAL HIDL 1.1 service."); + } + } else { + ALOGV("Couldn't load power HAL HIDL service"); + gPowerHalHidlExists = false; + return HalVersion::NONE; + } + } + if (gPowerHalHidlV1_1_) { + return HalVersion::HIDL_1_1; + } else if (gPowerHalHidlV1_0_) { + return HalVersion::HIDL_1_0; + } + return HalVersion::NONE; +} + +// Check if a call to a power HAL function failed; if so, log the failure and invalidate the +// current handle to the power HAL service. +bool processPowerHalReturn(bool isOk, const char* functionName) { + if (!isOk) { + ALOGE("%s() failed: power HAL service not available.", functionName); + gPowerHalMutex.lock(); + gPowerHalHidlV1_0_ = nullptr; + gPowerHalHidlV1_1_ = nullptr; + gPowerHalAidl_ = nullptr; + gPowerHalMutex.unlock(); + } + return isOk; +} + +enum class HalSupport { + UNKNOWN = 0, + ON, + OFF, +}; + +static void setPowerBoostWithHandle(sp<IPowerAidl> handle, Boost boost, int32_t durationMs) { + // Android framework only sends boost upto DISPLAY_UPDATE_IMMINENT. + // Need to increase the array size if more boost supported. + static std::array<std::atomic<HalSupport>, + static_cast<int32_t>(Boost::DISPLAY_UPDATE_IMMINENT) + 1> + boostSupportedArray = {HalSupport::UNKNOWN}; + + // Quick return if boost is not supported by HAL + if (boost > Boost::DISPLAY_UPDATE_IMMINENT || + boostSupportedArray[static_cast<int32_t>(boost)] == HalSupport::OFF) { + ALOGV("Skipped setPowerBoost %s because HAL doesn't support it", toString(boost).c_str()); + return; + } + + if (boostSupportedArray[static_cast<int32_t>(boost)] == HalSupport::UNKNOWN) { + bool isSupported = false; + handle->isBoostSupported(boost, &isSupported); + boostSupportedArray[static_cast<int32_t>(boost)] = + isSupported ? HalSupport::ON : HalSupport::OFF; + if (!isSupported) { + ALOGV("Skipped setPowerBoost %s because HAL doesn't support it", + toString(boost).c_str()); + return; + } + } + + auto ret = handle->setBoost(boost, durationMs); + processPowerHalReturn(ret.isOk(), "setPowerBoost"); +} + static void setPowerBoost(Boost boost, int32_t durationMs) { - gPowerHalController.setBoost(boost, durationMs); - SurfaceComposerClient::notifyPowerBoost(static_cast<int32_t>(boost)); + std::unique_lock<std::mutex> lock(gPowerHalMutex); + if (connectPowerHalLocked() != HalVersion::AIDL) { + ALOGV("Power HAL AIDL not available"); + return; + } + sp<IPowerAidl> handle = gPowerHalAidl_; + lock.unlock(); + setPowerBoostWithHandle(handle, boost, durationMs); +} + +static bool setPowerModeWithHandle(sp<IPowerAidl> handle, Mode mode, bool enabled) { + // Android framework only sends mode upto DISPLAY_INACTIVE. + // Need to increase the array if more mode supported. + static std::array<std::atomic<HalSupport>, static_cast<int32_t>(Mode::DISPLAY_INACTIVE) + 1> + modeSupportedArray = {HalSupport::UNKNOWN}; + + // Quick return if mode is not supported by HAL + if (mode > Mode::DISPLAY_INACTIVE || + modeSupportedArray[static_cast<int32_t>(mode)] == HalSupport::OFF) { + ALOGV("Skipped setPowerMode %s because HAL doesn't support it", toString(mode).c_str()); + return false; + } + + if (modeSupportedArray[static_cast<int32_t>(mode)] == HalSupport::UNKNOWN) { + bool isSupported = false; + handle->isModeSupported(mode, &isSupported); + modeSupportedArray[static_cast<int32_t>(mode)] = + isSupported ? HalSupport::ON : HalSupport::OFF; + if (!isSupported) { + ALOGV("Skipped setPowerMode %s because HAL doesn't support it", toString(mode).c_str()); + return false; + } + } + + auto ret = handle->setMode(mode, enabled); + processPowerHalReturn(ret.isOk(), "setPowerMode"); + return ret.isOk(); } static bool setPowerMode(Mode mode, bool enabled) { - android::base::Timer t; - auto result = gPowerHalController.setMode(mode, enabled); - if (mode == Mode::INTERACTIVE && t.duration() > 20ms) { - ALOGD("Excessive delay in setting interactive mode to %s while turning screen %s", - enabled ? "true" : "false", enabled ? "on" : "off"); + std::unique_lock<std::mutex> lock(gPowerHalMutex); + if (connectPowerHalLocked() != HalVersion::AIDL) { + ALOGV("Power HAL AIDL not available"); + return false; + } + sp<IPowerAidl> handle = gPowerHalAidl_; + lock.unlock(); + return setPowerModeWithHandle(handle, mode, enabled); +} + +static void sendPowerHint(PowerHint hintId, uint32_t data) { + std::unique_lock<std::mutex> lock(gPowerHalMutex); + switch (connectPowerHalLocked()) { + case HalVersion::NONE: + return; + case HalVersion::HIDL_1_0: { + sp<IPowerV1_0> handle = gPowerHalHidlV1_0_; + lock.unlock(); + auto ret = handle->powerHint(hintId, data); + processPowerHalReturn(ret.isOk(), "powerHint"); + break; + } + case HalVersion::HIDL_1_1: { + sp<IPowerV1_1> handle = gPowerHalHidlV1_1_; + lock.unlock(); + auto ret = handle->powerHintAsync(hintId, data); + processPowerHalReturn(ret.isOk(), "powerHintAsync"); + break; + } + case HalVersion::AIDL: { + if (hintId == PowerHint::INTERACTION) { + sp<IPowerAidl> handle = gPowerHalAidl_; + lock.unlock(); + setPowerBoostWithHandle(handle, Boost::INTERACTION, data); + break; + } else if (hintId == PowerHint::LAUNCH) { + sp<IPowerAidl> handle = gPowerHalAidl_; + lock.unlock(); + setPowerModeWithHandle(handle, Mode::LAUNCH, static_cast<bool>(data)); + break; + } else if (hintId == PowerHint::LOW_POWER) { + sp<IPowerAidl> handle = gPowerHalAidl_; + lock.unlock(); + setPowerModeWithHandle(handle, Mode::LOW_POWER, static_cast<bool>(data)); + break; + } else if (hintId == PowerHint::SUSTAINED_PERFORMANCE) { + sp<IPowerAidl> handle = gPowerHalAidl_; + lock.unlock(); + setPowerModeWithHandle(handle, Mode::SUSTAINED_PERFORMANCE, + static_cast<bool>(data)); + break; + } else if (hintId == PowerHint::VR_MODE) { + sp<IPowerAidl> handle = gPowerHalAidl_; + lock.unlock(); + setPowerModeWithHandle(handle, Mode::VR, static_cast<bool>(data)); + break; + } else { + ALOGE("Unsupported power hint: %s.", toString(hintId).c_str()); + return; + } + } + default: { + ALOGE("Unknown power HAL state"); + return; + } + } + if (hintId == PowerHint::INTERACTION) { + SurfaceComposerClient::notifyPowerBoost(static_cast<int32_t>(Boost::INTERACTION)); } - return result == power::HalResult::SUCCESSFUL; } void android_server_PowerManagerService_userActivity(nsecs_t eventTime, int32_t eventType) { @@ -119,7 +324,7 @@ void android_server_PowerManagerService_userActivity(nsecs_t eventTime, int32_t gLastEventTime[eventType] = eventTime; // Tell the power HAL when user activity occurs. - setPowerBoost(Boost::INTERACTION, 0); + sendPowerHint(PowerHint::INTERACTION, 0); } JNIEnv* env = AndroidRuntime::getJNIEnv(); @@ -186,7 +391,10 @@ void disableAutoSuspend() { static void nativeInit(JNIEnv* env, jobject obj) { gPowerManagerServiceObj = env->NewGlobalRef(obj); - gPowerHalController.init(); + + gPowerHalMutex.lock(); + connectPowerHalLocked(); + gPowerHalMutex.unlock(); } static void nativeAcquireSuspendBlocker(JNIEnv *env, jclass /* clazz */, jstring nameStr) { @@ -199,6 +407,38 @@ static void nativeReleaseSuspendBlocker(JNIEnv *env, jclass /* clazz */, jstring release_wake_lock(name.c_str()); } +static void nativeSetInteractive(JNIEnv* /* env */, jclass /* clazz */, jboolean enable) { + std::unique_lock<std::mutex> lock(gPowerHalMutex); + switch (connectPowerHalLocked()) { + case HalVersion::NONE: + return; + case HalVersion::HIDL_1_0: + FALLTHROUGH_INTENDED; + case HalVersion::HIDL_1_1: { + android::base::Timer t; + sp<IPowerV1_0> handle = gPowerHalHidlV1_0_; + lock.unlock(); + auto ret = handle->setInteractive(enable); + processPowerHalReturn(ret.isOk(), "setInteractive"); + if (t.duration() > 20ms) { + ALOGD("Excessive delay in setInteractive(%s) while turning screen %s", + enable ? "true" : "false", enable ? "on" : "off"); + } + return; + } + case HalVersion::AIDL: { + sp<IPowerAidl> handle = gPowerHalAidl_; + lock.unlock(); + setPowerModeWithHandle(handle, Mode::INTERACTIVE, enable); + return; + } + default: { + ALOGE("Unknown power HAL state"); + return; + } + } +} + static void nativeSetAutoSuspend(JNIEnv* /* env */, jclass /* clazz */, jboolean enable) { if (enable) { android::base::Timer t; @@ -215,6 +455,10 @@ static void nativeSetAutoSuspend(JNIEnv* /* env */, jclass /* clazz */, jboolean } } +static void nativeSendPowerHint(JNIEnv* /* env */, jclass /* clazz */, jint hintId, jint data) { + sendPowerHint(static_cast<PowerHint>(hintId), data); +} + static void nativeSetPowerBoost(JNIEnv* /* env */, jclass /* clazz */, jint boost, jint durationMs) { setPowerBoost(static_cast<Boost>(boost), durationMs); @@ -225,6 +469,33 @@ static jboolean nativeSetPowerMode(JNIEnv* /* env */, jclass /* clazz */, jint m return setPowerMode(static_cast<Mode>(mode), enabled); } +static void nativeSetFeature(JNIEnv* /* env */, jclass /* clazz */, jint featureId, jint data) { + std::unique_lock<std::mutex> lock(gPowerHalMutex); + switch (connectPowerHalLocked()) { + case HalVersion::NONE: + return; + case HalVersion::HIDL_1_0: + FALLTHROUGH_INTENDED; + case HalVersion::HIDL_1_1: { + sp<IPowerV1_0> handle = gPowerHalHidlV1_0_; + lock.unlock(); + auto ret = handle->setFeature(static_cast<Feature>(featureId), static_cast<bool>(data)); + processPowerHalReturn(ret.isOk(), "setFeature"); + return; + } + case HalVersion::AIDL: { + sp<IPowerAidl> handle = gPowerHalAidl_; + lock.unlock(); + setPowerModeWithHandle(handle, Mode::DOUBLE_TAP_TO_WAKE, static_cast<bool>(data)); + return; + } + default: { + ALOGE("Unknown power HAL state"); + return; + } + } +} + static bool nativeForceSuspend(JNIEnv* /* env */, jclass /* clazz */) { bool retval = false; getSuspendControl()->forceSuspend(&retval); @@ -241,9 +512,12 @@ static const JNINativeMethod gPowerManagerServiceMethods[] = { {"nativeForceSuspend", "()Z", (void*)nativeForceSuspend}, {"nativeReleaseSuspendBlocker", "(Ljava/lang/String;)V", (void*)nativeReleaseSuspendBlocker}, + {"nativeSetInteractive", "(Z)V", (void*)nativeSetInteractive}, {"nativeSetAutoSuspend", "(Z)V", (void*)nativeSetAutoSuspend}, + {"nativeSendPowerHint", "(II)V", (void*)nativeSendPowerHint}, {"nativeSetPowerBoost", "(II)V", (void*)nativeSetPowerBoost}, {"nativeSetPowerMode", "(IZ)Z", (void*)nativeSetPowerMode}, + {"nativeSetFeature", "(II)V", (void*)nativeSetFeature}, }; #define FIND_CLASS(var, className) \ diff --git a/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java index 419fb14df340..96690100fc03 100644 --- a/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java @@ -369,11 +369,9 @@ public class PowerManagerServiceTest { } @Test - public void testCreateService_initializesNativeServiceAndSetsPowerModes() { + public void testCreateService_initializesNativeService() { PowerManagerService service = createService(); verify(mNativeWrapperMock).nativeInit(same(service)); - verify(mNativeWrapperMock).nativeSetPowerMode(eq(Mode.INTERACTIVE), eq(true)); - verify(mNativeWrapperMock).nativeSetPowerMode(eq(Mode.DOUBLE_TAP_TO_WAKE), eq(false)); } @Test diff --git a/services/tests/wmtests/src/com/android/server/wm/SurfaceAnimationRunnerTest.java b/services/tests/wmtests/src/com/android/server/wm/SurfaceAnimationRunnerTest.java index be9bf24a0325..7ffb2eb26721 100644 --- a/services/tests/wmtests/src/com/android/server/wm/SurfaceAnimationRunnerTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/SurfaceAnimationRunnerTest.java @@ -26,6 +26,7 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.when; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; +import static org.mockito.ArgumentMatchers.anyInt; import static java.util.concurrent.TimeUnit.SECONDS; @@ -33,7 +34,6 @@ import android.animation.AnimationHandler.AnimationFrameCallbackProvider; import android.animation.ValueAnimator; import android.graphics.Matrix; import android.graphics.Point; -import android.hardware.power.Boost; import android.os.PowerManagerInternal; import android.platform.test.annotations.Presubmit; import android.view.Choreographer; @@ -194,7 +194,7 @@ public class SurfaceAnimationRunnerTest extends WindowTestsBase { mMockTransaction, this::finishedCallback); waitUntilNextFrame(); - verify(mMockPowerManager).setPowerBoost(eq(Boost.INTERACTION), eq(0)); + verify(mMockPowerManager).powerHint(anyInt(), eq(0)); } private void waitUntilNextFrame() throws Exception { diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java index 157e885c8856..4fc9e4a3ac11 100755 --- a/telephony/java/android/telephony/CarrierConfigManager.java +++ b/telephony/java/android/telephony/CarrierConfigManager.java @@ -3216,6 +3216,17 @@ public class CarrierConfigManager { "5g_icon_display_secondary_grace_period_string"; /** + * Whether device reset all of NR timers when device camped on a network that haven't 5G + * capability and RRC currently in IDLE state. + * + * The default value is false; + * + * @hide + */ + public static final String KEY_NR_TIMERS_RESET_IF_NON_ENDC_AND_RRC_IDLE_BOOL = + "nr_timers_reset_if_non_endc_and_rrc_idle_bool"; + + /** * Controls time in milliseconds until DcTracker reevaluates 5G connection state. * @hide */ @@ -4326,6 +4337,7 @@ public class CarrierConfigManager { + "not_restricted_rrc_con:5G"); sDefaults.putString(KEY_5G_ICON_DISPLAY_GRACE_PERIOD_STRING, ""); sDefaults.putString(KEY_5G_ICON_DISPLAY_SECONDARY_GRACE_PERIOD_STRING, ""); + sDefaults.putBoolean(KEY_NR_TIMERS_RESET_IF_NON_ENDC_AND_RRC_IDLE_BOOL, false); /* Default value is 1 hour. */ sDefaults.putLong(KEY_5G_WATCHDOG_TIME_MS_LONG, 3600000); sDefaults.putBoolean(KEY_UNMETERED_NR_NSA_BOOL, false); |