EMMA Coverage Report (generated Fri Aug 23 16:39:17 PDT 2013)
[all classes][org.chromium.content.browser]

COVERAGE SUMMARY FOR SOURCE FILE [SelectActionModeCallback.java]

nameclass, %method, %block, %line, %
SelectActionModeCallback.java100% (1/1)91%  (10/11)69%  (236/342)56%  (42.9/77)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class SelectActionModeCallback100% (1/1)91%  (10/11)69%  (236/342)56%  (42.9/77)
onActionItemClicked (ActionMode, MenuItem): boolean 0%   (0/1)0%   (0/104)0%   (0/34)
isShareHandlerAvailable (): boolean 100% (1/1)95%  (20/21)98%  (3/3)
isWebSearchAvailable (): boolean 100% (1/1)95%  (21/22)98%  (3/3)
<static initializer> 100% (1/1)100% (20/20)100% (1/1)
SelectActionModeCallback (Context, SelectActionModeCallback$ActionHandler, bo... 100% (1/1)100% (12/12)100% (5/5)
canPaste (): boolean 100% (1/1)100% (9/9)100% (2/2)
createActionMenu (ActionMode, Menu): void 100% (1/1)100% (109/109)100% (14/14)
getContext (): Context 100% (1/1)100% (3/3)100% (1/1)
onCreateActionMode (ActionMode, Menu): boolean 100% (1/1)100% (17/17)100% (5/5)
onDestroyActionMode (ActionMode): void 100% (1/1)100% (4/4)100% (2/2)
onPrepareActionMode (ActionMode, Menu): boolean 100% (1/1)100% (21/21)100% (7/7)

1// Copyright (c) 2012 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 
5package org.chromium.content.browser;
6 
7import android.app.SearchManager;
8import android.content.ClipboardManager;
9import android.content.Context;
10import android.content.Intent;
11import android.content.pm.PackageManager;
12import android.content.res.TypedArray;
13import android.provider.Browser;
14import android.text.TextUtils;
15import android.view.ActionMode;
16import android.view.Menu;
17import android.view.MenuItem;
18 
19import org.chromium.content.R;
20 
21/**
22 * An ActionMode.Callback for in-page selection. This class handles both the editable and
23 * non-editable cases.
24 */
25public class SelectActionModeCallback implements ActionMode.Callback {
26    private static final int SELECT_ALL_ATTR_INDEX = 0;
27    private static final int CUT_ATTR_INDEX = 1;
28    private static final int COPY_ATTR_INDEX = 2;
29    private static final int PASTE_ATTR_INDEX = 3;
30    private static final int[] ACTION_MODE_ATTRS = {
31        android.R.attr.actionModeSelectAllDrawable,
32        android.R.attr.actionModeCutDrawable,
33        android.R.attr.actionModeCopyDrawable,
34        android.R.attr.actionModePasteDrawable,
35    };
36 
37    private static final int ID_SELECTALL = 0;
38    private static final int ID_COPY = 1;
39    private static final int ID_SHARE = 2;
40    private static final int ID_SEARCH = 3;
41    private static final int ID_CUT = 4;
42    private static final int ID_PASTE = 5;
43 
44    /**
45     * An interface to retrieve information about the current selection, and also to perform
46     * actions based on the selection or when the action bar is dismissed.
47     */
48    public interface ActionHandler {
49        /**
50         * Perform a select all action.
51         * @return true iff the action was successful.
52         */
53        boolean selectAll();
54 
55        /**
56         * Perform a copy (to clipboard) action.
57         * @return true iff the action was successful.
58         */
59        boolean copy();
60 
61        /**
62         * Perform a cut (to clipboard) action.
63         * @return true iff the action was successful.
64         */
65        boolean cut();
66 
67        /**
68         * Perform a paste action.
69         * @return true iff the action was successful.
70         */
71        boolean paste();
72 
73        /**
74         * @return true iff the current selection is editable (e.g. text within an input field).
75         */
76        boolean isSelectionEditable();
77 
78        /**
79         * @return the currently selected text String.
80         */
81        String getSelectedText();
82 
83        /**
84         * Called when the onDestroyActionMode of the SelectActionmodeCallback is called.
85         */
86        void onDestroyActionMode();
87    }
88 
89    private Context mContext;
90    private ActionHandler mActionHandler;
91    private final boolean mIncognito;
92    private boolean mEditable;
93 
94    protected SelectActionModeCallback(
95            Context context, ActionHandler actionHandler, boolean incognito) {
96        mContext = context;
97        mActionHandler = actionHandler;
98        mIncognito = incognito;
99    }
100 
101    protected Context getContext() {
102        return mContext;
103    }
104 
105    @Override
106    public boolean onCreateActionMode(ActionMode mode, Menu menu) {
107        mode.setTitle(null);
108        mode.setSubtitle(null);
109        mEditable = mActionHandler.isSelectionEditable();
110        createActionMenu(mode, menu);
111        return true;
112    }
113 
114    @Override
115    public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
116        boolean isEditableNow = mActionHandler.isSelectionEditable();
117        if (mEditable != isEditableNow) {
118            mEditable = isEditableNow;
119            menu.clear();
120            createActionMenu(mode, menu);
121            return true;
122        }
123        return false;
124    }
125 
126    private void createActionMenu(ActionMode mode, Menu menu) {
127        TypedArray styledAttributes = getContext().obtainStyledAttributes(ACTION_MODE_ATTRS);
128 
129        menu.add(Menu.NONE, ID_SELECTALL, Menu.NONE, android.R.string.selectAll).
130            setAlphabeticShortcut('a').
131            setIcon(styledAttributes.getResourceId(SELECT_ALL_ATTR_INDEX, 0)).
132            setShowAsAction(
133                    MenuItem.SHOW_AS_ACTION_ALWAYS | MenuItem.SHOW_AS_ACTION_WITH_TEXT);
134 
135        if (mEditable) {
136            menu.add(Menu.NONE, ID_CUT, Menu.NONE, android.R.string.cut).
137            setIcon(styledAttributes.getResourceId(CUT_ATTR_INDEX, 0)).
138            setAlphabeticShortcut('x').
139            setShowAsAction(
140                    MenuItem.SHOW_AS_ACTION_ALWAYS | MenuItem.SHOW_AS_ACTION_WITH_TEXT);
141        }
142 
143        menu.add(Menu.NONE, ID_COPY, Menu.NONE, android.R.string.copy).
144            setIcon(styledAttributes.getResourceId(COPY_ATTR_INDEX, 0)).
145            setAlphabeticShortcut('c').
146            setShowAsAction(
147                    MenuItem.SHOW_AS_ACTION_ALWAYS | MenuItem.SHOW_AS_ACTION_WITH_TEXT);
148 
149        if (mEditable && canPaste()) {
150            menu.add(Menu.NONE, ID_PASTE, Menu.NONE, android.R.string.paste).
151                setIcon(styledAttributes.getResourceId(PASTE_ATTR_INDEX, 0)).
152                setAlphabeticShortcut('v').
153                setShowAsAction(
154                        MenuItem.SHOW_AS_ACTION_ALWAYS | MenuItem.SHOW_AS_ACTION_WITH_TEXT);
155        }
156 
157        if (!mEditable) {
158            if (isShareHandlerAvailable()) {
159                menu.add(Menu.NONE, ID_SHARE, Menu.NONE, R.string.actionbar_share).
160                    setIcon(R.drawable.ic_menu_share_holo_light).
161                    setShowAsAction(
162                            MenuItem.SHOW_AS_ACTION_ALWAYS | MenuItem.SHOW_AS_ACTION_WITH_TEXT);
163            }
164 
165            if (!mIncognito && isWebSearchAvailable()) {
166                menu.add(Menu.NONE, ID_SEARCH, Menu.NONE, R.string.actionbar_web_search).
167                    setIcon(R.drawable.ic_menu_search_holo_light).
168                    setShowAsAction(
169                            MenuItem.SHOW_AS_ACTION_ALWAYS | MenuItem.SHOW_AS_ACTION_WITH_TEXT);
170            }
171        }
172 
173        styledAttributes.recycle();
174    }
175 
176    @Override
177    public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
178        String selection = mActionHandler.getSelectedText();
179        switch(item.getItemId()) {
180            case ID_SELECTALL:
181                mActionHandler.selectAll();
182                break;
183            case ID_CUT:
184                mActionHandler.cut();
185                break;
186            case ID_COPY:
187                mActionHandler.copy();
188                mode.finish();
189                break;
190            case ID_PASTE:
191                mActionHandler.paste();
192                break;
193            case ID_SHARE:
194                if (!TextUtils.isEmpty(selection)) {
195                    Intent send = new Intent(Intent.ACTION_SEND);
196                    send.setType("text/plain");
197                    send.putExtra(Intent.EXTRA_TEXT, selection);
198                    try {
199                        Intent i = Intent.createChooser(send, getContext().getString(
200                                R.string.actionbar_share));
201                        i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
202                        getContext().startActivity(i);
203                    } catch (android.content.ActivityNotFoundException ex) {
204                        // If no app handles it, do nothing.
205                    }
206                }
207                mode.finish();
208                break;
209            case ID_SEARCH:
210                if (!TextUtils.isEmpty(selection)) {
211                    Intent i = new Intent(Intent.ACTION_WEB_SEARCH);
212                    i.putExtra(SearchManager.EXTRA_NEW_SEARCH, true);
213                    i.putExtra(SearchManager.QUERY, selection);
214                    i.putExtra(Browser.EXTRA_APPLICATION_ID, getContext().getPackageName());
215                    try {
216                        getContext().startActivity(i);
217                    } catch (android.content.ActivityNotFoundException ex) {
218                        // If no app handles it, do nothing.
219                    }
220                }
221                mode.finish();
222                break;
223            default:
224                return false;
225        }
226        return true;
227    }
228 
229    @Override
230    public void onDestroyActionMode(ActionMode mode) {
231        mActionHandler.onDestroyActionMode();
232    }
233 
234    private boolean canPaste() {
235        ClipboardManager clipMgr = (ClipboardManager)
236                getContext().getSystemService(Context.CLIPBOARD_SERVICE);
237        return clipMgr.hasPrimaryClip();
238    }
239 
240    private boolean isShareHandlerAvailable() {
241        Intent intent = new Intent(Intent.ACTION_SEND);
242        intent.setType("text/plain");
243        return getContext().getPackageManager()
244                .queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY).size() > 0;
245    }
246 
247    private boolean isWebSearchAvailable() {
248        Intent intent = new Intent(Intent.ACTION_WEB_SEARCH);
249        intent.putExtra(SearchManager.EXTRA_NEW_SEARCH, true);
250        return getContext().getPackageManager()
251                .queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY).size() > 0;
252    }
253}

[all classes][org.chromium.content.browser]
EMMA 2.0.5312 (C) Vladimir Roubtsov