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

Commit b49d9af7 authored by Suchi Amalapurapu's avatar Suchi Amalapurapu Committed by Android (Google) Code Review
Browse files

Merge "Mount/Unmount secure containers Persist flags in PackageSetting. Flags...

Merge "Mount/Unmount secure containers Persist flags in PackageSetting. Flags are relevant to ApplicationInfo.FLAG_SYSTEM, Application.FLAG_ON_SDCARD, ApplicationInfo.FLAG_FORWARD_LOCK. New pm command to simulate mount/unmount in Pm. This will be removed when MountService/vold event generation gets fixed. Calls from MountService into PackageManager when media gets mounted/unmounted. Scan the packages and grant permissions when the sdcard gets mounted. This api might change again."
parents 56d42582 fd3530f9
Loading
Loading
Loading
Loading
+40 −0
Original line number Diff line number Diff line
@@ -92,6 +92,11 @@ public final class Pm {
            return;
        }

        if ("mountsd".equals(op)) {
            runMountSd();
            return;
        }

        if ("uninstall".equals(op)) {
            runUninstall();
            return;
@@ -637,6 +642,37 @@ public final class Pm {
        }
    }

    private void runMountSd() {
        String opt;
        boolean mount = false;
        while ((opt=nextOption()) != null) {
            if (opt.equals("-m")) {
                String mountStr = nextOptionData();
                if (mountStr == null) {
                    System.err.println("Error: no value specified for -m");
                    showUsage();
                    return;
                }
                if ("true".equalsIgnoreCase(mountStr)) {
                    mount = true;
                } else if ("false".equalsIgnoreCase(mountStr)) {
                    mount = false;
                } else {
                    System.err.println("Error: no value specified for -m");
                    showUsage();
                    return;
                }
            }
        }

        try {
            mPm.updateExternalMediaStatus(mount);
        } catch (RemoteException e) {
            System.err.println(e.toString());
            System.err.println(PM_NOT_RUNNING_ERR);
        }
    }

    class PackageDeleteObserver extends IPackageDeleteObserver.Stub {
        boolean finished;
        boolean result;
@@ -826,6 +862,7 @@ public final class Pm {
        System.err.println("       pm path PACKAGE");
        System.err.println("       pm install [-l] [-r] [-t] [-i INSTALLER_PACKAGE_NAME] [-s] PATH");
        System.err.println("       pm uninstall [-k] PACKAGE");
        System.err.println("       pm mountsd [-m true/false]");
        System.err.println("       pm enable PACKAGE_OR_COMPONENT");
        System.err.println("       pm disable PACKAGE_OR_COMPONENT");
        System.err.println("");
@@ -862,6 +899,9 @@ public final class Pm {
        System.err.println("  -k: keep the data and cache directories around.");
        System.err.println("after the package removal.");
        System.err.println("");
        System.err.println("The mountsd command simulates mounting/unmounting sdcard.Options:");
        System.err.println("  -m: true or false.");
        System.err.println("");
        System.err.println("The enable and disable commands change the enabled state of");
        System.err.println("a given package or component (written as \"package/class\").");
    }
+10 −0
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@ import android.content.res.Resources;
import android.net.Uri;
import android.os.IMountService;
import android.os.Environment;
import android.os.ServiceManager;
import android.os.SystemProperties;
import android.os.UEventObserver;
import android.os.Handler;
@@ -131,6 +132,8 @@ class MountService extends IMountService.Stub

    private String  mLegacyState = Environment.MEDIA_REMOVED;

    private PackageManagerService mPms;

    /**
     * Constructs a new MountService instance
     * 
@@ -139,6 +142,7 @@ class MountService extends IMountService.Stub
    public MountService(Context context) {
        mContext = context;

        mPms = (PackageManagerService) ServiceManager.getService("package");
        // Register a BOOT_COMPLETED handler so that we can start
        // our NativeDaemonConnector. We defer the startup so that we don't
        // start processing events before we ought-to
@@ -509,6 +513,8 @@ class MountService extends IMountService.Stub
    void handlePossibleExplicitUnmountBroadcast(String path) {
        if (mMounted) {
            mMounted = false;
            // Update media status on PackageManagerService to unmount packages on sdcard
            mPms.updateExternalMediaStatus(false);
            Intent intent = new Intent(Intent.ACTION_MEDIA_UNMOUNTED, 
                    Uri.parse("file://" + path));
            mContext.sendBroadcast(intent);
@@ -739,6 +745,8 @@ class MountService extends IMountService.Stub

        updatePublicVolumeState(path, Environment.MEDIA_UNMOUNTED);

        // Update media status on PackageManagerService to unmount packages on sdcard
        mPms.updateExternalMediaStatus(false);
        if (mShowSafeUnmountNotificationWhenUnmounted) {
            setMediaStorageNotification(
                    com.android.internal.R.string.ext_media_safe_unmount_notification_title,
@@ -800,6 +808,8 @@ class MountService extends IMountService.Stub
    void notifyMediaMounted(String path, boolean readOnly) {
        updatePublicVolumeState(path, Environment.MEDIA_MOUNTED);

        // Update media status on PackageManagerService to mount packages on sdcard
        mPms.updateExternalMediaStatus(true);
        setMediaStorageNotification(0, 0, 0, false, false, null);
        updateUsbMassStorageNotification(false, false);
        Intent intent = new Intent(Intent.ACTION_MEDIA_MOUNTED, 
+104 −19
Original line number Diff line number Diff line
@@ -4753,6 +4753,7 @@ class PackageManagerService extends IPackageManager.Stub {
            ret = deleteInstalledPackageLI (p, deleteCodeAndResources, flags, outInfo);
        }
        if (ret && onSd) {
            if (deleteCodeAndResources) {
                // Post a delayed destroy on the container since there might
                // be active processes holding open file handles to package
                // resources which will get killed by the process killer when
@@ -4760,6 +4761,10 @@ class PackageManagerService extends IPackageManager.Stub {
                // process and crash the system. Delay the destroy a bit so
                // that the active processes get to handle the uninstall broadcasts.
                sendDelayedDestroySdDir(packageName);
            } else {
                // Just unmount the directory
                unMountSdDir(packageName);
            }
        }
        return ret;
    }
@@ -5866,7 +5871,9 @@ class PackageManagerService extends IPackageManager.Stub {
        HashSet<String> loadedPermissions = new HashSet<String>();

        GrantedPermissions(int pkgFlags) {
            this.pkgFlags = pkgFlags & ApplicationInfo.FLAG_SYSTEM;
            this.pkgFlags = (pkgFlags & ApplicationInfo.FLAG_SYSTEM) |
                    (pkgFlags & ApplicationInfo.FLAG_FORWARD_LOCK) |
                    (pkgFlags & ApplicationInfo.FLAG_ON_SDCARD);
        }
    }

@@ -6672,9 +6679,8 @@ class PackageManagerService extends IPackageManager.Stub {
            if (!pkg.resourcePathString.equals(pkg.codePathString)) {
                serializer.attribute(null, "resourcePath", pkg.resourcePathString);
            }
            serializer.attribute(null, "system",
                    (pkg.pkgFlags&ApplicationInfo.FLAG_SYSTEM) != 0
                    ? "true" : "false");
            serializer.attribute(null, "flags",
                    Integer.toString(pkg.pkgFlags));
            serializer.attribute(null, "ts", pkg.getTimeStampStr());
            serializer.attribute(null, "version", String.valueOf(pkg.versionCode));
            if (pkg.sharedUser == null) {
@@ -7065,17 +7071,25 @@ class PackageManagerService extends IPackageManager.Stub {
                    } catch (NumberFormatException e) {
                    }
                }
                systemStr = parser.getAttributeValue(null, "system");
                installerPackageName = parser.getAttributeValue(null, "installer");

                systemStr = parser.getAttributeValue(null, "flags");
                if (systemStr != null) {
                    if ("true".equals(systemStr)) {
                        pkgFlags |= ApplicationInfo.FLAG_SYSTEM;
                    try {
                        pkgFlags = Integer.parseInt(systemStr);
                    } catch (NumberFormatException e) {
                    }
                } else {
                    // For backward compatibility
                    systemStr = parser.getAttributeValue(null, "system");
                    if (systemStr != null) {
                        pkgFlags |= ("true".equalsIgnoreCase(systemStr)) ? ApplicationInfo.FLAG_SYSTEM : 0;
                    } else {
                        // Old settings that don't specify system...  just treat
                        // them as system, good enough.
                        pkgFlags |= ApplicationInfo.FLAG_SYSTEM;
                    }
                }
                timeStampStr = parser.getAttributeValue(null, "ts");
                if (timeStampStr != null) {
                    try {
@@ -7443,6 +7457,7 @@ class PackageManagerService extends IPackageManager.Stub {
    static final boolean DEBUG_SD_INSTALL = false;
    final private String mSdEncryptKey = "AppsOnSD";
    final private String mSdEncryptAlg = "AES";
    private boolean mMediaMounted = false;

    private MountService getMountService() {
        return (MountService) ServiceManager.getService("mount");
@@ -7518,6 +7533,11 @@ class PackageManagerService extends IPackageManager.Stub {
       return null;
   }

   private boolean unMountSdDir(String pkgName) {
       // STOPSHIP unmount directory
       return true;
   }

   private String getSdDir(String pkgName) {
       String cachePath = null;
       try {
@@ -7553,6 +7573,15 @@ class PackageManagerService extends IPackageManager.Stub {
       }
   }

   private String[] getSecureContainerList() {
       try {
           return getMountService().getSecureContainerList();
       } catch (IllegalStateException e) {
           Log.i(TAG, "Failed to getSecureContainerList");
       }
       return null;
   }

   private void sendDelayedDestroySdDir(String pkgName) {
       if (mHandler.hasMessages(DESTROY_SD_CONTAINER, pkgName)) {
           // Don't have to send message again
@@ -7562,7 +7591,63 @@ class PackageManagerService extends IPackageManager.Stub {
       mHandler.sendMessageDelayed(msg, DESTROY_SD_CONTAINER_DELAY);
   }

   public void updateExternalMediaStatus(boolean mediaStatus) {
       // TODO
   public void updateExternalMediaStatus(final boolean mediaStatus) {
       if (mediaStatus == mMediaMounted) {
           return;
       }
       mMediaMounted = mediaStatus;
        // Queue up an async operation since the package installation may take a little while.
       mHandler.post(new Runnable() {
           public void run() {
               mHandler.removeCallbacks(this);
               final String list[] = getSecureContainerList();
               if (list == null || list.length == 0) {
                   return;
               }
               for (int i = 0; i < list.length; i++) {
                   String mountPkg = list[i];
                   // TODO compare with default package
                   synchronized (mPackages) {
                       PackageSetting ps = mSettings.mPackages.get(mountPkg);
                       if (ps != null && (ps.pkgFlags & ApplicationInfo.FLAG_ON_SDCARD) != 0) {
                           if (mediaStatus) {
                               String pkgPath = getSdDir(mountPkg);
                               if (pkgPath == null) {
                                   continue;
                               }
                               pkgPath = ps.codePathString;
                               int parseFlags = PackageParser.PARSE_CHATTY |
                               PackageParser.PARSE_ON_SDCARD | mDefParseFlags;
                               PackageParser pp = new PackageParser(pkgPath);
                               pp.setSeparateProcesses(mSeparateProcesses);
                               final PackageParser.Package pkg = pp.parsePackage(new File(pkgPath),
                                       null, mMetrics, parseFlags);
                               if (pkg == null) {
                                   Log.w(TAG, "Failed to install package : " + mountPkg + " from sd card");
                                   continue;
                               }
                               int scanMode = SCAN_MONITOR;
                               // Scan the package
                               if (scanPackageLI(pkg, parseFlags, scanMode) != null) {
                                   // Grant permissions
                                   grantPermissionsLP(pkg, false);
                                   // Persist settings
                                   mSettings.writeLP();
                               } else {
                                   Log.i(TAG, "Failed to install package: " + mountPkg + " from sdcard");
                               }
                           } else {
                               // Delete package
                               PackageRemovedInfo outInfo = new PackageRemovedInfo();
                               boolean res = deletePackageLI(mountPkg, false, PackageManager.DONT_DELETE_DATA, outInfo);
                               if (!res) {
                                   Log.e(TAG, "Failed to delete pkg  from sdcard : " + mountPkg);
                               }
                           }
                       }
                   }
               }
           }
       });
   }
}