Merge change I3b1b7873 into eclair-mr2

* changes:
  New API to instantiate a MediaExtractor given a URI and optional MIME type.
diff --git a/services/java/com/android/server/WifiService.java b/services/java/com/android/server/WifiService.java
index 370ee68..0ea832b 100644
--- a/services/java/com/android/server/WifiService.java
+++ b/services/java/com/android/server/WifiService.java
@@ -142,6 +142,7 @@
     private static final int MESSAGE_STOP_WIFI        = 2;
     private static final int MESSAGE_START_WIFI       = 3;
     private static final int MESSAGE_RELEASE_WAKELOCK = 4;
+    private static final int MESSAGE_UPDATE_STATE     = 5;
 
     private final  WifiHandler mWifiHandler;
 
@@ -1446,6 +1447,11 @@
     }
 
     private void updateWifiState() {
+        // send a message so it's all serialized
+        Message.obtain(mWifiHandler, MESSAGE_UPDATE_STATE, 0, 0).sendToTarget();
+    }
+
+    private void doUpdateWifiState() {
         boolean wifiEnabled = getPersistedWifiEnabled();
         boolean airplaneMode = isAirplaneModeOn() && !mAirplaneModeOverwridden;
         boolean lockHeld = mLocks.hasLocks();
@@ -1551,6 +1557,10 @@
                     sWakeLock.release();
                     break;
 
+                case MESSAGE_UPDATE_STATE:
+                    doUpdateWifiState();
+                    break;
+
                 case MESSAGE_DISABLE_WIFI:
                     // a non-zero msg.arg1 value means the "enabled" setting
                     // should be persisted
diff --git a/telephony/java/android/telephony/PhoneNumberUtils.java b/telephony/java/android/telephony/PhoneNumberUtils.java
index a0a1b14..6b33f52aa 100644
--- a/telephony/java/android/telephony/PhoneNumberUtils.java
+++ b/telephony/java/android/telephony/PhoneNumberUtils.java
@@ -378,6 +378,8 @@
     compareLoosely(String a, String b) {
         int ia, ib;
         int matched;
+        int numNonDialableCharsInA = 0;
+        int numNonDialableCharsInB = 0;
 
         if (a == null || b == null) return a == b;
 
@@ -398,6 +400,7 @@
             if (!isDialable(ca)) {
                 ia--;
                 skipCmp = true;
+                numNonDialableCharsInA++;
             }
 
             cb = b.charAt(ib);
@@ -405,6 +408,7 @@
             if (!isDialable(cb)) {
                 ib--;
                 skipCmp = true;
+                numNonDialableCharsInB++;
             }
 
             if (!skipCmp) {
@@ -416,13 +420,16 @@
         }
 
         if (matched < MIN_MATCH) {
-            int aLen = a.length();
+            int effectiveALen = a.length() - numNonDialableCharsInA;
+            int effectiveBLen = b.length() - numNonDialableCharsInB;
 
-            // if the input strings match, but their lengths < MIN_MATCH,
-            // treat them as equal.
-            if (aLen == b.length() && aLen == matched) {
+
+            // if the number of dialable chars in a and b match, but the matched chars < MIN_MATCH,
+            // treat them as equal (i.e. 404-04 and 40404)
+            if (effectiveALen == effectiveBLen && effectiveALen == matched) {
                 return true;
             }
+
             return false;
         }
 
diff --git a/tests/CoreTests/com/android/internal/telephony/PhoneNumberUtilsTest.java b/tests/CoreTests/com/android/internal/telephony/PhoneNumberUtilsTest.java
index a4e253e..aa2981b 100644
--- a/tests/CoreTests/com/android/internal/telephony/PhoneNumberUtilsTest.java
+++ b/tests/CoreTests/com/android/internal/telephony/PhoneNumberUtilsTest.java
@@ -314,6 +314,9 @@
         // 444 is not a valid country code, but
         // matchIntlPrefixAndCC doesnt know this
         assertTrue(PhoneNumberUtils.compare("+444 207 792 3490", "0 207 792 3490"));
+
+        // compare SMS short code
+        assertTrue(PhoneNumberUtils.compare("404-04", "40404"));
     }
 
 
diff --git a/wifi/java/android/net/wifi/WifiMonitor.java b/wifi/java/android/net/wifi/WifiMonitor.java
index fc750e2..1e322bd 100644
--- a/wifi/java/android/net/wifi/WifiMonitor.java
+++ b/wifi/java/android/net/wifi/WifiMonitor.java
@@ -255,6 +255,8 @@
                 mWifiStateTracker.notifyDriverStopped();
             } else if (state.equals("STARTED")) {
                 mWifiStateTracker.notifyDriverStarted();
+            } else if (state.equals("HANGED")) {
+                mWifiStateTracker.notifyDriverHung();
             }
         }
 
diff --git a/wifi/java/android/net/wifi/WifiStateTracker.java b/wifi/java/android/net/wifi/WifiStateTracker.java
index d8538ea..66552e4 100644
--- a/wifi/java/android/net/wifi/WifiStateTracker.java
+++ b/wifi/java/android/net/wifi/WifiStateTracker.java
@@ -87,12 +87,19 @@
     /**
      * The driver is started or stopped. The object will be the state: true for
      * started, false for stopped.
-     */ 
+     */
     private static final int EVENT_DRIVER_STATE_CHANGED              = 12;
     private static final int EVENT_PASSWORD_KEY_MAY_BE_INCORRECT     = 13;
     private static final int EVENT_MAYBE_START_SCAN_POST_DISCONNECT  = 14;
 
     /**
+     * The driver state indication.
+     */
+    private static final int DRIVER_STARTED                          = 0;
+    private static final int DRIVER_STOPPED                          = 1;
+    private static final int DRIVER_HUNG                             = 2;
+
+    /**
      * Interval in milliseconds between polling for connection
      * status items that are not sent via asynchronous events.
      * An example is RSSI (signal strength).
@@ -556,7 +563,7 @@
         mRunState = RUN_STATE_STOPPED;
 
         // Send a driver stopped message to our handler
-        Message.obtain(this, EVENT_DRIVER_STATE_CHANGED, 0, 0).sendToTarget();
+        Message.obtain(this, EVENT_DRIVER_STATE_CHANGED, DRIVER_STOPPED, 0).sendToTarget();
     }
 
     /**
@@ -565,9 +572,17 @@
      */
     void notifyDriverStarted() {
         // Send a driver started message to our handler
-        Message.obtain(this, EVENT_DRIVER_STATE_CHANGED, 1, 0).sendToTarget();
+        Message.obtain(this, EVENT_DRIVER_STATE_CHANGED, DRIVER_STARTED, 0).sendToTarget();
     }
-    
+
+    /**
+     * Send the tracker a notification that the Wi-Fi driver has hung and needs restarting.
+     */
+    void notifyDriverHung() {
+        // Send a driver hanged message to our handler
+        Message.obtain(this, EVENT_DRIVER_STATE_CHANGED, DRIVER_HUNG, 0).sendToTarget();
+    }
+
     /**
      * Set the interval timer for polling connection information
      * that is not delivered asynchronously.
@@ -1149,15 +1164,14 @@
                 break;
                 
             case EVENT_DRIVER_STATE_CHANGED:
-                boolean driverStarted = msg.arg1 != 0;
-                
                 // Wi-Fi driver state changed:
-                // [31- 1] Reserved for future use
-                // [ 0- 0] Driver start (1) or stopped (0)   
-                eventLogParam = driverStarted ? 1 : 0;
-                EventLog.writeEvent(EVENTLOG_DRIVER_STATE_CHANGED, eventLogParam);
-                
-                if (driverStarted) {
+                // 0 STARTED
+                // 1 STOPPED
+                // 2 HUNG
+                EventLog.writeEvent(EVENTLOG_DRIVER_STATE_CHANGED, msg.arg1);
+
+                switch (msg.arg1) {
+                case DRIVER_STARTED:
                     /**
                      * Set the number of allowed radio channels according
                      * to the system setting, since it gets reset by the
@@ -1176,6 +1190,15 @@
                             }
                         }
                     }
+                    break;
+                case DRIVER_HUNG:
+                    Log.e(TAG, "Wifi Driver reports HUNG - reloading.");
+                    /**
+                     * restart the driver - toggle off and on
+                     */
+                    mWM.setWifiEnabled(false);
+                    mWM.setWifiEnabled(true);
+                    break;
                 }
                 noteRunState();
                 break;