Merge "Libcore: Change miranda modifier flag" into lmp-dev
diff --git a/JavaLibrary.mk b/JavaLibrary.mk
index ff0f6e9..c857390 100644
--- a/JavaLibrary.mk
+++ b/JavaLibrary.mk
@@ -95,7 +95,7 @@
 LOCAL_SRC_FILES := $(test_src_files)
 LOCAL_JAVA_RESOURCE_DIRS := $(test_resource_dirs)
 LOCAL_NO_STANDARD_LIBRARIES := true
-LOCAL_JAVA_LIBRARIES := bouncycastle core-libart core-junit okhttp
+LOCAL_JAVA_LIBRARIES := core-libart okhttp core-junit bouncycastle
 LOCAL_STATIC_JAVA_LIBRARIES := core-tests-support sqlite-jdbc mockwebserver nist-pkix-tests
 LOCAL_JAVACFLAGS := $(local_javac_flags)
 LOCAL_MODULE := core-tests
@@ -109,7 +109,7 @@
 LOCAL_SRC_FILES := $(call all-test-java-files-under,support)
 LOCAL_JAVA_RESOURCE_DIRS := $(test_resource_dirs)
 LOCAL_NO_STANDARD_LIBRARIES := true
-LOCAL_JAVA_LIBRARIES := bouncycastle core-libart core-junit
+LOCAL_JAVA_LIBRARIES := core-libart core-junit bouncycastle
 LOCAL_JAVACFLAGS := $(local_javac_flags)
 LOCAL_MODULE := core-tests-support
 LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/JavaLibrary.mk
@@ -175,7 +175,8 @@
     include $(CLEAR_VARS)
     LOCAL_SRC_FILES := $(test_src_files)
     LOCAL_JAVA_RESOURCE_DIRS := $(test_resource_dirs)
-    LOCAL_JAVA_LIBRARIES := bouncycastle-hostdex core-junit-hostdex core-tests-support-hostdex okhttp-hostdex
+    LOCAL_NO_STANDARD_LIBRARIES := true
+    LOCAL_JAVA_LIBRARIES := core-libart-hostdex okhttp-hostdex bouncycastle-hostdex core-junit-hostdex core-tests-support-hostdex
     LOCAL_STATIC_JAVA_LIBRARIES := sqlite-jdbc-host mockwebserver-host nist-pkix-tests-host
     LOCAL_JAVACFLAGS := $(local_javac_flags)
     LOCAL_MODULE_TAGS := optional
@@ -189,7 +190,8 @@
     include $(CLEAR_VARS)
     LOCAL_SRC_FILES := $(call all-test-java-files-under,support)
     LOCAL_JAVA_RESOURCE_DIRS := $(test_resource_dirs)
-    LOCAL_JAVA_LIBRARIES := bouncycastle-hostdex core-junit-hostdex
+    LOCAL_NO_STANDARD_LIBRARIES := true
+    LOCAL_JAVA_LIBRARIES := core-libart-hostdex core-junit-hostdex bouncycastle-hostdex
     LOCAL_JAVACFLAGS := $(local_javac_flags)
     LOCAL_MODULE_TAGS := optional
     LOCAL_MODULE := core-tests-support-hostdex
diff --git a/benchmarks/Android.mk b/benchmarks/Android.mk
index 4b90704..c0a38a0 100644
--- a/benchmarks/Android.mk
+++ b/benchmarks/Android.mk
@@ -1,34 +1,39 @@
+# -*- mode: makefile -*-
+# Copyright (C) 2013 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.
+
 LOCAL_PATH:= $(call my-dir)
-##################################################
-include $(CLEAR_VARS)
 
 ifeq ($(LIBCORE_SKIP_TESTS),)
-# Only compile source java files in this apk.
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
+##################################################
+include $(CLEAR_VARS)
 LOCAL_MODULE := benchmarks
-
-LOCAL_STATIC_JAVA_LIBRARIES := \
-	caliper-prebuilt \
-	core-tests
-
-LOCAL_JAVA_LIBRARIES := \
-	bouncycastle \
-	conscrypt \
-	core-libart
-
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+LOCAL_STATIC_JAVA_LIBRARIES := caliper-prebuilt core-tests
+LOCAL_NO_STANDARD_LIBRARIES := true
+LOCAL_JAVA_LIBRARIES := core-libart conscrypt core-junit bouncycastle framework
 LOCAL_MODULE_TAGS := tests
-
 LOCAL_MODULE_PATH := $(PRODUCT_OUT)/data/caliperperf
-
+LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
 include $(BUILD_JAVA_LIBRARY)
 
 ##################################################
 # Prebuilt Java libraries
 include $(CLEAR_VARS)
-
-LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES := \
-	caliper-prebuilt:libs/caliper.jar
-
+LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES := caliper-prebuilt:libs/caliper.jar
+LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
 include $(BUILD_MULTI_PREBUILT)
+
 endif
diff --git a/expectations/knownfailures.txt b/expectations/knownfailures.txt
index 175fe03..ebb4305 100644
--- a/expectations/knownfailures.txt
+++ b/expectations/knownfailures.txt
@@ -1354,6 +1354,7 @@
     "com.android.org.apache.harmony.sql.tests.java.sql.DataTruncationTest#testGetParameter",
     "com.android.org.apache.harmony.sql.tests.java.sql.DataTruncationTest#testGetRead",
     "com.android.org.apache.harmony.sql.tests.java.sql.DataTruncationTest#testGetTransferSize",
+    "com.android.org.apache.harmony.sql.tests.java.sql.DataTruncationTest#testDataTruncationintbooleanbooleanintint",
     "com.android.org.apache.harmony.sql.tests.java.sql.DateTest#test_valueOf_IllegalArgumentException",
     "com.android.org.apache.harmony.sql.tests.java.sql.DriverManagerTest#testDeregisterDriver",
     "com.android.org.apache.harmony.sql.tests.java.sql.DriverManagerTest#testGetConnectionString",
@@ -1426,6 +1427,23 @@
   ]
 },
 {
+  description: "java.util.beans: the harmony tests were broken by Android commit 19a270e90b1e992c1f6639f355ae13564c2f3a6a",
+  bug: 17394106,
+  names: [
+    "com.android.org.apache.harmony.beans.tests.java.beans.PropertyChangeSupportTest#testSerialization",
+    "com.android.org.apache.harmony.beans.tests.java.beans.PropertyChangeSupportTest#testGetPropertyChangeListener_String_Normal",
+    "com.android.org.apache.harmony.beans.tests.java.beans.PropertyChangeSupportTest#testAddPropertyChangeListener_PropertyChangeListener_String_Normal",
+    "com.android.org.apache.harmony.beans.tests.java.beans.PropertyChangeSupportTest#testAddPropertyChangeListener_PropertyChangeListener_Normal"
+  ]
+},
+{
+  description: "java.util.beans: the serialized form references org.apache not com.android.org.apache",
+  bug: 17394106,
+  names: [
+    "com.android.org.apache.harmony.beans.tests.java.beans.PropertyChangeSupportTest#testSerializationCompatibility"
+  ]
+},
+{
   description: "Known failure in GregorianCalendarTest",
   bug: 12778197,
   name: "org.apache.harmony.tests.java.util.GregorianCalendarTest#test_computeTime"
@@ -1434,6 +1452,7 @@
   description: "SpdyConnection issue https://github.com/square/okhttp/issues/644 crashes the test app. Android does not provide SPDY/HTTP_2 connections by default so have been suppressed.",
   bug: 14462336,
   names: [
+    "com.squareup.okhttp.ConnectionPoolTest",
     "com.squareup.okhttp.internal.spdy.SpdyConnectionTest",
     "com.squareup.okhttp.internal.http.HttpOverHttp20Draft09Test",
     "com.squareup.okhttp.internal.http.HttpOverSpdy3Test",
diff --git a/libart/src/main/java/java/lang/ref/Reference.java b/libart/src/main/java/java/lang/ref/Reference.java
index 31ea588..70967b5 100644
--- a/libart/src/main/java/java/lang/ref/Reference.java
+++ b/libart/src/main/java/java/lang/ref/Reference.java
@@ -199,7 +199,19 @@
      * @return the referent to which reference refers, or {@code null} if the
      *         object has been cleared.
      */
-    public native T get();
+    public T get() {
+        return getReferent();
+    }
+
+    /**
+     * Returns the referent of the reference object.
+     *
+     * @return the referent to which reference refers, or {@code null} if the
+     *         object has been cleared. Required since the compiler
+     *         intrisifies getReferent() since we can't intrinsify Reference.get()
+     *         due to incorrect devirtualization (and inlining) of PhantomReference.get().
+     */
+    private final native T getReferent();
 
     /**
      * Checks whether the reference object has been enqueued.
diff --git a/luni/src/main/java/java/math/BigDecimal.java b/luni/src/main/java/java/math/BigDecimal.java
index 03ce8dd..f735607 100644
--- a/luni/src/main/java/java/math/BigDecimal.java
+++ b/luni/src/main/java/java/math/BigDecimal.java
@@ -1025,6 +1025,14 @@
         }
 
         long diffScale = ((long)this.scale - divisor.scale) - scale;
+
+        // Check whether the diffScale will fit into an int. See http://b/17393664.
+        if (bitLength(diffScale) > 32) {
+            throw new ArithmeticException(
+                    "Unable to perform divisor / dividend scaling: the difference in scale is too" +
+                            " big (" + diffScale + ")");
+        }
+
         if(this.bitLength < 64 && divisor.bitLength < 64 ) {
             if(diffScale == 0) {
                 return dividePrimitiveLongs(this.smallValue,
diff --git a/luni/src/main/java/java/nio/SelectorImpl.java b/luni/src/main/java/java/nio/SelectorImpl.java
index efa8712..45406b1 100644
--- a/luni/src/main/java/java/nio/SelectorImpl.java
+++ b/luni/src/main/java/java/nio/SelectorImpl.java
@@ -39,6 +39,7 @@
 import libcore.io.Libcore;
 
 import static android.system.OsConstants.EINTR;
+import static android.system.OsConstants.POLLERR;
 import static android.system.OsConstants.POLLHUP;
 import static android.system.OsConstants.POLLIN;
 import static android.system.OsConstants.POLLOUT;
@@ -259,7 +260,7 @@
 
             int ops = key.interestOpsNoCheck();
             int selectedOps = 0;
-            if ((pollFd.revents & POLLHUP) != 0) {
+            if ((pollFd.revents & POLLHUP) != 0 || (pollFd.revents & POLLERR) != 0) {
                 // If there was an error condition, we definitely want to wake listeners,
                 // regardless of what they're waiting for. Failure is always interesting.
                 selectedOps |= ops;
diff --git a/luni/src/main/java/libcore/net/event/NetworkEventDispatcher.java b/luni/src/main/java/libcore/net/event/NetworkEventDispatcher.java
new file mode 100644
index 0000000..d1c7c21
--- /dev/null
+++ b/luni/src/main/java/libcore/net/event/NetworkEventDispatcher.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+package libcore.net.event;
+
+import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+/**
+ * A singleton used to dispatch network events to registered listeners.
+ */
+public class NetworkEventDispatcher {
+
+  private static final NetworkEventDispatcher instance = new NetworkEventDispatcher();
+
+  private final List<NetworkEventListener> listeners =
+      new CopyOnWriteArrayList<NetworkEventListener>();
+
+  /**
+   * Returns the shared {@link NetworkEventDispatcher} instance.
+   */
+  public static NetworkEventDispatcher getInstance() {
+    return instance;
+  }
+
+  /** Visible for testing. Use {@link #getInstance()} instead. */
+  protected NetworkEventDispatcher() {
+  }
+
+  /**
+   * Registers a listener to be notified when network events occur.
+   * It can be deregistered using {@link #removeListener(NetworkEventListener)}
+   */
+  public void addListener(NetworkEventListener toAdd) {
+    if (toAdd == null) {
+      throw new NullPointerException("toAdd == null");
+    }
+    listeners.add(toAdd);
+  }
+
+  /**
+   * De-registers a listener previously added with {@link #addListener(NetworkEventListener)}. If
+   * the listener was not previously registered this is a no-op.
+   */
+  public void removeListener(NetworkEventListener toRemove) {
+    for (NetworkEventListener listener : listeners) {
+      if (listener == toRemove) {
+        listeners.remove(listener);
+        return;
+      }
+    }
+  }
+
+  /**
+   * Notifies registered listeners of a network configuration change.
+   */
+  public void onNetworkConfigurationChanged() {
+    for (NetworkEventListener listener : listeners) {
+      try {
+        listener.onNetworkConfigurationChanged();
+      } catch (RuntimeException e) {
+        System.logI("Exception thrown during network event propagation", e);
+      }
+    }
+  }
+}
diff --git a/luni/src/main/java/libcore/net/event/NetworkEventListener.java b/luni/src/main/java/libcore/net/event/NetworkEventListener.java
new file mode 100644
index 0000000..73b9f88
--- /dev/null
+++ b/luni/src/main/java/libcore/net/event/NetworkEventListener.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+package libcore.net.event;
+
+/**
+ * A base class for objects interested in network events.
+ */
+public class NetworkEventListener {
+
+  public void onNetworkConfigurationChanged() {
+    // no-op
+  }
+}
diff --git a/luni/src/main/java/libcore/util/ZoneInfo.java b/luni/src/main/java/libcore/util/ZoneInfo.java
index fbd120b..4a70a83 100644
--- a/luni/src/main/java/libcore/util/ZoneInfo.java
+++ b/luni/src/main/java/libcore/util/ZoneInfo.java
@@ -156,22 +156,21 @@
             mOffsets[i] -= mRawOffset;
         }
 
-        // Is this zone still observing DST?
+        // Is this zone observing DST currently or in the future?
         // We don't care if they've historically used it: most places have at least once.
-        // We want to know whether the last "schedule info" (the unix times in the mTransitions
-        // array) is in the future. If it is, DST is still relevant.
         // See http://code.google.com/p/android/issues/detail?id=877.
         // This test means that for somewhere like Morocco, which tried DST in 2009 but has
         // no future plans (and thus no future schedule info) will report "true" from
         // useDaylightTime at the start of 2009 but "false" at the end. This seems appropriate.
         boolean usesDst = false;
-        long currentUnixTime = System.currentTimeMillis() / 1000;
-        if (mTransitions.length > 0) {
-            // (We're really dealing with uint32_t values, so long is most convenient in Java.)
-            long latestScheduleTime = ((long) mTransitions[mTransitions.length - 1]) & 0xffffffff;
-            if (currentUnixTime < latestScheduleTime) {
+        int currentUnixTimeSeconds = (int) (System.currentTimeMillis() / 1000);
+        int i = mTransitions.length - 1;
+        while (i >= 0 && mTransitions[i] >= currentUnixTimeSeconds) {
+            if (mIsDsts[mTypes[i]] > 0) {
                 usesDst = true;
+                break;
             }
+            i--;
         }
         mUseDst = usesDst;
 
diff --git a/luni/src/test/java/libcore/java/security/KeyPairGeneratorTest.java b/luni/src/test/java/libcore/java/security/KeyPairGeneratorTest.java
index eb0e3d0..e7fdb1f 100644
--- a/luni/src/test/java/libcore/java/security/KeyPairGeneratorTest.java
+++ b/luni/src/test/java/libcore/java/security/KeyPairGeneratorTest.java
@@ -56,28 +56,63 @@
 public class KeyPairGeneratorTest extends TestCase {
 
     public void test_providerCount() {
-        // If this fails remember to add/remove _provider methods below. This test is sharded
-        // because it takes so long.
-        assertEquals(4, Security.getProviders().length);
+        Provider[] providers = Security.getProviders();
+        // We expect there to be at least one provider.
+        assertTrue(providers.length > 0);
+        // If this fails remember to add _provider methods below. This test is sharded because it
+        // takes a long time to execute.
+        assertTrue(providers.length < 10);
     }
 
     public void test_getInstance_provider0() throws Exception {
-        test_getInstance(Security.getProviders()[0]);
+        test_getInstance(0);
     }
 
     public void test_getInstance_provider1() throws Exception {
-        test_getInstance(Security.getProviders()[1]);
+        test_getInstance(1);
     }
 
     public void test_getInstance_provider2() throws Exception {
-        test_getInstance(Security.getProviders()[2]);
+        test_getInstance(2);
     }
 
     public void test_getInstance_provider3() throws Exception {
-        test_getInstance(Security.getProviders()[3]);
+        test_getInstance(3);
     }
 
-    private void test_getInstance(Provider provider) throws Exception {
+    public void test_getInstance_provider4() throws Exception {
+        test_getInstance(4);
+    }
+
+    public void test_getInstance_provider5() throws Exception {
+        test_getInstance(5);
+    }
+
+    public void test_getInstance_provider6() throws Exception {
+        test_getInstance(6);
+    }
+
+    public void test_getInstance_provider7() throws Exception {
+        test_getInstance(7);
+    }
+
+    public void test_getInstance_provider8() throws Exception {
+        test_getInstance(8);
+    }
+
+    public void test_getInstance_provider9() throws Exception {
+        test_getInstance(9);
+    }
+
+    private void test_getInstance(int providerIndex) throws Exception {
+        Provider[] providers = Security.getProviders();
+        if (providerIndex >= providers.length) {
+            // Providers can be added by vendors and other tests. We do not
+            // specify a fixed number and silenty pass if the provider at the
+            // specified index does not exist.
+            return;
+        }
+        Provider provider = providers[providerIndex];
         Set<Provider.Service> services = provider.getServices();
         for (Provider.Service service : services) {
             String type = service.getType();
diff --git a/luni/src/test/java/libcore/net/event/NetworkEventDispatcherTest.java b/luni/src/test/java/libcore/net/event/NetworkEventDispatcherTest.java
new file mode 100644
index 0000000..dc32da6
--- /dev/null
+++ b/luni/src/test/java/libcore/net/event/NetworkEventDispatcherTest.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+package libcore.net.event;
+
+import junit.framework.TestCase;
+
+/**
+ * Tests for {@link NetworkEventDispatcher}.
+ */
+public class NetworkEventDispatcherTest extends TestCase {
+
+  public void testGetInstance_isSingleton() {
+    assertSame(NetworkEventDispatcher.getInstance(), NetworkEventDispatcher.getInstance());
+  }
+
+  public void testAddListener_null() throws Exception {
+    NetworkEventDispatcher networkEventDispatcher = new NetworkEventDispatcher() {};
+    try {
+      networkEventDispatcher.addListener(null);
+      fail();
+    } catch (NullPointerException expected) {
+    }
+  }
+
+  public void testOnNetworkConfigurationChanged_noListeners() throws Exception {
+    NetworkEventDispatcher networkEventDispatcher = new NetworkEventDispatcher() {};
+    networkEventDispatcher.onNetworkConfigurationChanged();
+  }
+
+  public void testFireNetworkEvent_oneListener() throws Exception {
+    FakeNetworkEventListener listener = new FakeNetworkEventListener();
+    NetworkEventDispatcher networkEventDispatcher = new NetworkEventDispatcher() {};
+    networkEventDispatcher.addListener(listener);
+
+    networkEventDispatcher.onNetworkConfigurationChanged();
+
+    listener.assertNetworkConfigurationChangedEvent(1);
+  }
+
+  public void testRemoveEventListener() throws Exception {
+    FakeNetworkEventListener listener = new FakeNetworkEventListener();
+    NetworkEventDispatcher networkEventDispatcher = new NetworkEventDispatcher() {};
+    networkEventDispatcher.addListener(listener);
+    networkEventDispatcher.removeListener(listener);
+
+    networkEventDispatcher.onNetworkConfigurationChanged();
+
+    listener.assertNetworkConfigurationChangedEvent(0);
+  }
+
+  private static class FakeNetworkEventListener extends NetworkEventListener {
+
+    private int networkConfigurationChangedCount;
+
+    @Override
+    public void onNetworkConfigurationChanged() {
+      networkConfigurationChangedCount++;
+    }
+
+    public void assertNetworkConfigurationChangedEvent(int expectedCount) {
+      assertEquals(expectedCount, networkConfigurationChangedCount);
+    }
+  }
+}