1 /* 2 * Copyright (C) 2021 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.systemui.statusbar.policy; 18 19 import android.content.Context; 20 import android.hardware.devicestate.DeviceStateManager; 21 import android.util.SparseIntArray; 22 23 import androidx.annotation.NonNull; 24 25 import com.android.internal.R; 26 import com.android.systemui.dagger.SysUISingleton; 27 import com.android.systemui.dagger.qualifiers.Main; 28 import com.android.systemui.util.Assert; 29 30 import java.util.ArrayList; 31 import java.util.List; 32 import java.util.concurrent.Executor; 33 34 import javax.inject.Inject; 35 36 /** Implementation of {@link DevicePostureController} using the DeviceStateManager. */ 37 @SysUISingleton 38 public class DevicePostureControllerImpl implements DevicePostureController { 39 private final List<Callback> mListeners = new ArrayList<>(); 40 private int mCurrentDevicePosture = DEVICE_POSTURE_UNKNOWN; 41 42 private final SparseIntArray mDeviceStateToPostureMap = new SparseIntArray(); 43 44 @Inject DevicePostureControllerImpl( Context context, DeviceStateManager deviceStateManager, @Main Executor executor)45 public DevicePostureControllerImpl( 46 Context context, DeviceStateManager deviceStateManager, @Main Executor executor) { 47 // Most of this is borrowed from WindowManager/Jetpack/DeviceStateManagerPostureProducer. 48 // Using the sidecar/extension libraries directly brings in a new dependency that it'd be 49 // good to avoid (along with the fact that sidecar is deprecated, and extensions isn't fully 50 // ready yet), and we'd have to make our own layer over the sidecar library anyway to easily 51 // allow the implementation to change, so it was easier to just interface with 52 // DeviceStateManager directly. 53 String[] deviceStatePosturePairs = context.getResources() 54 .getStringArray(R.array.config_device_state_postures); 55 for (String deviceStatePosturePair : deviceStatePosturePairs) { 56 String[] deviceStatePostureMapping = deviceStatePosturePair.split(":"); 57 if (deviceStatePostureMapping.length != 2) { 58 continue; 59 } 60 61 int deviceState; 62 int posture; 63 try { 64 deviceState = Integer.parseInt(deviceStatePostureMapping[0]); 65 posture = Integer.parseInt(deviceStatePostureMapping[1]); 66 } catch (NumberFormatException e) { 67 continue; 68 } 69 70 mDeviceStateToPostureMap.put(deviceState, posture); 71 } 72 73 deviceStateManager.registerCallback(executor, state -> { 74 Assert.isMainThread(); 75 mCurrentDevicePosture = 76 mDeviceStateToPostureMap.get(state, DEVICE_POSTURE_UNKNOWN); 77 78 mListeners.forEach(l -> l.onPostureChanged(mCurrentDevicePosture)); 79 }); 80 } 81 82 @Override addCallback(@onNull Callback listener)83 public void addCallback(@NonNull Callback listener) { 84 Assert.isMainThread(); 85 mListeners.add(listener); 86 } 87 88 @Override removeCallback(@onNull Callback listener)89 public void removeCallback(@NonNull Callback listener) { 90 Assert.isMainThread(); 91 mListeners.remove(listener); 92 } 93 94 @Override getDevicePosture()95 public int getDevicePosture() { 96 return mCurrentDevicePosture; 97 } 98 } 99