From 7f2d2c5b3c46360a998694b7603a88c4656a72c7 Mon Sep 17 00:00:00 2001 From: roynatech2544 Date: Tue, 16 Nov 2021 12:56:26 +0900 Subject: [PATCH] universal7885: CameraLightSensor: Convert to Kotlin Change-Id: I8162d1f88583143a333b282ad59e45085ec66023 Signed-off-by: roynatech2544 --- .../apps/CameraLightSensor/Android.bp | 2 +- .../cameralightsensor/BootReceiver.java | 18 - .../cameralightsensor/BootReceiver.kt | 14 + .../CameraLightSensorService.java | 427 ----------------- .../CameraLightSensorService.kt | 432 ++++++++++++++++++ 5 files changed, 447 insertions(+), 446 deletions(-) delete mode 100755 universal7885-common/apps/CameraLightSensor/src/com/eurekateam/cameralightsensor/BootReceiver.java create mode 100755 universal7885-common/apps/CameraLightSensor/src/com/eurekateam/cameralightsensor/BootReceiver.kt delete mode 100755 universal7885-common/apps/CameraLightSensor/src/com/eurekateam/cameralightsensor/CameraLightSensorService.java create mode 100755 universal7885-common/apps/CameraLightSensor/src/com/eurekateam/cameralightsensor/CameraLightSensorService.kt diff --git a/universal7885-common/apps/CameraLightSensor/Android.bp b/universal7885-common/apps/CameraLightSensor/Android.bp index 6b28d05..2e9772c 100644 --- a/universal7885-common/apps/CameraLightSensor/Android.bp +++ b/universal7885-common/apps/CameraLightSensor/Android.bp @@ -1,7 +1,7 @@ android_app { name: "CameraLightSensor", srcs: [ - "src/**/*.java", + "src/**/*.kt", ], platform_apis: true, privileged: true, diff --git a/universal7885-common/apps/CameraLightSensor/src/com/eurekateam/cameralightsensor/BootReceiver.java b/universal7885-common/apps/CameraLightSensor/src/com/eurekateam/cameralightsensor/BootReceiver.java deleted file mode 100755 index b849dbe..0000000 --- a/universal7885-common/apps/CameraLightSensor/src/com/eurekateam/cameralightsensor/BootReceiver.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.eurekateam.cameralightsensor; - -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import com.eurekateam.cameralightsensor.CameraLightSensorService; - -public class BootReceiver extends BroadcastReceiver { - @Override - public void onReceive(Context context, Intent intent) { - if (intent.getAction().equalsIgnoreCase(Intent.ACTION_BOOT_COMPLETED)) { - if (context != null) { - final Intent i = new Intent(context, CameraLightSensorService.class); - context.startForegroundService(i); - } - } - } -} diff --git a/universal7885-common/apps/CameraLightSensor/src/com/eurekateam/cameralightsensor/BootReceiver.kt b/universal7885-common/apps/CameraLightSensor/src/com/eurekateam/cameralightsensor/BootReceiver.kt new file mode 100755 index 0000000..e0c7bd1 --- /dev/null +++ b/universal7885-common/apps/CameraLightSensor/src/com/eurekateam/cameralightsensor/BootReceiver.kt @@ -0,0 +1,14 @@ +package com.eurekateam.cameralightsensor + +import android.content.BroadcastReceiver +import android.content.Context +import android.content.Intent + +class BootReceiver : BroadcastReceiver() { + override fun onReceive(context: Context, intent: Intent) { + if (intent.action.equals(Intent.ACTION_BOOT_COMPLETED, ignoreCase = true)) { + val i = Intent(context, CameraLightSensorService::class.java) + context.startForegroundService(i) + } + } +} \ No newline at end of file diff --git a/universal7885-common/apps/CameraLightSensor/src/com/eurekateam/cameralightsensor/CameraLightSensorService.java b/universal7885-common/apps/CameraLightSensor/src/com/eurekateam/cameralightsensor/CameraLightSensorService.java deleted file mode 100755 index f6bf9d0..0000000 --- a/universal7885-common/apps/CameraLightSensor/src/com/eurekateam/cameralightsensor/CameraLightSensorService.java +++ /dev/null @@ -1,427 +0,0 @@ -package com.eurekateam.cameralightsensor; - -import android.annotation.NonNull; -import android.annotation.SuppressLint; -import android.app.Notification; -import android.app.NotificationChannel; -import android.app.NotificationManager; -import android.app.PendingIntent; -import android.app.Service; -import android.content.BroadcastReceiver; -import android.content.ContentResolver; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.content.pm.ServiceInfo; -import android.database.ContentObserver; -import android.graphics.Bitmap; -import android.graphics.BitmapFactory; -import android.graphics.Color; -import android.graphics.ImageFormat; -import android.hardware.camera2.CameraAccessException; -import android.hardware.camera2.CameraCaptureSession; -import android.hardware.camera2.CameraCharacteristics; -import android.hardware.camera2.CameraDevice; -import android.hardware.camera2.CameraManager; -import android.hardware.camera2.CaptureRequest; -import android.media.Image; -import android.media.ImageReader; -import android.net.Uri; -import android.os.Handler; -import android.os.IBinder; -import android.os.Looper; -import android.os.PowerManager; -import android.os.SystemClock; -import android.provider.Settings; -import android.util.Log; - -import androidx.core.app.NotificationCompat; -import androidx.core.content.ContextCompat; - -import java.nio.ByteBuffer; -import java.util.Collections; - -public class CameraLightSensorService extends Service { - protected static final String TAG = CameraLightSensorService.class.getSimpleName(); - static final boolean DEBUG = false; - IntentFilter screenStateFilter; - private Context mContext; - public ContentResolver contentResolver; - private boolean mRegistered; - protected static final int CAMERA_CHOICE = CameraCharacteristics.LENS_FACING_FRONT; - boolean destroy; - protected CameraDevice cameraDevice; - protected CameraCaptureSession session; - volatile boolean avail = true; - protected ImageReader imageReader; - private CameraManager manager; - private final static int DELAY = 5 * 1000; // 5 Seconds - private boolean mServiceStarted; - volatile private boolean mLock; - private boolean mThreadRunning; - - public Notification PushNotification() - { - NotificationManager nm = (NotificationManager) mContext.getSystemService(NOTIFICATION_SERVICE); - NotificationChannel channel = new NotificationChannel( - mContext.getBasePackageName(), "CameraLightSensor", - NotificationManager.IMPORTANCE_LOW - ); - nm.createNotificationChannel(channel); - NotificationCompat.Builder builder = - new NotificationCompat.Builder(mContext, mContext.getBasePackageName()); - Intent notificationIntent = new Intent(mContext, CameraLightSensorService.class); - PendingIntent contentIntent = PendingIntent.getActivity(mContext,50, - notificationIntent,PendingIntent.FLAG_IMMUTABLE); - - //set - builder.setContentIntent(contentIntent); - builder.setSmallIcon(R.drawable.ic_brightness); - builder.setContentTitle("Camera Light Sensor Service"); - builder.setChannelId(mContext.getBasePackageName()); - - return builder.build(); - } - - @Override - public void onDestroy() { - if (DEBUG) Log.d(TAG, "Destroying service"); - if(mRegistered) contentResolver.unregisterContentObserver(mSettingsObserver); - mRegistered = false; - cameraDevice.close(); - if (session != null && avail) { - try { - session.abortCaptures(); - session.close(); - } catch (CameraAccessException e) { - Log.e(TAG, e.getMessage()); - } catch (IllegalStateException e2){ - Log.e(TAG, "Session Already Closed"); - } - - } - manager.unregisterAvailabilityCallback(availabilityCallback); - avail = false; - destroy = true; - stopForeground(true); - super.onDestroy(); - } - - @Override - public IBinder onBind(Intent intent) { - return null; - } - - private final BroadcastReceiver mScreenStateReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) { - onDisplayOn(); - mServiceStarted = true; - } else if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) { - if (mServiceStarted) onDisplayOff(); - mServiceStarted = false; - } - } - }; - // Make a listener for settings - ContentObserver mSettingsObserver = new ContentObserver(new Handler(Looper.getMainLooper())) { - @Override - public void onChange(boolean selfChange) { - super.onChange(selfChange); - Log.i(TAG, "observer: Brightness Settings Changed"); - try { - if(Settings.System.getInt(contentResolver, Settings.System.SCREEN_BRIGHTNESS_MODE) - == Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC){ - registerReceiver(mScreenStateReceiver, screenStateFilter); - mRegistered = true; - onDisplayOn(); - }else{ - if(mRegistered) unregisterReceiver(mScreenStateReceiver); - mRegistered = false; - onDisplayOff(); - } - } catch (Settings.SettingNotFoundException e) { - e.printStackTrace(); - } - } - @Override - public boolean deliverSelfNotifications() { - return true; - } - }; - - private void onDisplayOn() { - if(DEBUG) Log.d(TAG, "Screen is on. Starting Service..."); - avail = true; - readyCamera(); - } - private void onDisplayOff(){ - if(DEBUG) Log.d(TAG, "Screen is off. Stopping Service..."); - thread.interrupt(); - avail = false; - mThreadRunning = false; - } - public static void BatteryOptimization(Context context){ - Intent intent = new Intent(); - String packageName = context.getPackageName(); - PowerManager pm = (PowerManager) context.getSystemService(POWER_SERVICE); - if (!pm.isIgnoringBatteryOptimizations(packageName)) { - intent.setAction(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS); - intent.setData(Uri.parse("package:" + packageName)); - intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - context.startActivity(intent); - } - } - protected CameraDevice.StateCallback cameraStateCallback = new CameraDevice.StateCallback() { - @Override - public void onOpened(@NonNull CameraDevice camera) { - Log.d(TAG, "CameraDevice.StateCallback onOpened"); - cameraDevice = camera; - actOnReadyCameraDevice(); - } - - @Override - public void onDisconnected(@NonNull CameraDevice camera) { - Log.w(TAG, "CameraDevice.StateCallback onDisconnected"); - } - - @Override - public void onError(@NonNull CameraDevice camera, int error) { - Log.e(TAG, "CameraDevice.StateCallback onError " + error); - } - }; - - protected CameraCaptureSession.StateCallback sessionStateCallback = new CameraCaptureSession.StateCallback() { - - @Override - public void onReady(CameraCaptureSession session) { - if (!destroy) { - CameraLightSensorService.this.session = session; - try { - if (createCaptureRequest() == null) return; - try { - session.capture(createCaptureRequest(), captureCallback, null); - } catch (CameraAccessException e) { - e.printStackTrace(); - } catch (IllegalStateException e) { - Log.w(TAG, "onReady: Session is NULL"); - } - } catch (Exception e) { - Log.e(TAG, "Camera is in use"); - e.printStackTrace(); - } - } - } - - - @Override - public void onConfigured(CameraCaptureSession session) { - - } - - @Override - public void onConfigureFailed(@NonNull CameraCaptureSession session) { - } - }; - - - protected ImageReader.OnImageAvailableListener onImageAvailableListener = reader -> { - if (DEBUG) Log.d(TAG, "onImageAvailable: Capturing"); - Image img = reader.acquireLatestImage(); - if (img != null) { - try { - processImage(img); - } catch (Settings.SettingNotFoundException | InterruptedException e) { - e.printStackTrace(); - } - img.close(); - if (DEBUG) - Log.d(TAG, "ImageReader.OnImageAvailableListener: Closing Camera and Sessions.."); - cameraDevice.close(); - session.close(); - } - }; - - @SuppressLint("MissingPermission") - public void readyCamera() { - manager = (CameraManager) getSystemService(CAMERA_SERVICE); - try { - String pickedCamera = getCamera(manager); - manager.registerAvailabilityCallback(availabilityCallback, null); - manager.openCamera(pickedCamera, cameraStateCallback, null); - imageReader = ImageReader.newInstance(250, 250, ImageFormat.JPEG, 2 /* images buffered */); - imageReader.setOnImageAvailableListener(onImageAvailableListener, null); - if(!mThreadRunning){ - Thread mMyThread = new Thread(thread); - mMyThread.start(); - mThreadRunning = true; - } - if (DEBUG) Log.d(TAG, "imageReader created"); - } catch (CameraAccessException e) { - Log.e(TAG, e.getMessage()); - } - } - - public String getCamera(CameraManager manager) { - try { - for (String cameraId : manager.getCameraIdList()) { - CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraId); - int cOrientation = characteristics.get(CameraCharacteristics.LENS_FACING); - if (cOrientation == CAMERA_CHOICE) { - return cameraId; - } - } - } catch (CameraAccessException e) { - e.printStackTrace(); - } - return null; - } - @Override - public int onStartCommand(Intent intent, int flags, int startId) { - mContext = getApplicationContext(); - contentResolver = getContentResolver(); - startForeground(50, PushNotification(), ServiceInfo.FOREGROUND_SERVICE_TYPE_CAMERA); - BatteryOptimization(mContext); - mRegistered = false; - screenStateFilter = new IntentFilter(Intent.ACTION_SCREEN_ON); - screenStateFilter.addAction(Intent.ACTION_SCREEN_OFF); - try { - if(Settings.System.getInt(contentResolver, Settings.System.SCREEN_BRIGHTNESS_MODE) - == Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC){ - registerReceiver(mScreenStateReceiver, screenStateFilter); - mRegistered = true; - } - } catch (Settings.SettingNotFoundException e) { - e.printStackTrace(); - } - Uri setting = Settings.System.getUriFor(Settings.System.SCREEN_BRIGHTNESS_MODE); - contentResolver.registerContentObserver(setting, false, mSettingsObserver); - if(DEBUG) Log.d(TAG, "onStartCommand flags " + flags + " startId " + startId); - destroy = false; - avail = true; - startForeground(50, PushNotification()); - return START_STICKY; - } - - @Override - public void onCreate() { - if(DEBUG) Log.d(TAG, "onCreate service"); - mContext = getApplicationContext(); - startForeground(50, PushNotification()); - super.onCreate(); - } - - public void actOnReadyCameraDevice() { - try { - cameraDevice.createCaptureSession(Collections.singletonList(imageReader.getSurface()), sessionStateCallback, null); - } catch (CameraAccessException e) { - Log.e(TAG, e.getMessage()); - mLock = false; - } - } - private void processImage(Image image) throws Settings.SettingNotFoundException, InterruptedException { - ByteBuffer buffer = image.getPlanes()[0].getBuffer(); - byte[] bytes = new byte[buffer.capacity()]; - buffer.get(bytes); - Bitmap bitmapImage = BitmapFactory.decodeByteArray(bytes, 0, bytes.length, null); - int brightness = calculateBrightnessEstimate(bitmapImage,5); - AdjustBrightness(brightness); - } - - protected CaptureRequest createCaptureRequest() { - try { - CaptureRequest.Builder builder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_RECORD); - builder.addTarget(imageReader.getSurface()); - return builder.build(); - } catch (CameraAccessException e) { - Log.e(TAG, e.getMessage()); - mLock = false; - return null; - } - } - CameraManager.AvailabilityCallback availabilityCallback = new CameraManager.AvailabilityCallback() { - @Override - public void onCameraOpened(String cameraId, String packageId) { - super.onCameraOpened(cameraId, packageId); - Log.i(TAG, "CameraManager.AvailabilityCallback: Camera " + cameraId - + " Opened by Package " + packageId); - mLock = true; - if (packageId.equals(mContext.getBasePackageName())) return; - avail = false; - } - - @Override - public void onCameraUnavailable(String cameraId) { - if (DEBUG) Log.i(TAG, "CameraManager.AvailabilityCallback : Camera NOT Available. "); - avail = false; - super.onCameraUnavailable(cameraId); - } - - @Override - public void onCameraAvailable(String cameraId) { - if (DEBUG) Log.i(TAG, "CameraManager.AvailabilityCallback : Camera IS Available. "); - avail = true; - mLock = false; - super.onCameraAvailable(cameraId); - } - - @Override - public void onCameraClosed(String cameraId) { - super.onCameraClosed(cameraId); - } - - }; - CameraCaptureSession.CaptureCallback captureCallback = new CameraCaptureSession.CaptureCallback() { - @Override - public void onCaptureSequenceCompleted(CameraCaptureSession session, int sequenceId, long frameNumber) { - if (DEBUG) Log.d(TAG, "captureCallback: Closing Session"); - super.onCaptureSequenceCompleted(session, sequenceId, frameNumber); - cameraDevice.close(); - session.close(); - } - - }; - - public int calculateBrightnessEstimate(Bitmap bitmap, int pixelSpacing) { - int R = 0; int G = 0; int B = 0; - int height = bitmap.getHeight(); - int width = bitmap.getWidth(); - int n = 0; - int[] pixels = new int[width * height]; - bitmap.getPixels(pixels, 0, width, 0, 0, width, height); - for (int i = 0; i < pixels.length; i += pixelSpacing) { - int color = pixels[i]; - R += Color.red(color); - G += Color.green(color); - B += Color.blue(color); - n++; - } - return (R + B + G) / (n * 3); - } - private void AdjustBrightness(int brightness) throws Settings.SettingNotFoundException { - if (DEBUG) Log.i(TAG, "AdjustBrightness: Received Brightness Value " + brightness); - int oldbrightness = Settings.System.getInt(getContentResolver(), Settings.System.SCREEN_BRIGHTNESS); - if (DEBUG) Log.i(TAG, "AdjustBrightness: OldVal = " + oldbrightness + " NewVal = " + - brightness + " Adjusting.."); - int newbrightness = brightness; - if (newbrightness > 255){ - newbrightness = 255; - }else if (newbrightness < 0){ - newbrightness = 0; - } - Settings.System.putInt(getContentResolver(), Settings.System.SCREEN_BRIGHTNESS, newbrightness); - } - Thread thread = new Thread(() -> { - while (!Thread.currentThread().isInterrupted()) { - if (avail && !mLock) { - SystemClock.sleep(DELAY); - ContextCompat.getMainExecutor(mContext).execute(() -> { - if (avail) readyCamera(); - }); - } - } - - }); -} - diff --git a/universal7885-common/apps/CameraLightSensor/src/com/eurekateam/cameralightsensor/CameraLightSensorService.kt b/universal7885-common/apps/CameraLightSensor/src/com/eurekateam/cameralightsensor/CameraLightSensorService.kt new file mode 100755 index 0000000..1454da9 --- /dev/null +++ b/universal7885-common/apps/CameraLightSensor/src/com/eurekateam/cameralightsensor/CameraLightSensorService.kt @@ -0,0 +1,432 @@ +package com.eurekateam.cameralightsensor + +import android.hardware.camera2.CameraDevice +import android.hardware.camera2.CameraCaptureSession +import kotlin.jvm.Volatile +import android.hardware.camera2.CameraManager +import androidx.core.app.NotificationCompat +import android.hardware.camera2.CameraAccessException +import android.database.ContentObserver +import android.provider.Settings.SettingNotFoundException +import android.annotation.SuppressLint +import android.app.* +import android.content.* +import android.content.pm.ServiceInfo +import android.hardware.camera2.CameraCharacteristics +import kotlin.Throws +import android.graphics.Bitmap +import android.graphics.BitmapFactory +import android.graphics.Color +import android.graphics.ImageFormat +import android.hardware.camera2.CaptureRequest +import android.hardware.camera2.CameraManager.AvailabilityCallback +import android.media.Image +import android.media.ImageReader +import android.net.Uri +import android.os.* +import androidx.core.content.ContextCompat +import android.provider.Settings +import android.util.Log +import java.lang.Exception +import java.lang.IllegalStateException + +open class CameraLightSensorService : Service() { + var screenStateFilter: IntentFilter? = null + private var mContext: Context? = null + private var mRegistered = false + var destroy = false + private var cameraDevice: CameraDevice? = null + private var session: CameraCaptureSession? = null + + @Volatile + var avail = true + private var imageReader: ImageReader? = null + private var manager: CameraManager? = null + private var mServiceStarted = false + + @Volatile + private var mLock = false + private var mThreadRunning = false + private fun PushNotification(): Notification { + val nm = mContext!!.getSystemService(NOTIFICATION_SERVICE) as NotificationManager + val channel = NotificationChannel( + mContext!!.basePackageName, "CameraLightSensor", + NotificationManager.IMPORTANCE_LOW + ) + nm.createNotificationChannel(channel) + val builder = NotificationCompat.Builder(mContext!!, mContext!!.basePackageName) + val notificationIntent = Intent(mContext, CameraLightSensorService::class.java) + val contentIntent = PendingIntent.getActivity( + mContext, 50, + notificationIntent, PendingIntent.FLAG_IMMUTABLE + ) + + //set + builder.setContentIntent(contentIntent) + builder.setSmallIcon(R.drawable.ic_brightness) + builder.setContentTitle("Camera Light Sensor Service") + builder.setChannelId(mContext!!.basePackageName) + return builder.build() + } + + override fun onDestroy() { + if (DEBUG) Log.d(TAG, "Destroying service") + if (mRegistered) contentResolver!!.unregisterContentObserver(mSettingsObserver) + mRegistered = false + cameraDevice!!.close() + if (session != null && avail) { + try { + session!!.abortCaptures() + session!!.close() + } catch (e: CameraAccessException) { + Log.e(TAG, e.message) + } catch (e2: IllegalStateException) { + Log.e(TAG, "Session Already Closed") + } + } + manager!!.unregisterAvailabilityCallback(availabilityCallback) + avail = false + destroy = true + stopForeground(true) + super.onDestroy() + } + + override fun onBind(intent: Intent): IBinder? { + return null + } + + private val mScreenStateReceiver: BroadcastReceiver = object : BroadcastReceiver() { + override fun onReceive(context: Context, intent: Intent) { + if (intent.action == Intent.ACTION_SCREEN_ON) { + onDisplayOn() + mServiceStarted = true + } else if (intent.action == Intent.ACTION_SCREEN_OFF) { + if (mServiceStarted) onDisplayOff() + mServiceStarted = false + } + } + } + + // Make a listener for settings + private var mSettingsObserver: ContentObserver = + object : ContentObserver(Handler(Looper.getMainLooper())) { + override fun onChange(selfChange: Boolean) { + super.onChange(selfChange) + Log.i(TAG, "observer: Brightness Settings Changed") + try { + if (Settings.System.getInt( + contentResolver, + Settings.System.SCREEN_BRIGHTNESS_MODE + ) + == Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC + ) { + registerReceiver(mScreenStateReceiver, screenStateFilter) + mRegistered = true + onDisplayOn() + } else { + if (mRegistered) unregisterReceiver(mScreenStateReceiver) + mRegistered = false + onDisplayOff() + } + } catch (e: SettingNotFoundException) { + e.printStackTrace() + } + } + + override fun deliverSelfNotifications(): Boolean { + return true + } + } + + private fun onDisplayOn() { + if (DEBUG) Log.d(TAG, "Screen is on. Starting Service...") + avail = true + readyCamera() + } + + private fun onDisplayOff() { + if (DEBUG) Log.d(TAG, "Screen is off. Stopping Service...") + thread.interrupt() + avail = false + mThreadRunning = false + } + + private var cameraStateCallback: CameraDevice.StateCallback = + object : CameraDevice.StateCallback() { + override fun onOpened(camera: CameraDevice) { + Log.d(TAG, "CameraDevice.StateCallback onOpened") + cameraDevice = camera + actOnReadyCameraDevice() + } + + override fun onDisconnected(camera: CameraDevice) { + Log.w(TAG, "CameraDevice.StateCallback onDisconnected") + } + + override fun onError(camera: CameraDevice, error: Int) { + Log.e(TAG, "CameraDevice.StateCallback onError $error") + } + } + private var sessionStateCallback: CameraCaptureSession.StateCallback = + object : CameraCaptureSession.StateCallback() { + override fun onReady(session: CameraCaptureSession) { + if (!destroy) { + this@CameraLightSensorService.session = session + try { + if (createCaptureRequest() == null) return + try { + session.capture(createCaptureRequest(), captureCallback, null) + } catch (e: CameraAccessException) { + e.printStackTrace() + } catch (e: IllegalStateException) { + Log.w(TAG, "onReady: Session is NULL") + } + } catch (e: Exception) { + Log.e(TAG, "Camera is in use") + e.printStackTrace() + } + } + } + + override fun onConfigured(session: CameraCaptureSession) {} + override fun onConfigureFailed(session: CameraCaptureSession) {} + } + private var onImageAvailableListener = + ImageReader.OnImageAvailableListener { reader: ImageReader -> + if (DEBUG) Log.d(TAG, "onImageAvailable: Capturing") + val img = reader.acquireLatestImage() + if (img != null) { + try { + processImage(img) + } catch (e: SettingNotFoundException) { + e.printStackTrace() + } catch (e: InterruptedException) { + e.printStackTrace() + } + img.close() + if (DEBUG) Log.d( + TAG, + "ImageReader.OnImageAvailableListener: Closing Camera and Sessions.." + ) + cameraDevice!!.close() + session!!.close() + } + } + + @SuppressLint("MissingPermission") + fun readyCamera() { + manager = getSystemService(CAMERA_SERVICE) as CameraManager + try { + val pickedCamera = getCamera(manager) + manager!!.registerAvailabilityCallback(availabilityCallback, null) + manager!!.openCamera(pickedCamera, cameraStateCallback, null) + imageReader = + ImageReader.newInstance(250, 250, ImageFormat.JPEG, 2 /* images buffered */) + imageReader?.setOnImageAvailableListener(onImageAvailableListener, null) + if (!mThreadRunning) { + val mMyThread = Thread(thread) + mMyThread.start() + mThreadRunning = true + } + if (DEBUG) Log.d(TAG, "imageReader created") + } catch (e: CameraAccessException) { + Log.e(TAG, e.message) + } + } + + private fun getCamera(manager: CameraManager?): String? { + try { + for (cameraId in manager!!.cameraIdList) { + val characteristics = manager.getCameraCharacteristics(cameraId) + val cOrientation = characteristics.get(CameraCharacteristics.LENS_FACING) + if (cOrientation == CAMERA_CHOICE) { + return cameraId + } + } + } catch (e: CameraAccessException) { + e.printStackTrace() + } + return null + } + + override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int { + mContext = applicationContext + startForeground(50, PushNotification(), ServiceInfo.FOREGROUND_SERVICE_TYPE_CAMERA) + BatteryOptimization(mContext) + mRegistered = false + screenStateFilter = IntentFilter(Intent.ACTION_SCREEN_ON) + screenStateFilter!!.addAction(Intent.ACTION_SCREEN_OFF) + try { + if (Settings.System.getInt(contentResolver, Settings.System.SCREEN_BRIGHTNESS_MODE) + == Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC + ) { + registerReceiver(mScreenStateReceiver, screenStateFilter) + mRegistered = true + } + } catch (e: SettingNotFoundException) { + e.printStackTrace() + } + val setting = Settings.System.getUriFor(Settings.System.SCREEN_BRIGHTNESS_MODE) + contentResolver?.registerContentObserver(setting, false, mSettingsObserver) + if (DEBUG) Log.d(TAG, "onStartCommand flags $flags startId $startId") + destroy = false + avail = true + startForeground(50, PushNotification()) + return START_STICKY + } + + override fun onCreate() { + if (DEBUG) Log.d(TAG, "onCreate service") + mContext = applicationContext + startForeground(50, PushNotification()) + super.onCreate() + } + + fun actOnReadyCameraDevice() { + try { + cameraDevice!!.createCaptureSession( + listOf(imageReader!!.surface), + sessionStateCallback, + null + ) + } catch (e: CameraAccessException) { + Log.e(TAG, e.message) + mLock = false + } + } + + @Throws(SettingNotFoundException::class, InterruptedException::class) + private fun processImage(image: Image) { + val buffer = image.planes[0].buffer + val bytes = ByteArray(buffer.capacity()) + buffer[bytes] + val bitmapImage = BitmapFactory.decodeByteArray(bytes, 0, bytes.size, null) + val brightness = calculateBrightnessEstimate(bitmapImage, 5) + AdjustBrightness(brightness) + } + + protected fun createCaptureRequest(): CaptureRequest? { + return try { + val builder = cameraDevice!!.createCaptureRequest(CameraDevice.TEMPLATE_RECORD) + builder.addTarget(imageReader!!.surface) + builder.build() + } catch (e: CameraAccessException) { + Log.e(TAG, e.message) + mLock = false + null + } + } + + private var availabilityCallback: AvailabilityCallback = object : AvailabilityCallback() { + override fun onCameraOpened(cameraId: String, packageId: String) { + super.onCameraOpened(cameraId, packageId) + Log.i( + TAG, "CameraManager.AvailabilityCallback: Camera " + cameraId + + " Opened by Package " + packageId + ) + mLock = true + if (packageId == mContext!!.basePackageName) return + avail = false + } + + override fun onCameraUnavailable(cameraId: String) { + if (DEBUG) Log.i(TAG, "CameraManager.AvailabilityCallback : Camera NOT Available. ") + avail = false + super.onCameraUnavailable(cameraId) + } + + override fun onCameraAvailable(cameraId: String) { + if (DEBUG) Log.i(TAG, "CameraManager.AvailabilityCallback : Camera IS Available. ") + avail = true + mLock = false + super.onCameraAvailable(cameraId) + } + + override fun onCameraClosed(cameraId: String) { + super.onCameraClosed(cameraId) + } + } + var captureCallback: CameraCaptureSession.CaptureCallback = + object : CameraCaptureSession.CaptureCallback() { + override fun onCaptureSequenceCompleted( + session: CameraCaptureSession, + sequenceId: Int, + frameNumber: Long + ) { + if (DEBUG) Log.d(TAG, "captureCallback: Closing Session") + super.onCaptureSequenceCompleted(session, sequenceId, frameNumber) + cameraDevice!!.close() + session.close() + } + } + + private fun calculateBrightnessEstimate(bitmap: Bitmap, pixelSpacing: Int): Int { + var R = 0 + var G = 0 + var B = 0 + val height = bitmap.height + val width = bitmap.width + var n = 0 + val pixels = IntArray(width * height) + bitmap.getPixels(pixels, 0, width, 0, 0, width, height) + var i = 0 + while (i < pixels.size) { + val color = pixels[i] + R += Color.red(color) + G += Color.green(color) + B += Color.blue(color) + n++ + i += pixelSpacing + } + return (R + B + G) / (n * 3) + } + + @Throws(SettingNotFoundException::class) + private fun AdjustBrightness(brightness: Int) { + if (DEBUG) Log.i(TAG, "AdjustBrightness: Received Brightness Value $brightness") + val oldbrightness = + Settings.System.getInt(contentResolver, Settings.System.SCREEN_BRIGHTNESS) + if (DEBUG) Log.i( + TAG, "AdjustBrightness: OldVal = " + oldbrightness + " NewVal = " + + brightness + " Adjusting.." + ) + var newbrightness = brightness + if (newbrightness > 255) { + newbrightness = 255 + } else if (newbrightness < 0) { + newbrightness = 0 + } + Settings.System.putInt( + contentResolver, + Settings.System.SCREEN_BRIGHTNESS, + newbrightness + ) + } + + private var thread = Thread { + while (!Thread.currentThread().isInterrupted) { + if (avail && !mLock) { + SystemClock.sleep(DELAY.toLong()) + ContextCompat.getMainExecutor(mContext!!).execute { if (avail) readyCamera() } + } + } + } + + companion object { + protected val TAG: String = CameraLightSensorService::class.java.simpleName + const val DEBUG = false + protected const val CAMERA_CHOICE = CameraCharacteristics.LENS_FACING_FRONT + private const val DELAY = 5 * 1000 // 5 Seconds + fun BatteryOptimization(context: Context?) { + val intent = Intent() + val packageName = context!!.packageName + val pm = context.getSystemService(POWER_SERVICE) as PowerManager + if (!pm.isIgnoringBatteryOptimizations(packageName)) { + intent.action = Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS + intent.data = Uri.parse("package:$packageName") + intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK + context.startActivity(intent) + } + } + } +} \ No newline at end of file