なぜBLEペアリング時に連絡先と通話履歴のアクセスパーミッションが要求されるのか

# はじめに
* AndroidではBLEペアリング時にペアリングの許可を求めるダイアログが表示されますが、連絡先や通話履歴にアクセスするアプリではないのにも関わらず以下のような要求が表示されることがあります。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/296478/9063f6fe-2d8b-c1c3-fbe8-3a859d7af1c2.jpeg" width=50%>

* このチェックボックスが表示されてしまう理由について調べたことを備忘録的に残しておきます。
* この記事にはチェックボックスを消す方法については書いていません。

# 関連記事
* 同様の質問がポストされているものの、2017年時点ではチェックボックスを消す方法は無いとのこと。
  * https://stackoverflow.com/questions/42647579/change-pairing-dialog-appearance-in-android

* ペアリングプロセスを自前で実装すれば、そもそもポップアップ自体をなくすことができるらしい。
  * https://stackoverflow.com/questions/50217230/ble-pairing-confirmation-dialog
  * https://stackoverflow.com/questions/48375624/bluetooth-pairing-with-nrf-uart-is-not-working-properly/48378224#48378224
  * ただシステムアプリのみが設定できる"BLUETOOTH_PRIVILEGED"をマニフェストに追加する必要があるとのことで、一般的なアプリではできないのでは？
  * 今回はチェックボックスが表示される理由を調べたいのでちゃんとは読んでません。

# Androidのソースコード
* ダイアログ中のメッセージは以下に定義されていています。
  * [/packages/apps/Settings/res/values/strings.xml](https://search.siprop.org/android-9.0.0_r1.0/xref/packages/apps/Settings/res/values-ja/strings.xml)
  
```xml
<string name="bluetooth_pairing_shares_phonebook" msgid="9082518313285787097">"連絡先と通話履歴へのアクセスを許可する"</string>
```

* 以下の箇所でポップアップを生成しており、このメッセージをチェックボックスと共に表示しているようです。
* 
  * [/packages/apps/Settings/src/com/android/settings/bluetooth/BluetoothPairingDialogFragment.java](https://search.siprop.org/android-9.0.0_r1.0/xref/packages/apps/Settings/src/com/android/settings/bluetooth/BluetoothPairingDialogFragment.java)
  * コード内の*isProfileReady*がtrueの時にチェックボックスはinvisibleになり、表示されなくなるもとの思われます。

```java
/**
 * Creates the custom view with UI elements for user input.
 */
private View createPinEntryView() {
    View view = getActivity().getLayoutInflater().inflate(R.layout.bluetooth_pin_entry, null);
    TextView messageViewCaptionHint = (TextView) view.findViewById(R.id.pin_values_hint);
    TextView messageView2 = (TextView) view.findViewById(R.id.message_below_pin);
    CheckBox alphanumericPin = (CheckBox) view.findViewById(R.id.alphanumeric_pin);
    CheckBox contactSharing = (CheckBox) view.findViewById(
            R.id.phonebook_sharing_message_entry_pin);
    contactSharing.setText(getString(R.string.bluetooth_pairing_shares_phonebook,
            mPairingController.getDeviceName()));
    EditText pairingView = (EditText) view.findViewById(R.id.tex
    contactSharing.setVisibility(mPairingController.isProfileReady()
            ? View.GONE : View.VISIBLE);
    mPairingController.setContactSharingState();
    contactSharing.setOnCheckedChangeListener(mPairingController);
    contactSharing.setChecked(mPairingController.getContactSharingState(
    mPairingView = pairingView;
```

* コメントによると*isProfileReady*の戻り値は、Bluetooth Deviceのプロファイルが端末にセットアップされているか否かで決まるようです。
  * [/packages/apps/Settings/src/com/android/settings/bluetooth/BluetoothPairingController.java](https://search.siprop.org/android-9.0.0_r1.0/xref/packages/apps/Settings/src/com/android/settings/bluetooth/BluetoothPairingController.java)

```java
/**
 * A method for querying if the bluetooth device has a profile already set up on this device.
 *
 * @return - A boolean indicating if the device has previous knowledge of a profile for this
 * device.
 */
public boolean isProfileReady() {
    return mPbapClientProfile != null && mPbapClientProfile.isProfileReady();
}
```

# 考察
* 端末が対応するプロファイルは機種ごとに決められているので、対応していないプロファイルの場合はとりあえず連絡先と通話履歴のアクセス権をリクエストするという仕様？（間違っていたら修正します。）
  * AQUOS sense2 SH-01Lの例 (https://jp.sharp/products/sh01l/spec.html)
 　![sh01l_profile.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/296478/6e345a71-2f73-b8ee-0ef4-13745f251c15.png)

  * そうだとすると、アプリが使うかどうかもわからないのに連絡先と通話履歴の権限を要求するのは不自然な気がする。
    * Androidのプロファイル周りについて("previous knowlege of a profile"とは？等)もう少し理解を深める必要はありそう。