1 /* 2 * Copyright (C) 2024 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package com.example.tracing.demo.experiments 17 18 import android.os.Trace 19 import com.android.app.tracing.coroutines.flow.collectTraced 20 import com.android.app.tracing.coroutines.flow.filterTraced as filter 21 import com.android.app.tracing.coroutines.flow.filterTraced 22 import com.android.app.tracing.coroutines.flow.flowName 23 import com.android.app.tracing.coroutines.flow.mapTraced as map 24 import com.android.app.tracing.coroutines.flow.mapTraced 25 import com.android.app.tracing.coroutines.flow.onEachTraced 26 import com.example.tracing.demo.FixedThread1 27 import com.example.tracing.demo.FixedThread2 28 import com.example.tracing.demo.FixedThread3 29 import javax.inject.Inject 30 import javax.inject.Singleton 31 import kotlinx.coroutines.CoroutineDispatcher 32 import kotlinx.coroutines.flow.flow 33 import kotlinx.coroutines.flow.flowOn 34 35 @Singleton 36 class CollectFlow 37 @Inject 38 constructor( 39 @FixedThread1 private var dispatcher1: CoroutineDispatcher, 40 @FixedThread2 private var dispatcher2: CoroutineDispatcher, 41 @FixedThread3 private val dispatcher3: CoroutineDispatcher, 42 ) : TracedExperiment() { 43 override val description: String = "Collect a cold flow with intermediate operators" 44 45 private val coldFlow = <lambda>null46 flow { 47 var n = 0 48 while (true) { 49 Trace.instant(Trace.TRACE_TAG_APP, "emit:$n") 50 emit(n++) 51 forceSuspend(timeMillis = 8) 52 } 53 } <lambda>null54 .mapTraced("A") { 55 Trace.instant(Trace.TRACE_TAG_APP, "map:$it") 56 it 57 } <lambda>null58 .onEachTraced("B") { Trace.instant(Trace.TRACE_TAG_APP, "onEach:$it") } <lambda>null59 .filterTraced("C") { 60 Trace.instant(Trace.TRACE_TAG_APP, "filter:$it") 61 true 62 } 63 .flowOn(dispatcher3) 64 .flowName("inner-flow") <lambda>null65 .filter("evens") { 66 forceSuspend(timeMillis = 4) 67 Trace.instant(Trace.TRACE_TAG_APP, "filter-evens") 68 it % 2 == 0 69 } 70 .flowName("middle-flow") 71 .flowOn(dispatcher2) <lambda>null72 .map("3x") { 73 forceSuspend(timeMillis = 2) 74 Trace.instant(Trace.TRACE_TAG_APP, "3x") 75 it * 3 76 } 77 .flowOn(dispatcher1) 78 .flowName("outer-flow") 79 runExperimentnull80 override suspend fun runExperiment() { 81 coldFlow.collectTraced("collect-flow") { Trace.instant(Trace.TRACE_TAG_APP, "got: $it") } 82 } 83 } 84