Upstream version 6.35.121.0
[platform/framework/web/crosswalk.git] / src / chrome / android / java / src / org / chromium / chrome / browser / appmenu / AppMenuHandler.java
1 // Copyright 2013 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.appmenu;
6
7 import android.app.Activity;
8 import android.content.res.TypedArray;
9 import android.graphics.Rect;
10 import android.view.ContextThemeWrapper;
11 import android.view.Menu;
12 import android.view.MenuItem;
13 import android.view.View;
14 import android.widget.PopupMenu;
15
16 import com.google.common.annotations.VisibleForTesting;
17
18 import org.chromium.chrome.browser.UmaBridge;
19
20 import java.util.ArrayList;
21
22 /**
23  * Object responsible for handling the creation, showing, hiding of the AppMenu and notifying the
24  * AppMenuObservers about these actions.
25  */
26 public class AppMenuHandler {
27     private AppMenu mAppMenu;
28     private AppMenuDragHelper mAppMenuDragHelper;
29     private Menu mMenu;
30     private final ArrayList<AppMenuObserver> mObservers;
31     private final int mMenuResourceId;
32
33     private final AppMenuPropertiesDelegate mDelegate;
34     private final Activity mActivity;
35
36     /**
37      * Constructs an AppMenuHandler object.
38      * @param activity Activity that is using the AppMenu.
39      * @param delegate Delegate used to check the desired AppMenu properties on show.
40      * @param menuResourceId Resource Id that should be used as the source for the menu items.
41      *            It is assumed to have back_menu_id, forward_menu_id, bookmark_this_page_id.
42      */
43     public AppMenuHandler(Activity activity, AppMenuPropertiesDelegate delegate,
44             int menuResourceId) {
45         mActivity = activity;
46         mDelegate = delegate;
47         mObservers = new ArrayList<AppMenuObserver>();
48         mMenuResourceId = menuResourceId;
49     }
50
51     /**
52      * Show the app menu.
53      * @param anchorView         Anchor view (usually a menu button) to be used for the popup.
54      * @param isByHardwareButton True if hardware button triggered it. (oppose to software
55      *                           button)
56      * @param startDragging      Whether dragging is started. For example, if the app menu is
57      *                           showed by tapping on a button, this should be false. If it is
58      *                           showed by start dragging down on the menu button, this should
59      *                           be true. Note that if isByHardwareButton is true, this is
60      *                           ignored.
61      * @return True, if the menu is shown, false, if menu is not shown, example reasons:
62      *         the menu is not yet available to be shown, or the menu is already showing.
63      */
64     public boolean showAppMenu(View anchorView, boolean isByHardwareButton, boolean startDragging) {
65         if (!mDelegate.shouldShowAppMenu()) return false;
66
67         if (mMenu == null) {
68             // Use a PopupMenu to create the Menu object. Note this is not the same as the
69             // AppMenu (mAppMenu) created below.
70             PopupMenu tempMenu = new PopupMenu(mActivity, anchorView);
71             tempMenu.inflate(mMenuResourceId);
72             mMenu = tempMenu.getMenu();
73         }
74         mDelegate.prepareMenu(mMenu);
75
76         if (mAppMenu == null) {
77             TypedArray a = mActivity.obtainStyledAttributes(
78                     new int[] {android.R.attr.listPreferredItemHeightSmall});
79             int itemRowHeight = a.getDimensionPixelSize(0, 0);
80             a.recycle();
81             mAppMenu = new AppMenu(mMenu, itemRowHeight, this, mActivity.getResources());
82             mAppMenuDragHelper = new AppMenuDragHelper(mActivity, mAppMenu, itemRowHeight);
83         }
84
85         ContextThemeWrapper wrapper = new ContextThemeWrapper(mActivity,
86                 mDelegate.getMenuThemeResourceId());
87         // Get the height and width of the display.
88         Rect appRect = new Rect();
89         mActivity.getWindow().getDecorView().getWindowVisibleDisplayFrame(appRect);
90         int rotation = mActivity.getWindowManager().getDefaultDisplay().getRotation();
91         mAppMenu.show(wrapper, anchorView, isByHardwareButton, rotation, appRect);
92         mAppMenuDragHelper.onShow(isByHardwareButton, startDragging);
93         UmaBridge.menuShow();
94         return true;
95     }
96
97     void appMenuDismissed() {
98         mAppMenuDragHelper.onDismiss();
99     }
100
101     /**
102      * @return Whether the App Menu is currently showing.
103      */
104     public boolean isAppMenuShowing() {
105         return mAppMenu != null && mAppMenu.isShowing();
106     }
107
108     /**
109      * @return The App Menu that the menu handler is interacting with.
110      */
111     @VisibleForTesting
112     AppMenu getAppMenu() {
113         return mAppMenu;
114     }
115
116     AppMenuDragHelper getAppMenuDragHelper() {
117         return mAppMenuDragHelper;
118     }
119
120     /**
121      * Requests to hide the App Menu.
122      */
123     public void hideAppMenu() {
124         if (mAppMenu != null && mAppMenu.isShowing()) mAppMenu.dismiss();
125     }
126
127     /**
128      * Adds the observer to App Menu.
129      * @param observer Observer that should be notified about App Menu changes.
130      */
131     public void addObserver(AppMenuObserver observer) {
132         mObservers.add(observer);
133     }
134
135     /**
136      * Removes the observer from the App Menu.
137      * @param observer Observer that should no longer be notified about App Menu changes.
138      */
139     public void removeObserver(AppMenuObserver observer) {
140         mObservers.remove(observer);
141     }
142
143     void onOptionsItemSelected(MenuItem item) {
144         mActivity.onOptionsItemSelected(item);
145     }
146
147     /**
148      * Called by AppMenu to report that the App Menu visibility has changed.
149      * @param isVisible Whether the App Menu is showing.
150      */
151     void onMenuVisibilityChanged(boolean isVisible) {
152         for (int i = 0; i < mObservers.size(); ++i) {
153             mObservers.get(i).onMenuVisibilityChanged(isVisible);
154         }
155     }
156
157     /**
158      * TODO(kkimlabs) remove this call.
159      */
160     public void hardwareMenuButtonUp() {
161         if (mAppMenuDragHelper != null) mAppMenuDragHelper.hardwareMenuButtonUp();
162     }
163 }