151ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov/*
251ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov * Copyright (C) 2011 The Android Open Source Project
351ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov *
451ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov * Licensed under the Apache License, Version 2.0 (the "License");
551ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov * you may not use this file except in compliance with the License.
651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov * You may obtain a copy of the License at
751ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov *
851ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov *      http://www.apache.org/licenses/LICENSE-2.0
951ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov *
1051ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov * Unless required by applicable law or agreed to in writing, software
1151ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov * distributed under the License is distributed on an "AS IS" BASIS,
1251ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1351ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov * See the License for the specific language governing permissions and
1451ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov * limitations under the License.
1551ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov */
1651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
1751ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganovpackage android.widget;
1851ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
197b9c912f536925ac6ec43935d6e97506851b33d6Tor Norbyeimport android.annotation.StringRes;
2051ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganovimport android.content.Context;
2151ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganovimport android.content.Intent;
2251ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganovimport android.content.pm.PackageManager;
2351ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganovimport android.content.pm.ResolveInfo;
24414051b8b1e31b69ca622d68f391245f1989500bSvetoslav Ganovimport android.content.res.Resources;
2551ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganovimport android.content.res.TypedArray;
2651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganovimport android.database.DataSetObserver;
27e471a4e0f720c1ea89025cd79ffca88daffcfde7sergeyvimport android.graphics.Color;
28e471a4e0f720c1ea89025cd79ffca88daffcfde7sergeyvimport android.graphics.drawable.ColorDrawable;
2951ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganovimport android.graphics.drawable.Drawable;
3051ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganovimport android.util.AttributeSet;
31baeabb65e1e818c6679036774933f40e8540b293Svetoslavimport android.util.Log;
32823f074a73cfc23c40a7b576c71daa096ee9ed6aAdam Powellimport android.view.ActionProvider;
3351ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganovimport android.view.LayoutInflater;
3451ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganovimport android.view.View;
3551ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganovimport android.view.ViewGroup;
368c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganovimport android.view.ViewTreeObserver;
378c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganovimport android.view.ViewTreeObserver.OnGlobalLayoutListener;
38058ac7cfe5bb7b9ecc411b94622ac3f31a7fa25eAlan Viveretteimport android.view.accessibility.AccessibilityNodeInfo;
3951ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganovimport android.widget.ActivityChooserModel.ActivityChooserModelClient;
4051ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
4199441c5d7da45c10b729185852be97cbb0bdc8d5Aurimas Liutikasimport com.android.internal.R;
4299441c5d7da45c10b729185852be97cbb0bdc8d5Aurimas Liutikasimport com.android.internal.view.menu.ShowableListMenu;
4399441c5d7da45c10b729185852be97cbb0bdc8d5Aurimas Liutikas
4451ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov/**
4551ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov * This class is a view for choosing an activity for handling a given {@link Intent}.
4651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov * <p>
4751ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov * The view is composed of two adjacent buttons:
4851ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov * <ul>
4951ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov * <li>
5051ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov * The left button is an immediate action and allows one click activity choosing.
5151ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov * Tapping this button immediately executes the intent without requiring any further
5251ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov * user input. Long press on this button shows a popup for changing the default
5351ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov * activity.
5451ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov * </li>
5551ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov * <li>
5651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov * The right button is an overflow action and provides an optimized menu
5751ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov * of additional activities. Tapping this button shows a popup anchored to this
5851ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov * view, listing the most frequently used activities. This list is initially
5951ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov * limited to a small number of items in frequency used order. The last item,
6051ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov * "Show all..." serves as an affordance to display all available activities.
6151ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov * </li>
6251ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov * </ul>
6351ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov * </p>
6451ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov *
6551ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov * @hide
6651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov */
6751ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganovpublic class ActivityChooserView extends ViewGroup implements ActivityChooserModelClient {
6851ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
69baeabb65e1e818c6679036774933f40e8540b293Svetoslav    private static final String LOG_TAG = "ActivityChooserView";
70baeabb65e1e818c6679036774933f40e8540b293Svetoslav
7151ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    /**
7251ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     * An adapter for displaying the activities in an {@link AdapterView}.
7351ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     */
7451ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    private final ActivityChooserViewAdapter mAdapter;
7551ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
7651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    /**
7751ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     * Implementation of various interfaces to avoid publishing them in the APIs.
7851ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     */
7951ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    private final Callbacks mCallbacks;
8051ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
8151ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    /**
8251ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     * The content of this view.
8351ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     */
8451ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    private final LinearLayout mActivityChooserContent;
8551ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
8651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    /**
87f2e754002166b8126e6faf8c494da5835432d572Svetoslav Ganov     * Stores the background drawable to allow hiding and latter showing.
88f2e754002166b8126e6faf8c494da5835432d572Svetoslav Ganov     */
89f2e754002166b8126e6faf8c494da5835432d572Svetoslav Ganov    private final Drawable mActivityChooserContentBackground;
90f2e754002166b8126e6faf8c494da5835432d572Svetoslav Ganov
91f2e754002166b8126e6faf8c494da5835432d572Svetoslav Ganov    /**
9251ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     * The expand activities action button;
9351ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     */
94bfbbcf5677d4a5f8c8f938e4c8a8f86d3c7d74c2Svetoslav Ganov    private final FrameLayout mExpandActivityOverflowButton;
95bfbbcf5677d4a5f8c8f938e4c8a8f86d3c7d74c2Svetoslav Ganov
96bfbbcf5677d4a5f8c8f938e4c8a8f86d3c7d74c2Svetoslav Ganov    /**
97bfbbcf5677d4a5f8c8f938e4c8a8f86d3c7d74c2Svetoslav Ganov     * The image for the expand activities action button;
98bfbbcf5677d4a5f8c8f938e4c8a8f86d3c7d74c2Svetoslav Ganov     */
99bfbbcf5677d4a5f8c8f938e4c8a8f86d3c7d74c2Svetoslav Ganov    private final ImageView mExpandActivityOverflowButtonImage;
10051ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
10151ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    /**
10251ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     * The default activities action button;
10351ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     */
104bfbbcf5677d4a5f8c8f938e4c8a8f86d3c7d74c2Svetoslav Ganov    private final FrameLayout mDefaultActivityButton;
105bfbbcf5677d4a5f8c8f938e4c8a8f86d3c7d74c2Svetoslav Ganov
106bfbbcf5677d4a5f8c8f938e4c8a8f86d3c7d74c2Svetoslav Ganov    /**
107bfbbcf5677d4a5f8c8f938e4c8a8f86d3c7d74c2Svetoslav Ganov     * The image for the default activities action button;
108bfbbcf5677d4a5f8c8f938e4c8a8f86d3c7d74c2Svetoslav Ganov     */
109bfbbcf5677d4a5f8c8f938e4c8a8f86d3c7d74c2Svetoslav Ganov    private final ImageView mDefaultActivityButtonImage;
11051ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
11151ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    /**
112414051b8b1e31b69ca622d68f391245f1989500bSvetoslav Ganov     * The maximal width of the list popup.
113414051b8b1e31b69ca622d68f391245f1989500bSvetoslav Ganov     */
114414051b8b1e31b69ca622d68f391245f1989500bSvetoslav Ganov    private final int mListPopupMaxWidth;
115414051b8b1e31b69ca622d68f391245f1989500bSvetoslav Ganov
116414051b8b1e31b69ca622d68f391245f1989500bSvetoslav Ganov    /**
117823f074a73cfc23c40a7b576c71daa096ee9ed6aAdam Powell     * The ActionProvider hosting this view, if applicable.
118823f074a73cfc23c40a7b576c71daa096ee9ed6aAdam Powell     */
119823f074a73cfc23c40a7b576c71daa096ee9ed6aAdam Powell    ActionProvider mProvider;
120823f074a73cfc23c40a7b576c71daa096ee9ed6aAdam Powell
121823f074a73cfc23c40a7b576c71daa096ee9ed6aAdam Powell    /**
12276559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov     * Observer for the model data.
12351ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     */
12476559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov    private final DataSetObserver mModelDataSetOberver = new DataSetObserver() {
12551ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
12676559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov        @Override
12776559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov        public void onChanged() {
12876559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov            super.onChanged();
12976559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov            mAdapter.notifyDataSetChanged();
13076559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov        }
13176559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov        @Override
13276559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov        public void onInvalidated() {
13376559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov            super.onInvalidated();
13476559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov            mAdapter.notifyDataSetInvalidated();
13576559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov        }
13676559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov    };
13751ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
1388c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov    private final OnGlobalLayoutListener mOnGlobalLayoutListener = new OnGlobalLayoutListener() {
1398c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov        @Override
1408c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov        public void onGlobalLayout() {
1418c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov            if (isShowingPopup()) {
1428c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov                if (!isShown()) {
1438c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov                    getListPopupWindow().dismiss();
1448c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov                } else {
1458c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov                    getListPopupWindow().show();
146823f074a73cfc23c40a7b576c71daa096ee9ed6aAdam Powell                    if (mProvider != null) {
147823f074a73cfc23c40a7b576c71daa096ee9ed6aAdam Powell                        mProvider.subUiVisibilityChanged(true);
148823f074a73cfc23c40a7b576c71daa096ee9ed6aAdam Powell                    }
1498c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov                }
1508c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov            }
1518c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov        }
1528c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov    };
1538c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov
15451ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    /**
15551ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     * Popup window for showing the activity overflow list.
15651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     */
15751ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    private ListPopupWindow mListPopupWindow;
15851ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
15951ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    /**
16051ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     * Listener for the dismissal of the popup/alert.
16151ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     */
16251ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    private PopupWindow.OnDismissListener mOnDismissListener;
16351ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
16451ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    /**
16551ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     * Flag whether a default activity currently being selected.
16651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     */
16751ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    private boolean mIsSelectingDefaultActivity;
16851ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
16951ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    /**
17051ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     * The count of activities in the popup.
17151ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     */
17251ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    private int mInitialActivityCount = ActivityChooserViewAdapter.MAX_ACTIVITY_COUNT_DEFAULT;
17351ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
17451ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    /**
17551ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     * Flag whether this view is attached to a window.
17651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     */
17751ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    private boolean mIsAttachedToWindow;
17851ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
17951ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    /**
18070853772bd119339244a4fc8e020ad78495228beSvetoslav Ganov     * String resource for formatting content description of the default target.
18170853772bd119339244a4fc8e020ad78495228beSvetoslav Ganov     */
18270853772bd119339244a4fc8e020ad78495228beSvetoslav Ganov    private int mDefaultActionButtonContentDescription;
18370853772bd119339244a4fc8e020ad78495228beSvetoslav Ganov
18470853772bd119339244a4fc8e020ad78495228beSvetoslav Ganov    /**
18551ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     * Create a new instance.
18651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     *
18751ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     * @param context The application environment.
18851ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     */
18951ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    public ActivityChooserView(Context context) {
19051ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        this(context, null);
19151ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    }
19251ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
19351ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    /**
19451ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     * Create a new instance.
19551ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     *
19651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     * @param context The application environment.
19751ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     * @param attrs A collection of attributes.
19851ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     */
19951ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    public ActivityChooserView(Context context, AttributeSet attrs) {
20023f4cc0353615107cc9c19fda9cf96ddd43266e2Adam Powell        this(context, attrs, 0);
20151ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    }
20251ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
20351ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    /**
20451ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     * Create a new instance.
20551ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     *
20651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     * @param context The application environment.
20751ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     * @param attrs A collection of attributes.
208617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette     * @param defStyleAttr An attribute in the current theme that contains a
209617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette     *        reference to a style resource that supplies default values for
210617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette     *        the view. Can be 0 to not look for defaults.
21151ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     */
212617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette    public ActivityChooserView(Context context, AttributeSet attrs, int defStyleAttr) {
213617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette        this(context, attrs, defStyleAttr, 0);
214617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette    }
215617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette
216617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette    /**
217617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette     * Create a new instance.
218617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette     *
219617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette     * @param context The application environment.
220617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette     * @param attrs A collection of attributes.
221617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette     * @param defStyleAttr An attribute in the current theme that contains a
222617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette     *        reference to a style resource that supplies default values for
223617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette     *        the view. Can be 0 to not look for defaults.
224617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette     * @param defStyleRes A resource identifier of a style resource that
225617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette     *        supplies default values for the view, used only if
226617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette     *        defStyleAttr is 0 or can not be found in the theme. Can be 0
227617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette     *        to not look for defaults.
228617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette     */
229617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette    public ActivityChooserView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
230617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette        super(context, attrs, defStyleAttr, defStyleRes);
23151ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
23251ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        TypedArray attributesArray = context.obtainStyledAttributes(attrs,
233617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette                R.styleable.ActivityChooserView, defStyleAttr, defStyleRes);
23451ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
23551ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        mInitialActivityCount = attributesArray.getInt(
23651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov                R.styleable.ActivityChooserView_initialActivityCount,
23751ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov                ActivityChooserViewAdapter.MAX_ACTIVITY_COUNT_DEFAULT);
23851ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
23951ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        Drawable expandActivityOverflowButtonDrawable = attributesArray.getDrawable(
24051ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov                R.styleable.ActivityChooserView_expandActivityOverflowButtonDrawable);
24151ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
242f2e754002166b8126e6faf8c494da5835432d572Svetoslav Ganov        attributesArray.recycle();
243f2e754002166b8126e6faf8c494da5835432d572Svetoslav Ganov
24476559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov        LayoutInflater inflater = LayoutInflater.from(mContext);
24551ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        inflater.inflate(R.layout.activity_chooser_view, this, true);
24651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
24751ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        mCallbacks = new Callbacks();
24851ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
24951ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        mActivityChooserContent = (LinearLayout) findViewById(R.id.activity_chooser_view_content);
250f2e754002166b8126e6faf8c494da5835432d572Svetoslav Ganov        mActivityChooserContentBackground = mActivityChooserContent.getBackground();
25151ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
252bfbbcf5677d4a5f8c8f938e4c8a8f86d3c7d74c2Svetoslav Ganov        mDefaultActivityButton = (FrameLayout) findViewById(R.id.default_activity_button);
253bfbbcf5677d4a5f8c8f938e4c8a8f86d3c7d74c2Svetoslav Ganov        mDefaultActivityButton.setOnClickListener(mCallbacks);
254bfbbcf5677d4a5f8c8f938e4c8a8f86d3c7d74c2Svetoslav Ganov        mDefaultActivityButton.setOnLongClickListener(mCallbacks);
2558e1a72964517bfd01d8e650453ef41e22f770f21Alan Viverette        mDefaultActivityButtonImage = mDefaultActivityButton.findViewById(R.id.image);
25651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
2575d46c89e3c032711a3835dbe5e4b499f5cd4d023Alan Viverette        final FrameLayout expandButton = (FrameLayout) findViewById(R.id.expand_activities_button);
2585d46c89e3c032711a3835dbe5e4b499f5cd4d023Alan Viverette        expandButton.setOnClickListener(mCallbacks);
2595d46c89e3c032711a3835dbe5e4b499f5cd4d023Alan Viverette        expandButton.setAccessibilityDelegate(new AccessibilityDelegate() {
260058ac7cfe5bb7b9ecc411b94622ac3f31a7fa25eAlan Viverette            @Override
261058ac7cfe5bb7b9ecc411b94622ac3f31a7fa25eAlan Viverette            public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfo info) {
262058ac7cfe5bb7b9ecc411b94622ac3f31a7fa25eAlan Viverette                super.onInitializeAccessibilityNodeInfo(host, info);
263cb8ed39b3fb591be60b9fb1799d4ea4530eab758Svetoslav Ganov                info.setCanOpenPopup(true);
264058ac7cfe5bb7b9ecc411b94622ac3f31a7fa25eAlan Viverette            }
265058ac7cfe5bb7b9ecc411b94622ac3f31a7fa25eAlan Viverette        });
2665d46c89e3c032711a3835dbe5e4b499f5cd4d023Alan Viverette        expandButton.setOnTouchListener(new ForwardingListener(expandButton) {
2675d46c89e3c032711a3835dbe5e4b499f5cd4d023Alan Viverette            @Override
268f44d90b5c247f0629201d1fa322b83fa55b20608Oren Blasberg            public ShowableListMenu getPopup() {
2695d46c89e3c032711a3835dbe5e4b499f5cd4d023Alan Viverette                return getListPopupWindow();
2705d46c89e3c032711a3835dbe5e4b499f5cd4d023Alan Viverette            }
2715d46c89e3c032711a3835dbe5e4b499f5cd4d023Alan Viverette
2725d46c89e3c032711a3835dbe5e4b499f5cd4d023Alan Viverette            @Override
2735d46c89e3c032711a3835dbe5e4b499f5cd4d023Alan Viverette            protected boolean onForwardingStarted() {
2745d46c89e3c032711a3835dbe5e4b499f5cd4d023Alan Viverette                showPopup();
2755d46c89e3c032711a3835dbe5e4b499f5cd4d023Alan Viverette                return true;
2765d46c89e3c032711a3835dbe5e4b499f5cd4d023Alan Viverette            }
2775d46c89e3c032711a3835dbe5e4b499f5cd4d023Alan Viverette
2785d46c89e3c032711a3835dbe5e4b499f5cd4d023Alan Viverette            @Override
2795d46c89e3c032711a3835dbe5e4b499f5cd4d023Alan Viverette            protected boolean onForwardingStopped() {
2805d46c89e3c032711a3835dbe5e4b499f5cd4d023Alan Viverette                dismissPopup();
2815d46c89e3c032711a3835dbe5e4b499f5cd4d023Alan Viverette                return true;
2825d46c89e3c032711a3835dbe5e4b499f5cd4d023Alan Viverette            }
2835d46c89e3c032711a3835dbe5e4b499f5cd4d023Alan Viverette        });
2845d46c89e3c032711a3835dbe5e4b499f5cd4d023Alan Viverette        mExpandActivityOverflowButton = expandButton;
2855d46c89e3c032711a3835dbe5e4b499f5cd4d023Alan Viverette
286bfbbcf5677d4a5f8c8f938e4c8a8f86d3c7d74c2Svetoslav Ganov        mExpandActivityOverflowButtonImage =
2878e1a72964517bfd01d8e650453ef41e22f770f21Alan Viverette            expandButton.findViewById(R.id.image);
288bfbbcf5677d4a5f8c8f938e4c8a8f86d3c7d74c2Svetoslav Ganov        mExpandActivityOverflowButtonImage.setImageDrawable(expandActivityOverflowButtonDrawable);
28951ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
29051ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        mAdapter = new ActivityChooserViewAdapter();
29151ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        mAdapter.registerDataSetObserver(new DataSetObserver() {
29251ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            @Override
29351ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            public void onChanged() {
29451ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov                super.onChanged();
295f2e754002166b8126e6faf8c494da5835432d572Svetoslav Ganov                updateAppearance();
29651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            }
29751ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        });
298414051b8b1e31b69ca622d68f391245f1989500bSvetoslav Ganov
299414051b8b1e31b69ca622d68f391245f1989500bSvetoslav Ganov        Resources resources = context.getResources();
300414051b8b1e31b69ca622d68f391245f1989500bSvetoslav Ganov        mListPopupMaxWidth = Math.max(resources.getDisplayMetrics().widthPixels / 2,
301414051b8b1e31b69ca622d68f391245f1989500bSvetoslav Ganov              resources.getDimensionPixelSize(com.android.internal.R.dimen.config_prefDialogWidth));
30251ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    }
30351ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
30451ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    /**
30551ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     * {@inheritDoc}
30651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     */
30751ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    public void setActivityChooserModel(ActivityChooserModel dataModel) {
30851ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        mAdapter.setDataModel(dataModel);
30951ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        if (isShowingPopup()) {
31051ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            dismissPopup();
31151ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            showPopup();
31251ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        }
31351ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    }
31451ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
31551ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    /**
31651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     * Sets the background for the button that expands the activity
31751ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     * overflow list.
31851ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     *
31951ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     * <strong>Note:</strong> Clients would like to set this drawable
32051ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     * as a clue about the action the chosen activity will perform. For
32170853772bd119339244a4fc8e020ad78495228beSvetoslav Ganov     * example, if a share activity is to be chosen the drawable should
32251ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     * give a clue that sharing is to be performed.
32351ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     *
32451ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     * @param drawable The drawable.
32551ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     */
32651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    public void setExpandActivityOverflowButtonDrawable(Drawable drawable) {
327bfbbcf5677d4a5f8c8f938e4c8a8f86d3c7d74c2Svetoslav Ganov        mExpandActivityOverflowButtonImage.setImageDrawable(drawable);
32851ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    }
32951ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
33051ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    /**
33170853772bd119339244a4fc8e020ad78495228beSvetoslav Ganov     * Sets the content description for the button that expands the activity
33270853772bd119339244a4fc8e020ad78495228beSvetoslav Ganov     * overflow list.
33370853772bd119339244a4fc8e020ad78495228beSvetoslav Ganov     *
33470853772bd119339244a4fc8e020ad78495228beSvetoslav Ganov     * description as a clue about the action performed by the button.
33570853772bd119339244a4fc8e020ad78495228beSvetoslav Ganov     * For example, if a share activity is to be chosen the content
33670853772bd119339244a4fc8e020ad78495228beSvetoslav Ganov     * description should be something like "Share with".
33770853772bd119339244a4fc8e020ad78495228beSvetoslav Ganov     *
33870853772bd119339244a4fc8e020ad78495228beSvetoslav Ganov     * @param resourceId The content description resource id.
33970853772bd119339244a4fc8e020ad78495228beSvetoslav Ganov     */
3407b9c912f536925ac6ec43935d6e97506851b33d6Tor Norbye    public void setExpandActivityOverflowButtonContentDescription(@StringRes int resourceId) {
34170853772bd119339244a4fc8e020ad78495228beSvetoslav Ganov        CharSequence contentDescription = mContext.getString(resourceId);
34270853772bd119339244a4fc8e020ad78495228beSvetoslav Ganov        mExpandActivityOverflowButtonImage.setContentDescription(contentDescription);
34370853772bd119339244a4fc8e020ad78495228beSvetoslav Ganov    }
34470853772bd119339244a4fc8e020ad78495228beSvetoslav Ganov
34570853772bd119339244a4fc8e020ad78495228beSvetoslav Ganov    /**
346823f074a73cfc23c40a7b576c71daa096ee9ed6aAdam Powell     * Set the provider hosting this view, if applicable.
347823f074a73cfc23c40a7b576c71daa096ee9ed6aAdam Powell     * @hide Internal use only
348823f074a73cfc23c40a7b576c71daa096ee9ed6aAdam Powell     */
349823f074a73cfc23c40a7b576c71daa096ee9ed6aAdam Powell    public void setProvider(ActionProvider provider) {
350823f074a73cfc23c40a7b576c71daa096ee9ed6aAdam Powell        mProvider = provider;
351823f074a73cfc23c40a7b576c71daa096ee9ed6aAdam Powell    }
352823f074a73cfc23c40a7b576c71daa096ee9ed6aAdam Powell
353823f074a73cfc23c40a7b576c71daa096ee9ed6aAdam Powell    /**
35451ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     * Shows the popup window with activities.
35551ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     *
35651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     * @return True if the popup was shown, false if already showing.
35751ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     */
35851ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    public boolean showPopup() {
35976559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov        if (isShowingPopup() || !mIsAttachedToWindow) {
36051ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            return false;
36151ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        }
36251ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        mIsSelectingDefaultActivity = false;
36351ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        showPopupUnchecked(mInitialActivityCount);
36451ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        return true;
36551ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    }
36651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
36751ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    /**
36851ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     * Shows the popup no matter if it was already showing.
36951ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     *
37051ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     * @param maxActivityCount The max number of activities to display.
37151ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     */
37251ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    private void showPopupUnchecked(int maxActivityCount) {
37376559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov        if (mAdapter.getDataModel() == null) {
37476559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov            throw new IllegalStateException("No data model. Did you call #setDataModel?");
37551ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        }
37651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
3778c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov        getViewTreeObserver().addOnGlobalLayoutListener(mOnGlobalLayoutListener);
3788c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov
379f632eaa9d64fb21892cc057ec7444ec157686734Svetoslav Ganov        final boolean defaultActivityButtonShown =
380f632eaa9d64fb21892cc057ec7444ec157686734Svetoslav Ganov            mDefaultActivityButton.getVisibility() == VISIBLE;
381f632eaa9d64fb21892cc057ec7444ec157686734Svetoslav Ganov
38276559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov        final int activityCount = mAdapter.getActivityCount();
383f632eaa9d64fb21892cc057ec7444ec157686734Svetoslav Ganov        final int maxActivityCountOffset = defaultActivityButtonShown ? 1 : 0;
38476559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov        if (maxActivityCount != ActivityChooserViewAdapter.MAX_ACTIVITY_COUNT_UNLIMITED
385f632eaa9d64fb21892cc057ec7444ec157686734Svetoslav Ganov                && activityCount > maxActivityCount + maxActivityCountOffset) {
38676559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov            mAdapter.setShowFooterView(true);
3871c07e22c364732779b33c72bdc0e18c4bda0f7efSvetoslav Ganov            mAdapter.setMaxActivityCount(maxActivityCount - 1);
38851ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        } else {
38976559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov            mAdapter.setShowFooterView(false);
3901c07e22c364732779b33c72bdc0e18c4bda0f7efSvetoslav Ganov            mAdapter.setMaxActivityCount(maxActivityCount);
39151ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        }
39251ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
39376559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov        ListPopupWindow popupWindow = getListPopupWindow();
39476559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov        if (!popupWindow.isShowing()) {
395efab4e7f59835cb2ea9fdc42cc8fd9ea3771d261Svetoslav Ganov            if (mIsSelectingDefaultActivity || !defaultActivityButtonShown) {
396efab4e7f59835cb2ea9fdc42cc8fd9ea3771d261Svetoslav Ganov                mAdapter.setShowDefaultActivity(true, defaultActivityButtonShown);
39776559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov            } else {
398efab4e7f59835cb2ea9fdc42cc8fd9ea3771d261Svetoslav Ganov                mAdapter.setShowDefaultActivity(false, false);
39951ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            }
400414051b8b1e31b69ca622d68f391245f1989500bSvetoslav Ganov            final int contentWidth = Math.min(mAdapter.measureContentWidth(), mListPopupMaxWidth);
401414051b8b1e31b69ca622d68f391245f1989500bSvetoslav Ganov            popupWindow.setContentWidth(contentWidth);
40276559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov            popupWindow.show();
403823f074a73cfc23c40a7b576c71daa096ee9ed6aAdam Powell            if (mProvider != null) {
404823f074a73cfc23c40a7b576c71daa096ee9ed6aAdam Powell                mProvider.subUiVisibilityChanged(true);
405823f074a73cfc23c40a7b576c71daa096ee9ed6aAdam Powell            }
40670853772bd119339244a4fc8e020ad78495228beSvetoslav Ganov            popupWindow.getListView().setContentDescription(mContext.getString(
40770853772bd119339244a4fc8e020ad78495228beSvetoslav Ganov                    R.string.activitychooserview_choose_application));
408e471a4e0f720c1ea89025cd79ffca88daffcfde7sergeyv            popupWindow.getListView().setSelector(new ColorDrawable(Color.TRANSPARENT));
40951ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        }
41051ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    }
41151ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
41251ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    /**
41351ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     * Dismisses the popup window with activities.
41451ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     *
41551ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     * @return True if dismissed, false if already dismissed.
41651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     */
41751ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    public boolean dismissPopup() {
41876559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov        if (isShowingPopup()) {
41951ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            getListPopupWindow().dismiss();
4208c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov            ViewTreeObserver viewTreeObserver = getViewTreeObserver();
4218c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov            if (viewTreeObserver.isAlive()) {
422aa47a6b35a209812212fcd4ed7b600557ab66f0aSvetoslav Ganov                viewTreeObserver.removeOnGlobalLayoutListener(mOnGlobalLayoutListener);
4238c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov            }
42451ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        }
42551ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        return true;
42651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    }
42751ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
42851ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    /**
42951ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     * Gets whether the popup window with activities is shown.
43051ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     *
43151ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     * @return True if the popup is shown.
43251ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     */
43351ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    public boolean isShowingPopup() {
43476559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov        return getListPopupWindow().isShowing();
43551ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    }
43651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
43751ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    @Override
43851ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    protected void onAttachedToWindow() {
43951ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        super.onAttachedToWindow();
44051ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        ActivityChooserModel dataModel = mAdapter.getDataModel();
441b9f286e1a31bfc13e9c0e9635294742d558014c6Svetoslav Ganov        if (dataModel != null) {
44276559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov            dataModel.registerObserver(mModelDataSetOberver);
44351ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        }
44451ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        mIsAttachedToWindow = true;
44551ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    }
44651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
44751ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    @Override
44851ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    protected void onDetachedFromWindow() {
44951ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        super.onDetachedFromWindow();
45051ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        ActivityChooserModel dataModel = mAdapter.getDataModel();
451b9f286e1a31bfc13e9c0e9635294742d558014c6Svetoslav Ganov        if (dataModel != null) {
45276559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov            dataModel.unregisterObserver(mModelDataSetOberver);
45351ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        }
4548c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov        ViewTreeObserver viewTreeObserver = getViewTreeObserver();
4558c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov        if (viewTreeObserver.isAlive()) {
456aa47a6b35a209812212fcd4ed7b600557ab66f0aSvetoslav Ganov            viewTreeObserver.removeOnGlobalLayoutListener(mOnGlobalLayoutListener);
4578c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov        }
458748ee2e82a6f7a3adbbb522d45001e6dcb52b947Svetoslav Ganov        if (isShowingPopup()) {
459748ee2e82a6f7a3adbbb522d45001e6dcb52b947Svetoslav Ganov            dismissPopup();
460748ee2e82a6f7a3adbbb522d45001e6dcb52b947Svetoslav Ganov        }
46151ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        mIsAttachedToWindow = false;
46251ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    }
46351ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
46451ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    @Override
46551ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
466f2e754002166b8126e6faf8c494da5835432d572Svetoslav Ganov        View child = mActivityChooserContent;
467f2e754002166b8126e6faf8c494da5835432d572Svetoslav Ganov        // If the default action is not visible we want to be as tall as the
468f2e754002166b8126e6faf8c494da5835432d572Svetoslav Ganov        // ActionBar so if this widget is used in the latter it will look as
469f2e754002166b8126e6faf8c494da5835432d572Svetoslav Ganov        // a normal action button.
470f2e754002166b8126e6faf8c494da5835432d572Svetoslav Ganov        if (mDefaultActivityButton.getVisibility() != VISIBLE) {
471f2e754002166b8126e6faf8c494da5835432d572Svetoslav Ganov            heightMeasureSpec = MeasureSpec.makeMeasureSpec(MeasureSpec.getSize(heightMeasureSpec),
472f2e754002166b8126e6faf8c494da5835432d572Svetoslav Ganov                    MeasureSpec.EXACTLY);
473f2e754002166b8126e6faf8c494da5835432d572Svetoslav Ganov        }
474f2e754002166b8126e6faf8c494da5835432d572Svetoslav Ganov        measureChild(child, widthMeasureSpec, heightMeasureSpec);
475f2e754002166b8126e6faf8c494da5835432d572Svetoslav Ganov        setMeasuredDimension(child.getMeasuredWidth(), child.getMeasuredHeight());
47651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    }
47751ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
47851ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    @Override
47951ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
48076559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov        mActivityChooserContent.layout(0, 0, right - left, bottom - top);
481748ee2e82a6f7a3adbbb522d45001e6dcb52b947Svetoslav Ganov        if (!isShowingPopup()) {
48276559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov            dismissPopup();
48351ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        }
48451ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    }
48551ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
48651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    public ActivityChooserModel getDataModel() {
48751ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        return mAdapter.getDataModel();
48851ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    }
48951ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
49051ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    /**
49151ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     * Sets a listener to receive a callback when the popup is dismissed.
49251ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     *
49351ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     * @param listener The listener to be notified.
49451ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     */
49551ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    public void setOnDismissListener(PopupWindow.OnDismissListener listener) {
49651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        mOnDismissListener = listener;
49751ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    }
49851ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
49951ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    /**
50051ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     * Sets the initial count of items shown in the activities popup
50151ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     * i.e. the items before the popup is expanded. This is an upper
50251ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     * bound since it is not guaranteed that such number of intent
50351ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     * handlers exist.
50451ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     *
50551ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     * @param itemCount The initial popup item count.
50651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     */
50751ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    public void setInitialActivityCount(int itemCount) {
50851ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        mInitialActivityCount = itemCount;
50951ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    }
51051ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
51151ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    /**
51270853772bd119339244a4fc8e020ad78495228beSvetoslav Ganov     * Sets a content description of the default action button. This
51370853772bd119339244a4fc8e020ad78495228beSvetoslav Ganov     * resource should be a string taking one formatting argument and
51470853772bd119339244a4fc8e020ad78495228beSvetoslav Ganov     * will be used for formatting the content description of the button
51570853772bd119339244a4fc8e020ad78495228beSvetoslav Ganov     * dynamically as the default target changes. For example, a resource
51670853772bd119339244a4fc8e020ad78495228beSvetoslav Ganov     * pointing to the string "share with %1$s" will result in a content
51770853772bd119339244a4fc8e020ad78495228beSvetoslav Ganov     * description "share with Bluetooth" for the Bluetooth activity.
51870853772bd119339244a4fc8e020ad78495228beSvetoslav Ganov     *
51970853772bd119339244a4fc8e020ad78495228beSvetoslav Ganov     * @param resourceId The resource id.
52070853772bd119339244a4fc8e020ad78495228beSvetoslav Ganov     */
5217b9c912f536925ac6ec43935d6e97506851b33d6Tor Norbye    public void setDefaultActionButtonContentDescription(@StringRes int resourceId) {
52270853772bd119339244a4fc8e020ad78495228beSvetoslav Ganov        mDefaultActionButtonContentDescription = resourceId;
52370853772bd119339244a4fc8e020ad78495228beSvetoslav Ganov    }
52470853772bd119339244a4fc8e020ad78495228beSvetoslav Ganov
52570853772bd119339244a4fc8e020ad78495228beSvetoslav Ganov    /**
52651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     * Gets the list popup window which is lazily initialized.
52751ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     *
52851ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     * @return The popup.
52951ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     */
53051ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    private ListPopupWindow getListPopupWindow() {
53151ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        if (mListPopupWindow == null) {
53251ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            mListPopupWindow = new ListPopupWindow(getContext());
53351ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            mListPopupWindow.setAdapter(mAdapter);
53451ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            mListPopupWindow.setAnchorView(ActivityChooserView.this);
53551ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            mListPopupWindow.setModal(true);
53651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            mListPopupWindow.setOnItemClickListener(mCallbacks);
53751ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            mListPopupWindow.setOnDismissListener(mCallbacks);
53851ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        }
53951ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        return mListPopupWindow;
54051ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    }
54151ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
54251ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    /**
54351ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     * Updates the buttons state.
54451ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     */
545f2e754002166b8126e6faf8c494da5835432d572Svetoslav Ganov    private void updateAppearance() {
546f2e754002166b8126e6faf8c494da5835432d572Svetoslav Ganov        // Expand overflow button.
547f2e754002166b8126e6faf8c494da5835432d572Svetoslav Ganov        if (mAdapter.getCount() > 0) {
548f2e754002166b8126e6faf8c494da5835432d572Svetoslav Ganov            mExpandActivityOverflowButton.setEnabled(true);
549f2e754002166b8126e6faf8c494da5835432d572Svetoslav Ganov        } else {
550f2e754002166b8126e6faf8c494da5835432d572Svetoslav Ganov            mExpandActivityOverflowButton.setEnabled(false);
551f2e754002166b8126e6faf8c494da5835432d572Svetoslav Ganov        }
552f2e754002166b8126e6faf8c494da5835432d572Svetoslav Ganov        // Default activity button.
55351ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        final int activityCount = mAdapter.getActivityCount();
554f2e754002166b8126e6faf8c494da5835432d572Svetoslav Ganov        final int historySize = mAdapter.getHistorySize();
5555a1195fd5faf40428bc98e5bc24d09edbf3c3b6cfredc        if (activityCount==1 || activityCount > 1 && historySize > 0) {
556bfbbcf5677d4a5f8c8f938e4c8a8f86d3c7d74c2Svetoslav Ganov            mDefaultActivityButton.setVisibility(VISIBLE);
55751ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            ResolveInfo activity = mAdapter.getDefaultActivity();
55851ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            PackageManager packageManager = mContext.getPackageManager();
559bfbbcf5677d4a5f8c8f938e4c8a8f86d3c7d74c2Svetoslav Ganov            mDefaultActivityButtonImage.setImageDrawable(activity.loadIcon(packageManager));
56070853772bd119339244a4fc8e020ad78495228beSvetoslav Ganov            if (mDefaultActionButtonContentDescription != 0) {
56170853772bd119339244a4fc8e020ad78495228beSvetoslav Ganov                CharSequence label = activity.loadLabel(packageManager);
56270853772bd119339244a4fc8e020ad78495228beSvetoslav Ganov                String contentDescription = mContext.getString(
56370853772bd119339244a4fc8e020ad78495228beSvetoslav Ganov                        mDefaultActionButtonContentDescription, label);
56470853772bd119339244a4fc8e020ad78495228beSvetoslav Ganov                mDefaultActivityButton.setContentDescription(contentDescription);
56570853772bd119339244a4fc8e020ad78495228beSvetoslav Ganov            }
56651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        } else {
567f2e754002166b8126e6faf8c494da5835432d572Svetoslav Ganov            mDefaultActivityButton.setVisibility(View.GONE);
568f2e754002166b8126e6faf8c494da5835432d572Svetoslav Ganov        }
569f2e754002166b8126e6faf8c494da5835432d572Svetoslav Ganov        // Activity chooser content.
570f2e754002166b8126e6faf8c494da5835432d572Svetoslav Ganov        if (mDefaultActivityButton.getVisibility() == VISIBLE) {
571baeabb65e1e818c6679036774933f40e8540b293Svetoslav            mActivityChooserContent.setBackground(mActivityChooserContentBackground);
572f2e754002166b8126e6faf8c494da5835432d572Svetoslav Ganov        } else {
573baeabb65e1e818c6679036774933f40e8540b293Svetoslav            mActivityChooserContent.setBackground(null);
57451ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        }
57551ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    }
57651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
57751ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    /**
57851ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     * Interface implementation to avoid publishing them in the APIs.
57951ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     */
58051ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    private class Callbacks implements AdapterView.OnItemClickListener,
58176559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov            View.OnClickListener, View.OnLongClickListener, PopupWindow.OnDismissListener {
58251ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
58351ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        // AdapterView#OnItemClickListener
58451ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
58551ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            ActivityChooserViewAdapter adapter = (ActivityChooserViewAdapter) parent.getAdapter();
58651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            final int itemViewType = adapter.getItemViewType(position);
58751ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            switch (itemViewType) {
58851ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov                case ActivityChooserViewAdapter.ITEM_VIEW_TYPE_FOOTER: {
58951ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov                    showPopupUnchecked(ActivityChooserViewAdapter.MAX_ACTIVITY_COUNT_UNLIMITED);
59051ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov                } break;
59151ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov                case ActivityChooserViewAdapter.ITEM_VIEW_TYPE_ACTIVITY: {
59251ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov                    dismissPopup();
59351ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov                    if (mIsSelectingDefaultActivity) {
59476559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov                        // The item at position zero is the default already.
59576559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov                        if (position > 0) {
59676559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov                            mAdapter.getDataModel().setDefaultActivity(position);
59776559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov                        }
59851ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov                    } else {
599efab4e7f59835cb2ea9fdc42cc8fd9ea3771d261Svetoslav Ganov                        // If the default target is not shown in the list, the first
600efab4e7f59835cb2ea9fdc42cc8fd9ea3771d261Svetoslav Ganov                        // item in the model is default action => adjust index
601efab4e7f59835cb2ea9fdc42cc8fd9ea3771d261Svetoslav Ganov                        position = mAdapter.getShowDefaultActivity() ? position : position + 1;
602efab4e7f59835cb2ea9fdc42cc8fd9ea3771d261Svetoslav Ganov                        Intent launchIntent = mAdapter.getDataModel().chooseActivity(position);
6038c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov                        if (launchIntent != null) {
604314419ccb9daa215c5148f59e5b60c696ef51385Adam Powell                            launchIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
605baeabb65e1e818c6679036774933f40e8540b293Svetoslav                            ResolveInfo resolveInfo = mAdapter.getDataModel().getActivity(position);
606baeabb65e1e818c6679036774933f40e8540b293Svetoslav                            startActivity(launchIntent, resolveInfo);
6078c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov                        }
60851ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov                    }
60951ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov                } break;
61051ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov                default:
61151ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov                    throw new IllegalArgumentException();
61251ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            }
61351ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        }
61451ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
61551ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        // View.OnClickListener
61651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        public void onClick(View view) {
617bfbbcf5677d4a5f8c8f938e4c8a8f86d3c7d74c2Svetoslav Ganov            if (view == mDefaultActivityButton) {
61851ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov                dismissPopup();
61951ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov                ResolveInfo defaultActivity = mAdapter.getDefaultActivity();
62051ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov                final int index = mAdapter.getDataModel().getActivityIndex(defaultActivity);
62151ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov                Intent launchIntent = mAdapter.getDataModel().chooseActivity(index);
6228c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov                if (launchIntent != null) {
623314419ccb9daa215c5148f59e5b60c696ef51385Adam Powell                    launchIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
624baeabb65e1e818c6679036774933f40e8540b293Svetoslav                    startActivity(launchIntent, defaultActivity);
6258c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov                }
62651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            } else if (view == mExpandActivityOverflowButton) {
62751ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov                mIsSelectingDefaultActivity = false;
62851ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov                showPopupUnchecked(mInitialActivityCount);
62951ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            } else {
63051ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov                throw new IllegalArgumentException();
63151ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            }
63251ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        }
63351ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
63451ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        // OnLongClickListener#onLongClick
63551ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        @Override
63651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        public boolean onLongClick(View view) {
637b9f286e1a31bfc13e9c0e9635294742d558014c6Svetoslav Ganov            if (view == mDefaultActivityButton) {
63851ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov                if (mAdapter.getCount() > 0) {
63951ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov                    mIsSelectingDefaultActivity = true;
64051ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov                    showPopupUnchecked(mInitialActivityCount);
64151ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov                }
64251ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            } else {
64351ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov                throw new IllegalArgumentException();
64451ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            }
64551ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            return true;
64651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        }
64751ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
64851ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        // PopUpWindow.OnDismissListener#onDismiss
64951ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        public void onDismiss() {
65051ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            notifyOnDismissListener();
651823f074a73cfc23c40a7b576c71daa096ee9ed6aAdam Powell            if (mProvider != null) {
652823f074a73cfc23c40a7b576c71daa096ee9ed6aAdam Powell                mProvider.subUiVisibilityChanged(false);
653823f074a73cfc23c40a7b576c71daa096ee9ed6aAdam Powell            }
65451ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        }
65551ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
65651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        private void notifyOnDismissListener() {
65751ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            if (mOnDismissListener != null) {
65851ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov                mOnDismissListener.onDismiss();
65951ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            }
66051ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        }
661baeabb65e1e818c6679036774933f40e8540b293Svetoslav
662baeabb65e1e818c6679036774933f40e8540b293Svetoslav        private void startActivity(Intent intent, ResolveInfo resolveInfo) {
663baeabb65e1e818c6679036774933f40e8540b293Svetoslav            try {
664baeabb65e1e818c6679036774933f40e8540b293Svetoslav                mContext.startActivity(intent);
665baeabb65e1e818c6679036774933f40e8540b293Svetoslav            } catch (RuntimeException re) {
666baeabb65e1e818c6679036774933f40e8540b293Svetoslav                CharSequence appLabel = resolveInfo.loadLabel(mContext.getPackageManager());
667baeabb65e1e818c6679036774933f40e8540b293Svetoslav                String message = mContext.getString(
668baeabb65e1e818c6679036774933f40e8540b293Svetoslav                        R.string.activitychooserview_choose_application_error, appLabel);
669baeabb65e1e818c6679036774933f40e8540b293Svetoslav                Log.e(LOG_TAG, message);
670baeabb65e1e818c6679036774933f40e8540b293Svetoslav                Toast.makeText(mContext, message, Toast.LENGTH_SHORT).show();
671baeabb65e1e818c6679036774933f40e8540b293Svetoslav            }
672baeabb65e1e818c6679036774933f40e8540b293Svetoslav        }
67351ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    }
67451ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
67551ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    /**
67651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     * Adapter for backing the list of activities shown in the popup.
67751ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     */
67851ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    private class ActivityChooserViewAdapter extends BaseAdapter {
67951ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
68051ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        public static final int MAX_ACTIVITY_COUNT_UNLIMITED = Integer.MAX_VALUE;
68151ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
68251ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        public static final int MAX_ACTIVITY_COUNT_DEFAULT = 4;
68351ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
68476559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov        private static final int ITEM_VIEW_TYPE_ACTIVITY = 0;
68551ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
68676559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov        private static final int ITEM_VIEW_TYPE_FOOTER = 1;
68751ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
68851ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        private static final int ITEM_VIEW_TYPE_COUNT = 3;
68951ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
69051ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        private ActivityChooserModel mDataModel;
69151ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
69251ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        private int mMaxActivityCount = MAX_ACTIVITY_COUNT_DEFAULT;
69351ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
69476559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov        private boolean mShowDefaultActivity;
69551ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
696efab4e7f59835cb2ea9fdc42cc8fd9ea3771d261Svetoslav Ganov        private boolean mHighlightDefaultActivity;
697efab4e7f59835cb2ea9fdc42cc8fd9ea3771d261Svetoslav Ganov
69876559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov        private boolean mShowFooterView;
69951ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
70051ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        public void setDataModel(ActivityChooserModel dataModel) {
70176559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov            ActivityChooserModel oldDataModel = mAdapter.getDataModel();
702b9f286e1a31bfc13e9c0e9635294742d558014c6Svetoslav Ganov            if (oldDataModel != null && isShown()) {
70376559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov                oldDataModel.unregisterObserver(mModelDataSetOberver);
70476559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov            }
70551ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            mDataModel = dataModel;
706b9f286e1a31bfc13e9c0e9635294742d558014c6Svetoslav Ganov            if (dataModel != null && isShown()) {
70776559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov                dataModel.registerObserver(mModelDataSetOberver);
70851ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            }
709b9f286e1a31bfc13e9c0e9635294742d558014c6Svetoslav Ganov            notifyDataSetChanged();
71051ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        }
71151ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
71251ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        @Override
71351ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        public int getItemViewType(int position) {
71476559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov            if (mShowFooterView && position == getCount() - 1) {
71551ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov                return ITEM_VIEW_TYPE_FOOTER;
71651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            } else {
71751ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov                return ITEM_VIEW_TYPE_ACTIVITY;
71851ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            }
71951ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        }
72051ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
72151ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        @Override
72251ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        public int getViewTypeCount() {
72351ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            return ITEM_VIEW_TYPE_COUNT;
72451ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        }
72551ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
72651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        public int getCount() {
72751ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            int count = 0;
72851ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            int activityCount = mDataModel.getActivityCount();
72976559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov            if (!mShowDefaultActivity && mDataModel.getDefaultActivity() != null) {
73051ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov                activityCount--;
73151ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            }
73251ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            count = Math.min(activityCount, mMaxActivityCount);
73376559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov            if (mShowFooterView) {
73451ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov                count++;
73551ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            }
73651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            return count;
73751ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        }
73851ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
73951ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        public Object getItem(int position) {
74051ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            final int itemViewType = getItemViewType(position);
74151ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            switch (itemViewType) {
74251ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov                case ITEM_VIEW_TYPE_FOOTER:
74376559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov                    return null;
74451ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov                case ITEM_VIEW_TYPE_ACTIVITY:
74576559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov                    if (!mShowDefaultActivity && mDataModel.getDefaultActivity() != null) {
74676559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov                        position++;
74751ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov                    }
74876559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov                    return mDataModel.getActivity(position);
74951ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov                default:
75051ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov                    throw new IllegalArgumentException();
75151ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            }
75251ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        }
75351ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
75451ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        public long getItemId(int position) {
75551ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            return position;
75651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        }
75751ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
75851ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        public View getView(int position, View convertView, ViewGroup parent) {
75951ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            final int itemViewType = getItemViewType(position);
76051ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            switch (itemViewType) {
76151ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov                case ITEM_VIEW_TYPE_FOOTER:
76276559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov                    if (convertView == null || convertView.getId() != ITEM_VIEW_TYPE_FOOTER) {
76376559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov                        convertView = LayoutInflater.from(getContext()).inflate(
76476559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov                                R.layout.activity_chooser_view_list_item, parent, false);
76576559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov                        convertView.setId(ITEM_VIEW_TYPE_FOOTER);
7668e1a72964517bfd01d8e650453ef41e22f770f21Alan Viverette                        TextView titleView = convertView.findViewById(R.id.title);
76776559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov                        titleView.setText(mContext.getString(
76876559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov                                R.string.activity_chooser_view_see_all));
76976559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov                    }
77076559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov                    return convertView;
77151ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov                case ITEM_VIEW_TYPE_ACTIVITY:
77251ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov                    if (convertView == null || convertView.getId() != R.id.list_item) {
77351ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov                        convertView = LayoutInflater.from(getContext()).inflate(
77451ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov                                R.layout.activity_chooser_view_list_item, parent, false);
77551ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov                    }
77651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov                    PackageManager packageManager = mContext.getPackageManager();
77751ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov                    // Set the icon
7788e1a72964517bfd01d8e650453ef41e22f770f21Alan Viverette                    ImageView iconView = convertView.findViewById(R.id.icon);
77951ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov                    ResolveInfo activity = (ResolveInfo) getItem(position);
780414051b8b1e31b69ca622d68f391245f1989500bSvetoslav Ganov                    iconView.setImageDrawable(activity.loadIcon(packageManager));
78151ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov                    // Set the title.
7828e1a72964517bfd01d8e650453ef41e22f770f21Alan Viverette                    TextView titleView = convertView.findViewById(R.id.title);
78351ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov                    titleView.setText(activity.loadLabel(packageManager));
78476559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov                    // Highlight the default.
785efab4e7f59835cb2ea9fdc42cc8fd9ea3771d261Svetoslav Ganov                    if (mShowDefaultActivity && position == 0 && mHighlightDefaultActivity) {
78676559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov                        convertView.setActivated(true);
78776559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov                    } else {
78876559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov                        convertView.setActivated(false);
78976559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov                    }
79051ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov                    return convertView;
79151ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov                default:
79251ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov                    throw new IllegalArgumentException();
79351ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            }
79451ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        }
79551ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
79651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        public int measureContentWidth() {
79776559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov            // The user may have specified some of the target not to be shown but we
79851ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            // want to measure all of them since after expansion they should fit.
79951ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            final int oldMaxActivityCount = mMaxActivityCount;
80051ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            mMaxActivityCount = MAX_ACTIVITY_COUNT_UNLIMITED;
80151ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
80251ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            int contentWidth = 0;
80351ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            View itemView = null;
80451ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
80551ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            final int widthMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
80651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            final int heightMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
80751ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            final int count = getCount();
80851ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
80951ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            for (int i = 0; i < count; i++) {
81051ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov                itemView = getView(i, itemView, null);
81151ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov                itemView.measure(widthMeasureSpec, heightMeasureSpec);
81251ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov                contentWidth = Math.max(contentWidth, itemView.getMeasuredWidth());
81351ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            }
81451ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
81551ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            mMaxActivityCount = oldMaxActivityCount;
81651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
81751ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            return contentWidth;
81851ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        }
81951ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
82051ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        public void setMaxActivityCount(int maxActivityCount) {
82151ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            if (mMaxActivityCount != maxActivityCount) {
82251ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov                mMaxActivityCount = maxActivityCount;
82351ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov                notifyDataSetChanged();
82451ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            }
82551ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        }
82651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
82751ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        public ResolveInfo getDefaultActivity() {
82876559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov            return mDataModel.getDefaultActivity();
82951ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        }
83051ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
83176559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov        public void setShowFooterView(boolean showFooterView) {
83276559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov            if (mShowFooterView != showFooterView) {
83376559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov                mShowFooterView = showFooterView;
83451ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov                notifyDataSetChanged();
83551ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            }
83651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        }
83751ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
83851ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        public int getActivityCount() {
83951ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            return mDataModel.getActivityCount();
84051ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        }
84151ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
842f2e754002166b8126e6faf8c494da5835432d572Svetoslav Ganov        public int getHistorySize() {
843f2e754002166b8126e6faf8c494da5835432d572Svetoslav Ganov            return mDataModel.getHistorySize();
844f2e754002166b8126e6faf8c494da5835432d572Svetoslav Ganov        }
845f2e754002166b8126e6faf8c494da5835432d572Svetoslav Ganov
84651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        public ActivityChooserModel getDataModel() {
84751ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            return mDataModel;
84851ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        }
84976559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov
850efab4e7f59835cb2ea9fdc42cc8fd9ea3771d261Svetoslav Ganov        public void setShowDefaultActivity(boolean showDefaultActivity,
851efab4e7f59835cb2ea9fdc42cc8fd9ea3771d261Svetoslav Ganov                boolean highlightDefaultActivity) {
852efab4e7f59835cb2ea9fdc42cc8fd9ea3771d261Svetoslav Ganov            if (mShowDefaultActivity != showDefaultActivity
853efab4e7f59835cb2ea9fdc42cc8fd9ea3771d261Svetoslav Ganov                    || mHighlightDefaultActivity != highlightDefaultActivity) {
85476559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov                mShowDefaultActivity = showDefaultActivity;
855efab4e7f59835cb2ea9fdc42cc8fd9ea3771d261Svetoslav Ganov                mHighlightDefaultActivity = highlightDefaultActivity;
85676559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov                notifyDataSetChanged();
85776559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov            }
85876559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov        }
859efab4e7f59835cb2ea9fdc42cc8fd9ea3771d261Svetoslav Ganov
860efab4e7f59835cb2ea9fdc42cc8fd9ea3771d261Svetoslav Ganov        public boolean getShowDefaultActivity() {
861efab4e7f59835cb2ea9fdc42cc8fd9ea3771d261Svetoslav Ganov            return mShowDefaultActivity;
862efab4e7f59835cb2ea9fdc42cc8fd9ea3771d261Svetoslav Ganov        }
86351ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    }
86451ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov}
865