caarmen / FRCAndroidWidget

French Revolutionary Calendar Android Widget
GNU General Public License v3.0
11 stars 2 forks source link

API Compatibility Issues #32

Closed lilicoding closed 7 years ago

lilicoding commented 7 years ago

Dear developers,

We have recently developed a state-of-the-art static analysis tool for uncovering API compatibility issues in Android apps. Applying this tool to open source apps on F-droid, we have exposed a few instances of compatibility issues and submitting them to development teams for a fix.

For your app, we have found that this project has accessed the following APIs which are available only on an API level higher than the declared minSdkVersion and which are accessed without proper protection. In other words, if those APIs get called at runtime, it will trigger a NoSuchMethodError and thus result in a crash of the running application.

<android.app.Notification.Builder: android.app.Notification.Builder addAction(android.app.Notification.Action)>:[21,25]
<android.widget.TextView: float getShadowDx()>:[16,25]
<android.view.Display: void getSize(android.graphics.Point)>:[13,25]
<android.app.Notification.Builder: void <init>(android.content.Context)>:[11,25]
<android.widget.TextView: float getShadowRadius()>:[16,25]
<android.app.Notification.Builder: android.app.Notification.Builder addAction(int,java.lang.CharSequence,android.app.PendingIntent)>:[16,25]
<android.graphics.drawable.Icon: android.graphics.drawable.Icon createWithResource(android.content.Context,int)>:[23,25]
<android.app.Notification.BigTextStyle: void <init>()>:[16,25]
<android.app.Notification.Builder: android.app.Notification.Builder setAutoCancel(boolean)>:[11,25]
<android.app.Notification.Builder: android.app.Notification.Builder setSmallIcon(int)>:[11,25]
<android.app.Notification.Action.Builder: void <init>(android.graphics.drawable.Icon,java.lang.CharSequence,android.app.PendingIntent)>:[23,25]
<android.app.Notification.Builder: android.app.Notification.Builder setContentTitle(java.lang.CharSequence)>:[11,25]
<android.app.Notification.Builder: android.app.Notification.Builder setContentText(java.lang.CharSequence)>:[11,25]
<android.widget.TextView: int getShadowColor()>:[16,25]
<android.app.Notification.Builder: android.app.Notification getNotification()>:[11,25]
<android.app.Activity: android.app.ActionBar getActionBar()>:[11,25]
<android.app.Notification.Builder: android.app.Notification.Builder setStyle(android.app.Notification.Style)>:[16,25]
<android.content.Intent: android.content.Intent setPackage(java.lang.String)>:[4,25]
<android.app.Notification.Builder: android.app.Notification build()>:[16,25]
<android.app.Notification.BigTextStyle: android.app.Notification.BigTextStyle bigText(java.lang.CharSequence)>:[16,25]
<android.app.Notification.Builder: android.app.Notification.Builder setContentIntent(android.app.PendingIntent)>:[11,25]
<android.app.Notification.Builder: android.app.Notification.Builder setLocalOnly(boolean)>:[21,25]
<android.app.ActionBar: void setDisplayHomeAsUpEnabled(boolean)>:[11,25]
<android.app.Notification.Action.Builder: android.app.Notification.Action build()>:[21,25]
<android.app.AlarmManager: void setExact(int,long,android.app.PendingIntent)>:[19,25]
<android.widget.TextView: float getShadowDy()>:[16,25]
<android.appwidget.AppWidgetManager: android.os.Bundle getAppWidgetOptions(int)>:[16,25]

Note that, because of the nature of the static analysis, we cannot confirm whether the flagged APIs would actually be called at runtime (e.g., unreachable code). However, we still believe that those APIs, which may cause compatibility issues, should not be accessed or at least be accessed with proper protections.

In addition to the aforementioned APIs (i.e., backward-compatibility), which could cause app crashes if accessed, we have also identified that this project has also accessed some APIs that have been removed from the latest public SDK, making the app possibly suffer from forward-compatibility issues.

NONE

We would be very much appreciated if you can acknowledge to us that those reported APIs are indeed problematic for the project’s long-term stability. please let us know if you need any more information relating to this issue report.

caarmen commented 7 years ago

It would be nice if:

Thanks :)

caarmen commented 7 years ago

I went through all these issues manually, and found only one that is a real problem: setLocalOnly(). For info, Android Studio also only found this one issue. Could you take a look at your static analysis tool and see why it finds so many false positives?

newmethods

Here are the results of my analysis:


<android.app.Notification.Builder: android.app.Notification.Builder setLocalOnly(boolean)>:[21,25] This is one needs a fix, as it is called on api levels 11+ instead of 20+. Note: This api is available on level 20, and your tool says it's only available on level 21+.


<android.app.Notification.Action.Builder: android.app.Notification.Action build()>:[21,25] <android.app.Notification.Action.Builder: void (android.graphics.drawable.Icon,java.lang.CharSequence,android.app.PendingIntent)>:[23,25] <android.app.Notification.BigTextStyle: android.app.Notification.BigTextStyle bigText(java.lang.CharSequence)>:[16,25] <android.app.Notification.BigTextStyle: void ()>:[16,25] <android.app.Notification.Builder: android.app.Notification build()>:[16,25] <android.app.Notification.Builder: android.app.Notification getNotification()>:[11,25] <android.app.Notification.Builder: android.app.Notification.Builder addAction(android.app.Notification.Action)>:[21,25] <android.app.Notification.Builder: android.app.Notification.Builder addAction(int,java.lang.CharSequence,android.app.PendingIntent)>:[16,25] <android.app.Notification.Builder: android.app.Notification.Builder setAutoCancel(boolean)>:[11,25] <android.app.Notification.Builder: android.app.Notification.Builder setContentIntent(android.app.PendingIntent)>:[11,25] <android.app.Notification.Builder: android.app.Notification.Builder setContentText(java.lang.CharSequence)>:[11,25] <android.app.Notification.Builder: android.app.Notification.Builder setContentTitle(java.lang.CharSequence)>:[11,25] <android.app.Notification.Builder: android.app.Notification.Builder setSmallIcon(int)>:[11,25] <android.app.Notification.Builder: android.app.Notification.Builder setStyle(android.app.Notification.Style)>:[16,25] <android.app.Notification.Builder: void (android.content.Context)>:[11,25] <android.graphics.drawable.Icon: android.graphics.drawable.Icon createWithResource(android.content.Context,int)>:[23,25]

The NotificationCompat class ensures that only the correct apis are used to build a notification on the given android version.


<android.app.Activity: android.app.ActionBar getActionBar()>:[11,25] <android.app.ActionBar: void setDisplayHomeAsUpEnabled(boolean)>:[11,25] These are only called, from Api11Helper.java, if the api level is 11+.


<android.view.Display: void getSize(android.graphics.Point)>:[13,25] This is only called, from FRCRender.getScaleFactor(), if the api level is 13+


<android.app.AlarmManager: void setExact(int,long,android.app.PendingIntent)>:[19,25] This is only called from FRWWidgetScheduler, if the api level is 19+


<android.appwidget.AppWidgetManager: android.os.Bundle getAppWidgetOptions(int)>:[16,25] This is only called from FRCRender.getScaleFactor(), if the api level is 16+.


<android.content.Intent: android.content.Intent setPackage(java.lang.String)>:[4,25] This is only called from Api4Helper.java, if the Android Wear setting is enabled. This setting is enabled only on api level 18+, in FRCPreferenceActivity, and it is disabled on all versions of android for f-droid (foss):

boolean canUseWear = !BuildConfig.FOSS && Integer.valueOf(Build.VERSION.SDK) >= Build.VERSION_CODES.JELLY_BEAN_MR2;
// Don't show Android Wear stuff for old devices that don't support it
if (!canUseWear) {
    //noinspection deprecation
    PreferenceCategory category = (PreferenceCategory) getPreferenceScreen().findPreference(FRCPreferences.PREF_CATEGORY_OTHER);
    Preference wearPreference = category.findPreference(FRCPreferences.PREF_ANDROID_WEAR);
    category.removePreference(wearPreference);

<android.widget.TextView: float getShadowDx()>:[16,25] <android.widget.TextView: float getShadowDy()>:[16,25] <android.widget.TextView: float getShadowRadius()>:[16,25] <android.widget.TextView: int getShadowColor()>:[16,25]

These are only called from FRCRender.scaleViews() if the api level is 16+

caarmen commented 7 years ago

I created a new issue just for the one compatibility problem: https://github.com/caarmen/FRCAndroidWidget/issues/33

Will close this one now.

lilicoding commented 7 years ago

Dear Caarmen,

Thank you very much for your detailed feedback, which again is very useful for us.

Our research tool faces the same problem as I have replied to you before, where we have considered only SDK_INT field.

Besides, the reason why we have flagged setLocalOnly(boolean) as from 21+ is that there is no release in level 20 for smartphones. Because level 20 is only made for wearable devices. Anyway, thank you for letting us know on this. we will take this into account in our future release of our research tool.

lilicoding commented 7 years ago

Dear Caarmen,

After switching to Android Studio, you are able to find the compatibility issue because of the warnings given by Android Studio. I am wondering that what IDE are you using for developing this project before? In general, any possible reasons that cause those problematic APIs remained in the project would be very much helpful for us.

caarmen commented 7 years ago

Hello, Actually I was already using Android Studio when I introduced that compatibility issue. I guess I just didn't notice it before :) It was underlined in red, and when I ran the code inspection tool, it came up. I just needed to pay more attention it seems.