Due to warning from GooglePlay regarding the security vulnerabilities found in older apache cordova on android platform (warning letter example), affected apps should be upgraded to apache cordova version 3.5.1 or newer. The deadline is, last time I saw, the end of April 2015.

Warning: this is not the proper way to update your app. This is mostly notes of things I have done to achieve the desired effect because of the specific pre-existing condition.

The existing source code had been implemented with apache cordova 2.5, which has considerable differences compared to apache cordova 3.X, and already in the android platform with custom native plugins. I did not use —you should if you want to maintain the cross-platform capability— the CLI npm, cordova, and plugman to update the cordova version and fit in the custom plugins without writing a number of adjustment to comply with the newer plugin development guideline. Another consideration is that the updated project should be able to be opened and built in Eclipse. This is where most of my headaches come from. But as this was a patch before newer version of the app comes out in a few weeks (hope so!) I just wiggled my way into the new structure and mechanism.

For illustration purposes, I use myapp as the existing project that needed updating, with the following folder structure:

		/* ... other .java files... */
		/* ... other files... */
		/* ... other .jar files... */ 

existing folder structure and files that need touch up



Step #0: Create separate app, for config.xml reference and step #3

So what I did was creating a cordova app project as is shown in the guideline, in separate unrelated folder, called newapp. I added the android platform and built it. I would need the newapp/platforms/android/res/xml/config.xml as reference for step #2.

Step #1: Getting the right cordova.jar and cordova.js

From apache cordova archives I picked apache cordova 3.7.1 android platform and extracted the archive.

I imported the cordova-android-3.7.1/package/framework into Eclipse. It would automatically build a jar file (or, use the ant build command, if you want to escape Eclipse), cordova-android-3.7.1/package/framework/bin/cordova.jar. I would copy the jar file into myapp/libs/ and have it added in the build path list in the project properties section. Or, I could simply add the Cordova lib to the property library, in the project properties.

For the javascript file, I removed the myapp/assets/www/cordova/cordova-2.5.0.js and then copied the cordova-android-3.7.1/package/framework/assets/www/cordova.js into the existing myapp/assets/www/ folder. I changed the reference to cordova’s javascript file in the index.html and other .html files.

<script type="text/javascript" src="js/cordova/cordova-2.5.0.js"> </script>

The old cordova-2.5.0.js reference in .html files

<script type="text/javascript" src="cordova.js"></script>

The new cordova.js (from apache cordova 3.7.1) reference in .html files

Step #2: Porting Custom Plugins Manually

To get existing native plugins to work, there are a number of files I need to manipulate:

  1. The plugin java class file, eg. APlugin.java
  2. res/xml/config.xml

APlugin.java and related .java files

The files that need to be altered are ones that call apache cordova api and extend the DroidGap in version 2.5 CordovaPlugin class in version 3.7.1.

package com.app.plugin;

// .. imports

import org.apache.cordova.api.CallbackContext;
import org.apache.cordova.api.CordovaPlugin;
import org.apache.cordova.api.PluginResult;

// ...imports 

public class APlugin extends DroidGap {
    *  class APlugin implementation

The old APlugin.java (for apache cordova 2.5)

The changes are:

  1. import org.apache.cordova.api.{class-name} to import org.apache.cordova.{class-name}
  2. extends DroidGap to extends CordovaPlugin
package com.app.plugin;

// .. imports

import org.apache.cordova.CallbackContext;
import org.apache.cordova.CordovaPlugin;
import org.apache.cordova.PluginResult;

// ...imports 

public class APlugin extends CordovaPlugin {
    *  class APlugin implementation

The new APlugin.java (for apache cordova 3.7.1)


The old myapp/res/xml/config.xml would look like this:

<?xml version="1.0" encoding="utf-8"?>
     <!-- ... -->
     <!-- plugin registry -->

        <plugin name="Device" value="org.apache.cordova.Device"/>
        <!-- Developer section -->
        <!-- entry for custom plugin APlugin -->
        <plugin name="APlugin" value="com.app.plugin.APlugin"></plugin>
        <!-- End of section -->

the old config.xml (apache cordova 2.5)

I replaced it with the config.xml found in cordova-android-3.7.1/package/framework/res/xml.

<?xml version='1.0' encoding='utf-8'?>
<widget id="com.app.mobile.myapp" version="0.0.1" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0">
      <feature name="Device">
        <param name="android-package" value="org.apache.cordova.device.Device" />

     <!-- entry for custom plugin APlugin -->  
     <feature name="APlugin"> 
        <param   name="android-package" value="com.app.plugin.APlugin" /> 

    <!-- ... other configs ... -->  

the new config.xml (apache cordova 3.7.1)

There would be error and deprecation warnings shown in Eclipse that should be adjusted to newer version, like in MainActivity.java, I got deprecation warning on this.loadUrl() and should change it to loadUrl().



Step #3: What About Apache Cordova Plugins?

Yes, there is the issue with plugins written for apache cordova (for example from Apache Cordova Plugins Registry) that are usually added with the command:

cordova plugin add <path-to-plugin-or-git-url>

The existing app had used apache cordova facebook plugin that also needed updating. This is where step #0 comes in handy. In that newapp project, I added the intended plugin, the com.phonegap.plugins.facebookconnect, added the android platform and built it.

Then, I put the facebook.jar and bolts-android-1.1.2.jar (found in newapp/platforms/android/com.phonegap.plugins.facebookconnect/myapp-FacebookLib/libs) to myapp/libs/, and added them in the build path in the properties setting.

There was also the javascipt plugin bridges that had to be added to myapp. From newapp/platforms/android/assets/www, I copied the cordova_plugins.js and folder plugins (containing the com.phonegap.plugins.facebookconnect/facebookConnectPlugins.js) to myapp/assets/www.

In the myapp/res/xml/config.xml, had step #3 been done before step #1, the newapp/platforms/android/res/xml/config.xml would have included the entry for facebook connect plugin:

      <feature name="FacebookConnectPlugin">
          <param name="android-package" value="org.apache.cordova.facebook.ConnectPlugin" />
      <access origin="https://m.facebook.com" />
      <access origin="https://graph.facebook.com" />
      <access origin="https://api.facebook.com" />
      <access origin="https://*.fbcdn.net" />
      <access origin="https://*.akamaihd.net" />

Facebook connect plugin entry in config.xml

I copied the entries related to facebook connect to myapp/res/xml/config.xml.



That was more or less the gist of what I did to get the app updated to meet the security requirement from Google Play.