Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3e3b251f authored by Jeff Sharkey's avatar Jeff Sharkey Committed by Android (Google) Code Review
Browse files

Merge "PackageInstaller API refactoring." into lmp-dev

parents 78fc9220 a0907436
Loading
Loading
Loading
Loading
+47 −59
Original line number Diff line number Diff line
@@ -8540,36 +8540,6 @@ package android.content.pm {
    field public int reqGlEsVersion;
  }
  public class InstallSessionInfo implements android.os.Parcelable {
    method public int describeContents();
    method public android.graphics.Bitmap getAppIcon();
    method public java.lang.CharSequence getAppLabel();
    method public java.lang.String getAppPackageName();
    method public android.content.Intent getDetailsIntent();
    method public java.lang.String getInstallerPackageName();
    method public float getProgress();
    method public int getSessionId();
    method public boolean isOpen();
    method public void writeToParcel(android.os.Parcel, int);
    field public static final android.os.Parcelable.Creator CREATOR;
  }
  public class InstallSessionParams implements android.os.Parcelable {
    ctor public InstallSessionParams(int);
    method public int describeContents();
    method public void setAppIcon(android.graphics.Bitmap);
    method public void setAppLabel(java.lang.CharSequence);
    method public void setAppPackageName(java.lang.String);
    method public void setInstallLocation(int);
    method public void setOriginatingUri(android.net.Uri);
    method public void setReferrerUri(android.net.Uri);
    method public void setSize(long);
    method public void writeToParcel(android.os.Parcel, int);
    field public static final android.os.Parcelable.Creator CREATOR;
    field public static final int MODE_FULL_INSTALL = 1; // 0x1
    field public static final int MODE_INHERIT_EXISTING = 2; // 0x2
  }
  public class InstrumentationInfo extends android.content.pm.PackageItemInfo implements android.os.Parcelable {
    ctor public InstrumentationInfo();
    ctor public InstrumentationInfo(android.content.pm.InstrumentationInfo);
@@ -8671,37 +8641,35 @@ package android.content.pm {
  public class PackageInstaller {
    method public void addSessionCallback(android.content.pm.PackageInstaller.SessionCallback);
    method public void addSessionCallback(android.content.pm.PackageInstaller.SessionCallback, android.os.Handler);
    method public int createSession(android.content.pm.InstallSessionParams) throws java.io.IOException;
    method public java.util.List<android.content.pm.InstallSessionInfo> getAllSessions();
    method public java.util.List<android.content.pm.InstallSessionInfo> getMySessions();
    method public android.content.pm.InstallSessionInfo getSessionInfo(int);
    method public int createSession(android.content.pm.PackageInstaller.SessionParams) throws java.io.IOException;
    method public java.util.List<android.content.pm.PackageInstaller.SessionInfo> getAllSessions();
    method public java.util.List<android.content.pm.PackageInstaller.SessionInfo> getMySessions();
    method public android.content.pm.PackageInstaller.SessionInfo getSessionInfo(int);
    method public android.content.pm.PackageInstaller.Session openSession(int);
    method public void removeSessionCallback(android.content.pm.PackageInstaller.SessionCallback);
    method public void uninstall(java.lang.String, android.content.pm.PackageInstaller.UninstallCallback);
    method public void uninstall(java.lang.String, android.content.IntentSender);
    field public static final java.lang.String ACTION_SESSION_DETAILS = "android.content.pm.action.SESSION_DETAILS";
    field public static final java.lang.String EXTRA_PACKAGE_NAMES = "android.content.pm.extra.PACKAGE_NAMES";
    field public static final java.lang.String EXTRA_SESSION_ID = "android.content.pm.extra.SESSION_ID";
  }
  public static abstract class PackageInstaller.CommitCallback {
    ctor public PackageInstaller.CommitCallback();
    method public abstract void onFailure(int, java.lang.String, android.os.Bundle);
    method public abstract void onSuccess();
    method public abstract void onUserActionRequired(android.content.Intent);
    field public static final java.lang.String EXTRA_PACKAGE_NAME = "android.content.pm.extra.PACKAGE_NAME";
    field public static final int FAILURE_ABORTED = 5; // 0x5
    field public static final int FAILURE_CONFLICT = 2; // 0x2
    field public static final int FAILURE_INCOMPATIBLE = 4; // 0x4
    field public static final int FAILURE_INVALID = 1; // 0x1
    field public static final int FAILURE_STORAGE = 3; // 0x3
    field public static final int FAILURE_UNKNOWN = 0; // 0x0
    field public static final java.lang.String EXTRA_STATUS = "android.content.pm.extra.STATUS";
    field public static final java.lang.String EXTRA_STATUS_MESSAGE = "android.content.pm.extra.STATUS_MESSAGE";
    field public static final int STATUS_FAILURE = 1; // 0x1
    field public static final int STATUS_FAILURE_ABORTED = 2; // 0x2
    field public static final int STATUS_FAILURE_BLOCKED = 1; // 0x1
    field public static final int STATUS_FAILURE_CONFLICT = 4; // 0x4
    field public static final int STATUS_FAILURE_INCOMPATIBLE = 6; // 0x6
    field public static final int STATUS_FAILURE_INVALID = 3; // 0x3
    field public static final int STATUS_FAILURE_STORAGE = 5; // 0x5
    field public static final int STATUS_SUCCESS = 0; // 0x0
    field public static final int STATUS_USER_ACTION_REQUIRED = -1; // 0xffffffff
  }
  public static class PackageInstaller.Session implements java.io.Closeable {
    method public void abandon();
    method public void close();
    method public void commit(android.content.pm.PackageInstaller.CommitCallback);
    method public void commit(android.content.IntentSender);
    method public void fsync(java.io.OutputStream) throws java.io.IOException;
    method public java.lang.String[] list();
    method public java.lang.String[] getNames();
    method public java.io.InputStream openRead(java.lang.String) throws java.io.IOException;
    method public java.io.OutputStream openWrite(java.lang.String, long, long) throws java.io.IOException;
    method public void setProgress(float);
@@ -8716,14 +8684,34 @@ package android.content.pm {
    method public abstract void onProgressChanged(int, float);
  }
  public static abstract class PackageInstaller.UninstallCallback {
    ctor public PackageInstaller.UninstallCallback();
    method public abstract void onFailure(int, java.lang.String, android.os.Bundle);
    method public abstract void onSuccess();
    method public abstract void onUserActionRequired(android.content.Intent);
    field public static final int FAILURE_ABORTED = 2; // 0x2
    field public static final int FAILURE_BLOCKED = 1; // 0x1
    field public static final int FAILURE_UNKNOWN = 0; // 0x0
  public static class PackageInstaller.SessionInfo implements android.os.Parcelable {
    method public int describeContents();
    method public android.graphics.Bitmap getAppIcon();
    method public java.lang.CharSequence getAppLabel();
    method public java.lang.String getAppPackageName();
    method public android.content.Intent getDetailsIntent();
    method public java.lang.String getInstallerPackageName();
    method public float getProgress();
    method public int getSessionId();
    method public boolean isOpen();
    method public void writeToParcel(android.os.Parcel, int);
    field public static final android.os.Parcelable.Creator CREATOR;
  }
  public static class PackageInstaller.SessionParams implements android.os.Parcelable {
    ctor public PackageInstaller.SessionParams(int);
    method public int describeContents();
    method public void setAppIcon(android.graphics.Bitmap);
    method public void setAppLabel(java.lang.CharSequence);
    method public void setAppPackageName(java.lang.String);
    method public void setInstallLocation(int);
    method public void setOriginatingUri(android.net.Uri);
    method public void setReferrerUri(android.net.Uri);
    method public void setSize(long);
    method public void writeToParcel(android.os.Parcel, int);
    field public static final android.os.Parcelable.Creator CREATOR;
    field public static final int MODE_FULL_INSTALL = 1; // 0x1
    field public static final int MODE_INHERIT_EXISTING = 2; // 0x2
  }
  public class PackageItemInfo {
+66 −95
Original line number Diff line number Diff line
@@ -19,21 +19,22 @@ package com.android.commands.pm;
import android.app.ActivityManager;
import android.app.ActivityManagerNative;
import android.app.IActivityManager;
import android.app.PackageDeleteObserver;
import android.app.PackageInstallObserver;
import android.content.ComponentName;
import android.content.IIntentReceiver;
import android.content.IIntentSender;
import android.content.Intent;
import android.content.IntentSender;
import android.content.pm.ApplicationInfo;
import android.content.pm.FeatureInfo;
import android.content.pm.IPackageDataObserver;
import android.content.pm.IPackageInstaller;
import android.content.pm.IPackageManager;
import android.content.pm.InstallSessionInfo;
import android.content.pm.InstallSessionParams;
import android.content.pm.InstrumentationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageInstaller;
import android.content.pm.PackageInstaller.CommitCallback;
import android.content.pm.PackageInstaller.SessionInfo;
import android.content.pm.PackageInstaller.SessionParams;
import android.content.pm.PackageItemInfo;
import android.content.pm.PackageManager;
import android.content.pm.ParceledListSlice;
@@ -74,6 +75,8 @@ import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.WeakHashMap;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.TimeUnit;

public final class Pm {
    private static final String TAG = "Pm";
@@ -776,36 +779,6 @@ public final class Pm {
        }
    }

    class LocalCommitCallback extends CommitCallback {
        boolean finished;
        boolean success;
        String msg;

        private void setResult(boolean success, String msg) {
            synchronized (this) {
                this.finished = true;
                this.success = success;
                this.msg = msg;
                notifyAll();
            }
        }

        @Override
        public void onUserActionRequired(Intent intent) {
            setResult(false, "Unexepected user action required!");
        }

        @Override
        public void onSuccess() {
            setResult(true, null);
        }

        @Override
        public void onFailure(int failureReason, String msg, Bundle extras) {
            setResult(false, msg);
        }
    }

    /**
     * Converts a failure code into a string by using reflection to find a matching constant
     * in PackageManager.
@@ -1007,8 +980,7 @@ public final class Pm {
    private void runInstallCreate() throws RemoteException {
        String installerPackageName = null;

        final InstallSessionParams params = new InstallSessionParams(
                InstallSessionParams.MODE_FULL_INSTALL);
        final SessionParams params = new SessionParams(SessionParams.MODE_FULL_INSTALL);
        params.installFlags = PackageManager.INSTALL_ALL_USERS;

        String opt;
@@ -1031,7 +1003,7 @@ public final class Pm {
            } else if (opt.equals("-d")) {
                params.installFlags |= PackageManager.INSTALL_ALLOW_DOWNGRADE;
            } else if (opt.equals("-p")) {
                params.mode = InstallSessionParams.MODE_INHERIT_EXISTING;
                params.mode = SessionParams.MODE_INHERIT_EXISTING;
            } else if (opt.equals("-S")) {
                params.setSize(Long.parseLong(nextOptionData()));
            } else if (opt.equals("--abi")) {
@@ -1073,7 +1045,7 @@ public final class Pm {
            }
        }

        final InstallSessionInfo info = mInstaller.getSessionInfo(sessionId);
        final SessionInfo info = mInstaller.getSessionInfo(sessionId);

        PackageInstaller.Session session = null;
        InputStream in = null;
@@ -1117,22 +1089,20 @@ public final class Pm {
        try {
            session = new PackageInstaller.Session(mInstaller.openSession(sessionId));

            final LocalCommitCallback callback = new LocalCommitCallback();
            session.commit(callback);

            synchronized (callback) {
                while (!callback.finished) {
                    try {
                        callback.wait();
                    } catch (InterruptedException e) {
                    }
                }
                if (!callback.success) {
                    throw new IllegalStateException("Failure [" + callback.msg + "]");
                }
            }
            final LocalIntentReceiver receiver = new LocalIntentReceiver();
            session.commit(receiver.getIntentSender());

            final Intent result = receiver.getResult();
            final int status = result.getIntExtra(PackageInstaller.EXTRA_STATUS,
                    PackageInstaller.STATUS_FAILURE);
            if (status == PackageInstaller.STATUS_SUCCESS) {
                System.out.println("Success");
            } else {
                Log.e(TAG, "Failure details: " + result.getExtras());
                System.out.println("Failure ["
                        + result.getStringExtra(PackageInstaller.EXTRA_STATUS_MESSAGE) + "]");
                return;
            }
        } finally {
            IoUtils.closeQuietly(session);
        }
@@ -1274,28 +1244,14 @@ public final class Pm {
        }
    }

    class LocalPackageDeleteObserver extends PackageDeleteObserver {
        boolean finished;
        boolean result;

        @Override
        public void onPackageDeleted(String name, int returnCode, String msg) {
            synchronized (this) {
                finished = true;
                result = returnCode == PackageManager.DELETE_SUCCEEDED;
                notifyAll();
            }
        }
    }

    private void runUninstall() {
        int unInstallFlags = 0;
    private void runUninstall() throws RemoteException {
        int flags = 0;
        int userId = UserHandle.USER_ALL;

        String opt;
        while ((opt=nextOption()) != null) {
            if (opt.equals("-k")) {
                unInstallFlags |= PackageManager.DELETE_KEEP_DATA;
                flags |= PackageManager.DELETE_KEEP_DATA;
            } else if (opt.equals("--user")) {
                String param = nextArg();
                if (isNumber(param)) {
@@ -1320,7 +1276,7 @@ public final class Pm {

        if (userId == UserHandle.USER_ALL) {
            userId = UserHandle.USER_OWNER;
            unInstallFlags |= PackageManager.DELETE_ALL_USERS;
            flags |= PackageManager.DELETE_ALL_USERS;
        } else {
            PackageInfo info;
            try {
@@ -1340,36 +1296,23 @@ public final class Pm {
            // user set flag so it disables rather than reverting to system
            // version of the app.
            if (isSystem) {
                unInstallFlags |= PackageManager.DELETE_SYSTEM_APP;
                flags |= PackageManager.DELETE_SYSTEM_APP;
            }
        }

        boolean result = deletePackage(pkg, unInstallFlags, userId);
        if (result) {
        final LocalIntentReceiver receiver = new LocalIntentReceiver();
        mInstaller.uninstall(pkg, flags, receiver.getIntentSender(), userId);

        final Intent result = receiver.getResult();
        final int status = result.getIntExtra(PackageInstaller.EXTRA_STATUS,
                PackageInstaller.STATUS_FAILURE);
        if (status == PackageInstaller.STATUS_SUCCESS) {
            System.out.println("Success");
        } else {
            System.out.println("Failure");
        }
    }

    private boolean deletePackage(String packageName, int flags, int userId) {
        LocalPackageDeleteObserver obs = new LocalPackageDeleteObserver();
        try {
            mInstaller.uninstall(packageName, flags, obs.getBinder(), userId);

            synchronized (obs) {
                while (!obs.finished) {
                    try {
                        obs.wait();
                    } catch (InterruptedException e) {
                    }
                }
            }
        } catch (RemoteException e) {
            System.err.println(e.toString());
            System.err.println(PM_NOT_RUNNING_ERR);
            Log.e(TAG, "Failure details: " + result.getExtras());
            System.out.println("Failure ["
                    + result.getStringExtra(PackageInstaller.EXTRA_STATUS_MESSAGE) + "]");
        }
        return obs.result;
    }

    static class ClearDataObserver extends IPackageDataObserver.Stub {
@@ -1384,7 +1327,6 @@ public final class Pm {
                notifyAll();
            }
        }

    }

    private void runClear() {
@@ -1717,6 +1659,35 @@ public final class Pm {
        throw new IllegalArgumentException("ABI " + abi + " not supported on this device");
    }

    private static class LocalIntentReceiver {
        private final SynchronousQueue<Intent> mResult = new SynchronousQueue<>();

        private IIntentSender.Stub mLocalSender = new IIntentSender.Stub() {
            @Override
            public int send(int code, Intent intent, String resolvedType,
                    IIntentReceiver finishedReceiver, String requiredPermission) {
                try {
                    mResult.offer(intent, 5, TimeUnit.SECONDS);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
                return 0;
            }
        };

        public IntentSender getIntentSender() {
            return new IntentSender((IIntentSender) mLocalSender);
        }

        public Intent getResult() {
            try {
                return mResult.poll(30, TimeUnit.SECONDS);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }

    private String nextOption() {
        if (mNextArg >= mArgs.length) {
            return null;
+1 −1
Original line number Diff line number Diff line
@@ -1568,7 +1568,7 @@ final class ApplicationPackageManager extends PackageManager {
        synchronized (mLock) {
            if (mInstaller == null) {
                try {
                    mInstaller = new PackageInstaller(this, mPM.getPackageInstaller(),
                    mInstaller = new PackageInstaller(mContext, this, mPM.getPackageInstaller(),
                            mContext.getPackageName(), mContext.getUserId());
                } catch (RemoteException e) {
                    throw e.rethrowAsRuntimeException();
+7 −8
Original line number Diff line number Diff line
@@ -19,23 +19,22 @@ package android.content.pm;
import android.content.pm.IPackageDeleteObserver2;
import android.content.pm.IPackageInstallerCallback;
import android.content.pm.IPackageInstallerSession;
import android.content.pm.InstallSessionInfo;
import android.content.pm.InstallSessionParams;
import android.content.pm.PackageInstaller;
import android.content.IntentSender;

/** {@hide} */
interface IPackageInstaller {
    int createSession(in InstallSessionParams params, String installerPackageName, int userId);
    int createSession(in PackageInstaller.SessionParams params, String installerPackageName, int userId);
    IPackageInstallerSession openSession(int sessionId);

    InstallSessionInfo getSessionInfo(int sessionId);
    List<InstallSessionInfo> getAllSessions(int userId);
    List<InstallSessionInfo> getMySessions(String installerPackageName, int userId);
    PackageInstaller.SessionInfo getSessionInfo(int sessionId);
    List<PackageInstaller.SessionInfo> getAllSessions(int userId);
    List<PackageInstaller.SessionInfo> getMySessions(String installerPackageName, int userId);

    void registerCallback(IPackageInstallerCallback callback, int userId);
    void unregisterCallback(IPackageInstallerCallback callback);

    void uninstall(String packageName, int flags, in IPackageDeleteObserver2 observer, int userId);
    void uninstallSplit(String packageName, String splitName, int flags, in IPackageDeleteObserver2 observer, int userId);
    void uninstall(String packageName, int flags, in IntentSender statusReceiver, int userId);

    void setPermissionsResult(int sessionId, boolean accepted);
}
+3 −2
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package android.content.pm;

import android.content.pm.IPackageInstallObserver2;
import android.content.IntentSender;
import android.os.ParcelFileDescriptor;

/** {@hide} */
@@ -24,11 +25,11 @@ interface IPackageInstallerSession {
    void setClientProgress(float progress);
    void addClientProgress(float progress);

    String[] list();
    String[] getNames();
    ParcelFileDescriptor openWrite(String name, long offsetBytes, long lengthBytes);
    ParcelFileDescriptor openRead(String name);

    void close();
    void commit(in IPackageInstallObserver2 observer);
    void commit(in IntentSender statusReceiver);
    void abandon();
}
Loading