summaryrefslogtreecommitdiffstats
path: root/packages/SystemUI/src
diff options
context:
space:
mode:
Diffstat (limited to 'packages/SystemUI/src')
-rw-r--r--packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/recent/RecentsScrollViewPerformanceHelper.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java333
-rw-r--r--packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java16
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/StatusBar.java22
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java51
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java26
8 files changed, 287 insertions, 167 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java b/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
index 8d5c33f..bd1fcfc 100644
--- a/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
@@ -230,7 +230,7 @@ public class RecentsPanelView extends RelativeLayout
public void handleShowBackground(boolean show) {
if (show) {
- mRecentsScrim.setBackgroundResource(R.drawable.status_bar_recents_background);
+ mRecentsScrim.setBackgroundResource(R.drawable.status_bar_recents_background_solid);
} else {
mRecentsScrim.setBackgroundDrawable(null);
}
diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentsScrollViewPerformanceHelper.java b/packages/SystemUI/src/com/android/systemui/recent/RecentsScrollViewPerformanceHelper.java
index b7e656e..813099a 100644
--- a/packages/SystemUI/src/com/android/systemui/recent/RecentsScrollViewPerformanceHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/recent/RecentsScrollViewPerformanceHelper.java
@@ -83,7 +83,7 @@ public class RecentsScrollViewPerformanceHelper {
mLinearLayout = layout;
mAttachedToWindow = true;
mBackgroundDrawable = mContext.getResources()
- .getDrawable(R.drawable.status_bar_recents_background).getConstantState();
+ .getDrawable(R.drawable.status_bar_recents_background_solid).getConstantState();
updateShowBackground();
}
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
index 3fa3078..181cc98 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
@@ -19,27 +19,28 @@ package com.android.systemui.screenshot;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
-import android.animation.ObjectAnimator;
-import android.animation.TimeInterpolator;
import android.animation.ValueAnimator;
import android.animation.ValueAnimator.AnimatorUpdateListener;
-import android.app.Activity;
+import android.app.Notification;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
+import android.content.Intent;
+import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.PixelFormat;
-import android.media.MediaScannerConnection;
+import android.graphics.PointF;
+import android.graphics.RectF;
import android.net.Uri;
import android.os.AsyncTask;
-import android.os.Binder;
import android.os.Environment;
import android.os.ServiceManager;
import android.provider.MediaStore;
import android.util.DisplayMetrics;
-import android.util.Log;
import android.view.Display;
import android.view.IWindowManager;
import android.view.LayoutInflater;
@@ -48,18 +49,16 @@ import android.view.Surface;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
+import android.view.animation.AccelerateInterpolator;
+import android.view.animation.DecelerateInterpolator;
import android.widget.FrameLayout;
import android.widget.ImageView;
-import android.widget.TextView;
-import android.widget.Toast;
+import com.android.server.wm.WindowManagerService;
import com.android.systemui.R;
import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
import java.io.OutputStream;
-import java.lang.Thread;
import java.text.SimpleDateFormat;
import java.util.Date;
@@ -70,6 +69,7 @@ class SaveImageInBackgroundData {
Context context;
Bitmap image;
Runnable finisher;
+ int iconSize;
int result;
}
@@ -83,6 +83,71 @@ class SaveImageInBackgroundTask extends AsyncTask<SaveImageInBackgroundData, Voi
private static final String SCREENSHOT_FILE_NAME_TEMPLATE = "Screenshot_%s.png";
private static final String SCREENSHOT_FILE_PATH_TEMPLATE = "%s/%s/%s";
+ private int mNotificationId;
+ private NotificationManager mNotificationManager;
+ private Notification.Builder mNotificationBuilder;
+ private Intent mLaunchIntent;
+ private String mImageDir;
+ private String mImageFileName;
+ private String mImageFilePath;
+ private String mImageDate;
+ private long mImageTime;
+
+ // WORKAROUND: We want the same notification across screenshots that we update so that we don't
+ // spam a user's notification drawer. However, we only show the ticker for the saving state
+ // and if the ticker text is the same as the previous notification, then it will not show. So
+ // for now, we just add and remove a space from the ticker text to trigger the animation when
+ // necessary.
+ private static boolean mTickerAddSpace;
+
+ SaveImageInBackgroundTask(Context context, SaveImageInBackgroundData data,
+ NotificationManager nManager, int nId) {
+ Resources r = context.getResources();
+
+ // Prepare all the output metadata
+ mImageTime = System.currentTimeMillis();
+ mImageDate = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss").format(new Date(mImageTime));
+ mImageDir = Environment.getExternalStoragePublicDirectory(
+ Environment.DIRECTORY_PICTURES).getAbsolutePath();
+ mImageFileName = String.format(SCREENSHOT_FILE_NAME_TEMPLATE, mImageDate);
+ mImageFilePath = String.format(SCREENSHOT_FILE_PATH_TEMPLATE, mImageDir,
+ SCREENSHOTS_DIR_NAME, mImageFileName);
+
+ // Create the large notification icon
+ int imageWidth = data.image.getWidth();
+ int imageHeight = data.image.getHeight();
+ int iconWidth = data.iconSize;
+ int iconHeight = data.iconSize;
+ if (imageWidth > imageHeight) {
+ iconWidth = (int) (((float) iconHeight / imageHeight) * imageWidth);
+ } else {
+ iconHeight = (int) (((float) iconWidth / imageWidth) * imageHeight);
+ }
+ Bitmap rawIcon = Bitmap.createScaledBitmap(data.image, iconWidth, iconHeight, true);
+ Bitmap croppedIcon = Bitmap.createBitmap(rawIcon, (iconWidth - data.iconSize) / 2,
+ (iconHeight - data.iconSize) / 2, data.iconSize, data.iconSize);
+
+ // Show the intermediate notification
+ mLaunchIntent = new Intent(Intent.ACTION_VIEW);
+ mLaunchIntent.setDataAndType(Uri.fromFile(new File(mImageFilePath)), "image/png");
+ mLaunchIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ mTickerAddSpace = !mTickerAddSpace;
+ mNotificationId = nId;
+ mNotificationBuilder = new Notification.Builder(context)
+ .setLargeIcon(croppedIcon)
+ .setTicker(r.getString(R.string.screenshot_saving_ticker)
+ + (mTickerAddSpace ? " " : ""))
+ .setContentTitle(r.getString(R.string.screenshot_saving_title))
+ .setContentText(r.getString(R.string.screenshot_saving_text))
+ .setSmallIcon(android.R.drawable.ic_menu_gallery)
+ .setWhen(System.currentTimeMillis());
+ Notification n = mNotificationBuilder.getNotification();
+ n.flags |= Notification.FLAG_NO_CLEAR;
+
+ mNotificationManager = nManager;
+ mNotificationManager.notify(nId, n);
+ }
+
@Override
protected SaveImageInBackgroundData doInBackground(SaveImageInBackgroundData... params) {
if (params.length != 1) return null;
@@ -91,23 +156,15 @@ class SaveImageInBackgroundTask extends AsyncTask<SaveImageInBackgroundData, Voi
Bitmap image = params[0].image;
try {
- long currentTime = System.currentTimeMillis();
- String date = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss").format(new Date(currentTime));
- String imageDir = Environment.getExternalStoragePublicDirectory(
- Environment.DIRECTORY_PICTURES).getAbsolutePath();
- String imageFileName = String.format(SCREENSHOT_FILE_NAME_TEMPLATE, date);
- String imageFilePath = String.format(SCREENSHOT_FILE_PATH_TEMPLATE, imageDir,
- SCREENSHOTS_DIR_NAME, imageFileName);
-
// Save the screenshot to the MediaStore
ContentValues values = new ContentValues();
ContentResolver resolver = context.getContentResolver();
- values.put(MediaStore.Images.ImageColumns.DATA, imageFilePath);
- values.put(MediaStore.Images.ImageColumns.TITLE, imageFileName);
- values.put(MediaStore.Images.ImageColumns.DISPLAY_NAME, imageFileName);
- values.put(MediaStore.Images.ImageColumns.DATE_TAKEN, currentTime);
- values.put(MediaStore.Images.ImageColumns.DATE_ADDED, currentTime);
- values.put(MediaStore.Images.ImageColumns.DATE_MODIFIED, currentTime);
+ values.put(MediaStore.Images.ImageColumns.DATA, mImageFilePath);
+ values.put(MediaStore.Images.ImageColumns.TITLE, mImageFileName);
+ values.put(MediaStore.Images.ImageColumns.DISPLAY_NAME, mImageFileName);
+ values.put(MediaStore.Images.ImageColumns.DATE_TAKEN, mImageTime);
+ values.put(MediaStore.Images.ImageColumns.DATE_ADDED, mImageTime);
+ values.put(MediaStore.Images.ImageColumns.DATE_MODIFIED, mImageTime);
values.put(MediaStore.Images.ImageColumns.MIME_TYPE, "image/png");
Uri uri = resolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
@@ -118,7 +175,7 @@ class SaveImageInBackgroundTask extends AsyncTask<SaveImageInBackgroundData, Voi
// update file size in the database
values.clear();
- values.put(MediaStore.Images.ImageColumns.SIZE, new File(imageFilePath).length());
+ values.put(MediaStore.Images.ImageColumns.SIZE, new File(mImageFilePath).length());
resolver.update(uri, values, null, null);
params[0].result = 0;
@@ -135,12 +192,21 @@ class SaveImageInBackgroundTask extends AsyncTask<SaveImageInBackgroundData, Voi
protected void onPostExecute(SaveImageInBackgroundData params) {
if (params.result > 0) {
// Show a message that we've failed to save the image to disk
- Toast.makeText(params.context, R.string.screenshot_failed_toast,
- Toast.LENGTH_SHORT).show();
+ GlobalScreenshot.notifyScreenshotError(params.context, mNotificationManager);
} else {
- // Show a message that we've saved the screenshot to disk
- Toast.makeText(params.context, R.string.screenshot_saving_toast,
- Toast.LENGTH_SHORT).show();
+ // Show the final notification to indicate screenshot saved
+ Resources r = params.context.getResources();
+
+ mNotificationBuilder
+ .setContentTitle(r.getString(R.string.screenshot_saved_title))
+ .setContentText(r.getString(R.string.screenshot_saved_text))
+ .setContentIntent(PendingIntent.getActivity(params.context, 0, mLaunchIntent, 0))
+ .setWhen(System.currentTimeMillis())
+ .setAutoCancel(true);
+
+ Notification n = mNotificationBuilder.getNotification();
+ n.flags &= ~Notification.FLAG_NO_CLEAR;
+ mNotificationManager.notify(mNotificationId, n);
}
params.finisher.run();
};
@@ -154,22 +220,23 @@ class SaveImageInBackgroundTask extends AsyncTask<SaveImageInBackgroundData, Voi
*/
class GlobalScreenshot {
private static final String TAG = "GlobalScreenshot";
- private static final int SCREENSHOT_FADE_IN_DURATION = 900;
- private static final int SCREENSHOT_FADE_OUT_DELAY = 1000;
- private static final int SCREENSHOT_FADE_OUT_DURATION = 450;
- private static final int TOAST_FADE_IN_DURATION = 500;
- private static final int TOAST_FADE_OUT_DELAY = 1000;
- private static final int TOAST_FADE_OUT_DURATION = 500;
+ private static final int SCREENSHOT_NOTIFICATION_ID = 789;
+ private static final int SCREENSHOT_FADE_IN_DURATION = 250;
+ private static final int SCREENSHOT_FADE_OUT_DELAY = 750;
+ private static final int SCREENSHOT_FADE_OUT_DURATION = 500;
+ private static final int SCREENSHOT_FAST_FADE_OUT_DURATION = 350;
private static final float BACKGROUND_ALPHA = 0.65f;
- private static final float SCREENSHOT_SCALE = 0.85f;
- private static final float SCREENSHOT_MIN_SCALE = 0.7f;
- private static final float SCREENSHOT_ROTATION = -6.75f; // -12.5f;
+ private static final float SCREENSHOT_SCALE_FUDGE = 0.075f; // To account for the border padding
+ private static final float SCREENSHOT_SCALE = 0.55f;
+ private static final float SCREENSHOT_FADE_IN_MIN_SCALE = SCREENSHOT_SCALE * 0.975f;
+ private static final float SCREENSHOT_FADE_OUT_MIN_SCALE = SCREENSHOT_SCALE * 0.925f;
private Context mContext;
private LayoutInflater mLayoutInflater;
private IWindowManager mIWindowManager;
private WindowManager mWindowManager;
private WindowManager.LayoutParams mWindowLayoutParams;
+ private NotificationManager mNotificationManager;
private Display mDisplay;
private DisplayMetrics mDisplayMetrics;
private Matrix mDisplayMatrix;
@@ -182,34 +249,24 @@ class GlobalScreenshot {
private AnimatorSet mScreenshotAnimation;
- // General use cubic interpolator
- final TimeInterpolator mCubicInterpolator = new TimeInterpolator() {
- public float getInterpolation(float t) {
- return t*t*t;
- }
- };
- // The interpolator used to control the background alpha at the start of the animation
- final TimeInterpolator mBackgroundViewAlphaInterpolator = new TimeInterpolator() {
- public float getInterpolation(float t) {
- float tStep = 0.35f;
- if (t < tStep) {
- return t * (1f / tStep);
- } else {
- return 1f;
- }
- }
- };
+ private int mStatusBarIconSize;
+ private int mNotificationIconSize;
+ private float mDropOffsetX;
+ private float mDropOffsetY;
+ private float mBgPadding;
+ private float mBgPaddingScale;
+
/**
* @param context everything needs a context :(
*/
public GlobalScreenshot(Context context) {
+ Resources r = context.getResources();
mContext = context;
mLayoutInflater = (LayoutInflater)
context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
// Inflate the screenshot layout
- mDisplayMetrics = new DisplayMetrics();
mDisplayMatrix = new Matrix();
mScreenshotLayout = mLayoutInflater.inflate(R.layout.global_screenshot, null);
mBackgroundView = (ImageView) mScreenshotLayout.findViewById(R.id.global_screenshot_background);
@@ -237,7 +294,23 @@ class GlobalScreenshot {
PixelFormat.TRANSLUCENT);
mWindowLayoutParams.setTitle("ScreenshotAnimation");
mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
+ mNotificationManager =
+ (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
mDisplay = mWindowManager.getDefaultDisplay();
+ mDisplayMetrics = new DisplayMetrics();
+ mDisplay.getRealMetrics(mDisplayMetrics);
+
+ // Get the various target sizes
+ mStatusBarIconSize =
+ r.getDimensionPixelSize(com.android.internal.R.dimen.status_bar_icon_size);
+ mNotificationIconSize =
+ r.getDimensionPixelSize(android.R.dimen.notification_large_icon_height);
+ mDropOffsetX = r.getDimensionPixelSize(R.dimen.global_screenshot_drop_offset_x);
+ mDropOffsetY = r.getDimensionPixelSize(R.dimen.global_screenshot_drop_offset_y);
+
+ // Scale has to account for both sides of the bg
+ mBgPadding = (float) r.getDimensionPixelSize(R.dimen.global_screenshot_bg_padding);
+ mBgPaddingScale = (2f * mBgPadding) / mDisplayMetrics.widthPixels;
}
/**
@@ -247,8 +320,10 @@ class GlobalScreenshot {
SaveImageInBackgroundData data = new SaveImageInBackgroundData();
data.context = mContext;
data.image = mScreenBitmap;
+ data.iconSize = mNotificationIconSize;
data.finisher = finisher;
- new SaveImageInBackgroundTask().execute(data);
+ new SaveImageInBackgroundTask(mContext, data, mNotificationManager,
+ SCREENSHOT_NOTIFICATION_ID).execute(data);
}
/**
@@ -257,11 +332,11 @@ class GlobalScreenshot {
private float getDegreesForRotation(int value) {
switch (value) {
case Surface.ROTATION_90:
- return 90f;
+ return 360f - 90f;
case Surface.ROTATION_180:
- return 180f;
+ return 360f - 180f;
case Surface.ROTATION_270:
- return 270f;
+ return 360f - 270f;
}
return 0f;
}
@@ -269,7 +344,7 @@ class GlobalScreenshot {
/**
* Takes a screenshot of the current display and shows an animation.
*/
- void takeScreenshot(Runnable finisher) {
+ void takeScreenshot(Runnable finisher, boolean statusBarVisible, boolean navBarVisible) {
// We need to orient the screenshot correctly (and the Surface api seems to take screenshots
// only in the natural orientation of the device :!)
mDisplay.getRealMetrics(mDisplayMetrics);
@@ -291,7 +366,7 @@ class GlobalScreenshot {
mDisplayMetrics.heightPixels, Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(ss);
c.translate(ss.getWidth() / 2, ss.getHeight() / 2);
- c.rotate(360f - degrees);
+ c.rotate(degrees);
c.translate(-dims[0] / 2, -dims[1] / 2);
c.drawBitmap(mScreenBitmap, 0, 0, null);
c.setBitmap(null);
@@ -300,21 +375,26 @@ class GlobalScreenshot {
// If we couldn't take the screenshot, notify the user
if (mScreenBitmap == null) {
- Toast.makeText(mContext, R.string.screenshot_failed_toast,
- Toast.LENGTH_SHORT).show();
+ notifyScreenshotError(mContext, mNotificationManager);
finisher.run();
return;
}
+ // Optimizations
+ mScreenBitmap.setHasAlpha(false);
+ mScreenBitmap.prepareToDraw();
+
// Start the post-screenshot animation
- startAnimation(finisher);
+ startAnimation(finisher, mDisplayMetrics.widthPixels, mDisplayMetrics.heightPixels,
+ statusBarVisible, navBarVisible);
}
/**
* Starts the animation after taking the screenshot
*/
- private void startAnimation(final Runnable finisher) {
+ private void startAnimation(final Runnable finisher, int w, int h, boolean statusBarVisible,
+ boolean navBarVisible) {
// Add the view for the animation
mScreenshotView.setImageBitmap(mScreenBitmap);
mScreenshotLayout.requestFocus();
@@ -326,7 +406,8 @@ class GlobalScreenshot {
mWindowManager.addView(mScreenshotLayout, mWindowLayoutParams);
ValueAnimator screenshotFadeInAnim = createScreenshotFadeInAnimation();
- ValueAnimator screenshotFadeOutAnim = createScreenshotFadeOutAnimation();
+ ValueAnimator screenshotFadeOutAnim = createScreenshotFadeOutAnimation(w, h,
+ statusBarVisible, navBarVisible);
mScreenshotAnimation = new AnimatorSet();
mScreenshotAnimation.play(screenshotFadeInAnim).before(screenshotFadeOutAnim);
mScreenshotAnimation.addListener(new AnimatorListenerAdapter() {
@@ -337,16 +418,29 @@ class GlobalScreenshot {
mWindowManager.removeView(mScreenshotLayout);
}
});
- mScreenshotAnimation.start();
+ mScreenshotLayout.post(new Runnable() {
+ @Override
+ public void run() {
+ mScreenshotContainerView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
+ mScreenshotContainerView.buildLayer();
+ mScreenshotAnimation.start();
+ }
+ });
}
private ValueAnimator createScreenshotFadeInAnimation() {
ValueAnimator anim = ValueAnimator.ofFloat(0f, 1f);
- anim.setInterpolator(mCubicInterpolator);
+ anim.setInterpolator(new AccelerateInterpolator(1.5f));
anim.setDuration(SCREENSHOT_FADE_IN_DURATION);
anim.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animation) {
+ mBackgroundView.setAlpha(0f);
mBackgroundView.setVisibility(View.VISIBLE);
+ mScreenshotContainerView.setTranslationX(0f);
+ mScreenshotContainerView.setTranslationY(0f);
+ mScreenshotContainerView.setScaleX(SCREENSHOT_FADE_IN_MIN_SCALE);
+ mScreenshotContainerView.setScaleY(SCREENSHOT_FADE_IN_MIN_SCALE);
+ mScreenshotContainerView.setAlpha(0f);
mScreenshotContainerView.setVisibility(View.VISIBLE);
}
});
@@ -354,41 +448,98 @@ class GlobalScreenshot {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
float t = ((Float) animation.getAnimatedValue()).floatValue();
- mBackgroundView.setAlpha(mBackgroundViewAlphaInterpolator.getInterpolation(t) *
- BACKGROUND_ALPHA);
- float scaleT = SCREENSHOT_SCALE + (1f - t) * SCREENSHOT_SCALE;
- mScreenshotContainerView.setAlpha(t*t*t*t);
+ float scaleT = (SCREENSHOT_FADE_IN_MIN_SCALE)
+ + (float) t * (SCREENSHOT_SCALE - SCREENSHOT_FADE_IN_MIN_SCALE);
+ mBackgroundView.setAlpha(t * BACKGROUND_ALPHA);
mScreenshotContainerView.setScaleX(scaleT);
mScreenshotContainerView.setScaleY(scaleT);
- mScreenshotContainerView.setRotation(t * SCREENSHOT_ROTATION);
+ mScreenshotContainerView.setAlpha(t);
}
});
return anim;
}
- private ValueAnimator createScreenshotFadeOutAnimation() {
- ValueAnimator anim = ValueAnimator.ofFloat(1f, 0f);
- anim.setInterpolator(mCubicInterpolator);
+ private ValueAnimator createScreenshotFadeOutAnimation(int w, int h, boolean statusBarVisible,
+ boolean navBarVisible) {
+ ValueAnimator anim = ValueAnimator.ofFloat(0f, 1f);
+ anim.setInterpolator(new DecelerateInterpolator(0.5f));
anim.setStartDelay(SCREENSHOT_FADE_OUT_DELAY);
- anim.setDuration(SCREENSHOT_FADE_OUT_DURATION);
anim.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
mBackgroundView.setVisibility(View.GONE);
mScreenshotContainerView.setVisibility(View.GONE);
+ mScreenshotContainerView.setLayerType(View.LAYER_TYPE_NONE, null);
}
});
- anim.addUpdateListener(new AnimatorUpdateListener() {
- @Override
- public void onAnimationUpdate(ValueAnimator animation) {
- float t = ((Float) animation.getAnimatedValue()).floatValue();
- float scaleT = SCREENSHOT_MIN_SCALE +
- t*(SCREENSHOT_SCALE - SCREENSHOT_MIN_SCALE);
- mScreenshotContainerView.setAlpha(t);
- mScreenshotContainerView.setScaleX(scaleT);
- mScreenshotContainerView.setScaleY(scaleT);
- mBackgroundView.setAlpha(t * t * BACKGROUND_ALPHA);
+
+ if (!statusBarVisible || !navBarVisible) {
+ // There is no status bar/nav bar, so just fade the screenshot away in place
+ anim.setDuration(SCREENSHOT_FAST_FADE_OUT_DURATION);
+ anim.addUpdateListener(new AnimatorUpdateListener() {
+ @Override
+ public void onAnimationUpdate(ValueAnimator animation) {
+ float t = ((Float) animation.getAnimatedValue()).floatValue();
+ float scaleT = (SCREENSHOT_FADE_OUT_MIN_SCALE)
+ + (float) (1f - t) * (SCREENSHOT_SCALE - SCREENSHOT_FADE_OUT_MIN_SCALE);
+ mBackgroundView.setAlpha((1f - t) * BACKGROUND_ALPHA);
+ mScreenshotContainerView.setAlpha((1f - t) * BACKGROUND_ALPHA);
+ mScreenshotContainerView.setScaleX(scaleT);
+ mScreenshotContainerView.setScaleY(scaleT);
+ }
+ });
+ } else {
+ // Determine the bounds of how to scale
+ float halfScreenWidth = (w - 2f * mBgPadding) / 2f;
+ float halfScreenHeight = (h - 2f * mBgPadding) / 2f;
+ final RectF finalBounds = new RectF(mDropOffsetX, mDropOffsetY,
+ mDropOffsetX + mStatusBarIconSize,
+ mDropOffsetY + mStatusBarIconSize);
+ final PointF currentPos = new PointF(0f, 0f);
+ final PointF finalPos = new PointF(-halfScreenWidth + finalBounds.centerX(),
+ -halfScreenHeight + finalBounds.centerY());
+ final DecelerateInterpolator d = new DecelerateInterpolator(2f);
+ // Note: since the scale origin is in the center of the view, divide difference by 2
+ float tmpMinScale = 0f;
+ if (w > h) {
+ tmpMinScale = finalBounds.width() / (2f * w);
+ } else {
+ tmpMinScale = finalBounds.height() / (2f * h);
}
- });
+ final float minScale = tmpMinScale;
+
+ // Animate the screenshot to the status bar
+ anim.setDuration(SCREENSHOT_FADE_OUT_DURATION);
+ anim.addUpdateListener(new AnimatorUpdateListener() {
+ @Override
+ public void onAnimationUpdate(ValueAnimator animation) {
+ float t = ((Float) animation.getAnimatedValue()).floatValue();
+ float scaleT = minScale
+ + (float) (1f - t) * (SCREENSHOT_SCALE - minScale - mBgPaddingScale)
+ + mBgPaddingScale;
+ mScreenshotContainerView.setAlpha(d.getInterpolation(1f - t));
+ mScreenshotContainerView.setTranslationX(d.getInterpolation(t) * finalPos.x);
+ mScreenshotContainerView.setTranslationY(d.getInterpolation(t) * finalPos.y);
+ mScreenshotContainerView.setScaleX(scaleT);
+ mScreenshotContainerView.setScaleY(scaleT);
+ mBackgroundView.setAlpha((1f - t) * BACKGROUND_ALPHA);
+ }
+ });
+ }
return anim;
}
+
+ static void notifyScreenshotError(Context context, NotificationManager nManager) {
+ Resources r = context.getResources();
+
+ // Clear all existing notification, compose the new notification and show it
+ Notification n = new Notification.Builder(context)
+ .setTicker(r.getString(R.string.screenshot_failed_title))
+ .setContentTitle(r.getString(R.string.screenshot_failed_title))
+ .setContentText(r.getString(R.string.screenshot_failed_text))
+ .setSmallIcon(android.R.drawable.ic_menu_report_image)
+ .setWhen(System.currentTimeMillis())
+ .setAutoCancel(true)
+ .getNotification();
+ nManager.notify(SCREENSHOT_NOTIFICATION_ID, n);
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java b/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java
index 05ff8be..456b5fa 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java
@@ -17,26 +17,12 @@
package com.android.systemui.screenshot;
import android.app.Service;
-import android.app.AlertDialog;
-import android.content.ActivityNotFoundException;
-import android.content.Context;
-import android.content.DialogInterface;
import android.content.Intent;
-import android.net.Uri;
-import android.hardware.usb.UsbAccessory;
-import android.hardware.usb.UsbManager;
-import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
-import android.util.Log;
-
-import com.android.internal.app.AlertActivity;
-import com.android.internal.app.AlertController;
-
-import com.android.systemui.R;
public class TakeScreenshotService extends Service {
private static final String TAG = "TakeScreenshotService";
@@ -60,7 +46,7 @@ public class TakeScreenshotService extends Service {
} catch (RemoteException e) {
}
}
- });
+ }, msg.arg1 > 0, msg.arg2 > 0);
}
}
};
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBar.java
index 5959537..2e1803e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBar.java
@@ -146,4 +146,26 @@ public abstract class StatusBar extends SystemUI implements CommandQueue.Callbac
mDoNotDisturb = new DoNotDisturb(mContext);
}
+
+ protected View updateNotificationVetoButton(View row, StatusBarNotification n) {
+ View vetoButton = row.findViewById(R.id.veto);
+ if (n.isClearable()) {
+ final String _pkg = n.pkg;
+ final String _tag = n.tag;
+ final int _id = n.id;
+ vetoButton.setOnClickListener(new View.OnClickListener() {
+ public void onClick(View v) {
+ try {
+ mBarService.onNotificationClear(_pkg, _tag, _id);
+ } catch (RemoteException ex) {
+ // system process is dead if we're here.
+ }
+ }
+ });
+ vetoButton.setVisibility(View.VISIBLE);
+ } else {
+ vetoButton.setVisibility(View.GONE);
+ }
+ return vetoButton;
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index 9c8c229..4e9b411 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -94,7 +94,7 @@ public class PhoneStatusBar extends StatusBar {
public static final boolean DUMPTRUCK = true; // extra dumpsys info
// additional instrumentation for testing purposes; intended to be left on during development
- public static final boolean CHATTY = DEBUG || true;
+ public static final boolean CHATTY = DEBUG;
public static final String ACTION_STATUSBAR_START
= "com.android.internal.policy.statusbar.START";
@@ -618,6 +618,10 @@ public class PhoneStatusBar extends StatusBar {
boolean orderUnchanged = notification.notification.when==oldNotification.notification.when
&& notification.priority == oldNotification.priority;
// priority now encompasses isOngoing()
+
+ boolean updateTicker = notification.notification.tickerText != null
+ && !TextUtils.equals(notification.notification.tickerText,
+ oldEntry.notification.notification.tickerText);
boolean isFirstAnyway = rowParent.indexOfChild(oldEntry.row) == 0;
if (contentsUnchanged && (orderUnchanged || isFirstAnyway)) {
if (DEBUG) Slog.d(TAG, "reusing notification for key: " + key);
@@ -665,10 +669,13 @@ public class PhoneStatusBar extends StatusBar {
addNotificationViews(key, notification);
}
+ // Update the veto button accordingly (and as a result, whether this row is
+ // swipe-dismissable)
+ updateNotificationVetoButton(oldEntry.row, notification);
+
// Restart the ticker if it's still running
- if (notification.notification.tickerText != null
- && !TextUtils.equals(notification.notification.tickerText,
- oldEntry.notification.notification.tickerText)) {
+ if (updateTicker) {
+ mTicker.halt();
tick(notification);
}
@@ -711,23 +718,7 @@ public class PhoneStatusBar extends StatusBar {
View row = inflater.inflate(R.layout.status_bar_notification_row, parent, false);
// wire up the veto button
- View vetoButton = row.findViewById(R.id.veto);
- if (notification.isClearable()) {
- final String _pkg = notification.pkg;
- final String _tag = notification.tag;
- final int _id = notification.id;
- vetoButton.setOnClickListener(new View.OnClickListener() {
- public void onClick(View v) {
- try {
- mBarService.onNotificationClear(_pkg, _tag, _id);
- } catch (RemoteException ex) {
- // system process is dead if we're here.
- }
- }
- });
- } else {
- vetoButton.setVisibility(View.GONE);
- }
+ View vetoButton = updateNotificationVetoButton(row, notification);
vetoButton.setContentDescription(mContext.getString(
R.string.accessibility_remove_notification));
@@ -897,23 +888,7 @@ public class PhoneStatusBar extends StatusBar {
LayoutInflater inflater = (LayoutInflater)mContext.getSystemService(
Context.LAYOUT_INFLATER_SERVICE);
View row = inflater.inflate(R.layout.status_bar_notification_row, parent, false);
- View vetoButton = row.findViewById(R.id.veto);
- if (entry.notification.isClearable()) {
- final String _pkg = sbn.pkg;
- final String _tag = sbn.tag;
- final int _id = sbn.id;
- vetoButton.setOnClickListener(new View.OnClickListener() {
- public void onClick(View v) {
- try {
- mBarService.onNotificationClear(_pkg, _tag, _id);
- } catch (RemoteException ex) {
- // system process is dead if we're here.
- }
- }
- });
- } else {
- vetoButton.setVisibility(View.GONE);
- }
+ View vetoButton = updateNotificationVetoButton(row, sbn);
vetoButton.setContentDescription(mContext.getString(
R.string.accessibility_remove_notification));
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
index 8d964e3..4f9eb38 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
@@ -61,7 +61,7 @@ public class NetworkController extends BroadcastReceiver {
// debug
static final String TAG = "StatusBar.NetworkController";
static final boolean DEBUG = false;
- static final boolean CHATTY = true; // additional diagnostics, but not logspew
+ static final boolean CHATTY = false; // additional diagnostics, but not logspew
// telephony
boolean mHspaDataDistinguishable;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
index 415a9a4..f0a10f3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
@@ -840,6 +840,9 @@ public class TabletStatusBar extends StatusBar implements
boolean orderUnchanged = notification.notification.when==oldNotification.notification.when
&& notification.priority == oldNotification.priority;
// priority now encompasses isOngoing()
+ boolean updateTicker = notification.notification.tickerText != null
+ && !TextUtils.equals(notification.notification.tickerText,
+ oldEntry.notification.notification.tickerText);
boolean isLastAnyway = rowParent.indexOfChild(oldEntry.row) == rowParent.getChildCount()-1;
if (contentsUnchanged && (orderUnchanged || isLastAnyway)) {
if (DEBUG) Slog.d(TAG, "reusing notification for key: " + key);
@@ -896,9 +899,8 @@ public class TabletStatusBar extends StatusBar implements
}
// Restart the ticker if it's still running
- if (notification.notification.tickerText != null
- && !TextUtils.equals(notification.notification.tickerText,
- oldEntry.notification.notification.tickerText)) {
+ if (updateTicker) {
+ mTicker.halt();
tick(key, notification, false);
}
@@ -1736,23 +1738,7 @@ public class TabletStatusBar extends StatusBar implements
Context.LAYOUT_INFLATER_SERVICE);
View row = inflater.inflate(R.layout.status_bar_notification_row, parent, false);
workAroundBadLayerDrawableOpacity(row);
- View vetoButton = row.findViewById(R.id.veto);
- if (entry.notification.isClearable()) {
- final String _pkg = sbn.pkg;
- final String _tag = sbn.tag;
- final int _id = sbn.id;
- vetoButton.setOnClickListener(new View.OnClickListener() {
- public void onClick(View v) {
- try {
- mBarService.onNotificationClear(_pkg, _tag, _id);
- } catch (RemoteException ex) {
- // system process is dead if we're here.
- }
- }
- });
- } else {
- vetoButton.setVisibility(View.GONE);
- }
+ View vetoButton = updateNotificationVetoButton(row, entry.notification);
vetoButton.setContentDescription(mContext.getString(
R.string.accessibility_remove_notification));