Loading packages/SystemUI/res/layout/navigation_bar_with_apps.xml +5 −69 Original line number Diff line number Diff line Loading @@ -91,42 +91,10 @@ android:src="@drawable/nav_app_divider" /> <!-- TODO: Build the list of icons dynamically. --> <com.android.systemui.statusbar.phone.NavigationBarRecents android:layout_width="wrap_content" android:layout_height="match_parent" > <ImageView android:id="@+id/recent0" android:layout_width="48dp" android:layout_height="48dp" android:layout_marginLeft="8dp" android:layout_marginRight="8dp" android:padding="6dp" android:layout_gravity="center" android:scaleType="centerInside" android:visibility="invisible" /> <ImageView android:id="@+id/recent1" android:layout_width="48dp" android:layout_height="48dp" android:layout_marginLeft="8dp" android:layout_marginRight="8dp" android:padding="6dp" android:layout_gravity="center" android:scaleType="centerInside" android:visibility="invisible" /> <ImageView android:id="@+id/recent2" android:layout_width="48dp" android:layout_height="48dp" android:layout_marginLeft="8dp" android:layout_marginRight="8dp" android:padding="6dp" android:layout_gravity="center" android:scaleType="centerInside" android:visibility="invisible" /> </com.android.systemui.statusbar.phone.NavigationBarRecents> </LinearLayout> <FrameLayout Loading Loading @@ -287,42 +255,10 @@ android:src="@drawable/nav_app_divider" /> <!-- TODO: Build the list of icons dynamically. --> <com.android.systemui.statusbar.phone.NavigationBarRecents android:layout_width="wrap_content" android:layout_height="match_parent" > <ImageView android:id="@+id/recent0" android:layout_width="48dp" android:layout_height="48dp" android:layout_marginLeft="8dp" android:layout_marginRight="8dp" android:padding="6dp" android:layout_gravity="center" android:scaleType="centerInside" android:visibility="invisible" /> <ImageView android:id="@+id/recent1" android:layout_width="48dp" android:layout_height="48dp" android:layout_marginLeft="8dp" android:layout_marginRight="8dp" android:padding="6dp" android:layout_gravity="center" android:scaleType="centerInside" android:visibility="invisible" /> <ImageView android:id="@+id/recent2" android:layout_width="48dp" android:layout_height="48dp" android:layout_marginLeft="8dp" android:layout_marginRight="8dp" android:padding="6dp" android:layout_gravity="center" android:scaleType="centerInside" android:visibility="invisible" /> </com.android.systemui.statusbar.phone.NavigationBarRecents> </LinearLayout> <FrameLayout Loading packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarApps.java +19 −11 Original line number Diff line number Diff line Loading @@ -29,7 +29,7 @@ import android.graphics.Rect; import android.os.Bundle; import android.os.UserHandle; import android.util.AttributeSet; import android.util.Log; import android.util.Slog; import android.view.DragEvent; import android.view.LayoutInflater; import android.view.View; Loading Loading @@ -111,19 +111,27 @@ class NavigationBarApps extends LinearLayout { return button; } // Not shared with NavigationBarRecents because the data model is specific to pinned apps. private class AppLongClickListener implements View.OnLongClickListener { @Override public boolean onLongClick(View v) { mDragView = v; ImageView icon = (ImageView) v; ComponentName activityName = mAppsModel.getApp(indexOfChild(v)); startAppDrag(icon, activityName); return true; } } /** Helper function to start dragging an app icon (either pinned or recent). */ static void startAppDrag(ImageView icon, ComponentName activityName) { // The drag data is an Intent to launch the activity. Intent mainIntent = Intent.makeMainActivity(activityName); ClipData dragData = ClipData.newIntent("", mainIntent); // Use the ImageView to create the shadow. View.DragShadowBuilder shadow = new AppIconDragShadowBuilder((ImageView) v); v.startDrag(dragData, shadow, null /* myLocalState */, 0 /* flags */); return true; } View.DragShadowBuilder shadow = new AppIconDragShadowBuilder(icon); // Use a global drag because the icon might be dragged into the launcher. icon.startDrag(dragData, shadow, null /* myLocalState */, View.DRAG_FLAG_GLOBAL); } @Override Loading Loading @@ -161,7 +169,7 @@ class NavigationBarApps extends LinearLayout { * an app shortcut and will be accepted for a drop. */ private boolean onDragStarted(DragEvent event) { if (DEBUG) Log.d(TAG, "onDragStarted"); if (DEBUG) Slog.d(TAG, "onDragStarted"); // Ensure that an app shortcut is being dragged. if (!canAcceptDrag(event)) { Loading Loading @@ -194,7 +202,7 @@ class NavigationBarApps extends LinearLayout { * needs to use LinearLayout/ViewGroup methods. */ private void onDragEnteredIcon(View target) { if (DEBUG) Log.d(TAG, "onDragEntered " + indexOfChild(target)); if (DEBUG) Slog.d(TAG, "onDragEntered " + indexOfChild(target)); // If the drag didn't start from an existing icon, add an invisible placeholder to create // empty space for the user to drag into. Loading Loading @@ -227,7 +235,7 @@ class NavigationBarApps extends LinearLayout { } private boolean onDrop(DragEvent event) { if (DEBUG) Log.d(TAG, "onDrop"); if (DEBUG) Slog.d(TAG, "onDrop"); int dragViewIndex = indexOfChild(mDragView); if (mAppsModel.getApp(dragViewIndex) == null) { Loading Loading @@ -285,7 +293,7 @@ class NavigationBarApps extends LinearLayout { /** Cleans up at the end of the drag. */ private boolean onDragEnded() { if (DEBUG) Log.d(TAG, "onDragEnded"); if (DEBUG) Slog.d(TAG, "onDragEnded"); if (mDragView != null) { // The icon wasn't dropped into the app list. Remove the placeholder. Loading packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarRecents.java +85 −49 Original line number Diff line number Diff line Loading @@ -20,7 +20,6 @@ import android.app.ActivityManager; import android.app.ActivityManagerNative; import android.app.IActivityManager; import android.app.ITaskStackListener; import android.content.ClipData; import android.content.ComponentName; import android.content.Context; import android.content.Intent; Loading @@ -28,7 +27,10 @@ import android.content.pm.PackageManager; import android.os.Handler; import android.os.RemoteException; import android.os.UserHandle; import android.util.ArraySet; import android.util.AttributeSet; import android.util.Slog; import android.view.LayoutInflater; import android.view.View; import android.widget.ImageView; import android.widget.LinearLayout; Loading @@ -36,6 +38,7 @@ import android.widget.LinearLayout; import com.android.systemui.R; import java.util.List; import java.util.Set; /** * Recent task icons appearing in the navigation bar. Touching an icon brings the activity to the Loading @@ -43,21 +46,31 @@ import java.util.List; * icons. */ class NavigationBarRecents extends LinearLayout { private final static boolean DEBUG = false; private final static String TAG = "NavigationBarRecents"; private final static int[] RECENT_APP_BUTTON_IDS = { R.id.recent0, R.id.recent1, R.id.recent2 }; // Maximum number of icons to show. // TODO: Implement an overflow UI so the shelf can display an unlimited number of recents. private final static int MAX_RECENTS = 10; private final ActivityManager mActivityManager; private final PackageManager mPackageManager; private final LayoutInflater mLayoutInflater; private final TaskStackListenerImpl mTaskStackListener; // Recent tasks being displayed in the shelf. private final Set<ComponentName> mCurrentTasks = new ArraySet<ComponentName>(MAX_RECENTS); public NavigationBarRecents(Context context, AttributeSet attrs) { super(context, attrs); mActivityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); mPackageManager = getContext().getPackageManager(); mLayoutInflater = LayoutInflater.from(context); // Listen for task stack changes and refresh when they happen. Update notifications happen // on an IPC thread, so use Handler to handle the message on the main thread. // TODO: This has too much latency. It only adds the icon when app launch is completed // and the launch animation is done playing. This class should add the icon immediately // when the launch starts. Handler handler = new Handler(); mTaskStackListener = new TaskStackListenerImpl(handler); IActivityManager iam = ActivityManagerNative.getDefault(); Loading @@ -68,54 +81,86 @@ class NavigationBarRecents extends LinearLayout { } } @Override protected void onFinishInflate() { super.onFinishInflate(); // Set up the buttons. for (int i = 0; i < RECENT_APP_BUTTON_IDS.length; i++) { ImageView button = getRecentAppButton(i); button.setOnLongClickListener(AppLongClickListener.getInstance()); } // TODO: When is the right time to do the initial update? updateRecentApps(); } private ImageView getRecentAppButton(int index) { return (ImageView) findViewById(RECENT_APP_BUTTON_IDS[index]); } private void updateRecentApps() { // TODO: Should this be getRunningTasks? List<ActivityManager.RecentTaskInfo> tasks = mActivityManager.getRecentTasksForUser( RECENT_APP_BUTTON_IDS.length, // TODO: Query other UserHandles? List<ActivityManager.RecentTaskInfo> recentTasks = mActivityManager.getRecentTasksForUser( MAX_RECENTS, ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS | ActivityManager.RECENT_IGNORE_UNAVAILABLE | ActivityManager.RECENT_INCLUDE_PROFILES | ActivityManager.RECENT_WITH_EXCLUDED, UserHandle.USER_CURRENT); // Show the recent icons with the oldest on the left. int buttonIndex = 0; int taskIndex = tasks.size() - 1; while (taskIndex >= 0 && buttonIndex < RECENT_APP_BUTTON_IDS.length) { updateRecentAppButton(getRecentAppButton(buttonIndex), tasks.get(taskIndex)); taskIndex--; buttonIndex++; if (DEBUG) Slog.d(TAG, "Got recents " + recentTasks.size()); removeMissingRecents(recentTasks); addNewRecents(recentTasks); } // Remove any icons that disappeared from recents. private void removeMissingRecents(List<ActivityManager.RecentTaskInfo> recentTasks) { // Extract the component names. Set<ComponentName> recentComponents = new ArraySet<ComponentName>(recentTasks.size()); for (ActivityManager.RecentTaskInfo task : recentTasks) { ComponentName component = task.baseIntent.getComponent(); if (component == null) { // It's unclear if this can happen in practice. continue; } recentComponents.add(component); } // Hide the unused buttons. while (buttonIndex < RECENT_APP_BUTTON_IDS.length) { hideButton(getRecentAppButton(buttonIndex)); buttonIndex++; // Start with a copy of the currently displayed tasks. Set<ComponentName> removed = new ArraySet<ComponentName>(mCurrentTasks); // Remove all the entries that still exist in recents. removed.removeAll(recentComponents); // The remaining entries no longer exist in recents, so remove their icons. for (ComponentName task : removed) { removeIcon(task); } } private void updateRecentAppButton(ImageView button, ActivityManager.RecentTaskInfo task) { ComponentName component = task.baseIntent.getComponent(); if (component == null) { hideButton(button); // Removes the icon for a task. private void removeIcon(ComponentName task) { for (int i = 0; i < getChildCount(); i++) { ComponentName childTask = (ComponentName) getChildAt(i).getTag(); if (childTask.equals(task)) { if (DEBUG) Slog.d(TAG, "removing missing " + task); removeViewAt(i); mCurrentTasks.remove(task); return; } } } // Adds new tasks at the end of the icon list. private void addNewRecents(List<ActivityManager.RecentTaskInfo> recentTasks) { for (ActivityManager.RecentTaskInfo task : recentTasks) { // Don't overflow the list. if (getChildCount() >= MAX_RECENTS) { return; } ComponentName component = task.baseIntent.getComponent(); if (component == null) { // It's unclear if this can happen in practice. continue; } // Don't add tasks that are already being shown. if (mCurrentTasks.contains(component)) { continue; } addRecentAppButton(task); } } // Adds an icon at the end of the list to represent an activity for a given component. private void addRecentAppButton(ActivityManager.RecentTaskInfo task) { // Add this task to the currently-shown set. ComponentName component = task.baseIntent.getComponent(); mCurrentTasks.add(component); if (DEBUG) Slog.d(TAG, "adding " + component); ImageView button = (ImageView) mLayoutInflater.inflate( R.layout.navigation_bar_app_item, this, false /* attachToRoot */); button.setOnLongClickListener(AppLongClickListener.getInstance()); addView(button); // Use the View's tag to store metadata for drag and drop. button.setTag(component); Loading @@ -134,11 +179,6 @@ class NavigationBarRecents extends LinearLayout { }); } private void hideButton(ImageView button) { button.setImageDrawable(null); button.setVisibility(View.GONE); } /** * A listener that updates the app buttons whenever the recents task stack changes. * NOTE: This is not the right way to do this. Loading Loading @@ -173,13 +213,9 @@ class NavigationBarRecents extends LinearLayout { @Override public boolean onLongClick(View v) { ImageView icon = (ImageView) v; ComponentName activityName = (ComponentName) v.getTag(); // The drag data is an Intent to launch the activity. Intent mainIntent = Intent.makeMainActivity(activityName); ClipData dragData = ClipData.newIntent("", mainIntent); // Use the ImageView to create the shadow. View.DragShadowBuilder shadow = new AppIconDragShadowBuilder((ImageView) v); v.startDrag(dragData, shadow, null /* myLocalState */, 0 /* flags */); NavigationBarApps.startAppDrag(icon, activityName); return true; } } Loading services/core/java/com/android/server/am/ActivityManagerService.java +1 −1 Original line number Diff line number Diff line Loading @@ -391,7 +391,7 @@ public final class ActivityManagerService extends ActivityManagerNative static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000; // Delay in notifying task stack change listeners (in millis) static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 1000; static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 100; // Necessary ApplicationInfo flags to mark an app as persistent private static final int PERSISTENT_MASK = Loading Loading
packages/SystemUI/res/layout/navigation_bar_with_apps.xml +5 −69 Original line number Diff line number Diff line Loading @@ -91,42 +91,10 @@ android:src="@drawable/nav_app_divider" /> <!-- TODO: Build the list of icons dynamically. --> <com.android.systemui.statusbar.phone.NavigationBarRecents android:layout_width="wrap_content" android:layout_height="match_parent" > <ImageView android:id="@+id/recent0" android:layout_width="48dp" android:layout_height="48dp" android:layout_marginLeft="8dp" android:layout_marginRight="8dp" android:padding="6dp" android:layout_gravity="center" android:scaleType="centerInside" android:visibility="invisible" /> <ImageView android:id="@+id/recent1" android:layout_width="48dp" android:layout_height="48dp" android:layout_marginLeft="8dp" android:layout_marginRight="8dp" android:padding="6dp" android:layout_gravity="center" android:scaleType="centerInside" android:visibility="invisible" /> <ImageView android:id="@+id/recent2" android:layout_width="48dp" android:layout_height="48dp" android:layout_marginLeft="8dp" android:layout_marginRight="8dp" android:padding="6dp" android:layout_gravity="center" android:scaleType="centerInside" android:visibility="invisible" /> </com.android.systemui.statusbar.phone.NavigationBarRecents> </LinearLayout> <FrameLayout Loading Loading @@ -287,42 +255,10 @@ android:src="@drawable/nav_app_divider" /> <!-- TODO: Build the list of icons dynamically. --> <com.android.systemui.statusbar.phone.NavigationBarRecents android:layout_width="wrap_content" android:layout_height="match_parent" > <ImageView android:id="@+id/recent0" android:layout_width="48dp" android:layout_height="48dp" android:layout_marginLeft="8dp" android:layout_marginRight="8dp" android:padding="6dp" android:layout_gravity="center" android:scaleType="centerInside" android:visibility="invisible" /> <ImageView android:id="@+id/recent1" android:layout_width="48dp" android:layout_height="48dp" android:layout_marginLeft="8dp" android:layout_marginRight="8dp" android:padding="6dp" android:layout_gravity="center" android:scaleType="centerInside" android:visibility="invisible" /> <ImageView android:id="@+id/recent2" android:layout_width="48dp" android:layout_height="48dp" android:layout_marginLeft="8dp" android:layout_marginRight="8dp" android:padding="6dp" android:layout_gravity="center" android:scaleType="centerInside" android:visibility="invisible" /> </com.android.systemui.statusbar.phone.NavigationBarRecents> </LinearLayout> <FrameLayout Loading
packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarApps.java +19 −11 Original line number Diff line number Diff line Loading @@ -29,7 +29,7 @@ import android.graphics.Rect; import android.os.Bundle; import android.os.UserHandle; import android.util.AttributeSet; import android.util.Log; import android.util.Slog; import android.view.DragEvent; import android.view.LayoutInflater; import android.view.View; Loading Loading @@ -111,19 +111,27 @@ class NavigationBarApps extends LinearLayout { return button; } // Not shared with NavigationBarRecents because the data model is specific to pinned apps. private class AppLongClickListener implements View.OnLongClickListener { @Override public boolean onLongClick(View v) { mDragView = v; ImageView icon = (ImageView) v; ComponentName activityName = mAppsModel.getApp(indexOfChild(v)); startAppDrag(icon, activityName); return true; } } /** Helper function to start dragging an app icon (either pinned or recent). */ static void startAppDrag(ImageView icon, ComponentName activityName) { // The drag data is an Intent to launch the activity. Intent mainIntent = Intent.makeMainActivity(activityName); ClipData dragData = ClipData.newIntent("", mainIntent); // Use the ImageView to create the shadow. View.DragShadowBuilder shadow = new AppIconDragShadowBuilder((ImageView) v); v.startDrag(dragData, shadow, null /* myLocalState */, 0 /* flags */); return true; } View.DragShadowBuilder shadow = new AppIconDragShadowBuilder(icon); // Use a global drag because the icon might be dragged into the launcher. icon.startDrag(dragData, shadow, null /* myLocalState */, View.DRAG_FLAG_GLOBAL); } @Override Loading Loading @@ -161,7 +169,7 @@ class NavigationBarApps extends LinearLayout { * an app shortcut and will be accepted for a drop. */ private boolean onDragStarted(DragEvent event) { if (DEBUG) Log.d(TAG, "onDragStarted"); if (DEBUG) Slog.d(TAG, "onDragStarted"); // Ensure that an app shortcut is being dragged. if (!canAcceptDrag(event)) { Loading Loading @@ -194,7 +202,7 @@ class NavigationBarApps extends LinearLayout { * needs to use LinearLayout/ViewGroup methods. */ private void onDragEnteredIcon(View target) { if (DEBUG) Log.d(TAG, "onDragEntered " + indexOfChild(target)); if (DEBUG) Slog.d(TAG, "onDragEntered " + indexOfChild(target)); // If the drag didn't start from an existing icon, add an invisible placeholder to create // empty space for the user to drag into. Loading Loading @@ -227,7 +235,7 @@ class NavigationBarApps extends LinearLayout { } private boolean onDrop(DragEvent event) { if (DEBUG) Log.d(TAG, "onDrop"); if (DEBUG) Slog.d(TAG, "onDrop"); int dragViewIndex = indexOfChild(mDragView); if (mAppsModel.getApp(dragViewIndex) == null) { Loading Loading @@ -285,7 +293,7 @@ class NavigationBarApps extends LinearLayout { /** Cleans up at the end of the drag. */ private boolean onDragEnded() { if (DEBUG) Log.d(TAG, "onDragEnded"); if (DEBUG) Slog.d(TAG, "onDragEnded"); if (mDragView != null) { // The icon wasn't dropped into the app list. Remove the placeholder. Loading
packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarRecents.java +85 −49 Original line number Diff line number Diff line Loading @@ -20,7 +20,6 @@ import android.app.ActivityManager; import android.app.ActivityManagerNative; import android.app.IActivityManager; import android.app.ITaskStackListener; import android.content.ClipData; import android.content.ComponentName; import android.content.Context; import android.content.Intent; Loading @@ -28,7 +27,10 @@ import android.content.pm.PackageManager; import android.os.Handler; import android.os.RemoteException; import android.os.UserHandle; import android.util.ArraySet; import android.util.AttributeSet; import android.util.Slog; import android.view.LayoutInflater; import android.view.View; import android.widget.ImageView; import android.widget.LinearLayout; Loading @@ -36,6 +38,7 @@ import android.widget.LinearLayout; import com.android.systemui.R; import java.util.List; import java.util.Set; /** * Recent task icons appearing in the navigation bar. Touching an icon brings the activity to the Loading @@ -43,21 +46,31 @@ import java.util.List; * icons. */ class NavigationBarRecents extends LinearLayout { private final static boolean DEBUG = false; private final static String TAG = "NavigationBarRecents"; private final static int[] RECENT_APP_BUTTON_IDS = { R.id.recent0, R.id.recent1, R.id.recent2 }; // Maximum number of icons to show. // TODO: Implement an overflow UI so the shelf can display an unlimited number of recents. private final static int MAX_RECENTS = 10; private final ActivityManager mActivityManager; private final PackageManager mPackageManager; private final LayoutInflater mLayoutInflater; private final TaskStackListenerImpl mTaskStackListener; // Recent tasks being displayed in the shelf. private final Set<ComponentName> mCurrentTasks = new ArraySet<ComponentName>(MAX_RECENTS); public NavigationBarRecents(Context context, AttributeSet attrs) { super(context, attrs); mActivityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); mPackageManager = getContext().getPackageManager(); mLayoutInflater = LayoutInflater.from(context); // Listen for task stack changes and refresh when they happen. Update notifications happen // on an IPC thread, so use Handler to handle the message on the main thread. // TODO: This has too much latency. It only adds the icon when app launch is completed // and the launch animation is done playing. This class should add the icon immediately // when the launch starts. Handler handler = new Handler(); mTaskStackListener = new TaskStackListenerImpl(handler); IActivityManager iam = ActivityManagerNative.getDefault(); Loading @@ -68,54 +81,86 @@ class NavigationBarRecents extends LinearLayout { } } @Override protected void onFinishInflate() { super.onFinishInflate(); // Set up the buttons. for (int i = 0; i < RECENT_APP_BUTTON_IDS.length; i++) { ImageView button = getRecentAppButton(i); button.setOnLongClickListener(AppLongClickListener.getInstance()); } // TODO: When is the right time to do the initial update? updateRecentApps(); } private ImageView getRecentAppButton(int index) { return (ImageView) findViewById(RECENT_APP_BUTTON_IDS[index]); } private void updateRecentApps() { // TODO: Should this be getRunningTasks? List<ActivityManager.RecentTaskInfo> tasks = mActivityManager.getRecentTasksForUser( RECENT_APP_BUTTON_IDS.length, // TODO: Query other UserHandles? List<ActivityManager.RecentTaskInfo> recentTasks = mActivityManager.getRecentTasksForUser( MAX_RECENTS, ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS | ActivityManager.RECENT_IGNORE_UNAVAILABLE | ActivityManager.RECENT_INCLUDE_PROFILES | ActivityManager.RECENT_WITH_EXCLUDED, UserHandle.USER_CURRENT); // Show the recent icons with the oldest on the left. int buttonIndex = 0; int taskIndex = tasks.size() - 1; while (taskIndex >= 0 && buttonIndex < RECENT_APP_BUTTON_IDS.length) { updateRecentAppButton(getRecentAppButton(buttonIndex), tasks.get(taskIndex)); taskIndex--; buttonIndex++; if (DEBUG) Slog.d(TAG, "Got recents " + recentTasks.size()); removeMissingRecents(recentTasks); addNewRecents(recentTasks); } // Remove any icons that disappeared from recents. private void removeMissingRecents(List<ActivityManager.RecentTaskInfo> recentTasks) { // Extract the component names. Set<ComponentName> recentComponents = new ArraySet<ComponentName>(recentTasks.size()); for (ActivityManager.RecentTaskInfo task : recentTasks) { ComponentName component = task.baseIntent.getComponent(); if (component == null) { // It's unclear if this can happen in practice. continue; } recentComponents.add(component); } // Hide the unused buttons. while (buttonIndex < RECENT_APP_BUTTON_IDS.length) { hideButton(getRecentAppButton(buttonIndex)); buttonIndex++; // Start with a copy of the currently displayed tasks. Set<ComponentName> removed = new ArraySet<ComponentName>(mCurrentTasks); // Remove all the entries that still exist in recents. removed.removeAll(recentComponents); // The remaining entries no longer exist in recents, so remove their icons. for (ComponentName task : removed) { removeIcon(task); } } private void updateRecentAppButton(ImageView button, ActivityManager.RecentTaskInfo task) { ComponentName component = task.baseIntent.getComponent(); if (component == null) { hideButton(button); // Removes the icon for a task. private void removeIcon(ComponentName task) { for (int i = 0; i < getChildCount(); i++) { ComponentName childTask = (ComponentName) getChildAt(i).getTag(); if (childTask.equals(task)) { if (DEBUG) Slog.d(TAG, "removing missing " + task); removeViewAt(i); mCurrentTasks.remove(task); return; } } } // Adds new tasks at the end of the icon list. private void addNewRecents(List<ActivityManager.RecentTaskInfo> recentTasks) { for (ActivityManager.RecentTaskInfo task : recentTasks) { // Don't overflow the list. if (getChildCount() >= MAX_RECENTS) { return; } ComponentName component = task.baseIntent.getComponent(); if (component == null) { // It's unclear if this can happen in practice. continue; } // Don't add tasks that are already being shown. if (mCurrentTasks.contains(component)) { continue; } addRecentAppButton(task); } } // Adds an icon at the end of the list to represent an activity for a given component. private void addRecentAppButton(ActivityManager.RecentTaskInfo task) { // Add this task to the currently-shown set. ComponentName component = task.baseIntent.getComponent(); mCurrentTasks.add(component); if (DEBUG) Slog.d(TAG, "adding " + component); ImageView button = (ImageView) mLayoutInflater.inflate( R.layout.navigation_bar_app_item, this, false /* attachToRoot */); button.setOnLongClickListener(AppLongClickListener.getInstance()); addView(button); // Use the View's tag to store metadata for drag and drop. button.setTag(component); Loading @@ -134,11 +179,6 @@ class NavigationBarRecents extends LinearLayout { }); } private void hideButton(ImageView button) { button.setImageDrawable(null); button.setVisibility(View.GONE); } /** * A listener that updates the app buttons whenever the recents task stack changes. * NOTE: This is not the right way to do this. Loading Loading @@ -173,13 +213,9 @@ class NavigationBarRecents extends LinearLayout { @Override public boolean onLongClick(View v) { ImageView icon = (ImageView) v; ComponentName activityName = (ComponentName) v.getTag(); // The drag data is an Intent to launch the activity. Intent mainIntent = Intent.makeMainActivity(activityName); ClipData dragData = ClipData.newIntent("", mainIntent); // Use the ImageView to create the shadow. View.DragShadowBuilder shadow = new AppIconDragShadowBuilder((ImageView) v); v.startDrag(dragData, shadow, null /* myLocalState */, 0 /* flags */); NavigationBarApps.startAppDrag(icon, activityName); return true; } } Loading
services/core/java/com/android/server/am/ActivityManagerService.java +1 −1 Original line number Diff line number Diff line Loading @@ -391,7 +391,7 @@ public final class ActivityManagerService extends ActivityManagerNative static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000; // Delay in notifying task stack change listeners (in millis) static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 1000; static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 100; // Necessary ApplicationInfo flags to mark an app as persistent private static final int PERSISTENT_MASK = Loading