14f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos/*
24f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos * Copyright (C) 2015 The Android Open Source Project
34f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos *
44f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos * Licensed under the Apache License, Version 2.0 (the "License");
54f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos * you may not use this file except in compliance with the License.
64f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos * You may obtain a copy of the License at
74f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos *
84f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos *      http://www.apache.org/licenses/LICENSE-2.0
94f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos *
104f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos * Unless required by applicable law or agreed to in writing, software
114f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos * distributed under the License is distributed on an "AS IS" BASIS,
124f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
134f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos * See the License for the specific language governing permissions and
144f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos * limitations under the License
154f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos */
164f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos
174f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roospackage com.android.systemui.assist;
184f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos
194f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roosimport android.animation.Animator;
204f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roosimport android.animation.AnimatorListenerAdapter;
214f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roosimport android.animation.AnimatorSet;
224f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roosimport android.animation.ValueAnimator;
234f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roosimport android.content.Context;
244f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roosimport android.graphics.Canvas;
254f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roosimport android.graphics.Color;
264f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roosimport android.graphics.Paint;
274f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roosimport android.graphics.PixelFormat;
284f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roosimport android.graphics.PorterDuff;
294f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roosimport android.graphics.PorterDuffXfermode;
304f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roosimport android.os.Handler;
314f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roosimport android.view.View;
324f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roosimport android.view.WindowManager;
33e85da2bad5b80f4e2269a64255cbaf8c11efce61Jorim Jaggiimport android.view.accessibility.AccessibilityEvent;
344f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roosimport android.view.animation.AnimationUtils;
354f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos
36c0d7058b14c24cd07912f5629c26b39b7b4673d5Winsonimport com.android.systemui.Interpolators;
37c18010f6720f606003cde3cd376ddacaca30f6e5Selim Cinekimport com.android.systemui.R;
38c18010f6720f606003cde3cd376ddacaca30f6e5Selim Cinek
394f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos/**
404f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos * Visually discloses that contextual data was provided to an assistant.
414f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos */
424f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roospublic class AssistDisclosure {
434f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos    private final Context mContext;
444f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos    private final WindowManager mWm;
454f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos    private final Handler mHandler;
464f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos
474f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos    private AssistDisclosureView mView;
484f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos    private boolean mViewAdded;
494f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos
504f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos    public AssistDisclosure(Context context, Handler handler) {
514f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos        mContext = context;
524f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos        mHandler = handler;
534f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos        mWm = mContext.getSystemService(WindowManager.class);
544f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos    }
554f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos
564f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos    public void postShow() {
574f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos        mHandler.removeCallbacks(mShowRunnable);
584f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos        mHandler.post(mShowRunnable);
594f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos    }
604f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos
614f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos    private void show() {
624f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos        if (mView == null) {
634f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos            mView = new AssistDisclosureView(mContext);
644f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos        }
654f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos        if (!mViewAdded) {
664f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos            WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
674f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos                    WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY,
684f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos                    WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
694f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos                            | WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED
704f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos                            | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
714f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos                            | WindowManager.LayoutParams.FLAG_FULLSCREEN
724f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos                            | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED,
734f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos                    PixelFormat.TRANSLUCENT);
744f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos            lp.setTitle("AssistDisclosure");
754f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos
764f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos            mWm.addView(mView, lp);
774f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos            mViewAdded = true;
784f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos        }
794f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos    }
804f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos
814f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos    private void hide() {
824f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos        if (mViewAdded) {
834f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos            mWm.removeView(mView);
844f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos            mViewAdded = false;
854f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos        }
864f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos    }
874f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos
884f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos    private Runnable mShowRunnable = new Runnable() {
894f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos        @Override
904f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos        public void run() {
914f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos            show();
924f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos        }
934f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos    };
944f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos
954f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos    private class AssistDisclosureView extends View
964f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos            implements ValueAnimator.AnimatorUpdateListener {
974f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos
98d15745bdba23a2cccb08e27bf9aae4d9d4aff270Adrian Roos        static final int FULL_ALPHA = 222; // 87%
99d15745bdba23a2cccb08e27bf9aae4d9d4aff270Adrian Roos        static final int ALPHA_IN_ANIMATION_DURATION = 400;
100d15745bdba23a2cccb08e27bf9aae4d9d4aff270Adrian Roos        static final int ALPHA_OUT_ANIMATION_DURATION = 300;
101d15745bdba23a2cccb08e27bf9aae4d9d4aff270Adrian Roos
1024f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos
1034f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos        private float mThickness;
1044f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos        private float mShadowThickness;
1054f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos        private final Paint mPaint = new Paint();
1064f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos        private final Paint mShadowPaint = new Paint();
1074f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos
108c6d3e0e11da6e0515f29928efaaf6969f2de610bAdrian Roos        private final ValueAnimator mAlphaOutAnimator;
109c6d3e0e11da6e0515f29928efaaf6969f2de610bAdrian Roos        private final ValueAnimator mAlphaInAnimator;
1104f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos        private final AnimatorSet mAnimator;
1114f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos
112c6d3e0e11da6e0515f29928efaaf6969f2de610bAdrian Roos        private int mAlpha = 0;
1134f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos
1144f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos        public AssistDisclosureView(Context context) {
1154f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos            super(context);
1164f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos
117d15745bdba23a2cccb08e27bf9aae4d9d4aff270Adrian Roos            mAlphaInAnimator = ValueAnimator.ofInt(0, FULL_ALPHA)
118d15745bdba23a2cccb08e27bf9aae4d9d4aff270Adrian Roos                    .setDuration(ALPHA_IN_ANIMATION_DURATION);
119c6d3e0e11da6e0515f29928efaaf6969f2de610bAdrian Roos            mAlphaInAnimator.addUpdateListener(this);
120d15745bdba23a2cccb08e27bf9aae4d9d4aff270Adrian Roos            mAlphaInAnimator.setInterpolator(Interpolators.CUSTOM_40_40);
121d15745bdba23a2cccb08e27bf9aae4d9d4aff270Adrian Roos            mAlphaOutAnimator = ValueAnimator.ofInt(FULL_ALPHA, 0).setDuration(
122c6d3e0e11da6e0515f29928efaaf6969f2de610bAdrian Roos                    ALPHA_OUT_ANIMATION_DURATION);
123c6d3e0e11da6e0515f29928efaaf6969f2de610bAdrian Roos            mAlphaOutAnimator.addUpdateListener(this);
124d15745bdba23a2cccb08e27bf9aae4d9d4aff270Adrian Roos            mAlphaOutAnimator.setInterpolator(Interpolators.CUSTOM_40_40);
1254f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos            mAnimator = new AnimatorSet();
126c6d3e0e11da6e0515f29928efaaf6969f2de610bAdrian Roos            mAnimator.play(mAlphaInAnimator).before(mAlphaOutAnimator);
1274f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos            mAnimator.addListener(new AnimatorListenerAdapter() {
1284f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos                boolean mCancelled;
1294f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos
1304f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos                @Override
1314f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos                public void onAnimationStart(Animator animation) {
1324f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos                    mCancelled = false;
1334f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos                }
1344f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos
1354f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos                @Override
1364f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos                public void onAnimationCancel(Animator animation) {
1374f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos                    mCancelled = true;
1384f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos                }
1394f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos
1404f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos                @Override
1414f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos                public void onAnimationEnd(Animator animation) {
1424f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos                    if (!mCancelled) {
1434f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos                        hide();
1444f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos                    }
1454f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos                }
1464f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos            });
1474f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos
1484f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos            PorterDuffXfermode srcMode = new PorterDuffXfermode(PorterDuff.Mode.SRC);
1494f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos            mPaint.setColor(Color.WHITE);
1504f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos            mPaint.setXfermode(srcMode);
1514f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos            mShadowPaint.setColor(Color.DKGRAY);
1524f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos            mShadowPaint.setXfermode(srcMode);
1534f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos
1544f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos            mThickness = getResources().getDimension(R.dimen.assist_disclosure_thickness);
1554f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos            mShadowThickness = getResources().getDimension(
1564f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos                    R.dimen.assist_disclosure_shadow_thickness);
1574f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos        }
1584f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos
1594f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos        @Override
1604f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos        protected void onAttachedToWindow() {
1614f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos            super.onAttachedToWindow();
1624f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos
1634f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos            startAnimation();
164e85da2bad5b80f4e2269a64255cbaf8c11efce61Jorim Jaggi            sendAccessibilityEvent(AccessibilityEvent.TYPE_ASSIST_READING_CONTEXT);
1654f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos        }
1664f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos
1674f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos        @Override
1684f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos        protected void onDetachedFromWindow() {
1694f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos            super.onDetachedFromWindow();
1704f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos
1714f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos            mAnimator.cancel();
172c6d3e0e11da6e0515f29928efaaf6969f2de610bAdrian Roos            mAlpha = 0;
1734f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos        }
1744f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos
1754f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos        private void startAnimation() {
1764f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos            mAnimator.cancel();
1774f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos            mAnimator.start();
1784f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos        }
1794f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos
1804f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos        @Override
1814f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos        protected void onDraw(Canvas canvas) {
1824f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos            mPaint.setAlpha(mAlpha);
1834f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos            mShadowPaint.setAlpha(mAlpha / 4);
1844f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos
1854f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos            drawGeometry(canvas, mShadowPaint, mShadowThickness);
1864f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos            drawGeometry(canvas, mPaint, 0);
1874f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos        }
1884f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos
1894f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos        private void drawGeometry(Canvas canvas, Paint paint, float padding) {
1904f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos            final int width = getWidth();
1914f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos            final int height = getHeight();
1924f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos            float thickness = mThickness;
1934f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos
194d15745bdba23a2cccb08e27bf9aae4d9d4aff270Adrian Roos            // bottom
195d15745bdba23a2cccb08e27bf9aae4d9d4aff270Adrian Roos            drawBeam(canvas,
196d15745bdba23a2cccb08e27bf9aae4d9d4aff270Adrian Roos                    0,
197d15745bdba23a2cccb08e27bf9aae4d9d4aff270Adrian Roos                    height - thickness,
198d15745bdba23a2cccb08e27bf9aae4d9d4aff270Adrian Roos                    width,
199d15745bdba23a2cccb08e27bf9aae4d9d4aff270Adrian Roos                    height, paint, padding);
200d15745bdba23a2cccb08e27bf9aae4d9d4aff270Adrian Roos
201d15745bdba23a2cccb08e27bf9aae4d9d4aff270Adrian Roos            // sides
202d15745bdba23a2cccb08e27bf9aae4d9d4aff270Adrian Roos            drawBeam(canvas,
203d15745bdba23a2cccb08e27bf9aae4d9d4aff270Adrian Roos                    0,
204d15745bdba23a2cccb08e27bf9aae4d9d4aff270Adrian Roos                    0,
205d15745bdba23a2cccb08e27bf9aae4d9d4aff270Adrian Roos                    thickness,
206d15745bdba23a2cccb08e27bf9aae4d9d4aff270Adrian Roos                    height - thickness, paint, padding);
207d15745bdba23a2cccb08e27bf9aae4d9d4aff270Adrian Roos            drawBeam(canvas,
208d15745bdba23a2cccb08e27bf9aae4d9d4aff270Adrian Roos                    width - thickness,
209d15745bdba23a2cccb08e27bf9aae4d9d4aff270Adrian Roos                    0,
210d15745bdba23a2cccb08e27bf9aae4d9d4aff270Adrian Roos                    width,
211d15745bdba23a2cccb08e27bf9aae4d9d4aff270Adrian Roos                    height - thickness, paint, padding);
212d15745bdba23a2cccb08e27bf9aae4d9d4aff270Adrian Roos
213d15745bdba23a2cccb08e27bf9aae4d9d4aff270Adrian Roos            // top
214d15745bdba23a2cccb08e27bf9aae4d9d4aff270Adrian Roos            drawBeam(canvas,
215d15745bdba23a2cccb08e27bf9aae4d9d4aff270Adrian Roos                    thickness,
216d15745bdba23a2cccb08e27bf9aae4d9d4aff270Adrian Roos                    0,
217d15745bdba23a2cccb08e27bf9aae4d9d4aff270Adrian Roos                    width - thickness,
218d15745bdba23a2cccb08e27bf9aae4d9d4aff270Adrian Roos                    thickness, paint, padding);
2194f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos        }
2204f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos
2214f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos        private void drawBeam(Canvas canvas, float left, float top, float right, float bottom,
2224f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos                Paint paint, float padding) {
2234f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos            canvas.drawRect(left - padding,
2244f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos                    top - padding,
2254f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos                    right + padding,
2264f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos                    bottom + padding,
2274f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos                    paint);
2284f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos        }
2294f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos
2304f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos        @Override
2314f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos        public void onAnimationUpdate(ValueAnimator animation) {
232c6d3e0e11da6e0515f29928efaaf6969f2de610bAdrian Roos            if (animation == mAlphaOutAnimator) {
233c6d3e0e11da6e0515f29928efaaf6969f2de610bAdrian Roos                mAlpha = (int) mAlphaOutAnimator.getAnimatedValue();
234c6d3e0e11da6e0515f29928efaaf6969f2de610bAdrian Roos            } else if (animation == mAlphaInAnimator) {
235c6d3e0e11da6e0515f29928efaaf6969f2de610bAdrian Roos                mAlpha = (int) mAlphaInAnimator.getAnimatedValue();
2364f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos            }
2374f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos            invalidate();
2384f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos        }
2394f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos    }
2404f43dc042bf76ec6c3b340b2297dec7c4cdd9098Adrian Roos}
241