summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--data/etc/platform.xml1
-rw-r--r--graphics/java/android/graphics/drawable/LayerDrawable.java11
-rw-r--r--packages/SystemUI/AndroidManifest.xml1
-rw-r--r--packages/SystemUI/res/anim/recent_appear.xml (renamed from packages/SystemUI/res/drawable/recents_thumbnail_layers.xml)11
-rw-r--r--packages/SystemUI/res/layout-land/status_bar_recent_item.xml12
-rw-r--r--packages/SystemUI/res/layout-port/status_bar_recent_item.xml10
-rw-r--r--packages/SystemUI/res/layout-sw600dp/status_bar_recent_item.xml10
-rw-r--r--packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java217
-rw-r--r--packages/SystemUI/src/com/android/systemui/recent/RecentsVerticalScrollView.java43
-rw-r--r--packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java17
-rw-r--r--packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java32
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java7
-rwxr-xr-xpolicy/src/com/android/internal/policy/impl/PhoneWindowManager.java53
13 files changed, 340 insertions, 85 deletions
diff --git a/data/etc/platform.xml b/data/etc/platform.xml
index 05bd626..0353a47 100644
--- a/data/etc/platform.xml
+++ b/data/etc/platform.xml
@@ -155,6 +155,7 @@
<assign-permission name="android.permission.DEVICE_POWER" uid="shell" />
<assign-permission name="android.permission.INSTALL_LOCATION_PROVIDER" uid="shell" />
<assign-permission name="android.permission.BACKUP" uid="shell" />
+ <assign-permission name="android.permission.FORCE_STOP_PACKAGES" uid="shell" />
<assign-permission name="android.permission.MODIFY_AUDIO_SETTINGS" uid="media" />
<assign-permission name="android.permission.ACCESS_DRM" uid="media" />
diff --git a/graphics/java/android/graphics/drawable/LayerDrawable.java b/graphics/java/android/graphics/drawable/LayerDrawable.java
index 49dbbca..6698d31 100644
--- a/graphics/java/android/graphics/drawable/LayerDrawable.java
+++ b/graphics/java/android/graphics/drawable/LayerDrawable.java
@@ -277,10 +277,19 @@ public class LayerDrawable extends Drawable implements Drawable.Callback {
*/
public boolean setDrawableByLayerId(int id, Drawable drawable) {
final ChildDrawable[] layers = mLayerState.mChildren;
- drawable.setCallback(this);
for (int i = mLayerState.mNum - 1; i >= 0; i--) {
if (layers[i].mId == id) {
+ if (layers[i].mDrawable != null) {
+ if (drawable != null) {
+ Rect bounds = layers[i].mDrawable.getBounds();
+ drawable.setBounds(bounds);
+ }
+ layers[i].mDrawable.setCallback(null);
+ }
+ if (drawable != null) {
+ drawable.setCallback(this);
+ }
layers[i].mDrawable = drawable;
return true;
}
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index 2080fad..d10911f 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -29,6 +29,7 @@
<!-- started from PhoneWindowManager
TODO: Should have an android:permission attribute -->
<service android:name=".screenshot.TakeScreenshotService"
+ android:process=":screenshot"
android:exported="false" />
<service android:name=".LoadAverageService"
diff --git a/packages/SystemUI/res/drawable/recents_thumbnail_layers.xml b/packages/SystemUI/res/anim/recent_appear.xml
index 6cae2c4..4400d9d 100644
--- a/packages/SystemUI/res/drawable/recents_thumbnail_layers.xml
+++ b/packages/SystemUI/res/anim/recent_appear.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 The Android Open Source Project
+<!-- Copyright (C) 2010 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -13,7 +13,8 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
- <item android:drawable="@drawable/recents_thumbnail_bg" android:id="@+id/base_layer"/>
- <item android:drawable="@drawable/recents_thumbnail_overlay" android:id="@+id/overlay_layer"/>
-</layer-list> \ No newline at end of file
+
+<alpha xmlns:android="http://schemas.android.com/apk/res/android"
+ android:fromAlpha="0.0" android:toAlpha="1.0"
+ android:duration="@android:integer/config_shortAnimTime"
+ />
diff --git a/packages/SystemUI/res/layout-land/status_bar_recent_item.xml b/packages/SystemUI/res/layout-land/status_bar_recent_item.xml
index 8c29042..16008a3 100644
--- a/packages/SystemUI/res/layout-land/status_bar_recent_item.xml
+++ b/packages/SystemUI/res/layout-land/status_bar_recent_item.xml
@@ -32,8 +32,14 @@
android:layout_marginLeft="@dimen/status_bar_recents_thumbnail_left_margin"
android:scaleType="center"
android:clickable="true"
- android:background="@drawable/recents_thumbnail_layers"
- />
+ android:background="@drawable/recents_thumbnail_bg"
+ android:foreground="@drawable/recents_thumbnail_overlay">
+ <ImageView android:id="@+id/app_thumbnail_image"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:visibility="invisible"
+ />
+ </FrameLayout>
<ImageView android:id="@+id/app_icon"
android:layout_width="wrap_content"
@@ -45,6 +51,7 @@
android:maxWidth="@dimen/status_bar_recents_thumbnail_max_width"
android:maxHeight="@dimen/status_bar_recents_thumbnail_max_height"
android:adjustViewBounds="true"
+ android:visibility="invisible"
/>
<TextView android:id="@+id/app_label"
@@ -60,6 +67,7 @@
android:layout_marginLeft="@dimen/recents_thumbnail_bg_padding_left"
android:singleLine="true"
android:ellipsize="marquee"
+ android:visibility="invisible"
/>
<TextView android:id="@+id/app_description"
diff --git a/packages/SystemUI/res/layout-port/status_bar_recent_item.xml b/packages/SystemUI/res/layout-port/status_bar_recent_item.xml
index c705a69..c0fce71 100644
--- a/packages/SystemUI/res/layout-port/status_bar_recent_item.xml
+++ b/packages/SystemUI/res/layout-port/status_bar_recent_item.xml
@@ -32,8 +32,14 @@
android:clickable="true"
android:layout_marginLeft="@dimen/status_bar_recents_thumbnail_left_margin"
android:scaleType="center"
- android:background="@drawable/recents_thumbnail_layers"
- />
+ android:background="@drawable/recents_thumbnail_bg"
+ android:foreground="@drawable/recents_thumbnail_overlay">
+ <ImageView android:id="@+id/app_thumbnail_image"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:visibility="invisible"
+ />
+ </FrameLayout>
<ImageView android:id="@+id/app_icon"
android:layout_width="wrap_content"
diff --git a/packages/SystemUI/res/layout-sw600dp/status_bar_recent_item.xml b/packages/SystemUI/res/layout-sw600dp/status_bar_recent_item.xml
index 386ce30..5306508 100644
--- a/packages/SystemUI/res/layout-sw600dp/status_bar_recent_item.xml
+++ b/packages/SystemUI/res/layout-sw600dp/status_bar_recent_item.xml
@@ -32,8 +32,14 @@
android:layout_marginLeft="@dimen/status_bar_recents_thumbnail_left_margin"
android:scaleType="center"
android:clickable="true"
- android:background="@drawable/recents_thumbnail_layers"
- />
+ android:background="@drawable/recents_thumbnail_bg"
+ android:foreground="@drawable/recents_thumbnail_overlay">
+ <ImageView android:id="@+id/app_thumbnail_image"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:visibility="invisible"
+ />
+ </FrameLayout>
<ImageView android:id="@+id/app_icon"
android:layout_width="wrap_content"
diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java b/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
index 28a5cc8..8c03ef8 100644
--- a/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
@@ -41,6 +41,10 @@ import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.LayerDrawable;
import android.net.Uri;
+import android.os.AsyncTask;
+import android.os.Handler;
+import android.os.Process;
+import android.os.SystemClock;
import android.provider.Settings;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
@@ -51,12 +55,15 @@ import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
+import android.view.animation.AnimationUtils;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.BaseAdapter;
+import android.widget.HorizontalScrollView;
import android.widget.ImageView;
import android.widget.PopupMenu;
import android.widget.RelativeLayout;
+import android.widget.ScrollView;
import android.widget.TextView;
import com.android.systemui.R;
@@ -68,11 +75,12 @@ import com.android.systemui.statusbar.tablet.TabletStatusBar;
public class RecentsPanelView extends RelativeLayout
implements OnItemClickListener, RecentsCallback, StatusBarPanel, Animator.AnimatorListener {
static final String TAG = "RecentsListView";
- static final boolean DEBUG = TabletStatusBar.DEBUG || PhoneStatusBar.DEBUG;
+ static final boolean DEBUG = TabletStatusBar.DEBUG || PhoneStatusBar.DEBUG || false;
private static final int DISPLAY_TASKS = 20;
private static final int MAX_TASKS = DISPLAY_TASKS + 1; // allow extra for non-apps
private StatusBar mBar;
private ArrayList<ActivityDescription> mActivityDescriptions;
+ private AsyncTask<Void, Integer, Void> mThumbnailLoader;
private int mIconDpi;
private View mRecentsScrim;
private View mRecentsGlowView;
@@ -87,31 +95,47 @@ public class RecentsPanelView extends RelativeLayout
private Choreographer mChoreo;
private View mRecentsDismissButton;
private ActivityDescriptionAdapter mListAdapter;
+ private final Handler mHandler = new Handler();
- /* package */ final static class ActivityDescription {
+ /* package */ final class ActivityDescription {
+ final ActivityManager.RecentTaskInfo recentTaskInfo;
+ final ResolveInfo resolveInfo;
int taskId; // application task id for curating apps
- Bitmap thumbnail; // generated by Activity.onCreateThumbnail()
- Drawable icon; // application package icon
- String label; // application package label
- CharSequence description; // generated by Activity.onCreateDescription()
Intent intent; // launch intent for application
Matrix matrix; // arbitrary rotation matrix to correct orientation
String packageName; // used to override animations (see onClick())
int position; // position in list
- public ActivityDescription(Bitmap _thumbnail,
- Drawable _icon, String _label, CharSequence _desc, Intent _intent,
- int _id, int _pos, String _packageName)
- {
- thumbnail = _thumbnail;
- icon = _icon;
- label = _label;
- description = _desc;
+ private Bitmap mThumbnail; // generated by Activity.onCreateThumbnail()
+ private Drawable mIcon; // application package icon
+ private CharSequence mLabel; // application package label
+
+ public ActivityDescription(ActivityManager.RecentTaskInfo _recentInfo,
+ ResolveInfo _resolveInfo, Intent _intent,
+ int _id, int _pos, String _packageName) {
+ recentTaskInfo = _recentInfo;
+ resolveInfo = _resolveInfo;
intent = _intent;
taskId = _id;
position = _pos;
packageName = _packageName;
}
+
+ public CharSequence getLabel() {
+ return mLabel;
+ }
+
+ public Drawable getIcon() {
+ return mIcon;
+ }
+
+ public void setThumbnail(Bitmap thumbnail) {
+ mThumbnail = compositeBitmap(mGlowBitmap, thumbnail);
+ }
+
+ public Bitmap getThumbnail() {
+ return mThumbnail;
+ }
}
private final class OnLongClickDelegate implements View.OnLongClickListener {
@@ -126,6 +150,7 @@ public class RecentsPanelView extends RelativeLayout
/* package */ final static class ViewHolder {
View thumbnailView;
+ ImageView thumbnailViewImage;
ImageView iconView;
TextView labelView;
TextView descriptionView;
@@ -157,6 +182,8 @@ public class RecentsPanelView extends RelativeLayout
convertView = mInflater.inflate(R.layout.status_bar_recent_item, null);
holder = new ViewHolder();
holder.thumbnailView = convertView.findViewById(R.id.app_thumbnail);
+ holder.thumbnailViewImage = (ImageView) convertView.findViewById(
+ R.id.app_thumbnail_image);
holder.iconView = (ImageView) convertView.findViewById(R.id.app_icon);
holder.labelView = (TextView) convertView.findViewById(R.id.app_label);
holder.descriptionView = (TextView) convertView.findViewById(R.id.app_description);
@@ -169,11 +196,10 @@ public class RecentsPanelView extends RelativeLayout
final int activityId = mActivityDescriptions.size() - position - 1;
final ActivityDescription activityDescription = mActivityDescriptions.get(activityId);
- final Bitmap thumb = activityDescription.thumbnail;
- updateDrawable(holder.thumbnailView, compositeBitmap(mGlowBitmap, thumb));
- holder.iconView.setImageDrawable(activityDescription.icon);
- holder.labelView.setText(activityDescription.label);
- holder.descriptionView.setText(activityDescription.description);
+ holder.thumbnailViewImage.setImageBitmap(activityDescription.getThumbnail());
+ holder.iconView.setImageDrawable(activityDescription.getIcon());
+ holder.labelView.setText(activityDescription.getLabel());
+ holder.descriptionView.setText(activityDescription.recentTaskInfo.description);
holder.thumbnailView.setTag(activityDescription);
holder.thumbnailView.setOnLongClickListener(new OnLongClickDelegate(convertView));
holder.activityDescription = activityDescription;
@@ -201,20 +227,6 @@ public class RecentsPanelView extends RelativeLayout
return x >= l && x < r && y >= t && y < b;
}
- private void updateDrawable(View thumbnailView, Bitmap bitmap) {
- Drawable d = thumbnailView.getBackground();
- if (d instanceof LayerDrawable) {
- LayerDrawable layerD = (LayerDrawable) d;
- Drawable thumb = layerD.findDrawableByLayerId(R.id.base_layer);
- if (thumb != null) {
- layerD.setDrawableByLayerId(R.id.base_layer,
- new BitmapDrawable(getResources(), bitmap));
- return;
- }
- }
- Log.w(TAG, "Failed to update drawable");
- }
-
public void show(boolean show, boolean animate) {
if (animate) {
if (mShowing != show) {
@@ -373,12 +385,12 @@ public class RecentsPanelView extends RelativeLayout
}
}
- private Drawable getFullResDefaultActivityIcon() {
+ Drawable getFullResDefaultActivityIcon() {
return getFullResIcon(Resources.getSystem(),
com.android.internal.R.mipmap.sym_def_app_icon);
}
- private Drawable getFullResIcon(Resources resources, int iconId) {
+ Drawable getFullResIcon(Resources resources, int iconId) {
try {
return resources.getDrawableForDensity(iconId, mIconDpi);
} catch (Resources.NotFoundException e) {
@@ -442,15 +454,13 @@ public class RecentsPanelView extends RelativeLayout
final String title = info.loadLabel(pm).toString();
// Drawable icon = info.loadIcon(pm);
Drawable icon = getFullResIcon(resolveInfo, pm);
- int id = recentTasks.get(i).id;
+ int id = recentInfo.id;
if (title != null && title.length() > 0 && icon != null) {
if (DEBUG) Log.v(TAG, "creating activity desc for id=" + id + ", label=" + title);
ActivityManager.TaskThumbnails thumbs = am.getTaskThumbnails(
recentInfo.persistentId);
- ActivityDescription item = new ActivityDescription(
- thumbs != null ? thumbs.mainThumbnail : null,
- icon, title, recentInfo.description, intent, id,
- index, info.packageName);
+ ActivityDescription item = new ActivityDescription(recentInfo,
+ resolveInfo, intent, id, index, info.packageName);
activityDescriptions.add(item);
++index;
} else {
@@ -474,12 +484,137 @@ public class RecentsPanelView extends RelativeLayout
return desc;
}
+ void loadActivityDescription(ActivityDescription ad, int index) {
+ final ActivityManager am = (ActivityManager)
+ mContext.getSystemService(Context.ACTIVITY_SERVICE);
+ final PackageManager pm = mContext.getPackageManager();
+ ActivityManager.TaskThumbnails thumbs = am.getTaskThumbnails(
+ ad.recentTaskInfo.persistentId);
+ CharSequence label = ad.resolveInfo.activityInfo.loadLabel(pm);
+ Drawable icon = getFullResIcon(ad.resolveInfo, pm);
+ if (DEBUG) Log.v(TAG, "Loaded bitmap for #" + index + " in "
+ + ad + ": " + thumbs.mainThumbnail);
+ synchronized (ad) {
+ ad.mLabel = label;
+ ad.mIcon = icon;
+ ad.setThumbnail(thumbs.mainThumbnail);
+ }
+ }
+
+ void applyActivityDescription(ActivityDescription ad, int index, boolean anim) {
+ synchronized (ad) {
+ if (mRecentsContainer != null) {
+ ViewGroup container = mRecentsContainer;
+ if (container instanceof HorizontalScrollView
+ || container instanceof ScrollView) {
+ container = (ViewGroup)container.findViewById(
+ R.id.recents_linear_layout);
+ }
+ // Look for a view showing this thumbnail, to update.
+ for (int i=0; i<container.getChildCount(); i++) {
+ View v = container.getChildAt(i);
+ if (v.getTag() instanceof ViewHolder) {
+ ViewHolder h = (ViewHolder)v.getTag();
+ if (h.activityDescription == ad) {
+ if (DEBUG) Log.v(TAG, "Updatating thumbnail #" + index + " in "
+ + h.activityDescription
+ + ": " + ad.getThumbnail());
+ h.iconView.setImageDrawable(ad.getIcon());
+ if (anim) {
+ h.iconView.setAnimation(AnimationUtils.loadAnimation(
+ mContext, R.anim.recent_appear));
+ }
+ h.iconView.setVisibility(View.VISIBLE);
+ h.labelView.setText(ad.getLabel());
+ if (anim) {
+ h.labelView.setAnimation(AnimationUtils.loadAnimation(
+ mContext, R.anim.recent_appear));
+ }
+ h.labelView.setVisibility(View.VISIBLE);
+ Bitmap thumbnail = ad.getThumbnail();
+ if (thumbnail != null) {
+ // Should remove the default image in the frame
+ // that this now covers, to improve scrolling speed.
+ // That can't be done until the anim is complete though.
+ h.thumbnailViewImage.setImageBitmap(thumbnail);
+ if (anim) {
+ h.thumbnailViewImage.setAnimation(AnimationUtils.loadAnimation(
+ mContext, R.anim.recent_appear));
+ }
+ h.thumbnailViewImage.setVisibility(View.VISIBLE);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
private void refreshApplicationList() {
+ if (mThumbnailLoader != null) {
+ mThumbnailLoader.cancel(false);
+ mThumbnailLoader = null;
+ }
mActivityDescriptions = getRecentTasks();
mListAdapter.notifyDataSetInvalidated();
if (mActivityDescriptions.size() > 0) {
if (DEBUG) Log.v(TAG, "Showing " + mActivityDescriptions.size() + " apps");
updateUiElements(getResources().getConfiguration());
+ final ArrayList<ActivityDescription> descriptions = mActivityDescriptions;
+ loadActivityDescription(descriptions.get(0), 0);
+ applyActivityDescription(descriptions.get(0), 0, false);
+ if (descriptions.size() > 1) {
+ mThumbnailLoader = new AsyncTask<Void, Integer, Void>() {
+ @Override
+ protected void onProgressUpdate(Integer... values) {
+ final ActivityDescription ad = descriptions.get(values[0]);
+ if (!isCancelled()) {
+ applyActivityDescription(ad, values[0], true);
+ }
+ // This is to prevent the loader thread from getting ahead
+ // of our UI updates.
+ mHandler.post(new Runnable() {
+ @Override public void run() {
+ synchronized (ad) {
+ ad.notifyAll();
+ }
+ }
+ });
+ }
+
+ @Override
+ protected Void doInBackground(Void... params) {
+ final int origPri = Process.getThreadPriority(Process.myTid());
+ Process.setThreadPriority(Process.THREAD_GROUP_BG_NONINTERACTIVE);
+ long nextTime = SystemClock.uptimeMillis();
+ for (int i=1; i<descriptions.size(); i++) {
+ ActivityDescription ad = descriptions.get(i);
+ loadActivityDescription(ad, i);
+ long now = SystemClock.uptimeMillis();
+ nextTime += 200;
+ if (nextTime > now) {
+ try {
+ Thread.sleep(nextTime-now);
+ } catch (InterruptedException e) {
+ }
+ }
+ if (isCancelled()) {
+ break;
+ }
+ synchronized (ad) {
+ publishProgress(i);
+ try {
+ ad.wait(500);
+ } catch (InterruptedException e) {
+ }
+ }
+ }
+ Process.setThreadPriority(origPri);
+ return null;
+ }
+ };
+ mThumbnailLoader.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
+ }
} else {
// Immediately hide this panel
if (DEBUG) Log.v(TAG, "Nothing to show");
@@ -548,7 +683,7 @@ public class RecentsPanelView extends RelativeLayout
public void handleSwipe(View view) {
ActivityDescription ad = ((ViewHolder) view.getTag()).activityDescription;
- if (DEBUG) Log.v(TAG, "Jettison " + ad.label);
+ if (DEBUG) Log.v(TAG, "Jettison " + ad.getLabel());
mActivityDescriptions.remove(ad);
// Handled by widget containers to enable LayoutTransitions properly
diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentsVerticalScrollView.java b/packages/SystemUI/src/com/android/systemui/recent/RecentsVerticalScrollView.java
index 89900a1..959328f 100644
--- a/packages/SystemUI/src/com/android/systemui/recent/RecentsVerticalScrollView.java
+++ b/packages/SystemUI/src/com/android/systemui/recent/RecentsVerticalScrollView.java
@@ -66,20 +66,34 @@ public class RecentsVerticalScrollView extends ScrollView implements SwipeHelper
private void update() {
mLinearLayout.removeAllViews();
+ // Once we can clear the data associated with individual item views,
+ // we can get rid of the removeAllViews() and the code below will
+ // recycle them.
for (int i = 0; i < mAdapter.getCount(); i++) {
- final View view = mAdapter.getView(i, null, mLinearLayout);
- view.setClickable(true);
- view.setOnLongClickListener(mOnLongClick);
-
- final View thumbnail = getChildContentView(view);
- // thumbnail is set to clickable in the layout file
- thumbnail.setOnClickListener(new OnClickListener() {
- public void onClick(View v) {
- mCallback.handleOnClick(view);
- }
- });
+ View old = null;
+ if (i < mLinearLayout.getChildCount()) {
+ old = mLinearLayout.getChildAt(i);
+ old.setVisibility(View.VISIBLE);
+ }
+ final View view = mAdapter.getView(i, old, mLinearLayout);
+
+ if (old == null) {
+ view.setClickable(true);
+ view.setOnLongClickListener(mOnLongClick);
- mLinearLayout.addView(view);
+ final View thumbnail = getChildContentView(view);
+ // thumbnail is set to clickable in the layout file
+ thumbnail.setOnClickListener(new OnClickListener() {
+ public void onClick(View v) {
+ mCallback.handleOnClick(view);
+ }
+ });
+
+ mLinearLayout.addView(view);
+ }
+ }
+ for (int i = mAdapter.getCount(); i < mLinearLayout.getChildCount(); i++) {
+ mLinearLayout.getChildAt(i).setVisibility(View.GONE);
}
// Scroll to end after layout.
post(new Runnable() {
@@ -128,8 +142,9 @@ public class RecentsVerticalScrollView extends ScrollView implements SwipeHelper
final float y = ev.getY() + getScrollY();
for (int i = 0; i < mLinearLayout.getChildCount(); i++) {
View item = mLinearLayout.getChildAt(i);
- if (x >= item.getLeft() && x < item.getRight()
- && y >= item.getTop() && y < item.getBottom()) {
+ if (item.getVisibility() == View.VISIBLE
+ && x >= item.getLeft() && x < item.getRight()
+ && y >= item.getTop() && y < item.getBottom()) {
return item;
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
index 86dc9a6..fe255cb 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
@@ -69,6 +69,7 @@ import java.util.Date;
class SaveImageInBackgroundData {
Context context;
Bitmap image;
+ Runnable finisher;
int result;
}
@@ -141,6 +142,7 @@ class SaveImageInBackgroundTask extends AsyncTask<SaveImageInBackgroundData, Voi
Toast.makeText(params.context, R.string.screenshot_saving_toast,
Toast.LENGTH_SHORT).show();
}
+ params.finisher.run();
};
}
@@ -231,11 +233,9 @@ class GlobalScreenshot {
WindowManager.LayoutParams.FLAG_FULLSCREEN
| WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED
| WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED_SYSTEM
- | WindowManager.LayoutParams.FLAG_KEEP_SURFACE_WHILE_ANIMATING
| WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
| WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED,
PixelFormat.TRANSLUCENT);
- mWindowLayoutParams.token = new Binder();
mWindowLayoutParams.setTitle("ScreenshotAnimation");
mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
mDisplay = mWindowManager.getDefaultDisplay();
@@ -244,10 +244,11 @@ class GlobalScreenshot {
/**
* Creates a new worker thread and saves the screenshot to the media store.
*/
- private void saveScreenshotInWorkerThread() {
+ private void saveScreenshotInWorkerThread(Runnable finisher) {
SaveImageInBackgroundData data = new SaveImageInBackgroundData();
data.context = mContext;
data.image = mScreenBitmap;
+ data.finisher = finisher;
new SaveImageInBackgroundTask().execute(data);
}
@@ -269,7 +270,7 @@ class GlobalScreenshot {
/**
* Takes a screenshot of the current display and shows an animation.
*/
- void takeScreenshot() {
+ void takeScreenshot(Runnable finisher) {
// 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);
@@ -302,18 +303,19 @@ class GlobalScreenshot {
if (mScreenBitmap == null) {
Toast.makeText(mContext, R.string.screenshot_failed_toast,
Toast.LENGTH_SHORT).show();
+ finisher.run();
return;
}
// Start the post-screenshot animation
- startAnimation();
+ startAnimation(finisher);
}
/**
* Starts the animation after taking the screenshot
*/
- private void startAnimation() {
+ private void startAnimation(final Runnable finisher) {
// Add the view for the animation
mScreenshotView.setImageBitmap(mScreenBitmap);
mScreenshotLayout.requestFocus();
@@ -332,8 +334,7 @@ class GlobalScreenshot {
@Override
public void onAnimationEnd(Animator animation) {
// Save the screenshot once we have a bit of time now
- saveScreenshotInWorkerThread();
-
+ saveScreenshotInWorkerThread(finisher);
mWindowManager.removeView(mScreenshotLayout);
}
});
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java b/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java
index 35eaedf..05ff8be 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java
@@ -26,7 +26,11 @@ 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;
@@ -39,12 +43,30 @@ public class TakeScreenshotService extends Service {
private static GlobalScreenshot mScreenshot;
+ private Handler mHandler = new Handler() {
+ @Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case 1:
+ final Messenger callback = msg.replyTo;
+ if (mScreenshot == null) {
+ mScreenshot = new GlobalScreenshot(TakeScreenshotService.this);
+ }
+ mScreenshot.takeScreenshot(new Runnable() {
+ @Override public void run() {
+ Message reply = Message.obtain(null, 1);
+ try {
+ callback.send(reply);
+ } catch (RemoteException e) {
+ }
+ }
+ });
+ }
+ }
+ };
+
@Override
public IBinder onBind(Intent intent) {
- if (mScreenshot == null) {
- mScreenshot = new GlobalScreenshot(this);
- }
- mScreenshot.takeScreenshot();
- return null;
+ return new Messenger(mHandler).getBinder();
}
}
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 2e14bef..e894831 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -17,6 +17,7 @@
package com.android.systemui.statusbar.phone;
import android.animation.ObjectAnimator;
+import android.app.ActivityManager;
import android.app.ActivityManagerNative;
import android.app.Dialog;
import android.app.Notification;
@@ -371,9 +372,11 @@ public class PhoneStatusBar extends StatusBar {
WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL,
WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
| WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM
- | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH
- | WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED,
+ | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
(translucent ? PixelFormat.OPAQUE : PixelFormat.TRANSLUCENT));
+ if (ActivityManager.isHighEndGfx(mDisplay)) {
+ lp.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
+ }
lp.gravity = Gravity.BOTTOM | Gravity.LEFT;
lp.setTitle("RecentsPanel");
lp.windowAnimations = R.style.Animation_RecentPanel;
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index b60a038..7764e35 100755
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -41,6 +41,8 @@ import android.os.Binder;
import android.os.Handler;
import android.os.IBinder;
import android.os.LocalPowerManager;
+import android.os.Message;
+import android.os.Messenger;
import android.os.PowerManager;
import android.os.RemoteException;
import android.os.ServiceManager;
@@ -2396,22 +2398,67 @@ public class PhoneWindowManager implements WindowManagerPolicy {
}
}
+ ServiceConnection mScreenshotConnection = null;
+ Runnable mScreenshotTimeout = null;
+
+ void finishScreenshot(ServiceConnection conn) {
+ if (mScreenshotConnection == conn) {
+ mContext.unbindService(conn);
+ mScreenshotConnection = null;
+ if (mScreenshotTimeout != null) {
+ mHandler.removeCallbacks(mScreenshotTimeout);
+ mScreenshotTimeout = null;
+ }
+ }
+ }
+
private void takeScreenshot() {
mHandler.post(new Runnable() {
@Override
public void run() {
+ if (mScreenshotConnection != null) {
+ return;
+ }
ComponentName cn = new ComponentName("com.android.systemui",
"com.android.systemui.screenshot.TakeScreenshotService");
Intent intent = new Intent();
intent.setComponent(cn);
ServiceConnection conn = new ServiceConnection() {
@Override
- public void onServiceConnected(ComponentName name, IBinder service) {}
+ public void onServiceConnected(ComponentName name, IBinder service) {
+ if (mScreenshotConnection != this) {
+ return;
+ }
+ Messenger messenger = new Messenger(service);
+ Message msg = Message.obtain(null, 1);
+ final ServiceConnection myConn = this;
+ Handler h = new Handler(mHandler.getLooper()) {
+ @Override
+ public void handleMessage(Message msg) {
+ finishScreenshot(myConn);
+ }
+ };
+ msg.replyTo = new Messenger(h);
+ try {
+ messenger.send(msg);
+ } catch (RemoteException e) {
+ }
+ }
@Override
public void onServiceDisconnected(ComponentName name) {}
};
- mContext.bindService(intent, conn, Context.BIND_AUTO_CREATE);
- mContext.unbindService(conn);
+ if (mContext.bindService(intent, conn, Context.BIND_AUTO_CREATE)) {
+ mScreenshotConnection = conn;
+ mScreenshotTimeout = new Runnable() {
+ @Override public void run() {
+ if (mScreenshotConnection != null) {
+ finishScreenshot(mScreenshotConnection);
+ }
+ }
+
+ };
+ mHandler.postDelayed(mScreenshotTimeout, 10000);
+ }
}
});
}