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