From 1e8be31ab54bab02b5d9179f5c4f32cf0ae1b06e Mon Sep 17 00:00:00 2001 From: serso Date: Wed, 13 Jan 2016 17:41:05 +0100 Subject: [PATCH] Dagger 2 DI --- app/build.gradle | 6 + .../android/calculator/AndroidCalculator.java | 17 ++- .../org/solovyev/android/calculator/App.java | 96 +++------------- .../android/calculator/AppComponent.java | 16 +++ .../android/calculator/AppModule.java | 106 ++++++++++++++++++ .../solovyev/android/calculator/BaseUi.java | 14 ++- .../calculator/CalculatorActivity.java | 18 ++- .../CalculatorActivityLauncher.java | 6 +- .../calculator/CalculatorApplication.java | 69 ++++++++---- .../calculator/CalculatorBroadcaster.java | 16 ++- .../android/calculator/CalculatorButtons.java | 2 +- .../calculator/CalculatorDisplayFragment.java | 4 +- .../CalculatorDisplayOnClickListener.java | 2 +- .../calculator/CalculatorEditorFragment.java | 24 ++-- .../android/calculator/CalculatorImpl.java | 15 +-- .../android/calculator/CalculatorLocator.java | 26 +---- .../calculator/CalculatorSpecialButton.java | 48 ++++---- .../calculator/CursorDragProcessor.java | 11 +- .../calculator/DigitButtonDragProcessor.java | 8 +- .../solovyev/android/calculator/Display.java | 17 ++- .../solovyev/android/calculator/Editor.java | 22 +++- .../android/calculator/EditorView.java | 29 ++++- ...{CalculatorKeyboard.java => Keyboard.java} | 27 +++-- .../solovyev/android/calculator/Locator.java | 54 ++------- .../solovyev/android/calculator/ga/Ga.java | 5 +- .../history/BaseHistoryFragment.java | 5 +- .../android/calculator/history/History.java | 23 ++-- .../history/HistoryDragProcessor.java | 9 +- .../history/RecentHistoryFragment.java | 5 +- .../history/SavedHistoryFragment.java | 5 +- .../onscreen/CalculatorOnscreenService.java | 27 ++++- .../calculator/view/EditorTextProcessor.java | 14 +-- .../calculator/view/LongClickEraser.java | 3 +- .../calculator/widget/CalculatorWidget.java | 4 +- .../calculator/AbstractCalculatorTest.java | 3 +- .../calculator/AndroidEditorViewTest.java | 2 +- .../calculator/CalculatorReceiverTest.java | 4 +- .../calculator/CalculatorTestUtils.java | 19 ++-- .../calculator/history/HistoryTest.java | 19 +++- build.gradle | 1 + 40 files changed, 486 insertions(+), 315 deletions(-) create mode 100644 app/src/main/java/org/solovyev/android/calculator/AppComponent.java create mode 100644 app/src/main/java/org/solovyev/android/calculator/AppModule.java rename app/src/main/java/org/solovyev/android/calculator/{CalculatorKeyboard.java => Keyboard.java} (88%) diff --git a/app/build.gradle b/app/build.gradle index 2e662abd..68b2367b 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -23,6 +23,7 @@ apply plugin: 'com.android.application' apply plugin: 'maven' apply plugin: 'signing' +apply plugin: 'com.neenbedankt.android-apt' android { compileSdkVersion 23 @@ -98,6 +99,11 @@ dependencies { } compile 'commons-cli:commons-cli:1.2' compile 'com.squareup:otto:1.3.8' + + compile 'com.google.dagger:dagger:2.0.2' + apt "com.google.dagger:dagger-compiler:2.0.2" + compile 'javax.annotation:jsr250-api:1.0' + testCompile 'junit:junit:4.12' testCompile 'net.sf.opencsv:opencsv:2.0' testCompile 'org.mockito:mockito-core:1.9.0' diff --git a/app/src/main/java/org/solovyev/android/calculator/AndroidCalculator.java b/app/src/main/java/org/solovyev/android/calculator/AndroidCalculator.java index 76bdf00a..f341570c 100644 --- a/app/src/main/java/org/solovyev/android/calculator/AndroidCalculator.java +++ b/app/src/main/java/org/solovyev/android/calculator/AndroidCalculator.java @@ -25,14 +25,20 @@ package org.solovyev.android.calculator; import android.app.Application; import android.content.SharedPreferences; import android.preference.PreferenceManager; -import jscl.NumeralBase; -import jscl.math.Generic; + +import com.squareup.otto.Bus; + import org.solovyev.android.calculator.jscl.JsclOperation; import org.solovyev.common.msg.Message; +import java.util.List; +import java.util.concurrent.Executor; + import javax.annotation.Nonnull; import javax.annotation.Nullable; -import java.util.List; + +import jscl.NumeralBase; +import jscl.math.Generic; /** * User: serso @@ -42,13 +48,14 @@ import java.util.List; public class AndroidCalculator implements Calculator, CalculatorEventListener, SharedPreferences.OnSharedPreferenceChangeListener { @Nonnull - private final CalculatorImpl calculator = new CalculatorImpl(); + private final CalculatorImpl calculator; @Nonnull private final Application context; - public AndroidCalculator(@Nonnull Application application) { + public AndroidCalculator(@Nonnull Application application, @Nonnull Bus bus, Executor eventExecutor) { this.context = application; + this.calculator = new CalculatorImpl(bus, eventExecutor); this.calculator.addCalculatorEventListener(this); PreferenceManager.getDefaultSharedPreferences(application).registerOnSharedPreferenceChangeListener(this); diff --git a/app/src/main/java/org/solovyev/android/calculator/App.java b/app/src/main/java/org/solovyev/android/calculator/App.java index 469fcd93..2bf2ad1d 100644 --- a/app/src/main/java/org/solovyev/android/calculator/App.java +++ b/app/src/main/java/org/solovyev/android/calculator/App.java @@ -29,8 +29,6 @@ import android.content.pm.PackageManager; import android.content.res.Configuration; import android.graphics.Typeface; import android.os.Build; -import android.os.Handler; -import android.os.Looper; import android.preference.PreferenceManager; import android.support.annotation.NonNull; import android.support.v4.app.DialogFragment; @@ -40,12 +38,10 @@ import android.support.v4.app.FragmentTransaction; import android.text.Spannable; import android.text.SpannableString; import android.text.style.ForegroundColorSpan; -import android.util.Log; import com.squareup.otto.Bus; import org.solovyev.android.Check; -import org.solovyev.android.UiThreadExecutor; import org.solovyev.android.Views; import org.solovyev.android.calculator.ga.Ga; import org.solovyev.android.calculator.language.Languages; @@ -60,10 +56,6 @@ import org.solovyev.android.checkout.Products; import org.solovyev.android.checkout.RobotmediaDatabase; import org.solovyev.android.checkout.RobotmediaInventory; import org.solovyev.android.wizard.Wizards; -import org.solovyev.common.listeners.JEvent; -import org.solovyev.common.listeners.JEventListener; -import org.solovyev.common.listeners.JEventListeners; -import org.solovyev.common.listeners.Listeners; import org.solovyev.common.threads.DelayedExecutor; import java.util.Arrays; @@ -75,12 +67,6 @@ import java.util.concurrent.atomic.AtomicInteger; import javax.annotation.Nonnull; import javax.annotation.Nullable; -/** - * User: serso - * Date: 12/1/12 - * Time: 3:58 PM - */ - /** * This class aggregates several useful in any Android application interfaces and provides access to {@link android.app.Application} object from a static context. * NOTE: use this class only if you don't use and dependency injection library (if you use any you can directly set interfaces through it).
@@ -108,13 +94,9 @@ public final class App { @Nonnull private static volatile Application application; @Nonnull - private static volatile DelayedExecutor uiThreadExecutor; - @Nonnull - private static Bus bus; + private static Executor uiThreadExecutor; private static volatile boolean initialized; @Nonnull - private static CalculatorBroadcaster broadcaster; - @Nonnull private static SharedPreferences preferences; @Nonnull private static volatile Ga ga; @@ -127,16 +109,13 @@ public final class App { @Nonnull private static volatile ScreenMetrics screenMetrics; @Nonnull - private static final Handler handler = new Handler(Looper.getMainLooper()); - @Nonnull private static Wizards wizards; @Nonnull - private static final Executor initThread = Executors.newSingleThreadExecutor(new ThreadFactory() { - @Override - public Thread newThread(@Nonnull Runnable r) { - return new Thread(r, "Init"); - } - }); + private static Editor editor; + @Nonnull + private static Bus bus; + @Nonnull + private static Display display; @Nonnull private static final Executor background = Executors.newFixedThreadPool(5, new ThreadFactory() { @NonNull @@ -151,22 +130,15 @@ public final class App { throw new AssertionError(); } - public static void init(@Nonnull Application application, @Nonnull Languages languages) { - init(application, new UiThreadExecutor(), Listeners.newEventBus(), languages); - } - - public static void init(@Nonnull Application application, - @Nonnull UiThreadExecutor uiThreadExecutor, - @Nonnull JEventListeners, JEvent> eventBus, + public static void init(@Nonnull CalculatorApplication application, @Nonnull Languages languages) { if (initialized) { throw new IllegalStateException("Already initialized!"); } App.application = application; App.preferences = PreferenceManager.getDefaultSharedPreferences(application); - App.uiThreadExecutor = uiThreadExecutor; - App.bus = new MyBus(); - App.ga = new Ga(application, preferences, eventBus); + App.uiThreadExecutor = application.uiThread; + App.ga = new Ga(application, preferences); App.billing = new Billing(application, new Billing.DefaultConfiguration() { @Nonnull @Override @@ -184,11 +156,13 @@ public final class App { } } }); - App.broadcaster = new CalculatorBroadcaster(application, preferences, bus); App.screenMetrics = new ScreenMetrics(application); App.languages = languages; App.languages.init(); App.wizards = new CalculatorWizards(application); + App.editor = application.editor; + App.display = application.display; + App.bus = application.bus; App.initialized = true; } @@ -215,33 +189,15 @@ public final class App { * @return UI thread executor */ @Nonnull - public static DelayedExecutor getUiThreadExecutor() { + public static Executor getUiThreadExecutor() { return uiThreadExecutor; } - /** - * @return application's event bus - */ - @Nonnull - public static Bus getBus() { - return bus; - } - - @Nonnull - public static CalculatorBroadcaster getBroadcaster() { - return broadcaster; - } - @Nonnull public static Wizards getWizards() { return wizards; } - @Nonnull - public static Handler getHandler() { - return handler; - } - @Nonnull public static Ga getGa() { return ga; @@ -276,11 +232,6 @@ public final class App { return Preferences.Widget.getTheme(getPreferences()); } - @Nonnull - public static Executor getInitThread() { - return initThread; - } - @Nonnull public static Executor getBackground() { return background; @@ -363,27 +314,16 @@ public final class App { @Nonnull public static Editor getEditor() { - return Locator.getInstance().getEditor(); + return editor; } @Nonnull public static Display getDisplay() { - return Locator.getInstance().getDisplay(); + return display; } - private static class MyBus extends Bus { - @Override - public void post(final Object event) { - if (Looper.myLooper() == Looper.getMainLooper()) { - super.post(event); - return; - } - handler.post(new Runnable() { - @Override - public void run() { - MyBus.super.post(event); - } - }); - } + @Nonnull + public static Bus getBus() { + return bus; } } \ No newline at end of file diff --git a/app/src/main/java/org/solovyev/android/calculator/AppComponent.java b/app/src/main/java/org/solovyev/android/calculator/AppComponent.java new file mode 100644 index 00000000..f461ee54 --- /dev/null +++ b/app/src/main/java/org/solovyev/android/calculator/AppComponent.java @@ -0,0 +1,16 @@ +package org.solovyev.android.calculator; + +import org.solovyev.android.calculator.onscreen.CalculatorOnscreenService; + +import javax.inject.Singleton; + +import dagger.Component; + +@Singleton +@Component(modules = AppModule.class) +public interface AppComponent { + void inject(CalculatorApplication application); + void inject(CalculatorEditorFragment fragment); + void inject(BaseUi ui); + void inject(CalculatorOnscreenService service); +} diff --git a/app/src/main/java/org/solovyev/android/calculator/AppModule.java b/app/src/main/java/org/solovyev/android/calculator/AppModule.java new file mode 100644 index 00000000..788ac088 --- /dev/null +++ b/app/src/main/java/org/solovyev/android/calculator/AppModule.java @@ -0,0 +1,106 @@ +package org.solovyev.android.calculator; + +import android.app.Application; +import android.content.SharedPreferences; +import android.os.Handler; +import android.os.Looper; +import android.preference.PreferenceManager; +import android.support.annotation.NonNull; + +import com.squareup.otto.Bus; + +import org.solovyev.android.UiThreadExecutor; + +import java.util.concurrent.Executor; +import java.util.concurrent.Executors; +import java.util.concurrent.ThreadFactory; + +import javax.annotation.Nonnull; +import javax.inject.Named; +import javax.inject.Singleton; + +import dagger.Module; +import dagger.Provides; + +@Module +public class AppModule { + + @NonNull + public static final String THREAD_INIT = "thread-init"; + @NonNull + public static final String THREAD_UI = "thread-ui"; + + @NonNull + private final Application application; + + public AppModule(@NonNull Application application) { + this.application = application; + } + + @Provides + @Singleton + Handler provideHandler() { + return new Handler(Looper.getMainLooper()); + } + + @Provides + @Singleton + Bus provideBus(Handler handler) { + return new AppBus(handler); + } + + @Provides + @Singleton + SharedPreferences providePreferences() { + return PreferenceManager.getDefaultSharedPreferences(application); + } + + @Provides + @Singleton + Calculator provideCalculator(Bus bus, @Named(THREAD_UI) Executor executor) { + return new AndroidCalculator(application, bus, executor); + } + + @Provides + @Singleton + @Named(THREAD_INIT) + Executor provideInitThread() { + return Executors.newSingleThreadExecutor(new ThreadFactory() { + @Override + public Thread newThread(@Nonnull Runnable r) { + return new Thread(r, "Init"); + } + }); + } + + @Provides + @Singleton + @Named(THREAD_UI) + Executor provideUiThread() { + return new UiThreadExecutor(); + } + + private static class AppBus extends Bus { + + @NonNull + private final Handler handler; + + public AppBus(@Nonnull Handler handler) { + this.handler = handler; + } + + @Override + public void post(final Object event) { + if (Looper.myLooper() == Looper.getMainLooper()) { + super.post(event); + return; + } + handler.post(new Runnable() { + @Override + public void run() { + AppBus.super.post(event); + } + }); + } + } +} diff --git a/app/src/main/java/org/solovyev/android/calculator/BaseUi.java b/app/src/main/java/org/solovyev/android/calculator/BaseUi.java index ff08ee37..b21d4ffb 100644 --- a/app/src/main/java/org/solovyev/android/calculator/BaseUi.java +++ b/app/src/main/java/org/solovyev/android/calculator/BaseUi.java @@ -43,6 +43,8 @@ import org.solovyev.android.views.dragbutton.*; import javax.annotation.Nonnull; import javax.annotation.Nullable; +import javax.inject.Inject; + import java.util.ArrayList; import java.util.List; @@ -110,8 +112,14 @@ public abstract class BaseUi implements SharedPreferences.OnSharedPreferenceChan return viewIds; } + @Inject + SharedPreferences preferences; + + @Inject + Editor editor; + protected void onCreate(@Nonnull Activity activity) { - final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(activity); + ((CalculatorApplication) activity.getApplication()).getComponent().inject(this); layout = Preferences.Gui.layout.getPreferenceNoError(preferences); theme = Preferences.Gui.theme.getPreferenceNoError(preferences); @@ -170,7 +178,7 @@ public abstract class BaseUi implements SharedPreferences.OnSharedPreferenceChan minusButton.setOnDragListener(newDragListener(new OperatorsDragProcessor(), activity)); } - final DragListener toPositionDragListener = new SimpleDragListener(new CursorDragProcessor(), activity); + final DragListener toPositionDragListener = new SimpleDragListener(new CursorDragProcessor(editor), activity); final DragButton rightButton = getButton(views, R.id.cpp_button_right); if (rightButton != null) { @@ -278,7 +286,7 @@ public abstract class BaseUi implements SharedPreferences.OnSharedPreferenceChan } @Nonnull - private CalculatorKeyboard getKeyboard() { + private Keyboard getKeyboard() { return Locator.getInstance().getKeyboard(); } diff --git a/app/src/main/java/org/solovyev/android/calculator/CalculatorActivity.java b/app/src/main/java/org/solovyev/android/calculator/CalculatorActivity.java index e1a11bef..b5f21f93 100644 --- a/app/src/main/java/org/solovyev/android/calculator/CalculatorActivity.java +++ b/app/src/main/java/org/solovyev/android/calculator/CalculatorActivity.java @@ -32,11 +32,17 @@ import android.os.Bundle; import android.preference.PreferenceManager; import android.support.v7.app.ActionBar; import android.text.method.LinkMovementMethod; -import android.view.*; +import android.view.KeyEvent; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewConfiguration; +import android.view.Window; import android.widget.TextView; + import org.solovyev.android.Activities; import org.solovyev.android.Android; import org.solovyev.android.Threads; +import org.solovyev.android.calculator.history.History; import org.solovyev.android.calculator.plot.CalculatorPlotActivity; import org.solovyev.android.calculator.wizard.CalculatorWizards; import org.solovyev.android.fragments.FragmentUtils; @@ -47,13 +53,16 @@ import org.solovyev.common.Objects; import javax.annotation.Nonnull; import javax.annotation.Nullable; +import javax.inject.Inject; import static android.os.Build.VERSION_CODES.GINGERBREAD_MR1; import static android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH; import static android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON; import static org.solovyev.android.calculator.Preferences.Gui.preventScreenFromFading; import static org.solovyev.android.calculator.release.ReleaseNotes.hasReleaseNotes; -import static org.solovyev.android.wizard.WizardUi.*; +import static org.solovyev.android.wizard.WizardUi.continueWizard; +import static org.solovyev.android.wizard.WizardUi.createLaunchIntent; +import static org.solovyev.android.wizard.WizardUi.startWizard; public class CalculatorActivity extends BaseActivity implements SharedPreferences.OnSharedPreferenceChangeListener, CalculatorEventListener { @@ -135,6 +144,9 @@ public class CalculatorActivity extends BaseActivity implements SharedPreference return result; } + @Inject + History history; + /** * Called when the activity is first created. */ @@ -203,7 +215,7 @@ public class CalculatorActivity extends BaseActivity implements SharedPreference public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK) { if (useBackAsPrev) { - Locator.getInstance().getHistory().undo(); + history.undo(); return true; } } diff --git a/app/src/main/java/org/solovyev/android/calculator/CalculatorActivityLauncher.java b/app/src/main/java/org/solovyev/android/calculator/CalculatorActivityLauncher.java index ebf8e216..525d8e58 100644 --- a/app/src/main/java/org/solovyev/android/calculator/CalculatorActivityLauncher.java +++ b/app/src/main/java/org/solovyev/android/calculator/CalculatorActivityLauncher.java @@ -136,7 +136,7 @@ public final class CalculatorActivityLauncher implements CalculatorEventListener } public static void tryCreateVar(@Nonnull final Context context) { - final Display display = Locator.getInstance().getDisplay(); + final Display display = App.getDisplay(); final DisplayState viewState = display.getState(); if (viewState.valid) { final String varValue = viewState.text; @@ -162,7 +162,7 @@ public final class CalculatorActivityLauncher implements CalculatorEventListener } public static void tryCreateFunction(@Nonnull final Context context) { - final Display display = Locator.getInstance().getDisplay(); + final Display display = App.getDisplay(); final DisplayState viewState = display.getState(); if (viewState.valid) { @@ -184,7 +184,7 @@ public final class CalculatorActivityLauncher implements CalculatorEventListener public static void tryPlot() { final CalculatorPlotter plotter = Locator.getInstance().getPlotter(); - final Display display = Locator.getInstance().getDisplay(); + final Display display = App.getDisplay(); final DisplayState viewState = display.getState(); if (viewState.valid) { diff --git a/app/src/main/java/org/solovyev/android/calculator/CalculatorApplication.java b/app/src/main/java/org/solovyev/android/calculator/CalculatorApplication.java index a547ce48..7e8edfaa 100644 --- a/app/src/main/java/org/solovyev/android/calculator/CalculatorApplication.java +++ b/app/src/main/java/org/solovyev/android/calculator/CalculatorApplication.java @@ -23,41 +23,78 @@ package org.solovyev.android.calculator; import android.content.SharedPreferences; +import android.os.Handler; import android.preference.PreferenceManager; import android.util.Log; import com.squareup.leakcanary.LeakCanary; +import com.squareup.otto.Bus; import org.acra.ACRA; import org.acra.ACRAConfiguration; import org.acra.sender.HttpSender; import org.solovyev.android.Android; -import org.solovyev.android.calculator.history.History; import org.solovyev.android.calculator.language.Language; import org.solovyev.android.calculator.language.Languages; import org.solovyev.android.calculator.model.AndroidCalculatorEngine; import org.solovyev.android.calculator.onscreen.CalculatorOnscreenStartActivity; import org.solovyev.android.calculator.plot.AndroidCalculatorPlotter; import org.solovyev.android.calculator.plot.CalculatorPlotterImpl; -import org.solovyev.android.calculator.view.EditorTextProcessor; import org.solovyev.common.msg.MessageType; import java.util.ArrayList; import java.util.List; import java.util.Locale; +import java.util.concurrent.Executor; import javax.annotation.Nonnull; +import javax.inject.Inject; +import javax.inject.Named; public class CalculatorApplication extends android.app.Application implements SharedPreferences.OnSharedPreferenceChangeListener { + + @Inject + @Named(AppModule.THREAD_INIT) + Executor initThread; + + @Inject + Handler handler; + @Nonnull private final List listeners = new ArrayList<>(); + private AppComponent component; + + @Inject + Editor editor; + + @Inject + Display display; + + @Inject + Bus bus; + + @Inject + Calculator calculator; + + @Inject + Keyboard keyboard; + + @Inject + @Named(AppModule.THREAD_UI) + Executor uiThread; + @Override public void onCreate() { final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this); final Languages languages = new Languages(preferences); onPreCreate(preferences, languages); + component = DaggerAppComponent.builder() + .appModule(new AppModule(this)) + .build(); + component.inject(this); + super.onCreate(); onPostCreate(preferences, languages); } @@ -69,22 +106,15 @@ public class CalculatorApplication extends android.app.Application implements Sh languages.updateContextLocale(this, true); App.getGa().reportInitially(preferences); - final AndroidCalculator calculator = new AndroidCalculator(this); - - final EditorTextProcessor editorTextProcessor = new EditorTextProcessor(); - Locator.getInstance().init(calculator, new AndroidCalculatorEngine(this), new AndroidCalculatorClipboard(this), new AndroidCalculatorNotifier(this), - new History(), new AndroidCalculatorLogger(), new AndroidCalculatorPreferenceService(this), - new CalculatorKeyboard(), - new AndroidCalculatorPlotter(this, new CalculatorPlotterImpl(calculator)), - editorTextProcessor); - - editorTextProcessor.init(this); + keyboard, + new AndroidCalculatorPlotter(this, new CalculatorPlotterImpl(calculator)) + ); listeners.add(new CalculatorActivityLauncher()); for (CalculatorEventListener listener : listeners) { @@ -93,20 +123,12 @@ public class CalculatorApplication extends android.app.Application implements Sh Locator.getInstance().getCalculator().init(); - App.getInitThread().execute(new Runnable() { + initThread.execute(new Runnable() { @Override public void run() { warmUpEngine(); } }); - - App.getHandler().postDelayed(new Runnable() { - @Override - public void run() { - // we must update the widget when app starts - App.getBroadcaster().sendInitIntent(); - } - }, 100); } private void warmUpEngine() { @@ -154,4 +176,9 @@ public class CalculatorApplication extends android.app.Application implements Sh Locator.getInstance().getNotifier().showMessage(R.string.cpp_this_change_may_require_reboot, MessageType.info); } } + + @Nonnull + public AppComponent getComponent() { + return component; + } } diff --git a/app/src/main/java/org/solovyev/android/calculator/CalculatorBroadcaster.java b/app/src/main/java/org/solovyev/android/calculator/CalculatorBroadcaster.java index e4e3e414..9219c974 100644 --- a/app/src/main/java/org/solovyev/android/calculator/CalculatorBroadcaster.java +++ b/app/src/main/java/org/solovyev/android/calculator/CalculatorBroadcaster.java @@ -3,13 +3,17 @@ package org.solovyev.android.calculator; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; +import android.os.Handler; + import com.squareup.otto.Bus; import com.squareup.otto.Subscribe; -import javax.annotation.Nonnull; import java.util.HashMap; import java.util.Map; +import javax.annotation.Nonnull; +import javax.inject.Inject; + public final class CalculatorBroadcaster implements SharedPreferences.OnSharedPreferenceChangeListener { public static final String ACTION_INIT = "org.solovyev.android.calculator.INIT"; @@ -21,10 +25,18 @@ public final class CalculatorBroadcaster implements SharedPreferences.OnSharedPr @Nonnull private final Intents intents = new Intents(); - public CalculatorBroadcaster(@Nonnull Context context, @Nonnull SharedPreferences preferences, @Nonnull Bus bus) { + @Inject + public CalculatorBroadcaster(@Nonnull Context context, @Nonnull SharedPreferences preferences, @Nonnull Bus bus, @Nonnull Handler handler) { this.context = context; preferences.registerOnSharedPreferenceChangeListener(this); bus.register(this); + handler.postDelayed(new Runnable() { + @Override + public void run() { + // we must update the widget when app starts + sendInitIntent(); + } + }, 100); } @Subscribe diff --git a/app/src/main/java/org/solovyev/android/calculator/CalculatorButtons.java b/app/src/main/java/org/solovyev/android/calculator/CalculatorButtons.java index c67e39f4..c2deb78f 100644 --- a/app/src/main/java/org/solovyev/android/calculator/CalculatorButtons.java +++ b/app/src/main/java/org/solovyev/android/calculator/CalculatorButtons.java @@ -107,7 +107,7 @@ public final class CalculatorButtons { } @Nonnull - private static CalculatorKeyboard getKeyboard() { + private static Keyboard getKeyboard() { return Locator.getInstance().getKeyboard(); } diff --git a/app/src/main/java/org/solovyev/android/calculator/CalculatorDisplayFragment.java b/app/src/main/java/org/solovyev/android/calculator/CalculatorDisplayFragment.java index 76370790..d9d08612 100644 --- a/app/src/main/java/org/solovyev/android/calculator/CalculatorDisplayFragment.java +++ b/app/src/main/java/org/solovyev/android/calculator/CalculatorDisplayFragment.java @@ -69,7 +69,7 @@ public class CalculatorDisplayFragment extends Fragment { super.onViewCreated(root, savedInstanceState); displayView = (DisplayView) root.findViewById(R.id.calculator_display); - Locator.getInstance().getDisplay().setView(displayView); + App.getDisplay().setView(displayView); fragmentUi.onViewCreated(this, root); } @@ -95,7 +95,7 @@ public class CalculatorDisplayFragment extends Fragment { @Override public void onDestroyView() { - Locator.getInstance().getDisplay().clearView(displayView); + App.getDisplay().clearView(displayView); fragmentUi.onDestroyView(this); super.onDestroyView(); } diff --git a/app/src/main/java/org/solovyev/android/calculator/CalculatorDisplayOnClickListener.java b/app/src/main/java/org/solovyev/android/calculator/CalculatorDisplayOnClickListener.java index 8e6b2ac8..9f501ebe 100644 --- a/app/src/main/java/org/solovyev/android/calculator/CalculatorDisplayOnClickListener.java +++ b/app/src/main/java/org/solovyev/android/calculator/CalculatorDisplayOnClickListener.java @@ -50,7 +50,7 @@ public class CalculatorDisplayOnClickListener implements View.OnClickListener { @Override public void onClick(View v) { if (v instanceof DisplayView) { - final Display cd = Locator.getInstance().getDisplay(); + final Display cd = App.getDisplay(); final DisplayState displayViewState = cd.getState(); diff --git a/app/src/main/java/org/solovyev/android/calculator/CalculatorEditorFragment.java b/app/src/main/java/org/solovyev/android/calculator/CalculatorEditorFragment.java index 53acaec1..10f907e4 100644 --- a/app/src/main/java/org/solovyev/android/calculator/CalculatorEditorFragment.java +++ b/app/src/main/java/org/solovyev/android/calculator/CalculatorEditorFragment.java @@ -25,7 +25,6 @@ package org.solovyev.android.calculator; import android.app.Activity; import android.content.SharedPreferences; import android.os.Bundle; -import android.preference.PreferenceManager; import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.Menu; @@ -39,23 +38,23 @@ import org.solovyev.android.menu.AndroidMenuHelper; import org.solovyev.android.menu.ListActivityMenu; import javax.annotation.Nonnull; +import javax.inject.Inject; -/** - * User: Solovyev_S - * Date: 25.09.12 - * Time: 10:49 - */ public class CalculatorEditorFragment extends Fragment { - @Nonnull private FragmentUi fragmentUi; @Nonnull private ActivityMenu menu = ListActivityMenu.fromEnum(CalculatorMenu.class, AndroidMenuHelper.getInstance()); - @Nonnull private EditorView editorView; + @Inject + Editor editor; + + @Inject + SharedPreferences preferences; + public CalculatorEditorFragment() { } @@ -66,7 +65,7 @@ public class CalculatorEditorFragment extends Fragment { fragmentUi.onViewCreated(this, view); editorView = (EditorView) view.findViewById(R.id.calculator_editor); - Locator.getInstance().getEditor().setView(editorView); + editor.setView(editorView); } @Override @@ -78,8 +77,9 @@ public class CalculatorEditorFragment extends Fragment { public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this.getActivity()); - final Preferences.Gui.Layout layout = Preferences.Gui.getLayout(prefs); + ((CalculatorApplication) getActivity().getApplication()).getComponent().inject(this); + + final Preferences.Gui.Layout layout = Preferences.Gui.getLayout(preferences); if (!layout.isOptimized()) { fragmentUi = new FragmentUi(R.layout.cpp_app_editor_mobile, R.string.editor); } else { @@ -109,7 +109,7 @@ public class CalculatorEditorFragment extends Fragment { @Override public void onDestroyView() { - Locator.getInstance().getEditor().clearView(editorView); + editor.clearView(editorView); fragmentUi.onDestroyView(this); super.onDestroyView(); } diff --git a/app/src/main/java/org/solovyev/android/calculator/CalculatorImpl.java b/app/src/main/java/org/solovyev/android/calculator/CalculatorImpl.java index b4485bc1..4352ffa1 100644 --- a/app/src/main/java/org/solovyev/android/calculator/CalculatorImpl.java +++ b/app/src/main/java/org/solovyev/android/calculator/CalculatorImpl.java @@ -24,6 +24,7 @@ package org.solovyev.android.calculator; import android.text.TextUtils; +import com.squareup.otto.Bus; import com.squareup.otto.Subscribe; import org.solovyev.android.calculator.jscl.JsclOperation; @@ -94,17 +95,17 @@ public class CalculatorImpl implements Calculator, CalculatorEventListener { @Nonnull private final Executor calculationsExecutor = Executors.newFixedThreadPool(10); - // NOTE: only one thread is responsible for events as all events must be done in order of their creating @Nonnull - private final Executor eventExecutor = App.getUiThreadExecutor(); + private final Executor eventExecutor; private volatile boolean calculateOnFly = true; private volatile long lastPreferenceCheck = 0L; - public CalculatorImpl() { - App.getBus().register(this); + public CalculatorImpl(@Nonnull Bus bus, @Nonnull Executor eventExecutor) { + this.eventExecutor = eventExecutor; + bus.register(this); this.addCalculatorEventListener(this); } @@ -373,7 +374,7 @@ public class CalculatorImpl implements Calculator, CalculatorEventListener { @Nonnull final NumeralBase to) { final CalculatorEventData eventDataId = nextEventData(); - final DisplayState displayViewState = Locator.getInstance().getDisplay().getState(); + final DisplayState displayViewState = App.getDisplay().getState(); final NumeralBase from = Locator.getInstance().getEngine().getNumeralBase(); calculationsExecutor.execute(new Runnable() { @@ -550,11 +551,11 @@ public class CalculatorImpl implements Calculator, CalculatorEventListener { @Nonnull private Editor getEditor() { - return Locator.getInstance().getEditor(); + return App.getEditor(); } @Nonnull private Display getDisplay() { - return Locator.getInstance().getDisplay(); + return App.getDisplay(); } } diff --git a/app/src/main/java/org/solovyev/android/calculator/CalculatorLocator.java b/app/src/main/java/org/solovyev/android/calculator/CalculatorLocator.java index 24b772f2..ccbb4edd 100644 --- a/app/src/main/java/org/solovyev/android/calculator/CalculatorLocator.java +++ b/app/src/main/java/org/solovyev/android/calculator/CalculatorLocator.java @@ -22,31 +22,20 @@ package org.solovyev.android.calculator; -import org.solovyev.android.calculator.history.History; import org.solovyev.android.calculator.plot.CalculatorPlotter; -import org.solovyev.android.calculator.text.TextProcessor; -import org.solovyev.android.calculator.text.TextProcessorEditorResult; import javax.annotation.Nonnull; -import javax.annotation.Nullable; -/** - * User: Solovyev_S - * Date: 20.09.12 - * Time: 12:45 - */ public interface CalculatorLocator { void init(@Nonnull Calculator calculator, @Nonnull CalculatorEngine engine, @Nonnull CalculatorClipboard clipboard, @Nonnull CalculatorNotifier notifier, - @Nonnull History history, @Nonnull CalculatorLogger logger, @Nonnull CalculatorPreferenceService preferenceService, - @Nonnull CalculatorKeyboard keyboard, - @Nonnull CalculatorPlotter plotter, - @Nullable TextProcessor editorTextProcessor); + @Nonnull Keyboard keyboard, + @Nonnull CalculatorPlotter plotter); @Nonnull Calculator getCalculator(); @@ -55,13 +44,7 @@ public interface CalculatorLocator { CalculatorEngine getEngine(); @Nonnull - Display getDisplay(); - - @Nonnull - Editor getEditor(); - - @Nonnull - CalculatorKeyboard getKeyboard(); + Keyboard getKeyboard(); @Nonnull CalculatorClipboard getClipboard(); @@ -69,9 +52,6 @@ public interface CalculatorLocator { @Nonnull CalculatorNotifier getNotifier(); - @Nonnull - History getHistory(); - @Nonnull CalculatorLogger getLogger(); diff --git a/app/src/main/java/org/solovyev/android/calculator/CalculatorSpecialButton.java b/app/src/main/java/org/solovyev/android/calculator/CalculatorSpecialButton.java index 4c91649d..4525ad57 100644 --- a/app/src/main/java/org/solovyev/android/calculator/CalculatorSpecialButton.java +++ b/app/src/main/java/org/solovyev/android/calculator/CalculatorSpecialButton.java @@ -37,76 +37,76 @@ public enum CalculatorSpecialButton { history("history") { @Override - public void onClick(@Nonnull CalculatorKeyboard keyboard) { + public void onClick(@Nonnull Keyboard keyboard) { Locator.getInstance().getCalculator().fireCalculatorEvent(CalculatorEventType.show_history, null); } }, history_detached("history_detached") { @Override - public void onClick(@Nonnull CalculatorKeyboard keyboard) { + public void onClick(@Nonnull Keyboard keyboard) { Locator.getInstance().getCalculator().fireCalculatorEvent(CalculatorEventType.show_history_detached, null); } }, cursor_right("▷") { @Override - public void onClick(@Nonnull CalculatorKeyboard keyboard) { + public void onClick(@Nonnull Keyboard keyboard) { keyboard.moveCursorRight(); } }, cursor_left("◁") { @Override - public void onClick(@Nonnull CalculatorKeyboard keyboard) { + public void onClick(@Nonnull Keyboard keyboard) { keyboard.moveCursorLeft(); } }, settings("settings") { @Override - public void onClick(@Nonnull CalculatorKeyboard keyboard) { + public void onClick(@Nonnull Keyboard keyboard) { Locator.getInstance().getCalculator().fireCalculatorEvent(CalculatorEventType.show_settings, null); } }, settings_detached("settings_detached") { @Override - public void onClick(@Nonnull CalculatorKeyboard keyboard) { + public void onClick(@Nonnull Keyboard keyboard) { Locator.getInstance().getCalculator().fireCalculatorEvent(CalculatorEventType.show_settings_detached, null); } }, settings_widget("settings_widget") { @Override - public void onClick(@Nonnull CalculatorKeyboard keyboard) { + public void onClick(@Nonnull Keyboard keyboard) { Locator.getInstance().getCalculator().fireCalculatorEvent(CalculatorEventType.show_settings_widget, null); } }, like("like") { @Override - public void onClick(@Nonnull CalculatorKeyboard keyboard) { + public void onClick(@Nonnull Keyboard keyboard) { Locator.getInstance().getCalculator().fireCalculatorEvent(CalculatorEventType.show_like_dialog, null); } }, erase("erase") { @Override - public void onClick(@Nonnull CalculatorKeyboard keyboard) { - Locator.getInstance().getEditor().erase(); + public void onClick(@Nonnull Keyboard keyboard) { + App.getEditor().erase(); } }, paste("paste") { @Override - public void onClick(@Nonnull CalculatorKeyboard keyboard) { + public void onClick(@Nonnull Keyboard keyboard) { keyboard.pasteButtonPressed(); } }, copy("copy") { @Override - public void onClick(@Nonnull CalculatorKeyboard keyboard) { + public void onClick(@Nonnull Keyboard keyboard) { keyboard.copyButtonPressed(); } }, equals("=") { @Override - public void onClick(@Nonnull CalculatorKeyboard keyboard) { + public void onClick(@Nonnull Keyboard keyboard) { final Calculator calculator = Locator.getInstance().getCalculator(); if (!calculator.isCalculateOnFly()) { // no automatic calculations are => equals button must be used to calculate @@ -114,59 +114,59 @@ public enum CalculatorSpecialButton { return; } - final DisplayState displayState = Locator.getInstance().getDisplay().getState(); + final DisplayState displayState = App.getDisplay().getState(); if (!displayState.valid) { return; } - Locator.getInstance().getEditor().setText(displayState.text); + App.getEditor().setText(displayState.text); } }, clear("clear") { @Override - public void onClick(@Nonnull CalculatorKeyboard keyboard) { + public void onClick(@Nonnull Keyboard keyboard) { keyboard.clearButtonPressed(); } }, functions("functions") { @Override - public void onClick(@Nonnull CalculatorKeyboard keyboard) { + public void onClick(@Nonnull Keyboard keyboard) { Locator.getInstance().getCalculator().fireCalculatorEvent(CalculatorEventType.show_functions, null); } }, functions_detached("functions_detached") { @Override - public void onClick(@Nonnull CalculatorKeyboard keyboard) { + public void onClick(@Nonnull Keyboard keyboard) { Locator.getInstance().getCalculator().fireCalculatorEvent(CalculatorEventType.show_functions_detached, null); } }, open_app("open_app") { @Override - public void onClick(@Nonnull CalculatorKeyboard keyboard) { + public void onClick(@Nonnull Keyboard keyboard) { Locator.getInstance().getCalculator().fireCalculatorEvent(CalculatorEventType.open_app, null); } }, vars("vars") { @Override - public void onClick(@Nonnull CalculatorKeyboard keyboard) { + public void onClick(@Nonnull Keyboard keyboard) { Locator.getInstance().getCalculator().fireCalculatorEvent(CalculatorEventType.show_vars, null); } }, vars_detached("vars_detached") { @Override - public void onClick(@Nonnull CalculatorKeyboard keyboard) { + public void onClick(@Nonnull Keyboard keyboard) { Locator.getInstance().getCalculator().fireCalculatorEvent(CalculatorEventType.show_vars_detached, null); } }, operators("operators") { @Override - public void onClick(@Nonnull CalculatorKeyboard keyboard) { + public void onClick(@Nonnull Keyboard keyboard) { Locator.getInstance().getCalculator().fireCalculatorEvent(CalculatorEventType.show_operators, null); } }, operators_detached("operators_detached") { @Override - public void onClick(@Nonnull CalculatorKeyboard keyboard) { + public void onClick(@Nonnull Keyboard keyboard) { Locator.getInstance().getCalculator().fireCalculatorEvent(CalculatorEventType.show_operators_detached, null); } }; @@ -207,5 +207,5 @@ public enum CalculatorSpecialButton { return actionCode; } - public abstract void onClick(@Nonnull CalculatorKeyboard keyboard); + public abstract void onClick(@Nonnull Keyboard keyboard); } diff --git a/app/src/main/java/org/solovyev/android/calculator/CursorDragProcessor.java b/app/src/main/java/org/solovyev/android/calculator/CursorDragProcessor.java index 0b495efc..44fed6f0 100644 --- a/app/src/main/java/org/solovyev/android/calculator/CursorDragProcessor.java +++ b/app/src/main/java/org/solovyev/android/calculator/CursorDragProcessor.java @@ -34,15 +34,22 @@ import javax.annotation.Nonnull; public class CursorDragProcessor implements SimpleDragListener.DragProcessor { + @Nonnull + private final Editor editor; + + public CursorDragProcessor(@Nonnull Editor editor) { + this.editor = editor; + } + @Override public boolean processDragEvent(@Nonnull DragDirection dragDirection, @Nonnull DragButton dragButton, @Nonnull PointF startPoint, @Nonnull MotionEvent motionEvent) { if (dragButton instanceof DirectionDragButton) { final String text = ((DirectionDragButton) dragButton).getText(dragDirection); if ("◁◁".equals(text)) { - Locator.getInstance().getEditor().setCursorOnStart(); + editor.setCursorOnStart(); return true; } else if ("▷▷".equals(text)) { - Locator.getInstance().getEditor().setCursorOnEnd(); + editor.setCursorOnEnd(); return true; } } diff --git a/app/src/main/java/org/solovyev/android/calculator/DigitButtonDragProcessor.java b/app/src/main/java/org/solovyev/android/calculator/DigitButtonDragProcessor.java index 8bfafce1..ebfc15d2 100644 --- a/app/src/main/java/org/solovyev/android/calculator/DigitButtonDragProcessor.java +++ b/app/src/main/java/org/solovyev/android/calculator/DigitButtonDragProcessor.java @@ -34,15 +34,15 @@ import javax.annotation.Nonnull; public class DigitButtonDragProcessor implements SimpleDragListener.DragProcessor { @Nonnull - private CalculatorKeyboard calculatorKeyboard; + private Keyboard keyboard; - public DigitButtonDragProcessor(@Nonnull CalculatorKeyboard calculatorKeyboard) { - this.calculatorKeyboard = calculatorKeyboard; + public DigitButtonDragProcessor(@Nonnull Keyboard keyboard) { + this.keyboard = keyboard; } @Override public boolean processDragEvent(@Nonnull DragDirection direction, @Nonnull DragButton button, @Nonnull PointF startPoint, @Nonnull MotionEvent motionEvent) { final String text = ((DirectionDragButton) button).getText(direction); - return calculatorKeyboard.buttonPressed(text); + return keyboard.buttonPressed(text); } } diff --git a/app/src/main/java/org/solovyev/android/calculator/Display.java b/app/src/main/java/org/solovyev/android/calculator/Display.java index ca1ef956..777d4443 100644 --- a/app/src/main/java/org/solovyev/android/calculator/Display.java +++ b/app/src/main/java/org/solovyev/android/calculator/Display.java @@ -22,13 +22,22 @@ package org.solovyev.android.calculator; +import com.squareup.otto.Bus; + import org.solovyev.android.Check; import javax.annotation.Nonnull; import javax.annotation.Nullable; +import javax.inject.Inject; +import javax.inject.Singleton; -import static org.solovyev.android.calculator.CalculatorEventType.*; +import static org.solovyev.android.calculator.CalculatorEventType.calculation_cancelled; +import static org.solovyev.android.calculator.CalculatorEventType.calculation_failed; +import static org.solovyev.android.calculator.CalculatorEventType.calculation_result; +import static org.solovyev.android.calculator.CalculatorEventType.conversion_failed; +import static org.solovyev.android.calculator.CalculatorEventType.conversion_result; +@Singleton public class Display implements CalculatorEventListener { public static class ChangedEvent { @@ -52,6 +61,10 @@ public class Display implements CalculatorEventListener { @Nonnull private DisplayState state = DisplayState.empty(); + @Inject + Bus bus; + + @Inject public Display(@Nonnull Calculator calculator) { this.lastEvent = new CalculatorEventHolder(CalculatorUtils.createFirstEventDataId()); calculator.addCalculatorEventListener(this); @@ -85,7 +98,7 @@ public class Display implements CalculatorEventListener { if (view != null) { view.setState(newState); } - App.getBus().post(new ChangedEvent(oldState, newState)); + bus.post(new ChangedEvent(oldState, newState)); } @Override diff --git a/app/src/main/java/org/solovyev/android/calculator/Editor.java b/app/src/main/java/org/solovyev/android/calculator/Editor.java index 00ac5d7f..7a7f8ba5 100644 --- a/app/src/main/java/org/solovyev/android/calculator/Editor.java +++ b/app/src/main/java/org/solovyev/android/calculator/Editor.java @@ -22,15 +22,23 @@ package org.solovyev.android.calculator; +import android.content.SharedPreferences; + +import com.squareup.otto.Bus; + import org.solovyev.android.Check; import org.solovyev.android.calculator.text.TextProcessor; import org.solovyev.android.calculator.text.TextProcessorEditorResult; +import org.solovyev.android.calculator.view.EditorTextProcessor; import javax.annotation.Nonnull; import javax.annotation.Nullable; +import javax.inject.Inject; +import javax.inject.Singleton; import static java.lang.Math.min; +@Singleton public class Editor { private static final String TAG = App.subTag("Editor"); @@ -40,6 +48,14 @@ public class Editor { private EditorView view; @Nonnull private EditorState state = EditorState.empty(); + @Inject + Bus bus; + + @Inject + public Editor(@Nonnull SharedPreferences preferences) { + this(new EditorTextProcessor(preferences)); + } + public Editor(@Nullable TextProcessor textProcessor) { this.textProcessor = textProcessor; } @@ -56,11 +72,13 @@ public class Editor { Check.isMainThread(); this.view = view; this.view.setState(state); + this.view.setEditor(this); } public void clearView(@Nonnull EditorView view) { Check.isMainThread(); if (this.view == view) { + this.view.setEditor(null); this.view = null; } } @@ -86,7 +104,7 @@ public class Editor { if (view != null) { view.setState(newState); } - App.getBus().post(new ChangedEvent(oldState, newState)); + bus.post(new ChangedEvent(oldState, newState)); return state; } @@ -97,7 +115,7 @@ public class Editor { if (view != null) { view.setState(newState); } - App.getBus().post(new CursorMovedEvent(newState)); + bus.post(new CursorMovedEvent(newState)); return state; } diff --git a/app/src/main/java/org/solovyev/android/calculator/EditorView.java b/app/src/main/java/org/solovyev/android/calculator/EditorView.java index b2e32fc4..bcced567 100644 --- a/app/src/main/java/org/solovyev/android/calculator/EditorView.java +++ b/app/src/main/java/org/solovyev/android/calculator/EditorView.java @@ -31,12 +31,14 @@ import android.util.AttributeSet; import android.util.Log; import android.view.ContextMenu; import android.widget.EditText; + import org.solovyev.android.Check; import org.solovyev.android.calculator.onscreen.CalculatorOnscreenService; +import java.lang.reflect.Method; + import javax.annotation.Nonnull; import javax.annotation.Nullable; -import java.lang.reflect.Method; public class EditorView extends EditText { @@ -46,6 +48,8 @@ public class EditorView extends EditText { private boolean reportChanges; @Nullable private Method setShowSoftInputOnFocusMethod; + @Nullable + private Editor editor; public EditorView(Context context) { super(context); @@ -75,6 +79,10 @@ public class EditorView extends EditText { reportChanges = true; } + public void setEditor(@Nullable Editor editor) { + this.editor = editor; + } + @Override protected void onCreateContextMenu(ContextMenu menu) { super.onCreateContextMenu(menu); @@ -104,10 +112,15 @@ public class EditorView extends EditText { // external text change => need to notify editor super.onSelectionChanged(start, end); - if (start == end) { - // only if cursor moving, if selection do nothing - Locator.getInstance().getEditor().setSelection(start); + // only if cursor moving, if selection do nothing + if (start != end) { + return; } + if (editor == null) { + Check.shouldNotHappen(); + return; + } + editor.setSelection(start); } public void setShowSoftInputOnFocusCompat(boolean show) { @@ -143,11 +156,15 @@ public class EditorView extends EditText { @Override public void afterTextChanged(Editable s) { + // external text change => need to notify editor if (!reportChanges) { return; } - // external text change => need to notify editor - Locator.getInstance().getEditor().setText(String.valueOf(s)); + if (editor == null) { + Check.shouldNotHappen(); + return; + } + editor.setText(String.valueOf(s)); } } } diff --git a/app/src/main/java/org/solovyev/android/calculator/CalculatorKeyboard.java b/app/src/main/java/org/solovyev/android/calculator/Keyboard.java similarity index 88% rename from app/src/main/java/org/solovyev/android/calculator/CalculatorKeyboard.java rename to app/src/main/java/org/solovyev/android/calculator/Keyboard.java index f10dc25e..08c60150 100644 --- a/app/src/main/java/org/solovyev/android/calculator/CalculatorKeyboard.java +++ b/app/src/main/java/org/solovyev/android/calculator/Keyboard.java @@ -27,8 +27,21 @@ import org.solovyev.common.text.Strings; import javax.annotation.Nonnull; import javax.annotation.Nullable; +import javax.inject.Inject; +import javax.inject.Singleton; -public class CalculatorKeyboard { +@Singleton +public class Keyboard { + + @Inject + Editor editor; + + @Inject + Display display; + + @Inject + public Keyboard() { + } public boolean buttonPressed(@Nullable final String text) { App.getGa().onButtonPressed(text); @@ -69,7 +82,6 @@ public class CalculatorKeyboard { } } - final Editor editor = Locator.getInstance().getEditor(); editor.insert(textToBeInserted.toString(), cursorPositionOffset); } @@ -95,7 +107,6 @@ public class CalculatorKeyboard { } public void roundBracketsButtonPressed() { - final Editor editor = Locator.getInstance().getEditor(); EditorState viewState = editor.getState(); final int cursorPosition = viewState.selection; @@ -107,16 +118,16 @@ public class CalculatorKeyboard { public void pasteButtonPressed() { final String text = Locator.getInstance().getClipboard().getText(); if (text != null) { - Locator.getInstance().getEditor().insert(text); + editor.insert(text); } } public void clearButtonPressed() { - Locator.getInstance().getEditor().clear(); + editor.clear(); } public void copyButtonPressed() { - final DisplayState displayState = Locator.getInstance().getDisplay().getState(); + final DisplayState displayState = display.getState(); if (!displayState.valid) { return; } @@ -125,10 +136,10 @@ public class CalculatorKeyboard { } public void moveCursorLeft() { - Locator.getInstance().getEditor().moveCursorLeft(); + editor.moveCursorLeft(); } public void moveCursorRight() { - Locator.getInstance().getEditor().moveCursorRight(); + editor.moveCursorRight(); } } diff --git a/app/src/main/java/org/solovyev/android/calculator/Locator.java b/app/src/main/java/org/solovyev/android/calculator/Locator.java index 06409288..57c26057 100644 --- a/app/src/main/java/org/solovyev/android/calculator/Locator.java +++ b/app/src/main/java/org/solovyev/android/calculator/Locator.java @@ -22,19 +22,10 @@ package org.solovyev.android.calculator; -import org.solovyev.android.calculator.history.History; import org.solovyev.android.calculator.plot.CalculatorPlotter; -import org.solovyev.android.calculator.text.TextProcessor; -import org.solovyev.android.calculator.text.TextProcessorEditorResult; import javax.annotation.Nonnull; -import javax.annotation.Nullable; -/** - * User: Solovyev_S - * Date: 20.09.12 - * Time: 12:45 - */ public class Locator implements CalculatorLocator { @Nonnull @@ -44,13 +35,7 @@ public class Locator implements CalculatorLocator { @Nonnull private Calculator calculator; @Nonnull - private Editor editor; - @Nonnull - private Display display; - @Nonnull - private CalculatorKeyboard calculatorKeyboard; - @Nonnull - private History history; + private Keyboard keyboard; @Nonnull private CalculatorNotifier calculatorNotifier = new DummyCalculatorNotifier(); @Nonnull @@ -76,25 +61,20 @@ public class Locator implements CalculatorLocator { @Nonnull CalculatorEngine engine, @Nonnull CalculatorClipboard clipboard, @Nonnull CalculatorNotifier notifier, - @Nonnull History history, @Nonnull CalculatorLogger logger, @Nonnull CalculatorPreferenceService preferenceService, - @Nonnull CalculatorKeyboard keyboard, - @Nonnull CalculatorPlotter plotter, - @Nullable TextProcessor editorTextProcessor) { + @Nonnull Keyboard keyboard, + @Nonnull CalculatorPlotter plotter) { this.calculator = calculator; this.calculatorEngine = engine; this.calculatorClipboard = clipboard; this.calculatorNotifier = notifier; - this.history = history; this.calculatorLogger = logger; this.calculatorPreferenceService = preferenceService; this.calculatorPlotter = plotter; - editor = new Editor(editorTextProcessor); - display = new Display(this.calculator); - calculatorKeyboard = keyboard; + this.keyboard = keyboard; } @Nonnull @@ -111,24 +91,12 @@ public class Locator implements CalculatorLocator { @Override @Nonnull - public Display getDisplay() { - return display; + public Keyboard getKeyboard() { + return keyboard; } - @Nonnull - @Override - public Editor getEditor() { - return editor; - } - - @Override - @Nonnull - public CalculatorKeyboard getKeyboard() { - return calculatorKeyboard; - } - - public static void setKeyboard(@Nonnull CalculatorKeyboard keyboard) { - instance.calculatorKeyboard = keyboard; + public static void setKeyboard(@Nonnull Keyboard keyboard) { + instance.keyboard = keyboard; } @Override @@ -143,12 +111,6 @@ public class Locator implements CalculatorLocator { return calculatorNotifier; } - @Override - @Nonnull - public History getHistory() { - return history; - } - @Override @Nonnull public CalculatorLogger getLogger() { diff --git a/app/src/main/java/org/solovyev/android/calculator/ga/Ga.java b/app/src/main/java/org/solovyev/android/calculator/ga/Ga.java index 33dd36f3..a37829c9 100644 --- a/app/src/main/java/org/solovyev/android/calculator/ga/Ga.java +++ b/app/src/main/java/org/solovyev/android/calculator/ga/Ga.java @@ -11,9 +11,6 @@ import com.google.android.gms.analytics.Tracker; import org.solovyev.android.calculator.Preferences; import org.solovyev.android.calculator.R; -import org.solovyev.common.listeners.JEvent; -import org.solovyev.common.listeners.JEventListener; -import org.solovyev.common.listeners.JEventListeners; import java.io.ByteArrayOutputStream; import java.io.PrintStream; @@ -32,7 +29,7 @@ public final class Ga implements SharedPreferences.OnSharedPreferenceChangeListe @Nonnull private final Tracker tracker; - public Ga(@Nonnull Context context, @Nonnull SharedPreferences preferences, @Nonnull JEventListeners, JEvent> bus) { + public Ga(@Nonnull Context context, @Nonnull SharedPreferences preferences) { analytics = GoogleAnalytics.getInstance(context); tracker = analytics.newTracker(R.xml.ga); preferences.registerOnSharedPreferenceChangeListener(this); diff --git a/app/src/main/java/org/solovyev/android/calculator/history/BaseHistoryFragment.java b/app/src/main/java/org/solovyev/android/calculator/history/BaseHistoryFragment.java index a41b482e..786e3a78 100644 --- a/app/src/main/java/org/solovyev/android/calculator/history/BaseHistoryFragment.java +++ b/app/src/main/java/org/solovyev/android/calculator/history/BaseHistoryFragment.java @@ -61,6 +61,7 @@ import java.util.List; import javax.annotation.Nonnull; import javax.annotation.Nullable; +import javax.inject.Inject; import static android.view.Menu.NONE; import static org.solovyev.android.calculator.CalculatorEventType.clear_history_requested; @@ -84,6 +85,8 @@ public abstract class BaseHistoryFragment extends ListFragment implements Calcul private FragmentUi ui; @Nullable private AlertDialog clearDialog; + @Inject + History history; protected BaseHistoryFragment(@Nonnull CalculatorFragmentType fragmentType) { ui = new FragmentUi(fragmentType.getDefaultLayoutId(), fragmentType.getDefaultTitleResId(), false); @@ -220,7 +223,7 @@ public abstract class BaseHistoryFragment extends ListFragment implements Calcul return true; case R.string.c_remove: getAdapter().remove(state); - Locator.getInstance().getHistory().removeSaved(state); + history.removeSaved(state); Toast.makeText(context, context.getText(R.string.c_history_was_removed), Toast.LENGTH_LONG).show(); getAdapter().notifyDataSetChanged(); return true; diff --git a/app/src/main/java/org/solovyev/android/calculator/history/History.java b/app/src/main/java/org/solovyev/android/calculator/history/History.java index 89c3a485..05250be4 100644 --- a/app/src/main/java/org/solovyev/android/calculator/history/History.java +++ b/app/src/main/java/org/solovyev/android/calculator/history/History.java @@ -28,12 +28,14 @@ import android.support.annotation.NonNull; import android.text.TextUtils; import com.google.common.base.Strings; +import com.squareup.otto.Bus; import com.squareup.otto.Subscribe; import org.json.JSONArray; import org.json.JSONException; import org.solovyev.android.Check; import org.solovyev.android.calculator.App; +import org.solovyev.android.calculator.AppModule; import org.solovyev.android.calculator.CalculatorEventType; import org.solovyev.android.calculator.Display; import org.solovyev.android.calculator.DisplayState; @@ -49,9 +51,12 @@ import java.util.ArrayList; import java.util.Collections; import java.util.LinkedList; import java.util.List; +import java.util.concurrent.Executor; import javax.annotation.Nonnull; import javax.annotation.Nullable; +import javax.inject.Inject; +import javax.inject.Named; import static java.lang.Character.isDigit; @@ -66,15 +71,18 @@ public class History { private final RecentHistory recent = new RecentHistory(); @Nonnull private final List saved = new ArrayList<>(); - @Nonnull - private final Handler handler = App.getHandler(); + @Inject + Handler handler; + @Inject + SharedPreferences preferences; @Nullable private EditorState lastEditorState; private boolean initialized; - public History() { - App.getBus().register(this); - App.getInitThread().execute(new Runnable() { + @Inject + public History(Bus bus, @Named(AppModule.THREAD_INIT) Executor initThread) { + bus.register(this); + initThread.execute(new Runnable() { @Override public void run() { init(); @@ -82,9 +90,8 @@ public class History { }); } - private static void migrateOldHistory() { + private void migrateOldHistory() { try { - final SharedPreferences preferences = App.getPreferences(); final String xml = preferences.getString("org.solovyev.android.calculator.CalculatorModel_history", null); if (TextUtils.isEmpty(xml)) { return; @@ -101,7 +108,7 @@ public class History { } @Nullable - private static List convertOldHistory(String xml) { + static List convertOldHistory(@NonNull String xml) { final OldHistory history = OldHistory.fromXml(xml); if (history == null) { // strange, history seems to be broken. Avoid clearing the preference diff --git a/app/src/main/java/org/solovyev/android/calculator/history/HistoryDragProcessor.java b/app/src/main/java/org/solovyev/android/calculator/history/HistoryDragProcessor.java index c57287c7..602cf1f6 100644 --- a/app/src/main/java/org/solovyev/android/calculator/history/HistoryDragProcessor.java +++ b/app/src/main/java/org/solovyev/android/calculator/history/HistoryDragProcessor.java @@ -25,23 +25,26 @@ package org.solovyev.android.calculator.history; import android.graphics.PointF; import android.view.MotionEvent; -import org.solovyev.android.calculator.Locator; import org.solovyev.android.views.dragbutton.DragButton; import org.solovyev.android.views.dragbutton.DragDirection; import org.solovyev.android.views.dragbutton.SimpleDragListener; import javax.annotation.Nonnull; +import javax.inject.Inject; public class HistoryDragProcessor implements SimpleDragListener.DragProcessor { + @Inject + History history; + @Override public boolean processDragEvent(@Nonnull DragDirection direction, @Nonnull DragButton button, @Nonnull PointF startPoint, @Nonnull MotionEvent motionEvent) { switch (direction) { case up: - Locator.getInstance().getHistory().undo(); + history.undo(); return true; case down: - Locator.getInstance().getHistory().redo(); + history.redo(); return true; } return false; diff --git a/app/src/main/java/org/solovyev/android/calculator/history/RecentHistoryFragment.java b/app/src/main/java/org/solovyev/android/calculator/history/RecentHistoryFragment.java index e191879a..00b76e6a 100644 --- a/app/src/main/java/org/solovyev/android/calculator/history/RecentHistoryFragment.java +++ b/app/src/main/java/org/solovyev/android/calculator/history/RecentHistoryFragment.java @@ -23,7 +23,6 @@ package org.solovyev.android.calculator.history; import org.solovyev.android.calculator.CalculatorFragmentType; -import org.solovyev.android.calculator.Locator; import org.solovyev.android.calculator.R; import java.util.List; @@ -44,12 +43,12 @@ public class RecentHistoryFragment extends BaseHistoryFragment { @Nonnull @Override protected List getHistoryItems() { - return Locator.getInstance().getHistory().getRecent(); + return history.getRecent(); } @Override protected void clearHistory() { - Locator.getInstance().getHistory().clearRecent(); + history.clearRecent(); getAdapter().clear(); } } diff --git a/app/src/main/java/org/solovyev/android/calculator/history/SavedHistoryFragment.java b/app/src/main/java/org/solovyev/android/calculator/history/SavedHistoryFragment.java index 4d245e62..4dd7f540 100644 --- a/app/src/main/java/org/solovyev/android/calculator/history/SavedHistoryFragment.java +++ b/app/src/main/java/org/solovyev/android/calculator/history/SavedHistoryFragment.java @@ -23,7 +23,6 @@ package org.solovyev.android.calculator.history; import org.solovyev.android.calculator.CalculatorFragmentType; -import org.solovyev.android.calculator.Locator; import org.solovyev.android.calculator.R; import java.util.List; @@ -44,12 +43,12 @@ public class SavedHistoryFragment extends BaseHistoryFragment { @Nonnull @Override protected List getHistoryItems() { - return Locator.getInstance().getHistory().getSaved(); + return history.getSaved(); } @Override protected void clearHistory() { - Locator.getInstance().getHistory().clearSaved(); + history.clearSaved(); getAdapter().clear(); } } diff --git a/app/src/main/java/org/solovyev/android/calculator/onscreen/CalculatorOnscreenService.java b/app/src/main/java/org/solovyev/android/calculator/onscreen/CalculatorOnscreenService.java index 5f1d72fe..513515f7 100644 --- a/app/src/main/java/org/solovyev/android/calculator/onscreen/CalculatorOnscreenService.java +++ b/app/src/main/java/org/solovyev/android/calculator/onscreen/CalculatorOnscreenService.java @@ -33,13 +33,21 @@ import android.support.v4.app.NotificationCompat; import android.util.DisplayMetrics; import android.view.WindowManager; +import com.squareup.otto.Bus; import com.squareup.otto.Subscribe; + import org.solovyev.android.Check; import org.solovyev.android.Views; -import org.solovyev.android.calculator.*; +import org.solovyev.android.calculator.App; +import org.solovyev.android.calculator.CalculatorApplication; +import org.solovyev.android.calculator.Display; +import org.solovyev.android.calculator.Editor; +import org.solovyev.android.calculator.Preferences; +import org.solovyev.android.calculator.R; import javax.annotation.Nonnull; import javax.annotation.Nullable; +import javax.inject.Inject; public class CalculatorOnscreenService extends Service implements OnscreenViewListener, SharedPreferences.OnSharedPreferenceChangeListener { @@ -50,6 +58,9 @@ public class CalculatorOnscreenService extends Service implements OnscreenViewLi private CalculatorOnscreenView view; + @Inject + Bus bus; + @Nonnull private static Class getIntentListenerClass() { return INTENT_LISTENER_CLASS; @@ -101,10 +112,10 @@ public class CalculatorOnscreenService extends Service implements OnscreenViewLi view = CalculatorOnscreenView.create(this, CalculatorOnscreenViewState.create(width, height, -1, -1), this); view.show(); - view.updateEditorState(Locator.getInstance().getEditor().getState()); - view.updateDisplayState(Locator.getInstance().getDisplay().getState()); + view.updateEditorState(App.getEditor().getState()); + view.updateDisplayState(App.getDisplay().getState()); - App.getBus().register(this); + bus.register(this); App.getPreferences().registerOnSharedPreferenceChangeListener(this); } @@ -112,11 +123,17 @@ public class CalculatorOnscreenService extends Service implements OnscreenViewLi return 4 * width / 3; } + @Override + public void onCreate() { + super.onCreate(); + ((CalculatorApplication) getApplication()).getComponent().inject(this); + } + @Override public void onDestroy() { if (view != null) { App.getPreferences().unregisterOnSharedPreferenceChangeListener(this); - App.getBus().unregister(this); + bus.unregister(this); view.hide(); view = null; } diff --git a/app/src/main/java/org/solovyev/android/calculator/view/EditorTextProcessor.java b/app/src/main/java/org/solovyev/android/calculator/view/EditorTextProcessor.java index dd06679d..419b726e 100644 --- a/app/src/main/java/org/solovyev/android/calculator/view/EditorTextProcessor.java +++ b/app/src/main/java/org/solovyev/android/calculator/view/EditorTextProcessor.java @@ -1,9 +1,7 @@ package org.solovyev.android.calculator.view; import android.app.Application; -import android.content.Context; import android.content.SharedPreferences; -import android.preference.PreferenceManager; import android.util.Log; import org.solovyev.android.calculator.App; @@ -14,15 +12,11 @@ import org.solovyev.android.calculator.text.TextProcessorEditorResult; import javax.annotation.Nonnull; import javax.annotation.Nullable; +import javax.inject.Inject; import static org.solovyev.android.calculator.Preferences.Gui.colorDisplay; import static org.solovyev.android.calculator.Preferences.Gui.theme; -/** - * User: serso - * Date: 6/27/13 - * Time: 6:11 PM - */ public final class EditorTextProcessor implements TextProcessor, SharedPreferences.OnSharedPreferenceChangeListener { private boolean highlightText = true; @@ -30,11 +24,7 @@ public final class EditorTextProcessor implements TextProcessor textHighlighter; - public EditorTextProcessor() { - } - - public void init(@Nonnull Context context) { - final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context); + public EditorTextProcessor(@Nonnull SharedPreferences preferences) { preferences.registerOnSharedPreferenceChangeListener(this); onSharedPreferenceChanged(preferences, colorDisplay.getKey()); } diff --git a/app/src/main/java/org/solovyev/android/calculator/view/LongClickEraser.java b/app/src/main/java/org/solovyev/android/calculator/view/LongClickEraser.java index 75f781f8..6c82d1b2 100644 --- a/app/src/main/java/org/solovyev/android/calculator/view/LongClickEraser.java +++ b/app/src/main/java/org/solovyev/android/calculator/view/LongClickEraser.java @@ -5,6 +5,7 @@ import android.view.HapticFeedbackConstants; import android.view.MotionEvent; import android.view.View; +import org.solovyev.android.calculator.App; import org.solovyev.android.calculator.Calculator; import org.solovyev.android.calculator.Editor; import org.solovyev.android.calculator.EditorState; @@ -23,7 +24,7 @@ public final class LongClickEraser implements View.OnTouchListener { private final GestureDetector gestureDetector; @Nonnull - private final Editor editor = Locator.getInstance().getEditor(); + private final Editor editor = App.getEditor(); @Nonnull private final Calculator calculator = Locator.getInstance().getCalculator(); diff --git a/app/src/main/java/org/solovyev/android/calculator/widget/CalculatorWidget.java b/app/src/main/java/org/solovyev/android/calculator/widget/CalculatorWidget.java index a65b6e80..e38e805c 100644 --- a/app/src/main/java/org/solovyev/android/calculator/widget/CalculatorWidget.java +++ b/app/src/main/java/org/solovyev/android/calculator/widget/CalculatorWidget.java @@ -120,8 +120,8 @@ public class CalculatorWidget extends AppWidgetProvider { @Nonnull AppWidgetManager manager, @Nonnull int[] widgetIds, boolean partially) { - final EditorState editorState = Locator.getInstance().getEditor().getState(); - final DisplayState displayState = Locator.getInstance().getDisplay().getState(); + final EditorState editorState = App.getEditor().getState(); + final DisplayState displayState = App.getDisplay().getState(); final Resources resources = context.getResources(); final SimpleTheme theme = App.getWidgetTheme().resolveThemeFor(App.getTheme()); diff --git a/app/src/test/java/org/solovyev/android/calculator/AbstractCalculatorTest.java b/app/src/test/java/org/solovyev/android/calculator/AbstractCalculatorTest.java index 6cedc5dd..68e21c62 100644 --- a/app/src/test/java/org/solovyev/android/calculator/AbstractCalculatorTest.java +++ b/app/src/test/java/org/solovyev/android/calculator/AbstractCalculatorTest.java @@ -23,7 +23,6 @@ package org.solovyev.android.calculator; import org.mockito.Mockito; -import org.solovyev.android.calculator.history.History; import org.solovyev.android.calculator.plot.CalculatorPlotter; /** @@ -34,7 +33,7 @@ import org.solovyev.android.calculator.plot.CalculatorPlotter; public class AbstractCalculatorTest { protected void setUp() throws Exception { - Locator.getInstance().init(new CalculatorImpl(), CalculatorTestUtils.newCalculatorEngine(), Mockito.mock(CalculatorClipboard.class), Mockito.mock(CalculatorNotifier.class), Mockito.mock(History.class), new SystemOutCalculatorLogger(), Mockito.mock(CalculatorPreferenceService.class), Mockito.mock(CalculatorKeyboard.class), Mockito.mock(CalculatorPlotter.class), null); + Locator.getInstance().init(new CalculatorImpl(null, eventExecutor), CalculatorTestUtils.newCalculatorEngine(), Mockito.mock(CalculatorClipboard.class), Mockito.mock(CalculatorNotifier.class), new SystemOutCalculatorLogger(), Mockito.mock(CalculatorPreferenceService.class), Mockito.mock(Keyboard.class), Mockito.mock(CalculatorPlotter.class)); Locator.getInstance().getEngine().init(); } diff --git a/app/src/test/java/org/solovyev/android/calculator/AndroidEditorViewTest.java b/app/src/test/java/org/solovyev/android/calculator/AndroidEditorViewTest.java index 2748e848..97efdab8 100644 --- a/app/src/test/java/org/solovyev/android/calculator/AndroidEditorViewTest.java +++ b/app/src/test/java/org/solovyev/android/calculator/AndroidEditorViewTest.java @@ -95,7 +95,7 @@ public class AndroidEditorViewTest { for (int j = 0; j < count; j++) { try { int textLength = random.nextInt(maxTextLength); - Locator.getInstance().getEditor().insert(Strings.generateRandomString(textLength), textLength); + App.getEditor().insert(Strings.generateRandomString(textLength), textLength); } catch (Throwable e) { System.out.println(e); error.set(true); diff --git a/app/src/test/java/org/solovyev/android/calculator/CalculatorReceiverTest.java b/app/src/test/java/org/solovyev/android/calculator/CalculatorReceiverTest.java index 1ecf7bf7..ff019112 100644 --- a/app/src/test/java/org/solovyev/android/calculator/CalculatorReceiverTest.java +++ b/app/src/test/java/org/solovyev/android/calculator/CalculatorReceiverTest.java @@ -24,7 +24,7 @@ public class CalculatorReceiverTest { @Test public void testShouldPressButtonOnIntent() throws Exception { - Locator.setKeyboard(mock(CalculatorKeyboard.class)); + Locator.setKeyboard(mock(Keyboard.class)); final Intent intent = newButtonClickedIntent(application, four); new CalculatorReceiver().onReceive(application, intent); @@ -35,7 +35,7 @@ public class CalculatorReceiverTest { @Test public void testShouldDoNothingIfButtonInvalid() throws Exception { - Locator.setKeyboard(mock(CalculatorKeyboard.class)); + Locator.setKeyboard(mock(Keyboard.class)); final Intent intent = new Intent(application, CalculatorReceiver.class); intent.setAction(ACTION_BUTTON_PRESSED); diff --git a/app/src/test/java/org/solovyev/android/calculator/CalculatorTestUtils.java b/app/src/test/java/org/solovyev/android/calculator/CalculatorTestUtils.java index c1713dc2..bbe7b82e 100644 --- a/app/src/test/java/org/solovyev/android/calculator/CalculatorTestUtils.java +++ b/app/src/test/java/org/solovyev/android/calculator/CalculatorTestUtils.java @@ -26,8 +26,10 @@ import android.content.Context; import org.junit.Assert; import org.mockito.Mockito; -import org.solovyev.android.calculator.history.History; +import org.robolectric.RuntimeEnvironment; +import org.robolectric.fakes.RoboSharedPreferences; import org.solovyev.android.calculator.jscl.JsclOperation; +import org.solovyev.android.calculator.language.Languages; import org.solovyev.android.calculator.plot.CalculatorPlotter; import java.io.ByteArrayInputStream; @@ -37,6 +39,8 @@ import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; import java.text.DecimalFormatSymbols; +import java.util.HashMap; +import java.util.Map; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; @@ -56,7 +60,8 @@ public class CalculatorTestUtils { public static final int TIMEOUT = 3; public static void staticSetUp() throws Exception { - Locator.getInstance().init(new CalculatorImpl(), newCalculatorEngine(), Mockito.mock(CalculatorClipboard.class), Mockito.mock(CalculatorNotifier.class), Mockito.mock(History.class), new SystemOutCalculatorLogger(), Mockito.mock(CalculatorPreferenceService.class), Mockito.mock(CalculatorKeyboard.class), Mockito.mock(CalculatorPlotter.class), null); + App.init(RuntimeEnvironment.application, new Languages(new RoboSharedPreferences(new HashMap>(), "test", 0))); + Locator.getInstance().init(new CalculatorImpl(), newCalculatorEngine(), Mockito.mock(CalculatorClipboard.class), Mockito.mock(CalculatorNotifier.class), new SystemOutCalculatorLogger(), Mockito.mock(CalculatorPreferenceService.class), Mockito.mock(Keyboard.class), Mockito.mock(CalculatorPlotter.class)); Locator.getInstance().getEngine().init(); final DecimalFormatSymbols decimalGroupSymbols = new DecimalFormatSymbols(); @@ -66,7 +71,7 @@ public class CalculatorTestUtils { } public static void staticSetUp(@Nullable Context context) throws Exception { - Locator.getInstance().init(new CalculatorImpl(), newCalculatorEngine(), Mockito.mock(CalculatorClipboard.class), Mockito.mock(CalculatorNotifier.class), Mockito.mock(History.class), new SystemOutCalculatorLogger(), Mockito.mock(CalculatorPreferenceService.class), Mockito.mock(CalculatorKeyboard.class), Mockito.mock(CalculatorPlotter.class), null); + Locator.getInstance().init(new CalculatorImpl(), newCalculatorEngine(), Mockito.mock(CalculatorClipboard.class), Mockito.mock(CalculatorNotifier.class), new SystemOutCalculatorLogger(), Mockito.mock(CalculatorPreferenceService.class), Mockito.mock(Keyboard.class), Mockito.mock(CalculatorPlotter.class)); Locator.getInstance().getEngine().init(); if (context != null) { @@ -75,8 +80,8 @@ public class CalculatorTestUtils { } public static void initViews(@Nonnull Context context) { - Locator.getInstance().getEditor().setView(new EditorView(context)); - Locator.getInstance().getDisplay().setView(new DisplayView(context)); + App.getEditor().setView(new EditorView(context)); + App.getDisplay().setView(new DisplayView(context)); } @Nonnull @@ -100,7 +105,7 @@ public class CalculatorTestUtils { public static void assertEval(@Nonnull String expected, @Nonnull String expression, @Nonnull JsclOperation operation) { final Calculator calculator = Locator.getInstance().getCalculator(); - Locator.getInstance().getDisplay().setState(DisplayState.empty()); + App.getDisplay().setState(DisplayState.empty()); final CountDownLatch latch = new CountDownLatch(1); final TestCalculatorEventListener calculatorEventListener = new TestCalculatorEventListener(latch); @@ -156,7 +161,7 @@ public class CalculatorTestUtils { public static void assertError(@Nonnull String expression, @Nonnull JsclOperation operation) { final Calculator calculator = Locator.getInstance().getCalculator(); - Locator.getInstance().getDisplay().setState(DisplayState.empty()); + App.getDisplay().setState(DisplayState.empty()); final CountDownLatch latch = new CountDownLatch(1); final TestCalculatorEventListener calculatorEventListener = new TestCalculatorEventListener(latch); diff --git a/app/src/test/java/org/solovyev/android/calculator/history/HistoryTest.java b/app/src/test/java/org/solovyev/android/calculator/history/HistoryTest.java index c43a5455..5e2c8b04 100644 --- a/app/src/test/java/org/solovyev/android/calculator/history/HistoryTest.java +++ b/app/src/test/java/org/solovyev/android/calculator/history/HistoryTest.java @@ -22,22 +22,24 @@ package org.solovyev.android.calculator.history; +import com.squareup.otto.Bus; + import org.junit.Assert; import org.junit.BeforeClass; import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mockito; +import org.solovyev.android.CalculatorTestRunner; import org.solovyev.android.calculator.CalculatorTestUtils; import org.solovyev.android.calculator.DisplayState; import org.solovyev.android.calculator.EditorState; import java.util.List; +import java.util.concurrent.Executor; import javax.annotation.Nonnull; -/** - * User: Solovyev_S - * Date: 10.10.12 - * Time: 15:07 - */ +@RunWith(CalculatorTestRunner.class) public class HistoryTest { @BeforeClass @@ -47,7 +49,12 @@ public class HistoryTest { @Test public void testGetStates() throws Exception { - History history = new History(); + History history = new History(Mockito.any(Bus.class), new Executor() { + @Override + public void execute(@Nonnull Runnable command) { + command.run(); + } + }); addState(history, "1"); addState(history, "12"); diff --git a/build.gradle b/build.gradle index 2d950b68..9605ba73 100644 --- a/build.gradle +++ b/build.gradle @@ -4,6 +4,7 @@ buildscript { } dependencies { classpath 'com.android.tools.build:gradle:1.5.0' + classpath 'com.neenbedankt.gradle.plugins:android-apt:1.4' } }