Merge "Cancel fullscreen countdown timer on interaction." into oc-mr1-dev
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index cc197a2..175293d 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -4021,6 +4021,7 @@
      * @hide
      */
     @SystemApi
+    @RequiresPermission(Manifest.permission.INTERACT_ACROSS_USERS)
     public List<ResolveInfo> queryBroadcastReceiversAsUser(Intent intent,
             @ResolveInfoFlags int flags, UserHandle userHandle) {
         return queryBroadcastReceiversAsUser(intent, flags, userHandle.getIdentifier());
@@ -4809,6 +4810,7 @@
      * @hide
      */
     @SystemApi
+    @RequiresPermission(Manifest.permission.INTERACT_ACROSS_USERS_FULL)
     public abstract int getIntentVerificationStatusAsUser(String packageName, @UserIdInt int userId);
 
     /**
@@ -4878,6 +4880,7 @@
      */
     @TestApi
     @SystemApi
+    @RequiresPermission(Manifest.permission.INTERACT_ACROSS_USERS_FULL)
     public abstract String getDefaultBrowserPackageNameAsUser(@UserIdInt int userId);
 
     /**
@@ -4893,7 +4896,9 @@
      * @hide
      */
     @SystemApi
-    @RequiresPermission(android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
+    @RequiresPermission(allOf = {
+            Manifest.permission.SET_PREFERRED_APPLICATIONS,
+            Manifest.permission.INTERACT_ACROSS_USERS_FULL})
     public abstract boolean setDefaultBrowserPackageNameAsUser(String packageName,
             @UserIdInt int userId);
 
diff --git a/core/java/android/service/autofill/FillResponse.java b/core/java/android/service/autofill/FillResponse.java
index e13fdf6..95e8c88 100644
--- a/core/java/android/service/autofill/FillResponse.java
+++ b/core/java/android/service/autofill/FillResponse.java
@@ -23,15 +23,16 @@
 import android.annotation.Nullable;
 import android.app.Activity;
 import android.content.IntentSender;
+import android.content.pm.ParceledListSlice;
 import android.os.Bundle;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.view.autofill.AutofillId;
-import android.view.autofill.AutofillManager;
 import android.widget.RemoteViews;
 
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.List;
 
 /**
  * Response for a {@link
@@ -41,7 +42,7 @@
  */
 public final class FillResponse implements Parcelable {
 
-    private final @Nullable ArrayList<Dataset> mDatasets;
+    private final @Nullable ParceledListSlice<Dataset> mDatasets;
     private final @Nullable SaveInfo mSaveInfo;
     private final @Nullable Bundle mClientState;
     private final @Nullable RemoteViews mPresentation;
@@ -51,7 +52,7 @@
     private int mRequestId;
 
     private FillResponse(@NonNull Builder builder) {
-        mDatasets = builder.mDatasets;
+        mDatasets = (builder.mDatasets != null) ? new ParceledListSlice<>(builder.mDatasets) : null;
         mSaveInfo = builder.mSaveInfo;
         mClientState = builder.mCLientState;
         mPresentation = builder.mPresentation;
@@ -67,8 +68,8 @@
     }
 
     /** @hide */
-    public @Nullable ArrayList<Dataset> getDatasets() {
-        return mDatasets;
+    public @Nullable List<Dataset> getDatasets() {
+        return (mDatasets != null) ? mDatasets.getList() : null;
     }
 
     /** @hide */
@@ -143,12 +144,13 @@
          * for the user to trigger your authentication flow.
          *
          * <p>When a user triggers autofill, the system launches the provided intent
-         * whose extras will have the {@link AutofillManager#EXTRA_ASSIST_STRUCTURE screen
+         * whose extras will have the
+         * {@link android.view.autofill.AutofillManager#EXTRA_ASSIST_STRUCTURE screen
          * content} and your {@link android.view.autofill.AutofillManager#EXTRA_CLIENT_STATE
          * client state}. Once you complete your authentication flow you should set the
          * {@link Activity} result to {@link android.app.Activity#RESULT_OK} and provide the fully
-         * populated {@link FillResponse response} by setting it to the {@link
-         * AutofillManager#EXTRA_AUTHENTICATION_RESULT} extra.
+         * populated {@link FillResponse response} by setting it to the
+         * {@link android.view.autofill.AutofillManager#EXTRA_AUTHENTICATION_RESULT} extra.
          * For example, if you provided an empty {@link FillResponse resppnse} because the
          * user's data was locked and marked that the response needs an authentication then
          * in the response returned if authentication succeeds you need to provide all
@@ -205,6 +207,15 @@
         /**
          * Adds a new {@link Dataset} to this response.
          *
+         * <p><b>Note: </b> on Android {@link android.os.Build.VERSION_CODES#O}, the total number of
+         * datasets is limited by the Binder transaction size, so it's recommended to keep it
+         * small (in the range of 10-20 at most) and use pagination by adding a fake
+         * {@link Dataset.Builder#setAuthentication(IntentSender) authenticated} at the end with
+         * a presentation string like "Next 10" that would return a new {@link FillResponse} with
+         * the next 10 datasets, and so on. This limitation was lifted on
+         * Android {@link android.os.Build.VERSION_CODES#O_MR1}, although the Binder transaction
+         * size can still be reached if each dataset itself is too big.
+         *
          * @return This builder.
          */
         public @NonNull Builder addDataset(@Nullable Dataset dataset) {
@@ -313,7 +324,7 @@
 
     @Override
     public void writeToParcel(Parcel parcel, int flags) {
-        parcel.writeTypedArrayList(mDatasets, flags);
+        parcel.writeParcelable(mDatasets, flags);
         parcel.writeParcelable(mSaveInfo, flags);
         parcel.writeParcelable(mClientState, flags);
         parcel.writeParcelableArray(mAuthenticationIds, flags);
@@ -331,7 +342,8 @@
             // the system obeys the contract of the builder to avoid attacks
             // using specially crafted parcels.
             final Builder builder = new Builder();
-            final ArrayList<Dataset> datasets = parcel.readTypedArrayList(null);
+            final ParceledListSlice<Dataset> datasetSlice = parcel.readParcelable(null);
+            final List<Dataset> datasets = (datasetSlice != null) ? datasetSlice.getList() : null;
             final int datasetCount = (datasets != null) ? datasets.size() : 0;
             for (int i = 0; i < datasetCount; i++) {
                 builder.addDataset(datasets.get(i));
diff --git a/core/java/com/android/internal/util/AsyncChannel.java b/core/java/com/android/internal/util/AsyncChannel.java
index 6fbfff8..e760f25 100644
--- a/core/java/com/android/internal/util/AsyncChannel.java
+++ b/core/java/com/android/internal/util/AsyncChannel.java
@@ -402,7 +402,6 @@
 
         // Initialize destination fields
         mDstMessenger = dstMessenger;
-        linkToDeathMonitor();
         if (DBG) log("connected srcHandler to the dstMessenger X");
     }
 
diff --git a/packages/SystemUI/res/layout/zen_mode_condition.xml b/packages/SystemUI/res/layout/zen_mode_condition.xml
index 2b4a0f5..ab52465 100644
--- a/packages/SystemUI/res/layout/zen_mode_condition.xml
+++ b/packages/SystemUI/res/layout/zen_mode_condition.xml
@@ -27,6 +27,8 @@
         android:id="@android:id/content"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
+        android:minHeight="48dp"
+        android:gravity="center_vertical"
         android:layout_centerVertical="true"
         android:orientation="vertical"
         android:layout_toEndOf="@android:id/checkbox"
@@ -79,4 +81,4 @@
         android:tint="?android:attr/textColorPrimary"
         android:src="@drawable/ic_qs_plus" />
 
-</RelativeLayout>
\ No newline at end of file
+</RelativeLayout>
diff --git a/packages/SystemUI/res/layout/zen_mode_panel.xml b/packages/SystemUI/res/layout/zen_mode_panel.xml
index 4261641..5516983 100644
--- a/packages/SystemUI/res/layout/zen_mode_panel.xml
+++ b/packages/SystemUI/res/layout/zen_mode_panel.xml
@@ -93,7 +93,7 @@
 
         </RelativeLayout>
 
-        <LinearLayout
+        <com.android.systemui.volume.ZenRadioLayout
             android:id="@+id/zen_conditions"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
@@ -111,7 +111,7 @@
                 android:layout_width="fill_parent"
                 android:layout_height="fill_parent"
                 android:orientation="vertical"/>
-        </LinearLayout>
+        </com.android.systemui.volume.ZenRadioLayout>
 
         <TextView
             android:id="@+id/zen_alarm_warning"
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
index 14afbfa..c691498 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
@@ -269,7 +269,7 @@
                     item.icon = R.drawable.ic_qs_bluetooth_on;
                     item.line1 = device.getName();
                     item.tag = device;
-                    int state = mController.getMaxConnectionState(device);
+                    int state = device.getMaxConnectionState();
                     if (state == BluetoothProfile.STATE_CONNECTED) {
                         item.icon = R.drawable.ic_qs_bluetooth_connected;
                         int batteryLevel = device.getBatteryLevel();
diff --git a/packages/SystemUI/src/com/android/systemui/volume/ZenRadioLayout.java b/packages/SystemUI/src/com/android/systemui/volume/ZenRadioLayout.java
new file mode 100644
index 0000000..5dbcd8a
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/volume/ZenRadioLayout.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package com.android.systemui.volume;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.LinearLayout;
+
+/**
+ * Specialized layout for zen mode that allows the radio buttons to reside within
+ * a RadioGroup, but also makes sure that all the heights off the radio buttons align
+ * with the corresponding content in the second child of this view.
+ */
+public class ZenRadioLayout extends LinearLayout {
+
+    public ZenRadioLayout(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    /**
+     * Run 2 measurement passes, 1 that figures out the size of the content, and another
+     * that sets the size of the radio buttons to the heights of the corresponding content.
+     */
+    @Override
+    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+
+        ViewGroup radioGroup = (ViewGroup) getChildAt(0);
+        ViewGroup radioContent = (ViewGroup) getChildAt(1);
+        int size = radioGroup.getChildCount();
+        if (size != radioContent.getChildCount()) {
+            throw new IllegalStateException("Expected matching children");
+        }
+        boolean hasChanges = false;
+        for (int i = 0; i < size; i++) {
+            View radio = radioGroup.getChildAt(i);
+            View content = radioContent.getChildAt(i);
+            if (radio.getLayoutParams().height != content.getMeasuredHeight()) {
+                hasChanges = true;
+                radio.getLayoutParams().height = content.getMeasuredHeight();
+            }
+        }
+        // Measure again if any heights changed.
+        if (hasChanges) {
+            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+        }
+    }
+}
diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java
index 4107756..f8fb13a 100644
--- a/services/autofill/java/com/android/server/autofill/Session.java
+++ b/services/autofill/java/com/android/server/autofill/Session.java
@@ -928,7 +928,7 @@
 
                 // Make sure the service doesn't have the fields already by checking the datasets
                 // content.
-                final ArrayList<Dataset> datasets = response.getDatasets();
+                final List<Dataset> datasets = response.getDatasets();
                 if (datasets != null) {
                     datasets_loop: for (int i = 0; i < datasets.size(); i++) {
                         final Dataset dataset = datasets.get(i);
@@ -1157,7 +1157,7 @@
                 }
             }
 
-            final ArrayList<Dataset> datasets = response.getDatasets();
+            final List<Dataset> datasets = response.getDatasets();
             if (datasets != null) {
                 final int numDatasets = datasets.size();
 
@@ -1353,7 +1353,7 @@
         // Must also track that are part of datasets, otherwise the FillUI won't be hidden when
         // they go away (if they're not savable).
 
-        final ArrayList<Dataset> datasets = response.getDatasets();
+        final List<Dataset> datasets = response.getDatasets();
         ArraySet<AutofillId> fillableIds = null;
         if (datasets != null) {
             for (int i = 0; i < datasets.size(); i++) {
@@ -1426,7 +1426,7 @@
      * Sets the state of all views in the given response.
      */
     private void setViewStatesLocked(FillResponse response, int state, boolean clearResponse) {
-        final ArrayList<Dataset> datasets = response.getDatasets();
+        final List<Dataset> datasets = response.getDatasets();
         if (datasets != null) {
             for (int i = 0; i < datasets.size(); i++) {
                 final Dataset dataset = datasets.get(i);
diff --git a/services/core/java/com/android/server/display/NightDisplayService.java b/services/core/java/com/android/server/display/NightDisplayService.java
index b124a39..026921d 100644
--- a/services/core/java/com/android/server/display/NightDisplayService.java
+++ b/services/core/java/com/android/server/display/NightDisplayService.java
@@ -119,9 +119,9 @@
      *  </table>
      */
     private static final float[] mColorTempCoefficients = new float[] {
-            0.0f, -0.0000000871377221f, -0.0000000753960646f,
-            0.0f, 0.000750142586f, .000725567598f,
-            1.0f, -.830130222f, -1.15546312f
+            0.0f, -0.000000014365268757f, -0.000000000910931179f,
+            0.0f, 0.000255092801250106f, 0.000207598323269139f,
+            1.0f, -0.064156942434907716f, -0.349361641294833436f
     };
 
     private int mCurrentUser = UserHandle.USER_NULL;
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index baa2856..b74f183 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -7943,6 +7943,9 @@
             String resolvedType, int flags, int userId) {
         if (!sUserManager.exists(userId)) return Collections.emptyList();
         final int callingUid = Binder.getCallingUid();
+        enforceCrossUserPermission(callingUid, userId,
+                false /*requireFullPermission*/, false /*checkShell*/,
+                "query intent receivers");
         final String instantAppPkgName = getInstantAppPackageName(callingUid);
         flags = updateFlagsForResolve(flags, userId, intent, callingUid,
                 false /*includeInstantApps*/);
@@ -8049,6 +8052,9 @@
             String resolvedType, int flags, int userId, int callingUid,
             boolean includeInstantApps) {
         if (!sUserManager.exists(userId)) return Collections.emptyList();
+        enforceCrossUserPermission(callingUid, userId,
+                false /*requireFullPermission*/, false /*checkShell*/,
+                "query intent receivers");
         final String instantAppPkgName = getInstantAppPackageName(callingUid);
         flags = updateFlagsForResolve(flags, userId, intent, callingUid, includeInstantApps);
         ComponentName comp = intent.getComponent();
@@ -15273,6 +15279,11 @@
     @Override
     public int getIntentVerificationStatus(String packageName, int userId) {
         final int callingUid = Binder.getCallingUid();
+        if (UserHandle.getUserId(callingUid) != userId) {
+            mContext.enforceCallingOrSelfPermission(
+                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
+                    "getIntentVerificationStatus" + userId);
+        }
         if (getInstantAppPackageName(callingUid) != null) {
             return INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
         }
@@ -15356,6 +15367,10 @@
     public boolean setDefaultBrowserPackageName(String packageName, int userId) {
         mContext.enforceCallingOrSelfPermission(
                 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
+        if (UserHandle.getCallingUserId() != userId) {
+            mContext.enforceCallingOrSelfPermission(
+                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
+        }
 
         synchronized (mPackages) {
             boolean result = mSettings.setDefaultBrowserPackageNameLPw(packageName, userId);
@@ -15369,6 +15384,10 @@
 
     @Override
     public String getDefaultBrowserPackageName(int userId) {
+        if (UserHandle.getCallingUserId() != userId) {
+            mContext.enforceCallingOrSelfPermission(
+                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
+        }
         if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
             return null;
         }
diff --git a/services/core/jni/BroadcastRadio/BroadcastRadioService.cpp b/services/core/jni/BroadcastRadio/BroadcastRadioService.cpp
index 492be17..b3817db 100644
--- a/services/core/jni/BroadcastRadio/BroadcastRadioService.cpp
+++ b/services/core/jni/BroadcastRadio/BroadcastRadioService.cpp
@@ -27,14 +27,17 @@
 #include <android/hidl/manager/1.0/IServiceManager.h>
 #include <core_jni_helpers.h>
 #include <hidl/ServiceManagement.h>
+#include <nativehelper/JNIHelp.h>
 #include <utils/Log.h>
-#include <JNIHelp.h>
 
 namespace android {
 namespace server {
 namespace BroadcastRadio {
 namespace BroadcastRadioService {
 
+using std::lock_guard;
+using std::mutex;
+
 using hardware::Return;
 using hardware::hidl_string;
 using hardware::hidl_vec;
@@ -50,7 +53,7 @@
 using V1_0::MetaData;
 using V1_0::ITuner;
 
-static Mutex gContextMutex;
+static mutex gContextMutex;
 
 static struct {
     struct {
@@ -90,8 +93,8 @@
 }
 
 static jlong nativeInit(JNIEnv *env, jobject obj) {
-    ALOGV("nativeInit()");
-    AutoMutex _l(gContextMutex);
+    ALOGV("%s", __func__);
+    lock_guard<mutex> lk(gContextMutex);
 
     auto nativeContext = new ServiceContext();
     static_assert(sizeof(jlong) >= sizeof(nativeContext), "jlong is smaller than a pointer");
@@ -99,16 +102,16 @@
 }
 
 static void nativeFinalize(JNIEnv *env, jobject obj, jlong nativeContext) {
-    ALOGV("nativeFinalize()");
-    AutoMutex _l(gContextMutex);
+    ALOGV("%s", __func__);
+    lock_guard<mutex> lk(gContextMutex);
 
     auto ctx = reinterpret_cast<ServiceContext*>(nativeContext);
     delete ctx;
 }
 
 static jobject nativeLoadModules(JNIEnv *env, jobject obj, jlong nativeContext) {
-    ALOGV("nativeLoadModules()");
-    AutoMutex _l(gContextMutex);
+    ALOGV("%s", __func__);
+    lock_guard<mutex> lk(gContextMutex);
     auto& ctx = getNativeContext(nativeContext);
 
     // Get list of registered HIDL HAL implementations.
@@ -182,8 +185,8 @@
 
 static jobject nativeOpenTuner(JNIEnv *env, jobject obj, long nativeContext, jint moduleId,
         jobject bandConfig, bool withAudio, jobject callback) {
-    ALOGV("nativeOpenTuner()");
-    AutoMutex _l(gContextMutex);
+    ALOGV("%s", __func__);
+    lock_guard<mutex> lk(gContextMutex);
     auto& ctx = getNativeContext(nativeContext);
 
     if (callback == nullptr) {
diff --git a/services/core/jni/BroadcastRadio/NativeCallbackThread.cpp b/services/core/jni/BroadcastRadio/NativeCallbackThread.cpp
index 0c84e6d..85ec9e0 100644
--- a/services/core/jni/BroadcastRadio/NativeCallbackThread.cpp
+++ b/services/core/jni/BroadcastRadio/NativeCallbackThread.cpp
@@ -23,45 +23,38 @@
 
 namespace android {
 
-NativeCallbackThread::NativeCallbackThread(JavaVM *vm) : mExitting(false), mvm(vm) {
-    auto res = pthread_create(&mThread, nullptr, main, this);
-    if (res != 0) {
-        ALOGE("Couldn't start NativeCallbackThread");
-        mThread = 0;
-        return;
-    }
+using std::lock_guard;
+using std::mutex;
+using std::unique_lock;
+
+NativeCallbackThread::NativeCallbackThread(JavaVM *vm) : mvm(vm), mExiting(false),
+        mThread(&NativeCallbackThread::threadLoop, this) {
     ALOGD("Started native callback thread %p", this);
 }
 
 NativeCallbackThread::~NativeCallbackThread() {
-    ALOGV("~NativeCallbackThread %p", this);
+    ALOGV("%s %p", __func__, this);
     stop();
 }
 
-void* NativeCallbackThread::main(void *args) {
-    auto self = reinterpret_cast<NativeCallbackThread*>(args);
-    self->main();
-    return nullptr;
-}
-
-void NativeCallbackThread::main() {
-    ALOGV("NativeCallbackThread::main()");
+void NativeCallbackThread::threadLoop() {
+    ALOGV("%s", __func__);
 
     JNIEnv *env = nullptr;
     JavaVMAttachArgs aargs = {JNI_VERSION_1_4, "NativeCallbackThread", nullptr};
     if (mvm->AttachCurrentThread(&env, &aargs) != JNI_OK || env == nullptr) {
         ALOGE("Couldn't attach thread");
+        mExiting = true;
         return;
     }
 
-    while (!mExitting) {
+    while (!mExiting) {
         ALOGV("Waiting for task...");
         Task task;
         {
-            AutoMutex _l(mQueueMutex);
-            auto res = mQueueCond.wait(mQueueMutex);
-            ALOGE_IF(res != 0, "Wait failed: %d", res);
-            if (mExitting || res != 0) break;
+            unique_lock<mutex> lk(mQueueMutex);
+            mQueueCond.wait(lk);
+            if (mExiting) break;
 
             if (mQueue.empty()) continue;
             task = mQueue.front();
@@ -84,36 +77,35 @@
 }
 
 void NativeCallbackThread::enqueue(const Task &task) {
-    AutoMutex _l(mQueueMutex);
+    lock_guard<mutex> lk(mQueueMutex);
 
-    if (mThread == 0 || mExitting) {
+    if (mExiting) {
         ALOGW("Callback thread %p is not serving calls", this);
         return;
     }
 
     mQueue.push(task);
-    mQueueCond.signal();
+    mQueueCond.notify_one();
 }
 
 void NativeCallbackThread::stop() {
-    ALOGV("stop() %p", this);
+    ALOGV("%s %p", __func__, this);
 
     {
-        AutoMutex _l(mQueueMutex);
+        lock_guard<mutex> lk(mQueueMutex);
 
-        if (mThread == 0 || mExitting) return;
+        if (mExiting) return;
 
-        mExitting = true;
-        mQueueCond.signal();
+        mExiting = true;
+        mQueueCond.notify_one();
     }
 
-    if (pthread_self() == mThread) {
+    if (mThread.get_id() == std::thread::id()) {
         // you can't self-join a thread, but it's ok when calling from our sub-task
         ALOGD("About to stop native callback thread %p", this);
+        mThread.detach();
     } else {
-        auto ret = pthread_join(mThread, nullptr);
-        ALOGE_IF(ret != 0, "Couldn't join thread: %d", ret);
-
+        mThread.join();
         ALOGD("Stopped native callback thread %p", this);
     }
 }
diff --git a/services/core/jni/BroadcastRadio/NativeCallbackThread.h b/services/core/jni/BroadcastRadio/NativeCallbackThread.h
index 4e03b11..53990be 100644
--- a/services/core/jni/BroadcastRadio/NativeCallbackThread.h
+++ b/services/core/jni/BroadcastRadio/NativeCallbackThread.h
@@ -20,26 +20,23 @@
 #include <android-base/macros.h>
 #include <functional>
 #include <jni.h>
-#include <pthread.h>
 #include <queue>
-#include <utils/Condition.h>
-#include <utils/Mutex.h>
+#include <thread>
 
 namespace android {
 
 class NativeCallbackThread {
     typedef std::function<void(JNIEnv*)> Task;
 
-    pthread_t mThread;
-    Mutex mQueueMutex;
-    Condition mQueueCond;
-    std::atomic<bool> mExitting;
-
     JavaVM *mvm;
     std::queue<Task> mQueue;
 
-    static void* main(void *args);
-    void main();
+    std::mutex mQueueMutex;
+    std::condition_variable mQueueCond;
+    std::atomic<bool> mExiting;
+    std::thread mThread;
+
+    void threadLoop();
 
     DISALLOW_COPY_AND_ASSIGN(NativeCallbackThread);
 
diff --git a/services/core/jni/BroadcastRadio/Tuner.cpp b/services/core/jni/BroadcastRadio/Tuner.cpp
index 2e8798b..f5a85c1 100644
--- a/services/core/jni/BroadcastRadio/Tuner.cpp
+++ b/services/core/jni/BroadcastRadio/Tuner.cpp
@@ -22,12 +22,12 @@
 #include "convert.h"
 #include "TunerCallback.h"
 
-#include <JNIHelp.h>
-#include <Utils.h>
 #include <android/hardware/broadcastradio/1.1/IBroadcastRadioFactory.h>
 #include <binder/IPCThreadState.h>
+#include <broadcastradio-utils/Utils.h>
 #include <core_jni_helpers.h>
 #include <media/AudioSystem.h>
+#include <nativehelper/JNIHelp.h>
 #include <utils/Log.h>
 
 namespace android {
@@ -35,6 +35,9 @@
 namespace BroadcastRadio {
 namespace Tuner {
 
+using std::lock_guard;
+using std::mutex;
+
 using hardware::Return;
 using hardware::hidl_death_recipient;
 using hardware::hidl_vec;
@@ -49,7 +52,7 @@
 using V1_1::ITunerCallback;
 using V1_1::ProgramListResult;
 
-static Mutex gContextMutex;
+static mutex gContextMutex;
 
 static struct {
     struct {
@@ -106,8 +109,8 @@
 }
 
 static jlong nativeInit(JNIEnv *env, jobject obj, jint halRev, bool withAudio, jint band) {
-    ALOGV("nativeInit()");
-    AutoMutex _l(gContextMutex);
+    ALOGV("%s", __func__);
+    lock_guard<mutex> lk(gContextMutex);
 
     auto ctx = new TunerContext();
     ctx->mHalRev = static_cast<HalRevision>(halRev);
@@ -119,8 +122,8 @@
 }
 
 static void nativeFinalize(JNIEnv *env, jobject obj, jlong nativeContext) {
-    ALOGV("nativeFinalize()");
-    AutoMutex _l(gContextMutex);
+    ALOGV("%s", __func__);
+    lock_guard<mutex> lk(gContextMutex);
 
     auto ctx = reinterpret_cast<TunerContext*>(nativeContext);
     delete ctx;
@@ -150,10 +153,9 @@
 
 void assignHalInterfaces(JNIEnv *env, JavaRef<jobject> const &jTuner,
         sp<V1_0::IBroadcastRadio> halModule, sp<V1_0::ITuner> halTuner) {
-    ALOGV("setHalTuner(%p)", halTuner.get());
+    ALOGV("%s(%p)", __func__, halTuner.get());
     ALOGE_IF(halTuner == nullptr, "HAL tuner is a nullptr");
-
-    AutoMutex _l(gContextMutex);
+    lock_guard<mutex> lk(gContextMutex);
     auto& ctx = getNativeContext(env, jTuner);
 
     if (ctx.mIsClosed) {
@@ -187,12 +189,12 @@
 }
 
 sp<V1_0::ITuner> getHalTuner(jlong nativeContext) {
-    AutoMutex _l(gContextMutex);
+    lock_guard<mutex> lk(gContextMutex);
     return getHalTuner(getNativeContext(nativeContext));
 }
 
 sp<V1_1::ITuner> getHalTuner11(jlong nativeContext) {
-    AutoMutex _l(gContextMutex);
+    lock_guard<mutex> lk(gContextMutex);
     return getNativeContext(nativeContext).mHalTuner11;
 }
 
@@ -206,8 +208,9 @@
 }
 
 static void nativeClose(JNIEnv *env, jobject obj, jlong nativeContext) {
-    AutoMutex _l(gContextMutex);
+    lock_guard<mutex> lk(gContextMutex);
     auto& ctx = getNativeContext(nativeContext);
+
     if (ctx.mIsClosed) return;
     ctx.mIsClosed = true;
 
@@ -228,9 +231,10 @@
 }
 
 static void nativeSetConfiguration(JNIEnv *env, jobject obj, jlong nativeContext, jobject config) {
-    ALOGV("nativeSetConfiguration()");
-    AutoMutex _l(gContextMutex);
+    ALOGV("%s", __func__);
+    lock_guard<mutex> lk(gContextMutex);
     auto& ctx = getNativeContext(nativeContext);
+
     auto halTuner = getHalTuner(ctx);
     if (halTuner == nullptr) return;
 
@@ -244,7 +248,7 @@
 
 static jobject nativeGetConfiguration(JNIEnv *env, jobject obj, jlong nativeContext,
         Region region) {
-    ALOGV("nativeSetConfiguration()");
+    ALOGV("%s", __func__);
     auto halTuner = getHalTuner(nativeContext);
     if (halTuner == nullptr) return nullptr;
 
@@ -263,7 +267,7 @@
 
 static void nativeStep(JNIEnv *env, jobject obj, jlong nativeContext,
         bool directionDown, bool skipSubChannel) {
-    ALOGV("nativeStep()");
+    ALOGV("%s", __func__);
     auto halTuner = getHalTuner(nativeContext);
     if (halTuner == nullptr) return;
 
@@ -273,7 +277,7 @@
 
 static void nativeScan(JNIEnv *env, jobject obj, jlong nativeContext,
         bool directionDown, bool skipSubChannel) {
-    ALOGV("nativeScan()");
+    ALOGV("%s", __func__);
     auto halTuner = getHalTuner(nativeContext);
     if (halTuner == nullptr) return;
 
@@ -282,9 +286,10 @@
 }
 
 static void nativeTune(JNIEnv *env, jobject obj, jlong nativeContext, jobject jSelector) {
-    ALOGV("nativeTune()");
-    AutoMutex _l(gContextMutex);
+    ALOGV("%s", __func__);
+    lock_guard<mutex> lk(gContextMutex);
     auto& ctx = getNativeContext(nativeContext);
+
     auto halTuner10 = getHalTuner(ctx);
     auto halTuner11 = ctx.mHalTuner11;
     if (halTuner10 == nullptr) return;
@@ -304,7 +309,7 @@
 }
 
 static void nativeCancel(JNIEnv *env, jobject obj, jlong nativeContext) {
-    ALOGV("nativeCancel()");
+    ALOGV("%s", __func__);
     auto halTuner = getHalTuner(nativeContext);
     if (halTuner == nullptr) return;
 
@@ -323,9 +328,10 @@
 }
 
 static jobject nativeGetProgramInformation(JNIEnv *env, jobject obj, jlong nativeContext) {
-    ALOGV("nativeGetProgramInformation()");
-    AutoMutex _l(gContextMutex);
+    ALOGV("%s", __func__);
+    lock_guard<mutex> lk(gContextMutex);
     auto& ctx = getNativeContext(nativeContext);
+
     auto halTuner10 = getHalTuner(ctx);
     auto halTuner11 = ctx.mHalTuner11;
     if (halTuner10 == nullptr) return nullptr;
@@ -355,7 +361,7 @@
 }
 
 static bool nativeStartBackgroundScan(JNIEnv *env, jobject obj, jlong nativeContext) {
-    ALOGV("nativeStartBackgroundScan()");
+    ALOGV("%s", __func__);
     auto halTuner = getHalTuner11(nativeContext);
     if (halTuner == nullptr) {
         ALOGI("Background scan is not supported with HAL < 1.1");
@@ -369,7 +375,7 @@
 }
 
 static jobject nativeGetProgramList(JNIEnv *env, jobject obj, jlong nativeContext, jstring jFilter) {
-    ALOGV("nativeGetProgramList()");
+    ALOGV("%s", __func__);
     auto halTuner = getHalTuner11(nativeContext);
     if (halTuner == nullptr) {
         ALOGI("Program list is not supported with HAL < 1.1");
@@ -398,7 +404,7 @@
 
 static jbyteArray nativeGetImage(JNIEnv *env, jobject obj, jlong nativeContext, jint id) {
     ALOGV("%s(%x)", __func__, id);
-    AutoMutex _l(gContextMutex);
+    lock_guard<mutex> lk(gContextMutex);
     auto& ctx = getNativeContext(nativeContext);
 
     if (ctx.mHalModule11 == nullptr) {
@@ -435,7 +441,7 @@
 }
 
 static bool nativeIsAnalogForced(JNIEnv *env, jobject obj, jlong nativeContext) {
-    ALOGV("nativeIsAnalogForced()");
+    ALOGV("%s", __func__);
     auto halTuner = getHalTuner11(nativeContext);
     if (halTuner == nullptr) {
         jniThrowException(env, "java/lang/IllegalStateException",
@@ -456,7 +462,7 @@
 }
 
 static void nativeSetAnalogForced(JNIEnv *env, jobject obj, jlong nativeContext, bool isForced) {
-    ALOGV("nativeSetAnalogForced()");
+    ALOGV("%s(%d)", __func__, isForced);
     auto halTuner = getHalTuner11(nativeContext);
     if (halTuner == nullptr) {
         jniThrowException(env, "java/lang/IllegalStateException",
@@ -469,7 +475,7 @@
 }
 
 static bool nativeIsAntennaConnected(JNIEnv *env, jobject obj, jlong nativeContext) {
-    ALOGV("nativeIsAntennaConnected()");
+    ALOGV("%s", __func__);
     auto halTuner = getHalTuner(nativeContext);
     if (halTuner == nullptr) return false;
 
diff --git a/services/core/jni/BroadcastRadio/TunerCallback.cpp b/services/core/jni/BroadcastRadio/TunerCallback.cpp
index d22ee82..04bdddf 100644
--- a/services/core/jni/BroadcastRadio/TunerCallback.cpp
+++ b/services/core/jni/BroadcastRadio/TunerCallback.cpp
@@ -22,9 +22,9 @@
 #include "Tuner.h"
 #include "convert.h"
 
-#include <JNIHelp.h>
-#include <Utils.h>
+#include <broadcastradio-utils/Utils.h>
 #include <core_jni_helpers.h>
+#include <nativehelper/JNIHelp.h>
 #include <utils/Log.h>
 
 namespace android {
@@ -32,6 +32,9 @@
 namespace BroadcastRadio {
 namespace TunerCallback {
 
+using std::lock_guard;
+using std::mutex;
+
 using hardware::Return;
 using hardware::hidl_vec;
 
@@ -76,7 +79,7 @@
     BACKGROUND_SCAN_FAILED = 6,
 };
 
-static Mutex gContextMutex;
+static mutex gContextMutex;
 
 class NativeCallback : public ITunerCallback {
     jobject mJTuner;
@@ -122,13 +125,13 @@
 
 NativeCallback::NativeCallback(JNIEnv *env, jobject jTuner, jobject jCallback, HalRevision halRev)
         : mCallbackThread(gvm), mHalRev(halRev) {
-    ALOGV("NativeCallback()");
+    ALOGV("%s", __func__);
     mJTuner = env->NewGlobalRef(jTuner);
     mJCallback = env->NewGlobalRef(jCallback);
 }
 
 NativeCallback::~NativeCallback() {
-    ALOGV("~NativeCallback()");
+    ALOGV("%s", __func__);
 
     // stop callback thread before dereferencing client callback
     mCallbackThread.stop();
@@ -155,7 +158,7 @@
 }
 
 Return<void> NativeCallback::configChange(Result result, const BandConfig& config) {
-    ALOGV("configChange(%d)", result);
+    ALOGV("%s(%d)", __func__, result);
 
     mCallbackThread.enqueue([result, config, this](JNIEnv *env) {
         if (result == Result::OK) {
@@ -173,7 +176,7 @@
 }
 
 Return<void> NativeCallback::tuneComplete(Result result, const V1_0::ProgramInfo& info) {
-    ALOGV("tuneComplete(%d)", result);
+    ALOGV("%s(%d)", __func__, result);
 
     if (mHalRev > HalRevision::V1_0) {
         ALOGW("1.0 callback was ignored");
@@ -185,7 +188,7 @@
 }
 
 Return<void> NativeCallback::tuneComplete_1_1(Result result, const ProgramSelector& selector) {
-    ALOGV("tuneComplete_1_1(%d)", result);
+    ALOGV("%s(%d)", __func__, result);
 
     mCallbackThread.enqueue([result, this](JNIEnv *env) {
         if (result == Result::OK) {
@@ -201,17 +204,17 @@
 }
 
 Return<void> NativeCallback::afSwitch(const V1_0::ProgramInfo& info) {
-    ALOGV("afSwitch()");
+    ALOGV("%s", __func__);
     return tuneComplete(Result::OK, info);
 }
 
 Return<void> NativeCallback::afSwitch_1_1(const ProgramSelector& selector) {
-    ALOGV("afSwitch_1_1()");
+    ALOGV("%s", __func__);
     return tuneComplete_1_1(Result::OK, selector);
 }
 
 Return<void> NativeCallback::antennaStateChange(bool connected) {
-    ALOGV("antennaStateChange(%d)", connected);
+    ALOGV("%s(%d)", __func__, connected);
 
     mCallbackThread.enqueue([this, connected](JNIEnv *env) {
         env->CallVoidMethod(mJCallback, gjni.TunerCallback.onAntennaState, connected);
@@ -221,7 +224,7 @@
 }
 
 Return<void> NativeCallback::trafficAnnouncement(bool active) {
-    ALOGV("trafficAnnouncement(%d)", active);
+    ALOGV("%s(%d)", __func__, active);
 
     mCallbackThread.enqueue([this, active](JNIEnv *env) {
         env->CallVoidMethod(mJCallback, gjni.TunerCallback.onTrafficAnnouncement, active);
@@ -231,7 +234,7 @@
 }
 
 Return<void> NativeCallback::emergencyAnnouncement(bool active) {
-    ALOGV("emergencyAnnouncement(%d)", active);
+    ALOGV("%s(%d)", __func__, active);
 
     mCallbackThread.enqueue([this, active](JNIEnv *env) {
         env->CallVoidMethod(mJCallback, gjni.TunerCallback.onEmergencyAnnouncement, active);
@@ -243,7 +246,7 @@
 Return<void> NativeCallback::newMetadata(uint32_t channel, uint32_t subChannel,
         const hidl_vec<MetaData>& metadata) {
     // channel and subChannel are not used
-    ALOGV("newMetadata(%d, %d)", channel, subChannel);
+    ALOGV("%s(%d, %d)", __func__, channel, subChannel);
 
     if (mHalRev > HalRevision::V1_0) {
         ALOGW("1.0 callback was ignored");
@@ -258,7 +261,7 @@
 }
 
 Return<void> NativeCallback::backgroundScanAvailable(bool isAvailable) {
-    ALOGV("backgroundScanAvailable(%d)", isAvailable);
+    ALOGV("%s(%d)", __func__, isAvailable);
 
     mCallbackThread.enqueue([this, isAvailable](JNIEnv *env) {
         env->CallVoidMethod(mJCallback,
@@ -269,7 +272,7 @@
 }
 
 Return<void> NativeCallback::backgroundScanComplete(ProgramListResult result) {
-    ALOGV("backgroundScanComplete(%d)", result);
+    ALOGV("%s(%d)", __func__, result);
 
     mCallbackThread.enqueue([this, result](JNIEnv *env) {
         if (result == ProgramListResult::OK) {
@@ -285,7 +288,7 @@
 }
 
 Return<void> NativeCallback::programListChanged() {
-    ALOGV("programListChanged()");
+    ALOGV("%s", __func__);
 
     mCallbackThread.enqueue([this](JNIEnv *env) {
         env->CallVoidMethod(mJCallback, gjni.TunerCallback.onProgramListChanged);
@@ -295,7 +298,7 @@
 }
 
 Return<void> NativeCallback::programInfoChanged() {
-    ALOGV("programInfoChanged()");
+    ALOGV("%s", __func__);
 
     mCallbackThread.enqueue([this](JNIEnv *env) {
         env->CallVoidMethod(mJCallback, gjni.TunerCallback.onProgramInfoChanged);
@@ -318,8 +321,8 @@
 }
 
 static jlong nativeInit(JNIEnv *env, jobject obj, jobject jTuner, jint jHalRev) {
-    ALOGV("nativeInit()");
-    AutoMutex _l(gContextMutex);
+    ALOGV("%s", __func__);
+    lock_guard<mutex> lk(gContextMutex);
 
     auto halRev = static_cast<HalRevision>(jHalRev);
 
@@ -331,16 +334,16 @@
 }
 
 static void nativeFinalize(JNIEnv *env, jobject obj, jlong nativeContext) {
-    ALOGV("nativeFinalize()");
-    AutoMutex _l(gContextMutex);
+    ALOGV("%s", __func__);
+    lock_guard<mutex> lk(gContextMutex);
 
     auto ctx = reinterpret_cast<TunerCallbackContext*>(nativeContext);
     delete ctx;
 }
 
 static void nativeDetach(JNIEnv *env, jobject obj, jlong nativeContext) {
-    ALOGV("nativeDetach()");
-    AutoMutex _l(gContextMutex);
+    ALOGV("%s", __func__);
+    lock_guard<mutex> lk(gContextMutex);
     auto& ctx = getNativeContext(nativeContext);
 
     if (ctx.mNativeCallback == nullptr) return;
@@ -349,7 +352,7 @@
 }
 
 sp<ITunerCallback> getNativeCallback(JNIEnv *env, jobject jTunerCallback) {
-    AutoMutex _l(gContextMutex);
+    lock_guard<mutex> lk(gContextMutex);
     auto& ctx = getNativeContext(env, jTunerCallback);
     return ctx.mNativeCallback;
 }
diff --git a/services/core/jni/BroadcastRadio/convert.cpp b/services/core/jni/BroadcastRadio/convert.cpp
index a2e5643..ba1395f73 100644
--- a/services/core/jni/BroadcastRadio/convert.cpp
+++ b/services/core/jni/BroadcastRadio/convert.cpp
@@ -19,9 +19,9 @@
 
 #include "convert.h"
 
-#include <JNIHelp.h>
-#include <Utils.h>
+#include <broadcastradio-utils/Utils.h>
 #include <core_jni_helpers.h>
+#include <nativehelper/JNIHelp.h>
 #include <utils/Log.h>
 
 namespace android {
@@ -262,7 +262,7 @@
 
 static JavaRef<jobject> ModulePropertiesFromHal(JNIEnv *env, const V1_0::Properties &prop10,
         const V1_1::Properties *prop11, jint moduleId, const std::string& serviceName) {
-    ALOGV("ModulePropertiesFromHal()");
+    ALOGV("%s", __func__);
     using namespace std::placeholders;
 
     auto jServiceName = make_javastr(env, serviceName);
@@ -298,7 +298,7 @@
 }
 
 static JavaRef<jobject> BandDescriptorFromHal(JNIEnv *env, const V1_0::BandConfig &config, Region region) {
-    ALOGV("BandDescriptorFromHal()");
+    ALOGV("%s", __func__);
 
     jint spacing = config.spacings.size() > 0 ? config.spacings[0] : 0;
     ALOGW_IF(config.spacings.size() == 0, "No channel spacing specified");
@@ -327,7 +327,7 @@
 }
 
 JavaRef<jobject> BandConfigFromHal(JNIEnv *env, const V1_0::BandConfig &config, Region region) {
-    ALOGV("BandConfigFromHal()");
+    ALOGV("%s", __func__);
 
     auto descriptor = BandDescriptorFromHal(env, config, region);
     if (descriptor == nullptr) return nullptr;
@@ -350,7 +350,7 @@
 }
 
 V1_0::BandConfig BandConfigToHal(JNIEnv *env, jobject jConfig, Region &region) {
-    ALOGV("BandConfigToHal()");
+    ALOGV("%s", __func__);
     auto jDescriptor = env->GetObjectField(jConfig, gjni.BandConfig.descriptor);
     if (jDescriptor == nullptr) {
         ALOGE("Descriptor is missing");
@@ -392,7 +392,7 @@
 }
 
 JavaRef<jobject> MetadataFromHal(JNIEnv *env, const hidl_vec<V1_0::MetaData> &metadata) {
-    ALOGV("MetadataFromHal()");
+    ALOGV("%s", __func__);
     if (metadata.size() == 0) return nullptr;
 
     auto jMetadata = make_javaref(env, env->NewObject(
@@ -445,13 +445,13 @@
 }
 
 static JavaRef<jobject> ProgramIdentifierFromHal(JNIEnv *env, const ProgramIdentifier &id) {
-    ALOGV("ProgramIdentifierFromHal()");
+    ALOGV("%s", __func__);
     return make_javaref(env, env->NewObject(gjni.ProgramSelector.Identifier.clazz,
             gjni.ProgramSelector.Identifier.cstor, id.type, id.value));
 }
 
 static JavaRef<jobject> ProgramSelectorFromHal(JNIEnv *env, const ProgramSelector &selector) {
-    ALOGV("ProgramSelectorFromHal()");
+    ALOGV("%s", __func__);
     auto jPrimary = ProgramIdentifierFromHal(env, selector.primaryId);
     auto jSecondary = ArrayFromHal(env, selector.secondaryIds,
             gjni.ProgramSelector.Identifier.clazz, ProgramIdentifierFromHal);
@@ -462,7 +462,7 @@
 }
 
 static ProgramIdentifier ProgramIdentifierToHal(JNIEnv *env, jobject jId) {
-    ALOGV("ProgramIdentifierToHal()");
+    ALOGV("%s", __func__);
 
     ProgramIdentifier id = {};
     id.type = env->GetIntField(jId, gjni.ProgramSelector.Identifier.type);
@@ -471,7 +471,7 @@
 }
 
 ProgramSelector ProgramSelectorToHal(JNIEnv *env, jobject jSelector) {
-    ALOGV("ProgramSelectorToHal()");
+    ALOGV("%s", __func__);
 
     ProgramSelector selector = {};
 
@@ -509,7 +509,7 @@
 
 static JavaRef<jobject> ProgramInfoFromHal(JNIEnv *env, const V1_0::ProgramInfo &info10,
         const V1_1::ProgramInfo *info11, const ProgramSelector &selector) {
-    ALOGV("ProgramInfoFromHal()");
+    ALOGV("%s", __func__);
 
     auto jMetadata = MetadataFromHal(env, info10.metadata);
     auto jVendorInfo = info11 ? make_javastr(env, info11->vendorInfo) : nullptr;
diff --git a/wifi/java/android/net/wifi/IRttManager.aidl b/wifi/java/android/net/wifi/IRttManager.aidl
index 90f66c4..3831809 100644
--- a/wifi/java/android/net/wifi/IRttManager.aidl
+++ b/wifi/java/android/net/wifi/IRttManager.aidl
@@ -23,6 +23,6 @@
  */
 interface IRttManager
 {
-    Messenger getMessenger();
+    Messenger getMessenger(in IBinder binder, out int[] key);
     RttManager.RttCapabilities getRttCapabilities();
 }
diff --git a/wifi/java/android/net/wifi/RttManager.java b/wifi/java/android/net/wifi/RttManager.java
index a4b3bf2a..ac5df05 100644
--- a/wifi/java/android/net/wifi/RttManager.java
+++ b/wifi/java/android/net/wifi/RttManager.java
@@ -6,6 +6,7 @@
 import android.annotation.SystemApi;
 import android.annotation.SystemService;
 import android.content.Context;
+import android.os.Binder;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.Looper;
@@ -1187,6 +1188,8 @@
             CMD_OP_ENALBE_RESPONDER_SUCCEEDED           = BASE + 7;
     public static final int
             CMD_OP_ENALBE_RESPONDER_FAILED              = BASE + 8;
+    /** @hide */
+    public static final int CMD_OP_REG_BINDER           = BASE + 9;
 
     private static final int INVALID_KEY = 0;
 
@@ -1215,9 +1218,10 @@
         mContext = context;
         mService = service;
         Messenger messenger = null;
+        int[] key = new int[1];
         try {
             Log.d(TAG, "Get the messenger from " + mService);
-            messenger = mService.getMessenger();
+            messenger = mService.getMessenger(new Binder(), key);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -1233,6 +1237,7 @@
         // We cannot use fullyConnectSync because it sends the FULL_CONNECTION message
         // synchronously, which causes RttService to receive the wrong replyTo value.
         mAsyncChannel.sendMessage(AsyncChannel.CMD_CHANNEL_FULL_CONNECTION);
+        mAsyncChannel.sendMessage(CMD_OP_REG_BINDER, key[0]);
     }
 
     private void validateChannel() {