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