From 1f24ae5b51310b42ce7e5a4ba89282e9cbc86476 Mon Sep 17 00:00:00 2001 From: aragaer Date: Tue, 3 Dec 2019 22:50:11 +0300 Subject: [PATCH] WIP: Changing the server Instead of using the server for global stuff switch to application context. This does break when system stops the IntentService ticking. The correct solution would be to start using alarm manager. --- .../java/com/aragaer/jtt/JttServiceTest.java | 70 ------------ .../java/com/aragaer/jtt/WidgetTest.java | 1 - .../aragaer/jtt/android/NotificationTest.java | 4 - .../jtt/android/TimeChangeReceiverTest.java | 73 ------------- src/main/AndroidManifest.xml | 15 ++- src/main/java/com/aragaer/jtt/ClockView.java | 4 +- .../java/com/aragaer/jtt/JTTMainActivity.java | 8 +- .../com/aragaer/jtt/JTTWidgetProvider.java | 48 +++------ ...erviceComponent.java => JttComponent.java} | 2 +- src/main/java/com/aragaer/jtt/JttService.java | 100 ------------------ src/main/java/com/aragaer/jtt/JttStatus.java | 86 +++++++-------- .../java/com/aragaer/jtt/MainFragment.java | 4 +- src/main/java/com/aragaer/jtt/Settings.java | 2 +- .../com/aragaer/jtt/SettingsFragment.java | 5 - .../com/aragaer/jtt/android/BootReceiver.java | 23 ---- .../aragaer/jtt/android/JttApplication.java | 80 ++++++++++++++ .../com/aragaer/jtt/android/TickerStart.java | 15 +++ .../jtt/android/TimeChangeReceiver.java | 25 ----- .../dialogs/WaitingForLocationDialog.java | 4 +- .../jtt/mechanics/AndroidAnnouncer.java | 18 ++-- .../aragaer/jtt/mechanics/AndroidTicker.java | 11 +- .../jtt/resources/RuntimeResources.java | 28 ----- .../jtt/resources/StringResources.java | 2 +- .../com/aragaer/jtt/today/BoundaryItem.java | 4 +- .../java/com/aragaer/jtt/today/HourItem.java | 4 +- src/main/res/layout/today_item.xml | 2 +- ...mponentTest.java => JttComponentTest.java} | 16 +-- .../java/com/aragaer/jtt/JttServiceTest.java | 80 -------------- .../jtt/android/TimeChangeReceiverTest.java | 64 ----------- .../jtt/resources/RuntimeResourcesTest.java | 71 ------------- 30 files changed, 199 insertions(+), 670 deletions(-) delete mode 100644 src/androidTest/java/com/aragaer/jtt/JttServiceTest.java delete mode 100644 src/androidTest/java/com/aragaer/jtt/android/TimeChangeReceiverTest.java rename src/main/java/com/aragaer/jtt/{ServiceComponent.java => JttComponent.java} (96%) delete mode 100644 src/main/java/com/aragaer/jtt/JttService.java delete mode 100644 src/main/java/com/aragaer/jtt/android/BootReceiver.java create mode 100644 src/main/java/com/aragaer/jtt/android/JttApplication.java create mode 100644 src/main/java/com/aragaer/jtt/android/TickerStart.java delete mode 100644 src/main/java/com/aragaer/jtt/android/TimeChangeReceiver.java delete mode 100644 src/main/java/com/aragaer/jtt/resources/RuntimeResources.java rename src/test/java/com/aragaer/jtt/{ServiceComponentTest.java => JttComponentTest.java} (86%) delete mode 100644 src/test/java/com/aragaer/jtt/JttServiceTest.java delete mode 100644 src/test/java/com/aragaer/jtt/android/TimeChangeReceiverTest.java delete mode 100644 src/test/java/com/aragaer/jtt/resources/RuntimeResourcesTest.java diff --git a/src/androidTest/java/com/aragaer/jtt/JttServiceTest.java b/src/androidTest/java/com/aragaer/jtt/JttServiceTest.java deleted file mode 100644 index fa52db2..0000000 --- a/src/androidTest/java/com/aragaer/jtt/JttServiceTest.java +++ /dev/null @@ -1,70 +0,0 @@ -// -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; -*- -// vim: et ts=4 sts=4 sw=4 syntax=java -package com.aragaer.jtt; - -import android.content.*; -import androidx.test.uiautomator.UiDevice; - -import org.junit.*; - -import com.aragaer.jtt.mechanics.AndroidTicker; - -import static org.junit.Assert.*; -import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation; - - -public class JttServiceTest { - - private Context context; - private MyReceiver receiver; - - @Before public void setUp() { - context = getInstrumentation().getTargetContext(); - receiver = new MyReceiver(); - context.removeStickyBroadcast(new Intent(AndroidTicker.ACTION_JTT_TICK)); - context.registerReceiver(receiver, new IntentFilter(AndroidTicker.ACTION_JTT_TICK)); - } - - @After public void cleanUp() { - context.stopService(new Intent(context, JttService.class)); - context.removeStickyBroadcast(new Intent(AndroidTicker.ACTION_JTT_TICK)); - } - - @Test public void testTicksOnStart() throws Exception { - Intent intent = new Intent(context, JttService.class); - context.startService(intent); - synchronized (receiver) { - receiver.wait(1000); - } - } - - // FIXME: This test fails on emulator - @Ignore("This test fails on emulator") - @Test public void testTicksOnScreenOn() throws Exception { - Intent intent = new Intent(context, JttService.class); - context.startService(intent); - synchronized (receiver) { - receiver.wait(1000); - } - - UiDevice device = UiDevice.getInstance(getInstrumentation()); - device.sleep(); - receiver.triggered = null; - device.wakeUp(); - synchronized (receiver) { - receiver.wait(1000); - } - assertNotNull(receiver.triggered); - } - - private class MyReceiver extends BroadcastReceiver { - Intent triggered; - - @Override public void onReceive(Context context, Intent intent) { - triggered = intent; - synchronized (this) { - this.notify(); - } - } - } -} diff --git a/src/androidTest/java/com/aragaer/jtt/WidgetTest.java b/src/androidTest/java/com/aragaer/jtt/WidgetTest.java index 9815cc8..9c1dc60 100644 --- a/src/androidTest/java/com/aragaer/jtt/WidgetTest.java +++ b/src/androidTest/java/com/aragaer/jtt/WidgetTest.java @@ -28,7 +28,6 @@ private void setInitialLocation(Context context) { @Before public void setUp() { Context context = getInstrumentation().getTargetContext(); setInitialLocation(context); - context.startService(new Intent(getInstrumentation().getTargetContext(), JttService.class)); } private void putWidgetOnHome(String widgetName) throws Exception { diff --git a/src/androidTest/java/com/aragaer/jtt/android/NotificationTest.java b/src/androidTest/java/com/aragaer/jtt/android/NotificationTest.java index 6c640c7..235bba4 100644 --- a/src/androidTest/java/com/aragaer/jtt/android/NotificationTest.java +++ b/src/androidTest/java/com/aragaer/jtt/android/NotificationTest.java @@ -9,7 +9,6 @@ import androidx.test.filters.LargeTest; -import com.aragaer.jtt.JttService; import com.aragaer.jtt.Settings; import com.aragaer.jtt.mechanics.AndroidTicker; @@ -31,12 +30,9 @@ public class NotificationTest { context = instrumentation.getTargetContext(); SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(context); settings.edit().putString(Settings.PREF_LOCALE, "1").commit(); - Intent intent = new Intent(context, JttService.class); - context.startService(intent); } @After public void cleanUp() { - context.stopService(new Intent(context, JttService.class)); context.removeStickyBroadcast(new Intent(AndroidTicker.ACTION_JTT_TICK)); device.pressHome(); } diff --git a/src/androidTest/java/com/aragaer/jtt/android/TimeChangeReceiverTest.java b/src/androidTest/java/com/aragaer/jtt/android/TimeChangeReceiverTest.java deleted file mode 100644 index d6d3030..0000000 --- a/src/androidTest/java/com/aragaer/jtt/android/TimeChangeReceiverTest.java +++ /dev/null @@ -1,73 +0,0 @@ -// -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; -*- -// vim: et ts=4 sts=4 sw=4 syntax=java -package com.aragaer.jtt.android; - -import android.content.*; -import android.content.pm.*; - -import com.aragaer.jtt.mechanics.AndroidTicker; - -import org.junit.*; - -import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.fail; - - -public class TimeChangeReceiverTest { - - private Context context; - private MyReceiver receiver; - - @Before public void setUp() { - context = getInstrumentation().getTargetContext(); - receiver = new MyReceiver(); - context.registerReceiver(receiver, new IntentFilter(AndroidTicker.ACTION_JTT_TICK)); - } - - @Test public void testListensForTimeChange() { - Intent intent = new Intent(Intent.ACTION_TIME_CHANGED); - PackageManager pm = context.getPackageManager(); - for (ResolveInfo ri : pm.queryBroadcastReceivers(intent, 0)) { - ActivityInfo ai = ri.activityInfo; - if (ai.name.equals("com.aragaer.jtt.android.TimeChangeReceiver")) - return; - } - fail("Not listening for time change event"); - } - - @Test public void testListensForDateChange() { - Intent intent = new Intent(Intent.ACTION_DATE_CHANGED); - PackageManager pm = context.getPackageManager(); - for (ResolveInfo ri : pm.queryBroadcastReceivers(intent, 0)) { - ActivityInfo ai = ri.activityInfo; - if (ai.name.equals("com.aragaer.jtt.android.TimeChangeReceiver")) - return; - } - fail("Not listening for date change event"); - } - - @Test public void testTriggersTick() throws Exception { - new TimeChangeReceiver().onReceive(context, new Intent(Intent.ACTION_DATE_CHANGED)); - synchronized (receiver) { - receiver.wait(); - } - assertEquals("Actually got correct event", - AndroidTicker.ACTION_JTT_TICK, receiver.triggered.getAction()); - } - - @After public void tearDown() { - context.unregisterReceiver(receiver); - } - - private class MyReceiver extends BroadcastReceiver { - Intent triggered; - - @Override public void onReceive(Context context, Intent intent) { - triggered = intent; - synchronized (this) { - this.notify(); - } - } - } -} diff --git a/src/main/AndroidManifest.xml b/src/main/AndroidManifest.xml index 82bada0..8913478 100644 --- a/src/main/AndroidManifest.xml +++ b/src/main/AndroidManifest.xml @@ -13,7 +13,8 @@ + android:label="@string/app_name" + android:name=".android.JttApplication"> - + + + - - - - - - diff --git a/src/main/java/com/aragaer/jtt/ClockView.java b/src/main/java/com/aragaer/jtt/ClockView.java index 61f53b2..a487b4a 100644 --- a/src/main/java/com/aragaer/jtt/ClockView.java +++ b/src/main/java/com/aragaer/jtt/ClockView.java @@ -2,10 +2,10 @@ // vim: et ts=4 sts=4 sw=4 syntax=java package com.aragaer.jtt; +import com.aragaer.jtt.android.JttApplication; import com.aragaer.jtt.core.Hour; import com.aragaer.jtt.graphics.ArrowView; import com.aragaer.jtt.graphics.WadokeiView; -import com.aragaer.jtt.resources.RuntimeResources; import com.aragaer.jtt.resources.StringResources; import com.aragaer.jtt.wadokei.AutoresizeTextView; @@ -26,7 +26,7 @@ public class ClockView extends ViewGroup implements StringResources.StringResour public ClockView(Context context) { super(context); - sr = RuntimeResources.get(context).getStringResources(); + sr = ((JttApplication) context.getApplicationContext()).getStringResources(); sr.registerStringResourceChangeListener(this, StringResources.TYPE_HOUR_NAME); wadokei = new WadokeiView(context); arrow = new ArrowView(context); diff --git a/src/main/java/com/aragaer/jtt/JTTMainActivity.java b/src/main/java/com/aragaer/jtt/JTTMainActivity.java index d069a07..8977e72 100644 --- a/src/main/java/com/aragaer/jtt/JTTMainActivity.java +++ b/src/main/java/com/aragaer/jtt/JTTMainActivity.java @@ -3,12 +3,12 @@ import android.app.Activity; import android.app.FragmentManager; import android.content.*; -import android.os.Build; import android.os.Bundle; import android.preference.PreferenceManager; import android.view.Menu; import android.view.MenuItem; +import com.aragaer.jtt.android.JttApplication; import com.aragaer.jtt.android.fragments.LocationFragment; import org.jetbrains.annotations.NotNull; @@ -20,11 +20,7 @@ public class JTTMainActivity extends Activity implements SharedPreferences.OnSha public void onCreate(Bundle savedInstanceState) { setTheme(Settings.getAppTheme(this)); super.onCreate(savedInstanceState); - Intent serviceIntent = new Intent(this, JttService.class); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) - startForegroundService(serviceIntent); - else - startService(serviceIntent); + ((JttApplication) getApplicationContext()).startTicker(); final SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(this); pref.registerOnSharedPreferenceChangeListener(this); if (savedInstanceState == null) { // Otherwise we assume that fragments are saved/restored diff --git a/src/main/java/com/aragaer/jtt/JTTWidgetProvider.java b/src/main/java/com/aragaer/jtt/JTTWidgetProvider.java index 16928b2..99f92fd 100644 --- a/src/main/java/com/aragaer/jtt/JTTWidgetProvider.java +++ b/src/main/java/com/aragaer/jtt/JTTWidgetProvider.java @@ -5,11 +5,10 @@ import java.util.Map; import java.util.HashMap; +import com.aragaer.jtt.android.JttApplication; import com.aragaer.jtt.core.Hour; import com.aragaer.jtt.graphics.Paints; import com.aragaer.jtt.graphics.WadokeiDraw; -import com.aragaer.jtt.mechanics.AndroidTicker; -import com.aragaer.jtt.resources.RuntimeResources; import android.app.PendingIntent; import android.appwidget.AppWidgetManager; @@ -18,7 +17,6 @@ import android.content.res.Resources.Theme; import android.content.res.TypedArray; import android.graphics.*; -import android.os.Build; import android.util.Log; import android.widget.RemoteViews; @@ -45,7 +43,7 @@ private static final class WidgetHolder { } static private final Map, WidgetHolder> classes = new HashMap<>(); - static void draw_all(final Context c) { + public static void draw_all(final Context c) { for (WidgetHolder holder : classes.values()) draw(c, null, holder); } @@ -65,37 +63,21 @@ protected JTTWidget(final int frequency, final Class pa } } - public void onReceive(Context c, Intent i) { - final String action = i.getAction(); - if (action == null) - return; - if (action.equals(AppWidgetManager.ACTION_APPWIDGET_UPDATE)) - update(c, i); - else if (action.equals(AndroidTicker.ACTION_JTT_TICK)) - tick(c, i, getClass()); - else - Log.d("Widgets", "Got action "+action); - } - - private void update(Context c, Intent i) { - Intent intent = new Intent(c, JttService.class); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) - c.startForegroundService(intent); - else - c.startService(intent); - int[] ids = i.getIntArrayExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS); - draw(c, ids, classes.get(getClass())); + @Override public void onUpdate(Context context, AppWidgetManager manager, int[] ids) { + ((JttApplication) context.getApplicationContext()).startTicker(); + draw(context, ids, classes.get(getClass())); } } - private static void tick(Context c, Intent i, Class cls) { - int wrapped = i.getIntExtra("jtt", 0); - final WidgetHolder holder = classes.get(cls); - Hour hour = Hour.fromTickNumber(wrapped, holder.granularity); - if (hour.equals(holder.last_update)) - return; - holder.last_update = hour; - draw(c, null, holder); + public static void tick(Context context, Intent intent) { + int wrapped = intent.getIntExtra("jtt", 0); + for (WidgetHolder holder : classes.values()) { + Hour hour = Hour.fromTickNumber(wrapped, holder.granularity); + if (hour.equals(holder.last_update)) + continue; + holder.last_update = hour; + draw(context, null, holder); + } } private static void draw(Context c, int[] ids, final WidgetHolder holder) { @@ -229,7 +211,7 @@ public Bitmap get_bmp(Context c, Hour h) { @Override public String get_text(Context c, Hour h) { - return RuntimeResources.get(c).getStringResources().formatHourForWidget(h.num); + return ((JttApplication) c.getApplicationContext()).getStringResources().formatHourForWidget(h.num); } @Override diff --git a/src/main/java/com/aragaer/jtt/ServiceComponent.java b/src/main/java/com/aragaer/jtt/JttComponent.java similarity index 96% rename from src/main/java/com/aragaer/jtt/ServiceComponent.java rename to src/main/java/com/aragaer/jtt/JttComponent.java index 5050943..f2faccc 100644 --- a/src/main/java/com/aragaer/jtt/ServiceComponent.java +++ b/src/main/java/com/aragaer/jtt/JttComponent.java @@ -19,7 +19,7 @@ @Component(modules={AstronomyModule.class, CoreModule.class, MechanicsModule.class}) -interface ServiceComponent { +public interface JttComponent { Ticker getTicker(); Clockwork provideClockwork(); IntervalProvider provideIntervalProvider(); diff --git a/src/main/java/com/aragaer/jtt/JttService.java b/src/main/java/com/aragaer/jtt/JttService.java deleted file mode 100644 index 766dc25..0000000 --- a/src/main/java/com/aragaer/jtt/JttService.java +++ /dev/null @@ -1,100 +0,0 @@ -// -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; -*- -// vim: et ts=4 sts=4 sw=4 syntax=java -package com.aragaer.jtt; - -import com.aragaer.jtt.astronomy.AstronomyModule; -import com.aragaer.jtt.mechanics.MechanicsModule; -import com.aragaer.jtt.mechanics.Ticker; - -import android.app.Service; -import android.content.*; -import android.os.IBinder; -import android.preference.PreferenceManager; -import android.util.Log; - - -public class JttService extends Service implements SharedPreferences.OnSharedPreferenceChangeListener { - private static final String TAG = "JTT_SERVICE"; - private JttStatus status_notify; - private Ticker ticker; - - @Override public IBinder onBind(Intent intent) { - return null; - } - - @Override public void onCreate() { - super.onCreate(); - ServiceComponent component = DaggerServiceComponent - .builder() - .astronomyModule(new AstronomyModule(this)) - .mechanicsModule(new MechanicsModule(this)) - .build(); - ticker = component.getTicker(); - registerReceiver(on, new IntentFilter(Intent.ACTION_SCREEN_ON)); - registerReceiver(off, new IntentFilter(Intent.ACTION_SCREEN_OFF)); - Log.i(TAG, "Service created"); - } - - @Override public void onDestroy() { - if (status_notify != null) { - status_notify.release(); - status_notify = null; - } - unregisterReceiver(on); - unregisterReceiver(off); - } - - @Override public int onStartCommand(Intent intent, int flags, int startid) { - Log.i(TAG, "Service starting"); - ticker.start(); - - SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(this); - pref.registerOnSharedPreferenceChangeListener(this); - - toggle_notify(pref.getBoolean("jtt_notify", true)); - - return START_STICKY; - } - - private void toggle_notify(boolean notify) { - notify = true; // FIXME: This is a "hotfix" for "Background execution not allowed" - if (status_notify == null) { - if (notify) - status_notify = new JttStatus(this); - } else { - if (!notify) { - status_notify.release(); - status_notify = null; - } - } - Log.i("jtt", "Toggle notify to "+status_notify); - } - - private final BroadcastReceiver on = new BroadcastReceiver() { - @Override public void onReceive(Context context, Intent intent) { - ticker.start(); - } - }; - private final BroadcastReceiver off = new BroadcastReceiver() { - @Override public void onReceive(Context context, Intent intent) { - ticker.stop(); - } - }; - - public void onSharedPreferenceChanged(SharedPreferences pref, String key) { - switch (key) { - case Settings.PREF_NOTIFY: - toggle_notify(pref.getBoolean(Settings.PREF_NOTIFY, true)); - break; - case Settings.PREF_LOCATION: - ticker.start(); - break; - case Settings.PREF_WIDGET: - case Settings.PREF_LOCALE: - case Settings.PREF_HNAME: - case Settings.PREF_EMOJI_WIDGET: - JTTWidgetProvider.draw_all(this); - break; - } - } -} diff --git a/src/main/java/com/aragaer/jtt/JttStatus.java b/src/main/java/com/aragaer/jtt/JttStatus.java index e8f4bc3..89e0057 100644 --- a/src/main/java/com/aragaer/jtt/JttStatus.java +++ b/src/main/java/com/aragaer/jtt/JttStatus.java @@ -2,9 +2,9 @@ // vim: et ts=4 sts=4 sw=4 syntax=java package com.aragaer.jtt; +import com.aragaer.jtt.android.JttApplication; import com.aragaer.jtt.core.*; import com.aragaer.jtt.mechanics.AndroidTicker; -import com.aragaer.jtt.resources.RuntimeResources; import com.aragaer.jtt.resources.StringResources; import com.aragaer.jtt.resources.StringResources.StringResourceChangeListener; @@ -13,56 +13,54 @@ import androidx.core.app.NotificationCompat; import android.os.Build; +import android.os.IBinder; import android.widget.RemoteViews; -public class JttStatus extends BroadcastReceiver implements StringResourceChangeListener { +public class JttStatus extends Service implements StringResourceChangeListener { private static final int APP_ID = 1; private static final String CHANNEL_ID = "jtt_notification_channel"; - private final JttService context; - private final StringResources sr; private Hour h = new Hour(0); private long start, end; - private final NotificationManager nm; - public JttStatus(final JttService ctx) { - context = ctx; - nm = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); - createNotificationChannel(); - sr = RuntimeResources.get(context).getStringResources(); - sr.registerStringResourceChangeListener(this, - StringResources.TYPE_HOUR_NAME | StringResources.TYPE_TIME_FORMAT); - - context.registerReceiver(this, new IntentFilter(AndroidTicker.ACTION_JTT_TICK)); + @Override public IBinder onBind(Intent intent) { + return null; } - public void release() { - context.stopForeground(true); + @Override public void onDestroy() { + stopForeground(true); + StringResources sr = ((JttApplication) getApplicationContext()).getStringResources(); sr.unregisterStringResourceChangeListener(this); - context.unregisterReceiver(this); + unregisterReceiver(_tick); deleteNotificationChannel(); } - @Override public void onReceive(Context ctx, Intent intent) { - final String action = intent.getAction(); - if (!AndroidTicker.ACTION_JTT_TICK.equals(action)) - return; - - // FIXME: kicking widgets from here - Intent widgetIntent = new Intent(intent); - widgetIntent.setClass(ctx, JTTWidgetProvider.Widget1.class); - ctx.sendBroadcast(widgetIntent); - widgetIntent.setClass(ctx, JTTWidgetProvider.Widget12.class); - ctx.sendBroadcast(widgetIntent); - - ThreeIntervals data = (ThreeIntervals) intent.getSerializableExtra("intervals"); - if (data == null) - return; - Hour hour = Hour.fromTickNumber(intent.getIntExtra("jtt", 0)); - setIntervals(data, hour); + @Override public int onStartCommand(Intent intent, int flags, int startid) { + StringResources sr = ((JttApplication) getApplicationContext()).getStringResources(); + createNotificationChannel(); + sr.registerStringResourceChangeListener(this, + StringResources.TYPE_HOUR_NAME | StringResources.TYPE_TIME_FORMAT); + registerReceiver(_tick, new IntentFilter(AndroidTicker.ACTION_JTT_TICK)); + show(); + return START_STICKY; } + private final BroadcastReceiver _tick = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + final String action = intent.getAction(); + if (!AndroidTicker.ACTION_JTT_TICK.equals(action)) + return; + + ThreeIntervals data = (ThreeIntervals) intent.getSerializableExtra("intervals"); + if (data == null) + return; + Hour hour = Hour.fromTickNumber(intent.getIntExtra("jtt", 0)); + setIntervals(data, hour); + } + }; + private void setIntervals(ThreeIntervals intervals, Hour hour) { Interval currentInterval = intervals.getMiddleInterval(); h = hour; @@ -82,26 +80,30 @@ private void setIntervals(ThreeIntervals intervals, Hour hour) { } private void show() { - context.startForeground(APP_ID, buildNotification()); + startForeground(APP_ID, buildNotification()); } private void createNotificationChannel() { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) return; - CharSequence name = context.getString(R.string.app_name); + NotificationManager nm = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); + CharSequence name = getString(R.string.app_name); int importance = NotificationManager.IMPORTANCE_LOW; NotificationChannel channel = new NotificationChannel(CHANNEL_ID, name, importance); nm.createNotificationChannel(channel); } private void deleteNotificationChannel() { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) - nm.deleteNotificationChannel(CHANNEL_ID); + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) + return; + NotificationManager nm = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); + nm.deleteNotificationChannel(CHANNEL_ID); } private Notification buildNotification() { + StringResources sr = ((JttApplication) getApplicationContext()).getStringResources(); int hf = h.quarter * Hour.TICKS_PER_QUARTER + h.tick; - RemoteViews rv = new RemoteViews(context.getPackageName(), R.layout.notification); + RemoteViews rv = new RemoteViews(getPackageName(), R.layout.notification); rv.setTextViewText(R.id.image, Hour.Glyphs[h.num]); rv.setTextViewText(R.id.title, sr.getHrOf(h.num)); @@ -111,12 +113,12 @@ private Notification buildNotification() { rv.setTextViewText(R.id.start, sr.format_time(start)); rv.setTextViewText(R.id.end, sr.format_time(end)); - return new NotificationCompat.Builder(context) + return new NotificationCompat.Builder(this) .setContent(rv) .setOngoing(true) .setSmallIcon(R.drawable.notification_icon, h.num) - .setContentIntent(PendingIntent.getActivity(context, 0, - new Intent(context, JTTMainActivity.class), 0)) + .setContentIntent(PendingIntent.getActivity(this, 0, + new Intent(this, JTTMainActivity.class), 0)) .setVisibility(NotificationCompat.VISIBILITY_PUBLIC) .setChannelId(CHANNEL_ID) .getNotification(); diff --git a/src/main/java/com/aragaer/jtt/MainFragment.java b/src/main/java/com/aragaer/jtt/MainFragment.java index 8de667d..05f1ffa 100644 --- a/src/main/java/com/aragaer/jtt/MainFragment.java +++ b/src/main/java/com/aragaer/jtt/MainFragment.java @@ -11,9 +11,9 @@ import android.view.*; import android.widget.ListView; +import com.aragaer.jtt.android.JttApplication; import com.aragaer.jtt.core.ThreeIntervals; import com.aragaer.jtt.mechanics.AndroidTicker; -import com.aragaer.jtt.resources.RuntimeResources; import com.aragaer.jtt.resources.StringResources; import com.aragaer.jtt.today.TodayAdapter; @@ -54,7 +54,7 @@ public class MainFragment extends Fragment { clock.setHour(tickNumber); final ListView today_list = new ListView(getActivity()); - today = new TodayAdapter(getActivity(), 0, RuntimeResources.get(getActivity()).getStringResources()); + today = new TodayAdapter(getActivity(), 0, ((JttApplication) getActivity().getApplicationContext()).getStringResources()); today_list.setAdapter(today); today_list.setDividerHeight(-getResources().getDimensionPixelSize(R.dimen.today_divider_neg)); if (intervals != null) diff --git a/src/main/java/com/aragaer/jtt/Settings.java b/src/main/java/com/aragaer/jtt/Settings.java index 730ced5..9865a1d 100644 --- a/src/main/java/com/aragaer/jtt/Settings.java +++ b/src/main/java/com/aragaer/jtt/Settings.java @@ -12,7 +12,7 @@ public class Settings { public static final String PREF_HNAME = "jtt_hname"; public static final String PREF_NOTIFY = "jtt_notify"; /* package private */ static final String PREF_THEME = "jtt_theme"; - /* package private */ static final String PREF_WIDGET = "jtt_widget_theme"; + public static final String PREF_WIDGET = "jtt_widget_theme"; public static final String PREF_EMOJI_WIDGET = "jtt_emoji_widget"; private static final int[] app_themes = {R.style.JTTTheme, R.style.DarkTheme, R.style.LightTheme}; diff --git a/src/main/java/com/aragaer/jtt/SettingsFragment.java b/src/main/java/com/aragaer/jtt/SettingsFragment.java index 35b1096..4cb6340 100644 --- a/src/main/java/com/aragaer/jtt/SettingsFragment.java +++ b/src/main/java/com/aragaer/jtt/SettingsFragment.java @@ -61,11 +61,6 @@ public boolean onPreferenceChange(Preference preference, Object newValue) { pref_location.setSummary(pref.getString(Settings.PREF_LOCATION, "")); } - // FIXME: notification must be shown for application to work properly - CheckBoxPreference notify = (CheckBoxPreference) findPreference(Settings.PREF_NOTIFY); - notify.setEnabled(false); - notify.setChecked(true); - setHasOptionsMenu(true); } diff --git a/src/main/java/com/aragaer/jtt/android/BootReceiver.java b/src/main/java/com/aragaer/jtt/android/BootReceiver.java deleted file mode 100644 index d31b505..0000000 --- a/src/main/java/com/aragaer/jtt/android/BootReceiver.java +++ /dev/null @@ -1,23 +0,0 @@ -// -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; -*- -// vim: et ts=4 sts=4 sw=4 syntax=java -package com.aragaer.jtt.android; - -import com.aragaer.jtt.JttService; - -import android.content.*; -import android.os.Build; - -public class BootReceiver extends BroadcastReceiver { - public void onReceive(Context context, Intent intent) { - String action = intent.getAction(); - if (action == null) - return; - if (action.equals(Intent.ACTION_BOOT_COMPLETED)) { - Intent serviceIntent = new Intent(context, JttService.class); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) - context.startForegroundService(serviceIntent); - else - context.startService(serviceIntent); - } - } -} diff --git a/src/main/java/com/aragaer/jtt/android/JttApplication.java b/src/main/java/com/aragaer/jtt/android/JttApplication.java new file mode 100644 index 0000000..4aacb6c --- /dev/null +++ b/src/main/java/com/aragaer/jtt/android/JttApplication.java @@ -0,0 +1,80 @@ +package com.aragaer.jtt.android; + +import android.app.Application; +import android.content.*; +import android.os.Build; +import android.preference.PreferenceManager; + +import com.aragaer.jtt.*; +import com.aragaer.jtt.astronomy.AstronomyModule; +import com.aragaer.jtt.mechanics.*; +import com.aragaer.jtt.resources.StringResources; + + +public class JttApplication extends Application implements SharedPreferences.OnSharedPreferenceChangeListener { + private Ticker _ticker; + private StringResources _stringResources; + + private final BroadcastReceiver _widget_tick_forwarder = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + if (AndroidTicker.ACTION_JTT_TICK.equals(intent.getAction())) + JTTWidgetProvider.tick(context, intent); + } + }; + + @Override public void onCreate() { + super.onCreate(); + JttComponent component = DaggerJttComponent + .builder() + .astronomyModule(new AstronomyModule(this)) + .mechanicsModule(new MechanicsModule(this)) + .build(); + _ticker = component.getTicker(); + + registerReceiver(_widget_tick_forwarder, new IntentFilter(AndroidTicker.ACTION_JTT_TICK)); + + _stringResources = new StringResources(this); + + SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(this); + pref.registerOnSharedPreferenceChangeListener(this); + + toggle_notify(pref.getBoolean(Settings.PREF_NOTIFY, true)); + } + + public StringResources getStringResources() { + return _stringResources; + } + + public void startTicker() { + _ticker.start(); + } + + public void onSharedPreferenceChanged(SharedPreferences pref, String key) { + switch (key) { + case Settings.PREF_NOTIFY: + toggle_notify(pref.getBoolean(Settings.PREF_NOTIFY, true)); + break; + case Settings.PREF_LOCATION: + startTicker(); + break; + case Settings.PREF_WIDGET: + case Settings.PREF_LOCALE: + case Settings.PREF_HNAME: + case Settings.PREF_EMOJI_WIDGET: + JTTWidgetProvider.draw_all(this); + break; + } + } + + private void toggle_notify(boolean notify) { + Intent statusIntent = new Intent(this, JttStatus.class); + if (notify) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) + startForegroundService(statusIntent); + else + startService(statusIntent); + } else + stopService(statusIntent); + } +} diff --git a/src/main/java/com/aragaer/jtt/android/TickerStart.java b/src/main/java/com/aragaer/jtt/android/TickerStart.java new file mode 100644 index 0000000..7fad255 --- /dev/null +++ b/src/main/java/com/aragaer/jtt/android/TickerStart.java @@ -0,0 +1,15 @@ +// -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; -*- +// vim: et ts=4 sts=4 sw=4 syntax=java +package com.aragaer.jtt.android; + +import android.content.*; + +public class TickerStart extends BroadcastReceiver { + @Override public void onReceive(Context context, Intent intent) { + String action = intent.getAction(); + if (Intent.ACTION_BOOT_COMPLETED.equals(action) + || Intent.ACTION_TIME_CHANGED.equals(action) + || Intent.ACTION_DATE_CHANGED.equals(action)) + ((JttApplication) context.getApplicationContext()).startTicker(); + } +} diff --git a/src/main/java/com/aragaer/jtt/android/TimeChangeReceiver.java b/src/main/java/com/aragaer/jtt/android/TimeChangeReceiver.java deleted file mode 100644 index 0d7889b..0000000 --- a/src/main/java/com/aragaer/jtt/android/TimeChangeReceiver.java +++ /dev/null @@ -1,25 +0,0 @@ -// -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; -*- -// vim: et ts=4 sts=4 sw=4 syntax=java -package com.aragaer.jtt.android; - -import android.content.*; -import android.os.Build; - -import com.aragaer.jtt.JttService; - - -public class TimeChangeReceiver extends BroadcastReceiver { - - @Override - public void onReceive(Context context, Intent intent) { - String action = intent.getAction(); - if (Intent.ACTION_TIME_CHANGED.equals(action) - || Intent.ACTION_DATE_CHANGED.equals(action)) { - Intent serviceIntent = new Intent(context, JttService.class); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) - context.startForegroundService(serviceIntent); - else - context.startService(serviceIntent); - } - } -} diff --git a/src/main/java/com/aragaer/jtt/android/dialogs/WaitingForLocationDialog.java b/src/main/java/com/aragaer/jtt/android/dialogs/WaitingForLocationDialog.java index 93dcee9..ab6225a 100644 --- a/src/main/java/com/aragaer/jtt/android/dialogs/WaitingForLocationDialog.java +++ b/src/main/java/com/aragaer/jtt/android/dialogs/WaitingForLocationDialog.java @@ -3,9 +3,7 @@ import android.app.ProgressDialog; import android.content.Context; import android.content.DialogInterface; -import android.location.Location; -import android.location.LocationListener; -import android.location.LocationManager; +import android.location.*; import android.os.Bundle; import android.util.Log; diff --git a/src/main/java/com/aragaer/jtt/mechanics/AndroidAnnouncer.java b/src/main/java/com/aragaer/jtt/mechanics/AndroidAnnouncer.java index 8b8ddfc..afec204 100644 --- a/src/main/java/com/aragaer/jtt/mechanics/AndroidAnnouncer.java +++ b/src/main/java/com/aragaer/jtt/mechanics/AndroidAnnouncer.java @@ -14,17 +14,17 @@ public class AndroidAnnouncer implements Announcer { private final IntervalProvider _intervalProvider; public AndroidAnnouncer(Context context, IntervalProvider intervalProvider) { - _context = context; - _intervalProvider = intervalProvider; + _context = context; + _intervalProvider = intervalProvider; } @Override public void announce(long timestamp) { - ThreeIntervals intervals = _intervalProvider.getIntervalsForTimestamp(timestamp); - Hour hour = Hour.fromInterval(intervals.getMiddleInterval(), timestamp); - Intent intent = new Intent(AndroidTicker.ACTION_JTT_TICK) - .putExtra("intervals", intervals) - .putExtra("hour", hour.num) - .putExtra("jtt", hour.wrapped); - _context.sendStickyBroadcast(intent); + ThreeIntervals intervals = _intervalProvider.getIntervalsForTimestamp(timestamp); + Hour hour = Hour.fromInterval(intervals.getMiddleInterval(), timestamp); + Intent intent = new Intent(AndroidTicker.ACTION_JTT_TICK) + .putExtra("intervals", intervals) + .putExtra("hour", hour.num) + .putExtra("jtt", hour.wrapped); + _context.sendStickyBroadcast(intent); } } diff --git a/src/main/java/com/aragaer/jtt/mechanics/AndroidTicker.java b/src/main/java/com/aragaer/jtt/mechanics/AndroidTicker.java index 4cacc0c..6a0d921 100644 --- a/src/main/java/com/aragaer/jtt/mechanics/AndroidTicker.java +++ b/src/main/java/com/aragaer/jtt/mechanics/AndroidTicker.java @@ -7,6 +7,7 @@ import com.aragaer.jtt.core.Clockwork; +import android.content.BroadcastReceiver; import android.os.Handler; import android.os.Message; import android.util.Log; @@ -15,6 +16,7 @@ public class AndroidTicker extends Handler implements Ticker { + private static final int WHAT = 1; public static final String ACTION_JTT_TICK = "com.aragaer.jtt.action.TICK"; private final Clockwork _clockwork; @@ -26,15 +28,16 @@ public AndroidTicker(Clockwork clockwork, Announcer announcer) { } public void start() { - sendEmptyMessage(0); + sendEmptyMessage(WHAT); } public void stop() { - removeMessages(0); + removeMessages(WHAT); } @Override public void handleMessage(@NonNull Message msg) { - removeMessages(0); + if (hasMessages(WHAT)) + removeMessages(WHAT); Log.d("JTT CLOCKWORK", "Handler ticked"); long now = System.currentTimeMillis(); _clockwork.setTime(now); @@ -43,7 +46,7 @@ public void stop() { int ticks_passed = (int) (ms_passed / _clockwork.repeat); long next_tick = (ticks_passed + 1) * _clockwork.repeat + _clockwork.start; long delay = next_tick - now; - sendEmptyMessageDelayed(0, delay); + sendEmptyMessageDelayed(WHAT, delay); Log.d("JTT CLOCKWORK", "Tick delay " + delay); Log.d("JTT CLOCKWORK", "Next tick scheduled at "+(new SimpleDateFormat("HH:mm:ss.SSS", Locale.US).format(next_tick))); _announcer.announce(now); diff --git a/src/main/java/com/aragaer/jtt/resources/RuntimeResources.java b/src/main/java/com/aragaer/jtt/resources/RuntimeResources.java deleted file mode 100644 index 1c41c45..0000000 --- a/src/main/java/com/aragaer/jtt/resources/RuntimeResources.java +++ /dev/null @@ -1,28 +0,0 @@ -// -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; -*- -// vim: et ts=4 sts=4 sw=4 syntax=java -package com.aragaer.jtt.resources; - -import android.content.Context; - - -public class RuntimeResources { - private final Context context; - private static RuntimeResources instance; - private static StringResources srInstance; - - private RuntimeResources(final Context ctx) { - context = ctx; - } - - public static RuntimeResources get(final Context c) { - if (instance == null) - instance = new RuntimeResources(c.getApplicationContext()); - return instance; - } - - public StringResources getStringResources() { - if (srInstance == null) - srInstance = new StringResources(context); - return srInstance; - } -} diff --git a/src/main/java/com/aragaer/jtt/resources/StringResources.java b/src/main/java/com/aragaer/jtt/resources/StringResources.java index 7a7dfd7..9fe5a0b 100644 --- a/src/main/java/com/aragaer/jtt/resources/StringResources.java +++ b/src/main/java/com/aragaer/jtt/resources/StringResources.java @@ -41,7 +41,7 @@ public void onReceive(Context context, Intent intent) { private int hour_name_option; private static final String[] HourEmoji = "🐓🐕🐖🐀🐂🐅🐇🐉🐍🐎🐏🐒".split("(?!^)"); - protected StringResources(final Context context) { + public StringResources(final Context context) { c = context; resources = c.getResources(); SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(c); diff --git a/src/main/java/com/aragaer/jtt/today/BoundaryItem.java b/src/main/java/com/aragaer/jtt/today/BoundaryItem.java index 24d6525..67c1944 100644 --- a/src/main/java/com/aragaer/jtt/today/BoundaryItem.java +++ b/src/main/java/com/aragaer/jtt/today/BoundaryItem.java @@ -3,7 +3,7 @@ package com.aragaer.jtt.today; import com.aragaer.jtt.R; -import com.aragaer.jtt.resources.RuntimeResources; +import com.aragaer.jtt.android.JttApplication; import com.aragaer.jtt.resources.StringResources; import android.content.Context; @@ -21,7 +21,7 @@ public BoundaryItem(long t) { public View toView(Context c, View v, int sel_p_diff) { if (v == null) v = View.inflate(c, R.layout.today_boundary_item, null); - final StringResources sr = RuntimeResources.get(c).getStringResources(); + final StringResources sr = ((JttApplication) c.getApplicationContext()).getStringResources(); ((TextView) v.findViewById(R.id.time)).setText(sr.format_time(time)); int level; switch (sel_p_diff) { diff --git a/src/main/java/com/aragaer/jtt/today/HourItem.java b/src/main/java/com/aragaer/jtt/today/HourItem.java index 294c1a7..cd6c16a 100644 --- a/src/main/java/com/aragaer/jtt/today/HourItem.java +++ b/src/main/java/com/aragaer/jtt/today/HourItem.java @@ -3,8 +3,8 @@ package com.aragaer.jtt.today; import com.aragaer.jtt.R; +import com.aragaer.jtt.android.JttApplication; import com.aragaer.jtt.core.Hour; -import com.aragaer.jtt.resources.RuntimeResources; import com.aragaer.jtt.resources.StringResources; import android.content.Context; @@ -26,7 +26,7 @@ class HourItem extends TodayItem { public View toView(Context c, View v, int sel_p_diff) { if (v == null) v = View.inflate(c, R.layout.today_item, null); - final StringResources sr = RuntimeResources.get(c).getStringResources(); + final StringResources sr = ((JttApplication) c.getApplicationContext()).getStringResources(); ((TextView) v.findViewById(R.id.glyph)).setText(Hour.Glyphs[hnum]); ((TextView) v.findViewById(R.id.name)).setText(sr.getHrOf(hnum)); diff --git a/src/main/res/layout/today_item.xml b/src/main/res/layout/today_item.xml index cfdb326..75fa8d8 100644 --- a/src/main/res/layout/today_item.xml +++ b/src/main/res/layout/today_item.xml @@ -18,7 +18,7 @@ android:layout_height="wrap_content" android:layout_gravity="center" android:textSize="@dimen/today_glyph_size" - android:layout_marginTop="-3dp" + android:layout_marginTop="-1dp" android:layout_marginLeft="7dp" android:layout_marginRight="5dp"/> diff --git a/src/test/java/com/aragaer/jtt/ServiceComponentTest.java b/src/test/java/com/aragaer/jtt/JttComponentTest.java similarity index 86% rename from src/test/java/com/aragaer/jtt/ServiceComponentTest.java rename to src/test/java/com/aragaer/jtt/JttComponentTest.java index 5aee848..de069ca 100644 --- a/src/test/java/com/aragaer/jtt/ServiceComponentTest.java +++ b/src/test/java/com/aragaer/jtt/JttComponentTest.java @@ -15,15 +15,15 @@ import com.aragaer.jtt.mechanics.*; -public class ServiceComponentTest { +public class JttComponentTest { private static final long MS_PER_DAY = TimeUnit.DAYS.toMillis(1); - private ServiceComponent serviceComponent; + private JttComponent jttComponent; @Before public void setUp() { TestMechanicsModule mechanicsModule = new TestMechanicsModule(); - serviceComponent = DaggerServiceComponent + jttComponent = DaggerJttComponent .builder() .mechanicsModule(mechanicsModule) .astronomyModule(new TestAstronomyModule()) @@ -31,15 +31,15 @@ public class ServiceComponentTest { } @Test public void testGetTicker() { - Ticker ticker = serviceComponent.getTicker(); + Ticker ticker = jttComponent.getTicker(); ticker.start(); ticker.stop(); assertEquals("There is only one ticker ever", - ticker, serviceComponent.getTicker()); + ticker, jttComponent.getTicker()); } @Test public void testSolarEventCalculator() { - SolarEventCalculator calculator = serviceComponent.provideSolarEventCalculator(); + SolarEventCalculator calculator = jttComponent.provideSolarEventCalculator(); assertNotNull(calculator); } @@ -47,7 +47,7 @@ public class ServiceComponentTest { @Test public void testGetIntervalProvider() { long timestamp = 0; long tzOffset = TimeZone.getDefault().getOffset(timestamp); - IntervalProvider intervalProvider = serviceComponent.provideIntervalProvider(); + IntervalProvider intervalProvider = jttComponent.provideIntervalProvider(); ThreeIntervals intervals = intervalProvider.getIntervalsForTimestamp(0); assertFalse("Is night", intervals.isDay()); assertEquals("Previous sunrise", -MS_PER_DAY*3/4-tzOffset, intervals.getTransitions()[0]); @@ -57,7 +57,7 @@ public class ServiceComponentTest { } @Test public void testGetClockwork() { - Clockwork clockwork = serviceComponent.provideClockwork(); + Clockwork clockwork = jttComponent.provideClockwork(); clockwork.setTime(System.currentTimeMillis()); } } diff --git a/src/test/java/com/aragaer/jtt/JttServiceTest.java b/src/test/java/com/aragaer/jtt/JttServiceTest.java deleted file mode 100644 index 5b60375..0000000 --- a/src/test/java/com/aragaer/jtt/JttServiceTest.java +++ /dev/null @@ -1,80 +0,0 @@ -// -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; -*- -// vim: et ts=4 sts=4 sw=4 syntax=java -package com.aragaer.jtt; - -import static org.junit.Assert.*; -import static org.mockito.Matchers.*; -import static org.powermock.api.mockito.PowerMockito.*; - -import java.util.LinkedList; - -import android.app.Service; -import android.content.*; -import android.preference.PreferenceManager; -import android.os.Handler; -import android.util.Log; - -import org.junit.*; -import org.junit.runner.RunWith; -import org.powermock.modules.junit4.PowerMockRunner; -import org.powermock.core.classloader.annotations.PrepareForTest; - -import com.aragaer.jtt.mechanics.AndroidTicker; - - -@RunWith(PowerMockRunner.class) -@PrepareForTest({AndroidTicker.class, Log.class, Service.class, - PreferenceManager.class}) -public class JttServiceTest { - - private static final SharedPreferences mockPref = mock(SharedPreferences.class); - - private TestJttService service; - - @Before public void setUp() { - mockStatic(Log.class); - mockStatic(PreferenceManager.class); - when(PreferenceManager.getDefaultSharedPreferences(any(Context.class))) - .thenReturn(mockPref); - when(mockPref.getString(eq(Settings.PREF_LOCATION), anyString())) - .thenReturn("0.0:0.0"); - suppress(method(Handler.class, "sendEmptyMessage")); - suppress(method(Service.class, "onCreate")); - - service = new TestJttService(); - } - - @Test public void testCreate() { - service.onCreate(); - assertEquals("Two receivers registered in onCreate", - 2, service.receivers.size()); - } - - @Test public void testStart() { - service.onCreate(); - service.resetReceivers(); - int result = service.onStartCommand(null, 0, 0); - assertEquals("onStartCommand returns START_STICKY", - Service.START_STICKY, result); - assertEquals("No receivers registered in onStartCommand", - 0, service.receivers.size()); - } - -} - -class TestJttService extends JttService { - final LinkedList receivers = new LinkedList<>(); - private final LinkedList filters = new LinkedList<>(); - - @Override public Intent registerReceiver(BroadcastReceiver receiver, - IntentFilter intentFilter) { - receivers.add(receiver); - filters.add(intentFilter); - return null; - } - - public void resetReceivers() { - receivers.clear(); - filters.clear(); - } -} diff --git a/src/test/java/com/aragaer/jtt/android/TimeChangeReceiverTest.java b/src/test/java/com/aragaer/jtt/android/TimeChangeReceiverTest.java deleted file mode 100644 index 6e4564d..0000000 --- a/src/test/java/com/aragaer/jtt/android/TimeChangeReceiverTest.java +++ /dev/null @@ -1,64 +0,0 @@ -// -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; -*- -// vim: et ts=4 sts=4 sw=4 syntax=java -package com.aragaer.jtt.android; - -import static org.mockito.Matchers.*; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.verify; -import static org.powermock.api.mockito.PowerMockito.*; - -import android.content.*; -import android.os.Handler; - -import org.junit.*; -import org.junit.runner.RunWith; -import org.mockito.ArgumentCaptor; -import org.powermock.modules.junit4.PowerMockRunner; -import org.powermock.core.classloader.annotations.PrepareForTest; - -import com.aragaer.jtt.mechanics.AndroidTicker; - - -@RunWith(PowerMockRunner.class) -@PrepareForTest(AndroidTicker.class) -public class TimeChangeReceiverTest { - - private Context mockContext; - private Intent mockIntent; - private TimeChangeReceiver receiver; - - @Before public void setUp() { - receiver = new TimeChangeReceiver(); - mockIntent = mock(Intent.class); - mockContext = mock(Context.class); - } - - @Test public void testReceiveNoAction() { - receiver.onReceive(mockContext, mockIntent); - verify(mockContext, never()).startService(any(Intent.class)); - } - - @Test public void testReceiveTimeChanged() { - ArgumentCaptor captor = ArgumentCaptor.forClass(Intent.class); - suppress(method(Handler.class, "sendEmptyMessage")); - when(mockIntent.getAction()).thenReturn(Intent.ACTION_TIME_CHANGED); - receiver.onReceive(mockContext, mockIntent); - verify(mockContext).startService(captor.capture()); - // Instrumentation test checks that this actually triggers Jtt Tick event - } - - @Test public void testReceiveDateChanged() { - ArgumentCaptor captor = ArgumentCaptor.forClass(Intent.class); - suppress(method(Handler.class, "sendEmptyMessage")); - when(mockIntent.getAction()).thenReturn(Intent.ACTION_TIME_CHANGED); - receiver.onReceive(mockContext, mockIntent); - verify(mockContext).startService(captor.capture()); - // Instrumentation test checks that this actually triggers Jtt Tick event - } - - @Test public void testReceiveSomethingElse() { - when(mockIntent.getAction()).thenReturn(Intent.ACTION_BOOT_COMPLETED); - receiver.onReceive(mockContext, mockIntent); - verify(mockContext, never()).startService(any(Intent.class)); - } -} diff --git a/src/test/java/com/aragaer/jtt/resources/RuntimeResourcesTest.java b/src/test/java/com/aragaer/jtt/resources/RuntimeResourcesTest.java deleted file mode 100644 index 7e32314..0000000 --- a/src/test/java/com/aragaer/jtt/resources/RuntimeResourcesTest.java +++ /dev/null @@ -1,71 +0,0 @@ -// -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; -*- -// vim: et ts=4 sts=4 sw=4 syntax=java -package com.aragaer.jtt.resources; - -import static org.junit.Assert.*; -import static org.powermock.api.mockito.PowerMockito.*; - -import android.content.Context; -import android.content.SharedPreferences; -import android.content.res.Configuration; -import android.content.res.Resources; -import android.preference.PreferenceManager; -import android.text.format.DateFormat; -import android.util.Log; - -import com.aragaer.jtt.R; -import com.aragaer.jtt.Settings; - -import org.junit.*; -import org.junit.runner.RunWith; -import org.powermock.modules.junit4.PowerMockRunner; -import org.powermock.core.classloader.annotations.PrepareForTest; - - -@RunWith(PowerMockRunner.class) -@PrepareForTest({Log.class, Configuration.class, PreferenceManager.class, - SharedPreferences.class, Resources.class, Context.class, - DateFormat.class}) -public class RuntimeResourcesTest { - - private static final Context mockContext = mock(Context.class); - private final SharedPreferences mockPref = mock(SharedPreferences.class); - private final Resources resources = mock(Resources.class); - private final Configuration config = mock(Configuration.class); - - @Before public void setUp() { - mockStatic(Log.class); - mockStatic(PreferenceManager.class); - mockStatic(Resources.class); - mockStatic(DateFormat.class); - when(mockContext.getApplicationContext()).thenReturn(mockContext); - when(mockContext.getResources()).thenReturn(resources); - when(PreferenceManager.getDefaultSharedPreferences(mockContext)).thenReturn(mockPref); - when(mockPref.getString(Settings.PREF_HNAME, "0")).thenReturn("0"); - when(mockPref.getString(Settings.PREF_LOCALE, "")).thenReturn(""); - when(Resources.getSystem()).thenReturn(resources); - when(resources.getConfiguration()).thenReturn(config); - when(resources.getStringArray(R.array.hour)).thenReturn(new String[] {""}); - when(resources.getStringArray(R.array.hour_of)).thenReturn(new String[] {""}); - when(resources.getStringArray(R.array.quarter)).thenReturn(new String[] {""}); - } - - @Test public void test_canGetForContext() { - RuntimeResources rr = RuntimeResources.get(mockContext); - assertNotNull(rr); - } - - @Test public void test_isSingleton() { - RuntimeResources rr = RuntimeResources.get(mockContext); - RuntimeResources rr2 = RuntimeResources.get(mockContext); - - assertEquals(rr, rr2); - } - - @Test public void test_canGetStringResources() { - RuntimeResources rr = RuntimeResources.get(mockContext); - StringResources sr = rr.getStringResources(); - - assertNotNull(sr); - } -}