diff --git a/android/capacitor/proguard-rules.pro b/android/capacitor/proguard-rules.pro index d34e7df58..936dc8a28 100644 --- a/android/capacitor/proguard-rules.pro +++ b/android/capacitor/proguard-rules.pro @@ -14,9 +14,3 @@ } -keep public class * extends com.getcapacitor.Plugin { *; } - -# Rules for Capacitor v2 plugins and annotations -# These are deprecated but can still be used with Capacitor for now --keep @com.getcapacitor.NativePlugin public class * { - @com.getcapacitor.PluginMethod public ; -} diff --git a/android/capacitor/src/main/java/com/getcapacitor/Bridge.java b/android/capacitor/src/main/java/com/getcapacitor/Bridge.java index 9999b405c..ac145454c 100644 --- a/android/capacitor/src/main/java/com/getcapacitor/Bridge.java +++ b/android/capacitor/src/main/java/com/getcapacitor/Bridge.java @@ -618,17 +618,6 @@ public void registerPluginInstances(Plugin[] pluginInstances) { } } - @SuppressWarnings("deprecation") - private String getLegacyPluginName(Class pluginClass) { - NativePlugin legacyPluginAnnotation = pluginClass.getAnnotation(NativePlugin.class); - if (legacyPluginAnnotation == null) { - Logger.error("Plugin doesn't have the @CapacitorPlugin annotation. Please add it"); - return null; - } - - return legacyPluginAnnotation.name(); - } - /** * Register a plugin class * @param pluginClass a class inheriting from Plugin @@ -671,20 +660,17 @@ private String pluginId(Class clazz) { } private String pluginName(Class clazz) { - String pluginName; CapacitorPlugin pluginAnnotation = clazz.getAnnotation(CapacitorPlugin.class); if (pluginAnnotation == null) { - pluginName = this.getLegacyPluginName(clazz); - } else { - pluginName = pluginAnnotation.name(); + Logger.error("Plugin doesn't have the @CapacitorPlugin annotation. Please add it"); + return null; } - - return pluginName; + return pluginAnnotation.name(); } private void logInvalidPluginException(Class clazz) { Logger.error( - "NativePlugin " + + "Plugin " + clazz.getName() + " is invalid. Ensure the @CapacitorPlugin annotation exists on the plugin class and" + " the class extends Plugin" @@ -692,7 +678,7 @@ private void logInvalidPluginException(Class clazz) { } private void logPluginLoadException(Class clazz, Exception ex) { - Logger.error("NativePlugin " + clazz.getName() + " failed to load", ex); + Logger.error("Plugin " + clazz.getName() + " failed to load", ex); } public PluginHandle getPlugin(String pluginId) { @@ -706,38 +692,16 @@ public PluginHandle getPlugin(String pluginId) { * @return */ @Deprecated - @SuppressWarnings("deprecation") public PluginHandle getPluginWithRequestCode(int requestCode) { for (PluginHandle handle : this.plugins.values()) { - int[] requestCodes; - CapacitorPlugin pluginAnnotation = handle.getPluginAnnotation(); if (pluginAnnotation == null) { - // Check for legacy plugin annotation, @NativePlugin - NativePlugin legacyPluginAnnotation = handle.getLegacyPluginAnnotation(); - if (legacyPluginAnnotation == null) { - continue; - } - - if (legacyPluginAnnotation.permissionRequestCode() == requestCode) { + continue; + } + for (int rc : pluginAnnotation.requestCodes()) { + if (rc == requestCode) { return handle; } - - requestCodes = legacyPluginAnnotation.requestCodes(); - - for (int rc : requestCodes) { - if (rc == requestCode) { - return handle; - } - } - } else { - requestCodes = pluginAnnotation.requestCodes(); - - for (int rc : requestCodes) { - if (rc == requestCode) { - return handle; - } - } } } return null; @@ -1042,16 +1006,6 @@ public void saveInstanceState(Bundle outState) { } } - @Deprecated - @SuppressWarnings("deprecation") - public void startActivityForPluginWithResult(PluginCall call, Intent intent, int requestCode) { - Logger.debug("Starting activity for result"); - - pluginCallForLastActivity = call; - - getActivity().startActivityForResult(intent, requestCode); - } - /** * Check for legacy Capacitor or Cordova plugins that may have registered to handle a permission * request, and handle them if so. If not handled, false is returned. @@ -1079,12 +1033,6 @@ boolean onRequestPermissionsResult(int requestCode, String[] permissions, int[] return permissionHandled; } - // Call deprecated method if using deprecated NativePlugin annotation - if (plugin.getPluginAnnotation() == null) { - plugin.getInstance().handleRequestPermissionsResult(requestCode, permissions, grantResults); - return true; - } - return false; } @@ -1220,22 +1168,8 @@ boolean onActivityResult(int requestCode, int resultCode, Intent data) { return false; } - // deprecated, to be removed - PluginCall lastCall = plugin.getInstance().getSavedCall(); - - // If we don't have a saved last call (because our app was killed and restarted, for example), - // Then we should see if we have any saved plugin call information and generate a new, - // "dangling" plugin call (a plugin call that doesn't have a corresponding web callback) - // and then send that to the plugin - if (lastCall == null && pluginCallForLastActivity != null) { - plugin.getInstance().saveCall(pluginCallForLastActivity); - } - plugin.getInstance().handleOnActivityResult(requestCode, resultCode, data); - // Clear the plugin call we may have re-hydrated on app launch - pluginCallForLastActivity = null; - return true; } diff --git a/android/capacitor/src/main/java/com/getcapacitor/NativePlugin.java b/android/capacitor/src/main/java/com/getcapacitor/NativePlugin.java deleted file mode 100644 index c43076240..000000000 --- a/android/capacitor/src/main/java/com/getcapacitor/NativePlugin.java +++ /dev/null @@ -1,37 +0,0 @@ -package com.getcapacitor; - -import com.getcapacitor.annotation.CapacitorPlugin; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; - -/** - * Base annotation for all Plugins - * @deprecated - *

Use {@link CapacitorPlugin} instead - */ -@Retention(RetentionPolicy.RUNTIME) -@Deprecated -public @interface NativePlugin { - /** - * Request codes this plugin uses and responds to, in order to tie - * Android events back the plugin to handle - */ - int[] requestCodes() default {}; - - /** - * Permissions this plugin needs, in order to make permission requests - * easy if the plugin only needs basic permission prompting - */ - String[] permissions() default {}; - - /** - * The request code to use when automatically requesting permissions - */ - int permissionRequestCode() default 9000; - - /** - * A custom name for the plugin, otherwise uses the - * simple class name. - */ - String name() default ""; -} diff --git a/android/capacitor/src/main/java/com/getcapacitor/Plugin.java b/android/capacitor/src/main/java/com/getcapacitor/Plugin.java index e07851022..1f8c72cb0 100644 --- a/android/capacitor/src/main/java/com/getcapacitor/Plugin.java +++ b/android/capacitor/src/main/java/com/getcapacitor/Plugin.java @@ -53,18 +53,6 @@ public class Plugin { // Reference to the PluginHandle wrapper for this Plugin protected PluginHandle handle; - /** - * A way for plugins to quickly save a call that they will need to reference - * between activity/permissions starts/requests - * - * @deprecated store calls on the bridge using the methods - * {@link com.getcapacitor.Bridge#saveCall(PluginCall)}, - * {@link com.getcapacitor.Bridge#getSavedCall(String)} and - * {@link com.getcapacitor.Bridge#releaseCall(PluginCall)} - */ - @Deprecated - protected PluginCall savedLastCall; - // Stored event listeners private final Map> eventListeners; @@ -253,39 +241,6 @@ public String getAppId() { return getContext().getPackageName(); } - /** - * Called to save a {@link PluginCall} in order to reference it - * later, such as in an activity or permissions result handler - * @deprecated use {@link Bridge#saveCall(PluginCall)} - * - * @param lastCall - */ - @Deprecated - public void saveCall(PluginCall lastCall) { - this.savedLastCall = lastCall; - } - - /** - * Set the last saved call to null to free memory - * @deprecated use {@link PluginCall#release(Bridge)} - */ - @Deprecated - public void freeSavedCall() { - this.savedLastCall.release(bridge); - this.savedLastCall = null; - } - - /** - * Get the last saved call, if any - * @deprecated use {@link Bridge#getSavedCall(String)} - * - * @return - */ - @Deprecated - public PluginCall getSavedCall() { - return this.savedLastCall; - } - /** * Get the config options for this plugin. * @@ -296,23 +251,6 @@ public PluginConfig getConfig() { return bridge.getConfig().getPluginConfiguration(handle.getId()); } - /** - * Check whether any of the given permissions has been defined in the AndroidManifest.xml - * @deprecated use {@link #isPermissionDeclared(String)} - * - * @param permissions - * @return - */ - @Deprecated - public boolean hasDefinedPermissions(String[] permissions) { - for (String permission : permissions) { - if (!PermissionHelper.hasDefinedPermission(getContext(), permission)) { - return false; - } - } - return true; - } - /** * Check if all annotated permissions have been defined in the AndroidManifest.xml * @deprecated use {@link #isPermissionDeclared(String)} @@ -323,19 +261,15 @@ public boolean hasDefinedPermissions(String[] permissions) { public boolean hasDefinedRequiredPermissions() { CapacitorPlugin annotation = handle.getPluginAnnotation(); if (annotation == null) { - // Check for legacy plugin annotation, @NativePlugin - NativePlugin legacyAnnotation = handle.getLegacyPluginAnnotation(); - return hasDefinedPermissions(legacyAnnotation.permissions()); - } else { - for (Permission perm : annotation.permissions()) { - for (String permString : perm.strings()) { - if (!PermissionHelper.hasDefinedPermission(getContext(), permString)) { - return false; - } + return false; + } + for (Permission perm : annotation.permissions()) { + for (String permString : perm.strings()) { + if (!PermissionHelper.hasDefinedPermission(getContext(), permString)) { + return false; } } } - return true; } @@ -390,17 +324,8 @@ public boolean hasPermission(String permission) { public boolean hasRequiredPermissions() { CapacitorPlugin annotation = handle.getPluginAnnotation(); if (annotation == null) { - // Check for legacy plugin annotation, @NativePlugin - NativePlugin legacyAnnotation = handle.getLegacyPluginAnnotation(); - for (String perm : legacyAnnotation.permissions()) { - if (ActivityCompat.checkSelfPermission(this.getContext(), perm) != PackageManager.PERMISSION_GRANTED) { - return false; - } - } - - return true; + return false; } - for (Permission perm : annotation.permissions()) { for (String permString : perm.strings()) { if (ActivityCompat.checkSelfPermission(this.getContext(), permString) != PackageManager.PERMISSION_GRANTED) { @@ -408,7 +333,6 @@ public boolean hasRequiredPermissions() { } } } - return true; } @@ -545,42 +469,6 @@ private String[] getPermissionStringsForAliases(@NonNull String[] aliases) { return permissionLauncher; } - /** - * Request all of the specified permissions in the CapacitorPlugin annotation (if any) - * - * @deprecated use {@link #requestAllPermissions(PluginCall, String)} in conjunction with @CapacitorPlugin - */ - @Deprecated - public void pluginRequestAllPermissions() { - NativePlugin legacyAnnotation = handle.getLegacyPluginAnnotation(); - ActivityCompat.requestPermissions(getActivity(), legacyAnnotation.permissions(), legacyAnnotation.permissionRequestCode()); - } - - /** - * Helper for requesting a specific permission - * - * @param permission the permission to request - * @param requestCode the requestCode to use to associate the result with the plugin - * @deprecated use {@link #requestPermissionForAlias(String, PluginCall, String)} in conjunction with @CapacitorPlugin - */ - @Deprecated - public void pluginRequestPermission(String permission, int requestCode) { - ActivityCompat.requestPermissions(getActivity(), new String[] { permission }, requestCode); - } - - /** - * Helper for requesting specific permissions - * @deprecated use {@link #requestPermissionForAliases(String[], PluginCall, String)} in conjunction - * with @CapacitorPlugin - * - * @param permissions the set of permissions to request - * @param requestCode the requestCode to use to associate the result with the plugin - */ - @Deprecated - public void pluginRequestPermissions(String[] permissions, int requestCode) { - ActivityCompat.requestPermissions(getActivity(), permissions, requestCode); - } - /** * Get the permission state for the provided permission alias. * @@ -785,92 +673,72 @@ public void checkPermissions(PluginCall pluginCall) { @PluginMethod public void requestPermissions(PluginCall call) { CapacitorPlugin annotation = handle.getPluginAnnotation(); - if (annotation == null) { - handleLegacyPermission(call); - } else { - // handle permission requests for plugins defined with @CapacitorPlugin (since 3.0.0) - String[] permAliases = null; - Set autoGrantPerms = new HashSet<>(); - - // If call was made with a list of specific permission aliases to request, save them - // to be requested - JSArray providedPerms = call.getArray("permissions"); - List providedPermsList = null; - - if (providedPerms != null) { - try { - providedPermsList = providedPerms.toList(); - } catch (JSONException ignore) { - // do nothing - } - } + String[] permAliases = null; + Set autoGrantPerms = new HashSet<>(); - // If call was made without any custom permissions, request all from plugin annotation - Set aliasSet = new HashSet<>(); - if (providedPermsList == null || providedPermsList.isEmpty()) { - for (Permission perm : annotation.permissions()) { - // If a permission is defined with no permission strings, separate it for auto-granting. - // Otherwise, the alias is added to the list to be requested. - if (perm.strings().length == 0 || (perm.strings().length == 1 && perm.strings()[0].isEmpty())) { - if (!perm.alias().isEmpty()) { - autoGrantPerms.add(perm.alias()); - } - } else { - aliasSet.add(perm.alias()); - } - } + // If call was made with a list of specific permission aliases to request, save them + // to be requested + JSArray providedPerms = call.getArray("permissions"); + List providedPermsList = null; - permAliases = aliasSet.toArray(new String[0]); - } else { - for (Permission perm : annotation.permissions()) { - if (providedPermsList.contains(perm.alias())) { - aliasSet.add(perm.alias()); - } - } + if (providedPerms != null) { + try { + providedPermsList = providedPerms.toList(); + } catch (JSONException ignore) { + // do nothing + } + } - if (aliasSet.isEmpty()) { - call.reject("No valid permission alias was requested of this plugin."); + // If call was made without any custom permissions, request all from plugin annotation + Set aliasSet = new HashSet<>(); + if (providedPermsList == null || providedPermsList.isEmpty()) { + for (Permission perm : annotation.permissions()) { + // If a permission is defined with no permission strings, separate it for auto-granting. + // Otherwise, the alias is added to the list to be requested. + if (perm.strings().length == 0 || (perm.strings().length == 1 && perm.strings()[0].isEmpty())) { + if (!perm.alias().isEmpty()) { + autoGrantPerms.add(perm.alias()); + } } else { - permAliases = aliasSet.toArray(new String[0]); + aliasSet.add(perm.alias()); } } - if (permAliases != null && permAliases.length > 0) { - // request permissions using provided aliases or all defined on the plugin - requestPermissionForAliases(permAliases, call, "checkPermissions"); - } else if (!autoGrantPerms.isEmpty()) { - // if the plugin only has auto-grant permissions, return all as GRANTED - JSObject permissionsResults = new JSObject(); - - for (String perm : autoGrantPerms) { - permissionsResults.put(perm, PermissionState.GRANTED.toString()); + permAliases = aliasSet.toArray(new String[0]); + } else { + for (Permission perm : annotation.permissions()) { + if (providedPermsList.contains(perm.alias())) { + aliasSet.add(perm.alias()); } + } - call.resolve(permissionsResults); + if (aliasSet.isEmpty()) { + call.reject("No valid permission alias was requested of this plugin."); } else { - // no permissions are defined on the plugin, resolve undefined - call.resolve(); + permAliases = aliasSet.toArray(new String[0]); } } - } - @SuppressWarnings("deprecation") - private void handleLegacyPermission(PluginCall call) { - // handle permission requests for plugins defined with @NativePlugin (prior to 3.0.0) - NativePlugin legacyAnnotation = this.handle.getLegacyPluginAnnotation(); - String[] perms = legacyAnnotation.permissions(); - if (perms.length > 0) { - saveCall(call); - pluginRequestPermissions(perms, legacyAnnotation.permissionRequestCode()); + if (permAliases != null && permAliases.length > 0) { + // request permissions using provided aliases or all defined on the plugin + requestPermissionForAliases(permAliases, call, "checkPermissions"); + } else if (!autoGrantPerms.isEmpty()) { + // if the plugin only has auto-grant permissions, return all as GRANTED + JSObject permissionsResults = new JSObject(); + + for (String perm : autoGrantPerms) { + permissionsResults.put(perm, PermissionState.GRANTED.toString()); + } + + call.resolve(permissionsResults); } else { + // no permissions are defined on the plugin, resolve undefined call.resolve(); } } /** - * Handle request permissions result. A plugin using the deprecated {@link NativePlugin} - * should override this to handle the result, or this method will handle the result - * for our convenient requestPermissions call. + * Handle request permissions result. Subclasses may override to handle the result. * @deprecated in favor of using callbacks in conjunction with {@link CapacitorPlugin} * * @param requestCode @@ -878,18 +746,7 @@ private void handleLegacyPermission(PluginCall call) { * @param grantResults */ @Deprecated - protected void handleRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { - if (!hasDefinedPermissions(permissions)) { - StringBuilder builder = new StringBuilder(); - builder.append("Missing the following permissions in AndroidManifest.xml:\n"); - String[] missing = PermissionHelper.getUndefinedPermissions(getContext(), permissions); - for (String perm : missing) { - builder.append(perm + "\n"); - } - savedLastCall.reject(builder.toString()); - savedLastCall = null; - } - } + protected void handleRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {} /** * Called before the app is destroyed to give a plugin the chance to @@ -992,21 +849,6 @@ public Boolean shouldOverrideLoad(Uri url) { return null; } - /** - * Start a new Activity. - * - * Note: This method must be used by all plugins instead of calling - * {@link Activity#startActivityForResult} as it associates the plugin with - * any resulting data from the new Activity even if this app - * is destroyed by the OS (to free up memory, for example). - * @param intent - * @param resultCode - */ - @Deprecated - protected void startActivityForResult(PluginCall call, Intent intent, int resultCode) { - bridge.startActivityForPluginWithResult(call, intent, resultCode); - } - /** * Execute the given runnable on the Bridge's task handler * @param runnable diff --git a/android/capacitor/src/main/java/com/getcapacitor/PluginHandle.java b/android/capacitor/src/main/java/com/getcapacitor/PluginHandle.java index bfdd92285..f3df206b8 100644 --- a/android/capacitor/src/main/java/com/getcapacitor/PluginHandle.java +++ b/android/capacitor/src/main/java/com/getcapacitor/PluginHandle.java @@ -20,43 +20,27 @@ public class PluginHandle { private final String pluginId; - @SuppressWarnings("deprecation") - private NativePlugin legacyPluginAnnotation; - private CapacitorPlugin pluginAnnotation; private Plugin instance; - @SuppressWarnings("deprecation") private PluginHandle(Class clazz, Bridge bridge) throws InvalidPluginException { this.bridge = bridge; this.pluginClass = clazz; CapacitorPlugin pluginAnnotation = pluginClass.getAnnotation(CapacitorPlugin.class); if (pluginAnnotation == null) { - // Check for legacy plugin annotation, @NativePlugin - NativePlugin legacyPluginAnnotation = pluginClass.getAnnotation(NativePlugin.class); - if (legacyPluginAnnotation == null) { - throw new InvalidPluginException("No @CapacitorPlugin annotation found for plugin " + pluginClass.getName()); - } - - if (!legacyPluginAnnotation.name().equals("")) { - this.pluginId = legacyPluginAnnotation.name(); - } else { - this.pluginId = pluginClass.getSimpleName(); - } + throw new InvalidPluginException("No @CapacitorPlugin annotation found for plugin " + pluginClass.getName()); + } - this.legacyPluginAnnotation = legacyPluginAnnotation; + if (!pluginAnnotation.name().equals("")) { + this.pluginId = pluginAnnotation.name(); } else { - if (!pluginAnnotation.name().equals("")) { - this.pluginId = pluginAnnotation.name(); - } else { - this.pluginId = pluginClass.getSimpleName(); - } - - this.pluginAnnotation = pluginAnnotation; + this.pluginId = pluginClass.getSimpleName(); } + this.pluginAnnotation = pluginAnnotation; + this.indexMethods(clazz); } @@ -78,11 +62,6 @@ public String getId() { return this.pluginId; } - @SuppressWarnings("deprecation") - public NativePlugin getLegacyPluginAnnotation() { - return this.legacyPluginAnnotation; - } - public CapacitorPlugin getPluginAnnotation() { return this.pluginAnnotation; } diff --git a/cli/src/android/update.ts b/cli/src/android/update.ts index 8da8d8d9d..e0b7b264a 100644 --- a/cli/src/android/update.ts +++ b/cli/src/android/update.ts @@ -105,7 +105,7 @@ async function findAndroidPluginClassesInPlugin(plugin: Plugin): Promise !entry.stats.isDirectory() && ['.java', '.kt'].includes(extname(entry.path)), }); - const classRegex = /^@(?:CapacitorPlugin|NativePlugin)[\s\S]+?class ([\w]+)/gm; + const classRegex = /^@CapacitorPlugin[\s\S]+?class ([\w]+)/gm; const packageRegex = /^package ([\w.]+);?$/gm; debug('Searching %O source files in %O by %O regex', srcFiles.length, srcPath, classRegex);