From b1252dfd2a8a27aaada9b616e57be43177a7f422 Mon Sep 17 00:00:00 2001 From: Andres Morales Date: Mon, 1 Jun 2015 17:50:43 +0000 Subject: Revert "[partition checking] re-enable bootimage/bootloader, add recovery" This reverts commit 831e01a89e9636baf15d35e7f8ff5e9f290c8b87. Change-Id: I48bf74631b842178964d25906b2790f18632e32a --- core/java/android/os/Build.java | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java index dfd523a6c2ce..50eed3e9df7e 100644 --- a/core/java/android/os/Build.java +++ b/core/java/android/os/Build.java @@ -685,8 +685,6 @@ public class Build { final String bootimage = SystemProperties.get("ro.bootimage.build.fingerprint"); final String requiredBootloader = SystemProperties.get("ro.build.expect.bootloader"); final String currentBootloader = SystemProperties.get("ro.bootloader"); - final String requiredRecovery = SystemProperties.get("ro.expect.recovery_id"); - final String currentRecovery = SystemProperties.get("ro.recovery_id"); final String requiredRadio = SystemProperties.get("ro.build.expect.baseband"); final String currentRadio = SystemProperties.get("gsm.version.baseband"); @@ -703,6 +701,7 @@ public class Build { } } + /* TODO: Figure out issue with checks failing if (!TextUtils.isEmpty(bootimage)) { if (!Objects.equals(system, bootimage)) { Slog.e(TAG, "Mismatched fingerprints; system reported " + system @@ -719,15 +718,6 @@ public class Build { } } - if (!TextUtils.isEmpty(requiredRecovery)) { - if (!Objects.equals(currentRecovery, requiredRecovery)) { - Slog.e(TAG, "Mismatched recovery version: build requires " + requiredRecovery - + " but runtime reports " + currentRecovery); - return false; - } - } - - /* TODO: uncomment when new bootloader lands b/20860620 if (!TextUtils.isEmpty(requiredRadio)) { if (!Objects.equals(currentRadio, requiredRadio)) { Slog.e(TAG, "Mismatched radio version: build requires " + requiredRadio -- cgit v1.2.3-59-g8ed1b From 43c778039fd8d9329a3f0a562c42e166345c6fc3 Mon Sep 17 00:00:00 2001 From: Jason Monk Date: Mon, 1 Jun 2015 15:00:57 -0400 Subject: Be more careful with mAccessPoints usage Bug: 21559453 Change-Id: I1a0bcf7282ad1a651169dea7e8ac5bc618b580d1 --- .../src/com/android/settingslib/wifi/WifiTracker.java | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java index 68803b39ea1d..f32493375e9e 100644 --- a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java +++ b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java @@ -205,7 +205,9 @@ public class WifiTracker { * Gets the current list of access points. */ public List getAccessPoints() { - return mAccessPoints; + synchronized (mAccessPoints) { + return new ArrayList<>(mAccessPoints); + } } public WifiManager getManager() { @@ -230,14 +232,14 @@ public class WifiTracker { public void dump(PrintWriter pw) { pw.println(" - wifi tracker ------"); - for (AccessPoint accessPoint : mAccessPoints) { + for (AccessPoint accessPoint : getAccessPoints()) { pw.println(" " + accessPoint); } } private void updateAccessPoints() { // Swap the current access points into a cached list. - ArrayList cachedAccessPoints = new ArrayList<>(mAccessPoints); + List cachedAccessPoints = getAccessPoints(); ArrayList accessPoints = new ArrayList<>(); // Clear out the configs so we don't think something is saved when it isn't. @@ -330,7 +332,7 @@ public class WifiTracker { mMainHandler.sendEmptyMessage(MainHandler.MSG_ACCESS_POINT_CHANGED); } - private AccessPoint getCachedOrCreate(ScanResult result, ArrayList cache) { + private AccessPoint getCachedOrCreate(ScanResult result, List cache) { final int N = cache.size(); for (int i = 0; i < N; i++) { if (cache.get(i).matches(result)) { @@ -342,7 +344,7 @@ public class WifiTracker { return new AccessPoint(mContext, result); } - private AccessPoint getCachedOrCreate(WifiConfiguration config, ArrayList cache) { + private AccessPoint getCachedOrCreate(WifiConfiguration config, List cache) { final int N = cache.size(); for (int i = 0; i < N; i++) { if (cache.get(i).matches(config)) { @@ -380,7 +382,9 @@ public class WifiTracker { } } if (reorder) { - Collections.sort(mAccessPoints); + synchronized (mAccessPoints) { + Collections.sort(mAccessPoints); + } mMainHandler.sendEmptyMessage(MainHandler.MSG_ACCESS_POINT_CHANGED); } } -- cgit v1.2.3-59-g8ed1b From da4ea03b9514f42f2257ee8442c37dbf4dc9ff73 Mon Sep 17 00:00:00 2001 From: Raph Levien Date: Mon, 1 Jun 2015 12:40:42 -0700 Subject: Revert "Use getRunAdvance to position cursor" This reverts commit cb5499c85097450c48f66f6c08a35bab2ad5ab12. Bug: 21549197 --- core/java/android/text/Layout.java | 1 - core/java/android/text/TextLine.java | 10 ++++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/core/java/android/text/Layout.java b/core/java/android/text/Layout.java index f7027f9e20b8..f176240dbb73 100644 --- a/core/java/android/text/Layout.java +++ b/core/java/android/text/Layout.java @@ -1121,7 +1121,6 @@ public abstract class Layout { * closest to the specified horizontal position. */ public int getOffsetForHorizontal(int line, float horiz) { - // TODO: use Paint.getOffsetForAdvance to avoid binary search int max = getLineEnd(line) - 1; int min = getLineStart(line); Directions dirs = getLineDirections(line); diff --git a/core/java/android/text/TextLine.java b/core/java/android/text/TextLine.java index 605b91dee9c0..479242c85695 100644 --- a/core/java/android/text/TextLine.java +++ b/core/java/android/text/TextLine.java @@ -739,14 +739,16 @@ class TextLine { float ret = 0; + int contextLen = contextEnd - contextStart; if (needWidth || (c != null && (wp.bgColor != 0 || wp.underlineColor != 0 || runIsRtl))) { if (mCharsValid) { - ret = wp.getRunAdvance(mChars, start, contextEnd, contextStart, contextEnd, - runIsRtl, end); + ret = wp.getTextRunAdvances(mChars, start, runLen, + contextStart, contextLen, runIsRtl, null, 0); } else { int delta = mStart; - ret = wp.getRunAdvance(mText, delta + start, delta + contextEnd, - delta + contextStart, delta + contextEnd, runIsRtl, delta + end); + ret = wp.getTextRunAdvances(mText, delta + start, + delta + end, delta + contextStart, delta + contextEnd, + runIsRtl, null, 0); } } -- cgit v1.2.3-59-g8ed1b From 4ac084d4ffb3e86b572ab066a994a394396b9122 Mon Sep 17 00:00:00 2001 From: Ruben Brunk Date: Mon, 1 Jun 2015 18:41:28 -0700 Subject: Make CameraService proxy retry behavior more lenient. Bug: 21527760 Change-Id: I70abea66f1d1fafffcfdd8e30b0cff244f814e59 --- .../com/android/server/camera/CameraService.java | 63 ++++++++++++++++++---- 1 file changed, 54 insertions(+), 9 deletions(-) diff --git a/services/core/java/com/android/server/camera/CameraService.java b/services/core/java/com/android/server/camera/CameraService.java index 777a9dd1bdcf..9347c241bb4e 100644 --- a/services/core/java/com/android/server/camera/CameraService.java +++ b/services/core/java/com/android/server/camera/CameraService.java @@ -20,10 +20,15 @@ import android.content.Context; import android.content.pm.UserInfo; import android.hardware.ICameraService; import android.hardware.ICameraServiceProxy; +import android.os.Handler; import android.os.IBinder; +import android.os.Message; +import android.os.Process; import android.os.RemoteException; import android.os.UserManager; +import android.util.Slog; +import com.android.server.ServiceThread; import com.android.server.SystemService; import java.util.Collection; @@ -36,7 +41,8 @@ import java.util.Set; * * @hide */ -public class CameraService extends SystemService { +public class CameraService extends SystemService implements Handler.Callback { + private static final String TAG = "CameraService_proxy"; /** * This must match the ICameraService.aidl definition @@ -49,7 +55,14 @@ public class CameraService extends SystemService { public static final int NO_EVENT = 0; // NOOP public static final int USER_SWITCHED = 1; // User changed, argument is the new user handle + // Handler message codes + private static final int MSG_SWITCH_USER = 1; + + private static final int RETRY_DELAY_TIME = 20; //ms + private final Context mContext; + private final ServiceThread mHandlerThread; + private final Handler mHandler; private UserManager mUserManager; private final Object mLock = new Object(); @@ -58,18 +71,29 @@ public class CameraService extends SystemService { private final ICameraServiceProxy.Stub mCameraServiceProxy = new ICameraServiceProxy.Stub() { @Override public void pingForUserUpdate() { - // Binder call - synchronized(mLock) { - if (mEnabledCameraUsers != null) { - notifyMediaserver(USER_SWITCHED, mEnabledCameraUsers); - } - } + notifySwitchWithRetries(30); } }; public CameraService(Context context) { super(context); mContext = context; + mHandlerThread = new ServiceThread(TAG, Process.THREAD_PRIORITY_DISPLAY, /*allowTo*/false); + mHandlerThread.start(); + mHandler = new Handler(mHandlerThread.getLooper(), this); + } + + @Override + public boolean handleMessage(Message msg) { + switch(msg.what) { + case MSG_SWITCH_USER: { + notifySwitchWithRetries(msg.arg1); + } break; + default: { + Slog.e(TAG, "CameraService error, invalid message: " + msg.what); + } break; + } + return true; } @Override @@ -119,12 +143,30 @@ public class CameraService extends SystemService { return handles; } - private void notifyMediaserver(int eventType, Set updatedUserHandles) { + private void notifySwitchWithRetries(int retries) { + synchronized(mLock) { + if (mEnabledCameraUsers == null) { + return; + } + if (notifyMediaserver(USER_SWITCHED, mEnabledCameraUsers)) { + retries = 0; + } + } + if (retries <= 0) { + return; + } + Slog.i(TAG, "Could not notify camera service of user switch, retrying..."); + mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_SWITCH_USER, retries - 1, 0, null), + RETRY_DELAY_TIME); + } + + private boolean notifyMediaserver(int eventType, Set updatedUserHandles) { // Forward the user switch event to the native camera service running in the mediaserver // process. IBinder cameraServiceBinder = getBinderService(CAMERA_SERVICE_BINDER_NAME); if (cameraServiceBinder == null) { - return; // Camera service not active, cannot evict user clients. + Slog.w(TAG, "Could not notify mediaserver, camera service not available."); + return false; // Camera service not active, cannot evict user clients. } ICameraService cameraServiceRaw = ICameraService.Stub.asInterface(cameraServiceBinder); @@ -132,8 +174,11 @@ public class CameraService extends SystemService { try { cameraServiceRaw.notifySystemEvent(eventType, toArray(updatedUserHandles)); } catch (RemoteException e) { + Slog.w(TAG, "Could not notify mediaserver, remote exception: " + e); // Not much we can do if camera service is dead. + return false; } + return true; } private static int[] toArray(Collection c) { -- cgit v1.2.3-59-g8ed1b From e8d84beff93ccce2f71a9959f565a9a814d27a91 Mon Sep 17 00:00:00 2001 From: Wale Ogunwale Date: Tue, 2 Jun 2015 11:32:52 -0700 Subject: Enabled WMS.DEBUG_STARTING_WINDOW To debug starting window issue reported in comment #38 of b/21384482 Bug 21384482 Change-Id: I2fbafda5fa79448057cf27a65d1be9b96894770e --- services/core/java/com/android/server/wm/WindowManagerService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 5c9f87e08f1a..d996caa3fc2f 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -208,7 +208,7 @@ public class WindowManagerService extends IWindowManager.Stub static final boolean DEBUG_APP_ORIENTATION = false; static final boolean DEBUG_CONFIGURATION = false; static final boolean DEBUG_APP_TRANSITIONS = false; - static final boolean DEBUG_STARTING_WINDOW = false; + static final boolean DEBUG_STARTING_WINDOW = true; static final boolean DEBUG_WALLPAPER = false; static final boolean DEBUG_WALLPAPER_LIGHT = false || DEBUG_WALLPAPER; static final boolean DEBUG_DRAG = false; -- cgit v1.2.3-59-g8ed1b From a2bb03925bd2d0c8ebe4499999faaeefc43e4414 Mon Sep 17 00:00:00 2001 From: Jason Monk Date: Tue, 2 Jun 2015 14:52:22 -0400 Subject: Handle network info updates while scanning is paused Bug: 21581533 Change-Id: I4216c3e9b64cb758e32dd93c39061f9d7a642ee0 --- .../com/android/settingslib/wifi/WifiTracker.java | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java index f32493375e9e..cf3b7c873d59 100644 --- a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java +++ b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java @@ -357,17 +357,19 @@ public class WifiTracker { } private void updateNetworkInfo(NetworkInfo networkInfo) { - /* sticky broadcasts can call this when wifi is disabled */ - if (!mWifiManager.isWifiEnabled()) { - mScanner.pause(); - return; - } + if (mScanner != null) { + /* sticky broadcasts can call this when wifi is disabled */ + if (!mWifiManager.isWifiEnabled()) { + mScanner.pause(); + return; + } - if (networkInfo != null && - networkInfo.getDetailedState() == DetailedState.OBTAINING_IPADDR) { - mScanner.pause(); - } else { - mScanner.resume(); + if (networkInfo != null && + networkInfo.getDetailedState() == DetailedState.OBTAINING_IPADDR) { + mScanner.pause(); + } else { + mScanner.resume(); + } } mLastInfo = mWifiManager.getConnectionInfo(); -- cgit v1.2.3-59-g8ed1b From 4c433ee5385398d957711e558765fdae773e03f1 Mon Sep 17 00:00:00 2001 From: Tao Bao Date: Tue, 2 Jun 2015 12:12:53 -0700 Subject: Fix the NPE when checking mRebootReason Bug: 21584198 Change-Id: Ie11092dbc771b54bd049d258dc705835a3eda494 --- services/core/java/com/android/server/power/ShutdownThread.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/core/java/com/android/server/power/ShutdownThread.java b/services/core/java/com/android/server/power/ShutdownThread.java index e5981fb99c07..4b62c401fc72 100644 --- a/services/core/java/com/android/server/power/ShutdownThread.java +++ b/services/core/java/com/android/server/power/ShutdownThread.java @@ -408,7 +408,7 @@ public final class ShutdownThread extends Thread { } // If it's to reboot into recovery, invoke uncrypt via init service. - if (mRebootReason.equals(PowerManager.REBOOT_RECOVERY)) { + if (PowerManager.REBOOT_RECOVERY.equals(mRebootReason)) { uncrypt(); } -- cgit v1.2.3-59-g8ed1b From dc6d513803c8c67b6004b218129bff2c66b4c262 Mon Sep 17 00:00:00 2001 From: Nick Kralevich Date: Tue, 2 Jun 2015 16:56:06 -0700 Subject: UsbDeviceManager: Don't unnecessarily touch properties Before setting the properties persist.sys.usb.config or sys.usb.config, check the existing values. If the values are the same as what we'd set it to, don't perform the set. Any USB property set, even if setting the property to the value it already has, triggers one of the "on property" triggers in system/core/rootdir/init.usb.rc . The script then reconfigures the driver unnecessarily, which causes instability and dropped connections when trying to use ADB. Avoid this instability by not performing property sets which would have no effect. Bug: 21404762 Bug: 18905620 Change-Id: Id3c2543308df994a0114a0661e20ca799c2dc0e8 --- .../java/com/android/server/usb/UsbDeviceManager.java | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/services/usb/java/com/android/server/usb/UsbDeviceManager.java b/services/usb/java/com/android/server/usb/UsbDeviceManager.java index cb8f938ca50e..d6a7dd16902a 100644 --- a/services/usb/java/com/android/server/usb/UsbDeviceManager.java +++ b/services/usb/java/com/android/server/usb/UsbDeviceManager.java @@ -411,6 +411,16 @@ public class UsbDeviceManager { sendMessageDelayed(msg, (connected == 0) ? UPDATE_DELAY : 0); } + private void updatePersistentProperty() { + String newValue = mAdbEnabled ? "adb" : "none"; + String value = SystemProperties.get(UsbManager.ADB_PERSISTENT_PROPERTY); + if (DEBUG) { Slog.d(TAG, "updatePersistentProperty newValue=" + newValue + " value=" + value); } + if (!newValue.equals(value)) { + SystemProperties.set(UsbManager.ADB_PERSISTENT_PROPERTY, mAdbEnabled ? "adb" : "none"); + } + waitForState(newValue); + } + private boolean waitForState(String state) { // wait for the transition to complete. // give up after 1 second. @@ -426,7 +436,10 @@ public class UsbDeviceManager { private boolean setUsbConfig(String config) { if (DEBUG) Slog.d(TAG, "setUsbConfig(" + config + ")"); // set the new configuration - SystemProperties.set(UsbManager.USB_SETTINGS_PROPERTY, config); + String oldConfig = SystemProperties.get(UsbManager.USB_SETTINGS_PROPERTY); + if (!config.equals(oldConfig)) { + SystemProperties.set(UsbManager.USB_SETTINGS_PROPERTY, config); + } return waitForState(config); } @@ -436,7 +449,7 @@ public class UsbDeviceManager { mAdbEnabled = enable; // Due to the persist.sys.usb.config property trigger, changing adb state requires // persisting default function - SystemProperties.set(UsbManager.ADB_PERSISTENT_PROPERTY, mAdbEnabled ? "adb" : "none"); + updatePersistentProperty(); // After persisting them use the lock-down aware function set setEnabledFunctions(getDefaultFunctions()); updateAdbNotification(); @@ -610,7 +623,7 @@ public class UsbDeviceManager { break; case MSG_SYSTEM_READY: setUsbConfig(mCurrentFunctions); - SystemProperties.set(UsbManager.ADB_PERSISTENT_PROPERTY, mAdbEnabled ? "adb" : "none"); + updatePersistentProperty(); updateUsbNotification(); updateAdbNotification(); updateUsbState(); -- cgit v1.2.3-59-g8ed1b From 48de126b71c22fb0ce36797ac1c46538395d08c0 Mon Sep 17 00:00:00 2001 From: Filip Gruszczynski Date: Wed, 3 Jun 2015 10:32:26 -0700 Subject: Fix NPE when requesting outsets for detached view. Outsets are used during measure/layout pass, but this can be called on a view that is not currently attached. Bug: 21602590 Change-Id: I23e3acc45ca4bf7684d8913f839e29e8e9e94d78 --- core/java/android/view/View.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index 37c8100bebb0..1e92a067a2e3 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -7366,7 +7366,11 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * @hide */ public void getOutsets(Rect outOutsetRect) { - outOutsetRect.set(mAttachInfo.mOutsets); + if (mAttachInfo != null) { + outOutsetRect.set(mAttachInfo.mOutsets); + } else { + outOutsetRect.setEmpty(); + } } /** @@ -14508,7 +14512,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } } - onDetachedFromWindow(); + onDetachedFromWindows(); onDetachedFromWindowInternal(); InputMethodManager imm = InputMethodManager.peekInstance(); -- cgit v1.2.3-59-g8ed1b From ba91fc8ae41693b06f5e69fa480b9fd5ba726c9f Mon Sep 17 00:00:00 2001 From: Jason Monk Date: Wed, 3 Jun 2015 14:06:34 -0400 Subject: SettingsLib/Wifi: Run pause/resumes on main thread To avoid our objects from disappearing out from under us. Bug: 21581533 Change-Id: Ia6fc9e56271f79c7d8b0f86f9c35351c39c35d29 --- .../com/android/settingslib/wifi/WifiTracker.java | 34 ++++++++++++++-------- 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java index cf3b7c873d59..09c93e9820d4 100644 --- a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java +++ b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java @@ -357,19 +357,17 @@ public class WifiTracker { } private void updateNetworkInfo(NetworkInfo networkInfo) { - if (mScanner != null) { - /* sticky broadcasts can call this when wifi is disabled */ - if (!mWifiManager.isWifiEnabled()) { - mScanner.pause(); - return; - } + /* sticky broadcasts can call this when wifi is disabled */ + if (!mWifiManager.isWifiEnabled()) { + mMainHandler.sendEmptyMessage(MainHandler.MSG_PAUSE_SCANNING); + return; + } - if (networkInfo != null && - networkInfo.getDetailedState() == DetailedState.OBTAINING_IPADDR) { - mScanner.pause(); - } else { - mScanner.resume(); - } + if (networkInfo != null && + networkInfo.getDetailedState() == DetailedState.OBTAINING_IPADDR) { + mMainHandler.sendEmptyMessage(MainHandler.MSG_PAUSE_SCANNING); + } else { + mMainHandler.sendEmptyMessage(MainHandler.MSG_RESUME_SCANNING); } mLastInfo = mWifiManager.getConnectionInfo(); @@ -448,6 +446,8 @@ public class WifiTracker { private static final int MSG_CONNECTED_CHANGED = 0; private static final int MSG_WIFI_STATE_CHANGED = 1; private static final int MSG_ACCESS_POINT_CHANGED = 2; + private static final int MSG_RESUME_SCANNING = 3; + private static final int MSG_PAUSE_SCANNING = 4; public MainHandler(Looper looper) { super(looper); @@ -468,6 +468,16 @@ public class WifiTracker { case MSG_ACCESS_POINT_CHANGED: mListener.onAccessPointsChanged(); break; + case MSG_RESUME_SCANNING: + if (mScanner != null) { + mScanner.resume(); + } + break; + case MSG_PAUSE_SCANNING: + if (mScanner != null) { + mScanner.pause(); + } + break; } } } -- cgit v1.2.3-59-g8ed1b From 6a644aff7882254b72e22b3893af02cb0ae2b3e5 Mon Sep 17 00:00:00 2001 From: Dmitriy Ivanov Date: Wed, 3 Jun 2015 12:02:59 -0700 Subject: Fix build Bug: 21602590 Change-Id: Iffb9a7b74dc97bf30aea2014b0e3d2a96097291b --- core/java/android/view/View.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index 1e92a067a2e3..65a0ccba5c64 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -14512,7 +14512,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } } - onDetachedFromWindows(); + onDetachedFromWindow(); onDetachedFromWindowInternal(); InputMethodManager imm = InputMethodManager.peekInstance(); -- cgit v1.2.3-59-g8ed1b From 900fb48d269e2fbf3baea995c6324e4c08ad7c22 Mon Sep 17 00:00:00 2001 From: Jorim Jaggi Date: Tue, 2 Jun 2015 15:07:33 -0700 Subject: Make entering recents a lot faster - Precache the bitmap for the window animation in the preload phase - Remove some post's so we have a faster path from UP -> startActivity - Don't dim the headers in the first frame drawn, because layer creation is slow. Instead, do it in the second frame, when the window animation is already running. All these changes combined make going to recents about 40-50ms faster. Change-Id: I3e4060af1ac57b3f359fe7f86f9e3814c6490323 --- .../src/com/android/systemui/recents/Recents.java | 142 +++++++++++++++------ .../android/systemui/recents/RecentsActivity.java | 4 + .../systemui/recents/views/RecentsView.java | 7 + .../systemui/recents/views/TaskStackView.java | 22 +++- .../android/systemui/recents/views/TaskView.java | 4 + .../systemui/recents/views/TaskViewHeader.java | 28 +++- .../android/systemui/statusbar/BaseStatusBar.java | 4 +- 7 files changed, 168 insertions(+), 43 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/recents/Recents.java b/packages/SystemUI/src/com/android/systemui/recents/Recents.java index bbd3e609b554..7d2b5c8776d1 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/Recents.java +++ b/packages/SystemUI/src/com/android/systemui/recents/Recents.java @@ -32,6 +32,7 @@ import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Rect; +import android.os.AsyncTask; import android.os.Handler; import android.os.SystemClock; import android.os.UserHandle; @@ -40,6 +41,7 @@ import android.util.Pair; import android.view.Display; import android.view.LayoutInflater; import android.view.View; + import com.android.systemui.R; import com.android.systemui.RecentsComponent; import com.android.systemui.SystemUI; @@ -184,12 +186,16 @@ public class Recents extends SystemUI // Header (for transition) TaskViewHeader mHeaderBar; + final Object mHeaderBarLock = new Object(); TaskStackView mDummyStackView; // Variables to keep track of if we need to start recents after binding boolean mTriggeredFromAltTab; long mLastToggleTime; + Bitmap mThumbnailTransitionBitmapCache; + Task mThumbnailTransitionBitmapCacheKey; + public Recents() { } @@ -360,13 +366,16 @@ public class Recents extends SystemUI void preloadRecentsInternal() { // Preload only the raw task list into a new load plan (which will be consumed by the // RecentsActivity) + ActivityManager.RunningTaskInfo topTask = mSystemServicesProxy.getTopMostTask(); + MutableBoolean topTaskHome = new MutableBoolean(true); RecentsTaskLoader loader = RecentsTaskLoader.getInstance(); sInstanceLoadPlan = loader.createLoadPlan(mContext); - - ActivityManager.RunningTaskInfo topTask = mSystemServicesProxy.getTopMostTask(); - MutableBoolean isTopTaskHome = new MutableBoolean(true); - if (topTask != null && mSystemServicesProxy.isRecentsTopMost(topTask, isTopTaskHome)) { - sInstanceLoadPlan.preloadRawTasks(isTopTaskHome.value); + if (topTask != null && !mSystemServicesProxy.isRecentsTopMost(topTask, topTaskHome)) { + sInstanceLoadPlan.preloadRawTasks(topTaskHome.value); + loader.preloadTasks(sInstanceLoadPlan, topTaskHome.value); + TaskStack top = sInstanceLoadPlan.getAllTaskStacks().get(0); + preCacheThumbnailTransitionBitmapAsync(topTask, top, mDummyStackView, + topTaskHome.value); } } @@ -513,12 +522,14 @@ public class Recents extends SystemUI algo.computeRects(mWindowRect.width(), mWindowRect.height(), taskStackBounds); Rect taskViewSize = algo.getUntransformedTaskViewSize(); int taskBarHeight = res.getDimensionPixelSize(R.dimen.recents_task_bar_height); - mHeaderBar = (TaskViewHeader) mInflater.inflate(R.layout.recents_task_view_header, null, - false); - mHeaderBar.measure( - View.MeasureSpec.makeMeasureSpec(taskViewSize.width(), View.MeasureSpec.EXACTLY), - View.MeasureSpec.makeMeasureSpec(taskBarHeight, View.MeasureSpec.EXACTLY)); - mHeaderBar.layout(0, 0, taskViewSize.width(), taskBarHeight); + synchronized (mHeaderBarLock) { + mHeaderBar = (TaskViewHeader) mInflater.inflate(R.layout.recents_task_view_header, null, + false); + mHeaderBar.measure( + View.MeasureSpec.makeMeasureSpec(taskViewSize.width(), View.MeasureSpec.EXACTLY), + View.MeasureSpec.makeMeasureSpec(taskBarHeight, View.MeasureSpec.EXACTLY)); + mHeaderBar.layout(0, 0, taskViewSize.width(), taskBarHeight); + } } /** Prepares the search bar app widget */ @@ -607,30 +618,27 @@ public class Recents extends SystemUI */ ActivityOptions getThumbnailTransitionActivityOptions(ActivityManager.RunningTaskInfo topTask, TaskStack stack, TaskStackView stackView) { + // Update the destination rect Task toTask = new Task(); TaskViewTransform toTransform = getThumbnailTransitionTransform(stack, stackView, topTask.id, toTask); - if (toTransform != null && toTask.key != null) { - Rect toTaskRect = toTransform.rect; - int toHeaderWidth = (int) (mHeaderBar.getMeasuredWidth() * toTransform.scale); - int toHeaderHeight = (int) (mHeaderBar.getMeasuredHeight() * toTransform.scale); - Bitmap thumbnail = Bitmap.createBitmap(toHeaderWidth, toHeaderHeight, - Bitmap.Config.ARGB_8888); - if (Constants.DebugFlags.App.EnableTransitionThumbnailDebugMode) { - thumbnail.eraseColor(0xFFff0000); - } else { - Canvas c = new Canvas(thumbnail); - c.scale(toTransform.scale, toTransform.scale); - mHeaderBar.rebindToTask(toTask); - mHeaderBar.draw(c); - c.setBitmap(null); - } - Bitmap thumbnailImmutable = thumbnail.createAshmemBitmap(); - + Rect toTaskRect = toTransform.rect; + Bitmap thumbnail; + if (mThumbnailTransitionBitmapCacheKey != null + && mThumbnailTransitionBitmapCacheKey.key != null + && mThumbnailTransitionBitmapCacheKey.key.equals(toTask.key)) { + thumbnail = mThumbnailTransitionBitmapCache; + mThumbnailTransitionBitmapCacheKey = null; + mThumbnailTransitionBitmapCache = null; + } else { + preloadIcon(topTask); + thumbnail = drawThumbnailTransitionBitmap(toTask, toTransform); + } + if (thumbnail != null) { mStartAnimationTriggered = false; return ActivityOptions.makeThumbnailAspectScaleDownAnimation(mDummyStackView, - thumbnailImmutable, toTaskRect.left, toTaskRect.top, toTaskRect.width(), + thumbnail, toTaskRect.left, toTaskRect.top, toTaskRect.width(), toTaskRect.height(), mHandler, this); } @@ -638,6 +646,72 @@ public class Recents extends SystemUI return getUnknownTransitionActivityOptions(); } + /** + * Preloads the icon of a task. + */ + void preloadIcon(ActivityManager.RunningTaskInfo task) { + + // Ensure that we load the running task's icon + RecentsTaskLoadPlan.Options launchOpts = new RecentsTaskLoadPlan.Options(); + launchOpts.runningTaskId = task.id; + launchOpts.loadThumbnails = false; + launchOpts.onlyLoadForCache = true; + RecentsTaskLoader.getInstance().loadTasks(mContext, sInstanceLoadPlan, launchOpts); + } + + /** + * Caches the header thumbnail used for a window animation asynchronously into + * {@link #mThumbnailTransitionBitmapCache}. + */ + void preCacheThumbnailTransitionBitmapAsync(ActivityManager.RunningTaskInfo topTask, + TaskStack stack, TaskStackView stackView, boolean isTopTaskHome) { + preloadIcon(topTask); + + // Update the destination rect + mDummyStackView.updateMinMaxScrollForStack(stack, mTriggeredFromAltTab, isTopTaskHome); + final Task toTask = new Task(); + final TaskViewTransform toTransform = getThumbnailTransitionTransform(stack, stackView, + topTask.id, toTask); + new AsyncTask() { + @Override + protected Bitmap doInBackground(Void... params) { + return drawThumbnailTransitionBitmap(toTask, toTransform); + } + + @Override + protected void onPostExecute(Bitmap bitmap) { + mThumbnailTransitionBitmapCache = bitmap; + mThumbnailTransitionBitmapCacheKey = toTask; + } + }.execute(); + } + + /** + * Draws the header of a task used for the window animation into a bitmap. + */ + Bitmap drawThumbnailTransitionBitmap(Task toTask, TaskViewTransform toTransform) { + if (toTransform != null && toTask.key != null) { + Bitmap thumbnail; + synchronized (mHeaderBarLock) { + int toHeaderWidth = (int) (mHeaderBar.getMeasuredWidth() * toTransform.scale); + int toHeaderHeight = (int) (mHeaderBar.getMeasuredHeight() * toTransform.scale); + thumbnail = Bitmap.createBitmap(toHeaderWidth, toHeaderHeight, + Bitmap.Config.ARGB_8888); + if (Constants.DebugFlags.App.EnableTransitionThumbnailDebugMode) { + thumbnail.eraseColor(0xFFff0000); + } else { + Canvas c = new Canvas(thumbnail); + c.scale(toTransform.scale, toTransform.scale); + mHeaderBar.rebindToTask(toTask); + mHeaderBar.draw(c); + c.setBitmap(null); + } + } + return thumbnail.createAshmemBitmap(); + } + return null; + } + /** Returns the transition rect for the given task id. */ TaskViewTransform getThumbnailTransitionTransform(TaskStack stack, TaskStackView stackView, int runningTaskId, Task runningTaskOut) { @@ -694,7 +768,9 @@ public class Recents extends SystemUI return; } - loader.preloadTasks(sInstanceLoadPlan, isTopTaskHome); + if (!sInstanceLoadPlan.hasTasks()) { + loader.preloadTasks(sInstanceLoadPlan, isTopTaskHome); + } ArrayList stacks = sInstanceLoadPlan.getAllTaskStacks(); TaskStack stack = stacks.get(0); @@ -706,12 +782,6 @@ public class Recents extends SystemUI boolean useThumbnailTransition = (topTask != null) && !isTopTaskHome && hasRecentTasks; if (useThumbnailTransition) { - // Ensure that we load the running task's icon - RecentsTaskLoadPlan.Options launchOpts = new RecentsTaskLoadPlan.Options(); - launchOpts.runningTaskId = topTask.id; - launchOpts.loadThumbnails = false; - launchOpts.onlyLoadForCache = true; - loader.loadTasks(mContext, sInstanceLoadPlan, launchOpts); // Try starting with a thumbnail transition ActivityOptions opts = getThumbnailTransitionActivityOptions(topTask, stack, diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java index ad97f91535d1..9404dcbbeeb7 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java +++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java @@ -441,6 +441,10 @@ public class RecentsActivity extends Activity implements RecentsView.RecentsView if (mConfig.launchedHasConfigurationChanged) { onEnterAnimationTriggered(); } + + if (!mConfig.launchedHasConfigurationChanged) { + mRecentsView.disableLayersForOneFrame(); + } } @Override diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java index cec613cd33af..1a21d8a6f25f 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java +++ b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java @@ -431,6 +431,13 @@ public class RecentsView extends FrameLayout implements TaskStackView.TaskStackV return false; } + public void disableLayersForOneFrame() { + List stackViews = getTaskStackViews(); + for (int i = 0; i < stackViews.size(); i++) { + stackViews.get(i).disableLayersForOneFrame(); + } + } + /**** TaskStackView.TaskStackCallbacks Implementation ****/ @Override diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java index 5f151e87a680..5711cd6d22aa 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java +++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java @@ -19,6 +19,7 @@ package com.android.systemui.recents.views; import android.animation.ValueAnimator; import android.content.ComponentName; import android.content.Context; +import android.graphics.Canvas; import android.graphics.Matrix; import android.graphics.Rect; import android.view.LayoutInflater; @@ -63,7 +64,6 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal public void onTaskResize(Task t); } - RecentsConfiguration mConfig; TaskStack mStack; @@ -81,7 +81,6 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal boolean mDismissAllButtonAnimating; int mFocusedTaskIndex = -1; int mPrevAccessibilityFocusedIndex = -1; - // Optimizations int mStackViewsAnimationDuration; boolean mStackViewsDirty = true; @@ -99,6 +98,7 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal ArrayList mTaskViews = new ArrayList(); List mImmutableTaskViews = new ArrayList(); LayoutInflater mInflater; + boolean mLayersDisabled; // A convenience update listener to request updating clipping of tasks ValueAnimator.AnimatorUpdateListener mRequestUpdateClippingListener = @@ -375,7 +375,9 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal if (tv == null) { tv = mViewPool.pickUpViewFromPool(task, task); - + if (mLayersDisabled) { + tv.disableLayersForOneFrame(); + } if (mStackViewsAnimationDuration > 0) { // For items in the list, put them in start animating them from the // approriate ends of the list where they are expected to appear @@ -1031,6 +1033,20 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal mUIDozeTrigger.poke(); } + @Override + protected void dispatchDraw(Canvas canvas) { + mLayersDisabled = false; + super.dispatchDraw(canvas); + } + + public void disableLayersForOneFrame() { + mLayersDisabled = true; + List taskViews = getTaskViews(); + for (int i = 0; i < taskViews.size(); i++) { + taskViews.get(i).disableLayersForOneFrame(); + } + } + /**** TaskStackCallbacks Implementation ****/ @Override diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java index 01ed08a9d042..c27e3a815ccb 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java +++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java @@ -650,6 +650,10 @@ public class TaskView extends FrameLayout implements Task.TaskCallbacks, } } + public void disableLayersForOneFrame() { + mHeaderView.disableLayersForOneFrame(); + } + /**** TaskCallbacks Implementation ****/ /** Binds this task view to the task */ diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java index f397bc395eb4..09e98396fcd8 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java +++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java @@ -80,6 +80,8 @@ public class TaskViewHeader extends FrameLayout { Paint mDimLayerPaint = new Paint(); PorterDuffColorFilter mDimColorFilter = new PorterDuffColorFilter(0, PorterDuff.Mode.SRC_ATOP); + boolean mLayersDisabled; + public TaskViewHeader(Context context) { this(context, null); } @@ -172,7 +174,9 @@ public class TaskViewHeader extends FrameLayout { void setDimAlpha(int alpha) { mDimColorFilter.setColor(Color.argb(alpha, 0, 0, 0)); mDimLayerPaint.setColorFilter(mDimColorFilter); - setLayerType(LAYER_TYPE_HARDWARE, mDimLayerPaint); + if (!mLayersDisabled) { + setLayerType(LAYER_TYPE_HARDWARE, mDimLayerPaint); + } } /** Returns the secondary color for a primary color. */ @@ -305,6 +309,28 @@ public class TaskViewHeader extends FrameLayout { return new int[] {}; } + @Override + protected void dispatchDraw(Canvas canvas) { + super.dispatchDraw(canvas); + if (mLayersDisabled) { + mLayersDisabled = false; + postOnAnimation(new Runnable() { + @Override + public void run() { + mLayersDisabled = false; + setLayerType(LAYER_TYPE_HARDWARE, mDimLayerPaint); + } + }); + } + } + + public void disableLayersForOneFrame() { + mLayersDisabled = true; + + // Disable layer for a frame so we can draw our first frame faster. + setLayerType(LAYER_TYPE_NONE, null); + } + /** Notifies the associated TaskView has been focused. */ void onTaskViewFocusChanged(boolean focused, boolean animateFocusedState) { // If we are not animating the visible state, just return diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java index fa172a44af8a..f05ac1a26890 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java @@ -1030,9 +1030,7 @@ public abstract class BaseStatusBar extends SystemUI implements @Override public void toggleRecentApps() { - int msg = MSG_TOGGLE_RECENTS_APPS; - mHandler.removeMessages(msg); - mHandler.sendEmptyMessage(msg); + toggleRecents(); } @Override -- cgit v1.2.3-59-g8ed1b