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

Commit f657aa62 authored by Charlie Boutier's avatar Charlie Boutier Committed by Gerrit Code Review
Browse files

Merge "Pandora: Do not crash when a profile proxy is null"

parents 0e863b59 f6f27616
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@ import android.media.*
import android.util.Log
import io.grpc.Status
import io.grpc.stub.StreamObserver
import java.io.Closeable
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.cancel
@@ -41,7 +42,7 @@ import pandora.A2DPGrpc.A2DPImplBase
import pandora.A2dpProto.*

@kotlinx.coroutines.ExperimentalCoroutinesApi
class A2dp(val context: Context) : A2DPImplBase() {
class A2dp(val context: Context) : A2DPImplBase(), Closeable {
  private val TAG = "PandoraA2dp"

  private val scope: CoroutineScope
@@ -64,7 +65,7 @@ class A2dp(val context: Context) : A2DPImplBase() {
    flow = intentFlow(context, intentFilter).shareIn(scope, SharingStarted.Eagerly)
  }

  fun deinit() {
  override fun close() {
    bluetoothAdapter.closeProfileProxy(BluetoothProfile.A2DP, bluetoothA2dp)
    scope.cancel()
  }
+3 −2
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@ import android.media.*
import android.util.Log
import io.grpc.Status
import io.grpc.stub.StreamObserver
import java.io.Closeable
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.cancel
@@ -40,7 +41,7 @@ import pandora.A2DPGrpc.A2DPImplBase
import pandora.A2dpProto.*

@kotlinx.coroutines.ExperimentalCoroutinesApi
class A2dpSink(val context: Context) : A2DPImplBase() {
class A2dpSink(val context: Context) : A2DPImplBase(), Closeable {
  private val TAG = "PandoraA2dpSink"

  private val scope: CoroutineScope
@@ -59,7 +60,7 @@ class A2dpSink(val context: Context) : A2DPImplBase() {
    flow = intentFlow(context, intentFilter).shareIn(scope, SharingStarted.Eagerly)
  }

  fun deinit() {
  override fun close() {
    bluetoothAdapter.closeProfileProxy(BluetoothProfile.A2DP_SINK, bluetoothA2dpSink)
    scope.cancel()
  }
+61 −33
Original line number Diff line number Diff line
@@ -16,34 +16,33 @@

package com.android.pandora

import android.util.Log
import android.bluetooth.BluetoothDevice
import android.bluetooth.BluetoothManager
import android.content.ComponentName
import android.content.ContentUris
import android.content.Context
import com.google.protobuf.Empty
import io.grpc.stub.StreamObserver
import android.content.Intent
import android.graphics.Bitmap
import android.os.Environment
import android.provider.MediaStore.Images.Media
import android.provider.MediaStore.MediaColumns
import android.provider.Telephony.*
import android.telephony.SmsManager
import android.telephony.SubscriptionManager
import android.telephony.TelephonyManager
import android.content.Intent
import android.content.ComponentName
import android.content.ContentUris
import java.io.File
import java.io.FileOutputStream
import android.provider.MediaStore.Images.Media
import android.provider.MediaStore.MediaColumns
import android.net.Uri
import kotlinx.coroutines.async
import android.bluetooth.BluetoothAdapter
import android.bluetooth.BluetoothDevice
import android.bluetooth.BluetoothManager
import android.util.Log
import androidx.test.InstrumentationRegistry
import androidx.test.uiautomator.By
import androidx.test.uiautomator.UiDevice
import androidx.test.uiautomator.Until
import com.google.protobuf.Empty
import io.grpc.stub.StreamObserver
import java.io.Closeable
import java.io.File
import java.io.FileOutputStream
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.async
import kotlinx.coroutines.cancel
import pandora.AndroidGrpc.AndroidImplBase
import pandora.AndroidProto.*
@@ -51,7 +50,7 @@ import pandora.AndroidProto.*
private const val TAG = "PandoraAndroidInternal"

@kotlinx.coroutines.ExperimentalCoroutinesApi
class AndroidInternal(val context: Context) : AndroidImplBase() {
class AndroidInternal(val context: Context) : AndroidImplBase(), Closeable {

  private val scope: CoroutineScope = CoroutineScope(Dispatchers.Default)
  private val INCOMING_FILE_ACCEPT_BTN = "ACCEPT"
@@ -73,10 +72,14 @@ class AndroidInternal(val context: Context) : AndroidImplBase() {
    createImageFile()
  }

  fun deinit() {
  override fun close() {
    scope.cancel()

    val file = File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), IMAGE_FILE_NAME)
    val file =
      File(
        Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),
        IMAGE_FILE_NAME
      )

    if (file.exists()) {
      file.delete()
@@ -90,13 +93,19 @@ class AndroidInternal(val context: Context) : AndroidImplBase() {
    }
  }

  override fun setAccessPermission(request: SetAccessPermissionRequest, responseObserver: StreamObserver<Empty>) {
  override fun setAccessPermission(
    request: SetAccessPermissionRequest,
    responseObserver: StreamObserver<Empty>
  ) {
    grpcUnary<Empty>(scope, responseObserver) {
      val bluetoothDevice = request.address.toBluetoothDevice(bluetoothAdapter)
      when (request.accessType!!) {
        AccessType.ACCESS_MESSAGE -> bluetoothDevice.setMessageAccessPermission(BluetoothDevice.ACCESS_ALLOWED)
        AccessType.ACCESS_PHONEBOOK -> bluetoothDevice.setPhonebookAccessPermission(BluetoothDevice.ACCESS_ALLOWED)
        AccessType.ACCESS_SIM -> bluetoothDevice.setSimAccessPermission(BluetoothDevice.ACCESS_ALLOWED)
        AccessType.ACCESS_MESSAGE ->
          bluetoothDevice.setMessageAccessPermission(BluetoothDevice.ACCESS_ALLOWED)
        AccessType.ACCESS_PHONEBOOK ->
          bluetoothDevice.setPhonebookAccessPermission(BluetoothDevice.ACCESS_ALLOWED)
        AccessType.ACCESS_SIM ->
          bluetoothDevice.setSimAccessPermission(BluetoothDevice.ACCESS_ALLOWED)
        else -> {}
      }
      Empty.getDefaultInstance()
@@ -110,15 +119,25 @@ class AndroidInternal(val context: Context) : AndroidImplBase() {
      telephonyManager = telephonyManager.createForSubscriptionId(defaultSmsSub)
      val avdPhoneNumber = telephonyManager.getLine1Number()

      smsManager.sendTextMessage(avdPhoneNumber, avdPhoneNumber, generateAlphanumericString(DEFAULT_MESSAGE_LEN), null, null)
      smsManager.sendTextMessage(
        avdPhoneNumber,
        avdPhoneNumber,
        generateAlphanumericString(DEFAULT_MESSAGE_LEN),
        null,
        null
      )
      Empty.getDefaultInstance()
    }
  }

  override fun acceptIncomingFile(request: Empty, responseObserver: StreamObserver<Empty>) {
    grpcUnary<Empty>(scope, responseObserver) {
      device.wait(Until.findObject(By.text(INCOMING_FILE_TITLE)), INCOMING_FILE_WAIT_TIMEOUT).click()
      device.wait(Until.findObject(By.text(INCOMING_FILE_ACCEPT_BTN)), INCOMING_FILE_WAIT_TIMEOUT).click()
      device
        .wait(Until.findObject(By.text(INCOMING_FILE_TITLE)), INCOMING_FILE_WAIT_TIMEOUT)
        .click()
      device
        .wait(Until.findObject(By.text(INCOMING_FILE_ACCEPT_BTN)), INCOMING_FILE_WAIT_TIMEOUT)
        .click()
      Empty.getDefaultInstance()
    }
  }
@@ -132,8 +151,11 @@ class AndroidInternal(val context: Context) : AndroidImplBase() {
  }

  suspend private fun waitAndSelectBluetoothDevice() {
    var selectJob = scope.async {
      device.wait(Until.findObject(By.textContains("Cuttlefish")), BT_DEVICE_SELECT_WAIT_TIMEOUT).click()
    var selectJob =
      scope.async {
        device
          .wait(Until.findObject(By.textContains("Cuttlefish")), BT_DEVICE_SELECT_WAIT_TIMEOUT)
          .click()
      }
    selectJob.await()
  }
@@ -148,14 +170,16 @@ class AndroidInternal(val context: Context) : AndroidImplBase() {
      sendingIntent.setComponent(ComponentName(BT_PKG_NAME, BT_OPP_LAUNCHER_ACTIVITY))
      sendingIntent.putExtra(Intent.EXTRA_STREAM, contentUri)
      context.startActivity(sendingIntent)
    } catch(e: Exception) {
    }
    } catch (e: Exception) {}
  }

  private fun getImageId(fileName: String): Long {
    val selection = MediaColumns.DISPLAY_NAME + "=?"
    val selectionArgs = arrayOf(fileName)
    val cursor = context.getContentResolver().query(Media.EXTERNAL_CONTENT_URI, null, selection, selectionArgs, null)
    val cursor =
      context
        .getContentResolver()
        .query(Media.EXTERNAL_CONTENT_URI, null, selection, selectionArgs, null)

    cursor?.use {
      it.let {
@@ -168,7 +192,11 @@ class AndroidInternal(val context: Context) : AndroidImplBase() {

  private fun createImageFile() {
    val bitmapImage = Bitmap.createBitmap(30, 20, Bitmap.Config.ARGB_8888)
    val file = File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), IMAGE_FILE_NAME)
    val file =
      File(
        Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),
        IMAGE_FILE_NAME
      )
    var fileOutputStream: FileOutputStream? = null

    if (file.exists()) {
+3 −2
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package com.android.pandora

import android.bluetooth.BluetoothManager
import android.content.Context
import java.io.Closeable
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.cancel
@@ -25,7 +26,7 @@ import pandora.AVRCPGrpc.AVRCPImplBase
import pandora.AvrcpProto.*

@kotlinx.coroutines.ExperimentalCoroutinesApi
class Avrcp(val context: Context) : AVRCPImplBase() {
class Avrcp(val context: Context) : AVRCPImplBase(), Closeable {
  private val TAG = "PandoraAvrcp"

  private val scope: CoroutineScope
@@ -39,7 +40,7 @@ class Avrcp(val context: Context) : AVRCPImplBase() {
    scope = CoroutineScope(Dispatchers.Default)
  }

  fun deinit() {
  override fun close() {
    // Deinit the CoroutineScope
    scope.cancel()
  }
+3 −2
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@ import android.content.IntentFilter
import android.util.Log
import io.grpc.Status
import io.grpc.stub.StreamObserver
import java.io.Closeable
import java.util.UUID
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
@@ -45,7 +46,7 @@ import pandora.GATTGrpc.GATTImplBase
import pandora.GattProto.*

@kotlinx.coroutines.ExperimentalCoroutinesApi
class Gatt(private val context: Context) : GATTImplBase() {
class Gatt(private val context: Context) : GATTImplBase(), Closeable {
  private val TAG = "PandoraGatt"

  private val mScope: CoroutineScope = CoroutineScope(Dispatchers.Default)
@@ -63,7 +64,7 @@ class Gatt(private val context: Context) : GATTImplBase() {
    flow = intentFlow(context, intentFilter).shareIn(mScope, SharingStarted.Eagerly)
  }

  fun deinit() {
  override fun close() {
    serverManager.server.close()
    mScope.cancel()
  }
Loading