Merge change 3008 into donut

* changes:
  adb: Workaround for adb disconnect problem.
diff --git a/include/cutils/ashmem.h b/include/cutils/ashmem.h
index fd71352..0683bf2 100644
--- a/include/cutils/ashmem.h
+++ b/include/cutils/ashmem.h
@@ -18,6 +18,7 @@
 int ashmem_set_prot_region(int fd, int prot);
 int ashmem_pin_region(int fd, size_t offset, size_t len);
 int ashmem_unpin_region(int fd, size_t offset, size_t len);
+int ashmem_get_size_region(int fd);
 
 #ifdef __cplusplus
 }
diff --git a/libcutils/ashmem-dev.c b/libcutils/ashmem-dev.c
index 5e158af..8b71f87 100644
--- a/libcutils/ashmem-dev.c
+++ b/libcutils/ashmem-dev.c
@@ -83,3 +83,8 @@
 	struct ashmem_pin pin = { offset, len };
 	return ioctl(fd, ASHMEM_UNPIN, &pin);
 }
+
+int ashmem_get_size_region(int fd)
+{
+  return ioctl(fd, ASHMEM_GET_SIZE, NULL);
+}
diff --git a/libcutils/ashmem-host.c b/libcutils/ashmem-host.c
index dbb52bc..f03e130 100644
--- a/libcutils/ashmem-host.c
+++ b/libcutils/ashmem-host.c
@@ -92,3 +92,23 @@
 {
 	return ASHMEM_IS_UNPINNED;
 }
+
+int ashmem_get_size_region(int fd)
+{
+        struct stat buf;
+        int result;
+
+        result = fstat(fd, &buf);
+        if (result == -1) {
+                return -1;
+        }
+
+        // Check if this is an "ashmem" region.
+        // TODO: This is very hacky, and can easily break. We need some reliable indicator.
+        if (!(buf.st_nlink == 0 && S_ISREG(buf.st_mode))) {
+                errno = ENOTTY;
+                return -1;
+        }
+
+        return (int)buf.st_size;  // TODO: care about overflow (> 2GB file)?
+}
diff --git a/libpixelflinger/codeflinger/ARMAssembler.h b/libpixelflinger/codeflinger/ARMAssembler.h
index 8837e07..ef3b66a 100644
--- a/libpixelflinger/codeflinger/ARMAssembler.h
+++ b/libpixelflinger/codeflinger/ARMAssembler.h
@@ -21,8 +21,9 @@
 #include <stdint.h>
 #include <sys/types.h>
 
-#include <utils/Vector.h>
-#include <utils/KeyedVector.h>
+#include "tinyutils/Vector.h"
+#include "tinyutils/KeyedVector.h"
+#include "tinyutils/smartpointer.h"
 
 #include "tinyutils/smartpointer.h"
 #include "codeflinger/ARMAssemblerInterface.h"
diff --git a/libpixelflinger/codeflinger/CodeCache.h b/libpixelflinger/codeflinger/CodeCache.h
index 370ce17..8ff1366 100644
--- a/libpixelflinger/codeflinger/CodeCache.h
+++ b/libpixelflinger/codeflinger/CodeCache.h
@@ -23,8 +23,7 @@
 #include <pthread.h>
 #include <sys/types.h>
 
-#include <utils/KeyedVector.h>
-
+#include "tinyutils/KeyedVector.h"
 #include "tinyutils/smartpointer.h"
 
 namespace android {
diff --git a/libpixelflinger/tinyutils/Errors.h b/libpixelflinger/tinyutils/Errors.h
new file mode 100644
index 0000000..b9fd5f4
--- /dev/null
+++ b/libpixelflinger/tinyutils/Errors.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_ERRORS_H
+#define ANDROID_ERRORS_H
+
+#include <sys/types.h>
+#include <errno.h>
+
+namespace android {
+
+// use this type to return error codes
+typedef int32_t     status_t;
+
+/*
+ * Error codes. 
+ * All error codes are negative values.
+ */
+
+enum {
+    OK                = 0,    // Everything's swell.
+    NO_ERROR          = 0,    // No errors.
+    
+    UNKNOWN_ERROR       = 0x80000000,
+
+    NO_MEMORY           = -ENOMEM,
+    INVALID_OPERATION   = -ENOSYS,
+    BAD_VALUE           = -EINVAL,
+    BAD_TYPE            = 0x80000001,
+    NAME_NOT_FOUND      = -ENOENT,
+    PERMISSION_DENIED   = -EPERM,
+    NO_INIT             = -ENODEV,
+    ALREADY_EXISTS      = -EEXIST,
+    DEAD_OBJECT         = -EPIPE,
+    FAILED_TRANSACTION  = 0x80000002,
+    JPARKS_BROKE_IT     = -EPIPE,
+    BAD_INDEX           = -EOVERFLOW,
+    NOT_ENOUGH_DATA     = -ENODATA,
+    WOULD_BLOCK         = -EWOULDBLOCK, 
+    TIMED_OUT           = -ETIME,
+    UNKNOWN_TRANSACTION = -EBADMSG,
+};
+
+
+}; // namespace android
+    
+// ---------------------------------------------------------------------------
+    
+#endif // ANDROID_ERRORS_H
diff --git a/libpixelflinger/tinyutils/SortedVector.h b/libpixelflinger/tinyutils/SortedVector.h
new file mode 100644
index 0000000..7a6b443
--- /dev/null
+++ b/libpixelflinger/tinyutils/SortedVector.h
@@ -0,0 +1,282 @@
+/*
+ * Copyright (C) 2005 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_SORTED_VECTOR_H
+#define ANDROID_SORTED_VECTOR_H
+
+#include <assert.h>
+#include <stdint.h>
+#include <sys/types.h>
+
+#include "tinyutils/Vector.h"
+#include "tinyutils/VectorImpl.h"
+#include "tinyutils/TypeHelpers.h"
+
+// ---------------------------------------------------------------------------
+
+namespace android {
+
+template <class TYPE>
+class SortedVector : private SortedVectorImpl
+{
+public:
+            typedef TYPE    value_type;
+    
+    /*! 
+     * Constructors and destructors
+     */
+    
+                            SortedVector();
+                            SortedVector(const SortedVector<TYPE>& rhs);
+    virtual                 ~SortedVector();
+
+    /*! copy operator */
+    const SortedVector<TYPE>&   operator = (const SortedVector<TYPE>& rhs) const;    
+    SortedVector<TYPE>&         operator = (const SortedVector<TYPE>& rhs);    
+
+    /*
+     * empty the vector
+     */
+
+    inline  void            clear()             { VectorImpl::clear(); }
+
+    /*! 
+     * vector stats
+     */
+
+    //! returns number of items in the vector
+    inline  size_t          size() const                { return VectorImpl::size(); }
+    //! returns wether or not the vector is empty
+    inline  bool            isEmpty() const             { return VectorImpl::isEmpty(); }
+    //! returns how many items can be stored without reallocating the backing store
+    inline  size_t          capacity() const            { return VectorImpl::capacity(); }
+    //! setst the capacity. capacity can never be reduced less than size()
+    inline  ssize_t         setCapacity(size_t size)    { return VectorImpl::setCapacity(size); }
+
+    /*! 
+     * C-style array access
+     */
+     
+    //! read-only C-style access 
+    inline  const TYPE*     array() const;
+
+    //! read-write C-style access. BE VERY CAREFUL when modifying the array
+    //! you ust keep it sorted! You usually don't use this function.
+            TYPE*           editArray();
+
+            //! finds the index of an item
+            ssize_t         indexOf(const TYPE& item) const;
+            
+            //! finds where this item should be inserted
+            size_t          orderOf(const TYPE& item) const;
+            
+    
+    /*! 
+     * accessors
+     */
+
+    //! read-only access to an item at a given index
+    inline  const TYPE&     operator [] (size_t index) const;
+    //! alternate name for operator []
+    inline  const TYPE&     itemAt(size_t index) const;
+    //! stack-usage of the vector. returns the top of the stack (last element)
+            const TYPE&     top() const;
+    //! same as operator [], but allows to access the vector backward (from the end) with a negative index
+            const TYPE&     mirrorItemAt(ssize_t index) const;
+
+    /*!
+     * modifing the array
+     */
+
+            //! add an item in the right place (and replace the one that is there)
+            ssize_t         add(const TYPE& item);
+            
+            //! editItemAt() MUST NOT change the order of this item
+            TYPE&           editItemAt(size_t index) {
+                return *( static_cast<TYPE *>(VectorImpl::editItemLocation(index)) );
+            }
+
+            //! merges a vector into this one
+            ssize_t         merge(const Vector<TYPE>& vector);
+            ssize_t         merge(const SortedVector<TYPE>& vector);
+            
+            //! removes an item
+            ssize_t         remove(const TYPE&);
+
+    //! remove several items
+    inline  ssize_t         removeItemsAt(size_t index, size_t count = 1);
+    //! remove one item
+    inline  ssize_t         removeAt(size_t index)  { return removeItemsAt(index); }
+            
+protected:
+    virtual void    do_construct(void* storage, size_t num) const;
+    virtual void    do_destroy(void* storage, size_t num) const;
+    virtual void    do_copy(void* dest, const void* from, size_t num) const;
+    virtual void    do_splat(void* dest, const void* item, size_t num) const;
+    virtual void    do_move_forward(void* dest, const void* from, size_t num) const;
+    virtual void    do_move_backward(void* dest, const void* from, size_t num) const;
+    virtual int     do_compare(const void* lhs, const void* rhs) const;
+};
+
+
+// ---------------------------------------------------------------------------
+// No user serviceable parts from here...
+// ---------------------------------------------------------------------------
+
+template<class TYPE> inline
+SortedVector<TYPE>::SortedVector()
+    : SortedVectorImpl(sizeof(TYPE),
+                ((traits<TYPE>::has_trivial_ctor   ? HAS_TRIVIAL_CTOR   : 0)
+                |(traits<TYPE>::has_trivial_dtor   ? HAS_TRIVIAL_DTOR   : 0)
+                |(traits<TYPE>::has_trivial_copy   ? HAS_TRIVIAL_COPY   : 0)
+                |(traits<TYPE>::has_trivial_assign ? HAS_TRIVIAL_ASSIGN : 0))
+                )
+{
+}
+
+template<class TYPE> inline
+SortedVector<TYPE>::SortedVector(const SortedVector<TYPE>& rhs)
+    : SortedVectorImpl(rhs) {
+}
+
+template<class TYPE> inline
+SortedVector<TYPE>::~SortedVector() {
+    finish_vector();
+}
+
+template<class TYPE> inline
+SortedVector<TYPE>& SortedVector<TYPE>::operator = (const SortedVector<TYPE>& rhs) {
+    SortedVectorImpl::operator = (rhs);
+    return *this; 
+}
+
+template<class TYPE> inline
+const SortedVector<TYPE>& SortedVector<TYPE>::operator = (const SortedVector<TYPE>& rhs) const {
+    SortedVectorImpl::operator = (rhs);
+    return *this; 
+}
+
+template<class TYPE> inline
+const TYPE* SortedVector<TYPE>::array() const {
+    return static_cast<const TYPE *>(arrayImpl());
+}
+
+template<class TYPE> inline
+TYPE* SortedVector<TYPE>::editArray() {
+    return static_cast<TYPE *>(editArrayImpl());
+}
+
+
+template<class TYPE> inline
+const TYPE& SortedVector<TYPE>::operator[](size_t index) const {
+    assert( index<size() );
+    return *(array() + index);
+}
+
+template<class TYPE> inline
+const TYPE& SortedVector<TYPE>::itemAt(size_t index) const {
+    return operator[](index);
+}
+
+template<class TYPE> inline
+const TYPE& SortedVector<TYPE>::mirrorItemAt(ssize_t index) const {
+    assert( (index>0 ? index : -index)<size() );
+    return *(array() + ((index<0) ? (size()-index) : index));
+}
+
+template<class TYPE> inline
+const TYPE& SortedVector<TYPE>::top() const {
+    return *(array() + size() - 1);
+}
+
+template<class TYPE> inline
+ssize_t SortedVector<TYPE>::add(const TYPE& item) {
+    return SortedVectorImpl::add(&item);
+}
+
+template<class TYPE> inline
+ssize_t SortedVector<TYPE>::indexOf(const TYPE& item) const {
+    return SortedVectorImpl::indexOf(&item);
+}
+
+template<class TYPE> inline
+size_t SortedVector<TYPE>::orderOf(const TYPE& item) const {
+    return SortedVectorImpl::orderOf(&item);
+}
+
+template<class TYPE> inline
+ssize_t SortedVector<TYPE>::merge(const Vector<TYPE>& vector) {
+    return SortedVectorImpl::merge(reinterpret_cast<const VectorImpl&>(vector));
+}
+
+template<class TYPE> inline
+ssize_t SortedVector<TYPE>::merge(const SortedVector<TYPE>& vector) {
+    return SortedVectorImpl::merge(reinterpret_cast<const SortedVectorImpl&>(vector));
+}
+
+template<class TYPE> inline
+ssize_t SortedVector<TYPE>::remove(const TYPE& item) {
+    return SortedVectorImpl::remove(&item);
+}
+
+template<class TYPE> inline
+ssize_t SortedVector<TYPE>::removeItemsAt(size_t index, size_t count) {
+    return VectorImpl::removeItemsAt(index, count);
+}
+
+// ---------------------------------------------------------------------------
+
+template<class TYPE>
+void SortedVector<TYPE>::do_construct(void* storage, size_t num) const {
+    construct_type( reinterpret_cast<TYPE*>(storage), num );
+}
+
+template<class TYPE>
+void SortedVector<TYPE>::do_destroy(void* storage, size_t num) const {
+    destroy_type( reinterpret_cast<TYPE*>(storage), num );
+}
+
+template<class TYPE>
+void SortedVector<TYPE>::do_copy(void* dest, const void* from, size_t num) const {
+    copy_type( reinterpret_cast<TYPE*>(dest), reinterpret_cast<const TYPE*>(from), num );
+}
+
+template<class TYPE>
+void SortedVector<TYPE>::do_splat(void* dest, const void* item, size_t num) const {
+    splat_type( reinterpret_cast<TYPE*>(dest), reinterpret_cast<const TYPE*>(item), num );
+}
+
+template<class TYPE>
+void SortedVector<TYPE>::do_move_forward(void* dest, const void* from, size_t num) const {
+    move_forward_type( reinterpret_cast<TYPE*>(dest), reinterpret_cast<const TYPE*>(from), num );
+}
+
+template<class TYPE>
+void SortedVector<TYPE>::do_move_backward(void* dest, const void* from, size_t num) const {
+    move_backward_type( reinterpret_cast<TYPE*>(dest), reinterpret_cast<const TYPE*>(from), num );
+}
+
+template<class TYPE>
+int SortedVector<TYPE>::do_compare(const void* lhs, const void* rhs) const {
+    return compare_type( *reinterpret_cast<const TYPE*>(lhs), *reinterpret_cast<const TYPE*>(rhs) );
+}
+
+}; // namespace android
+
+
+// ---------------------------------------------------------------------------
+
+#endif // ANDROID_SORTED_VECTOR_H
diff --git a/libpixelflinger/tinyutils/Vector.h b/libpixelflinger/tinyutils/Vector.h
index 182bc7b..14cf99a 100644
--- a/libpixelflinger/tinyutils/Vector.h
+++ b/libpixelflinger/tinyutils/Vector.h
@@ -15,6 +15,7 @@
 
 #include <cutils/log.h>
 
+#include "tinyutils/Errors.h"
 #include "tinyutils/VectorImpl.h"
 #include "tinyutils/TypeHelpers.h"
 
@@ -302,16 +303,6 @@
     return VectorImpl::removeItemsAt(index, count);
 }
 
-template<class TYPE> inline
-status_t Vector<TYPE>::sort(Vector<TYPE>::compar_t cmp) {
-    return VectorImpl::sort((VectorImpl::compar_t)cmp);
-}
-
-template<class TYPE> inline
-status_t Vector<TYPE>::sort(Vector<TYPE>::compar_r_t cmp, void* state) {
-    return VectorImpl::sort((VectorImpl::compar_r_t)cmp, state);
-}
-
 // ---------------------------------------------------------------------------
 
 template<class TYPE>
diff --git a/nexus/Android.mk b/nexus/Android.mk
index 1c4a394..bd4e3d4 100644
--- a/nexus/Android.mk
+++ b/nexus/Android.mk
@@ -32,7 +32,7 @@
 
 LOCAL_CFLAGS := 
 
-LOCAL_SHARED_LIBRARIES := libsysutils libwpa_client libutils
+LOCAL_SHARED_LIBRARIES := libsysutils libwpa_client
 
 include $(BUILD_EXECUTABLE)
 
@@ -46,7 +46,7 @@
 
 LOCAL_CFLAGS := 
 
-LOCAL_SHARED_LIBRARIES := libutils
+LOCAL_SHARED_LIBRARIES := libcutils
 
 include $(BUILD_EXECUTABLE)
 
diff --git a/nexus/ISupplicantEventHandler.h b/nexus/ISupplicantEventHandler.h
new file mode 100644
index 0000000..7e1bd5a
--- /dev/null
+++ b/nexus/ISupplicantEventHandler.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _ISUPPLICANT_EVENT_HANDLER_H
+#define _ISUPPLICANT_EVENT_HANDLER_H
+
+class ISupplicantEventHandler {
+public:
+    virtual int onConnectedEvent(SupplicantEvent *evt) = 0;
+    virtual int onDisconnectedEvent(SupplicantEvent *evt) = 0;
+    virtual int onTerminatingEvent(SupplicantEvent *evt) = 0;
+    virtual int onPasswordChangedEvent(SupplicantEvent *evt) = 0;
+    virtual int onEapNotificationEvent(SupplicantEvent *evt) = 0;
+    virtual int onEapStartedEvent(SupplicantEvent *evt) = 0;
+    virtual int onEapMethodEvent(SupplicantEvent *evt) = 0;
+    virtual int onEapSuccessEvent(SupplicantEvent *evt) = 0;
+    virtual int onEapFailureEvent(SupplicantEvent *evt) = 0;
+    virtual int onScanResultsEvent(SupplicantEvent *evt) = 0;
+    virtual int onStateChangeEvent(SupplicantEvent *evt) = 0;
+    virtual int onLinkSpeedEvent(SupplicantEvent *evt) = 0;
+    virtual int onDriverStateEvent(SupplicantEvent *evt) = 0;
+};
+
+#endif
+
diff --git a/nexus/Supplicant.h b/nexus/Supplicant.h
index 34ecdcf..42f2f79 100644
--- a/nexus/Supplicant.h
+++ b/nexus/Supplicant.h
@@ -30,8 +30,9 @@
 #include "ScanResult.h"
 #include "WifiNetwork.h"
 #include "IPropertyProvider.h"
+#include "ISupplicantEventHandler.h"
 
-class Supplicant : public IPropertyProvider {
+class Supplicant : public IPropertyProvider, public ISupplicantEventHandler {
 private:
     struct wpa_ctrl      *mCtrl;
     struct wpa_ctrl      *mMonitor;
@@ -77,9 +78,13 @@
     int set(const char *name, const char *value);
     const char *get(const char *name, char *buffer, size_t max);
 
-// XXX: Extract these into an interface
-// handlers for SupplicantListener
-public:
+private:
+    int connectToSupplicant();
+    int sendCommand(const char *cmd, char *reply, size_t *reply_len);
+    int setupConfig();
+    int retrieveInterfaceName();
+
+    // ISupplicantEventHandler methods
     virtual int onConnectedEvent(SupplicantEvent *evt);
     virtual int onDisconnectedEvent(SupplicantEvent *evt);
     virtual int onTerminatingEvent(SupplicantEvent *evt);
@@ -93,12 +98,6 @@
     virtual int onStateChangeEvent(SupplicantEvent *evt);
     virtual int onLinkSpeedEvent(SupplicantEvent *evt);
     virtual int onDriverStateEvent(SupplicantEvent *evt);
-
-private:
-    int connectToSupplicant();
-    int sendCommand(const char *cmd, char *reply, size_t *reply_len);
-    int setupConfig();
-    int retrieveInterfaceName();
 };
 
 #endif
diff --git a/nexus/SupplicantListener.cpp b/nexus/SupplicantListener.cpp
index 852eeb2..b94648b 100644
--- a/nexus/SupplicantListener.cpp
+++ b/nexus/SupplicantListener.cpp
@@ -23,13 +23,14 @@
 
 #include "libwpa_client/wpa_ctrl.h"
 
-#include "Supplicant.h"
 #include "SupplicantListener.h"
 #include "SupplicantEvent.h"
+#include "ISupplicantEventHandler.h"
 
-SupplicantListener::SupplicantListener(Supplicant *supplicant, struct wpa_ctrl *monitor) :
+SupplicantListener::SupplicantListener(ISupplicantEventHandler *handlers, 
+                                       struct wpa_ctrl *monitor) :
                     SocketListener(wpa_ctrl_get_fd(monitor), false) {
-    mSupplicant = supplicant;
+    mHandlers = handlers;
     mMonitor = monitor;
 }
 
@@ -58,29 +59,29 @@
     // XXX: Instead of calling Supplicant directly
     // extract an Interface and use that instead
     if (evt->getType() == SupplicantEvent::EVENT_CONNECTED)
-        rc = mSupplicant->onConnectedEvent(evt);
+        rc = mHandlers->onConnectedEvent(evt);
     else if (evt->getType() == SupplicantEvent::EVENT_DISCONNECTED)
-        rc = mSupplicant->onDisconnectedEvent(evt);
+        rc = mHandlers->onDisconnectedEvent(evt);
     else if (evt->getType() == SupplicantEvent::EVENT_TERMINATING)
-        rc = mSupplicant->onTerminatingEvent(evt);
+        rc = mHandlers->onTerminatingEvent(evt);
     else if (evt->getType() == SupplicantEvent::EVENT_PASSWORD_CHANGED)
-        rc = mSupplicant->onPasswordChangedEvent(evt);
+        rc = mHandlers->onPasswordChangedEvent(evt);
     else if (evt->getType() == SupplicantEvent::EVENT_EAP_NOTIFICATION)
-        rc = mSupplicant->onEapNotificationEvent(evt);
+        rc = mHandlers->onEapNotificationEvent(evt);
     else if (evt->getType() == SupplicantEvent::EVENT_EAP_STARTED)
-        rc = mSupplicant->onEapStartedEvent(evt);
+        rc = mHandlers->onEapStartedEvent(evt);
     else if (evt->getType() == SupplicantEvent::EVENT_EAP_SUCCESS)
-        rc = mSupplicant->onEapSuccessEvent(evt);
+        rc = mHandlers->onEapSuccessEvent(evt);
     else if (evt->getType() == SupplicantEvent::EVENT_EAP_FAILURE)
-        rc = mSupplicant->onEapFailureEvent(evt);
+        rc = mHandlers->onEapFailureEvent(evt);
     else if (evt->getType() == SupplicantEvent::EVENT_SCAN_RESULTS)
-        rc = mSupplicant->onScanResultsEvent(evt);
+        rc = mHandlers->onScanResultsEvent(evt);
     else if (evt->getType() == SupplicantEvent::EVENT_STATE_CHANGE)
-        rc = mSupplicant->onStateChangeEvent(evt);
+        rc = mHandlers->onStateChangeEvent(evt);
     else if (evt->getType() == SupplicantEvent::EVENT_LINK_SPEED)
-        rc = mSupplicant->onLinkSpeedEvent(evt);
+        rc = mHandlers->onLinkSpeedEvent(evt);
     else if (evt->getType() == SupplicantEvent::EVENT_DRIVER_STATE)
-        rc = mSupplicant->onDriverStateEvent(evt);
+        rc = mHandlers->onDriverStateEvent(evt);
     else {
         LOGW("Ignoring unknown event");
     }
diff --git a/nexus/SupplicantListener.h b/nexus/SupplicantListener.h
index 680a523..3d186ad 100644
--- a/nexus/SupplicantListener.h
+++ b/nexus/SupplicantListener.h
@@ -22,22 +22,22 @@
 struct wpa_ctrl;
 class Supplicant;
 class SocketClient;
+class ISupplicantEventHandler;
 
 class SupplicantListener: public SocketListener {
 private:
-    struct wpa_ctrl *mMonitor;
-    Supplicant      *mSupplicant;
+    struct wpa_ctrl         *mMonitor;
+    ISupplicantEventHandler *mHandlers;
 
 public:
-    SupplicantListener(Supplicant *supplicant, struct wpa_ctrl *monitor);
+    SupplicantListener(ISupplicantEventHandler *handlers,
+                       struct wpa_ctrl *monitor);
     virtual ~SupplicantListener() {}
 
     struct wpa_ctrl *getMonitor() { return mMonitor; }
-    Supplicant *getSupplicant() { return mSupplicant; }
 
 protected:
     virtual bool onDataAvailable(SocketClient *c);
-
 };
 
 #endif
diff --git a/nexus/WifiNetwork.cpp b/nexus/WifiNetwork.cpp
index 1f53a20..818b91d 100644
--- a/nexus/WifiNetwork.cpp
+++ b/nexus/WifiNetwork.cpp
@@ -551,6 +551,20 @@
 }
 
 int WifiNetwork::setEnabled(bool enabled) {
+
+    if (enabled) {
+        if (getPriority() == -1) {
+            LOGE("Cannot enable network when priority is not set");
+            errno = EAGAIN;
+            return -1;
+        }
+        if (getAllowedKeyManagement() == KeyManagementMask::UNKNOWN) {
+            LOGE("Cannot enable network when KeyManagement is not set");
+            errno = EAGAIN;
+            return -1;
+        }
+    }
+
     if (mSuppl->enableNetwork(mNetid, enabled))
         return -1;
 
diff --git a/nexus/WifiNetwork.h b/nexus/WifiNetwork.h
index bdffa8b..360ccc2 100644
--- a/nexus/WifiNetwork.h
+++ b/nexus/WifiNetwork.h
@@ -23,10 +23,11 @@
 
 class KeyManagementMask {
 public:
-    static const uint32_t NONE      = 0;
-    static const uint32_t WPA_PSK   = 0x01;
-    static const uint32_t WPA_EAP   = 0x02;
-    static const uint32_t IEEE8021X = 0x04;
+    static const uint32_t UNKNOWN   = 0;
+    static const uint32_t NONE      = 0x01;
+    static const uint32_t WPA_PSK   = 0x02;
+    static const uint32_t WPA_EAP   = 0x04;
+    static const uint32_t IEEE8021X = 0x08;
     static const uint32_t ALL       = WPA_PSK | WPA_EAP | IEEE8021X;
 };
 
diff --git a/vold/volmgr_vfat.c b/vold/volmgr_vfat.c
index 4013df8..2b0e1fa 100644
--- a/vold/volmgr_vfat.c
+++ b/vold/volmgr_vfat.c
@@ -110,7 +110,7 @@
     LOG_VOL("vfat_mount(%d:%d, %s, %d):", dev->major, dev->minor, vol->mount_point, safe_mode);
 #endif
 
-    flags = MS_NODEV | MS_NOEXEC | MS_NOSUID | MS_DIRSYNC | MS_SYNCHRONOUS;
+    flags = MS_NODEV | MS_NOEXEC | MS_NOSUID | MS_DIRSYNC;
 
     if (vol->state == volstate_mounted) {
         LOG_VOL("Remounting %d:%d on %s, safe mode %d", dev->major,