ActivityChooserView.java revision 76559a65ad9d644f10beacf8895ceb217fdd0aeb
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
1951ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganovimport android.content.Context;
2051ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganovimport android.content.Intent;
2151ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganovimport android.content.pm.PackageManager;
2251ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganovimport android.content.pm.ResolveInfo;
2351ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganovimport android.content.res.TypedArray;
2451ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganovimport android.database.DataSetObserver;
2551ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganovimport android.graphics.Canvas;
2651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganovimport android.graphics.drawable.Drawable;
2751ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganovimport android.util.AttributeSet;
2851ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganovimport android.view.LayoutInflater;
2951ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganovimport android.view.View;
3051ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganovimport android.view.ViewGroup;
3176559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganovimport android.widget.ActivityChooserModel;
3251ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganovimport android.widget.ActivityChooserModel.ActivityChooserModelClient;
3376559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganovimport android.widget.AdapterView;
3476559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganovimport android.widget.BaseAdapter;
3576559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganovimport android.widget.ImageButton;
3676559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganovimport android.widget.ImageView;
3776559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganovimport android.widget.LinearLayout;
3876559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganovimport android.widget.ListPopupWindow;
3976559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganovimport android.widget.PopupWindow;
4076559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganovimport android.widget.TextView;
4151ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
4251ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganovimport com.android.internal.R;
4351ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
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
6951ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    /**
7051ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     * An adapter for displaying the activities in an {@link AdapterView}.
7151ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     */
7251ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    private final ActivityChooserViewAdapter mAdapter;
7351ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
7451ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    /**
7551ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     * Implementation of various interfaces to avoid publishing them in the APIs.
7651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     */
7751ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    private final Callbacks mCallbacks;
7851ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
7951ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    /**
8051ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     * The content of this view.
8151ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     */
8251ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    private final LinearLayout mActivityChooserContent;
8351ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
8451ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    /**
8551ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     * The expand activities action button;
8651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     */
8751ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    private final ImageButton mExpandActivityOverflowButton;
8851ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
8951ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    /**
9051ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     * The default activities action button;
9151ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     */
9251ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    private final ImageButton mDefaultActionButton;
9351ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
9451ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    /**
9576559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov     * Observer for the model data.
9651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     */
9776559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov    private final DataSetObserver mModelDataSetOberver = new DataSetObserver() {
9851ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
9976559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov        @Override
10076559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov        public void onChanged() {
10176559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov            super.onChanged();
10276559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov            mAdapter.notifyDataSetChanged();
10376559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov        }
10476559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov        @Override
10576559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov        public void onInvalidated() {
10676559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov            super.onInvalidated();
10776559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov            mAdapter.notifyDataSetInvalidated();
10876559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov        }
10976559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov    };
11051ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
11151ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    /**
11251ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     * Popup window for showing the activity overflow list.
11351ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     */
11451ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    private ListPopupWindow mListPopupWindow;
11551ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
11651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    /**
11751ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     * Listener for the dismissal of the popup/alert.
11851ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     */
11951ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    private PopupWindow.OnDismissListener mOnDismissListener;
12051ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
12151ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    /**
12251ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     * Flag whether a default activity currently being selected.
12351ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     */
12451ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    private boolean mIsSelectingDefaultActivity;
12551ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
12651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    /**
12751ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     * The count of activities in the popup.
12851ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     */
12951ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    private int mInitialActivityCount = ActivityChooserViewAdapter.MAX_ACTIVITY_COUNT_DEFAULT;
13051ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
13151ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    /**
13251ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     * Flag whether this view is attached to a window.
13351ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     */
13451ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    private boolean mIsAttachedToWindow;
13551ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
13651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    /**
13751ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     * Create a new instance.
13851ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     *
13951ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     * @param context The application environment.
14051ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     */
14151ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    public ActivityChooserView(Context context) {
14251ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        this(context, null);
14351ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    }
14451ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
14551ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    /**
14651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     * Create a new instance.
14751ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     *
14851ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     * @param context The application environment.
14951ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     * @param attrs A collection of attributes.
15051ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     */
15151ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    public ActivityChooserView(Context context, AttributeSet attrs) {
15251ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        this(context, attrs, R.attr.actionButtonStyle);
15351ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    }
15451ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
15551ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    /**
15651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     * Create a new instance.
15751ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     *
15851ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     * @param context The application environment.
15951ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     * @param attrs A collection of attributes.
16051ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     * @param defStyle The default style to apply to this view.
16151ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     */
16251ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    public ActivityChooserView(Context context, AttributeSet attrs, int defStyle) {
16351ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        super(context, attrs, defStyle);
16451ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
16551ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        TypedArray attributesArray = context.obtainStyledAttributes(attrs,
16651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov                R.styleable.ActivityChooserView, defStyle, 0);
16751ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
16851ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        mInitialActivityCount = attributesArray.getInt(
16951ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov                R.styleable.ActivityChooserView_initialActivityCount,
17051ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov                ActivityChooserViewAdapter.MAX_ACTIVITY_COUNT_DEFAULT);
17151ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
17251ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        Drawable expandActivityOverflowButtonDrawable = attributesArray.getDrawable(
17351ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov                R.styleable.ActivityChooserView_expandActivityOverflowButtonDrawable);
17451ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
17576559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov        LayoutInflater inflater = LayoutInflater.from(mContext);
17651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        inflater.inflate(R.layout.activity_chooser_view, this, true);
17751ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
17851ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        mCallbacks = new Callbacks();
17951ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
18051ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        mActivityChooserContent = (LinearLayout) findViewById(R.id.activity_chooser_view_content);
18151ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
18251ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        mDefaultActionButton = (ImageButton) findViewById(R.id.default_activity_button);
18351ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        mDefaultActionButton.setOnClickListener(mCallbacks);
18451ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        mDefaultActionButton.setOnLongClickListener(mCallbacks);
18551ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
18651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        mExpandActivityOverflowButton = (ImageButton) findViewById(R.id.expand_activities_button);
18751ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        mExpandActivityOverflowButton.setOnClickListener(mCallbacks);
18851ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        mExpandActivityOverflowButton.setBackgroundDrawable(expandActivityOverflowButtonDrawable);
18951ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
19051ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        mAdapter = new ActivityChooserViewAdapter();
19151ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        mAdapter.registerDataSetObserver(new DataSetObserver() {
19251ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            @Override
19351ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            public void onChanged() {
19451ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov                super.onChanged();
19551ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov                updateButtons();
19651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            }
19751ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        });
19851ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    }
19951ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
20051ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    /**
20151ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     * {@inheritDoc}
20251ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     */
20351ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    public void setActivityChooserModel(ActivityChooserModel dataModel) {
20451ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        mAdapter.setDataModel(dataModel);
20551ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        if (isShowingPopup()) {
20651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            dismissPopup();
20751ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            showPopup();
20851ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        }
20951ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    }
21051ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
21151ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    /**
21251ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     * Sets the background for the button that expands the activity
21351ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     * overflow list.
21451ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     *
21551ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     * <strong>Note:</strong> Clients would like to set this drawable
21651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     * as a clue about the action the chosen activity will perform. For
21751ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     * example, if share activity is to be chosen the drawable should
21851ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     * give a clue that sharing is to be performed.
21951ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     *
22051ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     * @param drawable The drawable.
22151ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     */
22251ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    public void setExpandActivityOverflowButtonDrawable(Drawable drawable) {
22351ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        mExpandActivityOverflowButton.setBackgroundDrawable(drawable);
22451ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    }
22551ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
22651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    /**
22751ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     * Shows the popup window with activities.
22851ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     *
22951ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     * @return True if the popup was shown, false if already showing.
23051ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     */
23151ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    public boolean showPopup() {
23276559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov        if (isShowingPopup() || !mIsAttachedToWindow) {
23351ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            return false;
23451ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        }
23551ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        mIsSelectingDefaultActivity = false;
23651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        showPopupUnchecked(mInitialActivityCount);
23751ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        return true;
23851ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    }
23951ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
24051ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    /**
24151ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     * Shows the popup no matter if it was already showing.
24251ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     *
24351ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     * @param maxActivityCount The max number of activities to display.
24451ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     */
24551ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    private void showPopupUnchecked(int maxActivityCount) {
24676559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov        if (mAdapter.getDataModel() == null) {
24776559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov            throw new IllegalStateException("No data model. Did you call #setDataModel?");
24851ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        }
24951ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
25076559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov        mAdapter.setMaxActivityCount(maxActivityCount);
25176559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov
25276559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov        final int activityCount = mAdapter.getActivityCount();
25376559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov        if (maxActivityCount != ActivityChooserViewAdapter.MAX_ACTIVITY_COUNT_UNLIMITED
25476559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov                && activityCount > maxActivityCount + 1) {
25576559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov            mAdapter.setShowFooterView(true);
25651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        } else {
25776559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov            mAdapter.setShowFooterView(false);
25851ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        }
25951ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
26076559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov        ListPopupWindow popupWindow = getListPopupWindow();
26176559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov        if (!popupWindow.isShowing()) {
26276559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov            if (mIsSelectingDefaultActivity) {
26376559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov                mAdapter.setShowDefaultActivity(true);
26476559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov            } else {
26576559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov                mAdapter.setShowDefaultActivity(false);
26651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            }
26776559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov            popupWindow.setContentWidth(mAdapter.measureContentWidth());
26876559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov            popupWindow.show();
26951ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        }
27051ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    }
27151ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
27251ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    /**
27351ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     * Dismisses the popup window with activities.
27451ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     *
27551ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     * @return True if dismissed, false if already dismissed.
27651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     */
27751ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    public boolean dismissPopup() {
27876559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov        if (isShowingPopup()) {
27951ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            getListPopupWindow().dismiss();
28051ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        }
28151ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        return true;
28251ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    }
28351ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
28451ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    /**
28551ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     * Gets whether the popup window with activities is shown.
28651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     *
28751ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     * @return True if the popup is shown.
28851ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     */
28951ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    public boolean isShowingPopup() {
29076559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov        return getListPopupWindow().isShowing();
29151ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    }
29251ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
29351ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    @Override
29451ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    protected void onAttachedToWindow() {
29551ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        super.onAttachedToWindow();
29651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        ActivityChooserModel dataModel = mAdapter.getDataModel();
29751ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        if (dataModel != null) {
29876559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov            dataModel.registerObserver(mModelDataSetOberver);
29951ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            dataModel.readHistoricalData();
30051ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        }
30151ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        mIsAttachedToWindow = true;
30251ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    }
30351ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
30451ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    @Override
30551ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    protected void onDetachedFromWindow() {
30651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        super.onDetachedFromWindow();
30751ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        ActivityChooserModel dataModel = mAdapter.getDataModel();
30851ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        if (dataModel != null) {
30976559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov            dataModel.unregisterObserver(mModelDataSetOberver);
31051ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            dataModel.persistHistoricalData();
31151ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        }
31251ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        mIsAttachedToWindow = false;
31351ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    }
31451ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
31551ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    @Override
31651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
31751ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        mActivityChooserContent.measure(widthMeasureSpec, heightMeasureSpec);
31851ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        setMeasuredDimension(mActivityChooserContent.getMeasuredWidth(),
31951ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov                mActivityChooserContent.getMeasuredHeight());
32051ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    }
32151ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
32251ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    @Override
32351ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
32476559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov        mActivityChooserContent.layout(0, 0, right - left, bottom - top);
32576559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov        if (getListPopupWindow().isShowing()) {
32676559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov            showPopupUnchecked(mAdapter.getMaxActivityCount());
32776559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov        } else {
32876559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov            dismissPopup();
32951ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        }
33051ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    }
33151ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
33251ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    @Override
33351ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    protected void onDraw(Canvas canvas) {
33451ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        mActivityChooserContent.onDraw(canvas);
33551ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    }
33651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
33751ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    public ActivityChooserModel getDataModel() {
33851ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        return mAdapter.getDataModel();
33951ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    }
34051ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
34151ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    /**
34251ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     * Sets a listener to receive a callback when the popup is dismissed.
34351ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     *
34451ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     * @param listener The listener to be notified.
34551ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     */
34651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    public void setOnDismissListener(PopupWindow.OnDismissListener listener) {
34751ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        mOnDismissListener = listener;
34851ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    }
34951ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
35051ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    /**
35151ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     * Sets the initial count of items shown in the activities popup
35251ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     * i.e. the items before the popup is expanded. This is an upper
35351ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     * bound since it is not guaranteed that such number of intent
35451ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     * handlers exist.
35551ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     *
35651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     * @param itemCount The initial popup item count.
35751ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     */
35851ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    public void setInitialActivityCount(int itemCount) {
35951ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        mInitialActivityCount = itemCount;
36051ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    }
36151ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
36251ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    /**
36351ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     * Gets the list popup window which is lazily initialized.
36451ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     *
36551ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     * @return The popup.
36651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     */
36751ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    private ListPopupWindow getListPopupWindow() {
36851ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        if (mListPopupWindow == null) {
36951ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            mListPopupWindow = new ListPopupWindow(getContext());
37051ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            mListPopupWindow.setAdapter(mAdapter);
37151ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            mListPopupWindow.setAnchorView(ActivityChooserView.this);
37251ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            mListPopupWindow.setModal(true);
37351ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            mListPopupWindow.setOnItemClickListener(mCallbacks);
37451ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            mListPopupWindow.setOnDismissListener(mCallbacks);
37551ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        }
37651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        return mListPopupWindow;
37751ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    }
37851ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
37951ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    /**
38051ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     * Updates the buttons state.
38151ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     */
38251ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    private void updateButtons() {
38351ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        final int activityCount = mAdapter.getActivityCount();
38451ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        if (activityCount > 0) {
38551ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            mDefaultActionButton.setVisibility(VISIBLE);
38651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            if (mAdapter.getCount() > 0) {
38751ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov                mExpandActivityOverflowButton.setEnabled(true);
38851ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            } else {
38951ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov                mExpandActivityOverflowButton.setEnabled(false);
39051ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            }
39151ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            ResolveInfo activity = mAdapter.getDefaultActivity();
39251ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            PackageManager packageManager = mContext.getPackageManager();
39351ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            mDefaultActionButton.setBackgroundDrawable(activity.loadIcon(packageManager));
39451ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        } else {
39551ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            mDefaultActionButton.setVisibility(View.INVISIBLE);
39651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            mExpandActivityOverflowButton.setEnabled(false);
39751ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        }
39851ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    }
39951ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
40051ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    /**
40151ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     * Interface implementation to avoid publishing them in the APIs.
40251ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     */
40351ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    private class Callbacks implements AdapterView.OnItemClickListener,
40476559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov            View.OnClickListener, View.OnLongClickListener, PopupWindow.OnDismissListener {
40551ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
40651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        // AdapterView#OnItemClickListener
40751ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
40851ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            ActivityChooserViewAdapter adapter = (ActivityChooserViewAdapter) parent.getAdapter();
40951ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            final int itemViewType = adapter.getItemViewType(position);
41051ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            switch (itemViewType) {
41151ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov                case ActivityChooserViewAdapter.ITEM_VIEW_TYPE_FOOTER: {
41251ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov                    showPopupUnchecked(ActivityChooserViewAdapter.MAX_ACTIVITY_COUNT_UNLIMITED);
41351ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov                } break;
41451ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov                case ActivityChooserViewAdapter.ITEM_VIEW_TYPE_ACTIVITY: {
41551ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov                    dismissPopup();
41651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov                    if (mIsSelectingDefaultActivity) {
41776559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov                        // The item at position zero is the default already.
41876559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov                        if (position > 0) {
41976559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov                            mAdapter.getDataModel().setDefaultActivity(position);
42076559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov                        }
42151ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov                    } else {
42251ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov                        // The first item in the model is default action => adjust index
42351ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov                        Intent launchIntent = mAdapter.getDataModel().chooseActivity(position + 1);
42451ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov                        mContext.startActivity(launchIntent);
42551ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov                    }
42651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov                } break;
42751ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov                default:
42851ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov                    throw new IllegalArgumentException();
42951ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            }
43051ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        }
43151ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
43251ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        // View.OnClickListener
43351ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        public void onClick(View view) {
43451ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            if (view == mDefaultActionButton) {
43551ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov                dismissPopup();
43651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov                ResolveInfo defaultActivity = mAdapter.getDefaultActivity();
43751ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov                final int index = mAdapter.getDataModel().getActivityIndex(defaultActivity);
43851ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov                Intent launchIntent = mAdapter.getDataModel().chooseActivity(index);
43951ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov                mContext.startActivity(launchIntent);
44051ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            } else if (view == mExpandActivityOverflowButton) {
44151ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov                mIsSelectingDefaultActivity = false;
44251ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov                showPopupUnchecked(mInitialActivityCount);
44351ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            } else {
44451ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov                throw new IllegalArgumentException();
44551ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            }
44651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        }
44751ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
44851ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        // OnLongClickListener#onLongClick
44951ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        @Override
45051ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        public boolean onLongClick(View view) {
45151ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            if (view == mDefaultActionButton) {
45251ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov                if (mAdapter.getCount() > 0) {
45351ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov                    mIsSelectingDefaultActivity = true;
45451ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov                    showPopupUnchecked(mInitialActivityCount);
45551ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov                }
45651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            } else {
45751ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov                throw new IllegalArgumentException();
45851ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            }
45951ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            return true;
46051ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        }
46151ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
46251ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        // PopUpWindow.OnDismissListener#onDismiss
46351ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        public void onDismiss() {
46451ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            notifyOnDismissListener();
46551ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        }
46651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
46751ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        private void notifyOnDismissListener() {
46851ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            if (mOnDismissListener != null) {
46951ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov                mOnDismissListener.onDismiss();
47051ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            }
47151ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        }
47251ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    }
47351ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
47451ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    /**
47551ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     * Adapter for backing the list of activities shown in the popup.
47651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     */
47751ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    private class ActivityChooserViewAdapter extends BaseAdapter {
47851ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
47951ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        public static final int MAX_ACTIVITY_COUNT_UNLIMITED = Integer.MAX_VALUE;
48051ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
48151ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        public static final int MAX_ACTIVITY_COUNT_DEFAULT = 4;
48251ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
48376559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov        private static final int ITEM_VIEW_TYPE_ACTIVITY = 0;
48451ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
48576559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov        private static final int ITEM_VIEW_TYPE_FOOTER = 1;
48651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
48751ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        private static final int ITEM_VIEW_TYPE_COUNT = 3;
48851ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
48951ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        private ActivityChooserModel mDataModel;
49051ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
49151ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        private int mMaxActivityCount = MAX_ACTIVITY_COUNT_DEFAULT;
49251ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
49376559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov        private boolean mShowDefaultActivity;
49451ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
49576559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov        private boolean mShowFooterView;
49651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
49751ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        public void setDataModel(ActivityChooserModel dataModel) {
49876559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov            ActivityChooserModel oldDataModel = mAdapter.getDataModel();
49976559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov            if (oldDataModel != null && isShown()) {
50076559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov                oldDataModel.unregisterObserver(mModelDataSetOberver);
50176559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov            }
50251ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            mDataModel = dataModel;
50376559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov            if (dataModel != null && isShown()) {
50476559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov                dataModel.registerObserver(mModelDataSetOberver);
50551ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            }
50676559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov            notifyDataSetChanged();
50751ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        }
50851ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
50951ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        @Override
51051ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        public int getItemViewType(int position) {
51176559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov            if (mShowFooterView && position == getCount() - 1) {
51251ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov                return ITEM_VIEW_TYPE_FOOTER;
51351ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            } else {
51451ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov                return ITEM_VIEW_TYPE_ACTIVITY;
51551ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            }
51651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        }
51751ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
51851ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        @Override
51951ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        public int getViewTypeCount() {
52051ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            return ITEM_VIEW_TYPE_COUNT;
52151ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        }
52251ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
52351ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        public int getCount() {
52451ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            int count = 0;
52551ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            int activityCount = mDataModel.getActivityCount();
52676559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov            if (!mShowDefaultActivity && mDataModel.getDefaultActivity() != null) {
52751ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov                activityCount--;
52851ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            }
52951ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            count = Math.min(activityCount, mMaxActivityCount);
53076559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov            if (mShowFooterView) {
53151ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov                count++;
53251ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            }
53351ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            return count;
53451ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        }
53551ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
53651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        public Object getItem(int position) {
53751ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            final int itemViewType = getItemViewType(position);
53851ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            switch (itemViewType) {
53951ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov                case ITEM_VIEW_TYPE_FOOTER:
54076559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov                    return null;
54151ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov                case ITEM_VIEW_TYPE_ACTIVITY:
54276559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov                    if (!mShowDefaultActivity && mDataModel.getDefaultActivity() != null) {
54376559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov                        position++;
54451ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov                    }
54576559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov                    return mDataModel.getActivity(position);
54651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov                default:
54751ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov                    throw new IllegalArgumentException();
54851ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            }
54951ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        }
55051ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
55151ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        public long getItemId(int position) {
55251ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            return position;
55351ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        }
55451ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
55551ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        public View getView(int position, View convertView, ViewGroup parent) {
55651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            final int itemViewType = getItemViewType(position);
55751ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            switch (itemViewType) {
55851ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov                case ITEM_VIEW_TYPE_FOOTER:
55976559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov                    if (convertView == null || convertView.getId() != ITEM_VIEW_TYPE_FOOTER) {
56076559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov                        convertView = LayoutInflater.from(getContext()).inflate(
56176559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov                                R.layout.activity_chooser_view_list_item, parent, false);
56276559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov                        convertView.setId(ITEM_VIEW_TYPE_FOOTER);
56376559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov                        TextView titleView = (TextView) convertView.findViewById(R.id.title);
56476559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov                        titleView.setText(mContext.getString(
56576559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov                                R.string.activity_chooser_view_see_all));
56676559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov                    }
56776559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov                    return convertView;
56851ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov                case ITEM_VIEW_TYPE_ACTIVITY:
56951ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov                    if (convertView == null || convertView.getId() != R.id.list_item) {
57051ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov                        convertView = LayoutInflater.from(getContext()).inflate(
57151ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov                                R.layout.activity_chooser_view_list_item, parent, false);
57251ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov                    }
57351ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov                    PackageManager packageManager = mContext.getPackageManager();
57451ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov                    // Set the icon
57551ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov                    ImageView iconView = (ImageView) convertView.findViewById(R.id.icon);
57651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov                    ResolveInfo activity = (ResolveInfo) getItem(position);
57751ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov                    iconView.setBackgroundDrawable(activity.loadIcon(packageManager));
57851ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov                    // Set the title.
57951ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov                    TextView titleView = (TextView) convertView.findViewById(R.id.title);
58051ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov                    titleView.setText(activity.loadLabel(packageManager));
58176559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov                    // Highlight the default.
58276559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov                    if (mShowDefaultActivity && position == 0) {
58376559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov                        convertView.setActivated(true);
58476559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov                    } else {
58576559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov                        convertView.setActivated(false);
58676559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov                    }
58751ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov                    return convertView;
58851ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov                default:
58951ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov                    throw new IllegalArgumentException();
59051ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            }
59151ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        }
59251ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
59351ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        public int measureContentWidth() {
59476559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov            // The user may have specified some of the target not to be shown but we
59551ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            // want to measure all of them since after expansion they should fit.
59651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            final int oldMaxActivityCount = mMaxActivityCount;
59751ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            mMaxActivityCount = MAX_ACTIVITY_COUNT_UNLIMITED;
59851ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
59951ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            int contentWidth = 0;
60051ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            View itemView = null;
60151ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
60251ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            final int widthMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
60351ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            final int heightMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
60451ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            final int count = getCount();
60551ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
60651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            for (int i = 0; i < count; i++) {
60751ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov                itemView = getView(i, itemView, null);
60851ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov                itemView.measure(widthMeasureSpec, heightMeasureSpec);
60951ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov                contentWidth = Math.max(contentWidth, itemView.getMeasuredWidth());
61051ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            }
61151ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
61251ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            mMaxActivityCount = oldMaxActivityCount;
61351ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
61451ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            return contentWidth;
61551ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        }
61651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
61751ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        public void setMaxActivityCount(int maxActivityCount) {
61851ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            if (mMaxActivityCount != maxActivityCount) {
61951ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov                mMaxActivityCount = maxActivityCount;
62051ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov                notifyDataSetChanged();
62151ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            }
62251ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        }
62351ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
62451ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        public ResolveInfo getDefaultActivity() {
62576559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov            return mDataModel.getDefaultActivity();
62651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        }
62751ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
62876559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov        public void setShowFooterView(boolean showFooterView) {
62976559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov            if (mShowFooterView != showFooterView) {
63076559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov                mShowFooterView = showFooterView;
63151ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov                notifyDataSetChanged();
63251ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            }
63351ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        }
63451ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
63551ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        public int getActivityCount() {
63651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            return mDataModel.getActivityCount();
63751ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        }
63851ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
63951ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        public int getMaxActivityCount() {
64051ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            return mMaxActivityCount;
64151ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        }
64251ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
64351ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        public ActivityChooserModel getDataModel() {
64451ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov            return mDataModel;
64551ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        }
64676559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov
64776559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov        public void setShowDefaultActivity(boolean showDefaultActivity) {
64876559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov            if (mShowDefaultActivity != showDefaultActivity) {
64976559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov                mShowDefaultActivity = showDefaultActivity;
65076559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov                notifyDataSetChanged();
65176559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov            }
65276559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov        }
65351ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    }
65451ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov}
655