Media.java revision f108cdd9ee5efe354d87edd02a07b323298c116c
1/*
2**
3** Copyright 2013, The Android Open Source Project
4**
5** Licensed under the Apache License, Version 2.0 (the "License");
6** you may not use this file except in compliance with the License.
7** You may obtain a copy of the License at
8**
9**     http://www.apache.org/licenses/LICENSE-2.0
10**
11** Unless required by applicable law or agreed to in writing, software
12** distributed under the License is distributed on an "AS IS" BASIS,
13** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14** See the License for the specific language governing permissions and
15** limitations under the License.
16*/
17
18package com.android.commands.media;
19
20import android.app.PendingIntent;
21import android.content.Context;
22import android.graphics.Bitmap;
23import android.media.IAudioService;
24import android.media.IRemoteControlDisplay;
25import android.os.Bundle;
26import android.os.RemoteException;
27import android.os.ServiceManager;
28import android.os.SystemClock;
29import android.util.AndroidException;
30import android.view.InputDevice;
31import android.view.KeyCharacterMap;
32import android.view.KeyEvent;
33import com.android.internal.os.BaseCommand;
34
35import java.io.BufferedReader;
36import java.io.IOException;
37import java.io.InputStreamReader;
38import java.io.PrintStream;
39
40public class Media extends BaseCommand {
41
42    private IAudioService mAudioService;
43
44    /**
45     * Command-line entry point.
46     *
47     * @param args The command-line arguments
48     */
49    public static void main(String[] args) {
50        (new Media()).run(args);
51    }
52
53    public void onShowUsage(PrintStream out) {
54        out.println(
55                "usage: media [subcommand] [options]\n" +
56                "       media dispatch KEY\n" +
57                "       media remote-display\n" +
58                "\n" +
59                "media dispatch: dispatch a media key to the current media client.\n" +
60                "                KEY may be: play, pause, play-pause, mute, headsethook,\n" +
61                "                stop, next, previous, rewind, recordm fast-forword.\n" +
62                "media remote-display: monitor remote display updates.\n"
63        );
64    }
65
66    public void onRun() throws Exception {
67        mAudioService = IAudioService.Stub.asInterface(ServiceManager.checkService(
68                Context.AUDIO_SERVICE));
69        if (mAudioService == null) {
70            System.err.println(NO_SYSTEM_ERROR_CODE);
71            throw new AndroidException("Can't connect to audio service; is the system running?");
72        }
73
74        String op = nextArgRequired();
75
76        if (op.equals("dispatch")) {
77            runDispatch();
78        } else if (op.equals("remote-display")) {
79            runRemoteDisplay();
80        } else {
81            showError("Error: unknown command '" + op + "'");
82            return;
83        }
84    }
85
86    private void sendMediaKey(KeyEvent event) {
87        try {
88            mAudioService.dispatchMediaKeyEvent(event);
89        } catch (RemoteException e) {
90        }
91    }
92
93    private void runDispatch() throws Exception {
94        String cmd = nextArgRequired();
95        int keycode;
96        if ("play".equals(cmd)) {
97            keycode = KeyEvent.KEYCODE_MEDIA_PLAY;
98        } else if ("pause".equals(cmd)) {
99            keycode = KeyEvent.KEYCODE_MEDIA_PAUSE;
100        } else if ("play-pause".equals(cmd)) {
101            keycode = KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE;
102        } else if ("mute".equals(cmd)) {
103            keycode = KeyEvent.KEYCODE_MUTE;
104        } else if ("headsethook".equals(cmd)) {
105            keycode = KeyEvent.KEYCODE_HEADSETHOOK;
106        } else if ("stop".equals(cmd)) {
107            keycode = KeyEvent.KEYCODE_MEDIA_STOP;
108        } else if ("next".equals(cmd)) {
109            keycode = KeyEvent.KEYCODE_MEDIA_NEXT;
110        } else if ("previous".equals(cmd)) {
111            keycode = KeyEvent.KEYCODE_MEDIA_PREVIOUS;
112        } else if ("rewind".equals(cmd)) {
113            keycode = KeyEvent.KEYCODE_MEDIA_REWIND;
114        } else if ("record".equals(cmd)) {
115            keycode = KeyEvent.KEYCODE_MEDIA_RECORD;
116        } else if ("fast-forward".equals(cmd)) {
117            keycode = KeyEvent.KEYCODE_MEDIA_FAST_FORWARD;
118        } else {
119            showError("Error: unknown dispatch code '" + cmd + "'");
120            return;
121        }
122
123        final long now = SystemClock.uptimeMillis();
124        sendMediaKey(new KeyEvent(now, now, KeyEvent.ACTION_DOWN, keycode, 0, 0,
125                KeyCharacterMap.VIRTUAL_KEYBOARD, 0, 0, InputDevice.SOURCE_KEYBOARD));
126        sendMediaKey(new KeyEvent(now, now, KeyEvent.ACTION_UP, keycode, 0, 0,
127                KeyCharacterMap.VIRTUAL_KEYBOARD, 0, 0, InputDevice.SOURCE_KEYBOARD));
128    }
129
130    class RemoteDisplayMonitor extends IRemoteControlDisplay.Stub {
131        RemoteDisplayMonitor() {
132        }
133
134
135        @Override
136        public void setCurrentClientId(int clientGeneration, PendingIntent clientMediaIntent,
137                boolean clearing) {
138            System.out.println("New client: id=" + clientGeneration
139                    + " intent=" + clientMediaIntent + " clearing=" + clearing);
140        }
141
142        @Override
143        public void setEnabled(boolean enabled) {
144            System.out.println("New enable state= " + (enabled ? "enabled" : "disabled"));
145        }
146
147        @Override
148        public void setPlaybackState(int generationId, int state, long stateChangeTimeMs,
149                long currentPosMs, float speed) {
150            System.out.println("New state: id=" + generationId + " state=" + state
151                    + " time=" + stateChangeTimeMs + " pos=" + currentPosMs + " speed=" + speed);
152        }
153
154        @Override
155        public void setTransportControlInfo(int generationId, int transportControlFlags,
156                int posCapabilities) {
157            System.out.println("New control info: id=" + generationId
158                    + " flags=0x" + Integer.toHexString(transportControlFlags)
159                    + " cap=0x" + Integer.toHexString(posCapabilities));
160        }
161
162        @Override
163        public void setMetadata(int generationId, Bundle metadata) {
164            System.out.println("New metadata: id=" + generationId
165                    + " data=" + metadata);
166        }
167
168        @Override
169        public void setArtwork(int generationId, Bitmap artwork) {
170            System.out.println("New artwork: id=" + generationId
171                    + " art=" + artwork);
172        }
173
174        @Override
175        public void setAllMetadata(int generationId, Bundle metadata, Bitmap artwork) {
176            System.out.println("New metadata+artwork: id=" + generationId
177                    + " data=" + metadata + " art=" + artwork);
178        }
179
180        void printUsageMessage() {
181            System.out.println("Monitoring remote control displays...  available commands:");
182            System.out.println("(q)uit: finish monitoring");
183        }
184
185        void run() throws RemoteException {
186            printUsageMessage();
187
188            mAudioService.registerRemoteControlDisplay(this, 0, 0);
189
190            try {
191                InputStreamReader converter = new InputStreamReader(System.in);
192                BufferedReader in = new BufferedReader(converter);
193                String line;
194
195                while ((line = in.readLine()) != null) {
196                    boolean addNewline = true;
197                    if (line.length() <= 0) {
198                        addNewline = false;
199                    } else if ("q".equals(line) || "quit".equals(line)) {
200                        break;
201                    } else {
202                        System.out.println("Invalid command: " + line);
203                    }
204
205                    synchronized (this) {
206                        if (addNewline) {
207                            System.out.println("");
208                        }
209                        printUsageMessage();
210                    }
211                }
212
213            } catch (IOException e) {
214                e.printStackTrace();
215            } finally {
216                mAudioService.unregisterRemoteControlDisplay(this);
217            }
218        }
219    }
220
221    private void runRemoteDisplay() throws Exception {
222        RemoteDisplayMonitor monitor = new RemoteDisplayMonitor();
223        monitor.run();
224    }
225}
226