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); - } -}