Skip to content

Commit c6ba1d2

Browse files
jkmasselclaude
andcommitted
Add Device Info screen to Help & Support
Adds a dedicated Device Info screen accessible from Help & Support showing manufacturer, brand, model, Android version, SDK level, app version, and e-ink detection status. Includes a copy-to-clipboard button for sharing device details with support. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent cf551cf commit c6ba1d2

4 files changed

Lines changed: 232 additions & 0 deletions

File tree

WordPress/src/main/AndroidManifest.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,11 @@
213213
android:label="@string/help_buttons_screen_title"
214214
android:theme="@style/WordPress.NoActionBar" />
215215

216+
<activity
217+
android:name=".ui.accounts.DeviceInfoActivity"
218+
android:label="@string/device_info_title"
219+
android:theme="@style/WordPress.NoActionBar" />
220+
216221
<activity
217222
android:name=".ui.main.feedbackform.FeedbackFormActivity"
218223
android:label="@string/feedback_form_title"
Lines changed: 219 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,219 @@
1+
package org.wordpress.android.ui.accounts
2+
3+
import android.content.ClipData
4+
import android.content.ClipboardManager
5+
import android.os.Build
6+
import android.os.Bundle
7+
import android.widget.Toast
8+
import androidx.compose.foundation.layout.Column
9+
import androidx.compose.foundation.layout.fillMaxWidth
10+
import androidx.compose.foundation.layout.padding
11+
import androidx.compose.foundation.rememberScrollState
12+
import androidx.compose.foundation.verticalScroll
13+
import androidx.compose.material.icons.Icons
14+
import androidx.compose.material.icons.automirrored.filled.ArrowBack
15+
import androidx.compose.material3.Button
16+
import androidx.compose.material3.ExperimentalMaterial3Api
17+
import androidx.compose.material3.HorizontalDivider
18+
import androidx.compose.material3.Icon
19+
import androidx.compose.material3.IconButton
20+
import androidx.compose.material3.MaterialTheme
21+
import androidx.compose.material3.Scaffold
22+
import androidx.compose.material3.Text
23+
import androidx.compose.material3.TopAppBar
24+
import androidx.compose.runtime.Composable
25+
import androidx.compose.ui.Modifier
26+
import androidx.compose.ui.platform.LocalContext
27+
import androidx.compose.ui.res.stringResource
28+
import androidx.compose.ui.text.font.FontWeight
29+
import androidx.compose.ui.tooling.preview.Preview
30+
import androidx.compose.ui.unit.dp
31+
import dagger.hilt.android.AndroidEntryPoint
32+
import org.wordpress.android.R
33+
import org.wordpress.android.WordPress
34+
import org.wordpress.android.ui.compose.theme.AppThemeM3
35+
import org.wordpress.android.ui.main.BaseAppCompatActivity
36+
import org.wordpress.android.util.EinkDeviceDetector
37+
import org.wordpress.android.util.extensions.setContent
38+
39+
@AndroidEntryPoint
40+
class DeviceInfoActivity : BaseAppCompatActivity() {
41+
override fun onCreate(savedInstanceState: Bundle?) {
42+
super.onCreate(savedInstanceState)
43+
44+
setContent {
45+
AppThemeM3 {
46+
DeviceInfoScreen(
47+
onNavigateBack = onBackPressedDispatcher::onBackPressed
48+
)
49+
}
50+
}
51+
}
52+
}
53+
54+
private data class DeviceInfoSection(
55+
val title: String,
56+
val entries: List<Pair<String, String>>,
57+
)
58+
59+
@OptIn(ExperimentalMaterial3Api::class)
60+
@Composable
61+
private fun DeviceInfoScreen(onNavigateBack: () -> Unit) {
62+
val context = LocalContext.current
63+
val sections = buildDeviceInfoSections()
64+
65+
Scaffold(
66+
topBar = {
67+
TopAppBar(
68+
title = {
69+
Text(
70+
text = stringResource(R.string.device_info_title)
71+
)
72+
},
73+
navigationIcon = {
74+
IconButton(onClick = onNavigateBack) {
75+
Icon(
76+
Icons.AutoMirrored.Filled.ArrowBack,
77+
stringResource(R.string.back)
78+
)
79+
}
80+
},
81+
)
82+
},
83+
) { innerPadding ->
84+
Column(
85+
modifier = Modifier
86+
.padding(innerPadding)
87+
.verticalScroll(rememberScrollState())
88+
) {
89+
sections.forEach { section ->
90+
SectionHeader(title = section.title)
91+
section.entries.forEach { (label, value) ->
92+
DeviceInfoRow(label = label, value = value)
93+
}
94+
}
95+
Button(
96+
onClick = {
97+
val text = sections.joinToString("\n\n") { s ->
98+
s.title + "\n" + s.entries.joinToString(
99+
"\n"
100+
) { "${it.first}: ${it.second}" }
101+
}
102+
val clipboard = context.getSystemService(
103+
ClipboardManager::class.java
104+
)
105+
clipboard.setPrimaryClip(
106+
ClipData.newPlainText(
107+
context.getString(
108+
R.string.device_info_title
109+
),
110+
text
111+
)
112+
)
113+
Toast.makeText(
114+
context,
115+
R.string.device_info_copied,
116+
Toast.LENGTH_SHORT
117+
).show()
118+
},
119+
modifier = Modifier
120+
.fillMaxWidth()
121+
.padding(16.dp)
122+
) {
123+
Text(
124+
text = stringResource(
125+
R.string.copy_to_clipboard
126+
)
127+
)
128+
}
129+
}
130+
}
131+
}
132+
133+
@Composable
134+
private fun SectionHeader(title: String) {
135+
Text(
136+
text = title,
137+
style = MaterialTheme.typography.titleSmall,
138+
color = MaterialTheme.colorScheme.primary,
139+
modifier = Modifier.padding(
140+
start = 16.dp, end = 16.dp, top = 16.dp, bottom = 4.dp
141+
),
142+
)
143+
}
144+
145+
@Composable
146+
private fun buildDeviceInfoSections(): List<DeviceInfoSection> {
147+
val einkValue = if (EinkDeviceDetector.isEinkDevice()) {
148+
stringResource(R.string.yes)
149+
} else {
150+
stringResource(R.string.no)
151+
}
152+
return listOf(
153+
DeviceInfoSection(
154+
title = stringResource(R.string.device_info_section_application),
155+
entries = listOf(
156+
stringResource(R.string.device_info_app_version)
157+
to WordPress.versionName,
158+
),
159+
),
160+
DeviceInfoSection(
161+
title = stringResource(R.string.device_info_section_device),
162+
entries = listOf(
163+
stringResource(R.string.device_info_manufacturer)
164+
to Build.MANUFACTURER,
165+
stringResource(R.string.device_info_brand)
166+
to Build.BRAND,
167+
stringResource(R.string.device_info_model)
168+
to Build.MODEL,
169+
stringResource(R.string.device_info_device)
170+
to Build.DEVICE,
171+
stringResource(R.string.device_info_product)
172+
to Build.PRODUCT,
173+
stringResource(R.string.device_info_eink_detected)
174+
to einkValue,
175+
),
176+
),
177+
DeviceInfoSection(
178+
title = stringResource(R.string.device_info_section_android),
179+
entries = listOf(
180+
stringResource(R.string.device_info_android_version)
181+
to Build.VERSION.RELEASE,
182+
stringResource(R.string.device_info_sdk_level)
183+
to Build.VERSION.SDK_INT.toString(),
184+
),
185+
),
186+
)
187+
}
188+
189+
@Composable
190+
private fun DeviceInfoRow(label: String, value: String) {
191+
Column(
192+
modifier = Modifier
193+
.fillMaxWidth()
194+
.padding(horizontal = 16.dp, vertical = 12.dp)
195+
) {
196+
Text(
197+
text = label,
198+
style = MaterialTheme.typography.bodySmall,
199+
color = MaterialTheme.colorScheme.onSurfaceVariant,
200+
)
201+
Text(
202+
text = value,
203+
style = MaterialTheme.typography.bodyLarge,
204+
fontWeight = FontWeight.Normal,
205+
)
206+
}
207+
HorizontalDivider()
208+
}
209+
210+
@Preview(showBackground = true)
211+
@Composable
212+
private fun DeviceInfoRowPreview() {
213+
AppThemeM3 {
214+
DeviceInfoRow(
215+
label = "App version",
216+
value = "24.5-rc-1"
217+
)
218+
}
219+
}

WordPress/src/main/java/org/wordpress/android/ui/accounts/HelpActivity.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,9 @@ class HelpActivity : BaseAppCompatActivity() {
131131
logsButton.setOnClickListener { v ->
132132
startActivity(Intent(v.context, AppLogViewerActivity::class.java))
133133
}
134+
deviceInfoButton.setOnClickListener { v ->
135+
startActivity(Intent(v.context, DeviceInfoActivity::class.java))
136+
}
134137

135138
if (originFromExtras == Origin.JETPACK_MIGRATION_HELP) {
136139
configureForJetpackMigrationHelp()

WordPress/src/main/res/layout/help_activity.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,11 @@
275275
style="@style/HelpActivitySingleText"
276276
android:text="@string/logs_button" />
277277

278+
<com.google.android.material.textview.MaterialTextView
279+
android:id="@+id/device_info_button"
280+
style="@style/HelpActivitySingleText"
281+
android:text="@string/device_info_title" />
282+
278283
<com.google.android.material.textview.MaterialTextView
279284
android:id="@+id/applicationVersion"
280285
style="@style/HelpActivitySingleText"

0 commit comments

Comments
 (0)