Do not show install confirm activity if there are no new permissions, externalize app diff for this functionality
This commit is contained in:
parent
62a4d58756
commit
f48236deb9
69
F-Droid/src/org/fdroid/fdroid/installer/AppDiff.java
Normal file
69
F-Droid/src/org/fdroid/fdroid/installer/AppDiff.java
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
/*
|
||||||
|
**
|
||||||
|
** Copyright 2007, The Android Open Source Project
|
||||||
|
** Copyright 2015 Dominik Schürmann <dominik@dominikschuermann.de>
|
||||||
|
**
|
||||||
|
** Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
** you may not use this file except in compliance with the License.
|
||||||
|
** You may obtain a copy of the License at
|
||||||
|
**
|
||||||
|
** http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
**
|
||||||
|
** Unless required by applicable law or agreed to in writing, software
|
||||||
|
** distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
** See the License for the specific language governing permissions and
|
||||||
|
** limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.fdroid.fdroid.installer;
|
||||||
|
|
||||||
|
import android.content.pm.ApplicationInfo;
|
||||||
|
import android.content.pm.PackageInfo;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
|
import android.net.Uri;
|
||||||
|
|
||||||
|
public class AppDiff {
|
||||||
|
|
||||||
|
PackageManager mPm;
|
||||||
|
PackageInfo mPkgInfo;
|
||||||
|
|
||||||
|
ApplicationInfo mAppInfo = null;
|
||||||
|
|
||||||
|
public AppDiff(PackageManager mPm, Uri mPackageURI) {
|
||||||
|
this.mPm = mPm;
|
||||||
|
|
||||||
|
final String pkgPath = mPackageURI.getPath();
|
||||||
|
|
||||||
|
mPkgInfo = mPm.getPackageArchiveInfo(pkgPath, PackageManager.GET_PERMISSIONS);
|
||||||
|
mPkgInfo.applicationInfo.sourceDir = pkgPath;
|
||||||
|
mPkgInfo.applicationInfo.publicSourceDir = pkgPath;
|
||||||
|
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void init() {
|
||||||
|
String pkgName = mPkgInfo.packageName;
|
||||||
|
// Check if there is already a package on the device with this name
|
||||||
|
// but it has been renamed to something else.
|
||||||
|
final String[] oldName = mPm.canonicalToCurrentPackageNames(new String[] { pkgName });
|
||||||
|
if (oldName != null && oldName.length > 0 && oldName[0] != null) {
|
||||||
|
pkgName = oldName[0];
|
||||||
|
mPkgInfo.packageName = pkgName;
|
||||||
|
mPkgInfo.applicationInfo.packageName = pkgName;
|
||||||
|
}
|
||||||
|
// Check if package is already installed. display confirmation dialog if replacing pkg
|
||||||
|
try {
|
||||||
|
// This is a little convoluted because we want to get all uninstalled
|
||||||
|
// apps, but this may include apps with just data, and if it is just
|
||||||
|
// data we still want to count it as "installed".
|
||||||
|
mAppInfo = mPm.getApplicationInfo(pkgName,
|
||||||
|
PackageManager.GET_UNINSTALLED_PACKAGES);
|
||||||
|
if ((mAppInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
|
||||||
|
mAppInfo = null;
|
||||||
|
}
|
||||||
|
} catch (PackageManager.NameNotFoundException e) {
|
||||||
|
mAppInfo = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -15,6 +15,7 @@
|
|||||||
** See the License for the specific language governing permissions and
|
** See the License for the specific language governing permissions and
|
||||||
** limitations under the License.
|
** limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.fdroid.fdroid.installer;
|
package org.fdroid.fdroid.installer;
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
@ -23,9 +24,7 @@ import android.content.DialogInterface;
|
|||||||
import android.content.DialogInterface.OnCancelListener;
|
import android.content.DialogInterface.OnCancelListener;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.pm.ApplicationInfo;
|
import android.content.pm.ApplicationInfo;
|
||||||
import android.content.pm.PackageInfo;
|
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.content.pm.PackageManager.NameNotFoundException;
|
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
@ -47,9 +46,8 @@ public class InstallConfirmActivity extends Activity implements OnCancelListener
|
|||||||
private Intent intent;
|
private Intent intent;
|
||||||
|
|
||||||
PackageManager mPm;
|
PackageManager mPm;
|
||||||
PackageInfo mPkgInfo;
|
|
||||||
|
|
||||||
private ApplicationInfo mAppInfo = null;
|
AppDiff mAppDiff;
|
||||||
|
|
||||||
// View for install progress
|
// View for install progress
|
||||||
View mInstallConfirm;
|
View mInstallConfirm;
|
||||||
@ -64,8 +62,8 @@ public class InstallConfirmActivity extends Activity implements OnCancelListener
|
|||||||
|
|
||||||
private void startInstallConfirm() {
|
private void startInstallConfirm() {
|
||||||
|
|
||||||
final Drawable appIcon = mPkgInfo.applicationInfo.loadIcon(mPm);
|
final Drawable appIcon = mAppDiff.mPkgInfo.applicationInfo.loadIcon(mPm);
|
||||||
final String appLabel = (String) mPkgInfo.applicationInfo.loadLabel(mPm);
|
final String appLabel = (String) mAppDiff.mPkgInfo.applicationInfo.loadLabel(mPm);
|
||||||
|
|
||||||
View appSnippet = findViewById(R.id.app_snippet);
|
View appSnippet = findViewById(R.id.app_snippet);
|
||||||
((ImageView) appSnippet.findViewById(R.id.app_icon)).setImageDrawable(appIcon);
|
((ImageView) appSnippet.findViewById(R.id.app_icon)).setImageDrawable(appIcon);
|
||||||
@ -85,12 +83,12 @@ public class InstallConfirmActivity extends Activity implements OnCancelListener
|
|||||||
mScrollView = null;
|
mScrollView = null;
|
||||||
mOkCanInstall = false;
|
mOkCanInstall = false;
|
||||||
int msg = 0;
|
int msg = 0;
|
||||||
if (mPkgInfo != null) {
|
if (mAppDiff.mPkgInfo != null) {
|
||||||
AppSecurityPermissions perms = new AppSecurityPermissions(this, mPkgInfo);
|
AppSecurityPermissions perms = new AppSecurityPermissions(this, mAppDiff.mPkgInfo);
|
||||||
final int NP = perms.getPermissionCount(AppSecurityPermissions.WHICH_PERSONAL);
|
final int NP = perms.getPermissionCount(AppSecurityPermissions.WHICH_PERSONAL);
|
||||||
final int ND = perms.getPermissionCount(AppSecurityPermissions.WHICH_DEVICE);
|
final int ND = perms.getPermissionCount(AppSecurityPermissions.WHICH_DEVICE);
|
||||||
if (mAppInfo != null) {
|
if (mAppDiff.mAppInfo != null) {
|
||||||
msg = (mAppInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0
|
msg = (mAppDiff.mAppInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0
|
||||||
? R.string.install_confirm_update_system
|
? R.string.install_confirm_update_system
|
||||||
: R.string.install_confirm_update;
|
: R.string.install_confirm_update;
|
||||||
mScrollView = new CaffeinatedScrollView(this);
|
mScrollView = new CaffeinatedScrollView(this);
|
||||||
@ -139,10 +137,10 @@ public class InstallConfirmActivity extends Activity implements OnCancelListener
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!permVisible) {
|
if (!permVisible) {
|
||||||
if (mAppInfo != null) {
|
if (mAppDiff.mAppInfo != null) {
|
||||||
// This is an update to an application, but there are no
|
// This is an update to an application, but there are no
|
||||||
// permissions at all.
|
// permissions at all.
|
||||||
msg = (mAppInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0
|
msg = (mAppDiff.mAppInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0
|
||||||
? R.string.install_confirm_update_system_no_perms
|
? R.string.install_confirm_update_system_no_perms
|
||||||
: R.string.install_confirm_update_no_perms;
|
: R.string.install_confirm_update_no_perms;
|
||||||
} else {
|
} else {
|
||||||
@ -178,33 +176,6 @@ public class InstallConfirmActivity extends Activity implements OnCancelListener
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initiateInstall() {
|
|
||||||
String pkgName = mPkgInfo.packageName;
|
|
||||||
// Check if there is already a package on the device with this name
|
|
||||||
// but it has been renamed to something else.
|
|
||||||
final String[] oldName = mPm.canonicalToCurrentPackageNames(new String[] { pkgName });
|
|
||||||
if (oldName != null && oldName.length > 0 && oldName[0] != null) {
|
|
||||||
pkgName = oldName[0];
|
|
||||||
mPkgInfo.packageName = pkgName;
|
|
||||||
mPkgInfo.applicationInfo.packageName = pkgName;
|
|
||||||
}
|
|
||||||
// Check if package is already installed. display confirmation dialog if replacing pkg
|
|
||||||
try {
|
|
||||||
// This is a little convoluted because we want to get all uninstalled
|
|
||||||
// apps, but this may include apps with just data, and if it is just
|
|
||||||
// data we still want to count it as "installed".
|
|
||||||
mAppInfo = mPm.getApplicationInfo(pkgName,
|
|
||||||
PackageManager.GET_UNINSTALLED_PACKAGES);
|
|
||||||
if ((mAppInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
|
|
||||||
mAppInfo = null;
|
|
||||||
}
|
|
||||||
} catch (NameNotFoundException e) {
|
|
||||||
mAppInfo = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
startInstallConfirm();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle icicle) {
|
protected void onCreate(Bundle icicle) {
|
||||||
super.onCreate(icicle);
|
super.onCreate(icicle);
|
||||||
@ -214,18 +185,15 @@ public class InstallConfirmActivity extends Activity implements OnCancelListener
|
|||||||
mPm = getPackageManager();
|
mPm = getPackageManager();
|
||||||
|
|
||||||
intent = getIntent();
|
intent = getIntent();
|
||||||
Uri mPackageURI = intent.getData();
|
Uri packageURI = intent.getData();
|
||||||
final String pkgPath = mPackageURI.getPath();
|
|
||||||
|
|
||||||
mPkgInfo = mPm.getPackageArchiveInfo(pkgPath, PackageManager.GET_PERMISSIONS);
|
mAppDiff = new AppDiff(mPm, packageURI);
|
||||||
mPkgInfo.applicationInfo.sourceDir = pkgPath;
|
|
||||||
mPkgInfo.applicationInfo.publicSourceDir = pkgPath;
|
|
||||||
|
|
||||||
setContentView(R.layout.install_start);
|
setContentView(R.layout.install_start);
|
||||||
mInstallConfirm = findViewById(R.id.install_confirm_panel);
|
mInstallConfirm = findViewById(R.id.install_confirm_panel);
|
||||||
mInstallConfirm.setVisibility(View.INVISIBLE);
|
mInstallConfirm.setVisibility(View.INVISIBLE);
|
||||||
|
|
||||||
initiateInstall();
|
startInstallConfirm();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -138,9 +138,32 @@ public class SystemInstaller extends Installer {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void installPackageInternal(File apkFile) throws AndroidNotCompatibleException {
|
protected void installPackageInternal(File apkFile) throws AndroidNotCompatibleException {
|
||||||
Intent intent = new Intent(mContext, InstallConfirmActivity.class);
|
Uri packageUri = Uri.fromFile(apkFile);
|
||||||
intent.setData(Uri.fromFile(apkFile));
|
if (hasNewPermissions(packageUri)) {
|
||||||
mActivity.startActivityForResult(intent, REQUEST_CONFIRM_PERMS);
|
Intent intent = new Intent(mContext, InstallConfirmActivity.class);
|
||||||
|
intent.setData(packageUri);
|
||||||
|
mActivity.startActivityForResult(intent, REQUEST_CONFIRM_PERMS);
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
doInstallPackageInternal(packageUri);
|
||||||
|
} catch (AndroidNotCompatibleException e) {
|
||||||
|
mCallback.onError(InstallerCallback.OPERATION_INSTALL,
|
||||||
|
InstallerCallback.ERROR_CODE_OTHER);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean hasNewPermissions(Uri packageUri) {
|
||||||
|
AppDiff appDiff = new AppDiff(mContext.getPackageManager(), packageUri);
|
||||||
|
if (appDiff.mPkgInfo != null) {
|
||||||
|
AppSecurityPermissions perms = new AppSecurityPermissions(mContext, appDiff.mPkgInfo);
|
||||||
|
if (appDiff.mAppInfo != null) { // it is an update to an existing app
|
||||||
|
// return false if there are no new permissions
|
||||||
|
return (perms.getPermissionCount(AppSecurityPermissions.WHICH_NEW) > 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// default: show install confirm activity
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void doInstallPackageInternal(Uri packageURI) throws AndroidNotCompatibleException {
|
private void doInstallPackageInternal(Uri packageURI) throws AndroidNotCompatibleException {
|
||||||
@ -220,9 +243,9 @@ public class SystemInstaller extends Installer {
|
|||||||
switch (requestCode) {
|
switch (requestCode) {
|
||||||
case REQUEST_CONFIRM_PERMS:
|
case REQUEST_CONFIRM_PERMS:
|
||||||
if (resultCode == Activity.RESULT_OK) {
|
if (resultCode == Activity.RESULT_OK) {
|
||||||
final Uri packageURI = data.getData();
|
final Uri packageUri = data.getData();
|
||||||
try {
|
try {
|
||||||
doInstallPackageInternal(packageURI);
|
doInstallPackageInternal(packageUri);
|
||||||
} catch (AndroidNotCompatibleException e) {
|
} catch (AndroidNotCompatibleException e) {
|
||||||
mCallback.onError(InstallerCallback.OPERATION_INSTALL,
|
mCallback.onError(InstallerCallback.OPERATION_INSTALL,
|
||||||
InstallerCallback.ERROR_CODE_OTHER);
|
InstallerCallback.ERROR_CODE_OTHER);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user