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

Commit 752cd922 authored by Jeff Sharkey's avatar Jeff Sharkey
Browse files

Always bind to DefaultContainerService as OWNER.

When PackageManagerService deals with external storage, always bind
to DefaultContainerService as USER_OWNER.  This avoids binding to a
stopped user, which would fail.

Bug: 7203111
Change-Id: I8e303c7558e8b5cbe4fea0acc9a472b598df0caa
parent 5a370882
Loading
Loading
Loading
Loading
+8 −2
Original line number Original line Diff line number Diff line
@@ -21,10 +21,12 @@ import android.os.Parcelable;


/** @hide */
/** @hide */
public class PackageCleanItem {
public class PackageCleanItem {
    public final int userId;
    public final String packageName;
    public final String packageName;
    public final boolean andCode;
    public final boolean andCode;


    public PackageCleanItem(String packageName, boolean andCode) {
    public PackageCleanItem(int userId, String packageName, boolean andCode) {
        this.userId = userId;
        this.packageName = packageName;
        this.packageName = packageName;
        this.andCode = andCode;
        this.andCode = andCode;
    }
    }
@@ -37,7 +39,8 @@ public class PackageCleanItem {
        try {
        try {
            if (obj != null) {
            if (obj != null) {
                PackageCleanItem other = (PackageCleanItem)obj;
                PackageCleanItem other = (PackageCleanItem)obj;
                return packageName.equals(other.packageName) && andCode == other.andCode;
                return userId == other.userId && packageName.equals(other.packageName)
                        && andCode == other.andCode;
            }
            }
        } catch (ClassCastException e) {
        } catch (ClassCastException e) {
        }
        }
@@ -47,6 +50,7 @@ public class PackageCleanItem {
    @Override
    @Override
    public int hashCode() {
    public int hashCode() {
        int result = 17;
        int result = 17;
        result = 31 * result + userId;
        result = 31 * result + packageName.hashCode();
        result = 31 * result + packageName.hashCode();
        result = 31 * result + (andCode ? 1 : 0);
        result = 31 * result + (andCode ? 1 : 0);
        return result;
        return result;
@@ -57,6 +61,7 @@ public class PackageCleanItem {
    }
    }


    public void writeToParcel(Parcel dest, int parcelableFlags) {
    public void writeToParcel(Parcel dest, int parcelableFlags) {
        dest.writeInt(userId);
        dest.writeString(packageName);
        dest.writeString(packageName);
        dest.writeInt(andCode ? 1 : 0);
        dest.writeInt(andCode ? 1 : 0);
    }
    }
@@ -73,6 +78,7 @@ public class PackageCleanItem {
    };
    };


    private PackageCleanItem(Parcel source) {
    private PackageCleanItem(Parcel source) {
        userId = source.readInt();
        packageName = source.readString();
        packageName = source.readString();
        andCode = source.readInt() != 0;
        andCode = source.readInt() != 0;
    }
    }
+9 −7
Original line number Original line Diff line number Diff line
@@ -35,6 +35,7 @@ import android.content.res.ObbInfo;
import android.content.res.ObbScanner;
import android.content.res.ObbScanner;
import android.net.Uri;
import android.net.Uri;
import android.os.Environment;
import android.os.Environment;
import android.os.Environment.UserEnvironment;
import android.os.FileUtils;
import android.os.FileUtils;
import android.os.IBinder;
import android.os.IBinder;
import android.os.ParcelFileDescriptor;
import android.os.ParcelFileDescriptor;
@@ -268,15 +269,16 @@ public class DefaultContainerService extends IntentService {
    @Override
    @Override
    protected void onHandleIntent(Intent intent) {
    protected void onHandleIntent(Intent intent) {
        if (PackageManager.ACTION_CLEAN_EXTERNAL_STORAGE.equals(intent.getAction())) {
        if (PackageManager.ACTION_CLEAN_EXTERNAL_STORAGE.equals(intent.getAction())) {
            IPackageManager pm = IPackageManager.Stub.asInterface(
            final IPackageManager pm = IPackageManager.Stub.asInterface(
                    ServiceManager.getService("package"));
                    ServiceManager.getService("package"));
            PackageCleanItem pkg = null;
            PackageCleanItem item = null;
            try {
            try {
                while ((pkg=pm.nextPackageToClean(pkg)) != null) {
                while ((item = pm.nextPackageToClean(item)) != null) {
                    eraseFiles(Environment.getExternalStorageAppDataDirectory(pkg.packageName));
                    final UserEnvironment userEnv = new UserEnvironment(item.userId);
                    eraseFiles(Environment.getExternalStorageAppMediaDirectory(pkg.packageName));
                    eraseFiles(userEnv.getExternalStorageAppDataDirectory(item.packageName));
                    if (pkg.andCode) {
                    eraseFiles(userEnv.getExternalStorageAppMediaDirectory(item.packageName));
                        eraseFiles(Environment.getExternalStorageAppObbDirectory(pkg.packageName));
                    if (item.andCode) {
                        eraseFiles(userEnv.getExternalStorageAppObbDirectory(item.packageName));
                    }
                    }
                }
                }
            } catch (RemoteException e) {
            } catch (RemoteException e) {
+34 −66
Original line number Original line Diff line number Diff line
@@ -413,7 +413,6 @@ public class PackageManagerService extends IPackageManager.Stub {
    // package uri's from external media onto secure containers
    // package uri's from external media onto secure containers
    // or internal storage.
    // or internal storage.
    private IMediaContainerService mContainerService = null;
    private IMediaContainerService mContainerService = null;
    private int mContainerServiceUserId;


    static final int SEND_PENDING_BROADCAST = 1;
    static final int SEND_PENDING_BROADCAST = 1;
    static final int MCS_BOUND = 3;
    static final int MCS_BOUND = 3;
@@ -482,15 +481,8 @@ public class PackageManagerService extends IPackageManager.Stub {
                    " DefaultContainerService");
                    " DefaultContainerService");
            Intent service = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT);
            Intent service = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT);
            Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
            Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
            mContainerServiceUserId = 0;
            if (mPendingInstalls.size() > 0) {
                mContainerServiceUserId = mPendingInstalls.get(0).getUser().getIdentifier();
                if (mContainerServiceUserId == UserHandle.USER_ALL) {
                    mContainerServiceUserId = 0;
                }
            }
            if (mContext.bindService(service, mDefContainerConn,
            if (mContext.bindService(service, mDefContainerConn,
                    Context.BIND_AUTO_CREATE, mContainerServiceUserId)) {
                    Context.BIND_AUTO_CREATE, UserHandle.USER_OWNER)) {
                Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
                Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
                mBound = true;
                mBound = true;
                return true;
                return true;
@@ -567,15 +559,6 @@ public class PackageManagerService extends IPackageManager.Stub {
                    } else if (mPendingInstalls.size() > 0) {
                    } else if (mPendingInstalls.size() > 0) {
                        HandlerParams params = mPendingInstalls.get(0);
                        HandlerParams params = mPendingInstalls.get(0);
                        if (params != null) {
                        if (params != null) {
                            // Check if we're connected to the correct service, if it's an install
                            // request.
                            final int installFor = params.getUser().getIdentifier();
                            if (installFor != mContainerServiceUserId
                                    && (installFor == UserHandle.USER_ALL
                                            && mContainerServiceUserId != 0)) {
                                mHandler.sendEmptyMessage(MCS_RECONNECT);
                                return;
                            }
                            if (params.startCopy()) {
                            if (params.startCopy()) {
                                // We are done...  look for more work or to
                                // We are done...  look for more work or to
                                // go idle.
                                // go idle.
@@ -693,20 +676,23 @@ public class PackageManagerService extends IPackageManager.Stub {
                }
                }
                case START_CLEANING_PACKAGE: {
                case START_CLEANING_PACKAGE: {
                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
                    PackageCleanItem item = new PackageCleanItem((String)msg.obj,
                    final String packageName = (String)msg.obj;
                            msg.arg2 != 0);
                    final int userId = msg.arg1;
                    final boolean andCode = msg.arg2 != 0;
                    synchronized (mPackages) {
                    synchronized (mPackages) {
                        if (msg.arg1 == UserHandle.USER_ALL) {
                        if (userId == UserHandle.USER_ALL) {
                            int[] users = sUserManager.getUserIds();
                            int[] users = sUserManager.getUserIds();
                            for (int user : users) {
                            for (int user : users) {
                                mSettings.addPackageToCleanLPw(user, item);
                                mSettings.addPackageToCleanLPw(
                                        new PackageCleanItem(user, packageName, andCode));
                            }
                            }
                        } else {
                        } else {
                            mSettings.addPackageToCleanLPw(msg.arg1, item);
                            mSettings.addPackageToCleanLPw(
                                    new PackageCleanItem(userId, packageName, andCode));
                        }
                        }
                    }
                    }
                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
                    startCleaningPackages(-1);
                    startCleaningPackages();
                } break;
                } break;
                case POST_INSTALL: {
                case POST_INSTALL: {
                    if (DEBUG_INSTALL) Log.v(TAG, "Handling post-install for " + msg.arg1);
                    if (DEBUG_INSTALL) Log.v(TAG, "Handling post-install for " + msg.arg1);
@@ -4193,8 +4179,12 @@ public class PackageManagerService extends IPackageManager.Stub {
            // Add the new setting to mPackages
            // Add the new setting to mPackages
            mPackages.put(pkg.applicationInfo.packageName, pkg);
            mPackages.put(pkg.applicationInfo.packageName, pkg);
            // Make sure we don't accidentally delete its data.
            // Make sure we don't accidentally delete its data.
            for (int i=0; i<mSettings.mPackagesToBeCleaned.size(); i++) {
            final Iterator<PackageCleanItem> iter = mSettings.mPackagesToBeCleaned.iterator();
                mSettings.mPackagesToBeCleaned.valueAt(i).remove(pkgName);
            while (iter.hasNext()) {
                PackageCleanItem item = iter.next();
                if (pkgName.equals(item.packageName)) {
                    iter.remove();
                }
            }
            }


            // Take care of first install / last update times.
            // Take care of first install / last update times.
@@ -5443,7 +5433,6 @@ public class PackageManagerService extends IPackageManager.Stub {


    public PackageCleanItem nextPackageToClean(PackageCleanItem lastPackage) {
    public PackageCleanItem nextPackageToClean(PackageCleanItem lastPackage) {
        // writer
        // writer
        final int userId = UserHandle.getCallingUserId();
        synchronized (mPackages) {
        synchronized (mPackages) {
            if (!isExternalMediaAvailable()) {
            if (!isExternalMediaAvailable()) {
                // If the external storage is no longer mounted at this point,
                // If the external storage is no longer mounted at this point,
@@ -5451,8 +5440,7 @@ public class PackageManagerService extends IPackageManager.Stub {
                // packages files and can not delete any more.  Bail.
                // packages files and can not delete any more.  Bail.
                return null;
                return null;
            }
            }
            ArrayList<PackageCleanItem> pkgs = mSettings.mPackagesToBeCleaned.get(userId);
            final ArrayList<PackageCleanItem> pkgs = mSettings.mPackagesToBeCleaned;
            if (pkgs != null) {
            if (lastPackage != null) {
            if (lastPackage != null) {
                pkgs.remove(lastPackage);
                pkgs.remove(lastPackage);
            }
            }
@@ -5460,15 +5448,6 @@ public class PackageManagerService extends IPackageManager.Stub {
                return pkgs.get(0);
                return pkgs.get(0);
            }
            }
        }
        }
            mSettings.mPackagesToBeCleaned.remove(userId);
        }
        // Move on to the next user to clean.
        long ident = Binder.clearCallingIdentity();
        try {
            startCleaningPackages(userId);
        } finally {
            Binder.restoreCallingIdentity(ident);
        }
        return null;
        return null;
    }
    }


@@ -5483,34 +5462,22 @@ public class PackageManagerService extends IPackageManager.Stub {
                userId, andCode ? 1 : 0, packageName));
                userId, andCode ? 1 : 0, packageName));
    }
    }
    
    
    void startCleaningPackages(int lastUser) {
    void startCleaningPackages() {
        // reader
        // reader
        int nextUser = -1;
        synchronized (mPackages) {
        synchronized (mPackages) {
            if (!isExternalMediaAvailable()) {
            if (!isExternalMediaAvailable()) {
                return;
                return;
            }
            }
            final int N = mSettings.mPackagesToBeCleaned.size();
            if (mSettings.mPackagesToBeCleaned.isEmpty()) {
            if (N <= 0) {
                return;
                return;
            }
            }
            for (int i=0; i<N; i++) {
                int user = mSettings.mPackagesToBeCleaned.keyAt(i);
                if (user > lastUser) {
                    nextUser = user;
                    break;
                }
            }
            if (nextUser < 0) {
                nextUser = mSettings.mPackagesToBeCleaned.keyAt(0);
            }
        }
        }
        Intent intent = new Intent(PackageManager.ACTION_CLEAN_EXTERNAL_STORAGE);
        Intent intent = new Intent(PackageManager.ACTION_CLEAN_EXTERNAL_STORAGE);
        intent.setComponent(DEFAULT_CONTAINER_COMPONENT);
        intent.setComponent(DEFAULT_CONTAINER_COMPONENT);
        IActivityManager am = ActivityManagerNative.getDefault();
        IActivityManager am = ActivityManagerNative.getDefault();
        if (am != null) {
        if (am != null) {
            try {
            try {
                am.startService(null, intent, null, nextUser);
                am.startService(null, intent, null, UserHandle.USER_OWNER);
            } catch (RemoteException e) {
            } catch (RemoteException e) {
            }
            }
        }
        }
@@ -8399,10 +8366,11 @@ public class PackageManagerService extends IPackageManager.Stub {
        } else {
        } else {
            users = new int[] { userId };
            users = new int[] { userId };
        }
        }
        for (int curUser : users) {
        final ClearStorageConnection conn = new ClearStorageConnection();
            ClearStorageConnection conn = new ClearStorageConnection();
        if (mContext.bindService(
            if (mContext.bindService(containerIntent, conn, Context.BIND_AUTO_CREATE, curUser)) {
                containerIntent, conn, Context.BIND_AUTO_CREATE, UserHandle.USER_OWNER)) {
            try {
            try {
                for (int curUser : users) {
                    long timeout = SystemClock.uptimeMillis() + 5000;
                    long timeout = SystemClock.uptimeMillis() + 5000;
                    synchronized (conn) {
                    synchronized (conn) {
                        long now = SystemClock.uptimeMillis();
                        long now = SystemClock.uptimeMillis();
@@ -8438,12 +8406,12 @@ public class PackageManagerService extends IPackageManager.Stub {
                        } catch (RemoteException e) {
                        } catch (RemoteException e) {
                        }
                        }
                    }
                    }
                }
            } finally {
            } finally {
                mContext.unbindService(conn);
                mContext.unbindService(conn);
            }
            }
        }
        }
    }
    }
    }


    @Override
    @Override
    public void clearApplicationUserData(final String packageName,
    public void clearApplicationUserData(final String packageName,
@@ -9596,7 +9564,7 @@ public class PackageManagerService extends IPackageManager.Stub {
            if (DEBUG_SD_INSTALL)
            if (DEBUG_SD_INSTALL)
                Log.i(TAG, "Loading packages");
                Log.i(TAG, "Loading packages");
            loadMediaPackages(processCids, uidArr, removeCids);
            loadMediaPackages(processCids, uidArr, removeCids);
            startCleaningPackages(-1);
            startCleaningPackages();
        } else {
        } else {
            if (DEBUG_SD_INSTALL)
            if (DEBUG_SD_INSTALL)
                Log.i(TAG, "Unloading packages");
                Log.i(TAG, "Unloading packages");
+14 −25
Original line number Original line Diff line number Diff line
@@ -159,8 +159,7 @@ final class Settings {


    // Packages that have been uninstalled and still need their external
    // Packages that have been uninstalled and still need their external
    // storage data deleted.
    // storage data deleted.
    final SparseArray<ArrayList<PackageCleanItem>> mPackagesToBeCleaned
    final ArrayList<PackageCleanItem> mPackagesToBeCleaned = new ArrayList<PackageCleanItem>();
            = new SparseArray<ArrayList<PackageCleanItem>>();
    
    
    // Packages that have been renamed since they were first installed.
    // Packages that have been renamed since they were first installed.
    // Keys are the new names of the packages, values are the original
    // Keys are the new names of the packages, values are the original
@@ -1257,20 +1256,15 @@ final class Settings {
            }
            }


            if (mPackagesToBeCleaned.size() > 0) {
            if (mPackagesToBeCleaned.size() > 0) {
                for (int i=0; i<mPackagesToBeCleaned.size(); i++) {
                for (PackageCleanItem item : mPackagesToBeCleaned) {
                    final int userId = mPackagesToBeCleaned.keyAt(i);
                    final String userStr = Integer.toString(item.userId);
                    final String userStr = Integer.toString(userId);
                    final ArrayList<PackageCleanItem> pkgs = mPackagesToBeCleaned.valueAt(i);
                    for (int j=0; j<pkgs.size(); j++) {
                    serializer.startTag(null, "cleaning-package");
                    serializer.startTag(null, "cleaning-package");
                        PackageCleanItem item = pkgs.get(j);
                    serializer.attribute(null, ATTR_NAME, item.packageName);
                    serializer.attribute(null, ATTR_NAME, item.packageName);
                    serializer.attribute(null, ATTR_CODE, item.andCode ? "true" : "false");
                    serializer.attribute(null, ATTR_CODE, item.andCode ? "true" : "false");
                    serializer.attribute(null, ATTR_USER, userStr);
                    serializer.attribute(null, ATTR_USER, userStr);
                    serializer.endTag(null, "cleaning-package");
                    serializer.endTag(null, "cleaning-package");
                }
                }
            }
            }
            }
            
            
            if (mRenamedPackages.size() > 0) {
            if (mRenamedPackages.size() > 0) {
                for (Map.Entry<String, String> e : mRenamedPackages.entrySet()) {
                for (Map.Entry<String, String> e : mRenamedPackages.entrySet()) {
@@ -1524,14 +1518,9 @@ final class Settings {
        return ret;
        return ret;
    }
    }


    void addPackageToCleanLPw(int userId, PackageCleanItem pkg) {
    void addPackageToCleanLPw(PackageCleanItem pkg) {
        ArrayList<PackageCleanItem> pkgs = mPackagesToBeCleaned.get(userId);
        if (!mPackagesToBeCleaned.contains(pkg)) {
        if (pkgs == null) {
            mPackagesToBeCleaned.add(pkg);
            pkgs = new ArrayList<PackageCleanItem>();
            mPackagesToBeCleaned.put(userId, pkgs);
        }
        if (!pkgs.contains(pkg)) {
            pkgs.add(pkg);
        }
        }
    }
    }


@@ -1615,18 +1604,18 @@ final class Settings {
                    String userStr = parser.getAttributeValue(null, ATTR_USER);
                    String userStr = parser.getAttributeValue(null, ATTR_USER);
                    String codeStr = parser.getAttributeValue(null, ATTR_CODE);
                    String codeStr = parser.getAttributeValue(null, ATTR_CODE);
                    if (name != null) {
                    if (name != null) {
                        int user = 0;
                        int userId = 0;
                        boolean andCode = true;
                        boolean andCode = true;
                        try {
                        try {
                            if (userStr != null) {
                            if (userStr != null) {
                                user = Integer.parseInt(userStr);
                                userId = Integer.parseInt(userStr);
                            }
                            }
                        } catch (NumberFormatException e) {
                        } catch (NumberFormatException e) {
                        }
                        }
                        if (codeStr != null) {
                        if (codeStr != null) {
                            andCode = Boolean.parseBoolean(codeStr);
                            andCode = Boolean.parseBoolean(codeStr);
                        }
                        }
                        addPackageToCleanLPw(user, new PackageCleanItem(name, andCode));
                        addPackageToCleanLPw(new PackageCleanItem(userId, name, andCode));
                    }
                    }
                } else if (tagName.equals("renamed-package")) {
                } else if (tagName.equals("renamed-package")) {
                    String nname = parser.getAttributeValue(null, "new");
                    String nname = parser.getAttributeValue(null, "new");