Skip to content

Commit be25ca2

Browse files
adampAndroid (Google) Code Review
authored andcommitted
Merge "Fix bugs around overlay action modes."
2 parents f00b4de + f8419a0 commit be25ca2

File tree

6 files changed

+89
-11
lines changed

6 files changed

+89
-11
lines changed

core/java/android/view/ActionMode.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,18 @@ public Object getTag() {
152152
*/
153153
public abstract MenuInflater getMenuInflater();
154154

155+
/**
156+
* Returns whether the UI presenting this action mode can take focus or not.
157+
* This is used by internal components within the framework that would otherwise
158+
* present an action mode UI that requires focus, such as an EditText as a custom view.
159+
*
160+
* @return true if the UI used to show this action mode can take focus
161+
* @hide Internal use only
162+
*/
163+
public boolean isUiFocusable() {
164+
return true;
165+
}
166+
155167
/**
156168
* Callback interface for action modes. Supplied to
157169
* {@link View#startActionMode(Callback)}, a Callback

core/java/android/webkit/FindActionModeCallback.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,14 @@ public void onClick(View v) {
180180

181181
@Override
182182
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
183+
if (!mode.isUiFocusable()) {
184+
// If the action mode we're running in is not focusable the user
185+
// will not be able to type into the find on page field. This
186+
// should only come up when we're running in a dialog which is
187+
// already less than ideal; disable the option for now.
188+
return false;
189+
}
190+
183191
mode.setCustomView(mCustomView);
184192
mode.getMenuInflater().inflate(com.android.internal.R.menu.webview_find,
185193
menu);

core/java/android/webkit/SelectActionModeCallback.java

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,12 @@
1717
package android.webkit;
1818

1919
import android.app.SearchManager;
20+
import android.content.Context;
2021
import android.content.Intent;
2122
import android.provider.Browser;
22-
import android.webkit.WebView;
2323
import android.view.ActionMode;
2424
import android.view.Menu;
2525
import android.view.MenuItem;
26-
import android.view.View;
2726

2827
class SelectActionModeCallback implements ActionMode.Callback {
2928
private WebView mWebView;
@@ -45,9 +44,25 @@ void finish() {
4544

4645
@Override
4746
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
48-
mode.getMenuInflater().inflate(com.android.internal.R.menu.webview_copy,
49-
menu);
50-
mode.setTitle(com.android.internal.R.string.textSelectionCABTitle);
47+
mode.getMenuInflater().inflate(com.android.internal.R.menu.webview_copy, menu);
48+
49+
final Context context = mWebView.getContext();
50+
boolean allowText = context.getResources().getBoolean(
51+
com.android.internal.R.bool.config_allowActionMenuItemTextWithIcon);
52+
mode.setTitle(allowText ?
53+
context.getString(com.android.internal.R.string.textSelectionCABTitle) : null);
54+
55+
if (!mode.isUiFocusable()) {
56+
// If the action mode UI we're running in isn't capable of taking window focus
57+
// the user won't be able to type into the find on page UI. Disable this functionality.
58+
// (Note that this should only happen in floating dialog windows.)
59+
// This can be removed once we can handle multiple focusable windows at a time
60+
// in a better way.
61+
final MenuItem findOnPageItem = menu.findItem(com.android.internal.R.id.find);
62+
if (findOnPageItem != null) {
63+
findOnPageItem.setVisible(false);
64+
}
65+
}
5166
mActionMode = mode;
5267
return true;
5368
}

core/java/com/android/internal/view/StandaloneActionMode.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,17 +36,19 @@ public class StandaloneActionMode extends ActionMode implements MenuBuilder.Call
3636
private ActionMode.Callback mCallback;
3737
private WeakReference<View> mCustomView;
3838
private boolean mFinished;
39+
private boolean mFocusable;
3940

4041
private MenuBuilder mMenu;
4142

4243
public StandaloneActionMode(Context context, ActionBarContextView view,
43-
ActionMode.Callback callback) {
44+
ActionMode.Callback callback, boolean isFocusable) {
4445
mContext = context;
4546
mContextView = view;
4647
mCallback = callback;
4748

4849
mMenu = new MenuBuilder(context).setDefaultShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
4950
mMenu.setCallback(this);
51+
mFocusable = isFocusable;
5052
}
5153

5254
@Override
@@ -139,4 +141,8 @@ public void onMenuModeChange(MenuBuilder menu) {
139141
invalidate();
140142
mContextView.showOverflowMenu();
141143
}
144+
145+
public boolean isUiFocusable() {
146+
return mFocusable;
147+
}
142148
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<!--
3+
/*
4+
** Copyright 2011, The Android Open Source Project
5+
**
6+
** Licensed under the Apache License, Version 2.0 (the "License");
7+
** you may not use this file except in compliance with the License.
8+
** You may obtain a copy of the License at
9+
**
10+
** http://www.apache.org/licenses/LICENSE-2.0
11+
**
12+
** Unless required by applicable law or agreed to in writing, software
13+
** distributed under the License is distributed on an "AS IS" BASIS,
14+
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
** See the License for the specific language governing permissions and
16+
** limitations under the License.
17+
*/
18+
19+
This is an optimized layout for a screen, with the minimum set of features
20+
enabled.
21+
-->
22+
23+
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
24+
android:fitsSystemWindows="true">
25+
<FrameLayout
26+
android:id="@android:id/content"
27+
android:layout_width="match_parent"
28+
android:layout_height="match_parent"
29+
android:foregroundInsidePadding="false"
30+
android:foregroundGravity="fill_horizontal|top"
31+
android:foreground="?android:attr/windowContentOverlay" />
32+
<ViewStub android:id="@+id/action_mode_bar_stub"
33+
android:inflatedId="@+id/action_mode_bar"
34+
android:layout="@layout/action_mode_bar"
35+
android:layout_width="match_parent"
36+
android:layout_height="wrap_content" />
37+
</FrameLayout>

policy/src/com/android/internal/policy/impl/PhoneWindow.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2147,15 +2147,12 @@ public ActionMode startActionMode(ActionMode.Callback callback) {
21472147
mActionMode = mode;
21482148
} else {
21492149
if (mActionModeView == null) {
2150-
if (hasFeature(FEATURE_ACTION_MODE_OVERLAY)) {
2150+
if (isFloating()) {
21512151
mActionModeView = new ActionBarContextView(mContext);
21522152
mActionModePopup = new PopupWindow(mContext, null,
21532153
com.android.internal.R.attr.actionModePopupWindowStyle);
21542154
mActionModePopup.setLayoutInScreenEnabled(true);
21552155
mActionModePopup.setLayoutInsetDecor(true);
2156-
mActionModePopup.setFocusable(true);
2157-
mActionModePopup.setOutsideTouchable(false);
2158-
mActionModePopup.setTouchModal(false);
21592156
mActionModePopup.setWindowLayoutType(
21602157
WindowManager.LayoutParams.TYPE_APPLICATION);
21612158
mActionModePopup.setContentView(mActionModeView);
@@ -2186,7 +2183,8 @@ public void run() {
21862183

21872184
if (mActionModeView != null) {
21882185
mActionModeView.killMode();
2189-
mode = new StandaloneActionMode(getContext(), mActionModeView, wrappedCallback);
2186+
mode = new StandaloneActionMode(getContext(), mActionModeView, wrappedCallback,
2187+
mActionModePopup == null);
21902188
if (callback.onCreateActionMode(mode, mode.getMenu())) {
21912189
mode.invalidate();
21922190
mActionModeView.initForMode(mode);
@@ -2664,6 +2662,8 @@ protected ViewGroup generateLayout(DecorView decor) {
26642662
layoutResource = com.android.internal.R.layout.screen_title;
26652663
}
26662664
// System.out.println("Title!");
2665+
} else if ((features & (1 << FEATURE_ACTION_MODE_OVERLAY)) != 0) {
2666+
layoutResource = com.android.internal.R.layout.screen_simple_overlay_action_mode;
26672667
} else {
26682668
// Embedded, so no decoration is needed.
26692669
layoutResource = com.android.internal.R.layout.screen_simple;

0 commit comments

Comments
 (0)