blob: 1c3d884e3a988c83dc70d9228d8811c1572b99b4 [file] [log] [blame]
/*
* 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.pm;
import android.annotation.NonNull;
import android.annotation.Nullable;
import com.android.server.IntentResolver;
import com.android.server.utils.Snappable;
import com.android.server.utils.Watchable;
import com.android.server.utils.WatchableImpl;
import com.android.server.utils.Watcher;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
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 WatchedIntentResolver<F extends WatchedIntentFilter,
R extends WatchedIntentFilter>
extends IntentResolver<F, R>
implements Watchable, Snappable {
/**
* Watchable machinery
*/
private final Watchable mWatchable = new WatchableImpl();
/**
* Register an observer to receive change notifications.
* @param observer The observer to register.
*/
@Override
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.
*/
@Override
public void unregisterObserver(@NonNull Watcher observer) {
mWatchable.unregisterObserver(observer);
}
/**
* Return true if the {@link Watcher) is a registered observer.
* @param observer A {@link Watcher} that might be registered
* @return true if the observer is registered with this {@link Watchable}.
*/
@Override
public boolean isRegisteredObserver(@NonNull Watcher observer) {
return mWatchable.isRegisteredObserver(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.
*/
@Override
public void dispatchChange(@Nullable Watchable what) {
mWatchable.dispatchChange(what);
}
private final Watcher mWatcher = new Watcher() {
@Override
public void onChange(@Nullable Watchable what) {
dispatchChange(what);
}
};
/**
* Notify listeners that this object has changed.
*/
protected void onChanged() {
dispatchChange(this);
}
@Override
public void addFilter(F f) {
super.addFilter(f);
f.registerObserver(mWatcher);
onChanged();
}
@Override
public void removeFilter(F f) {
f.unregisterObserver(mWatcher);
super.removeFilter(f);
onChanged();
}
@Override
protected void removeFilterInternal(F f) {
f.unregisterObserver(mWatcher);
super.removeFilterInternal(f);
onChanged();
}
// Sorts a List of IntentFilter objects into descending priority order.
@SuppressWarnings("rawtypes")
private static final Comparator<WatchedIntentFilter> sResolvePrioritySorter =
new Comparator<>() {
public int compare(WatchedIntentFilter o1, WatchedIntentFilter o2) {
final int q1 = o1.getPriority();
final int q2 = o2.getPriority();
return (q1 > q2) ? -1 : ((q1 < q2) ? 1 : 0);
}
};
@Override
@SuppressWarnings("unchecked")
protected void sortResults(List<R> results) {
Collections.sort(results, sResolvePrioritySorter);
}
/**
* @see IntentResolver#findFilters(IntentFilter)
*/
public ArrayList<F> findFilters(WatchedIntentFilter matching) {
return super.findFilters(matching.getIntentFilter());
}
// Make <this> a copy of <orig>. The presumption is that <this> is empty but all
// arrays are cleared out explicitly, just to be sure.
protected void copyFrom(WatchedIntentResolver orig) {
super.copyFrom(orig);
}
}