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