diff options
23 files changed, 669 insertions, 153 deletions
diff --git a/AndroidStyle.xml b/AndroidStyle.xml index 7b3a09ea6..2ee5e1f78 100644 --- a/AndroidStyle.xml +++ b/AndroidStyle.xml @@ -89,6 +89,9 @@ <option name="JD_KEEP_EMPTY_RETURN" value="false" /> <option name="JD_PRESERVE_LINE_FEEDS" value="true" /> </JavaCodeStyleSettings> + <MarkdownNavigatorCodeStyleSettings> + <option name="RIGHT_MARGIN" value="72" /> + </MarkdownNavigatorCodeStyleSettings> <Objective-C-extensions> <file> <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Import" /> @@ -115,6 +118,9 @@ </extensions> </Objective-C-extensions> <XML> + <option name="XML_KEEP_LINE_BREAKS" value="false" /> + <option name="XML_ALIGN_ATTRIBUTES" value="false" /> + <option name="XML_SPACE_INSIDE_EMPTY_TAG" value="true" /> <option name="XML_LEGACY_SETTINGS_IMPORTED" value="true" /> </XML> <ADDITIONAL_INDENT_OPTIONS fileType="java"> @@ -138,6 +144,7 @@ <option name="BINARY_OPERATION_SIGN_ON_NEXT_LINE" value="true" /> <option name="TERNARY_OPERATION_WRAP" value="1" /> <option name="TERNARY_OPERATION_SIGNS_ON_NEXT_LINE" value="true" /> + <option name="KEEP_SIMPLE_LAMBDAS_IN_ONE_LINE" value="true" /> <option name="FOR_STATEMENT_WRAP" value="1" /> <option name="ARRAY_INITIALIZER_WRAP" value="1" /> <option name="ASSIGNMENT_WRAP" value="1" /> diff --git a/app/src/main/java/com/anysoftkeyboard/prefs/GlobalPrefsBackup.java b/app/src/main/java/com/anysoftkeyboard/prefs/GlobalPrefsBackup.java new file mode 100644 index 000000000..8a646f6c5 --- /dev/null +++ b/app/src/main/java/com/anysoftkeyboard/prefs/GlobalPrefsBackup.java @@ -0,0 +1,112 @@ +package com.anysoftkeyboard.prefs; + +import android.content.Context; +import android.support.annotation.NonNull; +import android.support.annotation.StringRes; +import android.support.annotation.VisibleForTesting; +import android.support.v4.util.Pair; +import android.support.v7.preference.PreferenceManager; + +import com.anysoftkeyboard.prefs.backup.PrefItem; +import com.anysoftkeyboard.prefs.backup.PrefsProvider; +import com.anysoftkeyboard.prefs.backup.PrefsRoot; +import com.anysoftkeyboard.prefs.backup.PrefsXmlStorage; +import com.menny.android.anysoftkeyboard.AnyApplication; +import com.menny.android.anysoftkeyboard.R; + +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +import io.reactivex.Observable; +import io.reactivex.ObservableSource; +import io.reactivex.functions.BiConsumer; +import io.reactivex.functions.BiFunction; +import io.reactivex.functions.Function; + +public class GlobalPrefsBackup { + @VisibleForTesting + static final String GLOBAL_BACKUP_FILENAME = "AnySoftKeyboardPrefs.xml"; + + public static List<ProviderDetails> getAllPrefsProviders(@NonNull Context context) { + return Arrays.asList( + new ProviderDetails( + new RxSharedPrefs.SharedPrefsProvider(PreferenceManager.getDefaultSharedPreferences(context)), + R.string.shared_prefs_provider_name)); + } + + + private static Boolean backupProvider(PrefsProvider provider, PrefsRoot prefsRoot) { + final PrefsRoot providerRoot = provider.getPrefsRoot(); + prefsRoot.createChild() + .addValue("providerId", provider.providerId()) + .addValue("version", Integer.toString(providerRoot.getVersion())) + .addChild(providerRoot); + + return Boolean.TRUE; + } + + private static Boolean restoreProvider(PrefsProvider provider, PrefsRoot prefsRoot) { + Observable.fromIterable(prefsRoot.getChildren()) + .filter(prefItem -> provider.providerId().equals(prefItem.getValue("providerId"))) + .blockingSubscribe(providerPrefItem -> { + PrefsRoot prefsRootForProvider = new PrefsRoot(Integer.parseInt(providerPrefItem.getValue("version"))); + final PrefItem actualPrefRoot = providerPrefItem.getChildren().iterator().next(); + for (Map.Entry<String, String> attribute : actualPrefRoot.getValues()) { + prefsRootForProvider.addValue(attribute.getKey(), attribute.getValue()); + } + for (PrefItem child : actualPrefRoot.getChildren()) { + prefsRootForProvider.addChild(child); + } + + provider.storePrefsRoot(prefsRootForProvider); + }); + + return Boolean.TRUE; + } + + @NonNull + public static Observable<Boolean> backup(Observable<Pair<List<ProviderDetails>, Boolean[]>> enabledProvidersObservable) { + return doIt(enabledProvidersObservable, GlobalPrefsBackup::backupProvider, s -> new PrefsRoot(1), PrefsXmlStorage::store); + } + + @NonNull + public static Observable<Boolean> restore(Observable<Pair<List<ProviderDetails>, Boolean[]>> enabledProvidersObservable) { + return doIt(enabledProvidersObservable, GlobalPrefsBackup::restoreProvider, PrefsXmlStorage::load, (s, p) -> { /*no-op*/ }); + } + + @NonNull + private static Observable<Boolean> doIt( + Observable<Pair<List<ProviderDetails>, Boolean[]>> enabledProvidersObservable, + BiFunction<PrefsProvider, PrefsRoot, Boolean> providerAction, + Function<PrefsXmlStorage, PrefsRoot> prefsRootFactory, + BiConsumer<PrefsXmlStorage, PrefsRoot> prefsRootFinalizer) { + + final Observable<PrefsProvider> providersObservable = enabledProvidersObservable + .flatMap((Function<Pair<List<ProviderDetails>, Boolean[]>, ObservableSource<Pair<ProviderDetails, Boolean>>>) pair -> Observable.zip( + Observable.fromIterable(pair.first), + Observable.fromArray(pair.second), + Pair::new + )) + .filter(pair -> pair.second) + .map(pair -> pair.first.provider); + + final PrefsXmlStorage storage = new PrefsXmlStorage(AnyApplication.getBackupFile(GLOBAL_BACKUP_FILENAME)); + + return Observable.using(() -> prefsRootFactory.apply(storage), + prefsRoot -> providersObservable.map(provider -> providerAction.apply(provider, prefsRoot)), + prefsRoot -> prefsRootFinalizer.accept(storage, prefsRoot)); + } + + public static class ProviderDetails { + public final PrefsProvider provider; + @StringRes + public final int providerTitle; + + @VisibleForTesting + ProviderDetails(PrefsProvider provider, @StringRes int providerTitle) { + this.provider = provider; + this.providerTitle = providerTitle; + } + } +} diff --git a/app/src/main/java/com/anysoftkeyboard/ui/settings/MainFragment.java b/app/src/main/java/com/anysoftkeyboard/ui/settings/MainFragment.java index 7931f7aa9..cbbad2c1e 100644 --- a/app/src/main/java/com/anysoftkeyboard/ui/settings/MainFragment.java +++ b/app/src/main/java/com/anysoftkeyboard/ui/settings/MainFragment.java @@ -11,7 +11,6 @@ import android.os.Bundle; import android.support.annotation.NonNull; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentManager; -import android.support.v4.view.MenuItemCompat; import android.support.v7.graphics.Palette; import android.text.SpannableStringBuilder; import android.text.Spanned; @@ -92,20 +91,20 @@ public class MainFragment extends Fragment { @Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { + inflater.inflate(R.menu.main_fragment_menu, menu); super.onCreateOptionsMenu(menu, inflater); - final MenuItem aboutMenuItem = menu.add(0, R.id.about_menu_option, Menu.FIRST, R.string.menu_about_item) - .setIcon(R.drawable.ic_menu_action_about) - .setVisible(true); - MenuItemCompat.setShowAsAction(aboutMenuItem, MenuItemCompat.SHOW_AS_ACTION_ALWAYS); } @Override public boolean onOptionsItemSelected(MenuItem item) { + FragmentChauffeurActivity activity = (FragmentChauffeurActivity) getActivity(); switch (item.getItemId()) { case R.id.about_menu_option: - FragmentChauffeurActivity activity = (FragmentChauffeurActivity) getActivity(); activity.addFragmentToUi(new AboutAnySoftKeyboardFragment(), TransitionExperiences.DEEPER_EXPERIENCE_TRANSITION); return true; + case R.id.tweaks_menu_option: + activity.addFragmentToUi(new MainTweaksFragment(), TransitionExperiences.DEEPER_EXPERIENCE_TRANSITION); + return true; default: return super.onOptionsItemSelected(item); } @@ -182,8 +181,9 @@ public class MainFragment extends Fragment { mDemoAnyKeyboardView.setOnViewBitmapReadyListener(this::onDemoViewBitmapReady); - if (mNotConfiguredAnimation != null) + if (mNotConfiguredAnimation != null) { mNotConfiguredAnimation.start(); + } } private void onDemoViewBitmapReady(Bitmap demoViewBitmap) { @@ -193,8 +193,9 @@ public class MainFragment extends Fragment { Palette p = Palette.from(bitmap).generate(); Palette.Swatch highestSwatch = null; for (Palette.Swatch swatch : p.getSwatches()) { - if (highestSwatch == null || highestSwatch.getPopulation() < swatch.getPopulation()) + if (highestSwatch == null || highestSwatch.getPopulation() < swatch.getPopulation()) { highestSwatch = swatch; + } } return highestSwatch; }) diff --git a/app/src/main/java/com/anysoftkeyboard/ui/settings/MainTweaksFragment.java b/app/src/main/java/com/anysoftkeyboard/ui/settings/MainTweaksFragment.java new file mode 100644 index 000000000..f5de86481 --- /dev/null +++ b/app/src/main/java/com/anysoftkeyboard/ui/settings/MainTweaksFragment.java @@ -0,0 +1,171 @@ +/* + * Copyright (c) 2013 Menny Even-Danan + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.anysoftkeyboard.ui.settings; + +import android.app.Activity; +import android.os.Bundle; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import android.support.annotation.VisibleForTesting; +import android.support.v4.util.Pair; +import android.support.v7.app.AlertDialog; +import android.support.v7.preference.Preference; +import android.support.v7.preference.PreferenceFragmentCompat; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; +import android.view.View; + +import com.anysoftkeyboard.prefs.GlobalPrefsBackup; +import com.anysoftkeyboard.rx.RxSchedulers; +import com.anysoftkeyboard.ui.GeneralDialogController; +import com.anysoftkeyboard.ui.dev.DeveloperToolsFragment; +import com.menny.android.anysoftkeyboard.R; + +import net.evendanan.chauffeur.lib.FragmentChauffeurActivity; +import net.evendanan.chauffeur.lib.experiences.TransitionExperiences; +import net.evendanan.pushingpixels.RxProgressDialog; + +import java.util.List; + +import io.reactivex.Observable; +import io.reactivex.disposables.CompositeDisposable; + +public class MainTweaksFragment extends PreferenceFragmentCompat { + + @VisibleForTesting + static final String DEV_TOOLS_KEY = "dev_tools"; + + private static final int FAILED_DIALOG = 10; + private static final int SUCCESS_DIALOG = 20; + + private GeneralDialogController mDialogController; + @NonNull + private CompositeDisposable mDisposable = new CompositeDisposable(); + + @Override + public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { + addPreferencesFromResource(R.xml.prefs_main_tweaks); + } + + @Override + public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + mDialogController = new GeneralDialogController(getActivity(), this::onSetupDialogRequired); + + Preference preference = findPreference(DEV_TOOLS_KEY); + if (preference == null) { + throw new NullPointerException("Preference with key '" + DEV_TOOLS_KEY + "' was not found in resource " + R.xml.prefs_main_tweaks); + } else { + preference.setOnPreferenceClickListener(this::onDevToolsPreferenceClicked); + } + setHasOptionsMenu(true); + } + + @Override + public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { + super.onCreateOptionsMenu(menu, inflater); + inflater.inflate(R.menu.main_tweaks_menu, menu); + } + + @Override + public void onStart() { + super.onStart(); + MainSettingsActivity.setActivityTitle(this, getString(R.string.tweaks_group)); + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + mDialogController.dismiss(); + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case R.id.backup_prefs: + case R.id.restore_prefs: + mDialogController.showDialog(item.getItemId()); + return true; + default: + return super.onOptionsItemSelected(item); + } + } + + private void onSetupDialogRequired(AlertDialog.Builder builder, int optionId, Object data) { + final int actionString; + final boolean backup; + switch (optionId) { + case R.id.backup_prefs: + backup = true; + actionString = R.string.word_editor_action_backup_words; + builder.setMessage(R.string.pick_prefs_providers_to_backup); + break; + case R.id.restore_prefs: + backup = false; + actionString = R.string.word_editor_action_restore_words; + builder.setMessage(R.string.pick_prefs_providers_to_restore); + break; + default: + throw new IllegalArgumentException("The option-id " + optionId + " is not supported here."); + } + + final List<GlobalPrefsBackup.ProviderDetails> supportedProviders = GlobalPrefsBackup.getAllPrefsProviders(getContext()); + final CharSequence[] providersTitles = new CharSequence[supportedProviders.size()]; + final boolean[] initialChecked = new boolean[supportedProviders.size()]; + final Boolean[] checked = new Boolean[supportedProviders.size()]; + + for (int providerIndex = 0; providerIndex < supportedProviders.size(); providerIndex++) { + //starting with everything checked + checked[providerIndex] = initialChecked[providerIndex] = true; + providersTitles[providerIndex] = getText(supportedProviders.get(providerIndex).providerTitle); + } + + builder.setMultiChoiceItems(providersTitles, initialChecked, (dialogInterface, i, b) -> checked[i] = b); + builder.setNegativeButton(android.R.string.cancel, null); + builder.setCancelable(true); + builder.setTitle(actionString); + builder.setPositiveButton(actionString, (dialog, which) -> { + mDisposable.dispose(); + mDisposable = new CompositeDisposable(); + + + final Observable<Pair<List<GlobalPrefsBackup.ProviderDetails>, Boolean[]>> dialogObservable = + RxProgressDialog.create(new Pair<>(supportedProviders, checked), getActivity(), getText(R.string.take_a_while_progress_message)) + .subscribeOn(RxSchedulers.background()); + + final Observable<Boolean> prefsOperationObservable = backup ? GlobalPrefsBackup.backup(dialogObservable) : GlobalPrefsBackup.restore(dialogObservable); + + mDisposable.add(prefsOperationObservable + .lastOrError() + .observeOn(RxSchedulers.mainThread()) + .subscribe( + lastBoolean -> mDialogController.showDialog(SUCCESS_DIALOG), + e -> mDialogController.showDialog(FAILED_DIALOG, e))); + }); + } + + private boolean onDevToolsPreferenceClicked(Preference p) { + Activity activity = getActivity(); + if (activity != null && activity instanceof FragmentChauffeurActivity) { + ((FragmentChauffeurActivity) activity).addFragmentToUi(new DeveloperToolsFragment(), TransitionExperiences.DEEPER_EXPERIENCE_TRANSITION); + return true; + } + return false; + } + +} diff --git a/app/src/main/java/com/anysoftkeyboard/ui/settings/UiTweaksFragment.java b/app/src/main/java/com/anysoftkeyboard/ui/settings/UiTweaksFragment.java index 5f50f2a8f..275c185cf 100644 --- a/app/src/main/java/com/anysoftkeyboard/ui/settings/UiTweaksFragment.java +++ b/app/src/main/java/com/anysoftkeyboard/ui/settings/UiTweaksFragment.java @@ -16,22 +16,12 @@ package com.anysoftkeyboard.ui.settings; -import android.app.Activity; import android.os.Bundle; -import android.support.annotation.Nullable; -import android.support.v7.preference.Preference; import android.support.v7.preference.PreferenceFragmentCompat; -import android.view.View; -import com.anysoftkeyboard.ui.dev.DeveloperToolsFragment; import com.menny.android.anysoftkeyboard.R; -import net.evendanan.chauffeur.lib.FragmentChauffeurActivity; -import net.evendanan.chauffeur.lib.experiences.TransitionExperiences; - -public class UiTweaksFragment extends PreferenceFragmentCompat implements Preference.OnPreferenceClickListener { - - public static final String DEV_TOOLS_KEY = "dev_tools"; +public class UiTweaksFragment extends PreferenceFragmentCompat { @Override public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { @@ -39,35 +29,9 @@ public class UiTweaksFragment extends PreferenceFragmentCompat implements Prefer } @Override - public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { - super.onViewCreated(view, savedInstanceState); - Preference preference = findPreference(DEV_TOOLS_KEY); - if (preference == null) { - throw new NullPointerException("Preference with key '" + DEV_TOOLS_KEY + "' was not found in resource " + R.xml.prefs_ui_tweaks); - } else { - preference.setOnPreferenceClickListener(this); - } - } - - @Override public void onStart() { super.onStart(); MainSettingsActivity.setActivityTitle(this, getString(R.string.tweaks_group)); } - @Override - public boolean onPreferenceClick(Preference preference) { - switch (preference.getKey()) { - case DEV_TOOLS_KEY: - Activity activity = getActivity(); - if (activity != null && activity instanceof FragmentChauffeurActivity) { - ((FragmentChauffeurActivity) activity).addFragmentToUi(new DeveloperToolsFragment(), TransitionExperiences.DEEPER_EXPERIENCE_TRANSITION); - return true; - } - return true; - - default: - return false; - } - } } diff --git a/app/src/main/res/menu/main_fragment_menu.xml b/app/src/main/res/menu/main_fragment_menu.xml new file mode 100644 index 000000000..02e398b5b --- /dev/null +++ b/app/src/main/res/menu/main_fragment_menu.xml @@ -0,0 +1,10 @@ +<?xml version="1.0" encoding="utf-8"?> +<menu xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto"> + + <item android:id="@+id/about_menu_option" android:icon="@drawable/ic_menu_action_about" + android:title="@string/menu_about_item" app:showAsAction="ifRoom|never" /> + + <item android:id="@+id/tweaks_menu_option" android:icon="@drawable/ic_action_settings_light" + android:title="@string/tweaks_group" app:showAsAction="never|withText" /> +</menu>
\ No newline at end of file diff --git a/app/src/main/res/menu/main_tweaks_menu.xml b/app/src/main/res/menu/main_tweaks_menu.xml new file mode 100644 index 000000000..4a8327c67 --- /dev/null +++ b/app/src/main/res/menu/main_tweaks_menu.xml @@ -0,0 +1,9 @@ +<?xml version="1.0" encoding="utf-8"?> +<menu xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto"> + <item android:id="@+id/backup_prefs" android:icon="@android:drawable/ic_menu_save" + android:title="@string/word_editor_action_backup_words" app:showAsAction="never|withText" /> + <item android:id="@+id/restore_prefs" android:icon="@android:drawable/ic_menu_upload" + android:title="@string/word_editor_action_restore_words" + app:showAsAction="never|withText" /> +</menu>
\ No newline at end of file diff --git a/app/src/main/res/values/ids.xml b/app/src/main/res/values/ids.xml index 2023b44c8..0d4b6ff20 100644 --- a/app/src/main/res/values/ids.xml +++ b/app/src/main/res/values/ids.xml @@ -16,6 +16,4 @@ <item name="notification_icon_debug_version" type="id" /> <item name="notification_icon_app_error" type="id" /> - - <item name="about_menu_option" type="id" /> </resources>
\ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 7f083d460..ae6864dd3 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -708,4 +708,7 @@ <string name="theme_case_type_override_title">Keyboard letter-case override</string> <string name="theme_case_type_override_summary">How to determine letters-case in the keyboard view. Currently, %s</string> <string name="take_a_while_progress_message">This might take a while…</string> + <string name="shared_prefs_provider_name">App Settings</string> + <string name="pick_prefs_providers_to_backup">What would you like to backup?</string> + <string name="pick_prefs_providers_to_restore">What would you like to restore?</string> </resources> diff --git a/app/src/main/res/xml/prefs_main_tweaks.xml b/app/src/main/res/xml/prefs_main_tweaks.xml new file mode 100644 index 000000000..6792e8420 --- /dev/null +++ b/app/src/main/res/xml/prefs_main_tweaks.xml @@ -0,0 +1,39 @@ +<?xml version="1.0" encoding="utf-8"?> +<android.support.v7.preference.PreferenceScreen + xmlns:android="http://schemas.android.com/apk/res/android" android:key="tweaks_group_screen" + android:title="@string/tweaks_group"> + + <android.support.v7.preference.ListPreference + android:defaultValue="@string/settings_default_force_locale_setting" + android:dialogTitle="@string/settings_force_locale_title" + android:entries="@array/settings_key_force_locale_values" + android:entryValues="@array/settings_key_force_locale_values" + android:key="@string/settings_key_force_locale" + android:summary="@string/settings_force_locale_summary" + android:title="@string/settings_force_locale_title" /> + + <android.support.v7.preference.CheckBoxPreference + android:defaultValue="@bool/settings_default_keyboard_icon_in_status_bar" + android:key="@string/settings_key_keyboard_icon_in_status_bar" android:persistent="true" + android:summaryOff="@string/show_keyboard_icon_in_status_bar_off_summary" + android:summaryOn="@string/show_keyboard_icon_in_status_bar_on_summary" + android:title="@string/show_keyboard_icon_in_status_bar_title" /> + + <android.support.v7.preference.CheckBoxPreference + android:defaultValue="@bool/settings_default_show_settings_app" + android:key="@string/settings_key_show_settings_app" android:persistent="true" + android:summaryOff="@string/settings_key_show_settings_app_off_summary" + android:summaryOn="@string/settings_key_show_settings_app_on_summary" + android:title="@string/show_settings_app_in_launcher" /> + + <android.support.v7.preference.CheckBoxPreference + android:defaultValue="@bool/settings_default_show_chewbacca" + android:key="@string/settings_key_show_chewbacca" android:persistent="true" + android:summaryOff="@string/show_crash_notification_off_summary" + android:summaryOn="@string/show_crash_notification_on_summary" + android:title="@string/show_crash_notification" /> + + <Preference android:key="dev_tools" + android:summary="@string/click_for_developer_features_summary" + android:title="@string/click_for_developer_features" /> +</android.support.v7.preference.PreferenceScreen>
\ No newline at end of file diff --git a/app/src/main/res/xml/prefs_ui_tweaks.xml b/app/src/main/res/xml/prefs_ui_tweaks.xml index 5c7b25ee8..1b1a5af0d 100644 --- a/app/src/main/res/xml/prefs_ui_tweaks.xml +++ b/app/src/main/res/xml/prefs_ui_tweaks.xml @@ -1,87 +1,59 @@ <?xml version="1.0" encoding="utf-8"?> -<android.support.v7.preference.PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:pp="http://schemas.android.com/apk/res-auto" - android:key="tweaks_group_screen" +<android.support.v7.preference.PreferenceScreen + xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:pp="http://schemas.android.com/apk/res-auto" android:key="tweaks_group_screen" android:title="@string/tweaks_group"> - <android.support.v7.preference.PreferenceCategory - android:key="tweak_sound_group" + <android.support.v7.preference.PreferenceCategory android:key="tweak_sound_group" android:title="@string/tweak_sound_group"> - <android.support.v7.preference.CheckBoxPreference - android:defaultValue="false" - android:key="use_custom_sound_volume" - android:persistent="true" + <android.support.v7.preference.CheckBoxPreference android:defaultValue="false" + android:key="use_custom_sound_volume" android:persistent="true" android:summaryOff="@string/use_custom_sound_volume_off_summary" android:summaryOn="@string/use_custom_sound_volume_on_summary" android:title="@string/use_custom_sound_volume" /> <!-- Using this import require an Android Library reference from https://github.com/menny/PushingPixels --> <net.evendanan.pushingpixels.SlidePreference android:defaultValue="@integer/settings_default_custom_volume_level" - android:dependency="use_custom_sound_volume" - android:key="custom_sound_volume" - android:persistent="true" - android:title="@string/custom_sound_volume" + android:dependency="use_custom_sound_volume" android:key="custom_sound_volume" + android:persistent="true" android:title="@string/custom_sound_volume" pp:slideMaximum="@integer/settings_custom_volume_level_slide_max" pp:slideMinimum="@integer/settings_custom_volume_level_slide_min" /> </android.support.v7.preference.PreferenceCategory> - <android.support.v7.preference.PreferenceCategory - android:key="tweak_ui_group" + <android.support.v7.preference.PreferenceCategory android:key="tweak_ui_group" android:title="@string/tweak_ui_group"> - <android.support.v7.preference.ListPreference - android:defaultValue="@string/settings_default_force_locale_setting" - android:dialogTitle="@string/settings_force_locale_title" - android:entries="@array/settings_key_force_locale_values" - android:entryValues="@array/settings_key_force_locale_values" - android:key="@string/settings_key_force_locale" - android:summary="@string/settings_force_locale_summary" - android:title="@string/settings_force_locale_title" /> - - <android.support.v7.preference.CheckBoxPreference - android:defaultValue="@bool/settings_default_keyboard_icon_in_status_bar" - android:key="@string/settings_key_keyboard_icon_in_status_bar" - android:persistent="true" - android:summaryOff="@string/show_keyboard_icon_in_status_bar_off_summary" - android:summaryOn="@string/show_keyboard_icon_in_status_bar_on_summary" - android:title="@string/show_keyboard_icon_in_status_bar_title" /> - <android.support.v7.preference.CheckBoxPreference android:defaultValue="@bool/settings_default_extension_keyboard_enabled" - android:key="@string/settings_key_extension_keyboard_enabled" - android:persistent="true" + android:key="@string/settings_key_extension_keyboard_enabled" android:persistent="true" android:summaryOff="@string/extension_keyboard_enabled_off_summary" android:summaryOn="@string/extension_keyboard_enabled_on_summary" android:title="@string/is_extesion_keyboard_above_keyboard" /> <android.support.v7.preference.CheckBoxPreference android:defaultValue="@bool/settings_default_is_sticky_extesion_keyboard" - android:key="@string/settings_key_is_sticky_extesion_keyboard" - android:persistent="true" + android:key="@string/settings_key_is_sticky_extesion_keyboard" android:persistent="true" android:summaryOff="@string/is_sticky_extesion_keyboard_off_summary" android:summaryOn="@string/is_sticky_extesion_keyboard_on_summary" android:title="@string/is_sticky_extesion_keyboard" /> <android.support.v7.preference.CheckBoxPreference android:defaultValue="@bool/settings_default_portrait_fullscreen" - android:key="@string/settings_key_portrait_fullscreen" - android:persistent="true" + android:key="@string/settings_key_portrait_fullscreen" android:persistent="true" android:summaryOff="@string/fullscreen_portrait_input_connection_supported_off_summary" android:summaryOn="@string/fullscreen_portrait_input_connection_supported_on_summary" android:title="@string/fullscreen_portrait_input_connection_supported" /> <android.support.v7.preference.CheckBoxPreference android:defaultValue="@bool/settings_default_landscape_fullscreen" - android:key="@string/settings_key_landscape_fullscreen" - android:persistent="true" + android:key="@string/settings_key_landscape_fullscreen" android:persistent="true" android:summaryOff="@string/fullscreen_input_connection_supported_off_summary" android:summaryOn="@string/fullscreen_input_connection_supported_on_summary" android:title="@string/fullscreen_input_connection_supported" /> </android.support.v7.preference.PreferenceCategory> - <android.support.v7.preference.PreferenceCategory - android:key="tweak_ux_group" + <android.support.v7.preference.PreferenceCategory android:key="tweak_ux_group" android:title="@string/tweak_ux_group"> <android.support.v7.preference.ListPreference @@ -104,27 +76,19 @@ <android.support.v7.preference.CheckBoxPreference android:defaultValue="@bool/settings_default_lang_key_shows_popup" - android:key="@string/settings_key_lang_key_shows_popup" - android:persistent="true" + android:key="@string/settings_key_lang_key_shows_popup" android:persistent="true" android:summaryOff="@string/lang_key_shows_popup_off_summary" android:summaryOn="@string/lang_key_shows_popup_on_summary" android:title="@string/lang_key_shows_popup" /> - <EditTextPreference - android:autoText="false" - android:capitalize="none" - android:defaultValue=".com" - android:dialogTitle="@string/default_domain_text" - android:key="default_domain_text" - android:lines="1" - android:persistent="true" - android:singleLine="true" - android:title="@string/default_domain_text" /> + <EditTextPreference android:autoText="false" android:capitalize="none" + android:defaultValue=".com" android:dialogTitle="@string/default_domain_text" + android:key="default_domain_text" android:lines="1" android:persistent="true" + android:singleLine="true" android:title="@string/default_domain_text" /> <android.support.v7.preference.CheckBoxPreference android:defaultValue="@bool/settings_default_always_hide_language_key" - android:key="@string/settings_key_always_hide_language_key" - android:persistent="true" + android:key="@string/settings_key_always_hide_language_key" android:persistent="true" android:summaryOff="@string/always_hide_language_key_off_summary" android:summaryOn="@string/always_hide_language_key_on_summary" android:title="@string/always_hide_language_key" /> @@ -148,37 +112,15 @@ android:title="@string/settings_split_state_title_landscape" /> </android.support.v7.preference.PreferenceCategory> - <android.support.v7.preference.PreferenceCategory - android:key="tweak_workarounds_group" + <android.support.v7.preference.PreferenceCategory android:key="tweak_workarounds_group" android:title="@string/tweak_workarounds_group"> <android.support.v7.preference.CheckBoxPreference android:defaultValue="@bool/settings_default_workaround_disable_rtl_fix" - android:key="@string/settings_key_workaround_disable_rtl_fix" - android:persistent="true" + android:key="@string/settings_key_workaround_disable_rtl_fix" android:persistent="true" android:summaryOff="@string/workaround_disable_rtl_fix_summary_off" android:summaryOn="@string/workaround_disable_rtl_fix_summary_on" android:title="@string/workaround_disable_rtl_fix" /> </android.support.v7.preference.PreferenceCategory> - <android.support.v7.preference.CheckBoxPreference - android:defaultValue="@bool/settings_default_show_settings_app" - android:key="@string/settings_key_show_settings_app" - android:persistent="true" - android:summaryOff="@string/settings_key_show_settings_app_off_summary" - android:summaryOn="@string/settings_key_show_settings_app_on_summary" - android:title="@string/show_settings_app_in_launcher" /> - - <android.support.v7.preference.CheckBoxPreference - android:defaultValue="@bool/settings_default_show_chewbacca" - android:key="@string/settings_key_show_chewbacca" - android:persistent="true" - android:summaryOff="@string/show_crash_notification_off_summary" - android:summaryOn="@string/show_crash_notification_on_summary" - android:title="@string/show_crash_notification" /> - - <Preference - android:key="dev_tools" - android:summary="@string/click_for_developer_features_summary" - android:title="@string/click_for_developer_features"/> </android.support.v7.preference.PreferenceScreen>
\ No newline at end of file diff --git a/app/src/test/java/com/anysoftkeyboard/ViewTestUtils.java b/app/src/test/java/com/anysoftkeyboard/ViewTestUtils.java index f684195a1..49fea5ca1 100644 --- a/app/src/test/java/com/anysoftkeyboard/ViewTestUtils.java +++ b/app/src/test/java/com/anysoftkeyboard/ViewTestUtils.java @@ -2,17 +2,22 @@ package com.anysoftkeyboard; import android.graphics.Point; import android.os.SystemClock; +import android.support.annotation.NonNull; +import android.support.v4.app.Fragment; import android.support.v7.preference.Preference; import android.view.MotionEvent; import android.view.View; import com.anysoftkeyboard.keyboards.Keyboard; +import com.menny.android.anysoftkeyboard.R; import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Mockito; +import org.robolectric.Robolectric; +import org.robolectric.Shadows; import org.robolectric.shadows.ShadowSystemClock; import java.util.List; @@ -75,6 +80,17 @@ public class ViewTestUtils { return navigateFromTo(view, getKeyCenterPoint(start), getKeyCenterPoint(end), duration, alsoDown, alsoUp); } + @NonNull + public static Fragment navigateByClicking(Fragment rootFragment, int viewToClick) { + final View viewById = rootFragment.getView().findViewById(viewToClick); + Assert.assertNotNull(viewById); + final View.OnClickListener onClickListener = Shadows.shadowOf(viewById).getOnClickListener(); + Assert.assertNotNull(onClickListener); + onClickListener.onClick(viewById); + Robolectric.flushForegroundThreadScheduler(); + return rootFragment.getActivity().getSupportFragmentManager().findFragmentById(R.id.main_ui_content); + } + @Test public void testNavigateFromToHelpMethod() { View view = Mockito.mock(View.class); diff --git a/app/src/test/java/com/anysoftkeyboard/prefs/GlobalPrefsBackupTest.java b/app/src/test/java/com/anysoftkeyboard/prefs/GlobalPrefsBackupTest.java new file mode 100644 index 000000000..73e090f22 --- /dev/null +++ b/app/src/test/java/com/anysoftkeyboard/prefs/GlobalPrefsBackupTest.java @@ -0,0 +1,148 @@ +package com.anysoftkeyboard.prefs; + +import android.support.annotation.Nullable; +import android.support.v4.util.Pair; + +import com.anysoftkeyboard.AnySoftKeyboardRobolectricTestRunner; +import com.anysoftkeyboard.base.Charsets; +import com.anysoftkeyboard.prefs.backup.PrefItem; +import com.anysoftkeyboard.prefs.backup.PrefsProvider; +import com.anysoftkeyboard.prefs.backup.PrefsRoot; +import com.anysoftkeyboard.test.TestUtils; +import com.menny.android.anysoftkeyboard.AnyApplication; +import com.menny.android.anysoftkeyboard.R; + +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.RuntimeEnvironment; + +import java.nio.file.Files; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Map; + +import io.reactivex.Observable; + +@RunWith(AnySoftKeyboardRobolectricTestRunner.class) +public class GlobalPrefsBackupTest { + + static class FakePrefsProvider implements PrefsProvider { + private final String mId; + @Nullable + public PrefsRoot storedPrefsRoot; + + FakePrefsProvider(String id) { + + mId = id; + } + + @Override + public PrefsRoot getPrefsRoot() { + PrefsRoot root = new PrefsRoot(2); + root.addValue("test", "value"); + root.addValue("ctorId", mId); + root.createChild() + .addValue("child", "child-value"); + return root; + } + + @Override + public String providerId() { + return mId; + } + + @Override + public void storePrefsRoot(PrefsRoot prefsRoot) { + storedPrefsRoot = prefsRoot; + } + } + + @Test + public void testGetAllPrefsProviders() { + final List<GlobalPrefsBackup.ProviderDetails> allPrefsProviders = GlobalPrefsBackup.getAllPrefsProviders(RuntimeEnvironment.application); + Assert.assertNotNull(allPrefsProviders); + Assert.assertEquals(1, allPrefsProviders.size()); + } + + @Test + public void testBackupRestoreHappyPath() throws Exception { + final FakePrefsProvider fakePrefsProvider = new FakePrefsProvider("id1"); + final PrefsRoot originalPrefsRoot = fakePrefsProvider.getPrefsRoot(); + List<GlobalPrefsBackup.ProviderDetails> fakeDetails = Collections.singletonList( + new GlobalPrefsBackup.ProviderDetails(fakePrefsProvider, R.string.pop_text_type_title)); + + GlobalPrefsBackup.backup(Observable.just(Pair.create(fakeDetails, new Boolean[]{true}))) + .blockingSubscribe(b -> { }); + + System.out.println("AnyApplication.getBackupFile(GlobalPrefsBackup.GLOBAL_BACKUP_FILENAME) is " + AnyApplication.getBackupFile(GlobalPrefsBackup.GLOBAL_BACKUP_FILENAME).getAbsolutePath()); + System.out.println(Arrays.toString(Files.readAllLines(AnyApplication.getBackupFile(GlobalPrefsBackup.GLOBAL_BACKUP_FILENAME).toPath(), Charsets.UTF8).toArray())); + Assert.assertTrue(AnyApplication.getBackupFile(GlobalPrefsBackup.GLOBAL_BACKUP_FILENAME).exists()); + Assert.assertTrue(AnyApplication.getBackupFile(GlobalPrefsBackup.GLOBAL_BACKUP_FILENAME).length() > 0); + + Assert.assertNull(fakePrefsProvider.storedPrefsRoot); + GlobalPrefsBackup.restore(Observable.just(Pair.create(fakeDetails, new Boolean[]{true}))) + .blockingSubscribe(b -> { }); + + Assert.assertNotNull(fakePrefsProvider.storedPrefsRoot); + Assert.assertNotSame(originalPrefsRoot, fakePrefsProvider.storedPrefsRoot); + assertRootsEqual(originalPrefsRoot, fakePrefsProvider.storedPrefsRoot); + } + + @Test + public void testOnlyBackupRestoreEnabledProviders() { + List<GlobalPrefsBackup.ProviderDetails> fakesDetails = new ArrayList<>(5); + final FakePrefsProvider[] fakePrefsProviders = new FakePrefsProvider[5]; + final PrefsRoot[] originalRoots = new PrefsRoot[fakePrefsProviders.length]; + for (int providerIndex = 0; providerIndex < fakePrefsProviders.length; providerIndex++) { + fakePrefsProviders[providerIndex] = new FakePrefsProvider("id_" + providerIndex); + originalRoots[providerIndex] = fakePrefsProviders[providerIndex].getPrefsRoot(); + fakesDetails.add(new GlobalPrefsBackup.ProviderDetails(fakePrefsProviders[providerIndex], R.string.pop_text_type_title)); + } + + final Boolean[] providersToBackup = {true, true, true, false, true}; + GlobalPrefsBackup.backup(Observable.just(Pair.create(fakesDetails, providersToBackup))) + .blockingSubscribe(b -> { }); + + //restoring the first and last. Also asking for restore of the 4th, which is not in the list + final Boolean[] providersToRestore = {true, false, false, true, true}; + GlobalPrefsBackup.restore(Observable.just(Pair.create(fakesDetails, providersToRestore))) + .blockingSubscribe(b -> { }); + + for (int providerIndex = 0; providerIndex < fakePrefsProviders.length; providerIndex++) { + final FakePrefsProvider fakePrefsProvider = fakePrefsProviders[providerIndex]; + if (providersToRestore[providerIndex] && providersToBackup[providerIndex]) { + Assert.assertNotNull("Provider at index " + providerIndex + " should have been restored!", fakePrefsProvider.storedPrefsRoot); + Assert.assertNotSame("Provider at index " + providerIndex, originalRoots[providerIndex], fakePrefsProvider.storedPrefsRoot); + assertRootsEqual(originalRoots[providerIndex], fakePrefsProvider.storedPrefsRoot); + } else { + Assert.assertNull("Provider at index " + providerIndex, fakePrefsProvider.storedPrefsRoot); + } + } + } + + public static void assertRootsEqual(PrefsRoot root1, PrefsRoot root2) { + Assert.assertEquals(root1.getVersion(), root2.getVersion()); + + assertPrefItemsEqual(root1, root2); + } + + public static void assertPrefItemsEqual(PrefItem prefItem1, PrefItem prefItem2) { + for (Map.Entry<String, String> values : prefItem1.getValues()) { + Assert.assertEquals(values.getValue(), prefItem2.getValue(values.getKey())); + } + + for (Map.Entry<String, String> values : prefItem2.getValues()) { + Assert.assertEquals(values.getValue(), prefItem1.getValue(values.getKey())); + } + + final List<PrefItem> prefItems1 = TestUtils.convertToList(prefItem1.getChildren()); + final List<PrefItem> prefItems2 = TestUtils.convertToList(prefItem2.getChildren()); + Assert.assertEquals(prefItems1.size(), prefItems2.size()); + for (int childIndex = 0; childIndex < prefItems1.size(); childIndex++) { + assertPrefItemsEqual(prefItems1.get(childIndex), prefItems2.get(childIndex)); + } + } +}
\ No newline at end of file diff --git a/app/src/test/java/com/anysoftkeyboard/ui/settings/BaseSettingsFragmentTest.java b/app/src/test/java/com/anysoftkeyboard/ui/settings/BaseSettingsFragmentTest.java index 6876347f9..e773c5e61 100644 --- a/app/src/test/java/com/anysoftkeyboard/ui/settings/BaseSettingsFragmentTest.java +++ b/app/src/test/java/com/anysoftkeyboard/ui/settings/BaseSettingsFragmentTest.java @@ -1,9 +1,7 @@ package com.anysoftkeyboard.ui.settings; import android.content.res.Configuration; -import android.support.annotation.NonNull; import android.support.v4.app.Fragment; -import android.view.View; import android.widget.LinearLayout; import com.anysoftkeyboard.AnySoftKeyboardRobolectricTestRunner; @@ -13,9 +11,7 @@ import com.menny.android.anysoftkeyboard.R; import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; -import org.robolectric.Robolectric; import org.robolectric.RuntimeEnvironment; -import org.robolectric.Shadows; import org.robolectric.annotation.Config; @RunWith(AnySoftKeyboardRobolectricTestRunner.class) @@ -41,14 +37,4 @@ public abstract class BaseSettingsFragmentTest<T extends Fragment> extends Robol Assert.assertEquals(LinearLayout.VERTICAL, rootView.getOrientation()); } - @NonNull - protected Fragment navigateByClicking(Fragment rootFragment, int viewToClick) { - final View viewById = rootFragment.getView().findViewById(viewToClick); - Assert.assertNotNull(viewById); - final View.OnClickListener onClickListener = Shadows.shadowOf(viewById).getOnClickListener(); - Assert.assertNotNull(onClickListener); - onClickListener.onClick(viewById); - Robolectric.flushForegroundThreadScheduler(); - return rootFragment.getActivity().getSupportFragmentManager().findFragmentById(R.id.main_ui_content); - } }
\ No newline at end of file diff --git a/app/src/test/java/com/anysoftkeyboard/ui/settings/LanguageSettingsFragmentTest.java b/app/src/test/java/com/anysoftkeyboard/ui/settings/LanguageSettingsFragmentTest.java index 35777f26c..9fc239f9b 100644 --- a/app/src/test/java/com/anysoftkeyboard/ui/settings/LanguageSettingsFragmentTest.java +++ b/app/src/test/java/com/anysoftkeyboard/ui/settings/LanguageSettingsFragmentTest.java @@ -3,6 +3,7 @@ package com.anysoftkeyboard.ui.settings; import android.support.annotation.NonNull; import com.anysoftkeyboard.AnySoftKeyboardRobolectricTestRunner; +import com.anysoftkeyboard.ViewTestUtils; import com.menny.android.anysoftkeyboard.R; import org.junit.Assert; @@ -22,20 +23,20 @@ public class LanguageSettingsFragmentTest extends BaseSettingsFragmentTest<Langu public void testNavigationKeyboards() { final LanguageSettingsFragment languageSettingsFragment = startFragment(); - Assert.assertTrue(navigateByClicking(languageSettingsFragment, R.id.settings_tile_keyboards) instanceof KeyboardAddOnBrowserFragment); + Assert.assertTrue(ViewTestUtils.navigateByClicking(languageSettingsFragment, R.id.settings_tile_keyboards) instanceof KeyboardAddOnBrowserFragment); } @Test public void testNavigationGrammar() { final LanguageSettingsFragment languageSettingsFragment = startFragment(); - Assert.assertTrue(navigateByClicking(languageSettingsFragment, R.id.settings_tile_grammar) instanceof DictionariesFragment); + Assert.assertTrue(ViewTestUtils.navigateByClicking(languageSettingsFragment, R.id.settings_tile_grammar) instanceof DictionariesFragment); } @Test public void testNavigationTweaks() { final LanguageSettingsFragment languageSettingsFragment = startFragment(); - Assert.assertTrue(navigateByClicking(languageSettingsFragment, R.id.settings_tile_even_more) instanceof AdditionalLanguageSettingsFragment); + Assert.assertTrue(ViewTestUtils.navigateByClicking(languageSettingsFragment, R.id.settings_tile_even_more) instanceof AdditionalLanguageSettingsFragment); } }
\ No newline at end of file diff --git a/app/src/test/java/com/anysoftkeyboard/ui/settings/MainFragmentTest.java b/app/src/test/java/com/anysoftkeyboard/ui/settings/MainFragmentTest.java index c6a1b9b1b..62ab8d046 100644 --- a/app/src/test/java/com/anysoftkeyboard/ui/settings/MainFragmentTest.java +++ b/app/src/test/java/com/anysoftkeyboard/ui/settings/MainFragmentTest.java @@ -50,4 +50,23 @@ public class MainFragmentTest extends RobolectricFragmentTestCase<MainFragment> Assert.assertNotNull(aboutFragment); Assert.assertTrue(aboutFragment instanceof AboutAnySoftKeyboardFragment); } + + @Test + public void testTweaksMenuCommand() throws Exception { + final MainFragment fragment = startFragment(); + final FragmentActivity activity = fragment.getActivity(); + + Menu menu = Shadows.shadowOf(activity).getOptionsMenu(); + Assert.assertNotNull(menu); + final MenuItem item = menu.findItem(R.id.tweaks_menu_option); + Assert.assertNotNull(item); + Assert.assertTrue(item.isVisible()); + + fragment.onOptionsItemSelected(item); + Robolectric.flushForegroundThreadScheduler(); + + Fragment aboutFragment = activity.getSupportFragmentManager().findFragmentById(R.id.main_ui_content); + Assert.assertNotNull(aboutFragment); + Assert.assertTrue(aboutFragment instanceof MainTweaksFragment); + } }
\ No newline at end of file diff --git a/app/src/test/java/com/anysoftkeyboard/ui/settings/MainTweaksFragmentTest.java b/app/src/test/java/com/anysoftkeyboard/ui/settings/MainTweaksFragmentTest.java new file mode 100644 index 000000000..0fca900f0 --- /dev/null +++ b/app/src/test/java/com/anysoftkeyboard/ui/settings/MainTweaksFragmentTest.java @@ -0,0 +1,88 @@ +package com.anysoftkeyboard.ui.settings; + +import android.support.annotation.NonNull; +import android.support.v4.app.Fragment; +import android.support.v4.app.FragmentActivity; +import android.support.v7.app.AlertDialog; +import android.support.v7.preference.Preference; +import android.view.Menu; +import android.view.MenuItem; + +import com.anysoftkeyboard.RobolectricFragmentTestCase; +import com.anysoftkeyboard.prefs.GlobalPrefsBackup; +import com.anysoftkeyboard.ui.GeneralDialogControllerTest; +import com.anysoftkeyboard.ui.dev.DeveloperToolsFragment; +import com.menny.android.anysoftkeyboard.R; + +import org.junit.Assert; +import org.junit.Test; +import org.robolectric.Robolectric; +import org.robolectric.RuntimeEnvironment; +import org.robolectric.Shadows; + +public class MainTweaksFragmentTest extends RobolectricFragmentTestCase<MainTweaksFragment> { + + @NonNull + @Override + protected MainTweaksFragment createFragment() { + return new MainTweaksFragment(); + } + + @Test + public void testNavigateToDevTools() { + MainTweaksFragment fragment = startFragment(); + + final Preference preferenceDevTools = fragment.findPreference(MainTweaksFragment.DEV_TOOLS_KEY); + preferenceDevTools.getOnPreferenceClickListener().onPreferenceClick(preferenceDevTools); + + Robolectric.flushForegroundThreadScheduler(); + Fragment navigatedToFragment = fragment.getActivity().getSupportFragmentManager().findFragmentById(R.id.main_ui_content); + Assert.assertTrue(navigatedToFragment instanceof DeveloperToolsFragment); + } + + @Test + public void testBackupMenuItem() throws Exception { + final MainTweaksFragment fragment = startFragment(); + final FragmentActivity activity = fragment.getActivity(); + + Menu menu = Shadows.shadowOf(activity).getOptionsMenu(); + Assert.assertNotNull(menu); + final MenuItem item = menu.findItem(R.id.backup_prefs); + Assert.assertNotNull(item); + + fragment.onOptionsItemSelected(item); + + final AlertDialog dialog = GeneralDialogControllerTest.getLatestShownDialog(); + Assert.assertNotNull(dialog); + Assert.assertEquals(RuntimeEnvironment.application.getText(R.string.word_editor_action_backup_words), GeneralDialogControllerTest.getTitleFromDialog(dialog)); + Assert.assertNotNull(dialog.getListView()); + Assert.assertEquals(GlobalPrefsBackup.getAllPrefsProviders(RuntimeEnvironment.application).size(), dialog.getListView().getCount()); +/* + Assert.assertTrue(AnyApplication.getBackupFile(MainTweaksFragment.GLOBAL_BACKUP_FILENAME).exists()); + Assert.assertTrue(AnyApplication.getBackupFile(MainTweaksFragment.GLOBAL_BACKUP_FILENAME).length() > 0); +*/ + } + + @Test + public void testRestoreMenuItem() throws Exception { + final MainTweaksFragment fragment = startFragment(); + final FragmentActivity activity = fragment.getActivity(); + + Menu menu = Shadows.shadowOf(activity).getOptionsMenu(); + Assert.assertNotNull(menu); + final MenuItem item = menu.findItem(R.id.restore_prefs); + Assert.assertNotNull(item); + + fragment.onOptionsItemSelected(item); + + final AlertDialog dialog = GeneralDialogControllerTest.getLatestShownDialog(); + Assert.assertNotNull(dialog); + Assert.assertEquals(RuntimeEnvironment.application.getText(R.string.word_editor_action_restore_words), GeneralDialogControllerTest.getTitleFromDialog(dialog)); + Assert.assertNotNull(dialog.getListView()); + Assert.assertEquals(GlobalPrefsBackup.getAllPrefsProviders(RuntimeEnvironment.application).size(), dialog.getListView().getCount()); +/* + Assert.assertTrue(AnyApplication.getBackupFile(MainTweaksFragment.GLOBAL_BACKUP_FILENAME).exists()); + Assert.assertTrue(AnyApplication.getBackupFile(MainTweaksFragment.GLOBAL_BACKUP_FILENAME).length() > 0); +*/ + } +}
\ No newline at end of file diff --git a/app/src/test/java/com/anysoftkeyboard/ui/settings/UserInterfaceSettingsFragmentTest.java b/app/src/test/java/com/anysoftkeyboard/ui/settings/UserInterfaceSettingsFragmentTest.java index 517506b7e..002170009 100644 --- a/app/src/test/java/com/anysoftkeyboard/ui/settings/UserInterfaceSettingsFragmentTest.java +++ b/app/src/test/java/com/anysoftkeyboard/ui/settings/UserInterfaceSettingsFragmentTest.java @@ -5,6 +5,7 @@ import android.support.v4.app.Fragment; import android.view.View; import com.anysoftkeyboard.AnySoftKeyboardRobolectricTestRunner; +import com.anysoftkeyboard.ViewTestUtils; import com.menny.android.anysoftkeyboard.R; import org.junit.Assert; @@ -40,20 +41,20 @@ public class UserInterfaceSettingsFragmentTest extends BaseSettingsFragmentTest< public void testNavigationThemes() { final Fragment fragment = startFragment(); - Assert.assertTrue(navigateByClicking(fragment, R.id.settings_tile_themes) instanceof KeyboardThemeSelectorFragment); + Assert.assertTrue(ViewTestUtils.navigateByClicking(fragment, R.id.settings_tile_themes) instanceof KeyboardThemeSelectorFragment); } @Test public void testNavigationEffects() { final Fragment fragment = startFragment(); - Assert.assertTrue(navigateByClicking(fragment, R.id.settings_tile_effects) instanceof EffectsSettingsFragment); + Assert.assertTrue(ViewTestUtils.navigateByClicking(fragment, R.id.settings_tile_effects) instanceof EffectsSettingsFragment); } @Test public void testNavigationTweaks() { final Fragment fragment = startFragment(); - Assert.assertTrue(navigateByClicking(fragment, R.id.settings_tile_even_more) instanceof AdditionalUiSettingsFragment); + Assert.assertTrue(ViewTestUtils.navigateByClicking(fragment, R.id.settings_tile_even_more) instanceof AdditionalUiSettingsFragment); } }
\ No newline at end of file diff --git a/build.gradle b/build.gradle index 6765b70d6..ea7918cac 100644 --- a/build.gradle +++ b/build.gradle @@ -11,7 +11,7 @@ buildscript { maven { url "https://plugins.gradle.org/m2/" } } dependencies { - classpath 'com.android.tools.build:gradle:3.1.0-alpha09' + classpath 'com.android.tools.build:gradle:3.1.0-beta1' classpath 'com.github.Triple-T:gradle-play-publisher:8cda31a5d0e3c4f2d7f47ffde6fc3b370e59dd8a' classpath "net.ltgt.gradle:gradle-errorprone-plugin:0.0.13" } diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar Binary files differindex 70489cefb..eaa7667fd 100644 --- a/gradle/wrapper/gradle-wrapper.jar +++ b/gradle/wrapper/gradle-wrapper.jar diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index aa783d434..be280bec0 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,5 @@ -#Fri Jan 26 20:53:35 EST 2018 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.5-rc-2-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-4.5-bin.zip diff --git a/prefs/src/main/java/com/anysoftkeyboard/prefs/RxSharedPrefs.java b/prefs/src/main/java/com/anysoftkeyboard/prefs/RxSharedPrefs.java index 68dee9bde..fbd4f86ca 100644 --- a/prefs/src/main/java/com/anysoftkeyboard/prefs/RxSharedPrefs.java +++ b/prefs/src/main/java/com/anysoftkeyboard/prefs/RxSharedPrefs.java @@ -28,7 +28,6 @@ import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.support.annotation.RequiresApi; import android.support.annotation.StringRes; -import android.support.annotation.VisibleForTesting; import android.support.v4.content.SharedPreferencesCompat; import com.anysoftkeyboard.base.utils.Logger; @@ -154,8 +153,7 @@ public class RxSharedPrefs { T parse(String value); } - @VisibleForTesting - static class SharedPrefsProvider implements PrefsProvider { + public static class SharedPrefsProvider implements PrefsProvider { private final SharedPreferences mSharedPreferences; diff --git a/prefs/src/main/java/com/anysoftkeyboard/prefs/backup/PrefItem.java b/prefs/src/main/java/com/anysoftkeyboard/prefs/backup/PrefItem.java index 26148bfda..85d6b0476 100644 --- a/prefs/src/main/java/com/anysoftkeyboard/prefs/backup/PrefItem.java +++ b/prefs/src/main/java/com/anysoftkeyboard/prefs/backup/PrefItem.java @@ -47,4 +47,8 @@ public class PrefItem { throw new IllegalArgumentException("The key '" + text + "' has non ASCII or has whitespaces or is empty! This is not valid as an XML attribute"); } } + + public void addChild(PrefItem prefsItem) { + mChildren.add(prefsItem); + } } |
