├── .firebaserc ├── .gitignore ├── .metadata ├── README.md ├── analysis_options.yaml ├── android ├── .gitignore ├── app │ ├── build.gradle │ └── src │ │ ├── debug │ │ └── AndroidManifest.xml │ │ ├── main │ │ ├── AndroidManifest.xml │ │ ├── kotlin │ │ │ └── com │ │ │ │ └── example │ │ │ │ └── hms_callkit │ │ │ │ └── MainActivity.kt │ │ └── res │ │ │ ├── drawable-v21 │ │ │ └── launch_background.xml │ │ │ ├── drawable │ │ │ └── launch_background.xml │ │ │ ├── mipmap-hdpi │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-mdpi │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-xhdpi │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-xxhdpi │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-xxxhdpi │ │ │ └── ic_launcher.png │ │ │ ├── values-night │ │ │ └── styles.xml │ │ │ └── values │ │ │ └── styles.xml │ │ └── profile │ │ └── AndroidManifest.xml ├── build.gradle ├── gradle.properties ├── gradle │ └── wrapper │ │ └── gradle-wrapper.properties └── settings.gradle ├── firebase.json ├── functions ├── .eslintrc.js ├── .gitignore ├── index.js ├── package-lock.json └── package.json ├── ios ├── .gitignore ├── Flutter │ ├── AppFrameworkInfo.plist │ ├── Debug.xcconfig │ └── Release.xcconfig ├── Podfile ├── Podfile.lock ├── Runner.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ ├── IDEWorkspaceChecks.plist │ │ │ ├── WorkspaceSettings.xcsettings │ │ │ └── swiftpm │ │ │ └── Package.resolved │ └── xcshareddata │ │ └── xcschemes │ │ └── Runner.xcscheme ├── Runner.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ ├── IDEWorkspaceChecks.plist │ │ └── WorkspaceSettings.xcsettings ├── Runner │ ├── AppDelegate.swift │ ├── Assets.xcassets │ │ ├── AppIcon.appiconset │ │ │ ├── Contents.json │ │ │ ├── Icon-App-1024x1024@1x.png │ │ │ ├── Icon-App-20x20@1x.png │ │ │ ├── Icon-App-20x20@2x.png │ │ │ ├── Icon-App-20x20@3x.png │ │ │ ├── Icon-App-29x29@1x.png │ │ │ ├── Icon-App-29x29@2x.png │ │ │ ├── Icon-App-29x29@3x.png │ │ │ ├── Icon-App-40x40@1x.png │ │ │ ├── Icon-App-40x40@2x.png │ │ │ ├── Icon-App-40x40@3x.png │ │ │ ├── Icon-App-60x60@2x.png │ │ │ ├── Icon-App-60x60@3x.png │ │ │ ├── Icon-App-76x76@1x.png │ │ │ ├── Icon-App-76x76@2x.png │ │ │ └── Icon-App-83.5x83.5@2x.png │ │ └── LaunchImage.imageset │ │ │ ├── Contents.json │ │ │ ├── LaunchImage.png │ │ │ ├── LaunchImage@2x.png │ │ │ ├── LaunchImage@3x.png │ │ │ └── README.md │ ├── Base.lproj │ │ ├── LaunchScreen.storyboard │ │ └── Main.storyboard │ ├── GoogleService-Info.plist │ ├── Info.plist │ ├── Runner-Bridging-Header.h │ └── Runner.entitlements └── firebase_app_id_file.json ├── lib ├── app_navigation │ ├── app_router.dart │ └── navigation_service.dart ├── firebase_options.dart ├── hmssdk │ ├── hmssdk_interactor.dart │ ├── join_service.dart │ ├── meeting_page.dart │ └── preview_page.dart ├── home_page.dart ├── main.dart ├── receive_call.dart └── utility_functions.dart ├── pubspec.lock ├── pubspec.yaml └── test └── widget_test.dart /.firebaserc: -------------------------------------------------------------------------------- 1 | { 2 | "projects": { 3 | "default": "hms-callkit-dd0c9" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.log 4 | *.pyc 5 | *.swp 6 | .DS_Store 7 | .atom/ 8 | .buildlog/ 9 | .history 10 | .svn/ 11 | migrate_working_dir/ 12 | 13 | # IntelliJ related 14 | *.iml 15 | *.ipr 16 | *.iws 17 | .idea/ 18 | 19 | # The .vscode folder contains launch configuration and tasks you configure in 20 | # VS Code which you may wish to be included in version control, so this line 21 | # is commented out by default. 22 | #.vscode/ 23 | 24 | # Flutter/Dart/Pub related 25 | **/doc/api/ 26 | **/ios/Flutter/.last_build_id 27 | .dart_tool/ 28 | .flutter-plugins 29 | .flutter-plugins-dependencies 30 | .packages 31 | .pub-cache/ 32 | .pub/ 33 | /build/ 34 | /android/app/google-services.json 35 | /ios/GoogleService-Info.plist 36 | 37 | # Symbolication related 38 | app.*.symbols 39 | 40 | # Obfuscation related 41 | app.*.map.json 42 | 43 | # Android Studio will place build artifacts here 44 | /android/app/debug 45 | /android/app/profile 46 | /android/app/release 47 | -------------------------------------------------------------------------------- /.metadata: -------------------------------------------------------------------------------- 1 | # This file tracks properties of this Flutter project. 2 | # Used by Flutter tool to assess capabilities and perform upgrades etc. 3 | # 4 | # This file should be version controlled. 5 | 6 | version: 7 | revision: b06b8b2710955028a6b562f5aa6fe62941d6febf 8 | channel: stable 9 | 10 | project_type: app 11 | 12 | # Tracks metadata for the flutter migrate command 13 | migration: 14 | platforms: 15 | - platform: root 16 | create_revision: b06b8b2710955028a6b562f5aa6fe62941d6febf 17 | base_revision: b06b8b2710955028a6b562f5aa6fe62941d6febf 18 | - platform: android 19 | create_revision: b06b8b2710955028a6b562f5aa6fe62941d6febf 20 | base_revision: b06b8b2710955028a6b562f5aa6fe62941d6febf 21 | - platform: ios 22 | create_revision: b06b8b2710955028a6b562f5aa6fe62941d6febf 23 | base_revision: b06b8b2710955028a6b562f5aa6fe62941d6febf 24 | - platform: linux 25 | create_revision: b06b8b2710955028a6b562f5aa6fe62941d6febf 26 | base_revision: b06b8b2710955028a6b562f5aa6fe62941d6febf 27 | - platform: macos 28 | create_revision: b06b8b2710955028a6b562f5aa6fe62941d6febf 29 | base_revision: b06b8b2710955028a6b562f5aa6fe62941d6febf 30 | - platform: web 31 | create_revision: b06b8b2710955028a6b562f5aa6fe62941d6febf 32 | base_revision: b06b8b2710955028a6b562f5aa6fe62941d6febf 33 | - platform: windows 34 | create_revision: b06b8b2710955028a6b562f5aa6fe62941d6febf 35 | base_revision: b06b8b2710955028a6b562f5aa6fe62941d6febf 36 | 37 | # User provided section 38 | 39 | # List of Local paths (relative to this file) that should be 40 | # ignored by the migrate tool. 41 | # 42 | # Files that are not part of the templates will be ignored by default. 43 | unmanaged_files: 44 | - 'lib/main.dart' 45 | - 'ios/Runner.xcodeproj/project.pbxproj' 46 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # One To One Call Application 2 | 3 | A sample project for calling made with 100ms and flutter_callkit_incoming. 4 | 5 | https://github.com/Decoder07/hms-callkit-demo/assets/93931528/69bd9d0f-65e9-46cd-a50c-4ac7ea9a6446 6 | 7 | 8 | ## Getting Started 9 | 10 | - Clone the repo 11 | - Run flutter pub get 12 | - Setup 100ms token service 13 | - Setup firebase service for notifications 14 | 15 | That's it now to run the project execute `flutter run` 16 | 17 | ## How to test 18 | 19 | To test the application install the app in two devices. 20 | 21 | - Copy the code(FCM token) from one device. Let's call it Device-1 22 | - Paste this token on different device. Let's call this Device-2 23 | - Press the Call Now button on Device-1 24 | - You will receive a notification on Device-2 25 | - Accept the call on Device-2 26 | 27 | ### Setup 100ms token service 28 | 29 | 100ms token service takes care of joining room once you receive a call or you wish to call someone. 30 | We will need an authentication token to join the room which we will also send to other peer through payload by which the receiver can also join the room. You can find the code for this in `join_service.dart`. 31 | 32 | Here's the code for this: 33 | 34 | ```dart 35 | Future getAuthToken({required String roomId,required String tokenEndpoint,required String userId,required String role}) async { 36 | Uri endPoint = Uri.parse( 37 | tokenEndpoint); 38 | http.Response response = await http.post(endPoint, 39 | body: {'user_id': userId, 'room_id': roomId, 'role': role}); 40 | var body = json.decode(response.body); 41 | return body['token']; 42 | } 43 | ``` 44 | 45 | `getAuthToken` returns the authentication token which we will use for joining the room and also share with the receiver for him to join the room. 46 | 47 | Let's understand the parameters of this function: 48 | 49 | - roomId 50 | 51 | `roomId` refers to the room which you wish to join. You can find the roomId in dashboard's rooms section. 52 | 53 | - tokenEndpoint 54 | 55 | `tokenEndpoint` is the url which is used to get the authentication token. You can find the `tokenEndpoint` in developer section of 100ms dashboard. 56 | 57 | - userId 58 | 59 | `userId` can be used to uniquely identify user to perform any specific actions on that user later on. 60 | 61 | - role 62 | 63 | `role` refers the role which you wish to join the room. Ensure that the given role is present in the room template for given roomId. 64 | 65 | ### Setup firebase service for notifications 66 | 67 | First create a project on firebase. You can find the steps [here](https://medium.com/enappd/adding-firebase-to-your-flutter-app-281b8f391b47) 68 | 69 | Since we will be using firebase messaging to deliver notifications ensure that you have a `blaze plan` enabled on firebase and please enable `cloud messaging` and `Firebase Cloud Messaging API` from firebase cloud console. 70 | 71 | ![cloud-console](https://user-images.githubusercontent.com/93931528/218379651-d35036ff-98f2-4b6c-a298-4a229d3326b7.jpeg) 72 | 73 | For setting up firebase notifications please follow [this](https://quickcoder.org/flutter-push-notifications/) 74 | 75 | The repo already contains a `functions` folder which has the firebase functions so you can directly deploy them. 76 | 77 | That's it you are all set for running the application. 78 | 79 | Have any issues. Please reach out to us over [discord](https://100ms.live/discord) 80 | -------------------------------------------------------------------------------- /analysis_options.yaml: -------------------------------------------------------------------------------- 1 | # This file configures the analyzer, which statically analyzes Dart code to 2 | # check for errors, warnings, and lints. 3 | # 4 | # The issues identified by the analyzer are surfaced in the UI of Dart-enabled 5 | # IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be 6 | # invoked from the command line by running `flutter analyze`. 7 | 8 | # The following line activates a set of recommended lints for Flutter apps, 9 | # packages, and plugins designed to encourage good coding practices. 10 | include: package:flutter_lints/flutter.yaml 11 | 12 | linter: 13 | # The lint rules applied to this project can be customized in the 14 | # section below to disable rules from the `package:flutter_lints/flutter.yaml` 15 | # included above or to enable additional rules. A list of all available lints 16 | # and their documentation is published at 17 | # https://dart-lang.github.io/linter/lints/index.html. 18 | # 19 | # Instead of disabling a lint rule for the entire project in the 20 | # section below, it can also be suppressed for a single line of code 21 | # or a specific dart file by using the `// ignore: name_of_lint` and 22 | # `// ignore_for_file: name_of_lint` syntax on the line or in the file 23 | # producing the lint. 24 | rules: 25 | # avoid_print: false # Uncomment to disable the `avoid_print` rule 26 | # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule 27 | 28 | # Additional information about this file can be found at 29 | # https://dart.dev/guides/language/analysis-options 30 | -------------------------------------------------------------------------------- /android/.gitignore: -------------------------------------------------------------------------------- 1 | gradle-wrapper.jar 2 | /.gradle 3 | /captures/ 4 | /gradlew 5 | /gradlew.bat 6 | /local.properties 7 | GeneratedPluginRegistrant.java 8 | 9 | # Remember to never publicly share your keystore. 10 | # See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app 11 | key.properties 12 | **/*.keystore 13 | **/*.jks 14 | -------------------------------------------------------------------------------- /android/app/build.gradle: -------------------------------------------------------------------------------- 1 | def localProperties = new Properties() 2 | def localPropertiesFile = rootProject.file('local.properties') 3 | if (localPropertiesFile.exists()) { 4 | localPropertiesFile.withReader('UTF-8') { reader -> 5 | localProperties.load(reader) 6 | } 7 | } 8 | 9 | def flutterRoot = localProperties.getProperty('flutter.sdk') 10 | if (flutterRoot == null) { 11 | throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") 12 | } 13 | 14 | def flutterVersionCode = localProperties.getProperty('flutter.versionCode') 15 | if (flutterVersionCode == null) { 16 | flutterVersionCode = '1' 17 | } 18 | 19 | def flutterVersionName = localProperties.getProperty('flutter.versionName') 20 | if (flutterVersionName == null) { 21 | flutterVersionName = '1.0' 22 | } 23 | 24 | apply plugin: 'com.android.application' 25 | apply plugin: 'com.google.gms.google-services' 26 | apply plugin: 'kotlin-android' 27 | apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" 28 | 29 | android { 30 | compileSdkVersion flutter.compileSdkVersion 31 | ndkVersion flutter.ndkVersion 32 | 33 | compileOptions { 34 | sourceCompatibility JavaVersion.VERSION_1_8 35 | targetCompatibility JavaVersion.VERSION_1_8 36 | } 37 | 38 | kotlinOptions { 39 | jvmTarget = '1.8' 40 | } 41 | 42 | sourceSets { 43 | main.java.srcDirs += 'src/main/kotlin' 44 | } 45 | 46 | defaultConfig { 47 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). 48 | applicationId "com.example.hms_callkit" 49 | // You can update the following values to match your application needs. 50 | // For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration. 51 | minSdkVersion 21 52 | targetSdkVersion 33 53 | versionCode flutterVersionCode.toInteger() 54 | versionName flutterVersionName 55 | } 56 | 57 | buildTypes { 58 | release { 59 | // TODO: Add your own signing config for the release build. 60 | // Signing with the debug keys for now, so `flutter run --release` works. 61 | signingConfig signingConfigs.debug 62 | } 63 | } 64 | } 65 | 66 | flutter { 67 | source '../..' 68 | } 69 | 70 | dependencies { 71 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" 72 | implementation platform('com.google.firebase:firebase-bom:31.2.0') 73 | implementation 'com.google.firebase:firebase-analytics-ktx' 74 | } 75 | -------------------------------------------------------------------------------- /android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 7 | 15 | 19 | 23 | 24 | 25 | 26 | 27 | 28 | 30 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /android/app/src/main/kotlin/com/example/hms_callkit/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package com.example.hms_callkit 2 | 3 | import io.flutter.embedding.android.FlutterActivity 4 | 5 | class MainActivity: FlutterActivity() { 6 | } 7 | -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-v21/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /android/app/src/main/res/drawable/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Decoder07/hms-callkit-demo/4cdbfee6d2bd443985aa9bfe436a1b30bf0c641a/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Decoder07/hms-callkit-demo/4cdbfee6d2bd443985aa9bfe436a1b30bf0c641a/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Decoder07/hms-callkit-demo/4cdbfee6d2bd443985aa9bfe436a1b30bf0c641a/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Decoder07/hms-callkit-demo/4cdbfee6d2bd443985aa9bfe436a1b30bf0c641a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Decoder07/hms-callkit-demo/4cdbfee6d2bd443985aa9bfe436a1b30bf0c641a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/values-night/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /android/app/src/profile/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /android/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | ext.kotlin_version = '1.7.10' 3 | repositories { 4 | google() 5 | mavenCentral() 6 | } 7 | 8 | dependencies { 9 | classpath 'com.android.tools.build:gradle:7.2.0' 10 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" 11 | classpath 'com.google.gms:google-services:4.3.15' 12 | } 13 | } 14 | 15 | allprojects { 16 | repositories { 17 | google() 18 | mavenCentral() 19 | } 20 | } 21 | 22 | rootProject.buildDir = '../build' 23 | subprojects { 24 | project.buildDir = "${rootProject.buildDir}/${project.name}" 25 | } 26 | subprojects { 27 | project.evaluationDependsOn(':app') 28 | } 29 | 30 | task clean(type: Delete) { 31 | delete rootProject.buildDir 32 | } 33 | -------------------------------------------------------------------------------- /android/gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx1536M 2 | android.useAndroidX=true 3 | android.enableJetifier=true 4 | -------------------------------------------------------------------------------- /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-7.5-all.zip 6 | -------------------------------------------------------------------------------- /android/settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | 3 | def localPropertiesFile = new File(rootProject.projectDir, "local.properties") 4 | def properties = new Properties() 5 | 6 | assert localPropertiesFile.exists() 7 | localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) } 8 | 9 | def flutterSdkPath = properties.getProperty("flutter.sdk") 10 | assert flutterSdkPath != null, "flutter.sdk not set in local.properties" 11 | apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle" 12 | -------------------------------------------------------------------------------- /firebase.json: -------------------------------------------------------------------------------- 1 | { 2 | "functions": [ 3 | { 4 | "source": "functions", 5 | "codebase": "default", 6 | "ignore": [ 7 | "node_modules", 8 | ".git", 9 | "firebase-debug.log", 10 | "firebase-debug.*.log" 11 | ], 12 | "predeploy": [ 13 | 14 | ] 15 | } 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /functions/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | env: { 4 | es6: true, 5 | node: true, 6 | }, 7 | extends: [ 8 | "eslint:recommended", 9 | "google", 10 | ], 11 | rules: { 12 | quotes: ["error", "double"], 13 | }, 14 | }; 15 | -------------------------------------------------------------------------------- /functions/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ -------------------------------------------------------------------------------- /functions/index.js: -------------------------------------------------------------------------------- 1 | const functions = require("firebase-functions"); 2 | const admin = require("firebase-admin"); 3 | 4 | admin.initializeApp(); 5 | 6 | const messaging = admin.messaging(); 7 | 8 | exports.notifySubscribers = functions.https.onCall(async (data, _) => { 9 | try { 10 | console.log(data.targetDevices); 11 | await messaging.sendToDevice(data.targetDevices, { 12 | notification: { 13 | title: data.messageTitle, 14 | body: data.messageBody, 15 | }, 16 | data:{ 17 | params:data.callkitParams 18 | } 19 | }); 20 | 21 | return true; 22 | } catch (ex) { 23 | console.log(ex); 24 | return false; 25 | } 26 | }); -------------------------------------------------------------------------------- /functions/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "functions", 3 | "description": "Cloud Functions for Firebase", 4 | "scripts": { 5 | "lint": "eslint .", 6 | "serve": "firebase emulators:start --only functions", 7 | "shell": "firebase functions:shell", 8 | "start": "npm run shell", 9 | "deploy": "firebase deploy --only functions", 10 | "logs": "firebase functions:log" 11 | }, 12 | "engines": { 13 | "node": "16" 14 | }, 15 | "main": "index.js", 16 | "dependencies": { 17 | "firebase-admin": "^10.0.2", 18 | "firebase-functions": "^3.18.0" 19 | }, 20 | "devDependencies": { 21 | "eslint": "^8.9.0", 22 | "eslint-config-google": "^0.14.0", 23 | "firebase-functions-test": "^0.2.0" 24 | }, 25 | "private": true 26 | } 27 | -------------------------------------------------------------------------------- /ios/.gitignore: -------------------------------------------------------------------------------- 1 | **/dgph 2 | *.mode1v3 3 | *.mode2v3 4 | *.moved-aside 5 | *.pbxuser 6 | *.perspectivev3 7 | **/*sync/ 8 | .sconsign.dblite 9 | .tags* 10 | **/.vagrant/ 11 | **/DerivedData/ 12 | Icon? 13 | **/Pods/ 14 | **/.symlinks/ 15 | profile 16 | xcuserdata 17 | **/.generated/ 18 | Flutter/App.framework 19 | Flutter/Flutter.framework 20 | Flutter/Flutter.podspec 21 | Flutter/Generated.xcconfig 22 | Flutter/ephemeral/ 23 | Flutter/app.flx 24 | Flutter/app.zip 25 | Flutter/flutter_assets/ 26 | Flutter/flutter_export_environment.sh 27 | ServiceDefinitions.json 28 | Runner/GeneratedPluginRegistrant.* 29 | 30 | # Exceptions to above rules. 31 | !default.mode1v3 32 | !default.mode2v3 33 | !default.pbxuser 34 | !default.perspectivev3 35 | -------------------------------------------------------------------------------- /ios/Flutter/AppFrameworkInfo.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | App 9 | CFBundleIdentifier 10 | io.flutter.flutter.app 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | App 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1.0 23 | MinimumOSVersion 24 | 11.0 25 | 26 | 27 | -------------------------------------------------------------------------------- /ios/Flutter/Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /ios/Flutter/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /ios/Podfile: -------------------------------------------------------------------------------- 1 | # Uncomment this line to define a global platform for your project 2 | platform :ios, '12.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 flutter_root 14 | generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__) 15 | unless File.exist?(generated_xcode_build_settings_path) 16 | raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first" 17 | end 18 | 19 | File.foreach(generated_xcode_build_settings_path) do |line| 20 | matches = line.match(/FLUTTER_ROOT\=(.*)/) 21 | return matches[1].strip if matches 22 | end 23 | raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get" 24 | end 25 | 26 | require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) 27 | 28 | flutter_ios_podfile_setup 29 | 30 | target 'Runner' do 31 | use_frameworks! 32 | use_modular_headers! 33 | 34 | flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) 35 | end 36 | 37 | post_install do |installer| 38 | installer.pods_project.targets.each do |target| 39 | flutter_additional_ios_build_settings(target) 40 | end 41 | end 42 | -------------------------------------------------------------------------------- /ios/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - cloud_functions (4.0.8): 3 | - Firebase/Functions (= 10.3.0) 4 | - firebase_core 5 | - Flutter 6 | - CryptoSwift (1.6.0) 7 | - Firebase/CoreOnly (10.3.0): 8 | - FirebaseCore (= 10.3.0) 9 | - Firebase/Functions (10.3.0): 10 | - Firebase/CoreOnly 11 | - FirebaseFunctions (~> 10.3.0) 12 | - Firebase/Messaging (10.3.0): 13 | - Firebase/CoreOnly 14 | - FirebaseMessaging (~> 10.3.0) 15 | - firebase_core (2.5.0): 16 | - Firebase/CoreOnly (= 10.3.0) 17 | - Flutter 18 | - firebase_messaging (14.2.2): 19 | - Firebase/Messaging (= 10.3.0) 20 | - firebase_core 21 | - Flutter 22 | - FirebaseAppCheckInterop (10.5.0) 23 | - FirebaseAuthInterop (10.5.0) 24 | - FirebaseCore (10.3.0): 25 | - FirebaseCoreInternal (~> 10.0) 26 | - GoogleUtilities/Environment (~> 7.8) 27 | - GoogleUtilities/Logger (~> 7.8) 28 | - FirebaseCoreExtension (10.5.0): 29 | - FirebaseCore (~> 10.0) 30 | - FirebaseCoreInternal (10.5.0): 31 | - "GoogleUtilities/NSData+zlib (~> 7.8)" 32 | - FirebaseFunctions (10.3.0): 33 | - FirebaseAppCheckInterop (~> 10.0) 34 | - FirebaseAuthInterop (~> 10.0) 35 | - FirebaseCore (~> 10.0) 36 | - FirebaseCoreExtension (~> 10.0) 37 | - FirebaseMessagingInterop (~> 10.0) 38 | - FirebaseSharedSwift (~> 10.0) 39 | - GTMSessionFetcher/Core (< 4.0, >= 2.1) 40 | - FirebaseInstallations (10.5.0): 41 | - FirebaseCore (~> 10.0) 42 | - GoogleUtilities/Environment (~> 7.8) 43 | - GoogleUtilities/UserDefaults (~> 7.8) 44 | - PromisesObjC (~> 2.1) 45 | - FirebaseMessaging (10.3.0): 46 | - FirebaseCore (~> 10.0) 47 | - FirebaseInstallations (~> 10.0) 48 | - GoogleDataTransport (~> 9.2) 49 | - GoogleUtilities/AppDelegateSwizzler (~> 7.8) 50 | - GoogleUtilities/Environment (~> 7.8) 51 | - GoogleUtilities/Reachability (~> 7.8) 52 | - GoogleUtilities/UserDefaults (~> 7.8) 53 | - nanopb (< 2.30910.0, >= 2.30908.0) 54 | - FirebaseMessagingInterop (10.5.0) 55 | - FirebaseSharedSwift (10.5.0) 56 | - Flutter (1.0.0) 57 | - flutter_callkit_incoming (0.0.1): 58 | - CryptoSwift 59 | - Flutter 60 | - GoogleDataTransport (9.2.1): 61 | - GoogleUtilities/Environment (~> 7.7) 62 | - nanopb (< 2.30910.0, >= 2.30908.0) 63 | - PromisesObjC (< 3.0, >= 1.2) 64 | - GoogleUtilities/AppDelegateSwizzler (7.11.0): 65 | - GoogleUtilities/Environment 66 | - GoogleUtilities/Logger 67 | - GoogleUtilities/Network 68 | - GoogleUtilities/Environment (7.11.0): 69 | - PromisesObjC (< 3.0, >= 1.2) 70 | - GoogleUtilities/Logger (7.11.0): 71 | - GoogleUtilities/Environment 72 | - GoogleUtilities/Network (7.11.0): 73 | - GoogleUtilities/Logger 74 | - "GoogleUtilities/NSData+zlib" 75 | - GoogleUtilities/Reachability 76 | - "GoogleUtilities/NSData+zlib (7.11.0)" 77 | - GoogleUtilities/Reachability (7.11.0): 78 | - GoogleUtilities/Logger 79 | - GoogleUtilities/UserDefaults (7.11.0): 80 | - GoogleUtilities/Logger 81 | - GTMSessionFetcher/Core (3.1.0) 82 | - HMSBroadcastExtensionSDK (0.0.7) 83 | - HMSSDK (0.6.2): 84 | - HMSWebRTC (= 1.0.5113) 85 | - hmssdk_flutter (1.3.0): 86 | - Flutter 87 | - HMSBroadcastExtensionSDK (= 0.0.7) 88 | - HMSSDK (= 0.6.2) 89 | - HMSWebRTC (1.0.5113) 90 | - nanopb (2.30909.0): 91 | - nanopb/decode (= 2.30909.0) 92 | - nanopb/encode (= 2.30909.0) 93 | - nanopb/decode (2.30909.0) 94 | - nanopb/encode (2.30909.0) 95 | - path_provider_foundation (0.0.1): 96 | - Flutter 97 | - FlutterMacOS 98 | - permission_handler_apple (9.0.4): 99 | - Flutter 100 | - PromisesObjC (2.1.1) 101 | - share_plus (0.0.1): 102 | - Flutter 103 | 104 | DEPENDENCIES: 105 | - cloud_functions (from `.symlinks/plugins/cloud_functions/ios`) 106 | - firebase_core (from `.symlinks/plugins/firebase_core/ios`) 107 | - firebase_messaging (from `.symlinks/plugins/firebase_messaging/ios`) 108 | - Flutter (from `Flutter`) 109 | - flutter_callkit_incoming (from `.symlinks/plugins/flutter_callkit_incoming/ios`) 110 | - hmssdk_flutter (from `.symlinks/plugins/hmssdk_flutter/ios`) 111 | - path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/ios`) 112 | - permission_handler_apple (from `.symlinks/plugins/permission_handler_apple/ios`) 113 | - share_plus (from `.symlinks/plugins/share_plus/ios`) 114 | 115 | SPEC REPOS: 116 | trunk: 117 | - CryptoSwift 118 | - Firebase 119 | - FirebaseAppCheckInterop 120 | - FirebaseAuthInterop 121 | - FirebaseCore 122 | - FirebaseCoreExtension 123 | - FirebaseCoreInternal 124 | - FirebaseFunctions 125 | - FirebaseInstallations 126 | - FirebaseMessaging 127 | - FirebaseMessagingInterop 128 | - FirebaseSharedSwift 129 | - GoogleDataTransport 130 | - GoogleUtilities 131 | - GTMSessionFetcher 132 | - HMSBroadcastExtensionSDK 133 | - HMSSDK 134 | - HMSWebRTC 135 | - nanopb 136 | - PromisesObjC 137 | 138 | EXTERNAL SOURCES: 139 | cloud_functions: 140 | :path: ".symlinks/plugins/cloud_functions/ios" 141 | firebase_core: 142 | :path: ".symlinks/plugins/firebase_core/ios" 143 | firebase_messaging: 144 | :path: ".symlinks/plugins/firebase_messaging/ios" 145 | Flutter: 146 | :path: Flutter 147 | flutter_callkit_incoming: 148 | :path: ".symlinks/plugins/flutter_callkit_incoming/ios" 149 | hmssdk_flutter: 150 | :path: ".symlinks/plugins/hmssdk_flutter/ios" 151 | path_provider_foundation: 152 | :path: ".symlinks/plugins/path_provider_foundation/ios" 153 | permission_handler_apple: 154 | :path: ".symlinks/plugins/permission_handler_apple/ios" 155 | share_plus: 156 | :path: ".symlinks/plugins/share_plus/ios" 157 | 158 | SPEC CHECKSUMS: 159 | cloud_functions: a2726f70f64877eb8ba47e3bd0e4e52f6e8bfc8e 160 | CryptoSwift: 562f8eceb40e80796fffc668b0cad9313284cfa6 161 | Firebase: f92fc551ead69c94168d36c2b26188263860acd9 162 | firebase_core: f95c8bbe65213d406d592573ad42a12d64849cb8 163 | firebase_messaging: 3daef9f9ee5b91de2f282895ec91cc5e5ca78556 164 | FirebaseAppCheckInterop: 95bc238f8755d597cad95815b3c448f8617f720f 165 | FirebaseAuthInterop: e1a53afba01599095100f92d6d3ecb75da6b5fa8 166 | FirebaseCore: 988754646ab3bd4bdcb740f1bfe26b9f6c0d5f2a 167 | FirebaseCoreExtension: d9fa427f1ae1edccf2368ce5e8d567e4c1f0ebc8 168 | FirebaseCoreInternal: e463f41bb935cd049505bf7e9a5bdd7dcea90df6 169 | FirebaseFunctions: d8415d2237cc807d05fa0a921d645f50a0d9d803 170 | FirebaseInstallations: 935bc4abb6f7a035cab7a0c31cb777b2be3dd254 171 | FirebaseMessaging: e345b219fd15d325f0cf2fef28cb8ce00d851b3f 172 | FirebaseMessagingInterop: 1fc10aa48ca7bd70747d8211190890dccdfb9c65 173 | FirebaseSharedSwift: 30289ed76ccb441067a2cd3472cc5b2f491b9d8f 174 | Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854 175 | flutter_callkit_incoming: 417dd1b46541cdd5d855ad795ccbe97d1c18155e 176 | GoogleDataTransport: ea169759df570f4e37bdee1623ec32a7e64e67c4 177 | GoogleUtilities: c2bdc4cf2ce786c4d2e6b3bcfd599a25ca78f06f 178 | GTMSessionFetcher: c9e714f7eec91a55641e2bab9f45fd83a219b882 179 | HMSBroadcastExtensionSDK: d22df4b2c22843efe4a1779478889076db8eaabd 180 | HMSSDK: c995b000287512ae30cba17605f5dd0cec7cd994 181 | hmssdk_flutter: 0b06e99ae9fd36a43777b37485096397e75d7091 182 | HMSWebRTC: 6bd851709766bf4b28fd89046a65654e86741aed 183 | nanopb: b552cce312b6c8484180ef47159bc0f65a1f0431 184 | path_provider_foundation: 37748e03f12783f9de2cb2c4eadfaa25fe6d4852 185 | permission_handler_apple: 44366e37eaf29454a1e7b1b7d736c2cceaeb17ce 186 | PromisesObjC: ab77feca74fa2823e7af4249b8326368e61014cb 187 | share_plus: 056a1e8ac890df3e33cb503afffaf1e9b4fbae68 188 | 189 | PODFILE CHECKSUM: 4e8f8b2be68aeea4c0d5beb6ff1e79fface1d048 190 | 191 | COCOAPODS: 1.11.3 192 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 54; 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 | 5591585E1B195DA41EDD827C /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C62DE3DB7AA5EAF48460307E /* Pods_Runner.framework */; }; 13 | 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; 14 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 15 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 16 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; 17 | B41EAFA62994C8C500A77921 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = B41EAFA52994C8C500A77921 /* GoogleService-Info.plist */; }; 18 | /* End PBXBuildFile section */ 19 | 20 | /* Begin PBXCopyFilesBuildPhase section */ 21 | 9705A1C41CF9048500538489 /* Embed Frameworks */ = { 22 | isa = PBXCopyFilesBuildPhase; 23 | buildActionMask = 2147483647; 24 | dstPath = ""; 25 | dstSubfolderSpec = 10; 26 | files = ( 27 | ); 28 | name = "Embed Frameworks"; 29 | runOnlyForDeploymentPostprocessing = 0; 30 | }; 31 | /* End PBXCopyFilesBuildPhase section */ 32 | 33 | /* Begin PBXFileReference section */ 34 | 1492280945658C3943234759 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; 35 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; 36 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; 37 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; 38 | 69DD47EE60C537104AF5C2BC /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; 39 | 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; 40 | 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 41 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; 42 | 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; 43 | 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; 44 | 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; 45 | 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 46 | 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 47 | 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 48 | 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 49 | B41EAFA52994C8C500A77921 /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = ""; }; 50 | B41EAFB42994DAC600A77921 /* Runner.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Runner.entitlements; sourceTree = ""; }; 51 | C62DE3DB7AA5EAF48460307E /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 52 | E4A18052FF88149A1C2D748E /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; }; 53 | /* End PBXFileReference section */ 54 | 55 | /* Begin PBXFrameworksBuildPhase section */ 56 | 97C146EB1CF9000F007C117D /* Frameworks */ = { 57 | isa = PBXFrameworksBuildPhase; 58 | buildActionMask = 2147483647; 59 | files = ( 60 | 5591585E1B195DA41EDD827C /* Pods_Runner.framework in Frameworks */, 61 | ); 62 | runOnlyForDeploymentPostprocessing = 0; 63 | }; 64 | /* End PBXFrameworksBuildPhase section */ 65 | 66 | /* Begin PBXGroup section */ 67 | 9740EEB11CF90186004384FC /* Flutter */ = { 68 | isa = PBXGroup; 69 | children = ( 70 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, 71 | 9740EEB21CF90195004384FC /* Debug.xcconfig */, 72 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, 73 | 9740EEB31CF90195004384FC /* Generated.xcconfig */, 74 | ); 75 | name = Flutter; 76 | sourceTree = ""; 77 | }; 78 | 97C146E51CF9000F007C117D = { 79 | isa = PBXGroup; 80 | children = ( 81 | B41EAFA52994C8C500A77921 /* GoogleService-Info.plist */, 82 | 9740EEB11CF90186004384FC /* Flutter */, 83 | 97C146F01CF9000F007C117D /* Runner */, 84 | 97C146EF1CF9000F007C117D /* Products */, 85 | BEB3B576775832673B7AC62F /* Pods */, 86 | 9F08784B10B35CE030B38E70 /* Frameworks */, 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 | B41EAFB42994DAC600A77921 /* Runner.entitlements */, 102 | 97C146FA1CF9000F007C117D /* Main.storyboard */, 103 | 97C146FD1CF9000F007C117D /* Assets.xcassets */, 104 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, 105 | 97C147021CF9000F007C117D /* Info.plist */, 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 | 9F08784B10B35CE030B38E70 /* Frameworks */ = { 115 | isa = PBXGroup; 116 | children = ( 117 | C62DE3DB7AA5EAF48460307E /* Pods_Runner.framework */, 118 | ); 119 | name = Frameworks; 120 | sourceTree = ""; 121 | }; 122 | BEB3B576775832673B7AC62F /* Pods */ = { 123 | isa = PBXGroup; 124 | children = ( 125 | 69DD47EE60C537104AF5C2BC /* Pods-Runner.debug.xcconfig */, 126 | 1492280945658C3943234759 /* Pods-Runner.release.xcconfig */, 127 | E4A18052FF88149A1C2D748E /* Pods-Runner.profile.xcconfig */, 128 | ); 129 | path = Pods; 130 | sourceTree = ""; 131 | }; 132 | /* End PBXGroup section */ 133 | 134 | /* Begin PBXNativeTarget section */ 135 | 97C146ED1CF9000F007C117D /* Runner */ = { 136 | isa = PBXNativeTarget; 137 | buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; 138 | buildPhases = ( 139 | FA0F422EAE174B1811F4111E /* [CP] Check Pods Manifest.lock */, 140 | 9740EEB61CF901F6004384FC /* Run Script */, 141 | 97C146EA1CF9000F007C117D /* Sources */, 142 | 97C146EB1CF9000F007C117D /* Frameworks */, 143 | 97C146EC1CF9000F007C117D /* Resources */, 144 | 9705A1C41CF9048500538489 /* Embed Frameworks */, 145 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */, 146 | 0CD5B6BF545EDDAD81CC48BB /* [CP] Embed Pods Frameworks */, 147 | ); 148 | buildRules = ( 149 | ); 150 | dependencies = ( 151 | ); 152 | name = Runner; 153 | packageProductDependencies = ( 154 | ); 155 | productName = Runner; 156 | productReference = 97C146EE1CF9000F007C117D /* Runner.app */; 157 | productType = "com.apple.product-type.application"; 158 | }; 159 | /* End PBXNativeTarget section */ 160 | 161 | /* Begin PBXProject section */ 162 | 97C146E61CF9000F007C117D /* Project object */ = { 163 | isa = PBXProject; 164 | attributes = { 165 | LastUpgradeCheck = 1300; 166 | ORGANIZATIONNAME = ""; 167 | TargetAttributes = { 168 | 97C146ED1CF9000F007C117D = { 169 | CreatedOnToolsVersion = 7.3.1; 170 | LastSwiftMigration = 1100; 171 | }; 172 | }; 173 | }; 174 | buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; 175 | compatibilityVersion = "Xcode 9.3"; 176 | developmentRegion = en; 177 | hasScannedForEncodings = 0; 178 | knownRegions = ( 179 | en, 180 | Base, 181 | ); 182 | mainGroup = 97C146E51CF9000F007C117D; 183 | packageReferences = ( 184 | ); 185 | productRefGroup = 97C146EF1CF9000F007C117D /* Products */; 186 | projectDirPath = ""; 187 | projectRoot = ""; 188 | targets = ( 189 | 97C146ED1CF9000F007C117D /* Runner */, 190 | ); 191 | }; 192 | /* End PBXProject section */ 193 | 194 | /* Begin PBXResourcesBuildPhase section */ 195 | 97C146EC1CF9000F007C117D /* Resources */ = { 196 | isa = PBXResourcesBuildPhase; 197 | buildActionMask = 2147483647; 198 | files = ( 199 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, 200 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, 201 | B41EAFA62994C8C500A77921 /* GoogleService-Info.plist in Resources */, 202 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, 203 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, 204 | ); 205 | runOnlyForDeploymentPostprocessing = 0; 206 | }; 207 | /* End PBXResourcesBuildPhase section */ 208 | 209 | /* Begin PBXShellScriptBuildPhase section */ 210 | 0CD5B6BF545EDDAD81CC48BB /* [CP] Embed Pods Frameworks */ = { 211 | isa = PBXShellScriptBuildPhase; 212 | buildActionMask = 2147483647; 213 | files = ( 214 | ); 215 | inputFileListPaths = ( 216 | "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist", 217 | ); 218 | name = "[CP] Embed Pods Frameworks"; 219 | outputFileListPaths = ( 220 | "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist", 221 | ); 222 | runOnlyForDeploymentPostprocessing = 0; 223 | shellPath = /bin/sh; 224 | shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; 225 | showEnvVarsInLog = 0; 226 | }; 227 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { 228 | isa = PBXShellScriptBuildPhase; 229 | alwaysOutOfDate = 1; 230 | buildActionMask = 2147483647; 231 | files = ( 232 | ); 233 | inputPaths = ( 234 | ); 235 | name = "Thin Binary"; 236 | outputPaths = ( 237 | ); 238 | runOnlyForDeploymentPostprocessing = 0; 239 | shellPath = /bin/sh; 240 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; 241 | }; 242 | 9740EEB61CF901F6004384FC /* Run Script */ = { 243 | isa = PBXShellScriptBuildPhase; 244 | alwaysOutOfDate = 1; 245 | buildActionMask = 2147483647; 246 | files = ( 247 | ); 248 | inputPaths = ( 249 | ); 250 | name = "Run Script"; 251 | outputPaths = ( 252 | ); 253 | runOnlyForDeploymentPostprocessing = 0; 254 | shellPath = /bin/sh; 255 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; 256 | }; 257 | FA0F422EAE174B1811F4111E /* [CP] Check Pods Manifest.lock */ = { 258 | isa = PBXShellScriptBuildPhase; 259 | buildActionMask = 2147483647; 260 | files = ( 261 | ); 262 | inputFileListPaths = ( 263 | ); 264 | inputPaths = ( 265 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 266 | "${PODS_ROOT}/Manifest.lock", 267 | ); 268 | name = "[CP] Check Pods Manifest.lock"; 269 | outputFileListPaths = ( 270 | ); 271 | outputPaths = ( 272 | "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", 273 | ); 274 | runOnlyForDeploymentPostprocessing = 0; 275 | shellPath = /bin/sh; 276 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; 277 | showEnvVarsInLog = 0; 278 | }; 279 | /* End PBXShellScriptBuildPhase section */ 280 | 281 | /* Begin PBXSourcesBuildPhase section */ 282 | 97C146EA1CF9000F007C117D /* Sources */ = { 283 | isa = PBXSourcesBuildPhase; 284 | buildActionMask = 2147483647; 285 | files = ( 286 | 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */, 287 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, 288 | ); 289 | runOnlyForDeploymentPostprocessing = 0; 290 | }; 291 | /* End PBXSourcesBuildPhase section */ 292 | 293 | /* Begin PBXVariantGroup section */ 294 | 97C146FA1CF9000F007C117D /* Main.storyboard */ = { 295 | isa = PBXVariantGroup; 296 | children = ( 297 | 97C146FB1CF9000F007C117D /* Base */, 298 | ); 299 | name = Main.storyboard; 300 | sourceTree = ""; 301 | }; 302 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { 303 | isa = PBXVariantGroup; 304 | children = ( 305 | 97C147001CF9000F007C117D /* Base */, 306 | ); 307 | name = LaunchScreen.storyboard; 308 | sourceTree = ""; 309 | }; 310 | /* End PBXVariantGroup section */ 311 | 312 | /* Begin XCBuildConfiguration section */ 313 | 249021D3217E4FDB00AE95B9 /* Profile */ = { 314 | isa = XCBuildConfiguration; 315 | buildSettings = { 316 | ALWAYS_SEARCH_USER_PATHS = NO; 317 | CLANG_ANALYZER_NONNULL = YES; 318 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 319 | CLANG_CXX_LIBRARY = "libc++"; 320 | CLANG_ENABLE_MODULES = YES; 321 | CLANG_ENABLE_OBJC_ARC = YES; 322 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 323 | CLANG_WARN_BOOL_CONVERSION = YES; 324 | CLANG_WARN_COMMA = YES; 325 | CLANG_WARN_CONSTANT_CONVERSION = YES; 326 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 327 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 328 | CLANG_WARN_EMPTY_BODY = YES; 329 | CLANG_WARN_ENUM_CONVERSION = YES; 330 | CLANG_WARN_INFINITE_RECURSION = YES; 331 | CLANG_WARN_INT_CONVERSION = YES; 332 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 333 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 334 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 335 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 336 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 337 | CLANG_WARN_STRICT_PROTOTYPES = YES; 338 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 339 | CLANG_WARN_UNREACHABLE_CODE = YES; 340 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 341 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 342 | COPY_PHASE_STRIP = NO; 343 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 344 | ENABLE_NS_ASSERTIONS = NO; 345 | ENABLE_STRICT_OBJC_MSGSEND = YES; 346 | GCC_C_LANGUAGE_STANDARD = gnu99; 347 | GCC_NO_COMMON_BLOCKS = YES; 348 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 349 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 350 | GCC_WARN_UNDECLARED_SELECTOR = YES; 351 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 352 | GCC_WARN_UNUSED_FUNCTION = YES; 353 | GCC_WARN_UNUSED_VARIABLE = YES; 354 | IPHONEOS_DEPLOYMENT_TARGET = 11.0; 355 | MTL_ENABLE_DEBUG_INFO = NO; 356 | SDKROOT = iphoneos; 357 | SUPPORTED_PLATFORMS = iphoneos; 358 | TARGETED_DEVICE_FAMILY = "1,2"; 359 | VALIDATE_PRODUCT = YES; 360 | }; 361 | name = Profile; 362 | }; 363 | 249021D4217E4FDB00AE95B9 /* Profile */ = { 364 | isa = XCBuildConfiguration; 365 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 366 | buildSettings = { 367 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 368 | CLANG_ENABLE_MODULES = YES; 369 | CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; 370 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 371 | DEVELOPMENT_TEAM = 5N85PP82A9; 372 | ENABLE_BITCODE = NO; 373 | INFOPLIST_FILE = Runner/Info.plist; 374 | IPHONEOS_DEPLOYMENT_TARGET = 12.0; 375 | LD_RUNPATH_SEARCH_PATHS = ( 376 | "$(inherited)", 377 | "@executable_path/Frameworks", 378 | ); 379 | PRODUCT_BUNDLE_IDENTIFIER = com.example.hmsCallkit; 380 | PRODUCT_NAME = "$(TARGET_NAME)"; 381 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; 382 | SWIFT_VERSION = 5.0; 383 | VERSIONING_SYSTEM = "apple-generic"; 384 | }; 385 | name = Profile; 386 | }; 387 | 97C147031CF9000F007C117D /* Debug */ = { 388 | isa = XCBuildConfiguration; 389 | buildSettings = { 390 | ALWAYS_SEARCH_USER_PATHS = NO; 391 | CLANG_ANALYZER_NONNULL = YES; 392 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 393 | CLANG_CXX_LIBRARY = "libc++"; 394 | CLANG_ENABLE_MODULES = YES; 395 | CLANG_ENABLE_OBJC_ARC = YES; 396 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 397 | CLANG_WARN_BOOL_CONVERSION = YES; 398 | CLANG_WARN_COMMA = YES; 399 | CLANG_WARN_CONSTANT_CONVERSION = YES; 400 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 401 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 402 | CLANG_WARN_EMPTY_BODY = YES; 403 | CLANG_WARN_ENUM_CONVERSION = YES; 404 | CLANG_WARN_INFINITE_RECURSION = YES; 405 | CLANG_WARN_INT_CONVERSION = YES; 406 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 407 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 408 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 409 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 410 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 411 | CLANG_WARN_STRICT_PROTOTYPES = YES; 412 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 413 | CLANG_WARN_UNREACHABLE_CODE = YES; 414 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 415 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 416 | COPY_PHASE_STRIP = NO; 417 | DEBUG_INFORMATION_FORMAT = dwarf; 418 | ENABLE_STRICT_OBJC_MSGSEND = YES; 419 | ENABLE_TESTABILITY = YES; 420 | GCC_C_LANGUAGE_STANDARD = gnu99; 421 | GCC_DYNAMIC_NO_PIC = NO; 422 | GCC_NO_COMMON_BLOCKS = YES; 423 | GCC_OPTIMIZATION_LEVEL = 0; 424 | GCC_PREPROCESSOR_DEFINITIONS = ( 425 | "DEBUG=1", 426 | "$(inherited)", 427 | ); 428 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 429 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 430 | GCC_WARN_UNDECLARED_SELECTOR = YES; 431 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 432 | GCC_WARN_UNUSED_FUNCTION = YES; 433 | GCC_WARN_UNUSED_VARIABLE = YES; 434 | IPHONEOS_DEPLOYMENT_TARGET = 11.0; 435 | MTL_ENABLE_DEBUG_INFO = YES; 436 | ONLY_ACTIVE_ARCH = YES; 437 | SDKROOT = iphoneos; 438 | TARGETED_DEVICE_FAMILY = "1,2"; 439 | }; 440 | name = Debug; 441 | }; 442 | 97C147041CF9000F007C117D /* Release */ = { 443 | isa = XCBuildConfiguration; 444 | buildSettings = { 445 | ALWAYS_SEARCH_USER_PATHS = NO; 446 | CLANG_ANALYZER_NONNULL = YES; 447 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 448 | CLANG_CXX_LIBRARY = "libc++"; 449 | CLANG_ENABLE_MODULES = YES; 450 | CLANG_ENABLE_OBJC_ARC = YES; 451 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 452 | CLANG_WARN_BOOL_CONVERSION = YES; 453 | CLANG_WARN_COMMA = YES; 454 | CLANG_WARN_CONSTANT_CONVERSION = YES; 455 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 456 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 457 | CLANG_WARN_EMPTY_BODY = YES; 458 | CLANG_WARN_ENUM_CONVERSION = YES; 459 | CLANG_WARN_INFINITE_RECURSION = YES; 460 | CLANG_WARN_INT_CONVERSION = YES; 461 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 462 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 463 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 464 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 465 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 466 | CLANG_WARN_STRICT_PROTOTYPES = YES; 467 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 468 | CLANG_WARN_UNREACHABLE_CODE = YES; 469 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 470 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 471 | COPY_PHASE_STRIP = NO; 472 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 473 | ENABLE_NS_ASSERTIONS = NO; 474 | ENABLE_STRICT_OBJC_MSGSEND = YES; 475 | GCC_C_LANGUAGE_STANDARD = gnu99; 476 | GCC_NO_COMMON_BLOCKS = YES; 477 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 478 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 479 | GCC_WARN_UNDECLARED_SELECTOR = YES; 480 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 481 | GCC_WARN_UNUSED_FUNCTION = YES; 482 | GCC_WARN_UNUSED_VARIABLE = YES; 483 | IPHONEOS_DEPLOYMENT_TARGET = 11.0; 484 | MTL_ENABLE_DEBUG_INFO = NO; 485 | SDKROOT = iphoneos; 486 | SUPPORTED_PLATFORMS = iphoneos; 487 | SWIFT_COMPILATION_MODE = wholemodule; 488 | SWIFT_OPTIMIZATION_LEVEL = "-O"; 489 | TARGETED_DEVICE_FAMILY = "1,2"; 490 | VALIDATE_PRODUCT = YES; 491 | }; 492 | name = Release; 493 | }; 494 | 97C147061CF9000F007C117D /* Debug */ = { 495 | isa = XCBuildConfiguration; 496 | baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; 497 | buildSettings = { 498 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 499 | CLANG_ENABLE_MODULES = YES; 500 | CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; 501 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 502 | DEVELOPMENT_TEAM = 5N85PP82A9; 503 | ENABLE_BITCODE = NO; 504 | INFOPLIST_FILE = Runner/Info.plist; 505 | IPHONEOS_DEPLOYMENT_TARGET = 12.0; 506 | LD_RUNPATH_SEARCH_PATHS = ( 507 | "$(inherited)", 508 | "@executable_path/Frameworks", 509 | ); 510 | PRODUCT_BUNDLE_IDENTIFIER = com.example.hmsCallkit; 511 | PRODUCT_NAME = "$(TARGET_NAME)"; 512 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; 513 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 514 | SWIFT_VERSION = 5.0; 515 | VERSIONING_SYSTEM = "apple-generic"; 516 | }; 517 | name = Debug; 518 | }; 519 | 97C147071CF9000F007C117D /* Release */ = { 520 | isa = XCBuildConfiguration; 521 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 522 | buildSettings = { 523 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 524 | CLANG_ENABLE_MODULES = YES; 525 | CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; 526 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 527 | DEVELOPMENT_TEAM = 5N85PP82A9; 528 | ENABLE_BITCODE = NO; 529 | INFOPLIST_FILE = Runner/Info.plist; 530 | IPHONEOS_DEPLOYMENT_TARGET = 12.0; 531 | LD_RUNPATH_SEARCH_PATHS = ( 532 | "$(inherited)", 533 | "@executable_path/Frameworks", 534 | ); 535 | PRODUCT_BUNDLE_IDENTIFIER = com.example.hmsCallkit; 536 | PRODUCT_NAME = "$(TARGET_NAME)"; 537 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; 538 | SWIFT_VERSION = 5.0; 539 | VERSIONING_SYSTEM = "apple-generic"; 540 | }; 541 | name = Release; 542 | }; 543 | /* End XCBuildConfiguration section */ 544 | 545 | /* Begin XCConfigurationList section */ 546 | 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { 547 | isa = XCConfigurationList; 548 | buildConfigurations = ( 549 | 97C147031CF9000F007C117D /* Debug */, 550 | 97C147041CF9000F007C117D /* Release */, 551 | 249021D3217E4FDB00AE95B9 /* Profile */, 552 | ); 553 | defaultConfigurationIsVisible = 0; 554 | defaultConfigurationName = Release; 555 | }; 556 | 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { 557 | isa = XCConfigurationList; 558 | buildConfigurations = ( 559 | 97C147061CF9000F007C117D /* Debug */, 560 | 97C147071CF9000F007C117D /* Release */, 561 | 249021D4217E4FDB00AE95B9 /* Profile */, 562 | ); 563 | defaultConfigurationIsVisible = 0; 564 | defaultConfigurationName = Release; 565 | }; 566 | /* End XCConfigurationList section */ 567 | }; 568 | rootObject = 97C146E61CF9000F007C117D /* Project object */; 569 | } 570 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved: -------------------------------------------------------------------------------- 1 | { 2 | "pins" : [ 3 | { 4 | "identity" : "abseil-cpp-swiftpm", 5 | "kind" : "remoteSourceControl", 6 | "location" : "https://github.com/firebase/abseil-cpp-SwiftPM.git", 7 | "state" : { 8 | "revision" : "583de9bd60f66b40e78d08599cc92036c2e7e4e1", 9 | "version" : "0.20220203.2" 10 | } 11 | }, 12 | { 13 | "identity" : "boringssl-swiftpm", 14 | "kind" : "remoteSourceControl", 15 | "location" : "https://github.com/firebase/boringssl-SwiftPM.git", 16 | "state" : { 17 | "revision" : "dd3eda2b05a3f459fc3073695ad1b28659066eab", 18 | "version" : "0.9.1" 19 | } 20 | }, 21 | { 22 | "identity" : "firebase-ios-sdk", 23 | "kind" : "remoteSourceControl", 24 | "location" : "https://github.com/firebase/firebase-ios-sdk", 25 | "state" : { 26 | "branch" : "master", 27 | "revision" : "8c684750bf32b71bc81e15c87e0cd284dca43c2b" 28 | } 29 | }, 30 | { 31 | "identity" : "googleappmeasurement", 32 | "kind" : "remoteSourceControl", 33 | "location" : "https://github.com/google/GoogleAppMeasurement.git", 34 | "state" : { 35 | "revision" : "9a09ece724128e8d1e14c5133b87c0e236844ac0", 36 | "version" : "10.4.0" 37 | } 38 | }, 39 | { 40 | "identity" : "googledatatransport", 41 | "kind" : "remoteSourceControl", 42 | "location" : "https://github.com/google/GoogleDataTransport.git", 43 | "state" : { 44 | "revision" : "f6b558e3f801f2cac336b04f615ce111fa9ddaa0", 45 | "version" : "9.2.1" 46 | } 47 | }, 48 | { 49 | "identity" : "googleutilities", 50 | "kind" : "remoteSourceControl", 51 | "location" : "https://github.com/google/GoogleUtilities.git", 52 | "state" : { 53 | "revision" : "0543562f85620b5b7c510c6bcbef75b562a5127b", 54 | "version" : "7.11.0" 55 | } 56 | }, 57 | { 58 | "identity" : "grpc-ios", 59 | "kind" : "remoteSourceControl", 60 | "location" : "https://github.com/grpc/grpc-ios.git", 61 | "state" : { 62 | "revision" : "8440b914756e0d26d4f4d054a1c1581daedfc5b6", 63 | "version" : "1.44.3-grpc" 64 | } 65 | }, 66 | { 67 | "identity" : "gtm-session-fetcher", 68 | "kind" : "remoteSourceControl", 69 | "location" : "https://github.com/google/gtm-session-fetcher.git", 70 | "state" : { 71 | "revision" : "96d7cc73a71ce950723aa3c50ce4fb275ae180b8", 72 | "version" : "3.1.0" 73 | } 74 | }, 75 | { 76 | "identity" : "leveldb", 77 | "kind" : "remoteSourceControl", 78 | "location" : "https://github.com/firebase/leveldb.git", 79 | "state" : { 80 | "revision" : "0706abcc6b0bd9cedfbb015ba840e4a780b5159b", 81 | "version" : "1.22.2" 82 | } 83 | }, 84 | { 85 | "identity" : "nanopb", 86 | "kind" : "remoteSourceControl", 87 | "location" : "https://github.com/firebase/nanopb.git", 88 | "state" : { 89 | "revision" : "819d0a2173aff699fb8c364b6fb906f7cdb1a692", 90 | "version" : "2.30909.0" 91 | } 92 | }, 93 | { 94 | "identity" : "promises", 95 | "kind" : "remoteSourceControl", 96 | "location" : "https://github.com/google/promises.git", 97 | "state" : { 98 | "revision" : "3e4e743631e86c8c70dbc6efdc7beaa6e90fd3bb", 99 | "version" : "2.1.1" 100 | } 101 | }, 102 | { 103 | "identity" : "swift-protobuf", 104 | "kind" : "remoteSourceControl", 105 | "location" : "https://github.com/apple/swift-protobuf.git", 106 | "state" : { 107 | "revision" : "ab3a58b7209a17d781c0d1dbb3e1ff3da306bae8", 108 | "version" : "1.20.3" 109 | } 110 | } 111 | ], 112 | "version" : 2 113 | } 114 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 37 | 38 | 39 | 40 | 41 | 42 | 52 | 54 | 60 | 61 | 62 | 63 | 69 | 71 | 77 | 78 | 79 | 80 | 82 | 83 | 86 | 87 | 88 | -------------------------------------------------------------------------------- /ios/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ios/Runner/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | import Flutter 3 | 4 | @UIApplicationMain 5 | @objc class AppDelegate: FlutterAppDelegate { 6 | override func application( 7 | _ application: UIApplication, 8 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? 9 | ) -> Bool { 10 | GeneratedPluginRegistrant.register(with: self) 11 | return super.application(application, didFinishLaunchingWithOptions: launchOptions) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "20x20", 5 | "idiom" : "iphone", 6 | "filename" : "Icon-App-20x20@2x.png", 7 | "scale" : "2x" 8 | }, 9 | { 10 | "size" : "20x20", 11 | "idiom" : "iphone", 12 | "filename" : "Icon-App-20x20@3x.png", 13 | "scale" : "3x" 14 | }, 15 | { 16 | "size" : "29x29", 17 | "idiom" : "iphone", 18 | "filename" : "Icon-App-29x29@1x.png", 19 | "scale" : "1x" 20 | }, 21 | { 22 | "size" : "29x29", 23 | "idiom" : "iphone", 24 | "filename" : "Icon-App-29x29@2x.png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "29x29", 29 | "idiom" : "iphone", 30 | "filename" : "Icon-App-29x29@3x.png", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "size" : "40x40", 35 | "idiom" : "iphone", 36 | "filename" : "Icon-App-40x40@2x.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "40x40", 41 | "idiom" : "iphone", 42 | "filename" : "Icon-App-40x40@3x.png", 43 | "scale" : "3x" 44 | }, 45 | { 46 | "size" : "60x60", 47 | "idiom" : "iphone", 48 | "filename" : "Icon-App-60x60@2x.png", 49 | "scale" : "2x" 50 | }, 51 | { 52 | "size" : "60x60", 53 | "idiom" : "iphone", 54 | "filename" : "Icon-App-60x60@3x.png", 55 | "scale" : "3x" 56 | }, 57 | { 58 | "size" : "20x20", 59 | "idiom" : "ipad", 60 | "filename" : "Icon-App-20x20@1x.png", 61 | "scale" : "1x" 62 | }, 63 | { 64 | "size" : "20x20", 65 | "idiom" : "ipad", 66 | "filename" : "Icon-App-20x20@2x.png", 67 | "scale" : "2x" 68 | }, 69 | { 70 | "size" : "29x29", 71 | "idiom" : "ipad", 72 | "filename" : "Icon-App-29x29@1x.png", 73 | "scale" : "1x" 74 | }, 75 | { 76 | "size" : "29x29", 77 | "idiom" : "ipad", 78 | "filename" : "Icon-App-29x29@2x.png", 79 | "scale" : "2x" 80 | }, 81 | { 82 | "size" : "40x40", 83 | "idiom" : "ipad", 84 | "filename" : "Icon-App-40x40@1x.png", 85 | "scale" : "1x" 86 | }, 87 | { 88 | "size" : "40x40", 89 | "idiom" : "ipad", 90 | "filename" : "Icon-App-40x40@2x.png", 91 | "scale" : "2x" 92 | }, 93 | { 94 | "size" : "76x76", 95 | "idiom" : "ipad", 96 | "filename" : "Icon-App-76x76@1x.png", 97 | "scale" : "1x" 98 | }, 99 | { 100 | "size" : "76x76", 101 | "idiom" : "ipad", 102 | "filename" : "Icon-App-76x76@2x.png", 103 | "scale" : "2x" 104 | }, 105 | { 106 | "size" : "83.5x83.5", 107 | "idiom" : "ipad", 108 | "filename" : "Icon-App-83.5x83.5@2x.png", 109 | "scale" : "2x" 110 | }, 111 | { 112 | "size" : "1024x1024", 113 | "idiom" : "ios-marketing", 114 | "filename" : "Icon-App-1024x1024@1x.png", 115 | "scale" : "1x" 116 | } 117 | ], 118 | "info" : { 119 | "version" : 1, 120 | "author" : "xcode" 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Decoder07/hms-callkit-demo/4cdbfee6d2bd443985aa9bfe436a1b30bf0c641a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Decoder07/hms-callkit-demo/4cdbfee6d2bd443985aa9bfe436a1b30bf0c641a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Decoder07/hms-callkit-demo/4cdbfee6d2bd443985aa9bfe436a1b30bf0c641a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Decoder07/hms-callkit-demo/4cdbfee6d2bd443985aa9bfe436a1b30bf0c641a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Decoder07/hms-callkit-demo/4cdbfee6d2bd443985aa9bfe436a1b30bf0c641a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Decoder07/hms-callkit-demo/4cdbfee6d2bd443985aa9bfe436a1b30bf0c641a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Decoder07/hms-callkit-demo/4cdbfee6d2bd443985aa9bfe436a1b30bf0c641a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Decoder07/hms-callkit-demo/4cdbfee6d2bd443985aa9bfe436a1b30bf0c641a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Decoder07/hms-callkit-demo/4cdbfee6d2bd443985aa9bfe436a1b30bf0c641a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Decoder07/hms-callkit-demo/4cdbfee6d2bd443985aa9bfe436a1b30bf0c641a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Decoder07/hms-callkit-demo/4cdbfee6d2bd443985aa9bfe436a1b30bf0c641a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Decoder07/hms-callkit-demo/4cdbfee6d2bd443985aa9bfe436a1b30bf0c641a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Decoder07/hms-callkit-demo/4cdbfee6d2bd443985aa9bfe436a1b30bf0c641a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Decoder07/hms-callkit-demo/4cdbfee6d2bd443985aa9bfe436a1b30bf0c641a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Decoder07/hms-callkit-demo/4cdbfee6d2bd443985aa9bfe436a1b30bf0c641a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "LaunchImage.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "LaunchImage@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "LaunchImage@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Decoder07/hms-callkit-demo/4cdbfee6d2bd443985aa9bfe436a1b30bf0c641a/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Decoder07/hms-callkit-demo/4cdbfee6d2bd443985aa9bfe436a1b30bf0c641a/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Decoder07/hms-callkit-demo/4cdbfee6d2bd443985aa9bfe436a1b30bf0c641a/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md: -------------------------------------------------------------------------------- 1 | # Launch Screen Assets 2 | 3 | You can customize the launch screen with your own desired assets by replacing the image files in this directory. 4 | 5 | You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images. -------------------------------------------------------------------------------- /ios/Runner/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /ios/Runner/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /ios/Runner/GoogleService-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CLIENT_ID 6 | 639484339298-q450qsqg6t7uopupiklago0me8mq0al7.apps.googleusercontent.com 7 | REVERSED_CLIENT_ID 8 | com.googleusercontent.apps.639484339298-q450qsqg6t7uopupiklago0me8mq0al7 9 | API_KEY 10 | AIzaSyChFexqq7iHsUAqZcZF3zOW0yrUD9o2dTI 11 | GCM_SENDER_ID 12 | 639484339298 13 | PLIST_VERSION 14 | 1 15 | BUNDLE_ID 16 | com.example.hmsCallkit 17 | PROJECT_ID 18 | hms-callkit-dd0c9 19 | STORAGE_BUCKET 20 | hms-callkit-dd0c9.appspot.com 21 | IS_ADS_ENABLED 22 | 23 | IS_ANALYTICS_ENABLED 24 | 25 | IS_APPINVITE_ENABLED 26 | 27 | IS_GCM_ENABLED 28 | 29 | IS_SIGNIN_ENABLED 30 | 31 | GOOGLE_APP_ID 32 | 1:639484339298:ios:e2e461e93cd90c217c9d3b 33 | 34 | -------------------------------------------------------------------------------- /ios/Runner/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleDisplayName 8 | Hms Callkit 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | hms_callkit 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | $(FLUTTER_BUILD_NAME) 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | $(FLUTTER_BUILD_NUMBER) 25 | LSRequiresIPhoneOS 26 | 27 | UILaunchStoryboardName 28 | LaunchScreen 29 | UIMainStoryboardFile 30 | Main 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | UISupportedInterfaceOrientations~ipad 38 | 39 | UIInterfaceOrientationPortrait 40 | UIInterfaceOrientationPortraitUpsideDown 41 | UIInterfaceOrientationLandscapeLeft 42 | UIInterfaceOrientationLandscapeRight 43 | 44 | UIViewControllerBasedStatusBarAppearance 45 | 46 | CADisableMinimumFrameDurationOnPhone 47 | 48 | UIApplicationSupportsIndirectInputEvents 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /ios/Runner/Runner-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | #import "GeneratedPluginRegistrant.h" 2 | -------------------------------------------------------------------------------- /ios/Runner/Runner.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | aps-environment 6 | development 7 | 8 | 9 | -------------------------------------------------------------------------------- /ios/firebase_app_id_file.json: -------------------------------------------------------------------------------- 1 | { 2 | "file_generated_by": "FlutterFire CLI", 3 | "purpose": "FirebaseAppID & ProjectID for this Firebase app in this directory", 4 | "GOOGLE_APP_ID": "1:639484339298:ios:e2e461e93cd90c217c9d3b", 5 | "FIREBASE_PROJECT_ID": "hms-callkit-dd0c9", 6 | "GCM_SENDER_ID": "639484339298" 7 | } -------------------------------------------------------------------------------- /lib/app_navigation/app_router.dart: -------------------------------------------------------------------------------- 1 | //Package imports 2 | 3 | import 'package:flutter/material.dart'; 4 | import 'package:hms_callkit/home_page.dart'; 5 | import 'package:hms_callkit/hmssdk/meeting_page.dart'; 6 | import 'package:hms_callkit/hmssdk/preview_page.dart'; 7 | import 'package:hms_callkit/receive_call.dart'; 8 | 9 | class AppRoute { 10 | static const homePage = '/home_page'; 11 | 12 | static const callingPage = '/meeting_page'; 13 | static const previewPage = '/preview_page'; 14 | static const receiveCallPage = '/receive-call-page'; 15 | 16 | static Route? generateRoute( 17 | RouteSettings settings){ 18 | switch (settings.name) { 19 | case homePage: 20 | return MaterialPageRoute( 21 | builder: (_) => HomePage(), settings: settings); 22 | case callingPage: 23 | return MaterialPageRoute( 24 | builder: (_) => MeetingPage( 25 | authToken: settings.arguments as String?, 26 | userName: 'Test User', 27 | ), 28 | settings: settings); 29 | case previewPage: 30 | return MaterialPageRoute( 31 | builder: (_) => PreviewPage( 32 | authToken: settings.arguments as String?, 33 | userName: 'Test User', 34 | ), 35 | settings: settings); 36 | case receiveCallPage: 37 | return MaterialPageRoute( 38 | builder: (_) => ReceiveCall( 39 | callKitParams: settings.arguments as Map)); 40 | default: 41 | return null; 42 | } 43 | } 44 | 45 | 46 | } 47 | -------------------------------------------------------------------------------- /lib/app_navigation/navigation_service.dart: -------------------------------------------------------------------------------- 1 | //Package imports 2 | import 'package:flutter/material.dart'; 3 | 4 | class NavigationService { 5 | // Global navigation key for whole application 6 | GlobalKey navigationKey = GlobalKey(); 7 | 8 | /// Get app context 9 | BuildContext? get appContext => navigationKey.currentContext; 10 | 11 | /// App route observer 12 | RouteObserver> routeObserver = RouteObserver>(); 13 | 14 | static final NavigationService _instance = NavigationService._private(); 15 | factory NavigationService() { 16 | return _instance; 17 | } 18 | NavigationService._private(); 19 | 20 | static NavigationService get instance => _instance; 21 | 22 | /// Pushing new page into navigation stack 23 | /// 24 | /// `routeName` is page's route name defined in [AppRoute] 25 | /// `args` is optional data to be sent to new page 26 | Future pushNamed(String routeName, 27 | {Object? args}) async { 28 | print(navigationKey); 29 | print(navigationKey.currentState); 30 | return navigationKey.currentState?.pushNamed( 31 | routeName, 32 | arguments: args, 33 | ); 34 | } 35 | 36 | Future pushNamedIfNotCurrent(String routeName, 37 | {Object? args}) async { 38 | if (!isCurrent(routeName)) { 39 | return pushNamed(routeName, args: args); 40 | } 41 | return null; 42 | } 43 | 44 | bool isCurrent(String routeName) { 45 | bool isCurrent = false; 46 | navigationKey.currentState!.popUntil((route) { 47 | if (route.settings.name == routeName) { 48 | isCurrent = true; 49 | } 50 | return true; 51 | }); 52 | return isCurrent; 53 | } 54 | 55 | /// Pushing new page into navigation stack 56 | /// 57 | /// `route` is route generator 58 | Future push(Route route) async { 59 | return navigationKey.currentState?.push(route); 60 | } 61 | 62 | /// Replace the current route of the navigator by pushing the given route and 63 | /// then disposing the previous route once the new route has finished 64 | /// animating in. 65 | Future pushReplacementNamed( 66 | String routeName, 67 | {Object? args}) async { 68 | return navigationKey.currentState?.pushReplacementNamed( 69 | routeName, 70 | arguments: args, 71 | ); 72 | } 73 | 74 | /// Push the route with the given name onto the navigator, and then remove all 75 | /// the previous routes until the `predicate` returns true. 76 | Future pushNamedAndRemoveUntil( 77 | String routeName, { 78 | Object? args, 79 | bool Function(Route)? predicate, 80 | }) async { 81 | return navigationKey.currentState?.pushNamedAndRemoveUntil( 82 | routeName, 83 | predicate ?? (_) => false, 84 | arguments: args, 85 | ); 86 | } 87 | 88 | /// Push the given route onto the navigator, and then remove all the previous 89 | /// routes until the `predicate` returns true. 90 | Future pushAndRemoveUntil( 91 | Route route, { 92 | bool Function(Route)? predicate, 93 | }) async { 94 | return navigationKey.currentState?.pushAndRemoveUntil( 95 | route, 96 | predicate ?? (_) => false, 97 | ); 98 | } 99 | 100 | /// Consults the current route's [Route.willPop] method, and acts accordingly, 101 | /// potentially popping the route as a result; returns whether the pop request 102 | /// should be considered handled. 103 | Future maybePop([Object? args]) async { 104 | return navigationKey.currentState!.maybePop(args as T); 105 | } 106 | 107 | /// Whether the navigator can be popped. 108 | bool canPop() => navigationKey.currentState!.canPop(); 109 | 110 | /// Pop the top-most route off the navigator. 111 | void goBack({T? result}) { 112 | navigationKey.currentState?.pop(result); 113 | } 114 | 115 | /// Calls [pop] repeatedly until the predicate returns true. 116 | void popUntil(String route) { 117 | navigationKey.currentState!.popUntil(ModalRoute.withName(route)); 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /lib/firebase_options.dart: -------------------------------------------------------------------------------- 1 | // File generated by FlutterFire CLI. 2 | // ignore_for_file: lines_longer_than_80_chars, avoid_classes_with_only_static_members 3 | import 'package:firebase_core/firebase_core.dart' show FirebaseOptions; 4 | import 'package:flutter/foundation.dart' 5 | show defaultTargetPlatform, kIsWeb, TargetPlatform; 6 | 7 | /// Default [FirebaseOptions] for use with your Firebase apps. 8 | /// 9 | /// Example: 10 | /// ```dart 11 | /// import 'firebase_options.dart'; 12 | /// // ... 13 | /// await Firebase.initializeApp( 14 | /// options: DefaultFirebaseOptions.currentPlatform, 15 | /// ); 16 | /// ``` 17 | class DefaultFirebaseOptions { 18 | static FirebaseOptions get currentPlatform { 19 | if (kIsWeb) { 20 | throw UnsupportedError( 21 | 'DefaultFirebaseOptions have not been configured for web - ' 22 | 'you can reconfigure this by running the FlutterFire CLI again.', 23 | ); 24 | } 25 | switch (defaultTargetPlatform) { 26 | case TargetPlatform.android: 27 | return android; 28 | case TargetPlatform.iOS: 29 | return ios; 30 | case TargetPlatform.macOS: 31 | throw UnsupportedError( 32 | 'DefaultFirebaseOptions have not been configured for macos - ' 33 | 'you can reconfigure this by running the FlutterFire CLI again.', 34 | ); 35 | case TargetPlatform.windows: 36 | throw UnsupportedError( 37 | 'DefaultFirebaseOptions have not been configured for windows - ' 38 | 'you can reconfigure this by running the FlutterFire CLI again.', 39 | ); 40 | case TargetPlatform.linux: 41 | throw UnsupportedError( 42 | 'DefaultFirebaseOptions have not been configured for linux - ' 43 | 'you can reconfigure this by running the FlutterFire CLI again.', 44 | ); 45 | default: 46 | throw UnsupportedError( 47 | 'DefaultFirebaseOptions are not supported for this platform.', 48 | ); 49 | } 50 | } 51 | 52 | static const FirebaseOptions android = FirebaseOptions( 53 | apiKey: 'AIzaSyBHWLPFpOUzUcy7v-ci_zAL9jYEBW9Mim0', 54 | appId: '1:639484339298:android:3a8154b3773841737c9d3b', 55 | messagingSenderId: '639484339298', 56 | projectId: 'hms-callkit-dd0c9', 57 | storageBucket: 'hms-callkit-dd0c9.appspot.com', 58 | ); 59 | 60 | static const FirebaseOptions ios = FirebaseOptions( 61 | apiKey: 'AIzaSyChFexqq7iHsUAqZcZF3zOW0yrUD9o2dTI', 62 | appId: '1:639484339298:ios:e2e461e93cd90c217c9d3b', 63 | messagingSenderId: '639484339298', 64 | projectId: 'hms-callkit-dd0c9', 65 | storageBucket: 'hms-callkit-dd0c9.appspot.com', 66 | iosClientId: '639484339298-q450qsqg6t7uopupiklago0me8mq0al7.apps.googleusercontent.com', 67 | iosBundleId: 'com.example.hmsCallkit', 68 | ); 69 | } 70 | -------------------------------------------------------------------------------- /lib/hmssdk/hmssdk_interactor.dart: -------------------------------------------------------------------------------- 1 | //Package imports 2 | 3 | import 'package:hmssdk_flutter/hmssdk_flutter.dart'; 4 | 5 | class HMSSDKInteractor { 6 | static HMSSDK? hmsSDK; 7 | 8 | HMSSDKInteractor() { 9 | hmsSDK = HMSSDK(); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /lib/hmssdk/join_service.dart: -------------------------------------------------------------------------------- 1 | //Dart imports 2 | import 'dart:convert'; 3 | import 'dart:developer'; 4 | 5 | //Package imports 6 | import 'package:http/http.dart' as http; 7 | 8 | Future getAuthToken( 9 | {required String roomId, 10 | required String tokenEndpoint, 11 | required String userId, 12 | required String role}) async { 13 | Uri endPoint = Uri.parse(tokenEndpoint); 14 | try { 15 | http.Response response = await http.post(endPoint, 16 | body: {'user_id': userId, 'room_id': roomId, 'role': role}); 17 | var body = json.decode(response.body); 18 | return body['token']; 19 | } catch (e) { 20 | log(e.toString()); 21 | return null; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /lib/hmssdk/meeting_page.dart: -------------------------------------------------------------------------------- 1 | //Dart imports 2 | import 'dart:developer'; 3 | 4 | //Package imports 5 | import 'package:draggable_widget/draggable_widget.dart'; 6 | import 'package:flutter/material.dart'; 7 | import 'package:hms_callkit/utility_functions.dart'; 8 | import 'package:hms_callkit/app_navigation/app_router.dart'; 9 | import 'package:hms_callkit/hmssdk/hmssdk_interactor.dart'; 10 | import 'package:hms_callkit/app_navigation/navigation_service.dart'; 11 | import 'package:hmssdk_flutter/hmssdk_flutter.dart'; 12 | 13 | class MeetingPage extends StatefulWidget { 14 | final String? authToken; 15 | final String userName; 16 | const MeetingPage({ 17 | super.key, 18 | this.authToken, 19 | required this.userName, 20 | }); 21 | 22 | @override 23 | State createState() => _MeetingPageState(); 24 | } 25 | 26 | class _MeetingPageState extends State 27 | with WidgetsBindingObserver 28 | implements HMSUpdateListener, HMSActionResultListener { 29 | Offset position = const Offset(5, 5); 30 | bool isJoinSuccessful = false; 31 | HMSPeer? localPeer, remotePeer; 32 | HMSVideoTrack? localPeerVideoTrack, remotePeerVideoTrack; 33 | bool isLocalVideoOn = true, isLocalAudioOn = true; 34 | 35 | @override 36 | Future didChangeAppLifecycleState(AppLifecycleState state) async {} 37 | 38 | @override 39 | void initState() { 40 | super.initState(); 41 | WidgetsBinding.instance.addObserver(this); 42 | joinCall(); 43 | } 44 | 45 | void joinCall() async { 46 | if (!isJoinSuccessful) { 47 | HMSSDKInteractor.hmsSDK ??= HMSSDK(); 48 | print("HMSSDK instance created"); 49 | await HMSSDKInteractor.hmsSDK?.build(); 50 | HMSSDKInteractor.hmsSDK?.addUpdateListener(listener: this); 51 | if (widget.authToken != null) { 52 | log("Join called..."); 53 | isJoinSuccessful = true; 54 | HMSSDKInteractor.hmsSDK?.join( 55 | config: HMSConfig( 56 | authToken: widget.authToken!, userName: widget.userName)); 57 | } else { 58 | log("authToken is null"); 59 | NavigationService.instance.pushNamedIfNotCurrent(AppRoute.homePage); 60 | } 61 | } 62 | } 63 | 64 | @override 65 | void dispose() { 66 | remotePeer = null; 67 | remotePeerVideoTrack = null; 68 | localPeer = null; 69 | localPeerVideoTrack = null; 70 | WidgetsBinding.instance.removeObserver(this); 71 | super.dispose(); 72 | } 73 | 74 | @override 75 | void onJoin({required HMSRoom room}) { 76 | room.peers?.forEach((peer) { 77 | if (peer.isLocal) { 78 | localPeer = peer; 79 | if (peer.videoTrack != null) { 80 | localPeerVideoTrack = peer.videoTrack; 81 | } 82 | if (mounted) { 83 | WidgetsBinding.instance.addPostFrameCallback((_) { 84 | setState(() {}); 85 | }); 86 | } 87 | } 88 | }); 89 | } 90 | 91 | @override 92 | void onPeerUpdate({required HMSPeer peer, required HMSPeerUpdate update}) { 93 | if (update == HMSPeerUpdate.networkQualityUpdated) { 94 | return; 95 | } 96 | if (update == HMSPeerUpdate.peerJoined) { 97 | if (!peer.isLocal) { 98 | if (mounted) { 99 | WidgetsBinding.instance.addPostFrameCallback((_) { 100 | setState(() { 101 | remotePeer = peer; 102 | }); 103 | }); 104 | } 105 | } 106 | } else if (update == HMSPeerUpdate.peerLeft) { 107 | if (!peer.isLocal) { 108 | if (mounted) { 109 | setState(() { 110 | remotePeer = null; 111 | }); 112 | } 113 | } else { 114 | if (mounted) { 115 | setState(() { 116 | localPeer = null; 117 | }); 118 | } 119 | } 120 | } 121 | } 122 | 123 | @override 124 | void onTrackUpdate( 125 | {required HMSTrack track, 126 | required HMSTrackUpdate trackUpdate, 127 | required HMSPeer peer}) { 128 | if (track.kind == HMSTrackKind.kHMSTrackKindVideo) { 129 | if (trackUpdate == HMSTrackUpdate.trackRemoved) { 130 | if (peer.isLocal) { 131 | if (mounted) { 132 | setState(() { 133 | localPeerVideoTrack = null; 134 | }); 135 | } 136 | } else { 137 | if (mounted) { 138 | setState(() { 139 | remotePeerVideoTrack = null; 140 | }); 141 | } 142 | } 143 | return; 144 | } 145 | if (peer.isLocal) { 146 | if (mounted) { 147 | setState(() { 148 | localPeerVideoTrack = track as HMSVideoTrack; 149 | }); 150 | } 151 | } else { 152 | if (mounted) { 153 | setState(() { 154 | remotePeerVideoTrack = track as HMSVideoTrack; 155 | }); 156 | } 157 | } 158 | } 159 | } 160 | 161 | @override 162 | void onAudioDeviceChanged( 163 | {HMSAudioDevice? currentAudioDevice, 164 | List? availableAudioDevice}) {} 165 | 166 | @override 167 | void onChangeTrackStateRequest( 168 | {required HMSTrackChangeRequest hmsTrackChangeRequest}) {} 169 | 170 | @override 171 | void onHMSError({required HMSException error}) {} 172 | 173 | @override 174 | void onMessage({required HMSMessage message}) {} 175 | 176 | @override 177 | void onReconnected() {} 178 | 179 | @override 180 | void onReconnecting() {} 181 | 182 | @override 183 | void onRemovedFromRoom( 184 | {required HMSPeerRemovedFromPeer hmsPeerRemovedFromPeer}) {} 185 | 186 | @override 187 | void onRoleChangeRequest({required HMSRoleChangeRequest roleChangeRequest}) {} 188 | 189 | @override 190 | void onRoomUpdate({required HMSRoom room, required HMSRoomUpdate update}) {} 191 | 192 | @override 193 | void onUpdateSpeakers({required List updateSpeakers}) {} 194 | 195 | @override 196 | Widget build(BuildContext context) { 197 | return WillPopScope( 198 | onWillPop: () async { 199 | HMSSDKInteractor.hmsSDK?.leave(hmsActionResultListener: this); 200 | return true; 201 | }, 202 | child: SafeArea( 203 | child: Scaffold( 204 | body: SizedBox( 205 | height: MediaQuery.of(context).size.height, 206 | width: MediaQuery.of(context).size.width, 207 | child: Stack( 208 | children: [ 209 | (remotePeerVideoTrack != null && remotePeer != null) 210 | ? peerTile( 211 | Key(remotePeerVideoTrack?.trackId ?? "" "mainVideo"), 212 | remotePeerVideoTrack, 213 | remotePeer, 214 | context, 215 | height: MediaQuery.of(context).size.height, 216 | width: MediaQuery.of(context).size.width) 217 | : Container( 218 | width: MediaQuery.of(context).size.width, 219 | color: Colors.black, 220 | height: MediaQuery.of(context).size.height, 221 | child: Column( 222 | mainAxisAlignment: MainAxisAlignment.center, 223 | crossAxisAlignment: CrossAxisAlignment.center, 224 | children: const [ 225 | Text( 226 | "Waiting for other peer to join", 227 | style: TextStyle(color: Colors.white, fontSize: 20), 228 | ), 229 | SizedBox(height: 10), 230 | CircularProgressIndicator( 231 | strokeWidth: 2, 232 | ) 233 | ], 234 | )), 235 | Align( 236 | alignment: Alignment.bottomCenter, 237 | child: Padding( 238 | padding: const EdgeInsets.only(bottom: 15), 239 | child: Row( 240 | mainAxisAlignment: MainAxisAlignment.spaceEvenly, 241 | children: [ 242 | GestureDetector( 243 | onTap: () async { 244 | HMSSDKInteractor.hmsSDK 245 | ?.leave(hmsActionResultListener: this); 246 | }, 247 | child: Container( 248 | decoration: 249 | BoxDecoration(shape: BoxShape.circle, boxShadow: [ 250 | BoxShadow( 251 | color: Colors.red.withAlpha(60), 252 | blurRadius: 3.0, 253 | spreadRadius: 5.0, 254 | ), 255 | ]), 256 | child: const CircleAvatar( 257 | radius: 25, 258 | backgroundColor: Colors.red, 259 | child: Icon(Icons.call_end, color: Colors.white), 260 | ), 261 | ), 262 | ), 263 | GestureDetector( 264 | onTap: () => { 265 | HMSSDKInteractor.hmsSDK?.toggleCameraMuteState(), 266 | if (mounted) 267 | { 268 | setState(() { 269 | isLocalVideoOn = !isLocalVideoOn; 270 | }) 271 | } 272 | }, 273 | child: CircleAvatar( 274 | radius: 25, 275 | backgroundColor: Colors.grey.withOpacity(0.3), 276 | child: Icon( 277 | isLocalVideoOn 278 | ? Icons.videocam 279 | : Icons.videocam_off_rounded, 280 | color: Colors.white, 281 | ), 282 | ), 283 | ), 284 | GestureDetector( 285 | onTap: () => { 286 | HMSSDKInteractor.hmsSDK?.toggleMicMuteState(), 287 | if (mounted) 288 | { 289 | setState(() { 290 | isLocalAudioOn = !isLocalAudioOn; 291 | }) 292 | } 293 | }, 294 | child: CircleAvatar( 295 | radius: 25, 296 | backgroundColor: Colors.grey.withOpacity(0.3), 297 | child: Icon( 298 | isLocalAudioOn ? Icons.mic : Icons.mic_off, 299 | color: Colors.white, 300 | ), 301 | ), 302 | ), 303 | ], 304 | ), 305 | ), 306 | ), 307 | DraggableWidget( 308 | topMargin: 10, 309 | bottomMargin: 130, 310 | horizontalSpace: 10, 311 | child: peerTile( 312 | Key(localPeerVideoTrack?.trackId ?? "" "mainVideo"), 313 | localPeerVideoTrack, 314 | localPeer, 315 | context), 316 | ) 317 | ], 318 | ), 319 | ), 320 | )), 321 | ); 322 | } 323 | 324 | Widget peerTile( 325 | Key key, HMSVideoTrack? videoTrack, HMSPeer? peer, BuildContext context, 326 | {double height = 150, double width = 100}) { 327 | return Container( 328 | height: height, 329 | width: width, 330 | key: key, 331 | color: Colors.grey.shade900, 332 | child: (videoTrack != null && !(videoTrack.isMute)) 333 | ? HMSVideoView( 334 | scaleType: ScaleType.SCALE_ASPECT_FILL, 335 | track: videoTrack, 336 | ) 337 | : Center( 338 | child: Container( 339 | decoration: BoxDecoration( 340 | color: Colors.blue.withAlpha(4), 341 | shape: BoxShape.circle, 342 | boxShadow: const [ 343 | BoxShadow( 344 | color: Colors.blue, 345 | blurRadius: 20.0, 346 | spreadRadius: 5.0, 347 | ), 348 | ], 349 | ), 350 | child: Text( 351 | peer?.name.substring(0, 1) ?? "D", 352 | style: const TextStyle( 353 | color: Colors.white, 354 | fontSize: 24, 355 | fontWeight: FontWeight.w600), 356 | ), 357 | ), 358 | ), 359 | ); 360 | } 361 | 362 | @override 363 | void onException( 364 | {required HMSActionResultListenerMethod methodType, 365 | Map? arguments, 366 | required HMSException hmsException}) { 367 | if (methodType == HMSActionResultListenerMethod.leave) { 368 | log("Error occured in leave"); 369 | } 370 | } 371 | 372 | @override 373 | void onSuccess( 374 | {required HMSActionResultListenerMethod methodType, 375 | Map? arguments}) { 376 | if (methodType == HMSActionResultListenerMethod.leave) { 377 | isJoinSuccessful = false; 378 | endAllCalls(); 379 | NavigationService.instance.pushNamedAndRemoveUntil(AppRoute.homePage); 380 | } 381 | } 382 | } 383 | -------------------------------------------------------------------------------- /lib/hmssdk/preview_page.dart: -------------------------------------------------------------------------------- 1 | import 'dart:developer'; 2 | 3 | import 'package:flutter/material.dart'; 4 | import 'package:hms_callkit/utility_functions.dart'; 5 | import 'package:hms_callkit/app_navigation/app_router.dart'; 6 | import 'package:hms_callkit/hmssdk/hmssdk_interactor.dart'; 7 | import 'package:hms_callkit/app_navigation/navigation_service.dart'; 8 | import 'package:hmssdk_flutter/hmssdk_flutter.dart'; 9 | 10 | class PreviewPage extends StatefulWidget { 11 | final String? authToken; 12 | final String userName; 13 | const PreviewPage({ 14 | super.key, 15 | this.authToken, 16 | required this.userName, 17 | }); 18 | 19 | @override 20 | State createState() => _PreviewPageState(); 21 | } 22 | 23 | class _PreviewPageState extends State 24 | implements HMSPreviewListener, HMSActionResultListener { 25 | Offset position = const Offset(5, 5); 26 | bool isPreviewSuccessful = false; 27 | HMSPeer? localPeer; 28 | HMSVideoTrack? localPeerVideoTrack; 29 | bool isLocalVideoOn = true, isLocalAudioOn = true; 30 | @override 31 | void initState() { 32 | super.initState(); 33 | joinCall(); 34 | } 35 | 36 | void joinCall() async { 37 | HMSSDKInteractor.hmsSDK ??= HMSSDK(); 38 | await HMSSDKInteractor.hmsSDK?.build(); 39 | if (widget.authToken != null) { 40 | HMSSDKInteractor.hmsSDK?.addPreviewListener(listener: this); 41 | HMSSDKInteractor.hmsSDK?.preview( 42 | config: HMSConfig( 43 | authToken: widget.authToken!, userName: widget.userName)); 44 | } else { 45 | log("authToken is null"); 46 | NavigationService.instance.pushNamedIfNotCurrent(AppRoute.homePage); 47 | } 48 | } 49 | 50 | @override 51 | void onPreview({required HMSRoom room, required List localTracks}) { 52 | room.peers?.forEach((peer) { 53 | if (peer.isLocal) { 54 | log("Peer is ${peer.toString()}"); 55 | localPeer = peer; 56 | } 57 | }); 58 | for (var track in localTracks) { 59 | if (track.kind == HMSTrackKind.kHMSTrackKindVideo) { 60 | log("Peer track is ${track.toString()}"); 61 | localPeerVideoTrack = track as HMSVideoTrack?; 62 | isLocalVideoOn = !(localPeerVideoTrack?.isMute ?? false); 63 | } else { 64 | isLocalAudioOn = ((track as HMSAudioTrack?)?.isMute ?? false); 65 | } 66 | } 67 | if (mounted) { 68 | setState(() {}); 69 | } 70 | } 71 | 72 | @override 73 | void dispose() { 74 | // TODO: implement dispose 75 | super.dispose(); 76 | HMSSDKInteractor.hmsSDK?.removePreviewListener(listener: this); 77 | } 78 | 79 | @override 80 | void onPeerUpdate({required HMSPeer peer, required HMSPeerUpdate update}) { 81 | log("On peer Update $update"); 82 | if (update == HMSPeerUpdate.networkQualityUpdated) { 83 | return; 84 | } 85 | if (update == HMSPeerUpdate.peerJoined) { 86 | if (!peer.isLocal) { 87 | NavigationService.instance.pushNamedAndRemoveUntil(AppRoute.callingPage, 88 | args: widget.authToken); 89 | } 90 | } else if (update == HMSPeerUpdate.peerLeft) { 91 | if (peer.isLocal) { 92 | if (mounted) { 93 | setState(() { 94 | localPeer = null; 95 | }); 96 | } 97 | } else { 98 | if (mounted) { 99 | setState(() { 100 | localPeer = null; 101 | }); 102 | } 103 | } 104 | } 105 | } 106 | 107 | @override 108 | void onAudioDeviceChanged( 109 | {HMSAudioDevice? currentAudioDevice, 110 | List? availableAudioDevice}) {} 111 | 112 | @override 113 | void onHMSError({required HMSException error}) {} 114 | 115 | @override 116 | void onRoomUpdate({required HMSRoom room, required HMSRoomUpdate update}) { 117 | log("On Room Update $update"); 118 | } 119 | 120 | @override 121 | Widget build(BuildContext context) { 122 | return WillPopScope( 123 | onWillPop: () async { 124 | HMSSDKInteractor.hmsSDK?.leave(hmsActionResultListener: this); 125 | return true; 126 | }, 127 | child: SafeArea( 128 | child: Scaffold( 129 | body: SizedBox( 130 | height: MediaQuery.of(context).size.height, 131 | width: MediaQuery.of(context).size.width, 132 | child: Stack( 133 | children: [ 134 | peerTile(Key(localPeerVideoTrack?.trackId ?? "" "mainVideo"), 135 | localPeerVideoTrack, localPeer, context, 136 | height: MediaQuery.of(context).size.height, 137 | width: MediaQuery.of(context).size.width), 138 | Align( 139 | alignment: Alignment.bottomCenter, 140 | child: Padding( 141 | padding: const EdgeInsets.only(bottom: 15), 142 | child: Row( 143 | mainAxisAlignment: MainAxisAlignment.spaceEvenly, 144 | children: [ 145 | GestureDetector( 146 | onTap: () => { 147 | HMSSDKInteractor.hmsSDK?.toggleCameraMuteState(), 148 | if (mounted) 149 | { 150 | setState(() { 151 | isLocalVideoOn = !isLocalVideoOn; 152 | }) 153 | } 154 | }, 155 | child: CircleAvatar( 156 | radius: 25, 157 | backgroundColor: Colors.grey.withOpacity(0.3), 158 | child: Icon( 159 | isLocalVideoOn 160 | ? Icons.videocam 161 | : Icons.videocam_off_rounded, 162 | color: Colors.white, 163 | ), 164 | ), 165 | ), 166 | GestureDetector( 167 | onTap: () => { 168 | HMSSDKInteractor.hmsSDK?.toggleMicMuteState(), 169 | if (mounted) 170 | { 171 | setState(() { 172 | isLocalAudioOn = !isLocalAudioOn; 173 | }) 174 | } 175 | }, 176 | child: CircleAvatar( 177 | radius: 25, 178 | backgroundColor: Colors.grey.withOpacity(0.3), 179 | child: Icon( 180 | isLocalAudioOn ? Icons.mic : Icons.mic_off, 181 | color: Colors.white, 182 | ), 183 | ), 184 | ), 185 | ], 186 | ), 187 | ), 188 | ), 189 | const Padding( 190 | padding: EdgeInsets.only(top: 100.0), 191 | child: Align( 192 | alignment: Alignment.topCenter, 193 | child: Text( 194 | "Ringing...", 195 | style: TextStyle( 196 | fontSize: 20, 197 | fontWeight: FontWeight.bold, 198 | color: Colors.white), 199 | ), 200 | ), 201 | ) 202 | ], 203 | ), 204 | ), 205 | )), 206 | ); 207 | } 208 | 209 | Widget peerTile( 210 | Key key, HMSVideoTrack? videoTrack, HMSPeer? peer, BuildContext context, 211 | {double height = 150, double width = 100}) { 212 | return Container( 213 | height: height, 214 | width: width, 215 | key: key, 216 | color: Colors.grey.shade900, 217 | child: (videoTrack != null && !(videoTrack.isMute)) 218 | ? HMSVideoView( 219 | scaleType: ScaleType.SCALE_ASPECT_FILL, 220 | track: videoTrack, 221 | ) 222 | : Center( 223 | child: Container( 224 | decoration: BoxDecoration( 225 | color: Colors.blue.withAlpha(4), 226 | shape: BoxShape.circle, 227 | boxShadow: const [ 228 | BoxShadow( 229 | color: Colors.blue, 230 | blurRadius: 20.0, 231 | spreadRadius: 5.0, 232 | ), 233 | ], 234 | ), 235 | child: Text( 236 | peer?.name.substring(0, 1) ?? "D", 237 | style: const TextStyle( 238 | color: Colors.white, 239 | fontSize: 24, 240 | fontWeight: FontWeight.w600), 241 | ), 242 | ), 243 | ), 244 | ); 245 | } 246 | 247 | @override 248 | void onException( 249 | {required HMSActionResultListenerMethod methodType, 250 | Map? arguments, 251 | required HMSException hmsException}) { 252 | if (methodType == HMSActionResultListenerMethod.leave) { 253 | log("Error occured in leave"); 254 | } 255 | } 256 | 257 | @override 258 | void onSuccess( 259 | {required HMSActionResultListenerMethod methodType, 260 | Map? arguments}) { 261 | if (methodType == HMSActionResultListenerMethod.leave) { 262 | endCurrentCall(); 263 | NavigationService.instance.pushNamedIfNotCurrent(AppRoute.homePage); 264 | } 265 | } 266 | } 267 | -------------------------------------------------------------------------------- /lib/home_page.dart: -------------------------------------------------------------------------------- 1 | //Package imports 2 | 3 | import 'package:flutter/material.dart'; 4 | import 'package:flutter/services.dart'; 5 | import 'package:flutter_callkit_incoming/entities/entities.dart'; 6 | import 'package:flutter_callkit_incoming/flutter_callkit_incoming.dart'; 7 | import 'package:hms_callkit/utility_functions.dart'; 8 | import 'package:hms_callkit/app_navigation/app_router.dart'; 9 | import 'package:hms_callkit/hmssdk/join_service.dart'; 10 | import 'package:hms_callkit/app_navigation/navigation_service.dart'; 11 | import 'package:share_plus/share_plus.dart'; 12 | 13 | class HomePage extends StatefulWidget { 14 | const HomePage({super.key}); 15 | 16 | @override 17 | State createState() => _HomePageState(); 18 | } 19 | 20 | class _HomePageState extends State { 21 | TextEditingController fcmTokenController = TextEditingController(); 22 | TextEditingController roomIdController = 23 | TextEditingController(); 24 | 25 | Future listenerEvent(Function? callback) async { 26 | try { 27 | FlutterCallkitIncoming.onEvent.listen((event) async { 28 | print(' HMSSDK HOME: $event'); 29 | switch (event!.event) { 30 | case Event.ACTION_CALL_INCOMING: 31 | break; 32 | case Event.ACTION_CALL_START: 33 | break; 34 | case Event.ACTION_CALL_ACCEPT: 35 | var data = event.body; 36 | String authToken = data["extra"]["authToken"]; 37 | String userName = data["nameCaller"]; 38 | bool res = await getPermissions(); 39 | if (res) { 40 | startOutGoingCall(); 41 | NavigationService.instance 42 | .pushNamed(AppRoute.callingPage, args: authToken); 43 | } 44 | break; 45 | case Event.ACTION_CALL_DECLINE: 46 | break; 47 | case Event.ACTION_CALL_ENDED: 48 | break; 49 | case Event.ACTION_CALL_TIMEOUT: 50 | break; 51 | case Event.ACTION_CALL_CALLBACK: 52 | break; 53 | case Event.ACTION_CALL_TOGGLE_HOLD: 54 | break; 55 | case Event.ACTION_CALL_TOGGLE_MUTE: 56 | break; 57 | case Event.ACTION_CALL_TOGGLE_DMTF: 58 | break; 59 | case Event.ACTION_CALL_TOGGLE_GROUP: 60 | break; 61 | case Event.ACTION_CALL_TOGGLE_AUDIO_SESSION: 62 | break; 63 | case Event.ACTION_DID_UPDATE_DEVICE_PUSH_TOKEN_VOIP: 64 | break; 65 | } 66 | if (callback != null) { 67 | callback(event.toString()); 68 | } 69 | }); 70 | } on Exception { 71 | print("HMSSDK Exception"); 72 | } 73 | } 74 | 75 | @override 76 | void initState() { 77 | super.initState(); 78 | listenerEvent(onEvent); 79 | } 80 | 81 | onEvent(event) { 82 | if (!mounted) return; 83 | setState(() { 84 | onEventLogs += "${event.toString()}\n"; 85 | }); 86 | } 87 | 88 | @override 89 | Widget build(BuildContext context) { 90 | return SafeArea( 91 | child: Scaffold( 92 | body: SingleChildScrollView( 93 | child: Container( 94 | width: MediaQuery.of(context).size.width, 95 | height: MediaQuery.of(context).size.height, 96 | color: Colors.black, 97 | child: Padding( 98 | padding: 99 | const EdgeInsets.symmetric(horizontal: 8.0, vertical: 30.0), 100 | child: Column( 101 | children: [ 102 | Align( 103 | alignment: Alignment.topLeft, 104 | child: RichText( 105 | text: const TextSpan( 106 | text: "Wanna try out", 107 | style: TextStyle( 108 | fontSize: 30, fontWeight: FontWeight.bold), 109 | children: [ 110 | TextSpan( 111 | text: "\nCalling", 112 | style: TextStyle( 113 | fontStyle: FontStyle.italic, fontSize: 35)), 114 | TextSpan( 115 | text: "\nShare the code below", 116 | style: TextStyle( 117 | fontSize: 30, fontWeight: FontWeight.bold), 118 | ) 119 | ])), 120 | ), 121 | const SizedBox( 122 | height: 10, 123 | ), 124 | Row( 125 | mainAxisAlignment: MainAxisAlignment.spaceBetween, 126 | children: [ 127 | Container( 128 | width: MediaQuery.of(context).size.width - 80, 129 | height: 40, 130 | decoration: BoxDecoration( 131 | borderRadius: BorderRadius.circular(10), 132 | color: Colors.grey.shade900), 133 | child: const Center( 134 | child: Text( 135 | "XXXX-XXXX-XXXX", 136 | overflow: TextOverflow.clip, 137 | style: 138 | TextStyle(fontSize: 20, color: Colors.white), 139 | ), 140 | ), 141 | ), 142 | InkWell( 143 | onTap: () { 144 | Clipboard.setData( 145 | ClipboardData(text: deviceFCMToken)); 146 | Share.share( 147 | deviceFCMToken, 148 | subject: 'Share device FCM Token', 149 | ); 150 | }, 151 | child: Container( 152 | width: 40, 153 | height: 40, 154 | decoration: BoxDecoration( 155 | border: Border.all( 156 | color: Colors.grey.shade900, width: 1), 157 | borderRadius: const BorderRadius.all( 158 | Radius.circular(12)), 159 | color: Colors.black), 160 | child: const Icon( 161 | Icons.copy, 162 | color: Colors.white, 163 | )), 164 | ), 165 | ], 166 | ), 167 | const SizedBox( 168 | height: 100, 169 | ), 170 | Padding( 171 | padding: const EdgeInsets.symmetric( 172 | horizontal: 8, vertical: 8), 173 | child: Row( 174 | mainAxisAlignment: MainAxisAlignment.spaceBetween, 175 | crossAxisAlignment: CrossAxisAlignment.end, 176 | children: const [ 177 | Text("Paste the FCM Token here", 178 | key: Key('fcm_token_text'), 179 | style: TextStyle(color: Colors.white)) 180 | ], 181 | ), 182 | ), 183 | SizedBox( 184 | width: MediaQuery.of(context).size.width * 0.95, 185 | child: TextField( 186 | key: Key('fcm_token_field'), 187 | textInputAction: TextInputAction.done, 188 | onSubmitted: (value) {}, 189 | controller: fcmTokenController, 190 | onChanged: (value) { 191 | setState(() {}); 192 | }, 193 | decoration: InputDecoration( 194 | focusColor: hmsdefaultColor, 195 | contentPadding: EdgeInsets.only(left: 16), 196 | fillColor: Colors.white, 197 | filled: true, 198 | hintText: 'Enter the FCM token here', 199 | suffixIcon: fcmTokenController.text.isEmpty 200 | ? null 201 | : IconButton( 202 | onPressed: () { 203 | fcmTokenController.text = ""; 204 | setState(() {}); 205 | }, 206 | icon: const Icon(Icons.clear), 207 | ), 208 | enabledBorder: OutlineInputBorder( 209 | borderSide: BorderSide( 210 | color: hmsdefaultColor, width: 1), 211 | borderRadius: 212 | const BorderRadius.all(Radius.circular(8))), 213 | border: const OutlineInputBorder( 214 | borderRadius: 215 | BorderRadius.all(Radius.circular(8)))), 216 | ), 217 | ), 218 | const SizedBox( 219 | height: 30, 220 | ), 221 | Padding( 222 | padding: const EdgeInsets.symmetric( 223 | horizontal: 8, vertical: 8), 224 | child: Row( 225 | mainAxisAlignment: MainAxisAlignment.spaceBetween, 226 | crossAxisAlignment: CrossAxisAlignment.end, 227 | children: const [ 228 | Text("Paste the room-id here", 229 | key: Key('room_id_text'), 230 | style: TextStyle(color: Colors.white)) 231 | ], 232 | ), 233 | ), 234 | SizedBox( 235 | width: MediaQuery.of(context).size.width * 0.95, 236 | child: TextField( 237 | key: const Key('room_id_field'), 238 | textInputAction: TextInputAction.done, 239 | onSubmitted: (value) {}, 240 | controller: roomIdController, 241 | onChanged: (value) { 242 | setState(() {}); 243 | }, 244 | decoration: InputDecoration( 245 | focusColor: hmsdefaultColor, 246 | contentPadding: const EdgeInsets.only(left: 16), 247 | fillColor: Colors.white, 248 | filled: true, 249 | hintText: 'Enter room-id here', 250 | suffixIcon: roomIdController.text.isEmpty 251 | ? null 252 | : IconButton( 253 | onPressed: () { 254 | roomIdController.text = ""; 255 | setState(() {}); 256 | }, 257 | icon: const Icon(Icons.clear), 258 | ), 259 | enabledBorder: OutlineInputBorder( 260 | borderSide: BorderSide( 261 | color: hmsdefaultColor, width: 1), 262 | borderRadius: 263 | const BorderRadius.all(Radius.circular(8))), 264 | border: const OutlineInputBorder( 265 | borderRadius: 266 | BorderRadius.all(Radius.circular(8)))), 267 | ), 268 | ), 269 | const SizedBox( 270 | height: 30, 271 | ), 272 | ElevatedButton( 273 | style: ButtonStyle( 274 | backgroundColor: 275 | MaterialStateProperty.all(hmsdefaultColor), 276 | shape: 277 | MaterialStateProperty.all( 278 | RoundedRectangleBorder( 279 | borderRadius: BorderRadius.circular(8.0), 280 | ))), 281 | onPressed: () async { 282 | if (fcmTokenController.text.isEmpty || 283 | roomIdController.text.isEmpty) { 284 | return; 285 | } 286 | await getPermissions(); 287 | //Enter the tokenEndPoint, role and userId here 288 | String? authToken = 289 | await getAuthToken( 290 | roomId: roomIdController.text, 291 | role: "Enter the role here", 292 | tokenEndpoint: 293 | "Enter your token endpoint here", 294 | userId: "Enter the user Id here"); 295 | //Checking whether authentication token is null or not 296 | if(authToken != null){ 297 | call( 298 | receiverFCMToken: fcmTokenController.text, 299 | authToken: authToken); 300 | NavigationService.instance.pushNamedIfNotCurrent( 301 | AppRoute.previewPage, 302 | args: authToken); 303 | } 304 | }, 305 | child: Padding( 306 | padding: const EdgeInsets.all(12.0), 307 | child: Row( 308 | mainAxisSize: MainAxisSize.min, 309 | mainAxisAlignment: MainAxisAlignment.center, 310 | children: const [ 311 | Icon( 312 | Icons.call, 313 | color: Colors.white, 314 | ), 315 | SizedBox( 316 | width: 5, 317 | ), 318 | Text( 319 | 'Call Now', 320 | style: TextStyle(color: Colors.white), 321 | ), 322 | ], 323 | ), 324 | ), 325 | ) 326 | ], 327 | ), 328 | )), 329 | ), 330 | ), 331 | ); 332 | } 333 | } 334 | -------------------------------------------------------------------------------- /lib/main.dart: -------------------------------------------------------------------------------- 1 | //Package imports 2 | import 'package:firebase_core/firebase_core.dart'; 3 | import 'package:firebase_messaging/firebase_messaging.dart'; 4 | import 'package:flutter/material.dart'; 5 | import 'package:hms_callkit/utility_functions.dart'; 6 | import 'package:hms_callkit/app_navigation/app_router.dart'; 7 | import 'package:hms_callkit/app_navigation/navigation_service.dart'; 8 | 9 | void main() async { 10 | WidgetsFlutterBinding.ensureInitialized(); 11 | await Firebase.initializeApp(); 12 | FirebaseMessaging.onBackgroundMessage(firebaseMessagingBackgroundHandler); 13 | runApp(const MyApp()); 14 | } 15 | 16 | class MyApp extends StatefulWidget { 17 | const MyApp({super.key}); 18 | 19 | @override 20 | State createState() => _MyAppState(); 21 | } 22 | 23 | class _MyAppState extends State { 24 | @override 25 | void initState() { 26 | super.initState(); 27 | initFirebase(); 28 | //Checks call when open app from terminated 29 | checkAndNavigationCallingPage("Navigation called from main.dart"); 30 | } 31 | 32 | @override 33 | Widget build(BuildContext context) { 34 | return MaterialApp( 35 | title: "HMS-Callkit Demo", 36 | onGenerateRoute: AppRoute.generateRoute, 37 | initialRoute: AppRoute.homePage, 38 | navigatorKey: NavigationService.instance.navigationKey, 39 | navigatorObservers: [ 40 | NavigationService.instance.routeObserver 41 | ], 42 | theme: ThemeData( 43 | primarySwatch: Colors.blue, 44 | ), 45 | ); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /lib/receive_call.dart: -------------------------------------------------------------------------------- 1 | //Package imports 2 | import 'package:flutter/material.dart'; 3 | import 'package:hms_callkit/utility_functions.dart'; 4 | import 'package:hms_callkit/app_navigation/app_router.dart'; 5 | import 'package:hms_callkit/app_navigation/navigation_service.dart'; 6 | 7 | class ReceiveCall extends StatefulWidget { 8 | final Map? callKitParams; 9 | const ReceiveCall({super.key,required this.callKitParams}); 10 | 11 | @override 12 | State createState() => _ReceiveCallState(); 13 | } 14 | 15 | class _ReceiveCallState extends State { 16 | @override 17 | Widget build(BuildContext context) { 18 | return SafeArea( 19 | child: Scaffold( 20 | body: Center( 21 | child: Container( 22 | color: Colors.black, 23 | width: MediaQuery.of(context).size.width, 24 | child: Column( 25 | mainAxisAlignment: MainAxisAlignment.center, 26 | children: [ 27 | ClipRRect( 28 | borderRadius: BorderRadius.circular(50), 29 | child: Image(image: NetworkImage(widget.callKitParams?["avatar"]),fit: BoxFit.fill,height: 100,width: 100,)), 30 | const SizedBox(height: 60,), 31 | ElevatedButton( 32 | style: ButtonStyle( 33 | backgroundColor: 34 | MaterialStateProperty.all(hmsdefaultColor), 35 | shape: 36 | MaterialStateProperty.all( 37 | RoundedRectangleBorder( 38 | borderRadius: BorderRadius.circular(8.0), 39 | ))), 40 | onPressed: () async { 41 | NavigationService.instance.pushNamedIfNotCurrent( 42 | AppRoute.callingPage, 43 | args: widget.callKitParams!["extra"]["authToken"]); 44 | }, 45 | child: Padding( 46 | padding: const EdgeInsets.all(12.0), 47 | child: Row( 48 | mainAxisSize: MainAxisSize.min, 49 | mainAxisAlignment: MainAxisAlignment.center, 50 | children: const [ 51 | Icon( 52 | Icons.call, 53 | color: Colors.white, 54 | ), 55 | SizedBox( 56 | width: 5, 57 | ), 58 | Text( 59 | 'Join Call', 60 | style: TextStyle(color: Colors.white), 61 | ), 62 | ], 63 | ), 64 | ), 65 | ) 66 | ], 67 | ), 68 | ), 69 | ), 70 | )); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /lib/utility_functions.dart: -------------------------------------------------------------------------------- 1 | //Dart imports 2 | import 'dart:convert'; 3 | import 'dart:developer'; 4 | import 'dart:io'; 5 | 6 | //Package imports 7 | import 'package:cloud_functions/cloud_functions.dart'; 8 | import 'package:firebase_messaging/firebase_messaging.dart'; 9 | import 'package:flutter/material.dart'; 10 | import 'package:flutter_callkit_incoming/entities/entities.dart'; 11 | import 'package:flutter_callkit_incoming/flutter_callkit_incoming.dart'; 12 | import 'package:hms_callkit/app_navigation/app_router.dart'; 13 | import 'package:hms_callkit/app_navigation/navigation_service.dart'; 14 | import 'package:permission_handler/permission_handler.dart'; 15 | import 'package:uuid/uuid.dart'; 16 | 17 | Uuid? _uniqueCallId; 18 | String? _currentCallId; 19 | String onEventLogs = ""; 20 | late final FirebaseMessaging _firebaseMessaging; 21 | String deviceFCMToken = ""; 22 | Color hmsdefaultColor = const Color.fromRGBO(36, 113, 237, 1); 23 | 24 | //Handles when app is in background or terminated 25 | Future firebaseMessagingBackgroundHandler(RemoteMessage message) async { 26 | var response = jsonDecode(message.data["params"]); 27 | CallKitParams data = CallKitParams.fromJson(response); 28 | if (data.extra?.containsKey("authToken") ?? false) { 29 | placeCall(data.extra!["authToken"]); 30 | } else { 31 | log("No Valid authToken found"); 32 | } 33 | } 34 | 35 | //This initializes the firebase 36 | void initFirebase() async { 37 | print("Firebase init"); 38 | _uniqueCallId = const Uuid(); 39 | _firebaseMessaging = FirebaseMessaging.instance; 40 | NotificationSettings settings = await _firebaseMessaging.requestPermission( 41 | alert: true, 42 | badge: true, 43 | provisional: false, 44 | sound: true, 45 | ); 46 | if (settings.authorizationStatus != AuthorizationStatus.authorized) { 47 | return; 48 | } 49 | deviceFCMToken = await _firebaseMessaging.getToken() ?? ""; 50 | FirebaseMessaging.onMessage.listen((RemoteMessage message) async { 51 | print("HMSSDK Value is ${message.data["params"]}"); 52 | var response = jsonDecode(message.data["params"]); 53 | CallKitParams data = CallKitParams.fromJson(response); 54 | if (data.extra?.containsKey("authToken") ?? false) { 55 | print("HMSSDK Received Notification"); 56 | placeCall(data.extra!["authToken"]); 57 | } else { 58 | log("No Valid authToken found"); 59 | } 60 | }); 61 | _firebaseMessaging.getToken().then((token) { 62 | log('Device Token FCM: $token'); 63 | }); 64 | initCurrentCall(); 65 | } 66 | 67 | //This function returns the currently running call if any 68 | _getCurrentCall() async { 69 | var calls = await FlutterCallkitIncoming.activeCalls(); 70 | if (calls is List) { 71 | if (calls.isNotEmpty) { 72 | log('DATA: $calls'); 73 | _currentCallId = calls[0]['id']; 74 | return calls[0]; 75 | } else { 76 | _currentCallId = ""; 77 | return null; 78 | } 79 | } 80 | } 81 | 82 | //Method to place the call 83 | Future placeCall(String authToken) async { 84 | await FlutterCallkitIncoming.showCallkitIncoming(getCallInfo(authToken)); 85 | } 86 | 87 | //This function navigates to the call screen if a call is currently running 88 | void checkAndNavigationCallingPage(String message) async { 89 | var currentCall = await _getCurrentCall(); 90 | bool res = await getPermissions(); 91 | if(currentCall != null){ 92 | Map callData = {}; 93 | currentCall.forEach((key, value) { 94 | callData[key] = value; 95 | }); 96 | if (res == true && currentCall != null && currentCall["extra"] != null) { 97 | NavigationService.instance 98 | .pushNamedIfNotCurrent(AppRoute.callingPage, args: currentCall["extra"]["authToken"]); 99 | } 100 | } 101 | } 102 | 103 | //To make a fake call on same device 104 | Future makeFakeCallInComing() async { 105 | await Future.delayed(const Duration(seconds: 5), () async { 106 | _currentCallId = _uniqueCallId?.v4(); 107 | 108 | final params = CallKitParams( 109 | id: _currentCallId, 110 | nameCaller: 'Test User', 111 | appName: 'Callkit', 112 | avatar: 'https://i.pravatar.cc/100', 113 | handle: '0123456789', 114 | type: 1, 115 | duration: 30000, 116 | textAccept: 'Accept', 117 | textDecline: 'Decline', 118 | textMissedCall: 'Missed call', 119 | textCallback: 'Call back', 120 | extra: { 121 | 'userId': '1a2b3c4d', 122 | 'authToken': "Enter your authToken here", 123 | }, 124 | headers: {'apiKey': 'Abc@123!', 'platform': 'flutter'}, 125 | android: const AndroidParams( 126 | isCustomNotification: true, 127 | isShowLogo: false, 128 | isShowCallback: true, 129 | isShowMissedCallNotification: true, 130 | ringtonePath: 'system_ringtone_default', 131 | backgroundColor: '#0955fa', 132 | backgroundUrl: 'assets/test.png', 133 | actionColor: '#4CAF50', 134 | incomingCallNotificationChannelName: 'Incoming Call', 135 | missedCallNotificationChannelName: 'Missed Call', 136 | ), 137 | ios: IOSParams( 138 | iconName: 'CallKitLogo', 139 | handleType: '', 140 | supportsVideo: true, 141 | maximumCallGroups: 2, 142 | maximumCallsPerCallGroup: 1, 143 | audioSessionMode: 'default', 144 | audioSessionActive: true, 145 | audioSessionPreferredSampleRate: 44100.0, 146 | audioSessionPreferredIOBufferDuration: 0.005, 147 | supportsDTMF: true, 148 | supportsHolding: true, 149 | supportsGrouping: false, 150 | supportsUngrouping: false, 151 | ringtonePath: 'system_ringtone_default', 152 | ), 153 | ); 154 | await FlutterCallkitIncoming.showCallkitIncoming(params); 155 | }); 156 | } 157 | 158 | //To start a call but we are directly logging into the meeting 159 | Future startOutGoingCall() async { 160 | _currentCallId = _uniqueCallId?.v4(); 161 | final params = CallKitParams( 162 | id: _currentCallId, 163 | nameCaller: 'Test user', 164 | handle: '0123456789', 165 | type: 1, 166 | extra: {'userId': '1a2b3c4d'}, 167 | ios: IOSParams(handleType: 'number'), 168 | ); 169 | await FlutterCallkitIncoming.startCall(params); 170 | } 171 | 172 | //This method returns all the calls running currently 173 | Future activeCalls() async { 174 | var calls = await FlutterCallkitIncoming.activeCalls(); 175 | log(calls); 176 | } 177 | 178 | //This method ends all the calls that are running currently 179 | Future endAllCalls() async { 180 | await FlutterCallkitIncoming.endAllCalls(); 181 | } 182 | 183 | //This function fetches the calls that are currently active and set the _currentCallId to that call 184 | initCurrentCall() async { 185 | var calls = await FlutterCallkitIncoming.activeCalls(); 186 | if (calls is List) { 187 | if (calls.isNotEmpty) { 188 | log('DATA: $calls'); 189 | _currentCallId = calls[0]['id']; 190 | return calls[0]; 191 | } else { 192 | _currentCallId = ""; 193 | return null; 194 | } 195 | } 196 | } 197 | 198 | //This method ends the currently running call 199 | Future endCurrentCall() async { 200 | initCurrentCall(); 201 | await FlutterCallkitIncoming.endCall(_currentCallId!); 202 | } 203 | 204 | //To get microphone and camera permissions 205 | Future getPermissions() async { 206 | if (Platform.isIOS) return true; 207 | await Permission.camera.request(); 208 | await Permission.microphone.request(); 209 | await Permission.bluetoothConnect.request(); 210 | 211 | while ((await Permission.camera.isDenied)) { 212 | await Permission.camera.request(); 213 | } 214 | while ((await Permission.microphone.isDenied)) { 215 | await Permission.microphone.request(); 216 | } 217 | while ((await Permission.bluetoothConnect.isDenied)) { 218 | await Permission.bluetoothConnect.request(); 219 | } 220 | return true; 221 | } 222 | 223 | //This is used to get the deviceFCM token just for printing in logs 224 | Future getDevicePushTokenVoIP() async { 225 | var devicePushTokenVoIP = 226 | await FlutterCallkitIncoming.getDevicePushTokenVoIP(); 227 | log("Device token is $devicePushTokenVoIP"); 228 | return devicePushTokenVoIP; 229 | } 230 | 231 | //This method sends the notification to the receiver's device 232 | Future call( 233 | {required String receiverFCMToken, required String authToken}) async { 234 | var func = FirebaseFunctions.instance.httpsCallable("notifySubscribers"); 235 | startOutGoingCall(); 236 | await func.call({ 237 | "targetDevices": [receiverFCMToken], //Enter the device fcmToken here 238 | "messageTitle": "Incoming Call", 239 | "messageBody": "Someone is calling you...", 240 | "callkitParams": json.encode(getCallInfo(authToken).toJson()) 241 | }); 242 | } 243 | 244 | //This method is used to set the info which needs to be sent to the receiver for joining the room and showing the caller UI 245 | CallKitParams getCallInfo(String authToken) { 246 | if (_uniqueCallId == null) { 247 | _uniqueCallId = const Uuid(); 248 | _currentCallId = _uniqueCallId?.v4(); 249 | } 250 | return CallKitParams( 251 | id: _uniqueCallId?.v4(), 252 | nameCaller: 'Test User', 253 | appName: 'HMS Call', 254 | avatar: 'https://i.pravatar.cc/100', 255 | handle: '0123456789', 256 | type: 1, 257 | duration: 60000, 258 | textAccept: 'Accept', 259 | textDecline: 'Decline', 260 | textMissedCall: 'Missed call', 261 | textCallback: 'Call back', 262 | extra: {'authToken': authToken}, 263 | android: const AndroidParams( 264 | isCustomNotification: true, 265 | isShowLogo: false, 266 | isShowCallback: true, 267 | isShowMissedCallNotification: true, 268 | ringtonePath: 'system_ringtone_default', 269 | backgroundColor: '#0955fa', 270 | backgroundUrl: 'assets/test.png', 271 | actionColor: '#4CAF50', 272 | ), 273 | ios: IOSParams( 274 | iconName: 'CallKitLogo', 275 | handleType: '', 276 | supportsVideo: true, 277 | maximumCallGroups: 2, 278 | maximumCallsPerCallGroup: 1, 279 | audioSessionMode: 'default', 280 | audioSessionActive: true, 281 | audioSessionPreferredSampleRate: 44100.0, 282 | audioSessionPreferredIOBufferDuration: 0.005, 283 | supportsDTMF: true, 284 | supportsHolding: true, 285 | supportsGrouping: false, 286 | supportsUngrouping: false, 287 | ringtonePath: 'system_ringtone_default', 288 | ), 289 | ); 290 | } 291 | -------------------------------------------------------------------------------- /pubspec.lock: -------------------------------------------------------------------------------- 1 | # Generated by pub 2 | # See https://dart.dev/tools/pub/glossary#lockfile 3 | packages: 4 | _flutterfire_internals: 5 | dependency: transitive 6 | description: 7 | name: _flutterfire_internals 8 | sha256: "6215ac7d00ed98300b72f45ed2b38c2ca841f9f4e6965fab33cbd591e45e4473" 9 | url: "https://pub.dev" 10 | source: hosted 11 | version: "1.0.13" 12 | async: 13 | dependency: transitive 14 | description: 15 | name: async 16 | sha256: bfe67ef28df125b7dddcea62755991f807aa39a2492a23e1550161692950bbe0 17 | url: "https://pub.dev" 18 | source: hosted 19 | version: "2.10.0" 20 | boolean_selector: 21 | dependency: transitive 22 | description: 23 | name: boolean_selector 24 | sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66" 25 | url: "https://pub.dev" 26 | source: hosted 27 | version: "2.1.1" 28 | characters: 29 | dependency: transitive 30 | description: 31 | name: characters 32 | sha256: e6a326c8af69605aec75ed6c187d06b349707a27fbff8222ca9cc2cff167975c 33 | url: "https://pub.dev" 34 | source: hosted 35 | version: "1.2.1" 36 | clock: 37 | dependency: transitive 38 | description: 39 | name: clock 40 | sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf 41 | url: "https://pub.dev" 42 | source: hosted 43 | version: "1.1.1" 44 | cloud_functions: 45 | dependency: "direct main" 46 | description: 47 | name: cloud_functions 48 | sha256: "7650b1b61a53dfe82cd05048477b526d57360a0b5b432c16b4e8d5cf61b30a7f" 49 | url: "https://pub.dev" 50 | source: hosted 51 | version: "4.0.8" 52 | cloud_functions_platform_interface: 53 | dependency: transitive 54 | description: 55 | name: cloud_functions_platform_interface 56 | sha256: "0de65c92bea969f4b3edc8e9bfb945205a3b75d86a1922881fdfd3f00b250b19" 57 | url: "https://pub.dev" 58 | source: hosted 59 | version: "5.1.27" 60 | cloud_functions_web: 61 | dependency: transitive 62 | description: 63 | name: cloud_functions_web 64 | sha256: "5c588d9cadd7c2107e56052f0dfd279500c4ea358b09ec97afd48cdead14029d" 65 | url: "https://pub.dev" 66 | source: hosted 67 | version: "4.3.16" 68 | collection: 69 | dependency: transitive 70 | description: 71 | name: collection 72 | sha256: cfc915e6923fe5ce6e153b0723c753045de46de1b4d63771530504004a45fae0 73 | url: "https://pub.dev" 74 | source: hosted 75 | version: "1.17.0" 76 | cross_file: 77 | dependency: transitive 78 | description: 79 | name: cross_file 80 | sha256: "0b0036e8cccbfbe0555fd83c1d31a6f30b77a96b598b35a5d36dd41f718695e9" 81 | url: "https://pub.dev" 82 | source: hosted 83 | version: "0.3.3+4" 84 | crypto: 85 | dependency: transitive 86 | description: 87 | name: crypto 88 | sha256: aa274aa7774f8964e4f4f38cc994db7b6158dd36e9187aaceaddc994b35c6c67 89 | url: "https://pub.dev" 90 | source: hosted 91 | version: "3.0.2" 92 | cupertino_icons: 93 | dependency: "direct main" 94 | description: 95 | name: cupertino_icons 96 | sha256: e35129dc44c9118cee2a5603506d823bab99c68393879edb440e0090d07586be 97 | url: "https://pub.dev" 98 | source: hosted 99 | version: "1.0.5" 100 | draggable_widget: 101 | dependency: "direct main" 102 | description: 103 | name: draggable_widget 104 | sha256: d7f6b1eb9cb79b724b02dc2ac699f82d1ab20b99920b8b1f25812054d72ca803 105 | url: "https://pub.dev" 106 | source: hosted 107 | version: "2.0.0" 108 | fake_async: 109 | dependency: transitive 110 | description: 111 | name: fake_async 112 | sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78" 113 | url: "https://pub.dev" 114 | source: hosted 115 | version: "1.3.1" 116 | ffi: 117 | dependency: transitive 118 | description: 119 | name: ffi 120 | sha256: a38574032c5f1dd06c4aee541789906c12ccaab8ba01446e800d9c5b79c4a978 121 | url: "https://pub.dev" 122 | source: hosted 123 | version: "2.0.1" 124 | file: 125 | dependency: transitive 126 | description: 127 | name: file 128 | sha256: "1b92bec4fc2a72f59a8e15af5f52cd441e4a7860b49499d69dfa817af20e925d" 129 | url: "https://pub.dev" 130 | source: hosted 131 | version: "6.1.4" 132 | firebase_core: 133 | dependency: "direct main" 134 | description: 135 | name: firebase_core 136 | sha256: be13e431c0c950f0fc66bdb67b41b8059121d7e7d8bbbc21fb59164892d561f8 137 | url: "https://pub.dev" 138 | source: hosted 139 | version: "2.5.0" 140 | firebase_core_platform_interface: 141 | dependency: transitive 142 | description: 143 | name: firebase_core_platform_interface 144 | sha256: "5615b30c36f55b2777d0533771deda7e5730e769e5d3cb7fda79e9bed86cfa55" 145 | url: "https://pub.dev" 146 | source: hosted 147 | version: "4.5.3" 148 | firebase_core_web: 149 | dependency: transitive 150 | description: 151 | name: firebase_core_web 152 | sha256: "4b3a41410f3313bb95fd560aa5eb761b6ad65c185de772c72231e8b4aeed6d18" 153 | url: "https://pub.dev" 154 | source: hosted 155 | version: "2.1.1" 156 | firebase_messaging: 157 | dependency: "direct main" 158 | description: 159 | name: firebase_messaging 160 | sha256: dbccddc62fef6f3745ba83062bfd1fbf2eb6a931db4c73d03f85c5772dfdec7f 161 | url: "https://pub.dev" 162 | source: hosted 163 | version: "14.2.2" 164 | firebase_messaging_platform_interface: 165 | dependency: "direct main" 166 | description: 167 | name: firebase_messaging_platform_interface 168 | sha256: "564a47ea76db9cd2d17e7d95790428ad3de9d0075795d14c4c901ba0bf518e1a" 169 | url: "https://pub.dev" 170 | source: hosted 171 | version: "4.2.11" 172 | firebase_messaging_web: 173 | dependency: transitive 174 | description: 175 | name: firebase_messaging_web 176 | sha256: "76291494583a003d4ce0d613c41cb87c58fab25773317daa66a245f537e1c3f7" 177 | url: "https://pub.dev" 178 | source: hosted 179 | version: "3.2.12" 180 | flutter: 181 | dependency: "direct main" 182 | description: flutter 183 | source: sdk 184 | version: "0.0.0" 185 | flutter_callkit_incoming: 186 | dependency: "direct main" 187 | description: 188 | name: flutter_callkit_incoming 189 | sha256: "8e76be35d86bce00c358fc083c6f6232a7630958616d3e49cbc89ef661a4a464" 190 | url: "https://pub.dev" 191 | source: hosted 192 | version: "1.0.3+3" 193 | flutter_lints: 194 | dependency: "direct dev" 195 | description: 196 | name: flutter_lints 197 | sha256: aeb0b80a8b3709709c9cc496cdc027c5b3216796bc0af0ce1007eaf24464fd4c 198 | url: "https://pub.dev" 199 | source: hosted 200 | version: "2.0.1" 201 | flutter_test: 202 | dependency: "direct dev" 203 | description: flutter 204 | source: sdk 205 | version: "0.0.0" 206 | flutter_web_plugins: 207 | dependency: transitive 208 | description: flutter 209 | source: sdk 210 | version: "0.0.0" 211 | hmssdk_flutter: 212 | dependency: "direct main" 213 | description: 214 | name: hmssdk_flutter 215 | sha256: "8efca6fc1e7eb03655889e2ac3b103b5cfb92e49a28be9d7d49fba02d642549b" 216 | url: "https://pub.dev" 217 | source: hosted 218 | version: "1.3.0" 219 | http: 220 | dependency: "direct main" 221 | description: 222 | name: http 223 | sha256: "6aa2946395183537c8b880962d935877325d6a09a2867c3970c05c0fed6ac482" 224 | url: "https://pub.dev" 225 | source: hosted 226 | version: "0.13.5" 227 | http_parser: 228 | dependency: transitive 229 | description: 230 | name: http_parser 231 | sha256: "2aa08ce0341cc9b354a498388e30986515406668dbcc4f7c950c3e715496693b" 232 | url: "https://pub.dev" 233 | source: hosted 234 | version: "4.0.2" 235 | js: 236 | dependency: transitive 237 | description: 238 | name: js 239 | sha256: "5528c2f391ededb7775ec1daa69e65a2d61276f7552de2b5f7b8d34ee9fd4ab7" 240 | url: "https://pub.dev" 241 | source: hosted 242 | version: "0.6.5" 243 | json_annotation: 244 | dependency: transitive 245 | description: 246 | name: json_annotation 247 | sha256: c33da08e136c3df0190bd5bbe51ae1df4a7d96e7954d1d7249fea2968a72d317 248 | url: "https://pub.dev" 249 | source: hosted 250 | version: "4.8.0" 251 | lints: 252 | dependency: transitive 253 | description: 254 | name: lints 255 | sha256: "5e4a9cd06d447758280a8ac2405101e0e2094d2a1dbdd3756aec3fe7775ba593" 256 | url: "https://pub.dev" 257 | source: hosted 258 | version: "2.0.1" 259 | matcher: 260 | dependency: transitive 261 | description: 262 | name: matcher 263 | sha256: "16db949ceee371e9b99d22f88fa3a73c4e59fd0afed0bd25fc336eb76c198b72" 264 | url: "https://pub.dev" 265 | source: hosted 266 | version: "0.12.13" 267 | material_color_utilities: 268 | dependency: transitive 269 | description: 270 | name: material_color_utilities 271 | sha256: d92141dc6fe1dad30722f9aa826c7fbc896d021d792f80678280601aff8cf724 272 | url: "https://pub.dev" 273 | source: hosted 274 | version: "0.2.0" 275 | meta: 276 | dependency: transitive 277 | description: 278 | name: meta 279 | sha256: "6c268b42ed578a53088d834796959e4a1814b5e9e164f147f580a386e5decf42" 280 | url: "https://pub.dev" 281 | source: hosted 282 | version: "1.8.0" 283 | mime: 284 | dependency: transitive 285 | description: 286 | name: mime 287 | sha256: e4ff8e8564c03f255408decd16e7899da1733852a9110a58fe6d1b817684a63e 288 | url: "https://pub.dev" 289 | source: hosted 290 | version: "1.0.4" 291 | path: 292 | dependency: transitive 293 | description: 294 | name: path 295 | sha256: db9d4f58c908a4ba5953fcee2ae317c94889433e5024c27ce74a37f94267945b 296 | url: "https://pub.dev" 297 | source: hosted 298 | version: "1.8.2" 299 | path_provider: 300 | dependency: transitive 301 | description: 302 | name: path_provider 303 | sha256: dcea5feb97d8abf90cab9e9030b497fb7c3cbf26b7a1fe9e3ef7dcb0a1ddec95 304 | url: "https://pub.dev" 305 | source: hosted 306 | version: "2.0.12" 307 | path_provider_android: 308 | dependency: transitive 309 | description: 310 | name: path_provider_android 311 | sha256: a776c088d671b27f6e3aa8881d64b87b3e80201c64e8869b811325de7a76c15e 312 | url: "https://pub.dev" 313 | source: hosted 314 | version: "2.0.22" 315 | path_provider_foundation: 316 | dependency: transitive 317 | description: 318 | name: path_provider_foundation 319 | sha256: "62a68e7e1c6c459f9289859e2fae58290c981ce21d1697faf54910fe1faa4c74" 320 | url: "https://pub.dev" 321 | source: hosted 322 | version: "2.1.1" 323 | path_provider_linux: 324 | dependency: transitive 325 | description: 326 | name: path_provider_linux 327 | sha256: ab0987bf95bc591da42dffb38c77398fc43309f0b9b894dcc5d6f40c4b26c379 328 | url: "https://pub.dev" 329 | source: hosted 330 | version: "2.1.7" 331 | path_provider_platform_interface: 332 | dependency: transitive 333 | description: 334 | name: path_provider_platform_interface 335 | sha256: f0abc8ebd7253741f05488b4813d936b4d07c6bae3e86148a09e342ee4b08e76 336 | url: "https://pub.dev" 337 | source: hosted 338 | version: "2.0.5" 339 | path_provider_windows: 340 | dependency: transitive 341 | description: 342 | name: path_provider_windows 343 | sha256: bcabbe399d4042b8ee687e17548d5d3f527255253b4a639f5f8d2094a9c2b45c 344 | url: "https://pub.dev" 345 | source: hosted 346 | version: "2.1.3" 347 | permission_handler: 348 | dependency: "direct main" 349 | description: 350 | name: permission_handler 351 | sha256: "33c6a1253d1f95fd06fa74b65b7ba907ae9811f9d5c1d3150e51417d04b8d6a8" 352 | url: "https://pub.dev" 353 | source: hosted 354 | version: "10.2.0" 355 | permission_handler_android: 356 | dependency: transitive 357 | description: 358 | name: permission_handler_android 359 | sha256: "8028362b40c4a45298f1cbfccd227c8dd6caf0e27088a69f2ba2ab15464159e2" 360 | url: "https://pub.dev" 361 | source: hosted 362 | version: "10.2.0" 363 | permission_handler_apple: 364 | dependency: transitive 365 | description: 366 | name: permission_handler_apple 367 | sha256: "9c370ef6a18b1c4b2f7f35944d644a56aa23576f23abee654cf73968de93f163" 368 | url: "https://pub.dev" 369 | source: hosted 370 | version: "9.0.7" 371 | permission_handler_platform_interface: 372 | dependency: transitive 373 | description: 374 | name: permission_handler_platform_interface 375 | sha256: "68abbc472002b5e6dfce47fe9898c6b7d8328d58b5d2524f75e277c07a97eb84" 376 | url: "https://pub.dev" 377 | source: hosted 378 | version: "3.9.0" 379 | permission_handler_windows: 380 | dependency: transitive 381 | description: 382 | name: permission_handler_windows 383 | sha256: f67cab14b4328574938ecea2db3475dad7af7ead6afab6338772c5f88963e38b 384 | url: "https://pub.dev" 385 | source: hosted 386 | version: "0.1.2" 387 | platform: 388 | dependency: transitive 389 | description: 390 | name: platform 391 | sha256: "4a451831508d7d6ca779f7ac6e212b4023dd5a7d08a27a63da33756410e32b76" 392 | url: "https://pub.dev" 393 | source: hosted 394 | version: "3.1.0" 395 | plugin_platform_interface: 396 | dependency: transitive 397 | description: 398 | name: plugin_platform_interface 399 | sha256: dbf0f707c78beedc9200146ad3cb0ab4d5da13c246336987be6940f026500d3a 400 | url: "https://pub.dev" 401 | source: hosted 402 | version: "2.1.3" 403 | process: 404 | dependency: transitive 405 | description: 406 | name: process 407 | sha256: "53fd8db9cec1d37b0574e12f07520d582019cb6c44abf5479a01505099a34a09" 408 | url: "https://pub.dev" 409 | source: hosted 410 | version: "4.2.4" 411 | share_plus: 412 | dependency: "direct main" 413 | description: 414 | name: share_plus 415 | sha256: e387077716f80609bb979cd199331033326033ecd1c8f200a90c5f57b1c9f55e 416 | url: "https://pub.dev" 417 | source: hosted 418 | version: "6.3.0" 419 | share_plus_platform_interface: 420 | dependency: transitive 421 | description: 422 | name: share_plus_platform_interface 423 | sha256: "82ddd4ab9260c295e6e39612d4ff00390b9a7a21f1bb1da771e2f232d80ab8a1" 424 | url: "https://pub.dev" 425 | source: hosted 426 | version: "3.2.0" 427 | sky_engine: 428 | dependency: transitive 429 | description: flutter 430 | source: sdk 431 | version: "0.0.99" 432 | source_span: 433 | dependency: transitive 434 | description: 435 | name: source_span 436 | sha256: dd904f795d4b4f3b870833847c461801f6750a9fa8e61ea5ac53f9422b31f250 437 | url: "https://pub.dev" 438 | source: hosted 439 | version: "1.9.1" 440 | stack_trace: 441 | dependency: transitive 442 | description: 443 | name: stack_trace 444 | sha256: c3c7d8edb15bee7f0f74debd4b9c5f3c2ea86766fe4178eb2a18eb30a0bdaed5 445 | url: "https://pub.dev" 446 | source: hosted 447 | version: "1.11.0" 448 | stream_channel: 449 | dependency: transitive 450 | description: 451 | name: stream_channel 452 | sha256: "83615bee9045c1d322bbbd1ba209b7a749c2cbcdcb3fdd1df8eb488b3279c1c8" 453 | url: "https://pub.dev" 454 | source: hosted 455 | version: "2.1.1" 456 | string_scanner: 457 | dependency: transitive 458 | description: 459 | name: string_scanner 460 | sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde" 461 | url: "https://pub.dev" 462 | source: hosted 463 | version: "1.2.0" 464 | term_glyph: 465 | dependency: transitive 466 | description: 467 | name: term_glyph 468 | sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84 469 | url: "https://pub.dev" 470 | source: hosted 471 | version: "1.2.1" 472 | test_api: 473 | dependency: transitive 474 | description: 475 | name: test_api 476 | sha256: ad540f65f92caa91bf21dfc8ffb8c589d6e4dc0c2267818b4cc2792857706206 477 | url: "https://pub.dev" 478 | source: hosted 479 | version: "0.4.16" 480 | typed_data: 481 | dependency: transitive 482 | description: 483 | name: typed_data 484 | sha256: "26f87ade979c47a150c9eaab93ccd2bebe70a27dc0b4b29517f2904f04eb11a5" 485 | url: "https://pub.dev" 486 | source: hosted 487 | version: "1.3.1" 488 | url_launcher_linux: 489 | dependency: transitive 490 | description: 491 | name: url_launcher_linux 492 | sha256: "318c42cba924e18180c029be69caf0a1a710191b9ec49bb42b5998fdcccee3cc" 493 | url: "https://pub.dev" 494 | source: hosted 495 | version: "3.0.2" 496 | url_launcher_platform_interface: 497 | dependency: transitive 498 | description: 499 | name: url_launcher_platform_interface 500 | sha256: "4eae912628763eb48fc214522e58e942fd16ce195407dbf45638239523c759a6" 501 | url: "https://pub.dev" 502 | source: hosted 503 | version: "2.1.1" 504 | url_launcher_web: 505 | dependency: transitive 506 | description: 507 | name: url_launcher_web 508 | sha256: "44d79408ce9f07052095ef1f9a693c258d6373dc3944249374e30eff7219ccb0" 509 | url: "https://pub.dev" 510 | source: hosted 511 | version: "2.0.14" 512 | url_launcher_windows: 513 | dependency: transitive 514 | description: 515 | name: url_launcher_windows 516 | sha256: b6217370f8eb1fd85c8890c539f5a639a01ab209a36db82c921ebeacefc7a615 517 | url: "https://pub.dev" 518 | source: hosted 519 | version: "3.0.3" 520 | uuid: 521 | dependency: "direct main" 522 | description: 523 | name: uuid 524 | sha256: "2469694ad079893e3b434a627970c33f2fa5adc46dfe03c9617546969a9a8afc" 525 | url: "https://pub.dev" 526 | source: hosted 527 | version: "3.0.6" 528 | vector_math: 529 | dependency: transitive 530 | description: 531 | name: vector_math 532 | sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803" 533 | url: "https://pub.dev" 534 | source: hosted 535 | version: "2.1.4" 536 | win32: 537 | dependency: transitive 538 | description: 539 | name: win32 540 | sha256: c9ebe7ee4ab0c2194e65d3a07d8c54c5d00bb001b76081c4a04cdb8448b59e46 541 | url: "https://pub.dev" 542 | source: hosted 543 | version: "3.1.3" 544 | xdg_directories: 545 | dependency: transitive 546 | description: 547 | name: xdg_directories 548 | sha256: bd512f03919aac5f1313eb8249f223bacf4927031bf60b02601f81f687689e86 549 | url: "https://pub.dev" 550 | source: hosted 551 | version: "0.2.0+3" 552 | sdks: 553 | dart: ">=2.19.0 <3.0.0" 554 | flutter: ">=3.0.0" 555 | -------------------------------------------------------------------------------- /pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: hms_callkit 2 | description: A new Flutter project. 3 | # The following line prevents the package from being accidentally published to 4 | # pub.dev using `flutter pub publish`. This is preferred for private packages. 5 | publish_to: 'none' # Remove this line if you wish to publish to pub.dev 6 | 7 | # The following defines the version and build number for your application. 8 | # A version number is three numbers separated by dots, like 1.2.43 9 | # followed by an optional build number separated by a +. 10 | # Both the version and the builder number may be overridden in flutter 11 | # build by specifying --build-name and --build-number, respectively. 12 | # In Android, build-name is used as versionName while build-number used as versionCode. 13 | # Read more about Android versioning at https://developer.android.com/studio/publish/versioning 14 | # In iOS, build-name is used as CFBundleShortVersionString while build-number is used as CFBundleVersion. 15 | # Read more about iOS versioning at 16 | # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html 17 | # In Windows, build-name is used as the major, minor, and patch parts 18 | # of the product and file versions while build-number is used as the build suffix. 19 | version: 1.0.0+1 20 | 21 | environment: 22 | sdk: '>=2.19.0 <3.0.0' 23 | 24 | # Dependencies specify other packages that your package needs in order to work. 25 | # To automatically upgrade your package dependencies to the latest versions 26 | # consider running `flutter pub upgrade --major-versions`. Alternatively, 27 | # dependencies can be manually updated by changing the version numbers below to 28 | # the latest version available on pub.dev. To see which dependencies have newer 29 | # versions available, run `flutter pub outdated`. 30 | dependencies: 31 | flutter: 32 | sdk: flutter 33 | 34 | 35 | # The following adds the Cupertino Icons font to your application. 36 | # Use with the CupertinoIcons class for iOS style icons. 37 | cupertino_icons: ^1.0.2 38 | firebase_messaging: 39 | firebase_core: 40 | firebase_messaging_platform_interface: 41 | uuid: 3.0.6 42 | http: ^0.13.4 43 | hmssdk_flutter: 44 | git: 45 | url: https://github.com/100mslive/100ms-flutter.git 46 | ref: plugin-android-fix 47 | permission_handler: 10.2.0 48 | flutter_callkit_incoming: 49 | cloud_functions: 50 | draggable_widget: 2.0.0 51 | share_plus: 6.3.0 52 | dev_dependencies: 53 | flutter_test: 54 | sdk: flutter 55 | 56 | # The "flutter_lints" package below contains a set of recommended lints to 57 | # encourage good coding practices. The lint set provided by the package is 58 | # activated in the `analysis_options.yaml` file located at the root of your 59 | # package. See that file for information about deactivating specific lint 60 | # rules and activating additional ones. 61 | flutter_lints: ^2.0.0 62 | 63 | # For information on the generic Dart part of this file, see the 64 | # following page: https://dart.dev/tools/pub/pubspec 65 | 66 | # The following section is specific to Flutter packages. 67 | flutter: 68 | 69 | # The following line ensures that the Material Icons font is 70 | # included with your application, so that you can use the icons in 71 | # the material Icons class. 72 | uses-material-design: true 73 | 74 | # To add assets to your application, add an assets section, like this: 75 | # assets: 76 | # - images/a_dot_burr.jpeg 77 | # - images/a_dot_ham.jpeg 78 | 79 | # An image asset can refer to one or more resolution-specific "variants", see 80 | # https://flutter.dev/assets-and-images/#resolution-aware 81 | 82 | # For details regarding adding assets from package dependencies, see 83 | # https://flutter.dev/assets-and-images/#from-packages 84 | 85 | # To add custom fonts to your application, add a fonts section here, 86 | # in this "flutter" section. Each entry in this list should have a 87 | # "family" key with the font family name, and a "fonts" key with a 88 | # list giving the asset and other descriptors for the font. For 89 | # example: 90 | # fonts: 91 | # - family: Schyler 92 | # fonts: 93 | # - asset: fonts/Schyler-Regular.ttf 94 | # - asset: fonts/Schyler-Italic.ttf 95 | # style: italic 96 | # - family: Trajan Pro 97 | # fonts: 98 | # - asset: fonts/TrajanPro.ttf 99 | # - asset: fonts/TrajanPro_Bold.ttf 100 | # weight: 700 101 | # 102 | # For details regarding fonts from package dependencies, 103 | # see https://flutter.dev/custom-fonts/#from-packages 104 | -------------------------------------------------------------------------------- /test/widget_test.dart: -------------------------------------------------------------------------------- 1 | // This is a basic Flutter widget test. 2 | // 3 | // To perform an interaction with a widget in your test, use the WidgetTester 4 | // utility in the flutter_test package. For example, you can send tap and scroll 5 | // gestures. You can also use WidgetTester to find child widgets in the widget 6 | // tree, read text, and verify that the values of widget properties are correct. 7 | 8 | import 'package:flutter/material.dart'; 9 | import 'package:flutter_test/flutter_test.dart'; 10 | 11 | import 'package:hms_callkit/main.dart'; 12 | 13 | void main() { 14 | testWidgets('Counter increments smoke test', (WidgetTester tester) async { 15 | // Build our app and trigger a frame. 16 | await tester.pumpWidget(const MyApp()); 17 | 18 | // Verify that our counter starts at 0. 19 | expect(find.text('0'), findsOneWidget); 20 | expect(find.text('1'), findsNothing); 21 | 22 | // Tap the '+' icon and trigger a frame. 23 | await tester.tap(find.byIcon(Icons.add)); 24 | await tester.pump(); 25 | 26 | // Verify that our counter has incremented. 27 | expect(find.text('0'), findsNothing); 28 | expect(find.text('1'), findsOneWidget); 29 | }); 30 | } 31 | --------------------------------------------------------------------------------