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.settings.biometrics2.ui.viewmodel;
18 
19 import static android.hardware.display.DisplayManager.DisplayListener;
20 
21 import android.app.Application;
22 import android.hardware.display.DisplayManager;
23 import android.util.Log;
24 import android.view.DisplayInfo;
25 import android.view.Surface;
26 
27 import androidx.annotation.NonNull;
28 import androidx.lifecycle.AndroidViewModel;
29 import androidx.lifecycle.LiveData;
30 import androidx.lifecycle.MutableLiveData;
31 
32 import com.android.internal.annotations.VisibleForTesting;
33 
34 /**
35  * ViewModel explaining the fingerprint sensor location for fingerprint enrollment.
36  */
37 public class DeviceRotationViewModel extends AndroidViewModel {
38 
39     private static final boolean DEBUG = false;
40     private static final String TAG = "DeviceRotationViewModel";
41 
42     private final DisplayManager mDisplayManager;
43     private final boolean mIsReverseDefaultRotation;
44     @NonNull private final DisplayInfo mDisplayInfo = new DisplayInfo();
45 
46     /** {@link android.hardware.display.DisplayManager} is a final class, set this member visibility
47      * to 'protected' for testing
48      */
49     @VisibleForTesting
50     protected final DisplayListener mDisplayListener = new DisplayListener() {
51         @Override
52         public void onDisplayAdded(int displayId) {
53         }
54 
55         @Override
56         public void onDisplayRemoved(int displayId) {
57         }
58 
59         @Override
60         public void onDisplayChanged(int displayId) {
61             final int rotation = getRotation();
62             Log.d(TAG, "onDisplayChanged(" + displayId + "), rotation:" + rotation);
63             mLiveData.postValue(rotation);
64         }
65     };
66 
67     @NonNull private final MutableLiveData<Integer> mLiveData = new MutableLiveData<>();
68 
DeviceRotationViewModel(@onNull Application application)69     public DeviceRotationViewModel(@NonNull Application application) {
70         super(application);
71         mDisplayManager = application.getSystemService(DisplayManager.class);
72         mDisplayManager.registerDisplayListener(mDisplayListener,
73                 application.getMainThreadHandler());
74         mIsReverseDefaultRotation = application.getResources().getBoolean(
75                 com.android.internal.R.bool.config_reverseDefaultRotation);
76     }
77 
78     /**
79      * Returns current rotation.
80      *
81      * {@link android.view.Display} is a final class, set this method visibility to "protected" for
82      * inheriting it in test
83      */
84     @VisibleForTesting
85     @Surface.Rotation
getRotation()86     protected int getRotation() {
87         getApplication().getDisplay().getDisplayInfo(mDisplayInfo);
88         if (mIsReverseDefaultRotation) {
89             return (mDisplayInfo.rotation + 1) % 4;
90         } else {
91             return mDisplayInfo.rotation;
92         }
93     }
94 
95     /**
96      * Returns RotationLiveData
97      */
getLiveData()98     public LiveData<Integer> getLiveData() {
99         final Integer lastRotation = mLiveData.getValue();
100         @Surface.Rotation int newRotation = getRotation();
101         if (lastRotation == null || lastRotation != newRotation) {
102             Log.d(TAG, "getLiveData, update rotation from " + lastRotation + " to " + newRotation);
103             mLiveData.setValue(newRotation);
104         }
105         return mLiveData;
106     }
107 
108     @Override
onCleared()109     protected void onCleared() {
110         mDisplayManager.unregisterDisplayListener(mDisplayListener);
111         super.onCleared();
112     }
113 }
114