Loading packages/SystemUI/src/com/android/systemui/Dependency.java +5 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.systemui; import android.content.Context; import android.content.res.Configuration; import android.hardware.SensorManager; import android.os.Handler; import android.os.HandlerThread; import android.os.Looper; Loading Loading @@ -84,6 +85,7 @@ import com.android.systemui.statusbar.policy.ZenModeControllerImpl; import com.android.systemui.tuner.TunablePadding.TunablePaddingService; import com.android.systemui.tuner.TunerService; import com.android.systemui.tuner.TunerServiceImpl; import com.android.systemui.util.AsyncSensorManager; import com.android.systemui.util.leak.GarbageMonitor; import com.android.systemui.util.leak.LeakDetector; import com.android.systemui.util.leak.LeakReporter; Loading Loading @@ -156,6 +158,9 @@ public class Dependency extends SystemUI { mProviders.put(ActivityStarterDelegate.class, () -> getDependency(ActivityStarter.class)); mProviders.put(AsyncSensorManager.class, () -> new AsyncSensorManager(mContext.getSystemService(SensorManager.class))); mProviders.put(BluetoothController.class, () -> new BluetoothControllerImpl(mContext, getDependency(BG_LOOPER))); Loading packages/SystemUI/src/com/android/systemui/classifier/FalsingManager.java +2 −1 Original line number Diff line number Diff line Loading @@ -35,6 +35,7 @@ import com.android.systemui.Dependency; import com.android.systemui.UiOffloadThread; import com.android.systemui.analytics.DataCollector; import com.android.systemui.statusbar.StatusBarState; import com.android.systemui.util.AsyncSensorManager; import java.io.PrintWriter; Loading Loading @@ -87,7 +88,7 @@ public class FalsingManager implements SensorEventListener { private FalsingManager(Context context) { mContext = context; mSensorManager = mContext.getSystemService(SensorManager.class); mSensorManager = Dependency.get(AsyncSensorManager.class); mAccessibilityManager = context.getSystemService(AccessibilityManager.class); mDataCollector = DataCollector.getInstance(mContext); mHumanInteractionClassifier = HumanInteractionClassifier.getInstance(mContext); Loading packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java +3 −1 Original line number Diff line number Diff line Loading @@ -24,10 +24,12 @@ import android.hardware.SensorManager; import android.os.Handler; import com.android.internal.hardware.AmbientDisplayConfiguration; import com.android.systemui.Dependency; import com.android.systemui.R; import com.android.systemui.SystemUIApplication; import com.android.systemui.classifier.FalsingManager; import com.android.systemui.statusbar.phone.DozeParameters; import com.android.systemui.util.AsyncSensorManager; import com.android.systemui.util.wakelock.DelayedWakeLock; import com.android.systemui.util.wakelock.WakeLock; Loading @@ -39,7 +41,7 @@ public class DozeFactory { /** Creates a DozeMachine with its parts for {@code dozeService}. */ public DozeMachine assembleMachine(DozeService dozeService) { Context context = dozeService; SensorManager sensorManager = context.getSystemService(SensorManager.class); SensorManager sensorManager = Dependency.get(AsyncSensorManager.class); AlarmManager alarmManager = context.getSystemService(AlarmManager.class); DozeHost host = getHost(dozeService); Loading packages/SystemUI/src/com/android/systemui/util/AsyncSensorManager.java 0 → 100644 +155 −0 Original line number Diff line number Diff line /* * Copyright (C) 2017 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.systemui.util; import android.hardware.HardwareBuffer; import android.hardware.Sensor; import android.hardware.SensorAdditionalInfo; import android.hardware.SensorDirectChannel; import android.hardware.SensorEventListener; import android.hardware.SensorManager; import android.hardware.TriggerEventListener; import android.os.Handler; import android.os.HandlerThread; import android.os.MemoryFile; import android.util.Log; import com.android.internal.util.Preconditions; import java.util.List; /** * Wrapper around sensor manager that hides potential sources of latency. * * Offloads fetching (non-dynamic) sensors and (un)registering listeners onto a background thread * without blocking. Note that this means registering listeners now always appears successful even * if it is not. */ public class AsyncSensorManager extends SensorManager { private static final String TAG = "AsyncSensorManager"; private final SensorManager mInner; private final List<Sensor> mSensorCache; private final HandlerThread mHandlerThread = new HandlerThread("async_sensor"); private final Handler mHandler; public AsyncSensorManager(SensorManager inner) { mInner = inner; mHandlerThread.start(); mHandler = new Handler(mHandlerThread.getLooper()); mSensorCache = mInner.getSensorList(Sensor.TYPE_ALL); } @Override protected List<Sensor> getFullSensorList() { return mSensorCache; } @Override protected List<Sensor> getFullDynamicSensorList() { return mInner.getDynamicSensorList(Sensor.TYPE_ALL); } @Override protected boolean registerListenerImpl(SensorEventListener listener, Sensor sensor, int delayUs, Handler handler, int maxReportLatencyUs, int reservedFlags) { mHandler.post(() -> { if (!mInner.registerListener(listener, sensor, delayUs, maxReportLatencyUs, handler)) { Log.e(TAG, "Registering " + listener + " for " + sensor + " failed."); } }); return true; } @Override protected boolean flushImpl(SensorEventListener listener) { return mInner.flush(listener); } @Override protected SensorDirectChannel createDirectChannelImpl(MemoryFile memoryFile, HardwareBuffer hardwareBuffer) { throw new UnsupportedOperationException("not implemented"); } @Override protected void destroyDirectChannelImpl(SensorDirectChannel channel) { throw new UnsupportedOperationException("not implemented"); } @Override protected int configureDirectChannelImpl(SensorDirectChannel channel, Sensor s, int rate) { throw new UnsupportedOperationException("not implemented"); } @Override protected void registerDynamicSensorCallbackImpl(DynamicSensorCallback callback, Handler handler) { mHandler.post(() -> mInner.registerDynamicSensorCallback(callback, handler)); } @Override protected void unregisterDynamicSensorCallbackImpl(DynamicSensorCallback callback) { mHandler.post(() -> mInner.unregisterDynamicSensorCallback(callback)); } @Override protected boolean requestTriggerSensorImpl(TriggerEventListener listener, Sensor sensor) { mHandler.post(() -> { if (!mInner.requestTriggerSensor(listener, sensor)) { Log.e(TAG, "Requesting " + listener + " for " + sensor + " failed."); } }); return true; } @Override protected boolean cancelTriggerSensorImpl(TriggerEventListener listener, Sensor sensor, boolean disable) { Preconditions.checkArgument(disable); mHandler.post(() -> { if (!mInner.cancelTriggerSensor(listener, sensor)) { Log.e(TAG, "Canceling " + listener + " for " + sensor + " failed."); } }); return true; } @Override protected boolean initDataInjectionImpl(boolean enable) { throw new UnsupportedOperationException("not implemented"); } @Override protected boolean injectSensorDataImpl(Sensor sensor, float[] values, int accuracy, long timestamp) { throw new UnsupportedOperationException("not implemented"); } @Override protected boolean setOperationParameterImpl(SensorAdditionalInfo parameter) { mHandler.post(() -> mInner.setOperationParameter(parameter)); return true; } @Override protected void unregisterListenerImpl(SensorEventListener listener, Sensor sensor) { mHandler.post(() -> mInner.unregisterListener(listener, sensor)); } } Loading
packages/SystemUI/src/com/android/systemui/Dependency.java +5 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.systemui; import android.content.Context; import android.content.res.Configuration; import android.hardware.SensorManager; import android.os.Handler; import android.os.HandlerThread; import android.os.Looper; Loading Loading @@ -84,6 +85,7 @@ import com.android.systemui.statusbar.policy.ZenModeControllerImpl; import com.android.systemui.tuner.TunablePadding.TunablePaddingService; import com.android.systemui.tuner.TunerService; import com.android.systemui.tuner.TunerServiceImpl; import com.android.systemui.util.AsyncSensorManager; import com.android.systemui.util.leak.GarbageMonitor; import com.android.systemui.util.leak.LeakDetector; import com.android.systemui.util.leak.LeakReporter; Loading Loading @@ -156,6 +158,9 @@ public class Dependency extends SystemUI { mProviders.put(ActivityStarterDelegate.class, () -> getDependency(ActivityStarter.class)); mProviders.put(AsyncSensorManager.class, () -> new AsyncSensorManager(mContext.getSystemService(SensorManager.class))); mProviders.put(BluetoothController.class, () -> new BluetoothControllerImpl(mContext, getDependency(BG_LOOPER))); Loading
packages/SystemUI/src/com/android/systemui/classifier/FalsingManager.java +2 −1 Original line number Diff line number Diff line Loading @@ -35,6 +35,7 @@ import com.android.systemui.Dependency; import com.android.systemui.UiOffloadThread; import com.android.systemui.analytics.DataCollector; import com.android.systemui.statusbar.StatusBarState; import com.android.systemui.util.AsyncSensorManager; import java.io.PrintWriter; Loading Loading @@ -87,7 +88,7 @@ public class FalsingManager implements SensorEventListener { private FalsingManager(Context context) { mContext = context; mSensorManager = mContext.getSystemService(SensorManager.class); mSensorManager = Dependency.get(AsyncSensorManager.class); mAccessibilityManager = context.getSystemService(AccessibilityManager.class); mDataCollector = DataCollector.getInstance(mContext); mHumanInteractionClassifier = HumanInteractionClassifier.getInstance(mContext); Loading
packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java +3 −1 Original line number Diff line number Diff line Loading @@ -24,10 +24,12 @@ import android.hardware.SensorManager; import android.os.Handler; import com.android.internal.hardware.AmbientDisplayConfiguration; import com.android.systemui.Dependency; import com.android.systemui.R; import com.android.systemui.SystemUIApplication; import com.android.systemui.classifier.FalsingManager; import com.android.systemui.statusbar.phone.DozeParameters; import com.android.systemui.util.AsyncSensorManager; import com.android.systemui.util.wakelock.DelayedWakeLock; import com.android.systemui.util.wakelock.WakeLock; Loading @@ -39,7 +41,7 @@ public class DozeFactory { /** Creates a DozeMachine with its parts for {@code dozeService}. */ public DozeMachine assembleMachine(DozeService dozeService) { Context context = dozeService; SensorManager sensorManager = context.getSystemService(SensorManager.class); SensorManager sensorManager = Dependency.get(AsyncSensorManager.class); AlarmManager alarmManager = context.getSystemService(AlarmManager.class); DozeHost host = getHost(dozeService); Loading
packages/SystemUI/src/com/android/systemui/util/AsyncSensorManager.java 0 → 100644 +155 −0 Original line number Diff line number Diff line /* * Copyright (C) 2017 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.systemui.util; import android.hardware.HardwareBuffer; import android.hardware.Sensor; import android.hardware.SensorAdditionalInfo; import android.hardware.SensorDirectChannel; import android.hardware.SensorEventListener; import android.hardware.SensorManager; import android.hardware.TriggerEventListener; import android.os.Handler; import android.os.HandlerThread; import android.os.MemoryFile; import android.util.Log; import com.android.internal.util.Preconditions; import java.util.List; /** * Wrapper around sensor manager that hides potential sources of latency. * * Offloads fetching (non-dynamic) sensors and (un)registering listeners onto a background thread * without blocking. Note that this means registering listeners now always appears successful even * if it is not. */ public class AsyncSensorManager extends SensorManager { private static final String TAG = "AsyncSensorManager"; private final SensorManager mInner; private final List<Sensor> mSensorCache; private final HandlerThread mHandlerThread = new HandlerThread("async_sensor"); private final Handler mHandler; public AsyncSensorManager(SensorManager inner) { mInner = inner; mHandlerThread.start(); mHandler = new Handler(mHandlerThread.getLooper()); mSensorCache = mInner.getSensorList(Sensor.TYPE_ALL); } @Override protected List<Sensor> getFullSensorList() { return mSensorCache; } @Override protected List<Sensor> getFullDynamicSensorList() { return mInner.getDynamicSensorList(Sensor.TYPE_ALL); } @Override protected boolean registerListenerImpl(SensorEventListener listener, Sensor sensor, int delayUs, Handler handler, int maxReportLatencyUs, int reservedFlags) { mHandler.post(() -> { if (!mInner.registerListener(listener, sensor, delayUs, maxReportLatencyUs, handler)) { Log.e(TAG, "Registering " + listener + " for " + sensor + " failed."); } }); return true; } @Override protected boolean flushImpl(SensorEventListener listener) { return mInner.flush(listener); } @Override protected SensorDirectChannel createDirectChannelImpl(MemoryFile memoryFile, HardwareBuffer hardwareBuffer) { throw new UnsupportedOperationException("not implemented"); } @Override protected void destroyDirectChannelImpl(SensorDirectChannel channel) { throw new UnsupportedOperationException("not implemented"); } @Override protected int configureDirectChannelImpl(SensorDirectChannel channel, Sensor s, int rate) { throw new UnsupportedOperationException("not implemented"); } @Override protected void registerDynamicSensorCallbackImpl(DynamicSensorCallback callback, Handler handler) { mHandler.post(() -> mInner.registerDynamicSensorCallback(callback, handler)); } @Override protected void unregisterDynamicSensorCallbackImpl(DynamicSensorCallback callback) { mHandler.post(() -> mInner.unregisterDynamicSensorCallback(callback)); } @Override protected boolean requestTriggerSensorImpl(TriggerEventListener listener, Sensor sensor) { mHandler.post(() -> { if (!mInner.requestTriggerSensor(listener, sensor)) { Log.e(TAG, "Requesting " + listener + " for " + sensor + " failed."); } }); return true; } @Override protected boolean cancelTriggerSensorImpl(TriggerEventListener listener, Sensor sensor, boolean disable) { Preconditions.checkArgument(disable); mHandler.post(() -> { if (!mInner.cancelTriggerSensor(listener, sensor)) { Log.e(TAG, "Canceling " + listener + " for " + sensor + " failed."); } }); return true; } @Override protected boolean initDataInjectionImpl(boolean enable) { throw new UnsupportedOperationException("not implemented"); } @Override protected boolean injectSensorDataImpl(Sensor sensor, float[] values, int accuracy, long timestamp) { throw new UnsupportedOperationException("not implemented"); } @Override protected boolean setOperationParameterImpl(SensorAdditionalInfo parameter) { mHandler.post(() -> mInner.setOperationParameter(parameter)); return true; } @Override protected void unregisterListenerImpl(SensorEventListener listener, Sensor sensor) { mHandler.post(() -> mInner.unregisterListener(listener, sensor)); } }