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.view.ViewGroup.LayoutParams;
28 import android.widget.LinearLayout;
29 
30 import com.android.internal.statusbar.StatusBarIcon;
31 import com.android.systemui.DemoMode;
32 import com.android.systemui.R;
33 import com.android.systemui.statusbar.StatusIconDisplayable;
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.phone.StatusBarSignalPolicy.MobileIconState;
38 import com.android.systemui.statusbar.phone.StatusBarSignalPolicy.WifiIconState;
39 import com.android.systemui.statusbar.policy.DarkIconDispatcher;
40 import com.android.systemui.statusbar.policy.DarkIconDispatcher.DarkReceiver;
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("important") ? R.drawable.stat_sys_zen_important
112                         : zen.equals("none") ? R.drawable.stat_sys_zen_none
113                         : 0;
114                 updateSlot("zen", null, iconId);
115             }
116             String bt = args.getString("bluetooth");
117             if (bt != null) {
118                 int iconId = bt.equals("disconnected") ? R.drawable.stat_sys_data_bluetooth
119                         : bt.equals("connected") ? R.drawable.stat_sys_data_bluetooth_connected
120                         : 0;
121                 updateSlot("bluetooth", null, iconId);
122             }
123             String location = args.getString("location");
124             if (location != null) {
125                 int iconId = location.equals("show") ? PhoneStatusBarPolicy.LOCATION_STATUS_ICON_ID
126                         : 0;
127                 updateSlot("location", null, iconId);
128             }
129             String alarm = args.getString("alarm");
130             if (alarm != null) {
131                 int iconId = alarm.equals("show") ? R.drawable.stat_sys_alarm
132                         : 0;
133                 updateSlot("alarm_clock", null, iconId);
134             }
135             String tty = args.getString("tty");
136             if (tty != null) {
137                 int iconId = tty.equals("show") ? R.drawable.stat_sys_tty_mode
138                         : 0;
139                 updateSlot("tty", null, iconId);
140             }
141             String mute = args.getString("mute");
142             if (mute != null) {
143                 int iconId = mute.equals("show") ? android.R.drawable.stat_notify_call_mute
144                         : 0;
145                 updateSlot("mute", null, iconId);
146             }
147             String speakerphone = args.getString("speakerphone");
148             if (speakerphone != null) {
149                 int iconId = speakerphone.equals("show") ? android.R.drawable.stat_sys_speakerphone
150                         : 0;
151                 updateSlot("speakerphone", null, iconId);
152             }
153             String cast = args.getString("cast");
154             if (cast != null) {
155                 int iconId = cast.equals("show") ? R.drawable.stat_sys_cast : 0;
156                 updateSlot("cast", null, iconId);
157             }
158             String hotspot = args.getString("hotspot");
159             if (hotspot != null) {
160                 int iconId = hotspot.equals("show") ? R.drawable.stat_sys_hotspot : 0;
161                 updateSlot("hotspot", null, iconId);
162             }
163         }
164     }
165 
166     /// Can only be used to update non-signal related slots
updateSlot(String slot, String iconPkg, int iconId)167     private void updateSlot(String slot, String iconPkg, int iconId) {
168         if (!mDemoMode) return;
169         if (iconPkg == null) {
170             iconPkg = mContext.getPackageName();
171         }
172         int removeIndex = -1;
173         for (int i = 0; i < getChildCount(); i++) {
174             View child = getChildAt(i);
175             if (!(child instanceof StatusBarIconView)) {
176                 continue;
177             }
178             StatusBarIconView v = (StatusBarIconView) child;
179             if (slot.equals(v.getTag())) {
180                 if (iconId == 0) {
181                     removeIndex = i;
182                     break;
183                 } else {
184                     StatusBarIcon icon = v.getStatusBarIcon();
185                     icon.visible = true;
186                     icon.icon = Icon.createWithResource(icon.icon.getResPackage(), iconId);
187                     v.set(icon);
188                     v.updateDrawable();
189                     return;
190                 }
191             }
192         }
193         if (iconId == 0) {
194             if (removeIndex != -1) {
195                 removeViewAt(removeIndex);
196             }
197             return;
198         }
199         StatusBarIcon icon = new StatusBarIcon(iconPkg, UserHandle.SYSTEM, iconId, 0, 0, "Demo");
200         icon.visible = true;
201         StatusBarIconView v = new StatusBarIconView(getContext(), slot, null, false);
202         v.setTag(slot);
203         v.set(icon);
204         v.setStaticDrawableColor(mColor);
205         v.setDecorColor(mColor);
206         addView(v, 0, new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, mIconSize));
207     }
208 
addDemoWifiView(WifiIconState state)209     public void addDemoWifiView(WifiIconState state) {
210         Log.d(TAG, "addDemoWifiView: ");
211         StatusBarWifiView view = StatusBarWifiView.fromContext(mContext, state.slot);
212 
213         int viewIndex = getChildCount();
214         // If we have mobile views, put wifi before them
215         for (int i = 0; i < getChildCount(); i++) {
216             View child = getChildAt(i);
217             if (child instanceof StatusBarMobileView) {
218                 viewIndex = i;
219                 break;
220             }
221         }
222 
223         mWifiView = view;
224         mWifiView.applyWifiState(state);
225         mWifiView.setStaticDrawableColor(mColor);
226         addView(view, viewIndex);
227     }
228 
updateWifiState(WifiIconState state)229     public void updateWifiState(WifiIconState state) {
230         Log.d(TAG, "updateWifiState: ");
231         if (mWifiView == null) {
232             addDemoWifiView(state);
233         } else {
234             mWifiView.applyWifiState(state);
235         }
236     }
237 
addMobileView(MobileIconState state)238     public void addMobileView(MobileIconState state) {
239         Log.d(TAG, "addMobileView: ");
240         StatusBarMobileView view = StatusBarMobileView.fromContext(mContext, state.slot);
241 
242         view.applyMobileState(state);
243         view.setStaticDrawableColor(mColor);
244 
245         // mobile always goes at the end
246         mMobileViews.add(view);
247         addView(view, getChildCount());
248     }
249 
updateMobileState(MobileIconState state)250     public void updateMobileState(MobileIconState state) {
251         Log.d(TAG, "updateMobileState: ");
252         // If the view for this subId exists already, use it
253         for (int i = 0; i < mMobileViews.size(); i++) {
254             StatusBarMobileView view = mMobileViews.get(i);
255             if (view.getState().subId == state.subId) {
256                 view.applyMobileState(state);
257                 return;
258             }
259         }
260 
261         // Else we have to add it
262         addMobileView(state);
263     }
264 
onRemoveIcon(StatusIconDisplayable view)265     public void onRemoveIcon(StatusIconDisplayable view) {
266         if (view.getSlot().equals("wifi")) {
267             removeView(mWifiView);
268             mWifiView = null;
269         } else {
270             StatusBarMobileView mobileView = matchingMobileView(view);
271             if (mobileView != null) {
272                 removeView(mobileView);
273                 mMobileViews.remove(mobileView);
274             }
275         }
276     }
277 
matchingMobileView(StatusIconDisplayable otherView)278     private StatusBarMobileView matchingMobileView(StatusIconDisplayable otherView) {
279         if (!(otherView instanceof StatusBarMobileView)) {
280             return null;
281         }
282 
283         StatusBarMobileView v = (StatusBarMobileView) otherView;
284         for (StatusBarMobileView view : mMobileViews) {
285             if (view.getState().subId == v.getState().subId) {
286                 return view;
287             }
288         }
289 
290         return null;
291     }
292 
293     @Override
onDarkChanged(Rect area, float darkIntensity, int tint)294     public void onDarkChanged(Rect area, float darkIntensity, int tint) {
295         setColor(DarkIconDispatcher.getTint(area, mStatusIcons, tint));
296 
297         if (mWifiView != null) {
298             mWifiView.onDarkChanged(area, darkIntensity, tint);
299         }
300         for (StatusBarMobileView view : mMobileViews) {
301             view.onDarkChanged(area, darkIntensity, tint);
302         }
303     }
304 }
305