fix(deps): refresh and document native dependencies
This commit is contained in:
@@ -0,0 +1,29 @@
|
||||
BSD 3-Clause License
|
||||
|
||||
Copyright (c) 2020-2023, creativecreatorormaybenot
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
@@ -0,0 +1,9 @@
|
||||
*.iml
|
||||
.gradle
|
||||
/local.properties
|
||||
/.idea/workspace.xml
|
||||
/.idea/libraries
|
||||
.DS_Store
|
||||
/build
|
||||
/captures
|
||||
.cxx
|
||||
@@ -0,0 +1,71 @@
|
||||
group 'dev.fluttercommunity.plus.wakelock'
|
||||
version '1.0-SNAPSHOT'
|
||||
|
||||
buildscript {
|
||||
ext.kotlin_version = '2.2.0'
|
||||
repositories {
|
||||
google()
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:8.12.1'
|
||||
}
|
||||
}
|
||||
|
||||
rootProject.allprojects {
|
||||
repositories {
|
||||
google()
|
||||
mavenCentral()
|
||||
}
|
||||
}
|
||||
|
||||
apply plugin: 'com.android.library'
|
||||
apply plugin: 'kotlin-android'
|
||||
|
||||
android {
|
||||
namespace 'dev.fluttercommunity.plus.wakelock'
|
||||
compileSdk = flutter.compileSdkVersion
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_17
|
||||
targetCompatibility JavaVersion.VERSION_17
|
||||
}
|
||||
|
||||
kotlinOptions {
|
||||
jvmTarget = '17'
|
||||
}
|
||||
lintOptions {
|
||||
disable 'InvalidPackage'
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
main.java.srcDirs += 'src/main/kotlin'
|
||||
test.java.srcDirs += 'src/test/kotlin'
|
||||
}
|
||||
|
||||
defaultConfig {
|
||||
// Use flutter.minSdkVersion once the minimum supported Flutter version is 3.35 or higher.
|
||||
minSdkVersion flutter.minSdkVersion
|
||||
testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner'
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
|
||||
testImplementation 'org.jetbrains.kotlin:kotlin-test'
|
||||
testImplementation 'org.mockito:mockito-core:5.0.0'
|
||||
}
|
||||
|
||||
testOptions {
|
||||
unitTests.includeAndroidResources = true
|
||||
unitTests.all {
|
||||
useJUnitPlatform()
|
||||
|
||||
testLogging {
|
||||
events 'passed', 'skipped', 'failed', 'standardOut', 'standardError'
|
||||
outputs.upToDateWhen { false }
|
||||
showStandardStreams = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
rootProject.name = 'wakelock_plus'
|
||||
@@ -0,0 +1,3 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="dev.fluttercommunity.plus.wakelock">
|
||||
</manifest>
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
package dev.fluttercommunity.plus.wakelock
|
||||
|
||||
import IsEnabledMessage
|
||||
import ToggleMessage
|
||||
import android.app.Activity
|
||||
import android.view.WindowManager
|
||||
|
||||
internal class Wakelock {
|
||||
var activity: Activity? = null
|
||||
|
||||
private val enabled
|
||||
get() = activity!!.window.attributes.flags and
|
||||
WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON != 0
|
||||
|
||||
fun toggle(message: ToggleMessage) {
|
||||
if (activity == null) {
|
||||
throw NoActivityException()
|
||||
}
|
||||
|
||||
val activity = this.activity!!
|
||||
val enabled = this.enabled
|
||||
|
||||
if (message.enable!!) {
|
||||
if (!enabled) activity.window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
|
||||
} else if (enabled) {
|
||||
activity.window.clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
|
||||
}
|
||||
}
|
||||
|
||||
fun isEnabled(): IsEnabledMessage {
|
||||
if (activity == null) {
|
||||
throw NoActivityException()
|
||||
}
|
||||
|
||||
return IsEnabledMessage(enabled = enabled)
|
||||
}
|
||||
}
|
||||
|
||||
class NoActivityException : Exception("wakelock requires a foreground activity")
|
||||
+223
@@ -0,0 +1,223 @@
|
||||
// Autogenerated from Pigeon (v26.2.3), do not edit directly.
|
||||
// See also: https://pub.dev/packages/pigeon
|
||||
@file:Suppress("UNCHECKED_CAST", "ArrayInDataClass")
|
||||
|
||||
|
||||
import android.util.Log
|
||||
import io.flutter.plugin.common.BasicMessageChannel
|
||||
import io.flutter.plugin.common.BinaryMessenger
|
||||
import io.flutter.plugin.common.EventChannel
|
||||
import io.flutter.plugin.common.MessageCodec
|
||||
import io.flutter.plugin.common.StandardMethodCodec
|
||||
import io.flutter.plugin.common.StandardMessageCodec
|
||||
import java.io.ByteArrayOutputStream
|
||||
import java.nio.ByteBuffer
|
||||
private object WakelockPlusMessagesPigeonUtils {
|
||||
|
||||
fun wrapResult(result: Any?): List<Any?> {
|
||||
return listOf(result)
|
||||
}
|
||||
|
||||
fun wrapError(exception: Throwable): List<Any?> {
|
||||
return if (exception is WakelockPlusFlutterError) {
|
||||
listOf(
|
||||
exception.code,
|
||||
exception.message,
|
||||
exception.details
|
||||
)
|
||||
} else {
|
||||
listOf(
|
||||
exception.javaClass.simpleName,
|
||||
exception.toString(),
|
||||
"Cause: " + exception.cause + ", Stacktrace: " + Log.getStackTraceString(exception)
|
||||
)
|
||||
}
|
||||
}
|
||||
fun deepEquals(a: Any?, b: Any?): Boolean {
|
||||
if (a is ByteArray && b is ByteArray) {
|
||||
return a.contentEquals(b)
|
||||
}
|
||||
if (a is IntArray && b is IntArray) {
|
||||
return a.contentEquals(b)
|
||||
}
|
||||
if (a is LongArray && b is LongArray) {
|
||||
return a.contentEquals(b)
|
||||
}
|
||||
if (a is DoubleArray && b is DoubleArray) {
|
||||
return a.contentEquals(b)
|
||||
}
|
||||
if (a is Array<*> && b is Array<*>) {
|
||||
return a.size == b.size &&
|
||||
a.indices.all{ deepEquals(a[it], b[it]) }
|
||||
}
|
||||
if (a is List<*> && b is List<*>) {
|
||||
return a.size == b.size &&
|
||||
a.indices.all{ deepEquals(a[it], b[it]) }
|
||||
}
|
||||
if (a is Map<*, *> && b is Map<*, *>) {
|
||||
return a.size == b.size && a.all {
|
||||
(b as Map<Any?, Any?>).contains(it.key) &&
|
||||
deepEquals(it.value, b[it.key])
|
||||
}
|
||||
}
|
||||
return a == b
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Error class for passing custom error details to Flutter via a thrown PlatformException.
|
||||
* @property code The error code.
|
||||
* @property message The error message.
|
||||
* @property details The error details. Must be a datatype supported by the api codec.
|
||||
*/
|
||||
class WakelockPlusFlutterError (
|
||||
val code: String,
|
||||
override val message: String? = null,
|
||||
val details: Any? = null
|
||||
) : Throwable()
|
||||
|
||||
/**
|
||||
* Message for toggling the wakelock on the platform side.
|
||||
*
|
||||
* Generated class from Pigeon that represents data sent in messages.
|
||||
*/
|
||||
data class ToggleMessage (
|
||||
val enable: Boolean? = null
|
||||
)
|
||||
{
|
||||
companion object {
|
||||
fun fromList(pigeonVar_list: List<Any?>): ToggleMessage {
|
||||
val enable = pigeonVar_list[0] as Boolean?
|
||||
return ToggleMessage(enable)
|
||||
}
|
||||
}
|
||||
fun toList(): List<Any?> {
|
||||
return listOf(
|
||||
enable,
|
||||
)
|
||||
}
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (other !is ToggleMessage) {
|
||||
return false
|
||||
}
|
||||
if (this === other) {
|
||||
return true
|
||||
}
|
||||
return WakelockPlusMessagesPigeonUtils.deepEquals(toList(), other.toList()) }
|
||||
|
||||
override fun hashCode(): Int = toList().hashCode()
|
||||
}
|
||||
|
||||
/**
|
||||
* Message for reporting the wakelock state from the platform side.
|
||||
*
|
||||
* Generated class from Pigeon that represents data sent in messages.
|
||||
*/
|
||||
data class IsEnabledMessage (
|
||||
val enabled: Boolean? = null
|
||||
)
|
||||
{
|
||||
companion object {
|
||||
fun fromList(pigeonVar_list: List<Any?>): IsEnabledMessage {
|
||||
val enabled = pigeonVar_list[0] as Boolean?
|
||||
return IsEnabledMessage(enabled)
|
||||
}
|
||||
}
|
||||
fun toList(): List<Any?> {
|
||||
return listOf(
|
||||
enabled,
|
||||
)
|
||||
}
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (other !is IsEnabledMessage) {
|
||||
return false
|
||||
}
|
||||
if (this === other) {
|
||||
return true
|
||||
}
|
||||
return WakelockPlusMessagesPigeonUtils.deepEquals(toList(), other.toList()) }
|
||||
|
||||
override fun hashCode(): Int = toList().hashCode()
|
||||
}
|
||||
private open class WakelockPlusMessagesPigeonCodec : StandardMessageCodec() {
|
||||
override fun readValueOfType(type: Byte, buffer: ByteBuffer): Any? {
|
||||
return when (type) {
|
||||
129.toByte() -> {
|
||||
return (readValue(buffer) as? List<Any?>)?.let {
|
||||
ToggleMessage.fromList(it)
|
||||
}
|
||||
}
|
||||
130.toByte() -> {
|
||||
return (readValue(buffer) as? List<Any?>)?.let {
|
||||
IsEnabledMessage.fromList(it)
|
||||
}
|
||||
}
|
||||
else -> super.readValueOfType(type, buffer)
|
||||
}
|
||||
}
|
||||
override fun writeValue(stream: ByteArrayOutputStream, value: Any?) {
|
||||
when (value) {
|
||||
is ToggleMessage -> {
|
||||
stream.write(129)
|
||||
writeValue(stream, value.toList())
|
||||
}
|
||||
is IsEnabledMessage -> {
|
||||
stream.write(130)
|
||||
writeValue(stream, value.toList())
|
||||
}
|
||||
else -> super.writeValue(stream, value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Generated interface from Pigeon that represents a handler of messages from Flutter. */
|
||||
interface WakelockPlusApi {
|
||||
fun toggle(msg: ToggleMessage)
|
||||
fun isEnabled(): IsEnabledMessage
|
||||
|
||||
companion object {
|
||||
/** The codec used by WakelockPlusApi. */
|
||||
val codec: MessageCodec<Any?> by lazy {
|
||||
WakelockPlusMessagesPigeonCodec()
|
||||
}
|
||||
/** Sets up an instance of `WakelockPlusApi` to handle messages through the `binaryMessenger`. */
|
||||
@JvmOverloads
|
||||
fun setUp(binaryMessenger: BinaryMessenger, api: WakelockPlusApi?, messageChannelSuffix: String = "") {
|
||||
val separatedMessageChannelSuffix = if (messageChannelSuffix.isNotEmpty()) ".$messageChannelSuffix" else ""
|
||||
run {
|
||||
val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.wakelock_plus_platform_interface.WakelockPlusApi.toggle$separatedMessageChannelSuffix", codec)
|
||||
if (api != null) {
|
||||
channel.setMessageHandler { message, reply ->
|
||||
val args = message as List<Any?>
|
||||
val msgArg = args[0] as ToggleMessage
|
||||
val wrapped: List<Any?> = try {
|
||||
api.toggle(msgArg)
|
||||
listOf(null)
|
||||
} catch (exception: Throwable) {
|
||||
WakelockPlusMessagesPigeonUtils.wrapError(exception)
|
||||
}
|
||||
reply.reply(wrapped)
|
||||
}
|
||||
} else {
|
||||
channel.setMessageHandler(null)
|
||||
}
|
||||
}
|
||||
run {
|
||||
val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.wakelock_plus_platform_interface.WakelockPlusApi.isEnabled$separatedMessageChannelSuffix", codec)
|
||||
if (api != null) {
|
||||
channel.setMessageHandler { _, reply ->
|
||||
val wrapped: List<Any?> = try {
|
||||
listOf(api.isEnabled())
|
||||
} catch (exception: Throwable) {
|
||||
WakelockPlusMessagesPigeonUtils.wrapError(exception)
|
||||
}
|
||||
reply.reply(wrapped)
|
||||
}
|
||||
} else {
|
||||
channel.setMessageHandler(null)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
package dev.fluttercommunity.plus.wakelock
|
||||
|
||||
import IsEnabledMessage
|
||||
import ToggleMessage
|
||||
import WakelockPlusApi
|
||||
|
||||
import io.flutter.embedding.engine.plugins.FlutterPlugin
|
||||
import io.flutter.embedding.engine.plugins.activity.ActivityAware
|
||||
import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding
|
||||
|
||||
/** WakelockPlusPlugin */
|
||||
class WakelockPlusPlugin: FlutterPlugin, WakelockPlusApi, ActivityAware {
|
||||
private var wakelock: Wakelock? = null
|
||||
|
||||
override fun onAttachedToEngine(flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) {
|
||||
WakelockPlusApi.setUp(flutterPluginBinding.binaryMessenger, this)
|
||||
wakelock = Wakelock()
|
||||
}
|
||||
|
||||
override fun onDetachedFromEngine(binding: FlutterPlugin.FlutterPluginBinding) {
|
||||
WakelockPlusApi.setUp(binding.binaryMessenger, null)
|
||||
wakelock = null
|
||||
}
|
||||
|
||||
override fun onAttachedToActivity(binding: ActivityPluginBinding) {
|
||||
wakelock?.activity = binding.activity
|
||||
}
|
||||
|
||||
override fun onDetachedFromActivity() {
|
||||
wakelock?.activity = null
|
||||
}
|
||||
|
||||
override fun onReattachedToActivityForConfigChanges(binding: ActivityPluginBinding) {
|
||||
onAttachedToActivity(binding)
|
||||
}
|
||||
|
||||
override fun onDetachedFromActivityForConfigChanges() {
|
||||
onDetachedFromActivity()
|
||||
}
|
||||
|
||||
override fun toggle(msg: ToggleMessage) {
|
||||
wakelock!!.toggle(msg)
|
||||
}
|
||||
|
||||
override fun isEnabled(): IsEnabledMessage {
|
||||
return wakelock!!.isEnabled()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
.idea/
|
||||
.vagrant/
|
||||
.sconsign.dblite
|
||||
.svn/
|
||||
|
||||
.DS_Store
|
||||
*.swp
|
||||
profile
|
||||
|
||||
DerivedData/
|
||||
build/
|
||||
.build/
|
||||
.index-build/
|
||||
GeneratedPluginRegistrant.h
|
||||
GeneratedPluginRegistrant.m
|
||||
|
||||
.generated/
|
||||
|
||||
*.pbxuser
|
||||
*.mode1v3
|
||||
*.mode2v3
|
||||
*.perspectivev3
|
||||
|
||||
!default.pbxuser
|
||||
!default.mode1v3
|
||||
!default.mode2v3
|
||||
!default.perspectivev3
|
||||
|
||||
xcuserdata
|
||||
|
||||
*.moved-aside
|
||||
|
||||
*.pyc
|
||||
*sync/
|
||||
Icon?
|
||||
.tags*
|
||||
|
||||
/Flutter/Generated.xcconfig
|
||||
/Flutter/ephemeral/
|
||||
/Flutter/flutter_export_environment.sh
|
||||
@@ -0,0 +1,25 @@
|
||||
#
|
||||
# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html.
|
||||
# Run `pod lib lint wakelock_plus.podspec` to validate before publishing.
|
||||
#
|
||||
Pod::Spec.new do |s|
|
||||
s.name = 'wakelock_plus'
|
||||
s.version = '0.0.1'
|
||||
s.summary = 'Plugin that allows you to keep the device screen awake, i.e. prevent the screen from sleeping on Android, iOS, macOS, Windows, Linux, and web.'
|
||||
s.description = <<-DESC
|
||||
Plugin that allows you to keep the device screen awake, i.e. prevent the screen from sleeping on Android, iOS, macOS, Windows, Linux, and web.
|
||||
DESC
|
||||
s.homepage = 'https://github.com/fluttercommunity/wakelock_plus'
|
||||
s.license = { :file => '../LICENSE' }
|
||||
s.author = { 'Flutter Team' => 'flutter-dev@googlegroups.com' }
|
||||
s.source = { :path => '.' }
|
||||
s.source_files = 'wakelock_plus/Sources/wakelock_plus/**/*.{h,m}'
|
||||
s.public_header_files = 'wakelock_plus/Sources/wakelock_plus/include/**/*.h'
|
||||
s.dependency 'Flutter'
|
||||
s.ios.deployment_target = '12.0'
|
||||
s.tvos.deployment_target = '12.0'
|
||||
|
||||
# Flutter.framework does not contain a i386 slice.
|
||||
s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'i386' }
|
||||
s.resource_bundles = {'wakelock_plus_privacy' => ['wakelock_plus/Sources/wakelock_plus/Resources/PrivacyInfo.xcprivacy']}
|
||||
end
|
||||
@@ -0,0 +1,27 @@
|
||||
// swift-tools-version: 5.9
|
||||
// The swift-tools-version declares the minimum version of Swift required to build this package.
|
||||
|
||||
import PackageDescription
|
||||
|
||||
let package = Package(
|
||||
name: "wakelock_plus",
|
||||
platforms: [
|
||||
.iOS("11.0")
|
||||
],
|
||||
products: [
|
||||
.library(name: "wakelock-plus", targets: ["wakelock_plus"])
|
||||
],
|
||||
dependencies: [],
|
||||
targets: [
|
||||
.target(
|
||||
name: "wakelock_plus",
|
||||
dependencies: [],
|
||||
resources: [
|
||||
.process("Resources")
|
||||
],
|
||||
cSettings: [
|
||||
.headerSearchPath("include/wakelock_plus")
|
||||
]
|
||||
)
|
||||
]
|
||||
)
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>NSPrivacyTrackingDomains</key>
|
||||
<array/>
|
||||
<key>NSPrivacyAccessedAPITypes</key>
|
||||
<array/>
|
||||
<key>NSPrivacyCollectedDataTypes</key>
|
||||
<array/>
|
||||
<key>NSPrivacyTracking</key>
|
||||
<false/>
|
||||
</dict>
|
||||
</plist>
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
//
|
||||
// UIApplication+idleTimerLock.m
|
||||
// wakelock
|
||||
//
|
||||
// Created by suyao on 2021/12/17.
|
||||
//
|
||||
|
||||
#import "./include/wakelock_plus/UIApplication+idleTimerLock.h"
|
||||
#import <objc/runtime.h>
|
||||
|
||||
static NSString *idleTimerLockKey = @"idleTimerLockKey";
|
||||
|
||||
|
||||
@implementation UIApplication (idleTimerLock)
|
||||
|
||||
+ (void)load {
|
||||
Method setIdleTimerDisabled = class_getInstanceMethod(self, @selector(setIdleTimerDisabled:));
|
||||
|
||||
Method lock_setIdleTimerDisabled = class_getInstanceMethod(self, @selector(lock_setIdleTimerDisabled:));
|
||||
|
||||
method_exchangeImplementations(setIdleTimerDisabled, lock_setIdleTimerDisabled);
|
||||
}
|
||||
|
||||
- (void)lock_setIdleTimerDisabled:(BOOL)enable {
|
||||
if ([self lock_idleTimerlockEnable]) {
|
||||
return;
|
||||
}
|
||||
[self lock_setIdleTimerDisabled:enable];
|
||||
}
|
||||
|
||||
- (void)lock_idleTimerlockEnable:(BOOL)enable {
|
||||
objc_setAssociatedObject(self, &idleTimerLockKey, @(enable), OBJC_ASSOCIATION_COPY);
|
||||
}
|
||||
|
||||
- (BOOL)lock_idleTimerlockEnable
|
||||
{
|
||||
return [objc_getAssociatedObject(self, &idleTimerLockKey) boolValue];
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,48 @@
|
||||
#import "./include/wakelock_plus/WakelockPlusPlugin.h"
|
||||
#import "./include/wakelock_plus/messages.g.h"
|
||||
#import "./include/wakelock_plus/UIApplication+idleTimerLock.h"
|
||||
|
||||
@interface WakelockPlusPlugin () <WAKELOCKPLUSWakelockPlusApi>
|
||||
|
||||
@property (nonatomic, assign) BOOL enable;
|
||||
|
||||
@end
|
||||
|
||||
@implementation WakelockPlusPlugin
|
||||
+ (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar>*)registrar {
|
||||
WakelockPlusPlugin* instance = [[WakelockPlusPlugin alloc] init];
|
||||
SetUpWAKELOCKPLUSWakelockPlusApi(registrar.messenger, instance);
|
||||
}
|
||||
|
||||
- (void)toggleMsg:(WAKELOCKPLUSToggleMessage*)input error:(FlutterError**)error {
|
||||
BOOL enable = [input.enable boolValue];
|
||||
if (!enable) {
|
||||
[[UIApplication sharedApplication] lock_idleTimerlockEnable:enable];//should disable first
|
||||
[self setIdleTimerDisabled:enable];
|
||||
} else {
|
||||
[self setIdleTimerDisabled:enable];
|
||||
[[UIApplication sharedApplication] lock_idleTimerlockEnable:enable];
|
||||
}
|
||||
self.enable = enable;
|
||||
}
|
||||
|
||||
- (void)setIdleTimerDisabled:(BOOL)enable {
|
||||
BOOL enabled = [[UIApplication sharedApplication] isIdleTimerDisabled];
|
||||
if (enable!= enabled) {
|
||||
[[UIApplication sharedApplication] setIdleTimerDisabled:enable];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
- (WAKELOCKPLUSIsEnabledMessage*)isEnabledWithError:(FlutterError* __autoreleasing *)error {
|
||||
NSNumber *enabled = [NSNumber numberWithBool:[[UIApplication sharedApplication] isIdleTimerDisabled]];
|
||||
WAKELOCKPLUSIsEnabledMessage* result = [[WAKELOCKPLUSIsEnabledMessage alloc] init];
|
||||
result.enabled = enabled;
|
||||
return result;
|
||||
}
|
||||
|
||||
- (void)setEnable:(BOOL)enable {
|
||||
_enable = enable;
|
||||
}
|
||||
|
||||
@end
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
//
|
||||
// UIApplication+idleTimerLock.h
|
||||
// wakelock
|
||||
//
|
||||
// Created by suyao on 2021/12/17.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface UIApplication (idleTimerLock)
|
||||
|
||||
- (void)lock_idleTimerlockEnable:(BOOL)enable;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
#import <Flutter/Flutter.h>
|
||||
|
||||
@interface WakelockPlusPlugin : NSObject<FlutterPlugin>
|
||||
@end
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
// Autogenerated from Pigeon (v26.2.3), do not edit directly.
|
||||
// See also: https://pub.dev/packages/pigeon
|
||||
|
||||
@import Foundation;
|
||||
|
||||
@protocol FlutterBinaryMessenger;
|
||||
@protocol FlutterMessageCodec;
|
||||
@class FlutterError;
|
||||
@class FlutterStandardTypedData;
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@class WAKELOCKPLUSToggleMessage;
|
||||
@class WAKELOCKPLUSIsEnabledMessage;
|
||||
|
||||
/// Message for toggling the wakelock on the platform side.
|
||||
@interface WAKELOCKPLUSToggleMessage : NSObject
|
||||
+ (instancetype)makeWithEnable:(nullable NSNumber *)enable;
|
||||
@property(nonatomic, strong, nullable) NSNumber * enable;
|
||||
@end
|
||||
|
||||
/// Message for reporting the wakelock state from the platform side.
|
||||
@interface WAKELOCKPLUSIsEnabledMessage : NSObject
|
||||
+ (instancetype)makeWithEnabled:(nullable NSNumber *)enabled;
|
||||
@property(nonatomic, strong, nullable) NSNumber * enabled;
|
||||
@end
|
||||
|
||||
/// The codec used by all APIs.
|
||||
NSObject<FlutterMessageCodec> *WAKELOCKPLUSGetMessagesCodec(void);
|
||||
|
||||
@protocol WAKELOCKPLUSWakelockPlusApi
|
||||
- (void)toggleMsg:(WAKELOCKPLUSToggleMessage *)msg error:(FlutterError *_Nullable *_Nonnull)error;
|
||||
/// @return `nil` only when `error != nil`.
|
||||
- (nullable WAKELOCKPLUSIsEnabledMessage *)isEnabledWithError:(FlutterError *_Nullable *_Nonnull)error;
|
||||
@end
|
||||
|
||||
extern void SetUpWAKELOCKPLUSWakelockPlusApi(id<FlutterBinaryMessenger> binaryMessenger, NSObject<WAKELOCKPLUSWakelockPlusApi> *_Nullable api);
|
||||
|
||||
extern void SetUpWAKELOCKPLUSWakelockPlusApiWithSuffix(id<FlutterBinaryMessenger> binaryMessenger, NSObject<WAKELOCKPLUSWakelockPlusApi> *_Nullable api, NSString *messageChannelSuffix);
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -0,0 +1,173 @@
|
||||
// Autogenerated from Pigeon (v26.2.3), do not edit directly.
|
||||
// See also: https://pub.dev/packages/pigeon
|
||||
|
||||
#import "./include/wakelock_plus/messages.g.h"
|
||||
|
||||
#if TARGET_OS_OSX
|
||||
@import FlutterMacOS;
|
||||
#else
|
||||
@import Flutter;
|
||||
#endif
|
||||
|
||||
static NSArray<id> *wrapResult(id result, FlutterError *error) {
|
||||
if (error) {
|
||||
return @[
|
||||
error.code ?: [NSNull null], error.message ?: [NSNull null], error.details ?: [NSNull null]
|
||||
];
|
||||
}
|
||||
return @[ result ?: [NSNull null] ];
|
||||
}
|
||||
|
||||
static id GetNullableObjectAtIndex(NSArray<id> *array, NSInteger key) {
|
||||
id result = array[key];
|
||||
return (result == [NSNull null]) ? nil : result;
|
||||
}
|
||||
|
||||
@interface WAKELOCKPLUSToggleMessage ()
|
||||
+ (WAKELOCKPLUSToggleMessage *)fromList:(NSArray<id> *)list;
|
||||
+ (nullable WAKELOCKPLUSToggleMessage *)nullableFromList:(NSArray<id> *)list;
|
||||
- (NSArray<id> *)toList;
|
||||
@end
|
||||
|
||||
@interface WAKELOCKPLUSIsEnabledMessage ()
|
||||
+ (WAKELOCKPLUSIsEnabledMessage *)fromList:(NSArray<id> *)list;
|
||||
+ (nullable WAKELOCKPLUSIsEnabledMessage *)nullableFromList:(NSArray<id> *)list;
|
||||
- (NSArray<id> *)toList;
|
||||
@end
|
||||
|
||||
@implementation WAKELOCKPLUSToggleMessage
|
||||
+ (instancetype)makeWithEnable:(nullable NSNumber *)enable {
|
||||
WAKELOCKPLUSToggleMessage* pigeonResult = [[WAKELOCKPLUSToggleMessage alloc] init];
|
||||
pigeonResult.enable = enable;
|
||||
return pigeonResult;
|
||||
}
|
||||
+ (WAKELOCKPLUSToggleMessage *)fromList:(NSArray<id> *)list {
|
||||
WAKELOCKPLUSToggleMessage *pigeonResult = [[WAKELOCKPLUSToggleMessage alloc] init];
|
||||
pigeonResult.enable = GetNullableObjectAtIndex(list, 0);
|
||||
return pigeonResult;
|
||||
}
|
||||
+ (nullable WAKELOCKPLUSToggleMessage *)nullableFromList:(NSArray<id> *)list {
|
||||
return (list) ? [WAKELOCKPLUSToggleMessage fromList:list] : nil;
|
||||
}
|
||||
- (NSArray<id> *)toList {
|
||||
return @[
|
||||
self.enable ?: [NSNull null],
|
||||
];
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation WAKELOCKPLUSIsEnabledMessage
|
||||
+ (instancetype)makeWithEnabled:(nullable NSNumber *)enabled {
|
||||
WAKELOCKPLUSIsEnabledMessage* pigeonResult = [[WAKELOCKPLUSIsEnabledMessage alloc] init];
|
||||
pigeonResult.enabled = enabled;
|
||||
return pigeonResult;
|
||||
}
|
||||
+ (WAKELOCKPLUSIsEnabledMessage *)fromList:(NSArray<id> *)list {
|
||||
WAKELOCKPLUSIsEnabledMessage *pigeonResult = [[WAKELOCKPLUSIsEnabledMessage alloc] init];
|
||||
pigeonResult.enabled = GetNullableObjectAtIndex(list, 0);
|
||||
return pigeonResult;
|
||||
}
|
||||
+ (nullable WAKELOCKPLUSIsEnabledMessage *)nullableFromList:(NSArray<id> *)list {
|
||||
return (list) ? [WAKELOCKPLUSIsEnabledMessage fromList:list] : nil;
|
||||
}
|
||||
- (NSArray<id> *)toList {
|
||||
return @[
|
||||
self.enabled ?: [NSNull null],
|
||||
];
|
||||
}
|
||||
@end
|
||||
|
||||
@interface WAKELOCKPLUSMessagesPigeonCodecReader : FlutterStandardReader
|
||||
@end
|
||||
@implementation WAKELOCKPLUSMessagesPigeonCodecReader
|
||||
- (nullable id)readValueOfType:(UInt8)type {
|
||||
switch (type) {
|
||||
case 129:
|
||||
return [WAKELOCKPLUSToggleMessage fromList:[self readValue]];
|
||||
case 130:
|
||||
return [WAKELOCKPLUSIsEnabledMessage fromList:[self readValue]];
|
||||
default:
|
||||
return [super readValueOfType:type];
|
||||
}
|
||||
}
|
||||
@end
|
||||
|
||||
@interface WAKELOCKPLUSMessagesPigeonCodecWriter : FlutterStandardWriter
|
||||
@end
|
||||
@implementation WAKELOCKPLUSMessagesPigeonCodecWriter
|
||||
- (void)writeValue:(id)value {
|
||||
if ([value isKindOfClass:[WAKELOCKPLUSToggleMessage class]]) {
|
||||
[self writeByte:129];
|
||||
[self writeValue:[value toList]];
|
||||
} else if ([value isKindOfClass:[WAKELOCKPLUSIsEnabledMessage class]]) {
|
||||
[self writeByte:130];
|
||||
[self writeValue:[value toList]];
|
||||
} else {
|
||||
[super writeValue:value];
|
||||
}
|
||||
}
|
||||
@end
|
||||
|
||||
@interface WAKELOCKPLUSMessagesPigeonCodecReaderWriter : FlutterStandardReaderWriter
|
||||
@end
|
||||
@implementation WAKELOCKPLUSMessagesPigeonCodecReaderWriter
|
||||
- (FlutterStandardWriter *)writerWithData:(NSMutableData *)data {
|
||||
return [[WAKELOCKPLUSMessagesPigeonCodecWriter alloc] initWithData:data];
|
||||
}
|
||||
- (FlutterStandardReader *)readerWithData:(NSData *)data {
|
||||
return [[WAKELOCKPLUSMessagesPigeonCodecReader alloc] initWithData:data];
|
||||
}
|
||||
@end
|
||||
|
||||
NSObject<FlutterMessageCodec> *WAKELOCKPLUSGetMessagesCodec(void) {
|
||||
static FlutterStandardMessageCodec *sSharedObject = nil;
|
||||
static dispatch_once_t sPred = 0;
|
||||
dispatch_once(&sPred, ^{
|
||||
WAKELOCKPLUSMessagesPigeonCodecReaderWriter *readerWriter = [[WAKELOCKPLUSMessagesPigeonCodecReaderWriter alloc] init];
|
||||
sSharedObject = [FlutterStandardMessageCodec codecWithReaderWriter:readerWriter];
|
||||
});
|
||||
return sSharedObject;
|
||||
}
|
||||
void SetUpWAKELOCKPLUSWakelockPlusApi(id<FlutterBinaryMessenger> binaryMessenger, NSObject<WAKELOCKPLUSWakelockPlusApi> *api) {
|
||||
SetUpWAKELOCKPLUSWakelockPlusApiWithSuffix(binaryMessenger, api, @"");
|
||||
}
|
||||
|
||||
void SetUpWAKELOCKPLUSWakelockPlusApiWithSuffix(id<FlutterBinaryMessenger> binaryMessenger, NSObject<WAKELOCKPLUSWakelockPlusApi> *api, NSString *messageChannelSuffix) {
|
||||
messageChannelSuffix = messageChannelSuffix.length > 0 ? [NSString stringWithFormat: @".%@", messageChannelSuffix] : @"";
|
||||
{
|
||||
FlutterBasicMessageChannel *channel =
|
||||
[[FlutterBasicMessageChannel alloc]
|
||||
initWithName:[NSString stringWithFormat:@"%@%@", @"dev.flutter.pigeon.wakelock_plus_platform_interface.WakelockPlusApi.toggle", messageChannelSuffix]
|
||||
binaryMessenger:binaryMessenger
|
||||
codec:WAKELOCKPLUSGetMessagesCodec()];
|
||||
if (api) {
|
||||
NSCAssert([api respondsToSelector:@selector(toggleMsg:error:)], @"WAKELOCKPLUSWakelockPlusApi api (%@) doesn't respond to @selector(toggleMsg:error:)", api);
|
||||
[channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
|
||||
NSArray<id> *args = message;
|
||||
WAKELOCKPLUSToggleMessage *arg_msg = GetNullableObjectAtIndex(args, 0);
|
||||
FlutterError *error;
|
||||
[api toggleMsg:arg_msg error:&error];
|
||||
callback(wrapResult(nil, error));
|
||||
}];
|
||||
} else {
|
||||
[channel setMessageHandler:nil];
|
||||
}
|
||||
}
|
||||
{
|
||||
FlutterBasicMessageChannel *channel =
|
||||
[[FlutterBasicMessageChannel alloc]
|
||||
initWithName:[NSString stringWithFormat:@"%@%@", @"dev.flutter.pigeon.wakelock_plus_platform_interface.WakelockPlusApi.isEnabled", messageChannelSuffix]
|
||||
binaryMessenger:binaryMessenger
|
||||
codec:WAKELOCKPLUSGetMessagesCodec()];
|
||||
if (api) {
|
||||
NSCAssert([api respondsToSelector:@selector(isEnabledWithError:)], @"WAKELOCKPLUSWakelockPlusApi api (%@) doesn't respond to @selector(isEnabledWithError:)", api);
|
||||
[channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
|
||||
FlutterError *error;
|
||||
WAKELOCKPLUSIsEnabledMessage *output = [api isEnabledWithError:&error];
|
||||
callback(wrapResult(output, error));
|
||||
}];
|
||||
} else {
|
||||
[channel setMessageHandler:nil];
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,3 @@
|
||||
export 'wakelock_plus_linux_plugin.dart';
|
||||
export 'wakelock_plus_macos_plugin.dart';
|
||||
export 'wakelock_plus_windows_plugin.dart';
|
||||
@@ -0,0 +1,91 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:dbus/dbus.dart';
|
||||
import 'package:meta/meta.dart';
|
||||
import 'package:package_info_plus/package_info_plus.dart';
|
||||
import 'package:wakelock_plus_platform_interface/wakelock_plus_platform_interface.dart';
|
||||
|
||||
/// The Linux implementation of the [WakelockPlusPlatformInterface].
|
||||
///
|
||||
/// This class implements the `wakelock_plus` plugin functionality for Linux
|
||||
/// using the `org.freedesktop.portal.Inhibit` D-Bus API
|
||||
/// (see https://flatpak.github.io/xdg-desktop-portal/docs/doc-org.freedesktop.portal.Inhibit).
|
||||
class WakelockPlusLinuxPlugin extends WakelockPlusPlatformInterface {
|
||||
/// Registers this class as the default instance of [WakelockPlatformInterface].
|
||||
static void registerWith() {
|
||||
WakelockPlusPlatformInterface.instance = WakelockPlusLinuxPlugin();
|
||||
}
|
||||
|
||||
/// Constructs an instance of [WakelockPlusLinuxPlugin].
|
||||
factory WakelockPlusLinuxPlugin({
|
||||
@visibleForTesting DBusClient? client,
|
||||
@visibleForTesting DBusRemoteObject? object,
|
||||
@visibleForTesting Future<String> Function()? appNameGetter,
|
||||
}) {
|
||||
final dbusClient = client ?? DBusClient.session();
|
||||
final remoteObject =
|
||||
object ??
|
||||
DBusRemoteObject(
|
||||
dbusClient,
|
||||
name: 'org.freedesktop.portal.Desktop',
|
||||
path: DBusObjectPath('/org/freedesktop/portal/desktop'),
|
||||
);
|
||||
return WakelockPlusLinuxPlugin._internal(
|
||||
dbusClient,
|
||||
remoteObject,
|
||||
appNameGetter,
|
||||
);
|
||||
}
|
||||
|
||||
WakelockPlusLinuxPlugin._internal(
|
||||
this._client,
|
||||
this._object,
|
||||
this._appNameGetter,
|
||||
);
|
||||
|
||||
final DBusClient _client;
|
||||
final DBusRemoteObject _object;
|
||||
final Future<String> Function()? _appNameGetter;
|
||||
DBusObjectPath? _requestHandle;
|
||||
|
||||
Future<String> get _appName =>
|
||||
_appNameGetter?.call() ??
|
||||
PackageInfo.fromPlatform().then((info) => info.appName);
|
||||
|
||||
@override
|
||||
Future<void> toggle({required bool enable}) async {
|
||||
if (enable) {
|
||||
final appName = await _appName;
|
||||
_requestHandle = await _object
|
||||
.callMethod(
|
||||
'org.freedesktop.portal.Inhibit',
|
||||
'Inhibit',
|
||||
[
|
||||
const DBusString(''),
|
||||
const DBusUint32(8),
|
||||
DBusDict.stringVariant({
|
||||
'reason': DBusString('$appName: wakelock active'),
|
||||
}),
|
||||
],
|
||||
replySignature: DBusSignature('o'),
|
||||
)
|
||||
.then((response) => response.returnValues.single.asObjectPath());
|
||||
} else if (_requestHandle != null) {
|
||||
final requestObject = DBusRemoteObject(
|
||||
_client,
|
||||
name: 'org.freedesktop.portal.Desktop',
|
||||
path: _requestHandle!,
|
||||
);
|
||||
await requestObject.callMethod(
|
||||
'org.freedesktop.portal.Request',
|
||||
'Close',
|
||||
[],
|
||||
replySignature: DBusSignature.empty,
|
||||
);
|
||||
_requestHandle = null;
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<bool> get enabled async => _requestHandle != null;
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:wakelock_plus_platform_interface/wakelock_plus_platform_interface.dart';
|
||||
|
||||
/// The macOS implementation of the [WakelockPlusPlatformInterface].
|
||||
///
|
||||
/// This class implements the `wakelock_plus` plugin functionality for macOS.
|
||||
///
|
||||
/// Note that this is *also* a method channel implementation (like the default
|
||||
/// instance). We use manual method channel calls instead of `pigeon` for the
|
||||
/// moment because macOS support for `pigeon` is not clear yet.
|
||||
/// See https://github.com/flutter/flutter/issues/73738.
|
||||
class WakelockPlusMacOSPlugin extends WakelockPlusPlatformInterface {
|
||||
static const MethodChannel _channel = MethodChannel('wakelock_plus_macos');
|
||||
|
||||
/// Registers this class as the default instance of [WakelockPlatformInterface].
|
||||
static void registerWith() {
|
||||
WakelockPlusPlatformInterface.instance = WakelockPlusMacOSPlugin();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> toggle({required bool enable}) async {
|
||||
await _channel.invokeMethod('toggle', <String, dynamic>{'enable': enable});
|
||||
}
|
||||
|
||||
@override
|
||||
Future<bool> get enabled async =>
|
||||
await _channel.invokeMethod('enabled') as bool;
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:flutter_web_plugins/flutter_web_plugins.dart';
|
||||
import 'package:wakelock_plus/src/web_impl/import_js_library.dart';
|
||||
import 'package:wakelock_plus/src/web_impl/js_wakelock.dart'
|
||||
as wakelock_plus_web;
|
||||
import 'package:wakelock_plus_platform_interface/wakelock_plus_platform_interface.dart';
|
||||
|
||||
/// The web implementation of the [WakelockPlatformInterface].
|
||||
///
|
||||
/// This class implements the `wakelock_plus` plugin functionality for web.
|
||||
class WakelockPlusWebPlugin extends WakelockPlusPlatformInterface {
|
||||
/// Registers [WakelockPlusWebPlugin] as the default instance of the
|
||||
/// [WakelockPlatformInterface].
|
||||
static void registerWith(Registrar registrar) {
|
||||
WakelockPlusPlatformInterface.instance = WakelockPlusWebPlugin();
|
||||
}
|
||||
|
||||
// The future that signals when the JS is loaded.
|
||||
// This needs to be `await`ed before accessing any methods of the
|
||||
// JS-interop layer.
|
||||
Future<void>? _jsLoaded;
|
||||
|
||||
//
|
||||
// Lazily imports the JS library once, then awaits to ensure that
|
||||
// it's loaded into the DOM.
|
||||
//
|
||||
Future<void> _ensureJsLoaded() async {
|
||||
_jsLoaded ??= importJsLibrary(
|
||||
url: 'assets/no_sleep.js',
|
||||
flutterPluginName: 'wakelock_plus',
|
||||
);
|
||||
return _jsLoaded;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> toggle({required bool enable}) async {
|
||||
// Make sure the JS library is loaded before calling it.
|
||||
await _ensureJsLoaded();
|
||||
await wakelock_plus_web.toggle(enable);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<bool> get enabled async {
|
||||
// Make sure the JS library is loaded before calling it.
|
||||
await _ensureJsLoaded();
|
||||
return wakelock_plus_web.enabled();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:wakelock_plus_platform_interface/wakelock_plus_platform_interface.dart';
|
||||
import 'package:win32/win32.dart';
|
||||
|
||||
/// The Windows implementation of the [WakelockPlusPlatformInterface].
|
||||
///
|
||||
/// This class implements the `wakelock_plus` plugin functionality for Windows
|
||||
/// using the `SetThreadExecutionState` win32 API
|
||||
/// (see https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-setthreadexecutionstate).
|
||||
class WakelockPlusWindowsPlugin extends WakelockPlusPlatformInterface {
|
||||
/// Registers this class as the default instance of [WakelockPlatformInterface].
|
||||
static void registerWith() {
|
||||
WakelockPlusPlatformInterface.instance = WakelockPlusWindowsPlugin();
|
||||
}
|
||||
|
||||
var _enabled = false;
|
||||
|
||||
@override
|
||||
Future<void> toggle({required bool enable}) async {
|
||||
final int response;
|
||||
if (enable) {
|
||||
response = SetThreadExecutionState(ES_CONTINUOUS | ES_DISPLAY_REQUIRED);
|
||||
} else {
|
||||
response = SetThreadExecutionState(ES_CONTINUOUS);
|
||||
}
|
||||
|
||||
// SetThreadExecutionState returns 0 if the operation failed.
|
||||
if (response != 0) {
|
||||
_enabled = enable;
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<bool> get enabled async => _enabled;
|
||||
|
||||
@override
|
||||
bool get isMock => false;
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
import 'dart:async';
|
||||
import 'dart:ui_web' as ui_web;
|
||||
|
||||
import 'package:web/web.dart' as web;
|
||||
|
||||
/// This is an implementation of the `import_js_library` plugin that is used
|
||||
/// until that plugin is migrated to null safety.
|
||||
/// See https://github.com/florent37/flutter_web_import_js_library/pull/6#issuecomment-735349208.
|
||||
|
||||
/// Imports a JS script file from the given [url] given the relative
|
||||
/// [flutterPluginName].
|
||||
Future<void> importJsLibrary({required String url, String? flutterPluginName}) async {
|
||||
if (flutterPluginName == null) {
|
||||
return _importJSLibraries([url]);
|
||||
} else {
|
||||
return _importJSLibraries([_libraryUrl(url, flutterPluginName)]);
|
||||
}
|
||||
}
|
||||
|
||||
String _libraryUrl(String url, String pluginName) {
|
||||
// Added suggested changes as per
|
||||
// https://github.com/fluttercommunity/wakelock_plus/issues/19#issuecomment-2301963609
|
||||
if (url.startsWith('./')) {
|
||||
url = url.replaceFirst('./', '');
|
||||
}
|
||||
|
||||
if (url.startsWith('assets/')) {
|
||||
if (const bool.fromEnvironment('WEB_PLUGIN_TESTS', defaultValue: false)) {
|
||||
// Flutter tests running on Chrome just need to use the library path
|
||||
// without pre-pending "assets/".
|
||||
//
|
||||
// In other words, don't use the asset manager since it's not currently
|
||||
// supported for Chrome-based Flutter tests.
|
||||
//
|
||||
// See https://github.com/flutter/flutter/issues/159879 for more details.
|
||||
// TODO: Remove the workaround once test asset support is added
|
||||
// for tests running in Chrome.
|
||||
return 'packages/$pluginName/$url';
|
||||
}
|
||||
return ui_web.assetManager.getAssetUrl('packages/$pluginName/$url');
|
||||
}
|
||||
|
||||
return url;
|
||||
}
|
||||
|
||||
Future? _importRunning;
|
||||
Map<String, String> _loadedLibraries = {};
|
||||
int _nextLibraryId = 0;
|
||||
|
||||
web.HTMLScriptElement _createScriptTag(String library) {
|
||||
final scriptId = 'imported-js-library-${_nextLibraryId++}';
|
||||
final script = web.document.createElement('script') as web.HTMLScriptElement
|
||||
..type = 'text/javascript'
|
||||
..charset = 'utf-8'
|
||||
..async = true
|
||||
..src = library
|
||||
..id = scriptId;
|
||||
return script;
|
||||
}
|
||||
|
||||
/// Injects a bunch of libraries in the `<head>` and returns a
|
||||
/// Future that resolves when all load.
|
||||
Future<void> _importJSLibraries(List<String> libraries) async {
|
||||
// we add the library to _loadedLibraries asynchronously, so we need locking.
|
||||
// Dart uses voluntary preemption, so everything between two `await`s can be
|
||||
// considered locked
|
||||
while (_importRunning != null) {
|
||||
await _importRunning;
|
||||
}
|
||||
final importLockCompleter = Completer();
|
||||
_importRunning = importLockCompleter.future;
|
||||
final loading = <Future<void>>[];
|
||||
final head = web.document.head;
|
||||
|
||||
for (final library in libraries) {
|
||||
if (!_isImported(library)) {
|
||||
final scriptTag = _createScriptTag(library);
|
||||
head!.appendChild(scriptTag);
|
||||
final completer = Completer();
|
||||
loading.add(completer.future);
|
||||
|
||||
unawaited(
|
||||
scriptTag.onLoad.first.then((_) {
|
||||
_loadedLibraries[library] = scriptTag.id;
|
||||
completer.complete();
|
||||
}),
|
||||
);
|
||||
unawaited(scriptTag.onError.first.then((event) => completer.completeError(Exception('Error loading: $library'))));
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
await Future.wait(loading, eagerError: true);
|
||||
} finally {
|
||||
// first "unlock" future, then complete the completer for anyone already waiting.
|
||||
// I'm not sure if `.complete()` is yielding execution, so this is the safe order
|
||||
_importRunning = null;
|
||||
importLockCompleter.complete();
|
||||
}
|
||||
}
|
||||
|
||||
bool _isImported(String url) {
|
||||
final head = web.document.head!;
|
||||
return _isLoaded(head, url);
|
||||
}
|
||||
|
||||
bool _isLoaded(web.HTMLHeadElement head, String url) {
|
||||
final scriptId = _loadedLibraries[url];
|
||||
if (scriptId == null) {
|
||||
return false;
|
||||
}
|
||||
return head.querySelector('#$scriptId') != null;
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
@JS('Wakelock')
|
||||
library;
|
||||
|
||||
import 'dart:js_interop';
|
||||
|
||||
@JS('toggle')
|
||||
external JSPromise<JSAny?> _toggle(JSBoolean enable);
|
||||
|
||||
/// Toggles the JS wakelock.
|
||||
Future<void> toggle(bool enable) {
|
||||
return _toggle(enable.toJS).toDart.then((_) => null);
|
||||
}
|
||||
|
||||
@JS('enabled')
|
||||
external JSPromise<JSBoolean> _enabled();
|
||||
|
||||
/// Returns a JS promise of whether the wakelock is enabled or not.
|
||||
Future<bool> enabled() {
|
||||
return _enabled().toDart.then((enabled) => enabled.toDart);
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:wakelock_plus_platform_interface/wakelock_plus_platform_interface.dart';
|
||||
|
||||
export 'src/wakelock_plus_io_plugin.dart'
|
||||
if (dart.library.js_interop) 'src/wakelock_plus_web_plugin.dart';
|
||||
|
||||
/// The [WakelockPlusPlatformInterface] that is used by [WakelockPlus].
|
||||
///
|
||||
/// This needs to be exposed for testing as unit tests might run on macOS.
|
||||
/// In that case, the "hacky" instance override that we use here would be
|
||||
/// triggered for the unit tests, even though the unit tests should actually
|
||||
/// test the `pigeon` method channel implementation. Therefore, we want to
|
||||
/// override this in tests that run on macOS (where there is no actual device).
|
||||
@visibleForTesting
|
||||
var wakelockPlusPlatformInstance = WakelockPlusPlatformInterface.instance;
|
||||
|
||||
/// Class providing all wakelock functionality using static members.
|
||||
///
|
||||
/// To enable the wakelock, you can use [WakelockPlus.enable] and to disable it,
|
||||
/// you can call [WakelockPlus.disable].
|
||||
/// You do not need to worry about making redundant calls, e.g. calling
|
||||
/// [WakelockPlus.enable] when the wakelock is already enabled as the plugin handles
|
||||
/// this for you, i.e. it checks the status to determine if the wakelock is
|
||||
/// already enabled or disabled.
|
||||
/// If you want the flexibility to pass a [bool] to control whether the wakelock
|
||||
/// should be enabled or disabled, you can use [WakelockPlus.toggle].
|
||||
///
|
||||
/// The [WakelockPlus.enabled] getter allows you to retrieve the current wakelock
|
||||
/// status of the device..
|
||||
class WakelockPlus {
|
||||
/// Enables the wakelock.
|
||||
///
|
||||
/// This can simply be called using `WakelockPlus.enable()` and does not return
|
||||
/// anything.
|
||||
/// You can await the [Future] to wait for the operation to complete.
|
||||
///
|
||||
/// See also:
|
||||
/// * [toggle], which allows to enable or disable using a [bool] parameter.
|
||||
static Future<void> enable() => toggle(enable: true);
|
||||
|
||||
/// Disables the wakelock.
|
||||
///
|
||||
/// This can simply be called using `WakelockPlus.disable()` and does not return
|
||||
/// anything.
|
||||
/// You can await the [Future] to wait for the operation to complete.
|
||||
///
|
||||
/// See also:
|
||||
/// * [toggle], which allows to enable or disable using a [bool] parameter.
|
||||
static Future<void> disable() => toggle(enable: false);
|
||||
|
||||
/// Toggles the wakelock on or off.
|
||||
///
|
||||
/// You can simply use this function to toggle the wakelock using a [bool]
|
||||
/// value (for the [enable] parameter).
|
||||
///
|
||||
/// ```dart
|
||||
/// // This line keeps the screen on.
|
||||
/// WakelockPlus.toggle(enable: true);
|
||||
///
|
||||
/// bool enableWakelock = false;
|
||||
/// // The following line disables the WakelockPlus.
|
||||
/// WakelockPlus.toggle(enable: enableWakelock);
|
||||
/// ```
|
||||
///
|
||||
/// You can await the [Future] to wait for the operation to complete.
|
||||
static Future<void> toggle({required bool enable}) {
|
||||
return wakelockPlusPlatformInstance.toggle(enable: enable);
|
||||
}
|
||||
|
||||
/// Returns whether the wakelock is currently enabled or not.
|
||||
///
|
||||
/// If you want to retrieve the current wakelock status, you will have to call
|
||||
/// [WakelockPlus.enabled] and await its result:
|
||||
///
|
||||
/// ```dart
|
||||
/// bool wakelockEnabled = await WakelockPlus.enabled;
|
||||
/// ```
|
||||
static Future<bool> get enabled => wakelockPlusPlatformInstance.enabled;
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
#
|
||||
# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html
|
||||
#
|
||||
Pod::Spec.new do |s|
|
||||
s.name = 'wakelock_plus'
|
||||
s.version = '0.0.1'
|
||||
s.summary = 'Plugin that allows you to keep the device screen awake, i.e. prevent the screen from sleeping on Android, iOS, macOS, Windows, and web.'
|
||||
s.description = <<-DESC
|
||||
Plugin that allows you to keep the device screen awake, i.e. prevent the screen from sleeping on Android, iOS, macOS, Windows, and web.
|
||||
DESC
|
||||
s.homepage = 'https://github.com/fluttercommunity/wakelock_plus'
|
||||
s.license = { :type => 'BSD', :file => '../LICENSE' }
|
||||
s.author = { 'Flutter Team' => 'flutter-dev@googlegroups.com' }
|
||||
s.source = { :http => 'https://github.com/fluttercommunity/wakelock_plus/tree/main/packages/wakelock_plus_macos' }
|
||||
s.source_files = 'wakelock_plus/Sources/wakelock_plus/**/*.swift'
|
||||
s.dependency 'FlutterMacOS'
|
||||
s.osx.deployment_target = '10.15'
|
||||
# Flutter.framework does not contain a i386 slice.
|
||||
s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'i386' }
|
||||
s.swift_version = '5.0'
|
||||
s.resource_bundles = {'wakelock_plus' => ['wakelock_plus/Sources/wakelock_plus/Resources/PrivacyInfo.xcprivacy']}
|
||||
end
|
||||
@@ -0,0 +1,24 @@
|
||||
// swift-tools-version: 5.9
|
||||
// The swift-tools-version declares the minimum version of Swift required to build this package.
|
||||
|
||||
import PackageDescription
|
||||
|
||||
let package = Package(
|
||||
name: "wakelock_plus",
|
||||
platforms: [
|
||||
.macOS("10.15")
|
||||
],
|
||||
products: [
|
||||
.library(name: "wakelock-plus", targets: ["wakelock_plus"])
|
||||
],
|
||||
dependencies: [],
|
||||
targets: [
|
||||
.target(
|
||||
name: "wakelock_plus",
|
||||
dependencies: [],
|
||||
resources: [
|
||||
.process("Resources"),
|
||||
]
|
||||
)
|
||||
]
|
||||
)
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>NSPrivacyTrackingDomains</key>
|
||||
<array/>
|
||||
<key>NSPrivacyCollectedDataTypes</key>
|
||||
<array/>
|
||||
<key>NSPrivacyTracking</key>
|
||||
<false/>
|
||||
</dict>
|
||||
</plist>
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
import Cocoa
|
||||
import FlutterMacOS
|
||||
import IOKit.pwr_mgt
|
||||
|
||||
public class WakelockPlusMacosPlugin: NSObject, FlutterPlugin {
|
||||
public static func register(with registrar: FlutterPluginRegistrar) {
|
||||
let channel = FlutterMethodChannel(name: "wakelock_plus_macos", binaryMessenger: registrar.messenger)
|
||||
let instance = WakelockPlusMacosPlugin()
|
||||
registrar.addMethodCallDelegate(instance, channel: channel)
|
||||
}
|
||||
|
||||
var assertionID: IOPMAssertionID = 0
|
||||
var wakelockEnabled = false
|
||||
|
||||
public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
|
||||
switch call.method {
|
||||
case "toggle":
|
||||
let args = call.arguments as? Dictionary<String, Any>
|
||||
let enable = args!["enable"] as! Bool
|
||||
if enable {
|
||||
enableWakelock()
|
||||
} else {
|
||||
disableWakelock();
|
||||
}
|
||||
result(true)
|
||||
case "enabled":
|
||||
result(wakelockEnabled)
|
||||
default:
|
||||
result(FlutterMethodNotImplemented)
|
||||
}
|
||||
}
|
||||
|
||||
func enableWakelock(reason: String = "Disabling display sleep") {
|
||||
if !wakelockEnabled {
|
||||
wakelockEnabled = IOPMAssertionCreateWithName( kIOPMAssertionTypeNoDisplaySleep as CFString,
|
||||
IOPMAssertionLevel(kIOPMAssertionLevelOn),
|
||||
reason as CFString,
|
||||
&assertionID) == kIOReturnSuccess
|
||||
}
|
||||
}
|
||||
|
||||
func disableWakelock() {
|
||||
if wakelockEnabled {
|
||||
IOPMAssertionRelease(assertionID)
|
||||
wakelockEnabled = false
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
# Vendored from fluttercommunity/wakelock_plus at
|
||||
# 4f4be85aafe1f8216c2fdd3376263d6f40529684. Local changes are the tvOS
|
||||
# deployment target and explicit unawaited wrappers required by the root lint
|
||||
# policy. Refresh from the newest upstream release compatible with win32 5.x,
|
||||
# reapply both changes, then run pub get and the tvOS pod build.
|
||||
name: wakelock_plus
|
||||
description: >-2
|
||||
Plugin that allows you to keep the device screen awake, i.e. prevent the screen from sleeping on
|
||||
Android, iOS, macOS, Windows, Linux, and web.
|
||||
version: 1.5.2
|
||||
repository: https://github.com/fluttercommunity/wakelock_plus/tree/main/wakelock_plus
|
||||
|
||||
environment:
|
||||
sdk: '>=3.10.0 <4.0.0'
|
||||
flutter: ">=3.38.0"
|
||||
|
||||
dependencies:
|
||||
flutter:
|
||||
sdk: flutter
|
||||
flutter_web_plugins:
|
||||
sdk: flutter
|
||||
meta: ^1.17.0
|
||||
wakelock_plus_platform_interface: ^1.4.0
|
||||
|
||||
# Windows dependencies
|
||||
# win32 is compatible across v5 for Win32 only (not COM)
|
||||
win32: ">=5.6.1 <6.0.0"
|
||||
|
||||
# Linux dependencies
|
||||
dbus: ^0.7.12
|
||||
package_info_plus: ^9.0.0
|
||||
|
||||
# Web dependencies
|
||||
web: ">=0.5.1 <2.0.0"
|
||||
|
||||
dev_dependencies:
|
||||
flutter_test:
|
||||
sdk: flutter
|
||||
flutter_lints: ^6.0.0
|
||||
pigeon: ^26.2.3 # dart run pigeon --input "pigeons/messages.dart"
|
||||
mocktail: ^1.0.4
|
||||
|
||||
# For information on the generic Dart part of this file, see the
|
||||
# following page: https://dart.dev/tools/pub/pubspec
|
||||
|
||||
# The following section is specific to Flutter packages.
|
||||
flutter:
|
||||
# This section identifies this Flutter project as a plugin project.
|
||||
# The 'pluginClass' specifies the class (in Java, Kotlin, Swift, Objective-C, etc.)
|
||||
# which should be registered in the plugin registry. This is required for
|
||||
# using method channels.
|
||||
# The Android 'package' specifies package in which the registered class is.
|
||||
# This is required for using method channels on Android.
|
||||
# The 'ffiPlugin' specifies that native code should be built and bundled.
|
||||
# This is required for using `dart:ffi`.
|
||||
# All these are used by the tooling to maintain consistency when
|
||||
# adding or updating assets for this project.
|
||||
plugin:
|
||||
platforms:
|
||||
android:
|
||||
package: dev.fluttercommunity.plus.wakelock
|
||||
pluginClass: WakelockPlusPlugin
|
||||
ios:
|
||||
pluginClass: WakelockPlusPlugin
|
||||
windows:
|
||||
dartPluginClass: WakelockPlusWindowsPlugin
|
||||
macos:
|
||||
pluginClass: WakelockPlusMacosPlugin
|
||||
dartPluginClass: WakelockPlusMacOSPlugin
|
||||
linux:
|
||||
dartPluginClass: WakelockPlusLinuxPlugin
|
||||
web:
|
||||
pluginClass: WakelockPlusWebPlugin
|
||||
fileName: src/wakelock_plus_web_plugin.dart
|
||||
|
||||
# To add assets to your plugin package, add an assets section, like this:
|
||||
# assets:
|
||||
# - images/a_dot_burr.jpeg
|
||||
# - images/a_dot_ham.jpeg
|
||||
#
|
||||
# For details regarding assets in packages, see
|
||||
# https://flutter.dev/assets-and-images/#from-packages
|
||||
#
|
||||
# An image asset can refer to one or more resolution-specific "variants", see
|
||||
# https://flutter.dev/assets-and-images/#resolution-aware
|
||||
|
||||
# To add custom fonts to your plugin package, add a fonts section here,
|
||||
# in this "flutter" section. Each entry in this list should have a
|
||||
# "family" key with the font family name, and a "fonts" key with a
|
||||
# list giving the asset and other descriptors for the font. For
|
||||
# example:
|
||||
# fonts:
|
||||
# - family: Schyler
|
||||
# fonts:
|
||||
# - asset: fonts/Schyler-Regular.ttf
|
||||
# - asset: fonts/Schyler-Italic.ttf
|
||||
# style: italic
|
||||
# - family: Trajan Pro
|
||||
# fonts:
|
||||
# - asset: fonts/TrajanPro.ttf
|
||||
# - asset: fonts/TrajanPro_Bold.ttf
|
||||
# weight: 700
|
||||
#
|
||||
# For details regarding fonts in packages, see
|
||||
# https://flutter.dev/custom-fonts/#from-packages
|
||||
|
||||
assets:
|
||||
- packages/wakelock_plus/assets/no_sleep.js
|
||||
Reference in New Issue
Block a user