Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make R8 + proguard-android-optimize.txt + Google Drive API works seamlessly?

This is our R8 version

Current version is: 1.4.94 (build 390954928f0db9c3b888a367f7f128ce3bbfb160 from go/r8bot (luci-r8-ci-archive-0-5g74)).

When I switch from

buildTypes {
    release {
        minifyEnabled true
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
    }
}

to

buildTypes {
    release {
        minifyEnabled true
        proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
    }
}

We're getting the following error.

com.google.api.client.googleapis.json.GoogleJsonResponseException: 403 Forbidden
    {
      "code": 403,
      "errors": [
        {
          "domain": "usageLimits",
          "message": "Daily Limit for Unauthenticated Use Exceeded. Continued use requires signup.",
          "reason": "dailyLimitExceededUnreg",
          "extendedHelp": "https://code.google.com/apis/console"
        }
      ],
      "message": "Daily Limit for Unauthenticated Use Exceeded. Continued use requires signup."
    }
        at com.google.api.client.googleapis.services.json.AbstractGoogleJsonClientRequest.newExceptionOnError(AbstractGoogleJsonClientRequest.java:113)
        at com.google.api.client.googleapis.services.json.AbstractGoogleJsonClientRequest.newExceptionOnError(AbstractGoogleJsonClientRequest.java:40)
        at com.google.api.client.googleapis.services.AbstractGoogleClientRequest$1.interceptResponse(AbstractGoogleClientRequest.java:378)
        at com.google.api.client.http.HttpRequest.a(HttpRequest.java:1067)
        at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:476)
        at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:409)
        at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.execute(AbstractGoogleClientRequest.java:526)
        at com.yocto.wenote.sync.Utils.searchFromGoogleDrive(Utils.java:808)

The crash happens at the following code

try {
    Drive.Files.List request = drive.files().list().setSpaces(APP_DATA_FOLDER)
            .setQ("name = '" + Utils.getWeNoteZipFileTitle() + "'")
            .setFields("nextPageToken, files(id, name, modifiedTime)")
            .setOrderBy("modifiedTime desc")
            .setPageSize(10);

    do {
        FileList fileList = request.execute();  // <-- This is line Utils.java:808

Take note that, the above code works 100% fine, before we're switching from proguard-android.txt to proguard-android-optimize.txt.

It seems that based on proguard-android-optimize.txt, R8 stripes out some important information, which causes calling to Google Drive API fails.

Anyone how to make proguard-android-optimize.txt work with Google Drive API?


How about replace R8 with Proguard?

If I use ProGuard, version 6.0.3 by applying android.enableR8=false (Still using proguard-android-optimize.txt), there are no issue when running Google Drive API related code.


My Google Drive API libs

// For Google Drive REST API - https://github.com/gsuitedevs/android-samples/blob/master/drive/deprecation/app/build.gradle
implementation('com.google.http-client:google-http-client-gson:1.26.0') {
    exclude group: 'org.apache.httpcomponents'
}
implementation('com.google.api-client:google-api-client-android:1.26.0') {
    exclude group: 'org.apache.httpcomponents'
}
implementation('com.google.apis:google-api-services-drive:v3-rev136-1.25.0') {
    exclude group: 'org.apache.httpcomponents'
}

My complete proguard file

-keep class * implements android.os.Parcelable {
*;
}



# https://github.com/huanghaibin-dev/CalendarView
-keep class com.yocto.wenote.calendar.CustomWeekView {
    public <init>(android.content.Context);
}
-keep class com.yocto.wenote.calendar.CustomMonthView {
    public <init>(android.content.Context);
}
-keep class com.yocto.wenote.calendar.CustomWeekBar {
    public <init>(android.content.Context);
}
-keep class com.yocto.wenote.calendar.FullscreenCustomWeekBar {
    public <init>(android.content.Context);
}
-keep class com.haibin.calendarview.DefaultWeekView {
    public <init>(android.content.Context);
}
-keep class com.haibin.calendarview.DefaultYearView {
    public <init>(android.content.Context);
}

# http://stackoverflow.com/questions/3913338/how-to-debug-with-obfuscated-with-proguard-applications-on-android
# http://proguard.sourceforge.net/index.html#manual/examples.html (Producing useful obfuscated stack traces)
-renamesourcefileattribute SourceFile
-keepattributes SourceFile,LineNumberTable,InnerClasses



# https://github.com/bumptech/glide
-keep public class * implements com.bumptech.glide.module.GlideModule
-keep public class * extends com.bumptech.glide.module.AppGlideModule
-keep public enum com.bumptech.glide.load.ImageHeaderParser$** {
  **[] $VALUES;
  public *;
}



# Used in menu/search_toolbar_menu.xml
-keep class com.yocto.wenote.search.SearchView {
*;
}



# setHintTextTypeface & setFloatTextTypeface & setFloatTextColor
-keep class com.google.android.material.textfield.TextInputLayout {
*;
}
# setHintTextTypeface & setFloatTextTypeface
-keep class com.google.android.material.internal.CollapsingTextHelper {
*;
}
# setMaxHeight & setMinimumHeight
-keep class android.widget.ImageView {
  public <methods>;
}



-keep class com.yocto.wenote.recording.RippleBackground$RippleView {
  void setScaleX(***);
  void setScaleY(***);
}



# https://github.com/zhihu/Matisse
-dontwarn com.squareup.picasso.**
-dontwarn com.bumptech.glide.**



# For Google Drive API
-dontwarn com.google.common.**
-dontwarn com.google.api.client.util.**
-keep class * extends com.google.api.client.json.GenericJson {
*;
}
-keep class com.google.api.services.drive.** {
*;
}


# VerifyError in Android 4
# https://github.com/material-components/material-components-android/issues/397
-keep class com.google.android.material.tabs.TabLayout$Tab {
*;
}


# http://developer.android.com/google/play/billing/billing_best_practices.html#obfuscate
-keep class com.android.vending.billing.**



# https://r8.googlesource.com/r8/+/refs/heads/master/compatibility-faq.md
-keepclassmembers,allowobfuscation class * {
  @com.google.gson.annotations.SerializedName <fields>;
}



# https://stackoverflow.com/questions/13218772/removing-log-call-using-proguard
-assumenosideeffects class android.util.Log {
    public static boolean isLoggable(java.lang.String, int);
    public static int v(...);
    public static int i(...);
    public static int w(...);
    public static int d(...);
    public static int e(...);
}



# https://stackoverflow.com/questions/13218772/removing-log-call-using-proguard
-assumenosideeffects class com.yocto.wenote.Utils {
    public static void trackView(...);
    public static void trackEvent(...);
}
like image 729
Cheok Yan Cheng Avatar asked Jul 15 '19 12:07

Cheok Yan Cheng


People also ask

Is R8 better than proguard?

R8 gives better output results than Proguard. R8 reduces the app size by 10 % whereas Proguard reduces app size by 8.5 %. The android app having a Gradle plugin above 3.4. 0 or above then the project uses R8 by default with Proguard rules only.

Does R8 replace proguard?

Google released R8 as a replacement of Proguard to help developers shrink the code with the better-generated output (APK). They are considered much faster compared to Proguard.

What is the purpose of R8 in Android applications?

R8 is a tool that is used to shrink, secure, and optimize Android applications. It uses proguard rules to change the behavior of application. Developers tend to confuse R8 with proguard.

Does R8 use Proguard?

R8 configuration files. R8 uses ProGuard rules files to modify its default behavior and better understand your app's structure, such as the classes that serve as entry points into your app's code.


1 Answers

Could you try the following keep rule?

-keepclassmembers class * {
  @com.google.api.client.util.Key <fields>;
}

The google api client uses the com.google.api.client.util.Key by reflection: https://developers.google.com/api-client-library/java/google-http-java-client/setup

This seems to work for others who has reported a similar issue.

like image 90
MortenKJ Avatar answered Oct 18 '22 23:10

MortenKJ