Merge branch 'fix-installer-on-gingerbread' into 'master'

Removed `TargetApi` annotation from class, pushing it to methods, and fix API problems.

Fixes #708.

On gingerbread (in my case, 2.3.4) F-Droid will reliably crash whenever it views `AppDetails` with the following error:

```
                         E  java.lang.NoSuchMethodError: android.content.Context.getDrawable
                         E      at org.fdroid.fdroid.privileged.views.AppSecurityPermissions$MyPermissionGroupInfo.loadGroupIcon(AppSecurityPermissions.java:111)
                         E      at org.fdroid.fdroid.privileged.views.AppSecurityPermissions$PermissionItemView.setPermission(AppSecurityPermissions.java:158)
                         E      at org.fdroid.fdroid.privileged.views.AppSecurityPermissions.getPermissionItemView(AppSecurityPermissions.java:396)
                         E      at org.fdroid.fdroid.privileged.views.AppSecurityPermissions.displayPermissions(AppSecurityPermissions.java:370)
                         E      at org.fdroid.fdroid.privileged.views.AppSecurityPermissions.getPermissionsView(AppSecurityPermissions.java:348)
                         E      at org.fdroid.fdroid.AppDetails$AppDetailsSummaryFragment.buildPermissionInfo(AppDetails.java:1381)
                         E      at org.fdroid.fdroid.AppDetails$AppDetailsSummaryFragment.setupView(AppDetails.java:1348)
                         E      at org.fdroid.fdroid.AppDetails$AppDetailsSummaryFragment.onCreateView(AppDetails.java:1095)
                         E      at android.support.v4.app.Fragment.performCreateView(Fragment.java:2074)
                         E      at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1104)
                         E      at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1286)
                         E      at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:758)
                         E      at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1671)
                         E      at android.support.v4.app.Fragment.performStart(Fragment.java:2096)
                         E      at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1142)
                         E      at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1286)
                         E      at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1268)
                         E      at android.support.v4.app.FragmentManagerImpl.dispatchStart(FragmentManager.java:2148)
                         E      at android.support.v4.app.FragmentController.dispatchStart(FragmentController.java:212)
                         E      at android.support.v4.app.FragmentActivity.onStart(FragmentActivity.java:625)
                         E      at org.fdroid.fdroid.AppDetails.onStart(AppDetails.java:424)
                         E      at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1129)
                         E      at android.app.Activity.performStart(Activity.java:3791)
                         E      at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1620)
                         E      at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1663)
                         E      at android.app.ActivityThread.access$1500(ActivityThread.java:117)
                         E      at android.app.ActivityThread$H.handleMessage(ActivityThread.java:931)
                         E      at android.os.Handler.dispatchMessage(Handler.java:99)
                         E      at android.os.Looper.loop(Looper.java:130)
                         E      at android.app.ActivityThread.main(ActivityThread.java:3683)
                         E      at java.lang.reflect.Method.invokeNative(Native Method)
                         E      at java.lang.reflect.Method.invoke(Method.java:507)
                         E      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:864)
                         E      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:622)
                         E      at dalvik.system.NativeStart.main(Native Method)
```

This is because `AppSecurityPermissions` uses a method that was not added until a later API. This class is used by `AppDetails` without an API verison check around its access. Thus, we call methods on this that are unsupported when on gingerbread.

By removing `TargetApi` from the class, it unearthed a couple of locations where methods were being invoked without first guarding against the build version correctly. These two locations have been fixed and a `TargetApi` attached to the more narrowly defined method which requires it.

See merge request !353
This commit is contained in:
Daniel Martí 2016-07-17 22:28:39 +00:00
commit 30334c3714

View File

@ -29,6 +29,7 @@ import android.content.pm.PermissionInfo;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.os.Parcel;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AlertDialog;
import android.text.SpannableStringBuilder;
import android.text.TextUtils;
@ -70,7 +71,6 @@ import java.util.Set;
* - Open https://github.com/android/platform_frameworks_base/commits/master/core/java/android/widget/AppSecurityPermissions.java
* - Start from latest included commit and include changes until the newest commit with care
*/
@TargetApi(Build.VERSION_CODES.M)
public class AppSecurityPermissions {
private static final String TAG = "AppSecurityPermissions";
@ -104,11 +104,12 @@ public class AppSecurityPermissions {
super(info);
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP_MR1)
public Drawable loadGroupIcon(Context context, PackageManager pm) {
if (icon != 0) {
return (Build.VERSION.SDK_INT < 22) ? loadIcon(pm) : loadUnbadgedIcon(pm);
return (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP_MR1) ? loadIcon(pm) : loadUnbadgedIcon(pm);
}
return context.getDrawable(R.drawable.ic_perm_device_info);
return ContextCompat.getDrawable(context, R.drawable.ic_perm_device_info);
}
}
@ -309,13 +310,9 @@ public class AppSecurityPermissions {
}
permGroups.put(tmpPermInfo.group, group);
}
final boolean newPerm = installedPkgInfo != null
&& (existingFlags & PackageInfo.REQUESTED_PERMISSION_GRANTED) == 0;
MyPermissionInfo myPerm = new MyPermissionInfo(tmpPermInfo);
myPerm.existingReqFlags = existingFlags;
// This is a new permission if the app is already installed and
// doesn't currently hold this permission.
myPerm.newPerm = newPerm;
myPerm.newPerm = isNewPermission(installedPkgInfo, existingFlags);
permSet.add(myPerm);
} catch (NameNotFoundException e) {
Log.i(TAG, "Ignoring unknown permission:" + permName);
@ -323,6 +320,20 @@ public class AppSecurityPermissions {
}
}
/**
* A permission is a "new permission" if the app is already installed and
* doesn't currently hold this permission. On older devices that don't support
* this concept, permissions are never "new permissions".
*/
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
private static boolean isNewPermission(PackageInfo installedPkgInfo, int existingFlags) {
if (installedPkgInfo == null || Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
return false;
}
return (existingFlags & PackageInfo.REQUESTED_PERMISSION_GRANTED) == 0;
}
private List<MyPermissionInfo> getPermissionList(MyPermissionGroupInfo grp, int which) {
switch (which) {
case WHICH_NEW: