Skip to content

Commit a77049a

Browse files
authored
bug(analytics): Force session start (#764)
* Force session start * Add iOS no-op * Update comment * Mark internal method protected
1 parent ed16e42 commit a77049a

File tree

8 files changed

+82
-23
lines changed

8 files changed

+82
-23
lines changed
Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
<?xml version="1.0" encoding="utf-8"?>
12
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
2-
package="com.amazonaws.amplify.amplify_analytics_pinpoint">
3-
</manifest>
3+
package="com.amazonaws.amplify.amplify_analytics_pinpoint">
4+
5+
<application>
6+
<activity
7+
android:name=".EmptyActivity"
8+
android:exported="false" />
9+
</application>
10+
11+
</manifest>

packages/amplify_analytics_pinpoint/android/src/main/kotlin/com/amazonaws/amplify/amplify_analytics_pinpoint/AmplifyAnalyticsPinpointPlugin.kt

Lines changed: 27 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,9 @@
1616
package com.amazonaws.amplify.amplify_analytics_pinpoint
1717

1818
import android.app.Activity
19-
import android.app.Application
2019
import android.content.Context
21-
import android.util.Log
20+
import android.content.Intent
2221
import androidx.annotation.NonNull
23-
import com.amplifyframework.analytics.pinpoint.AWSPinpointAnalyticsPlugin
2422
import com.amplifyframework.core.Amplify
2523
import io.flutter.embedding.engine.plugins.FlutterPlugin
2624
import io.flutter.embedding.engine.plugins.activity.ActivityAware
@@ -29,36 +27,26 @@ import io.flutter.plugin.common.MethodCall
2927
import io.flutter.plugin.common.MethodChannel
3028
import io.flutter.plugin.common.MethodChannel.MethodCallHandler
3129
import io.flutter.plugin.common.MethodChannel.Result
32-
import io.flutter.plugin.common.PluginRegistry.Registrar
3330

34-
public class AmplifyAnalyticsPinpointPlugin : FlutterPlugin, ActivityAware, MethodCallHandler {
31+
class AmplifyAnalyticsPinpointPlugin : FlutterPlugin, ActivityAware, MethodCallHandler {
3532

3633
private lateinit var channel: MethodChannel
3734
private var mainActivity: Activity? = null
3835
private lateinit var context: Context
3936

4037
override fun onAttachedToEngine(
41-
@NonNull flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) {
38+
@NonNull flutterPluginBinding: FlutterPlugin.FlutterPluginBinding
39+
) {
4240

43-
channel = MethodChannel(flutterPluginBinding.getFlutterEngine().getDartExecutor(),
44-
"com.amazonaws.amplify/analytics_pinpoint")
41+
channel = MethodChannel(flutterPluginBinding.binaryMessenger,
42+
"com.amazonaws.amplify/analytics_pinpoint")
4543
channel.setMethodCallHandler(this)
46-
context = flutterPluginBinding.applicationContext;
44+
context = flutterPluginBinding.applicationContext
4745
}
4846

49-
// This static function is optional and equivalent to onAttachedToEngine. It supports the old
50-
// pre-Flutter-1.12 Android projects.
5147
companion object {
5248
const val TAG = "AmplifyAnalyticsPinpointPlugin"
5349
val LOG = Amplify.Logging.forNamespace("amplify:flutter:analytics_pinpoint")
54-
55-
@JvmStatic
56-
fun registerWith(registrar: Registrar) {
57-
val channel =
58-
MethodChannel(registrar.messenger(), "com.amazonaws.amplify/analytics_pinpoint")
59-
Amplify.addPlugin(AWSPinpointAnalyticsPlugin(registrar.activity().application))
60-
LOG.info("Added AnalyticsPinpoint plugin")
61-
}
6250
}
6351

6452
// Handle methods received via MethodChannel
@@ -67,6 +55,26 @@ public class AmplifyAnalyticsPinpointPlugin : FlutterPlugin, ActivityAware, Meth
6755
when (call.method) {
6856
"addPlugin" ->
6957
AmplifyAnalyticsBridge.addPlugin(result, context)
58+
"startSession" -> {
59+
// TODO: Update AutoSessionTracker logic to support Flutter.
60+
//
61+
// The AutoSessionTracker in the Pinpoint plugin listens for lifecycle changes and
62+
// starts and stops session tracking accordingly. It is registered during the call
63+
// to Amplify.configure. In native Android apps, this call is made before launching
64+
// the main activity and thus receives the initial onResume event, kicking off session
65+
// tracking. However, in Flutter, the call to Amplify.configure is made sometime later.
66+
// The initial onResume call is not received by the AutoSessionTracker, and no session
67+
// tracking occurs.
68+
//
69+
// The startSession/stopSession calls made by the AutoSessionTracker are not available
70+
// via the escape hatch, the AWS SDK, or reflection, so this hack must be used to
71+
// force an onPause/onResume cycle.
72+
//
73+
// This method is invoked in the Flutter SDK just after Amplify.configure.
74+
val intent = Intent(mainActivity, EmptyActivity::class.java)
75+
mainActivity?.startActivity(intent)
76+
result.success(null)
77+
}
7078
"recordEvent" ->
7179
AmplifyAnalyticsBridge.recordEvent(call.arguments, result)
7280
"flushEvents" ->
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package com.amazonaws.amplify.amplify_analytics_pinpoint
2+
3+
import android.app.Activity
4+
import androidx.appcompat.app.AppCompatActivity
5+
import android.os.Bundle
6+
7+
/// Empty activity used to force lifecycle events in the user's app.
8+
class EmptyActivity : Activity() {
9+
override fun onCreate(savedInstanceState: Bundle?) {
10+
super.onCreate(savedInstanceState)
11+
finish()
12+
}
13+
}

packages/amplify_analytics_pinpoint/ios/Classes/SwiftAmplifyAnalyticsPinpointPlugin.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,9 @@ public class SwiftAmplifyAnalyticsPinpointPlugin: NSObject, FlutterPlugin {
4242
switch method{
4343
case "addPlugin":
4444
FlutterAnalytics.addPlugin(result: result)
45+
case "sessionStart":
46+
// No-op
47+
result(nil)
4548
case "recordEvent":
4649
FlutterAnalytics.record(arguments: callArgs, result: result, bridge: bridge)
4750
case "flushEvents":

packages/amplify_analytics_pinpoint/lib/amplify_analytics_pinpoint.dart

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,4 +77,9 @@ class AmplifyAnalyticsPinpoint extends AnalyticsPluginInterface {
7777
required AnalyticsUserProfile userProfile}) async {
7878
return _instance.identifyUser(userId: userId, userProfile: userProfile);
7979
}
80+
81+
@override
82+
Future<void> onConfigure() {
83+
return _instance.onConfigure();
84+
}
8085
}

packages/amplify_analytics_pinpoint/lib/method_channel_amplify.dart

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
* permissions and limitations under the License.
1414
*/
1515

16+
import 'dart:io';
17+
1618
import 'package:amplify_analytics_plugin_interface/amplify_analytics_plugin_interface.dart';
1719
import 'package:amplify_core/types/exception/AmplifyException.dart';
1820
import 'package:amplify_core/types/exception/AmplifyExceptionMessages.dart';
@@ -41,6 +43,15 @@ class AmplifyAnalyticsPinpointMethodChannel extends AmplifyAnalyticsPinpoint {
4143
}
4244
}
4345

46+
@override
47+
Future<void> onConfigure() async {
48+
try {
49+
await _channel.invokeMethod('startSession');
50+
} on Exception {
51+
// TODO: log, but should not happen
52+
}
53+
}
54+
4455
@override
4556
Future<void> recordEvent({required AnalyticsEvent event}) async {
4657
var name = event.name;

packages/amplify_analytics_plugin_interface/lib/amplify_analytics_plugin_interface.dart

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ library amplify_analytics_plugin_interface;
1818
import 'dart:async';
1919

2020
import 'package:amplify_core/types/index.dart';
21+
import 'package:meta/meta.dart';
2122

2223
import 'src/types.dart';
2324
export 'src/types.dart';
@@ -63,4 +64,7 @@ abstract class AnalyticsPluginInterface extends AmplifyPluginInterface {
6364
required AnalyticsUserProfile userProfile}) async {
6465
throw UnimplementedError('identifyUser() has not been implemented.');
6566
}
67+
68+
@protected
69+
Future<void> onConfigure() async {}
6670
}

packages/amplify_flutter/lib/method_channel_amplify.dart

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,20 @@ class MethodChannelAmplify extends AmplifyClass {
2222
MethodChannelAmplify() : super.protected();
2323

2424
@override
25-
Future<bool?> _configurePlatforms(String version, String configuration) {
26-
return _channel.invokeMethod<bool>(
25+
Future<bool?> _configurePlatforms(
26+
String version, String configuration) async {
27+
final configured = await _channel.invokeMethod<bool>(
2728
'configure',
2829
<String, Object>{
2930
'version': version,
3031
'configuration': configuration,
3132
},
3233
);
34+
if (configured ?? false) {
35+
await Future.wait(
36+
//ignore:invalid_use_of_protected_member
37+
AnalyticsCategory.plugins.map((plugin) => plugin.onConfigure()));
38+
}
39+
return configured;
3340
}
3441
}

0 commit comments

Comments
 (0)