1 /* 2 * Copyright 2022 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 androidx.camera.integration.diagnose 18 19 import android.content.Context 20 import android.graphics.Bitmap 21 import androidx.annotation.WorkerThread 22 import java.io.File 23 import java.io.FileInputStream 24 import java.io.FileOutputStream 25 import java.util.zip.ZipEntry 26 import java.util.zip.ZipOutputStream 27 28 /** 29 * DataStore object that store {@link DiagnosisTask} results (text and images) to files in a Zip 30 * File. 31 */ 32 class DataStore(context: Context, zipFileName: String) { 33 34 private val zipFile: File 35 private val fout: FileOutputStream 36 private val zout: ZipOutputStream 37 private val logger: StringBuffer 38 39 init { 40 // create zip file 41 zipFile = createZip(context, zipFileName) 42 zipFile.deleteOnExit() 43 44 // open output streams 45 fout = FileOutputStream(zipFile) 46 zout = ZipOutputStream(fout) 47 48 // single logger used for all tasks 49 logger = StringBuffer() 50 } 51 52 /** Append text to store in logger */ appendTextnull53 fun appendText(text: String) { 54 logger.appendLine(text) 55 } 56 appendTitlenull57 fun appendTitle(taskName: String) { 58 appendText("Task name: $taskName") 59 } 60 61 /** Copy and flush file as an image file to a ZipEntry */ 62 @WorkerThread flushTempFileToImageFilenull63 fun flushTempFileToImageFile(file: File, filename: String) { 64 val inputStream = FileInputStream(file) 65 zout.putNextEntry(ZipEntry("$filename.jpeg")) 66 inputStream.copyTo(zout) 67 zout.closeEntry() 68 } 69 70 /** Flush text in logger as a text file to a ZipEntry and clear logger */ 71 @WorkerThread flushTextToTextFilenull72 fun flushTextToTextFile(filename: String) { 73 if (logger.isEmpty()) { 74 return 75 } 76 zout.putNextEntry(ZipEntry("$filename.txt")) 77 zout.write(logger.toString().toByteArray()) 78 zout.closeEntry() 79 // clear logger 80 logger.setLength(0) 81 } 82 83 /** Flush bitmap as JPEG to a ZipEntry */ 84 @WorkerThread flushBitmapToFilenull85 fun flushBitmapToFile(imageName: String, bitmap: Bitmap) { 86 zout.putNextEntry(ZipEntry(("$imageName.jpeg"))) 87 bitmap.compress(Bitmap.CompressFormat.JPEG, 100, zout) 88 zout.closeEntry() 89 } 90 91 /** Close output streams and return zip file */ flushZipnull92 fun flushZip(): File { 93 zout.close() 94 fout.close() 95 96 return zipFile 97 } 98 createZipnull99 private fun createZip(context: Context, filename: String): File { 100 val dir = File("${context.externalCacheDir}") 101 if (!dir.exists()) { 102 assert(dir.mkdirs()) 103 } 104 return File(dir, filename) 105 } 106 } 107