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

Commit 39d35099 authored by Stefan Andonian's avatar Stefan Andonian
Browse files

Share available TAGs with other processes via IPC.

Other apps like system ui may want to start custom traces, but they
don't have access to the perfetto commands that retrieve available tags
due to SELinux constraints. This change creates an API for other apps to
retrieve that data.

Bug: 305049544
Test: Verified via logs that tags are returned from the service
correctly.
Flag: com.android.systemui.record_issue_qs_tile

Change-Id: I06cd2986a6affebc02600c37ef707a96719d14b6
parent 535468ca
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -87,7 +87,10 @@ constructor(
            setNegativeButton(R.string.cancel) { _, _ -> }
            setPositiveButton(R.string.qs_record_issue_start) { _, _ -> onStarted.run() }
        }
        bgExecutor.execute { traceurMessageSender.bindToTraceur(dialog.context) }
        bgExecutor.execute {
            traceurMessageSender.onBoundToTraceur.add { traceurMessageSender.getTags() }
            traceurMessageSender.bindToTraceur(dialog.context)
        }
    }

    override fun createDialog(): SystemUIDialog = factory.create(this)
+37 −2
Original line number Diff line number Diff line
@@ -45,11 +45,15 @@ class TraceurMessageSender @Inject constructor(@Background private val backgroun
    private var binder: Messenger? = null
    private var isBound: Boolean = false

    val onBoundToTraceur = mutableListOf<Runnable>()

    private val traceurConnection =
        object : ServiceConnection {
            override fun onServiceConnected(className: ComponentName, service: IBinder) {
                binder = Messenger(service)
                isBound = true
                onBoundToTraceur.forEach(Runnable::run)
                onBoundToTraceur.clear()
            }

            override fun onServiceDisconnected(className: ComponentName) {
@@ -103,10 +107,16 @@ class TraceurMessageSender @Inject constructor(@Background private val backgroun

    @WorkerThread
    fun shareTraces(context: Context, screenRecord: Uri?) {
        val replyHandler = Messenger(TraceurMessageHandler(context, screenRecord, backgroundLooper))
        val replyHandler = Messenger(ShareFilesHandler(context, screenRecord, backgroundLooper))
        notifyTraceur(MessageConstants.SHARE_WHAT, replyTo = replyHandler)
    }

    @WorkerThread
    fun getTags() {
        val replyHandler = Messenger(TagsHandler(backgroundLooper))
        notifyTraceur(MessageConstants.TAGS_WHAT, replyTo = replyHandler)
    }

    @WorkerThread
    private fun notifyTraceur(what: Int, data: Bundle = Bundle(), replyTo: Messenger? = null) {
        try {
@@ -122,7 +132,7 @@ class TraceurMessageSender @Inject constructor(@Background private val backgroun
        }
    }

    private class TraceurMessageHandler(
    private class ShareFilesHandler(
        private val context: Context,
        private val screenRecord: Uri?,
        looper: Looper,
@@ -154,4 +164,29 @@ class TraceurMessageSender @Inject constructor(@Background private val backgroun
            context.startActivity(fileSharingIntent)
        }
    }

    private class TagsHandler(looper: Looper) : Handler(looper) {

        override fun handleMessage(msg: Message) {
            if (MessageConstants.TAGS_WHAT == msg.what) {
                val keys = msg.data.getStringArrayList(MessageConstants.BUNDLE_KEY_TAGS)
                val values =
                    msg.data.getStringArrayList(MessageConstants.BUNDLE_KEY_TAG_DESCRIPTIONS)
                if (keys == null || values == null) {
                    throw IllegalArgumentException(
                        "Neither keys: $keys, nor values: $values can " + "be null"
                    )
                }

                val tags = keys.zip(values).map { "${it.first}: ${it.second}" }.toSet()
                Log.e(
                    TAG,
                    "These tags: $tags will be saved and used for the Custom Trace" +
                        " Config dialog in a future CL. This log will be removed."
                )
            } else {
                throw IllegalArgumentException("received unknown msg.what: " + msg.what)
            }
        }
    }
}