Loading packages/SystemUI/src/com/android/systemui/recent/Recents.java +15 −319 Original line number Diff line number Diff line Loading @@ -16,142 +16,54 @@ package com.android.systemui.recent; import android.app.ActivityManager; import android.app.ActivityOptions; import android.content.ActivityNotFoundException; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; import android.content.pm.ActivityInfo; import android.content.pm.PackageManager; import android.content.res.Configuration; import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Matrix; import android.graphics.Paint; import android.graphics.Rect; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.os.Bundle; import android.os.Handler; import android.os.IBinder; import android.os.Message; import android.os.Messenger; import android.os.RemoteException; import android.os.SystemProperties; import android.os.UserHandle; import android.util.DisplayMetrics; import android.util.Log; import android.view.Display; import android.view.Surface; import android.view.SurfaceControl; import android.view.View; import android.view.WindowManager; import com.android.systemui.R; import com.android.systemui.RecentsComponent; import com.android.systemui.SystemUI; import java.util.List; import com.android.systemui.recents.AlternateRecentsComponent; public class Recents extends SystemUI implements RecentsComponent { /** A handler for messages from the recents implementation */ class RecentsMessageHandler extends Handler { @Override public void handleMessage(Message msg) { if (!mUseAlternateRecents) return; if (msg.what == MSG_UPDATE_FOR_CONFIGURATION) { Resources res = mContext.getResources(); float statusBarHeight = res.getDimensionPixelSize( com.android.internal.R.dimen.status_bar_height); mFirstTaskRect = (Rect) msg.getData().getParcelable("taskRect"); mFirstTaskRect.offset(0, (int) statusBarHeight); } } } /** A service connection to the recents implementation */ class RecentsServiceConnection implements ServiceConnection { @Override public void onServiceConnected(ComponentName className, IBinder service) { if (!mUseAlternateRecents) return; Log.d(TAG, "[RecentsComponent|ServiceConnection|onServiceConnected] toggleRecents: " + mToggleRecentsUponServiceBound); mService = new Messenger(service); mServiceIsBound = true; // Toggle recents if this service connection was triggered by hitting the recents button if (mToggleRecentsUponServiceBound) { startAlternateRecentsActivity(); } mToggleRecentsUponServiceBound = false; } @Override public void onServiceDisconnected(ComponentName className) { if (!mUseAlternateRecents) return; Log.d(TAG, "[RecentsComponent|ServiceConnection|onServiceDisconnected]"); mService = null; mServiceIsBound = false; } } private static final String TAG = "Recents"; private static final boolean DEBUG = true; final static int MSG_UPDATE_FOR_CONFIGURATION = 0; final static int MSG_UPDATE_TASK_THUMBNAIL = 1; final static int MSG_PRELOAD_TASKS = 2; final static int MSG_CANCEL_PRELOAD_TASKS = 3; final static int MSG_CLOSE_RECENTS = 4; final static int MSG_TOGGLE_RECENTS = 5; final static String sToggleRecentsAction = "com.android.systemui.recents.SHOW_RECENTS"; final static String sRecentsPackage = "com.android.systemui"; final static String sRecentsActivity = "com.android.systemui.recents.RecentsActivity"; final static String sRecentsService = "com.android.systemui.recents.RecentsService"; // Which recents to use boolean mUseAlternateRecents; // Recents service binding Messenger mService = null; Messenger mMessenger; boolean mServiceIsBound = false; boolean mToggleRecentsUponServiceBound; RecentsServiceConnection mConnection = new RecentsServiceConnection(); View mStatusBarView; Rect mFirstTaskRect = new Rect(); public Recents() { mMessenger = new Messenger(new RecentsMessageHandler()); } AlternateRecentsComponent mAlternateRecents; @Override public void start() { mUseAlternateRecents = SystemProperties.getBoolean("persist.recents.use_alternate", false); putComponent(RecentsComponent.class, this); mUseAlternateRecents = SystemProperties.getBoolean("persist.recents.use_alternate", false); if (mUseAlternateRecents) { Log.d(TAG, "[RecentsComponent|start]"); // Try to create a long-running connection to the recents service bindToRecentsService(false); if (mAlternateRecents == null) { mAlternateRecents = new AlternateRecentsComponent(mContext); } mAlternateRecents.onStart(); } putComponent(RecentsComponent.class, this); } @Override public void toggleRecents(Display display, int layoutDirection, View statusBarView) { if (mUseAlternateRecents) { // Launch the alternate recents if required toggleAlternateRecents(display, layoutDirection, statusBarView); mAlternateRecents.onToggleRecents(display, layoutDirection, statusBarView); return; } Loading Loading @@ -298,222 +210,17 @@ public class Recents extends SystemUI implements RecentsComponent { } } /** Toggles the alternate recents activity */ public void toggleAlternateRecents(Display display, int layoutDirection, View statusBarView) { if (!mUseAlternateRecents) return; Log.d(TAG, "[RecentsComponent|toggleRecents] serviceIsBound: " + mServiceIsBound); mStatusBarView = statusBarView; if (!mServiceIsBound) { // Try to create a long-running connection to the recents service before toggling // recents bindToRecentsService(true); return; } try { startAlternateRecentsActivity(); } catch (ActivityNotFoundException e) { Log.e(TAG, "Failed to launch RecentAppsIntent", e); } } @Override protected void onConfigurationChanged(Configuration newConfig) { if (mServiceIsBound) { Resources res = mContext.getResources(); int statusBarHeight = res.getDimensionPixelSize( com.android.internal.R.dimen.status_bar_height); int navBarHeight = res.getDimensionPixelSize( com.android.internal.R.dimen.navigation_bar_height); Rect rect = new Rect(); WindowManager wm = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE); wm.getDefaultDisplay().getRectSize(rect); // Try and update the recents configuration try { Bundle data = new Bundle(); data.putParcelable("windowRect", rect); data.putParcelable("systemInsets", new Rect(0, statusBarHeight, 0, 0)); Message msg = Message.obtain(null, MSG_UPDATE_FOR_CONFIGURATION, 0, 0); msg.setData(data); msg.replyTo = mMessenger; mService.send(msg); } catch (RemoteException re) { re.printStackTrace(); } } } /** Binds to the recents implementation */ private void bindToRecentsService(boolean toggleRecentsUponConnection) { if (!mUseAlternateRecents) return; mToggleRecentsUponServiceBound = toggleRecentsUponConnection; Intent intent = new Intent(); intent.setClassName(sRecentsPackage, sRecentsService); mContext.bindService(intent, mConnection, Context.BIND_AUTO_CREATE); } /** Loads the first task thumbnail */ Bitmap loadFirstTaskThumbnail() { ActivityManager am = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE); List<ActivityManager.RecentTaskInfo> tasks = am.getRecentTasksForUser(1, ActivityManager.RECENT_IGNORE_UNAVAILABLE | ActivityManager.RECENT_INCLUDE_RELATED, UserHandle.CURRENT.getIdentifier()); for (ActivityManager.RecentTaskInfo t : tasks) { // Skip tasks in the home stack if (am.isInHomeStack(t.persistentId)) { return null; } Bitmap thumbnail = am.getTaskTopThumbnail(t.persistentId); return thumbnail; } return null; } /** Returns whether there is a first task */ boolean hasFirstTask() { ActivityManager am = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE); List<ActivityManager.RecentTaskInfo> tasks = am.getRecentTasksForUser(1, ActivityManager.RECENT_IGNORE_UNAVAILABLE | ActivityManager.RECENT_INCLUDE_RELATED, UserHandle.CURRENT.getIdentifier()); for (ActivityManager.RecentTaskInfo t : tasks) { // Skip tasks in the home stack if (am.isInHomeStack(t.persistentId)) { continue; } return true; } return false; } /** Converts from the device rotation to the degree */ float getDegreesForRotation(int value) { switch (value) { case Surface.ROTATION_90: return 360f - 90f; case Surface.ROTATION_180: return 360f - 180f; case Surface.ROTATION_270: return 360f - 270f; } return 0f; } /** Takes a screenshot of the surface */ Bitmap takeScreenshot(Display display) { DisplayMetrics dm = new DisplayMetrics(); display.getRealMetrics(dm); float[] dims = {dm.widthPixels, dm.heightPixels}; float degrees = getDegreesForRotation(display.getRotation()); boolean requiresRotation = (degrees > 0); if (requiresRotation) { // Get the dimensions of the device in its native orientation Matrix m = new Matrix(); m.preRotate(-degrees); m.mapPoints(dims); dims[0] = Math.abs(dims[0]); dims[1] = Math.abs(dims[1]); } return SurfaceControl.screenshot((int) dims[0], (int) dims[1]); } /** Starts the recents activity */ void startAlternateRecentsActivity() { // If Recents is the front most activity, then we should just communicate with it directly // to launch the first task or dismiss itself ActivityManager am = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE); List<ActivityManager.RunningTaskInfo> tasks = am.getRunningTasks(1); if (!tasks.isEmpty()) { ComponentName topActivity = tasks.get(0).topActivity; Log.d(TAG, "[RecentsComponent|topActivity] " + topActivity); // Check if the front most activity is recents if (topActivity.getPackageName().equals(sRecentsPackage) && topActivity.getClassName().equals(sRecentsActivity)) { // Notify Recents to toggle itself try { Bundle data = new Bundle(); Message msg = Message.obtain(null, MSG_TOGGLE_RECENTS, 0, 0); msg.setData(data); mService.send(msg); } catch (RemoteException re) { re.printStackTrace(); } return; } } // XXX: If window transitions are currently happening, then we should eat up the event here // Otherwise, Recents is not the front-most activity and we should animate into it Rect taskRect = mFirstTaskRect; if (taskRect != null && taskRect.width() > 0 && taskRect.height() > 0 && hasFirstTask()) { // Loading from thumbnail Bitmap thumbnail; Bitmap firstThumbnail = loadFirstTaskThumbnail(); if (firstThumbnail == null) { // Load the thumbnail from the screenshot WindowManager wm = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE); Display display = wm.getDefaultDisplay(); Bitmap screenshot = takeScreenshot(display); Resources res = mContext.getResources(); int size = Math.min(screenshot.getWidth(), screenshot.getHeight()); int statusBarHeight = res.getDimensionPixelSize( com.android.internal.R.dimen.status_bar_height); thumbnail = Bitmap.createBitmap(mFirstTaskRect.width(), mFirstTaskRect.height(), Bitmap.Config.ARGB_8888); Canvas c = new Canvas(thumbnail); c.drawBitmap(screenshot, new Rect(0, statusBarHeight, size, statusBarHeight + size), new Rect(0, 0, mFirstTaskRect.width(), mFirstTaskRect.height()), null); c.setBitmap(null); // Recycle the old screenshot screenshot.recycle(); } else { // Create the thumbnail thumbnail = Bitmap.createBitmap(mFirstTaskRect.width(), mFirstTaskRect.height(), Bitmap.Config.ARGB_8888); int size = Math.min(firstThumbnail.getWidth(), firstThumbnail.getHeight()); Canvas c = new Canvas(thumbnail); c.drawBitmap(firstThumbnail, new Rect(0, 0, size, size), new Rect(0, 0, mFirstTaskRect.width(), mFirstTaskRect.height()), null); c.setBitmap(null); // Recycle the old thumbnail firstThumbnail.recycle(); } ActivityOptions opts = ActivityOptions.makeThumbnailScaleDownAnimation(mStatusBarView, thumbnail, mFirstTaskRect.left, mFirstTaskRect.top, null); startAlternateRecentsActivity(opts); } else { ActivityOptions opts = ActivityOptions.makeCustomAnimation(mContext, R.anim.recents_from_launcher_enter, R.anim.recents_from_launcher_exit); startAlternateRecentsActivity(opts); } } /** Starts the recents activity */ void startAlternateRecentsActivity(ActivityOptions opts) { Intent intent = new Intent(sToggleRecentsAction); intent.setClassName(sRecentsPackage, sRecentsActivity); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); if (opts != null) { mContext.startActivityAsUser(intent, opts.toBundle(), new UserHandle( UserHandle.USER_CURRENT)); } else { mContext.startActivityAsUser(intent, new UserHandle(UserHandle.USER_CURRENT)); if (mUseAlternateRecents) { mAlternateRecents.onConfigurationChanged(newConfig); } } @Override public void preloadRecentTasksList() { if (mUseAlternateRecents) { Log.d(TAG, "[RecentsComponent|preloadRecents]"); mAlternateRecents.onPreloadRecents(); } else { Intent intent = new Intent(RecentsActivity.PRELOAD_INTENT); intent.setClassName("com.android.systemui", Loading @@ -527,7 +234,7 @@ public class Recents extends SystemUI implements RecentsComponent { @Override public void cancelPreloadingRecentTasksList() { if (mUseAlternateRecents) { Log.d(TAG, "[RecentsComponent|cancelPreload]"); mAlternateRecents.onCancelPreloadingRecents(); } else { Intent intent = new Intent(RecentsActivity.CANCEL_PRELOAD_INTENT); intent.setClassName("com.android.systemui", Loading @@ -541,18 +248,7 @@ public class Recents extends SystemUI implements RecentsComponent { @Override public void closeRecents() { if (mUseAlternateRecents) { Log.d(TAG, "[RecentsComponent|closeRecents]"); if (mServiceIsBound) { // Try and update the recents configuration try { Bundle data = new Bundle(); Message msg = Message.obtain(null, MSG_CLOSE_RECENTS, 0, 0); msg.setData(data); mService.send(msg); } catch (RemoteException re) { re.printStackTrace(); } } mAlternateRecents.onCloseRecents(); } else { Intent intent = new Intent(RecentsActivity.CLOSE_RECENTS_INTENT); intent.setPackage("com.android.systemui"); Loading packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java 0 → 100644 +376 −0 File added.Preview size limit exceeded, changes collapsed. Show changes packages/SystemUI/src/com/android/systemui/recents/Console.java +5 −0 Original line number Diff line number Diff line Loading @@ -67,6 +67,11 @@ public class Console { Log.e("Recents", msg); } /** Logs a raw error */ public static void logRawError(String msg, Exception e) { Log.e("Recents", msg, e); } /** Logs a divider bar */ public static void logDivider(boolean condition) { if (condition) { Loading packages/SystemUI/src/com/android/systemui/recents/Constants.java +1 −0 Original line number Diff line number Diff line Loading @@ -32,6 +32,7 @@ public class Constants { // This disables the bitmap and icon caches to public static final boolean DisableBackgroundCache = false; public static final boolean RecentsComponent = false; public static final boolean TaskDataLoader = false; public static final boolean SystemUIHandshake = false; public static final boolean TimeSystemCalls = false; Loading packages/SystemUI/src/com/android/systemui/recents/RecentsTaskLoader.java +2 −1 Original line number Diff line number Diff line Loading @@ -340,7 +340,8 @@ public class RecentsTaskLoader { // Get the recent tasks List<ActivityManager.RecentTaskInfo> tasks = am.getRecentTasksForUser(25, ActivityManager.RECENT_IGNORE_UNAVAILABLE, UserHandle.CURRENT.getIdentifier()); ActivityManager.RECENT_IGNORE_UNAVAILABLE | ActivityManager.RECENT_INCLUDE_RELATED, UserHandle.CURRENT.getIdentifier()); Collections.reverse(tasks); Console.log(Constants.DebugFlags.App.TimeSystemCalls, "[RecentsTaskLoader|getRecentTasks]", Loading Loading
packages/SystemUI/src/com/android/systemui/recent/Recents.java +15 −319 Original line number Diff line number Diff line Loading @@ -16,142 +16,54 @@ package com.android.systemui.recent; import android.app.ActivityManager; import android.app.ActivityOptions; import android.content.ActivityNotFoundException; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; import android.content.pm.ActivityInfo; import android.content.pm.PackageManager; import android.content.res.Configuration; import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Matrix; import android.graphics.Paint; import android.graphics.Rect; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.os.Bundle; import android.os.Handler; import android.os.IBinder; import android.os.Message; import android.os.Messenger; import android.os.RemoteException; import android.os.SystemProperties; import android.os.UserHandle; import android.util.DisplayMetrics; import android.util.Log; import android.view.Display; import android.view.Surface; import android.view.SurfaceControl; import android.view.View; import android.view.WindowManager; import com.android.systemui.R; import com.android.systemui.RecentsComponent; import com.android.systemui.SystemUI; import java.util.List; import com.android.systemui.recents.AlternateRecentsComponent; public class Recents extends SystemUI implements RecentsComponent { /** A handler for messages from the recents implementation */ class RecentsMessageHandler extends Handler { @Override public void handleMessage(Message msg) { if (!mUseAlternateRecents) return; if (msg.what == MSG_UPDATE_FOR_CONFIGURATION) { Resources res = mContext.getResources(); float statusBarHeight = res.getDimensionPixelSize( com.android.internal.R.dimen.status_bar_height); mFirstTaskRect = (Rect) msg.getData().getParcelable("taskRect"); mFirstTaskRect.offset(0, (int) statusBarHeight); } } } /** A service connection to the recents implementation */ class RecentsServiceConnection implements ServiceConnection { @Override public void onServiceConnected(ComponentName className, IBinder service) { if (!mUseAlternateRecents) return; Log.d(TAG, "[RecentsComponent|ServiceConnection|onServiceConnected] toggleRecents: " + mToggleRecentsUponServiceBound); mService = new Messenger(service); mServiceIsBound = true; // Toggle recents if this service connection was triggered by hitting the recents button if (mToggleRecentsUponServiceBound) { startAlternateRecentsActivity(); } mToggleRecentsUponServiceBound = false; } @Override public void onServiceDisconnected(ComponentName className) { if (!mUseAlternateRecents) return; Log.d(TAG, "[RecentsComponent|ServiceConnection|onServiceDisconnected]"); mService = null; mServiceIsBound = false; } } private static final String TAG = "Recents"; private static final boolean DEBUG = true; final static int MSG_UPDATE_FOR_CONFIGURATION = 0; final static int MSG_UPDATE_TASK_THUMBNAIL = 1; final static int MSG_PRELOAD_TASKS = 2; final static int MSG_CANCEL_PRELOAD_TASKS = 3; final static int MSG_CLOSE_RECENTS = 4; final static int MSG_TOGGLE_RECENTS = 5; final static String sToggleRecentsAction = "com.android.systemui.recents.SHOW_RECENTS"; final static String sRecentsPackage = "com.android.systemui"; final static String sRecentsActivity = "com.android.systemui.recents.RecentsActivity"; final static String sRecentsService = "com.android.systemui.recents.RecentsService"; // Which recents to use boolean mUseAlternateRecents; // Recents service binding Messenger mService = null; Messenger mMessenger; boolean mServiceIsBound = false; boolean mToggleRecentsUponServiceBound; RecentsServiceConnection mConnection = new RecentsServiceConnection(); View mStatusBarView; Rect mFirstTaskRect = new Rect(); public Recents() { mMessenger = new Messenger(new RecentsMessageHandler()); } AlternateRecentsComponent mAlternateRecents; @Override public void start() { mUseAlternateRecents = SystemProperties.getBoolean("persist.recents.use_alternate", false); putComponent(RecentsComponent.class, this); mUseAlternateRecents = SystemProperties.getBoolean("persist.recents.use_alternate", false); if (mUseAlternateRecents) { Log.d(TAG, "[RecentsComponent|start]"); // Try to create a long-running connection to the recents service bindToRecentsService(false); if (mAlternateRecents == null) { mAlternateRecents = new AlternateRecentsComponent(mContext); } mAlternateRecents.onStart(); } putComponent(RecentsComponent.class, this); } @Override public void toggleRecents(Display display, int layoutDirection, View statusBarView) { if (mUseAlternateRecents) { // Launch the alternate recents if required toggleAlternateRecents(display, layoutDirection, statusBarView); mAlternateRecents.onToggleRecents(display, layoutDirection, statusBarView); return; } Loading Loading @@ -298,222 +210,17 @@ public class Recents extends SystemUI implements RecentsComponent { } } /** Toggles the alternate recents activity */ public void toggleAlternateRecents(Display display, int layoutDirection, View statusBarView) { if (!mUseAlternateRecents) return; Log.d(TAG, "[RecentsComponent|toggleRecents] serviceIsBound: " + mServiceIsBound); mStatusBarView = statusBarView; if (!mServiceIsBound) { // Try to create a long-running connection to the recents service before toggling // recents bindToRecentsService(true); return; } try { startAlternateRecentsActivity(); } catch (ActivityNotFoundException e) { Log.e(TAG, "Failed to launch RecentAppsIntent", e); } } @Override protected void onConfigurationChanged(Configuration newConfig) { if (mServiceIsBound) { Resources res = mContext.getResources(); int statusBarHeight = res.getDimensionPixelSize( com.android.internal.R.dimen.status_bar_height); int navBarHeight = res.getDimensionPixelSize( com.android.internal.R.dimen.navigation_bar_height); Rect rect = new Rect(); WindowManager wm = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE); wm.getDefaultDisplay().getRectSize(rect); // Try and update the recents configuration try { Bundle data = new Bundle(); data.putParcelable("windowRect", rect); data.putParcelable("systemInsets", new Rect(0, statusBarHeight, 0, 0)); Message msg = Message.obtain(null, MSG_UPDATE_FOR_CONFIGURATION, 0, 0); msg.setData(data); msg.replyTo = mMessenger; mService.send(msg); } catch (RemoteException re) { re.printStackTrace(); } } } /** Binds to the recents implementation */ private void bindToRecentsService(boolean toggleRecentsUponConnection) { if (!mUseAlternateRecents) return; mToggleRecentsUponServiceBound = toggleRecentsUponConnection; Intent intent = new Intent(); intent.setClassName(sRecentsPackage, sRecentsService); mContext.bindService(intent, mConnection, Context.BIND_AUTO_CREATE); } /** Loads the first task thumbnail */ Bitmap loadFirstTaskThumbnail() { ActivityManager am = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE); List<ActivityManager.RecentTaskInfo> tasks = am.getRecentTasksForUser(1, ActivityManager.RECENT_IGNORE_UNAVAILABLE | ActivityManager.RECENT_INCLUDE_RELATED, UserHandle.CURRENT.getIdentifier()); for (ActivityManager.RecentTaskInfo t : tasks) { // Skip tasks in the home stack if (am.isInHomeStack(t.persistentId)) { return null; } Bitmap thumbnail = am.getTaskTopThumbnail(t.persistentId); return thumbnail; } return null; } /** Returns whether there is a first task */ boolean hasFirstTask() { ActivityManager am = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE); List<ActivityManager.RecentTaskInfo> tasks = am.getRecentTasksForUser(1, ActivityManager.RECENT_IGNORE_UNAVAILABLE | ActivityManager.RECENT_INCLUDE_RELATED, UserHandle.CURRENT.getIdentifier()); for (ActivityManager.RecentTaskInfo t : tasks) { // Skip tasks in the home stack if (am.isInHomeStack(t.persistentId)) { continue; } return true; } return false; } /** Converts from the device rotation to the degree */ float getDegreesForRotation(int value) { switch (value) { case Surface.ROTATION_90: return 360f - 90f; case Surface.ROTATION_180: return 360f - 180f; case Surface.ROTATION_270: return 360f - 270f; } return 0f; } /** Takes a screenshot of the surface */ Bitmap takeScreenshot(Display display) { DisplayMetrics dm = new DisplayMetrics(); display.getRealMetrics(dm); float[] dims = {dm.widthPixels, dm.heightPixels}; float degrees = getDegreesForRotation(display.getRotation()); boolean requiresRotation = (degrees > 0); if (requiresRotation) { // Get the dimensions of the device in its native orientation Matrix m = new Matrix(); m.preRotate(-degrees); m.mapPoints(dims); dims[0] = Math.abs(dims[0]); dims[1] = Math.abs(dims[1]); } return SurfaceControl.screenshot((int) dims[0], (int) dims[1]); } /** Starts the recents activity */ void startAlternateRecentsActivity() { // If Recents is the front most activity, then we should just communicate with it directly // to launch the first task or dismiss itself ActivityManager am = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE); List<ActivityManager.RunningTaskInfo> tasks = am.getRunningTasks(1); if (!tasks.isEmpty()) { ComponentName topActivity = tasks.get(0).topActivity; Log.d(TAG, "[RecentsComponent|topActivity] " + topActivity); // Check if the front most activity is recents if (topActivity.getPackageName().equals(sRecentsPackage) && topActivity.getClassName().equals(sRecentsActivity)) { // Notify Recents to toggle itself try { Bundle data = new Bundle(); Message msg = Message.obtain(null, MSG_TOGGLE_RECENTS, 0, 0); msg.setData(data); mService.send(msg); } catch (RemoteException re) { re.printStackTrace(); } return; } } // XXX: If window transitions are currently happening, then we should eat up the event here // Otherwise, Recents is not the front-most activity and we should animate into it Rect taskRect = mFirstTaskRect; if (taskRect != null && taskRect.width() > 0 && taskRect.height() > 0 && hasFirstTask()) { // Loading from thumbnail Bitmap thumbnail; Bitmap firstThumbnail = loadFirstTaskThumbnail(); if (firstThumbnail == null) { // Load the thumbnail from the screenshot WindowManager wm = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE); Display display = wm.getDefaultDisplay(); Bitmap screenshot = takeScreenshot(display); Resources res = mContext.getResources(); int size = Math.min(screenshot.getWidth(), screenshot.getHeight()); int statusBarHeight = res.getDimensionPixelSize( com.android.internal.R.dimen.status_bar_height); thumbnail = Bitmap.createBitmap(mFirstTaskRect.width(), mFirstTaskRect.height(), Bitmap.Config.ARGB_8888); Canvas c = new Canvas(thumbnail); c.drawBitmap(screenshot, new Rect(0, statusBarHeight, size, statusBarHeight + size), new Rect(0, 0, mFirstTaskRect.width(), mFirstTaskRect.height()), null); c.setBitmap(null); // Recycle the old screenshot screenshot.recycle(); } else { // Create the thumbnail thumbnail = Bitmap.createBitmap(mFirstTaskRect.width(), mFirstTaskRect.height(), Bitmap.Config.ARGB_8888); int size = Math.min(firstThumbnail.getWidth(), firstThumbnail.getHeight()); Canvas c = new Canvas(thumbnail); c.drawBitmap(firstThumbnail, new Rect(0, 0, size, size), new Rect(0, 0, mFirstTaskRect.width(), mFirstTaskRect.height()), null); c.setBitmap(null); // Recycle the old thumbnail firstThumbnail.recycle(); } ActivityOptions opts = ActivityOptions.makeThumbnailScaleDownAnimation(mStatusBarView, thumbnail, mFirstTaskRect.left, mFirstTaskRect.top, null); startAlternateRecentsActivity(opts); } else { ActivityOptions opts = ActivityOptions.makeCustomAnimation(mContext, R.anim.recents_from_launcher_enter, R.anim.recents_from_launcher_exit); startAlternateRecentsActivity(opts); } } /** Starts the recents activity */ void startAlternateRecentsActivity(ActivityOptions opts) { Intent intent = new Intent(sToggleRecentsAction); intent.setClassName(sRecentsPackage, sRecentsActivity); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); if (opts != null) { mContext.startActivityAsUser(intent, opts.toBundle(), new UserHandle( UserHandle.USER_CURRENT)); } else { mContext.startActivityAsUser(intent, new UserHandle(UserHandle.USER_CURRENT)); if (mUseAlternateRecents) { mAlternateRecents.onConfigurationChanged(newConfig); } } @Override public void preloadRecentTasksList() { if (mUseAlternateRecents) { Log.d(TAG, "[RecentsComponent|preloadRecents]"); mAlternateRecents.onPreloadRecents(); } else { Intent intent = new Intent(RecentsActivity.PRELOAD_INTENT); intent.setClassName("com.android.systemui", Loading @@ -527,7 +234,7 @@ public class Recents extends SystemUI implements RecentsComponent { @Override public void cancelPreloadingRecentTasksList() { if (mUseAlternateRecents) { Log.d(TAG, "[RecentsComponent|cancelPreload]"); mAlternateRecents.onCancelPreloadingRecents(); } else { Intent intent = new Intent(RecentsActivity.CANCEL_PRELOAD_INTENT); intent.setClassName("com.android.systemui", Loading @@ -541,18 +248,7 @@ public class Recents extends SystemUI implements RecentsComponent { @Override public void closeRecents() { if (mUseAlternateRecents) { Log.d(TAG, "[RecentsComponent|closeRecents]"); if (mServiceIsBound) { // Try and update the recents configuration try { Bundle data = new Bundle(); Message msg = Message.obtain(null, MSG_CLOSE_RECENTS, 0, 0); msg.setData(data); mService.send(msg); } catch (RemoteException re) { re.printStackTrace(); } } mAlternateRecents.onCloseRecents(); } else { Intent intent = new Intent(RecentsActivity.CLOSE_RECENTS_INTENT); intent.setPackage("com.android.systemui"); Loading
packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java 0 → 100644 +376 −0 File added.Preview size limit exceeded, changes collapsed. Show changes
packages/SystemUI/src/com/android/systemui/recents/Console.java +5 −0 Original line number Diff line number Diff line Loading @@ -67,6 +67,11 @@ public class Console { Log.e("Recents", msg); } /** Logs a raw error */ public static void logRawError(String msg, Exception e) { Log.e("Recents", msg, e); } /** Logs a divider bar */ public static void logDivider(boolean condition) { if (condition) { Loading
packages/SystemUI/src/com/android/systemui/recents/Constants.java +1 −0 Original line number Diff line number Diff line Loading @@ -32,6 +32,7 @@ public class Constants { // This disables the bitmap and icon caches to public static final boolean DisableBackgroundCache = false; public static final boolean RecentsComponent = false; public static final boolean TaskDataLoader = false; public static final boolean SystemUIHandshake = false; public static final boolean TimeSystemCalls = false; Loading
packages/SystemUI/src/com/android/systemui/recents/RecentsTaskLoader.java +2 −1 Original line number Diff line number Diff line Loading @@ -340,7 +340,8 @@ public class RecentsTaskLoader { // Get the recent tasks List<ActivityManager.RecentTaskInfo> tasks = am.getRecentTasksForUser(25, ActivityManager.RECENT_IGNORE_UNAVAILABLE, UserHandle.CURRENT.getIdentifier()); ActivityManager.RECENT_IGNORE_UNAVAILABLE | ActivityManager.RECENT_INCLUDE_RELATED, UserHandle.CURRENT.getIdentifier()); Collections.reverse(tasks); Console.log(Constants.DebugFlags.App.TimeSystemCalls, "[RecentsTaskLoader|getRecentTasks]", Loading