Move shared AIDL files into lib, restructure, start of install/delete code

This commit is contained in:
Dominik Schürmann 2015-08-26 22:12:16 +02:00
parent 09cdb08fdb
commit 85c8e7035d
26 changed files with 140 additions and 673 deletions

View File

@ -1,14 +1,9 @@
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:1.3.1'
}
}
apply plugin: 'com.android.application' apply plugin: 'com.android.application'
dependencies {
compile project(':privileged-api-lib')
}
android { android {
compileSdkVersion 22 compileSdkVersion 22
buildToolsVersion '23.0.0' buildToolsVersion '23.0.0'

View File

@ -51,11 +51,7 @@
android:maxSdkVersion="18" /> android:maxSdkVersion="18" />
<uses-permission android:name="android.permission.NFC" /> <uses-permission android:name="android.permission.NFC" />
<!-- These permissions are only granted when F-Droid is installed as a system-app! --> <uses-permission android:name="org.fdroid.fdroid.privileged.USE_SERVICE" />
<uses-permission android:name="android.permission.INSTALL_PACKAGES"
tools:ignore="ProtectedPermissions"/>
<uses-permission android:name="android.permission.DELETE_PACKAGES"
tools:ignore="ProtectedPermissions"/>
<!-- Indicate that F-Droid may request root access (introduced by Koush's Superuser app) <!-- Indicate that F-Droid may request root access (introduced by Koush's Superuser app)
This permission is deprecated, but necessary for some old superuser This permission is deprecated, but necessary for some old superuser

View File

@ -15,6 +15,7 @@ if ( !hasProperty( 'sourceDeps' ) ) {
} }
dependencies { dependencies {
compile project(':privileged-api-lib')
compile 'com.android.support:support-v4:22.2.1' compile 'com.android.support:support-v4:22.2.1'
compile 'com.android.support:appcompat-v7:22.1.1' compile 'com.android.support:appcompat-v7:22.1.1'
@ -60,6 +61,7 @@ if ( !hasProperty( 'sourceDeps' ) ) {
} }
dependencies { dependencies {
compile project(':privileged-api-lib')
compile project(':extern:AndroidPinning') compile project(':extern:AndroidPinning')
compile project(':extern:UniversalImageLoader:library') compile project(':extern:UniversalImageLoader:library')
compile project(':extern:libsuperuser:libsuperuser') compile project(':extern:libsuperuser:libsuperuser')

View File

@ -21,25 +21,28 @@
package org.fdroid.fdroid.installer; package org.fdroid.fdroid.installer;
import android.app.Activity; import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;
import android.content.ServiceConnection;
import android.content.pm.ApplicationInfo; import android.content.pm.ApplicationInfo;
import android.content.pm.IPackageDeleteObserver;
import android.content.pm.IPackageInstallObserver;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.net.Uri; import android.net.Uri;
import android.os.IBinder;
import android.os.RemoteException; import android.os.RemoteException;
import android.support.v7.app.AlertDialog; import android.support.v7.app.AlertDialog;
import android.util.Log; import android.util.Log;
import org.fdroid.fdroid.R; import org.fdroid.fdroid.R;
import org.fdroid.fdroid.Utils; import org.fdroid.fdroid.Utils;
import org.fdroid.fdroid.privileged.IPrivilegedCallback;
import org.fdroid.fdroid.privileged.IPrivilegedService;
import org.fdroid.fdroid.privileged.views.AppDiff; import org.fdroid.fdroid.privileged.views.AppDiff;
import org.fdroid.fdroid.privileged.views.AppSecurityPermissions; import org.fdroid.fdroid.privileged.views.AppSecurityPermissions;
import org.fdroid.fdroid.privileged.views.InstallConfirmActivity; import org.fdroid.fdroid.privileged.views.InstallConfirmActivity;
import java.io.File; import java.io.File;
import java.lang.reflect.Method;
import java.util.List; import java.util.List;
/** /**
@ -70,11 +73,10 @@ public class PrivilegedInstaller extends Installer {
private static final String TAG = "PrivilegedInstaller"; private static final String TAG = "PrivilegedInstaller";
private static final String PRIVILEGED_INTENT = "org.fdroid.fdroid.privileged.IPrivilegedService";
private static final String PRIVILEGED_PACKAGE_NAME = "org.fdroid.fdroid.privileged";
private Activity mActivity; private Activity mActivity;
// private final PackageInstallObserver mInstallObserver;
// private final PackageDeleteObserver mDeleteObserver;
// private Method mInstallMethod;
// private Method mDeleteMethod;
public static final int REQUEST_CONFIRM_PERMS = 0; public static final int REQUEST_CONFIRM_PERMS = 0;
@ -83,61 +85,6 @@ public class PrivilegedInstaller extends Installer {
super(activity, pm, callback); super(activity, pm, callback);
this.mActivity = activity; this.mActivity = activity;
// create internal callbacks
mInstallObserver = new PackageInstallObserver();
mDeleteObserver = new PackageDeleteObserver();
try {
Class<?>[] installTypes = {
Uri.class, IPackageInstallObserver.class, int.class,
String.class
};
Class<?>[] deleteTypes = {
String.class, IPackageDeleteObserver.class,
int.class
};
mInstallMethod = mPm.getClass().getMethod("installPackage", installTypes);
mDeleteMethod = mPm.getClass().getMethod("deletePackage", deleteTypes);
} catch (NoSuchMethodException e) {
throw new AndroidNotCompatibleException(e);
}
}
/**
* Internal install callback from the system
*/
class PackageInstallObserver extends IPackageInstallObserver.Stub {
public void packageInstalled(String packageName, int returnCode) throws RemoteException {
// TODO: propagate other return codes?
if (returnCode == INSTALL_SUCCEEDED) {
Utils.DebugLog(TAG, "Install succeeded");
mCallback.onSuccess(InstallerCallback.OPERATION_INSTALL);
} else {
Log.e(TAG, "Install failed with returnCode " + returnCode);
mCallback.onError(InstallerCallback.OPERATION_INSTALL,
InstallerCallback.ERROR_CODE_OTHER);
}
}
}
/**
* Internal delete callback from the system
*/
class PackageDeleteObserver extends IPackageDeleteObserver.Stub {
public void packageDeleted(String packageName, int returnCode) throws RemoteException {
// TODO: propagate other return codes?
if (returnCode == DELETE_SUCCEEDED) {
Utils.DebugLog(TAG, "Delete succeeded");
mCallback.onSuccess(InstallerCallback.OPERATION_DELETE);
} else {
Log.e(TAG, "Delete failed with returnCode " + returnCode);
mCallback.onError(InstallerCallback.OPERATION_DELETE,
InstallerCallback.ERROR_CODE_OTHER);
}
}
} }
@Override @Override
@ -179,15 +126,47 @@ public class PrivilegedInstaller extends Installer {
return 1; return 1;
} }
private void doInstallPackageInternal(Uri packageURI) throws AndroidNotCompatibleException { private void doInstallPackageInternal(final Uri packageURI) throws AndroidNotCompatibleException {
try { ServiceConnection mServiceConnection = new ServiceConnection() {
mInstallMethod.invoke(mPm, packageURI, mInstallObserver, public void onServiceConnected(ComponentName name, IBinder service) {
INSTALL_REPLACE_EXISTING, null); IPrivilegedService privService = IPrivilegedService.Stub.asInterface(service);
} catch (Exception e) {
throw new AndroidNotCompatibleException(e); IPrivilegedCallback callback = new IPrivilegedCallback() {
@Override
public void handleResult(String packageName, int returnCode) throws RemoteException {
// TODO: propagate other return codes?
if (returnCode == INSTALL_SUCCEEDED) {
Utils.DebugLog(TAG, "Install succeeded");
mCallback.onSuccess(InstallerCallback.OPERATION_INSTALL);
} else {
Log.e(TAG, "Install failed with returnCode " + returnCode);
mCallback.onError(InstallerCallback.OPERATION_INSTALL,
InstallerCallback.ERROR_CODE_OTHER);
} }
} }
@Override
public IBinder asBinder() {
return null;
}
};
try {
privService.installPackage(packageURI, INSTALL_REPLACE_EXISTING, null, callback);
} catch (RemoteException e) {
Log.e(TAG, "RemoteException", e);
}
}
public void onServiceDisconnected(ComponentName name) {
}
};
Intent serviceIntent = new Intent(PRIVILEGED_INTENT);
serviceIntent.setPackage(PRIVILEGED_PACKAGE_NAME);
mContext.getApplicationContext().bindService(serviceIntent, mServiceConnection,
Context.BIND_AUTO_CREATE);
}
@Override @Override
protected void installPackageInternal(List<File> apkFiles) protected void installPackageInternal(List<File> apkFiles)
@ -253,13 +232,48 @@ public class PrivilegedInstaller extends Installer {
private void doDeletePackageInternal(final String packageName) private void doDeletePackageInternal(final String packageName)
throws AndroidNotCompatibleException { throws AndroidNotCompatibleException {
try { ServiceConnection mServiceConnection = new ServiceConnection() {
mDeleteMethod.invoke(mPm, packageName, mDeleteObserver, 0); public void onServiceConnected(ComponentName name, IBinder service) {
} catch (Exception e) { IPrivilegedService privService = IPrivilegedService.Stub.asInterface(service);
throw new AndroidNotCompatibleException(e);
IPrivilegedCallback callback = new IPrivilegedCallback() {
@Override
public void handleResult(String packageName, int returnCode) throws RemoteException {
// TODO: propagate other return codes?
if (returnCode == DELETE_SUCCEEDED) {
Utils.DebugLog(TAG, "Delete succeeded");
mCallback.onSuccess(InstallerCallback.OPERATION_DELETE);
} else {
Log.e(TAG, "Delete failed with returnCode " + returnCode);
mCallback.onError(InstallerCallback.OPERATION_DELETE,
InstallerCallback.ERROR_CODE_OTHER);
} }
} }
@Override
public IBinder asBinder() {
return null;
}
};
try {
privService.deletePackage(packageName, 0, callback);
} catch (RemoteException e) {
Log.e(TAG, "RemoteException", e);
}
}
public void onServiceDisconnected(ComponentName name) {
}
};
Intent serviceIntent = new Intent(PRIVILEGED_INTENT);
serviceIntent.setPackage(PRIVILEGED_PACKAGE_NAME);
mContext.getApplicationContext().bindService(serviceIntent, mServiceConnection,
Context.BIND_AUTO_CREATE);
}
@Override @Override
public boolean handleOnActivityResult(int requestCode, int resultCode, Intent data) { public boolean handleOnActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) { switch (requestCode) {
@ -582,7 +596,7 @@ public class PrivilegedInstaller extends Installer {
* {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)} * {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)}
* if the system failed to install the package because it is attempting to define a * if the system failed to install the package because it is attempting to define a
* permission that is already defined by some existing package. * permission that is already defined by some existing package.
* * <p/>
* <p>The package name of the app which has already defined the permission is passed to * <p>The package name of the app which has already defined the permission is passed to
* a {@link PackageInstallObserver}, if any, as the {@link #EXTRA_EXISTING_PACKAGE} * a {@link PackageInstallObserver}, if any, as the {@link #EXTRA_EXISTING_PACKAGE}
* string extra; and the name of the permission being redefined is passed in the * string extra; and the name of the permission being redefined is passed in the

View File

@ -1,26 +0,0 @@
/*
* Copyright (C) 2015 Dominik Schürmann <dominik@dominikschuermann.de>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 3
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*/
package org.fdroid.fdroid.privileged;
interface IPrivilegedCallback {
void handleResult(in String packageName, in int returnCode);
}

View File

@ -1,65 +0,0 @@
/*
* Copyright (C) 2015 Dominik Schürmann <dominik@dominikschuermann.de>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 3
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*/
package org.fdroid.fdroid.privileged;
import org.fdroid.fdroid.privileged.IPrivilegedCallback;
/**
* Asynchronous (oneway) IPC calls!
*/
oneway interface IPrivilegedService {
/**
* Docs based on PackageManager.installPackage()
*
* Install a package. Since this may take a little while, the result will
* be posted back to the given callback. An installation will fail if the
* package named in the package file's manifest is already installed, or if there's no space
* available on the device.
*
* @param packageURI The location of the package file to install. This can be a 'file:' or a
* 'content:' URI.
* @param flags - possible values: {@link #INSTALL_FORWARD_LOCK},
* {@link #INSTALL_REPLACE_EXISTING}, {@link #INSTALL_ALLOW_TEST}.
* @param installerPackageName Optional package name of the application that is performing the
* installation. This identifies which market the package came from.
* @param callback An callback to get notified when the package installation is
* complete.
*/
void installPackage(in Uri packageURI, in int flags, in String installerPackageName,
in IPrivilegedCallback callback);
/**
* Docs based on PackageManager.deletePackage()
*
* Attempts to delete a package. Since this may take a little while, the result will
* be posted back to the given observer. A deletion will fail if the
* named package cannot be found, or if the named package is a "system package".
*
* @param packageName The name of the package to delete
* @param flags - possible values: {@link #DELETE_KEEP_DATA},
* {@link #DELETE_ALL_USERS}.
* @param callback An callback to get notified when the package deletion is
* complete.
*/
void deletePackage(in String packageName, in int flags, in IPrivilegedCallback callback);
}

View File

@ -1,33 +0,0 @@
#Android specific
bin
gen
obj
lint.xml
local.properties
release.properties
ant.properties
*.class
*.apk
#Gradle
.gradle
build
gradle.properties
#Maven
target
pom.xml.*
#Eclipse
.project
.classpath
.settings
.metadata
#IntelliJ IDEA
.idea
*.iml
#Lint output
lint-report.html
lint-report_files/*

View File

@ -1,51 +0,0 @@
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:1.3.1'
}
}
apply plugin: 'com.android.application'
android {
compileSdkVersion 22
buildToolsVersion '23.0.0'
defaultConfig {
minSdkVersion 8
targetSdkVersion 22
versionCode 1
versionName "1.0"
}
compileOptions {
compileOptions.encoding = "UTF-8"
// Use Java 1.7, requires minSdk 8
sourceCompatibility JavaVersion.VERSION_1_7
targetCompatibility JavaVersion.VERSION_1_7
}
buildTypes {
release {
minifyEnabled true
// Reference them in the java files with e.g. BuildConfig.F_DROID_CERT_SHA512.
buildConfigField "String", "F_DROID_CERT_SHA512", "\"9ba5d51a0d5c3627e270c2542b761937c721b0d8a1caed88bd3b2f21add138c2f16e295ce67bef21b21e0b75d5a0c6fd13d67efeb85c198cffa365755c94f4c2\""
}
debug {
// Reference them in the java files with e.g. BuildConfig.F_DROID_CERT_SHA512.
buildConfigField "String", "F_DROID_CERT_SHA512", "\"9ba5d51a0d5c3627e270c2542b761937c721b0d8a1caed88bd3b2f21add138c2f16e295ce67bef21b21e0b75d5a0c6fd13d67efeb85c198cffa365755c94f4c2\""
}
}
lintOptions {
// Do not abort build if lint finds errors
abortOnError false
}
}

View File

@ -1,41 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="org.fdroid.fdroid.privileged">
<!-- These permissions are only granted when this apk is installed as a privileged app! -->
<uses-permission
android:name="android.permission.INSTALL_PACKAGES"
tools:ignore="ProtectedPermissions" />
<uses-permission
android:name="android.permission.DELETE_PACKAGES"
tools:ignore="ProtectedPermissions" />
<!--
Only apps signed with the same key can use this permission!
Never presented to the user due to the protectionLevel.
-->
<permission
android:name="org.fdroid.fdroid.privileged.USE_SERVICE"
android:protectionLevel="signature" />
<application
android:allowBackup="false"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name">
<!-- API -->
<service
android:name=".PrivilegedService"
android:enabled="true"
android:exported="true"
android:process=":fdroid_privileged"
android:permission="org.fdroid.fdroid.privileged.USE_SERVICE">
<intent-filter>
<action android:name="org.fdroid.fdroid.privileged.IPrivilegedService" />
</intent-filter>
</service>
</application>
</manifest>

View File

@ -1,26 +0,0 @@
/*
* Copyright (C) 2015 Dominik Schürmann <dominik@dominikschuermann.de>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 3
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*/
package org.fdroid.fdroid.privileged;
interface IPrivilegedCallback {
void handleResult(in String packageName, in int returnCode);
}

View File

@ -1,65 +0,0 @@
/*
* Copyright (C) 2015 Dominik Schürmann <dominik@dominikschuermann.de>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 3
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*/
package org.fdroid.fdroid.privileged;
import org.fdroid.fdroid.privileged.IPrivilegedCallback;
/**
* Asynchronous (oneway) IPC calls!
*/
oneway interface IPrivilegedService {
/**
* Docs based on PackageManager.installPackage()
*
* Install a package. Since this may take a little while, the result will
* be posted back to the given callback. An installation will fail if the
* package named in the package file's manifest is already installed, or if there's no space
* available on the device.
*
* @param packageURI The location of the package file to install. This can be a 'file:' or a
* 'content:' URI.
* @param flags - possible values: {@link #INSTALL_FORWARD_LOCK},
* {@link #INSTALL_REPLACE_EXISTING}, {@link #INSTALL_ALLOW_TEST}.
* @param installerPackageName Optional package name of the application that is performing the
* installation. This identifies which market the package came from.
* @param callback An callback to get notified when the package installation is
* complete.
*/
void installPackage(in Uri packageURI, in int flags, in String installerPackageName,
in IPrivilegedCallback callback);
/**
* Docs based on PackageManager.deletePackage()
*
* Attempts to delete a package. Since this may take a little while, the result will
* be posted back to the given observer. A deletion will fail if the
* named package cannot be found, or if the named package is a "system package".
*
* @param packageName The name of the package to delete
* @param flags - possible values: {@link #DELETE_KEEP_DATA},
* {@link #DELETE_ALL_USERS}.
* @param callback An callback to get notified when the package deletion is
* complete.
*/
void deletePackage(in String packageName, in int flags, in IPrivilegedCallback callback);
}

View File

@ -1,54 +0,0 @@
/*
* Copyright (C) 2015 Dominik Schürmann <dominik@dominikschuermann.de>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 3
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*/
package android.content.pm;
import android.os.Binder;
import android.os.IBinder;
import android.os.IInterface;
import android.os.Parcel;
import android.os.RemoteException;
/**
* Just a non-working implementation of this Stub to satisfy compiler!
*/
public interface IPackageDeleteObserver extends IInterface {
abstract class Stub extends Binder implements android.content.pm.IPackageDeleteObserver {
public Stub() {
throw new RuntimeException("Stub!");
}
public static IPackageDeleteObserver asInterface(IBinder obj) {
throw new RuntimeException("Stub!");
}
public IBinder asBinder() {
throw new RuntimeException("Stub!");
}
public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
throws RemoteException {
throw new RuntimeException("Stub!");
}
}
void packageDeleted(java.lang.String packageName, int returnCode) throws RemoteException;
}

View File

@ -1,54 +0,0 @@
/*
* Copyright (C) 2015 Dominik Schürmann <dominik@dominikschuermann.de>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 3
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*/
package android.content.pm;
import android.os.Binder;
import android.os.IBinder;
import android.os.IInterface;
import android.os.Parcel;
import android.os.RemoteException;
/**
* Just a non-working implementation of this Stub to satisfy compiler!
*/
public interface IPackageInstallObserver extends IInterface {
abstract class Stub extends Binder implements android.content.pm.IPackageInstallObserver {
public Stub() {
throw new RuntimeException("Stub!");
}
public static android.content.pm.IPackageInstallObserver asInterface(IBinder obj) {
throw new RuntimeException("Stub!");
}
public IBinder asBinder() {
throw new RuntimeException("Stub!");
}
public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
throws RemoteException {
throw new RuntimeException("Stub!");
}
}
void packageInstalled(String packageName, int returnCode) throws RemoteException;
}

View File

@ -1,145 +0,0 @@
/*
* Copyright (C) 2015 Dominik Schürmann <dominik@dominikschuermann.de>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 3
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*/
package org.fdroid.fdroid.privileged;
import android.app.Service;
import android.content.Intent;
import android.content.pm.IPackageDeleteObserver;
import android.content.pm.IPackageInstallObserver;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
import java.lang.reflect.Method;
/**
* This service provides an API via AIDL IPC for the main F-Droid app to install/delete packages.
*/
public class PrivilegedService extends Service {
public static final String TAG = "PrivilegedFDroid";
private Method mInstallMethod;
private Method mDeleteMethod;
private void installPackageImpl(Uri packageURI, int flags, String installerPackageName,
final IPrivilegedCallback callback) {
// Internal callback from the system
IPackageInstallObserver.Stub installObserver = new IPackageInstallObserver.Stub() {
@Override
public void packageInstalled(String packageName, int returnCode) throws RemoteException {
// forward this internal callback to our callback
try {
callback.handleResult(packageName, returnCode);
} catch (RemoteException e1) {
Log.e(TAG, "RemoteException", e1);
}
}
};
// execute internal method
try {
mInstallMethod.invoke(getPackageManager(), packageURI, installObserver,
flags, installerPackageName);
} catch (Exception e) {
Log.e(TAG, "Android not compatible!", e);
try {
callback.handleResult(null, 0);
} catch (RemoteException e1) {
Log.e(TAG, "RemoteException", e1);
}
}
}
private void deletePackageImpl(String packageName, int flags, final IPrivilegedCallback callback) {
// Internal callback from the system
IPackageDeleteObserver.Stub deleteObserver = new IPackageDeleteObserver.Stub() {
@Override
public void packageDeleted(String packageName, int returnCode) throws RemoteException {
// forward this internal callback to our callback
try {
callback.handleResult(packageName, returnCode);
} catch (RemoteException e1) {
Log.e(TAG, "RemoteException", e1);
}
}
};
// execute internal method
try {
mDeleteMethod.invoke(getPackageManager(), packageName, deleteObserver, flags);
} catch (Exception e) {
Log.e(TAG, "Android not compatible!", e);
try {
callback.handleResult(null, 0);
} catch (RemoteException e1) {
Log.e(TAG, "RemoteException", e1);
}
}
}
private final IPrivilegedService.Stub mBinder = new IPrivilegedService.Stub() {
@Override
public void installPackage(Uri packageURI, int flags, String installerPackageName,
IPrivilegedCallback callback) {
installPackageImpl(packageURI, flags, installerPackageName, callback);
}
@Override
public void deletePackage(String packageName, int flags, IPrivilegedCallback callback) {
deletePackageImpl(packageName, flags, callback);
}
};
@Override
public IBinder onBind(Intent intent) {
return mBinder;
}
@Override
public void onCreate() {
super.onCreate();
// get internal methods via reflection
try {
Class<?>[] installTypes = {
Uri.class, IPackageInstallObserver.class, int.class,
String.class
};
Class<?>[] deleteTypes = {
String.class, IPackageDeleteObserver.class,
int.class
};
PackageManager pm = getPackageManager();
mInstallMethod = pm.getClass().getMethod("installPackage", installTypes);
mDeleteMethod = pm.getClass().getMethod("deletePackage", deleteTypes);
} catch (NoSuchMethodException e) {
Log.e(TAG, "Android not compatible!", e);
stopSelf();
}
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

View File

@ -1,6 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">F-Droid Privileged</string>
</resources>

View File

@ -0,0 +1,18 @@
apply plugin: 'com.android.library'
android {
compileSdkVersion 22
buildToolsVersion '23.0.0'
defaultConfig {
minSdkVersion 8
targetSdkVersion 22
versionCode 1
versionName "1.0"
}
// Do not abort build if lint finds errors
lintOptions {
abortOnError false
}
}

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest package="org.fdroid.fdroid.privileged.api">
<application />
</manifest>

View File

@ -1,4 +1,6 @@
include ':F-Droid' include ':F-Droid'
include ':F-Droid-Privileged'
include ':privileged-api-lib'
if ( hasProperty( 'sourceDeps' ) ) { if ( hasProperty( 'sourceDeps' ) ) {
include ':extern:AndroidPinning' include ':extern:AndroidPinning'