Merge "Correctly init code cache path for RS"
diff --git a/api/current.txt b/api/current.txt
index 30a4a97..5e84851 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -6756,9 +6756,10 @@
     method public void onServicesDiscovered(android.bluetooth.BluetoothGatt, int);
   }
 
-  public class BluetoothGattCharacteristic {
+  public class BluetoothGattCharacteristic implements android.os.Parcelable {
     ctor public BluetoothGattCharacteristic(java.util.UUID, int, int);
     method public boolean addDescriptor(android.bluetooth.BluetoothGattDescriptor);
+    method public int describeContents();
     method public android.bluetooth.BluetoothGattDescriptor getDescriptor(java.util.UUID);
     method public java.util.List<android.bluetooth.BluetoothGattDescriptor> getDescriptors();
     method public java.lang.Float getFloatValue(int, int);
@@ -6776,6 +6777,8 @@
     method public boolean setValue(int, int, int, int);
     method public boolean setValue(java.lang.String);
     method public void setWriteType(int);
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.bluetooth.BluetoothGattCharacteristic> CREATOR;
     field public static final int FORMAT_FLOAT = 52; // 0x34
     field public static final int FORMAT_SFLOAT = 50; // 0x32
     field public static final int FORMAT_SINT16 = 34; // 0x22
@@ -6806,13 +6809,16 @@
     field protected java.util.List<android.bluetooth.BluetoothGattDescriptor> mDescriptors;
   }
 
-  public class BluetoothGattDescriptor {
+  public class BluetoothGattDescriptor implements android.os.Parcelable {
     ctor public BluetoothGattDescriptor(java.util.UUID, int);
+    method public int describeContents();
     method public android.bluetooth.BluetoothGattCharacteristic getCharacteristic();
     method public int getPermissions();
     method public java.util.UUID getUuid();
     method public byte[] getValue();
     method public boolean setValue(byte[]);
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.bluetooth.BluetoothGattDescriptor> CREATOR;
     field public static final byte[] DISABLE_NOTIFICATION_VALUE;
     field public static final byte[] ENABLE_INDICATION_VALUE;
     field public static final byte[] ENABLE_NOTIFICATION_VALUE;
@@ -6855,16 +6861,19 @@
     method public void onServiceAdded(int, android.bluetooth.BluetoothGattService);
   }
 
-  public class BluetoothGattService {
+  public class BluetoothGattService implements android.os.Parcelable {
     ctor public BluetoothGattService(java.util.UUID, int);
     method public boolean addCharacteristic(android.bluetooth.BluetoothGattCharacteristic);
     method public boolean addService(android.bluetooth.BluetoothGattService);
+    method public int describeContents();
     method public android.bluetooth.BluetoothGattCharacteristic getCharacteristic(java.util.UUID);
     method public java.util.List<android.bluetooth.BluetoothGattCharacteristic> getCharacteristics();
     method public java.util.List<android.bluetooth.BluetoothGattService> getIncludedServices();
     method public int getInstanceId();
     method public int getType();
     method public java.util.UUID getUuid();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.bluetooth.BluetoothGattService> CREATOR;
     field public static final int SERVICE_TYPE_PRIMARY = 0; // 0x0
     field public static final int SERVICE_TYPE_SECONDARY = 1; // 0x1
     field protected java.util.List<android.bluetooth.BluetoothGattCharacteristic> mCharacteristics;
@@ -48341,6 +48350,7 @@
     method public float floatValue();
     method public static int hashCode(double);
     method public int intValue();
+    method public static boolean isFinite(double);
     method public static boolean isInfinite(double);
     method public boolean isInfinite();
     method public static boolean isNaN(double);
@@ -48422,6 +48432,7 @@
     method public float floatValue();
     method public static float intBitsToFloat(int);
     method public int intValue();
+    method public static boolean isFinite(float);
     method public static boolean isInfinite(float);
     method public boolean isInfinite();
     method public static boolean isNaN(float);
@@ -55002,6 +55013,7 @@
     method public E get(int);
     method public boolean removeIf(java.util.function.Predicate<? super E>);
     method public int size();
+    method public void sort(java.util.Comparator<? super E>);
     method public java.util.Spliterator<E> spliterator();
     method public void trimToSize();
   }
@@ -55103,6 +55115,10 @@
     method public static void parallelSort(T[], int, int);
     method public static void parallelSort(T[], java.util.Comparator<? super T>);
     method public static void parallelSort(T[], int, int, java.util.Comparator<? super T>);
+    method public static void setAll(T[], java.util.function.IntFunction<? extends T>);
+    method public static void setAll(int[], java.util.function.IntUnaryOperator);
+    method public static void setAll(long[], java.util.function.IntToLongFunction);
+    method public static void setAll(double[], java.util.function.IntToDoubleFunction);
     method public static void sort(int[]);
     method public static void sort(int[], int, int);
     method public static void sort(long[]);
@@ -55129,6 +55145,14 @@
     method public static java.util.Spliterator.OfLong spliterator(long[], int, int);
     method public static java.util.Spliterator.OfDouble spliterator(double[]);
     method public static java.util.Spliterator.OfDouble spliterator(double[], int, int);
+    method public static java.util.stream.Stream<T> stream(T[]);
+    method public static java.util.stream.Stream<T> stream(T[], int, int);
+    method public static java.util.stream.IntStream stream(int[]);
+    method public static java.util.stream.IntStream stream(int[], int, int);
+    method public static java.util.stream.LongStream stream(long[]);
+    method public static java.util.stream.LongStream stream(long[], int, int);
+    method public static java.util.stream.DoubleStream stream(double[]);
+    method public static java.util.stream.DoubleStream stream(double[], int, int);
     method public static java.lang.String toString(long[]);
     method public static java.lang.String toString(int[]);
     method public static java.lang.String toString(short[]);
@@ -55288,11 +55312,13 @@
     method public abstract int hashCode();
     method public abstract boolean isEmpty();
     method public abstract java.util.Iterator<E> iterator();
+    method public default java.util.stream.Stream<E> parallelStream();
     method public abstract boolean remove(java.lang.Object);
     method public abstract boolean removeAll(java.util.Collection<?>);
     method public default boolean removeIf(java.util.function.Predicate<? super E>);
     method public abstract boolean retainAll(java.util.Collection<?>);
     method public abstract int size();
+    method public default java.util.stream.Stream<E> stream();
     method public abstract java.lang.Object[] toArray();
     method public abstract T[] toArray(T[]);
   }
@@ -56492,6 +56518,34 @@
     method public java.util.Spliterator<T> trySplit();
   }
 
+  public final class SplittableRandom {
+    ctor public SplittableRandom(long);
+    ctor public SplittableRandom();
+    method public java.util.stream.DoubleStream doubles(long);
+    method public java.util.stream.DoubleStream doubles();
+    method public java.util.stream.DoubleStream doubles(long, double, double);
+    method public java.util.stream.DoubleStream doubles(double, double);
+    method public java.util.stream.IntStream ints(long);
+    method public java.util.stream.IntStream ints();
+    method public java.util.stream.IntStream ints(long, int, int);
+    method public java.util.stream.IntStream ints(int, int);
+    method public java.util.stream.LongStream longs(long);
+    method public java.util.stream.LongStream longs();
+    method public java.util.stream.LongStream longs(long, long, long);
+    method public java.util.stream.LongStream longs(long, long);
+    method public boolean nextBoolean();
+    method public double nextDouble();
+    method public double nextDouble(double);
+    method public double nextDouble(double, double);
+    method public int nextInt();
+    method public int nextInt(int);
+    method public int nextInt(int, int);
+    method public long nextLong();
+    method public long nextLong(long);
+    method public long nextLong(long, long);
+    method public java.util.SplittableRandom split();
+  }
+
   public class Stack extends java.util.Vector {
     ctor public Stack();
     method public boolean empty();
@@ -57675,6 +57729,18 @@
 
   public class ThreadLocalRandom extends java.util.Random {
     method public static java.util.concurrent.ThreadLocalRandom current();
+    method public java.util.stream.DoubleStream doubles(long);
+    method public java.util.stream.DoubleStream doubles();
+    method public java.util.stream.DoubleStream doubles(long, double, double);
+    method public java.util.stream.DoubleStream doubles(double, double);
+    method public java.util.stream.IntStream ints(long);
+    method public java.util.stream.IntStream ints();
+    method public java.util.stream.IntStream ints(long, int, int);
+    method public java.util.stream.IntStream ints(int, int);
+    method public java.util.stream.LongStream longs(long);
+    method public java.util.stream.LongStream longs();
+    method public java.util.stream.LongStream longs(long, long, long);
+    method public java.util.stream.LongStream longs(long, long);
     method public double nextDouble(double);
     method public double nextDouble(double, double);
     method public int nextInt(int, int);
@@ -59076,6 +59142,292 @@
 
 }
 
+package java.util.stream {
+
+  public abstract interface BaseStream implements java.lang.AutoCloseable {
+    method public abstract void close();
+    method public abstract boolean isParallel();
+    method public abstract java.util.Iterator<T> iterator();
+    method public abstract S onClose(java.lang.Runnable);
+    method public abstract S parallel();
+    method public abstract S sequential();
+    method public abstract java.util.Spliterator<T> spliterator();
+    method public abstract S unordered();
+  }
+
+  public abstract interface Collector {
+    method public abstract java.util.function.BiConsumer<A, T> accumulator();
+    method public abstract java.util.Set<java.util.stream.Collector.Characteristics> characteristics();
+    method public abstract java.util.function.BinaryOperator<A> combiner();
+    method public abstract java.util.function.Function<A, R> finisher();
+    method public static java.util.stream.Collector<T, R, R> of(java.util.function.Supplier<R>, java.util.function.BiConsumer<R, T>, java.util.function.BinaryOperator<R>, java.util.stream.Collector.Characteristics...);
+    method public static java.util.stream.Collector<T, A, R> of(java.util.function.Supplier<A>, java.util.function.BiConsumer<A, T>, java.util.function.BinaryOperator<A>, java.util.function.Function<A, R>, java.util.stream.Collector.Characteristics...);
+    method public abstract java.util.function.Supplier<A> supplier();
+  }
+
+  public static final class Collector.Characteristics extends java.lang.Enum {
+    method public static java.util.stream.Collector.Characteristics valueOf(java.lang.String);
+    method public static final java.util.stream.Collector.Characteristics[] values();
+    enum_constant public static final java.util.stream.Collector.Characteristics CONCURRENT;
+    enum_constant public static final java.util.stream.Collector.Characteristics IDENTITY_FINISH;
+    enum_constant public static final java.util.stream.Collector.Characteristics UNORDERED;
+  }
+
+  public final class Collectors {
+    method public static java.util.stream.Collector<T, ?, java.lang.Double> averagingDouble(java.util.function.ToDoubleFunction<? super T>);
+    method public static java.util.stream.Collector<T, ?, java.lang.Double> averagingInt(java.util.function.ToIntFunction<? super T>);
+    method public static java.util.stream.Collector<T, ?, java.lang.Double> averagingLong(java.util.function.ToLongFunction<? super T>);
+    method public static java.util.stream.Collector<T, A, RR> collectingAndThen(java.util.stream.Collector<T, A, R>, java.util.function.Function<R, RR>);
+    method public static java.util.stream.Collector<T, ?, java.lang.Long> counting();
+    method public static java.util.stream.Collector<T, ?, java.util.Map<K, java.util.List<T>>> groupingBy(java.util.function.Function<? super T, ? extends K>);
+    method public static java.util.stream.Collector<T, ?, java.util.Map<K, D>> groupingBy(java.util.function.Function<? super T, ? extends K>, java.util.stream.Collector<? super T, A, D>);
+    method public static java.util.stream.Collector<T, ?, M> groupingBy(java.util.function.Function<? super T, ? extends K>, java.util.function.Supplier<M>, java.util.stream.Collector<? super T, A, D>);
+    method public static java.util.stream.Collector<T, ?, java.util.concurrent.ConcurrentMap<K, java.util.List<T>>> groupingByConcurrent(java.util.function.Function<? super T, ? extends K>);
+    method public static java.util.stream.Collector<T, ?, java.util.concurrent.ConcurrentMap<K, D>> groupingByConcurrent(java.util.function.Function<? super T, ? extends K>, java.util.stream.Collector<? super T, A, D>);
+    method public static java.util.stream.Collector<T, ?, M> groupingByConcurrent(java.util.function.Function<? super T, ? extends K>, java.util.function.Supplier<M>, java.util.stream.Collector<? super T, A, D>);
+    method public static java.util.stream.Collector<java.lang.CharSequence, ?, java.lang.String> joining();
+    method public static java.util.stream.Collector<java.lang.CharSequence, ?, java.lang.String> joining(java.lang.CharSequence);
+    method public static java.util.stream.Collector<java.lang.CharSequence, ?, java.lang.String> joining(java.lang.CharSequence, java.lang.CharSequence, java.lang.CharSequence);
+    method public static java.util.stream.Collector<T, ?, R> mapping(java.util.function.Function<? super T, ? extends U>, java.util.stream.Collector<? super U, A, R>);
+    method public static java.util.stream.Collector<T, ?, java.util.Optional<T>> maxBy(java.util.Comparator<? super T>);
+    method public static java.util.stream.Collector<T, ?, java.util.Optional<T>> minBy(java.util.Comparator<? super T>);
+    method public static java.util.stream.Collector<T, ?, java.util.Map<java.lang.Boolean, java.util.List<T>>> partitioningBy(java.util.function.Predicate<? super T>);
+    method public static java.util.stream.Collector<T, ?, java.util.Map<java.lang.Boolean, D>> partitioningBy(java.util.function.Predicate<? super T>, java.util.stream.Collector<? super T, A, D>);
+    method public static java.util.stream.Collector<T, ?, T> reducing(T, java.util.function.BinaryOperator<T>);
+    method public static java.util.stream.Collector<T, ?, java.util.Optional<T>> reducing(java.util.function.BinaryOperator<T>);
+    method public static java.util.stream.Collector<T, ?, U> reducing(U, java.util.function.Function<? super T, ? extends U>, java.util.function.BinaryOperator<U>);
+    method public static java.util.stream.Collector<T, ?, java.util.DoubleSummaryStatistics> summarizingDouble(java.util.function.ToDoubleFunction<? super T>);
+    method public static java.util.stream.Collector<T, ?, java.util.IntSummaryStatistics> summarizingInt(java.util.function.ToIntFunction<? super T>);
+    method public static java.util.stream.Collector<T, ?, java.util.LongSummaryStatistics> summarizingLong(java.util.function.ToLongFunction<? super T>);
+    method public static java.util.stream.Collector<T, ?, java.lang.Double> summingDouble(java.util.function.ToDoubleFunction<? super T>);
+    method public static java.util.stream.Collector<T, ?, java.lang.Integer> summingInt(java.util.function.ToIntFunction<? super T>);
+    method public static java.util.stream.Collector<T, ?, java.lang.Long> summingLong(java.util.function.ToLongFunction<? super T>);
+    method public static java.util.stream.Collector<T, ?, C> toCollection(java.util.function.Supplier<C>);
+    method public static java.util.stream.Collector<T, ?, java.util.concurrent.ConcurrentMap<K, U>> toConcurrentMap(java.util.function.Function<? super T, ? extends K>, java.util.function.Function<? super T, ? extends U>);
+    method public static java.util.stream.Collector<T, ?, java.util.concurrent.ConcurrentMap<K, U>> toConcurrentMap(java.util.function.Function<? super T, ? extends K>, java.util.function.Function<? super T, ? extends U>, java.util.function.BinaryOperator<U>);
+    method public static java.util.stream.Collector<T, ?, M> toConcurrentMap(java.util.function.Function<? super T, ? extends K>, java.util.function.Function<? super T, ? extends U>, java.util.function.BinaryOperator<U>, java.util.function.Supplier<M>);
+    method public static java.util.stream.Collector<T, ?, java.util.List<T>> toList();
+    method public static java.util.stream.Collector<T, ?, java.util.Map<K, U>> toMap(java.util.function.Function<? super T, ? extends K>, java.util.function.Function<? super T, ? extends U>);
+    method public static java.util.stream.Collector<T, ?, java.util.Map<K, U>> toMap(java.util.function.Function<? super T, ? extends K>, java.util.function.Function<? super T, ? extends U>, java.util.function.BinaryOperator<U>);
+    method public static java.util.stream.Collector<T, ?, M> toMap(java.util.function.Function<? super T, ? extends K>, java.util.function.Function<? super T, ? extends U>, java.util.function.BinaryOperator<U>, java.util.function.Supplier<M>);
+    method public static java.util.stream.Collector<T, ?, java.util.Set<T>> toSet();
+  }
+
+  public abstract interface DoubleStream implements java.util.stream.BaseStream {
+    method public abstract boolean allMatch(java.util.function.DoublePredicate);
+    method public abstract boolean anyMatch(java.util.function.DoublePredicate);
+    method public abstract java.util.OptionalDouble average();
+    method public abstract java.util.stream.Stream<java.lang.Double> boxed();
+    method public static java.util.stream.DoubleStream.Builder builder();
+    method public abstract R collect(java.util.function.Supplier<R>, java.util.function.ObjDoubleConsumer<R>, java.util.function.BiConsumer<R, R>);
+    method public static java.util.stream.DoubleStream concat(java.util.stream.DoubleStream, java.util.stream.DoubleStream);
+    method public abstract long count();
+    method public abstract java.util.stream.DoubleStream distinct();
+    method public static java.util.stream.DoubleStream empty();
+    method public abstract java.util.stream.DoubleStream filter(java.util.function.DoublePredicate);
+    method public abstract java.util.OptionalDouble findAny();
+    method public abstract java.util.OptionalDouble findFirst();
+    method public abstract java.util.stream.DoubleStream flatMap(java.util.function.DoubleFunction<? extends java.util.stream.DoubleStream>);
+    method public abstract void forEach(java.util.function.DoubleConsumer);
+    method public abstract void forEachOrdered(java.util.function.DoubleConsumer);
+    method public static java.util.stream.DoubleStream generate(java.util.function.DoubleSupplier);
+    method public static java.util.stream.DoubleStream iterate(double, java.util.function.DoubleUnaryOperator);
+    method public abstract java.util.PrimitiveIterator.OfDouble iterator();
+    method public abstract java.util.stream.DoubleStream limit(long);
+    method public abstract java.util.stream.DoubleStream map(java.util.function.DoubleUnaryOperator);
+    method public abstract java.util.stream.IntStream mapToInt(java.util.function.DoubleToIntFunction);
+    method public abstract java.util.stream.LongStream mapToLong(java.util.function.DoubleToLongFunction);
+    method public abstract java.util.stream.Stream<U> mapToObj(java.util.function.DoubleFunction<? extends U>);
+    method public abstract java.util.OptionalDouble max();
+    method public abstract java.util.OptionalDouble min();
+    method public abstract boolean noneMatch(java.util.function.DoublePredicate);
+    method public static java.util.stream.DoubleStream of(double);
+    method public static java.util.stream.DoubleStream of(double...);
+    method public abstract java.util.stream.DoubleStream parallel();
+    method public abstract java.util.stream.DoubleStream peek(java.util.function.DoubleConsumer);
+    method public abstract double reduce(double, java.util.function.DoubleBinaryOperator);
+    method public abstract java.util.OptionalDouble reduce(java.util.function.DoubleBinaryOperator);
+    method public abstract java.util.stream.DoubleStream sequential();
+    method public abstract java.util.stream.DoubleStream skip(long);
+    method public abstract java.util.stream.DoubleStream sorted();
+    method public abstract java.util.Spliterator.OfDouble spliterator();
+    method public abstract double sum();
+    method public abstract java.util.DoubleSummaryStatistics summaryStatistics();
+    method public abstract double[] toArray();
+  }
+
+  public static abstract interface DoubleStream.Builder implements java.util.function.DoubleConsumer {
+    method public abstract void accept(double);
+    method public default java.util.stream.DoubleStream.Builder add(double);
+    method public abstract java.util.stream.DoubleStream build();
+  }
+
+  public abstract interface IntStream implements java.util.stream.BaseStream {
+    method public abstract boolean allMatch(java.util.function.IntPredicate);
+    method public abstract boolean anyMatch(java.util.function.IntPredicate);
+    method public abstract java.util.stream.DoubleStream asDoubleStream();
+    method public abstract java.util.stream.LongStream asLongStream();
+    method public abstract java.util.OptionalDouble average();
+    method public abstract java.util.stream.Stream<java.lang.Integer> boxed();
+    method public static java.util.stream.IntStream.Builder builder();
+    method public abstract R collect(java.util.function.Supplier<R>, java.util.function.ObjIntConsumer<R>, java.util.function.BiConsumer<R, R>);
+    method public static java.util.stream.IntStream concat(java.util.stream.IntStream, java.util.stream.IntStream);
+    method public abstract long count();
+    method public abstract java.util.stream.IntStream distinct();
+    method public static java.util.stream.IntStream empty();
+    method public abstract java.util.stream.IntStream filter(java.util.function.IntPredicate);
+    method public abstract java.util.OptionalInt findAny();
+    method public abstract java.util.OptionalInt findFirst();
+    method public abstract java.util.stream.IntStream flatMap(java.util.function.IntFunction<? extends java.util.stream.IntStream>);
+    method public abstract void forEach(java.util.function.IntConsumer);
+    method public abstract void forEachOrdered(java.util.function.IntConsumer);
+    method public static java.util.stream.IntStream generate(java.util.function.IntSupplier);
+    method public static java.util.stream.IntStream iterate(int, java.util.function.IntUnaryOperator);
+    method public abstract java.util.PrimitiveIterator.OfInt iterator();
+    method public abstract java.util.stream.IntStream limit(long);
+    method public abstract java.util.stream.IntStream map(java.util.function.IntUnaryOperator);
+    method public abstract java.util.stream.DoubleStream mapToDouble(java.util.function.IntToDoubleFunction);
+    method public abstract java.util.stream.LongStream mapToLong(java.util.function.IntToLongFunction);
+    method public abstract java.util.stream.Stream<U> mapToObj(java.util.function.IntFunction<? extends U>);
+    method public abstract java.util.OptionalInt max();
+    method public abstract java.util.OptionalInt min();
+    method public abstract boolean noneMatch(java.util.function.IntPredicate);
+    method public static java.util.stream.IntStream of(int);
+    method public static java.util.stream.IntStream of(int...);
+    method public abstract java.util.stream.IntStream parallel();
+    method public abstract java.util.stream.IntStream peek(java.util.function.IntConsumer);
+    method public static java.util.stream.IntStream range(int, int);
+    method public static java.util.stream.IntStream rangeClosed(int, int);
+    method public abstract int reduce(int, java.util.function.IntBinaryOperator);
+    method public abstract java.util.OptionalInt reduce(java.util.function.IntBinaryOperator);
+    method public abstract java.util.stream.IntStream sequential();
+    method public abstract java.util.stream.IntStream skip(long);
+    method public abstract java.util.stream.IntStream sorted();
+    method public abstract java.util.Spliterator.OfInt spliterator();
+    method public abstract int sum();
+    method public abstract java.util.IntSummaryStatistics summaryStatistics();
+    method public abstract int[] toArray();
+  }
+
+  public static abstract interface IntStream.Builder implements java.util.function.IntConsumer {
+    method public abstract void accept(int);
+    method public default java.util.stream.IntStream.Builder add(int);
+    method public abstract java.util.stream.IntStream build();
+  }
+
+  public abstract interface LongStream implements java.util.stream.BaseStream {
+    method public abstract boolean allMatch(java.util.function.LongPredicate);
+    method public abstract boolean anyMatch(java.util.function.LongPredicate);
+    method public abstract java.util.stream.DoubleStream asDoubleStream();
+    method public abstract java.util.OptionalDouble average();
+    method public abstract java.util.stream.Stream<java.lang.Long> boxed();
+    method public static java.util.stream.LongStream.Builder builder();
+    method public abstract R collect(java.util.function.Supplier<R>, java.util.function.ObjLongConsumer<R>, java.util.function.BiConsumer<R, R>);
+    method public static java.util.stream.LongStream concat(java.util.stream.LongStream, java.util.stream.LongStream);
+    method public abstract long count();
+    method public abstract java.util.stream.LongStream distinct();
+    method public static java.util.stream.LongStream empty();
+    method public abstract java.util.stream.LongStream filter(java.util.function.LongPredicate);
+    method public abstract java.util.OptionalLong findAny();
+    method public abstract java.util.OptionalLong findFirst();
+    method public abstract java.util.stream.LongStream flatMap(java.util.function.LongFunction<? extends java.util.stream.LongStream>);
+    method public abstract void forEach(java.util.function.LongConsumer);
+    method public abstract void forEachOrdered(java.util.function.LongConsumer);
+    method public static java.util.stream.LongStream generate(java.util.function.LongSupplier);
+    method public static java.util.stream.LongStream iterate(long, java.util.function.LongUnaryOperator);
+    method public abstract java.util.PrimitiveIterator.OfLong iterator();
+    method public abstract java.util.stream.LongStream limit(long);
+    method public abstract java.util.stream.LongStream map(java.util.function.LongUnaryOperator);
+    method public abstract java.util.stream.DoubleStream mapToDouble(java.util.function.LongToDoubleFunction);
+    method public abstract java.util.stream.IntStream mapToInt(java.util.function.LongToIntFunction);
+    method public abstract java.util.stream.Stream<U> mapToObj(java.util.function.LongFunction<? extends U>);
+    method public abstract java.util.OptionalLong max();
+    method public abstract java.util.OptionalLong min();
+    method public abstract boolean noneMatch(java.util.function.LongPredicate);
+    method public static java.util.stream.LongStream of(long);
+    method public static java.util.stream.LongStream of(long...);
+    method public abstract java.util.stream.LongStream parallel();
+    method public abstract java.util.stream.LongStream peek(java.util.function.LongConsumer);
+    method public static java.util.stream.LongStream range(long, long);
+    method public static java.util.stream.LongStream rangeClosed(long, long);
+    method public abstract long reduce(long, java.util.function.LongBinaryOperator);
+    method public abstract java.util.OptionalLong reduce(java.util.function.LongBinaryOperator);
+    method public abstract java.util.stream.LongStream sequential();
+    method public abstract java.util.stream.LongStream skip(long);
+    method public abstract java.util.stream.LongStream sorted();
+    method public abstract java.util.Spliterator.OfLong spliterator();
+    method public abstract long sum();
+    method public abstract java.util.LongSummaryStatistics summaryStatistics();
+    method public abstract long[] toArray();
+  }
+
+  public static abstract interface LongStream.Builder implements java.util.function.LongConsumer {
+    method public abstract void accept(long);
+    method public default java.util.stream.LongStream.Builder add(long);
+    method public abstract java.util.stream.LongStream build();
+  }
+
+  public abstract interface Stream implements java.util.stream.BaseStream {
+    method public abstract boolean allMatch(java.util.function.Predicate<? super T>);
+    method public abstract boolean anyMatch(java.util.function.Predicate<? super T>);
+    method public static java.util.stream.Stream.Builder<T> builder();
+    method public abstract R collect(java.util.function.Supplier<R>, java.util.function.BiConsumer<R, ? super T>, java.util.function.BiConsumer<R, R>);
+    method public abstract R collect(java.util.stream.Collector<? super T, A, R>);
+    method public static java.util.stream.Stream<T> concat(java.util.stream.Stream<? extends T>, java.util.stream.Stream<? extends T>);
+    method public abstract long count();
+    method public abstract java.util.stream.Stream<T> distinct();
+    method public static java.util.stream.Stream<T> empty();
+    method public abstract java.util.stream.Stream<T> filter(java.util.function.Predicate<? super T>);
+    method public abstract java.util.Optional<T> findAny();
+    method public abstract java.util.Optional<T> findFirst();
+    method public abstract java.util.stream.Stream<R> flatMap(java.util.function.Function<? super T, ? extends java.util.stream.Stream<? extends R>>);
+    method public abstract java.util.stream.DoubleStream flatMapToDouble(java.util.function.Function<? super T, ? extends java.util.stream.DoubleStream>);
+    method public abstract java.util.stream.IntStream flatMapToInt(java.util.function.Function<? super T, ? extends java.util.stream.IntStream>);
+    method public abstract java.util.stream.LongStream flatMapToLong(java.util.function.Function<? super T, ? extends java.util.stream.LongStream>);
+    method public abstract void forEach(java.util.function.Consumer<? super T>);
+    method public abstract void forEachOrdered(java.util.function.Consumer<? super T>);
+    method public static java.util.stream.Stream<T> generate(java.util.function.Supplier<T>);
+    method public static java.util.stream.Stream<T> iterate(T, java.util.function.UnaryOperator<T>);
+    method public abstract java.util.stream.Stream<T> limit(long);
+    method public abstract java.util.stream.Stream<R> map(java.util.function.Function<? super T, ? extends R>);
+    method public abstract java.util.stream.DoubleStream mapToDouble(java.util.function.ToDoubleFunction<? super T>);
+    method public abstract java.util.stream.IntStream mapToInt(java.util.function.ToIntFunction<? super T>);
+    method public abstract java.util.stream.LongStream mapToLong(java.util.function.ToLongFunction<? super T>);
+    method public abstract java.util.Optional<T> max(java.util.Comparator<? super T>);
+    method public abstract java.util.Optional<T> min(java.util.Comparator<? super T>);
+    method public abstract boolean noneMatch(java.util.function.Predicate<? super T>);
+    method public static java.util.stream.Stream<T> of(T);
+    method public static java.util.stream.Stream<T> of(T...);
+    method public abstract java.util.stream.Stream<T> peek(java.util.function.Consumer<? super T>);
+    method public abstract T reduce(T, java.util.function.BinaryOperator<T>);
+    method public abstract java.util.Optional<T> reduce(java.util.function.BinaryOperator<T>);
+    method public abstract U reduce(U, java.util.function.BiFunction<U, ? super T, U>, java.util.function.BinaryOperator<U>);
+    method public abstract java.util.stream.Stream<T> skip(long);
+    method public abstract java.util.stream.Stream<T> sorted();
+    method public abstract java.util.stream.Stream<T> sorted(java.util.Comparator<? super T>);
+    method public abstract java.lang.Object[] toArray();
+    method public abstract A[] toArray(java.util.function.IntFunction<A[]>);
+  }
+
+  public static abstract interface Stream.Builder implements java.util.function.Consumer {
+    method public abstract void accept(T);
+    method public default java.util.stream.Stream.Builder<T> add(T);
+    method public abstract java.util.stream.Stream<T> build();
+  }
+
+  public final class StreamSupport {
+    method public static java.util.stream.DoubleStream doubleStream(java.util.Spliterator.OfDouble, boolean);
+    method public static java.util.stream.DoubleStream doubleStream(java.util.function.Supplier<? extends java.util.Spliterator.OfDouble>, int, boolean);
+    method public static java.util.stream.IntStream intStream(java.util.Spliterator.OfInt, boolean);
+    method public static java.util.stream.IntStream intStream(java.util.function.Supplier<? extends java.util.Spliterator.OfInt>, int, boolean);
+    method public static java.util.stream.LongStream longStream(java.util.Spliterator.OfLong, boolean);
+    method public static java.util.stream.LongStream longStream(java.util.function.Supplier<? extends java.util.Spliterator.OfLong>, int, boolean);
+    method public static java.util.stream.Stream<T> stream(java.util.Spliterator<T>, boolean);
+    method public static java.util.stream.Stream<T> stream(java.util.function.Supplier<? extends java.util.Spliterator<T>>, int, boolean);
+  }
+
+}
+
 package java.util.zip {
 
   public class Adler32 implements java.util.zip.Checksum {
diff --git a/api/system-current.txt b/api/system-current.txt
index 6adca2b..0305c70 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -6977,9 +6977,10 @@
     method public void onServicesDiscovered(android.bluetooth.BluetoothGatt, int);
   }
 
-  public class BluetoothGattCharacteristic {
+  public class BluetoothGattCharacteristic implements android.os.Parcelable {
     ctor public BluetoothGattCharacteristic(java.util.UUID, int, int);
     method public boolean addDescriptor(android.bluetooth.BluetoothGattDescriptor);
+    method public int describeContents();
     method public android.bluetooth.BluetoothGattDescriptor getDescriptor(java.util.UUID);
     method public java.util.List<android.bluetooth.BluetoothGattDescriptor> getDescriptors();
     method public java.lang.Float getFloatValue(int, int);
@@ -6997,6 +6998,8 @@
     method public boolean setValue(int, int, int, int);
     method public boolean setValue(java.lang.String);
     method public void setWriteType(int);
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.bluetooth.BluetoothGattCharacteristic> CREATOR;
     field public static final int FORMAT_FLOAT = 52; // 0x34
     field public static final int FORMAT_SFLOAT = 50; // 0x32
     field public static final int FORMAT_SINT16 = 34; // 0x22
@@ -7027,13 +7030,16 @@
     field protected java.util.List<android.bluetooth.BluetoothGattDescriptor> mDescriptors;
   }
 
-  public class BluetoothGattDescriptor {
+  public class BluetoothGattDescriptor implements android.os.Parcelable {
     ctor public BluetoothGattDescriptor(java.util.UUID, int);
+    method public int describeContents();
     method public android.bluetooth.BluetoothGattCharacteristic getCharacteristic();
     method public int getPermissions();
     method public java.util.UUID getUuid();
     method public byte[] getValue();
     method public boolean setValue(byte[]);
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.bluetooth.BluetoothGattDescriptor> CREATOR;
     field public static final byte[] DISABLE_NOTIFICATION_VALUE;
     field public static final byte[] ENABLE_INDICATION_VALUE;
     field public static final byte[] ENABLE_NOTIFICATION_VALUE;
@@ -7076,16 +7082,19 @@
     method public void onServiceAdded(int, android.bluetooth.BluetoothGattService);
   }
 
-  public class BluetoothGattService {
+  public class BluetoothGattService implements android.os.Parcelable {
     ctor public BluetoothGattService(java.util.UUID, int);
     method public boolean addCharacteristic(android.bluetooth.BluetoothGattCharacteristic);
     method public boolean addService(android.bluetooth.BluetoothGattService);
+    method public int describeContents();
     method public android.bluetooth.BluetoothGattCharacteristic getCharacteristic(java.util.UUID);
     method public java.util.List<android.bluetooth.BluetoothGattCharacteristic> getCharacteristics();
     method public java.util.List<android.bluetooth.BluetoothGattService> getIncludedServices();
     method public int getInstanceId();
     method public int getType();
     method public java.util.UUID getUuid();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.bluetooth.BluetoothGattService> CREATOR;
     field public static final int SERVICE_TYPE_PRIMARY = 0; // 0x0
     field public static final int SERVICE_TYPE_SECONDARY = 1; // 0x1
     field protected java.util.List<android.bluetooth.BluetoothGattCharacteristic> mCharacteristics;
@@ -50959,6 +50968,7 @@
     method public float floatValue();
     method public static int hashCode(double);
     method public int intValue();
+    method public static boolean isFinite(double);
     method public static boolean isInfinite(double);
     method public boolean isInfinite();
     method public static boolean isNaN(double);
@@ -51040,6 +51050,7 @@
     method public float floatValue();
     method public static float intBitsToFloat(int);
     method public int intValue();
+    method public static boolean isFinite(float);
     method public static boolean isInfinite(float);
     method public boolean isInfinite();
     method public static boolean isNaN(float);
@@ -57620,6 +57631,7 @@
     method public E get(int);
     method public boolean removeIf(java.util.function.Predicate<? super E>);
     method public int size();
+    method public void sort(java.util.Comparator<? super E>);
     method public java.util.Spliterator<E> spliterator();
     method public void trimToSize();
   }
@@ -57721,6 +57733,10 @@
     method public static void parallelSort(T[], int, int);
     method public static void parallelSort(T[], java.util.Comparator<? super T>);
     method public static void parallelSort(T[], int, int, java.util.Comparator<? super T>);
+    method public static void setAll(T[], java.util.function.IntFunction<? extends T>);
+    method public static void setAll(int[], java.util.function.IntUnaryOperator);
+    method public static void setAll(long[], java.util.function.IntToLongFunction);
+    method public static void setAll(double[], java.util.function.IntToDoubleFunction);
     method public static void sort(int[]);
     method public static void sort(int[], int, int);
     method public static void sort(long[]);
@@ -57747,6 +57763,14 @@
     method public static java.util.Spliterator.OfLong spliterator(long[], int, int);
     method public static java.util.Spliterator.OfDouble spliterator(double[]);
     method public static java.util.Spliterator.OfDouble spliterator(double[], int, int);
+    method public static java.util.stream.Stream<T> stream(T[]);
+    method public static java.util.stream.Stream<T> stream(T[], int, int);
+    method public static java.util.stream.IntStream stream(int[]);
+    method public static java.util.stream.IntStream stream(int[], int, int);
+    method public static java.util.stream.LongStream stream(long[]);
+    method public static java.util.stream.LongStream stream(long[], int, int);
+    method public static java.util.stream.DoubleStream stream(double[]);
+    method public static java.util.stream.DoubleStream stream(double[], int, int);
     method public static java.lang.String toString(long[]);
     method public static java.lang.String toString(int[]);
     method public static java.lang.String toString(short[]);
@@ -57906,11 +57930,13 @@
     method public abstract int hashCode();
     method public abstract boolean isEmpty();
     method public abstract java.util.Iterator<E> iterator();
+    method public default java.util.stream.Stream<E> parallelStream();
     method public abstract boolean remove(java.lang.Object);
     method public abstract boolean removeAll(java.util.Collection<?>);
     method public default boolean removeIf(java.util.function.Predicate<? super E>);
     method public abstract boolean retainAll(java.util.Collection<?>);
     method public abstract int size();
+    method public default java.util.stream.Stream<E> stream();
     method public abstract java.lang.Object[] toArray();
     method public abstract T[] toArray(T[]);
   }
@@ -59110,6 +59136,34 @@
     method public java.util.Spliterator<T> trySplit();
   }
 
+  public final class SplittableRandom {
+    ctor public SplittableRandom(long);
+    ctor public SplittableRandom();
+    method public java.util.stream.DoubleStream doubles(long);
+    method public java.util.stream.DoubleStream doubles();
+    method public java.util.stream.DoubleStream doubles(long, double, double);
+    method public java.util.stream.DoubleStream doubles(double, double);
+    method public java.util.stream.IntStream ints(long);
+    method public java.util.stream.IntStream ints();
+    method public java.util.stream.IntStream ints(long, int, int);
+    method public java.util.stream.IntStream ints(int, int);
+    method public java.util.stream.LongStream longs(long);
+    method public java.util.stream.LongStream longs();
+    method public java.util.stream.LongStream longs(long, long, long);
+    method public java.util.stream.LongStream longs(long, long);
+    method public boolean nextBoolean();
+    method public double nextDouble();
+    method public double nextDouble(double);
+    method public double nextDouble(double, double);
+    method public int nextInt();
+    method public int nextInt(int);
+    method public int nextInt(int, int);
+    method public long nextLong();
+    method public long nextLong(long);
+    method public long nextLong(long, long);
+    method public java.util.SplittableRandom split();
+  }
+
   public class Stack extends java.util.Vector {
     ctor public Stack();
     method public boolean empty();
@@ -60293,6 +60347,18 @@
 
   public class ThreadLocalRandom extends java.util.Random {
     method public static java.util.concurrent.ThreadLocalRandom current();
+    method public java.util.stream.DoubleStream doubles(long);
+    method public java.util.stream.DoubleStream doubles();
+    method public java.util.stream.DoubleStream doubles(long, double, double);
+    method public java.util.stream.DoubleStream doubles(double, double);
+    method public java.util.stream.IntStream ints(long);
+    method public java.util.stream.IntStream ints();
+    method public java.util.stream.IntStream ints(long, int, int);
+    method public java.util.stream.IntStream ints(int, int);
+    method public java.util.stream.LongStream longs(long);
+    method public java.util.stream.LongStream longs();
+    method public java.util.stream.LongStream longs(long, long, long);
+    method public java.util.stream.LongStream longs(long, long);
     method public double nextDouble(double);
     method public double nextDouble(double, double);
     method public int nextInt(int, int);
@@ -61694,6 +61760,292 @@
 
 }
 
+package java.util.stream {
+
+  public abstract interface BaseStream implements java.lang.AutoCloseable {
+    method public abstract void close();
+    method public abstract boolean isParallel();
+    method public abstract java.util.Iterator<T> iterator();
+    method public abstract S onClose(java.lang.Runnable);
+    method public abstract S parallel();
+    method public abstract S sequential();
+    method public abstract java.util.Spliterator<T> spliterator();
+    method public abstract S unordered();
+  }
+
+  public abstract interface Collector {
+    method public abstract java.util.function.BiConsumer<A, T> accumulator();
+    method public abstract java.util.Set<java.util.stream.Collector.Characteristics> characteristics();
+    method public abstract java.util.function.BinaryOperator<A> combiner();
+    method public abstract java.util.function.Function<A, R> finisher();
+    method public static java.util.stream.Collector<T, R, R> of(java.util.function.Supplier<R>, java.util.function.BiConsumer<R, T>, java.util.function.BinaryOperator<R>, java.util.stream.Collector.Characteristics...);
+    method public static java.util.stream.Collector<T, A, R> of(java.util.function.Supplier<A>, java.util.function.BiConsumer<A, T>, java.util.function.BinaryOperator<A>, java.util.function.Function<A, R>, java.util.stream.Collector.Characteristics...);
+    method public abstract java.util.function.Supplier<A> supplier();
+  }
+
+  public static final class Collector.Characteristics extends java.lang.Enum {
+    method public static java.util.stream.Collector.Characteristics valueOf(java.lang.String);
+    method public static final java.util.stream.Collector.Characteristics[] values();
+    enum_constant public static final java.util.stream.Collector.Characteristics CONCURRENT;
+    enum_constant public static final java.util.stream.Collector.Characteristics IDENTITY_FINISH;
+    enum_constant public static final java.util.stream.Collector.Characteristics UNORDERED;
+  }
+
+  public final class Collectors {
+    method public static java.util.stream.Collector<T, ?, java.lang.Double> averagingDouble(java.util.function.ToDoubleFunction<? super T>);
+    method public static java.util.stream.Collector<T, ?, java.lang.Double> averagingInt(java.util.function.ToIntFunction<? super T>);
+    method public static java.util.stream.Collector<T, ?, java.lang.Double> averagingLong(java.util.function.ToLongFunction<? super T>);
+    method public static java.util.stream.Collector<T, A, RR> collectingAndThen(java.util.stream.Collector<T, A, R>, java.util.function.Function<R, RR>);
+    method public static java.util.stream.Collector<T, ?, java.lang.Long> counting();
+    method public static java.util.stream.Collector<T, ?, java.util.Map<K, java.util.List<T>>> groupingBy(java.util.function.Function<? super T, ? extends K>);
+    method public static java.util.stream.Collector<T, ?, java.util.Map<K, D>> groupingBy(java.util.function.Function<? super T, ? extends K>, java.util.stream.Collector<? super T, A, D>);
+    method public static java.util.stream.Collector<T, ?, M> groupingBy(java.util.function.Function<? super T, ? extends K>, java.util.function.Supplier<M>, java.util.stream.Collector<? super T, A, D>);
+    method public static java.util.stream.Collector<T, ?, java.util.concurrent.ConcurrentMap<K, java.util.List<T>>> groupingByConcurrent(java.util.function.Function<? super T, ? extends K>);
+    method public static java.util.stream.Collector<T, ?, java.util.concurrent.ConcurrentMap<K, D>> groupingByConcurrent(java.util.function.Function<? super T, ? extends K>, java.util.stream.Collector<? super T, A, D>);
+    method public static java.util.stream.Collector<T, ?, M> groupingByConcurrent(java.util.function.Function<? super T, ? extends K>, java.util.function.Supplier<M>, java.util.stream.Collector<? super T, A, D>);
+    method public static java.util.stream.Collector<java.lang.CharSequence, ?, java.lang.String> joining();
+    method public static java.util.stream.Collector<java.lang.CharSequence, ?, java.lang.String> joining(java.lang.CharSequence);
+    method public static java.util.stream.Collector<java.lang.CharSequence, ?, java.lang.String> joining(java.lang.CharSequence, java.lang.CharSequence, java.lang.CharSequence);
+    method public static java.util.stream.Collector<T, ?, R> mapping(java.util.function.Function<? super T, ? extends U>, java.util.stream.Collector<? super U, A, R>);
+    method public static java.util.stream.Collector<T, ?, java.util.Optional<T>> maxBy(java.util.Comparator<? super T>);
+    method public static java.util.stream.Collector<T, ?, java.util.Optional<T>> minBy(java.util.Comparator<? super T>);
+    method public static java.util.stream.Collector<T, ?, java.util.Map<java.lang.Boolean, java.util.List<T>>> partitioningBy(java.util.function.Predicate<? super T>);
+    method public static java.util.stream.Collector<T, ?, java.util.Map<java.lang.Boolean, D>> partitioningBy(java.util.function.Predicate<? super T>, java.util.stream.Collector<? super T, A, D>);
+    method public static java.util.stream.Collector<T, ?, T> reducing(T, java.util.function.BinaryOperator<T>);
+    method public static java.util.stream.Collector<T, ?, java.util.Optional<T>> reducing(java.util.function.BinaryOperator<T>);
+    method public static java.util.stream.Collector<T, ?, U> reducing(U, java.util.function.Function<? super T, ? extends U>, java.util.function.BinaryOperator<U>);
+    method public static java.util.stream.Collector<T, ?, java.util.DoubleSummaryStatistics> summarizingDouble(java.util.function.ToDoubleFunction<? super T>);
+    method public static java.util.stream.Collector<T, ?, java.util.IntSummaryStatistics> summarizingInt(java.util.function.ToIntFunction<? super T>);
+    method public static java.util.stream.Collector<T, ?, java.util.LongSummaryStatistics> summarizingLong(java.util.function.ToLongFunction<? super T>);
+    method public static java.util.stream.Collector<T, ?, java.lang.Double> summingDouble(java.util.function.ToDoubleFunction<? super T>);
+    method public static java.util.stream.Collector<T, ?, java.lang.Integer> summingInt(java.util.function.ToIntFunction<? super T>);
+    method public static java.util.stream.Collector<T, ?, java.lang.Long> summingLong(java.util.function.ToLongFunction<? super T>);
+    method public static java.util.stream.Collector<T, ?, C> toCollection(java.util.function.Supplier<C>);
+    method public static java.util.stream.Collector<T, ?, java.util.concurrent.ConcurrentMap<K, U>> toConcurrentMap(java.util.function.Function<? super T, ? extends K>, java.util.function.Function<? super T, ? extends U>);
+    method public static java.util.stream.Collector<T, ?, java.util.concurrent.ConcurrentMap<K, U>> toConcurrentMap(java.util.function.Function<? super T, ? extends K>, java.util.function.Function<? super T, ? extends U>, java.util.function.BinaryOperator<U>);
+    method public static java.util.stream.Collector<T, ?, M> toConcurrentMap(java.util.function.Function<? super T, ? extends K>, java.util.function.Function<? super T, ? extends U>, java.util.function.BinaryOperator<U>, java.util.function.Supplier<M>);
+    method public static java.util.stream.Collector<T, ?, java.util.List<T>> toList();
+    method public static java.util.stream.Collector<T, ?, java.util.Map<K, U>> toMap(java.util.function.Function<? super T, ? extends K>, java.util.function.Function<? super T, ? extends U>);
+    method public static java.util.stream.Collector<T, ?, java.util.Map<K, U>> toMap(java.util.function.Function<? super T, ? extends K>, java.util.function.Function<? super T, ? extends U>, java.util.function.BinaryOperator<U>);
+    method public static java.util.stream.Collector<T, ?, M> toMap(java.util.function.Function<? super T, ? extends K>, java.util.function.Function<? super T, ? extends U>, java.util.function.BinaryOperator<U>, java.util.function.Supplier<M>);
+    method public static java.util.stream.Collector<T, ?, java.util.Set<T>> toSet();
+  }
+
+  public abstract interface DoubleStream implements java.util.stream.BaseStream {
+    method public abstract boolean allMatch(java.util.function.DoublePredicate);
+    method public abstract boolean anyMatch(java.util.function.DoublePredicate);
+    method public abstract java.util.OptionalDouble average();
+    method public abstract java.util.stream.Stream<java.lang.Double> boxed();
+    method public static java.util.stream.DoubleStream.Builder builder();
+    method public abstract R collect(java.util.function.Supplier<R>, java.util.function.ObjDoubleConsumer<R>, java.util.function.BiConsumer<R, R>);
+    method public static java.util.stream.DoubleStream concat(java.util.stream.DoubleStream, java.util.stream.DoubleStream);
+    method public abstract long count();
+    method public abstract java.util.stream.DoubleStream distinct();
+    method public static java.util.stream.DoubleStream empty();
+    method public abstract java.util.stream.DoubleStream filter(java.util.function.DoublePredicate);
+    method public abstract java.util.OptionalDouble findAny();
+    method public abstract java.util.OptionalDouble findFirst();
+    method public abstract java.util.stream.DoubleStream flatMap(java.util.function.DoubleFunction<? extends java.util.stream.DoubleStream>);
+    method public abstract void forEach(java.util.function.DoubleConsumer);
+    method public abstract void forEachOrdered(java.util.function.DoubleConsumer);
+    method public static java.util.stream.DoubleStream generate(java.util.function.DoubleSupplier);
+    method public static java.util.stream.DoubleStream iterate(double, java.util.function.DoubleUnaryOperator);
+    method public abstract java.util.PrimitiveIterator.OfDouble iterator();
+    method public abstract java.util.stream.DoubleStream limit(long);
+    method public abstract java.util.stream.DoubleStream map(java.util.function.DoubleUnaryOperator);
+    method public abstract java.util.stream.IntStream mapToInt(java.util.function.DoubleToIntFunction);
+    method public abstract java.util.stream.LongStream mapToLong(java.util.function.DoubleToLongFunction);
+    method public abstract java.util.stream.Stream<U> mapToObj(java.util.function.DoubleFunction<? extends U>);
+    method public abstract java.util.OptionalDouble max();
+    method public abstract java.util.OptionalDouble min();
+    method public abstract boolean noneMatch(java.util.function.DoublePredicate);
+    method public static java.util.stream.DoubleStream of(double);
+    method public static java.util.stream.DoubleStream of(double...);
+    method public abstract java.util.stream.DoubleStream parallel();
+    method public abstract java.util.stream.DoubleStream peek(java.util.function.DoubleConsumer);
+    method public abstract double reduce(double, java.util.function.DoubleBinaryOperator);
+    method public abstract java.util.OptionalDouble reduce(java.util.function.DoubleBinaryOperator);
+    method public abstract java.util.stream.DoubleStream sequential();
+    method public abstract java.util.stream.DoubleStream skip(long);
+    method public abstract java.util.stream.DoubleStream sorted();
+    method public abstract java.util.Spliterator.OfDouble spliterator();
+    method public abstract double sum();
+    method public abstract java.util.DoubleSummaryStatistics summaryStatistics();
+    method public abstract double[] toArray();
+  }
+
+  public static abstract interface DoubleStream.Builder implements java.util.function.DoubleConsumer {
+    method public abstract void accept(double);
+    method public default java.util.stream.DoubleStream.Builder add(double);
+    method public abstract java.util.stream.DoubleStream build();
+  }
+
+  public abstract interface IntStream implements java.util.stream.BaseStream {
+    method public abstract boolean allMatch(java.util.function.IntPredicate);
+    method public abstract boolean anyMatch(java.util.function.IntPredicate);
+    method public abstract java.util.stream.DoubleStream asDoubleStream();
+    method public abstract java.util.stream.LongStream asLongStream();
+    method public abstract java.util.OptionalDouble average();
+    method public abstract java.util.stream.Stream<java.lang.Integer> boxed();
+    method public static java.util.stream.IntStream.Builder builder();
+    method public abstract R collect(java.util.function.Supplier<R>, java.util.function.ObjIntConsumer<R>, java.util.function.BiConsumer<R, R>);
+    method public static java.util.stream.IntStream concat(java.util.stream.IntStream, java.util.stream.IntStream);
+    method public abstract long count();
+    method public abstract java.util.stream.IntStream distinct();
+    method public static java.util.stream.IntStream empty();
+    method public abstract java.util.stream.IntStream filter(java.util.function.IntPredicate);
+    method public abstract java.util.OptionalInt findAny();
+    method public abstract java.util.OptionalInt findFirst();
+    method public abstract java.util.stream.IntStream flatMap(java.util.function.IntFunction<? extends java.util.stream.IntStream>);
+    method public abstract void forEach(java.util.function.IntConsumer);
+    method public abstract void forEachOrdered(java.util.function.IntConsumer);
+    method public static java.util.stream.IntStream generate(java.util.function.IntSupplier);
+    method public static java.util.stream.IntStream iterate(int, java.util.function.IntUnaryOperator);
+    method public abstract java.util.PrimitiveIterator.OfInt iterator();
+    method public abstract java.util.stream.IntStream limit(long);
+    method public abstract java.util.stream.IntStream map(java.util.function.IntUnaryOperator);
+    method public abstract java.util.stream.DoubleStream mapToDouble(java.util.function.IntToDoubleFunction);
+    method public abstract java.util.stream.LongStream mapToLong(java.util.function.IntToLongFunction);
+    method public abstract java.util.stream.Stream<U> mapToObj(java.util.function.IntFunction<? extends U>);
+    method public abstract java.util.OptionalInt max();
+    method public abstract java.util.OptionalInt min();
+    method public abstract boolean noneMatch(java.util.function.IntPredicate);
+    method public static java.util.stream.IntStream of(int);
+    method public static java.util.stream.IntStream of(int...);
+    method public abstract java.util.stream.IntStream parallel();
+    method public abstract java.util.stream.IntStream peek(java.util.function.IntConsumer);
+    method public static java.util.stream.IntStream range(int, int);
+    method public static java.util.stream.IntStream rangeClosed(int, int);
+    method public abstract int reduce(int, java.util.function.IntBinaryOperator);
+    method public abstract java.util.OptionalInt reduce(java.util.function.IntBinaryOperator);
+    method public abstract java.util.stream.IntStream sequential();
+    method public abstract java.util.stream.IntStream skip(long);
+    method public abstract java.util.stream.IntStream sorted();
+    method public abstract java.util.Spliterator.OfInt spliterator();
+    method public abstract int sum();
+    method public abstract java.util.IntSummaryStatistics summaryStatistics();
+    method public abstract int[] toArray();
+  }
+
+  public static abstract interface IntStream.Builder implements java.util.function.IntConsumer {
+    method public abstract void accept(int);
+    method public default java.util.stream.IntStream.Builder add(int);
+    method public abstract java.util.stream.IntStream build();
+  }
+
+  public abstract interface LongStream implements java.util.stream.BaseStream {
+    method public abstract boolean allMatch(java.util.function.LongPredicate);
+    method public abstract boolean anyMatch(java.util.function.LongPredicate);
+    method public abstract java.util.stream.DoubleStream asDoubleStream();
+    method public abstract java.util.OptionalDouble average();
+    method public abstract java.util.stream.Stream<java.lang.Long> boxed();
+    method public static java.util.stream.LongStream.Builder builder();
+    method public abstract R collect(java.util.function.Supplier<R>, java.util.function.ObjLongConsumer<R>, java.util.function.BiConsumer<R, R>);
+    method public static java.util.stream.LongStream concat(java.util.stream.LongStream, java.util.stream.LongStream);
+    method public abstract long count();
+    method public abstract java.util.stream.LongStream distinct();
+    method public static java.util.stream.LongStream empty();
+    method public abstract java.util.stream.LongStream filter(java.util.function.LongPredicate);
+    method public abstract java.util.OptionalLong findAny();
+    method public abstract java.util.OptionalLong findFirst();
+    method public abstract java.util.stream.LongStream flatMap(java.util.function.LongFunction<? extends java.util.stream.LongStream>);
+    method public abstract void forEach(java.util.function.LongConsumer);
+    method public abstract void forEachOrdered(java.util.function.LongConsumer);
+    method public static java.util.stream.LongStream generate(java.util.function.LongSupplier);
+    method public static java.util.stream.LongStream iterate(long, java.util.function.LongUnaryOperator);
+    method public abstract java.util.PrimitiveIterator.OfLong iterator();
+    method public abstract java.util.stream.LongStream limit(long);
+    method public abstract java.util.stream.LongStream map(java.util.function.LongUnaryOperator);
+    method public abstract java.util.stream.DoubleStream mapToDouble(java.util.function.LongToDoubleFunction);
+    method public abstract java.util.stream.IntStream mapToInt(java.util.function.LongToIntFunction);
+    method public abstract java.util.stream.Stream<U> mapToObj(java.util.function.LongFunction<? extends U>);
+    method public abstract java.util.OptionalLong max();
+    method public abstract java.util.OptionalLong min();
+    method public abstract boolean noneMatch(java.util.function.LongPredicate);
+    method public static java.util.stream.LongStream of(long);
+    method public static java.util.stream.LongStream of(long...);
+    method public abstract java.util.stream.LongStream parallel();
+    method public abstract java.util.stream.LongStream peek(java.util.function.LongConsumer);
+    method public static java.util.stream.LongStream range(long, long);
+    method public static java.util.stream.LongStream rangeClosed(long, long);
+    method public abstract long reduce(long, java.util.function.LongBinaryOperator);
+    method public abstract java.util.OptionalLong reduce(java.util.function.LongBinaryOperator);
+    method public abstract java.util.stream.LongStream sequential();
+    method public abstract java.util.stream.LongStream skip(long);
+    method public abstract java.util.stream.LongStream sorted();
+    method public abstract java.util.Spliterator.OfLong spliterator();
+    method public abstract long sum();
+    method public abstract java.util.LongSummaryStatistics summaryStatistics();
+    method public abstract long[] toArray();
+  }
+
+  public static abstract interface LongStream.Builder implements java.util.function.LongConsumer {
+    method public abstract void accept(long);
+    method public default java.util.stream.LongStream.Builder add(long);
+    method public abstract java.util.stream.LongStream build();
+  }
+
+  public abstract interface Stream implements java.util.stream.BaseStream {
+    method public abstract boolean allMatch(java.util.function.Predicate<? super T>);
+    method public abstract boolean anyMatch(java.util.function.Predicate<? super T>);
+    method public static java.util.stream.Stream.Builder<T> builder();
+    method public abstract R collect(java.util.function.Supplier<R>, java.util.function.BiConsumer<R, ? super T>, java.util.function.BiConsumer<R, R>);
+    method public abstract R collect(java.util.stream.Collector<? super T, A, R>);
+    method public static java.util.stream.Stream<T> concat(java.util.stream.Stream<? extends T>, java.util.stream.Stream<? extends T>);
+    method public abstract long count();
+    method public abstract java.util.stream.Stream<T> distinct();
+    method public static java.util.stream.Stream<T> empty();
+    method public abstract java.util.stream.Stream<T> filter(java.util.function.Predicate<? super T>);
+    method public abstract java.util.Optional<T> findAny();
+    method public abstract java.util.Optional<T> findFirst();
+    method public abstract java.util.stream.Stream<R> flatMap(java.util.function.Function<? super T, ? extends java.util.stream.Stream<? extends R>>);
+    method public abstract java.util.stream.DoubleStream flatMapToDouble(java.util.function.Function<? super T, ? extends java.util.stream.DoubleStream>);
+    method public abstract java.util.stream.IntStream flatMapToInt(java.util.function.Function<? super T, ? extends java.util.stream.IntStream>);
+    method public abstract java.util.stream.LongStream flatMapToLong(java.util.function.Function<? super T, ? extends java.util.stream.LongStream>);
+    method public abstract void forEach(java.util.function.Consumer<? super T>);
+    method public abstract void forEachOrdered(java.util.function.Consumer<? super T>);
+    method public static java.util.stream.Stream<T> generate(java.util.function.Supplier<T>);
+    method public static java.util.stream.Stream<T> iterate(T, java.util.function.UnaryOperator<T>);
+    method public abstract java.util.stream.Stream<T> limit(long);
+    method public abstract java.util.stream.Stream<R> map(java.util.function.Function<? super T, ? extends R>);
+    method public abstract java.util.stream.DoubleStream mapToDouble(java.util.function.ToDoubleFunction<? super T>);
+    method public abstract java.util.stream.IntStream mapToInt(java.util.function.ToIntFunction<? super T>);
+    method public abstract java.util.stream.LongStream mapToLong(java.util.function.ToLongFunction<? super T>);
+    method public abstract java.util.Optional<T> max(java.util.Comparator<? super T>);
+    method public abstract java.util.Optional<T> min(java.util.Comparator<? super T>);
+    method public abstract boolean noneMatch(java.util.function.Predicate<? super T>);
+    method public static java.util.stream.Stream<T> of(T);
+    method public static java.util.stream.Stream<T> of(T...);
+    method public abstract java.util.stream.Stream<T> peek(java.util.function.Consumer<? super T>);
+    method public abstract T reduce(T, java.util.function.BinaryOperator<T>);
+    method public abstract java.util.Optional<T> reduce(java.util.function.BinaryOperator<T>);
+    method public abstract U reduce(U, java.util.function.BiFunction<U, ? super T, U>, java.util.function.BinaryOperator<U>);
+    method public abstract java.util.stream.Stream<T> skip(long);
+    method public abstract java.util.stream.Stream<T> sorted();
+    method public abstract java.util.stream.Stream<T> sorted(java.util.Comparator<? super T>);
+    method public abstract java.lang.Object[] toArray();
+    method public abstract A[] toArray(java.util.function.IntFunction<A[]>);
+  }
+
+  public static abstract interface Stream.Builder implements java.util.function.Consumer {
+    method public abstract void accept(T);
+    method public default java.util.stream.Stream.Builder<T> add(T);
+    method public abstract java.util.stream.Stream<T> build();
+  }
+
+  public final class StreamSupport {
+    method public static java.util.stream.DoubleStream doubleStream(java.util.Spliterator.OfDouble, boolean);
+    method public static java.util.stream.DoubleStream doubleStream(java.util.function.Supplier<? extends java.util.Spliterator.OfDouble>, int, boolean);
+    method public static java.util.stream.IntStream intStream(java.util.Spliterator.OfInt, boolean);
+    method public static java.util.stream.IntStream intStream(java.util.function.Supplier<? extends java.util.Spliterator.OfInt>, int, boolean);
+    method public static java.util.stream.LongStream longStream(java.util.Spliterator.OfLong, boolean);
+    method public static java.util.stream.LongStream longStream(java.util.function.Supplier<? extends java.util.Spliterator.OfLong>, int, boolean);
+    method public static java.util.stream.Stream<T> stream(java.util.Spliterator<T>, boolean);
+    method public static java.util.stream.Stream<T> stream(java.util.function.Supplier<? extends java.util.Spliterator<T>>, int, boolean);
+  }
+
+}
+
 package java.util.zip {
 
   public class Adler32 implements java.util.zip.Checksum {
diff --git a/cmds/app_process/app_main.cpp b/cmds/app_process/app_main.cpp
index 8bcbf51..7590325 100644
--- a/cmds/app_process/app_main.cpp
+++ b/cmds/app_process/app_main.cpp
@@ -305,7 +305,7 @@
     }
 
     if (zygote) {
-        PreloadPublicNativeLibraries();
+        InitializeNativeLoader();
         runtime.start("com.android.internal.os.ZygoteInit", args, zygote);
     } else if (className) {
         runtime.start("com.android.internal.os.RuntimeInit", args, zygote);
diff --git a/core/java/android/bluetooth/BluetoothGatt.java b/core/java/android/bluetooth/BluetoothGatt.java
index ea2dca0..ef05665 100644
--- a/core/java/android/bluetooth/BluetoothGatt.java
+++ b/core/java/android/bluetooth/BluetoothGatt.java
@@ -197,109 +197,43 @@
             }
 
             /**
-             * A new GATT service has been discovered.
-             * The service is added to the internal list and the search
-             * continues.
-             * @hide
-             */
-            public void onGetService(String address, int srvcType,
-                                     int srvcInstId, ParcelUuid srvcUuid) {
-                if (VDBG) Log.d(TAG, "onGetService() - Device=" + address + " UUID=" + srvcUuid);
-                if (!address.equals(mDevice.getAddress())) {
-                    return;
-                }
-                mServices.add(new BluetoothGattService(mDevice, srvcUuid.getUuid(),
-                                                       srvcInstId, srvcType));
-            }
-
-            /**
-             * An included service has been found durig GATT discovery.
-             * The included service is added to the respective parent.
-             * @hide
-             */
-            public void onGetIncludedService(String address, int srvcType,
-                                             int srvcInstId, ParcelUuid srvcUuid,
-                                             int inclSrvcType, int inclSrvcInstId,
-                                             ParcelUuid inclSrvcUuid) {
-                if (VDBG) Log.d(TAG, "onGetIncludedService() - Device=" + address
-                    + " UUID=" + srvcUuid + " Included=" + inclSrvcUuid);
-
-                if (!address.equals(mDevice.getAddress())) {
-                    return;
-                }
-                BluetoothGattService service = getService(mDevice,
-                        srvcUuid.getUuid(), srvcInstId, srvcType);
-                BluetoothGattService includedService = getService(mDevice,
-                        inclSrvcUuid.getUuid(), inclSrvcInstId, inclSrvcType);
-
-                if (service != null && includedService != null) {
-                    service.addIncludedService(includedService);
-                }
-            }
-
-            /**
-             * A new GATT characteristic has been discovered.
-             * Add the new characteristic to the relevant service and continue
-             * the remote device inspection.
-             * @hide
-             */
-            public void onGetCharacteristic(String address, int srvcType,
-                             int srvcInstId, ParcelUuid srvcUuid,
-                             int charInstId, ParcelUuid charUuid,
-                             int charProps) {
-                if (VDBG) Log.d(TAG, "onGetCharacteristic() - Device=" + address + " UUID=" +
-                               charUuid);
-
-                if (!address.equals(mDevice.getAddress())) {
-                    return;
-                }
-                BluetoothGattService service = getService(mDevice, srvcUuid.getUuid(),
-                                                          srvcInstId, srvcType);
-                if (service != null) {
-                    service.addCharacteristic(new BluetoothGattCharacteristic(
-                           service, charUuid.getUuid(), charInstId, charProps, 0));
-                }
-            }
-
-            /**
-             * A new GATT descriptor has been discovered.
-             * Finally, add the descriptor to the related characteristic.
-             * This should conclude the remote device update.
-             * @hide
-             */
-            public void onGetDescriptor(String address, int srvcType,
-                             int srvcInstId, ParcelUuid srvcUuid,
-                             int charInstId, ParcelUuid charUuid,
-                             int descrInstId, ParcelUuid descUuid) {
-                if (VDBG) Log.d(TAG, "onGetDescriptor() - Device=" + address + " UUID=" + descUuid);
-
-                if (!address.equals(mDevice.getAddress())) {
-                    return;
-                }
-                BluetoothGattService service = getService(mDevice, srvcUuid.getUuid(),
-                                                          srvcInstId, srvcType);
-                if (service == null) return;
-
-                BluetoothGattCharacteristic characteristic = service.getCharacteristic(
-                    charUuid.getUuid(), charInstId);
-                if (characteristic == null) return;
-
-                characteristic.addDescriptor(new BluetoothGattDescriptor(
-                    characteristic, descUuid.getUuid(), descrInstId, 0));
-            }
-
-            /**
              * Remote search has been completed.
              * The internal object structure should now reflect the state
              * of the remote device database. Let the application know that
              * we are done at this point.
              * @hide
              */
-            public void onSearchComplete(String address, int status) {
+            public void onSearchComplete(String address, List<BluetoothGattService> services,
+                                         int status) {
                 if (DBG) Log.d(TAG, "onSearchComplete() = Device=" + address + " Status=" + status);
                 if (!address.equals(mDevice.getAddress())) {
                     return;
                 }
+
+                for (BluetoothGattService s : services) {
+                    //services we receive don't have device set properly.
+                    s.setDevice(mDevice);
+                }
+
+                mServices.addAll(services);
+
+                // Fix references to included services, as they doesn't point to right objects.
+                for (BluetoothGattService fixedService : mServices) {
+                    ArrayList<BluetoothGattService> includedServices =
+                        new ArrayList(fixedService.getIncludedServices());
+                    fixedService.getIncludedServices().clear();
+
+                    for(BluetoothGattService brokenRef : includedServices) {
+                        BluetoothGattService includedService = getService(mDevice,
+                            brokenRef.getUuid(), brokenRef.getInstanceId(), brokenRef.getType());
+                        if (includedService != null) {
+                            fixedService.addIncludedService(includedService);
+                        } else {
+                            Log.e(TAG, "Broken GATT database: can't find included service.");
+                        }
+                    }
+                }
+
                 try {
                     mCallback.onServicesDiscovered(BluetoothGatt.this, status);
                 } catch (Exception ex) {
diff --git a/core/java/android/bluetooth/BluetoothGattCallbackWrapper.java b/core/java/android/bluetooth/BluetoothGattCallbackWrapper.java
index 01778b3..64ead54 100644
--- a/core/java/android/bluetooth/BluetoothGattCallbackWrapper.java
+++ b/core/java/android/bluetooth/BluetoothGattCallbackWrapper.java
@@ -18,6 +18,7 @@
 
 import android.bluetooth.le.AdvertiseSettings;
 import android.bluetooth.le.ScanResult;
+import android.bluetooth.BluetoothGattService;
 import android.os.ParcelUuid;
 import android.os.RemoteException;
 
@@ -48,30 +49,8 @@
     }
 
     @Override
-    public void onGetService(String address, int srvcType, int srvcInstId, ParcelUuid srvcUuid)
-            throws RemoteException {
-    }
-
-    @Override
-    public void onGetIncludedService(String address, int srvcType, int srvcInstId,
-            ParcelUuid srvcUuid, int inclSrvcType, int inclSrvcInstId, ParcelUuid inclSrvcUuid)
-            throws RemoteException {
-    }
-
-    @Override
-    public void onGetCharacteristic(String address, int srvcType, int srvcInstId,
-            ParcelUuid srvcUuid, int charInstId, ParcelUuid charUuid, int charProps)
-            throws RemoteException {
-    }
-
-    @Override
-    public void onGetDescriptor(String address, int srvcType, int srvcInstId, ParcelUuid srvcUuid,
-            int charInstId, ParcelUuid charUuid, int descrInstId, ParcelUuid descrUuid)
-            throws RemoteException {
-    }
-
-    @Override
-    public void onSearchComplete(String address, int status) throws RemoteException {
+    public void onSearchComplete(String address, List<BluetoothGattService> services,
+            int status) throws RemoteException {
     }
 
     @Override
diff --git a/core/java/android/bluetooth/BluetoothGattCharacteristic.aidl b/core/java/android/bluetooth/BluetoothGattCharacteristic.aidl
new file mode 100644
index 0000000..bbb8623
--- /dev/null
+++ b/core/java/android/bluetooth/BluetoothGattCharacteristic.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2016 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 android.bluetooth;
+
+parcelable BluetoothGattCharacteristic;
diff --git a/core/java/android/bluetooth/BluetoothGattCharacteristic.java b/core/java/android/bluetooth/BluetoothGattCharacteristic.java
index 7cdcc2c..7d698b3 100644
--- a/core/java/android/bluetooth/BluetoothGattCharacteristic.java
+++ b/core/java/android/bluetooth/BluetoothGattCharacteristic.java
@@ -15,6 +15,9 @@
  */
 package android.bluetooth;
 
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.os.ParcelUuid;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.UUID;
@@ -26,7 +29,7 @@
  * {@link BluetoothGattService}. The characteristic contains a value as well as
  * additional information and optional GATT descriptors, {@link BluetoothGattDescriptor}.
  */
-public class BluetoothGattCharacteristic {
+public class BluetoothGattCharacteristic implements Parcelable {
 
     /**
      * Characteristic proprty: Characteristic is broadcastable.
@@ -242,6 +245,15 @@
         initCharacteristic(service, uuid, instanceId, properties, permissions);
     }
 
+    /**
+     * Create a new BluetoothGattCharacteristic
+     * @hide
+     */
+    public BluetoothGattCharacteristic(UUID uuid, int instanceId,
+                                       int properties, int permissions) {
+        initCharacteristic(null, uuid, instanceId, properties, permissions);
+    }
+
     private void initCharacteristic(BluetoothGattService service,
                                     UUID uuid, int instanceId,
                                     int properties, int permissions) {
@@ -261,6 +273,50 @@
     }
 
     /**
+     * @hide
+     */
+    public int describeContents() {
+        return 0;
+    }
+
+    public void writeToParcel(Parcel out, int flags) {
+        out.writeParcelable(new ParcelUuid(mUuid), 0);
+        out.writeInt(mInstance);
+        out.writeInt(mProperties);
+        out.writeInt(mPermissions);
+        out.writeTypedList(mDescriptors);
+    }
+
+    public static final Parcelable.Creator<BluetoothGattCharacteristic> CREATOR
+            = new Parcelable.Creator<BluetoothGattCharacteristic>() {
+        public BluetoothGattCharacteristic createFromParcel(Parcel in) {
+            return new BluetoothGattCharacteristic(in);
+        }
+
+        public BluetoothGattCharacteristic[] newArray(int size) {
+            return new BluetoothGattCharacteristic[size];
+        }
+    };
+
+    private BluetoothGattCharacteristic(Parcel in) {
+        mUuid = ((ParcelUuid)in.readParcelable(null)).getUuid();
+        mInstance = in.readInt();
+        mProperties = in.readInt();
+        mPermissions = in.readInt();
+
+        mDescriptors = new ArrayList<BluetoothGattDescriptor>();
+
+        ArrayList<BluetoothGattDescriptor> descs =
+                in.createTypedArrayList(BluetoothGattDescriptor.CREATOR);
+        if (descs != null) {
+            for (BluetoothGattDescriptor desc: descs) {
+                desc.setCharacteristic(this);
+                mDescriptors.add(desc);
+            }
+        }
+    }
+
+    /**
      * Returns the deisred key size.
      * @hide
      */
diff --git a/core/java/android/bluetooth/BluetoothGattDescriptor.aidl b/core/java/android/bluetooth/BluetoothGattDescriptor.aidl
new file mode 100644
index 0000000..4393273
--- /dev/null
+++ b/core/java/android/bluetooth/BluetoothGattDescriptor.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2016 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 android.bluetooth;
+
+parcelable BluetoothGattDescriptor;
diff --git a/core/java/android/bluetooth/BluetoothGattDescriptor.java b/core/java/android/bluetooth/BluetoothGattDescriptor.java
index 5f525dc..28317c4 100644
--- a/core/java/android/bluetooth/BluetoothGattDescriptor.java
+++ b/core/java/android/bluetooth/BluetoothGattDescriptor.java
@@ -16,6 +16,9 @@
 
 package android.bluetooth;
 
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.os.ParcelUuid;
 import java.util.UUID;
 
 /**
@@ -25,7 +28,7 @@
  * characteristic, {@link BluetoothGattCharacteristic}. They can be used to describe
  * the characteristic's features or to control certain behaviours of the characteristic.
  */
-public class BluetoothGattDescriptor {
+public class BluetoothGattDescriptor implements Parcelable {
 
     /**
      * Value used to enable notification for a client configuration descriptor
@@ -138,6 +141,13 @@
         initDescriptor(characteristic, uuid, instance, permissions);
     }
 
+    /**
+     * @hide
+     */
+    public BluetoothGattDescriptor(UUID uuid, int instance, int permissions) {
+        initDescriptor(null, uuid, instance, permissions);
+    }
+
     private void initDescriptor(BluetoothGattCharacteristic characteristic, UUID uuid,
                                 int instance, int permissions) {
         mCharacteristic = characteristic;
@@ -147,6 +157,36 @@
     }
 
     /**
+     * @hide
+     */
+    public int describeContents() {
+        return 0;
+    }
+
+    public void writeToParcel(Parcel out, int flags) {
+        out.writeParcelable(new ParcelUuid(mUuid), 0);
+        out.writeInt(mInstance);
+        out.writeInt(mPermissions);
+    }
+
+    public static final Parcelable.Creator<BluetoothGattDescriptor> CREATOR
+            = new Parcelable.Creator<BluetoothGattDescriptor>() {
+        public BluetoothGattDescriptor createFromParcel(Parcel in) {
+            return new BluetoothGattDescriptor(in);
+        }
+
+        public BluetoothGattDescriptor[] newArray(int size) {
+            return new BluetoothGattDescriptor[size];
+        }
+    };
+
+    private BluetoothGattDescriptor(Parcel in) {
+        mUuid = ((ParcelUuid)in.readParcelable(null)).getUuid();
+        mInstance = in.readInt();
+        mPermissions = in.readInt();
+    }
+
+    /**
      * Returns the characteristic this descriptor belongs to.
      * @return The characteristic.
      */
diff --git a/core/java/android/bluetooth/BluetoothGattIncludedService.aidl b/core/java/android/bluetooth/BluetoothGattIncludedService.aidl
new file mode 100644
index 0000000..1ef427e
--- /dev/null
+++ b/core/java/android/bluetooth/BluetoothGattIncludedService.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2016 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 android.bluetooth;
+
+parcelable BluetoothGattIncludedService;
diff --git a/core/java/android/bluetooth/BluetoothGattIncludedService.java b/core/java/android/bluetooth/BluetoothGattIncludedService.java
new file mode 100644
index 0000000..155dc57
--- /dev/null
+++ b/core/java/android/bluetooth/BluetoothGattIncludedService.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2016 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 android.bluetooth;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.os.ParcelUuid;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
+
+/**
+ * Represents a Bluetooth GATT Included Service
+ * @hide
+ */
+public class BluetoothGattIncludedService implements Parcelable {
+
+    /**
+     * The UUID of this service.
+     */
+    protected UUID mUuid;
+
+    /**
+     * Instance ID for this service.
+     */
+    protected int mInstanceId;
+
+    /**
+     * Service type (Primary/Secondary).
+     */
+    protected int mServiceType;
+
+    /**
+     * Create a new BluetoothGattIncludedService
+     */
+    public BluetoothGattIncludedService(UUID uuid, int instanceId, int serviceType) {
+        mUuid = uuid;
+        mInstanceId = instanceId;
+        mServiceType = serviceType;
+    }
+
+    public int describeContents() {
+        return 0;
+    }
+
+    public void writeToParcel(Parcel out, int flags) {
+        out.writeParcelable(new ParcelUuid(mUuid), 0);
+        out.writeInt(mInstanceId);
+        out.writeInt(mServiceType);
+     }
+
+    public static final Parcelable.Creator<BluetoothGattIncludedService> CREATOR
+            = new Parcelable.Creator<BluetoothGattIncludedService>() {
+        public BluetoothGattIncludedService createFromParcel(Parcel in) {
+            return new BluetoothGattIncludedService(in);
+        }
+
+        public BluetoothGattIncludedService[] newArray(int size) {
+            return new BluetoothGattIncludedService[size];
+        }
+    };
+
+    private BluetoothGattIncludedService(Parcel in) {
+        mUuid = ((ParcelUuid)in.readParcelable(null)).getUuid();
+        mInstanceId = in.readInt();
+        mServiceType = in.readInt();
+    }
+
+    /**
+     * Returns the UUID of this service
+     *
+     * @return UUID of this service
+     */
+    public UUID getUuid() {
+        return mUuid;
+    }
+
+    /**
+     * Returns the instance ID for this service
+     *
+     * <p>If a remote device offers multiple services with the same UUID
+     * (ex. multiple battery services for different batteries), the instance
+     * ID is used to distuinguish services.
+     *
+     * @return Instance ID of this service
+     */
+    public int getInstanceId() {
+        return mInstanceId;
+    }
+
+    /**
+     * Get the type of this service (primary/secondary)
+     */
+    public int getType() {
+        return mServiceType;
+    }
+}
diff --git a/core/java/android/bluetooth/BluetoothGattService.aidl b/core/java/android/bluetooth/BluetoothGattService.aidl
new file mode 100644
index 0000000..84314d2
--- /dev/null
+++ b/core/java/android/bluetooth/BluetoothGattService.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2016 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 android.bluetooth;
+
+parcelable BluetoothGattService;
diff --git a/core/java/android/bluetooth/BluetoothGattService.java b/core/java/android/bluetooth/BluetoothGattService.java
index 52bc0f7..a4e1dc0 100644
--- a/core/java/android/bluetooth/BluetoothGattService.java
+++ b/core/java/android/bluetooth/BluetoothGattService.java
@@ -15,6 +15,9 @@
  */
 package android.bluetooth;
 
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.os.ParcelUuid;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.UUID;
@@ -25,7 +28,7 @@
  * <p> Gatt Service contains a collection of {@link BluetoothGattCharacteristic},
  * as well as referenced services.
  */
-public class BluetoothGattService {
+public class BluetoothGattService implements Parcelable {
 
     /**
      * Primary service
@@ -117,6 +120,81 @@
     }
 
     /**
+     * Create a new BluetoothGattService
+     * @hide
+     */
+    public BluetoothGattService(UUID uuid, int instanceId, int serviceType) {
+        mDevice = null;
+        mUuid = uuid;
+        mInstanceId = instanceId;
+        mServiceType = serviceType;
+        mCharacteristics = new ArrayList<BluetoothGattCharacteristic>();
+        mIncludedServices = new ArrayList<BluetoothGattService>();
+    }
+
+    /**
+     * @hide
+     */
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel out, int flags) {
+        out.writeParcelable(new ParcelUuid(mUuid), 0);
+        out.writeInt(mInstanceId);
+        out.writeInt(mServiceType);
+        out.writeTypedList(mCharacteristics);
+
+        ArrayList<BluetoothGattIncludedService> includedServices =
+                new ArrayList<BluetoothGattIncludedService>(mIncludedServices.size());
+        for(BluetoothGattService s : mIncludedServices) {
+            includedServices.add(new BluetoothGattIncludedService(s.getUuid(),
+                                                                  s.getInstanceId(), s.getType()));
+        }
+        out.writeTypedList(includedServices);
+     }
+
+    public static final Parcelable.Creator<BluetoothGattService> CREATOR
+            = new Parcelable.Creator<BluetoothGattService>() {
+        public BluetoothGattService createFromParcel(Parcel in) {
+            return new BluetoothGattService(in);
+        }
+
+        public BluetoothGattService[] newArray(int size) {
+            return new BluetoothGattService[size];
+        }
+    };
+
+    private BluetoothGattService(Parcel in) {
+        mUuid = ((ParcelUuid)in.readParcelable(null)).getUuid();
+        mInstanceId = in.readInt();
+        mServiceType = in.readInt();
+
+        mCharacteristics = new ArrayList<BluetoothGattCharacteristic>();
+
+        ArrayList<BluetoothGattCharacteristic> chrcs =
+                in.createTypedArrayList(BluetoothGattCharacteristic.CREATOR);
+        if (chrcs != null) {
+            for (BluetoothGattCharacteristic chrc : chrcs) {
+                chrc.setService(this);
+                mCharacteristics.add(chrc);
+            }
+        }
+
+        mIncludedServices = new ArrayList<BluetoothGattService>();
+
+        ArrayList<BluetoothGattIncludedService> inclSvcs =
+                in.createTypedArrayList(BluetoothGattIncludedService.CREATOR);
+        if (chrcs != null) {
+            for (BluetoothGattIncludedService isvc : inclSvcs) {
+                mIncludedServices.add(new BluetoothGattService(null, isvc.getUuid(),
+                                                            isvc.getInstanceId(), isvc.getType()));
+            }
+        }
+    }
+
+    /**
      * Returns the device associated with this service.
      * @hide
      */
@@ -125,6 +203,14 @@
     }
 
     /**
+     * Returns the device associated with this service.
+     * @hide
+     */
+    /*package*/ void setDevice(BluetoothDevice device) {
+        this.mDevice = device;
+    }
+
+    /**
      * Add an included service to this service.
      * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
      *
@@ -192,7 +278,7 @@
      * Add an included service to the internal map.
      * @hide
      */
-    /*package*/ void addIncludedService(BluetoothGattService includedService) {
+    public void addIncludedService(BluetoothGattService includedService) {
         mIncludedServices.add(includedService);
     }
 
diff --git a/core/java/android/bluetooth/IBluetoothGattCallback.aidl b/core/java/android/bluetooth/IBluetoothGattCallback.aidl
index cbba9f0..f177244 100644
--- a/core/java/android/bluetooth/IBluetoothGattCallback.aidl
+++ b/core/java/android/bluetooth/IBluetoothGattCallback.aidl
@@ -16,6 +16,7 @@
 package android.bluetooth;
 
 import android.os.ParcelUuid;
+import android.bluetooth.BluetoothGattService;
 import android.bluetooth.le.AdvertiseSettings;
 import android.bluetooth.le.ScanResult;
 
@@ -29,20 +30,7 @@
                                  in boolean connected, in String address);
     void onScanResult(in ScanResult scanResult);
     void onBatchScanResults(in List<ScanResult> batchResults);
-    void onGetService(in String address, in int srvcType, in int srvcInstId,
-                      in ParcelUuid srvcUuid);
-    void onGetIncludedService(in String address, in int srvcType, in int srvcInstId,
-                              in ParcelUuid srvcUuid, in int inclSrvcType,
-                              in int inclSrvcInstId, in ParcelUuid inclSrvcUuid);
-    void onGetCharacteristic(in String address, in int srvcType,
-                             in int srvcInstId, in ParcelUuid srvcUuid,
-                             in int charInstId, in ParcelUuid charUuid,
-                             in int charProps);
-    void onGetDescriptor(in String address, in int srvcType,
-                             in int srvcInstId, in ParcelUuid srvcUuid,
-                             in int charInstId, in ParcelUuid charUuid,
-                             in int descrInstId, in ParcelUuid descrUuid);
-    void onSearchComplete(in String address, in int status);
+    void onSearchComplete(in String address, in List<BluetoothGattService> services, in int status);
     void onCharacteristicRead(in String address, in int status, in int srvcType,
                              in int srvcInstId, in ParcelUuid srvcUuid,
                              in int charInstId, in ParcelUuid charUuid,
diff --git a/core/java/android/bluetooth/IBluetoothManagerCallback.aidl b/core/java/android/bluetooth/IBluetoothManagerCallback.aidl
index 1385daf..8104d21 100644
--- a/core/java/android/bluetooth/IBluetoothManagerCallback.aidl
+++ b/core/java/android/bluetooth/IBluetoothManagerCallback.aidl
@@ -23,7 +23,7 @@
  *
  * {@hide}
  */
-interface IBluetoothManagerCallback {
+oneway interface IBluetoothManagerCallback {
     void onBluetoothServiceUp(in IBluetooth bluetoothService);
     void onBluetoothServiceDown();
     void onBrEdrDown();
diff --git a/core/jni/Android.mk b/core/jni/Android.mk
index 3720498..9e58944 100644
--- a/core/jni/Android.mk
+++ b/core/jni/Android.mk
@@ -279,10 +279,6 @@
 #                        is not being compiled with that level. Remove once this has changed.
 LOCAL_CLANG_CFLAGS += -Wno-c++11-extensions
 
-# b/22414716: thread_local (android/graphics/Paint.cpp) and Clang don't like each other at the
-#             moment.
-LOCAL_CLANG := false
-
 include $(BUILD_SHARED_LIBRARY)
 
 include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/media/java/android/media/MediaDrm.java b/media/java/android/media/MediaDrm.java
index ab61e2b..67ceca5 100644
--- a/media/java/android/media/MediaDrm.java
+++ b/media/java/android/media/MediaDrm.java
@@ -1082,16 +1082,15 @@
      * A CryptoSession is obtained using {@link #getCryptoSession}
      */
     public final class CryptoSession {
-        private MediaDrm mDrm;
         private byte[] mSessionId;
 
-        CryptoSession(@NonNull MediaDrm drm, @NonNull byte[] sessionId,
-                @NonNull String cipherAlgorithm, @NonNull String macAlgorithm)
+        CryptoSession(@NonNull byte[] sessionId,
+                      @NonNull String cipherAlgorithm,
+                      @NonNull String macAlgorithm)
         {
             mSessionId = sessionId;
-            mDrm = drm;
-            setCipherAlgorithmNative(drm, sessionId, cipherAlgorithm);
-            setMacAlgorithmNative(drm, sessionId, macAlgorithm);
+            setCipherAlgorithmNative(MediaDrm.this, sessionId, cipherAlgorithm);
+            setMacAlgorithmNative(MediaDrm.this, sessionId, macAlgorithm);
         }
 
         /**
@@ -1104,7 +1103,7 @@
         @NonNull
         public byte[] encrypt(
                 @NonNull byte[] keyid, @NonNull byte[] input, @NonNull byte[] iv) {
-            return encryptNative(mDrm, mSessionId, keyid, input, iv);
+            return encryptNative(MediaDrm.this, mSessionId, keyid, input, iv);
         }
 
         /**
@@ -1117,7 +1116,7 @@
         @NonNull
         public byte[] decrypt(
                 @NonNull byte[] keyid, @NonNull byte[] input, @NonNull byte[] iv) {
-            return decryptNative(mDrm, mSessionId, keyid, input, iv);
+            return decryptNative(MediaDrm.this, mSessionId, keyid, input, iv);
         }
 
         /**
@@ -1128,7 +1127,7 @@
          */
         @NonNull
         public byte[] sign(@NonNull byte[] keyid, @NonNull byte[] message) {
-            return signNative(mDrm, mSessionId, keyid, message);
+            return signNative(MediaDrm.this, mSessionId, keyid, message);
         }
 
         /**
@@ -1142,7 +1141,7 @@
          */
         public boolean verify(
                 @NonNull byte[] keyid, @NonNull byte[] message, @NonNull byte[] signature) {
-            return verifyNative(mDrm, mSessionId, keyid, message, signature);
+            return verifyNative(MediaDrm.this, mSessionId, keyid, message, signature);
         }
     };
 
@@ -1170,7 +1169,7 @@
             @NonNull byte[] sessionId,
             @NonNull String cipherAlgorithm, @NonNull String macAlgorithm)
     {
-        return new CryptoSession(this, sessionId, cipherAlgorithm, macAlgorithm);
+        return new CryptoSession(sessionId, cipherAlgorithm, macAlgorithm);
     }
 
     /**
diff --git a/media/java/android/media/MediaScanner.java b/media/java/android/media/MediaScanner.java
index 4c8085f..f85a1f2 100644
--- a/media/java/android/media/MediaScanner.java
+++ b/media/java/android/media/MediaScanner.java
@@ -1390,7 +1390,7 @@
             prescan(path, true);
 
             File file = new File(path);
-            if (!file.exists()) {
+            if (!file.exists() || !file.canRead()) {
                 return null;
             }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ServiceMonitor.java b/packages/SystemUI/src/com/android/systemui/statusbar/ServiceMonitor.java
index 602989a..db46dc6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ServiceMonitor.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ServiceMonitor.java
@@ -272,7 +272,7 @@
 
     private static String bundleToString(Bundle bundle) {
         if (bundle == null) return null;
-        StringBuilder sb = new StringBuilder('{');
+        StringBuilder sb = new StringBuilder("{");
         for (String key : bundle.keySet()) {
             if (sb.length() > 1) sb.append(',');
             Object v = bundle.get(key);
diff --git a/services/core/java/com/android/server/job/controllers/ConnectivityController.java b/services/core/java/com/android/server/job/controllers/ConnectivityController.java
index daba0d9..2d5e11a 100644
--- a/services/core/java/com/android/server/job/controllers/ConnectivityController.java
+++ b/services/core/java/com/android/server/job/controllers/ConnectivityController.java
@@ -27,6 +27,7 @@
 import android.os.UserHandle;
 import android.util.Slog;
 
+import com.android.internal.os.BackgroundThread;
 import com.android.server.ConnectivityService;
 import com.android.server.job.JobSchedulerService;
 import com.android.server.job.StateChangedListener;
@@ -70,7 +71,8 @@
         IntentFilter intentFilter = new IntentFilter();
         intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
         mContext.registerReceiverAsUser(
-                mConnectivityChangedReceiver, UserHandle.ALL, intentFilter, null, null);
+                mConnectivityChangedReceiver, UserHandle.ALL, intentFilter, null,
+                BackgroundThread.getHandler());
         ConnectivityService cs =
                 (ConnectivityService)ServiceManager.getService(Context.CONNECTIVITY_SERVICE);
         if (cs != null) {