forked from organicmaps/organicmaps-tmp
[android] Modified implicit receivers for lollipop or later
This commit is contained in:
parent
d934d0551c
commit
3d0727b571
8 changed files with 327 additions and 77 deletions
|
@ -440,24 +440,22 @@
|
|||
android:label="@string/subtittle_opt_out"
|
||||
android:configChanges="keyboardHidden|orientation|screenSize">
|
||||
</activity>
|
||||
<receiver
|
||||
android:name="com.mapswithme.maps.background.ConnectivityChangedReceiver"
|
||||
android:enabled="true"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.net.conn.CONNECTIVITY_CHANGE"/>
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
|
||||
<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:permission="android.permission.BIND_JOB_SERVICE"
|
||||
android:exported="false"/>
|
||||
|
||||
<service android:name="com.mapswithme.maps.scheduling.NativeJobService"
|
||||
android:enabled="true"
|
||||
android:exported="false"
|
||||
android:permission="android.permission.BIND_JOB_SERVICE"/>
|
||||
|
||||
<receiver android:name="com.mapswithme.maps.location.TrackRecorderWakeReceiver">
|
||||
<intent-filter>
|
||||
<action android:name="com.mapswithme.maps.TRACK_RECORDER_ALARM"/>
|
||||
|
@ -489,16 +487,6 @@
|
|||
MultipleTrackerReferrerReceiver and then pass it manually to myTracker's one. -->
|
||||
<service android:name="com.my.tracker.campaign.CampaignService"/>
|
||||
|
||||
<!-- Alohalytics -->
|
||||
<receiver
|
||||
android:name="org.alohalytics.ConnectivityChangedReceiver"
|
||||
android:enabled="true"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.net.conn.CONNECTIVITY_CHANGE"/>
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
|
||||
<receiver
|
||||
android:name="com.google.android.gms.gcm.GcmReceiver"
|
||||
android:exported="true"
|
||||
|
|
|
@ -546,7 +546,6 @@ public class MwmActivity extends BaseMwmFragmentActivity
|
|||
mSearchController.setVisibilityListener(this);
|
||||
|
||||
SharingHelper.INSTANCE.initialize();
|
||||
|
||||
//TODO: uncomment after correct visible rect calculation.
|
||||
//mVisibleRectMeasurer = new VisibleRectMeasurer(new VisibleRectListener() {
|
||||
// @Override
|
||||
|
|
|
@ -28,6 +28,8 @@ import com.mapswithme.maps.maplayer.traffic.TrafficManager;
|
|||
import com.mapswithme.maps.purchase.Factory;
|
||||
import com.mapswithme.maps.purchase.PurchaseValidator;
|
||||
import com.mapswithme.maps.routing.RoutingController;
|
||||
import com.mapswithme.maps.scheduling.JobDispatcher;
|
||||
import com.mapswithme.maps.scheduling.JobDispatcherComposite;
|
||||
import com.mapswithme.maps.sound.TtsPlayer;
|
||||
import com.mapswithme.maps.ugc.UGC;
|
||||
import com.mapswithme.util.Config;
|
||||
|
@ -81,54 +83,15 @@ public class MwmApplication extends Application
|
|||
|
||||
private Handler mMainLoopHandler;
|
||||
private final Object mMainQueueToken = new Object();
|
||||
|
||||
private final MapManager.StorageCallback mStorageCallbacks = new MapManager.StorageCallback()
|
||||
{
|
||||
@Override
|
||||
public void onStatusChanged(List<MapManager.StorageCallbackData> data)
|
||||
{
|
||||
for (MapManager.StorageCallbackData item : data)
|
||||
if (item.isLeafNode && item.newStatus == CountryItem.STATUS_FAILED)
|
||||
{
|
||||
if (MapManager.nativeIsAutoretryFailed())
|
||||
{
|
||||
Notifier.notifyDownloadFailed(item.countryId, MapManager.nativeGetName(item.countryId));
|
||||
MapManager.sendErrorStat(Statistics.EventName.DOWNLOADER_ERROR, MapManager.nativeGetError(item.countryId));
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onProgress(String countryId, long localSize, long remoteSize) {}
|
||||
};
|
||||
|
||||
@NonNull
|
||||
private final AppBackgroundTracker.OnTransitionListener mBackgroundListener =
|
||||
new AppBackgroundTracker.OnTransitionListener()
|
||||
{
|
||||
@Override
|
||||
public void onTransit(boolean foreground)
|
||||
{
|
||||
if (!foreground && LoggerFactory.INSTANCE.isFileLoggingEnabled())
|
||||
{
|
||||
Log.i(TAG, "The app goes to background. All logs are going to be zipped.");
|
||||
LoggerFactory.INSTANCE.zipLogs(null);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private final AppBackgroundTracker.OnVisibleAppLaunchListener mVisibleAppLaunchListener = new VisibleAppLaunchListener();
|
||||
@SuppressWarnings("NullableProblems")
|
||||
@NonNull
|
||||
private final AppBackgroundTracker.OnVisibleAppLaunchListener mVisibleAppLaunchListener =
|
||||
new AppBackgroundTracker.OnVisibleAppLaunchListener()
|
||||
{
|
||||
@Override
|
||||
public void onVisibleAppLaunch()
|
||||
{
|
||||
Statistics.INSTANCE.trackColdStartupInfo();
|
||||
}
|
||||
};
|
||||
private JobDispatcher mJobDispatcher;
|
||||
@NonNull
|
||||
private final MapManager.StorageCallback mStorageCallbacks = new StorageCallbackImpl();
|
||||
@NonNull
|
||||
private final AppBackgroundTracker.OnTransitionListener mBackgroundListener = new TransitionListener();
|
||||
|
||||
@NonNull
|
||||
public SubwayManager getSubwayManager()
|
||||
|
@ -205,6 +168,8 @@ public class MwmApplication extends Application
|
|||
mBackgroundTracker = new AppBackgroundTracker();
|
||||
mBackgroundTracker.addListener(mVisibleAppLaunchListener);
|
||||
mSubwayManager = new SubwayManager(this);
|
||||
mJobDispatcher = new JobDispatcherComposite(this);
|
||||
mJobDispatcher.dispatch();
|
||||
}
|
||||
|
||||
private void initCoreIndependentSdks()
|
||||
|
@ -476,6 +441,12 @@ public class MwmApplication extends Application
|
|||
mMainLoopHandler.sendMessage(m);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public JobDispatcher getJobDispatcher()
|
||||
{
|
||||
return mJobDispatcher;
|
||||
}
|
||||
|
||||
private native void nativeInitPlatform(String apkPath, String storagePath, String privatePath,
|
||||
String tmpPath, String obbGooglePath, String flavorName,
|
||||
String buildType, boolean isTablet);
|
||||
|
@ -486,4 +457,48 @@ public class MwmApplication extends Application
|
|||
|
||||
@UiThread
|
||||
private static native void nativeInitCrashlytics();
|
||||
|
||||
private static class VisibleAppLaunchListener implements AppBackgroundTracker.OnVisibleAppLaunchListener
|
||||
{
|
||||
@Override
|
||||
public void onVisibleAppLaunch()
|
||||
{
|
||||
Statistics.INSTANCE.trackColdStartupInfo();
|
||||
}
|
||||
}
|
||||
|
||||
private static class StorageCallbackImpl implements MapManager.StorageCallback
|
||||
{
|
||||
@Override
|
||||
public void onStatusChanged(List<MapManager.StorageCallbackData> data)
|
||||
{
|
||||
for (MapManager.StorageCallbackData item : data)
|
||||
if (item.isLeafNode && item.newStatus == CountryItem.STATUS_FAILED)
|
||||
{
|
||||
if (MapManager.nativeIsAutoretryFailed())
|
||||
{
|
||||
Notifier.notifyDownloadFailed(item.countryId, MapManager.nativeGetName(item.countryId));
|
||||
MapManager.sendErrorStat(Statistics.EventName.DOWNLOADER_ERROR, MapManager.nativeGetError(item.countryId));
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onProgress(String countryId, long localSize, long remoteSize) {}
|
||||
}
|
||||
|
||||
private static class TransitionListener implements AppBackgroundTracker.OnTransitionListener
|
||||
{
|
||||
@Override
|
||||
public void onTransit(boolean foreground)
|
||||
{
|
||||
if (!foreground && LoggerFactory.INSTANCE.isFileLoggingEnabled())
|
||||
{
|
||||
Log.i(TAG, "The app goes to background. All logs are going to be zipped.");
|
||||
LoggerFactory.INSTANCE.zipLogs(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,9 +2,9 @@ package com.mapswithme.maps.background;
|
|||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.net.ConnectivityManager;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v4.app.JobIntentService;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.mapswithme.maps.LightFramework;
|
||||
import com.mapswithme.maps.MwmApplication;
|
||||
|
@ -32,7 +32,7 @@ public class NotificationService extends JobIntentService
|
|||
boolean tryToNotify();
|
||||
}
|
||||
|
||||
static void startOnConnectivityChanged(Context context)
|
||||
public static void startOnConnectivityChanged(Context context)
|
||||
{
|
||||
final Intent intent = new Intent(context, NotificationService.class)
|
||||
.setAction(CONNECTIVITY_ACTION);
|
||||
|
@ -88,15 +88,8 @@ public class NotificationService extends JobIntentService
|
|||
{
|
||||
final String action = intent.getAction();
|
||||
|
||||
if (TextUtils.isEmpty(action))
|
||||
return;
|
||||
|
||||
switch(action)
|
||||
{
|
||||
case CONNECTIVITY_ACTION:
|
||||
onConnectivityChanged();
|
||||
break;
|
||||
}
|
||||
if (ConnectivityManager.CONNECTIVITY_ACTION.equals(action))
|
||||
onConnectivityChanged();
|
||||
}
|
||||
|
||||
private static void onConnectivityChanged()
|
||||
|
|
|
@ -89,7 +89,8 @@ public final class TrackRecorder
|
|||
|
||||
private static PendingIntent getAlarmIntent()
|
||||
{
|
||||
return PendingIntent.getBroadcast(MwmApplication.get(), 0, sAlarmIntent, 0);
|
||||
Intent intent = new Intent(MwmApplication.get(), TrackRecorderWakeReceiver.class);
|
||||
return PendingIntent.getBroadcast(MwmApplication.get(), 0, intent, 0);
|
||||
}
|
||||
|
||||
private static void restartAlarmIfEnabled()
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
package com.mapswithme.maps.scheduling;
|
||||
|
||||
public interface JobDispatcher
|
||||
{
|
||||
void dispatch();
|
||||
void cancelAll();
|
||||
}
|
|
@ -0,0 +1,199 @@
|
|||
package com.mapswithme.maps.scheduling;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.app.job.JobInfo;
|
||||
import android.app.job.JobScheduler;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.IntentFilter;
|
||||
import android.net.ConnectivityManager;
|
||||
import android.net.NetworkInfo;
|
||||
import android.os.Build;
|
||||
import android.support.annotation.NonNull;
|
||||
|
||||
import com.mapswithme.maps.MwmApplication;
|
||||
import com.mapswithme.maps.background.ConnectivityChangedReceiver;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
public class JobDispatcherComposite implements JobDispatcher
|
||||
{
|
||||
@NonNull
|
||||
private final JobDispatcher mMasterJobDispatcher;
|
||||
|
||||
@NonNull
|
||||
private final MwmApplication mContext;
|
||||
|
||||
@NonNull
|
||||
private final AtomicInteger mCurrentNetworkType;
|
||||
|
||||
public JobDispatcherComposite(@NonNull MwmApplication context)
|
||||
{
|
||||
mContext = context;
|
||||
mMasterJobDispatcher = Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP
|
||||
? new NativeJobDispatcher(mContext)
|
||||
: new LegacyJobDispatcher(mContext);
|
||||
|
||||
mCurrentNetworkType = new AtomicInteger(getCurrentNetworkType().ordinal());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispatch()
|
||||
{
|
||||
mMasterJobDispatcher.dispatch();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancelAll()
|
||||
{
|
||||
mMasterJobDispatcher.cancelAll();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public NetworkStatus getNetworkStatus()
|
||||
{
|
||||
NetworkType currentNetworkType = getCurrentNetworkType();
|
||||
int prevTypeIndex = mCurrentNetworkType.getAndSet(currentNetworkType.mType);
|
||||
NetworkType prevNetworkType = NetworkType.getInstance(prevTypeIndex);
|
||||
boolean isNetworkChanged = prevNetworkType != currentNetworkType;
|
||||
return new NetworkStatus(isNetworkChanged, currentNetworkType);
|
||||
}
|
||||
|
||||
private NetworkType getCurrentNetworkType()
|
||||
{
|
||||
ConnectivityManager cm = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
|
||||
NetworkInfo activeNetwork;
|
||||
if (cm == null || (activeNetwork = cm.getActiveNetworkInfo()) == null)
|
||||
return NetworkType.UNDEFINED;
|
||||
|
||||
return NetworkType.getInstance(activeNetwork.getType());
|
||||
}
|
||||
|
||||
public enum NetworkType
|
||||
{
|
||||
WIFI(ConnectivityManager.TYPE_WIFI),
|
||||
MOBILE(ConnectivityManager.TYPE_MOBILE),
|
||||
UNDEFINED;
|
||||
|
||||
private final int mType;
|
||||
|
||||
NetworkType(int type)
|
||||
{
|
||||
|
||||
mType = type;
|
||||
}
|
||||
|
||||
NetworkType()
|
||||
{
|
||||
this(-1);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static NetworkType getInstance(int type)
|
||||
{
|
||||
for (NetworkType each : values())
|
||||
{
|
||||
if (each.mType == type)
|
||||
return each;
|
||||
}
|
||||
|
||||
return NetworkType.UNDEFINED;
|
||||
}
|
||||
}
|
||||
|
||||
public static JobDispatcherComposite from(@NonNull Context context)
|
||||
{
|
||||
MwmApplication application = (MwmApplication) context.getApplicationContext();
|
||||
return (JobDispatcherComposite) application.getJobDispatcher();
|
||||
}
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
|
||||
private static class NativeJobDispatcher implements JobDispatcher
|
||||
{
|
||||
private static final int PERIODIC_IN_MILLIS = 4000;
|
||||
@NonNull
|
||||
private final JobScheduler mJobScheduler;
|
||||
@NonNull
|
||||
private final Context mContext;
|
||||
|
||||
NativeJobDispatcher(@NonNull Context context)
|
||||
{
|
||||
mContext = context;
|
||||
JobScheduler jobScheduler = (JobScheduler) mContext.getSystemService(Context.JOB_SCHEDULER_SERVICE);
|
||||
Objects.requireNonNull(jobScheduler);
|
||||
mJobScheduler = jobScheduler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispatch()
|
||||
{
|
||||
ComponentName component = new ComponentName(mContext, NativeJobService.class);
|
||||
int jobId = NativeJobService.class.hashCode();
|
||||
JobInfo jobInfo = new JobInfo
|
||||
.Builder(jobId, component)
|
||||
.setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY)
|
||||
.setPeriodic(PERIODIC_IN_MILLIS)
|
||||
.build();
|
||||
mJobScheduler.schedule(jobInfo);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancelAll()
|
||||
{
|
||||
mJobScheduler.cancelAll();
|
||||
}
|
||||
}
|
||||
|
||||
public static class NetworkStatus
|
||||
{
|
||||
private final boolean mNetworkStateChanged;
|
||||
@NonNull
|
||||
private final NetworkType mCurrentNetworkType;
|
||||
|
||||
NetworkStatus(boolean networkStateChanged,
|
||||
@NonNull NetworkType currentNetworkType)
|
||||
{
|
||||
mNetworkStateChanged = networkStateChanged;
|
||||
mCurrentNetworkType = currentNetworkType;
|
||||
}
|
||||
|
||||
public boolean isNetworkStateChanged()
|
||||
{
|
||||
return mNetworkStateChanged;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public NetworkType getCurrentNetworkType()
|
||||
{
|
||||
return mCurrentNetworkType;
|
||||
}
|
||||
}
|
||||
|
||||
private static class LegacyJobDispatcher implements JobDispatcher
|
||||
{
|
||||
@NonNull
|
||||
private final MwmApplication mContext;
|
||||
@NonNull
|
||||
private final ConnectivityChangedReceiver mReceiver;
|
||||
|
||||
LegacyJobDispatcher(@NonNull MwmApplication context)
|
||||
{
|
||||
mContext = context;
|
||||
mReceiver = new ConnectivityChangedReceiver();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispatch()
|
||||
{
|
||||
IntentFilter filter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
|
||||
mContext.registerReceiver(mReceiver, filter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancelAll()
|
||||
{
|
||||
mContext.unregisterReceiver(mReceiver);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
package com.mapswithme.maps.scheduling;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.app.job.JobInfo;
|
||||
import android.app.job.JobParameters;
|
||||
import android.app.job.JobScheduler;
|
||||
import android.app.job.JobService;
|
||||
import android.content.ComponentName;
|
||||
import android.os.Build;
|
||||
|
||||
import com.mapswithme.maps.background.NotificationService;
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
|
||||
public class NativeJobService extends JobService
|
||||
{
|
||||
@Override
|
||||
public boolean onStartJob(JobParameters params)
|
||||
{
|
||||
JobDispatcherComposite jobDispatcher = JobDispatcherComposite.from(this);
|
||||
JobDispatcherComposite.NetworkStatus status = jobDispatcher.getNetworkStatus();
|
||||
if (status.isNetworkStateChanged())
|
||||
NotificationService.startOnConnectivityChanged(this);
|
||||
|
||||
if(android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
|
||||
scheduleRefresh();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void scheduleRefresh()
|
||||
{
|
||||
JobScheduler service = (JobScheduler) getSystemService(JOB_SCHEDULER_SERVICE);
|
||||
ComponentName component = new ComponentName(getApplicationContext(), NativeJobService.class);
|
||||
int jobId = NativeJobService.class.hashCode();
|
||||
/*FIXME*/
|
||||
JobInfo jobInfo = new JobInfo.Builder(jobId, component)
|
||||
.setMinimumLatency(4000)
|
||||
.setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY)
|
||||
.build();
|
||||
service.schedule(jobInfo);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onStopJob(JobParameters params)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue