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

Commit b5f3f030 authored by android-build-team Robot's avatar android-build-team Robot
Browse files

Snap for 5304822 from 7ed81d17 to pi-qpr3-release

Change-Id: Ib7a1bcccff19c71cfe2eb3b08fa57fe86ba79999
parents b4ddb4a4 7ed81d17
Loading
Loading
Loading
Loading
+39 −20
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package android.content.pm;

import android.Manifest;
import android.annotation.Nullable;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
@@ -174,7 +175,8 @@ public abstract class RegisteredServicesCache<V> {
        mContext.registerReceiver(mUserRemovedReceiver, userFilter);
    }

    private final void handlePackageEvent(Intent intent, int userId) {
    @VisibleForTesting
    protected void handlePackageEvent(Intent intent, int userId) {
        // Don't regenerate the services map when the package is removed or its
        // ASEC container unmounted as a step in replacement.  The subsequent
        // _ADDED / _AVAILABLE call will regenerate the map in the final state.
@@ -236,6 +238,9 @@ public abstract class RegisteredServicesCache<V> {

    public void invalidateCache(int userId) {
        synchronized (mServicesLock) {
            if (DEBUG) {
                Slog.d(TAG, "invalidating cache for " + userId + " " + mInterfaceName);
            }
            final UserServices<V> user = findOrCreateUserLocked(userId);
            user.services = null;
            onServicesChangedLocked(userId);
@@ -460,16 +465,37 @@ public abstract class RegisteredServicesCache<V> {
     *                    or null to assume that everything is affected.
     * @param userId the user for whom to update the services map.
     */
    private void generateServicesMap(int[] changedUids, int userId) {
    private void generateServicesMap(@Nullable int[] changedUids, int userId) {
        if (DEBUG) {
            Slog.d(TAG, "generateServicesMap() for " + userId + ", changed UIDs = "
                    + Arrays.toString(changedUids));
        }

        synchronized (mServicesLock) {
            final UserServices<V> user = findOrCreateUserLocked(userId);
            final boolean cacheInvalid = user.services == null;
            if (cacheInvalid) {
                user.services = Maps.newHashMap();
            }

            final ArrayList<ServiceInfo<V>> serviceInfos = new ArrayList<>();
            final List<ResolveInfo> resolveInfos = queryIntentServices(userId);

            for (ResolveInfo resolveInfo : resolveInfos) {
                try {
                    // when changedUids == null, we want to do a rescan of everything, this means
                    // it's the initial scan, and containsUid will trivially return true
                    // when changedUids != null, we got here because a package changed, but
                    // invalidateCache could have been called (thus user.services == null), and we
                    // should query from PackageManager again
                    if (!cacheInvalid
                            && !containsUid(
                                    changedUids, resolveInfo.serviceInfo.applicationInfo.uid)) {
                        if (DEBUG) {
                            Slog.d(TAG, "Skipping parseServiceInfo for " + resolveInfo);
                        }
                        continue;
                    }
                    ServiceInfo<V> info = parseServiceInfo(resolveInfo);
                    if (info == null) {
                        Log.w(TAG, "Unable to load service info " + resolveInfo.toString());
@@ -481,13 +507,6 @@ public abstract class RegisteredServicesCache<V> {
                }
            }

        synchronized (mServicesLock) {
            final UserServices<V> user = findOrCreateUserLocked(userId);
            final boolean firstScan = user.services == null;
            if (firstScan) {
                user.services = Maps.newHashMap();
            }

            StringBuilder changes = new StringBuilder();
            boolean changed = false;
            for (ServiceInfo<V> info : serviceInfos) {
@@ -508,7 +527,7 @@ public abstract class RegisteredServicesCache<V> {
                    changed = true;
                    user.services.put(info.type, info);
                    user.persistentServices.put(info.type, info.uid);
                    if (!(user.mPersistentServicesFileDidNotExist && firstScan)) {
                    if (!(user.mPersistentServicesFileDidNotExist && cacheInvalid)) {
                        notifyListener(info.type, userId, false /* removed */);
                    }
                } else if (previousUid == info.uid) {
+41 −0
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package android.content.pm;

import android.content.Intent;
import android.content.res.Resources;
import android.os.FileUtils;
import android.os.Parcel;
@@ -188,6 +189,36 @@ public class RegisteredServicesCacheTest extends AndroidTestCase {
        assertEquals(0, cache.getPersistentServicesSize(u1));
    }

    /**
     * Check that an optimization to skip a call to PackageManager handles an invalidated cache.
     *
     * We added an optimization in generateServicesMap to only query PackageManager for packages
     * that have been changed, because if a package is unchanged, we have already cached the
     * services info for it, so we can save a query to PackageManager (and save some memory).
     * However, if invalidateCache was called, we cannot optimize, and must do a full query.
     * The initial optimization was buggy because it failed to check for an invalidated cache, and
     * only scanned the changed packages, given in the ACTION_PACKAGE_CHANGED intent (b/122912184).
     */
    public void testParseServiceInfoOptimizationHandlesInvalidatedCache() {
        TestServicesCache cache = new TestServicesCache();
        cache.addServiceForQuerying(U0, r1, newServiceInfo(t1, UID1));
        cache.addServiceForQuerying(U0, r2, newServiceInfo(t2, UID2));
        assertEquals(2, cache.getAllServicesSize(U0));

        // simulate the client of the cache invalidating it
        cache.invalidateCache(U0);

        // there should be 0 services (userServices.services == null ) at this point, but we don't
        // call getAllServicesSize since that would force a full scan of packages,
        // instead we trigger a package change in a package that is in the list of services
        Intent intent = new Intent(Intent.ACTION_PACKAGE_CHANGED);
        intent.putExtra(Intent.EXTRA_UID, UID1);
        cache.handlePackageEvent(intent, U0);

        // check that the optimization does a full query and caches both services
        assertEquals(2, cache.getAllServicesSize(U0));
    }

    private static RegisteredServicesCache.ServiceInfo<TestServiceType> newServiceInfo(
            TestServiceType type, int uid) {
        final ComponentInfo info = new ComponentInfo();
@@ -265,6 +296,11 @@ public class RegisteredServicesCacheTest extends AndroidTestCase {
                map = new HashMap<>();
                mServices.put(userId, map);
            }
            // in actual cases, resolveInfo should always have a serviceInfo, since we specifically
            // query for intent services
            resolveInfo.serviceInfo = new android.content.pm.ServiceInfo();
            resolveInfo.serviceInfo.applicationInfo =
                new ApplicationInfo(serviceInfo.componentInfo.applicationInfo);
            map.put(resolveInfo, serviceInfo);
        }

@@ -303,6 +339,11 @@ public class RegisteredServicesCacheTest extends AndroidTestCase {
        public void onUserRemoved(int userId) {
            super.onUserRemoved(userId);
        }

        @Override
        public void handlePackageEvent(Intent intent, int userId) {
            super.handlePackageEvent(intent, userId);
        }
    }

    static class TestSerializer implements XmlSerializerAndParser<TestServiceType> {
+7 −2
Original line number Diff line number Diff line
@@ -48,6 +48,7 @@ import android.content.pm.PermissionInfo;
import android.database.ContentObserver;
import android.net.Uri;
import android.os.Binder;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
@@ -1288,9 +1289,13 @@ class AlarmManagerService extends SystemService {
        // because kernel doesn't keep this after reboot
        setTimeZoneImpl(SystemProperties.get(TIMEZONE_PROPERTY));

        // Also sure that we're booting with a halfway sensible current time
        if (mNativeData != 0) {
            final long systemBuildTime = Environment.getRootDirectory().lastModified();
            // Ensure that we're booting with a halfway sensible current time.  Use the
            // most recent of Build.TIME, the root file system's timestamp, and the
            // value of the ro.build.date.utc system property (which is in seconds).
            final long systemBuildTime =  Long.max(
                    1000L * SystemProperties.getLong("ro.build.date.utc", -1L),
                    Long.max(Environment.getRootDirectory().lastModified(), Build.TIME));
            if (System.currentTimeMillis() < systemBuildTime) {
                Slog.i(TAG, "Current time only " + System.currentTimeMillis()
                        + ", advancing to build time " + systemBuildTime);
+14 −0
Original line number Diff line number Diff line
@@ -1091,6 +1091,19 @@ public class CarrierConfigManager {
     */
    public static final String KEY_CARRIER_NAME_STRING = "carrier_name_string";

    /**
     * String to override sim country iso.
     * Sim country iso is based on sim MCC which is coarse and doesn't work with dual IMSI SIM where
     * a SIM can have multiple MCC from different countries.
     * Instead, each sim carrier should have a single country code, apply per carrier based iso
     * code as an override. The overridden value can be read from
     * {@link TelephonyManager#getSimCountryIso()} and {@link SubscriptionInfo#getCountryIso()}
     *
     * @hide
     */
    public static final String KEY_SIM_COUNTRY_ISO_OVERRIDE_STRING =
            "sim_country_iso_override_string";

    /**
     * Override the registered PLMN name using #KEY_CDMA_HOME_REGISTERED_PLMN_NAME_STRING.
     *
@@ -2237,6 +2250,7 @@ public class CarrierConfigManager {
        sDefaults.putBoolean(KEY_CONFIG_WIFI_DISABLE_IN_ECBM, false);
        sDefaults.putBoolean(KEY_CARRIER_NAME_OVERRIDE_BOOL, false);
        sDefaults.putString(KEY_CARRIER_NAME_STRING, "");
        sDefaults.putString(KEY_SIM_COUNTRY_ISO_OVERRIDE_STRING, "");
        sDefaults.putBoolean(KEY_CDMA_HOME_REGISTERED_PLMN_NAME_OVERRIDE_BOOL, false);
        sDefaults.putString(KEY_CDMA_HOME_REGISTERED_PLMN_NAME_STRING, "");
        sDefaults.putBoolean(KEY_SUPPORT_DIRECT_FDN_DIALING_BOOL, false);
+11 −0
Original line number Diff line number Diff line
@@ -257,6 +257,15 @@ public final class SmsManager {
     */
    public static final String MMS_CONFIG_SUPPORT_HTTP_CHARSET_HEADER =
            CarrierConfigManager.KEY_MMS_SUPPORT_HTTP_CHARSET_HEADER_BOOL;

    /**
     * When roaming, some operator's MCC would change. It results in MMSService's verification
     * failure. This config could use correct country.
     * @hide
     */
    public static final String MMS_CONFIG_SIM_COUNTRY_ISO_OVERRIDE =
            CarrierConfigManager.KEY_SIM_COUNTRY_ISO_OVERRIDE_STRING;

    /**
     * If true, add "Connection: close" header to MMS HTTP requests so the connection
     * is immediately closed (disabling keep-alive). (Boolean type)
@@ -2065,6 +2074,8 @@ public final class SmsManager {
        filtered.putString(MMS_CONFIG_EMAIL_GATEWAY_NUMBER,
                config.getString(MMS_CONFIG_EMAIL_GATEWAY_NUMBER));
        filtered.putString(MMS_CONFIG_NAI_SUFFIX, config.getString(MMS_CONFIG_NAI_SUFFIX));
        filtered.putString(MMS_CONFIG_SIM_COUNTRY_ISO_OVERRIDE,
                config.getString(MMS_CONFIG_SIM_COUNTRY_ISO_OVERRIDE));
        filtered.putBoolean(MMS_CONFIG_SHOW_CELL_BROADCAST_APP_LINKS,
                config.getBoolean(MMS_CONFIG_SHOW_CELL_BROADCAST_APP_LINKS));
        filtered.putBoolean(MMS_CONFIG_SUPPORT_HTTP_CHARSET_HEADER,