Move shared AIDL files into lib, restructure, start of install/delete code
This commit is contained in:
		
							parent
							
								
									09cdb08fdb
								
							
						
					
					
						commit
						85c8e7035d
					
				@ -1,14 +1,9 @@
 | 
			
		||||
buildscript {
 | 
			
		||||
    repositories {
 | 
			
		||||
        jcenter()
 | 
			
		||||
    }
 | 
			
		||||
    dependencies {
 | 
			
		||||
        classpath 'com.android.tools.build:gradle:1.3.1'
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
apply plugin: 'com.android.application'
 | 
			
		||||
 | 
			
		||||
dependencies {
 | 
			
		||||
    compile project(':privileged-api-lib')
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
android {
 | 
			
		||||
    compileSdkVersion 22
 | 
			
		||||
    buildToolsVersion '23.0.0'
 | 
			
		||||
 | 
			
		||||
@ -51,11 +51,7 @@
 | 
			
		||||
        android:maxSdkVersion="18" />
 | 
			
		||||
    <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="android.permission.INSTALL_PACKAGES"
 | 
			
		||||
        tools:ignore="ProtectedPermissions"/>
 | 
			
		||||
    <uses-permission android:name="android.permission.DELETE_PACKAGES"
 | 
			
		||||
        tools:ignore="ProtectedPermissions"/>
 | 
			
		||||
    <uses-permission android:name="org.fdroid.fdroid.privileged.USE_SERVICE" />
 | 
			
		||||
 | 
			
		||||
    <!-- Indicate that F-Droid may request root access (introduced by Koush's Superuser app)
 | 
			
		||||
         This permission is deprecated, but necessary for some old superuser
 | 
			
		||||
 | 
			
		||||
@ -15,6 +15,7 @@ if ( !hasProperty( 'sourceDeps' ) ) {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    dependencies {
 | 
			
		||||
        compile project(':privileged-api-lib')
 | 
			
		||||
 | 
			
		||||
        compile 'com.android.support:support-v4:22.2.1'
 | 
			
		||||
        compile 'com.android.support:appcompat-v7:22.1.1'
 | 
			
		||||
@ -60,6 +61,7 @@ if ( !hasProperty( 'sourceDeps' ) ) {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    dependencies {
 | 
			
		||||
        compile project(':privileged-api-lib')
 | 
			
		||||
        compile project(':extern:AndroidPinning')
 | 
			
		||||
        compile project(':extern:UniversalImageLoader:library')
 | 
			
		||||
        compile project(':extern:libsuperuser:libsuperuser')
 | 
			
		||||
 | 
			
		||||
@ -21,25 +21,28 @@
 | 
			
		||||
package org.fdroid.fdroid.installer;
 | 
			
		||||
 | 
			
		||||
import android.app.Activity;
 | 
			
		||||
import android.content.ComponentName;
 | 
			
		||||
import android.content.Context;
 | 
			
		||||
import android.content.DialogInterface;
 | 
			
		||||
import android.content.Intent;
 | 
			
		||||
import android.content.ServiceConnection;
 | 
			
		||||
import android.content.pm.ApplicationInfo;
 | 
			
		||||
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.support.v7.app.AlertDialog;
 | 
			
		||||
import android.util.Log;
 | 
			
		||||
 | 
			
		||||
import org.fdroid.fdroid.R;
 | 
			
		||||
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.AppSecurityPermissions;
 | 
			
		||||
import org.fdroid.fdroid.privileged.views.InstallConfirmActivity;
 | 
			
		||||
 | 
			
		||||
import java.io.File;
 | 
			
		||||
import java.lang.reflect.Method;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@ -70,11 +73,10 @@ public class PrivilegedInstaller extends Installer {
 | 
			
		||||
 | 
			
		||||
    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 final PackageInstallObserver mInstallObserver;
 | 
			
		||||
//    private final PackageDeleteObserver mDeleteObserver;
 | 
			
		||||
//    private Method mInstallMethod;
 | 
			
		||||
//    private Method mDeleteMethod;
 | 
			
		||||
 | 
			
		||||
    public static final int REQUEST_CONFIRM_PERMS = 0;
 | 
			
		||||
 | 
			
		||||
@ -83,61 +85,6 @@ public class PrivilegedInstaller extends Installer {
 | 
			
		||||
        super(activity, pm, callback);
 | 
			
		||||
        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
 | 
			
		||||
@ -179,15 +126,47 @@ public class PrivilegedInstaller extends Installer {
 | 
			
		||||
        return 1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void doInstallPackageInternal(Uri packageURI) throws AndroidNotCompatibleException {
 | 
			
		||||
        try {
 | 
			
		||||
            mInstallMethod.invoke(mPm, packageURI, mInstallObserver,
 | 
			
		||||
                    INSTALL_REPLACE_EXISTING, null);
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
            throw new AndroidNotCompatibleException(e);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    private void doInstallPackageInternal(final Uri packageURI) throws AndroidNotCompatibleException {
 | 
			
		||||
        ServiceConnection mServiceConnection = new ServiceConnection() {
 | 
			
		||||
            public void onServiceConnected(ComponentName name, IBinder service) {
 | 
			
		||||
                IPrivilegedService privService = IPrivilegedService.Stub.asInterface(service);
 | 
			
		||||
 | 
			
		||||
                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
 | 
			
		||||
    protected void installPackageInternal(List<File> apkFiles)
 | 
			
		||||
@ -253,35 +232,70 @@ public class PrivilegedInstaller extends Installer {
 | 
			
		||||
 | 
			
		||||
    private void doDeletePackageInternal(final String packageName)
 | 
			
		||||
            throws AndroidNotCompatibleException {
 | 
			
		||||
        try {
 | 
			
		||||
            mDeleteMethod.invoke(mPm, packageName, mDeleteObserver, 0);
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
            throw new AndroidNotCompatibleException(e);
 | 
			
		||||
        }
 | 
			
		||||
        ServiceConnection mServiceConnection = new ServiceConnection() {
 | 
			
		||||
            public void onServiceConnected(ComponentName name, IBinder service) {
 | 
			
		||||
                IPrivilegedService privService = IPrivilegedService.Stub.asInterface(service);
 | 
			
		||||
 | 
			
		||||
                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
 | 
			
		||||
    public boolean handleOnActivityResult(int requestCode, int resultCode, Intent data) {
 | 
			
		||||
        switch (requestCode) {
 | 
			
		||||
        case REQUEST_CONFIRM_PERMS:
 | 
			
		||||
            if (resultCode == Activity.RESULT_OK) {
 | 
			
		||||
                final Uri packageUri = data.getData();
 | 
			
		||||
                try {
 | 
			
		||||
                    doInstallPackageInternal(packageUri);
 | 
			
		||||
                } catch (AndroidNotCompatibleException e) {
 | 
			
		||||
            case REQUEST_CONFIRM_PERMS:
 | 
			
		||||
                if (resultCode == Activity.RESULT_OK) {
 | 
			
		||||
                    final Uri packageUri = data.getData();
 | 
			
		||||
                    try {
 | 
			
		||||
                        doInstallPackageInternal(packageUri);
 | 
			
		||||
                    } catch (AndroidNotCompatibleException e) {
 | 
			
		||||
                        mCallback.onError(InstallerCallback.OPERATION_INSTALL,
 | 
			
		||||
                                InstallerCallback.ERROR_CODE_OTHER);
 | 
			
		||||
                    }
 | 
			
		||||
                } else if (resultCode == InstallConfirmActivity.RESULT_CANNOT_PARSE) {
 | 
			
		||||
                    mCallback.onError(InstallerCallback.OPERATION_INSTALL,
 | 
			
		||||
                            InstallerCallback.ERROR_CODE_OTHER);
 | 
			
		||||
                            InstallerCallback.ERROR_CODE_CANNOT_PARSE);
 | 
			
		||||
                } else { // Activity.RESULT_CANCELED
 | 
			
		||||
                    mCallback.onError(InstallerCallback.OPERATION_INSTALL,
 | 
			
		||||
                            InstallerCallback.ERROR_CODE_CANCELED);
 | 
			
		||||
                }
 | 
			
		||||
            } else if (resultCode == InstallConfirmActivity.RESULT_CANNOT_PARSE) {
 | 
			
		||||
                mCallback.onError(InstallerCallback.OPERATION_INSTALL,
 | 
			
		||||
                        InstallerCallback.ERROR_CODE_CANNOT_PARSE);
 | 
			
		||||
            } else { // Activity.RESULT_CANCELED
 | 
			
		||||
                mCallback.onError(InstallerCallback.OPERATION_INSTALL,
 | 
			
		||||
                        InstallerCallback.ERROR_CODE_CANCELED);
 | 
			
		||||
            }
 | 
			
		||||
            return true;
 | 
			
		||||
        default:
 | 
			
		||||
            return false;
 | 
			
		||||
                return true;
 | 
			
		||||
            default:
 | 
			
		||||
                return false;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -582,7 +596,7 @@ public class PrivilegedInstaller extends Installer {
 | 
			
		||||
     * {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)}
 | 
			
		||||
     * if the system failed to install the package because it is attempting to define a
 | 
			
		||||
     * 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
 | 
			
		||||
     * 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
 | 
			
		||||
 | 
			
		||||
@ -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);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -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);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										33
									
								
								Privileged-F-Droid/.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										33
									
								
								Privileged-F-Droid/.gitignore
									
									
									
									
										vendored
									
									
								
							@ -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/*
 | 
			
		||||
@ -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
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -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>
 | 
			
		||||
@ -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);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -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);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -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;
 | 
			
		||||
}
 | 
			
		||||
@ -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;
 | 
			
		||||
}
 | 
			
		||||
@ -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  | 
@ -1,6 +0,0 @@
 | 
			
		||||
<?xml version="1.0" encoding="utf-8"?>
 | 
			
		||||
<resources>
 | 
			
		||||
 | 
			
		||||
    <string name="app_name">F-Droid Privileged</string>
 | 
			
		||||
 | 
			
		||||
</resources>
 | 
			
		||||
							
								
								
									
										18
									
								
								privileged-api-lib/build.gradle
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								privileged-api-lib/build.gradle
									
									
									
									
									
										Normal 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
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										6
									
								
								privileged-api-lib/src/main/AndroidManifest.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								privileged-api-lib/src/main/AndroidManifest.xml
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,6 @@
 | 
			
		||||
<?xml version="1.0" encoding="utf-8"?>
 | 
			
		||||
<manifest package="org.fdroid.fdroid.privileged.api">
 | 
			
		||||
 | 
			
		||||
    <application />
 | 
			
		||||
 | 
			
		||||
</manifest>
 | 
			
		||||
@ -1,4 +1,6 @@
 | 
			
		||||
include ':F-Droid'
 | 
			
		||||
include ':F-Droid-Privileged'
 | 
			
		||||
include ':privileged-api-lib'
 | 
			
		||||
 | 
			
		||||
if ( hasProperty( 'sourceDeps' ) ) {
 | 
			
		||||
	include ':extern:AndroidPinning'
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user