forked from organicmaps/organicmaps
Merge pull request #5388 from alexzatsepin/android-my-pos-fix
Android my pos fix
This commit is contained in:
commit
5f43e2cd31
26 changed files with 428 additions and 522 deletions
|
@ -95,14 +95,8 @@ void Framework::OnLocationError(int errorCode)
|
|||
|
||||
void Framework::OnLocationUpdated(location::GpsInfo const & info)
|
||||
{
|
||||
ASSERT(IsDrapeEngineCreated(), ());
|
||||
m_work.OnLocationUpdate(info);
|
||||
|
||||
if (!IsDrapeEngineCreated())
|
||||
{
|
||||
location::EMyPositionMode const mode = GetMyPositionMode();
|
||||
if (mode == location::PendingPosition)
|
||||
SetMyPositionMode(location::Follow);
|
||||
}
|
||||
}
|
||||
|
||||
void Framework::OnCompassUpdated(location::CompassInfo const & info, bool forceRedraw)
|
||||
|
@ -135,13 +129,6 @@ void Framework::TrafficStateChanged(TrafficManager::TrafficState state)
|
|||
m_onTrafficStateChangedFn(state);
|
||||
}
|
||||
|
||||
void Framework::SetMyPositionMode(location::EMyPositionMode mode)
|
||||
{
|
||||
OnMyPositionModeChanged(mode);
|
||||
settings::Set(settings::kLocationStateMode, m_currentMode);
|
||||
MyPositionModeChanged(m_currentMode, false /* routingActive, does not matter */);
|
||||
}
|
||||
|
||||
bool Framework::CreateDrapeEngine(JNIEnv * env, jobject jSurface, int densityDpi, bool firstLaunch)
|
||||
{
|
||||
m_contextFactory = make_unique_dp<dp::ThreadSafeFactory>(new AndroidOGLContextFactory(env, jSurface));
|
||||
|
@ -463,15 +450,8 @@ void Framework::OnMyPositionModeChanged(location::EMyPositionMode mode)
|
|||
|
||||
void Framework::SwitchMyPositionNextMode()
|
||||
{
|
||||
if (IsDrapeEngineCreated())
|
||||
{
|
||||
m_work.SwitchMyPositionNextMode();
|
||||
return;
|
||||
}
|
||||
|
||||
// Engine is not available, but the client requests to change mode.
|
||||
if (GetMyPositionMode() == location::NotFollowNoPosition)
|
||||
SetMyPositionMode(location::PendingPosition);
|
||||
ASSERT(IsDrapeEngineCreated(), ());
|
||||
m_work.SwitchMyPositionNextMode();
|
||||
}
|
||||
|
||||
void Framework::SetupWidget(gui::EWidget widget, float x, float y, dp::Anchor anchor)
|
||||
|
|
|
@ -52,7 +52,6 @@ namespace android
|
|||
void TrafficStateChanged(TrafficManager::TrafficState state);
|
||||
|
||||
void MyPositionModeChanged(location::EMyPositionMode mode, bool routingActive);
|
||||
void SetMyPositionMode(location::EMyPositionMode mode);
|
||||
|
||||
location::TMyPositionModeChanged m_myPositionModeSignal;
|
||||
location::EMyPositionMode m_currentMode;
|
||||
|
|
|
@ -54,7 +54,6 @@ public class MapFragment extends BaseMwmFragment
|
|||
private int mWidth;
|
||||
private boolean mRequireResize;
|
||||
private boolean mContextCreated;
|
||||
private boolean mFirstStart;
|
||||
private static boolean sWasCopyrightDisplayed;
|
||||
|
||||
interface MapRenderingListener
|
||||
|
@ -167,11 +166,11 @@ public class MapFragment extends BaseMwmFragment
|
|||
getActivity().getWindowManager().getDefaultDisplay().getMetrics(metrics);
|
||||
final float exactDensityDpi = metrics.densityDpi;
|
||||
|
||||
mFirstStart = ((MwmActivity) getMwmActivity()).isFirstStart();
|
||||
if (mFirstStart)
|
||||
boolean firstStart = ((MwmActivity) getMwmActivity()).isFirstStart();
|
||||
if (firstStart)
|
||||
PushwooshHelper.nativeProcessFirstLaunch();
|
||||
|
||||
if (!nativeCreateEngine(surface, (int) exactDensityDpi, mFirstStart))
|
||||
if (!nativeCreateEngine(surface, (int) exactDensityDpi, firstStart))
|
||||
{
|
||||
reportUnsupported();
|
||||
return;
|
||||
|
@ -286,13 +285,6 @@ public class MapFragment extends BaseMwmFragment
|
|||
}
|
||||
}
|
||||
|
||||
boolean isFirstStart()
|
||||
{
|
||||
boolean res = mFirstStart;
|
||||
mFirstStart = false;
|
||||
return res;
|
||||
}
|
||||
|
||||
boolean isContextCreated()
|
||||
{
|
||||
return mContextCreated;
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package com.mapswithme.maps;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.Dialog;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
|
@ -174,6 +175,8 @@ public class MwmActivity extends BaseMwmFragmentActivity
|
|||
private boolean mPlacePageRestored;
|
||||
|
||||
private boolean mLocationErrorDialogAnnoying = false;
|
||||
@Nullable
|
||||
private Dialog mLocationErrorDialog;
|
||||
|
||||
@NonNull
|
||||
private final OnClickListener mOnMyPositionClickListener = new OnClickListener()
|
||||
|
@ -183,6 +186,7 @@ public class MwmActivity extends BaseMwmFragmentActivity
|
|||
{
|
||||
mLocationErrorDialogAnnoying = false;
|
||||
LocationHelper.INSTANCE.switchToNextMode();
|
||||
LocationHelper.INSTANCE.restart();
|
||||
Statistics.INSTANCE.trackEvent(Statistics.EventName.TOOLBAR_MY_POSITION);
|
||||
AlohaHelper.logClick(AlohaHelper.TOOLBAR_MY_POSITION);
|
||||
}
|
||||
|
@ -1006,20 +1010,9 @@ public class MwmActivity extends BaseMwmFragmentActivity
|
|||
{
|
||||
mFirstStart = FirstStartFragment.showOn(this);
|
||||
if (mFirstStart)
|
||||
{
|
||||
if (LocationHelper.INSTANCE.isTurnedOn())
|
||||
addTask(new MwmActivity.MapTask()
|
||||
{
|
||||
@Override
|
||||
public boolean run(MwmActivity target)
|
||||
{
|
||||
if (LocationHelper.INSTANCE.isTurnedOn())
|
||||
LocationHelper.INSTANCE.switchToNextMode();
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
else if (!NewsFragment.showOn(this))
|
||||
return;
|
||||
|
||||
if (!NewsFragment.showOn(this))
|
||||
{
|
||||
if (ViralFragment.shouldDisplay())
|
||||
new ViralFragment().show(getSupportFragmentManager(), "");
|
||||
|
@ -1792,7 +1785,10 @@ public class MwmActivity extends BaseMwmFragmentActivity
|
|||
|
||||
private void showLocationErrorDialog(@NonNull final Intent intent)
|
||||
{
|
||||
new AlertDialog.Builder(this)
|
||||
if (mLocationErrorDialog != null && mLocationErrorDialog.isShowing())
|
||||
return;
|
||||
|
||||
mLocationErrorDialog = new AlertDialog.Builder(this)
|
||||
.setTitle(R.string.enable_location_services)
|
||||
.setMessage(R.string.location_is_disabled_long_text)
|
||||
.setNegativeButton(R.string.close, new DialogInterface.OnClickListener()
|
||||
|
@ -1824,9 +1820,6 @@ public class MwmActivity extends BaseMwmFragmentActivity
|
|||
@Override
|
||||
public void onLocationNotFound()
|
||||
{
|
||||
if (!shouldNotifyLocationNotFound())
|
||||
return;
|
||||
|
||||
showLocationNotFoundDialog();
|
||||
}
|
||||
|
||||
|
@ -1836,34 +1829,15 @@ public class MwmActivity extends BaseMwmFragmentActivity
|
|||
getString(R.string.current_location_unknown_title));
|
||||
new AlertDialog.Builder(this)
|
||||
.setMessage(message)
|
||||
.setNegativeButton(R.string.current_location_unknown_stop_button, new DialogInterface.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which)
|
||||
{
|
||||
LocationHelper.INSTANCE.stop();
|
||||
}
|
||||
})
|
||||
.setNegativeButton(R.string.current_location_unknown_stop_button, null)
|
||||
.setPositiveButton(R.string.current_location_unknown_continue_button, new DialogInterface.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which)
|
||||
{
|
||||
LocationHelper.INSTANCE.switchToNextMode();
|
||||
LocationHelper.INSTANCE.start();
|
||||
}
|
||||
}).setOnDismissListener(new DialogInterface.OnDismissListener()
|
||||
{
|
||||
@Override
|
||||
public void onDismiss(DialogInterface dialog)
|
||||
{
|
||||
LocationHelper.INSTANCE.stop();
|
||||
}
|
||||
}).show();
|
||||
}
|
||||
|
||||
private boolean shouldNotifyLocationNotFound()
|
||||
{
|
||||
return mMapFragment != null && !mMapFragment.isFirstStart();
|
||||
}).show();
|
||||
}
|
||||
|
||||
public static class ShowAuthorizationTask implements MapTask
|
||||
|
|
|
@ -23,6 +23,7 @@ import com.mapswithme.maps.bookmarks.data.BookmarkManager;
|
|||
import com.mapswithme.maps.downloader.CountryItem;
|
||||
import com.mapswithme.maps.downloader.MapManager;
|
||||
import com.mapswithme.maps.editor.Editor;
|
||||
import com.mapswithme.maps.location.LocationHelper;
|
||||
import com.mapswithme.maps.location.TrackRecorder;
|
||||
import com.mapswithme.maps.routing.RoutingController;
|
||||
import com.mapswithme.maps.settings.StoragePathManager;
|
||||
|
@ -179,6 +180,7 @@ public class MwmApplication extends Application
|
|||
BookmarkManager.nativeLoadBookmarks();
|
||||
TtsPlayer.INSTANCE.init(this);
|
||||
ThemeSwitcher.restart();
|
||||
LocationHelper.INSTANCE.initialize();
|
||||
RoutingController.get().initialize();
|
||||
TrafficManager.INSTANCE.initialize();
|
||||
mIsFrameworkInitialized = true;
|
||||
|
|
|
@ -7,6 +7,7 @@ import android.os.Bundle;
|
|||
import android.support.annotation.NonNull;
|
||||
import android.view.View;
|
||||
|
||||
import com.mapswithme.maps.location.LocationHelper;
|
||||
import com.mapswithme.maps.location.LocationState;
|
||||
import com.mapswithme.maps.routing.RoutingController;
|
||||
import com.mapswithme.util.Animations;
|
||||
|
@ -219,7 +220,7 @@ class NavigationButtonsAnimationController
|
|||
|
||||
private boolean shouldBeHidden()
|
||||
{
|
||||
return LocationState.getMode() == LocationState.FOLLOW_AND_ROTATE
|
||||
return LocationHelper.INSTANCE.getMyPositionMode() == LocationState.FOLLOW_AND_ROTATE
|
||||
&& (RoutingController.get().isPlanning() || RoutingController.get().isNavigating());
|
||||
}
|
||||
|
||||
|
|
|
@ -21,7 +21,6 @@ class AndroidNativeProvider extends BaseLocationProvider
|
|||
LocationManager.GPS_PROVIDER };
|
||||
@NonNull
|
||||
private final LocationManager mLocationManager;
|
||||
private boolean mIsActive;
|
||||
@NonNull
|
||||
private final List<LocationListener> mListeners = new ArrayList<>();
|
||||
|
||||
|
@ -32,22 +31,27 @@ class AndroidNativeProvider extends BaseLocationProvider
|
|||
}
|
||||
|
||||
@Override
|
||||
protected boolean start()
|
||||
protected void start()
|
||||
{
|
||||
sLogger.d(TAG, "Android native provider is started");
|
||||
if (mIsActive)
|
||||
return true;
|
||||
LOGGER.d(TAG, "Android native provider is started");
|
||||
if (isActive())
|
||||
return;
|
||||
|
||||
List<String> providers = getAvailableProviders(mLocationManager);
|
||||
if (providers.isEmpty())
|
||||
return false;
|
||||
{
|
||||
setActive(false);
|
||||
return;
|
||||
}
|
||||
|
||||
mIsActive = true;
|
||||
setActive(true);
|
||||
for (String provider : providers)
|
||||
{
|
||||
sLogger.d(TAG, "Request location updates from the provider: " + provider);
|
||||
LocationListener listener = new BaseLocationListener(getLocationFixChecker());
|
||||
mLocationManager.requestLocationUpdates(provider, LocationHelper.INSTANCE.getInterval(), 0, listener);
|
||||
long interval = LocationHelper.INSTANCE.getInterval();
|
||||
LOGGER.d(TAG, "Request Android native provider '" + provider
|
||||
+ "' to get locations at this interval = " + interval + " ms");
|
||||
mLocationManager.requestLocationUpdates(provider, interval, 0, listener);
|
||||
mListeners.add(listener);
|
||||
}
|
||||
|
||||
|
@ -61,14 +65,12 @@ class AndroidNativeProvider extends BaseLocationProvider
|
|||
if (location == null || LocationUtils.isExpired(location, LocationHelper.INSTANCE.getSavedLocationTime(),
|
||||
LocationUtils.LOCATION_EXPIRATION_TIME_MILLIS_SHORT))
|
||||
{
|
||||
return true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (location != null)
|
||||
onLocationChanged(location);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void onLocationChanged(@NonNull Location location)
|
||||
|
@ -85,14 +87,14 @@ class AndroidNativeProvider extends BaseLocationProvider
|
|||
@Override
|
||||
protected void stop()
|
||||
{
|
||||
sLogger.d(TAG, "Android native provider is stopped");
|
||||
LOGGER.d(TAG, "Android native provider is stopped");
|
||||
ListIterator<LocationListener> iterator = mListeners.listIterator();
|
||||
// noinspection WhileLoopReplaceableByForEach
|
||||
while (iterator.hasNext())
|
||||
mLocationManager.removeUpdates(iterator.next());
|
||||
|
||||
mListeners.clear();
|
||||
mIsActive = false;
|
||||
setActive(false);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
|
|
@ -7,10 +7,11 @@ import com.mapswithme.util.log.LoggerFactory;
|
|||
|
||||
abstract class BaseLocationProvider
|
||||
{
|
||||
static final Logger sLogger = LoggerFactory.INSTANCE.getLogger(LoggerFactory.Type.LOCATION);
|
||||
static final Logger LOGGER = LoggerFactory.INSTANCE.getLogger(LoggerFactory.Type.LOCATION);
|
||||
private static final String TAG = BaseLocationProvider.class.getSimpleName();
|
||||
@NonNull
|
||||
private final LocationFixChecker mLocationFixChecker;
|
||||
|
||||
private boolean mActive;
|
||||
@NonNull
|
||||
LocationFixChecker getLocationFixChecker()
|
||||
{
|
||||
|
@ -22,9 +23,21 @@ abstract class BaseLocationProvider
|
|||
mLocationFixChecker = locationFixChecker;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return whether location polling was started successfully.
|
||||
*/
|
||||
protected abstract boolean start();
|
||||
protected abstract void start();
|
||||
protected abstract void stop();
|
||||
|
||||
/**
|
||||
* Indicates whether this provider is providing location updates or not
|
||||
* @return true - if locations are actively coming from this provider, false - otherwise
|
||||
*/
|
||||
public final boolean isActive()
|
||||
{
|
||||
return mActive;
|
||||
}
|
||||
|
||||
final void setActive(boolean active)
|
||||
{
|
||||
LOGGER.d(TAG, "setActive active = " + active);
|
||||
mActive = active;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,6 +11,8 @@ public class GPSCheck extends BroadcastReceiver
|
|||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
if (MwmApplication.get().isFrameworkInitialized() && MwmApplication.backgroundTracker().isForeground())
|
||||
LocationHelper.INSTANCE.checkProvidersAndStartIfNeeded();
|
||||
{
|
||||
LocationHelper.INSTANCE.restart();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,33 +39,31 @@ class GoogleFusedLocationProvider extends BaseLocationProvider
|
|||
}
|
||||
|
||||
@Override
|
||||
protected boolean start()
|
||||
protected void start()
|
||||
{
|
||||
sLogger.d(TAG, "Google fused provider is started");
|
||||
LOGGER.d(TAG, "Google fused provider is started");
|
||||
if (mGoogleApiClient.isConnected() || mGoogleApiClient.isConnecting())
|
||||
return true;
|
||||
{
|
||||
setActive(true);
|
||||
return;
|
||||
}
|
||||
|
||||
mLocationRequest = LocationRequest.create();
|
||||
// mLocationRequest.setPriority(LocationHelper.INSTANCE.isHighAccuracy() ? LocationRequest.PRIORITY_HIGH_ACCURACY
|
||||
// : LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
|
||||
// TODO @yunikkk
|
||||
// Currently there are some problems concerning location strategies switching.
|
||||
// With LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY priority GPS is not used and location icon isn't shown in system navbar,
|
||||
// hence it confuses user.
|
||||
// We should reconsider if balanced mode is needed at all after results of tests for battery usage will arrive.
|
||||
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
|
||||
long interval = LocationHelper.INSTANCE.getInterval();
|
||||
mLocationRequest.setInterval(interval);
|
||||
LOGGER.d(TAG, "Request Google fused provider to provide locations at this interval = "
|
||||
+ interval + " ms");
|
||||
mLocationRequest.setFastestInterval(interval / 2);
|
||||
|
||||
mGoogleApiClient.connect();
|
||||
return true;
|
||||
setActive(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void stop()
|
||||
{
|
||||
sLogger.d(TAG, "Google fused provider is stopped");
|
||||
LOGGER.d(TAG, "Google fused provider is stopped");
|
||||
if (mGoogleApiClient.isConnected())
|
||||
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, mListener);
|
||||
|
||||
|
@ -73,18 +71,19 @@ class GoogleFusedLocationProvider extends BaseLocationProvider
|
|||
mLocationSettingsResult.cancel();
|
||||
|
||||
mGoogleApiClient.disconnect();
|
||||
setActive(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConnected(Bundle bundle)
|
||||
{
|
||||
sLogger.d(TAG, "Fused onConnected. Bundle " + bundle);
|
||||
LOGGER.d(TAG, "Fused onConnected. Bundle " + bundle);
|
||||
checkSettingsAndRequestUpdates();
|
||||
}
|
||||
|
||||
private void checkSettingsAndRequestUpdates()
|
||||
{
|
||||
sLogger.d(TAG, "checkSettingsAndRequestUpdates()");
|
||||
LOGGER.d(TAG, "checkSettingsAndRequestUpdates()");
|
||||
LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder().addLocationRequest(mLocationRequest);
|
||||
builder.setAlwaysShow(true); // hides 'never' button in resolve dialog afterwards.
|
||||
mLocationSettingsResult = LocationServices.SettingsApi.checkLocationSettings(mGoogleApiClient, builder.build());
|
||||
|
@ -94,19 +93,21 @@ class GoogleFusedLocationProvider extends BaseLocationProvider
|
|||
public void onResult(@NonNull LocationSettingsResult locationSettingsResult)
|
||||
{
|
||||
final Status status = locationSettingsResult.getStatus();
|
||||
sLogger.d(TAG, "onResult status: " + status);
|
||||
LOGGER.d(TAG, "onResult status: " + status);
|
||||
switch (status.getStatusCode())
|
||||
{
|
||||
case LocationSettingsStatusCodes.SUCCESS:
|
||||
break;
|
||||
|
||||
case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
|
||||
setActive(false);
|
||||
// Location settings are not satisfied. AndroidNativeProvider should be used.
|
||||
resolveError(status);
|
||||
resolveResolutionRequired();
|
||||
return;
|
||||
|
||||
case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
|
||||
// Location settings are not satisfied. However, we have no way to fix the settings so we won't show the dialog.
|
||||
setActive(false);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -115,13 +116,11 @@ class GoogleFusedLocationProvider extends BaseLocationProvider
|
|||
});
|
||||
}
|
||||
|
||||
private static void resolveError(Status status)
|
||||
private static void resolveResolutionRequired()
|
||||
{
|
||||
sLogger.d(TAG, "resolveError()");
|
||||
if (LocationHelper.INSTANCE.isLocationStopped())
|
||||
return;
|
||||
|
||||
LocationHelper.INSTANCE.initProvider(true /* forceNative */);
|
||||
LOGGER.d(TAG, "resolveResolutionRequired()");
|
||||
LocationHelper.INSTANCE.initNativeProvider();
|
||||
LocationHelper.INSTANCE.start();
|
||||
}
|
||||
|
||||
private void requestLocationUpdates()
|
||||
|
@ -139,14 +138,17 @@ class GoogleFusedLocationProvider extends BaseLocationProvider
|
|||
@Override
|
||||
public void onConnectionSuspended(int i)
|
||||
{
|
||||
sLogger.d(TAG, "Fused onConnectionSuspended. Code " + i);
|
||||
setActive(false);
|
||||
LOGGER.d(TAG, "Fused onConnectionSuspended. Code " + i);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConnectionFailed(@NonNull ConnectionResult connectionResult)
|
||||
{
|
||||
sLogger.d(TAG, "Fused onConnectionFailed. Fall back to native provider. ConnResult " + connectionResult);
|
||||
setActive(false);
|
||||
LOGGER.d(TAG, "Fused onConnectionFailed. Fall back to native provider. ConnResult " + connectionResult);
|
||||
// TODO handle error in a smarter way
|
||||
LocationHelper.INSTANCE.initProvider(true);
|
||||
LocationHelper.INSTANCE.initNativeProvider();
|
||||
LocationHelper.INSTANCE.start();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,13 +1,10 @@
|
|||
package com.mapswithme.maps.location;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.location.Location;
|
||||
import android.location.LocationManager;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.annotation.UiThread;
|
||||
|
||||
import com.google.android.gms.common.ConnectionResult;
|
||||
import com.google.android.gms.common.GoogleApiAvailability;
|
||||
|
@ -20,12 +17,9 @@ import com.mapswithme.util.Config;
|
|||
import com.mapswithme.util.Listeners;
|
||||
import com.mapswithme.util.LocationUtils;
|
||||
import com.mapswithme.util.Utils;
|
||||
import com.mapswithme.util.concurrency.UiThread;
|
||||
import com.mapswithme.util.log.Logger;
|
||||
import com.mapswithme.util.log.LoggerFactory;
|
||||
|
||||
import static com.mapswithme.maps.background.AppBackgroundTracker.OnTransitionListener;
|
||||
|
||||
public enum LocationHelper
|
||||
{
|
||||
INSTANCE;
|
||||
|
@ -46,49 +40,11 @@ public enum LocationHelper
|
|||
private static final long INTERVAL_NAVIGATION_BICYCLE_MS = 1000;
|
||||
private static final long INTERVAL_NAVIGATION_PEDESTRIAN_MS = 1000;
|
||||
|
||||
private static final long STOP_DELAY_MS = 5000;
|
||||
|
||||
private boolean mErrorOccurred;
|
||||
|
||||
public interface UiCallback
|
||||
{
|
||||
Activity getActivity();
|
||||
void onMyPositionModeChanged(int newMode);
|
||||
void onLocationUpdated(@NonNull Location location);
|
||||
void onCompassUpdated(@NonNull CompassData compass);
|
||||
void onLocationError();
|
||||
void onLocationNotFound();
|
||||
}
|
||||
|
||||
private final OnTransitionListener mOnTransition = new OnTransitionListener()
|
||||
{
|
||||
private final GPSCheck mReceiver = new GPSCheck();
|
||||
private boolean mReceiverRegistered;
|
||||
|
||||
@Override
|
||||
public void onTransit(boolean foreground)
|
||||
{
|
||||
if (foreground && !mReceiverRegistered)
|
||||
{
|
||||
final IntentFilter filter = new IntentFilter();
|
||||
filter.addAction(LocationManager.PROVIDERS_CHANGED_ACTION);
|
||||
filter.addCategory(Intent.CATEGORY_DEFAULT);
|
||||
|
||||
MwmApplication.get().registerReceiver(mReceiver, filter);
|
||||
mReceiverRegistered = true;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!foreground && mReceiverRegistered)
|
||||
{
|
||||
MwmApplication.get().unregisterReceiver(mReceiver);
|
||||
mReceiverRegistered = false;
|
||||
}
|
||||
}
|
||||
};
|
||||
@NonNull
|
||||
private final TransitionListener mOnTransition = new TransitionListener();
|
||||
|
||||
@NonNull
|
||||
private final LocationListener mLocationListener = new LocationListener()
|
||||
private final LocationListener mCoreLocationListener = new LocationListener()
|
||||
{
|
||||
@Override
|
||||
public void onLocationUpdated(Location location)
|
||||
|
@ -123,13 +79,11 @@ public enum LocationHelper
|
|||
@Override
|
||||
public void onLocationError(int errorCode)
|
||||
{
|
||||
mErrorOccurred = true;
|
||||
mLogger.d(TAG, "onLocationError errorCode = " + errorCode);
|
||||
mLogger.d(TAG, "onLocationError errorCode = " + errorCode, new Throwable());
|
||||
|
||||
nativeOnLocationError(errorCode);
|
||||
mLogger.d(TAG, "nativeOnLocationError errorCode = " + errorCode +
|
||||
", current state = " + LocationState.nameOf(LocationState.getMode()));
|
||||
stop();
|
||||
", current state = " + LocationState.nameOf(getMyPositionMode()));
|
||||
|
||||
if (mUiCallback == null)
|
||||
return;
|
||||
|
@ -140,7 +94,7 @@ public enum LocationHelper
|
|||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return "LocationHelper.mLocationListener";
|
||||
return "LocationHelper.mCoreLocationListener";
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -148,128 +102,91 @@ public enum LocationHelper
|
|||
private final Logger mLogger = LoggerFactory.INSTANCE.getLogger(LoggerFactory.Type.LOCATION);
|
||||
@NonNull
|
||||
private final Listeners<LocationListener> mListeners = new Listeners<>();
|
||||
|
||||
private boolean mActive;
|
||||
private boolean mLocationStopped;
|
||||
private boolean mColdStart = true;
|
||||
|
||||
private Location mSavedLocation;
|
||||
private MapObject mMyPosition;
|
||||
private long mSavedLocationTime;
|
||||
@NonNull
|
||||
private final SensorHelper mSensorHelper = new SensorHelper();
|
||||
@Nullable
|
||||
private BaseLocationProvider mLocationProvider;
|
||||
@NonNull
|
||||
private final LocationPredictor mPredictor = new LocationPredictor(mLocationListener);
|
||||
private final LocationPredictor mPredictor = new LocationPredictor(mCoreLocationListener);
|
||||
@Nullable
|
||||
private UiCallback mUiCallback;
|
||||
|
||||
private long mInterval;
|
||||
private boolean mHighAccuracy;
|
||||
private CompassData mCompassData;
|
||||
private boolean mInFirstRun;
|
||||
|
||||
@SuppressWarnings("FieldCanBeLocal")
|
||||
private final LocationState.ModeChangeListener mModeChangeListener = new LocationState.ModeChangeListener()
|
||||
private final LocationState.ModeChangeListener mMyPositionModeListener =
|
||||
new LocationState.ModeChangeListener()
|
||||
{
|
||||
@Override
|
||||
public void onMyPositionModeChanged(int newMode)
|
||||
{
|
||||
notifyMyPositionModeChanged(newMode);
|
||||
mLogger.d(TAG, "onMyPositionModeChanged mode = " + LocationState.nameOf(newMode) +
|
||||
" mColdStart = " + mColdStart + " mErrorOccurred = " + mErrorOccurred);
|
||||
switch (newMode)
|
||||
mLogger.d(TAG, "onMyPositionModeChanged mode = " + LocationState.nameOf(newMode));
|
||||
|
||||
if (mUiCallback == null)
|
||||
{
|
||||
case LocationState.PENDING_POSITION:
|
||||
addListener(mLocationListener, true);
|
||||
break;
|
||||
|
||||
case LocationState.NOT_FOLLOW_NO_POSITION:
|
||||
if (mColdStart && !mErrorOccurred)
|
||||
{
|
||||
LocationState.nativeSwitchToNextMode();
|
||||
break;
|
||||
}
|
||||
|
||||
removeListener(mLocationListener);
|
||||
|
||||
if (mLocationStopped)
|
||||
break;
|
||||
|
||||
if (LocationUtils.areLocationServicesTurnedOn())
|
||||
{
|
||||
mLocationStopped = true;
|
||||
notifyLocationNotFound();
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
mLocationStopped = false;
|
||||
restart();
|
||||
break;
|
||||
mLogger.d(TAG, "UI is not ready to listen my position changes, i.e. it's not attached yet.");
|
||||
return;
|
||||
}
|
||||
|
||||
mColdStart = false;
|
||||
mErrorOccurred = false;
|
||||
switch (newMode)
|
||||
{
|
||||
case LocationState.NOT_FOLLOW_NO_POSITION:
|
||||
// In the first run mode, the NOT_FOLLOW_NO_POSITION state doesn't mean that location
|
||||
// is actually not found.
|
||||
if (mInFirstRun)
|
||||
{
|
||||
mLogger.i(TAG, "It's the first run, so this state should be skipped");
|
||||
return;
|
||||
}
|
||||
|
||||
stop();
|
||||
if (LocationUtils.areLocationServicesTurnedOn())
|
||||
notifyLocationNotFound();
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private final Runnable mStopLocationTask = new Runnable()
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
mLogger.d(TAG, "mStopLocationTask.run(). Was active: " + mActive);
|
||||
|
||||
if (mActive)
|
||||
stopInternal();
|
||||
}
|
||||
};
|
||||
|
||||
LocationHelper()
|
||||
{
|
||||
mLogger.d(LocationHelper.class.getSimpleName(), "ctor()");
|
||||
}
|
||||
|
||||
// TODO consider refactoring.
|
||||
// Actually we shouldn't initialize Framework here,
|
||||
// to allow app components to retrieve location updates without all heavy framework's stuff initialized.
|
||||
// For now this is necessary to connect mModeChangeListener below.
|
||||
MwmApplication.get().initNativeCore();
|
||||
LocationState.nativeSetListener(mModeChangeListener);
|
||||
|
||||
calcParams();
|
||||
initProvider(false);
|
||||
@UiThread
|
||||
public void initialize()
|
||||
{
|
||||
initProvider();
|
||||
LocationState.nativeSetListener(mMyPositionModeListener);
|
||||
MwmApplication.backgroundTracker().addListener(mOnTransition);
|
||||
}
|
||||
|
||||
public void initProvider(boolean forceNative)
|
||||
private void initProvider()
|
||||
{
|
||||
mLogger.d(TAG, "initProvider forceNative = " + forceNative, new Throwable());
|
||||
mActive = !mListeners.isEmpty();
|
||||
if (mActive)
|
||||
{
|
||||
mLogger.d(TAG, "Stop the active provider '" + mLocationProvider + "' before starting the new one");
|
||||
stopInternal();
|
||||
}
|
||||
|
||||
mLogger.d(TAG, "initProvider", new Throwable());
|
||||
final MwmApplication application = MwmApplication.get();
|
||||
final boolean containsGoogleServices = GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(application) == ConnectionResult.SUCCESS;
|
||||
final boolean googleServicesTurnedInSettings = Config.useGoogleServices();
|
||||
if (!forceNative &&
|
||||
containsGoogleServices &&
|
||||
googleServicesTurnedInSettings)
|
||||
if (containsGoogleServices && googleServicesTurnedInSettings)
|
||||
{
|
||||
mLogger.d(TAG, "Use fused provider.");
|
||||
mLocationProvider = new GoogleFusedLocationProvider(new FusedLocationFixChecker());
|
||||
}
|
||||
else
|
||||
{
|
||||
mLogger.d(TAG, "Use native provider.");
|
||||
mLocationProvider = new AndroidNativeProvider(new DefaultLocationFixChecker());
|
||||
initNativeProvider();
|
||||
}
|
||||
}
|
||||
|
||||
mActive = !mListeners.isEmpty();
|
||||
if (mActive)
|
||||
startInternal();
|
||||
void initNativeProvider()
|
||||
{
|
||||
mLogger.d(TAG, "Use native provider");
|
||||
mLocationProvider = new AndroidNativeProvider(new DefaultLocationFixChecker());
|
||||
}
|
||||
|
||||
public void onLocationUpdated(@NonNull Location location)
|
||||
|
@ -313,12 +230,7 @@ public enum LocationHelper
|
|||
|
||||
public void switchToNextMode()
|
||||
{
|
||||
if (mErrorOccurred)
|
||||
{
|
||||
mLogger.d(TAG, "Location services are still not available, no need to switch to the next mode.");
|
||||
notifyLocationError(ERROR_DENIED);
|
||||
return;
|
||||
}
|
||||
mLogger.d(TAG, "switchToNextMode()");
|
||||
LocationState.nativeSwitchToNextMode();
|
||||
}
|
||||
|
||||
|
@ -345,6 +257,15 @@ public enum LocationHelper
|
|||
return;
|
||||
}
|
||||
|
||||
// If we are still in the first run mode, i.e. user stays on the first run screens,
|
||||
// not on the map, we mustn't post location update to the core. Only this preserving allows us
|
||||
// to play nice zoom animation once a user will see map.
|
||||
if (mInFirstRun)
|
||||
{
|
||||
mLogger.d(TAG, "Location update is obtained, but ignore, because it's a first run mode");
|
||||
return;
|
||||
}
|
||||
|
||||
for (LocationListener listener : mListeners)
|
||||
listener.onLocationUpdated(mSavedLocation);
|
||||
mListeners.finishIterate();
|
||||
|
@ -385,7 +306,7 @@ public enum LocationHelper
|
|||
|
||||
private void notifyMyPositionModeChanged(int newMode)
|
||||
{
|
||||
mLogger.d(TAG, "notifyMyPositionModeChanged(): " + LocationState.nameOf(newMode));
|
||||
mLogger.d(TAG, "notifyMyPositionModeChanged(): " + LocationState.nameOf(newMode) , new Throwable());
|
||||
|
||||
if (mUiCallback != null)
|
||||
mUiCallback.onMyPositionModeChanged(newMode);
|
||||
|
@ -400,105 +321,33 @@ public enum LocationHelper
|
|||
mUiCallback.onLocationNotFound();
|
||||
}
|
||||
|
||||
boolean isLocationStopped()
|
||||
{
|
||||
return mLocationStopped;
|
||||
}
|
||||
|
||||
public void stop()
|
||||
{
|
||||
mLogger.d(TAG, "stop()");
|
||||
mLocationStopped = true;
|
||||
removeListener(mLocationListener, false);
|
||||
}
|
||||
|
||||
void checkProvidersAndStartIfNeeded()
|
||||
{
|
||||
Context context = MwmApplication.get();
|
||||
LocationManager locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
|
||||
boolean networkEnabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
|
||||
boolean gpsEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
|
||||
mLocationStopped = !networkEnabled && !gpsEnabled;
|
||||
LocationUtils.logAvailableProviders();
|
||||
|
||||
if (mLocationStopped)
|
||||
{
|
||||
if (LocationState.getMode() == LocationState.PENDING_POSITION)
|
||||
notifyLocationError(ERROR_DENIED);
|
||||
return;
|
||||
}
|
||||
|
||||
initProvider(false);
|
||||
mLogger.i(TAG, "checkProvidersAndStartIfNeeded, current mode '" + LocationState.nameOf(LocationState.getMode()) + "'");
|
||||
LocationState.nativeSwitchToNextMode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers listener about location changes. Starts polling on the first listener registration.
|
||||
* Registers listener about location changes.
|
||||
* @param listener listener to register.
|
||||
* @param forceUpdate instantly notify given listener about available location, if any.
|
||||
*/
|
||||
@android.support.annotation.UiThread
|
||||
public void addListener(LocationListener listener, boolean forceUpdate)
|
||||
@UiThread
|
||||
public void addListener(@NonNull LocationListener listener, boolean forceUpdate)
|
||||
{
|
||||
mLogger.d(TAG, "addListener(): " + listener + ", forceUpdate: " + forceUpdate);
|
||||
mLogger.d(TAG, " - listener count was: " + mListeners.getSize());
|
||||
|
||||
UiThread.cancelDelayedTasks(mStopLocationTask);
|
||||
|
||||
boolean wasEmpty = mListeners.isEmpty();
|
||||
mListeners.register(listener);
|
||||
|
||||
if (wasEmpty)
|
||||
{
|
||||
calcParams();
|
||||
startInternal();
|
||||
}
|
||||
|
||||
if (mActive && forceUpdate)
|
||||
if (forceUpdate)
|
||||
notifyLocationUpdated(listener);
|
||||
}
|
||||
|
||||
@android.support.annotation.UiThread
|
||||
private void removeListener(LocationListener listener, boolean delayed)
|
||||
{
|
||||
mLogger.d(TAG, "removeListener(), delayed: " + delayed + ", listener: " + listener);
|
||||
mLogger.d(TAG, " - listener count was: " + mListeners.getSize());
|
||||
|
||||
boolean wasEmpty = mListeners.isEmpty();
|
||||
mListeners.unregister(listener);
|
||||
|
||||
if (!wasEmpty && mListeners.isEmpty())
|
||||
{
|
||||
mLogger.d(TAG, " - was not empty");
|
||||
|
||||
if (delayed)
|
||||
{
|
||||
mLogger.d(TAG, " - schedule stop");
|
||||
stopDelayed();
|
||||
}
|
||||
else
|
||||
{
|
||||
mLogger.d(TAG, " - stop now");
|
||||
stopInternal();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@UiThread
|
||||
/**
|
||||
* Removes given location listener. Stops polling if there are no listeners left.
|
||||
* Removes given location listener.
|
||||
* @param listener listener to unregister.
|
||||
*/
|
||||
@android.support.annotation.UiThread
|
||||
public void removeListener(LocationListener listener)
|
||||
public void removeListener(@NonNull LocationListener listener)
|
||||
{
|
||||
removeListener(listener, false);
|
||||
}
|
||||
|
||||
@android.support.annotation.UiThread
|
||||
public void removeListener()
|
||||
{
|
||||
removeListener(mLocationListener);
|
||||
mLogger.d(TAG, "removeListener(), listener: " + listener);
|
||||
mLogger.d(TAG, " - listener count was: " + mListeners.getSize());
|
||||
mListeners.unregister(listener);
|
||||
}
|
||||
|
||||
void startSensors()
|
||||
|
@ -511,11 +360,12 @@ public enum LocationHelper
|
|||
mSensorHelper.resetMagneticField(mSavedLocation, location);
|
||||
}
|
||||
|
||||
private void calcParams()
|
||||
private void calcLocationUpdatesInterval()
|
||||
{
|
||||
mHighAccuracy = true;
|
||||
mLogger.d(TAG, "calcLocationUpdatesInterval()");
|
||||
if (RoutingController.get().isNavigating())
|
||||
{
|
||||
mLogger.d(TAG, "calcLocationUpdatesInterval(), it's navigation mode");
|
||||
final @Framework.RouterType int router = Framework.nativeGetRouter();
|
||||
switch (router)
|
||||
{
|
||||
|
@ -538,22 +388,20 @@ public enum LocationHelper
|
|||
return;
|
||||
}
|
||||
|
||||
int mode = LocationState.getMode();
|
||||
int mode = getMyPositionMode();
|
||||
switch (mode)
|
||||
{
|
||||
default:
|
||||
case LocationState.NOT_FOLLOW:
|
||||
mHighAccuracy = false;
|
||||
mInterval = INTERVAL_NOT_FOLLOW_MS;
|
||||
break;
|
||||
case LocationState.FOLLOW:
|
||||
mInterval = INTERVAL_FOLLOW_MS;
|
||||
break;
|
||||
|
||||
case LocationState.FOLLOW:
|
||||
mInterval = INTERVAL_FOLLOW_MS;
|
||||
break;
|
||||
case LocationState.FOLLOW_AND_ROTATE:
|
||||
mInterval = INTERVAL_FOLLOW_AND_ROTATE_MS;
|
||||
break;
|
||||
|
||||
case LocationState.FOLLOW_AND_ROTATE:
|
||||
mInterval = INTERVAL_FOLLOW_AND_ROTATE_MS;
|
||||
break;
|
||||
default:
|
||||
mInterval = INTERVAL_NOT_FOLLOW_MS;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -562,41 +410,71 @@ public enum LocationHelper
|
|||
return mInterval;
|
||||
}
|
||||
|
||||
// TODO (trashkalmar): Usage of this method was temporarily commented out from GoogleFusedLocationProvider.start(). See comments there.
|
||||
boolean isHighAccuracy()
|
||||
{
|
||||
return mHighAccuracy;
|
||||
}
|
||||
|
||||
/**
|
||||
* Recalculates location parameters and restarts locator if it was in a progress before.
|
||||
* <p>Does nothing if there were no subscribers.
|
||||
* Stops the current provider. Then initialize the location provider again,
|
||||
* because location settings could be changed and a new location provider can be used,
|
||||
* such as Google fused provider. And we think that Google fused provider is preferable
|
||||
* for the most cases. And starts the initialized location provider.
|
||||
*
|
||||
* @see #start()
|
||||
*
|
||||
*/
|
||||
public void restart()
|
||||
{
|
||||
mLogger.d(TAG, "restart()");
|
||||
mActive &= !mListeners.isEmpty();
|
||||
if (!mActive)
|
||||
checkProviderInitialization();
|
||||
stopInternal();
|
||||
initProvider();
|
||||
start();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the {@link #mCoreLocationListener} to listen location updates and notify UI.
|
||||
* Notifies about {@link #ERROR_DENIED} if there are no enabled location providers.
|
||||
* Calculates minimum time interval for location updates.
|
||||
* Starts polling location updates.
|
||||
*/
|
||||
public void start()
|
||||
{
|
||||
checkProviderInitialization();
|
||||
//noinspection ConstantConditions
|
||||
if (mLocationProvider.isActive())
|
||||
throw new AssertionError("Location provider '" + mLocationProvider + "' must be stopped first");
|
||||
|
||||
addListener(mCoreLocationListener, true);
|
||||
|
||||
if (!LocationUtils.checkProvidersAvailability())
|
||||
{
|
||||
stopInternal();
|
||||
// No need to notify about an error in first run mode
|
||||
if (!mInFirstRun)
|
||||
notifyLocationError(ERROR_DENIED);
|
||||
return;
|
||||
}
|
||||
|
||||
boolean oldHighAccuracy = mHighAccuracy;
|
||||
long oldInterval = mInterval;
|
||||
mLogger.d(TAG, "restart. Old params: " + oldInterval + " / " + (oldHighAccuracy ? "high" : "normal"));
|
||||
mLogger.d(TAG, "Old time interval (ms): " + oldInterval);
|
||||
calcLocationUpdatesInterval();
|
||||
mLogger.d(TAG, "start(), params: " + mInterval);
|
||||
startInternal();
|
||||
}
|
||||
|
||||
calcParams();
|
||||
mLogger.d(TAG, "New params: " + mInterval + " / " + (mHighAccuracy ? "high" : "normal"));
|
||||
|
||||
if (mHighAccuracy != oldHighAccuracy || mInterval != oldInterval)
|
||||
/**
|
||||
* Stops the polling location updates, i.e. removes the {@link #mCoreLocationListener} and stops
|
||||
* the current active provider.
|
||||
*/
|
||||
private void stop()
|
||||
{
|
||||
mLogger.d(TAG, "stop()");
|
||||
checkProviderInitialization();
|
||||
//noinspection ConstantConditions
|
||||
if (!mLocationProvider.isActive())
|
||||
{
|
||||
boolean active = mActive;
|
||||
stopInternal();
|
||||
|
||||
if (active)
|
||||
startInternal();
|
||||
mLogger.i(TAG, "Provider '" + mLocationProvider + "' is already stopped");
|
||||
return;
|
||||
}
|
||||
|
||||
removeListener(mCoreLocationListener);
|
||||
stopInternal();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -604,18 +482,30 @@ public enum LocationHelper
|
|||
*/
|
||||
private void startInternal()
|
||||
{
|
||||
mLogger.d(TAG, "startInternal(), current provider is '" + mLocationProvider + "'");
|
||||
mLogger.d(TAG, "startInternal(), current provider is '" + mLocationProvider
|
||||
+ "' , my position mode = " + LocationState.nameOf(getMyPositionMode())
|
||||
+ ", mInFirstRun = " + mInFirstRun);
|
||||
checkProviderInitialization();
|
||||
//noinspection ConstantConditions
|
||||
mLocationProvider.start();
|
||||
mLogger.d(TAG, mLocationProvider.isActive() ? "SUCCESS" : "FAILURE");
|
||||
|
||||
mActive = mLocationProvider.start();
|
||||
mLogger.d(TAG, mActive ? "SUCCESS" : "FAILURE");
|
||||
|
||||
if (mActive)
|
||||
if (mLocationProvider.isActive())
|
||||
{
|
||||
mErrorOccurred = false;
|
||||
if (!mInFirstRun && getMyPositionMode() == LocationState.NOT_FOLLOW_NO_POSITION)
|
||||
switchToNextMode();
|
||||
mPredictor.resume();
|
||||
}
|
||||
else
|
||||
notifyLocationError(LocationHelper.ERROR_DENIED);
|
||||
}
|
||||
|
||||
private void checkProviderInitialization()
|
||||
{
|
||||
if (mLocationProvider == null)
|
||||
{
|
||||
String error = "A location provider must be initialized!";
|
||||
mLogger.e(TAG, error, new Throwable());
|
||||
throw new AssertionError(error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -624,29 +514,20 @@ public enum LocationHelper
|
|||
private void stopInternal()
|
||||
{
|
||||
mLogger.d(TAG, "stopInternal()");
|
||||
|
||||
mActive = false;
|
||||
checkProviderInitialization();
|
||||
//noinspection ConstantConditions
|
||||
mLocationProvider.stop();
|
||||
mSensorHelper.stop();
|
||||
mPredictor.pause();
|
||||
notifyMyPositionModeChanged(LocationState.getMode());
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedules poll termination after {@link #STOP_DELAY_MS}.
|
||||
*/
|
||||
private void stopDelayed()
|
||||
{
|
||||
mLogger.d(TAG, "stopDelayed()");
|
||||
UiThread.runLater(mStopLocationTask, STOP_DELAY_MS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Attach UI to helper.
|
||||
*/
|
||||
public void attach(UiCallback callback)
|
||||
@UiThread
|
||||
public void attach(@NonNull UiCallback callback)
|
||||
{
|
||||
mLogger.d(TAG, "attach() callback = " + callback + " mColdStart = " + mColdStart);
|
||||
mLogger.d(TAG, "attach() callback = " + callback);
|
||||
|
||||
if (mUiCallback != null)
|
||||
{
|
||||
|
@ -658,20 +539,27 @@ public enum LocationHelper
|
|||
|
||||
Utils.keepScreenOn(true, mUiCallback.getActivity().getWindow());
|
||||
|
||||
mUiCallback.onMyPositionModeChanged(LocationState.getMode());
|
||||
mUiCallback.onMyPositionModeChanged(getMyPositionMode());
|
||||
if (mCompassData != null)
|
||||
mUiCallback.onCompassUpdated(mCompassData);
|
||||
|
||||
if (!mLocationStopped)
|
||||
addListener(mLocationListener, true);
|
||||
checkProviderInitialization();
|
||||
//noinspection ConstantConditions
|
||||
if (mLocationProvider.isActive())
|
||||
{
|
||||
mLogger.d(TAG, "attach() provider '" + mLocationProvider + "' is active, just add the listener");
|
||||
addListener(mCoreLocationListener, true);
|
||||
}
|
||||
else
|
||||
checkProvidersAndStartIfNeeded();
|
||||
|
||||
{
|
||||
restart();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Detach UI from helper.
|
||||
*/
|
||||
@UiThread
|
||||
public void detach(boolean delayed)
|
||||
{
|
||||
mLogger.d(TAG, "detach(), delayed: " + delayed);
|
||||
|
@ -684,7 +572,47 @@ public enum LocationHelper
|
|||
|
||||
Utils.keepScreenOn(false, mUiCallback.getActivity().getWindow());
|
||||
mUiCallback = null;
|
||||
removeListener(mLocationListener, delayed);
|
||||
stop();
|
||||
}
|
||||
|
||||
@UiThread
|
||||
public void onEnteredIntoFirstRun()
|
||||
{
|
||||
mLogger.i(TAG, "onEnteredIntoFirstRun");
|
||||
mInFirstRun = true;
|
||||
}
|
||||
|
||||
@UiThread
|
||||
public void onExitFromFirstRun()
|
||||
{
|
||||
mLogger.i(TAG, "onExitFromFirstRun");
|
||||
if (!mInFirstRun)
|
||||
throw new AssertionError("Must be called only after 'onEnteredIntoFirstRun' method!");
|
||||
|
||||
mInFirstRun = false;
|
||||
|
||||
if (getMyPositionMode() != LocationState.NOT_FOLLOW_NO_POSITION)
|
||||
throw new AssertionError("My position mode must be equal NOT_FOLLOW_NO_POSITION");
|
||||
|
||||
// If there is a location we need just to pass it to the listeners, so that
|
||||
// my position state machine will be switched to the FOLLOW state.
|
||||
Location location = getSavedLocation();
|
||||
if (location != null)
|
||||
{
|
||||
notifyLocationUpdated();
|
||||
mLogger.d(TAG, "Current location is available, so play the nice zoom animation");
|
||||
Framework.nativeZoomToPoint(location.getLatitude(), location.getLongitude(), 14, true);
|
||||
return;
|
||||
}
|
||||
|
||||
checkProviderInitialization();
|
||||
// If the location hasn't been obtained yet we need to switch to the next mode and wait for locations.
|
||||
// Otherwise, try to restart location updates polling.
|
||||
// noinspection ConstantConditions
|
||||
if (mLocationProvider.isActive())
|
||||
switchToNextMode();
|
||||
else
|
||||
restart();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -712,8 +640,24 @@ public enum LocationHelper
|
|||
return mCompassData;
|
||||
}
|
||||
|
||||
@LocationState.Value
|
||||
public int getMyPositionMode()
|
||||
{
|
||||
return LocationState.nativeGetMode();
|
||||
}
|
||||
|
||||
private static native void nativeOnLocationError(int errorCode);
|
||||
private static native void nativeLocationUpdated(long time, double lat, double lon, float accuracy,
|
||||
double altitude, float speed, float bearing);
|
||||
static native float[] nativeUpdateCompassSensor(int ind, float[] arr);
|
||||
|
||||
public interface UiCallback
|
||||
{
|
||||
Activity getActivity();
|
||||
void onMyPositionModeChanged(int newMode);
|
||||
void onLocationUpdated(@NonNull Location location);
|
||||
void onCompassUpdated(@NonNull CompassData compass);
|
||||
void onLocationError();
|
||||
void onLocationNotFound();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,7 +38,7 @@ class LocationPredictor
|
|||
|
||||
void resume()
|
||||
{
|
||||
onMyPositionModeChanged(LocationState.getMode());
|
||||
onMyPositionModeChanged(LocationHelper.INSTANCE.getMyPositionMode());
|
||||
}
|
||||
|
||||
void pause()
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
package com.mapswithme.maps.location;
|
||||
|
||||
import com.mapswithme.maps.MwmApplication;
|
||||
import android.support.annotation.IntDef;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
public final class LocationState
|
||||
{
|
||||
|
@ -10,6 +13,10 @@ public final class LocationState
|
|||
void onMyPositionModeChanged(int newMode);
|
||||
}
|
||||
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@IntDef({ PENDING_POSITION, NOT_FOLLOW_NO_POSITION, NOT_FOLLOW, FOLLOW, FOLLOW_AND_ROTATE})
|
||||
@interface Value {}
|
||||
|
||||
// These values should correspond to location::EMyPositionMode enum (from platform/location.hpp)
|
||||
public static final int PENDING_POSITION = 0;
|
||||
public static final int NOT_FOLLOW_NO_POSITION = 1;
|
||||
|
@ -18,7 +25,8 @@ public final class LocationState
|
|||
public static final int FOLLOW_AND_ROTATE = 4;
|
||||
|
||||
static native void nativeSwitchToNextMode();
|
||||
private static native int nativeGetMode();
|
||||
@Value
|
||||
static native int nativeGetMode();
|
||||
|
||||
static native void nativeSetListener(ModeChangeListener listener);
|
||||
static native void nativeRemoveListener();
|
||||
|
@ -30,7 +38,7 @@ public final class LocationState
|
|||
*/
|
||||
static boolean isTurnedOn()
|
||||
{
|
||||
return hasLocation(getMode());
|
||||
return hasLocation(nativeGetMode());
|
||||
}
|
||||
|
||||
static boolean hasLocation(int mode)
|
||||
|
@ -38,13 +46,7 @@ public final class LocationState
|
|||
return (mode > NOT_FOLLOW_NO_POSITION);
|
||||
}
|
||||
|
||||
public static int getMode()
|
||||
{
|
||||
MwmApplication.get().initNativeCore();
|
||||
return nativeGetMode();
|
||||
}
|
||||
|
||||
static String nameOf(int mode)
|
||||
static String nameOf(@Value int mode)
|
||||
{
|
||||
switch (mode)
|
||||
{
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
package com.mapswithme.maps.location;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.location.LocationManager;
|
||||
import android.support.annotation.NonNull;
|
||||
|
||||
import com.mapswithme.maps.MwmApplication;
|
||||
import com.mapswithme.maps.background.AppBackgroundTracker;
|
||||
|
||||
class TransitionListener implements AppBackgroundTracker.OnTransitionListener
|
||||
{
|
||||
@NonNull
|
||||
private final GPSCheck mReceiver = new GPSCheck();
|
||||
private boolean mReceiverRegistered;
|
||||
|
||||
@Override
|
||||
public void onTransit(boolean foreground)
|
||||
{
|
||||
if (foreground && !mReceiverRegistered)
|
||||
{
|
||||
final IntentFilter filter = new IntentFilter();
|
||||
filter.addAction(LocationManager.PROVIDERS_CHANGED_ACTION);
|
||||
filter.addCategory(Intent.CATEGORY_DEFAULT);
|
||||
|
||||
MwmApplication.get().registerReceiver(mReceiver, filter);
|
||||
mReceiverRegistered = true;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!foreground && mReceiverRegistered)
|
||||
{
|
||||
MwmApplication.get().unregisterReceiver(mReceiver);
|
||||
mReceiverRegistered = false;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -277,7 +277,7 @@ abstract class BaseNewsFragment extends BaseMwmDialogFragment
|
|||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
dismissAllowingStateLoss();
|
||||
onDoneClick();
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -285,6 +285,11 @@ abstract class BaseNewsFragment extends BaseMwmDialogFragment
|
|||
return res;
|
||||
}
|
||||
|
||||
protected void onDoneClick()
|
||||
{
|
||||
dismissAllowingStateLoss();
|
||||
}
|
||||
|
||||
@SuppressWarnings("TryWithIdenticalCatches")
|
||||
static void create(FragmentActivity activity, Class<? extends BaseNewsFragment> clazz)
|
||||
{
|
||||
|
|
|
@ -1,43 +1,18 @@
|
|||
package com.mapswithme.maps.news;
|
||||
|
||||
import android.app.Dialog;
|
||||
import android.content.DialogInterface;
|
||||
import android.location.Location;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v4.app.FragmentActivity;
|
||||
import android.support.v4.app.FragmentManager;
|
||||
|
||||
import com.mapswithme.maps.BuildConfig;
|
||||
import com.mapswithme.maps.Framework;
|
||||
import com.mapswithme.maps.R;
|
||||
import com.mapswithme.maps.location.LocationHelper;
|
||||
import com.mapswithme.maps.location.LocationListener;
|
||||
import com.mapswithme.util.Config;
|
||||
import com.mapswithme.util.statistics.Statistics;
|
||||
|
||||
public class FirstStartFragment extends BaseNewsFragment
|
||||
{
|
||||
private static Location sLocation;
|
||||
private static int sError = LocationHelper.ERROR_UNKNOWN;
|
||||
|
||||
private final LocationListener mLocationListener = new LocationListener.Simple()
|
||||
{
|
||||
@Override
|
||||
public void onLocationUpdated(Location location)
|
||||
{
|
||||
sLocation = location;
|
||||
sError = LocationHelper.ERROR_UNKNOWN;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLocationError(int errorCode)
|
||||
{
|
||||
sLocation = null;
|
||||
sError = errorCode;
|
||||
}
|
||||
};
|
||||
|
||||
private class Adapter extends BaseNewsFragment.Adapter
|
||||
{
|
||||
@Override
|
||||
|
@ -87,37 +62,15 @@ public class FirstStartFragment extends BaseNewsFragment
|
|||
@Override
|
||||
public Dialog onCreateDialog(Bundle savedInstanceState)
|
||||
{
|
||||
LocationHelper.INSTANCE.addListener(mLocationListener, true);
|
||||
LocationHelper.INSTANCE.onEnteredIntoFirstRun();
|
||||
return super.onCreateDialog(savedInstanceState);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDismiss(DialogInterface dialog)
|
||||
protected void onDoneClick()
|
||||
{
|
||||
super.onDismiss(dialog);
|
||||
|
||||
if (sLocation == null)
|
||||
{
|
||||
String reason;
|
||||
switch (sError)
|
||||
{
|
||||
case LocationHelper.ERROR_DENIED:
|
||||
reason = "unavailable";
|
||||
break;
|
||||
|
||||
default:
|
||||
Statistics.INSTANCE.trackEvent(Statistics.EventName.FIRST_START_DONT_ZOOM);
|
||||
return;
|
||||
}
|
||||
|
||||
Statistics.INSTANCE.trackEvent(Statistics.EventName.FIRST_START_NO_LOCATION, Statistics.params().add("reason", reason));
|
||||
return;
|
||||
}
|
||||
|
||||
Framework.nativeZoomToPoint(sLocation.getLatitude(), sLocation.getLongitude(), 14, true);
|
||||
|
||||
sLocation = null;
|
||||
LocationHelper.INSTANCE.removeListener(mLocationListener);
|
||||
super.onDoneClick();
|
||||
LocationHelper.INSTANCE.onExitFromFirstRun();
|
||||
}
|
||||
|
||||
public static boolean showOn(FragmentActivity activity)
|
||||
|
@ -136,8 +89,6 @@ public class FirstStartFragment extends BaseNewsFragment
|
|||
create(activity, FirstStartFragment.class);
|
||||
|
||||
Config.setFirstStartDialogSeen();
|
||||
Statistics.INSTANCE.trackEvent(Statistics.EventName.FIRST_START_SHOWN);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ import android.util.Pair;
|
|||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.mapswithme.maps.location.LocationHelper;
|
||||
import com.mapswithme.maps.location.LocationState;
|
||||
import com.mapswithme.maps.MwmApplication;
|
||||
import com.mapswithme.maps.R;
|
||||
|
@ -34,7 +35,7 @@ class ResultCodesHelper
|
|||
switch (errorCode)
|
||||
{
|
||||
case NO_POSITION:
|
||||
if (LocationState.getMode() == LocationState.NOT_FOLLOW_NO_POSITION)
|
||||
if (LocationHelper.INSTANCE.getMyPositionMode() == LocationState.NOT_FOLLOW_NO_POSITION)
|
||||
{
|
||||
titleRes = R.string.dialog_routing_location_turn_on;
|
||||
messages.add(resources.getString(R.string.dialog_routing_location_unknown_turn_on));
|
||||
|
|
|
@ -61,7 +61,7 @@ public class MiscPrefsFragment extends BaseXmlSettingsFragment
|
|||
if (oldVal != newVal)
|
||||
{
|
||||
Config.setUseGoogleService(newVal);
|
||||
LocationHelper.INSTANCE.initProvider(false /* forceNative */);
|
||||
LocationHelper.INSTANCE.restart();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -119,7 +119,7 @@ public class LocationUtils
|
|||
}
|
||||
}
|
||||
|
||||
public static void logAvailableProviders()
|
||||
private static void logAvailableProviders()
|
||||
{
|
||||
LocationManager locMngr = (LocationManager) MwmApplication.get().getSystemService(Context.LOCATION_SERVICE);
|
||||
List<String> providers = locMngr.getProviders(true);
|
||||
|
@ -134,6 +134,22 @@ public class LocationUtils
|
|||
{
|
||||
sb = new StringBuilder("There are no enabled location providers!");
|
||||
}
|
||||
LOGGER.i(TAG, sb.toString(), new Throwable());
|
||||
LOGGER.i(TAG, sb.toString());
|
||||
}
|
||||
|
||||
public static boolean checkProvidersAvailability()
|
||||
{
|
||||
Context context = MwmApplication.get();
|
||||
LocationManager locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
|
||||
if (locationManager == null)
|
||||
{
|
||||
LOGGER.e(TAG, "This device doesn't support the location service.");
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean networkEnabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
|
||||
boolean gpsEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
|
||||
LocationUtils.logAvailableProviders();
|
||||
return networkEnabled || gpsEnabled;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -47,11 +47,6 @@ public enum Statistics
|
|||
public static final String DOWNLOADER_ACTION = "Downloader_Map_action";
|
||||
public static final String DOWNLOADER_CANCEL = "Downloader_Cancel_downloading";
|
||||
|
||||
// First start
|
||||
public static final String FIRST_START_SHOWN = "FirstStart_Dialog_show";
|
||||
public static final String FIRST_START_NO_LOCATION = "FirstStart_Location_disable";
|
||||
public static final String FIRST_START_DONT_ZOOM = "FirstStart_ZAnimation_disable";
|
||||
|
||||
// bookmarks
|
||||
public static final String BMK_DESCRIPTION_CHANGED = "Bookmark. Description changed";
|
||||
public static final String BMK_GROUP_CREATED = "Bookmark. Group created";
|
||||
|
|
|
@ -16,7 +16,8 @@
|
|||
namespace df
|
||||
{
|
||||
DrapeEngine::DrapeEngine(Params && params)
|
||||
: m_viewport(params.m_viewport)
|
||||
: m_myPositionModeChanged(move(params.m_myPositionModeChanged))
|
||||
, m_viewport(move(params.m_viewport))
|
||||
{
|
||||
VisualParams::Init(params.m_vs, df::CalculateTileSize(m_viewport.GetWidth(), m_viewport.GetHeight()));
|
||||
|
||||
|
@ -321,11 +322,6 @@ void DrapeEngine::SetModelViewListener(TModelViewListenerFn && fn)
|
|||
m_modelViewChanged = move(fn);
|
||||
}
|
||||
|
||||
void DrapeEngine::SetMyPositionModeListener(location::TMyPositionModeChanged && fn)
|
||||
{
|
||||
m_myPositionModeChanged = move(fn);
|
||||
}
|
||||
|
||||
void DrapeEngine::SetTapEventInfoListener(TTapEventInfoFn && fn)
|
||||
{
|
||||
m_tapListener = move(fn);
|
||||
|
|
|
@ -46,6 +46,7 @@ public:
|
|||
double fontsScaleFactor,
|
||||
gui::TWidgetsInitInfo && info,
|
||||
pair<location::EMyPositionMode, bool> const & initialMyPositionMode,
|
||||
location::TMyPositionModeChanged && myPositionModeChanged,
|
||||
bool allow3dBuildings,
|
||||
bool trafficEnabled,
|
||||
bool blockTapEvents,
|
||||
|
@ -62,6 +63,7 @@ public:
|
|||
, m_fontsScaleFactor(fontsScaleFactor)
|
||||
, m_info(move(info))
|
||||
, m_initialMyPositionMode(initialMyPositionMode)
|
||||
, m_myPositionModeChanged(move(myPositionModeChanged))
|
||||
, m_allow3dBuildings(allow3dBuildings)
|
||||
, m_trafficEnabled(trafficEnabled)
|
||||
, m_blockTapEvents(blockTapEvents)
|
||||
|
@ -80,6 +82,7 @@ public:
|
|||
double m_fontsScaleFactor;
|
||||
gui::TWidgetsInitInfo m_info;
|
||||
pair<location::EMyPositionMode, bool> m_initialMyPositionMode;
|
||||
location::TMyPositionModeChanged m_myPositionModeChanged;
|
||||
bool m_allow3dBuildings;
|
||||
bool m_trafficEnabled;
|
||||
bool m_blockTapEvents;
|
||||
|
@ -125,7 +128,6 @@ public:
|
|||
void SwitchMyPositionNextMode();
|
||||
void LoseLocation();
|
||||
void StopLocationFollow();
|
||||
void SetMyPositionModeListener(location::TMyPositionModeChanged && fn);
|
||||
|
||||
using TTapEventInfoFn = FrontendRenderer::TTapEventInfoFn;
|
||||
void SetTapEventInfoListener(TTapEventInfoFn && fn);
|
||||
|
@ -198,11 +200,11 @@ private:
|
|||
drape_ptr<ThreadsCommutator> m_threadCommutator;
|
||||
drape_ptr<dp::TextureManager> m_textureManager;
|
||||
drape_ptr<RequestedTiles> m_requestedTiles;
|
||||
location::TMyPositionModeChanged m_myPositionModeChanged;
|
||||
|
||||
Viewport m_viewport;
|
||||
|
||||
TModelViewListenerFn m_modelViewChanged;
|
||||
location::TMyPositionModeChanged m_myPositionModeChanged;
|
||||
TUserPositionChangedFn m_userPositionChanged;
|
||||
TTapEventInfoFn m_tapListener;
|
||||
|
||||
|
|
|
@ -151,9 +151,7 @@ FrontendRenderer::FrontendRenderer(Params const & params)
|
|||
|
||||
m_myPositionController.reset(new MyPositionController(params.m_initMyPositionMode, params.m_timeInBackground,
|
||||
params.m_firstLaunch, params.m_isRoutingActive,
|
||||
params.m_isAutozoomEnabled));
|
||||
m_myPositionController->SetModeListener(params.m_myPositionModeCallback);
|
||||
|
||||
params.m_isAutozoomEnabled, params.m_myPositionModeCallback));
|
||||
StartThread();
|
||||
}
|
||||
|
||||
|
|
|
@ -124,9 +124,11 @@ double CalculateZoomBySpeed(double speed, bool isPerspectiveAllowed)
|
|||
} // namespace
|
||||
|
||||
MyPositionController::MyPositionController(location::EMyPositionMode initMode, double timeInBackground,
|
||||
bool isFirstLaunch, bool isRoutingActive, bool isAutozoomEnabled)
|
||||
bool isFirstLaunch, bool isRoutingActive, bool isAutozoomEnabled,
|
||||
location::TMyPositionModeChanged const & fn)
|
||||
: m_mode(location::PendingPosition)
|
||||
, m_desiredInitMode(initMode)
|
||||
, m_modeChangeCallback(fn)
|
||||
, m_isFirstLaunch(isFirstLaunch)
|
||||
, m_isInRouting(isRoutingActive)
|
||||
, m_needBlockAnimation(false)
|
||||
|
@ -163,6 +165,9 @@ MyPositionController::MyPositionController(location::EMyPositionMode initMode, d
|
|||
{
|
||||
m_desiredInitMode = location::Follow;
|
||||
}
|
||||
|
||||
if (m_modeChangeCallback != nullptr)
|
||||
m_modeChangeCallback(m_mode, m_isInRouting);
|
||||
}
|
||||
|
||||
MyPositionController::~MyPositionController()
|
||||
|
@ -486,18 +491,6 @@ void MyPositionController::OnCompassUpdate(location::CompassInfo const & info, S
|
|||
}
|
||||
}
|
||||
|
||||
void MyPositionController::SetModeListener(location::TMyPositionModeChanged const & fn)
|
||||
{
|
||||
m_modeChangeCallback = fn;
|
||||
|
||||
location::EMyPositionMode mode = m_mode;
|
||||
if (m_isFirstLaunch)
|
||||
mode = location::NotFollowNoPosition;
|
||||
|
||||
if (m_modeChangeCallback != nullptr)
|
||||
m_modeChangeCallback(mode, m_isInRouting);
|
||||
}
|
||||
|
||||
bool MyPositionController::IsInStateWithPosition() const
|
||||
{
|
||||
return m_mode == location::NotFollow || m_mode == location::Follow ||
|
||||
|
|
|
@ -41,7 +41,8 @@ public:
|
|||
};
|
||||
|
||||
MyPositionController(location::EMyPositionMode initMode, double timeInBackground,
|
||||
bool isFirstLaunch, bool isRoutingActive, bool isAutozoomEnabled);
|
||||
bool isFirstLaunch, bool isRoutingActive, bool isAutozoomEnabled,
|
||||
location::TMyPositionModeChanged const & fn);
|
||||
~MyPositionController();
|
||||
|
||||
void UpdatePosition();
|
||||
|
@ -90,8 +91,6 @@ public:
|
|||
void OnLocationUpdate(location::GpsInfo const & info, bool isNavigable, ScreenBase const & screen);
|
||||
void OnCompassUpdate(location::CompassInfo const & info, ScreenBase const & screen);
|
||||
|
||||
void SetModeListener(location::TMyPositionModeChanged const & fn);
|
||||
|
||||
void Render(ScreenBase const & screen, int zoomLevel, ref_ptr<dp::GpuProgramManager> mng,
|
||||
dp::UniformValuesStorage const & commonUniforms);
|
||||
|
||||
|
@ -133,6 +132,7 @@ private:
|
|||
private:
|
||||
location::EMyPositionMode m_mode;
|
||||
location::EMyPositionMode m_desiredInitMode;
|
||||
location::TMyPositionModeChanged m_modeChangeCallback;
|
||||
bool m_isFirstLaunch;
|
||||
|
||||
bool m_isInRouting;
|
||||
|
@ -140,7 +140,6 @@ private:
|
|||
bool m_needBlockAnimation;
|
||||
bool m_wasRotationInScaling;
|
||||
|
||||
location::TMyPositionModeChanged m_modeChangeCallback;
|
||||
drape_ptr<MyPosition> m_shape;
|
||||
ref_ptr<Listener> m_listener;
|
||||
|
||||
|
|
|
@ -1654,6 +1654,19 @@ void Framework::CreateDrapeEngine(ref_ptr<dp::OGLContextFactory> contextFactory,
|
|||
m_model.ReadFeatures(fn, ids);
|
||||
};
|
||||
|
||||
auto myPositionModeChangedFn = [this](location::EMyPositionMode mode, bool routingActive)
|
||||
{
|
||||
GetPlatform().RunOnGuiThread([this, mode, routingActive]()
|
||||
{
|
||||
// Deactivate selection (and hide place page) if we return to routing in F&R mode.
|
||||
if (routingActive && mode == location::FollowAndRotate)
|
||||
DeactivateMapSelection(true /* notifyUI */);
|
||||
|
||||
if (m_myPositionListener != nullptr)
|
||||
m_myPositionListener(mode, routingActive);
|
||||
});
|
||||
};
|
||||
|
||||
auto isCountryLoadedByNameFn = bind(&Framework::IsCountryLoadedByName, this, _1);
|
||||
auto updateCurrentCountryFn = bind(&Framework::OnUpdateCurrentCountry, this, _1, _2);
|
||||
|
||||
|
@ -1673,7 +1686,7 @@ void Framework::CreateDrapeEngine(ref_ptr<dp::OGLContextFactory> contextFactory,
|
|||
df::MapDataProvider(idReadFn, featureReadFn, isCountryLoadedByNameFn, updateCurrentCountryFn),
|
||||
params.m_visualScale, fontsScaleFactor, move(params.m_widgetsInitInfo),
|
||||
make_pair(params.m_initialMyPositionState, params.m_hasMyPositionState),
|
||||
allow3dBuildings, trafficEnabled, params.m_isChoosePositionMode,
|
||||
move(myPositionModeChangedFn), allow3dBuildings, trafficEnabled, params.m_isChoosePositionMode,
|
||||
params.m_isChoosePositionMode, GetSelectedFeatureTriangles(), params.m_isFirstLaunch,
|
||||
m_routingSession.IsActive() && m_routingSession.IsFollowing(), isAutozoomEnabled);
|
||||
|
||||
|
@ -1694,19 +1707,6 @@ void Framework::CreateDrapeEngine(ref_ptr<dp::OGLContextFactory> contextFactory,
|
|||
|
||||
OnSize(params.m_surfaceWidth, params.m_surfaceHeight);
|
||||
|
||||
m_drapeEngine->SetMyPositionModeListener([this](location::EMyPositionMode mode, bool routingActive)
|
||||
{
|
||||
GetPlatform().RunOnGuiThread([this, mode, routingActive]()
|
||||
{
|
||||
// Deactivate selection (and hide place page) if we return to routing in F&R mode.
|
||||
if (routingActive && mode == location::FollowAndRotate)
|
||||
DeactivateMapSelection(true /* notifyUI */);
|
||||
|
||||
if (m_myPositionListener != nullptr)
|
||||
m_myPositionListener(mode, routingActive);
|
||||
});
|
||||
});
|
||||
|
||||
InvalidateUserMarks();
|
||||
|
||||
Allow3dMode(allow3d, allow3dBuildings);
|
||||
|
|
Loading…
Add table
Reference in a new issue