forked from organicmaps/organicmaps
[android]: Fix random crashes in the background
Follow up a4cbcad
"Initialize core before handle received broadcast"
This patch also removes leftovers of booking synchronization.
Closes #205
Signed-off-by: Roman Tsisyk <roman@tsisyk.com>
This commit is contained in:
parent
6225d51578
commit
48da9c7d63
18 changed files with 129 additions and 534 deletions
|
@ -26,6 +26,15 @@
|
|||
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
|
||||
<uses-permission android:name="android.permission.INTERNET"/>
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
|
||||
<!--
|
||||
https://developer.android.com/reference/androidx/core/app/JobIntentService:
|
||||
When running on Android O, the JobScheduler will take care of wake locks
|
||||
for you (holding a wake lock from the time you enqueue work until the job
|
||||
has been dispatched and while it is running). When running on previous
|
||||
versions of the platform, this wake lock handling is emulated in the
|
||||
class here by directly calling the PowerManager; this means
|
||||
the application must request the Manifest.permission.WAKE_LOCK permission.
|
||||
//-->
|
||||
<uses-permission android:name="android.permission.WAKE_LOCK"/>
|
||||
<uses-permission android:name="android.permission.BATTERY_STATS"/>
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
|
||||
|
@ -260,12 +269,7 @@
|
|||
android:name="com.mapswithme.maps.settings.DrivingOptionsActivity"
|
||||
android:label="@string/driving_options_title"/>
|
||||
<service
|
||||
android:name="com.mapswithme.maps.background.WorkerService"
|
||||
android:permission="android.permission.BIND_JOB_SERVICE"
|
||||
android:exported="false"/>
|
||||
|
||||
<service
|
||||
android:name="com.mapswithme.maps.background.NotificationService"
|
||||
android:name="com.mapswithme.maps.background.OsmUploadService"
|
||||
android:permission="android.permission.BIND_JOB_SERVICE"
|
||||
android:exported="false"/>
|
||||
|
||||
|
@ -279,20 +283,6 @@
|
|||
android:permission="android.permission.BIND_JOB_SERVICE"
|
||||
android:exported="false"/>
|
||||
|
||||
<receiver
|
||||
android:name="com.mapswithme.maps.bookmarks.SystemDownloadCompletedReceiver"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.DOWNLOAD_COMPLETE"/>
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
|
||||
<service
|
||||
android:name="com.mapswithme.maps.bookmarks.SystemDownloadCompletedService"
|
||||
android:permission="android.permission.BIND_JOB_SERVICE"
|
||||
android:exported="false">
|
||||
</service>
|
||||
|
||||
<!-- Catches app upgraded intent -->
|
||||
<receiver android:name=".background.UpgradeReceiver">
|
||||
<intent-filter>
|
||||
|
|
|
@ -3,21 +3,40 @@ package com.mapswithme.maps;
|
|||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
public abstract class MwmBroadcastReceiver extends BroadcastReceiver {
|
||||
import com.mapswithme.util.CrashlyticsUtils;
|
||||
import com.mapswithme.util.log.Logger;
|
||||
import com.mapswithme.util.log.LoggerFactory;
|
||||
|
||||
protected abstract void onReceiveInitialized(@NonNull Context context, @Nullable Intent intent);
|
||||
public abstract class MwmBroadcastReceiver extends BroadcastReceiver
|
||||
{
|
||||
private static final Logger LOGGER = LoggerFactory.INSTANCE.getLogger(LoggerFactory.Type.MISC);
|
||||
|
||||
@Override
|
||||
public final void onReceive(Context context, Intent intent)
|
||||
@NonNull
|
||||
protected String getTag()
|
||||
{
|
||||
return getClass().getSimpleName();
|
||||
}
|
||||
|
||||
protected abstract void onReceiveInitialized(@NonNull Context context, @NonNull Intent intent);
|
||||
|
||||
@Override
|
||||
public final void onReceive(@NonNull Context context, @NonNull Intent intent)
|
||||
{
|
||||
MwmApplication app = MwmApplication.from(context);
|
||||
String msg = "onReceive: " + intent;
|
||||
LOGGER.i(getTag(), msg);
|
||||
CrashlyticsUtils.INSTANCE.log(Log.INFO, getTag(), msg);
|
||||
if (!app.arePlatformAndCoreInitialized() && !app.initCore())
|
||||
{
|
||||
MwmApplication app = MwmApplication.from(context);
|
||||
if (!app.arePlatformAndCoreInitialized() && !app.initCore())
|
||||
return;
|
||||
onReceiveInitialized(context, intent);
|
||||
LOGGER.w(getTag(), "Application is not initialized, ignoring " + intent);
|
||||
return;
|
||||
}
|
||||
onReceiveInitialized(context, intent);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
39
android/src/com/mapswithme/maps/MwmJobIntentService.java
Normal file
39
android/src/com/mapswithme/maps/MwmJobIntentService.java
Normal file
|
@ -0,0 +1,39 @@
|
|||
package com.mapswithme.maps;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.core.app.JobIntentService;
|
||||
|
||||
import com.mapswithme.util.CrashlyticsUtils;
|
||||
import com.mapswithme.util.log.Logger;
|
||||
import com.mapswithme.util.log.LoggerFactory;
|
||||
|
||||
public abstract class MwmJobIntentService extends JobIntentService
|
||||
{
|
||||
private static final Logger LOGGER = LoggerFactory.INSTANCE.getLogger(LoggerFactory.Type.MISC);
|
||||
|
||||
@NonNull
|
||||
protected String getTag()
|
||||
{
|
||||
return getClass().getSimpleName();
|
||||
}
|
||||
|
||||
protected abstract void onHandleWorkInitialized(@NonNull Intent intent);
|
||||
|
||||
@Override
|
||||
protected void onHandleWork(@NonNull Intent intent)
|
||||
{
|
||||
MwmApplication app = MwmApplication.from(this);
|
||||
String msg = "onHandleWork: " + intent;
|
||||
LOGGER.i(getTag(), msg);
|
||||
CrashlyticsUtils.INSTANCE.log(Log.INFO, getTag(), msg);
|
||||
if (!app.arePlatformAndCoreInitialized() && !app.initCore())
|
||||
{
|
||||
LOGGER.w(getTag(), "Application is not initialized, ignoring " + intent);
|
||||
return;
|
||||
}
|
||||
onHandleWorkInitialized(intent);
|
||||
}
|
||||
}
|
|
@ -1,49 +0,0 @@
|
|||
package com.mapswithme.maps.background;
|
||||
|
||||
import static com.mapswithme.maps.MwmApplication.backgroundTracker;
|
||||
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.mapswithme.util.CrashlyticsUtils;
|
||||
import com.mapswithme.util.log.Logger;
|
||||
import com.mapswithme.util.log.LoggerFactory;
|
||||
|
||||
public abstract class AbstractLogBroadcastReceiver extends BroadcastReceiver
|
||||
{
|
||||
private static final Logger LOGGER = LoggerFactory.INSTANCE.getLogger(LoggerFactory.Type.MISC);
|
||||
|
||||
@Override
|
||||
public final void onReceive(Context context, Intent intent)
|
||||
{
|
||||
String action = intent != null ? intent.getAction() : null;
|
||||
if (!TextUtils.equals(getAssertAction(), action))
|
||||
{
|
||||
LOGGER.w(getTag(), "An intent with wrong action detected: " + action);
|
||||
return;
|
||||
}
|
||||
|
||||
String msg = "onReceive: " + intent + " app in background = "
|
||||
+ !backgroundTracker(context).isForeground();
|
||||
LOGGER.i(getTag(), msg);
|
||||
CrashlyticsUtils.INSTANCE.log(Log.INFO, getTag(), msg);
|
||||
onReceiveInternal(context, intent);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
protected String getTag()
|
||||
{
|
||||
return getClass().getSimpleName();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
protected abstract String getAssertAction();
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public abstract void onReceiveInternal(@NonNull Context context, @NonNull Intent intent);
|
||||
}
|
|
@ -1,23 +0,0 @@
|
|||
package com.mapswithme.maps.background;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.net.ConnectivityManager;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
public class ConnectivityChangedReceiver extends AbstractLogBroadcastReceiver
|
||||
{
|
||||
|
||||
@Override
|
||||
public void onReceiveInternal(@NonNull Context context, @NonNull Intent intent)
|
||||
{
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
protected String getAssertAction()
|
||||
{
|
||||
return ConnectivityManager.CONNECTIVITY_ACTION;
|
||||
}
|
||||
}
|
|
@ -1,104 +0,0 @@
|
|||
package com.mapswithme.maps.background;
|
||||
|
||||
import static android.net.ConnectivityManager.CONNECTIVITY_ACTION;
|
||||
import static com.mapswithme.maps.MwmApplication.prefs;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.net.ConnectivityManager;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.core.app.JobIntentService;
|
||||
|
||||
import com.mapswithme.maps.MwmApplication;
|
||||
import com.mapswithme.maps.routing.RoutingController;
|
||||
import com.mapswithme.maps.scheduling.JobIdMap;
|
||||
import com.mapswithme.util.PermissionsUtils;
|
||||
import com.mapswithme.util.log.Logger;
|
||||
import com.mapswithme.util.log.LoggerFactory;
|
||||
|
||||
public class NotificationService extends JobIntentService
|
||||
{
|
||||
private static final Logger LOGGER = LoggerFactory.INSTANCE.getLogger(LoggerFactory.Type.MISC);
|
||||
private static final String TAG = NotificationService.class.getSimpleName();
|
||||
private static final String LAST_AUTH_NOTIFICATION_TIMESTAMP = "DownloadOrUpdateTimestamp";
|
||||
|
||||
private interface NotificationExecutor
|
||||
{
|
||||
boolean tryToNotify();
|
||||
}
|
||||
|
||||
public static void startOnConnectivityChanged(@NonNull Context context)
|
||||
{
|
||||
final Intent intent = new Intent(context, NotificationService.class)
|
||||
.setAction(CONNECTIVITY_ACTION);
|
||||
|
||||
int id = JobIdMap.getId(NotificationService.class);
|
||||
JobIntentService.enqueueWork(context, NotificationService.class, id, intent);
|
||||
}
|
||||
|
||||
private boolean notifyIsNotAuthenticated()
|
||||
{
|
||||
final long lastEventTimestamp = prefs(this)
|
||||
.getLong(LAST_AUTH_NOTIFICATION_TIMESTAMP, 0);
|
||||
|
||||
// if (System.currentTimeMillis() - lastEventTimestamp > MIN_AUTH_EVENT_DELTA_MILLIS)
|
||||
// {
|
||||
// LOGGER.d(TAG, "Authentication notification will be sent.");
|
||||
//
|
||||
// prefs(this).edit().putLong(LAST_AUTH_NOTIFICATION_TIMESTAMP, System.currentTimeMillis()).apply();
|
||||
//
|
||||
// Notifier notifier = Notifier.from(getApplication());
|
||||
// notifier.notifyAuthentication();
|
||||
//
|
||||
// return true;
|
||||
// }
|
||||
LOGGER.d(TAG, "Authentication notification is rejected. Last event timestamp: " +
|
||||
lastEventTimestamp + "Current time milliseconds: " + System.currentTimeMillis());
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean notifySmart()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onHandleWork(@NonNull Intent intent)
|
||||
{
|
||||
final String action = intent.getAction();
|
||||
|
||||
if (ConnectivityManager.CONNECTIVITY_ACTION.equals(action))
|
||||
tryToShowNotification();
|
||||
}
|
||||
|
||||
private void tryToShowNotification()
|
||||
{
|
||||
if (!PermissionsUtils.isLocationGranted(this))
|
||||
{
|
||||
LOGGER.d(TAG, "Notification is rejected. Location permission is not granted.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Do not show push when user is in the navigation mode.
|
||||
if (MwmApplication.from(this).arePlatformAndCoreInitialized()
|
||||
&& RoutingController.get().isNavigating())
|
||||
{
|
||||
LOGGER.d(TAG, "Notification is rejected. The user is in navigation mode.");
|
||||
return;
|
||||
}
|
||||
|
||||
final NotificationExecutor[] notifyOrder =
|
||||
{
|
||||
this::notifyIsNotAuthenticated,
|
||||
this::notifySmart
|
||||
};
|
||||
|
||||
// Only one notification should be shown at a time.
|
||||
for (NotificationExecutor executor : notifyOrder)
|
||||
{
|
||||
if (executor.tryToNotify())
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -57,25 +57,6 @@ public final class Notifier
|
|||
placeNotification(title, content, pi, ID_DOWNLOAD_FAILED, channel);
|
||||
}
|
||||
|
||||
// void notifyAuthentication()
|
||||
// {
|
||||
// Intent authIntent = MwmActivity.createAuthenticateIntent(mContext);
|
||||
// authIntent.putExtra(EXTRA_CANCEL_NOTIFICATION, Notifier.ID_IS_NOT_AUTHENTICATED);
|
||||
// PendingIntent pi = PendingIntent.getActivity(mContext, 0, authIntent,
|
||||
// PendingIntent.FLAG_UPDATE_CURRENT);
|
||||
//
|
||||
// String channel = NotificationChannelFactory.createProvider(mContext).getUGCChannel();
|
||||
// NotificationCompat.Builder builder =
|
||||
// getBuilder(mContext.getString(R.string.notification_unsent_reviews_title),
|
||||
// mContext.getString(R.string.notification_unsent_reviews_message),
|
||||
// pi, channel);
|
||||
//
|
||||
// builder.addAction(0, mContext.getString(R.string.authorization_button_sign_in), pi);
|
||||
//
|
||||
// getNotificationManager().notify(ID_IS_NOT_AUTHENTICATED, builder.build());
|
||||
//
|
||||
// }
|
||||
|
||||
public void cancelNotification(@NotificationId int id)
|
||||
{
|
||||
if (id == ID_NONE)
|
||||
|
@ -95,11 +76,6 @@ public final class Notifier
|
|||
int notificationId = intent.getIntExtra(Notifier.EXTRA_CANCEL_NOTIFICATION, Notifier.ID_NONE);
|
||||
cancelNotification(notificationId);
|
||||
}
|
||||
|
||||
if (intent.hasExtra(Notifier.EXTRA_NOTIFICATION_CLICKED))
|
||||
{
|
||||
String eventName = intent.getStringExtra(Notifier.EXTRA_NOTIFICATION_CLICKED);
|
||||
}
|
||||
}
|
||||
|
||||
private void placeNotification(String title, String content, PendingIntent pendingIntent,
|
||||
|
|
|
@ -15,12 +15,11 @@ import java.util.Objects;
|
|||
@TargetApi(Build.VERSION_CODES.O)
|
||||
public class OreoCompatNotificationChannelProvider extends StubNotificationChannelProvider
|
||||
{
|
||||
private static final String AUTH_NOTIFICATION_CHANNEL = "auth_notification_channel";
|
||||
private static final String DOWNLOADING_NOTIFICATION_CHANNEL = "downloading_notification_channel";
|
||||
|
||||
OreoCompatNotificationChannelProvider(@NonNull Application app)
|
||||
{
|
||||
super(app, AUTH_NOTIFICATION_CHANNEL, DOWNLOADING_NOTIFICATION_CHANNEL);
|
||||
super(app, DOWNLOADING_NOTIFICATION_CHANNEL);
|
||||
}
|
||||
|
||||
private void setChannelInternal(@NonNull String id, @NonNull String name)
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
package com.mapswithme.maps.background;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.core.app.JobIntentService;
|
||||
|
||||
import com.mapswithme.maps.MwmJobIntentService;
|
||||
import com.mapswithme.maps.editor.Editor;
|
||||
import com.mapswithme.maps.scheduling.JobIdMap;
|
||||
|
||||
public class OsmUploadService extends MwmJobIntentService
|
||||
{
|
||||
/**
|
||||
* Starts this service to upload map edits to osm servers.
|
||||
*/
|
||||
public static void startActionUploadOsmChanges(@NonNull Context context)
|
||||
{
|
||||
final Intent intent = new Intent(context, OsmUploadService.class);
|
||||
JobIntentService.enqueueWork(context.getApplicationContext(), OsmUploadService.class,
|
||||
JobIdMap.getId(OsmUploadService.class), intent);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onHandleWorkInitialized(@NonNull Intent intent)
|
||||
{
|
||||
final Context context = getApplicationContext();
|
||||
Editor.uploadChanges(context);
|
||||
}
|
||||
}
|
|
@ -11,24 +11,19 @@ public class StubNotificationChannelProvider implements NotificationChannelProvi
|
|||
@NonNull
|
||||
private final Application mApplication;
|
||||
|
||||
@NonNull
|
||||
private final String mAuthChannel;
|
||||
|
||||
@NonNull
|
||||
private final String mDownloadingChannel;
|
||||
|
||||
|
||||
StubNotificationChannelProvider(@NonNull Application context, @NonNull String authChannel,
|
||||
@NonNull String downloadingChannel)
|
||||
StubNotificationChannelProvider(@NonNull Application context, @NonNull String downloadingChannel)
|
||||
{
|
||||
mApplication = context;
|
||||
mAuthChannel = authChannel;
|
||||
mDownloadingChannel = downloadingChannel;
|
||||
}
|
||||
|
||||
StubNotificationChannelProvider(@NonNull Application context)
|
||||
{
|
||||
this(context, DEFAULT_NOTIFICATION_CHANNEL, DEFAULT_NOTIFICATION_CHANNEL);
|
||||
this(context, DEFAULT_NOTIFICATION_CHANNEL);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
|
|
|
@ -1,63 +0,0 @@
|
|||
package com.mapswithme.maps.background;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.core.app.JobIntentService;
|
||||
|
||||
import com.mapswithme.maps.MwmApplication;
|
||||
import com.mapswithme.maps.editor.Editor;
|
||||
import com.mapswithme.maps.scheduling.JobIdMap;
|
||||
import com.mapswithme.util.CrashlyticsUtils;
|
||||
import com.mapswithme.util.log.Logger;
|
||||
import com.mapswithme.util.log.LoggerFactory;
|
||||
|
||||
public class WorkerService extends JobIntentService
|
||||
{
|
||||
private static final Logger LOGGER = LoggerFactory.INSTANCE.getLogger(LoggerFactory.Type.MISC);
|
||||
private static final String TAG = WorkerService.class.getSimpleName();
|
||||
private static final String ACTION_UPLOAD_OSM_CHANGES = "com.mapswithme.maps.action.upload_osm_changes";
|
||||
|
||||
/**
|
||||
* Starts this service to upload map edits to osm servers.
|
||||
*/
|
||||
public static void startActionUploadOsmChanges(@NonNull Context context)
|
||||
{
|
||||
final Intent intent = new Intent(context, WorkerService.class);
|
||||
intent.setAction(WorkerService.ACTION_UPLOAD_OSM_CHANGES);
|
||||
JobIntentService.enqueueWork(context.getApplicationContext(), WorkerService.class,
|
||||
JobIdMap.getId(WorkerService.class), intent);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onHandleWork(@NonNull Intent intent)
|
||||
{
|
||||
final Context context = getApplicationContext();
|
||||
String msg = "onHandleIntent: " + intent + " app in background = "
|
||||
+ !MwmApplication.backgroundTracker(context).isForeground();
|
||||
LOGGER.i(TAG, msg);
|
||||
CrashlyticsUtils.INSTANCE.log(Log.INFO, TAG, msg);
|
||||
final String action = intent.getAction();
|
||||
|
||||
if (TextUtils.isEmpty(action))
|
||||
return;
|
||||
|
||||
if (!MwmApplication.from(context).arePlatformAndCoreInitialized())
|
||||
return;
|
||||
|
||||
switch (action)
|
||||
{
|
||||
case ACTION_UPLOAD_OSM_CHANGES:
|
||||
handleActionUploadOsmChanges(context);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private static void handleActionUploadOsmChanges(@NonNull Context context)
|
||||
{
|
||||
Editor.uploadChanges(context);
|
||||
}
|
||||
}
|
|
@ -1,32 +0,0 @@
|
|||
package com.mapswithme.maps.bookmarks;
|
||||
|
||||
import android.app.DownloadManager;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.core.app.JobIntentService;
|
||||
|
||||
import com.mapswithme.maps.background.AbstractLogBroadcastReceiver;
|
||||
import com.mapswithme.maps.scheduling.JobIdMap;
|
||||
|
||||
public class SystemDownloadCompletedReceiver extends AbstractLogBroadcastReceiver
|
||||
{
|
||||
@NonNull
|
||||
@Override
|
||||
protected String getAssertAction()
|
||||
{
|
||||
return DownloadManager.ACTION_DOWNLOAD_COMPLETE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onReceiveInternal(@NonNull Context context, @NonNull Intent intent)
|
||||
{
|
||||
DownloadManager manager = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE);
|
||||
if (manager == null)
|
||||
return;
|
||||
intent.setClass(context, SystemDownloadCompletedService.class);
|
||||
int jobId = JobIdMap.getId(SystemDownloadCompletedService.class);
|
||||
JobIntentService.enqueueWork(context, SystemDownloadCompletedService.class, jobId, intent);
|
||||
}
|
||||
}
|
|
@ -1,155 +0,0 @@
|
|||
package com.mapswithme.maps.bookmarks;
|
||||
|
||||
import android.app.DownloadManager;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.database.Cursor;
|
||||
import android.net.Uri;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.core.app.JobIntentService;
|
||||
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
|
||||
|
||||
import com.mapswithme.maps.MwmApplication;
|
||||
import com.mapswithme.maps.bookmarks.data.Error;
|
||||
import com.mapswithme.maps.bookmarks.data.Result;
|
||||
import com.mapswithme.util.Utils;
|
||||
import com.mapswithme.util.concurrency.UiThread;
|
||||
import com.mapswithme.util.log.Logger;
|
||||
import com.mapswithme.util.log.LoggerFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class SystemDownloadCompletedService extends JobIntentService
|
||||
{
|
||||
public final static String ACTION_DOWNLOAD_COMPLETED = "action_download_completed";
|
||||
public final static String EXTRA_DOWNLOAD_STATUS = "extra_download_status";
|
||||
|
||||
@Override
|
||||
public void onCreate()
|
||||
{
|
||||
super.onCreate();
|
||||
MwmApplication app = (MwmApplication) getApplication();
|
||||
if (app.arePlatformAndCoreInitialized())
|
||||
return;
|
||||
app.initCore();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onHandleWork(@NonNull Intent intent)
|
||||
{
|
||||
DownloadManager manager = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
|
||||
if (manager == null)
|
||||
throw new IllegalStateException("Failed to get a download manager");
|
||||
|
||||
final OperationStatus status = calculateStatus(manager, intent);
|
||||
Logger logger = LoggerFactory.INSTANCE.getLogger(LoggerFactory.Type.BILLING);
|
||||
String tag = SystemDownloadCompletedService.class.getSimpleName();
|
||||
logger.i(tag, "Download status: " + status);
|
||||
UiThread.run(new SendStatusTask(getApplicationContext(), status));
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private OperationStatus calculateStatus(@NonNull DownloadManager manager, @NonNull Intent intent)
|
||||
{
|
||||
try
|
||||
{
|
||||
return calculateStatusInternal(manager, intent);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
return new OperationStatus(null, new Error(e.getMessage()));
|
||||
}
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private OperationStatus calculateStatusInternal(
|
||||
@NonNull DownloadManager manager, @NonNull Intent intent) throws IOException
|
||||
{
|
||||
Cursor cursor = null;
|
||||
try
|
||||
{
|
||||
final long id = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, 0);
|
||||
DownloadManager.Query query = new DownloadManager.Query().setFilterById(id);
|
||||
cursor = manager.query(query);
|
||||
if (cursor.moveToFirst())
|
||||
{
|
||||
|
||||
if (isDownloadFailed(cursor))
|
||||
{
|
||||
Error error = new Error(getHttpStatus(cursor), getErrorMessage(cursor));
|
||||
return new OperationStatus(null, error);
|
||||
}
|
||||
|
||||
Result result = new Result(getFilePath(cursor), getArchiveId(cursor));
|
||||
return new OperationStatus(result, null);
|
||||
}
|
||||
throw new IOException("Failed to move the cursor at first row");
|
||||
}
|
||||
finally
|
||||
{
|
||||
Utils.closeSafely(cursor);
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isDownloadFailed(@NonNull Cursor cursor)
|
||||
{
|
||||
int status = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS));
|
||||
return status != DownloadManager.STATUS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static String getFilePath(@NonNull Cursor cursor)
|
||||
{
|
||||
String localUri = getColumnValue(cursor, DownloadManager.COLUMN_LOCAL_URI);
|
||||
return localUri == null ? null : Uri.parse(localUri).getPath();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static String getArchiveId(@NonNull Cursor cursor)
|
||||
{
|
||||
return Uri.parse(getColumnValue(cursor, DownloadManager.COLUMN_URI)).getLastPathSegment();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static String getColumnValue(@NonNull Cursor cursor, @NonNull String columnName)
|
||||
{
|
||||
return cursor.getString(cursor.getColumnIndex(columnName));
|
||||
}
|
||||
|
||||
private static int getHttpStatus(@NonNull Cursor cursor)
|
||||
{
|
||||
String rawStatus = cursor.getString(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS));
|
||||
return Integer.parseInt(rawStatus);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static String getErrorMessage(@NonNull Cursor cursor)
|
||||
{
|
||||
return cursor.getString(cursor.getColumnIndex(DownloadManager.COLUMN_REASON));
|
||||
}
|
||||
|
||||
private static class SendStatusTask implements Runnable
|
||||
{
|
||||
@NonNull
|
||||
private final Context mAppContext;
|
||||
@NonNull
|
||||
private final OperationStatus mStatus;
|
||||
|
||||
private SendStatusTask(@NonNull Context applicationContext,
|
||||
@NonNull OperationStatus status)
|
||||
{
|
||||
mAppContext = applicationContext;
|
||||
mStatus = status;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
Intent intent = new Intent(ACTION_DOWNLOAD_COMPLETED);
|
||||
intent.putExtra(EXTRA_DOWNLOAD_STATUS, mStatus);
|
||||
LocalBroadcastManager.getInstance(mAppContext).sendBroadcast(intent);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -11,7 +11,7 @@ import com.mapswithme.maps.BuildConfig;
|
|||
import com.mapswithme.maps.Framework;
|
||||
import com.mapswithme.maps.MwmApplication;
|
||||
import com.mapswithme.maps.background.AppBackgroundTracker;
|
||||
import com.mapswithme.maps.background.WorkerService;
|
||||
import com.mapswithme.maps.background.OsmUploadService;
|
||||
import com.mapswithme.maps.editor.data.FeatureCategory;
|
||||
import com.mapswithme.maps.editor.data.Language;
|
||||
import com.mapswithme.maps.editor.data.LocalizedName;
|
||||
|
@ -199,7 +199,7 @@ public final class Editor
|
|||
if (foreground)
|
||||
return;
|
||||
|
||||
WorkerService.startActionUploadOsmChanges(mContext);
|
||||
OsmUploadService.startActionUploadOsmChanges(mContext);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,28 +1,23 @@
|
|||
package com.mapswithme.maps.location;
|
||||
|
||||
import static com.mapswithme.maps.MwmApplication.backgroundTracker;
|
||||
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.location.LocationManager;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.mapswithme.maps.MwmApplication;
|
||||
import com.mapswithme.util.log.Logger;
|
||||
import com.mapswithme.util.log.LoggerFactory;
|
||||
import com.mapswithme.maps.MwmBroadcastReceiver;
|
||||
|
||||
public class GPSCheck extends BroadcastReceiver
|
||||
public class GPSCheck extends MwmBroadcastReceiver
|
||||
{
|
||||
private static final Logger LOGGER = LoggerFactory.INSTANCE.getLogger(LoggerFactory.Type.LOCATION);
|
||||
private static final String TAG = GPSCheck.class.getSimpleName();
|
||||
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent)
|
||||
public void onReceiveInitialized(Context context, Intent intent)
|
||||
{
|
||||
String msg = "onReceive: " + intent + " app in background = "
|
||||
+ !backgroundTracker(context).isForeground();
|
||||
LOGGER.i(TAG, msg);
|
||||
if (MwmApplication.from(context).arePlatformAndCoreInitialized() &&
|
||||
MwmApplication.backgroundTracker(context).isForeground())
|
||||
if (!TextUtils.equals(intent.getAction(), LocationManager.PROVIDERS_CHANGED_ACTION))
|
||||
{
|
||||
throw new AssertionError("An intent with wrong action detected: " + intent.getAction());
|
||||
}
|
||||
if (MwmApplication.backgroundTracker(context).isForeground())
|
||||
{
|
||||
LocationHelper.INSTANCE.restart();
|
||||
}
|
||||
|
|
|
@ -1,31 +1,17 @@
|
|||
package com.mapswithme.maps.location;
|
||||
|
||||
import static com.mapswithme.maps.MwmApplication.backgroundTracker;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.mapswithme.maps.MwmBroadcastReceiver;
|
||||
import com.mapswithme.util.CrashlyticsUtils;
|
||||
import com.mapswithme.util.log.Logger;
|
||||
import com.mapswithme.util.log.LoggerFactory;
|
||||
|
||||
public class TrackRecorderWakeReceiver extends MwmBroadcastReceiver
|
||||
{
|
||||
private static final Logger LOGGER = LoggerFactory.INSTANCE.getLogger(LoggerFactory.Type.MISC);
|
||||
private static final String TAG = TrackRecorderWakeReceiver.class.getSimpleName();
|
||||
|
||||
@Override
|
||||
public void onReceiveInitialized(@NonNull Context context, @Nullable Intent intent)
|
||||
public void onReceiveInitialized(@NonNull Context context, @NonNull Intent intent)
|
||||
{
|
||||
String msg = "onReceive: " + intent + " app in background = "
|
||||
+ !backgroundTracker(context).isForeground();
|
||||
LOGGER.i(TAG, msg);
|
||||
CrashlyticsUtils.INSTANCE.log(Log.INFO, TAG, msg);
|
||||
TrackRecorder.INSTANCE.onWakeAlarm();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ import android.util.Log;
|
|||
import androidx.annotation.NonNull;
|
||||
import androidx.core.app.JobIntentService;
|
||||
|
||||
import com.mapswithme.maps.MwmApplication;
|
||||
import com.mapswithme.maps.MwmJobIntentService;
|
||||
import com.mapswithme.maps.scheduling.JobIdMap;
|
||||
import com.mapswithme.util.CrashlyticsUtils;
|
||||
import com.mapswithme.util.log.Logger;
|
||||
|
@ -21,7 +21,7 @@ import java.util.Objects;
|
|||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class TrackRecorderWakeService extends JobIntentService
|
||||
public class TrackRecorderWakeService extends MwmJobIntentService
|
||||
{
|
||||
private static final String TAG = TrackRecorderWakeService.class.getSimpleName();
|
||||
private static final Logger LOGGER = LoggerFactory.INSTANCE.getLogger(LoggerFactory.Type.TRACK_RECORDER);
|
||||
|
@ -30,13 +30,8 @@ public class TrackRecorderWakeService extends JobIntentService
|
|||
private final CountDownLatch mWaitMonitor = new CountDownLatch(1);
|
||||
|
||||
@Override
|
||||
protected void onHandleWork(@NonNull Intent intent)
|
||||
protected void onHandleWorkInitialized(@NonNull Intent intent)
|
||||
{
|
||||
String msg = "onHandleIntent: " + intent + " app in background = "
|
||||
+ !MwmApplication.backgroundTracker(getApplicationContext()).isForeground();
|
||||
LOGGER.i(TAG, msg);
|
||||
CrashlyticsUtils.INSTANCE.log(Log.INFO, TAG, msg);
|
||||
|
||||
synchronized (sLock)
|
||||
{
|
||||
sService = this;
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
package com.mapswithme.maps.scheduling;
|
||||
|
||||
import com.mapswithme.maps.background.NotificationService;
|
||||
import com.mapswithme.maps.background.WorkerService;
|
||||
import com.mapswithme.maps.bookmarks.SystemDownloadCompletedService;
|
||||
import com.mapswithme.maps.background.OsmUploadService;
|
||||
import com.mapswithme.maps.location.TrackRecorderWakeService;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
@ -13,10 +11,8 @@ public class JobIdMap
|
|||
private static final Map<Class<?>, Integer> MAP = new HashMap<>();
|
||||
|
||||
static {
|
||||
MAP.put(NotificationService.class, calcIdentifier(MAP.size()));
|
||||
MAP.put(TrackRecorderWakeService.class, calcIdentifier(MAP.size()));
|
||||
MAP.put(SystemDownloadCompletedService.class, calcIdentifier(MAP.size()));
|
||||
MAP.put(WorkerService.class, calcIdentifier(MAP.size()));
|
||||
MAP.put(OsmUploadService.class, calcIdentifier(MAP.size()));
|
||||
}
|
||||
|
||||
private static final int ID_BASIC = 1070;
|
||||
|
|
Loading…
Add table
Reference in a new issue