[android] Added bookmark backup statistics and refactored authorizaton logic

This commit is contained in:
Александр Зацепин 2018-02-19 19:32:07 +03:00 committed by Roman Kuznetsov
parent 848c118d6f
commit 0025240c30
9 changed files with 180 additions and 53 deletions

View file

@ -81,11 +81,13 @@ public class Framework
public static final int ROUTE_REBUILD_AFTER_POINTS_LOADING = 0;
@Retention(RetentionPolicy.SOURCE)
@IntDef({ SOCIAL_TOKEN_FACEBOOK, SOCIAL_TOKEN_GOOGLE })
public @interface SocialTokenType {}
@IntDef({ SOCIAL_TOKEN_FACEBOOK, SOCIAL_TOKEN_GOOGLE, TOKEN_MAPSME })
public @interface AuthTokenType
{}
public static final int SOCIAL_TOKEN_FACEBOOK = 0;
public static final int SOCIAL_TOKEN_GOOGLE = 1;
public static final int TOKEN_MAPSME = 2;
@SuppressWarnings("unused")
public interface MapObjectListener
@ -381,7 +383,7 @@ public class Framework
public static native Banner[] nativeGetSearchBanners();
public static native void nativeAuthenticateUser(@NonNull String socialToken,
@SocialTokenType int socialTokenType,
@AuthTokenType int socialTokenType,
@NonNull AuthorizationListener listener);
public static native boolean nativeIsUserAuthenticated();

View file

@ -70,16 +70,38 @@ public class Authorizer implements AuthorizationListener
public final void onActivityResult(int requestCode, int resultCode, @Nullable Intent data)
{
if (requestCode != Constants.REQ_CODE_GET_SOCIAL_TOKEN
|| resultCode != Activity.RESULT_OK || data == null)
if (requestCode != Constants.REQ_CODE_GET_SOCIAL_TOKEN)
return;
if (data == null)
return;
if (resultCode == Activity.RESULT_CANCELED)
{
if (mCallback == null)
return;
@Framework.AuthTokenType
int type = data.getIntExtra(Constants.EXTRA_TOKEN_TYPE, -1);
boolean isCancel = data.getBooleanExtra(Constants.EXTRA_IS_CANCEL, false);
if (isCancel)
{
mCallback.onSocialAuthenticationCancel(type);
return;
}
mCallback.onSocialAuthenticationError(type, data.getStringExtra(Constants.EXTRA_AUTH_ERROR));
return;
}
if (resultCode != Activity.RESULT_OK)
return;
String socialToken = data.getStringExtra(Constants.EXTRA_SOCIAL_TOKEN);
if (!TextUtils.isEmpty(socialToken))
{
@Framework.SocialTokenType
@Framework.AuthTokenType
int type = data.getIntExtra(Constants.EXTRA_TOKEN_TYPE, -1);
mIsAuthorizationInProgress = true;
if (mCallback != null)
@ -110,5 +132,7 @@ public class Authorizer implements AuthorizationListener
{
void onAuthorizationFinish(boolean success);
void onAuthorizationStart();
void onSocialAuthenticationCancel(@Framework.AuthTokenType int type);
void onSocialAuthenticationError(@Framework.AuthTokenType int type, @Nullable String error);
}
}

View file

@ -8,6 +8,8 @@ class Constants
static final int REQ_CODE_GET_SOCIAL_TOKEN = 101;
static final String EXTRA_SOCIAL_TOKEN = "extra_social_token";
static final String EXTRA_TOKEN_TYPE = "extra_token_type";
static final String EXTRA_AUTH_ERROR = "extra_auth_error";
static final String EXTRA_IS_CANCEL = "extra_is_cancel";
static final List<String> FACEBOOK_PERMISSIONS =
Arrays.asList("email", "user_friends");
}

View file

@ -51,7 +51,7 @@ public class SocialAuthDialogFragment extends BaseMwmDialogFragment
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState)
{
View view = inflater.inflate(R.layout.fragment_auth_passport_dialog, container, false);
LoginButton button = (LoginButton) view.findViewById(R.id.loging_button);
LoginButton button = view.findViewById(R.id.loging_button);
button.setReadPermissions(Constants.FACEBOOK_PERMISSIONS);
button.setFragment(this);
button.registerCallback(mCallbackManager, new FBCallback(this));
@ -78,19 +78,18 @@ public class SocialAuthDialogFragment extends BaseMwmDialogFragment
}
private void sendResult(int resultCode, @Nullable String socialToken,
@Framework.SocialTokenType int type)
@Framework.AuthTokenType int type, @Nullable String error,
boolean isCancel)
{
Fragment caller = getTargetFragment();
if (caller == null)
return;
Intent data = null;
if (resultCode == Activity.RESULT_OK)
{
data = new Intent();
data.putExtra(Constants.EXTRA_SOCIAL_TOKEN, socialToken);
data.putExtra(Constants.EXTRA_TOKEN_TYPE, type);
}
Intent data = new Intent();
data.putExtra(Constants.EXTRA_SOCIAL_TOKEN, socialToken);
data.putExtra(Constants.EXTRA_TOKEN_TYPE, type);
data.putExtra(Constants.EXTRA_AUTH_ERROR, error);
data.putExtra(Constants.EXTRA_IS_CANCEL, isCancel);
caller.onActivityResult(Constants.REQ_CODE_GET_SOCIAL_TOKEN, resultCode, data);
}
@ -104,10 +103,11 @@ public class SocialAuthDialogFragment extends BaseMwmDialogFragment
@Override
public void onDismiss(DialogInterface dialog)
{
Statistics.INSTANCE.trackEvent(Statistics.EventName.UGC_AUTH_DECLINED);
AccessToken token = AccessToken.getCurrentAccessToken();
sendResult(Activity.RESULT_OK, token != null ? token.getToken() : null,
Framework.SOCIAL_TOKEN_FACEBOOK);
int resultCode = token == null || TextUtils.isEmpty(token.getToken()) ? Activity.RESULT_CANCELED
: Activity.RESULT_OK;
sendResult(resultCode, token != null ? token.getToken() : null,
Framework.SOCIAL_TOKEN_FACEBOOK, null, true);
super.onDismiss(dialog);
}
@ -131,28 +131,28 @@ public class SocialAuthDialogFragment extends BaseMwmDialogFragment
@Override
public void onCancel()
{
Statistics.INSTANCE.trackEvent(Statistics.EventName.UGC_AUTH_DECLINED);
LOGGER.w(TAG, "onCancel");
sendResult(Activity.RESULT_CANCELED, null, Framework.SOCIAL_TOKEN_FACEBOOK);
sendResult(Activity.RESULT_CANCELED, null, Framework.SOCIAL_TOKEN_FACEBOOK,
null, true);
}
@Override
public void onError(FacebookException error)
{
Statistics.INSTANCE.trackUGCAuthFailed(Statistics.ParamValue.FACEBOOK,
error != null ? error.getMessage() : null);
LOGGER.e(TAG, "onError", error);
sendResult(Activity.RESULT_CANCELED, null, Framework.SOCIAL_TOKEN_FACEBOOK);
sendResult(Activity.RESULT_CANCELED, null, Framework.SOCIAL_TOKEN_FACEBOOK,
error != null ? error.getMessage() : null, false);
}
private void sendResult(int resultCode, @Nullable String socialToken,
@Framework.SocialTokenType int type)
@Framework.AuthTokenType int type, @Nullable String error,
boolean isCancel)
{
SocialAuthDialogFragment fragment = mFragmentRef.get();
if (fragment == null)
return;
fragment.sendResult(resultCode, socialToken, type);
fragment.sendResult(resultCode, socialToken, type, error, isCancel);
}
}
}

View file

@ -64,8 +64,8 @@ public class BookmarkCategoriesFragment extends BaseMwmRecyclerFragment
super.onViewCreated(view, savedInstanceState);
mLoadingPlaceholder = view.findViewById(R.id.placeholder_loading);
mBackupController = new BookmarkBackupController(view.findViewById(R.id.backup));
mBackupController.setAuthorizer(new Authorizer(this));
mBackupController = new BookmarkBackupController(view.findViewById(R.id.backup),
new Authorizer(this));
if (getAdapter() != null)
{
getAdapter().setOnClickListener(this);
@ -209,7 +209,7 @@ public class BookmarkCategoriesFragment extends BaseMwmRecyclerFragment
protected void setupPlaceholder(@NonNull PlaceholderView placeholder)
{
placeholder.setContent(R.drawable.img_bookmarks, R.string.bookmarks_empty_title,
R.string.bookmarks_usage_hint);
R.string.bookmarks_usage_hint);
}
@Override

View file

@ -6,10 +6,12 @@ import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.view.View;
import com.mapswithme.maps.Framework;
import com.mapswithme.maps.R;
import com.mapswithme.maps.auth.Authorizer;
import com.mapswithme.maps.widget.BookmarkBackupView;
import com.mapswithme.util.DateUtils;
import com.mapswithme.util.statistics.Statistics;
import java.util.Date;
@ -17,35 +19,40 @@ public class BookmarkBackupController implements Authorizer.Callback
{
@NonNull
private final BookmarkBackupView mBackupView;
@Nullable
private Authorizer mAuthorizer;
@NonNull
private final View.OnClickListener mSignInClickListener = v ->
private final Authorizer mAuthorizer;
@NonNull
private final View.OnClickListener mSignInClickListener = new View.OnClickListener()
{
if (mAuthorizer != null)
@Override
public void onClick(View v)
{
mAuthorizer.authorize();
Statistics.INSTANCE.trackBkmSyncProposalApproved(false);
}
};
@NonNull
private final View.OnClickListener mEnableClickListener = v ->
private final View.OnClickListener mEnableClickListener = new View.OnClickListener()
{
BookmarkManager.INSTANCE.setCloudEnabled(true);
update();
@Override
public void onClick(View v)
{
BookmarkManager.INSTANCE.setCloudEnabled(true);
update();
Statistics.INSTANCE.trackBkmSyncProposalApproved(mAuthorizer.isAuthorized());
}
};
public BookmarkBackupController(@NonNull BookmarkBackupView backupView)
public BookmarkBackupController(@NonNull BookmarkBackupView backupView, @NonNull Authorizer authorizer)
{
mBackupView = backupView;
}
public void setAuthorizer(@Nullable Authorizer authorizer)
{
mAuthorizer = authorizer;
}
public void update()
{
final Context context = mBackupView.getContext();
if (mAuthorizer != null && !mAuthorizer.isAuthorized())
if (!mAuthorizer.isAuthorized())
{
mBackupView.setMessage(context.getString(R.string.bookmarks_message_unauthorized_user));
mBackupView.setButtonLabel(context.getString(R.string.authorization_button_sign_in));
@ -59,6 +66,7 @@ public class BookmarkBackupController implements Authorizer.Callback
mBackupView.hideProgressBar();
mBackupView.setClickListener(mSignInClickListener);
mBackupView.showButton();
Statistics.INSTANCE.trackBkmSyncProposalShown(mAuthorizer.isAuthorized());
}
return;
}
@ -89,25 +97,23 @@ public class BookmarkBackupController implements Authorizer.Callback
mBackupView.setButtonLabel(context.getString(R.string.bookmarks_backup));
mBackupView.setClickListener(mEnableClickListener);
mBackupView.showButton();
Statistics.INSTANCE.trackBkmSyncProposalShown(mAuthorizer.isAuthorized());
}
public void onStart()
{
if (mAuthorizer != null)
mAuthorizer.attach(this);
mAuthorizer.attach(this);
update();
}
public void onStop()
{
if (mAuthorizer != null)
mAuthorizer.detach();
mAuthorizer.detach();
}
public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data)
{
if (mAuthorizer != null)
mAuthorizer.onActivityResult(requestCode, resultCode, data);
mAuthorizer.onActivityResult(requestCode, resultCode, data);
}
@Override
@ -120,7 +126,26 @@ public class BookmarkBackupController implements Authorizer.Callback
public void onAuthorizationFinish(boolean success /* it's ignored for a while.*/)
{
if (success)
{
BookmarkManager.INSTANCE.setCloudEnabled(true);
Statistics.INSTANCE.trackEvent(Statistics.EventName.BMK_SYNC_PROPOSAL_ENABLED);
}
else
{
Statistics.INSTANCE.trackBkmSyncProposalError(Framework.TOKEN_MAPSME, "Unknown error");
}
update();
}
@Override
public void onSocialAuthenticationError(@Framework.AuthTokenType int type, @Nullable String error)
{
Statistics.INSTANCE.trackBkmSyncProposalError(type, error);
}
@Override
public void onSocialAuthenticationCancel(@Framework.AuthTokenType int type)
{
Statistics.INSTANCE.trackBkmSyncProposalError(type, "Cancel");
}
}

View file

@ -746,7 +746,9 @@ public class SettingsPrefsFragment extends BaseXmlSettingsFragment
pref.setOnPreferenceChangeListener(
(preference, newValue) ->
{
BookmarkManager.INSTANCE.setCloudEnabled((Boolean) newValue);
Boolean value = (Boolean) newValue;
BookmarkManager.INSTANCE.setCloudEnabled(value);
Statistics.INSTANCE.trackBkmSettingsToggle(value);
return true;
});
}

View file

@ -10,6 +10,7 @@ import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import com.mapswithme.maps.Framework;
import com.mapswithme.maps.R;
import com.mapswithme.maps.auth.BaseMwmAuthorizationFragment;
import com.mapswithme.maps.bookmarks.data.FeatureId;
@ -42,9 +43,9 @@ public class UGCEditorFragment extends BaseMwmAuthorizationFragment
@Nullable Bundle savedInstanceState)
{
View root = inflater.inflate(R.layout.fragment_ugc_editor, container, false);
mReviewEditText = (EditText) root.findViewById(R.id.review);
mReviewEditText = root.findViewById(R.id.review);
RecyclerView rvRatingView = (RecyclerView) root.findViewById(R.id.ratings);
RecyclerView rvRatingView = root.findViewById(R.id.ratings);
rvRatingView.setLayoutManager(new LinearLayoutManager(getContext()));
rvRatingView.getLayoutManager().setAutoMeasureEnabled(true);
rvRatingView.setNestedScrollingEnabled(false);
@ -109,6 +110,18 @@ public class UGCEditorFragment extends BaseMwmAuthorizationFragment
getActivity().finish();
}
@Override
public void onSocialAuthenticationCancel(@Framework.AuthTokenType int type)
{
Statistics.INSTANCE.trackEvent(Statistics.EventName.UGC_AUTH_DECLINED);
}
@Override
public void onSocialAuthenticationError(int type, @Nullable String error)
{
Statistics.INSTANCE.trackUGCAuthFailed(type, error);
}
private void onSubmitButtonClick()
{
List<UGC.Rating> modifiedRatings = mUGCRatingAdapter.getItems();

View file

@ -50,6 +50,10 @@ import static com.mapswithme.util.BatteryState.CHARGING_STATUS_PLUGGED;
import static com.mapswithme.util.BatteryState.CHARGING_STATUS_UNKNOWN;
import static com.mapswithme.util.BatteryState.CHARGING_STATUS_UNPLUGGED;
import static com.mapswithme.util.statistics.Statistics.EventName.APPLICATION_COLD_STARTUP_INFO;
import static com.mapswithme.util.statistics.Statistics.EventName.BMK_SYNC_PROPOSAL_APPROVED;
import static com.mapswithme.util.statistics.Statistics.EventName.BMK_SYNC_PROPOSAL_ERROR;
import static com.mapswithme.util.statistics.Statistics.EventName.BMK_SYNC_PROPOSAL_SHOWN;
import static com.mapswithme.util.statistics.Statistics.EventName.BMK_SYNC_PROPOSAL_TOGGLE;
import static com.mapswithme.util.statistics.Statistics.EventName.DISCOVERY_OPEN;
import static com.mapswithme.util.statistics.Statistics.EventName.DOWNLOADER_DIALOG_ERROR;
import static com.mapswithme.util.statistics.Statistics.EventName.PP_BANNER_BLANK;
@ -63,7 +67,6 @@ import static com.mapswithme.util.statistics.Statistics.EventName.PP_SPONSORED_S
import static com.mapswithme.util.statistics.Statistics.EventName.PP_SPONSOR_ITEM_SELECTED;
import static com.mapswithme.util.statistics.Statistics.EventName.ROUTING_PLAN_TOOLTIP_CLICK;
import static com.mapswithme.util.statistics.Statistics.EventName.SEARCH_FILTER_CLICK;
import static com.mapswithme.util.statistics.Statistics.EventName.SEARCH_FILTER_OPEN;
import static com.mapswithme.util.statistics.Statistics.EventName.UGC_AUTH_ERROR;
import static com.mapswithme.util.statistics.Statistics.EventName.UGC_AUTH_EXTERNAL_REQUEST_SUCCESS;
import static com.mapswithme.util.statistics.Statistics.EventName.UGC_AUTH_SHOWN;
@ -77,6 +80,7 @@ import static com.mapswithme.util.statistics.Statistics.EventParam.ERROR;
import static com.mapswithme.util.statistics.Statistics.EventParam.ERROR_CODE;
import static com.mapswithme.util.statistics.Statistics.EventParam.ERROR_MESSAGE;
import static com.mapswithme.util.statistics.Statistics.EventParam.FEATURE_ID;
import static com.mapswithme.util.statistics.Statistics.EventParam.HAS_AUTH;
import static com.mapswithme.util.statistics.Statistics.EventParam.HOTEL;
import static com.mapswithme.util.statistics.Statistics.EventParam.HOTEL_LAT;
import static com.mapswithme.util.statistics.Statistics.EventParam.HOTEL_LON;
@ -98,7 +102,10 @@ import static com.mapswithme.util.statistics.Statistics.EventParam.STATE;
import static com.mapswithme.util.statistics.Statistics.EventParam.TYPE;
import static com.mapswithme.util.statistics.Statistics.EventParam.VALUE;
import static com.mapswithme.util.statistics.Statistics.ParamValue.BOOKING_COM;
import static com.mapswithme.util.statistics.Statistics.ParamValue.FACEBOOK;
import static com.mapswithme.util.statistics.Statistics.ParamValue.GOOGLE;
import static com.mapswithme.util.statistics.Statistics.ParamValue.HOLIDAY;
import static com.mapswithme.util.statistics.Statistics.ParamValue.MAPSME;
import static com.mapswithme.util.statistics.Statistics.ParamValue.OPENTABLE;
import static com.mapswithme.util.statistics.Statistics.ParamValue.SEARCH_BOOKING_COM;
import static com.mapswithme.util.statistics.Statistics.ParamValue.VIATOR;
@ -140,6 +147,11 @@ public enum Statistics
public static final String BMK_GROUP_CHANGED = "Bookmark. Group changed";
public static final String BMK_COLOR_CHANGED = "Bookmark. Color changed";
public static final String BMK_CREATED = "Bookmark. Bookmark created";
public static final String BMK_SYNC_PROPOSAL_SHOWN = "Bookmarks_SyncProposal_shown";
public static final String BMK_SYNC_PROPOSAL_APPROVED = "Bookmarks_SyncProposal_approved";
public static final String BMK_SYNC_PROPOSAL_ERROR = "Bookmarks_SyncProposal_error";
public static final String BMK_SYNC_PROPOSAL_ENABLED = "Bookmarks_SyncProposal_enabled";
public static final String BMK_SYNC_PROPOSAL_TOGGLE = "Settings_BookmarksSync_toggle";
// search
public static final String SEARCH_CAT_CLICKED = "Search. Category clicked";
@ -355,6 +367,7 @@ public enum Statistics
static final String PLACEMENT = "placement";
public static final String PRICE_CATEGORY = "price_category";
public static final String DATE = "date";
static final String HAS_AUTH = "has_auth";
private EventParam() {}
}
@ -379,6 +392,8 @@ public enum Statistics
public static final String CHECKIN = "check_in";
public static final String CHECKOUT = "check_out";
public static final String ANY = "any";
public static final String GOOGLE = "google";
public static final String MAPSME = "mapsme";
}
// Initialized once in constructor and does not change until the process restarts.
@ -950,14 +965,30 @@ public enum Statistics
trackEvent(UGC_AUTH_EXTERNAL_REQUEST_SUCCESS, params().add(EventParam.PROVIDER, provider));
}
public void trackUGCAuthFailed(@NonNull String provider, @Nullable String error)
public void trackUGCAuthFailed(@Framework.AuthTokenType int type, @Nullable String error)
{
trackEvent(UGC_AUTH_ERROR, params()
.add(EventParam.PROVIDER, provider)
.add(EventParam.PROVIDER, getAuthProvider(type))
.add(EventParam.ERROR, error)
.get());
}
@NonNull
private static String getAuthProvider(@Framework.AuthTokenType int type)
{
switch (type)
{
case Framework.SOCIAL_TOKEN_FACEBOOK:
return FACEBOOK;
case Framework.SOCIAL_TOKEN_GOOGLE:
return GOOGLE;
case Framework.TOKEN_MAPSME:
return MAPSME;
default:
throw new AssertionError("Unknown social token type: " + type);
}
}
public void trackDiscoveryOpen()
{
trackEvent(DISCOVERY_OPEN, params().add(NETWORK, getConnectionState()));
@ -978,6 +1009,34 @@ public enum Statistics
.get());
}
public void trackBkmSyncProposalShown(boolean hasAuth)
{
trackEvent(BMK_SYNC_PROPOSAL_SHOWN, params().add(HAS_AUTH, hasAuth ? 1 : 0).get());
}
public void trackBkmSyncProposalApproved(boolean hasAuth)
{
trackEvent(BMK_SYNC_PROPOSAL_APPROVED, params()
.add(HAS_AUTH, hasAuth ? 1 : 0)
.add(NETWORK, getConnectionState())
.get());
}
public void trackBkmSyncProposalError(@Framework.AuthTokenType int type, @Nullable String message)
{
trackEvent(BMK_SYNC_PROPOSAL_ERROR, params()
.add(PROVIDER, getAuthProvider(type))
.add(ERROR, message)
.get());
}
public void trackBkmSettingsToggle(boolean checked)
{
trackEvent(BMK_SYNC_PROPOSAL_TOGGLE, params()
.add(STATE, checked ? 1 : 0)
.get());
}
public static ParameterBuilder params()
{
return new ParameterBuilder();