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