• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 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.server.wm;
18 
19 import android.annotation.NonNull;
20 import android.annotation.Nullable;
21 import android.content.Context;
22 import android.hardware.devicestate.DeviceStateManager;
23 import android.os.Handler;
24 import android.os.HandlerExecutor;
25 
26 import com.android.internal.R;
27 import com.android.internal.util.ArrayUtils;
28 
29 import java.util.ArrayList;
30 import java.util.List;
31 import java.util.function.Consumer;
32 
33 /**
34  * Class that registers callbacks with the {@link DeviceStateManager} and responds to device
35  * changes.
36  */
37 final class DeviceStateController implements DeviceStateManager.DeviceStateCallback {
38 
39     @NonNull
40     private final DeviceStateManager mDeviceStateManager;
41     @NonNull
42     private final int[] mOpenDeviceStates;
43     @NonNull
44     private final int[] mHalfFoldedDeviceStates;
45     @NonNull
46     private final int[] mFoldedDeviceStates;
47     @NonNull
48     private final int[] mRearDisplayDeviceStates;
49     @NonNull
50     private final int[] mReverseRotationAroundZAxisStates;
51     @NonNull
52     private final List<Consumer<DeviceState>> mDeviceStateCallbacks = new ArrayList<>();
53 
54     @Nullable
55     private DeviceState mLastDeviceState;
56     private int mCurrentState;
57 
58     public enum DeviceState {
59         UNKNOWN, OPEN, FOLDED, HALF_FOLDED, REAR,
60     }
61 
DeviceStateController(@onNull Context context, @NonNull Handler handler)62     DeviceStateController(@NonNull Context context, @NonNull Handler handler) {
63         mDeviceStateManager = context.getSystemService(DeviceStateManager.class);
64 
65         mOpenDeviceStates = context.getResources()
66                 .getIntArray(R.array.config_openDeviceStates);
67         mHalfFoldedDeviceStates = context.getResources()
68                 .getIntArray(R.array.config_halfFoldedDeviceStates);
69         mFoldedDeviceStates = context.getResources()
70                 .getIntArray(R.array.config_foldedDeviceStates);
71         mRearDisplayDeviceStates = context.getResources()
72                 .getIntArray(R.array.config_rearDisplayDeviceStates);
73         mReverseRotationAroundZAxisStates = context.getResources()
74                 .getIntArray(R.array.config_deviceStatesToReverseDefaultDisplayRotationAroundZAxis);
75 
76         if (mDeviceStateManager != null) {
77             mDeviceStateManager.registerCallback(new HandlerExecutor(handler), this);
78         }
79     }
80 
unregisterFromDeviceStateManager()81     void unregisterFromDeviceStateManager() {
82         if (mDeviceStateManager != null) {
83             mDeviceStateManager.unregisterCallback(this);
84         }
85     }
86 
registerDeviceStateCallback(@onNull Consumer<DeviceState> callback)87     void registerDeviceStateCallback(@NonNull Consumer<DeviceState> callback) {
88         mDeviceStateCallbacks.add(callback);
89     }
90 
91     /**
92      * @return true if the rotation direction on the Z axis should be reversed.
93      */
shouldReverseRotationDirectionAroundZAxis()94     boolean shouldReverseRotationDirectionAroundZAxis() {
95         return ArrayUtils.contains(mReverseRotationAroundZAxisStates, mCurrentState);
96     }
97 
98     @Override
onStateChanged(int state)99     public void onStateChanged(int state) {
100         mCurrentState = state;
101 
102         final DeviceState deviceState;
103         if (ArrayUtils.contains(mHalfFoldedDeviceStates, state)) {
104             deviceState = DeviceState.HALF_FOLDED;
105         } else if (ArrayUtils.contains(mFoldedDeviceStates, state)) {
106             deviceState = DeviceState.FOLDED;
107         } else if (ArrayUtils.contains(mRearDisplayDeviceStates, state)) {
108             deviceState = DeviceState.REAR;
109         } else if (ArrayUtils.contains(mOpenDeviceStates, state)) {
110             deviceState = DeviceState.OPEN;
111         } else {
112             deviceState = DeviceState.UNKNOWN;
113         }
114 
115         if (mLastDeviceState == null || !mLastDeviceState.equals(deviceState)) {
116             mLastDeviceState = deviceState;
117 
118             for (Consumer<DeviceState> callback : mDeviceStateCallbacks) {
119                 callback.accept(mLastDeviceState);
120             }
121         }
122     }
123 }
124