diff options
Diffstat (limited to 'android/src')
8 files changed, 399 insertions, 2 deletions
diff --git a/android/src/org/rockbox/Helper/RunForegroundManager.java b/android/src/org/rockbox/Helper/RunForegroundManager.java index 6c5f2deb14..99ac66b686 100644 --- a/android/src/org/rockbox/Helper/RunForegroundManager.java +++ b/android/src/org/rockbox/Helper/RunForegroundManager.java @@ -11,6 +11,7 @@ import android.app.NotificationManager; import android.app.PendingIntent; import android.app.Service; import android.content.Intent; +import android.net.Uri; import android.util.Log; import android.widget.RemoteViews; @@ -92,6 +93,19 @@ public class RunForegroundManager else mNotification.tickerText = title+" - "+artist; mNM.notify(R.string.notification, mNotification); + + Intent widgetUpdate = new Intent("org.rockbox.TrackUpdateInfo"); + widgetUpdate.putExtra("title", title); + widgetUpdate.putExtra("artist", artist); + widgetUpdate.putExtra("album", album); + mCurrentService.sendBroadcast(widgetUpdate); + } + + public void finishNotification() + { + Log.d("Rockbox", "TrackFinish"); + Intent widgetUpdate = new Intent("org.rockbox.TrackFinish"); + mCurrentService.sendBroadcast(widgetUpdate); } private interface IRunForeground diff --git a/android/src/org/rockbox/RockboxFramebuffer.java b/android/src/org/rockbox/RockboxFramebuffer.java index 18415562f3..05d2b11184 100644 --- a/android/src/org/rockbox/RockboxFramebuffer.java +++ b/android/src/org/rockbox/RockboxFramebuffer.java @@ -147,5 +147,5 @@ public class RockboxFramebuffer extends View private native void post_update_done(); private native void set_lcd_active(int active); private native void touchHandler(boolean down, int x, int y); - private native boolean buttonHandler(int keycode, boolean state); + private native static boolean buttonHandler(int keycode, boolean state); } diff --git a/android/src/org/rockbox/RockboxPCM.java b/android/src/org/rockbox/RockboxPCM.java index 146e639a08..c1fecbcc15 100644 --- a/android/src/org/rockbox/RockboxPCM.java +++ b/android/src/org/rockbox/RockboxPCM.java @@ -23,9 +23,11 @@ package org.rockbox; import java.util.Arrays; +import android.content.Intent; import android.media.AudioFormat; import android.media.AudioManager; import android.media.AudioTrack; +import android.net.Uri; import android.os.Handler; import android.os.HandlerThread; import android.os.Process; @@ -80,10 +82,16 @@ public class RockboxPCM extends AudioTrack private void play_pause(boolean pause) { if (pause) { + Intent widgetUpdate = new Intent("org.rockbox.UpdateState"); + widgetUpdate.putExtra("state", "pause"); + RockboxService.get_instance().sendBroadcast(widgetUpdate); pause(); } else { + Intent widgetUpdate = new Intent("org.rockbox.UpdateState"); + widgetUpdate.putExtra("state", "play"); + RockboxService.get_instance().sendBroadcast(widgetUpdate); if (getPlayState() == AudioTrack.PLAYSTATE_STOPPED) { RockboxService.get_instance().startForeground(); @@ -114,6 +122,9 @@ public class RockboxPCM extends AudioTrack throw new IllegalStateException(e); } RockboxService.get_instance().stopForeground(); + Intent widgetUpdate = new Intent("org.rockbox.UpdateState"); + widgetUpdate.putExtra("state", "stop"); + RockboxService.get_instance().sendBroadcast(widgetUpdate); } @SuppressWarnings("unused") diff --git a/android/src/org/rockbox/RockboxService.java b/android/src/org/rockbox/RockboxService.java index 23086eae29..de90999783 100644 --- a/android/src/org/rockbox/RockboxService.java +++ b/android/src/org/rockbox/RockboxService.java @@ -43,6 +43,7 @@ import android.os.Bundle; import android.os.IBinder; import android.os.ResultReceiver; import android.util.Log; +import android.view.KeyEvent; /* This class is used as the main glue between java and c. * All access should be done through RockboxService.get_instance() for safety. @@ -76,7 +77,7 @@ public class RockboxService extends Service @Override public void onCreate() { - instance = this; + instance = this; } public static RockboxService get_instance() @@ -115,6 +116,31 @@ public class RockboxService extends Service if (!rbLibLoaded) startservice(); + if (intent != null && intent.getAction() != null) + { + Log.d("RockboxService", intent.getAction()); + if (intent.getAction().equals("org.rockbox.PlayPause")) + { + if (fb != null) + fb.onKeyUp(KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE, null); + } + else if (intent.getAction().equals("org.rockbox.Prev")) + { + if (fb != null) + fb.onKeyUp(KeyEvent.KEYCODE_MEDIA_PREVIOUS, null); + } + else if (intent.getAction().equals("org.rockbox.Next")) + { + if (fb != null) + fb.onKeyUp(KeyEvent.KEYCODE_MEDIA_NEXT, null); + } + else if (intent.getAction().equals("org.rockbox.Stop")) + { + if (fb != null) + fb.onKeyUp(KeyEvent.KEYCODE_MEDIA_STOP, null); + } + } + /* Display a notification about us starting. * We put an icon in the status bar. */ if (fg_runner == null) diff --git a/android/src/org/rockbox/widgets/RockboxWidgetConfigure.java b/android/src/org/rockbox/widgets/RockboxWidgetConfigure.java new file mode 100644 index 0000000000..82adb97126 --- /dev/null +++ b/android/src/org/rockbox/widgets/RockboxWidgetConfigure.java @@ -0,0 +1,121 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2011 Antoine Cellerier <dionoea at videolan dot org> + * + * 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 software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +package org.rockbox.widgets; + +import org.rockbox.R; + +import android.app.Activity; +import android.appwidget.AppWidgetManager; +import android.content.Context; +import android.content.Intent; +import android.content.SharedPreferences; +import android.os.Bundle; +import android.util.Log; +import android.view.View; +import android.widget.CheckBox; + + +public class RockboxWidgetConfigure extends Activity +{ + int mAppWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID; + + public RockboxWidgetConfigure() + { + super(); + } + + @Override + public void onCreate(Bundle savedInstanceState) + { + super.onCreate(savedInstanceState); + + setResult(RESULT_CANCELED); + setContentView(R.layout.appwidget_configure); + + ((CheckBox)findViewById(R.id.enable_prev)).setChecked(false); + ((CheckBox)findViewById(R.id.enable_stop)).setChecked(true); + ((CheckBox)findViewById(R.id.enable_playpause)).setChecked(true); + ((CheckBox)findViewById(R.id.enable_next)).setChecked(false); + + findViewById(R.id.confirm).setOnClickListener(mCreateWidget); + + Intent intent = getIntent(); + Bundle extras = intent.getExtras(); + if (extras != null) + mAppWidgetId = extras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID); + + if (mAppWidgetId == AppWidgetManager.INVALID_APPWIDGET_ID) + finish(); + } + + View.OnClickListener mCreateWidget = new View.OnClickListener() + { + public void onClick(View v) + { + final Context context = RockboxWidgetConfigure.this; + + WidgetPref state = new WidgetPref(); + state.enablePrev = ((CheckBox)findViewById(R.id.enable_prev)).isChecked(); + state.enableStop = ((CheckBox)findViewById(R.id.enable_stop)).isChecked(); + state.enablePlayPause = ((CheckBox)findViewById(R.id.enable_playpause)).isChecked(); + state.enableNext = ((CheckBox)findViewById(R.id.enable_next)).isChecked(); + saveWidgetPref(context, mAppWidgetId, state); + + AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context); + RockboxWidgetProvider.updateAppWidget(context, appWidgetManager, mAppWidgetId, null); + + Intent result = new Intent(); + result.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mAppWidgetId); + setResult(RESULT_OK, result); + finish(); + } + }; + + static public class WidgetPref + { + public boolean enablePrev = true; + public boolean enableStop = true; + public boolean enablePlayPause = true; + public boolean enableNext = true; + } + + static void saveWidgetPref(Context context, int appWidgetId, WidgetPref state) + { + SharedPreferences.Editor prefs = context.getSharedPreferences("org.rockbox.RockboxWidgetConfigure", 0).edit(); + prefs.putBoolean("prev"+appWidgetId, state.enablePrev); + prefs.putBoolean("stop"+appWidgetId, state.enableStop); + prefs.putBoolean("playpause"+appWidgetId, state.enablePlayPause); + prefs.putBoolean("next"+appWidgetId, state.enableNext); + prefs.commit(); + } + + static WidgetPref loadWidgetPref(Context context, int appWidgetId) + { + SharedPreferences prefs = context.getSharedPreferences("org.rockbox.RockboxWidgetConfigure", 0); + WidgetPref state = new WidgetPref(); + state.enablePrev = prefs.getBoolean("prev"+appWidgetId, true); + state.enableStop = prefs.getBoolean("stop"+appWidgetId, true); + state.enablePlayPause = prefs.getBoolean("playpause"+appWidgetId, true); + state.enableNext = prefs.getBoolean("next"+appWidgetId, true); + return state; + } +} diff --git a/android/src/org/rockbox/widgets/RockboxWidgetProvider.java b/android/src/org/rockbox/widgets/RockboxWidgetProvider.java new file mode 100644 index 0000000000..756d9f9a13 --- /dev/null +++ b/android/src/org/rockbox/widgets/RockboxWidgetProvider.java @@ -0,0 +1,171 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2011 Antoine Cellerier <dionoea at videolan dot org> + * + * 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 software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +package org.rockbox.widgets; + +import org.rockbox.R; +import org.rockbox.RockboxActivity; +import org.rockbox.RockboxService; + +import android.app.PendingIntent; +import android.appwidget.AppWidgetManager; +import android.appwidget.AppWidgetProvider; +import android.appwidget.AppWidgetProviderInfo; +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.content.pm.PackageManager; +import android.net.Uri; +import android.util.Log; +import android.view.View; +import android.view.KeyEvent; +import android.widget.RemoteViews; + +import java.util.ArrayList; + +public class RockboxWidgetProvider extends AppWidgetProvider +{ + @Override + public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) + { + final int N = appWidgetIds.length; + for (int i = 0; i < N; i++) + { + int appWidgetId = appWidgetIds[i]; + updateAppWidget(context, appWidgetManager, appWidgetId, null); + + } + } + + @Override + public void onDeleted(Context context, int[] appWidgetIds) + { + } + + @Override + public void onEnabled(Context context) + { + } + + @Override + public void onDisabled(Context context) + { + } + + @Override + public void onReceive(Context context, Intent intent) + { + String action = intent.getAction(); + if (intent.getAction().equals("org.rockbox.TrackUpdateInfo") || + intent.getAction().equals("org.rockbox.TrackFinish") || + intent.getAction().equals("org.rockbox.UpdateState")) + { + AppWidgetManager gm = AppWidgetManager.getInstance(context); + int[] appWidgetIds = gm.getAppWidgetIds(new ComponentName(context, this.getClass())); + final int N = appWidgetIds.length; + for (int i = 0; i < N; i++) + { + updateAppWidget(context, gm, appWidgetIds[i], intent); + } + } + else + { + super.onReceive(context, intent); + } + } + + public static void updateAppWidget(Context context, AppWidgetManager appWidgetManager, int appWidgetId, Intent args) + { + AppWidgetProviderInfo provider = appWidgetManager.getAppWidgetInfo(appWidgetId); + RemoteViews views = null; + views = new RemoteViews(context.getPackageName(), provider.initialLayout); + + Intent intent = new Intent(context, RockboxActivity.class); + PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0); + views.setOnClickPendingIntent(R.id.infoDisplay, pendingIntent); + + RockboxWidgetConfigure.WidgetPref state = RockboxWidgetConfigure.loadWidgetPref(context, appWidgetId); + + if (state.enablePrev) + { + intent = new Intent("org.rockbox.Prev", Uri.EMPTY, context, RockboxService.class); + pendingIntent = PendingIntent.getService(context, 0, intent, 0); + views.setOnClickPendingIntent(R.id.prev, pendingIntent); + } + else + views.setViewVisibility(R.id.prev, View.GONE); + + if (state.enablePlayPause) + { + intent = new Intent("org.rockbox.PlayPause", Uri.EMPTY, context, RockboxService.class); + pendingIntent = PendingIntent.getService(context, 0, intent, 0); + views.setOnClickPendingIntent(R.id.playPause, pendingIntent); + } + else + views.setViewVisibility(R.id.playPause, View.GONE); + + if (state.enableNext) + { + intent = new Intent("org.rockbox.Next", Uri.EMPTY, context, RockboxService.class); + pendingIntent = PendingIntent.getService(context, 0, intent, 0); + views.setOnClickPendingIntent(R.id.next, pendingIntent); + } + else + views.setViewVisibility(R.id.next, View.GONE); + + if (state.enableStop) + { + intent = new Intent("org.rockbox.Stop", Uri.EMPTY, context, RockboxService.class); + pendingIntent = PendingIntent.getService(context, 0, intent, 0); + views.setOnClickPendingIntent(R.id.stop, pendingIntent); + } + else + views.setViewVisibility(R.id.stop, View.GONE); + + if (args != null) + { + if (args.getAction().equals("org.rockbox.TrackUpdateInfo")) + { + CharSequence title = args.getCharSequenceExtra("title"); + CharSequence artist = args.getCharSequenceExtra("artist"); + CharSequence album = args.getCharSequenceExtra("album"); + views.setTextViewText(R.id.infoDisplay, title+"\n"+artist+"\n"+album); + } + else if (args.getAction().equals("org.rockbox.TrackFinish")) + { + // FIXME: looks like this event is always fired earlier than + // the actual track change (a few seconds) + views.setTextViewText(R.id.infoDisplay, context.getString(R.string.appwidget_infoDisplay)); + } + else if (args.getAction().equals("org.rockbox.UpdateState")) + { + CharSequence playstate = args.getCharSequenceExtra("state"); + if (playstate.equals("play")) + views.setImageViewResource(R.id.playPause, R.drawable.appwidget_pause); + else /* pause or stop */ + views.setImageViewResource(R.id.playPause, R.drawable.appwidget_play); + } + } + + appWidgetManager.updateAppWidget(appWidgetId, views); + } +} + diff --git a/android/src/org/rockbox/widgets/RockboxWidgetProvider2x2.java b/android/src/org/rockbox/widgets/RockboxWidgetProvider2x2.java new file mode 100644 index 0000000000..183c4273ec --- /dev/null +++ b/android/src/org/rockbox/widgets/RockboxWidgetProvider2x2.java @@ -0,0 +1,27 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2011 Antoine Cellerier <dionoea at videolan dot org> + * + * 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 software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +package org.rockbox.widgets; + +public class RockboxWidgetProvider2x2 extends RockboxWidgetProvider +{ +} + diff --git a/android/src/org/rockbox/widgets/RockboxWidgetProvider4x1.java b/android/src/org/rockbox/widgets/RockboxWidgetProvider4x1.java new file mode 100644 index 0000000000..303c54c92b --- /dev/null +++ b/android/src/org/rockbox/widgets/RockboxWidgetProvider4x1.java @@ -0,0 +1,27 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2011 Antoine Cellerier <dionoea at videolan dot org> + * + * 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 software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +package org.rockbox.widgets; + +public class RockboxWidgetProvider4x1 extends RockboxWidgetProvider +{ +} + |