1 /*
2  * Copyright (C) 2010 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 static com.android.systemui.statusbar.policy.dagger.StatusBarPolicyModule.DEVICE_STATE_ROTATION_LOCK_DEFAULTS;
20 
21 import android.Manifest;
22 import android.content.Context;
23 import android.content.pm.PackageManager;
24 import android.os.UserHandle;
25 
26 import androidx.annotation.NonNull;
27 
28 import com.android.internal.view.RotationPolicy.RotationPolicyListener;
29 import com.android.systemui.dagger.SysUISingleton;
30 import com.android.systemui.util.wrapper.RotationPolicyWrapper;
31 
32 import java.util.concurrent.CopyOnWriteArrayList;
33 
34 import javax.inject.Inject;
35 import javax.inject.Named;
36 
37 /** Platform implementation of the rotation lock controller. **/
38 @SysUISingleton
39 public final class RotationLockControllerImpl implements RotationLockController {
40 
41     private final CopyOnWriteArrayList<RotationLockControllerCallback> mCallbacks =
42             new CopyOnWriteArrayList<>();
43 
44     private final RotationPolicyListener mRotationPolicyListener =
45             new RotationPolicyListener() {
46         @Override
47         public void onChange() {
48             notifyChanged();
49         }
50     };
51 
52     private final RotationPolicyWrapper mRotationPolicy;
53     private final DeviceStateRotationLockSettingController
54             mDeviceStateRotationLockSettingController;
55     private final boolean mIsPerDeviceStateRotationLockEnabled;
56 
57     @Inject
RotationLockControllerImpl( RotationPolicyWrapper rotationPolicyWrapper, DeviceStateRotationLockSettingController deviceStateRotationLockSettingController, @Named(DEVICE_STATE_ROTATION_LOCK_DEFAULTS) String[] deviceStateRotationLockDefaults )58     public RotationLockControllerImpl(
59             RotationPolicyWrapper rotationPolicyWrapper,
60             DeviceStateRotationLockSettingController deviceStateRotationLockSettingController,
61             @Named(DEVICE_STATE_ROTATION_LOCK_DEFAULTS) String[] deviceStateRotationLockDefaults
62     ) {
63         mRotationPolicy = rotationPolicyWrapper;
64         mDeviceStateRotationLockSettingController = deviceStateRotationLockSettingController;
65         mIsPerDeviceStateRotationLockEnabled = deviceStateRotationLockDefaults.length > 0;
66         if (mIsPerDeviceStateRotationLockEnabled) {
67             mCallbacks.add(mDeviceStateRotationLockSettingController);
68         }
69 
70         setListening(true);
71     }
72 
73     @Override
addCallback(@onNull RotationLockControllerCallback callback)74     public void addCallback(@NonNull RotationLockControllerCallback callback) {
75         mCallbacks.add(callback);
76         notifyChanged(callback);
77     }
78 
79     @Override
removeCallback(@onNull RotationLockControllerCallback callback)80     public void removeCallback(@NonNull RotationLockControllerCallback callback) {
81         mCallbacks.remove(callback);
82     }
83 
getRotationLockOrientation()84     public int getRotationLockOrientation() {
85         return mRotationPolicy.getRotationLockOrientation();
86     }
87 
isRotationLocked()88     public boolean isRotationLocked() {
89         return mRotationPolicy.isRotationLocked();
90     }
91 
isCameraRotationEnabled()92     public boolean isCameraRotationEnabled() {
93         return mRotationPolicy.isCameraRotationEnabled();
94     }
95 
setRotationLocked(boolean locked, String caller)96     public void setRotationLocked(boolean locked, String caller) {
97         mRotationPolicy.setRotationLock(locked, caller);
98     }
99 
setRotationLockedAtAngle(boolean locked, int rotation, String caller)100     public void setRotationLockedAtAngle(boolean locked, int rotation, String caller) {
101         mRotationPolicy.setRotationLockAtAngle(locked, rotation, caller);
102     }
103 
isRotationLockAffordanceVisible()104     public boolean isRotationLockAffordanceVisible() {
105         return mRotationPolicy.isRotationLockToggleVisible();
106     }
107 
108     @Override
setListening(boolean listening)109     public void setListening(boolean listening) {
110         if (listening) {
111             mRotationPolicy.registerRotationPolicyListener(mRotationPolicyListener,
112                     UserHandle.USER_ALL);
113         } else {
114             mRotationPolicy.unregisterRotationPolicyListener(mRotationPolicyListener);
115         }
116         if (mIsPerDeviceStateRotationLockEnabled) {
117             mDeviceStateRotationLockSettingController.setListening(listening);
118         }
119     }
120 
notifyChanged()121     private void notifyChanged() {
122         for (RotationLockControllerCallback callback : mCallbacks) {
123             notifyChanged(callback);
124         }
125     }
126 
notifyChanged(RotationLockControllerCallback callback)127     private void notifyChanged(RotationLockControllerCallback callback) {
128         callback.onRotationLockStateChanged(mRotationPolicy.isRotationLocked(),
129                 mRotationPolicy.isRotationLockToggleVisible());
130     }
131 
hasSufficientPermission(Context context)132     public static boolean hasSufficientPermission(Context context) {
133         final PackageManager packageManager = context.getPackageManager();
134         final String rotationPackage = packageManager.getRotationResolverPackageName();
135         return rotationPackage != null && packageManager.checkPermission(
136                 Manifest.permission.CAMERA, rotationPackage) == PackageManager.PERMISSION_GRANTED;
137     }
138 }
139