diff options
| author | 2017-08-02 22:51:23 +0000 | |
|---|---|---|
| committer | 2017-08-02 22:51:23 +0000 | |
| commit | a418f377afd551c306592254b3a49cda90f51376 (patch) | |
| tree | 1f4c8ec90bd25c5861de3bc5ecf5028e388e6fea | |
| parent | 623fbea979cfb477090612d16c8fd30bd62b7589 (diff) | |
| parent | e81cdeea1c13a75abe69a2e430791496ed91bad3 (diff) | |
Merge "SysUI: Move all sensor operations to the background thread" into oc-dr1-dev
am: e81cdeea1c
Change-Id: Idd7b5d3741f629b560e9de5b985d895a45e8a532
4 files changed, 165 insertions, 2 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/Dependency.java b/packages/SystemUI/src/com/android/systemui/Dependency.java index e5c729faae04..9c1cb4ef8c81 100644 --- a/packages/SystemUI/src/com/android/systemui/Dependency.java +++ b/packages/SystemUI/src/com/android/systemui/Dependency.java @@ -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; @@ -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; @@ -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))); diff --git a/packages/SystemUI/src/com/android/systemui/classifier/FalsingManager.java b/packages/SystemUI/src/com/android/systemui/classifier/FalsingManager.java index e92ed2f75d49..e4b405f580d4 100644 --- a/packages/SystemUI/src/com/android/systemui/classifier/FalsingManager.java +++ b/packages/SystemUI/src/com/android/systemui/classifier/FalsingManager.java @@ -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; @@ -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); diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java b/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java index 91ca571e9f7a..cbdabf5de876 100644 --- a/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java +++ b/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java @@ -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; @@ -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); diff --git a/packages/SystemUI/src/com/android/systemui/util/AsyncSensorManager.java b/packages/SystemUI/src/com/android/systemui/util/AsyncSensorManager.java new file mode 100644 index 000000000000..a1cabff4c7aa --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/util/AsyncSensorManager.java @@ -0,0 +1,155 @@ +/* + * 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)); + } +} |