From 6c1f03a492c3a4f8eb747627b7ebe13b821af2d5 Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Wed, 11 Aug 2021 17:22:12 +0200 Subject: [PATCH] [android][expo-brightness] Rewrite android code to Kotlin (#13993) --- packages/expo-brightness/CHANGELOG.md | 1 + packages/expo-brightness/android/build.gradle | 4 + .../modules/brightness/BrightnessModule.java | 224 ------------------ .../modules/brightness/BrightnessModule.kt | 209 ++++++++++++++++ .../modules/brightness/BrightnessPackage.java | 16 -- .../modules/brightness/BrightnessPackage.kt | 11 + 6 files changed, 225 insertions(+), 240 deletions(-) delete mode 100644 packages/expo-brightness/android/src/main/java/expo/modules/brightness/BrightnessModule.java create mode 100644 packages/expo-brightness/android/src/main/java/expo/modules/brightness/BrightnessModule.kt delete mode 100644 packages/expo-brightness/android/src/main/java/expo/modules/brightness/BrightnessPackage.java create mode 100644 packages/expo-brightness/android/src/main/java/expo/modules/brightness/BrightnessPackage.kt diff --git a/packages/expo-brightness/CHANGELOG.md b/packages/expo-brightness/CHANGELOG.md index e1e44cdb8c6dc3..db33e584e92626 100644 --- a/packages/expo-brightness/CHANGELOG.md +++ b/packages/expo-brightness/CHANGELOG.md @@ -12,6 +12,7 @@ ### 💡 Others +- Rewrite android code to Kotlin. ([#13993](https://github.com/expo/expo/pull/13993) by [@kkafar](https://github.com/kkafar)) - Migrated from `@unimodules/core` to `expo-modules-core`. ([#13757](https://github.com/expo/expo/pull/13757) by [@tsapeta](https://github.com/tsapeta)) ## 9.2.0 — 2021-06-16 diff --git a/packages/expo-brightness/android/build.gradle b/packages/expo-brightness/android/build.gradle index 2d0d6b08b86bad..7b3af63e7ecbf3 100644 --- a/packages/expo-brightness/android/build.gradle +++ b/packages/expo-brightness/android/build.gradle @@ -53,6 +53,10 @@ android { targetCompatibility JavaVersion.VERSION_1_8 } + kotlinOptions { + jvmTarget = JavaVersion.VERSION_1_8 + } + defaultConfig { minSdkVersion safeExtGet("minSdkVersion", 21) targetSdkVersion safeExtGet("targetSdkVersion", 30) diff --git a/packages/expo-brightness/android/src/main/java/expo/modules/brightness/BrightnessModule.java b/packages/expo-brightness/android/src/main/java/expo/modules/brightness/BrightnessModule.java deleted file mode 100644 index 20ffd6d7ff924b..00000000000000 --- a/packages/expo-brightness/android/src/main/java/expo/modules/brightness/BrightnessModule.java +++ /dev/null @@ -1,224 +0,0 @@ -package expo.modules.brightness; - -import android.Manifest; -import android.app.Activity; -import android.content.Context; -import android.os.Build; -import android.provider.Settings; -import android.view.WindowManager; - -import expo.modules.core.ExportedModule; -import expo.modules.core.ModuleRegistry; -import expo.modules.core.Promise; -import expo.modules.core.errors.InvalidArgumentException; -import expo.modules.core.interfaces.ActivityProvider; -import expo.modules.core.interfaces.ExpoMethod; - -import expo.modules.interfaces.permissions.Permissions; - -public class BrightnessModule extends ExportedModule { - private ModuleRegistry mModuleRegistry; - - public BrightnessModule(Context reactContext) { - super(reactContext); - } - - @Override - public String getName() { - return "ExpoBrightness"; - } - - @Override - public void onCreate(ModuleRegistry moduleRegistry) { - mModuleRegistry = moduleRegistry; - } - - @ExpoMethod - public void requestPermissionsAsync(final Promise promise) { - Permissions.askForPermissionsWithPermissionsManager(mModuleRegistry.getModule(Permissions.class), promise, Manifest.permission.WRITE_SETTINGS); - } - - @ExpoMethod - public void getPermissionsAsync(final Promise promise) { - Permissions.getPermissionsWithPermissionsManager(mModuleRegistry.getModule(Permissions.class), promise, Manifest.permission.WRITE_SETTINGS); - } - - @ExpoMethod - public void setBrightnessAsync(final float brightnessValue, final Promise promise) { - final Activity activity = getCurrentActivity(); - activity.runOnUiThread(new Runnable() { - @Override - public void run() { - try { - WindowManager.LayoutParams lp = activity.getWindow().getAttributes(); - lp.screenBrightness = brightnessValue; - activity.getWindow().setAttributes(lp); // must be done on UI thread - promise.resolve(null); - } catch (Exception e) { - promise.reject("ERR_BRIGHTNESS", "Failed to set the current screen brightness", e); - } - } - }); - } - - @ExpoMethod - public void getBrightnessAsync(final Promise promise) { - final Activity activity = getCurrentActivity(); - activity.runOnUiThread(new Runnable() { - @Override - public void run() { - WindowManager.LayoutParams lp = getCurrentActivity().getWindow().getAttributes(); - if (lp.screenBrightness == WindowManager.LayoutParams.BRIGHTNESS_OVERRIDE_NONE) { - // system brightness is not overridden by the current activity, so just resolve with it - getSystemBrightnessAsync(promise); - } else { - promise.resolve(lp.screenBrightness); - } - } - }); - } - - @ExpoMethod - public void getSystemBrightnessAsync(Promise promise) { - try { - int brightnessMode = Settings.System.getInt( - getCurrentActivity().getContentResolver(), - Settings.System.SCREEN_BRIGHTNESS_MODE - ); - if (brightnessMode == Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC) { - float brightness = Settings.System.getFloat( - getCurrentActivity().getContentResolver(), - // https://stackoverflow.com/questions/29349153/change-adaptive-brightness-level-programatically - // this setting cannot be changed starting in targetSdkVersion 23, but it can still be read - "screen_auto_brightness_adj" - ); - promise.resolve((brightness + 1.0f) / 2); - } else { - String brightness = Settings.System.getString( - getCurrentActivity().getContentResolver(), - Settings.System.SCREEN_BRIGHTNESS - ); - promise.resolve(Integer.parseInt(brightness) / 255f); - } - } catch (Exception e) { - promise.reject("ERR_BRIGHTNESS_SYSTEM", "Failed to get the system brightness value", e); - } - } - - @ExpoMethod - public void setSystemBrightnessAsync(float brightnessValue, Promise promise) { - try { - // we have to just check this every time - // if we try to store a value for this permission, there is no way to know if the user has changed it - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && !Settings.System.canWrite(getCurrentActivity())) { - promise.reject("ERR_BRIGHTNESS_PERMISSIONS_DENIED", "WRITE_SETTINGS permission has not been granted"); - return; - } - // manual mode must be set in order to change system brightness (sets the automatic mode off) - Settings.System.putInt( - getCurrentActivity().getContentResolver(), - Settings.System.SCREEN_BRIGHTNESS_MODE, - Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL - ); - Settings.System.putInt( - getCurrentActivity().getContentResolver(), - Settings.System.SCREEN_BRIGHTNESS, - Math.round(brightnessValue * 255) - ); - promise.resolve(null); - } catch (Exception e) { - promise.reject("ERR_BRIGHTNESS_SYSTEM", "Failed to set the system brightness value", e); - } - } - - @ExpoMethod - public void useSystemBrightnessAsync(final Promise promise) { - final Activity activity = getCurrentActivity(); - activity.runOnUiThread(new Runnable() { - @Override - public void run() { - try { - WindowManager.LayoutParams lp = activity.getWindow().getAttributes(); - lp.screenBrightness = WindowManager.LayoutParams.BRIGHTNESS_OVERRIDE_NONE; - activity.getWindow().setAttributes(lp); // must be done on UI thread - promise.resolve(null); - } catch (Exception e) { - promise.reject("ERR_BRIGHTNESS", "Failed to set the brightness of the current screen", e); - } - } - }); - } - - @ExpoMethod - public void isUsingSystemBrightnessAsync(final Promise promise) { - final Activity activity = getCurrentActivity(); - activity.runOnUiThread(new Runnable() { - @Override - public void run() { - WindowManager.LayoutParams lp = getCurrentActivity().getWindow().getAttributes(); - promise.resolve(lp.screenBrightness == WindowManager.LayoutParams.BRIGHTNESS_OVERRIDE_NONE); - } - }); - } - - @ExpoMethod - public void getSystemBrightnessModeAsync(Promise promise) { - try { - int brightnessMode = Settings.System.getInt( - getCurrentActivity().getContentResolver(), - Settings.System.SCREEN_BRIGHTNESS_MODE - ); - promise.resolve(brightnessModeNativeToJS(brightnessMode)); - } catch (Exception e) { - promise.reject("ERR_BRIGHTNESS_MODE", "Failed to get the system brightness mode", e); - } - } - - @ExpoMethod - public void setSystemBrightnessModeAsync(int brightnessMode, Promise promise) { - try { - // we have to just check this every time - // if we try to store a value for this permission, there is no way to know if the user has changed it - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && !Settings.System.canWrite(getCurrentActivity())) { - promise.reject("ERR_BRIGHTNESS_PERMISSIONS_DENIED", "WRITE_SETTINGS permission has not been granted"); - return; - } - Settings.System.putInt( - getCurrentActivity().getContentResolver(), - Settings.System.SCREEN_BRIGHTNESS_MODE, - brightnessModeJSToNative(brightnessMode) - ); - promise.resolve(null); - } catch (InvalidArgumentException e) { - promise.reject(e); - } catch (Exception e) { - promise.reject("ERR_BRIGHTNESS_MODE", "Failed to set the system brightness mode", e); - } - } - - private int brightnessModeNativeToJS(int nativeValue) { - switch (nativeValue) { - case Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC: - return 1; - case Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL: - return 2; - default: - return 0; - } - } - - private int brightnessModeJSToNative(int jsValue) throws InvalidArgumentException { - switch (jsValue) { - case 1: - return Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC; - case 2: - return Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL; - default: - throw new InvalidArgumentException("Unsupported brightness mode " + String.valueOf(jsValue)); - } - } - - private Activity getCurrentActivity() { - return mModuleRegistry.getModule(ActivityProvider.class).getCurrentActivity(); - } -} diff --git a/packages/expo-brightness/android/src/main/java/expo/modules/brightness/BrightnessModule.kt b/packages/expo-brightness/android/src/main/java/expo/modules/brightness/BrightnessModule.kt new file mode 100644 index 00000000000000..080d6b95fed1bc --- /dev/null +++ b/packages/expo-brightness/android/src/main/java/expo/modules/brightness/BrightnessModule.kt @@ -0,0 +1,209 @@ +package expo.modules.brightness + +import expo.modules.core.ExportedModule +import expo.modules.core.ModuleRegistry +import expo.modules.core.ModuleRegistryDelegate +import expo.modules.core.Promise +import expo.modules.core.errors.InvalidArgumentException +import expo.modules.core.interfaces.ActivityProvider +import expo.modules.interfaces.permissions.Permissions +import expo.modules.core.interfaces.ExpoMethod + +import android.Manifest +import android.app.Activity +import android.content.Context +import android.os.Build +import android.provider.Settings +import android.view.WindowManager + +import java.lang.Exception +import kotlin.math.roundToInt + +class BrightnessModule( + reactContext: Context?, + private val moduleRegistryDelegate: ModuleRegistryDelegate = ModuleRegistryDelegate() +) : ExportedModule(reactContext) { + + private val permissionModule: Permissions by moduleRegistry() + private val activityProvider: ActivityProvider by moduleRegistry() + + private inline fun moduleRegistry() = moduleRegistryDelegate.getFromModuleRegistry() + + override fun getName(): String { + return "ExpoBrightness" + } + + override fun onCreate(moduleRegistry: ModuleRegistry) { + moduleRegistryDelegate.onCreate(moduleRegistry) + } + + @ExpoMethod + fun requestPermissionsAsync(promise: Promise?) { + Permissions.askForPermissionsWithPermissionsManager(permissionModule, promise, Manifest.permission.WRITE_SETTINGS) + } + + @ExpoMethod + fun getPermissionsAsync(promise: Promise?) { + Permissions.getPermissionsWithPermissionsManager(permissionModule, promise, Manifest.permission.WRITE_SETTINGS) + } + + @ExpoMethod + fun setBrightnessAsync(brightnessValue: Float, promise: Promise) { + val activity = currentActivity + activity.runOnUiThread { + try { + val lp = activity.window.attributes + lp.screenBrightness = brightnessValue + activity.window.attributes = lp // must be done on UI thread + promise.resolve(null) + } catch (e: Exception) { + promise.reject("ERR_BRIGHTNESS", "Failed to set the current screen brightness", e) + } + } + } + + @ExpoMethod + fun getBrightnessAsync(promise: Promise) { + val activity = currentActivity + activity.runOnUiThread { + val lp = activity.window.attributes + if (lp.screenBrightness == WindowManager.LayoutParams.BRIGHTNESS_OVERRIDE_NONE) { + // system brightness is not overridden by the current activity, so just resolve with it + getSystemBrightnessAsync(promise) + } else { + promise.resolve(lp.screenBrightness) + } + } + } + + @ExpoMethod + fun getSystemBrightnessAsync(promise: Promise) { + try { + val brightnessMode = Settings.System.getInt( + currentActivity.contentResolver, + Settings.System.SCREEN_BRIGHTNESS_MODE + ) + if (brightnessMode == Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC) { + val brightness = Settings.System.getFloat( + currentActivity.contentResolver, // https://stackoverflow.com/questions/29349153/change-adaptive-brightness-level-programatically + // this setting cannot be changed starting in targetSdkVersion 23, but it can still be read + "screen_auto_brightness_adj" + ) + promise.resolve((brightness + 1.0f) / 2) + } else { + val brightness = Settings.System.getString( + currentActivity.contentResolver, + Settings.System.SCREEN_BRIGHTNESS + ) + promise.resolve(brightness.toInt() / 255f) + } + } catch (e: Exception) { + promise.reject("ERR_BRIGHTNESS_SYSTEM", "Failed to get the system brightness value", e) + } + } + + @ExpoMethod + fun setSystemBrightnessAsync(brightnessValue: Float, promise: Promise) { + try { + // we have to just check this every time + // if we try to store a value for this permission, there is no way to know if the user has changed it + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && !Settings.System.canWrite(currentActivity)) { + promise.reject("ERR_BRIGHTNESS_PERMISSIONS_DENIED", "WRITE_SETTINGS permission has not been granted") + return + } + // manual mode must be set in order to change system brightness (sets the automatic mode off) + Settings.System.putInt( + currentActivity.contentResolver, + Settings.System.SCREEN_BRIGHTNESS_MODE, + Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL + ) + Settings.System.putInt( + currentActivity.contentResolver, + Settings.System.SCREEN_BRIGHTNESS, + (brightnessValue * 255).roundToInt() + ) + promise.resolve(null) + } catch (e: Exception) { + promise.reject("ERR_BRIGHTNESS_SYSTEM", "Failed to set the system brightness value", e) + } + } + + @ExpoMethod + fun useSystemBrightnessAsync(promise: Promise) { + val activity = currentActivity + activity.runOnUiThread { + try { + val lp = activity.window.attributes + lp.screenBrightness = WindowManager.LayoutParams.BRIGHTNESS_OVERRIDE_NONE + activity.window.attributes = lp // must be done on UI thread + promise.resolve(null) + } catch (e: Exception) { + promise.reject("ERR_BRIGHTNESS", "Failed to set the brightness of the current screen", e) + } + } + } + + @ExpoMethod + fun isUsingSystemBrightnessAsync(promise: Promise) { + val activity = currentActivity + activity.runOnUiThread { + val lp = activity.window.attributes + promise.resolve(lp.screenBrightness == WindowManager.LayoutParams.BRIGHTNESS_OVERRIDE_NONE) + } + } + + @ExpoMethod + fun getSystemBrightnessModeAsync(promise: Promise) { + try { + val brightnessMode = Settings.System.getInt( + currentActivity.contentResolver, + Settings.System.SCREEN_BRIGHTNESS_MODE + ) + promise.resolve(brightnessModeNativeToJS(brightnessMode)) + } catch (e: Exception) { + promise.reject("ERR_BRIGHTNESS_MODE", "Failed to get the system brightness mode", e) + } + } + + @ExpoMethod + fun setSystemBrightnessModeAsync(brightnessMode: Int, promise: Promise) { + try { + // we have to just check this every time + // if we try to store a value for this permission, there is no way to know if the user has changed it + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && !Settings.System.canWrite(currentActivity)) { + promise.reject("ERR_BRIGHTNESS_PERMISSIONS_DENIED", "WRITE_SETTINGS permission has not been granted") + return + } + Settings.System.putInt( + currentActivity.contentResolver, + Settings.System.SCREEN_BRIGHTNESS_MODE, + brightnessModeJSToNative(brightnessMode) + ) + promise.resolve(null) + } catch (e: InvalidArgumentException) { + promise.reject(e) + } catch (e: Exception) { + promise.reject("ERR_BRIGHTNESS_MODE", "Failed to set the system brightness mode", e) + } + } + + private fun brightnessModeNativeToJS(nativeValue: Int): Int { + return when (nativeValue) { + Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC -> 1 + Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL -> 2 + else -> 0 + } + } + + @Throws(InvalidArgumentException::class) + private fun brightnessModeJSToNative(jsValue: Int): Int { + return when (jsValue) { + 1 -> Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC + 2 -> Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL + else -> throw InvalidArgumentException("Unsupported brightness mode $jsValue") + } + } + + private val currentActivity: Activity + get() = activityProvider.currentActivity +} diff --git a/packages/expo-brightness/android/src/main/java/expo/modules/brightness/BrightnessPackage.java b/packages/expo-brightness/android/src/main/java/expo/modules/brightness/BrightnessPackage.java deleted file mode 100644 index 7dc70fdd592d5d..00000000000000 --- a/packages/expo-brightness/android/src/main/java/expo/modules/brightness/BrightnessPackage.java +++ /dev/null @@ -1,16 +0,0 @@ -package expo.modules.brightness; - -import android.content.Context; - -import java.util.Collections; -import java.util.List; - -import expo.modules.core.BasePackage; -import expo.modules.core.ExportedModule; - -public class BrightnessPackage extends BasePackage { - @Override - public List createExportedModules(Context context) { - return Collections.singletonList((ExportedModule) new BrightnessModule(context)); - } -} diff --git a/packages/expo-brightness/android/src/main/java/expo/modules/brightness/BrightnessPackage.kt b/packages/expo-brightness/android/src/main/java/expo/modules/brightness/BrightnessPackage.kt new file mode 100644 index 00000000000000..53503fc545e138 --- /dev/null +++ b/packages/expo-brightness/android/src/main/java/expo/modules/brightness/BrightnessPackage.kt @@ -0,0 +1,11 @@ +package expo.modules.brightness + +import android.content.Context +import expo.modules.core.BasePackage +import expo.modules.core.ExportedModule + +class BrightnessPackage : BasePackage() { + override fun createExportedModules(context: Context): List { + return listOf(BrightnessModule(context)) + } +}