Enable update notification (#1454)

* Enable update notification

* version check rather than build time

* fixup with Disable-Omaha-update-checks.patch

* taking the last-modified together with the redirect.

the check between build times in any case is currently commented (see isNewVersionAvailableByBuildTime)

* removed code related to build time check

* removed PREF_LATEST_MODIFIED_BUILDTIME
This commit is contained in:
uazo 2021-10-16 09:27:49 +02:00 committed by GitHub
parent ed23baeb48
commit ad34a777bb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 938 additions and 2 deletions

View file

@ -34,7 +34,6 @@ Skip-the-first-run-and-metrics.patch
Disable-all-promo-dialogs.patch
Remove-signin-and-data-saver-integrations.patch
Hide-passwords-manager-link.patch
Disable-Omaha-update-checks.patch
Disable-update-scheduler.patch
Add-English-only-search-engine.patch
Add-DuckDuckGo-Lite-search-engine.patch
@ -164,4 +163,5 @@ Enable-share-intent.patch
Automated-domain-substitution.patch
Observe-WebContents-in-PPAPIDownloadRequest.patch
Prevents-non-browser-processes-from-requesting-memory-dumps.patch
Add-images-contentsettings.patch
Add-images-contentsettings.patch
Enable-update-notification.patch

View file

@ -0,0 +1,936 @@
From: uazo <uazo@users.noreply.github.com>
Date: Thu, 7 Oct 2021 14:27:12 +0000
Subject: Enable update notification
Enable checking for new version, with proxy support
---
.../java/templates/BuildConfig.template | 2 +
build/config/android/rules.gni | 3 +
chrome/android/chrome_java_sources.gni | 1 +
.../java/res/xml/about_chrome_preferences.xml | 5 +
.../about_settings/AboutChromeSettings.java | 27 ++-
.../chrome/browser/omaha/OmahaBase.java | 44 +++-
.../chrome/browser/omaha/UpdateConfigs.java | 6 +-
.../browser/omaha/UpdateStatusProvider.java | 36 ++--
.../browser/omaha/VersionNumberGetter.java | 3 +-
.../inline/BromiteInlineUpdateController.java | 204 ++++++++++++++++++
.../inline/InlineUpdateControllerFactory.java | 8 +-
chrome/browser/endpoint_fetcher/BUILD.gn | 2 +
.../endpoint_fetcher/endpoint_fetcher.cc | 125 +++++++++++
.../endpoint_fetcher/endpoint_fetcher.h | 23 +-
.../endpoint_fetcher/EndpointFetcher.java | 11 +
.../EndpointHeaderResponse.java | 31 +++
chrome/browser/flag-metadata.json | 2 +-
chrome/browser/flag_descriptions.cc | 5 +-
.../flags/android/chrome_feature_list.cc | 2 +-
.../strings/android_chrome_strings.grd | 8 +-
20 files changed, 511 insertions(+), 37 deletions(-)
create mode 100644 chrome/android/java/src/org/chromium/chrome/browser/omaha/inline/BromiteInlineUpdateController.java
create mode 100644 chrome/browser/endpoint_fetcher/java/src/org/chromium/chrome/browser/endpoint_fetcher/EndpointHeaderResponse.java
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
@@ -92,4 +92,6 @@ public class BuildConfig {
#else
public static MAYBE_FINAL boolean ISOLATED_SPLITS_ENABLED MAYBE_FALSE;
#endif
+
+ public static MAYBE_FINAL String BUILD_TARGET_CPU = _BUILD_TARGET_CPU;
}
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
@@ -1967,6 +1967,9 @@ if (enable_java_templates) {
]
}
}
+
+ # add arch to org.chromium.build.BuildConfig
+ defines += [ "_BUILD_TARGET_CPU=\"${target_cpu}\"" ]
}
}
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
@@ -880,6 +880,7 @@ chrome_java_sources = [
"java/src/org/chromium/chrome/browser/omaha/inline/InlineUpdateController.java",
"java/src/org/chromium/chrome/browser/omaha/inline/InlineUpdateControllerFactory.java",
"java/src/org/chromium/chrome/browser/omaha/inline/NoopInlineUpdateController.java",
+ "java/src/org/chromium/chrome/browser/omaha/inline/BromiteInlineUpdateController.java",
"java/src/org/chromium/chrome/browser/omaha/inline/PlayInlineUpdateController.java",
"java/src/org/chromium/chrome/browser/omaha/metrics/HistogramUtils.java",
"java/src/org/chromium/chrome/browser/omaha/metrics/TrackingProvider.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
@@ -7,6 +7,11 @@
<Preference
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
@@ -21,11 +21,16 @@ import org.chromium.ui.widget.Toast;
import java.util.Calendar;
+import android.content.SharedPreferences;
+import org.chromium.chrome.browser.omaha.OmahaBase;
+import org.chromium.components.browser_ui.settings.ChromeSwitchPreference;
+
/**
* Settings fragment that displays information about Chrome.
*/
public class AboutChromeSettings
- extends PreferenceFragmentCompat implements Preference.OnPreferenceClickListener {
+ extends PreferenceFragmentCompat implements Preference.OnPreferenceClickListener,
+ Preference.OnPreferenceChangeListener {
private static final int TAPS_FOR_DEVELOPER_SETTINGS = 7;
private static final String PREF_APPLICATION_VERSION = "application_version";
@@ -59,6 +64,13 @@ public class AboutChromeSettings
p = findPreference(PREF_LEGAL_INFORMATION);
int currentYear = Calendar.getInstance().get(Calendar.YEAR);
p.setSummary(getString(R.string.legal_information_summary, currentYear));
+
+ ChromeSwitchPreference allowInlineUpdate =
+ (ChromeSwitchPreference) findPreference(OmahaBase.PREF_ALLOW_INLINE_UPDATE);
+ allowInlineUpdate.setChecked(
+ OmahaBase.getSharedPreferences()
+ .getBoolean(OmahaBase.PREF_ALLOW_INLINE_UPDATE, false));
+ allowInlineUpdate.setOnPreferenceChangeListener(this);
}
/**
@@ -122,4 +134,17 @@ public class AboutChromeSettings
}
return true;
}
+
+ @Override
+ public boolean onPreferenceChange(Preference preference, Object newValue) {
+ String key = preference.getKey();
+ if (OmahaBase.PREF_ALLOW_INLINE_UPDATE.equals(key)) {
+ SharedPreferences.Editor sharedPreferenceEditor = OmahaBase.getSharedPreferences().edit();
+ sharedPreferenceEditor.putBoolean(OmahaBase.PREF_ALLOW_INLINE_UPDATE, (boolean) newValue);
+ sharedPreferenceEditor.apply();
+
+ OmahaBase.resetUpdatePrefs();
+ }
+ return true;
+ }
}
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
@@ -31,6 +31,8 @@ import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Date;
+import org.chromium.build.BuildConfig;
+
/**
* Keeps tabs on the current state of Chrome, tracking if and when a request should be sent to the
* Omaha Server.
@@ -97,7 +99,9 @@ public class OmahaBase {
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";
+ public static final String PREF_LATEST_MODIFIED_VERSION = "latestModifiedVersion";
+ public static final String PREF_ALLOW_INLINE_UPDATE = "allow_inline_update";
static final int MIN_API_JOB_SCHEDULER = Build.VERSION_CODES.M;
@@ -157,8 +161,9 @@ public class OmahaBase {
}
/** See {@link #sIsDisabled}. */
+ // do not enable version control with Omaha Update Server
static boolean isDisabled() {
- return sIsDisabled;
+ return true;
}
/**
@@ -630,4 +635,39 @@ public class OmahaBase {
// updateStatus is only used for the on-demand check.
null);
}
+
+ public static boolean isNewVersionAvailableByVersion(String latestVersionString) {
+ VersionNumber mCurrentProductVersion = VersionNumber.fromString(ChromeVersionInfo.getProductVersion());
+ if (mCurrentProductVersion == null || latestVersionString == null)
+ return false;
+
+ VersionNumber latestVersion = VersionNumber.fromString(latestVersionString);
+ if (latestVersion == null) return false;
+
+ Log.i(TAG, "isNewVersionAvailable: CurrentProductVersion: %s",
+ mCurrentProductVersion.toString());
+ Log.i(TAG, "isNewVersionAvailable: LatestVersion: %s",
+ latestVersion.toString());
+
+ return mCurrentProductVersion.isSmallerThan(latestVersion);
+ }
+
+ public static void updateLastPushedTimeStamp(long timeMillis) {
+ SharedPreferences preferences = OmahaBase.getSharedPreferences();
+ SharedPreferences.Editor editor = preferences.edit();
+ editor.putLong(OmahaBase.PREF_TIMESTAMP_OF_REQUEST, timeMillis);
+ editor.apply();
+ }
+
+ public static void setLastModifiedVersion(String version) {
+ SharedPreferences preferences = OmahaBase.getSharedPreferences();
+ SharedPreferences.Editor editor = preferences.edit();
+ editor.putString(OmahaBase.PREF_LATEST_MODIFIED_VERSION, version);
+ editor.apply();
+ }
+
+ public static void resetUpdatePrefs() {
+ OmahaBase.setLastModifiedVersion("");
+ OmahaBase.updateLastPushedTimeStamp(0);
+ }
}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omaha/UpdateConfigs.java b/chrome/android/java/src/org/chromium/chrome/browser/omaha/UpdateConfigs.java
--- a/chrome/android/java/src/org/chromium/chrome/browser/omaha/UpdateConfigs.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/omaha/UpdateConfigs.java
@@ -65,7 +65,7 @@ public class UpdateConfigs {
private static final String UPDATE_NOTIFICATION_EXPERIMENTAL_PARAM_NAME =
"update_notification_experimental_context";
- private static final long DEFAULT_UPDATE_NOTIFICATION_INTERVAL = 21 * DateUtils.DAY_IN_MILLIS;
+ private static final long DEFAULT_UPDATE_NOTIFICATION_INTERVAL = 7 * DateUtils.DAY_IN_MILLIS;
private static final long DEFAULT_UPDATE_ATTRIBUTION_WINDOW_MS = 2 * DateUtils.DAY_IN_MILLIS;
/** Possible update flow configurations. */
@@ -300,7 +300,7 @@ public class UpdateConfigs {
* @return the current inline update flow configuration.
*/
@UpdateFlowConfiguration
- static int getConfiguration() {
+ 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.INTENT_ONLY;
@@ -328,4 +328,4 @@ public class UpdateConfigs {
if (configuration == null) return "";
return configuration.toLowerCase(Locale.US);
}
-}
\ No newline at end of file
+}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omaha/UpdateStatusProvider.java b/chrome/android/java/src/org/chromium/chrome/browser/omaha/UpdateStatusProvider.java
--- a/chrome/android/java/src/org/chromium/chrome/browser/omaha/UpdateStatusProvider.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/omaha/UpdateStatusProvider.java
@@ -45,6 +45,12 @@ 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;
+import org.chromium.chrome.browser.version.ChromeVersionInfo;
+
/**
* Provides the current update state for Chrome. This update state is asynchronously determined and
* can change as Chrome runs.
@@ -112,6 +118,8 @@ public class UpdateStatusProvider implements ActivityStateListener {
*/
public String latestUnsupportedVersion;
+ public long latestLastModifiedBuildTime;
+
/**
* Whether or not we are currently trying to simulate the update. Used to ignore other
* update signals.
@@ -133,6 +141,7 @@ public class UpdateStatusProvider implements ActivityStateListener {
latestUnsupportedVersion = other.latestUnsupportedVersion;
mIsSimulated = other.mIsSimulated;
mIsInlineSimulated = other.mIsInlineSimulated;
+ latestLastModifiedBuildTime = other.latestLastModifiedBuildTime;
}
}
@@ -339,8 +348,7 @@ public class UpdateStatusProvider implements ActivityStateListener {
case UpdateConfigs.UpdateFlowConfiguration.NEVER_SHOW:
return UpdateState.NONE;
case UpdateConfigs.UpdateFlowConfiguration.INLINE_ONLY:
- if (omahaState != UpdateState.UPDATE_AVAILABLE) return omahaState;
- if (inlineState == UpdateState.NONE) return UpdateState.NONE;
+ if (inlineState == UpdateState.NONE) return omahaState;
return inlineState;
case UpdateConfigs.UpdateFlowConfiguration.BEST_EFFORT:
if (omahaState != UpdateState.UPDATE_AVAILABLE) return omahaState;
@@ -415,24 +423,12 @@ public class UpdateStatusProvider implements ActivityStateListener {
private UpdateStatus getRealStatus(Context context) {
UpdateStatus status = new UpdateStatus();
- if (VersionNumberGetter.isNewerVersionAvailable(context)) {
- status.updateUrl = MarketURLGetter.getMarketUrl();
- status.latestVersion =
- VersionNumberGetter.getInstance().getLatestKnownVersion(context);
-
- boolean allowedToUpdate =
- checkForSufficientStorage() && isGooglePlayStoreAvailable(context);
- status.updateState =
- allowedToUpdate ? UpdateState.UPDATE_AVAILABLE : UpdateState.NONE;
-
- SharedPreferencesManager.getInstance().removeKey(
- ChromePreferenceKeys.LATEST_UNSUPPORTED_VERSION);
- } else if (!VersionNumberGetter.isCurrentOsVersionSupported()) {
- status.updateState = UpdateState.UNSUPPORTED_OS_VERSION;
- status.latestUnsupportedVersion = SharedPreferencesManager.getInstance().readString(
- ChromePreferenceKeys.LATEST_UNSUPPORTED_VERSION, null);
- } else {
- status.updateState = UpdateState.NONE;
+ SharedPreferences preferences = OmahaBase.getSharedPreferences();
+ status.latestVersion = preferences.getString(OmahaBase.PREF_LATEST_MODIFIED_VERSION, "");
+
+ status.updateState = UpdateState.NONE;
+ if (OmahaBase.isNewVersionAvailableByVersion(status.latestVersion)) {
+ status.updateState = UpdateState.INLINE_UPDATE_AVAILABLE;
}
return status;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omaha/VersionNumberGetter.java b/chrome/android/java/src/org/chromium/chrome/browser/omaha/VersionNumberGetter.java
--- a/chrome/android/java/src/org/chromium/chrome/browser/omaha/VersionNumberGetter.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/omaha/VersionNumberGetter.java
@@ -43,7 +43,8 @@ public class VersionNumberGetter {
private static VersionNumberGetter sInstanceForTests;
/** If false, OmahaClient will never report that a newer version is available. */
- private static boolean sEnableUpdateDetection = true;
+ // it must be false to not enable version control with Omaha server
+ private static boolean sEnableUpdateDetection = false;
protected VersionNumberGetter() { }
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,204 @@
+// 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.chrome.browser.app.ChromeActivity;
+import org.chromium.chrome.browser.omaha.OmahaBase;
+import org.chromium.chrome.browser.omaha.UpdateConfigs;
+import org.chromium.chrome.browser.omaha.UpdateStatusProvider;
+import org.chromium.chrome.browser.profiles.Profile;
+import org.chromium.chrome.browser.tab.TabLaunchType;
+import org.chromium.chrome.browser.tabmodel.TabCreator;
+import org.chromium.chrome.browser.version.ChromeVersionInfo;
+import org.chromium.content_public.browser.LoadUrlParams;
+import org.chromium.content_public.browser.UiThreadTaskTraits;
+import org.chromium.ui.base.PageTransition;
+
+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;
+import org.chromium.chrome.browser.omaha.VersionNumber;
+
+class BromiteInlineUpdateController implements InlineUpdateController {
+
+ private static final String TAG = "BromiteInlineUpdateController";
+ private final String UPDATE_VERSION_URL = "https://github.com/bromite/bromite/releases/latest/download/";
+
+ private String getDownloadUrl() {
+ return UPDATE_VERSION_URL + BuildConfig.BUILD_TARGET_CPU + "_ChromePublic.apk";
+ }
+
+ private boolean mEnabled = true;
+ private Runnable mCallback;
+ private @Nullable @UpdateStatusProvider.UpdateState Integer mUpdateState =
+ UpdateStatusProvider.UpdateState.NONE;
+
+ BromiteInlineUpdateController(Runnable callback) {
+ mCallback = callback;
+ }
+
+ @Override
+ public void setEnabled(boolean enabled) {
+ if (mEnabled == enabled) return;
+
+ mEnabled = enabled;
+ if (mEnabled) pullCurrentState();
+ }
+
+ @Override
+ public @Nullable @UpdateStatusProvider.UpdateState Integer getStatus() {
+ if (mEnabled) pullCurrentState();
+ return mUpdateState;
+ }
+
+ @Override
+ public void startUpdate(Activity activity) {
+ assert ChromeActivity.class.isInstance(activity);
+ ChromeActivity thisActivity = (ChromeActivity) activity;
+ String downloadUrl = getDownloadUrl();
+ // Always open in new incognito tab
+ TabCreator tabCreator = thisActivity.getTabCreator(true);
+ tabCreator.createNewTab(new LoadUrlParams(downloadUrl, PageTransition.AUTO_BOOKMARK),
+ TabLaunchType.FROM_LINK, thisActivity.getActivityTab());
+ }
+
+ @Override
+ public void completeUpdate() {
+ }
+
+ private void pullCurrentState() {
+ if (OmahaBase.getSharedPreferences()
+ .getBoolean(OmahaBase.PREF_ALLOW_INLINE_UPDATE, false) == false) {
+ Log.i(TAG, "Checking for update disabled by user");
+ return;
+ }
+
+ if (mUpdateState != UpdateStatusProvider.UpdateState.NONE)
+ return;
+
+ if (shallUpdate() == false)
+ return;
+
+ switch (mUpdateState) {
+ case UpdateStatusProvider.UpdateState.INLINE_UPDATE_AVAILABLE:
+ break;
+ case UpdateStatusProvider.UpdateState.NONE:
+ checkLatestVersion((ok) -> {
+ if (ok == false) return;
+
+ SharedPreferences preferences = OmahaBase.getSharedPreferences();
+ String latestVersion = preferences.getString(OmahaBase.PREF_LATEST_MODIFIED_VERSION, "");
+
+ if (OmahaBase.isNewVersionAvailableByVersion(latestVersion)) {
+ postStatus(UpdateStatusProvider.UpdateState.INLINE_UPDATE_AVAILABLE);
+ } else {
+ if (mUpdateState != UpdateStatusProvider.UpdateState.NONE) {
+ postStatus(UpdateStatusProvider.UpdateState.NONE);
+ }
+ }
+ });
+ 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.
+ default:
+ return;
+ }
+ }
+
+ private boolean shallUpdate() {
+ long currentTime = System.currentTimeMillis();
+ SharedPreferences preferences = OmahaBase.getSharedPreferences();
+ long lastPushedTimeStamp = preferences.getLong(OmahaBase.PREF_TIMESTAMP_OF_REQUEST, 0);
+ return currentTime - lastPushedTimeStamp >= getUpdateNotificationInterval();
+ }
+
+ private void checkLatestVersion(final Callback<Boolean> callback) {
+ assert UPDATE_VERSION_URL != null;
+
+ OmahaBase.resetUpdatePrefs();
+
+ String urlToCheck = getDownloadUrl();
+ Log.i(TAG, "Fetching with HEAD: " + urlToCheck);
+
+ EndpointFetcher.nativeHeadWithNoAuth(
+ (endpointResponse) -> {
+ Log.i(TAG, "Obtained response");
+ Log.i(TAG, "with message: '%s'", endpointResponse.getResponseString());
+ Log.i(TAG, "and redirect: '%s'", endpointResponse.getRedirectUrl());
+
+ OmahaBase.updateLastPushedTimeStamp(System.currentTimeMillis());
+
+ if (endpointResponse.getRedirectUrl() != null) {
+ String[] parts = endpointResponse.getRedirectUrl()
+ .split(Pattern.quote("/"));
+ for(String part:parts) {
+ VersionNumber version = VersionNumber.fromString(part);
+ if (version != null) {
+ OmahaBase.setLastModifiedVersion(part);
+ callback.onResult(true);
+ return;
+ }
+ }
+ } else {
+ // retry after 1 hour
+ OmahaBase.updateLastPushedTimeStamp(
+ System.currentTimeMillis() - getUpdateNotificationInterval() -
+ DateUtils.HOUR_IN_MILLIS * 1);
+ Log.i(TAG, "Some error has occurred. I'll try again in 1 hour");
+ }
+
+ callback.onResult(false);
+ },
+ Profile.getLastUsedRegularProfile(),
+ urlToCheck, /*timeout*/5000, /*follow_redirect*/false);
+ }
+
+ private void postStatus(@UpdateStatusProvider.UpdateState int status) {
+ mUpdateState = status;
+ PostTask.postTask(UiThreadTaskTraits.DEFAULT, mCallback);
+ }
+}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omaha/inline/InlineUpdateControllerFactory.java b/chrome/android/java/src/org/chromium/chrome/browser/omaha/inline/InlineUpdateControllerFactory.java
--- a/chrome/android/java/src/org/chromium/chrome/browser/omaha/inline/InlineUpdateControllerFactory.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/omaha/inline/InlineUpdateControllerFactory.java
@@ -19,8 +19,10 @@ public class InlineUpdateControllerFactory {
@FakeAppUpdateManagerWrapper.Type
int mockInlineEndState = UpdateConfigs.getMockInlineScenarioEndState();
- // No test scenario was in place, and the inline flow has not been enabled, so use a
- // controller with no functionality.
- return new NoopInlineUpdateController(callback);
+ if (ChromeFeatureList.isEnabled(ChromeFeatureList.INLINE_UPDATE_FLOW)) {
+ return new BromiteInlineUpdateController(callback);
+ } else {
+ return new NoopInlineUpdateController(callback);
+ }
}
}
diff --git a/chrome/browser/endpoint_fetcher/BUILD.gn b/chrome/browser/endpoint_fetcher/BUILD.gn
--- a/chrome/browser/endpoint_fetcher/BUILD.gn
+++ b/chrome/browser/endpoint_fetcher/BUILD.gn
@@ -14,6 +14,7 @@ android_library("java") {
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",
]
annotation_processor_deps = [ "//base/android/jni_generator:jni_processor" ]
}
@@ -22,5 +23,6 @@ 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/endpoint_fetcher.cc b/chrome/browser/endpoint_fetcher/endpoint_fetcher.cc
--- a/chrome/browser/endpoint_fetcher/endpoint_fetcher.cc
+++ b/chrome/browser/endpoint_fetcher/endpoint_fetcher.cc
@@ -26,10 +26,15 @@
#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_android.h"
#endif // defined(OS_ANDROID)
+#include "net/base/load_flags.h"
+#include "net/http/http_status_code.h"
+#include "services/network/public/cpp/resource_request.h"
+
namespace {
const char kContentTypeKey[] = "Content-Type";
const char kDeveloperKey[] = "X-Developer-Key";
@@ -150,6 +155,19 @@ EndpointFetcher::EndpointFetcher(
identity_manager_(nullptr),
sanitize_response_(true) {}
+EndpointFetcher::EndpointFetcher(
+ Profile* const profile,
+ const GURL& url,
+ int64_t timeout_ms,
+ const net::NetworkTrafficAnnotationTag& annotation_tag)
+ : url_(url),
+ timeout_ms_(timeout_ms),
+ annotation_tag_(annotation_tag),
+ url_loader_factory_(profile->GetDefaultStoragePartition()
+ ->GetURLLoaderFactoryForBrowserProcess()),
+ identity_manager_(nullptr),
+ sanitize_response_(false) {}
+
EndpointFetcher::~EndpointFetcher() = default;
void EndpointFetcher::Fetch(EndpointFetcherCallback endpoint_fetcher_callback) {
@@ -279,6 +297,73 @@ void EndpointFetcher::OnSanitizationResult(
std::move(endpoint_fetcher_callback).Run(std::move(response));
}
+void EndpointFetcher::PerformHeadRequest(
+ EndpointFetcherCallback endpoint_fetcher_callback,
+ const char* key,
+ bool allow_redirect) {
+
+ endpoint_fetcher_callback_ = std::move(endpoint_fetcher_callback);
+
+ auto resource_request = std::make_unique<network::ResourceRequest>();
+ resource_request->method = "HEAD";
+ resource_request->url = 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;
+ if (allow_redirect == false) {
+ resource_request->redirect_mode = network::mojom::RedirectMode::kManual;
+ }
+
+ simple_url_loader_ = network::SimpleURLLoader::Create(
+ std::move(resource_request), annotation_tag_);
+ simple_url_loader_->SetTimeoutDuration(
+ base::TimeDelta::FromMilliseconds(timeout_ms_));
+ simple_url_loader_->SetAllowHttpErrorResults(true);
+
+ if(!response_)
+ response_ = std::make_unique<EndpointResponse>();
+
+ if (allow_redirect == false) {
+ simple_url_loader_->SetOnRedirectCallback(base::BindRepeating(
+ &EndpointFetcher::OnSimpleLoaderRedirect, base::Unretained(this)));
+ }
+
+ simple_url_loader_->DownloadHeadersOnly(
+ url_loader_factory_.get(),
+ base::BindOnce(&EndpointFetcher::OnURLLoadComplete,
+ base::Unretained(this)));
+}
+
+void EndpointFetcher::OnSimpleLoaderRedirect(
+ const net::RedirectInfo& redirect_info,
+ const network::mojom::URLResponseHead& response_head,
+ std::vector<std::string>* removed_headers) {
+ url_ = redirect_info.new_url;
+ if (response_->redirect_url.empty())
+ response_->redirect_url = url_.spec();
+
+ PerformHeadRequest(std::move(endpoint_fetcher_callback_), nullptr, true);
+}
+
+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_));
+}
+
#if defined(OS_ANDROID)
namespace {
static void OnEndpointFetcherComplete(
@@ -295,6 +380,25 @@ static void OnEndpointFetcherComplete(
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<EndpointFetcher> endpoint_fetcher,
+ std::unique_ptr<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
// TODO(crbug.com/1077537) Create a KeyProvider so
@@ -380,4 +484,25 @@ static void JNI_EndpointFetcher_NativeFetchWithNoAuth(
nullptr);
}
+static void JNI_EndpointFetcher_NativeHeadWithNoAuth(
+ JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& jprofile,
+ const base::android::JavaParamRef<jstring>& jurl,
+ jlong jtimeout, jboolean allow_redirect,
+ const base::android::JavaParamRef<jobject>& jcallback) {
+ auto endpoint_fetcher = std::make_unique<EndpointFetcher>(
+ ProfileAndroid::FromProfileAndroid(jprofile),
+ GURL(base::android::ConvertJavaStringToUTF8(env, jurl)),
+ jtimeout,
+ NO_TRAFFIC_ANNOTATION_YET);
+ auto* const endpoint_fetcher_ptr = endpoint_fetcher.get();
+ endpoint_fetcher_ptr->PerformHeadRequest(
+ 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, allow_redirect);
+}
+
#endif // defined(OS_ANDROID)
diff --git a/chrome/browser/endpoint_fetcher/endpoint_fetcher.h b/chrome/browser/endpoint_fetcher/endpoint_fetcher.h
--- a/chrome/browser/endpoint_fetcher/endpoint_fetcher.h
+++ b/chrome/browser/endpoint_fetcher/endpoint_fetcher.h
@@ -14,6 +14,8 @@
#include "components/signin/public/identity_manager/scope_set.h"
#include "net/traffic_annotation/network_traffic_annotation.h"
#include "services/data_decoder/public/cpp/json_sanitizer.h"
+#include "services/network/public/cpp/resource_request.h"
+#include "services/network/public/mojom/url_response_head.mojom.h"
namespace network {
struct ResourceRequest;
@@ -31,6 +33,8 @@ class Profile;
struct EndpointResponse {
std::string response;
+ long last_modified;
+ std::string redirect_url;
// TODO(crbug.com/993393) Add more detailed error messaging
};
@@ -77,6 +81,12 @@ class EndpointFetcher {
const GURL& url,
const net::NetworkTrafficAnnotationTag& annotation_tag);
+ // Constructor if no authentication is needed, with timeout
+ EndpointFetcher(Profile* const profile,
+ const GURL& url,
+ int64_t timeout_ms,
+ const net::NetworkTrafficAnnotationTag& annotation_tag);
+
// Used for tests. Can be used if caller constructs their own
// url_loader_factory and identity_manager.
EndpointFetcher(
@@ -113,6 +123,10 @@ class EndpointFetcher {
virtual void PerformRequest(EndpointFetcherCallback endpoint_fetcher_callback,
const char* key);
+ virtual void PerformHeadRequest(EndpointFetcherCallback endpoint_fetcher_callback,
+ const char* key,
+ bool allow_redirect);
+
protected:
// Used for Mock only. see MockEndpointFetcher class.
explicit EndpointFetcher(
@@ -126,6 +140,10 @@ class EndpointFetcher {
std::unique_ptr<std::string> response_body);
void OnSanitizationResult(EndpointFetcherCallback endpoint_fetcher_callback,
data_decoder::JsonSanitizer::Result result);
+ void OnURLLoadComplete(scoped_refptr<net::HttpResponseHeaders> headers);
+ void OnSimpleLoaderRedirect(const net::RedirectInfo& redirect_info,
+ const network::mojom::URLResponseHead& response_head,
+ std::vector<std::string>* removed_headers);
enum AuthType { CHROME_API_KEY, OAUTH, NO_AUTH };
AuthType auth_type_;
@@ -133,7 +151,7 @@ class EndpointFetcher {
// Members set in constructor to be passed to network::ResourceRequest or
// network::SimpleURLLoader.
const std::string oauth_consumer_name_;
- const GURL url_;
+ GURL url_;
const std::string http_method_;
const std::string content_type_;
int64_t timeout_ms_;
@@ -152,6 +170,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/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
--- 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
@@ -68,6 +68,14 @@ public final class EndpointFetcher {
profile, url, httpsMethod, contentType, postData, timeout, headers, callback);
}
+ @MainThread
+ public static void nativeHeadWithNoAuth(
+ Callback<EndpointHeaderResponse> callback, Profile profile,
+ String url, long timeout, boolean allow_redirect) {
+ EndpointFetcherJni.get().nativeHeadWithNoAuth(
+ profile, url, timeout, allow_redirect, callback);
+ }
+
@NativeMethods
public interface Natives {
void nativeFetchOAuth(Profile profile, String oathConsumerName, String url,
@@ -78,5 +86,8 @@ public final class EndpointFetcher {
Callback<EndpointResponse> callback);
void nativeFetchWithNoAuth(
Profile profile, String url, Callback<EndpointResponse> callback);
+ void nativeHeadWithNoAuth(
+ Profile profile, String url, long timeout, boolean allow_redirect,
+ 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.chromium.base.annotations.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/flag-metadata.json b/chrome/browser/flag-metadata.json
--- a/chrome/browser/flag-metadata.json
+++ b/chrome/browser/flag-metadata.json
@@ -2059,7 +2059,7 @@
{
"name": "enable-inline-update-flow",
"owners": [ "nyquist", "dtrainor" ],
- "expiry_milestone": 83
+ "expiry_milestone": -1
},
{
"name": "enable-input-event-logging",
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc
--- a/chrome/browser/flag_descriptions.cc
+++ b/chrome/browser/flag_descriptions.cc
@@ -3705,10 +3705,9 @@ const char kVoiceButtonInTopToolbarDescription[] =
"Enables showing the voice search button in the top toolbar. Enabling "
"Adaptive Button overrides this.";
-const char kInlineUpdateFlowName[] = "Enable Google Play inline update flow";
+const char kInlineUpdateFlowName[] = "Enable inline update flow";
const char kInlineUpdateFlowDescription[] =
- "When this flag is set, instead of taking the user to the Google Play "
- "Store when an update is available, the user is presented with an inline "
+ "When this flag is set, the user is presented with an inline "
"flow where they do not have to leave Chrome until the update is ready "
"to install.";
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
@@ -594,7 +594,7 @@ const base::Feature kIncognitoScreenshot{"IncognitoScreenshot",
base::FEATURE_DISABLED_BY_DEFAULT};
const base::Feature kInlineUpdateFlow{"InlineUpdateFlow",
- base::FEATURE_DISABLED_BY_DEFAULT};
+ base::FEATURE_ENABLED_BY_DEFAULT};
const base::Feature kInstantStart{"InstantStart",
base::FEATURE_DISABLED_BY_DEFAULT};
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
@@ -1631,6 +1631,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">
+ Check for updates by contacting the Bromite repo
+ </message>
<!-- Account management UI strings. -->
<message name="IDS_ACCOUNT_MANAGEMENT_TITLE" desc="Header title for the account management screen. [CHAR_LIMIT=32]">
@@ -3059,7 +3065,7 @@ To change this setting, <ph name="BEGIN_LINK">&lt;resetlink&gt;</ph>reset sync<p
<!-- 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_DEFAULT" desc="Summary string for update menu item explaining that a newer version of Chrome is available. [CHAR_LIMIT=30]">
Newer version is available
--
2.17.1