Merge "Recents: apps scale down to thumbnails now" into jb-mr1-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
03f482c34d
@@ -53,6 +53,7 @@
|
|||||||
<uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
|
<uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
|
||||||
|
|
||||||
<application
|
<application
|
||||||
|
android:name="com.android.systemui.SystemUIApplication"
|
||||||
android:persistent="true"
|
android:persistent="true"
|
||||||
android:allowClearUserData="false"
|
android:allowClearUserData="false"
|
||||||
android:allowBackup="false"
|
android:allowBackup="false"
|
||||||
@@ -96,6 +97,16 @@
|
|||||||
android:excludeFromRecents="true">
|
android:excludeFromRecents="true">
|
||||||
</activity>
|
</activity>
|
||||||
|
|
||||||
|
<activity android:name=".recent.RecentsActivity"
|
||||||
|
android:theme="@android:style/Theme.Holo.Wallpaper.NoTitleBar"
|
||||||
|
android:excludeFromRecents="true"
|
||||||
|
android:launchMode="singleInstance"
|
||||||
|
android:exported="true">
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="com.android.systemui.TOGGLE_RECENTS" />
|
||||||
|
</intent-filter>
|
||||||
|
</activity>
|
||||||
|
|
||||||
<!-- started from UsbDeviceSettingsManager -->
|
<!-- started from UsbDeviceSettingsManager -->
|
||||||
<activity android:name=".usb.UsbConfirmActivity"
|
<activity android:name=".usb.UsbConfirmActivity"
|
||||||
android:exported="true"
|
android:exported="true"
|
||||||
|
|||||||
@@ -26,11 +26,6 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
systemui:recentItemLayout="@layout/status_bar_recent_item"
|
systemui:recentItemLayout="@layout/status_bar_recent_item"
|
||||||
>
|
>
|
||||||
<View
|
|
||||||
android:id="@+id/recents_transition_background"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:visibility="invisible" />
|
|
||||||
<FrameLayout
|
<FrameLayout
|
||||||
android:id="@+id/recents_bg_protect"
|
android:id="@+id/recents_bg_protect"
|
||||||
android:background="@drawable/status_bar_recents_background"
|
android:background="@drawable/status_bar_recents_background"
|
||||||
@@ -40,12 +35,6 @@
|
|||||||
android:clipToPadding="false"
|
android:clipToPadding="false"
|
||||||
android:clipChildren="false">
|
android:clipChildren="false">
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:id="@+id/recents_transition_placeholder_icon"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:visibility="invisible" />
|
|
||||||
|
|
||||||
<com.android.systemui.recent.RecentsHorizontalScrollView android:id="@+id/recents_container"
|
<com.android.systemui.recent.RecentsHorizontalScrollView android:id="@+id/recents_container"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
|
|||||||
@@ -26,11 +26,6 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
systemui:recentItemLayout="@layout/status_bar_recent_item"
|
systemui:recentItemLayout="@layout/status_bar_recent_item"
|
||||||
>
|
>
|
||||||
<View
|
|
||||||
android:id="@+id/recents_transition_background"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:visibility="invisible" />
|
|
||||||
<FrameLayout
|
<FrameLayout
|
||||||
android:id="@+id/recents_bg_protect"
|
android:id="@+id/recents_bg_protect"
|
||||||
android:background="@drawable/status_bar_recents_background"
|
android:background="@drawable/status_bar_recents_background"
|
||||||
@@ -38,12 +33,6 @@
|
|||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:layout_alignParentBottom="true">
|
android:layout_alignParentBottom="true">
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:id="@+id/recents_transition_placeholder_icon"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:visibility="invisible" />
|
|
||||||
|
|
||||||
<com.android.systemui.recent.RecentsVerticalScrollView
|
<com.android.systemui.recent.RecentsVerticalScrollView
|
||||||
android:id="@+id/recents_container"
|
android:id="@+id/recents_container"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
|||||||
@@ -28,11 +28,6 @@
|
|||||||
android:clipChildren="false"
|
android:clipChildren="false"
|
||||||
systemui:recentItemLayout="@layout/system_bar_recent_item"
|
systemui:recentItemLayout="@layout/system_bar_recent_item"
|
||||||
>
|
>
|
||||||
<View
|
|
||||||
android:id="@+id/recents_transition_background"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:visibility="invisible" />
|
|
||||||
<FrameLayout
|
<FrameLayout
|
||||||
android:id="@+id/recents_bg_protect"
|
android:id="@+id/recents_bg_protect"
|
||||||
android:background="@drawable/recents_bg_protect_tile"
|
android:background="@drawable/recents_bg_protect_tile"
|
||||||
@@ -42,11 +37,6 @@
|
|||||||
android:layout_marginBottom="@*android:dimen/system_bar_height"
|
android:layout_marginBottom="@*android:dimen/system_bar_height"
|
||||||
android:clipToPadding="false"
|
android:clipToPadding="false"
|
||||||
android:clipChildren="false">
|
android:clipChildren="false">
|
||||||
<ImageView
|
|
||||||
android:id="@+id/recents_transition_placeholder_icon"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:visibility="invisible" />
|
|
||||||
|
|
||||||
<com.android.systemui.recent.RecentsVerticalScrollView android:id="@+id/recents_container"
|
<com.android.systemui.recent.RecentsVerticalScrollView android:id="@+id/recents_container"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
|
|||||||
@@ -28,6 +28,7 @@
|
|||||||
<!-- Size of application thumbnail -->
|
<!-- Size of application thumbnail -->
|
||||||
<dimen name="status_bar_recents_thumbnail_width">164dp</dimen>
|
<dimen name="status_bar_recents_thumbnail_width">164dp</dimen>
|
||||||
<dimen name="status_bar_recents_thumbnail_height">145dp</dimen>
|
<dimen name="status_bar_recents_thumbnail_height">145dp</dimen>
|
||||||
|
<dimen name="status_bar_recents_thumbnail_bg_padding">4dp</dimen>
|
||||||
|
|
||||||
<!-- Size of application label text -->
|
<!-- Size of application label text -->
|
||||||
<dimen name="status_bar_recents_app_label_text_size">14dip</dimen>
|
<dimen name="status_bar_recents_app_label_text_size">14dip</dimen>
|
||||||
|
|||||||
@@ -0,0 +1,32 @@
|
|||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
import android.app.Application;
|
||||||
|
|
||||||
|
import com.android.systemui.recent.RecentTasksLoader;
|
||||||
|
|
||||||
|
public class SystemUIApplication extends Application {
|
||||||
|
private RecentTasksLoader mRecentTasksLoader;
|
||||||
|
|
||||||
|
public RecentTasksLoader getRecentTasksLoader() {
|
||||||
|
if (mRecentTasksLoader == null) {
|
||||||
|
mRecentTasksLoader = new RecentTasksLoader(this);
|
||||||
|
}
|
||||||
|
return mRecentTasksLoader;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,191 +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.AnimatorSet;
|
|
||||||
import android.animation.AnimatorSet.Builder;
|
|
||||||
import android.animation.ObjectAnimator;
|
|
||||||
import android.content.res.Resources;
|
|
||||||
import android.graphics.drawable.ColorDrawable;
|
|
||||||
import android.graphics.drawable.Drawable;
|
|
||||||
import android.util.Slog;
|
|
||||||
import android.view.View;
|
|
||||||
|
|
||||||
import com.android.systemui.R;
|
|
||||||
|
|
||||||
/* package */ class Choreographer implements Animator.AnimatorListener {
|
|
||||||
// should group this into a multi-property animation
|
|
||||||
private static final int OPEN_DURATION = 136;
|
|
||||||
private static final int CLOSE_DURATION = 230;
|
|
||||||
private static final int SCRIM_DURATION = 400;
|
|
||||||
private static final String TAG = RecentsPanelView.TAG;
|
|
||||||
private static final boolean DEBUG = RecentsPanelView.DEBUG;
|
|
||||||
|
|
||||||
boolean mVisible;
|
|
||||||
int mPanelHeight;
|
|
||||||
RecentsPanelView mRootView;
|
|
||||||
View mScrimView;
|
|
||||||
View mContentView;
|
|
||||||
View mNoRecentAppsView;
|
|
||||||
AnimatorSet mContentAnim;
|
|
||||||
Animator.AnimatorListener mListener;
|
|
||||||
|
|
||||||
// the panel will start to appear this many px from the end
|
|
||||||
final int HYPERSPACE_OFFRAMP = 200;
|
|
||||||
|
|
||||||
public Choreographer(RecentsPanelView root, View scrim, View content,
|
|
||||||
View noRecentApps, Animator.AnimatorListener listener) {
|
|
||||||
mRootView = root;
|
|
||||||
mScrimView = scrim;
|
|
||||||
mContentView = content;
|
|
||||||
mListener = listener;
|
|
||||||
mNoRecentAppsView = noRecentApps;
|
|
||||||
}
|
|
||||||
|
|
||||||
void createAnimation(boolean appearing) {
|
|
||||||
float start, end;
|
|
||||||
|
|
||||||
// 0: on-screen
|
|
||||||
// height: off-screen
|
|
||||||
float y = mContentView.getTranslationY();
|
|
||||||
if (appearing) {
|
|
||||||
// we want to go from near-the-top to the top, unless we're half-open in the right
|
|
||||||
// general vicinity
|
|
||||||
start = (y < HYPERSPACE_OFFRAMP) ? y : HYPERSPACE_OFFRAMP;
|
|
||||||
end = 0;
|
|
||||||
} else {
|
|
||||||
start = y;
|
|
||||||
end = y;
|
|
||||||
}
|
|
||||||
|
|
||||||
Animator posAnim = ObjectAnimator.ofFloat(mContentView, "translationY",
|
|
||||||
start, end);
|
|
||||||
posAnim.setInterpolator(appearing
|
|
||||||
? new android.view.animation.DecelerateInterpolator(2.5f)
|
|
||||||
: new android.view.animation.AccelerateInterpolator(2.5f));
|
|
||||||
posAnim.setDuration(appearing ? OPEN_DURATION : CLOSE_DURATION);
|
|
||||||
|
|
||||||
Animator fadeAnim = ObjectAnimator.ofFloat(mContentView, "alpha",
|
|
||||||
mContentView.getAlpha(), appearing ? 1.0f : 0.0f);
|
|
||||||
fadeAnim.setInterpolator(appearing
|
|
||||||
? new android.view.animation.AccelerateInterpolator(1.0f)
|
|
||||||
: new android.view.animation.AccelerateInterpolator(2.5f));
|
|
||||||
fadeAnim.setDuration(appearing ? OPEN_DURATION : CLOSE_DURATION);
|
|
||||||
|
|
||||||
Animator noRecentAppsFadeAnim = null;
|
|
||||||
if (mNoRecentAppsView != null && // doesn't exist on large devices
|
|
||||||
mNoRecentAppsView.getVisibility() == View.VISIBLE) {
|
|
||||||
noRecentAppsFadeAnim = ObjectAnimator.ofFloat(mNoRecentAppsView, "alpha",
|
|
||||||
mContentView.getAlpha(), appearing ? 1.0f : 0.0f);
|
|
||||||
noRecentAppsFadeAnim.setInterpolator(appearing
|
|
||||||
? new android.view.animation.AccelerateInterpolator(1.0f)
|
|
||||||
: new android.view.animation.DecelerateInterpolator(1.0f));
|
|
||||||
noRecentAppsFadeAnim.setDuration(appearing ? OPEN_DURATION : CLOSE_DURATION);
|
|
||||||
}
|
|
||||||
|
|
||||||
mContentAnim = new AnimatorSet();
|
|
||||||
final Builder builder = mContentAnim.play(fadeAnim).with(posAnim);
|
|
||||||
|
|
||||||
if (noRecentAppsFadeAnim != null) {
|
|
||||||
builder.with(noRecentAppsFadeAnim);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (appearing) {
|
|
||||||
Drawable background = mScrimView.getBackground();
|
|
||||||
if (background != null) {
|
|
||||||
Animator bgAnim = ObjectAnimator.ofInt(background,
|
|
||||||
"alpha", appearing ? 0 : 255, appearing ? 255 : 0);
|
|
||||||
bgAnim.setDuration(appearing ? SCRIM_DURATION : CLOSE_DURATION);
|
|
||||||
builder.with(bgAnim);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
final Resources res = mRootView.getResources();
|
|
||||||
boolean isTablet = res.getBoolean(R.bool.config_recents_interface_for_tablets);
|
|
||||||
if (!isTablet) {
|
|
||||||
View recentsTransitionBackground =
|
|
||||||
mRootView.findViewById(R.id.recents_transition_background);
|
|
||||||
recentsTransitionBackground.setVisibility(View.VISIBLE);
|
|
||||||
Drawable bgDrawable = new ColorDrawable(0xFF000000);
|
|
||||||
recentsTransitionBackground.setBackground(bgDrawable);
|
|
||||||
Animator bgAnim = ObjectAnimator.ofInt(bgDrawable, "alpha", 0, 255);
|
|
||||||
bgAnim.setDuration(CLOSE_DURATION);
|
|
||||||
bgAnim.setInterpolator(new android.view.animation.AccelerateInterpolator(1f));
|
|
||||||
builder.with(bgAnim);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
mContentAnim.addListener(this);
|
|
||||||
if (mListener != null) {
|
|
||||||
mContentAnim.addListener(mListener);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void startAnimation(boolean appearing) {
|
|
||||||
if (DEBUG) Slog.d(TAG, "startAnimation(appearing=" + appearing + ")");
|
|
||||||
|
|
||||||
createAnimation(appearing);
|
|
||||||
|
|
||||||
// isHardwareAccelerated() checks if we're attached to a window and if that
|
|
||||||
// window is HW accelerated-- we were sometimes not attached to a window
|
|
||||||
// and buildLayer was throwing an IllegalStateException
|
|
||||||
if (mContentView.isHardwareAccelerated()) {
|
|
||||||
mContentView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
|
|
||||||
mContentView.buildLayer();
|
|
||||||
}
|
|
||||||
mContentAnim.start();
|
|
||||||
|
|
||||||
mVisible = appearing;
|
|
||||||
}
|
|
||||||
|
|
||||||
void jumpTo(boolean appearing) {
|
|
||||||
mContentView.setTranslationY(appearing ? 0 : mPanelHeight);
|
|
||||||
if (mScrimView.getBackground() != null) {
|
|
||||||
mScrimView.getBackground().setAlpha(appearing ? 255 : 0);
|
|
||||||
}
|
|
||||||
View recentsTransitionBackground =
|
|
||||||
mRootView.findViewById(R.id.recents_transition_background);
|
|
||||||
recentsTransitionBackground.setVisibility(View.INVISIBLE);
|
|
||||||
mRootView.requestLayout();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPanelHeight(int h) {
|
|
||||||
if (DEBUG) Slog.d(TAG, "panelHeight=" + h);
|
|
||||||
mPanelHeight = h;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onAnimationCancel(Animator animation) {
|
|
||||||
if (DEBUG) Slog.d(TAG, "onAnimationCancel");
|
|
||||||
// force this to zero so we close the window
|
|
||||||
mVisible = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onAnimationEnd(Animator animation) {
|
|
||||||
if (DEBUG) Slog.d(TAG, "onAnimationEnd");
|
|
||||||
if (!mVisible) {
|
|
||||||
mRootView.hideWindow();
|
|
||||||
}
|
|
||||||
mContentView.setLayerType(View.LAYER_TYPE_NONE, null);
|
|
||||||
mContentView.setAlpha(1f);
|
|
||||||
mContentAnim = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onAnimationRepeat(Animator animation) {
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onAnimationStart(Animator animation) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -32,6 +32,8 @@ import android.os.Handler;
|
|||||||
import android.os.Process;
|
import android.os.Process;
|
||||||
import android.os.UserHandle;
|
import android.os.UserHandle;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
import android.view.MotionEvent;
|
||||||
|
import android.view.View;
|
||||||
|
|
||||||
import com.android.systemui.R;
|
import com.android.systemui.R;
|
||||||
import com.android.systemui.statusbar.phone.PhoneStatusBar;
|
import com.android.systemui.statusbar.phone.PhoneStatusBar;
|
||||||
@@ -42,7 +44,7 @@ import java.util.List;
|
|||||||
import java.util.concurrent.BlockingQueue;
|
import java.util.concurrent.BlockingQueue;
|
||||||
import java.util.concurrent.LinkedBlockingQueue;
|
import java.util.concurrent.LinkedBlockingQueue;
|
||||||
|
|
||||||
public class RecentTasksLoader {
|
public class RecentTasksLoader implements View.OnTouchListener {
|
||||||
static final String TAG = "RecentTasksLoader";
|
static final String TAG = "RecentTasksLoader";
|
||||||
static final boolean DEBUG = TabletStatusBar.DEBUG || PhoneStatusBar.DEBUG || false;
|
static final boolean DEBUG = TabletStatusBar.DEBUG || PhoneStatusBar.DEBUG || false;
|
||||||
|
|
||||||
@@ -51,17 +53,43 @@ public class RecentTasksLoader {
|
|||||||
|
|
||||||
private Context mContext;
|
private Context mContext;
|
||||||
private RecentsPanelView mRecentsPanel;
|
private RecentsPanelView mRecentsPanel;
|
||||||
|
private TaskDescription mFirstTask;
|
||||||
|
private boolean mFirstTaskLoaded;
|
||||||
|
|
||||||
private AsyncTask<Void, ArrayList<TaskDescription>, Void> mTaskLoader;
|
private AsyncTask<Void, ArrayList<TaskDescription>, Void> mTaskLoader;
|
||||||
private AsyncTask<Void, TaskDescription, Void> mThumbnailLoader;
|
private AsyncTask<Void, TaskDescription, Void> mThumbnailLoader;
|
||||||
|
private Handler mHandler;
|
||||||
|
|
||||||
private int mIconDpi;
|
private int mIconDpi;
|
||||||
private Bitmap mDefaultThumbnailBackground;
|
private Bitmap mDefaultThumbnailBackground;
|
||||||
private Bitmap mDefaultIconBackground;
|
private Bitmap mDefaultIconBackground;
|
||||||
private int mNumTasksInFirstScreenful;
|
private int mNumTasksInFirstScreenful = Integer.MAX_VALUE;
|
||||||
|
|
||||||
|
private boolean mFirstScreenful;
|
||||||
|
private ArrayList<TaskDescription> mLoadedTasks;
|
||||||
|
|
||||||
|
private enum State { LOADING, LOADED, CANCELLED };
|
||||||
|
private State mState = State.CANCELLED;
|
||||||
|
|
||||||
|
public TaskDescription getFirstTask() {
|
||||||
|
while (!mFirstTaskLoaded) {
|
||||||
|
if (mState == State.CANCELLED) {
|
||||||
|
loadTasksInBackground();
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
if (mState == State.LOADED) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
Thread.sleep(5);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return mFirstTask;
|
||||||
|
}
|
||||||
|
|
||||||
public RecentTasksLoader(Context context) {
|
public RecentTasksLoader(Context context) {
|
||||||
mContext = context;
|
mContext = context;
|
||||||
|
mHandler = new Handler();
|
||||||
|
|
||||||
final Resources res = context.getResources();
|
final Resources res = context.getResources();
|
||||||
|
|
||||||
@@ -91,16 +119,16 @@ public class RecentTasksLoader {
|
|||||||
Bitmap.createBitmap(thumbnailWidth, thumbnailHeight, Bitmap.Config.ARGB_8888);
|
Bitmap.createBitmap(thumbnailWidth, thumbnailHeight, Bitmap.Config.ARGB_8888);
|
||||||
Canvas c = new Canvas(mDefaultThumbnailBackground);
|
Canvas c = new Canvas(mDefaultThumbnailBackground);
|
||||||
c.drawColor(color);
|
c.drawColor(color);
|
||||||
|
|
||||||
// If we're using the cache, begin listening to the activity manager for
|
|
||||||
// updated thumbnails
|
|
||||||
final ActivityManager am = (ActivityManager)
|
|
||||||
mContext.getSystemService(Context.ACTIVITY_SERVICE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setRecentsPanel(RecentsPanelView recentsPanel) {
|
public void setRecentsPanel(RecentsPanelView newRecentsPanel, RecentsPanelView caller) {
|
||||||
mRecentsPanel = recentsPanel;
|
// Only allow clearing mRecentsPanel if the caller is the current recentsPanel
|
||||||
mNumTasksInFirstScreenful = mRecentsPanel.numItemsInOneScreenful();
|
if (newRecentsPanel != null || mRecentsPanel == caller) {
|
||||||
|
mRecentsPanel = newRecentsPanel;
|
||||||
|
if (mRecentsPanel != null) {
|
||||||
|
mNumTasksInFirstScreenful = mRecentsPanel.numItemsInOneScreenful();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Bitmap getDefaultThumbnail() {
|
public Bitmap getDefaultThumbnail() {
|
||||||
@@ -111,26 +139,33 @@ public class RecentTasksLoader {
|
|||||||
return mDefaultIconBackground;
|
return mDefaultIconBackground;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create an TaskDescription, returning null if the title or icon is null, or if it's the
|
public ArrayList<TaskDescription> getLoadedTasks() {
|
||||||
// home activity
|
return mLoadedTasks;
|
||||||
|
}
|
||||||
|
|
||||||
|
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,
|
TaskDescription createTaskDescription(int taskId, int persistentTaskId, Intent baseIntent,
|
||||||
ComponentName origActivity, CharSequence description, ActivityInfo homeInfo) {
|
ComponentName origActivity, CharSequence description) {
|
||||||
Intent intent = new Intent(baseIntent);
|
Intent intent = new Intent(baseIntent);
|
||||||
if (origActivity != null) {
|
if (origActivity != null) {
|
||||||
intent.setComponent(origActivity);
|
intent.setComponent(origActivity);
|
||||||
}
|
}
|
||||||
final PackageManager pm = mContext.getPackageManager();
|
final PackageManager pm = mContext.getPackageManager();
|
||||||
if (homeInfo == null) {
|
|
||||||
homeInfo = new Intent(Intent.ACTION_MAIN).addCategory(Intent.CATEGORY_HOME)
|
|
||||||
.resolveActivityInfo(pm, 0);
|
|
||||||
}
|
|
||||||
// Don't load the current home activity.
|
|
||||||
if (homeInfo != null
|
|
||||||
&& homeInfo.packageName.equals(intent.getComponent().getPackageName())
|
|
||||||
&& homeInfo.name.equals(intent.getComponent().getClassName())) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
intent.setFlags((intent.getFlags()&~Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED)
|
intent.setFlags((intent.getFlags()&~Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED)
|
||||||
| Intent.FLAG_ACTIVITY_NEW_TASK);
|
| Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||||
final ResolveInfo resolveInfo = pm.resolveActivity(intent, 0);
|
final ResolveInfo resolveInfo = pm.resolveActivity(intent, 0);
|
||||||
@@ -207,7 +242,43 @@ public class RecentTasksLoader {
|
|||||||
return getFullResDefaultActivityIcon();
|
return getFullResDefaultActivityIcon();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void cancelLoadingThumbnailsAndIcons() {
|
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) {
|
||||||
|
mHandler.post(mPreloadTasksRunnable);
|
||||||
|
} else if (action == MotionEvent.ACTION_CANCEL) {
|
||||||
|
cancelLoadingThumbnailsAndIcons();
|
||||||
|
mHandler.removeCallbacks(mPreloadTasksRunnable);
|
||||||
|
} 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 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 (mTaskLoader != null) {
|
if (mTaskLoader != null) {
|
||||||
mTaskLoader.cancel(false);
|
mTaskLoader.cancel(false);
|
||||||
mTaskLoader = null;
|
mTaskLoader = null;
|
||||||
@@ -216,11 +287,26 @@ public class RecentTasksLoader {
|
|||||||
mThumbnailLoader.cancel(false);
|
mThumbnailLoader.cancel(false);
|
||||||
mThumbnailLoader = null;
|
mThumbnailLoader = null;
|
||||||
}
|
}
|
||||||
|
mLoadedTasks = null;
|
||||||
|
mFirstTask = null;
|
||||||
|
mFirstTaskLoaded = false;
|
||||||
|
if (mRecentsPanel != null) {
|
||||||
|
mRecentsPanel.onTaskLoadingCancelled();
|
||||||
|
}
|
||||||
|
mFirstScreenful = false;
|
||||||
|
mState = State.CANCELLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void loadTasksInBackground() {
|
public void loadTasksInBackground() {
|
||||||
// cancel all previous loading of tasks and thumbnails
|
loadTasksInBackground(false);
|
||||||
cancelLoadingThumbnailsAndIcons();
|
}
|
||||||
|
public void loadTasksInBackground(final boolean zeroeth) {
|
||||||
|
if (mState != State.CANCELLED) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mState = State.LOADING;
|
||||||
|
mFirstScreenful = true;
|
||||||
|
|
||||||
final LinkedBlockingQueue<TaskDescription> tasksWaitingForThumbnails =
|
final LinkedBlockingQueue<TaskDescription> tasksWaitingForThumbnails =
|
||||||
new LinkedBlockingQueue<TaskDescription>();
|
new LinkedBlockingQueue<TaskDescription>();
|
||||||
mTaskLoader = new AsyncTask<Void, ArrayList<TaskDescription>, Void>() {
|
mTaskLoader = new AsyncTask<Void, ArrayList<TaskDescription>, Void>() {
|
||||||
@@ -230,7 +316,14 @@ public class RecentTasksLoader {
|
|||||||
ArrayList<TaskDescription> newTasks = values[0];
|
ArrayList<TaskDescription> newTasks = values[0];
|
||||||
// do a callback to RecentsPanelView to let it know we have more values
|
// 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
|
// how do we let it know we're all done? just always call back twice
|
||||||
mRecentsPanel.onTasksLoaded(newTasks);
|
if (mRecentsPanel != null) {
|
||||||
|
mRecentsPanel.onTasksLoaded(newTasks, mFirstScreenful);
|
||||||
|
}
|
||||||
|
if (mLoadedTasks == null) {
|
||||||
|
mLoadedTasks = new ArrayList<TaskDescription>();
|
||||||
|
}
|
||||||
|
mLoadedTasks.addAll(newTasks);
|
||||||
|
mFirstScreenful = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
@@ -254,15 +347,34 @@ public class RecentTasksLoader {
|
|||||||
ArrayList<TaskDescription> tasks = new ArrayList<TaskDescription>();
|
ArrayList<TaskDescription> tasks = new ArrayList<TaskDescription>();
|
||||||
|
|
||||||
// skip the first task - assume it's either the home screen or the current activity.
|
// skip the first task - assume it's either the home screen or the current activity.
|
||||||
final int first = 1;
|
final int first = 0;
|
||||||
for (int i = first, index = 0; i < numTasks && (index < MAX_TASKS); ++i) {
|
for (int i = first, index = 0; i < numTasks && (index < MAX_TASKS); ++i) {
|
||||||
if (isCancelled()) {
|
if (isCancelled()) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
final ActivityManager.RecentTaskInfo recentInfo = recentTasks.get(i);
|
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)) {
|
||||||
|
if (index == 0) {
|
||||||
|
mFirstTaskLoaded = true;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Don't load ourselves
|
||||||
|
if (intent.getComponent().getPackageName().equals(mContext.getPackageName())) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
TaskDescription item = createTaskDescription(recentInfo.id,
|
TaskDescription item = createTaskDescription(recentInfo.id,
|
||||||
recentInfo.persistentId, recentInfo.baseIntent,
|
recentInfo.persistentId, recentInfo.baseIntent,
|
||||||
recentInfo.origActivity, recentInfo.description, homeInfo);
|
recentInfo.origActivity, recentInfo.description);
|
||||||
|
|
||||||
if (item != null) {
|
if (item != null) {
|
||||||
while (true) {
|
while (true) {
|
||||||
@@ -317,7 +429,13 @@ public class RecentTasksLoader {
|
|||||||
protected void onProgressUpdate(TaskDescription... values) {
|
protected void onProgressUpdate(TaskDescription... values) {
|
||||||
if (!isCancelled()) {
|
if (!isCancelled()) {
|
||||||
TaskDescription td = values[0];
|
TaskDescription td = values[0];
|
||||||
mRecentsPanel.onTaskThumbnailLoaded(td);
|
if (td.isNull()) { // end sentinel
|
||||||
|
mState = State.LOADED;
|
||||||
|
} else {
|
||||||
|
if (mRecentsPanel != null) {
|
||||||
|
mRecentsPanel.onTaskThumbnailLoaded(td);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
@@ -336,19 +454,25 @@ public class RecentTasksLoader {
|
|||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (td.isNull()) {
|
if (td.isNull()) { // end sentinel
|
||||||
|
publishProgress(td);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
loadThumbnailAndIcon(td);
|
loadThumbnailAndIcon(td);
|
||||||
synchronized(td) {
|
|
||||||
publishProgress(td);
|
if (!mFirstTaskLoaded) {
|
||||||
|
mFirstTask = td;
|
||||||
|
mFirstTaskLoaded = true;
|
||||||
}
|
}
|
||||||
|
publishProgress(td);
|
||||||
}
|
}
|
||||||
|
|
||||||
Process.setThreadPriority(origPri);
|
Process.setThreadPriority(origPri);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
mFirstTask = null;
|
||||||
|
mFirstTaskLoaded = false;
|
||||||
mThumbnailLoader.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
mThumbnailLoader.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,176 @@
|
|||||||
|
/*
|
||||||
|
* 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.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 com.android.systemui.R;
|
||||||
|
import com.android.systemui.SystemUIApplication;
|
||||||
|
import com.android.systemui.statusbar.tablet.StatusBarPanel;
|
||||||
|
|
||||||
|
public class RecentsActivity extends Activity {
|
||||||
|
public static final String TOGGLE_RECENTS_INTENT = "com.android.systemui.TOGGLE_RECENTS";
|
||||||
|
public static final String CLOSE_RECENTS_INTENT = "com.android.systemui.CLOSE_RECENTS";
|
||||||
|
|
||||||
|
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 (mRecentsPanel != null && mRecentsPanel.isShowing()) {
|
||||||
|
if (mShowing && !mForeground) {
|
||||||
|
// Captures the case right before we transition to another activity
|
||||||
|
mRecentsPanel.show(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
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() {
|
||||||
|
mForeground = false;
|
||||||
|
super.onPause();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStop() {
|
||||||
|
mShowing = false;
|
||||||
|
if (mRecentsPanel != null) {
|
||||||
|
mRecentsPanel.onUiHidden();
|
||||||
|
}
|
||||||
|
super.onStop();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStart() {
|
||||||
|
mShowing = true;
|
||||||
|
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 SystemUIApplication app = (SystemUIApplication) getApplication();
|
||||||
|
final RecentTasksLoader recentTasksLoader = app.getRecentTasksLoader();
|
||||||
|
TaskDescription firstTask = recentTasksLoader.getFirstTask();
|
||||||
|
if (firstTask != null && mRecentsPanel.simulateClick(firstTask)) {
|
||||||
|
// recents panel will take care of calling show(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mRecentsPanel.show(false);
|
||||||
|
}
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
final SystemUIApplication app = (SystemUIApplication) getApplication();
|
||||||
|
final RecentTasksLoader recentTasksLoader = app.getRecentTasksLoader();
|
||||||
|
|
||||||
|
setContentView(R.layout.status_bar_recent_panel);
|
||||||
|
mRecentsPanel = (RecentsPanelView) findViewById(R.id.recents_root);
|
||||||
|
mRecentsPanel.setOnTouchListener(new TouchOutsideListener(mRecentsPanel));
|
||||||
|
mRecentsPanel.setRecentTasksLoader(recentTasksLoader);
|
||||||
|
recentTasksLoader.setRecentsPanel(mRecentsPanel, mRecentsPanel);
|
||||||
|
|
||||||
|
handleIntent(getIntent());
|
||||||
|
mIntentFilter = new IntentFilter();
|
||||||
|
mIntentFilter.addAction(CLOSE_RECENTS_INTENT);
|
||||||
|
registerReceiver(mIntentReceiver, mIntentFilter);
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onDestroy() {
|
||||||
|
final SystemUIApplication app = (SystemUIApplication) getApplication();
|
||||||
|
final RecentTasksLoader recentTasksLoader = app.getRecentTasksLoader();
|
||||||
|
recentTasksLoader.setRecentsPanel(null, mRecentsPanel);
|
||||||
|
unregisterReceiver(mIntentReceiver);
|
||||||
|
super.onDestroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onNewIntent(Intent intent) {
|
||||||
|
handleIntent(intent);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handleIntent(Intent intent) {
|
||||||
|
super.onNewIntent(intent);
|
||||||
|
|
||||||
|
if (TOGGLE_RECENTS_INTENT.equals(intent.getAction())) {
|
||||||
|
if (mRecentsPanel != null && !mRecentsPanel.isShowing()) {
|
||||||
|
final SystemUIApplication app = (SystemUIApplication) getApplication();
|
||||||
|
final RecentTasksLoader recentTasksLoader = app.getRecentTasksLoader();
|
||||||
|
mRecentsPanel.show(true, recentTasksLoader.getLoadedTasks(),
|
||||||
|
recentTasksLoader.isFirstScreenful());
|
||||||
|
} else if ((mRecentsPanel != null && mRecentsPanel.isShowing())) {
|
||||||
|
dismissAndGoBack();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -76,6 +76,17 @@ public class RecentsHorizontalScrollView extends HorizontalScrollView
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public View findViewForTask(TaskDescription task) {
|
||||||
|
for (int i = 0; i < mLinearLayout.getChildCount(); i++) {
|
||||||
|
View v = mLinearLayout.getChildAt(i);
|
||||||
|
RecentsPanelView.ViewHolder holder = (RecentsPanelView.ViewHolder) v.getTag();
|
||||||
|
if (holder.taskDescription == task) {
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
private void update() {
|
private void update() {
|
||||||
for (int i = 0; i < mLinearLayout.getChildCount(); i++) {
|
for (int i = 0; i < mLinearLayout.getChildCount(); i++) {
|
||||||
View v = mLinearLayout.getChildAt(i);
|
View v = mLinearLayout.getChildAt(i);
|
||||||
|
|||||||
@@ -29,20 +29,17 @@ import android.content.res.Resources;
|
|||||||
import android.content.res.TypedArray;
|
import android.content.res.TypedArray;
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
import android.graphics.Matrix;
|
import android.graphics.Matrix;
|
||||||
import android.graphics.Rect;
|
|
||||||
import android.graphics.Shader.TileMode;
|
import android.graphics.Shader.TileMode;
|
||||||
import android.graphics.drawable.BitmapDrawable;
|
import android.graphics.drawable.BitmapDrawable;
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
import android.os.ServiceManager;
|
|
||||||
import android.os.UserHandle;
|
import android.os.UserHandle;
|
||||||
import android.provider.Settings;
|
import android.provider.Settings;
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.Display;
|
import android.view.Display;
|
||||||
import android.view.KeyEvent;
|
import android.view.KeyEvent;
|
||||||
import android.view.IWindowManager;
|
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
import android.view.MotionEvent;
|
import android.view.MotionEvent;
|
||||||
@@ -71,7 +68,7 @@ import com.android.systemui.statusbar.tablet.TabletStatusBar;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
public class RecentsPanelView extends FrameLayout implements OnItemClickListener, RecentsCallback,
|
public class RecentsPanelView extends FrameLayout implements OnItemClickListener, RecentsCallback,
|
||||||
StatusBarPanel, Animator.AnimatorListener, View.OnTouchListener {
|
StatusBarPanel, Animator.AnimatorListener {
|
||||||
static final String TAG = "RecentsPanelView";
|
static final String TAG = "RecentsPanelView";
|
||||||
static final boolean DEBUG = TabletStatusBar.DEBUG || PhoneStatusBar.DEBUG || false;
|
static final boolean DEBUG = TabletStatusBar.DEBUG || PhoneStatusBar.DEBUG || false;
|
||||||
private Context mContext;
|
private Context mContext;
|
||||||
@@ -84,36 +81,22 @@ public class RecentsPanelView extends FrameLayout implements OnItemClickListener
|
|||||||
|
|
||||||
private boolean mShowing;
|
private boolean mShowing;
|
||||||
private boolean mWaitingToShow;
|
private boolean mWaitingToShow;
|
||||||
private boolean mWaitingToShowAnimated;
|
|
||||||
private boolean mReadyToShow;
|
|
||||||
private int mNumItemsWaitingForThumbnailsAndIcons;
|
private int mNumItemsWaitingForThumbnailsAndIcons;
|
||||||
private Choreographer mChoreo;
|
|
||||||
OnRecentsPanelVisibilityChangedListener mVisibilityChangedListener;
|
|
||||||
|
|
||||||
ImageView mPlaceholderThumbnail;
|
|
||||||
View mTransitionBg;
|
|
||||||
boolean mHideRecentsAfterThumbnailScaleUpStarted;
|
|
||||||
|
|
||||||
private RecentTasksLoader mRecentTasksLoader;
|
private RecentTasksLoader mRecentTasksLoader;
|
||||||
private ArrayList<TaskDescription> mRecentTaskDescriptions;
|
private ArrayList<TaskDescription> mRecentTaskDescriptions;
|
||||||
private Runnable mPreloadTasksRunnable;
|
|
||||||
private boolean mRecentTasksDirty = true;
|
|
||||||
private TaskDescriptionAdapter mListAdapter;
|
private TaskDescriptionAdapter mListAdapter;
|
||||||
private int mThumbnailWidth;
|
private int mThumbnailWidth;
|
||||||
private boolean mFitThumbnailToXY;
|
private boolean mFitThumbnailToXY;
|
||||||
private int mRecentItemLayoutId;
|
private int mRecentItemLayoutId;
|
||||||
private boolean mFirstScreenful = true;
|
|
||||||
private boolean mHighEndGfx;
|
private boolean mHighEndGfx;
|
||||||
|
|
||||||
public static interface OnRecentsPanelVisibilityChangedListener {
|
|
||||||
public void onRecentsPanelVisibilityChanged(boolean visible);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static interface RecentsScrollView {
|
public static interface RecentsScrollView {
|
||||||
public int numItemsInOneScreenful();
|
public int numItemsInOneScreenful();
|
||||||
public void setAdapter(TaskDescriptionAdapter adapter);
|
public void setAdapter(TaskDescriptionAdapter adapter);
|
||||||
public void setCallback(RecentsCallback callback);
|
public void setCallback(RecentsCallback callback);
|
||||||
public void setMinSwipeAlpha(float minAlpha);
|
public void setMinSwipeAlpha(float minAlpha);
|
||||||
|
public View findViewForTask(TaskDescription task);
|
||||||
}
|
}
|
||||||
|
|
||||||
private final class OnLongClickDelegate implements View.OnLongClickListener {
|
private final class OnLongClickDelegate implements View.OnLongClickListener {
|
||||||
@@ -252,15 +235,6 @@ public class RecentsPanelView extends FrameLayout implements OnItemClickListener
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onKeyUp(int keyCode, KeyEvent event) {
|
|
||||||
if (keyCode == KeyEvent.KEYCODE_BACK && !event.isCanceled()) {
|
|
||||||
show(false, false);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return super.onKeyUp(keyCode, event);
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean pointInside(int x, int y, View v) {
|
private boolean pointInside(int x, int y, View v) {
|
||||||
final int l = v.getLeft();
|
final int l = v.getLeft();
|
||||||
final int r = v.getRight();
|
final int r = v.getRight();
|
||||||
@@ -280,22 +254,26 @@ public class RecentsPanelView extends FrameLayout implements OnItemClickListener
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void show(boolean show, boolean animate) {
|
public void show(boolean show) {
|
||||||
|
show(show, null, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void show(boolean show, ArrayList<TaskDescription> recentTaskDescriptions,
|
||||||
|
boolean firstScreenful) {
|
||||||
if (show) {
|
if (show) {
|
||||||
refreshRecentTasksList(null, true);
|
|
||||||
mWaitingToShow = true;
|
mWaitingToShow = true;
|
||||||
mWaitingToShowAnimated = animate;
|
refreshRecentTasksList(recentTaskDescriptions, firstScreenful);
|
||||||
showIfReady();
|
showIfReady();
|
||||||
} else {
|
} else {
|
||||||
show(show, animate, null, false);
|
showImpl(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void showIfReady() {
|
private void showIfReady() {
|
||||||
// mWaitingToShow = there was a touch up on the recents button
|
// mWaitingToShow => there was a touch up on the recents button
|
||||||
// mReadyToShow = we've created views for the first screenful of items
|
// mRecentTaskDescriptions != null => we've created views for the first screenful of items
|
||||||
if (mWaitingToShow && mReadyToShow) { // && mNumItemsWaitingForThumbnailsAndIcons <= 0
|
if (mWaitingToShow && mRecentTaskDescriptions != null) {
|
||||||
show(true, mWaitingToShowAnimated, null, false);
|
showImpl(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -308,79 +286,44 @@ public class RecentsPanelView extends FrameLayout implements OnItemClickListener
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void show(boolean show, boolean animate,
|
private void showImpl(boolean show) {
|
||||||
ArrayList<TaskDescription> recentTaskDescriptions, boolean firstScreenful) {
|
|
||||||
sendCloseSystemWindows(mContext, BaseStatusBar.SYSTEM_DIALOG_REASON_RECENT_APPS);
|
sendCloseSystemWindows(mContext, BaseStatusBar.SYSTEM_DIALOG_REASON_RECENT_APPS);
|
||||||
|
|
||||||
|
mShowing = show;
|
||||||
|
|
||||||
if (show) {
|
if (show) {
|
||||||
// Need to update list of recent apps before we set visibility so this view's
|
// if there are no apps, bring up a "No recent apps" message
|
||||||
// content description is updated before it gets focus for TalkBack mode
|
boolean noApps = mRecentTaskDescriptions != null
|
||||||
refreshRecentTasksList(recentTaskDescriptions, firstScreenful);
|
&& (mRecentTaskDescriptions.size() == 0);
|
||||||
|
mRecentsNoApps.setAlpha(1f);
|
||||||
|
mRecentsNoApps.setVisibility(noApps ? View.VISIBLE : View.INVISIBLE);
|
||||||
|
|
||||||
// if there are no apps, either bring up a "No recent apps" message, or just
|
|
||||||
// quit early
|
|
||||||
boolean noApps = !mFirstScreenful && (mRecentTaskDescriptions.size() == 0);
|
|
||||||
if (mRecentsNoApps != null) {
|
|
||||||
mRecentsNoApps.setAlpha(1f);
|
|
||||||
mRecentsNoApps.setVisibility(noApps ? View.VISIBLE : View.INVISIBLE);
|
|
||||||
} else {
|
|
||||||
if (noApps) {
|
|
||||||
if (DEBUG) Log.v(TAG, "Nothing to show");
|
|
||||||
// Need to set recent tasks to dirty so that next time we load, we
|
|
||||||
// refresh the list of tasks
|
|
||||||
mRecentTasksLoader.cancelLoadingThumbnailsAndIcons();
|
|
||||||
mRecentTasksDirty = true;
|
|
||||||
|
|
||||||
mWaitingToShow = false;
|
|
||||||
mReadyToShow = false;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Need to set recent tasks to dirty so that next time we load, we
|
|
||||||
// refresh the list of tasks
|
|
||||||
mRecentTasksLoader.cancelLoadingThumbnailsAndIcons();
|
|
||||||
mRecentTasksDirty = true;
|
|
||||||
mWaitingToShow = false;
|
|
||||||
mReadyToShow = false;
|
|
||||||
}
|
|
||||||
if (animate) {
|
|
||||||
if (mShowing != show) {
|
|
||||||
mShowing = show;
|
|
||||||
if (show) {
|
|
||||||
setVisibility(View.VISIBLE);
|
|
||||||
}
|
|
||||||
mChoreo.startAnimation(show);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
mShowing = show;
|
|
||||||
setVisibility(show ? View.VISIBLE : View.GONE);
|
|
||||||
mChoreo.jumpTo(show);
|
|
||||||
onAnimationEnd(null);
|
onAnimationEnd(null);
|
||||||
}
|
|
||||||
if (show) {
|
|
||||||
setFocusable(true);
|
setFocusable(true);
|
||||||
setFocusableInTouchMode(true);
|
setFocusableInTouchMode(true);
|
||||||
requestFocus();
|
requestFocus();
|
||||||
} else {
|
} else {
|
||||||
|
mWaitingToShow = false;
|
||||||
|
// call onAnimationEnd() and clearRecentTasksList() in onUiHidden()
|
||||||
if (mPopup != null) {
|
if (mPopup != null) {
|
||||||
mPopup.dismiss();
|
mPopup.dismiss();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void dismiss() {
|
public void onUiHidden() {
|
||||||
hide(true);
|
if (!mShowing && mRecentTaskDescriptions != null) {
|
||||||
|
onAnimationEnd(null);
|
||||||
|
clearRecentTasksList();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void hide(boolean animate) {
|
public void dismiss() {
|
||||||
if (!animate) {
|
((RecentsActivity) mContext).dismissAndGoHome();
|
||||||
setVisibility(View.GONE);
|
}
|
||||||
}
|
|
||||||
if (mBar != null) {
|
public void dismissAndGoBack() {
|
||||||
// This will indirectly cause show(false, ...) to get called
|
((RecentsActivity) mContext).dismissAndGoBack();
|
||||||
mBar.animateCollapse(CommandQueue.FLAG_EXCLUDE_NONE);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onAnimationCancel(Animator animation) {
|
public void onAnimationCancel(Animator animation) {
|
||||||
@@ -393,7 +336,6 @@ public class RecentsPanelView extends FrameLayout implements OnItemClickListener
|
|||||||
createCustomAnimations(transitioner);
|
createCustomAnimations(transitioner);
|
||||||
} else {
|
} else {
|
||||||
((ViewGroup)mRecentsContainer).setLayoutTransition(null);
|
((ViewGroup)mRecentsContainer).setLayoutTransition(null);
|
||||||
clearRecentTasksList();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -403,16 +345,6 @@ public class RecentsPanelView extends FrameLayout implements OnItemClickListener
|
|||||||
public void onAnimationStart(Animator animation) {
|
public void onAnimationStart(Animator animation) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* We need to be aligned at the bottom. LinearLayout can't do this, so instead,
|
|
||||||
* let LinearLayout do all the hard work, and then shift everything down to the bottom.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
protected void onLayout(boolean changed, int l, int t, int r, int b) {
|
|
||||||
super.onLayout(changed, l, t, r, b);
|
|
||||||
mChoreo.setPanelHeight(mRecentsContainer.getHeight());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean dispatchHoverEvent(MotionEvent event) {
|
public boolean dispatchHoverEvent(MotionEvent event) {
|
||||||
// Ignore hover events outside of this panel bounds since such events
|
// Ignore hover events outside of this panel bounds since such events
|
||||||
@@ -449,18 +381,6 @@ public class RecentsPanelView extends FrameLayout implements OnItemClickListener
|
|||||||
mRecentTasksLoader = loader;
|
mRecentTasksLoader = loader;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setOnVisibilityChangedListener(OnRecentsPanelVisibilityChangedListener l) {
|
|
||||||
mVisibilityChangedListener = l;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setVisibility(int visibility) {
|
|
||||||
if (mVisibilityChangedListener != null) {
|
|
||||||
mVisibilityChangedListener.onRecentsPanelVisibilityChanged(visibility == VISIBLE);
|
|
||||||
}
|
|
||||||
super.setVisibility(visibility);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void updateValuesFromResources() {
|
public void updateValuesFromResources() {
|
||||||
final Resources res = mContext.getResources();
|
final Resources res = mContext.getResources();
|
||||||
mThumbnailWidth = Math.round(res.getDimension(R.dimen.status_bar_recents_thumbnail_width));
|
mThumbnailWidth = Math.round(res.getDimension(R.dimen.status_bar_recents_thumbnail_width));
|
||||||
@@ -486,7 +406,6 @@ public class RecentsPanelView extends FrameLayout implements OnItemClickListener
|
|||||||
|
|
||||||
mRecentsScrim = findViewById(R.id.recents_bg_protect);
|
mRecentsScrim = findViewById(R.id.recents_bg_protect);
|
||||||
mRecentsNoApps = findViewById(R.id.recents_no_apps);
|
mRecentsNoApps = findViewById(R.id.recents_no_apps);
|
||||||
mChoreo = new Choreographer(this, mRecentsScrim, mRecentsContainer, mRecentsNoApps, this);
|
|
||||||
|
|
||||||
if (mRecentsScrim != null) {
|
if (mRecentsScrim != null) {
|
||||||
mHighEndGfx = ActivityManager.isHighEndGfx();
|
mHighEndGfx = ActivityManager.isHighEndGfx();
|
||||||
@@ -497,18 +416,6 @@ public class RecentsPanelView extends FrameLayout implements OnItemClickListener
|
|||||||
((BitmapDrawable) mRecentsScrim.getBackground()).setTileModeY(TileMode.REPEAT);
|
((BitmapDrawable) mRecentsScrim.getBackground()).setTileModeY(TileMode.REPEAT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mPreloadTasksRunnable = new Runnable() {
|
|
||||||
public void run() {
|
|
||||||
// If we set our visibility to INVISIBLE here, we avoid an extra call to
|
|
||||||
// onLayout later when we become visible (because onLayout is always called
|
|
||||||
// when going from GONE)
|
|
||||||
if (!mShowing) {
|
|
||||||
setVisibility(INVISIBLE);
|
|
||||||
refreshRecentTasksList();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setMinSwipeAlpha(float minAlpha) {
|
public void setMinSwipeAlpha(float minAlpha) {
|
||||||
@@ -602,44 +509,19 @@ public class RecentsPanelView extends FrameLayout implements OnItemClickListener
|
|||||||
showIfReady();
|
showIfReady();
|
||||||
}
|
}
|
||||||
|
|
||||||
// additional optimization when we have software system buttons - start loading the recent
|
|
||||||
// tasks on touch down
|
|
||||||
@Override
|
|
||||||
public boolean onTouch(View v, MotionEvent ev) {
|
|
||||||
if (!mShowing) {
|
|
||||||
int action = ev.getAction() & MotionEvent.ACTION_MASK;
|
|
||||||
if (action == MotionEvent.ACTION_DOWN) {
|
|
||||||
post(mPreloadTasksRunnable);
|
|
||||||
} else if (action == MotionEvent.ACTION_CANCEL) {
|
|
||||||
setVisibility(GONE);
|
|
||||||
clearRecentTasksList();
|
|
||||||
// Remove the preloader if we haven't called it yet
|
|
||||||
removeCallbacks(mPreloadTasksRunnable);
|
|
||||||
} else if (action == MotionEvent.ACTION_UP) {
|
|
||||||
// Remove the preloader if we haven't called it yet
|
|
||||||
removeCallbacks(mPreloadTasksRunnable);
|
|
||||||
if (!v.isPressed()) {
|
|
||||||
setVisibility(GONE);
|
|
||||||
clearRecentTasksList();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void preloadRecentTasksList() {
|
|
||||||
if (!mShowing) {
|
|
||||||
mPreloadTasksRunnable.run();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void clearRecentTasksList() {
|
public void clearRecentTasksList() {
|
||||||
// Clear memory used by screenshots
|
// Clear memory used by screenshots
|
||||||
if (!mShowing && mRecentTaskDescriptions != null) {
|
if (mRecentTaskDescriptions != null) {
|
||||||
mRecentTasksLoader.cancelLoadingThumbnailsAndIcons();
|
mRecentTasksLoader.cancelLoadingThumbnailsAndIcons(this);
|
||||||
mRecentTaskDescriptions.clear();
|
onTaskLoadingCancelled();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onTaskLoadingCancelled() {
|
||||||
|
// Gets called by RecentTasksLoader when it's cancelled
|
||||||
|
if (mRecentTaskDescriptions != null) {
|
||||||
|
mRecentTaskDescriptions = null;
|
||||||
mListAdapter.notifyDataSetInvalidated();
|
mListAdapter.notifyDataSetInvalidated();
|
||||||
mRecentTasksDirty = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -649,23 +531,15 @@ public class RecentsPanelView extends FrameLayout implements OnItemClickListener
|
|||||||
|
|
||||||
private void refreshRecentTasksList(
|
private void refreshRecentTasksList(
|
||||||
ArrayList<TaskDescription> recentTasksList, boolean firstScreenful) {
|
ArrayList<TaskDescription> recentTasksList, boolean firstScreenful) {
|
||||||
if (mRecentTasksDirty) {
|
if (mRecentTaskDescriptions == null && recentTasksList != null) {
|
||||||
if (recentTasksList != null) {
|
onTasksLoaded(recentTasksList, firstScreenful);
|
||||||
mFirstScreenful = true;
|
} else {
|
||||||
onTasksLoaded(recentTasksList);
|
mRecentTasksLoader.loadTasksInBackground();
|
||||||
} else {
|
|
||||||
mFirstScreenful = true;
|
|
||||||
mRecentTasksLoader.loadTasksInBackground();
|
|
||||||
}
|
|
||||||
mRecentTasksDirty = false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onTasksLoaded(ArrayList<TaskDescription> tasks) {
|
public void onTasksLoaded(ArrayList<TaskDescription> tasks, boolean firstScreenful) {
|
||||||
if (!mFirstScreenful && tasks.size() == 0) {
|
mNumItemsWaitingForThumbnailsAndIcons = firstScreenful
|
||||||
return;
|
|
||||||
}
|
|
||||||
mNumItemsWaitingForThumbnailsAndIcons = mFirstScreenful
|
|
||||||
? tasks.size() : mRecentTaskDescriptions == null
|
? tasks.size() : mRecentTaskDescriptions == null
|
||||||
? 0 : mRecentTaskDescriptions.size();
|
? 0 : mRecentTaskDescriptions.size();
|
||||||
if (mRecentTaskDescriptions == null) {
|
if (mRecentTaskDescriptions == null) {
|
||||||
@@ -675,19 +549,9 @@ public class RecentsPanelView extends FrameLayout implements OnItemClickListener
|
|||||||
}
|
}
|
||||||
mListAdapter.notifyDataSetInvalidated();
|
mListAdapter.notifyDataSetInvalidated();
|
||||||
updateUiElements(getResources().getConfiguration());
|
updateUiElements(getResources().getConfiguration());
|
||||||
mReadyToShow = true;
|
|
||||||
mFirstScreenful = false;
|
|
||||||
showIfReady();
|
showIfReady();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ArrayList<TaskDescription> getRecentTasksList() {
|
|
||||||
return mRecentTaskDescriptions;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean getFirstScreenful() {
|
|
||||||
return mFirstScreenful;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateUiElements(Configuration config) {
|
private void updateUiElements(Configuration config) {
|
||||||
final int items = mRecentTaskDescriptions.size();
|
final int items = mRecentTaskDescriptions.size();
|
||||||
|
|
||||||
@@ -706,8 +570,19 @@ public class RecentsPanelView extends FrameLayout implements OnItemClickListener
|
|||||||
setContentDescription(recentAppsAccessibilityDescription);
|
setContentDescription(recentAppsAccessibilityDescription);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean simulateClick(TaskDescription task) {
|
||||||
|
if (mRecentsContainer instanceof RecentsScrollView){
|
||||||
|
RecentsScrollView scrollView
|
||||||
|
= (RecentsScrollView) mRecentsContainer;
|
||||||
|
View v = scrollView.findViewForTask(task);
|
||||||
|
if (v != null) {
|
||||||
|
handleOnClick(v);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
boolean mThumbnailScaleUpStarted;
|
|
||||||
public void handleOnClick(View view) {
|
public void handleOnClick(View view) {
|
||||||
ViewHolder holder = (ViewHolder)view.getTag();
|
ViewHolder holder = (ViewHolder)view.getTag();
|
||||||
TaskDescription ad = holder.taskDescription;
|
TaskDescription ad = holder.taskDescription;
|
||||||
@@ -725,59 +600,10 @@ public class RecentsPanelView extends FrameLayout implements OnItemClickListener
|
|||||||
usingDrawingCache = true;
|
usingDrawingCache = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mPlaceholderThumbnail == null) {
|
|
||||||
mPlaceholderThumbnail =
|
|
||||||
(ImageView) findViewById(R.id.recents_transition_placeholder_icon);
|
|
||||||
}
|
|
||||||
if (mTransitionBg == null) {
|
|
||||||
mTransitionBg = (View) findViewById(R.id.recents_transition_background);
|
|
||||||
|
|
||||||
IWindowManager wm = WindowManagerGlobal.getWindowManagerService();
|
|
||||||
try {
|
|
||||||
if (!wm.hasSystemNavBar()) {
|
|
||||||
FrameLayout.LayoutParams lp =
|
|
||||||
(FrameLayout.LayoutParams) mTransitionBg.getLayoutParams();
|
|
||||||
int statusBarHeight = getResources().
|
|
||||||
getDimensionPixelSize(com.android.internal.R.dimen.status_bar_height);
|
|
||||||
lp.setMargins(0, statusBarHeight, 0, 0);
|
|
||||||
mTransitionBg.setLayoutParams(lp);
|
|
||||||
}
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
Log.w(TAG, "Failing checking whether status bar is visible", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
final ImageView placeholderThumbnail = mPlaceholderThumbnail;
|
|
||||||
mHideRecentsAfterThumbnailScaleUpStarted = false;
|
|
||||||
placeholderThumbnail.setVisibility(VISIBLE);
|
|
||||||
if (!usingDrawingCache) {
|
|
||||||
placeholderThumbnail.setImageBitmap(bm);
|
|
||||||
} else {
|
|
||||||
Bitmap b2 = bm.copy(bm.getConfig(), true);
|
|
||||||
placeholderThumbnail.setImageBitmap(b2);
|
|
||||||
}
|
|
||||||
Rect r = new Rect();
|
|
||||||
holder.thumbnailViewImage.getGlobalVisibleRect(r);
|
|
||||||
|
|
||||||
placeholderThumbnail.setTranslationX(r.left);
|
|
||||||
placeholderThumbnail.setTranslationY(r.top);
|
|
||||||
|
|
||||||
show(false, true);
|
|
||||||
|
|
||||||
mThumbnailScaleUpStarted = false;
|
|
||||||
ActivityOptions opts = ActivityOptions.makeThumbnailScaleUpAnimation(
|
ActivityOptions opts = ActivityOptions.makeThumbnailScaleUpAnimation(
|
||||||
holder.thumbnailViewImage, bm, 0, 0,
|
holder.thumbnailViewImage, bm, 0, 0, null);
|
||||||
new ActivityOptions.OnAnimationStartedListener() {
|
|
||||||
@Override public void onAnimationStarted() {
|
show(false);
|
||||||
mThumbnailScaleUpStarted = true;
|
|
||||||
if (!mHighEndGfx) {
|
|
||||||
mPlaceholderThumbnail.setVisibility(INVISIBLE);
|
|
||||||
}
|
|
||||||
if (mHideRecentsAfterThumbnailScaleUpStarted) {
|
|
||||||
hideWindow();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
if (ad.taskId >= 0) {
|
if (ad.taskId >= 0) {
|
||||||
// This is an active task; it should just go to the foreground.
|
// This is an active task; it should just go to the foreground.
|
||||||
am.moveTaskToFront(ad.taskId, ActivityManager.MOVE_TASK_WITH_HOME,
|
am.moveTaskToFront(ad.taskId, ActivityManager.MOVE_TASK_WITH_HOME,
|
||||||
@@ -796,17 +622,6 @@ public class RecentsPanelView extends FrameLayout implements OnItemClickListener
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void hideWindow() {
|
|
||||||
if (!mThumbnailScaleUpStarted) {
|
|
||||||
mHideRecentsAfterThumbnailScaleUpStarted = true;
|
|
||||||
} else {
|
|
||||||
setVisibility(GONE);
|
|
||||||
mTransitionBg.setVisibility(INVISIBLE);
|
|
||||||
mPlaceholderThumbnail.setVisibility(INVISIBLE);
|
|
||||||
mHideRecentsAfterThumbnailScaleUpStarted = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
|
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
|
||||||
handleOnClick(view);
|
handleOnClick(view);
|
||||||
}
|
}
|
||||||
@@ -825,7 +640,7 @@ public class RecentsPanelView extends FrameLayout implements OnItemClickListener
|
|||||||
// mListAdapter.notifyDataSetChanged();
|
// mListAdapter.notifyDataSetChanged();
|
||||||
|
|
||||||
if (mRecentTaskDescriptions.size() == 0) {
|
if (mRecentTaskDescriptions.size() == 0) {
|
||||||
hide(false);
|
dismissAndGoBack();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Currently, either direction means the same thing, so ignore direction and remove
|
// Currently, either direction means the same thing, so ignore direction and remove
|
||||||
@@ -875,7 +690,7 @@ public class RecentsPanelView extends FrameLayout implements OnItemClickListener
|
|||||||
if (viewHolder != null) {
|
if (viewHolder != null) {
|
||||||
final TaskDescription ad = viewHolder.taskDescription;
|
final TaskDescription ad = viewHolder.taskDescription;
|
||||||
startApplicationDetailsActivity(ad.packageName);
|
startApplicationDetailsActivity(ad.packageName);
|
||||||
mBar.animateCollapse(CommandQueue.FLAG_EXCLUDE_NONE);
|
show(false);
|
||||||
} else {
|
} else {
|
||||||
throw new IllegalStateException("Oops, no tag on view " + selectedView);
|
throw new IllegalStateException("Oops, no tag on view " + selectedView);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -77,6 +77,17 @@ public class RecentsVerticalScrollView extends ScrollView
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public View findViewForTask(TaskDescription task) {
|
||||||
|
for (int i = 0; i < mLinearLayout.getChildCount(); i++) {
|
||||||
|
View v = mLinearLayout.getChildAt(i);
|
||||||
|
RecentsPanelView.ViewHolder holder = (RecentsPanelView.ViewHolder) v.getTag();
|
||||||
|
if (holder.taskDescription == task) {
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
private void update() {
|
private void update() {
|
||||||
for (int i = 0; i < mLinearLayout.getChildCount(); i++) {
|
for (int i = 0; i < mLinearLayout.getChildCount(); i++) {
|
||||||
View v = mLinearLayout.getChildAt(i);
|
View v = mLinearLayout.getChildAt(i);
|
||||||
@@ -146,7 +157,9 @@ public class RecentsVerticalScrollView extends ScrollView
|
|||||||
appTitle.setContentDescription(" ");
|
appTitle.setContentDescription(" ");
|
||||||
appTitle.setOnTouchListener(noOpListener);
|
appTitle.setOnTouchListener(noOpListener);
|
||||||
final View calloutLine = view.findViewById(R.id.recents_callout_line);
|
final View calloutLine = view.findViewById(R.id.recents_callout_line);
|
||||||
calloutLine.setOnTouchListener(noOpListener);
|
if (calloutLine != null) {
|
||||||
|
calloutLine.setOnTouchListener(noOpListener);
|
||||||
|
}
|
||||||
|
|
||||||
mLinearLayout.addView(view);
|
mLinearLayout.addView(view);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2010 The Android Open Source Project
|
* Copyright (C) 2010 The Android Open Source Project
|
||||||
*
|
*
|
||||||
@@ -24,23 +25,31 @@ import com.android.internal.widget.SizeAdaptiveLayout;
|
|||||||
import com.android.systemui.R;
|
import com.android.systemui.R;
|
||||||
import com.android.systemui.SearchPanelView;
|
import com.android.systemui.SearchPanelView;
|
||||||
import com.android.systemui.SystemUI;
|
import com.android.systemui.SystemUI;
|
||||||
|
import com.android.systemui.SystemUIApplication;
|
||||||
import com.android.systemui.recent.RecentTasksLoader;
|
import com.android.systemui.recent.RecentTasksLoader;
|
||||||
import com.android.systemui.recent.RecentsPanelView;
|
import com.android.systemui.recent.RecentsActivity;
|
||||||
import com.android.systemui.recent.TaskDescription;
|
import com.android.systemui.recent.TaskDescription;
|
||||||
import com.android.systemui.statusbar.policy.NotificationRowLayout;
|
import com.android.systemui.statusbar.policy.NotificationRowLayout;
|
||||||
import com.android.systemui.statusbar.tablet.StatusBarPanel;
|
import com.android.systemui.statusbar.tablet.StatusBarPanel;
|
||||||
|
|
||||||
import android.app.ActivityManagerNative;
|
import android.app.ActivityManagerNative;
|
||||||
|
import android.app.ActivityOptions;
|
||||||
import android.app.KeyguardManager;
|
import android.app.KeyguardManager;
|
||||||
import android.app.PendingIntent;
|
import android.app.PendingIntent;
|
||||||
|
import android.app.Service;
|
||||||
import android.app.TaskStackBuilder;
|
import android.app.TaskStackBuilder;
|
||||||
|
import android.content.ActivityNotFoundException;
|
||||||
import android.content.BroadcastReceiver;
|
import android.content.BroadcastReceiver;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.IntentFilter;
|
import android.content.IntentFilter;
|
||||||
import android.content.pm.ApplicationInfo;
|
import android.content.pm.ApplicationInfo;
|
||||||
import android.content.pm.PackageManager.NameNotFoundException;
|
import android.content.pm.PackageManager.NameNotFoundException;
|
||||||
|
import android.content.res.Configuration;
|
||||||
|
import android.content.res.Resources;
|
||||||
import android.database.ContentObserver;
|
import android.database.ContentObserver;
|
||||||
|
import android.graphics.Bitmap;
|
||||||
|
import android.graphics.Paint;
|
||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
@@ -52,6 +61,7 @@ import android.os.ServiceManager;
|
|||||||
import android.os.UserHandle;
|
import android.os.UserHandle;
|
||||||
import android.provider.Settings;
|
import android.provider.Settings;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
|
import android.util.DisplayMetrics;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.util.Slog;
|
import android.util.Slog;
|
||||||
import android.view.Display;
|
import android.view.Display;
|
||||||
@@ -73,12 +83,12 @@ import android.widget.TextView;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
public abstract class BaseStatusBar extends SystemUI implements
|
public abstract class BaseStatusBar extends SystemUI implements
|
||||||
CommandQueue.Callbacks, RecentsPanelView.OnRecentsPanelVisibilityChangedListener {
|
CommandQueue.Callbacks {
|
||||||
static final String TAG = "StatusBar";
|
static final String TAG = "StatusBar";
|
||||||
private static final boolean DEBUG = false;
|
private static final boolean DEBUG = false;
|
||||||
public static final boolean MULTIUSER_DEBUG = false;
|
public static final boolean MULTIUSER_DEBUG = false;
|
||||||
|
|
||||||
protected static final int MSG_OPEN_RECENTS_PANEL = 1020;
|
protected static final int MSG_TOGGLE_RECENTS_PANEL = 1020;
|
||||||
protected static final int MSG_CLOSE_RECENTS_PANEL = 1021;
|
protected static final int MSG_CLOSE_RECENTS_PANEL = 1021;
|
||||||
protected static final int MSG_PRELOAD_RECENT_APPS = 1022;
|
protected static final int MSG_PRELOAD_RECENT_APPS = 1022;
|
||||||
protected static final int MSG_CANCEL_PRELOAD_RECENT_APPS = 1023;
|
protected static final int MSG_CANCEL_PRELOAD_RECENT_APPS = 1023;
|
||||||
@@ -111,10 +121,6 @@ public abstract class BaseStatusBar extends SystemUI implements
|
|||||||
// Search panel
|
// Search panel
|
||||||
protected SearchPanelView mSearchPanelView;
|
protected SearchPanelView mSearchPanelView;
|
||||||
|
|
||||||
// Recent apps
|
|
||||||
protected RecentsPanelView mRecentsPanel;
|
|
||||||
protected RecentTasksLoader mRecentTasksLoader;
|
|
||||||
|
|
||||||
protected PopupMenu mNotificationBlamePopup;
|
protected PopupMenu mNotificationBlamePopup;
|
||||||
|
|
||||||
protected int mCurrentUserId = 0;
|
protected int mCurrentUserId = 0;
|
||||||
@@ -377,8 +383,7 @@ public abstract class BaseStatusBar extends SystemUI implements
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void toggleRecentApps() {
|
public void toggleRecentApps() {
|
||||||
int msg = (mRecentsPanel.getVisibility() == View.VISIBLE)
|
int msg = MSG_TOGGLE_RECENTS_PANEL;
|
||||||
? MSG_CLOSE_RECENTS_PANEL : MSG_OPEN_RECENTS_PANEL;
|
|
||||||
mHandler.removeMessages(msg);
|
mHandler.removeMessages(msg);
|
||||||
mHandler.sendEmptyMessage(msg);
|
mHandler.sendEmptyMessage(msg);
|
||||||
}
|
}
|
||||||
@@ -411,49 +416,15 @@ public abstract class BaseStatusBar extends SystemUI implements
|
|||||||
mHandler.sendEmptyMessage(msg);
|
mHandler.sendEmptyMessage(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onRecentsPanelVisibilityChanged(boolean visible) {
|
|
||||||
}
|
|
||||||
|
|
||||||
protected abstract WindowManager.LayoutParams getRecentsLayoutParams(
|
protected abstract WindowManager.LayoutParams getRecentsLayoutParams(
|
||||||
LayoutParams layoutParams);
|
LayoutParams layoutParams);
|
||||||
|
|
||||||
protected abstract WindowManager.LayoutParams getSearchLayoutParams(
|
protected abstract WindowManager.LayoutParams getSearchLayoutParams(
|
||||||
LayoutParams layoutParams);
|
LayoutParams layoutParams);
|
||||||
|
|
||||||
protected void updateRecentsPanel(int recentsResId) {
|
protected RecentTasksLoader getRecentTasksLoader() {
|
||||||
// Recents Panel
|
final SystemUIApplication app = (SystemUIApplication) ((Service) mContext).getApplication();
|
||||||
boolean visible = false;
|
return app.getRecentTasksLoader();
|
||||||
ArrayList<TaskDescription> recentTasksList = null;
|
|
||||||
boolean firstScreenful = false;
|
|
||||||
if (mRecentsPanel != null) {
|
|
||||||
visible = mRecentsPanel.isShowing();
|
|
||||||
mWindowManager.removeView(mRecentsPanel);
|
|
||||||
if (visible) {
|
|
||||||
recentTasksList = mRecentsPanel.getRecentTasksList();
|
|
||||||
firstScreenful = mRecentsPanel.getFirstScreenful();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Provide RecentsPanelView with a temporary parent to allow layout params to work.
|
|
||||||
LinearLayout tmpRoot = new LinearLayout(mContext);
|
|
||||||
mRecentsPanel = (RecentsPanelView) LayoutInflater.from(mContext).inflate(
|
|
||||||
recentsResId, tmpRoot, false);
|
|
||||||
mRecentsPanel.setRecentTasksLoader(mRecentTasksLoader);
|
|
||||||
mRecentTasksLoader.setRecentsPanel(mRecentsPanel);
|
|
||||||
mRecentsPanel.setOnTouchListener(
|
|
||||||
new TouchOutsideListener(MSG_CLOSE_RECENTS_PANEL, mRecentsPanel));
|
|
||||||
mRecentsPanel.setVisibility(View.GONE);
|
|
||||||
|
|
||||||
|
|
||||||
WindowManager.LayoutParams lp = getRecentsLayoutParams(mRecentsPanel.getLayoutParams());
|
|
||||||
|
|
||||||
mWindowManager.addView(mRecentsPanel, lp);
|
|
||||||
mRecentsPanel.setBar(this);
|
|
||||||
if (visible) {
|
|
||||||
mRecentsPanel.show(true, false, recentTasksList, firstScreenful);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void updateSearchPanel() {
|
protected void updateSearchPanel() {
|
||||||
@@ -494,28 +465,148 @@ public abstract class BaseStatusBar extends SystemUI implements
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected abstract View getStatusBarView();
|
||||||
|
|
||||||
|
protected void toggleRecentsActivity() {
|
||||||
|
try {
|
||||||
|
final RecentTasksLoader recentTasksLoader = getRecentTasksLoader();
|
||||||
|
TaskDescription firstTask = recentTasksLoader.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) {
|
||||||
|
mContext.startActivityAsUser(intent, new UserHandle(UserHandle.USER_CURRENT));
|
||||||
|
} else {
|
||||||
|
Bitmap first = firstTask.getThumbnail();
|
||||||
|
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.getWidth() != thumbWidth || first.getHeight() != thumbHeight) {
|
||||||
|
first = Bitmap.createScaledBitmap(first, (int) thumbWidth, (int) thumbHeight,
|
||||||
|
true);
|
||||||
|
}
|
||||||
|
|
||||||
|
DisplayMetrics dm = new DisplayMetrics();
|
||||||
|
mDisplay.getMetrics(dm);
|
||||||
|
// calculate it here, but consider moving it elsewhere
|
||||||
|
// first, determine which orientation you're in.
|
||||||
|
// todo: move the system_bar layouts to sw600dp ?
|
||||||
|
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);
|
||||||
|
} 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(labelTextSize);
|
||||||
|
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(
|
||||||
|
getStatusBarView(),
|
||||||
|
first, x, y,
|
||||||
|
null);
|
||||||
|
mContext.startActivityAsUser(intent, opts.toBundle(), new UserHandle(
|
||||||
|
UserHandle.USER_CURRENT));
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
} catch (ActivityNotFoundException e) {
|
||||||
|
Log.e(TAG, "Failed to launch RecentAppsIntent", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected class H extends Handler {
|
protected class H extends Handler {
|
||||||
public void handleMessage(Message m) {
|
public void handleMessage(Message m) {
|
||||||
switch (m.what) {
|
switch (m.what) {
|
||||||
case MSG_OPEN_RECENTS_PANEL:
|
case MSG_TOGGLE_RECENTS_PANEL:
|
||||||
if (DEBUG) Slog.d(TAG, "opening recents panel");
|
if (DEBUG) Slog.d(TAG, "toggle recents panel");
|
||||||
if (mRecentsPanel != null) {
|
toggleRecentsActivity();
|
||||||
mRecentsPanel.show(true, false);
|
break;
|
||||||
}
|
|
||||||
break;
|
|
||||||
case MSG_CLOSE_RECENTS_PANEL:
|
case MSG_CLOSE_RECENTS_PANEL:
|
||||||
if (DEBUG) Slog.d(TAG, "closing recents panel");
|
if (DEBUG) Slog.d(TAG, "closing recents panel");
|
||||||
if (mRecentsPanel != null && mRecentsPanel.isShowing()) {
|
Intent intent = new Intent(RecentsActivity.CLOSE_RECENTS_INTENT);
|
||||||
mRecentsPanel.show(false, false);
|
intent.setPackage("com.android.systemui");
|
||||||
}
|
mContext.sendBroadcastAsUser(intent, new UserHandle(UserHandle.USER_CURRENT));
|
||||||
break;
|
break;
|
||||||
case MSG_PRELOAD_RECENT_APPS:
|
case MSG_PRELOAD_RECENT_APPS:
|
||||||
if (DEBUG) Slog.d(TAG, "preloading recents");
|
if (DEBUG) Slog.d(TAG, "preloading recents");
|
||||||
mRecentsPanel.preloadRecentTasksList();
|
{
|
||||||
|
// TODO:
|
||||||
|
// need to implement this
|
||||||
|
//final RecentsPanelView recentsPanel = getRecentsPanel();
|
||||||
|
//if (recentsPanel != null) {
|
||||||
|
//recentsPanel.preloadRecentTasksList();
|
||||||
|
//}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case MSG_CANCEL_PRELOAD_RECENT_APPS:
|
case MSG_CANCEL_PRELOAD_RECENT_APPS:
|
||||||
if (DEBUG) Slog.d(TAG, "cancel preloading recents");
|
if (DEBUG) Slog.d(TAG, "cancel preloading recents");
|
||||||
mRecentsPanel.clearRecentTasksList();
|
{
|
||||||
|
// TODO:
|
||||||
|
// need to implement this
|
||||||
|
//final RecentsPanelView recentsPanel = getRecentsPanel();
|
||||||
|
//if (recentsPanel != null) {
|
||||||
|
//recentsPanel.clearRecentTasksList();
|
||||||
|
//}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case MSG_OPEN_SEARCH_PANEL:
|
case MSG_OPEN_SEARCH_PANEL:
|
||||||
if (DEBUG) Slog.d(TAG, "opening search panel");
|
if (DEBUG) Slog.d(TAG, "opening search panel");
|
||||||
@@ -559,8 +650,6 @@ public abstract class BaseStatusBar extends SystemUI implements
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected boolean inflateViews(NotificationData.Entry entry, ViewGroup parent) {
|
protected boolean inflateViews(NotificationData.Entry entry, ViewGroup parent) {
|
||||||
int rowHeight =
|
|
||||||
mContext.getResources().getDimensionPixelSize(R.dimen.notification_row_min_height);
|
|
||||||
int minHeight =
|
int minHeight =
|
||||||
mContext.getResources().getDimensionPixelSize(R.dimen.notification_min_height);
|
mContext.getResources().getDimensionPixelSize(R.dimen.notification_min_height);
|
||||||
int maxHeight =
|
int maxHeight =
|
||||||
@@ -605,7 +694,6 @@ public abstract class BaseStatusBar extends SystemUI implements
|
|||||||
// TODO(cwren) normalize variable names with those in updateNotification
|
// TODO(cwren) normalize variable names with those in updateNotification
|
||||||
View expandedOneU = null;
|
View expandedOneU = null;
|
||||||
View expandedLarge = null;
|
View expandedLarge = null;
|
||||||
Exception exception = null;
|
|
||||||
try {
|
try {
|
||||||
expandedOneU = oneU.apply(mContext, adaptive, mOnClickHandler);
|
expandedOneU = oneU.apply(mContext, adaptive, mOnClickHandler);
|
||||||
if (large != null) {
|
if (large != null) {
|
||||||
|
|||||||
@@ -445,9 +445,6 @@ public class PhoneStatusBar extends BaseStatusBar {
|
|||||||
// if (wimaxRSSI != null) {
|
// if (wimaxRSSI != null) {
|
||||||
// mNetworkController.addWimaxIconView(wimaxRSSI);
|
// mNetworkController.addWimaxIconView(wimaxRSSI);
|
||||||
// }
|
// }
|
||||||
// Recents Panel
|
|
||||||
mRecentTasksLoader = new RecentTasksLoader(context);
|
|
||||||
updateRecentsPanel();
|
|
||||||
|
|
||||||
// receive broadcasts
|
// receive broadcasts
|
||||||
IntentFilter filter = new IntentFilter();
|
IntentFilter filter = new IntentFilter();
|
||||||
@@ -459,6 +456,11 @@ public class PhoneStatusBar extends BaseStatusBar {
|
|||||||
return mStatusBarView;
|
return mStatusBarView;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected View getStatusBarView() {
|
||||||
|
return mStatusBarView;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected WindowManager.LayoutParams getRecentsLayoutParams(LayoutParams layoutParams) {
|
protected WindowManager.LayoutParams getRecentsLayoutParams(LayoutParams layoutParams) {
|
||||||
boolean opaque = false;
|
boolean opaque = false;
|
||||||
@@ -507,6 +509,7 @@ public class PhoneStatusBar extends BaseStatusBar {
|
|||||||
return lp;
|
return lp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
protected void updateRecentsPanel() {
|
protected void updateRecentsPanel() {
|
||||||
super.updateRecentsPanel(R.layout.status_bar_recent_panel);
|
super.updateRecentsPanel(R.layout.status_bar_recent_panel);
|
||||||
// Make .03 alpha the minimum so you always see the item a bit-- slightly below
|
// Make .03 alpha the minimum so you always see the item a bit-- slightly below
|
||||||
@@ -517,6 +520,7 @@ public class PhoneStatusBar extends BaseStatusBar {
|
|||||||
mNavigationBarView.getRecentsButton().setOnTouchListener(mRecentsPanel);
|
mNavigationBarView.getRecentsButton().setOnTouchListener(mRecentsPanel);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void updateSearchPanel() {
|
protected void updateSearchPanel() {
|
||||||
@@ -604,7 +608,7 @@ public class PhoneStatusBar extends BaseStatusBar {
|
|||||||
mNavigationBarView.reorient();
|
mNavigationBarView.reorient();
|
||||||
|
|
||||||
mNavigationBarView.getRecentsButton().setOnClickListener(mRecentsClickListener);
|
mNavigationBarView.getRecentsButton().setOnClickListener(mRecentsClickListener);
|
||||||
mNavigationBarView.getRecentsButton().setOnTouchListener(mRecentsPanel);
|
mNavigationBarView.getRecentsButton().setOnTouchListener(getRecentTasksLoader());
|
||||||
mNavigationBarView.getHomeButton().setOnTouchListener(mHomeSearchActionListener);
|
mNavigationBarView.getHomeButton().setOnTouchListener(mHomeSearchActionListener);
|
||||||
updateSearchPanel();
|
updateSearchPanel();
|
||||||
}
|
}
|
||||||
@@ -785,7 +789,6 @@ public class PhoneStatusBar extends BaseStatusBar {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onConfigurationChanged(Configuration newConfig) {
|
protected void onConfigurationChanged(Configuration newConfig) {
|
||||||
updateRecentsPanel();
|
|
||||||
updateShowSearchHoldoff();
|
updateShowSearchHoldoff();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -84,8 +84,7 @@ import java.io.PrintWriter;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
public class TabletStatusBar extends BaseStatusBar implements
|
public class TabletStatusBar extends BaseStatusBar implements
|
||||||
InputMethodsPanel.OnHardKeyboardEnabledChangeListener,
|
InputMethodsPanel.OnHardKeyboardEnabledChangeListener {
|
||||||
RecentsPanelView.OnRecentsPanelVisibilityChangedListener {
|
|
||||||
public static final boolean DEBUG = false;
|
public static final boolean DEBUG = false;
|
||||||
public static final boolean DEBUG_COMPAT_HELP = false;
|
public static final boolean DEBUG_COMPAT_HELP = false;
|
||||||
public static final String TAG = "TabletStatusBar";
|
public static final String TAG = "TabletStatusBar";
|
||||||
@@ -305,10 +304,6 @@ public class TabletStatusBar extends BaseStatusBar implements
|
|||||||
|
|
||||||
mWindowManager.addView(mNotificationPanel, lp);
|
mWindowManager.addView(mNotificationPanel, lp);
|
||||||
|
|
||||||
// Recents Panel
|
|
||||||
mRecentTasksLoader = new RecentTasksLoader(context);
|
|
||||||
updateRecentsPanel();
|
|
||||||
|
|
||||||
// Search Panel
|
// Search Panel
|
||||||
mStatusBarView.setBar(this);
|
mStatusBarView.setBar(this);
|
||||||
mHomeButton.setOnTouchListener(mHomeSearchActionListener);
|
mHomeButton.setOnTouchListener(mHomeSearchActionListener);
|
||||||
@@ -360,7 +355,7 @@ public class TabletStatusBar extends BaseStatusBar implements
|
|||||||
|
|
||||||
mWindowManager.addView(mCompatModePanel, lp);
|
mWindowManager.addView(mCompatModePanel, lp);
|
||||||
|
|
||||||
mRecentButton.setOnTouchListener(mRecentsPanel);
|
//mRecentButton.setOnTouchListener(mRecentsPanel); //TODO: plumb this
|
||||||
|
|
||||||
mPile = (NotificationRowLayout)mNotificationPanel.findViewById(R.id.content);
|
mPile = (NotificationRowLayout)mNotificationPanel.findViewById(R.id.content);
|
||||||
mPile.removeAllViews();
|
mPile.removeAllViews();
|
||||||
@@ -393,7 +388,6 @@ public class TabletStatusBar extends BaseStatusBar implements
|
|||||||
loadDimens();
|
loadDimens();
|
||||||
mNotificationPanelParams.height = getNotificationPanelHeight();
|
mNotificationPanelParams.height = getNotificationPanelHeight();
|
||||||
mWindowManager.updateViewLayout(mNotificationPanel, mNotificationPanelParams);
|
mWindowManager.updateViewLayout(mNotificationPanel, mNotificationPanelParams);
|
||||||
mRecentsPanel.updateValuesFromResources();
|
|
||||||
mShowSearchHoldoff = mContext.getResources().getInteger(
|
mShowSearchHoldoff = mContext.getResources().getInteger(
|
||||||
R.integer.config_show_search_delay);
|
R.integer.config_show_search_delay);
|
||||||
updateSearchPanel();
|
updateSearchPanel();
|
||||||
@@ -445,6 +439,7 @@ public class TabletStatusBar extends BaseStatusBar implements
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public View getStatusBarView() {
|
public View getStatusBarView() {
|
||||||
return mStatusBarView;
|
return mStatusBarView;
|
||||||
}
|
}
|
||||||
@@ -656,11 +651,6 @@ public class TabletStatusBar extends BaseStatusBar implements
|
|||||||
return lp;
|
return lp;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void updateRecentsPanel() {
|
|
||||||
super.updateRecentsPanel(R.layout.system_bar_recent_panel);
|
|
||||||
mRecentsPanel.setStatusBarView(mStatusBarView);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void updateSearchPanel() {
|
protected void updateSearchPanel() {
|
||||||
super.updateSearchPanel();
|
super.updateSearchPanel();
|
||||||
@@ -1182,14 +1172,6 @@ public class TabletStatusBar extends BaseStatusBar implements
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onRecentsPanelVisibilityChanged(boolean visible) {
|
|
||||||
boolean altBack = visible || mAltBackButtonEnabledForIme;
|
|
||||||
mCommandQueue.setNavigationIconHints(
|
|
||||||
altBack ? (mNavigationIconHints | StatusBarManager.NAVIGATION_HINT_BACK_ALT)
|
|
||||||
: (mNavigationIconHints & ~StatusBarManager.NAVIGATION_HINT_BACK_ALT));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setHardKeyboardStatus(boolean available, boolean enabled) {
|
public void setHardKeyboardStatus(boolean available, boolean enabled) {
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
@@ -1241,10 +1223,7 @@ public class TabletStatusBar extends BaseStatusBar implements
|
|||||||
public void onClickRecentButton() {
|
public void onClickRecentButton() {
|
||||||
if (DEBUG) Slog.d(TAG, "clicked recent apps; disabled=" + mDisabled);
|
if (DEBUG) Slog.d(TAG, "clicked recent apps; disabled=" + mDisabled);
|
||||||
if ((mDisabled & StatusBarManager.DISABLE_EXPAND) == 0) {
|
if ((mDisabled & StatusBarManager.DISABLE_EXPAND) == 0) {
|
||||||
int msg = (mRecentsPanel.getVisibility() == View.VISIBLE)
|
toggleRecentApps();
|
||||||
? MSG_CLOSE_RECENTS_PANEL : MSG_OPEN_RECENTS_PANEL;
|
|
||||||
mHandler.removeMessages(msg);
|
|
||||||
mHandler.sendEmptyMessage(msg);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1523,14 +1502,6 @@ public class TabletStatusBar extends BaseStatusBar implements
|
|||||||
flags |= CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL;
|
flags |= CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (Intent.ACTION_SCREEN_OFF.equals(action)) {
|
|
||||||
// If we're turning the screen off, we want to hide the
|
|
||||||
// recents panel with no animation
|
|
||||||
// TODO: hide other things, like the notification tray,
|
|
||||||
// with no animation as well
|
|
||||||
mRecentsPanel.show(false, false);
|
|
||||||
flags |= CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL;
|
|
||||||
}
|
|
||||||
animateCollapse(flags);
|
animateCollapse(flags);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -148,6 +148,10 @@ public class TvStatusBar extends BaseStatusBar {
|
|||||||
return mView;
|
return mView;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public View getStatusBarView() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
protected int getStatusBarGravity() {
|
protected int getStatusBarGravity() {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user