• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2024 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      https://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.devicediagnostics
18 
19 import android.accessibilityservice.AccessibilityServiceInfo
20 import android.content.Context
21 import android.os.Build
22 import android.os.SystemProperties
23 import android.view.accessibility.AccessibilityManager
24 import com.android.devicediagnostics.bluetooth.BluetoothClient
25 import com.android.devicediagnostics.bluetooth.BluetoothClientImpl
26 import com.android.devicediagnostics.bluetooth.BluetoothServer
27 import com.android.devicediagnostics.bluetooth.FakeBluetoothClient
28 import com.android.settingslib.qrcode.QrCamera
29 import com.google.android.attestation.ParsedAttestationRecord
30 import kotlin.math.min
31 import kotlin.random.Random
32 
33 open class ApplicationInterface {
34     private val btClient = BluetoothClientImpl()
35     private val btServer = BluetoothServer()
36     private var singleDeviceMode = false
37 
getRandomBytesnull38     open fun getRandomBytes(count: Int): ByteArray {
39         return Random.nextBytes(count)
40     }
41 
getQrCameranull42     open fun getQrCamera(context: Context, activity: QrCamera.ScannerCallback): QrCamera {
43         return QrCamera(context, activity)
44     }
45 
getBluetoothClientnull46     open fun getBluetoothClient(): BluetoothClient {
47         if (singleDeviceMode) {
48             return FakeBluetoothClient()
49         }
50         return btClient
51     }
52 
getBluetoothServernull53     open fun getBluetoothServer(): BluetoothServer {
54         return btServer
55     }
56 
verifyAttestationnull57     open fun verifyAttestation(
58         attestation: ByteArray,
59         challenge: ByteArray,
60     ): Pair<ParsedAttestationRecord?, AttestationResult> {
61         return checkAttestation(attestation, challenge)
62     }
63 
getLaunchLevelnull64     open fun getLaunchLevel(): Int {
65         val vendorApiLevel = getPropertyInt("ro.vendor.api_level", -1)
66         if (vendorApiLevel != -1) {
67             return vendorApiLevel
68         }
69         val boardApiLevel = getPropertyInt("ro.board.api_level", -1)
70         val firstApiLevel = getPropertyInt("ro.product.first_api_level", -1)
71         if (boardApiLevel != -1) {
72             if (firstApiLevel != -1) {
73                 return min(boardApiLevel, firstApiLevel)
74             }
75             return boardApiLevel
76         }
77         return firstApiLevel
78     }
79 
isUsingScreenReadernull80     open fun isUsingScreenReader(context: Context): Boolean {
81         val am = context.getSystemService(Context.ACCESSIBILITY_SERVICE) as AccessibilityManager?
82         if (am == null || !am.isEnabled) {
83             return false
84         }
85         val serviceInfoList =
86             am.getEnabledAccessibilityServiceList(AccessibilityServiceInfo.FEEDBACK_SPOKEN)
87         return serviceInfoList.isNotEmpty() || am.isTouchExplorationEnabled
88     }
89 
getPropertyIntnull90     private fun getPropertyInt(key: String, defaultValue: Int): Int {
91         var value: String? = null
92         value = SystemProperties.get(key, null)
93         if (value == null) {
94             return defaultValue
95         }
96         return try {
97             Integer.parseInt(value)
98         } catch (e: Exception) {
99             defaultValue
100         }
101     }
102 
103     // This allows testing the Bluetooth flow without having two devices.
enterSingleDeviceModenull104     fun enterSingleDeviceMode(): Boolean {
105         if (Build.IS_USER) {
106             return false
107         }
108         singleDeviceMode = true
109         return true
110     }
111 
leaveSingleDeviceModenull112     fun leaveSingleDeviceMode() {
113         singleDeviceMode = false
114     }
115 
116     companion object {
117         private var singleton = ApplicationInterface()
118 
119         val app
120             get() = singleton
121 
setAppnull122         fun setApp(app: ApplicationInterface) {
123             this.singleton = app
124         }
125     }
126 }
127