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

Commit 5a34ae36 authored by Stefan Andonian's avatar Stefan Andonian
Browse files

Adding RecordIssueDialog with dropdown list to choose issue type.

Bug: 305049544
Flag: ACONFIG record_issue_qs_tile DEVELOPMENT
Test: Manually tested on device.
Screenshot: https://photos.app.goo.gl/MvR5pTzA31mwNU7Z9
Change-Id: Idfc2342e995d145f9b364a9303ece4ffc768487c
parent ef586bd6
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