1818import android .os .StrictMode ;
1919import androidx .annotation .RestrictTo ;
2020import java .util .ArrayList ;
21+ import java .util .HashSet ;
2122import java .util .List ;
2223import java .util .ServiceLoader ;
24+ import java .util .Set ;
2325
2426/**
2527 * Wrapper class for {@link ServiceLoader} that disables StrictMode.
@@ -86,7 +88,7 @@ public static <T> T loadSingleService(Class<T> serviceClass, Factory<T> defaultI
8688 * @throws IllegalStateException if more than one service implementations are found
8789 */
8890 public static <T > T loadSingleServiceOrNull (Class <T > serviceClass ) {
89- List <T > impls = ServiceLoaderWrapper .loadService (serviceClass );
91+ List <T > impls = filter ( ServiceLoaderWrapper .loadService (serviceClass ) );
9092 if (impls .isEmpty ()) {
9193 return null ;
9294 } else if (impls .size () == 1 ) {
@@ -102,4 +104,27 @@ public static <T> T loadSingleServiceOrNull(Class<T> serviceClass) {
102104 "Found more than one implementation for " + serviceClass .getName () + combinedImpls );
103105 }
104106 }
107+
108+ @ SuppressWarnings ("unchecked" )
109+ private static <T > List <T > filter (List <T > services ) {
110+ Set <Class <?>> superseded = new HashSet <>();
111+ for (T service : services ) {
112+ Class <? extends T > clazz = (Class <? extends T >) service .getClass ();
113+ Supersedes supersedes = clazz .getAnnotation (Supersedes .class );
114+ if (supersedes != null ) {
115+ superseded .add (supersedes .value ());
116+ }
117+ }
118+ if (superseded .isEmpty ()) {
119+ return services ;
120+ } else {
121+ List <T > filtered = new ArrayList <>();
122+ for (T service : services ) {
123+ if (!superseded .contains (service .getClass ())) {
124+ filtered .add (service );
125+ }
126+ }
127+ return filtered ;
128+ }
129+ }
105130}
0 commit comments