1 /*
2  * Copyright 2022 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 androidx.webkit;
18 
19 import android.content.ContentProvider;
20 import android.content.ContentValues;
21 import android.database.Cursor;
22 import android.net.Uri;
23 import android.os.Bundle;
24 import android.os.ParcelFileDescriptor;
25 
26 import androidx.webkit.internal.WebViewGlueCommunicator;
27 
28 import org.chromium.support_lib_boundary.DropDataContentProviderBoundaryInterface;
29 import org.jspecify.annotations.NonNull;
30 import org.jspecify.annotations.Nullable;
31 
32 import java.io.FileNotFoundException;
33 
34 /**
35  * WebView provides partial support for Android
36  * <a href="https://developer.android.com/develop/ui/views/touch-and-input/drag-drop">
37  * Drag and Drop</a> allowing images, text and links to be dragged out of a WebView.
38  * <p>
39  * The content provider is required to make the images drag work, to enable, you should add this
40  * class to your manifest, for example:
41  *
42  * <pre class="prettyprint">
43  *  &lt;provider
44  *             android:authorities="&lt;your-package&gt;.DropDataProvider"
45  *             android:name="androidx.webkit.DropDataContentProvider"
46  *             android:exported="false"
47  *             android:grantUriPermissions="true"/&gt;
48  * </pre>
49  *
50  */
51 public final class DropDataContentProvider extends ContentProvider {
52     DropDataContentProviderBoundaryInterface mImpl;
53 
54     @Override
onCreate()55     public boolean onCreate() {
56         return true;
57     }
58 
59     @Override
openFile(@onNull Uri uri, @NonNull String mode)60     public @Nullable ParcelFileDescriptor openFile(@NonNull Uri uri, @NonNull String mode)
61             throws FileNotFoundException {
62         return getDropImpl().openFile(this, uri);
63     }
64 
65     @Override
query(@onNull Uri uri, String @Nullable [] projection, @Nullable String selection, String @Nullable [] selectionArgs, @Nullable String sortOrder)66     public @Nullable Cursor query(@NonNull Uri uri, String @Nullable [] projection,
67             @Nullable String selection, String @Nullable [] selectionArgs,
68             @Nullable String sortOrder) {
69         return getDropImpl().query(uri, projection, selection, selectionArgs, sortOrder);
70     }
71 
72     @Override
getType(@onNull Uri uri)73     public @Nullable String getType(@NonNull Uri uri) {
74         return getDropImpl().getType(uri);
75     }
76 
77     @Override
insert(@onNull Uri uri, @Nullable ContentValues contentValues)78     public @Nullable Uri insert(@NonNull Uri uri, @Nullable ContentValues contentValues) {
79         throw new UnsupportedOperationException("Insert method is not supported.");
80     }
81 
82     @Override
delete(@onNull Uri uri, @Nullable String selection, String @Nullable [] selectionArgs)83     public int delete(@NonNull Uri uri, @Nullable String selection,
84             String @Nullable [] selectionArgs) {
85         throw new UnsupportedOperationException("delete method is not supported.");
86     }
87 
88     @Override
update(@onNull Uri uri, @Nullable ContentValues contentValues, @Nullable String s, String @Nullable [] strings)89     public int update(@NonNull Uri uri, @Nullable ContentValues contentValues, @Nullable String s,
90             String @Nullable [] strings) {
91         throw new UnsupportedOperationException("update method is not supported.");
92     }
93 
94     @Override
call(@onNull String method, @Nullable String arg, @Nullable Bundle extras)95     public @Nullable Bundle call(@NonNull String method, @Nullable String arg,
96             @Nullable Bundle extras) {
97         return getDropImpl().call(method, arg, extras);
98     }
99 
getDropImpl()100     private DropDataContentProviderBoundaryInterface getDropImpl() {
101         if (mImpl == null) {
102             mImpl = WebViewGlueCommunicator.getFactory().getDropDataProvider();
103             mImpl.onCreate();
104         }
105         return mImpl;
106     }
107 }
108