Merge "caching PRAGMA sql statements caused cts-tests failures."
diff --git a/core/java/android/os/INetworkManagementService.aidl b/core/java/android/os/INetworkManagementService.aidl
index bd6cabb..fe416c5 100644
--- a/core/java/android/os/INetworkManagementService.aidl
+++ b/core/java/android/os/INetworkManagementService.aidl
@@ -102,4 +102,25 @@
      *  Disables Network Address Translation between two interfaces.
      */
     void disableNat(String internalInterface, String externalInterface);
+
+    /**
+     ** PPPD
+     **/
+
+    /**
+     * Returns the list of currently known TTY devices on the system
+     */
+    String[] listTtys();
+
+    /**
+     * Attaches a PPP server daemon to the specified TTY with the specified
+     * local/remote addresses.
+     */
+    void attachPppd(String tty, String localAddr, String remoteAddr);
+
+    /**
+     * Detaches a PPP server daemon from the specified TTY.
+     */
+    void detachPppd(String tty);
+
 }
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index db5641c..2d9b52e 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -55,6 +55,8 @@
 import android.view.ViewGroup;
 import android.view.ViewTreeObserver;
 import android.view.animation.AlphaAnimation;
+import android.view.inputmethod.EditorInfo;
+import android.view.inputmethod.InputConnection;
 import android.view.inputmethod.InputMethodManager;
 import android.webkit.WebTextView.AutoCompleteAdapter;
 import android.webkit.WebViewCore.EventHub;
@@ -3206,6 +3208,13 @@
         mWebViewCore.sendMessage(EventHub.SET_SELECTION, start, end);
     }
 
+    @Override
+    public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
+      InputConnection connection = super.onCreateInputConnection(outAttrs);
+      outAttrs.imeOptions |= EditorInfo.IME_FLAG_NO_FULLSCREEN;
+      return connection;
+    }
+
     /**
      * Called in response to a message from webkit telling us that the soft
      * keyboard should be launched.
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index cc54ba3..9a8af3f 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -164,6 +164,15 @@
     <!-- Close low battery warning when battery level reaches this value -->
     <integer name="config_lowBatteryCloseWarningLevel">20</integer>
 
+    <!-- Default color for notification LED. -->
+    <color name="config_defaultNotificationColor">#ff00ff00</color>
+
+    <!-- Default LED on time for notification LED in milliseconds. -->
+    <integer name="config_defaultNotificationLedOn">500</integer>
+
+    <!-- Default LED off time for notification LED in milliseconds. -->
+    <integer name="config_defaultNotificationLedOff">2000</integer>
+
     <!-- Allow the menu hard key to be disabled in LockScreen on some devices -->
     <bool name="config_disableMenuKeyInLockScreen">false</bool>
 
diff --git a/services/java/com/android/server/LightsService.java b/services/java/com/android/server/LightsService.java
index 1937b04..9cc74e8 100644
--- a/services/java/com/android/server/LightsService.java
+++ b/services/java/com/android/server/LightsService.java
@@ -80,11 +80,16 @@
             }
         }
 
+
         public void pulse() {
+            pulse(0x00ffffff, 7);
+        }
+
+        public void pulse(int color, int onMS) {
             synchronized (this) {
                 if (mColor == 0 && !mFlashing) {
-                    setLightLocked(0x00ffffff, LIGHT_FLASH_HARDWARE, 7, 0, BRIGHTNESS_MODE_USER);
-                    mH.sendMessageDelayed(Message.obtain(mH, 1, this), 3000);
+                    setLightLocked(color, LIGHT_FLASH_HARDWARE, onMS, 1000, BRIGHTNESS_MODE_USER);
+                    mH.sendMessageDelayed(Message.obtain(mH, 1, this), onMS);
                 }
             }
         }
diff --git a/services/java/com/android/server/MountService.java b/services/java/com/android/server/MountService.java
index 0d9f98f..381a300 100644
--- a/services/java/com/android/server/MountService.java
+++ b/services/java/com/android/server/MountService.java
@@ -1024,23 +1024,7 @@
     }
 
     public String[] getSecureContainerList() throws IllegalStateException {
-        ArrayList<String> rsp = mConnector.doCommand("list_asec");
-
-        String[] rdata = new String[rsp.size()];
-        int idx = 0;
-
-        for (String line : rsp) {
-            String []tok = line.split(" ");
-            int code = Integer.parseInt(tok[0]);
-            if (code == VoldResponseCode.AsecListResult) {
-                rdata[idx++] = tok[1];
-            } else if (code == NativeDaemonConnector.ResponseCode.CommandOkay) {
-                return rdata;
-            } else {
-                throw new IllegalStateException(String.format("Unexpected response code %d", code));
-            }
-        }
-        throw new IllegalStateException("Got an empty response");
+        return mConnector.doListCommand("list_asec", VoldResponseCode.AsecListResult);
     }
 
     public String createSecureContainer(String id, int sizeMb, String fstype,
diff --git a/services/java/com/android/server/NativeDaemonConnector.java b/services/java/com/android/server/NativeDaemonConnector.java
index da3e562..98e00dc 100644
--- a/services/java/com/android/server/NativeDaemonConnector.java
+++ b/services/java/com/android/server/NativeDaemonConnector.java
@@ -201,6 +201,9 @@
         }
     }
 
+    /**
+     * Issue a command to the native daemon and return the responses
+     */
     public synchronized ArrayList<String> doCommand(String cmd) throws IllegalStateException {
         sendCommand(cmd);
 
@@ -236,4 +239,38 @@
         }
         return response;
     }
+
+    /*
+     * Issues a list command and returns the cooked list
+     */
+    public String[] doListCommand(String cmd, int expectedResponseCode)
+            throws IllegalStateException {
+
+        ArrayList<String> rsp = doCommand(cmd);
+        String[] rdata = new String[rsp.size()-1];
+        int idx = 0;
+
+        for (String line : rsp) {
+            try {
+                String[] tok = line.split(" ");
+                int code = Integer.parseInt(tok[0]);
+                if (code == expectedResponseCode) {
+                    if (tok.length !=2) {
+                        throw new IllegalStateException(
+                                String.format("Malformatted list entry '%s'", line));
+                    }
+                    rdata[idx++] = tok[1];
+                } else if (code == NativeDaemonConnector.ResponseCode.CommandOkay) {
+                    return rdata;
+                } else {
+                    throw new IllegalStateException(
+                            String.format("Expected list response %d, but got %d",
+                                    expectedResponseCode, code));
+                }
+            } catch (NumberFormatException nfe) {
+                throw new IllegalStateException(String.format("Error reading code '%s'", line));
+            }
+        }
+        throw new IllegalStateException("Got an empty response");
+    }
 }
diff --git a/services/java/com/android/server/NetworkManagementService.java b/services/java/com/android/server/NetworkManagementService.java
index 97fa0cc..a4abddb 100644
--- a/services/java/com/android/server/NetworkManagementService.java
+++ b/services/java/com/android/server/NetworkManagementService.java
@@ -52,6 +52,7 @@
         public static final int InterfaceListResult       = 110;
         public static final int TetherInterfaceListResult = 111;
         public static final int TetherDnsFwdTgtListResult = 112;
+        public static final int TtyListResult             = 113;
 
         public static final int TetherStatusResult        = 210;
         public static final int IpFwdStatusResult         = 211;
@@ -106,27 +107,7 @@
         mContext.enforceCallingOrSelfPermission(
                 android.Manifest.permission.ACCESS_NETWORK_STATE, "NetworkManagementService");
 
-        ArrayList<String> rsp = mConnector.doCommand("list_interfaces");
-
-        String[] rdata = new String[rsp.size()];
-        int idx = 0;
-
-        for (String line : rsp) {
-            String []tok = line.split(" ");
-            int code = Integer.parseInt(tok[0]);
-            if (code == NetdResponseCode.InterfaceListResult) {
-                if (tok.length !=2) {
-                    throw new IllegalStateException(
-                            String.format("Malformatted list entry '%s'", line));
-                }
-                rdata[idx++] = tok[1];
-            } else if (code == NativeDaemonConnector.ResponseCode.CommandOkay) {
-                return rdata;
-            } else {
-                throw new IllegalStateException(String.format("Unexpected response code %d", code));
-            }
-        }
-        throw new IllegalStateException("Got an empty response");
+        return mConnector.doListCommand("list_interfaces", NetdResponseCode.InterfaceListResult);
     }
 
     public void shutdown() {
@@ -219,28 +200,8 @@
     public String[] listTetheredInterfaces() throws IllegalStateException {
         mContext.enforceCallingOrSelfPermission(
                 android.Manifest.permission.ACCESS_NETWORK_STATE, "NetworkManagementService");
-
-        ArrayList<String> rsp = mConnector.doCommand("tether interface list");
-
-        String[] rdata = new String[rsp.size()];
-        int idx = 0;
-
-        for (String line : rsp) {
-            String []tok = line.split(" ");
-            int code = Integer.parseInt(tok[0]);
-            if (code == NetdResponseCode.TetherInterfaceListResult) {
-                if (tok.length !=2) {
-                    throw new IllegalStateException(
-                            String.format("Malformatted list entry '%s'", line));
-                }
-                rdata[idx++] = tok[1];
-            } else if (code == NativeDaemonConnector.ResponseCode.CommandOkay) {
-                return rdata;
-            } else {
-                throw new IllegalStateException(String.format("Unexpected response code %d", code));
-            }
-        }
-        throw new IllegalStateException("Got an empty response");
+        return mConnector.doListCommand(
+                "tether interface list", NetdResponseCode.TetherInterfaceListResult);
     }
 
     public void setDnsForwarders(String[] dns) throws IllegalStateException {
@@ -260,28 +221,8 @@
     public String[] getDnsForwarders() throws IllegalStateException {
         mContext.enforceCallingOrSelfPermission(
                 android.Manifest.permission.ACCESS_NETWORK_STATE, "NetworkManagementService");
-
-        ArrayList<String> rsp = mConnector.doCommand("tether dns list");
-
-        String[] rdata = new String[rsp.size()];
-        int idx = 0;
-
-        for (String line : rsp) {
-            String []tok = line.split(" ");
-            int code = Integer.parseInt(tok[0]);
-            if (code == NetdResponseCode.TetherDnsFwdTgtListResult) {
-                if (tok.length !=2) {
-                    throw new IllegalStateException(
-                            String.format("Malformatted list entry '%s'", line));
-                }
-                rdata[idx++] = tok[1];
-            } else if (code == NativeDaemonConnector.ResponseCode.CommandOkay) {
-                return rdata;
-            } else {
-                throw new IllegalStateException(String.format("Unexpected response code %d", code));
-            }
-        }
-        throw new IllegalStateException("Got an empty response");
+        return mConnector.doListCommand(
+                "tether dns list", NetdResponseCode.TetherDnsFwdTgtListResult);
     }
 
     public void enableNat(String internalInterface, String externalInterface)
@@ -299,5 +240,30 @@
         mConnector.doCommand(
                 String.format("nat disable %s %s", internalInterface, externalInterface));
     }
+
+    public String[] listTtys() throws IllegalStateException {
+        mContext.enforceCallingOrSelfPermission(
+                android.Manifest.permission.ACCESS_NETWORK_STATE, "NetworkManagementService");
+        return mConnector.doListCommand("list_ttys", NetdResponseCode.TtyListResult);
+    }
+
+    public void attachPppd(String tty, String localAddr, String remoteAddr)
+            throws IllegalStateException {
+        try {
+            mContext.enforceCallingOrSelfPermission(
+                    android.Manifest.permission.CHANGE_NETWORK_STATE, "NetworkManagementService");
+            mConnector.doCommand(String.format("pppd attach %s %s %s", tty,
+                    InetAddress.getByName(localAddr).toString(),
+                    InetAddress.getByName(localAddr).toString()));
+        } catch (UnknownHostException e) {
+            throw new IllegalStateException("Error resolving addr", e);
+        }
+    }
+
+    public void detachPppd(String tty) throws IllegalStateException {
+        mContext.enforceCallingOrSelfPermission(
+                android.Manifest.permission.CHANGE_NETWORK_STATE, "NetworkManagementService");
+        mConnector.doCommand(String.format("pppd detach %s", tty));
+    }
 }
 
diff --git a/services/java/com/android/server/NotificationManagerService.java b/services/java/com/android/server/NotificationManagerService.java
index 436a60e..fc89ec8 100755
--- a/services/java/com/android/server/NotificationManagerService.java
+++ b/services/java/com/android/server/NotificationManagerService.java
@@ -91,6 +91,10 @@
     private LightsService.Light mNotificationLight;
     private LightsService.Light mAttentionLight;
 
+    private int mDefaultNotificationColor;
+    private int mDefaultNotificationLedOn;
+    private int mDefaultNotificationLedOff;
+
     private NotificationRecord mSoundNotification;
     private AsyncPlayer mSound;
     private boolean mSystemReady;
@@ -398,6 +402,14 @@
         mNotificationLight = lights.getLight(LightsService.LIGHT_ID_NOTIFICATIONS);
         mAttentionLight = lights.getLight(LightsService.LIGHT_ID_ATTENTION);
 
+        Resources resources = mContext.getResources();
+        mDefaultNotificationColor = resources.getColor(
+                com.android.internal.R.color.config_defaultNotificationColor);
+        mDefaultNotificationLedOn = resources.getInteger(
+                com.android.internal.R.integer.config_defaultNotificationLedOn);
+        mDefaultNotificationLedOff = resources.getInteger(
+                com.android.internal.R.integer.config_defaultNotificationLedOff);
+
         // Don't start allowing notifications until the setup wizard has run once.
         // After that, including subsequent boots, init with notifications turned on.
         // This works on the first boot because the setup wizard will toggle this
@@ -1024,14 +1036,25 @@
         }
 
         // we only flash if screen is off and persistent pulsing is enabled
-        if (mLedNotification == null || mScreenOn || !mNotificationPulseEnabled) {
+        if (mLedNotification == null || mScreenOn) {
             mNotificationLight.turnOff();
         } else {
-            mNotificationLight.setFlashing(
-                    mLedNotification.notification.ledARGB,
-                    LightsService.LIGHT_FLASH_TIMED,
-                    mLedNotification.notification.ledOnMS,
-                    mLedNotification.notification.ledOffMS);
+            int ledARGB = mLedNotification.notification.ledARGB;
+            int ledOnMS = mLedNotification.notification.ledOnMS;
+            int ledOffMS = mLedNotification.notification.ledOffMS;
+            if ((mLedNotification.notification.defaults & Notification.DEFAULT_LIGHTS) != 0) {
+                ledARGB = mDefaultNotificationColor;
+                ledOnMS = mDefaultNotificationLedOn;
+                ledOffMS = mDefaultNotificationLedOff;
+            }
+            if (mNotificationPulseEnabled) {
+                // pulse repeatedly
+                mNotificationLight.setFlashing(ledARGB, LightsService.LIGHT_FLASH_TIMED,
+                        ledOnMS, ledOffMS);
+            } else {
+                // pulse only once
+                mNotificationLight.pulse(ledARGB, ledOnMS);
+            }
         }
     }