1 // Copyright 2023 The Chromium Authors 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 package org.chromium.testing.local; 6 7 import com.google.auto.service.AutoService; 8 9 import org.json.JSONArray; 10 import org.json.JSONException; 11 import org.json.JSONObject; 12 import org.robolectric.annotation.Config; 13 import org.robolectric.config.AndroidConfigurer; 14 import org.robolectric.internal.bytecode.InstrumentationConfiguration; 15 import org.robolectric.internal.bytecode.ShadowProviders; 16 17 import java.util.Optional; 18 import java.util.ServiceLoader; 19 20 /** 21 * Tells Robolectric which classes to exclude from its sandbox. This is required to avoid the need 22 * to create a new Robolectric ClassLoader for each distinct set of Shadows. 23 */ 24 @AutoService(AndroidConfigurer.class) 25 public class ChromiumAndroidConfigurer extends AndroidConfigurer { 26 public interface ExtraConfiguration { withConfig(InstrumentationConfiguration.Builder builder, Config config)27 void withConfig(InstrumentationConfiguration.Builder builder, Config config); 28 } 29 30 private static JSONObject sConfigJson; 31 private Optional<ExtraConfiguration> mExtraConfig; 32 setJsonConfig(JSONObject root)33 static void setJsonConfig(JSONObject root) { 34 sConfigJson = root; 35 } 36 ChromiumAndroidConfigurer(ShadowProviders shadowProviders)37 public ChromiumAndroidConfigurer(ShadowProviders shadowProviders) { 38 super(shadowProviders); 39 mExtraConfig = ServiceLoader.load(ExtraConfiguration.class).findFirst(); 40 } 41 42 @Override withConfig(InstrumentationConfiguration.Builder builder, Config config)43 public void withConfig(InstrumentationConfiguration.Builder builder, Config config) { 44 super.withConfig(builder, config); 45 try { 46 JSONArray instrumentedPackages = sConfigJson.getJSONArray("instrumentedPackages"); 47 for (int i = 0, len = instrumentedPackages.length(); i < len; ++i) { 48 builder.addInstrumentedPackage(instrumentedPackages.getString(i)); 49 } 50 JSONArray instrumentedClasses = sConfigJson.getJSONArray("instrumentedClasses"); 51 for (int i = 0, len = instrumentedClasses.length(); i < len; ++i) { 52 builder.addInstrumentedClass(instrumentedClasses.getString(i)); 53 } 54 } catch (JSONException e) { 55 throw new RuntimeException(e); 56 } 57 if (mExtraConfig.isPresent()) { 58 mExtraConfig.get().withConfig(builder, config); 59 } 60 } 61 } 62