diff options
Diffstat (limited to 'packages/SystemUI/src')
11 files changed, 307 insertions, 84 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java index 0369ab5..5d74604 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java @@ -74,7 +74,11 @@ public class FlashlightTile extends QSTile<QSTile.BooleanState> implements state.visible = mFlashlightController.isAvailable(); state.label = mHost.getContext().getString(R.string.quick_settings_flashlight_label); if (arg instanceof UserBoolean) { - state.value = ((UserBoolean) arg).value; + boolean value = ((UserBoolean) arg).value; + if (value == state.value) { + return; + } + state.value = value; } final AnimationIcon icon = state.value ? mEnable : mDisable; icon.setAllowAnimation(arg instanceof UserBoolean && ((UserBoolean) arg).userInitiated); diff --git a/packages/SystemUI/src/com/android/systemui/recents/Recents.java b/packages/SystemUI/src/com/android/systemui/recents/Recents.java index bbd3e60..7d2b5c87 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/Recents.java +++ b/packages/SystemUI/src/com/android/systemui/recents/Recents.java @@ -32,6 +32,7 @@ import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Rect; +import android.os.AsyncTask; import android.os.Handler; import android.os.SystemClock; import android.os.UserHandle; @@ -40,6 +41,7 @@ import android.util.Pair; import android.view.Display; import android.view.LayoutInflater; import android.view.View; + import com.android.systemui.R; import com.android.systemui.RecentsComponent; import com.android.systemui.SystemUI; @@ -184,12 +186,16 @@ public class Recents extends SystemUI // Header (for transition) TaskViewHeader mHeaderBar; + final Object mHeaderBarLock = new Object(); TaskStackView mDummyStackView; // Variables to keep track of if we need to start recents after binding boolean mTriggeredFromAltTab; long mLastToggleTime; + Bitmap mThumbnailTransitionBitmapCache; + Task mThumbnailTransitionBitmapCacheKey; + public Recents() { } @@ -360,13 +366,16 @@ public class Recents extends SystemUI void preloadRecentsInternal() { // Preload only the raw task list into a new load plan (which will be consumed by the // RecentsActivity) + ActivityManager.RunningTaskInfo topTask = mSystemServicesProxy.getTopMostTask(); + MutableBoolean topTaskHome = new MutableBoolean(true); RecentsTaskLoader loader = RecentsTaskLoader.getInstance(); sInstanceLoadPlan = loader.createLoadPlan(mContext); - - ActivityManager.RunningTaskInfo topTask = mSystemServicesProxy.getTopMostTask(); - MutableBoolean isTopTaskHome = new MutableBoolean(true); - if (topTask != null && mSystemServicesProxy.isRecentsTopMost(topTask, isTopTaskHome)) { - sInstanceLoadPlan.preloadRawTasks(isTopTaskHome.value); + if (topTask != null && !mSystemServicesProxy.isRecentsTopMost(topTask, topTaskHome)) { + sInstanceLoadPlan.preloadRawTasks(topTaskHome.value); + loader.preloadTasks(sInstanceLoadPlan, topTaskHome.value); + TaskStack top = sInstanceLoadPlan.getAllTaskStacks().get(0); + preCacheThumbnailTransitionBitmapAsync(topTask, top, mDummyStackView, + topTaskHome.value); } } @@ -513,12 +522,14 @@ public class Recents extends SystemUI algo.computeRects(mWindowRect.width(), mWindowRect.height(), taskStackBounds); Rect taskViewSize = algo.getUntransformedTaskViewSize(); int taskBarHeight = res.getDimensionPixelSize(R.dimen.recents_task_bar_height); - mHeaderBar = (TaskViewHeader) mInflater.inflate(R.layout.recents_task_view_header, null, - false); - mHeaderBar.measure( - View.MeasureSpec.makeMeasureSpec(taskViewSize.width(), View.MeasureSpec.EXACTLY), - View.MeasureSpec.makeMeasureSpec(taskBarHeight, View.MeasureSpec.EXACTLY)); - mHeaderBar.layout(0, 0, taskViewSize.width(), taskBarHeight); + synchronized (mHeaderBarLock) { + mHeaderBar = (TaskViewHeader) mInflater.inflate(R.layout.recents_task_view_header, null, + false); + mHeaderBar.measure( + View.MeasureSpec.makeMeasureSpec(taskViewSize.width(), View.MeasureSpec.EXACTLY), + View.MeasureSpec.makeMeasureSpec(taskBarHeight, View.MeasureSpec.EXACTLY)); + mHeaderBar.layout(0, 0, taskViewSize.width(), taskBarHeight); + } } /** Prepares the search bar app widget */ @@ -607,30 +618,27 @@ public class Recents extends SystemUI */ ActivityOptions getThumbnailTransitionActivityOptions(ActivityManager.RunningTaskInfo topTask, TaskStack stack, TaskStackView stackView) { + // Update the destination rect Task toTask = new Task(); TaskViewTransform toTransform = getThumbnailTransitionTransform(stack, stackView, topTask.id, toTask); - if (toTransform != null && toTask.key != null) { - Rect toTaskRect = toTransform.rect; - int toHeaderWidth = (int) (mHeaderBar.getMeasuredWidth() * toTransform.scale); - int toHeaderHeight = (int) (mHeaderBar.getMeasuredHeight() * toTransform.scale); - Bitmap thumbnail = Bitmap.createBitmap(toHeaderWidth, toHeaderHeight, - Bitmap.Config.ARGB_8888); - if (Constants.DebugFlags.App.EnableTransitionThumbnailDebugMode) { - thumbnail.eraseColor(0xFFff0000); - } else { - Canvas c = new Canvas(thumbnail); - c.scale(toTransform.scale, toTransform.scale); - mHeaderBar.rebindToTask(toTask); - mHeaderBar.draw(c); - c.setBitmap(null); - } - Bitmap thumbnailImmutable = thumbnail.createAshmemBitmap(); - + Rect toTaskRect = toTransform.rect; + Bitmap thumbnail; + if (mThumbnailTransitionBitmapCacheKey != null + && mThumbnailTransitionBitmapCacheKey.key != null + && mThumbnailTransitionBitmapCacheKey.key.equals(toTask.key)) { + thumbnail = mThumbnailTransitionBitmapCache; + mThumbnailTransitionBitmapCacheKey = null; + mThumbnailTransitionBitmapCache = null; + } else { + preloadIcon(topTask); + thumbnail = drawThumbnailTransitionBitmap(toTask, toTransform); + } + if (thumbnail != null) { mStartAnimationTriggered = false; return ActivityOptions.makeThumbnailAspectScaleDownAnimation(mDummyStackView, - thumbnailImmutable, toTaskRect.left, toTaskRect.top, toTaskRect.width(), + thumbnail, toTaskRect.left, toTaskRect.top, toTaskRect.width(), toTaskRect.height(), mHandler, this); } @@ -638,6 +646,72 @@ public class Recents extends SystemUI return getUnknownTransitionActivityOptions(); } + /** + * Preloads the icon of a task. + */ + void preloadIcon(ActivityManager.RunningTaskInfo task) { + + // Ensure that we load the running task's icon + RecentsTaskLoadPlan.Options launchOpts = new RecentsTaskLoadPlan.Options(); + launchOpts.runningTaskId = task.id; + launchOpts.loadThumbnails = false; + launchOpts.onlyLoadForCache = true; + RecentsTaskLoader.getInstance().loadTasks(mContext, sInstanceLoadPlan, launchOpts); + } + + /** + * Caches the header thumbnail used for a window animation asynchronously into + * {@link #mThumbnailTransitionBitmapCache}. + */ + void preCacheThumbnailTransitionBitmapAsync(ActivityManager.RunningTaskInfo topTask, + TaskStack stack, TaskStackView stackView, boolean isTopTaskHome) { + preloadIcon(topTask); + + // Update the destination rect + mDummyStackView.updateMinMaxScrollForStack(stack, mTriggeredFromAltTab, isTopTaskHome); + final Task toTask = new Task(); + final TaskViewTransform toTransform = getThumbnailTransitionTransform(stack, stackView, + topTask.id, toTask); + new AsyncTask<Void, Void, Bitmap>() { + @Override + protected Bitmap doInBackground(Void... params) { + return drawThumbnailTransitionBitmap(toTask, toTransform); + } + + @Override + protected void onPostExecute(Bitmap bitmap) { + mThumbnailTransitionBitmapCache = bitmap; + mThumbnailTransitionBitmapCacheKey = toTask; + } + }.execute(); + } + + /** + * Draws the header of a task used for the window animation into a bitmap. + */ + Bitmap drawThumbnailTransitionBitmap(Task toTask, TaskViewTransform toTransform) { + if (toTransform != null && toTask.key != null) { + Bitmap thumbnail; + synchronized (mHeaderBarLock) { + int toHeaderWidth = (int) (mHeaderBar.getMeasuredWidth() * toTransform.scale); + int toHeaderHeight = (int) (mHeaderBar.getMeasuredHeight() * toTransform.scale); + thumbnail = Bitmap.createBitmap(toHeaderWidth, toHeaderHeight, + Bitmap.Config.ARGB_8888); + if (Constants.DebugFlags.App.EnableTransitionThumbnailDebugMode) { + thumbnail.eraseColor(0xFFff0000); + } else { + Canvas c = new Canvas(thumbnail); + c.scale(toTransform.scale, toTransform.scale); + mHeaderBar.rebindToTask(toTask); + mHeaderBar.draw(c); + c.setBitmap(null); + } + } + return thumbnail.createAshmemBitmap(); + } + return null; + } + /** Returns the transition rect for the given task id. */ TaskViewTransform getThumbnailTransitionTransform(TaskStack stack, TaskStackView stackView, int runningTaskId, Task runningTaskOut) { @@ -694,7 +768,9 @@ public class Recents extends SystemUI return; } - loader.preloadTasks(sInstanceLoadPlan, isTopTaskHome); + if (!sInstanceLoadPlan.hasTasks()) { + loader.preloadTasks(sInstanceLoadPlan, isTopTaskHome); + } ArrayList<TaskStack> stacks = sInstanceLoadPlan.getAllTaskStacks(); TaskStack stack = stacks.get(0); @@ -706,12 +782,6 @@ public class Recents extends SystemUI boolean useThumbnailTransition = (topTask != null) && !isTopTaskHome && hasRecentTasks; if (useThumbnailTransition) { - // Ensure that we load the running task's icon - RecentsTaskLoadPlan.Options launchOpts = new RecentsTaskLoadPlan.Options(); - launchOpts.runningTaskId = topTask.id; - launchOpts.loadThumbnails = false; - launchOpts.onlyLoadForCache = true; - loader.loadTasks(mContext, sInstanceLoadPlan, launchOpts); // Try starting with a thumbnail transition ActivityOptions opts = getThumbnailTransitionActivityOptions(topTask, stack, diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java index ad97f91..3885799 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java +++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java @@ -81,6 +81,9 @@ public class RecentsActivity extends Activity implements RecentsView.RecentsView // Runnables to finish the Recents activity FinishRecentsRunnable mFinishLaunchHomeRunnable; + // Runnable to be executed after we paused ourselves + Runnable mAfterPauseRunnable; + /** * A common Runnable to finish Recents either by calling finish() (with a custom animation) or * launching Home with some ActivityOptions. Generally we always launch home when we exit @@ -441,6 +444,19 @@ public class RecentsActivity extends Activity implements RecentsView.RecentsView if (mConfig.launchedHasConfigurationChanged) { onEnterAnimationTriggered(); } + + if (!mConfig.launchedHasConfigurationChanged) { + mRecentsView.disableLayersForOneFrame(); + } + } + + @Override + protected void onPause() { + super.onPause(); + if (mAfterPauseRunnable != null) { + mRecentsView.post(mAfterPauseRunnable); + mAfterPauseRunnable = null; + } } @Override @@ -624,6 +640,11 @@ public class RecentsActivity extends Activity implements RecentsView.RecentsView Recents.startScreenPinning(this, ssp); } + @Override + public void runAfterPause(Runnable r) { + mAfterPauseRunnable = r; + } + /**** RecentsAppWidgetHost.RecentsAppWidgetHostCallbacks Implementation ****/ @Override diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/FixedSizeImageView.java b/packages/SystemUI/src/com/android/systemui/recents/views/FixedSizeImageView.java index 4b5c0bd..3f5d0a8 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/views/FixedSizeImageView.java +++ b/packages/SystemUI/src/com/android/systemui/recents/views/FixedSizeImageView.java @@ -73,4 +73,9 @@ public class FixedSizeImageView extends ImageView { mAllowRelayout = true; mAllowInvalidate = true; } + + @Override + public boolean hasOverlappingRendering() { + return false; + } } diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java index cec613c..fa97a86 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java +++ b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java @@ -24,14 +24,19 @@ import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Rect; import android.net.Uri; +import android.os.Bundle; +import android.os.IRemoteCallback; +import android.os.RemoteException; import android.os.UserHandle; import android.provider.Settings; import android.util.AttributeSet; +import android.util.Log; import android.view.LayoutInflater; import android.view.View; -import android.view.ViewStub; import android.view.WindowInsets; +import android.view.WindowManagerGlobal; import android.widget.FrameLayout; + import com.android.systemui.R; import com.android.systemui.recents.Constants; import com.android.systemui.recents.RecentsAppWidgetHostView; @@ -52,6 +57,8 @@ import java.util.List; public class RecentsView extends FrameLayout implements TaskStackView.TaskStackViewCallbacks, RecentsPackageMonitor.PackageCallbacks { + private static final String TAG = "RecentsView"; + /** The RecentsView callbacks */ public interface RecentsViewCallbacks { public void onTaskViewClicked(); @@ -59,8 +66,8 @@ public class RecentsView extends FrameLayout implements TaskStackView.TaskStackV public void onAllTaskViewsDismissed(); public void onExitToHomeAnimationTriggered(); public void onScreenPinningRequest(); - public void onTaskResize(Task t); + public void runAfterPause(Runnable r); } RecentsConfiguration mConfig; @@ -431,11 +438,75 @@ public class RecentsView extends FrameLayout implements TaskStackView.TaskStackV return false; } + public void disableLayersForOneFrame() { + List<TaskStackView> stackViews = getTaskStackViews(); + for (int i = 0; i < stackViews.size(); i++) { + stackViews.get(i).disableLayersForOneFrame(); + } + } + + private void postDrawHeaderThumbnailTransitionRunnable(final TaskView tv, final int offsetX, + final int offsetY, final TaskViewTransform transform, + final ActivityOptions.OnAnimationStartedListener animStartedListener) { + Runnable r = new Runnable() { + @Override + public void run() { + // Disable any focused state before we draw the header + if (tv.isFocusedTask()) { + tv.unsetFocusedTask(); + } + + float scale = tv.getScaleX(); + int fromHeaderWidth = (int) (tv.mHeaderView.getMeasuredWidth() * scale); + int fromHeaderHeight = (int) (tv.mHeaderView.getMeasuredHeight() * scale); + + Bitmap b = Bitmap.createBitmap(fromHeaderWidth, fromHeaderHeight, + Bitmap.Config.ARGB_8888); + if (Constants.DebugFlags.App.EnableTransitionThumbnailDebugMode) { + b.eraseColor(0xFFff0000); + } else { + Canvas c = new Canvas(b); + c.scale(tv.getScaleX(), tv.getScaleY()); + tv.mHeaderView.draw(c); + c.setBitmap(null); + } + b = b.createAshmemBitmap(); + int[] pts = new int[2]; + tv.getLocationOnScreen(pts); + try { + WindowManagerGlobal.getWindowManagerService() + .overridePendingAppTransitionAspectScaledThumb(b, + pts[0] + offsetX, + pts[1] + offsetY, + transform.rect.width(), + transform.rect.height(), + new IRemoteCallback.Stub() { + @Override + public void sendResult(Bundle data) + throws RemoteException { + post(new Runnable() { + @Override + public void run() { + if (animStartedListener != null) { + animStartedListener.onAnimationStarted(); + } + } + }); + } + }, true); + } catch (RemoteException e) { + Log.w(TAG, "Error overriding app transition", e); + } + } + }; + mCb.runAfterPause(r); + } /**** TaskStackView.TaskStackCallbacks Implementation ****/ @Override public void onTaskViewClicked(final TaskStackView stackView, final TaskView tv, final TaskStack stack, final Task task, final boolean lockToTask) { + // Notify any callbacks of the launching of a new task if (mCb != null) { mCb.onTaskViewClicked(); @@ -466,31 +537,6 @@ public class RecentsView extends FrameLayout implements TaskStackView.TaskStackV ActivityOptions opts = null; if (task.thumbnail != null && task.thumbnail.getWidth() > 0 && task.thumbnail.getHeight() > 0) { - Bitmap b; - if (tv != null) { - // Disable any focused state before we draw the header - if (tv.isFocusedTask()) { - tv.unsetFocusedTask(); - } - - float scale = tv.getScaleX(); - int fromHeaderWidth = (int) (tv.mHeaderView.getMeasuredWidth() * scale); - int fromHeaderHeight = (int) (tv.mHeaderView.getMeasuredHeight() * scale); - b = Bitmap.createBitmap(fromHeaderWidth, fromHeaderHeight, - Bitmap.Config.ARGB_8888); - if (Constants.DebugFlags.App.EnableTransitionThumbnailDebugMode) { - b.eraseColor(0xFFff0000); - } else { - Canvas c = new Canvas(b); - c.scale(tv.getScaleX(), tv.getScaleY()); - tv.mHeaderView.draw(c); - c.setBitmap(null); - } - } else { - // Notify the system to skip the thumbnail layer by using an ALPHA_8 bitmap - b = Bitmap.createBitmap(1, 1, Bitmap.Config.ALPHA_8); - } - Bitmap bImmut = b.createAshmemBitmap(); ActivityOptions.OnAnimationStartedListener animStartedListener = null; if (lockToTask) { animStartedListener = new ActivityOptions.OnAnimationStartedListener() { @@ -509,6 +555,10 @@ public class RecentsView extends FrameLayout implements TaskStackView.TaskStackV } }; } + if (tv != null) { + postDrawHeaderThumbnailTransitionRunnable(tv, offsetX, offsetY, transform, + animStartedListener); + } if (mConfig.multiStackEnabled) { opts = ActivityOptions.makeCustomAnimation(sourceView.getContext(), R.anim.recents_from_unknown_enter, @@ -516,7 +566,8 @@ public class RecentsView extends FrameLayout implements TaskStackView.TaskStackV sourceView.getHandler(), animStartedListener); } else { opts = ActivityOptions.makeThumbnailAspectScaleUpAnimation(sourceView, - bImmut, offsetX, offsetY, transform.rect.width(), transform.rect.height(), + Bitmap.createBitmap(1, 1, Bitmap.Config.ALPHA_8).createAshmemBitmap(), + offsetX, offsetY, transform.rect.width(), transform.rect.height(), sourceView.getHandler(), animStartedListener); } } diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java index 5f151e8..5711cd6 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java +++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java @@ -19,6 +19,7 @@ package com.android.systemui.recents.views; import android.animation.ValueAnimator; import android.content.ComponentName; import android.content.Context; +import android.graphics.Canvas; import android.graphics.Matrix; import android.graphics.Rect; import android.view.LayoutInflater; @@ -63,7 +64,6 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal public void onTaskResize(Task t); } - RecentsConfiguration mConfig; TaskStack mStack; @@ -81,7 +81,6 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal boolean mDismissAllButtonAnimating; int mFocusedTaskIndex = -1; int mPrevAccessibilityFocusedIndex = -1; - // Optimizations int mStackViewsAnimationDuration; boolean mStackViewsDirty = true; @@ -99,6 +98,7 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal ArrayList<TaskView> mTaskViews = new ArrayList<TaskView>(); List<TaskView> mImmutableTaskViews = new ArrayList<TaskView>(); LayoutInflater mInflater; + boolean mLayersDisabled; // A convenience update listener to request updating clipping of tasks ValueAnimator.AnimatorUpdateListener mRequestUpdateClippingListener = @@ -375,7 +375,9 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal if (tv == null) { tv = mViewPool.pickUpViewFromPool(task, task); - + if (mLayersDisabled) { + tv.disableLayersForOneFrame(); + } if (mStackViewsAnimationDuration > 0) { // For items in the list, put them in start animating them from the // approriate ends of the list where they are expected to appear @@ -1031,6 +1033,20 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal mUIDozeTrigger.poke(); } + @Override + protected void dispatchDraw(Canvas canvas) { + mLayersDisabled = false; + super.dispatchDraw(canvas); + } + + public void disableLayersForOneFrame() { + mLayersDisabled = true; + List<TaskView> taskViews = getTaskViews(); + for (int i = 0; i < taskViews.size(); i++) { + taskViews.get(i).disableLayersForOneFrame(); + } + } + /**** TaskStackCallbacks Implementation ****/ @Override diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java index 01ed08a..5906ef1 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java +++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java @@ -22,6 +22,7 @@ import android.animation.ValueAnimator; import android.content.Context; import android.graphics.*; import android.util.AttributeSet; +import android.view.accessibility.AccessibilityManager; import android.view.View; import android.view.ViewOutlineProvider; import android.view.animation.AccelerateInterpolator; @@ -366,7 +367,6 @@ public class TaskView extends FrameLayout implements Task.TaskCallbacks, .setStartDelay(delay) .setDuration(duration) .setInterpolator(PhoneStatusBar.ALPHA_IN) - .withLayer() .start(); } @@ -415,7 +415,6 @@ public class TaskView extends FrameLayout implements Task.TaskCallbacks, .setStartDelay(0) .setDuration(mConfig.taskViewExitToAppDuration) .setInterpolator(mConfig.fastOutLinearInInterpolator) - .withLayer() .start(); } else { // Hide the dismiss button @@ -650,6 +649,10 @@ public class TaskView extends FrameLayout implements Task.TaskCallbacks, } } + public void disableLayersForOneFrame() { + mHeaderView.disableLayersForOneFrame(); + } + /**** TaskCallbacks Implementation ****/ /** Binds this task view to the task */ @@ -672,7 +675,11 @@ public class TaskView extends FrameLayout implements Task.TaskCallbacks, mThumbnailView.rebindToTask(mTask); mHeaderView.rebindToTask(mTask); // Rebind any listeners - mHeaderView.mApplicationIcon.setOnClickListener(this); + AccessibilityManager am = (AccessibilityManager) getContext(). + getSystemService(Context.ACCESSIBILITY_SERVICE); + if (Constants.DebugFlags.App.EnableTaskFiltering || (am != null && am.isEnabled())) { + mHeaderView.mApplicationIcon.setOnClickListener(this); + } mHeaderView.mDismissButton.setOnClickListener(this); if (mConfig.multiStackEnabled) { mHeaderView.mMoveTaskButton.setOnClickListener(this); @@ -718,9 +725,19 @@ public class TaskView extends FrameLayout implements Task.TaskCallbacks, postDelayed(new Runnable() { @Override public void run() { - if (Constants.DebugFlags.App.EnableTaskFiltering && v == mHeaderView.mApplicationIcon) { - if (mCb != null) { - mCb.onTaskViewAppIconClicked(tv); + if (v == mHeaderView.mApplicationIcon) { + if (Constants.DebugFlags.App.EnableTaskFiltering) { + if (mCb != null) { + mCb.onTaskViewAppIconClicked(tv); + } + } else { + AccessibilityManager am = (AccessibilityManager) getContext(). + getSystemService(Context.ACCESSIBILITY_SERVICE); + if (am != null && am.isEnabled()) { + if (mCb != null) { + mCb.onTaskViewAppInfoClicked(tv); + } + } } } else if (v == mHeaderView.mDismissButton) { dismissTask(); diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java index f397bc3..062ded2 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java +++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java @@ -80,6 +80,8 @@ public class TaskViewHeader extends FrameLayout { Paint mDimLayerPaint = new Paint(); PorterDuffColorFilter mDimColorFilter = new PorterDuffColorFilter(0, PorterDuff.Mode.SRC_ATOP); + boolean mLayersDisabled; + public TaskViewHeader(Context context) { this(context, null); } @@ -172,7 +174,9 @@ public class TaskViewHeader extends FrameLayout { void setDimAlpha(int alpha) { mDimColorFilter.setColor(Color.argb(alpha, 0, 0, 0)); mDimLayerPaint.setColorFilter(mDimColorFilter); - setLayerType(LAYER_TYPE_HARDWARE, mDimLayerPaint); + if (!mLayersDisabled) { + setLayerType(LAYER_TYPE_HARDWARE, mDimLayerPaint); + } } /** Returns the secondary color for a primary color. */ @@ -190,7 +194,6 @@ public class TaskViewHeader extends FrameLayout { } else if (t.applicationIcon != null) { mApplicationIcon.setImageDrawable(t.applicationIcon); } - mApplicationIcon.setContentDescription(t.contentDescription); if (!mActivityDescription.getText().toString().equals(t.activityLabel)) { mActivityDescription.setText(t.activityLabel); } @@ -263,7 +266,6 @@ public class TaskViewHeader extends FrameLayout { .setStartDelay(0) .setInterpolator(mConfig.fastOutSlowInInterpolator) .setDuration(mConfig.taskViewExitToAppDuration) - .withLayer() .start(); } } @@ -278,7 +280,6 @@ public class TaskViewHeader extends FrameLayout { .setStartDelay(0) .setInterpolator(mConfig.fastOutLinearInInterpolator) .setDuration(mConfig.taskViewEnterFromAppDuration) - .withLayer() .start(); } } @@ -305,6 +306,28 @@ public class TaskViewHeader extends FrameLayout { return new int[] {}; } + @Override + protected void dispatchDraw(Canvas canvas) { + super.dispatchDraw(canvas); + if (mLayersDisabled) { + mLayersDisabled = false; + postOnAnimation(new Runnable() { + @Override + public void run() { + mLayersDisabled = false; + setLayerType(LAYER_TYPE_HARDWARE, mDimLayerPaint); + } + }); + } + } + + public void disableLayersForOneFrame() { + mLayersDisabled = true; + + // Disable layer for a frame so we can draw our first frame faster. + setLayerType(LAYER_TYPE_NONE, null); + } + /** Notifies the associated TaskView has been focused. */ void onTaskViewFocusChanged(boolean focused, boolean animateFocusedState) { // If we are not animating the visible state, just return diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java index fa172a4..6fb4b48 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java @@ -1030,9 +1030,7 @@ public abstract class BaseStatusBar extends SystemUI implements @Override public void toggleRecentApps() { - int msg = MSG_TOGGLE_RECENTS_APPS; - mHandler.removeMessages(msg); - mHandler.sendEmptyMessage(msg); + toggleRecents(); } @Override @@ -1904,7 +1902,7 @@ public abstract class BaseStatusBar extends SystemUI implements logUpdate(entry, n); } boolean applyInPlace = shouldApplyInPlace(entry, n); - boolean shouldInterrupt = shouldInterrupt(notification); + boolean shouldInterrupt = shouldInterrupt(entry); boolean alertAgain = alertAgain(entry, n); entry.notification = notification; @@ -2075,7 +2073,8 @@ public abstract class BaseStatusBar extends SystemUI implements || (newNotification.flags & Notification.FLAG_ONLY_ALERT_ONCE) == 0; } - protected boolean shouldInterrupt(StatusBarNotification sbn) { + protected boolean shouldInterrupt(Entry entry) { + StatusBarNotification sbn = entry.notification; if (mNotificationData.shouldFilterOut(sbn)) { if (DEBUG) { Log.d(TAG, "Skipping HUN check for " + sbn.getKey() + " since it's filtered out."); @@ -2100,10 +2099,12 @@ public abstract class BaseStatusBar extends SystemUI implements Notification.HEADS_UP_ALLOWED) != Notification.HEADS_UP_NEVER; boolean accessibilityForcesLaunch = isFullscreen && mAccessibilityManager.isTouchExplorationEnabled(); + boolean justLaunchedFullScreenIntent = entry.hasJustLaunchedFullScreenIntent(); boolean interrupt = (isFullscreen || (isHighPriority && (isNoisy || hasTicker))) && isAllowed && !accessibilityForcesLaunch + && !justLaunchedFullScreenIntent && mPowerManager.isScreenOn() && (!mStatusBarKeyguardViewManager.isShowing() || mStatusBarKeyguardViewManager.isOccluded()) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java index 2a8b4ac..dbabe3f 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java @@ -17,6 +17,7 @@ package com.android.systemui.statusbar; import android.app.Notification; +import android.os.SystemClock; import android.service.notification.NotificationListenerService; import android.service.notification.NotificationListenerService.Ranking; import android.service.notification.NotificationListenerService.RankingMap; @@ -41,6 +42,8 @@ public class NotificationData { private HeadsUpManager mHeadsUpManager; public static final class Entry { + private static final long LAUNCH_COOLDOWN = 2000; + private static final long NOT_LAUNCHED_YET = -LAUNCH_COOLDOWN; public String key; public StatusBarNotification notification; public StatusBarIconView icon; @@ -49,6 +52,7 @@ public class NotificationData { public boolean autoRedacted; // whether the redacted notification was generated by us public boolean legacy; // whether the notification has a legacy, dark background public int targetSdk; + private long lastFullScreenIntentLaunchTime = NOT_LAUNCHED_YET; public Entry(StatusBarNotification n, StatusBarIconView ic) { this.key = n.getKey(); @@ -72,6 +76,7 @@ public class NotificationData { // We should fix this at some point. autoRedacted = false; legacy = false; + lastFullScreenIntentLaunchTime = NOT_LAUNCHED_YET; if (row != null) { row.reset(); } @@ -92,6 +97,14 @@ public class NotificationData { public View getPublicContentView() { return row.getPublicLayout().getContractedChild(); } + + public void notifyFullScreenIntentLaunched() { + lastFullScreenIntentLaunchTime = SystemClock.elapsedRealtime(); + } + + public boolean hasJustLaunchedFullScreenIntent() { + return SystemClock.elapsedRealtime() < lastFullScreenIntentLaunchTime + LAUNCH_COOLDOWN; + } } private final ArrayMap<String, Entry> mEntries = new ArrayMap<>(); 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 7c7bec9..984c201 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java @@ -1153,7 +1153,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, if (shadeEntry == null) { return; } - boolean isHeadsUped = mUseHeadsUp && shouldInterrupt(notification); + boolean isHeadsUped = mUseHeadsUp && shouldInterrupt(shadeEntry); if (isHeadsUped) { mHeadsUpManager.showNotification(shadeEntry); // Mark as seen immediately @@ -1171,6 +1171,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, EventLog.writeEvent(EventLogTags.SYSUI_FULLSCREEN_NOTIFICATION, notification.getKey()); notification.getNotification().fullScreenIntent.send(); + shadeEntry.notifyFullScreenIntentLaunched(); } catch (PendingIntent.CanceledException e) { } } @@ -2045,6 +2046,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, EventLog.writeEvent(EventLogTags.SYSUI_HEADS_UP_ESCALATION, sbn.getKey()); notification.fullScreenIntent.send(); + entry.entry.notifyFullScreenIntentLaunched(); } catch (PendingIntent.CanceledException e) { } } |