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 17 package platform.test.screenshot.report 18 19 import android.graphics.Bitmap 20 import android.os.Build 21 import platform.test.screenshot.GoldenPathManager 22 import platform.test.screenshot.proto.ScreenshotResultProto.DiffResult 23 24 /** 25 * Strategy to "export" the results of a bitmap diff to an external system, such as Scuba. 26 * 27 * This allows to implement a strategy to pass the results to the external system which is 28 * appropriate for the environment the Android test is running in. 29 */ 30 interface DiffResultExportStrategy { 31 /** 32 * TODO(b/322324387) Simplify this interface. Right now, this is just factoring out the existing 33 * call. 34 */ reportResultnull35 fun reportResult( 36 testIdentifier: String, 37 goldenIdentifier: String, 38 actual: Bitmap, 39 status: DiffResult.Status, 40 comparisonStatistics: DiffResult.ComparisonStatistics? = null, 41 expected: Bitmap? = null, 42 diff: Bitmap? = null 43 ) 44 45 companion object { 46 /** Creates the export strategy to be used in Android tests. */ 47 fun createDefaultStrategy(goldenPathManager: GoldenPathManager): DiffResultExportStrategy { 48 val exportStrategy = ExportToScubaStrategy(goldenPathManager) 49 50 val isRobolectric = Build.FINGERPRINT.contains("robolectric") 51 val doesWriteScreenshotToLocal = 52 "yes".equals( 53 System.getProperty("screenshot.writeScreenshotToLocal"), ignoreCase = true) 54 55 return if (isRobolectric && doesWriteScreenshotToLocal) { 56 MultiplexedStrategy( 57 listOf(exportStrategy, DevicelessDevMachineExportStrategy(goldenPathManager)) 58 ) 59 } else { 60 exportStrategy 61 } 62 } 63 } 64 } 65 66 /** Delegates [reportResult] calls to all [strategies]. */ 67 private class MultiplexedStrategy(private val strategies: List<DiffResultExportStrategy>) : 68 DiffResultExportStrategy { reportResultnull69 override fun reportResult( 70 testIdentifier: String, 71 goldenIdentifier: String, 72 actual: Bitmap, 73 status: DiffResult.Status, 74 comparisonStatistics: DiffResult.ComparisonStatistics?, 75 expected: Bitmap?, 76 diff: Bitmap? 77 ) { 78 strategies.forEach { 79 it.reportResult( 80 testIdentifier, 81 goldenIdentifier, 82 actual, 83 status, 84 comparisonStatistics, 85 expected, 86 diff 87 ) 88 } 89 } 90 } 91