• 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.evaluated
18 
19 import android.content.Intent
20 import android.os.Bundle
21 import android.util.Log
22 import android.view.LayoutInflater
23 import android.view.View
24 import android.widget.Button
25 import android.widget.LinearLayout
26 import android.widget.TextView
27 import androidx.fragment.app.commit
28 import androidx.preference.Preference
29 import androidx.preference.PreferenceFragmentCompat
30 import com.android.devicediagnostics.ApplicationInterface
31 import com.android.devicediagnostics.AttestationController
32 import com.android.devicediagnostics.DisplayResultFragment
33 import com.android.devicediagnostics.MainActivity
34 import com.android.devicediagnostics.Protos.DeviceReport
35 import com.android.devicediagnostics.R
36 import com.android.devicediagnostics.runInBackground
37 import com.android.settingslib.collapsingtoolbar.CollapsingToolbarBaseActivity
38 
39 private const val TAG = "EvaluationFinalize"
40 
41 class EvaluationFinalizeFragment(private val ok: Boolean) : PreferenceFragmentCompat() {
onCreatePreferencesnull42     override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
43         setPreferencesFromResource(R.xml.preferences_evaluated_done, rootKey)
44         findPreference<Preference>("Done")!!.also {
45             if (!ok) {
46                 it.setTitle(R.string.bluetooth_error_title)
47                 it.setSummary(R.string.bluetooth_error_summary)
48             }
49             it.setOnPreferenceClickListener {
50                 val intent = Intent(activity, MainActivity::class.java)
51                 intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
52                 activity!!.startActivity(intent)
53                 activity!!.finish()
54                 true
55             }
56         }
57     }
58 }
59 
60 class EvaluationFinalizeActivity : CollapsingToolbarBaseActivity() {
onCreatenull61     override fun onCreate(savedInstanceState: Bundle?) {
62         super.onCreate(savedInstanceState)
63         setContentView(R.layout.evaluated_finalize)
64         setTitle(R.string.evaluation_mode_title)
65 
66         if (savedInstanceState == null) {
67             showProgressIndicator(R.string.evaluated_finalizing_report)
68             buildReport()
69         }
70     }
71 
buildReportnull72     private fun buildReport() {
73         val state = TestState.fromActivity(this)!!
74 
75         // Launch in separate thread since gathering attestation takes time and we don't want to
76         // block the UI from appearing
77         runInBackground {
78             val reportBuilder = DeviceReport.newBuilder()
79 
80             reportBuilder.setTests(state.testResults)
81 
82             val batteryInfo = getBatteryInfo(this)
83             val storageInfo = getStorageInfo(this)
84             val launchLevel = ApplicationInterface.app.getLaunchLevel()
85 
86             val attestation = createAttestationRecord(state.trustedDevice.challenge.toByteArray())
87 
88             val bluetoothClient = ApplicationInterface.app.getBluetoothClient()
89             val connectionData = bluetoothClient.connectionData
90             if (connectionData != null && connectionData.version == 4) {
91                 reportBuilder.setOldAttestation(attestation.certificates)
92             } else {
93                 reportBuilder.setAttestation(attestation)
94             }
95 
96             reportBuilder.setBattery(batteryInfo)
97             reportBuilder.setStorage(storageInfo)
98             reportBuilder.setLaunchLevel(launchLevel)
99 
100             val report = reportBuilder.build()
101 
102             runOnUiThread { onReportReady(report) }
103         }
104     }
105 
onReportReadynull106     private fun onReportReady(report: DeviceReport) {
107         val confirmation = showHeaderLayout(R.layout.evaluated_final_confirmation)
108         val button = confirmation.findViewById<Button>(R.id.send_button)
109         button!!.setOnClickListener {
110             sendReport(report)
111             true
112         }
113 
114         val state = TestState.fromActivity(this)!!
115         val attestationController =
116             AttestationController(state.trustedDevice.challenge.toByteArray(), true)
117 
118         supportFragmentManager.commit {
119             setReorderingAllowed(true)
120             replace(
121                 R.id.fragment_container_view,
122                 DisplayResultFragment(report, attestationController),
123             )
124         }
125     }
126 
sendReportnull127     private fun sendReport(report: DeviceReport) {
128         showProgressIndicator(R.string.sending_report)
129 
130         runInBackground {
131             val bluetoothClient = ApplicationInterface.app.getBluetoothClient()
132             try {
133                 bluetoothClient.sendReport(report)
134                 runOnUiThread { onReportSent(true) }
135             } catch (e: Exception) {
136                 Log.e(TAG, "Bluetooth error: $e")
137                 runOnUiThread { onReportSent(false) }
138             }
139         }
140 
141         supportFragmentManager.commit {
142             hide(supportFragmentManager.findFragmentById(R.id.fragment_container_view)!!)
143         }
144     }
145 
onReportSentnull146     private fun onReportSent(sent: Boolean) {
147         hideHeaderLayout()
148         supportFragmentManager.commit {
149             replace(R.id.fragment_container_view, EvaluationFinalizeFragment(sent))
150         }
151     }
152 
showHeaderLayoutnull153     private fun showHeaderLayout(layoutId: Int): View {
154         val inflater = LayoutInflater.from(this)
155         val container = findViewById<LinearLayout>(R.id.header_container)!!
156 
157         val view = inflater.inflate(layoutId, container, false)
158 
159         container.removeAllViews()
160         container.addView(view)
161         container.visibility = View.VISIBLE
162         return view
163     }
164 
hideHeaderLayoutnull165     private fun hideHeaderLayout() {
166         val container = findViewById<LinearLayout>(R.id.header_container)!!
167         container.visibility = View.GONE
168     }
169 
showProgressIndicatornull170     private fun showProgressIndicator(stringResId: Int) {
171         val progress = showHeaderLayout(R.layout.progress_indicator)
172         val text = progress.findViewById<TextView>(R.id.progress_explainer)
173         text!!.setText(stringResId)
174     }
175 }
176