Merge "Improve screenshot animation performance Bug #5525888" into ics-mr1

This commit is contained in:
Romain Guy
2011-11-29 14:14:44 -08:00
committed by Android (Google) Code Review
2 changed files with 50 additions and 85 deletions

View File

@@ -19,23 +19,18 @@
<ImageView android:id="@+id/global_screenshot_background" <ImageView android:id="@+id/global_screenshot_background"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:background="#FF000000" android:src="@android:color/black"
android:visibility="gone" /> android:visibility="gone" />
<FrameLayout <ImageView android:id="@+id/global_screenshot"
android:id="@+id/global_screenshot_container"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center" android:layout_gravity="center"
android:background="@drawable/screenshot_panel" android:background="@drawable/screenshot_panel"
android:visibility="gone"> android:visibility="gone"
<ImageView android:id="@+id/global_screenshot" android:adjustViewBounds="true" />
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:adjustViewBounds="true" />
</FrameLayout>
<ImageView android:id="@+id/global_screenshot_flash" <ImageView android:id="@+id/global_screenshot_flash"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:background="#FFFFFFFF" android:src="@android:color/white"
android:visibility="gone" /> android:visibility="gone" />
</FrameLayout> </FrameLayout>

View File

@@ -38,11 +38,9 @@ import android.net.Uri;
import android.os.AsyncTask; import android.os.AsyncTask;
import android.os.Environment; import android.os.Environment;
import android.os.Process; import android.os.Process;
import android.os.ServiceManager;
import android.provider.MediaStore; import android.provider.MediaStore;
import android.util.DisplayMetrics; import android.util.DisplayMetrics;
import android.view.Display; import android.view.Display;
import android.view.IWindowManager;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.MotionEvent; import android.view.MotionEvent;
import android.view.Surface; import android.view.Surface;
@@ -50,9 +48,7 @@ import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.view.WindowManager; import android.view.WindowManager;
import android.view.animation.Interpolator; import android.view.animation.Interpolator;
import android.widget.FrameLayout;
import android.widget.ImageView; import android.widget.ImageView;
import com.android.systemui.R; import com.android.systemui.R;
import java.io.File; import java.io.File;
@@ -77,7 +73,6 @@ class SaveImageInBackgroundData {
*/ */
class SaveImageInBackgroundTask extends AsyncTask<SaveImageInBackgroundData, Void, class SaveImageInBackgroundTask extends AsyncTask<SaveImageInBackgroundData, Void,
SaveImageInBackgroundData> { SaveImageInBackgroundData> {
private static final String TAG = "SaveImageInBackgroundTask";
private static final String SCREENSHOTS_DIR_NAME = "Screenshots"; private static final String SCREENSHOTS_DIR_NAME = "Screenshots";
private static final String SCREENSHOT_FILE_NAME_TEMPLATE = "Screenshot_%s.png"; private static final String SCREENSHOT_FILE_NAME_TEMPLATE = "Screenshot_%s.png";
private static final String SCREENSHOT_FILE_PATH_TEMPLATE = "%s/%s/%s"; private static final String SCREENSHOT_FILE_PATH_TEMPLATE = "%s/%s/%s";
@@ -85,11 +80,8 @@ class SaveImageInBackgroundTask extends AsyncTask<SaveImageInBackgroundData, Voi
private int mNotificationId; private int mNotificationId;
private NotificationManager mNotificationManager; private NotificationManager mNotificationManager;
private Notification.Builder mNotificationBuilder; private Notification.Builder mNotificationBuilder;
private Intent mLaunchIntent;
private String mImageDir;
private String mImageFileName; private String mImageFileName;
private String mImageFilePath; private String mImageFilePath;
private String mImageDate;
private long mImageTime; private long mImageTime;
// WORKAROUND: We want the same notification across screenshots that we update so that we don't // WORKAROUND: We want the same notification across screenshots that we update so that we don't
@@ -105,11 +97,11 @@ class SaveImageInBackgroundTask extends AsyncTask<SaveImageInBackgroundData, Voi
// Prepare all the output metadata // Prepare all the output metadata
mImageTime = System.currentTimeMillis(); mImageTime = System.currentTimeMillis();
mImageDate = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss").format(new Date(mImageTime)); String imageDate = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss").format(new Date(mImageTime));
mImageDir = Environment.getExternalStoragePublicDirectory( String imageDir = Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES).getAbsolutePath(); Environment.DIRECTORY_PICTURES).getAbsolutePath();
mImageFileName = String.format(SCREENSHOT_FILE_NAME_TEMPLATE, mImageDate); mImageFileName = String.format(SCREENSHOT_FILE_NAME_TEMPLATE, imageDate);
mImageFilePath = String.format(SCREENSHOT_FILE_PATH_TEMPLATE, mImageDir, mImageFilePath = String.format(SCREENSHOT_FILE_PATH_TEMPLATE, imageDir,
SCREENSHOTS_DIR_NAME, mImageFileName); SCREENSHOTS_DIR_NAME, mImageFileName);
// Create the large notification icon // Create the large notification icon
@@ -190,7 +182,7 @@ class SaveImageInBackgroundTask extends AsyncTask<SaveImageInBackgroundData, Voi
} }
return params[0]; return params[0];
}; }
@Override @Override
protected void onPostExecute(SaveImageInBackgroundData params) { protected void onPostExecute(SaveImageInBackgroundData params) {
@@ -202,14 +194,14 @@ class SaveImageInBackgroundTask extends AsyncTask<SaveImageInBackgroundData, Voi
Resources r = params.context.getResources(); Resources r = params.context.getResources();
// Create the intent to show the screenshot in gallery // Create the intent to show the screenshot in gallery
mLaunchIntent = new Intent(Intent.ACTION_VIEW); Intent launchIntent = new Intent(Intent.ACTION_VIEW);
mLaunchIntent.setDataAndType(params.imageUri, "image/png"); launchIntent.setDataAndType(params.imageUri, "image/png");
mLaunchIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); launchIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mNotificationBuilder mNotificationBuilder
.setContentTitle(r.getString(R.string.screenshot_saved_title)) .setContentTitle(r.getString(R.string.screenshot_saved_title))
.setContentText(r.getString(R.string.screenshot_saved_text)) .setContentText(r.getString(R.string.screenshot_saved_text))
.setContentIntent(PendingIntent.getActivity(params.context, 0, mLaunchIntent, 0)) .setContentIntent(PendingIntent.getActivity(params.context, 0, launchIntent, 0))
.setWhen(System.currentTimeMillis()) .setWhen(System.currentTimeMillis())
.setAutoCancel(true); .setAutoCancel(true);
@@ -218,7 +210,7 @@ class SaveImageInBackgroundTask extends AsyncTask<SaveImageInBackgroundData, Voi
mNotificationManager.notify(mNotificationId, n); mNotificationManager.notify(mNotificationId, n);
} }
params.finisher.run(); params.finisher.run();
}; }
} }
/** /**
@@ -228,7 +220,6 @@ class SaveImageInBackgroundTask extends AsyncTask<SaveImageInBackgroundData, Voi
* type of gallery? * type of gallery?
*/ */
class GlobalScreenshot { class GlobalScreenshot {
private static final String TAG = "GlobalScreenshot";
private static final int SCREENSHOT_NOTIFICATION_ID = 789; private static final int SCREENSHOT_NOTIFICATION_ID = 789;
private static final int SCREENSHOT_FLASH_TO_PEAK_DURATION = 130; private static final int SCREENSHOT_FLASH_TO_PEAK_DURATION = 130;
private static final int SCREENSHOT_DROP_IN_DURATION = 430; private static final int SCREENSHOT_DROP_IN_DURATION = 430;
@@ -244,8 +235,6 @@ class GlobalScreenshot {
private static final float SCREENSHOT_DROP_OUT_MIN_SCALE_OFFSET = 0f; private static final float SCREENSHOT_DROP_OUT_MIN_SCALE_OFFSET = 0f;
private Context mContext; private Context mContext;
private LayoutInflater mLayoutInflater;
private IWindowManager mIWindowManager;
private WindowManager mWindowManager; private WindowManager mWindowManager;
private WindowManager.LayoutParams mWindowLayoutParams; private WindowManager.LayoutParams mWindowLayoutParams;
private NotificationManager mNotificationManager; private NotificationManager mNotificationManager;
@@ -256,7 +245,6 @@ class GlobalScreenshot {
private Bitmap mScreenBitmap; private Bitmap mScreenBitmap;
private View mScreenshotLayout; private View mScreenshotLayout;
private ImageView mBackgroundView; private ImageView mBackgroundView;
private FrameLayout mScreenshotContainerView;
private ImageView mScreenshotView; private ImageView mScreenshotView;
private ImageView mScreenshotFlash; private ImageView mScreenshotFlash;
@@ -273,14 +261,13 @@ class GlobalScreenshot {
public GlobalScreenshot(Context context) { public GlobalScreenshot(Context context) {
Resources r = context.getResources(); Resources r = context.getResources();
mContext = context; mContext = context;
mLayoutInflater = (LayoutInflater) LayoutInflater layoutInflater = (LayoutInflater)
context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
// Inflate the screenshot layout // Inflate the screenshot layout
mDisplayMatrix = new Matrix(); mDisplayMatrix = new Matrix();
mScreenshotLayout = mLayoutInflater.inflate(R.layout.global_screenshot, null); mScreenshotLayout = layoutInflater.inflate(R.layout.global_screenshot, null);
mBackgroundView = (ImageView) mScreenshotLayout.findViewById(R.id.global_screenshot_background); mBackgroundView = (ImageView) mScreenshotLayout.findViewById(R.id.global_screenshot_background);
mScreenshotContainerView = (FrameLayout) mScreenshotLayout.findViewById(R.id.global_screenshot_container);
mScreenshotView = (ImageView) mScreenshotLayout.findViewById(R.id.global_screenshot); mScreenshotView = (ImageView) mScreenshotLayout.findViewById(R.id.global_screenshot);
mScreenshotFlash = (ImageView) mScreenshotLayout.findViewById(R.id.global_screenshot_flash); mScreenshotFlash = (ImageView) mScreenshotLayout.findViewById(R.id.global_screenshot_flash);
mScreenshotLayout.setFocusable(true); mScreenshotLayout.setFocusable(true);
@@ -293,8 +280,6 @@ class GlobalScreenshot {
}); });
// Setup the window that we are going to use // Setup the window that we are going to use
mIWindowManager = IWindowManager.Stub.asInterface(
ServiceManager.getService(Context.WINDOW_SERVICE));
mWindowLayoutParams = new WindowManager.LayoutParams( mWindowLayoutParams = new WindowManager.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT, 0, 0, ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT, 0, 0,
WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY, WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY,
@@ -428,8 +413,8 @@ class GlobalScreenshot {
mScreenshotLayout.post(new Runnable() { mScreenshotLayout.post(new Runnable() {
@Override @Override
public void run() { public void run() {
mScreenshotContainerView.setLayerType(View.LAYER_TYPE_HARDWARE, null); mScreenshotView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
mScreenshotContainerView.buildLayer(); mScreenshotView.buildLayer();
mScreenshotAnimation.start(); mScreenshotAnimation.start();
} }
}); });
@@ -463,20 +448,16 @@ class GlobalScreenshot {
anim.addListener(new AnimatorListenerAdapter() { anim.addListener(new AnimatorListenerAdapter() {
@Override @Override
public void onAnimationStart(Animator animation) { public void onAnimationStart(Animator animation) {
mBackgroundView.setFastAlpha(0f); mBackgroundView.setAlpha(0f);
mBackgroundView.setVisibility(View.VISIBLE); mBackgroundView.setVisibility(View.VISIBLE);
mBackgroundView.fastInvalidate(); mScreenshotView.setAlpha(0f);
mScreenshotContainerView.setFastAlpha(0f); mScreenshotView.setTranslationX(0f);
mScreenshotContainerView.setFastTranslationX(0f); mScreenshotView.setTranslationY(0f);
mScreenshotContainerView.setFastTranslationY(0f); mScreenshotView.setScaleX(SCREENSHOT_SCALE + mBgPaddingScale);
mScreenshotContainerView.setFastScaleX(SCREENSHOT_SCALE + mBgPaddingScale); mScreenshotView.setScaleY(SCREENSHOT_SCALE + mBgPaddingScale);
mScreenshotContainerView.setFastScaleY(SCREENSHOT_SCALE + mBgPaddingScale); mScreenshotView.setVisibility(View.VISIBLE);
mScreenshotContainerView.setVisibility(View.VISIBLE); mScreenshotFlash.setAlpha(0f);
mScreenshotContainerView.fastInvalidate();
mScreenshotFlash.setFastAlpha(0f);
mScreenshotFlash.setVisibility(View.VISIBLE); mScreenshotFlash.setVisibility(View.VISIBLE);
mScreenshotFlash.fastInvalidate();
mScreenshotLayout.invalidate();
} }
@Override @Override
public void onAnimationEnd(android.animation.Animator animation) { public void onAnimationEnd(android.animation.Animator animation) {
@@ -486,19 +467,15 @@ class GlobalScreenshot {
anim.addUpdateListener(new AnimatorUpdateListener() { anim.addUpdateListener(new AnimatorUpdateListener() {
@Override @Override
public void onAnimationUpdate(ValueAnimator animation) { public void onAnimationUpdate(ValueAnimator animation) {
float t = ((Float) animation.getAnimatedValue()).floatValue(); float t = (Float) animation.getAnimatedValue();
float scaleT = (SCREENSHOT_SCALE + mBgPaddingScale) float scaleT = (SCREENSHOT_SCALE + mBgPaddingScale)
- (float) scaleInterpolator.getInterpolation(t) - scaleInterpolator.getInterpolation(t)
* (SCREENSHOT_SCALE - SCREENSHOT_DROP_IN_MIN_SCALE); * (SCREENSHOT_SCALE - SCREENSHOT_DROP_IN_MIN_SCALE);
mBackgroundView.setFastAlpha(scaleInterpolator.getInterpolation(t) * BACKGROUND_ALPHA); mBackgroundView.setAlpha(scaleInterpolator.getInterpolation(t) * BACKGROUND_ALPHA);
mBackgroundView.fastInvalidate(); mScreenshotView.setAlpha(t);
mScreenshotContainerView.setFastAlpha(t); mScreenshotView.setScaleX(scaleT);
mScreenshotContainerView.setFastScaleX(scaleT); mScreenshotView.setScaleY(scaleT);
mScreenshotContainerView.setFastScaleY(scaleT); mScreenshotFlash.setAlpha(flashAlphaInterpolator.getInterpolation(t));
mScreenshotContainerView.fastInvalidate();
mScreenshotFlash.setFastAlpha(flashAlphaInterpolator.getInterpolation(t));
mScreenshotFlash.fastInvalidate();
mScreenshotLayout.invalidate();
} }
}); });
return anim; return anim;
@@ -511,8 +488,8 @@ class GlobalScreenshot {
@Override @Override
public void onAnimationEnd(Animator animation) { public void onAnimationEnd(Animator animation) {
mBackgroundView.setVisibility(View.GONE); mBackgroundView.setVisibility(View.GONE);
mScreenshotContainerView.setVisibility(View.GONE); mScreenshotView.setVisibility(View.GONE);
mScreenshotContainerView.setLayerType(View.LAYER_TYPE_NONE, null); mScreenshotView.setLayerType(View.LAYER_TYPE_NONE, null);
} }
}); });
@@ -522,17 +499,13 @@ class GlobalScreenshot {
anim.addUpdateListener(new AnimatorUpdateListener() { anim.addUpdateListener(new AnimatorUpdateListener() {
@Override @Override
public void onAnimationUpdate(ValueAnimator animation) { public void onAnimationUpdate(ValueAnimator animation) {
float t = ((Float) animation.getAnimatedValue()).floatValue(); float t = (Float) animation.getAnimatedValue();
float scaleT = (SCREENSHOT_DROP_IN_MIN_SCALE + mBgPaddingScale) float scaleT = (SCREENSHOT_DROP_IN_MIN_SCALE + mBgPaddingScale)
- (float) t * (SCREENSHOT_DROP_IN_MIN_SCALE - t * (SCREENSHOT_DROP_IN_MIN_SCALE - SCREENSHOT_FAST_DROP_OUT_MIN_SCALE);
- SCREENSHOT_FAST_DROP_OUT_MIN_SCALE); mBackgroundView.setAlpha((1f - t) * BACKGROUND_ALPHA);
mBackgroundView.setFastAlpha((1f - t) * BACKGROUND_ALPHA); mScreenshotView.setAlpha(1f - t);
mBackgroundView.fastInvalidate(); mScreenshotView.setScaleX(scaleT);
mScreenshotContainerView.setFastAlpha(1f - t); mScreenshotView.setScaleY(scaleT);
mScreenshotContainerView.setFastScaleX(scaleT);
mScreenshotContainerView.setFastScaleY(scaleT);
mScreenshotContainerView.fastInvalidate();
mScreenshotLayout.invalidate();
} }
}); });
} else { } else {
@@ -563,19 +536,16 @@ class GlobalScreenshot {
anim.addUpdateListener(new AnimatorUpdateListener() { anim.addUpdateListener(new AnimatorUpdateListener() {
@Override @Override
public void onAnimationUpdate(ValueAnimator animation) { public void onAnimationUpdate(ValueAnimator animation) {
float t = ((Float) animation.getAnimatedValue()).floatValue(); float t = (Float) animation.getAnimatedValue();
float scaleT = (SCREENSHOT_DROP_IN_MIN_SCALE + mBgPaddingScale) float scaleT = (SCREENSHOT_DROP_IN_MIN_SCALE + mBgPaddingScale)
- (float) scaleInterpolator.getInterpolation(t) - scaleInterpolator.getInterpolation(t)
* (SCREENSHOT_DROP_IN_MIN_SCALE - SCREENSHOT_DROP_OUT_MIN_SCALE); * (SCREENSHOT_DROP_IN_MIN_SCALE - SCREENSHOT_DROP_OUT_MIN_SCALE);
mBackgroundView.setFastAlpha((1f - t) * BACKGROUND_ALPHA); mBackgroundView.setAlpha((1f - t) * BACKGROUND_ALPHA);
mBackgroundView.fastInvalidate(); mScreenshotView.setAlpha(1f - scaleInterpolator.getInterpolation(t));
mScreenshotContainerView.setFastAlpha(1f - scaleInterpolator.getInterpolation(t)); mScreenshotView.setScaleX(scaleT);
mScreenshotContainerView.setFastScaleX(scaleT); mScreenshotView.setScaleY(scaleT);
mScreenshotContainerView.setFastScaleY(scaleT); mScreenshotView.setTranslationX(t * finalPos.x);
mScreenshotContainerView.setFastTranslationX(t * finalPos.x); mScreenshotView.setTranslationY(t * finalPos.y);
mScreenshotContainerView.setFastTranslationY(t * finalPos.y);
mScreenshotContainerView.fastInvalidate();
mScreenshotLayout.invalidate();
} }
}); });
} }