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

Commit f9270393 authored by Lee Shombert's avatar Lee Shombert
Browse files

PackageManager lock reduction: IntentResolver

Bug: 161323622

Modify the IntentResolver classes used by PackageManagerServer to be
Watchable and Snappable.

Test: atest
 * FrameworksServicesTests:UserSystemPackageInstallerTest
 * FrameworksServicesTests:PackageManagerSettingsTests
 * FrameworksServicesTests:PackageManagerServiceTest
 * FrameworksServicesTests:AppsFilterTest
 * FrameworksServicesTests:PackageInstallerSessionTest
 * FrameworksServicesTests:ScanTests
 * FrameworksServicesTests:WatcherTest

Change-Id: Ifb243cf9da801462fdaef3bcf5786a80fac202f2
parent 0b54fc0d
Loading
Loading
Loading
Loading
+11 −0
Original line number Diff line number Diff line
@@ -839,6 +839,17 @@ public abstract class IntentResolver<F, R extends Object> {
        }
    };

    // Make <this> a copy of <orig>.  The presumption is that <this> is empty.
    protected void doCopy(IntentResolver orig) {
        mFilters.addAll(orig.mFilters);
        mTypeToFilter.putAll(orig.mTypeToFilter);
        mBaseTypeToFilter.putAll(orig.mBaseTypeToFilter);
        mWildTypeToFilter.putAll(orig.mWildTypeToFilter);
        mSchemeToFilter.putAll(orig.mSchemeToFilter);
        mActionToFilter.putAll(orig.mActionToFilter);
        mTypedActionToFilter.putAll(orig.mTypedActionToFilter);
    }

    /**
     * All filters that have been registered.
     */
+16 −4
Original line number Diff line number Diff line
@@ -14,21 +14,22 @@
 * limitations under the License.
 */


package com.android.server.pm;


import android.annotation.NonNull;
import android.content.IntentFilter;

import com.android.server.IntentResolver;
import com.android.server.utils.Snappable;
import com.android.server.utils.WatchableIntentResolver;

import java.util.List;

/**
 * Used to find a list of {@link CrossProfileIntentFilter}s that match an intent.
 */
class CrossProfileIntentResolver
        extends IntentResolver<CrossProfileIntentFilter, CrossProfileIntentFilter> {
        extends WatchableIntentResolver<CrossProfileIntentFilter, CrossProfileIntentFilter>
        implements Snappable {
    @Override
    protected CrossProfileIntentFilter[] newArray(int size) {
        return new CrossProfileIntentFilter[size];
@@ -48,4 +49,15 @@ class CrossProfileIntentResolver
    protected IntentFilter getIntentFilter(@NonNull CrossProfileIntentFilter input) {
        return input;
    }

    /**
     * Return a snapshot of the current object.  The snapshot is a read-only copy suitable
     * for read-only methods.
     * @return A snapshot of the current object.
     */
    public CrossProfileIntentResolver snapshot() {
        CrossProfileIntentResolver result = new CrossProfileIntentResolver();
        result.doCopy(this);
        return result;
    }
}
+15 −2
Original line number Diff line number Diff line
@@ -19,10 +19,12 @@ package com.android.server.pm;
import android.annotation.NonNull;
import android.content.IntentFilter;

import com.android.server.IntentResolver;
import com.android.server.utils.Snappable;
import com.android.server.utils.WatchableIntentResolver;

public class PersistentPreferredIntentResolver
        extends IntentResolver<PersistentPreferredActivity, PersistentPreferredActivity> {
        extends WatchableIntentResolver<PersistentPreferredActivity, PersistentPreferredActivity>
        implements Snappable {
    @Override
    protected PersistentPreferredActivity[] newArray(int size) {
        return new PersistentPreferredActivity[size];
@@ -37,4 +39,15 @@ public class PersistentPreferredIntentResolver
    protected boolean isPackageForFilter(String packageName, PersistentPreferredActivity filter) {
        return packageName.equals(filter.mComponent.getPackageName());
    }

    /**
     * Return a snapshot of the current object.  The snapshot is a read-only copy suitable
     * for read-only methods.
     * @return A snapshot of the current object.
     */
    public PersistentPreferredIntentResolver snapshot() {
        PersistentPreferredIntentResolver result = new PersistentPreferredIntentResolver();
        result.doCopy(this);
        return result;
    }
}
+16 −3
Original line number Diff line number Diff line
@@ -19,13 +19,15 @@ package com.android.server.pm;
import android.annotation.NonNull;
import android.content.IntentFilter;

import java.io.PrintWriter;
import com.android.server.utils.Snappable;
import com.android.server.utils.WatchableIntentResolver;

import com.android.server.IntentResolver;
import java.io.PrintWriter;
import java.util.ArrayList;

public class PreferredIntentResolver
        extends IntentResolver<PreferredActivity, PreferredActivity> {
        extends WatchableIntentResolver<PreferredActivity, PreferredActivity>
        implements Snappable {
    @Override
    protected PreferredActivity[] newArray(int size) {
        return new PreferredActivity[size];
@@ -66,4 +68,15 @@ public class PreferredIntentResolver
        }
        return true;
    }

    /**
     * Return a snapshot of the current object.  The snapshot is a read-only copy suitable
     * for read-only methods.
     * @return A snapshot of the current object.
     */
    public PreferredIntentResolver snapshot() {
        PreferredIntentResolver result = new PreferredIntentResolver();
        result.doCopy(this);
        return result;
    }
}
+93 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2020 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.server.utils;

import android.annotation.NonNull;
import android.annotation.Nullable;

import com.android.server.IntentResolver;

import java.util.List;

/**
 * A watched {@link IntentResolver}.  The parameters are inherited from the superclass.
 * @param <F> The filter type
 * @param <R> The resolver type.
 * {@hide}
 */
public abstract class WatchableIntentResolver<F, R extends Object>
        extends IntentResolver<F, R>
        implements Watchable {

    /**
     * Watchable machinery
     */
    private final Watchable mWatchable = new WatchableImpl();
    /**
     * Register an observer to receive change notifications.
     * @param observer The observer to register.
     */
    public void registerObserver(@NonNull Watcher observer) {
        mWatchable.registerObserver(observer);
    }
    /**
     * Unregister the observer, which will no longer receive change notifications.
     * @param observer The observer to unregister.
     */
    public void unregisterObserver(@NonNull Watcher observer) {
        mWatchable.unregisterObserver(observer);
    }
    /**
     * Notify listeners that the object has changd.  The argument is a hint as to the
     * source of the change.
     * @param what The attribute or sub-object that changed, if not null.
     */
    public void dispatchChange(@Nullable Watchable what) {
        mWatchable.dispatchChange(what);
    }
    /**
     * Notify listeners that this object has changed.
     */
    protected void onChanged() {
        dispatchChange(this);
    }

    @Override
    public void addFilter(F f) {
        super.addFilter(f);
        onChanged();
    }

    @Override
    public void removeFilter(F f) {
        super.removeFilter(f);
        onChanged();
    }

    @Override
    protected void removeFilterInternal(F f) {
        super.removeFilterInternal(f);
        onChanged();
    }

    @Override
    @SuppressWarnings("unchecked")
    protected void sortResults(List<R> results) {
        super.sortResults(results);
        onChanged();
    }
}