[android][sdk] Refactor shared preferences

Signed-off-by: Andrei Shkrob <github@shkrob.dev>
This commit is contained in:
Andrei Shkrob
2025-06-29 22:07:12 +02:00
committed by Konstantin Pastbin
parent c600a4fd5d
commit 40adb0f860
18 changed files with 137 additions and 127 deletions

View File

@@ -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();

View File

@@ -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<Activity> 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);

View File

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

View File

@@ -356,8 +356,7 @@ public class EditorHostFragment
private void processEditedFeatures()
{
Context context = requireContext();
if (OsmOAuth.isAuthorized(context))
if (OsmOAuth.isAuthorized())
{
Utils.navigateToParent(requireActivity());
return;

View File

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

View File

@@ -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)

View File

@@ -43,7 +43,7 @@ public class LayersAdapter extends RecyclerView.Adapter<LayerHolder>
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;

View File

@@ -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();

View File

@@ -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");

View File

@@ -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();

View File

@@ -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];
}
}

View File

@@ -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()

View File

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

View File

@@ -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.
*
* <p>
* 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.
*
* <p>
* 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");

View File

@@ -586,7 +586,7 @@ public class SearchFragment extends BaseMwmFragment implements SearchListener, C
@Override
void executeInternal()
{
SharedPropertiesUtils.setShouldShowEmulateBadStorageSetting(mContext, true);
SharedPropertiesUtils.setShouldShowEmulateBadStorageSetting(true);
}
}

View File

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

View File

@@ -13,7 +13,6 @@
<string name="pref_enable_logging" translatable="false">EnableLogging</string>
<string name="pref_emulate_bad_external_storage" translatable="false">EmulateBadExternalStorage</string>
<string name="pref_about" translatable="false">AboutOrganicMaps</string>
<string name="pref_file_name" translatable="false">OrganicMapsPrefs</string>
<string name="pref_map_style" translatable="false">MapStyle</string>
<string name="pref_tts_screen" translatable="false">TtsScreen</string>
<string name="pref_tts_enabled" translatable="false">TtsEnabled</string>

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="pref_file_name" translatable="false">OrganicMapsPrefs</string>
</resources>