Merge "Fixed the incorrect permission for data/network service binding"
diff --git a/Android.bp b/Android.bp
index cb32b36..773c9b7 100644
--- a/Android.bp
+++ b/Android.bp
@@ -1116,6 +1116,9 @@
     local_sourcepaths: frameworks_base_subdirs,
     installable: false,
     metalava_enabled: true,
+    metalava_annotations_enabled: true,
+    metalava_previous_api: ":public-api-for-metalava-annotations",
+    metalava_merge_annotations_dir: "tools/metalava/manual",
 }
 
 droiddoc {
diff --git a/CleanSpec.mk b/CleanSpec.mk
index cc0e762..1f6860b 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -244,6 +244,7 @@
 $(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework_intermediates/core/java/android/os/storage/*)
 $(call add-clean-step, rm -rf $(OUT_DIR)/host/common/obj/JAVA_LIBRARIES/platformprotos_intermediates)
 $(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/framework/com.android.mediadrm.signer.jar)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/framework/com.android.location.provider.jar)
 # ******************************************************************
 # NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST ABOVE THIS BANNER
 # ******************************************************************
diff --git a/core/java/android/util/TimestampedValue.java b/core/java/android/util/TimestampedValue.java
index 2160380..75fa18d 100644
--- a/core/java/android/util/TimestampedValue.java
+++ b/core/java/android/util/TimestampedValue.java
@@ -72,6 +72,14 @@
         return Objects.hash(mReferenceTimeMillis, mValue);
     }
 
+    @Override
+    public String toString() {
+        return "TimestampedValue{"
+                + "mReferenceTimeMillis=" + mReferenceTimeMillis
+                + ", mValue=" + mValue
+                + '}';
+    }
+
     /**
      * Read a {@link TimestampedValue} from a parcel that was stored using
      * {@link #writeToParcel(Parcel, TimestampedValue)}.
diff --git a/core/java/com/android/internal/util/HexDump.java b/core/java/com/android/internal/util/HexDump.java
index 7be95d8..af00400 100644
--- a/core/java/com/android/internal/util/HexDump.java
+++ b/core/java/com/android/internal/util/HexDump.java
@@ -16,18 +16,21 @@
 
 package com.android.internal.util;
 
+import android.annotation.Nullable;
+
 public class HexDump
 {
     private final static char[] HEX_DIGITS = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
     private final static char[] HEX_LOWER_CASE_DIGITS = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
 
-    public static String dumpHexString(byte[] array)
-    {
+    public static String dumpHexString(@Nullable byte[] array) {
+        if (array == null) return "(null)";
         return dumpHexString(array, 0, array.length);
     }
 
-    public static String dumpHexString(byte[] array, int offset, int length)
+    public static String dumpHexString(@Nullable byte[] array, int offset, int length)
     {
+        if (array == null) return "(null)";
         StringBuilder result = new StringBuilder();
 
         byte[] line = new byte[16];
diff --git a/core/jni/android_os_Debug.cpp b/core/jni/android_os_Debug.cpp
index d3da21b..b35d92f 100644
--- a/core/jni/android_os_Debug.cpp
+++ b/core/jni/android_os_Debug.cpp
@@ -902,146 +902,6 @@
 jint android_os_Debug_getProxyObjectCount(JNIEnv* env, jobject clazz);
 jint android_os_Debug_getDeathObjectCount(JNIEnv* env, jobject clazz);
 
-
-/* pulled out of bionic */
-extern "C" void get_malloc_leak_info(uint8_t** info, size_t* overallSize,
-    size_t* infoSize, size_t* totalMemory, size_t* backtraceSize);
-extern "C" void free_malloc_leak_info(uint8_t* info);
-#define SIZE_FLAG_ZYGOTE_CHILD  (1<<31)
-
-static size_t gNumBacktraceElements;
-
-/*
- * This is a qsort() callback.
- *
- * See dumpNativeHeap() for comments about the data format and sort order.
- */
-static int compareHeapRecords(const void* vrec1, const void* vrec2)
-{
-    const size_t* rec1 = (const size_t*) vrec1;
-    const size_t* rec2 = (const size_t*) vrec2;
-    size_t size1 = *rec1;
-    size_t size2 = *rec2;
-
-    if (size1 < size2) {
-        return 1;
-    } else if (size1 > size2) {
-        return -1;
-    }
-
-    uintptr_t* bt1 = (uintptr_t*)(rec1 + 2);
-    uintptr_t* bt2 = (uintptr_t*)(rec2 + 2);
-    for (size_t idx = 0; idx < gNumBacktraceElements; idx++) {
-        uintptr_t addr1 = bt1[idx];
-        uintptr_t addr2 = bt2[idx];
-        if (addr1 == addr2) {
-            if (addr1 == 0)
-                break;
-            continue;
-        }
-        if (addr1 < addr2) {
-            return -1;
-        } else if (addr1 > addr2) {
-            return 1;
-        }
-    }
-
-    return 0;
-}
-
-/*
- * The get_malloc_leak_info() call returns an array of structs that
- * look like this:
- *
- *   size_t size
- *   size_t allocations
- *   intptr_t backtrace[32]
- *
- * "size" is the size of the allocation, "backtrace" is a fixed-size
- * array of function pointers, and "allocations" is the number of
- * allocations with the exact same size and backtrace.
- *
- * The entries are sorted by descending total size (i.e. size*allocations)
- * then allocation count.  For best results with "diff" we'd like to sort
- * primarily by individual size then stack trace.  Since the entries are
- * fixed-size, and we're allowed (by the current implementation) to mangle
- * them, we can do this in place.
- */
-static void dumpNativeHeap(FILE* fp)
-{
-    uint8_t* info = NULL;
-    size_t overallSize, infoSize, totalMemory, backtraceSize;
-
-    get_malloc_leak_info(&info, &overallSize, &infoSize, &totalMemory,
-        &backtraceSize);
-    if (info == NULL) {
-        fprintf(fp, "Native heap dump not available. To enable, run these"
-                    " commands (requires root):\n");
-        fprintf(fp, "# adb shell stop\n");
-        fprintf(fp, "# adb shell setprop libc.debug.malloc.options "
-                    "backtrace\n");
-        fprintf(fp, "# adb shell start\n");
-        return;
-    }
-    assert(infoSize != 0);
-    assert(overallSize % infoSize == 0);
-
-    fprintf(fp, "Android Native Heap Dump v1.0\n\n");
-
-    size_t recordCount = overallSize / infoSize;
-    fprintf(fp, "Total memory: %zu\n", totalMemory);
-    fprintf(fp, "Allocation records: %zd\n", recordCount);
-    fprintf(fp, "Backtrace size: %zd\n", backtraceSize);
-    fprintf(fp, "\n");
-
-    /* re-sort the entries */
-    gNumBacktraceElements = backtraceSize;
-    qsort(info, recordCount, infoSize, compareHeapRecords);
-
-    /* dump the entries to the file */
-    const uint8_t* ptr = info;
-    for (size_t idx = 0; idx < recordCount; idx++) {
-        size_t size = *(size_t*) ptr;
-        size_t allocations = *(size_t*) (ptr + sizeof(size_t));
-        uintptr_t* backtrace = (uintptr_t*) (ptr + sizeof(size_t) * 2);
-
-        fprintf(fp, "z %d  sz %8zu  num %4zu  bt",
-                (size & SIZE_FLAG_ZYGOTE_CHILD) != 0,
-                size & ~SIZE_FLAG_ZYGOTE_CHILD,
-                allocations);
-        for (size_t bt = 0; bt < backtraceSize; bt++) {
-            if (backtrace[bt] == 0) {
-                break;
-            } else {
-#ifdef __LP64__
-                fprintf(fp, " %016" PRIxPTR, backtrace[bt]);
-#else
-                fprintf(fp, " %08" PRIxPTR, backtrace[bt]);
-#endif
-            }
-        }
-        fprintf(fp, "\n");
-
-        ptr += infoSize;
-    }
-
-    free_malloc_leak_info(info);
-
-    fprintf(fp, "MAPS\n");
-    const char* maps = "/proc/self/maps";
-    UniqueFile in = MakeUniqueFile(maps, "re");
-    if (in == nullptr) {
-        fprintf(fp, "Could not open %s\n", maps);
-        return;
-    }
-    char buf[BUFSIZ];
-    while (size_t n = fread(buf, sizeof(char), BUFSIZ, in.get())) {
-        fwrite(buf, sizeof(char), n, fp);
-    }
-
-    fprintf(fp, "END\n");
-}
-
 static bool openFile(JNIEnv* env, jobject fileDescriptor, UniqueFile& fp)
 {
     if (fileDescriptor == NULL) {
@@ -1072,6 +932,9 @@
     return true;
 }
 
+/* pulled out of bionic */
+extern "C" void write_malloc_leak_info(FILE* fp);
+
 /*
  * Dump the native heap, writing human-readable output to the specified
  * file descriptor.
@@ -1085,7 +948,9 @@
     }
 
     ALOGD("Native heap dump starting...\n");
-    dumpNativeHeap(fp.get());
+    // Formatting of the native heap dump is handled by malloc debug itself.
+    // See https://android.googlesource.com/platform/bionic/+/master/libc/malloc_debug/README.md#backtrace-heap-dump-format
+    write_malloc_leak_info(fp.get());
     ALOGD("Native heap dump complete.\n");
 }
 
diff --git a/core/tests/coretests/src/com/android/internal/util/HexDumpTest.java b/core/tests/coretests/src/com/android/internal/util/HexDumpTest.java
index 951e87a..359bd5e 100644
--- a/core/tests/coretests/src/com/android/internal/util/HexDumpTest.java
+++ b/core/tests/coretests/src/com/android/internal/util/HexDumpTest.java
@@ -25,4 +25,7 @@
         assertEquals("ABCDEF", HexDump.toHexString(
                 new byte[] { (byte) 0xab, (byte) 0xcd, (byte) 0xef }, true));
     }
+    public void testNullArray() {
+        assertEquals("(null)", HexDump.toHexString(null));
+    }
 }
diff --git a/location/lib/Android.bp b/location/lib/Android.bp
new file mode 100644
index 0000000..447195d
--- /dev/null
+++ b/location/lib/Android.bp
@@ -0,0 +1,21 @@
+//
+// Copyright (C) 2018 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.
+//
+
+java_sdk_library {
+    name: "com.android.location.provider",
+    srcs: ["java/**/*.java"],
+    api_packages: ["com.android.location.provider"],
+}
diff --git a/location/lib/Android.mk b/location/lib/Android.mk
deleted file mode 100644
index 6642134..0000000
--- a/location/lib/Android.mk
+++ /dev/null
@@ -1,66 +0,0 @@
-#
-# Copyright (C) 2010 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)
-
-# the library
-# ============================================================
-include $(CLEAR_VARS)
-
-LOCAL_MODULE:= com.android.location.provider
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
-
-include $(BUILD_JAVA_LIBRARY)
-
-
-# ====  com.google.location.xml lib def  ========================
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := com.android.location.provider.xml
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_MODULE_CLASS := ETC
-
-# This will install the file in /system/etc/permissions
-#
-LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)/permissions
-
-LOCAL_SRC_FILES := $(LOCAL_MODULE)
-
-include $(BUILD_PREBUILT)
-
-# ==== Stub library  ===========================================
-include $(CLEAR_VARS)
-LOCAL_MODULE := com.android.location.provider-stubs-gen
-LOCAL_MODULE_CLASS := JAVA_LIBRARIES
-LOCAL_SRC_FILES := $(call all-java-files-under,java)
-LOCAL_DROIDDOC_STUB_OUT_DIR := $(TARGET_OUT_COMMON_INTERMEDIATES)/JAVA_LIBRARIES/com.android.location.provider.stubs_intermediates/src
-LOCAL_DROIDDOC_OPTIONS:= \
-    -hide 111 -hide 113 -hide 125 -hide 126 -hide 127 -hide 128 \
-    -stubpackages com.android.location.provider \
-    -nodocs
-LOCAL_UNINSTALLABLE_MODULE := true
-include $(BUILD_DROIDDOC)
-com_android_nfc_extras_gen_stamp := $(full_target)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := com.android.location.provider.stubs
-LOCAL_SOURCE_FILES_ALL_GENERATED := true
-LOCAL_SDK_VERSION := current
-LOCAL_ADDITIONAL_DEPENDENCIES := $(com_android_nfc_extras_gen_stamp)
-com_android_nfc_extras_gen_stamp :=
-include $(BUILD_STATIC_JAVA_LIBRARY)
diff --git a/location/lib/api/current.txt b/location/lib/api/current.txt
new file mode 100644
index 0000000..1e69f16
--- /dev/null
+++ b/location/lib/api/current.txt
@@ -0,0 +1,47 @@
+package com.android.location.provider {
+
+  public abstract deprecated class FusedProvider {
+    ctor public FusedProvider();
+    method public android.os.IBinder getBinder();
+  }
+
+  public abstract class LocationProviderBase {
+    ctor public LocationProviderBase(java.lang.String, com.android.location.provider.ProviderPropertiesUnbundled);
+    method public android.os.IBinder getBinder();
+    method public abstract void onDisable();
+    method public void onDump(java.io.FileDescriptor, java.io.PrintWriter, java.lang.String[]);
+    method public abstract void onEnable();
+    method public abstract int onGetStatus(android.os.Bundle);
+    method public abstract long onGetStatusUpdateTime();
+    method public boolean onSendExtraCommand(java.lang.String, android.os.Bundle);
+    method public abstract void onSetRequest(com.android.location.provider.ProviderRequestUnbundled, android.os.WorkSource);
+    method public final void reportLocation(android.location.Location);
+    field public static final java.lang.String EXTRA_NO_GPS_LOCATION = "noGPSLocation";
+    field public static final java.lang.String FUSED_PROVIDER = "fused";
+  }
+
+  public final class LocationRequestUnbundled {
+    method public long getFastestInterval();
+    method public long getInterval();
+    method public int getQuality();
+    method public float getSmallestDisplacement();
+    field public static final int ACCURACY_BLOCK = 102; // 0x66
+    field public static final int ACCURACY_CITY = 104; // 0x68
+    field public static final int ACCURACY_FINE = 100; // 0x64
+    field public static final int POWER_HIGH = 203; // 0xcb
+    field public static final int POWER_LOW = 201; // 0xc9
+    field public static final int POWER_NONE = 200; // 0xc8
+  }
+
+  public final class ProviderPropertiesUnbundled {
+    method public static com.android.location.provider.ProviderPropertiesUnbundled create(boolean, boolean, boolean, boolean, boolean, boolean, boolean, int, int);
+  }
+
+  public final class ProviderRequestUnbundled {
+    method public long getInterval();
+    method public java.util.List<com.android.location.provider.LocationRequestUnbundled> getLocationRequests();
+    method public boolean getReportLocation();
+  }
+
+}
+
diff --git a/location/lib/api/removed.txt b/location/lib/api/removed.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/location/lib/api/removed.txt
diff --git a/location/lib/api/system-current.txt b/location/lib/api/system-current.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/location/lib/api/system-current.txt
diff --git a/location/lib/api/system-removed.txt b/location/lib/api/system-removed.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/location/lib/api/system-removed.txt
diff --git a/location/lib/api/test-current.txt b/location/lib/api/test-current.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/location/lib/api/test-current.txt
diff --git a/location/lib/api/test-removed.txt b/location/lib/api/test-removed.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/location/lib/api/test-removed.txt
diff --git a/location/lib/com.android.location.provider.xml b/location/lib/com.android.location.provider.xml
deleted file mode 100644
index 000e68f..0000000
--- a/location/lib/com.android.location.provider.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2008 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.
--->
-
-<permissions>
-    <library name="com.android.location.provider"
-            file="/system/framework/com.android.location.provider.jar" />
-</permissions>
diff --git a/packages/SettingsLib/Android.mk b/packages/SettingsLib/Android.mk
index fd7c87e..c9f9972 100644
--- a/packages/SettingsLib/Android.mk
+++ b/packages/SettingsLib/Android.mk
@@ -21,6 +21,8 @@
 
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
+LOCAL_MIN_SDK_VERSION := 21
+
 include $(BUILD_STATIC_JAVA_LIBRARY)
 
 # For the test package.
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index dadd327..69b2bbf 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -3334,35 +3334,7 @@
                 && Uri.EMPTY.equals(proxy.getPacFileUrl())) {
             proxy = null;
         }
-        synchronized (mProxyTracker.mProxyLock) {
-            if (mProxyTracker.mDefaultProxy != null && mProxyTracker.mDefaultProxy.equals(proxy)) {
-                return;
-            }
-            if (mProxyTracker.mDefaultProxy == proxy) return; // catches repeated nulls
-            if (proxy != null &&  !proxy.isValid()) {
-                if (DBG) log("Invalid proxy properties, ignoring: " + proxy.toString());
-                return;
-            }
-
-            // This call could be coming from the PacManager, containing the port of the local
-            // proxy.  If this new proxy matches the global proxy then copy this proxy to the
-            // global (to get the correct local port), and send a broadcast.
-            // TODO: Switch PacManager to have its own message to send back rather than
-            // reusing EVENT_HAS_CHANGED_PROXY and this call to handleApplyDefaultProxy.
-            if ((mProxyTracker.mGlobalProxy != null) && (proxy != null)
-                    && (!Uri.EMPTY.equals(proxy.getPacFileUrl()))
-                    && proxy.getPacFileUrl().equals(mProxyTracker.mGlobalProxy.getPacFileUrl())) {
-                mProxyTracker.mGlobalProxy = proxy;
-                mProxyTracker.sendProxyBroadcast(mProxyTracker.mGlobalProxy);
-                return;
-            }
-            mProxyTracker.mDefaultProxy = proxy;
-
-            if (mProxyTracker.mGlobalProxy != null) return;
-            if (!mProxyTracker.mDefaultProxyDisabled) {
-                mProxyTracker.sendProxyBroadcast(proxy);
-            }
-        }
+        mProxyTracker.setDefaultProxy(proxy);
     }
 
     // If the proxy has changed from oldLp to newLp, resend proxy broadcast with default proxy.
diff --git a/services/core/java/com/android/server/connectivity/PacManager.java b/services/core/java/com/android/server/connectivity/PacManager.java
index 19b61e6..c370959 100644
--- a/services/core/java/com/android/server/connectivity/PacManager.java
+++ b/services/core/java/com/android/server/connectivity/PacManager.java
@@ -166,14 +166,14 @@
 
     /**
      * Updates the PAC Manager with current Proxy information. This is called by
-     * the ConnectivityService directly before a broadcast takes place to allow
+     * the ProxyTracker directly before a broadcast takes place to allow
      * the PacManager to indicate that the broadcast should not be sent and the
      * PacManager will trigger a new broadcast when it is ready.
      *
      * @param proxy Proxy information that is about to be broadcast.
      * @return Returns true when the broadcast should not be sent
      */
-    public synchronized boolean setCurrentProxyScriptUrl(ProxyInfo proxy) {
+    synchronized boolean setCurrentProxyScriptUrl(ProxyInfo proxy) {
         if (!Uri.EMPTY.equals(proxy.getPacFileUrl())) {
             if (proxy.getPacFileUrl().equals(mPacUrl) && (proxy.getPort() > 0)) {
                 // Allow to send broadcast, nothing to do.
diff --git a/services/core/java/com/android/server/connectivity/ProxyTracker.java b/services/core/java/com/android/server/connectivity/ProxyTracker.java
index daaedd8..dc65e1e 100644
--- a/services/core/java/com/android/server/connectivity/ProxyTracker.java
+++ b/services/core/java/com/android/server/connectivity/ProxyTracker.java
@@ -51,15 +51,25 @@
     // possible
     @NonNull
     public final Object mProxyLock = new Object();
+    // The global proxy is the proxy that is set device-wide, overriding any network-specific
+    // proxy. Note however that proxies are hints ; the system does not enforce their use. Hence
+    // this value is only for querying.
     @Nullable
     @GuardedBy("mProxyLock")
     public ProxyInfo mGlobalProxy = null;
+    // The default proxy is the proxy that applies to no particular network if the global proxy
+    // is not set. Individual networks have their own settings that override this. This member
+    // is set through setDefaultProxy, which is called when the default network changes proxies
+    // in its LinkProperties, or when ConnectivityService switches to a new default network, or
+    // when PacManager resolves the proxy.
     @Nullable
     @GuardedBy("mProxyLock")
     public volatile ProxyInfo mDefaultProxy = null;
+    // Whether the default proxy is disabled. TODO : make this mDefaultProxyEnabled
     @GuardedBy("mProxyLock")
     public boolean mDefaultProxyDisabled = false;
 
+    // The object responsible for Proxy Auto Configuration (PAC).
     @NonNull
     private final PacManager mPacManager;
 
@@ -98,6 +108,16 @@
         return Objects.equals(pa, pb) && (pa == null || Objects.equals(pa.getHost(), pb.getHost()));
     }
 
+    /**
+     * Gets the default system-wide proxy.
+     *
+     * This will return the global proxy if set, otherwise the default proxy if in use. Note
+     * that this is not necessarily the proxy that any given process should use, as the right
+     * proxy for a process is the proxy for the network this process will use, which may be
+     * different from this value. This value is simply the default in case there is no proxy set
+     * in the network that will be used by a specific process.
+     * @return The default system-wide proxy or null if none.
+     */
     @Nullable
     public ProxyInfo getDefaultProxy() {
         // This information is already available as a world read/writable jvm property.
@@ -108,6 +128,11 @@
         }
     }
 
+    /**
+     * Gets the global proxy.
+     *
+     * @return The global proxy or null if none.
+     */
     @Nullable
     public ProxyInfo getGlobalProxy() {
         // This information is already available as a world read/writable jvm property.
@@ -116,19 +141,22 @@
         }
     }
 
-    public boolean setCurrentProxyScriptUrl(@NonNull final ProxyInfo proxy) {
-        return mPacManager.setCurrentProxyScriptUrl(proxy);
-    }
-
-    // TODO : make the argument NonNull final
-    public void sendProxyBroadcast(@Nullable ProxyInfo proxy) {
-        if (proxy == null) proxy = new ProxyInfo("", 0, "");
-        if (setCurrentProxyScriptUrl(proxy)) return;
-        if (DBG) Slog.d(TAG, "sending Proxy Broadcast for " + proxy);
+    /**
+     * Sends the system broadcast informing apps about a new proxy configuration.
+     *
+     * Confusingly this method also sets the PAC file URL. TODO : separate this, it has nothing
+     * to do in a "sendProxyBroadcast" method.
+     * @param proxyInfo the proxy spec, or null for no proxy.
+     */
+    // TODO : make the argument NonNull final and the method private
+    public void sendProxyBroadcast(@Nullable ProxyInfo proxyInfo) {
+        if (proxyInfo == null) proxyInfo = new ProxyInfo("", 0, "");
+        if (mPacManager.setCurrentProxyScriptUrl(proxyInfo)) return;
+        if (DBG) Slog.d(TAG, "sending Proxy Broadcast for " + proxyInfo);
         Intent intent = new Intent(Proxy.PROXY_CHANGE_ACTION);
         intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING |
                 Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
-        intent.putExtra(Proxy.EXTRA_PROXY_INFO, proxy);
+        intent.putExtra(Proxy.EXTRA_PROXY_INFO, proxyInfo);
         final long ident = Binder.clearCallingIdentity();
         try {
             mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
@@ -137,30 +165,39 @@
         }
     }
 
-    public void setGlobalProxy(@Nullable ProxyInfo proxyProperties) {
+    /**
+     * Sets the global proxy in memory. Also writes the values to the global settings of the device.
+     *
+     * @param proxyInfo the proxy spec, or null for no proxy.
+     */
+    public void setGlobalProxy(@Nullable ProxyInfo proxyInfo) {
         synchronized (mProxyLock) {
-            if (proxyProperties == mGlobalProxy) return;
-            if (proxyProperties != null && proxyProperties.equals(mGlobalProxy)) return;
-            if (mGlobalProxy != null && mGlobalProxy.equals(proxyProperties)) return;
+            // ProxyInfo#equals is not commutative :( and is public API, so it can't be fixed.
+            if (proxyInfo == mGlobalProxy) return;
+            if (proxyInfo != null && proxyInfo.equals(mGlobalProxy)) return;
+            if (mGlobalProxy != null && mGlobalProxy.equals(proxyInfo)) return;
 
-            String host = "";
-            int port = 0;
-            String exclList = "";
-            String pacFileUrl = "";
-            if (proxyProperties != null && (!TextUtils.isEmpty(proxyProperties.getHost()) ||
-                    !Uri.EMPTY.equals(proxyProperties.getPacFileUrl()))) {
-                if (!proxyProperties.isValid()) {
-                    if (DBG) Slog.d(TAG, "Invalid proxy properties, ignoring: " + proxyProperties);
+            final String host;
+            final int port;
+            final String exclList;
+            final String pacFileUrl;
+            if (proxyInfo != null && (!TextUtils.isEmpty(proxyInfo.getHost()) ||
+                    !Uri.EMPTY.equals(proxyInfo.getPacFileUrl()))) {
+                if (!proxyInfo.isValid()) {
+                    if (DBG) Slog.d(TAG, "Invalid proxy properties, ignoring: " + proxyInfo);
                     return;
                 }
-                mGlobalProxy = new ProxyInfo(proxyProperties);
+                mGlobalProxy = new ProxyInfo(proxyInfo);
                 host = mGlobalProxy.getHost();
                 port = mGlobalProxy.getPort();
                 exclList = mGlobalProxy.getExclusionListAsString();
-                if (!Uri.EMPTY.equals(proxyProperties.getPacFileUrl())) {
-                    pacFileUrl = proxyProperties.getPacFileUrl().toString();
-                }
+                pacFileUrl = Uri.EMPTY.equals(proxyInfo.getPacFileUrl())
+                        ? "" : proxyInfo.getPacFileUrl().toString();
             } else {
+                host = "";
+                port = 0;
+                exclList = "";
+                pacFileUrl = "";
                 mGlobalProxy = null;
             }
             final ContentResolver res = mContext.getContentResolver();
@@ -175,10 +212,45 @@
                 Binder.restoreCallingIdentity(token);
             }
 
-            if (mGlobalProxy == null) {
-                proxyProperties = mDefaultProxy;
+            sendProxyBroadcast(mGlobalProxy == null ? mDefaultProxy : proxyInfo);
+        }
+    }
+
+    /**
+     * Sets the default proxy for the device.
+     *
+     * The default proxy is the proxy used for networks that do not have a specific proxy.
+     * @param proxyInfo the proxy spec, or null for no proxy.
+     */
+    public void setDefaultProxy(@Nullable ProxyInfo proxyInfo) {
+        synchronized (mProxyLock) {
+            if (mDefaultProxy != null && mDefaultProxy.equals(proxyInfo)) {
+                return;
             }
-            sendProxyBroadcast(proxyProperties);
+            if (mDefaultProxy == proxyInfo) return; // catches repeated nulls
+            if (proxyInfo != null &&  !proxyInfo.isValid()) {
+                if (DBG) Slog.d(TAG, "Invalid proxy properties, ignoring: " + proxyInfo);
+                return;
+            }
+
+            // This call could be coming from the PacManager, containing the port of the local
+            // proxy. If this new proxy matches the global proxy then copy this proxy to the
+            // global (to get the correct local port), and send a broadcast.
+            // TODO: Switch PacManager to have its own message to send back rather than
+            // reusing EVENT_HAS_CHANGED_PROXY and this call to handleApplyDefaultProxy.
+            if ((mGlobalProxy != null) && (proxyInfo != null)
+                    && (!Uri.EMPTY.equals(proxyInfo.getPacFileUrl()))
+                    && proxyInfo.getPacFileUrl().equals(mGlobalProxy.getPacFileUrl())) {
+                mGlobalProxy = proxyInfo;
+                sendProxyBroadcast(mGlobalProxy);
+                return;
+            }
+            mDefaultProxy = proxyInfo;
+
+            if (mGlobalProxy != null) return;
+            if (!mDefaultProxyDisabled) {
+                sendProxyBroadcast(proxyInfo);
+            }
         }
     }
 }
diff --git a/services/core/java/com/android/server/timedetector/TimeDetectorService.java b/services/core/java/com/android/server/timedetector/TimeDetectorService.java
index efd49b5..0ec24d8 100644
--- a/services/core/java/com/android/server/timedetector/TimeDetectorService.java
+++ b/services/core/java/com/android/server/timedetector/TimeDetectorService.java
@@ -21,6 +21,7 @@
 import android.app.timedetector.ITimeDetectorService;
 import android.app.timedetector.TimeSignal;
 import android.content.Context;
+import android.os.Binder;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.DumpUtils;
@@ -69,7 +70,13 @@
     @Override
     public void suggestTime(@NonNull TimeSignal timeSignal) {
         enforceSetTimePermission();
-        mTimeDetectorStrategy.suggestTime(timeSignal);
+
+        long callerIdToken = Binder.clearCallingIdentity();
+        try {
+            mTimeDetectorStrategy.suggestTime(timeSignal);
+        } finally {
+            Binder.restoreCallingIdentity(callerIdToken);
+        }
     }
 
     @Override
diff --git a/tests/net/java/android/net/apf/ApfTest.java b/tests/net/java/android/net/apf/ApfTest.java
index 0248e97..9838020 100644
--- a/tests/net/java/android/net/apf/ApfTest.java
+++ b/tests/net/java/android/net/apf/ApfTest.java
@@ -314,9 +314,9 @@
 
         // Test multiply.
         gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoadImmediate(Register.R0, 1234567890);
+        gen.addLoadImmediate(Register.R0, 123456789);
         gen.addMul(2);
-        gen.addJumpIfR0Equals(1234567890 * 2, gen.DROP_LABEL);
+        gen.addJumpIfR0Equals(123456789 * 2, gen.DROP_LABEL);
         assertDrop(gen);
 
         // Test divide.
@@ -379,10 +379,10 @@
 
         // Test multiply.
         gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoadImmediate(Register.R0, 1234567890);
+        gen.addLoadImmediate(Register.R0, 123456789);
         gen.addLoadImmediate(Register.R1, 2);
         gen.addMulR1();
-        gen.addJumpIfR0Equals(1234567890 * 2, gen.DROP_LABEL);
+        gen.addJumpIfR0Equals(123456789 * 2, gen.DROP_LABEL);
         assertDrop(gen);
 
         // Test divide.