agamemnus / cordova-plugin-xapkreader

Easily access Google Play APK expansion file data.
32 stars 55 forks source link

Gradle patch (work in progress) #22

Closed agamemnus closed 8 years ago

agamemnus commented 8 years ago

Cordova 5 ignores the ant build system. It uses gradle, instead. That means that the links to the Google Play downloader and licensing libraries are broken. To fix that, we need to use a build-extras.gradle file, and do some other things...

Due to some various Cordova 5 issues/bugs, a fully working Cordova 5 version isn't currently available. (there is a test Cordova-5 branch, however) Here are steps to make this plugin work for Cordova 5 (PLEASE NOTE THESE ARE STILL DRAFT INSTRUCTIONS): 1) Create a /platforms/android/com.flyingsoftgames.xapkreader/ directory. 2) Copy your /plugins/com.flyingsoftgames.xapkreader/android-sdk/extras/google/play_apk_expansion/downloader_library directory contents and your /plugins/com.flyingsoftgames.xapkreader/android-sdk/extras/google/play_licensing/library directory contents to /platforms/android/com.flyingsoftgames.xapkreader/downloader_library and /platforms/android/com.flyingsoftgames.xapkreader/library. 3) Instead of the single reference we added before, add this instead to project.properties:

android.library.reference.2=com.flyingsoftgames.xapkreader/downloader_library
android.library.reference.3=com.flyingsoftgames.xapkreader/library

4) Inside downloader_library, add a file named build-extras.gradle, with the following contents:

dependencies {
debugCompile project(path: ':com.flyingsoftgames.xapkreader:library',configuration: "debug")
releaseCompile project(path: ':com.flyingsoftgames.xapkreader:library',configuration: "release")
}

5) The automatic downloader DOES NOT SEEM TO WORK. We must disable it. In platforms/android/src/com/flyingsoftgames/xapkreader/XAPKDownloaderActivity.java, change return isDebug; to return true;.

6a) Cordova 5 has a whitelist plugin requirement. New builds have it by default. You must add this: cordova plugin add cordova-plugin-whitelist. In your index.html file, you also need to add a Content-Security-Policy meta tag. Note that the instructions on the whitelist plugin on github do not show the most permissive meta tag and forget about content:// or cdvfile://. The most permissive meta tag seems to be: <meta http-equiv="Content-Security-Policy" content="* * 'self' default-src 'unsafe-inline' 'unsafe-eval' http://* https://* data: cdvfile://* content://*;">. (content:// and cdvfile:// should really be included by default. If you want to omit those, I made a patch here: https://github.com/agamemnus/cordova-plugin-whitelist)

6b) Make sure to add allow-navigation, and allow-intent, and extra access origin tags to config.xml. E.G.:

    <allow-navigation href="*://*/*"/>
    <allow-intent href="*" />
    <access origin="*" />
    <access origin="content:///*" />
    <access origin="cdvfile:///*" />

NOTE 1: Please do not post any logs here (unless absolutely necessary)! NOTE 2: If you are on Crosswalk, note that you must use the plugin method for Cordova 5+ builds. The migrate method no longer works.

mattrayner commented 8 years ago

Is there any way I can help?

agamemnus commented 8 years ago

You could try to find the documentation for gradle's "dependencies {" syntax and the path syntax.

agamemnus commented 8 years ago

I managed to get both libraries to compile in a VERY HACKISH WAY, but IT IS STILL CRASHING after trying to open and process a PNG file: C:\mr_jigtato_free\platforms\android\build\intermediates\exploded-aar\android.......plugins. com.flyingsoftgames.xapkreader.android-sdk.extras.google.play_apk_expansion\downloader_library\unspecified\release\res\drawable-mdpi-v4\notify_panel_notification_icon_bg.png.

To have both files compile: 1) Add the build-extras.gradle in /platforms/android as described above. 2) Add an EXTRA line in project.properties (apparently, it is still used): android.library.reference.3=../../plugins/com.flyingsoftgames.xapkreader/android-sdk/extras/google/play_licensing/library 3) In the downloader_library directory, add a build-extras.gradle like this:

dependencies {
 debugCompile project(path: ':..:..:plugins:com.flyingsoftgames.xapkreader:android-sdk:extras:google:play_licensing:library',configuration: "debug")
 releaseCompile project(path: ':..:..:plugins:com.flyingsoftgames.xapkreader:android-sdk:extras:google:play_licensing:library',configuration: "release")
}
mattrayner commented 8 years ago

Do these docs help at all? https://docs.gradle.org/current/dsl/org.gradle.api.artifacts.dsl.DependencyHandler.html

agamemnus commented 8 years ago

Nope (but getting there??). It would be nice to see an example of more than one dependency for the same compile type. Just try playing around with it... I tried putting both sets of dependencies (downloader/licensing) in one spot, or making the second one relative (I think?), and neither of those worked.

igormas commented 8 years ago

I tried to fix this issue with no success, now i switched to this plugin https://github.com/imaffett/APKexpansion. I think the correct way to add 'play_apk_expansion' as a dependency to this plugin is by adding, framework element to plugin.xml (you can check how this done in the repo).

agamemnus commented 8 years ago

I did add the framework stuff. I forgot to mention it. I just noticed, though, that the second library is "not zip_file", it is "play_licensing". Stay tuned...

I don't know if my PROJECTNAME would ever work, anyway. It has spaces and is inside a tag. I don't know if that is even the same thing. Maybe the PROJECTNAME referred to is a phonegap thing. Edit: in any case, I do not add the libraries to the platforms/android/src directory.

igormas commented 8 years ago

I might be wrong, but I think that all the dependencies which included in the project.properties should be download/copied to platforms/android folder. The discussed bug, in which the PROJECTNAME is added as a suffix, is caused during this process.

agamemnus commented 8 years ago

The project.properties dependency list doesn't copy anything to platforms/android, it just links.

I don't quite know how and the gradle linking system works, though...

agamemnus commented 8 years ago

Okay, I am seeing that Cordova 5 puts er (edit: gradle files) in /android/platforms instead of in /plugins. Apparently. (after trying to remove my "old" xapkreader plugin, I wasn't able to as it was trying to get it from /android/platforms/com.flyingsoftgames.xapkreader).

What a mess.

agamemnus commented 8 years ago

I found a way to get this to compile with Cordova 5. I made a branch for this. Unfortunately, I don't know how to add a plugin from a non-main branch with Cordova. Anyway, It involves a number of manual steps. I'll post this as soon as I fix an issue with another plugin that is preventing me from fully compiling and fully testing.

agamemnus commented 8 years ago

Here is the associated Cordova bug which I just posted:

https://issues.apache.org/jira/browse/CB-9132

mattrayner commented 8 years ago

You are amazing! Do you have GitTip?

agamemnus commented 8 years ago

Yes, same name.

Did you get it working with the bug report info? I just managed to get my game to freaking compile. I needed to add the whitelist plugin as a final step (which is added on Cordova 5 new builds): cordova plugin add cordova-plugin-whitelist.

mattrayner commented 8 years ago

Hi, I didnt have access to my work repo over the weekend so I'm attempting this fix now that I'm at my desk, I'll report on any issues I have :+1:

mattrayner commented 8 years ago

To answer your above statement about adding a non-master plugin for this repo you can use the below sript:

SETUP

cd ~
mkdir -p ~/projects/cordova-plugins
cd ~/projects/cordova-plugins
git clone git@github.com:agamemnus/cordova-plugin-xapkreader.git
cd cordova-plugin-xapkreader
git checkout cordova-5.0

WITHIN CORDOVA PROJECT

cordova plugin add ~/projects/cordova-plugins/cordova-plugin-xapkreader
mattrayner commented 8 years ago

I'm struggling now with the build-extras.gradle file within platforms/android/com.flyingsoftgames.xapkreader/$PROJECT_NAME-downloader_library

it is looking for play_licensing as if it is in the plugins directory still. I'm going to carry on trying to fix it and will let you know if I get anywhere

mattrayner commented 8 years ago

I finally got my project building, I belive what did it was editing the build-extras.gradle file i mentioned above to have the below content

dependencies {
 debugCompile project(path: ':com.flyingsoftgames.xapkreader:$PATH_NAME-library',configuration: "debug")
 releaseCompile project(path: ':com.flyingsoftgames.xapkreader:$PATH_NAME-library',configuration: "release")
}

It was this Stackoverflow article that helped me in the end

Apparently relative names are frowned upon in Gradle

mattrayner commented 8 years ago

Ok, I've got the furthest ever got :stuck_out_tongue_closed_eyes:... The problem is that I'm still erroring... I've whitelisted the plugin content as explained above and now have a null pointer error:

W/System.err(31236): java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.res.AssetFileDescriptor com.flyingsoftgames.xapkreader.XAPKZipResourceFile.getAssetFileDescriptor(java.lang.String)' on a null object reference

I'm trying to see if I can fix it

agamemnus commented 8 years ago

I never got that problem, so I am not sure about it right now.

I'm updating the first post with whitelist instructions -- you also need to add a header, but it is not related, I think.

mattrayner commented 8 years ago

I've got mine past the Null Pointer Error and onto contacting Google Play - I had to make the following change to XAPKProvider.java at like 113

AssetFileDescriptor result;

  try {
   result = mAPKExtensionFile.getAssetFileDescriptor (path);
  } catch(Exception e) {
   throw new FileNotFoundException();
  }
agamemnus commented 8 years ago

Oh wow... actually I may have had this problem too. I updated the meta tag at the top. I'm compiling now with your code. Let's see what happens.

agamemnus commented 8 years ago

Did you manage to get around the whitelist plugin terminating cdvfile:// and content:// attempts? I gave it a shot but it looks like the meta tag above ignores my feeble pleas.

mattrayner commented 8 years ago

I'm looking into that now

agamemnus commented 8 years ago

OK. I am going to try a change in the whitelist plugin. https://github.com/apache/cordova-plugin-whitelist/pull/5 ... made a fork temporarily: https://github.com/agamemnus/cordova-plugin-whitelist. (still broken, trying different things)

mattrayner commented 8 years ago

Did that fix your whitelist issues? I'm still having problems :-1:

agamemnus commented 8 years ago

Sorry, it's still broken. I am trying different things.

agamemnus commented 8 years ago

We don't need to use the whitelist plugin, I suppose. There's some stuff (JS files?) hard-coding its requirement somewhere, though, I think.

mattrayner commented 8 years ago

I've got rid of the Web view issues with this:

<!-- A wildcard can be used to whitelist the entire network,
     over HTTP and HTTPS.
     *NOT RECOMMENDED* -->
    <allow-navigation href="*" />
    <!-- Allow all unrecognized URLs to open installed apps
      *NOT RECOMMENDED* -->
    <allow-intent href="*" />
    <!-- Don't block any requests -->
    <access origin="*" />

    <access origin="content:///*" />

Now I just have issues with the AndroidProtocolHandler which appears to not know what to do with it?

mattrayner commented 8 years ago

I added that to the bottom of config.xml

mattrayner commented 8 years ago

This meta tag seemed to help surpress some of the warnings I was getting:

<meta http-equiv="Content-Security-Policy" content="default-src 'self' data: 'unsafe-inline' 'unsafe-eval' http:///* https:///* cdvfile:///* content:///* ">
agamemnus commented 8 years ago

Hmm. I get errors in the console though if I use three forward slashes, like this:

"The source list for Content Security Policy directive 'default-src' contains an invalid source: 'cdvfile:///*'. It will be ignored."

Edit: it seems I am getting errors with 3 slashes that doesn't let me go forward.

agamemnus commented 8 years ago

BAH! I modified my code to just let everything go through -- https://github.com/agamemnus/cordova-plugin-whitelist.

mattrayner commented 8 years ago

Ok, what did you change?

agamemnus commented 8 years ago

I made "shouldAllowNavigation" just return true... I'm still playing around with this, but that is the extreme that always works. :+1:

mattrayner commented 8 years ago

Ok awesome, I've just implemented that... Paired with this it seems to work:

<meta http-equiv="Content-Security-Policy" content="default-src 'self' http://*/* https://*/* cdvfile://*/* content://*/* data 'unsafe-inline' 'unsafe-eval';">
agamemnus commented 8 years ago

It would really be better if we could disable the whitelist shenanigans completely.

mattrayner commented 8 years ago

Yeah :/

It seems to be working on min now (other than not finding the files) - how do I get it to initialise the download from google?

agamemnus commented 8 years ago

Okay, I updated my whitelist code.

I think you need to change your origin back by the way. It should just be <access origin="*" />.

mattrayner commented 8 years ago

If I change it back I get 'url blocked by whitelist'

agamemnus commented 8 years ago

The second access-origin overwrites the first, I think, so that shouldn't happen.

Regarding the download, that's a little broken for debug builds. (edit: or maybe builds in general??) I'll work on it later today. Just change return isDebug; to return true; in XAPKDownloaderActivity.java.

igormas commented 8 years ago

Hi, I made a PR with cordova 5.0.0 patch, the android build is passing with this fix. The only manual change that is required is in build-extras.gradle file which located in platforms/android/com.flyingsoftgames.xapkreader/$PROJECTNAME-downloader_library. You need to fix the path, just add the $PROJECTNAME prefix to debug & release compile, eventually it should look like this:

dependencies {
    debugCompile project(path: ':com.flyingsoftgames.xapkreader:$PROJECTNAME-library',configuration: "debug")
    releaseCompile project(path: ':com.flyingsoftgames.xapkreader:$PROJECTNAME-library',configuration: "release")
}
marcoturi commented 8 years ago

@igormas what should be $PROJECTNAME ? Can you provide an example ?

agamemnus commented 8 years ago

Thank you. Similar code is in the cordova-5 branch, but there are still 3 (or maybe 4) problems I have with merging this.

1) I am concerned that <framework> may break non-Gradle builds. So, this needs to be checked. 2a) The bug with the naming and proper directory structure for copied "framework" files will cause more complaints (!) that this isn't working for 5. (https://issues.apache.org/jira/browse/CB-9132) Even more confusing, it is not $PROJECTNAME that needs to be added as a prefix, it is the last part of $PROJECTNAME after any spaces in it. 2b) I don't want to copy the library files into the project. That means setting custom=false in the <framework> tag. That avoid (2a), but then the problem is that the linking doesn't work, or at least I don't know how to do it correctly. 3) The thing about isDebug returning false (in signatureIsDebug in XAPKDownloaderActivity.java and the download not starting on APKs not installed from Google Play... Actually maybe this is an issue from before, but I am not 100% certain... Two scenarios here: A) Builds not installed from Google Play would not get downloads at all, regardless of the signature and Cordova version. So, there needs to be some way to make sure that these builds don't try to start a download from Google Play. I added in something that checks the certificate for a "CN=Android Debug" string, but what if the cert is the same on debug versus builds from Google Play? B) If this is just an issue with Cordova 5 (for some reason), then that needs to be fixed at the same time.

TL; DR: I really need to test this further!

agamemnus commented 8 years ago

@Shinji89: the prefix is the last part after the space of the tag in config.xml, in lower-case. Once you re-install the plugin with Cordova 5 you will see this. So, if you had <name>My Game</name>, the prefix would be game-.

igormas commented 8 years ago

Sounds like a big headache.... If I'll make any progress with these issues I'll keep you posted. You are doing great work here !!! :)

igormas commented 8 years ago

@Shinji89 yeah it seems that the libraries copied only when you installing the plugin.

marcoturi commented 8 years ago

Thank @agamemnus ! I keep getting errors from plugins\com.flyingsoftgames.xapkreader\android-sdk\extras\google\play_apk_expansion\downloader_library\build-extras.gradle...

I tried:

dependencies {
    debugCompile project(path: ':com.flyingsoftgames.xapkreader:library',configuration: "debug")
    releaseCompile project(path: ':com.flyingsoftgames.xapkreader:library',configuration: "release")
}
dependencies {
    debugCompile project(path: ':com.flyingsoftgames.xapkreader:project-library',configuration: "debug")
    releaseCompile project(path: ':com.flyingsoftgames.xapkreader:project-library',configuration: "release")
}
dependencies {
 debugCompile project(path: '..:..:play_licensing:library',configuration: "debug")
 releaseCompile project(path: '..:..:play_licensing:library',configuration: "release")
}
agamemnus commented 8 years ago

(Please make sure to use double or quadruple `` when quoting.)

Do you have the project-library directory actually present in /platforms/android/com.flyingsoftgames.xapkreader?

marcoturi commented 8 years ago

nope