Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b8e7d3e2 authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge "Avrcp: Fix the potential NPE in AvrcpController jni callback"

parents b99d9e62 6c40ed9b
Loading
Loading
Loading
Loading
+91 −2
Original line number Original line Diff line number Diff line
@@ -24,6 +24,7 @@
#include "utils/Log.h"
#include "utils/Log.h"


#include <string.h>
#include <string.h>
#include <shared_mutex>


namespace android {
namespace android {
static jmethodID method_handlePassthroughRsp;
static jmethodID method_handlePassthroughRsp;
@@ -54,12 +55,18 @@ static jclass class_AvrcpPlayer;


static const btrc_ctrl_interface_t* sBluetoothAvrcpInterface = NULL;
static const btrc_ctrl_interface_t* sBluetoothAvrcpInterface = NULL;
static jobject sCallbacksObj = NULL;
static jobject sCallbacksObj = NULL;
static std::shared_timed_mutex sCallbacks_mutex;


static void btavrcp_passthrough_response_callback(const RawAddress& bd_addr,
static void btavrcp_passthrough_response_callback(const RawAddress& bd_addr,
                                                  int id, int pressed) {
                                                  int id, int pressed) {
  ALOGI("%s: id: %d, pressed: %d", __func__, id, pressed);
  ALOGI("%s: id: %d, pressed: %d", __func__, id, pressed);
  std::shared_lock<std::shared_timed_mutex> lock(sCallbacks_mutex);
  CallbackEnv sCallbackEnv(__func__);
  CallbackEnv sCallbackEnv(__func__);
  if (!sCallbackEnv.valid()) return;
  if (!sCallbackEnv.valid()) return;
  if (!sCallbacksObj) {
    ALOGE("%s: sCallbacksObj is null", __func__);
    return;
  }


  ScopedLocalRef<jbyteArray> addr(
  ScopedLocalRef<jbyteArray> addr(
      sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress)));
      sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress)));
@@ -76,8 +83,13 @@ static void btavrcp_passthrough_response_callback(const RawAddress& bd_addr,


static void btavrcp_groupnavigation_response_callback(int id, int pressed) {
static void btavrcp_groupnavigation_response_callback(int id, int pressed) {
  ALOGV("%s", __func__);
  ALOGV("%s", __func__);
  std::shared_lock<std::shared_timed_mutex> lock(sCallbacks_mutex);
  CallbackEnv sCallbackEnv(__func__);
  CallbackEnv sCallbackEnv(__func__);
  if (!sCallbackEnv.valid()) return;
  if (!sCallbackEnv.valid()) return;
  if (!sCallbacksObj) {
    ALOGE("%s: sCallbacksObj is null", __func__);
    return;
  }


  sCallbackEnv->CallVoidMethod(sCallbacksObj, method_handleGroupNavigationRsp,
  sCallbackEnv->CallVoidMethod(sCallbacksObj, method_handleGroupNavigationRsp,
                               (jint)id, (jint)pressed);
                               (jint)id, (jint)pressed);
@@ -86,8 +98,13 @@ static void btavrcp_groupnavigation_response_callback(int id, int pressed) {
static void btavrcp_connection_state_callback(bool rc_connect, bool br_connect,
static void btavrcp_connection_state_callback(bool rc_connect, bool br_connect,
                                              const RawAddress& bd_addr) {
                                              const RawAddress& bd_addr) {
  ALOGI("%s: conn state: rc: %d br: %d", __func__, rc_connect, br_connect);
  ALOGI("%s: conn state: rc: %d br: %d", __func__, rc_connect, br_connect);
  std::shared_lock<std::shared_timed_mutex> lock(sCallbacks_mutex);
  CallbackEnv sCallbackEnv(__func__);
  CallbackEnv sCallbackEnv(__func__);
  if (!sCallbackEnv.valid()) return;
  if (!sCallbackEnv.valid()) return;
  if (!sCallbacksObj) {
    ALOGE("%s: sCallbacksObj is null", __func__);
    return;
  }


  ScopedLocalRef<jbyteArray> addr(
  ScopedLocalRef<jbyteArray> addr(
      sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress)));
      sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress)));
@@ -106,8 +123,13 @@ static void btavrcp_connection_state_callback(bool rc_connect, bool br_connect,
static void btavrcp_get_rcfeatures_callback(const RawAddress& bd_addr,
static void btavrcp_get_rcfeatures_callback(const RawAddress& bd_addr,
                                            int features) {
                                            int features) {
  ALOGV("%s", __func__);
  ALOGV("%s", __func__);
  std::shared_lock<std::shared_timed_mutex> lock(sCallbacks_mutex);
  CallbackEnv sCallbackEnv(__func__);
  CallbackEnv sCallbackEnv(__func__);
  if (!sCallbackEnv.valid()) return;
  if (!sCallbackEnv.valid()) return;
  if (!sCallbacksObj) {
    ALOGE("%s: sCallbacksObj is null", __func__);
    return;
  }


  ScopedLocalRef<jbyteArray> addr(
  ScopedLocalRef<jbyteArray> addr(
      sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress)));
      sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress)));
@@ -125,8 +147,13 @@ static void btavrcp_get_rcfeatures_callback(const RawAddress& bd_addr,
static void btavrcp_setplayerapplicationsetting_rsp_callback(
static void btavrcp_setplayerapplicationsetting_rsp_callback(
    const RawAddress& bd_addr, uint8_t accepted) {
    const RawAddress& bd_addr, uint8_t accepted) {
  ALOGV("%s", __func__);
  ALOGV("%s", __func__);
  std::shared_lock<std::shared_timed_mutex> lock(sCallbacks_mutex);
  CallbackEnv sCallbackEnv(__func__);
  CallbackEnv sCallbackEnv(__func__);
  if (!sCallbackEnv.valid()) return;
  if (!sCallbackEnv.valid()) return;
  if (!sCallbacksObj) {
    ALOGE("%s: sCallbacksObj is null", __func__);
    return;
  }


  ScopedLocalRef<jbyteArray> addr(
  ScopedLocalRef<jbyteArray> addr(
      sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress)));
      sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress)));
@@ -146,8 +173,13 @@ static void btavrcp_playerapplicationsetting_callback(
    btrc_player_app_attr_t* app_attrs, uint8_t num_ext_attr,
    btrc_player_app_attr_t* app_attrs, uint8_t num_ext_attr,
    btrc_player_app_ext_attr_t* ext_attrs) {
    btrc_player_app_ext_attr_t* ext_attrs) {
  ALOGI("%s", __func__);
  ALOGI("%s", __func__);
  std::shared_lock<std::shared_timed_mutex> lock(sCallbacks_mutex);
  CallbackEnv sCallbackEnv(__func__);
  CallbackEnv sCallbackEnv(__func__);
  if (!sCallbackEnv.valid()) return;
  if (!sCallbackEnv.valid()) return;
  if (!sCallbacksObj) {
    ALOGE("%s: sCallbacksObj is null", __func__);
    return;
  }


  ScopedLocalRef<jbyteArray> addr(
  ScopedLocalRef<jbyteArray> addr(
      sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress)));
      sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress)));
@@ -193,8 +225,13 @@ static void btavrcp_playerapplicationsetting_callback(
static void btavrcp_playerapplicationsetting_changed_callback(
static void btavrcp_playerapplicationsetting_changed_callback(
    const RawAddress& bd_addr, const btrc_player_settings_t& vals) {
    const RawAddress& bd_addr, const btrc_player_settings_t& vals) {
  ALOGI("%s", __func__);
  ALOGI("%s", __func__);
  std::shared_lock<std::shared_timed_mutex> lock(sCallbacks_mutex);
  CallbackEnv sCallbackEnv(__func__);
  CallbackEnv sCallbackEnv(__func__);
  if (!sCallbackEnv.valid()) return;
  if (!sCallbackEnv.valid()) return;
  if (!sCallbacksObj) {
    ALOGE("%s: sCallbacksObj is null", __func__);
    return;
  }


  ScopedLocalRef<jbyteArray> addr(
  ScopedLocalRef<jbyteArray> addr(
      sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress)));
      sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress)));
@@ -231,8 +268,13 @@ static void btavrcp_playerapplicationsetting_changed_callback(
static void btavrcp_set_abs_vol_cmd_callback(const RawAddress& bd_addr,
static void btavrcp_set_abs_vol_cmd_callback(const RawAddress& bd_addr,
                                             uint8_t abs_vol, uint8_t label) {
                                             uint8_t abs_vol, uint8_t label) {
  ALOGI("%s", __func__);
  ALOGI("%s", __func__);
  std::shared_lock<std::shared_timed_mutex> lock(sCallbacks_mutex);
  CallbackEnv sCallbackEnv(__func__);
  CallbackEnv sCallbackEnv(__func__);
  if (!sCallbackEnv.valid()) return;
  if (!sCallbackEnv.valid()) return;
  if (!sCallbacksObj) {
    ALOGE("%s: sCallbacksObj is null", __func__);
    return;
  }


  ScopedLocalRef<jbyteArray> addr(
  ScopedLocalRef<jbyteArray> addr(
      sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress)));
      sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress)));
@@ -250,8 +292,13 @@ static void btavrcp_set_abs_vol_cmd_callback(const RawAddress& bd_addr,
static void btavrcp_register_notification_absvol_callback(
static void btavrcp_register_notification_absvol_callback(
    const RawAddress& bd_addr, uint8_t label) {
    const RawAddress& bd_addr, uint8_t label) {
  ALOGI("%s", __func__);
  ALOGI("%s", __func__);
  std::shared_lock<std::shared_timed_mutex> lock(sCallbacks_mutex);
  CallbackEnv sCallbackEnv(__func__);
  CallbackEnv sCallbackEnv(__func__);
  if (!sCallbackEnv.valid()) return;
  if (!sCallbackEnv.valid()) return;
  if (!sCallbacksObj) {
    ALOGE("%s: sCallbacksObj is null", __func__);
    return;
  }


  ScopedLocalRef<jbyteArray> addr(
  ScopedLocalRef<jbyteArray> addr(
      sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress)));
      sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress)));
@@ -275,8 +322,13 @@ static void btavrcp_track_changed_callback(const RawAddress& bd_addr,
   * Assuming text feild to be null terminated.
   * Assuming text feild to be null terminated.
   */
   */
  ALOGI("%s", __func__);
  ALOGI("%s", __func__);
  std::shared_lock<std::shared_timed_mutex> lock(sCallbacks_mutex);
  CallbackEnv sCallbackEnv(__func__);
  CallbackEnv sCallbackEnv(__func__);
  if (!sCallbackEnv.valid()) return;
  if (!sCallbackEnv.valid()) return;
  if (!sCallbacksObj) {
    ALOGE("%s: sCallbacksObj is null", __func__);
    return;
  }


  ScopedLocalRef<jbyteArray> addr(
  ScopedLocalRef<jbyteArray> addr(
      sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress)));
      sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress)));
@@ -325,8 +377,13 @@ static void btavrcp_play_position_changed_callback(const RawAddress& bd_addr,
                                                   uint32_t song_len,
                                                   uint32_t song_len,
                                                   uint32_t song_pos) {
                                                   uint32_t song_pos) {
  ALOGI("%s", __func__);
  ALOGI("%s", __func__);
  std::shared_lock<std::shared_timed_mutex> lock(sCallbacks_mutex);
  CallbackEnv sCallbackEnv(__func__);
  CallbackEnv sCallbackEnv(__func__);
  if (!sCallbackEnv.valid()) return;
  if (!sCallbackEnv.valid()) return;
  if (!sCallbacksObj) {
    ALOGE("%s: sCallbacksObj is null", __func__);
    return;
  }


  ScopedLocalRef<jbyteArray> addr(
  ScopedLocalRef<jbyteArray> addr(
      sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress)));
      sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress)));
@@ -343,8 +400,13 @@ static void btavrcp_play_position_changed_callback(const RawAddress& bd_addr,
static void btavrcp_play_status_changed_callback(
static void btavrcp_play_status_changed_callback(
    const RawAddress& bd_addr, btrc_play_status_t play_status) {
    const RawAddress& bd_addr, btrc_play_status_t play_status) {
  ALOGI("%s", __func__);
  ALOGI("%s", __func__);
  std::shared_lock<std::shared_timed_mutex> lock(sCallbacks_mutex);
  CallbackEnv sCallbackEnv(__func__);
  CallbackEnv sCallbackEnv(__func__);
  if (!sCallbackEnv.valid()) return;
  if (!sCallbackEnv.valid()) return;
  if (!sCallbacksObj) {
    ALOGE("%s: sCallbacksObj is null", __func__);
    return;
  }


  ScopedLocalRef<jbyteArray> addr(
  ScopedLocalRef<jbyteArray> addr(
      sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress)));
      sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress)));
@@ -366,8 +428,13 @@ static void btavrcp_get_folder_items_callback(
   * counterparts by calling the java constructor for each of the items.
   * counterparts by calling the java constructor for each of the items.
   */
   */
  ALOGV("%s count %d", __func__, count);
  ALOGV("%s count %d", __func__, count);
  std::shared_lock<std::shared_timed_mutex> lock(sCallbacks_mutex);
  CallbackEnv sCallbackEnv(__func__);
  CallbackEnv sCallbackEnv(__func__);
  if (!sCallbackEnv.valid()) return;
  if (!sCallbackEnv.valid()) return;
  if (!sCallbacksObj) {
    ALOGE("%s: sCallbacksObj is null", __func__);
    return;
  }


  // Inspect if the first element is a folder/item or player listing. They are
  // Inspect if the first element is a folder/item or player listing. They are
  // always exclusive.
  // always exclusive.
@@ -552,8 +619,13 @@ static void btavrcp_get_folder_items_callback(
static void btavrcp_change_path_callback(const RawAddress& bd_addr,
static void btavrcp_change_path_callback(const RawAddress& bd_addr,
                                         uint32_t count) {
                                         uint32_t count) {
  ALOGI("%s count %d", __func__, count);
  ALOGI("%s count %d", __func__, count);
  std::shared_lock<std::shared_timed_mutex> lock(sCallbacks_mutex);
  CallbackEnv sCallbackEnv(__func__);
  CallbackEnv sCallbackEnv(__func__);
  if (!sCallbackEnv.valid()) return;
  if (!sCallbackEnv.valid()) return;
  if (!sCallbacksObj) {
    ALOGE("%s: sCallbacksObj is null", __func__);
    return;
  }


  sCallbackEnv->CallVoidMethod(sCallbacksObj, method_handleChangeFolderRsp,
  sCallbackEnv->CallVoidMethod(sCallbacksObj, method_handleChangeFolderRsp,
                               (jint)count);
                               (jint)count);
@@ -563,8 +635,13 @@ static void btavrcp_set_browsed_player_callback(const RawAddress& bd_addr,
                                                uint8_t num_items,
                                                uint8_t num_items,
                                                uint8_t depth) {
                                                uint8_t depth) {
  ALOGI("%s items %d depth %d", __func__, num_items, depth);
  ALOGI("%s items %d depth %d", __func__, num_items, depth);
  std::shared_lock<std::shared_timed_mutex> lock(sCallbacks_mutex);
  CallbackEnv sCallbackEnv(__func__);
  CallbackEnv sCallbackEnv(__func__);
  if (!sCallbackEnv.valid()) return;
  if (!sCallbackEnv.valid()) return;
  if (!sCallbacksObj) {
    ALOGE("%s: sCallbacksObj is null", __func__);
    return;
  }


  sCallbackEnv->CallVoidMethod(sCallbacksObj, method_handleSetBrowsedPlayerRsp,
  sCallbackEnv->CallVoidMethod(sCallbacksObj, method_handleSetBrowsedPlayerRsp,
                               (jint)num_items, (jint)depth);
                               (jint)num_items, (jint)depth);
@@ -573,9 +650,13 @@ static void btavrcp_set_browsed_player_callback(const RawAddress& bd_addr,
static void btavrcp_set_addressed_player_callback(const RawAddress& bd_addr,
static void btavrcp_set_addressed_player_callback(const RawAddress& bd_addr,
                                                  uint8_t status) {
                                                  uint8_t status) {
  ALOGI("%s status %d", __func__, status);
  ALOGI("%s status %d", __func__, status);

  std::shared_lock<std::shared_timed_mutex> lock(sCallbacks_mutex);
  CallbackEnv sCallbackEnv(__func__);
  CallbackEnv sCallbackEnv(__func__);
  if (!sCallbackEnv.valid()) return;
  if (!sCallbackEnv.valid()) return;
  if (!sCallbacksObj) {
    ALOGE("%s: sCallbacksObj is null", __func__);
    return;
  }


  sCallbackEnv->CallVoidMethod(
  sCallbackEnv->CallVoidMethod(
      sCallbacksObj, method_handleSetAddressedPlayerRsp, (jint)status);
      sCallbacksObj, method_handleSetAddressedPlayerRsp, (jint)status);
@@ -584,9 +665,13 @@ static void btavrcp_set_addressed_player_callback(const RawAddress& bd_addr,
static void btavrcp_addressed_player_changed_callback(const RawAddress& bd_addr,
static void btavrcp_addressed_player_changed_callback(const RawAddress& bd_addr,
                                                      uint16_t id) {
                                                      uint16_t id) {
  ALOGI("%s status %d", __func__, id);
  ALOGI("%s status %d", __func__, id);

  std::shared_lock<std::shared_timed_mutex> lock(sCallbacks_mutex);
  CallbackEnv sCallbackEnv(__func__);
  CallbackEnv sCallbackEnv(__func__);
  if (!sCallbackEnv.valid()) return;
  if (!sCallbackEnv.valid()) return;
  if (!sCallbacksObj) {
    ALOGE("%s: sCallbacksObj is null", __func__);
    return;
  }


  sCallbackEnv->CallVoidMethod(sCallbacksObj,
  sCallbackEnv->CallVoidMethod(sCallbacksObj,
                               method_handleAddressedPlayerChanged, (jint)id);
                               method_handleAddressedPlayerChanged, (jint)id);
@@ -693,6 +778,8 @@ static void classInitNative(JNIEnv* env, jclass clazz) {
}
}


static void initNative(JNIEnv* env, jobject object) {
static void initNative(JNIEnv* env, jobject object) {
  std::unique_lock<std::shared_timed_mutex> lock(sCallbacks_mutex);

  jclass tmpMediaItem =
  jclass tmpMediaItem =
      env->FindClass("android/media/browse/MediaBrowser$MediaItem");
      env->FindClass("android/media/browse/MediaBrowser$MediaItem");
  class_MediaBrowser_MediaItem = (jclass)env->NewGlobalRef(tmpMediaItem);
  class_MediaBrowser_MediaItem = (jclass)env->NewGlobalRef(tmpMediaItem);
@@ -740,6 +827,8 @@ static void initNative(JNIEnv* env, jobject object) {
}
}


static void cleanupNative(JNIEnv* env, jobject object) {
static void cleanupNative(JNIEnv* env, jobject object) {
  std::unique_lock<std::shared_timed_mutex> lock(sCallbacks_mutex);

  const bt_interface_t* btInf = getBluetoothInterface();
  const bt_interface_t* btInf = getBluetoothInterface();
  if (btInf == NULL) {
  if (btInf == NULL) {
    ALOGE("Bluetooth module is not loaded");
    ALOGE("Bluetooth module is not loaded");