SendUi.java revision b2112cff553c3b6658440bf06060c7a08f82df5c
15438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly/*
25438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly * Copyright (C) 2011 The Android Open Source Project
35438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly *
45438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly * Licensed under the Apache License, Version 2.0 (the "License");
55438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly * you may not use this file except in compliance with the License.
65438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly * You may obtain a copy of the License at
75438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly *
85438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly *      http://www.apache.org/licenses/LICENSE-2.0
95438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly *
105438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly * Unless required by applicable law or agreed to in writing, software
115438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly * distributed under the License is distributed on an "AS IS" BASIS,
125438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
135438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly * See the License for the specific language governing permissions and
145438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly * limitations under the License.
155438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly */
165438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly
175438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pellypackage com.android.nfc;
185438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly
195438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pellyimport com.android.nfc3.R;
205438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly
215438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pellyimport android.animation.Animator;
225438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pellyimport android.animation.ObjectAnimator;
235438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pellyimport android.animation.PropertyValuesHolder;
245438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pellyimport android.content.Context;
255438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pellyimport android.graphics.Bitmap;
265438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pellyimport android.graphics.Canvas;
275438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pellyimport android.graphics.Matrix;
285438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pellyimport android.graphics.PixelFormat;
295438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pellyimport android.os.Binder;
305438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pellyimport android.util.DisplayMetrics;
315438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pellyimport android.view.Display;
325438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pellyimport android.view.LayoutInflater;
33b2112cff553c3b6658440bf06060c7a08f82df5cNick Pellyimport android.view.MotionEvent;
345438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pellyimport android.view.Surface;
355438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pellyimport android.view.View;
365438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pellyimport android.view.ViewGroup;
375438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pellyimport android.view.WindowManager;
385438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pellyimport android.widget.ImageView;
395438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly
40b2112cff553c3b6658440bf06060c7a08f82df5cNick Pellyimport android.util.Log;
415438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly/**
425438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly * All methods must be called on UI thread
435438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly */
44b2112cff553c3b6658440bf06060c7a08f82df5cNick Pellypublic class SendUi implements Animator.AnimatorListener, View.OnTouchListener {
455438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly
465438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly    static final float[] PRE_SCREENSHOT_SCALE = {1.0f, 0.6f};
475438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly    static final int PRE_DURATION_MS = 50;
485438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly
495438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly    static final float[] POST_SCREENSHOT_SCALE = {0.6f, 0.0f};
50b2112cff553c3b6658440bf06060c7a08f82df5cNick Pelly    static final int POST_DURATION_MS = 600;
515438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly
525438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly    // all members are only used on UI thread
535438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly    final WindowManager mWindowManager;
545438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly    final Context mContext;
555438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly    final Display mDisplay;
565438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly    final DisplayMetrics mDisplayMetrics;
575438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly    final Matrix mDisplayMatrix;
585438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly    final WindowManager.LayoutParams mWindowLayoutParams;
595438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly    final LayoutInflater mLayoutInflater;
605438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly    final View mScreenshotLayout;
615438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly    final ImageView mScreenshotView;
625438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly    final Callback mCallback;
635438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly    final ObjectAnimator mPreAnimator;
645438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly    final ObjectAnimator mPostAnimator;
655438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly
665438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly    Bitmap mScreenshotBitmap;
675438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly    boolean mAttached;
685438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly
695438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly    interface Callback {
70b2112cff553c3b6658440bf06060c7a08f82df5cNick Pelly        public void onSendConfirmed();
715438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly    }
725438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly
735438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly    public SendUi(Context context, Callback callback) {
745438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly        mContext = context;
755438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly        mCallback = callback;
765438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly
775438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly        mDisplayMetrics = new DisplayMetrics();
785438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly        mDisplayMatrix = new Matrix();
795438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly        mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
805438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly        mDisplay = mWindowManager.getDefaultDisplay();
815438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly
825438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly        mLayoutInflater = (LayoutInflater)
835438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly                context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
845438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly        mScreenshotLayout = mLayoutInflater.inflate(R.layout.screenshot, null);
855438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly        mScreenshotView = (ImageView) mScreenshotLayout.findViewById(R.id.screenshot);
86b2112cff553c3b6658440bf06060c7a08f82df5cNick Pelly        mScreenshotView.setOnTouchListener(this);
875438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly        mScreenshotLayout.setFocusable(true);
885438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly
895438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly        mWindowLayoutParams = new WindowManager.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
905438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly                ViewGroup.LayoutParams.MATCH_PARENT, 0, 0, 0,
915438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly                WindowManager.LayoutParams.FLAG_FULLSCREEN
925438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly                | WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED
935438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly                | WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED_SYSTEM
945438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly                | WindowManager.LayoutParams.FLAG_KEEP_SURFACE_WHILE_ANIMATING
95b2112cff553c3b6658440bf06060c7a08f82df5cNick Pelly                | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN,
96b2112cff553c3b6658440bf06060c7a08f82df5cNick Pelly//                | WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY,
975438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly                PixelFormat.OPAQUE);
985438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly        mWindowLayoutParams.token = new Binder();
995438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly
1005438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly        PropertyValuesHolder preX = PropertyValuesHolder.ofFloat("scaleX", PRE_SCREENSHOT_SCALE);
1015438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly        PropertyValuesHolder preY = PropertyValuesHolder.ofFloat("scaleY", PRE_SCREENSHOT_SCALE);
1025438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly        mPreAnimator = ObjectAnimator.ofPropertyValuesHolder(mScreenshotView, preX, preY);
1035438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly        mPreAnimator.setInterpolator(null);  // linear
1045438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly        mPreAnimator.setDuration(PRE_DURATION_MS);
1055438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly        mPreAnimator.addListener(this);
1065438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly
1075438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly        PropertyValuesHolder postX = PropertyValuesHolder.ofFloat("scaleX", POST_SCREENSHOT_SCALE);
1085438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly        PropertyValuesHolder postY = PropertyValuesHolder.ofFloat("scaleY", POST_SCREENSHOT_SCALE);
1095438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly        mPostAnimator = ObjectAnimator.ofPropertyValuesHolder(mScreenshotView, postX, postY);
1105438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly        mPostAnimator.setInterpolator(null);  // linear
1115438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly        mPostAnimator.setDuration(POST_DURATION_MS);
1125438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly        mPostAnimator.addListener(this);
1135438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly
1145438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly        mAttached = false;
1155438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly    }
1165438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly
1175438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly    public void takeScreenshot() {
1185438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly        mScreenshotBitmap = createScreenshot();
1195438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly    }
1205438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly
1215438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly    /** Show pre-send animation, calls onPreFinished() when complete */
1225438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly    public void showPreSend() {
1235438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly        if (mScreenshotBitmap == null || mAttached) {
1245438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly            return;
1255438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly        }
126b2112cff553c3b6658440bf06060c7a08f82df5cNick Pelly        Log.e("npelly", "1");
1275438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly        mScreenshotView.setImageBitmap(mScreenshotBitmap);
1285438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly        mScreenshotLayout.requestFocus();
1295438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly        mWindowManager.addView(mScreenshotLayout, mWindowLayoutParams);
1305438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly        mAttached = true;
1315438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly        mPreAnimator.start();
1325438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly
1335438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly        //TODO: Lock rotation
1345438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly//        final int orientation = getResources().getConfiguration().orientation;
1355438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly//        setRequestedOrientation(orientation);
1365438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly    }
1375438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly
1385438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly    /** Show post-send animation */
1395438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly    public void showPostSend() {
1405438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly        if (!mAttached) {
1415438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly            return;
1425438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly        }
1435438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly        mPostAnimator.start();
1445438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly    }
1455438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly
1465438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly    public void dismiss() {
1475438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly        if (!mAttached) {
1485438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly            return;
1495438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly        }
1505438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly        mPreAnimator.cancel();
1515438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly        mPostAnimator.cancel();
1525438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly        mWindowManager.removeView(mScreenshotLayout);
1535438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly        mAttached = false;
1545438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly        releaseScreenshot();
1555438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly    }
1565438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly
1575438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly    public void releaseScreenshot() {
1585438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly        mScreenshotBitmap = null;
1595438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly    }
1605438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly
1615438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly    /**
1625438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly     * @return the current display rotation in degrees
1635438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly     */
1645438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly    static float getDegreesForRotation(int value) {
1655438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly        switch (value) {
1665438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly        case Surface.ROTATION_90:
1675438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly            return 90f;
1685438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly        case Surface.ROTATION_180:
1695438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly            return 180f;
1705438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly        case Surface.ROTATION_270:
1715438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly            return 270f;
1725438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly        }
1735438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly        return 0f;
1745438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly    }
1755438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly
1765438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly    /**
1775438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly     * Returns a screenshot of the current display contents.
1785438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly     * @param context Context.
1795438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly     * @return
1805438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly     */
1815438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly    Bitmap createScreenshot() {
1825438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly        // We need to orient the screenshot correctly (and the Surface api seems to
1835438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly        // take screenshots only in the natural orientation of the device :!)
1845438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly        mDisplay.getRealMetrics(mDisplayMetrics);
1855438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly        float[] dims = {mDisplayMetrics.widthPixels, mDisplayMetrics.heightPixels};
1865438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly        float degrees = getDegreesForRotation(mDisplay.getRotation());
1875438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly        boolean requiresRotation = (degrees > 0);
1885438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly        if (requiresRotation) {
1895438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly            // Get the dimensions of the device in its native orientation
1905438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly            mDisplayMatrix.reset();
1915438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly            mDisplayMatrix.preRotate(-degrees);
1925438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly            mDisplayMatrix.mapPoints(dims);
1935438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly            dims[0] = Math.abs(dims[0]);
1945438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly            dims[1] = Math.abs(dims[1]);
1955438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly        }
1965438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly
1975438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly        Bitmap bitmap = Surface.screenshot((int) dims[0], (int) dims[1]);
1985438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly        // Bail if we couldn't take the screenshot
1995438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly        if (bitmap == null) {
2005438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly            return null;
2015438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly        }
2025438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly
2035438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly        if (requiresRotation) {
2045438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly            // Rotate the screenshot to the current orientation
2055438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly            Bitmap ss = Bitmap.createBitmap(mDisplayMetrics.widthPixels,
2065438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly                    mDisplayMetrics.heightPixels, Bitmap.Config.ARGB_8888);
2075438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly            Canvas c = new Canvas(ss);
2085438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly            c.translate(ss.getWidth() / 2, ss.getHeight() / 2);
2095438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly            c.rotate(360f - degrees);
2105438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly            c.translate(-dims[0] / 2, -dims[1] / 2);
2115438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly            c.drawBitmap(bitmap, 0, 0, null);
2125438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly
2135438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly            bitmap = ss;
2145438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly        }
2155438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly
2165438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly        return bitmap;
2175438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly    }
2185438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly
2195438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly    @Override
2205438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly    public void onAnimationStart(Animator animation) {  }
2215438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly
2225438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly    @Override
2235438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly    public void onAnimationEnd(Animator animation) {
224b2112cff553c3b6658440bf06060c7a08f82df5cNick Pelly        if (animation == mPostAnimator) {
2255438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly            dismiss();
2265438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly        }
2275438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly    }
2285438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly
2295438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly    @Override
2305438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly    public void onAnimationCancel(Animator animation) {  }
2315438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly
2325438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly    @Override
2335438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly    public void onAnimationRepeat(Animator animation) {  }
234b2112cff553c3b6658440bf06060c7a08f82df5cNick Pelly
235b2112cff553c3b6658440bf06060c7a08f82df5cNick Pelly    @Override
236b2112cff553c3b6658440bf06060c7a08f82df5cNick Pelly    public boolean onTouch(View v, MotionEvent event) {
237b2112cff553c3b6658440bf06060c7a08f82df5cNick Pelly        if (!mAttached) {
238b2112cff553c3b6658440bf06060c7a08f82df5cNick Pelly            return false;
239b2112cff553c3b6658440bf06060c7a08f82df5cNick Pelly        }
240b2112cff553c3b6658440bf06060c7a08f82df5cNick Pelly        mPreAnimator.end();
241b2112cff553c3b6658440bf06060c7a08f82df5cNick Pelly        mCallback.onSendConfirmed();
242b2112cff553c3b6658440bf06060c7a08f82df5cNick Pelly        return true;
243b2112cff553c3b6658440bf06060c7a08f82df5cNick Pelly    }
2445438ab0e17064e20870ac893a2dd2b9e1219eef1Nick Pelly}
245