Loading services/core/java/com/android/server/camera/CameraServiceProxy.java +126 −14 Original line number Diff line number Diff line Loading @@ -15,6 +15,7 @@ */ package com.android.server.camera; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.content.BroadcastReceiver; Loading @@ -39,6 +40,7 @@ import android.util.ArrayMap; import android.util.ArraySet; import android.util.Slog; import com.android.internal.annotations.GuardedBy; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.internal.util.FrameworkStatsLog; Loading @@ -48,6 +50,8 @@ import com.android.server.SystemService; import com.android.server.SystemService.TargetUser; import com.android.server.wm.WindowManagerInternal; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; Loading Loading @@ -79,10 +83,19 @@ public class CameraServiceProxy extends SystemService // Handler message codes private static final int MSG_SWITCH_USER = 1; private static final int MSG_NOTIFY_DEVICE_STATE = 2; private static final int RETRY_DELAY_TIME = 20; //ms private static final int RETRY_TIMES = 60; @IntDef(flag = true, prefix = { "DEVICE_STATE_" }, value = { ICameraService.DEVICE_STATE_BACK_COVERED, ICameraService.DEVICE_STATE_FRONT_COVERED, ICameraService.DEVICE_STATE_FOLDED }) @Retention(RetentionPolicy.SOURCE) @interface DeviceStateFlags {} // Maximum entries to keep in usage history before dumping out private static final int MAX_USAGE_HISTORY = 100; Loading @@ -94,6 +107,15 @@ public class CameraServiceProxy extends SystemService private final Object mLock = new Object(); private Set<Integer> mEnabledCameraUsers; private int mLastUser; // The current set of device state flags. May be different from mLastReportedDeviceState if the // native camera service has not been notified of the change. @GuardedBy("mLock") @DeviceStateFlags private int mDeviceState; // The most recent device state flags reported to the native camera server. @GuardedBy("mLock") @DeviceStateFlags private int mLastReportedDeviceState; private ICameraService mCameraServiceRaw; Loading Loading @@ -185,6 +207,7 @@ public class CameraServiceProxy extends SystemService return; } notifySwitchWithRetries(RETRY_TIMES); notifyDeviceStateWithRetries(RETRY_TIMES); } @Override Loading Loading @@ -218,12 +241,55 @@ public class CameraServiceProxy extends SystemService mLogWriterService.allowCoreThreadTimeOut(true); } /** * Sets the device state bits set within {@code deviceStateFlags} leaving all other bits the * same. * <p> * Calling requires permission {@link android.Manifest.permission#CAMERA_SEND_SYSTEM_EVENTS}. * * @param deviceStateFlags a bitmask of the device state bits that should be set. * * @see #clearDeviceStateFlags(int) */ public void setDeviceStateFlags(@DeviceStateFlags int deviceStateFlags) { synchronized (mLock) { mHandler.removeMessages(MSG_NOTIFY_DEVICE_STATE); mDeviceState |= deviceStateFlags; if (mDeviceState != mLastReportedDeviceState) { notifyDeviceStateWithRetriesLocked(RETRY_TIMES); } } } /** * Clears the device state bits set within {@code deviceStateFlags} leaving all other bits the * same. * <p> * Calling requires permission {@link android.Manifest.permission#CAMERA_SEND_SYSTEM_EVENTS}. * * @param deviceStateFlags a bitmask of the device state bits that should be cleared. * * @see #setDeviceStateFlags(int) */ public void clearDeviceStateFlags(@DeviceStateFlags int deviceStateFlags) { synchronized (mLock) { mHandler.removeMessages(MSG_NOTIFY_DEVICE_STATE); mDeviceState &= ~deviceStateFlags; if (mDeviceState != mLastReportedDeviceState) { notifyDeviceStateWithRetriesLocked(RETRY_TIMES); } } } @Override public boolean handleMessage(Message msg) { switch(msg.what) { case MSG_SWITCH_USER: { notifySwitchWithRetries(msg.arg1); } break; case MSG_NOTIFY_DEVICE_STATE: { notifyDeviceStateWithRetries(msg.arg1); } break; default: { Slog.e(TAG, "CameraServiceProxy error, invalid message: " + msg.what); } break; Loading Loading @@ -386,6 +452,25 @@ public class CameraServiceProxy extends SystemService } } @Nullable private ICameraService getCameraServiceRawLocked() { if (mCameraServiceRaw == null) { IBinder cameraServiceBinder = getBinderService(CAMERA_SERVICE_BINDER_NAME); if (cameraServiceBinder == null) { return null; } try { cameraServiceBinder.linkToDeath(this, /*flags*/ 0); } catch (RemoteException e) { Slog.w(TAG, "Could not link to death of native camera service"); return null; } mCameraServiceRaw = ICameraService.Stub.asInterface(cameraServiceBinder); } return mCameraServiceRaw; } private void switchUserLocked(int userHandle) { Set<Integer> currentUserHandles = getEnabledUserHandles(userHandle); mLastUser = userHandle; Loading Loading @@ -431,29 +516,56 @@ public class CameraServiceProxy extends SystemService private boolean notifyCameraserverLocked(int eventType, Set<Integer> updatedUserHandles) { // Forward the user switch event to the native camera service running in the cameraserver // process. if (mCameraServiceRaw == null) { IBinder cameraServiceBinder = getBinderService(CAMERA_SERVICE_BINDER_NAME); if (cameraServiceBinder == null) { ICameraService cameraService = getCameraServiceRawLocked(); if (cameraService == null) { Slog.w(TAG, "Could not notify cameraserver, camera service not available."); return false; // Camera service not active, cannot evict user clients. return false; } try { cameraServiceBinder.linkToDeath(this, /*flags*/ 0); mCameraServiceRaw.notifySystemEvent(eventType, toArray(updatedUserHandles)); } catch (RemoteException e) { Slog.w(TAG, "Could not link to death of native camera service"); Slog.w(TAG, "Could not notify cameraserver, remote exception: " + e); // Not much we can do if camera service is dead. return false; } return true; } mCameraServiceRaw = ICameraService.Stub.asInterface(cameraServiceBinder); private void notifyDeviceStateWithRetries(int retries) { synchronized (mLock) { notifyDeviceStateWithRetriesLocked(retries); } } private void notifyDeviceStateWithRetriesLocked(int retries) { if (notifyDeviceStateChangeLocked(mDeviceState)) { return; } if (retries <= 0) { return; } Slog.i(TAG, "Could not notify camera service of device state change, retrying..."); mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_NOTIFY_DEVICE_STATE, retries - 1, 0, null), RETRY_DELAY_TIME); } private boolean notifyDeviceStateChangeLocked(@DeviceStateFlags int deviceState) { // Forward the state to the native camera service running in the cameraserver process. ICameraService cameraService = getCameraServiceRawLocked(); if (cameraService == null) { Slog.w(TAG, "Could not notify cameraserver, camera service not available."); return false; } try { mCameraServiceRaw.notifySystemEvent(eventType, toArray(updatedUserHandles)); mCameraServiceRaw.notifyDeviceStateChange(deviceState); } catch (RemoteException e) { Slog.w(TAG, "Could not notify cameraserver, remote exception: " + e); // Not much we can do if camera service is dead. return false; } mLastReportedDeviceState = deviceState; return true; } Loading services/core/java/com/android/server/policy/DisplayFoldController.java +27 −4 Original line number Diff line number Diff line Loading @@ -16,8 +16,10 @@ package com.android.server.policy; import android.annotation.Nullable; import android.content.Context; import android.graphics.Rect; import android.hardware.ICameraService; import android.hardware.Sensor; import android.hardware.SensorEvent; import android.hardware.SensorEventListener; Loading @@ -26,11 +28,13 @@ import android.hardware.display.DisplayManagerInternal; import android.os.Handler; import android.os.RemoteCallbackList; import android.os.RemoteException; import android.util.Slog; import android.view.DisplayInfo; import android.view.IDisplayFoldListener; import com.android.server.DisplayThread; import com.android.server.LocalServices; import com.android.server.camera.CameraServiceProxy; import com.android.server.wm.WindowManagerInternal; /** Loading @@ -38,11 +42,13 @@ import com.android.server.wm.WindowManagerInternal; * TODO(b/126160895): Move DisplayFoldController from PhoneWindowManager to DisplayPolicy. */ class DisplayFoldController { private static final String TAG = "DisplayFoldController"; private final WindowManagerInternal mWindowManagerInternal; private final DisplayManagerInternal mDisplayManagerInternal; // Camera service proxy can be disabled through a config. @Nullable private final CameraServiceProxy mCameraServiceProxy; private final int mDisplayId; private final Handler mHandler; Loading @@ -58,10 +64,12 @@ class DisplayFoldController { private final DisplayFoldDurationLogger mDurationLogger = new DisplayFoldDurationLogger(); DisplayFoldController(WindowManagerInternal windowManagerInternal, DisplayManagerInternal displayManagerInternal, int displayId, Rect foldedArea, DisplayManagerInternal displayManagerInternal, @Nullable CameraServiceProxy cameraServiceProxy, int displayId, Rect foldedArea, Handler handler) { mWindowManagerInternal = windowManagerInternal; mDisplayManagerInternal = displayManagerInternal; mCameraServiceProxy = cameraServiceProxy; mDisplayId = displayId; mFoldedArea = new Rect(foldedArea); mHandler = handler; Loading Loading @@ -116,6 +124,16 @@ class DisplayFoldController { } } if (mCameraServiceProxy != null) { if (folded) { mCameraServiceProxy.setDeviceStateFlags(ICameraService.DEVICE_STATE_FOLDED); } else { mCameraServiceProxy.clearDeviceStateFlags(ICameraService.DEVICE_STATE_FOLDED); } } else { Slog.w(TAG, "Camera service unavailable to toggle folded state."); } mDurationLogger.setDeviceFolded(folded); mDurationLogger.logFocusedAppWithFoldState(folded, mFocusedApp); mFolded = folded; Loading Loading @@ -193,8 +211,13 @@ class DisplayFoldController { } static DisplayFoldController create(Context context, int displayId) { final WindowManagerInternal windowManagerService = LocalServices.getService(WindowManagerInternal.class); final DisplayManagerInternal displayService = LocalServices.getService(DisplayManagerInternal.class); final CameraServiceProxy cameraServiceProxy = LocalServices.getService(CameraServiceProxy.class); final String configFoldedArea = context.getResources().getString( com.android.internal.R.string.config_foldedArea); final Rect foldedArea; Loading @@ -204,7 +227,7 @@ class DisplayFoldController { foldedArea = Rect.unflattenFromString(configFoldedArea); } return new DisplayFoldController(LocalServices.getService(WindowManagerInternal.class), displayService, displayId, foldedArea, DisplayThread.getHandler()); return new DisplayFoldController(windowManagerService, displayService, cameraServiceProxy, displayId, foldedArea, DisplayThread.getHandler()); } } services/java/com/android/server/SystemServer.java +6 −6 Original line number Diff line number Diff line Loading @@ -1266,6 +1266,12 @@ public final class SystemServer implements Dumpable { inputManager = new InputManagerService(context); t.traceEnd(); if (!disableCameraService) { t.traceBegin("StartCameraServiceProxy"); mSystemServiceManager.startService(CameraServiceProxy.class); t.traceEnd(); } t.traceBegin("StartWindowManagerService"); // WMS needs sensor service ready ConcurrentUtils.waitForFutureNoInterrupt(mSensorServiceStart, START_SENSOR_SERVICE); Loading Loading @@ -2200,12 +2206,6 @@ public final class SystemServer implements Dumpable { t.traceEnd(); } if (!disableCameraService) { t.traceBegin("StartCameraServiceProxy"); mSystemServiceManager.startService(CameraServiceProxy.class); t.traceEnd(); } if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_EMBEDDED)) { t.traceBegin("StartIoTSystemService"); mSystemServiceManager.startService(IOT_SERVICE_CLASS); Loading Loading
services/core/java/com/android/server/camera/CameraServiceProxy.java +126 −14 Original line number Diff line number Diff line Loading @@ -15,6 +15,7 @@ */ package com.android.server.camera; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.content.BroadcastReceiver; Loading @@ -39,6 +40,7 @@ import android.util.ArrayMap; import android.util.ArraySet; import android.util.Slog; import com.android.internal.annotations.GuardedBy; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.internal.util.FrameworkStatsLog; Loading @@ -48,6 +50,8 @@ import com.android.server.SystemService; import com.android.server.SystemService.TargetUser; import com.android.server.wm.WindowManagerInternal; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; Loading Loading @@ -79,10 +83,19 @@ public class CameraServiceProxy extends SystemService // Handler message codes private static final int MSG_SWITCH_USER = 1; private static final int MSG_NOTIFY_DEVICE_STATE = 2; private static final int RETRY_DELAY_TIME = 20; //ms private static final int RETRY_TIMES = 60; @IntDef(flag = true, prefix = { "DEVICE_STATE_" }, value = { ICameraService.DEVICE_STATE_BACK_COVERED, ICameraService.DEVICE_STATE_FRONT_COVERED, ICameraService.DEVICE_STATE_FOLDED }) @Retention(RetentionPolicy.SOURCE) @interface DeviceStateFlags {} // Maximum entries to keep in usage history before dumping out private static final int MAX_USAGE_HISTORY = 100; Loading @@ -94,6 +107,15 @@ public class CameraServiceProxy extends SystemService private final Object mLock = new Object(); private Set<Integer> mEnabledCameraUsers; private int mLastUser; // The current set of device state flags. May be different from mLastReportedDeviceState if the // native camera service has not been notified of the change. @GuardedBy("mLock") @DeviceStateFlags private int mDeviceState; // The most recent device state flags reported to the native camera server. @GuardedBy("mLock") @DeviceStateFlags private int mLastReportedDeviceState; private ICameraService mCameraServiceRaw; Loading Loading @@ -185,6 +207,7 @@ public class CameraServiceProxy extends SystemService return; } notifySwitchWithRetries(RETRY_TIMES); notifyDeviceStateWithRetries(RETRY_TIMES); } @Override Loading Loading @@ -218,12 +241,55 @@ public class CameraServiceProxy extends SystemService mLogWriterService.allowCoreThreadTimeOut(true); } /** * Sets the device state bits set within {@code deviceStateFlags} leaving all other bits the * same. * <p> * Calling requires permission {@link android.Manifest.permission#CAMERA_SEND_SYSTEM_EVENTS}. * * @param deviceStateFlags a bitmask of the device state bits that should be set. * * @see #clearDeviceStateFlags(int) */ public void setDeviceStateFlags(@DeviceStateFlags int deviceStateFlags) { synchronized (mLock) { mHandler.removeMessages(MSG_NOTIFY_DEVICE_STATE); mDeviceState |= deviceStateFlags; if (mDeviceState != mLastReportedDeviceState) { notifyDeviceStateWithRetriesLocked(RETRY_TIMES); } } } /** * Clears the device state bits set within {@code deviceStateFlags} leaving all other bits the * same. * <p> * Calling requires permission {@link android.Manifest.permission#CAMERA_SEND_SYSTEM_EVENTS}. * * @param deviceStateFlags a bitmask of the device state bits that should be cleared. * * @see #setDeviceStateFlags(int) */ public void clearDeviceStateFlags(@DeviceStateFlags int deviceStateFlags) { synchronized (mLock) { mHandler.removeMessages(MSG_NOTIFY_DEVICE_STATE); mDeviceState &= ~deviceStateFlags; if (mDeviceState != mLastReportedDeviceState) { notifyDeviceStateWithRetriesLocked(RETRY_TIMES); } } } @Override public boolean handleMessage(Message msg) { switch(msg.what) { case MSG_SWITCH_USER: { notifySwitchWithRetries(msg.arg1); } break; case MSG_NOTIFY_DEVICE_STATE: { notifyDeviceStateWithRetries(msg.arg1); } break; default: { Slog.e(TAG, "CameraServiceProxy error, invalid message: " + msg.what); } break; Loading Loading @@ -386,6 +452,25 @@ public class CameraServiceProxy extends SystemService } } @Nullable private ICameraService getCameraServiceRawLocked() { if (mCameraServiceRaw == null) { IBinder cameraServiceBinder = getBinderService(CAMERA_SERVICE_BINDER_NAME); if (cameraServiceBinder == null) { return null; } try { cameraServiceBinder.linkToDeath(this, /*flags*/ 0); } catch (RemoteException e) { Slog.w(TAG, "Could not link to death of native camera service"); return null; } mCameraServiceRaw = ICameraService.Stub.asInterface(cameraServiceBinder); } return mCameraServiceRaw; } private void switchUserLocked(int userHandle) { Set<Integer> currentUserHandles = getEnabledUserHandles(userHandle); mLastUser = userHandle; Loading Loading @@ -431,29 +516,56 @@ public class CameraServiceProxy extends SystemService private boolean notifyCameraserverLocked(int eventType, Set<Integer> updatedUserHandles) { // Forward the user switch event to the native camera service running in the cameraserver // process. if (mCameraServiceRaw == null) { IBinder cameraServiceBinder = getBinderService(CAMERA_SERVICE_BINDER_NAME); if (cameraServiceBinder == null) { ICameraService cameraService = getCameraServiceRawLocked(); if (cameraService == null) { Slog.w(TAG, "Could not notify cameraserver, camera service not available."); return false; // Camera service not active, cannot evict user clients. return false; } try { cameraServiceBinder.linkToDeath(this, /*flags*/ 0); mCameraServiceRaw.notifySystemEvent(eventType, toArray(updatedUserHandles)); } catch (RemoteException e) { Slog.w(TAG, "Could not link to death of native camera service"); Slog.w(TAG, "Could not notify cameraserver, remote exception: " + e); // Not much we can do if camera service is dead. return false; } return true; } mCameraServiceRaw = ICameraService.Stub.asInterface(cameraServiceBinder); private void notifyDeviceStateWithRetries(int retries) { synchronized (mLock) { notifyDeviceStateWithRetriesLocked(retries); } } private void notifyDeviceStateWithRetriesLocked(int retries) { if (notifyDeviceStateChangeLocked(mDeviceState)) { return; } if (retries <= 0) { return; } Slog.i(TAG, "Could not notify camera service of device state change, retrying..."); mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_NOTIFY_DEVICE_STATE, retries - 1, 0, null), RETRY_DELAY_TIME); } private boolean notifyDeviceStateChangeLocked(@DeviceStateFlags int deviceState) { // Forward the state to the native camera service running in the cameraserver process. ICameraService cameraService = getCameraServiceRawLocked(); if (cameraService == null) { Slog.w(TAG, "Could not notify cameraserver, camera service not available."); return false; } try { mCameraServiceRaw.notifySystemEvent(eventType, toArray(updatedUserHandles)); mCameraServiceRaw.notifyDeviceStateChange(deviceState); } catch (RemoteException e) { Slog.w(TAG, "Could not notify cameraserver, remote exception: " + e); // Not much we can do if camera service is dead. return false; } mLastReportedDeviceState = deviceState; return true; } Loading
services/core/java/com/android/server/policy/DisplayFoldController.java +27 −4 Original line number Diff line number Diff line Loading @@ -16,8 +16,10 @@ package com.android.server.policy; import android.annotation.Nullable; import android.content.Context; import android.graphics.Rect; import android.hardware.ICameraService; import android.hardware.Sensor; import android.hardware.SensorEvent; import android.hardware.SensorEventListener; Loading @@ -26,11 +28,13 @@ import android.hardware.display.DisplayManagerInternal; import android.os.Handler; import android.os.RemoteCallbackList; import android.os.RemoteException; import android.util.Slog; import android.view.DisplayInfo; import android.view.IDisplayFoldListener; import com.android.server.DisplayThread; import com.android.server.LocalServices; import com.android.server.camera.CameraServiceProxy; import com.android.server.wm.WindowManagerInternal; /** Loading @@ -38,11 +42,13 @@ import com.android.server.wm.WindowManagerInternal; * TODO(b/126160895): Move DisplayFoldController from PhoneWindowManager to DisplayPolicy. */ class DisplayFoldController { private static final String TAG = "DisplayFoldController"; private final WindowManagerInternal mWindowManagerInternal; private final DisplayManagerInternal mDisplayManagerInternal; // Camera service proxy can be disabled through a config. @Nullable private final CameraServiceProxy mCameraServiceProxy; private final int mDisplayId; private final Handler mHandler; Loading @@ -58,10 +64,12 @@ class DisplayFoldController { private final DisplayFoldDurationLogger mDurationLogger = new DisplayFoldDurationLogger(); DisplayFoldController(WindowManagerInternal windowManagerInternal, DisplayManagerInternal displayManagerInternal, int displayId, Rect foldedArea, DisplayManagerInternal displayManagerInternal, @Nullable CameraServiceProxy cameraServiceProxy, int displayId, Rect foldedArea, Handler handler) { mWindowManagerInternal = windowManagerInternal; mDisplayManagerInternal = displayManagerInternal; mCameraServiceProxy = cameraServiceProxy; mDisplayId = displayId; mFoldedArea = new Rect(foldedArea); mHandler = handler; Loading Loading @@ -116,6 +124,16 @@ class DisplayFoldController { } } if (mCameraServiceProxy != null) { if (folded) { mCameraServiceProxy.setDeviceStateFlags(ICameraService.DEVICE_STATE_FOLDED); } else { mCameraServiceProxy.clearDeviceStateFlags(ICameraService.DEVICE_STATE_FOLDED); } } else { Slog.w(TAG, "Camera service unavailable to toggle folded state."); } mDurationLogger.setDeviceFolded(folded); mDurationLogger.logFocusedAppWithFoldState(folded, mFocusedApp); mFolded = folded; Loading Loading @@ -193,8 +211,13 @@ class DisplayFoldController { } static DisplayFoldController create(Context context, int displayId) { final WindowManagerInternal windowManagerService = LocalServices.getService(WindowManagerInternal.class); final DisplayManagerInternal displayService = LocalServices.getService(DisplayManagerInternal.class); final CameraServiceProxy cameraServiceProxy = LocalServices.getService(CameraServiceProxy.class); final String configFoldedArea = context.getResources().getString( com.android.internal.R.string.config_foldedArea); final Rect foldedArea; Loading @@ -204,7 +227,7 @@ class DisplayFoldController { foldedArea = Rect.unflattenFromString(configFoldedArea); } return new DisplayFoldController(LocalServices.getService(WindowManagerInternal.class), displayService, displayId, foldedArea, DisplayThread.getHandler()); return new DisplayFoldController(windowManagerService, displayService, cameraServiceProxy, displayId, foldedArea, DisplayThread.getHandler()); } }
services/java/com/android/server/SystemServer.java +6 −6 Original line number Diff line number Diff line Loading @@ -1266,6 +1266,12 @@ public final class SystemServer implements Dumpable { inputManager = new InputManagerService(context); t.traceEnd(); if (!disableCameraService) { t.traceBegin("StartCameraServiceProxy"); mSystemServiceManager.startService(CameraServiceProxy.class); t.traceEnd(); } t.traceBegin("StartWindowManagerService"); // WMS needs sensor service ready ConcurrentUtils.waitForFutureNoInterrupt(mSensorServiceStart, START_SENSOR_SERVICE); Loading Loading @@ -2200,12 +2206,6 @@ public final class SystemServer implements Dumpable { t.traceEnd(); } if (!disableCameraService) { t.traceBegin("StartCameraServiceProxy"); mSystemServiceManager.startService(CameraServiceProxy.class); t.traceEnd(); } if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_EMBEDDED)) { t.traceBegin("StartIoTSystemService"); mSystemServiceManager.startService(IOT_SERVICE_CLASS); Loading