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 package com.android.devicediagnostics
17 
18 import android.content.Intent
19 import android.os.Bundle
20 import androidx.preference.Preference
21 import androidx.preference.PreferenceFragmentCompat
22 import com.android.devicediagnostics.Protos.DeviceReport
23 import com.android.devicediagnostics.trusted.QrCodeDisplayActivity
24 import com.google.android.attestation.ParsedAttestationRecord
25 
26 private const val TAG = "DisplayResultFragment"
27 
28 class DisplayResultFragment(
29     private val report: DeviceReport,
30     private val attestation: AttestationController
31 ) : PreferenceFragmentCompat(), AttestationController.Callbacks {
onCreatePreferencesnull32     override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
33         setPreferencesFromResource(R.xml.preferences_trusted_display_result, rootKey)
34 
35         val tests = report.tests
36 
37         val pass = getString(R.string.pass)
38         val fail = getString(R.string.fail)
39 
40         findPreference<Preference>("screen")?.summary = if (tests.screenTest) pass else fail
41         findPreference<Preference>("touch")?.summary = if (tests.touchTest) pass else fail
42 
43         findPreference<Preference>("battery")!!.setOnPreferenceClickListener {
44             val intent =
45                 BatteryActivity.createIntent(activity!!, report.battery, report.launchLevel)
46             activity!!.startActivity(intent)
47             true
48         }
49 
50         findPreference<Preference>("storage")!!.setOnPreferenceClickListener {
51             val intent = StorageActivity.createIntent(activity!!, report.storage)
52             activity!!.startActivity(intent)
53             true
54         }
55 
56         findPreference<Preference>("evaluate_another")?.setOnPreferenceClickListener {
57             val intent = Intent(activity, QrCodeDisplayActivity::class.java)
58             intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
59             activity!!.startActivity(intent)
60             activity!!.finish()
61             true
62         }
63 
64         findPreference<Preference>("done")?.setOnPreferenceClickListener {
65             val intent = Intent(activity, MainActivity::class.java)
66             intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
67             activity!!.startActivity(intent)
68             activity!!.finish()
69             true
70         }
71 
72         findPreference<Preference>("retry_failure")?.also {
73             it.setOnPreferenceClickListener {
74                 attestation.verifyAttestation(activity!!, report, this)
75                 true
76             }
77         }
78 
79         attestation.verifyAttestation(activity!!, report, this)
80     }
81 
onAttestationReceivednull82     override fun onAttestationReceived(
83         attestation: Pair<ParsedAttestationRecord, AttestationResult>
84     ) {
85         if (activity == null) {
86             return
87         }
88 
89         val attestationRecord = attestation.first
90 
91         // Make invisible in case this is a successful retry attempt.
92         findPreference<Preference>("retry_failure")?.also { it.isVisible = false }
93 
94         findPreference<Preference>("imei")?.also {
95             if (attestationRecord.teeEnforced.attestationIdImei.isPresent) {
96                 it.summary =
97                     attestationRecord.teeEnforced.attestationIdImei.get().toString(Charsets.UTF_8)
98                 it.isVisible = true
99             }
100         }
101 
102         findPreference<Preference>("imei2")?.also {
103             if (attestationRecord.teeEnforced.attestationIdSecondImei.isPresent) {
104                 it.summary =
105                     attestationRecord.teeEnforced.attestationIdSecondImei
106                         .get()
107                         .toString(Charsets.UTF_8)
108                 it.isVisible = true
109             }
110         }
111 
112         findPreference<Preference>("serial")?.also {
113             if (attestationRecord.teeEnforced.attestationIdSerial.isPresent) {
114                 it.summary =
115                     attestationRecord.teeEnforced.attestationIdSerial.get().toString(Charsets.UTF_8)
116                 it.isVisible = true
117             }
118         }
119 
120         findPreference<Preference>("locked")?.also {
121             val rootOfTrust = attestationRecord.teeEnforced.rootOfTrust
122             it.summary =
123                 if (rootOfTrust.isPresent && rootOfTrust.get().deviceLocked) {
124                     resources.getString(R.string.locked)
125                 } else {
126                     resources.getString(R.string.not_locked)
127                 }
128             it.isVisible = true
129         }
130         findPreference<Preference>("trustworthy")?.also {
131             if (attestation.second == AttestationResult.VERIFIED) {
132                 it.summary = activity!!.resources.getString(getVerifiedBootStateResId(attestationRecord))
133             } else {
134                 it.summary = activity!!.resources.getString(R.string.no)
135             }
136             it.isVisible = true
137         }
138         findPreference<Preference>("attestation_details")?.also {
139             it.setOnPreferenceClickListener {
140                 DisplayAttestationDetailsActivity.attestation = attestation
141                 startActivity(
142                     Intent(requireActivity(), DisplayAttestationDetailsActivity::class.java)
143                 )
144                 true
145             }
146             it.isVisible = true
147         }
148     }
149 
onAttestationErrornull150     override fun onAttestationError() {
151         if (activity == null) {
152             return
153         }
154         findPreference<Preference>("non_retry_failure")?.also { it.isVisible = true }
155     }
156 
onAttestationRetrynull157     override fun onAttestationRetry() {
158         findPreference<Preference>("retry_failure")?.also {
159             it.setOnPreferenceClickListener {
160                 attestation.verifyAttestation(activity!!, report, this)
161                 true
162             }
163             it.isVisible = true
164         }
165     }
166 }
167