Merge pull request #4564 from alexzatsepin/MAPSME-2794-handle-uber-errors

[android] Mapsme 2794 handle uber errors
This commit is contained in:
Arsentiy Milchakov 2016-10-31 15:20:41 +03:00 committed by GitHub
commit dad7cd66b0
70 changed files with 509 additions and 142 deletions

View file

@ -31,8 +31,8 @@ apply plugin: 'io.fabric'
dependencies {
// android support libs
compile 'com.android.support:support-v4:22.2.1'
compile 'com.android.support:appcompat-v7:22.2.1'
compile 'com.android.support:support-v4:23.0.0'
compile 'com.android.support:appcompat-v7:23.0.0'
compile 'com.android.support:recyclerview-v7:22.2.1'
compile 'com.android.support:design:22.2.1'
compile 'com.android.support:cardview-v7:22.2.1'
@ -78,7 +78,7 @@ crashlytics {
android {
// All properties are read from gradle.properties file
compileSdkVersion propTargetSdkVersion.toInteger()
compileSdkVersion propCompileSdkVersion.toInteger()
buildToolsVersion propBuildToolsVersion
defaultConfig {

View file

@ -2,11 +2,13 @@ propMinSdkVersion=15
# TODO use 23 target and build tools version, when ProGuard problem will be fixed
# https://code.google.com/p/android/issues/detail?id=184567
propTargetSdkVersion=22
propCompileSdkVersion=23
propBuildToolsVersion=22.0.1
propVersionCode=650
propVersionName=6.5.0
propDebugNdkFlags=V=1 NDK_DEBUG=1 DEBUG=1
propReleaseNdkFlags=V=1 NDK_DEBUG=0 PRODUCTION=1
org.gradle.daemon=true
# list of files for obb-s
propObbFonts ../data/01_dejavusans.ttf \

View file

@ -514,9 +514,9 @@ void Framework::EnableDownloadOn3g()
}
uint64_t Framework::RequestUberProducts(ms::LatLon const & from, ms::LatLon const & to,
uber::ProductsCallback const & callback)
uber::ProductsCallback const & callback,
uber::ErrorCallback const & errorCallback)
{
auto const errorCallback = [](uber::ErrorCode const code, uint64_t const requestId) {};
return m_work.GetUberApi().GetAvailableProducts(from, to, callback, errorCallback);
}

View file

@ -167,7 +167,9 @@ namespace android
bool IsDownloadOn3gEnabled();
void EnableDownloadOn3g();
uint64_t RequestUberProducts(ms::LatLon const & from, ms::LatLon const & to, uber::ProductsCallback const & callback);
uint64_t RequestUberProducts(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);
};
}

View file

@ -14,6 +14,7 @@ jobject g_routingControllerInstance;
jmethodID g_productConstructor;
jmethodID g_routingControllerGetMethod;
jmethodID g_uberInfoCallbackMethod;
jmethodID g_uberErrorCallbackMethod;
jclass g_uberLinksClass;
jmethodID g_uberLinksConstructor;
uint64_t g_lastRequestId;
@ -38,12 +39,57 @@ void PrepareClassRefs(JNIEnv * env)
g_uberInfoCallbackMethod =
jni::GetMethodID(env, g_routingControllerInstance, "onUberInfoReceived",
"(Lcom/mapswithme/maps/uber/UberInfo;)V");
g_uberErrorCallbackMethod = jni::GetMethodID(env, g_routingControllerInstance,
"onUberError", "(Ljava/lang/String;)V");
g_uberInfoConstructor = jni::GetConstructorID(env, g_uberInfoClass,
"([Lcom/mapswithme/maps/uber/UberInfo$Product;)V");
g_uberLinksClass = jni::GetGlobalClassRef(env, "com/mapswithme/maps/uber/UberLinks");
g_uberLinksConstructor =
jni::GetConstructorID(env, g_uberLinksClass, "(Ljava/lang/String;Ljava/lang/String;)V");
}
void OnUberInfoReceived(vector<uber::Product> const & products, uint64_t const requestId)
{
GetPlatform().RunOnGuiThread([=]() {
if (g_lastRequestId != requestId)
return;
CHECK(!products.empty(), ("List of the products cannot be empty"));
JNIEnv * env = jni::GetEnv();
auto const uberProducts = jni::ToJavaArray(
env, g_productClass, products, [](JNIEnv * env, uber::Product const & item) {
return env->NewObject(
g_productClass, g_productConstructor, jni::ToJavaString(env, item.m_productId),
jni::ToJavaString(env, item.m_name), jni::ToJavaString(env, item.m_time),
jni::ToJavaString(env, item.m_price));
});
jobject const routingControllerInstance =
env->CallStaticObjectMethod(g_routingControllerClass, g_routingControllerGetMethod);
env->CallVoidMethod(routingControllerInstance, g_uberInfoCallbackMethod,
env->NewObject(g_uberInfoClass, g_uberInfoConstructor, uberProducts));
});
}
void OnUberError(uber::ErrorCode const code, uint64_t const requestId)
{
GetPlatform().RunOnGuiThread([=]() {
if (g_lastRequestId != requestId)
return;
JNIEnv * env = jni::GetEnv();
static jclass const errCodeClass = env->FindClass("com/mapswithme/maps/uber/Uber$ErrorCode");
ASSERT(errCodeClass, ());
jobject const routingControllerInstance =
env->CallStaticObjectMethod(g_routingControllerClass, g_routingControllerGetMethod);
env->CallVoidMethod(routingControllerInstance, g_uberErrorCallbackMethod,
jni::ToJavaString(env, uber::DebugPrint(code)));
});
}
} // namespace
extern "C" {
@ -56,29 +102,7 @@ JNIEXPORT void JNICALL Java_com_mapswithme_maps_uber_Uber_nativeRequestUberProdu
ms::LatLon const from(srcLat, srcLon);
ms::LatLon const to(dstLat, dstLon);
g_lastRequestId = g_framework->RequestUberProducts(
from, to, [](vector<uber::Product> const & products, uint64_t const requestId) {
GetPlatform().RunOnGuiThread([=]() {
if (g_lastRequestId != requestId)
return;
JNIEnv * env = jni::GetEnv();
auto uberProducts = jni::ToJavaArray(
env, g_productClass, products, [](JNIEnv * env, uber::Product const & item) {
return env->NewObject(
g_productClass, g_productConstructor, jni::ToJavaString(env, item.m_productId),
jni::ToJavaString(env, item.m_name), jni::ToJavaString(env, item.m_time),
jni::ToJavaString(env, item.m_price));
});
jobject const routingControllerInstance =
env->CallStaticObjectMethod(g_routingControllerClass, g_routingControllerGetMethod);
env->CallVoidMethod(routingControllerInstance, g_uberInfoCallbackMethod,
env->NewObject(g_uberInfoClass, g_uberInfoConstructor, uberProducts));
});
});
g_lastRequestId = g_framework->RequestUberProducts(from, to, &OnUberInfoReceived, &OnUberError);
}
JNIEXPORT jobject JNICALL Java_com_mapswithme_maps_uber_Uber_nativeGetUberLinks(

View file

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:state_activated="true"
android:color="@color/routing_button_activated_tint"/>
<item
android:state_pressed="true"
android:color="@color/routing_button_pressed_tint"/>
<item
android:color="@color/routing_button_tint"/>
</selector>

View file

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:state_activated="true"
android:color="@color/routing_button_activated_tint_night"/>
<item
android:state_pressed="true"
android:color="@color/routing_button_pressed_tint"/>
<item
android:color="@color/routing_button_tint"/>
</selector>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 682 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 411 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 419 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 464 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 545 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 156 B

After

Width:  |  Height:  |  Size: 305 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 454 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 441 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 432 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 253 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 255 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 305 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 390 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 132 B

After

Width:  |  Height:  |  Size: 162 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 291 B

View file

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="?attr/colorControlHighlight">
<item>
<selector>
<item
android:state_activated="true"
android:drawable="@drawable/routing_toolbar_button_active"/>
<item
android:drawable="@drawable/routing_toolbar_button_normal"/>
</selector>
</item>
</ripple>

View file

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="?attr/colorControlHighlight">
<item>
<selector>
<item
android:state_activated="true"
android:drawable="@drawable/routing_toolbar_button_active"/>
<item
android:drawable="@drawable/routing_toolbar_button_normal_night"/>
</selector>
</item>
</ripple>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 901 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 445 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 440 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 589 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 704 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 156 B

After

Width:  |  Height:  |  Size: 197 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 570 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 667 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 646 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 891 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 247 B

After

Width:  |  Height:  |  Size: 343 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 858 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 916 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 864 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 335 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

View file

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<selector
xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:state_activated="true"
android:drawable="@drawable/routing_toolbar_button_active"/>
<item
android:drawable="@drawable/routing_toolbar_button_normal"/>
</selector>

View file

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval"
android:height="40dp"
android:width="40dp">
<solid android:color="@color/white_primary"/>
</shape>

View file

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<selector
xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:state_activated="true"
android:drawable="@drawable/routing_toolbar_button_active"/>
<item
android:drawable="@drawable/routing_toolbar_button_normal_night"/>
</selector>

View file

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval"
android:height="40dp"
android:width="40dp">
<solid android:color="@color/bg_statusbar"/>
</shape>

View file

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval"
android:height="40dp"
android:width="40dp">
<solid android:color="@color/bg_statusbar_night"/>
</shape>

View file

@ -43,37 +43,88 @@
android:scaleType="center"
tools:src="@drawable/ic_down" />
<LinearLayout
android:id="@+id/progress_frame"
<RadioGroup
android:id="@+id/route_type"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_height="match_parent"
android:layout_centerInParent="true"
android:orientation="horizontal"
tools:background="#80FF0000">
android:orientation="horizontal">
<com.mapswithme.maps.widget.WheelProgressView
android:id="@+id/progress_vehicle"
style="@style/MwmWidget.ProgressWheel.RoutingPlan"
<com.mapswithme.maps.widget.RoutingToolbarButton
android:id="@+id/vehicle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/routing_selector_wheel_margin"
android:layout_marginStart="@dimen/routing_selector_wheel_margin"
android:layout_marginTop="@dimen/routing_selector_wheel_margin"
android:layout_marginBottom="@dimen/routing_selector_wheel_margin"/>
tools:button="@drawable/ic_car"
tools:buttonTint="?colorAccent" />
<com.mapswithme.maps.widget.WheelProgressView
android:id="@+id/progress_bicycle"
style="@style/MwmWidget.ProgressWheel.RoutingPlan"
android:layout_marginTop="@dimen/routing_selector_wheel_margin"
android:layout_marginBottom="@dimen/routing_selector_wheel_margin"
<com.mapswithme.maps.widget.RoutingToolbarButton
android:id="@+id/bicycle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="12dp"
android:layout_marginRight="12dp"/>
android:layout_marginStart="12dp"
android:layout_marginRight="12dp"
android:layout_marginEnd="12dp"
tools:button="@drawable/ic_bike"
tools:buttonTint="?iconTintLight" />
<com.mapswithme.maps.widget.RoutingToolbarButton
android:id="@+id/pedestrian"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="12dp"
android:layout_marginEnd="12dp"
tools:button="@drawable/ic_walk"
tools:buttonTint="?iconTintLight" />
<com.mapswithme.maps.widget.RoutingToolbarButton
android:id="@+id/taxi"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="@dimen/routing_selector_wheel_margin"
android:layout_marginEnd="@dimen/routing_selector_wheel_margin"
tools:button="@drawable/ic_taxi"
tools:buttonTint="?iconTintLight" />
</RadioGroup>
<LinearLayout
android:id="@+id/progress_frame"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="@id/route_type"
android:layout_alignStart="@id/route_type"
android:layout_centerInParent="true"
android:orientation="horizontal"
tools:background="#80FF0000">
<com.mapswithme.maps.widget.WheelProgressView
android:id="@+id/progress_pedestrian"
style="@style/MwmWidget.ProgressWheel.RoutingPlan"
android:layout_marginTop="@dimen/routing_selector_wheel_margin"
android:layout_marginBottom="@dimen/routing_selector_wheel_margin"
android:layout_marginRight="12dp"
android:layout_marginEnd="12dp"/>
android:id="@+id/progress_vehicle"
style="@style/MwmWidget.ProgressWheel.RoutingPlan"
android:layout_marginLeft="@dimen/routing_selector_wheel_margin"
android:layout_marginStart="@dimen/routing_selector_wheel_margin"
android:layout_marginTop="@dimen/routing_selector_wheel_margin"
android:layout_marginBottom="@dimen/routing_selector_wheel_margin"
tools:visibility="visible"/>
<com.mapswithme.maps.widget.WheelProgressView
android:id="@+id/progress_bicycle"
style="@style/MwmWidget.ProgressWheel.RoutingPlan"
android:layout_marginTop="@dimen/routing_selector_wheel_margin"
android:layout_marginBottom="@dimen/routing_selector_wheel_margin"
android:layout_marginLeft="12dp"
android:layout_marginStart="12dp"
android:layout_marginRight="12dp"
android:layout_marginEnd="12dp"/>
<com.mapswithme.maps.widget.WheelProgressView
android:id="@+id/progress_pedestrian"
style="@style/MwmWidget.ProgressWheel.RoutingPlan"
android:layout_marginTop="@dimen/routing_selector_wheel_margin"
android:layout_marginBottom="@dimen/routing_selector_wheel_margin"
android:layout_marginRight="12dp"
android:layout_marginEnd="12dp"/>
<com.mapswithme.maps.widget.WheelProgressView
android:id="@+id/progress_taxi"
@ -85,46 +136,6 @@
</LinearLayout>
<RadioGroup
android:id="@+id/route_type"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_alignLeft="@id/progress_frame"
android:layout_alignStart="@id/progress_frame"
android:orientation="horizontal">
<RadioButton
android:id="@+id/vehicle"
android:layout_width="@dimen/routing_selector_size"
android:layout_height="@dimen/routing_selector_size"
tools:button="@drawable/ic_drive"
tools:buttonTint="?colorAccent" />
<RadioButton
android:id="@+id/bicycle"
android:layout_width="@dimen/routing_selector_size"
android:layout_height="@dimen/routing_selector_size"
android:layout_marginRight="@dimen/routing_selector_wheel_margin"
android:layout_marginLeft="@dimen/routing_selector_wheel_margin"
tools:button="@drawable/ic_bicycle"
tools:buttonTint="?iconTintLight" />
<RadioButton
android:id="@+id/pedestrian"
android:layout_width="@dimen/routing_selector_size"
android:layout_height="@dimen/routing_selector_size"
android:layout_marginRight="@dimen/routing_selector_wheel_margin"
tools:button="@drawable/ic_walk"
tools:buttonTint="?iconTintLight" />
<RadioButton
android:id="@+id/taxi"
android:layout_width="@dimen/routing_selector_size"
android:layout_height="@dimen/routing_selector_size"
tools:button="@drawable/ic_route_type_taxi"
tools:buttonTint="?iconTintLight" />
</RadioGroup>
<ImageView
android:id="@+id/toggle"
android:layout_width="?attr/actionBarSize"

View file

@ -40,8 +40,8 @@
<!-- Backgrounds -->
<color name="bg_window">#FFEEEEEE</color>
<color name="bg_window_night">#FF32363A</color>
<color name="bg_primary">#FF1F9952</color>
<color name="bg_primary_night">#FF1E2226</color>
<color name="bg_primary">#1F9952</color>
<color name="bg_primary_night">#1E2226</color>
<color name="bg_cards">@android:color/white</color>
<color name="bg_cards_night">#FF3C4044</color>
<color name="bg_panel">@color/bg_window</color>
@ -57,8 +57,8 @@
<color name="bg_menu_open">#FFFFFFFF</color>
<color name="bg_menu_open_night">#FF2D3237</color>
<color name="bg_statusbar">#FF197E46</color>
<color name="bg_statusbar_night">#FF000000</color>
<color name="bg_statusbar">#197841</color>
<color name="bg_statusbar_night">#14181C</color>
<color name="bg_azimut_arrow">#1D414651</color>
<color name="fg_azimut_arrow">#FFFFFFFF</color>
@ -113,8 +113,11 @@
<color name="routing_slot_background_pressed">#FFF0F0F0</color>
<color name="routing_slot_background_pressed_night">@color/bg_window_night</color>
<color name="routing_slot_shadow">#3D000000</color>
<color name="routing_button_tint">#80FFFFFF</color>
<color name="routing_button_pressed_tint">#FFFFFFFF</color>
<color name="routing_button_tint">#FFFFFFFF</color>
<color name="routing_button_activated_tint">@color/bg_statusbar</color>
<color name="routing_button_activated_tint_night">@color/bg_statusbar_night</color>
<color name="routing_button_pressed_tint">#80FFFFFF</color>
<color name="bs_divider_color">@color/divider</color>
<color name="bs_dark_divider_color">@color/divider_night</color>

View file

@ -1002,4 +1002,7 @@
<string name="booking_hotel_room">Room</string>
<string name="chat">Geochat</string>
<string name="chat_open">Open</string>
<!-- TODO: it's temporary -->
<string name="uber_no_internet">Internet connection is required to order taxi</string>
<string name="uber_remote_error">Uber is unavailable</string>
</resources>

View file

@ -47,7 +47,7 @@
<item name="android:visibility">invisible</item>
<item name="android:background">?selectableItemBackgroundBorderless</item>
<item name="centerDrawable">@android:color/transparent</item>
<item name="wheelProgressColor">?routingButtonPressedHint</item>
<item name="wheelProgressColor">?routingButtonHint</item>
<item name="wheelSecondaryColor">@android:color/transparent</item>
<item name="wheelThickness">@dimen/margin_eighth</item>
</style>

View file

@ -65,6 +65,7 @@
<attr name="routingButtonHint" format="color"/>
<attr name="routingButtonPressedHint" format="color"/>
<attr name="routingButtonActivatedHint" format="color"/>
</declare-styleable>
<declare-styleable name="ThemeAttrs.NavButtons">

View file

@ -76,6 +76,7 @@
<item name="fabAdd">@drawable/ic_fab_add</item>
<item name="routingButtonHint">@color/routing_button_tint</item>
<item name="routingButtonActivatedHint">?statusBar</item>
<item name="routingButtonPressedHint">@color/routing_button_pressed_tint</item>
<item name="ppRatingBackground">@color/bg_placepage_rating</item>
@ -160,6 +161,7 @@
<item name="fabAdd">@drawable/ic_fab_add_night</item>
<item name="routingButtonHint">@color/routing_button_tint</item>
<item name="routingButtonActivatedHint">?statusBar</item>
<item name="routingButtonPressedHint">@color/routing_button_pressed_tint</item>
<item name="ppRatingBackground">@color/bg_placepage_rating_night</item>

View file

@ -28,6 +28,7 @@ import com.mapswithme.maps.api.ParsedMwmRequest;
import com.mapswithme.maps.api.ParsedRoutingData;
import com.mapswithme.maps.api.ParsedUrlMwmRequest;
import com.mapswithme.maps.api.RoutePoint;
import com.mapswithme.maps.uber.Uber;
import com.mapswithme.maps.uber.UberInfo;
import com.mapswithme.maps.base.BaseMwmFragmentActivity;
import com.mapswithme.maps.base.OnBackPressListener;
@ -1343,7 +1344,7 @@ public class MwmActivity extends BaseMwmFragmentActivity
{
final RoutingController controller = RoutingController.get();
if (controller.isBuilt() || controller.isUberInfoObtained())
if (controller.isBuilt() || controller.isUberRequestHandled())
{
mMainMenu.showLineFrame(true);
return;
@ -1444,6 +1445,21 @@ public class MwmActivity extends BaseMwmFragmentActivity
}
}
@Override
public void onUberError(@NonNull Uber.ErrorCode code)
{
if (mIsFragmentContainer)
{
RoutingPlanFragment fragment = (RoutingPlanFragment) getFragment(RoutingPlanFragment.class);
if (fragment != null)
fragment.showUberError(code);
}
else
{
mRoutingPlanInplaceController.showUberError(code);
}
}
boolean isFirstStart()
{
boolean res = mFirstStart;

View file

@ -25,6 +25,7 @@ import com.mapswithme.maps.bookmarks.data.MapObject;
import com.mapswithme.maps.downloader.MapManager;
import com.mapswithme.maps.location.LocationHelper;
import com.mapswithme.util.Config;
import com.mapswithme.util.ConnectionState;
import com.mapswithme.util.StringUtils;
import com.mapswithme.util.ThemeSwitcher;
import com.mapswithme.util.Utils;
@ -67,6 +68,7 @@ public class RoutingController
void updateMenu();
void updatePoints();
void onUberInfoReceived(@NonNull UberInfo info);
void onUberError(@NonNull Uber.ErrorCode code);
/**
* @param progress progress to be displayed.
@ -98,8 +100,9 @@ public class RoutingController
private String[] mLastMissingMaps;
@Nullable
private RoutingInfo mCachedRoutingInfo;
private boolean mUberInfoObtained;
private boolean mUberRequestHandled;
private boolean mUberPlanning;
private boolean mInternetConnected;
@SuppressWarnings("FieldCanBeLocal")
private final Framework.RoutingListener mRoutingListener = new Framework.RoutingListener()
@ -263,8 +266,20 @@ public class RoutingController
private void build()
{
mLogger.d("build");
mUberInfoObtained = false;
mUberRequestHandled = false;
mLastBuildProgress = 0;
mInternetConnected = ConnectionState.isConnected();
if (mLastRouterType == Framework.ROUTER_TYPE_TAXI)
{
if (!mInternetConnected)
{
completeUberRequest();
return;
}
requestUberInfo();
}
setBuildState(BuildState.BUILDING);
updatePlan();
@ -272,9 +287,16 @@ public class RoutingController
org.alohalytics.Statistics.logEvent(AlohaHelper.ROUTING_BUILD, new String[] {Statistics.EventParam.FROM, Statistics.getPointType(mStartPoint),
Statistics.EventParam.TO, Statistics.getPointType(mEndPoint)});
Framework.nativeBuildRoute(mStartPoint.getLat(), mStartPoint.getLon(), mEndPoint.getLat(), mEndPoint.getLon());
}
if (mLastRouterType == Framework.ROUTER_TYPE_TAXI)
requestUberInfo();
private void completeUberRequest()
{
mUberRequestHandled = true;
if (mContainer != null)
{
mContainer.updateBuildProgress(100, mLastRouterType);
mContainer.updateMenu();
}
}
private void showDisclaimer(final MapObject startPoint, final MapObject endPoint)
@ -426,6 +448,7 @@ public class RoutingController
mEndPoint = null;
setPointsInternal();
mWaitingPoiPickSlot = NO_SLOT;
mUberRequestHandled = false;
setBuildState(BuildState.NONE);
setState(State.NONE);
@ -482,7 +505,7 @@ public class RoutingController
return mState == State.PREPARE;
}
private boolean isUberPlanning()
boolean isUberPlanning()
{
return mLastRouterType == Framework.ROUTER_TYPE_TAXI && mUberPlanning;
}
@ -513,9 +536,14 @@ public class RoutingController
return (mWaitingPoiPickSlot != NO_SLOT);
}
public boolean isUberInfoObtained()
public boolean isUberRequestHandled()
{
return mUberInfoObtained;
return mUberRequestHandled;
}
boolean isInternetConnected()
{
return mInternetConnected;
}
BuildState getBuildState()
@ -690,7 +718,9 @@ public class RoutingController
{
mLogger.d("setRouterType: " + mLastRouterType + " -> " + router);
if (router == mLastRouterType)
// Repeating tap on Uber icon should trigger the route building always,
// because it may be "No internet connection, try later" case
if (router == mLastRouterType && router != Framework.ROUTER_TYPE_TAXI)
return;
mLastRouterType = router;
@ -803,9 +833,24 @@ public class RoutingController
if (mLastRouterType == Framework.ROUTER_TYPE_TAXI && mContainer != null)
{
mContainer.onUberInfoReceived(info);
mUberInfoObtained = true;
mContainer.updateBuildProgress(100, mLastRouterType);
mContainer.updateMenu();
completeUberRequest();
}
}
/**
* Called from the native code
* @param errorCode must match the one of the values in {@link com.mapswithme.maps.uber.Uber.ErrorCode}
*/
@MainThread
private void onUberError(@NonNull String errorCode)
{
mUberPlanning = false;
Uber.ErrorCode code = Uber.ErrorCode.valueOf(errorCode);
mLogger.e("onUberError error = " + code);
if (mLastRouterType == Framework.ROUTER_TYPE_TAXI && mContainer != null)
{
mContainer.onUberError(code);
completeUberRequest();
}
}
}

View file

@ -24,14 +24,15 @@ import com.mapswithme.maps.Framework;
import com.mapswithme.maps.MwmActivity;
import com.mapswithme.maps.MwmApplication;
import com.mapswithme.maps.R;
import com.mapswithme.maps.uber.Uber;
import com.mapswithme.maps.uber.UberAdapter;
import com.mapswithme.maps.uber.UberInfo;
import com.mapswithme.maps.uber.UberLinks;
import com.mapswithme.maps.widget.DotPager;
import com.mapswithme.maps.widget.RotateDrawable;
import com.mapswithme.maps.widget.RoutingToolbarButton;
import com.mapswithme.maps.widget.ToolbarController;
import com.mapswithme.maps.widget.WheelProgressView;
import com.mapswithme.util.Graphics;
import com.mapswithme.util.UiUtils;
import com.mapswithme.util.Utils;
import com.mapswithme.util.statistics.AlohaHelper;
@ -52,6 +53,7 @@ public class RoutingPlanController extends ToolbarController
private final WheelProgressView mProgressPedestrian;
private final WheelProgressView mProgressBicycle;
private final WheelProgressView mProgressTaxi;
private final View mAltitudeChartFrame;
private final View mUberFrame;
@ -72,16 +74,19 @@ public class RoutingPlanController extends ToolbarController
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
{
buttonView.setButtonDrawable(Graphics.tint(mActivity, iconRes, isChecked ? R.attr.routingButtonPressedHint
: R.attr.routingButtonHint));
RoutingToolbarButton button = (RoutingToolbarButton) buttonView;
button.setIcon(iconRes);
if (isChecked)
button.activate();
else
button.deactivate();
}
};
RadioButton rb = (RadioButton) mRouterTypes.findViewById(buttonId);
RoutingToolbarButton rb = (RoutingToolbarButton) mRouterTypes.findViewById(buttonId);
listener.onCheckedChanged(rb, false);
rb.setOnCheckedChangeListener(listener);
rb.setOnClickListener(clickListener);
return rb;
}
@ -94,7 +99,7 @@ public class RoutingPlanController extends ToolbarController
mSlotFrame = (SlotFrame) root.findViewById(R.id.slots);
mRouterTypes = (RadioGroup) mToolbar.findViewById(R.id.route_type);
setupRouterButton(R.id.vehicle, R.drawable.ic_drive, new View.OnClickListener()
setupRouterButton(R.id.vehicle, R.drawable.ic_car, new View.OnClickListener()
{
@Override
public void onClick(View v)
@ -105,7 +110,7 @@ public class RoutingPlanController extends ToolbarController
}
});
setupRouterButton(R.id.pedestrian, R.drawable.ic_walk, new View.OnClickListener()
setupRouterButton(R.id.pedestrian, R.drawable.ic_pedestrian, new View.OnClickListener()
{
@Override
public void onClick(View v)
@ -116,7 +121,7 @@ public class RoutingPlanController extends ToolbarController
}
});
setupRouterButton(R.id.bicycle, R.drawable.ic_bicycle, new View.OnClickListener()
setupRouterButton(R.id.bicycle, R.drawable.ic_bike, new View.OnClickListener()
{
@Override
public void onClick(View v)
@ -278,10 +283,28 @@ public class RoutingPlanController extends ToolbarController
progressView = mProgressBicycle;
}
RoutingToolbarButton button = (RoutingToolbarButton)mRouterTypes
.findViewById(mRouterTypes.getCheckedRadioButtonId());
button.progress();
updateProgressLabels();
if (!RoutingController.get().isBuilding() || RoutingController.get().isUberInfoObtained())
if (RoutingController.get().isUberRequestHandled())
{
if (!RoutingController.get().isInternetConnected())
{
showNoInternetError();
return;
}
button.complete();
return;
}
if (!RoutingController.get().isBuilding() && !RoutingController.get().isUberPlanning())
{
button.complete();
return;
}
UiUtils.show(progressView);
progressView.setPending(progress == 0);
@ -386,15 +409,9 @@ public class RoutingPlanController extends ToolbarController
public void showUberInfo(@NonNull UberInfo info)
{
final UberInfo.Product[] products = info.getProducts();
if (products == null || products.length == 0)
{
UiUtils.hide(mUberFrame);
showError(R.string.taxi_not_found);
return;
}
UiUtils.hide(getViewById(R.id.error), mAltitudeChartFrame);
UiUtils.hide(getViewById(R.id.error));
final UberInfo.Product[] products = info.getProducts();
mUberInfo = info;
mUberProduct = products[0];
final PagerAdapter adapter = new UberAdapter(mActivity, products);
@ -411,13 +428,36 @@ public class RoutingPlanController extends ToolbarController
pager.show();
setStartButton();
UiUtils.hide(mAltitudeChartFrame);
UiUtils.show(mUberFrame);
}
public void showUberError(@NonNull Uber.ErrorCode code)
{
switch (code)
{
case NoProducts:
showError(R.string.taxi_not_found);
break;
case RemoteError:
showError(R.string.uber_remote_error);
break;
default:
throw new AssertionError("Unsupported uber error: " + code);
}
}
private void showNoInternetError()
{
@IdRes
int checkedId = mRouterTypes.getCheckedRadioButtonId();
RoutingToolbarButton rb = (RoutingToolbarButton) mRouterTypes.findViewById(checkedId);
rb.error();
showError(R.string.uber_no_internet);
}
private void showError(@StringRes int message)
{
UiUtils.hide(mUberFrame, mAltitudeChartFrame);
TextView error = (TextView) getViewById(R.id.error);
error.setText(message);
error.setVisibility(View.VISIBLE);
@ -455,7 +495,7 @@ public class RoutingPlanController extends ToolbarController
if (isTaxiRouteChecked())
{
start.setText(R.string.taxi_order);
start.setText(Utils.isUberInstalled(mActivity) ? R.string.taxi_order : R.string.install_app);
start.setOnClickListener(new View.OnClickListener()
{
@Override

View file

@ -9,6 +9,7 @@ import android.view.ViewGroup;
import com.mapswithme.maps.Framework;
import com.mapswithme.maps.R;
import com.mapswithme.maps.uber.Uber;
import com.mapswithme.maps.uber.UberInfo;
import com.mapswithme.maps.base.BaseMwmFragment;
import com.mapswithme.maps.base.OnBackPressListener;
@ -55,6 +56,11 @@ public class RoutingPlanFragment extends BaseMwmFragment
mPlanController.showUberInfo(info);
}
public void showUberError(@NonNull Uber.ErrorCode code)
{
mPlanController.showUberError(code);
}
@Override
public boolean onBackPressed()
{

View file

@ -9,4 +9,9 @@ public class Uber
@NonNull
public static native UberLinks nativeGetUberLinks(@NonNull String productId, double srcLon, double srcLat,
double dstLat, double dstLon);
public enum ErrorCode
{
NoProducts, RemoteError
}
}

View file

@ -24,10 +24,10 @@ public class UberInfo implements Parcelable
}
};
@Nullable
@NonNull
private final Product[] mProducts;
private UberInfo(@Nullable Product[] products)
private UberInfo(@NonNull Product[] products)
{
mProducts = products;
}
@ -37,7 +37,7 @@ public class UberInfo implements Parcelable
mProducts = (Product[]) parcel.readParcelableArray(Product.class.getClassLoader());
}
@Nullable
@NonNull
public Product[] getProducts()
{
return mProducts;

View file

@ -0,0 +1,99 @@
package com.mapswithme.maps.widget;
import android.content.Context;
import android.os.Build;
import android.support.annotation.ColorRes;
import android.support.annotation.DrawableRes;
import android.support.v7.widget.AppCompatRadioButton;
import android.util.AttributeSet;
import com.mapswithme.maps.R;
import com.mapswithme.util.ThemeUtils;
public class RoutingToolbarButton extends AppCompatRadioButton
{
private boolean mInProgress;
@DrawableRes
private int mIcon;
public RoutingToolbarButton(Context context, AttributeSet attrs, int defStyleAttr)
{
super(context, attrs, defStyleAttr);
initView();
}
public RoutingToolbarButton(Context context, AttributeSet attrs)
{
super(context, attrs);
initView();
}
public RoutingToolbarButton(Context context)
{
super(context);
initView();
}
private void initView()
{
setBackgroundResource(ThemeUtils.isNightTheme() ? R.drawable.routing_toolbar_button_night
: R.drawable.routing_toolbar_button);
setButtonTintList(ThemeUtils.isNightTheme() ? R.color.routing_toolbar_icon_tint_night
: R.color.routing_toolbar_icon_tint);
}
public void progress()
{
if (mInProgress)
return;
setButtonDrawable(mIcon);
mInProgress = true;
setActivated(false);
setSelected(true);
}
public void error()
{
mInProgress = false;
setSelected(false);
setButtonDrawable(R.drawable.ic_reload);
setActivated(true);
}
public void activate()
{
if (!mInProgress)
{
setButtonDrawable(mIcon);
setSelected(false);
setActivated(true);
}
}
public void complete()
{
mInProgress = false;
activate();
}
public void deactivate()
{
setActivated(false);
mInProgress = false;
}
public void setButtonTintList(@ColorRes int color)
{
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP)
setSupportButtonTintList(getResources().getColorStateList(color));
else
setButtonTintList(getResources().getColorStateList(color));
}
public void setIcon(@DrawableRes int icon)
{
mIcon = icon;
setButtonDrawable(icon);
}
}

View file

@ -401,22 +401,32 @@ public class Utils
return installationId;
}
public static void launchUber(@NonNull Activity context, @NonNull UberLinks links)
public static boolean isUberInstalled(@NonNull Activity context)
{
try
{
PackageManager pm = context.getPackageManager();
pm.getPackageInfo("com.ubercab", PackageManager.GET_ACTIVITIES);
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setData(Uri.parse(links.getDeepLink()));
context.startActivity(intent);
return true;
} catch (PackageManager.NameNotFoundException e)
{
// No Uber app! Open mobile website.
Intent i = new Intent(Intent.ACTION_VIEW);
i.setData(Uri.parse(links.getUniversalLink()));
context.startActivity(i);
return false;
}
}
public static void launchUber(@NonNull Activity context, @NonNull UberLinks links)
{
final Intent intent = new Intent(Intent.ACTION_VIEW);
if (isUberInstalled(context))
{
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setData(Uri.parse(links.getDeepLink()));
} else
{
// No Uber app! Open mobile website.
intent.setData(Uri.parse(links.getUniversalLink()));
}
context.startActivity(intent);
}
}

View file

@ -249,4 +249,13 @@ RideRequestLinks Api::GetRideRequestLinks(string const & productId, ms::LatLon c
return {"uber://" + url.str(), "https://m.uber.com/ul" + url.str()};
}
string DebugPrint(ErrorCode error)
{
switch (error)
{
case ErrorCode::NoProducts: return "NoProducts";
case ErrorCode::RemoteError: return "RemoteError";
}
}
} // namespace uber

View file

@ -101,4 +101,6 @@ private:
shared_ptr<ProductMaker> m_maker = make_shared<ProductMaker>();
uint64_t m_requestId = 0;
};
string DebugPrint(ErrorCode error);
} // namespace uber