diff options
author | Jeff Brown <jeffbrown@google.com> | 2014-01-16 22:16:42 -0800 |
---|---|---|
committer | Jeff Brown <jeffbrown@google.com> | 2014-01-16 22:16:42 -0800 |
commit | 4ccb823a9f62e57f9d221f83a97e82967e79a9e5 (patch) | |
tree | 2c21ff973f7f41f4baabf9531404b87c8af1966a | |
parent | 6f357d3284a833cc50a990e14b39f389b8972254 (diff) | |
download | frameworks_base-4ccb823a9f62e57f9d221f83a97e82967e79a9e5.zip frameworks_base-4ccb823a9f62e57f9d221f83a97e82967e79a9e5.tar.gz frameworks_base-4ccb823a9f62e57f9d221f83a97e82967e79a9e5.tar.bz2 |
Refactor display manager service to new pattern.
Transform DisplayManagerService into a SystemService and start cleaning
up other local services that it uses from window manager and input manager.
Clean up service thread initialization.
Remove unnecessary static variables from ActivityManagerService.
It's starting to become clear that we really need a better way to manage
service dependencies. Boot phases don't quite cut it.
Change-Id: If319dbd7cbfbd4812fe55ece969e818d4b20755b
25 files changed, 880 insertions, 628 deletions
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 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 @@ import android.graphics.Rect; * 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 @@ import android.view.WindowManagerPolicy; * * @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 @@ public interface PowerManagerInternal { * * @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 @@ public interface PowerManagerInternal { * * @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 @@ public interface PowerManagerInternal { * * @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/services/core/java/com/android/server/display/DisplayTransactionListener.java b/core/java/android/view/WindowManagerInternal.java index 34eb8f9..a1bd4bd 100644 --- a/services/core/java/com/android/server/display/DisplayTransactionListener.java +++ b/core/java/android/view/WindowManagerInternal.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012 The Android Open Source Project + * 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. @@ -14,13 +14,20 @@ * limitations under the License. */ -package com.android.server.display; +package android.view; + +import android.hardware.display.DisplayManagerInternal; /** - * 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. + * Window manager local system service interface. + * + * @hide Only for use within the system server. */ -public interface DisplayTransactionListener { - void onDisplayTransaction(); -} +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 @@ public abstract class SystemService { /* * 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 @@ public abstract class SystemService { * 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 @@ import android.os.HandlerThread; * 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 @@ public final class FgThread extends HandlerThread { 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 @@ public final class IoThread extends HandlerThread { 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 @@ import android.util.Slog; /** * 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 @@ public final class ServiceThread extends HandlerThread { 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 c66a849..6a76388 100644 --- a/services/core/java/com/android/server/SystemServer.java +++ b/services/core/java/com/android/server/SystemServer.java @@ -121,8 +121,11 @@ public final class SystemServer { 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; /** @@ -213,6 +216,7 @@ public final class SystemServer { // Start services. try { startBootstrapServices(); + startCoreServices(); startOtherServices(); } catch (RuntimeException ex) { Slog.e("System", "******************************************"); @@ -271,22 +275,21 @@ public final class SystemServer { mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class); // Activity manager runs the show. - mSystemServiceManager.startService(ActivityManagerService.Lifecycle.class); + mActivityManagerService = mSystemServiceManager.startService( + ActivityManagerService.Lifecycle.class).getService(); } - 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); + private void startCoreServices() { + // Display manager is needed to provide display metrics before package manager + // starts up. + mDisplayManagerService = mSystemServiceManager.startService(DisplayManagerService.class); + } + private void startOtherServices() { 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; @@ -324,10 +327,6 @@ public final class SystemServer { 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); @@ -337,10 +336,8 @@ public final class SystemServer { 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. @@ -361,7 +358,7 @@ public final class SystemServer { } catch (RemoteException e) { } - ActivityManagerService.setSystemProcess(); + mActivityManagerService.setSystemProcess(); Slog.i(TAG, "Entropy Mixer"); ServiceManager.addService("entropy", new EntropyMixer(context)); @@ -387,7 +384,7 @@ public final class SystemServer { 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); @@ -405,7 +402,7 @@ public final class SystemServer { // 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); @@ -417,26 +414,25 @@ public final class SystemServer { 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 @@ -599,7 +595,7 @@ public final class SystemServer { 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); @@ -864,7 +860,7 @@ public final class SystemServer { 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); @@ -910,7 +906,7 @@ public final class SystemServer { // 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 @@ -948,7 +944,7 @@ public final class SystemServer { } if (safeMode) { - ActivityManagerService.self().showSafeModeOverlay(); + mActivityManagerService.showSafeModeOverlay(); } // Update the configuration for this context by hand, because we're going @@ -974,7 +970,8 @@ public final class SystemServer { } 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); } @@ -1009,12 +1006,12 @@ public final class SystemServer { // 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 @@ public final class UiThread extends HandlerThread { 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 @@ public class Watchdog extends Thread { // 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 75ea853..9ea242c 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 @@ public final class ActivityManagerService extends ActivityManagerNative WindowManagerService mWindowManager; - static ActivityManagerService sSelf; - static ActivityThread sSystemThread; + final ActivityThread mSystemThread; int mCurrentUserId = 0; private UserManagerService mUserManager; @@ -1735,38 +1734,34 @@ public final class ActivityManagerService extends ActivityManagerNative } }; - 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 final class ActivityManagerService extends ActivityManagerNative } 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 final class ActivityManagerService extends ActivityManagerNative 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 @@ public final class ActivityManagerService extends ActivityManagerNative // 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 final class ActivityManagerService extends ActivityManagerNative } } - 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 @@ public final class ActivityManagerService extends ActivityManagerNative } } if (providers != null) { - sSystemThread.installSystemProviders(providers); + mSystemThread.installSystemProviders(providers); } - sSelf.mCoreSettingsObserver = new CoreSettingsObserver(sSelf); + mCoreSettingsObserver = new CoreSettingsObserver(this); - sSelf.mUsageStatsService.monitorPackages(); + mUsageStatsService.monitorPackages(); } /** @@ -13996,7 +13990,7 @@ public final class ActivityManagerService extends ActivityManagerNative // 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 @@ final class NativeCrashListener extends Thread { * 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.Context; 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.util.SparseArray; 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 @@ import java.util.concurrent.CopyOnWriteArrayList; * 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 @@ public final class DisplayManagerService extends IDisplayManager.Stub { 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 @@ public final class DisplayManagerService extends IDisplayManager.Stub { 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); + } + + @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()); } - /** - * 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 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) { - synchronized (mSyncRoot) { - mWindowManagerFuncs = windowManagerFuncs; - scheduleTraversalLocked(false); - } - } - - /** - * Called during initialization to associate the display manager with the - * input manager. - */ - public void setInputManager(InputManagerFuncs inputManagerFuncs) { + // TODO: Use dependencies or a boot phase + public void windowManagerAndInputReady() { synchronized (mSyncRoot) { - mInputManagerFuncs = inputManagerFuncs; + mWindowManagerInternal = LocalServices.getService(WindowManagerInternal.class); + mInputManagerInternal = LocalServices.getService(InputManagerInternal.class); scheduleTraversalLocked(false); } } @@ -266,50 +273,19 @@ public final class DisplayManagerService extends IDisplayManager.Stub { 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 @@ public final class DisplayManagerService extends IDisplayManager.Stub { } } - /** - * 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 @@ public final class DisplayManagerService extends IDisplayManager.Stub { } } - /** - * 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 @@ public final class DisplayManagerService extends IDisplayManager.Stub { } } - /** - * 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 @@ public final class DisplayManagerService 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 { - synchronized (mSyncRoot) { - LogicalDisplay display = mLogicalDisplays.get(displayId); - if (display != null) { - DisplayInfo info = display.getDisplayInfoLocked(); - if (info.hasAccess(callingUid)) { - return info; - } + private DisplayInfo getDisplayInfoInternal(int displayId, int callingUid) { + 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); + return null; } } - /** - * 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); + 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); } - return displayIds; } - } finally { - Binder.restoreCallingIdentity(token); + if (n != count) { + displayIds = Arrays.copyOfRange(displayIds, 0, n); + } + return displayIds; } } - @Override // Binder call - public void registerCallback(IDisplayManagerCallback callback) { - if (callback == null) { - throw new IllegalArgumentException("listener must not be null"); - } - + private void registerCallbackInternal(IDisplayManagerCallback callback, int callingPid) { synchronized (mSyncRoot) { - int callingPid = Binder.getCallingPid(); if (mCallbacks.get(callingPid) != null) { throw new SecurityException("The calling process has already " + "registered an IDisplayManagerCallback."); @@ -457,24 +393,14 @@ public final class DisplayManagerService extends IDisplayManager.Stub { } } - @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 @@ public final class DisplayManagerService extends IDisplayManager.Stub { } } - @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 @@ public final class DisplayManagerService extends IDisplayManager.Stub { } } - @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."); - } - } - 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."); + 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; } - } - - 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(); - } + DisplayDevice device = mVirtualDisplayAdapter.createVirtualDisplayLocked( + appToken, callingUid, packageName, name, width, height, densityDpi, + surface, flags); + if (device == null) { + return -1; + } - // 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 @@ public final class DisplayManagerService extends IDisplayManager.Stub { } // 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 @@ public final class DisplayManagerService extends IDisplayManager.Stub { // 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 @@ public final class DisplayManagerService extends IDisplayManager.Stub { 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 final class DisplayManagerService extends IDisplayManager.Stub { 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 @@ public final class DisplayManagerService extends IDisplayManager.Stub { break; case MSG_REQUEST_TRAVERSAL: - mWindowManagerFuncs.requestTraversal(); + mWindowManagerInternal.requestTraversalFromDisplayManager(); break; case MSG_UPDATE_VIEWPORT: { @@ -1248,7 +980,7 @@ public final class DisplayManagerService extends IDisplayManager.Stub { mTempDefaultViewport.copyFrom(mDefaultViewport); mTempExternalTouchViewport.copyFrom(mExternalTouchViewport); } - mInputManagerFuncs.setDisplayViewports( + mInputManagerInternal.setDisplayViewports( mTempDefaultViewport, mTempExternalTouchViewport); break; } @@ -1311,4 +1043,325 @@ public final class DisplayManagerService extends IDisplayManager.Stub { } } } + + 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/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 @@ public final class DreamManagerService extends IDreamManager.Stub { 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 9178664..fa18149 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 @@ package com.android.server.input; 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,9 +44,11 @@ import android.content.res.Resources.NotFoundException; 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.InputManager; +import android.hardware.input.InputManagerInternal; import android.hardware.input.KeyboardLayout; import android.os.Binder; import android.os.Bundle; @@ -94,7 +96,7 @@ import libcore.util.Objects; * 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; @@ -241,15 +243,17 @@ public class InputManagerService extends IInputManager.Stub /** 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) { @@ -329,8 +333,7 @@ public class InputManagerService extends IInputManager.Stub nativeReloadDeviceAliases(mPtr); } - @Override - public void setDisplayViewports(DisplayViewport defaultViewport, + private void setDisplayViewportsInternal(DisplayViewport defaultViewport, DisplayViewport externalTouchViewport) { if (defaultViewport.valid) { setDisplayViewport(false, defaultViewport); @@ -1639,4 +1642,12 @@ public class InputManagerService extends IInputManager.Stub 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 eccc3cf..209a4b4 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 @@ public class PackageManagerService extends IPackageManager.Stub { 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 @@ package com.android.server.power; 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 @@ final class DisplayPowerController { // 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 @@ final class DisplayPowerController { */ 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 @@ final class DisplayPowerController { mLights = lights; mTwilight = twilight; mSensorManager = sensorManager; - mDisplayManager = displayManager; final Resources resources = context.getResources(); @@ -527,8 +521,7 @@ final class DisplayPowerController { } 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 java.nio.FloatBuffer; 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.Surface; 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 @@ final class ElectronBeam { 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 @@ final class ElectronBeam { public static final int MODE_FADE = 2; - public ElectronBeam(DisplayManagerService displayManager) { - mDisplayManager = displayManager; + public ElectronBeam() { + mDisplayManagerInternal = LocalServices.getService(DisplayManagerInternal.class); } /** @@ -138,7 +139,7 @@ final class ElectronBeam { // 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 @@ final class ElectronBeam { 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 @@ final class ElectronBeam { * 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 @@ final class ElectronBeam { 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 7f03cc0..94876bb 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.internal.app.IBatteryStats; 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.content.res.Resources; 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 @@ public final class PowerManagerService extends com.android.server.SystemService 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 final class PowerManagerService extends com.android.server.SystemService */ 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 @@ public final class PowerManagerService extends com.android.server.SystemService // 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, @@ -2296,7 +2295,7 @@ public final class PowerManagerService extends com.android.server.SystemService public void blankAllDisplays() { synchronized (this) { mBlanked = true; - mDisplayManagerService.blankAllDisplaysFromPowerManager(); + mDisplayManagerInternal.blankAllDisplaysFromPowerManager(); nativeSetInteractive(false); nativeSetAutoSuspend(true); } @@ -2307,7 +2306,7 @@ public final class PowerManagerService extends com.android.server.SystemService synchronized (this) { nativeSetAutoSuspend(false); nativeSetInteractive(true); - mDisplayManagerService.unblankAllDisplaysFromPowerManager(); + mDisplayManagerInternal.unblankAllDisplaysFromPowerManager(); mBlanked = false; } } @@ -2694,7 +2693,7 @@ public final class PowerManagerService extends com.android.server.SystemService } } - 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 f77f183..59134f9 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.IInputMethodClient; 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.Rect; 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.InputEventReceiver; 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 @@ import java.util.List; /** {@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; @@ -540,7 +540,7 @@ public class WindowManagerService extends IWindowManager.Stub float mAnimatorDurationScale = 1.0f; final InputManagerService mInputManager; - final DisplayManagerService mDisplayManagerService; + final DisplayManagerInternal mDisplayManagerInternal; final DisplayManager mDisplayManager; // Who is holding the screen on. @@ -693,23 +693,22 @@ public class WindowManagerService extends IWindowManager.Stub 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()); @@ -722,8 +721,7 @@ public class WindowManagerService extends IWindowManager.Stub }, 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; @@ -732,7 +730,7 @@ public class WindowManagerService extends IWindowManager.Stub 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(); @@ -788,7 +786,7 @@ public class WindowManagerService extends IWindowManager.Stub mAnimator = new WindowAnimator(this); - initPolicy(UiThread.getHandler()); + initPolicy(); // Add ourself to the Watchdog monitors. Watchdog.getInstance().addMonitor(this); @@ -801,6 +799,8 @@ public class WindowManagerService extends IWindowManager.Stub } finally { SurfaceControl.closeTransaction(); } + + LocalServices.addService(WindowManagerInternal.class, new LocalService()); } public InputMonitor getInputMonitor() { @@ -5919,7 +5919,7 @@ public class WindowManagerService extends IWindowManager.Stub } } - mDisplayManagerService.performTraversalInTransactionFromWindowManager(); + mDisplayManagerInternal.performTraversalInTransactionFromWindowManager(); } finally { if (!inTransaction) { SurfaceControl.closeTransaction(); @@ -6613,7 +6613,7 @@ public class WindowManagerService extends IWindowManager.Stub displayInfo.getLogicalMetrics(mRealDisplayMetrics, CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null); displayInfo.getAppMetrics(mDisplayMetrics); - mDisplayManagerService.setDisplayInfoOverrideFromWindowManager( + mDisplayManagerInternal.setDisplayInfoOverrideFromWindowManager( displayContent.getDisplayId(), displayInfo); } if (false) { @@ -6946,7 +6946,7 @@ public class WindowManagerService extends IWindowManager.Stub 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); } @@ -9108,7 +9108,7 @@ public class WindowManagerService extends IWindowManager.Stub updateResizingWindows(w); } - mDisplayManagerService.setDisplayHasContent(displayId, + mDisplayManagerInternal.setDisplayHasContent(displayId, mInnerFields.mDisplayHasContent, true /* inTraversal, must call performTraversalInTrans... below */); @@ -9125,7 +9125,7 @@ public class WindowManagerService extends IWindowManager.Stub // 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); @@ -9494,8 +9494,7 @@ public class WindowManagerService extends IWindowManager.Stub } } - @Override - public void requestTraversal() { + void requestTraversal() { synchronized (mWindowMap) { requestTraversalLocked(); } @@ -10692,7 +10691,7 @@ public class WindowManagerService extends IWindowManager.Stub displayInfo.overscanTop = rect.top; displayInfo.overscanRight = rect.right; displayInfo.overscanBottom = rect.bottom; - mDisplayManagerService.setDisplayInfoOverrideFromWindowManager( + mDisplayManagerInternal.setDisplayInfoOverrideFromWindowManager( displayId, displayInfo); } configureDisplayPolicyLocked(displayContent); @@ -10815,4 +10814,11 @@ public class WindowManagerService extends IWindowManager.Stub public Object getWindowManagerLock() { return mWindowMap; } + + private final class LocalService extends WindowManagerInternal { + @Override + public void requestTraversalFromDisplayManager() { + requestTraversal(); + } + } } |