/* * Copyright (c) 2013, Sorokin Alexander (uas.sorokin@gmail.com) * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * 3. The names of the authors may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.uas.media.aimp.player; import android.app.Service; import android.content.Intent; import android.os.Binder; import android.os.IBinder; import java.util.HashMap; import java.util.Map; import java.util.Timer; import java.util.TimerTask; /** * User: uas.sorokin@gmail.com */ public class SyncService extends Service { public interface ErrorsCallback { void onException(Exception ex); } private IBinder mBinder; private Map<AimpPlayer, Timer> mTimers; private Map<AimpPlayer, ErrorsCallback> mErrorCallbacks; @Override public void onCreate() { super.onCreate(); mBinder = new LocalBinder(); mTimers = new HashMap<AimpPlayer, Timer>(); mErrorCallbacks = new HashMap<AimpPlayer, ErrorsCallback>(); } @Override public int onStartCommand(final Intent intent, int flags, int startId) { startForeground(0, null); return START_STICKY_COMPATIBILITY; } @Override public void onDestroy() { super.onDestroy(); for (Map.Entry<AimpPlayer, Timer> e: mTimers.entrySet()) { cancelSync(e.getKey()); } stopForeground(true); } @Override public IBinder onBind(Intent intent) { return mBinder; } public void submitSync(AimpPlayer player, SyncParams syncParams, ErrorsCallback callback) { Timer t = new Timer(); mTimers.put(player, t); mErrorCallbacks.put(player, callback); Updaters updaters = new Updaters(player); t.scheduleAtFixedRate( updaters.getPlaylistsUpdater(), 0, syncParams.getPlaylistsUpdatePeriod()); t.scheduleAtFixedRate( updaters.getPlayStateUpdater(), 0, syncParams.getPlaystateUpdatePeriod()); t.scheduleAtFixedRate( updaters.getCommonsUpdater(), 0, syncParams.getOthersUpdatePeriod()); } public void cancelSync(AimpPlayer player) { Timer t = mTimers.remove(player); t.cancel(); t.purge(); mErrorCallbacks.remove(player); } class Updaters { private AimpPlayer mPlayer; private AimpPlayerPackageLoaders mLoaders; Updaters(AimpPlayer player) { mPlayer = player; mLoaders = new AimpPlayerPackageLoaders(mPlayer); } protected void notifyException(Exception ex) { ErrorsCallback callback = mErrorCallbacks.get(mPlayer); if (callback != null) { callback.onException(ex); } } public TimerTask getPlayStateUpdater() { return new TimerTask() { @Override public void run() { try { if (mPlayer.hasPlaylists()) { mLoaders.loadSongPlayPosition(); mLoaders.loadCommons(); mLoaders.loadCurrentSong(); } } catch (Exception ex) { notifyException(ex); } } }; } public TimerTask getPlaylistsUpdater() { return new TimerTask() { @Override public void run() { try { mLoaders.loadPlaylists(AimpPlayerPackageLoaders.CHECK_HASH_YES); mLoaders.loadCurrentSong(); mLoaders.loadSongPlayPosition(); } catch (Exception ex) { notifyException(ex); } } }; } public TimerTask getCommonsUpdater() { return new TimerTask() { @Override public void run() { try { mLoaders.loadCommons(); mLoaders.loadVolume(); } catch (Exception ex) { notifyException(ex); } } }; } } class LocalBinder extends Binder { public SyncService getService() { return SyncService.this; } } }