Merge "Recents: apps scale down to thumbnails now" into jb-mr1-dev

This commit is contained in:
Michael Jurka
2012-08-23 04:57:54 -07:00
committed by Android (Google) Code Review
16 changed files with 637 additions and 611 deletions

View File

@@ -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"

View File

@@ -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"

View File

@@ -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"

View File

@@ -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"

View File

@@ -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>

View File

@@ -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;
}
}

View File

@@ -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) {
}
}

View File

@@ -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);
} }
} }

View File

@@ -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();
}
}
}
}

View File

@@ -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);

View File

@@ -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);
} }

View File

@@ -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);
} }

View File

@@ -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) {

View File

@@ -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();
} }

View File

@@ -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);
} }
} }

View File

@@ -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;
} }