├── .gitignore
├── .metadata
├── README.md
├── analysis_options.yaml
├── android
├── .gitignore
├── app
│ ├── build.gradle
│ └── src
│ │ ├── debug
│ │ └── AndroidManifest.xml
│ │ ├── main
│ │ ├── AndroidManifest.xml
│ │ ├── kotlin
│ │ │ └── ws
│ │ │ │ └── diye
│ │ │ │ └── scrcpy_flutter
│ │ │ │ └── MainActivity.kt
│ │ └── res
│ │ │ ├── drawable-v21
│ │ │ └── launch_background.xml
│ │ │ ├── drawable
│ │ │ └── launch_background.xml
│ │ │ ├── mipmap-hdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-mdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xhdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xxhdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xxxhdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── values-night
│ │ │ └── styles.xml
│ │ │ └── values
│ │ │ └── styles.xml
│ │ └── profile
│ │ └── AndroidManifest.xml
├── build.gradle
├── gradle.properties
├── gradle
│ └── wrapper
│ │ └── gradle-wrapper.properties
└── settings.gradle
├── ios
├── .gitignore
├── Flutter
│ ├── AppFrameworkInfo.plist
│ ├── Debug.xcconfig
│ └── Release.xcconfig
├── Runner.xcodeproj
│ ├── project.pbxproj
│ ├── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ │ ├── IDEWorkspaceChecks.plist
│ │ │ └── WorkspaceSettings.xcsettings
│ └── xcshareddata
│ │ └── xcschemes
│ │ └── Runner.xcscheme
├── Runner.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcshareddata
│ │ ├── IDEWorkspaceChecks.plist
│ │ └── WorkspaceSettings.xcsettings
└── Runner
│ ├── AppDelegate.swift
│ ├── Assets.xcassets
│ ├── AppIcon.appiconset
│ │ ├── Contents.json
│ │ ├── Icon-App-1024x1024@1x.png
│ │ ├── Icon-App-20x20@1x.png
│ │ ├── Icon-App-20x20@2x.png
│ │ ├── Icon-App-20x20@3x.png
│ │ ├── Icon-App-29x29@1x.png
│ │ ├── Icon-App-29x29@2x.png
│ │ ├── Icon-App-29x29@3x.png
│ │ ├── Icon-App-40x40@1x.png
│ │ ├── Icon-App-40x40@2x.png
│ │ ├── Icon-App-40x40@3x.png
│ │ ├── Icon-App-60x60@2x.png
│ │ ├── Icon-App-60x60@3x.png
│ │ ├── Icon-App-76x76@1x.png
│ │ ├── Icon-App-76x76@2x.png
│ │ └── Icon-App-83.5x83.5@2x.png
│ └── LaunchImage.imageset
│ │ ├── Contents.json
│ │ ├── LaunchImage.png
│ │ ├── LaunchImage@2x.png
│ │ ├── LaunchImage@3x.png
│ │ └── README.md
│ ├── Base.lproj
│ ├── LaunchScreen.storyboard
│ └── Main.storyboard
│ ├── Info.plist
│ └── Runner-Bridging-Header.h
├── lib
├── android_keycode.dart
├── cbc_cipher.dart
├── debug_control.dart
├── device_list.dart
├── main.dart
└── scrcpy.dart
├── pubspec.lock
├── pubspec.yaml
└── test
└── widget_test.dart
/.gitignore:
--------------------------------------------------------------------------------
1 | # Miscellaneous
2 | *.class
3 | *.log
4 | *.pyc
5 | *.swp
6 | .DS_Store
7 | .atom/
8 | .buildlog/
9 | .history
10 | .svn/
11 |
12 | # IntelliJ related
13 | *.iml
14 | *.ipr
15 | *.iws
16 | .idea/
17 |
18 | # The .vscode folder contains launch configuration and tasks you configure in
19 | # VS Code which you may wish to be included in version control, so this line
20 | # is commented out by default.
21 | #.vscode/
22 |
23 | # Flutter/Dart/Pub related
24 | **/doc/api/
25 | **/ios/Flutter/.last_build_id
26 | .dart_tool/
27 | .flutter-plugins
28 | .flutter-plugins-dependencies
29 | .packages
30 | .pub-cache/
31 | .pub/
32 | /build/
33 |
34 | # Web related
35 | lib/generated_plugin_registrant.dart
36 |
37 | # Symbolication related
38 | app.*.symbols
39 |
40 | # Obfuscation related
41 | app.*.map.json
42 |
43 | # Android Studio will place build artifacts here
44 | /android/app/debug
45 | /android/app/profile
46 | /android/app/release
47 |
--------------------------------------------------------------------------------
/.metadata:
--------------------------------------------------------------------------------
1 | # This file tracks properties of this Flutter project.
2 | # Used by Flutter tool to assess capabilities and perform upgrades etc.
3 | #
4 | # This file should be version controlled and should not be manually edited.
5 |
6 | version:
7 | revision: ffb2ecea5223acdd139a5039be2f9c796962833d
8 | channel: stable
9 |
10 | project_type: app
11 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # scrcpy_flutter
2 |
3 | Scrcpy client base on flutter.
4 |
5 | ## Getting Started
6 | *Note: 16-char-key is requried for AES encryption if you need sceenshot feature, otherwise provide any string(16-char) while starting server.*
7 |
8 |
9 | - Windows
10 |
11 | 1. Use adb to push [server.jar](https://github.com/diyews/scrcpy/releases) to phone
12 |
13 | .\adb.exe push "C:\scrcpy-server-flutter.jar" /sdcard/scrcpy-server-flutter.jar
14 |
15 | 1. Use adb to start server (Replace `<16_char_key>` to your own)
16 |
17 |
18 | Click to expand!
19 |
20 | ``.\adb.exe shell CLASSPATH=/sdcard/scrcpy-server-flutter.jar nohup app_process / --nice-name=scrcpy_device_server com.genymobile.scrcpy.Server <16_char_key> error 0 8000000 0 -1 true - true true 0 false false - - false `>/dev/null 2`>`&1 `& ``
21 |
22 | (Above `powershell.exe` use `` ` `` to escape character, in `cmd.exe` it is `` ^ ``)
23 |
24 |
25 | - Unix
26 | 1. Use adb to push [server.jar](https://github.com/diyews/scrcpy/releases) to phone
27 |
28 | adb push ./scrcpy-server-flutter.jar /sdcard/scrcpy-server-flutter.jar
29 |
30 | 1. Use adb to start server (Replace `<16_char_key>` to your own)
31 |
32 | ``adb shell CLASSPATH=/sdcard/scrcpy-server-flutter.jar nohup app_process / --nice-name=scrcpy_device_server com.genymobile.scrcpy.Server <16_char_key> error 0 8000000 0 -1 true - true true 0 false false - - false >/dev/null 2>&1 & ``
33 |
34 | Then you are able to connect to the phone via app.
35 |
36 | ## How this app works
37 | App use tcp to connect to `scrcpy-server-flutter.jar`, server port `7007`.
38 |
39 | Server use port `7008` to start http server for serving screenshot.
40 |
41 | ## Trouble shooting
42 |
43 | 1. Server didn't start.
44 |
45 | You can check if server is running by typing `adb shell "ps -A | grep scrcpy_device_server"`
46 |
47 | Try to run command in the front to check if errors there whiling start server. (remove `nohup`, `&` and output redirect from the start script)
48 |
49 | `adb shell CLASSPATH=/sdcard/scrcpy-server-flutter.jar nohup app_process / --nice-name=scrcpy_device_server com.genymobile.scrcpy.Server <16_char_key> error 0 8000000 0 -1 true - true true 0 false false - - false`
50 |
51 | ## Preview
52 | 
53 |
54 |
--------------------------------------------------------------------------------
/analysis_options.yaml:
--------------------------------------------------------------------------------
1 | # This file configures the analyzer, which statically analyzes Dart code to
2 | # check for errors, warnings, and lints.
3 | #
4 | # The issues identified by the analyzer are surfaced in the UI of Dart-enabled
5 | # IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be
6 | # invoked from the command line by running `flutter analyze`.
7 |
8 | # The following line activates a set of recommended lints for Flutter apps,
9 | # packages, and plugins designed to encourage good coding practices.
10 | include: package:flutter_lints/flutter.yaml
11 |
12 | linter:
13 | # The lint rules applied to this project can be customized in the
14 | # section below to disable rules from the `package:flutter_lints/flutter.yaml`
15 | # included above or to enable additional rules. A list of all available lints
16 | # and their documentation is published at
17 | # https://dart-lang.github.io/linter/lints/index.html.
18 | #
19 | # Instead of disabling a lint rule for the entire project in the
20 | # section below, it can also be suppressed for a single line of code
21 | # or a specific dart file by using the `// ignore: name_of_lint` and
22 | # `// ignore_for_file: name_of_lint` syntax on the line or in the file
23 | # producing the lint.
24 | rules:
25 | # avoid_print: false # Uncomment to disable the `avoid_print` rule
26 | # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule
27 |
28 | # Additional information about this file can be found at
29 | # https://dart.dev/guides/language/analysis-options
30 |
--------------------------------------------------------------------------------
/android/.gitignore:
--------------------------------------------------------------------------------
1 | gradle-wrapper.jar
2 | /.gradle
3 | /captures/
4 | /gradlew
5 | /gradlew.bat
6 | /local.properties
7 | GeneratedPluginRegistrant.java
8 |
9 | # Remember to never publicly share your keystore.
10 | # See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app
11 | key.properties
12 | **/*.keystore
13 | **/*.jks
14 |
--------------------------------------------------------------------------------
/android/app/build.gradle:
--------------------------------------------------------------------------------
1 | def localProperties = new Properties()
2 | def localPropertiesFile = rootProject.file('local.properties')
3 | if (localPropertiesFile.exists()) {
4 | localPropertiesFile.withReader('UTF-8') { reader ->
5 | localProperties.load(reader)
6 | }
7 | }
8 |
9 | def flutterRoot = localProperties.getProperty('flutter.sdk')
10 | if (flutterRoot == null) {
11 | throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
12 | }
13 |
14 | def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
15 | if (flutterVersionCode == null) {
16 | flutterVersionCode = '1'
17 | }
18 |
19 | def flutterVersionName = localProperties.getProperty('flutter.versionName')
20 | if (flutterVersionName == null) {
21 | flutterVersionName = '1.0'
22 | }
23 |
24 | apply plugin: 'com.android.application'
25 | apply plugin: 'kotlin-android'
26 | apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
27 |
28 | android {
29 | compileSdkVersion 30
30 |
31 | compileOptions {
32 | sourceCompatibility JavaVersion.VERSION_1_8
33 | targetCompatibility JavaVersion.VERSION_1_8
34 | }
35 |
36 | kotlinOptions {
37 | jvmTarget = '1.8'
38 | }
39 |
40 | sourceSets {
41 | main.java.srcDirs += 'src/main/kotlin'
42 | }
43 |
44 | defaultConfig {
45 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
46 | applicationId "ws.diye.scrcpy_flutter"
47 | minSdkVersion 16
48 | targetSdkVersion 30
49 | versionCode flutterVersionCode.toInteger()
50 | versionName flutterVersionName
51 | }
52 |
53 | buildTypes {
54 | release {
55 | // TODO: Add your own signing config for the release build.
56 | // Signing with the debug keys for now, so `flutter run --release` works.
57 | signingConfig signingConfigs.debug
58 | }
59 | }
60 | }
61 |
62 | flutter {
63 | source '../..'
64 | }
65 |
66 | dependencies {
67 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
68 | }
69 |
--------------------------------------------------------------------------------
/android/app/src/debug/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/android/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
7 |
14 |
18 |
22 |
27 |
31 |
32 |
33 |
34 |
35 |
36 |
38 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/android/app/src/main/kotlin/ws/diye/scrcpy_flutter/MainActivity.kt:
--------------------------------------------------------------------------------
1 | package ws.diye.scrcpy_flutter
2 |
3 | import io.flutter.embedding.android.FlutterActivity
4 |
5 | class MainActivity: FlutterActivity() {
6 | }
7 |
--------------------------------------------------------------------------------
/android/app/src/main/res/drawable-v21/launch_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
12 |
13 |
--------------------------------------------------------------------------------
/android/app/src/main/res/drawable/launch_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
12 |
13 |
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/diyews/scrcpy-flutter/8eeda96c67c1ab5addf5cf5121a0a6601aa2c32c/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/diyews/scrcpy-flutter/8eeda96c67c1ab5addf5cf5121a0a6601aa2c32c/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/diyews/scrcpy-flutter/8eeda96c67c1ab5addf5cf5121a0a6601aa2c32c/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/diyews/scrcpy-flutter/8eeda96c67c1ab5addf5cf5121a0a6601aa2c32c/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/diyews/scrcpy-flutter/8eeda96c67c1ab5addf5cf5121a0a6601aa2c32c/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/values-night/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
15 |
18 |
19 |
--------------------------------------------------------------------------------
/android/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
15 |
18 |
19 |
--------------------------------------------------------------------------------
/android/app/src/profile/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/android/build.gradle:
--------------------------------------------------------------------------------
1 | buildscript {
2 | ext.kotlin_version = '1.3.50'
3 | repositories {
4 | google()
5 | mavenCentral()
6 | }
7 |
8 | dependencies {
9 | classpath 'com.android.tools.build:gradle:4.1.0'
10 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
11 | }
12 | }
13 |
14 | allprojects {
15 | repositories {
16 | google()
17 | mavenCentral()
18 | }
19 | }
20 |
21 | rootProject.buildDir = '../build'
22 | subprojects {
23 | project.buildDir = "${rootProject.buildDir}/${project.name}"
24 | project.evaluationDependsOn(':app')
25 | }
26 |
27 | task clean(type: Delete) {
28 | delete rootProject.buildDir
29 | }
30 |
--------------------------------------------------------------------------------
/android/gradle.properties:
--------------------------------------------------------------------------------
1 | org.gradle.jvmargs=-Xmx1536M
2 | android.useAndroidX=true
3 | android.enableJetifier=true
4 |
--------------------------------------------------------------------------------
/android/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Fri Jun 23 08:50:38 CEST 2017
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-all.zip
7 |
--------------------------------------------------------------------------------
/android/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 |
3 | def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
4 | def properties = new Properties()
5 |
6 | assert localPropertiesFile.exists()
7 | localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) }
8 |
9 | def flutterSdkPath = properties.getProperty("flutter.sdk")
10 | assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
11 | apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle"
12 |
--------------------------------------------------------------------------------
/ios/.gitignore:
--------------------------------------------------------------------------------
1 | *.mode1v3
2 | *.mode2v3
3 | *.moved-aside
4 | *.pbxuser
5 | *.perspectivev3
6 | **/*sync/
7 | .sconsign.dblite
8 | .tags*
9 | **/.vagrant/
10 | **/DerivedData/
11 | Icon?
12 | **/Pods/
13 | **/.symlinks/
14 | profile
15 | xcuserdata
16 | **/.generated/
17 | Flutter/App.framework
18 | Flutter/Flutter.framework
19 | Flutter/Flutter.podspec
20 | Flutter/Generated.xcconfig
21 | Flutter/ephemeral/
22 | Flutter/app.flx
23 | Flutter/app.zip
24 | Flutter/flutter_assets/
25 | Flutter/flutter_export_environment.sh
26 | ServiceDefinitions.json
27 | Runner/GeneratedPluginRegistrant.*
28 |
29 | # Exceptions to above rules.
30 | !default.mode1v3
31 | !default.mode2v3
32 | !default.pbxuser
33 | !default.perspectivev3
34 |
--------------------------------------------------------------------------------
/ios/Flutter/AppFrameworkInfo.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | App
9 | CFBundleIdentifier
10 | io.flutter.flutter.app
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | App
15 | CFBundlePackageType
16 | FMWK
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1.0
23 | MinimumOSVersion
24 | 9.0
25 |
26 |
27 |
--------------------------------------------------------------------------------
/ios/Flutter/Debug.xcconfig:
--------------------------------------------------------------------------------
1 | #include "Generated.xcconfig"
2 |
--------------------------------------------------------------------------------
/ios/Flutter/Release.xcconfig:
--------------------------------------------------------------------------------
1 | #include "Generated.xcconfig"
2 |
--------------------------------------------------------------------------------
/ios/Runner.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
11 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
12 | 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; };
13 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
14 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
15 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
16 | /* End PBXBuildFile section */
17 |
18 | /* Begin PBXCopyFilesBuildPhase section */
19 | 9705A1C41CF9048500538489 /* Embed Frameworks */ = {
20 | isa = PBXCopyFilesBuildPhase;
21 | buildActionMask = 2147483647;
22 | dstPath = "";
23 | dstSubfolderSpec = 10;
24 | files = (
25 | );
26 | name = "Embed Frameworks";
27 | runOnlyForDeploymentPostprocessing = 0;
28 | };
29 | /* End PBXCopyFilesBuildPhase section */
30 |
31 | /* Begin PBXFileReference section */
32 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; };
33 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; };
34 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; };
35 | 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; };
36 | 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
37 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; };
38 | 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; };
39 | 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; };
40 | 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; };
41 | 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
42 | 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
43 | 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; };
44 | 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
45 | /* End PBXFileReference section */
46 |
47 | /* Begin PBXFrameworksBuildPhase section */
48 | 97C146EB1CF9000F007C117D /* Frameworks */ = {
49 | isa = PBXFrameworksBuildPhase;
50 | buildActionMask = 2147483647;
51 | files = (
52 | );
53 | runOnlyForDeploymentPostprocessing = 0;
54 | };
55 | /* End PBXFrameworksBuildPhase section */
56 |
57 | /* Begin PBXGroup section */
58 | 9740EEB11CF90186004384FC /* Flutter */ = {
59 | isa = PBXGroup;
60 | children = (
61 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */,
62 | 9740EEB21CF90195004384FC /* Debug.xcconfig */,
63 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */,
64 | 9740EEB31CF90195004384FC /* Generated.xcconfig */,
65 | );
66 | name = Flutter;
67 | sourceTree = "";
68 | };
69 | 97C146E51CF9000F007C117D = {
70 | isa = PBXGroup;
71 | children = (
72 | 9740EEB11CF90186004384FC /* Flutter */,
73 | 97C146F01CF9000F007C117D /* Runner */,
74 | 97C146EF1CF9000F007C117D /* Products */,
75 | );
76 | sourceTree = "";
77 | };
78 | 97C146EF1CF9000F007C117D /* Products */ = {
79 | isa = PBXGroup;
80 | children = (
81 | 97C146EE1CF9000F007C117D /* Runner.app */,
82 | );
83 | name = Products;
84 | sourceTree = "";
85 | };
86 | 97C146F01CF9000F007C117D /* Runner */ = {
87 | isa = PBXGroup;
88 | children = (
89 | 97C146FA1CF9000F007C117D /* Main.storyboard */,
90 | 97C146FD1CF9000F007C117D /* Assets.xcassets */,
91 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */,
92 | 97C147021CF9000F007C117D /* Info.plist */,
93 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */,
94 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */,
95 | 74858FAE1ED2DC5600515810 /* AppDelegate.swift */,
96 | 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */,
97 | );
98 | path = Runner;
99 | sourceTree = "";
100 | };
101 | /* End PBXGroup section */
102 |
103 | /* Begin PBXNativeTarget section */
104 | 97C146ED1CF9000F007C117D /* Runner */ = {
105 | isa = PBXNativeTarget;
106 | buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
107 | buildPhases = (
108 | 9740EEB61CF901F6004384FC /* Run Script */,
109 | 97C146EA1CF9000F007C117D /* Sources */,
110 | 97C146EB1CF9000F007C117D /* Frameworks */,
111 | 97C146EC1CF9000F007C117D /* Resources */,
112 | 9705A1C41CF9048500538489 /* Embed Frameworks */,
113 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */,
114 | );
115 | buildRules = (
116 | );
117 | dependencies = (
118 | );
119 | name = Runner;
120 | productName = Runner;
121 | productReference = 97C146EE1CF9000F007C117D /* Runner.app */;
122 | productType = "com.apple.product-type.application";
123 | };
124 | /* End PBXNativeTarget section */
125 |
126 | /* Begin PBXProject section */
127 | 97C146E61CF9000F007C117D /* Project object */ = {
128 | isa = PBXProject;
129 | attributes = {
130 | LastUpgradeCheck = 1020;
131 | ORGANIZATIONNAME = "";
132 | TargetAttributes = {
133 | 97C146ED1CF9000F007C117D = {
134 | CreatedOnToolsVersion = 7.3.1;
135 | LastSwiftMigration = 1100;
136 | };
137 | };
138 | };
139 | buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */;
140 | compatibilityVersion = "Xcode 9.3";
141 | developmentRegion = en;
142 | hasScannedForEncodings = 0;
143 | knownRegions = (
144 | en,
145 | Base,
146 | );
147 | mainGroup = 97C146E51CF9000F007C117D;
148 | productRefGroup = 97C146EF1CF9000F007C117D /* Products */;
149 | projectDirPath = "";
150 | projectRoot = "";
151 | targets = (
152 | 97C146ED1CF9000F007C117D /* Runner */,
153 | );
154 | };
155 | /* End PBXProject section */
156 |
157 | /* Begin PBXResourcesBuildPhase section */
158 | 97C146EC1CF9000F007C117D /* Resources */ = {
159 | isa = PBXResourcesBuildPhase;
160 | buildActionMask = 2147483647;
161 | files = (
162 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */,
163 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */,
164 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */,
165 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */,
166 | );
167 | runOnlyForDeploymentPostprocessing = 0;
168 | };
169 | /* End PBXResourcesBuildPhase section */
170 |
171 | /* Begin PBXShellScriptBuildPhase section */
172 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {
173 | isa = PBXShellScriptBuildPhase;
174 | buildActionMask = 2147483647;
175 | files = (
176 | );
177 | inputPaths = (
178 | );
179 | name = "Thin Binary";
180 | outputPaths = (
181 | );
182 | runOnlyForDeploymentPostprocessing = 0;
183 | shellPath = /bin/sh;
184 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin";
185 | };
186 | 9740EEB61CF901F6004384FC /* Run Script */ = {
187 | isa = PBXShellScriptBuildPhase;
188 | buildActionMask = 2147483647;
189 | files = (
190 | );
191 | inputPaths = (
192 | );
193 | name = "Run Script";
194 | outputPaths = (
195 | );
196 | runOnlyForDeploymentPostprocessing = 0;
197 | shellPath = /bin/sh;
198 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build";
199 | };
200 | /* End PBXShellScriptBuildPhase section */
201 |
202 | /* Begin PBXSourcesBuildPhase section */
203 | 97C146EA1CF9000F007C117D /* Sources */ = {
204 | isa = PBXSourcesBuildPhase;
205 | buildActionMask = 2147483647;
206 | files = (
207 | 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */,
208 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */,
209 | );
210 | runOnlyForDeploymentPostprocessing = 0;
211 | };
212 | /* End PBXSourcesBuildPhase section */
213 |
214 | /* Begin PBXVariantGroup section */
215 | 97C146FA1CF9000F007C117D /* Main.storyboard */ = {
216 | isa = PBXVariantGroup;
217 | children = (
218 | 97C146FB1CF9000F007C117D /* Base */,
219 | );
220 | name = Main.storyboard;
221 | sourceTree = "";
222 | };
223 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = {
224 | isa = PBXVariantGroup;
225 | children = (
226 | 97C147001CF9000F007C117D /* Base */,
227 | );
228 | name = LaunchScreen.storyboard;
229 | sourceTree = "";
230 | };
231 | /* End PBXVariantGroup section */
232 |
233 | /* Begin XCBuildConfiguration section */
234 | 249021D3217E4FDB00AE95B9 /* Profile */ = {
235 | isa = XCBuildConfiguration;
236 | buildSettings = {
237 | ALWAYS_SEARCH_USER_PATHS = NO;
238 | CLANG_ANALYZER_NONNULL = YES;
239 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
240 | CLANG_CXX_LIBRARY = "libc++";
241 | CLANG_ENABLE_MODULES = YES;
242 | CLANG_ENABLE_OBJC_ARC = YES;
243 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
244 | CLANG_WARN_BOOL_CONVERSION = YES;
245 | CLANG_WARN_COMMA = YES;
246 | CLANG_WARN_CONSTANT_CONVERSION = YES;
247 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
248 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
249 | CLANG_WARN_EMPTY_BODY = YES;
250 | CLANG_WARN_ENUM_CONVERSION = YES;
251 | CLANG_WARN_INFINITE_RECURSION = YES;
252 | CLANG_WARN_INT_CONVERSION = YES;
253 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
254 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
255 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
256 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
257 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
258 | CLANG_WARN_STRICT_PROTOTYPES = YES;
259 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
260 | CLANG_WARN_UNREACHABLE_CODE = YES;
261 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
262 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
263 | COPY_PHASE_STRIP = NO;
264 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
265 | ENABLE_NS_ASSERTIONS = NO;
266 | ENABLE_STRICT_OBJC_MSGSEND = YES;
267 | GCC_C_LANGUAGE_STANDARD = gnu99;
268 | GCC_NO_COMMON_BLOCKS = YES;
269 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
270 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
271 | GCC_WARN_UNDECLARED_SELECTOR = YES;
272 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
273 | GCC_WARN_UNUSED_FUNCTION = YES;
274 | GCC_WARN_UNUSED_VARIABLE = YES;
275 | IPHONEOS_DEPLOYMENT_TARGET = 9.0;
276 | MTL_ENABLE_DEBUG_INFO = NO;
277 | SDKROOT = iphoneos;
278 | SUPPORTED_PLATFORMS = iphoneos;
279 | TARGETED_DEVICE_FAMILY = "1,2";
280 | VALIDATE_PRODUCT = YES;
281 | };
282 | name = Profile;
283 | };
284 | 249021D4217E4FDB00AE95B9 /* Profile */ = {
285 | isa = XCBuildConfiguration;
286 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
287 | buildSettings = {
288 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
289 | CLANG_ENABLE_MODULES = YES;
290 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
291 | ENABLE_BITCODE = NO;
292 | INFOPLIST_FILE = Runner/Info.plist;
293 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
294 | PRODUCT_BUNDLE_IDENTIFIER = ws.diye.scrcpyFlutter;
295 | PRODUCT_NAME = "$(TARGET_NAME)";
296 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
297 | SWIFT_VERSION = 5.0;
298 | VERSIONING_SYSTEM = "apple-generic";
299 | };
300 | name = Profile;
301 | };
302 | 97C147031CF9000F007C117D /* Debug */ = {
303 | isa = XCBuildConfiguration;
304 | buildSettings = {
305 | ALWAYS_SEARCH_USER_PATHS = NO;
306 | CLANG_ANALYZER_NONNULL = YES;
307 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
308 | CLANG_CXX_LIBRARY = "libc++";
309 | CLANG_ENABLE_MODULES = YES;
310 | CLANG_ENABLE_OBJC_ARC = YES;
311 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
312 | CLANG_WARN_BOOL_CONVERSION = YES;
313 | CLANG_WARN_COMMA = YES;
314 | CLANG_WARN_CONSTANT_CONVERSION = YES;
315 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
316 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
317 | CLANG_WARN_EMPTY_BODY = YES;
318 | CLANG_WARN_ENUM_CONVERSION = YES;
319 | CLANG_WARN_INFINITE_RECURSION = YES;
320 | CLANG_WARN_INT_CONVERSION = YES;
321 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
322 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
323 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
324 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
325 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
326 | CLANG_WARN_STRICT_PROTOTYPES = YES;
327 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
328 | CLANG_WARN_UNREACHABLE_CODE = YES;
329 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
330 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
331 | COPY_PHASE_STRIP = NO;
332 | DEBUG_INFORMATION_FORMAT = dwarf;
333 | ENABLE_STRICT_OBJC_MSGSEND = YES;
334 | ENABLE_TESTABILITY = YES;
335 | GCC_C_LANGUAGE_STANDARD = gnu99;
336 | GCC_DYNAMIC_NO_PIC = NO;
337 | GCC_NO_COMMON_BLOCKS = YES;
338 | GCC_OPTIMIZATION_LEVEL = 0;
339 | GCC_PREPROCESSOR_DEFINITIONS = (
340 | "DEBUG=1",
341 | "$(inherited)",
342 | );
343 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
344 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
345 | GCC_WARN_UNDECLARED_SELECTOR = YES;
346 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
347 | GCC_WARN_UNUSED_FUNCTION = YES;
348 | GCC_WARN_UNUSED_VARIABLE = YES;
349 | IPHONEOS_DEPLOYMENT_TARGET = 9.0;
350 | MTL_ENABLE_DEBUG_INFO = YES;
351 | ONLY_ACTIVE_ARCH = YES;
352 | SDKROOT = iphoneos;
353 | TARGETED_DEVICE_FAMILY = "1,2";
354 | };
355 | name = Debug;
356 | };
357 | 97C147041CF9000F007C117D /* Release */ = {
358 | isa = XCBuildConfiguration;
359 | buildSettings = {
360 | ALWAYS_SEARCH_USER_PATHS = NO;
361 | CLANG_ANALYZER_NONNULL = YES;
362 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
363 | CLANG_CXX_LIBRARY = "libc++";
364 | CLANG_ENABLE_MODULES = YES;
365 | CLANG_ENABLE_OBJC_ARC = YES;
366 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
367 | CLANG_WARN_BOOL_CONVERSION = YES;
368 | CLANG_WARN_COMMA = YES;
369 | CLANG_WARN_CONSTANT_CONVERSION = YES;
370 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
371 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
372 | CLANG_WARN_EMPTY_BODY = YES;
373 | CLANG_WARN_ENUM_CONVERSION = YES;
374 | CLANG_WARN_INFINITE_RECURSION = YES;
375 | CLANG_WARN_INT_CONVERSION = YES;
376 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
377 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
378 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
379 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
380 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
381 | CLANG_WARN_STRICT_PROTOTYPES = YES;
382 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
383 | CLANG_WARN_UNREACHABLE_CODE = YES;
384 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
385 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
386 | COPY_PHASE_STRIP = NO;
387 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
388 | ENABLE_NS_ASSERTIONS = NO;
389 | ENABLE_STRICT_OBJC_MSGSEND = YES;
390 | GCC_C_LANGUAGE_STANDARD = gnu99;
391 | GCC_NO_COMMON_BLOCKS = YES;
392 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
393 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
394 | GCC_WARN_UNDECLARED_SELECTOR = YES;
395 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
396 | GCC_WARN_UNUSED_FUNCTION = YES;
397 | GCC_WARN_UNUSED_VARIABLE = YES;
398 | IPHONEOS_DEPLOYMENT_TARGET = 9.0;
399 | MTL_ENABLE_DEBUG_INFO = NO;
400 | SDKROOT = iphoneos;
401 | SUPPORTED_PLATFORMS = iphoneos;
402 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
403 | TARGETED_DEVICE_FAMILY = "1,2";
404 | VALIDATE_PRODUCT = YES;
405 | };
406 | name = Release;
407 | };
408 | 97C147061CF9000F007C117D /* Debug */ = {
409 | isa = XCBuildConfiguration;
410 | baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
411 | buildSettings = {
412 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
413 | CLANG_ENABLE_MODULES = YES;
414 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
415 | ENABLE_BITCODE = NO;
416 | INFOPLIST_FILE = Runner/Info.plist;
417 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
418 | PRODUCT_BUNDLE_IDENTIFIER = ws.diye.scrcpyFlutter;
419 | PRODUCT_NAME = "$(TARGET_NAME)";
420 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
421 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
422 | SWIFT_VERSION = 5.0;
423 | VERSIONING_SYSTEM = "apple-generic";
424 | };
425 | name = Debug;
426 | };
427 | 97C147071CF9000F007C117D /* Release */ = {
428 | isa = XCBuildConfiguration;
429 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
430 | buildSettings = {
431 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
432 | CLANG_ENABLE_MODULES = YES;
433 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
434 | ENABLE_BITCODE = NO;
435 | INFOPLIST_FILE = Runner/Info.plist;
436 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
437 | PRODUCT_BUNDLE_IDENTIFIER = ws.diye.scrcpyFlutter;
438 | PRODUCT_NAME = "$(TARGET_NAME)";
439 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
440 | SWIFT_VERSION = 5.0;
441 | VERSIONING_SYSTEM = "apple-generic";
442 | };
443 | name = Release;
444 | };
445 | /* End XCBuildConfiguration section */
446 |
447 | /* Begin XCConfigurationList section */
448 | 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = {
449 | isa = XCConfigurationList;
450 | buildConfigurations = (
451 | 97C147031CF9000F007C117D /* Debug */,
452 | 97C147041CF9000F007C117D /* Release */,
453 | 249021D3217E4FDB00AE95B9 /* Profile */,
454 | );
455 | defaultConfigurationIsVisible = 0;
456 | defaultConfigurationName = Release;
457 | };
458 | 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = {
459 | isa = XCConfigurationList;
460 | buildConfigurations = (
461 | 97C147061CF9000F007C117D /* Debug */,
462 | 97C147071CF9000F007C117D /* Release */,
463 | 249021D4217E4FDB00AE95B9 /* Profile */,
464 | );
465 | defaultConfigurationIsVisible = 0;
466 | defaultConfigurationName = Release;
467 | };
468 | /* End XCConfigurationList section */
469 | };
470 | rootObject = 97C146E61CF9000F007C117D /* Project object */;
471 | }
472 |
--------------------------------------------------------------------------------
/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | PreviewsEnabled
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
39 |
40 |
41 |
42 |
43 |
44 |
54 |
56 |
62 |
63 |
64 |
65 |
66 |
67 |
73 |
75 |
81 |
82 |
83 |
84 |
86 |
87 |
90 |
91 |
92 |
--------------------------------------------------------------------------------
/ios/Runner.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | PreviewsEnabled
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ios/Runner/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | import UIKit
2 | import Flutter
3 |
4 | @UIApplicationMain
5 | @objc class AppDelegate: FlutterAppDelegate {
6 | override func application(
7 | _ application: UIApplication,
8 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
9 | ) -> Bool {
10 | GeneratedPluginRegistrant.register(with: self)
11 | return super.application(application, didFinishLaunchingWithOptions: launchOptions)
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "size" : "20x20",
5 | "idiom" : "iphone",
6 | "filename" : "Icon-App-20x20@2x.png",
7 | "scale" : "2x"
8 | },
9 | {
10 | "size" : "20x20",
11 | "idiom" : "iphone",
12 | "filename" : "Icon-App-20x20@3x.png",
13 | "scale" : "3x"
14 | },
15 | {
16 | "size" : "29x29",
17 | "idiom" : "iphone",
18 | "filename" : "Icon-App-29x29@1x.png",
19 | "scale" : "1x"
20 | },
21 | {
22 | "size" : "29x29",
23 | "idiom" : "iphone",
24 | "filename" : "Icon-App-29x29@2x.png",
25 | "scale" : "2x"
26 | },
27 | {
28 | "size" : "29x29",
29 | "idiom" : "iphone",
30 | "filename" : "Icon-App-29x29@3x.png",
31 | "scale" : "3x"
32 | },
33 | {
34 | "size" : "40x40",
35 | "idiom" : "iphone",
36 | "filename" : "Icon-App-40x40@2x.png",
37 | "scale" : "2x"
38 | },
39 | {
40 | "size" : "40x40",
41 | "idiom" : "iphone",
42 | "filename" : "Icon-App-40x40@3x.png",
43 | "scale" : "3x"
44 | },
45 | {
46 | "size" : "60x60",
47 | "idiom" : "iphone",
48 | "filename" : "Icon-App-60x60@2x.png",
49 | "scale" : "2x"
50 | },
51 | {
52 | "size" : "60x60",
53 | "idiom" : "iphone",
54 | "filename" : "Icon-App-60x60@3x.png",
55 | "scale" : "3x"
56 | },
57 | {
58 | "size" : "20x20",
59 | "idiom" : "ipad",
60 | "filename" : "Icon-App-20x20@1x.png",
61 | "scale" : "1x"
62 | },
63 | {
64 | "size" : "20x20",
65 | "idiom" : "ipad",
66 | "filename" : "Icon-App-20x20@2x.png",
67 | "scale" : "2x"
68 | },
69 | {
70 | "size" : "29x29",
71 | "idiom" : "ipad",
72 | "filename" : "Icon-App-29x29@1x.png",
73 | "scale" : "1x"
74 | },
75 | {
76 | "size" : "29x29",
77 | "idiom" : "ipad",
78 | "filename" : "Icon-App-29x29@2x.png",
79 | "scale" : "2x"
80 | },
81 | {
82 | "size" : "40x40",
83 | "idiom" : "ipad",
84 | "filename" : "Icon-App-40x40@1x.png",
85 | "scale" : "1x"
86 | },
87 | {
88 | "size" : "40x40",
89 | "idiom" : "ipad",
90 | "filename" : "Icon-App-40x40@2x.png",
91 | "scale" : "2x"
92 | },
93 | {
94 | "size" : "76x76",
95 | "idiom" : "ipad",
96 | "filename" : "Icon-App-76x76@1x.png",
97 | "scale" : "1x"
98 | },
99 | {
100 | "size" : "76x76",
101 | "idiom" : "ipad",
102 | "filename" : "Icon-App-76x76@2x.png",
103 | "scale" : "2x"
104 | },
105 | {
106 | "size" : "83.5x83.5",
107 | "idiom" : "ipad",
108 | "filename" : "Icon-App-83.5x83.5@2x.png",
109 | "scale" : "2x"
110 | },
111 | {
112 | "size" : "1024x1024",
113 | "idiom" : "ios-marketing",
114 | "filename" : "Icon-App-1024x1024@1x.png",
115 | "scale" : "1x"
116 | }
117 | ],
118 | "info" : {
119 | "version" : 1,
120 | "author" : "xcode"
121 | }
122 | }
123 |
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/diyews/scrcpy-flutter/8eeda96c67c1ab5addf5cf5121a0a6601aa2c32c/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/diyews/scrcpy-flutter/8eeda96c67c1ab5addf5cf5121a0a6601aa2c32c/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/diyews/scrcpy-flutter/8eeda96c67c1ab5addf5cf5121a0a6601aa2c32c/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/diyews/scrcpy-flutter/8eeda96c67c1ab5addf5cf5121a0a6601aa2c32c/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/diyews/scrcpy-flutter/8eeda96c67c1ab5addf5cf5121a0a6601aa2c32c/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/diyews/scrcpy-flutter/8eeda96c67c1ab5addf5cf5121a0a6601aa2c32c/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/diyews/scrcpy-flutter/8eeda96c67c1ab5addf5cf5121a0a6601aa2c32c/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/diyews/scrcpy-flutter/8eeda96c67c1ab5addf5cf5121a0a6601aa2c32c/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/diyews/scrcpy-flutter/8eeda96c67c1ab5addf5cf5121a0a6601aa2c32c/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/diyews/scrcpy-flutter/8eeda96c67c1ab5addf5cf5121a0a6601aa2c32c/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/diyews/scrcpy-flutter/8eeda96c67c1ab5addf5cf5121a0a6601aa2c32c/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/diyews/scrcpy-flutter/8eeda96c67c1ab5addf5cf5121a0a6601aa2c32c/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/diyews/scrcpy-flutter/8eeda96c67c1ab5addf5cf5121a0a6601aa2c32c/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/diyews/scrcpy-flutter/8eeda96c67c1ab5addf5cf5121a0a6601aa2c32c/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/diyews/scrcpy-flutter/8eeda96c67c1ab5addf5cf5121a0a6601aa2c32c/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "LaunchImage.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "LaunchImage@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "LaunchImage@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/diyews/scrcpy-flutter/8eeda96c67c1ab5addf5cf5121a0a6601aa2c32c/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/diyews/scrcpy-flutter/8eeda96c67c1ab5addf5cf5121a0a6601aa2c32c/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/diyews/scrcpy-flutter/8eeda96c67c1ab5addf5cf5121a0a6601aa2c32c/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md:
--------------------------------------------------------------------------------
1 | # Launch Screen Assets
2 |
3 | You can customize the launch screen with your own desired assets by replacing the image files in this directory.
4 |
5 | You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images.
--------------------------------------------------------------------------------
/ios/Runner/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/ios/Runner/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/ios/Runner/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | scrcpy_flutter
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | $(FLUTTER_BUILD_NAME)
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | $(FLUTTER_BUILD_NUMBER)
23 | LSRequiresIPhoneOS
24 |
25 | UILaunchStoryboardName
26 | LaunchScreen
27 | UIMainStoryboardFile
28 | Main
29 | UISupportedInterfaceOrientations
30 |
31 | UIInterfaceOrientationPortrait
32 | UIInterfaceOrientationLandscapeLeft
33 | UIInterfaceOrientationLandscapeRight
34 |
35 | UISupportedInterfaceOrientations~ipad
36 |
37 | UIInterfaceOrientationPortrait
38 | UIInterfaceOrientationPortraitUpsideDown
39 | UIInterfaceOrientationLandscapeLeft
40 | UIInterfaceOrientationLandscapeRight
41 |
42 | UIViewControllerBasedStatusBarAppearance
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/ios/Runner/Runner-Bridging-Header.h:
--------------------------------------------------------------------------------
1 | #import "GeneratedPluginRegistrant.h"
2 |
--------------------------------------------------------------------------------
/lib/android_keycode.dart:
--------------------------------------------------------------------------------
1 | /**
2 | * Key codes.
3 | */
4 | class AndroidKeycode {
5 | /** Unknown key code. */
6 | static const int AKEYCODE_UNKNOWN = 0;
7 |
8 | /** Soft Left key.
9 | * Usually situated below the display on phones and used as a multi-function
10 | * feature key for selecting a software defined function shown on the bottom left
11 | * of the display. */
12 | static const int AKEYCODE_SOFT_LEFT = 1;
13 |
14 | /** Soft Right key.
15 | * Usually situated below the display on phones and used as a multi-function
16 | * feature key for selecting a software defined function shown on the bottom right
17 | * of the display. */
18 | static const int AKEYCODE_SOFT_RIGHT = 2;
19 |
20 | /** Home key.
21 | * This key is handled by the framework and is never delivered to applications. */
22 | static const int AKEYCODE_HOME = 3;
23 |
24 | /** Back key. */
25 | static const int AKEYCODE_BACK = 4;
26 |
27 | /** Call key. */
28 | static const int AKEYCODE_CALL = 5;
29 |
30 | /** End Call key. */
31 | static const int AKEYCODE_ENDCALL = 6;
32 |
33 | /** '0' key. */
34 | static const int AKEYCODE_0 = 7;
35 |
36 | /** '1' key. */
37 | static const int AKEYCODE_1 = 8;
38 |
39 | /** '2' key. */
40 | static const int AKEYCODE_2 = 9;
41 |
42 | /** '3' key. */
43 | static const int AKEYCODE_3 = 10;
44 |
45 | /** '4' key. */
46 | static const int AKEYCODE_4 = 11;
47 |
48 | /** '5' key. */
49 | static const int AKEYCODE_5 = 12;
50 |
51 | /** '6' key. */
52 | static const int AKEYCODE_6 = 13;
53 |
54 | /** '7' key. */
55 | static const int AKEYCODE_7 = 14;
56 |
57 | /** '8' key. */
58 | static const int AKEYCODE_8 = 15;
59 |
60 | /** '9' key. */
61 | static const int AKEYCODE_9 = 16;
62 |
63 | /** '*' key. */
64 | static const int AKEYCODE_STAR = 17;
65 |
66 | /** '#' key. */
67 | static const int AKEYCODE_POUND = 18;
68 |
69 | /** Directional Pad Up key.
70 | * May also be synthesized from trackball motions. */
71 | static const int AKEYCODE_DPAD_UP = 19;
72 |
73 | /** Directional Pad Down key.
74 | * May also be synthesized from trackball motions. */
75 | static const int AKEYCODE_DPAD_DOWN = 20;
76 |
77 | /** Directional Pad Left key.
78 | * May also be synthesized from trackball motions. */
79 | static const int AKEYCODE_DPAD_LEFT = 21;
80 |
81 | /** Directional Pad Right key.
82 | * May also be synthesized from trackball motions. */
83 | static const int AKEYCODE_DPAD_RIGHT = 22;
84 |
85 | /** Directional Pad Center key.
86 | * May also be synthesized from trackball motions. */
87 | static const int AKEYCODE_DPAD_CENTER = 23;
88 |
89 | /** Volume Up key.
90 | * Adjusts the speaker volume up. */
91 | static const int AKEYCODE_VOLUME_UP = 24;
92 |
93 | /** Volume Down key.
94 | * Adjusts the speaker volume down. */
95 | static const int AKEYCODE_VOLUME_DOWN = 25;
96 |
97 | /** Power key. */
98 | static const int AKEYCODE_POWER = 26;
99 |
100 | /** Camera key.
101 | * Used to launch a camera application or take pictures. */
102 | static const int AKEYCODE_CAMERA = 27;
103 |
104 | /** Clear key. */
105 | static const int AKEYCODE_CLEAR = 28;
106 |
107 | /** 'A' key. */
108 | static const int AKEYCODE_A = 29;
109 |
110 | /** 'B' key. */
111 | static const int AKEYCODE_B = 30;
112 |
113 | /** 'C' key. */
114 | static const int AKEYCODE_C = 31;
115 |
116 | /** 'D' key. */
117 | static const int AKEYCODE_D = 32;
118 |
119 | /** 'E' key. */
120 | static const int AKEYCODE_E = 33;
121 |
122 | /** 'F' key. */
123 | static const int AKEYCODE_F = 34;
124 |
125 | /** 'G' key. */
126 | static const int AKEYCODE_G = 35;
127 |
128 | /** 'H' key. */
129 | static const int AKEYCODE_H = 36;
130 |
131 | /** 'I' key. */
132 | static const int AKEYCODE_I = 37;
133 |
134 | /** 'J' key. */
135 | static const int AKEYCODE_J = 38;
136 |
137 | /** 'K' key. */
138 | static const int AKEYCODE_K = 39;
139 |
140 | /** 'L' key. */
141 | static const int AKEYCODE_L = 40;
142 |
143 | /** 'M' key. */
144 | static const int AKEYCODE_M = 41;
145 |
146 | /** 'N' key. */
147 | static const int AKEYCODE_N = 42;
148 |
149 | /** 'O' key. */
150 | static const int AKEYCODE_O = 43;
151 |
152 | /** 'P' key. */
153 | static const int AKEYCODE_P = 44;
154 |
155 | /** 'Q' key. */
156 | static const int AKEYCODE_Q = 45;
157 |
158 | /** 'R' key. */
159 | static const int AKEYCODE_R = 46;
160 |
161 | /** 'S' key. */
162 | static const int AKEYCODE_S = 47;
163 |
164 | /** 'T' key. */
165 | static const int AKEYCODE_T = 48;
166 |
167 | /** 'U' key. */
168 | static const int AKEYCODE_U = 49;
169 |
170 | /** 'V' key. */
171 | static const int AKEYCODE_V = 50;
172 |
173 | /** 'W' key. */
174 | static const int AKEYCODE_W = 51;
175 |
176 | /** 'X' key. */
177 | static const int AKEYCODE_X = 52;
178 |
179 | /** 'Y' key. */
180 | static const int AKEYCODE_Y = 53;
181 |
182 | /** 'Z' key. */
183 | static const int AKEYCODE_Z = 54;
184 |
185 | /** ',' key. */
186 | static const int AKEYCODE_COMMA = 55;
187 |
188 | /** '.' key. */
189 | static const int AKEYCODE_PERIOD = 56;
190 |
191 | /** Left Alt modifier key. */
192 | static const int AKEYCODE_ALT_LEFT = 57;
193 |
194 | /** Right Alt modifier key. */
195 | static const int AKEYCODE_ALT_RIGHT = 58;
196 |
197 | /** Left Shift modifier key. */
198 | static const int AKEYCODE_SHIFT_LEFT = 59;
199 |
200 | /** Right Shift modifier key. */
201 | static const int AKEYCODE_SHIFT_RIGHT = 60;
202 |
203 | /** Tab key. */
204 | static const int AKEYCODE_TAB = 61;
205 |
206 | /** Space key. */
207 | static const int AKEYCODE_SPACE = 62;
208 |
209 | /** Symbol modifier key.
210 | * Used to enter alternate symbols. */
211 | static const int AKEYCODE_SYM = 63;
212 |
213 | /** Explorer special function key.
214 | * Used to launch a browser application. */
215 | static const int AKEYCODE_EXPLORER = 64;
216 |
217 | /** Envelope special function key.
218 | * Used to launch a mail application. */
219 | static const int AKEYCODE_ENVELOPE = 65;
220 |
221 | /** Enter key. */
222 | static const int AKEYCODE_ENTER = 66;
223 |
224 | /** Backspace key.
225 | * Deletes characters before the insertion point, unlike {@link AKEYCODE_FORWARD_DEL}. */
226 | static const int AKEYCODE_DEL = 67;
227 |
228 | /** '`' (backtick) key. */
229 | static const int AKEYCODE_GRAVE = 68;
230 |
231 | /** '-'. */
232 | static const int AKEYCODE_MINUS = 69;
233 |
234 | /** '=' key. */
235 | static const int AKEYCODE_EQUALS = 70;
236 |
237 | /** '[' key. */
238 | static const int AKEYCODE_LEFT_BRACKET = 71;
239 |
240 | /** ']' key. */
241 | static const int AKEYCODE_RIGHT_BRACKET = 72;
242 |
243 | /** '\' key. */
244 | static const int AKEYCODE_BACKSLASH = 73;
245 |
246 | /** ';' key. */
247 | static const int AKEYCODE_SEMICOLON = 74;
248 |
249 | /** ''' (apostrophe) key. */
250 | static const int AKEYCODE_APOSTROPHE = 75;
251 |
252 | /** '/' key. */
253 | static const int AKEYCODE_SLASH = 76;
254 |
255 | /** '@' key. */
256 | static const int AKEYCODE_AT = 77;
257 |
258 | /** Number modifier key.
259 | * Used to enter numeric symbols.
260 | * This key is not {@link AKEYCODE_NUM_LOCK}; it is more like {@link AKEYCODE_ALT_LEFT}. */
261 | static const int AKEYCODE_NUM = 78;
262 |
263 | /** Headset Hook key.
264 | * Used to hang up calls and stop media. */
265 | static const int AKEYCODE_HEADSETHOOK = 79;
266 |
267 | /** Camera Focus key.
268 | * Used to focus the camera. */
269 | static const int AKEYCODE_FOCUS = 80;
270 |
271 | /** '+' key. */
272 | static const int AKEYCODE_PLUS = 81;
273 |
274 | /** Menu key. */
275 | static const int AKEYCODE_MENU = 82;
276 |
277 | /** Notification key. */
278 | static const int AKEYCODE_NOTIFICATION = 83;
279 |
280 | /** Search key. */
281 | static const int AKEYCODE_SEARCH = 84;
282 |
283 | /** Play/Pause media key. */
284 | static const int AKEYCODE_MEDIA_PLAY_PAUSE = 85;
285 |
286 | /** Stop media key. */
287 | static const int AKEYCODE_MEDIA_STOP = 86;
288 |
289 | /** Play Next media key. */
290 | static const int AKEYCODE_MEDIA_NEXT = 87;
291 |
292 | /** Play Previous media key. */
293 | static const int AKEYCODE_MEDIA_PREVIOUS = 88;
294 |
295 | /** Rewind media key. */
296 | static const int AKEYCODE_MEDIA_REWIND = 89;
297 |
298 | /** Fast Forward media key. */
299 | static const int AKEYCODE_MEDIA_FAST_FORWARD = 90;
300 |
301 | /** Mute key.
302 | * Mutes the microphone, unlike {@link AKEYCODE_VOLUME_MUTE}. */
303 | static const int AKEYCODE_MUTE = 91;
304 |
305 | /** Page Up key. */
306 | static const int AKEYCODE_PAGE_UP = 92;
307 |
308 | /** Page Down key. */
309 | static const int AKEYCODE_PAGE_DOWN = 93;
310 |
311 | /** Picture Symbols modifier key.
312 | * Used to switch symbol sets (Emoji, Kao-moji). */
313 | static const int AKEYCODE_PICTSYMBOLS = 94;
314 |
315 | /** Switch Charset modifier key.
316 | * Used to switch character sets (Kanji, Katakana). */
317 | static const int AKEYCODE_SWITCH_CHARSET = 95;
318 |
319 | /** A Button key.
320 | * On a game controller, the A button should be either the button labeled A
321 | * or the first button on the bottom row of controller buttons. */
322 | static const int AKEYCODE_BUTTON_A = 96;
323 |
324 | /** B Button key.
325 | * On a game controller, the B button should be either the button labeled B
326 | * or the second button on the bottom row of controller buttons. */
327 | static const int AKEYCODE_BUTTON_B = 97;
328 |
329 | /** C Button key.
330 | * On a game controller, the C button should be either the button labeled C
331 | * or the third button on the bottom row of controller buttons. */
332 | static const int AKEYCODE_BUTTON_C = 98;
333 |
334 | /** X Button key.
335 | * On a game controller, the X button should be either the button labeled X
336 | * or the first button on the upper row of controller buttons. */
337 | static const int AKEYCODE_BUTTON_X = 99;
338 |
339 | /** Y Button key.
340 | * On a game controller, the Y button should be either the button labeled Y
341 | * or the second button on the upper row of controller buttons. */
342 | static const int AKEYCODE_BUTTON_Y = 100;
343 |
344 | /** Z Button key.
345 | * On a game controller, the Z button should be either the button labeled Z
346 | * or the third button on the upper row of controller buttons. */
347 | static const int AKEYCODE_BUTTON_Z = 101;
348 |
349 | /** L1 Button key.
350 | * On a game controller, the L1 button should be either the button labeled L1 (or L)
351 | * or the top left trigger button. */
352 | static const int AKEYCODE_BUTTON_L1 = 102;
353 |
354 | /** R1 Button key.
355 | * On a game controller, the R1 button should be either the button labeled R1 (or R)
356 | * or the top right trigger button. */
357 | static const int AKEYCODE_BUTTON_R1 = 103;
358 |
359 | /** L2 Button key.
360 | * On a game controller, the L2 button should be either the button labeled L2
361 | * or the bottom left trigger button. */
362 | static const int AKEYCODE_BUTTON_L2 = 104;
363 |
364 | /** R2 Button key.
365 | * On a game controller, the R2 button should be either the button labeled R2
366 | * or the bottom right trigger button. */
367 | static const int AKEYCODE_BUTTON_R2 = 105;
368 |
369 | /** Left Thumb Button key.
370 | * On a game controller, the left thumb button indicates that the left (or only)
371 | * joystick is pressed. */
372 | static const int AKEYCODE_BUTTON_THUMBL = 106;
373 |
374 | /** Right Thumb Button key.
375 | * On a game controller, the right thumb button indicates that the right
376 | * joystick is pressed. */
377 | static const int AKEYCODE_BUTTON_THUMBR = 107;
378 |
379 | /** Start Button key.
380 | * On a game controller, the button labeled Start. */
381 | static const int AKEYCODE_BUTTON_START = 108;
382 |
383 | /** Select Button key.
384 | * On a game controller, the button labeled Select. */
385 | static const int AKEYCODE_BUTTON_SELECT = 109;
386 |
387 | /** Mode Button key.
388 | * On a game controller, the button labeled Mode. */
389 | static const int AKEYCODE_BUTTON_MODE = 110;
390 |
391 | /** Escape key. */
392 | static const int AKEYCODE_ESCAPE = 111;
393 |
394 | /** Forward Delete key.
395 | * Deletes characters ahead of the insertion point, unlike {@link AKEYCODE_DEL}. */
396 | static const int AKEYCODE_FORWARD_DEL = 112;
397 |
398 | /** Left Control modifier key. */
399 | static const int AKEYCODE_CTRL_LEFT = 113;
400 |
401 | /** Right Control modifier key. */
402 | static const int AKEYCODE_CTRL_RIGHT = 114;
403 |
404 | /** Caps Lock key. */
405 | static const int AKEYCODE_CAPS_LOCK = 115;
406 |
407 | /** Scroll Lock key. */
408 | static const int AKEYCODE_SCROLL_LOCK = 116;
409 |
410 | /** Left Meta modifier key. */
411 | static const int AKEYCODE_META_LEFT = 117;
412 |
413 | /** Right Meta modifier key. */
414 | static const int AKEYCODE_META_RIGHT = 118;
415 |
416 | /** Function modifier key. */
417 | static const int AKEYCODE_FUNCTION = 119;
418 |
419 | /** System Request / Print Screen key. */
420 | static const int AKEYCODE_SYSRQ = 120;
421 |
422 | /** Break / Pause key. */
423 | static const int AKEYCODE_BREAK = 121;
424 |
425 | /** Home Movement key.
426 | * Used for scrolling or moving the cursor around to the start of a line
427 | * or to the top of a list. */
428 | static const int AKEYCODE_MOVE_HOME = 122;
429 |
430 | /** End Movement key.
431 | * Used for scrolling or moving the cursor around to the end of a line
432 | * or to the bottom of a list. */
433 | static const int AKEYCODE_MOVE_END = 123;
434 |
435 | /** Insert key.
436 | * Toggles insert / overwrite edit mode. */
437 | static const int AKEYCODE_INSERT = 124;
438 |
439 | /** Forward key.
440 | * Navigates forward in the history stack. Complement of {@link AKEYCODE_BACK}. */
441 | static const int AKEYCODE_FORWARD = 125;
442 |
443 | /** Play media key. */
444 | static const int AKEYCODE_MEDIA_PLAY = 126;
445 |
446 | /** Pause media key. */
447 | static const int AKEYCODE_MEDIA_PAUSE = 127;
448 |
449 | /** Close media key.
450 | * May be used to close a CD tray, for example. */
451 | static const int AKEYCODE_MEDIA_CLOSE = 128;
452 |
453 | /** Eject media key.
454 | * May be used to eject a CD tray, for example. */
455 | static const int AKEYCODE_MEDIA_EJECT = 129;
456 |
457 | /** Record media key. */
458 | static const int AKEYCODE_MEDIA_RECORD = 130;
459 |
460 | /** F1 key. */
461 | static const int AKEYCODE_F1 = 131;
462 |
463 | /** F2 key. */
464 | static const int AKEYCODE_F2 = 132;
465 |
466 | /** F3 key. */
467 | static const int AKEYCODE_F3 = 133;
468 |
469 | /** F4 key. */
470 | static const int AKEYCODE_F4 = 134;
471 |
472 | /** F5 key. */
473 | static const int AKEYCODE_F5 = 135;
474 |
475 | /** F6 key. */
476 | static const int AKEYCODE_F6 = 136;
477 |
478 | /** F7 key. */
479 | static const int AKEYCODE_F7 = 137;
480 |
481 | /** F8 key. */
482 | static const int AKEYCODE_F8 = 138;
483 |
484 | /** F9 key. */
485 | static const int AKEYCODE_F9 = 139;
486 |
487 | /** F10 key. */
488 | static const int AKEYCODE_F10 = 140;
489 |
490 | /** F11 key. */
491 | static const int AKEYCODE_F11 = 141;
492 |
493 | /** F12 key. */
494 | static const int AKEYCODE_F12 = 142;
495 |
496 | /** Num Lock key.
497 | * This is the Num Lock key; it is different from {@link AKEYCODE_NUM}.
498 | * This key alters the behavior of other keys on the numeric keypad. */
499 | static const int AKEYCODE_NUM_LOCK = 143;
500 |
501 | /** Numeric keypad '0' key. */
502 | static const int AKEYCODE_NUMPAD_0 = 144;
503 |
504 | /** Numeric keypad '1' key. */
505 | static const int AKEYCODE_NUMPAD_1 = 145;
506 |
507 | /** Numeric keypad '2' key. */
508 | static const int AKEYCODE_NUMPAD_2 = 146;
509 |
510 | /** Numeric keypad '3' key. */
511 | static const int AKEYCODE_NUMPAD_3 = 147;
512 |
513 | /** Numeric keypad '4' key. */
514 | static const int AKEYCODE_NUMPAD_4 = 148;
515 |
516 | /** Numeric keypad '5' key. */
517 | static const int AKEYCODE_NUMPAD_5 = 149;
518 |
519 | /** Numeric keypad '6' key. */
520 | static const int AKEYCODE_NUMPAD_6 = 150;
521 |
522 | /** Numeric keypad '7' key. */
523 | static const int AKEYCODE_NUMPAD_7 = 151;
524 |
525 | /** Numeric keypad '8' key. */
526 | static const int AKEYCODE_NUMPAD_8 = 152;
527 |
528 | /** Numeric keypad '9' key. */
529 | static const int AKEYCODE_NUMPAD_9 = 153;
530 |
531 | /** Numeric keypad '/' key (for division). */
532 | static const int AKEYCODE_NUMPAD_DIVIDE = 154;
533 |
534 | /** Numeric keypad '*' key (for multiplication). */
535 | static const int AKEYCODE_NUMPAD_MULTIPLY = 155;
536 |
537 | /** Numeric keypad '-' key (for subtraction). */
538 | static const int AKEYCODE_NUMPAD_SUBTRACT = 156;
539 |
540 | /** Numeric keypad '+' key (for addition). */
541 | static const int AKEYCODE_NUMPAD_ADD = 157;
542 |
543 | /** Numeric keypad '.' key (for decimals or digit grouping). */
544 | static const int AKEYCODE_NUMPAD_DOT = 158;
545 |
546 | /** Numeric keypad ',' key (for decimals or digit grouping). */
547 | static const int AKEYCODE_NUMPAD_COMMA = 159;
548 |
549 | /** Numeric keypad Enter key. */
550 | static const int AKEYCODE_NUMPAD_ENTER = 160;
551 |
552 | /** Numeric keypad '=' key. */
553 | static const int AKEYCODE_NUMPAD_EQUALS = 161;
554 |
555 | /** Numeric keypad '(' key. */
556 | static const int AKEYCODE_NUMPAD_LEFT_PAREN = 162;
557 |
558 | /** Numeric keypad ')' key. */
559 | static const int AKEYCODE_NUMPAD_RIGHT_PAREN = 163;
560 |
561 | /** Volume Mute key.
562 | * Mutes the speaker, unlike {@link AKEYCODE_MUTE}.
563 | * This key should normally be implemented as a toggle such that the first press
564 | * mutes the speaker and the second press restores the original volume. */
565 | static const int AKEYCODE_VOLUME_MUTE = 164;
566 |
567 | /** Info key.
568 | * Common on TV remotes to show additional information related to what is
569 | * currently being viewed. */
570 | static const int AKEYCODE_INFO = 165;
571 |
572 | /** Channel up key.
573 | * On TV remotes, increments the television channel. */
574 | static const int AKEYCODE_CHANNEL_UP = 166;
575 |
576 | /** Channel down key.
577 | * On TV remotes, decrements the television channel. */
578 | static const int AKEYCODE_CHANNEL_DOWN = 167;
579 |
580 | /** Zoom in key. */
581 | static const int AKEYCODE_ZOOM_IN = 168;
582 |
583 | /** Zoom out key. */
584 | static const int AKEYCODE_ZOOM_OUT = 169;
585 |
586 | /** TV key.
587 | * On TV remotes, switches to viewing live TV. */
588 | static const int AKEYCODE_TV = 170;
589 |
590 | /** Window key.
591 | * On TV remotes, toggles picture-in-picture mode or other windowing functions. */
592 | static const int AKEYCODE_WINDOW = 171;
593 |
594 | /** Guide key.
595 | * On TV remotes, shows a programming guide. */
596 | static const int AKEYCODE_GUIDE = 172;
597 |
598 | /** DVR key.
599 | * On some TV remotes, switches to a DVR mode for recorded shows. */
600 | static const int AKEYCODE_DVR = 173;
601 |
602 | /** Bookmark key.
603 | * On some TV remotes, bookmarks content or web pages. */
604 | static const int AKEYCODE_BOOKMARK = 174;
605 |
606 | /** Toggle captions key.
607 | * Switches the mode for closed-captioning text, for example during television shows. */
608 | static const int AKEYCODE_CAPTIONS = 175;
609 |
610 | /** Settings key.
611 | * Starts the system settings activity. */
612 | static const int AKEYCODE_SETTINGS = 176;
613 |
614 | /** TV power key.
615 | * On TV remotes, toggles the power on a television screen. */
616 | static const int AKEYCODE_TV_POWER = 177;
617 |
618 | /** TV input key.
619 | * On TV remotes, switches the input on a television screen. */
620 | static const int AKEYCODE_TV_INPUT = 178;
621 |
622 | /** Set-top-box power key.
623 | * On TV remotes, toggles the power on an external Set-top-box. */
624 | static const int AKEYCODE_STB_POWER = 179;
625 |
626 | /** Set-top-box input key.
627 | * On TV remotes, switches the input mode on an external Set-top-box. */
628 | static const int AKEYCODE_STB_INPUT = 180;
629 |
630 | /** A/V Receiver power key.
631 | * On TV remotes, toggles the power on an external A/V Receiver. */
632 | static const int AKEYCODE_AVR_POWER = 181;
633 |
634 | /** A/V Receiver input key.
635 | * On TV remotes, switches the input mode on an external A/V Receiver. */
636 | static const int AKEYCODE_AVR_INPUT = 182;
637 |
638 | /** Red "programmable" key.
639 | * On TV remotes, acts as a contextual/programmable key. */
640 | static const int AKEYCODE_PROG_RED = 183;
641 |
642 | /** Green "programmable" key.
643 | * On TV remotes, actsas a contextual/programmable key. */
644 | static const int AKEYCODE_PROG_GREEN = 184;
645 |
646 | /** Yellow "programmable" key.
647 | * On TV remotes, acts as a contextual/programmable key. */
648 | static const int AKEYCODE_PROG_YELLOW = 185;
649 |
650 | /** Blue "programmable" key.
651 | * On TV remotes, acts as a contextual/programmable key. */
652 | static const int AKEYCODE_PROG_BLUE = 186;
653 |
654 | /** App switch key.
655 | * Should bring up the application switcher dialog. */
656 | static const int AKEYCODE_APP_SWITCH = 187;
657 |
658 | /** Generic Game Pad Button #1.*/
659 | static const int AKEYCODE_BUTTON_1 = 188;
660 |
661 | /** Generic Game Pad Button #2.*/
662 | static const int AKEYCODE_BUTTON_2 = 189;
663 |
664 | /** Generic Game Pad Button #3.*/
665 | static const int AKEYCODE_BUTTON_3 = 190;
666 |
667 | /** Generic Game Pad Button #4.*/
668 | static const int AKEYCODE_BUTTON_4 = 191;
669 |
670 | /** Generic Game Pad Button #5.*/
671 | static const int AKEYCODE_BUTTON_5 = 192;
672 |
673 | /** Generic Game Pad Button #6.*/
674 | static const int AKEYCODE_BUTTON_6 = 193;
675 |
676 | /** Generic Game Pad Button #7.*/
677 | static const int AKEYCODE_BUTTON_7 = 194;
678 |
679 | /** Generic Game Pad Button #8.*/
680 | static const int AKEYCODE_BUTTON_8 = 195;
681 |
682 | /** Generic Game Pad Button #9.*/
683 | static const int AKEYCODE_BUTTON_9 = 196;
684 |
685 | /** Generic Game Pad Button #10.*/
686 | static const int AKEYCODE_BUTTON_10 = 197;
687 |
688 | /** Generic Game Pad Button #11.*/
689 | static const int AKEYCODE_BUTTON_11 = 198;
690 |
691 | /** Generic Game Pad Button #12.*/
692 | static const int AKEYCODE_BUTTON_12 = 199;
693 |
694 | /** Generic Game Pad Button #13.*/
695 | static const int AKEYCODE_BUTTON_13 = 200;
696 |
697 | /** Generic Game Pad Button #14.*/
698 | static const int AKEYCODE_BUTTON_14 = 201;
699 |
700 | /** Generic Game Pad Button #15.*/
701 | static const int AKEYCODE_BUTTON_15 = 202;
702 |
703 | /** Generic Game Pad Button #16.*/
704 | static const int AKEYCODE_BUTTON_16 = 203;
705 |
706 | /** Language Switch key.
707 | * Toggles the current input language such as switching between English and Japanese on
708 | * a QWERTY keyboard. On some devices, the same function may be performed by
709 | * pressing Shift+Spacebar. */
710 | static const int AKEYCODE_LANGUAGE_SWITCH = 204;
711 |
712 | /** Manner Mode key.
713 | * Toggles silent or vibrate mode on and off to make the device behave more politely
714 | * in certain settings such as on a crowded train. On some devices, the key may only
715 | * operate when long-pressed. */
716 | static const int AKEYCODE_MANNER_MODE = 205;
717 |
718 | /** 3D Mode key.
719 | * Toggles the display between 2D and 3D mode. */
720 | static const int AKEYCODE_3D_MODE = 206;
721 |
722 | /** Contacts special function key.
723 | * Used to launch an address book application. */
724 | static const int AKEYCODE_CONTACTS = 207;
725 |
726 | /** Calendar special function key.
727 | * Used to launch a calendar application. */
728 | static const int AKEYCODE_CALENDAR = 208;
729 |
730 | /** Music special function key.
731 | * Used to launch a music player application. */
732 | static const int AKEYCODE_MUSIC = 209;
733 |
734 | /** Calculator special function key.
735 | * Used to launch a calculator application. */
736 | static const int AKEYCODE_CALCULATOR = 210;
737 |
738 | /** Japanese full-width / half-width key. */
739 | static const int AKEYCODE_ZENKAKU_HANKAKU = 211;
740 |
741 | /** Japanese alphanumeric key. */
742 | static const int AKEYCODE_EISU = 212;
743 |
744 | /** Japanese non-conversion key. */
745 | static const int AKEYCODE_MUHENKAN = 213;
746 |
747 | /** Japanese conversion key. */
748 | static const int AKEYCODE_HENKAN = 214;
749 |
750 | /** Japanese katakana / hiragana key. */
751 | static const int AKEYCODE_KATAKANA_HIRAGANA = 215;
752 |
753 | /** Japanese Yen key. */
754 | static const int AKEYCODE_YEN = 216;
755 |
756 | /** Japanese Ro key. */
757 | static const int AKEYCODE_RO = 217;
758 |
759 | /** Japanese kana key. */
760 | static const int AKEYCODE_KANA = 218;
761 |
762 | /** Assist key.
763 | * Launches the global assist activity. Not delivered to applications. */
764 | static const int AKEYCODE_ASSIST = 219;
765 |
766 | /** Brightness Down key.
767 | * Adjusts the screen brightness down. */
768 | static const int AKEYCODE_BRIGHTNESS_DOWN = 220;
769 |
770 | /** Brightness Up key.
771 | * Adjusts the screen brightness up. */
772 | static const int AKEYCODE_BRIGHTNESS_UP = 221;
773 |
774 | /** Audio Track key.
775 | * Switches the audio tracks. */
776 | static const int AKEYCODE_MEDIA_AUDIO_TRACK = 222;
777 |
778 | /** Sleep key.
779 | * Puts the device to sleep. Behaves somewhat like {@link AKEYCODE_POWER} but it
780 | * has no effect if the device is already asleep. */
781 | static const int AKEYCODE_SLEEP = 223;
782 |
783 | /** Wakeup key.
784 | * Wakes up the device. Behaves somewhat like {@link AKEYCODE_POWER} but it
785 | * has no effect if the device is already awake. */
786 | static const int AKEYCODE_WAKEUP = 224;
787 |
788 | /** Pairing key.
789 | * Initiates peripheral pairing mode. Useful for pairing remote control
790 | * devices or game controllers, especially if no other input mode is
791 | * available. */
792 | static const int AKEYCODE_PAIRING = 225;
793 |
794 | /** Media Top Menu key.
795 | * Goes to the top of media menu. */
796 | static const int AKEYCODE_MEDIA_TOP_MENU = 226;
797 |
798 | /** '11' key. */
799 | static const int AKEYCODE_11 = 227;
800 |
801 | /** '12' key. */
802 | static const int AKEYCODE_12 = 228;
803 |
804 | /** Last Channel key.
805 | * Goes to the last viewed channel. */
806 | static const int AKEYCODE_LAST_CHANNEL = 229;
807 |
808 | /** TV data service key.
809 | * Displays data services like weather, sports. */
810 | static const int AKEYCODE_TV_DATA_SERVICE = 230;
811 |
812 | /** Voice Assist key.
813 | * Launches the global voice assist activity. Not delivered to applications. */
814 | static const int AKEYCODE_VOICE_ASSIST = 231;
815 |
816 | /** Radio key.
817 | * Toggles TV service / Radio service. */
818 | static const int AKEYCODE_TV_RADIO_SERVICE = 232;
819 |
820 | /** Teletext key.
821 | * Displays Teletext service. */
822 | static const int AKEYCODE_TV_TELETEXT = 233;
823 |
824 | /** Number entry key.
825 | * Initiates to enter multi-digit channel nubmber when each digit key is assigned
826 | * for selecting separate channel. Corresponds to Number Entry Mode (0x1D) of CEC
827 | * User Control Code. */
828 | static const int AKEYCODE_TV_NUMBER_ENTRY = 234;
829 |
830 | /** Analog Terrestrial key.
831 | * Switches to analog terrestrial broadcast service. */
832 | static const int AKEYCODE_TV_TERRESTRIAL_ANALOG = 235;
833 |
834 | /** Digital Terrestrial key.
835 | * Switches to digital terrestrial broadcast service. */
836 | static const int AKEYCODE_TV_TERRESTRIAL_DIGITAL = 236;
837 |
838 | /** Satellite key.
839 | * Switches to digital satellite broadcast service. */
840 | static const int AKEYCODE_TV_SATELLITE = 237;
841 |
842 | /** BS key.
843 | * Switches to BS digital satellite broadcasting service available in Japan. */
844 | static const int AKEYCODE_TV_SATELLITE_BS = 238;
845 |
846 | /** CS key.
847 | * Switches to CS digital satellite broadcasting service available in Japan. */
848 | static const int AKEYCODE_TV_SATELLITE_CS = 239;
849 |
850 | /** BS/CS key.
851 | * Toggles between BS and CS digital satellite services. */
852 | static const int AKEYCODE_TV_SATELLITE_SERVICE = 240;
853 |
854 | /** Toggle Network key.
855 | * Toggles selecting broacast services. */
856 | static const int AKEYCODE_TV_NETWORK = 241;
857 |
858 | /** Antenna/Cable key.
859 | * Toggles broadcast input source between antenna and cable. */
860 | static const int AKEYCODE_TV_ANTENNA_CABLE = 242;
861 |
862 | /** HDMI #1 key.
863 | * Switches to HDMI input #1. */
864 | static const int AKEYCODE_TV_INPUT_HDMI_1 = 243;
865 |
866 | /** HDMI #2 key.
867 | * Switches to HDMI input #2. */
868 | static const int AKEYCODE_TV_INPUT_HDMI_2 = 244;
869 |
870 | /** HDMI #3 key.
871 | * Switches to HDMI input #3. */
872 | static const int AKEYCODE_TV_INPUT_HDMI_3 = 245;
873 |
874 | /** HDMI #4 key.
875 | * Switches to HDMI input #4. */
876 | static const int AKEYCODE_TV_INPUT_HDMI_4 = 246;
877 |
878 | /** Composite #1 key.
879 | * Switches to composite video input #1. */
880 | static const int AKEYCODE_TV_INPUT_COMPOSITE_1 = 247;
881 |
882 | /** Composite #2 key.
883 | * Switches to composite video input #2. */
884 | static const int AKEYCODE_TV_INPUT_COMPOSITE_2 = 248;
885 |
886 | /** Component #1 key.
887 | * Switches to component video input #1. */
888 | static const int AKEYCODE_TV_INPUT_COMPONENT_1 = 249;
889 |
890 | /** Component #2 key.
891 | * Switches to component video input #2. */
892 | static const int AKEYCODE_TV_INPUT_COMPONENT_2 = 250;
893 |
894 | /** VGA #1 key.
895 | * Switches to VGA (analog RGB) input #1. */
896 | static const int AKEYCODE_TV_INPUT_VGA_1 = 251;
897 |
898 | /** Audio description key.
899 | * Toggles audio description off / on. */
900 | static const int AKEYCODE_TV_AUDIO_DESCRIPTION = 252;
901 |
902 | /** Audio description mixing volume up key.
903 | * Louden audio description volume as compared with normal audio volume. */
904 | static const int AKEYCODE_TV_AUDIO_DESCRIPTION_MIX_UP = 253;
905 |
906 | /** Audio description mixing volume down key.
907 | * Lessen audio description volume as compared with normal audio volume. */
908 | static const int AKEYCODE_TV_AUDIO_DESCRIPTION_MIX_DOWN = 254;
909 |
910 | /** Zoom mode key.
911 | * Changes Zoom mode (Normal, Full, Zoom, Wide-zoom, etc.) */
912 | static const int AKEYCODE_TV_ZOOM_MODE = 255;
913 |
914 | /** Contents menu key.
915 | * Goes to the title list. Corresponds to Contents Menu (0x0B) of CEC User Control
916 | * Code */
917 | static const int AKEYCODE_TV_CONTENTS_MENU = 256;
918 |
919 | /** Media context menu key.
920 | * Goes to the context menu of media contents. Corresponds to Media Context-sensitive
921 | * Menu (0x11) of CEC User Control Code. */
922 | static const int AKEYCODE_TV_MEDIA_CONTEXT_MENU = 257;
923 |
924 | /** Timer programming key.
925 | * Goes to the timer recording menu. Corresponds to Timer Programming (0x54) of
926 | * CEC User Control Code. */
927 | static const int AKEYCODE_TV_TIMER_PROGRAMMING = 258;
928 |
929 | /** Help key. */
930 | static const int AKEYCODE_HELP = 259;
931 | static const int AKEYCODE_NAVIGATE_PREVIOUS = 260;
932 | static const int AKEYCODE_NAVIGATE_NEXT = 261;
933 | static const int AKEYCODE_NAVIGATE_IN = 262;
934 | static const int AKEYCODE_NAVIGATE_OUT = 263;
935 |
936 | /** Primary stem key for Wear
937 | * Main power/reset button on watch. */
938 | static const int AKEYCODE_STEM_PRIMARY = 264;
939 |
940 | /** Generic stem key 1 for Wear */
941 | static const int AKEYCODE_STEM_1 = 265;
942 |
943 | /** Generic stem key 2 for Wear */
944 | static const int AKEYCODE_STEM_2 = 266;
945 |
946 | /** Generic stem key 3 for Wear */
947 | static const int AKEYCODE_STEM_3 = 267;
948 |
949 | /** Directional Pad Up-Left */
950 | static const int AKEYCODE_DPAD_UP_LEFT = 268;
951 |
952 | /** Directional Pad Down-Left */
953 | static const int AKEYCODE_DPAD_DOWN_LEFT = 269;
954 |
955 | /** Directional Pad Up-Right */
956 | static const int AKEYCODE_DPAD_UP_RIGHT = 270;
957 |
958 | /** Directional Pad Down-Right */
959 | static const int AKEYCODE_DPAD_DOWN_RIGHT = 271;
960 |
961 | /** Skip forward media key */
962 | static const int AKEYCODE_MEDIA_SKIP_FORWARD = 272;
963 |
964 | /** Skip backward media key */
965 | static const int AKEYCODE_MEDIA_SKIP_BACKWARD = 273;
966 |
967 | /** Step forward media key.
968 | * Steps media forward one from at a time. */
969 | static const int AKEYCODE_MEDIA_STEP_FORWARD = 274;
970 |
971 | /** Step backward media key.
972 | * Steps media backward one from at a time. */
973 | static const int AKEYCODE_MEDIA_STEP_BACKWARD = 275;
974 |
975 | /** Put device to sleep unless a wakelock is held. */
976 | static const int AKEYCODE_SOFT_SLEEP = 276;
977 |
978 | /** Cut key. */
979 | static const int AKEYCODE_CUT = 277;
980 |
981 | /** Copy key. */
982 | static const int AKEYCODE_COPY = 278;
983 |
984 | /** Paste key. */
985 | static const int AKEYCODE_PASTE = 279;
986 |
987 | /** fingerprint navigation key, up. */
988 | static const int AKEYCODE_SYSTEM_NAVIGATION_UP = 280;
989 |
990 | /** fingerprint navigation key, down. */
991 | static const int AKEYCODE_SYSTEM_NAVIGATION_DOWN = 281;
992 |
993 | /** fingerprint navigation key, left. */
994 | static const int AKEYCODE_SYSTEM_NAVIGATION_LEFT = 282;
995 |
996 | /** fingerprint navigation key, right. */
997 | static const int AKEYCODE_SYSTEM_NAVIGATION_RIGHT = 283;
998 |
999 | /** all apps */
1000 | static const int AKEYCODE_ALL_APPS = 284;
1001 | }
1002 |
--------------------------------------------------------------------------------
/lib/cbc_cipher.dart:
--------------------------------------------------------------------------------
1 | import 'dart:isolate';
2 | import 'dart:typed_data';
3 |
4 | import 'package:pointycastle/export.dart' hide State;
5 | import 'package:shared_preferences/shared_preferences.dart';
6 |
7 | class CBCCipher {
8 | static Uint8List aesKey = Uint8List(0);
9 |
10 | static void setAESKey(Uint8List key, [bool isSync = true]) {
11 | aesKey = key;
12 | if (isSync) {
13 | CBCCipherIsolate.syncKey();
14 | }
15 | }
16 |
17 | static Future initKey() async {
18 | final prefs = await SharedPreferences.getInstance();
19 | final key = prefs.getString('encrypt_key') ?? '';
20 | if (key.isNotEmpty) {
21 | setAESKey(Uint8List.fromList(key.codeUnits));
22 | }
23 | }
24 |
25 | static Future initIsolate() async {
26 | final receivePort = ReceivePort();
27 | await Isolate.spawn(_handler, receivePort.sendPort);
28 | final sendPort = await receivePort.first;
29 | CBCCipherIsolate.initSendPort(sendPort);
30 | await CBCCipherIsolate.syncKey();
31 | }
32 |
33 | static Uint8List processBodyBytes(Uint8List bodyBytes) {
34 | final iv = Uint8List.sublistView(bodyBytes, 0, aesKey.length);
35 | final cipherText = Uint8List.sublistView(bodyBytes, aesKey.length);
36 |
37 | final cbc = CBCBlockCipher(AESFastEngine())
38 | ..init(false, ParametersWithIV(KeyParameter(aesKey), iv));
39 |
40 | final paddedPlainText = Uint8List(cipherText.length);
41 |
42 | /* decrypt take 100ms(cold), 50ms(medium), 15-30ms(hot) */
43 | var offset = 0;
44 | while (offset < cipherText.length) {
45 | offset += cbc.processBlock(cipherText, offset, paddedPlainText, offset);
46 | }
47 |
48 | return Uint8List.sublistView(
49 | paddedPlainText, 0, paddedPlainText.length - paddedPlainText.last);
50 | }
51 | }
52 |
53 | class CBCCipherIsolate {
54 | static SendPort? _sendPort;
55 |
56 | static initSendPort(SendPort sendPort) {
57 | _sendPort = sendPort;
58 | }
59 |
60 | static Future syncKey() {
61 | return _send(_sendPort!, {'type': 'update_key', 'data': CBCCipher.aesKey});
62 | }
63 |
64 | static Future processBodyBytesIsolate(Uint8List bodyBytes) {
65 | return _send(_sendPort!, {'type': 'decrypt', 'data': bodyBytes});
66 | }
67 | }
68 |
69 | Future _send(SendPort port, msg) {
70 | final response = ReceivePort();
71 | port.send([msg, response.sendPort]);
72 | return response.first;
73 | }
74 |
75 | Future _handler(SendPort sendPort) async {
76 | final port = ReceivePort();
77 | sendPort.send(port.sendPort);
78 |
79 | await for (var msg in port) {
80 | final request = msg[0];
81 | SendPort replyTo = msg[1];
82 |
83 | switch (request['type']) {
84 | case 'update_key':
85 | CBCCipher.setAESKey(request['data'], false);
86 | replyTo.send('Done');
87 | break;
88 | case 'decrypt':
89 | final decrypted = CBCCipher.processBodyBytes(request['data']);
90 | replyTo.send(decrypted);
91 | break;
92 | case 'test':
93 | replyTo.send('Done');
94 | break;
95 | default:
96 | replyTo.send('Done');
97 | }
98 | }
99 | }
100 |
--------------------------------------------------------------------------------
/lib/debug_control.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/cupertino.dart';
2 | import 'package:flutter/material.dart';
3 | import 'package:flutter/services.dart';
4 |
5 | class DebugControl extends StatefulWidget {
6 | const DebugControl({Key? key}) : super(key: key);
7 |
8 | @override
9 | _DebugControlState createState() => _DebugControlState();
10 | }
11 |
12 | class _DebugControlState extends State {
13 | static const platform = MethodChannel('samples.flutter.dev/battery');
14 |
15 | int _counter = 0;
16 |
17 | void _incrementCounter() {
18 | setState(() {
19 | // This call to setState tells the Flutter framework that something has
20 | // changed in this State, which causes it to rerun the build method below
21 | // so that the display can reflect the updated values. If we changed
22 | // _counter without calling setState(), then the build method would not be
23 | // called again, and so nothing would appear to happen.
24 | _counter++;
25 | });
26 | }
27 |
28 | @override
29 | Widget build(BuildContext context) {
30 | final double devicePixelRatio = MediaQuery.of(context).devicePixelRatio;
31 |
32 | return Scaffold(
33 | body: GestureDetector(
34 | behavior: HitTestBehavior.opaque,
35 | onTapUp: (details) {
36 | print(details.globalPosition.dx * devicePixelRatio);
37 | print(details.globalPosition.dy * devicePixelRatio);
38 | platform.invokeMethod('tapEvent').then((value) {
39 | print(value);
40 | });
41 | },
42 | child: Center(
43 | // Center is a layout widget. It takes a single child and positions it
44 | // in the middle of the parent.
45 | child: Column(
46 | // Column is also a layout widget. It takes a list of children and
47 | // arranges them vertically. By default, it sizes itself to fit its
48 | // children horizontally, and tries to be as tall as its parent.
49 | //
50 | // Invoke "debug painting" (press "p" in the console, choose the
51 | // "Toggle Debug Paint" action from the Flutter Inspector in Android
52 | // Studio, or the "Toggle Debug Paint" command in Visual Studio Code)
53 | // to see the wireframe for each widget.
54 | //
55 | // Column has various properties to control how it sizes itself and
56 | // how it positions its children. Here we use mainAxisAlignment to
57 | // center the children vertically; the main axis here is the vertical
58 | // axis because Columns are vertical (the cross axis would be
59 | // horizontal).
60 | mainAxisAlignment: MainAxisAlignment.center,
61 | children: [
62 | Text(
63 | '$_counter',
64 | style: Theme.of(context).textTheme.headline4,
65 | ),
66 | ],
67 | ),
68 | ),
69 | ),
70 | floatingActionButton: FloatingActionButton(
71 | onPressed: _incrementCounter,
72 | tooltip: 'Increment',
73 | child: const Icon(Icons.add),
74 | ), // This trailing comma makes auto-formatting nicer for build methods.
75 | );
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/lib/device_list.dart:
--------------------------------------------------------------------------------
1 | import 'dart:convert';
2 |
3 | import 'package:flutter/material.dart';
4 | import 'package:http/http.dart' as http;
5 | import 'package:scrcpy_flutter/cbc_cipher.dart';
6 | import 'package:scrcpy_flutter/scrcpy.dart';
7 | import 'package:shared_preferences/shared_preferences.dart';
8 |
9 | class DeviceList extends StatefulWidget {
10 | const DeviceList({Key? key, required this.refreshNotifier}) : super(key: key);
11 | final ChangeNotifier refreshNotifier;
12 |
13 | @override
14 | _DeviceListState createState() => _DeviceListState();
15 | }
16 |
17 | class _DeviceListState extends State {
18 | List<_DeviceWidget> _deviceWidgetList = [];
19 | SharedPreferences? prefs;
20 |
21 | @override
22 | void initState() {
23 | super.initState();
24 |
25 | SharedPreferences.getInstance().then((prefs) {
26 | this.prefs = prefs;
27 | final devicesStr = prefs.getString('queried_devices') ?? '';
28 | if (devicesStr.isEmpty) {
29 | batchQueryWrapped();
30 | } else if (CBCCipher.aesKey.isNotEmpty) {
31 | _deviceWidgetList.addAll(_DeviceWidget.jsonStringToList(devicesStr));
32 | }
33 |
34 | /* clear and refresh */
35 | widget.refreshNotifier.addListener(() async {
36 | _deviceWidgetList = [];
37 | prefs.remove('queried_devices');
38 | batchQueryWrapped();
39 | });
40 | });
41 | }
42 |
43 | batchQueryWrapped() {
44 | if (CBCCipher.aesKey.isNotEmpty) {
45 | batchQuery();
46 | }
47 | }
48 |
49 | batchQuery() {
50 | final List prefixList = ['192.168.0', '192.168.1'];
51 |
52 | for (var element in prefixList) {
53 | for (var i = 1; i < 255; ++i) {
54 | query('$element.$i');
55 | }
56 | }
57 | }
58 |
59 | query(String ip) async {
60 | try {
61 | final res = await http.get(Uri.parse('http://$ip:7008/huinyegrbizgn'));
62 | final bytes = CBCCipher.processBodyBytes(res.bodyBytes);
63 | final name = String.fromCharCodes(bytes);
64 | setState(() {
65 | _deviceWidgetList.add(_DeviceWidget(ip: ip, name: name));
66 | });
67 | prefs!.setString(
68 | 'queried_devices', _DeviceWidget.listToJsonString(_deviceWidgetList));
69 | } catch (e) {
70 | /* ignore */
71 | }
72 | }
73 |
74 | @override
75 | Widget build(BuildContext context) {
76 | return CBCCipher.aesKey.isNotEmpty
77 | ? GridView.count(
78 | crossAxisCount: 2,
79 | padding: const EdgeInsets.all(10),
80 | mainAxisSpacing: 10,
81 | crossAxisSpacing: 10,
82 | children: _deviceWidgetList,
83 | )
84 | : const Center(
85 | child: Text('Please set key'),
86 | );
87 | }
88 | }
89 |
90 | class _DeviceWidget extends StatefulWidget {
91 | final String name;
92 | final String ip;
93 |
94 | const _DeviceWidget({Key? key, required this.ip, this.name = ''})
95 | : super(key: key);
96 |
97 | static String listToJsonString(List<_DeviceWidget> list) {
98 | return jsonEncode(list.map((e) => {"ip": e.ip, "name": e.name}).toList());
99 | }
100 |
101 | static List<_DeviceWidget> jsonStringToList(String str) {
102 | return (jsonDecode(str) as List)
103 | .map((e) => _DeviceWidget(
104 | ip: e['ip']!,
105 | name: e['name']!,
106 | ))
107 | .toList();
108 | }
109 |
110 | @override
111 | _DeviceWidgetState createState() => _DeviceWidgetState();
112 | }
113 |
114 | class _DeviceWidgetState extends State<_DeviceWidget> {
115 | @override
116 | Widget build(BuildContext context) {
117 | return InkWell(
118 | onTap: () {
119 | Navigator.of(context).push(MaterialPageRoute(
120 | builder: (_) => Scrcpy(
121 | ip: widget.ip,
122 | )));
123 | },
124 | child: Container(
125 | alignment: Alignment.center,
126 | decoration: const BoxDecoration(color: Colors.black26),
127 | child: Column(
128 | mainAxisAlignment: MainAxisAlignment.center,
129 | children: [
130 | Text(widget.name),
131 | const SizedBox(
132 | height: 2,
133 | ),
134 | Text(
135 | widget.ip,
136 | style: const TextStyle(color: Colors.black26, fontSize: 12),
137 | ),
138 | ],
139 | )),
140 | );
141 | }
142 | }
143 |
--------------------------------------------------------------------------------
/lib/main.dart:
--------------------------------------------------------------------------------
1 | import 'dart:async';
2 | import 'dart:typed_data';
3 |
4 | import 'package:flutter/material.dart';
5 | import 'package:flutter/services.dart';
6 | import 'package:scrcpy_flutter/cbc_cipher.dart';
7 | import 'package:scrcpy_flutter/device_list.dart';
8 | import 'package:scrcpy_flutter/scrcpy.dart';
9 | import 'package:shared_preferences/shared_preferences.dart';
10 |
11 | void main() async {
12 | WidgetsFlutterBinding.ensureInitialized();
13 | await CBCCipher.initIsolate();
14 | await CBCCipher.initKey();
15 | runApp(const MyApp());
16 | }
17 |
18 | class MyApp extends StatelessWidget {
19 | const MyApp({Key? key}) : super(key: key);
20 |
21 | // This widget is the root of your application.
22 | @override
23 | Widget build(BuildContext context) {
24 | return MaterialApp(
25 | title: 'Scrcpy flutter',
26 | theme: ThemeData(
27 | // This is the theme of your application.
28 | //
29 | // Try running your application with "flutter run". You'll see the
30 | // application has a blue toolbar. Then, without quitting the app, try
31 | // changing the primarySwatch below to Colors.green and then invoke
32 | // "hot reload" (press "r" in the console where you ran "flutter run",
33 | // or simply save your changes to "hot reload" in a Flutter IDE).
34 | // Notice that the counter didn't reset back to zero; the application
35 | // is not restarted.
36 | primarySwatch: Colors.blue,
37 | ),
38 | home: const MyHomePage(),
39 | debugShowCheckedModeBanner: false,
40 | );
41 | }
42 | }
43 |
44 | class MyHomePage extends StatefulWidget {
45 | const MyHomePage({Key? key}) : super(key: key);
46 |
47 | // This widget is the home page of your application. It is stateful, meaning
48 | // that it has a State object (defined below) that contains fields that affect
49 | // how it looks.
50 |
51 | @override
52 | State createState() => _MyHomePageState();
53 | }
54 |
55 | class _MyHomePageState extends State {
56 | SharedPreferences? prefs;
57 | final refreshDeviceNotifier = ChangeNotifier();
58 |
59 | _MyHomePageState() {
60 | SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual, overlays: []);
61 | }
62 |
63 | void _incrementCounter(BuildContext context) async {
64 | prefs ??= await SharedPreferences.getInstance();
65 | String? ip = prefs!.getString('lastDeviceIP');
66 | TextEditingController _controller = TextEditingController()
67 | ..text = (ip ?? '192.168.1.151');
68 | showDialog(
69 | context: context,
70 | builder: (context) {
71 | return AlertDialog(
72 | title: Text('IP'),
73 | titlePadding: const EdgeInsets.symmetric(vertical: 2, horizontal: 8),
74 | contentPadding:
75 | const EdgeInsets.symmetric(vertical: 2, horizontal: 8),
76 | content: TextField(
77 | controller: _controller,
78 | autofocus: true,
79 | ),
80 | actions: [
81 | ElevatedButton(
82 | onPressed: () {
83 | Navigator.of(context).pop(_controller.value.text);
84 | },
85 | child: Text('OK'))
86 | ],
87 | );
88 | },
89 | ).then((val) {
90 | print(val);
91 | if (val == null) return;
92 | prefs!.setString('lastDeviceIP', val);
93 | Navigator.of(context).push(MaterialPageRoute(
94 | builder: (_) => Scrcpy(
95 | ip: val,
96 | )));
97 | });
98 | }
99 |
100 | @override
101 | Widget build(BuildContext context) {
102 | // This method is rerun every time setState is called, for instance as done
103 | // by the _incrementCounter method above.
104 | //
105 | // The Flutter framework has been optimized to make rerunning build methods
106 | // fast, so that you can just rebuild anything that needs updating rather
107 | // than having to individually change instances of widgets.
108 | return Scaffold(
109 | appBar: AppBar(
110 | title: Text('X'),
111 | actions: [
112 | IconButton(
113 | onPressed: () {
114 | refreshDeviceNotifier.notifyListeners();
115 | },
116 | icon: const Icon(Icons.refresh)),
117 | PopupMenuButton(itemBuilder: (_context) {
118 | return [
119 | PopupMenuItem(
120 | child: const Text('Key'),
121 | onTap: () {
122 | Timer.run(() async {
123 | final result = await _openEditEncryptKeyDialog(context);
124 | if (result.isNotEmpty) {
125 | refreshDeviceNotifier.notifyListeners();
126 | }
127 | });
128 | },
129 | )
130 | ];
131 | }),
132 | ],
133 | ),
134 | resizeToAvoidBottomInset: false,
135 | body: Center(
136 | // Center is a layout widget. It takes a single child and positions it
137 | // in the middle of the parent.
138 | child: DeviceList(
139 | refreshNotifier: refreshDeviceNotifier,
140 | ),
141 | ),
142 | floatingActionButton: FloatingActionButton(
143 | onPressed: () => _incrementCounter(context),
144 | tooltip: 'Increment',
145 | child: const Icon(Icons.add),
146 | ), // This trailing comma makes auto-formatting nicer for build methods.
147 | );
148 | }
149 | }
150 |
151 | Future _openEditEncryptKeyDialog(BuildContext context) async {
152 | final prefs = await SharedPreferences.getInstance();
153 | final String key = prefs.getString('encrypt_key') ?? '';
154 |
155 | TextEditingController _controller = TextEditingController()..text = key;
156 |
157 | return showDialog(
158 | context: context,
159 | builder: (context) {
160 | return AlertDialog(
161 | title: const Text('Key(16 length)'),
162 | titlePadding: const EdgeInsets.symmetric(vertical: 2, horizontal: 8),
163 | contentPadding: const EdgeInsets.symmetric(vertical: 2, horizontal: 8),
164 | content: TextField(
165 | controller: _controller,
166 | autofocus: true,
167 | ),
168 | actions: [
169 | ElevatedButton(
170 | onPressed: () {
171 | final text = _controller.text;
172 | prefs.setString('encrypt_key', text);
173 | CBCCipher.setAESKey(Uint8List.fromList(text.codeUnits));
174 | Navigator.of(context).pop(text);
175 | },
176 | child: const Text('OK')),
177 | ],
178 | );
179 | },
180 | ).then((value) {
181 | return value ?? '';
182 | });
183 | }
184 |
--------------------------------------------------------------------------------
/lib/scrcpy.dart:
--------------------------------------------------------------------------------
1 | import 'dart:async';
2 | import 'dart:io';
3 | import 'dart:typed_data';
4 |
5 | import 'package:floatingpanel/floatingpanel.dart';
6 | import 'package:flutter/cupertino.dart';
7 | import 'package:flutter/material.dart';
8 | import 'package:http/http.dart' as http;
9 |
10 | import 'android_keycode.dart';
11 | import 'cbc_cipher.dart';
12 |
13 | class Scrcpy extends StatefulWidget {
14 | final String ip;
15 |
16 | const Scrcpy({Key? key, required this.ip}) : super(key: key);
17 |
18 | @override
19 | _ScrcpyState createState() => _ScrcpyState();
20 | }
21 |
22 | class _ScrcpyState extends _ScrcpySocketState {
23 | final _ScreenShotModel _screenShotModel = _ScreenShotModel();
24 |
25 | @override
26 | void dispose() {
27 | _screenShotModel.dispose();
28 |
29 | super.dispose();
30 | }
31 |
32 | @override
33 | Widget build(BuildContext context) {
34 | final double devicePixelRatio = MediaQuery.of(context).devicePixelRatio;
35 |
36 | return Scaffold(
37 | body: Stack(
38 | children: [
39 | Center(
40 | child: OrientationBuilder(builder: (context, orientation) {
41 | if ((orientation == Orientation.portrait &&
42 | deviceHeight < deviceWidth) ||
43 | (orientation == Orientation.landscape &&
44 | deviceHeight > deviceWidth)) {
45 | final int tmp = deviceHeight;
46 | deviceHeight = deviceWidth;
47 | deviceWidth = tmp;
48 | }
49 | return AspectRatio(
50 | aspectRatio:
51 | deviceWidth == 0 ? 9 / 16 : deviceWidth / deviceHeight,
52 | child: Listener(
53 | behavior: HitTestBehavior.opaque,
54 | onPointerUp: (details) {
55 | sendPointerEvent(details, devicePixelRatio, 1);
56 | },
57 | onPointerMove: (details) {
58 | sendPointerEvent(details, devicePixelRatio, 2);
59 | },
60 | onPointerDown: (details) {
61 | sendPointerEvent(details, devicePixelRatio, 0);
62 | },
63 | child: LayoutBuilder(builder: (context, constraints) {
64 | touchableSize =
65 | Size(constraints.maxWidth, constraints.maxHeight);
66 | if (connected) {
67 | positionScale = deviceHeight /
68 | (touchableSize.height * devicePixelRatio);
69 | }
70 | return Container(
71 | decoration: const BoxDecoration(color: Colors.black26),
72 | child: Stack(
73 | children: [
74 | Center(
75 | child: Text(
76 | centerText,
77 | style: Theme.of(context).textTheme.headline4,
78 | ),
79 | ),
80 | if (CBCCipher.aesKey.isNotEmpty)
81 | _ScreenShot(
82 | 'http://${widget.ip}:7008/ognahaonogna',
83 | screenShotModel: _screenShotModel,
84 | )
85 | ],
86 | ),
87 | );
88 | }),
89 | ),
90 | );
91 | }),
92 | ),
93 | FloatBoxPanel(
94 | positionTop: 50,
95 | size: 50,
96 | backgroundColor: Theme.of(context).colorScheme.primary,
97 | dockType: DockType.inside,
98 | defaultDock: true,
99 | buttons: const [
100 | Icons.arrow_back,
101 | Icons.home,
102 | Icons.menu,
103 | Icons.screenshot,
104 | Icons.video_camera_back_outlined,
105 | Icons.power_settings_new,
106 | ],
107 | onPressed: (int index) {
108 | switch (index) {
109 | case 0:
110 | sendBackEvent();
111 | break;
112 | case 1:
113 | sendKeyEvent(AndroidKeycode.AKEYCODE_HOME);
114 | break;
115 | case 2:
116 | sendKeyEvent(AndroidKeycode.AKEYCODE_APP_SWITCH);
117 | break;
118 | case 3:
119 | _screenShotModel.setMode(_ScreenShotMode.one);
120 | break;
121 | case 4:
122 | _screenShotModel.setMode(_ScreenShotMode.videoLike);
123 | break;
124 | case 5:
125 | sendKeyEvent(AndroidKeycode.AKEYCODE_POWER);
126 | break;
127 | default:
128 | }
129 | },
130 | ),
131 | ],
132 | ),
133 | );
134 | }
135 | }
136 |
137 | abstract class _ScrcpySocketState extends State {
138 | static const int remotePort = 7007;
139 | String get ip => widget.ip;
140 | Socket? videoSocket;
141 | Socket? controlSocket;
142 | String deviceName = '';
143 | int deviceWidth = 0;
144 | int deviceHeight = 0;
145 | bool connected = false;
146 | Size touchableSize = Size.zero;
147 | double positionScale = 0;
148 | String centerText = 'A';
149 |
150 | @override
151 | initState() {
152 | super.initState();
153 |
154 | try {
155 | setupSocket();
156 | } catch (e) {
157 | centerText = 'Connect failed';
158 | }
159 | }
160 |
161 | setupSocket() async {
162 | await Socket.connect(ip, remotePort).then((socket) {
163 | videoSocket = socket;
164 | socket.transform(genVideoStreamTransformer()).listen((event) {
165 | print(event);
166 | });
167 | });
168 | Socket.connect(ip, remotePort).then((socket) {
169 | controlSocket = socket;
170 | socket.listen((event) {
171 | print(event);
172 | });
173 | });
174 | }
175 |
176 | StreamTransformer genVideoStreamTransformer() {
177 | int headCurrentByteCount = 0;
178 |
179 | return StreamTransformer.fromHandlers(
180 | handleData: (data, sink) {
181 | print(data);
182 | sink.add(data);
183 | for (var i = 0; i < data.length; ++i) {
184 | var o = data[i];
185 | // 69 = 1 + 64 + 4
186 | if (++headCurrentByteCount <= 69 && headCurrentByteCount > 1) {
187 | if (headCurrentByteCount <= 65 && o > 0) {
188 | deviceName += String.fromCharCode(o);
189 | }
190 | if (headCurrentByteCount == 66) {
191 | deviceWidth += o << 8;
192 | }
193 | if (headCurrentByteCount == 67) {
194 | deviceWidth += o;
195 | }
196 | if (headCurrentByteCount == 68) {
197 | deviceHeight += o << 8;
198 | }
199 | if (headCurrentByteCount == 69) {
200 | deviceHeight += o;
201 | print(deviceName);
202 | print(deviceWidth);
203 | print(deviceHeight);
204 | connected = true;
205 | centerText = deviceName;
206 | setState(() {});
207 | }
208 | }
209 | }
210 | },
211 | );
212 | }
213 |
214 | sendPointerEvent(PointerEvent details, double devicePixelRatio, int type) {
215 | int x =
216 | (details.localPosition.dx * positionScale * devicePixelRatio).floor();
217 | int y =
218 | (details.localPosition.dy * positionScale * devicePixelRatio).floor();
219 | var bd = BytesBuilder();
220 | bd.addByte(2);
221 | bd.addByte(type);
222 | bd.add(Uint8List(8)..buffer.asByteData().setInt64(0, 1, Endian.big));
223 | bd.add(Uint8List(4)..buffer.asByteData().setInt32(0, x, Endian.big));
224 | bd.add(Uint8List(4)..buffer.asByteData().setInt32(0, y, Endian.big));
225 | bd.add(
226 | Uint8List(2)..buffer.asByteData().setInt16(0, deviceWidth, Endian.big));
227 | bd.add(Uint8List(2)
228 | ..buffer.asByteData().setInt16(0, deviceHeight, Endian.big));
229 | bd.add(
230 | Uint8List(2)..buffer.asByteData().setInt16(0, 255 * 255, Endian.big));
231 | bd.add(Uint8List(4)..buffer.asByteData().setInt32(0, 0, Endian.big));
232 | controlSocket!.add(bd.toBytes());
233 | }
234 |
235 | sendBackEvent() {
236 | var bd = BytesBuilder();
237 | bd.addByte(4);
238 | bd.addByte(0);
239 | bd.addByte(4);
240 | bd.addByte(1);
241 | controlSocket!.add(bd.toBytes());
242 | }
243 |
244 | sendKeyEvent(int keycode) {
245 | var bd = BytesBuilder();
246 | bd.addByte(0);
247 | bd.addByte(0);
248 | bd.add(Uint8List(4)..buffer.asByteData().setInt32(0, keycode, Endian.big));
249 | bd.add(Uint8List(4)..buffer.asByteData().setInt32(0, 0, Endian.big));
250 | bd.add(Uint8List(4)..buffer.asByteData().setInt32(0, 0, Endian.big));
251 |
252 | bd.addByte(0);
253 | bd.addByte(1);
254 | bd.add(Uint8List(4)..buffer.asByteData().setInt32(0, keycode, Endian.big));
255 | bd.add(Uint8List(4)..buffer.asByteData().setInt32(0, 0, Endian.big));
256 | bd.add(Uint8List(4)..buffer.asByteData().setInt32(0, 0, Endian.big));
257 | controlSocket!.add(bd.toBytes());
258 | }
259 |
260 | @override
261 | void dispose() {
262 | super.dispose();
263 |
264 | videoSocket?.destroy();
265 | controlSocket?.destroy();
266 | }
267 | }
268 |
269 | class _ScreenShot extends StatefulWidget {
270 | final String url;
271 | final _ScreenShotModel screenShotModel;
272 |
273 | const _ScreenShot(this.url, {Key? key, required this.screenShotModel})
274 | : super(key: key);
275 |
276 | @override
277 | _ScreenShotState createState() => _ScreenShotState();
278 | }
279 |
280 | class _ScreenShotState extends State<_ScreenShot> {
281 | bool running = false;
282 | late Future imageFuture;
283 | Uint8List imageBytes = Uint8List(0);
284 |
285 | @override
286 | void initState() {
287 | super.initState();
288 | widget.screenShotModel.addListener(() {
289 | requestImage();
290 | });
291 | }
292 |
293 | @override
294 | void dispose() {
295 | super.dispose();
296 | }
297 |
298 | requestImage() async {
299 | if (running) {
300 | return;
301 | }
302 | running = true;
303 | final timestamp = DateTime.now().millisecondsSinceEpoch;
304 | final res = await http.get(Uri.parse('${widget.url}?v=$timestamp'));
305 | if (!mounted) {
306 | running = false;
307 | return;
308 | }
309 | imageBytes = await CBCCipherIsolate.processBodyBytesIsolate(res.bodyBytes);
310 | setState(() {});
311 | running = false;
312 | if (widget.screenShotModel.mode == _ScreenShotMode.one) {
313 | return;
314 | }
315 | return requestImage();
316 | }
317 |
318 | @override
319 | Widget build(BuildContext context) {
320 | return imageBytes.isEmpty
321 | ? Container()
322 | : Image.memory(
323 | imageBytes,
324 | gaplessPlayback: true,
325 | );
326 | }
327 | }
328 |
329 | enum _ScreenShotMode { one, videoLike }
330 |
331 | class _ScreenShotModel extends ChangeNotifier {
332 | _ScreenShotMode mode = _ScreenShotMode.one;
333 |
334 | setMode(_ScreenShotMode v) {
335 | mode = v;
336 | notifyListeners();
337 | }
338 | }
339 |
--------------------------------------------------------------------------------
/pubspec.lock:
--------------------------------------------------------------------------------
1 | # Generated by pub
2 | # See https://dart.dev/tools/pub/glossary#lockfile
3 | packages:
4 | async:
5 | dependency: transitive
6 | description:
7 | name: async
8 | url: "https://pub.flutter-io.cn"
9 | source: hosted
10 | version: "2.8.1"
11 | boolean_selector:
12 | dependency: transitive
13 | description:
14 | name: boolean_selector
15 | url: "https://pub.flutter-io.cn"
16 | source: hosted
17 | version: "2.1.0"
18 | characters:
19 | dependency: transitive
20 | description:
21 | name: characters
22 | url: "https://pub.flutter-io.cn"
23 | source: hosted
24 | version: "1.1.0"
25 | charcode:
26 | dependency: transitive
27 | description:
28 | name: charcode
29 | url: "https://pub.flutter-io.cn"
30 | source: hosted
31 | version: "1.3.1"
32 | clock:
33 | dependency: transitive
34 | description:
35 | name: clock
36 | url: "https://pub.flutter-io.cn"
37 | source: hosted
38 | version: "1.1.0"
39 | collection:
40 | dependency: transitive
41 | description:
42 | name: collection
43 | url: "https://pub.flutter-io.cn"
44 | source: hosted
45 | version: "1.15.0"
46 | convert:
47 | dependency: transitive
48 | description:
49 | name: convert
50 | url: "https://pub.flutter-io.cn"
51 | source: hosted
52 | version: "3.0.1"
53 | cupertino_icons:
54 | dependency: "direct main"
55 | description:
56 | name: cupertino_icons
57 | url: "https://pub.flutter-io.cn"
58 | source: hosted
59 | version: "1.0.3"
60 | fake_async:
61 | dependency: transitive
62 | description:
63 | name: fake_async
64 | url: "https://pub.flutter-io.cn"
65 | source: hosted
66 | version: "1.2.0"
67 | ffi:
68 | dependency: transitive
69 | description:
70 | name: ffi
71 | url: "https://pub.flutter-io.cn"
72 | source: hosted
73 | version: "1.1.2"
74 | file:
75 | dependency: transitive
76 | description:
77 | name: file
78 | url: "https://pub.flutter-io.cn"
79 | source: hosted
80 | version: "6.1.2"
81 | floatingpanel:
82 | dependency: "direct main"
83 | description:
84 | path: "."
85 | ref: a8f7f6a628e2cccc2e902f71969352c737bb1b83
86 | resolved-ref: a8f7f6a628e2cccc2e902f71969352c737bb1b83
87 | url: "https://github.com/diyews/floating_panel.git"
88 | source: git
89 | version: "1.1.3"
90 | flutter:
91 | dependency: "direct main"
92 | description: flutter
93 | source: sdk
94 | version: "0.0.0"
95 | flutter_lints:
96 | dependency: "direct dev"
97 | description:
98 | name: flutter_lints
99 | url: "https://pub.flutter-io.cn"
100 | source: hosted
101 | version: "1.0.4"
102 | flutter_test:
103 | dependency: "direct dev"
104 | description: flutter
105 | source: sdk
106 | version: "0.0.0"
107 | flutter_web_plugins:
108 | dependency: transitive
109 | description: flutter
110 | source: sdk
111 | version: "0.0.0"
112 | http:
113 | dependency: "direct main"
114 | description:
115 | name: http
116 | url: "https://pub.flutter-io.cn"
117 | source: hosted
118 | version: "0.13.4"
119 | http_parser:
120 | dependency: transitive
121 | description:
122 | name: http_parser
123 | url: "https://pub.flutter-io.cn"
124 | source: hosted
125 | version: "4.0.0"
126 | js:
127 | dependency: transitive
128 | description:
129 | name: js
130 | url: "https://pub.flutter-io.cn"
131 | source: hosted
132 | version: "0.6.3"
133 | lints:
134 | dependency: transitive
135 | description:
136 | name: lints
137 | url: "https://pub.flutter-io.cn"
138 | source: hosted
139 | version: "1.0.1"
140 | matcher:
141 | dependency: transitive
142 | description:
143 | name: matcher
144 | url: "https://pub.flutter-io.cn"
145 | source: hosted
146 | version: "0.12.10"
147 | meta:
148 | dependency: transitive
149 | description:
150 | name: meta
151 | url: "https://pub.flutter-io.cn"
152 | source: hosted
153 | version: "1.7.0"
154 | path:
155 | dependency: transitive
156 | description:
157 | name: path
158 | url: "https://pub.flutter-io.cn"
159 | source: hosted
160 | version: "1.8.0"
161 | path_provider_linux:
162 | dependency: transitive
163 | description:
164 | name: path_provider_linux
165 | url: "https://pub.flutter-io.cn"
166 | source: hosted
167 | version: "2.1.0"
168 | path_provider_platform_interface:
169 | dependency: transitive
170 | description:
171 | name: path_provider_platform_interface
172 | url: "https://pub.flutter-io.cn"
173 | source: hosted
174 | version: "2.0.1"
175 | path_provider_windows:
176 | dependency: transitive
177 | description:
178 | name: path_provider_windows
179 | url: "https://pub.flutter-io.cn"
180 | source: hosted
181 | version: "2.0.3"
182 | platform:
183 | dependency: transitive
184 | description:
185 | name: platform
186 | url: "https://pub.flutter-io.cn"
187 | source: hosted
188 | version: "3.0.2"
189 | plugin_platform_interface:
190 | dependency: transitive
191 | description:
192 | name: plugin_platform_interface
193 | url: "https://pub.flutter-io.cn"
194 | source: hosted
195 | version: "2.0.2"
196 | pointycastle:
197 | dependency: "direct main"
198 | description:
199 | name: pointycastle
200 | url: "https://pub.flutter-io.cn"
201 | source: hosted
202 | version: "3.4.0"
203 | process:
204 | dependency: transitive
205 | description:
206 | name: process
207 | url: "https://pub.flutter-io.cn"
208 | source: hosted
209 | version: "4.2.3"
210 | shared_preferences:
211 | dependency: "direct main"
212 | description:
213 | name: shared_preferences
214 | url: "https://pub.flutter-io.cn"
215 | source: hosted
216 | version: "2.0.8"
217 | shared_preferences_linux:
218 | dependency: transitive
219 | description:
220 | name: shared_preferences_linux
221 | url: "https://pub.flutter-io.cn"
222 | source: hosted
223 | version: "2.0.2"
224 | shared_preferences_macos:
225 | dependency: transitive
226 | description:
227 | name: shared_preferences_macos
228 | url: "https://pub.flutter-io.cn"
229 | source: hosted
230 | version: "2.0.2"
231 | shared_preferences_platform_interface:
232 | dependency: transitive
233 | description:
234 | name: shared_preferences_platform_interface
235 | url: "https://pub.flutter-io.cn"
236 | source: hosted
237 | version: "2.0.0"
238 | shared_preferences_web:
239 | dependency: transitive
240 | description:
241 | name: shared_preferences_web
242 | url: "https://pub.flutter-io.cn"
243 | source: hosted
244 | version: "2.0.2"
245 | shared_preferences_windows:
246 | dependency: transitive
247 | description:
248 | name: shared_preferences_windows
249 | url: "https://pub.flutter-io.cn"
250 | source: hosted
251 | version: "2.0.2"
252 | sky_engine:
253 | dependency: transitive
254 | description: flutter
255 | source: sdk
256 | version: "0.0.99"
257 | source_span:
258 | dependency: transitive
259 | description:
260 | name: source_span
261 | url: "https://pub.flutter-io.cn"
262 | source: hosted
263 | version: "1.8.1"
264 | stack_trace:
265 | dependency: transitive
266 | description:
267 | name: stack_trace
268 | url: "https://pub.flutter-io.cn"
269 | source: hosted
270 | version: "1.10.0"
271 | stream_channel:
272 | dependency: transitive
273 | description:
274 | name: stream_channel
275 | url: "https://pub.flutter-io.cn"
276 | source: hosted
277 | version: "2.1.0"
278 | string_scanner:
279 | dependency: transitive
280 | description:
281 | name: string_scanner
282 | url: "https://pub.flutter-io.cn"
283 | source: hosted
284 | version: "1.1.0"
285 | term_glyph:
286 | dependency: transitive
287 | description:
288 | name: term_glyph
289 | url: "https://pub.flutter-io.cn"
290 | source: hosted
291 | version: "1.2.0"
292 | test_api:
293 | dependency: transitive
294 | description:
295 | name: test_api
296 | url: "https://pub.flutter-io.cn"
297 | source: hosted
298 | version: "0.4.2"
299 | typed_data:
300 | dependency: transitive
301 | description:
302 | name: typed_data
303 | url: "https://pub.flutter-io.cn"
304 | source: hosted
305 | version: "1.3.0"
306 | vector_math:
307 | dependency: transitive
308 | description:
309 | name: vector_math
310 | url: "https://pub.flutter-io.cn"
311 | source: hosted
312 | version: "2.1.0"
313 | win32:
314 | dependency: transitive
315 | description:
316 | name: win32
317 | url: "https://pub.flutter-io.cn"
318 | source: hosted
319 | version: "2.2.9"
320 | xdg_directories:
321 | dependency: transitive
322 | description:
323 | name: xdg_directories
324 | url: "https://pub.flutter-io.cn"
325 | source: hosted
326 | version: "0.2.0"
327 | sdks:
328 | dart: ">=2.14.0 <3.0.0"
329 | flutter: ">=2.5.0"
330 |
--------------------------------------------------------------------------------
/pubspec.yaml:
--------------------------------------------------------------------------------
1 | name: scrcpy_flutter
2 | description: Scrcpy client base on flutter.
3 |
4 | # The following line prevents the package from being accidentally published to
5 | # pub.dev using `flutter pub publish`. This is preferred for private packages.
6 | publish_to: 'none' # Remove this line if you wish to publish to pub.dev
7 |
8 | # The following defines the version and build number for your application.
9 | # A version number is three numbers separated by dots, like 1.2.43
10 | # followed by an optional build number separated by a +.
11 | # Both the version and the builder number may be overridden in flutter
12 | # build by specifying --build-name and --build-number, respectively.
13 | # In Android, build-name is used as versionName while build-number used as versionCode.
14 | # Read more about Android versioning at https://developer.android.com/studio/publish/versioning
15 | # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
16 | # Read more about iOS versioning at
17 | # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
18 | version: 1.0.0+1
19 |
20 | environment:
21 | sdk: ">=2.12.0 <3.0.0"
22 |
23 | # Dependencies specify other packages that your package needs in order to work.
24 | # To automatically upgrade your package dependencies to the latest versions
25 | # consider running `flutter pub upgrade --major-versions`. Alternatively,
26 | # dependencies can be manually updated by changing the version numbers below to
27 | # the latest version available on pub.dev. To see which dependencies have newer
28 | # versions available, run `flutter pub outdated`.
29 | dependencies:
30 | flutter:
31 | sdk: flutter
32 |
33 |
34 | # The following adds the Cupertino Icons font to your application.
35 | # Use with the CupertinoIcons class for iOS style icons.
36 | cupertino_icons: ^1.0.2
37 |
38 | floatingpanel:
39 | git:
40 | url: https://github.com/diyews/floating_panel.git
41 | ref: a8f7f6a628e2cccc2e902f71969352c737bb1b83
42 | shared_preferences: ^2.0.8
43 | http: ^0.13.4
44 | pointycastle: ^3.4.0
45 |
46 | dev_dependencies:
47 | flutter_test:
48 | sdk: flutter
49 |
50 | # The "flutter_lints" package below contains a set of recommended lints to
51 | # encourage good coding practices. The lint set provided by the package is
52 | # activated in the `analysis_options.yaml` file located at the root of your
53 | # package. See that file for information about deactivating specific lint
54 | # rules and activating additional ones.
55 | flutter_lints: ^1.0.0
56 |
57 | # For information on the generic Dart part of this file, see the
58 | # following page: https://dart.dev/tools/pub/pubspec
59 |
60 | # The following section is specific to Flutter.
61 | flutter:
62 |
63 | # The following line ensures that the Material Icons font is
64 | # included with your application, so that you can use the icons in
65 | # the material Icons class.
66 | uses-material-design: true
67 |
68 | # To add assets to your application, add an assets section, like this:
69 | # assets:
70 | # - images/a_dot_burr.jpeg
71 | # - images/a_dot_ham.jpeg
72 |
73 | # An image asset can refer to one or more resolution-specific "variants", see
74 | # https://flutter.dev/assets-and-images/#resolution-aware.
75 |
76 | # For details regarding adding assets from package dependencies, see
77 | # https://flutter.dev/assets-and-images/#from-packages
78 |
79 | # To add custom fonts to your application, add a fonts section here,
80 | # in this "flutter" section. Each entry in this list should have a
81 | # "family" key with the font family name, and a "fonts" key with a
82 | # list giving the asset and other descriptors for the font. For
83 | # example:
84 | # fonts:
85 | # - family: Schyler
86 | # fonts:
87 | # - asset: fonts/Schyler-Regular.ttf
88 | # - asset: fonts/Schyler-Italic.ttf
89 | # style: italic
90 | # - family: Trajan Pro
91 | # fonts:
92 | # - asset: fonts/TrajanPro.ttf
93 | # - asset: fonts/TrajanPro_Bold.ttf
94 | # weight: 700
95 | #
96 | # For details regarding fonts from package dependencies,
97 | # see https://flutter.dev/custom-fonts/#from-packages
98 |
--------------------------------------------------------------------------------
/test/widget_test.dart:
--------------------------------------------------------------------------------
1 | // This is a basic Flutter widget test.
2 | //
3 | // To perform an interaction with a widget in your test, use the WidgetTester
4 | // utility that Flutter provides. For example, you can send tap and scroll
5 | // gestures. You can also use WidgetTester to find child widgets in the widget
6 | // tree, read text, and verify that the values of widget properties are correct.
7 |
8 | import 'package:flutter/material.dart';
9 | import 'package:flutter_test/flutter_test.dart';
10 |
11 | import 'package:scrcpy_flutter/main.dart';
12 |
13 | void main() {
14 | testWidgets('Counter increments smoke test', (WidgetTester tester) async {
15 | // Build our app and trigger a frame.
16 | await tester.pumpWidget(const MyApp());
17 |
18 | // Verify that our counter starts at 0.
19 | expect(find.text('0'), findsOneWidget);
20 | expect(find.text('1'), findsNothing);
21 |
22 | // Tap the '+' icon and trigger a frame.
23 | await tester.tap(find.byIcon(Icons.add));
24 | await tester.pump();
25 |
26 | // Verify that our counter has incremented.
27 | expect(find.text('0'), findsNothing);
28 | expect(find.text('1'), findsOneWidget);
29 | });
30 | }
31 |
--------------------------------------------------------------------------------