Switch display control betw. Android and Sidekick
Test: builds; Sidekick animates watch faces
Change-Id: I6ef1e91ed33b1790eed9a7b9af9bc6b6441c7de9
(cherry picked from commit 40f6f257f537b270be06a09a959202260cb53267)
diff --git a/core/java/android/hardware/sidekick/SidekickInternal.java b/core/java/android/hardware/sidekick/SidekickInternal.java
new file mode 100644
index 0000000..fe3550b
--- /dev/null
+++ b/core/java/android/hardware/sidekick/SidekickInternal.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2017 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.hardware.sidekick;
+
+
+/**
+ * Sidekick local system service interface.
+ *
+ * @hide Only for use within the system server, and maybe by Clockwork Home.
+ */
+public abstract class SidekickInternal {
+
+ /**
+ * Tell Sidekick to reset back to newly-powered-on state.
+ *
+ * @return true on success (Sidekick is reset), false if Sidekick is not
+ * available (failed or not present). Either way, upon return Sidekick is
+ * guaranteed not to be controlling the display.
+ */
+ public abstract boolean reset();
+
+ /**
+ * Tell Sidekick it can start controlling the display.
+ *
+ * SidekickServer may choose not to actually control the display, if it's been told
+ * via other channels to leave the previous image on the display (same as SUSPEND in
+ * a non-Sidekick system).
+ *
+ * @param displayState - one of Display.STATE_DOZE_SUSPEND, Display.STATE_ON_SUSPEND
+ * @return true on success, false on failure (no sidekick available)
+ */
+ public abstract boolean startDisplayControl(int displayState);
+
+ /**
+ * Tell Sidekick it must stop controlling the display.
+ *
+ * No return code because this must always succeed - after return, Sidekick
+ * is guaranteed to not be controlling the display.
+ */
+ public abstract void endDisplayControl();
+
+}
diff --git a/services/core/java/com/android/server/display/LocalDisplayAdapter.java b/services/core/java/com/android/server/display/LocalDisplayAdapter.java
index d61a418..9fdc35f 100644
--- a/services/core/java/com/android/server/display/LocalDisplayAdapter.java
+++ b/services/core/java/com/android/server/display/LocalDisplayAdapter.java
@@ -22,6 +22,7 @@
import com.android.server.lights.LightsManager;
import android.content.Context;
+import android.hardware.sidekick.SidekickInternal;
import android.os.Build;
import android.os.Handler;
import android.os.IBinder;
@@ -35,7 +36,6 @@
import android.view.DisplayEventReceiver;
import android.view.Surface;
import android.view.SurfaceControl;
-
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
@@ -170,6 +170,8 @@
private int mActiveColorMode;
private boolean mActiveColorModeInvalid;
private Display.HdrCapabilities mHdrCapabilities;
+ private boolean mSidekickActive;
+ private SidekickInternal mSidekickInternal;
private SurfaceControl.PhysicalDisplayInfo mDisplayInfos[];
@@ -181,6 +183,7 @@
updatePhysicalDisplayInfoLocked(physicalDisplayInfos, activeDisplayInfo,
colorModes, activeColorMode);
updateColorModesLocked(colorModes, activeColorMode);
+ mSidekickInternal = LocalServices.getService(SidekickInternal.class);
if (mBuiltInDisplayId == SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN) {
LightsManager lights = LocalServices.getService(LightsManager.class);
mBacklight = lights.getLight(LightsManager.LIGHT_ID_BACKLIGHT);
@@ -510,16 +513,40 @@
+ ", state=" + Display.stateToString(state) + ")");
}
+ // We must tell sidekick to stop controlling the display before we
+ // can change its power mode, so do that first.
+ if (mSidekickActive) {
+ Trace.traceBegin(Trace.TRACE_TAG_POWER,
+ "SidekickInternal#endDisplayControl");
+ try {
+ mSidekickInternal.endDisplayControl();
+ } finally {
+ Trace.traceEnd(Trace.TRACE_TAG_POWER);
+ }
+ mSidekickActive = false;
+ }
+ final int mode = getPowerModeForState(state);
Trace.traceBegin(Trace.TRACE_TAG_POWER, "setDisplayState("
+ "id=" + displayId
+ ", state=" + Display.stateToString(state) + ")");
try {
- final int mode = getPowerModeForState(state);
SurfaceControl.setDisplayPowerMode(token, mode);
Trace.traceCounter(Trace.TRACE_TAG_POWER, "DisplayPowerMode", mode);
} finally {
Trace.traceEnd(Trace.TRACE_TAG_POWER);
}
+ // If we're entering a suspended (but not OFF) power state and we
+ // have a sidekick available, tell it now that it can take control.
+ if (Display.isSuspendedState(state) && state != Display.STATE_OFF
+ && mSidekickInternal != null && !mSidekickActive) {
+ Trace.traceBegin(Trace.TRACE_TAG_POWER,
+ "SidekickInternal#startDisplayControl");
+ try {
+ mSidekickActive = mSidekickInternal.startDisplayControl(state);
+ } finally {
+ Trace.traceEnd(Trace.TRACE_TAG_POWER);
+ }
+ }
}
private void setDisplayBrightness(int brightness) {
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index de5d879..4f29aca 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -193,6 +193,8 @@
"com.google.android.clockwork.ThermalObserver";
private static final String WEAR_CONNECTIVITY_SERVICE_CLASS =
"com.google.android.clockwork.connectivity.WearConnectivityService";
+ private static final String WEAR_SIDEKICK_SERVICE_CLASS =
+ "com.google.android.clockwork.sidekick.SidekickService";
private static final String WEAR_DISPLAY_SERVICE_CLASS =
"com.google.android.clockwork.display.WearDisplayService";
private static final String WEAR_LEFTY_SERVICE_CLASS =
@@ -561,6 +563,13 @@
mSystemServiceManager.startService(LightsService.class);
traceEnd();
+ traceBeginAndSlog("StartSidekickService");
+ // Package manager isn't started yet; need to use SysProp not hardware feature
+ if (SystemProperties.getBoolean("config.enable_sidekick_graphics", false)) {
+ mSystemServiceManager.startService(WEAR_SIDEKICK_SERVICE_CLASS);
+ }
+ traceEnd();
+
// Display manager is needed to provide display metrics before package manager
// starts up.
traceBeginAndSlog("StartDisplayManager");