diff options
Diffstat (limited to 'packages/SystemUI')
21 files changed, 97 insertions, 3394 deletions
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml index b606a6f..035bb0e 100644 --- a/packages/SystemUI/AndroidManifest.xml +++ b/packages/SystemUI/AndroidManifest.xml @@ -173,18 +173,6 @@ android:excludeFromRecents="true"> </activity> - <activity android:name=".recent.RecentsActivity" - android:label="@string/accessibility_desc_recent_apps" - android:theme="@style/RecentsStyle" - android:excludeFromRecents="true" - android:launchMode="singleInstance" - android:resumeWhilePausing="true" - android:exported="true"> - <intent-filter> - <action android:name="com.android.systemui.TOGGLE_RECENTS" /> - </intent-filter> - </activity> - <receiver android:name=".recent.RecentsPreloadReceiver" android:exported="false"> diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java b/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java index b3f90d7..e302c98 100644 --- a/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java +++ b/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java @@ -41,7 +41,7 @@ public class SystemUIApplication extends Application { */ private final Class<?>[] SERVICES = new Class[] { com.android.systemui.keyguard.KeyguardViewMediator.class, - com.android.systemui.recent.Recents.class, + com.android.systemui.recents.Recents.class, com.android.systemui.volume.VolumeUI.class, com.android.systemui.statusbar.SystemBars.class, com.android.systemui.usb.StorageNotification.class, diff --git a/packages/SystemUI/src/com/android/systemui/recent/ColorDrawableWithDimensions.java b/packages/SystemUI/src/com/android/systemui/recent/ColorDrawableWithDimensions.java deleted file mode 100644 index b4d3edd..0000000 --- a/packages/SystemUI/src/com/android/systemui/recent/ColorDrawableWithDimensions.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (C) 2013 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. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.systemui.recent; - -import android.graphics.drawable.ColorDrawable; - -public class ColorDrawableWithDimensions extends ColorDrawable { - private int mWidth; - private int mHeight; - - public ColorDrawableWithDimensions(int color, int width, int height) { - super(color); - mWidth = width; - mHeight = height; - } - - @Override - public int getIntrinsicWidth() { - return mWidth; - } - - @Override - public int getIntrinsicHeight() { - return mHeight; - } -} diff --git a/packages/SystemUI/src/com/android/systemui/recent/Constants.java b/packages/SystemUI/src/com/android/systemui/recent/Constants.java deleted file mode 100644 index 8252a9f..0000000 --- a/packages/SystemUI/src/com/android/systemui/recent/Constants.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (C) 2011 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. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.systemui.recent; - -public class Constants { - static final int MAX_ESCAPE_ANIMATION_DURATION = 500; // in ms - static final int SNAP_BACK_DURATION = 250; // in ms - static final int ESCAPE_VELOCITY = 100; // speed of item required to "curate" it in dp/s - public static float ALPHA_FADE_START = 0.8f; // fraction of thumbnail width where fade starts - static final float ALPHA_FADE_END = 0.5f; // fraction of thumbnail width beyond which alpha->0 -} diff --git a/packages/SystemUI/src/com/android/systemui/recent/FadedEdgeDrawHelper.java b/packages/SystemUI/src/com/android/systemui/recent/FadedEdgeDrawHelper.java deleted file mode 100644 index 59f7a80..0000000 --- a/packages/SystemUI/src/com/android/systemui/recent/FadedEdgeDrawHelper.java +++ /dev/null @@ -1,193 +0,0 @@ -/* - * Copyright (C) 2011 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. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.systemui.recent; - -import android.content.Context; -import android.content.res.TypedArray; -import android.graphics.Canvas; -import android.graphics.LinearGradient; -import android.graphics.Matrix; -import android.graphics.Paint; -import android.graphics.Shader; -import android.util.AttributeSet; -import android.view.View; -import android.view.ViewConfiguration; -import android.widget.LinearLayout; - -import com.android.systemui.R; - -public class FadedEdgeDrawHelper { - public static final boolean OPTIMIZE_SW_RENDERED_RECENTS = true; - public static final boolean USE_DARK_FADE_IN_HW_ACCELERATED_MODE = true; - private View mScrollView; - - private int mFadingEdgeLength; - private boolean mIsVertical; - private boolean mSoftwareRendered = false; - private Paint mBlackPaint; - private Paint mFadePaint; - private Matrix mFadeMatrix; - private LinearGradient mFade; - - public static FadedEdgeDrawHelper create(Context context, - AttributeSet attrs, View scrollView, boolean isVertical) { - boolean isTablet = context.getResources(). - getBoolean(R.bool.config_recents_interface_for_tablets); - if (!isTablet && (OPTIMIZE_SW_RENDERED_RECENTS || USE_DARK_FADE_IN_HW_ACCELERATED_MODE)) { - return new FadedEdgeDrawHelper(context, attrs, scrollView, isVertical); - } else { - return null; - } - } - - public FadedEdgeDrawHelper(Context context, - AttributeSet attrs, View scrollView, boolean isVertical) { - mScrollView = scrollView; - TypedArray a = context.obtainStyledAttributes(attrs, com.android.internal.R.styleable.View); - mFadingEdgeLength = a.getDimensionPixelSize(android.R.styleable.View_fadingEdgeLength, - ViewConfiguration.get(context).getScaledFadingEdgeLength()); - mIsVertical = isVertical; - } - - public void onAttachedToWindowCallback( - LinearLayout layout, boolean hardwareAccelerated) { - mSoftwareRendered = !hardwareAccelerated; - if ((mSoftwareRendered && OPTIMIZE_SW_RENDERED_RECENTS) - || USE_DARK_FADE_IN_HW_ACCELERATED_MODE) { - mScrollView.setVerticalFadingEdgeEnabled(false); - mScrollView.setHorizontalFadingEdgeEnabled(false); - } - } - - public void addViewCallback(View newLinearLayoutChild) { - if (mSoftwareRendered && OPTIMIZE_SW_RENDERED_RECENTS) { - final RecentsPanelView.ViewHolder holder = - (RecentsPanelView.ViewHolder) newLinearLayoutChild.getTag(); - holder.labelView.setDrawingCacheEnabled(true); - holder.labelView.buildDrawingCache(); - } - } - - public void drawCallback(Canvas canvas, - int left, int right, int top, int bottom, int scrollX, int scrollY, - float topFadingEdgeStrength, float bottomFadingEdgeStrength, - float leftFadingEdgeStrength, float rightFadingEdgeStrength, int mPaddingTop) { - - if ((mSoftwareRendered && OPTIMIZE_SW_RENDERED_RECENTS) - || USE_DARK_FADE_IN_HW_ACCELERATED_MODE) { - if (mFadePaint == null) { - mFadePaint = new Paint(); - mFadeMatrix = new Matrix(); - // use use a height of 1, and then wack the matrix each time we - // actually use it. - mFade = new LinearGradient(0, 0, 0, 1, 0xCC000000, 0, Shader.TileMode.CLAMP); - // PULL OUT THIS CONSTANT - mFadePaint.setShader(mFade); - } - - // draw the fade effect - boolean drawTop = false; - boolean drawBottom = false; - boolean drawLeft = false; - boolean drawRight = false; - - float topFadeStrength = 0.0f; - float bottomFadeStrength = 0.0f; - float leftFadeStrength = 0.0f; - float rightFadeStrength = 0.0f; - - final float fadeHeight = mFadingEdgeLength; - int length = (int) fadeHeight; - - // clip the fade length if top and bottom fades overlap - // overlapping fades produce odd-looking artifacts - if (mIsVertical && (top + length > bottom - length)) { - length = (bottom - top) / 2; - } - - // also clip horizontal fades if necessary - if (!mIsVertical && (left + length > right - length)) { - length = (right - left) / 2; - } - - if (mIsVertical) { - topFadeStrength = Math.max(0.0f, Math.min(1.0f, topFadingEdgeStrength)); - drawTop = topFadeStrength * fadeHeight > 1.0f; - bottomFadeStrength = Math.max(0.0f, Math.min(1.0f, bottomFadingEdgeStrength)); - drawBottom = bottomFadeStrength * fadeHeight > 1.0f; - } - - if (!mIsVertical) { - leftFadeStrength = Math.max(0.0f, Math.min(1.0f, leftFadingEdgeStrength)); - drawLeft = leftFadeStrength * fadeHeight > 1.0f; - rightFadeStrength = Math.max(0.0f, Math.min(1.0f, rightFadingEdgeStrength)); - drawRight = rightFadeStrength * fadeHeight > 1.0f; - } - - if (drawTop) { - mFadeMatrix.setScale(1, fadeHeight * topFadeStrength); - mFadeMatrix.postTranslate(left, top); - mFade.setLocalMatrix(mFadeMatrix); - mFadePaint.setShader(mFade); - canvas.drawRect(left, top, right, top + length, mFadePaint); - - if (mBlackPaint == null) { - // Draw under the status bar at the top - mBlackPaint = new Paint(); - mBlackPaint.setColor(0xFF000000); - } - canvas.drawRect(left, top - mPaddingTop, right, top, mBlackPaint); - } - - if (drawBottom) { - mFadeMatrix.setScale(1, fadeHeight * bottomFadeStrength); - mFadeMatrix.postRotate(180); - mFadeMatrix.postTranslate(left, bottom); - mFade.setLocalMatrix(mFadeMatrix); - mFadePaint.setShader(mFade); - canvas.drawRect(left, bottom - length, right, bottom, mFadePaint); - } - - if (drawLeft) { - mFadeMatrix.setScale(1, fadeHeight * leftFadeStrength); - mFadeMatrix.postRotate(-90); - mFadeMatrix.postTranslate(left, top); - mFade.setLocalMatrix(mFadeMatrix); - mFadePaint.setShader(mFade); - canvas.drawRect(left, top, left + length, bottom, mFadePaint); - } - - if (drawRight) { - mFadeMatrix.setScale(1, fadeHeight * rightFadeStrength); - mFadeMatrix.postRotate(90); - mFadeMatrix.postTranslate(right, top); - mFade.setLocalMatrix(mFadeMatrix); - mFadePaint.setShader(mFade); - canvas.drawRect(right - length, top, right, bottom, mFadePaint); - } - } - } - - public int getVerticalFadingEdgeLength() { - return mFadingEdgeLength; - } - - public int getHorizontalFadingEdgeLength() { - return mFadingEdgeLength; - } - -} diff --git a/packages/SystemUI/src/com/android/systemui/recent/FirstFrameAnimatorHelper.java b/packages/SystemUI/src/com/android/systemui/recent/FirstFrameAnimatorHelper.java deleted file mode 100644 index 84d13cf..0000000 --- a/packages/SystemUI/src/com/android/systemui/recent/FirstFrameAnimatorHelper.java +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Copyright (C) 2013 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. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.systemui.recent; - -import android.animation.Animator; -import android.animation.AnimatorListenerAdapter; -import android.animation.ValueAnimator; -import android.util.Log; -import android.view.View; -import android.view.ViewPropertyAnimator; -import android.view.ViewTreeObserver; - -/* - * This is a helper class that listens to updates from the corresponding animation. - * For the first two frames, it adjusts the current play time of the animation to - * prevent jank at the beginning of the animation - */ -public class FirstFrameAnimatorHelper extends AnimatorListenerAdapter - implements ValueAnimator.AnimatorUpdateListener { - private static final boolean DEBUG = false; - private static final int MAX_DELAY = 1000; - private static final int IDEAL_FRAME_DURATION = 16; - private View mTarget; - private long mStartFrame; - private long mStartTime = -1; - private boolean mHandlingOnAnimationUpdate; - private boolean mAdjustedSecondFrameTime; - - private static ViewTreeObserver.OnDrawListener sGlobalDrawListener; - private static long sGlobalFrameCounter; - - public FirstFrameAnimatorHelper(ValueAnimator animator, View target) { - mTarget = target; - animator.addUpdateListener(this); - } - - public FirstFrameAnimatorHelper(ViewPropertyAnimator vpa, View target) { - mTarget = target; - vpa.setListener(this); - } - - // only used for ViewPropertyAnimators - public void onAnimationStart(Animator animation) { - final ValueAnimator va = (ValueAnimator) animation; - va.addUpdateListener(FirstFrameAnimatorHelper.this); - onAnimationUpdate(va); - } - - public static void initializeDrawListener(View view) { - if (sGlobalDrawListener != null) { - view.getViewTreeObserver().removeOnDrawListener(sGlobalDrawListener); - } - sGlobalDrawListener = new ViewTreeObserver.OnDrawListener() { - private long mTime = System.currentTimeMillis(); - public void onDraw() { - sGlobalFrameCounter++; - if (DEBUG) { - long newTime = System.currentTimeMillis(); - Log.d("FirstFrameAnimatorHelper", "TICK " + (newTime - mTime)); - mTime = newTime; - } - } - }; - view.getViewTreeObserver().addOnDrawListener(sGlobalDrawListener); - } - - public void onAnimationUpdate(final ValueAnimator animation) { - final long currentTime = System.currentTimeMillis(); - if (mStartTime == -1) { - mStartFrame = sGlobalFrameCounter; - mStartTime = currentTime; - } - - if (!mHandlingOnAnimationUpdate && - // If the current play time exceeds the duration, the animation - // will get finished, even if we call setCurrentPlayTime -- therefore - // don't adjust the animation in that case - animation.getCurrentPlayTime() < animation.getDuration()) { - mHandlingOnAnimationUpdate = true; - long frameNum = sGlobalFrameCounter - mStartFrame; - // If we haven't drawn our first frame, reset the time to t = 0 - // (give up after MAX_DELAY ms of waiting though - might happen, for example, if we - // are no longer in the foreground and no frames are being rendered ever) - if (frameNum == 0 && currentTime < mStartTime + MAX_DELAY) { - // The first frame on animations doesn't always trigger an invalidate... - // force an invalidate here to make sure the animation continues to advance - mTarget.getRootView().invalidate(); - animation.setCurrentPlayTime(0); - - // For the second frame, if the first frame took more than 16ms, - // adjust the start time and pretend it took only 16ms anyway. This - // prevents a large jump in the animation due to an expensive first frame - } else if (frameNum == 1 && currentTime < mStartTime + MAX_DELAY && - !mAdjustedSecondFrameTime && - currentTime > mStartTime + IDEAL_FRAME_DURATION) { - animation.setCurrentPlayTime(IDEAL_FRAME_DURATION); - mAdjustedSecondFrameTime = true; - } else { - if (frameNum > 1) { - mTarget.post(new Runnable() { - public void run() { - animation.removeUpdateListener(FirstFrameAnimatorHelper.this); - } - }); - } - if (DEBUG) print(animation); - } - mHandlingOnAnimationUpdate = false; - } else { - if (DEBUG) print(animation); - } - } - - public void print(ValueAnimator animation) { - float flatFraction = animation.getCurrentPlayTime() / (float) animation.getDuration(); - Log.d("FirstFrameAnimatorHelper", sGlobalFrameCounter + - "(" + (sGlobalFrameCounter - mStartFrame) + ") " + mTarget + " dirty? " + - mTarget.isDirty() + " " + flatFraction + " " + this + " " + animation); - } -} diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentTasksLoader.java b/packages/SystemUI/src/com/android/systemui/recent/RecentTasksLoader.java deleted file mode 100644 index 34430d9..0000000 --- a/packages/SystemUI/src/com/android/systemui/recent/RecentTasksLoader.java +++ /dev/null @@ -1,586 +0,0 @@ -/* - * Copyright (C) 2011 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. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.systemui.recent; - -import android.app.ActivityManager; -import android.app.AppGlobals; -import android.content.ComponentName; -import android.content.Context; -import android.content.Intent; -import android.content.pm.ActivityInfo; -import android.content.pm.IPackageManager; -import android.content.pm.PackageManager; -import android.content.pm.ResolveInfo; -import android.content.res.Resources; -import android.graphics.Bitmap; -import android.graphics.drawable.BitmapDrawable; -import android.graphics.drawable.Drawable; -import android.os.AsyncTask; -import android.os.Handler; -import android.os.Process; -import android.os.RemoteException; -import android.os.UserHandle; -import android.util.Log; -import android.view.MotionEvent; -import android.view.View; - -import com.android.systemui.R; -import com.android.systemui.recents.misc.SystemServicesProxy; -import com.android.systemui.statusbar.phone.PhoneStatusBar; - -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.BlockingQueue; -import java.util.concurrent.LinkedBlockingQueue; - -public class RecentTasksLoader implements View.OnTouchListener { - static final String TAG = "RecentTasksLoader"; - static final boolean 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 Context mContext; - private RecentsPanelView mRecentsPanel; - - private Object mFirstTaskLock = new Object(); - private TaskDescription mFirstTask; - private boolean mFirstTaskLoaded; - - private AsyncTask<Void, ArrayList<TaskDescription>, Void> mTaskLoader; - private AsyncTask<Void, TaskDescription, Void> mThumbnailLoader; - private Handler mHandler; - - private int mIconDpi; - private ColorDrawableWithDimensions mDefaultThumbnailBackground; - private ColorDrawableWithDimensions mDefaultIconBackground; - private int mNumTasksInFirstScreenful = Integer.MAX_VALUE; - - private boolean mFirstScreenful; - private ArrayList<TaskDescription> mLoadedTasks; - - private enum State { LOADING, LOADED, CANCELLED }; - private State mState = State.CANCELLED; - - - private static RecentTasksLoader sInstance; - public static RecentTasksLoader getInstance(Context context) { - if (sInstance == null) { - sInstance = new RecentTasksLoader(context); - } - return sInstance; - } - - private RecentTasksLoader(Context context) { - mContext = context; - mHandler = new Handler(); - - final Resources res = context.getResources(); - - // get the icon size we want -- on tablets, we use bigger icons - boolean isTablet = res.getBoolean(R.bool.config_recents_interface_for_tablets); - if (isTablet) { - ActivityManager activityManager = - (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); - mIconDpi = activityManager.getLauncherLargeIconDensity(); - } else { - mIconDpi = res.getDisplayMetrics().densityDpi; - } - - // Render default icon (just a blank image) - int defaultIconSize = res.getDimensionPixelSize(com.android.internal.R.dimen.app_icon_size); - int iconSize = (int) (defaultIconSize * mIconDpi / res.getDisplayMetrics().densityDpi); - mDefaultIconBackground = new ColorDrawableWithDimensions(0x00000000, iconSize, iconSize); - - // Render the default thumbnail background - int thumbnailWidth = - (int) res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width); - int thumbnailHeight = - (int) res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height); - int color = res.getColor(R.drawable.status_bar_recents_app_thumbnail_background); - - mDefaultThumbnailBackground = - new ColorDrawableWithDimensions(color, thumbnailWidth, thumbnailHeight); - } - - public void setRecentsPanel(RecentsPanelView newRecentsPanel, RecentsPanelView caller) { - // Only allow clearing mRecentsPanel if the caller is the current recentsPanel - if (newRecentsPanel != null || mRecentsPanel == caller) { - mRecentsPanel = newRecentsPanel; - if (mRecentsPanel != null) { - mNumTasksInFirstScreenful = mRecentsPanel.numItemsInOneScreenful(); - } - } - } - - public Drawable getDefaultThumbnail() { - return mDefaultThumbnailBackground; - } - - public Drawable getDefaultIcon() { - return mDefaultIconBackground; - } - - public ArrayList<TaskDescription> getLoadedTasks() { - return mLoadedTasks; - } - - public void remove(TaskDescription td) { - mLoadedTasks.remove(td); - } - - public boolean isFirstScreenful() { - return mFirstScreenful; - } - - private boolean isCurrentHomeActivity(ComponentName component, ActivityInfo homeInfo) { - if (homeInfo == null) { - final PackageManager pm = mContext.getPackageManager(); - homeInfo = new Intent(Intent.ACTION_MAIN).addCategory(Intent.CATEGORY_HOME) - .resolveActivityInfo(pm, 0); - } - return homeInfo != null - && homeInfo.packageName.equals(component.getPackageName()) - && homeInfo.name.equals(component.getClassName()); - } - - // Create an TaskDescription, returning null if the title or icon is null - TaskDescription createTaskDescription(int taskId, int persistentTaskId, Intent baseIntent, - ComponentName origActivity, CharSequence description, int userId) { - Intent intent = new Intent(baseIntent); - if (origActivity != null) { - intent.setComponent(origActivity); - } - final PackageManager pm = mContext.getPackageManager(); - final IPackageManager ipm = AppGlobals.getPackageManager(); - intent.setFlags((intent.getFlags()&~Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) - | Intent.FLAG_ACTIVITY_NEW_TASK); - ResolveInfo resolveInfo = null; - try { - resolveInfo = ipm.resolveIntent(intent, null, 0, userId); - } catch (RemoteException re) { - } - if (resolveInfo != null) { - final ActivityInfo info = resolveInfo.activityInfo; - final String title = info.loadLabel(pm).toString(); - - if (title != null && title.length() > 0) { - if (DEBUG) Log.v(TAG, "creating activity desc for id=" - + persistentTaskId + ", label=" + title); - - TaskDescription item = new TaskDescription(taskId, - persistentTaskId, resolveInfo, baseIntent, info.packageName, - description, userId); - item.setLabel(title); - - return item; - } else { - if (DEBUG) Log.v(TAG, "SKIPPING item " + persistentTaskId); - } - } - return null; - } - - void loadThumbnailAndIcon(TaskDescription td) { - final ActivityManager am = (ActivityManager) - mContext.getSystemService(Context.ACTIVITY_SERVICE); - final PackageManager pm = mContext.getPackageManager(); - final Bitmap thumbnail = SystemServicesProxy.getThumbnail(am, td.persistentTaskId); - Drawable icon = getFullResIcon(td.resolveInfo, pm); - if (td.userId != UserHandle.myUserId()) { - // Need to badge the icon - icon = mContext.getPackageManager().getUserBadgedIcon(icon, new UserHandle(td.userId)); - } - if (DEBUG) Log.v(TAG, "Loaded bitmap for task " - + td + ": " + thumbnail); - synchronized (td) { - if (thumbnail != null) { - td.setThumbnail(new BitmapDrawable(mContext.getResources(), thumbnail)); - } else { - td.setThumbnail(mDefaultThumbnailBackground); - } - if (icon != null) { - td.setIcon(icon); - } - td.setLoaded(true); - } - } - - Drawable getFullResDefaultActivityIcon() { - return getFullResIcon(Resources.getSystem(), - com.android.internal.R.mipmap.sym_def_app_icon); - } - - Drawable getFullResIcon(Resources resources, int iconId) { - try { - return resources.getDrawableForDensity(iconId, mIconDpi); - } catch (Resources.NotFoundException e) { - return getFullResDefaultActivityIcon(); - } - } - - private Drawable getFullResIcon(ResolveInfo info, PackageManager packageManager) { - Resources resources; - try { - resources = packageManager.getResourcesForApplication( - info.activityInfo.applicationInfo); - } catch (PackageManager.NameNotFoundException e) { - resources = null; - } - if (resources != null) { - int iconId = info.activityInfo.getIconResource(); - if (iconId != 0) { - return getFullResIcon(resources, iconId); - } - } - return getFullResDefaultActivityIcon(); - } - - Runnable mPreloadTasksRunnable = new Runnable() { - public void run() { - loadTasksInBackground(); - } - }; - - // additional optimization when we have software system buttons - start loading the recent - // tasks on touch down - @Override - public boolean onTouch(View v, MotionEvent ev) { - int action = ev.getAction() & MotionEvent.ACTION_MASK; - if (action == MotionEvent.ACTION_DOWN) { - preloadRecentTasksList(); - } else if (action == MotionEvent.ACTION_CANCEL) { - cancelPreloadingRecentTasksList(); - } else if (action == MotionEvent.ACTION_UP) { - // Remove the preloader if we haven't called it yet - mHandler.removeCallbacks(mPreloadTasksRunnable); - if (!v.isPressed()) { - cancelLoadingThumbnailsAndIcons(); - } - - } - return false; - } - - public void preloadRecentTasksList() { - mHandler.post(mPreloadTasksRunnable); - } - - public void cancelPreloadingRecentTasksList() { - cancelLoadingThumbnailsAndIcons(); - mHandler.removeCallbacks(mPreloadTasksRunnable); - } - - public void cancelLoadingThumbnailsAndIcons(RecentsPanelView caller) { - // Only oblige this request if it comes from the current RecentsPanel - // (eg when you rotate, the old RecentsPanel request should be ignored) - if (mRecentsPanel == caller) { - cancelLoadingThumbnailsAndIcons(); - } - } - - - private void cancelLoadingThumbnailsAndIcons() { - if (mRecentsPanel != null && mRecentsPanel.isShowing()) { - return; - } - - if (mTaskLoader != null) { - mTaskLoader.cancel(false); - mTaskLoader = null; - } - if (mThumbnailLoader != null) { - mThumbnailLoader.cancel(false); - mThumbnailLoader = null; - } - mLoadedTasks = null; - if (mRecentsPanel != null) { - mRecentsPanel.onTaskLoadingCancelled(); - } - mFirstScreenful = false; - mState = State.CANCELLED; - } - - private void clearFirstTask() { - synchronized (mFirstTaskLock) { - mFirstTask = null; - mFirstTaskLoaded = false; - } - } - - public void preloadFirstTask() { - Thread bgLoad = new Thread() { - public void run() { - TaskDescription first = loadFirstTask(); - synchronized(mFirstTaskLock) { - if (mCancelPreloadingFirstTask) { - clearFirstTask(); - } else { - mFirstTask = first; - mFirstTaskLoaded = true; - } - mPreloadingFirstTask = false; - } - } - }; - synchronized(mFirstTaskLock) { - if (!mPreloadingFirstTask) { - clearFirstTask(); - mPreloadingFirstTask = true; - bgLoad.start(); - } - } - } - - public void cancelPreloadingFirstTask() { - synchronized(mFirstTaskLock) { - if (mPreloadingFirstTask) { - mCancelPreloadingFirstTask = true; - } else { - clearFirstTask(); - } - } - } - - boolean mPreloadingFirstTask; - boolean mCancelPreloadingFirstTask; - public TaskDescription getFirstTask() { - while(true) { - synchronized(mFirstTaskLock) { - if (mFirstTaskLoaded) { - return mFirstTask; - } else if (!mFirstTaskLoaded && !mPreloadingFirstTask) { - mFirstTask = loadFirstTask(); - mFirstTaskLoaded = true; - return mFirstTask; - } - } - try { - Thread.sleep(3); - } catch (InterruptedException e) { - } - } - } - - public TaskDescription loadFirstTask() { - final ActivityManager am = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE); - - final List<ActivityManager.RecentTaskInfo> recentTasks = am.getRecentTasksForUser(1, - ActivityManager.RECENT_IGNORE_UNAVAILABLE | ActivityManager.RECENT_INCLUDE_PROFILES, - UserHandle.CURRENT.getIdentifier()); - TaskDescription item = null; - if (recentTasks.size() > 0) { - ActivityManager.RecentTaskInfo recentInfo = recentTasks.get(0); - - Intent intent = new Intent(recentInfo.baseIntent); - if (recentInfo.origActivity != null) { - intent.setComponent(recentInfo.origActivity); - } - - // Don't load the current home activity. - if (isCurrentHomeActivity(intent.getComponent(), null)) { - return null; - } - - // Don't load ourselves - if (intent.getComponent().getPackageName().equals(mContext.getPackageName())) { - return null; - } - - item = createTaskDescription(recentInfo.id, - recentInfo.persistentId, recentInfo.baseIntent, - recentInfo.origActivity, recentInfo.description, - recentInfo.userId); - if (item != null) { - loadThumbnailAndIcon(item); - } - return item; - } - return null; - } - - public void loadTasksInBackground() { - loadTasksInBackground(false); - } - public void loadTasksInBackground(final boolean zeroeth) { - if (mState != State.CANCELLED) { - return; - } - mState = State.LOADING; - mFirstScreenful = true; - - final LinkedBlockingQueue<TaskDescription> tasksWaitingForThumbnails = - new LinkedBlockingQueue<TaskDescription>(); - mTaskLoader = new AsyncTask<Void, ArrayList<TaskDescription>, Void>() { - @Override - protected void onProgressUpdate(ArrayList<TaskDescription>... values) { - if (!isCancelled()) { - ArrayList<TaskDescription> newTasks = values[0]; - // do a callback to RecentsPanelView to let it know we have more values - // how do we let it know we're all done? just always call back twice - if (mRecentsPanel != null) { - mRecentsPanel.onTasksLoaded(newTasks, mFirstScreenful); - } - if (mLoadedTasks == null) { - mLoadedTasks = new ArrayList<TaskDescription>(); - } - mLoadedTasks.addAll(newTasks); - mFirstScreenful = false; - } - } - @Override - protected Void doInBackground(Void... params) { - // We load in two stages: first, we update progress with just the first screenful - // of items. Then, we update with the rest of the items - final int origPri = Process.getThreadPriority(Process.myTid()); - Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); - final PackageManager pm = mContext.getPackageManager(); - final ActivityManager am = (ActivityManager) - mContext.getSystemService(Context.ACTIVITY_SERVICE); - - final List<ActivityManager.RecentTaskInfo> recentTasks = - am.getRecentTasks(MAX_TASKS, ActivityManager.RECENT_IGNORE_UNAVAILABLE - | ActivityManager.RECENT_INCLUDE_PROFILES); - int numTasks = recentTasks.size(); - ActivityInfo homeInfo = new Intent(Intent.ACTION_MAIN) - .addCategory(Intent.CATEGORY_HOME).resolveActivityInfo(pm, 0); - - boolean firstScreenful = true; - ArrayList<TaskDescription> tasks = new ArrayList<TaskDescription>(); - - // skip the first task - assume it's either the home screen or the current activity. - final int first = 0; - for (int i = first, index = 0; i < numTasks && (index < MAX_TASKS); ++i) { - if (isCancelled()) { - break; - } - final ActivityManager.RecentTaskInfo recentInfo = recentTasks.get(i); - - Intent intent = new Intent(recentInfo.baseIntent); - if (recentInfo.origActivity != null) { - intent.setComponent(recentInfo.origActivity); - } - - // Don't load the current home activity. - if (isCurrentHomeActivity(intent.getComponent(), homeInfo)) { - continue; - } - - // Don't load ourselves - if (intent.getComponent().getPackageName().equals(mContext.getPackageName())) { - continue; - } - - TaskDescription item = createTaskDescription(recentInfo.id, - recentInfo.persistentId, recentInfo.baseIntent, - recentInfo.origActivity, recentInfo.description, - recentInfo.userId); - - if (item != null) { - while (true) { - try { - tasksWaitingForThumbnails.put(item); - break; - } catch (InterruptedException e) { - } - } - tasks.add(item); - if (firstScreenful && tasks.size() == mNumTasksInFirstScreenful) { - publishProgress(tasks); - tasks = new ArrayList<TaskDescription>(); - firstScreenful = false; - //break; - } - ++index; - } - } - - if (!isCancelled()) { - publishProgress(tasks); - if (firstScreenful) { - // always should publish two updates - publishProgress(new ArrayList<TaskDescription>()); - } - } - - while (true) { - try { - tasksWaitingForThumbnails.put(new TaskDescription()); - break; - } catch (InterruptedException e) { - } - } - - Process.setThreadPriority(origPri); - return null; - } - }; - mTaskLoader.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); - loadThumbnailsAndIconsInBackground(tasksWaitingForThumbnails); - } - - private void loadThumbnailsAndIconsInBackground( - final BlockingQueue<TaskDescription> tasksWaitingForThumbnails) { - // continually read items from tasksWaitingForThumbnails and load - // thumbnails and icons for them. finish thread when cancelled or there - // is a null item in tasksWaitingForThumbnails - mThumbnailLoader = new AsyncTask<Void, TaskDescription, Void>() { - @Override - protected void onProgressUpdate(TaskDescription... values) { - if (!isCancelled()) { - TaskDescription td = values[0]; - if (td.isNull()) { // end sentinel - mState = State.LOADED; - } else { - if (mRecentsPanel != null) { - mRecentsPanel.onTaskThumbnailLoaded(td); - } - } - } - } - @Override - protected Void doInBackground(Void... params) { - final int origPri = Process.getThreadPriority(Process.myTid()); - Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); - - while (true) { - if (isCancelled()) { - break; - } - TaskDescription td = null; - while (td == null) { - try { - td = tasksWaitingForThumbnails.take(); - } catch (InterruptedException e) { - } - } - if (td.isNull()) { // end sentinel - publishProgress(td); - break; - } - loadThumbnailAndIcon(td); - - publishProgress(td); - } - - Process.setThreadPriority(origPri); - return null; - } - }; - mThumbnailLoader.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); - } -} diff --git a/packages/SystemUI/src/com/android/systemui/recent/Recents.java b/packages/SystemUI/src/com/android/systemui/recent/Recents.java deleted file mode 100644 index e9f3cf9..0000000 --- a/packages/SystemUI/src/com/android/systemui/recent/Recents.java +++ /dev/null @@ -1,326 +0,0 @@ -/* - * Copyright (C) 2013 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. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.systemui.recent; - -import android.app.ActivityOptions; -import android.content.ActivityNotFoundException; -import android.content.Context; -import android.content.Intent; -import android.content.res.Configuration; -import android.content.res.Resources; -import android.graphics.Bitmap; -import android.graphics.Canvas; -import android.graphics.Paint; -import android.graphics.drawable.BitmapDrawable; -import android.graphics.drawable.Drawable; -import android.os.Bundle; -import android.os.UserHandle; -import android.util.DisplayMetrics; -import android.util.Log; -import android.view.Display; -import android.view.View; -import com.android.systemui.R; -import com.android.systemui.RecentsComponent; -import com.android.systemui.SystemUI; -import com.android.systemui.recents.AlternateRecentsComponent; - - -public class Recents extends SystemUI implements RecentsComponent { - private static final String TAG = "Recents"; - private static final boolean DEBUG = true; - - // Which recents to use - boolean mUseAlternateRecents = true; - boolean mBootCompleted = false; - static AlternateRecentsComponent sAlternateRecents; - - /** Returns the Recents component, creating a new one in-process if necessary. */ - public static AlternateRecentsComponent getRecentsComponent(Context context, - boolean forceInitialize) { - if (sAlternateRecents == null) { - sAlternateRecents = new AlternateRecentsComponent(context); - if (forceInitialize) { - sAlternateRecents.onStart(); - sAlternateRecents.onBootCompleted(); - } - } - return sAlternateRecents; - } - - @Override - public void start() { - if (mUseAlternateRecents) { - if (sAlternateRecents == null) { - sAlternateRecents = getRecentsComponent(mContext, false); - } - sAlternateRecents.onStart(); - } - - putComponent(RecentsComponent.class, this); - } - - @Override - protected void onBootCompleted() { - if (mUseAlternateRecents) { - if (sAlternateRecents != null) { - sAlternateRecents.onBootCompleted(); - } - } - mBootCompleted = true; - } - - @Override - public void showRecents(boolean triggeredFromAltTab, View statusBarView) { - if (mUseAlternateRecents) { - sAlternateRecents.onShowRecents(triggeredFromAltTab); - } - } - - @Override - public void hideRecents(boolean triggeredFromAltTab, boolean triggeredFromHomeKey) { - if (mUseAlternateRecents) { - sAlternateRecents.onHideRecents(triggeredFromAltTab, triggeredFromHomeKey); - } else { - Intent intent = new Intent(RecentsActivity.CLOSE_RECENTS_INTENT); - intent.setPackage("com.android.systemui"); - sendBroadcastSafely(intent); - - RecentTasksLoader.getInstance(mContext).cancelPreloadingFirstTask(); - } - } - - @Override - public void toggleRecents(Display display, int layoutDirection, View statusBarView) { - if (mUseAlternateRecents) { - // Launch the alternate recents if required - sAlternateRecents.onToggleRecents(); - return; - } - - if (DEBUG) Log.d(TAG, "toggle recents panel"); - try { - TaskDescription firstTask = RecentTasksLoader.getInstance(mContext).getFirstTask(); - - Intent intent = new Intent(RecentsActivity.TOGGLE_RECENTS_INTENT); - intent.setClassName("com.android.systemui", - "com.android.systemui.recent.RecentsActivity"); - intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK - | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); - - if (firstTask == null) { - if (RecentsActivity.forceOpaqueBackground(mContext)) { - ActivityOptions opts = ActivityOptions.makeCustomAnimation(mContext, - R.anim.recents_launch_from_launcher_enter, - R.anim.recents_launch_from_launcher_exit); - mContext.startActivityAsUser(intent, opts.toBundle(), new UserHandle( - UserHandle.USER_CURRENT)); - } else { - // The correct window animation will be applied via the activity's style - mContext.startActivityAsUser(intent, new UserHandle( - UserHandle.USER_CURRENT)); - } - - } else { - Bitmap first = null; - if (firstTask.getThumbnail() instanceof BitmapDrawable) { - first = ((BitmapDrawable) firstTask.getThumbnail()).getBitmap(); - } else { - first = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888); - Drawable d = RecentTasksLoader.getInstance(mContext).getDefaultThumbnail(); - d.draw(new Canvas(first)); - } - final Resources res = mContext.getResources(); - - float thumbWidth = res - .getDimensionPixelSize(R.dimen.status_bar_recents_thumbnail_width); - float thumbHeight = res - .getDimensionPixelSize(R.dimen.status_bar_recents_thumbnail_height); - if (first == null) { - throw new RuntimeException("Recents thumbnail is null"); - } - if (first.getWidth() != thumbWidth || first.getHeight() != thumbHeight) { - first = Bitmap.createScaledBitmap(first, (int) thumbWidth, (int) thumbHeight, - true); - if (first == null) { - throw new RuntimeException("Recents thumbnail is null"); - } - } - - - DisplayMetrics dm = new DisplayMetrics(); - display.getMetrics(dm); - // calculate it here, but consider moving it elsewhere - // first, determine which orientation you're in. - final Configuration config = res.getConfiguration(); - int x, y; - - if (config.orientation == Configuration.ORIENTATION_PORTRAIT) { - float appLabelLeftMargin = res.getDimensionPixelSize( - R.dimen.status_bar_recents_app_label_left_margin); - float appLabelWidth = res.getDimensionPixelSize( - R.dimen.status_bar_recents_app_label_width); - float thumbLeftMargin = res.getDimensionPixelSize( - R.dimen.status_bar_recents_thumbnail_left_margin); - float thumbBgPadding = res.getDimensionPixelSize( - R.dimen.status_bar_recents_thumbnail_bg_padding); - - float width = appLabelLeftMargin + - +appLabelWidth - + thumbLeftMargin - + thumbWidth - + 2 * thumbBgPadding; - - x = (int) ((dm.widthPixels - width) / 2f + appLabelLeftMargin + appLabelWidth - + thumbBgPadding + thumbLeftMargin); - y = (int) (dm.heightPixels - - res.getDimensionPixelSize(R.dimen.status_bar_recents_thumbnail_height) - - thumbBgPadding); - if (layoutDirection == View.LAYOUT_DIRECTION_RTL) { - x = dm.widthPixels - x - res.getDimensionPixelSize( - R.dimen.status_bar_recents_thumbnail_width); - } - - } else { // if (config.orientation == Configuration.ORIENTATION_LANDSCAPE) { - float thumbTopMargin = res.getDimensionPixelSize( - R.dimen.status_bar_recents_thumbnail_top_margin); - float thumbBgPadding = res.getDimensionPixelSize( - R.dimen.status_bar_recents_thumbnail_bg_padding); - float textPadding = res.getDimensionPixelSize( - R.dimen.status_bar_recents_text_description_padding); - float labelTextSize = res.getDimensionPixelSize( - R.dimen.status_bar_recents_app_label_text_size); - Paint p = new Paint(); - p.setTextSize(labelTextSize); - float labelTextHeight = p.getFontMetricsInt().bottom - - p.getFontMetricsInt().top; - float descriptionTextSize = res.getDimensionPixelSize( - R.dimen.status_bar_recents_app_description_text_size); - p.setTextSize(descriptionTextSize); - float descriptionTextHeight = p.getFontMetricsInt().bottom - - p.getFontMetricsInt().top; - - float statusBarHeight = res.getDimensionPixelSize( - com.android.internal.R.dimen.status_bar_height); - float recentsItemTopPadding = statusBarHeight; - - float height = thumbTopMargin - + thumbHeight - + 2 * thumbBgPadding + textPadding + labelTextHeight - + recentsItemTopPadding + textPadding + descriptionTextHeight; - float recentsItemRightPadding = res - .getDimensionPixelSize(R.dimen.status_bar_recents_item_padding); - float recentsScrollViewRightPadding = res - .getDimensionPixelSize(R.dimen.status_bar_recents_right_glow_margin); - x = (int) (dm.widthPixels - res - .getDimensionPixelSize(R.dimen.status_bar_recents_thumbnail_width) - - thumbBgPadding - recentsItemRightPadding - - recentsScrollViewRightPadding); - y = (int) ((dm.heightPixels - statusBarHeight - height) / 2f + thumbTopMargin - + recentsItemTopPadding + thumbBgPadding + statusBarHeight); - } - - ActivityOptions opts = ActivityOptions.makeThumbnailScaleDownAnimation( - statusBarView, - first, x, y, - new ActivityOptions.OnAnimationStartedListener() { - public void onAnimationStarted() { - Intent intent = - new Intent(RecentsActivity.WINDOW_ANIMATION_START_INTENT); - intent.setPackage("com.android.systemui"); - sendBroadcastSafely(intent); - } - }); - intent.putExtra(RecentsActivity.WAITING_FOR_WINDOW_ANIMATION_PARAM, true); - startActivitySafely(intent, opts.toBundle()); - } - } catch (ActivityNotFoundException e) { - Log.e(TAG, "Failed to launch RecentAppsIntent", e); - } - } - - @Override - protected void onConfigurationChanged(Configuration newConfig) { - if (mUseAlternateRecents) { - sAlternateRecents.onConfigurationChanged(newConfig); - } - } - - @Override - public void preloadRecents() { - if (mUseAlternateRecents) { - sAlternateRecents.onPreloadRecents(); - } else { - Intent intent = new Intent(RecentsActivity.PRELOAD_INTENT); - intent.setClassName("com.android.systemui", - "com.android.systemui.recent.RecentsPreloadReceiver"); - sendBroadcastSafely(intent); - - RecentTasksLoader.getInstance(mContext).preloadFirstTask(); - } - } - - @Override - public void cancelPreloadingRecents() { - if (mUseAlternateRecents) { - sAlternateRecents.onCancelPreloadingRecents(); - } else { - Intent intent = new Intent(RecentsActivity.CANCEL_PRELOAD_INTENT); - intent.setClassName("com.android.systemui", - "com.android.systemui.recent.RecentsPreloadReceiver"); - sendBroadcastSafely(intent); - - RecentTasksLoader.getInstance(mContext).cancelPreloadingFirstTask(); - } - } - - @Override - public void showNextAffiliatedTask() { - if (mUseAlternateRecents) { - sAlternateRecents.onShowNextAffiliatedTask(); - } - } - - @Override - public void showPrevAffiliatedTask() { - if (mUseAlternateRecents) { - sAlternateRecents.onShowPrevAffiliatedTask(); - } - } - - @Override - public void setCallback(Callbacks cb) { - if (mUseAlternateRecents) { - sAlternateRecents.setRecentsComponentCallback(cb); - } - } - - /** - * Send broadcast only if BOOT_COMPLETED - */ - private void sendBroadcastSafely(Intent intent) { - if (!mBootCompleted) return; - mContext.sendBroadcastAsUser(intent, new UserHandle(UserHandle.USER_CURRENT)); - } - - /** - * Start activity only if BOOT_COMPLETED - */ - private void startActivitySafely(Intent intent, Bundle opts) { - if (!mBootCompleted) return; - mContext.startActivityAsUser(intent, opts, new UserHandle(UserHandle.USER_CURRENT)); - } -} diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentsActivity.java b/packages/SystemUI/src/com/android/systemui/recent/RecentsActivity.java deleted file mode 100644 index 7ab40b0..0000000 --- a/packages/SystemUI/src/com/android/systemui/recent/RecentsActivity.java +++ /dev/null @@ -1,248 +0,0 @@ -/* - * Copyright (C) 2012 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. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.systemui.recent; - -import android.app.Activity; -import android.app.ActivityManager; -import android.app.WallpaperManager; -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.os.Bundle; -import android.os.UserHandle; -import android.view.MotionEvent; -import android.view.View; -import android.view.WindowManager; - -import com.android.systemui.R; -import com.android.systemui.statusbar.StatusBarPanel; - -import java.util.List; - -public class RecentsActivity extends Activity { - public static final String TOGGLE_RECENTS_INTENT = "com.android.systemui.recent.action.TOGGLE_RECENTS"; - public static final String PRELOAD_INTENT = "com.android.systemui.recent.action.PRELOAD"; - public static final String CANCEL_PRELOAD_INTENT = "com.android.systemui.recent.CANCEL_PRELOAD"; - public static final String CLOSE_RECENTS_INTENT = "com.android.systemui.recent.action.CLOSE"; - public static final String WINDOW_ANIMATION_START_INTENT = "com.android.systemui.recent.action.WINDOW_ANIMATION_START"; - public static final String PRELOAD_PERMISSION = "com.android.systemui.recent.permission.PRELOAD"; - public static final String WAITING_FOR_WINDOW_ANIMATION_PARAM = "com.android.systemui.recent.WAITING_FOR_WINDOW_ANIMATION"; - private static final String WAS_SHOWING = "was_showing"; - - private RecentsPanelView mRecentsPanel; - private IntentFilter mIntentFilter; - private boolean mShowing; - private boolean mForeground; - - private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - if (CLOSE_RECENTS_INTENT.equals(intent.getAction())) { - if (mRecentsPanel != null && mRecentsPanel.isShowing()) { - if (mShowing && !mForeground) { - // Captures the case right before we transition to another activity - mRecentsPanel.show(false); - } - } - } else if (WINDOW_ANIMATION_START_INTENT.equals(intent.getAction())) { - if (mRecentsPanel != null) { - mRecentsPanel.onWindowAnimationStart(); - } - } - } - }; - - public class TouchOutsideListener implements View.OnTouchListener { - private StatusBarPanel mPanel; - - public TouchOutsideListener(StatusBarPanel panel) { - mPanel = panel; - } - - public boolean onTouch(View v, MotionEvent ev) { - final int action = ev.getAction(); - if (action == MotionEvent.ACTION_OUTSIDE - || (action == MotionEvent.ACTION_DOWN - && !mPanel.isInContentArea((int) ev.getX(), (int) ev.getY()))) { - dismissAndGoHome(); - return true; - } - return false; - } - } - - @Override - public void onPause() { - overridePendingTransition( - R.anim.recents_return_to_launcher_enter, - R.anim.recents_return_to_launcher_exit); - mForeground = false; - super.onPause(); - } - - @Override - public void onStop() { - mShowing = false; - if (mRecentsPanel != null) { - mRecentsPanel.onUiHidden(); - } - super.onStop(); - } - - private void updateWallpaperVisibility(boolean visible) { - int wpflags = visible ? WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER : 0; - int curflags = getWindow().getAttributes().flags - & WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER; - if (wpflags != curflags) { - getWindow().setFlags(wpflags, WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER); - } - } - - public static boolean forceOpaqueBackground(Context context) { - return WallpaperManager.getInstance(context).getWallpaperInfo() != null; - } - - @Override - public void onStart() { - // Hide wallpaper if it's not a static image - if (forceOpaqueBackground(this)) { - updateWallpaperVisibility(false); - } else { - updateWallpaperVisibility(true); - } - mShowing = true; - if (mRecentsPanel != null) { - // Call and refresh the recent tasks list in case we didn't preload tasks - // or in case we don't get an onNewIntent - mRecentsPanel.refreshRecentTasksList(); - mRecentsPanel.refreshViews(); - } - super.onStart(); - } - - @Override - public void onResume() { - mForeground = true; - super.onResume(); - } - - @Override - public void onBackPressed() { - dismissAndGoBack(); - } - - public void dismissAndGoHome() { - if (mRecentsPanel != null) { - Intent homeIntent = new Intent(Intent.ACTION_MAIN, null); - homeIntent.addCategory(Intent.CATEGORY_HOME); - homeIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK - | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED); - startActivityAsUser(homeIntent, new UserHandle(UserHandle.USER_CURRENT)); - mRecentsPanel.show(false); - } - } - - public void dismissAndGoBack() { - if (mRecentsPanel != null) { - final ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE); - - final List<ActivityManager.RecentTaskInfo> recentTasks = - am.getRecentTasks(2, - ActivityManager.RECENT_WITH_EXCLUDED | - ActivityManager.RECENT_IGNORE_UNAVAILABLE | - ActivityManager.RECENT_INCLUDE_PROFILES); - if (recentTasks.size() > 1 && - mRecentsPanel.simulateClick(recentTasks.get(1).persistentId)) { - // recents panel will take care of calling show(false) through simulateClick - return; - } - mRecentsPanel.show(false); - } - finish(); - } - - @Override - protected void onCreate(Bundle savedInstanceState) { - getWindow().addPrivateFlags( - WindowManager.LayoutParams.PRIVATE_FLAG_INHERIT_TRANSLUCENT_DECOR); - setContentView(R.layout.status_bar_recent_panel); - mRecentsPanel = (RecentsPanelView) findViewById(R.id.recents_root); - mRecentsPanel.setOnTouchListener(new TouchOutsideListener(mRecentsPanel)); - mRecentsPanel.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE - | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN - | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION); - - final RecentTasksLoader recentTasksLoader = RecentTasksLoader.getInstance(this); - recentTasksLoader.setRecentsPanel(mRecentsPanel, mRecentsPanel); - mRecentsPanel.setMinSwipeAlpha( - getResources().getInteger(R.integer.config_recent_item_min_alpha) / 100f); - - if (savedInstanceState == null || - savedInstanceState.getBoolean(WAS_SHOWING)) { - handleIntent(getIntent(), (savedInstanceState == null)); - } - mIntentFilter = new IntentFilter(); - mIntentFilter.addAction(CLOSE_RECENTS_INTENT); - mIntentFilter.addAction(WINDOW_ANIMATION_START_INTENT); - registerReceiver(mIntentReceiver, mIntentFilter); - super.onCreate(savedInstanceState); - } - - @Override - protected void onSaveInstanceState(Bundle outState) { - outState.putBoolean(WAS_SHOWING, mRecentsPanel.isShowing()); - } - - @Override - protected void onDestroy() { - RecentTasksLoader.getInstance(this).setRecentsPanel(null, mRecentsPanel); - unregisterReceiver(mIntentReceiver); - super.onDestroy(); - } - - @Override - protected void onNewIntent(Intent intent) { - handleIntent(intent, true); - } - - private void handleIntent(Intent intent, boolean checkWaitingForAnimationParam) { - super.onNewIntent(intent); - - if (TOGGLE_RECENTS_INTENT.equals(intent.getAction())) { - if (mRecentsPanel != null) { - if (mRecentsPanel.isShowing()) { - dismissAndGoBack(); - } else { - final RecentTasksLoader recentTasksLoader = RecentTasksLoader.getInstance(this); - boolean waitingForWindowAnimation = checkWaitingForAnimationParam && - intent.getBooleanExtra(WAITING_FOR_WINDOW_ANIMATION_PARAM, false); - mRecentsPanel.show(true, recentTasksLoader.getLoadedTasks(), - recentTasksLoader.isFirstScreenful(), waitingForWindowAnimation); - } - } - } - } - - boolean isForeground() { - return mForeground; - } - - boolean isActivityShowing() { - return mShowing; - } -} diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentsCallback.java b/packages/SystemUI/src/com/android/systemui/recent/RecentsCallback.java deleted file mode 100644 index deb5670..0000000 --- a/packages/SystemUI/src/com/android/systemui/recent/RecentsCallback.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (C) 2011 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. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.systemui.recent; - -import android.view.View; - -public interface RecentsCallback { - static final int SWIPE_LEFT = 0; - static final int SWIPE_RIGHT = 1; - static final int SWIPE_UP = 2; - static final int SWIPE_DOWN = 3; - - void handleOnClick(View selectedView); - void handleSwipe(View selectedView); - void handleLongPress(View selectedView, View anchorView, View thumbnailView); - void dismiss(); -} diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentsHorizontalScrollView.java b/packages/SystemUI/src/com/android/systemui/recent/RecentsHorizontalScrollView.java deleted file mode 100644 index cf5d3a6..0000000 --- a/packages/SystemUI/src/com/android/systemui/recent/RecentsHorizontalScrollView.java +++ /dev/null @@ -1,391 +0,0 @@ -/* - * Copyright (C) 2011 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. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.systemui.recent; - -import android.animation.LayoutTransition; -import android.content.Context; -import android.content.res.Configuration; -import android.database.DataSetObserver; -import android.graphics.Canvas; -import android.util.AttributeSet; -import android.util.DisplayMetrics; -import android.util.Log; -import android.view.MotionEvent; -import android.view.View; -import android.view.ViewConfiguration; -import android.view.ViewTreeObserver; -import android.view.ViewTreeObserver.OnGlobalLayoutListener; -import android.widget.HorizontalScrollView; -import android.widget.LinearLayout; - -import com.android.systemui.R; -import com.android.systemui.SwipeHelper; -import com.android.systemui.recent.RecentsPanelView.TaskDescriptionAdapter; - -import java.util.HashSet; -import java.util.Iterator; - -public class RecentsHorizontalScrollView extends HorizontalScrollView - implements SwipeHelper.Callback, RecentsPanelView.RecentsScrollView { - private static final String TAG = RecentsPanelView.TAG; - private static final boolean DEBUG = RecentsPanelView.DEBUG; - private LinearLayout mLinearLayout; - private TaskDescriptionAdapter mAdapter; - private RecentsCallback mCallback; - protected int mLastScrollPosition; - private SwipeHelper mSwipeHelper; - private FadedEdgeDrawHelper mFadedEdgeDrawHelper; - private HashSet<View> mRecycledViews; - private int mNumItemsInOneScreenful; - private Runnable mOnScrollListener; - - public RecentsHorizontalScrollView(Context context, AttributeSet attrs) { - super(context, attrs, 0); - mSwipeHelper = new SwipeHelper(SwipeHelper.Y, this, context); - mFadedEdgeDrawHelper = FadedEdgeDrawHelper.create(context, attrs, this, false); - mRecycledViews = new HashSet<View>(); - } - - public void setMinSwipeAlpha(float minAlpha) { - mSwipeHelper.setMinSwipeProgress(minAlpha); - } - - private int scrollPositionOfMostRecent() { - return mLinearLayout.getWidth() - getWidth(); - } - - private void addToRecycledViews(View v) { - if (mRecycledViews.size() < mNumItemsInOneScreenful) { - mRecycledViews.add(v); - } - } - - public View findViewForTask(int persistentTaskId) { - for (int i = 0; i < mLinearLayout.getChildCount(); i++) { - View v = mLinearLayout.getChildAt(i); - RecentsPanelView.ViewHolder holder = (RecentsPanelView.ViewHolder) v.getTag(); - if (holder.taskDescription.persistentTaskId == persistentTaskId) { - return v; - } - } - return null; - } - - private void update() { - for (int i = 0; i < mLinearLayout.getChildCount(); i++) { - View v = mLinearLayout.getChildAt(i); - addToRecycledViews(v); - mAdapter.recycleView(v); - } - LayoutTransition transitioner = getLayoutTransition(); - setLayoutTransition(null); - - mLinearLayout.removeAllViews(); - Iterator<View> recycledViews = mRecycledViews.iterator(); - for (int i = 0; i < mAdapter.getCount(); i++) { - View old = null; - if (recycledViews.hasNext()) { - old = recycledViews.next(); - recycledViews.remove(); - old.setVisibility(VISIBLE); - } - - final View view = mAdapter.getView(i, old, mLinearLayout); - - if (mFadedEdgeDrawHelper != null) { - mFadedEdgeDrawHelper.addViewCallback(view); - } - - OnTouchListener noOpListener = new OnTouchListener() { - @Override - public boolean onTouch(View v, MotionEvent event) { - return true; - } - }; - - view.setOnClickListener(new OnClickListener() { - public void onClick(View v) { - mCallback.dismiss(); - } - }); - // We don't want a click sound when we dimiss recents - view.setSoundEffectsEnabled(false); - - OnClickListener launchAppListener = new OnClickListener() { - public void onClick(View v) { - mCallback.handleOnClick(view); - } - }; - - RecentsPanelView.ViewHolder holder = (RecentsPanelView.ViewHolder) view.getTag(); - final View thumbnailView = holder.thumbnailView; - OnLongClickListener longClickListener = new OnLongClickListener() { - public boolean onLongClick(View v) { - final View anchorView = view.findViewById(R.id.app_description); - mCallback.handleLongPress(view, anchorView, thumbnailView); - return true; - } - }; - thumbnailView.setClickable(true); - thumbnailView.setOnClickListener(launchAppListener); - thumbnailView.setOnLongClickListener(longClickListener); - - // We don't want to dismiss recents if a user clicks on the app title - // (we also don't want to launch the app either, though, because the - // app title is a small target and doesn't have great click feedback) - final View appTitle = view.findViewById(R.id.app_label); - appTitle.setContentDescription(" "); - appTitle.setOnTouchListener(noOpListener); - mLinearLayout.addView(view); - } - setLayoutTransition(transitioner); - - // Scroll to end after initial layout. - - final OnGlobalLayoutListener updateScroll = new OnGlobalLayoutListener() { - public void onGlobalLayout() { - mLastScrollPosition = scrollPositionOfMostRecent(); - scrollTo(mLastScrollPosition, 0); - final ViewTreeObserver observer = getViewTreeObserver(); - if (observer.isAlive()) { - observer.removeOnGlobalLayoutListener(this); - } - } - }; - getViewTreeObserver().addOnGlobalLayoutListener(updateScroll); - } - - @Override - public void removeViewInLayout(final View view) { - dismissChild(view); - } - - public boolean onInterceptTouchEvent(MotionEvent ev) { - if (DEBUG) Log.v(TAG, "onInterceptTouchEvent()"); - return mSwipeHelper.onInterceptTouchEvent(ev) || - super.onInterceptTouchEvent(ev); - } - - @Override - public boolean onTouchEvent(MotionEvent ev) { - return mSwipeHelper.onTouchEvent(ev) || - super.onTouchEvent(ev); - } - - public boolean canChildBeDismissed(View v) { - return true; - } - - @Override - public boolean isAntiFalsingNeeded() { - return false; - } - - @Override - public float getFalsingThresholdFactor() { - return 1.0f; - } - - public void dismissChild(View v) { - mSwipeHelper.dismissChild(v, 0); - } - - public void onChildDismissed(View v) { - addToRecycledViews(v); - mLinearLayout.removeView(v); - mCallback.handleSwipe(v); - // Restore the alpha/translation parameters to what they were before swiping - // (for when these items are recycled) - View contentView = getChildContentView(v); - contentView.setAlpha(1f); - contentView.setTranslationY(0); - } - - public void onBeginDrag(View v) { - // We do this so the underlying ScrollView knows that it won't get - // the chance to intercept events anymore - requestDisallowInterceptTouchEvent(true); - } - - public void onDragCancelled(View v) { - } - - @Override - public void onChildSnappedBack(View animView) { - } - - @Override - public boolean updateSwipeProgress(View animView, boolean dismissable, float swipeProgress) { - return false; - } - - public View getChildAtPosition(MotionEvent ev) { - final float x = ev.getX() + getScrollX(); - 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()) { - return item; - } - } - return null; - } - - public View getChildContentView(View v) { - return v.findViewById(R.id.recent_item); - } - - @Override - public void drawFadedEdges(Canvas canvas, int left, int right, int top, int bottom) { - if (mFadedEdgeDrawHelper != null) { - - mFadedEdgeDrawHelper.drawCallback(canvas, - left, right, top, bottom, getScrollX(), getScrollY(), - 0, 0, - getLeftFadingEdgeStrength(), getRightFadingEdgeStrength(), getPaddingTop()); - } - } - - @Override - protected void onScrollChanged(int l, int t, int oldl, int oldt) { - super.onScrollChanged(l, t, oldl, oldt); - if (mOnScrollListener != null) { - mOnScrollListener.run(); - } - } - - public void setOnScrollListener(Runnable listener) { - mOnScrollListener = listener; - } - - @Override - public int getVerticalFadingEdgeLength() { - if (mFadedEdgeDrawHelper != null) { - return mFadedEdgeDrawHelper.getVerticalFadingEdgeLength(); - } else { - return super.getVerticalFadingEdgeLength(); - } - } - - @Override - public int getHorizontalFadingEdgeLength() { - if (mFadedEdgeDrawHelper != null) { - return mFadedEdgeDrawHelper.getHorizontalFadingEdgeLength(); - } else { - return super.getHorizontalFadingEdgeLength(); - } - } - - @Override - protected void onFinishInflate() { - super.onFinishInflate(); - setScrollbarFadingEnabled(true); - mLinearLayout = (LinearLayout) findViewById(R.id.recents_linear_layout); - final int leftPadding = getContext().getResources() - .getDimensionPixelOffset(R.dimen.status_bar_recents_thumbnail_left_margin); - setOverScrollEffectPadding(leftPadding, 0); - } - - @Override - public void onAttachedToWindow() { - if (mFadedEdgeDrawHelper != null) { - mFadedEdgeDrawHelper.onAttachedToWindowCallback(mLinearLayout, isHardwareAccelerated()); - } - } - - @Override - protected void onConfigurationChanged(Configuration newConfig) { - super.onConfigurationChanged(newConfig); - float densityScale = getResources().getDisplayMetrics().density; - mSwipeHelper.setDensityScale(densityScale); - float pagingTouchSlop = ViewConfiguration.get(getContext()).getScaledPagingTouchSlop(); - mSwipeHelper.setPagingTouchSlop(pagingTouchSlop); - } - - private void setOverScrollEffectPadding(int leftPadding, int i) { - // TODO Add to (Vertical)ScrollView - } - - @Override - protected void onSizeChanged(int w, int h, int oldw, int oldh) { - super.onSizeChanged(w, h, oldw, oldh); - - // Skip this work if a transition is running; it sets the scroll values independently - // and should not have those animated values clobbered by this logic - LayoutTransition transition = mLinearLayout.getLayoutTransition(); - if (transition != null && transition.isRunning()) { - return; - } - // Keep track of the last visible item in the list so we can restore it - // to the bottom when the orientation changes. - mLastScrollPosition = scrollPositionOfMostRecent(); - - // This has to happen post-layout, so run it "in the future" - post(new Runnable() { - public void run() { - // Make sure we're still not clobbering the transition-set values, since this - // runnable launches asynchronously - LayoutTransition transition = mLinearLayout.getLayoutTransition(); - if (transition == null || !transition.isRunning()) { - scrollTo(mLastScrollPosition, 0); - } - } - }); - } - - public void setAdapter(TaskDescriptionAdapter adapter) { - mAdapter = adapter; - mAdapter.registerDataSetObserver(new DataSetObserver() { - public void onChanged() { - update(); - } - - public void onInvalidated() { - update(); - } - }); - DisplayMetrics dm = getResources().getDisplayMetrics(); - int childWidthMeasureSpec = - MeasureSpec.makeMeasureSpec(dm.widthPixels, MeasureSpec.AT_MOST); - int childheightMeasureSpec = - MeasureSpec.makeMeasureSpec(dm.heightPixels, MeasureSpec.AT_MOST); - View child = mAdapter.createView(mLinearLayout); - child.measure(childWidthMeasureSpec, childheightMeasureSpec); - mNumItemsInOneScreenful = - (int) Math.ceil(dm.widthPixels / (double) child.getMeasuredWidth()); - addToRecycledViews(child); - - for (int i = 0; i < mNumItemsInOneScreenful - 1; i++) { - addToRecycledViews(mAdapter.createView(mLinearLayout)); - } - } - - public int numItemsInOneScreenful() { - return mNumItemsInOneScreenful; - } - - @Override - public void setLayoutTransition(LayoutTransition transition) { - // The layout transition applies to our embedded LinearLayout - mLinearLayout.setLayoutTransition(transition); - } - - public void setCallback(RecentsCallback callback) { - mCallback = callback; - } -} diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java b/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java deleted file mode 100644 index 4c3460e..0000000 --- a/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java +++ /dev/null @@ -1,813 +0,0 @@ -/* - * Copyright (C) 2011 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. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.systemui.recent; - -import android.animation.Animator; -import android.animation.LayoutTransition; -import android.animation.TimeInterpolator; -import android.app.ActivityManager; -import android.app.ActivityManagerNative; -import android.app.ActivityOptions; -import android.app.TaskStackBuilder; -import android.content.ActivityNotFoundException; -import android.content.Context; -import android.content.Intent; -import android.content.res.Configuration; -import android.content.res.Resources; -import android.content.res.TypedArray; -import android.graphics.Bitmap; -import android.graphics.Canvas; -import android.graphics.Matrix; -import android.graphics.Shader.TileMode; -import android.graphics.drawable.BitmapDrawable; -import android.graphics.drawable.Drawable; -import android.net.Uri; -import android.os.Bundle; -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.MenuItem; -import android.view.MotionEvent; -import android.view.View; -import android.view.ViewGroup; -import android.view.ViewPropertyAnimator; -import android.view.ViewRootImpl; -import android.view.accessibility.AccessibilityEvent; -import android.view.animation.AnimationUtils; -import android.view.animation.DecelerateInterpolator; -import android.widget.AdapterView; -import android.widget.AdapterView.OnItemClickListener; -import android.widget.BaseAdapter; -import android.widget.FrameLayout; -import android.widget.ImageView; -import android.widget.ImageView.ScaleType; -import android.widget.PopupMenu; -import android.widget.TextView; - -import com.android.systemui.R; -import com.android.systemui.statusbar.BaseStatusBar; -import com.android.systemui.statusbar.StatusBarPanel; -import com.android.systemui.statusbar.phone.PhoneStatusBar; - -import java.util.ArrayList; - -public class RecentsPanelView extends FrameLayout implements OnItemClickListener, RecentsCallback, - StatusBarPanel, Animator.AnimatorListener { - static final String TAG = "RecentsPanelView"; - static final boolean DEBUG = PhoneStatusBar.DEBUG || false; - private PopupMenu mPopup; - private View mRecentsScrim; - private View mRecentsNoApps; - private RecentsScrollView mRecentsContainer; - - private boolean mShowing; - private boolean mWaitingToShow; - private ViewHolder mItemToAnimateInWhenWindowAnimationIsFinished; - private boolean mAnimateIconOfFirstTask; - private boolean mWaitingForWindowAnimation; - private long mWindowAnimationStartTime; - private boolean mCallUiHiddenBeforeNextReload; - - private RecentTasksLoader mRecentTasksLoader; - private ArrayList<TaskDescription> mRecentTaskDescriptions; - private TaskDescriptionAdapter mListAdapter; - private int mThumbnailWidth; - private boolean mFitThumbnailToXY; - private int mRecentItemLayoutId; - private boolean mHighEndGfx; - - public static interface RecentsScrollView { - public int numItemsInOneScreenful(); - public void setAdapter(TaskDescriptionAdapter adapter); - public void setCallback(RecentsCallback callback); - public void setMinSwipeAlpha(float minAlpha); - public View findViewForTask(int persistentTaskId); - public void drawFadedEdges(Canvas c, int left, int right, int top, int bottom); - public void setOnScrollListener(Runnable listener); - } - - private final class OnLongClickDelegate implements View.OnLongClickListener { - View mOtherView; - OnLongClickDelegate(View other) { - mOtherView = other; - } - public boolean onLongClick(View v) { - return mOtherView.performLongClick(); - } - } - - /* package */ final static class ViewHolder { - View thumbnailView; - ImageView thumbnailViewImage; - Drawable thumbnailViewDrawable; - ImageView iconView; - TextView labelView; - TextView descriptionView; - View calloutLine; - TaskDescription taskDescription; - boolean loadedThumbnailAndIcon; - } - - /* package */ final class TaskDescriptionAdapter extends BaseAdapter { - private LayoutInflater mInflater; - - public TaskDescriptionAdapter(Context context) { - mInflater = LayoutInflater.from(context); - } - - public int getCount() { - return mRecentTaskDescriptions != null ? mRecentTaskDescriptions.size() : 0; - } - - public Object getItem(int position) { - return position; // we only need the index - } - - public long getItemId(int position) { - return position; // we just need something unique for this position - } - - public View createView(ViewGroup parent) { - View convertView = mInflater.inflate(mRecentItemLayoutId, parent, false); - ViewHolder holder = new ViewHolder(); - holder.thumbnailView = convertView.findViewById(R.id.app_thumbnail); - holder.thumbnailViewImage = - (ImageView) convertView.findViewById(R.id.app_thumbnail_image); - // If we set the default thumbnail now, we avoid an onLayout when we update - // the thumbnail later (if they both have the same dimensions) - updateThumbnail(holder, mRecentTasksLoader.getDefaultThumbnail(), false, false); - holder.iconView = (ImageView) convertView.findViewById(R.id.app_icon); - holder.iconView.setImageDrawable(mRecentTasksLoader.getDefaultIcon()); - holder.labelView = (TextView) convertView.findViewById(R.id.app_label); - holder.calloutLine = convertView.findViewById(R.id.recents_callout_line); - holder.descriptionView = (TextView) convertView.findViewById(R.id.app_description); - - convertView.setTag(holder); - return convertView; - } - - public View getView(int position, View convertView, ViewGroup parent) { - if (convertView == null) { - convertView = createView(parent); - } - final ViewHolder holder = (ViewHolder) convertView.getTag(); - - // index is reverse since most recent appears at the bottom... - final int index = mRecentTaskDescriptions.size() - position - 1; - - final TaskDescription td = mRecentTaskDescriptions.get(index); - - holder.labelView.setText(td.getLabel()); - holder.thumbnailView.setContentDescription(td.getLabel()); - holder.loadedThumbnailAndIcon = td.isLoaded(); - if (td.isLoaded()) { - updateThumbnail(holder, td.getThumbnail(), true, false); - updateIcon(holder, td.getIcon(), true, false); - } - if (index == 0) { - if (mAnimateIconOfFirstTask) { - ViewHolder oldHolder = mItemToAnimateInWhenWindowAnimationIsFinished; - if (oldHolder != null) { - oldHolder.iconView.setAlpha(1f); - oldHolder.iconView.setTranslationX(0f); - oldHolder.iconView.setTranslationY(0f); - oldHolder.labelView.setAlpha(1f); - oldHolder.labelView.setTranslationX(0f); - oldHolder.labelView.setTranslationY(0f); - if (oldHolder.calloutLine != null) { - oldHolder.calloutLine.setAlpha(1f); - oldHolder.calloutLine.setTranslationX(0f); - oldHolder.calloutLine.setTranslationY(0f); - } - } - mItemToAnimateInWhenWindowAnimationIsFinished = holder; - int translation = -getResources().getDimensionPixelSize( - R.dimen.status_bar_recents_app_icon_translate_distance); - final Configuration config = getResources().getConfiguration(); - if (config.orientation == Configuration.ORIENTATION_PORTRAIT) { - if (getLayoutDirection() == View.LAYOUT_DIRECTION_RTL) { - translation = -translation; - } - holder.iconView.setAlpha(0f); - holder.iconView.setTranslationX(translation); - holder.labelView.setAlpha(0f); - holder.labelView.setTranslationX(translation); - holder.calloutLine.setAlpha(0f); - holder.calloutLine.setTranslationX(translation); - } else { - holder.iconView.setAlpha(0f); - holder.iconView.setTranslationY(translation); - } - if (!mWaitingForWindowAnimation) { - animateInIconOfFirstTask(); - } - } - } - - holder.thumbnailView.setTag(td); - holder.thumbnailView.setOnLongClickListener(new OnLongClickDelegate(convertView)); - holder.taskDescription = td; - return convertView; - } - - public void recycleView(View v) { - ViewHolder holder = (ViewHolder) v.getTag(); - updateThumbnail(holder, mRecentTasksLoader.getDefaultThumbnail(), false, false); - holder.iconView.setImageDrawable(mRecentTasksLoader.getDefaultIcon()); - holder.iconView.setVisibility(INVISIBLE); - holder.iconView.animate().cancel(); - holder.labelView.setText(null); - holder.labelView.animate().cancel(); - holder.thumbnailView.setContentDescription(null); - holder.thumbnailView.setTag(null); - holder.thumbnailView.setOnLongClickListener(null); - holder.thumbnailView.setVisibility(INVISIBLE); - holder.iconView.setAlpha(1f); - holder.iconView.setTranslationX(0f); - holder.iconView.setTranslationY(0f); - holder.labelView.setAlpha(1f); - holder.labelView.setTranslationX(0f); - holder.labelView.setTranslationY(0f); - if (holder.calloutLine != null) { - holder.calloutLine.setAlpha(1f); - holder.calloutLine.setTranslationX(0f); - holder.calloutLine.setTranslationY(0f); - holder.calloutLine.animate().cancel(); - } - holder.taskDescription = null; - holder.loadedThumbnailAndIcon = false; - } - } - - public RecentsPanelView(Context context, AttributeSet attrs) { - this(context, attrs, 0); - } - - public RecentsPanelView(Context context, AttributeSet attrs, int defStyle) { - super(context, attrs, defStyle); - updateValuesFromResources(); - - TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.RecentsPanelView, - defStyle, 0); - - mRecentItemLayoutId = a.getResourceId(R.styleable.RecentsPanelView_recentItemLayout, 0); - mRecentTasksLoader = RecentTasksLoader.getInstance(context); - a.recycle(); - } - - public int numItemsInOneScreenful() { - return mRecentsContainer.numItemsInOneScreenful(); - } - - private boolean pointInside(int x, int y, View v) { - final int l = v.getLeft(); - final int r = v.getRight(); - final int t = v.getTop(); - final int b = v.getBottom(); - return x >= l && x < r && y >= t && y < b; - } - - public boolean isInContentArea(int x, int y) { - return pointInside(x, y, (View) mRecentsContainer); - } - - public void show(boolean show) { - show(show, null, false, false); - } - - public void show(boolean show, ArrayList<TaskDescription> recentTaskDescriptions, - boolean firstScreenful, boolean animateIconOfFirstTask) { - if (show && mCallUiHiddenBeforeNextReload) { - onUiHidden(); - recentTaskDescriptions = null; - mAnimateIconOfFirstTask = false; - mWaitingForWindowAnimation = false; - } else { - mAnimateIconOfFirstTask = animateIconOfFirstTask; - mWaitingForWindowAnimation = animateIconOfFirstTask; - } - if (show) { - mWaitingToShow = true; - refreshRecentTasksList(recentTaskDescriptions, firstScreenful); - showIfReady(); - } else { - showImpl(false); - } - } - - private void showIfReady() { - // mWaitingToShow => there was a touch up on the recents button - // mRecentTaskDescriptions != null => we've created views for the first screenful of items - if (mWaitingToShow && mRecentTaskDescriptions != null) { - showImpl(true); - } - } - - static void sendCloseSystemWindows(Context context, String reason) { - if (ActivityManagerNative.isSystemReady()) { - try { - ActivityManagerNative.getDefault().closeSystemDialogs(reason); - } catch (RemoteException e) { - } - } - } - - private void showImpl(boolean show) { - sendCloseSystemWindows(getContext(), BaseStatusBar.SYSTEM_DIALOG_REASON_RECENT_APPS); - - mShowing = show; - - if (show) { - // if there are no apps, bring up a "No recent apps" message - boolean noApps = mRecentTaskDescriptions != null - && (mRecentTaskDescriptions.size() == 0); - mRecentsNoApps.setAlpha(1f); - mRecentsNoApps.setVisibility(noApps ? View.VISIBLE : View.INVISIBLE); - - onAnimationEnd(null); - setFocusable(true); - setFocusableInTouchMode(true); - requestFocus(); - } else { - mWaitingToShow = false; - // call onAnimationEnd() and clearRecentTasksList() in onUiHidden() - mCallUiHiddenBeforeNextReload = true; - if (mPopup != null) { - mPopup.dismiss(); - } - } - } - - protected void onAttachedToWindow () { - super.onAttachedToWindow(); - final ViewRootImpl root = getViewRootImpl(); - if (root != null) { - root.setDrawDuringWindowsAnimating(true); - } - } - - public void onUiHidden() { - mCallUiHiddenBeforeNextReload = false; - if (!mShowing && mRecentTaskDescriptions != null) { - onAnimationEnd(null); - clearRecentTasksList(); - } - } - - public void dismiss() { - ((RecentsActivity) getContext()).dismissAndGoHome(); - } - - public void dismissAndGoBack() { - ((RecentsActivity) getContext()).dismissAndGoBack(); - } - - public void onAnimationCancel(Animator animation) { - } - - public void onAnimationEnd(Animator animation) { - if (mShowing) { - final LayoutTransition transitioner = new LayoutTransition(); - ((ViewGroup)mRecentsContainer).setLayoutTransition(transitioner); - createCustomAnimations(transitioner); - } else { - ((ViewGroup)mRecentsContainer).setLayoutTransition(null); - } - } - - public void onAnimationRepeat(Animator animation) { - } - - public void onAnimationStart(Animator animation) { - } - - @Override - public boolean dispatchHoverEvent(MotionEvent event) { - // Ignore hover events outside of this panel bounds since such events - // generate spurious accessibility events with the panel content when - // tapping outside of it, thus confusing the user. - final int x = (int) event.getX(); - final int y = (int) event.getY(); - if (x >= 0 && x < getWidth() && y >= 0 && y < getHeight()) { - return super.dispatchHoverEvent(event); - } - return true; - } - - /** - * Whether the panel is showing, or, if it's animating, whether it will be - * when the animation is done. - */ - public boolean isShowing() { - return mShowing; - } - - public void setRecentTasksLoader(RecentTasksLoader loader) { - mRecentTasksLoader = loader; - } - - public void updateValuesFromResources() { - final Resources res = getContext().getResources(); - mThumbnailWidth = Math.round(res.getDimension(R.dimen.status_bar_recents_thumbnail_width)); - mFitThumbnailToXY = res.getBoolean(R.bool.config_recents_thumbnail_image_fits_to_xy); - } - - @Override - protected void onFinishInflate() { - super.onFinishInflate(); - - mRecentsContainer = (RecentsScrollView) findViewById(R.id.recents_container); - mRecentsContainer.setOnScrollListener(new Runnable() { - public void run() { - // need to redraw the faded edges - invalidate(); - } - }); - mListAdapter = new TaskDescriptionAdapter(getContext()); - mRecentsContainer.setAdapter(mListAdapter); - mRecentsContainer.setCallback(this); - - mRecentsScrim = findViewById(R.id.recents_bg_protect); - mRecentsNoApps = findViewById(R.id.recents_no_apps); - - if (mRecentsScrim != null) { - mHighEndGfx = ActivityManager.isHighEndGfx(); - if (!mHighEndGfx) { - mRecentsScrim.setBackground(null); - } else if (mRecentsScrim.getBackground() instanceof BitmapDrawable) { - // In order to save space, we make the background texture repeat in the Y direction - ((BitmapDrawable) mRecentsScrim.getBackground()).setTileModeY(TileMode.REPEAT); - } - } - } - - public void setMinSwipeAlpha(float minAlpha) { - mRecentsContainer.setMinSwipeAlpha(minAlpha); - } - - private void createCustomAnimations(LayoutTransition transitioner) { - transitioner.setDuration(200); - transitioner.setStartDelay(LayoutTransition.CHANGE_DISAPPEARING, 0); - transitioner.setAnimator(LayoutTransition.DISAPPEARING, null); - } - - private void updateIcon(ViewHolder h, Drawable icon, boolean show, boolean anim) { - if (icon != null) { - h.iconView.setImageDrawable(icon); - if (show && h.iconView.getVisibility() != View.VISIBLE) { - if (anim) { - h.iconView.setAnimation( - AnimationUtils.loadAnimation(getContext(), R.anim.recent_appear)); - } - h.iconView.setVisibility(View.VISIBLE); - } - } - } - - private void updateThumbnail(ViewHolder h, Drawable thumbnail, boolean show, boolean anim) { - 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.setImageDrawable(thumbnail); - - // scale the image to fill the full width of the ImageView. do this only if - // we haven't set a bitmap before, or if the bitmap size has changed - if (h.thumbnailViewDrawable == null || - h.thumbnailViewDrawable.getIntrinsicWidth() != thumbnail.getIntrinsicWidth() || - h.thumbnailViewDrawable.getIntrinsicHeight() != thumbnail.getIntrinsicHeight()) { - if (mFitThumbnailToXY) { - h.thumbnailViewImage.setScaleType(ScaleType.FIT_XY); - } else { - Matrix scaleMatrix = new Matrix(); - float scale = mThumbnailWidth / (float) thumbnail.getIntrinsicWidth(); - scaleMatrix.setScale(scale, scale); - h.thumbnailViewImage.setScaleType(ScaleType.MATRIX); - h.thumbnailViewImage.setImageMatrix(scaleMatrix); - } - } - if (show && h.thumbnailView.getVisibility() != View.VISIBLE) { - if (anim) { - h.thumbnailView.setAnimation( - AnimationUtils.loadAnimation(getContext(), R.anim.recent_appear)); - } - h.thumbnailView.setVisibility(View.VISIBLE); - } - h.thumbnailViewDrawable = thumbnail; - } - } - - void onTaskThumbnailLoaded(TaskDescription td) { - synchronized (td) { - if (mRecentsContainer != null) { - ViewGroup container = (ViewGroup) mRecentsContainer; - if (container instanceof RecentsScrollView) { - 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.loadedThumbnailAndIcon && h.taskDescription == td) { - // only fade in the thumbnail if recents is already visible-- we - // show it immediately otherwise - //boolean animateShow = mShowing && - // mRecentsContainer.getAlpha() > ViewConfiguration.ALPHA_THRESHOLD; - boolean animateShow = false; - updateIcon(h, td.getIcon(), true, animateShow); - updateThumbnail(h, td.getThumbnail(), true, animateShow); - h.loadedThumbnailAndIcon = true; - } - } - } - } - } - showIfReady(); - } - - private void animateInIconOfFirstTask() { - if (mItemToAnimateInWhenWindowAnimationIsFinished != null && - !mRecentTasksLoader.isFirstScreenful()) { - int timeSinceWindowAnimation = - (int) (System.currentTimeMillis() - mWindowAnimationStartTime); - final int minStartDelay = 150; - final int startDelay = Math.max(0, Math.min( - minStartDelay - timeSinceWindowAnimation, minStartDelay)); - final int duration = 250; - final ViewHolder holder = mItemToAnimateInWhenWindowAnimationIsFinished; - final TimeInterpolator cubic = new DecelerateInterpolator(1.5f); - FirstFrameAnimatorHelper.initializeDrawListener(holder.iconView); - for (View v : - new View[] { holder.iconView, holder.labelView, holder.calloutLine }) { - if (v != null) { - ViewPropertyAnimator vpa = v.animate().translationX(0).translationY(0) - .alpha(1f).setStartDelay(startDelay) - .setDuration(duration).setInterpolator(cubic); - FirstFrameAnimatorHelper h = new FirstFrameAnimatorHelper(vpa, v); - } - } - mItemToAnimateInWhenWindowAnimationIsFinished = null; - mAnimateIconOfFirstTask = false; - } - } - - public void onWindowAnimationStart() { - mWaitingForWindowAnimation = false; - mWindowAnimationStartTime = System.currentTimeMillis(); - animateInIconOfFirstTask(); - } - - public void clearRecentTasksList() { - // Clear memory used by screenshots - if (mRecentTaskDescriptions != null) { - mRecentTasksLoader.cancelLoadingThumbnailsAndIcons(this); - onTaskLoadingCancelled(); - } - } - - public void onTaskLoadingCancelled() { - // Gets called by RecentTasksLoader when it's cancelled - if (mRecentTaskDescriptions != null) { - mRecentTaskDescriptions = null; - mListAdapter.notifyDataSetInvalidated(); - } - } - - public void refreshViews() { - mListAdapter.notifyDataSetInvalidated(); - updateUiElements(); - showIfReady(); - } - - public void refreshRecentTasksList() { - refreshRecentTasksList(null, false); - } - - private void refreshRecentTasksList( - ArrayList<TaskDescription> recentTasksList, boolean firstScreenful) { - if (mRecentTaskDescriptions == null && recentTasksList != null) { - onTasksLoaded(recentTasksList, firstScreenful); - } else { - mRecentTasksLoader.loadTasksInBackground(); - } - } - - public void onTasksLoaded(ArrayList<TaskDescription> tasks, boolean firstScreenful) { - if (mRecentTaskDescriptions == null) { - mRecentTaskDescriptions = new ArrayList<TaskDescription>(tasks); - } else { - mRecentTaskDescriptions.addAll(tasks); - } - if (((RecentsActivity) getContext()).isActivityShowing()) { - refreshViews(); - } - } - - private void updateUiElements() { - final int items = mRecentTaskDescriptions != null - ? mRecentTaskDescriptions.size() : 0; - - ((View) mRecentsContainer).setVisibility(items > 0 ? View.VISIBLE : View.GONE); - - // Set description for accessibility - int numRecentApps = mRecentTaskDescriptions != null - ? mRecentTaskDescriptions.size() : 0; - String recentAppsAccessibilityDescription; - if (numRecentApps == 0) { - recentAppsAccessibilityDescription = - getResources().getString(R.string.status_bar_no_recent_apps); - } else { - recentAppsAccessibilityDescription = getResources().getQuantityString( - R.plurals.status_bar_accessibility_recent_apps, numRecentApps, numRecentApps); - } - setContentDescription(recentAppsAccessibilityDescription); - } - - public boolean simulateClick(int persistentTaskId) { - View v = mRecentsContainer.findViewForTask(persistentTaskId); - if (v != null) { - handleOnClick(v); - return true; - } - return false; - } - - public void handleOnClick(View view) { - ViewHolder holder = (ViewHolder) view.getTag(); - TaskDescription ad = holder.taskDescription; - final Context context = view.getContext(); - final ActivityManager am = (ActivityManager) - context.getSystemService(Context.ACTIVITY_SERVICE); - - Bitmap bm = null; - boolean usingDrawingCache = true; - if (holder.thumbnailViewDrawable instanceof BitmapDrawable) { - bm = ((BitmapDrawable) holder.thumbnailViewDrawable).getBitmap(); - if (bm.getWidth() == holder.thumbnailViewImage.getWidth() && - bm.getHeight() == holder.thumbnailViewImage.getHeight()) { - usingDrawingCache = false; - } - } - if (usingDrawingCache) { - holder.thumbnailViewImage.setDrawingCacheEnabled(true); - bm = holder.thumbnailViewImage.getDrawingCache(); - } - Bundle opts = (bm == null) ? - null : - ActivityOptions.makeThumbnailScaleUpAnimation( - holder.thumbnailViewImage, bm, 0, 0, null).toBundle(); - - show(false); - if (ad.taskId >= 0) { - // This is an active task; it should just go to the foreground. - am.moveTaskToFront(ad.taskId, ActivityManager.MOVE_TASK_WITH_HOME, - opts); - } else { - Intent intent = ad.intent; - intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY - | Intent.FLAG_ACTIVITY_TASK_ON_HOME - | Intent.FLAG_ACTIVITY_NEW_TASK); - if (DEBUG) Log.v(TAG, "Starting activity " + intent); - try { - context.startActivityAsUser(intent, opts, - new UserHandle(ad.userId)); - } catch (SecurityException e) { - Log.e(TAG, "Recents does not have the permission to launch " + intent, e); - } catch (ActivityNotFoundException e) { - Log.e(TAG, "Error launching activity " + intent, e); - } - } - if (usingDrawingCache) { - holder.thumbnailViewImage.setDrawingCacheEnabled(false); - } - } - - public void onItemClick(AdapterView<?> parent, View view, int position, long id) { - handleOnClick(view); - } - - public void handleSwipe(View view) { - TaskDescription ad = ((ViewHolder) view.getTag()).taskDescription; - if (ad == null) { - Log.v(TAG, "Not able to find activity description for swiped task; view=" + view + - " tag=" + view.getTag()); - return; - } - if (DEBUG) Log.v(TAG, "Jettison " + ad.getLabel()); - mRecentTaskDescriptions.remove(ad); - mRecentTasksLoader.remove(ad); - - // Handled by widget containers to enable LayoutTransitions properly - // mListAdapter.notifyDataSetChanged(); - - if (mRecentTaskDescriptions.size() == 0) { - dismissAndGoBack(); - } - - // Currently, either direction means the same thing, so ignore direction and remove - // the task. - final ActivityManager am = (ActivityManager) - getContext().getSystemService(Context.ACTIVITY_SERVICE); - if (am != null) { - am.removeTask(ad.persistentTaskId); - - // Accessibility feedback - setContentDescription( - getContext().getString(R.string.accessibility_recents_item_dismissed, ad.getLabel())); - sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_SELECTED); - setContentDescription(null); - } - } - - private void startApplicationDetailsActivity(String packageName, int userId) { - Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS, - Uri.fromParts("package", packageName, null)); - intent.setComponent(intent.resolveActivity(getContext().getPackageManager())); - TaskStackBuilder.create(getContext()) - .addNextIntentWithParentStack(intent).startActivities(null, new UserHandle(userId)); - } - - public boolean onInterceptTouchEvent(MotionEvent ev) { - if (mPopup != null) { - return true; - } else { - return super.onInterceptTouchEvent(ev); - } - } - - public void handleLongPress( - final View selectedView, final View anchorView, final View thumbnailView) { - thumbnailView.setSelected(true); - final PopupMenu popup = - new PopupMenu(getContext(), anchorView == null ? selectedView : anchorView); - mPopup = popup; - popup.getMenuInflater().inflate(R.menu.recent_popup_menu, popup.getMenu()); - popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() { - public boolean onMenuItemClick(MenuItem item) { - if (item.getItemId() == R.id.recent_remove_item) { - ((ViewGroup) mRecentsContainer).removeViewInLayout(selectedView); - } else if (item.getItemId() == R.id.recent_inspect_item) { - ViewHolder viewHolder = (ViewHolder) selectedView.getTag(); - if (viewHolder != null) { - final TaskDescription ad = viewHolder.taskDescription; - startApplicationDetailsActivity(ad.packageName, ad.userId); - show(false); - } else { - throw new IllegalStateException("Oops, no tag on view " + selectedView); - } - } else { - return false; - } - return true; - } - }); - popup.setOnDismissListener(new PopupMenu.OnDismissListener() { - public void onDismiss(PopupMenu menu) { - thumbnailView.setSelected(false); - mPopup = null; - } - }); - popup.show(); - } - - @Override - protected void dispatchDraw(Canvas canvas) { - super.dispatchDraw(canvas); - - int paddingLeft = getPaddingLeft(); - final boolean offsetRequired = isPaddingOffsetRequired(); - if (offsetRequired) { - paddingLeft += getLeftPaddingOffset(); - } - - int left = getScrollX() + paddingLeft; - int right = left + getRight() - getLeft() - getPaddingRight() - paddingLeft; - int top = getScrollY() + getFadeTop(offsetRequired); - int bottom = top + getFadeHeight(offsetRequired); - - if (offsetRequired) { - right += getRightPaddingOffset(); - bottom += getBottomPaddingOffset(); - } - mRecentsContainer.drawFadedEdges(canvas, left, right, top, bottom); - } -} diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentsPreloadReceiver.java b/packages/SystemUI/src/com/android/systemui/recent/RecentsPreloadReceiver.java deleted file mode 100644 index eb58920..0000000 --- a/packages/SystemUI/src/com/android/systemui/recent/RecentsPreloadReceiver.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (C) 2012 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. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.systemui.recent; - -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; - -public class RecentsPreloadReceiver extends BroadcastReceiver { - @Override - public void onReceive(Context context, Intent intent) { - if (RecentsActivity.PRELOAD_INTENT.equals(intent.getAction())) { - RecentTasksLoader.getInstance(context).preloadRecentTasksList(); - } else if (RecentsActivity.CANCEL_PRELOAD_INTENT.equals(intent.getAction())){ - RecentTasksLoader.getInstance(context).cancelPreloadingRecentTasksList(); - } - } -} diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentsVerticalScrollView.java b/packages/SystemUI/src/com/android/systemui/recent/RecentsVerticalScrollView.java deleted file mode 100644 index d518f74..0000000 --- a/packages/SystemUI/src/com/android/systemui/recent/RecentsVerticalScrollView.java +++ /dev/null @@ -1,401 +0,0 @@ -/* - * Copyright (C) 2011 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. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.systemui.recent; - -import android.animation.LayoutTransition; -import android.content.Context; -import android.content.res.Configuration; -import android.database.DataSetObserver; -import android.graphics.Canvas; -import android.util.AttributeSet; -import android.util.DisplayMetrics; -import android.util.Log; -import android.view.MotionEvent; -import android.view.View; -import android.view.ViewConfiguration; -import android.view.ViewTreeObserver; -import android.view.ViewTreeObserver.OnGlobalLayoutListener; -import android.widget.LinearLayout; -import android.widget.ScrollView; - -import com.android.systemui.R; -import com.android.systemui.SwipeHelper; -import com.android.systemui.recent.RecentsPanelView.TaskDescriptionAdapter; - -import java.util.HashSet; -import java.util.Iterator; - -public class RecentsVerticalScrollView extends ScrollView - implements SwipeHelper.Callback, RecentsPanelView.RecentsScrollView { - private static final String TAG = RecentsPanelView.TAG; - private static final boolean DEBUG = RecentsPanelView.DEBUG; - private LinearLayout mLinearLayout; - private TaskDescriptionAdapter mAdapter; - private RecentsCallback mCallback; - protected int mLastScrollPosition; - private SwipeHelper mSwipeHelper; - private FadedEdgeDrawHelper mFadedEdgeDrawHelper; - private HashSet<View> mRecycledViews; - private int mNumItemsInOneScreenful; - private Runnable mOnScrollListener; - - public RecentsVerticalScrollView(Context context, AttributeSet attrs) { - super(context, attrs, 0); - mSwipeHelper = new SwipeHelper(SwipeHelper.X, this, context); - - mFadedEdgeDrawHelper = FadedEdgeDrawHelper.create(context, attrs, this, true); - mRecycledViews = new HashSet<View>(); - } - - public void setMinSwipeAlpha(float minAlpha) { - mSwipeHelper.setMinSwipeProgress(minAlpha); - } - - private int scrollPositionOfMostRecent() { - return mLinearLayout.getHeight() - getHeight() + getPaddingTop(); - } - - private void addToRecycledViews(View v) { - if (mRecycledViews.size() < mNumItemsInOneScreenful) { - mRecycledViews.add(v); - } - } - - public View findViewForTask(int persistentTaskId) { - for (int i = 0; i < mLinearLayout.getChildCount(); i++) { - View v = mLinearLayout.getChildAt(i); - RecentsPanelView.ViewHolder holder = (RecentsPanelView.ViewHolder) v.getTag(); - if (holder.taskDescription.persistentTaskId == persistentTaskId) { - return v; - } - } - return null; - } - - private void update() { - for (int i = 0; i < mLinearLayout.getChildCount(); i++) { - View v = mLinearLayout.getChildAt(i); - addToRecycledViews(v); - mAdapter.recycleView(v); - } - LayoutTransition transitioner = getLayoutTransition(); - setLayoutTransition(null); - - 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. - Iterator<View> recycledViews = mRecycledViews.iterator(); - for (int i = 0; i < mAdapter.getCount(); i++) { - View old = null; - if (recycledViews.hasNext()) { - old = recycledViews.next(); - recycledViews.remove(); - old.setVisibility(VISIBLE); - } - final View view = mAdapter.getView(i, old, mLinearLayout); - - if (mFadedEdgeDrawHelper != null) { - mFadedEdgeDrawHelper.addViewCallback(view); - } - - OnTouchListener noOpListener = new OnTouchListener() { - @Override - public boolean onTouch(View v, MotionEvent event) { - return true; - } - }; - - view.setOnClickListener(new OnClickListener() { - public void onClick(View v) { - mCallback.dismiss(); - } - }); - // We don't want a click sound when we dimiss recents - view.setSoundEffectsEnabled(false); - - OnClickListener launchAppListener = new OnClickListener() { - public void onClick(View v) { - mCallback.handleOnClick(view); - } - }; - - RecentsPanelView.ViewHolder holder = (RecentsPanelView.ViewHolder) view.getTag(); - final View thumbnailView = holder.thumbnailView; - OnLongClickListener longClickListener = new OnLongClickListener() { - public boolean onLongClick(View v) { - final View anchorView = view.findViewById(R.id.app_description); - mCallback.handleLongPress(view, anchorView, thumbnailView); - return true; - } - }; - thumbnailView.setClickable(true); - thumbnailView.setOnClickListener(launchAppListener); - thumbnailView.setOnLongClickListener(longClickListener); - - // We don't want to dismiss recents if a user clicks on the app title - // (we also don't want to launch the app either, though, because the - // app title is a small target and doesn't have great click feedback) - final View appTitle = view.findViewById(R.id.app_label); - appTitle.setContentDescription(" "); - appTitle.setOnTouchListener(noOpListener); - final View calloutLine = view.findViewById(R.id.recents_callout_line); - if (calloutLine != null) { - calloutLine.setOnTouchListener(noOpListener); - } - - mLinearLayout.addView(view); - } - setLayoutTransition(transitioner); - - // Scroll to end after initial layout. - final OnGlobalLayoutListener updateScroll = new OnGlobalLayoutListener() { - public void onGlobalLayout() { - mLastScrollPosition = scrollPositionOfMostRecent(); - scrollTo(0, mLastScrollPosition); - final ViewTreeObserver observer = getViewTreeObserver(); - if (observer.isAlive()) { - observer.removeOnGlobalLayoutListener(this); - } - } - }; - getViewTreeObserver().addOnGlobalLayoutListener(updateScroll); - } - - @Override - public void removeViewInLayout(final View view) { - dismissChild(view); - } - - public boolean onInterceptTouchEvent(MotionEvent ev) { - if (DEBUG) Log.v(TAG, "onInterceptTouchEvent()"); - return mSwipeHelper.onInterceptTouchEvent(ev) || - super.onInterceptTouchEvent(ev); - } - - @Override - public boolean onTouchEvent(MotionEvent ev) { - return mSwipeHelper.onTouchEvent(ev) || - super.onTouchEvent(ev); - } - - public boolean canChildBeDismissed(View v) { - return true; - } - - @Override - public boolean isAntiFalsingNeeded() { - return false; - } - - @Override - public float getFalsingThresholdFactor() { - return 1.0f; - } - - public void dismissChild(View v) { - mSwipeHelper.dismissChild(v, 0); - } - - public void onChildDismissed(View v) { - addToRecycledViews(v); - mLinearLayout.removeView(v); - mCallback.handleSwipe(v); - // Restore the alpha/translation parameters to what they were before swiping - // (for when these items are recycled) - View contentView = getChildContentView(v); - contentView.setAlpha(1f); - contentView.setTranslationX(0); - } - - public void onBeginDrag(View v) { - // We do this so the underlying ScrollView knows that it won't get - // the chance to intercept events anymore - requestDisallowInterceptTouchEvent(true); - } - - public void onDragCancelled(View v) { - } - - @Override - public void onChildSnappedBack(View animView) { - } - - @Override - public boolean updateSwipeProgress(View animView, boolean dismissable, float swipeProgress) { - return false; - } - - public View getChildAtPosition(MotionEvent ev) { - final float x = ev.getX() + getScrollX(); - final float y = ev.getY() + getScrollY(); - for (int i = 0; i < mLinearLayout.getChildCount(); i++) { - View item = mLinearLayout.getChildAt(i); - if (item.getVisibility() == View.VISIBLE - && x >= item.getLeft() && x < item.getRight() - && y >= item.getTop() && y < item.getBottom()) { - return item; - } - } - return null; - } - - public View getChildContentView(View v) { - return v.findViewById(R.id.recent_item); - } - - @Override - public void drawFadedEdges(Canvas canvas, int left, int right, int top, int bottom) { - if (mFadedEdgeDrawHelper != null) { - final boolean offsetRequired = isPaddingOffsetRequired(); - mFadedEdgeDrawHelper.drawCallback(canvas, - left, right, top + getFadeTop(offsetRequired), bottom, getScrollX(), getScrollY(), - getTopFadingEdgeStrength(), getBottomFadingEdgeStrength(), - 0, 0, getPaddingTop()); - } - } - - @Override - protected void onScrollChanged(int l, int t, int oldl, int oldt) { - super.onScrollChanged(l, t, oldl, oldt); - if (mOnScrollListener != null) { - mOnScrollListener.run(); - } - } - - public void setOnScrollListener(Runnable listener) { - mOnScrollListener = listener; - } - - @Override - public int getVerticalFadingEdgeLength() { - if (mFadedEdgeDrawHelper != null) { - return mFadedEdgeDrawHelper.getVerticalFadingEdgeLength(); - } else { - return super.getVerticalFadingEdgeLength(); - } - } - - @Override - public int getHorizontalFadingEdgeLength() { - if (mFadedEdgeDrawHelper != null) { - return mFadedEdgeDrawHelper.getHorizontalFadingEdgeLength(); - } else { - return super.getHorizontalFadingEdgeLength(); - } - } - - @Override - protected void onFinishInflate() { - super.onFinishInflate(); - setScrollbarFadingEnabled(true); - mLinearLayout = (LinearLayout) findViewById(R.id.recents_linear_layout); - final int leftPadding = getContext().getResources() - .getDimensionPixelOffset(R.dimen.status_bar_recents_thumbnail_left_margin); - setOverScrollEffectPadding(leftPadding, 0); - } - - @Override - public void onAttachedToWindow() { - if (mFadedEdgeDrawHelper != null) { - mFadedEdgeDrawHelper.onAttachedToWindowCallback(mLinearLayout, isHardwareAccelerated()); - } - } - - @Override - protected void onConfigurationChanged(Configuration newConfig) { - super.onConfigurationChanged(newConfig); - float densityScale = getResources().getDisplayMetrics().density; - mSwipeHelper.setDensityScale(densityScale); - float pagingTouchSlop = ViewConfiguration.get(getContext()).getScaledPagingTouchSlop(); - mSwipeHelper.setPagingTouchSlop(pagingTouchSlop); - } - - private void setOverScrollEffectPadding(int leftPadding, int i) { - // TODO Add to (Vertical)ScrollView - } - - @Override - protected void onSizeChanged(int w, int h, int oldw, int oldh) { - super.onSizeChanged(w, h, oldw, oldh); - - // Skip this work if a transition is running; it sets the scroll values independently - // and should not have those animated values clobbered by this logic - LayoutTransition transition = mLinearLayout.getLayoutTransition(); - if (transition != null && transition.isRunning()) { - return; - } - // Keep track of the last visible item in the list so we can restore it - // to the bottom when the orientation changes. - mLastScrollPosition = scrollPositionOfMostRecent(); - - // This has to happen post-layout, so run it "in the future" - post(new Runnable() { - public void run() { - // Make sure we're still not clobbering the transition-set values, since this - // runnable launches asynchronously - LayoutTransition transition = mLinearLayout.getLayoutTransition(); - if (transition == null || !transition.isRunning()) { - scrollTo(0, mLastScrollPosition); - } - } - }); - } - - public void setAdapter(TaskDescriptionAdapter adapter) { - mAdapter = adapter; - mAdapter.registerDataSetObserver(new DataSetObserver() { - public void onChanged() { - update(); - } - - public void onInvalidated() { - update(); - } - }); - - DisplayMetrics dm = getResources().getDisplayMetrics(); - int childWidthMeasureSpec = - MeasureSpec.makeMeasureSpec(dm.widthPixels, MeasureSpec.AT_MOST); - int childheightMeasureSpec = - MeasureSpec.makeMeasureSpec(dm.heightPixels, MeasureSpec.AT_MOST); - View child = mAdapter.createView(mLinearLayout); - child.measure(childWidthMeasureSpec, childheightMeasureSpec); - mNumItemsInOneScreenful = - (int) Math.ceil(dm.heightPixels / (double) child.getMeasuredHeight()); - addToRecycledViews(child); - - for (int i = 0; i < mNumItemsInOneScreenful - 1; i++) { - addToRecycledViews(mAdapter.createView(mLinearLayout)); - } - } - - public int numItemsInOneScreenful() { - return mNumItemsInOneScreenful; - } - - @Override - public void setLayoutTransition(LayoutTransition transition) { - // The layout transition applies to our embedded LinearLayout - mLinearLayout.setLayoutTransition(transition); - } - - public void setCallback(RecentsCallback callback) { - mCallback = callback; - } -} diff --git a/packages/SystemUI/src/com/android/systemui/recent/TaskDescription.java b/packages/SystemUI/src/com/android/systemui/recent/TaskDescription.java deleted file mode 100644 index 5ad965f..0000000 --- a/packages/SystemUI/src/com/android/systemui/recent/TaskDescription.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright (C) 2011 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. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.systemui.recent; - -import android.os.UserHandle; -import android.content.Intent; -import android.content.pm.ResolveInfo; -import android.graphics.drawable.Drawable; - -public final class TaskDescription { - final ResolveInfo resolveInfo; - final int taskId; // application task id for curating apps - final int persistentTaskId; // persistent id - final Intent intent; // launch intent for application - final String packageName; // used to override animations (see onClick()) - final CharSequence description; - final int userId; - - private Drawable mThumbnail; // generated by Activity.onCreateThumbnail() - private Drawable mIcon; // application package icon - private CharSequence mLabel; // application package label - private boolean mLoaded; - - public TaskDescription(int _taskId, int _persistentTaskId, - ResolveInfo _resolveInfo, Intent _intent, - String _packageName, CharSequence _description, int _userId) { - resolveInfo = _resolveInfo; - intent = _intent; - taskId = _taskId; - persistentTaskId = _persistentTaskId; - - description = _description; - packageName = _packageName; - userId = _userId; - } - - public TaskDescription() { - resolveInfo = null; - intent = null; - taskId = -1; - persistentTaskId = -1; - - description = null; - packageName = null; - userId = UserHandle.USER_NULL; - } - - public void setLoaded(boolean loaded) { - mLoaded = loaded; - } - - public boolean isLoaded() { - return mLoaded; - } - - public boolean isNull() { - return resolveInfo == null; - } - - // mark all these as locked? - public CharSequence getLabel() { - return mLabel; - } - - public void setLabel(CharSequence label) { - mLabel = label; - } - - public Drawable getIcon() { - return mIcon; - } - - public void setIcon(Drawable icon) { - mIcon = icon; - } - - public void setThumbnail(Drawable thumbnail) { - mThumbnail = thumbnail; - } - - public Drawable getThumbnail() { - return mThumbnail; - } -} diff --git a/packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java b/packages/SystemUI/src/com/android/systemui/recents/Recents.java index 10618e0..7d7766b 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java +++ b/packages/SystemUI/src/com/android/systemui/recents/Recents.java @@ -37,10 +37,12 @@ import android.os.Handler; import android.os.SystemClock; import android.os.UserHandle; 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; import com.android.systemui.recents.misc.Console; import com.android.systemui.recents.misc.SystemServicesProxy; import com.android.systemui.recents.model.RecentsTaskLoadPlan; @@ -69,7 +71,8 @@ import java.util.concurrent.atomic.AtomicBoolean; @interface ProxyFromAnyToPrimaryUser {} /** A proxy implementation for the recents component */ -public class AlternateRecentsComponent implements ActivityOptions.OnAnimationStartedListener { +public class Recents extends SystemUI + implements ActivityOptions.OnAnimationStartedListener, RecentsComponent { final public static String EXTRA_TRIGGERED_FROM_ALT_TAB = "triggeredFromAltTab"; final public static String EXTRA_TRIGGERED_FROM_HOME_KEY = "triggeredFromHomeKey"; @@ -149,8 +152,8 @@ public class AlternateRecentsComponent implements ActivityOptions.OnAnimationSta static RecentsComponent.Callbacks sRecentsComponentCallbacks; static RecentsTaskLoadPlan sInstanceLoadPlan; + static Recents sInstance; - Context mContext; LayoutInflater mInflater; SystemServicesProxy mSystemServicesProxy; Handler mHandler; @@ -178,11 +181,43 @@ public class AlternateRecentsComponent implements ActivityOptions.OnAnimationSta boolean mTriggeredFromAltTab; long mLastToggleTime; - public AlternateRecentsComponent(Context context) { - RecentsTaskLoader.initialize(context); - mInflater = LayoutInflater.from(context); - mContext = context; - mSystemServicesProxy = new SystemServicesProxy(context); + public Recents() { + } + + /** + * Gets the singleton instance and starts it if needed. On the primary user on the device, this + * component gets started as a normal {@link SystemUI} component. On a secondary user, this + * lifecycle doesn't exist, so we need to start it manually here if needed. + */ + public static Recents getInstanceAndStartIfNeeded(Context ctx) { + if (sInstance == null) { + sInstance = new Recents(); + sInstance.mContext = ctx; + sInstance.start(); + sInstance.onBootCompleted(); + } + return sInstance; + } + + /** Creates a new broadcast intent */ + static Intent createLocalBroadcastIntent(Context context, String action) { + Intent intent = new Intent(action); + intent.setPackage(context.getPackageName()); + intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT | + Intent.FLAG_RECEIVER_FOREGROUND); + return intent; + } + + /** Initializes the Recents. */ + @ProxyFromPrimaryToCurrentUser + @Override + public void start() { + if (sInstance == null) { + sInstance = this; + } + RecentsTaskLoader.initialize(mContext); + mInflater = LayoutInflater.from(mContext); + mSystemServicesProxy = new SystemServicesProxy(mContext); mHandler = new Handler(); mTaskStackBounds = new Rect(); @@ -196,24 +231,11 @@ public class AlternateRecentsComponent implements ActivityOptions.OnAnimationSta if (mSystemServicesProxy.isForegroundUserOwner()) { mProxyBroadcastReceiver = new RecentsOwnerEventProxyReceiver(); IntentFilter filter = new IntentFilter(); - filter.addAction(AlternateRecentsComponent.ACTION_PROXY_NOTIFY_RECENTS_VISIBLITY_TO_OWNER); + filter.addAction(Recents.ACTION_PROXY_NOTIFY_RECENTS_VISIBLITY_TO_OWNER); mContext.registerReceiverAsUser(mProxyBroadcastReceiver, UserHandle.CURRENT, filter, null, mHandler); } - } - /** Creates a new broadcast intent */ - static Intent createLocalBroadcastIntent(Context context, String action) { - Intent intent = new Intent(action); - intent.setPackage(context.getPackageName()); - intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT | - Intent.FLAG_RECEIVER_FOREGROUND); - return intent; - } - - /** Initializes the Recents. */ - @ProxyFromPrimaryToCurrentUser - public void onStart() { // Initialize some static datastructures TaskStackViewLayoutAlgorithm.initializeCurve(); // Load the header bar layout @@ -229,17 +251,20 @@ public class AlternateRecentsComponent implements ActivityOptions.OnAnimationSta launchOpts.numVisibleTaskThumbnails = loader.getThumbnailCacheSize(); launchOpts.onlyLoadForCache = true; loader.loadTasks(mContext, plan, launchOpts); + putComponent(Recents.class, this); } + @Override public void onBootCompleted() { mBootCompleted = true; } /** Shows the Recents. */ @ProxyFromPrimaryToCurrentUser - public void onShowRecents(boolean triggeredFromAltTab) { + @Override + public void showRecents(boolean triggeredFromAltTab, View statusBarView) { if (mSystemServicesProxy.isForegroundUserOwner()) { - showRecents(triggeredFromAltTab); + showRecentsInternal(triggeredFromAltTab); } else { Intent intent = createLocalBroadcastIntent(mContext, RecentsUserEventProxyReceiver.ACTION_PROXY_SHOW_RECENTS_TO_USER); @@ -247,7 +272,8 @@ public class AlternateRecentsComponent implements ActivityOptions.OnAnimationSta mContext.sendBroadcastAsUser(intent, UserHandle.CURRENT); } } - void showRecents(boolean triggeredFromAltTab) { + + void showRecentsInternal(boolean triggeredFromAltTab) { mTriggeredFromAltTab = triggeredFromAltTab; try { @@ -259,9 +285,10 @@ public class AlternateRecentsComponent implements ActivityOptions.OnAnimationSta /** Hides the Recents. */ @ProxyFromPrimaryToCurrentUser - public void onHideRecents(boolean triggeredFromAltTab, boolean triggeredFromHomeKey) { + @Override + public void hideRecents(boolean triggeredFromAltTab, boolean triggeredFromHomeKey) { if (mSystemServicesProxy.isForegroundUserOwner()) { - hideRecents(triggeredFromAltTab, triggeredFromHomeKey); + hideRecentsInternal(triggeredFromAltTab, triggeredFromHomeKey); } else { Intent intent = createLocalBroadcastIntent(mContext, RecentsUserEventProxyReceiver.ACTION_PROXY_HIDE_RECENTS_TO_USER); @@ -270,7 +297,8 @@ public class AlternateRecentsComponent implements ActivityOptions.OnAnimationSta mContext.sendBroadcastAsUser(intent, UserHandle.CURRENT); } } - void hideRecents(boolean triggeredFromAltTab, boolean triggeredFromHomeKey) { + + void hideRecentsInternal(boolean triggeredFromAltTab, boolean triggeredFromHomeKey) { if (mBootCompleted) { ActivityManager.RunningTaskInfo topTask = getTopMostTask(); if (topTask != null && isRecentsTopMost(topTask, null)) { @@ -285,16 +313,18 @@ public class AlternateRecentsComponent implements ActivityOptions.OnAnimationSta /** Toggles the Recents activity. */ @ProxyFromPrimaryToCurrentUser - public void onToggleRecents() { + @Override + public void toggleRecents(Display display, int layoutDirection, View statusBarView) { if (mSystemServicesProxy.isForegroundUserOwner()) { - toggleRecents(); + toggleRecentsInternal(); } else { Intent intent = createLocalBroadcastIntent(mContext, RecentsUserEventProxyReceiver.ACTION_PROXY_TOGGLE_RECENTS_TO_USER); mContext.sendBroadcastAsUser(intent, UserHandle.CURRENT); } } - void toggleRecents() { + + void toggleRecentsInternal() { mTriggeredFromAltTab = false; try { @@ -306,16 +336,18 @@ public class AlternateRecentsComponent implements ActivityOptions.OnAnimationSta /** Preloads info for the Recents activity. */ @ProxyFromPrimaryToCurrentUser - public void onPreloadRecents() { + @Override + public void preloadRecents() { if (mSystemServicesProxy.isForegroundUserOwner()) { - preloadRecents(); + preloadRecentsInternal(); } else { Intent intent = createLocalBroadcastIntent(mContext, RecentsUserEventProxyReceiver.ACTION_PROXY_PRELOAD_RECENTS_TO_USER); mContext.sendBroadcastAsUser(intent, UserHandle.CURRENT); } } - void preloadRecents() { + + void preloadRecentsInternal() { // Preload only the raw task list into a new load plan (which will be consumed by the // RecentsActivity) RecentsTaskLoader loader = RecentsTaskLoader.getInstance(); @@ -323,7 +355,8 @@ public class AlternateRecentsComponent implements ActivityOptions.OnAnimationSta sInstanceLoadPlan.preloadRawTasks(true); } - public void onCancelPreloadingRecents() { + @Override + public void cancelPreloadingRecents() { // Do nothing } @@ -398,11 +431,13 @@ public class AlternateRecentsComponent implements ActivityOptions.OnAnimationSta } } - public void onShowNextAffiliatedTask() { + @Override + public void showNextAffiliatedTask() { showRelativeAffiliatedTask(true); } - public void onShowPrevAffiliatedTask() { + @Override + public void showPrevAffiliatedTask() { showRelativeAffiliatedTask(false); } @@ -745,7 +780,8 @@ public class AlternateRecentsComponent implements ActivityOptions.OnAnimationSta } /** Sets the RecentsComponent callbacks. */ - public void setRecentsComponentCallback(RecentsComponent.Callbacks cb) { + @Override + public void setCallback(RecentsComponent.Callbacks cb) { sRecentsComponentCallbacks = cb; } diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java index ee631f5..95f2b7d 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java +++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java @@ -130,20 +130,20 @@ public class RecentsActivity extends Activity implements RecentsView.RecentsView @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); - if (action.equals(AlternateRecentsComponent.ACTION_HIDE_RECENTS_ACTIVITY)) { - if (intent.getBooleanExtra(AlternateRecentsComponent.EXTRA_TRIGGERED_FROM_ALT_TAB, false)) { + if (action.equals(Recents.ACTION_HIDE_RECENTS_ACTIVITY)) { + if (intent.getBooleanExtra(Recents.EXTRA_TRIGGERED_FROM_ALT_TAB, false)) { // If we are hiding from releasing Alt-Tab, dismiss Recents to the focused app dismissRecentsToFocusedTaskOrHome(false); - } else if (intent.getBooleanExtra(AlternateRecentsComponent.EXTRA_TRIGGERED_FROM_HOME_KEY, false)) { + } else if (intent.getBooleanExtra(Recents.EXTRA_TRIGGERED_FROM_HOME_KEY, false)) { // Otherwise, dismiss Recents to Home dismissRecentsToHome(true); } else { // Do nothing, another activity is being launched on top of Recents } - } else if (action.equals(AlternateRecentsComponent.ACTION_TOGGLE_RECENTS_ACTIVITY)) { + } else if (action.equals(Recents.ACTION_TOGGLE_RECENTS_ACTIVITY)) { // If we are toggling Recents, then first unfilter any filtered stacks first dismissRecentsToFocusedTaskOrHome(true); - } else if (action.equals(AlternateRecentsComponent.ACTION_START_ENTER_ANIMATION)) { + } else if (action.equals(Recents.ACTION_START_ENTER_ANIMATION)) { // Trigger the enter animation onEnterAnimationTriggered(); // Notify the fallback receiver that we have successfully got the broadcast @@ -185,7 +185,7 @@ public class RecentsActivity extends Activity implements RecentsView.RecentsView // If AlternateRecentsComponent has preloaded a load plan, then use that to prevent // reconstructing the task stack RecentsTaskLoader loader = RecentsTaskLoader.getInstance(); - RecentsTaskLoadPlan plan = AlternateRecentsComponent.consumeInstanceLoadPlan(); + RecentsTaskLoadPlan plan = Recents.consumeInstanceLoadPlan(); if (plan == null) { plan = loader.createLoadPlan(this); } @@ -436,13 +436,13 @@ public class RecentsActivity extends Activity implements RecentsView.RecentsView mVisible = true; RecentsTaskLoader loader = RecentsTaskLoader.getInstance(); SystemServicesProxy ssp = loader.getSystemServicesProxy(); - AlternateRecentsComponent.notifyVisibilityChanged(this, ssp, true); + Recents.notifyVisibilityChanged(this, ssp, true); // Register the broadcast receiver to handle messages from our service IntentFilter filter = new IntentFilter(); - filter.addAction(AlternateRecentsComponent.ACTION_HIDE_RECENTS_ACTIVITY); - filter.addAction(AlternateRecentsComponent.ACTION_TOGGLE_RECENTS_ACTIVITY); - filter.addAction(AlternateRecentsComponent.ACTION_START_ENTER_ANIMATION); + filter.addAction(Recents.ACTION_HIDE_RECENTS_ACTIVITY); + filter.addAction(Recents.ACTION_TOGGLE_RECENTS_ACTIVITY); + filter.addAction(Recents.ACTION_START_ENTER_ANIMATION); registerReceiver(mServiceBroadcastReceiver, filter); // Register any broadcast receivers for the task loader @@ -458,7 +458,7 @@ public class RecentsActivity extends Activity implements RecentsView.RecentsView mVisible = false; RecentsTaskLoader loader = RecentsTaskLoader.getInstance(); SystemServicesProxy ssp = loader.getSystemServicesProxy(); - AlternateRecentsComponent.notifyVisibilityChanged(this, ssp, false); + Recents.notifyVisibilityChanged(this, ssp, false); // Notify the views that we are no longer visible mRecentsView.onRecentsHidden(); diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsUserEventProxyReceiver.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsUserEventProxyReceiver.java index 236da5d..5eefbc7 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/RecentsUserEventProxyReceiver.java +++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsUserEventProxyReceiver.java @@ -19,8 +19,6 @@ package com.android.systemui.recents; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; -import com.android.systemui.recent.Recents; - /** * A proxy for Recents events which happens strictly for non-owner users. @@ -39,28 +37,27 @@ public class RecentsUserEventProxyReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { - AlternateRecentsComponent recents = Recents.getRecentsComponent( - context.getApplicationContext(), true); + Recents recents = Recents.getInstanceAndStartIfNeeded(context); switch (intent.getAction()) { case ACTION_PROXY_SHOW_RECENTS_TO_USER: { boolean triggeredFromAltTab = intent.getBooleanExtra( - AlternateRecentsComponent.EXTRA_TRIGGERED_FROM_ALT_TAB, false); - recents.showRecents(triggeredFromAltTab); + Recents.EXTRA_TRIGGERED_FROM_ALT_TAB, false); + recents.showRecentsInternal(triggeredFromAltTab); break; } case ACTION_PROXY_HIDE_RECENTS_TO_USER: { boolean triggeredFromAltTab = intent.getBooleanExtra( - AlternateRecentsComponent.EXTRA_TRIGGERED_FROM_ALT_TAB, false); + Recents.EXTRA_TRIGGERED_FROM_ALT_TAB, false); boolean triggeredFromHome = intent.getBooleanExtra( - AlternateRecentsComponent.EXTRA_TRIGGERED_FROM_HOME_KEY, false); - recents.hideRecents(triggeredFromAltTab, triggeredFromHome); + Recents.EXTRA_TRIGGERED_FROM_HOME_KEY, false); + recents.hideRecentsInternal(triggeredFromAltTab, triggeredFromHome); break; } case ACTION_PROXY_TOGGLE_RECENTS_TO_USER: - recents.toggleRecents(); + recents.toggleRecentsInternal(); break; case ACTION_PROXY_PRELOAD_RECENTS_TO_USER: - recents.preloadRecents(); + recents.preloadRecentsInternal(); break; case ACTION_PROXY_CONFIG_CHANGE_TO_USER: recents.configurationChanged(); diff --git a/packages/SystemUI/src/com/android/systemui/recent/ScreenPinningRequest.java b/packages/SystemUI/src/com/android/systemui/recents/ScreenPinningRequest.java index 2fa0b58..502862e 100644 --- a/packages/SystemUI/src/com/android/systemui/recent/ScreenPinningRequest.java +++ b/packages/SystemUI/src/com/android/systemui/recents/ScreenPinningRequest.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.recent; +package com.android.systemui.recents; import android.animation.ArgbEvaluator; import android.animation.ValueAnimator; @@ -41,7 +41,6 @@ import android.widget.LinearLayout; import android.widget.TextView; import com.android.systemui.R; -import com.android.systemui.recents.model.RecentsTaskLoader; import java.util.ArrayList; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java index da3d94a..f1538a5 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java @@ -91,6 +91,7 @@ import com.android.systemui.RecentsComponent; import com.android.systemui.SearchPanelView; import com.android.systemui.SwipeHelper; import com.android.systemui.SystemUI; +import com.android.systemui.recents.Recents; import com.android.systemui.statusbar.NotificationData.Entry; import com.android.systemui.statusbar.phone.NavigationBarView; import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager; @@ -531,7 +532,7 @@ public abstract class BaseStatusBar extends SystemUI implements mBarService = IStatusBarService.Stub.asInterface( ServiceManager.getService(Context.STATUS_BAR_SERVICE)); - mRecents = getComponent(RecentsComponent.class); + mRecents = getComponent(Recents.class); mRecents.setCallback(this); final Configuration currentConfig = mContext.getResources().getConfiguration(); 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 5e7a33a..da63009 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java @@ -128,7 +128,7 @@ import com.android.systemui.doze.DozeHost; import com.android.systemui.doze.DozeLog; import com.android.systemui.keyguard.KeyguardViewMediator; import com.android.systemui.qs.QSPanel; -import com.android.systemui.recent.ScreenPinningRequest; +import com.android.systemui.recents.ScreenPinningRequest; import com.android.systemui.statusbar.ActivatableNotificationView; import com.android.systemui.statusbar.BackDropView; import com.android.systemui.statusbar.BaseStatusBar; |