blob: 4fe54d3a24f40451cb258614195acb06c059c024 [file] [log] [blame]
Axesh R. Ajmera34d3f142014-06-30 20:05:36 -07001/*
2 * Copyright (c) 2014, The Linux Foundation. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above
10 * copyright notice, this list of conditions and the following
11 * disclaimer in the documentation and/or other materials provided
12 * with the distribution.
13 * * Neither the name of The Linux Foundation nor the names of its
14 * contributors may be used to endorse or promote products derived
15 * from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
18 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
21 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
24 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
26 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 *
29 */
30package com.android.browser;
31
32import android.app.Activity;
33import android.app.AlertDialog;
34import android.content.ComponentName;
35import android.content.Context;
36import android.content.DialogInterface;
37import android.content.DialogInterface.OnClickListener;
38import android.content.Intent;
39import android.content.pm.ActivityInfo;
40import android.content.pm.ResolveInfo;
41import android.content.pm.PackageManager;
42import android.graphics.Bitmap;
Danesh M22398a72015-10-07 13:08:21 -070043import android.net.Uri;
44import android.os.AsyncTask;
Axesh R. Ajmera89cf4d82015-05-19 11:26:18 -070045import android.os.Build;
Martin Brabham1a8e7472016-01-21 12:47:43 -050046import android.os.Environment;
Axesh R. Ajmera34d3f142014-06-30 20:05:36 -070047
48import java.util.List;
49import java.util.Collections;
50
51import android.util.Log;
52
Danesh M22398a72015-10-07 13:08:21 -070053import org.chromium.base.ContentUriUtils;
Danesh M22398a72015-10-07 13:08:21 -070054
55import java.io.File;
56import java.io.FileOutputStream;
57import java.io.IOException;
Axesh R. Ajmera34d3f142014-06-30 20:05:36 -070058
59public class ShareDialog extends AppItem {
60 private Activity activity = null;
61 public String title = null;
62 public String url = null;
63 public Bitmap favicon = null;
64 public Bitmap screenshot = null;
65 private List<ResolveInfo>apps = null;
66 public final static String EXTRA_SHARE_SCREENSHOT = "share_screenshot";
67 public final static String EXTRA_SHARE_FAVICON = "share_favicon";
Danesh M22398a72015-10-07 13:08:21 -070068 private static final String SCREENSHOT_DIRECTORY_NAME = "screenshot_share";
69 private static final int MAX_SCREENSHOT_COUNT = 10;
Martin Brabham1a8e7472016-01-21 12:47:43 -050070 public static final String EXTERNAL_IMAGE_FILE_PATH = "browser-images";
71 public static final String IMAGE_FILE_PATH = "images";
Axesh R. Ajmera34d3f142014-06-30 20:05:36 -070072
73 public ShareDialog (Activity activity, String title, String url, Bitmap favicon, Bitmap screenshot) {
74 super(null);
75 this.activity = activity;
76 this.apps = getShareableApps();
77 this.title = title;
78 this.url = url;
79 this.favicon = favicon;
80 this.screenshot = screenshot;
Danesh M22398a72015-10-07 13:08:21 -070081
82 ContentUriUtils.setFileProviderUtil(new FileProviderHelper());
83 trimScreenshots();
84 }
85
86 private void trimScreenshots() {
87 try {
88 File directory = getScreenshotDir();
89 if (directory.list() != null && directory.list().length >= MAX_SCREENSHOT_COUNT) {
90 clearSharedScreenshots();
91 }
92 } catch (IOException e) {
93 e.printStackTrace();
94 clearSharedScreenshots();
95 }
96 }
97
98 private File getScreenshotDir() throws IOException {
Martin Brabham1a8e7472016-01-21 12:47:43 -050099 File baseDir = getDirectoryForImageCapture(activity);
Danesh M22398a72015-10-07 13:08:21 -0700100 return new File(baseDir, SCREENSHOT_DIRECTORY_NAME);
101 }
102
103 private void deleteScreenshotFiles(File file) {
104 if (!file.exists()) return;
105 if (file.isDirectory()) {
106 for (File f : file.listFiles()) deleteScreenshotFiles(f);
107 }
108 }
109
110 /**
111 * Clears all shared screenshot files.
112 */
113 private void clearSharedScreenshots() {
114 AsyncTask.execute(new Runnable() {
115 @Override
116 public void run() {
117 try {
118 File dir = getScreenshotDir();
119 deleteScreenshotFiles(dir);
120 } catch (IOException ie) {
121 // Ignore exception.
122 }
123 }
124 });
Axesh R. Ajmera34d3f142014-06-30 20:05:36 -0700125 }
126
127 private List<ResolveInfo> getShareableApps() {
128 Intent shareIntent = new Intent("android.intent.action.SEND");
129 shareIntent.setType("text/plain");
130 PackageManager pm = activity.getPackageManager();
131 List<ResolveInfo> launchables = pm.queryIntentActivities(shareIntent, 0);
132
133 Collections.sort(launchables,
134 new ResolveInfo.DisplayNameComparator(pm));
135
136 return launchables;
137 }
138
139
140 public List<ResolveInfo> getApps() {
141 return apps;
142 }
143
144 public void loadView(final AppAdapter adapter) {
145 AlertDialog.Builder builderSingle = new AlertDialog.Builder(activity);
Tarun Nainani82ca1bd2015-07-16 14:31:17 -0700146 builderSingle.setIcon(R.mipmap.ic_launcher_browser);
Axesh R. Ajmera34d3f142014-06-30 20:05:36 -0700147 builderSingle.setTitle(activity.getString(R.string.choosertitle_sharevia));
148 builderSingle.setAdapter(adapter, new DialogInterface.OnClickListener() {
149 @Override
150 public void onClick(DialogInterface dialog, int position) {
151 dialog.dismiss();
152 ResolveInfo launchable = adapter.getItem(position);
153 ActivityInfo activityInfo = launchable.activityInfo;
154 ComponentName name = new android.content.ComponentName(activityInfo.applicationInfo.packageName,
155 activityInfo.name);
156 Intent i = new Intent(Intent.ACTION_SEND);
Axesh R. Ajmera89cf4d82015-05-19 11:26:18 -0700157 if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.KITKAT) {
158 // This flag clears the called app from the activity stack,
159 // so users arrive in the expected place next time this application is restarted
160 i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
161 } else {
162 // flag used from Lollipop onwards
163 i.addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT);
164 }
165
166 i.addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT |
167 Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP);
168 i.setType("text/plain");
Axesh R. Ajmera34d3f142014-06-30 20:05:36 -0700169 i.putExtra(Intent.EXTRA_TEXT, url);
170 i.putExtra(Intent.EXTRA_SUBJECT, title);
171 i.putExtra(EXTRA_SHARE_FAVICON, favicon);
Danesh M22398a72015-10-07 13:08:21 -0700172 i.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
173 i.putExtra(Intent.EXTRA_STREAM, getShareBitmapUri(screenshot));
Axesh R. Ajmera34d3f142014-06-30 20:05:36 -0700174 i.setComponent(name);
175 activity.startActivity(i);
176 }
177 });
178
179 builderSingle.show();
180 }
Danesh M22398a72015-10-07 13:08:21 -0700181
182 public Uri getShareBitmapUri(Bitmap screenshot) {
183 Uri uri = null;
184 if (screenshot != null) {
185 FileOutputStream fOut = null;
186 try {
187 File path = getScreenshotDir();
188 if (path.exists() || path.mkdir()) {
189 File saveFile = File.createTempFile(
190 String.valueOf(System.currentTimeMillis()), ".jpg", path);
191 fOut = new FileOutputStream(saveFile);
192 screenshot.compress(Bitmap.CompressFormat.JPEG, 90, fOut);
193 fOut.flush();
194 fOut.close();
Martin Brabham1a8e7472016-01-21 12:47:43 -0500195 uri = getUriForImageCaptureFile(activity, saveFile);
Danesh M22398a72015-10-07 13:08:21 -0700196 }
197 } catch (IOException ie) {
198 if (fOut != null) {
199 try {
200 fOut.close();
201 } catch (IOException e) {
202 // Ignore exception.
203 }
204 }
205 }
206 }
207 return uri;
208 }
Martin Brabham1a8e7472016-01-21 12:47:43 -0500209
210 public static Uri getUriForImageCaptureFile(Context context, File file) {
211 return Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2
212 ? ContentUriUtils.getContentUriFromFile(context, file)
213 : Uri.fromFile(file);
214 }
215
216 public static File getDirectoryForImageCapture(Context context) throws IOException {
217 File path;
218 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
219 path = new File(context.getFilesDir(), IMAGE_FILE_PATH);
220 if (!path.exists() && !path.mkdir()) {
221 throw new IOException("Folder cannot be created.");
222 }
223 } else {
224 File externalDataDir =
225 Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM);
226 path = new File(
227 externalDataDir.getAbsolutePath() + File.separator + EXTERNAL_IMAGE_FILE_PATH);
228 if (!path.exists() && !path.mkdirs()) {
229 path = externalDataDir;
230 }
231 }
232 return path;
233 }
234
Tarun Nainani82ca1bd2015-07-16 14:31:17 -0700235}