Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright 2017 The Chromium Authors. All rights reserved. | |
| 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.net; | |
| 6 | |
| 7 import android.content.Context; | |
| 8 import android.support.annotation.VisibleForTesting; | |
| 9 import android.util.Log; | |
| 10 | |
| 11 import java.lang.reflect.Constructor; | |
| 12 import java.lang.reflect.InvocationTargetException; | |
| 13 import java.util.ArrayList; | |
| 14 import java.util.Collections; | |
| 15 import java.util.List; | |
| 16 | |
| 17 /** | |
| 18 * Provides the list of available {@link CronetProvider} instances. | |
| 19 * <p/> | |
| 20 * <b>NOTE:</b> This class is for advanced users that want to select a particula r | |
| 21 * Cronet implementation. Most users should simply use {@code new} {@link | |
| 22 * CronetEngine.Builder#CronetEngine.Builder(android.content.Context)}. | |
| 23 */ | |
| 24 public class CronetProviders { | |
| 25 private static final String TAG = CronetProvider.class.getSimpleName(); | |
| 26 | |
| 27 /** | |
| 28 * String returned by {@link CronetProvider#getName} for {@link CronetProvid er} | |
| 29 * that provides Cronet implementation based on the system's | |
| 30 * {@link java.net.HttpURLConnection} implementation. This implementation | |
| 31 * offers significantly degraded performance relative to native Cronet | |
| 32 * implementations (see {@link #PROVIDER_NAME_NATIVE}). | |
| 33 */ | |
| 34 public static final String PROVIDER_NAME_PLATFORM = "Platform-Cronet-Provide r"; | |
| 35 | |
| 36 /** | |
| 37 * String returned by {@link CronetProvider#getName} for {@link CronetProvid er} | |
| 38 * that provides native Cronet implementation. This implementation | |
| 39 * offers significantly higher performance relative to the system Cronet | |
| 40 * implementations (see {@link #PROVIDER_NAME_PLATFORM}). | |
|
pauljensen
2017/01/23 14:44:29
I don't understand "system Cronet implementation",
| |
| 41 */ | |
| 42 public static final String PROVIDER_NAME_NATIVE = "Native-Cronet-Provider"; | |
| 43 | |
| 44 /** | |
| 45 * The key in the app string resource file that is be searched | |
| 46 * for an alternative implementation. | |
| 47 */ | |
| 48 private static final String RES_KEY_CRONET_IMPL_CLASS = "CronetProviderClass Name"; | |
| 49 | |
| 50 private static CronetProviders sInstance = new CronetProviders(); | |
| 51 private List<CronetProvider> mProviders; | |
| 52 private final Object mLock = new Object(); | |
|
pauljensen
2017/01/23 14:44:29
swap these two lines and add @GuardedBy
| |
| 53 | |
| 54 @VisibleForTesting | |
| 55 CronetProviders() {} | |
| 56 | |
| 57 /** | |
| 58 * Returns an instance of {@link CronetProviders}. | |
| 59 * | |
| 60 * @return an instance of {@code CronetProviders}. | |
| 61 */ | |
| 62 public static CronetProviders getInstance() { | |
| 63 return sInstance; | |
| 64 } | |
| 65 | |
| 66 /** | |
| 67 * Name of the Java {@link CronetProvider} class. | |
| 68 */ | |
| 69 private static final String JAVA_CRONET_PROVIDER_CLASS = | |
| 70 "org.chromium.net.impl.JavaCronetProvider"; | |
| 71 | |
| 72 /** | |
| 73 * Name of the native {@link CronetProvider} class. | |
| 74 */ | |
| 75 private static final String NATIVE_CRONET_PROVIDER_CLASS = | |
| 76 "org.chromium.net.impl.NativeCronetProvider"; | |
| 77 | |
| 78 /** | |
| 79 * Returns an unmodifiable list of all available {@link CronetProvider}s. | |
| 80 * The providers are returned in no particular order. Some of the returned | |
| 81 * providers may be in a disabled state and should be enabled by the invoker . | |
| 82 * See {@link CronetProvider#isEnabled()}. | |
| 83 * | |
| 84 * @return the list of available providers. | |
| 85 */ | |
| 86 public List<CronetProvider> getAllProviders(Context context) { | |
|
pauljensen
2017/01/23 14:44:29
I really think we should move this to CronetProvid
| |
| 87 synchronized (mLock) { | |
| 88 if (mProviders != null) { | |
| 89 return mProviders; | |
| 90 } | |
| 91 List<CronetProvider> providers = new ArrayList<>(); | |
| 92 addCronetProviderFromResourceFile(context, providers); | |
| 93 addCronetProviderImplByClassName( | |
| 94 context, NATIVE_CRONET_PROVIDER_CLASS, providers, false); | |
| 95 addCronetProviderImplByClassName(context, JAVA_CRONET_PROVIDER_CLASS , providers, false); | |
| 96 mProviders = Collections.unmodifiableList(providers); | |
| 97 return mProviders; | |
| 98 } | |
| 99 } | |
| 100 | |
| 101 /** | |
| 102 * Attempts to add a new provider referenced by the class name to the end of the list. | |
| 103 * | |
| 104 * @param className the class name of the provider that should be instantiat ed. | |
| 105 * @param providers the list of providers to add the new provider to. | |
| 106 * @return {@code true} if the provider was added to the list; {@code false} | |
| 107 * if the provider couldn't be instantiated. | |
| 108 */ | |
| 109 private static boolean addCronetProviderImplByClassName( | |
| 110 Context context, String className, List<CronetProvider> providers, b oolean logError) { | |
| 111 ClassLoader loader = context.getClassLoader(); | |
| 112 try { | |
| 113 Class<? extends CronetProvider> providerClass = | |
| 114 loader.loadClass(className).asSubclass(CronetProvider.class) ; | |
| 115 Constructor<? extends CronetProvider> ctor = | |
| 116 providerClass.getConstructor(Context.class); | |
| 117 providers.add(ctor.newInstance(context)); | |
| 118 return true; | |
| 119 } catch (InstantiationException e) { | |
| 120 logReflectiveOperationException(className, logError, e); | |
| 121 } catch (InvocationTargetException e) { | |
| 122 logReflectiveOperationException(className, logError, e); | |
| 123 } catch (NoSuchMethodException e) { | |
| 124 logReflectiveOperationException(className, logError, e); | |
| 125 } catch (IllegalAccessException e) { | |
| 126 logReflectiveOperationException(className, logError, e); | |
| 127 } catch (ClassNotFoundException e) { | |
| 128 logReflectiveOperationException(className, logError, e); | |
| 129 } | |
| 130 return false; | |
| 131 } | |
| 132 | |
| 133 /** | |
| 134 * De-duplicates exception handling logic in {@link #addCronetProviderImplBy ClassName}. | |
| 135 * It should be removed when support of API Levels lower than 19 is deprecat ed. | |
| 136 */ | |
| 137 private static void logReflectiveOperationException( | |
| 138 String className, boolean logError, Exception e) { | |
| 139 if (logError) { | |
| 140 Log.e(TAG, "Unable to load provider class: " + className, e); | |
| 141 } else { | |
| 142 Log.d(TAG, "Tried to load " + className + " provider class but it wa sn't" | |
| 143 + " included in the app classpath"); | |
| 144 } | |
| 145 } | |
| 146 | |
| 147 /** | |
| 148 * Attempts to add a provider specified in the app resource file to the end | |
| 149 * of the provider list. | |
| 150 * | |
| 151 * @param providers the list of providers to add the new provider to. | |
| 152 * @return {@code true} if the provider was added to the list; {@code false} | |
| 153 * if the app resources do not include the string with | |
| 154 * {@link #RES_KEY_CRONET_IMPL_CLASS} key. | |
| 155 * @throws RuntimeException if the provider cannot be found or instantiated. | |
| 156 */ | |
| 157 private static boolean addCronetProviderFromResourceFile( | |
| 158 Context context, List<CronetProvider> providers) { | |
| 159 int resId = context.getResources().getIdentifier( | |
| 160 RES_KEY_CRONET_IMPL_CLASS, "string", context.getPackageName()); | |
| 161 // Resource not found | |
| 162 if (resId == 0) { | |
| 163 // The resource wasn't included in the app; therefore, there is noth ing to add. | |
| 164 return false; | |
| 165 } | |
| 166 String className = context.getResources().getString(resId); | |
| 167 | |
| 168 if (!addCronetProviderImplByClassName(context, className, providers, tru e)) { | |
| 169 throw new RuntimeException("Unable to instantiate Cronet implementat ion class " | |
| 170 + className + " that is listed as in the app string resource file under" | |
| 171 + RES_KEY_CRONET_IMPL_CLASS + " key"); | |
| 172 } | |
| 173 return true; | |
| 174 } | |
| 175 } | |
| OLD | NEW |