| /* |
| * Copyright (C) 2015 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package android.media.midi; |
| |
| import android.app.Service; |
| import android.content.Context; |
| import android.content.Intent; |
| import android.os.IBinder; |
| import android.os.RemoteException; |
| import android.os.ServiceManager; |
| import android.util.Log; |
| |
| /** |
| * A service that implements a virtual MIDI device. |
| * Subclasses must implement the {@link #onGetInputPortReceivers} method to provide a |
| * list of {@link MidiReceiver}s to receive data sent to the device's input ports. |
| * Similarly, subclasses can call {@link #getOutputPortReceivers} to fetch a list |
| * of {@link MidiReceiver}s for sending data out the output ports. |
| * |
| * <p>To extend this class, you must declare the service in your manifest file with |
| * an intent filter with the {@link #SERVICE_INTERFACE} action |
| * and meta-data to describe the virtual device. |
| For example:</p> |
| * <pre> |
| * <service android:name=".VirtualDeviceService" |
| * android:label="@string/service_name"> |
| * <intent-filter> |
| * <action android:name="android.media.midi.MidiDeviceService" /> |
| * </intent-filter> |
| * <meta-data android:name="android.media.midi.MidiDeviceService" |
| android:resource="@xml/device_info" /> |
| * </service></pre> |
| */ |
| abstract public class MidiDeviceService extends Service { |
| private static final String TAG = "MidiDeviceService"; |
| |
| public static final String SERVICE_INTERFACE = "android.media.midi.MidiDeviceService"; |
| |
| private IMidiManager mMidiManager; |
| private MidiDeviceServer mServer; |
| private MidiDeviceInfo mDeviceInfo; |
| |
| private final MidiDeviceServer.Callback mCallback = new MidiDeviceServer.Callback() { |
| @Override |
| public void onDeviceStatusChanged(MidiDeviceServer server, MidiDeviceStatus status) { |
| MidiDeviceService.this.onDeviceStatusChanged(status); |
| } |
| |
| @Override |
| public void onClose() { |
| MidiDeviceService.this.onClose(); |
| } |
| }; |
| |
| @Override |
| public void onCreate() { |
| mMidiManager = IMidiManager.Stub.asInterface( |
| ServiceManager.getService(Context.MIDI_SERVICE)); |
| MidiDeviceServer server; |
| try { |
| MidiDeviceInfo deviceInfo = mMidiManager.getServiceDeviceInfo(getPackageName(), |
| this.getClass().getName()); |
| if (deviceInfo == null) { |
| Log.e(TAG, "Could not find MidiDeviceInfo for MidiDeviceService " + this); |
| return; |
| } |
| mDeviceInfo = deviceInfo; |
| MidiReceiver[] inputPortReceivers = onGetInputPortReceivers(); |
| if (inputPortReceivers == null) { |
| inputPortReceivers = new MidiReceiver[0]; |
| } |
| server = new MidiDeviceServer(mMidiManager, inputPortReceivers, deviceInfo, mCallback); |
| } catch (RemoteException e) { |
| Log.e(TAG, "RemoteException in IMidiManager.getServiceDeviceInfo"); |
| server = null; |
| } |
| mServer = server; |
| } |
| |
| /** |
| * Returns an array of {@link MidiReceiver} for the device's input ports. |
| * Subclasses must override this to provide the receivers which will receive |
| * data sent to the device's input ports. An empty array should be returned if |
| * the device has no input ports. |
| * @return array of MidiReceivers |
| */ |
| abstract public MidiReceiver[] onGetInputPortReceivers(); |
| |
| /** |
| * Returns an array of {@link MidiReceiver} for the device's output ports. |
| * These can be used to send data out the device's output ports. |
| * @return array of MidiReceivers |
| */ |
| public final MidiReceiver[] getOutputPortReceivers() { |
| if (mServer == null) { |
| return null; |
| } else { |
| return mServer.getOutputPortReceivers(); |
| } |
| } |
| |
| /** |
| * returns the {@link MidiDeviceInfo} instance for this service |
| * @return our MidiDeviceInfo |
| */ |
| public final MidiDeviceInfo getDeviceInfo() { |
| return mDeviceInfo; |
| } |
| |
| /** |
| * Called to notify when an our {@link MidiDeviceStatus} has changed |
| * @param status the number of the port that was opened |
| */ |
| public void onDeviceStatusChanged(MidiDeviceStatus status) { |
| } |
| |
| /** |
| * Called to notify when our device has been closed by all its clients |
| */ |
| public void onClose() { |
| } |
| |
| @Override |
| public IBinder onBind(Intent intent) { |
| if (SERVICE_INTERFACE.equals(intent.getAction()) && mServer != null) { |
| return mServer.getBinderInterface().asBinder(); |
| } else { |
| return null; |
| } |
| } |
| } |