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

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

Snap for 6862191 from 711cdc22 to rvc-qpr1-release

Change-Id: Icd5e06e0c0d6bc86577157d825cbc233a5b07e13
parents aa3e4d56 711cdc22
Loading
Loading
Loading
Loading
+16 −0
Original line number Diff line number Diff line
@@ -1120,6 +1120,10 @@ public class AppStandbyController implements AppStandbyInternal {
            if (isDeviceProvisioningPackage(packageName)) {
                return STANDBY_BUCKET_EXEMPTED;
            }

            if (mInjector.isWellbeingPackage(packageName)) {
                return STANDBY_BUCKET_WORKING_SET;
            }
        }

        // Check this last, as it can be the most expensive check
@@ -1929,6 +1933,7 @@ public class AppStandbyController implements AppStandbyInternal {
         */
        @GuardedBy("mPowerWhitelistedApps")
        private final ArraySet<String> mPowerWhitelistedApps = new ArraySet<>();
        private String mWellbeingApp = null;

        Injector(Context context, Looper looper) {
            mContext = context;
@@ -1962,6 +1967,9 @@ public class AppStandbyController implements AppStandbyInternal {
                if (activityManager.isLowRamDevice() || ActivityManager.isSmallBatteryDevice()) {
                    mAutoRestrictedBucketDelayMs = 12 * ONE_HOUR;
                }

                final PackageManager packageManager = mContext.getPackageManager();
                mWellbeingApp = packageManager.getWellbeingPackageName();
            }
            mBootPhase = phase;
        }
@@ -2006,6 +2014,14 @@ public class AppStandbyController implements AppStandbyInternal {
            }
        }

        /**
         * Returns {@code true} if the supplied package is the wellbeing app. Otherwise,
         * returns {@code false}.
         */
        boolean isWellbeingPackage(String packageName) {
            return mWellbeingApp != null && mWellbeingApp.equals(packageName);
        }

        void updatePowerWhitelistCache() {
            try {
                // Don't call out to DeviceIdleController with the lock held.
+146 −122
Original line number Diff line number Diff line
@@ -40,7 +40,6 @@ import android.os.Trace;
import android.util.ArrayMap;
import android.util.DisplayMetrics;
import android.util.Log;
import android.util.LruCache;
import android.util.Pair;
import android.util.Slog;
import android.view.Display;
@@ -63,7 +62,6 @@ import java.util.List;
import java.util.Objects;
import java.util.WeakHashMap;
import java.util.function.Consumer;
import java.util.function.Predicate;

/** @hide */
public class ResourcesManager {
@@ -130,17 +128,30 @@ public class ResourcesManager {
        }
    }

    private static final boolean ENABLE_APK_ASSETS_CACHE = false;
    /**
     * Loads {@link ApkAssets} and caches them to prevent their garbage collection while the
     * instance is alive and reachable.
     */
    private class ApkAssetsSupplier {
        final ArrayMap<ApkKey, ApkAssets> mLocalCache = new ArrayMap<>();

        /**
     * The ApkAssets we are caching and intend to hold strong references to.
         * Retrieves the {@link ApkAssets} corresponding to the specified key, caches the ApkAssets
         * within this instance, and inserts the loaded ApkAssets into the {@link #mCachedApkAssets}
         * cache.
         */
    private final LruCache<ApkKey, ApkAssets> mLoadedApkAssets =
            (ENABLE_APK_ASSETS_CACHE) ? new LruCache<>(3) : null;
        ApkAssets load(final ApkKey apkKey) throws IOException {
            ApkAssets apkAssets = mLocalCache.get(apkKey);
            if (apkAssets == null) {
                apkAssets = loadApkAssets(apkKey);
                mLocalCache.put(apkKey, apkAssets);
            }
            return apkAssets;
        }
    }

    /**
     * The ApkAssets that are being referenced in the wild that we can reuse, even if they aren't
     * in our LRU cache. Bonus resources :)
     * The ApkAssets that are being referenced in the wild that we can reuse.
     */
    private final ArrayMap<ApkKey, WeakReference<ApkAssets>> mCachedApkAssets = new ArrayMap<>();

@@ -338,113 +349,116 @@ public class ResourcesManager {
        return "/data/resource-cache/" + path.substring(1).replace('/', '@') + "@idmap";
    }

    private @NonNull ApkAssets loadApkAssets(String path, boolean sharedLib, boolean overlay)
            throws IOException {
        final ApkKey newKey = new ApkKey(path, sharedLib, overlay);
        ApkAssets apkAssets = null;
        if (mLoadedApkAssets != null) {
            apkAssets = mLoadedApkAssets.get(newKey);
            if (apkAssets != null && apkAssets.isUpToDate()) {
                return apkAssets;
            }
        }
    private @NonNull ApkAssets loadApkAssets(@NonNull final ApkKey key) throws IOException {
        ApkAssets apkAssets;

        // Optimistically check if this ApkAssets exists somewhere else.
        final WeakReference<ApkAssets> apkAssetsRef = mCachedApkAssets.get(newKey);
        synchronized (this) {
            final WeakReference<ApkAssets> apkAssetsRef = mCachedApkAssets.get(key);
            if (apkAssetsRef != null) {
                apkAssets = apkAssetsRef.get();
                if (apkAssets != null && apkAssets.isUpToDate()) {
                if (mLoadedApkAssets != null) {
                    mLoadedApkAssets.put(newKey, apkAssets);
                }

                    return apkAssets;
                } else {
                    // Clean up the reference.
                mCachedApkAssets.remove(newKey);
                    mCachedApkAssets.remove(key);
                }
            }
        }

        // We must load this from disk.
        if (overlay) {
            apkAssets = ApkAssets.loadOverlayFromPath(overlayPathToIdmapPath(path), 0 /*flags*/);
        if (key.overlay) {
            apkAssets = ApkAssets.loadOverlayFromPath(overlayPathToIdmapPath(key.path),
                    0 /*flags*/);
        } else {
            apkAssets = ApkAssets.loadFromPath(path, sharedLib ? ApkAssets.PROPERTY_DYNAMIC : 0);
            apkAssets = ApkAssets.loadFromPath(key.path,
                    key.sharedLib ? ApkAssets.PROPERTY_DYNAMIC : 0);
        }

        if (mLoadedApkAssets != null) {
            mLoadedApkAssets.put(newKey, apkAssets);
        synchronized (this) {
            mCachedApkAssets.put(key, new WeakReference<>(apkAssets));
        }

        mCachedApkAssets.put(newKey, new WeakReference<>(apkAssets));
        return apkAssets;
    }

    /**
     * Creates an AssetManager from the paths within the ResourcesKey.
     *
     * This can be overridden in tests so as to avoid creating a real AssetManager with
     * real APK paths.
     * @param key The key containing the resource paths to add to the AssetManager.
     * @return a new AssetManager.
     * Retrieves a list of apk keys representing the ApkAssets that should be loaded for
     * AssetManagers mapped to the {@param key}.
     */
    @VisibleForTesting
    @UnsupportedAppUsage
    protected @Nullable AssetManager createAssetManager(@NonNull final ResourcesKey key) {
        final AssetManager.Builder builder = new AssetManager.Builder();
    private static @NonNull ArrayList<ApkKey> extractApkKeys(@NonNull final ResourcesKey key) {
        final ArrayList<ApkKey> apkKeys = new ArrayList<>();

        // resDir can be null if the 'android' package is creating a new Resources object.
        // This is fine, since each AssetManager automatically loads the 'android' package
        // already.
        if (key.mResDir != null) {
            try {
                builder.addApkAssets(loadApkAssets(key.mResDir, false /*sharedLib*/,
                        false /*overlay*/));
            } catch (IOException e) {
                Log.e(TAG, "failed to add asset path " + key.mResDir);
                return null;
            }
            apkKeys.add(new ApkKey(key.mResDir, false /*sharedLib*/, false /*overlay*/));
        }

        if (key.mSplitResDirs != null) {
            for (final String splitResDir : key.mSplitResDirs) {
                try {
                    builder.addApkAssets(loadApkAssets(splitResDir, false /*sharedLib*/,
                            false /*overlay*/));
                } catch (IOException e) {
                    Log.e(TAG, "failed to add split asset path " + splitResDir);
                    return null;
                }
                apkKeys.add(new ApkKey(splitResDir, false /*sharedLib*/, false /*overlay*/));
            }
        }

        if (key.mLibDirs != null) {
            for (final String libDir : key.mLibDirs) {
                // Avoid opening files we know do not have resources, like code-only .jar files.
                if (libDir.endsWith(".apk")) {
                    // Avoid opening files we know do not have resources,
                    // like code-only .jar files.
                    try {
                        builder.addApkAssets(loadApkAssets(libDir, true /*sharedLib*/,
                                false /*overlay*/));
                    } catch (IOException e) {
                        Log.w(TAG, "Asset path '" + libDir +
                                "' does not exist or contains no resources.");

                        // continue.
                    }
                    apkKeys.add(new ApkKey(libDir, true /*sharedLib*/, false /*overlay*/));
                }
            }
        }

        if (key.mOverlayDirs != null) {
            for (final String idmapPath : key.mOverlayDirs) {
                apkKeys.add(new ApkKey(idmapPath, false /*sharedLib*/, true /*overlay*/));
            }
        }

        return apkKeys;
    }

    /**
     * Creates an AssetManager from the paths within the ResourcesKey.
     *
     * This can be overridden in tests so as to avoid creating a real AssetManager with
     * real APK paths.
     * @param key The key containing the resource paths to add to the AssetManager.
     * @return a new AssetManager.
    */
    @VisibleForTesting
    @UnsupportedAppUsage
    protected @Nullable AssetManager createAssetManager(@NonNull final ResourcesKey key) {
        return createAssetManager(key, /* apkSupplier */ null);
    }

    /**
     * Variant of {@link #createAssetManager(ResourcesKey)} that attempts to load ApkAssets
     * from an {@link ApkAssetsSupplier} if non-null; otherwise ApkAssets are loaded using
     * {@link #loadApkAssets(ApkKey)}.
     */
    private @Nullable AssetManager createAssetManager(@NonNull final ResourcesKey key,
            @Nullable ApkAssetsSupplier apkSupplier) {
        final AssetManager.Builder builder = new AssetManager.Builder();

        final ArrayList<ApkKey> apkKeys = extractApkKeys(key);
        for (int i = 0, n = apkKeys.size(); i < n; i++) {
            final ApkKey apkKey = apkKeys.get(i);
            try {
                    builder.addApkAssets(loadApkAssets(idmapPath, false /*sharedLib*/,
                            true /*overlay*/));
                builder.addApkAssets(
                        (apkSupplier != null) ? apkSupplier.load(apkKey) : loadApkAssets(apkKey));
            } catch (IOException e) {
                    Log.w(TAG, "failed to add overlay path " + idmapPath);

                    // continue.
                if (apkKey.overlay) {
                    Log.w(TAG, String.format("failed to add overlay path '%s'", apkKey.path), e);
                } else if (apkKey.sharedLib) {
                    Log.w(TAG, String.format(
                            "asset path '%s' does not exist or contains no resources",
                            apkKey.path), e);
                } else {
                    Log.e(TAG, String.format("failed to add asset path '%s'", apkKey.path), e);
                    return null;
                }
            }
        }
@@ -481,24 +495,6 @@ public class ResourcesManager {

            pw.println("ResourcesManager:");
            pw.increaseIndent();
            if (mLoadedApkAssets != null) {
                pw.print("cached apks: total=");
                pw.print(mLoadedApkAssets.size());
                pw.print(" created=");
                pw.print(mLoadedApkAssets.createCount());
                pw.print(" evicted=");
                pw.print(mLoadedApkAssets.evictionCount());
                pw.print(" hit=");
                pw.print(mLoadedApkAssets.hitCount());
                pw.print(" miss=");
                pw.print(mLoadedApkAssets.missCount());
                pw.print(" max=");
                pw.print(mLoadedApkAssets.maxSize());
            } else {
                pw.print("cached apks: 0 [cache disabled]");
            }
            pw.println();

            pw.print("total apks: ");
            pw.println(countLiveReferences(mCachedApkAssets.values()));

@@ -534,11 +530,12 @@ public class ResourcesManager {
        return config;
    }

    private @Nullable ResourcesImpl createResourcesImpl(@NonNull ResourcesKey key) {
    private @Nullable ResourcesImpl createResourcesImpl(@NonNull ResourcesKey key,
            @Nullable ApkAssetsSupplier apkSupplier) {
        final DisplayAdjustments daj = new DisplayAdjustments(key.mOverrideConfiguration);
        daj.setCompatibilityInfo(key.mCompatInfo);

        final AssetManager assets = createAssetManager(key);
        final AssetManager assets = createAssetManager(key, apkSupplier);
        if (assets == null) {
            return null;
        }
@@ -576,9 +573,18 @@ public class ResourcesManager {
     */
    private @Nullable ResourcesImpl findOrCreateResourcesImplForKeyLocked(
            @NonNull ResourcesKey key) {
        return findOrCreateResourcesImplForKeyLocked(key, /* apkSupplier */ null);
    }

    /**
     * Variant of {@link #findOrCreateResourcesImplForKeyLocked(ResourcesKey)} that attempts to
     * load ApkAssets from a {@link ApkAssetsSupplier} when creating a new ResourcesImpl.
     */
    private @Nullable ResourcesImpl findOrCreateResourcesImplForKeyLocked(
            @NonNull ResourcesKey key, @Nullable ApkAssetsSupplier apkSupplier) {
        ResourcesImpl impl = findResourcesImplForKeyLocked(key);
        if (impl == null) {
            impl = createResourcesImpl(key);
            impl = createResourcesImpl(key, apkSupplier);
            if (impl != null) {
                mResourceImpls.put(key, new WeakReference<>(impl));
            }
@@ -767,7 +773,7 @@ public class ResourcesManager {
            }

            // Now request an actual Resources object.
            return createResources(token, key, classLoader);
            return createResources(token, key, classLoader, /* apkSupplier */ null);
        } finally {
            Trace.traceEnd(Trace.TRACE_TAG_RESOURCES);
        }
@@ -810,6 +816,31 @@ public class ResourcesManager {
                (ref) -> ref == null || deadReferences.contains(ref));
    }

    /**
     * Creates an {@link ApkAssetsSupplier} and loads all the ApkAssets required by the {@param key}
     * into the supplier. This should be done while the lock is not held to prevent performing I/O
     * while holding the lock.
     */
    private @NonNull ApkAssetsSupplier createApkAssetsSupplierNotLocked(@NonNull ResourcesKey key) {
        Trace.traceBegin(Trace.TRACE_TAG_RESOURCES,
                "ResourcesManager#createApkAssetsSupplierNotLocked");
        try {
            final ApkAssetsSupplier supplier = new ApkAssetsSupplier();
            final ArrayList<ApkKey> apkKeys = extractApkKeys(key);
            for (int i = 0, n = apkKeys.size(); i < n; i++) {
                final ApkKey apkKey = apkKeys.get(i);
                try {
                    supplier.load(apkKey);
                } catch (IOException e) {
                    Log.w(TAG, String.format("failed to preload asset path '%s'", apkKey.path), e);
                }
            }
            return supplier;
        } finally {
            Trace.traceEnd(Trace.TRACE_TAG_RESOURCES);
        }
    }

    /**
     * Creates a Resources object set with a ResourcesImpl object matching the given key.
     *
@@ -817,12 +848,14 @@ public class ResourcesManager {
     * @param key The key describing the parameters of the ResourcesImpl object.
     * @param classLoader The classloader to use for the Resources object.
     *                    If null, {@link ClassLoader#getSystemClassLoader()} is used.
     * @param apkSupplier The apk assets supplier to use when creating a new ResourcesImpl object.
     * @return A Resources object that gets updated when
     *         {@link #applyConfigurationToResourcesLocked(Configuration, CompatibilityInfo)}
     *         is called.
     */
    private @Nullable Resources createResources(@Nullable IBinder activityToken,
            @NonNull ResourcesKey key, @NonNull ClassLoader classLoader) {
            @NonNull ResourcesKey key, @NonNull ClassLoader classLoader,
            @Nullable ApkAssetsSupplier apkSupplier) {
        synchronized (this) {
            if (DEBUG) {
                Throwable here = new Throwable();
@@ -830,7 +863,7 @@ public class ResourcesManager {
                Slog.w(TAG, "!! Get resources for activity=" + activityToken + " key=" + key, here);
            }

            ResourcesImpl resourcesImpl = findOrCreateResourcesImplForKeyLocked(key);
            ResourcesImpl resourcesImpl = findOrCreateResourcesImplForKeyLocked(key, apkSupplier);
            if (resourcesImpl == null) {
                return null;
            }
@@ -899,7 +932,10 @@ public class ResourcesManager {
                rebaseKeyForActivity(activityToken, key);
            }

            return createResources(activityToken, key, classLoader);
            // Preload the ApkAssets required by the key to prevent performing heavy I/O while the
            // ResourcesManager lock is held.
            final ApkAssetsSupplier assetsSupplier = createApkAssetsSupplierNotLocked(key);
            return createResources(activityToken, key, classLoader, assetsSupplier);
        } finally {
            Trace.traceEnd(Trace.TRACE_TAG_RESOURCES);
        }
@@ -970,7 +1006,13 @@ public class ResourcesManager {
                    final ResourcesKey newKey = rebaseActivityOverrideConfig(resources, oldConfig,
                            overrideConfig, displayId);
                    if (newKey != null) {
                        updateActivityResources(resources, newKey, false);
                        final ResourcesImpl resourcesImpl =
                                findOrCreateResourcesImplForKeyLocked(newKey);
                        if (resourcesImpl != null && resourcesImpl != resources.getImpl()) {
                            // Set the ResourcesImpl, updating it for all users of this Resources
                            // object.
                            resources.setImpl(resourcesImpl);
                        }
                    }
                }
            }
@@ -1025,24 +1067,6 @@ public class ResourcesManager {
        return newKey;
    }

    private void updateActivityResources(Resources resources, ResourcesKey newKey,
            boolean hasLoader) {
        final ResourcesImpl resourcesImpl;

        if (hasLoader) {
            // Loaders always get new Impls because they cannot be shared
            resourcesImpl = createResourcesImpl(newKey);
        } else {
            resourcesImpl = findOrCreateResourcesImplForKeyLocked(newKey);
        }

        if (resourcesImpl != null && resourcesImpl != resources.getImpl()) {
            // Set the ResourcesImpl, updating it for all users of this Resources
            // object.
            resources.setImpl(resourcesImpl);
        }
    }

    @TestApi
    public final boolean applyConfigurationToResources(@NonNull Configuration config,
            @Nullable CompatibilityInfo compat) {
+32 −9
Original line number Diff line number Diff line
@@ -76,6 +76,10 @@ public class InsetsState implements Parcelable {
            ITYPE_BOTTOM_GESTURES,
            ITYPE_LEFT_GESTURES,
            ITYPE_RIGHT_GESTURES,
            ITYPE_TOP_MANDATORY_GESTURES,
            ITYPE_BOTTOM_MANDATORY_GESTURES,
            ITYPE_LEFT_MANDATORY_GESTURES,
            ITYPE_RIGHT_MANDATORY_GESTURES,
            ITYPE_TOP_TAPPABLE_ELEMENT,
            ITYPE_BOTTOM_TAPPABLE_ELEMENT,
            ITYPE_LEFT_DISPLAY_CUTOUT,
@@ -104,20 +108,27 @@ public class InsetsState implements Parcelable {
    public static final int ITYPE_BOTTOM_GESTURES = 4;
    public static final int ITYPE_LEFT_GESTURES = 5;
    public static final int ITYPE_RIGHT_GESTURES = 6;
    public static final int ITYPE_TOP_TAPPABLE_ELEMENT = 7;
    public static final int ITYPE_BOTTOM_TAPPABLE_ELEMENT = 8;

    public static final int ITYPE_LEFT_DISPLAY_CUTOUT = 9;
    public static final int ITYPE_TOP_DISPLAY_CUTOUT = 10;
    public static final int ITYPE_RIGHT_DISPLAY_CUTOUT = 11;
    public static final int ITYPE_BOTTOM_DISPLAY_CUTOUT = 12;
    /** Additional gesture inset types that map into {@link Type.MANDATORY_SYSTEM_GESTURES}. */
    public static final int ITYPE_TOP_MANDATORY_GESTURES = 7;
    public static final int ITYPE_BOTTOM_MANDATORY_GESTURES = 8;
    public static final int ITYPE_LEFT_MANDATORY_GESTURES = 9;
    public static final int ITYPE_RIGHT_MANDATORY_GESTURES = 10;

    public static final int ITYPE_TOP_TAPPABLE_ELEMENT = 11;
    public static final int ITYPE_BOTTOM_TAPPABLE_ELEMENT = 12;

    public static final int ITYPE_LEFT_DISPLAY_CUTOUT = 13;
    public static final int ITYPE_TOP_DISPLAY_CUTOUT = 14;
    public static final int ITYPE_RIGHT_DISPLAY_CUTOUT = 15;
    public static final int ITYPE_BOTTOM_DISPLAY_CUTOUT = 16;

    /** Input method window. */
    public static final int ITYPE_IME = 13;
    public static final int ITYPE_IME = 17;

    /** Additional system decorations inset type. */
    public static final int ITYPE_CLIMATE_BAR = 14;
    public static final int ITYPE_EXTRA_NAVIGATION_BAR = 15;
    public static final int ITYPE_CLIMATE_BAR = 18;
    public static final int ITYPE_EXTRA_NAVIGATION_BAR = 19;

    static final int LAST_TYPE = ITYPE_EXTRA_NAVIGATION_BAR;
    public static final int SIZE = LAST_TYPE + 1;
@@ -493,6 +504,10 @@ public class InsetsState implements Parcelable {
                return Type.IME;
            case ITYPE_TOP_GESTURES:
            case ITYPE_BOTTOM_GESTURES:
            case ITYPE_TOP_MANDATORY_GESTURES:
            case ITYPE_BOTTOM_MANDATORY_GESTURES:
            case ITYPE_LEFT_MANDATORY_GESTURES:
            case ITYPE_RIGHT_MANDATORY_GESTURES:
                return Type.MANDATORY_SYSTEM_GESTURES;
            case ITYPE_LEFT_GESTURES:
            case ITYPE_RIGHT_GESTURES:
@@ -552,6 +567,14 @@ public class InsetsState implements Parcelable {
                return "ITYPE_LEFT_GESTURES";
            case ITYPE_RIGHT_GESTURES:
                return "ITYPE_RIGHT_GESTURES";
            case ITYPE_TOP_MANDATORY_GESTURES:
                return "ITYPE_TOP_MANDATORY_GESTURES";
            case ITYPE_BOTTOM_MANDATORY_GESTURES:
                return "ITYPE_BOTTOM_MANDATORY_GESTURES";
            case ITYPE_LEFT_MANDATORY_GESTURES:
                return "ITYPE_LEFT_MANDATORY_GESTURES";
            case ITYPE_RIGHT_MANDATORY_GESTURES:
                return "ITYPE_RIGHT_MANDATORY_GESTURES";
            case ITYPE_TOP_TAPPABLE_ELEMENT:
                return "ITYPE_TOP_TAPPABLE_ELEMENT";
            case ITYPE_BOTTOM_TAPPABLE_ELEMENT:
+25 −7
Original line number Diff line number Diff line
@@ -1981,11 +1981,7 @@ public final class ViewRootImpl implements ViewParent,
            mCompatibleVisibilityInfo.globalVisibility =
                    (mCompatibleVisibilityInfo.globalVisibility & ~View.SYSTEM_UI_FLAG_LOW_PROFILE)
                            | (mAttachInfo.mSystemUiVisibility & View.SYSTEM_UI_FLAG_LOW_PROFILE);
            if (mDispatchedSystemUiVisibility != mCompatibleVisibilityInfo.globalVisibility) {
                mHandler.removeMessages(MSG_DISPATCH_SYSTEM_UI_VISIBILITY);
                mHandler.sendMessage(mHandler.obtainMessage(
                        MSG_DISPATCH_SYSTEM_UI_VISIBILITY, mCompatibleVisibilityInfo));
            }
            dispatchDispatchSystemUiVisibilityChanged(mCompatibleVisibilityInfo);
            if (mAttachInfo.mKeepScreenOn != oldScreenOn
                    || mAttachInfo.mSystemUiVisibility != params.subtreeSystemUiVisibility
                    || mAttachInfo.mHasSystemUiListeners != params.hasSystemUiListeners) {
@@ -2039,9 +2035,30 @@ public final class ViewRootImpl implements ViewParent,
            info.globalVisibility |= systemUiFlag;
            info.localChanges &= ~systemUiFlag;
        }
        if (mDispatchedSystemUiVisibility != info.globalVisibility) {
        dispatchDispatchSystemUiVisibilityChanged(info);
    }

    /**
     * If the system is forcing showing any system bar, the legacy low profile flag should be
     * cleared for compatibility.
     *
     * @param showTypes {@link InsetsType types} shown by the system.
     * @param fromIme {@code true} if the invocation is from IME.
     */
    private void clearLowProfileModeIfNeeded(@InsetsType int showTypes, boolean fromIme) {
        final SystemUiVisibilityInfo info = mCompatibleVisibilityInfo;
        if ((showTypes & Type.systemBars()) != 0 && !fromIme
                && (info.globalVisibility & SYSTEM_UI_FLAG_LOW_PROFILE) != 0) {
            info.globalVisibility &= ~SYSTEM_UI_FLAG_LOW_PROFILE;
            info.localChanges |= SYSTEM_UI_FLAG_LOW_PROFILE;
            dispatchDispatchSystemUiVisibilityChanged(info);
        }
    }

    private void dispatchDispatchSystemUiVisibilityChanged(SystemUiVisibilityInfo args) {
        if (mDispatchedSystemUiVisibility != args.globalVisibility) {
            mHandler.removeMessages(MSG_DISPATCH_SYSTEM_UI_VISIBILITY);
            mHandler.sendMessage(mHandler.obtainMessage(MSG_DISPATCH_SYSTEM_UI_VISIBILITY, info));
            mHandler.sendMessage(mHandler.obtainMessage(MSG_DISPATCH_SYSTEM_UI_VISIBILITY, args));
        }
    }

@@ -5008,6 +5025,7 @@ public final class ViewRootImpl implements ViewParent,
                                String.format("Calling showInsets(%d,%b) on window that no longer"
                                        + " has views.", msg.arg1, msg.arg2 == 1));
                    }
                    clearLowProfileModeIfNeeded(msg.arg1, msg.arg2 == 1);
                    mInsetsController.show(msg.arg1, msg.arg2 == 1);
                    break;
                }
+7 −5

File changed.

Preview size limit exceeded, changes collapsed.

Loading