@capacitor/android 4.0.1-alpha.0 → 4.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (27) hide show
  1. package/CHANGELOG.md +126 -1
  2. package/capacitor/build.gradle +9 -7
  3. package/capacitor/proguard-rules.pro +26 -0
  4. package/capacitor/src/main/assets/native-bridge.js +8 -0
  5. package/capacitor/src/main/java/com/getcapacitor/AppUUID.java +65 -0
  6. package/capacitor/src/main/java/com/getcapacitor/Bridge.java +147 -13
  7. package/capacitor/src/main/java/com/getcapacitor/BridgeActivity.java +11 -54
  8. package/capacitor/src/main/java/com/getcapacitor/BridgeWebChromeClient.java +4 -5
  9. package/capacitor/src/main/java/com/getcapacitor/BridgeWebViewClient.java +11 -0
  10. package/capacitor/src/main/java/com/getcapacitor/CapConfig.java +65 -2
  11. package/capacitor/src/main/java/com/getcapacitor/CapacitorWebView.java +1 -0
  12. package/capacitor/src/main/java/com/getcapacitor/FileUtils.java +6 -1
  13. package/capacitor/src/main/java/com/getcapacitor/JSExport.java +1 -1
  14. package/capacitor/src/main/java/com/getcapacitor/MessageHandler.java +31 -4
  15. package/capacitor/src/main/java/com/getcapacitor/Plugin.java +16 -10
  16. package/capacitor/src/main/java/com/getcapacitor/PluginCall.java +28 -9
  17. package/capacitor/src/main/java/com/getcapacitor/PluginHandle.java +4 -0
  18. package/capacitor/src/main/java/com/getcapacitor/ProcessedRoute.java +28 -0
  19. package/capacitor/src/main/java/com/getcapacitor/RouteProcessor.java +8 -0
  20. package/capacitor/src/main/java/com/getcapacitor/WebViewLocalServer.java +27 -5
  21. package/capacitor/src/main/java/com/getcapacitor/cordova/CapacitorCordovaCookieManager.java +1 -2
  22. package/capacitor/src/main/java/com/getcapacitor/cordova/MockCordovaWebViewImpl.java +5 -0
  23. package/capacitor/src/main/res/values/colors.xml +4 -4
  24. package/capacitor/src/main/res/values/strings.xml +0 -5
  25. package/capacitor/src/main/res/values/styles.xml +0 -9
  26. package/package.json +4 -3
  27. package/capacitor/src/main/res/drawable/ic_transparent.xml +0 -12
@@ -12,11 +12,11 @@ public class BridgeActivity extends AppCompatActivity {
12
12
 
13
13
  protected Bridge bridge;
14
14
  protected boolean keepRunning = true;
15
- private CapConfig config;
15
+ protected CapConfig config;
16
16
 
17
- private int activityDepth = 0;
18
- private List<Class<? extends Plugin>> initialPlugins = new ArrayList<>();
19
- private final Bridge.Builder bridgeBuilder = new Bridge.Builder(this);
17
+ protected int activityDepth = 0;
18
+ protected List<Class<? extends Plugin>> initialPlugins = new ArrayList<>();
19
+ protected final Bridge.Builder bridgeBuilder = new Bridge.Builder(this);
20
20
 
21
21
  @Override
22
22
  protected void onCreate(Bundle savedInstanceState) {
@@ -26,47 +26,18 @@ public class BridgeActivity extends AppCompatActivity {
26
26
  setTheme(getResources().getIdentifier("AppTheme_NoActionBar", "style", getPackageName()));
27
27
  setTheme(R.style.AppTheme_NoActionBar);
28
28
  setContentView(R.layout.bridge_layout_main);
29
- }
30
-
31
- /**
32
- * Initializes the Capacitor Bridge with the Activity.
33
- * @deprecated It is preferred not to call this method. If it is not called, the bridge is
34
- * initialized automatically. If you need to add additional plugins during initialization,
35
- * use {@link #registerPlugin(Class)} or {@link #registerPlugins(List)}.
36
- *
37
- * @param plugins A list of plugins to initialize with Capacitor
38
- */
39
- @Deprecated
40
- protected void init(Bundle savedInstanceState, List<Class<? extends Plugin>> plugins) {
41
- this.init(savedInstanceState, plugins, null);
42
- }
43
-
44
- /**
45
- * Initializes the Capacitor Bridge with the Activity.
46
- * @deprecated It is preferred not to call this method. If it is not called, the bridge is
47
- * initialized automatically. If you need to add additional plugins during initialization,
48
- * use {@link #registerPlugin(Class)} or {@link #registerPlugins(List)}.
49
- *
50
- * @param plugins A list of plugins to initialize with Capacitor
51
- * @param config An instance of a Capacitor Configuration to use. If null, will load from file
52
- */
53
- @Deprecated
54
- protected void init(Bundle savedInstanceState, List<Class<? extends Plugin>> plugins, CapConfig config) {
55
- this.initialPlugins = plugins;
56
- this.config = config;
29
+ PluginManager loader = new PluginManager(getAssets());
57
30
 
58
- this.load();
59
- }
31
+ try {
32
+ bridgeBuilder.addPlugins(loader.loadPluginClasses());
33
+ } catch (PluginLoadException ex) {
34
+ Logger.error("Error loading plugins.", ex);
35
+ }
60
36
 
61
- /**
62
- * @deprecated This method should not be called manually.
63
- */
64
- @Deprecated
65
- protected void load(Bundle savedInstanceState) {
66
37
  this.load();
67
38
  }
68
39
 
69
- private void load() {
40
+ protected void load() {
70
41
  Logger.debug("Starting BridgeActivity");
71
42
 
72
43
  bridge = bridgeBuilder.addPlugins(initialPlugins).setConfig(config).create();
@@ -96,20 +67,6 @@ public class BridgeActivity extends AppCompatActivity {
96
67
  @Override
97
68
  public void onStart() {
98
69
  super.onStart();
99
-
100
- // Preferred behavior: init() was not called, so we construct the bridge with auto-loaded plugins.
101
- if (bridge == null) {
102
- PluginManager loader = new PluginManager(getAssets());
103
-
104
- try {
105
- bridgeBuilder.addPlugins(loader.loadPluginClasses());
106
- } catch (PluginLoadException ex) {
107
- Logger.error("Error loading plugins.", ex);
108
- }
109
-
110
- this.load();
111
- }
112
-
113
70
  activityDepth++;
114
71
  this.bridge.onStart();
115
72
  Logger.debug("App started");
@@ -147,7 +147,6 @@ public class BridgeWebChromeClient extends WebChromeClient {
147
147
  AlertDialog.Builder builder = new AlertDialog.Builder(view.getContext());
148
148
  builder
149
149
  .setMessage(message)
150
- .setTitle("Alert")
151
150
  .setPositiveButton(
152
151
  "OK",
153
152
  (dialog, buttonIndex) -> {
@@ -187,7 +186,6 @@ public class BridgeWebChromeClient extends WebChromeClient {
187
186
 
188
187
  builder
189
188
  .setMessage(message)
190
- .setTitle("Confirm")
191
189
  .setPositiveButton(
192
190
  "OK",
193
191
  (dialog, buttonIndex) -> {
@@ -236,7 +234,6 @@ public class BridgeWebChromeClient extends WebChromeClient {
236
234
 
237
235
  builder
238
236
  .setMessage(message)
239
- .setTitle("Prompt")
240
237
  .setView(input)
241
238
  .setPositiveButton(
242
239
  "OK",
@@ -286,8 +283,10 @@ public class BridgeWebChromeClient extends WebChromeClient {
286
283
  callback.invoke(origin, true, false);
287
284
  } else {
288
285
  final String[] coarsePermission = { Manifest.permission.ACCESS_COARSE_LOCATION };
289
- // TODO replace with Build.VERSION_CODES.S once we target SDK 31
290
- if (Build.VERSION.SDK_INT >= 31 && PermissionHelper.hasPermissions(bridge.getContext(), coarsePermission)) {
286
+ if (
287
+ Build.VERSION.SDK_INT >= Build.VERSION_CODES.S &&
288
+ PermissionHelper.hasPermissions(bridge.getContext(), coarsePermission)
289
+ ) {
291
290
  callback.invoke(origin, true, false);
292
291
  } else {
293
292
  callback.invoke(origin, false, false);
@@ -28,6 +28,7 @@ public class BridgeWebViewClient extends WebViewClient {
28
28
  return bridge.launchIntent(url);
29
29
  }
30
30
 
31
+ @Deprecated
31
32
  @Override
32
33
  public boolean shouldOverrideUrlLoading(WebView view, String url) {
33
34
  return bridge.launchIntent(Uri.parse(url));
@@ -55,6 +56,11 @@ public class BridgeWebViewClient extends WebViewClient {
55
56
  listener.onReceivedError(view);
56
57
  }
57
58
  }
59
+
60
+ String errorPath = bridge.getErrorUrl();
61
+ if (errorPath != null && request.isForMainFrame()) {
62
+ view.loadUrl(errorPath);
63
+ }
58
64
  }
59
65
 
60
66
  @Override
@@ -80,5 +86,10 @@ public class BridgeWebViewClient extends WebViewClient {
80
86
  listener.onReceivedHttpError(view);
81
87
  }
82
88
  }
89
+
90
+ String errorPath = bridge.getErrorUrl();
91
+ if (errorPath != null && request.isForMainFrame()) {
92
+ view.loadUrl(errorPath);
93
+ }
83
94
  }
84
95
  }
@@ -1,6 +1,8 @@
1
1
  package com.getcapacitor;
2
2
 
3
3
  import static com.getcapacitor.Bridge.CAPACITOR_HTTP_SCHEME;
4
+ import static com.getcapacitor.Bridge.DEFAULT_ANDROID_WEBVIEW_VERSION;
5
+ import static com.getcapacitor.Bridge.MINIMUM_ANDROID_WEBVIEW_VERSION;
4
6
  import static com.getcapacitor.FileUtils.readFile;
5
7
 
6
8
  import android.content.Context;
@@ -9,8 +11,10 @@ import android.content.res.AssetManager;
9
11
  import androidx.annotation.Nullable;
10
12
  import com.getcapacitor.util.JSONUtils;
11
13
  import java.io.IOException;
14
+ import java.util.Arrays;
12
15
  import java.util.HashMap;
13
16
  import java.util.Iterator;
17
+ import java.util.List;
14
18
  import java.util.Locale;
15
19
  import java.util.Map;
16
20
  import org.json.JSONException;
@@ -40,6 +44,9 @@ public class CapConfig {
40
44
  private boolean captureInput = false;
41
45
  private boolean webContentsDebuggingEnabled = false;
42
46
  private boolean loggingEnabled = true;
47
+ private boolean initialFocus = true;
48
+ private int minWebViewVersion = DEFAULT_ANDROID_WEBVIEW_VERSION;
49
+ private String errorPath;
43
50
 
44
51
  // Embedded
45
52
  private String startPath;
@@ -105,7 +112,11 @@ public class CapConfig {
105
112
  this.html5mode = builder.html5mode;
106
113
  this.serverUrl = builder.serverUrl;
107
114
  this.hostname = builder.hostname;
108
- this.androidScheme = builder.androidScheme;
115
+
116
+ if (this.validateScheme(builder.androidScheme)) {
117
+ this.androidScheme = builder.androidScheme;
118
+ }
119
+
109
120
  this.allowNavigation = builder.allowNavigation;
110
121
 
111
122
  // Android Config
@@ -116,6 +127,9 @@ public class CapConfig {
116
127
  this.captureInput = builder.captureInput;
117
128
  this.webContentsDebuggingEnabled = builder.webContentsDebuggingEnabled;
118
129
  this.loggingEnabled = builder.loggingEnabled;
130
+ this.initialFocus = builder.initialFocus;
131
+ this.minWebViewVersion = builder.minWebViewVersion;
132
+ this.errorPath = builder.errorPath;
119
133
 
120
134
  // Embedded
121
135
  this.startPath = builder.startPath;
@@ -148,7 +162,13 @@ public class CapConfig {
148
162
  html5mode = JSONUtils.getBoolean(configJSON, "server.html5mode", html5mode);
149
163
  serverUrl = JSONUtils.getString(configJSON, "server.url", null);
150
164
  hostname = JSONUtils.getString(configJSON, "server.hostname", hostname);
151
- androidScheme = JSONUtils.getString(configJSON, "server.androidScheme", androidScheme);
165
+ errorPath = JSONUtils.getString(configJSON, "server.errorPath", null);
166
+
167
+ String configSchema = JSONUtils.getString(configJSON, "server.androidScheme", androidScheme);
168
+ if (this.validateScheme(configSchema)) {
169
+ androidScheme = configSchema;
170
+ }
171
+
152
172
  allowNavigation = JSONUtils.getArray(configJSON, "server.allowNavigation", null);
153
173
 
154
174
  // Android
@@ -164,6 +184,7 @@ public class CapConfig {
164
184
  "android.allowMixedContent",
165
185
  JSONUtils.getBoolean(configJSON, "allowMixedContent", allowMixedContent)
166
186
  );
187
+ minWebViewVersion = JSONUtils.getInt(configJSON, "android.minWebViewVersion", DEFAULT_ANDROID_WEBVIEW_VERSION);
167
188
  captureInput = JSONUtils.getBoolean(configJSON, "android.captureInput", captureInput);
168
189
  webContentsDebuggingEnabled = JSONUtils.getBoolean(configJSON, "android.webContentsDebuggingEnabled", isDebug);
169
190
 
@@ -187,10 +208,22 @@ public class CapConfig {
187
208
  loggingEnabled = isDebug;
188
209
  }
189
210
 
211
+ initialFocus = JSONUtils.getBoolean(configJSON, "android.initialFocus", initialFocus);
212
+
190
213
  // Plugins
191
214
  pluginsConfiguration = deserializePluginsConfig(JSONUtils.getObject(configJSON, "plugins"));
192
215
  }
193
216
 
217
+ private boolean validateScheme(String scheme) {
218
+ List<String> invalidSchemes = Arrays.asList("file", "ftp", "ftps", "ws", "wss", "about", "blob", "data");
219
+ if (invalidSchemes.contains(scheme)) {
220
+ Logger.warn(scheme + " is not an allowed scheme. Defaulting to http.");
221
+ return false;
222
+ }
223
+
224
+ return true;
225
+ }
226
+
194
227
  public boolean isHTML5Mode() {
195
228
  return html5mode;
196
229
  }
@@ -199,6 +232,10 @@ public class CapConfig {
199
232
  return serverUrl;
200
233
  }
201
234
 
235
+ public String getErrorPath() {
236
+ return errorPath;
237
+ }
238
+
202
239
  public String getHostname() {
203
240
  return hostname;
204
241
  }
@@ -243,6 +280,19 @@ public class CapConfig {
243
280
  return loggingEnabled;
244
281
  }
245
282
 
283
+ public boolean isInitialFocus() {
284
+ return initialFocus;
285
+ }
286
+
287
+ public int getMinWebViewVersion() {
288
+ if (minWebViewVersion < MINIMUM_ANDROID_WEBVIEW_VERSION) {
289
+ Logger.warn("Specified minimum webview version is too low, defaulting to " + MINIMUM_ANDROID_WEBVIEW_VERSION);
290
+ return MINIMUM_ANDROID_WEBVIEW_VERSION;
291
+ }
292
+
293
+ return minWebViewVersion;
294
+ }
295
+
246
296
  public PluginConfig getPluginConfiguration(String pluginId) {
247
297
  PluginConfig pluginConfig = pluginsConfiguration.get(pluginId);
248
298
  if (pluginConfig == null) {
@@ -386,6 +436,7 @@ public class CapConfig {
386
436
  // Server Config Values
387
437
  private boolean html5mode = true;
388
438
  private String serverUrl;
439
+ private String errorPath;
389
440
  private String hostname = "localhost";
390
441
  private String androidScheme = CAPACITOR_HTTP_SCHEME;
391
442
  private String[] allowNavigation;
@@ -398,6 +449,8 @@ public class CapConfig {
398
449
  private boolean captureInput = false;
399
450
  private Boolean webContentsDebuggingEnabled = null;
400
451
  private boolean loggingEnabled = true;
452
+ private boolean initialFocus = false;
453
+ private int minWebViewVersion = DEFAULT_ANDROID_WEBVIEW_VERSION;
401
454
 
402
455
  // Embedded
403
456
  private String startPath = null;
@@ -442,6 +495,11 @@ public class CapConfig {
442
495
  return this;
443
496
  }
444
497
 
498
+ public Builder setErrorPath(String errorPath) {
499
+ this.errorPath = errorPath;
500
+ return this;
501
+ }
502
+
445
503
  public Builder setHostname(String hostname) {
446
504
  this.hostname = hostname;
447
505
  return this;
@@ -496,5 +554,10 @@ public class CapConfig {
496
554
  this.loggingEnabled = enabled;
497
555
  return this;
498
556
  }
557
+
558
+ public Builder setInitialFocus(boolean focus) {
559
+ this.initialFocus = focus;
560
+ return this;
561
+ }
499
562
  }
500
563
  }
@@ -30,6 +30,7 @@ public class CapacitorWebView extends WebView {
30
30
  }
31
31
 
32
32
  @Override
33
+ @SuppressWarnings("deprecation")
33
34
  public boolean dispatchKeyEvent(KeyEvent event) {
34
35
  if (event.getAction() == KeyEvent.ACTION_MULTIPLE) {
35
36
  evaluateJavascript("document.activeElement.value = document.activeElement.value + '" + event.getCharacters() + "';", null);
@@ -77,7 +77,7 @@ public class FileUtils {
77
77
  final String type = split[0];
78
78
 
79
79
  if ("primary".equalsIgnoreCase(type)) {
80
- return Environment.getExternalStorageDirectory() + "/" + split[1];
80
+ return legacyPrimaryPath(split[1]);
81
81
  } else {
82
82
  final int splitIndex = docId.indexOf(':', 1);
83
83
  final String tag = docId.substring(0, splitIndex);
@@ -136,6 +136,11 @@ public class FileUtils {
136
136
  return null;
137
137
  }
138
138
 
139
+ @SuppressWarnings("deprecation")
140
+ private static String legacyPrimaryPath(String pathPart) {
141
+ return Environment.getExternalStorageDirectory() + "/" + pathPart;
142
+ }
143
+
139
144
  /**
140
145
  * Read a plaintext file.
141
146
  *
@@ -94,7 +94,7 @@ public class JSExport {
94
94
  return readFile(context.getAssets(), path);
95
95
  }
96
96
  } catch (IOException ex) {
97
- Logger.error("Unable to read file at path " + path);
97
+ Logger.warn("Unable to read file at path " + path);
98
98
  }
99
99
  return builder.toString();
100
100
  }
@@ -1,7 +1,12 @@
1
1
  package com.getcapacitor;
2
2
 
3
+ import android.net.Uri;
3
4
  import android.webkit.JavascriptInterface;
4
5
  import android.webkit.WebView;
6
+ import androidx.webkit.JavaScriptReplyProxy;
7
+ import androidx.webkit.WebMessageCompat;
8
+ import androidx.webkit.WebViewCompat;
9
+ import androidx.webkit.WebViewFeature;
5
10
  import org.apache.cordova.PluginManager;
6
11
 
7
12
  /**
@@ -13,13 +18,31 @@ public class MessageHandler {
13
18
  private Bridge bridge;
14
19
  private WebView webView;
15
20
  private PluginManager cordovaPluginManager;
21
+ private JavaScriptReplyProxy javaScriptReplyProxy;
16
22
 
17
23
  public MessageHandler(Bridge bridge, WebView webView, PluginManager cordovaPluginManager) {
18
24
  this.bridge = bridge;
19
25
  this.webView = webView;
20
26
  this.cordovaPluginManager = cordovaPluginManager;
21
27
 
22
- webView.addJavascriptInterface(this, "androidBridge");
28
+ WebViewCompat.WebMessageListener capListener = (view, message, sourceOrigin, isMainFrame, replyProxy) -> {
29
+ if (isMainFrame) {
30
+ postMessage(message.getData());
31
+ javaScriptReplyProxy = replyProxy;
32
+ } else {
33
+ Logger.warn("Plugin execution is allowed in Main Frame only");
34
+ }
35
+ };
36
+
37
+ if (WebViewFeature.isFeatureSupported(WebViewFeature.WEB_MESSAGE_LISTENER)) {
38
+ try {
39
+ WebViewCompat.addWebMessageListener(webView, "androidBridge", bridge.getAllowedOriginRules(), capListener);
40
+ } catch (Exception ex) {
41
+ webView.addJavascriptInterface(this, "androidBridge");
42
+ }
43
+ } else {
44
+ webView.addJavascriptInterface(this, "androidBridge");
45
+ }
23
46
  }
24
47
 
25
48
  /**
@@ -100,9 +123,13 @@ public class MessageHandler {
100
123
 
101
124
  boolean isValidCallbackId = !call.getCallbackId().equals(PluginCall.CALLBACK_ID_DANGLING);
102
125
  if (isValidCallbackId) {
103
- final String runScript = "window.Capacitor.fromNative(" + data.toString() + ")";
104
- final WebView webView = this.webView;
105
- webView.post(() -> webView.evaluateJavascript(runScript, null));
126
+ if (WebViewFeature.isFeatureSupported(WebViewFeature.WEB_MESSAGE_LISTENER) && javaScriptReplyProxy != null) {
127
+ javaScriptReplyProxy.postMessage(data.toString());
128
+ } else {
129
+ final String runScript = "window.Capacitor.fromNative(" + data.toString() + ")";
130
+ final WebView webView = this.webView;
131
+ webView.post(() -> webView.evaluateJavascript(runScript, null));
132
+ }
106
133
  } else {
107
134
  bridge.getApp().fireRestoredResult(data);
108
135
  }
@@ -745,9 +745,10 @@ public class Plugin {
745
745
  * @param call
746
746
  */
747
747
  @SuppressWarnings("unused")
748
- @PluginMethod(returnType = PluginMethod.RETURN_NONE)
748
+ @PluginMethod(returnType = PluginMethod.RETURN_PROMISE)
749
749
  public void removeAllListeners(PluginCall call) {
750
750
  eventListeners.clear();
751
+ call.resolve();
751
752
  }
752
753
 
753
754
  /**
@@ -788,15 +789,7 @@ public class Plugin {
788
789
  public void requestPermissions(PluginCall call) {
789
790
  CapacitorPlugin annotation = handle.getPluginAnnotation();
790
791
  if (annotation == null) {
791
- // handle permission requests for plugins defined with @NativePlugin (prior to 3.0.0)
792
- NativePlugin legacyAnnotation = this.handle.getLegacyPluginAnnotation();
793
- String[] perms = legacyAnnotation.permissions();
794
- if (perms.length > 0) {
795
- saveCall(call);
796
- pluginRequestPermissions(perms, legacyAnnotation.permissionRequestCode());
797
- } else {
798
- call.resolve();
799
- }
792
+ handleLegacyPermission(call);
800
793
  } else {
801
794
  // handle permission requests for plugins defined with @CapacitorPlugin (since 3.0.0)
802
795
  String[] permAliases = null;
@@ -862,6 +855,19 @@ public class Plugin {
862
855
  }
863
856
  }
864
857
 
858
+ @SuppressWarnings("deprecation")
859
+ private void handleLegacyPermission(PluginCall call) {
860
+ // handle permission requests for plugins defined with @NativePlugin (prior to 3.0.0)
861
+ NativePlugin legacyAnnotation = this.handle.getLegacyPluginAnnotation();
862
+ String[] perms = legacyAnnotation.permissions();
863
+ if (perms.length > 0) {
864
+ saveCall(call);
865
+ pluginRequestPermissions(perms, legacyAnnotation.permissionRequestCode());
866
+ } else {
867
+ call.resolve();
868
+ }
869
+ }
870
+
865
871
  /**
866
872
  * Handle request permissions result. A plugin using the deprecated {@link NativePlugin}
867
873
  * should override this to handle the result, or this method will handle the result
@@ -96,7 +96,7 @@ public class PluginCall {
96
96
  */
97
97
  @Deprecated
98
98
  public void error(String msg, Exception ex) {
99
- reject(msg, null, ex);
99
+ reject(msg, ex);
100
100
  }
101
101
 
102
102
  /**
@@ -114,10 +114,10 @@ public class PluginCall {
114
114
  */
115
115
  @Deprecated
116
116
  public void error(String msg) {
117
- reject(msg, null, null);
117
+ reject(msg);
118
118
  }
119
119
 
120
- public void reject(String msg, String code, Exception ex) {
120
+ public void reject(String msg, String code, Exception ex, JSObject data) {
121
121
  PluginResult errorResult = new PluginResult();
122
122
 
123
123
  if (ex != null) {
@@ -127,23 +127,42 @@ public class PluginCall {
127
127
  try {
128
128
  errorResult.put("message", msg);
129
129
  errorResult.put("code", code);
130
+ if (null != data) {
131
+ errorResult.put("data", data);
132
+ }
130
133
  } catch (Exception jsonEx) {
131
- Logger.error(Logger.tags("Plugin"), jsonEx.getMessage(), null);
134
+ Logger.error(Logger.tags("Plugin"), jsonEx.getMessage(), jsonEx);
132
135
  }
133
136
 
134
137
  this.msgHandler.sendResponseMessage(this, null, errorResult);
135
138
  }
136
139
 
140
+ public void reject(String msg, Exception ex, JSObject data) {
141
+ reject(msg, null, ex, data);
142
+ }
143
+
144
+ public void reject(String msg, String code, JSObject data) {
145
+ reject(msg, code, null, data);
146
+ }
147
+
148
+ public void reject(String msg, String code, Exception ex) {
149
+ reject(msg, code, ex, null);
150
+ }
151
+
152
+ public void reject(String msg, JSObject data) {
153
+ reject(msg, null, null, data);
154
+ }
155
+
137
156
  public void reject(String msg, Exception ex) {
138
- reject(msg, null, ex);
157
+ reject(msg, null, ex, null);
139
158
  }
140
159
 
141
160
  public void reject(String msg, String code) {
142
- reject(msg, code, null);
161
+ reject(msg, code, null, null);
143
162
  }
144
163
 
145
164
  public void reject(String msg) {
146
- reject(msg, null, null);
165
+ reject(msg, null, null, null);
147
166
  }
148
167
 
149
168
  public void unimplemented() {
@@ -151,7 +170,7 @@ public class PluginCall {
151
170
  }
152
171
 
153
172
  public void unimplemented(String msg) {
154
- reject(msg, "UNIMPLEMENTED", null);
173
+ reject(msg, "UNIMPLEMENTED", null, null);
155
174
  }
156
175
 
157
176
  public void unavailable() {
@@ -159,7 +178,7 @@ public class PluginCall {
159
178
  }
160
179
 
161
180
  public void unavailable(String msg) {
162
- reject(msg, "UNAVAILABLE", null);
181
+ reject(msg, "UNAVAILABLE", null, null);
163
182
  }
164
183
 
165
184
  public String getPluginId() {
@@ -20,11 +20,14 @@ public class PluginHandle {
20
20
 
21
21
  private final String pluginId;
22
22
 
23
+ @SuppressWarnings("deprecation")
23
24
  private NativePlugin legacyPluginAnnotation;
25
+
24
26
  private CapacitorPlugin pluginAnnotation;
25
27
 
26
28
  private Plugin instance;
27
29
 
30
+ @SuppressWarnings("deprecation")
28
31
  public PluginHandle(Bridge bridge, Class<? extends Plugin> pluginClass) throws InvalidPluginException, PluginLoadException {
29
32
  this.bridge = bridge;
30
33
  this.pluginClass = pluginClass;
@@ -67,6 +70,7 @@ public class PluginHandle {
67
70
  return this.pluginId;
68
71
  }
69
72
 
73
+ @SuppressWarnings("deprecation")
70
74
  public NativePlugin getLegacyPluginAnnotation() {
71
75
  return this.legacyPluginAnnotation;
72
76
  }
@@ -0,0 +1,28 @@
1
+ package com.getcapacitor;
2
+
3
+ /**
4
+ * An data class used in conjunction with RouteProcessor.
5
+ *
6
+ * @see com.getcapacitor.RouteProcessor
7
+ */
8
+ public class ProcessedRoute {
9
+
10
+ private String path;
11
+ private boolean isAsset;
12
+
13
+ public String getPath() {
14
+ return path;
15
+ }
16
+
17
+ public void setPath(String path) {
18
+ this.path = path;
19
+ }
20
+
21
+ public boolean isAsset() {
22
+ return isAsset;
23
+ }
24
+
25
+ public void setAsset(boolean asset) {
26
+ isAsset = asset;
27
+ }
28
+ }
@@ -0,0 +1,8 @@
1
+ package com.getcapacitor;
2
+
3
+ /**
4
+ * An interface used in the processing of routes
5
+ */
6
+ public interface RouteProcessor {
7
+ ProcessedRoute process(String basePath, String path);
8
+ }