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

Commit d3c8642d authored by RoboErik's avatar RoboErik
Browse files

Remove some more old code and fix Media command

Removes some more hidden apis from AudioService/Manager. This also
fixes up Media.java to support commands for the new service to help
with debugging. Also fixes a couple bugs that were found while fixing
up Media.

Change-Id: I68e4aa80a4de430b98236aafc883664b9432c62b
parent 150bfcd7
Loading
Loading
Loading
Loading
+105 −61
Original line number Diff line number Diff line
@@ -17,12 +17,19 @@

package com.android.commands.media;

import android.app.PendingIntent;
import android.app.ActivityManager;
import android.content.Context;
import android.graphics.Bitmap;
import android.media.IAudioService;
import android.media.IRemoteControlDisplay;
import android.media.MediaMetadata;
import android.media.session.ISessionController;
import android.media.session.ISessionManager;
import android.media.session.MediaController;
import android.media.session.MediaSessionInfo;
import android.media.session.PlaybackState;
import android.media.session.RouteInfo;
import android.os.Bundle;
import android.os.HandlerThread;
import android.os.IBinder;
import android.os.Looper;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SystemClock;
@@ -30,16 +37,17 @@ import android.util.AndroidException;
import android.view.InputDevice;
import android.view.KeyCharacterMap;
import android.view.KeyEvent;

import com.android.internal.os.BaseCommand;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.util.List;

public class Media extends BaseCommand {

    private IAudioService mAudioService;
    private ISessionManager mSessionService;

    /**
     * Command-line entry point.
@@ -54,29 +62,35 @@ public class Media extends BaseCommand {
        out.println(
                "usage: media [subcommand] [options]\n" +
                "       media dispatch KEY\n" +
                "       media remote-display\n" +
                "       media list-sessions\n" +
                "       media monitor <sessionId>\n" +
                "\n" +
                "media dispatch: dispatch a media key to the current media client.\n" +
                "media dispatch: dispatch a media key to the system.\n" +
                "                KEY may be: play, pause, play-pause, mute, headsethook,\n" +
                "                stop, next, previous, rewind, recordm fast-forword.\n" +
                "media remote-display: monitor remote display updates.\n"
                "                stop, next, previous, rewind, record, fast-forword.\n" +
                "media list-sessions: print a list of the current sessions.\n" +
                        "media monitor: monitor updates to the specified session.\n" +
                "                       Use the sessionId from list-sessions.\n"
        );
    }

    public void onRun() throws Exception {
        mAudioService = IAudioService.Stub.asInterface(ServiceManager.checkService(
                Context.AUDIO_SERVICE));
        if (mAudioService == null) {
        mSessionService = ISessionManager.Stub.asInterface(ServiceManager.checkService(
                Context.MEDIA_SESSION_SERVICE));
        if (mSessionService == null) {
            System.err.println(NO_SYSTEM_ERROR_CODE);
            throw new AndroidException("Can't connect to audio service; is the system running?");
            throw new AndroidException(
                    "Can't connect to media session service; is the system running?");
        }

        String op = nextArgRequired();

        if (op.equals("dispatch")) {
            runDispatch();
        } else if (op.equals("remote-display")) {
            runRemoteDisplay();
        } else if (op.equals("list-sessions")) {
            runListSessions();
        } else if (op.equals("monitor")) {
            runMonitor();
        } else {
            showError("Error: unknown command '" + op + "'");
            return;
@@ -85,11 +99,39 @@ public class Media extends BaseCommand {

    private void sendMediaKey(KeyEvent event) {
        try {
            mAudioService.dispatchMediaKeyEvent(event);
            mSessionService.dispatchMediaKeyEvent(event, false);
        } catch (RemoteException e) {
        }
    }

    private void runMonitor() throws Exception {
        String id = nextArgRequired();
        if (id == null) {
            showError("Error: must include a session id");
            return;
        }
        boolean success = false;
        try {
            List<IBinder> sessions = mSessionService
                    .getSessions(null, ActivityManager.getCurrentUser());
            for (IBinder session : sessions) {
                MediaController controller = MediaController.fromBinder(ISessionController.Stub
                        .asInterface(session));
                if (controller != null && controller.getSessionInfo().getId().equals(id)) {
                    ControllerMonitor monitor = new ControllerMonitor(controller);
                    monitor.run();
                    success = true;
                    break;
                }
            }
        } catch (Exception e) {
            System.out.println("***Error monitoring session*** " + e.getMessage());
        }
        if (!success) {
            System.out.println("No session found with id " + id);
        }
    }

    private void runDispatch() throws Exception {
        String cmd = nextArgRequired();
        int keycode;
@@ -127,65 +169,49 @@ public class Media extends BaseCommand {
                KeyCharacterMap.VIRTUAL_KEYBOARD, 0, 0, InputDevice.SOURCE_KEYBOARD));
    }

    class RemoteDisplayMonitor extends IRemoteControlDisplay.Stub {
        RemoteDisplayMonitor() {
        }


        @Override
        public void setCurrentClientId(int clientGeneration, PendingIntent clientMediaIntent,
                boolean clearing) {
            System.out.println("New client: id=" + clientGeneration
                    + " intent=" + clientMediaIntent + " clearing=" + clearing);
        }

        @Override
        public void setEnabled(boolean enabled) {
            System.out.println("New enable state= " + (enabled ? "enabled" : "disabled"));
        }
    class ControllerMonitor extends MediaController.Callback {
        private final MediaController mController;

        @Override
        public void setPlaybackState(int generationId, int state, long stateChangeTimeMs,
                long currentPosMs, float speed) {
            System.out.println("New state: id=" + generationId + " state=" + state
                    + " time=" + stateChangeTimeMs + " pos=" + currentPosMs + " speed=" + speed);
        public ControllerMonitor(MediaController controller) {
            mController = controller;
        }

        @Override
        public void setTransportControlInfo(int generationId, int transportControlFlags,
                int posCapabilities) {
            System.out.println("New control info: id=" + generationId
                    + " flags=0x" + Integer.toHexString(transportControlFlags)
                    + " cap=0x" + Integer.toHexString(posCapabilities));
        public void onSessionEvent(String event, Bundle extras) {
            System.out.println("onSessionEvent event=" + event + ", extras=" + extras);
        }

        @Override
        public void setMetadata(int generationId, Bundle metadata) {
            System.out.println("New metadata: id=" + generationId
                    + " data=" + metadata);
        public void onRouteChanged(RouteInfo route) {
            System.out.println("onRouteChanged " + route);
        }

        @Override
        public void setArtwork(int generationId, Bitmap artwork) {
            System.out.println("New artwork: id=" + generationId
                    + " art=" + artwork);
        public void onPlaybackStateChanged(PlaybackState state) {
            System.out.println("onPlaybackStateChanged " + state);
        }

        @Override
        public void setAllMetadata(int generationId, Bundle metadata, Bitmap artwork) {
            System.out.println("New metadata+artwork: id=" + generationId
                    + " data=" + metadata + " art=" + artwork);
        public void onMetadataChanged(MediaMetadata metadata) {
            String mmString = metadata == null ? null : "title=" + metadata
                    .getString(MediaMetadata.METADATA_KEY_TITLE);
            System.out.println("onMetadataChanged " + mmString);
        }

        void printUsageMessage() {
            System.out.println("Monitoring remote control displays...  available commands:");
            System.out.println("V2Monitoring session " + mController.getSessionInfo().getId()
                    + "...  available commands:");
            System.out.println("(q)uit: finish monitoring");
        }

        void run() throws RemoteException {
            printUsageMessage();

            mAudioService.registerRemoteControlDisplay(this, 0, 0);
            HandlerThread cbThread = new HandlerThread("MediaCb") {
                @Override
                protected void onLooperPrepared() {
                    mController.addCallback(ControllerMonitor.this);
                }
            };
            cbThread.start();

            try {
                InputStreamReader converter = new InputStreamReader(System.in);
@@ -209,17 +235,35 @@ public class Media extends BaseCommand {
                        printUsageMessage();
                    }
                }

            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                mAudioService.unregisterRemoteControlDisplay(this);
                cbThread.getLooper().quit();
                try {
                    mController.removeCallback(this);
                } catch (Exception e) {
                    // ignoring
                }
            }
        }
    }

    private void runRemoteDisplay() throws Exception {
        RemoteDisplayMonitor monitor = new RemoteDisplayMonitor();
        monitor.run();
    private void runListSessions() {
        System.out.println("Sessions:");
        try {
            List<IBinder> sessions = mSessionService
                    .getSessions(null, ActivityManager.getCurrentUser());
            for (IBinder session : sessions) {
                MediaController controller = MediaController.fromBinder(ISessionController.Stub
                        .asInterface(session));
                if (controller != null) {
                    MediaSessionInfo info = controller.getSessionInfo();
                    System.out.println("  id=" + info.getId() + ", package="
                            + info.getPackageName());
                }
            }
        } catch (Exception e) {
            System.out.println("***Error listing sessions***");
        }
    }
}
+0 −20
Original line number Diff line number Diff line
@@ -1615,26 +1615,6 @@ public class AudioManager {
        }
    }

    /**
     * @hide
     * If the stream is active locally or remotely, adjust its volume according to the enforced
     * priority rules.
     * Note: only AudioManager.STREAM_MUSIC is supported at the moment
     */
    public void adjustLocalOrRemoteStreamVolume(int streamType, int direction) {
        if (streamType != STREAM_MUSIC) {
            Log.w(TAG, "adjustLocalOrRemoteStreamVolume() doesn't support stream " + streamType);
        }
        IAudioService service = getService();
        try {
            service.adjustLocalOrRemoteStreamVolume(streamType, direction,
                    mContext.getOpPackageName());
        } catch (RemoteException e) {
            Log.e(TAG, "Dead object in adjustLocalOrRemoteStreamVolume", e);
        }
    }


    /**
     * Return a new audio session identifier not associated with any player or effect.
     * It can for instance be used to create one of the {@link android.media.audiofx.AudioEffect}
+0 −34
Original line number Diff line number Diff line
@@ -829,24 +829,6 @@ public class AudioService extends IAudioService.Stub {
        return false;
    }

    /** @see AudioManager#adjustVolume(int, int) */
    public void adjustVolume(int direction, int flags, String callingPackage) {
        adjustSuggestedStreamVolume(direction, AudioManager.USE_DEFAULT_STREAM_TYPE, flags,
                callingPackage);
    }

    /** @see AudioManager#adjustLocalOrRemoteStreamVolume(int, int) with current assumption
     *  on streamType: fixed to STREAM_MUSIC */
    public void adjustLocalOrRemoteStreamVolume(int streamType, int direction,
            String callingPackage) {
        if (DEBUG_VOL) Log.d(TAG, "adjustLocalOrRemoteStreamVolume(dir="+direction+")");
        if (AudioSystem.isStreamActive(AudioSystem.STREAM_MUSIC, 0)) {
            adjustStreamVolume(AudioSystem.STREAM_MUSIC, direction, 0, callingPackage);
        } else if (mMediaFocusControl.checkUpdateRemoteStateIfActive(AudioSystem.STREAM_MUSIC)) {
            mMediaFocusControl.adjustRemoteVolume(AudioSystem.STREAM_MUSIC, direction, 0);
        }
    }

    /** @see AudioManager#adjustVolume(int, int) */
    public void adjustSuggestedStreamVolume(int direction, int suggestedStreamType, int flags,
            String callingPackage) {
@@ -4482,22 +4464,6 @@ public class AudioService extends IAudioService.Stub {
        mMediaFocusControl.setPlaybackInfoForRcc(rccId, what, value);
    }

    public void dispatchMediaKeyEvent(KeyEvent keyEvent) {
        if (DEBUG_SESSIONS) {
            int pid = getCallingPid();
            Log.w(TAG, "Call to dispatchMediaKeyEvent from " + pid);
        }
        MediaSessionLegacyHelper.getHelper(mContext).sendMediaButtonEvent(keyEvent, false);
    }

    public void dispatchMediaKeyEventUnderWakelock(KeyEvent keyEvent) {
        if (DEBUG_SESSIONS) {
            int pid = getCallingPid();
            Log.w(TAG, "Call to dispatchMediaKeyEventUnderWakelock from " + pid);
        }
        MediaSessionLegacyHelper.getHelper(mContext).sendMediaButtonEvent(keyEvent, true);
    }

    //==========================================================================================
    // Audio Focus
    //==========================================================================================
+0 −8
Original line number Diff line number Diff line
@@ -36,13 +36,8 @@ import android.view.KeyEvent;
 */
interface IAudioService {

    void adjustVolume(int direction, int flags, String callingPackage);

    boolean isLocalOrRemoteMusicActive();

    oneway void adjustLocalOrRemoteStreamVolume(int streamType, int direction,
            String callingPackage);

    void adjustSuggestedStreamVolume(int direction, int suggestedStreamType, int flags,
            String callingPackage);

@@ -127,9 +122,6 @@ interface IAudioService {

    int getCurrentAudioFocus();

    oneway void dispatchMediaKeyEvent(in KeyEvent keyEvent);
    void dispatchMediaKeyEventUnderWakelock(in KeyEvent keyEvent);

           void registerMediaButtonIntent(in PendingIntent pi, in ComponentName c, IBinder token);
    oneway void unregisterMediaButtonIntent(in PendingIntent pi);

+13 −11
Original line number Diff line number Diff line
@@ -70,14 +70,7 @@ public final class MediaController {
     * @hide
     */
    public static MediaController fromBinder(ISessionController sessionBinder) {
        MediaController controller = new MediaController(sessionBinder);
        try {
            controller.mSessionBinder.registerCallbackListener(controller.mCbStub);
        } catch (RemoteException e) {
            Log.wtf(TAG, "MediaController created with expired token", e);
            controller = null;
        }
        return controller;
        return new MediaController(sessionBinder);
    }

    /**
@@ -305,7 +298,7 @@ public final class MediaController {
                mSessionBinder.registerCallbackListener(mCbStub);
                mCbRegistered = true;
            } catch (RemoteException e) {
                Log.d(TAG, "Dead object in registerCallback", e);
                Log.e(TAG, "Dead object in registerCallback", e);
            }
        }
    }
@@ -314,14 +307,23 @@ public final class MediaController {
        if (cb == null) {
            throw new IllegalArgumentException("Callback cannot be null");
        }
        boolean success = false;
        for (int i = mCallbacks.size() - 1; i >= 0; i--) {
            MessageHandler handler = mCallbacks.get(i);
            if (cb == handler.mCallback) {
                mCallbacks.remove(i);
                return true;
                success = true;
            }
        }
        return false;
        if (mCbRegistered && mCallbacks.size() == 0) {
            try {
                mSessionBinder.unregisterCallbackListener(mCbStub);
            } catch (RemoteException e) {
                Log.e(TAG, "Dead object in removeCallbackLocked");
            }
            mCbRegistered = false;
        }
        return success;
    }

    private MessageHandler getHandlerForCallbackLocked(Callback cb) {
Loading