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

Commit 4cbc7f31 authored by Stefan Andonian's avatar Stefan Andonian
Browse files

Persist User Selections in Record Issue Tile Dialog

Bug: 305049544
Test: Tested this manually on my device.
Flag: com.android.systemui.record_issue_qs_tile STAGING
Change-Id: Ib5e5776d76744e6b1d3136e039277edfdac06b49
parent 37d905d0
Loading
Loading
Loading
Loading
+4 −10
Original line number Original line Diff line number Diff line
@@ -52,7 +52,6 @@ import com.android.systemui.screenrecord.RecordingService
import com.android.systemui.settings.UserContextProvider
import com.android.systemui.settings.UserContextProvider
import com.android.systemui.statusbar.phone.KeyguardDismissUtil
import com.android.systemui.statusbar.phone.KeyguardDismissUtil
import com.android.systemui.statusbar.policy.KeyguardStateController
import com.android.systemui.statusbar.policy.KeyguardStateController
import com.android.traceur.TraceUtils.PresetTraceType
import java.util.concurrent.Executor
import java.util.concurrent.Executor
import javax.inject.Inject
import javax.inject.Inject


@@ -131,15 +130,11 @@ constructor(
        }
        }
    }
    }


    private fun startIssueRecordingService(screenRecord: Boolean, traceType: PresetTraceType) =
    private fun startIssueRecordingService() =
        PendingIntent.getForegroundService(
        PendingIntent.getForegroundService(
                userContextProvider.userContext,
                userContextProvider.userContext,
                RecordingService.REQUEST_CODE,
                RecordingService.REQUEST_CODE,
                IssueRecordingService.getStartIntent(
                IssueRecordingService.getStartIntent(userContextProvider.userContext),
                    userContextProvider.userContext,
                    screenRecord,
                    traceType
                ),
                PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
                PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
            )
            )
            .send(BroadcastOptions.makeBasic().apply { isInteractive = true }.toBundle())
            .send(BroadcastOptions.makeBasic().apply { isInteractive = true }.toBundle())
@@ -157,7 +152,7 @@ constructor(
        val dialog: AlertDialog =
        val dialog: AlertDialog =
            delegateFactory
            delegateFactory
                .create {
                .create {
                    startIssueRecordingService(it.screenRecord, it.traceType)
                    startIssueRecordingService()
                    dialogTransitionAnimator.disableAllCurrentDialogsExitAnimations()
                    dialogTransitionAnimator.disableAllCurrentDialogsExitAnimations()
                    panelInteractor.collapsePanels()
                    panelInteractor.collapsePanels()
                }
                }
@@ -169,8 +164,7 @@ constructor(
                if (expandable != null && !keyguardStateController.isShowing) {
                if (expandable != null && !keyguardStateController.isShowing) {
                    expandable
                    expandable
                        .dialogTransitionController(DialogCuj(CUJ_SHADE_DIALOG_OPEN, TILE_SPEC))
                        .dialogTransitionController(DialogCuj(CUJ_SHADE_DIALOG_OPEN, TILE_SPEC))
                        ?.let { dialogTransitionAnimator.show(dialog, it) }
                        ?.let { dialogTransitionAnimator.show(dialog, it) } ?: dialog.show()
                        ?: dialog.show()
                } else {
                } else {
                    dialog.show()
                    dialog.show()
                }
                }
+0 −21
Original line number Original line Diff line number Diff line
/*
 * Copyright (C) 2024 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 com.android.traceur.TraceUtils.PresetTraceType

data class IssueRecordingConfig(val screenRecord: Boolean, val traceType: PresetTraceType)
+13 −20
Original line number Original line Diff line number Diff line
@@ -35,8 +35,6 @@ import com.android.systemui.screenrecord.RecordingService
import com.android.systemui.screenrecord.RecordingServiceStrings
import com.android.systemui.screenrecord.RecordingServiceStrings
import com.android.systemui.settings.UserContextProvider
import com.android.systemui.settings.UserContextProvider
import com.android.systemui.statusbar.phone.KeyguardDismissUtil
import com.android.systemui.statusbar.phone.KeyguardDismissUtil
import com.android.traceur.MessageConstants.INTENT_EXTRA_TRACE_TYPE
import com.android.traceur.TraceUtils.PresetTraceType
import java.util.concurrent.Executor
import java.util.concurrent.Executor
import javax.inject.Inject
import javax.inject.Inject


@@ -76,15 +74,10 @@ constructor(
        when (intent?.action) {
        when (intent?.action) {
            ACTION_START -> {
            ACTION_START -> {
                bgExecutor.execute {
                bgExecutor.execute {
                    traceurMessageSender.startTracing(
                    traceurMessageSender.startTracing(issueRecordingState.traceType)
                        intent.getSerializableExtra(
                            INTENT_EXTRA_TRACE_TYPE,
                            PresetTraceType::class.java
                        )
                    )
                }
                }
                issueRecordingState.isRecording = true
                issueRecordingState.isRecording = true
                if (!intent.getBooleanExtra(EXTRA_SCREEN_RECORD, false)) {
                if (!issueRecordingState.recordScreen) {
                    // If we don't want to record the screen, the ACTION_SHOW_START_NOTIF action
                    // If we don't want to record the screen, the ACTION_SHOW_START_NOTIF action
                    // will circumvent the RecordingService's screen recording start code.
                    // will circumvent the RecordingService's screen recording start code.
                    return super.onStartCommand(Intent(ACTION_SHOW_START_NOTIF), flags, startId)
                    return super.onStartCommand(Intent(ACTION_SHOW_START_NOTIF), flags, startId)
@@ -107,7 +100,7 @@ constructor(
                    )
                    )


                    val screenRecording = intent.getParcelableExtra(EXTRA_PATH, Uri::class.java)
                    val screenRecording = intent.getParcelableExtra(EXTRA_PATH, Uri::class.java)
                    if (issueRecordingState.takeBugReport) {
                    if (issueRecordingState.takeBugreport) {
                        iActivityManager.requestBugReportWithExtraAttachment(screenRecording)
                        iActivityManager.requestBugReportWithExtraAttachment(screenRecording)
                    } else {
                    } else {
                        traceurMessageSender.shareTraces(applicationContext, screenRecording)
                        traceurMessageSender.shareTraces(applicationContext, screenRecording)
@@ -130,7 +123,6 @@ constructor(
    companion object {
    companion object {
        private const val TAG = "IssueRecordingService"
        private const val TAG = "IssueRecordingService"
        private const val CHANNEL_ID = "issue_record"
        private const val CHANNEL_ID = "issue_record"
        private const val EXTRA_SCREEN_RECORD = "extra_screenRecord"


        /**
        /**
         * Get an intent to stop the issue recording service.
         * Get an intent to stop the issue recording service.
@@ -148,35 +140,36 @@ constructor(
         *
         *
         * @param context Context from the requesting activity
         * @param context Context from the requesting activity
         */
         */
        fun getStartIntent(
        fun getStartIntent(context: Context): Intent =
            context: Context,
            Intent(context, IssueRecordingService::class.java).setAction(ACTION_START)
            screenRecord: Boolean,
            traceType: PresetTraceType,
        ): Intent =
            Intent(context, IssueRecordingService::class.java)
                .setAction(ACTION_START)
                .putExtra(EXTRA_SCREEN_RECORD, screenRecord)
                .putExtra(INTENT_EXTRA_TRACE_TYPE, traceType)
    }
    }
}
}


private class IrsStrings(private val res: Resources) : RecordingServiceStrings(res) {
private class IrsStrings(private val res: Resources) : RecordingServiceStrings(res) {
    override val title
    override val title
        get() = res.getString(R.string.issuerecord_title)
        get() = res.getString(R.string.issuerecord_title)

    override val notificationChannelDescription
    override val notificationChannelDescription
        get() = res.getString(R.string.issuerecord_channel_description)
        get() = res.getString(R.string.issuerecord_channel_description)

    override val startErrorResId
    override val startErrorResId
        get() = R.string.issuerecord_start_error
        get() = R.string.issuerecord_start_error

    override val startError
    override val startError
        get() = res.getString(R.string.issuerecord_start_error)
        get() = res.getString(R.string.issuerecord_start_error)

    override val saveErrorResId
    override val saveErrorResId
        get() = R.string.issuerecord_save_error
        get() = R.string.issuerecord_save_error

    override val saveError
    override val saveError
        get() = res.getString(R.string.issuerecord_save_error)
        get() = res.getString(R.string.issuerecord_save_error)

    override val ongoingRecording
    override val ongoingRecording
        get() = res.getString(R.string.issuerecord_ongoing_screen_only)
        get() = res.getString(R.string.issuerecord_ongoing_screen_only)

    override val backgroundProcessingLabel
    override val backgroundProcessingLabel
        get() = res.getString(R.string.issuerecord_background_processing_label)
        get() = res.getString(R.string.issuerecord_background_processing_label)

    override val saveTitle
    override val saveTitle
        get() = res.getString(R.string.issuerecord_save_title)
        get() = res.getString(R.string.issuerecord_save_title)
}
}
+58 −3
Original line number Original line Diff line number Diff line
@@ -16,16 +16,51 @@


package com.android.systemui.recordissue
package com.android.systemui.recordissue


import android.content.Context
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.qs.tiles.RecordIssueTile
import com.android.systemui.res.R
import com.android.systemui.settings.UserFileManager
import com.android.systemui.settings.UserTracker
import com.android.traceur.TraceUtils.PresetTraceType
import java.util.concurrent.CopyOnWriteArrayList
import java.util.concurrent.CopyOnWriteArrayList
import javax.inject.Inject
import javax.inject.Inject


@SysUISingleton
@SysUISingleton
class IssueRecordingState @Inject constructor() {
class IssueRecordingState
@Inject
constructor(
    userTracker: UserTracker,
    userFileManager: UserFileManager,
) {


    private val listeners = CopyOnWriteArrayList<Runnable>()
    private val prefs =
        userFileManager.getSharedPreferences(
            RecordIssueTile.TILE_SPEC,
            Context.MODE_PRIVATE,
            userTracker.userId
        )

    var takeBugreport
        get() = prefs.getBoolean(KEY_TAKE_BUG_REPORT, false)
        set(value) = prefs.edit().putBoolean(KEY_TAKE_BUG_REPORT, value).apply()

    var recordScreen
        get() = prefs.getBoolean(KEY_RECORD_SCREEN, false)
        set(value) = prefs.edit().putBoolean(KEY_RECORD_SCREEN, value).apply()

    var hasUserApprovedScreenRecording
        get() = prefs.getBoolean(HAS_APPROVED_SCREEN_RECORDING, false)
        private set(value) = prefs.edit().putBoolean(HAS_APPROVED_SCREEN_RECORDING, value).apply()

    var issueTypeRes
        get() = prefs.getInt(KEY_ISSUE_TYPE_RES, ISSUE_TYPE_NOT_SET)
        set(value) = prefs.edit().putInt(KEY_ISSUE_TYPE_RES, value).apply()

    val traceType: PresetTraceType
        get() = ALL_ISSUE_TYPES[issueTypeRes] ?: PresetTraceType.UNSET


    var takeBugReport: Boolean = false
    private val listeners = CopyOnWriteArrayList<Runnable>()


    var isRecording = false
    var isRecording = false
        set(value) {
        set(value) {
@@ -33,6 +68,10 @@ class IssueRecordingState @Inject constructor() {
            listeners.forEach(Runnable::run)
            listeners.forEach(Runnable::run)
        }
        }


    fun markUserApprovalForScreenRecording() {
        hasUserApprovedScreenRecording = true
    }

    fun addListener(listener: Runnable) {
    fun addListener(listener: Runnable) {
        listeners.add(listener)
        listeners.add(listener)
    }
    }
@@ -40,4 +79,20 @@ class IssueRecordingState @Inject constructor() {
    fun removeListener(listener: Runnable) {
    fun removeListener(listener: Runnable) {
        listeners.remove(listener)
        listeners.remove(listener)
    }
    }

    companion object {
        private const val KEY_TAKE_BUG_REPORT = "key_takeBugReport"
        private const val HAS_APPROVED_SCREEN_RECORDING = "HasApprovedScreenRecord"
        private const val KEY_RECORD_SCREEN = "key_recordScreen"
        const val KEY_ISSUE_TYPE_RES = "key_issueTypeRes"
        const val ISSUE_TYPE_NOT_SET = -1

        val ALL_ISSUE_TYPES: Map<Int, PresetTraceType> =
            hashMapOf(
                Pair(R.string.performance, PresetTraceType.PERFORMANCE),
                Pair(R.string.user_interface, PresetTraceType.UI),
                Pair(R.string.battery, PresetTraceType.BATTERY),
                Pair(R.string.thermal, PresetTraceType.THERMAL)
            )
    }
}
}
+53 −69
Original line number Original line Diff line number Diff line
@@ -17,7 +17,7 @@
package com.android.systemui.recordissue
package com.android.systemui.recordissue


import android.annotation.SuppressLint
import android.annotation.SuppressLint
import android.app.AlertDialog
import android.app.AlertDialog.BUTTON_POSITIVE
import android.content.Context
import android.content.Context
import android.content.Intent
import android.content.Intent
import android.content.res.ColorStateList
import android.content.res.ColorStateList
@@ -41,18 +41,16 @@ import com.android.systemui.mediaprojection.MediaProjectionMetricsLogger
import com.android.systemui.mediaprojection.SessionCreationSource
import com.android.systemui.mediaprojection.SessionCreationSource
import com.android.systemui.mediaprojection.devicepolicy.ScreenCaptureDevicePolicyResolver
import com.android.systemui.mediaprojection.devicepolicy.ScreenCaptureDevicePolicyResolver
import com.android.systemui.mediaprojection.devicepolicy.ScreenCaptureDisabledDialogDelegate
import com.android.systemui.mediaprojection.devicepolicy.ScreenCaptureDisabledDialogDelegate
import com.android.systemui.qs.tiles.RecordIssueTile
import com.android.systemui.recordissue.IssueRecordingState.Companion.ALL_ISSUE_TYPES
import com.android.systemui.recordissue.IssueRecordingState.Companion.ISSUE_TYPE_NOT_SET
import com.android.systemui.recordissue.IssueRecordingState.Companion.KEY_ISSUE_TYPE_RES
import com.android.systemui.res.R
import com.android.systemui.res.R
import com.android.systemui.settings.UserFileManager
import com.android.systemui.settings.UserTracker
import com.android.systemui.settings.UserTracker
import com.android.systemui.statusbar.phone.SystemUIDialog
import com.android.systemui.statusbar.phone.SystemUIDialog
import com.android.traceur.MessageConstants.INTENT_EXTRA_TRACE_TYPE
import com.android.traceur.TraceUtils.PresetTraceType
import dagger.assisted.Assisted
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
import dagger.assisted.AssistedInject
import java.util.concurrent.Executor
import java.util.concurrent.Executor
import java.util.function.Consumer


class RecordIssueDialogDelegate
class RecordIssueDialogDelegate
@AssistedInject
@AssistedInject
@@ -64,31 +62,20 @@ constructor(
    @Main private val mainExecutor: Executor,
    @Main private val mainExecutor: Executor,
    private val devicePolicyResolver: dagger.Lazy<ScreenCaptureDevicePolicyResolver>,
    private val devicePolicyResolver: dagger.Lazy<ScreenCaptureDevicePolicyResolver>,
    private val mediaProjectionMetricsLogger: MediaProjectionMetricsLogger,
    private val mediaProjectionMetricsLogger: MediaProjectionMetricsLogger,
    private val userFileManager: UserFileManager,
    private val screenCaptureDisabledDialogDelegate: ScreenCaptureDisabledDialogDelegate,
    private val screenCaptureDisabledDialogDelegate: ScreenCaptureDisabledDialogDelegate,
    private val issueRecordingState: IssueRecordingState,
    private val state: IssueRecordingState,
    private val traceurMessageSender: TraceurMessageSender,
    private val traceurMessageSender: TraceurMessageSender,
    @Assisted private val onStarted: Consumer<IssueRecordingConfig>,
    @Assisted private val onStarted: Runnable,
) : SystemUIDialog.Delegate {
) : SystemUIDialog.Delegate {


    private val issueTypeOptions: Map<Int, PresetTraceType> =
        hashMapOf(
            Pair(R.string.performance, PresetTraceType.PERFORMANCE),
            Pair(R.string.user_interface, PresetTraceType.UI),
            Pair(R.string.battery, PresetTraceType.BATTERY),
            Pair(R.string.thermal, PresetTraceType.THERMAL)
        )
    private var selectedIssueType: PresetTraceType? = null

    /** To inject dependencies and allow for easier testing */
    /** To inject dependencies and allow for easier testing */
    @AssistedFactory
    @AssistedFactory
    interface Factory {
    interface Factory {
        /** Create a dialog object */
        /** Create a dialog object */
        fun create(onStarted: Consumer<IssueRecordingConfig>): RecordIssueDialogDelegate
        fun create(onStarted: Runnable): RecordIssueDialogDelegate
    }
    }


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


    @MainThread
    @MainThread
@@ -97,21 +84,8 @@ constructor(
            setView(LayoutInflater.from(context).inflate(R.layout.record_issue_dialog, null))
            setView(LayoutInflater.from(context).inflate(R.layout.record_issue_dialog, null))
            setTitle(context.getString(R.string.qs_record_issue_label))
            setTitle(context.getString(R.string.qs_record_issue_label))
            setIcon(R.drawable.qs_record_issue_icon_off)
            setIcon(R.drawable.qs_record_issue_icon_off)
            setNegativeButton(R.string.cancel) { _, _ -> dismiss() }
            setNegativeButton(R.string.cancel) { _, _ -> }
            setPositiveButton(
            setPositiveButton(R.string.qs_record_issue_start) { _, _ -> onStarted.run() }
                R.string.qs_record_issue_start,
                { _, _ ->
                    issueRecordingState.takeBugReport = bugReportSwitch.isChecked
                    onStarted.accept(
                        IssueRecordingConfig(
                            screenRecordSwitch.isChecked,
                            selectedIssueType ?: PresetTraceType.UNSET
                        )
                    )
                    dismiss()
                },
                false
            )
        }
        }
        bgExecutor.execute { traceurMessageSender.bindToTraceur(dialog.context) }
        bgExecutor.execute { traceurMessageSender.bindToTraceur(dialog.context) }
    }
    }
@@ -121,23 +95,40 @@ constructor(
    @MainThread
    @MainThread
    override fun onCreate(dialog: SystemUIDialog, savedInstanceState: Bundle?) {
    override fun onCreate(dialog: SystemUIDialog, savedInstanceState: Bundle?) {
        dialog.apply {
        dialog.apply {
            window?.addPrivateFlags(WindowManager.LayoutParams.SYSTEM_FLAG_SHOW_FOR_ALL_USERS)
            window?.apply {
            window?.setGravity(Gravity.CENTER)
                addPrivateFlags(WindowManager.LayoutParams.SYSTEM_FLAG_SHOW_FOR_ALL_USERS)
                setGravity(Gravity.CENTER)
            }


            screenRecordSwitch = requireViewById(R.id.screenrecord_switch)
            screenRecordSwitch =
            screenRecordSwitch.setOnCheckedChangeListener { _, isEnabled ->
                requireViewById<Switch>(R.id.screenrecord_switch).apply {
                if (isEnabled) {
                    isChecked = state.recordScreen
                    setOnCheckedChangeListener { _, isChecked ->
                        state.recordScreen = isChecked
                        if (isChecked) {
                            bgExecutor.execute { onScreenRecordSwitchClicked() }
                            bgExecutor.execute { onScreenRecordSwitchClicked() }
                        }
                        }
                    }
                    }
            bugReportSwitch = requireViewById(R.id.bugreport_switch)
            val startButton = dialog.getButton(AlertDialog.BUTTON_POSITIVE)
            issueTypeButton = requireViewById(R.id.issue_type_button)
            issueTypeButton.setOnClickListener {
                onIssueTypeClicked(context) { startButton.isEnabled = true }
                }
                }

            requireViewById<Switch>(R.id.bugreport_switch).apply {
                isChecked = state.takeBugreport
                setOnCheckedChangeListener { _, isChecked -> state.takeBugreport = isChecked }
            }

            issueTypeButton =
                requireViewById<Button>(R.id.issue_type_button).apply {
                    val startButton = dialog.getButton(BUTTON_POSITIVE)
                    if (state.issueTypeRes != ISSUE_TYPE_NOT_SET) {
                        setText(state.issueTypeRes)
                    } else {
                        startButton.isEnabled = false
                        startButton.isEnabled = false
                    }
                    }
                    setOnClickListener {
                        onIssueTypeClicked(context) { startButton.isEnabled = true }
                    }
                }
        }
    }
    }


    @WorkerThread
    @WorkerThread
@@ -160,45 +151,38 @@ constructor(
            SessionCreationSource.SYSTEM_UI_SCREEN_RECORDER
            SessionCreationSource.SYSTEM_UI_SCREEN_RECORDER
        )
        )


        if (flags.isEnabled(Flags.WM_ENABLE_PARTIAL_SCREEN_SHARING)) {
        if (
            val prefs =
            flags.isEnabled(Flags.WM_ENABLE_PARTIAL_SCREEN_SHARING) &&
                userFileManager.getSharedPreferences(
                !state.hasUserApprovedScreenRecording
                    RecordIssueTile.TILE_SPEC,
        ) {
                    Context.MODE_PRIVATE,
                    userTracker.userId
                )
            if (!prefs.getBoolean(HAS_APPROVED_SCREEN_RECORDING, false)) {
            mainExecutor.execute {
            mainExecutor.execute {
                    ScreenCapturePermissionDialogDelegate(factory, prefs).createDialog().apply {
                ScreenCapturePermissionDialogDelegate(factory, state).createDialog().apply {
                    setOnCancelListener { screenRecordSwitch.isChecked = false }
                    setOnCancelListener { screenRecordSwitch.isChecked = false }
                    show()
                    show()
                }
                }
            }
            }
        }
        }
    }
    }
    }


    @MainThread
    @MainThread
    private fun onIssueTypeClicked(context: Context, onIssueTypeSelected: Runnable) {
    private fun onIssueTypeClicked(context: Context, onIssueTypeSelected: Runnable) {
        val popupMenu = PopupMenu(context, issueTypeButton)
        val popupMenu = PopupMenu(context, issueTypeButton)


        issueTypeOptions.keys.forEach {
        ALL_ISSUE_TYPES.keys.forEach {
            popupMenu.menu.add(it).apply {
            popupMenu.menu.add(it).apply {
                setIcon(R.drawable.arrow_pointing_down)
                setIcon(R.drawable.arrow_pointing_down)
                if (issueTypeOptions[it] != selectedIssueType) {
                if (it != state.issueTypeRes) {
                    iconTintList = ColorStateList.valueOf(Color.TRANSPARENT)
                    iconTintList = ColorStateList.valueOf(Color.TRANSPARENT)
                }
                }
                intent = Intent().putExtra(INTENT_EXTRA_TRACE_TYPE, issueTypeOptions[it])
                intent = Intent().putExtra(KEY_ISSUE_TYPE_RES, it)
            }
            }
        }
        }
        popupMenu.apply {
        popupMenu.apply {
            setOnMenuItemClickListener {
            setOnMenuItemClickListener {
                issueTypeButton.text = it.title
                issueTypeButton.text = it.title
                selectedIssueType =
                state.issueTypeRes =
                    it.intent?.getSerializableExtra(
                    it.intent?.getIntExtra(KEY_ISSUE_TYPE_RES, ISSUE_TYPE_NOT_SET)
                        INTENT_EXTRA_TRACE_TYPE,
                        ?: ISSUE_TYPE_NOT_SET
                        PresetTraceType::class.java
                    )
                onIssueTypeSelected.run()
                onIssueTypeSelected.run()
                true
                true
            }
            }
Loading