@Override @Nullable public LoadData<InputStream> buildLoadData(@NonNull Model model, int width, int height, @NonNull Options options) { GlideUrl result = null; if (modelCache != null) { result = modelCache.get(model, width, height); } if (result == null) { String stringURL = getUrl(model, width, height, options); if (TextUtils.isEmpty(stringURL)) { return null; } result = new GlideUrl(stringURL, getHeaders(model, width, height, options)); if (modelCache != null) { modelCache.put(model, width, height, result); } } // TODO: this is expensive and slow to calculate every time, we should either cache these, or // try to come up with a way to avoid finding them when not necessary. List<String> alternateUrls = getAlternateUrls(model, width, height, options); LoadData<InputStream> concreteLoaderData = concreteLoader.buildLoadData(result, width, height, options); if (concreteLoaderData == null || alternateUrls.isEmpty()) { return concreteLoaderData; } else { return new LoadData<>(concreteLoaderData.sourceKey, getAlternateKeys(alternateUrls), concreteLoaderData.fetcher); } }
@Override public LoadData<java.io.InputStream> buildLoadData(info.guardianproject.iocipher.File model, int width, int height, Options options) { Key k = new ObjectKey(model.getAbsoluteFile() + ":" + model.length()); // Log.i(TAG, "buildLoadData:key=" + k + " model=" + model); return new LoadData<>(k, new MyDataFetcher(model)); }
@Override public LoadData<InputStream> buildLoadData(Uri model, int width, int height, Options options) { if (MediaStoreUtil.isThumbnailSize(width, height)) { return new LoadData<>(new ObjectKey(model), ThumbFetcher.buildImageFetcher(context, model)); } else { return null; } }
@Override public LoadData<Model> buildLoadData(Model model, int width, int height, Options options) { return new LoadData<>(new ObjectKey(model), new UnitFetcher<>(model)); }
@Nullable @Override public LoadData<InputStream> buildLoadData(GlideUrl glideUrl, int width, int height, Options options) { return new LoadData<>(glideUrl, buildResourceFetcher(glideUrl, width, height, options)); }
@Override public LoadData<Data> buildLoadData(Uri model, int width, int height, Options options) { return new LoadData<>(new ObjectKey(model), factory.build(model)); }
@Override public LoadData<Data> buildLoadData(File model, int width, int height, Options options) { return new LoadData<>(new ObjectKey(model), new FileFetcher<>(model, fileOpener)); }
@Override public LoadData<InputStream> buildLoadData(@NonNull GlideUrl model, int width, int height, @NonNull Options options) { return new LoadData<>(model, new OkHttpStreamFetcher(client, model)); }
@Override public LoadData<InputStream> buildLoadData(@NonNull GlideUrl model, int width, int height, @NonNull Options options) { return new LoadData<>(model, new OkHttpStreamFetcher(client, model)); }
@Override public LoadData<Data> buildLoadData(@NonNull Model model, int width, int height, @NonNull Options options) { Key sourceKey = null; int size = modelLoaders.size(); List<DataFetcher<Data>> fetchers = new ArrayList<>(size); //noinspection ForLoopReplaceableByForEach to improve perf for (int i = 0; i < size; i++) { ModelLoader<Model, Data> modelLoader = modelLoaders.get(i); if (modelLoader.handles(model)) { LoadData<Data> loadData = modelLoader.buildLoadData(model, width, height, options); if (loadData != null) { sourceKey = loadData.sourceKey; fetchers.add(loadData.fetcher); } } } return !fetchers.isEmpty() && sourceKey != null ? new LoadData<>(sourceKey, new MultiFetcher<>(fetchers, exceptionListPool)) : null; }
private static <X, Y> void registerMockModelLoader(Class<X> modelClass, Class<Y> dataClass, Y loadedData, Registry registry) { DataFetcher<Y> mockStreamFetcher = mock(DataFetcher.class); when(mockStreamFetcher.getDataClass()).thenReturn(dataClass); try { doAnswer(new Util.CallDataReady<>(loadedData)) .when(mockStreamFetcher) .loadData(isA(Priority.class), isA(DataFetcher.DataCallback.class)); } catch (Exception e) { throw new RuntimeException(e); } ModelLoader<X, Y> mockUrlLoader = mock(ModelLoader.class); when(mockUrlLoader.buildLoadData(isA(modelClass), anyInt(), anyInt(), isA(Options.class))) .thenReturn(new ModelLoader.LoadData<>(mock(Key.class), mockStreamFetcher)); when(mockUrlLoader.handles(isA(modelClass))).thenReturn(true); ModelLoaderFactory<X, Y> mockUrlLoaderFactory = mock(ModelLoaderFactory.class); when(mockUrlLoaderFactory.build(isA(MultiModelLoaderFactory.class))) .thenReturn(mockUrlLoader); registry.replace(modelClass, dataClass, mockUrlLoaderFactory); }
@Override public LoadData<InputStream> buildLoadData(@NonNull GlideUrl model, int width, int height, @NonNull Options options) { // GlideUrls memoize parsed URLs so caching them saves a few object instantiations and time // spent parsing urls. GlideUrl url = model; if (modelCache != null) { url = modelCache.get(model, 0, 0); if (url == null) { modelCache.put(model, 0, 0, model); url = model; } } int timeout = options.get(TIMEOUT); return new LoadData<>(url, new HttpUrlFetcher(url, timeout)); }
@SuppressWarnings("unchecked") private <T> ModelLoader<T, InputStream> mockStreamModelLoader(final Class<T> modelClass) { ModelLoader<T, InputStream> modelLoader = mock(ModelLoader.class); DataFetcher<InputStream> fetcher = mock(DataFetcher.class); try { doAnswer(new Util.CallDataReady<>(new ByteArrayInputStream(new byte[0]))).when(fetcher) .loadData(isA(Priority.class), isA(DataFetcher.DataCallback.class)); } catch (Exception e) { // Do nothing. } when(fetcher.getDataClass()).thenReturn(InputStream.class); when(modelLoader.buildLoadData(isA(modelClass), anyInt(), anyInt(), isA(Options.class))) .thenReturn(new ModelLoader.LoadData<>(mock(Key.class), fetcher)); when(modelLoader.handles(isA(modelClass))).thenReturn(true); return modelLoader; }
@SuppressWarnings("unchecked") private <T, Z> void registerFailFactory(Class<T> failModel, Class<Z> failResource) { DataFetcher<Z> failFetcher = mock(DataFetcher.class); doAnswer(new Util.CallDataReady<>(null)) .when(failFetcher) .loadData(isA(Priority.class), isA(DataFetcher.DataCallback.class)); when(failFetcher.getDataClass()).thenReturn(failResource); ModelLoader<T, Z> failLoader = mock(ModelLoader.class); when(failLoader.buildLoadData(isA(failModel), anyInt(), anyInt(), isA(Options.class))) .thenReturn(new ModelLoader.LoadData<>(mock(Key.class), failFetcher)); when(failLoader.handles(isA(failModel))).thenReturn(true); ModelLoaderFactory<T, Z> failFactory = mock(ModelLoaderFactory.class); when(failFactory.build(isA(MultiModelLoaderFactory.class))).thenReturn(failLoader); Glide.get(context).getRegistry().prepend(failModel, failResource, failFactory); }
@Test public void testHandlesPaths() { // TODO fix drive letter parsing somehow assumeTrue("it will fail with schema being the drive letter (C:\\... -> C)", !Util.isWindows()); File f = RuntimeEnvironment.application.getCacheDir(); Uri expected = Uri.fromFile(f); when(uriLoader.buildLoadData(eq(expected), eq(IMAGE_SIDE), eq(IMAGE_SIDE), eq(options))) .thenReturn(new ModelLoader.LoadData<>(key, fetcher)); assertTrue(loader.handles(f.getAbsolutePath())); assertEquals( fetcher, Preconditions.checkNotNull( loader.buildLoadData(f.getAbsolutePath(), IMAGE_SIDE, IMAGE_SIDE, options)).fetcher); }
@Test public void testCanHandleComplexFilePaths() { String testPath = "/storage/emulated/0/DCIM/Camera/IMG_20140520_100001:nopm:.jpg,mimeType=image/jpeg," + "2448x3264,orientation=0,date=Tue"; Uri expected = Uri.fromFile(new File(testPath)); when(uriLoader.buildLoadData(eq(expected), eq(IMAGE_SIDE), eq(IMAGE_SIDE), eq(options))) .thenReturn(new ModelLoader.LoadData<>(key, fetcher)); assertTrue(loader.handles(testPath)); assertEquals( fetcher, Preconditions.checkNotNull( loader.buildLoadData(testPath, IMAGE_SIDE, IMAGE_SIDE, options)).fetcher); }
@Test public void testDoesNotInteractWithModelCacheIfNull() { TestLoader urlLoader = new TestLoader(wrapped, null); urlLoader.resultUrl = "fakeUrl"; int width = 456; int height = 789; when(wrapped.buildLoadData(any(GlideUrl.class), eq(width), eq(height), eq(options))) .thenReturn(new ModelLoader.LoadData<>(mock(Key.class), fetcher)); assertEquals( fetcher, Preconditions.checkNotNull( urlLoader.buildLoadData(new Object(), width, height, options)).fetcher); }
@Test public void testReturnsUrlFromCacheIfPresent() { Object model = new Object(); int width = 100; int height = 200; GlideUrl expectedUrl = mock(GlideUrl.class); when(modelCache.get(eq(model), eq(width), eq(height))).thenReturn(expectedUrl); when(wrapped.buildLoadData(eq(expectedUrl), eq(width), eq(height), eq(options))) .thenReturn(new ModelLoader.LoadData<>(mock(Key.class), fetcher)); assertEquals( fetcher, Preconditions.checkNotNull(urlLoader.buildLoadData(model, width, height, options)).fetcher); }
@Override public LoadData<Data> buildLoadData(@NonNull File model, int width, int height, @NonNull Options options) { return new LoadData<>(new ObjectKey(model), new FileFetcher<>(model, fileOpener)); }
@Override public LoadData<Data> buildLoadData( @NonNull byte[] model, int width, int height, @NonNull Options options) { return new LoadData<>(new ObjectKey(model), new Fetcher<>(model, converter)); }