content: /*
   * Copyright (C) 2019 The Android Open Source Project
   *
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   *      http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  
  
  package com.android.internal.telephony;
  
  import android.app.ActivityThread;
  import android.app.PendingIntent;
  import android.bluetooth.BluetoothAdapter;
  import android.bluetooth.BluetoothDevice;
  import android.bluetooth.BluetoothMapClient;
  import android.bluetooth.BluetoothProfile;
  import android.net.Uri;
  import android.telecom.PhoneAccount;
  import android.telephony.SmsManager;
  import android.telephony.SubscriptionInfo;
  import android.util.Log;
  
  
  /**
   * BtSmsInterfaceManager to provide a mechanism for sending SMS over Bluetooth
   */
  public class BtSmsInterfaceManager {
  
      private static final String LOG_TAG = "BtSmsInterfaceManager";
  
      /**
       * Sends text through connected Bluetooth device
       */
      public void sendText(String destAddr, String text, PendingIntent sentIntent,
              PendingIntent deliveryIntent, SubscriptionInfo info) {
          BluetoothAdapter btAdapter = BluetoothAdapter.getDefaultAdapter();
          if (btAdapter == null) {
              // No bluetooth service on this platform?
              sendErrorInPendingIntent(sentIntent, SmsManager.RESULT_ERROR_NO_SERVICE);
              return;
          }
          BluetoothDevice device = btAdapter.getRemoteDevice(info.getIccId());
          if (device == null) {
              Log.d(LOG_TAG, "Bluetooth device addr invalid: " + info.getIccId());
              sendErrorInPendingIntent(sentIntent, SmsManager.RESULT_ERROR_NO_SERVICE);
              return;
          }
          btAdapter.getProfileProxy(ActivityThread.currentApplication().getApplicationContext(),
                  new MapMessageSender(destAddr, text, device, sentIntent, deliveryIntent),
                  BluetoothProfile.MAP_CLIENT);
      }
  
      private void sendErrorInPendingIntent(PendingIntent intent, int errorCode) {
          if (intent == null) {
              return;
          }
          try {
              intent.send(errorCode);
          } catch (PendingIntent.CanceledException e) {
              // PendingIntent is cancelled. ignore sending this error code back to
              // caller.
              Log.d(LOG_TAG, "PendingIntent.CanceledException: " + e.getMessage());
          }
      }
  
      private class MapMessageSender implements BluetoothProfile.ServiceListener {
  
          final Uri[] mDestAddr;
          private String mMessage;
          final BluetoothDevice mDevice;
          final PendingIntent mSentIntent;
          final PendingIntent mDeliveryIntent;
  
          MapMessageSender(final String destAddr, final String message, final BluetoothDevice device,
                  final PendingIntent sentIntent, final PendingIntent deliveryIntent) {
              super();
              mDestAddr = new Uri[]{new Uri.Builder()
                      .appendPath(destAddr)
                      .scheme(PhoneAccount.SCHEME_TEL)
                      .build()};
              mMessage = message;
              mDevice = device;
              mSentIntent = sentIntent;
              mDeliveryIntent = deliveryIntent;
          }
  
          @Override
          public void onServiceConnected(int profile, BluetoothProfile proxy) {
              Log.d(LOG_TAG, "Service connected");
              if (profile != BluetoothProfile.MAP_CLIENT) {
                  return;
              }
              BluetoothMapClient mapProfile = (BluetoothMapClient) proxy;
              if (mMessage != null) {
                  Log.d(LOG_TAG, "Sending message thru bluetooth");
                  mapProfile.sendMessage(mDevice, mDestAddr, mMessage, mSentIntent, mDeliveryIntent);
                  mMessage = null;
              }
              BluetoothAdapter.getDefaultAdapter()
                      .closeProfileProxy(BluetoothProfile.MAP_CLIENT, mapProfile);
          }
  
          @Override
          public void onServiceDisconnected(int profile) {
              if (mMessage != null) {
                  Log.d(LOG_TAG, "Bluetooth disconnected before sending the message");
                  sendErrorInPendingIntent(mSentIntent, SmsManager.RESULT_ERROR_NO_SERVICE);
                  mMessage = null;
              }
          }
      }
  }
  