1 /*
2  * Copyright (C) 2013 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.phone;
18 
19 import android.graphics.Rect;
20 import android.graphics.drawable.Icon;
21 import android.os.Bundle;
22 import android.os.UserHandle;
23 import android.util.Log;
24 import android.view.Gravity;
25 import android.view.View;
26 import android.view.ViewGroup;
27 import android.widget.LinearLayout;
28 
29 import com.android.internal.statusbar.StatusBarIcon;
30 import com.android.systemui.DemoMode;
31 import com.android.systemui.R;
32 import com.android.systemui.plugins.DarkIconDispatcher;
33 import com.android.systemui.plugins.DarkIconDispatcher.DarkReceiver;
34 import com.android.systemui.statusbar.StatusBarIconView;
35 import com.android.systemui.statusbar.StatusBarMobileView;
36 import com.android.systemui.statusbar.StatusBarWifiView;
37 import com.android.systemui.statusbar.StatusIconDisplayable;
38 import com.android.systemui.statusbar.phone.StatusBarSignalPolicy.MobileIconState;
39 import com.android.systemui.statusbar.phone.StatusBarSignalPolicy.WifiIconState;
40 
41 import java.util.ArrayList;
42 
43 public class DemoStatusIcons extends StatusIconContainer implements DemoMode, DarkReceiver {
44     private static final String TAG = "DemoStatusIcons";
45 
46     private final LinearLayout mStatusIcons;
47     private final ArrayList<StatusBarMobileView> mMobileViews = new ArrayList<>();
48     private final int mIconSize;
49 
50     private StatusBarWifiView mWifiView;
51     private boolean mDemoMode;
52     private int mColor;
53 
DemoStatusIcons(LinearLayout statusIcons, int iconSize)54     public DemoStatusIcons(LinearLayout statusIcons, int iconSize) {
55         super(statusIcons.getContext());
56         mStatusIcons = statusIcons;
57         mIconSize = iconSize;
58         mColor = DarkIconDispatcher.DEFAULT_ICON_TINT;
59 
60         if (statusIcons instanceof StatusIconContainer) {
61             setShouldRestrictIcons(((StatusIconContainer) statusIcons).isRestrictingIcons());
62         } else {
63             setShouldRestrictIcons(false);
64         }
65         setLayoutParams(mStatusIcons.getLayoutParams());
66         setPadding(mStatusIcons.getPaddingLeft(),mStatusIcons.getPaddingTop(),
67                 mStatusIcons.getPaddingRight(), mStatusIcons.getPaddingBottom());
68         setOrientation(mStatusIcons.getOrientation());
69         setGravity(Gravity.CENTER_VERTICAL); // no LL.getGravity()
70         ViewGroup p = (ViewGroup) mStatusIcons.getParent();
71         p.addView(this, p.indexOfChild(mStatusIcons));
72     }
73 
remove()74     public void remove() {
75         mMobileViews.clear();
76         ((ViewGroup) getParent()).removeView(this);
77     }
78 
setColor(int color)79     public void setColor(int color) {
80         mColor = color;
81         updateColors();
82     }
83 
updateColors()84     private void updateColors() {
85         for (int i = 0; i < getChildCount(); i++) {
86             StatusIconDisplayable child = (StatusIconDisplayable) getChildAt(i);
87             child.setStaticDrawableColor(mColor);
88             child.setDecorColor(mColor);
89         }
90     }
91 
92     @Override
dispatchDemoCommand(String command, Bundle args)93     public void dispatchDemoCommand(String command, Bundle args) {
94         if (!mDemoMode && command.equals(COMMAND_ENTER)) {
95             mDemoMode = true;
96             mStatusIcons.setVisibility(View.GONE);
97             setVisibility(View.VISIBLE);
98         } else if (mDemoMode && command.equals(COMMAND_EXIT)) {
99             mDemoMode = false;
100             mStatusIcons.setVisibility(View.VISIBLE);
101             setVisibility(View.GONE);
102         } else if (mDemoMode && command.equals(COMMAND_STATUS)) {
103             String volume = args.getString("volume");
104             if (volume != null) {
105                 int iconId = volume.equals("vibrate") ? R.drawable.stat_sys_ringer_vibrate
106                         : 0;
107                 updateSlot("volume", null, iconId);
108             }
109             String zen = args.getString("zen");
110             if (zen != null) {
111                 int iconId = zen.equals("dnd") ? R.drawable.stat_sys_dnd : 0;
112                 updateSlot("zen", null, iconId);
113             }
114             String bt = args.getString("bluetooth");
115             if (bt != null) {
116                 int iconId = bt.equals("connected")
117                         ? R.drawable.stat_sys_data_bluetooth_connected : 0;
118                 updateSlot("bluetooth", null, iconId);
119             }
120             String location = args.getString("location");
121             if (location != null) {
122                 int iconId = location.equals("show") ? PhoneStatusBarPolicy.LOCATION_STATUS_ICON_ID
123                         : 0;
124                 updateSlot("location", null, iconId);
125             }
126             String alarm = args.getString("alarm");
127             if (alarm != null) {
128                 int iconId = alarm.equals("show") ? R.drawable.stat_sys_alarm
129                         : 0;
130                 updateSlot("alarm_clock", null, iconId);
131             }
132             String tty = args.getString("tty");
133             if (tty != null) {
134                 int iconId = tty.equals("show") ? R.drawable.stat_sys_tty_mode
135                         : 0;
136                 updateSlot("tty", null, iconId);
137             }
138             String mute = args.getString("mute");
139             if (mute != null) {
140                 int iconId = mute.equals("show") ? android.R.drawable.stat_notify_call_mute
141                         : 0;
142                 updateSlot("mute", null, iconId);
143             }
144             String speakerphone = args.getString("speakerphone");
145             if (speakerphone != null) {
146                 int iconId = speakerphone.equals("show") ? android.R.drawable.stat_sys_speakerphone
147                         : 0;
148                 updateSlot("speakerphone", null, iconId);
149             }
150             String cast = args.getString("cast");
151             if (cast != null) {
152                 int iconId = cast.equals("show") ? R.drawable.stat_sys_cast : 0;
153                 updateSlot("cast", null, iconId);
154             }
155             String hotspot = args.getString("hotspot");
156             if (hotspot != null) {
157                 int iconId = hotspot.equals("show") ? R.drawable.stat_sys_hotspot : 0;
158                 updateSlot("hotspot", null, iconId);
159             }
160         }
161     }
162 
163     /// Can only be used to update non-signal related slots
updateSlot(String slot, String iconPkg, int iconId)164     private void updateSlot(String slot, String iconPkg, int iconId) {
165         if (!mDemoMode) return;
166         if (iconPkg == null) {
167             iconPkg = mContext.getPackageName();
168         }
169         int removeIndex = -1;
170         for (int i = 0; i < getChildCount(); i++) {
171             View child = getChildAt(i);
172             if (!(child instanceof StatusBarIconView)) {
173                 continue;
174             }
175             StatusBarIconView v = (StatusBarIconView) child;
176             if (slot.equals(v.getTag())) {
177                 if (iconId == 0) {
178                     removeIndex = i;
179                     break;
180                 } else {
181                     StatusBarIcon icon = v.getStatusBarIcon();
182                     icon.visible = true;
183                     icon.icon = Icon.createWithResource(icon.icon.getResPackage(), iconId);
184                     v.set(icon);
185                     v.updateDrawable();
186                     return;
187                 }
188             }
189         }
190         if (iconId == 0) {
191             if (removeIndex != -1) {
192                 removeViewAt(removeIndex);
193             }
194             return;
195         }
196         StatusBarIcon icon = new StatusBarIcon(iconPkg, UserHandle.SYSTEM, iconId, 0, 0, "Demo");
197         icon.visible = true;
198         StatusBarIconView v = new StatusBarIconView(getContext(), slot, null, false);
199         v.setTag(slot);
200         v.set(icon);
201         v.setStaticDrawableColor(mColor);
202         v.setDecorColor(mColor);
203         addView(v, 0, createLayoutParams());
204     }
205 
addDemoWifiView(WifiIconState state)206     public void addDemoWifiView(WifiIconState state) {
207         Log.d(TAG, "addDemoWifiView: ");
208         StatusBarWifiView view = StatusBarWifiView.fromContext(mContext, state.slot);
209 
210         int viewIndex = getChildCount();
211         // If we have mobile views, put wifi before them
212         for (int i = 0; i < getChildCount(); i++) {
213             View child = getChildAt(i);
214             if (child instanceof StatusBarMobileView) {
215                 viewIndex = i;
216                 break;
217             }
218         }
219 
220         mWifiView = view;
221         mWifiView.applyWifiState(state);
222         mWifiView.setStaticDrawableColor(mColor);
223         addView(view, viewIndex, createLayoutParams());
224     }
225 
updateWifiState(WifiIconState state)226     public void updateWifiState(WifiIconState state) {
227         Log.d(TAG, "updateWifiState: ");
228         if (mWifiView == null) {
229             addDemoWifiView(state);
230         } else {
231             mWifiView.applyWifiState(state);
232         }
233     }
234 
addMobileView(MobileIconState state)235     public void addMobileView(MobileIconState state) {
236         Log.d(TAG, "addMobileView: ");
237         StatusBarMobileView view = StatusBarMobileView.fromContext(mContext, state.slot);
238 
239         view.applyMobileState(state);
240         view.setStaticDrawableColor(mColor);
241 
242         // mobile always goes at the end
243         mMobileViews.add(view);
244         addView(view, getChildCount(), createLayoutParams());
245     }
246 
updateMobileState(MobileIconState state)247     public void updateMobileState(MobileIconState state) {
248         Log.d(TAG, "updateMobileState: ");
249         // If the view for this subId exists already, use it
250         for (int i = 0; i < mMobileViews.size(); i++) {
251             StatusBarMobileView view = mMobileViews.get(i);
252             if (view.getState().subId == state.subId) {
253                 view.applyMobileState(state);
254                 return;
255             }
256         }
257 
258         // Else we have to add it
259         addMobileView(state);
260     }
261 
onRemoveIcon(StatusIconDisplayable view)262     public void onRemoveIcon(StatusIconDisplayable view) {
263         if (view.getSlot().equals("wifi")) {
264             removeView(mWifiView);
265             mWifiView = null;
266         } else {
267             StatusBarMobileView mobileView = matchingMobileView(view);
268             if (mobileView != null) {
269                 removeView(mobileView);
270                 mMobileViews.remove(mobileView);
271             }
272         }
273     }
274 
matchingMobileView(StatusIconDisplayable otherView)275     private StatusBarMobileView matchingMobileView(StatusIconDisplayable otherView) {
276         if (!(otherView instanceof StatusBarMobileView)) {
277             return null;
278         }
279 
280         StatusBarMobileView v = (StatusBarMobileView) otherView;
281         for (StatusBarMobileView view : mMobileViews) {
282             if (view.getState().subId == v.getState().subId) {
283                 return view;
284             }
285         }
286 
287         return null;
288     }
289 
createLayoutParams()290     private LayoutParams createLayoutParams() {
291         return new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, mIconSize);
292     }
293 
294     @Override
onDarkChanged(Rect area, float darkIntensity, int tint)295     public void onDarkChanged(Rect area, float darkIntensity, int tint) {
296         setColor(DarkIconDispatcher.getTint(area, mStatusIcons, tint));
297 
298         if (mWifiView != null) {
299             mWifiView.onDarkChanged(area, darkIntensity, tint);
300         }
301         for (StatusBarMobileView view : mMobileViews) {
302             view.onDarkChanged(area, darkIntensity, tint);
303         }
304     }
305 }
306