├── .gitignore ├── CHANGELOG.md ├── LICENSE.md ├── README.md ├── app ├── build.gradle ├── libs │ └── Parse-1.8.2.jar ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ ├── aidl │ └── com │ │ └── android │ │ └── vending │ │ └── licensing │ │ ├── ILicenseResultListener.aidl │ │ └── ILicensingService.aidl │ ├── assets │ ├── abaker_usage │ │ ├── archive.html │ │ ├── css │ │ │ ├── archive.css │ │ │ ├── download.css │ │ │ ├── read.css │ │ │ └── shared.css │ │ ├── download.html │ │ ├── img │ │ │ ├── abaker-ui-archive-hand.png │ │ │ ├── abaker-ui-download-hand.png │ │ │ └── abaker-ui-read-hand.png │ │ └── read.html │ ├── background.html │ ├── books │ │ └── README │ ├── header.html │ ├── img │ │ ├── header.png │ │ ├── logo.png │ │ └── splash.png │ ├── info.html │ └── sample.mp4 │ ├── java │ └── com │ │ ├── bakerframework │ │ └── baker │ │ │ ├── BakerApplication.java │ │ │ ├── GcmBroadcastReceiver.java │ │ │ ├── activity │ │ │ ├── InfoActivity.java │ │ │ ├── IssueActivity.java │ │ │ ├── ModalActivity.java │ │ │ ├── ShelfActivity.java │ │ │ └── SplashActivity.java │ │ │ ├── adapter │ │ │ └── IssueAdapter.java │ │ │ ├── events │ │ │ ├── ArchiveIssueCompleteEvent.java │ │ │ ├── DownloadIssueCompleteEvent.java │ │ │ ├── DownloadIssueErrorEvent.java │ │ │ ├── DownloadIssueProgressEvent.java │ │ │ ├── DownloadManifestCompleteEvent.java │ │ │ ├── DownloadManifestErrorEvent.java │ │ │ ├── ExtractIssueCompleteEvent.java │ │ │ ├── ExtractIssueErrorEvent.java │ │ │ ├── ExtractIssueProgressEvent.java │ │ │ ├── FetchPurchasesCompleteEvent.java │ │ │ ├── FetchPurchasesErrorEvent.java │ │ │ ├── IssueCollectionErrorEvent.java │ │ │ ├── IssueCollectionLoadedEvent.java │ │ │ ├── IssueDataUpdatedEvent.java │ │ │ ├── ParseBookJsonCompleteEvent.java │ │ │ └── ParseBookJsonErrorEvent.java │ │ │ ├── handler │ │ │ ├── ApiRequestHandler.java │ │ │ ├── DownloadHandler.java │ │ │ └── PluginManager.java │ │ │ ├── helper │ │ │ ├── FileHelper.java │ │ │ └── ImageLoaderHelper.java │ │ │ ├── jobs │ │ │ ├── ArchiveIssueJob.java │ │ │ ├── DownloadIssueJob.java │ │ │ ├── DownloadManifestJob.java │ │ │ ├── ExtractIssueJob.java │ │ │ ├── FetchPurchasesJob.java │ │ │ ├── ParseBookJsonJob.java │ │ │ └── Priority.java │ │ │ ├── model │ │ │ ├── BookJson.java │ │ │ ├── Issue.java │ │ │ ├── IssueCollection.java │ │ │ ├── LocalIssueCollection.java │ │ │ └── RemoteIssueCollection.java │ │ │ ├── play │ │ │ ├── ApiPurchaseVerifier.java │ │ │ ├── LicenceManager.java │ │ │ └── LicenceManagerDelegate.java │ │ │ ├── plugin │ │ │ ├── BakerPlugin.java │ │ │ ├── GoogleAnalyticsPlugin.java │ │ │ └── ParsePlugin.java │ │ │ ├── settings │ │ │ ├── Configuration.java │ │ │ ├── SettingsActivity.java │ │ │ └── SettingsFragment.java │ │ │ ├── view │ │ │ ├── CustomWebView.java │ │ │ ├── IssueCardView.java │ │ │ ├── ShelfView.java │ │ │ ├── WebViewFragment.java │ │ │ └── WebViewFragmentPagerAdapter.java │ │ │ └── widget │ │ │ └── SwipeRefreshScrollLayout.java │ │ └── google │ │ └── android │ │ └── vending │ │ └── licensing │ │ ├── AESObfuscator.java │ │ ├── APKExpansionPolicy.java │ │ ├── DeviceLimiter.java │ │ ├── ILicenseResultListener.java │ │ ├── ILicensingService.java │ │ ├── LicenseChecker.java │ │ ├── LicenseCheckerCallback.java │ │ ├── LicenseValidator.java │ │ ├── NullDeviceLimiter.java │ │ ├── Obfuscator.java │ │ ├── Policy.java │ │ ├── PreferenceObfuscator.java │ │ ├── ResponseData.java │ │ ├── ServerManagedPolicy.java │ │ ├── StrictPolicy.java │ │ ├── ValidationException.java │ │ └── util │ │ ├── Base64.java │ │ └── Base64DecoderException.java │ └── res │ ├── anim │ ├── bounce.xml │ ├── fade_in.xml │ ├── fade_out.xml │ └── logo_fade_in.xml │ ├── drawable-hdpi │ ├── baker_action_button.xml │ ├── baker_modal_button.xml │ ├── drawer_shadow.9.png │ ├── ic_action_about.png │ ├── ic_action_labels.png │ ├── ic_action_refresh.png │ ├── ic_action_settings.png │ ├── ic_drawer.png │ ├── ic_launcher.png │ ├── logo.png │ ├── progressbar.xml │ └── rounded_corners.xml │ ├── drawable-mdpi │ ├── drawer_shadow.9.png │ ├── ic_action_about.png │ ├── ic_action_labels.png │ ├── ic_action_refresh.png │ ├── ic_action_settings.png │ ├── ic_drawer.png │ ├── ic_launcher.png │ └── logo.png │ ├── drawable-xhdpi │ ├── drawer_shadow.9.png │ ├── ic_action_about.png │ ├── ic_action_labels.png │ ├── ic_action_refresh.png │ ├── ic_action_settings.png │ ├── ic_drawer.png │ ├── ic_launcher.png │ └── logo.png │ ├── drawable-xxhdpi │ ├── drawer_shadow.9.png │ ├── ic_action_about.png │ ├── ic_action_labels.png │ ├── ic_action_refresh.png │ ├── ic_action_settings.png │ ├── ic_action_subscribe.png │ ├── ic_drawer.png │ ├── ic_launcher.png │ └── logo.png │ ├── drawable │ ├── baker_scrollbar_horizontal.xml │ ├── baker_scrollbar_vertical.xml │ ├── cover_shadow.9.png │ └── loading.jpg │ ├── layout-v14 │ └── drawer_list_item.xml │ ├── layout │ ├── drawer_list_item.xml │ ├── fragment_category.xml │ ├── info_activity.xml │ ├── issue_activity.xml │ ├── issue_card_view.xml │ ├── modal_activity.xml │ ├── settings_actionbar.xml │ ├── shelf_actionbar.xml │ ├── shelf_activity.xml │ ├── splash_activity.xml │ ├── usage_activity.xml │ ├── view_loading_video.xml │ └── web_view_fragment.xml │ ├── menu │ ├── magazine.xml │ ├── shelf.xml │ └── video.xml │ ├── values-sw600dp │ └── dimens.xml │ ├── values-sw720dp-land │ └── dimens.xml │ ├── values-v11 │ └── styles.xml │ ├── values-v14 │ └── styles.xml │ ├── values-v16 │ └── styles.xml │ ├── values-w820dp │ └── dimens.xml │ ├── values │ ├── attrs.xml │ ├── booleans.xml │ ├── dimens.xml │ ├── ga_settings.xml │ ├── strings.xml │ ├── styles.xml │ └── theme.xml │ └── xml │ ├── ecommerce_tracker.xml │ ├── global_tracker.xml │ └── preferences.xml ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | #built application files 2 | *.apk 3 | *.ap_ 4 | 5 | # files for the dex VM 6 | *.dex 7 | 8 | # Java class files 9 | *.class 10 | 11 | # generated files 12 | bin/ 13 | gen/ 14 | 15 | # Local configuration file (sdk path, etc) 16 | local.properties 17 | 18 | # Windows thumbnail db 19 | Thumbs.db 20 | 21 | # OSX files 22 | .DS_Store 23 | 24 | # Eclipse project files 25 | .classpath 26 | .project 27 | 28 | # Android Studio 29 | .idea 30 | #.idea/workspace.xml - remove # and delete .idea if it better suit your needs. 31 | .gradle 32 | build/ 33 | 34 | # Project specific 35 | secret.yml 36 | app/manifest-merger-release-report.txt 37 | app/src/main/assets/books/*/* 38 | *.iml 39 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Baker Android App Changelog 2 | 3 | 4.4.0: 4 | 5 | ▸ XWalkView 11.40.277.7 integration (Chromium version 40) 6 | ▸ Removal of native Android Webview 7 | ▸ Support for latest chromium features 8 | ▸ Web view stability improvements (memory-management) 9 | 10 | 4.3.0: 11 | 12 | ▸ Initial Release, based on refactoring bakerframework/baker-android repository 13 | ▸ In App Purchases and Subscriptions 14 | ▸ Performance optimizations 15 | ▸ UI / Usability optimizations (aligned with baker iOS) 16 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright (c) 2013-2014. Francisco Contreras, Holland Salazar. 2 | Copyright (c) 2015. Tobias Strebitzer, Francisco Contreras, Holland Salazar. 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without modification, are 6 | permitted provided that the following conditions are met: 7 | 8 | Redistributions of source code must retain the above copyright notice, this list of 9 | conditions and the following disclaimer. 10 | Redistributions in binary form must reproduce the above copyright notice, this list of 11 | conditions and the following disclaimer in the documentation and/or other materials 12 | provided with the distribution. 13 | Neither the name of the Baker Framework nor the names of its contributors may be used to 14 | endorse or promote products derived from this software without specific prior written 15 | permission. 16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 17 | EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 | OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 19 | SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 20 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 21 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 24 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Baker Android App [](https://play.google.com/store/apps/details?id=com.magloft.demo) [](https://travis-ci.org/bakerframework/baker-android-refactor) 2 | 3 | The HTML5 ebook framework to publish interactive books & magazines on any Android device using simply open web standards http://bakerframework.com 4 | 5 | Please see the [issues](https://github.com/bakerframework/baker-android-refactor/issues) section to 6 | report any bugs or feature requests and to see the list of known issues. 7 | 8 | ## Preview 9 | 10 | [](http://cdn.magloft.com/preview/baker-android.mp4) 11 | 12 | [](https://play.google.com/store/apps/details?id=com.magloft.demo) 13 | 14 | ## Requirements 15 | 16 | 1. Android Studio: 17 | 18 | Tools > Android SDK Tools 19 | Tools > Android SDK Platform-tools 20 | Tools > Android SDK Build-tools 21 | Android 5.0.1 (API 21) > SDK Platform 22 | Extras > Android Support Repository 23 | Extras > Android Support Library 24 | Extras > Google Play services 25 | Extras > Google Repository 26 | Extras > Google Play Billing Library 27 | Extras > Google Play Licensing Library 28 | 29 | ## Installation 30 | Clone or [Download](https://github.com/bakerframework/baker-android-refactor/archive/4.4.0.zip) this repository, import in Android Studio and build/run the _Baker_ build configuration 31 | 32 | $ git clone git@github.com:bakerframework/baker-android-refactor.git 33 | 34 | Beginner-friendly instructions can be found in [Tutorial - Installation Guide](https://github.com/bakerframework/baker-android-refactor/wiki/Tutorial---Installation-Guide) 35 | 36 | ## Tutorials 37 | 38 | Tutorials can be found in the [Baker Android Wiki](https://github.com/bakerframework/baker-android-refactor/wiki) 39 | 40 | ## Acknowledgements 41 | 42 | This project is based on the original [Baker Android](https://github.com/bakerframework/baker-android) project by @fcontreras, @hsalazarl and @nin9creative. 43 | 44 | This project follows the features and roadmap of the official [Baker iOS Project](https://github.com/bakerframework/baker), currently maintained by @pieterclaerhout, @nin9creative and the baker community. 45 | 46 | This project integrates nicely with [Baker Cloud Console](http://www.bakerframework.com/bakercloudce/) and [MagLoft](http://www.magloft.com). 47 | 48 | A special shout-out to Intel Open Source Technology Center for bringing a chromium-based webview to android, allowing modern HTML5/CSS3 awesomeness, which is not provided by the native webview in current android sdks. 49 | 50 | It also uses other great open source libraries such as: 51 | 52 | * [jsoup](https://github.com/jhy/jsoup) 53 | * [Android Checkout Library](https://github.com/serso/android-checkout) 54 | * [Google GSON](https://code.google.com/p/google-gson) 55 | * [Universal Image Loader](https://github.com/nostra13/Android-Universal-Image-Loader) 56 | * [ViewPagerIndicator](https://github.com/JakeWharton/Android-ViewPagerIndicator) 57 | * [The Crosswalk Project](https://crosswalk-project.org/) 58 | 59 | ## Contributing 60 | 61 | Please fork this repository and contribute back using 62 | [pull requests](https://github.com/bakerframework/baker-android-refactor/pulls). 63 | 64 | Any kind of contribution, features, bug fixes, language translations, unit/integration tests, refactors are welcome and appreciated but will be thoroughly reviewed and discussed. 65 | 66 | Please make sure that: 67 | 68 | * Your pull request is based on the latest possible version of the Baker Android `master` branch 69 | * You have provided a meaningful title for your pull request 70 | * You have briefly explained in the pull request what it does and why it should be merged 71 | * You have referenced any relevant issue 72 | 73 | ## License 74 | 75 | This software is free to use under the BSD license. 76 | See the [LICENSE file][] for license text and copyright information. 77 | 78 | 79 | [LICENSE file]: https://github.com/bakerframework/baker-android-refactor/blob/master/LICENSE.md 80 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | repositories { 3 | mavenCentral() 4 | } 5 | dependencies { 6 | classpath 'com.android.tools.build:gradle:1.0.0' 7 | } 8 | } 9 | 10 | apply plugin: 'com.android.application' 11 | apply plugin: 'maven' 12 | 13 | version '1.0' 14 | group 'com.baker' 15 | 16 | android { 17 | compileSdkVersion 21 18 | buildToolsVersion "21.1.2" 19 | 20 | defaultConfig { 21 | applicationId project.property("application-id") 22 | minSdkVersion 14 23 | targetSdkVersion 21 24 | versionCode 10 25 | versionName "1.0" 26 | } 27 | 28 | buildTypes { 29 | debug { 30 | debuggable true 31 | } 32 | release { 33 | minifyEnabled false 34 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 35 | } 36 | } 37 | 38 | dexOptions { 39 | incremental true 40 | javaMaxHeapSize "4g" 41 | preDexLibraries = false 42 | } 43 | } 44 | 45 | // Release signing for debugging 46 | if(project.hasProperty("extra-gradle") && new File(project.property("extra-gradle")).exists()) { 47 | apply from: project.property("extra-gradle"); 48 | } 49 | 50 | repositories { 51 | maven { url "http://dl.bintray.com/populov/maven" } 52 | maven { url "https://download.01.org/crosswalk/releases/crosswalk/android/maven2" } 53 | mavenCentral() 54 | maven { 55 | url 'file://' + new File(System.getProperty('user.home'), '.m2/repository').absolutePath 56 | } 57 | } 58 | 59 | dependencies { 60 | compile 'com.google.android.gms:play-services:6.5.+' 61 | compile 'org.jsoup:jsoup:1.7.3' 62 | compile 'org.apache.commons:commons-compress:1.8.1' 63 | compile 'com.viewpagerindicator:library:2.4.1@aar' 64 | compile 'com.android.support:appcompat-v7:21.+' 65 | compile 'org.solovyev.android:checkout:0.6.2@aar' 66 | compile 'com.google.code.gson:gson:2.3.1' 67 | compile 'com.nostra13.universalimageloader:universal-image-loader:1.9.3' 68 | compile 'com.path:android-priority-jobqueue:1.1.2' 69 | compile 'de.greenrobot:eventbus:2.4.0' 70 | compile 'org.zeroturnaround:zt-zip:1.8' 71 | compile 'com.parse.bolts:bolts-android:1.+' 72 | compile 'org.xwalk:xwalk_core_library:11.40.277.7' 73 | compile fileTree(dir: 'libs', include: 'Parse-*.jar') 74 | } 75 | -------------------------------------------------------------------------------- /app/libs/Parse-1.8.2.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bakerframework/baker-android-refactor/e073b075ef8b0c8761db89f5e21e4e7943bc7164/app/libs/Parse-1.8.2.jar -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | -keepclassmembers class com.bakerframework.baker.view.VideoEnabledWebView$JavascriptInterface { public *; } 2 | -------------------------------------------------------------------------------- /app/src/main/aidl/com/android/vending/licensing/ILicenseResultListener.aidl: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.android.vending.licensing; 18 | 19 | // Android library projects do not yet support AIDL, so this has been 20 | // precompiled into the src directory. 21 | oneway interface ILicenseResultListener { 22 | void verifyLicense(int responseCode, String signedData, String signature); 23 | } 24 | -------------------------------------------------------------------------------- /app/src/main/aidl/com/android/vending/licensing/ILicensingService.aidl: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.android.vending.licensing; 18 | 19 | import com.android.vending.licensing.ILicenseResultListener; 20 | 21 | // Android library projects do not yet support AIDL, so this has been 22 | // precompiled into the src directory. 23 | oneway interface ILicensingService { 24 | void checkLicense(long nonce, String packageName, in ILicenseResultListener listener); 25 | } 26 | -------------------------------------------------------------------------------- /app/src/main/assets/abaker_usage/archive.html: -------------------------------------------------------------------------------- 1 | 2 |
3 | 4 | 5 | 6 | 7 | 8 |13 | Archive issues after you have finished with them! 14 |
15 |13 | Tap the "Download" button or the issue cover to get the content! 14 |
15 |13 | Tap the "Read" button to start viewing the issue! 14 |
15 |22 | * The LICENSED response from the server contains a user identifier unique to 23 | * the <application, user> pair. The developer can send this identifier 24 | * to their own server along with some device identifier (a random number 25 | * generated and stored once per application installation, 26 | * {@link android.telephony.TelephonyManager#getDeviceId getDeviceId}, 27 | * {@link android.provider.Settings.Secure#ANDROID_ID ANDROID_ID}, etc). 28 | * The more sources used to identify the device, the harder it will be for an 29 | * attacker to spoof. 30 | *
31 | * The server can look at the <application, user, device id> tuple and 32 | * restrict a user's application license to run on at most 10 different devices 33 | * in a week (for example). We recommend not being too restrictive because a 34 | * user might legitimately have multiple devices or be in the process of 35 | * changing phones. This will catch egregious violations of multiple people 36 | * sharing one license. 37 | */ 38 | public interface DeviceLimiter { 39 | 40 | /** 41 | * Checks if this device is allowed to use the given user's license. 42 | * 43 | * @param userId the user whose license the server responded with 44 | * @return LICENSED if the device is allowed, NOT_LICENSED if not, RETRY if an error occurs 45 | */ 46 | int isDeviceAllowed(String userId); 47 | } 48 | -------------------------------------------------------------------------------- /app/src/main/java/com/google/android/vending/licensing/ILicenseResultListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is auto-generated. DO NOT MODIFY. 3 | * Original file: aidl/ILicenseResultListener.aidl 4 | */ 5 | package com.google.android.vending.licensing; 6 | import java.lang.String; 7 | import android.os.RemoteException; 8 | import android.os.IBinder; 9 | import android.os.IInterface; 10 | import android.os.Binder; 11 | import android.os.Parcel; 12 | public interface ILicenseResultListener extends IInterface 13 | { 14 | /** Local-side IPC implementation stub class. */ 15 | public static abstract class Stub extends Binder implements ILicenseResultListener 16 | { 17 | private static final String DESCRIPTOR = "com.android.vending.licensing.ILicenseResultListener"; 18 | /** Construct the stub at attach it to the interface. */ 19 | public Stub() 20 | { 21 | this.attachInterface(this, DESCRIPTOR); 22 | } 23 | /** 24 | * Cast an IBinder object into an ILicenseResultListener interface, 25 | * generating a proxy if needed. 26 | */ 27 | public static ILicenseResultListener asInterface(IBinder obj) 28 | { 29 | if ((obj==null)) { 30 | return null; 31 | } 32 | IInterface iin = (IInterface)obj.queryLocalInterface(DESCRIPTOR); 33 | if (((iin!=null)&&(iin instanceof ILicenseResultListener))) { 34 | return ((ILicenseResultListener)iin); 35 | } 36 | return new Proxy(obj); 37 | } 38 | public IBinder asBinder() 39 | { 40 | return this; 41 | } 42 | public boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws RemoteException 43 | { 44 | switch (code) 45 | { 46 | case INTERFACE_TRANSACTION: 47 | { 48 | reply.writeString(DESCRIPTOR); 49 | return true; 50 | } 51 | case TRANSACTION_verifyLicense: 52 | { 53 | data.enforceInterface(DESCRIPTOR); 54 | int _arg0; 55 | _arg0 = data.readInt(); 56 | String _arg1; 57 | _arg1 = data.readString(); 58 | String _arg2; 59 | _arg2 = data.readString(); 60 | this.verifyLicense(_arg0, _arg1, _arg2); 61 | return true; 62 | } 63 | } 64 | return super.onTransact(code, data, reply, flags); 65 | } 66 | private static class Proxy implements ILicenseResultListener 67 | { 68 | private final IBinder mRemote; 69 | Proxy(IBinder remote) 70 | { 71 | mRemote = remote; 72 | } 73 | public IBinder asBinder() 74 | { 75 | return mRemote; 76 | } 77 | public String getInterfaceDescriptor() 78 | { 79 | return DESCRIPTOR; 80 | } 81 | public void verifyLicense(int responseCode, String signedData, String signature) throws RemoteException 82 | { 83 | Parcel _data = Parcel.obtain(); 84 | try { 85 | _data.writeInterfaceToken(DESCRIPTOR); 86 | _data.writeInt(responseCode); 87 | _data.writeString(signedData); 88 | _data.writeString(signature); 89 | mRemote.transact(Stub.TRANSACTION_verifyLicense, _data, null, IBinder.FLAG_ONEWAY); 90 | } 91 | finally { 92 | _data.recycle(); 93 | } 94 | } 95 | } 96 | static final int TRANSACTION_verifyLicense = (IBinder.FIRST_CALL_TRANSACTION + 0); 97 | } 98 | public void verifyLicense(int responseCode, String signedData, String signature) throws RemoteException; 99 | } 100 | -------------------------------------------------------------------------------- /app/src/main/java/com/google/android/vending/licensing/ILicensingService.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is auto-generated. DO NOT MODIFY. 3 | * Original file: aidl/ILicensingService.aidl 4 | */ 5 | package com.google.android.vending.licensing; 6 | import java.lang.String; 7 | import android.os.RemoteException; 8 | import android.os.IBinder; 9 | import android.os.IInterface; 10 | import android.os.Binder; 11 | import android.os.Parcel; 12 | public interface ILicensingService extends IInterface 13 | { 14 | /** Local-side IPC implementation stub class. */ 15 | public static abstract class Stub extends Binder implements ILicensingService 16 | { 17 | private static final String DESCRIPTOR = "com.android.vending.licensing.ILicensingService"; 18 | /** Construct the stub at attach it to the interface. */ 19 | public Stub() 20 | { 21 | this.attachInterface(this, DESCRIPTOR); 22 | } 23 | /** 24 | * Cast an IBinder object into an ILicensingService interface, 25 | * generating a proxy if needed. 26 | */ 27 | public static ILicensingService asInterface(IBinder obj) 28 | { 29 | if ((obj==null)) { 30 | return null; 31 | } 32 | IInterface iin = (IInterface)obj.queryLocalInterface(DESCRIPTOR); 33 | if (((iin!=null)&&(iin instanceof ILicensingService))) { 34 | return ((ILicensingService)iin); 35 | } 36 | return new Proxy(obj); 37 | } 38 | public IBinder asBinder() 39 | { 40 | return this; 41 | } 42 | public boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws RemoteException 43 | { 44 | switch (code) 45 | { 46 | case INTERFACE_TRANSACTION: 47 | { 48 | reply.writeString(DESCRIPTOR); 49 | return true; 50 | } 51 | case TRANSACTION_checkLicense: 52 | { 53 | data.enforceInterface(DESCRIPTOR); 54 | long _arg0; 55 | _arg0 = data.readLong(); 56 | String _arg1; 57 | _arg1 = data.readString(); 58 | com.google.android.vending.licensing.ILicenseResultListener _arg2; 59 | _arg2 = com.google.android.vending.licensing.ILicenseResultListener.Stub.asInterface(data.readStrongBinder()); 60 | this.checkLicense(_arg0, _arg1, _arg2); 61 | return true; 62 | } 63 | } 64 | return super.onTransact(code, data, reply, flags); 65 | } 66 | private static class Proxy implements ILicensingService 67 | { 68 | private final IBinder mRemote; 69 | Proxy(IBinder remote) 70 | { 71 | mRemote = remote; 72 | } 73 | public IBinder asBinder() 74 | { 75 | return mRemote; 76 | } 77 | public String getInterfaceDescriptor() 78 | { 79 | return DESCRIPTOR; 80 | } 81 | public void checkLicense(long nonce, String packageName, com.google.android.vending.licensing.ILicenseResultListener listener) throws RemoteException 82 | { 83 | Parcel _data = Parcel.obtain(); 84 | try { 85 | _data.writeInterfaceToken(DESCRIPTOR); 86 | _data.writeLong(nonce); 87 | _data.writeString(packageName); 88 | _data.writeStrongBinder((((listener!=null))?(listener.asBinder()):(null))); 89 | mRemote.transact(Stub.TRANSACTION_checkLicense, _data, null, IBinder.FLAG_ONEWAY); 90 | } 91 | finally { 92 | _data.recycle(); 93 | } 94 | } 95 | } 96 | static final int TRANSACTION_checkLicense = (IBinder.FIRST_CALL_TRANSACTION + 0); 97 | } 98 | public void checkLicense(long nonce, String packageName, com.google.android.vending.licensing.ILicenseResultListener listener) throws RemoteException; 99 | } 100 | -------------------------------------------------------------------------------- /app/src/main/java/com/google/android/vending/licensing/LicenseCheckerCallback.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.google.android.vending.licensing; 18 | 19 | /** 20 | * Callback for the license checker library. 21 | *
22 | * Upon checking with the Market server and conferring with the {@link com.google.android.vending.licensing.Policy}, 23 | * the library calls the appropriate callback method to communicate the result. 24 | *
25 | * The callback does not occur in the original checking thread. Your 26 | * application should post to the appropriate handling thread or lock 27 | * accordingly. 28 | *
29 | * The reason that is passed back with allow/dontAllow is the base status handed 30 | * to the policy for allowed/disallowing the license. Policy.RETRY will call 31 | * allow or dontAllow depending on other statistics associated with the policy, 32 | * while in most cases Policy.NOT_LICENSED will call dontAllow and 33 | * Policy.LICENSED will Allow. 34 | */ 35 | public interface LicenseCheckerCallback { 36 | 37 | /** 38 | * Allow use. App should proceed as normal. 39 | * 40 | * @param reason Policy.LICENSED or Policy.RETRY typically. (although in 41 | * theory the policy can return Policy.NOT_LICENSED here as well) 42 | */ 43 | public void allow(int reason); 44 | 45 | /** 46 | * Don't allow use. App should inform user and take appropriate action. 47 | * 48 | * @param reason Policy.NOT_LICENSED or Policy.RETRY. (although in theory 49 | * the policy can return Policy.LICENSED here as well --- 50 | * perhaps the call to the LVL took too long, for example) 51 | */ 52 | public void dontAllow(int reason); 53 | 54 | /** Application error codes. */ 55 | public static final int ERROR_INVALID_PACKAGE_NAME = 1; 56 | public static final int ERROR_NON_MATCHING_UID = 2; 57 | public static final int ERROR_NOT_MARKET_MANAGED = 3; 58 | public static final int ERROR_CHECK_IN_PROGRESS = 4; 59 | public static final int ERROR_INVALID_PUBLIC_KEY = 5; 60 | public static final int ERROR_MISSING_PERMISSION = 6; 61 | 62 | /** 63 | * Error in application code. Caller did not call or set up license checker 64 | * correctly. Should be considered fatal. 65 | */ 66 | public void applicationError(int errorCode); 67 | } 68 | -------------------------------------------------------------------------------- /app/src/main/java/com/google/android/vending/licensing/NullDeviceLimiter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.google.android.vending.licensing; 18 | 19 | /** 20 | * A DeviceLimiter that doesn't limit the number of devices that can use a 21 | * given user's license. 22 | *
23 | * Unless you have reason to believe that your application is being pirated 24 | * by multiple users using the same license (signing in to Market as the same 25 | * user), we recommend you use this implementation. 26 | */ 27 | public class NullDeviceLimiter implements DeviceLimiter { 28 | 29 | public int isDeviceAllowed(String userId) { 30 | return Policy.LICENSED; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /app/src/main/java/com/google/android/vending/licensing/Obfuscator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.google.android.vending.licensing; 18 | 19 | /** 20 | * Interface used as part of a {@link com.google.android.vending.licensing.Policy} to allow application authors to obfuscate 21 | * licensing data that will be stored into a SharedPreferences file. 22 | *
23 | * Any transformation scheme must be reversable. Implementing classes may optionally implement an 24 | * integrity check to further prevent modification to preference data. Implementing classes 25 | * should use device-specific information as a key in the obfuscation algorithm to prevent 26 | * obfuscated preferences from being shared among devices. 27 | */ 28 | public interface Obfuscator { 29 | 30 | /** 31 | * Obfuscate a string that is being stored into shared preferences. 32 | * 33 | * @param original The data that is to be obfuscated. 34 | * @param key The key for the data that is to be obfuscated. 35 | * @return A transformed version of the original data. 36 | */ 37 | String obfuscate(String original, String key); 38 | 39 | /** 40 | * Undo the transformation applied to data by the obfuscate() method. 41 | * 42 | * @param original The data that is to be obfuscated. 43 | * @param key The key for the data that is to be obfuscated. 44 | * @return A transformed version of the original data. 45 | * @throws ValidationException Optionally thrown if a data integrity check fails. 46 | */ 47 | String unobfuscate(String obfuscated, String key) throws ValidationException; 48 | } 49 | -------------------------------------------------------------------------------- /app/src/main/java/com/google/android/vending/licensing/Policy.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.google.android.vending.licensing; 18 | 19 | /** 20 | * Policy used by {@link LicenseChecker} to determine whether a user should have 21 | * access to the application. 22 | */ 23 | public interface Policy { 24 | 25 | /** 26 | * Change these values to make it more difficult for tools to automatically 27 | * strip LVL protection from your APK. 28 | */ 29 | 30 | /** 31 | * LICENSED means that the server returned back a valid license response 32 | */ 33 | public static final int LICENSED = 0x0100; 34 | /** 35 | * NOT_LICENSED means that the server returned back a valid license response 36 | * that indicated that the user definitively is not licensed 37 | */ 38 | public static final int NOT_LICENSED = 0x0231; 39 | /** 40 | * RETRY means that the license response was unable to be determined --- 41 | * perhaps as a result of faulty networking 42 | */ 43 | public static final int RETRY = 0x0123; 44 | 45 | /** 46 | * Provide results from contact with the license server. Retry counts are 47 | * incremented if the current value of response is RETRY. Results will be 48 | * used for any future policy decisions. 49 | * 50 | * @param response the result from validating the server response 51 | * @param rawData the raw server response data, can be null for RETRY 52 | */ 53 | void processServerResponse(int response, ResponseData rawData); 54 | 55 | /** 56 | * Check if the user should be allowed access to the application. 57 | */ 58 | boolean allowAccess(); 59 | } 60 | -------------------------------------------------------------------------------- /app/src/main/java/com/google/android/vending/licensing/PreferenceObfuscator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.google.android.vending.licensing; 18 | 19 | import android.content.SharedPreferences; 20 | import android.util.Log; 21 | 22 | /** 23 | * An wrapper for SharedPreferences that transparently performs data obfuscation. 24 | */ 25 | public class PreferenceObfuscator { 26 | 27 | private static final String TAG = "PreferenceObfuscator"; 28 | 29 | private final SharedPreferences mPreferences; 30 | private final Obfuscator mObfuscator; 31 | private SharedPreferences.Editor mEditor; 32 | 33 | /** 34 | * Constructor. 35 | * 36 | * @param sp A SharedPreferences instance provided by the system. 37 | * @param o The Obfuscator to use when reading or writing data. 38 | */ 39 | public PreferenceObfuscator(SharedPreferences sp, Obfuscator o) { 40 | mPreferences = sp; 41 | mObfuscator = o; 42 | mEditor = null; 43 | } 44 | 45 | public void putString(String key, String value) { 46 | if (mEditor == null) { 47 | mEditor = mPreferences.edit(); 48 | } 49 | String obfuscatedValue = mObfuscator.obfuscate(value, key); 50 | mEditor.putString(key, obfuscatedValue); 51 | } 52 | 53 | public String getString(String key, String defValue) { 54 | String result; 55 | String value = mPreferences.getString(key, null); 56 | if (value != null) { 57 | try { 58 | result = mObfuscator.unobfuscate(value, key); 59 | } catch (ValidationException e) { 60 | // Unable to unobfuscate, data corrupt or tampered 61 | Log.w(TAG, "Validation error while reading preference: " + key); 62 | result = defValue; 63 | } 64 | } else { 65 | // Preference not found 66 | result = defValue; 67 | } 68 | return result; 69 | } 70 | 71 | public void commit() { 72 | if (mEditor != null) { 73 | mEditor.commit(); 74 | mEditor = null; 75 | } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /app/src/main/java/com/google/android/vending/licensing/ResponseData.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.google.android.vending.licensing; 18 | 19 | import java.util.regex.Pattern; 20 | 21 | import android.text.TextUtils; 22 | 23 | /** 24 | * ResponseData from licensing server. 25 | */ 26 | public class ResponseData { 27 | 28 | public int responseCode; 29 | public int nonce; 30 | public String packageName; 31 | public String versionCode; 32 | public String userId; 33 | public long timestamp; 34 | /** Response-specific data. */ 35 | public String extra; 36 | 37 | /** 38 | * Parses response string into ResponseData. 39 | * 40 | * @param responseData response data string 41 | * @throws IllegalArgumentException upon parsing error 42 | * @return ResponseData object 43 | */ 44 | public static ResponseData parse(String responseData) { 45 | // Must parse out main response data and response-specific data. 46 | int index = responseData.indexOf(':'); 47 | String mainData, extraData; 48 | if ( -1 == index ) { 49 | mainData = responseData; 50 | extraData = ""; 51 | } else { 52 | mainData = responseData.substring(0, index); 53 | extraData = index >= responseData.length() ? "" : responseData.substring(index+1); 54 | } 55 | 56 | String [] fields = TextUtils.split(mainData, Pattern.quote("|")); 57 | if (fields.length < 6) { 58 | throw new IllegalArgumentException("Wrong number of fields."); 59 | } 60 | 61 | ResponseData data = new ResponseData(); 62 | data.extra = extraData; 63 | data.responseCode = Integer.parseInt(fields[0]); 64 | data.nonce = Integer.parseInt(fields[1]); 65 | data.packageName = fields[2]; 66 | data.versionCode = fields[3]; 67 | // Application-specific user identifier. 68 | data.userId = fields[4]; 69 | data.timestamp = Long.parseLong(fields[5]); 70 | 71 | return data; 72 | } 73 | 74 | @Override 75 | public String toString() { 76 | return TextUtils.join("|", new Object [] { responseCode, nonce, packageName, versionCode, 77 | userId, timestamp }); 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /app/src/main/java/com/google/android/vending/licensing/StrictPolicy.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.google.android.vending.licensing; 18 | 19 | /** 20 | * Non-caching policy. All requests will be sent to the licensing service, 21 | * and no local caching is performed. 22 | *
23 | * Using a non-caching policy ensures that there is no local preference data 24 | * for malicious users to tamper with. As a side effect, applications 25 | * will not be permitted to run while offline. Developers should carefully 26 | * weigh the risks of using this Policy over one which implements caching, 27 | * such as ServerManagedPolicy. 28 | *
29 | * Access to the application is only allowed if a LICESNED response is.
30 | * received. All other responses (including RETRY) will deny access.
31 | */
32 | public class StrictPolicy implements Policy {
33 |
34 | private int mLastResponse;
35 |
36 | public StrictPolicy() {
37 | // Set default policy. This will force the application to check the policy on launch.
38 | mLastResponse = Policy.RETRY;
39 | }
40 |
41 | /**
42 | * Process a new response from the license server. Since we aren't
43 | * performing any caching, this equates to reading the LicenseResponse.
44 | * Any ResponseData provided is ignored.
45 | *
46 | * @param response the result from validating the server response
47 | * @param rawData the raw server response data
48 | */
49 | public void processServerResponse(int response, ResponseData rawData) {
50 | mLastResponse = response;
51 | }
52 |
53 | /**
54 | * {@inheritDoc}
55 | *
56 | * This implementation allows access if and only if a LICENSED response
57 | * was received the last time the server was contacted.
58 | */
59 | public boolean allowAccess() {
60 | return (mLastResponse == Policy.LICENSED);
61 | }
62 |
63 | }
64 |
--------------------------------------------------------------------------------
/app/src/main/java/com/google/android/vending/licensing/ValidationException.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2010 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.google.android.vending.licensing;
18 |
19 | /**
20 | * Indicates that an error occurred while validating the integrity of data managed by an
21 | * {@link com.google.android.vending.licensing.Obfuscator}.}
22 | */
23 | public class ValidationException extends Exception {
24 | public ValidationException() {
25 | super();
26 | }
27 |
28 | public ValidationException(String s) {
29 | super(s);
30 | }
31 |
32 | private static final long serialVersionUID = 1L;
33 | }
34 |
--------------------------------------------------------------------------------
/app/src/main/java/com/google/android/vending/licensing/util/Base64DecoderException.java:
--------------------------------------------------------------------------------
1 | // Copyright 2002, Google, Inc.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package com.google.android.vending.licensing.util;
16 |
17 | /**
18 | * Exception thrown when encountering an invalid Base64 input character.
19 | *
20 | * @author nelson
21 | */
22 | public class Base64DecoderException extends Exception {
23 | public Base64DecoderException() {
24 | super();
25 | }
26 |
27 | public Base64DecoderException(String s) {
28 | super(s);
29 | }
30 |
31 | private static final long serialVersionUID = 1L;
32 | }
33 |
--------------------------------------------------------------------------------
/app/src/main/res/anim/bounce.xml:
--------------------------------------------------------------------------------
1 |
2 |