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

Commit 2cf70c7f authored by Chaohui Wang's avatar Chaohui Wang
Browse files

Allow copy version & package name in App Info page

Fix: 312095344
Test: manual - on "App info" page
Test: unit test
Change-Id: I0dd7c9a4ccc34375cb3dac62115b736dfcffe76a
parent e6c9abf7
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -49,6 +49,7 @@ import com.android.settingslib.spa.gallery.preference.SwitchPreferencePageProvid
import com.android.settingslib.spa.gallery.preference.TwoTargetSwitchPreferencePageProvider
import com.android.settingslib.spa.gallery.scaffold.SearchScaffoldPageProvider
import com.android.settingslib.spa.gallery.ui.CategoryPageProvider
import com.android.settingslib.spa.gallery.ui.CopyablePageProvider
import com.android.settingslib.spa.gallery.ui.SpinnerPageProvider
import com.android.settingslib.spa.slice.SpaSliceBroadcastReceiver

@@ -100,6 +101,7 @@ class GallerySpaEnvironment(context: Context) : SpaEnvironment(context) {
                SettingsTextFieldPasswordPageProvider,
                SearchScaffoldPageProvider,
                CardPageProvider,
                CopyablePageProvider,
            ),
            rootPages = listOf(
                HomePageProvider.createSettingsPage(),
+2 −0
Original line number Diff line number Diff line
@@ -44,6 +44,7 @@ import com.android.settingslib.spa.gallery.page.SliderPageProvider
import com.android.settingslib.spa.gallery.preference.PreferenceMainPageProvider
import com.android.settingslib.spa.gallery.scaffold.SearchScaffoldPageProvider
import com.android.settingslib.spa.gallery.ui.CategoryPageProvider
import com.android.settingslib.spa.gallery.ui.CopyablePageProvider
import com.android.settingslib.spa.gallery.ui.SpinnerPageProvider
import com.android.settingslib.spa.widget.scaffold.HomeScaffold

@@ -71,6 +72,7 @@ object HomePageProvider : SettingsPageProvider {
            AlertDialogPageProvider.buildInjectEntry().setLink(fromPage = owner).build(),
            EditorMainPageProvider.buildInjectEntry().setLink(fromPage = owner).build(),
            CardPageProvider.buildInjectEntry().setLink(fromPage = owner).build(),
            CopyablePageProvider.buildInjectEntry().setLink(fromPage = owner).build(),
        )
    }

+61 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2023 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.settingslib.spa.gallery.ui

import android.os.Bundle
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.padding
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import com.android.settingslib.spa.framework.common.EntrySearchData
import com.android.settingslib.spa.framework.common.SettingsEntryBuilder
import com.android.settingslib.spa.framework.common.SettingsPageProvider
import com.android.settingslib.spa.framework.common.createSettingsPage
import com.android.settingslib.spa.framework.compose.navigator
import com.android.settingslib.spa.framework.theme.SettingsDimension
import com.android.settingslib.spa.widget.preference.Preference
import com.android.settingslib.spa.widget.preference.PreferenceModel
import com.android.settingslib.spa.widget.scaffold.RegularScaffold
import com.android.settingslib.spa.widget.ui.CopyableBody

private const val TITLE = "Sample Copyable"

object CopyablePageProvider : SettingsPageProvider {
    override val name = "Copyable"

    private val owner = createSettingsPage()

    fun buildInjectEntry(): SettingsEntryBuilder {
        return SettingsEntryBuilder.createInject(owner)
            .setUiLayoutFn {
                Preference(object : PreferenceModel {
                    override val title = TITLE
                    override val onClick = navigator(name)
                })
            }
            .setSearchDataFn { EntrySearchData(title = TITLE) }
    }

    @Composable
    override fun Page(arguments: Bundle?) {
        RegularScaffold(title = TITLE) {
            Box(modifier = Modifier.padding(SettingsDimension.itemPadding)) {
                CopyableBody(body = "Copyable body")
            }
        }
    }
}
+1 −1
Original line number Diff line number Diff line
@@ -15,7 +15,7 @@
#

[versions]
agp = "8.1.3"
agp = "8.1.4"
compose-compiler = "1.5.1"
dexmaker-mockito = "2.28.3"
jvm = "17"
+102 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2023 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.settingslib.spa.widget.ui

import androidx.compose.foundation.gestures.detectTapGestures
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.DropdownMenu
import androidx.compose.material3.DropdownMenuItem
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.MenuDefaults
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.platform.LocalClipboardManager
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.unit.DpOffset
import com.android.settingslib.spa.framework.theme.SettingsDimension
import com.android.settingslib.spa.framework.theme.SettingsTheme

@Composable
fun CopyableBody(body: String) {
    var expanded by remember { mutableStateOf(false) }
    var dpOffset by remember { mutableStateOf(DpOffset.Unspecified) }

    Box(modifier = Modifier
        .fillMaxWidth()
        .pointerInput(Unit) {
            detectTapGestures(
                onLongPress = {
                    dpOffset = DpOffset(it.x.toDp(), it.y.toDp())
                    expanded = true
                },
            )
        }
    ) {
        SettingsBody(body)

        DropdownMenu(
            expanded = expanded,
            onDismissRequest = { expanded = false },
            offset = dpOffset,
        ) {
            DropdownMenuTitle(body)
            DropdownMenuCopy(body) { expanded = false }
        }
    }
}

@Composable
private fun DropdownMenuTitle(text: String) {
    Text(
        text = text,
        modifier = Modifier
            .padding(MenuDefaults.DropdownMenuItemContentPadding)
            .padding(
                top = SettingsDimension.itemPaddingAround,
                bottom = SettingsDimension.buttonPaddingVertical,
            ),
        color = SettingsTheme.colorScheme.categoryTitle,
        style = MaterialTheme.typography.labelMedium,
    )
}

@Composable
private fun DropdownMenuCopy(body: String, onCopy: () -> Unit) {
    val clipboardManager = LocalClipboardManager.current
    DropdownMenuItem(
        text = {
            Text(
                text = stringResource(android.R.string.copy),
                color = MaterialTheme.colorScheme.onSurface,
                style = MaterialTheme.typography.bodyLarge,
            )
        },
        onClick = {
            onCopy()
            clipboardManager.setText(AnnotatedString(body))
        }
    )
}
Loading