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

Commit 789cf782 authored by Stefan Andonian's avatar Stefan Andonian Committed by Android (Google) Code Review
Browse files

Merge "Adding RecordIssueDialog with dropdown list to choose issue type." into main

parents 8bc4eeae 5a34ae36
Loading
Loading
Loading
Loading
+26 −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.
  -->

<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="24dp"
    android:height="24dp"
    android:viewportWidth="24.0"
    android:viewportHeight="24.0"
    android:tint="?attr/colorControlNormal">
    <path
        android:fillColor="@android:color/white"
        android:pathData="M5.41,7.59L4,9l8,8 8,-8 -1.41,-1.41L12,14.17" />
</vector>
 No newline at end of file
+81 −0
Original line number Diff line number Diff line
<?xml version="1.0" encoding="utf-8"?>
<!--
  ~ 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.
  -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:orientation="vertical" >

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:textAppearance="@style/TextAppearance.Dialog.Body.Message"
        android:text="@string/qs_record_issue_dropdown_header" />

    <Button
        android:id="@+id/issue_type_button"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/qs_record_issue_dropdown_prompt"
        android:lines="1"
        android:drawableRight="@drawable/arrow_pointing_down"
        android:layout_marginTop="@dimen/qqs_layout_margin_top"
        android:focusable="false"
        android:clickable="true" />

    <!-- Screen Record Switch -->
    <LinearLayout
        android:id="@+id/screenrecord_switch_container"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="@dimen/qqs_layout_margin_top"
        android:orientation="horizontal">

        <ImageView
            android:layout_width="@dimen/screenrecord_option_icon_size"
            android:layout_height="@dimen/screenrecord_option_icon_size"
            android:layout_weight="0"
            android:src="@drawable/ic_screenrecord"
            app:tint="?androidprv:attr/materialColorOnSurface"
            android:layout_gravity="center"
            android:layout_marginEnd="@dimen/screenrecord_option_padding" />

        <TextView
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:minHeight="@dimen/screenrecord_option_icon_size"
            android:layout_weight="1"
            android:layout_gravity="fill_vertical"
            android:gravity="center"
            android:text="@string/quick_settings_screen_record_label"
            android:textAppearance="@style/TextAppearance.Dialog.Body.Message"
            android:importantForAccessibility="no"/>

        <Switch
            android:id="@+id/screenrecord_switch"
            android:layout_width="wrap_content"
            android:minHeight="@dimen/screenrecord_option_icon_size"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:layout_gravity="fill_vertical"
            android:layout_weight="0"
            android:contentDescription="@string/quick_settings_screen_record_label" />
    </LinearLayout>
</LinearLayout>
 No newline at end of file
+14 −0
Original line number Diff line number Diff line
@@ -831,6 +831,20 @@
    <!-- QuickSettings: Text to prompt the user to stop an ongoing recording [CHAR LIMIT=20] -->
    <string name="qs_record_issue_stop">Stop</string>

    <!-- QuickSettings: Issue Type Drop down options in Record Issue Start Dialog [CHAR LIMIT=50] -->
    <string name="qs_record_issue_dropdown_header">What part of your device experience was affected?</string>
    <!-- QuickSettings: Issue Type Drop down prompt in Record Issue Start Dialog [CHAR LIMIT=30] -->
    <string name="qs_record_issue_dropdown_prompt">Select issue type</string>
    <!-- QuickSettings: Screen record switch label in Record Issue Start Dialog [CHAR LIMIT=20] -->
    <string name="qs_record_issue_dropdown_screenrecord">Screen record</string>

    <!-- QuickSettings: Issue Type Drop down choices list in Record Issue Start Dialog [CHAR LIMIT=30] -->
    <string-array name="qs_record_issue_types">
        <item>Performance</item>
        <item>User Interface</item>
        <item>Battery</item>
    </string-array>

    <!-- QuickSettings: Label for the toggle that controls whether One-handed mode is enabled. [CHAR LIMIT=NONE] -->
    <string name="quick_settings_onehanded_label">One-handed mode</string>

+45 −3
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package com.android.systemui.qs.tiles

import android.app.AlertDialog
import android.content.Intent
import android.os.Handler
import android.os.Looper
@@ -24,8 +25,11 @@ import android.text.TextUtils
import android.view.View
import android.widget.Switch
import androidx.annotation.VisibleForTesting
import com.android.internal.jank.InteractionJankMonitor.CUJ_SHADE_DIALOG_OPEN
import com.android.internal.logging.MetricsLogger
import com.android.systemui.Flags.recordIssueQsTile
import com.android.systemui.animation.DialogCuj
import com.android.systemui.animation.DialogLaunchAnimator
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.plugins.ActivityStarter
@@ -36,7 +40,11 @@ import com.android.systemui.qs.QSHost
import com.android.systemui.qs.QsEventLogger
import com.android.systemui.qs.logging.QSLogger
import com.android.systemui.qs.tileimpl.QSTileImpl
import com.android.systemui.recordissue.RecordIssueDialogDelegate
import com.android.systemui.res.R
import com.android.systemui.statusbar.phone.KeyguardDismissUtil
import com.android.systemui.statusbar.phone.SystemUIDialog
import com.android.systemui.statusbar.policy.KeyguardStateController
import javax.inject.Inject

class RecordIssueTile
@@ -50,7 +58,11 @@ constructor(
    metricsLogger: MetricsLogger,
    statusBarStateController: StatusBarStateController,
    activityStarter: ActivityStarter,
    qsLogger: QSLogger
    qsLogger: QSLogger,
    private val keyguardDismissUtil: KeyguardDismissUtil,
    private val keyguardStateController: KeyguardStateController,
    private val dialogLaunchAnimator: DialogLaunchAnimator,
    private val sysuiDialogFactory: SystemUIDialog.Factory,
) :
    QSTileImpl<QSTile.BooleanState>(
        host,
@@ -76,11 +88,41 @@ constructor(
            handlesLongClick = false
        }

    override fun handleClick(view: View?) {
        isRecording = !isRecording
    @VisibleForTesting
    public override fun handleClick(view: View?) {
        if (isRecording) {
            isRecording = false
        } else {
            mUiHandler.post { showPrompt(view) }
        }
        refreshState()
    }

    private fun showPrompt(view: View?) {
        val dialog: AlertDialog =
            RecordIssueDialogDelegate(sysuiDialogFactory) {
                    isRecording = true
                    refreshState()
                }
                .createDialog()
        val dismissAction =
            ActivityStarter.OnDismissAction {
                // We animate from the touched view only if we are not on the keyguard, given
                // that if we are we will dismiss it which will also collapse the shade.
                if (view != null && !keyguardStateController.isShowing) {
                    dialogLaunchAnimator.showFromView(
                        dialog,
                        view,
                        DialogCuj(CUJ_SHADE_DIALOG_OPEN, TILE_SPEC)
                    )
                } else {
                    dialog.show()
                }
                false
            }
        keyguardDismissUtil.executeWhenUnlocked(dismissAction, false, true)
    }

    override fun getLongClickIntent(): Intent? = null

    @VisibleForTesting
+88 −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.systemui.recordissue

import android.annotation.SuppressLint
import android.content.Context
import android.content.res.ColorStateList
import android.graphics.Color
import android.os.Bundle
import android.view.Gravity
import android.view.LayoutInflater
import android.view.WindowManager
import android.widget.Button
import android.widget.PopupMenu
import android.widget.Switch
import com.android.systemui.res.R
import com.android.systemui.statusbar.phone.SystemUIDialog

class RecordIssueDialogDelegate(
    private val factory: SystemUIDialog.Factory,
    private val onStarted: Runnable
) : SystemUIDialog.Delegate {

    @SuppressLint("UseSwitchCompatOrMaterialCode") private lateinit var screenRecordSwitch: Switch
    private lateinit var issueTypeButton: Button

    override fun beforeCreate(dialog: SystemUIDialog, savedInstanceState: Bundle?) {
        dialog.apply {
            setView(LayoutInflater.from(context).inflate(R.layout.record_issue_dialog, null))
            setTitle(context.getString(R.string.qs_record_issue_label))
            setIcon(R.drawable.qs_record_issue_icon_off)
            setNegativeButton(R.string.cancel) { _, _ -> dismiss() }
            setPositiveButton(R.string.qs_record_issue_start) { _, _ ->
                onStarted.run()
                dismiss()
            }
        }
    }

    override fun createDialog(): SystemUIDialog = factory.create(this)

    override fun onCreate(dialog: SystemUIDialog, savedInstanceState: Bundle?) {
        dialog.apply {
            window?.addPrivateFlags(WindowManager.LayoutParams.SYSTEM_FLAG_SHOW_FOR_ALL_USERS)
            window?.setGravity(Gravity.CENTER)

            screenRecordSwitch = requireViewById(R.id.screenrecord_switch)
            issueTypeButton = requireViewById(R.id.issue_type_button)
            issueTypeButton.setOnClickListener { onIssueTypeClicked(context) }
        }
    }

    private fun onIssueTypeClicked(context: Context) {
        val selectedCategory = issueTypeButton.text.toString()
        val popupMenu = PopupMenu(context, issueTypeButton)

        context.resources.getStringArray(R.array.qs_record_issue_types).forEachIndexed { i, cat ->
            popupMenu.menu.add(0, 0, i, cat).apply {
                setIcon(R.drawable.arrow_pointing_down)
                if (selectedCategory != cat) {
                    iconTintList = ColorStateList.valueOf(Color.TRANSPARENT)
                }
            }
        }
        popupMenu.apply {
            setOnMenuItemClickListener {
                issueTypeButton.text = it.title
                true
            }
            setForceShowIcon(true)
            show()
        }
    }
}
Loading