From 22921988c2bd5214af15d517dd358b4f10e2524c Mon Sep 17 00:00:00 2001 From: Jason Sams Date: Sat, 13 Apr 2013 19:48:36 -0700 Subject: [PATCH 01/12] Revert GC thread changes This is not quite a straight revery, some manual edits were necessary. The original CL didn't undergo sufficient design review or testing. Revert until the regressions can be sorted out. Bug 8585185 This reverts commit 6dacf8355a0692b52c49f603f43317772cb36175 This reverts commit f8c033db1edf36a0ab09568c3142054f0be2d1a1 Change-Id: Ie7215bdf881332e822603547e92f810f595077fc --- .../java/android/renderscript/Allocation.java | 18 +---- .../java/android/renderscript/BaseObj.java | 6 -- .../android/renderscript/RenderScript.java | 72 ------------------- .../android/renderscript/RenderScriptGL.java | 3 - .../java/android/renderscript/ScriptC.java | 2 - 5 files changed, 2 insertions(+), 99 deletions(-) diff --git a/graphics/java/android/renderscript/Allocation.java b/graphics/java/android/renderscript/Allocation.java index ea29b7dc49cc3..5d1990a4b85e9 100644 --- a/graphics/java/android/renderscript/Allocation.java +++ b/graphics/java/android/renderscript/Allocation.java @@ -277,21 +277,13 @@ public class Allocation extends BaseObj { throw new RSIllegalArgumentException("Invalid usage combination."); } } - if (t != null) { - // don't need to account for USAGE_SHARED Allocations - if ((usage & USAGE_SHARED) == 0) { - int numBytes = t.getCount() * t.getElement().getBytesSize(); - rs.addAllocSizeForGC(numBytes); - mGCSize = numBytes; - } - } + mType = t; mUsage = usage; if (t != null) { updateCacheInfo(t); } - } private void validateIsInt32() { @@ -355,12 +347,6 @@ public class Allocation extends BaseObj { mType.updateFromNative(); updateCacheInfo(mType); } - // don't need to account for USAGE_SHARED Allocations - if ((mUsage & USAGE_SHARED) == 0) { - int numBytes = mType.getCount() * mType.getElement().getBytesSize(); - mRS.addAllocSizeForGC(numBytes); - mGCSize = numBytes; - } } /** @@ -1264,7 +1250,6 @@ public class Allocation extends BaseObj { if (type.getID(rs) == 0) { throw new RSInvalidStateException("Bad Type"); } - int id = rs.nAllocationCreateTyped(type.getID(rs), mips.mID, usage, 0); if (id == 0) { throw new RSRuntimeException("Allocation creation failed."); @@ -1414,6 +1399,7 @@ public class Allocation extends BaseObj { return alloc; } + int id = rs.nAllocationCreateFromBitmap(t.getID(rs), mips.mID, b, usage); if (id == 0) { throw new RSRuntimeException("Load failed."); diff --git a/graphics/java/android/renderscript/BaseObj.java b/graphics/java/android/renderscript/BaseObj.java index c2ebc9f79d6a3..f464f9bb1025a 100644 --- a/graphics/java/android/renderscript/BaseObj.java +++ b/graphics/java/android/renderscript/BaseObj.java @@ -71,9 +71,6 @@ public class BaseObj { private int mID; private boolean mDestroyed; private String mName; - - int mGCSize; - RenderScript mRS; /** @@ -138,9 +135,6 @@ public class BaseObj { throw new RSInvalidStateException("Object already destroyed."); } mDestroyed = true; - if (mGCSize != 0) { - mRS.removeAllocSizeForGC(mGCSize); - } mRS.nObjDestroy(mID); } diff --git a/graphics/java/android/renderscript/RenderScript.java b/graphics/java/android/renderscript/RenderScript.java index 33639dc57d4fb..6f614c3767e9c 100644 --- a/graphics/java/android/renderscript/RenderScript.java +++ b/graphics/java/android/renderscript/RenderScript.java @@ -18,9 +18,7 @@ package android.renderscript; import java.io.File; import java.lang.reflect.Field; -import java.util.concurrent.locks.*; -import android.app.ActivityManager; import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; @@ -804,8 +802,6 @@ public class RenderScript { int mContext; @SuppressWarnings({"FieldCanBeLocal"}) MessageThread mMessageThread; - GCThread mGCThread; - Element mElement_U8; Element mElement_I8; @@ -1095,60 +1091,6 @@ public class RenderScript { } } - static class GCThread extends Thread { - RenderScript mRS; - boolean mRun = true; - - long currentSize = 0; - long targetSize; // call System.gc after 512MB of allocs - - final Lock lock = new ReentrantLock(); - final Condition cond = lock.newCondition(); - - GCThread(RenderScript rs) { - super("RSGCThread"); - mRS = rs; - - } - - public void run() { - ActivityManager am = (ActivityManager)mRS.getApplicationContext().getSystemService(Context.ACTIVITY_SERVICE); - ActivityManager.MemoryInfo meminfo = new ActivityManager.MemoryInfo(); - am.getMemoryInfo(meminfo); - targetSize = (long)(meminfo.totalMem * .5f); - - while(mRun) { - System.gc(); - lock.lock(); - try { - cond.awaitUninterruptibly(); - } finally { - lock.unlock(); - } - } - - Log.d(LOG_TAG, "GCThread exiting."); - } - - public synchronized void addAllocSize(long bytes) { - currentSize += bytes; - if (currentSize >= targetSize) { - lock.lock(); - try { - cond.signal(); - } finally { - lock.unlock(); - } - } - } - - public synchronized void removeAllocSize(long bytes) { - currentSize -= bytes; - } - - } - - RenderScript(Context ctx) { if (ctx != null) { mApplicationContext = ctx.getApplicationContext(); @@ -1171,15 +1113,6 @@ public class RenderScript { return create(ctx, sdkVersion, ContextType.NORMAL); } - void addAllocSizeForGC(int bytes) { - mGCThread.addAllocSize(bytes); - } - - void removeAllocSizeForGC(int bytes) { - mGCThread.removeAllocSize(bytes); - } - - /** * Create a basic RenderScript context. * @@ -1196,9 +1129,7 @@ public class RenderScript { throw new RSDriverException("Failed to create RS context."); } rs.mMessageThread = new MessageThread(rs); - rs.mGCThread = new GCThread(rs); rs.mMessageThread.start(); - rs.mGCThread.start(); return rs; } @@ -1253,11 +1184,8 @@ public class RenderScript { validate(); nContextDeinitToClient(mContext); mMessageThread.mRun = false; - mGCThread.mRun = false; - mGCThread.addAllocSize(0); try { mMessageThread.join(); - mGCThread.join(); } catch(InterruptedException e) { } diff --git a/graphics/java/android/renderscript/RenderScriptGL.java b/graphics/java/android/renderscript/RenderScriptGL.java index fad883873458e..52034b19e7062 100644 --- a/graphics/java/android/renderscript/RenderScriptGL.java +++ b/graphics/java/android/renderscript/RenderScriptGL.java @@ -198,9 +198,6 @@ public class RenderScriptGL extends RenderScript { } mMessageThread = new MessageThread(this); mMessageThread.start(); - mGCThread = new GCThread(this); - mGCThread.start(); - } /** diff --git a/graphics/java/android/renderscript/ScriptC.java b/graphics/java/android/renderscript/ScriptC.java index 2f69775a20ae9..221f76060bba5 100644 --- a/graphics/java/android/renderscript/ScriptC.java +++ b/graphics/java/android/renderscript/ScriptC.java @@ -60,8 +60,6 @@ public class ScriptC extends Script { throw new RSRuntimeException("Loading of ScriptC script failed."); } setID(id); - mGCSize = 2 * 1024 * 1024; - rs.addAllocSizeForGC(mGCSize); } /** From 0a80ff3de103077e04e73738d28bf036272902af Mon Sep 17 00:00:00 2001 From: Svetoslav Date: Mon, 15 Apr 2013 12:10:36 -0700 Subject: [PATCH 02/12] Fully setup newly bound service before state management. If the connected service is not entirely setup when calling the method for handling a change in the current user state we get a potential NPE since the management method may have discarded the service, thus nullifying the connection to it. Now the service is fully configured before calling the state change management method. bug:8600489 Change-Id: Ib0bf7c6d575e15c620da419d43ece22f4187fd34 --- .../server/accessibility/AccessibilityManagerService.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/services/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/java/com/android/server/accessibility/AccessibilityManagerService.java index 110c4dadc201c..ac4f970d59883 100644 --- a/services/java/com/android/server/accessibility/AccessibilityManagerService.java +++ b/services/java/com/android/server/accessibility/AccessibilityManagerService.java @@ -1817,11 +1817,13 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { addServiceLocked(this, userState); if (userState.mBindingServices.contains(mComponentName)) { userState.mBindingServices.remove(mComponentName); - onUserStateChangedLocked(userState); try { - mServiceInterface.setConnection(this, mId); + mServiceInterface.setConnection(this, mId); + onUserStateChangedLocked(userState); } catch (RemoteException re) { - Slog.w(LOG_TAG, "Error while setting connection for service: " + service, re); + Slog.w(LOG_TAG, "Error while setting connection for service: " + + service, re); + binderDied(); } } else { binderDied(); From fae36f3d2a3606dbda1dbcff4e87aaa18bb4a40d Mon Sep 17 00:00:00 2001 From: Svetoslav Date: Mon, 15 Apr 2013 12:28:42 -0700 Subject: [PATCH 03/12] Crash on non-eng builds due to lacking null check. On eng builds we have an event consistency verifier to log any inconsistent event stream states due to mishandling of intercepted events by an accessibility service. On non-eng builds this verifier is null and a null check was lacking. bug:8616711 Change-Id: Ib083a405dfa8340025090a65e50155eb10526a90 --- .../server/accessibility/AccessibilityManagerService.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/services/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/java/com/android/server/accessibility/AccessibilityManagerService.java index ac4f970d59883..128a49f348875 100644 --- a/services/java/com/android/server/accessibility/AccessibilityManagerService.java +++ b/services/java/com/android/server/accessibility/AccessibilityManagerService.java @@ -2501,7 +2501,9 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { public void flush() { synchronized (mLock) { cancelAllPendingEventsLocked(); - mSentEventsVerifier.reset(); + if (mSentEventsVerifier != null) { + mSentEventsVerifier.reset(); + } } } From 38eded77a5fa88c6878968701fd9916d94bbec4f Mon Sep 17 00:00:00 2001 From: Irfan Sheriff Date: Mon, 15 Apr 2013 15:26:01 -0700 Subject: [PATCH 04/12] Fix CTS failure due to invalid EAP update Update EAP only when it has valid entry Bug: 8604987 Change-Id: Ib6b10bd06c26ee91c4ecd3a231b509d728725dfc --- wifi/java/android/net/wifi/WifiConfigStore.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/wifi/java/android/net/wifi/WifiConfigStore.java b/wifi/java/android/net/wifi/WifiConfigStore.java index d3d5b1bb48b7d..23a4e716a4b61 100644 --- a/wifi/java/android/net/wifi/WifiConfigStore.java +++ b/wifi/java/android/net/wifi/WifiConfigStore.java @@ -1111,7 +1111,8 @@ class WifiConfigStore { break setVariables; } - if (config.enterpriseConfig != null) { + if (config.enterpriseConfig != null && + config.enterpriseConfig.getEapMethod() != WifiEnterpriseConfig.Eap.NONE) { WifiEnterpriseConfig enterpriseConfig = config.enterpriseConfig; From 18ed3c85825275116d6f23a709b67a43402f30bb Mon Sep 17 00:00:00 2001 From: Dianne Hackborn Date: Mon, 15 Apr 2013 15:36:53 -0700 Subject: [PATCH 05/12] Maybe fix issue #8620910: Win_sdk build failed and unable to create... ...the sdk platform repo Change-Id: Ib6cd7c0dfb9b6217ae79af3e2ac25fe0442996e3 --- libs/androidfw/AssetManager.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libs/androidfw/AssetManager.cpp b/libs/androidfw/AssetManager.cpp index e0d96c93c600d..b08c36bd208fb 100644 --- a/libs/androidfw/AssetManager.cpp +++ b/libs/androidfw/AssetManager.cpp @@ -33,7 +33,9 @@ #include #include #include +#ifdef HAVE_ANDROID_OS #include +#endif #include #include From 1c4bf946641b6ccfa95140ba4ea98569683a2b81 Mon Sep 17 00:00:00 2001 From: Irfan Sheriff Date: Tue, 16 Apr 2013 13:52:32 -0700 Subject: [PATCH 06/12] Fix enabling networks after driver stop Bug: 8630194 Change-Id: If897fc1fe54bf2f35362b8482e56d98f80a3130c --- wifi/java/android/net/wifi/WifiStateMachine.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/wifi/java/android/net/wifi/WifiStateMachine.java b/wifi/java/android/net/wifi/WifiStateMachine.java index a5d98cc1f4d4c..2c3df9516a179 100644 --- a/wifi/java/android/net/wifi/WifiStateMachine.java +++ b/wifi/java/android/net/wifi/WifiStateMachine.java @@ -2383,6 +2383,8 @@ public class WifiStateMachine extends StateMachine { mWifiNative.disconnect(); transitionTo(mScanModeState); } else { + /* Driver stop may have disabled networks, enable right after start */ + mWifiConfigStore.enableAllNetworks(); mWifiNative.reconnect(); // Status pulls in the current supplicant state and network connection state // events over the monitor connection. This helps framework sync up with From 225a0220f4c040ccdf168e2b1004f009f515a6d7 Mon Sep 17 00:00:00 2001 From: Jeff Brown Date: Thu, 18 Apr 2013 15:17:48 -0700 Subject: [PATCH 07/12] Fix change of behavior in Looper.quit(). It seems some applications rely on Looper.quit() terminating the loop immediately without processing all messages. Rather than risk breaking them, make the safer behavior optional. Also take care to properly drain the message queue before quitting so that all of the Message instances are recycled. This may help release storage sooner in case the Looper doesn't get GC'd promptly and its remaining queue of undelivered messages sticks around. Improve docs on runWithScissors. Bug: 8596303 Change-Id: I8cbeb6f7a5f6b8e618b5109f87a03defc1486b9f Conflicts: opengl/java/android/opengl/GLSurfaceView.java --- api/current.txt | 2 + core/java/android/os/Handler.java | 15 ++++-- core/java/android/os/HandlerThread.java | 53 ++++++++++++++++--- core/java/android/os/Looper.java | 35 +++++++++--- core/java/android/os/MessageQueue.java | 46 +++++++++++++++- opengl/java/android/opengl/GLSurfaceView.java | 17 +++--- 6 files changed, 140 insertions(+), 28 deletions(-) diff --git a/api/current.txt b/api/current.txt index 309a235bbbd5d..d0aad13bb1915 100644 --- a/api/current.txt +++ b/api/current.txt @@ -17062,6 +17062,7 @@ package android.os { method public int getThreadId(); method protected void onLooperPrepared(); method public boolean quit(); + method public boolean quitSafely(); } public abstract interface IBinder { @@ -17102,6 +17103,7 @@ package android.os { method public static void prepare(); method public static void prepareMainLooper(); method public void quit(); + method public void quitSafely(); method public void setMessageLogging(android.util.Printer); } diff --git a/core/java/android/os/Handler.java b/core/java/android/os/Handler.java index 94de4487b645c..14d8f0765f9d8 100644 --- a/core/java/android/os/Handler.java +++ b/core/java/android/os/Handler.java @@ -413,27 +413,32 @@ public class Handler { /** * Runs the specified task synchronously. - * + *

* If the current thread is the same as the handler thread, then the runnable * runs immediately without being enqueued. Otherwise, posts the runnable * to the handler and waits for it to complete before returning. - * + *

* This method is dangerous! Improper use can result in deadlocks. * Never call this method while any locks are held or use it in a * possibly re-entrant manner. - * + *

* This method is occasionally useful in situations where a background thread * must synchronously await completion of a task that must run on the * handler's thread. However, this problem is often a symptom of bad design. * Consider improving the design (if possible) before resorting to this method. - * + *

* One example of where you might want to use this method is when you just * set up a Handler thread and need to perform some initialization steps on * it before continuing execution. - * + *

* If timeout occurs then this method returns false but the runnable * will remain posted on the handler and may already be in progress or * complete at a later time. + *

+ * When using this method, be sure to use {@link Looper#quitSafely} when + * quitting the looper. Otherwise {@link #runWithScissors} may hang indefinitely. + * (TODO: We should fix this by making MessageQueue aware of blocking runnables.) + *

* * @param r The Runnable that will be executed synchronously. * @param timeout The timeout in milliseconds, or 0 to wait indefinitely. diff --git a/core/java/android/os/HandlerThread.java b/core/java/android/os/HandlerThread.java index daf1f59335205..2904105ef7827 100644 --- a/core/java/android/os/HandlerThread.java +++ b/core/java/android/os/HandlerThread.java @@ -48,6 +48,7 @@ public class HandlerThread extends Thread { protected void onLooperPrepared() { } + @Override public void run() { mTid = Process.myTid(); Looper.prepare(); @@ -83,12 +84,25 @@ public class HandlerThread extends Thread { } return mLooper; } - + /** - * Ask the currently running looper to quit. If the thread has not - * been started or has finished (that is if {@link #getLooper} returns - * null), then false is returned. Otherwise the looper is asked to - * quit and true is returned. + * Quits the handler thread's looper. + *

+ * Causes the handler thread's looper to terminate without processing any + * more messages in the message queue. + *

+ * Any attempt to post messages to the queue after the looper is asked to quit will fail. + * For example, the {@link Handler#sendMessage(Message)} method will return false. + *

+ * Using this method may be unsafe because some messages may not be delivered + * before the looper terminates. Consider using {@link #quitSafely} instead to ensure + * that all pending work is completed in an orderly manner. + *

+ * + * @return True if the looper looper has been asked to quit or false if the + * thread had not yet started running. + * + * @see #quitSafely */ public boolean quit() { Looper looper = getLooper(); @@ -98,7 +112,34 @@ public class HandlerThread extends Thread { } return false; } - + + /** + * Quits the handler thread's looper safely. + *

+ * Causes the handler thread's looper to terminate as soon as all remaining messages + * in the message queue that are already due to be delivered have been handled. + * Pending delayed messages with due times in the future will not be delivered. + *

+ * Any attempt to post messages to the queue after the looper is asked to quit will fail. + * For example, the {@link Handler#sendMessage(Message)} method will return false. + *

+ * If the thread has not been started or has finished (that is if + * {@link #getLooper} returns null), then false is returned. + * Otherwise the looper is asked to quit and true is returned. + *

+ * + * @return True if the looper looper has been asked to quit or false if the + * thread had not yet started running. + */ + public boolean quitSafely() { + Looper looper = getLooper(); + if (looper != null) { + looper.quitSafely(); + return true; + } + return false; + } + /** * Returns the identifier of this thread. See Process.myTid(). */ diff --git a/core/java/android/os/Looper.java b/core/java/android/os/Looper.java index fa28765206f0b..d5cf771a22bc1 100644 --- a/core/java/android/os/Looper.java +++ b/core/java/android/os/Looper.java @@ -202,18 +202,37 @@ public final class Looper { /** * Quits the looper. *

- * Causes the {@link #loop} method to terminate as soon as all remaining messages - * in the message queue that are already due to be delivered have been handled. - * However delayed messages with due times in the future may not be handled before - * the loop terminates. + * Causes the {@link #loop} method to terminate without processing any + * more messages in the message queue. *

- * Any attempt to post messages to the queue after {@link #quit} has been called - * will fail. For example, the {@link Handler#sendMessage(Message)} method will - * return false when the looper is being terminated. + * Any attempt to post messages to the queue after the looper is asked to quit will fail. + * For example, the {@link Handler#sendMessage(Message)} method will return false. + *

+ * Using this method may be unsafe because some messages may not be delivered + * before the looper terminates. Consider using {@link #quitSafely} instead to ensure + * that all pending work is completed in an orderly manner. *

+ * + * @see #quitSafely */ public void quit() { - mQueue.quit(); + mQueue.quit(false); + } + + /** + * Quits the looper safely. + *

+ * Causes the {@link #loop} method to terminate as soon as all remaining messages + * in the message queue that are already due to be delivered have been handled. + * However pending delayed messages with due times in the future will not be + * delivered before the loop terminates. + *

+ * Any attempt to post messages to the queue after the looper is asked to quit will fail. + * For example, the {@link Handler#sendMessage(Message)} method will return false. + *

+ */ + public void quitSafely() { + mQueue.quit(true); } /** diff --git a/core/java/android/os/MessageQueue.java b/core/java/android/os/MessageQueue.java index c058bfce28e65..bf7e5caf7024c 100644 --- a/core/java/android/os/MessageQueue.java +++ b/core/java/android/os/MessageQueue.java @@ -219,7 +219,7 @@ public final class MessageQueue { } } - void quit() { + void quit(boolean safe) { if (!mQuitAllowed) { throw new RuntimeException("Main thread not allowed to quit."); } @@ -229,6 +229,12 @@ public final class MessageQueue { return; } mQuiting = true; + + if (safe) { + removeAllFutureMessagesLocked(); + } else { + removeAllMessagesLocked(); + } } nativeWake(mPtr); } @@ -473,4 +479,42 @@ public final class MessageQueue { } } } + + private void removeAllMessagesLocked() { + Message p = mMessages; + while (p != null) { + Message n = p.next; + p.recycle(); + p = n; + } + mMessages = null; + } + + private void removeAllFutureMessagesLocked() { + final long now = SystemClock.uptimeMillis(); + Message p = mMessages; + if (p != null) { + if (p.when > now) { + removeAllMessagesLocked(); + } else { + Message n; + for (;;) { + n = p.next; + if (n == null) { + return; + } + if (n.when > now) { + break; + } + p = n; + } + p.next = null; + do { + p = n; + n = p.next; + p.recycle(); + } while (n != null); + } + } + } } diff --git a/opengl/java/android/opengl/GLSurfaceView.java b/opengl/java/android/opengl/GLSurfaceView.java index ab7ceb61dbce2..22f010689aa4f 100644 --- a/opengl/java/android/opengl/GLSurfaceView.java +++ b/opengl/java/android/opengl/GLSurfaceView.java @@ -246,7 +246,7 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback if (mGLThread != null) { // GLThread may still be running if this view was never // attached to a window. - mGLThread.requestExitAndWait(); + mGLThread.quitSafely(); } } finally { super.finalize(); @@ -627,7 +627,11 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback Log.d(TAG, "onDetachedFromWindow"); } if (mGLThread != null) { - mGLThread.requestExitAndWait(); + mGLThread.quitSafely(); + try { + mGLThread.join(); + } catch (InterruptedException ex) { + } } mDetached = true; super.onDetachedFromWindow(); @@ -1607,12 +1611,9 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback }, 0); } - public void requestExitAndWait() { - getLooper().quit(); - try { - this.join(); - } catch (InterruptedException e) { - } + public int getRenderMode() { + mGLHandler.runWithScissors(mGetRenderModeRunnable, 0); + return mGetRenderModeRunnable.renderMode; } } // class GLThread From 989a40a304c137e7fc37cb0ca53ed3df5d72be17 Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Thu, 18 Apr 2013 13:52:58 -0700 Subject: [PATCH 08/12] don't trigger a render when setting the rendermode also don't cache the rendermode, to mimic the older behaviour. Bug: 8656076 Change-Id: Id9383852bed073927db2364f7ac30a1be28b4cd8 Conflicts: opengl/java/android/opengl/GLSurfaceView.java --- opengl/java/android/opengl/GLSurfaceView.java | 32 ++++++++++++++----- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/opengl/java/android/opengl/GLSurfaceView.java b/opengl/java/android/opengl/GLSurfaceView.java index 22f010689aa4f..dac3506e09232 100644 --- a/opengl/java/android/opengl/GLSurfaceView.java +++ b/opengl/java/android/opengl/GLSurfaceView.java @@ -184,7 +184,6 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback private int mDebugFlags; private int mEGLContextClientVersion; private boolean mPreserveEGLContextOnPause; - private int mUserRenderMode; /** * The renderer only renders @@ -258,7 +257,6 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback // underlying surface is created and destroyed SurfaceHolder holder = getHolder(); holder.addCallback(this); - mUserRenderMode = RENDERMODE_CONTINUOUSLY; } /** @@ -516,7 +514,6 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback default: throw new IllegalArgumentException("renderMode"); } - mUserRenderMode = renderMode; mGLThread.setRenderMode(renderMode); } @@ -528,7 +525,7 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback * @see #RENDERMODE_WHEN_DIRTY */ public int getRenderMode() { - return mUserRenderMode; + return mGLThread.getRenderMode(); } /** @@ -608,9 +605,13 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback if (LOG_ATTACH_DETACH) { Log.d(TAG, "onAttachedToWindow reattach =" + mDetached); } + + final int renderMode = mGLThread != null ? + mGLThread.mRenderMode : RENDERMODE_CONTINUOUSLY; + if (mDetached && (mRenderer != null)) { mGLThread = new GLThread(mThisWeakRef); - mGLThread.setRenderMode(mUserRenderMode); + mGLThread.setRenderMode(renderMode); mGLThread.start(); } mDetached = false; @@ -1265,6 +1266,17 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback private Handler mGLHandler; private Choreographer mChoreographer; + // this runnable could be called often, so we keep an instance around + class GetRenderModeRunnable implements Runnable { + volatile public int renderMode; + @Override + public void run() { + renderMode = doGetRenderMode(); + } + }; + + private final GetRenderModeRunnable mGetRenderModeRunnable = new GetRenderModeRunnable(); + /* * Set once at thread construction time, nulled out when the parent view is garbage * called. This weak reference allows the GLSurfaceView to be garbage collected while @@ -1515,7 +1527,7 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback } } - private void doWindowResize(final int width, final int height) { + private void doWindowResize(int width, int height) { // we were not drawing yet. Update the window size and // state and attempt to draw a frame. mSizeChanged = (mWidth != width || mHeight != height); @@ -1526,9 +1538,13 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback executeDraw(); } - private void doSetRenderMode(final int renderMode) { + private void doSetRenderMode(int renderMode) { mRenderMode = renderMode; - requestRender(); + } + + + private int doGetRenderMode() { + return mRenderMode; } /* From 428b063a2e1f5c9bb8caf560e770ea5f9d5fde02 Mon Sep 17 00:00:00 2001 From: Irfan Sheriff Date: Thu, 25 Apr 2013 23:22:41 -0700 Subject: [PATCH 09/12] Fix network reload when config is restored With scan mode opted in, supplicant connection is not shut down even when wifi is turned off. This is a problem since networks need to be reloaded when wifi is turned off and turned on and this currently happens only on a supplicant connection. Fix to handle this for scan mode state. Bug: 8714796 Change-Id: I7d66c39fb51018fb52e783341222cea993993893 --- wifi/java/android/net/wifi/WifiConfigStore.java | 2 +- wifi/java/android/net/wifi/WifiStateMachine.java | 9 +++++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/wifi/java/android/net/wifi/WifiConfigStore.java b/wifi/java/android/net/wifi/WifiConfigStore.java index 23a4e716a4b61..9418de1f7c6a8 100644 --- a/wifi/java/android/net/wifi/WifiConfigStore.java +++ b/wifi/java/android/net/wifi/WifiConfigStore.java @@ -156,7 +156,7 @@ class WifiConfigStore { * Fetch the list of configured networks * and enable all stored networks in supplicant. */ - void initialize() { + void loadAndEnableAllNetworks() { if (DBG) log("Loading config and enabling all networks"); loadConfiguredNetworks(); enableAllNetworks(); diff --git a/wifi/java/android/net/wifi/WifiStateMachine.java b/wifi/java/android/net/wifi/WifiStateMachine.java index 2c3df9516a179..9cae2cb9e32f8 100644 --- a/wifi/java/android/net/wifi/WifiStateMachine.java +++ b/wifi/java/android/net/wifi/WifiStateMachine.java @@ -1111,6 +1111,7 @@ public class WifiStateMachine extends StateMachine { pw.println("mUserWantsSuspendOpt " + mUserWantsSuspendOpt); pw.println("mSuspendOptNeedsDisabled " + mSuspendOptNeedsDisabled); pw.println("Supplicant status " + mWifiNative.status()); + pw.println("mEnableBackgroundScan " + mEnableBackgroundScan); pw.println(); mWifiConfigStore.dump(fd, pw, args); } @@ -2121,7 +2122,7 @@ public class WifiStateMachine extends StateMachine { mLastSignalLevel = -1; mWifiInfo.setMacAddress(mWifiNative.getMacAddress()); - mWifiConfigStore.initialize(); + mWifiConfigStore.loadAndEnableAllNetworks(); initializeWpsDetails(); sendSupplicantConnectionChangedBroadcast(true); @@ -2657,9 +2658,13 @@ public class WifiStateMachine extends StateMachine { public void exit() { if (mLastOperationMode == SCAN_ONLY_WITH_WIFI_OFF_MODE) { setWifiState(WIFI_STATE_ENABLED); + // Load and re-enable networks when going back to enabled state + // This is essential for networks to show up after restore + mWifiConfigStore.loadAndEnableAllNetworks(); mWifiP2pChannel.sendMessage(CMD_ENABLE_P2P); + } else { + mWifiConfigStore.enableAllNetworks(); } - mWifiConfigStore.enableAllNetworks(); mWifiNative.reconnect(); } @Override From b5a75b20aa276932dc2cb5131e7d7720e1e41822 Mon Sep 17 00:00:00 2001 From: Daniel Sandler Date: Wed, 8 May 2013 15:57:06 -0400 Subject: [PATCH 10/12] Exempt the notification panel from animation lockout. We do a lot of launch-app-then-collapse, and it's a game to see whether the app's window activity animation starts before the panel has a chance to finish collapsing. The winning move here is not to play. Requires change I2773601d in f/b. Bug: 8666124 Change-Id: I3e3f1c5a4a505ad7d487c804139445ffd499d8d4 --- .../systemui/statusbar/phone/StatusBarWindowView.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java index f526f0c6f988e..5620e1b35ab4a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java @@ -24,6 +24,7 @@ import android.util.Log; import android.view.KeyEvent; import android.view.MotionEvent; import android.view.View; +import android.view.ViewRootImpl; import android.widget.FrameLayout; import android.widget.ScrollView; import android.widget.TextSwitcher; @@ -63,6 +64,13 @@ public class StatusBarWindowView extends FrameLayout mExpandHelper = new ExpandHelper(mContext, latestItems, minHeight, maxHeight); mExpandHelper.setEventSource(this); mExpandHelper.setScrollView(mScrollView); + + // We really need to be able to animate while window animations are going on + // so that activities may be started asynchronously from panel animations + final ViewRootImpl root = getViewRootImpl(); + if (root != null) { + root.setDrawDuringWindowsAnimating(true); + } } @Override From e1c0cbcd55ffffac4b5be78d8ed8d25315353af1 Mon Sep 17 00:00:00 2001 From: Matthew Xie Date: Wed, 8 May 2013 19:26:57 -0700 Subject: [PATCH 11/12] Donot bind to GATT service when BLE is not supported bug 8664724 Change-Id: I9b9222cd5877babcded73798a5d1ff13fd10e791 --- core/java/android/bluetooth/BluetoothAdapter.java | 6 +++++- core/java/android/bluetooth/BluetoothDevice.java | 4 ++++ .../com/android/server/BluetoothManagerService.java | 12 ++++++++---- 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java index cfbfb48d4a1fe..7ec73ef741357 100644 --- a/core/java/android/bluetooth/BluetoothAdapter.java +++ b/core/java/android/bluetooth/BluetoothAdapter.java @@ -1472,9 +1472,13 @@ public final class BluetoothAdapter { try { IBluetoothGatt iGatt = mManagerService.getBluetoothGatt(); + if (iGatt == null) { + // BLE is not supported + return false; + } + UUID uuid = UUID.randomUUID(); GattCallbackWrapper wrapper = new GattCallbackWrapper(this, callback, serviceUuids); - iGatt.registerClient(new ParcelUuid(uuid), wrapper); if (wrapper.scanStarted()) { mLeScanClients.put(callback, wrapper); diff --git a/core/java/android/bluetooth/BluetoothDevice.java b/core/java/android/bluetooth/BluetoothDevice.java index 3c1ec90f19c3a..79a5ffea46ab2 100644 --- a/core/java/android/bluetooth/BluetoothDevice.java +++ b/core/java/android/bluetooth/BluetoothDevice.java @@ -1187,6 +1187,10 @@ public final class BluetoothDevice implements Parcelable { IBluetoothManager managerService = adapter.getBluetoothManager(); try { IBluetoothGatt iGatt = managerService.getBluetoothGatt(); + if (iGatt == null) { + // BLE is not supported + return null; + } BluetoothGatt gatt = new BluetoothGatt(context, iGatt, this); gatt.connect(autoConnect, callback); return gatt; diff --git a/services/java/com/android/server/BluetoothManagerService.java b/services/java/com/android/server/BluetoothManagerService.java index ea7b696f68b51..f7a7fdf5a41a6 100644 --- a/services/java/com/android/server/BluetoothManagerService.java +++ b/services/java/com/android/server/BluetoothManagerService.java @@ -31,6 +31,7 @@ import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.ServiceConnection; +import android.content.pm.PackageManager; import android.os.Binder; import android.os.Handler; import android.os.HandlerThread; @@ -1092,10 +1093,13 @@ class BluetoothManagerService extends IBluetoothManager.Stub { if (isUp) { // connect to GattService - Intent i = new Intent(IBluetoothGatt.class.getName()); - if (!mContext.bindServiceAsUser(i, mConnection, Context.BIND_AUTO_CREATE, - UserHandle.CURRENT)) { - Log.e(TAG, "Fail to bind to: " + IBluetoothGatt.class.getName()); + if (mContext.getPackageManager().hasSystemFeature( + PackageManager.FEATURE_BLUETOOTH_LE)) { + Intent i = new Intent(IBluetoothGatt.class.getName()); + if (!mContext.bindServiceAsUser(i, mConnection, Context.BIND_AUTO_CREATE, + UserHandle.CURRENT)) { + Log.e(TAG, "Fail to bind to: " + IBluetoothGatt.class.getName()); + } } } else { //If Bluetooth is off, send service down event to proxy objects, and unbind From d8bc100ae11a307a4a8c519b5f5c7fe6473a8837 Mon Sep 17 00:00:00 2001 From: Jeff Brown Date: Thu, 9 May 2013 13:41:11 -0700 Subject: [PATCH 12/12] Fix bug managing wifi display routes. We could sometimes crash due to some inconsistencies in the way the wifi display routes were updates when connecting, disconnecting or scanning wifi displays. Bug: 8837094 Change-Id: I10c7ccb163ec33c4ea107dfcb5074741049fe955 --- media/java/android/media/MediaRouter.java | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/media/java/android/media/MediaRouter.java b/media/java/android/media/MediaRouter.java index 61c55a58e5efe..9e8aeeb8a6e81 100644 --- a/media/java/android/media/MediaRouter.java +++ b/media/java/android/media/MediaRouter.java @@ -783,25 +783,21 @@ public class MediaRouter { for (int i = 0; i < newDisplays.length; i++) { final WifiDisplay d = newDisplays[i]; - final WifiDisplay oldRemembered = findMatchingDisplay(d, oldDisplays); - if (oldRemembered == null) { - addRouteStatic(makeWifiDisplayRoute(d, - findMatchingDisplay(d, availableDisplays) != null)); + final boolean available = findMatchingDisplay(d, availableDisplays) != null; + RouteInfo route = findWifiDisplayRoute(d); + if (route == null) { + route = makeWifiDisplayRoute(d, available); + addRouteStatic(route); wantScan = true; } else { - final boolean available = findMatchingDisplay(d, availableDisplays) != null; - final RouteInfo route = findWifiDisplayRoute(d); updateWifiDisplayRoute(route, d, available, newStatus); } if (d.equals(activeDisplay)) { - final RouteInfo activeRoute = findWifiDisplayRoute(d); - if (activeRoute != null) { - selectRouteStatic(activeRoute.getSupportedTypes(), activeRoute); + selectRouteStatic(route.getSupportedTypes(), route); - // Don't scan if we're already connected to a wifi display, - // the scanning process can cause a hiccup with some configurations. - blockScan = true; - } + // Don't scan if we're already connected to a wifi display, + // the scanning process can cause a hiccup with some configurations. + blockScan = true; } } for (int i = 0; i < oldDisplays.length; i++) {