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