Merge pull request #6204 from brave/android_syncv2_setup_infobar

Android syncv2 setup infobar
This commit is contained in:
AlexeyBarabash
2020-07-28 23:54:25 +03:00
committed by GitHub
15 changed files with 366 additions and 66 deletions
@@ -33,7 +33,7 @@ import org.chromium.base.task.PostTask;
import org.chromium.base.task.TaskTraits;
import org.chromium.chrome.R;
import org.chromium.chrome.browser.BraveHelper;
import org.chromium.chrome.browser.BraveSyncWorkerHolder;
import org.chromium.chrome.browser.BraveSyncReflectionUtils;
import org.chromium.chrome.browser.bookmarks.BookmarkBridge;
import org.chromium.chrome.browser.bookmarks.BookmarkModel;
import org.chromium.chrome.browser.dependency_injection.ChromeActivityComponent;
@@ -210,7 +210,7 @@ public abstract class BraveActivity<C extends ChromeActivityComponent> extends C
Context app = ContextUtils.getApplicationContext();
if (null != app && (this instanceof ChromeTabbedActivity)) {
// Trigger BraveSyncWorker CTOR to make migration from sync v1 if sync is enabled
BraveSyncWorkerHolder.get();
BraveSyncReflectionUtils.getSyncWorker();
}
if (!RateUtils.getInstance(this).getPrefRateEnabled()) {
@@ -221,7 +221,7 @@ public abstract class BraveActivity<C extends ChromeActivityComponent> extends C
if (RateUtils.getInstance(this).shouldShowRateDialog())
showBraveRateDialog();
if (PackageUtils.isFirstInstall(this)
if (PackageUtils.isFirstInstall(this)
&& SharedPreferencesManager.getInstance().readInt(BravePreferenceKeys.BRAVE_APP_OPEN_COUNT) == 1) {
Calendar calender = Calendar.getInstance();
calender.setTime(new Date());
@@ -255,6 +255,7 @@ public abstract class BraveActivity<C extends ChromeActivityComponent> extends C
showCrossPromotionalDialog();
OnboardingPrefManager.getInstance().setCrossPromoModalShown(true);
}
BraveSyncReflectionUtils.showInformers();
}
private void createNotificationChannel() {
@@ -0,0 +1,99 @@
/* Copyright (c) 2020 The Brave Authors. All rights reserved.
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.chromium.chrome.browser;
import android.app.Activity;
import android.content.Context;
import android.content.SharedPreferences;
import org.chromium.base.ContextUtils;
import org.chromium.base.ApplicationStatus;
import org.chromium.base.Log;
import org.chromium.chrome.R;
import org.chromium.chrome.browser.BraveActivity;
import org.chromium.chrome.browser.BraveSyncWorker;
import org.chromium.chrome.browser.infobar.InfoBarIdentifier;
import org.chromium.chrome.browser.preferences.BravePref;
import org.chromium.chrome.browser.preferences.BravePrefServiceBridge;
import org.chromium.chrome.browser.settings.BraveSyncScreensPreference;
import org.chromium.chrome.browser.settings.SettingsLauncher;
import org.chromium.chrome.browser.settings.SettingsLauncherImpl;
import org.chromium.chrome.browser.sync.ProfileSyncService;
import org.chromium.chrome.browser.tab.Tab;
import org.chromium.chrome.browser.ui.messages.infobar.BraveSimpleConfirmInfoBarBuilder;
import org.chromium.chrome.browser.ui.messages.infobar.SimpleConfirmInfoBarBuilder;
public class BraveSyncInformers {
public static void show() {
showSetupV2IfRequired();
}
private static void showSetupV2IfRequired() {
if (null == BraveSyncReflectionUtils.getSyncWorker()) return;
BraveSyncWorker braveSyncWorker = (BraveSyncWorker)BraveSyncReflectionUtils.getSyncWorker();
boolean wasV1User = braveSyncWorker.getSyncV1WasEnabled();
if (!wasV1User) {
return;
}
boolean infobarDismissed = braveSyncWorker.getSyncV2MigrateNoticeDismissed();
if (infobarDismissed) {
return;
}
boolean isV2User = ProfileSyncService.get() != null && ProfileSyncService.get().isFirstSetupComplete();
if (isV2User) {
braveSyncWorker.setSyncV2MigrateNoticeDismissed(true);
return;
}
showSyncV2NeedsSetup();
}
public static void showSyncV2NeedsSetup() {
BraveActivity activity = BraveActivity.getBraveActivity();
if (activity == null) return;
Tab tab = activity.getActivityTabProvider().get();
if (tab == null) return;
BraveSimpleConfirmInfoBarBuilder.createInfobarWithDrawable(tab.getWebContents(),
new SimpleConfirmInfoBarBuilder.Listener() {
@Override
public void onInfoBarDismissed() {
}
@Override
public boolean onInfoBarButtonClicked(boolean isPrimary) {
if (isPrimary) {
SettingsLauncher settingsLauncher = new SettingsLauncherImpl();
settingsLauncher.launchSettingsActivity(
ContextUtils.getApplicationContext(),
BraveSyncScreensPreference.class);
}
return false;
}
@Override
public boolean onInfoBarLinkClicked() {
return false;
}
},
// must be SYNC_V2_MIGRATE_INFOBAR_DELEGATE, but now it is introduced through
// src/brave/chromium_src/components/infobars/core/infobar_delegate.h and
// java enums are generated by //components/infobars/core:infobar_generated_enums
// who does not understand `brave/chromium_src`
InfoBarIdentifier.INLINE_UPDATE_READY_INFOBAR_ANDROID,
activity,
R.drawable.sync_icon /* drawableId */,
activity.getString(R.string.brave_sync_v2_migrate_infobar_message) /* message */,
activity.getString(R.string.brave_sync_v2_migrate_infobar_command) /* primaryText */,
null /* secondaryText */, null /* linkText */, false /* autoExpire */);
BraveSyncWorker braveSyncWorker = (BraveSyncWorker)BraveSyncReflectionUtils.getSyncWorker();
braveSyncWorker.setSyncV2MigrateNoticeDismissed(true);
}
}
@@ -0,0 +1,121 @@
/* Copyright (c) 2020 The Brave Authors. All rights reserved.
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.chromium.chrome.browser;
import java.lang.reflect.Method;
import org.chromium.base.Log;
import org.chromium.base.ThreadUtils;
import org.chromium.chrome.browser.BraveConfig;
// The purpose of this class is to hide BraveSyncWorker object under `enable_brave_sync`
// and create it without explict import
public class BraveSyncReflectionUtils {
private static Object sBraveSyncWorker = null;
private static boolean sInitialized = false;
private static String TAG = "SYNC";
public static Object getSyncWorker() {
// May be invoked in non-UI thread when we do validation for camera QR in callback
if (!sInitialized) {
if (BraveConfig.SYNC_ENABLED) {
try {
sBraveSyncWorker =
Class.forName("org.chromium.chrome.browser.BraveSyncWorker")
.getConstructor()
.newInstance();
} catch (Exception e) {
Log.e(TAG, "Cannot create BraveSyncWorker ", e);
}
}
sInitialized = true;
}
return sBraveSyncWorker;
}
public static void showInformers() {
Log.e(TAG, "showInformers 000");
if (!BraveConfig.SYNC_ENABLED) {
Log.e(TAG, "showInformers !BraveConfig.SYNC_ENABLED");
return;
}
Log.e(TAG, "showInformers will show");
try {
Method method = Class.forName("org.chromium.chrome.browser.BraveSyncInformers").getDeclaredMethod("show");
method.invoke(null);
} catch (Exception e) {
Log.e(TAG, "Cannot show sync informers with reflection ", e);
}
}
// public static boolean isSyncEnabledThroughConfig() {
// if (BraveConfig.SYNC_ENABLED) {
// return true;
// } else {
// return false;
// }
// }
// public static boolean getSyncV1WasEnabled() {
// Log.e(TAG, "BraveSyncWorkerHolder.getSyncV1WasEnabled 000++");
// Object braveSyncWorker = get();
// Log.e(TAG, "BraveSyncWorkerHolder.getSyncV1WasEnabled braveSyncWorker="+braveSyncWorker);
// if (braveSyncWorker == null) return false;
//
// // Class<?> c = braveSyncWorker.getClass();
// // Log.e(TAG, "BraveSyncWorkerHolder.getSyncV1WasEnabled c.getName()="+c.getName());
// // Method[] allMethods = c.getDeclaredMethods();
// // for (Method m : allMethods) {
// // Log.e(TAG, "BraveSyncWorkerHolder.getSyncV1WasEnabled m.getName()="+m.getName());
// // }
// //
// // Log.e(TAG, "BraveSyncWorkerHolder.getSyncV1WasEnabled---------------");
// // allMethods = c.getMethods();
// // for (Method m : allMethods) {
// // Log.e(TAG, "BraveSyncWorkerHolder.getSyncV1WasEnabled getMethods m.getName()="+m.getName());
// // }
//
// try {
// java.lang.reflect.Method method = braveSyncWorker.getClass().getDeclaredMethod("getSyncV1WasEnabled");
// Object ret = method.invoke(braveSyncWorker);
// return (boolean)ret;
// } catch (Exception e) {
// Log.e(TAG, "Cannot make call with reflection ", e);
// }
// return false;
// }
//
// public static boolean getSyncV2MigrateNoticeDismissed() {
// Log.e(TAG, "BraveSyncWorkerHolder.getSyncV2MigrateNoticeDismissed 000");
// Object braveSyncWorker = get();
// if (braveSyncWorker == null) return false;
//
// java.lang.reflect.Method method;
// try {
// method = braveSyncWorker.getClass().getMethod("getSyncV2MigrateNoticeDismissed");
// Object ret = method.invoke(braveSyncWorker);
// return (boolean)ret;
// } catch (Exception e) {
// Log.e(TAG, "Cannot make call with reflection ", e);
// }
// return false;
// }
//
// public static void setSyncV2MigrateNoticeDismissed(boolean isDismissed) {
// Log.e(TAG, "BraveSyncWorkerHolder.setSyncV2MigrateNoticeDismissed 000 isDismissed="+isDismissed);
// Object braveSyncWorker = get();
// if (braveSyncWorker == null) return;
//
// java.lang.reflect.Method method;
// try {
// method = braveSyncWorker.getClass().getMethod("setSyncV2MigrateNoticeDismissed", boolean.class);
// method.invoke(braveSyncWorker, isDismissed);
// } catch (Exception e) {
// Log.e(TAG, "Cannot make call with reflection ", e);
// }
// }
}
@@ -111,6 +111,7 @@ public class BraveSyncWorker {
@Override
public void run() {
nativeMarkSyncV1WasEnabledAndMigrated();
BraveSyncInformers.show();
}
});
}
@@ -150,6 +151,18 @@ public class BraveSyncWorker {
return nativeResetSync(mNativeBraveSyncWorker);
}
public boolean getSyncV1WasEnabled() {
return nativeGetSyncV1WasEnabled(mNativeBraveSyncWorker);
}
public boolean getSyncV2MigrateNoticeDismissed() {
return nativeGetSyncV2MigrateNoticeDismissed(mNativeBraveSyncWorker);
}
public void setSyncV2MigrateNoticeDismissed(boolean isDismissed) {
nativeSetSyncV2MigrateNoticeDismissed(mNativeBraveSyncWorker, isDismissed);
}
private native void nativeInit();
private native void nativeDestroy(long nativeBraveSyncWorker);
@@ -168,4 +181,8 @@ public class BraveSyncWorker {
private native boolean nativeIsFirstSetupComplete(long nativeBraveSyncWorker);
private native boolean nativeResetSync(long nativeBraveSyncWorker);
private native boolean nativeGetSyncV1WasEnabled(long nativeBraveSyncWorker);
private native boolean nativeGetSyncV2MigrateNoticeDismissed(long nativeBraveSyncWorker);
private native void nativeSetSyncV2MigrateNoticeDismissed(long nativeBraveSyncWorker, boolean isDismissed);
}
@@ -1,47 +0,0 @@
/* Copyright (c) 2020 The Brave Authors. All rights reserved.
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.chromium.chrome.browser;
import java.lang.reflect.InvocationTargetException;
import org.chromium.base.Log;
import org.chromium.base.ThreadUtils;
import org.chromium.chrome.browser.BraveConfig;
// The purpose of this class is to hide BraveSyncWorker object under `enable_brave_sync`
// and create it without explict import
public class BraveSyncWorkerHolder {
private static Object sBraveSyncWorker = null;
private static boolean sInitialized = false;
private static String TAG = "SYNC";
public static Object get() {
// May be invoked in non-UI thread when we do validation for camera QR in callback
if (!sInitialized) {
if (BraveConfig.SYNC_ENABLED) {
try {
sBraveSyncWorker =
Class.forName("org.chromium.chrome.browser.BraveSyncWorker")
.getConstructor()
.newInstance();
} catch (ClassNotFoundException e) {
Log.e(TAG, "Cannot create BraveSyncWorker ClassNotFoundException", e);
} catch (NoSuchMethodException e) {
Log.e(TAG, "Cannot create BraveSyncWorker NoSuchMethodException", e);
} catch (IllegalAccessException e) {
Log.e(TAG, "Cannot create BraveSyncWorker IllegalAccessException", e);
} catch (InstantiationException e) {
Log.e(TAG, "Cannot create BraveSyncWorker InstantiationException", e);
} catch (InvocationTargetException e) {
Log.e(TAG, "Cannot create BraveSyncWorker InvocationTargetException", e);
}
}
sInitialized = true;
}
return sBraveSyncWorker;
}
}
@@ -72,7 +72,7 @@ import org.chromium.base.task.PostTask;
import org.chromium.chrome.R;
import org.chromium.chrome.browser.BraveActivity;
import org.chromium.chrome.browser.BraveSyncWorker;
import org.chromium.chrome.browser.BraveSyncWorkerHolder;
import org.chromium.chrome.browser.BraveSyncReflectionUtils;
import org.chromium.chrome.browser.qrreader.BarcodeTracker;
import org.chromium.chrome.browser.qrreader.BarcodeTrackerFactory;
import org.chromium.chrome.browser.qrreader.CameraSource;
@@ -163,7 +163,7 @@ public class BraveSyncScreensPreference extends BravePreferenceFragment
private FrameLayout mLayoutLaptop;
BraveSyncWorker getBraveSyncWorker() {
Object object = BraveSyncWorkerHolder.get();
Object object = BraveSyncReflectionUtils.getSyncWorker();
if (object == null) {
return null;
}
@@ -0,0 +1,55 @@
/* Copyright (c) 2020 The Brave Authors. All rights reserved.
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.chromium.chrome.browser.ui.messages.infobar;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.drawable.Drawable;
import androidx.annotation.Nullable;
import androidx.annotation.Nullable;
import androidx.core.graphics.drawable.DrawableCompat;
import androidx.core.content.ContextCompat;
import org.chromium.base.Log;
import org.chromium.chrome.browser.ui.messages.infobar.SimpleConfirmInfoBarBuilder;
import org.chromium.content_public.browser.WebContents;
// This is subclass of SimpleConfirmInfoBarBuilder which allows to pass
// drawableId of vector drawable resource
public class BraveSimpleConfirmInfoBarBuilder extends SimpleConfirmInfoBarBuilder {
public static void createInfobarWithDrawable(WebContents webContents, SimpleConfirmInfoBarBuilder.Listener listener,
int infobarTypeIdentifier,
Context context, int drawableId, String message, String primaryText,
String secondaryText, String linkText, boolean autoExpire) {
Bitmap bitmap = null;
if (drawableId != 0 && context != null) {
bitmap = convertDrawableToBitmap(context, drawableId);
}
SimpleConfirmInfoBarBuilderJni.get().create(webContents, infobarTypeIdentifier, bitmap,
message, primaryText, secondaryText, linkText, autoExpire, listener);
}
@Nullable
public static Bitmap convertDrawableToBitmap(Context context, int drawableId) {
Drawable drawable = ContextCompat.getDrawable(context, drawableId);
if (drawable == null) {
return null;
}
drawable = DrawableCompat.wrap(drawable);
Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(),
drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
drawable.draw(canvas);
return bitmap;
}
}
+4 -12
View File
@@ -1,13 +1,5 @@
-keep public class org.chromium.chrome.browser.BraveSyncWorker$JsObject
-keep public class * implements org.chromium.chrome.browser.BraveSyncWorker$JsObject
-keepclassmembers class org.chromium.chrome.browser.BraveSyncWorker$JsObject {
<methods>;
}
-keep public class org.chromium.chrome.browser.BraveSyncWorker$JsObjectWordsToBytes
-keep public class * implements org.chromium.chrome.browser.BraveSyncWorker$JsObjectWordsToBytes
-keepclassmembers class org.chromium.chrome.browser.BraveSyncWorker$JsObjectWordsToBytes {
<methods>;
}
-keepattributes JavascriptInterface
-keep class com.google.android.material.bottomsheet.BottomSheetBehavior { *; }
-keep class org.chromium.chrome.browser.BraveSyncWorker { *; }
-keep class org.chromium.chrome.browser.BraveSyncInformers { *; }
+13
View File
@@ -0,0 +1,13 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="30dp"
android:height="30dp"
android:viewportWidth="30"
android:viewportHeight="30">
<path
android:pathData="M0,0h30v30h-30z"
android:fillColor="#ffffff"/>
<path
android:pathData="M9.2641,9.2609C10.8742,9.2609 12.1848,8.041 12.3601,6.4779C16.1677,5.7965 20.0328,7.4379 21.9883,10.8261C22.1824,11.161 22.533,11.3478 22.894,11.3478C23.0704,11.3478 23.2498,11.303 23.4147,11.208C23.9135,10.92 24.0846,10.2824 23.7966,9.7826C21.3831,5.6014 16.6227,3.577 11.902,4.4577C11.3469,3.5844 10.3764,3 9.2641,3C7.535,3 6.1337,4.4014 6.1337,6.1304C6.1337,7.8595 7.535,9.2609 9.2641,9.2609ZM9.2641,20.7391C8.6495,20.7391 8.0798,20.9228 7.5956,21.2296C6.5469,20.1746 5.7789,18.8546 5.3834,17.3583C4.7918,15.12 5.0933,12.8003 6.2328,10.8261C6.5208,10.3263 6.3497,9.6887 5.8509,9.4007C5.3521,9.1127 4.7135,9.2828 4.4245,9.7826C3.0085,12.2379 2.6328,15.1169 3.3664,17.8915C3.8808,19.8376 4.9034,21.5447 6.3069,22.8856C6.2025,23.1965 6.1337,23.5231 6.1337,23.8696C6.1337,25.5986 7.5351,27 9.2641,27C10.9932,27 12.3946,25.5986 12.3946,23.8696C12.3946,22.1405 10.9932,20.7391 9.2641,20.7391ZM23.8728,12.3913C25.6018,12.3913 27.0032,13.7927 27.0032,15.5217C27.0032,17.0588 25.894,18.3308 24.4331,18.5958C23.1131,22.9075 19.2126,25.9565 14.4815,25.9565C13.9044,25.9565 13.438,25.489 13.438,24.913C13.438,24.337 13.9044,23.8696 14.4815,23.8696C18.1618,23.8696 21.2067,21.5499 22.3441,18.2379C21.3924,17.7005 20.7424,16.6925 20.7424,15.5217C20.7424,13.7927 22.1437,12.3913 23.8728,12.3913Z"
android:fillColor="#5E6175"
android:fillType="evenOdd"/>
</vector>