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.util.Log; | |
| 9 | |
| 10 import java.lang.reflect.Constructor; | |
| 11 import java.lang.reflect.InvocationTargetException; | |
| 12 import java.util.ArrayList; | |
| 13 import java.util.List; | |
| 14 | |
| 15 /** | |
| 16 * Provides the list of available {@link CronetProvider} instances. | |
| 17 */ | |
|
pauljensen
2017/01/18 17:03:04
what about prefacing this with something like:
<b
kapishnikov
2017/01/19 01:25:24
Done. After the description; otherwise, it will no
| |
| 18 public class CronetProviders { | |
| 19 private static final String TAG = CronetProvider.class.getSimpleName(); | |
| 20 | |
| 21 /** | |
| 22 * The key in the app string resource file that is be searched | |
| 23 * for an alternative implementation. | |
| 24 */ | |
| 25 private static final String RES_KEY_CRONET_IMPL_CLASS = "CronetProviderClass Name"; | |
| 26 | |
| 27 private static CronetProviders sSingleton = new CronetProviders(); | |
|
pauljensen
2017/01/18 17:03:04
nit: rename to sInstance
kapishnikov
2017/01/19 01:25:24
Done.
| |
| 28 | |
| 29 private CronetProviders() {} | |
| 30 | |
| 31 public static CronetProviders instance() { | |
|
pauljensen
2017/01/18 17:03:04
I think this kind of function is normally called g
kapishnikov
2017/01/19 01:25:24
Done.
| |
| 32 return sSingleton; | |
| 33 } | |
| 34 | |
| 35 /** | |
| 36 * Name of the Java {@link CronetProvider} class. | |
| 37 */ | |
| 38 private static final String JAVA_CRONET_PROVIDER_CLASS = | |
| 39 "org.chromium.net.impl.JavaCronetProvider"; | |
| 40 | |
| 41 /** | |
| 42 * Name of the native {@link CronetProvider} class. | |
| 43 */ | |
| 44 private static final String NATIVE_CRONET_PROVIDER_CLASS = | |
| 45 "org.chromium.net.impl.NativeCronetProvider"; | |
| 46 | |
| 47 /** | |
| 48 * Returns the found list of available providers. | |
| 49 * The providers are added in the following order: | |
| 50 * <ul> | |
| 51 * <li>Class name specified as "CronetProviderClassName" application string resource.</li> | |
| 52 * <li>The default Cronet implementation</li> | |
| 53 * </ul> | |
| 54 * | |
| 55 * Some of the returned provider may be in a disabled state and should be en abled by | |
| 56 * the invoker. See {@link CronetProvider#isEnabled()}. | |
| 57 * | |
| 58 * @return the list of available providers. | |
| 59 */ | |
| 60 public List<CronetProvider> getAvailableProviders(Context context) { | |
| 61 List<CronetProvider> providers = new ArrayList<>(); | |
| 62 addCronetProviderFromResourceFile(context, providers); | |
| 63 addCronetProviderImplByClassName(context, NATIVE_CRONET_PROVIDER_CLASS, providers, false); | |
| 64 addCronetProviderImplByClassName(context, JAVA_CRONET_PROVIDER_CLASS, pr oviders, false); | |
| 65 return providers; | |
|
pauljensen
2017/01/18 17:03:04
how slow is this? should we cache the list?
mef
2017/01/18 20:57:54
Can it change? For example if ProviderFromResource
kapishnikov
2017/01/19 01:25:24
It should not be slow and normally it will be call
mef
2017/01/19 22:57:46
In this case what's the point of mInstance and get
kapishnikov
2017/01/20 16:21:53
A singleton provides more flexibility since it can
pauljensen
2017/01/20 17:13:34
Can you quantify that?
kapishnikov
2017/01/20 21:48:37
Yes, it will be called every time the default Cron
| |
| 66 } | |
| 67 | |
| 68 /** | |
| 69 * Adds a new provider referenced by the class name to the end of the list. | |
| 70 * | |
| 71 * @param className the class name of the provider that shoul dbe instantiat ed. | |
|
mef
2017/01/18 20:57:54
nit: s/shoul dbe/should be/
kapishnikov
2017/01/19 01:25:24
Done.
| |
| 72 * @param providers the list of providers to add the new provider to. | |
| 73 * @return true if the provider was added. | |
| 74 */ | |
| 75 private boolean addCronetProviderImplByClassName( | |
|
pauljensen
2017/01/18 17:03:04
nit: prefix with "maybe" as it can silently fail.
kapishnikov
2017/01/19 01:25:24
The return value implies that the provider may not
pauljensen
2017/01/20 17:13:34
Change the javadoc to start with "Attempts to add"
kapishnikov
2017/01/20 21:48:38
Done.
| |
| 76 Context context, String className, List<CronetProvider> providers, b oolean logError) { | |
| 77 ClassLoader loader = this.getClass().getClassLoader(); | |
| 78 try { | |
| 79 Class<? extends CronetProvider> providerClass = | |
| 80 loader.loadClass(className).asSubclass(CronetProvider.class) ; | |
| 81 Constructor<? extends CronetProvider> ctor = | |
| 82 providerClass.getConstructor(Context.class); | |
| 83 providers.add(ctor.newInstance(context)); | |
| 84 return true; | |
| 85 } catch (InstantiationException e) { | |
| 86 logReflectiveOperationException(className, logError, e); | |
| 87 } catch (InvocationTargetException e) { | |
| 88 logReflectiveOperationException(className, logError, e); | |
| 89 } catch (NoSuchMethodException e) { | |
| 90 logReflectiveOperationException(className, logError, e); | |
| 91 } catch (IllegalAccessException e) { | |
| 92 logReflectiveOperationException(className, logError, e); | |
| 93 } catch (ClassNotFoundException e) { | |
| 94 logReflectiveOperationException(className, logError, e); | |
| 95 } | |
| 96 return false; | |
| 97 } | |
| 98 | |
| 99 /** | |
| 100 * De-duplicates exception handling logic in {@link #addCronetProviderImplBy ClassName}. | |
| 101 * It should be removed when support of API Levels lower than 19 is deprecat ed. | |
| 102 */ | |
| 103 private void logReflectiveOperationException(String className, boolean logEr ror, Exception e) { | |
|
pauljensen
2017/01/18 17:03:04
nit: for this and all other private functions, can
kapishnikov
2017/01/19 01:25:24
Done.
| |
| 104 if (logError) { | |
| 105 Log.e(TAG, "Unable to load provider class: " + className, e); | |
| 106 } else { | |
| 107 Log.d(TAG, "Tried to load " + className + " provider class but it wa sn't" | |
| 108 + " included in the app classpath"); | |
| 109 } | |
| 110 } | |
| 111 | |
| 112 /** | |
| 113 * Adds a provider specified in the app resource file to the end of the prov ider list. | |
| 114 * | |
| 115 * @param providers the list of providers to add the new provider to. | |
| 116 * @return true if the provider was added. | |
| 117 */ | |
| 118 private boolean addCronetProviderFromResourceFile( | |
|
pauljensen
2017/01/18 17:03:04
nit: prefix with "maybe" as it can silently fail.
kapishnikov
2017/01/19 01:25:24
Added extra documentation to the @return.
pauljensen
2017/01/20 17:13:34
Change the javadoc to start with "Attempts to add"
kapishnikov
2017/01/20 21:48:37
Done. Also added @throws RuntimeException
| |
| 119 Context context, List<CronetProvider> providers) { | |
| 120 int resId = context.getResources().getIdentifier( | |
| 121 RES_KEY_CRONET_IMPL_CLASS, "string", context.getPackageName()); | |
| 122 // Resource not found | |
| 123 if (resId == 0) { | |
| 124 // The resource wasn't included in the app; therefore, there is noth ing to add. | |
| 125 return false; | |
| 126 } | |
| 127 String className = context.getResources().getString(resId); | |
| 128 | |
| 129 boolean added = addCronetProviderImplByClassName(context, className, pro viders, true); | |
| 130 | |
| 131 if (!added) { | |
| 132 Log.e(TAG, "Unable to instantiate Cronet implementation class " + cl assName | |
| 133 + " that is listed as in the app string resource fil e under" | |
| 134 + RES_KEY_CRONET_IMPL_CLASS + " key"); | |
|
pauljensen
2017/01/18 17:03:04
I think this should throw, not just log. I think
mef
2017/01/18 20:57:54
I disagree, this could represent that provider isn
kapishnikov
2017/01/19 01:25:24
Actually, the provider should be packaged inside t
| |
| 135 } | |
| 136 return added; | |
| 137 } | |
| 138 } | |
| OLD | NEW |