├── .gitignore
├── .idea
├── modules.xml
├── runConfigurations
│ └── example_lib_main_dart.xml
└── vcs.xml
├── .metadata
├── CHANGELOG.md
├── LICENSE
├── README.md
├── android
├── .gitignore
├── build.gradle
├── gradle.properties
├── libs
│ ├── .gitignore
│ └── go.jar
├── settings.gradle
└── src
│ └── main
│ ├── AndroidManifest.xml
│ └── java
│ └── io
│ └── github
│ └── empirefox
│ └── flutter_dial_go
│ ├── DialService.java
│ ├── Dialer.java
│ ├── FlutterDialGoPlugin.java
│ ├── Pipe.java
│ └── SimpleForegroundNotification.java
├── doc.go
├── example
├── .gitignore
├── .metadata
├── README.md
├── android
│ ├── .gitignore
│ ├── app
│ │ ├── build.gradle
│ │ └── src
│ │ │ ├── debug
│ │ │ └── AndroidManifest.xml
│ │ │ ├── main
│ │ │ ├── AndroidManifest.xml
│ │ │ ├── java
│ │ │ │ └── io
│ │ │ │ │ └── github
│ │ │ │ │ └── empirefox
│ │ │ │ │ └── flutter_dial_go_example
│ │ │ │ │ └── MainActivity.java
│ │ │ └── res
│ │ │ │ ├── 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
│ │ │ │ └── styles.xml
│ │ │ └── profile
│ │ │ └── AndroidManifest.xml
│ ├── build.gradle
│ ├── go
│ │ ├── .gitignore
│ │ └── build.gradle
│ ├── gradle.properties
│ ├── gradle
│ │ └── wrapper
│ │ │ └── gradle-wrapper.properties
│ └── settings.gradle
├── flutter_dial_go_example.iml
├── ios
│ ├── .gitignore
│ ├── Flutter
│ │ ├── AppFrameworkInfo.plist
│ │ ├── Debug.xcconfig
│ │ └── Release.xcconfig
│ ├── Frameworks
│ │ └── .gitignore
│ ├── Podfile
│ ├── Podfile.lock
│ ├── Runner.xcodeproj
│ │ ├── project.pbxproj
│ │ ├── project.xcworkspace
│ │ │ └── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ │ └── xcschemes
│ │ │ └── Runner.xcscheme
│ ├── Runner.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ │ ├── IDEWorkspaceChecks.plist
│ │ │ └── WorkspaceSettings.xcsettings
│ └── Runner
│ │ ├── AppDelegate.swift
│ │ ├── Assets.xcassets
│ │ ├── AppIcon.appiconset
│ │ │ ├── Contents.json
│ │ │ ├── Icon-App-1024x1024@1x.png
│ │ │ ├── Icon-App-20x20@1x.png
│ │ │ ├── Icon-App-20x20@2x.png
│ │ │ ├── Icon-App-20x20@3x.png
│ │ │ ├── Icon-App-29x29@1x.png
│ │ │ ├── Icon-App-29x29@2x.png
│ │ │ ├── Icon-App-29x29@3x.png
│ │ │ ├── Icon-App-40x40@1x.png
│ │ │ ├── Icon-App-40x40@2x.png
│ │ │ ├── Icon-App-40x40@3x.png
│ │ │ ├── Icon-App-60x60@2x.png
│ │ │ ├── Icon-App-60x60@3x.png
│ │ │ ├── Icon-App-76x76@1x.png
│ │ │ ├── Icon-App-76x76@2x.png
│ │ │ └── Icon-App-83.5x83.5@2x.png
│ │ └── LaunchImage.imageset
│ │ │ ├── Contents.json
│ │ │ ├── LaunchImage.png
│ │ │ ├── LaunchImage@2x.png
│ │ │ ├── LaunchImage@3x.png
│ │ │ └── README.md
│ │ ├── Base.lproj
│ │ ├── LaunchScreen.storyboard
│ │ └── Main.storyboard
│ │ ├── Info.plist
│ │ └── Runner-Bridging-Header.h
├── lib
│ ├── main.dart
│ └── src
│ │ ├── app.dart
│ │ └── generated
│ │ ├── helloworld.pb.dart
│ │ ├── helloworld.pbenum.dart
│ │ ├── helloworld.pbgrpc.dart
│ │ └── helloworld.pbjson.dart
├── pubspec.yaml
└── test
│ └── widget_test.dart
├── flutter_dial_go.iml
├── go
├── Makefile
├── example
│ ├── Makefile
│ ├── gomobile
│ │ └── mobile.go
│ ├── internal
│ │ └── gomobile
│ │ │ ├── proxy.go
│ │ │ └── server.go
│ └── protos
│ │ ├── helloworld.pb.go
│ │ └── helloworld.proto
├── forgo
│ └── forgo.go
├── formobile
│ └── formobile.go
└── internal
│ └── listener
│ ├── listener.go
│ ├── pipe.go
│ └── pipefordialer.go
├── ios
├── .gitignore
├── Assets
│ └── .gitkeep
├── Classes
│ ├── Dialer.swift
│ ├── FlutterDialGoPlugin.h
│ ├── FlutterDialGoPlugin.m
│ ├── Pipe.swift
│ └── SwiftFlutterDialGoPlugin.swift
└── flutter_dial_go.podspec
├── lib
└── flutter_dial_go.dart
├── pubspec.lock
├── pubspec.yaml
└── test
└── flutter_dial_go_test.dart
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | .dart_tool/
3 |
4 | .packages
5 | .pub/
6 |
7 | build/
8 |
9 | .idea/codeStyles/Project.xml
10 | .idea/libraries/Dart_SDK.xml
11 | .idea/libraries/Flutter_Plugins.xml
12 | .idea/libraries/Flutter_for_Android.xml
13 | .idea/gradle.xml
14 | .idea/misc.xml
15 | .idea/workspace.xml
16 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/.idea/runConfigurations/example_lib_main_dart.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.metadata:
--------------------------------------------------------------------------------
1 | # This file tracks properties of this Flutter project.
2 | # Used by Flutter tool to assess capabilities and perform upgrades etc.
3 | #
4 | # This file should be version controlled and should not be manually edited.
5 |
6 | version:
7 | revision: 8661d8aecd626f7f57ccbcb735553edc05a2e713
8 | channel: dev
9 |
10 | project_type: plugin
11 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | ## 0.0.1
2 |
3 | * TODO: Describe initial release.
4 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | TODO: Add your license here.
2 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # flutter_dial_go
2 |
3 | A flutter plugin for connecting to golang embeded servers via platform channel.
4 |
5 | ## Getting Started
6 |
7 | ### Example
8 |
9 | ```bash
10 | make -f ./go/Makefile protoc
11 | make -f ./go/Makefile bind-android
12 | make -f ./go/Makefile bind-ios
13 | flutter run
14 | ```
15 |
16 | ### Install for golang
17 |
18 | ```bash
19 | go get -u github.com/empirefox/flutter_dial_go
20 | cd GOPATH/github.com/empirefox/flutter_dial_go/go
21 | make android
22 | ```
23 |
24 | ### Install for flutter project
25 |
26 | Add to `pubsepc.yml`, replace `GOPATH` with real path.
27 |
28 | ```yaml
29 | dependencies:
30 | flutter_dial_go:
31 | path: GOPATH/github.com/empirefox/flutter_dial_go
32 | ```
33 |
34 | ### Develop golang side
35 |
36 | When write go code:
37 | Only use `github.com/empirefox/flutter_dial_go/go/forgo`.
38 | Do not use `github.com/empirefox/flutter_dial_go/go/formobile`.
39 |
40 | ```go
41 | import "github.com/empirefox/flutter_dial_go/go/forgo"
42 |
43 | // dart usage: var conn = await Conn.dial(9999)
44 | listener, err := forgo.Listen(9999)
45 | ```
46 |
47 | - Implement `gomobile` package exactly like: [Go Example](go/example/gomobile/mobile.go).
48 | - Copy [Makefile](go/example/Makefile) to flutter project, then replace the `GOMOBILE_PKG`, `APP_PATH` and `protoc:`.
49 | - Build with the new `Makefile`.
50 | - For Android Studio: import `go.aar` and add `api project(':go')` to `PROJECT_DIR$/android/app/build.gradle`.
51 | - For Xcode: add `PODS_ROOT/../Frameworks` to all Framework search paths.
52 |
53 | ### Develop flutter side
54 |
55 | Init with no service.
56 |
57 | ```dart
58 | import 'package:flutter_dial_go/flutter_dial_go.dart';
59 |
60 | Future initGo() async {
61 | await Conn.startGo();
62 | }
63 | ```
64 |
65 | Or init with foreground service. For ios, service will not start and it will work like above.
66 |
67 | ```dart
68 | import 'package:flutter_dial_go/flutter_dial_go.dart';
69 |
70 | Future initGo() async {
71 | await Conn.notificationChannel(
72 | channelId: channelId,
73 | importance: importance,
74 | name: 'fdg running',
75 | description: 'keep fdg running',
76 | );
77 | await Conn.startGoWithService(
78 | channelId: channelId,
79 | notificationId: notificationId,
80 | title: 'flutter_dial_go example',
81 | text: 'make flutter dial go',
82 | );
83 | }
84 | ```
85 |
86 | Then dial:
87 |
88 | ```dart
89 | // raw http request
90 | // golang: forgo.Listen(9998)
91 | Conn c = await Conn.dial(9998);
92 | print('GET /\n');
93 | c.receiveStream
94 | .fold(BytesBuilder(), (BytesBuilder a, List b) => a..add(b))
95 | .then((a) => setState(() {
96 | _result = 'GET / HTTP/1.0\n\n' + utf8.decode(a.takeBytes());
97 | }))
98 | .catchError((e) => setState(() {
99 | _result = 'Caught http error: e';
100 | }))
101 | .then((_) => c.close());
102 | c.add(utf8.encode('GET / HTTP/1.0\r\n\r\n'));
103 | ```
104 |
105 | Or http2:
106 |
107 | ```dart
108 | // golang: forgo.Listen(9997)
109 | Conn c = await Conn.dial(9997);
110 | var transport = ClientTransportConnection.viaStreams(c.receiveStream, c);
111 | ```
112 |
113 | Or grpc:
114 |
115 | ```dart
116 | Future _connect(String host, int port, ChannelCredentials credentials) async {
117 | // ignore: close_sinks
118 | final conn = await Conn.dial(port);
119 | return Http2Streams(conn.receiveStream, conn);
120 | }
121 |
122 | var channel = ClientChannel(
123 | 'go',
124 | port: 9999,
125 | options: ChannelOptions(
126 | credentials: ChannelCredentials.insecure(),
127 | connect: _connect,
128 | ),
129 | );
130 | var stub = GreeterClient(_channel);
131 |
132 | ...
133 |
134 | channel.terminate();
135 | ```
136 |
137 | [Flutter Example](example/lib/src/app.dart).
138 |
--------------------------------------------------------------------------------
/android/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /local.properties
4 | /.idea/workspace.xml
5 | /.idea/libraries
6 | .DS_Store
7 | /build
8 | /captures
9 |
--------------------------------------------------------------------------------
/android/build.gradle:
--------------------------------------------------------------------------------
1 | group 'io.github.empirefox.flutter_dial_go'
2 | version '1.0-SNAPSHOT'
3 |
4 | buildscript {
5 | repositories {
6 | google()
7 | jcenter()
8 | }
9 |
10 | dependencies {
11 | classpath 'com.android.tools.build:gradle:3.2.1'
12 | }
13 | }
14 |
15 | rootProject.allprojects {
16 | repositories {
17 | flatDir {
18 | dirs 'libs'
19 | }
20 | google()
21 | jcenter()
22 | }
23 | }
24 |
25 | apply plugin: 'com.android.library'
26 |
27 | android {
28 | compileSdkVersion 28
29 |
30 | defaultConfig {
31 | minSdkVersion 16
32 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
33 | }
34 | lintOptions {
35 | disable 'InvalidPackage'
36 | }
37 | compileOptions {
38 | targetCompatibility 1.8
39 | sourceCompatibility 1.8
40 | }
41 | }
42 |
43 | dependencies {
44 | compileOnly fileTree(dir: 'libs', include: ['*.jar', '*.aar'])
45 | implementation "androidx.core:core:1.0.0"
46 | }
47 |
--------------------------------------------------------------------------------
/android/gradle.properties:
--------------------------------------------------------------------------------
1 | org.gradle.jvmargs=-Xmx1536M
2 |
--------------------------------------------------------------------------------
/android/libs/.gitignore:
--------------------------------------------------------------------------------
1 | go-sources.jar
--------------------------------------------------------------------------------
/android/libs/go.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/empirefox/flutter_dial_go/5bd3bae6801d81588d3c26ecdadae915c390f5a9/android/libs/go.jar
--------------------------------------------------------------------------------
/android/settings.gradle:
--------------------------------------------------------------------------------
1 | rootProject.name = 'flutter_dial_go'
2 |
--------------------------------------------------------------------------------
/android/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
--------------------------------------------------------------------------------
/android/src/main/java/io/github/empirefox/flutter_dial_go/DialService.java:
--------------------------------------------------------------------------------
1 | package io.github.empirefox.flutter_dial_go;
2 |
3 | import android.app.Notification;
4 | import android.app.PendingIntent;
5 | import android.app.Service;
6 | import android.content.Context;
7 | import android.content.Intent;
8 | import android.content.pm.PackageManager;
9 | import android.os.Binder;
10 | import android.os.Build;
11 | import android.os.IBinder;
12 | import android.os.Looper;
13 | import android.util.Log;
14 |
15 | import androidx.core.app.NotificationCompat;
16 |
17 |
18 | public class DialService extends Service {
19 | private static final String TAG = "DialService#";
20 | public static final String ACTION_START = "ACTION_START";
21 | public static final String ACTION_STOP = "ACTION_STOP";
22 | private static final String INTENT_EXTRA_KEY_SFN = "sfn";
23 |
24 | private Dialer dialer = null;
25 | private final IBinder binder = new DialerBinder();
26 |
27 | public static Intent createIntent(Context context, SimpleForegroundNotification sfn) {
28 | Intent intent = new Intent(context, DialService.class);
29 | if (sfn != null) {
30 | intent.setAction(ACTION_START).putExtra(INTENT_EXTRA_KEY_SFN, sfn);
31 | } else {
32 | intent.setAction(ACTION_STOP);
33 | }
34 | return intent;
35 | }
36 |
37 | public static Dialer getDialer(IBinder binder) {
38 | return ((DialerBinder) binder).getDialer();
39 | }
40 |
41 | private class DialerBinder extends Binder {
42 | Dialer getDialer() {
43 | return dialer;
44 | }
45 | }
46 |
47 | @Override
48 | public int onStartCommand(Intent intent, int flags, int startId) {
49 | String action = intent.getAction();
50 | switch (action) {
51 | case ACTION_START:
52 | SimpleForegroundNotification sfn = (SimpleForegroundNotification) intent.getSerializableExtra(INTENT_EXTRA_KEY_SFN);
53 | showForegroundNotification(sfn);
54 | break;
55 |
56 | case ACTION_STOP:
57 | stopForeground(true);
58 | stopSelf();
59 | break;
60 | }
61 | return START_STICKY;
62 | }
63 |
64 | @Override
65 | public IBinder onBind(Intent intent) {
66 | return binder;
67 | }
68 |
69 | @Override
70 | public void onCreate() {
71 | super.onCreate();
72 | dialer = new Dialer(Looper.getMainLooper());
73 | }
74 |
75 | @Override
76 | public void onDestroy() {
77 | dialer.stopDialThread();
78 | try {
79 | dialer.doDestroySync();
80 | } catch (Exception e) {
81 | Log.e(TAG, "Failed to destroy go resources", e);
82 | }
83 | super.onDestroy();
84 | }
85 |
86 | private void showForegroundNotification(SimpleForegroundNotification sfn) {
87 | // Create notification default intent.
88 | PackageManager pm = getApplicationContext().getPackageManager();
89 | Intent notificationIntent = pm.getLaunchIntentForPackage(getApplicationContext().getPackageName());
90 | PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
91 |
92 | Notification notification;
93 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
94 | notification = new Notification.Builder(this, sfn.channelId)
95 | .setWhen(System.currentTimeMillis())
96 | .setSmallIcon(android.R.drawable.ic_media_play)
97 | .setContentTitle(sfn.title)
98 | .setContentText(sfn.text)
99 | .setContentIntent(pendingIntent)
100 | .build();
101 | } else {
102 | notification = new NotificationCompat.Builder(this, sfn.channelId)
103 | .setWhen(System.currentTimeMillis())
104 | .setSmallIcon(android.R.drawable.ic_media_play)
105 | .setContentTitle(sfn.title)
106 | .setContentText(sfn.text)
107 | .setPriority(Notification.PRIORITY_MAX)
108 | .setContentIntent(pendingIntent)
109 | .build();
110 | }
111 | startForeground(sfn.notificationId, notification);
112 | }
113 | }
114 |
--------------------------------------------------------------------------------
/android/src/main/java/io/github/empirefox/flutter_dial_go/Dialer.java:
--------------------------------------------------------------------------------
1 | package io.github.empirefox.flutter_dial_go;
2 |
3 | import android.os.Handler;
4 | import android.os.HandlerThread;
5 | import android.os.Looper;
6 |
7 | import formobile.Conn;
8 | import formobile.Formobile;
9 | import gomobile.ConcurrentRunner;
10 | import gomobile.FromGo;
11 | import gomobile.Gomobile;
12 |
13 | public class Dialer extends Handler implements formobile.Dialer {
14 | private final formobile.Dialer dialer = Formobile.getDialer();
15 | private final HandlerThread dialThread;
16 | private final Handler dialHandler;
17 | private FromGo go = null;
18 | private ConcurrentRunner destroyRunner = null;
19 |
20 | public Dialer(Looper looper) {
21 | super(looper);
22 | dialThread = new HandlerThread("dial_thread");
23 | dialThread.start();
24 | dialHandler = new Handler(dialThread.getLooper());
25 | }
26 |
27 | public void doInit(Callback cb) {
28 | if (go == null) {
29 | go = Gomobile.newFromGo();
30 | }
31 | ConcurrentRunner runner = go.doInitOnce();
32 | dialHandler.post(() -> {
33 | try {
34 | runner.done();
35 | post(() -> cb.onResult(null));
36 | } catch (Exception e) {
37 | post(() -> cb.onResult(e));
38 | }
39 | });
40 | }
41 |
42 | public void doDestroy(Callback cb) {
43 | if (go == null) {
44 | cb.onResult(null);
45 | return;
46 | }
47 |
48 | FromGo go = this.go;
49 | this.go = null;
50 | destroyRunner = go.doDestroyOnce();
51 |
52 | dialHandler.post(() -> {
53 | try {
54 | destroyRunner.done();
55 | post(() -> {
56 | cb.onResult(null);
57 | destroyRunner = null;
58 | });
59 | } catch (Exception e) {
60 | post(() -> {
61 | cb.onResult(e);
62 | destroyRunner = null;
63 | });
64 | }
65 | });
66 | }
67 |
68 | public void doDestroySync() throws Exception {
69 | ConcurrentRunner runner = null;
70 | if (go != null) {
71 | runner = go.doDestroyOnce();
72 | }
73 | if (runner == null) {
74 | runner = destroyRunner;
75 | destroyRunner = null;
76 | }
77 | if (runner != null) {
78 | runner.done();
79 | }
80 | go = null;
81 | }
82 |
83 | public Handler getDialHandler() {
84 | return dialHandler;
85 | }
86 |
87 | public void stopDialThread() {
88 | dialThread.quit();
89 | }
90 |
91 | public boolean isNotInitialized() {
92 | return go == null;
93 | }
94 |
95 | @Override
96 | public Conn dial(int port, long channelId, long timeoutnano) throws Exception {
97 | return dialer.dial(port, channelId, timeoutnano);
98 | }
99 |
100 | public interface Callback {
101 | // fatal error if e is not null, bugs here!!!
102 | void onResult(Exception e);
103 | }
104 | }
105 |
--------------------------------------------------------------------------------
/android/src/main/java/io/github/empirefox/flutter_dial_go/FlutterDialGoPlugin.java:
--------------------------------------------------------------------------------
1 | package io.github.empirefox.flutter_dial_go;
2 |
3 | import android.app.Activity;
4 | import android.app.NotificationChannel;
5 | import android.app.NotificationManager;
6 | import android.content.ComponentName;
7 | import android.content.Context;
8 | import android.content.Intent;
9 | import android.content.ServiceConnection;
10 | import android.os.Build;
11 | import android.os.Handler;
12 | import android.os.IBinder;
13 | import android.os.Looper;
14 |
15 | import java.util.ArrayList;
16 | import java.util.HashMap;
17 | import java.util.List;
18 | import java.util.Map;
19 |
20 | import formobile.Conn;
21 | import io.flutter.plugin.common.MethodCall;
22 | import io.flutter.plugin.common.MethodChannel;
23 | import io.flutter.plugin.common.MethodChannel.MethodCallHandler;
24 | import io.flutter.plugin.common.MethodChannel.Result;
25 | import io.flutter.plugin.common.PluginRegistry.Registrar;
26 | import io.flutter.plugin.common.PluginRegistry.ViewDestroyListener;
27 | import io.flutter.view.FlutterNativeView;
28 |
29 | /**
30 | * FlutterDialGoPlugin
31 | */
32 | public class FlutterDialGoPlugin extends Handler implements MethodCallHandler, ServiceConnection, ViewDestroyListener {
33 | private final MethodChannel controller;
34 | private final Registrar registrar;
35 | private final Map pipes = new HashMap<>();
36 |
37 | private Dialer dialer = null;
38 | private Result bindResult = null;
39 | private Result unbindResult = null;
40 | private boolean serviceMode = false;
41 |
42 | public FlutterDialGoPlugin(Registrar registrar, MethodChannel controller) {
43 | this.registrar = registrar;
44 | this.controller = controller;
45 | }
46 |
47 | /**
48 | * Plugin registration.
49 | */
50 | public static void registerWith(Registrar registrar) {
51 | final MethodChannel controller = new MethodChannel(registrar.messenger(), "flutter_dial_go");
52 | final FlutterDialGoPlugin instance = new FlutterDialGoPlugin(registrar, controller);
53 | controller.setMethodCallHandler(instance);
54 | registrar.addViewDestroyListener(instance);
55 | }
56 |
57 | @Override
58 | public void onMethodCall(MethodCall call, Result result) {
59 | switch (call.method) {
60 | case "notificationChannel":
61 | onMethodCreateNotificationChannel(call, result);
62 | return;
63 |
64 | case "noService":
65 | if (dialer != null || serviceMode) {
66 | result.error("onMethodCall", "service mode or dialer already exist", null);
67 | return;
68 | }
69 | dialer = new Dialer(Looper.getMainLooper());
70 | result.success(null);
71 | return;
72 |
73 | case "startService":
74 | if (dialer != null || serviceMode) {
75 | result.error("onMethodCall", "dialer already exist", null);
76 | return;
77 | }
78 | serviceMode = true;
79 | onMethodStartService(call, result);
80 | return;
81 |
82 | case "stopService":
83 | if (!serviceMode) {
84 | dialer = null;
85 | result.success(null);
86 | return;
87 | }
88 | if (dialer == null) {
89 | result.success(null);
90 | return;
91 | }
92 | onMethodStopService(call, result);
93 | return;
94 | }
95 |
96 | if (dialer == null) {
97 | result.error(call.method, "service stopped", null);
98 | return;
99 | }
100 |
101 | switch (call.method) {
102 | case "initGo":
103 | onMethodInitGo(call, result);
104 | return;
105 |
106 | case "destroyGo":
107 | onMethodDestroyGo(call, result);
108 | return;
109 | }
110 |
111 | if (dialer.isNotInitialized()) {
112 | result.error(call.method, "go not initialized", null);
113 | return;
114 | }
115 |
116 | switch (call.method) {
117 | // dial Conn
118 | case "dial":
119 | onMethodDial(call, result);
120 | return;
121 |
122 | // close Conn
123 | case "close":
124 | onMethodClose(call, result);
125 | return;
126 | }
127 |
128 | result.notImplemented();
129 | }
130 |
131 | private void onMethodCreateNotificationChannel(MethodCall call, Result result) {
132 | // Create the NotificationChannel, but only on API 26+ because
133 | // the NotificationChannel class is new and not in the support library
134 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
135 | ArrayList