Commit e1bcb0cc authored by David Trainor's avatar David Trainor

Add a mocked FakeAppUpdateManager for simulating inline updates

Add the ability to simulate an inline update flow, which will be used by variations,
test, and PM/UX to look at the update flow.

BUG=922714

Change-Id: Ic313e8cae6e9fc9f0413c227c151990d192e62a5
Reviewed-on: https://chromium-review.googlesource.com/c/1461831Reviewed-by: default avatarTommy Nyquist <nyquist@chromium.org>
Reviewed-by: default avatarDavid Trainor <dtrainor@chromium.org>
Cr-Commit-Position: refs/heads/master@{#632018}
parent be0bc552
...@@ -342,6 +342,7 @@ android_library("chrome_java") { ...@@ -342,6 +342,7 @@ android_library("chrome_java") {
"//third_party/custom_tabs_client:custom_tabs_support_java", "//third_party/custom_tabs_client:custom_tabs_support_java",
"//third_party/feed:feed_lib_proto_java", "//third_party/feed:feed_lib_proto_java",
"//third_party/gif_player:gif_player_java", "//third_party/gif_player:gif_player_java",
"//third_party/google_android_play_core:com_google_android_play_core_java",
"//third_party/jsr-305:jsr_305_javalib", "//third_party/jsr-305:jsr_305_javalib",
"//ui/android:ui_java", "//ui/android:ui_java",
"//ui/base/mojo:mojo_java", "//ui/base/mojo:mojo_java",
......
// 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.os.Handler;
import android.os.Looper;
import android.support.annotation.IntDef;
import com.google.android.play.core.appupdate.AppUpdateInfo;
import com.google.android.play.core.appupdate.testing.FakeAppUpdateManager;
import com.google.android.play.core.install.model.AppUpdateType;
import com.google.android.play.core.tasks.Task;
import org.chromium.base.ContextUtils;
import org.chromium.chrome.browser.ChromeActivity;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/**
* A wrapper of FakeAppUpdateManager meant to help automatically trigger more update scenarios. The
* wrapper isn't meant to be used for a full integration test, but simulating all of the possible
* error cases is a bit easier to do here.
*/
class FakeAppUpdateManagerWrapper extends FakeAppUpdateManager {
private static final int RESULT_IN_APP_UPDATE_FAILED = 1;
private static final int STEP_DELAY_MS = 5000;
/** A list of inline update end states that this class can simulate. */
@IntDef({Type.NONE, Type.SUCCESS, Type.FAIL_DIALOG_CANCEL, Type.FAIL_DIALOG_UPDATE_FAILED,
Type.FAIL_DOWNLOAD, Type.FAIL_DOWNLOAD_CANCEL, Type.FAIL_INSTALL})
@Retention(RetentionPolicy.SOURCE)
public @interface Type {
/** No update available. */
int NONE = 1;
/** The update will be successful. */
int SUCCESS = 2;
/** The update will fail because the user will choose cancel when the Play dialog shows. */
int FAIL_DIALOG_CANCEL = 3;
/** The update will fail because the dialog will fail with another unknown reason. */
int FAIL_DIALOG_UPDATE_FAILED = 4;
/** The update will fail because the download fails. */
int FAIL_DOWNLOAD = 5;
/** The update will fail because the download was cancelled.*/
int FAIL_DOWNLOAD_CANCEL = 6;
/** The update will fail because it failed to install. */
int FAIL_INSTALL = 6;
}
private final Handler mHandler = new Handler(Looper.getMainLooper());
private final @Type int mType;
/**
*
* @param type
*/
public FakeAppUpdateManagerWrapper(@Type int type) {
super(ContextUtils.getApplicationContext());
mType = type;
if (mType != Type.NONE) setUpdateAvailable(10000 /* Figure out a better version? */);
}
// FakeAppUpdateManager implementation.
@Override
public boolean startUpdateFlowForResult(AppUpdateInfo appUpdateInfo,
@AppUpdateType int appUpdateType, Activity activity, int requestCode) {
boolean success =
super.startUpdateFlowForResult(appUpdateInfo, appUpdateType, activity, requestCode);
if (!success) return false;
assert activity instanceof ChromeActivity : "Unexpected triggering activity.";
final int resultCode;
if (mType == Type.FAIL_DIALOG_CANCEL) {
resultCode = Activity.RESULT_CANCELED;
} else if (mType == Type.FAIL_DIALOG_UPDATE_FAILED) {
resultCode = RESULT_IN_APP_UPDATE_FAILED;
} else {
resultCode = Activity.RESULT_OK;
}
mHandler.postDelayed(() -> {
triggerDialogResponse((ChromeActivity) activity, requestCode, resultCode);
}, STEP_DELAY_MS);
return true;
}
@Override
public Task<Void> completeUpdate() {
Task<Void> result = super.completeUpdate();
if (mType == Type.FAIL_INSTALL) {
mHandler.postDelayed(this::installCompletes, STEP_DELAY_MS);
// This doesn't actually restart Chrome in this case.
} else {
mHandler.postDelayed(this::installFails, STEP_DELAY_MS);
}
return result;
}
private void triggerDialogResponse(ChromeActivity activity, int requestCode, int resultCode) {
if (resultCode == Activity.RESULT_OK) {
userAcceptsUpdate();
} else if (resultCode == Activity.RESULT_CANCELED) {
userRejectsUpdate();
}
activity.onActivityResult(requestCode, resultCode, null);
if (resultCode == Activity.RESULT_OK) {
mHandler.postDelayed(this::triggerDownload, STEP_DELAY_MS);
}
}
private void triggerDownload() {
downloadStarts();
if (mType == Type.FAIL_DOWNLOAD) {
mHandler.postDelayed(this::downloadFails, STEP_DELAY_MS);
} else if (mType == Type.FAIL_DOWNLOAD_CANCEL) {
mHandler.postDelayed(this::userCancelsDownload, STEP_DELAY_MS);
} else {
mHandler.postDelayed(this::triggerInstall, STEP_DELAY_MS);
}
}
private void triggerInstall() {
downloadCompletes();
}
}
\ No newline at end of file
// 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 com.google.android.play.core.appupdate.AppUpdateManager;
import com.google.android.play.core.appupdate.AppUpdateManagerFactory;
import org.chromium.base.ContextUtils;
import org.chromium.chrome.browser.omaha.inline.FakeAppUpdateManagerWrapper.Type;
/** A factory that creates an {@link AppUpdateManager} instance. */
public class InlineAppUpdateManagerFactory {
private static final boolean sTest = false;
/** @return A new {@link AppUpdateManager} to use to interact with Play for inline updates. */
public static AppUpdateManager create() {
// TODO(me): Check finch configuration to figure out what kind of test scenario to run.
if (sTest) {
return new FakeAppUpdateManagerWrapper(Type.NONE);
} else {
return AppUpdateManagerFactory.create(ContextUtils.getApplicationContext());
}
}
}
\ No newline at end of file
...@@ -1107,6 +1107,8 @@ chrome_java_sources = [ ...@@ -1107,6 +1107,8 @@ chrome_java_sources = [
"java/src/org/chromium/chrome/browser/offlinepages/prefetch/PrefetchConfiguration.java", "java/src/org/chromium/chrome/browser/offlinepages/prefetch/PrefetchConfiguration.java",
"java/src/org/chromium/chrome/browser/offlinepages/prefetch/PrefetchPrefs.java", "java/src/org/chromium/chrome/browser/offlinepages/prefetch/PrefetchPrefs.java",
"java/src/org/chromium/chrome/browser/offlinepages/prefetch/PrefetchedPagesNotifier.java", "java/src/org/chromium/chrome/browser/offlinepages/prefetch/PrefetchedPagesNotifier.java",
"java/src/org/chromium/chrome/browser/omaha/inline/FakeAppUpdateManagerWrapper.java",
"java/src/org/chromium/chrome/browser/omaha/inline/InlineAppUpdateManagerFactory.java",
"java/src/org/chromium/chrome/browser/omaha/inline/InlineUpdateController.java", "java/src/org/chromium/chrome/browser/omaha/inline/InlineUpdateController.java",
"java/src/org/chromium/chrome/browser/omaha/ExponentialBackoffScheduler.java", "java/src/org/chromium/chrome/browser/omaha/ExponentialBackoffScheduler.java",
"java/src/org/chromium/chrome/browser/omaha/MarketURLGetter.java", "java/src/org/chromium/chrome/browser/omaha/MarketURLGetter.java",
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment