Merge "Mark installable jars with installable: true"
diff --git a/CleanSpec.mk b/CleanSpec.mk
index 1f6860b..96aa055 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -245,6 +245,7 @@
 $(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)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/framework/com.android.future.usb.accessory.jar)
 # ******************************************************************
 # NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST ABOVE THIS BANNER
 # ******************************************************************
diff --git a/api/current.txt b/api/current.txt
index 241117b..9ffd50f 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -40176,6 +40176,7 @@
     field public static final java.lang.String KEY_SMS_REQUIRES_DESTINATION_NUMBER_CONVERSION_BOOL = "sms_requires_destination_number_conversion_bool";
     field public static final java.lang.String KEY_SUPPORT_3GPP_CALL_FORWARDING_WHILE_ROAMING_BOOL = "support_3gpp_call_forwarding_while_roaming_bool";
     field public static final java.lang.String KEY_SUPPORT_CONFERENCE_CALL_BOOL = "support_conference_call_bool";
+    field public static final java.lang.String KEY_SUPPORT_EMERGENCY_SMS_OVER_IMS_BOOL = "support_emergency_sms_over_ims_bool";
     field public static final java.lang.String KEY_SUPPORT_PAUSE_IMS_VIDEO_CALLS_BOOL = "support_pause_ims_video_calls_bool";
     field public static final java.lang.String KEY_SUPPORT_SWAP_AFTER_MERGE_BOOL = "support_swap_after_merge_bool";
     field public static final java.lang.String KEY_TREAT_DOWNGRADED_VIDEO_CALLS_AS_VIDEO_CALLS_BOOL = "treat_downgraded_video_calls_as_video_calls_bool";
@@ -40831,9 +40832,13 @@
     method public java.lang.String getIccAuthentication(int, int, java.lang.String);
     method public java.lang.String getImei();
     method public java.lang.String getImei(int);
+    method public java.lang.String getTypeAllocationCode();
+    method public java.lang.String getTypeAllocationCode(int);
     method public java.lang.String getLine1Number();
     method public java.lang.String getMeid();
     method public java.lang.String getMeid(int);
+    method public java.lang.String getManufacturerCode();
+    method public java.lang.String getManufacturerCode(int);
     method public java.lang.String getMmsUAProfUrl();
     method public java.lang.String getMmsUserAgent();
     method public java.lang.String getNai();
@@ -68724,7 +68729,7 @@
   public final class Pattern implements java.io.Serializable {
     method public java.util.function.Predicate<java.lang.String> asPredicate();
     method public static java.util.regex.Pattern compile(java.lang.String);
-    method public static java.util.regex.Pattern compile(java.lang.String, int) throws java.util.regex.PatternSyntaxException;
+    method public static java.util.regex.Pattern compile(java.lang.String, int);
     method public int flags();
     method public java.util.regex.Matcher matcher(java.lang.CharSequence);
     method public static boolean matches(java.lang.String, java.lang.CharSequence);
diff --git a/core/java/android/os/Binder.java b/core/java/android/os/Binder.java
index 5652d6d..a81d16a 100644
--- a/core/java/android/os/Binder.java
+++ b/core/java/android/os/Binder.java
@@ -536,6 +536,20 @@
     }
 
     /**
+     * Resolves a transaction code to a human readable name.
+     *
+     * <p>Default implementation is a stub that returns null.
+     * <p>AIDL generated code will return the original method name.
+     *
+     * @param transactionCode The code to resolve.
+     * @return A human readable name.
+     * @hide
+     */
+    public @Nullable String getTransactionName(int transactionCode) {
+        return null;
+    }
+
+    /**
      * Implemented to call the more convenient version
      * {@link #dump(FileDescriptor, PrintWriter, String[])}.
      */
@@ -592,7 +606,7 @@
 
     /**
      * Print the object's state into the given stream.
-     * 
+     *
      * @param fd The raw file descriptor that the dump is being sent to.
      * @param fout The file to which you should dump your state.  This will be
      * closed for you after you return.
diff --git a/core/java/android/text/TextUtils.java b/core/java/android/text/TextUtils.java
index 3e64af4..aca2bb8 100644
--- a/core/java/android/text/TextUtils.java
+++ b/core/java/android/text/TextUtils.java
@@ -333,8 +333,16 @@
     }
 
     /**
-     * String.split() returns [''] when the string to be split is empty. This returns []. This does
-     * not remove any empty strings from the result. For example split("a,", ","  ) returns {"a", ""}.
+     *
+     * This method yields the same result as {@code text.split(expression, -1)} except that if
+     * {@code text.isEmpty()} then this method returns an empty array whereas
+     * {@code "".split(expression, -1)} would have returned an array with a single {@code ""}.
+     *
+     * The {@code -1} means that trailing empty Strings are not removed from the result; for
+     * example split("a,", ","  ) returns {"a", ""}. Note that whether a leading zero-width match
+     * can result in a leading {@code ""} depends on whether your app
+     * {@link android.content.pm.ApplicationInfo#targetSdkVersion targets an SDK version}
+     * {@code <= 28}; see {@link Pattern#split(CharSequence, int)}.
      *
      * @param text the string to split
      * @param expression the regular expression to match
@@ -351,8 +359,16 @@
     }
 
     /**
-     * Splits a string on a pattern. String.split() returns [''] when the string to be
-     * split is empty. This returns []. This does not remove any empty strings from the result.
+     * Splits a string on a pattern. This method yields the same result as
+     * {@code pattern.split(text, -1)} except that if {@code text.isEmpty()} then this method
+     * returns an empty array whereas {@code pattern.split("", -1)} would have returned an array
+     * with a single {@code ""}.
+     *
+     * The {@code -1} means that trailing empty Strings are not removed from the result;
+     * Note that whether a leading zero-width match can result in a leading {@code ""} depends
+     * on whether your app {@link android.content.pm.ApplicationInfo#targetSdkVersion targets
+     * an SDK version} {@code <= 28}; see {@link Pattern#split(CharSequence, int)}.
+     *
      * @param text the string to split
      * @param pattern the regular expression to match
      * @return an array of strings. The array will be empty if text is empty
diff --git a/core/java/android/util/Half.java b/core/java/android/util/Half.java
index 84c2e83..5718d99 100644
--- a/core/java/android/util/Half.java
+++ b/core/java/android/util/Half.java
@@ -20,8 +20,6 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 
-import sun.misc.FloatingDecimal;
-
 /**
  * <p>The {@code Half} class is a wrapper and a utility class to manipulate half-precision 16-bit
  * <a href="https://en.wikipedia.org/wiki/Half-precision_floating-point_format">IEEE 754</a>
@@ -1026,7 +1024,7 @@
      *         half-precision float value
      */
     public static @HalfFloat short parseHalf(@NonNull String s) throws NumberFormatException {
-        return toHalf(FloatingDecimal.parseFloat(s));
+        return toHalf(Float.parseFloat(s));
     }
 
     /**
diff --git a/core/java/android/util/IntArray.java b/core/java/android/util/IntArray.java
index 3617aa7..5a74ec0 100644
--- a/core/java/android/util/IntArray.java
+++ b/core/java/android/util/IntArray.java
@@ -18,9 +18,11 @@
 
 import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.Preconditions;
-import java.util.Arrays;
+
 import libcore.util.EmptyArray;
 
+import java.util.Arrays;
+
 /**
  * Implements a growing array of int primitives.
  *
@@ -102,7 +104,7 @@
         ensureCapacity(1);
         int rightSegment = mSize - index;
         mSize++;
-        checkBounds(index);
+        ArrayUtils.checkBounds(mSize, index);
 
         if (rightSegment != 0) {
             // Move by 1 all values from the right of 'index'
@@ -175,7 +177,7 @@
      * Returns the value at the specified position in this array.
      */
     public int get(int index) {
-        checkBounds(index);
+        ArrayUtils.checkBounds(mSize, index);
         return mValues[index];
     }
 
@@ -183,7 +185,7 @@
      * Sets the value at the specified position in this array.
      */
     public void set(int index, int value) {
-        checkBounds(index);
+        ArrayUtils.checkBounds(mSize, index);
         mValues[index] = value;
     }
 
@@ -205,7 +207,7 @@
      * Removes the value at the specified index from this array.
      */
     public void remove(int index) {
-        checkBounds(index);
+        ArrayUtils.checkBounds(mSize, index);
         System.arraycopy(mValues, index + 1, mValues, index, mSize - index - 1);
         mSize--;
     }
@@ -223,10 +225,4 @@
     public int[] toArray() {
         return Arrays.copyOf(mValues, mSize);
     }
-
-    private void checkBounds(int index) {
-        if (index < 0 || mSize <= index) {
-            throw new ArrayIndexOutOfBoundsException(mSize, index);
-        }
-    }
 }
diff --git a/core/java/android/util/LongArray.java b/core/java/android/util/LongArray.java
index 9b0489c..9ddb0e2 100644
--- a/core/java/android/util/LongArray.java
+++ b/core/java/android/util/LongArray.java
@@ -18,9 +18,11 @@
 
 import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.Preconditions;
-import java.util.Arrays;
+
 import libcore.util.EmptyArray;
 
+import java.util.Arrays;
+
 /**
  * Implements a growing array of long primitives.
  *
@@ -102,7 +104,7 @@
         ensureCapacity(1);
         int rightSegment = mSize - index;
         mSize++;
-        checkBounds(index);
+        ArrayUtils.checkBounds(mSize, index);
 
         if (rightSegment != 0) {
             // Move by 1 all values from the right of 'index'
@@ -162,7 +164,7 @@
      * Returns the value at the specified position in this array.
      */
     public long get(int index) {
-        checkBounds(index);
+        ArrayUtils.checkBounds(mSize, index);
         return mValues[index];
     }
 
@@ -170,7 +172,7 @@
      * Sets the value at the specified position in this array.
      */
     public void set(int index, long value) {
-        checkBounds(index);
+        ArrayUtils.checkBounds(mSize, index);
         mValues[index] = value;
     }
 
@@ -192,7 +194,7 @@
      * Removes the value at the specified index from this array.
      */
     public void remove(int index) {
-        checkBounds(index);
+        ArrayUtils.checkBounds(mSize, index);
         System.arraycopy(mValues, index + 1, mValues, index, mSize - index - 1);
         mSize--;
     }
@@ -210,10 +212,4 @@
     public long[] toArray() {
         return Arrays.copyOf(mValues, mSize);
     }
-
-    private void checkBounds(int index) {
-        if (index < 0 || mSize <= index) {
-            throw new ArrayIndexOutOfBoundsException(mSize, index);
-        }
-    }
 }
diff --git a/core/java/com/android/internal/net/NetworkStatsFactory.java b/core/java/com/android/internal/net/NetworkStatsFactory.java
index 41802cc..fb54e69 100644
--- a/core/java/com/android/internal/net/NetworkStatsFactory.java
+++ b/core/java/com/android/internal/net/NetworkStatsFactory.java
@@ -192,7 +192,7 @@
                 reader.finishLine();
             }
         } catch (NullPointerException|NumberFormatException e) {
-            throw new ProtocolException("problem parsing stats", e);
+            throw protocolExceptionWithCause("problem parsing stats", e);
         } finally {
             IoUtils.closeQuietly(reader);
             StrictMode.setThreadPolicy(savedPolicy);
@@ -242,7 +242,7 @@
                 reader.finishLine();
             }
         } catch (NullPointerException|NumberFormatException e) {
-            throw new ProtocolException("problem parsing stats", e);
+            throw protocolExceptionWithCause("problem parsing stats", e);
         } finally {
             IoUtils.closeQuietly(reader);
             StrictMode.setThreadPolicy(savedPolicy);
@@ -339,7 +339,7 @@
                 reader.finishLine();
             }
         } catch (NullPointerException|NumberFormatException e) {
-            throw new ProtocolException("problem parsing idx " + idx, e);
+            throw protocolExceptionWithCause("problem parsing idx " + idx, e);
         } finally {
             IoUtils.closeQuietly(reader);
             StrictMode.setThreadPolicy(savedPolicy);
@@ -376,4 +376,10 @@
 
     @VisibleForTesting
     public static native int nativeReadNetworkStatsDev(NetworkStats stats);
+
+    private static ProtocolException protocolExceptionWithCause(String message, Throwable cause) {
+        ProtocolException pe = new ProtocolException(message);
+        pe.initCause(cause);
+        return pe;
+    }
 }
diff --git a/core/java/com/android/internal/util/ArrayUtils.java b/core/java/com/android/internal/util/ArrayUtils.java
index 91bc681..534f3b6 100644
--- a/core/java/com/android/internal/util/ArrayUtils.java
+++ b/core/java/com/android/internal/util/ArrayUtils.java
@@ -587,4 +587,17 @@
     public static @NonNull String[] defeatNullable(@Nullable String[] val) {
         return (val != null) ? val : EmptyArray.STRING;
     }
+
+    /**
+     * Throws {@link ArrayIndexOutOfBoundsException} if the index is out of bounds.
+     *
+     * @param len length of the array. Must be non-negative
+     * @param index the index to check
+     * @throws ArrayIndexOutOfBoundsException if the {@code index} is out of bounds of the array
+     */
+    public static void checkBounds(int len, int index) {
+        if (index < 0 || len <= index) {
+            throw new ArrayIndexOutOfBoundsException("length=" + len + "; index=" + index);
+        }
+    }
 }
diff --git a/core/tests/coretests/AndroidTest.xml b/core/tests/coretests/AndroidTest.xml
index 23d70b8..4b70cda 100644
--- a/core/tests/coretests/AndroidTest.xml
+++ b/core/tests/coretests/AndroidTest.xml
@@ -23,5 +23,6 @@
     <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
         <option name="package" value="com.android.frameworks.coretests" />
         <option name="runner" value="android.support.test.runner.AndroidJUnitRunner" />
+        <option name="hidden-api-checks" value="false"/>
     </test>
 </configuration>
diff --git a/libs/hwui/tests/macrobench/main.cpp b/libs/hwui/tests/macrobench/main.cpp
index 616558f..648fd35 100644
--- a/libs/hwui/tests/macrobench/main.cpp
+++ b/libs/hwui/tests/macrobench/main.cpp
@@ -135,8 +135,6 @@
         gBenchmarkReporter.reset(new benchmark::ConsoleReporter());
     } else if (!strcmp(format, "json")) {
         gBenchmarkReporter.reset(new benchmark::JSONReporter());
-    } else if (!strcmp(format, "csv")) {
-        gBenchmarkReporter.reset(new benchmark::CSVReporter());
     } else {
         fprintf(stderr, "Unknown format '%s'", format);
         return false;
diff --git a/libs/usb/Android.bp b/libs/usb/Android.bp
index b8f2904..027a748 100644
--- a/libs/usb/Android.bp
+++ b/libs/usb/Android.bp
@@ -1 +1,23 @@
+//
+// 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.future.usb.accessory",
+    srcs: ["src/**/*.java"],
+    api_packages: ["com.android.future.usb"],
+}
+
 subdirs = ["tests/*"]
diff --git a/libs/usb/Android.mk b/libs/usb/Android.mk
deleted file mode 100644
index 129828f..0000000
--- a/libs/usb/Android.mk
+++ /dev/null
@@ -1,27 +0,0 @@
-#
-# Copyright (C) 2011 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)
-
-LOCAL_SRC_FILES := $(call all-java-files-under,src)
-
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_MODULE:= com.android.future.usb.accessory
-
-include $(BUILD_JAVA_LIBRARY)
diff --git a/libs/usb/api/current.txt b/libs/usb/api/current.txt
new file mode 100644
index 0000000..8488db5
--- /dev/null
+++ b/libs/usb/api/current.txt
@@ -0,0 +1,25 @@
+package com.android.future.usb {
+
+  public class UsbAccessory {
+    method public java.lang.String getDescription();
+    method public java.lang.String getManufacturer();
+    method public java.lang.String getModel();
+    method public java.lang.String getSerial();
+    method public java.lang.String getUri();
+    method public java.lang.String getVersion();
+  }
+
+  public class UsbManager {
+    method public static com.android.future.usb.UsbAccessory getAccessory(android.content.Intent);
+    method public com.android.future.usb.UsbAccessory[] getAccessoryList();
+    method public static com.android.future.usb.UsbManager getInstance(android.content.Context);
+    method public boolean hasPermission(com.android.future.usb.UsbAccessory);
+    method public android.os.ParcelFileDescriptor openAccessory(com.android.future.usb.UsbAccessory);
+    method public void requestPermission(com.android.future.usb.UsbAccessory, android.app.PendingIntent);
+    field public static final java.lang.String ACTION_USB_ACCESSORY_ATTACHED = "android.hardware.usb.action.USB_ACCESSORY_ATTACHED";
+    field public static final java.lang.String ACTION_USB_ACCESSORY_DETACHED = "android.hardware.usb.action.USB_ACCESSORY_DETACHED";
+    field public static final java.lang.String EXTRA_PERMISSION_GRANTED = "permission";
+  }
+
+}
+
diff --git a/libs/usb/api/removed.txt b/libs/usb/api/removed.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/libs/usb/api/removed.txt
diff --git a/libs/usb/api/system-current.txt b/libs/usb/api/system-current.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/libs/usb/api/system-current.txt
diff --git a/libs/usb/api/system-removed.txt b/libs/usb/api/system-removed.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/libs/usb/api/system-removed.txt
diff --git a/libs/usb/api/test-current.txt b/libs/usb/api/test-current.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/libs/usb/api/test-current.txt
diff --git a/libs/usb/api/test-removed.txt b/libs/usb/api/test-removed.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/libs/usb/api/test-removed.txt
diff --git a/libs/usb/tests/AccessoryChat/Android.mk b/libs/usb/tests/AccessoryChat/Android.mk
index ecb455a..cfe2da1 100644
--- a/libs/usb/tests/AccessoryChat/Android.mk
+++ b/libs/usb/tests/AccessoryChat/Android.mk
@@ -23,4 +23,6 @@
 
 LOCAL_PACKAGE_NAME := AccessoryChat
 
+LOCAL_PRIVATE_PLATFORM_APIS := true
+
 include $(BUILD_PACKAGE)
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java b/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java
index 851b78c..ecbcb40 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java
@@ -27,7 +27,6 @@
 import com.android.systemui.util.wakelock.WakeLock;
 
 import java.util.Calendar;
-import java.util.GregorianCalendar;
 
 /**
  * The policy controlling doze.
@@ -139,7 +138,7 @@
     }
 
     private long roundToNextMinute(long timeInMillis) {
-        Calendar calendar = GregorianCalendar.getInstance();
+        Calendar calendar = Calendar.getInstance();
         calendar.setTimeInMillis(timeInMillis);
         calendar.set(Calendar.MILLISECOND, 0);
         calendar.set(Calendar.SECOND, 0);
diff --git a/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java b/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java
old mode 100644
new mode 100755
index 2d2869d..5a6a1c2
--- a/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java
@@ -251,12 +251,13 @@
                             entry = Pair.<String, String>create(packageAndClassName[0], null);
                             break;
                         case 2:
-                            if (packageAndClassName[1] != null
-                                    && packageAndClassName[1].startsWith(".")) {
-                                entry = Pair.<String, String>create(
-                                        packageAndClassName[0],
-                                        packageAndClassName[0] + packageAndClassName[1]);
+                            if (packageAndClassName[1] != null) {
+                                entry = Pair.<String, String>create(packageAndClassName[0],
+                                        packageAndClassName[1].startsWith(".")
+                                                ? packageAndClassName[0] + packageAndClassName[1]
+                                                : packageAndClassName[1]);
                             }
+                            break;
                     }
                     if (entry != null) {
                         sSettingsPackageAndClassNamePairList.add(entry);
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 0b24db0..28ac784 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -2191,6 +2191,7 @@
                         updateCapabilities(oldScore, nai, nai.networkCapabilities);
                         // If score has changed, rebroadcast to NetworkFactories. b/17726566
                         if (oldScore != nai.getCurrentScore()) sendUpdatedScoreToFactories(nai);
+                        if (valid) handleFreshlyValidatedNetwork(nai);
                     }
                     updateInetCondition(nai);
                     // Let the NetworkAgent know the state of its network
@@ -2285,6 +2286,16 @@
                 mDefaultRequest.networkCapabilities, nai.networkCapabilities);
     }
 
+    private void handleFreshlyValidatedNetwork(NetworkAgentInfo nai) {
+        if (nai == null) return;
+        // If the Private DNS mode is opportunistic, reprogram the DNS servers
+        // in order to restart a validation pass from within netd.
+        final PrivateDnsConfig cfg = mDnsManager.getPrivateDnsConfig();
+        if (cfg.useTls && TextUtils.isEmpty(cfg.hostname)) {
+            updateDnses(nai.linkProperties, null, nai.network.netId);
+        }
+    }
+
     private void handlePrivateDnsSettingsChanged() {
         final PrivateDnsConfig cfg = mDnsManager.getPrivateDnsConfig();
 
diff --git a/services/core/java/com/android/server/NetworkTimeUpdateService.java b/services/core/java/com/android/server/NetworkTimeUpdateService.java
index 2c24798..1ff455ea 100644
--- a/services/core/java/com/android/server/NetworkTimeUpdateService.java
+++ b/services/core/java/com/android/server/NetworkTimeUpdateService.java
@@ -16,318 +16,15 @@
 
 package com.android.server;
 
-import android.app.AlarmManager;
-import android.app.PendingIntent;
-import android.content.BroadcastReceiver;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.pm.PackageManager;
-import android.database.ContentObserver;
-import android.net.ConnectivityManager;
-import android.net.ConnectivityManager.NetworkCallback;
-import android.net.Network;
-import android.os.Binder;
-import android.os.Handler;
-import android.os.HandlerThread;
-import android.os.Looper;
-import android.os.Message;
-import android.os.SystemClock;
-import android.os.PowerManager;
-import android.provider.Settings;
-import android.util.Log;
-import android.util.NtpTrustedTime;
-import android.util.TimeUtils;
-import android.util.TrustedTime;
-
-import com.android.internal.telephony.TelephonyIntents;
-import com.android.internal.util.DumpUtils;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
+import android.os.IBinder;
 
 /**
- * Monitors the network time and updates the system time if it is out of sync
- * and there hasn't been any NITZ update from the carrier recently.
- * If looking up the network time fails for some reason, it tries a few times with a short
- * interval and then resets to checking on longer intervals.
- * <p>
- * If the user enables AUTO_TIME, it will check immediately for the network time, if NITZ wasn't
- * available.
- * </p>
+ * An interface for NetworkTimeUpdateService implementations. Eventually part or all of this service
+ * will be subsumed into {@link com.android.server.timedetector.TimeDetectorService}. In the
+ * meantime this interface allows Android to use either the old or new implementation.
  */
-public class NetworkTimeUpdateService extends Binder {
-
-    private static final String TAG = "NetworkTimeUpdateService";
-    private static final boolean DBG = false;
-
-    private static final int EVENT_AUTO_TIME_CHANGED = 1;
-    private static final int EVENT_POLL_NETWORK_TIME = 2;
-    private static final int EVENT_NETWORK_CHANGED = 3;
-
-    private static final String ACTION_POLL =
-            "com.android.server.NetworkTimeUpdateService.action.POLL";
-
-    private static final int POLL_REQUEST = 0;
-
-    private static final long NOT_SET = -1;
-    private long mNitzTimeSetTime = NOT_SET;
-    private Network mDefaultNetwork = null;
-
-    private Context mContext;
-    private TrustedTime mTime;
-
-    // NTP lookup is done on this thread and handler
-    private Handler mHandler;
-    private AlarmManager mAlarmManager;
-    private PendingIntent mPendingPollIntent;
-    private SettingsObserver mSettingsObserver;
-    private ConnectivityManager mCM;
-    private NetworkTimeUpdateCallback mNetworkTimeUpdateCallback;
-    // The last time that we successfully fetched the NTP time.
-    private long mLastNtpFetchTime = NOT_SET;
-    private final PowerManager.WakeLock mWakeLock;
-
-    // Normal polling frequency
-    private final long mPollingIntervalMs;
-    // Try-again polling interval, in case the network request failed
-    private final long mPollingIntervalShorterMs;
-    // Number of times to try again
-    private final int mTryAgainTimesMax;
-    // If the time difference is greater than this threshold, then update the time.
-    private final int mTimeErrorThresholdMs;
-    // Keeps track of how many quick attempts were made to fetch NTP time.
-    // During bootup, the network may not have been up yet, or it's taking time for the
-    // connection to happen.
-    private int mTryAgainCounter;
-
-    public NetworkTimeUpdateService(Context context) {
-        mContext = context;
-        mTime = NtpTrustedTime.getInstance(context);
-        mAlarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
-        mCM = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
-        Intent pollIntent = new Intent(ACTION_POLL, null);
-        mPendingPollIntent = PendingIntent.getBroadcast(mContext, POLL_REQUEST, pollIntent, 0);
-
-        mPollingIntervalMs = mContext.getResources().getInteger(
-                com.android.internal.R.integer.config_ntpPollingInterval);
-        mPollingIntervalShorterMs = mContext.getResources().getInteger(
-                com.android.internal.R.integer.config_ntpPollingIntervalShorter);
-        mTryAgainTimesMax = mContext.getResources().getInteger(
-                com.android.internal.R.integer.config_ntpRetry);
-        mTimeErrorThresholdMs = mContext.getResources().getInteger(
-                com.android.internal.R.integer.config_ntpThreshold);
-
-        mWakeLock = ((PowerManager) context.getSystemService(Context.POWER_SERVICE)).newWakeLock(
-                PowerManager.PARTIAL_WAKE_LOCK, TAG);
-    }
+public interface NetworkTimeUpdateService extends IBinder {
 
     /** Initialize the receivers and initiate the first NTP request */
-    public void systemRunning() {
-        registerForTelephonyIntents();
-        registerForAlarms();
-
-        HandlerThread thread = new HandlerThread(TAG);
-        thread.start();
-        mHandler = new MyHandler(thread.getLooper());
-        mNetworkTimeUpdateCallback = new NetworkTimeUpdateCallback();
-        mCM.registerDefaultNetworkCallback(mNetworkTimeUpdateCallback, mHandler);
-
-        mSettingsObserver = new SettingsObserver(mHandler, EVENT_AUTO_TIME_CHANGED);
-        mSettingsObserver.observe(mContext);
-    }
-
-    private void registerForTelephonyIntents() {
-        IntentFilter intentFilter = new IntentFilter();
-        intentFilter.addAction(TelephonyIntents.ACTION_NETWORK_SET_TIME);
-        mContext.registerReceiver(mNitzReceiver, intentFilter);
-    }
-
-    private void registerForAlarms() {
-        mContext.registerReceiver(
-            new BroadcastReceiver() {
-                @Override
-                public void onReceive(Context context, Intent intent) {
-                    mHandler.obtainMessage(EVENT_POLL_NETWORK_TIME).sendToTarget();
-                }
-            }, new IntentFilter(ACTION_POLL));
-    }
-
-    private void onPollNetworkTime(int event) {
-        // If Automatic time is not set, don't bother. Similarly, if we don't
-        // have any default network, don't bother.
-        if (!isAutomaticTimeRequested() || mDefaultNetwork == null) return;
-        mWakeLock.acquire();
-        try {
-            onPollNetworkTimeUnderWakeLock(event);
-        } finally {
-            mWakeLock.release();
-        }
-    }
-
-    private void onPollNetworkTimeUnderWakeLock(int event) {
-        final long refTime = SystemClock.elapsedRealtime();
-        // If NITZ time was received less than mPollingIntervalMs time ago,
-        // no need to sync to NTP.
-        if (mNitzTimeSetTime != NOT_SET && refTime - mNitzTimeSetTime < mPollingIntervalMs) {
-            resetAlarm(mPollingIntervalMs);
-            return;
-        }
-        final long currentTime = System.currentTimeMillis();
-        if (DBG) Log.d(TAG, "System time = " + currentTime);
-        // Get the NTP time
-        if (mLastNtpFetchTime == NOT_SET || refTime >= mLastNtpFetchTime + mPollingIntervalMs
-                || event == EVENT_AUTO_TIME_CHANGED) {
-            if (DBG) Log.d(TAG, "Before Ntp fetch");
-
-            // force refresh NTP cache when outdated
-            if (mTime.getCacheAge() >= mPollingIntervalMs) {
-                mTime.forceRefresh();
-            }
-
-            // only update when NTP time is fresh
-            if (mTime.getCacheAge() < mPollingIntervalMs) {
-                final long ntp = mTime.currentTimeMillis();
-                mTryAgainCounter = 0;
-                // If the clock is more than N seconds off or this is the first time it's been
-                // fetched since boot, set the current time.
-                if (Math.abs(ntp - currentTime) > mTimeErrorThresholdMs
-                        || mLastNtpFetchTime == NOT_SET) {
-                    // Set the system time
-                    if (DBG && mLastNtpFetchTime == NOT_SET
-                            && Math.abs(ntp - currentTime) <= mTimeErrorThresholdMs) {
-                        Log.d(TAG, "For initial setup, rtc = " + currentTime);
-                    }
-                    if (DBG) Log.d(TAG, "Ntp time to be set = " + ntp);
-                    // Make sure we don't overflow, since it's going to be converted to an int
-                    if (ntp / 1000 < Integer.MAX_VALUE) {
-                        SystemClock.setCurrentTimeMillis(ntp);
-                    }
-                } else {
-                    if (DBG) Log.d(TAG, "Ntp time is close enough = " + ntp);
-                }
-                mLastNtpFetchTime = SystemClock.elapsedRealtime();
-            } else {
-                // Try again shortly
-                mTryAgainCounter++;
-                if (mTryAgainTimesMax < 0 || mTryAgainCounter <= mTryAgainTimesMax) {
-                    resetAlarm(mPollingIntervalShorterMs);
-                } else {
-                    // Try much later
-                    mTryAgainCounter = 0;
-                    resetAlarm(mPollingIntervalMs);
-                }
-                return;
-            }
-        }
-        resetAlarm(mPollingIntervalMs);
-    }
-
-    /**
-     * Cancel old alarm and starts a new one for the specified interval.
-     *
-     * @param interval when to trigger the alarm, starting from now.
-     */
-    private void resetAlarm(long interval) {
-        mAlarmManager.cancel(mPendingPollIntent);
-        long now = SystemClock.elapsedRealtime();
-        long next = now + interval;
-        mAlarmManager.set(AlarmManager.ELAPSED_REALTIME, next, mPendingPollIntent);
-    }
-
-    /**
-     * Checks if the user prefers to automatically set the time.
-     */
-    private boolean isAutomaticTimeRequested() {
-        return Settings.Global.getInt(
-                mContext.getContentResolver(), Settings.Global.AUTO_TIME, 0) != 0;
-    }
-
-    /** Receiver for Nitz time events */
-    private BroadcastReceiver mNitzReceiver = new BroadcastReceiver() {
-
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            String action = intent.getAction();
-            if (DBG) Log.d(TAG, "Received " + action);
-            if (TelephonyIntents.ACTION_NETWORK_SET_TIME.equals(action)) {
-                mNitzTimeSetTime = SystemClock.elapsedRealtime();
-            }
-        }
-    };
-
-    /** Handler to do the network accesses on */
-    private class MyHandler extends Handler {
-
-        public MyHandler(Looper l) {
-            super(l);
-        }
-
-        @Override
-        public void handleMessage(Message msg) {
-            switch (msg.what) {
-                case EVENT_AUTO_TIME_CHANGED:
-                case EVENT_POLL_NETWORK_TIME:
-                case EVENT_NETWORK_CHANGED:
-                    onPollNetworkTime(msg.what);
-                    break;
-            }
-        }
-    }
-
-    private class NetworkTimeUpdateCallback extends NetworkCallback {
-        @Override
-        public void onAvailable(Network network) {
-            Log.d(TAG, String.format("New default network %s; checking time.", network));
-            mDefaultNetwork = network;
-            // Running on mHandler so invoke directly.
-            onPollNetworkTime(EVENT_NETWORK_CHANGED);
-        }
-
-        @Override
-        public void onLost(Network network) {
-            if (network.equals(mDefaultNetwork)) mDefaultNetwork = null;
-        }
-    }
-
-    /** Observer to watch for changes to the AUTO_TIME setting */
-    private static class SettingsObserver extends ContentObserver {
-
-        private int mMsg;
-        private Handler mHandler;
-
-        SettingsObserver(Handler handler, int msg) {
-            super(handler);
-            mHandler = handler;
-            mMsg = msg;
-        }
-
-        void observe(Context context) {
-            ContentResolver resolver = context.getContentResolver();
-            resolver.registerContentObserver(Settings.Global.getUriFor(Settings.Global.AUTO_TIME),
-                    false, this);
-        }
-
-        @Override
-        public void onChange(boolean selfChange) {
-            mHandler.obtainMessage(mMsg).sendToTarget();
-        }
-    }
-
-    @Override
-    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
-        if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
-        pw.print("PollingIntervalMs: ");
-        TimeUtils.formatDuration(mPollingIntervalMs, pw);
-        pw.print("\nPollingIntervalShorterMs: ");
-        TimeUtils.formatDuration(mPollingIntervalShorterMs, pw);
-        pw.println("\nTryAgainTimesMax: " + mTryAgainTimesMax);
-        pw.print("TimeErrorThresholdMs: ");
-        TimeUtils.formatDuration(mTimeErrorThresholdMs, pw);
-        pw.println("\nTryAgainCounter: " + mTryAgainCounter);
-        pw.print("LastNtpFetchTime: ");
-        TimeUtils.formatDuration(mLastNtpFetchTime, pw);
-        pw.println();
-    }
+    void systemRunning();
 }
diff --git a/services/core/java/com/android/server/NewNetworkTimeUpdateService.java b/services/core/java/com/android/server/NewNetworkTimeUpdateService.java
new file mode 100644
index 0000000..e918c1d
--- /dev/null
+++ b/services/core/java/com/android/server/NewNetworkTimeUpdateService.java
@@ -0,0 +1,333 @@
+/*
+ * 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.
+ */
+
+package com.android.server;
+
+import android.app.AlarmManager;
+import android.app.PendingIntent;
+import android.content.BroadcastReceiver;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.PackageManager;
+import android.database.ContentObserver;
+import android.net.ConnectivityManager;
+import android.net.ConnectivityManager.NetworkCallback;
+import android.net.Network;
+import android.os.Binder;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.Looper;
+import android.os.Message;
+import android.os.SystemClock;
+import android.os.PowerManager;
+import android.provider.Settings;
+import android.util.Log;
+import android.util.NtpTrustedTime;
+import android.util.TimeUtils;
+import android.util.TrustedTime;
+
+import com.android.internal.telephony.TelephonyIntents;
+import com.android.internal.util.DumpUtils;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+
+/**
+ * Monitors the network time and updates the system time if it is out of sync
+ * and there hasn't been any NITZ update from the carrier recently.
+ * If looking up the network time fails for some reason, it tries a few times with a short
+ * interval and then resets to checking on longer intervals.
+ * <p>
+ * If the user enables AUTO_TIME, it will check immediately for the network time, if NITZ wasn't
+ * available.
+ * </p>
+ */
+public class NewNetworkTimeUpdateService extends Binder implements NetworkTimeUpdateService {
+
+    private static final String TAG = "NetworkTimeUpdateService";
+    private static final boolean DBG = false;
+
+    private static final int EVENT_AUTO_TIME_CHANGED = 1;
+    private static final int EVENT_POLL_NETWORK_TIME = 2;
+    private static final int EVENT_NETWORK_CHANGED = 3;
+
+    private static final String ACTION_POLL =
+            "com.android.server.NetworkTimeUpdateService.action.POLL";
+
+    private static final int POLL_REQUEST = 0;
+
+    private static final long NOT_SET = -1;
+    private long mNitzTimeSetTime = NOT_SET;
+    private Network mDefaultNetwork = null;
+
+    private Context mContext;
+    private TrustedTime mTime;
+
+    // NTP lookup is done on this thread and handler
+    private Handler mHandler;
+    private AlarmManager mAlarmManager;
+    private PendingIntent mPendingPollIntent;
+    private SettingsObserver mSettingsObserver;
+    private ConnectivityManager mCM;
+    private NetworkTimeUpdateCallback mNetworkTimeUpdateCallback;
+    // The last time that we successfully fetched the NTP time.
+    private long mLastNtpFetchTime = NOT_SET;
+    private final PowerManager.WakeLock mWakeLock;
+
+    // Normal polling frequency
+    private final long mPollingIntervalMs;
+    // Try-again polling interval, in case the network request failed
+    private final long mPollingIntervalShorterMs;
+    // Number of times to try again
+    private final int mTryAgainTimesMax;
+    // If the time difference is greater than this threshold, then update the time.
+    private final int mTimeErrorThresholdMs;
+    // Keeps track of how many quick attempts were made to fetch NTP time.
+    // During bootup, the network may not have been up yet, or it's taking time for the
+    // connection to happen.
+    private int mTryAgainCounter;
+
+    public NewNetworkTimeUpdateService(Context context) {
+        mContext = context;
+        mTime = NtpTrustedTime.getInstance(context);
+        mAlarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
+        mCM = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
+        Intent pollIntent = new Intent(ACTION_POLL, null);
+        mPendingPollIntent = PendingIntent.getBroadcast(mContext, POLL_REQUEST, pollIntent, 0);
+
+        mPollingIntervalMs = mContext.getResources().getInteger(
+                com.android.internal.R.integer.config_ntpPollingInterval);
+        mPollingIntervalShorterMs = mContext.getResources().getInteger(
+                com.android.internal.R.integer.config_ntpPollingIntervalShorter);
+        mTryAgainTimesMax = mContext.getResources().getInteger(
+                com.android.internal.R.integer.config_ntpRetry);
+        mTimeErrorThresholdMs = mContext.getResources().getInteger(
+                com.android.internal.R.integer.config_ntpThreshold);
+
+        mWakeLock = ((PowerManager) context.getSystemService(Context.POWER_SERVICE)).newWakeLock(
+                PowerManager.PARTIAL_WAKE_LOCK, TAG);
+    }
+
+    /** Initialize the receivers and initiate the first NTP request */
+    public void systemRunning() {
+        registerForTelephonyIntents();
+        registerForAlarms();
+
+        HandlerThread thread = new HandlerThread(TAG);
+        thread.start();
+        mHandler = new MyHandler(thread.getLooper());
+        mNetworkTimeUpdateCallback = new NetworkTimeUpdateCallback();
+        mCM.registerDefaultNetworkCallback(mNetworkTimeUpdateCallback, mHandler);
+
+        mSettingsObserver = new SettingsObserver(mHandler, EVENT_AUTO_TIME_CHANGED);
+        mSettingsObserver.observe(mContext);
+    }
+
+    private void registerForTelephonyIntents() {
+        IntentFilter intentFilter = new IntentFilter();
+        intentFilter.addAction(TelephonyIntents.ACTION_NETWORK_SET_TIME);
+        mContext.registerReceiver(mNitzReceiver, intentFilter);
+    }
+
+    private void registerForAlarms() {
+        mContext.registerReceiver(
+            new BroadcastReceiver() {
+                @Override
+                public void onReceive(Context context, Intent intent) {
+                    mHandler.obtainMessage(EVENT_POLL_NETWORK_TIME).sendToTarget();
+                }
+            }, new IntentFilter(ACTION_POLL));
+    }
+
+    private void onPollNetworkTime(int event) {
+        // If Automatic time is not set, don't bother. Similarly, if we don't
+        // have any default network, don't bother.
+        if (!isAutomaticTimeRequested() || mDefaultNetwork == null) return;
+        mWakeLock.acquire();
+        try {
+            onPollNetworkTimeUnderWakeLock(event);
+        } finally {
+            mWakeLock.release();
+        }
+    }
+
+    private void onPollNetworkTimeUnderWakeLock(int event) {
+        final long refTime = SystemClock.elapsedRealtime();
+        // If NITZ time was received less than mPollingIntervalMs time ago,
+        // no need to sync to NTP.
+        if (mNitzTimeSetTime != NOT_SET && refTime - mNitzTimeSetTime < mPollingIntervalMs) {
+            resetAlarm(mPollingIntervalMs);
+            return;
+        }
+        final long currentTime = System.currentTimeMillis();
+        if (DBG) Log.d(TAG, "System time = " + currentTime);
+        // Get the NTP time
+        if (mLastNtpFetchTime == NOT_SET || refTime >= mLastNtpFetchTime + mPollingIntervalMs
+                || event == EVENT_AUTO_TIME_CHANGED) {
+            if (DBG) Log.d(TAG, "Before Ntp fetch");
+
+            // force refresh NTP cache when outdated
+            if (mTime.getCacheAge() >= mPollingIntervalMs) {
+                mTime.forceRefresh();
+            }
+
+            // only update when NTP time is fresh
+            if (mTime.getCacheAge() < mPollingIntervalMs) {
+                final long ntp = mTime.currentTimeMillis();
+                mTryAgainCounter = 0;
+                // If the clock is more than N seconds off or this is the first time it's been
+                // fetched since boot, set the current time.
+                if (Math.abs(ntp - currentTime) > mTimeErrorThresholdMs
+                        || mLastNtpFetchTime == NOT_SET) {
+                    // Set the system time
+                    if (DBG && mLastNtpFetchTime == NOT_SET
+                            && Math.abs(ntp - currentTime) <= mTimeErrorThresholdMs) {
+                        Log.d(TAG, "For initial setup, rtc = " + currentTime);
+                    }
+                    if (DBG) Log.d(TAG, "Ntp time to be set = " + ntp);
+                    // Make sure we don't overflow, since it's going to be converted to an int
+                    if (ntp / 1000 < Integer.MAX_VALUE) {
+                        SystemClock.setCurrentTimeMillis(ntp);
+                    }
+                } else {
+                    if (DBG) Log.d(TAG, "Ntp time is close enough = " + ntp);
+                }
+                mLastNtpFetchTime = SystemClock.elapsedRealtime();
+            } else {
+                // Try again shortly
+                mTryAgainCounter++;
+                if (mTryAgainTimesMax < 0 || mTryAgainCounter <= mTryAgainTimesMax) {
+                    resetAlarm(mPollingIntervalShorterMs);
+                } else {
+                    // Try much later
+                    mTryAgainCounter = 0;
+                    resetAlarm(mPollingIntervalMs);
+                }
+                return;
+            }
+        }
+        resetAlarm(mPollingIntervalMs);
+    }
+
+    /**
+     * Cancel old alarm and starts a new one for the specified interval.
+     *
+     * @param interval when to trigger the alarm, starting from now.
+     */
+    private void resetAlarm(long interval) {
+        mAlarmManager.cancel(mPendingPollIntent);
+        long now = SystemClock.elapsedRealtime();
+        long next = now + interval;
+        mAlarmManager.set(AlarmManager.ELAPSED_REALTIME, next, mPendingPollIntent);
+    }
+
+    /**
+     * Checks if the user prefers to automatically set the time.
+     */
+    private boolean isAutomaticTimeRequested() {
+        return Settings.Global.getInt(
+                mContext.getContentResolver(), Settings.Global.AUTO_TIME, 0) != 0;
+    }
+
+    /** Receiver for Nitz time events */
+    private BroadcastReceiver mNitzReceiver = new BroadcastReceiver() {
+
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            String action = intent.getAction();
+            if (DBG) Log.d(TAG, "Received " + action);
+            if (TelephonyIntents.ACTION_NETWORK_SET_TIME.equals(action)) {
+                mNitzTimeSetTime = SystemClock.elapsedRealtime();
+            }
+        }
+    };
+
+    /** Handler to do the network accesses on */
+    private class MyHandler extends Handler {
+
+        public MyHandler(Looper l) {
+            super(l);
+        }
+
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case EVENT_AUTO_TIME_CHANGED:
+                case EVENT_POLL_NETWORK_TIME:
+                case EVENT_NETWORK_CHANGED:
+                    onPollNetworkTime(msg.what);
+                    break;
+            }
+        }
+    }
+
+    private class NetworkTimeUpdateCallback extends NetworkCallback {
+        @Override
+        public void onAvailable(Network network) {
+            Log.d(TAG, String.format("New default network %s; checking time.", network));
+            mDefaultNetwork = network;
+            // Running on mHandler so invoke directly.
+            onPollNetworkTime(EVENT_NETWORK_CHANGED);
+        }
+
+        @Override
+        public void onLost(Network network) {
+            if (network.equals(mDefaultNetwork)) mDefaultNetwork = null;
+        }
+    }
+
+    /** Observer to watch for changes to the AUTO_TIME setting */
+    private static class SettingsObserver extends ContentObserver {
+
+        private int mMsg;
+        private Handler mHandler;
+
+        SettingsObserver(Handler handler, int msg) {
+            super(handler);
+            mHandler = handler;
+            mMsg = msg;
+        }
+
+        void observe(Context context) {
+            ContentResolver resolver = context.getContentResolver();
+            resolver.registerContentObserver(Settings.Global.getUriFor(Settings.Global.AUTO_TIME),
+                    false, this);
+        }
+
+        @Override
+        public void onChange(boolean selfChange) {
+            mHandler.obtainMessage(mMsg).sendToTarget();
+        }
+    }
+
+    @Override
+    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+        if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
+        pw.print("PollingIntervalMs: ");
+        TimeUtils.formatDuration(mPollingIntervalMs, pw);
+        pw.print("\nPollingIntervalShorterMs: ");
+        TimeUtils.formatDuration(mPollingIntervalShorterMs, pw);
+        pw.println("\nTryAgainTimesMax: " + mTryAgainTimesMax);
+        pw.print("TimeErrorThresholdMs: ");
+        TimeUtils.formatDuration(mTimeErrorThresholdMs, pw);
+        pw.println("\nTryAgainCounter: " + mTryAgainCounter);
+        pw.print("LastNtpFetchTime: ");
+        TimeUtils.formatDuration(mLastNtpFetchTime, pw);
+        pw.println();
+    }
+}
diff --git a/services/core/java/com/android/server/OldNetworkTimeUpdateService.java b/services/core/java/com/android/server/OldNetworkTimeUpdateService.java
new file mode 100644
index 0000000..d127b67
--- /dev/null
+++ b/services/core/java/com/android/server/OldNetworkTimeUpdateService.java
@@ -0,0 +1,333 @@
+/*
+ * 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.
+ */
+
+package com.android.server;
+
+import android.app.AlarmManager;
+import android.app.PendingIntent;
+import android.content.BroadcastReceiver;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.PackageManager;
+import android.database.ContentObserver;
+import android.net.ConnectivityManager;
+import android.net.ConnectivityManager.NetworkCallback;
+import android.net.Network;
+import android.os.Binder;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.Looper;
+import android.os.Message;
+import android.os.SystemClock;
+import android.os.PowerManager;
+import android.provider.Settings;
+import android.util.Log;
+import android.util.NtpTrustedTime;
+import android.util.TimeUtils;
+import android.util.TrustedTime;
+
+import com.android.internal.telephony.TelephonyIntents;
+import com.android.internal.util.DumpUtils;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+
+/**
+ * Monitors the network time and updates the system time if it is out of sync
+ * and there hasn't been any NITZ update from the carrier recently.
+ * If looking up the network time fails for some reason, it tries a few times with a short
+ * interval and then resets to checking on longer intervals.
+ * <p>
+ * If the user enables AUTO_TIME, it will check immediately for the network time, if NITZ wasn't
+ * available.
+ * </p>
+ */
+public class OldNetworkTimeUpdateService extends Binder implements NetworkTimeUpdateService {
+
+    private static final String TAG = "NetworkTimeUpdateService";
+    private static final boolean DBG = false;
+
+    private static final int EVENT_AUTO_TIME_CHANGED = 1;
+    private static final int EVENT_POLL_NETWORK_TIME = 2;
+    private static final int EVENT_NETWORK_CHANGED = 3;
+
+    private static final String ACTION_POLL =
+            "com.android.server.NetworkTimeUpdateService.action.POLL";
+
+    private static final int POLL_REQUEST = 0;
+
+    private static final long NOT_SET = -1;
+    private long mNitzTimeSetTime = NOT_SET;
+    private Network mDefaultNetwork = null;
+
+    private Context mContext;
+    private TrustedTime mTime;
+
+    // NTP lookup is done on this thread and handler
+    private Handler mHandler;
+    private AlarmManager mAlarmManager;
+    private PendingIntent mPendingPollIntent;
+    private SettingsObserver mSettingsObserver;
+    private ConnectivityManager mCM;
+    private NetworkTimeUpdateCallback mNetworkTimeUpdateCallback;
+    // The last time that we successfully fetched the NTP time.
+    private long mLastNtpFetchTime = NOT_SET;
+    private final PowerManager.WakeLock mWakeLock;
+
+    // Normal polling frequency
+    private final long mPollingIntervalMs;
+    // Try-again polling interval, in case the network request failed
+    private final long mPollingIntervalShorterMs;
+    // Number of times to try again
+    private final int mTryAgainTimesMax;
+    // If the time difference is greater than this threshold, then update the time.
+    private final int mTimeErrorThresholdMs;
+    // Keeps track of how many quick attempts were made to fetch NTP time.
+    // During bootup, the network may not have been up yet, or it's taking time for the
+    // connection to happen.
+    private int mTryAgainCounter;
+
+    public OldNetworkTimeUpdateService(Context context) {
+        mContext = context;
+        mTime = NtpTrustedTime.getInstance(context);
+        mAlarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
+        mCM = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
+        Intent pollIntent = new Intent(ACTION_POLL, null);
+        mPendingPollIntent = PendingIntent.getBroadcast(mContext, POLL_REQUEST, pollIntent, 0);
+
+        mPollingIntervalMs = mContext.getResources().getInteger(
+                com.android.internal.R.integer.config_ntpPollingInterval);
+        mPollingIntervalShorterMs = mContext.getResources().getInteger(
+                com.android.internal.R.integer.config_ntpPollingIntervalShorter);
+        mTryAgainTimesMax = mContext.getResources().getInteger(
+                com.android.internal.R.integer.config_ntpRetry);
+        mTimeErrorThresholdMs = mContext.getResources().getInteger(
+                com.android.internal.R.integer.config_ntpThreshold);
+
+        mWakeLock = ((PowerManager) context.getSystemService(Context.POWER_SERVICE)).newWakeLock(
+                PowerManager.PARTIAL_WAKE_LOCK, TAG);
+    }
+
+    /** Initialize the receivers and initiate the first NTP request */
+    public void systemRunning() {
+        registerForTelephonyIntents();
+        registerForAlarms();
+
+        HandlerThread thread = new HandlerThread(TAG);
+        thread.start();
+        mHandler = new MyHandler(thread.getLooper());
+        mNetworkTimeUpdateCallback = new NetworkTimeUpdateCallback();
+        mCM.registerDefaultNetworkCallback(mNetworkTimeUpdateCallback, mHandler);
+
+        mSettingsObserver = new SettingsObserver(mHandler, EVENT_AUTO_TIME_CHANGED);
+        mSettingsObserver.observe(mContext);
+    }
+
+    private void registerForTelephonyIntents() {
+        IntentFilter intentFilter = new IntentFilter();
+        intentFilter.addAction(TelephonyIntents.ACTION_NETWORK_SET_TIME);
+        mContext.registerReceiver(mNitzReceiver, intentFilter);
+    }
+
+    private void registerForAlarms() {
+        mContext.registerReceiver(
+            new BroadcastReceiver() {
+                @Override
+                public void onReceive(Context context, Intent intent) {
+                    mHandler.obtainMessage(EVENT_POLL_NETWORK_TIME).sendToTarget();
+                }
+            }, new IntentFilter(ACTION_POLL));
+    }
+
+    private void onPollNetworkTime(int event) {
+        // If Automatic time is not set, don't bother. Similarly, if we don't
+        // have any default network, don't bother.
+        if (!isAutomaticTimeRequested() || mDefaultNetwork == null) return;
+        mWakeLock.acquire();
+        try {
+            onPollNetworkTimeUnderWakeLock(event);
+        } finally {
+            mWakeLock.release();
+        }
+    }
+
+    private void onPollNetworkTimeUnderWakeLock(int event) {
+        final long refTime = SystemClock.elapsedRealtime();
+        // If NITZ time was received less than mPollingIntervalMs time ago,
+        // no need to sync to NTP.
+        if (mNitzTimeSetTime != NOT_SET && refTime - mNitzTimeSetTime < mPollingIntervalMs) {
+            resetAlarm(mPollingIntervalMs);
+            return;
+        }
+        final long currentTime = System.currentTimeMillis();
+        if (DBG) Log.d(TAG, "System time = " + currentTime);
+        // Get the NTP time
+        if (mLastNtpFetchTime == NOT_SET || refTime >= mLastNtpFetchTime + mPollingIntervalMs
+                || event == EVENT_AUTO_TIME_CHANGED) {
+            if (DBG) Log.d(TAG, "Before Ntp fetch");
+
+            // force refresh NTP cache when outdated
+            if (mTime.getCacheAge() >= mPollingIntervalMs) {
+                mTime.forceRefresh();
+            }
+
+            // only update when NTP time is fresh
+            if (mTime.getCacheAge() < mPollingIntervalMs) {
+                final long ntp = mTime.currentTimeMillis();
+                mTryAgainCounter = 0;
+                // If the clock is more than N seconds off or this is the first time it's been
+                // fetched since boot, set the current time.
+                if (Math.abs(ntp - currentTime) > mTimeErrorThresholdMs
+                        || mLastNtpFetchTime == NOT_SET) {
+                    // Set the system time
+                    if (DBG && mLastNtpFetchTime == NOT_SET
+                            && Math.abs(ntp - currentTime) <= mTimeErrorThresholdMs) {
+                        Log.d(TAG, "For initial setup, rtc = " + currentTime);
+                    }
+                    if (DBG) Log.d(TAG, "Ntp time to be set = " + ntp);
+                    // Make sure we don't overflow, since it's going to be converted to an int
+                    if (ntp / 1000 < Integer.MAX_VALUE) {
+                        SystemClock.setCurrentTimeMillis(ntp);
+                    }
+                } else {
+                    if (DBG) Log.d(TAG, "Ntp time is close enough = " + ntp);
+                }
+                mLastNtpFetchTime = SystemClock.elapsedRealtime();
+            } else {
+                // Try again shortly
+                mTryAgainCounter++;
+                if (mTryAgainTimesMax < 0 || mTryAgainCounter <= mTryAgainTimesMax) {
+                    resetAlarm(mPollingIntervalShorterMs);
+                } else {
+                    // Try much later
+                    mTryAgainCounter = 0;
+                    resetAlarm(mPollingIntervalMs);
+                }
+                return;
+            }
+        }
+        resetAlarm(mPollingIntervalMs);
+    }
+
+    /**
+     * Cancel old alarm and starts a new one for the specified interval.
+     *
+     * @param interval when to trigger the alarm, starting from now.
+     */
+    private void resetAlarm(long interval) {
+        mAlarmManager.cancel(mPendingPollIntent);
+        long now = SystemClock.elapsedRealtime();
+        long next = now + interval;
+        mAlarmManager.set(AlarmManager.ELAPSED_REALTIME, next, mPendingPollIntent);
+    }
+
+    /**
+     * Checks if the user prefers to automatically set the time.
+     */
+    private boolean isAutomaticTimeRequested() {
+        return Settings.Global.getInt(
+                mContext.getContentResolver(), Settings.Global.AUTO_TIME, 0) != 0;
+    }
+
+    /** Receiver for Nitz time events */
+    private BroadcastReceiver mNitzReceiver = new BroadcastReceiver() {
+
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            String action = intent.getAction();
+            if (DBG) Log.d(TAG, "Received " + action);
+            if (TelephonyIntents.ACTION_NETWORK_SET_TIME.equals(action)) {
+                mNitzTimeSetTime = SystemClock.elapsedRealtime();
+            }
+        }
+    };
+
+    /** Handler to do the network accesses on */
+    private class MyHandler extends Handler {
+
+        public MyHandler(Looper l) {
+            super(l);
+        }
+
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case EVENT_AUTO_TIME_CHANGED:
+                case EVENT_POLL_NETWORK_TIME:
+                case EVENT_NETWORK_CHANGED:
+                    onPollNetworkTime(msg.what);
+                    break;
+            }
+        }
+    }
+
+    private class NetworkTimeUpdateCallback extends NetworkCallback {
+        @Override
+        public void onAvailable(Network network) {
+            Log.d(TAG, String.format("New default network %s; checking time.", network));
+            mDefaultNetwork = network;
+            // Running on mHandler so invoke directly.
+            onPollNetworkTime(EVENT_NETWORK_CHANGED);
+        }
+
+        @Override
+        public void onLost(Network network) {
+            if (network.equals(mDefaultNetwork)) mDefaultNetwork = null;
+        }
+    }
+
+    /** Observer to watch for changes to the AUTO_TIME setting */
+    private static class SettingsObserver extends ContentObserver {
+
+        private int mMsg;
+        private Handler mHandler;
+
+        SettingsObserver(Handler handler, int msg) {
+            super(handler);
+            mHandler = handler;
+            mMsg = msg;
+        }
+
+        void observe(Context context) {
+            ContentResolver resolver = context.getContentResolver();
+            resolver.registerContentObserver(Settings.Global.getUriFor(Settings.Global.AUTO_TIME),
+                    false, this);
+        }
+
+        @Override
+        public void onChange(boolean selfChange) {
+            mHandler.obtainMessage(mMsg).sendToTarget();
+        }
+    }
+
+    @Override
+    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+        if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
+        pw.print("PollingIntervalMs: ");
+        TimeUtils.formatDuration(mPollingIntervalMs, pw);
+        pw.print("\nPollingIntervalShorterMs: ");
+        TimeUtils.formatDuration(mPollingIntervalShorterMs, pw);
+        pw.println("\nTryAgainTimesMax: " + mTryAgainTimesMax);
+        pw.print("TimeErrorThresholdMs: ");
+        TimeUtils.formatDuration(mTimeErrorThresholdMs, pw);
+        pw.println("\nTryAgainCounter: " + mTryAgainCounter);
+        pw.print("LastNtpFetchTime: ");
+        TimeUtils.formatDuration(mLastNtpFetchTime, pw);
+        pw.println();
+    }
+}
diff --git a/services/core/java/com/android/server/connectivity/Vpn.java b/services/core/java/com/android/server/connectivity/Vpn.java
index bce735b..2a80f0e 100644
--- a/services/core/java/com/android/server/connectivity/Vpn.java
+++ b/services/core/java/com/android/server/connectivity/Vpn.java
@@ -115,6 +115,7 @@
 import java.util.Collections;
 import java.util.Comparator;
 import java.util.List;
+import java.util.Objects;
 import java.util.Set;
 import java.util.SortedSet;
 import java.util.TreeSet;
@@ -895,6 +896,42 @@
                 .compareTo(MOST_IPV6_ADDRESSES_COUNT) >= 0;
     }
 
+    /**
+     * Attempt to perform a seamless handover of VPNs by only updating LinkProperties without
+     * registering a new NetworkAgent. This is not always possible if the new VPN configuration
+     * has certain changes, in which case this method would just return {@code false}.
+     */
+    private boolean updateLinkPropertiesInPlaceIfPossible(NetworkAgent agent, VpnConfig oldConfig) {
+        // NetworkMisc cannot be updated without registering a new NetworkAgent.
+        if (oldConfig.allowBypass != mConfig.allowBypass) {
+            Log.i(TAG, "Handover not possible due to changes to allowBypass");
+            return false;
+        }
+
+        // TODO: we currently do not support seamless handover if the allowed or disallowed
+        // applications have changed. Consider diffing UID ranges and only applying the delta.
+        if (!Objects.equals(oldConfig.allowedApplications, mConfig.allowedApplications) ||
+                !Objects.equals(oldConfig.disallowedApplications, mConfig.disallowedApplications)) {
+            Log.i(TAG, "Handover not possible due to changes to whitelisted/blacklisted apps");
+            return false;
+        }
+
+        LinkProperties lp = makeLinkProperties();
+        final boolean hadInternetCapability = mNetworkCapabilities.hasCapability(
+                NetworkCapabilities.NET_CAPABILITY_INTERNET);
+        final boolean willHaveInternetCapability = providesRoutesToMostDestinations(lp);
+        if (hadInternetCapability != willHaveInternetCapability) {
+            // A seamless handover would have led to a change to INTERNET capability, which
+            // is supposed to be immutable for a given network. In this case bail out and do not
+            // perform handover.
+            Log.i(TAG, "Handover not possible due to changes to INTERNET capability");
+            return false;
+        }
+
+        agent.sendLinkProperties(lp);
+        return true;
+    }
+
     private void agentConnect() {
         LinkProperties lp = makeLinkProperties();
 
@@ -1003,13 +1040,11 @@
         String oldInterface = mInterface;
         Connection oldConnection = mConnection;
         NetworkAgent oldNetworkAgent = mNetworkAgent;
-        mNetworkAgent = null;
         Set<UidRange> oldUsers = mNetworkCapabilities.getUids();
 
         // Configure the interface. Abort if any of these steps fails.
         ParcelFileDescriptor tun = ParcelFileDescriptor.adoptFd(jniCreate(config.mtu));
         try {
-            updateState(DetailedState.CONNECTING, "establish");
             String interfaze = jniGetName(tun.getFd());
 
             // TEMP use the old jni calls until there is support for netd address setting
@@ -1037,15 +1072,26 @@
             mConfig = config;
 
             // Set up forwarding and DNS rules.
-            agentConnect();
+            // First attempt to do a seamless handover that only changes the interface name and
+            // parameters. If that fails, disconnect.
+            if (oldConfig != null
+                    && updateLinkPropertiesInPlaceIfPossible(mNetworkAgent, oldConfig)) {
+                // Keep mNetworkAgent unchanged
+            } else {
+                mNetworkAgent = null;
+                updateState(DetailedState.CONNECTING, "establish");
+                // Set up forwarding and DNS rules.
+                agentConnect();
+                // Remove the old tun's user forwarding rules
+                // The new tun's user rules have already been added above so they will take over
+                // as rules are deleted. This prevents data leakage as the rules are moved over.
+                agentDisconnect(oldNetworkAgent);
+            }
 
             if (oldConnection != null) {
                 mContext.unbindService(oldConnection);
             }
-            // Remove the old tun's user forwarding rules
-            // The new tun's user rules have already been added so they will take over
-            // as rules are deleted. This prevents data leakage as the rules are moved over.
-            agentDisconnect(oldNetworkAgent);
+
             if (oldInterface != null && !oldInterface.equals(interfaze)) {
                 jniReset(oldInterface);
             }
diff --git a/services/core/java/com/android/server/connectivity/tethering/TetherInterfaceStateMachine.java b/services/core/java/com/android/server/connectivity/tethering/TetherInterfaceStateMachine.java
index fbee86a..9e6b659 100644
--- a/services/core/java/com/android/server/connectivity/tethering/TetherInterfaceStateMachine.java
+++ b/services/core/java/com/android/server/connectivity/tethering/TetherInterfaceStateMachine.java
@@ -379,7 +379,7 @@
                     // that adding routes that already exist does not cause an
                     // error (EEXIST is silently ignored).
                     mNMService.addInterfaceToLocalNetwork(mIfaceName, toBeAdded);
-                } catch (RemoteException e) {
+                } catch (Exception e) {
                     mLog.e("Failed to add IPv6 routes to local table: " + e);
                 }
 
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index c523c7e..a602ab1 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -1205,21 +1205,24 @@
                 traceEnd();
             }
 
-            traceBeginAndSlog("StartTimeDetectorService");
-            try {
-                mSystemServiceManager.startService(TIME_DETECTOR_SERVICE_CLASS);
-            } catch (Throwable e) {
-                reportWtf("starting StartTimeDetectorService service", e);
-            }
-            traceEnd();
+            final boolean useNewTimeServices = true;
+            if (useNewTimeServices) {
+                traceBeginAndSlog("StartTimeDetectorService");
+                try {
+                    mSystemServiceManager.startService(TIME_DETECTOR_SERVICE_CLASS);
+                } catch (Throwable e) {
+                    reportWtf("starting StartTimeDetectorService service", e);
+                }
+                traceEnd();
 
-            traceBeginAndSlog("StartTimeZoneDetectorService");
-            try {
-                mSystemServiceManager.startService(TIME_ZONE_DETECTOR_SERVICE_CLASS);
-            } catch (Throwable e) {
-                reportWtf("starting StartTimeZoneDetectorService service", e);
+                traceBeginAndSlog("StartTimeZoneDetectorService");
+                try {
+                    mSystemServiceManager.startService(TIME_ZONE_DETECTOR_SERVICE_CLASS);
+                } catch (Throwable e) {
+                    reportWtf("starting StartTimeZoneDetectorService service", e);
+                }
+                traceEnd();
             }
-            traceEnd();
 
             if (!disableNonCoreServices && !disableSearchManager) {
                 traceBeginAndSlog("StartSearchManagerService");
@@ -1394,7 +1397,12 @@
             if (!disableNetwork && !disableNetworkTime) {
                 traceBeginAndSlog("StartNetworkTimeUpdateService");
                 try {
-                    networkTimeUpdater = new NetworkTimeUpdateService(context);
+                    if (useNewTimeServices) {
+                        networkTimeUpdater = new NewNetworkTimeUpdateService(context);
+                    } else {
+                        networkTimeUpdater = new OldNetworkTimeUpdateService(context);
+                    }
+                    Slog.d(TAG, "Using networkTimeUpdater class=" + networkTimeUpdater.getClass());
                     ServiceManager.addService("network_time_update_service", networkTimeUpdater);
                 } catch (Throwable e) {
                     reportWtf("starting NetworkTimeUpdate service", e);
diff --git a/services/net/java/android/net/netlink/NetlinkSocket.java b/services/net/java/android/net/netlink/NetlinkSocket.java
index 5af3c29..cfcba3a 100644
--- a/services/net/java/android/net/netlink/NetlinkSocket.java
+++ b/services/net/java/android/net/netlink/NetlinkSocket.java
@@ -59,10 +59,9 @@
         final String errPrefix = "Error in NetlinkSocket.sendOneShotKernelMessage";
         final long IO_TIMEOUT = 300L;
 
-        FileDescriptor fd;
+        final FileDescriptor fd = forProto(nlProto);
 
         try {
-            fd = forProto(nlProto);
             connectToKernel(fd);
             sendMessage(fd, msg, 0, msg.length, IO_TIMEOUT);
             final ByteBuffer bytes = recvMessage(fd, DEFAULT_RECV_BUFSIZE, IO_TIMEOUT);
@@ -96,9 +95,9 @@
         } catch (SocketException e) {
             Log.e(TAG, errPrefix, e);
             throw new ErrnoException(errPrefix, EIO, e);
+        } finally {
+            IoUtils.closeQuietly(fd);
         }
-
-        IoUtils.closeQuietly(fd);
     }
 
     public static FileDescriptor forProto(int nlProto) throws ErrnoException {
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index b672e69..102d0f7 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -113,6 +113,14 @@
     public static final String
             KEY_SIM_NETWORK_UNLOCK_ALLOW_DISMISS_BOOL = "sim_network_unlock_allow_dismiss_bool";
 
+    /**
+     * Flag indicating whether or not sending emergency SMS messages over IMS
+     * is supported when in LTE/limited LTE (Emergency only) service mode..
+     *
+     */
+    public static final String
+            KEY_SUPPORT_EMERGENCY_SMS_OVER_IMS_BOOL = "support_emergency_sms_over_ims_bool";
+
     /** Flag indicating if the phone is a world phone */
     public static final String KEY_WORLD_PHONE_BOOL = "world_phone_bool";
 
@@ -1011,6 +1019,26 @@
     public static final String KEY_CARRIER_NAME_STRING = "carrier_name_string";
 
     /**
+     * Override the registered PLMN name using #KEY_CDMA_HOME_REGISTERED_PLMN_NAME_STRING.
+     *
+     * If true, then the registered PLMN name (only for CDMA/CDMA-LTE and only when not roaming)
+     * will be #KEY_CDMA_HOME_REGISTERED_PLMN_NAME_STRING. If false, or if phone type is not
+     * CDMA/CDMA-LTE or if roaming, then #KEY_CDMA_HOME_REGISTERED_PLMN_NAME_STRING will be ignored.
+     * @hide
+     */
+    public static final String KEY_CDMA_HOME_REGISTERED_PLMN_NAME_OVERRIDE_BOOL =
+            "cdma_home_registered_plmn_name_override_bool";
+
+    /**
+     * String to identify registered PLMN name in CarrierConfig app. This string overrides
+     * registered PLMN name if #KEY_CDMA_HOME_REGISTERED_PLMN_NAME_OVERRIDE_BOOL is true, phone type
+     * is CDMA/CDMA-LTE and device is not in roaming state; otherwise, it will be ignored.
+     * @hide
+     */
+    public static final String KEY_CDMA_HOME_REGISTERED_PLMN_NAME_STRING =
+            "cdma_home_registered_plmn_name_string";
+
+    /**
      * If this is true, the SIM card (through Customer Service Profile EF file) will be able to
      * prevent manual operator selection. If false, this SIM setting will be ignored and manual
      * operator selection will always be available. See CPHS4_2.WW6, CPHS B.4.7.1 for more
@@ -1528,7 +1556,7 @@
     public static final String KEY_EDITABLE_WFC_ROAMING_MODE_BOOL =
             "editable_wfc_roaming_mode_bool";
 
-   /**
+    /**
      * Determine whether current lpp_mode used for E-911 needs to be kept persistently.
      * {@code false} - not keeping the lpp_mode means using default configuration of gps.conf
      *                 when sim is not presented.
@@ -1967,6 +1995,7 @@
         sDefaults.putBoolean(KEY_SHOW_APN_SETTING_CDMA_BOOL, false);
         sDefaults.putBoolean(KEY_SHOW_CDMA_CHOICES_BOOL, false);
         sDefaults.putBoolean(KEY_SMS_REQUIRES_DESTINATION_NUMBER_CONVERSION_BOOL, false);
+        sDefaults.putBoolean(KEY_SUPPORT_EMERGENCY_SMS_OVER_IMS_BOOL, false);
         sDefaults.putBoolean(KEY_SHOW_ONSCREEN_DIAL_BUTTON_BOOL, true);
         sDefaults.putBoolean(KEY_SIM_NETWORK_UNLOCK_ALLOW_DISMISS_BOOL, true);
         sDefaults.putBoolean(KEY_SUPPORT_PAUSE_IMS_VIDEO_CALLS_BOOL, false);
@@ -2069,6 +2098,8 @@
         sDefaults.putBoolean(KEY_CONFIG_WIFI_DISABLE_IN_ECBM, false);
         sDefaults.putBoolean(KEY_CARRIER_NAME_OVERRIDE_BOOL, false);
         sDefaults.putString(KEY_CARRIER_NAME_STRING, "");
+        sDefaults.putBoolean(KEY_CDMA_HOME_REGISTERED_PLMN_NAME_OVERRIDE_BOOL, false);
+        sDefaults.putString(KEY_CDMA_HOME_REGISTERED_PLMN_NAME_STRING, "");
         sDefaults.putBoolean(KEY_SUPPORT_DIRECT_FDN_DIALING_BOOL, false);
         sDefaults.putBoolean(KEY_CARRIER_DEFAULT_DATA_ROAMING_ENABLED_BOOL, false);
         sDefaults.putBoolean(KEY_SKIP_CF_FAIL_TO_DISABLE_DIALOG_BOOL, false);
diff --git a/telephony/java/android/telephony/CellSignalStrengthLte.java b/telephony/java/android/telephony/CellSignalStrengthLte.java
index 7e86966..2b6928e 100644
--- a/telephony/java/android/telephony/CellSignalStrengthLte.java
+++ b/telephony/java/android/telephony/CellSignalStrengthLte.java
@@ -121,6 +121,8 @@
 
     /**
      * Get reference signal received quality
+     *
+     * @return the RSRQ if available or Integer.MAX_VALUE if unavailable.
      */
     public int getRsrq() {
         return mRsrq;
@@ -128,13 +130,17 @@
 
     /**
      * Get reference signal signal-to-noise ratio
+     *
+     * @return the RSSNR if available or Integer.MAX_VALUE if unavailable.
      */
     public int getRssnr() {
         return mRssnr;
     }
 
     /**
-     * Get reference signal received power
+     * Get reference signal received power in dBm
+     *
+     * @return the RSRP of the measured cell.
      */
     public int getRsrp() {
         return mRsrp;
@@ -142,13 +148,17 @@
 
     /**
      * Get channel quality indicator
+     *
+     * @return the CQI if available or Integer.MAX_VALUE if unavailable.
      */
     public int getCqi() {
         return mCqi;
     }
 
     /**
-     * Get signal strength as dBm
+     * Get signal strength in dBm
+     *
+     * @return the RSRP of the measured cell.
      */
     @Override
     public int getDbm() {
@@ -175,7 +185,8 @@
      * Get the timing advance value for LTE, as a value in range of 0..1282.
      * Integer.MAX_VALUE is reported when there is no active RRC
      * connection. Refer to 3GPP 36.213 Sec 4.2.3
-     * @return the LTE timing advance, if available.
+     *
+     * @return the LTE timing advance if available or Integer.MAX_VALUE if unavailable.
      */
     public int getTimingAdvance() {
         return mTimingAdvance;
diff --git a/telephony/java/android/telephony/LocationAccessPolicy.java b/telephony/java/android/telephony/LocationAccessPolicy.java
index 26ffe32..19b3d0d 100644
--- a/telephony/java/android/telephony/LocationAccessPolicy.java
+++ b/telephony/java/android/telephony/LocationAccessPolicy.java
@@ -21,31 +21,27 @@
 import android.annotation.UserIdInt;
 import android.app.ActivityManager;
 import android.app.AppOpsManager;
-import android.content.BroadcastReceiver;
 import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
 import android.content.pm.PackageManager;
 import android.content.pm.UserInfo;
-import android.location.LocationManager;
 import android.os.Binder;
-import android.os.Build;
 import android.os.Process;
 import android.os.Trace;
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.provider.Settings;
-import android.util.SparseBooleanArray;
+import android.util.Log;
 
-import java.util.HashMap;
 import java.util.List;
-import java.util.Map;
 
 /**
  * Helper for performing location access checks.
  * @hide
  */
 public final class LocationAccessPolicy {
+    private static final String TAG = "LocationAccessPolicy";
+    private static final boolean DBG = false;
+
     /**
      * API to determine if the caller has permissions to get cell location.
      *
@@ -58,10 +54,11 @@
             int uid, int pid) throws SecurityException {
         Trace.beginSection("TelephonyLocationCheck");
         try {
-            // Always allow the phone process to access location. This avoid breaking legacy code
-            // that rely on public-facing APIs to access cell location, and it doesn't create a
-            // info leak risk because the cell location is stored in the phone process anyway.
-            if (uid == Process.PHONE_UID) {
+            // Always allow the phone process and system server to access location. This avoid
+            // breaking legacy code that rely on public-facing APIs to access cell location, and
+            // it doesn't create an info leak risk because the cell location is stored in the phone
+            // process anyway, and the system server already has location access.
+            if (uid == Process.PHONE_UID || uid == Process.SYSTEM_UID || uid == Process.ROOT_UID) {
                 return true;
             }
 
@@ -74,15 +71,18 @@
 
             if (context.checkPermission(Manifest.permission.ACCESS_COARSE_LOCATION, pid, uid) ==
                     PackageManager.PERMISSION_DENIED) {
+                if (DBG) Log.w(TAG, "Permission checked failed (" + pid + "," + uid + ")");
                 return false;
             }
             final int opCode = AppOpsManager.permissionToOpCode(
                     Manifest.permission.ACCESS_COARSE_LOCATION);
             if (opCode != AppOpsManager.OP_NONE && context.getSystemService(AppOpsManager.class)
                     .noteOpNoThrow(opCode, uid, pkgName) != AppOpsManager.MODE_ALLOWED) {
+                if (DBG) Log.w(TAG, "AppOp check failed (" + uid + "," + pkgName + ")");
                 return false;
             }
             if (!isLocationModeEnabled(context, UserHandle.getUserId(uid))) {
+                if (DBG) Log.w(TAG, "Location disabled, failed, (" + uid + ")");
                 return false;
             }
             // If the user or profile is current, permission is granted.
diff --git a/telephony/java/android/telephony/NetworkRegistrationState.java b/telephony/java/android/telephony/NetworkRegistrationState.java
index bba779d..e881549 100644
--- a/telephony/java/android/telephony/NetworkRegistrationState.java
+++ b/telephony/java/android/telephony/NetworkRegistrationState.java
@@ -85,12 +85,12 @@
     public static final int SERVICE_TYPE_VIDEO = 4;
     public static final int SERVICE_TYPE_EMERGENCY = 5;
 
-    /** {@link AccessNetworkConstants.TransportType}*/
-    private final int mTransportType;
-
     @Domain
     private final int mDomain;
 
+    /** {@link AccessNetworkConstants.TransportType}*/
+    private final int mTransportType;
+
     @RegState
     private final int mRegState;
 
@@ -112,19 +112,19 @@
     private DataSpecificRegistrationStates mDataSpecificStates;
 
     /**
-     * @param transportType Transport type. Must be {@link AccessNetworkConstants.TransportType}
      * @param domain Network domain. Must be DOMAIN_CS or DOMAIN_PS.
+     * @param transportType Transport type. Must be {@link AccessNetworkConstants.TransportType}
      * @param regState Network registration state.
      * @param accessNetworkTechnology See TelephonyManager NETWORK_TYPE_XXXX.
      * @param reasonForDenial Reason for denial if the registration state is DENIED.
      * @param availableServices The supported service.
      * @param cellIdentity The identity representing a unique cell
      */
-    public NetworkRegistrationState(int transportType, int domain, int regState,
+    public NetworkRegistrationState(int domain, int transportType, int regState,
             int accessNetworkTechnology, int reasonForDenial, boolean emergencyOnly,
             int[] availableServices, @Nullable CellIdentity cellIdentity) {
-        mTransportType = transportType;
         mDomain = domain;
+        mTransportType = transportType;
         mRegState = regState;
         mAccessNetworkTechnology = accessNetworkTechnology;
         mReasonForDenial = reasonForDenial;
@@ -137,11 +137,11 @@
      * Constructor for voice network registration states.
      * @hide
      */
-    public NetworkRegistrationState(int transportType, int domain, int regState,
+    public NetworkRegistrationState(int domain, int transportType, int regState,
             int accessNetworkTechnology, int reasonForDenial, boolean emergencyOnly,
             int[] availableServices, @Nullable CellIdentity cellIdentity, boolean cssSupported,
             int roamingIndicator, int systemIsInPrl, int defaultRoamingIndicator) {
-        this(transportType, domain, regState, accessNetworkTechnology,
+        this(domain, transportType, regState, accessNetworkTechnology,
                 reasonForDenial, emergencyOnly, availableServices, cellIdentity);
 
         mVoiceSpecificStates = new VoiceSpecificRegistrationStates(cssSupported, roamingIndicator,
@@ -152,18 +152,18 @@
      * Constructor for data network registration states.
      * @hide
      */
-    public NetworkRegistrationState(int transportType, int domain, int regState,
+    public NetworkRegistrationState(int domain, int transportType, int regState,
             int accessNetworkTechnology, int reasonForDenial, boolean emergencyOnly,
             int[] availableServices, @Nullable CellIdentity cellIdentity, int maxDataCalls) {
-        this(transportType, domain, regState, accessNetworkTechnology,
+        this(domain, transportType, regState, accessNetworkTechnology,
                 reasonForDenial, emergencyOnly, availableServices, cellIdentity);
 
         mDataSpecificStates = new DataSpecificRegistrationStates(maxDataCalls);
     }
 
     protected NetworkRegistrationState(Parcel source) {
-        mTransportType = source.readInt();
         mDomain = source.readInt();
+        mTransportType = source.readInt();
         mRegState = source.readInt();
         mAccessNetworkTechnology = source.readInt();
         mReasonForDenial = source.readInt();
@@ -260,8 +260,8 @@
     @Override
     public String toString() {
         return new StringBuilder("NetworkRegistrationState{")
-                .append("transportType=").append(mTransportType)
                 .append(" domain=").append((mDomain == DOMAIN_CS) ? "CS" : "PS")
+                .append("transportType=").append(mTransportType)
                 .append(" regState=").append(regStateToString(mRegState))
                 .append(" accessNetworkTechnology=")
                 .append(TelephonyManager.getNetworkTypeName(mAccessNetworkTechnology))
@@ -290,8 +290,8 @@
         }
 
         NetworkRegistrationState other = (NetworkRegistrationState) o;
-        return mTransportType == other.mTransportType
-                && mDomain == other.mDomain
+        return mDomain == other.mDomain
+                && mTransportType == other.mTransportType
                 && mRegState == other.mRegState
                 && mAccessNetworkTechnology == other.mAccessNetworkTechnology
                 && mReasonForDenial == other.mReasonForDenial
@@ -305,8 +305,8 @@
 
     @Override
     public void writeToParcel(Parcel dest, int flags) {
-        dest.writeInt(mTransportType);
         dest.writeInt(mDomain);
+        dest.writeInt(mTransportType);
         dest.writeInt(mRegState);
         dest.writeInt(mAccessNetworkTechnology);
         dest.writeInt(mReasonForDenial);
diff --git a/telephony/java/android/telephony/ServiceState.java b/telephony/java/android/telephony/ServiceState.java
index e971d08..caf1d66 100644
--- a/telephony/java/android/telephony/ServiceState.java
+++ b/telephony/java/android/telephony/ServiceState.java
@@ -30,6 +30,7 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
+import java.util.Objects;
 
 /**
  * Contains phone state and service related information.
@@ -723,38 +724,40 @@
 
     @Override
     public int hashCode() {
-        return ((mVoiceRegState * 31)
-                + (mDataRegState * 37)
-                + mVoiceRoamingType
-                + mDataRoamingType
-                + mChannelNumber
-                + Arrays.hashCode(mCellBandwidths)
-                + (mIsManualNetworkSelection ? 1 : 0)
-                + ((null == mVoiceOperatorAlphaLong) ? 0 : mVoiceOperatorAlphaLong.hashCode())
-                + ((null == mVoiceOperatorAlphaShort) ? 0 : mVoiceOperatorAlphaShort.hashCode())
-                + ((null == mVoiceOperatorNumeric) ? 0 : mVoiceOperatorNumeric.hashCode())
-                + ((null == mDataOperatorAlphaLong) ? 0 : mDataOperatorAlphaLong.hashCode())
-                + ((null == mDataOperatorAlphaShort) ? 0 : mDataOperatorAlphaShort.hashCode())
-                + ((null == mDataOperatorNumeric) ? 0 : mDataOperatorNumeric.hashCode())
-                + mCdmaRoamingIndicator
-                + mCdmaDefaultRoamingIndicator
-                + (mIsEmergencyOnly ? 1 : 0)
-                + (mIsDataRoamingFromRegistration ? 1 : 0));
+        return Objects.hash(
+                mVoiceRegState,
+                mDataRegState,
+                mVoiceRoamingType,
+                mDataRoamingType,
+                mChannelNumber,
+                mCellBandwidths,
+                mVoiceOperatorAlphaLong,
+                mVoiceOperatorAlphaShort,
+                mVoiceOperatorNumeric,
+                mDataOperatorAlphaLong,
+                mDataOperatorAlphaShort,
+                mDataOperatorNumeric,
+                mIsManualNetworkSelection,
+                mRilVoiceRadioTechnology,
+                mRilDataRadioTechnology,
+                mCssIndicator,
+                mNetworkId,
+                mSystemId,
+                mCdmaRoamingIndicator,
+                mCdmaDefaultRoamingIndicator,
+                mCdmaEriIconIndex,
+                mCdmaEriIconMode,
+                mIsEmergencyOnly,
+                mIsDataRoamingFromRegistration,
+                mIsUsingCarrierAggregation,
+                mLteEarfcnRsrpBoost,
+                mNetworkRegistrationStates);
     }
 
     @Override
     public boolean equals (Object o) {
-        ServiceState s;
-
-        try {
-            s = (ServiceState) o;
-        } catch (ClassCastException ex) {
-            return false;
-        }
-
-        if (o == null) {
-            return false;
-        }
+        if (!(o instanceof ServiceState)) return false;
+        ServiceState s = (ServiceState) o;
 
         return (mVoiceRegState == s.mVoiceRegState
                 && mDataRegState == s.mDataRegState
@@ -1562,13 +1565,14 @@
     /**
      * Get the network registration states with given transport type and domain.
      *
+     * @param domain The network domain. Must be {@link NetworkRegistrationState#DOMAIN_CS} or
+     * {@link NetworkRegistrationState#DOMAIN_PS}.
      * @param transportType The transport type. See {@link AccessNetworkConstants.TransportType}
-     * @param domain The network domain. Must be DOMAIN_CS or DOMAIN_PS.
      * @return The matching NetworkRegistrationState.
      * @hide
      */
     @SystemApi
-    public NetworkRegistrationState getNetworkRegistrationStates(int transportType, int domain) {
+    public NetworkRegistrationState getNetworkRegistrationStates(int domain, int transportType) {
         synchronized (mNetworkRegistrationStates) {
             for (NetworkRegistrationState networkRegistrationState : mNetworkRegistrationStates) {
                 if (networkRegistrationState.getTransportType() == transportType
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index e0b465d..3bc7341 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -1230,6 +1230,33 @@
     }
 
     /**
+     * Returns the Type Allocation Code from the IMEI. Return null if Type Allocation Code is not
+     * available.
+     */
+    public String getTypeAllocationCode() {
+        return getTypeAllocationCode(getSlotIndex());
+    }
+
+    /**
+     * Returns the Type Allocation Code from the IMEI. Return null if Type Allocation Code is not
+     * available.
+     *
+     * @param slotIndex of which Type Allocation Code is returned
+     */
+    public String getTypeAllocationCode(int slotIndex) {
+        ITelephony telephony = getITelephony();
+        if (telephony == null) return null;
+
+        try {
+            return telephony.getTypeAllocationCodeForSlot(slotIndex);
+        } catch (RemoteException ex) {
+            return null;
+        } catch (NullPointerException ex) {
+            return null;
+        }
+    }
+
+    /**
      * Returns the MEID (Mobile Equipment Identifier). Return null if MEID is not available.
      *
      * <p>Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
@@ -1265,6 +1292,33 @@
     }
 
     /**
+     * Returns the Manufacturer Code from the MEID. Return null if Manufacturer Code is not
+     * available.
+     */
+    public String getManufacturerCode() {
+        return getManufacturerCode(getSlotIndex());
+    }
+
+    /**
+     * Returns the Manufacturer Code from the MEID. Return null if Manufacturer Code is not
+     * available.
+     *
+     * @param slotIndex of which Type Allocation Code is returned
+     */
+    public String getManufacturerCode(int slotIndex) {
+        ITelephony telephony = getITelephony();
+        if (telephony == null) return null;
+
+        try {
+            return telephony.getManufacturerCodeForSlot(slotIndex);
+        } catch (RemoteException ex) {
+            return null;
+        } catch (NullPointerException ex) {
+            return null;
+        }
+    }
+
+    /**
      * Returns the Network Access Identifier (NAI). Return null if NAI is not available.
      *
      * <p>Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
diff --git a/telephony/java/android/telephony/data/ApnSetting.java b/telephony/java/android/telephony/data/ApnSetting.java
index bb181e6..296e1de 100644
--- a/telephony/java/android/telephony/data/ApnSetting.java
+++ b/telephony/java/android/telephony/data/ApnSetting.java
@@ -70,7 +70,12 @@
     private static final String UNSPECIFIED_STRING = "";
 
     /**
-     * All APN types.
+     * APN type for none. Should only be used for initialization.
+     * @hide
+     */
+    public static final int TYPE_NONE = ApnTypes.NONE;
+    /**
+     * APN type for all APNs.
      * @hide
      */
     public static final int TYPE_ALL = ApnTypes.ALL;
diff --git a/telephony/java/android/telephony/ims/ImsExternalCallState.java b/telephony/java/android/telephony/ims/ImsExternalCallState.java
index e82c115..e158fa8 100644
--- a/telephony/java/android/telephony/ims/ImsExternalCallState.java
+++ b/telephony/java/android/telephony/ims/ImsExternalCallState.java
@@ -45,6 +45,7 @@
     private int mCallId;
     // Number
     private Uri mAddress;
+    private Uri mLocalAddress;
     private boolean mIsPullable;
     // CALL_STATE_CONFIRMED / CALL_STATE_TERMINATED
     private int mCallState;
@@ -69,10 +70,24 @@
     }
 
     /** @hide */
+    public ImsExternalCallState(int callId, Uri address, Uri localAddress,
+            boolean isPullable, int callState, int callType, boolean isCallheld) {
+        mCallId = callId;
+        mAddress = address;
+        mLocalAddress = localAddress;
+        mIsPullable = isPullable;
+        mCallState = callState;
+        mCallType = callType;
+        mIsHeld = isCallheld;
+        Rlog.d(TAG, "ImsExternalCallState = " + this);
+    }
+
+    /** @hide */
     public ImsExternalCallState(Parcel in) {
         mCallId = in.readInt();
         ClassLoader classLoader = ImsExternalCallState.class.getClassLoader();
         mAddress = in.readParcelable(classLoader);
+        mLocalAddress = in.readParcelable(classLoader);
         mIsPullable = (in.readInt() != 0);
         mCallState = in.readInt();
         mCallType = in.readInt();
@@ -89,6 +104,7 @@
     public void writeToParcel(Parcel out, int flags) {
         out.writeInt(mCallId);
         out.writeParcelable(mAddress, 0);
+        out.writeParcelable(mLocalAddress, 0);
         out.writeInt(mIsPullable ? 1 : 0);
         out.writeInt(mCallState);
         out.writeInt(mCallType);
@@ -117,6 +133,11 @@
         return mAddress;
     }
 
+    /** @hide */
+    public Uri getLocalAddress() {
+        return mLocalAddress;
+    }
+
     public boolean isCallPullable() {
         return mIsPullable;
     }
@@ -137,6 +158,7 @@
     public String toString() {
         return "ImsExternalCallState { mCallId = " + mCallId +
                 ", mAddress = " + Log.pii(mAddress) +
+                ", mLocalAddress = " + Log.pii(mLocalAddress) +
                 ", mIsPullable = " + mIsPullable +
                 ", mCallState = " + mCallState +
                 ", mCallType = " + mCallType +
diff --git a/telephony/java/com/android/internal/telephony/DctConstants.java b/telephony/java/com/android/internal/telephony/DctConstants.java
index e546917..86cb1b7 100644
--- a/telephony/java/com/android/internal/telephony/DctConstants.java
+++ b/telephony/java/com/android/internal/telephony/DctConstants.java
@@ -103,19 +103,6 @@
 
     /***** Constants *****/
 
-    public static final int APN_INVALID_ID = -1;
-    public static final int APN_DEFAULT_ID = 0;
-    public static final int APN_MMS_ID = 1;
-    public static final int APN_SUPL_ID = 2;
-    public static final int APN_DUN_ID = 3;
-    public static final int APN_HIPRI_ID = 4;
-    public static final int APN_IMS_ID = 5;
-    public static final int APN_FOTA_ID = 6;
-    public static final int APN_CBS_ID = 7;
-    public static final int APN_IA_ID = 8;
-    public static final int APN_EMERGENCY_ID = 9;
-    public static final int APN_NUM_TYPES = 10;
-
     public static final int INVALID = -1;
     public static final int DISABLED = 0;
     public static final int ENABLED = 1;
diff --git a/telephony/java/com/android/internal/telephony/ISmsBaseImpl.java b/telephony/java/com/android/internal/telephony/ISmsBaseImpl.java
new file mode 100644
index 0000000..cc1d105
--- /dev/null
+++ b/telephony/java/com/android/internal/telephony/ISmsBaseImpl.java
@@ -0,0 +1,199 @@
+/* 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.
+ *
+ */
+
+package com.android.internal.telephony;
+
+import android.app.PendingIntent;
+import android.net.Uri;
+import java.lang.UnsupportedOperationException;
+import java.util.List;
+
+public class ISmsBaseImpl extends ISms.Stub {
+
+    @Override
+    public List<SmsRawData> getAllMessagesFromIccEfForSubscriber(int subId, String callingPkg) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean updateMessageOnIccEfForSubscriber(int subId, String callingPkg,
+             int messageIndex, int newStatus, byte[] pdu) throws UnsupportedOperationException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean copyMessageToIccEfForSubscriber(int subId, String callingPkg, int status,
+            byte[] pdu, byte[] smsc) throws UnsupportedOperationException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void sendDataForSubscriber(int subId, String callingPkg, String destAddr,
+            String scAddr, int destPort, byte[] data, PendingIntent sentIntent,
+            PendingIntent deliveryIntent) throws UnsupportedOperationException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void sendDataForSubscriberWithSelfPermissions(int subId, String callingPkg,
+            String destAddr, String scAddr, int destPort, byte[] data,
+            PendingIntent sentIntent, PendingIntent deliveryIntent)
+            throws UnsupportedOperationException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void sendTextForSubscriber(int subId, String callingPkg, String destAddr,
+            String scAddr, String text, PendingIntent sentIntent,
+            PendingIntent deliveryIntent, boolean persistMessageForNonDefaultSmsApp)
+            throws UnsupportedOperationException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void sendTextForSubscriberWithSelfPermissions(int subId, String callingPkg,
+            String destAddr, String scAddr, String text, PendingIntent sentIntent,
+            PendingIntent deliveryIntent, boolean persistMessage)
+            throws UnsupportedOperationException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void sendTextForSubscriberWithOptions(int subId, String callingPkg, String destAddr,
+            String scAddr, String text, PendingIntent sentIntent,
+            PendingIntent deliveryIntent, boolean persistMessageForNonDefaultSmsApp,
+            int priority, boolean expectMore, int validityPeriod)
+            throws UnsupportedOperationException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void injectSmsPduForSubscriber(
+            int subId, byte[] pdu, String format, PendingIntent receivedIntent)
+            throws UnsupportedOperationException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void sendMultipartTextForSubscriber(int subId, String callingPkg,
+            String destinationAddress, String scAddress,
+            List<String> parts, List<PendingIntent> sentIntents,
+            List<PendingIntent> deliveryIntents, boolean persistMessageForNonDefaultSmsApp)
+            throws UnsupportedOperationException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void sendMultipartTextForSubscriberWithOptions(int subId, String callingPkg,
+            String destinationAddress, String scAddress,
+            List<String> parts, List<PendingIntent> sentIntents,
+            List<PendingIntent> deliveryIntents, boolean persistMessageForNonDefaultSmsApp,
+            int priority, boolean expectMore, int validityPeriod)
+            throws UnsupportedOperationException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean enableCellBroadcastForSubscriber(int subId, int messageIdentifier, int ranType)
+            throws UnsupportedOperationException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean disableCellBroadcastForSubscriber(int subId, int messageIdentifier, int ranType)
+            throws UnsupportedOperationException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean enableCellBroadcastRangeForSubscriber(int subId, int startMessageId,
+            int endMessageId, int ranType) throws UnsupportedOperationException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean disableCellBroadcastRangeForSubscriber(int subId, int startMessageId,
+            int endMessageId, int ranType) throws UnsupportedOperationException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public int getPremiumSmsPermission(String packageName) throws UnsupportedOperationException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public int getPremiumSmsPermissionForSubscriber(int subId, String packageName)
+            throws UnsupportedOperationException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void setPremiumSmsPermission(String packageName, int permission) throws UnsupportedOperationException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void setPremiumSmsPermissionForSubscriber(int subId, String packageName,
+            int permission) throws UnsupportedOperationException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean isImsSmsSupportedForSubscriber(int subId) throws UnsupportedOperationException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean isSmsSimPickActivityNeeded(int subId) throws UnsupportedOperationException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public int getPreferredSmsSubscription() throws UnsupportedOperationException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public String getImsSmsFormatForSubscriber(int subId) throws UnsupportedOperationException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean isSMSPromptEnabled() throws UnsupportedOperationException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void sendStoredText(int subId, String callingPkg, Uri messageUri, String scAddress,
+            PendingIntent sentIntent, PendingIntent deliveryIntent)
+            throws UnsupportedOperationException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void sendStoredMultipartText(int subId, String callingPkg, Uri messageUri,
+                String scAddress, List<PendingIntent> sentIntents,
+                List<PendingIntent> deliveryIntents) throws UnsupportedOperationException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public String createAppSpecificSmsToken(int subId, String callingPkg, PendingIntent intent)
+            throws UnsupportedOperationException {
+        throw new UnsupportedOperationException();
+    }
+}
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index 3fd1d04..70354b2 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -1198,6 +1198,13 @@
     String getImeiForSlot(int slotIndex, String callingPackage);
 
     /**
+     * Returns the Type Allocation Code from the IMEI for the given slot.
+     *
+     * @param slotIndex - Which slot to retrieve the Type Allocation Code from.
+     */
+    String getTypeAllocationCodeForSlot(int slotIndex);
+
+    /**
      * Returns the MEID for the given slot.
      *
      * @param slotIndex - device slot.
@@ -1208,6 +1215,13 @@
     String getMeidForSlot(int slotIndex, String callingPackage);
 
     /**
+     * Returns the Manufacturer Code from the MEID for the given slot.
+     *
+     * @param slotIndex - Which slot to retrieve the Manufacturer Code from.
+     */
+    String getManufacturerCodeForSlot(int slotIndex);
+
+    /**
      * Returns the device software version.
      *
      * @param slotIndex - device slot.
diff --git a/tests/TouchLatency/app/src/main/java/com/prefabulated/touchlatency/TouchLatencyActivity.java b/tests/TouchLatency/app/src/main/java/com/prefabulated/touchlatency/TouchLatencyActivity.java
index b763c78..b4b5ca7 100644
--- a/tests/TouchLatency/app/src/main/java/com/prefabulated/touchlatency/TouchLatencyActivity.java
+++ b/tests/TouchLatency/app/src/main/java/com/prefabulated/touchlatency/TouchLatencyActivity.java
@@ -30,6 +30,7 @@
 import android.view.MenuItem;
 import android.view.MotionEvent;
 import android.view.View;
+import android.os.Trace;
 
 import java.util.ArrayList;
 import java.util.Collections;
@@ -42,6 +43,7 @@
 
     public TouchLatencyView(Context context, AttributeSet attrs) {
         super(context, attrs);
+        Trace.beginSection("TouchLatencyView constructor");
         setOnTouchListener(this);
         setWillNotDraw(false);
         mBluePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
@@ -63,48 +65,56 @@
         mBallY = 100.0f;
         mVelocityX = 7.0f;
         mVelocityY = 7.0f;
+        Trace.endSection();
     }
 
     @Override
     public boolean onTouch(View view, MotionEvent event) {
+        Trace.beginSection("TouchLatencyView onTouch");
         int action = event.getActionMasked();
         if (action == MotionEvent.ACTION_DOWN || action == MotionEvent.ACTION_MOVE) {
             mTouching = true;
             invalidate();
+
+            mTouchX = event.getX();
+            mTouchY = event.getY();
         } else if (action == MotionEvent.ACTION_UP) {
             mTouching = false;
             invalidate();
-            return true;
-        } else {
-            return true;
         }
-        mTouchX = event.getX();
-        mTouchY = event.getY();
+        Trace.endSection();
         return true;
     }
 
     private void drawTouch(Canvas canvas) {
-        if (!mTouching) {
-            Log.d(LOG_TAG, "Filling background");
+        Trace.beginSection("TouchLatencyView drawTouch");
+
+        try {
+            if (!mTouching) {
+                Log.d(LOG_TAG, "Filling background");
+                canvas.drawColor(BACKGROUND_COLOR);
+                return;
+            }
+
+            float deltaX = (mTouchX - mLastDrawnX);
+            float deltaY = (mTouchY - mLastDrawnY);
+            float scaleFactor = (float) Math.sqrt(deltaX * deltaX + deltaY * deltaY) * 1.5f;
+
+            mLastDrawnX = mTouchX;
+            mLastDrawnY = mTouchY;
+
             canvas.drawColor(BACKGROUND_COLOR);
-            return;
+            canvas.drawCircle(mTouchX, mTouchY, INNER_RADIUS + 3 * scaleFactor, mRedPaint);
+            canvas.drawCircle(mTouchX, mTouchY, INNER_RADIUS + 2 * scaleFactor, mYellowPaint);
+            canvas.drawCircle(mTouchX, mTouchY, INNER_RADIUS + scaleFactor, mGreenPaint);
+            canvas.drawCircle(mTouchX, mTouchY, INNER_RADIUS, mBluePaint);
+        } finally {
+            Trace.endSection();
         }
-
-        float deltaX = (mTouchX - mLastDrawnX);
-        float deltaY = (mTouchY - mLastDrawnY);
-        float scaleFactor = (float) Math.sqrt(deltaX * deltaX + deltaY * deltaY) * 1.5f;
-
-        mLastDrawnX = mTouchX;
-        mLastDrawnY = mTouchY;
-
-        canvas.drawColor(BACKGROUND_COLOR);
-        canvas.drawCircle(mTouchX, mTouchY, INNER_RADIUS + 3 * scaleFactor, mRedPaint);
-        canvas.drawCircle(mTouchX, mTouchY, INNER_RADIUS + 2 * scaleFactor, mYellowPaint);
-        canvas.drawCircle(mTouchX, mTouchY, INNER_RADIUS + scaleFactor, mGreenPaint);
-        canvas.drawCircle(mTouchX, mTouchY, INNER_RADIUS, mBluePaint);
     }
 
     private void drawBall(Canvas canvas) {
+        Trace.beginSection("TouchLatencyView drawBall");
         int width = canvas.getWidth();
         int height = canvas.getHeight();
 
@@ -141,25 +151,29 @@
         canvas.drawColor(BACKGROUND_COLOR);
         canvas.drawOval(left, top, right, bottom, mYellowPaint);
         invalidate();
+        Trace.endSection();
     }
 
     @Override
     protected void onDraw(Canvas canvas) {
         super.onDraw(canvas);
-
+        Trace.beginSection("TouchLatencyView onDraw");
         if (mMode == 0) {
             drawTouch(canvas);
         } else {
             drawBall(canvas);
         }
+        Trace.endSection();
     }
 
     public void changeMode(MenuItem item) {
+        Trace.beginSection("TouchLatencyView changeMode");
         final int NUM_MODES = 2;
         final String modes[] = {"Touch", "Ball"};
         mMode = (mMode + 1) % NUM_MODES;
         invalidate();
         item.setTitle(modes[mMode]);
+        Trace.endSection();
     }
 
     private Paint mBluePaint, mGreenPaint, mYellowPaint, mRedPaint;
@@ -178,21 +192,26 @@
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
+        Trace.beginSection("TouchLatencyActivity onCreate");
         setContentView(R.layout.activity_touch_latency);
 
         mTouchView = findViewById(R.id.canvasView);
+        Trace.endSection();
     }
 
 
     @Override
     public boolean onCreateOptionsMenu(Menu menu) {
+        Trace.beginSection("TouchLatencyActivity onCreateOptionsMenu");
         // Inflate the menu; this adds items to the action bar if it is present.
         getMenuInflater().inflate(R.menu.menu_touch_latency, menu);
+        Trace.endSection();
         return true;
     }
 
     @Override
     public boolean onOptionsItemSelected(MenuItem item) {
+        Trace.beginSection("TouchLatencyActivity onOptionsItemSelected");
         // Handle action bar item clicks here. The action bar will
         // automatically handle clicks on the Home/Up button, so long
         // as you specify a parent activity in AndroidManifest.xml.
@@ -203,6 +222,7 @@
             mTouchView.changeMode(item);
         }
 
+        Trace.endSection();
         return super.onOptionsItemSelected(item);
     }
 
diff --git a/tests/net/AndroidTest.xml b/tests/net/AndroidTest.xml
index f8ecc6b..6e020a3 100644
--- a/tests/net/AndroidTest.xml
+++ b/tests/net/AndroidTest.xml
@@ -23,5 +23,6 @@
     <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
         <option name="package" value="com.android.frameworks.tests.net" />
         <option name="runner" value="android.support.test.runner.AndroidJUnitRunner" />
+        <option name="hidden-api-checks" value="false"/>
     </test>
 </configuration>