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.util.ArraySet; 20 import android.view.LayoutInflater; 21 import android.view.View; 22 import android.view.ViewPropertyAnimator; 23 import android.widget.FrameLayout; 24 25 import com.android.internal.util.Preconditions; 26 import com.android.systemui.Interpolators; 27 import com.android.systemui.R; 28 import com.android.systemui.statusbar.phone.ScrimController; 29 import com.android.systemui.statusbar.phone.StatusBarWindowView; 30 import com.android.systemui.statusbar.stack.NotificationStackScrollLayout; 31 32 /** 33 * Controls showing and hiding of the brightness mirror. 34 */ 35 public class BrightnessMirrorController 36 implements CallbackController<BrightnessMirrorController.BrightnessMirrorListener> { 37 38 private final NotificationStackScrollLayout mStackScroller; 39 public long TRANSITION_DURATION_OUT = 150; 40 public long TRANSITION_DURATION_IN = 200; 41 42 private final StatusBarWindowView mStatusBarWindow; 43 private final ScrimController mScrimController; 44 private final View mNotificationPanel; 45 private final ArraySet<BrightnessMirrorListener> mBrightnessMirrorListeners = new ArraySet<>(); 46 private final int[] mInt2Cache = new int[2]; 47 private View mBrightnessMirror; 48 49 public BrightnessMirrorController(StatusBarWindowView statusBarWindow, 50 ScrimController scrimController) { 51 mStatusBarWindow = statusBarWindow; 52 mBrightnessMirror = statusBarWindow.findViewById(R.id.brightness_mirror); 53 mNotificationPanel = statusBarWindow.findViewById(R.id.notification_panel); 54 mStackScroller = (NotificationStackScrollLayout) statusBarWindow.findViewById( 55 R.id.notification_stack_scroller); 56 mScrimController = scrimController; 57 } 58 59 public void showMirror() { 60 mBrightnessMirror.setVisibility(View.VISIBLE); 61 mStackScroller.setFadingOut(true); 62 mScrimController.forceHideScrims(true /* hide */, true /* animated */); 63 outAnimation(mNotificationPanel.animate()) 64 .withLayer(); 65 } 66 67 public void hideMirror() { 68 mScrimController.forceHideScrims(false /* hide */, true /* animated */); 69 inAnimation(mNotificationPanel.animate()) 70 .withLayer() 71 .withEndAction(new Runnable() { 72 @Override 73 public void run() { 74 mBrightnessMirror.setVisibility(View.INVISIBLE); 75 mStackScroller.setFadingOut(false); 76 } 77 }); 78 } 79 80 private ViewPropertyAnimator outAnimation(ViewPropertyAnimator a) { 81 return a.alpha(0.0f) 82 .setDuration(TRANSITION_DURATION_OUT) 83 .setInterpolator(Interpolators.ALPHA_OUT) 84 .withEndAction(null); 85 } 86 private ViewPropertyAnimator inAnimation(ViewPropertyAnimator a) { 87 return a.alpha(1.0f) 88 .setDuration(TRANSITION_DURATION_IN) 89 .setInterpolator(Interpolators.ALPHA_IN); 90 } 91 92 public void setLocation(View original) { 93 original.getLocationInWindow(mInt2Cache); 94 95 // Original is slightly larger than the mirror, so make sure to use the center for the 96 // positioning. 97 int originalX = mInt2Cache[0] + original.getWidth() / 2; 98 int originalY = mInt2Cache[1] + original.getHeight() / 2; 99 mBrightnessMirror.setTranslationX(0); 100 mBrightnessMirror.setTranslationY(0); 101 mBrightnessMirror.getLocationInWindow(mInt2Cache); 102 int mirrorX = mInt2Cache[0] + mBrightnessMirror.getWidth() / 2; 103 int mirrorY = mInt2Cache[1] + mBrightnessMirror.getHeight() / 2; 104 mBrightnessMirror.setTranslationX(originalX - mirrorX); 105 mBrightnessMirror.setTranslationY(originalY - mirrorY); 106 } 107 108 public View getMirror() { 109 return mBrightnessMirror; 110 } 111 112 public void updateResources() { 113 FrameLayout.LayoutParams lp = 114 (FrameLayout.LayoutParams) mBrightnessMirror.getLayoutParams(); 115 lp.width = mBrightnessMirror.getResources().getDimensionPixelSize( 116 R.dimen.qs_panel_width); 117 lp.gravity = mBrightnessMirror.getResources().getInteger( 118 R.integer.notification_panel_layout_gravity); 119 mBrightnessMirror.setLayoutParams(lp); 120 } 121 122 public void onOverlayChanged() { 123 reinflate(); 124 } 125 126 public void onDensityOrFontScaleChanged() { 127 reinflate(); 128 } 129 130 private void reinflate() { 131 int index = mStatusBarWindow.indexOfChild(mBrightnessMirror); 132 mStatusBarWindow.removeView(mBrightnessMirror); 133 mBrightnessMirror = LayoutInflater.from(mBrightnessMirror.getContext()).inflate( 134 R.layout.brightness_mirror, mStatusBarWindow, false); 135 mStatusBarWindow.addView(mBrightnessMirror, index); 136 137 for (int i = 0; i < mBrightnessMirrorListeners.size(); i++) { 138 mBrightnessMirrorListeners.valueAt(i).onBrightnessMirrorReinflated(mBrightnessMirror); 139 } 140 } 141 142 @Override 143 public void addCallback(BrightnessMirrorListener listener) { 144 Preconditions.checkNotNull(listener); 145 mBrightnessMirrorListeners.add(listener); 146 } 147 148 @Override 149 public void removeCallback(BrightnessMirrorListener listener) { 150 mBrightnessMirrorListeners.remove(listener); 151 } 152 153 public interface BrightnessMirrorListener { 154 void onBrightnessMirrorReinflated(View brightnessMirror); 155 } 156 } 157