diff --git a/android/app/src/main/java/app/organicmaps/MwmActivity.java b/android/app/src/main/java/app/organicmaps/MwmActivity.java index c4c38ffca..ce95246bd 100644 --- a/android/app/src/main/java/app/organicmaps/MwmActivity.java +++ b/android/app/src/main/java/app/organicmaps/MwmActivity.java @@ -347,10 +347,10 @@ public class MwmActivity extends BaseMwmFragmentActivity private void migrateOAuthCredentials() { - if (OsmOAuth.containsOAuth1Credentials(this)) + if (OsmOAuth.containsOAuth1Credentials()) { // Remove old OAuth v1 secrets - OsmOAuth.clearOAuth1Credentials(this); + OsmOAuth.clearOAuth1Credentials(); // Notify user to re-login dismissAlertDialog(); diff --git a/android/app/src/main/java/app/organicmaps/MwmApplication.java b/android/app/src/main/java/app/organicmaps/MwmApplication.java index 4bb8d07eb..8aa21dac2 100644 --- a/android/app/src/main/java/app/organicmaps/MwmApplication.java +++ b/android/app/src/main/java/app/organicmaps/MwmApplication.java @@ -31,7 +31,6 @@ import app.organicmaps.sdk.maplayer.subway.SubwayManager; import app.organicmaps.sdk.util.Config; import app.organicmaps.sdk.util.ConnectionState; import app.organicmaps.sdk.util.log.Logger; -import app.organicmaps.sdk.util.log.LogsManager; import app.organicmaps.util.Utils; import java.io.IOException; import java.lang.ref.WeakReference; @@ -52,6 +51,10 @@ public class MwmApplication extends Application implements Application.ActivityL @Nullable private WeakReference mTopActivity; + @SuppressWarnings("NotNullFieldNotInitialized") + @NonNull + public static MwmApplication sInstance; + @UiThread @Nullable public Activity getTopActivity() @@ -101,13 +104,10 @@ public class MwmApplication extends Application implements Application.ActivityL return (MwmApplication) context.getApplicationContext(); } - @NonNull - public static MwmApplication sInstance; - @NonNull public static SharedPreferences prefs(@NonNull Context context) { - return context.getSharedPreferences(context.getString(R.string.pref_file_name), MODE_PRIVATE); + return from(context).getOrganicMaps().getPreferences(); } @Override @@ -120,8 +120,6 @@ public class MwmApplication extends Application implements Application.ActivityL mOrganicMaps = new OrganicMaps(getApplicationContext()); - LogsManager.INSTANCE.initFileLogging(this); - ConnectionState.INSTANCE.initialize(this); DownloaderNotifier.createNotificationChannel(this); diff --git a/android/app/src/main/java/app/organicmaps/background/OsmUploadWork.java b/android/app/src/main/java/app/organicmaps/background/OsmUploadWork.java index cb1f0683c..a38106fdf 100644 --- a/android/app/src/main/java/app/organicmaps/background/OsmUploadWork.java +++ b/android/app/src/main/java/app/organicmaps/background/OsmUploadWork.java @@ -32,7 +32,7 @@ public class OsmUploadWork extends Worker */ public static void startActionUploadOsmChanges(@NonNull Context context) { - if (Editor.nativeHasSomethingToUpload() && OsmOAuth.isAuthorized(context)) + if (Editor.nativeHasSomethingToUpload() && OsmOAuth.isAuthorized()) { final Constraints c = new Constraints.Builder().setRequiredNetworkType(NetworkType.CONNECTED).build(); final WorkRequest wr = new OneTimeWorkRequest.Builder(OsmUploadWork.class).setConstraints(c).build(); @@ -44,13 +44,12 @@ public class OsmUploadWork extends Worker @Override public Result doWork() { - final MwmApplication app = MwmApplication.from(mContext); - if (!app.getOrganicMaps().arePlatformAndCoreInitialized()) + if (!MwmApplication.from(mContext).getOrganicMaps().arePlatformAndCoreInitialized()) { Logger.w(TAG, "Application is not initialized, ignoring " + mWorkerParameters); return Result.failure(); } - Editor.uploadChanges(mContext); + Editor.uploadChanges(); return Result.success(); } } diff --git a/android/app/src/main/java/app/organicmaps/editor/EditorHostFragment.java b/android/app/src/main/java/app/organicmaps/editor/EditorHostFragment.java index 12db30540..3a7cab0c3 100644 --- a/android/app/src/main/java/app/organicmaps/editor/EditorHostFragment.java +++ b/android/app/src/main/java/app/organicmaps/editor/EditorHostFragment.java @@ -356,8 +356,7 @@ public class EditorHostFragment private void processEditedFeatures() { - Context context = requireContext(); - if (OsmOAuth.isAuthorized(context)) + if (OsmOAuth.isAuthorized()) { Utils.navigateToParent(requireActivity()); return; diff --git a/android/app/src/main/java/app/organicmaps/editor/OsmLoginFragment.java b/android/app/src/main/java/app/organicmaps/editor/OsmLoginFragment.java index c4fefc08e..f99bfa254 100644 --- a/android/app/src/main/java/app/organicmaps/editor/OsmLoginFragment.java +++ b/android/app/src/main/java/app/organicmaps/editor/OsmLoginFragment.java @@ -138,7 +138,7 @@ public class OsmLoginFragment extends BaseMwmToolbarFragment private void onAuthSuccess(String oauthToken, String username) { - OsmOAuth.setAuthorization(requireContext(), oauthToken, username); + OsmOAuth.setAuthorization(oauthToken, username); final Bundle extras = requireActivity().getIntent().getExtras(); if (extras != null && extras.getBoolean("redirectToProfile", false)) startActivity(new Intent(requireContext(), ProfileActivity.class)); diff --git a/android/app/src/main/java/app/organicmaps/editor/ProfileFragment.java b/android/app/src/main/java/app/organicmaps/editor/ProfileFragment.java index 9efde2ac0..13d38d882 100644 --- a/android/app/src/main/java/app/organicmaps/editor/ProfileFragment.java +++ b/android/app/src/main/java/app/organicmaps/editor/ProfileFragment.java @@ -60,9 +60,9 @@ public class ProfileFragment extends BaseMwmToolbarFragment view.findViewById(R.id.about_osm) .setOnClickListener((v) -> Utils.openUrl(requireActivity(), getString(R.string.osm_wiki_about_url))); view.findViewById(R.id.osm_history) - .setOnClickListener((v) -> Utils.openUrl(requireActivity(), OsmOAuth.getHistoryUrl(requireContext()))); + .setOnClickListener((v) -> Utils.openUrl(requireActivity(), OsmOAuth.getHistoryUrl())); view.findViewById(R.id.osm_notes) - .setOnClickListener((v) -> Utils.openUrl(requireActivity(), OsmOAuth.getNotesUrl(requireContext()))); + .setOnClickListener((v) -> Utils.openUrl(requireActivity(), OsmOAuth.getNotesUrl())); View buttonsContainer = view.findViewById(R.id.buttons_container); ViewCompat.setOnApplyWindowInsetsListener( @@ -75,7 +75,7 @@ public class ProfileFragment extends BaseMwmToolbarFragment private void refreshViews() { - if (OsmOAuth.isAuthorized(requireContext())) + if (OsmOAuth.isAuthorized()) { // Update the number of uploaded changesets from OSM. ThreadPool.getWorker().execute(() -> { @@ -84,9 +84,9 @@ public class ProfileFragment extends BaseMwmToolbarFragment UiUtils.show(mProfileInfoLoading); UiUtils.hide(mUserInfoBlock); } - final int profileEditCount = OsmOAuth.getOsmChangesetsCount(requireContext(), getParentFragmentManager()); - final String profileUsername = OsmOAuth.getUsername(requireContext()); - final Bitmap profilePicture = OsmOAuth.getProfilePicture(requireContext()); + final int profileEditCount = OsmOAuth.getOsmChangesetsCount(getParentFragmentManager()); + final String profileUsername = OsmOAuth.getUsername(); + final Bitmap profilePicture = OsmOAuth.getProfilePicture(); UiThread.run(() -> { mEditsSent.setText(NumberFormat.getInstance().format(profileEditCount)); @@ -118,7 +118,7 @@ public class ProfileFragment extends BaseMwmToolbarFragment .setMessage(R.string.osm_log_out_confirmation) .setPositiveButton(R.string.yes, (dialog, which) -> { - OsmOAuth.clearAuthorization(requireContext()); + OsmOAuth.clearAuthorization(); refreshViews(); }) .setNegativeButton(R.string.no, null) diff --git a/android/app/src/main/java/app/organicmaps/maplayer/LayersAdapter.java b/android/app/src/main/java/app/organicmaps/maplayer/LayersAdapter.java index 39a8416ff..2d5e20ea8 100644 --- a/android/app/src/main/java/app/organicmaps/maplayer/LayersAdapter.java +++ b/android/app/src/main/java/app/organicmaps/maplayer/LayersAdapter.java @@ -43,7 +43,7 @@ public class LayersAdapter extends RecyclerView.Adapter holder.mButton.setContentDescription(context.getString(item.getTitle())); holder.mTitle.setSelected(isEnabled); holder.mTitle.setText(item.getTitle()); - boolean isNewLayer = SharedPropertiesUtils.shouldShowNewMarkerForLayerMode(context, item.getMode()); + boolean isNewLayer = SharedPropertiesUtils.shouldShowNewMarkerForLayerMode(item.getMode()); UiUtils.showIf(isNewLayer, holder.mNewMarker); holder.mButton.setImageResource(isEnabled ? item.getEnabledStateDrawable() : item.getDisabledStateDrawable()); holder.mListener = item::onClick; diff --git a/android/app/src/main/java/app/organicmaps/maplayer/ToggleMapLayerFragment.java b/android/app/src/main/java/app/organicmaps/maplayer/ToggleMapLayerFragment.java index 8dfab1bf8..60e774e80 100644 --- a/android/app/src/main/java/app/organicmaps/maplayer/ToggleMapLayerFragment.java +++ b/android/app/src/main/java/app/organicmaps/maplayer/ToggleMapLayerFragment.java @@ -70,7 +70,7 @@ public class ToggleMapLayerFragment extends Fragment { Mode mode = item.getMode(); Context context = v.getContext(); - SharedPropertiesUtils.setLayerMarkerShownForLayerMode(context, mode); + SharedPropertiesUtils.setLayerMarkerShownForLayerMode(mode); mode.setEnabled(context, !mode.isEnabled(context)); mAdapter.notifyDataSetChanged(); mMapButtonsController.updateLayerButton(); diff --git a/android/app/src/main/java/app/organicmaps/sdk/OrganicMaps.java b/android/app/src/main/java/app/organicmaps/sdk/OrganicMaps.java index 1bb583681..627d0c746 100644 --- a/android/app/src/main/java/app/organicmaps/sdk/OrganicMaps.java +++ b/android/app/src/main/java/app/organicmaps/sdk/OrganicMaps.java @@ -1,6 +1,7 @@ package app.organicmaps.sdk; import android.content.Context; +import android.content.SharedPreferences; import androidx.annotation.NonNull; import androidx.lifecycle.DefaultLifecycleObserver; import androidx.lifecycle.LifecycleOwner; @@ -9,6 +10,7 @@ import app.organicmaps.R; import app.organicmaps.routing.RoutingController; import app.organicmaps.sdk.bookmarks.data.BookmarkManager; import app.organicmaps.sdk.downloader.Android7RootCertificateWorkaround; +import app.organicmaps.sdk.editor.OsmOAuth; import app.organicmaps.sdk.location.LocationHelper; import app.organicmaps.sdk.location.SensorHelper; import app.organicmaps.sdk.maplayer.isolines.IsolinesManager; @@ -22,6 +24,7 @@ import app.organicmaps.sdk.util.StorageUtils; import app.organicmaps.sdk.util.ThemeSwitcher; import app.organicmaps.sdk.util.UiUtils; import app.organicmaps.sdk.util.log.Logger; +import app.organicmaps.sdk.util.log.LogsManager; import app.organicmaps.settings.StoragePathManager; import java.io.IOException; @@ -32,6 +35,9 @@ public final class OrganicMaps implements DefaultLifecycleObserver @NonNull private final Context mContext; + @NonNull + private final SharedPreferences mPreferences; + @NonNull private final IsolinesManager mIsolinesManager; @NonNull @@ -72,6 +78,8 @@ public final class OrganicMaps implements DefaultLifecycleObserver public OrganicMaps(@NonNull Context context) { mContext = context.getApplicationContext(); + mPreferences = mContext.getSharedPreferences(context.getString(app.organicmaps.sdk.R.string.pref_file_name), + Context.MODE_PRIVATE); // Set configuration directory as early as possible. // Other methods may explicitly use Config, which requires settingsDir to be set. @@ -81,7 +89,10 @@ public final class OrganicMaps implements DefaultLifecycleObserver Logger.d(TAG, "Settings path = " + settingsPath); nativeSetSettingsDir(settingsPath); - Config.init(mContext); + Config.init(mContext, mPreferences); + OsmOAuth.init(mPreferences); + SharedPropertiesUtils.init(mPreferences); + LogsManager.INSTANCE.initFileLogging(mContext, mPreferences); Android7RootCertificateWorkaround.initializeIfNeeded(mContext); @@ -120,6 +131,12 @@ public final class OrganicMaps implements DefaultLifecycleObserver nativeOnTransit(false); } + @NonNull + public SharedPreferences getPreferences() + { + return mPreferences; + } + private void initNativePlatform() throws IOException { if (mPlatformInitialized) @@ -143,7 +160,7 @@ public final class OrganicMaps implements DefaultLifecycleObserver nativeInitPlatform(mContext, apkPath, writablePath, privatePath, tempPath, app.organicmaps.BuildConfig.FLAVOR, app.organicmaps.BuildConfig.BUILD_TYPE, UiUtils.isTablet(mContext)); Config.setStoragePath(writablePath); - Config.setStatisticsEnabled(SharedPropertiesUtils.isStatisticsEnabled(mContext)); + Config.setStatisticsEnabled(SharedPropertiesUtils.isStatisticsEnabled()); mPlatformInitialized = true; Logger.i(TAG, "Platform initialized"); diff --git a/android/app/src/main/java/app/organicmaps/sdk/editor/Editor.java b/android/app/src/main/java/app/organicmaps/sdk/editor/Editor.java index 9e0d90950..7bc120164 100644 --- a/android/app/src/main/java/app/organicmaps/sdk/editor/Editor.java +++ b/android/app/src/main/java/app/organicmaps/sdk/editor/Editor.java @@ -1,6 +1,5 @@ package app.organicmaps.sdk.editor; -import android.content.Context; import androidx.annotation.IntDef; import androidx.annotation.NonNull; import androidx.annotation.Size; @@ -43,10 +42,10 @@ public final class Editor private static native void nativeInit(); @WorkerThread - public static void uploadChanges(@NonNull Context context) + public static void uploadChanges() { - if (nativeHasSomethingToUpload() && OsmOAuth.isAuthorized(context)) - nativeUploadChanges(OsmOAuth.getAuthToken(context), BuildConfig.VERSION_NAME, BuildConfig.APPLICATION_ID); + if (nativeHasSomethingToUpload() && OsmOAuth.isAuthorized()) + nativeUploadChanges(OsmOAuth.getAuthToken(), BuildConfig.VERSION_NAME, BuildConfig.APPLICATION_ID); } public static native boolean nativeShouldShowEditPlace(); diff --git a/android/app/src/main/java/app/organicmaps/sdk/editor/OsmOAuth.java b/android/app/src/main/java/app/organicmaps/sdk/editor/OsmOAuth.java index 093bce4dd..e0ea2f329 100644 --- a/android/app/src/main/java/app/organicmaps/sdk/editor/OsmOAuth.java +++ b/android/app/src/main/java/app/organicmaps/sdk/editor/OsmOAuth.java @@ -1,6 +1,5 @@ package app.organicmaps.sdk.editor; -import android.content.Context; import android.content.SharedPreferences; import android.graphics.Bitmap; import androidx.annotation.NonNull; @@ -8,7 +7,6 @@ import androidx.annotation.Nullable; import androidx.annotation.Size; import androidx.annotation.WorkerThread; import androidx.fragment.app.FragmentManager; -import app.organicmaps.MwmApplication; import app.organicmaps.sdk.util.NetworkPolicy; public final class OsmOAuth @@ -28,7 +26,9 @@ public final class OsmOAuth } } - public static final int OK = 0; + @SuppressWarnings("NotNullFieldNotInitialized") + @NonNull + private static SharedPreferences mPrefs; private static final String PREF_OSM_TOKEN = "OsmToken"; // Unused after migration from OAuth1 to OAuth2 private static final String PREF_OSM_SECRET = "OsmSecret"; // Unused after migration from OAuth1 to OAuth2 @@ -38,51 +38,50 @@ public final class OsmOAuth public static final String URL_PARAM_VERIFIER = "oauth_verifier"; - public static boolean isAuthorized(@NonNull Context context) + public static void init(@NonNull SharedPreferences prefs) { - return MwmApplication.prefs(context).contains(PREF_OSM_OAUTH2_TOKEN); + mPrefs = prefs; } - public static boolean containsOAuth1Credentials(@NonNull Context context) + public static boolean isAuthorized() { - SharedPreferences prefs = MwmApplication.prefs(context); - return prefs.contains(PREF_OSM_TOKEN) && prefs.contains(PREF_OSM_SECRET); + return mPrefs.contains(PREF_OSM_OAUTH2_TOKEN); } - public static void clearOAuth1Credentials(@NonNull Context context) + public static boolean containsOAuth1Credentials() { - MwmApplication.prefs(context).edit().remove(PREF_OSM_TOKEN).remove(PREF_OSM_SECRET).apply(); + return mPrefs.contains(PREF_OSM_TOKEN) && mPrefs.contains(PREF_OSM_SECRET); } - public static String getAuthToken(@NonNull Context context) + public static void clearOAuth1Credentials() { - return MwmApplication.prefs(context).getString(PREF_OSM_OAUTH2_TOKEN, ""); + mPrefs.edit().remove(PREF_OSM_TOKEN).remove(PREF_OSM_SECRET).apply(); } - public static String getUsername(@NonNull Context context) + public static String getAuthToken() { - return MwmApplication.prefs(context).getString(PREF_OSM_USERNAME, ""); + return mPrefs.getString(PREF_OSM_OAUTH2_TOKEN, ""); } - public static Bitmap getProfilePicture(@NonNull Context context) + public static String getUsername() + { + return mPrefs.getString(PREF_OSM_USERNAME, ""); + } + + public static Bitmap getProfilePicture() { // TODO(HB): load and store image in cache here return null; } - public static void setAuthorization(@NonNull Context context, String oauthToken, String username) + public static void setAuthorization(String oauthToken, String username) { - MwmApplication.prefs(context) - .edit() - .putString(PREF_OSM_OAUTH2_TOKEN, oauthToken) - .putString(PREF_OSM_USERNAME, username) - .apply(); + mPrefs.edit().putString(PREF_OSM_OAUTH2_TOKEN, oauthToken).putString(PREF_OSM_USERNAME, username).apply(); } - public static void clearAuthorization(@NonNull Context context) + public static void clearAuthorization() { - MwmApplication.prefs(context) - .edit() + mPrefs.edit() .remove(PREF_OSM_TOKEN) .remove(PREF_OSM_SECRET) .remove(PREF_OSM_USERNAME) @@ -90,14 +89,16 @@ public final class OsmOAuth .apply(); } - public static String getHistoryUrl(@NonNull Context context) + @NonNull + public static String getHistoryUrl() { - return nativeGetHistoryUrl(getUsername(context)); + return nativeGetHistoryUrl(getUsername()); } - public static String getNotesUrl(@NonNull Context context) + @NonNull + public static String getNotesUrl() { - return nativeGetNotesUrl(getUsername(context)); + return nativeGetNotesUrl(getUsername()); } /* @@ -144,21 +145,20 @@ public final class OsmOAuth private static native int nativeGetOsmChangesetsCount(String oauthToken); @WorkerThread - public static int getOsmChangesetsCount(@NonNull Context context, @NonNull FragmentManager fm) + public static int getOsmChangesetsCount(@NonNull FragmentManager fm) { final int[] editsCount = {-1}; NetworkPolicy.checkNetworkPolicy(fm, policy -> { if (!policy.canUseNetwork()) return; - final String token = getAuthToken(context); + final String token = getAuthToken(); editsCount[0] = OsmOAuth.nativeGetOsmChangesetsCount(token); }); - final SharedPreferences prefs = MwmApplication.prefs(context); if (editsCount[0] < 0) - return prefs.getInt(PREF_OSM_CHANGESETS_COUNT, 0); + return mPrefs.getInt(PREF_OSM_CHANGESETS_COUNT, 0); - prefs.edit().putInt(PREF_OSM_CHANGESETS_COUNT, editsCount[0]).apply(); + mPrefs.edit().putInt(PREF_OSM_CHANGESETS_COUNT, editsCount[0]).apply(); return editsCount[0]; } } diff --git a/android/app/src/main/java/app/organicmaps/sdk/util/Config.java b/android/app/src/main/java/app/organicmaps/sdk/util/Config.java index 693ddba52..3868c0aab 100644 --- a/android/app/src/main/java/app/organicmaps/sdk/util/Config.java +++ b/android/app/src/main/java/app/organicmaps/sdk/util/Config.java @@ -6,12 +6,15 @@ import android.os.Build; import androidx.annotation.NonNull; import androidx.preference.PreferenceManager; import app.organicmaps.BuildConfig; -import app.organicmaps.MwmApplication; import app.organicmaps.R; import app.organicmaps.util.ThemeUtils; public final class Config { + @SuppressWarnings("NotNullFieldNotInitialized") + @NonNull + private static SharedPreferences mPrefs; + private static final String KEY_APP_STORAGE = "StoragePath"; private static final String KEY_DOWNLOADER_AUTO = "AutoDownloadEnabled"; @@ -332,19 +335,19 @@ public final class Config return url; } - public static void init(@NonNull Context context) + public static void init(@NonNull Context context, @NonNull SharedPreferences prefs) { PreferenceManager.setDefaultValues(context, R.xml.prefs_main, false); - final SharedPreferences prefs = MwmApplication.prefs(context); - final SharedPreferences.Editor editor = prefs.edit(); + mPrefs = prefs; + final SharedPreferences.Editor editor = mPrefs.edit(); // Update counters. - final int launchNumber = prefs.getInt(KEY_APP_LAUNCH_NUMBER, 0); + final int launchNumber = mPrefs.getInt(KEY_APP_LAUNCH_NUMBER, 0); editor.putInt(KEY_APP_LAUNCH_NUMBER, launchNumber + 1); editor.putLong(KEY_APP_LAST_SESSION_TIMESTAMP, System.currentTimeMillis()); editor.putInt(KEY_APP_LAST_INSTALL_VERSION_CODE, BuildConfig.VERSION_CODE); - if (launchNumber == 0 || prefs.getInt(KEY_APP_FIRST_INSTALL_VERSION_CODE, 0) == 0) + if (launchNumber == 0 || mPrefs.getInt(KEY_APP_FIRST_INSTALL_VERSION_CODE, 0) == 0) editor.putInt(KEY_APP_FIRST_INSTALL_VERSION_CODE, BuildConfig.VERSION_CODE); // Clean up legacy counters. @@ -367,12 +370,12 @@ public final class Config public static boolean isFirstLaunch(@NonNull Context context) { - return !MwmApplication.prefs(context).getBoolean(KEY_MISC_FIRST_START_DIALOG_SEEN, false); + return !mPrefs.getBoolean(KEY_MISC_FIRST_START_DIALOG_SEEN, false); } public static void setFirstStartDialogSeen(@NonNull Context context) { - MwmApplication.prefs(context).edit().putBoolean(KEY_MISC_FIRST_START_DIALOG_SEEN, true).apply(); + mPrefs.edit().putBoolean(KEY_MISC_FIRST_START_DIALOG_SEEN, true).apply(); } public static boolean isSearchHistoryEnabled() diff --git a/android/app/src/main/java/app/organicmaps/sdk/util/SharedPropertiesUtils.java b/android/app/src/main/java/app/organicmaps/sdk/util/SharedPropertiesUtils.java index 361a4d9ef..6a28b6163 100644 --- a/android/app/src/main/java/app/organicmaps/sdk/util/SharedPropertiesUtils.java +++ b/android/app/src/main/java/app/organicmaps/sdk/util/SharedPropertiesUtils.java @@ -5,8 +5,6 @@ import static app.organicmaps.sdk.util.Config.KEY_PREF_STATISTICS; import android.content.Context; import android.content.SharedPreferences; import androidx.annotation.NonNull; -import androidx.preference.PreferenceManager; -import app.organicmaps.MwmApplication; import app.organicmaps.R; import app.organicmaps.sdk.maplayer.Mode; import java.io.IOException; @@ -17,27 +15,34 @@ public final class SharedPropertiesUtils private static final String PREFS_SHOW_EMULATE_BAD_STORAGE_SETTING = "ShowEmulateBadStorageSetting"; private static final String PREFS_SHOULD_SHOW_LAYER_MARKER_FOR = "ShouldShowGuidesLayerMarkerFor"; + @SuppressWarnings("NotNullFieldNotInitialized") + @NonNull + private static SharedPreferences mPrefs; + // Utils class private SharedPropertiesUtils() { throw new IllegalStateException("Try instantiate utility class SharedPropertiesUtils"); } - public static boolean isStatisticsEnabled(@NonNull Context context) + public static void init(@NonNull SharedPreferences prefs) { - return MwmApplication.prefs(context).getBoolean(KEY_PREF_STATISTICS, true); + mPrefs = prefs; } - public static void setShouldShowEmulateBadStorageSetting(@NonNull Context context, boolean show) + public static boolean isStatisticsEnabled() { - SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(MwmApplication.from(context)); - prefs.edit().putBoolean(PREFS_SHOW_EMULATE_BAD_STORAGE_SETTING, show).apply(); + return mPrefs.getBoolean(KEY_PREF_STATISTICS, true); } - public static boolean shouldShowEmulateBadStorageSetting(@NonNull Context context) + public static void setShouldShowEmulateBadStorageSetting(boolean show) { - SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(MwmApplication.from(context)); - return prefs.getBoolean(PREFS_SHOW_EMULATE_BAD_STORAGE_SETTING, false); + mPrefs.edit().putBoolean(PREFS_SHOW_EMULATE_BAD_STORAGE_SETTING, show).apply(); + } + + public static boolean shouldShowEmulateBadStorageSetting() + { + return mPrefs.getBoolean(PREFS_SHOW_EMULATE_BAD_STORAGE_SETTING, false); } /** @@ -46,38 +51,28 @@ public final class SharedPropertiesUtils */ public static void emulateBadExternalStorage(@NonNull Context context) throws IOException { - SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(MwmApplication.from(context)); - String key = MwmApplication.from(context).getString(R.string.pref_emulate_bad_external_storage); - if (prefs.getBoolean(key, false)) + final String key = context.getString(R.string.pref_emulate_bad_external_storage); + if (mPrefs.getBoolean(key, false)) { // Emulate one time only -> reset setting to run normally next time. - prefs.edit().putBoolean(key, false).apply(); + mPrefs.edit().putBoolean(key, false).apply(); throw new IOException("Bad external storage error injection"); } } - public static boolean shouldShowNewMarkerForLayerMode(@NonNull Context context, @NonNull Mode mode) + public static boolean shouldShowNewMarkerForLayerMode(@NonNull Mode mode) { return switch (mode) { case SUBWAY, TRAFFIC, ISOLINES -> false; - default -> - getBoolean(context, PREFS_SHOULD_SHOW_LAYER_MARKER_FOR + mode.name().toLowerCase(Locale.ENGLISH), true); + default -> mPrefs.getBoolean(PREFS_SHOULD_SHOW_LAYER_MARKER_FOR + mode.name().toLowerCase(Locale.ENGLISH), true); }; } - public static void setLayerMarkerShownForLayerMode(@NonNull Context context, @NonNull Mode mode) + public static void setLayerMarkerShownForLayerMode(@NonNull Mode mode) { - putBoolean(context, PREFS_SHOULD_SHOW_LAYER_MARKER_FOR + mode.name().toLowerCase(Locale.ENGLISH), false); - } - - private static boolean getBoolean(@NonNull Context context, @NonNull String key, boolean defValue) - { - return MwmApplication.prefs(context).getBoolean(key, defValue); - } - - private static void putBoolean(@NonNull Context context, @NonNull String key, boolean value) - { - MwmApplication.prefs(context).edit().putBoolean(key, value).apply(); + mPrefs.edit() + .putBoolean(PREFS_SHOULD_SHOW_LAYER_MARKER_FOR + mode.name().toLowerCase(Locale.ENGLISH), false) + .apply(); } } diff --git a/android/app/src/main/java/app/organicmaps/sdk/util/log/LogsManager.java b/android/app/src/main/java/app/organicmaps/sdk/util/log/LogsManager.java index e7a5db28e..fbcf1155b 100644 --- a/android/app/src/main/java/app/organicmaps/sdk/util/log/LogsManager.java +++ b/android/app/src/main/java/app/organicmaps/sdk/util/log/LogsManager.java @@ -2,7 +2,6 @@ package app.organicmaps.sdk.util.log; import android.Manifest; import android.app.ActivityManager; -import android.app.Application; import android.content.Context; import android.content.SharedPreferences; import android.content.pm.PackageManager; @@ -18,7 +17,6 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.core.content.ContextCompat; import app.organicmaps.BuildConfig; -import app.organicmaps.MwmApplication; import app.organicmaps.R; import app.organicmaps.sdk.util.ROMUtils; import app.organicmaps.sdk.util.StringUtils; @@ -34,7 +32,7 @@ import net.jcip.annotations.ThreadSafe; /** * By default uses Android's system logger. * After an initFileLogging() call can use a custom file logging implementation. - * + *

* Its important to have only system logging here to avoid infinite loop * (Logger calls getEnabledLogsFolder() in preparation to write). */ @@ -44,7 +42,7 @@ public final class LogsManager public interface OnZipCompletedListener { // Called from the logger thread. - public void onCompleted(final boolean success, @Nullable final String zipPath); + void onCompleted(final boolean success, @Nullable final String zipPath); } private final static String TAG = LogsManager.class.getSimpleName(); @@ -53,7 +51,9 @@ public final class LogsManager final static ExecutorService EXECUTOR = Executors.newSingleThreadExecutor(); @Nullable - private Application mApplication; + private Context mApplicationContext; + @Nullable + private SharedPreferences mPrefs; private boolean mIsFileLoggingEnabled = false; @Nullable private String mLogsFolder; @@ -63,13 +63,13 @@ public final class LogsManager Log.i(LogsManager.TAG, "Logging started"); } - public synchronized void initFileLogging(@NonNull Application application) + public synchronized void initFileLogging(@NonNull Context context, @NonNull SharedPreferences prefs) { Log.i(TAG, "Init file logging"); - mApplication = application; + mApplicationContext = context.getApplicationContext(); + mPrefs = prefs; - final SharedPreferences prefs = MwmApplication.prefs(mApplication); - mIsFileLoggingEnabled = prefs.getBoolean(mApplication.getString(R.string.pref_enable_logging), false); + mIsFileLoggingEnabled = mPrefs.getBoolean(mApplicationContext.getString(R.string.pref_enable_logging), false); Log.i(TAG, "isFileLoggingEnabled preference: " + mIsFileLoggingEnabled); mIsFileLoggingEnabled = mIsFileLoggingEnabled && ensureLogsFolder() != null; @@ -79,7 +79,7 @@ public final class LogsManager private void assertFileLoggingInit() { - assert mApplication != null : "mApplication must be initialized first by calling initFileLogging()"; + assert mApplicationContext != null : "mApplicationContext must be initialized first by calling initFileLogging()"; } /** @@ -114,9 +114,9 @@ public final class LogsManager if (mLogsFolder != null && createWritableDir(mLogsFolder)) return mLogsFolder; - mLogsFolder = createLogsFolder(mApplication.getExternalFilesDir(null)); + mLogsFolder = createLogsFolder(mApplicationContext.getExternalFilesDir(null)); if (mLogsFolder == null) - mLogsFolder = createLogsFolder(mApplication.getFilesDir()); + mLogsFolder = createLogsFolder(mApplicationContext.getFilesDir()); if (mLogsFolder == null) Log.e(TAG, "Can't create any logs folder"); @@ -166,10 +166,7 @@ public final class LogsManager mIsFileLoggingEnabled = enabled; // Only Debug builds log DEBUG level to Android system log. nativeToggleCoreDebugLogs(enabled || BuildConfig.DEBUG); - MwmApplication.prefs(mApplication) - .edit() - .putBoolean(mApplication.getString(R.string.pref_enable_logging), enabled) - .apply(); + mPrefs.edit().putBoolean(mApplicationContext.getString(R.string.pref_enable_logging), enabled).apply(); Log.i(TAG, "Logging to " + (enabled ? "logs folder " + mLogsFolder : "system log")); } @@ -180,7 +177,7 @@ public final class LogsManager /** * Returns false if file logging can't be enabled. - * + *

* NOTE: initFileLogging() must be called before. */ public synchronized boolean setFileLoggingEnabled(boolean enabled) @@ -256,7 +253,7 @@ public final class LogsManager .append(Locale.getDefault()) .append("\nNetworks: "); final ConnectivityManager manager = - (ConnectivityManager) mApplication.getSystemService(Context.CONNECTIVITY_SERVICE); + (ConnectivityManager) mApplicationContext.getSystemService(Context.CONNECTIVITY_SERVICE); if (manager != null) { for (Network network : manager.getAllNetworks()) @@ -267,16 +264,16 @@ public final class LogsManager } sb.append("\nLocation providers:"); final LocationManager locMngr = - (android.location.LocationManager) mApplication.getSystemService(Context.LOCATION_SERVICE); + (android.location.LocationManager) mApplicationContext.getSystemService(Context.LOCATION_SERVICE); if (locMngr != null) for (String provider : locMngr.getProviders(true)) sb.append(' ').append(provider); sb.append("\nLocation permissions:"); - if (ContextCompat.checkSelfPermission(mApplication, Manifest.permission.ACCESS_COARSE_LOCATION) + if (ContextCompat.checkSelfPermission(mApplicationContext, Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED) sb.append(' ').append("coarse"); - if (ContextCompat.checkSelfPermission(mApplication, Manifest.permission.ACCESS_FINE_LOCATION) + if (ContextCompat.checkSelfPermission(mApplicationContext, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) sb.append(' ').append("fine"); diff --git a/android/app/src/main/java/app/organicmaps/search/SearchFragment.java b/android/app/src/main/java/app/organicmaps/search/SearchFragment.java index bdfefb629..ab84b7caa 100644 --- a/android/app/src/main/java/app/organicmaps/search/SearchFragment.java +++ b/android/app/src/main/java/app/organicmaps/search/SearchFragment.java @@ -586,7 +586,7 @@ public class SearchFragment extends BaseMwmFragment implements SearchListener, C @Override void executeInternal() { - SharedPropertiesUtils.setShouldShowEmulateBadStorageSetting(mContext, true); + SharedPropertiesUtils.setShouldShowEmulateBadStorageSetting(true); } } diff --git a/android/app/src/main/java/app/organicmaps/settings/SettingsPrefsFragment.java b/android/app/src/main/java/app/organicmaps/settings/SettingsPrefsFragment.java index 3a7bf2cf2..125f786da 100644 --- a/android/app/src/main/java/app/organicmaps/settings/SettingsPrefsFragment.java +++ b/android/app/src/main/java/app/organicmaps/settings/SettingsPrefsFragment.java @@ -148,9 +148,9 @@ public class SettingsPrefsFragment extends BaseXmlSettingsFragment implements La private void updateProfileSettingsPrefsSummary() { final Preference pref = getPreference(getString(R.string.pref_osm_profile)); - if (OsmOAuth.isAuthorized(requireContext())) + if (OsmOAuth.isAuthorized()) { - final String username = OsmOAuth.getUsername(requireContext()); + final String username = OsmOAuth.getUsername(); pref.setSummary(username); } else @@ -285,7 +285,7 @@ public class SettingsPrefsFragment extends BaseXmlSettingsFragment implements La if (pref == null) return; - if (!SharedPropertiesUtils.shouldShowEmulateBadStorageSetting(requireContext())) + if (!SharedPropertiesUtils.shouldShowEmulateBadStorageSetting()) removePreference(getString(R.string.pref_settings_general), pref); else pref.setVisible(true); diff --git a/android/app/src/main/res/values/donottranslate.xml b/android/app/src/main/res/values/donottranslate.xml index f0ea2b2f9..5baab3565 100644 --- a/android/app/src/main/res/values/donottranslate.xml +++ b/android/app/src/main/res/values/donottranslate.xml @@ -13,7 +13,6 @@ EnableLogging EmulateBadExternalStorage AboutOrganicMaps - OrganicMapsPrefs MapStyle TtsScreen TtsEnabled diff --git a/android/sdk/src/main/res/values/donottranslate.xml b/android/sdk/src/main/res/values/donottranslate.xml new file mode 100644 index 000000000..3998fc654 --- /dev/null +++ b/android/sdk/src/main/res/values/donottranslate.xml @@ -0,0 +1,4 @@ + + + OrganicMapsPrefs +