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