diff --git a/android/jni/Android.mk b/android/jni/Android.mk index f51beee1b2..548b1d2eb1 100644 --- a/android/jni/Android.mk +++ b/android/jni/Android.mk @@ -110,6 +110,7 @@ LOCAL_SRC_FILES := \ com/mapswithme/util/HttpClient.cpp \ com/mapswithme/util/StringUtils.cpp \ com/mapswithme/util/statistics/PushwooshHelper.cpp \ + com/mapswithme/util/NetworkPolicy.cpp \ LOCAL_LDLIBS := -llog -landroid -lEGL -lGLESv2 -latomic -lz diff --git a/android/jni/com/mapswithme/maps/Framework.cpp b/android/jni/com/mapswithme/maps/Framework.cpp index 31c3284f1e..b2378c3909 100644 --- a/android/jni/com/mapswithme/maps/Framework.cpp +++ b/android/jni/com/mapswithme/maps/Framework.cpp @@ -12,10 +12,10 @@ #include "storage/storage_helpers.hpp" -#include "drape_frontend/visual_params.hpp" -#include "drape_frontend/user_event_stream.hpp" #include "drape/pointers.hpp" #include "drape/visual_scale.hpp" +#include "drape_frontend/user_event_stream.hpp" +#include "drape_frontend/visual_params.hpp" #include "coding/file_container.hpp" #include "coding/file_name_utils.hpp" @@ -32,18 +32,21 @@ #include "platform/preferred_languages.hpp" #include "platform/settings.hpp" -#include "base/math.hpp" #include "base/logging.hpp" +#include "base/math.hpp" #include "base/sunrise_sunset.hpp" +#include "../util/NetworkPolicy.hpp" + android::Framework * g_framework = 0; +using network_policy::GetNetworkPolicyStatus; + namespace platform { -// Dummy, implementation and location should be chosen by android developer. -NetworkPolicy ToNativeNetworkPolicy(jobject obj) +NetworkPolicy ToNativeNetworkPolicy(JNIEnv * env, jobject obj) { - return NetworkPolicy(true); + return NetworkPolicy(GetNetworkPolicyStatus(env, obj)); } } // namespace platform @@ -507,22 +510,20 @@ place_page::Info & Framework::GetPlacePageInfo() { return m_info; } - -void Framework::RequestBookingMinPrice(string const & hotelId, string const & currencyCode, function const & callback) +void Framework::RequestBookingMinPrice( + JNIEnv * env, jobject policy, string const & hotelId, string const & currencyCode, + function const & callback) { - // Stub obj must be changed. - jobject obj; - auto const bookingApi = m_work.GetBookingApi(ToNativeNetworkPolicy(obj)); + auto const bookingApi = m_work.GetBookingApi(ToNativeNetworkPolicy(env, policy)); if (bookingApi) bookingApi->GetMinPrice(hotelId, currencyCode, callback); } -void Framework::RequestBookingInfo(string const & hotelId, string const & lang, +void Framework::RequestBookingInfo(JNIEnv * env, jobject policy, string const & hotelId, + string const & lang, function const & callback) { - // Stub obj must be changed. - jobject obj; - auto const bookingApi = m_work.GetBookingApi(ToNativeNetworkPolicy(obj)); + auto const bookingApi = m_work.GetBookingApi(ToNativeNetworkPolicy(env, policy)); if (bookingApi) bookingApi->GetHotelInfo(hotelId, lang, callback); } @@ -557,14 +558,12 @@ void Framework::EnableDownloadOn3g() { m_work.GetDownloadingPolicy().EnableCellularDownload(true); } - -uint64_t Framework::RequestUberProducts(ms::LatLon const & from, ms::LatLon const & to, +uint64_t Framework::RequestUberProducts(JNIEnv * env, jobject policy, ms::LatLon const & from, + ms::LatLon const & to, uber::ProductsCallback const & callback, uber::ErrorCallback const & errorCallback) { - // Stub obj must be changed. - jobject obj; - auto const uberApi = m_work.GetUberApi(ToNativeNetworkPolicy(obj)); + auto const uberApi = m_work.GetUberApi(ToNativeNetworkPolicy(env, policy)); if (!uberApi) return 0; diff --git a/android/jni/com/mapswithme/maps/Framework.hpp b/android/jni/com/mapswithme/maps/Framework.hpp index a6e0f32483..9fa45ddc7a 100644 --- a/android/jni/com/mapswithme/maps/Framework.hpp +++ b/android/jni/com/mapswithme/maps/Framework.hpp @@ -162,8 +162,11 @@ namespace android void SetPlacePageInfo(place_page::Info const & info); place_page::Info & GetPlacePageInfo(); - void RequestBookingMinPrice(string const & hotelId, string const & currency, function const & callback); - void RequestBookingInfo(string const & hotelId, string const & lang, + void RequestBookingMinPrice(JNIEnv * env, jobject policy, string const & hotelId, + string const & currency, + function const & callback); + void RequestBookingInfo(JNIEnv * env, jobject policy, string const & hotelId, + string const & lang, function const & callback); bool HasSpaceForMigration(); @@ -175,8 +178,8 @@ namespace android bool IsDownloadOn3gEnabled(); void EnableDownloadOn3g(); - uint64_t RequestUberProducts(ms::LatLon const & from, ms::LatLon const & to, - uber::ProductsCallback const & callback, + uint64_t RequestUberProducts(JNIEnv * env, jobject policy, ms::LatLon const & from, + ms::LatLon const & to, uber::ProductsCallback const & callback, uber::ErrorCallback const & errorCallback); static uber::RideRequestLinks GetUberLinks(string const & productId, ms::LatLon const & from, ms::LatLon const & to); }; diff --git a/android/jni/com/mapswithme/maps/Sponsored.cpp b/android/jni/com/mapswithme/maps/Sponsored.cpp index ac8bb04fc5..76578faea1 100644 --- a/android/jni/com/mapswithme/maps/Sponsored.cpp +++ b/android/jni/com/mapswithme/maps/Sponsored.cpp @@ -93,70 +93,73 @@ JNIEXPORT jobject JNICALL Java_com_mapswithme_maps_widget_placepage_Sponsored_na // static void nativeRequestPrice(String id, String currencyCode); JNIEXPORT void JNICALL Java_com_mapswithme_maps_widget_placepage_Sponsored_nativeRequestPrice( - JNIEnv * env, jclass clazz, jstring id, jstring currencyCode) + JNIEnv * env, jclass clazz, jobject policy, jstring id, jstring currencyCode) { PrepareClassRefs(env, clazz); string const hotelId = jni::ToNativeString(env, id); string const code = jni::ToNativeString(env, currencyCode); - g_framework->RequestBookingMinPrice(hotelId, code, [hotelId](string const & price, - string const & currency) { - GetPlatform().RunOnGuiThread([=]() { - JNIEnv * env = jni::GetEnv(); - env->CallStaticVoidMethod(g_sponsoredClass, g_priceCallback, jni::ToJavaString(env, hotelId), - jni::ToJavaString(env, price), jni::ToJavaString(env, currency)); - }); - }); + g_framework->RequestBookingMinPrice( + env, policy, hotelId, code, [hotelId](string const & price, string const & currency) { + GetPlatform().RunOnGuiThread([=]() { + JNIEnv * env = jni::GetEnv(); + env->CallStaticVoidMethod(g_sponsoredClass, g_priceCallback, + jni::ToJavaString(env, hotelId), jni::ToJavaString(env, price), + jni::ToJavaString(env, currency)); + }); + }); } // static void nativeRequestInfo(String id, String locale); JNIEXPORT void JNICALL Java_com_mapswithme_maps_widget_placepage_Sponsored_nativeRequestHotelInfo( - JNIEnv * env, jclass clazz, jstring id, jstring locale) + JNIEnv * env, jclass clazz, jobject policy, jstring id, jstring locale) { PrepareClassRefs(env, clazz); string const hotelId = jni::ToNativeString(env, id); string const code = jni::ToNativeString(env, locale); - g_framework->RequestBookingInfo(hotelId, code, [hotelId]( - BookingApi::HotelInfo const & hotelInfo) { - GetPlatform().RunOnGuiThread([=]() { - JNIEnv * env = jni::GetEnv(); + g_framework->RequestBookingInfo( + env, policy, hotelId, code, [hotelId](BookingApi::HotelInfo const & hotelInfo) { + GetPlatform().RunOnGuiThread([=]() { + JNIEnv * env = jni::GetEnv(); - auto description = jni::ToJavaString(env, hotelInfo.m_description); - auto photos = - jni::ToJavaArray(env, g_imageClass, hotelInfo.m_photos, - [](JNIEnv * env, BookingApi::HotelPhotoUrls const & item) { - return env->NewObject(g_imageClass, g_imageConstructor, - jni::ToJavaString(env, item.m_original), - jni::ToJavaString(env, item.m_small)); - }); - auto facilities = - jni::ToJavaArray(env, g_facilityTypeClass, hotelInfo.m_facilities, - [](JNIEnv * env, BookingApi::Facility const & item) { - return env->NewObject(g_facilityTypeClass, g_facilityConstructor, + auto description = jni::ToJavaString(env, hotelInfo.m_description); + auto photos = + jni::ToJavaArray(env, g_imageClass, hotelInfo.m_photos, + [](JNIEnv * env, BookingApi::HotelPhotoUrls const & item) { + return env->NewObject(g_imageClass, g_imageConstructor, + jni::ToJavaString(env, item.m_original), + jni::ToJavaString(env, item.m_small)); + }); + auto facilities = jni::ToJavaArray(env, g_facilityTypeClass, hotelInfo.m_facilities, + [](JNIEnv * env, BookingApi::Facility const & item) { + return env->NewObject( + g_facilityTypeClass, g_facilityConstructor, jni::ToJavaString(env, item.m_id), jni::ToJavaString(env, item.m_localizedName)); - }); - auto reviews = jni::ToJavaArray( - env, g_reviewClass, hotelInfo.m_reviews, - [](JNIEnv * env, BookingApi::HotelReview const & item) { - return env->NewObject( - g_reviewClass, g_reviewConstructor, jni::ToJavaString(env, item.m_reviewNeutral), - jni::ToJavaString(env, item.m_reviewPositive), - jni::ToJavaString(env, item.m_reviewNegative), - jni::ToJavaString(env, item.m_author), jni::ToJavaString(env, item.m_authorPictUrl), - item.m_rating, - time_point_cast(item.m_date).time_since_epoch().count()); - }); - auto nearby = env->NewObjectArray(0, g_nearbyObjectClass, 0); + }); + auto reviews = jni::ToJavaArray( + env, g_reviewClass, hotelInfo.m_reviews, + [](JNIEnv * env, BookingApi::HotelReview const & item) { + return env->NewObject( + g_reviewClass, g_reviewConstructor, + jni::ToJavaString(env, item.m_reviewNeutral), + jni::ToJavaString(env, item.m_reviewPositive), + jni::ToJavaString(env, item.m_reviewNegative), + jni::ToJavaString(env, item.m_author), + jni::ToJavaString(env, item.m_authorPictUrl), item.m_rating, + time_point_cast(item.m_date).time_since_epoch().count()); + }); + auto nearby = env->NewObjectArray(0, g_nearbyObjectClass, 0); - env->CallStaticVoidMethod(g_sponsoredClass, g_infoCallback, jni::ToJavaString(env, hotelId), - env->NewObject(g_hotelInfoClass, g_hotelInfoConstructor, - description, photos, facilities, reviews, nearby)); - }); - }); + env->CallStaticVoidMethod( + g_sponsoredClass, g_infoCallback, jni::ToJavaString(env, hotelId), + env->NewObject(g_hotelInfoClass, g_hotelInfoConstructor, description, photos, + facilities, reviews, nearby)); + }); + }); } } // extern "C" diff --git a/android/jni/com/mapswithme/maps/uber/Uber.cpp b/android/jni/com/mapswithme/maps/uber/Uber.cpp index e9aba7a63b..6cb45241ab 100644 --- a/android/jni/com/mapswithme/maps/uber/Uber.cpp +++ b/android/jni/com/mapswithme/maps/uber/Uber.cpp @@ -95,14 +95,16 @@ void OnUberError(uber::ErrorCode const code, uint64_t const requestId) extern "C" { JNIEXPORT void JNICALL Java_com_mapswithme_maps_uber_Uber_nativeRequestUberProducts( - JNIEnv * env, jclass clazz, jdouble srcLat, jdouble srcLon, jdouble dstLat, jdouble dstLon) + JNIEnv * env, jclass clazz, jobject policy, jdouble srcLat, jdouble srcLon, jdouble dstLat, + jdouble dstLon) { PrepareClassRefs(env); ms::LatLon const from(srcLat, srcLon); ms::LatLon const to(dstLat, dstLon); - g_lastRequestId = g_framework->RequestUberProducts(from, to, &OnUberInfoReceived, &OnUberError); + g_lastRequestId = + g_framework->RequestUberProducts(env, policy, from, to, &OnUberInfoReceived, &OnUberError); } JNIEXPORT jobject JNICALL Java_com_mapswithme_maps_uber_Uber_nativeGetUberLinks( diff --git a/android/jni/com/mapswithme/util/NetworkPolicy.cpp b/android/jni/com/mapswithme/util/NetworkPolicy.cpp new file mode 100644 index 0000000000..beba28424a --- /dev/null +++ b/android/jni/com/mapswithme/util/NetworkPolicy.cpp @@ -0,0 +1,10 @@ +#include "com/mapswithme/core/jni_helper.hpp" + +namespace network_policy +{ +bool GetNetworkPolicyStatus(JNIEnv * env, jobject obj) +{ + const jmethodID networkPolicyCanUseMethod = jni::GetMethodID(env, obj, "isCanUseNetwork", "()Z"); + return env->CallBooleanMethod(obj, networkPolicyCanUseMethod); +} +} // namespace network_policy diff --git a/android/jni/com/mapswithme/util/NetworkPolicy.hpp b/android/jni/com/mapswithme/util/NetworkPolicy.hpp new file mode 100644 index 0000000000..9e273d08c5 --- /dev/null +++ b/android/jni/com/mapswithme/util/NetworkPolicy.hpp @@ -0,0 +1,6 @@ +#pragma once + +namespace network_policy +{ +bool GetNetworkPolicyStatus(JNIEnv * env, jobject obj); +} diff --git a/android/res/values/donottranslate.xml b/android/res/values/donottranslate.xml index 174a59b096..247f0117cb 100644 --- a/android/res/values/donottranslate.xml +++ b/android/res/values/donottranslate.xml @@ -50,6 +50,7 @@ Osm profile AutoZoom LargeFontSize + UseMobileData %1$s: %2$s %2$s :%1$s diff --git a/android/res/values/string-arrays.xml b/android/res/values/string-arrays.xml index 92230801e6..d722f25a1c 100644 --- a/android/res/values/string-arrays.xml +++ b/android/res/values/string-arrays.xml @@ -41,4 +41,18 @@ 12 24 + + + @string/mobile_data_option_ask + @string/mobile_data_option_always + @string/mobile_data_option_never + @string/mobile_data_option_not_today + + + + 0 + 1 + 2 + 3 + \ No newline at end of file diff --git a/android/res/xml-v21/prefs_misc.xml b/android/res/xml-v21/prefs_misc.xml index 9f06bc4511..b9eabbd3ec 100644 --- a/android/res/xml-v21/prefs_misc.xml +++ b/android/res/xml-v21/prefs_misc.xml @@ -30,4 +30,11 @@ android:defaultValue="false" android:switchTextOff="" android:switchTextOn=""/> + + diff --git a/android/res/xml/prefs_misc.xml b/android/res/xml/prefs_misc.xml index 6232e284b9..7e50633223 100644 --- a/android/res/xml/prefs_misc.xml +++ b/android/res/xml/prefs_misc.xml @@ -19,7 +19,14 @@ android:defaultValue="true"/> + + diff --git a/android/src/com/mapswithme/maps/routing/RoutingController.java b/android/src/com/mapswithme/maps/routing/RoutingController.java index 67e9921ec4..bb876d4936 100644 --- a/android/src/com/mapswithme/maps/routing/RoutingController.java +++ b/android/src/com/mapswithme/maps/routing/RoutingController.java @@ -26,6 +26,7 @@ import com.mapswithme.maps.uber.UberInfo; import com.mapswithme.maps.uber.UberLinks; import com.mapswithme.util.Config; import com.mapswithme.util.ConnectionState; +import com.mapswithme.util.NetworkPolicy; import com.mapswithme.util.StringUtils; import com.mapswithme.util.ThemeSwitcher; import com.mapswithme.util.Utils; @@ -283,7 +284,8 @@ public class RoutingController completeUberRequest(); return; } - requestUberInfo(); + if (mContainer != null) + requestUberInfo(mContainer.getActivity()); } setBuildState(BuildState.BUILDING); @@ -828,13 +830,21 @@ public class RoutingController return true; } - private void requestUberInfo() + private void requestUberInfo(@NonNull Context context) { - mUberPlanning = true; - Uber.nativeRequestUberProducts(mStartPoint.getLat(), mStartPoint.getLon(), - mEndPoint.getLat(), mEndPoint.getLon()); - if (mContainer != null) - mContainer.updateBuildProgress(0, mLastRouterType); + NetworkPolicy.checkNetworkPolicy(context, new NetworkPolicy.NetworkPolicyListener() + { + @Override + public void onResult(@NonNull NetworkPolicy policy) + { + mUberPlanning = true; + Uber.nativeRequestUberProducts(policy, mStartPoint.getLat(), + mStartPoint.getLon(), + mEndPoint.getLat(), mEndPoint.getLon()); + if (mContainer != null) + mContainer.updateBuildProgress(0, mLastRouterType); + } + }); } @NonNull diff --git a/android/src/com/mapswithme/maps/settings/MiscPrefsFragment.java b/android/src/com/mapswithme/maps/settings/MiscPrefsFragment.java index 26a45a6906..b48c1f441b 100644 --- a/android/src/com/mapswithme/maps/settings/MiscPrefsFragment.java +++ b/android/src/com/mapswithme/maps/settings/MiscPrefsFragment.java @@ -1,6 +1,7 @@ package com.mapswithme.maps.settings; import android.os.Bundle; +import android.preference.ListPreference; import android.preference.Preference; import android.preference.TwoStatePreference; @@ -12,6 +13,8 @@ import com.mapswithme.maps.location.LocationHelper; import com.mapswithme.maps.search.SearchFragment; import com.mapswithme.util.Config; import com.mapswithme.util.log.LoggerFactory; +import com.mapswithme.util.NetworkPolicy; +import com.mapswithme.util.concurrency.UiThread; import com.mapswithme.util.statistics.MytargetHelper; import com.mapswithme.util.statistics.Statistics; @@ -91,5 +94,47 @@ public class MiscPrefsFragment extends BaseXmlSettingsFragment } }); } + + int curValue = Config.getUseMobileDataSettings(); + final ListPreference mobilePref = (ListPreference)findPreference( + getString(R.string.pref_use_mobile_data)); + mobilePref.setValue(String.valueOf(curValue)); + mobilePref.setSummary(mobilePref.getEntry()); + mobilePref.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() + { + @Override + public boolean onPreferenceChange(Preference preference, Object newValue) + { + String valueStr = (String)newValue; + switch (Integer.parseInt(valueStr)) + { + case NetworkPolicy.ASK: + Config.setUseMobileDataSettings(NetworkPolicy.ASK); + break; + case NetworkPolicy.ALWAYS: + Config.setUseMobileDataSettings(NetworkPolicy.ALWAYS); + break; + case NetworkPolicy.NEVER: + Config.setUseMobileDataSettings(NetworkPolicy.NEVER); + break; + case NetworkPolicy.NOT_TODAY: + Config.setUseMobileDataSettings(NetworkPolicy.NOT_TODAY); + break; + default: + throw new AssertionError("Wrong NetworkPolicy type!"); + } + + UiThread.runLater(new Runnable() + { + @Override + public void run() + { + mobilePref.setSummary(mobilePref.getEntry()); + } + }); + + return true; + } + }); } } diff --git a/android/src/com/mapswithme/maps/uber/Uber.java b/android/src/com/mapswithme/maps/uber/Uber.java index 9ef688e812..19dcdfc8ff 100644 --- a/android/src/com/mapswithme/maps/uber/Uber.java +++ b/android/src/com/mapswithme/maps/uber/Uber.java @@ -2,9 +2,12 @@ package com.mapswithme.maps.uber; import android.support.annotation.NonNull; +import com.mapswithme.util.NetworkPolicy; + public class Uber { - public static native void nativeRequestUberProducts(double srcLat, double srcLon, double dstLat, double dstLon); + public static native void nativeRequestUberProducts(@NonNull NetworkPolicy policy, double srcLat, + double srcLon, double dstLat, double dstLon); @NonNull public static native UberLinks nativeGetUberLinks(@NonNull String productId, double srcLon, double srcLat, diff --git a/android/src/com/mapswithme/maps/widget/placepage/PlacePageView.java b/android/src/com/mapswithme/maps/widget/placepage/PlacePageView.java index 77698e53aa..50b7b66412 100644 --- a/android/src/com/mapswithme/maps/widget/placepage/PlacePageView.java +++ b/android/src/com/mapswithme/maps/widget/placepage/PlacePageView.java @@ -885,11 +885,11 @@ public class PlacePageView extends RelativeLayout Locale locale = Locale.getDefault(); Currency currency = Currency.getInstance(locale); - if (mSponsored.getType() == Sponsored.TYPE_BOOKING) - Sponsored.requestPrice(mSponsored.getId(), currency.getCurrencyCode()); + if (mSponsored.getType() == Sponsored.TYPE_BOOKING && mSponsored.getId() != null) + Sponsored.requestPrice(getContext(), mSponsored.getId(), currency.getCurrencyCode()); // TODO: remove this after booking_api.cpp will be done if (!USE_OLD_BOOKING) - Sponsored.requestInfo(mSponsored, locale.toString()); + Sponsored.requestInfo(getContext(), mSponsored, locale.toString()); } String country = MapManager.nativeGetSelectedCountry(); diff --git a/android/src/com/mapswithme/maps/widget/placepage/Sponsored.java b/android/src/com/mapswithme/maps/widget/placepage/Sponsored.java index 61296a9dce..5030ad7a21 100644 --- a/android/src/com/mapswithme/maps/widget/placepage/Sponsored.java +++ b/android/src/com/mapswithme/maps/widget/placepage/Sponsored.java @@ -1,5 +1,6 @@ package com.mapswithme.maps.widget.placepage; +import android.content.Context; import android.support.annotation.IntDef; import android.support.annotation.NonNull; import android.support.annotation.Nullable; @@ -10,6 +11,7 @@ import com.mapswithme.maps.bookmarks.data.MapObject; import com.mapswithme.maps.bookmarks.data.Metadata; import com.mapswithme.maps.gallery.Image; import com.mapswithme.maps.review.Review; +import com.mapswithme.util.NetworkPolicy; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -265,17 +267,26 @@ public final class Sponsored * @param id A Hotel id * @param currencyCode A user currency */ - static void requestPrice(String id, String currencyCode) + static void requestPrice(@NonNull Context context, @NonNull final String id, + @NonNull final String currencyCode) { Price p = sPriceCache.get(id); if (p != null) onPriceReceived(id, p.mPrice, p.mCurrency); - nativeRequestPrice(id, currencyCode); + NetworkPolicy.checkNetworkPolicy(context, new NetworkPolicy.NetworkPolicyListener() + { + @Override + public void onResult(@NonNull NetworkPolicy policy) + { + nativeRequestPrice(policy, id, currencyCode); + } + }); } - static void requestInfo(Sponsored sponsored, String locale) + static void requestInfo(@NonNull Context context, @NonNull Sponsored sponsored, + @NonNull String locale) { String id = sponsored.getId(); if (id == null) @@ -284,7 +295,7 @@ public final class Sponsored switch (sponsored.getType()) { case TYPE_BOOKING: - requestHotelInfo(id, locale); + requestHotelInfo(context, id, locale); break; case TYPE_GEOCHAT: // TODO: request geochat info @@ -305,13 +316,21 @@ public final class Sponsored * @param id A Hotel id * @param locale A user locale */ - private static void requestHotelInfo(String id, String locale) + private static void requestHotelInfo(@NonNull Context context, @NonNull final String id, + @NonNull final String locale) { HotelInfo info = sInfoCache.get(id); if (info != null) onHotelInfoReceived(id, info); - nativeRequestHotelInfo(id, locale); + NetworkPolicy.checkNetworkPolicy(context, new NetworkPolicy.NetworkPolicyListener() + { + @Override + public void onResult(@NonNull NetworkPolicy policy) + { + nativeRequestHotelInfo(policy, id, locale); + } + }); } private static void onPriceReceived(@NonNull String id, @NonNull String price, @@ -340,7 +359,9 @@ public final class Sponsored @Nullable public static native Sponsored nativeGetCurrent(); - private static native void nativeRequestPrice(@NonNull String id, @NonNull String currencyCode); + private static native void nativeRequestPrice(@NonNull NetworkPolicy policy, + @NonNull String id, @NonNull String currencyCode); - private static native void nativeRequestHotelInfo(@NonNull String id, @NonNull String locale); + private static native void nativeRequestHotelInfo(@NonNull NetworkPolicy policy, + @NonNull String id, @NonNull String locale); } diff --git a/android/src/com/mapswithme/util/Config.java b/android/src/com/mapswithme/util/Config.java index 7ae904bcdc..adaa81cfd2 100644 --- a/android/src/com/mapswithme/util/Config.java +++ b/android/src/com/mapswithme/util/Config.java @@ -34,6 +34,8 @@ public final class Config private static final String KEY_MISC_FIRST_START_DIALOG_SEEN = "FirstStartDialogSeen"; private static final String KEY_MISC_UI_THEME = "UiTheme"; private static final String KEY_MISC_UI_THEME_SETTINGS = "UiThemeSettings"; + private static final String KEY_MISC_USE_MOBILE_DATA = "UseMobileData"; + private static final String KEY_MISC_NOT_TODAY_TIMESTAMP = "NotTodayTimestamp"; private Config() {} @@ -355,6 +357,39 @@ public final class Config nativeSetLargeFontsSize(value); } + @NetworkPolicy.NetworkPolicyDef + public static int getUseMobileDataSettings() + { + switch(getInt(KEY_MISC_USE_MOBILE_DATA, NetworkPolicy.ASK)) + { + case NetworkPolicy.ASK: + return NetworkPolicy.ASK; + case NetworkPolicy.ALWAYS: + return NetworkPolicy.ALWAYS; + case NetworkPolicy.NEVER: + return NetworkPolicy.NEVER; + case NetworkPolicy.NOT_TODAY: + return NetworkPolicy.NOT_TODAY; + } + + throw new AssertionError("Wrong NetworkPolicy type!"); + } + + public static void setUseMobileDataSettings(@NetworkPolicy.NetworkPolicyDef int value) + { + setInt(KEY_MISC_USE_MOBILE_DATA, value); + } + + static void setNotTodayStamp(long timestamp) + { + setLong(KEY_MISC_NOT_TODAY_TIMESTAMP, timestamp); + } + + static long getNotTodayTimeStamp() + { + return getLong(KEY_MISC_NOT_TODAY_TIMESTAMP, 0L); + } + private static native boolean nativeGetBoolean(String name, boolean defaultValue); private static native void nativeSetBoolean(String name, boolean value); private static native int nativeGetInt(String name, int defaultValue); diff --git a/android/src/com/mapswithme/util/NetworkPolicy.java b/android/src/com/mapswithme/util/NetworkPolicy.java new file mode 100644 index 0000000000..6a6c3816f8 --- /dev/null +++ b/android/src/com/mapswithme/util/NetworkPolicy.java @@ -0,0 +1,114 @@ +package com.mapswithme.util; + +import android.content.Context; +import android.content.DialogInterface; +import android.support.annotation.IntDef; +import android.support.annotation.NonNull; +import android.support.v7.app.AlertDialog; + +import com.mapswithme.maps.R; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.util.concurrent.TimeUnit; + +public final class NetworkPolicy +{ + public static final int ASK = 0; + public static final int ALWAYS = 1; + public static final int NEVER = 2; + public static final int NOT_TODAY = 3; + + @Retention(RetentionPolicy.SOURCE) + @IntDef({ ASK, ALWAYS, NEVER, NOT_TODAY}) + @interface NetworkPolicyDef {} + + public static void checkNetworkPolicy(@NonNull Context context, + @NonNull final NetworkPolicyListener listener) + { + if (ConnectionState.isWifiConnected()) + { + listener.onResult(new NetworkPolicy(true)); + return; + } + + if (!ConnectionState.isMobileConnected()) + { + listener.onResult(new NetworkPolicy(false)); + return; + } + + int type = Config.getUseMobileDataSettings(); + switch (type) + { + case ASK: + showDialog(context, listener); + break; + case ALWAYS: + listener.onResult(new NetworkPolicy(true)); + break; + case NEVER: + listener.onResult(new NetworkPolicy(false)); + break; + case NOT_TODAY: + long timestamp = Config.getNotTodayTimeStamp(); + boolean showDialog = TimeUnit.MILLISECONDS.toDays(System.currentTimeMillis() - timestamp) >= 1; + if (!showDialog) + { + listener.onResult(new NetworkPolicy(false)); + return; + } + showDialog(context, listener); + break; + } + } + + private static void showDialog(@NonNull Context context, @NonNull final NetworkPolicyListener listener) + { + AlertDialog alertDialog = new AlertDialog.Builder(context).create(); + alertDialog.setTitle(R.string.mobile_data_dialog); + alertDialog.setMessage(context.getString(R.string.mobile_data_description)); + alertDialog.setCancelable(false); + alertDialog.setButton(AlertDialog.BUTTON_NEGATIVE, + context.getString(R.string.mobile_data_option_not_today), + new DialogInterface.OnClickListener() + { + @Override + public void onClick(DialogInterface dialog, int which) + { + Config.setUseMobileDataSettings(NOT_TODAY); + Config.setNotTodayStamp(System.currentTimeMillis()); + listener.onResult(new NetworkPolicy(false)); + } + }); + alertDialog.setButton(AlertDialog.BUTTON_POSITIVE, + context.getString(R.string.mobile_data_option_always), + new DialogInterface.OnClickListener() + { + @Override + public void onClick(DialogInterface dialog, int which) + { + Config.setUseMobileDataSettings(ALWAYS); + listener.onResult(new NetworkPolicy(true)); + } + }); + alertDialog.show(); + } + + private final boolean mCanUseNetwork; + + private NetworkPolicy(boolean canUse) + { + mCanUseNetwork = canUse; + } + + public boolean isCanUseNetwork() + { + return mCanUseNetwork; + } + + public interface NetworkPolicyListener + { + void onResult(@NonNull NetworkPolicy policy); + } +} diff --git a/platform/network_policy.hpp b/platform/network_policy.hpp index e48ad3daa9..f69387f8da 100644 --- a/platform/network_policy.hpp +++ b/platform/network_policy.hpp @@ -3,7 +3,9 @@ #include "std/function.hpp" class _jobject; +class _JNIEnv; typedef _jobject * jobject; +typedef _JNIEnv JNIEnv; namespace platform { @@ -22,7 +24,7 @@ namespace platform class NetworkPolicy { // Maker for android. - friend NetworkPolicy ToNativeNetworkPolicy(jobject obj); + friend NetworkPolicy ToNativeNetworkPolicy(JNIEnv * env, jobject obj); // iOS friend void network_policy::CallPartnersApi(platform::PartnersApiFn fn, bool force);