1 /*
2  * Copyright (C) 2018 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;
18 
19 import static com.android.systemui.statusbar.StatusBarIconView.STATE_DOT;
20 import static com.android.systemui.statusbar.StatusBarIconView.STATE_HIDDEN;
21 import static com.android.systemui.statusbar.StatusBarIconView.STATE_ICON;
22 import static com.android.systemui.statusbar.policy.DarkIconDispatcher.getTint;
23 import static com.android.systemui.statusbar.policy.DarkIconDispatcher.isInArea;
24 
25 import android.content.Context;
26 import android.content.res.ColorStateList;
27 import android.graphics.Rect;
28 import android.graphics.drawable.Drawable;
29 import android.util.AttributeSet;
30 import android.util.Log;
31 import android.view.ContextThemeWrapper;
32 import android.view.Gravity;
33 import android.view.LayoutInflater;
34 import android.view.View;
35 import android.view.ViewGroup;
36 import android.view.ViewGroup.LayoutParams;
37 import android.widget.FrameLayout;
38 import android.widget.ImageView;
39 
40 import android.widget.LinearLayout;
41 import com.android.keyguard.AlphaOptimizedLinearLayout;
42 import com.android.settingslib.Utils;
43 import com.android.systemui.R;
44 import com.android.systemui.statusbar.phone.StatusBarSignalPolicy.WifiIconState;
45 import com.android.systemui.statusbar.policy.DarkIconDispatcher.DarkReceiver;
46 
47 /**
48  * Start small: StatusBarWifiView will be able to layout from a WifiIconState
49  */
50 public class StatusBarWifiView extends FrameLayout implements DarkReceiver,
51         StatusIconDisplayable {
52     private static final String TAG = "StatusBarWifiView";
53 
54     /// Used to show etc dots
55     private StatusBarIconView mDotView;
56     /// Contains the main icon layout
57     private LinearLayout mWifiGroup;
58     private ImageView mWifiIcon;
59     private ImageView mIn;
60     private ImageView mOut;
61     private View mInoutContainer;
62     private View mSignalSpacer;
63     private View mAirplaneSpacer;
64     private WifiIconState mState;
65     private String mSlot;
66     private float mDarkIntensity = 0;
67     private int mVisibleState = -1;
68 
69     private ContextThemeWrapper mDarkContext;
70     private ContextThemeWrapper mLightContext;
71 
fromContext(Context context, String slot)72     public static StatusBarWifiView fromContext(Context context, String slot) {
73         LayoutInflater inflater = LayoutInflater.from(context);
74         StatusBarWifiView v = (StatusBarWifiView) inflater.inflate(R.layout.status_bar_wifi_group, null);
75         v.setSlot(slot);
76         v.init();
77         v.setVisibleState(STATE_ICON);
78         return v;
79     }
80 
StatusBarWifiView(Context context)81     public StatusBarWifiView(Context context) {
82         super(context);
83     }
84 
StatusBarWifiView(Context context, AttributeSet attrs)85     public StatusBarWifiView(Context context, AttributeSet attrs) {
86         super(context, attrs);
87     }
88 
StatusBarWifiView(Context context, AttributeSet attrs, int defStyleAttr)89     public StatusBarWifiView(Context context, AttributeSet attrs, int defStyleAttr) {
90         super(context, attrs, defStyleAttr);
91     }
92 
StatusBarWifiView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes)93     public StatusBarWifiView(Context context, AttributeSet attrs, int defStyleAttr,
94             int defStyleRes) {
95         super(context, attrs, defStyleAttr, defStyleRes);
96     }
97 
setSlot(String slot)98     public void setSlot(String slot) {
99         mSlot = slot;
100     }
101 
102     @Override
setStaticDrawableColor(int color)103     public void setStaticDrawableColor(int color) {
104         ColorStateList list = ColorStateList.valueOf(color);
105         mWifiIcon.setImageTintList(list);
106         mIn.setImageTintList(list);
107         mOut.setImageTintList(list);
108         mDotView.setDecorColor(color);
109     }
110 
111     @Override
setDecorColor(int color)112     public void setDecorColor(int color) {
113         mDotView.setDecorColor(color);
114     }
115 
116     @Override
getSlot()117     public String getSlot() {
118         return mSlot;
119     }
120 
121     @Override
isIconVisible()122     public boolean isIconVisible() {
123         return mState != null && mState.visible;
124     }
125 
126     @Override
setVisibleState(int state)127     public void setVisibleState(int state) {
128         if (state == mVisibleState) {
129             return;
130         }
131         mVisibleState = state;
132 
133         switch (state) {
134             case STATE_ICON:
135                 mWifiGroup.setVisibility(View.VISIBLE);
136                 mDotView.setVisibility(View.GONE);
137                 break;
138             case STATE_DOT:
139                 mWifiGroup.setVisibility(View.GONE);
140                 mDotView.setVisibility(View.VISIBLE);
141                 break;
142             case STATE_HIDDEN:
143             default:
144                 mWifiGroup.setVisibility(View.GONE);
145                 mDotView.setVisibility(View.GONE);
146                 break;
147         }
148     }
149 
150     @Override
getVisibleState()151     public int getVisibleState() {
152         return mVisibleState;
153     }
154 
155     @Override
getDrawingRect(Rect outRect)156     public void getDrawingRect(Rect outRect) {
157         super.getDrawingRect(outRect);
158         float translationX = getTranslationX();
159         float translationY = getTranslationY();
160         outRect.left += translationX;
161         outRect.right += translationX;
162         outRect.top += translationY;
163         outRect.bottom += translationY;
164     }
165 
init()166     private void init() {
167         int dualToneLightTheme = Utils.getThemeAttr(mContext, R.attr.lightIconTheme);
168         int dualToneDarkTheme = Utils.getThemeAttr(mContext, R.attr.darkIconTheme);
169         mLightContext = new ContextThemeWrapper(mContext, dualToneLightTheme);
170         mDarkContext = new ContextThemeWrapper(mContext, dualToneDarkTheme);
171 
172         mWifiGroup = findViewById(R.id.wifi_group);
173         mWifiIcon = findViewById(R.id.wifi_signal);
174         mIn = findViewById(R.id.wifi_in);
175         mOut = findViewById(R.id.wifi_out);
176         mSignalSpacer = findViewById(R.id.wifi_signal_spacer);
177         mAirplaneSpacer = findViewById(R.id.wifi_airplane_spacer);
178         mInoutContainer = findViewById(R.id.inout_container);
179 
180         initDotView();
181     }
182 
initDotView()183     private void initDotView() {
184         mDotView = new StatusBarIconView(mContext, mSlot, null);
185         mDotView.setVisibleState(STATE_DOT);
186 
187         int width = mContext.getResources().getDimensionPixelSize(R.dimen.status_bar_icon_size);
188         LayoutParams lp = new LayoutParams(width, width);
189         lp.gravity = Gravity.CENTER_VERTICAL | Gravity.START;
190         addView(mDotView, lp);
191     }
192 
applyWifiState(WifiIconState state)193     public void applyWifiState(WifiIconState state) {
194         if (state == null) {
195             setVisibility(View.GONE);
196             mState = null;
197             return;
198         }
199 
200         if (mState == null) {
201             mState = state.copy();
202             initViewState();
203         }
204 
205         if (!mState.equals(state)) {
206             updateState(state.copy());
207         }
208     }
209 
updateState(WifiIconState state)210     private void updateState(WifiIconState state) {
211         setContentDescription(state.contentDescription);
212         if (mState.resId != state.resId && state.resId >= 0) {
213             NeutralGoodDrawable drawable = NeutralGoodDrawable
214                     .create(mLightContext, mDarkContext, state.resId);
215             drawable.setDarkIntensity(mDarkIntensity);
216             mWifiIcon.setImageDrawable(drawable);
217         }
218 
219         mIn.setVisibility(state.activityIn ? View.VISIBLE : View.GONE);
220         mOut.setVisibility(state.activityOut ? View.VISIBLE : View.GONE);
221         mInoutContainer.setVisibility(
222                 (state.activityIn || state.activityOut) ? View.VISIBLE : View.GONE);
223         mAirplaneSpacer.setVisibility(state.airplaneSpacerVisible ? View.VISIBLE : View.GONE);
224         mSignalSpacer.setVisibility(state.signalSpacerVisible ? View.VISIBLE : View.GONE);
225         if (mState.visible != state.visible) {
226             setVisibility(state.visible ? View.VISIBLE : View.GONE);
227         }
228 
229         mState = state;
230     }
231 
initViewState()232     private void initViewState() {
233         setContentDescription(mState.contentDescription);
234         if (mState.resId >= 0) {
235             NeutralGoodDrawable drawable = NeutralGoodDrawable.create(
236                     mLightContext, mDarkContext, mState.resId);
237             drawable.setDarkIntensity(mDarkIntensity);
238             mWifiIcon.setImageDrawable(drawable);
239         }
240 
241         mIn.setVisibility(mState.activityIn ? View.VISIBLE : View.GONE);
242         mOut.setVisibility(mState.activityOut ? View.VISIBLE : View.GONE);
243         mInoutContainer.setVisibility(
244                 (mState.activityIn || mState.activityOut) ? View.VISIBLE : View.GONE);
245         mAirplaneSpacer.setVisibility(mState.airplaneSpacerVisible ? View.VISIBLE : View.GONE);
246         mSignalSpacer.setVisibility(mState.signalSpacerVisible ? View.VISIBLE : View.GONE);
247         setVisibility(mState.visible ? View.VISIBLE : View.GONE);
248     }
249 
250     @Override
onDarkChanged(Rect area, float darkIntensity, int tint)251     public void onDarkChanged(Rect area, float darkIntensity, int tint) {
252         if (!isInArea(area, this)) {
253             return;
254         }
255         mDarkIntensity = darkIntensity;
256         Drawable d = mWifiIcon.getDrawable();
257         if (d instanceof NeutralGoodDrawable) {
258             ((NeutralGoodDrawable)d).setDarkIntensity(darkIntensity);
259         }
260         mIn.setImageTintList(ColorStateList.valueOf(getTint(area, this, tint)));
261         mOut.setImageTintList(ColorStateList.valueOf(getTint(area, this, tint)));
262         mDotView.setDecorColor(tint);
263         mDotView.setIconColor(tint, false);
264     }
265 
266 
267     @Override
toString()268     public String toString() {
269         return "StatusBarWifiView(slot=" + mSlot + " state=" + mState + ")";
270     }
271 }
272