1 /*
2  * Copyright (C) 2017 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.android.wallpaper.asset;
17 
18 import android.graphics.Bitmap;
19 import android.graphics.BitmapFactory;
20 
21 import androidx.annotation.Nullable;
22 
23 import com.bumptech.glide.Priority;
24 import com.bumptech.glide.load.DataSource;
25 import com.bumptech.glide.load.Options;
26 import com.bumptech.glide.load.data.DataFetcher;
27 import com.bumptech.glide.load.model.ModelLoader;
28 import com.bumptech.glide.load.model.ModelLoaderFactory;
29 import com.bumptech.glide.load.model.MultiModelLoaderFactory;
30 
31 import java.io.ByteArrayInputStream;
32 import java.io.ByteArrayOutputStream;
33 import java.io.InputStream;
34 
35 /**
36  * Glide ModelLoader which loads InputStreams from ResourceAssets.
37  */
38 public class ResourceAssetLoader implements ModelLoader<ResourceAsset, InputStream> {
39 
40     @Override
handles(ResourceAsset resourceAsset)41     public boolean handles(ResourceAsset resourceAsset) {
42         return true;
43     }
44 
45     @Nullable
46     @Override
buildLoadData(ResourceAsset resourceAsset, int unusedWidth, int unusedHeight, Options options)47     public LoadData<InputStream> buildLoadData(ResourceAsset resourceAsset, int unusedWidth,
48                                                int unusedHeight, Options options) {
49         return new LoadData<>(resourceAsset.getKey(), new ResourceAssetFetcher(resourceAsset));
50     }
51 
52     /**
53      * Factory that constructs {@link ResourceAssetLoader} instances.
54      */
55     public static class ResourceAssetLoaderFactory
56             implements ModelLoaderFactory<ResourceAsset, InputStream> {
ResourceAssetLoaderFactory()57         public ResourceAssetLoaderFactory() {
58         }
59 
60         @Override
build(MultiModelLoaderFactory multiFactory)61         public ModelLoader<ResourceAsset, InputStream> build(MultiModelLoaderFactory multiFactory) {
62             return new ResourceAssetLoader();
63         }
64 
65         @Override
teardown()66         public void teardown() {
67             // no-op
68         }
69     }
70 
71     /**
72      * Glide DataFetcher for ResourceAsset.
73      */
74     protected static class ResourceAssetFetcher implements DataFetcher<InputStream> {
75 
76         private ResourceAsset mResourceAsset;
77 
ResourceAssetFetcher(ResourceAsset resourceAsset)78         public ResourceAssetFetcher(ResourceAsset resourceAsset) {
79             mResourceAsset = resourceAsset;
80         }
81 
82         @Override
loadData(Priority priority, final DataCallback<? super InputStream> callback)83         public void loadData(Priority priority, final DataCallback<? super InputStream> callback) {
84             if (mResourceAsset.mIsThumbnail) {
85                 callback.onDataReady(
86                         mResourceAsset.getResources().openRawResource(mResourceAsset.getResId()));
87             } else {
88                 BitmapFactory.Options options = new BitmapFactory.Options();
89                 options.inSampleSize = 8;
90                 Bitmap bitmap = BitmapFactory.decodeResource(mResourceAsset.getResources(),
91                         mResourceAsset.getResId(), options);
92                 ByteArrayOutputStream baos = new ByteArrayOutputStream();
93                 bitmap.compress(Bitmap.CompressFormat.PNG, 100, baos);
94                 callback.onDataReady(new ByteArrayInputStream(baos.toByteArray()));
95             }
96         }
97 
98         @Override
getDataSource()99         public DataSource getDataSource() {
100             return DataSource.LOCAL;
101         }
102 
103         @Override
cancel()104         public void cancel() {
105             // no op
106         }
107 
108         @Override
cleanup()109         public void cleanup() {
110             // no op
111         }
112 
113         @Override
getDataClass()114         public Class<InputStream> getDataClass() {
115             return InputStream.class;
116         }
117     }
118 }
119