am e2c9cd58: Merge "Refactor display manager service to new pattern." into klp-modular-dev
* commit 'e2c9cd583f4f706b48270b8cbe84df627c69af24':
Refactor display manager service to new pattern.
diff --git a/core/java/android/hardware/display/DisplayManagerInternal.java b/core/java/android/hardware/display/DisplayManagerInternal.java
new file mode 100644
index 0000000..8430973
--- /dev/null
+++ b/core/java/android/hardware/display/DisplayManagerInternal.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2014 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.display;
+
+import android.view.DisplayInfo;
+
+/**
+ * Display manager local system service interface.
+ *
+ * @hide Only for use within the system server.
+ */
+public abstract class DisplayManagerInternal {
+ /**
+ * Called by the power manager to blank all displays.
+ */
+ public abstract void blankAllDisplaysFromPowerManager();
+
+ /**
+ * Called by the power manager to unblank all displays.
+ */
+ public abstract void unblankAllDisplaysFromPowerManager();
+
+ /**
+ * Returns information about the specified logical display.
+ *
+ * @param displayId The logical display id.
+ * @return The logical display info, or null if the display does not exist. The
+ * returned object must be treated as immutable.
+ */
+ public abstract DisplayInfo getDisplayInfo(int displayId);
+
+ /**
+ * Registers a display transaction listener to provide the client a chance to
+ * update its surfaces within the same transaction as any display layout updates.
+ *
+ * @param listener The listener to register.
+ */
+ public abstract void registerDisplayTransactionListener(DisplayTransactionListener listener);
+
+ /**
+ * Unregisters a display transaction listener to provide the client a chance to
+ * update its surfaces within the same transaction as any display layout updates.
+ *
+ * @param listener The listener to unregister.
+ */
+ public abstract void unregisterDisplayTransactionListener(DisplayTransactionListener listener);
+
+ /**
+ * Overrides the display information of a particular logical display.
+ * This is used by the window manager to control the size and characteristics
+ * of the default display. It is expected to apply the requested change
+ * to the display information synchronously so that applications will immediately
+ * observe the new state.
+ *
+ * NOTE: This method must be the only entry point by which the window manager
+ * influences the logical configuration of displays.
+ *
+ * @param displayId The logical display id.
+ * @param info The new data to be stored.
+ */
+ public abstract void setDisplayInfoOverrideFromWindowManager(
+ int displayId, DisplayInfo info);
+
+ /**
+ * Called by the window manager to perform traversals while holding a
+ * surface flinger transaction.
+ */
+ public abstract void performTraversalInTransactionFromWindowManager();
+
+ /**
+ * Tells the display manager whether there is interesting unique content on the
+ * specified logical display. This is used to control automatic mirroring.
+ * <p>
+ * If the display has unique content, then the display manager arranges for it
+ * to be presented on a physical display if appropriate. Otherwise, the display manager
+ * may choose to make the physical display mirror some other logical display.
+ * </p>
+ *
+ * @param displayId The logical display id to update.
+ * @param hasContent True if the logical display has content.
+ * @param inTraversal True if called from WindowManagerService during a window traversal
+ * prior to call to performTraversalInTransactionFromWindowManager.
+ */
+ public abstract void setDisplayHasContent(int displayId, boolean hasContent,
+ boolean inTraversal);
+
+ /**
+ * Called within a Surface transaction whenever the size or orientation of a
+ * display may have changed. Provides an opportunity for the client to
+ * update the position of its surfaces as part of the same transaction.
+ */
+ public interface DisplayTransactionListener {
+ void onDisplayTransaction();
+ }
+}
diff --git a/services/core/java/com/android/server/display/DisplayViewport.java b/core/java/android/hardware/display/DisplayViewport.java
similarity index 96%
rename from services/core/java/com/android/server/display/DisplayViewport.java
rename to core/java/android/hardware/display/DisplayViewport.java
index 5080556..c2d498b 100644
--- a/services/core/java/com/android/server/display/DisplayViewport.java
+++ b/core/java/android/hardware/display/DisplayViewport.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.server.display;
+package android.hardware.display;
import android.graphics.Rect;
@@ -25,6 +25,8 @@
* This information is used by the input system to translate touch input from
* physical display coordinates into logical display coordinates.
* </p>
+ *
+ * @hide Only for use within the system server.
*/
public final class DisplayViewport {
// True if this viewport is valid.
diff --git a/core/java/android/hardware/input/InputManagerInternal.java b/core/java/android/hardware/input/InputManagerInternal.java
new file mode 100644
index 0000000..ecd32ea
--- /dev/null
+++ b/core/java/android/hardware/input/InputManagerInternal.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2014 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.input;
+
+import android.hardware.display.DisplayViewport;
+
+/**
+ * Input manager local system service interface.
+ *
+ * @hide Only for use within the system server.
+ */
+public abstract class InputManagerInternal {
+ /**
+ * Sets information about the displays as needed by the input system.
+ * The input system should copy this information if required.
+ */
+ public abstract void setDisplayViewports(DisplayViewport defaultViewport,
+ DisplayViewport externalTouchViewport);
+}
diff --git a/core/java/android/os/PowerManagerInternal.java b/core/java/android/os/PowerManagerInternal.java
index 8144576..cb3d528 100644
--- a/core/java/android/os/PowerManagerInternal.java
+++ b/core/java/android/os/PowerManagerInternal.java
@@ -23,7 +23,7 @@
*
* @hide Only for use within the system server.
*/
-public interface PowerManagerInternal {
+public abstract class PowerManagerInternal {
/**
* Used by the window manager to override the screen brightness based on the
* current foreground activity.
@@ -32,7 +32,7 @@
*
* @param brightness The overridden brightness, or -1 to disable the override.
*/
- public void setScreenBrightnessOverrideFromWindowManager(int brightness);
+ public abstract void setScreenBrightnessOverrideFromWindowManager(int brightness);
/**
* Used by the window manager to override the button brightness based on the
@@ -42,7 +42,7 @@
*
* @param brightness The overridden brightness, or -1 to disable the override.
*/
- public void setButtonBrightnessOverrideFromWindowManager(int brightness);
+ public abstract void setButtonBrightnessOverrideFromWindowManager(int brightness);
/**
* Used by the window manager to override the user activity timeout based on the
@@ -53,8 +53,8 @@
*
* @param timeoutMillis The overridden timeout, or -1 to disable the override.
*/
- public void setUserActivityTimeoutOverrideFromWindowManager(long timeoutMillis);
+ public abstract void setUserActivityTimeoutOverrideFromWindowManager(long timeoutMillis);
// TODO: Remove this and retrieve as a local service instead.
- public void setPolicy(WindowManagerPolicy policy);
+ public abstract void setPolicy(WindowManagerPolicy policy);
}
diff --git a/core/java/android/view/WindowManagerInternal.java b/core/java/android/view/WindowManagerInternal.java
new file mode 100644
index 0000000..a1bd4bd
--- /dev/null
+++ b/core/java/android/view/WindowManagerInternal.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.view;
+
+import android.hardware.display.DisplayManagerInternal;
+
+/**
+ * Window manager local system service interface.
+ *
+ * @hide Only for use within the system server.
+ */
+public abstract class WindowManagerInternal {
+ /**
+ * Request that the window manager call
+ * {@link DisplayManagerInternal#performTraversalInTransactionFromWindowManager}
+ * within a surface transaction at a later time.
+ */
+ public abstract void requestTraversalFromDisplayManager();
+}
\ No newline at end of file
diff --git a/core/java/com/android/server/SystemService.java b/core/java/com/android/server/SystemService.java
index 0356753..d69293a 100644
--- a/core/java/com/android/server/SystemService.java
+++ b/core/java/com/android/server/SystemService.java
@@ -48,6 +48,7 @@
/*
* Boot Phases
*/
+ public static final int PHASE_WAIT_FOR_DEFAULT_DISPLAY = 100; // maybe should be a dependency?
public static final int PHASE_LOCK_SETTINGS_READY = 480;
public static final int PHASE_SYSTEM_SERVICES_READY = 500;
public static final int PHASE_THIRD_PARTY_APPS_CAN_START = 600;
@@ -93,7 +94,15 @@
* Publish the service so it is accessible to other services and apps.
*/
protected final void publishBinderService(String name, IBinder service) {
- ServiceManager.addService(name, service);
+ publishBinderService(name, service, false);
+ }
+
+ /**
+ * Publish the service so it is accessible to other services and apps.
+ */
+ protected final void publishBinderService(String name, IBinder service,
+ boolean allowIsolated) {
+ ServiceManager.addService(name, service, allowIsolated);
}
/**
diff --git a/services/core/java/com/android/server/DisplayThread.java b/services/core/java/com/android/server/DisplayThread.java
new file mode 100644
index 0000000..528ba0a
--- /dev/null
+++ b/services/core/java/com/android/server/DisplayThread.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2013 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;
+
+import android.os.Handler;
+
+/**
+ * Shared singleton foreground thread for the system. This is a thread for
+ * operations that affect what's on the display, which needs to have a minimum
+ * of latency. This thread should pretty much only be used by the WindowManager,
+ * DisplayManager, and InputManager to perform quick operations in real time.
+ */
+public final class DisplayThread extends ServiceThread {
+ private static DisplayThread sInstance;
+ private static Handler sHandler;
+
+ private DisplayThread() {
+ super("android.display", android.os.Process.THREAD_PRIORITY_DISPLAY, false /*allowIo*/);
+ }
+
+ private static void ensureThreadLocked() {
+ if (sInstance == null) {
+ sInstance = new DisplayThread();
+ sInstance.start();
+ sHandler = new Handler(sInstance.getLooper());
+ }
+ }
+
+ public static DisplayThread get() {
+ synchronized (UiThread.class) {
+ ensureThreadLocked();
+ return sInstance;
+ }
+ }
+
+ public static Handler getHandler() {
+ synchronized (UiThread.class) {
+ ensureThreadLocked();
+ return sHandler;
+ }
+ }
+}
diff --git a/services/core/java/com/android/server/FgThread.java b/services/core/java/com/android/server/FgThread.java
index 3b655f2..03765db 100644
--- a/services/core/java/com/android/server/FgThread.java
+++ b/services/core/java/com/android/server/FgThread.java
@@ -17,7 +17,6 @@
package com.android.server;
import android.os.Handler;
-import android.os.HandlerThread;
/**
* Shared singleton foreground thread for the system. This is a thread for regular
@@ -27,12 +26,12 @@
* simply being a background priority), which can cause operations scheduled on it
* to be delayed for a user-noticeable amount of time.
*/
-public final class FgThread extends HandlerThread {
+public final class FgThread extends ServiceThread {
private static FgThread sInstance;
private static Handler sHandler;
private FgThread() {
- super("android.fg", android.os.Process.THREAD_PRIORITY_DEFAULT);
+ super("android.fg", android.os.Process.THREAD_PRIORITY_DEFAULT, true /*allowIo*/);
}
private static void ensureThreadLocked() {
@@ -40,12 +39,6 @@
sInstance = new FgThread();
sInstance.start();
sHandler = new Handler(sInstance.getLooper());
- sHandler.post(new Runnable() {
- @Override
- public void run() {
- android.os.Process.setCanSelfBackground(false);
- }
- });
}
}
diff --git a/services/core/java/com/android/server/IoThread.java b/services/core/java/com/android/server/IoThread.java
index 09f2af7..0f29857 100644
--- a/services/core/java/com/android/server/IoThread.java
+++ b/services/core/java/com/android/server/IoThread.java
@@ -17,19 +17,18 @@
package com.android.server;
import android.os.Handler;
-import android.os.HandlerThread;
/**
* Shared singleton I/O thread for the system. This is a thread for non-background
* service operations that can potential block briefly on network IO operations
* (not waiting for data itself, but communicating with network daemons).
*/
-public final class IoThread extends HandlerThread {
+public final class IoThread extends ServiceThread {
private static IoThread sInstance;
private static Handler sHandler;
private IoThread() {
- super("android.io", android.os.Process.THREAD_PRIORITY_DEFAULT);
+ super("android.io", android.os.Process.THREAD_PRIORITY_DEFAULT, true /*allowIo*/);
}
private static void ensureThreadLocked() {
@@ -37,12 +36,6 @@
sInstance = new IoThread();
sInstance.start();
sHandler = new Handler(sInstance.getLooper());
- sHandler.post(new Runnable() {
- @Override
- public void run() {
- android.os.Process.setCanSelfBackground(false);
- }
- });
}
}
diff --git a/services/core/java/com/android/server/ServiceThread.java b/services/core/java/com/android/server/ServiceThread.java
index 75ec4ef..bce64af 100644
--- a/services/core/java/com/android/server/ServiceThread.java
+++ b/services/core/java/com/android/server/ServiceThread.java
@@ -24,11 +24,14 @@
/**
* Special handler thread that we create for system services that require their own loopers.
*/
-public final class ServiceThread extends HandlerThread {
+public class ServiceThread extends HandlerThread {
private static final String TAG = "ServiceThread";
- public ServiceThread(String name, int priority) {
+ private final boolean mAllowIo;
+
+ public ServiceThread(String name, int priority, boolean allowIo) {
super(name, priority);
+ mAllowIo = allowIo;
}
@Override
@@ -36,7 +39,7 @@
Process.setCanSelfBackground(false);
// For debug builds, log event loop stalls to dropbox for analysis.
- if (StrictMode.conditionallyEnableDebugLogging()) {
+ if (!mAllowIo && StrictMode.conditionallyEnableDebugLogging()) {
Slog.i(TAG, "Enabled StrictMode logging for " + getName() + " looper.");
}
diff --git a/services/core/java/com/android/server/SystemServer.java b/services/core/java/com/android/server/SystemServer.java
index 24b1a92..b04fc15 100644
--- a/services/core/java/com/android/server/SystemServer.java
+++ b/services/core/java/com/android/server/SystemServer.java
@@ -119,8 +119,11 @@
private Context mSystemContext;
private SystemServiceManager mSystemServiceManager;
- private Installer mInstaller; // TODO: remove this
- private PowerManagerService mPowerManagerService; // TODO: remove this
+ // TODO: remove all of these references by improving dependency resolution and boot phases
+ private Installer mInstaller;
+ private PowerManagerService mPowerManagerService;
+ private ActivityManagerService mActivityManagerService;
+ private DisplayManagerService mDisplayManagerService;
private ContentResolver mContentResolver;
/**
@@ -211,6 +214,7 @@
// Start services.
try {
startBootstrapServices();
+ startCoreServices();
startOtherServices();
} catch (RuntimeException ex) {
Slog.e("System", "******************************************");
@@ -269,22 +273,21 @@
mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class);
// Activity manager runs the show.
- mSystemServiceManager.startService(ActivityManagerService.Lifecycle.class);
+ mActivityManagerService = mSystemServiceManager.startService(
+ ActivityManagerService.Lifecycle.class).getService();
+ }
+
+ private void startCoreServices() {
+ // Display manager is needed to provide display metrics before package manager
+ // starts up.
+ mDisplayManagerService = mSystemServiceManager.startService(DisplayManagerService.class);
}
private void startOtherServices() {
- // Create a handler thread that window manager will use.
- final ServiceThread windowManagerThread = new ServiceThread("WindowManager",
- android.os.Process.THREAD_PRIORITY_DISPLAY);
- windowManagerThread.start();
- final Handler windowManagerHandler = new Handler(windowManagerThread.getLooper());
- Watchdog.getInstance().addThread(windowManagerHandler);
-
final Context context = mSystemContext;
AccountManagerService accountManager = null;
ContentService contentService = null;
LightsManager lights = null;
- DisplayManagerService display = null;
BatteryService battery = null;
VibratorService vibrator = null;
IAlarmManager alarm = null;
@@ -320,10 +323,6 @@
boolean disableNetwork = SystemProperties.getBoolean("config.disable_network", false);
try {
- Slog.i(TAG, "Display Manager");
- display = new DisplayManagerService(context, windowManagerHandler);
- ServiceManager.addService(Context.DISPLAY_SERVICE, display, true);
-
Slog.i(TAG, "Telephony Registry");
telephonyRegistry = new TelephonyRegistry(context);
ServiceManager.addService("telephony.registry", telephonyRegistry);
@@ -333,10 +332,8 @@
AttributeCache.init(context);
- if (!display.waitForDefaultDisplay()) {
- reportWtf("Timeout waiting for default display to be initialized.",
- new Throwable());
- }
+ // We need the default display before we can initialize the package manager.
+ mSystemServiceManager.startBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY);
Slog.i(TAG, "Package Manager");
// Only run "core" apps if we're encrypting the device.
@@ -357,7 +354,7 @@
} catch (RemoteException e) {
}
- ActivityManagerService.setSystemProcess();
+ mActivityManagerService.setSystemProcess();
Slog.i(TAG, "Entropy Mixer");
ServiceManager.addService("entropy", new EntropyMixer(context));
@@ -383,7 +380,7 @@
mFactoryTestMode == FactoryTest.FACTORY_TEST_LOW_LEVEL);
Slog.i(TAG, "System Content Providers");
- ActivityManagerService.installSystemProviders();
+ mActivityManagerService.installSystemProviders();
mSystemServiceManager.startService(LightsService.class);
lights = LocalServices.getService(LightsManager.class);
@@ -401,7 +398,7 @@
// lights service, content providers and the battery service.
mPowerManagerService.init(lights, battery,
BatteryStatsService.getService(),
- ActivityManagerService.self().getAppOpsService(), display);
+ mActivityManagerService.getAppOpsService());
Slog.i(TAG, "Consumer IR Service");
consumerIr = new ConsumerIrService(context);
@@ -413,26 +410,25 @@
Slog.i(TAG, "Init Watchdog");
final Watchdog watchdog = Watchdog.getInstance();
- watchdog.init(context, ActivityManagerService.self());
+ watchdog.init(context, mActivityManagerService);
Slog.i(TAG, "Input Manager");
- inputManager = new InputManagerService(context, windowManagerHandler);
+ inputManager = new InputManagerService(context);
Slog.i(TAG, "Window Manager");
- wm = WindowManagerService.main(context, display, inputManager,
- windowManagerHandler,
+ wm = WindowManagerService.main(context, inputManager,
mFactoryTestMode != FactoryTest.FACTORY_TEST_LOW_LEVEL,
!firstBoot, onlyCore);
ServiceManager.addService(Context.WINDOW_SERVICE, wm);
ServiceManager.addService(Context.INPUT_SERVICE, inputManager);
- ActivityManagerService.self().setWindowManager(wm);
+ mActivityManagerService.setWindowManager(wm);
inputManager.setWindowManagerCallbacks(wm.getInputMonitor());
inputManager.start();
- display.setWindowManager(wm);
- display.setInputManager(inputManager);
+ // TODO: Use service dependencies instead.
+ mDisplayManagerService.windowManagerAndInputReady();
// Skip Bluetooth if we have an emulator kernel
// TODO: Use a more reliable check to see if this product should
@@ -595,7 +591,7 @@
try {
Slog.i(TAG, "NetworkPolicy Service");
networkPolicy = new NetworkPolicyManagerService(
- context, ActivityManagerService.self(),
+ context, mActivityManagerService,
(IPowerManager)ServiceManager.getService(Context.POWER_SERVICE),
networkStats, networkManagement);
ServiceManager.addService(Context.NETWORK_POLICY_SERVICE, networkPolicy);
@@ -857,7 +853,7 @@
try {
Slog.i(TAG, "Dreams Service");
// Dreams (interactive idle-time views, a/k/a screen savers)
- dreamy = new DreamManagerService(context, windowManagerHandler);
+ dreamy = new DreamManagerService(context);
ServiceManager.addService(DreamService.DREAM_SERVICE, dreamy);
} catch (Throwable e) {
reportWtf("starting DreamManagerService", e);
@@ -903,7 +899,7 @@
// we are in safe mode.
final boolean safeMode = wm.detectSafeMode();
if (safeMode) {
- ActivityManagerService.self().enterSafeMode();
+ mActivityManagerService.enterSafeMode();
// Post the safe mode state in the Zygote class
Zygote.systemInSafeMode = true;
// Disable the JIT for the system_server process
@@ -941,7 +937,7 @@
}
if (safeMode) {
- ActivityManagerService.self().showSafeModeOverlay();
+ mActivityManagerService.showSafeModeOverlay();
}
// Update the configuration for this context by hand, because we're going
@@ -967,7 +963,8 @@
}
try {
- display.systemReady(safeMode, onlyCore);
+ // TODO: use boot phase and communicate these flags some other way
+ mDisplayManagerService.systemReady(safeMode, onlyCore);
} catch (Throwable e) {
reportWtf("making Display Manager Service ready", e);
}
@@ -1002,12 +999,12 @@
// where third party code can really run (but before it has actually
// started launching the initial applications), for us to complete our
// initialization.
- ActivityManagerService.self().systemReady(new Runnable() {
+ mActivityManagerService.systemReady(new Runnable() {
public void run() {
Slog.i(TAG, "Making services ready");
try {
- ActivityManagerService.self().startObservingNativeCrashes();
+ mActivityManagerService.startObservingNativeCrashes();
} catch (Throwable e) {
reportWtf("observing native crashes", e);
}
diff --git a/services/core/java/com/android/server/UiThread.java b/services/core/java/com/android/server/UiThread.java
index 60d73aa..0beb77f 100644
--- a/services/core/java/com/android/server/UiThread.java
+++ b/services/core/java/com/android/server/UiThread.java
@@ -17,21 +17,18 @@
package com.android.server;
import android.os.Handler;
-import android.os.HandlerThread;
-import android.os.StrictMode;
-import android.util.Slog;
/**
* Shared singleton thread for showing UI. This is a foreground thread, and in
* additional should not have operations that can take more than a few ms scheduled
* on it to avoid UI jank.
*/
-public final class UiThread extends HandlerThread {
+public final class UiThread extends ServiceThread {
private static UiThread sInstance;
private static Handler sHandler;
private UiThread() {
- super("android.ui", android.os.Process.THREAD_PRIORITY_FOREGROUND);
+ super("android.ui", android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
}
private static void ensureThreadLocked() {
@@ -39,19 +36,6 @@
sInstance = new UiThread();
sInstance.start();
sHandler = new Handler(sInstance.getLooper());
- sHandler.post(new Runnable() {
- @Override
- public void run() {
- //Looper.myLooper().setMessageLogging(new LogPrinter(
- // Log.VERBOSE, "WindowManagerPolicy", Log.LOG_ID_SYSTEM));
- android.os.Process.setCanSelfBackground(false);
-
- // For debug builds, log event loop stalls to dropbox for analysis.
- if (StrictMode.conditionallyEnableDebugLogging()) {
- Slog.i("UiThread", "Enabled StrictMode logging for UI thread");
- }
- }
- });
}
}
diff --git a/services/core/java/com/android/server/Watchdog.java b/services/core/java/com/android/server/Watchdog.java
index 11dab0b..1ce073a 100644
--- a/services/core/java/com/android/server/Watchdog.java
+++ b/services/core/java/com/android/server/Watchdog.java
@@ -225,6 +225,9 @@
// And also check IO thread.
mHandlerCheckers.add(new HandlerChecker(IoThread.getHandler(),
"i/o thread", DEFAULT_TIMEOUT));
+ // And the display thread.
+ mHandlerCheckers.add(new HandlerChecker(DisplayThread.getHandler(),
+ "display thread", DEFAULT_TIMEOUT));
}
public void init(Context context, ActivityManagerService activity) {
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 77ffeca..522cda6 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -998,8 +998,7 @@
WindowManagerService mWindowManager;
- static ActivityManagerService sSelf;
- static ActivityThread sSystemThread;
+ final ActivityThread mSystemThread;
int mCurrentUserId = 0;
private UserManagerService mUserManager;
@@ -1735,38 +1734,34 @@
}
};
- public static void setSystemProcess() {
+ public void setSystemProcess() {
try {
- ActivityManagerService m = sSelf;
-
- ServiceManager.addService(Context.ACTIVITY_SERVICE, m, true);
- ServiceManager.addService(ProcessStats.SERVICE_NAME, m.mProcessStats);
- ServiceManager.addService("meminfo", new MemBinder(m));
- ServiceManager.addService("gfxinfo", new GraphicsBinder(m));
- ServiceManager.addService("dbinfo", new DbBinder(m));
+ ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
+ ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
+ ServiceManager.addService("meminfo", new MemBinder(this));
+ ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
+ ServiceManager.addService("dbinfo", new DbBinder(this));
if (MONITOR_CPU_USAGE) {
- ServiceManager.addService("cpuinfo", new CpuBinder(m));
+ ServiceManager.addService("cpuinfo", new CpuBinder(this));
}
- ServiceManager.addService("permission", new PermissionController(m));
+ ServiceManager.addService("permission", new PermissionController(this));
- ApplicationInfo info =
- sSelf.mContext.getPackageManager().getApplicationInfo(
- "android", STOCK_PM_FLAGS);
- sSystemThread.installSystemApplicationInfo(info);
+ ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
+ "android", STOCK_PM_FLAGS);
+ mSystemThread.installSystemApplicationInfo(info);
- synchronized (sSelf) {
- ProcessRecord app = sSelf.newProcessRecordLocked(info,
- info.processName, false);
+ synchronized (this) {
+ ProcessRecord app = newProcessRecordLocked(info, info.processName, false);
app.persistent = true;
app.pid = MY_PID;
app.maxAdj = ProcessList.SYSTEM_ADJ;
- app.makeActive(sSystemThread.getApplicationThread(), sSelf.mProcessStats);
- sSelf.mProcessNames.put(app.processName, app.uid, app);
- synchronized (sSelf.mPidsSelfLocked) {
- sSelf.mPidsSelfLocked.put(app.pid, app);
+ app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
+ mProcessNames.put(app.processName, app.uid, app);
+ synchronized (mPidsSelfLocked) {
+ mPidsSelfLocked.put(app.pid, app);
}
- sSelf.updateLruProcessLocked(app, false, null);
- sSelf.updateOomAdjLocked();
+ updateLruProcessLocked(app, false, null);
+ updateOomAdjLocked();
}
} catch (PackageManager.NameNotFoundException e) {
throw new RuntimeException(
@@ -1780,14 +1775,10 @@
}
public void startObservingNativeCrashes() {
- final NativeCrashListener ncl = new NativeCrashListener();
+ final NativeCrashListener ncl = new NativeCrashListener(this);
ncl.start();
}
- public static ActivityManagerService self() {
- return sSelf;
- }
-
public IAppOpsService getAppOpsService() {
return mAppOpsService;
}
@@ -1888,20 +1879,23 @@
public void onStart() {
mService.start();
}
+
+ public ActivityManagerService getService() {
+ return mService;
+ }
}
// Note: This method is invoked on the main thread but may need to attach various
// handlers to other threads. So take care to be explicit about the looper.
public ActivityManagerService(Context systemContext) {
- sSelf = this;
- sSystemThread = ActivityThread.currentActivityThread();
-
mContext = systemContext;
mFactoryTest = FactoryTest.getMode();
+ mSystemThread = ActivityThread.currentActivityThread();
Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
- mHandlerThread = new ServiceThread(TAG, android.os.Process.THREAD_PRIORITY_FOREGROUND);
+ mHandlerThread = new ServiceThread(TAG,
+ android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
mHandlerThread.start();
mHandler = new MainHandler(mHandlerThread.getLooper());
@@ -2882,7 +2876,7 @@
// See if we should be showing the platform update setup UI.
Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
- List<ResolveInfo> ris = sSelf.mContext.getPackageManager()
+ List<ResolveInfo> ris = mContext.getPackageManager()
.queryIntentActivities(intent, PackageManager.GET_META_DATA);
// We don't allow third party apps to replace this.
@@ -7974,11 +7968,11 @@
}
}
- public static final void installSystemProviders() {
+ public final void installSystemProviders() {
List<ProviderInfo> providers;
- synchronized (sSelf) {
- ProcessRecord app = sSelf.mProcessNames.get("system", Process.SYSTEM_UID);
- providers = sSelf.generateApplicationProvidersLocked(app);
+ synchronized (this) {
+ ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
+ providers = generateApplicationProvidersLocked(app);
if (providers != null) {
for (int i=providers.size()-1; i>=0; i--) {
ProviderInfo pi = (ProviderInfo)providers.get(i);
@@ -7991,12 +7985,12 @@
}
}
if (providers != null) {
- sSystemThread.installSystemProviders(providers);
+ mSystemThread.installSystemProviders(providers);
}
- sSelf.mCoreSettingsObserver = new CoreSettingsObserver(sSelf);
+ mCoreSettingsObserver = new CoreSettingsObserver(this);
- sSelf.mUsageStatsService.monitorPackages();
+ mUsageStatsService.monitorPackages();
}
/**
@@ -13999,7 +13993,7 @@
// boot, where the first config change needs to guarantee
// all resources have that config before following boot
// code is executed.
- sSystemThread.applyConfigurationToResources(configCopy);
+ mSystemThread.applyConfigurationToResources(configCopy);
if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
diff --git a/services/core/java/com/android/server/am/NativeCrashListener.java b/services/core/java/com/android/server/am/NativeCrashListener.java
index 2c7f1f1..b12843b 100644
--- a/services/core/java/com/android/server/am/NativeCrashListener.java
+++ b/services/core/java/com/android/server/am/NativeCrashListener.java
@@ -95,8 +95,8 @@
* Daemon thread that accept()s incoming domain socket connections from debuggerd
* and processes the crash dump that is passed through.
*/
- NativeCrashListener() {
- mAm = ActivityManagerService.self();
+ NativeCrashListener(ActivityManagerService am) {
+ mAm = am;
}
@Override
diff --git a/services/core/java/com/android/server/display/DisplayDevice.java b/services/core/java/com/android/server/display/DisplayDevice.java
index 4161147..9ec1122 100644
--- a/services/core/java/com/android/server/display/DisplayDevice.java
+++ b/services/core/java/com/android/server/display/DisplayDevice.java
@@ -17,6 +17,7 @@
package com.android.server.display;
import android.graphics.Rect;
+import android.hardware.display.DisplayViewport;
import android.os.IBinder;
import android.view.Surface;
import android.view.SurfaceControl;
diff --git a/services/core/java/com/android/server/display/DisplayDeviceInfo.java b/services/core/java/com/android/server/display/DisplayDeviceInfo.java
index 11aecdd..75f1f53 100644
--- a/services/core/java/com/android/server/display/DisplayDeviceInfo.java
+++ b/services/core/java/com/android/server/display/DisplayDeviceInfo.java
@@ -16,6 +16,7 @@
package com.android.server.display;
+import android.hardware.display.DisplayViewport;
import android.util.DisplayMetrics;
import android.view.Display;
import android.view.Surface;
diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java
index 12ef65a..d5ee838 100644
--- a/services/core/java/com/android/server/display/DisplayManagerService.java
+++ b/services/core/java/com/android/server/display/DisplayManagerService.java
@@ -23,12 +23,17 @@
import android.content.pm.PackageManager;
import android.hardware.display.DisplayManager;
import android.hardware.display.DisplayManagerGlobal;
+import android.hardware.display.DisplayManagerInternal;
+import android.hardware.display.DisplayViewport;
+import android.hardware.display.DisplayManagerInternal.DisplayTransactionListener;
import android.hardware.display.IDisplayManager;
import android.hardware.display.IDisplayManagerCallback;
import android.hardware.display.WifiDisplayStatus;
+import android.hardware.input.InputManagerInternal;
import android.os.Binder;
import android.os.Handler;
import android.os.IBinder;
+import android.os.IBinder.DeathRecipient;
import android.os.Looper;
import android.os.Message;
import android.os.Process;
@@ -42,7 +47,11 @@
import android.view.Display;
import android.view.DisplayInfo;
import android.view.Surface;
+import android.view.WindowManagerInternal;
+import com.android.server.DisplayThread;
+import com.android.server.LocalServices;
+import com.android.server.SystemService;
import com.android.server.UiThread;
import java.io.FileDescriptor;
@@ -94,7 +103,7 @@
* avoid this by making all potentially reentrant out-calls asynchronous.
* </p>
*/
-public final class DisplayManagerService extends IDisplayManager.Stub {
+public final class DisplayManagerService extends SystemService {
private static final String TAG = "DisplayManagerService";
private static final boolean DEBUG = false;
@@ -115,12 +124,12 @@
private static final int DISPLAY_BLANK_STATE_BLANKED = 1;
private static final int DISPLAY_BLANK_STATE_UNBLANKED = 2;
- private final Context mContext;
+ private Context mContext;
private final DisplayManagerHandler mHandler;
private final Handler mUiHandler;
private final DisplayAdapterListener mDisplayAdapterListener;
- private WindowManagerFuncs mWindowManagerFuncs;
- private InputManagerFuncs mInputManagerFuncs;
+ private WindowManagerInternal mWindowManagerInternal;
+ private InputManagerInternal mInputManagerInternal;
// The synchronization root for the display manager.
// This lock guards most of the display manager's state.
@@ -199,57 +208,55 @@
private final DisplayViewport mTempDefaultViewport = new DisplayViewport();
private final DisplayViewport mTempExternalTouchViewport = new DisplayViewport();
- public DisplayManagerService(Context context, Handler mainHandler) {
- mContext = context;
- mHandler = new DisplayManagerHandler(mainHandler.getLooper());
+ public DisplayManagerService() {
+ mHandler = new DisplayManagerHandler(DisplayThread.get().getLooper());
mUiHandler = UiThread.getHandler();
mDisplayAdapterListener = new DisplayAdapterListener();
mSingleDisplayDemoMode = SystemProperties.getBoolean("persist.demo.singledisplay", false);
-
- mHandler.sendEmptyMessage(MSG_REGISTER_DEFAULT_DISPLAY_ADAPTER);
}
- /**
- * Pauses the boot process to wait for the first display to be initialized.
- */
- public boolean waitForDefaultDisplay() {
- synchronized (mSyncRoot) {
- long timeout = SystemClock.uptimeMillis() + WAIT_FOR_DEFAULT_DISPLAY_TIMEOUT;
- while (mLogicalDisplays.get(Display.DEFAULT_DISPLAY) == null) {
- long delay = timeout - SystemClock.uptimeMillis();
- if (delay <= 0) {
- return false;
- }
- if (DEBUG) {
- Slog.d(TAG, "waitForDefaultDisplay: waiting, timeout=" + delay);
- }
- try {
- mSyncRoot.wait(delay);
- } catch (InterruptedException ex) {
+ @Override
+ public void onCreate(Context context) {
+ mContext = context;
+ }
+
+ @Override
+ public void onStart() {
+ mHandler.sendEmptyMessage(MSG_REGISTER_DEFAULT_DISPLAY_ADAPTER);
+
+ publishBinderService(Context.DISPLAY_SERVICE, new BinderService(),
+ true /*allowIsolated*/);
+ publishLocalService(DisplayManagerInternal.class, new LocalService());
+ }
+
+ @Override
+ public void onBootPhase(int phase) {
+ if (phase == PHASE_WAIT_FOR_DEFAULT_DISPLAY) {
+ synchronized (mSyncRoot) {
+ long timeout = SystemClock.uptimeMillis() + WAIT_FOR_DEFAULT_DISPLAY_TIMEOUT;
+ while (mLogicalDisplays.get(Display.DEFAULT_DISPLAY) == null) {
+ long delay = timeout - SystemClock.uptimeMillis();
+ if (delay <= 0) {
+ throw new RuntimeException("Timeout waiting for default display "
+ + "to be initialized.");
+ }
+ if (DEBUG) {
+ Slog.d(TAG, "waitForDefaultDisplay: waiting, timeout=" + delay);
+ }
+ try {
+ mSyncRoot.wait(delay);
+ } catch (InterruptedException ex) {
+ }
}
}
}
- return true;
}
- /**
- * Called during initialization to associate the display manager with the
- * window manager.
- */
- public void setWindowManager(WindowManagerFuncs windowManagerFuncs) {
+ // TODO: Use dependencies or a boot phase
+ public void windowManagerAndInputReady() {
synchronized (mSyncRoot) {
- mWindowManagerFuncs = windowManagerFuncs;
- scheduleTraversalLocked(false);
- }
- }
-
- /**
- * Called during initialization to associate the display manager with the
- * input manager.
- */
- public void setInputManager(InputManagerFuncs inputManagerFuncs) {
- synchronized (mSyncRoot) {
- mInputManagerFuncs = inputManagerFuncs;
+ mWindowManagerInternal = LocalServices.getService(WindowManagerInternal.class);
+ mInputManagerInternal = LocalServices.getService(InputManagerInternal.class);
scheduleTraversalLocked(false);
}
}
@@ -266,50 +273,19 @@
mHandler.sendEmptyMessage(MSG_REGISTER_ADDITIONAL_DISPLAY_ADAPTERS);
}
- /**
- * Registers a display transaction listener to provide the client a chance to
- * update its surfaces within the same transaction as any display layout updates.
- *
- * @param listener The listener to register.
- */
- public void registerDisplayTransactionListener(DisplayTransactionListener listener) {
- if (listener == null) {
- throw new IllegalArgumentException("listener must not be null");
- }
-
+ private void registerDisplayTransactionListenerInternal(
+ DisplayTransactionListener listener) {
// List is self-synchronized copy-on-write.
mDisplayTransactionListeners.add(listener);
}
- /**
- * Unregisters a display transaction listener to provide the client a chance to
- * update its surfaces within the same transaction as any display layout updates.
- *
- * @param listener The listener to unregister.
- */
- public void unregisterDisplayTransactionListener(DisplayTransactionListener listener) {
- if (listener == null) {
- throw new IllegalArgumentException("listener must not be null");
- }
-
+ private void unregisterDisplayTransactionListenerInternal(
+ DisplayTransactionListener listener) {
// List is self-synchronized copy-on-write.
mDisplayTransactionListeners.remove(listener);
}
- /**
- * Overrides the display information of a particular logical display.
- * This is used by the window manager to control the size and characteristics
- * of the default display. It is expected to apply the requested change
- * to the display information synchronously so that applications will immediately
- * observe the new state.
- *
- * NOTE: This method must be the only entry point by which the window manager
- * influences the logical configuration of displays.
- *
- * @param displayId The logical display id.
- * @param info The new data to be stored.
- */
- public void setDisplayInfoOverrideFromWindowManager(
+ private void setDisplayInfoOverrideFromWindowManagerInternal(
int displayId, DisplayInfo info) {
synchronized (mSyncRoot) {
LogicalDisplay display = mLogicalDisplays.get(displayId);
@@ -322,11 +298,7 @@
}
}
- /**
- * Called by the window manager to perform traversals while holding a
- * surface flinger transaction.
- */
- public void performTraversalInTransactionFromWindowManager() {
+ private void performTraversalInTransactionFromWindowManagerInternal() {
synchronized (mSyncRoot) {
if (!mPendingTraversal) {
return;
@@ -342,10 +314,7 @@
}
}
- /**
- * Called by the power manager to blank all displays.
- */
- public void blankAllDisplaysFromPowerManager() {
+ private void blankAllDisplaysFromPowerManagerInternal() {
synchronized (mSyncRoot) {
if (mAllDisplayBlankStateFromPowerManager != DISPLAY_BLANK_STATE_BLANKED) {
mAllDisplayBlankStateFromPowerManager = DISPLAY_BLANK_STATE_BLANKED;
@@ -355,10 +324,7 @@
}
}
- /**
- * Called by the power manager to unblank all displays.
- */
- public void unblankAllDisplaysFromPowerManager() {
+ private void unblankAllDisplaysFromPowerManagerInternal() {
synchronized (mSyncRoot) {
if (mAllDisplayBlankStateFromPowerManager != DISPLAY_BLANK_STATE_UNBLANKED) {
mAllDisplayBlankStateFromPowerManager = DISPLAY_BLANK_STATE_UNBLANKED;
@@ -368,70 +334,40 @@
}
}
- /**
- * Returns information about the specified logical display.
- *
- * @param displayId The logical display id.
- * @return The logical display info, or null if the display does not exist. The
- * returned object must be treated as immutable.
- */
- @Override // Binder call
- public DisplayInfo getDisplayInfo(int displayId) {
- final int callingUid = Binder.getCallingUid();
- final long token = Binder.clearCallingIdentity();
- try {
- synchronized (mSyncRoot) {
- LogicalDisplay display = mLogicalDisplays.get(displayId);
- if (display != null) {
- DisplayInfo info = display.getDisplayInfoLocked();
- if (info.hasAccess(callingUid)) {
- return info;
- }
- }
- return null;
- }
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- }
-
- /**
- * Returns the list of all display ids.
- */
- @Override // Binder call
- public int[] getDisplayIds() {
- final int callingUid = Binder.getCallingUid();
- final long token = Binder.clearCallingIdentity();
- try {
- synchronized (mSyncRoot) {
- final int count = mLogicalDisplays.size();
- int[] displayIds = new int[count];
- int n = 0;
- for (int i = 0; i < count; i++) {
- LogicalDisplay display = mLogicalDisplays.valueAt(i);
- DisplayInfo info = display.getDisplayInfoLocked();
- if (info.hasAccess(callingUid)) {
- displayIds[n++] = mLogicalDisplays.keyAt(i);
- }
- }
- if (n != count) {
- displayIds = Arrays.copyOfRange(displayIds, 0, n);
- }
- return displayIds;
- }
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- }
-
- @Override // Binder call
- public void registerCallback(IDisplayManagerCallback callback) {
- if (callback == null) {
- throw new IllegalArgumentException("listener must not be null");
- }
-
+ private DisplayInfo getDisplayInfoInternal(int displayId, int callingUid) {
synchronized (mSyncRoot) {
- int callingPid = Binder.getCallingPid();
+ LogicalDisplay display = mLogicalDisplays.get(displayId);
+ if (display != null) {
+ DisplayInfo info = display.getDisplayInfoLocked();
+ if (info.hasAccess(callingUid)) {
+ return info;
+ }
+ }
+ return null;
+ }
+ }
+
+ private int[] getDisplayIdsInternal(int callingUid) {
+ synchronized (mSyncRoot) {
+ final int count = mLogicalDisplays.size();
+ int[] displayIds = new int[count];
+ int n = 0;
+ for (int i = 0; i < count; i++) {
+ LogicalDisplay display = mLogicalDisplays.valueAt(i);
+ DisplayInfo info = display.getDisplayInfoLocked();
+ if (info.hasAccess(callingUid)) {
+ displayIds[n++] = mLogicalDisplays.keyAt(i);
+ }
+ }
+ if (n != count) {
+ displayIds = Arrays.copyOfRange(displayIds, 0, n);
+ }
+ return displayIds;
+ }
+ }
+
+ private void registerCallbackInternal(IDisplayManagerCallback callback, int callingPid) {
+ synchronized (mSyncRoot) {
if (mCallbacks.get(callingPid) != null) {
throw new SecurityException("The calling process has already "
+ "registered an IDisplayManagerCallback.");
@@ -457,24 +393,14 @@
}
}
- @Override // Binder call
- public void startWifiDisplayScan() {
- mContext.enforceCallingOrSelfPermission(Manifest.permission.CONFIGURE_WIFI_DISPLAY,
- "Permission required to start wifi display scans");
-
- final int callingPid = Binder.getCallingPid();
- final long token = Binder.clearCallingIdentity();
- try {
- synchronized (mSyncRoot) {
- CallbackRecord record = mCallbacks.get(callingPid);
- if (record == null) {
- throw new IllegalStateException("The calling process has not "
- + "registered an IDisplayManagerCallback.");
- }
- startWifiDisplayScanLocked(record);
+ private void startWifiDisplayScanInternal(int callingPid) {
+ synchronized (mSyncRoot) {
+ CallbackRecord record = mCallbacks.get(callingPid);
+ if (record == null) {
+ throw new IllegalStateException("The calling process has not "
+ + "registered an IDisplayManagerCallback.");
}
- } finally {
- Binder.restoreCallingIdentity(token);
+ startWifiDisplayScanLocked(record);
}
}
@@ -489,24 +415,14 @@
}
}
- @Override // Binder call
- public void stopWifiDisplayScan() {
- mContext.enforceCallingOrSelfPermission(Manifest.permission.CONFIGURE_WIFI_DISPLAY,
- "Permission required to stop wifi display scans");
-
- final int callingPid = Binder.getCallingPid();
- final long token = Binder.clearCallingIdentity();
- try {
- synchronized (mSyncRoot) {
- CallbackRecord record = mCallbacks.get(callingPid);
- if (record == null) {
- throw new IllegalStateException("The calling process has not "
- + "registered an IDisplayManagerCallback.");
- }
- stopWifiDisplayScanLocked(record);
+ private void stopWifiDisplayScanInternal(int callingPid) {
+ synchronized (mSyncRoot) {
+ CallbackRecord record = mCallbacks.get(callingPid);
+ if (record == null) {
+ throw new IllegalStateException("The calling process has not "
+ + "registered an IDisplayManagerCallback.");
}
- } finally {
- Binder.restoreCallingIdentity(token);
+ stopWifiDisplayScanLocked(record);
}
}
@@ -525,244 +441,106 @@
}
}
- @Override // Binder call
- public void connectWifiDisplay(String address) {
- if (address == null) {
- throw new IllegalArgumentException("address must not be null");
- }
- mContext.enforceCallingOrSelfPermission(Manifest.permission.CONFIGURE_WIFI_DISPLAY,
- "Permission required to connect to a wifi display");
-
- final long token = Binder.clearCallingIdentity();
- try {
- synchronized (mSyncRoot) {
- if (mWifiDisplayAdapter != null) {
- mWifiDisplayAdapter.requestConnectLocked(address);
- }
+ private void connectWifiDisplayInternal(String address) {
+ synchronized (mSyncRoot) {
+ if (mWifiDisplayAdapter != null) {
+ mWifiDisplayAdapter.requestConnectLocked(address);
}
- } finally {
- Binder.restoreCallingIdentity(token);
}
}
- @Override
- public void pauseWifiDisplay() {
- mContext.enforceCallingOrSelfPermission(Manifest.permission.CONFIGURE_WIFI_DISPLAY,
- "Permission required to pause a wifi display session");
-
- final long token = Binder.clearCallingIdentity();
- try {
- synchronized (mSyncRoot) {
- if (mWifiDisplayAdapter != null) {
- mWifiDisplayAdapter.requestPauseLocked();
- }
+ private void pauseWifiDisplayInternal() {
+ synchronized (mSyncRoot) {
+ if (mWifiDisplayAdapter != null) {
+ mWifiDisplayAdapter.requestPauseLocked();
}
- } finally {
- Binder.restoreCallingIdentity(token);
}
}
- @Override
- public void resumeWifiDisplay() {
- mContext.enforceCallingOrSelfPermission(Manifest.permission.CONFIGURE_WIFI_DISPLAY,
- "Permission required to resume a wifi display session");
-
- final long token = Binder.clearCallingIdentity();
- try {
- synchronized (mSyncRoot) {
- if (mWifiDisplayAdapter != null) {
- mWifiDisplayAdapter.requestResumeLocked();
- }
+ private void resumeWifiDisplayInternal() {
+ synchronized (mSyncRoot) {
+ if (mWifiDisplayAdapter != null) {
+ mWifiDisplayAdapter.requestResumeLocked();
}
- } finally {
- Binder.restoreCallingIdentity(token);
}
}
- @Override // Binder call
- public void disconnectWifiDisplay() {
- // This request does not require special permissions.
- // Any app can request disconnection from the currently active wifi display.
- // This exception should no longer be needed once wifi display control moves
- // to the media router service.
-
- final long token = Binder.clearCallingIdentity();
- try {
- synchronized (mSyncRoot) {
- if (mWifiDisplayAdapter != null) {
- mWifiDisplayAdapter.requestDisconnectLocked();
- }
+ private void disconnectWifiDisplayInternal() {
+ synchronized (mSyncRoot) {
+ if (mWifiDisplayAdapter != null) {
+ mWifiDisplayAdapter.requestDisconnectLocked();
}
- } finally {
- Binder.restoreCallingIdentity(token);
}
}
- @Override // Binder call
- public void renameWifiDisplay(String address, String alias) {
- if (address == null) {
- throw new IllegalArgumentException("address must not be null");
- }
- mContext.enforceCallingOrSelfPermission(Manifest.permission.CONFIGURE_WIFI_DISPLAY,
- "Permission required to rename to a wifi display");
-
- final long token = Binder.clearCallingIdentity();
- try {
- synchronized (mSyncRoot) {
- if (mWifiDisplayAdapter != null) {
- mWifiDisplayAdapter.requestRenameLocked(address, alias);
- }
+ private void renameWifiDisplayInternal(String address, String alias) {
+ synchronized (mSyncRoot) {
+ if (mWifiDisplayAdapter != null) {
+ mWifiDisplayAdapter.requestRenameLocked(address, alias);
}
- } finally {
- Binder.restoreCallingIdentity(token);
}
}
- @Override // Binder call
- public void forgetWifiDisplay(String address) {
- if (address == null) {
- throw new IllegalArgumentException("address must not be null");
- }
- mContext.enforceCallingOrSelfPermission(Manifest.permission.CONFIGURE_WIFI_DISPLAY,
- "Permission required to forget to a wifi display");
-
- final long token = Binder.clearCallingIdentity();
- try {
- synchronized (mSyncRoot) {
- if (mWifiDisplayAdapter != null) {
- mWifiDisplayAdapter.requestForgetLocked(address);
- }
+ private void forgetWifiDisplayInternal(String address) {
+ synchronized (mSyncRoot) {
+ if (mWifiDisplayAdapter != null) {
+ mWifiDisplayAdapter.requestForgetLocked(address);
}
- } finally {
- Binder.restoreCallingIdentity(token);
}
}
- @Override // Binder call
- public WifiDisplayStatus getWifiDisplayStatus() {
- // This request does not require special permissions.
- // Any app can get information about available wifi displays.
-
- final long token = Binder.clearCallingIdentity();
- try {
- synchronized (mSyncRoot) {
- if (mWifiDisplayAdapter != null) {
- return mWifiDisplayAdapter.getWifiDisplayStatusLocked();
- }
- return new WifiDisplayStatus();
+ private WifiDisplayStatus getWifiDisplayStatusInternal() {
+ synchronized (mSyncRoot) {
+ if (mWifiDisplayAdapter != null) {
+ return mWifiDisplayAdapter.getWifiDisplayStatusLocked();
}
- } finally {
- Binder.restoreCallingIdentity(token);
+ return new WifiDisplayStatus();
}
}
- @Override // Binder call
- public int createVirtualDisplay(IBinder appToken, String packageName,
+ private int createVirtualDisplayInternal(IBinder appToken, int callingUid, String packageName,
String name, int width, int height, int densityDpi, Surface surface, int flags) {
- final int callingUid = Binder.getCallingUid();
- if (!validatePackageName(callingUid, packageName)) {
- throw new SecurityException("packageName must match the calling uid");
- }
- if (appToken == null) {
- throw new IllegalArgumentException("appToken must not be null");
- }
- if (TextUtils.isEmpty(name)) {
- throw new IllegalArgumentException("name must be non-null and non-empty");
- }
- if (width <= 0 || height <= 0 || densityDpi <= 0) {
- throw new IllegalArgumentException("width, height, and densityDpi must be "
- + "greater than 0");
- }
- if (surface == null) {
- throw new IllegalArgumentException("surface must not be null");
- }
- if (callingUid != Process.SYSTEM_UID &&
- (flags & DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC) != 0) {
- if (mContext.checkCallingPermission(android.Manifest.permission.CAPTURE_VIDEO_OUTPUT)
- != PackageManager.PERMISSION_GRANTED
- && mContext.checkCallingPermission(
- android.Manifest.permission.CAPTURE_SECURE_VIDEO_OUTPUT)
- != PackageManager.PERMISSION_GRANTED) {
- throw new SecurityException("Requires CAPTURE_VIDEO_OUTPUT or "
- + "CAPTURE_SECURE_VIDEO_OUTPUT permission to create a "
- + "public virtual display.");
+ synchronized (mSyncRoot) {
+ if (mVirtualDisplayAdapter == null) {
+ Slog.w(TAG, "Rejecting request to create private virtual display "
+ + "because the virtual display adapter is not available.");
+ return -1;
}
- }
- if ((flags & DisplayManager.VIRTUAL_DISPLAY_FLAG_SECURE) != 0) {
- if (mContext.checkCallingPermission(
- android.Manifest.permission.CAPTURE_SECURE_VIDEO_OUTPUT)
- != PackageManager.PERMISSION_GRANTED) {
- throw new SecurityException("Requires CAPTURE_SECURE_VIDEO_OUTPUT "
- + "to create a secure virtual display.");
+
+ DisplayDevice device = mVirtualDisplayAdapter.createVirtualDisplayLocked(
+ appToken, callingUid, packageName, name, width, height, densityDpi,
+ surface, flags);
+ if (device == null) {
+ return -1;
}
- }
- final long token = Binder.clearCallingIdentity();
- try {
- synchronized (mSyncRoot) {
- if (mVirtualDisplayAdapter == null) {
- Slog.w(TAG, "Rejecting request to create private virtual display "
- + "because the virtual display adapter is not available.");
- return -1;
- }
-
- DisplayDevice device = mVirtualDisplayAdapter.createVirtualDisplayLocked(
- appToken, callingUid, packageName, name, width, height, densityDpi,
- surface, flags);
- if (device == null) {
- return -1;
- }
-
- handleDisplayDeviceAddedLocked(device);
- LogicalDisplay display = findLogicalDisplayForDeviceLocked(device);
- if (display != null) {
- return display.getDisplayIdLocked();
- }
-
- // Something weird happened and the logical display was not created.
- Slog.w(TAG, "Rejecting request to create virtual display "
- + "because the logical display was not created.");
- mVirtualDisplayAdapter.releaseVirtualDisplayLocked(appToken);
- handleDisplayDeviceRemovedLocked(device);
+ handleDisplayDeviceAddedLocked(device);
+ LogicalDisplay display = findLogicalDisplayForDeviceLocked(device);
+ if (display != null) {
+ return display.getDisplayIdLocked();
}
- } finally {
- Binder.restoreCallingIdentity(token);
+
+ // Something weird happened and the logical display was not created.
+ Slog.w(TAG, "Rejecting request to create virtual display "
+ + "because the logical display was not created.");
+ mVirtualDisplayAdapter.releaseVirtualDisplayLocked(appToken);
+ handleDisplayDeviceRemovedLocked(device);
}
return -1;
}
- @Override // Binder call
- public void releaseVirtualDisplay(IBinder appToken) {
- final long token = Binder.clearCallingIdentity();
- try {
- synchronized (mSyncRoot) {
- if (mVirtualDisplayAdapter == null) {
- return;
- }
-
- DisplayDevice device =
- mVirtualDisplayAdapter.releaseVirtualDisplayLocked(appToken);
- if (device != null) {
- handleDisplayDeviceRemovedLocked(device);
- }
+ private void releaseVirtualDisplayInternal(IBinder appToken) {
+ synchronized (mSyncRoot) {
+ if (mVirtualDisplayAdapter == null) {
+ return;
}
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- }
- private boolean validatePackageName(int uid, String packageName) {
- if (packageName != null) {
- String[] packageNames = mContext.getPackageManager().getPackagesForUid(uid);
- if (packageNames != null) {
- for (String n : packageNames) {
- if (n.equals(packageName)) {
- return true;
- }
- }
+ DisplayDevice device =
+ mVirtualDisplayAdapter.releaseVirtualDisplayLocked(appToken);
+ if (device != null) {
+ handleDisplayDeviceRemovedLocked(device);
}
}
- return false;
}
private void registerDefaultDisplayAdapter() {
@@ -986,26 +764,13 @@
}
// Tell the input system about these new viewports.
- if (mInputManagerFuncs != null) {
+ if (mInputManagerInternal != null) {
mHandler.sendEmptyMessage(MSG_UPDATE_VIEWPORT);
}
}
- /**
- * Tells the display manager whether there is interesting unique content on the
- * specified logical display. This is used to control automatic mirroring.
- * <p>
- * If the display has unique content, then the display manager arranges for it
- * to be presented on a physical display if appropriate. Otherwise, the display manager
- * may choose to make the physical display mirror some other logical display.
- * </p>
- *
- * @param displayId The logical display id to update.
- * @param hasContent True if the logical display has content.
- * @param inTraversal True if called from WindowManagerService during a window traversal prior
- * to call to performTraversalInTransactionFromWindowManager.
- */
- public void setDisplayHasContent(int displayId, boolean hasContent, boolean inTraversal) {
+ private void setDisplayHasContentInternal(int displayId, boolean hasContent,
+ boolean inTraversal) {
synchronized (mSyncRoot) {
LogicalDisplay display = mLogicalDisplays.get(displayId);
if (display != null && display.hasContentLocked() != hasContent) {
@@ -1091,7 +856,7 @@
// Requests that performTraversalsInTransactionFromWindowManager be called at a
// later time to apply changes to surfaces and displays.
private void scheduleTraversalLocked(boolean inTraversal) {
- if (!mPendingTraversal && mWindowManagerFuncs != null) {
+ if (!mPendingTraversal && mWindowManagerInternal != null) {
mPendingTraversal = true;
if (!inTraversal) {
mHandler.sendEmptyMessage(MSG_REQUEST_TRAVERSAL);
@@ -1124,16 +889,7 @@
mTempCallbacks.clear();
}
- @Override // Binder call
- public void dump(FileDescriptor fd, final PrintWriter pw, String[] args) {
- if (mContext == null
- || mContext.checkCallingOrSelfPermission(Manifest.permission.DUMP)
- != PackageManager.PERMISSION_GRANTED) {
- pw.println("Permission Denial: can't dump DisplayManager from from pid="
- + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid());
- return;
- }
-
+ private void dumpInternal(PrintWriter pw) {
pw.println("DISPLAY MANAGER (dumpsys display)");
synchronized (mSyncRoot) {
@@ -1195,30 +951,6 @@
public static final class SyncRoot {
}
- /**
- * Private interface to the window manager.
- */
- public interface WindowManagerFuncs {
- /**
- * Request that the window manager call
- * {@link #performTraversalInTransactionFromWindowManager} within a surface
- * transaction at a later time.
- */
- void requestTraversal();
- }
-
- /**
- * Private interface to the input manager.
- */
- public interface InputManagerFuncs {
- /**
- * Sets information about the displays as needed by the input system.
- * The input system should copy this information if required.
- */
- void setDisplayViewports(DisplayViewport defaultViewport,
- DisplayViewport externalTouchViewport);
- }
-
private final class DisplayManagerHandler extends Handler {
public DisplayManagerHandler(Looper looper) {
super(looper, null, true /*async*/);
@@ -1240,7 +972,7 @@
break;
case MSG_REQUEST_TRAVERSAL:
- mWindowManagerFuncs.requestTraversal();
+ mWindowManagerInternal.requestTraversalFromDisplayManager();
break;
case MSG_UPDATE_VIEWPORT: {
@@ -1248,7 +980,7 @@
mTempDefaultViewport.copyFrom(mDefaultViewport);
mTempExternalTouchViewport.copyFrom(mExternalTouchViewport);
}
- mInputManagerFuncs.setDisplayViewports(
+ mInputManagerInternal.setDisplayViewports(
mTempDefaultViewport, mTempExternalTouchViewport);
break;
}
@@ -1311,4 +1043,325 @@
}
}
}
+
+ private final class BinderService extends IDisplayManager.Stub {
+ /**
+ * Returns information about the specified logical display.
+ *
+ * @param displayId The logical display id.
+ * @return The logical display info, or null if the display does not exist. The
+ * returned object must be treated as immutable.
+ */
+ @Override // Binder call
+ public DisplayInfo getDisplayInfo(int displayId) {
+ final int callingUid = Binder.getCallingUid();
+ final long token = Binder.clearCallingIdentity();
+ try {
+ return getDisplayInfoInternal(displayId, callingUid);
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ }
+
+ /**
+ * Returns the list of all display ids.
+ */
+ @Override // Binder call
+ public int[] getDisplayIds() {
+ final int callingUid = Binder.getCallingUid();
+ final long token = Binder.clearCallingIdentity();
+ try {
+ return getDisplayIdsInternal(callingUid);
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ }
+
+ @Override // Binder call
+ public void registerCallback(IDisplayManagerCallback callback) {
+ if (callback == null) {
+ throw new IllegalArgumentException("listener must not be null");
+ }
+
+ final int callingPid = Binder.getCallingPid();
+ final long token = Binder.clearCallingIdentity();
+ try {
+ registerCallbackInternal(callback, callingPid);
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ }
+
+ @Override // Binder call
+ public void startWifiDisplayScan() {
+ mContext.enforceCallingOrSelfPermission(Manifest.permission.CONFIGURE_WIFI_DISPLAY,
+ "Permission required to start wifi display scans");
+
+ final int callingPid = Binder.getCallingPid();
+ final long token = Binder.clearCallingIdentity();
+ try {
+ startWifiDisplayScanInternal(callingPid);
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ }
+
+ @Override // Binder call
+ public void stopWifiDisplayScan() {
+ mContext.enforceCallingOrSelfPermission(Manifest.permission.CONFIGURE_WIFI_DISPLAY,
+ "Permission required to stop wifi display scans");
+
+ final int callingPid = Binder.getCallingPid();
+ final long token = Binder.clearCallingIdentity();
+ try {
+ stopWifiDisplayScanInternal(callingPid);
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ }
+
+ @Override // Binder call
+ public void connectWifiDisplay(String address) {
+ if (address == null) {
+ throw new IllegalArgumentException("address must not be null");
+ }
+ mContext.enforceCallingOrSelfPermission(Manifest.permission.CONFIGURE_WIFI_DISPLAY,
+ "Permission required to connect to a wifi display");
+
+ final long token = Binder.clearCallingIdentity();
+ try {
+ connectWifiDisplayInternal(address);
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ }
+
+ @Override // Binder call
+ public void disconnectWifiDisplay() {
+ // This request does not require special permissions.
+ // Any app can request disconnection from the currently active wifi display.
+ // This exception should no longer be needed once wifi display control moves
+ // to the media router service.
+
+ final long token = Binder.clearCallingIdentity();
+ try {
+ disconnectWifiDisplayInternal();
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ }
+
+ @Override // Binder call
+ public void renameWifiDisplay(String address, String alias) {
+ if (address == null) {
+ throw new IllegalArgumentException("address must not be null");
+ }
+ mContext.enforceCallingOrSelfPermission(Manifest.permission.CONFIGURE_WIFI_DISPLAY,
+ "Permission required to rename to a wifi display");
+
+ final long token = Binder.clearCallingIdentity();
+ try {
+ renameWifiDisplayInternal(address, alias);
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ }
+
+ @Override // Binder call
+ public void forgetWifiDisplay(String address) {
+ if (address == null) {
+ throw new IllegalArgumentException("address must not be null");
+ }
+ mContext.enforceCallingOrSelfPermission(Manifest.permission.CONFIGURE_WIFI_DISPLAY,
+ "Permission required to forget to a wifi display");
+
+ final long token = Binder.clearCallingIdentity();
+ try {
+ forgetWifiDisplayInternal(address);
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ }
+
+ @Override // Binder call
+ public void pauseWifiDisplay() {
+ mContext.enforceCallingOrSelfPermission(Manifest.permission.CONFIGURE_WIFI_DISPLAY,
+ "Permission required to pause a wifi display session");
+
+ final long token = Binder.clearCallingIdentity();
+ try {
+ pauseWifiDisplayInternal();
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ }
+
+ @Override // Binder call
+ public void resumeWifiDisplay() {
+ mContext.enforceCallingOrSelfPermission(Manifest.permission.CONFIGURE_WIFI_DISPLAY,
+ "Permission required to resume a wifi display session");
+
+ final long token = Binder.clearCallingIdentity();
+ try {
+ resumeWifiDisplayInternal();
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ }
+
+ @Override // Binder call
+ public WifiDisplayStatus getWifiDisplayStatus() {
+ // This request does not require special permissions.
+ // Any app can get information about available wifi displays.
+
+ final long token = Binder.clearCallingIdentity();
+ try {
+ return getWifiDisplayStatusInternal();
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ }
+
+ @Override // Binder call
+ public int createVirtualDisplay(IBinder appToken, String packageName,
+ String name, int width, int height, int densityDpi, Surface surface, int flags) {
+ final int callingUid = Binder.getCallingUid();
+ if (!validatePackageName(callingUid, packageName)) {
+ throw new SecurityException("packageName must match the calling uid");
+ }
+ if (appToken == null) {
+ throw new IllegalArgumentException("appToken must not be null");
+ }
+ if (TextUtils.isEmpty(name)) {
+ throw new IllegalArgumentException("name must be non-null and non-empty");
+ }
+ if (width <= 0 || height <= 0 || densityDpi <= 0) {
+ throw new IllegalArgumentException("width, height, and densityDpi must be "
+ + "greater than 0");
+ }
+ if (surface == null) {
+ throw new IllegalArgumentException("surface must not be null");
+ }
+ if (callingUid != Process.SYSTEM_UID &&
+ (flags & DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC) != 0) {
+ if (mContext.checkCallingPermission(android.Manifest.permission.CAPTURE_VIDEO_OUTPUT)
+ != PackageManager.PERMISSION_GRANTED
+ && mContext.checkCallingPermission(
+ android.Manifest.permission.CAPTURE_SECURE_VIDEO_OUTPUT)
+ != PackageManager.PERMISSION_GRANTED) {
+ throw new SecurityException("Requires CAPTURE_VIDEO_OUTPUT or "
+ + "CAPTURE_SECURE_VIDEO_OUTPUT permission to create a "
+ + "public virtual display.");
+ }
+ }
+ if ((flags & DisplayManager.VIRTUAL_DISPLAY_FLAG_SECURE) != 0) {
+ if (mContext.checkCallingPermission(
+ android.Manifest.permission.CAPTURE_SECURE_VIDEO_OUTPUT)
+ != PackageManager.PERMISSION_GRANTED) {
+ throw new SecurityException("Requires CAPTURE_SECURE_VIDEO_OUTPUT "
+ + "to create a secure virtual display.");
+ }
+ }
+
+ final long token = Binder.clearCallingIdentity();
+ try {
+ return createVirtualDisplayInternal(appToken, callingUid, packageName,
+ name, width, height, densityDpi, surface, flags);
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ }
+
+ @Override // Binder call
+ public void releaseVirtualDisplay(IBinder appToken) {
+ final long token = Binder.clearCallingIdentity();
+ try {
+ releaseVirtualDisplayInternal(appToken);
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ }
+
+ @Override // Binder call
+ public void dump(FileDescriptor fd, final PrintWriter pw, String[] args) {
+ if (mContext == null
+ || mContext.checkCallingOrSelfPermission(Manifest.permission.DUMP)
+ != PackageManager.PERMISSION_GRANTED) {
+ pw.println("Permission Denial: can't dump DisplayManager from from pid="
+ + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid());
+ return;
+ }
+
+ final long token = Binder.clearCallingIdentity();
+ try {
+ dumpInternal(pw);
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ }
+
+ private boolean validatePackageName(int uid, String packageName) {
+ if (packageName != null) {
+ String[] packageNames = mContext.getPackageManager().getPackagesForUid(uid);
+ if (packageNames != null) {
+ for (String n : packageNames) {
+ if (n.equals(packageName)) {
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+ }
+ }
+
+ private final class LocalService extends DisplayManagerInternal {
+ @Override
+ public void blankAllDisplaysFromPowerManager() {
+ blankAllDisplaysFromPowerManagerInternal();
+ }
+
+ @Override
+ public void unblankAllDisplaysFromPowerManager() {
+ unblankAllDisplaysFromPowerManagerInternal();
+ }
+
+ @Override
+ public DisplayInfo getDisplayInfo(int displayId) {
+ return getDisplayInfoInternal(displayId, Process.myUid());
+ }
+
+ @Override
+ public void registerDisplayTransactionListener(DisplayTransactionListener listener) {
+ if (listener == null) {
+ throw new IllegalArgumentException("listener must not be null");
+ }
+
+ registerDisplayTransactionListenerInternal(listener);
+ }
+
+ @Override
+ public void unregisterDisplayTransactionListener(DisplayTransactionListener listener) {
+ if (listener == null) {
+ throw new IllegalArgumentException("listener must not be null");
+ }
+
+ unregisterDisplayTransactionListenerInternal(listener);
+ }
+
+ @Override
+ public void setDisplayInfoOverrideFromWindowManager(int displayId, DisplayInfo info) {
+ setDisplayInfoOverrideFromWindowManagerInternal(displayId, info);
+ }
+
+ @Override
+ public void performTraversalInTransactionFromWindowManager() {
+ performTraversalInTransactionFromWindowManagerInternal();
+ }
+
+ @Override
+ public void setDisplayHasContent(int displayId, boolean hasContent, boolean inTraversal) {
+ setDisplayHasContentInternal(displayId, hasContent, inTraversal);
+ }
+ }
}
diff --git a/services/core/java/com/android/server/display/DisplayTransactionListener.java b/services/core/java/com/android/server/display/DisplayTransactionListener.java
deleted file mode 100644
index 34eb8f9..0000000
--- a/services/core/java/com/android/server/display/DisplayTransactionListener.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (C) 2012 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.display;
-
-/**
- * Called within a Surface transaction whenever the size or orientation of a
- * display may have changed. Provides an opportunity for the client to
- * update the position of its surfaces as part of the same transaction.
- */
-public interface DisplayTransactionListener {
- void onDisplayTransaction();
-}
diff --git a/services/core/java/com/android/server/dreams/DreamManagerService.java b/services/core/java/com/android/server/dreams/DreamManagerService.java
index b6e7781..f5acc4c 100644
--- a/services/core/java/com/android/server/dreams/DreamManagerService.java
+++ b/services/core/java/com/android/server/dreams/DreamManagerService.java
@@ -17,6 +17,7 @@
package com.android.server.dreams;
import com.android.internal.util.DumpUtils;
+import com.android.server.FgThread;
import android.app.ActivityManager;
import android.content.BroadcastReceiver;
@@ -65,9 +66,9 @@
private int mCurrentDreamUserId;
private boolean mCurrentDreamIsTest;
- public DreamManagerService(Context context, Handler mainHandler) {
+ public DreamManagerService(Context context) {
mContext = context;
- mHandler = new DreamHandler(mainHandler.getLooper());
+ mHandler = new DreamHandler(FgThread.get().getLooper());
mController = new DreamController(context, mHandler, mControllerListener);
mPowerManager = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
diff --git a/services/core/java/com/android/server/input/InputManagerService.java b/services/core/java/com/android/server/input/InputManagerService.java
index 825a31d..1522fd1 100644
--- a/services/core/java/com/android/server/input/InputManagerService.java
+++ b/services/core/java/com/android/server/input/InputManagerService.java
@@ -18,9 +18,9 @@
import com.android.internal.R;
import com.android.internal.util.XmlUtils;
+import com.android.server.DisplayThread;
+import com.android.server.LocalServices;
import com.android.server.Watchdog;
-import com.android.server.display.DisplayManagerService;
-import com.android.server.display.DisplayViewport;
import org.xmlpull.v1.XmlPullParser;
@@ -44,10 +44,12 @@
import android.content.res.TypedArray;
import android.content.res.XmlResourceParser;
import android.database.ContentObserver;
+import android.hardware.display.DisplayViewport;
import android.hardware.input.IInputDevicesChangedListener;
import android.hardware.input.IInputManager;
import android.hardware.input.InputDeviceIdentifier;
import android.hardware.input.InputManager;
+import android.hardware.input.InputManagerInternal;
import android.hardware.input.KeyboardLayout;
import android.os.Binder;
import android.os.Bundle;
@@ -95,7 +97,7 @@
* Wraps the C++ InputManager and provides its callbacks.
*/
public class InputManagerService extends IInputManager.Stub
- implements Watchdog.Monitor, DisplayManagerService.InputManagerFuncs {
+ implements Watchdog.Monitor {
static final String TAG = "InputManager";
static final boolean DEBUG = false;
@@ -242,15 +244,17 @@
/** Whether to use the dev/input/event or uevent subsystem for the audio jack. */
final boolean mUseDevInputEventForAudioJack;
- public InputManagerService(Context context, Handler handler) {
+ public InputManagerService(Context context) {
this.mContext = context;
- this.mHandler = new InputManagerHandler(handler.getLooper());
+ this.mHandler = new InputManagerHandler(DisplayThread.get().getLooper());
mUseDevInputEventForAudioJack =
context.getResources().getBoolean(R.bool.config_useDevInputEventForAudioJack);
Slog.i(TAG, "Initializing input manager, mUseDevInputEventForAudioJack="
+ mUseDevInputEventForAudioJack);
mPtr = nativeInit(this, mContext, mHandler.getLooper().getQueue());
+
+ LocalServices.addService(InputManagerInternal.class, new LocalService());
}
public void setWindowManagerCallbacks(WindowManagerCallbacks callbacks) {
@@ -330,8 +334,7 @@
nativeReloadDeviceAliases(mPtr);
}
- @Override
- public void setDisplayViewports(DisplayViewport defaultViewport,
+ private void setDisplayViewportsInternal(DisplayViewport defaultViewport,
DisplayViewport externalTouchViewport) {
if (defaultViewport.valid) {
setDisplayViewport(false, defaultViewport);
@@ -1675,4 +1678,12 @@
onVibratorTokenDied(this);
}
}
+
+ private final class LocalService extends InputManagerInternal {
+ @Override
+ public void setDisplayViewports(
+ DisplayViewport defaultViewport, DisplayViewport externalTouchViewport) {
+ setDisplayViewportsInternal(defaultViewport, externalTouchViewport);
+ }
+ }
}
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index cda6a88..902e56a 100755
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -1126,7 +1126,8 @@
synchronized (mInstallLock) {
// writer
synchronized (mPackages) {
- mHandlerThread = new ServiceThread(TAG, Process.THREAD_PRIORITY_BACKGROUND);
+ mHandlerThread = new ServiceThread(TAG,
+ Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/);
mHandlerThread.start();
mHandler = new PackageHandler(mHandlerThread.getLooper());
Watchdog.getInstance().addThread(mHandler, WATCHDOG_TIMEOUT);
diff --git a/services/core/java/com/android/server/power/DisplayPowerController.java b/services/core/java/com/android/server/power/DisplayPowerController.java
index b8a78e3..f1be504 100644
--- a/services/core/java/com/android/server/power/DisplayPowerController.java
+++ b/services/core/java/com/android/server/power/DisplayPowerController.java
@@ -19,7 +19,6 @@
import com.android.server.lights.LightsManager;
import com.android.server.twilight.TwilightListener;
import com.android.server.twilight.TwilightManager;
-import com.android.server.display.DisplayManagerService;
import com.android.server.twilight.TwilightState;
import android.animation.Animator;
@@ -185,9 +184,6 @@
// The twilight service.
private final TwilightManager mTwilight;
- // The display manager.
- private final DisplayManagerService mDisplayManager;
-
// The sensor manager.
private final SensorManager mSensorManager;
@@ -353,7 +349,6 @@
*/
public DisplayPowerController(Looper looper, Context context, Notifier notifier,
LightsManager lights, TwilightManager twilight, SensorManager sensorManager,
- DisplayManagerService displayManager,
SuspendBlocker displaySuspendBlocker, DisplayBlanker displayBlanker,
Callbacks callbacks, Handler callbackHandler) {
mHandler = new DisplayControllerHandler(looper);
@@ -366,7 +361,6 @@
mLights = lights;
mTwilight = twilight;
mSensorManager = sensorManager;
- mDisplayManager = displayManager;
final Resources resources = context.getResources();
@@ -527,8 +521,7 @@
}
private void initialize() {
- mPowerState = new DisplayPowerState(
- new ElectronBeam(mDisplayManager), mDisplayBlanker,
+ mPowerState = new DisplayPowerState(new ElectronBeam(), mDisplayBlanker,
mLights.getLight(LightsManager.LIGHT_ID_BACKLIGHT));
mElectronBeamOnAnimator = ObjectAnimator.ofFloat(
diff --git a/services/core/java/com/android/server/power/ElectronBeam.java b/services/core/java/com/android/server/power/ElectronBeam.java
index 729bd16..64921d7 100644
--- a/services/core/java/com/android/server/power/ElectronBeam.java
+++ b/services/core/java/com/android/server/power/ElectronBeam.java
@@ -23,6 +23,8 @@
import android.graphics.PixelFormat;
import android.graphics.SurfaceTexture;
+import android.hardware.display.DisplayManagerInternal;
+import android.hardware.display.DisplayManagerInternal.DisplayTransactionListener;
import android.opengl.EGL14;
import android.opengl.EGLConfig;
import android.opengl.EGLContext;
@@ -40,8 +42,7 @@
import android.view.SurfaceControl;
import android.view.SurfaceSession;
-import com.android.server.display.DisplayManagerService;
-import com.android.server.display.DisplayTransactionListener;
+import com.android.server.LocalServices;
/**
* Bzzzoooop! *crackle*
@@ -77,7 +78,7 @@
private boolean mPrepared;
private int mMode;
- private final DisplayManagerService mDisplayManager;
+ private final DisplayManagerInternal mDisplayManagerInternal;
private int mDisplayLayerStack; // layer stack associated with primary display
private int mDisplayWidth; // real width, not rotated
private int mDisplayHeight; // real height, not rotated
@@ -118,8 +119,8 @@
public static final int MODE_FADE = 2;
- public ElectronBeam(DisplayManagerService displayManager) {
- mDisplayManager = displayManager;
+ public ElectronBeam() {
+ mDisplayManagerInternal = LocalServices.getService(DisplayManagerInternal.class);
}
/**
@@ -138,7 +139,7 @@
// Get the display size and layer stack.
// This is not expected to change while the electron beam surface is showing.
- DisplayInfo displayInfo = mDisplayManager.getDisplayInfo(Display.DEFAULT_DISPLAY);
+ DisplayInfo displayInfo = mDisplayManagerInternal.getDisplayInfo(Display.DEFAULT_DISPLAY);
mDisplayLayerStack = displayInfo.layerStack;
mDisplayWidth = displayInfo.getNaturalWidth();
mDisplayHeight = displayInfo.getNaturalHeight();
@@ -527,7 +528,7 @@
mSurface = new Surface();
mSurface.copyFrom(mSurfaceControl);
- mSurfaceLayout = new NaturalSurfaceLayout(mDisplayManager, mSurfaceControl);
+ mSurfaceLayout = new NaturalSurfaceLayout(mDisplayManagerInternal, mSurfaceControl);
mSurfaceLayout.onDisplayTransaction();
} finally {
SurfaceControl.closeTransaction();
@@ -685,20 +686,21 @@
* owns the electron beam.
*/
private static final class NaturalSurfaceLayout implements DisplayTransactionListener {
- private final DisplayManagerService mDisplayManager;
+ private final DisplayManagerInternal mDisplayManagerInternal;
private SurfaceControl mSurfaceControl;
- public NaturalSurfaceLayout(DisplayManagerService displayManager, SurfaceControl surfaceControl) {
- mDisplayManager = displayManager;
+ public NaturalSurfaceLayout(DisplayManagerInternal displayManagerInternal,
+ SurfaceControl surfaceControl) {
+ mDisplayManagerInternal = displayManagerInternal;
mSurfaceControl = surfaceControl;
- mDisplayManager.registerDisplayTransactionListener(this);
+ mDisplayManagerInternal.registerDisplayTransactionListener(this);
}
public void dispose() {
synchronized (this) {
mSurfaceControl = null;
}
- mDisplayManager.unregisterDisplayTransactionListener(this);
+ mDisplayManagerInternal.unregisterDisplayTransactionListener(this);
}
@Override
@@ -708,7 +710,8 @@
return;
}
- DisplayInfo displayInfo = mDisplayManager.getDisplayInfo(Display.DEFAULT_DISPLAY);
+ DisplayInfo displayInfo =
+ mDisplayManagerInternal.getDisplayInfo(Display.DEFAULT_DISPLAY);
switch (displayInfo.rotation) {
case Surface.ROTATION_0:
mSurfaceControl.setPosition(0, 0);
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index 3692d76..b9ecde1 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -21,12 +21,10 @@
import com.android.server.BatteryService;
import com.android.server.EventLogTags;
import com.android.server.ServiceThread;
-import com.android.server.lights.LightsService;
import com.android.server.lights.Light;
import com.android.server.lights.LightsManager;
import com.android.server.twilight.TwilightManager;
import com.android.server.Watchdog;
-import com.android.server.display.DisplayManagerService;
import com.android.server.dreams.DreamManagerService;
import android.Manifest;
@@ -40,11 +38,11 @@
import android.database.ContentObserver;
import android.hardware.SensorManager;
import android.hardware.SystemSensorManager;
+import android.hardware.display.DisplayManagerInternal;
import android.net.Uri;
import android.os.BatteryManager;
import android.os.Binder;
import android.os.Handler;
-import android.os.HandlerThread;
import android.os.IBinder;
import android.os.IPowerManager;
import android.os.Looper;
@@ -173,7 +171,7 @@
private Context mContext;
private LightsManager mLightsManager;
private BatteryService mBatteryService;
- private DisplayManagerService mDisplayManagerService;
+ private DisplayManagerInternal mDisplayManagerInternal;
private IBatteryStats mBatteryStats;
private IAppOpsService mAppOps;
private ServiceThread mHandlerThread;
@@ -409,13 +407,14 @@
*/
public void init(LightsManager ls,
BatteryService bs, IBatteryStats bss,
- IAppOpsService appOps, DisplayManagerService dm) {
+ IAppOpsService appOps) {
mLightsManager = ls;
mBatteryService = bs;
mBatteryStats = bss;
mAppOps = appOps;
- mDisplayManagerService = dm;
- mHandlerThread = new ServiceThread(TAG, Process.THREAD_PRIORITY_DISPLAY);
+ mDisplayManagerInternal = getLocalService(DisplayManagerInternal.class);
+ mHandlerThread = new ServiceThread(TAG,
+ Process.THREAD_PRIORITY_DISPLAY, false /*allowIo*/);
mHandlerThread.start();
mHandler = new PowerManagerHandler(mHandlerThread.getLooper());
@@ -459,7 +458,7 @@
// own handler thread to ensure timely operation.
mDisplayPowerController = new DisplayPowerController(mHandler.getLooper(),
mContext, mNotifier, mLightsManager, twilight, sensorManager,
- mDisplayManagerService, mDisplaySuspendBlocker, mDisplayBlanker,
+ mDisplaySuspendBlocker, mDisplayBlanker,
mDisplayPowerControllerCallbacks, mHandler);
mWirelessChargerDetector = new WirelessChargerDetector(sensorManager,
@@ -2312,7 +2311,7 @@
public void blankAllDisplays() {
synchronized (this) {
mBlanked = true;
- mDisplayManagerService.blankAllDisplaysFromPowerManager();
+ mDisplayManagerInternal.blankAllDisplaysFromPowerManager();
nativeSetInteractive(false);
nativeSetAutoSuspend(true);
}
@@ -2323,7 +2322,7 @@
synchronized (this) {
nativeSetAutoSuspend(false);
nativeSetInteractive(true);
- mDisplayManagerService.unblankAllDisplaysFromPowerManager();
+ mDisplayManagerInternal.unblankAllDisplaysFromPowerManager();
mBlanked = false;
}
}
@@ -2713,7 +2712,7 @@
}
}
- private final class LocalService implements PowerManagerInternal {
+ private final class LocalService extends PowerManagerInternal {
/**
* Used by the window manager to override the screen brightness based on the
* current foreground activity.
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index a45ed49..6c7fb26 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -33,15 +33,13 @@
import com.android.internal.view.IInputMethodManager;
import com.android.internal.view.WindowManagerPolicyThread;
import com.android.server.AttributeCache;
+import com.android.server.DisplayThread;
import com.android.server.EventLogTags;
import com.android.server.LocalServices;
-import com.android.server.SystemService;
import com.android.server.UiThread;
import com.android.server.Watchdog;
import com.android.server.am.BatteryStatsService;
-import com.android.server.display.DisplayManagerService;
import com.android.server.input.InputManagerService;
-import com.android.server.power.PowerManagerService;
import com.android.server.power.ShutdownThread;
import android.Manifest;
@@ -68,6 +66,7 @@
import android.graphics.RectF;
import android.graphics.Region;
import android.hardware.display.DisplayManager;
+import android.hardware.display.DisplayManagerInternal;
import android.os.Binder;
import android.os.Bundle;
import android.os.Debug;
@@ -117,6 +116,7 @@
import android.view.KeyEvent;
import android.view.MagnificationSpec;
import android.view.MotionEvent;
+import android.view.WindowManagerInternal;
import android.view.Surface.OutOfResourcesException;
import android.view.Surface;
import android.view.SurfaceControl;
@@ -156,7 +156,7 @@
/** {@hide} */
public class WindowManagerService extends IWindowManager.Stub
implements Watchdog.Monitor, WindowManagerPolicy.WindowManagerFuncs,
- DisplayManagerService.WindowManagerFuncs, DisplayManager.DisplayListener {
+ DisplayManager.DisplayListener {
static final String TAG = "WindowManager";
static final boolean DEBUG = false;
static final boolean DEBUG_ADD_REMOVE = false;
@@ -544,7 +544,7 @@
float mAnimatorDurationScale = 1.0f;
final InputManagerService mInputManager;
- final DisplayManagerService mDisplayManagerService;
+ final DisplayManagerInternal mDisplayManagerInternal;
final DisplayManager mDisplayManager;
// Who is holding the screen on.
@@ -697,23 +697,22 @@
final boolean mOnlyCore;
public static WindowManagerService main(final Context context,
- final DisplayManagerService dm,
- final InputManagerService im, final Handler wmHandler,
+ final InputManagerService im,
final boolean haveInputMethods, final boolean showBootMsgs,
final boolean onlyCore) {
final WindowManagerService[] holder = new WindowManagerService[1];
- wmHandler.runWithScissors(new Runnable() {
+ DisplayThread.getHandler().runWithScissors(new Runnable() {
@Override
public void run() {
- holder[0] = new WindowManagerService(context, dm, im,
+ holder[0] = new WindowManagerService(context, im,
haveInputMethods, showBootMsgs, onlyCore);
}
}, 0);
return holder[0];
}
- private void initPolicy(Handler uiHandler) {
- uiHandler.runWithScissors(new Runnable() {
+ private void initPolicy() {
+ UiThread.getHandler().runWithScissors(new Runnable() {
@Override
public void run() {
WindowManagerPolicyThread.set(Thread.currentThread(), Looper.myLooper());
@@ -726,8 +725,7 @@
}, 0);
}
- private WindowManagerService(Context context,
- DisplayManagerService displayManager, InputManagerService inputManager,
+ private WindowManagerService(Context context, InputManagerService inputManager,
boolean haveInputMethods, boolean showBootMsgs, boolean onlyCore) {
mContext = context;
mHaveInputMethods = haveInputMethods;
@@ -736,7 +734,7 @@
mLimitedAlphaCompositing = context.getResources().getBoolean(
com.android.internal.R.bool.config_sf_limitedAlpha);
mInputManager = inputManager; // Must be before createDisplayContentLocked.
- mDisplayManagerService = displayManager;
+ mDisplayManagerInternal = LocalServices.getService(DisplayManagerInternal.class);
mDisplaySettings = new DisplaySettings(context);
mDisplaySettings.readSettingsLocked();
@@ -792,7 +790,7 @@
mAnimator = new WindowAnimator(this);
- initPolicy(UiThread.getHandler());
+ initPolicy();
// Add ourself to the Watchdog monitors.
Watchdog.getInstance().addMonitor(this);
@@ -805,6 +803,8 @@
} finally {
SurfaceControl.closeTransaction();
}
+
+ LocalServices.addService(WindowManagerInternal.class, new LocalService());
}
public InputMonitor getInputMonitor() {
@@ -5917,7 +5917,7 @@
}
}
- mDisplayManagerService.performTraversalInTransactionFromWindowManager();
+ mDisplayManagerInternal.performTraversalInTransactionFromWindowManager();
} finally {
if (!inTransaction) {
SurfaceControl.closeTransaction();
@@ -6617,7 +6617,7 @@
displayInfo.getLogicalMetrics(mRealDisplayMetrics,
CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null);
displayInfo.getAppMetrics(mDisplayMetrics);
- mDisplayManagerService.setDisplayInfoOverrideFromWindowManager(
+ mDisplayManagerInternal.setDisplayInfoOverrideFromWindowManager(
displayContent.getDisplayId(), displayInfo);
}
if (false) {
@@ -6950,7 +6950,7 @@
synchronized(displayContent.mDisplaySizeLock) {
// Bootstrap the default logical display from the display manager.
final DisplayInfo displayInfo = displayContent.getDisplayInfo();
- DisplayInfo newDisplayInfo = mDisplayManagerService.getDisplayInfo(displayId);
+ DisplayInfo newDisplayInfo = mDisplayManagerInternal.getDisplayInfo(displayId);
if (newDisplayInfo != null) {
displayInfo.copyFrom(newDisplayInfo);
}
@@ -9106,7 +9106,7 @@
updateResizingWindows(w);
}
- mDisplayManagerService.setDisplayHasContent(displayId,
+ mDisplayManagerInternal.setDisplayHasContent(displayId,
mInnerFields.mDisplayHasContent,
true /* inTraversal, must call performTraversalInTrans... below */);
@@ -9123,7 +9123,7 @@
// Give the display manager a chance to adjust properties
// like display rotation if it needs to.
- mDisplayManagerService.performTraversalInTransactionFromWindowManager();
+ mDisplayManagerInternal.performTraversalInTransactionFromWindowManager();
} catch (RuntimeException e) {
Log.wtf(TAG, "Unhandled exception in Window Manager", e);
@@ -9492,8 +9492,7 @@
}
}
- @Override
- public void requestTraversal() {
+ void requestTraversal() {
synchronized (mWindowMap) {
requestTraversalLocked();
}
@@ -10696,7 +10695,7 @@
displayInfo.overscanTop = rect.top;
displayInfo.overscanRight = rect.right;
displayInfo.overscanBottom = rect.bottom;
- mDisplayManagerService.setDisplayInfoOverrideFromWindowManager(
+ mDisplayManagerInternal.setDisplayInfoOverrideFromWindowManager(
displayId, displayInfo);
}
configureDisplayPolicyLocked(displayContent);
@@ -10819,4 +10818,11 @@
public Object getWindowManagerLock() {
return mWindowMap;
}
+
+ private final class LocalService extends WindowManagerInternal {
+ @Override
+ public void requestTraversalFromDisplayManager() {
+ requestTraversal();
+ }
+ }
}