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.Color; 28 import android.graphics.Rect; 29 import android.util.AttributeSet; 30 import android.util.Log; 31 import android.view.Gravity; 32 import android.view.LayoutInflater; 33 import android.view.View; 34 import android.widget.FrameLayout; 35 import android.widget.ImageView; 36 37 import android.widget.LinearLayout; 38 import com.android.internal.annotations.VisibleForTesting; 39 import com.android.keyguard.AlphaOptimizedLinearLayout; 40 import com.android.settingslib.graph.SignalDrawable; 41 import com.android.systemui.R; 42 import com.android.systemui.statusbar.phone.StatusBarSignalPolicy.MobileIconState; 43 import com.android.systemui.statusbar.policy.DarkIconDispatcher.DarkReceiver; 44 45 public class StatusBarMobileView extends FrameLayout implements DarkReceiver, 46 StatusIconDisplayable { 47 private static final String TAG = "StatusBarMobileView"; 48 49 /// Used to show etc dots 50 private StatusBarIconView mDotView; 51 /// The main icon view 52 private LinearLayout mMobileGroup; 53 private String mSlot; 54 private MobileIconState mState; 55 private SignalDrawable mMobileDrawable; 56 private View mInoutContainer; 57 private ImageView mIn; 58 private ImageView mOut; 59 private ImageView mMobile, mMobileType, mMobileRoaming; 60 private View mMobileRoamingSpace; 61 private int mVisibleState = -1; 62 63 public static StatusBarMobileView fromContext(Context context, String slot) { 64 LayoutInflater inflater = LayoutInflater.from(context); 65 StatusBarMobileView v = (StatusBarMobileView) 66 inflater.inflate(R.layout.status_bar_mobile_signal_group, null); 67 68 v.setSlot(slot); 69 v.init(); 70 v.setVisibleState(STATE_ICON); 71 return v; 72 } 73 74 public StatusBarMobileView(Context context) { 75 super(context); 76 } 77 78 public StatusBarMobileView(Context context, AttributeSet attrs) { 79 super(context, attrs); 80 } 81 82 public StatusBarMobileView(Context context, AttributeSet attrs, int defStyleAttr) { 83 super(context, attrs, defStyleAttr); 84 } 85 86 public StatusBarMobileView(Context context, AttributeSet attrs, int defStyleAttr, 87 int defStyleRes) { 88 super(context, attrs, defStyleAttr, defStyleRes); 89 } 90 91 @Override 92 public void getDrawingRect(Rect outRect) { 93 super.getDrawingRect(outRect); 94 float translationX = getTranslationX(); 95 float translationY = getTranslationY(); 96 outRect.left += translationX; 97 outRect.right += translationX; 98 outRect.top += translationY; 99 outRect.bottom += translationY; 100 } 101 102 private void init() { 103 mMobileGroup = findViewById(R.id.mobile_group); 104 mMobile = findViewById(R.id.mobile_signal); 105 mMobileType = findViewById(R.id.mobile_type); 106 mMobileRoaming = findViewById(R.id.mobile_roaming); 107 mMobileRoamingSpace = findViewById(R.id.mobile_roaming_space); 108 mIn = findViewById(R.id.mobile_in); 109 mOut = findViewById(R.id.mobile_out); 110 mInoutContainer = findViewById(R.id.inout_container); 111 112 mMobileDrawable = new SignalDrawable(getContext()); 113 mMobile.setImageDrawable(mMobileDrawable); 114 115 initDotView(); 116 } 117 118 private void initDotView() { 119 mDotView = new StatusBarIconView(mContext, mSlot, null); 120 mDotView.setVisibleState(STATE_DOT); 121 122 int width = mContext.getResources().getDimensionPixelSize(R.dimen.status_bar_icon_size); 123 LayoutParams lp = new LayoutParams(width, width); 124 lp.gravity = Gravity.CENTER_VERTICAL | Gravity.START; 125 addView(mDotView, lp); 126 } 127 128 public void applyMobileState(MobileIconState state) { 129 if (state == null) { 130 setVisibility(View.GONE); 131 mState = null; 132 return; 133 } 134 135 if (mState == null) { 136 mState = state.copy(); 137 initViewState(); 138 return; 139 } 140 141 if (!mState.equals(state)) { 142 updateState(state.copy()); 143 } 144 } 145 146 private void initViewState() { 147 setContentDescription(mState.contentDescription); 148 if (!mState.visible) { 149 mMobileGroup.setVisibility(View.GONE); 150 } else { 151 mMobileGroup.setVisibility(View.VISIBLE); 152 } 153 mMobileDrawable.setLevel(mState.strengthId); 154 if (mState.typeId > 0) { 155 mMobileType.setContentDescription(mState.typeContentDescription); 156 mMobileType.setImageResource(mState.typeId); 157 mMobileType.setVisibility(View.VISIBLE); 158 } else { 159 mMobileType.setVisibility(View.GONE); 160 } 161 162 mMobileRoaming.setVisibility(mState.roaming ? View.VISIBLE : View.GONE); 163 mMobileRoamingSpace.setVisibility(mState.roaming ? View.VISIBLE : View.GONE); 164 mIn.setVisibility(mState.activityIn ? View.VISIBLE : View.GONE); 165 mOut.setVisibility(mState.activityIn ? View.VISIBLE : View.GONE); 166 mInoutContainer.setVisibility((mState.activityIn || mState.activityOut) 167 ? View.VISIBLE : View.GONE); 168 } 169 170 private void updateState(MobileIconState state) { 171 setContentDescription(state.contentDescription); 172 if (mState.visible != state.visible) { 173 mMobileGroup.setVisibility(state.visible ? View.VISIBLE : View.GONE); 174 } 175 if (mState.strengthId != state.strengthId) { 176 mMobileDrawable.setLevel(state.strengthId); 177 } 178 if (mState.typeId != state.typeId) { 179 if (state.typeId != 0) { 180 mMobileType.setContentDescription(state.typeContentDescription); 181 mMobileType.setImageResource(state.typeId); 182 mMobileType.setVisibility(View.VISIBLE); 183 } else { 184 mMobileType.setVisibility(View.GONE); 185 } 186 } 187 188 mMobileRoaming.setVisibility(state.roaming ? View.VISIBLE : View.GONE); 189 mMobileRoamingSpace.setVisibility(state.roaming ? View.VISIBLE : View.GONE); 190 mIn.setVisibility(state.activityIn ? View.VISIBLE : View.GONE); 191 mOut.setVisibility(state.activityIn ? View.VISIBLE : View.GONE); 192 mInoutContainer.setVisibility((state.activityIn || state.activityOut) 193 ? View.VISIBLE : View.GONE); 194 195 mState = state; 196 } 197 198 @Override 199 public void onDarkChanged(Rect area, float darkIntensity, int tint) { 200 if (!isInArea(area, this)) { 201 return; 202 } 203 mMobileDrawable.setDarkIntensity(darkIntensity); 204 ColorStateList color = ColorStateList.valueOf(getTint(area, this, tint)); 205 mIn.setImageTintList(color); 206 mOut.setImageTintList(color); 207 mMobileType.setImageTintList(color); 208 mMobileRoaming.setImageTintList(color); 209 mDotView.setDecorColor(tint); 210 mDotView.setIconColor(tint, false); 211 } 212 213 @Override 214 public String getSlot() { 215 return mSlot; 216 } 217 218 public void setSlot(String slot) { 219 mSlot = slot; 220 } 221 222 @Override 223 public void setStaticDrawableColor(int color) { 224 ColorStateList list = ColorStateList.valueOf(color); 225 float intensity = color == Color.WHITE ? 0 : 1; 226 mMobileDrawable.setDarkIntensity(intensity); 227 228 mIn.setImageTintList(list); 229 mOut.setImageTintList(list); 230 mMobileType.setImageTintList(list); 231 mMobileRoaming.setImageTintList(list); 232 mDotView.setDecorColor(color); 233 } 234 235 @Override 236 public void setDecorColor(int color) { 237 mDotView.setDecorColor(color); 238 } 239 240 @Override 241 public boolean isIconVisible() { 242 return mState.visible; 243 } 244 245 @Override 246 public void setVisibleState(int state) { 247 if (state == mVisibleState) { 248 return; 249 } 250 251 mVisibleState = state; 252 switch (state) { 253 case STATE_ICON: 254 mMobileGroup.setVisibility(View.VISIBLE); 255 mDotView.setVisibility(View.GONE); 256 break; 257 case STATE_DOT: 258 mMobileGroup.setVisibility(View.INVISIBLE); 259 mDotView.setVisibility(View.VISIBLE); 260 break; 261 case STATE_HIDDEN: 262 default: 263 mMobileGroup.setVisibility(View.INVISIBLE); 264 mDotView.setVisibility(View.INVISIBLE); 265 break; 266 } 267 } 268 269 @Override 270 public int getVisibleState() { 271 return mVisibleState; 272 } 273 274 @VisibleForTesting 275 public MobileIconState getState() { 276 return mState; 277 } 278 279 @Override 280 public String toString() { 281 return "StatusBarMobileView(slot=" + mSlot + " state=" + mState + ")"; 282 } 283 } 284