1 /*
2  * Copyright (C) 2012 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.keyguard;
18 
19 import static java.util.Collections.emptySet;
20 
21 import android.content.Context;
22 import android.graphics.Canvas;
23 import android.os.Build;
24 import android.os.Trace;
25 import android.util.AttributeSet;
26 import android.view.MotionEvent;
27 import android.view.View;
28 import android.view.ViewGroup;
29 import android.view.ViewPropertyAnimator;
30 import android.widget.GridLayout;
31 
32 import com.android.systemui.res.R;
33 import com.android.systemui.shade.TouchLogger;
34 import com.android.systemui.statusbar.CrossFadeHelper;
35 
36 import java.io.PrintWriter;
37 import java.util.Set;
38 
39 /**
40  * View consisting of:
41  * - keyguard clock
42  * - media player (split shade mode only)
43  */
44 public class KeyguardStatusView extends GridLayout {
45     private static final boolean DEBUG = KeyguardConstants.DEBUG;
46     private static final String TAG = "KeyguardStatusView";
47 
48     private ViewGroup mStatusViewContainer;
49     private KeyguardClockSwitch mClockView;
50     private KeyguardSliceView mKeyguardSlice;
51     private View mMediaHostContainer;
52 
53     private int mDrawAlpha = 255;
54     private float mDarkAmount = 0;
55 
KeyguardStatusView(Context context)56     public KeyguardStatusView(Context context) {
57         this(context, null, 0);
58     }
59 
KeyguardStatusView(Context context, AttributeSet attrs)60     public KeyguardStatusView(Context context, AttributeSet attrs) {
61         this(context, attrs, 0);
62     }
63 
KeyguardStatusView(Context context, AttributeSet attrs, int defStyle)64     public KeyguardStatusView(Context context, AttributeSet attrs, int defStyle) {
65         super(context, attrs, defStyle);
66     }
67 
68     @Override
onFinishInflate()69     protected void onFinishInflate() {
70         super.onFinishInflate();
71         mStatusViewContainer = findViewById(R.id.status_view_container);
72 
73         mClockView = findViewById(R.id.keyguard_clock_container);
74         if (KeyguardClockAccessibilityDelegate.isNeeded(mContext)) {
75             mClockView.setAccessibilityDelegate(new KeyguardClockAccessibilityDelegate(mContext));
76         }
77 
78         mKeyguardSlice = findViewById(R.id.keyguard_slice_view);
79 
80         mMediaHostContainer = findViewById(R.id.status_view_media_container);
81 
82         updateDark();
83     }
84 
setDarkAmount(float darkAmount)85     void setDarkAmount(float darkAmount) {
86         if (mDarkAmount == darkAmount) {
87             return;
88         }
89         mDarkAmount = darkAmount;
90         CrossFadeHelper.fadeOut(mMediaHostContainer, darkAmount);
91         updateDark();
92     }
93 
updateDark()94     void updateDark() {
95         mKeyguardSlice.setDarkAmount(mDarkAmount);
96     }
97 
98     /** Sets a translationY value on every child view except for the media view. */
setChildrenTranslationY(float translationY, boolean excludeMedia)99     public void setChildrenTranslationY(float translationY, boolean excludeMedia) {
100         setChildrenTranslationYExcluding(translationY,
101                 excludeMedia ? Set.of(mMediaHostContainer) : emptySet());
102     }
103 
104     /** Sets a translationY value on every view except for the views in the provided set. */
setChildrenTranslationYExcluding(float translationY, Set<View> excludedViews)105     private void setChildrenTranslationYExcluding(float translationY, Set<View> excludedViews) {
106         for (int i = 0; i < mStatusViewContainer.getChildCount(); i++) {
107             final View child = mStatusViewContainer.getChildAt(i);
108 
109             if (!excludedViews.contains(child)) {
110                 child.setTranslationY(translationY);
111             }
112         }
113     }
114 
115     @Override
dispatchTouchEvent(MotionEvent ev)116     public boolean dispatchTouchEvent(MotionEvent ev) {
117         return TouchLogger.logDispatchTouch(TAG, ev, super.dispatchTouchEvent(ev));
118     }
119 
dump(PrintWriter pw, String[] args)120     public void dump(PrintWriter pw, String[] args) {
121         pw.println("KeyguardStatusView:");
122         pw.println("  mDarkAmount: " + mDarkAmount);
123         pw.println("  visibility: " + getVisibility());
124         if (mClockView != null) {
125             mClockView.dump(pw, args);
126         }
127         if (mKeyguardSlice != null) {
128             mKeyguardSlice.dump(pw, args);
129         }
130     }
131 
132     @Override
animate()133     public ViewPropertyAnimator animate() {
134         if (Build.IS_DEBUGGABLE) {
135             throw new IllegalArgumentException(
136                     "KeyguardStatusView does not support ViewPropertyAnimator. "
137                             + "Use PropertyAnimator instead.");
138         }
139         return super.animate();
140     }
141 
142     @Override
onMeasure(int widthMeasureSpec, int heightMeasureSpec)143     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
144         Trace.beginSection("KeyguardStatusView#onMeasure");
145         super.onMeasure(widthMeasureSpec, heightMeasureSpec);
146         Trace.endSection();
147     }
148 
149     @Override
onSetAlpha(int alpha)150     protected boolean onSetAlpha(int alpha) {
151         mDrawAlpha = alpha;
152         return true;
153     }
154 
155     @Override
dispatchDraw(Canvas canvas)156     protected void dispatchDraw(Canvas canvas) {
157         KeyguardClockFrame.saveCanvasAlpha(
158                 this, canvas, mDrawAlpha,
159                 c -> {
160                     super.dispatchDraw(c);
161                     return kotlin.Unit.INSTANCE;
162                 });
163     }
164 }
165