2074 lines
96 KiB
Diff
2074 lines
96 KiB
Diff
From: uazo <uazo@users.noreply.github.com>
|
||
Date: Thu, 7 Oct 2021 14:27:12 +0000
|
||
Subject: Bromite auto updater
|
||
|
||
Enable checking for new versions, with notifications and proxy support.
|
||
Restore InlineUpdateFlow feature.
|
||
Some parts authored by csagan5.
|
||
|
||
License: GPL-3.0-only - https://spdx.org/licenses/GPL-3.0-only.html
|
||
---
|
||
.../java/templates/BuildConfig.template | 2 +
|
||
build/config/android/rules.gni | 3 +
|
||
chrome/android/chrome_java_sources.gni | 2 +
|
||
.../java/res/xml/about_chrome_preferences.xml | 5 +
|
||
.../about_settings/AboutChromeSettings.java | 28 +-
|
||
.../omaha/CromiteUpdateStatusProvider.java | 42 +++
|
||
.../chrome/browser/omaha/OmahaBase.java | 7 +-
|
||
.../browser/omaha/UpdateMenuItemHelper.java | 89 +++++-
|
||
.../inline/BromiteInlineUpdateController.java | 285 ++++++++++++++++++
|
||
chrome/browser/BUILD.gn | 10 +
|
||
chrome/browser/endpoint_fetcher/BUILD.gn | 32 ++
|
||
chrome/browser/endpoint_fetcher/DEPS | 3 +
|
||
chrome/browser/endpoint_fetcher/OWNERS | 1 +
|
||
.../endpoint_fetcher_android.cc | 109 +++++++
|
||
.../endpoint_fetcher/EndpointFetcher.java | 63 ++++
|
||
.../EndpointHeaderResponse.java | 31 ++
|
||
.../endpoint_fetcher/EndpointResponse.java | 30 ++
|
||
.../flags/android/chrome_feature_list.cc | 1 +
|
||
.../browser/flags/ChromeFeatureList.java | 1 +
|
||
.../access_code_cast_discovery_interface.cc | 2 +-
|
||
chrome/browser/omaha/android/BUILD.gn | 3 +
|
||
.../chrome/browser/omaha/OmahaPrefUtils.java | 52 +++-
|
||
.../chrome/browser/omaha/UpdateConfigs.java | 27 +-
|
||
.../browser/omaha/UpdateStatusProvider.java | 168 +++++++----
|
||
.../browser/omaha/VersionNumberGetter.java | 4 +-
|
||
.../omaha/inline/InlineUpdateController.java | 57 ++++
|
||
.../safety_hub/SafetyHubFetchService.java | 5 -
|
||
.../browser/save_to_drive/drive_uploader.cc | 2 +-
|
||
.../strings/android_chrome_strings.grd | 23 +-
|
||
.../ui/lens/lens_overlay_query_controller.cc | 2 +-
|
||
components/commerce/core/account_checker.cc | 2 +-
|
||
.../subscriptions_server_proxy.cc | 2 +-
|
||
.../internal/composebox_query_controller.cc | 2 +-
|
||
.../data_sharing_network_loader_impl.cc | 2 +-
|
||
.../internal/preview_server_proxy.cc | 2 +-
|
||
.../endpoint_fetcher/endpoint_fetcher.cc | 127 ++++++--
|
||
.../endpoint_fetcher/endpoint_fetcher.h | 28 +-
|
||
components/manta/base_provider.cc | 4 +-
|
||
.../Bromite-auto-updater.inc | 3 +
|
||
.../Bromite-auto-updater.inc | 1 +
|
||
40 files changed, 1158 insertions(+), 104 deletions(-)
|
||
create mode 100644 chrome/android/java/src/org/chromium/chrome/browser/omaha/CromiteUpdateStatusProvider.java
|
||
create mode 100644 chrome/android/java/src/org/chromium/chrome/browser/omaha/inline/BromiteInlineUpdateController.java
|
||
create mode 100644 chrome/browser/endpoint_fetcher/BUILD.gn
|
||
create mode 100644 chrome/browser/endpoint_fetcher/DEPS
|
||
create mode 100644 chrome/browser/endpoint_fetcher/OWNERS
|
||
create mode 100644 chrome/browser/endpoint_fetcher/endpoint_fetcher_android.cc
|
||
create mode 100644 chrome/browser/endpoint_fetcher/java/src/org/chromium/chrome/browser/endpoint_fetcher/EndpointFetcher.java
|
||
create mode 100644 chrome/browser/endpoint_fetcher/java/src/org/chromium/chrome/browser/endpoint_fetcher/EndpointHeaderResponse.java
|
||
create mode 100644 chrome/browser/endpoint_fetcher/java/src/org/chromium/chrome/browser/endpoint_fetcher/EndpointResponse.java
|
||
create mode 100644 chrome/browser/omaha/android/java/src/org/chromium/chrome/browser/omaha/inline/InlineUpdateController.java
|
||
create mode 100644 cromite_flags/chrome/browser/flags/android/chrome_feature_list_cc/Bromite-auto-updater.inc
|
||
create mode 100644 cromite_flags/chrome/browser/flags/android/chrome_feature_list_h/Bromite-auto-updater.inc
|
||
|
||
diff --git a/build/android/java/templates/BuildConfig.template b/build/android/java/templates/BuildConfig.template
|
||
--- a/build/android/java/templates/BuildConfig.template
|
||
+++ b/build/android/java/templates/BuildConfig.template
|
||
@@ -83,6 +83,8 @@ public class BuildConfig {
|
||
public static boolean CRONET_FOR_AOSP_BUILD;
|
||
#endif
|
||
|
||
+ public static String BUILD_TARGET_CPU = QUOTE(_BUILD_TARGET_CPU);
|
||
+
|
||
#if defined(_WRITE_CLANG_PROFILING_DATA)
|
||
public static boolean WRITE_CLANG_PROFILING_DATA = true;
|
||
#else
|
||
diff --git a/build/config/android/rules.gni b/build/config/android/rules.gni
|
||
--- a/build/config/android/rules.gni
|
||
+++ b/build/config/android/rules.gni
|
||
@@ -1980,6 +1980,9 @@ if (!is_robolectric && enable_java_templates) {
|
||
sources = [ "//build/android/java/templates/BuildConfig.template" ]
|
||
defines = []
|
||
|
||
+ # add arch to org.chromium.build.BuildConfig
|
||
+ defines += [ "_BUILD_TARGET_CPU=${target_cpu}" ]
|
||
+
|
||
if ((defined(invoker.assertions_implicitly_enabled) &&
|
||
invoker.assertions_implicitly_enabled) || enable_java_asserts) {
|
||
defines += [ "_ENABLE_ASSERTS" ]
|
||
diff --git a/chrome/android/chrome_java_sources.gni b/chrome/android/chrome_java_sources.gni
|
||
--- a/chrome/android/chrome_java_sources.gni
|
||
+++ b/chrome/android/chrome_java_sources.gni
|
||
@@ -921,6 +921,8 @@ chrome_java_sources = [
|
||
"java/src/org/chromium/chrome/browser/omaha/OmahaBase.java",
|
||
"java/src/org/chromium/chrome/browser/omaha/OmahaDelegate.java",
|
||
"java/src/org/chromium/chrome/browser/omaha/OmahaDelegateBase.java",
|
||
+ "java/src/org/chromium/chrome/browser/omaha/CromiteUpdateStatusProvider.java",
|
||
+ "java/src/org/chromium/chrome/browser/omaha/inline/BromiteInlineUpdateController.java",
|
||
"java/src/org/chromium/chrome/browser/omaha/OmahaService.java",
|
||
"java/src/org/chromium/chrome/browser/omaha/RequestData.java",
|
||
"java/src/org/chromium/chrome/browser/omaha/RequestGenerator.java",
|
||
diff --git a/chrome/android/java/res/xml/about_chrome_preferences.xml b/chrome/android/java/res/xml/about_chrome_preferences.xml
|
||
--- a/chrome/android/java/res/xml/about_chrome_preferences.xml
|
||
+++ b/chrome/android/java/res/xml/about_chrome_preferences.xml
|
||
@@ -9,6 +9,11 @@ found in the LICENSE file.
|
||
<org.chromium.chrome.browser.about_settings.LongClickCopySummaryPreference
|
||
android:key="application_version"
|
||
android:title="@string/application_version_title" />
|
||
+ <org.chromium.components.browser_ui.settings.ChromeSwitchPreference
|
||
+ android:key="allow_inline_update"
|
||
+ android:title="@string/allow_inline_update_title"
|
||
+ android:summary="@string/allow_inline_update_summary"
|
||
+ android:defaultValue="false" />
|
||
<org.chromium.chrome.browser.about_settings.AboutChromePreferenceOSVersion
|
||
android:key="os_version"
|
||
android:title="@string/os_version_title" />
|
||
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/about_settings/AboutChromeSettings.java b/chrome/android/java/src/org/chromium/chrome/browser/about_settings/AboutChromeSettings.java
|
||
--- a/chrome/android/java/src/org/chromium/chrome/browser/about_settings/AboutChromeSettings.java
|
||
+++ b/chrome/android/java/src/org/chromium/chrome/browser/about_settings/AboutChromeSettings.java
|
||
@@ -32,10 +32,15 @@ import org.chromium.ui.widget.Toast;
|
||
|
||
import java.util.Calendar;
|
||
|
||
+import android.content.SharedPreferences;
|
||
+import org.chromium.chrome.browser.omaha.OmahaPrefUtils;
|
||
+import org.chromium.components.browser_ui.settings.ChromeSwitchPreference;
|
||
+
|
||
/** Settings fragment that displays information about Chrome. */
|
||
@NullMarked
|
||
public class AboutChromeSettings extends ChromeBaseSettingsFragment
|
||
- implements EmbeddableSettingsPage, Preference.OnPreferenceClickListener {
|
||
+ implements EmbeddableSettingsPage, Preference.OnPreferenceClickListener,
|
||
+ Preference.OnPreferenceChangeListener {
|
||
static {
|
||
CalendarFactory.warmUp();
|
||
}
|
||
@@ -43,6 +48,7 @@ public class AboutChromeSettings extends ChromeBaseSettingsFragment
|
||
private static final int TAPS_FOR_DEVELOPER_SETTINGS = 7;
|
||
|
||
private static final String PREF_APPLICATION_VERSION = "application_version";
|
||
+ private static final String PREF_ALLOW_INLINE_UPDATE = "allow_inline_update"; // switch preference
|
||
private static final String PREF_OS_VERSION = "os_version";
|
||
private static final String PREF_LEGAL_INFORMATION = "legal_information";
|
||
|
||
@@ -82,6 +88,13 @@ public class AboutChromeSettings extends ChromeBaseSettingsFragment
|
||
calendar.setTimeInMillis(System.currentTimeMillis());
|
||
int currentYear = calendar.get(Calendar.YEAR);
|
||
p.setSummary(getString(R.string.legal_information_summary, currentYear));
|
||
+
|
||
+ ChromeSwitchPreference allowInlineUpdate =
|
||
+ (ChromeSwitchPreference) findPreference(PREF_ALLOW_INLINE_UPDATE);
|
||
+ allowInlineUpdate.setChecked(
|
||
+ OmahaPrefUtils.getSharedPreferences()
|
||
+ .getBoolean(OmahaPrefUtils.PREF_ALLOW_INLINE_UPDATE, false));
|
||
+ allowInlineUpdate.setOnPreferenceChangeListener(this);
|
||
}
|
||
|
||
@Override
|
||
@@ -152,6 +165,19 @@ public class AboutChromeSettings extends ChromeBaseSettingsFragment
|
||
return true;
|
||
}
|
||
|
||
+ @Override
|
||
+ public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||
+ String key = preference.getKey();
|
||
+ if (PREF_ALLOW_INLINE_UPDATE.equals(key)) {
|
||
+ SharedPreferences.Editor sharedPreferenceEditor = OmahaPrefUtils.getSharedPreferences().edit();
|
||
+ sharedPreferenceEditor.putBoolean(OmahaPrefUtils.PREF_ALLOW_INLINE_UPDATE, (boolean) newValue);
|
||
+ sharedPreferenceEditor.apply();
|
||
+
|
||
+ OmahaPrefUtils.resetUpdatePrefs();
|
||
+ }
|
||
+ return true;
|
||
+ }
|
||
+
|
||
@Override
|
||
public @SettingsFragment.AnimationType int getAnimationType() {
|
||
return SettingsFragment.AnimationType.PROPERTY;
|
||
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omaha/CromiteUpdateStatusProvider.java b/chrome/android/java/src/org/chromium/chrome/browser/omaha/CromiteUpdateStatusProvider.java
|
||
new file mode 100644
|
||
--- /dev/null
|
||
+++ b/chrome/android/java/src/org/chromium/chrome/browser/omaha/CromiteUpdateStatusProvider.java
|
||
@@ -0,0 +1,42 @@
|
||
+package org.chromium.chrome.browser.omaha;
|
||
+
|
||
+import android.app.Activity;
|
||
+
|
||
+import org.chromium.base.ActivityState;
|
||
+import org.chromium.base.ApplicationStatus;
|
||
+
|
||
+import org.chromium.chrome.browser.app.ChromeActivity;
|
||
+
|
||
+import org.chromium.chrome.browser.omaha.UpdateStatusProvider;
|
||
+import org.chromium.chrome.browser.omaha.inline.BromiteInlineUpdateController;
|
||
+
|
||
+public class CromiteUpdateStatusProvider extends UpdateStatusProvider {
|
||
+ private static final class LazyHolder {
|
||
+ private static final UpdateStatusProvider INSTANCE = new CromiteUpdateStatusProvider();
|
||
+ }
|
||
+
|
||
+ private CromiteUpdateStatusProvider() {
|
||
+ super(new BromiteInlineUpdateController());
|
||
+ }
|
||
+
|
||
+ /** @return Returns a singleton of {@link UpdateStatusProvider}. */
|
||
+ public static UpdateStatusProvider getInstance() {
|
||
+ return LazyHolder.INSTANCE;
|
||
+ }
|
||
+
|
||
+ // ApplicationStateListener implementation.
|
||
+ @Override
|
||
+ public void onActivityStateChange(Activity changedActivity, @ActivityState int newState) {
|
||
+ boolean hasActiveActivity = false;
|
||
+
|
||
+ for (Activity activity : ApplicationStatus.getRunningActivities()) {
|
||
+ if (activity == null || !(activity instanceof ChromeActivity)) continue;
|
||
+
|
||
+ hasActiveActivity |=
|
||
+ ApplicationStatus.getStateForActivity(activity) == ActivityState.RESUMED;
|
||
+ if (hasActiveActivity) break;
|
||
+ }
|
||
+
|
||
+ mInlineController.setEnabled(hasActiveActivity);
|
||
+ }
|
||
+}
|
||
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omaha/OmahaBase.java b/chrome/android/java/src/org/chromium/chrome/browser/omaha/OmahaBase.java
|
||
--- a/chrome/android/java/src/org/chromium/chrome/browser/omaha/OmahaBase.java
|
||
+++ b/chrome/android/java/src/org/chromium/chrome/browser/omaha/OmahaBase.java
|
||
@@ -149,7 +149,8 @@ public class OmahaBase {
|
||
}
|
||
|
||
static boolean isDisabled() {
|
||
- return sDisabledForTesting;
|
||
+ // do not enable version control via Omaha Update Server
|
||
+ return true;
|
||
}
|
||
|
||
/**
|
||
@@ -592,6 +593,10 @@ public class OmahaBase {
|
||
/** Sends the request to the server and returns the response. */
|
||
static String sendRequestToServer(HttpURLConnection urlConnection, String request)
|
||
throws RequestFailureException {
|
||
+ if ((true)) {
|
||
+ throw new RequestFailureException("Requests to Omaha server are forbidden.",
|
||
+ RequestFailureException.ERROR_CONNECTIVITY);
|
||
+ }
|
||
try {
|
||
OutputStream out = new BufferedOutputStream(urlConnection.getOutputStream());
|
||
OutputStreamWriter writer = new OutputStreamWriter(out);
|
||
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omaha/UpdateMenuItemHelper.java b/chrome/android/java/src/org/chromium/chrome/browser/omaha/UpdateMenuItemHelper.java
|
||
--- a/chrome/android/java/src/org/chromium/chrome/browser/omaha/UpdateMenuItemHelper.java
|
||
+++ b/chrome/android/java/src/org/chromium/chrome/browser/omaha/UpdateMenuItemHelper.java
|
||
@@ -9,6 +9,7 @@ import android.content.ActivityNotFoundException;
|
||
import android.content.res.Resources;
|
||
import android.text.TextUtils;
|
||
import android.view.Choreographer;
|
||
+import androidx.annotation.StringRes;
|
||
|
||
import org.chromium.base.ApkInfo;
|
||
import org.chromium.base.Callback;
|
||
@@ -23,6 +24,7 @@ import org.chromium.build.annotations.Nullable;
|
||
import org.chromium.chrome.R;
|
||
import org.chromium.chrome.browser.omaha.UpdateStatusProvider.UpdateState;
|
||
import org.chromium.chrome.browser.omaha.UpdateStatusProvider.UpdateStatus;
|
||
+import org.chromium.chrome.browser.omaha.CromiteUpdateStatusProvider;
|
||
import org.chromium.chrome.browser.preferences.Pref;
|
||
import org.chromium.chrome.browser.profiles.Profile;
|
||
import org.chromium.chrome.browser.profiles.ProfileKeyedMap;
|
||
@@ -115,7 +117,7 @@ public class UpdateMenuItemHelper {
|
||
return;
|
||
}
|
||
|
||
- UpdateStatusProvider.getInstance().addObserver(mUpdateCallback);
|
||
+ CromiteUpdateStatusProvider.getInstance().addObserver(mUpdateCallback);
|
||
}
|
||
|
||
/** Unregisters {@code observer} from menu state changes. */
|
||
@@ -140,14 +142,27 @@ public class UpdateMenuItemHelper {
|
||
if (TextUtils.isEmpty(mStatus.updateUrl)) return;
|
||
|
||
try {
|
||
- UpdateStatusProvider.getInstance()
|
||
+ CromiteUpdateStatusProvider.getInstance()
|
||
.startIntentUpdate(activity, /* newTask= */ false);
|
||
} catch (ActivityNotFoundException e) {
|
||
Log.e(TAG, "Failed to launch Activity for: %s", mStatus.updateUrl);
|
||
}
|
||
break;
|
||
+ case UpdateState.VULNERABLE_VERSION:
|
||
+ // Intentional fall through.
|
||
+ case UpdateState.INLINE_UPDATE_AVAILABLE:
|
||
+ CromiteUpdateStatusProvider.getInstance().startInlineUpdate(activity);
|
||
+ break;
|
||
+ case UpdateState.INLINE_UPDATE_READY:
|
||
+ CromiteUpdateStatusProvider.getInstance().finishInlineUpdate();
|
||
+ break;
|
||
+ case UpdateState.INLINE_UPDATE_FAILED:
|
||
+ CromiteUpdateStatusProvider.getInstance().retryInlineUpdate(activity);
|
||
+ break;
|
||
case UpdateState.UNSUPPORTED_OS_VERSION:
|
||
// Intentional fall through.
|
||
+ case UpdateState.INLINE_UPDATE_DOWNLOADING:
|
||
+ // Intentional fall through.
|
||
default:
|
||
return;
|
||
}
|
||
@@ -183,7 +198,7 @@ public class UpdateMenuItemHelper {
|
||
if (mStatus == null) return;
|
||
if (mStatus.updateState != UpdateState.UNSUPPORTED_OS_VERSION) return;
|
||
|
||
- UpdateStatusProvider.getInstance().updateLatestUnsupportedVersion();
|
||
+ CromiteUpdateStatusProvider.getInstance().updateLatestUnsupportedVersion();
|
||
}
|
||
|
||
private void handleStateChanged() {
|
||
@@ -196,7 +211,7 @@ public class UpdateMenuItemHelper {
|
||
|
||
mMenuUiState = new MenuUiState();
|
||
switch (mStatus.updateState) {
|
||
- case UpdateState.UPDATE_AVAILABLE:
|
||
+ case UpdateState.UPDATE_AVAILABLE: // this is not used in Bromite
|
||
// The badge is hidden if the update menu item has been clicked until there is an
|
||
// even newer version of Chrome available.
|
||
showBadge |=
|
||
@@ -254,6 +269,72 @@ public class UpdateMenuItemHelper {
|
||
mMenuUiState.itemState.icon = R.drawable.ic_error_24dp_filled;
|
||
mMenuUiState.itemState.enabled = false;
|
||
break;
|
||
+ case UpdateState.VULNERABLE_VERSION:
|
||
+ // Intentional fall through.
|
||
+ case UpdateState.INLINE_UPDATE_AVAILABLE:
|
||
+ // The badge is hidden if the update menu item has been clicked until there is an
|
||
+ // even newer version of Chrome available.
|
||
+ @StringRes int defaultUpdateSummary = R.string.menu_update_summary_default;
|
||
+ if (mStatus.updateState == UpdateState.VULNERABLE_VERSION) {
|
||
+ // always show badge in case of vulnerable version
|
||
+ showBadge = true;
|
||
+ mMenuUiState.buttonState = new MenuButtonState();
|
||
+ mMenuUiState.buttonState.menuContentDescription = R.string.accessibility_toolbar_btn_menu_update;
|
||
+ mMenuUiState.buttonState.darkBadgeIcon =
|
||
+ R.drawable.ic_error_grey800_24dp_filled;
|
||
+ mMenuUiState.buttonState.lightBadgeIcon = R.drawable.ic_error_white_24dp_filled;
|
||
+ mMenuUiState.buttonState.adaptiveBadgeIcon = R.drawable.ic_error_24dp_filled;
|
||
+ defaultUpdateSummary = R.string.menu_update_summary_vulnerable;
|
||
+ } else {
|
||
+ showBadge |= !TextUtils.equals(
|
||
+ getPrefService().getString(
|
||
+ Pref.LATEST_VERSION_WHEN_CLICKED_UPDATE_MENU_ITEM),
|
||
+ mStatus.latestUnsupportedVersion);
|
||
+ if (showBadge) {
|
||
+ mMenuUiState.buttonState = new MenuButtonState();
|
||
+ mMenuUiState.buttonState.menuContentDescription = R.string.accessibility_toolbar_btn_menu_update;
|
||
+ mMenuUiState.buttonState.darkBadgeIcon = R.drawable.badge_update_dark;
|
||
+ mMenuUiState.buttonState.lightBadgeIcon = R.drawable.badge_update_light;
|
||
+ mMenuUiState.buttonState.adaptiveBadgeIcon = R.drawable.badge_update;
|
||
+ }
|
||
+ }
|
||
+
|
||
+ mMenuUiState.itemState = new MenuItemState();
|
||
+ mMenuUiState.itemState.title = R.string.menu_update;
|
||
+ mMenuUiState.itemState.titleColorId = R.color.default_text_color_blue_dark;
|
||
+ mMenuUiState.itemState.summary = UpdateConfigs.getCustomSummary();
|
||
+ if (TextUtils.isEmpty(mMenuUiState.itemState.summary)) {
|
||
+ mMenuUiState.itemState.summary =
|
||
+ resources.getString(defaultUpdateSummary);
|
||
+ }
|
||
+ mMenuUiState.itemState.icon = R.drawable.ic_history_24dp;
|
||
+ mMenuUiState.itemState.iconTintId = R.color.default_icon_color_blue_light;
|
||
+ mMenuUiState.itemState.enabled = true;
|
||
+ break;
|
||
+ case UpdateState.INLINE_UPDATE_DOWNLOADING:
|
||
+ mMenuUiState.itemState = new MenuItemState();
|
||
+ mMenuUiState.itemState.title = R.string.menu_inline_update_downloading;
|
||
+ mMenuUiState.itemState.titleColorId = R.color.default_text_color_secondary_dark;
|
||
+ break;
|
||
+ case UpdateState.INLINE_UPDATE_READY:
|
||
+ mMenuUiState.itemState = new MenuItemState();
|
||
+ mMenuUiState.itemState.title = R.string.menu_inline_update_ready;
|
||
+ mMenuUiState.itemState.titleColorId = R.color.default_text_color_blue_dark;
|
||
+ mMenuUiState.itemState.summary =
|
||
+ resources.getString(R.string.menu_inline_update_ready_summary);
|
||
+ mMenuUiState.itemState.icon = R.drawable.infobar_chrome;
|
||
+ mMenuUiState.itemState.iconTintId = R.color.default_icon_color_blue_light;
|
||
+ mMenuUiState.itemState.enabled = true;
|
||
+ break;
|
||
+ case UpdateState.INLINE_UPDATE_FAILED:
|
||
+ mMenuUiState.itemState = new MenuItemState();
|
||
+ mMenuUiState.itemState.title = R.string.menu_inline_update_failed;
|
||
+ mMenuUiState.itemState.titleColorId = R.color.default_text_color_blue_dark;
|
||
+ mMenuUiState.itemState.summary = resources.getString(R.string.try_again);
|
||
+ mMenuUiState.itemState.icon = R.drawable.ic_history_24dp;
|
||
+ mMenuUiState.itemState.iconTintId = R.color.default_icon_color_blue_light;
|
||
+ mMenuUiState.itemState.enabled = true;
|
||
+ break;
|
||
case UpdateState.NONE:
|
||
// Intentional fall through.
|
||
default:
|
||
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omaha/inline/BromiteInlineUpdateController.java b/chrome/android/java/src/org/chromium/chrome/browser/omaha/inline/BromiteInlineUpdateController.java
|
||
new file mode 100644
|
||
--- /dev/null
|
||
+++ b/chrome/android/java/src/org/chromium/chrome/browser/omaha/inline/BromiteInlineUpdateController.java
|
||
@@ -0,0 +1,285 @@
|
||
+// Copyright 2021 The Ungoogled Chromium Authors. All rights reserved.
|
||
+//
|
||
+// This file is part of Ungoogled Chromium Android.
|
||
+//
|
||
+// Ungoogled Chromium Android is free software: you can redistribute it
|
||
+// and/or modify it under the terms of the GNU General Public License as
|
||
+// published by the Free Software Foundation, either version 3 of the
|
||
+// License, or any later version.
|
||
+//
|
||
+// Ungoogled Chromium Android is distributed in the hope that it will be
|
||
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
|
||
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
+// GNU General Public License for more details.
|
||
+//
|
||
+// You should have received a copy of the GNU General Public License
|
||
+// along with Ungoogled Chromium Android. If not,
|
||
+// see <https://www.gnu.org/licenses/>.
|
||
+
|
||
+package org.chromium.chrome.browser.omaha.inline;
|
||
+
|
||
+import static org.chromium.chrome.browser.omaha.UpdateConfigs.getUpdateNotificationInterval;
|
||
+
|
||
+import android.app.Activity;
|
||
+import android.content.SharedPreferences;
|
||
+import android.os.Build;
|
||
+import android.text.format.DateUtils;
|
||
+import org.chromium.build.BuildConfig;
|
||
+
|
||
+import androidx.annotation.Nullable;
|
||
+
|
||
+import org.chromium.base.Callback;
|
||
+import org.chromium.base.Log;
|
||
+import org.chromium.base.task.AsyncTask;
|
||
+import org.chromium.base.task.PostTask;
|
||
+import org.chromium.base.task.TaskTraits;
|
||
+import org.chromium.chrome.browser.app.ChromeActivity;
|
||
+import org.chromium.chrome.browser.omaha.OmahaBase;
|
||
+import org.chromium.chrome.browser.omaha.OmahaPrefUtils;
|
||
+import org.chromium.chrome.browser.omaha.UpdateConfigs;
|
||
+import org.chromium.chrome.browser.omaha.UpdateStatusProvider;
|
||
+import org.chromium.chrome.browser.omaha.VersionNumber;
|
||
+import org.chromium.chrome.browser.profiles.Profile;
|
||
+import org.chromium.chrome.browser.profiles.ProfileManager;
|
||
+import org.chromium.chrome.browser.tab.TabLaunchType;
|
||
+import org.chromium.chrome.browser.tabmodel.TabCreator;
|
||
+import org.chromium.content_public.browser.LoadUrlParams;
|
||
+import org.chromium.ui.base.PageTransition;
|
||
+import org.chromium.net.NetworkTrafficAnnotationTag;
|
||
+
|
||
+import java.io.BufferedReader;
|
||
+import java.io.IOException;
|
||
+import java.io.InputStreamReader;
|
||
+import java.io.InputStream;
|
||
+import java.net.MalformedURLException;
|
||
+import java.net.URL;
|
||
+import java.net.HttpURLConnection;
|
||
+import java.util.regex.Pattern;
|
||
+
|
||
+import org.chromium.chrome.browser.endpoint_fetcher.EndpointFetcher;
|
||
+import org.chromium.chrome.browser.endpoint_fetcher.EndpointResponse;
|
||
+
|
||
+public class BromiteInlineUpdateController implements InlineUpdateController {
|
||
+
|
||
+ private static final String TAG = "BromiteInlineUpdateController";
|
||
+ private final String REDIRECT_URL_PREFIX = "https://github.com/bromite/bromite/releases/download/";
|
||
+ private static final String UPDATE_VERSION_URL = "https://github.com/bromite/bromite/releases/latest/download/";
|
||
+ private final String UPSTREAM_VERSION_URL = "https://www.bromite.org/upstream.txt";
|
||
+ public static final String VULNERABLE_VERSION_DOC_URL = "https://www.bromite.org/vulnerable-version";
|
||
+
|
||
+ @Override
|
||
+ public String getDownloadUrl() {
|
||
+ return UPDATE_VERSION_URL + BuildConfig.BUILD_TARGET_CPU + "_ChromePublic.apk";
|
||
+ }
|
||
+
|
||
+ @Override
|
||
+ public String getVulnerableVersionDocUrl() {
|
||
+ return VULNERABLE_VERSION_DOC_URL;
|
||
+ }
|
||
+
|
||
+ private static final NetworkTrafficAnnotationTag TRAFFIC_ANNOTATION =
|
||
+ NetworkTrafficAnnotationTag.createComplete("bromite_inline_update_controller",
|
||
+ "semantics {"
|
||
+ + " sender: 'Bromite Inline Update (Android)'"
|
||
+ + " description:"
|
||
+ + " 'Check for update'"
|
||
+ + " trigger: 'This request is made once, on first run'"
|
||
+ + " data: 'None.'"
|
||
+ + " destination: OTHER"
|
||
+ + " internal {"
|
||
+ + " contacts {"
|
||
+ + " email: 'uazo@users.noreply.github.com'"
|
||
+ + " }"
|
||
+ + " contacts {"
|
||
+ + " email: 'uazo@users.noreply.github.com'"
|
||
+ + " }"
|
||
+ + " }"
|
||
+ + " user_data {"
|
||
+ + " type: NONE"
|
||
+ + " }"
|
||
+ + " last_reviewed: '2023-01-01'"
|
||
+ + "}"
|
||
+ + "policy {"
|
||
+ + " cookies_allowed: NO"
|
||
+ + " setting: 'Can be disabled in Settings.'"
|
||
+ + " policy_exception_justification: 'Not implemented.'"
|
||
+ + "}");
|
||
+
|
||
+ private boolean mEnabled = true;
|
||
+ private Runnable mCallback;
|
||
+ private @Nullable @UpdateStatusProvider.UpdateState Integer mUpdateState =
|
||
+ UpdateStatusProvider.UpdateState.NONE;
|
||
+ private String mUpdateUrl = "";
|
||
+
|
||
+ public BromiteInlineUpdateController() {}
|
||
+
|
||
+ @Override
|
||
+ public void setCallback(Runnable callback) {
|
||
+ mCallback = callback;
|
||
+ }
|
||
+
|
||
+ @Override
|
||
+ public void setEnabled(boolean enabled) {
|
||
+ if (mEnabled == enabled) return;
|
||
+
|
||
+ mEnabled = enabled;
|
||
+ // check for an update when state changes
|
||
+ if (mEnabled) pullCurrentState();
|
||
+ }
|
||
+
|
||
+ @Override
|
||
+ public @Nullable @UpdateStatusProvider.UpdateState Integer getStatus() {
|
||
+ if (mEnabled) pullCurrentState();
|
||
+ return mUpdateState;
|
||
+ }
|
||
+
|
||
+ @Override
|
||
+ public String getUpdateUrl() {
|
||
+ // relies on a prior call to getStatus() to have state and URL correctly pulled
|
||
+ return mUpdateUrl;
|
||
+ }
|
||
+
|
||
+ @Override
|
||
+ public void startUpdate(Activity activity) {
|
||
+ assert ChromeActivity.class.isInstance(activity);
|
||
+ ChromeActivity thisActivity = (ChromeActivity) activity;
|
||
+ // Always open in new incognito tab
|
||
+ TabCreator tabCreator = thisActivity.getTabCreator(true);
|
||
+ tabCreator.createNewTab(new LoadUrlParams(mUpdateUrl, PageTransition.AUTO_BOOKMARK),
|
||
+ TabLaunchType.FROM_LINK, thisActivity.getActivityTab());
|
||
+ }
|
||
+
|
||
+ @Override
|
||
+ public void completeUpdate() {
|
||
+ }
|
||
+
|
||
+ private void pullCurrentState() {
|
||
+ if (OmahaPrefUtils.getSharedPreferences()
|
||
+ .getBoolean(OmahaPrefUtils.PREF_ALLOW_INLINE_UPDATE, false) == false) {
|
||
+ Log.i(TAG, "BromiteUpdater: disabled by user");
|
||
+ return;
|
||
+ }
|
||
+
|
||
+ // do not pull state if there is already a state set
|
||
+ if (mUpdateState != UpdateStatusProvider.UpdateState.NONE)
|
||
+ return;
|
||
+
|
||
+ if (shallUpdate() == false)
|
||
+ return;
|
||
+
|
||
+ switch (mUpdateState) {
|
||
+ case UpdateStatusProvider.UpdateState.INLINE_UPDATE_AVAILABLE:
|
||
+ break;
|
||
+ case UpdateStatusProvider.UpdateState.NONE:
|
||
+ OmahaPrefUtils.resetUpdatePrefs();
|
||
+ checkLatestVersion((latestVersion) -> {
|
||
+ if (latestVersion == null) return;
|
||
+
|
||
+ if (OmahaPrefUtils.isNewVersionAvailableByVersion(latestVersion)) {
|
||
+ postStatus(UpdateStatusProvider.UpdateState.INLINE_UPDATE_AVAILABLE, getDownloadUrl());
|
||
+ } else {
|
||
+ checkLatestUpstreamVersion((latestUpstreamVersion) -> {
|
||
+ if (latestUpstreamVersion == null) return;
|
||
+ if (OmahaPrefUtils.isNewVersionAvailableByVersion(latestUpstreamVersion)) {
|
||
+ postStatus(UpdateStatusProvider.UpdateState.VULNERABLE_VERSION, VULNERABLE_VERSION_DOC_URL);
|
||
+ }
|
||
+ });
|
||
+ }
|
||
+ });
|
||
+ break;
|
||
+ case UpdateStatusProvider.UpdateState.INLINE_UPDATE_READY:
|
||
+ // Intentional fall through.
|
||
+ case UpdateStatusProvider.UpdateState.INLINE_UPDATE_FAILED:
|
||
+ // Intentional fall through.
|
||
+ case UpdateStatusProvider.UpdateState.INLINE_UPDATE_DOWNLOADING:
|
||
+ // Intentional fall through.
|
||
+ case UpdateStatusProvider.UpdateState.UNSUPPORTED_OS_VERSION:
|
||
+ // Intentional fall through.
|
||
+ case UpdateStatusProvider.UpdateState.VULNERABLE_VERSION:
|
||
+ // Intentional fall through.
|
||
+ default:
|
||
+ return;
|
||
+ }
|
||
+ }
|
||
+
|
||
+ private boolean shallUpdate() {
|
||
+ long currentTime = System.currentTimeMillis();
|
||
+ SharedPreferences preferences = OmahaPrefUtils.getSharedPreferences();
|
||
+ long lastPushedTimeStamp = preferences.getLong(OmahaPrefUtils.PREF_TIMESTAMP_OF_REQUEST, 0);
|
||
+ return currentTime - lastPushedTimeStamp >= getUpdateNotificationInterval();
|
||
+ }
|
||
+
|
||
+ private void checkLatestVersion(final Callback<VersionNumber> callback) {
|
||
+ assert UPDATE_VERSION_URL != null;
|
||
+
|
||
+ String urlToCheck = getDownloadUrl();
|
||
+ Log.i(TAG, "BromiteUpdater: fetching with HEAD '%s'", urlToCheck);
|
||
+
|
||
+ EndpointFetcher.nativeHeadWithNoAuth(
|
||
+ (endpointResponse) -> {
|
||
+ boolean versionFound = false;
|
||
+ String redirectURL = endpointResponse.getRedirectUrl();
|
||
+ if (redirectURL != null) {
|
||
+ Log.i(TAG, "BromiteUpdater: obtained response '%s' and redirect URL '%s'", endpointResponse.getResponseString(), redirectURL);
|
||
+ if (redirectURL.indexOf(REDIRECT_URL_PREFIX) == 0) {
|
||
+ redirectURL = redirectURL.substring(REDIRECT_URL_PREFIX.length());
|
||
+ String[] parts = redirectURL.split(Pattern.quote("/"));
|
||
+ if (parts.length > 0) {
|
||
+ VersionNumber version = VersionNumber.fromString(parts[0]);
|
||
+ if (version != null) {
|
||
+ versionFound = true;
|
||
+ if (UPSTREAM_VERSION_URL.equals(""))
|
||
+ OmahaPrefUtils.updateLastPushedTimeStamp(System.currentTimeMillis());
|
||
+ OmahaPrefUtils.setLatestModifiedVersion(parts[0]);
|
||
+ callback.onResult(version);
|
||
+ return;
|
||
+ }
|
||
+ }
|
||
+ }
|
||
+ }
|
||
+ if (!versionFound) {
|
||
+ // retry after 1 hour
|
||
+ OmahaPrefUtils.updateLastPushedTimeStamp(
|
||
+ System.currentTimeMillis() - getUpdateNotificationInterval() -
|
||
+ DateUtils.HOUR_IN_MILLIS);
|
||
+ Log.e(TAG, "BromiteUpdater: failed, will retry in 1 hour");
|
||
+ }
|
||
+
|
||
+ callback.onResult(null);
|
||
+ },
|
||
+ ProfileManager.getLastUsedRegularProfile(),
|
||
+ urlToCheck, /*timeout*/5000, /*follow_redirect*/true, TRAFFIC_ANNOTATION);
|
||
+ }
|
||
+
|
||
+ private void checkLatestUpstreamVersion(final Callback<VersionNumber> callback) {
|
||
+ Log.i(TAG, "BromiteUpdater: fetching with GET '%s'", UPSTREAM_VERSION_URL);
|
||
+
|
||
+ EndpointFetcher.nativeFetchWithNoAuth(
|
||
+ (endpointResponse) -> {
|
||
+ String response = endpointResponse.getResponseString().trim();
|
||
+ Log.i(TAG, "BromiteUpdater: obtained upstream version update response '%s'", response);
|
||
+ VersionNumber version = VersionNumber.fromString(response);
|
||
+ if (version != null) {
|
||
+ OmahaPrefUtils.updateLastPushedTimeStamp(System.currentTimeMillis());
|
||
+ OmahaPrefUtils.setLatestUpstreamVersion(response);
|
||
+ callback.onResult(version);
|
||
+ return;
|
||
+ }
|
||
+ // retry after 1 hour
|
||
+ OmahaPrefUtils.updateLastPushedTimeStamp(
|
||
+ System.currentTimeMillis() - getUpdateNotificationInterval() -
|
||
+ DateUtils.HOUR_IN_MILLIS);
|
||
+ Log.e(TAG, "BromiteUpdater: failed to fetch upstream version, will retry in 1 hour");
|
||
+
|
||
+ callback.onResult(null);
|
||
+ },
|
||
+ ProfileManager.getLastUsedRegularProfile(),
|
||
+ UPSTREAM_VERSION_URL, /*timeout*/5000, /*follow_redirect*/false, TRAFFIC_ANNOTATION);
|
||
+ }
|
||
+
|
||
+ private void postStatus(@UpdateStatusProvider.UpdateState int status, String updateUrl) {
|
||
+ mUpdateState = status;
|
||
+ mUpdateUrl = updateUrl;
|
||
+ PostTask.postTask(TaskTraits.UI_DEFAULT, mCallback);
|
||
+ }
|
||
+}
|
||
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn
|
||
--- a/chrome/browser/BUILD.gn
|
||
+++ b/chrome/browser/BUILD.gn
|
||
@@ -4383,6 +4383,16 @@ static_library("browser") {
|
||
}
|
||
}
|
||
|
||
+ # static_library("browser")
|
||
+ if (is_android) {
|
||
+ sources += [
|
||
+ "endpoint_fetcher/endpoint_fetcher_android.cc",
|
||
+ ]
|
||
+ deps += [
|
||
+ "//chrome/browser/endpoint_fetcher:jni_headers",
|
||
+ ]
|
||
+ }
|
||
+
|
||
if (enable_screen_capture) {
|
||
sources += [
|
||
"media/capture_access_handler_base.cc",
|
||
diff --git a/chrome/browser/endpoint_fetcher/BUILD.gn b/chrome/browser/endpoint_fetcher/BUILD.gn
|
||
new file mode 100644
|
||
--- /dev/null
|
||
+++ b/chrome/browser/endpoint_fetcher/BUILD.gn
|
||
@@ -0,0 +1,32 @@
|
||
+# Copyright 2020 The Chromium Authors
|
||
+# Use of this source code is governed by a BSD-style license that can be
|
||
+# found in the LICENSE file.
|
||
+
|
||
+import("//build/config/android/rules.gni")
|
||
+import("//third_party/jni_zero/jni_zero.gni")
|
||
+
|
||
+android_library("java") {
|
||
+ deps = [
|
||
+ ":jni_headers",
|
||
+ "//base:base_java",
|
||
+ "//build/android:build_java",
|
||
+ "//chrome/browser/profiles/android:java",
|
||
+ "//net/android:net_java",
|
||
+ "//third_party/androidx:androidx_annotation_annotation_java",
|
||
+ "//third_party/jni_zero:jni_zero_java",
|
||
+ ]
|
||
+ srcjar_deps = [ ":jni_headers" ]
|
||
+ sources = [
|
||
+ "java/src/org/chromium/chrome/browser/endpoint_fetcher/EndpointFetcher.java",
|
||
+ "java/src/org/chromium/chrome/browser/endpoint_fetcher/EndpointResponse.java",
|
||
+ "java/src/org/chromium/chrome/browser/endpoint_fetcher/EndpointHeaderResponse.java",
|
||
+ ]
|
||
+}
|
||
+
|
||
+generate_jni("jni_headers") {
|
||
+ sources = [
|
||
+ "java/src/org/chromium/chrome/browser/endpoint_fetcher/EndpointFetcher.java",
|
||
+ "java/src/org/chromium/chrome/browser/endpoint_fetcher/EndpointResponse.java",
|
||
+ "java/src/org/chromium/chrome/browser/endpoint_fetcher/EndpointHeaderResponse.java",
|
||
+ ]
|
||
+}
|
||
diff --git a/chrome/browser/endpoint_fetcher/DEPS b/chrome/browser/endpoint_fetcher/DEPS
|
||
new file mode 100644
|
||
--- /dev/null
|
||
+++ b/chrome/browser/endpoint_fetcher/DEPS
|
||
@@ -0,0 +1,3 @@
|
||
+include_rules = [
|
||
+ "+components/endpoint_fetcher",
|
||
+]
|
||
diff --git a/chrome/browser/endpoint_fetcher/OWNERS b/chrome/browser/endpoint_fetcher/OWNERS
|
||
new file mode 100644
|
||
--- /dev/null
|
||
+++ b/chrome/browser/endpoint_fetcher/OWNERS
|
||
@@ -0,0 +1 @@
|
||
+file://chrome/browser/complex_tasks/OWNERS
|
||
diff --git a/chrome/browser/endpoint_fetcher/endpoint_fetcher_android.cc b/chrome/browser/endpoint_fetcher/endpoint_fetcher_android.cc
|
||
new file mode 100644
|
||
--- /dev/null
|
||
+++ b/chrome/browser/endpoint_fetcher/endpoint_fetcher_android.cc
|
||
@@ -0,0 +1,109 @@
|
||
+// Copyright 2019 The Chromium Authors
|
||
+// Use of this source code is governed by a BSD-style license that can be
|
||
+// found in the LICENSE file.
|
||
+
|
||
+#include "components/endpoint_fetcher/endpoint_fetcher.h"
|
||
+
|
||
+#include "base/android/callback_android.h"
|
||
+#include "base/android/jni_array.h"
|
||
+#include "base/android/jni_string.h"
|
||
+#include "chrome/browser/endpoint_fetcher/jni_headers/EndpointFetcher_jni.h"
|
||
+#include "chrome/browser/endpoint_fetcher/jni_headers/EndpointResponse_jni.h"
|
||
+#include "chrome/browser/endpoint_fetcher/jni_headers/EndpointHeaderResponse_jni.h"
|
||
+#include "chrome/browser/profiles/profile.h"
|
||
+#include "chrome/browser/signin/identity_manager_factory.h"
|
||
+#include "chrome/common/channel_info.h"
|
||
+#include "components/signin/public/base/consent_level.h"
|
||
+#include "components/version_info/channel.h"
|
||
+#include "content/public/browser/storage_partition.h"
|
||
+
|
||
+namespace {
|
||
+static void OnEndpointFetcherComplete(
|
||
+ const base::android::JavaRef<jobject>& jcaller,
|
||
+ // Passing the endpoint_fetcher ensures the endpoint_fetcher's
|
||
+ // lifetime extends to the callback and is not destroyed
|
||
+ // prematurely (which would result in cancellation of the request).
|
||
+ std::unique_ptr<endpoint_fetcher::EndpointFetcher> endpoint_fetcher,
|
||
+ std::unique_ptr<endpoint_fetcher::EndpointResponse> endpoint_response) {
|
||
+ base::android::RunObjectCallbackAndroid(
|
||
+ jcaller, Java_EndpointResponse_createEndpointResponse(
|
||
+ base::android::AttachCurrentThread(),
|
||
+ base::android::ConvertUTF8ToJavaString(
|
||
+ base::android::AttachCurrentThread(),
|
||
+ std::move(endpoint_response->response))));
|
||
+}
|
||
+
|
||
+static void OnEndpointFetcherHeadComplete(
|
||
+ const base::android::JavaRef<jobject>& jcaller,
|
||
+ // Passing the endpoint_fetcher ensures the endpoint_fetcher's
|
||
+ // lifetime extends to the callback and is not destroyed
|
||
+ // prematurely (which would result in cancellation of the request).
|
||
+ std::unique_ptr<endpoint_fetcher::EndpointFetcher> endpoint_fetcher,
|
||
+ std::unique_ptr<endpoint_fetcher::EndpointResponse> endpoint_response) {
|
||
+ base::android::RunObjectCallbackAndroid(
|
||
+ jcaller, Java_EndpointHeaderResponse_createEndpointResponse(
|
||
+ base::android::AttachCurrentThread(),
|
||
+ base::android::ConvertUTF8ToJavaString(
|
||
+ base::android::AttachCurrentThread(),
|
||
+ std::move(endpoint_response->response)),
|
||
+ base::android::ConvertUTF8ToJavaString(
|
||
+ base::android::AttachCurrentThread(),
|
||
+ std::move(endpoint_response->redirect_url))));
|
||
+}
|
||
+} // namespace
|
||
+
|
||
+static void JNI_EndpointFetcher_NativeFetchWithNoAuth(
|
||
+ JNIEnv* env,
|
||
+ const base::android::JavaRef<jobject>& jprofile,
|
||
+ const base::android::JavaRef<jstring>& jurl,
|
||
+ jlong jtimeout, jboolean intercept_redirect,
|
||
+ jint jannotation_hash_code,
|
||
+ const base::android::JavaRef<jobject>& jcallback) {
|
||
+ auto endpoint_fetcher = std::make_unique<endpoint_fetcher::EndpointFetcher>(
|
||
+ Profile::FromJavaObject(jprofile)
|
||
+ ->GetDefaultStoragePartition()
|
||
+ ->GetURLLoaderFactoryForBrowserProcess(),
|
||
+ GURL(base::android::ConvertJavaStringToUTF8(env, jurl)),
|
||
+ "GET",
|
||
+ jtimeout,
|
||
+ intercept_redirect,
|
||
+ net::NetworkTrafficAnnotationTag::FromJavaAnnotation(
|
||
+ jannotation_hash_code));
|
||
+ auto* const endpoint_fetcher_ptr = endpoint_fetcher.get();
|
||
+ endpoint_fetcher_ptr->PerformRequest(
|
||
+ base::BindOnce(&OnEndpointFetcherComplete,
|
||
+ base::android::ScopedJavaGlobalRef<jobject>(jcallback),
|
||
+ // unique_ptr endpoint_fetcher is passed until the callback
|
||
+ // to ensure its lifetime across the request.
|
||
+ std::move(endpoint_fetcher)),
|
||
+ nullptr);
|
||
+}
|
||
+
|
||
+static void JNI_EndpointFetcher_NativeHeadWithNoAuth(
|
||
+ JNIEnv* env,
|
||
+ const base::android::JavaRef<jobject>& jprofile,
|
||
+ const base::android::JavaRef<jstring>& jurl,
|
||
+ jlong jtimeout, jboolean intercept_redirect,
|
||
+ jint jannotation_hash_code,
|
||
+ const base::android::JavaRef<jobject>& jcallback) {
|
||
+ auto endpoint_fetcher = std::make_unique<endpoint_fetcher::EndpointFetcher>(
|
||
+ Profile::FromJavaObject(jprofile)
|
||
+ ->GetDefaultStoragePartition()
|
||
+ ->GetURLLoaderFactoryForBrowserProcess(),
|
||
+ GURL(base::android::ConvertJavaStringToUTF8(env, jurl)),
|
||
+ "HEAD",
|
||
+ jtimeout,
|
||
+ intercept_redirect,
|
||
+ net::NetworkTrafficAnnotationTag::FromJavaAnnotation(
|
||
+ jannotation_hash_code));
|
||
+ auto* const endpoint_fetcher_ptr = endpoint_fetcher.get();
|
||
+ endpoint_fetcher_ptr->PerformRequest(
|
||
+ base::BindOnce(&OnEndpointFetcherHeadComplete,
|
||
+ base::android::ScopedJavaGlobalRef<jobject>(jcallback),
|
||
+ // unique_ptr endpoint_fetcher is passed until the callback
|
||
+ // to ensure its lifetime across the request.
|
||
+ std::move(endpoint_fetcher)),
|
||
+ nullptr);
|
||
+}
|
||
+
|
||
+DEFINE_JNI(EndpointFetcher)
|
||
diff --git a/chrome/browser/endpoint_fetcher/java/src/org/chromium/chrome/browser/endpoint_fetcher/EndpointFetcher.java b/chrome/browser/endpoint_fetcher/java/src/org/chromium/chrome/browser/endpoint_fetcher/EndpointFetcher.java
|
||
new file mode 100644
|
||
--- /dev/null
|
||
+++ b/chrome/browser/endpoint_fetcher/java/src/org/chromium/chrome/browser/endpoint_fetcher/EndpointFetcher.java
|
||
@@ -0,0 +1,63 @@
|
||
+// Copyright 2019 The Chromium Authors
|
||
+// Use of this source code is governed by a BSD-style license that can be
|
||
+// found in the LICENSE file.
|
||
+
|
||
+package org.chromium.chrome.browser.endpoint_fetcher;
|
||
+
|
||
+import androidx.annotation.MainThread;
|
||
+
|
||
+import org.jni_zero.NativeMethods;
|
||
+
|
||
+import org.chromium.base.Callback;
|
||
+import org.chromium.chrome.browser.profiles.Profile;
|
||
+import org.chromium.net.NetworkTrafficAnnotationTag;
|
||
+
|
||
+/**
|
||
+ * EndpointFetcher uses native EndpointFetcher to call a HTTPS endpoint and return
|
||
+ * the response. The call to native EndpointFetcher is achieved over a static call
|
||
+ * over JNI. The native EndpointFetcher is created during the static call and
|
||
+ * destroyed in the callback function.
|
||
+ * EndpointFetcher currently doesn't support incognito mode.
|
||
+ * If the request times out an empty response will be returned. There will also
|
||
+ * be an error code indicating timeout once more detailed error messaging is added
|
||
+ * TODO(crbug.com/993393).
|
||
+ */
|
||
+public final class EndpointFetcher {
|
||
+ private EndpointFetcher() {}
|
||
+
|
||
+ @MainThread
|
||
+ public static void nativeHeadWithNoAuth(
|
||
+ Callback<EndpointHeaderResponse> callback, Profile profile,
|
||
+ String url, long timeout, boolean allow_redirect,
|
||
+ NetworkTrafficAnnotationTag annotation) {
|
||
+ EndpointFetcherJni.get().nativeHeadWithNoAuth(
|
||
+ profile, url, timeout, allow_redirect, annotation.getHashCode(), callback);
|
||
+ }
|
||
+
|
||
+ @MainThread
|
||
+ public static void nativeFetchWithNoAuth(
|
||
+ Callback<EndpointResponse> callback, Profile profile,
|
||
+ String url, long timeout, boolean allow_redirect,
|
||
+ NetworkTrafficAnnotationTag annotation) {
|
||
+ EndpointFetcherJni.get().nativeFetchWithNoAuth(
|
||
+ profile, url, timeout, allow_redirect, annotation.getHashCode(), callback);
|
||
+ }
|
||
+
|
||
+ @NativeMethods
|
||
+ public interface Natives {
|
||
+ void nativeFetchWithNoAuth(
|
||
+ Profile profile,
|
||
+ String url,
|
||
+ long timeout,
|
||
+ boolean allow_redirect,
|
||
+ int annotationHashCode,
|
||
+ Callback<EndpointResponse> callback);
|
||
+ void nativeHeadWithNoAuth(
|
||
+ Profile profile,
|
||
+ String url,
|
||
+ long timeout,
|
||
+ boolean allow_redirect,
|
||
+ int annotationHashCode,
|
||
+ Callback<EndpointHeaderResponse> callback);
|
||
+ }
|
||
+}
|
||
diff --git a/chrome/browser/endpoint_fetcher/java/src/org/chromium/chrome/browser/endpoint_fetcher/EndpointHeaderResponse.java b/chrome/browser/endpoint_fetcher/java/src/org/chromium/chrome/browser/endpoint_fetcher/EndpointHeaderResponse.java
|
||
new file mode 100644
|
||
--- /dev/null
|
||
+++ b/chrome/browser/endpoint_fetcher/java/src/org/chromium/chrome/browser/endpoint_fetcher/EndpointHeaderResponse.java
|
||
@@ -0,0 +1,31 @@
|
||
+// Copyright 2019 The Chromium Authors. All rights reserved.
|
||
+// Use of this source code is governed by a BSD-style license that can be
|
||
+// found in the LICENSE file.
|
||
+
|
||
+package org.chromium.chrome.browser.endpoint_fetcher;
|
||
+
|
||
+import org.jni_zero.CalledByNative;
|
||
+
|
||
+public class EndpointHeaderResponse {
|
||
+ private final String mResponseString;
|
||
+ private final String mRedirectUrl;
|
||
+
|
||
+ public EndpointHeaderResponse(String responseString, String redirectUrl) {
|
||
+ mResponseString = responseString;
|
||
+ mRedirectUrl = redirectUrl;
|
||
+ }
|
||
+
|
||
+ public String getResponseString() {
|
||
+ return mResponseString;
|
||
+ }
|
||
+
|
||
+ public String getRedirectUrl() {
|
||
+ return mRedirectUrl;
|
||
+ }
|
||
+
|
||
+ @CalledByNative
|
||
+ private static EndpointHeaderResponse createEndpointResponse(
|
||
+ String response, String redirectUrl) {
|
||
+ return new EndpointHeaderResponse(response, redirectUrl);
|
||
+ }
|
||
+}
|
||
diff --git a/chrome/browser/endpoint_fetcher/java/src/org/chromium/chrome/browser/endpoint_fetcher/EndpointResponse.java b/chrome/browser/endpoint_fetcher/java/src/org/chromium/chrome/browser/endpoint_fetcher/EndpointResponse.java
|
||
new file mode 100644
|
||
--- /dev/null
|
||
+++ b/chrome/browser/endpoint_fetcher/java/src/org/chromium/chrome/browser/endpoint_fetcher/EndpointResponse.java
|
||
@@ -0,0 +1,30 @@
|
||
+// Copyright 2019 The Chromium Authors
|
||
+// Use of this source code is governed by a BSD-style license that can be
|
||
+// found in the LICENSE file.
|
||
+
|
||
+package org.chromium.chrome.browser.endpoint_fetcher;
|
||
+
|
||
+import org.jni_zero.CalledByNative;
|
||
+
|
||
+/** Encapsulates the response from the {@Link EndpointFetcher} */
|
||
+public class EndpointResponse {
|
||
+ private final String mResponseString;
|
||
+
|
||
+ /**
|
||
+ * Create the EndpointResponse
|
||
+ * @param responseString the response string acquired from the endpoint
|
||
+ */
|
||
+ public EndpointResponse(String responseString) {
|
||
+ mResponseString = responseString;
|
||
+ }
|
||
+
|
||
+ /** Response string acquired from calling an endpoint */
|
||
+ public String getResponseString() {
|
||
+ return mResponseString;
|
||
+ }
|
||
+
|
||
+ @CalledByNative
|
||
+ private static EndpointResponse createEndpointResponse(String response) {
|
||
+ return new EndpointResponse(response);
|
||
+ }
|
||
+}
|
||
diff --git a/chrome/browser/flags/android/chrome_feature_list.cc b/chrome/browser/flags/android/chrome_feature_list.cc
|
||
--- a/chrome/browser/flags/android/chrome_feature_list.cc
|
||
+++ b/chrome/browser/flags/android/chrome_feature_list.cc
|
||
@@ -420,6 +420,7 @@ const base::Feature* const kFeaturesExposedToJava[] = {
|
||
&kProtectedTabsAndroid,
|
||
&kPwaRestoreUi,
|
||
&kPwaRestoreUiAtStartup,
|
||
+ &kInlineUpdateFlow,
|
||
&kReadAloudAudioOverviews,
|
||
&kReadAloudIPHMenuButtonHighlightCCT,
|
||
&kReadAloudPlayback,
|
||
diff --git a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java
|
||
--- a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java
|
||
+++ b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java
|
||
@@ -504,6 +504,7 @@ public abstract class ChromeFeatureList {
|
||
public static final String INCOGNITO_NTP_SMALL_ICON = "IncognitoNtpSmallIcon";
|
||
public static final String INCOGNITO_SCREENSHOT = "IncognitoScreenshot";
|
||
public static final String INCOGNITO_THEME_OVERLAY_TESTING = "IncognitoThemeOverlayTesting";
|
||
+ public static final String INLINE_UPDATE_FLOW = "InlineUpdateFlow";
|
||
public static final String INLINE_PDF_V2 = "InlinePdfV2";
|
||
public static final String KEYBOARD_ESC_BACK_NAVIGATION = "KeyboardEscBackNavigation";
|
||
public static final String LAUNCH_CAUSE_SCREEN_OFF_FIX = "LaunchCauseScreenOffFix";
|
||
diff --git a/chrome/browser/media/router/discovery/access_code/access_code_cast_discovery_interface.cc b/chrome/browser/media/router/discovery/access_code/access_code_cast_discovery_interface.cc
|
||
--- a/chrome/browser/media/router/discovery/access_code/access_code_cast_discovery_interface.cc
|
||
+++ b/chrome/browser/media/router/discovery/access_code/access_code_cast_discovery_interface.cc
|
||
@@ -265,7 +265,7 @@ AccessCodeCastDiscoveryInterface::CreateEndpointFetcher(
|
||
.SetTimeout(kTimeout)
|
||
.SetUrl(GURL(base::StrCat({GetDiscoveryUrl(), "/", access_code})))
|
||
.SetPostData(kEmptyPostData)
|
||
- .Build());
|
||
+ .Build(), kTrafficAnnotation);
|
||
}
|
||
|
||
void AccessCodeCastDiscoveryInterface::ValidateDiscoveryAccessCode(
|
||
diff --git a/chrome/browser/omaha/android/BUILD.gn b/chrome/browser/omaha/android/BUILD.gn
|
||
--- a/chrome/browser/omaha/android/BUILD.gn
|
||
+++ b/chrome/browser/omaha/android/BUILD.gn
|
||
@@ -19,6 +19,9 @@ android_library("java") {
|
||
"java/src/org/chromium/chrome/browser/omaha/metrics/TrackingProvider.java",
|
||
"java/src/org/chromium/chrome/browser/omaha/metrics/UpdateSuccessMetrics.java",
|
||
]
|
||
+ sources += [
|
||
+ "java/src/org/chromium/chrome/browser/omaha/inline/InlineUpdateController.java",
|
||
+ ]
|
||
deps = [
|
||
":update_proto_java",
|
||
"//base:base_java",
|
||
diff --git a/chrome/browser/omaha/android/java/src/org/chromium/chrome/browser/omaha/OmahaPrefUtils.java b/chrome/browser/omaha/android/java/src/org/chromium/chrome/browser/omaha/OmahaPrefUtils.java
|
||
--- a/chrome/browser/omaha/android/java/src/org/chromium/chrome/browser/omaha/OmahaPrefUtils.java
|
||
+++ b/chrome/browser/omaha/android/java/src/org/chromium/chrome/browser/omaha/OmahaPrefUtils.java
|
||
@@ -7,8 +7,10 @@ package org.chromium.chrome.browser.omaha;
|
||
import android.content.Context;
|
||
import android.content.SharedPreferences;
|
||
|
||
+import org.chromium.base.Log;
|
||
import org.chromium.base.ContextUtils;
|
||
import org.chromium.build.annotations.NullMarked;
|
||
+import org.chromium.base.version_info.VersionInfo;
|
||
|
||
@NullMarked
|
||
public class OmahaPrefUtils {
|
||
@@ -24,7 +26,55 @@ public class OmahaPrefUtils {
|
||
static final String PREF_TIMESTAMP_FOR_NEW_REQUEST = "timestampForNewRequest";
|
||
static final String PREF_TIMESTAMP_FOR_NEXT_POST_ATTEMPT = "timestampForNextPostAttempt";
|
||
static final String PREF_TIMESTAMP_OF_INSTALL = "timestampOfInstall";
|
||
- static final String PREF_TIMESTAMP_OF_REQUEST = "timestampOfRequest";
|
||
+ public static final String PREF_TIMESTAMP_OF_REQUEST = "timestampOfRequest";
|
||
+ static final String PREF_LATEST_MODIFIED_VERSION = "latestModifiedVersion";
|
||
+ static final String PREF_LATEST_UPSTREAM_VERSION = "latestUpstreamVersion";
|
||
+ public static final String PREF_ALLOW_INLINE_UPDATE = "allowInlineUpdate";
|
||
+
|
||
+ static final String TAG = "omaha_utils";
|
||
+
|
||
+ public static boolean isNewVersionAvailableByVersion(VersionNumber latestVersion) {
|
||
+ VersionNumber mCurrentProductVersion = VersionNumber.fromString(VersionInfo.getProductVersion());
|
||
+ if (mCurrentProductVersion == null) {
|
||
+ Log.e(TAG, "BromiteUpdater: current product version is null");
|
||
+ return false;
|
||
+ }
|
||
+
|
||
+ Log.i(TAG, "BromiteUpdater: currentProductVersion=%s, latestVersion=%s",
|
||
+ mCurrentProductVersion.toString(), latestVersion.toString());
|
||
+
|
||
+ return mCurrentProductVersion.isSmallerThan(latestVersion);
|
||
+ }
|
||
+
|
||
+ public static void updateLastPushedTimeStamp(long timeMillis) {
|
||
+ SharedPreferences preferences = getSharedPreferences();
|
||
+ SharedPreferences.Editor editor = preferences.edit();
|
||
+ editor.putLong(PREF_TIMESTAMP_OF_REQUEST, timeMillis);
|
||
+ editor.apply();
|
||
+ }
|
||
+
|
||
+ public static void setLatestModifiedVersion(String version) {
|
||
+ SharedPreferences preferences = getSharedPreferences();
|
||
+ SharedPreferences.Editor editor = preferences.edit();
|
||
+ editor.putString(PREF_LATEST_MODIFIED_VERSION, version);
|
||
+ editor.apply();
|
||
+ }
|
||
+
|
||
+ public static void setLatestUpstreamVersion(String version) {
|
||
+ SharedPreferences preferences = getSharedPreferences();
|
||
+ SharedPreferences.Editor editor = preferences.edit();
|
||
+ editor.putString(PREF_LATEST_UPSTREAM_VERSION, version);
|
||
+ editor.apply();
|
||
+ }
|
||
+
|
||
+ public static void resetUpdatePrefs() {
|
||
+ SharedPreferences preferences = getSharedPreferences();
|
||
+ SharedPreferences.Editor editor = preferences.edit();
|
||
+ editor.putLong(PREF_TIMESTAMP_OF_REQUEST, 0);
|
||
+ editor.putString(PREF_LATEST_MODIFIED_VERSION, "");
|
||
+ editor.putString(PREF_LATEST_UPSTREAM_VERSION, "");
|
||
+ editor.apply();
|
||
+ }
|
||
|
||
/** Returns the Omaha SharedPreferences. */
|
||
public static SharedPreferences getSharedPreferences() {
|
||
diff --git a/chrome/browser/omaha/android/java/src/org/chromium/chrome/browser/omaha/UpdateConfigs.java b/chrome/browser/omaha/android/java/src/org/chromium/chrome/browser/omaha/UpdateConfigs.java
|
||
--- a/chrome/browser/omaha/android/java/src/org/chromium/chrome/browser/omaha/UpdateConfigs.java
|
||
+++ b/chrome/browser/omaha/android/java/src/org/chromium/chrome/browser/omaha/UpdateConfigs.java
|
||
@@ -12,6 +12,7 @@ import androidx.annotation.IntDef;
|
||
import org.chromium.base.CommandLine;
|
||
import org.chromium.build.annotations.NullMarked;
|
||
import org.chromium.build.annotations.Nullable;
|
||
+import org.chromium.chrome.browser.flags.ChromeFeatureList;
|
||
import org.chromium.chrome.browser.flags.ChromeSwitches;
|
||
import org.chromium.chrome.browser.omaha.UpdateStatusProvider.UpdateState;
|
||
import org.chromium.components.variations.VariationsAssociatedData;
|
||
@@ -38,10 +39,12 @@ public class UpdateConfigs {
|
||
private static final String UPDATE_AVAILABLE_SWITCH_VALUE = "update_available";
|
||
private static final String UNSUPPORTED_OS_VERSION_SWITCH_VALUE = "unsupported_os_version";
|
||
|
||
+ private static final long DEFAULT_UPDATE_NOTIFICATION_INTERVAL = 3 * DateUtils.DAY_IN_MILLIS;
|
||
private static final long DEFAULT_UPDATE_ATTRIBUTION_WINDOW_MS = 2 * DateUtils.DAY_IN_MILLIS;
|
||
|
||
/** Possible update flow configurations. */
|
||
- @IntDef({UpdateFlowConfiguration.NEVER_SHOW, UpdateFlowConfiguration.INTENT_ONLY})
|
||
+ @IntDef({UpdateFlowConfiguration.NEVER_SHOW, UpdateFlowConfiguration.INTENT_ONLY,
|
||
+ UpdateFlowConfiguration.INLINE_ONLY})
|
||
@Retention(RetentionPolicy.SOURCE)
|
||
public @interface UpdateFlowConfiguration {
|
||
/** Turns off all update indicators. */
|
||
@@ -51,6 +54,12 @@ public class UpdateConfigs {
|
||
* Requires Omaha to say an update is available, and only ever Intents out to Play Store.
|
||
*/
|
||
int INTENT_ONLY = 2;
|
||
+
|
||
+ /**
|
||
+ * Inline updates that contact Bromite official GitHub repository to say whether an update is available.
|
||
+ * Only ever uses the inline update flow.
|
||
+ */
|
||
+ int INLINE_ONLY = 3;
|
||
}
|
||
|
||
/**
|
||
@@ -126,6 +135,13 @@ public class UpdateConfigs {
|
||
return DEFAULT_UPDATE_ATTRIBUTION_WINDOW_MS;
|
||
}
|
||
|
||
+ /**
|
||
+ * @return A time interval for scheduling update notification. Unit: mills.
|
||
+ */
|
||
+ public static long getUpdateNotificationInterval() {
|
||
+ return DEFAULT_UPDATE_NOTIFICATION_INTERVAL;
|
||
+ }
|
||
+
|
||
/**
|
||
* Gets a String VariationsAssociatedData parameter. Also checks for a command-line switch
|
||
* with the same name, for easy local testing.
|
||
@@ -139,4 +155,13 @@ public class UpdateConfigs {
|
||
}
|
||
return value;
|
||
}
|
||
+
|
||
+ @UpdateFlowConfiguration
|
||
+ public static int getConfiguration() {
|
||
+ if (!ChromeFeatureList.isEnabled(ChromeFeatureList.INLINE_UPDATE_FLOW)) {
|
||
+ // Always use the the old flow if the inline update flow feature is not enabled.
|
||
+ return UpdateFlowConfiguration.INLINE_ONLY;
|
||
+ }
|
||
+ return UpdateFlowConfiguration.NEVER_SHOW;
|
||
+ }
|
||
}
|
||
diff --git a/chrome/browser/omaha/android/java/src/org/chromium/chrome/browser/omaha/UpdateStatusProvider.java b/chrome/browser/omaha/android/java/src/org/chromium/chrome/browser/omaha/UpdateStatusProvider.java
|
||
--- a/chrome/browser/omaha/android/java/src/org/chromium/chrome/browser/omaha/UpdateStatusProvider.java
|
||
+++ b/chrome/browser/omaha/android/java/src/org/chromium/chrome/browser/omaha/UpdateStatusProvider.java
|
||
@@ -6,6 +6,7 @@ package org.chromium.chrome.browser.omaha;
|
||
|
||
import static org.chromium.build.NullUtil.assumeNonNull;
|
||
|
||
+import android.app.Activity;
|
||
import android.content.ActivityNotFoundException;
|
||
import android.content.Context;
|
||
import android.content.Intent;
|
||
@@ -15,9 +16,11 @@ import android.os.StatFs;
|
||
import android.text.TextUtils;
|
||
|
||
import androidx.annotation.IntDef;
|
||
+import androidx.annotation.VisibleForTesting;
|
||
|
||
-import com.google.android.gms.common.GooglePlayServicesUtil;
|
||
-
|
||
+import org.chromium.base.ActivityState;
|
||
+import org.chromium.base.ApplicationStatus;
|
||
+import org.chromium.base.ApplicationStatus.ActivityStateListener;
|
||
import org.chromium.base.ApkInfo;
|
||
import org.chromium.base.Callback;
|
||
import org.chromium.base.DeviceInfo;
|
||
@@ -31,6 +34,7 @@ import org.chromium.base.task.TaskTraits;
|
||
import org.chromium.build.annotations.NullMarked;
|
||
import org.chromium.build.annotations.Nullable;
|
||
import org.chromium.build.annotations.RequiresNonNull;
|
||
+import org.chromium.chrome.browser.omaha.inline.InlineUpdateController;
|
||
import org.chromium.chrome.browser.omaha.metrics.UpdateSuccessMetrics;
|
||
import org.chromium.chrome.browser.preferences.ChromePreferenceKeys;
|
||
import org.chromium.chrome.browser.preferences.ChromeSharedPreferences;
|
||
@@ -40,6 +44,11 @@ import java.io.File;
|
||
import java.lang.annotation.Retention;
|
||
import java.lang.annotation.RetentionPolicy;
|
||
|
||
+import org.chromium.base.Log;
|
||
+import android.content.SharedPreferences;
|
||
+import android.os.Build;
|
||
+import org.chromium.build.BuildConfig;
|
||
+
|
||
/**
|
||
* Provides the current update state for Chrome. This update state is asynchronously determined and
|
||
* can change as Chrome runs.
|
||
@@ -47,24 +56,26 @@ import java.lang.annotation.RetentionPolicy;
|
||
* For manually testing this functionality, see {@link UpdateConfigs}.
|
||
*/
|
||
@NullMarked
|
||
-public class UpdateStatusProvider {
|
||
+public abstract class UpdateStatusProvider implements ActivityStateListener {
|
||
/**
|
||
* Possible update states.
|
||
* Treat this as append only as it is used by UMA.
|
||
*/
|
||
- @IntDef({UpdateState.NONE, UpdateState.UPDATE_AVAILABLE, UpdateState.UNSUPPORTED_OS_VERSION})
|
||
+ @IntDef({UpdateState.NONE, UpdateState.UPDATE_AVAILABLE, UpdateState.UNSUPPORTED_OS_VERSION,
|
||
+ UpdateState.INLINE_UPDATE_AVAILABLE, UpdateState.INLINE_UPDATE_DOWNLOADING,
|
||
+ UpdateState.INLINE_UPDATE_READY, UpdateState.INLINE_UPDATE_FAILED, UpdateState.VULNERABLE_VERSION})
|
||
@Retention(RetentionPolicy.SOURCE)
|
||
public @interface UpdateState {
|
||
int NONE = 0;
|
||
int UPDATE_AVAILABLE = 1;
|
||
int UNSUPPORTED_OS_VERSION = 2;
|
||
- // Inline updates are deprecated.
|
||
- // int INLINE_UPDATE_AVAILABLE = 3;
|
||
- // int INLINE_UPDATE_DOWNLOADING = 4;
|
||
- // int INLINE_UPDATE_READY = 5;
|
||
- // int INLINE_UPDATE_FAILED = 6;
|
||
+ int INLINE_UPDATE_AVAILABLE = 3;
|
||
+ int INLINE_UPDATE_DOWNLOADING = 4;
|
||
+ int INLINE_UPDATE_READY = 5;
|
||
+ int INLINE_UPDATE_FAILED = 6;
|
||
+ int VULNERABLE_VERSION = 7;
|
||
|
||
- int NUM_ENTRIES = 7;
|
||
+ int NUM_ENTRIES = 8;
|
||
}
|
||
|
||
/** A set of properties that represent the current update state for Chrome. */
|
||
@@ -98,6 +109,12 @@ public class UpdateStatusProvider {
|
||
*/
|
||
private boolean mIsSimulated;
|
||
|
||
+ /**
|
||
+ * Whether or not we are currently trying to simulate an inline flow. Used to allow
|
||
+ * overriding Omaha update state, which usually supersedes inline update states.
|
||
+ */
|
||
+ private boolean mIsInlineSimulated;
|
||
+
|
||
public UpdateStatus() {}
|
||
|
||
UpdateStatus(UpdateStatus other) {
|
||
@@ -106,11 +123,13 @@ public class UpdateStatusProvider {
|
||
latestVersion = other.latestVersion;
|
||
latestUnsupportedVersion = other.latestUnsupportedVersion;
|
||
mIsSimulated = other.mIsSimulated;
|
||
+ mIsInlineSimulated = other.mIsInlineSimulated;
|
||
}
|
||
}
|
||
|
||
private final ObserverList<Callback<UpdateStatus>> mObservers = new ObserverList<>();
|
||
|
||
+ protected final InlineUpdateController mInlineController;
|
||
private final UpdateQuery mOmahaQuery;
|
||
private final UpdateSuccessMetrics mMetrics;
|
||
private @Nullable UpdateStatus mStatus;
|
||
@@ -118,11 +137,6 @@ public class UpdateStatusProvider {
|
||
/** Whether or not we've recorded the initial update status yet. */
|
||
private boolean mRecordedInitialStatus;
|
||
|
||
- /** @return Returns a singleton of {@link UpdateStatusProvider}. */
|
||
- public static UpdateStatusProvider getInstance() {
|
||
- return LazyHolder.INSTANCE;
|
||
- }
|
||
-
|
||
/**
|
||
* Adds {@code observer} to notify about update state changes. It is safe to call this multiple
|
||
* times with the same {@code observer}. This method will always notify {@code observer} of the
|
||
@@ -178,6 +192,30 @@ public class UpdateStatusProvider {
|
||
pingObservers();
|
||
}
|
||
|
||
+ /**
|
||
+ * Starts the inline update process, if possible.
|
||
+ * @param activity An {@link Activity} that will be used to interact with Play.
|
||
+ */
|
||
+ public void startInlineUpdate(Activity activity) {
|
||
+ if (mStatus == null || (mStatus.updateState != UpdateState.INLINE_UPDATE_AVAILABLE && mStatus.updateState != UpdateState.VULNERABLE_VERSION)) return;
|
||
+ mInlineController.startUpdate(activity);
|
||
+ }
|
||
+
|
||
+ /**
|
||
+ * Retries the inline update process, if possible.
|
||
+ * @param activity An {@link Activity} that will be used to interact with Play.
|
||
+ */
|
||
+ public void retryInlineUpdate(Activity activity) {
|
||
+ if (mStatus == null || (mStatus.updateState != UpdateState.INLINE_UPDATE_AVAILABLE && mStatus.updateState != UpdateState.VULNERABLE_VERSION)) return;
|
||
+ mInlineController.startUpdate(activity);
|
||
+ }
|
||
+
|
||
+ /** Finishes the inline update process, which may involve restarting the app. */
|
||
+ public void finishInlineUpdate() {
|
||
+ if (mStatus == null || mStatus.updateState != UpdateState.INLINE_UPDATE_READY) return;
|
||
+ mInlineController.completeUpdate();
|
||
+ }
|
||
+
|
||
/**
|
||
* Starts the intent update process, if possible
|
||
* @param context An {@link Context} that will be used to fire off the update intent.
|
||
@@ -185,12 +223,11 @@ public class UpdateStatusProvider {
|
||
* @return Whether or not the update intent was sent and had a valid handler.
|
||
*/
|
||
public boolean startIntentUpdate(Context context, boolean newTask) {
|
||
+ // currently not used in Bromite
|
||
if (mStatus == null || mStatus.updateState != UpdateState.UPDATE_AVAILABLE) return false;
|
||
if (TextUtils.isEmpty(mStatus.updateUrl)) return false;
|
||
|
||
try {
|
||
- mMetrics.startUpdate();
|
||
-
|
||
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(mStatus.updateUrl));
|
||
// Ensure that the app vs browser disambiguation dialog is not shown.
|
||
intent.addFlags(Intent.FLAG_ACTIVITY_REQUIRE_NON_BROWSER);
|
||
@@ -203,9 +240,15 @@ public class UpdateStatusProvider {
|
||
return true;
|
||
}
|
||
|
||
- private UpdateStatusProvider() {
|
||
- mOmahaQuery = new UpdateQuery(this::resolveStatus);
|
||
+ protected UpdateStatusProvider(InlineUpdateController inlineController) {
|
||
+ mInlineController = inlineController;
|
||
+ mInlineController.setCallback(this::resolveStatus);
|
||
+
|
||
+ mOmahaQuery = new UpdateQuery(mInlineController, this::resolveStatus);
|
||
mMetrics = new UpdateSuccessMetrics();
|
||
+
|
||
+ // Note that as a singleton this class never unregisters.
|
||
+ ApplicationStatus.registerStateListenerForAllActivities(this);
|
||
}
|
||
|
||
@RequiresNonNull("mStatus")
|
||
@@ -214,35 +257,52 @@ public class UpdateStatusProvider {
|
||
}
|
||
|
||
private void resolveStatus() {
|
||
- if (mOmahaQuery.getStatus() != Status.FINISHED) {
|
||
+ if (mOmahaQuery.getStatus() != Status.FINISHED || mInlineController.getStatus() == null) {
|
||
return;
|
||
}
|
||
|
||
// We pull the Omaha result once as it will never change.
|
||
if (mStatus == null) mStatus = new UpdateStatus(assumeNonNull(mOmahaQuery.getResult()));
|
||
|
||
- if (!mStatus.mIsSimulated) {
|
||
- mStatus.updateState = assumeNonNull(mOmahaQuery.getResult()).updateState;
|
||
+ if (mStatus.mIsSimulated) { // used only during tests
|
||
+ if (mStatus.mIsInlineSimulated) {
|
||
+ @UpdateState
|
||
+ int inlineState = mInlineController.getStatus();
|
||
+ String updateUrl = mInlineController.getUpdateUrl();
|
||
+
|
||
+ if (inlineState == UpdateState.NONE) {
|
||
+ mStatus.updateState = assumeNonNull(mOmahaQuery.getResult()).updateState;
|
||
+ } else {
|
||
+ mStatus.updateState = inlineState;
|
||
+ mStatus.updateUrl = updateUrl;
|
||
+ }
|
||
+ }
|
||
+ } else {
|
||
+ // used by Bromite to resolve update status
|
||
+ // ignores Omaha status
|
||
+ @UpdateState
|
||
+ int inlineState = mInlineController.getStatus();
|
||
+ mStatus.updateState = inlineState;
|
||
+ mStatus.updateUrl = mInlineController.getUpdateUrl();
|
||
}
|
||
|
||
if (!mRecordedInitialStatus) {
|
||
- mMetrics.analyzeFirstStatus();
|
||
mRecordedInitialStatus = true;
|
||
}
|
||
|
||
pingObservers();
|
||
}
|
||
|
||
- private static final class LazyHolder {
|
||
- private static final UpdateStatusProvider INSTANCE = new UpdateStatusProvider();
|
||
- }
|
||
-
|
||
private static final class UpdateQuery extends AsyncTask<UpdateStatus> {
|
||
+ static final String TAG = "UpdateStatusProvider";
|
||
private final Runnable mCallback;
|
||
|
||
private @Nullable UpdateStatus mStatus;
|
||
|
||
- public UpdateQuery(Runnable resultReceiver) {
|
||
+ private InlineUpdateController mInlineController;
|
||
+
|
||
+ public UpdateQuery(InlineUpdateController inlineController, Runnable resultReceiver) {
|
||
+ mInlineController = inlineController;
|
||
mCallback = resultReceiver;
|
||
}
|
||
|
||
@@ -254,7 +314,7 @@ public class UpdateStatusProvider {
|
||
protected UpdateStatus doInBackground() {
|
||
UpdateStatus testStatus = getTestStatus();
|
||
if (testStatus != null) return testStatus;
|
||
- return getRealStatus();
|
||
+ return getActualStatus();
|
||
}
|
||
|
||
@Override
|
||
@@ -272,6 +332,8 @@ public class UpdateStatusProvider {
|
||
status.mIsSimulated = true;
|
||
status.updateState = forcedUpdateState;
|
||
|
||
+ status.mIsInlineSimulated = forcedUpdateState == UpdateState.INLINE_UPDATE_AVAILABLE;
|
||
+
|
||
// Push custom configurations for certain update states.
|
||
switch (forcedUpdateState) {
|
||
case UpdateState.UPDATE_AVAILABLE:
|
||
@@ -289,31 +351,33 @@ public class UpdateStatusProvider {
|
||
return status;
|
||
}
|
||
|
||
- private UpdateStatus getRealStatus() {
|
||
+ private UpdateStatus getActualStatus() {
|
||
UpdateStatus status = new UpdateStatus();
|
||
|
||
- if (VersionNumberGetter.isNewerVersionAvailable()) {
|
||
- status.updateUrl = MarketURLGetter.getMarketUrl();
|
||
- status.latestVersion = VersionNumberGetter.getInstance().getLatestKnownVersion();
|
||
-
|
||
- boolean allowedToUpdate =
|
||
- checkForSufficientStorage()
|
||
- // Disable the version update check for automotive. See b/297925838.
|
||
- && !DeviceInfo.isAutomotive()
|
||
- && PackageUtils.isPackageInstalled(
|
||
- GooglePlayServicesUtil.GOOGLE_PLAY_STORE_PACKAGE);
|
||
- status.updateState =
|
||
- allowedToUpdate ? UpdateState.UPDATE_AVAILABLE : UpdateState.NONE;
|
||
-
|
||
- ChromeSharedPreferences.getInstance()
|
||
- .removeKey(ChromePreferenceKeys.LATEST_UNSUPPORTED_VERSION);
|
||
- } else if (!VersionNumberGetter.isCurrentOsVersionSupported()) {
|
||
- status.updateState = UpdateState.UNSUPPORTED_OS_VERSION;
|
||
- status.latestUnsupportedVersion =
|
||
- ChromeSharedPreferences.getInstance()
|
||
- .readString(ChromePreferenceKeys.LATEST_UNSUPPORTED_VERSION, null);
|
||
- } else {
|
||
- status.updateState = UpdateState.NONE;
|
||
+ SharedPreferences preferences = OmahaPrefUtils.getSharedPreferences();
|
||
+ status.latestVersion = preferences.getString(OmahaPrefUtils.PREF_LATEST_MODIFIED_VERSION, "");
|
||
+
|
||
+ status.updateState = UpdateState.NONE;
|
||
+ if (status.latestVersion != null && status.latestVersion.length() != 0) {
|
||
+ VersionNumber latestVersion = VersionNumber.fromString(status.latestVersion);
|
||
+ if (latestVersion == null) {
|
||
+ Log.e(TAG, "BromiteUpdater: stored latest version '%s' is invalid", status.latestVersion);
|
||
+ } else if (OmahaPrefUtils.isNewVersionAvailableByVersion(latestVersion)) {
|
||
+ status.updateState = UpdateState.INLINE_UPDATE_AVAILABLE;
|
||
+ status.updateUrl = mInlineController.getDownloadUrl();
|
||
+ return status;
|
||
+ }
|
||
+ String latestUpstreamVersion = preferences.getString(OmahaPrefUtils.PREF_LATEST_UPSTREAM_VERSION, "");
|
||
+ if (latestUpstreamVersion != null && latestUpstreamVersion.length() != 0) {
|
||
+ VersionNumber upstreamVersion = VersionNumber.fromString(latestUpstreamVersion);
|
||
+ if (upstreamVersion == null) {
|
||
+ Log.e(TAG, "BromiteUpdater: stored latest upstream version '%s' is invalid", latestUpstreamVersion);
|
||
+ } else if (OmahaPrefUtils.isNewVersionAvailableByVersion(upstreamVersion)) {
|
||
+ status.updateUrl = mInlineController.getVulnerableVersionDocUrl();
|
||
+ status.updateState = UpdateState.VULNERABLE_VERSION;
|
||
+ return status;
|
||
+ }
|
||
+ }
|
||
}
|
||
|
||
return status;
|
||
diff --git a/chrome/browser/omaha/android/java/src/org/chromium/chrome/browser/omaha/VersionNumberGetter.java b/chrome/browser/omaha/android/java/src/org/chromium/chrome/browser/omaha/VersionNumberGetter.java
|
||
--- a/chrome/browser/omaha/android/java/src/org/chromium/chrome/browser/omaha/VersionNumberGetter.java
|
||
+++ b/chrome/browser/omaha/android/java/src/org/chromium/chrome/browser/omaha/VersionNumberGetter.java
|
||
@@ -24,8 +24,8 @@ import org.chromium.chrome.browser.flags.ChromeFeatureList;
|
||
public class VersionNumberGetter {
|
||
private static VersionNumberGetter sInstance = new VersionNumberGetter();
|
||
|
||
- /** If true, OmahaClient will never report that a newer version is available. */
|
||
- private static boolean sDisableUpdateDetectionForTesting;
|
||
+ /** it must be true to disable version control via Omaha server. */
|
||
+ private static boolean sDisableUpdateDetectionForTesting = true;
|
||
|
||
@VisibleForTesting
|
||
static VersionNumberGetter getInstance() {
|
||
diff --git a/chrome/browser/omaha/android/java/src/org/chromium/chrome/browser/omaha/inline/InlineUpdateController.java b/chrome/browser/omaha/android/java/src/org/chromium/chrome/browser/omaha/inline/InlineUpdateController.java
|
||
new file mode 100644
|
||
--- /dev/null
|
||
+++ b/chrome/browser/omaha/android/java/src/org/chromium/chrome/browser/omaha/inline/InlineUpdateController.java
|
||
@@ -0,0 +1,57 @@
|
||
+// Copyright 2019 The Chromium Authors. All rights reserved.
|
||
+// Use of this source code is governed by a BSD-style license that can be
|
||
+// found in the LICENSE file.
|
||
+
|
||
+package org.chromium.chrome.browser.omaha.inline;
|
||
+
|
||
+import android.app.Activity;
|
||
+import android.content.Intent;
|
||
+
|
||
+import androidx.annotation.Nullable;
|
||
+
|
||
+import org.chromium.chrome.browser.omaha.UpdateStatusProvider;
|
||
+
|
||
+/**
|
||
+ * Helper for gluing interactions with the Play store's AppUpdateManager with Chrome. This
|
||
+ * involves hooking up to Play as a listener for install state changes, should only happen if we are
|
||
+ * in the foreground.
|
||
+ */
|
||
+public interface InlineUpdateController {
|
||
+ void setCallback(Runnable callback);
|
||
+
|
||
+ /**
|
||
+ * Enables or disables the controller. It will trigger an update check when previously disabled.
|
||
+ * @param enabled true iff the controller should be enabled.
|
||
+ */
|
||
+ void setEnabled(boolean enabled);
|
||
+
|
||
+ /**
|
||
+ * @return The current state of the inline update process. May be {@code null} if the state
|
||
+ * hasn't been determined yet.
|
||
+ */
|
||
+ @Nullable
|
||
+ @UpdateStatusProvider.UpdateState
|
||
+ Integer getStatus();
|
||
+
|
||
+ /**
|
||
+ * @return The current update URL for the inline update process. May be an empty string if the state
|
||
+ * hasn't been determined yet or if state does not specify one.
|
||
+ */
|
||
+ String getUpdateUrl();
|
||
+
|
||
+ String getDownloadUrl();
|
||
+
|
||
+ String getVulnerableVersionDocUrl();
|
||
+
|
||
+ /**
|
||
+ * Starts the update, if possible. This will send an {@link Intent} out to play, which may
|
||
+ * cause Chrome to move to the background.
|
||
+ * @param activity The {@link Activity} to use to interact with Play.
|
||
+ */
|
||
+ void startUpdate(Activity activity);
|
||
+
|
||
+ /**
|
||
+ * Completes the Play installation process, if possible. This may cause Chrome to restart.
|
||
+ */
|
||
+ void completeUpdate();
|
||
+}
|
||
diff --git a/chrome/browser/safety_hub/android/java/src/org/chromium/chrome/browser/safety_hub/SafetyHubFetchService.java b/chrome/browser/safety_hub/android/java/src/org/chromium/chrome/browser/safety_hub/SafetyHubFetchService.java
|
||
--- a/chrome/browser/safety_hub/android/java/src/org/chromium/chrome/browser/safety_hub/SafetyHubFetchService.java
|
||
+++ b/chrome/browser/safety_hub/android/java/src/org/chromium/chrome/browser/safety_hub/SafetyHubFetchService.java
|
||
@@ -85,9 +85,6 @@ public class SafetyHubFetchService implements SigninManager.SignInStateObserver,
|
||
mLocalPasswordsFetchService =
|
||
new SafetyHubPasswordsFetchService(passwordManagerHelper, prefService, null);
|
||
|
||
- // Fetch latest update status.
|
||
- UpdateStatusProvider.getInstance().addObserver(mUpdateCallback);
|
||
-
|
||
recordMetricForUnusedSitePermissionsSettingState();
|
||
}
|
||
|
||
@@ -116,8 +113,6 @@ public class SafetyHubFetchService implements SigninManager.SignInStateObserver,
|
||
if (mSigninManager != null) {
|
||
mSigninManager.removeSignInStateObserver(this);
|
||
}
|
||
-
|
||
- UpdateStatusProvider.getInstance().removeObserver(mUpdateCallback);
|
||
}
|
||
|
||
/** See {@link ChromeActivitySessionTracker#onForegroundSessionStart()}. */
|
||
diff --git a/chrome/browser/save_to_drive/drive_uploader.cc b/chrome/browser/save_to_drive/drive_uploader.cc
|
||
--- a/chrome/browser/save_to_drive/drive_uploader.cc
|
||
+++ b/chrome/browser/save_to_drive/drive_uploader.cc
|
||
@@ -290,7 +290,7 @@ DriveUploader::CreateEndpointFetcher(
|
||
return std::make_unique<endpoint_fetcher::EndpointFetcher>(
|
||
/*url_loader_factory=*/url_loader_factory_.get(),
|
||
/*identity_manager=*/identity_manager_,
|
||
- /*request_params=*/std::move(request_params));
|
||
+ /*request_params=*/std::move(request_params), kTrafficAnnotationTag);
|
||
}
|
||
|
||
DriveUploaderType DriveUploader::get_drive_uploader_type() const {
|
||
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings.grd b/chrome/browser/ui/android/strings/android_chrome_strings.grd
|
||
--- a/chrome/browser/ui/android/strings/android_chrome_strings.grd
|
||
+++ b/chrome/browser/ui/android/strings/android_chrome_strings.grd
|
||
@@ -2444,6 +2444,12 @@ Your Google account may have other forms of browsing history like searches and a
|
||
<message name="IDS_DEPRECATION_WARNING" desc="Warning about Chrome updates no longer being supported">
|
||
Chrome updates are no longer supported for this version of Android
|
||
</message>
|
||
+ <message name="IDS_ALLOW_INLINE_UPDATE_TITLE" desc="Title for allow inline update preference">
|
||
+ Allow checking for updates
|
||
+ </message>
|
||
+ <message name="IDS_ALLOW_INLINE_UPDATE_SUMMARY" desc="Summary for allow inline update preference">
|
||
+ Notify about new releases by periodically checking for their availability
|
||
+ </message>
|
||
|
||
<!-- Account management UI strings. -->
|
||
<message name="IDS_ACCOUNT_MANAGEMENT_TITLE" desc="Header title for the account management screen. [CHAR_LIMIT=32]">
|
||
@@ -4489,7 +4495,10 @@ To change this setting, <ph name="BEGIN_LINK">BEGIN_LINK</ph>delete the Chrome d
|
||
|
||
<!-- Main menu items -->
|
||
<message name="IDS_MENU_UPDATE" desc="Menu item for updating chrome. [CHAR_LIMIT=24]">
|
||
- Update Chrome
|
||
+ Update Bromite
|
||
+ </message>
|
||
+ <message name="IDS_MENU_UPDATE_SUMMARY_VULNERABLE" desc="Content description for the menu button when it is covered by the update icon that is displayed when the current version of Bromite is vulnerable.">
|
||
+ Update not available. Read more
|
||
</message>
|
||
<message name="IDS_MENU_UPDATE_SUMMARY_DEFAULT" desc="Summary string for update menu item explaining that a newer version of Chrome is available. [CHAR_LIMIT=30]">
|
||
Newer version is available
|
||
@@ -4500,6 +4509,18 @@ To change this setting, <ph name="BEGIN_LINK">BEGIN_LINK</ph>delete the Chrome d
|
||
<message name="IDS_MENU_UPDATE_UNSUPPORTED_SUMMARY_DEFAULT" desc="Summary string for update menu item explaining that the Android version on the device is unsupported. [CHAR_LIMIT=30]">
|
||
Android version is unsupported
|
||
</message>
|
||
+ <message name="IDS_MENU_INLINE_UPDATE_DOWNLOADING" desc="Menu item for when Chrome is in the process of updating. [CHAR_LIMIT=24]">
|
||
+ Downloading…
|
||
+ </message>
|
||
+ <message name="IDS_MENU_INLINE_UPDATE_FAILED" desc="Menu item for when Chrome failed to download an update. [CHAR_LIMIT=24]">
|
||
+ Couldn’t download
|
||
+ </message>
|
||
+ <message name="IDS_MENU_INLINE_UPDATE_READY" desc="Menu item text that is shown when Chrome has downloaded an update for itself and is ready to be restarted, which will apply the update. [CHAR_LIMIT=24]">
|
||
+ Update ready
|
||
+ </message>
|
||
+ <message name="IDS_MENU_INLINE_UPDATE_READY_SUMMARY" desc="Summary text that is shown when Chrome has downloaded an update for itself and is ready to be restarted, which will apply the update. This lets the user know the update will restart. [CHAR_LIMIT=24]">
|
||
+ Restart Bromite
|
||
+ </message>
|
||
<message name="IDS_MENU_NEW_WINDOW" desc="Menu item for opening a new window. [CHAR_LIMIT=27]">
|
||
New window
|
||
</message>
|
||
diff --git a/chrome/browser/ui/lens/lens_overlay_query_controller.cc b/chrome/browser/ui/lens/lens_overlay_query_controller.cc
|
||
--- a/chrome/browser/ui/lens/lens_overlay_query_controller.cc
|
||
+++ b/chrome/browser/ui/lens/lens_overlay_query_controller.cc
|
||
@@ -771,7 +771,7 @@ LensOverlayQueryController::CreateEndpointFetcher(
|
||
.SetTimeout(timeout)
|
||
.SetUrl(fetch_url)
|
||
.SetUploadProgressCallback(std::move(upload_progress_callback))
|
||
- .Build());
|
||
+ .Build(), kTrafficAnnotationTag);
|
||
}
|
||
|
||
void LensOverlayQueryController::SendLatencyGen204IfEnabled(
|
||
diff --git a/components/commerce/core/account_checker.cc b/components/commerce/core/account_checker.cc
|
||
--- a/components/commerce/core/account_checker.cc
|
||
+++ b/components/commerce/core/account_checker.cc
|
||
@@ -326,7 +326,7 @@ std::unique_ptr<EndpointFetcher> AccountChecker::CreateEndpointFetcher(
|
||
.SetPostData(post_data);
|
||
MaybeUseAlternateShoppingServer(request_params);
|
||
return std::make_unique<EndpointFetcher>(
|
||
- url_loader_factory_, identity_manager_, request_params.Build());
|
||
+ url_loader_factory_, identity_manager_, request_params.Build(), annotation_tag);
|
||
}
|
||
|
||
} // namespace commerce
|
||
diff --git a/components/commerce/core/subscriptions/subscriptions_server_proxy.cc b/components/commerce/core/subscriptions/subscriptions_server_proxy.cc
|
||
--- a/components/commerce/core/subscriptions/subscriptions_server_proxy.cc
|
||
+++ b/components/commerce/core/subscriptions/subscriptions_server_proxy.cc
|
||
@@ -302,7 +302,7 @@ SubscriptionsServerProxy::CreateEndpointFetcher(
|
||
.SetPostData(post_data);
|
||
MaybeUseAlternateShoppingServer(request_params);
|
||
return std::make_unique<EndpointFetcher>(
|
||
- url_loader_factory_, identity_manager_, request_params.Build());
|
||
+ url_loader_factory_, identity_manager_, request_params.Build(), annotation_tag);
|
||
}
|
||
|
||
void SubscriptionsServerProxy::HandleManageSubscriptionsResponses(
|
||
diff --git a/components/contextual_search/internal/composebox_query_controller.cc b/components/contextual_search/internal/composebox_query_controller.cc
|
||
--- a/components/contextual_search/internal/composebox_query_controller.cc
|
||
+++ b/components/contextual_search/internal/composebox_query_controller.cc
|
||
@@ -1226,7 +1226,7 @@ ComposeboxQueryController::CreateEndpointFetcher(
|
||
.SetTimeout(timeout)
|
||
.SetUploadProgressCallback(std::move(upload_progress_callback))
|
||
.SetUrl(fetch_url)
|
||
- .Build());
|
||
+ .Build(), kTrafficAnnotationTag);
|
||
}
|
||
|
||
lens::LensOverlayClientContext ComposeboxQueryController::CreateClientContext()
|
||
diff --git a/components/data_sharing/internal/data_sharing_network_loader_impl.cc b/components/data_sharing/internal/data_sharing_network_loader_impl.cc
|
||
--- a/components/data_sharing/internal/data_sharing_network_loader_impl.cc
|
||
+++ b/components/data_sharing/internal/data_sharing_network_loader_impl.cc
|
||
@@ -63,7 +63,7 @@ DataSharingNetworkLoaderImpl::CreateEndpointFetcher(
|
||
.SetUrl(url)
|
||
.SetOAuthConsumerId(signin::OAuthConsumerId::kDataSharingAndroid)
|
||
.SetPostData(post_data)
|
||
- .Build());
|
||
+ .Build(), annotation_tag);
|
||
}
|
||
|
||
void DataSharingNetworkLoaderImpl::OnDownloadComplete(
|
||
diff --git a/components/data_sharing/internal/preview_server_proxy.cc b/components/data_sharing/internal/preview_server_proxy.cc
|
||
--- a/components/data_sharing/internal/preview_server_proxy.cc
|
||
+++ b/components/data_sharing/internal/preview_server_proxy.cc
|
||
@@ -345,7 +345,7 @@ std::unique_ptr<EndpointFetcher> PreviewServerProxy::CreateEndpointFetcher(
|
||
.SetContentType(kContentType)
|
||
.SetTimeout(kTimeout)
|
||
.SetUrl(url)
|
||
- .Build());
|
||
+ .Build(), kGetSharedDataPreviewTrafficAnnotation);
|
||
}
|
||
|
||
void PreviewServerProxy::HandleServerResponse(
|
||
diff --git a/components/endpoint_fetcher/endpoint_fetcher.cc b/components/endpoint_fetcher/endpoint_fetcher.cc
|
||
--- a/components/endpoint_fetcher/endpoint_fetcher.cc
|
||
+++ b/components/endpoint_fetcher/endpoint_fetcher.cc
|
||
@@ -29,6 +29,11 @@
|
||
#include "services/network/public/mojom/referrer_policy.mojom-shared.h"
|
||
#include "services/network/public/mojom/url_response_head.mojom.h"
|
||
|
||
+// used for the Bromite customization
|
||
+#include "net/base/load_flags.h"
|
||
+#include "net/http/http_status_code.h"
|
||
+#include "services/network/public/cpp/resource_request.h"
|
||
+
|
||
namespace endpoint_fetcher {
|
||
|
||
namespace {
|
||
@@ -47,6 +52,8 @@ std::string GetHttpMethodString(const HttpMethod& http_method) {
|
||
return "DELETE";
|
||
case HttpMethod::kPut:
|
||
return "PUT";
|
||
+ case HttpMethod::kHead:
|
||
+ return "HEAD";
|
||
default:
|
||
DCHECK(0) << base::StringPrintf("Unknown HttpMethod %d\n",
|
||
static_cast<int>(http_method));
|
||
@@ -54,6 +61,13 @@ std::string GetHttpMethodString(const HttpMethod& http_method) {
|
||
return "";
|
||
}
|
||
|
||
+HttpMethod GetHttpMethod(const std::string& http_method_string) {
|
||
+ if (http_method_string == "HEAD") {
|
||
+ return HttpMethod::kHead;
|
||
+ }
|
||
+ return HttpMethod::kUndefined;
|
||
+}
|
||
+
|
||
} // namespace
|
||
|
||
EndpointResponse::EndpointResponse() = default;
|
||
@@ -109,9 +123,11 @@ EndpointFetcher::RequestParams::Builder::Build() {
|
||
EndpointFetcher::EndpointFetcher(
|
||
const scoped_refptr<network::SharedURLLoaderFactory>& url_loader_factory,
|
||
signin::IdentityManager* identity_manager,
|
||
- RequestParams request_params)
|
||
+ RequestParams request_params,
|
||
+ const net::NetworkTrafficAnnotationTag& annotation_tag)
|
||
: url_loader_factory_(url_loader_factory),
|
||
identity_manager_(identity_manager),
|
||
+ intercept_redirect_(false),
|
||
request_params_(std::move(request_params)) {
|
||
if (request_params_.auth_type() == OAUTH) {
|
||
DCHECK(identity_manager_)
|
||
@@ -124,12 +140,32 @@ EndpointFetcher::EndpointFetcher(
|
||
EndpointFetcher::EndpointFetcher(
|
||
const net::NetworkTrafficAnnotationTag& annotation_tag)
|
||
: identity_manager_(nullptr),
|
||
+ intercept_redirect_(false),
|
||
request_params_(
|
||
EndpointFetcher::RequestParams::Builder(HttpMethod::kUndefined,
|
||
annotation_tag)
|
||
.SetTimeout(kDefaultTimeOut)
|
||
.Build()) {}
|
||
|
||
+// constructor used by Cromite
|
||
+EndpointFetcher::EndpointFetcher(
|
||
+ const scoped_refptr<network::SharedURLLoaderFactory>& url_loader_factory,
|
||
+ const GURL& url,
|
||
+ const std::string& http_method,
|
||
+ int64_t timeout_ms,
|
||
+ const bool intercept_redirect,
|
||
+ const net::NetworkTrafficAnnotationTag& annotation_tag)
|
||
+ : url_loader_factory_(url_loader_factory),
|
||
+ identity_manager_(nullptr),
|
||
+ intercept_redirect_(intercept_redirect),
|
||
+ request_params_(
|
||
+ EndpointFetcher::RequestParams::Builder(GetHttpMethod(http_method),
|
||
+ annotation_tag)
|
||
+ .SetAuthType(NO_AUTH)
|
||
+ .SetTimeout(base::Milliseconds(timeout_ms))
|
||
+ .SetUrl(url)
|
||
+ .Build()) {}
|
||
+
|
||
EndpointFetcher::~EndpointFetcher() = default;
|
||
|
||
void EndpointFetcher::Fetch(EndpointFetcherCallback endpoint_fetcher_callback) {
|
||
@@ -212,13 +248,10 @@ void EndpointFetcher::PerformHttpRequest(
|
||
auto resource_request = std::make_unique<network::ResourceRequest>();
|
||
resource_request->method = GetHttpMethodString(request_params_.http_method());
|
||
resource_request->url = request_params_.url();
|
||
- resource_request->credentials_mode = GetCredentialsMode();
|
||
-
|
||
- if (GetSetSiteForCookies()) {
|
||
- resource_request->site_for_cookies =
|
||
- net::SiteForCookies::FromUrl(request_params_.url());
|
||
- }
|
||
+ resource_request->credentials_mode = network::mojom::CredentialsMode::kOmit;
|
||
|
||
+ resource_request->load_flags = net::LOAD_BYPASS_CACHE | net::LOAD_DISABLE_CACHE
|
||
+ | net::LOAD_DO_NOT_SAVE_COOKIES;
|
||
// Add Content-Type header if post data is present.
|
||
bool has_body_content = (request_params_.http_method() == HttpMethod::kPost ||
|
||
request_params_.http_method() == HttpMethod::kPut) &&
|
||
@@ -259,8 +292,23 @@ void EndpointFetcher::PerformHttpRequest(
|
||
break;
|
||
}
|
||
|
||
+ if (intercept_redirect_ == true) {
|
||
+ // will need manual mode to capture the landing page URL
|
||
+ resource_request->redirect_mode = network::mojom::RedirectMode::kManual; // default is kFollow
|
||
+ }
|
||
+
|
||
simple_url_loader_ = network::SimpleURLLoader::Create(
|
||
std::move(resource_request), request_params_.annotation_tag());
|
||
+ simple_url_loader_->SetAllowHttpErrorResults(true);
|
||
+
|
||
+ if (!response_)
|
||
+ response_ = std::make_unique<EndpointResponse>();
|
||
+
|
||
+ if (intercept_redirect_ == true) {
|
||
+ // use a callback to capture landing page URL
|
||
+ simple_url_loader_->SetOnRedirectCallback(base::BindRepeating(
|
||
+ &EndpointFetcher::OnSimpleLoaderRedirect, base::Unretained(this)));
|
||
+ }
|
||
|
||
if (has_body_content) {
|
||
simple_url_loader_->AttachStringForUpload(
|
||
@@ -273,9 +321,18 @@ void EndpointFetcher::PerformHttpRequest(
|
||
|
||
simple_url_loader_->SetRetryOptions(GetMaxRetries(),
|
||
network::SimpleURLLoader::RETRY_ON_5XX);
|
||
- simple_url_loader_->SetTimeoutDuration(request_params_.timeout());
|
||
- simple_url_loader_->SetAllowHttpErrorResults(true);
|
||
-
|
||
+ LOG(INFO) << "performing "
|
||
+ << GetHttpMethodString(request_params_.http_method())
|
||
+ << " request to " << url_;
|
||
+ if (request_params_.http_method() == HttpMethod::kHead) {
|
||
+ endpoint_fetcher_callback_ = std::move(endpoint_fetcher_callback);
|
||
+
|
||
+ simple_url_loader_->DownloadHeadersOnly(
|
||
+ url_loader_factory_.get(),
|
||
+ base::BindOnce(&EndpointFetcher::OnURLLoadComplete,
|
||
+ base::Unretained(this)));
|
||
+ return;
|
||
+ }
|
||
network::SimpleURLLoader::BodyAsStringCallback body_as_string_callback =
|
||
base::BindOnce(&EndpointFetcher::OnResponseFetched,
|
||
weak_ptr_factory_.GetWeakPtr(),
|
||
@@ -334,21 +391,6 @@ void EndpointFetcher::OnResponseFetched(
|
||
std::move(endpoint_fetcher_callback).Run(std::move(response));
|
||
}
|
||
|
||
-network::mojom::CredentialsMode EndpointFetcher::GetCredentialsMode() const {
|
||
- if (!request_params_.credentials_mode.has_value()) {
|
||
- return network::mojom::CredentialsMode::kOmit;
|
||
- }
|
||
- switch (request_params_.credentials_mode.value()) {
|
||
- case CredentialsMode::kOmit:
|
||
- return network::mojom::CredentialsMode::kOmit;
|
||
- case CredentialsMode::kInclude:
|
||
- return network::mojom::CredentialsMode::kInclude;
|
||
- }
|
||
- DCHECK(0) << base::StringPrintf(
|
||
- "Credentials mode %d not currently supported by EndpointFetcher\n",
|
||
- static_cast<int>(request_params_.credentials_mode.value()));
|
||
-}
|
||
-
|
||
int EndpointFetcher::GetMaxRetries() const {
|
||
return request_params_.max_retries.value_or(kNumRetries);
|
||
}
|
||
@@ -366,4 +408,39 @@ std::string EndpointFetcher::GetUrlForTesting() {
|
||
return request_params_.url().spec();
|
||
}
|
||
|
||
+void EndpointFetcher::OnSimpleLoaderRedirect(
|
||
+ const GURL& url_before_redirect,
|
||
+ const net::RedirectInfo& redirect_info,
|
||
+ const network::mojom::URLResponseHead& response_head,
|
||
+ std::vector<std::string>* removed_headers) {
|
||
+ url_ = redirect_info.new_url;
|
||
+ if (response_ && response_->redirect_url.empty()) {
|
||
+ response_->redirect_url = url_.spec();
|
||
+ response_->response = std::to_string(redirect_info.status_code);
|
||
+ } else {
|
||
+ LOG(INFO) << "BromiteUpdater: redirect URL is not empty, status code is " << redirect_info.status_code;
|
||
+ }
|
||
+
|
||
+ std::move(endpoint_fetcher_callback_).Run(std::move(response_));
|
||
+}
|
||
+
|
||
+void EndpointFetcher::OnURLLoadComplete(
|
||
+ scoped_refptr<net::HttpResponseHeaders> headers) {
|
||
+ if (!endpoint_fetcher_callback_)
|
||
+ return;
|
||
+
|
||
+ if (headers) {
|
||
+ if (response_->redirect_url.empty()) {
|
||
+ std::string location;
|
||
+ if (simple_url_loader_->ResponseInfo()->headers->IsRedirect(&location)) {
|
||
+ response_->redirect_url = location;
|
||
+ }
|
||
+ }
|
||
+ }
|
||
+
|
||
+ std::string net_error = net::ErrorToString(simple_url_loader_->NetError());
|
||
+ response_->response = net_error;
|
||
+ std::move(endpoint_fetcher_callback_).Run(std::move(response_));
|
||
+}
|
||
+
|
||
} // namespace endpoint_fetcher
|
||
diff --git a/components/endpoint_fetcher/endpoint_fetcher.h b/components/endpoint_fetcher/endpoint_fetcher.h
|
||
--- a/components/endpoint_fetcher/endpoint_fetcher.h
|
||
+++ b/components/endpoint_fetcher/endpoint_fetcher.h
|
||
@@ -19,6 +19,9 @@
|
||
#include "services/network/public/mojom/fetch_api.mojom-forward.h"
|
||
#include "url/gurl.h"
|
||
|
||
+#include "services/network/public/cpp/resource_request.h"
|
||
+#include "services/network/public/mojom/url_response_head.mojom.h"
|
||
+
|
||
namespace base {
|
||
class TimeDelta;
|
||
} // namespace base
|
||
@@ -60,6 +63,7 @@ enum class HttpMethod {
|
||
kPost = 1,
|
||
kDelete = 2,
|
||
kPut = 3,
|
||
+ kHead = 4,
|
||
};
|
||
|
||
enum AuthType {
|
||
@@ -78,6 +82,8 @@ struct EndpointResponse {
|
||
~EndpointResponse();
|
||
|
||
std::string response;
|
||
+ long last_modified;
|
||
+ std::string redirect_url;
|
||
int http_status_code{-1};
|
||
std::optional<FetchErrorType> error_type;
|
||
scoped_refptr<net::HttpResponseHeaders> headers;
|
||
@@ -300,7 +306,16 @@ class EndpointFetcher {
|
||
EndpointFetcher(
|
||
const scoped_refptr<network::SharedURLLoaderFactory>& url_loader_factory,
|
||
signin::IdentityManager* identity_manager,
|
||
- RequestParams request_params);
|
||
+ RequestParams request_params,
|
||
+ const net::NetworkTrafficAnnotationTag& annotation_tag);
|
||
+
|
||
+ // Constructor used by cromite
|
||
+ EndpointFetcher(const scoped_refptr<network::SharedURLLoaderFactory>& url_loader_factory,
|
||
+ const GURL& url,
|
||
+ const std::string& http_method,
|
||
+ int64_t timeout_ms,
|
||
+ const bool intercept_redirect,
|
||
+ const net::NetworkTrafficAnnotationTag& annotation_tag);
|
||
|
||
EndpointFetcher(const EndpointFetcher& endpoint_fetcher) = delete;
|
||
EndpointFetcher& operator=(const EndpointFetcher& endpoint_fetcher) = delete;
|
||
@@ -333,11 +348,17 @@ class EndpointFetcher {
|
||
|
||
void OnResponseFetched(EndpointFetcherCallback callback,
|
||
std::optional<std::string> response_body);
|
||
+ void OnURLLoadComplete(scoped_refptr<net::HttpResponseHeaders> headers);
|
||
+ void OnSimpleLoaderRedirect(const GURL& url_before_redirect,
|
||
+ const net::RedirectInfo& redirect_info,
|
||
+ const network::mojom::URLResponseHead& response_head,
|
||
+ std::vector<std::string>* removed_headers);
|
||
|
||
network::mojom::CredentialsMode GetCredentialsMode() const;
|
||
int GetMaxRetries() const;
|
||
bool GetSetSiteForCookies() const;
|
||
UploadProgressCallback GetUploadProgressCallback() const;
|
||
+ GURL url_;
|
||
|
||
// Members set in constructor
|
||
const scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory_;
|
||
@@ -348,6 +369,8 @@ class EndpointFetcher {
|
||
// SingleClientSharedTabGroupVersioningSyncTest.ShouldShowVersioningMessagesAfterRestart/kSyncTransportOnly
|
||
const raw_ptr<signin::IdentityManager, DanglingUntriaged> identity_manager_;
|
||
|
||
+ const bool intercept_redirect_;
|
||
+
|
||
// The complete definition of the specific network request to be performed.
|
||
// Contains authentication details and response handling preferences.
|
||
const RequestParams request_params_;
|
||
@@ -357,6 +380,9 @@ class EndpointFetcher {
|
||
access_token_fetcher_;
|
||
std::unique_ptr<network::SimpleURLLoader> simple_url_loader_;
|
||
|
||
+ EndpointFetcherCallback endpoint_fetcher_callback_;
|
||
+ std::unique_ptr<EndpointResponse> response_;
|
||
+
|
||
base::WeakPtrFactory<EndpointFetcher> weak_ptr_factory_{this};
|
||
};
|
||
|
||
diff --git a/components/manta/base_provider.cc b/components/manta/base_provider.cc
|
||
--- a/components/manta/base_provider.cc
|
||
+++ b/components/manta/base_provider.cc
|
||
@@ -140,7 +140,7 @@ std::unique_ptr<EndpointFetcher> BaseProvider::CreateEndpointFetcher(
|
||
.SetUrl(url)
|
||
.SetOAuthConsumerId(signin::OAuthConsumerId::kManta)
|
||
.SetPostData(post_data)
|
||
- .Build());
|
||
+ .Build(), annotation_tag);
|
||
}
|
||
|
||
std::unique_ptr<EndpointFetcher> BaseProvider::CreateEndpointFetcherForDemoMode(
|
||
@@ -158,7 +158,7 @@ std::unique_ptr<EndpointFetcher> BaseProvider::CreateEndpointFetcherForDemoMode(
|
||
.SetTimeout(timeout)
|
||
.SetPostData(post_data)
|
||
.SetChannel(version_info::Channel::STABLE)
|
||
- .Build());
|
||
+ .Build(), annotation_tag);
|
||
}
|
||
|
||
} // namespace manta
|
||
diff --git a/cromite_flags/chrome/browser/flags/android/chrome_feature_list_cc/Bromite-auto-updater.inc b/cromite_flags/chrome/browser/flags/android/chrome_feature_list_cc/Bromite-auto-updater.inc
|
||
new file mode 100644
|
||
--- /dev/null
|
||
+++ b/cromite_flags/chrome/browser/flags/android/chrome_feature_list_cc/Bromite-auto-updater.inc
|
||
@@ -0,0 +1,3 @@
|
||
+CROMITE_FEATURE(kInlineUpdateFlow,
|
||
+ "InlineUpdateFlow",
|
||
+ base::FEATURE_ENABLED_BY_DEFAULT);
|
||
diff --git a/cromite_flags/chrome/browser/flags/android/chrome_feature_list_h/Bromite-auto-updater.inc b/cromite_flags/chrome/browser/flags/android/chrome_feature_list_h/Bromite-auto-updater.inc
|
||
new file mode 100644
|
||
--- /dev/null
|
||
+++ b/cromite_flags/chrome/browser/flags/android/chrome_feature_list_h/Bromite-auto-updater.inc
|
||
@@ -0,0 +1 @@
|
||
+BASE_DECLARE_FEATURE(kInlineUpdateFlow);
|
||
--
|