blob: 63f6183fd95dc685c38badbbd5c8393945331f42 [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;
Axesh R. Ajmera34d3f142014-06-30 20:05:36 -070046
47import java.util.List;
48import java.util.Collections;
49
50import android.util.Log;
51
Danesh M22398a72015-10-07 13:08:21 -070052import org.chromium.base.ContentUriUtils;
53import org.chromium.ui.UiUtils;
54
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;
Axesh R. Ajmera34d3f142014-06-30 20:05:36 -070070
71 public ShareDialog (Activity activity, String title, String url, Bitmap favicon, Bitmap screenshot) {
72 super(null);
73 this.activity = activity;
74 this.apps = getShareableApps();
75 this.title = title;
76 this.url = url;
77 this.favicon = favicon;
78 this.screenshot = screenshot;
Danesh M22398a72015-10-07 13:08:21 -070079
80 ContentUriUtils.setFileProviderUtil(new FileProviderHelper());
81 trimScreenshots();
82 }
83
84 private void trimScreenshots() {
85 try {
86 File directory = getScreenshotDir();
87 if (directory.list() != null && directory.list().length >= MAX_SCREENSHOT_COUNT) {
88 clearSharedScreenshots();
89 }
90 } catch (IOException e) {
91 e.printStackTrace();
92 clearSharedScreenshots();
93 }
94 }
95
96 private File getScreenshotDir() throws IOException {
97 File baseDir = UiUtils.getDirectoryForImageCapture(activity);
98 return new File(baseDir, SCREENSHOT_DIRECTORY_NAME);
99 }
100
101 private void deleteScreenshotFiles(File file) {
102 if (!file.exists()) return;
103 if (file.isDirectory()) {
104 for (File f : file.listFiles()) deleteScreenshotFiles(f);
105 }
106 }
107
108 /**
109 * Clears all shared screenshot files.
110 */
111 private void clearSharedScreenshots() {
112 AsyncTask.execute(new Runnable() {
113 @Override
114 public void run() {
115 try {
116 File dir = getScreenshotDir();
117 deleteScreenshotFiles(dir);
118 } catch (IOException ie) {
119 // Ignore exception.
120 }
121 }
122 });
Axesh R. Ajmera34d3f142014-06-30 20:05:36 -0700123 }
124
125 private List<ResolveInfo> getShareableApps() {
126 Intent shareIntent = new Intent("android.intent.action.SEND");
127 shareIntent.setType("text/plain");
128 PackageManager pm = activity.getPackageManager();
129 List<ResolveInfo> launchables = pm.queryIntentActivities(shareIntent, 0);
130
131 Collections.sort(launchables,
132 new ResolveInfo.DisplayNameComparator(pm));
133
134 return launchables;
135 }
136
137
138 public List<ResolveInfo> getApps() {
139 return apps;
140 }
141
142 public void loadView(final AppAdapter adapter) {
143 AlertDialog.Builder builderSingle = new AlertDialog.Builder(activity);
Tarun Nainani82ca1bd2015-07-16 14:31:17 -0700144 builderSingle.setIcon(R.mipmap.ic_launcher_browser);
Axesh R. Ajmera34d3f142014-06-30 20:05:36 -0700145 builderSingle.setTitle(activity.getString(R.string.choosertitle_sharevia));
146 builderSingle.setAdapter(adapter, new DialogInterface.OnClickListener() {
147 @Override
148 public void onClick(DialogInterface dialog, int position) {
149 dialog.dismiss();
150 ResolveInfo launchable = adapter.getItem(position);
151 ActivityInfo activityInfo = launchable.activityInfo;
152 ComponentName name = new android.content.ComponentName(activityInfo.applicationInfo.packageName,
153 activityInfo.name);
154 Intent i = new Intent(Intent.ACTION_SEND);
Axesh R. Ajmera89cf4d82015-05-19 11:26:18 -0700155 if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.KITKAT) {
156 // This flag clears the called app from the activity stack,
157 // so users arrive in the expected place next time this application is restarted
158 i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
159 } else {
160 // flag used from Lollipop onwards
161 i.addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT);
162 }
163
164 i.addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT |
165 Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP);
166 i.setType("text/plain");
Axesh R. Ajmera34d3f142014-06-30 20:05:36 -0700167 i.putExtra(Intent.EXTRA_TEXT, url);
168 i.putExtra(Intent.EXTRA_SUBJECT, title);
169 i.putExtra(EXTRA_SHARE_FAVICON, favicon);
Danesh M22398a72015-10-07 13:08:21 -0700170 i.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
171 i.putExtra(Intent.EXTRA_STREAM, getShareBitmapUri(screenshot));
Axesh R. Ajmera34d3f142014-06-30 20:05:36 -0700172 i.setComponent(name);
173 activity.startActivity(i);
174 }
175 });
176
177 builderSingle.show();
178 }
Danesh M22398a72015-10-07 13:08:21 -0700179
180 public Uri getShareBitmapUri(Bitmap screenshot) {
181 Uri uri = null;
182 if (screenshot != null) {
183 FileOutputStream fOut = null;
184 try {
185 File path = getScreenshotDir();
186 if (path.exists() || path.mkdir()) {
187 File saveFile = File.createTempFile(
188 String.valueOf(System.currentTimeMillis()), ".jpg", path);
189 fOut = new FileOutputStream(saveFile);
190 screenshot.compress(Bitmap.CompressFormat.JPEG, 90, fOut);
191 fOut.flush();
192 fOut.close();
193 uri = UiUtils.getUriForImageCaptureFile(activity, saveFile);
194 }
195 } catch (IOException ie) {
196 if (fOut != null) {
197 try {
198 fOut.close();
199 } catch (IOException e) {
200 // Ignore exception.
201 }
202 }
203 }
204 }
205 return uri;
206 }
Tarun Nainani82ca1bd2015-07-16 14:31:17 -0700207}