• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2024 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 
17 package com.android.cts.verifier.sharesheet;
18 
19 import android.content.ClipDescription;
20 import android.content.ContentProvider;
21 import android.content.ContentValues;
22 import android.content.res.AssetFileDescriptor;
23 import android.database.Cursor;
24 import android.graphics.Bitmap;
25 import android.graphics.Bitmap.CompressFormat;
26 import android.graphics.Bitmap.Config;
27 import android.graphics.Canvas;
28 import android.graphics.Color;
29 import android.graphics.Paint;
30 import android.graphics.Paint.Align;
31 import android.graphics.Paint.Style;
32 import android.net.Uri;
33 import android.os.ParcelFileDescriptor;
34 import android.util.Log;
35 
36 import androidx.annotation.NonNull;
37 import androidx.annotation.Nullable;
38 
39 import com.android.cts.verifier.sharesheet.TestContract.UriParams;
40 
41 import java.io.FileNotFoundException;
42 import java.io.FileOutputStream;
43 import java.io.IOException;
44 import java.util.concurrent.Executor;
45 import java.util.concurrent.Executors;
46 
47 public class SharesheetTestImageProvider extends ContentProvider {
48     private static final String TAG = "TestImageProvider";
49     private final Executor mExecutor = Executors.newCachedThreadPool();
50 
51     @Override
onCreate()52     public boolean onCreate() {
53         return true;
54     }
55 
56     @Nullable
57     @Override
getType(@onNull Uri uri)58     public String getType(@NonNull Uri uri) {
59         return uri.getQueryParameter(UriParams.Type);
60     }
61 
62     @Nullable
63     @Override
openAssetFile(@onNull Uri uri, @NonNull String mode)64     public AssetFileDescriptor openAssetFile(@NonNull Uri uri, @NonNull String mode)
65             throws FileNotFoundException {
66         String name = uri.getQueryParameter(UriParams.Name);
67         if (name == null) {
68             throw new FileNotFoundException("Malformed URI: " + uri);
69         }
70         try {
71             final ParcelFileDescriptor[] pipe = ParcelFileDescriptor.createReliablePipe();
72             mExecutor.execute(() -> {
73                 try {
74                     sendBitmap(pipe[1], uriToColor(uri), name, getType(uri));
75                 } catch (IOException e) {
76                     Log.e(TAG, "Failed to send bitmap", e);
77                 } finally {
78                     try {
79                         pipe[1].close();
80                     } catch (Throwable t) {
81                         // ignore
82                     }
83                 }
84             });
85             return new AssetFileDescriptor(pipe[0], 0, -1);
86         } catch (IOException e) {
87             throw new FileNotFoundException(e.getMessage());
88         }
89     }
90 
sendBitmap( ParcelFileDescriptor fd, int color, String name, @Nullable String mimeType)91     private void sendBitmap(
92                 ParcelFileDescriptor fd,
93                 int color,
94                 String name,
95                 @Nullable String mimeType) throws IOException {
96         Bitmap bitmap = createBitmap(200, 200, color, name);
97         try (FileOutputStream fos = new FileOutputStream(fd.getFileDescriptor())) {
98             CompressFormat format = ClipDescription.compareMimeTypes(mimeType, "image/jpg")
99                     ? CompressFormat.JPEG
100                     : CompressFormat.PNG;
101             bitmap.compress(format, 100, fos);
102         }
103     }
104 
createBitmap(int width, int height, int bgColor, String name)105     private static Bitmap createBitmap(int width, int height, int bgColor, String name) {
106         Bitmap bitmap = Bitmap.createBitmap(width, height, Config.ARGB_8888);
107         Canvas canvas = new Canvas(bitmap);
108         Paint paint = new Paint();
109         paint.setColor(bgColor);
110         paint.setStyle(Style.FILL);
111         canvas.drawPaint(paint);
112         paint.setColor(getContrast(bgColor));
113         paint.setAntiAlias(true);
114         paint.setTextSize(28f);
115         paint.setTextAlign(Align.CENTER);
116         canvas.drawText(name, width / 2f, height / 2f, paint);
117         return bitmap;
118     }
119 
uriToColor(Uri uri)120     private static int uriToColor(Uri uri) {
121         int hash = uri.hashCode();
122         return Color.argb(
123                 255,
124                 (hash & 0x00ff0000) >>> 16,
125                 (hash & 0x0000ff00) >>> 8,
126                 hash & 0x000000ff);
127     }
128 
getContrast(int color)129     private static int getContrast(int color) {
130         return Color.argb(
131                 255,
132                 Color.red(color) > 127 ? 0 : 255,
133                 Color.green(color) > 127 ? 0 : 255,
134                 Color.blue(color) > 127 ? 0 : 255);
135     }
136 
137     @Nullable
138     @Override
query(@onNull Uri uri, @Nullable String[] projection, @Nullable String selection, @Nullable String[] selectionArgs, @Nullable String sortOrder)139     public Cursor query(@NonNull Uri uri, @Nullable String[] projection, @Nullable String selection,
140             @Nullable String[] selectionArgs, @Nullable String sortOrder) {
141         return null;
142     }
143 
144 
145     @Nullable
146     @Override
insert(@onNull Uri uri, @Nullable ContentValues values)147     public Uri insert(@NonNull Uri uri, @Nullable ContentValues values) {
148         return null;
149     }
150 
151     @Override
delete(@onNull Uri uri, @Nullable String selection, @Nullable String[] selectionArgs)152     public int delete(@NonNull Uri uri, @Nullable String selection,
153             @Nullable String[] selectionArgs) {
154         return 0;
155     }
156 
157     @Override
update(@onNull Uri uri, @Nullable ContentValues values, @Nullable String selection, @Nullable String[] selectionArgs)158     public int update(@NonNull Uri uri, @Nullable ContentValues values, @Nullable String selection,
159             @Nullable String[] selectionArgs) {
160         return 0;
161     }
162 }
163