Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 151763d3 authored by Svetoslav Ganov's avatar Svetoslav Ganov Committed by Android (Google) Code Review
Browse files

Merge "Adding a callback to ShareActionProvider + make ActivityChooserView...

Merge "Adding a callback to ShareActionProvider + make ActivityChooserView popup hide on action bar hide."
parents fb3db1f3 8c6c79f0
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -26694,11 +26694,16 @@ package android.widget {
  public class ShareActionProvider extends android.view.ActionProvider {
    ctor public ShareActionProvider(android.content.Context);
    method public android.view.View onCreateActionView();
    method public void setOnShareTargetSelectedListener(android.widget.ShareActionProvider.OnShareTargetSelectedListener);
    method public void setShareHistoryFileName(java.lang.String);
    method public void setShareIntent(android.content.Intent);
    field public static final java.lang.String DEFAULT_SHARE_HISTORY_FILE_NAME = "share_history.xml";
  }
  public static abstract interface ShareActionProvider.OnShareTargetSelectedListener {
    method public abstract boolean onShareTargetSelected(android.widget.ShareActionProvider, android.content.Intent);
  }
  public class SimpleAdapter extends android.widget.BaseAdapter implements android.widget.Filterable {
    ctor public SimpleAdapter(android.content.Context, java.util.List<? extends java.util.Map<java.lang.String, ?>>, int, java.lang.String[], int[]);
    method public int getCount();
+55 −4
Original line number Diff line number Diff line
@@ -130,6 +130,30 @@ public class ActivityChooserModel extends DataSetObservable {
                List<HistoricalRecord> historicalRecords);
    }

    /**
     * Listener for choosing an activity.
     */
    public interface OnChooseActivityListener {

        /**
         * Called when an activity has been chosen. The client can decide whether
         * an activity can be chosen and if so the caller of
         * {@link ActivityChooserModel#chooseActivity(int)} will receive and {@link Intent}
         * for launching it.
         * <p>
         * <strong>Note:</strong> Modifying the intent is not permitted and
         *     any changes to the latter will be ignored.
         * </p>
         *
         * @param host The listener's host model.
         * @param intent The intent for launching the chosen activity.
         * @return Whether the intent is handled and should not be delivered to clients.
         *
         * @see ActivityChooserModel#chooseActivity(int)
         */
        public boolean onChooseActivity(ActivityChooserModel host, Intent intent);
    }

    /**
     * Flag for selecting debug mode.
     */
@@ -286,6 +310,11 @@ public class ActivityChooserModel extends DataSetObservable {
     */
    private final Handler mHandler = new Handler();

    /**
     * Policy for controlling how the model handles chosen activities.
     */
    private OnChooseActivityListener mActivityChoserModelPolicy;

    /**
     * Gets the data model backed by the contents of the provided file with historical data.
     * Note that only one data model is backed by a given file, thus multiple calls with
@@ -426,9 +455,11 @@ public class ActivityChooserModel extends DataSetObservable {
     * the client solely to let additional customization before the start.
     * </p>
     *
     * @return Whether adding succeeded.
     * @return An {@link Intent} for launching the activity or null if the
     *         policy has consumed the intent.
     *
     * @see HistoricalRecord
     * @see OnChooseActivityListener
     */
    public Intent chooseActivity(int index) {
        ActivityResolveInfo chosenActivity = mActivites.get(index);
@@ -436,16 +467,36 @@ public class ActivityChooserModel extends DataSetObservable {
        ComponentName chosenName = new ComponentName(
                chosenActivity.resolveInfo.activityInfo.packageName,
                chosenActivity.resolveInfo.activityInfo.name);
        HistoricalRecord historicalRecord = new HistoricalRecord(chosenName,
                System.currentTimeMillis(), DEFAULT_HISTORICAL_RECORD_WEIGHT);
        addHisoricalRecord(historicalRecord);

        Intent choiceIntent = new Intent(mIntent);
        choiceIntent.setComponent(chosenName);

        if (mActivityChoserModelPolicy != null) {
            // Do not allow the policy to change the intent.
            Intent choiceIntentCopy = new Intent(choiceIntent);
            final boolean handled = mActivityChoserModelPolicy.onChooseActivity(this,
                    choiceIntentCopy);
            if (handled) {
                return null;
            }
        }

        HistoricalRecord historicalRecord = new HistoricalRecord(chosenName,
                System.currentTimeMillis(), DEFAULT_HISTORICAL_RECORD_WEIGHT);
        addHisoricalRecord(historicalRecord);

        return choiceIntent;
    }

    /**
     * Sets the listener for choosing an activity.
     *
     * @param listener The listener.
     */
    public void setOnChooseActivityListener(OnChooseActivityListener listener) {
        mActivityChoserModelPolicy = listener;
    }

    /**
     * Gets the default activity, The default activity is defined as the one
     * with highest rank i.e. the first one in the list of activities that can
+32 −3
Original line number Diff line number Diff line
@@ -29,6 +29,8 @@ import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
import android.widget.ActivityChooserModel.ActivityChooserModelClient;

import com.android.internal.R;
@@ -115,6 +117,19 @@ public class ActivityChooserView extends ViewGroup implements ActivityChooserMod
        }
    };

    private final OnGlobalLayoutListener mOnGlobalLayoutListener = new OnGlobalLayoutListener() {
        @Override
        public void onGlobalLayout() {
            if (isShowingPopup()) {
                if (!isShown()) {
                    getListPopupWindow().dismiss();
                } else {
                    getListPopupWindow().show();
                }
            }
        }
    };

    /**
     * Popup window for showing the activity overflow list.
     */
@@ -261,6 +276,8 @@ public class ActivityChooserView extends ViewGroup implements ActivityChooserMod
            throw new IllegalStateException("No data model. Did you call #setDataModel?");
        }

        getViewTreeObserver().addOnGlobalLayoutListener(mOnGlobalLayoutListener);

        mAdapter.setMaxActivityCount(maxActivityCount);

        final int activityCount = mAdapter.getActivityCount();
@@ -292,6 +309,10 @@ public class ActivityChooserView extends ViewGroup implements ActivityChooserMod
    public boolean dismissPopup() {
        if (isShowingPopup()) {
            getListPopupWindow().dismiss();
            ViewTreeObserver viewTreeObserver = getViewTreeObserver();
            if (viewTreeObserver.isAlive()) {
                viewTreeObserver.removeGlobalOnLayoutListener(mOnGlobalLayoutListener);
            }
        }
        return true;
    }
@@ -322,6 +343,10 @@ public class ActivityChooserView extends ViewGroup implements ActivityChooserMod
        if (dataModel != null) {
            dataModel.unregisterObserver(mModelDataSetOberver);
        }
        ViewTreeObserver viewTreeObserver = getViewTreeObserver();
        if (viewTreeObserver.isAlive()) {
            viewTreeObserver.removeGlobalOnLayoutListener(mOnGlobalLayoutListener);
        }
        mIsAttachedToWindow = false;
    }

@@ -434,8 +459,10 @@ public class ActivityChooserView extends ViewGroup implements ActivityChooserMod
                    } else {
                        // The first item in the model is default action => adjust index
                        Intent launchIntent  = mAdapter.getDataModel().chooseActivity(position + 1);
                        if (launchIntent != null) {
                            mContext.startActivity(launchIntent);
                        }
                    }
                } break;
                default:
                    throw new IllegalArgumentException();
@@ -449,7 +476,9 @@ public class ActivityChooserView extends ViewGroup implements ActivityChooserMod
                ResolveInfo defaultActivity = mAdapter.getDefaultActivity();
                final int index = mAdapter.getDataModel().getActivityIndex(defaultActivity);
                Intent launchIntent = mAdapter.getDataModel().chooseActivity(index);
                if (launchIntent != null) {
                    mContext.startActivity(launchIntent);
                }
            } else if (view == mExpandActivityOverflowButton) {
                mIsSelectingDefaultActivity = false;
                showPopupUnchecked(mInitialActivityCount);
+2 −1
Original line number Diff line number Diff line
@@ -23,11 +23,11 @@ import android.os.SystemClock;
import android.util.AttributeSet;
import android.util.SparseArray;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.SoundEffectConstants;
import android.view.View;
import android.view.ViewDebug;
import android.view.ViewGroup;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.accessibility.AccessibilityEvent;


@@ -278,6 +278,7 @@ public abstract class AdapterView<T extends Adapter> extends ViewGroup {
     */
    public boolean performItemClick(View view, int position, long id) {
        view.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED);

        if (mOnItemClickListener != null) {
            playSoundEffect(SoundEffectConstants.CLICK);
            mOnItemClickListener.onItemClick(this, view, position, id);
+74 −1
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@ import android.view.MenuItem;
import android.view.MenuItem.OnMenuItemClickListener;
import android.view.SubMenu;
import android.view.View;
import android.widget.ActivityChooserModel.OnChooseActivityListener;

import com.android.internal.R;

@@ -72,6 +73,27 @@ import com.android.internal.R;
 */
public class ShareActionProvider extends ActionProvider {

    /**
     * Listener for the event of selecting a share target.
     */
    public interface OnShareTargetSelectedListener {

        /**
         * Called when a share target has been selected. The client can
         * decide whether to handle the intent or rely on the default
         * behavior which is launching it.
         * <p>
         * <strong>Note:</strong> Modifying the intent is not permitted and
         *     any changes to the latter will be ignored.
         * </p>
         *
         * @param source The source of the notification.
         * @param intent The intent for launching the chosen share target.
         * @return Whether the client has handled the intent.
         */
        public boolean onShareTargetSelected(ShareActionProvider source, Intent intent);
    }

    /**
     * The default for the maximal number of activities shown in the sub-menu.
     */
@@ -103,6 +125,10 @@ public class ShareActionProvider extends ActionProvider {
     */
    private String mShareHistoryFileName = DEFAULT_SHARE_HISTORY_FILE_NAME;

    private OnShareTargetSelectedListener mOnShareTargetSelectedListener;

    private OnChooseActivityListener mOnChooseActivityListener;

    /**
     * Creates a new instance.
     *
@@ -113,6 +139,21 @@ public class ShareActionProvider extends ActionProvider {
        mContext = context;
    }

    /**
     * Sets a listener to be notified when a share target has been selected.
     * The listener can optionally decide to handle the selection and
     * not rely on the default behavior which is to launch the activity.
     * <p>
     * <strong>Note:</strong> If you choose the backing share history file
     *     you will still be notified in this callback.
     * </p>
     * @param listener The listener.
     */
    public void setOnShareTargetSelectedListener(OnShareTargetSelectedListener listener) {
        mOnShareTargetSelectedListener = listener;
        setActivityChooserPolicyIfNeeded();
    }

    /**
     * {@inheritDoc}
     */
@@ -192,6 +233,7 @@ public class ShareActionProvider extends ActionProvider {
     */
    public void setShareHistoryFileName(String shareHistoryFile) {
        mShareHistoryFileName = shareHistoryFile;
        setActivityChooserPolicyIfNeeded();
    }

    /**
@@ -229,8 +271,39 @@ public class ShareActionProvider extends ActionProvider {
                    mShareHistoryFileName);
            final int itemId = item.getItemId();
            Intent launchIntent = dataModel.chooseActivity(itemId);
            if (launchIntent != null) {
                mContext.startActivity(launchIntent);
            }
            return true;
        }
    }

    /**
     * Set the activity chooser policy of the model backed by the current
     * share history file if needed which is if there is a registered callback.
     */
    private void setActivityChooserPolicyIfNeeded() {
        if (mOnShareTargetSelectedListener == null) {
            return;
        }
        if (mOnChooseActivityListener == null) {
            mOnChooseActivityListener = new ShareAcitivityChooserModelPolicy();
        }
        ActivityChooserModel dataModel = ActivityChooserModel.get(mContext, mShareHistoryFileName);
        dataModel.setOnChooseActivityListener(mOnChooseActivityListener);
    }

    /**
     * Policy that delegates to the {@link OnShareTargetSelectedListener}, if such.
     */
    private class ShareAcitivityChooserModelPolicy implements OnChooseActivityListener {
        @Override
        public boolean onChooseActivity(ActivityChooserModel host, Intent intent) {
            if (mOnShareTargetSelectedListener != null) {
                return mOnShareTargetSelectedListener.onShareTargetSelected(
                        ShareActionProvider.this, intent);
            }
            return false;
        }
    }
}