1 /* 2 * Copyright (C) 2014 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.annotation.NonNull; 20 import android.content.Context; 21 import android.content.res.Resources; 22 import android.util.ArraySet; 23 import android.view.LayoutInflater; 24 import android.view.View; 25 import android.view.ViewGroup; 26 import android.widget.FrameLayout; 27 28 import com.android.systemui.R; 29 import com.android.systemui.settings.brightness.BrightnessSliderController; 30 import com.android.systemui.settings.brightness.ToggleSlider; 31 import com.android.systemui.shade.NotificationShadeWindowView; 32 import com.android.systemui.shade.ShadeViewController; 33 import com.android.systemui.statusbar.NotificationShadeDepthController; 34 35 import java.util.Objects; 36 import java.util.function.Consumer; 37 38 /** 39 * Controls showing and hiding of the brightness mirror. 40 */ 41 public class BrightnessMirrorController 42 implements CallbackController<BrightnessMirrorController.BrightnessMirrorListener> { 43 44 private final NotificationShadeWindowView mStatusBarWindow; 45 private final Consumer<Boolean> mVisibilityCallback; 46 private final ShadeViewController mNotificationPanel; 47 private final NotificationShadeDepthController mDepthController; 48 private final ArraySet<BrightnessMirrorListener> mBrightnessMirrorListeners = new ArraySet<>(); 49 private final BrightnessSliderController.Factory mToggleSliderFactory; 50 private BrightnessSliderController mToggleSliderController; 51 private final int[] mInt2Cache = new int[2]; 52 private FrameLayout mBrightnessMirror; 53 private int mBrightnessMirrorBackgroundPadding; 54 private int mLastBrightnessSliderWidth = -1; 55 BrightnessMirrorController(NotificationShadeWindowView statusBarWindow, ShadeViewController shadeViewController, NotificationShadeDepthController notificationShadeDepthController, BrightnessSliderController.Factory factory, @NonNull Consumer<Boolean> visibilityCallback)56 public BrightnessMirrorController(NotificationShadeWindowView statusBarWindow, 57 ShadeViewController shadeViewController, 58 NotificationShadeDepthController notificationShadeDepthController, 59 BrightnessSliderController.Factory factory, 60 @NonNull Consumer<Boolean> visibilityCallback) { 61 mStatusBarWindow = statusBarWindow; 62 mToggleSliderFactory = factory; 63 mBrightnessMirror = statusBarWindow.findViewById(R.id.brightness_mirror_container); 64 mToggleSliderController = setMirrorLayout(); 65 mNotificationPanel = shadeViewController; 66 mDepthController = notificationShadeDepthController; 67 mNotificationPanel.setAlphaChangeAnimationEndAction(() -> { 68 mBrightnessMirror.setVisibility(View.INVISIBLE); 69 }); 70 mVisibilityCallback = visibilityCallback; 71 updateResources(); 72 } 73 showMirror()74 public void showMirror() { 75 mBrightnessMirror.setVisibility(View.VISIBLE); 76 mVisibilityCallback.accept(true); 77 mNotificationPanel.setAlpha(0, true /* animate */); 78 mDepthController.setBrightnessMirrorVisible(true); 79 } 80 hideMirror()81 public void hideMirror() { 82 mVisibilityCallback.accept(false); 83 mNotificationPanel.setAlpha(255, true /* animate */); 84 mDepthController.setBrightnessMirrorVisible(false); 85 } 86 87 /** 88 * Set the location and size of the mirror container to match that of the slider in QS 89 * @param original the original view in QS 90 */ setLocationAndSize(View original)91 public void setLocationAndSize(View original) { 92 original.getLocationInWindow(mInt2Cache); 93 94 // Original is slightly larger than the mirror, so make sure to use the center for the 95 // positioning. 96 int originalX = mInt2Cache[0] - mBrightnessMirrorBackgroundPadding; 97 int originalY = mInt2Cache[1] - mBrightnessMirrorBackgroundPadding; 98 mBrightnessMirror.setTranslationX(0); 99 mBrightnessMirror.setTranslationY(0); 100 mBrightnessMirror.getLocationInWindow(mInt2Cache); 101 int mirrorX = mInt2Cache[0]; 102 int mirrorY = mInt2Cache[1]; 103 mBrightnessMirror.setTranslationX(originalX - mirrorX); 104 mBrightnessMirror.setTranslationY(originalY - mirrorY); 105 106 // Set the brightness mirror container to be the width of the mirror + 2 times the padding 107 int newWidth = original.getMeasuredWidth() + 2 * mBrightnessMirrorBackgroundPadding; 108 if (newWidth != mLastBrightnessSliderWidth) { 109 ViewGroup.LayoutParams lp = mBrightnessMirror.getLayoutParams(); 110 lp.width = newWidth; 111 mBrightnessMirror.setLayoutParams(lp); 112 } 113 } 114 getToggleSlider()115 public ToggleSlider getToggleSlider() { 116 return mToggleSliderController; 117 } 118 updateResources()119 public void updateResources() { 120 Resources r = mBrightnessMirror.getResources(); 121 mBrightnessMirrorBackgroundPadding = r 122 .getDimensionPixelSize(R.dimen.rounded_slider_background_padding); 123 mBrightnessMirror.setPadding( 124 mBrightnessMirrorBackgroundPadding, 125 mBrightnessMirrorBackgroundPadding, 126 mBrightnessMirrorBackgroundPadding, 127 mBrightnessMirrorBackgroundPadding 128 ); 129 } 130 onOverlayChanged()131 public void onOverlayChanged() { 132 reinflate(); 133 } 134 onDensityOrFontScaleChanged()135 public void onDensityOrFontScaleChanged() { 136 reinflate(); 137 } 138 setMirrorLayout()139 private BrightnessSliderController setMirrorLayout() { 140 Context context = mBrightnessMirror.getContext(); 141 BrightnessSliderController controller = mToggleSliderFactory.create(context, 142 mBrightnessMirror); 143 controller.init(); 144 145 mBrightnessMirror.addView(controller.getRootView(), ViewGroup.LayoutParams.MATCH_PARENT, 146 ViewGroup.LayoutParams.WRAP_CONTENT); 147 148 return controller; 149 } 150 reinflate()151 private void reinflate() { 152 int index = mStatusBarWindow.indexOfChild(mBrightnessMirror); 153 mStatusBarWindow.removeView(mBrightnessMirror); 154 mBrightnessMirror = (FrameLayout) LayoutInflater.from(mStatusBarWindow.getContext()) 155 .inflate(R.layout.brightness_mirror_container, mStatusBarWindow, false); 156 mToggleSliderController = setMirrorLayout(); 157 mStatusBarWindow.addView(mBrightnessMirror, index); 158 updateResources(); 159 160 for (int i = 0; i < mBrightnessMirrorListeners.size(); i++) { 161 mBrightnessMirrorListeners.valueAt(i).onBrightnessMirrorReinflated(mBrightnessMirror); 162 } 163 } 164 165 @Override addCallback(@onNull BrightnessMirrorListener listener)166 public void addCallback(@NonNull BrightnessMirrorListener listener) { 167 Objects.requireNonNull(listener); 168 mBrightnessMirrorListeners.add(listener); 169 } 170 171 @Override removeCallback(@onNull BrightnessMirrorListener listener)172 public void removeCallback(@NonNull BrightnessMirrorListener listener) { 173 mBrightnessMirrorListeners.remove(listener); 174 } 175 onUiModeChanged()176 public void onUiModeChanged() { 177 reinflate(); 178 } 179 180 public interface BrightnessMirrorListener { onBrightnessMirrorReinflated(View brightnessMirror)181 void onBrightnessMirrorReinflated(View brightnessMirror); 182 } 183 } 184