1 /*
2  * Copyright (C) 2016 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 android.server.wm.dndsourceapp;
18 
19 import android.app.Activity;
20 import android.content.ClipData;
21 import android.content.ClipDescription;
22 import android.net.Uri;
23 import android.os.Bundle;
24 import android.os.Handler;
25 import android.os.FileUriExposedException;
26 import android.os.PersistableBundle;
27 import android.server.wm.TestLogClient;
28 import android.view.MotionEvent;
29 import android.view.View;
30 import android.widget.TextView;
31 
32 import java.io.File;
33 
34 public class DragSource extends Activity{
35     private static final String RESULT_KEY_START_DRAG = "START_DRAG";
36     private static final String RESULT_KEY_DETAILS = "DETAILS";
37     private static final String RESULT_OK = "OK";
38     private static final String RESULT_EXCEPTION = "Exception";
39 
40     private static final String URI_PREFIX =
41             "content://" + DragSourceContentProvider.AUTHORITY + "/data";
42 
43     private static final String MAGIC_VALUE = "42";
44     private static final long TIMEOUT_CANCEL = 150;
45 
46     private TextView mTextView;
47     private TestLogClient mLogClient;
48 
49     @Override
onCreate(Bundle savedInstanceState)50     public void onCreate(Bundle savedInstanceState) {
51         super.onCreate(savedInstanceState);
52 
53         mLogClient = new TestLogClient(this, getIntent().getStringExtra("logtag"));
54 
55         View view = getLayoutInflater().inflate(R.layout.source_activity, null);
56         setContentView(view);
57 
58         final Uri plainUri = Uri.parse(URI_PREFIX + "/" + MAGIC_VALUE);
59 
60         setUpDragSource("disallow_global", plainUri, 0);
61         setUpDragSource("cancel_soon", plainUri, View.DRAG_FLAG_GLOBAL);
62 
63         setUpDragSource("grant_none", plainUri, View.DRAG_FLAG_GLOBAL);
64         setUpDragSource("grant_read", plainUri,
65                 View.DRAG_FLAG_GLOBAL | View.DRAG_FLAG_GLOBAL_URI_READ);
66         setUpDragSource("grant_write", plainUri,
67                 View.DRAG_FLAG_GLOBAL | View.DRAG_FLAG_GLOBAL_URI_WRITE);
68         setUpDragSource("grant_read_persistable", plainUri,
69                 View.DRAG_FLAG_GLOBAL | View.DRAG_FLAG_GLOBAL_URI_READ |
70                         View.DRAG_FLAG_GLOBAL_PERSISTABLE_URI_PERMISSION);
71 
72         final Uri prefixUri = Uri.parse(URI_PREFIX);
73 
74         setUpDragSource("grant_read_prefix", prefixUri,
75                 View.DRAG_FLAG_GLOBAL | View.DRAG_FLAG_GLOBAL_URI_READ |
76                         View.DRAG_FLAG_GLOBAL_PREFIX_URI_PERMISSION);
77         setUpDragSource("grant_read_noprefix", prefixUri,
78                 View.DRAG_FLAG_GLOBAL | View.DRAG_FLAG_GLOBAL_URI_READ);
79 
80         final Uri fileUri = Uri.fromFile(new File("/sdcard/sample.jpg"));
81 
82         setUpDragSource("file_local", fileUri, 0);
83         setUpDragSource("file_global", fileUri, View.DRAG_FLAG_GLOBAL);
84     }
85 
setUpDragSource(String mode, final Uri uri, final int flags)86     private void setUpDragSource(String mode, final Uri uri, final int flags) {
87         if (!mode.equals(getIntent().getStringExtra("mode"))) {
88             return;
89         }
90         mTextView = (TextView) findViewById(R.id.drag_source);
91         mTextView.setText(mode);
92         mTextView.setOnTouchListener(new View.OnTouchListener() {
93             @Override
94             public boolean onTouch(View v, MotionEvent event) {
95                 if (event.getAction() != MotionEvent.ACTION_DOWN) {
96                     return false;
97                 }
98                 try {
99                     final ClipDescription clipDescription = new ClipDescription("", new String[] {
100                             ClipDescription.MIMETYPE_TEXT_URILIST });
101                     PersistableBundle extras = new PersistableBundle(1);
102                     extras.putString("extraKey", "extraValue");
103                     clipDescription.setExtras(extras);
104                     final ClipData clipData = new ClipData(clipDescription, new ClipData.Item(uri));
105                     v.startDragAndDrop(
106                             clipData,
107                             new View.DragShadowBuilder(v),
108                             null,
109                             flags);
110                     logResult(RESULT_KEY_START_DRAG, RESULT_OK);
111                 } catch (FileUriExposedException e) {
112                     logResult(RESULT_KEY_DETAILS, e.getMessage());
113                     logResult(RESULT_KEY_START_DRAG, RESULT_EXCEPTION);
114                 }
115                 if (mode.equals("cancel_soon")) {
116                     new Handler().postDelayed(new Runnable() {
117                         @Override
118                         public void run() {
119                             v.cancelDragAndDrop();
120                         }
121                     }, TIMEOUT_CANCEL);
122                 }
123                 return true;
124             }
125         });
126     }
127 
logResult(String key, String value)128     private void logResult(String key, String value) {
129         mLogClient.record(key, value);
130         mTextView.setText(mTextView.getText() + "\n" + key + "=" + value);
131     }
132 }
133