Upstream version 11.40.277.0
[platform/framework/web/crosswalk.git] / src / chrome / android / java / src / org / chromium / chrome / browser / share / ShareHelper.java
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 package org.chromium.chrome.browser.share;
6
7 import android.app.Activity;
8 import android.app.AlertDialog;
9 import android.content.ComponentName;
10 import android.content.Context;
11 import android.content.Intent;
12 import android.content.SharedPreferences;
13 import android.content.pm.ActivityInfo;
14 import android.content.pm.ApplicationInfo;
15 import android.content.pm.PackageManager;
16 import android.content.pm.PackageManager.NameNotFoundException;
17 import android.content.pm.ResolveInfo;
18 import android.graphics.Bitmap;
19 import android.graphics.drawable.Drawable;
20 import android.preference.PreferenceManager;
21 import android.view.MenuItem;
22 import android.view.View;
23 import android.widget.AdapterView;
24 import android.widget.AdapterView.OnItemClickListener;
25
26 import org.chromium.base.VisibleForTesting;
27 import org.chromium.chrome.R;
28 import org.chromium.components.dom_distiller.core.DomDistillerUrlUtils;
29
30 import java.util.Collections;
31 import java.util.List;
32
33 /**
34  * A helper class that helps to start an intent to share titles and URLs.
35  */
36 public class ShareHelper {
37
38     private static final String PACKAGE_NAME_KEY = "last_shared_package_name";
39     private static final String CLASS_NAME_KEY = "last_shared_class_name";
40
41     /**
42      * Intent extra for sharing screenshots via the Share intent.
43      *
44      * Copied from {@link android.provider.Browser} as it is marked as {@literal @hide}.
45      */
46     private static final String EXTRA_SHARE_SCREENSHOT = "share_screenshot";
47
48     private ShareHelper() {}
49
50     /**
51      * Creates and shows a share intent picker dialog or starts a share intent directly with the
52      * activity that was most recently used to share based on shareDirectly value.
53      *
54      * @param shareDirectly Whether it should share directly with the activity that was most
55      *                      recently used to share.
56      * @param activity Activity that is used to access package manager.
57      * @param title Title of the page to be shared.
58      * @param url URL of the page to be shared.
59      * @param screenshot Screenshot of the page to be shared.
60      */
61     public static void share(boolean shareDirectly, Activity activity, String title, String url,
62             Bitmap screenshot, int extraIntentFlags) {
63         if (shareDirectly) {
64             shareWithLastUsed(activity, title, url, screenshot, extraIntentFlags);
65         } else {
66             showShareDialog(activity, title, url, screenshot, extraIntentFlags);
67         }
68     }
69
70     /**
71      * Creates and shows a share intent picker dialog.
72      *
73      * @param activity Activity that is used to access package manager.
74      * @param title Title of the page to be shared.
75      * @param url URL of the page to be shared.
76      * @param screenshot Screenshot of the page to be shared.
77      * @param extraIntentFlags Additional flags that should be added to the share intent.
78      */
79     private static void showShareDialog(final Activity activity, final String title,
80             final String url, final Bitmap screenshot, final int extraIntentFlags) {
81         Intent intent = getShareIntent(title, url, screenshot, extraIntentFlags);
82         PackageManager manager = activity.getPackageManager();
83         List<ResolveInfo> resolveInfoList = manager.queryIntentActivities(intent, 0);
84         assert resolveInfoList.size() > 0;
85         if (resolveInfoList.size() == 0) return;
86         Collections.sort(resolveInfoList, new ResolveInfo.DisplayNameComparator(manager));
87
88         final ShareDialogAdapter adapter =
89                 new ShareDialogAdapter(activity, manager, resolveInfoList);
90         AlertDialog.Builder builder = new AlertDialog.Builder(activity);
91         builder.setTitle(activity.getString(R.string.share_link_chooser_title));
92         builder.setAdapter(adapter, null);
93
94         final AlertDialog dialog = builder.create();
95         dialog.show();
96         dialog.getListView().setOnItemClickListener(new OnItemClickListener() {
97             @Override
98             public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
99                 ResolveInfo info = adapter.getItem(position);
100                 ActivityInfo ai = info.activityInfo;
101                 ComponentName component =
102                         new ComponentName(ai.applicationInfo.packageName, ai.name);
103                 setLastShareComponentName(activity, component);
104                 Intent intent = getDirectShareIntentForComponent(title, url, screenshot, component,
105                         extraIntentFlags);
106                 activity.startActivity(intent);
107                 dialog.dismiss();
108             }
109         });
110     }
111
112     /**
113      * Starts a share intent with the activity that was most recently used to share.
114      * If there is no most recently used activity, it does nothing.
115      * @param activity Activity that is used to start the share intent.
116      * @param title Title of the page to be shared.
117      * @param url URL of the page to be shared.
118      * @param screenshot Screenshot of the page to be shared.
119      * @param extraIntentFlags Additional flags that should be added to the share intent.
120      */
121     private static void shareWithLastUsed(
122             Activity activity, String title, String url, Bitmap screenshot, int extraIntentFlags) {
123         ComponentName component = getLastShareComponentName(activity);
124         if (component == null) return;
125         Intent intent = getDirectShareIntentForComponent(
126                 title, url, screenshot, component, extraIntentFlags);
127         activity.startActivity(intent);
128     }
129
130     /**
131      * Set the icon and the title for the menu item used for direct share.
132      *
133      * @param activity Activity that is used to access the package manager.
134      * @param item The menu item that is used for direct share
135      */
136     public static void configureDirectShareMenuItem(Activity activity, MenuItem item) {
137         Drawable directShareIcon = null;
138         CharSequence directShareTitle = null;
139
140         ComponentName component = getLastShareComponentName(activity);
141         if (component != null) {
142             try {
143                 directShareIcon = activity.getPackageManager().getActivityIcon(component);
144                 ApplicationInfo ai = activity.getPackageManager().getApplicationInfo(
145                         component.getPackageName(), 0);
146                 directShareTitle = activity.getPackageManager().getApplicationLabel(ai);
147             } catch (NameNotFoundException exception) {
148                 // Use the default null values.
149             }
150         }
151
152         item.setIcon(directShareIcon);
153         if (directShareTitle != null) {
154             item.setTitle(activity.getString(R.string.accessibility_menu_share_via,
155                     directShareTitle));
156         }
157     }
158
159     @VisibleForTesting
160     public static Intent getShareIntent(String title, String url, Bitmap screenshot,
161             int extraIntentFlags) {
162         url = DomDistillerUrlUtils.getOriginalUrlFromDistillerUrl(url);
163         Intent intent = new Intent(Intent.ACTION_SEND);
164         intent.addFlags(extraIntentFlags);
165         intent.setType("text/plain");
166         intent.putExtra(Intent.EXTRA_SUBJECT, title);
167         intent.putExtra(Intent.EXTRA_TEXT, url);
168         if (screenshot != null) intent.putExtra(EXTRA_SHARE_SCREENSHOT, screenshot);
169         return intent;
170     }
171
172     private static Intent getDirectShareIntentForComponent(String title, String url,
173             Bitmap screenshot, ComponentName component, int extraIntentFlags) {
174         Intent intent = getShareIntent(title, url, screenshot, extraIntentFlags);
175         intent.addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT
176                 | Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP);
177         intent.setComponent(component);
178         return intent;
179     }
180
181     private static ComponentName getLastShareComponentName(Context context) {
182         SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
183         String packageName = preferences.getString(PACKAGE_NAME_KEY, null);
184         String className = preferences.getString(CLASS_NAME_KEY, null);
185         if (packageName == null || className == null) return null;
186         return new ComponentName(packageName, className);
187     }
188
189     private static void setLastShareComponentName(Context context, ComponentName component) {
190         SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
191         SharedPreferences.Editor editor = preferences.edit();
192         editor.putString(PACKAGE_NAME_KEY, component.getPackageName());
193         editor.putString(CLASS_NAME_KEY, component.getClassName());
194         editor.apply();
195     }
196 }