/* * Copyright (C) 2019 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 android.content.res.loader; import android.annotation.NonNull; import android.content.res.ApkAssets; import android.content.res.Resources; import android.util.ArrayMap; import android.util.ArraySet; import com.android.internal.annotations.GuardedBy; import com.android.internal.util.ArrayUtils; import java.lang.ref.WeakReference; import java.util.Arrays; import java.util.Collections; import java.util.List; /** * A container for supplying {@link ResourcesProvider ResourcesProvider(s)} to {@link Resources} * objects. * *
{@link ResourcesLoader ResourcesLoader(s)} are added to Resources objects to supply * additional resources and assets or modify the values of existing resources and assets. Multiple * Resources objects can share the same ResourcesLoaders and ResourcesProviders. Changes to the list * of {@link ResourcesProvider ResourcesProvider(s)} a loader contains propagates to all Resources * objects that use the loader. * *
Loaders must be added to Resources objects in increasing precedence order. A loader will * override the resources and assets of loaders added before itself. * *
Providers retrieved with {@link #getProviders()} are listed in increasing precedence order. A * provider will override the resources and assets of providers listed before itself. * *
Modifying the list of providers a loader contains or the list of loaders a Resources object
* contains can cause lock contention with the UI thread. APIs that modify the lists of loaders or
* providers should only be used on the UI thread. Providers can be instantiated on any thread
* without causing lock contention.
*/
public class ResourcesLoader {
private final Object mLock = new Object();
@GuardedBy("mLock")
private ApkAssets[] mApkAssets;
@GuardedBy("mLock")
private ResourcesProvider[] mPreviousProviders;
@GuardedBy("mLock")
private ResourcesProvider[] mProviders;
@GuardedBy("mLock")
private ArrayMap This should only be called from the UI thread to avoid lock contention when propagating
* provider changes.
*
* @param resourcesProvider the provider to add
*/
public void addProvider(@NonNull ResourcesProvider resourcesProvider) {
synchronized (mLock) {
mProviders = ArrayUtils.appendElement(ResourcesProvider.class, mProviders,
resourcesProvider);
notifyProvidersChangedLocked();
}
}
/**
* Removes a provider from the provider list. If the provider is not present in the provider
* list, the list will not be modified.
*
* This should only be called from the UI thread to avoid lock contention when propagating
* provider changes.
*
* @param resourcesProvider the provider to remove
*/
public void removeProvider(@NonNull ResourcesProvider resourcesProvider) {
synchronized (mLock) {
mProviders = ArrayUtils.removeElement(ResourcesProvider.class, mProviders,
resourcesProvider);
notifyProvidersChangedLocked();
}
}
/**
* Sets the list of providers.
*
* This should only be called from the UI thread to avoid lock contention when propagating
* provider changes.
*
* @param resourcesProviders the new providers
*/
public void setProviders(@NonNull List This should only be called from the UI thread to avoid lock contention when propagating
* provider changes.
*/
public void clearProviders() {
synchronized (mLock) {
mProviders = null;
notifyProvidersChangedLocked();
}
}
/**
* Retrieves the list of {@link ApkAssets} used by the providers.
*
* @hide
*/
@NonNull
public List