Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
6aff2e8
Start of cordova removal
markemer May 20, 2024
2c2495c
Add files
markemer May 20, 2024
fceadd9
Continue cordova removal
Steven0351 May 20, 2024
42257e6
Allow CordovaPlugin to be initialized and used
Steven0351 May 22, 2024
d1be431
Cordova plugins working, first pass
markemer May 22, 2024
c1ea8df
Fixed server base path
markemer May 22, 2024
2b0a9c0
Update warning text
markemer May 22, 2024
e623660
Fix cordovaDeployDisabled selector nonsense
markemer May 22, 2024
0ed003c
Fix Capacitor Project
markemer May 22, 2024
ede62d1
Move CLI functions to prepare for cordova changes
markemer May 23, 2024
a03698e
fix: syntax errors from merge, update cordova cli
markemer Dec 16, 2024
b22fc33
fix: problem with podfile regex
markemer Dec 16, 2024
088aab1
Removed commented out stuff
markemer Dec 16, 2024
4e6d53e
npm run fmt
markemer Dec 16, 2024
d6c1769
More code cleanup
markemer Dec 17, 2024
4d160fc
fix test error looking for cordova
markemer Dec 17, 2024
a7c4859
Starting android cordova removal
Steven0351 May 24, 2024
d59d91e
Removing Cordova part 1
markemer May 28, 2024
a9e1212
Cordova removal part 3
Steven0351 May 28, 2024
2d78030
Cordova removal part 4
Steven0351 May 28, 2024
4d56638
Fixed interceptors maybe
markemer May 29, 2024
503b044
Cleanup for PR
markemer Dec 16, 2024
77b9090
fmt
markemer Dec 17, 2024
7dd9665
chore(cli): migrate command updates (#7795)
jcesarmobile Dec 16, 2024
426a54e
More code cleanup
markemer Dec 17, 2024
cf5df72
update ios/update to remove cordova if not needed
markemer Dec 17, 2024
1affb1e
npm run fmt
markemer Dec 17, 2024
87294a7
npm run fmt
markemer Nov 5, 2025
415c271
Remove some code that snuck back in
markemer Nov 5, 2025
a1aaad5
More code cleanup
markemer Nov 5, 2025
7b8d651
Temp workarounds (rebase this)
markemer Feb 3, 2026
a5e94b6
Merge branch 'main' into optional-cordova-cap8-rebase
markemer Feb 3, 2026
3723c13
Removed debugging statements
markemer Feb 3, 2026
0f2e0ea
add SPM cordova support
markemer Feb 9, 2026
d61e87f
Merge branch 'main' into optional-cordova-cap8-rebase
markemer Feb 11, 2026
1f223b0
npm run fmt`
markemer Feb 11, 2026
c3077cb
Merge branch 'main' into optional-cordova-cap8-rebase
markemer Feb 11, 2026
0e9b94b
Revert "Temp workarounds (rebase this)"
markemer Feb 11, 2026
d4116af
fixing weird merge collision
markemer Feb 11, 2026
8522a49
Merge branch 'main' into optional-cordova-cap8-rebase
markemer Feb 20, 2026
7b85309
Removed some comments, undid rename
markemer Feb 23, 2026
c10afab
npm run fmt
markemer Feb 23, 2026
4305ec6
Removed commented out code
markemer Feb 23, 2026
5b28e63
Remove unused Cordova configuration code
markemer Feb 23, 2026
bb535d1
This didn't make it into the last commmit like it should have
markemer Feb 24, 2026
414fbeb
Fixed tests, turned out to be a real bug.
markemer Feb 24, 2026
11b8b2f
npm run fmt
markemer Feb 24, 2026
7496e48
Added back some weirdly missing //es
markemer Feb 25, 2026
64d96e8
Merge branch 'next' of github.com:ionic-team/capacitor into optional-…
markemer Feb 25, 2026
4fdca99
Merge branch 'next' into optional-cordova-cap8-rebase
markemer Feb 26, 2026
e2bdc2b
Rename file to fix lint issue
markemer Feb 26, 2026
a3c57a9
Delete these weird useless files
markemer Feb 26, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
168 changes: 83 additions & 85 deletions android/capacitor/src/main/java/com/getcapacitor/Bridge.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,6 @@
import com.getcapacitor.android.R;
import com.getcapacitor.annotation.CapacitorPlugin;
import com.getcapacitor.annotation.Permission;
import com.getcapacitor.cordova.MockCordovaInterfaceImpl;
import com.getcapacitor.cordova.MockCordovaWebViewImpl;
import com.getcapacitor.util.HostMask;
import com.getcapacitor.util.InternalUtils;
import com.getcapacitor.util.PermissionHelper;
Expand All @@ -53,13 +51,9 @@
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Function;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.cordova.ConfigXmlParser;
import org.apache.cordova.CordovaPreferences;
import org.apache.cordova.CordovaWebView;
import org.apache.cordova.PluginEntry;
import org.apache.cordova.PluginManager;
import org.json.JSONException;

/**
Expand Down Expand Up @@ -125,9 +119,6 @@ public class Bridge {
private Boolean canInjectJS = true;
// A reference to the main WebView for the app
private final WebView webView;
public final MockCordovaInterfaceImpl cordovaInterface;
private CordovaWebView cordovaWebView;
private CordovaPreferences preferences;
private BridgeWebViewClient webViewClient;
private App app;

Expand All @@ -147,6 +138,8 @@ public class Bridge {
// A map of Plugin Id's to PluginHandle's
private Map<String, PluginHandle> plugins = new HashMap<>();

private Map<String, MessageHandler.Interceptor> interceptors = new HashMap<>();

// Stored plugin calls that we're keeping around to call again someday
private Map<String, PluginCall> savedCalls = new HashMap<>();

Expand Down Expand Up @@ -181,12 +174,12 @@ public Bridge(
AppCompatActivity context,
WebView webView,
List<Class<? extends Plugin>> initialPlugins,
MockCordovaInterfaceImpl cordovaInterface,
PluginManager pluginManager,
CordovaPreferences preferences,
Object cordovaInterface,
Object pluginManager,
Object preferences,
CapConfig config
) {
this(context, null, null, webView, initialPlugins, new ArrayList<>(), cordovaInterface, pluginManager, preferences, config);
this(context, (ServerPath) null, (Fragment) null, webView, initialPlugins, new ArrayList<>(), config);
}

private Bridge(
Expand All @@ -196,9 +189,6 @@ private Bridge(
WebView webView,
List<Class<? extends Plugin>> initialPlugins,
List<Plugin> pluginInstances,
MockCordovaInterfaceImpl cordovaInterface,
PluginManager pluginManager,
CordovaPreferences preferences,
CapConfig config
) {
this.app = new App();
Expand All @@ -209,20 +199,17 @@ private Bridge(
this.webViewClient = new BridgeWebViewClient(this);
this.initialPlugins = initialPlugins;
this.pluginInstances = pluginInstances;
this.cordovaInterface = cordovaInterface;
this.preferences = preferences;

// Start our plugin execution threads and handlers
handlerThread.start();
taskHandler = new Handler(handlerThread.getLooper());

this.config = config != null ? config : CapConfig.loadDefault(getActivity());
Logger.init(this.config);

// Initialize web view and message handler for it
this.initWebView();
this.setAllowedOriginRules();
this.msgHandler = new MessageHandler(this, webView, pluginManager);
this.msgHandler = new MessageHandler(this, webView);

// Grab any intent info that our app was launched with
Intent intent = context.getIntent();
Expand Down Expand Up @@ -450,12 +437,30 @@ private boolean isNewBinary() {
return false;
}

private Plugin cordova() {
PluginHandle handle = getPlugin("__CordovaHandle");
if (handle != null) {
return handle.getInstance();
}
return null;
}

public boolean isDeployDisabled() {
return preferences.getBoolean("DisableDeploy", false);
Plugin cordova = this.cordova();
if (cordova != null) {
return cordova.hasPermission("DisableDeploy");
} else {
return false;
}
}

public boolean shouldKeepRunning() {
return preferences.getBoolean("KeepRunning", true);
Plugin cordova = this.cordova();
if (cordova != null) {
return cordova.hasPermission("KeepRunning");
} else {
return false;
}
}

public void handleAppUrlLoadError(Exception ex) {
Expand All @@ -474,10 +479,6 @@ public boolean isDevMode() {
return (getActivity().getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
}

protected void setCordovaWebView(CordovaWebView cordovaWebView) {
this.cordovaWebView = cordovaWebView;
}

/**
* Get the Context for the App
* @return
Expand Down Expand Up @@ -567,6 +568,14 @@ public CapConfig getConfig() {
return this.config;
}

public MessageHandler.Interceptor getCallInterceptor(String type) {
return this.interceptors.get(type);
}

public void registerInterceptor(String type, MessageHandler.Interceptor interceptor) {
this.interceptors.put(type, interceptor);
}

public void reset() {
savedCalls = new HashMap<>();
for (PluginHandle handle : this.plugins.values()) {
Expand Down Expand Up @@ -1132,11 +1141,14 @@ boolean onRequestPermissionsResult(int requestCode, String[] permissions, int[]
if (plugin == null) {
boolean permissionHandled = false;
Logger.debug("Unable to find a Capacitor plugin to handle permission requestCode, trying Cordova plugins " + requestCode);
try {
permissionHandled = cordovaInterface.handlePermissionResult(requestCode, permissions, grantResults);
} catch (JSONException e) {
Logger.debug("Error on Cordova plugin permissions request " + e.getMessage());
PluginHandle cordovaHandle = getPlugin("__CordovaPlugin");

if (cordovaHandle != null) {
Plugin cordovaPlugin = cordovaHandle.getInstance();
cordovaPlugin.handleRequestPermissionsResult(requestCode, permissions, grantResults);
permissionHandled = cordovaPlugin.hasDefinedRequiredPermissions();
}

return permissionHandled;
}

Expand Down Expand Up @@ -1271,7 +1283,13 @@ boolean onActivityResult(int requestCode, int resultCode, Intent data) {

if (plugin == null || plugin.getInstance() == null) {
Logger.debug("Unable to find a Capacitor plugin to handle requestCode, trying Cordova plugins " + requestCode);
return cordovaInterface.onActivityResult(requestCode, resultCode, data);
PluginHandle cordovaHandle = getPlugin("__CordovaPlugin");
if (cordovaHandle != null) {
Plugin cordovaPlugin = cordovaHandle.getInstance();
cordovaPlugin.handleOnActivityResult(requestCode, resultCode, data);
// This is a bit hacky but required to return the boolean out of the cordova interface
return cordovaPlugin.hasRequiredPermissions();
}
}

// deprecated, to be removed
Expand Down Expand Up @@ -1301,10 +1319,6 @@ public void onNewIntent(Intent intent) {
for (PluginHandle plugin : plugins.values()) {
plugin.getInstance().handleOnNewIntent(intent);
}

if (cordovaWebView != null) {
cordovaWebView.onNewIntent(intent);
}
}

/**
Expand Down Expand Up @@ -1333,10 +1347,6 @@ public void onStart() {
for (PluginHandle plugin : plugins.values()) {
plugin.getInstance().handleOnStart();
}

if (cordovaWebView != null) {
cordovaWebView.handleStart();
}
}

/**
Expand All @@ -1346,10 +1356,6 @@ public void onResume() {
for (PluginHandle plugin : plugins.values()) {
plugin.getInstance().handleOnResume();
}

if (cordovaWebView != null) {
cordovaWebView.handleResume(this.shouldKeepRunning());
}
}

/**
Expand All @@ -1359,11 +1365,6 @@ public void onPause() {
for (PluginHandle plugin : plugins.values()) {
plugin.getInstance().handleOnPause();
}

if (cordovaWebView != null) {
boolean keepRunning = this.shouldKeepRunning() || cordovaInterface.getActivityResultCallback() != null;
cordovaWebView.handlePause(keepRunning);
}
}

/**
Expand All @@ -1373,10 +1374,6 @@ public void onStop() {
for (PluginHandle plugin : plugins.values()) {
plugin.getInstance().handleOnStop();
}

if (cordovaWebView != null) {
cordovaWebView.handleStop();
}
}

/**
Expand All @@ -1388,10 +1385,6 @@ public void onDestroy() {
}

handlerThread.quitSafely();

if (cordovaWebView != null) {
cordovaWebView.handleDestroy();
}
}

/**
Expand Down Expand Up @@ -1578,49 +1571,54 @@ public Builder setServerPath(ServerPath serverPath) {

public Bridge create() {
// Cordova initialization
ConfigXmlParser parser = new ConfigXmlParser();
parser.parse(activity.getApplicationContext());
CordovaPreferences preferences = parser.getPreferences();
preferences.setPreferencesBundle(activity.getIntent().getExtras());
List<PluginEntry> pluginEntries = parser.getPluginEntries();

MockCordovaInterfaceImpl cordovaInterface = new MockCordovaInterfaceImpl(activity);
if (instanceState != null) {
cordovaInterface.restoreInstanceState(instanceState);
}

WebView webView = this.fragment != null ? fragment.getView().findViewById(R.id.webview) : activity.findViewById(R.id.webview);
MockCordovaWebViewImpl mockWebView = new MockCordovaWebViewImpl(activity.getApplicationContext());
mockWebView.init(cordovaInterface, pluginEntries, preferences, webView);
PluginManager pluginManager = mockWebView.getPluginManager();
cordovaInterface.onCordovaInit(pluginManager);

// Bridge initialization
Bridge bridge = new Bridge(
activity,
serverPath,
fragment,
webView,
plugins,
pluginInstances,
cordovaInterface,
pluginManager,
preferences,
config
);
Bridge bridge = new Bridge(activity, serverPath, fragment, webView, plugins, pluginInstances, config);

if (webView instanceof CapacitorWebView capacitorWebView) {
capacitorWebView.setBridge(bridge);
}

bridge.setCordovaWebView(mockWebView);
bridge.setWebViewListeners(webViewListeners);
bridge.setRouteProcessor(routeProcessor);

if (instanceState != null) {
PluginHandle maybeCordova = bridge.getPlugin("__CordovaPlugin");
if (maybeCordova != null) {
maybeCordova.getInstance().restoreState(instanceState);
}
bridge.restoreInstanceState(instanceState);
}

bridge.registerInterceptor("message", (postData) -> {
try {
String callbackId = postData.getString("callbackId");
String pluginId = postData.getString("pluginId");
String methodName = postData.getString("methodName");
JSObject methodData = postData.getJSObject("options", new JSObject());

Logger.verbose(
Logger.tags("Plugin"),
"To native (Capacitor plugin): callbackId: " +
callbackId +
", pluginId: " +
pluginId +
", methodName: " +
methodName
);

PluginCall call = new PluginCall(bridge.msgHandler, pluginId, callbackId, methodName, methodData);
bridge.callPluginMethod(pluginId, methodName, call);
} catch (JSONException e) {
Logger.error(e.getMessage());
}
});

bridge.registerInterceptor("js.error", (postData) -> {
Logger.error("JavaScript Error: " + postData.toString());
});

return bridge;
}
}
Expand Down
Loading
Loading