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

Commit b814caa5 authored by Jin Seok Park's avatar Jin Seok Park Committed by Automerger Merge Worker
Browse files

Merge "[Media ML] Support customization for long press implementation" into...

Merge "[Media ML] Support customization for long press implementation" into rvc-dev am: 7101c112 am: edbd0fe0 am: 00de1c5e

Change-Id: I7f5f98634767a30b45c64915bd4a29c4d6c01fe9
parents dbd27ef5 00de1c5e
Loading
Loading
Loading
Loading
+174 −1
Original line number Diff line number Diff line
@@ -16,24 +16,64 @@

package com.android.server.media;

import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.media.session.ISessionManager;
import android.media.session.MediaSession;
import android.os.Binder;
import android.view.KeyEvent;
import android.view.ViewConfiguration;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.HashMap;
import java.util.Map;

/**
 * Provides a way to customize behavior for media key events.
 *
 * <p>
 * In order to override the implementation of the single/double/triple click or long press,
 * {@link #setOverriddenKeyEvents(int, int)} should be called for each key code with the
 * overridden {@link KeyEventType} bit value set, and the corresponding method,
 * {@link #onSingleClick(KeyEvent)}, {@link #onDoubleClick(KeyEvent)},
 * {@link #onTripleClick(KeyEvent)}, {@link #onLongPress(KeyEvent)} should be implemented.
 * <p>
 * Note: When instantiating this class, {@link MediaSessionService} will only use the constructor
 * without any parameters.
 */
// TODO: Change API names from using "click" to "tap"
// TODO: Move this class to apex/media/
public abstract class MediaKeyDispatcher {
    @IntDef(flag = true, value = {
            KEY_EVENT_SINGLE_CLICK,
            KEY_EVENT_DOUBLE_CLICK,
            KEY_EVENT_TRIPLE_CLICK,
            KEY_EVENT_LONG_PRESS
    })
    @Retention(RetentionPolicy.SOURCE)
    @interface KeyEventType {}
    static final int KEY_EVENT_SINGLE_CLICK = 1 << 0;
    static final int KEY_EVENT_DOUBLE_CLICK = 1 << 1;
    static final int KEY_EVENT_TRIPLE_CLICK = 1 << 2;
    static final int KEY_EVENT_LONG_PRESS = 1 << 3;

    private Map<Integer, Integer> mOverriddenKeyEvents;

    public MediaKeyDispatcher() {
        // Constructor used for reflection
        mOverriddenKeyEvents = new HashMap<>();
        mOverriddenKeyEvents.put(KeyEvent.KEYCODE_MEDIA_PLAY, 0);
        mOverriddenKeyEvents.put(KeyEvent.KEYCODE_MEDIA_PAUSE, 0);
        mOverriddenKeyEvents.put(KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE, 0);
        mOverriddenKeyEvents.put(KeyEvent.KEYCODE_MUTE, 0);
        mOverriddenKeyEvents.put(KeyEvent.KEYCODE_HEADSETHOOK, 0);
        mOverriddenKeyEvents.put(KeyEvent.KEYCODE_MEDIA_STOP, 0);
        mOverriddenKeyEvents.put(KeyEvent.KEYCODE_MEDIA_NEXT, 0);
        mOverriddenKeyEvents.put(KeyEvent.KEYCODE_MEDIA_PREVIOUS, 0);
    }

    // TODO: Move this method into SessionPolicyProvider.java for better readability.
    /**
     * Implement this to customize the logic for which MediaSession should consume which key event.
     *
@@ -49,4 +89,137 @@ public abstract class MediaKeyDispatcher {
            boolean asSystemService) {
        return null;
    }

    /**
     * Gets the map of key code -> {@link KeyEventType} that have been overridden.
     * <p>
     * The list of valid key codes are the following:
     * <ul>
     * <li> {@link KeyEvent#KEYCODE_MEDIA_PLAY}
     * <li> {@link KeyEvent#KEYCODE_MEDIA_PAUSE}
     * <li> {@link KeyEvent#KEYCODE_MEDIA_PLAY_PAUSE}
     * <li> {@link KeyEvent#KEYCODE_MUTE}
     * <li> {@link KeyEvent#KEYCODE_HEADSETHOOK}
     * <li> {@link KeyEvent#KEYCODE_MEDIA_STOP}
     * <li> {@link KeyEvent#KEYCODE_MEDIA_NEXT}
     * <li> {@link KeyEvent#KEYCODE_MEDIA_PREVIOUS}
     * </ul>
     * @see {@link KeyEvent#isMediaSessionKey(int)}
     */
    @KeyEventType Map<Integer, Integer> getOverriddenKeyEvents() {
        return mOverriddenKeyEvents;
    }

    static boolean isSingleClickOverridden(@KeyEventType int overriddenKeyEvents) {
        return (overriddenKeyEvents & MediaKeyDispatcher.KEY_EVENT_SINGLE_CLICK) != 0;
    }

    static boolean isDoubleClickOverridden(@KeyEventType int overriddenKeyEvents) {
        return (overriddenKeyEvents & MediaKeyDispatcher.KEY_EVENT_DOUBLE_CLICK) != 0;
    }

    static boolean isTripleClickOverridden(@KeyEventType int overriddenKeyEvents) {
        return (overriddenKeyEvents & MediaKeyDispatcher.KEY_EVENT_TRIPLE_CLICK) != 0;
    }

    static boolean isLongPressOverridden(@KeyEventType int overriddenKeyEvents) {
        return (overriddenKeyEvents & MediaKeyDispatcher.KEY_EVENT_LONG_PRESS) != 0;
    }

    /**
     * Sets the value of the given key event type flagged with overridden {@link KeyEventType} to
     * the given key code. If called multiple times for the same key code, will be overwritten to
     * the most recently called {@link KeyEventType} value.
     * <p>
     * The list of valid key codes are the following:
     * <ul>
     * <li> {@link KeyEvent#KEYCODE_MEDIA_PLAY}
     * <li> {@link KeyEvent#KEYCODE_MEDIA_PAUSE}
     * <li> {@link KeyEvent#KEYCODE_MEDIA_PLAY_PAUSE}
     * <li> {@link KeyEvent#KEYCODE_MUTE}
     * <li> {@link KeyEvent#KEYCODE_HEADSETHOOK}
     * <li> {@link KeyEvent#KEYCODE_MEDIA_STOP}
     * <li> {@link KeyEvent#KEYCODE_MEDIA_NEXT}
     * <li> {@link KeyEvent#KEYCODE_MEDIA_PREVIOUS}
     * </ul>
     * @see {@link KeyEvent#isMediaSessionKey(int)}
     * @param keyCode
     */
    void setOverriddenKeyEvents(int keyCode, @KeyEventType int keyEventType) {
        mOverriddenKeyEvents.put(keyCode, keyEventType);
    }

    /**
     * Customized implementation for single click event. Will be run if
     * {@link #KEY_EVENT_SINGLE_CLICK} flag is on for the corresponding key code from
     * {@link #getOverriddenKeyEvents()}.
     *
     * It is considered a single click if only one {@link KeyEvent} with the same
     * {@link KeyEvent#getKeyCode()} is dispatched within
     * {@link ViewConfiguration#getMultiPressTimeout()} milliseconds. Change the
     * {@link android.provider.Settings.Secure#MULTI_PRESS_TIMEOUT} value to adjust the interval.
     *
     * Note: This will only be called once with the {@link KeyEvent#ACTION_UP} KeyEvent.
     *
     * @param keyEvent
     */
    void onSingleClick(KeyEvent keyEvent) {
    }

    /**
     * Customized implementation for double click event. Will be run if
     * {@link #KEY_EVENT_DOUBLE_CLICK} flag is on for the corresponding key code from
     * {@link #getOverriddenKeyEvents()}.
     *
     * It is considered a double click if two {@link KeyEvent}s with the same
     * {@link KeyEvent#getKeyCode()} are dispatched within
     * {@link ViewConfiguration#getMultiPressTimeout()} milliseconds of each other. Change the
     * {@link android.provider.Settings.Secure#MULTI_PRESS_TIMEOUT} value to adjust the interval.
     *
     * Note: This will only be called once with the {@link KeyEvent#ACTION_UP} KeyEvent.
     *
     * @param keyEvent
     */
    void onDoubleClick(KeyEvent keyEvent) {
    }

    /**
     * Customized implementation for triple click event. Will be run if
     * {@link #KEY_EVENT_TRIPLE_CLICK} flag is on for the corresponding key code from
     * {@link #getOverriddenKeyEvents()}.
     *
     * It is considered a triple click if three {@link KeyEvent}s with the same
     * {@link KeyEvent#getKeyCode()} are dispatched within
     * {@link ViewConfiguration#getMultiPressTimeout()} milliseconds of each other. Change the
     * {@link android.provider.Settings.Secure#MULTI_PRESS_TIMEOUT} value to adjust the interval.
     *
     * Note: This will only be called once with the {@link KeyEvent#ACTION_UP} KeyEvent.
     *
     * @param keyEvent
     */
    void onTripleClick(KeyEvent keyEvent) {
    }

    /**
     * Customized implementation for long press event. Will be run if
     * {@link #KEY_EVENT_LONG_PRESS} flag is on for the corresponding key code from
     * {@link #getOverriddenKeyEvents()}.
     *
     * It is considered a long press if an {@link KeyEvent#ACTION_DOWN} key event is followed by
     * another {@link KeyEvent#ACTION_DOWN} key event with {@link KeyEvent#FLAG_LONG_PRESS}
     * enabled, and an {@link KeyEvent#getRepeatCount()} that is equal to 1.
     *
     * Note: This will be called for the following key events:
     * <ul>
     *   <li>A {@link KeyEvent#ACTION_DOWN} KeyEvent with {@link KeyEvent#FLAG_LONG_PRESS} and
     *   {@link KeyEvent#getRepeatCount()} equal to 1</li>
     *   <li>Multiple {@link KeyEvent#ACTION_DOWN} KeyEvents with increasing
     *   {@link KeyEvent#getRepeatCount()}</li>
     *   <li>A {@link KeyEvent#ACTION_UP} KeyEvent</li>
     * </ul>
     *
     * @param keyEvent
     */
    void onLongPress(KeyEvent keyEvent) {
    }
}
+197 −86

File changed.

Preview size limit exceeded, changes collapsed.

+1 −0
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@ import java.lang.annotation.RetentionPolicy;
 * Note: When instantiating this class, {@link MediaSessionService} will only use the constructor
 * without any parameters.
 */
// TODO: Move this class to apex/media/
public abstract class SessionPolicyProvider {
    @IntDef(value = {
            SESSION_POLICY_IGNORE_BUTTON_RECEIVER,