├── ios ├── Assets │ └── .gitkeep ├── Classes │ ├── FlutterDisplayModePlugin.h │ ├── SwiftFlutterdisplaymodePlugin.swift │ └── FlutterDisplayModePlugin.m ├── .gitignore └── flutter_displaymode.podspec ├── example ├── ios │ ├── Runner │ │ ├── Runner-Bridging-Header.h │ │ ├── Assets.xcassets │ │ │ ├── LaunchImage.imageset │ │ │ │ ├── LaunchImage.png │ │ │ │ ├── LaunchImage@2x.png │ │ │ │ ├── LaunchImage@3x.png │ │ │ │ ├── README.md │ │ │ │ └── Contents.json │ │ │ └── AppIcon.appiconset │ │ │ │ ├── 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-1024x1024@1x.png │ │ │ │ ├── Icon-App-83.5x83.5@2x.png │ │ │ │ └── Contents.json │ │ ├── AppDelegate.swift │ │ ├── Base.lproj │ │ │ ├── Main.storyboard │ │ │ └── LaunchScreen.storyboard │ │ └── Info.plist │ ├── Flutter │ │ ├── Debug.xcconfig │ │ ├── Release.xcconfig │ │ ├── ephemeral │ │ │ ├── flutter_lldbinit │ │ │ └── flutter_lldb_helper.py │ │ └── AppFrameworkInfo.plist │ ├── Runner.xcworkspace │ │ └── contents.xcworkspacedata │ ├── Runner.xcodeproj │ │ ├── project.xcworkspace │ │ │ └── contents.xcworkspacedata │ │ ├── xcshareddata │ │ │ └── xcschemes │ │ │ │ └── Runner.xcscheme │ │ └── project.pbxproj │ ├── .gitignore │ └── Podfile ├── android │ ├── gradle.properties │ ├── app │ │ ├── src │ │ │ ├── main │ │ │ │ ├── res │ │ │ │ │ ├── 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 │ │ │ │ │ ├── drawable │ │ │ │ │ │ └── launch_background.xml │ │ │ │ │ ├── drawable-v21 │ │ │ │ │ │ └── launch_background.xml │ │ │ │ │ ├── values │ │ │ │ │ │ └── styles.xml │ │ │ │ │ └── values-night │ │ │ │ │ │ └── styles.xml │ │ │ │ ├── java │ │ │ │ │ └── com │ │ │ │ │ │ └── ajinasokan │ │ │ │ │ │ └── example │ │ │ │ │ │ └── MainActivity.java │ │ │ │ └── AndroidManifest.xml │ │ │ ├── debug │ │ │ │ └── AndroidManifest.xml │ │ │ └── profile │ │ │ │ └── AndroidManifest.xml │ │ └── build.gradle │ ├── gradle │ │ └── wrapper │ │ │ └── gradle-wrapper.properties │ ├── .gitignore │ ├── build.gradle │ └── settings.gradle ├── .metadata ├── README.md ├── .gitignore ├── analysis_options.yaml ├── pubspec.yaml └── lib │ └── main.dart ├── android ├── gradle.properties ├── src │ └── main │ │ ├── AndroidManifest.xml │ │ └── java │ │ └── com │ │ └── ajinasokan │ │ └── flutterdisplaymode │ │ └── DisplayModePlugin.java ├── .gitignore ├── gradle │ └── wrapper │ │ └── gradle-wrapper.properties ├── build.gradle └── settings.gradle ├── lib ├── flutter_displaymode.dart └── src │ ├── model │ └── display_mode.dart │ └── flutter_display_mode.dart ├── .gitignore ├── .metadata ├── pubspec.yaml ├── flutterdisplaymode.iml ├── LICENSE ├── CHANGELOG.md ├── README.md └── analysis_options.yaml /ios/Assets/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /example/ios/Runner/Runner-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | #import "GeneratedPluginRegistrant.h" -------------------------------------------------------------------------------- /android/gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx1536M 2 | android.useAndroidX=true 3 | -------------------------------------------------------------------------------- /example/android/gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx1536M 2 | android.useAndroidX=true 3 | -------------------------------------------------------------------------------- /android/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /ios/Classes/FlutterDisplayModePlugin.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @interface DisplayModePlugin : NSObject 4 | @end 5 | -------------------------------------------------------------------------------- /android/.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/workspace.xml 5 | /.idea/libraries 6 | .DS_Store 7 | /build 8 | /captures 9 | -------------------------------------------------------------------------------- /example/ios/Flutter/Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /example/ios/Flutter/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /lib/flutter_displaymode.dart: -------------------------------------------------------------------------------- 1 | library flutter_displaymode; 2 | 3 | export 'src/flutter_display_mode.dart'; 4 | export 'src/model/display_mode.dart'; 5 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .dart_tool/ 3 | .idea/ 4 | .gradle/ 5 | .vscode/ 6 | 7 | .lock 8 | .packages 9 | .pub/ 10 | pubspec.lock 11 | 12 | build/ -------------------------------------------------------------------------------- /example/ios/Flutter/ephemeral/flutter_lldbinit: -------------------------------------------------------------------------------- 1 | # 2 | # Generated file, do not edit. 3 | # 4 | 5 | command script import --relative-to-command-file flutter_lldb_helper.py 6 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ajinasokan/flutter_displaymode/HEAD/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ajinasokan/flutter_displaymode/HEAD/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ajinasokan/flutter_displaymode/HEAD/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ajinasokan/flutter_displaymode/HEAD/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ajinasokan/flutter_displaymode/HEAD/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ajinasokan/flutter_displaymode/HEAD/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ajinasokan/flutter_displaymode/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ajinasokan/flutter_displaymode/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ajinasokan/flutter_displaymode/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ajinasokan/flutter_displaymode/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ajinasokan/flutter_displaymode/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ajinasokan/flutter_displaymode/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ajinasokan/flutter_displaymode/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ajinasokan/flutter_displaymode/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ajinasokan/flutter_displaymode/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ajinasokan/flutter_displaymode/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ajinasokan/flutter_displaymode/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ajinasokan/flutter_displaymode/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ajinasokan/flutter_displaymode/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ajinasokan/flutter_displaymode/HEAD/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ajinasokan/flutter_displaymode/HEAD/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ajinasokan/flutter_displaymode/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ajinasokan/flutter_displaymode/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png -------------------------------------------------------------------------------- /example/ios/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /example/android/app/src/main/java/com/ajinasokan/example/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.ajinasokan.example; 2 | 3 | import io.flutter.embedding.android.FlutterActivity; 4 | 5 | public class MainActivity extends FlutterActivity { 6 | } 7 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | zipStoreBase=GRADLE_USER_HOME 4 | zipStorePath=wrapper/dists 5 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.0-all.zip 6 | -------------------------------------------------------------------------------- /example/android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Thu Apr 20 15:34:06 EEST 2023 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-all.zip 5 | zipStoreBase=GRADLE_USER_HOME 6 | zipStorePath=wrapper/dists 7 | -------------------------------------------------------------------------------- /.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: 0b8abb4724aa590dd0f429683339b1e045a1594d 8 | channel: stable 9 | 10 | project_type: plugin 11 | -------------------------------------------------------------------------------- /example/android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /example/.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: 0b8abb4724aa590dd0f429683339b1e045a1594d 8 | channel: stable 9 | 10 | project_type: app 11 | -------------------------------------------------------------------------------- /example/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 | -------------------------------------------------------------------------------- /example/android/app/src/profile/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /example/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. -------------------------------------------------------------------------------- /example/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 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/drawable/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/drawable-v21/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /example/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/.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | .vagrant/ 3 | .sconsign.dblite 4 | .svn/ 5 | 6 | .DS_Store 7 | *.swp 8 | profile 9 | 10 | DerivedData/ 11 | build/ 12 | GeneratedPluginRegistrant.h 13 | GeneratedPluginRegistrant.m 14 | 15 | .generated/ 16 | 17 | *.pbxuser 18 | *.mode1v3 19 | *.mode2v3 20 | *.perspectivev3 21 | 22 | !default.pbxuser 23 | !default.mode1v3 24 | !default.mode2v3 25 | !default.perspectivev3 26 | 27 | xcuserdata 28 | 29 | *.moved-aside 30 | 31 | *.pyc 32 | *sync/ 33 | Icon? 34 | .tags* 35 | 36 | /Flutter/Generated.xcconfig 37 | /Flutter/flutter_export_environment.sh -------------------------------------------------------------------------------- /pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: flutter_displaymode 2 | description: A Flutter plugin to set display mode (resolution, refresh rate) on Android platform. Allows to enable high refresh rate on supported devices. 3 | version: 0.7.0 4 | homepage: https://github.com/ajinasokan/flutter_displaymode 5 | 6 | environment: 7 | sdk: ">=3.0.0 <4.0.0" 8 | flutter: ">=3.10.0" 9 | 10 | dependencies: 11 | flutter: 12 | sdk: flutter 13 | 14 | flutter: 15 | plugin: 16 | platforms: 17 | android: 18 | package: com.ajinasokan.flutterdisplaymode 19 | pluginClass: DisplayModePlugin 20 | -------------------------------------------------------------------------------- /example/android/build.gradle: -------------------------------------------------------------------------------- 1 | allprojects { 2 | repositories { 3 | google() 4 | mavenCentral() 5 | } 6 | gradle.projectsEvaluated { 7 | tasks.withType(JavaCompile) { 8 | options.compilerArgs << "-Xlint:unchecked" << "-Xlint:deprecation" 9 | } 10 | } 11 | } 12 | 13 | rootProject.buildDir = '../build' 14 | subprojects { 15 | project.buildDir = "${rootProject.buildDir}/${project.name}" 16 | } 17 | subprojects { 18 | project.evaluationDependsOn(':app') 19 | } 20 | 21 | tasks.register("clean", Delete) { 22 | delete rootProject.layout.buildDirectory 23 | } 24 | -------------------------------------------------------------------------------- /ios/Classes/SwiftFlutterdisplaymodePlugin.swift: -------------------------------------------------------------------------------- 1 | import Flutter 2 | import UIKit 3 | 4 | public class SwiftFlutterDisplayModePlugin: NSObject, FlutterPlugin { 5 | public static func register(with registrar: FlutterPluginRegistrar) { 6 | let channel = FlutterMethodChannel(name: "flutter_displaymode", binaryMessenger: registrar.messenger()) 7 | let instance = SwiftFlutterDisplayModePlugin() 8 | registrar.addMethodCallDelegate(instance, channel: channel) 9 | } 10 | 11 | public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) { 12 | result("iOS " + UIDevice.current.systemVersion) 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /android/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "com.android.library" 3 | } 4 | 5 | group 'com.ajinasokan.flutterdisplaymode' 6 | version '1.0' 7 | 8 | rootProject.allprojects { 9 | repositories { 10 | google() 11 | mavenCentral() 12 | } 13 | } 14 | 15 | android { 16 | namespace 'com.ajinasokan.flutterdisplaymode' 17 | 18 | compileSdkVersion flutter.compileSdkVersion 19 | 20 | defaultConfig { 21 | minSdkVersion flutter.minSdkVersion 22 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 23 | } 24 | 25 | lintOptions { 26 | disable 'InvalidPackage' 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /example/README.md: -------------------------------------------------------------------------------- 1 | # flutterdisplaymode_example 2 | 3 | Demonstrates how to use the flutterdisplaymode plugin. 4 | 5 | ## Getting Started 6 | 7 | This project is a starting point for a Flutter application. 8 | 9 | A few resources to get you started if this is your first Flutter project: 10 | 11 | - [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab) 12 | - [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook) 13 | 14 | For help getting started with Flutter, view our 15 | [online documentation](https://flutter.dev/docs), which offers tutorials, 16 | samples, guidance on mobile development, and a full API reference. 17 | -------------------------------------------------------------------------------- /example/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/app.flx 22 | Flutter/app.zip 23 | Flutter/flutter_assets/ 24 | Flutter/flutter_export_environment.sh 25 | ServiceDefinitions.json 26 | Runner/GeneratedPluginRegistrant.* 27 | 28 | # Exceptions to above rules. 29 | !default.mode1v3 30 | !default.mode2v3 31 | !default.pbxuser 32 | !default.perspectivev3 33 | -------------------------------------------------------------------------------- /ios/Classes/FlutterDisplayModePlugin.m: -------------------------------------------------------------------------------- 1 | #import "FlutterDisplayModePlugin.h" 2 | 3 | @implementation DisplayModePlugin 4 | + (void)registerWithRegistrar:(NSObject*)registrar { 5 | FlutterMethodChannel* channel = 6 | [FlutterMethodChannel methodChannelWithName:@"plugins.ajinasokan.com/flutter_displaymode" 7 | binaryMessenger:[registrar messenger]]; 8 | DisplayModePlugin* instance = [[DisplayModePlugin alloc] init]; 9 | [registrar addMethodCallDelegate:instance channel:channel]; 10 | } 11 | 12 | - (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result { 13 | result(FlutterMethodNotImplemented); 14 | } 15 | 16 | @end -------------------------------------------------------------------------------- /android/settings.gradle: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | def flutterSdkPath = { 3 | def properties = new Properties() 4 | file("local.properties").withInputStream { properties.load(it) } 5 | def flutterSdkPath = properties.getProperty("flutter.sdk") 6 | assert flutterSdkPath != null, "flutter.sdk not set in local.properties" 7 | return flutterSdkPath 8 | }() 9 | 10 | includeBuild("$flutterSdkPath/packages/flutter_tools/gradle") 11 | 12 | repositories { 13 | google() 14 | mavenCentral() 15 | gradlePluginPortal() 16 | } 17 | } 18 | 19 | plugins { 20 | id "dev.flutter.flutter-plugin-loader" version "1.0.0" 21 | id "com.android.library" version "8.3.0" apply false 22 | } 23 | 24 | rootProject.name = 'flutterdisplaymode' -------------------------------------------------------------------------------- /example/.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 | .dart_tool/ 26 | .flutter-plugins 27 | .flutter-plugins-dependencies 28 | .packages 29 | .lock 30 | .pub-cache/ 31 | .pub/ 32 | /build/ 33 | pubspec.lock 34 | 35 | # Web related 36 | lib/generated_plugin_registrant.dart 37 | 38 | # Exceptions to above rules. 39 | !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages 40 | -------------------------------------------------------------------------------- /example/ios/Flutter/AppFrameworkInfo.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 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 | 8.0 25 | 26 | 27 | -------------------------------------------------------------------------------- /example/android/settings.gradle: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | def flutterSdkPath = { 3 | def properties = new Properties() 4 | def localPropertiesFile = new File(rootProject.projectDir, "local.properties") 5 | if (localPropertiesFile.exists()) { 6 | localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) } 7 | } 8 | def flutterSdkPath = properties.getProperty("flutter.sdk") 9 | assert flutterSdkPath != null, "flutter.sdk not set in local.properties" 10 | return flutterSdkPath 11 | }() 12 | 13 | includeBuild("$flutterSdkPath/packages/flutter_tools/gradle") 14 | 15 | repositories { 16 | google() 17 | mavenCentral() 18 | gradlePluginPortal() 19 | } 20 | } 21 | 22 | plugins { 23 | id "dev.flutter.flutter-plugin-loader" version "1.0.0" 24 | id "com.android.application" version "8.3.0" apply false 25 | id "org.jetbrains.kotlin.android" version "1.8.20" apply false 26 | } 27 | 28 | include ":app" -------------------------------------------------------------------------------- /flutterdisplaymode.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /ios/flutter_displaymode.podspec: -------------------------------------------------------------------------------- 1 | # 2 | # To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html. 3 | # Run `pod lib lint flutter_displaymode.podspec' to validate before publishing. 4 | # 5 | Pod::Spec.new do |s| 6 | s.name = 'flutter_displaymode' 7 | s.version = '0.0.1' 8 | s.summary = 'A Flutter plugin to set display mode in Android' 9 | s.description = <<-DESC 10 | A Flutter plugin to set display mode in Android 11 | DESC 12 | s.homepage = 'http://example.com' 13 | s.license = { :file => '../LICENSE' } 14 | s.author = { 'Your Company' => 'email@example.com' } 15 | s.source = { :path => '.' } 16 | s.source_files = 'Classes/**/*' 17 | s.dependency 'Flutter' 18 | s.platform = :ios, '8.0' 19 | 20 | # Flutter.framework does not contain a i386 slice. Only x86_64 simulators are supported. 21 | s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'VALID_ARCHS[sdk=iphonesimulator*]' => 'x86_64' } 22 | s.swift_version = '5.0' 23 | end 24 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/values-night/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Ajin Asokan 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /lib/src/model/display_mode.dart: -------------------------------------------------------------------------------- 1 | class DisplayMode { 2 | const DisplayMode({ 3 | required this.id, 4 | required this.width, 5 | required this.height, 6 | required this.refreshRate, 7 | }); 8 | 9 | factory DisplayMode.fromJson(Map json) { 10 | return DisplayMode( 11 | id: json['id'] as int, 12 | width: json['width'] as int, 13 | height: json['height'] as int, 14 | refreshRate: json['refreshRate'] as double, 15 | ); 16 | } 17 | 18 | final int id; 19 | final int width; 20 | final int height; 21 | final double refreshRate; 22 | 23 | static const DisplayMode auto = DisplayMode( 24 | id: 0, 25 | width: 0, 26 | height: 0, 27 | refreshRate: 0, 28 | ); 29 | 30 | @override 31 | String toString() { 32 | return '#$id ${width}x$height @ ${refreshRate.toInt()}Hz'; 33 | } 34 | 35 | @override 36 | bool operator ==(Object other) => 37 | identical(this, other) || 38 | other is DisplayMode && 39 | runtimeType == other.runtimeType && 40 | width == other.width && 41 | height == other.height && 42 | refreshRate == other.refreshRate; 43 | 44 | @override 45 | int get hashCode => width.hashCode ^ height.hashCode ^ refreshRate.hashCode; 46 | } 47 | -------------------------------------------------------------------------------- /example/ios/Flutter/ephemeral/flutter_lldb_helper.py: -------------------------------------------------------------------------------- 1 | # 2 | # Generated file, do not edit. 3 | # 4 | 5 | import lldb 6 | 7 | def handle_new_rx_page(frame: lldb.SBFrame, bp_loc, extra_args, intern_dict): 8 | """Intercept NOTIFY_DEBUGGER_ABOUT_RX_PAGES and touch the pages.""" 9 | base = frame.register["x0"].GetValueAsAddress() 10 | page_len = frame.register["x1"].GetValueAsUnsigned() 11 | 12 | # Note: NOTIFY_DEBUGGER_ABOUT_RX_PAGES will check contents of the 13 | # first page to see if handled it correctly. This makes diagnosing 14 | # misconfiguration (e.g. missing breakpoint) easier. 15 | data = bytearray(page_len) 16 | data[0:8] = b'IHELPED!' 17 | 18 | error = lldb.SBError() 19 | frame.GetThread().GetProcess().WriteMemory(base, data, error) 20 | if not error.Success(): 21 | print(f'Failed to write into {base}[+{page_len}]', error) 22 | return 23 | 24 | def __lldb_init_module(debugger: lldb.SBDebugger, _): 25 | target = debugger.GetDummyTarget() 26 | # Caveat: must use BreakpointCreateByRegEx here and not 27 | # BreakpointCreateByName. For some reasons callback function does not 28 | # get carried over from dummy target for the later. 29 | bp = target.BreakpointCreateByRegex("^NOTIFY_DEBUGGER_ABOUT_RX_PAGES$") 30 | bp.SetScriptCallbackFunction('{}.handle_new_rx_page'.format(__name__)) 31 | bp.SetAutoContinue(True) 32 | print("-- LLDB integration loaded --") 33 | -------------------------------------------------------------------------------- /example/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 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## 0.7.0 2 | 3 | * Android project upgrades 4 | 5 | ## 0.6.0 6 | 7 | * Android project upgrades (Gradle 8, AGP 8.0, compileSDK 33, Java 17). Thanks to [@vbuberen](https://github.com/vbuberen) 8 | 9 | ## 0.5.0 10 | 11 | * Calling `setHighRefreshRate` or `setLowRefreshRate` will always set the display mode. Fixes #20 12 | * Setting compileSdkVersion to 30 13 | * Cleaned up all deprecation warnings. Fixes #14 14 | 15 | ## 0.4.1 16 | 17 | * Migrate to mavenCentral. Thanks to [@alvarisi](https://github.com/alvarisi) 18 | 19 | ## 0.4.0 20 | 21 | * Removed deprecated `registerWith` function to cleanup warnings 22 | 23 | ## 0.3.2 24 | 25 | * Fix setHighRefreshRate/setLowRefreshRate 26 | 27 | ## 0.3.1-nullsafety.0 28 | 29 | * Add `FlutterDisplayMode.setHighRefreshRate` and `FlutterDisplayMode.setLowRefreshRate` methods 30 | 31 | ## 0.3.0-nullsafety.0 32 | 33 | * Breaking changes to fix [issue#9](https://github.com/ajinasokan/flutter_displaymode/issues/9) 34 | * `FlutterDisplayMode.current` renamed to `FlutterDisplayMode.active` 35 | * `FlutterDisplayMode.setMode` renamed to `FlutterDisplayMode.setPreferredMode` 36 | * Added `FlutterDisplayMode.preferred` 37 | * Removed `DisplayMode.selected` field. Use `FlutterDisplayMode.active` instead. 38 | 39 | ## 0.2.0-nullsafety.0 40 | 41 | * Migrate to null safety. Thanks [@AlexV525](https://github.com/AlexV525) 42 | 43 | ## 0.1.1 44 | 45 | * Fix pubspec warning for iOS [issue#4](https://github.com/ajinasokan/flutter_displaymode/issues/4) 46 | 47 | ## 0.1.0 48 | 49 | * Support get current mode from platform. 50 | * Support default mode set according to platform setting. 51 | * Code stylus improving. 52 | 53 | ## 0.0.1 54 | 55 | * Initial release. 56 | -------------------------------------------------------------------------------- /example/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 | -------------------------------------------------------------------------------- /example/android/app/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "com.android.application" 3 | id "kotlin-android" 4 | id "dev.flutter.flutter-gradle-plugin" 5 | } 6 | 7 | def localProperties = new Properties() 8 | def localPropertiesFile = rootProject.file('local.properties') 9 | if (localPropertiesFile.exists()) { 10 | localPropertiesFile.withReader('UTF-8') { reader -> 11 | localProperties.load(reader) 12 | } 13 | } 14 | 15 | def flutterRoot = localProperties.getProperty('flutter.sdk') 16 | if (flutterRoot == null) { 17 | throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") 18 | } 19 | 20 | def flutterVersionCode = localProperties.getProperty('flutter.versionCode') 21 | if (flutterVersionCode == null) { 22 | flutterVersionCode = '1' 23 | } 24 | 25 | def flutterVersionName = localProperties.getProperty('flutter.versionName') 26 | if (flutterVersionName == null) { 27 | flutterVersionName = '1.0' 28 | } 29 | 30 | android { 31 | compileSdkVersion flutter.compileSdkVersion 32 | 33 | compileOptions { 34 | sourceCompatibility JavaVersion.VERSION_17 35 | targetCompatibility JavaVersion.VERSION_17 36 | } 37 | 38 | namespace 'com.ajinasokan.example' 39 | 40 | defaultConfig { 41 | applicationId "com.ajinasokan.example" 42 | minSdkVersion flutter.minSdkVersion 43 | targetSdkVersion flutter.targetSdkVersion 44 | versionCode flutterVersionCode.toInteger() 45 | versionName flutterVersionName 46 | } 47 | 48 | buildTypes { 49 | release { 50 | signingConfig signingConfigs.debug 51 | } 52 | } 53 | } 54 | 55 | flutter { 56 | source '../..' 57 | } 58 | -------------------------------------------------------------------------------- /example/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 | flutterdisplaymode_example 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 | -------------------------------------------------------------------------------- /example/android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 14 | 18 | 22 | 23 | 24 | 25 | 26 | 27 | 29 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /example/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: flutterdisplaymode_example 2 | description: Demonstrates how to use the flutterdisplaymode plugin. 3 | publish_to: "none" 4 | 5 | environment: 6 | sdk: ">=2.12.0-0 <3.0.0" 7 | 8 | dependencies: 9 | flutter: 10 | sdk: flutter 11 | 12 | dev_dependencies: 13 | flutter_test: 14 | sdk: flutter 15 | 16 | flutter_displaymode: 17 | path: ../ 18 | 19 | # For information on the generic Dart part of this file, see the 20 | # following page: https://dart.dev/tools/pub/pubspec 21 | 22 | # The following section is specific to Flutter. 23 | flutter: 24 | # The following line ensures that the Material Icons font is 25 | # included with your application, so that you can use the icons in 26 | # the material Icons class. 27 | uses-material-design: true 28 | # To add assets to your application, add an assets section, like this: 29 | # assets: 30 | # - images/a_dot_burr.jpeg 31 | # - images/a_dot_ham.jpeg 32 | # An image asset can refer to one or more resolution-specific "variants", see 33 | # https://flutter.dev/assets-and-images/#resolution-aware. 34 | # For details regarding adding assets from package dependencies, see 35 | # https://flutter.dev/assets-and-images/#from-packages 36 | # To add custom fonts to your application, add a fonts section here, 37 | # in this "flutter" section. Each entry in this list should have a 38 | # "family" key with the font family name, and a "fonts" key with a 39 | # list giving the asset and other descriptors for the font. For 40 | # example: 41 | # fonts: 42 | # - family: Schyler 43 | # fonts: 44 | # - asset: fonts/Schyler-Regular.ttf 45 | # - asset: fonts/Schyler-Italic.ttf 46 | # style: italic 47 | # - family: Trajan Pro 48 | # fonts: 49 | # - asset: fonts/TrajanPro.ttf 50 | # - asset: fonts/TrajanPro_Bold.ttf 51 | # weight: 700 52 | # 53 | # For details regarding fonts from package dependencies, 54 | # see https://flutter.dev/custom-fonts/#from-packages 55 | -------------------------------------------------------------------------------- /example/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 | -------------------------------------------------------------------------------- /example/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 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Flutter Display Mode 4 | 5 | [![pub package](https://img.shields.io/pub/v/flutter_displaymode.svg)](https://pub.dev/packages/flutter_displaymode) 6 | 7 | A Flutter plugin to set display mode in Android. This is useful to enable high refresh rate in devices with discrete framerates like 60Hz, 90Hz etc. This library is ineffective on devices with LTPO panels and iOS devices with ProMotion. 8 | 9 | This library should be used as a temporary fix to [#35162](https://github.com/flutter/flutter/issues/35162) until this API gets added to Flutter engine itself. 10 | 11 | ## Getting Started 12 | 13 | Add library to pubspec then and **rebuild** your app: 14 | 15 | ```shell 16 | flutter pub add flutter_displaymode 17 | ``` 18 | 19 | ### Set to highest/lowest framerate 20 | 21 | Use helper functions `FlutterDisplayMode.setHighRefreshRate` or `FlutterDisplayMode.setLowRefreshRate` to switch to highest or lowest refresh rate maintaining current resolution. 22 | 23 | ```dart 24 | // current: #1 1440x3120 @ 60Hz 25 | // new: #2 1440x3120 @ 90Hz 26 | await FlutterDisplayMode.setHighRefreshRate(); 27 | 28 | // current: #2 1440x3120 @ 90Hz 29 | // new: #1 1440x3120 @ 60Hz 30 | await FlutterDisplayMode.setLowRefreshRate(); 31 | ``` 32 | 33 | ### Get supported modes 34 | 35 | `FlutterDisplayMode.supported` returns all the modes that can be set as the preferred mode. This always returns `DisplayMode.auto` as one of the modes. 36 | 37 | ```dart 38 | import 'package:flutter_displaymode/flutter_displaymode.dart'; 39 | 40 | try { 41 | modes = await FlutterDisplayMode.supported; 42 | modes.forEach(print); 43 | 44 | /// On OnePlus 7 Pro: 45 | /// #0 0x0 @0Hz // Automatic 46 | /// #1 1080x2340 @ 60Hz 47 | /// #2 1080x2340 @ 90Hz 48 | /// #3 1440x3120 @ 90Hz 49 | /// #4 1440x3120 @ 60Hz 50 | 51 | /// On OnePlus 8 Pro: 52 | /// #0 0x0 @0Hz // Automatic 53 | /// #1 1080x2376 @ 60Hz 54 | /// #2 1440x3168 @ 120Hz 55 | /// #3 1440x3168 @ 60Hz 56 | /// #4 1080x2376 @ 120Hz 57 | } on PlatformException catch (e) { 58 | /// e.code => 59 | /// noAPI - No API support. Only Marshmallow and above. 60 | /// noActivity - Activity is not available. Probably app is in background 61 | } 62 | ``` 63 | 64 | ### Get active mode 65 | 66 | `FlutterDisplayMode.active` fetches the currently active mode. This is not always the preferred mode set by `FlutterDisplayMode.setPreferredMode`. It can be altered by the system based on the display settings. 67 | 68 | ```dart 69 | final DisplayMode m = await FlutterDisplayMode.active; 70 | ``` 71 | 72 | ### Set preferred mode 73 | 74 | `FlutterDisplayMode.setPreferredMode` changes the preferred mode. It is upto the system to use this mode. Sometimes system can choose not switch to this based on internal heuristics. Check `FlutterDisplayMode.active` to see if it actually switches. 75 | 76 | ```dart 77 | /// This setting is per session. 78 | /// Please ensure this was placed with `initState` of your root widget. 79 | await FlutterDisplayMode.setPreferredMode(modes[1]); 80 | ``` 81 | 82 | ### Get preferred mode 83 | 84 | `FlutterDisplayMode.preferred` returns the currently preferred mode. If not manually set with `FlutterDisplayMode.setPreferredMode` then it will be `DisplayMode.auto`. 85 | 86 | ```dart 87 | final DisplayMode m = await FlutterDisplayMode.preferred; 88 | ``` 89 | 90 | You can check out a complete example [here](https://github.com/ajinasokan/flutter_displaymode/blob/master/example/lib/main.dart). 91 | -------------------------------------------------------------------------------- /lib/src/flutter_display_mode.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | 3 | import 'package:flutter/services.dart'; 4 | 5 | import 'model/display_mode.dart'; 6 | 7 | class FlutterDisplayMode { 8 | const FlutterDisplayMode._(); 9 | 10 | static const MethodChannel _channel = MethodChannel('flutter_display_mode'); 11 | 12 | /// [supported] returns all the modes that can be set as the preferred mode. 13 | /// This always returns [DisplayMode.auto] as one of the modes. 14 | static Future> get supported async { 15 | final List rawModes = 16 | (await _channel.invokeMethod>('getSupportedModes'))!; 17 | final List modes = rawModes.map((dynamic i) { 18 | final Map item = 19 | (i as Map).cast(); 20 | return DisplayMode.fromJson(item); 21 | }).toList(); 22 | modes.insert(0, DisplayMode.auto); 23 | return modes; 24 | } 25 | 26 | /// [active] fetches the currently active mode. This is not always the 27 | /// preferred mode set by [setPreferredMode]. It can be altered by the 28 | /// system based on the display settings. 29 | static Future get active async { 30 | final Map mode = 31 | (await _channel.invokeMethod>('getActiveMode'))!; 32 | 33 | return DisplayMode.fromJson(mode.cast()); 34 | } 35 | 36 | /// [preferred] returns the currently preferred mode. If not manually set 37 | /// with [setPreferredMode] then it will be [DisplayMode.auto]. 38 | static Future get preferred async { 39 | final Map mode = (await _channel 40 | .invokeMethod>('getPreferredMode'))!; 41 | 42 | return DisplayMode.fromJson(mode.cast()); 43 | } 44 | 45 | /// [setPreferredMode] changes the preferred mode. It is upto the system 46 | /// to use this. Sometimes system can choose not switch to this based on 47 | /// internal heuristics. Check [active] to see if it actually switches. 48 | static Future setPreferredMode(DisplayMode mode) async { 49 | return await _channel.invokeMethod( 50 | 'setPreferredMode', 51 | {'mode': mode.id}, 52 | ); 53 | } 54 | 55 | /// [setHighRefreshRate] changes preferred mode to highest refresh rate 56 | /// available maintaining current resolution 57 | static Future setHighRefreshRate() async { 58 | final List modes = await supported; 59 | final DisplayMode activeMode = await active; 60 | 61 | DisplayMode newMode = activeMode; 62 | for (final DisplayMode mode in modes) { 63 | if (mode.height == newMode.height && 64 | mode.width == newMode.width && 65 | mode.refreshRate > newMode.refreshRate) { 66 | newMode = mode; 67 | } 68 | } 69 | 70 | await setPreferredMode(newMode); 71 | } 72 | 73 | /// [setLowRefreshRate] changes preferred mode to lowest refresh rate 74 | /// available maintaining current resolution 75 | static Future setLowRefreshRate() async { 76 | final List modes = await supported; 77 | final DisplayMode activeMode = await active; 78 | 79 | DisplayMode newMode = activeMode; 80 | for (final DisplayMode mode in modes) { 81 | if (mode.height == newMode.height && 82 | mode.width == newMode.width && 83 | mode.refreshRate < newMode.refreshRate) { 84 | newMode = mode; 85 | } 86 | } 87 | 88 | await setPreferredMode(newMode); 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /example/ios/Podfile: -------------------------------------------------------------------------------- 1 | # Uncomment this line to define a global platform for your project 2 | platform :ios, '9.0' 3 | 4 | # CocoaPods analytics sends network stats synchronously affecting flutter build latency. 5 | ENV['COCOAPODS_DISABLE_STATS'] = 'true' 6 | 7 | project 'Runner', { 8 | 'Debug' => :debug, 9 | 'Profile' => :release, 10 | 'Release' => :release, 11 | } 12 | 13 | def parse_KV_file(file, separator='=') 14 | file_abs_path = File.expand_path(file) 15 | if !File.exists? file_abs_path 16 | return []; 17 | end 18 | generated_key_values = {} 19 | skip_line_start_symbols = ["#", "/"] 20 | File.foreach(file_abs_path) do |line| 21 | next if skip_line_start_symbols.any? { |symbol| line =~ /^\s*#{symbol}/ } 22 | plugin = line.split(pattern=separator) 23 | if plugin.length == 2 24 | podname = plugin[0].strip() 25 | path = plugin[1].strip() 26 | podpath = File.expand_path("#{path}", file_abs_path) 27 | generated_key_values[podname] = podpath 28 | else 29 | puts "Invalid plugin specification: #{line}" 30 | end 31 | end 32 | generated_key_values 33 | end 34 | 35 | target 'Runner' do 36 | use_frameworks! 37 | use_modular_headers! 38 | 39 | # Flutter Pod 40 | 41 | copied_flutter_dir = File.join(__dir__, 'Flutter') 42 | copied_framework_path = File.join(copied_flutter_dir, 'Flutter.framework') 43 | copied_podspec_path = File.join(copied_flutter_dir, 'Flutter.podspec') 44 | unless File.exist?(copied_framework_path) && File.exist?(copied_podspec_path) 45 | # Copy Flutter.framework and Flutter.podspec to Flutter/ to have something to link against if the xcode backend script has not run yet. 46 | # That script will copy the correct debug/profile/release version of the framework based on the currently selected Xcode configuration. 47 | # CocoaPods will not embed the framework on pod install (before any build phases can generate) if the dylib does not exist. 48 | 49 | generated_xcode_build_settings_path = File.join(copied_flutter_dir, 'Generated.xcconfig') 50 | unless File.exist?(generated_xcode_build_settings_path) 51 | raise "Generated.xcconfig must exist. If you're running pod install manually, make sure flutter pub get is executed first" 52 | end 53 | generated_xcode_build_settings = parse_KV_file(generated_xcode_build_settings_path) 54 | cached_framework_dir = generated_xcode_build_settings['FLUTTER_FRAMEWORK_DIR']; 55 | 56 | unless File.exist?(copied_framework_path) 57 | FileUtils.cp_r(File.join(cached_framework_dir, 'Flutter.framework'), copied_flutter_dir) 58 | end 59 | unless File.exist?(copied_podspec_path) 60 | FileUtils.cp(File.join(cached_framework_dir, 'Flutter.podspec'), copied_flutter_dir) 61 | end 62 | end 63 | 64 | # Keep pod path relative so it can be checked into Podfile.lock. 65 | pod 'Flutter', :path => 'Flutter' 66 | 67 | # Plugin Pods 68 | 69 | # Prepare symlinks folder. We use symlinks to avoid having Podfile.lock 70 | # referring to absolute paths on developers' machines. 71 | system('rm -rf .symlinks') 72 | system('mkdir -p .symlinks/plugins') 73 | plugin_pods = parse_KV_file('../.flutter-plugins') 74 | plugin_pods.each do |name, path| 75 | symlink = File.join('.symlinks', 'plugins', name) 76 | File.symlink(path, symlink) 77 | pod name, :path => File.join(symlink, 'ios') 78 | end 79 | end 80 | 81 | post_install do |installer| 82 | installer.pods_project.targets.each do |target| 83 | target.build_configurations.each do |config| 84 | config.build_settings['ENABLE_BITCODE'] = 'NO' 85 | end 86 | end 87 | end 88 | -------------------------------------------------------------------------------- /example/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 | -------------------------------------------------------------------------------- /example/lib/main.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter/scheduler.dart'; 3 | import 'package:flutter/services.dart'; 4 | import 'package:flutter_displaymode/flutter_displaymode.dart'; 5 | 6 | void main() => runApp(MaterialApp(home: MyApp())); 7 | 8 | class MyApp extends StatefulWidget { 9 | @override 10 | _MyAppState createState() => _MyAppState(); 11 | } 12 | 13 | class _MyAppState extends State { 14 | List modes = []; 15 | DisplayMode? active; 16 | DisplayMode? preferred; 17 | 18 | final ValueNotifier page = ValueNotifier(0); 19 | late final PageController controller = PageController() 20 | ..addListener(() { 21 | page.value = controller.page!.round(); 22 | }); 23 | 24 | @override 25 | void initState() { 26 | super.initState(); 27 | SchedulerBinding.instance.addPostFrameCallback((_) { 28 | fetchAll(); 29 | }); 30 | } 31 | 32 | Future fetchAll() async { 33 | try { 34 | modes = await FlutterDisplayMode.supported; 35 | modes.forEach(print); 36 | 37 | /// On OnePlus 7 Pro: 38 | /// #1 1080x2340 @ 60Hz 39 | /// #2 1080x2340 @ 90Hz 40 | /// #3 1440x3120 @ 90Hz 41 | /// #4 1440x3120 @ 60Hz 42 | 43 | /// On OnePlus 8 Pro: 44 | /// #1 1080x2376 @ 60Hz 45 | /// #2 1440x3168 @ 120Hz 46 | /// #3 1440x3168 @ 60Hz 47 | /// #4 1080x2376 @ 120Hz 48 | } on PlatformException catch (e) { 49 | print(e); 50 | 51 | /// e.code => 52 | /// noAPI - No API support. Only Marshmallow and above. 53 | /// noActivity - Activity is not available. Probably app is in background 54 | } 55 | 56 | preferred = await FlutterDisplayMode.preferred; 57 | 58 | active = await FlutterDisplayMode.active; 59 | 60 | setState(() {}); 61 | } 62 | 63 | @override 64 | Widget build(BuildContext context) { 65 | return MaterialApp( 66 | home: Scaffold( 67 | appBar: AppBar(title: const Text('Plugin example app')), 68 | body: Padding( 69 | padding: const EdgeInsets.only(top: 16, left: 16, right: 16), 70 | child: PageView( 71 | controller: controller, 72 | children: [ 73 | Column( 74 | crossAxisAlignment: CrossAxisAlignment.start, 75 | children: [ 76 | Row( 77 | children: [ 78 | Text( 79 | 'Available modes', 80 | style: Theme.of(context).textTheme.headlineSmall, 81 | ), 82 | TextButton.icon( 83 | icon: const Icon(Icons.refresh), 84 | onPressed: () { 85 | fetchAll(); 86 | }, 87 | label: const Text('Fetch'), 88 | ), 89 | ], 90 | ), 91 | if (modes.isEmpty) const Text('Nothing here'), 92 | Expanded( 93 | child: ListView.builder( 94 | itemCount: modes.length, 95 | itemBuilder: (_, int i) { 96 | final DisplayMode mode = modes[i]; 97 | return Row( 98 | children: [ 99 | Radio( 100 | value: mode, 101 | groupValue: preferred, 102 | onChanged: (DisplayMode? newMode) async { 103 | await FlutterDisplayMode.setPreferredMode( 104 | newMode!); 105 | await Future.delayed( 106 | const Duration(milliseconds: 100), 107 | ); 108 | await fetchAll(); 109 | setState(() {}); 110 | }, 111 | ), 112 | if (mode == DisplayMode.auto) 113 | const Text('Automatic') 114 | else 115 | Text(mode.toString()), 116 | if (mode == active) const Text(' [ACTIVE]'), 117 | ], 118 | ); 119 | }, 120 | ), 121 | ), 122 | if (modes.isNotEmpty) const Divider(), 123 | if (modes.isNotEmpty) 124 | Row( 125 | children: [ 126 | ElevatedButton( 127 | onPressed: () async { 128 | await FlutterDisplayMode.setHighRefreshRate(); 129 | await Future.delayed( 130 | const Duration(milliseconds: 100), 131 | ); 132 | await fetchAll(); 133 | setState(() {}); 134 | }, 135 | child: const Text('Highest Hz'), 136 | ), 137 | const SizedBox(width: 8), 138 | ElevatedButton( 139 | onPressed: () async { 140 | await FlutterDisplayMode.setLowRefreshRate(); 141 | await Future.delayed( 142 | const Duration(milliseconds: 100), 143 | ); 144 | await fetchAll(); 145 | setState(() {}); 146 | }, 147 | child: const Text('Lowest Hz'), 148 | ), 149 | ], 150 | ), 151 | const Divider(), 152 | ], 153 | ), 154 | ListView.builder( 155 | itemBuilder: (BuildContext _, int i) { 156 | return Padding( 157 | padding: const EdgeInsets.all(8.0), 158 | child: Text('Index: $i'), 159 | ); 160 | }, 161 | ), 162 | ], 163 | ), 164 | ), 165 | bottomNavigationBar: ValueListenableBuilder( 166 | valueListenable: page, 167 | builder: (_, int page, __) => BottomNavigationBar( 168 | currentIndex: page, 169 | items: const [ 170 | BottomNavigationBarItem( 171 | icon: Icon(Icons.android), 172 | label: 'Modes', 173 | ), 174 | BottomNavigationBarItem( 175 | icon: Icon(Icons.list), 176 | label: 'Lists', 177 | ), 178 | ], 179 | onTap: (int i) => controller.animateToPage( 180 | i, 181 | duration: kTabScrollDuration, 182 | curve: Curves.easeOutQuart, 183 | ), 184 | ), 185 | ), 186 | ), 187 | ); 188 | } 189 | } 190 | -------------------------------------------------------------------------------- /android/src/main/java/com/ajinasokan/flutterdisplaymode/DisplayModePlugin.java: -------------------------------------------------------------------------------- 1 | package com.ajinasokan.flutterdisplaymode; 2 | 3 | import android.app.Activity; 4 | import android.content.Context; 5 | import android.os.Build; 6 | import android.view.Display; 7 | import android.view.Window; 8 | import android.view.WindowManager; 9 | 10 | import androidx.annotation.NonNull; 11 | import androidx.annotation.RequiresApi; 12 | 13 | import java.util.ArrayList; 14 | import java.util.HashMap; 15 | 16 | import io.flutter.embedding.engine.plugins.FlutterPlugin; 17 | import io.flutter.embedding.engine.plugins.activity.ActivityAware; 18 | import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding; 19 | import io.flutter.plugin.common.MethodCall; 20 | import io.flutter.plugin.common.MethodChannel; 21 | import io.flutter.plugin.common.MethodChannel.MethodCallHandler; 22 | import io.flutter.plugin.common.MethodChannel.Result; 23 | 24 | /** 25 | * DisplayModePlugin 26 | */ 27 | public class DisplayModePlugin implements FlutterPlugin, MethodCallHandler, ActivityAware { 28 | private Activity activity; 29 | private static final String METHOD_GET_ACTIVE_MODE = "getActiveMode"; 30 | private static final String METHOD_GET_SUPPORTED_MODES = "getSupportedModes"; 31 | private static final String METHOD_GET_PREFERRED_MODE = "getPreferredMode"; 32 | private static final String METHOD_SET_PREFERRED_MODE = "setPreferredMode"; 33 | 34 | @Override 35 | public void onAttachedToEngine(@NonNull FlutterPluginBinding flutterPluginBinding) { 36 | final MethodChannel channel = new MethodChannel(flutterPluginBinding.getBinaryMessenger(), "flutter_display_mode"); 37 | channel.setMethodCallHandler(this); 38 | } 39 | 40 | @Override 41 | public void onMethodCall(@NonNull MethodCall call, @NonNull Result result) { 42 | if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { 43 | result.error("noAPI", "API is supported only in Android 6 (Marshmallow) and later", null); 44 | return; 45 | } 46 | 47 | if (activity == null) { 48 | result.error("noActivity", "Activity not attached to plugin. App is probably in background.", null); 49 | return; 50 | } 51 | 52 | switch (call.method) { 53 | case METHOD_GET_ACTIVE_MODE: 54 | getActiveMode(result); 55 | break; 56 | case METHOD_GET_SUPPORTED_MODES: 57 | getSupportedModes(result); 58 | break; 59 | case METHOD_GET_PREFERRED_MODE: 60 | getPreferredMode(result); 61 | break; 62 | case METHOD_SET_PREFERRED_MODE: 63 | setPreferredMode(call, result); 64 | break; 65 | default: 66 | result.notImplemented(); 67 | break; 68 | } 69 | } 70 | 71 | @SuppressWarnings("deprecation") 72 | Display getDisplay() { 73 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { 74 | return activity.getDisplay(); 75 | } else { 76 | final WindowManager windowManager = (WindowManager) activity.getSystemService(Context.WINDOW_SERVICE); 77 | return windowManager.getDefaultDisplay(); 78 | } 79 | } 80 | 81 | @RequiresApi(api = Build.VERSION_CODES.M) 82 | private void getActiveMode(@NonNull Result result) { 83 | final Display.Mode mode = getDisplay().getMode(); 84 | final HashMap ret = new HashMap<>(); 85 | ret.put("id", mode.getModeId()); 86 | ret.put("width", mode.getPhysicalWidth()); 87 | ret.put("height", mode.getPhysicalHeight()); 88 | ret.put("refreshRate", mode.getRefreshRate()); 89 | result.success(ret); 90 | } 91 | 92 | @RequiresApi(api = Build.VERSION_CODES.M) 93 | private ArrayList> getSupportedModes() { 94 | final ArrayList> ret = new ArrayList<>(); 95 | final Display display = getDisplay(); 96 | final Display.Mode[] modes = display.getSupportedModes(); 97 | 98 | for (final Display.Mode mode : modes) { 99 | final HashMap item = new HashMap<>(); 100 | item.put("id", mode.getModeId()); 101 | item.put("width", mode.getPhysicalWidth()); 102 | item.put("height", mode.getPhysicalHeight()); 103 | item.put("refreshRate", mode.getRefreshRate()); 104 | ret.add(item); 105 | } 106 | return ret; 107 | } 108 | 109 | @RequiresApi(api = Build.VERSION_CODES.M) 110 | private void getSupportedModes(@NonNull Result result) { 111 | result.success(getSupportedModes()); 112 | } 113 | 114 | @RequiresApi(api = Build.VERSION_CODES.M) 115 | private void getPreferredMode(@NonNull Result result) { 116 | final Window window = activity.getWindow(); 117 | final WindowManager.LayoutParams params = window.getAttributes(); 118 | 119 | final Display display = getDisplay(); 120 | final Display.Mode[] modes = display.getSupportedModes(); 121 | 122 | // look for matching mode and return it 123 | for (final Display.Mode mode : modes) { 124 | if (params.preferredDisplayModeId == mode.getModeId()) { 125 | final HashMap item = new HashMap<>(); 126 | item.put("id", mode.getModeId()); 127 | item.put("width", mode.getPhysicalWidth()); 128 | item.put("height", mode.getPhysicalHeight()); 129 | item.put("refreshRate", mode.getRefreshRate()); 130 | result.success(item); 131 | return; 132 | } 133 | } 134 | 135 | // no match found. return as automatic 136 | final HashMap ret = new HashMap<>(); 137 | ret.put("id", 0); 138 | ret.put("width", 0); 139 | ret.put("height", 0); 140 | ret.put("refreshRate", 0.0); 141 | result.success(ret); 142 | } 143 | 144 | @RequiresApi(api = Build.VERSION_CODES.M) 145 | private void setPreferredMode(@NonNull MethodCall call, @NonNull Result result) { 146 | final int mode = call.argument("mode"); 147 | final Window window = activity.getWindow(); 148 | final WindowManager.LayoutParams params = window.getAttributes(); 149 | params.preferredDisplayModeId = mode; 150 | window.setAttributes(params); 151 | result.success(null); 152 | } 153 | 154 | private void setActivity(Activity activity) { 155 | this.activity = activity; 156 | } 157 | 158 | @Override 159 | public void onAttachedToActivity(ActivityPluginBinding binding) { 160 | activity = binding.getActivity(); 161 | } 162 | 163 | @Override 164 | public void onDetachedFromActivity() { 165 | activity = null; 166 | } 167 | 168 | @Override 169 | public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) { 170 | } 171 | 172 | @Override 173 | public void onDetachedFromActivityForConfigChanges() { 174 | onDetachedFromActivity(); 175 | } 176 | 177 | @Override 178 | public void onReattachedToActivityForConfigChanges(@NonNull ActivityPluginBinding binding) { 179 | onAttachedToActivity(binding); 180 | } 181 | } 182 | -------------------------------------------------------------------------------- /analysis_options.yaml: -------------------------------------------------------------------------------- 1 | # Specify analysis options. 2 | # 3 | # Until there are meta linter rules, each desired lint must be explicitly enabled. 4 | # See: https://github.com/dart-lang/linter/issues/288 5 | # 6 | # For a list of lints, see: http://dart-lang.github.io/linter/lints/ 7 | # See the configuration guide for more 8 | # https://github.com/dart-lang/sdk/tree/master/pkg/analyzer#configuring-the-analyzer 9 | # 10 | # There are other similar analysis options files in the flutter repos, 11 | # which should be kept in sync with this file: 12 | # 13 | # - analysis_options.yaml (this file) 14 | # - packages/flutter/lib/analysis_options_user.yaml 15 | # - https://github.com/flutter/plugins/blob/master/analysis_options.yaml 16 | # - https://github.com/flutter/engine/blob/master/analysis_options.yaml 17 | # 18 | # This file contains the analysis options used by Flutter tools, such as IntelliJ, 19 | # Android Studio, and the `flutter analyze` command. 20 | 21 | analyzer: 22 | strong-mode: 23 | implicit-casts: false 24 | implicit-dynamic: false 25 | errors: 26 | # treat missing required parameters as a warning (not a hint) 27 | missing_required_param: warning 28 | # treat missing returns as a warning (not a hint) 29 | missing_return: warning 30 | # allow having TODOs in the code 31 | todo: ignore 32 | # Ignore analyzer hints for updating pubspecs when using Future or 33 | # Stream and not importing dart:async 34 | # Please see https://github.com/flutter/flutter/pull/24528 for details. 35 | sdk_version_async_exported_from_core: ignore 36 | exclude: 37 | - "bin/cache/**" 38 | # the following two are relative to the stocks example and the flutter package respectively 39 | # see https://github.com/dart-lang/sdk/issues/28463 40 | - "lib/i18n/messages_*.dart" 41 | - "lib/src/http/**" 42 | 43 | linter: 44 | rules: 45 | # these rules are documented on and in the same order as 46 | # the Dart Lint rules page to make maintenance easier 47 | # https://github.com/dart-lang/linter/blob/master/example/all.yaml 48 | - always_declare_return_types 49 | - always_put_control_body_on_new_line 50 | # - always_put_required_named_parameters_first # we prefer having parameters in the same order as fields https://github.com/flutter/flutter/issues/10219 51 | - always_require_non_null_named_parameters 52 | - always_specify_types 53 | - annotate_overrides 54 | # - avoid_annotating_with_dynamic # conflicts with always_specify_types 55 | # - avoid_as # required for implicit-casts: true 56 | - avoid_bool_literals_in_conditional_expressions 57 | # - avoid_catches_without_on_clauses # we do this commonly 58 | # - avoid_catching_errors # we do this commonly 59 | - avoid_classes_with_only_static_members 60 | # - avoid_double_and_int_checks # only useful when targeting JS runtime 61 | - avoid_empty_else 62 | # - avoid_equals_and_hash_code_on_mutable_classes # not yet tested 63 | - avoid_field_initializers_in_const_classes 64 | - avoid_function_literals_in_foreach_calls 65 | # - avoid_implementing_value_types # not yet tested 66 | - avoid_init_to_null 67 | # - avoid_js_rounded_ints # only useful when targeting JS runtime 68 | - avoid_null_checks_in_equality_operators 69 | # - avoid_positional_boolean_parameters # not yet tested 70 | # - avoid_print # not yet tested 71 | # - avoid_private_typedef_functions # we prefer having typedef (discussion in https://github.com/flutter/flutter/pull/16356) 72 | # - avoid_redundant_argument_values # not yet tested 73 | - avoid_relative_lib_imports 74 | - avoid_renaming_method_parameters 75 | - avoid_return_types_on_setters 76 | # - avoid_returning_null # there are plenty of valid reasons to return null 77 | # - avoid_returning_null_for_future # not yet tested 78 | - avoid_returning_null_for_void 79 | # - avoid_returning_this # there are plenty of valid reasons to return this 80 | # - avoid_setters_without_getters # not yet tested 81 | # - avoid_shadowing_type_parameters # not yet tested 82 | # - avoid_single_cascade_in_expression_statements # not yet tested 83 | - avoid_slow_async_io 84 | - avoid_types_as_parameter_names 85 | # - avoid_types_on_closure_parameters # conflicts with always_specify_types 86 | # - avoid_unnecessary_containers # not yet tested 87 | - avoid_unused_constructor_parameters 88 | - avoid_void_async 89 | # - avoid_web_libraries_in_flutter # not yet tested 90 | - await_only_futures 91 | - camel_case_extensions 92 | - camel_case_types 93 | - cancel_subscriptions 94 | # - cascade_invocations # not yet tested 95 | # - close_sinks # not reliable enough 96 | # - comment_references # blocked on https://github.com/flutter/flutter/issues/20765 97 | # - constant_identifier_names # needs an opt-out https://github.com/dart-lang/linter/issues/204 98 | - control_flow_in_finally 99 | # - curly_braces_in_flow_control_structures # not yet tested 100 | # - diagnostic_describe_all_properties # not yet tested 101 | - directives_ordering 102 | - empty_catches 103 | - empty_constructor_bodies 104 | - empty_statements 105 | # - file_names # not yet tested 106 | - flutter_style_todos 107 | - hash_and_equals 108 | - implementation_imports 109 | # - invariant_booleans # too many false positives: https://github.com/dart-lang/linter/issues/811 110 | - iterable_contains_unrelated_type 111 | # - join_return_with_assignment # not yet tested 112 | - library_names 113 | - library_prefixes 114 | # - lines_longer_than_80_chars # not yet tested 115 | - list_remove_unrelated_type 116 | # - literal_only_boolean_expressions # too many false positives: https://github.com/dart-lang/sdk/issues/34181 117 | # - missing_whitespace_between_adjacent_strings # not yet tested 118 | - no_adjacent_strings_in_list 119 | - no_duplicate_case_values 120 | # - no_logic_in_create_state # not yet tested 121 | # - no_runtimeType_toString # not yet tested 122 | - non_constant_identifier_names 123 | # - null_closures # not yet tested 124 | # - omit_local_variable_types # opposite of always_specify_types 125 | # - one_member_abstracts # too many false positives 126 | # - only_throw_errors # https://github.com/flutter/flutter/issues/5792 127 | - overridden_fields 128 | - package_api_docs 129 | - package_names 130 | - package_prefixed_library_names 131 | # - parameter_assignments # we do this commonly 132 | - prefer_adjacent_string_concatenation 133 | - prefer_asserts_in_initializer_lists 134 | # - prefer_asserts_with_message # not yet tested 135 | - prefer_collection_literals 136 | - prefer_conditional_assignment 137 | - prefer_const_constructors 138 | - prefer_const_constructors_in_immutables 139 | - prefer_const_declarations 140 | - prefer_const_literals_to_create_immutables 141 | # - prefer_constructors_over_static_methods # not yet tested 142 | - prefer_contains 143 | # - prefer_double_quotes # opposite of prefer_single_quotes 144 | - prefer_equal_for_default_values 145 | # - prefer_expression_function_bodies # conflicts with https://github.com/flutter/flutter/wiki/Style-guide-for-Flutter-repo#consider-using--for-short-functions-and-methods 146 | - prefer_final_fields 147 | - prefer_final_in_for_each 148 | - prefer_final_locals 149 | - prefer_for_elements_to_map_fromIterable 150 | - prefer_foreach 151 | # - prefer_function_declarations_over_variables # not yet tested 152 | - prefer_generic_function_type_aliases 153 | - prefer_if_elements_to_conditional_expressions 154 | - prefer_if_null_operators 155 | - prefer_initializing_formals 156 | - prefer_inlined_adds 157 | # - prefer_int_literals # not yet tested 158 | # - prefer_interpolation_to_compose_strings # not yet tested 159 | - prefer_is_empty 160 | - prefer_is_not_empty 161 | - prefer_is_not_operator 162 | - prefer_iterable_whereType 163 | # - prefer_mixin # https://github.com/dart-lang/language/issues/32 164 | # - prefer_null_aware_operators # disable until NNBD, see https://github.com/flutter/flutter/pull/32711#issuecomment-492930932 165 | # - prefer_relative_imports # not yet tested 166 | - prefer_single_quotes 167 | - prefer_spread_collections 168 | - prefer_typing_uninitialized_variables 169 | - prefer_void_to_null 170 | # - provide_deprecation_message # not yet tested 171 | # - public_member_api_docs # enabled on a case-by-case basis; see e.g. packages/analysis_options.yaml 172 | - recursive_getters 173 | - slash_for_doc_comments 174 | # - sort_child_properties_last # not yet tested 175 | - sort_constructors_first 176 | - sort_pub_dependencies 177 | - sort_unnamed_constructors_first 178 | - test_types_in_equals 179 | - throw_in_finally 180 | # - type_annotate_public_apis # subset of always_specify_types 181 | - type_init_formals 182 | # - unawaited_futures # too many false positives 183 | # - unnecessary_await_in_return # not yet tested 184 | - unnecessary_brace_in_string_interps 185 | - unnecessary_const 186 | # - unnecessary_final # conflicts with prefer_final_locals 187 | - unnecessary_getters_setters 188 | # - unnecessary_lambdas # has false positives: https://github.com/dart-lang/linter/issues/498 189 | - unnecessary_new 190 | - unnecessary_null_aware_assignments 191 | - unnecessary_null_in_if_null_operators 192 | - unnecessary_overrides 193 | - unnecessary_parenthesis 194 | - unnecessary_statements 195 | # - unnecessary_string_interpolations 196 | - unnecessary_this 197 | - unrelated_type_equality_checks 198 | # - unsafe_html # not yet tested 199 | - use_full_hex_values_for_flutter_colors 200 | # - use_function_type_syntax_for_parameters # not yet tested 201 | # - use_key_in_widget_constructors # not yet tested 202 | - use_rethrow_when_possible 203 | # - use_setters_to_change_properties # not yet tested 204 | # - use_string_buffers # has false positives: https://github.com/dart-lang/sdk/issues/34182 205 | # - use_to_and_as_if_applicable # has false positives, so we prefer to catch this by code-review 206 | - valid_regexps 207 | - void_checks -------------------------------------------------------------------------------- /example/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 | 3B80C3941E831B6300D905FE /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; }; 13 | 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 14 | 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; 15 | 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; }; 16 | 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 17 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 18 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 19 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; 20 | /* End PBXBuildFile section */ 21 | 22 | /* Begin PBXCopyFilesBuildPhase section */ 23 | 9705A1C41CF9048500538489 /* Embed Frameworks */ = { 24 | isa = PBXCopyFilesBuildPhase; 25 | buildActionMask = 2147483647; 26 | dstPath = ""; 27 | dstSubfolderSpec = 10; 28 | files = ( 29 | 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */, 30 | 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */, 31 | ); 32 | name = "Embed Frameworks"; 33 | runOnlyForDeploymentPostprocessing = 0; 34 | }; 35 | /* End PBXCopyFilesBuildPhase section */ 36 | 37 | /* Begin PBXFileReference section */ 38 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; 39 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; 40 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; 41 | 3B80C3931E831B6300D905FE /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/App.framework; sourceTree = ""; }; 42 | 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; 43 | 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 44 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; 45 | 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; 46 | 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; 47 | 9740EEBA1CF902C7004384FC /* Flutter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Flutter.framework; path = Flutter/Flutter.framework; sourceTree = ""; }; 48 | 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; 49 | 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 50 | 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 51 | 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 52 | 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 53 | /* End PBXFileReference section */ 54 | 55 | /* Begin PBXFrameworksBuildPhase section */ 56 | 97C146EB1CF9000F007C117D /* Frameworks */ = { 57 | isa = PBXFrameworksBuildPhase; 58 | buildActionMask = 2147483647; 59 | files = ( 60 | 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */, 61 | 3B80C3941E831B6300D905FE /* App.framework in Frameworks */, 62 | ); 63 | runOnlyForDeploymentPostprocessing = 0; 64 | }; 65 | /* End PBXFrameworksBuildPhase section */ 66 | 67 | /* Begin PBXGroup section */ 68 | 9740EEB11CF90186004384FC /* Flutter */ = { 69 | isa = PBXGroup; 70 | children = ( 71 | 3B80C3931E831B6300D905FE /* App.framework */, 72 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, 73 | 9740EEBA1CF902C7004384FC /* Flutter.framework */, 74 | 9740EEB21CF90195004384FC /* Debug.xcconfig */, 75 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, 76 | 9740EEB31CF90195004384FC /* Generated.xcconfig */, 77 | ); 78 | name = Flutter; 79 | sourceTree = ""; 80 | }; 81 | 97C146E51CF9000F007C117D = { 82 | isa = PBXGroup; 83 | children = ( 84 | 9740EEB11CF90186004384FC /* Flutter */, 85 | 97C146F01CF9000F007C117D /* Runner */, 86 | 97C146EF1CF9000F007C117D /* Products */, 87 | ); 88 | sourceTree = ""; 89 | }; 90 | 97C146EF1CF9000F007C117D /* Products */ = { 91 | isa = PBXGroup; 92 | children = ( 93 | 97C146EE1CF9000F007C117D /* Runner.app */, 94 | ); 95 | name = Products; 96 | sourceTree = ""; 97 | }; 98 | 97C146F01CF9000F007C117D /* Runner */ = { 99 | isa = PBXGroup; 100 | children = ( 101 | 97C146FA1CF9000F007C117D /* Main.storyboard */, 102 | 97C146FD1CF9000F007C117D /* Assets.xcassets */, 103 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, 104 | 97C147021CF9000F007C117D /* Info.plist */, 105 | 97C146F11CF9000F007C117D /* Supporting Files */, 106 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, 107 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, 108 | 74858FAE1ED2DC5600515810 /* AppDelegate.swift */, 109 | 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */, 110 | ); 111 | path = Runner; 112 | sourceTree = ""; 113 | }; 114 | 97C146F11CF9000F007C117D /* Supporting Files */ = { 115 | isa = PBXGroup; 116 | children = ( 117 | ); 118 | name = "Supporting Files"; 119 | sourceTree = ""; 120 | }; 121 | /* End PBXGroup section */ 122 | 123 | /* Begin PBXNativeTarget section */ 124 | 97C146ED1CF9000F007C117D /* Runner */ = { 125 | isa = PBXNativeTarget; 126 | buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; 127 | buildPhases = ( 128 | 9740EEB61CF901F6004384FC /* Run Script */, 129 | 97C146EA1CF9000F007C117D /* Sources */, 130 | 97C146EB1CF9000F007C117D /* Frameworks */, 131 | 97C146EC1CF9000F007C117D /* Resources */, 132 | 9705A1C41CF9048500538489 /* Embed Frameworks */, 133 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */, 134 | ); 135 | buildRules = ( 136 | ); 137 | dependencies = ( 138 | ); 139 | name = Runner; 140 | productName = Runner; 141 | productReference = 97C146EE1CF9000F007C117D /* Runner.app */; 142 | productType = "com.apple.product-type.application"; 143 | }; 144 | /* End PBXNativeTarget section */ 145 | 146 | /* Begin PBXProject section */ 147 | 97C146E61CF9000F007C117D /* Project object */ = { 148 | isa = PBXProject; 149 | attributes = { 150 | LastUpgradeCheck = 1020; 151 | ORGANIZATIONNAME = "The Chromium Authors"; 152 | TargetAttributes = { 153 | 97C146ED1CF9000F007C117D = { 154 | CreatedOnToolsVersion = 7.3.1; 155 | LastSwiftMigration = 1100; 156 | }; 157 | }; 158 | }; 159 | buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; 160 | compatibilityVersion = "Xcode 3.2"; 161 | developmentRegion = en; 162 | hasScannedForEncodings = 0; 163 | knownRegions = ( 164 | en, 165 | Base, 166 | ); 167 | mainGroup = 97C146E51CF9000F007C117D; 168 | productRefGroup = 97C146EF1CF9000F007C117D /* Products */; 169 | projectDirPath = ""; 170 | projectRoot = ""; 171 | targets = ( 172 | 97C146ED1CF9000F007C117D /* Runner */, 173 | ); 174 | }; 175 | /* End PBXProject section */ 176 | 177 | /* Begin PBXResourcesBuildPhase section */ 178 | 97C146EC1CF9000F007C117D /* Resources */ = { 179 | isa = PBXResourcesBuildPhase; 180 | buildActionMask = 2147483647; 181 | files = ( 182 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, 183 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, 184 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, 185 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, 186 | ); 187 | runOnlyForDeploymentPostprocessing = 0; 188 | }; 189 | /* End PBXResourcesBuildPhase section */ 190 | 191 | /* Begin PBXShellScriptBuildPhase section */ 192 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { 193 | isa = PBXShellScriptBuildPhase; 194 | buildActionMask = 2147483647; 195 | files = ( 196 | ); 197 | inputPaths = ( 198 | ); 199 | name = "Thin Binary"; 200 | outputPaths = ( 201 | ); 202 | runOnlyForDeploymentPostprocessing = 0; 203 | shellPath = /bin/sh; 204 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" thin"; 205 | }; 206 | 9740EEB61CF901F6004384FC /* Run Script */ = { 207 | isa = PBXShellScriptBuildPhase; 208 | buildActionMask = 2147483647; 209 | files = ( 210 | ); 211 | inputPaths = ( 212 | ); 213 | name = "Run Script"; 214 | outputPaths = ( 215 | ); 216 | runOnlyForDeploymentPostprocessing = 0; 217 | shellPath = /bin/sh; 218 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; 219 | }; 220 | /* End PBXShellScriptBuildPhase section */ 221 | 222 | /* Begin PBXSourcesBuildPhase section */ 223 | 97C146EA1CF9000F007C117D /* Sources */ = { 224 | isa = PBXSourcesBuildPhase; 225 | buildActionMask = 2147483647; 226 | files = ( 227 | 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */, 228 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, 229 | ); 230 | runOnlyForDeploymentPostprocessing = 0; 231 | }; 232 | /* End PBXSourcesBuildPhase section */ 233 | 234 | /* Begin PBXVariantGroup section */ 235 | 97C146FA1CF9000F007C117D /* Main.storyboard */ = { 236 | isa = PBXVariantGroup; 237 | children = ( 238 | 97C146FB1CF9000F007C117D /* Base */, 239 | ); 240 | name = Main.storyboard; 241 | sourceTree = ""; 242 | }; 243 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { 244 | isa = PBXVariantGroup; 245 | children = ( 246 | 97C147001CF9000F007C117D /* Base */, 247 | ); 248 | name = LaunchScreen.storyboard; 249 | sourceTree = ""; 250 | }; 251 | /* End PBXVariantGroup section */ 252 | 253 | /* Begin XCBuildConfiguration section */ 254 | 249021D3217E4FDB00AE95B9 /* Profile */ = { 255 | isa = XCBuildConfiguration; 256 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 257 | buildSettings = { 258 | ALWAYS_SEARCH_USER_PATHS = NO; 259 | CLANG_ANALYZER_NONNULL = YES; 260 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 261 | CLANG_CXX_LIBRARY = "libc++"; 262 | CLANG_ENABLE_MODULES = YES; 263 | CLANG_ENABLE_OBJC_ARC = YES; 264 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 265 | CLANG_WARN_BOOL_CONVERSION = YES; 266 | CLANG_WARN_COMMA = YES; 267 | CLANG_WARN_CONSTANT_CONVERSION = YES; 268 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 269 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 270 | CLANG_WARN_EMPTY_BODY = YES; 271 | CLANG_WARN_ENUM_CONVERSION = YES; 272 | CLANG_WARN_INFINITE_RECURSION = YES; 273 | CLANG_WARN_INT_CONVERSION = YES; 274 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 275 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 276 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 277 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 278 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 279 | CLANG_WARN_STRICT_PROTOTYPES = YES; 280 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 281 | CLANG_WARN_UNREACHABLE_CODE = YES; 282 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 283 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 284 | COPY_PHASE_STRIP = NO; 285 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 286 | ENABLE_NS_ASSERTIONS = NO; 287 | ENABLE_STRICT_OBJC_MSGSEND = YES; 288 | GCC_C_LANGUAGE_STANDARD = gnu99; 289 | GCC_NO_COMMON_BLOCKS = YES; 290 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 291 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 292 | GCC_WARN_UNDECLARED_SELECTOR = YES; 293 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 294 | GCC_WARN_UNUSED_FUNCTION = YES; 295 | GCC_WARN_UNUSED_VARIABLE = YES; 296 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 297 | MTL_ENABLE_DEBUG_INFO = NO; 298 | SDKROOT = iphoneos; 299 | SUPPORTED_PLATFORMS = iphoneos; 300 | TARGETED_DEVICE_FAMILY = "1,2"; 301 | VALIDATE_PRODUCT = YES; 302 | }; 303 | name = Profile; 304 | }; 305 | 249021D4217E4FDB00AE95B9 /* Profile */ = { 306 | isa = XCBuildConfiguration; 307 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 308 | buildSettings = { 309 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 310 | CLANG_ENABLE_MODULES = YES; 311 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 312 | ENABLE_BITCODE = NO; 313 | FRAMEWORK_SEARCH_PATHS = ( 314 | "$(inherited)", 315 | "$(PROJECT_DIR)/Flutter", 316 | ); 317 | INFOPLIST_FILE = Runner/Info.plist; 318 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 319 | LIBRARY_SEARCH_PATHS = ( 320 | "$(inherited)", 321 | "$(PROJECT_DIR)/Flutter", 322 | ); 323 | PRODUCT_BUNDLE_IDENTIFIER = com.ajinasokan.flutterdisplaymodeExample; 324 | PRODUCT_NAME = "$(TARGET_NAME)"; 325 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; 326 | SWIFT_VERSION = 5.0; 327 | VERSIONING_SYSTEM = "apple-generic"; 328 | }; 329 | name = Profile; 330 | }; 331 | 97C147031CF9000F007C117D /* Debug */ = { 332 | isa = XCBuildConfiguration; 333 | baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; 334 | buildSettings = { 335 | ALWAYS_SEARCH_USER_PATHS = NO; 336 | CLANG_ANALYZER_NONNULL = YES; 337 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 338 | CLANG_CXX_LIBRARY = "libc++"; 339 | CLANG_ENABLE_MODULES = YES; 340 | CLANG_ENABLE_OBJC_ARC = YES; 341 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 342 | CLANG_WARN_BOOL_CONVERSION = YES; 343 | CLANG_WARN_COMMA = YES; 344 | CLANG_WARN_CONSTANT_CONVERSION = YES; 345 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 346 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 347 | CLANG_WARN_EMPTY_BODY = YES; 348 | CLANG_WARN_ENUM_CONVERSION = YES; 349 | CLANG_WARN_INFINITE_RECURSION = YES; 350 | CLANG_WARN_INT_CONVERSION = YES; 351 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 352 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 353 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 354 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 355 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 356 | CLANG_WARN_STRICT_PROTOTYPES = YES; 357 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 358 | CLANG_WARN_UNREACHABLE_CODE = YES; 359 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 360 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 361 | COPY_PHASE_STRIP = NO; 362 | DEBUG_INFORMATION_FORMAT = dwarf; 363 | ENABLE_STRICT_OBJC_MSGSEND = YES; 364 | ENABLE_TESTABILITY = YES; 365 | GCC_C_LANGUAGE_STANDARD = gnu99; 366 | GCC_DYNAMIC_NO_PIC = NO; 367 | GCC_NO_COMMON_BLOCKS = YES; 368 | GCC_OPTIMIZATION_LEVEL = 0; 369 | GCC_PREPROCESSOR_DEFINITIONS = ( 370 | "DEBUG=1", 371 | "$(inherited)", 372 | ); 373 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 374 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 375 | GCC_WARN_UNDECLARED_SELECTOR = YES; 376 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 377 | GCC_WARN_UNUSED_FUNCTION = YES; 378 | GCC_WARN_UNUSED_VARIABLE = YES; 379 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 380 | MTL_ENABLE_DEBUG_INFO = YES; 381 | ONLY_ACTIVE_ARCH = YES; 382 | SDKROOT = iphoneos; 383 | TARGETED_DEVICE_FAMILY = "1,2"; 384 | }; 385 | name = Debug; 386 | }; 387 | 97C147041CF9000F007C117D /* Release */ = { 388 | isa = XCBuildConfiguration; 389 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 390 | buildSettings = { 391 | ALWAYS_SEARCH_USER_PATHS = NO; 392 | CLANG_ANALYZER_NONNULL = YES; 393 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 394 | CLANG_CXX_LIBRARY = "libc++"; 395 | CLANG_ENABLE_MODULES = YES; 396 | CLANG_ENABLE_OBJC_ARC = YES; 397 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 398 | CLANG_WARN_BOOL_CONVERSION = YES; 399 | CLANG_WARN_COMMA = YES; 400 | CLANG_WARN_CONSTANT_CONVERSION = YES; 401 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 402 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 403 | CLANG_WARN_EMPTY_BODY = YES; 404 | CLANG_WARN_ENUM_CONVERSION = YES; 405 | CLANG_WARN_INFINITE_RECURSION = YES; 406 | CLANG_WARN_INT_CONVERSION = YES; 407 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 408 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 409 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 410 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 411 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 412 | CLANG_WARN_STRICT_PROTOTYPES = YES; 413 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 414 | CLANG_WARN_UNREACHABLE_CODE = YES; 415 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 416 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 417 | COPY_PHASE_STRIP = NO; 418 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 419 | ENABLE_NS_ASSERTIONS = NO; 420 | ENABLE_STRICT_OBJC_MSGSEND = YES; 421 | GCC_C_LANGUAGE_STANDARD = gnu99; 422 | GCC_NO_COMMON_BLOCKS = YES; 423 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 424 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 425 | GCC_WARN_UNDECLARED_SELECTOR = YES; 426 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 427 | GCC_WARN_UNUSED_FUNCTION = YES; 428 | GCC_WARN_UNUSED_VARIABLE = YES; 429 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 430 | MTL_ENABLE_DEBUG_INFO = NO; 431 | SDKROOT = iphoneos; 432 | SUPPORTED_PLATFORMS = iphoneos; 433 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 434 | TARGETED_DEVICE_FAMILY = "1,2"; 435 | VALIDATE_PRODUCT = YES; 436 | }; 437 | name = Release; 438 | }; 439 | 97C147061CF9000F007C117D /* Debug */ = { 440 | isa = XCBuildConfiguration; 441 | baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; 442 | buildSettings = { 443 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 444 | CLANG_ENABLE_MODULES = YES; 445 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 446 | ENABLE_BITCODE = NO; 447 | FRAMEWORK_SEARCH_PATHS = ( 448 | "$(inherited)", 449 | "$(PROJECT_DIR)/Flutter", 450 | ); 451 | INFOPLIST_FILE = Runner/Info.plist; 452 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 453 | LIBRARY_SEARCH_PATHS = ( 454 | "$(inherited)", 455 | "$(PROJECT_DIR)/Flutter", 456 | ); 457 | PRODUCT_BUNDLE_IDENTIFIER = com.ajinasokan.flutterdisplaymodeExample; 458 | PRODUCT_NAME = "$(TARGET_NAME)"; 459 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; 460 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 461 | SWIFT_VERSION = 5.0; 462 | VERSIONING_SYSTEM = "apple-generic"; 463 | }; 464 | name = Debug; 465 | }; 466 | 97C147071CF9000F007C117D /* Release */ = { 467 | isa = XCBuildConfiguration; 468 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 469 | buildSettings = { 470 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 471 | CLANG_ENABLE_MODULES = YES; 472 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 473 | ENABLE_BITCODE = NO; 474 | FRAMEWORK_SEARCH_PATHS = ( 475 | "$(inherited)", 476 | "$(PROJECT_DIR)/Flutter", 477 | ); 478 | INFOPLIST_FILE = Runner/Info.plist; 479 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 480 | LIBRARY_SEARCH_PATHS = ( 481 | "$(inherited)", 482 | "$(PROJECT_DIR)/Flutter", 483 | ); 484 | PRODUCT_BUNDLE_IDENTIFIER = com.ajinasokan.flutterdisplaymodeExample; 485 | PRODUCT_NAME = "$(TARGET_NAME)"; 486 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; 487 | SWIFT_VERSION = 5.0; 488 | VERSIONING_SYSTEM = "apple-generic"; 489 | }; 490 | name = Release; 491 | }; 492 | /* End XCBuildConfiguration section */ 493 | 494 | /* Begin XCConfigurationList section */ 495 | 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { 496 | isa = XCConfigurationList; 497 | buildConfigurations = ( 498 | 97C147031CF9000F007C117D /* Debug */, 499 | 97C147041CF9000F007C117D /* Release */, 500 | 249021D3217E4FDB00AE95B9 /* Profile */, 501 | ); 502 | defaultConfigurationIsVisible = 0; 503 | defaultConfigurationName = Release; 504 | }; 505 | 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { 506 | isa = XCConfigurationList; 507 | buildConfigurations = ( 508 | 97C147061CF9000F007C117D /* Debug */, 509 | 97C147071CF9000F007C117D /* Release */, 510 | 249021D4217E4FDB00AE95B9 /* Profile */, 511 | ); 512 | defaultConfigurationIsVisible = 0; 513 | defaultConfigurationName = Release; 514 | }; 515 | /* End XCConfigurationList section */ 516 | }; 517 | rootObject = 97C146E61CF9000F007C117D /* Project object */; 518 | } 519 | --------------------------------------------------------------------------------