diff options
| author | 2017-06-21 19:31:22 +0000 | |
|---|---|---|
| committer | 2017-06-21 19:31:28 +0000 | |
| commit | 6a651f81b52dcdc6518f1fc138985365feae4bfb (patch) | |
| tree | 29f5e50010b0e210ffa5538c3e22a8be13a7d7d2 | |
| parent | e8dceabd98fede5d32b2b1c630819801c1d46e5e (diff) | |
| parent | 3d1aad64754828b0b5f98f2499f125fd4c2b9fbc (diff) | |
Merge "Fix mobile signal icon when in airplane mode" into oc-dev
4 files changed, 115 insertions, 6 deletions
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml index 4245b1183e08..f66a09e04192 100644 --- a/packages/SystemUI/res/values/dimens.xml +++ b/packages/SystemUI/res/values/dimens.xml @@ -776,4 +776,7 @@ <dimen name="qs_gutter_height">6dp</dimen> + <!-- Width of the hollow triangle for empty signal state --> + <dimen name="mobile_signal_empty_strokewidth">2dp</dimen> + </resources> diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java index b52414eeda34..fbcdf1acfc6f 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java @@ -140,7 +140,11 @@ public class CellularTile extends QSTileImpl<SignalState> { state.value = mDataController.isMobileDataSupported() && mDataController.isMobileDataEnabled(); state.icon = new SignalIcon(cb.mobileSignalIconId); - state.state = Tile.STATE_ACTIVE; + if (cb.airplaneModeEnabled) { + state.state = Tile.STATE_INACTIVE; + } else { + state.state = Tile.STATE_ACTIVE; + } } @Override diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SignalDrawable.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SignalDrawable.java index 0a638d84cb4a..983a79615304 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SignalDrawable.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SignalDrawable.java @@ -21,6 +21,7 @@ import android.annotation.Nullable; import android.content.Context; import android.graphics.Canvas; import android.graphics.ColorFilter; +import android.graphics.Matrix; import android.graphics.Paint; import android.graphics.Paint.Style; import android.graphics.Path; @@ -28,6 +29,7 @@ import android.graphics.Path.Direction; import android.graphics.Path.FillType; import android.graphics.Path.Op; import android.graphics.Rect; +import android.graphics.RectF; import android.graphics.drawable.Drawable; import android.os.Handler; import android.util.LayoutDirection; @@ -64,6 +66,7 @@ public class SignalDrawable extends Drawable { private static final int STATE_EMPTY = 1; private static final int STATE_CUT = 2; private static final int STATE_CARRIER_CHANGE = 3; + private static final int STATE_AIRPLANE = 4; private static final long DOT_DELAY = 1000; @@ -82,6 +85,13 @@ public class SignalDrawable extends Drawable { {-1.9f / VIEWPORT, -1.9f / VIEWPORT}, }; + // The easiest way to understand this is as if we set Style.STROKE and draw the triangle, + // but that is only theoretically right. Instead, draw the triangle and clip out a smaller + // one inset by this amount. + private final float mEmptyStrokeWidth; + private static final float INV_TAN = 1f / (float) Math.tan(Math.PI / 8f); + private final float mEmptyDiagInset; // == mEmptyStrokeWidth * INV_TAN + private final Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); private final Paint mForegroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG); private final int mDarkModeBackgroundColor; @@ -91,6 +101,10 @@ public class SignalDrawable extends Drawable { private final Path mFullPath = new Path(); private final Path mForegroundPath = new Path(); private final Path mXPath = new Path(); + // Cut out when STATE_EMPTY + private final Path mCutPath = new Path(); + // Draws the slash when in airplane mode + private final SlashArtist mSlash = new SlashArtist(); private final Handler mHandler; private float mOldDarkIntensity = -1; private float mNumLevels = 1; @@ -111,6 +125,12 @@ public class SignalDrawable extends Drawable { mLightModeFillColor = Utils.getDefaultColor(context, R.color.light_mode_icon_color_dual_tone_fill); mIntrinsicSize = context.getResources().getDimensionPixelSize(R.dimen.signal_icon_size); + + // mCutPath parameters + mEmptyStrokeWidth = context.getResources() + .getDimensionPixelSize(R.dimen.mobile_signal_empty_strokewidth); + mEmptyDiagInset = mEmptyStrokeWidth * INV_TAN; + mHandler = new Handler(); setDarkIntensity(0); } @@ -208,7 +228,7 @@ public class SignalDrawable extends Drawable { mFullPath.setFillType(FillType.WINDING); float width = getBounds().width(); float height = getBounds().height(); - float padding = (PAD * width); + float padding = Math.round(PAD * width); mFullPath.moveTo(width - padding, height - padding); mFullPath.lineTo(width - padding, padding); mFullPath.lineTo(padding, height - padding); @@ -241,10 +261,27 @@ public class SignalDrawable extends Drawable { mFullPath.rLineTo(0, cut); } - mPaint.setStyle(mState == STATE_EMPTY ? Style.STROKE : Style.FILL); - mForegroundPaint.setStyle(mState == STATE_EMPTY ? Style.STROKE : Style.FILL); - - if (mState != STATE_CARRIER_CHANGE) { + if (mState == STATE_EMPTY) { + // Cut out a smaller triangle from the center of mFullPath + mCutPath.reset(); + mCutPath.setFillType(FillType.WINDING); + mCutPath.moveTo(width - padding - mEmptyStrokeWidth, + height - padding - mEmptyStrokeWidth); + mCutPath.lineTo(width - padding - mEmptyStrokeWidth, padding + mEmptyDiagInset); + mCutPath.lineTo(padding + mEmptyDiagInset, height - padding - mEmptyStrokeWidth); + mCutPath.lineTo(width - padding - mEmptyStrokeWidth, + height - padding - mEmptyStrokeWidth); + + // In empty state, draw the full path as the foreground paint + mForegroundPath.set(mFullPath); + mFullPath.reset(); + mForegroundPath.op(mCutPath, Path.Op.DIFFERENCE); + } else if (mState == STATE_AIRPLANE) { + // Airplane mode is slashed, full-signal + mForegroundPath.set(mFullPath); + mFullPath.reset(); + mSlash.draw((int) height, (int) width, canvas, mForegroundPaint); + } else if (mState != STATE_CARRIER_CHANGE) { mForegroundPath.reset(); int sigWidth = Math.round(calcFit(mLevel / (mNumLevels - 1)) * (width - 2 * padding)); mForegroundPath.addRect(padding, padding, padding + sigWidth, height - padding, @@ -354,4 +391,65 @@ public class SignalDrawable extends Drawable { public static int getEmptyState(int numLevels) { return (STATE_EMPTY << STATE_SHIFT) | (numLevels << NUM_LEVEL_SHIFT); } + + public static int getAirplaneModeState(int numLevels) { + return (STATE_AIRPLANE << STATE_SHIFT) | (numLevels << NUM_LEVEL_SHIFT); + } + + private final class SlashArtist { + // These values are derived in un-rotated (vertical) orientation + private static final float SLASH_WIDTH = 1.8384776f; + private static final float SLASH_HEIGHT = 22f; + private static final float CENTER_X = 10.65f; + private static final float CENTER_Y = 15.869239f; + private static final float SCALE = 24f; + + // Bottom is derived during animation + private static final float LEFT = (CENTER_X - (SLASH_WIDTH / 2)) / SCALE; + private static final float TOP = (CENTER_Y - (SLASH_HEIGHT / 2)) / SCALE; + private static final float RIGHT = (CENTER_X + (SLASH_WIDTH / 2)) / SCALE; + private static final float BOTTOM = (CENTER_Y + (SLASH_HEIGHT / 2)) / SCALE; + // Draw the slash washington-monument style; rotate to no-u-turn style + private static final float ROTATION = -45f; + + private final Path mPath = new Path(); + private final RectF mSlashRect = new RectF(); + + void draw(int height, int width, @NonNull Canvas canvas, Paint paint) { + Matrix m = new Matrix(); + updateRect( + scale(LEFT, width), + scale(TOP, height), + scale(RIGHT, width), + scale(BOTTOM, height)); + + mPath.reset(); + // Draw the slash vertically + mPath.addRect(mSlashRect, Direction.CW); + m.setRotate(ROTATION, width / 2, height / 2); + mPath.transform(m); + canvas.drawPath(mPath, paint); + + // Rotate back to vertical, and draw the cut-out rect next to this one + m.setRotate(-ROTATION, width / 2, height / 2); + mPath.transform(m); + m.setTranslate(mSlashRect.width(), 0); + mPath.transform(m); + mPath.addRect(mSlashRect, Direction.CW); + m.setRotate(ROTATION, width / 2, height / 2); + mPath.transform(m); + canvas.clipOutPath(mPath); + } + + void updateRect(float left, float top, float right, float bottom) { + mSlashRect.left = left; + mSlashRect.top = top; + mSlashRect.right = right; + mSlashRect.bottom = bottom; + } + + private float scale(float frac, int width) { + return frac * width; + } + } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java index 67b5596e34c9..efce87177faa 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java @@ -254,6 +254,10 @@ public class MobileSignalController extends SignalController< @Override public int getQsCurrentIconId() { + if (mCurrentState.airplaneMode) { + return SignalDrawable.getAirplaneModeState(getNumLevels()); + } + return getCurrentIconId(); } |