/* * Copyright (C) 2014 AChep@xda <artemchep@gmail.com> * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * MA 02110-1301, USA. */ package com.achep.acdisplay.services; import android.annotation.SuppressLint; import android.content.Context; import android.content.Intent; import android.media.AudioManager; import android.media.RemoteController; import android.os.Binder; import android.os.IBinder; import android.service.notification.NotificationListenerService; import android.service.notification.StatusBarNotification; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.util.Log; import com.achep.acdisplay.App; import com.achep.acdisplay.R; import com.achep.acdisplay.notifications.NotificationListener; import com.achep.base.AppHeap; import com.achep.base.Device; /** * Created by achep on 07.06.14. * * @author Artem Chepurnoy */ @SuppressWarnings("deprecation") // RemoteController is completely outdated. @SuppressLint("NewApi") // RemoteController is a new thing. public class MediaService extends NotificationListenerService implements RemoteController.OnClientUpdateListener { private static final String TAG = "MediaService"; public static MediaService sService; private final NotificationListener mNotificationListener = NotificationListener.newInstance(); private final IBinder mBinder = new B(); private AudioManager mAudioManager; private boolean mRegistered; private RemoteController mRemoteController; private RemoteController.OnClientUpdateListener mExternalListener; public class B extends Binder { public MediaService getService() { return MediaService.this; } } private static boolean isRemoteControllerSupported() { return Device.hasKitKatApi() && !Device.hasLollipopApi(); } @Override public IBinder onBind(@NonNull Intent intent) { switch (intent.getAction()) { case App.ACTION_BIND_MEDIA_CONTROL_SERVICE: if (!isRemoteControllerSupported()) { // Should never happen normally. throw new RuntimeException("Not supported Android version!"); } return mBinder; default: sService = this; mNotificationListener.onListenerBind(this); return super.onBind(intent); } } @Override public boolean onUnbind(@NonNull Intent intent) { switch (intent.getAction()) { case App.ACTION_BIND_MEDIA_CONTROL_SERVICE: break; default: mNotificationListener.onListenerUnbind(this); sService = null; break; } return super.onUnbind(intent); } //-- HANDLING NOTIFICATIONS ----------------------------------------------- @Override public void onListenerConnected() { super.onListenerConnected(); mNotificationListener.onListenerConnected(this); } @Override public void onNotificationPosted(@NonNull StatusBarNotification notification) { mNotificationListener.onNotificationPosted(this, notification); } @Override public void onNotificationRemoved(@NonNull StatusBarNotification notification) { mNotificationListener.onNotificationRemoved(this, notification); } //-- REMOTE CONTROLLER ---------------------------------------------------- @Override public void onCreate() { if (isRemoteControllerSupported()) { mRemoteController = new RemoteController(this, this); mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE); } } @Override public void onDestroy() { if (isRemoteControllerSupported()) { setRemoteControllerDisabled(); } AppHeap.getRefWatcher().watch(this); } public void setRemoteControllerEnabled() { if (mRegistered) { return; } mRegistered = mAudioManager.registerRemoteController(mRemoteController); if (mRegistered) { final int size = getResources().getDimensionPixelSize(R.dimen.media_artwork_size); mRemoteController.setArtworkConfiguration(size, size); // mRemoteController.setSynchronizationMode(RemoteController.POSITION_SYNCHRONIZATION_CHECK); } else { Log.e(TAG, "Error while registering RemoteController!"); } } public void setRemoteControllerDisabled() { if (!mRegistered) { return; } mAudioManager.unregisterRemoteController(mRemoteController); mRegistered = false; } public RemoteController getRemoteController() { return mRemoteController; } /** * Sets up external callback for client update events. */ public void setClientUpdateListener(@Nullable RemoteController.OnClientUpdateListener listener) { mExternalListener = listener; } @Override public void onClientChange(boolean clearing) { if (mExternalListener != null) { mExternalListener.onClientChange(clearing); } } @Override public void onClientPlaybackStateUpdate(int state) { if (mExternalListener != null) { mExternalListener.onClientPlaybackStateUpdate(state); } } @Override public void onClientPlaybackStateUpdate(int state, long stateChangeTimeMs, long currentPosMs, float speed) { if (mExternalListener != null) { mExternalListener.onClientPlaybackStateUpdate(state, stateChangeTimeMs, currentPosMs, speed); } } @Override public void onClientTransportControlUpdate(int transportControlFlags) { if (mExternalListener != null) { mExternalListener.onClientTransportControlUpdate(transportControlFlags); } } @Override public void onClientMetadataUpdate(RemoteController.MetadataEditor metadataEditor) { if (mExternalListener != null) { mExternalListener.onClientMetadataUpdate(metadataEditor); } } }