/*
* Copyright (C) 2012 Andrew Neal
* Copyright (C) 2014 The CyanogenMod Project
* Copyright (C) 2015 Naman Dwivedi
*
* 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 com.wm.remusic.service;
import android.app.Activity;
import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.Intent;
import android.content.ServiceConnection;
import android.database.Cursor;
import android.net.Uri;
import android.os.IBinder;
import android.os.RemoteException;
import android.provider.MediaStore;
import android.util.Log;
import android.widget.Toast;
import com.wm.remusic.MediaAidlInterface;
import com.wm.remusic.R;
import com.wm.remusic.info.MusicInfo;
import java.util.Arrays;
import java.util.HashMap;
import java.util.WeakHashMap;
public class MusicPlayer {
private static final WeakHashMap<Context, ServiceBinder> mConnectionMap;
private static final long[] sEmptyList;
public static MediaAidlInterface mService = null;
private static ContentValues[] mContentValuesCache = null;
static {
mConnectionMap = new WeakHashMap<Context, ServiceBinder>();
sEmptyList = new long[0];
}
public static final ServiceToken bindToService(final Context context,
final ServiceConnection callback) {
Activity realActivity = ((Activity) context).getParent();
if (realActivity == null) {
realActivity = (Activity) context;
}
final ContextWrapper contextWrapper = new ContextWrapper(realActivity);
contextWrapper.startService(new Intent(contextWrapper, MediaService.class));
final ServiceBinder binder = new ServiceBinder(callback,
contextWrapper.getApplicationContext());
if (contextWrapper.bindService(
new Intent().setClass(contextWrapper, MediaService.class), binder, 0)) {
mConnectionMap.put(contextWrapper, binder);
return new ServiceToken(contextWrapper);
}
return null;
}
public static void unbindFromService(final ServiceToken token) {
if (token == null) {
return;
}
final ContextWrapper mContextWrapper = token.mWrappedContext;
final ServiceBinder mBinder = mConnectionMap.remove(mContextWrapper);
if (mBinder == null) {
return;
}
mContextWrapper.unbindService(mBinder);
if (mConnectionMap.isEmpty()) {
mService = null;
}
}
public static final boolean isPlaybackServiceConnected() {
return mService != null;
}
public static void next() {
try {
if (mService != null) {
mService.next();
}
} catch (final RemoteException ignored) {
}
}
public static void initPlaybackServiceWithSettings(final Context context) {
setShowAlbumArtOnLockscreen(true);
}
public static void setShowAlbumArtOnLockscreen(final boolean enabled) {
try {
if (mService != null) {
mService.setLockscreenAlbumArt(enabled);
}
} catch (final RemoteException ignored) {
}
}
public static void asyncNext(final Context context) {
final Intent previous = new Intent(context, MediaService.class);
previous.setAction(MediaService.NEXT_ACTION);
context.startService(previous);
}
public static void previous(final Context context, final boolean force) {
final Intent previous = new Intent(context, MediaService.class);
if (force) {
previous.setAction(MediaService.PREVIOUS_FORCE_ACTION);
} else {
previous.setAction(MediaService.PREVIOUS_ACTION);
}
context.startService(previous);
}
public static void playOrPause() {
try {
if (mService != null) {
if (mService.isPlaying()) {
mService.pause();
} else {
mService.play();
}
}
} catch (final Exception ignored) {
}
}
public static boolean isTrackLocal() {
try {
if (mService != null) {
return mService.isTrackLocal();
}
} catch (RemoteException e) {
e.printStackTrace();
}
return false;
}
public static void cycleRepeat() {
try {
if (mService != null) {
if (mService.getShuffleMode() == MediaService.SHUFFLE_NORMAL) {
mService.setShuffleMode(MediaService.SHUFFLE_NONE);
mService.setRepeatMode(MediaService.REPEAT_CURRENT);
return;
} else {
switch (mService.getRepeatMode()) {
case MediaService.REPEAT_CURRENT:
mService.setRepeatMode(MediaService.REPEAT_ALL);
break;
case MediaService.REPEAT_ALL:
mService.setShuffleMode(MediaService.SHUFFLE_NORMAL);
// if (mService.getShuffleMode() != MediaService.SHUFFLE_NONE) {
// mService.setShuffleMode(MediaService.SHUFFLE_NONE);
// }
break;
}
}
}
} catch (final RemoteException ignored) {
}
}
public static void cycleShuffle() {
try {
if (mService != null) {
switch (mService.getShuffleMode()) {
case MediaService.SHUFFLE_NONE:
mService.setShuffleMode(MediaService.SHUFFLE_NORMAL);
if (mService.getRepeatMode() == MediaService.REPEAT_CURRENT) {
mService.setRepeatMode(MediaService.REPEAT_ALL);
}
break;
case MediaService.SHUFFLE_NORMAL:
mService.setShuffleMode(MediaService.SHUFFLE_NONE);
break;
// case MediaService.SHUFFLE_AUTO:
// mService.setShuffleMode(MediaService.SHUFFLE_NONE);
// break;
default:
break;
}
}
} catch (final RemoteException ignored) {
}
}
public static final boolean isPlaying() {
if (mService != null) {
try {
return mService.isPlaying();
} catch (final RemoteException ignored) {
}
}
return false;
}
public static final int getShuffleMode() {
if (mService != null) {
try {
return mService.getShuffleMode();
} catch (final RemoteException ignored) {
}
}
return 0;
}
public static void setShuffleMode(int mode) {
try {
if (mService != null) {
mService.setShuffleMode(mode);
}
} catch (RemoteException ignored) {
}
}
public static final int getRepeatMode() {
if (mService != null) {
try {
return mService.getRepeatMode();
} catch (final RemoteException ignored) {
}
}
return 0;
}
public static final String getTrackName() {
if (mService != null) {
try {
return mService.getTrackName();
} catch (final RemoteException ignored) {
}
}
return null;
}
public static final String getArtistName() {
if (mService != null) {
try {
return mService.getArtistName();
} catch (final RemoteException ignored) {
}
}
return null;
}
public static final String getAlbumName() {
if (mService != null) {
try {
return mService.getAlbumName();
} catch (final RemoteException ignored) {
}
}
return null;
}
public static final String getAlbumPath() {
if (mService != null) {
try {
return mService.getAlbumPath();
} catch (final RemoteException ignored) {
}
}
return null;
}
public static final String[] getAlbumPathAll() {
if (mService != null) {
try {
return mService.getAlbumPathtAll();
} catch (final RemoteException ignored) {
}
}
return null;
}
public static final long getCurrentAlbumId() {
if (mService != null) {
try {
return mService.getAlbumId();
} catch (final RemoteException ignored) {
}
}
return -1;
}
public static final long getCurrentAudioId() {
if (mService != null) {
try {
return mService.getAudioId();
} catch (final RemoteException ignored) {
}
}
return -1;
}
public static final MusicTrack getCurrentTrack() {
if (mService != null) {
try {
return mService.getCurrentTrack();
} catch (final RemoteException ignored) {
}
}
return null;
}
public static final MusicTrack getTrack(int index) {
if (mService != null) {
try {
return mService.getTrack(index);
} catch (final RemoteException ignored) {
}
}
return null;
}
public static final long getNextAudioId() {
if (mService != null) {
try {
return mService.getNextAudioId();
} catch (final RemoteException ignored) {
}
}
return -1;
}
public static final long getPreviousAudioId() {
if (mService != null) {
try {
return mService.getPreviousAudioId();
} catch (final RemoteException ignored) {
}
}
return -1;
}
public static final long getCurrentArtistId() {
if (mService != null) {
try {
return mService.getArtistId();
} catch (final RemoteException ignored) {
}
}
return -1;
}
public static final int getAudioSessionId() {
if (mService != null) {
try {
return mService.getAudioSessionId();
} catch (final RemoteException ignored) {
}
}
return -1;
}
public static final long[] getQueue() {
try {
if (mService != null) {
return mService.getQueue();
} else {
}
} catch (final RemoteException ignored) {
}
return sEmptyList;
}
public static final HashMap<Long, MusicInfo> getPlayinfos() {
try {
if (mService != null) {
return (HashMap<Long, MusicInfo>) mService.getPlayinfos();
} else {
}
} catch (final RemoteException ignored) {
}
return null;
}
public static final long getQueueItemAtPosition(int position) {
try {
if (mService != null) {
return mService.getQueueItemAtPosition(position);
} else {
}
} catch (final RemoteException ignored) {
}
return -1;
}
public static final int getQueueSize() {
try {
if (mService != null) {
return mService.getQueueSize();
} else {
}
} catch (final RemoteException ignored) {
}
return 0;
}
public static final int getQueuePosition() {
try {
if (mService != null) {
return mService.getQueuePosition();
}
} catch (final RemoteException ignored) {
}
return 0;
}
public static void setQueuePosition(final int position) {
if (mService != null) {
try {
mService.setQueuePosition(position);
} catch (final RemoteException ignored) {
}
}
}
public static final int getQueueHistorySize() {
if (mService != null) {
try {
return mService.getQueueHistorySize();
} catch (final RemoteException ignored) {
}
}
return 0;
}
public static final int getQueueHistoryPosition(int position) {
if (mService != null) {
try {
return mService.getQueueHistoryPosition(position);
} catch (final RemoteException ignored) {
}
}
return -1;
}
public static final int[] getQueueHistoryList() {
if (mService != null) {
try {
return mService.getQueueHistoryList();
} catch (final RemoteException ignored) {
}
}
return null;
}
public static final int removeTrack(final long id) {
try {
if (mService != null) {
return mService.removeTrack(id);
}
} catch (final RemoteException ingored) {
}
return 0;
}
public static final boolean removeTrackAtPosition(final long id, final int position) {
try {
if (mService != null) {
return mService.removeTrackAtPosition(id, position);
}
} catch (final RemoteException ingored) {
}
return false;
}
public static void moveQueueItem(final int from, final int to) {
try {
if (mService != null) {
mService.moveQueueItem(from, to);
} else {
}
} catch (final RemoteException ignored) {
}
}
public static synchronized void playAll(final HashMap<Long, MusicInfo> infos, final long[] list, int position, final boolean forceShuffle) {
if (list == null || list.length == 0 || mService == null) {
return;
}
try {
if (forceShuffle) {
mService.setShuffleMode(MediaService.SHUFFLE_NORMAL);
}
final long currentId = mService.getAudioId();
long playId = list[position];
Log.e("currentId", currentId + "");
final int currentQueuePosition = getQueuePosition();
if (position != -1) {
final long[] playlist = getQueue();
if (Arrays.equals(list, playlist)) {
if (currentQueuePosition == position && currentId == list[position]) {
mService.play();
return;
} else {
mService.setQueuePosition(position);
return;
}
}
}
if (position < 0) {
position = 0;
}
mService.open(infos, list, forceShuffle ? -1 : position);
mService.play();
Log.e("time", System.currentTimeMillis() + "");
} catch (final RemoteException ignored) {
} catch (IllegalStateException e) {
e.printStackTrace();
}
}
public static void playNext(Context context, final HashMap<Long, MusicInfo> map, final long[] list) {
if (mService == null) {
return;
}
try {
int current = -1;
long[] result = list;
for (int i = 0; i < list.length; i++) {
if (MusicPlayer.getCurrentAudioId() == list[i]) {
current = i;
} else {
MusicPlayer.removeTrack(list[i]);
}
}
// if( current != -1){
// ArrayList lists = new ArrayList();
// for(int i = 0; i<list.length;i++){
// if(i != current){
// lists.add(list[i]);
// }
// }
// result = new long[list.length - 1];
// for(int i = 0;i<lists.size();i++){
// result[i] = (long) lists.get(i);
// }
// }
mService.enqueue(list, map, MediaService.NEXT);
Toast.makeText(context, R.string.next_play, Toast.LENGTH_SHORT).show();
} catch (final RemoteException ignored) {
}
}
public static String getPath() {
if (mService == null) {
return null;
}
try {
return mService.getPath();
} catch (Exception e) {
}
return null;
}
public static void stop() {
try {
mService.stop();
} catch (Exception e) {
}
}
public static final int getSongCountForAlbumInt(final Context context, final long id) {
int songCount = 0;
if (id == -1) {
return songCount;
}
Uri uri = ContentUris.withAppendedId(MediaStore.Audio.Albums.EXTERNAL_CONTENT_URI, id);
Cursor cursor = context.getContentResolver().query(uri,
new String[]{MediaStore.Audio.AlbumColumns.NUMBER_OF_SONGS}, null, null, null);
if (cursor != null) {
cursor.moveToFirst();
if (!cursor.isAfterLast()) {
if (!cursor.isNull(0)) {
songCount = cursor.getInt(0);
}
}
cursor.close();
cursor = null;
}
return songCount;
}
public static final String getReleaseDateForAlbum(final Context context, final long id) {
if (id == -1) {
return null;
}
Uri uri = ContentUris.withAppendedId(MediaStore.Audio.Albums.EXTERNAL_CONTENT_URI, id);
Cursor cursor = context.getContentResolver().query(uri, new String[]{
MediaStore.Audio.AlbumColumns.FIRST_YEAR
}, null, null, null);
String releaseDate = null;
if (cursor != null) {
cursor.moveToFirst();
if (!cursor.isAfterLast()) {
releaseDate = cursor.getString(0);
}
cursor.close();
cursor = null;
}
return releaseDate;
}
public static void seek(final long position) {
if (mService != null) {
try {
mService.seek(position);
} catch (final RemoteException ignored) {
}
}
}
public static void seekRelative(final long deltaInMs) {
if (mService != null) {
try {
mService.seekRelative(deltaInMs);
} catch (final RemoteException ignored) {
} catch (final IllegalStateException ignored) {
}
}
}
public static final long position() {
if (mService != null) {
try {
return mService.position();
} catch (final RemoteException ignored) {
} catch (final IllegalStateException ex) {
}
}
return 0;
}
public static final int secondPosition() {
if (mService != null) {
try {
return mService.secondPosition();
} catch (final RemoteException ignored) {
} catch (final IllegalStateException ex) {
}
}
return 0;
}
public static final long duration() {
if (mService != null) {
try {
return mService.duration();
} catch (final RemoteException ignored) {
} catch (final IllegalStateException ignored) {
}
}
return 0;
}
public static void clearQueue() {
try {
if(mService != null)
mService.removeTracks(0, Integer.MAX_VALUE);
} catch (final RemoteException ignored) {
}
}
public static void addToQueue(final Context context, final long[] list, long sourceId) {
if (mService == null) {
return;
}
try {
mService.enqueue(list, null, MediaService.LAST);
//final String message = makeLabel(context, R.plurals.NNNtrackstoqueue, list.length);
//Toast.makeText(context, message, Toast.LENGTH_SHORT).show();
} catch (final RemoteException ignored) {
}
}
public static void addToPlaylist(final Context context, final long[] ids, final long playlistid) {
final int size = ids.length;
final ContentResolver resolver = context.getContentResolver();
final String[] projection = new String[]{
"max(" + "play_order" + ")",
};
final Uri uri = MediaStore.Audio.Playlists.Members.getContentUri("external", playlistid);
Cursor cursor = null;
int base = 0;
try {
cursor = resolver.query(uri, projection, null, null, null);
if (cursor != null && cursor.moveToFirst()) {
base = cursor.getInt(0) + 1;
}
} finally {
if (cursor != null) {
cursor.close();
cursor = null;
}
}
int numinserted = 0;
for (int offSet = 0; offSet < size; offSet += 1000) {
makeInsertItems(ids, offSet, 1000, base);
numinserted += resolver.bulkInsert(uri, mContentValuesCache);
}
}
public static void makeInsertItems(final long[] ids, final int offset, int len, final int base) {
if (offset + len > ids.length) {
len = ids.length - offset;
}
if (mContentValuesCache == null || mContentValuesCache.length != len) {
mContentValuesCache = new ContentValues[len];
}
for (int i = 0; i < len; i++) {
if (mContentValuesCache[i] == null) {
mContentValuesCache[i] = new ContentValues();
}
mContentValuesCache[i].put(MediaStore.Audio.Playlists.Members.PLAY_ORDER, base + offset + i);
mContentValuesCache[i].put(MediaStore.Audio.Playlists.Members.AUDIO_ID, ids[offset + i]);
}
}
public static final long createPlaylist(final Context context, final String name) {
if (name != null && name.length() > 0) {
final ContentResolver resolver = context.getContentResolver();
final String[] projection = new String[]{
MediaStore.Audio.PlaylistsColumns.NAME
};
final String selection = MediaStore.Audio.PlaylistsColumns.NAME + " = '" + name + "'";
Cursor cursor = resolver.query(MediaStore.Audio.Playlists.EXTERNAL_CONTENT_URI,
projection, selection, null, null);
if (cursor.getCount() <= 0) {
final ContentValues values = new ContentValues(1);
values.put(MediaStore.Audio.PlaylistsColumns.NAME, name);
final Uri uri = resolver.insert(MediaStore.Audio.Playlists.EXTERNAL_CONTENT_URI,
values);
return Long.parseLong(uri.getLastPathSegment());
}
if (cursor != null) {
cursor.close();
cursor = null;
}
return -1;
}
return -1;
}
public static void exitService() {
// if (mService == null) {
// return;
// }
try {
mConnectionMap.clear();
Log.e("exitmp", "Destroying service");
mService.exit();
} catch (Exception e) {
}
}
public static void timing(int time) {
if (mService == null) {
return;
}
try {
mService.timing(time);
} catch (Exception e) {
}
}
public static final class ServiceBinder implements ServiceConnection {
private final ServiceConnection mCallback;
private final Context mContext;
public ServiceBinder(final ServiceConnection callback, final Context context) {
mCallback = callback;
mContext = context;
}
@Override
public void onServiceConnected(final ComponentName className, final IBinder service) {
mService = MediaAidlInterface.Stub.asInterface(service);
if (mCallback != null) {
mCallback.onServiceConnected(className, service);
}
initPlaybackServiceWithSettings(mContext);
}
@Override
public void onServiceDisconnected(final ComponentName className) {
if (mCallback != null) {
mCallback.onServiceDisconnected(className);
}
mService = null;
}
}
public static final class ServiceToken {
public ContextWrapper mWrappedContext;
public ServiceToken(final ContextWrapper context) {
mWrappedContext = context;
}
}
}