diff options
author | Dmitry Donskoy <donskdmitry@mail.ru> | 2018-08-27 18:17:39 +0300 |
---|---|---|
committer | Aleksandr Zatsepin <alexzatsepin@users.noreply.github.com> | 2018-08-29 13:19:08 +0300 |
commit | 3d0727b571c459a41f614297a5ed1fb516e18edb (patch) | |
tree | 52edaea313e828285eff92306fda169c2448ff87 /android/src/com/mapswithme/maps | |
parent | d934d0551ccac008463c4bd2ca104116d80f4230 (diff) |
[android] Modified implicit receivers for lollipop or later
Diffstat (limited to 'android/src/com/mapswithme/maps')
7 files changed, 321 insertions, 59 deletions
diff --git a/android/src/com/mapswithme/maps/MwmActivity.java b/android/src/com/mapswithme/maps/MwmActivity.java index 6a8e7ec79d..5cc77f7ae4 100644 --- a/android/src/com/mapswithme/maps/MwmActivity.java +++ b/android/src/com/mapswithme/maps/MwmActivity.java @@ -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 diff --git a/android/src/com/mapswithme/maps/MwmApplication.java b/android/src/com/mapswithme/maps/MwmApplication.java index 58bf9e8def..98437deb5c 100644 --- a/android/src/com/mapswithme/maps/MwmApplication.java +++ b/android/src/com/mapswithme/maps/MwmApplication.java @@ -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); + } + } + } } diff --git a/android/src/com/mapswithme/maps/background/NotificationService.java b/android/src/com/mapswithme/maps/background/NotificationService.java index 8f38da99ae..109e701d33 100644 --- a/android/src/com/mapswithme/maps/background/NotificationService.java +++ b/android/src/com/mapswithme/maps/background/NotificationService.java @@ -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() diff --git a/android/src/com/mapswithme/maps/location/TrackRecorder.java b/android/src/com/mapswithme/maps/location/TrackRecorder.java index fdfac4b6f3..3e9c71076e 100644 --- a/android/src/com/mapswithme/maps/location/TrackRecorder.java +++ b/android/src/com/mapswithme/maps/location/TrackRecorder.java @@ -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() diff --git a/android/src/com/mapswithme/maps/scheduling/JobDispatcher.java b/android/src/com/mapswithme/maps/scheduling/JobDispatcher.java new file mode 100644 index 0000000000..68ffd2d5d7 --- /dev/null +++ b/android/src/com/mapswithme/maps/scheduling/JobDispatcher.java @@ -0,0 +1,7 @@ +package com.mapswithme.maps.scheduling; + +public interface JobDispatcher +{ + void dispatch(); + void cancelAll(); +} diff --git a/android/src/com/mapswithme/maps/scheduling/JobDispatcherComposite.java b/android/src/com/mapswithme/maps/scheduling/JobDispatcherComposite.java new file mode 100644 index 0000000000..4a28a58f28 --- /dev/null +++ b/android/src/com/mapswithme/maps/scheduling/JobDispatcherComposite.java @@ -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); + } + } +} diff --git a/android/src/com/mapswithme/maps/scheduling/NativeJobService.java b/android/src/com/mapswithme/maps/scheduling/NativeJobService.java new file mode 100644 index 0000000000..09c137726f --- /dev/null +++ b/android/src/com/mapswithme/maps/scheduling/NativeJobService.java @@ -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; + } +} |