Merge "WifiConfiguration: add constants for radio band" into mm-wireless-dev
diff --git a/api/system-current.txt b/api/system-current.txt
index ca92c45..fc9ae9b 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -21106,6 +21106,7 @@
     method public boolean reconnect();
     method public boolean removeNetwork(int);
     method public boolean saveConfiguration();
+    method public boolean setMetered(int, boolean);
     method public void setTdlsEnabled(java.net.InetAddress, boolean);
     method public void setTdlsEnabledWithMacAddress(java.lang.String, boolean);
     method public boolean setWifiEnabled(boolean);
diff --git a/services/net/java/android/net/dhcp/DhcpClient.java b/services/net/java/android/net/dhcp/DhcpClient.java
index c9efc69..f9c17b7 100644
--- a/services/net/java/android/net/dhcp/DhcpClient.java
+++ b/services/net/java/android/net/dhcp/DhcpClient.java
@@ -29,7 +29,6 @@
 import android.content.IntentFilter;
 import android.net.DhcpResults;
 import android.net.BaseDhcpStateMachine;
-import android.net.DhcpStateMachine;
 import android.net.InterfaceConfiguration;
 import android.net.LinkAddress;
 import android.net.NetworkUtils;
@@ -105,12 +104,35 @@
     // t=0, t=2, t=6, t=14, t=30, allowing for 10% jitter.
     private static final int DHCP_TIMEOUT_MS    =  36 * SECONDS;
 
+    private static final int PUBLIC_BASE = Protocol.BASE_DHCP;
+
+    /* Commands from controller to start/stop DHCP */
+    public static final int CMD_START_DHCP                  = PUBLIC_BASE + 1;
+    public static final int CMD_STOP_DHCP                   = PUBLIC_BASE + 2;
+    public static final int CMD_RENEW_DHCP                  = PUBLIC_BASE + 3;
+
+    /* Notification from DHCP state machine prior to DHCP discovery/renewal */
+    public static final int CMD_PRE_DHCP_ACTION             = PUBLIC_BASE + 4;
+    /* Notification from DHCP state machine post DHCP discovery/renewal. Indicates
+     * success/failure */
+    public static final int CMD_POST_DHCP_ACTION            = PUBLIC_BASE + 5;
+    /* Notification from DHCP state machine before quitting */
+    public static final int CMD_ON_QUIT                     = PUBLIC_BASE + 6;
+
+    /* Command from controller to indicate DHCP discovery/renewal can continue
+     * after pre DHCP action is complete */
+    public static final int CMD_PRE_DHCP_ACTION_COMPLETE    = PUBLIC_BASE + 7;
+
+    /* Message.arg1 arguments to CMD_POST_DHCP notification */
+    public static final int DHCP_SUCCESS = 1;
+    public static final int DHCP_FAILURE = 2;
+
     // Messages.
-    private static final int BASE                 = Protocol.BASE_DHCP + 100;
-    private static final int CMD_KICK             = BASE + 1;
-    private static final int CMD_RECEIVED_PACKET  = BASE + 2;
-    private static final int CMD_TIMEOUT          = BASE + 3;
-    private static final int CMD_ONESHOT_TIMEOUT  = BASE + 4;
+    private static final int PRIVATE_BASE         = Protocol.BASE_DHCP + 100;
+    private static final int CMD_KICK             = PRIVATE_BASE + 1;
+    private static final int CMD_RECEIVED_PACKET  = PRIVATE_BASE + 2;
+    private static final int CMD_TIMEOUT          = PRIVATE_BASE + 3;
+    private static final int CMD_ONESHOT_TIMEOUT  = PRIVATE_BASE + 4;
 
     // DHCP parameters that we request.
     private static final byte[] REQUESTED_PARAMS = new byte[] {
@@ -210,7 +232,7 @@
         // Used to time out PacketRetransmittingStates.
         mTimeoutIntent = createStateMachineCommandIntent("TIMEOUT", CMD_TIMEOUT);
         // Used to schedule DHCP renews.
-        mRenewIntent = createStateMachineCommandIntent("RENEW", DhcpStateMachine.CMD_RENEW_DHCP);
+        mRenewIntent = createStateMachineCommandIntent("RENEW", CMD_RENEW_DHCP);
         // Used to tell the caller when its request (CMD_START_DHCP or CMD_RENEW_DHCP) timed out.
         // TODO: when the legacy DHCP client is gone, make the client fully asynchronous and
         // remove this.
@@ -437,13 +459,12 @@
     }
 
     private void notifySuccess() {
-        mController.sendMessage(DhcpStateMachine.CMD_POST_DHCP_ACTION,
-                DhcpStateMachine.DHCP_SUCCESS, 0, new DhcpResults(mDhcpLease));
+        mController.sendMessage(
+                CMD_POST_DHCP_ACTION, DHCP_SUCCESS, 0, new DhcpResults(mDhcpLease));
     }
 
     private void notifyFailure() {
-        mController.sendMessage(DhcpStateMachine.CMD_POST_DHCP_ACTION,
-                DhcpStateMachine.DHCP_FAILURE, 0, null);
+        mController.sendMessage(CMD_POST_DHCP_ACTION, DHCP_FAILURE, 0, null);
     }
 
     private void clearDhcpState() {
@@ -465,7 +486,7 @@
 
     protected void onQuitting() {
         Log.d(TAG, "onQuitting");
-        mController.sendMessage(DhcpStateMachine.CMD_ON_QUIT);
+        mController.sendMessage(CMD_ON_QUIT);
     }
 
     private void maybeLog(String msg) {
@@ -479,17 +500,17 @@
 
         private String messageName(int what) {
             switch (what) {
-                case DhcpStateMachine.CMD_START_DHCP:
+                case CMD_START_DHCP:
                     return "CMD_START_DHCP";
-                case DhcpStateMachine.CMD_STOP_DHCP:
+                case CMD_STOP_DHCP:
                     return "CMD_STOP_DHCP";
-                case DhcpStateMachine.CMD_RENEW_DHCP:
+                case CMD_RENEW_DHCP:
                     return "CMD_RENEW_DHCP";
-                case DhcpStateMachine.CMD_PRE_DHCP_ACTION:
+                case CMD_PRE_DHCP_ACTION:
                     return "CMD_PRE_DHCP_ACTION";
-                case DhcpStateMachine.CMD_PRE_DHCP_ACTION_COMPLETE:
+                case CMD_PRE_DHCP_ACTION_COMPLETE:
                     return "CMD_PRE_DHCP_ACTION_COMPLETE";
-                case DhcpStateMachine.CMD_POST_DHCP_ACTION:
+                case CMD_POST_DHCP_ACTION:
                     return "CMD_POST_DHCP_ACTION";
                 case CMD_KICK:
                     return "CMD_KICK";
@@ -532,14 +553,14 @@
         @Override
         public void enter() {
             super.enter();
-            mController.sendMessage(DhcpStateMachine.CMD_PRE_DHCP_ACTION);
+            mController.sendMessage(CMD_PRE_DHCP_ACTION);
         }
 
         @Override
         public boolean processMessage(Message message) {
             super.processMessage(message);
             switch (message.what) {
-                case DhcpStateMachine.CMD_PRE_DHCP_ACTION_COMPLETE:
+                case CMD_PRE_DHCP_ACTION_COMPLETE:
                     transitionTo(mOtherState);
                     return HANDLED;
                 default:
@@ -574,7 +595,7 @@
         public boolean processMessage(Message message) {
             super.processMessage(message);
             switch (message.what) {
-                case DhcpStateMachine.CMD_START_DHCP:
+                case CMD_START_DHCP:
                     scheduleOneshotTimeout();
                     if (mRegisteredForPreDhcpNotification) {
                         transitionTo(mWaitBeforeStartState);
@@ -630,7 +651,7 @@
         public boolean processMessage(Message message) {
             super.processMessage(message);
             switch (message.what) {
-                case DhcpStateMachine.CMD_STOP_DHCP:
+                case CMD_STOP_DHCP:
                     transitionTo(mStoppedState);
                     return HANDLED;
                 case CMD_ONESHOT_TIMEOUT:
@@ -854,7 +875,7 @@
         public boolean processMessage(Message message) {
             super.processMessage(message);
             switch (message.what) {
-                case DhcpStateMachine.CMD_RENEW_DHCP:
+                case CMD_RENEW_DHCP:
                     if (mRegisteredForPreDhcpNotification) {
                         transitionTo(mWaitBeforeRenewalState);
                     } else {
diff --git a/services/net/java/android/net/ip/IpManager.java b/services/net/java/android/net/ip/IpManager.java
index 027c325..25cb793 100644
--- a/services/net/java/android/net/ip/IpManager.java
+++ b/services/net/java/android/net/ip/IpManager.java
@@ -61,7 +61,6 @@
  * @hide
  */
 public class IpManager extends StateMachine {
-    private static final String TAG = IpManager.class.getSimpleName();
     private static final boolean DBG = true;
     private static final boolean VDBG = false;
 
@@ -116,6 +115,64 @@
         public void onReachabilityLost(String logMsg) {}
     }
 
+    /**
+     * This class encapsulates parameters to be passed to
+     * IpManager#startProvisioning(). A defensive copy is made by IpManager
+     * and the values specified herein are in force until IpManager#stop()
+     * is called.
+     *
+     * Example use:
+     *
+     *     final ProvisioningConfiguration config =
+     *             mIpManager.buildProvisioningConfiguration()
+     *                     .withPreDhcpAction()
+     *                     .build();
+     *     mIpManager.startProvisioning(config);
+     *     ...
+     *     mIpManager.stop();
+     *
+     * The specified provisioning configuration will only be active until
+     * IpManager#stop() is called. Future calls to IpManager#startProvisioning()
+     * must specify the configuration again.
+     */
+    public static class ProvisioningConfiguration {
+
+        public static class Builder {
+            private ProvisioningConfiguration mConfig = new ProvisioningConfiguration();
+
+            public Builder withoutIpReachabilityMonitor() {
+                mConfig.mUsingIpReachabilityMonitor = false;
+                return this;
+            }
+
+            public Builder withPreDhcpAction() {
+                mConfig.mRequestedPreDhcpAction = true;
+                return this;
+            }
+
+            public Builder withStaticConfiguration(StaticIpConfiguration staticConfig) {
+                mConfig.mStaticIpConfig = staticConfig;
+                return this;
+            }
+
+            public ProvisioningConfiguration build() {
+                return new ProvisioningConfiguration(mConfig);
+            }
+        }
+
+        /* package */ boolean mUsingIpReachabilityMonitor = true;
+        /* package */ boolean mRequestedPreDhcpAction;
+        /* package */ StaticIpConfiguration mStaticIpConfig;
+
+        public ProvisioningConfiguration() {}
+
+        public ProvisioningConfiguration(ProvisioningConfiguration other) {
+            mUsingIpReachabilityMonitor = other.mUsingIpReachabilityMonitor;
+            mRequestedPreDhcpAction = other.mRequestedPreDhcpAction;
+            mStaticIpConfig = other.mStaticIpConfig;
+        }
+    }
+
     private static final int CMD_STOP = 1;
     private static final int CMD_START = 2;
     private static final int CMD_CONFIRM = 3;
@@ -130,6 +187,7 @@
     private final State mStoppingState = new StoppingState();
     private final State mStartedState = new StartedState();
 
+    private final String mTag;
     private final Context mContext;
     private final String mInterfaceName;
     @VisibleForTesting
@@ -145,7 +203,7 @@
     private IpReachabilityMonitor mIpReachabilityMonitor;
     private BaseDhcpStateMachine mDhcpStateMachine;
     private DhcpResults mDhcpResults;
-    private StaticIpConfiguration mStaticIpConfig;
+    private ProvisioningConfiguration mConfiguration;
 
     /**
      * Member variables accessed both from within the StateMachine thread
@@ -156,11 +214,11 @@
 
     public IpManager(Context context, String ifName, Callback callback)
                 throws IllegalArgumentException {
-        super(TAG + "." + ifName);
+        super(IpManager.class.getSimpleName() + "." + ifName);
+        mTag = getName();
 
         mContext = context;
         mInterfaceName = ifName;
-
         mCallback = callback;
 
         mNwService = INetworkManagementService.Stub.asInterface(
@@ -177,7 +235,7 @@
         try {
             mNwService.registerObserver(mNetlinkTracker);
         } catch (RemoteException e) {
-            Log.e(TAG, "Couldn't register NetlinkTracker: " + e.toString());
+            Log.e(mTag, "Couldn't register NetlinkTracker: " + e.toString());
         }
 
         resetLinkProperties();
@@ -200,7 +258,9 @@
      */
     @VisibleForTesting
     protected IpManager(String ifName, Callback callback) {
-        super(TAG + ".test-" + ifName);
+        super(IpManager.class.getSimpleName() + ".test-" + ifName);
+        mTag = getName();
+
         mInterfaceName = ifName;
         mCallback = callback;
 
@@ -209,14 +269,24 @@
         mNetlinkTracker = null;
     }
 
-    public void startProvisioning(StaticIpConfiguration staticIpConfig) {
+    public static ProvisioningConfiguration.Builder buildProvisioningConfiguration() {
+        return new ProvisioningConfiguration.Builder();
+    }
+
+    public void startProvisioning(ProvisioningConfiguration req) {
         getInterfaceIndex();
-        sendMessage(CMD_START, staticIpConfig);
+        sendMessage(CMD_START, new ProvisioningConfiguration(req));
+    }
+
+    // TODO: Delete this.
+    public void startProvisioning(StaticIpConfiguration staticIpConfig) {
+        startProvisioning(buildProvisioningConfiguration()
+                .withStaticConfiguration(staticIpConfig)
+                .build());
     }
 
     public void startProvisioning() {
-        getInterfaceIndex();
-        sendMessage(CMD_START);
+        startProvisioning(new ProvisioningConfiguration());
     }
 
     public void stop() {
@@ -256,12 +326,12 @@
                 return "EVENT_PRE_DHCP_ACTION_COMPLETE";
             case EVENT_NETLINK_LINKPROPERTIES_CHANGED:
                 return "EVENT_NETLINK_LINKPROPERTIES_CHANGED";
-            case DhcpStateMachine.CMD_PRE_DHCP_ACTION:
-                return "DhcpStateMachine.CMD_PRE_DHCP_ACTION";
-            case DhcpStateMachine.CMD_POST_DHCP_ACTION:
-                return "DhcpStateMachine.CMD_POST_DHCP_ACTION";
-            case DhcpStateMachine.CMD_ON_QUIT:
-                return "DhcpStateMachine.CMD_ON_QUIT";
+            case DhcpClient.CMD_PRE_DHCP_ACTION:
+                return "DhcpClient.CMD_PRE_DHCP_ACTION";
+            case DhcpClient.CMD_POST_DHCP_ACTION:
+                return "DhcpClient.CMD_POST_DHCP_ACTION";
+            case DhcpClient.CMD_ON_QUIT:
+                return "DhcpClient.CMD_ON_QUIT";
         }
         return "UNKNOWN:" + Integer.toString(what);
     }
@@ -273,7 +343,7 @@
                 mInterfaceName, mInterfaceIndex,
                 msg.arg1, msg.arg2, Objects.toString(msg.obj));
         if (VDBG) {
-            Log.d(TAG, getWhatToString(msg.what) + " " + logLine);
+            Log.d(mTag, getWhatToString(msg.what) + " " + logLine);
         }
         return logLine;
     }
@@ -283,7 +353,7 @@
             mInterfaceIndex = NetworkInterface.getByName(mInterfaceName).getIndex();
         } catch (SocketException | NullPointerException e) {
             // TODO: throw new IllegalStateException.
-            Log.e(TAG, "ALERT: Failed to get interface index: ", e);
+            Log.e(mTag, "ALERT: Failed to get interface index: ", e);
         }
     }
 
@@ -294,7 +364,7 @@
     private void resetLinkProperties() {
         mNetlinkTracker.clearLinkProperties();
         mDhcpResults = null;
-        mStaticIpConfig = null;
+        mConfiguration = null;
 
         synchronized (mLock) {
             mLinkProperties = new LinkProperties();
@@ -365,17 +435,17 @@
     private void dispatchCallback(ProvisioningChange delta, LinkProperties newLp) {
         switch (delta) {
             case GAINED_PROVISIONING:
-                if (VDBG) { Log.d(TAG, "onProvisioningSuccess()"); }
+                if (VDBG) { Log.d(mTag, "onProvisioningSuccess()"); }
                 mCallback.onProvisioningSuccess(newLp);
                 break;
 
             case LOST_PROVISIONING:
-                if (VDBG) { Log.d(TAG, "onProvisioningFailure()"); }
+                if (VDBG) { Log.d(mTag, "onProvisioningFailure()"); }
                 mCallback.onProvisioningFailure(newLp);
                 break;
 
             default:
-                if (VDBG) { Log.d(TAG, "onLinkPropertiesChange()"); }
+                if (VDBG) { Log.d(mTag, "onLinkPropertiesChange()"); }
                 mCallback.onLinkPropertiesChange(newLp);
                 break;
         }
@@ -396,7 +466,7 @@
             switch (delta) {
                 case GAINED_PROVISIONING:
                 case LOST_PROVISIONING:
-                    Log.d(TAG, "provisioning: " + delta);
+                    Log.d(mTag, "provisioning: " + delta);
                     break;
             }
         }
@@ -452,7 +522,7 @@
         }
 
         if (VDBG) {
-            Log.d(TAG, "newLp{" + newLp + "}");
+            Log.d(mTag, "newLp{" + newLp + "}");
         }
 
         return newLp;
@@ -464,7 +534,7 @@
             ifcg.setLinkAddress(new LinkAddress("0.0.0.0/0"));
             mNwService.setInterfaceConfig(mInterfaceName, ifcg);
         } catch (RemoteException e) {
-            Log.e(TAG, "ALERT: Failed to clear IPv4 address on interface " + mInterfaceName, e);
+            Log.e(mTag, "ALERT: Failed to clear IPv4 address on interface " + mInterfaceName, e);
         }
     }
 
@@ -474,7 +544,7 @@
         final ProvisioningChange delta = setLinkProperties(newLp);
 
         if (VDBG) {
-            Log.d(TAG, "onNewDhcpResults(" + Objects.toString(dhcpResults) + ")");
+            Log.d(mTag, "onNewDhcpResults(" + Objects.toString(dhcpResults) + ")");
         }
         mCallback.onNewDhcpResults(dhcpResults);
 
@@ -502,7 +572,7 @@
             delta = ProvisioningChange.LOST_PROVISIONING;
         }
 
-        if (VDBG) { Log.d(TAG, "onNewDhcpResults(null)"); }
+        if (VDBG) { Log.d(mTag, "onNewDhcpResults(null)"); }
         mCallback.onNewDhcpResults(null);
 
         dispatchCallback(delta, newLp);
@@ -518,7 +588,7 @@
                 mNwService.disableIpv6(mInterfaceName);
                 mNwService.clearInterfaceAddresses(mInterfaceName);
             } catch (Exception e) {
-                Log.e(TAG, "Failed to clear addresses or disable IPv6" + e);
+                Log.e(mTag, "Failed to clear addresses or disable IPv6" + e);
             }
 
             resetLinkProperties();
@@ -531,7 +601,7 @@
                     break;
 
                 case CMD_START:
-                    mStaticIpConfig = (StaticIpConfiguration) msg.obj;
+                    mConfiguration = (ProvisioningConfiguration) msg.obj;
                     transitionTo(mStartedState);
                     break;
 
@@ -539,9 +609,9 @@
                     setLinkProperties(assembleLinkProperties());
                     break;
 
-                case DhcpStateMachine.CMD_ON_QUIT:
+                case DhcpClient.CMD_ON_QUIT:
                     // Everything is already stopped.
-                    Log.e(TAG, "Unexpected CMD_ON_QUIT (already stopped).");
+                    Log.e(mTag, "Unexpected CMD_ON_QUIT (already stopped).");
                     break;
 
                 default:
@@ -563,7 +633,7 @@
         @Override
         public boolean processMessage(Message msg) {
             switch (msg.what) {
-                case DhcpStateMachine.CMD_ON_QUIT:
+                case DhcpClient.CMD_ON_QUIT:
                     mDhcpStateMachine = null;
                     transitionTo(mStoppedState);
                     break;
@@ -584,30 +654,30 @@
                 mNwService.enableIpv6(mInterfaceName);
                 // TODO: Perhaps clearIPv4Address() as well.
             } catch (RemoteException re) {
-                Log.e(TAG, "Unable to change interface settings: " + re);
+                Log.e(mTag, "Unable to change interface settings: " + re);
             } catch (IllegalStateException ie) {
-                Log.e(TAG, "Unable to change interface settings: " + ie);
+                Log.e(mTag, "Unable to change interface settings: " + ie);
             }
 
-            mIpReachabilityMonitor = new IpReachabilityMonitor(
-                    mContext,
-                    mInterfaceName,
-                    new IpReachabilityMonitor.Callback() {
-                        @Override
-                        public void notifyLost(InetAddress ip, String logMsg) {
-                            if (mCallback.usingIpReachabilityMonitor()) {
+            if (mConfiguration.mUsingIpReachabilityMonitor) {
+                mIpReachabilityMonitor = new IpReachabilityMonitor(
+                        mContext,
+                        mInterfaceName,
+                        new IpReachabilityMonitor.Callback() {
+                            @Override
+                            public void notifyLost(InetAddress ip, String logMsg) {
                                 mCallback.onReachabilityLost(logMsg);
                             }
-                        }
-                    });
+                        });
+            }
 
             // If we have a StaticIpConfiguration attempt to apply it and
             // handle the result accordingly.
-            if (mStaticIpConfig != null) {
+            if (mConfiguration.mStaticIpConfig != null) {
                 if (applyStaticIpConfig()) {
-                    handleIPv4Success(new DhcpResults(mStaticIpConfig));
+                    handleIPv4Success(new DhcpResults(mConfiguration.mStaticIpConfig));
                 } else {
-                    if (VDBG) { Log.d(TAG, "onProvisioningFailure()"); }
+                    if (VDBG) { Log.d(mTag, "onProvisioningFailure()"); }
                     mCallback.onProvisioningFailure(getLinkProperties());
                     transitionTo(mStoppingState);
                 }
@@ -615,17 +685,19 @@
                 // Start DHCPv4.
                 makeDhcpStateMachine();
                 mDhcpStateMachine.registerForPreDhcpNotification();
-                mDhcpStateMachine.sendMessage(DhcpStateMachine.CMD_START_DHCP);
+                mDhcpStateMachine.sendMessage(DhcpClient.CMD_START_DHCP);
             }
         }
 
         @Override
         public void exit() {
-            mIpReachabilityMonitor.stop();
-            mIpReachabilityMonitor = null;
+            if (mIpReachabilityMonitor != null) {
+                mIpReachabilityMonitor.stop();
+                mIpReachabilityMonitor = null;
+            }
 
             if (mDhcpStateMachine != null) {
-                mDhcpStateMachine.sendMessage(DhcpStateMachine.CMD_STOP_DHCP);
+                mDhcpStateMachine.sendMessage(DhcpClient.CMD_STOP_DHCP);
                 mDhcpStateMachine.doQuit();
             }
 
@@ -640,7 +712,7 @@
                     break;
 
                 case CMD_START:
-                    Log.e(TAG, "ALERT: START received in StartedState. Please fix caller.");
+                    Log.e(mTag, "ALERT: START received in StartedState. Please fix caller.");
                     break;
 
                 case CMD_CONFIRM:
@@ -648,7 +720,7 @@
                     // that both probes (a) on-link neighbors and (b) does
                     // a DHCPv4 RENEW.  We used to do this on Wi-Fi framework
                     // roams.
-                    if (mCallback.usingIpReachabilityMonitor()) {
+                    if (mIpReachabilityMonitor != null) {
                         mIpReachabilityMonitor.probeAll();
                     }
                     break;
@@ -658,8 +730,7 @@
                     // calls completedPreDhcpAction() after provisioning with
                     // a static IP configuration.
                     if (mDhcpStateMachine != null) {
-                        mDhcpStateMachine.sendMessage(
-                                DhcpStateMachine.CMD_PRE_DHCP_ACTION_COMPLETE);
+                        mDhcpStateMachine.sendMessage(DhcpClient.CMD_PRE_DHCP_ACTION_COMPLETE);
                     }
                     break;
 
@@ -676,35 +747,39 @@
                     break;
                 }
 
-                case DhcpStateMachine.CMD_PRE_DHCP_ACTION:
-                    if (VDBG) { Log.d(TAG, "onPreDhcpAction()"); }
-                    mCallback.onPreDhcpAction();
+                case DhcpClient.CMD_PRE_DHCP_ACTION:
+                    if (VDBG) { Log.d(mTag, "onPreDhcpAction()"); }
+                    if (mConfiguration.mRequestedPreDhcpAction) {
+                        mCallback.onPreDhcpAction();
+                    } else {
+                        sendMessage(EVENT_PRE_DHCP_ACTION_COMPLETE);
+                    }
                     break;
 
-                case DhcpStateMachine.CMD_POST_DHCP_ACTION: {
+                case DhcpClient.CMD_POST_DHCP_ACTION: {
                     // Note that onPostDhcpAction() is likely to be
                     // asynchronous, and thus there is no guarantee that we
                     // will be able to observe any of its effects here.
-                    if (VDBG) { Log.d(TAG, "onPostDhcpAction()"); }
+                    if (VDBG) { Log.d(mTag, "onPostDhcpAction()"); }
                     mCallback.onPostDhcpAction();
 
                     final DhcpResults dhcpResults = (DhcpResults) msg.obj;
                     switch (msg.arg1) {
-                        case DhcpStateMachine.DHCP_SUCCESS:
+                        case DhcpClient.DHCP_SUCCESS:
                             handleIPv4Success(dhcpResults);
                             break;
-                        case DhcpStateMachine.DHCP_FAILURE:
+                        case DhcpClient.DHCP_FAILURE:
                             handleIPv4Failure();
                             break;
                         default:
-                            Log.e(TAG, "Unknown CMD_POST_DHCP_ACTION status:" + msg.arg1);
+                            Log.e(mTag, "Unknown CMD_POST_DHCP_ACTION status:" + msg.arg1);
                     }
                     break;
                 }
 
-                case DhcpStateMachine.CMD_ON_QUIT:
+                case DhcpClient.CMD_ON_QUIT:
                     // DHCPv4 quit early for some reason.
-                    Log.e(TAG, "Unexpected CMD_ON_QUIT.");
+                    Log.e(mTag, "Unexpected CMD_ON_QUIT.");
                     mDhcpStateMachine = null;
                     break;
 
@@ -716,13 +791,13 @@
 
         private boolean applyStaticIpConfig() {
             final InterfaceConfiguration ifcg = new InterfaceConfiguration();
-            ifcg.setLinkAddress(mStaticIpConfig.ipAddress);
+            ifcg.setLinkAddress(mConfiguration.mStaticIpConfig.ipAddress);
             ifcg.setInterfaceUp();
             try {
                 mNwService.setInterfaceConfig(mInterfaceName, ifcg);
-                if (DBG) Log.d(TAG, "Static IP configuration succeeded");
+                if (DBG) Log.d(mTag, "Static IP configuration succeeded");
             } catch (IllegalStateException | RemoteException e) {
-                Log.e(TAG, "Static IP configuration failed: ", e);
+                Log.e(mTag, "Static IP configuration failed: ", e);
                 return false;
             }
 
diff --git a/telephony/java/com/android/ims/internal/IImsRegistrationListener.aidl b/telephony/java/com/android/ims/internal/IImsRegistrationListener.aidl
index 23a69d1..69259d0 100644
--- a/telephony/java/com/android/ims/internal/IImsRegistrationListener.aidl
+++ b/telephony/java/com/android/ims/internal/IImsRegistrationListener.aidl
@@ -17,6 +17,7 @@
 package com.android.ims.internal;
 
 import com.android.ims.ImsReasonInfo;
+
 /**
  * A listener type for receiving notifications about the changes to
  * the IMS connection(registration).
@@ -26,15 +27,36 @@
 interface IImsRegistrationListener {
     /**
      * Notifies the application when the device is connected to the IMS network.
+     *
+     * @deprecated see {@link registrationConnectedWithRadioTech}
      */
     void registrationConnected();
 
     /**
      * Notifies the application when the device is trying to connect the IMS network.
+     *
+     * @deprecated see {@link registrationProgressingWithRadioTech}
      */
     void registrationProgressing();
 
     /**
+     * Notifies the application when the device is connected to the IMS network.
+     *
+     * @param imsRadioTech the radio access technology. Valid values are {@code
+     * RIL_RADIO_TECHNOLOGY_*} defined in {@link ServiceState}.
+     */
+    void registrationConnectedWithRadioTech(int imsRadioTech);
+
+    /**
+     * Notifies the application when the device is trying to connect the IMS network.
+     *
+     * @param imsRadioTech the radio access technology. Valid values are {@code
+     * RIL_RADIO_TECHNOLOGY_*} defined in {@link ServiceState}.
+     */
+    void registrationProgressingWithRadioTech(int imsRadioTech);
+
+
+    /**
      * Notifies the application when the device is disconnected from the IMS network.
      */
     void registrationDisconnected(in ImsReasonInfo imsReasonInfo);
diff --git a/telephony/java/com/android/internal/telephony/RILConstants.java b/telephony/java/com/android/internal/telephony/RILConstants.java
index 429839f..0d6c70b 100644
--- a/telephony/java/com/android/internal/telephony/RILConstants.java
+++ b/telephony/java/com/android/internal/telephony/RILConstants.java
@@ -92,7 +92,33 @@
     int NO_SMS_TO_ACK = 48;                   /* ACK received when there is no SMS to ack */
     int NETWORK_ERR = 49;                     /* Received error from network */
     int REQUEST_RATE_LIMITED = 50;            /* Operation denied due to overly-frequent requests */
-
+    // Below is list of OEM specific error codes which can by used by OEMs in case they don't want to
+    // reveal particular replacement for Generic failure
+    int OEM_ERROR_1 = 501;
+    int OEM_ERROR_2 = 502;
+    int OEM_ERROR_3 = 503;
+    int OEM_ERROR_4 = 504;
+    int OEM_ERROR_5 = 505;
+    int OEM_ERROR_6 = 506;
+    int OEM_ERROR_7 = 507;
+    int OEM_ERROR_8 = 508;
+    int OEM_ERROR_9 = 509;
+    int OEM_ERROR_10 = 510;
+    int OEM_ERROR_11 = 511;
+    int OEM_ERROR_12 = 512;
+    int OEM_ERROR_13 = 513;
+    int OEM_ERROR_14 = 514;
+    int OEM_ERROR_15 = 515;
+    int OEM_ERROR_16 = 516;
+    int OEM_ERROR_17 = 517;
+    int OEM_ERROR_18 = 518;
+    int OEM_ERROR_19 = 519;
+    int OEM_ERROR_20 = 520;
+    int OEM_ERROR_21 = 521;
+    int OEM_ERROR_22 = 522;
+    int OEM_ERROR_23 = 523;
+    int OEM_ERROR_24 = 524;
+    int OEM_ERROR_25 = 525;
 
     /* NETWORK_MODE_* See ril.h RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE */
     int NETWORK_MODE_WCDMA_PREF     = 0; /* GSM/WCDMA (WCDMA preferred) */
diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java
index 37b34a6..a6aad3c 100644
--- a/wifi/java/android/net/wifi/WifiConfiguration.java
+++ b/wifi/java/android/net/wifi/WifiConfiguration.java
@@ -1767,11 +1767,6 @@
     }
 
     /** @hide */
-    public boolean isVisibleToUser(int userId) {
-        return shared || (UserHandle.getUserId(creatorUid) == userId);
-    }
-
-    /** @hide */
     public void setPasspointManagementObjectTree(String passpointManagementObjectTree) {
         mPasspointManagementObjectTree = passpointManagementObjectTree;
     }
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
index 4133cda..55b9182 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -44,6 +44,7 @@
 import com.android.internal.util.Protocol;
 
 import java.net.InetAddress;
+import java.util.ArrayList;
 import java.util.List;
 import java.util.concurrent.CountDownLatch;
 
@@ -884,6 +885,24 @@
     }
 
     /**
+     * Sets whether or not the given network is metered from a network policy
+     * point of view. A network should be classified as metered when the user is
+     * sensitive to heavy data usage on that connection due to monetary costs,
+     * data limitations or battery/performance issues. A typical example would
+     * be a wifi connection where the user was being charged for usage.
+     * @param netId the integer that identifies the network configuration
+     * to the supplicant.
+     * @param isMetered True to mark the network as metered.
+     * @return {@code true} if the operation succeeded.
+     * @hide
+     */
+    @SystemApi
+    public boolean setMetered(int netId, boolean isMetered) {
+        // TODO(jjoslin): Implement
+        return false;
+    }
+
+    /**
      * Remove the specified network from the list of configured networks.
      * This may result in the asynchronous delivery of state change
      * events.
@@ -1293,13 +1312,15 @@
      * @return the list of access points found in the most recent scan. An app must hold
      * {@link android.Manifest.permission#ACCESS_COARSE_LOCATION ACCESS_COARSE_LOCATION} or
      * {@link android.Manifest.permission#ACCESS_FINE_LOCATION ACCESS_FINE_LOCATION} permission
-     * in order to get valid results.
+     * in order to get valid results.  If there is a remote exception (e.g., either a communication
+     * problem with the system service or an exception within the framework) an empty list will be
+     * returned.
      */
     public List<ScanResult> getScanResults() {
         try {
             return mService.getScanResults(mContext.getOpPackageName());
         } catch (RemoteException e) {
-            return null;
+            return new ArrayList<ScanResult>();
         }
     }
 
diff --git a/wifi/java/android/net/wifi/nan/WifiNanEventListener.java b/wifi/java/android/net/wifi/nan/WifiNanEventListener.java
index 5c18bd7..9e6ed4e 100644
--- a/wifi/java/android/net/wifi/nan/WifiNanEventListener.java
+++ b/wifi/java/android/net/wifi/nan/WifiNanEventListener.java
@@ -36,7 +36,7 @@
  */
 public class WifiNanEventListener {
     private static final String TAG = "WifiNanEventListener";
-    private static final boolean DBG = true;
+    private static final boolean DBG = false;
     private static final boolean VDBG = false; // STOPSHIP if true
 
     /**
diff --git a/wifi/java/android/net/wifi/nan/WifiNanManager.java b/wifi/java/android/net/wifi/nan/WifiNanManager.java
index cb82268..667c4b1 100644
--- a/wifi/java/android/net/wifi/nan/WifiNanManager.java
+++ b/wifi/java/android/net/wifi/nan/WifiNanManager.java
@@ -38,7 +38,7 @@
  */
 public class WifiNanManager {
     private static final String TAG = "WifiNanManager";
-    private static final boolean DBG = true;
+    private static final boolean DBG = false;
     private static final boolean VDBG = false; // STOPSHIP if true
 
     private IBinder mBinder;
diff --git a/wifi/java/android/net/wifi/nan/WifiNanSession.java b/wifi/java/android/net/wifi/nan/WifiNanSession.java
index d0a9410..bc1787f 100644
--- a/wifi/java/android/net/wifi/nan/WifiNanSession.java
+++ b/wifi/java/android/net/wifi/nan/WifiNanSession.java
@@ -27,7 +27,7 @@
  */
 public class WifiNanSession {
     private static final String TAG = "WifiNanSession";
-    private static final boolean DBG = true;
+    private static final boolean DBG = false;
     private static final boolean VDBG = false; // STOPSHIP if true
 
     /**
diff --git a/wifi/java/android/net/wifi/nan/WifiNanSessionListener.java b/wifi/java/android/net/wifi/nan/WifiNanSessionListener.java
index 0925087..b9af7def 100644
--- a/wifi/java/android/net/wifi/nan/WifiNanSessionListener.java
+++ b/wifi/java/android/net/wifi/nan/WifiNanSessionListener.java
@@ -43,7 +43,7 @@
  */
 public class WifiNanSessionListener {
     private static final String TAG = "WifiNanSessionListener";
-    private static final boolean DBG = true;
+    private static final boolean DBG = false;
     private static final boolean VDBG = false; // STOPSHIP if true
 
     /**