diff options
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(); + } + } } |