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

Commit 6615d36c authored by Adnan Begovic's avatar Adnan Begovic Committed by Steve Kondik
Browse files

prebundled: Handle prebundled packages per-user.

  Also add migration step for reading old file to go towards
  per-user system file structure

TICKET: CYNGNOS-1006
Change-Id: I743e8efaa074c9b84291fdc8d3d15763cc39e79d

pm: Create per-mcc prebundled install filter.

  If packages are region locked, avoid installing them
  for the SKU, otherwise if a package is specified for
  a mobile country code, allow it to be installed.

TICKET: CYNGNOS-912
Change-Id: I69c5be62dff771fc7d3117e9edf65d8ea4150f28

pm: Update PackageManagerSettingsTests.

Change-Id: Ib3a23514055935f68f3f3bb4fd2b2d4d495c1132

PackageManager : Extend prebundled logic

Instead of specifying which packages to explicitly install,
Only install packages if :

a) Its in the current mcc's config_region_locked_packages
b) Its not region locked by checking config_restrict_to_region_locked_devices

Change-Id: I74c13763ef367e16e5e79290a569f3a720b85adc
parent a8ee5c9a
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -869,6 +869,14 @@ public abstract class PackageManager {
     */
    public static final int INSTALL_FAILED_UNINSTALLED_PREBUNDLE = -403;

    /**
     * Used for prebundles
     * Installation failed for a prebundled app because it wasn't needed in the default
     * mobile country exported by the hardware
     * @hide
     */
    public static final int INSTALL_FAILED_REGION_LOCKED_PREBUNDLE = -404; //bloat not found

    /**
     * Flag parameter for {@link #deletePackage} to indicate that you don't want to delete the
     * package's data directory.
+7 −0
Original line number Diff line number Diff line
@@ -102,4 +102,11 @@

    <!-- WiFi turn off notification -->
    <java-symbol type="string" name="notify_turn_wifi_off_title" />

    <!-- Region locked prebundled packages (per mcc) -->
    <java-symbol type="array" name="config_region_locked_packages" />

    <!-- Packages in this list should be a union of all packages defined in values-mccxxx (mcc) -->
    <java-symbol type="array" name="config_restrict_to_region_locked_devices" />

</resources>
+8 −0
Original line number Diff line number Diff line
@@ -2473,4 +2473,12 @@
    <!-- Boolean to enable Stylus gestures -->
    <bool name="config_stylusGestures">false</bool>

    <!-- Config to enable installation of region locked packages -->
    <string-array name="config_region_locked_packages" translatable="false">
    </string-array>

    <!-- Packages in this list should be a union of all packages defined in values-mccxxx (mcc) -->
    <string-array name="config_restrict_to_region_locked_devices" translatable="false">
    </string-array>

</resources>
+67 −17
Original line number Diff line number Diff line
@@ -44,6 +44,7 @@ import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_APK;
import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
import static android.content.pm.PackageManager.INSTALL_FAILED_MISSING_SHARED_LIBRARY;
import static android.content.pm.PackageManager.INSTALL_FAILED_PACKAGE_CHANGED;
import static android.content.pm.PackageManager.INSTALL_FAILED_REGION_LOCKED_PREBUNDLE;
import static android.content.pm.PackageManager.INSTALL_FAILED_REPLACE_COULDNT_DELETE;
import static android.content.pm.PackageManager.INSTALL_FAILED_SHARED_USER_INCOMPATIBLE;
import static android.content.pm.PackageManager.INSTALL_FAILED_TEST_ONLY;
@@ -87,6 +88,8 @@ import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_SUCCES
import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED;
import static com.android.internal.util.ArrayUtils.removeInt;
import android.content.res.Configuration;
import android.Manifest;
import cyanogenmod.app.suggest.AppSuggestManager;
@@ -330,6 +333,7 @@ public class PackageManagerService extends IPackageManager.Stub {
    private static final boolean DEBUG_VERIFY = false;
    private static final boolean DEBUG_DEXOPT = false;
    private static final boolean DEBUG_ABI_SELECTION = false;
    private static final boolean DEBUG_PREBUNDLED_SCAN = false;
    static final boolean CLEAR_RUNTIME_PERMISSIONS_ON_UPGRADE = false;
@@ -547,6 +551,8 @@ public class PackageManagerService extends IPackageManager.Stub {
    final Settings mSettings;
    boolean mRestoredSettings;
    private Resources mCustomResources;
    // System configuration read by SystemConfig.
    final int[] mGlobalGids;
    final SparseArray<ArraySet<String>> mSystemPermissions;
@@ -1974,7 +1980,8 @@ public class PackageManagerService extends IPackageManager.Stub {
            mFoundPolicyFile = SELinuxMMAC.readInstallPolicy();
            mRestoredSettings = mSettings.readLPw(this, sUserManager.getUsers(false),
                    mSdkVersion, mOnlyCore);
                    mSdkVersion, mOnlyCore, mInstaller);
            String customResolverActivity = SystemProperties.get("ro.custom.resolver.activity");
            if (TextUtils.isEmpty(customResolverActivity)) {
                customResolverActivity = Resources.getSystem().getString(
@@ -2137,24 +2144,24 @@ public class PackageManagerService extends IPackageManager.Stub {
            // overlay packages if they reside in VENDOR_OVERLAY_DIR.
            File vendorOverlayDir = new File(VENDOR_OVERLAY_DIR);
            scanDirLI(vendorOverlayDir, PackageParser.PARSE_IS_SYSTEM
                    | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags | SCAN_TRUSTED_OVERLAY, 0);
                    | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags | SCAN_TRUSTED_OVERLAY, 0, null);
            // Find base frameworks (resource packages without code).
            scanDirLI(frameworkDir, PackageParser.PARSE_IS_SYSTEM
                    | PackageParser.PARSE_IS_SYSTEM_DIR
                    | PackageParser.PARSE_IS_PRIVILEGED,
                    scanFlags | SCAN_NO_DEX, 0);
                    scanFlags | SCAN_NO_DEX, 0, null);
            // Collected privileged system packages.
            final File privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app");
            scanDirLI(privilegedAppDir, PackageParser.PARSE_IS_SYSTEM
                    | PackageParser.PARSE_IS_SYSTEM_DIR
                    | PackageParser.PARSE_IS_PRIVILEGED, scanFlags, 0);
                    | PackageParser.PARSE_IS_PRIVILEGED, scanFlags, 0, null);
            // Collect ordinary system packages.
            final File systemAppDir = new File(Environment.getRootDirectory(), "app");
            scanDirLI(systemAppDir, PackageParser.PARSE_IS_SYSTEM
                    | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);
                    | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0, null);
            // Collect all vendor packages.
            File vendorAppDir = new File("/vendor/app");
@@ -2164,16 +2171,19 @@ public class PackageManagerService extends IPackageManager.Stub {
                // failed to look up canonical path, continue with original one
            }
            scanDirLI(vendorAppDir, PackageParser.PARSE_IS_SYSTEM
                    | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);
                    | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0, null);
            // Collect all OEM packages.
            final File oemAppDir = new File(Environment.getOemDirectory(), "app");
            scanDirLI(oemAppDir, PackageParser.PARSE_IS_SYSTEM
                    | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);
                    | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0, null);
            // Collect all prebundled packages.
            createAndSetCustomResources();
            scanDirLI(Environment.getPrebundledDirectory(),
                    PackageParser.PARSE_IS_PREBUNDLED_DIR, scanFlags, 0);
                    PackageParser.PARSE_IS_PREBUNDLED_DIR, scanFlags, 0, UserHandle.OWNER);
            // Clean up
            mCustomResources = null;
            if (DEBUG_UPGRADE) Log.v(TAG, "Running installd update commands");
            mInstaller.moveFiles();
@@ -2248,10 +2258,10 @@ public class PackageManagerService extends IPackageManager.Stub {
            if (!mOnlyCore) {
                EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START,
                        SystemClock.uptimeMillis());
                scanDirLI(mAppInstallDir, 0, scanFlags | SCAN_REQUIRE_KNOWN, 0);
                scanDirLI(mAppInstallDir, 0, scanFlags | SCAN_REQUIRE_KNOWN, 0, null);
                scanDirLI(mDrmAppPrivateInstallDir, PackageParser.PARSE_FORWARD_LOCK,
                        scanFlags | SCAN_REQUIRE_KNOWN, 0);
                        scanFlags | SCAN_REQUIRE_KNOWN, 0, null);
                /**
                 * Remove disable package settings for any updated system
@@ -5746,7 +5756,8 @@ public class PackageManagerService extends IPackageManager.Stub {
        return true;
    }
    private void scanDirLI(File dir, int parseFlags, int scanFlags, long currentTime) {
    private void scanDirLI(File dir, int parseFlags, int scanFlags, long currentTime,
            UserHandle user) {
        final File[] files = dir.listFiles();
        if (ArrayUtils.isEmpty(files)) {
            Log.d(TAG, "No files in app dir " + dir);
@@ -5758,10 +5769,13 @@ public class PackageManagerService extends IPackageManager.Stub {
                    + " flags=0x" + Integer.toHexString(parseFlags));
        }
        int prebundledUserId = user == null ? UserHandle.USER_OWNER : user.getIdentifier();
        boolean isPrebundled = (parseFlags & PackageParser.PARSE_IS_PREBUNDLED_DIR) != 0;
        if (isPrebundled) {
            synchronized (mPackages) {
                mSettings.readPrebundledPackagesLPr();
                if (DEBUG_PREBUNDLED_SCAN) Log.d(TAG, "Reading prebundled packages for user "
                        + prebundledUserId);
                mSettings.readPrebundledPackagesLPr(prebundledUserId);
            }
        }
@@ -5774,7 +5788,7 @@ public class PackageManagerService extends IPackageManager.Stub {
            }
            try {
                scanPackageLI(file, parseFlags | PackageParser.PARSE_MUST_BE_APK,
                        scanFlags, currentTime, null);
                        scanFlags, currentTime, user);
                if (isPrebundled) {
                    final PackageParser.Package pkg;
                    try {
@@ -5783,7 +5797,16 @@ public class PackageManagerService extends IPackageManager.Stub {
                        throw PackageManagerException.from(e);
                    }
                    synchronized (mPackages) {
                        mSettings.markPrebundledPackageInstalledLPr(pkg.packageName);
                        if (DEBUG_PREBUNDLED_SCAN) Log.d(TAG,
                                "Marking prebundled packages for user " + prebundledUserId);
                        mSettings.markPrebundledPackageInstalledLPr(prebundledUserId,
                                pkg.packageName);
                        // do this for every other user
                        for (UserInfo userInfo : sUserManager.getUsers(true)) {
                            if (userInfo.id == prebundledUserId) continue;
                            mSettings.markPrebundledPackageInstalledLPr(userInfo.id,
                                    pkg.packageName);
                        }
                    }
                }
            } catch (PackageManagerException e) {
@@ -5804,7 +5827,9 @@ public class PackageManagerService extends IPackageManager.Stub {
        if (isPrebundled) {
            synchronized (mPackages) {
                mSettings.writePrebundledPackagesLPr();
                if (DEBUG_PREBUNDLED_SCAN) Log.d(TAG, "Writing prebundled packages for user "
                        + prebundledUserId);
                mSettings.writePrebundledPackagesLPr(prebundledUserId);
            }
        }
    }
@@ -5910,12 +5935,19 @@ public class PackageManagerService extends IPackageManager.Stub {
        if ((parseFlags & PackageParser.PARSE_IS_PREBUNDLED_DIR) != 0) {
            synchronized (mPackages) {
                PackageSetting existingSettings = mSettings.peekPackageLPr(pkg.packageName);
                if (mSettings.wasPrebundledPackageInstalledLPr(pkg.packageName) &&
                        existingSettings == null) {
                if (mSettings.wasPrebundledPackageInstalledLPr(user.getIdentifier()
                        , pkg.packageName) && existingSettings == null) {
                    // The prebundled app was installed at some point in time, but now it is
                    // gone.  Assume that the user uninstalled it intentionally: do not reinstall.
                    throw new PackageManagerException(INSTALL_FAILED_UNINSTALLED_PREBUNDLE,
                            "skip reinstall for " + pkg.packageName);
                } else if (existingSettings == null &&
                        !mSettings.shouldPrebundledPackageBeInstalled(mContext.getResources(),
                                pkg.packageName, mCustomResources)) {
                    // The prebundled app is not needed for the default mobile country code,
                    // skip installing it
                    throw new PackageManagerException(INSTALL_FAILED_REGION_LOCKED_PREBUNDLE,
                            "skip install for " + pkg.packageName);
                } else if (existingSettings != null
                        && existingSettings.versionCode >= pkg.mVersionCode
                        && !existingSettings.codePathString.contains(
@@ -16871,6 +16903,14 @@ public class PackageManagerService extends IPackageManager.Stub {
            mSettings.createNewUserLILPw(this, mInstaller, userHandle);
            applyFactoryDefaultBrowserLPw(userHandle);
            primeDomainVerificationsLPw(userHandle);
            // Set flag to monitor and not change apk file paths when
            // scanning install directories.
            final int scanFlags = SCAN_NO_PATHS | SCAN_DEFER_DEX | SCAN_BOOTING;
            createAndSetCustomResources();
            scanDirLI(Environment.getPrebundledDirectory(),
                    PackageParser.PARSE_IS_PREBUNDLED_DIR, scanFlags, 0,
                    new UserHandle(userHandle));
            mCustomResources = null;
        }
    }
@@ -17498,6 +17538,16 @@ public class PackageManagerService extends IPackageManager.Stub {
        }
    }
    private void createAndSetCustomResources() {
        Configuration tempConfiguration = new Configuration();
        String mcc = SystemProperties.get("ro.prebundled.mcc");
        if (!TextUtils.isEmpty(mcc)) {
            tempConfiguration.mcc = Integer.parseInt(mcc);
            mCustomResources = new Resources(new AssetManager(), new DisplayMetrics(),
                    tempConfiguration);
        }
    }
    /**
     * The new resource cache structure does not flatten the paths for idmaps, so this method
     * checks for files that end with @idmap and assumes this indicates the older format and
+151 −15
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED
import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED;
import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER;
import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
import static android.content.pm.PackageManager.INSTALL_FAILED_UNINSTALLED_PREBUNDLE;
import static android.Manifest.permission.READ_EXTERNAL_STORAGE;
import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER;
@@ -33,6 +34,8 @@ import android.content.IntentFilter;
import android.content.pm.ActivityInfo;
import android.content.pm.IntentFilterVerificationInfo;
import android.content.pm.ResolveInfo;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.net.Uri;
import android.os.Binder;
import android.os.Build;
@@ -56,6 +59,8 @@ import android.util.SparseLongArray;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.os.BackgroundThread;
import com.android.internal.util.ArrayUtils;
import com.android.internal.R;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.FastXmlSerializer;
import com.android.internal.util.IndentingPrintWriter;
import com.android.internal.util.JournaledFile;
@@ -231,8 +236,6 @@ final class Settings {
    // List of replaced system applications
    private final ArrayMap<String, PackageSetting> mDisabledSysPackages =
        new ArrayMap<String, PackageSetting>();
    private final HashSet<String> mPrebundledPackages =
            new HashSet<String>();

    // Set of restored intent-filter verification states
    private final ArrayMap<String, IntentFilterVerificationInfo> mRestoredIntentFilterVerifications =
@@ -293,6 +296,10 @@ final class Settings {
    final SparseArray<PersistentPreferredIntentResolver> mPersistentPreferredActivities =
            new SparseArray<PersistentPreferredIntentResolver>();

    // The persistent prebundled packages for a user
    final SparseArray<HashSet<String>> mPrebundledPackages =
            new SparseArray<HashSet<String>>();

    // For every user, it is used to find to which other users the intent can be forwarded.
    final SparseArray<CrossProfileIntentResolver> mCrossProfileIntentResolvers =
            new SparseArray<CrossProfileIntentResolver>();
@@ -366,12 +373,12 @@ final class Settings {
        mSettingsFilename = new File(mSystemDir, "packages.xml");
        mBackupSettingsFilename = new File(mSystemDir, "packages-backup.xml");
        mPackageListFilename = new File(mSystemDir, "packages.list");
        mPrebundledPackagesFilename = new File(mSystemDir, "prebundled-packages.list");
        FileUtils.setPermissions(mPackageListFilename, 0640, SYSTEM_UID, PACKAGE_INFO_GID);

        // Deprecated: Needed for migration
        mStoppedPackagesFilename = new File(mSystemDir, "packages-stopped.xml");
        mBackupStoppedPackagesFilename = new File(mSystemDir, "packages-stopped-backup.xml");
        mPrebundledPackagesFilename = new File(mSystemDir, "prebundled-packages.list");
    }

    PackageSetting getPackageLPw(PackageParser.Package pkg, PackageSetting origPackage,
@@ -1037,6 +1044,15 @@ final class Settings {
        return pir;
    }

    HashSet<String> editPrebundledPackagesLPw(int userId) {
        HashSet<String> hashSet = mPrebundledPackages.get(userId);
        if (hashSet == null) {
            hashSet = new HashSet<String>();
            mPrebundledPackages.put(userId, hashSet);
        }
        return hashSet;
    }

    PersistentPreferredIntentResolver editPersistentPreferredActivitiesLPw(int userId) {
        PersistentPreferredIntentResolver ppir = mPersistentPreferredActivities.get(userId);
        if (ppir == null) {
@@ -1206,6 +1222,10 @@ final class Settings {
                "package-restrictions-backup.xml");
    }

    private File getUserPrebundledStateFile(int userId) {
        return new File(Environment.getUserSystemDirectory(userId), "prebundled-packages.list");
    }

    void writeAllUsersPackageRestrictionsLPr() {
        List<UserInfo> users = getAllUsers();
        if (users == null) return;
@@ -2350,12 +2370,41 @@ final class Settings {
        }
    }

    void writePrebundledPackagesLPr() {
    // Migrate from previous prebundled packages file to new one
    void migratePrebundedPackagesIfNeededLPr(List<UserInfo> users, Installer installer) {
        if (mPrebundledPackagesFilename.exists()) {
            // Read old file
            editPrebundledPackagesLPw(UserHandle.USER_OWNER);
            readPrebundledPackagesOldLPw();
            mPrebundledPackagesFilename.delete();
            // Migrate to new file based on user
            writePrebundledPackagesLPr(UserHandle.USER_OWNER);
        } else {
            if (users == null) {
                readPrebundledPackagesLPr(UserHandle.USER_OWNER);
            } else {
                for (UserInfo user : users) {
                    editPrebundledPackagesLPw(user.id);
                    readPrebundledPackagesLPr(user.id);
                    // mark all existing users as having packages installed from OWNER
                    try {
                        markAllAsInstalledForUser(user.id, installer);
                    } catch (PackageManagerException e) {
                        Log.d(TAG, e.toString());
                    }
                }
            }
        }
    }

    void writePrebundledPackagesLPr(int userId) {
        editPrebundledPackagesLPw(userId);
        PrintWriter writer = null;
        try {
            writer = new PrintWriter(
                    new BufferedWriter(new FileWriter(mPrebundledPackagesFilename, false)));
            for (String packageName : mPrebundledPackages) {
                    new BufferedWriter(new FileWriter(getUserPrebundledStateFile(userId), false)));

            for (String packageName : mPrebundledPackages.get(userId)) {
                writer.println(packageName);
            }
        } catch (IOException e) {
@@ -2367,18 +2416,31 @@ final class Settings {
        }
    }

    void readPrebundledPackagesLPr() {
    // This is done for an intermediate migration step on upgrade
    void readPrebundledPackagesOldLPw() {
        if (!mPrebundledPackagesFilename.exists()) {
            return;
        }

        readPrebundledPackagesForUserFromFileLPr(UserHandle.USER_OWNER,
                mPrebundledPackagesFilename);
    }

    void readPrebundledPackagesLPr(int userId) {
        if (!getUserPrebundledStateFile(userId).exists()) {
            return;
        }
        readPrebundledPackagesForUserFromFileLPr(userId, getUserPrebundledStateFile(userId));
    }

    private void readPrebundledPackagesForUserFromFileLPr(int userId, File file) {
        BufferedReader reader = null;
        try {
            reader = new BufferedReader(new FileReader(mPrebundledPackagesFilename));
            reader = new BufferedReader(new FileReader(file));
            String packageName = reader.readLine();
            while (packageName != null) {
                if (!TextUtils.isEmpty(packageName)) {
                    mPrebundledPackages.add(packageName);
                    mPrebundledPackages.get(userId).add(packageName);
                }
                packageName = reader.readLine();
            }
@@ -2393,12 +2455,78 @@ final class Settings {
        }
    }

    void markPrebundledPackageInstalledLPr(String packageName) {
        mPrebundledPackages.add(packageName);
    private void markAllAsInstalledForUser(int userHandle, Installer installer)
            throws PackageManagerException {
        if (mPrebundledPackages.get(userHandle) == null) {
            throw new PackageManagerException(INSTALL_FAILED_UNINSTALLED_PREBUNDLE,
                    "Failure migrating prebundled packages to existing user " + userHandle);
        }

    boolean wasPrebundledPackageInstalledLPr(String packageName) {
        return mPrebundledPackages.contains(packageName);
        // grab all the packages from the user account, move them over
        for (String s : mPrebundledPackages.get(UserHandle.USER_OWNER)) {
            mPrebundledPackages.get(userHandle).add(s);
        }

        for (PackageSetting ps : mPackages.values()) {
            if (ps.pkg == null || ps.pkg.applicationInfo == null) {
                continue;
            }
            // Mark the app as installed
            boolean setInstalled =
                    wasPrebundledPackageInstalledLPr(UserHandle.USER_OWNER, ps.name);
            ps.setInstalled(setInstalled, userHandle);
            // Tell the installer to create the user data for the application
            installer.createUserData(ps.name,
                    UserHandle.getUid(userHandle, ps.appId), userHandle,
                    ps.pkg.applicationInfo.seinfo);
        }
        // Write the package restrications
        writePackageRestrictionsLPr(userHandle);
    }

    void markPrebundledPackageInstalledLPr(int userId, String packageName) {
        editPrebundledPackagesLPw(userId);
        mPrebundledPackages.get(userId).add(packageName);
    }

    boolean wasPrebundledPackageInstalledLPr(int userId, String packageName) {
        if (mPrebundledPackages.get(userId) == null) {
            return false;
        }
        return mPrebundledPackages.get(userId).contains(packageName);
    }

    boolean shouldPrebundledPackageBeInstalled(Resources res, String packageName,
                                            Resources configuredResources) {
        // Default fallback on lack of bad package
        if (TextUtils.isEmpty(packageName)) {
            return false;
        }

        // Configured resources can be null if the device
        // is not region locked. In such cases, fall back to
        // the default resources object
        Resources resources = configuredResources;
        if (configuredResources == null) {
            resources = res;
        }

        // If the package is compatible with the current region, install it
        // Note : If a package needs to be installed only if the device is
        // not provisioned, overlay values/config_region_locked_packages
        // TODO change config_region_locked_packages to something that is
        // not confusing inside a non region resource bucket
        String[] prebundledArray
                = resources.getStringArray(R.array.config_region_locked_packages);
        if (ArrayUtils.contains(prebundledArray, packageName)) {
            return true;
        }

        // If the package is not compatible with the current region, check if its locked
        // to any other region before installing it.
        prebundledArray = resources
                .getStringArray(R.array.config_restrict_to_region_locked_devices);
        return !ArrayUtils.contains(prebundledArray, packageName);
    }

    void writeDisabledSysPackageLPr(XmlSerializer serializer, final PackageSetting pkg)
@@ -2587,7 +2715,7 @@ final class Settings {
    }

    boolean readLPw(PackageManagerService service, List<UserInfo> users, int sdkVersion,
            boolean onlyCore) {
            boolean onlyCore, Installer installer) {
        FileInputStream str = null;
        if (mBackupSettingsFilename.exists()) {
            try {
@@ -2841,6 +2969,8 @@ final class Settings {
            }
        }

        migratePrebundedPackagesIfNeededLPr(users, installer);

        /*
         * Make sure all the updated system packages have their shared users
         * associated with them.
@@ -3765,7 +3895,9 @@ final class Settings {
                continue;
            }
            // Only system apps are initially installed.
            ps.setInstalled((ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) != 0, userHandle);
            boolean setInstalled = ((ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) != 0) ||
                    wasPrebundledPackageInstalledLPr(UserHandle.USER_OWNER, ps.name);
            ps.setInstalled(setInstalled, userHandle);
            // Need to create a data directory for all apps under this user.
            installer.createUserData(ps.volumeUuid, ps.name,
                    UserHandle.getUid(userHandle, ps.appId), userHandle,
@@ -3774,6 +3906,7 @@ final class Settings {
        applyDefaultPreferredAppsLPw(service, userHandle);
        writePackageRestrictionsLPr(userHandle);
        writePackageListLPr(userHandle);
        writePrebundledPackagesLPr(userHandle);
    }

    void removeUserLPw(int userId) {
@@ -3782,10 +3915,13 @@ final class Settings {
            entry.getValue().removeUser(userId);
        }
        mPreferredActivities.remove(userId);
        mPrebundledPackages.remove(userId);
        File file = getUserPackagesStateFile(userId);
        file.delete();
        file = getUserPackagesStateBackupFile(userId);
        file.delete();
        file = getUserPrebundledStateFile(userId);
        file.delete();
        removeCrossProfileIntentFiltersLPw(userId);

        mRuntimePermissionsPersistence.onUserRemoved(userId);
Loading