Merge "Add hashCode() in UiccAccessRule."
diff --git a/api/current.txt b/api/current.txt
index db0946d7..8df028c 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -37032,17 +37032,6 @@
     method public byte[] transmit(byte[]) throws java.io.IOException;
   }
 
-  public abstract interface ISecureElementListener implements android.os.IInterface {
-    method public abstract void serviceConnected() throws android.os.RemoteException;
-  }
-
-  public static abstract class ISecureElementListener.Stub extends android.os.Binder implements android.se.omapi.ISecureElementListener {
-    ctor public ISecureElementListener.Stub();
-    method public android.os.IBinder asBinder();
-    method public static android.se.omapi.ISecureElementListener asInterface(android.os.IBinder);
-    method public boolean onTransact(int, android.os.Parcel, android.os.Parcel, int) throws android.os.RemoteException;
-  }
-
   public class Reader {
     method public void closeSessions();
     method public java.lang.String getName();
@@ -37052,13 +37041,19 @@
   }
 
   public class SEService {
-    ctor public SEService(android.content.Context, android.se.omapi.ISecureElementListener);
+    ctor public SEService(android.content.Context, android.se.omapi.SEService.SecureElementListener);
     method public android.se.omapi.Reader[] getReaders();
     method public java.lang.String getVersion();
     method public boolean isConnected();
     method public void shutdown();
   }
 
+  public static abstract class SEService.SecureElementListener extends android.os.Binder {
+    ctor public SEService.SecureElementListener();
+    method public android.os.IBinder asBinder();
+    method public void serviceConnected();
+  }
+
   public class Session {
     method public void close();
     method public void closeChannels();
diff --git a/core/java/android/app/Dialog.java b/core/java/android/app/Dialog.java
index b162cb1..2eabd86 100644
--- a/core/java/android/app/Dialog.java
+++ b/core/java/android/app/Dialog.java
@@ -291,7 +291,10 @@
                 if (mWindow.hasFeature(Window.FEATURE_ACTION_BAR)) {
                     mWindow.invalidatePanelMenu(Window.FEATURE_ACTION_BAR);
                 }
-                mDecor.setVisibility(View.VISIBLE);
+                if (mDecor.getVisibility() != View.VISIBLE) {
+                    mDecor.setVisibility(View.VISIBLE);
+                    sendShowMessage();
+                }
             }
             return;
         }
diff --git a/core/java/android/bluetooth/BluetoothUuid.java b/core/java/android/bluetooth/BluetoothUuid.java
index 0a0d214..605dbd2 100644
--- a/core/java/android/bluetooth/BluetoothUuid.java
+++ b/core/java/android/bluetooth/BluetoothUuid.java
@@ -79,9 +79,8 @@
             ParcelUuid.fromString("00001132-0000-1000-8000-00805F9B34FB");
     public static final ParcelUuid SAP =
             ParcelUuid.fromString("0000112D-0000-1000-8000-00805F9B34FB");
-    /* TODO: b/69623109 update this value. It will change to 16bit UUID!! */
     public static final ParcelUuid HearingAid =
-            ParcelUuid.fromString("7312C48F-22CC-497F-85FD-A0616A3B9E05");
+            ParcelUuid.fromString("0000FDF0-0000-1000-8000-00805f9b34fb");
 
     public static final ParcelUuid BASE_UUID =
             ParcelUuid.fromString("00000000-0000-1000-8000-00805F9B34FB");
diff --git a/core/java/android/net/metrics/NetworkMetrics.java b/core/java/android/net/metrics/NetworkMetrics.java
index 2425bba..66d92c4 100644
--- a/core/java/android/net/metrics/NetworkMetrics.java
+++ b/core/java/android/net/metrics/NetworkMetrics.java
@@ -98,6 +98,9 @@
 
     /** Accumulate a single netd sock_diag poll result reported by netd. */
     public void addTcpStatsResult(int sent, int lost, int rttUs, int sentAckDiffMs) {
+        if (pendingSummary == null) {
+            pendingSummary = new Summary(netId, transports);
+        }
         pendingSummary.tcpLossRate.count(lost, sent);
         pendingSummary.roundTripTimeUs.count(rttUs);
         pendingSummary.sentAckTimeDiffenceMs.count(sentAckDiffMs);
diff --git a/core/java/android/se/omapi/ISecureElementListener.aidl b/core/java/android/se/omapi/ISecureElementListener.aidl
index 3a99d63..e0c6e04 100644
--- a/core/java/android/se/omapi/ISecureElementListener.aidl
+++ b/core/java/android/se/omapi/ISecureElementListener.aidl
@@ -21,6 +21,7 @@
 
 /**
  * Interface to receive call-backs when the service is connected.
+ * @hide
  */
 interface ISecureElementListener {
   /**
diff --git a/core/java/android/se/omapi/SEService.java b/core/java/android/se/omapi/SEService.java
index b8937e6..d59e86a 100644
--- a/core/java/android/se/omapi/SEService.java
+++ b/core/java/android/se/omapi/SEService.java
@@ -59,6 +59,21 @@
      */
     public static final int NO_SUCH_ELEMENT_ERROR = 2;
 
+    /**
+     * Interface to send call-backs to the application when the service is connected.
+     */
+    public abstract static class SecureElementListener extends ISecureElementListener.Stub {
+        @Override
+        public IBinder asBinder() {
+            return this;
+        }
+
+        /**
+         * Called by the framework when the service is connected.
+         */
+        public void serviceConnected() {};
+    }
+
     private static final String TAG = "OMAPI.SEService";
 
     private final Object mLock = new Object();
@@ -98,9 +113,9 @@
      *            the context of the calling application. Cannot be
      *            <code>null</code>.
      * @param listener
-     *            a ISecureElementListener object. Can be <code>null</code>.
+     *            a SecureElementListener object. Can be <code>null</code>.
      */
-    public SEService(Context context, ISecureElementListener listener) {
+    public SEService(Context context, SecureElementListener listener) {
 
         if (context == null) {
             throw new NullPointerException("context must not be null");
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 701ed55..42efc21 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -2400,6 +2400,32 @@
          in the display pipeline plus some slack just to be sure. -->
     <integer name="config_drawLockTimeoutMillis">120</integer>
 
+    <!-- An array of device capabilities defined by GSMA SGP.22 v2.0.
+         The first item is the capability name that the device supports. The second item is the
+         major version. The minor and revision versions are default to 0s.
+         The device capabilities and their definition in the spec are:
+             gsm : gsmSupportedRelease
+             utran : utranSupportedRelease
+             cdma1x : cdma2000onexSupportedRelease
+             hrpd : cdma2000hrpdSupportedRelease
+             ehrpd : cdma2000ehrpdSupportedRelease
+             eutran : eutranSupportedRelease
+             nfc : contactlessSupportedRelease
+             crl : rspCrlSupportedVersion
+    -->
+    <string-array translatable="false" name="config_telephonyEuiccDeviceCapabilities">
+        <!-- Example:
+        <item>"gsm,11"</item>
+        <item>"utran,11"</item>
+        <item>"cdma1x,1"</item>
+        <item>"hrpd,3"</item>
+        <item>"ehrpd,12"</item>
+        <item>"eutran,11"</item>
+        <item>"nfc,1"</item>
+        <item>"crl,1"</item>
+        -->
+    </string-array>
+
     <!-- default telephony hardware configuration for this platform.
     -->
     <!-- this string array should be overridden by the device to present a list
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 0aec47e..ba9b8fe 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -1195,6 +1195,7 @@
   <java-symbol type="array" name="config_disabledUntilUsedPreinstalledCarrierApps" />
   <java-symbol type="array" name="config_callBarringMMI" />
   <java-symbol type="array" name="config_globalActionsList" />
+  <java-symbol type="array" name="config_telephonyEuiccDeviceCapabilities" />
   <java-symbol type="array" name="config_telephonyHardware" />
   <java-symbol type="array" name="config_keySystemUuidMapping" />
   <java-symbol type="array" name="config_gpsParameters" />
diff --git a/services/core/java/com/android/server/NativeDaemonConnector.java b/services/core/java/com/android/server/NativeDaemonConnector.java
index b5a8332..ad02aad 100644
--- a/services/core/java/com/android/server/NativeDaemonConnector.java
+++ b/services/core/java/com/android/server/NativeDaemonConnector.java
@@ -134,21 +134,23 @@
         mCallbackHandler = new Handler(mLooper, this);
 
         while (true) {
+            if (isShuttingDown()) break;
             try {
                 listenToSocket();
             } catch (Exception e) {
                 loge("Error in NativeDaemonConnector: " + e);
-                String shutdownAct = SystemProperties.get(
-                        ShutdownThread.SHUTDOWN_ACTION_PROPERTY, "");
-                if (shutdownAct != null && shutdownAct.length() > 0) {
-                    // The device is in middle of shutdown.
-                    break;
-                }
+                if (isShuttingDown()) break;
                 SystemClock.sleep(5000);
             }
         }
     }
 
+    private static boolean isShuttingDown() {
+        String shutdownAct = SystemProperties.get(
+            ShutdownThread.SHUTDOWN_ACTION_PROPERTY, "");
+        return shutdownAct != null && shutdownAct.length() > 0;
+    }
+
     @Override
     public boolean handleMessage(Message msg) {
         final String event = (String) msg.obj;
diff --git a/services/core/java/com/android/server/connectivity/Tethering.java b/services/core/java/com/android/server/connectivity/Tethering.java
index 69dec2d..1767a21 100644
--- a/services/core/java/com/android/server/connectivity/Tethering.java
+++ b/services/core/java/com/android/server/connectivity/Tethering.java
@@ -19,6 +19,7 @@
 import static android.hardware.usb.UsbManager.USB_CONFIGURED;
 import static android.hardware.usb.UsbManager.USB_CONNECTED;
 import static android.hardware.usb.UsbManager.USB_FUNCTION_RNDIS;
+import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
 import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_INTERFACE_NAME;
 import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_MODE;
 import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_STATE;
@@ -99,6 +100,7 @@
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
 import java.net.Inet4Address;
+import java.net.Inet6Address;
 import java.net.InetAddress;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -1302,19 +1304,16 @@
 
         protected void setUpstreamNetwork(NetworkState ns) {
             String iface = null;
-            if (ns != null && ns.linkProperties != null) {
+            if (ns != null) {
                 // Find the interface with the default IPv4 route. It may be the
                 // interface described by linkProperties, or one of the interfaces
                 // stacked on top of it.
-                mLog.i("Finding IPv4 upstream interface on: " + ns.linkProperties);
-                RouteInfo ipv4Default = RouteInfo.selectBestRoute(
-                    ns.linkProperties.getAllRoutes(), Inet4Address.ANY);
-                if (ipv4Default != null) {
-                    iface = ipv4Default.getInterface();
-                    mLog.i("Found interface " + ipv4Default.getInterface());
-                } else {
-                    mLog.i("No IPv4 upstream interface, giving up.");
-                }
+                mLog.i("Looking for default routes on: " + ns.linkProperties);
+                final String iface4 = getIPv4DefaultRouteInterface(ns);
+                final String iface6 = getIPv6DefaultRouteInterface(ns);
+                mLog.i("IPv4/IPv6 upstream interface(s): " + iface4 + "/" + iface6);
+
+                iface = (iface4 != null) ? iface4 : null /* TODO: iface6 */;
             }
 
             if (iface != null) {
@@ -1957,6 +1956,31 @@
         mTetherStates.remove(iface);
     }
 
+    private static String getIPv4DefaultRouteInterface(NetworkState ns) {
+        if (ns == null) return null;
+        return getInterfaceForDestination(ns.linkProperties, Inet4Address.ANY);
+    }
+
+    private static String getIPv6DefaultRouteInterface(NetworkState ns) {
+        if (ns == null) return null;
+        // An upstream network's IPv6 capability is currently only useful if it
+        // can be 64share'd downstream (RFC 7278). For now, that means mobile
+        // upstream networks only.
+        if (ns.networkCapabilities == null ||
+                !ns.networkCapabilities.hasTransport(TRANSPORT_CELLULAR)) {
+            return null;
+        }
+
+        return getInterfaceForDestination(ns.linkProperties, Inet6Address.ANY);
+    }
+
+    private static String getInterfaceForDestination(LinkProperties lp, InetAddress dst) {
+        final RouteInfo ri = (lp != null)
+                ? RouteInfo.selectBestRoute(lp.getAllRoutes(), dst)
+                : null;
+        return (ri != null) ? ri.getInterface() : null;
+    }
+
     private static String[] copy(String[] strarray) {
         return Arrays.copyOf(strarray, strarray.length);
     }