Commit 71cebab1 authored by Takashi Sakamoto's avatar Takashi Sakamoto Committed by Commit Bot

Revert "Add App Service Instance related classes."

This reverts commit 29d31a12.

Reason for revert: suspect causing compile failure on linux-chromeos-rel

Sample build: https://ci.chromium.org/p/chromium/builders/ci/linux-chromeos-rel/30980

Original change's description:
> Add App Service Instance related classes.
> 
> Design doc:
> go/app-service-instance-registry-design-doc
> go/appservice-for-per-app-time-limit-design-doc
> 
> This CL adds the App Service Instance classes:
> Instance
> InstanceUpdate
> InstanceRegistry
> 
> InstanceRegistry depends on Instance and InstanceUpdate to calculate
> the instance updates to notify the client.
> 
> BUG=1011235
> 
> Change-Id: Ife2a25c1ae24b3a5c8e1ef67540ba49939126174
> Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1896484
> Reviewed-by: Dominick Ng <dominickn@chromium.org>
> Commit-Queue: Nancy Wang <nancylingwang@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#712915}

TBR=dominickn@chromium.org,nancylingwang@chromium.org

Change-Id: Ibd6556f36a71a477b4a3515b9d53a6be1cceb3fa
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: 1011235
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1900793Reviewed-by: default avatarTakashi Sakamoto <tasak@google.com>
Commit-Queue: Takashi Sakamoto <tasak@google.com>
Cr-Commit-Position: refs/heads/master@{#712919}
parent d551caae
......@@ -3717,7 +3717,6 @@ jumbo_static_library("browser") {
deps += [
"//ash/public/cpp",
"//chrome/browser/chromeos",
"//chrome/services/app_service/public/cpp:instance_update",
"//chromeos/components/account_manager",
"//chromeos/components/sync_wifi",
"//chromeos/services/assistant/public:feature_flags",
......
......@@ -15,7 +15,6 @@
#include "chrome/browser/apps/app_service/uninstall_dialog.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/services/app_service/app_service_impl.h"
#include "chrome/services/app_service/public/cpp/instance_registry.h"
#include "chrome/services/app_service/public/cpp/intent_filter_util.h"
#include "chrome/services/app_service/public/cpp/intent_util.h"
#include "chrome/services/app_service/public/mojom/types.mojom.h"
......@@ -164,12 +163,6 @@ apps::AppRegistryCache& AppServiceProxy::AppRegistryCache() {
return cache_;
}
#if defined(OS_CHROMEOS)
apps::InstanceRegistry& AppServiceProxy::InstanceRegistry() {
return instance_registry_;
}
#endif
apps::PreferredApps& AppServiceProxy::PreferredApps() {
return preferred_apps_;
}
......
......@@ -15,7 +15,6 @@
#include "chrome/services/app_service/public/cpp/app_registry_cache.h"
#include "chrome/services/app_service/public/cpp/icon_cache.h"
#include "chrome/services/app_service/public/cpp/icon_coalescer.h"
#include "chrome/services/app_service/public/cpp/instance_registry.h"
#include "chrome/services/app_service/public/cpp/preferred_apps.h"
#include "components/keyed_service/core/keyed_service.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
......@@ -53,11 +52,6 @@ class AppServiceProxy : public KeyedService,
mojo::Remote<apps::mojom::AppService>& AppService();
apps::AppRegistryCache& AppRegistryCache();
#if defined(OS_CHROMEOS)
apps::InstanceRegistry& InstanceRegistry();
#endif
apps::PreferredApps& PreferredApps();
// apps::IconLoader overrides.
......@@ -210,10 +204,7 @@ class AppServiceProxy : public KeyedService,
std::unique_ptr<CrostiniApps> crostini_apps_;
std::unique_ptr<ExtensionApps> extension_apps_;
std::unique_ptr<ExtensionApps> extension_web_apps_;
bool arc_is_registered_ = false;
apps::InstanceRegistry instance_registry_;
#endif // OS_CHROMEOS
Profile* profile_;
......
......@@ -15,22 +15,6 @@ source_set("app_update") {
]
}
if (is_chromeos) {
source_set("instance_update") {
sources = [
"instance.cc",
"instance.h",
"instance_registry.cc",
"instance_registry.h",
"instance_update.cc",
"instance_update.h",
]
deps = [
"//skia",
]
}
}
source_set("icon_loader") {
sources = [
"icon_cache.cc",
......@@ -104,13 +88,4 @@ source_set("unit_tests") {
":icon_loader",
"//testing/gtest",
]
if (is_chromeos) {
sources += [
"instance_registry_unittest.cc",
"instance_update_unittest.cc",
]
deps += [ ":instance_update" ]
}
}
// 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.
#include "chrome/services/app_service/public/cpp/instance.h"
#include <memory>
#include "ui/aura/window.h"
namespace apps {
Instance::Instance(const std::string& app_id, aura::Window* window)
: app_id_(app_id), window_(window) {
state_ = InstanceState::kUnknown;
}
Instance::~Instance() = default;
std::unique_ptr<Instance> Instance::Clone() {
auto instance = std::make_unique<Instance>(this->AppId(), this->Window());
instance->SetLaunchId(this->LaunchId());
instance->UpdateState(this->State(), this->LastUpdatedTime());
return instance;
}
void Instance::UpdateState(InstanceState state,
const base::Time& last_updated_time) {
state_ = state;
last_updated_time_ = last_updated_time;
}
} // namespace apps
// 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.
#ifndef CHROME_SERVICES_APP_SERVICE_PUBLIC_CPP_INSTANCE_H_
#define CHROME_SERVICES_APP_SERVICE_PUBLIC_CPP_INSTANCE_H_
#include <memory>
#include <string>
#include "base/time/time.h"
namespace aura {
class Window;
}
namespace apps {
enum InstanceState {
kUnknown = 0,
kStarted = 0x01,
kRunning = 0x02,
kActive = 0x04,
kVisible = 0x08,
};
// Instance is used to represent an App Instance, or a running app.
class Instance {
public:
Instance(const std::string& app_id, aura::Window* window);
~Instance();
Instance(const Instance&) = delete;
Instance& operator=(const Instance&) = delete;
std::unique_ptr<Instance> Clone();
void SetLaunchId(const std::string& launch_id) { launch_id_ = launch_id; }
void UpdateState(InstanceState state, const base::Time& last_updated_time);
const std::string& AppId() const { return app_id_; }
aura::Window* Window() const { return window_; }
const std::string& LaunchId() const { return launch_id_; }
InstanceState State() const { return state_; }
const base::Time& LastUpdatedTime() const { return last_updated_time_; }
private:
std::string app_id_;
// window_ is owned by ash and will be deleted when the user closes the
// window. Instance itself doesn't observe the window. The window's observer
// is responsible to delete Instance from InstanceRegistry when the window is
// destroyed.
aura::Window* window_;
std::string launch_id_;
InstanceState state_;
base::Time last_updated_time_;
};
} // namespace apps
#endif // CHROME_SERVICES_APP_SERVICE_PUBLIC_CPP_INSTANCE_H_
// 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.
#include "chrome/services/app_service/public/cpp/instance_registry.h"
#include <memory>
#include <utility>
#include "chrome/services/app_service/public/cpp/instance.h"
#include "chrome/services/app_service/public/cpp/instance_update.h"
namespace apps {
InstanceRegistry::Observer::Observer(InstanceRegistry* instance_registry) {
Observe(instance_registry);
}
InstanceRegistry::Observer::Observer() = default;
InstanceRegistry::Observer::~Observer() {
if (instance_registry_) {
instance_registry_->RemoveObserver(this);
}
}
void InstanceRegistry::Observer::Observe(InstanceRegistry* instance_registry) {
if (instance_registry == instance_registry_) {
return;
}
if (instance_registry_) {
instance_registry_->RemoveObserver(this);
}
instance_registry_ = instance_registry;
if (instance_registry_) {
instance_registry_->AddObserver(this);
}
}
InstanceRegistry::InstanceRegistry() = default;
InstanceRegistry::~InstanceRegistry() {
for (auto& obs : observers_) {
obs.OnInstanceRegistryWillBeDestroyed(this);
}
DCHECK(!observers_.might_have_observers());
}
void InstanceRegistry::AddObserver(Observer* observer) {
observers_.AddObserver(observer);
}
void InstanceRegistry::RemoveObserver(Observer* observer) {
observers_.RemoveObserver(observer);
}
void InstanceRegistry::OnInstances(const Instances& deltas) {
DCHECK_CALLED_ON_VALID_SEQUENCE(my_sequence_checker_);
if (!deltas_in_progress_.empty()) {
for (auto& delta : deltas) {
deltas_pending_.push_back(delta.get()->Clone());
}
return;
}
DoOnInstances(std::move(deltas));
while (!deltas_pending_.empty()) {
Instances pending;
pending.swap(deltas_pending_);
DoOnInstances(std::move(pending));
}
}
void InstanceRegistry::DoOnInstances(const Instances& deltas) {
// Merge any deltas elements that have the same window. If an observer's
// OnInstanceUpdate calls back into this InstanceRegistry, we can present a
// single delta for any given window.
for (auto& delta : deltas) {
auto d_iter = deltas_in_progress_.find(delta->Window());
if (d_iter != deltas_in_progress_.end()) {
InstanceUpdate::Merge(d_iter->second, delta.get());
} else {
deltas_in_progress_[delta->Window()] = delta.get();
}
}
// The remaining for loops range over the deltas_in_progress_ map, not the
// deltas vector, so that OninstanceUpdate is called only once per unique
// window. Notify the observers for every de-duplicated delta.
for (const auto& d_iter : deltas_in_progress_) {
auto s_iter = states_.find(d_iter.first);
Instance* state =
(s_iter != states_.end()) ? s_iter->second.get() : nullptr;
Instance* delta = d_iter.second;
for (auto& obs : observers_) {
obs.OnInstanceUpdate(InstanceUpdate(state, delta));
}
}
// Update the states for every de-duplicated delta.
for (const auto& d_iter : deltas_in_progress_) {
auto s_iter = states_.find(d_iter.first);
Instance* state =
(s_iter != states_.end()) ? s_iter->second.get() : nullptr;
Instance* delta = d_iter.second;
if (state) {
InstanceUpdate::Merge(state, delta);
} else {
states_.insert(std::make_pair(delta->Window(), (delta->Clone())));
}
}
deltas_in_progress_.clear();
}
} // namespace apps
// 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.
#ifndef CHROME_SERVICES_APP_SERVICE_PUBLIC_CPP_INSTANCE_REGISTRY_H_
#define CHROME_SERVICES_APP_SERVICE_PUBLIC_CPP_INSTANCE_REGISTRY_H_
#include <map>
#include <memory>
#include <string>
#include <vector>
#include "base/observer_list.h"
#include "base/observer_list_types.h"
#include "base/sequence_checker.h"
#include "chrome/services/app_service/public/cpp/instance.h"
#include "chrome/services/app_service/public/cpp/instance_update.h"
namespace aura {
class Window;
}
namespace apps {
// InstanceRegistry keeps all of the Instances seen by AppServiceProxy.
// It also keeps the "sum" of those previous deltas, so that observers of this
// object can be updated with the InstanceUpdate structure. It can also be
// queried synchronously.
//
// This class is not thread-safe.
class InstanceRegistry {
public:
class Observer : public base::CheckedObserver {
public:
Observer(const Observer&) = delete;
Observer& operator=(const Observer&) = delete;
// The InstanceUpdate argument shouldn't be accessed after OnInstanceUpdate
// returns.
virtual void OnInstanceUpdate(const InstanceUpdate& update) = 0;
// Called when the InstanceRegistry object (the thing that this observer
// observes) will be destroyed. In response, the observer, |this|, should
// call "instance_registry->RemoveObserver(this)", whether directly or
// indirectly (e.g. via ScopedObserver::Remove or via Observe(nullptr)).
virtual void OnInstanceRegistryWillBeDestroyed(InstanceRegistry* cache) = 0;
protected:
// Use this constructor when the observer |this| is tied to a single
// InstanceRegistry for its entire lifetime, or until the observee (the
// InstanceRegistry) is destroyed, whichever comes first.
explicit Observer(InstanceRegistry* cache);
// Use this constructor when the observer |this| wants to observe a
// InstanceRegistry for part of its lifetime. It can then call Observe() to
// start and stop observing.
Observer();
~Observer() override;
// Start observing a different InstanceRegistry. |instance_registry| may be
// nullptr, meaning to stop observing.
void Observe(InstanceRegistry* instance_registry);
private:
InstanceRegistry* instance_registry_ = nullptr;
};
InstanceRegistry();
~InstanceRegistry();
InstanceRegistry(const InstanceRegistry&) = delete;
InstanceRegistry& operator=(const InstanceRegistry&) = delete;
void AddObserver(Observer* observer);
void RemoveObserver(Observer* observer);
using InstancePtr = std::unique_ptr<Instance>;
using Instances = std::vector<InstancePtr>;
// Notification and merging might be delayed until after OnInstances returns.
// For example, suppose that the initial set of states is (a0, b0, c0) for
// three app_id's ("a", "b", "c"). Now suppose OnInstances is called with two
// updates (b1, c1), and when notified of b1, an observer calls OnInstances
// again with (c2, d2). The c1 delta should be processed before the c2 delta,
// as it was sent first: c2 should be merged (with "newest wins" semantics)
// onto c1 and not vice versa. This means that processing c2 (scheduled by the
// second OnInstances call) should wait until the first OnInstances call has
// finished processing b1 (and then c1), which means that processing c2 is
// delayed until after the second OnInstances call returns.
//
// The caller presumably calls OnInstances(std::move(deltas)).
void OnInstances(const Instances& deltas);
// Calls f, a void-returning function whose arguments are (const
// apps::InstanceUpdate&), on each window in the instance_registry.
//
// f's argument is an apps::InstanceUpdate instead of an Instance* so that
// callers can more easily share code with Observer::OnInstanceUpdate (which
// also takes an apps::InstanceUpdate), and an apps::InstanceUpdate also has a
// StateIsNull method.
//
// The apps::InstanceUpdate argument to f shouldn't be accessed after f
// returns.
//
// f must be synchronous, and if it asynchronously calls ForEachInstance
// again, it's not guaranteed to see a consistent state.
template <typename FunctionType>
void ForEachInstance(FunctionType f) {
DCHECK_CALLED_ON_VALID_SEQUENCE(my_sequence_checker_);
for (const auto& s_iter : states_) {
apps::Instance* state = s_iter.second.get();
auto d_iter = deltas_in_progress_.find(s_iter.first);
apps::Instance* delta =
(d_iter != deltas_in_progress_.end()) ? d_iter->second : nullptr;
f(apps::InstanceUpdate(state, delta));
}
for (const auto& d_iter : deltas_in_progress_) {
apps::Instance* delta = d_iter.second;
auto s_iter = states_.find(d_iter.first);
if (s_iter != states_.end()) {
continue;
}
f(apps::InstanceUpdate(nullptr, delta));
}
}
// Calls f, a void-returning function whose arguments are (const
// apps::InstanceUpdate&), on the instance in the instance_registry with the
// given window. It will return true (and call f) if there is such an
// instance, otherwise it will return false (and not call f). The
// InstanceUpdate argument to f has the same semantics as for ForEachInstance,
// above.
//
// f must be synchronous, and if it asynchronously calls ForOneInstance again,
// it's not guaranteed to see a consistent state.
template <typename FunctionType>
bool ForOneInstance(const aura::Window* window, FunctionType f) {
DCHECK_CALLED_ON_VALID_SEQUENCE(my_sequence_checker_);
auto s_iter = states_.find(window);
apps::Instance* state =
(s_iter != states_.end()) ? s_iter->second.get() : nullptr;
auto d_iter = deltas_in_progress_.find(window);
apps::Instance* delta =
(d_iter != deltas_in_progress_.end()) ? d_iter->second : nullptr;
if (state || delta) {
f(apps::InstanceUpdate(state, delta));
return true;
}
return false;
}
private:
void DoOnInstances(const Instances& deltas);
base::ObserverList<Observer> observers_;
// Maps from window to the latest state: the "sum" of all previous deltas.
std::map<const aura::Window*, InstancePtr> states_;
// Track the deltas being processed or are about to be processed by
// OnInstances. They are separate to manage the "notification and merging
// might be delayed until after OnInstances returns" concern described above.
//
// OnInstances calls DoOnInstances zero or more times. If we're nested, so
// that there's multiple OnInstances call to this InstanceRegistry in the call
// stack, the deeper OnInstances call simply adds work to deltas_pending_ and
// returns without calling DoOnInstances. If we're not nested, OnInstances
// calls DoOnInstances one or more times; "more times" happens if
// DoOnInstances notifying observers leads to more OnInstances calls that
// enqueue deltas_pending_ work. The deltas_in_progress_ map (keyed by window)
// contains those deltas being considered by DoOnInstances.
//
// Nested OnInstances calls are expected to be rare (but still dealt with
// sensibly). In the typical case, OnInstances should call DoOnInstances
// exactly once, and deltas_pending_ will stay empty.
std::map<const aura::Window*, Instance*> deltas_in_progress_;
Instances deltas_pending_;
SEQUENCE_CHECKER(my_sequence_checker_);
};
} // namespace apps
#endif // CHROME_SERVICES_APP_SERVICE_PUBLIC_CPP_INSTANCE_REGISTRY_H_
// 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.
#include "chrome/services/app_service/public/cpp/instance_update.h"
#include "base/strings/string_util.h"
#include "chrome/services/app_service/public/cpp/instance.h"
#include "ui/aura/window.h"
namespace apps {
// static
void InstanceUpdate::Merge(Instance* state, const Instance* delta) {
DCHECK(state);
if (!delta) {
return;
}
if ((delta->AppId() != state->AppId()) ||
delta->Window() != state->Window()) {
LOG(ERROR) << "inconsistent (app_id, window): (" << delta->AppId() << ", "
<< delta->Window() << ") vs (" << state->AppId() << ", "
<< state->Window() << ") ";
DCHECK(false);
return;
}
if (!delta->LaunchId().empty()) {
state->SetLaunchId(delta->LaunchId());
}
if (delta->State() != InstanceState::kUnknown) {
state->UpdateState(delta->State(), delta->LastUpdatedTime());
}
// When adding new fields to the Instance class, this function should also be
// updated.
}
InstanceUpdate::InstanceUpdate(Instance* state, Instance* delta)
: state_(state), delta_(delta) {
DCHECK(state_ || delta_);
if (state_ && delta_) {
DCHECK(state_->AppId() == delta->AppId());
DCHECK(state_->Window() == delta->Window());
}
}
bool InstanceUpdate::StateIsNull() const {
return state_ == nullptr;
}
const std::string& InstanceUpdate::AppId() const {
return delta_ ? delta_->AppId() : state_->AppId();
}
const aura::Window* InstanceUpdate::Window() const {
return delta_ ? delta_->Window() : state_->Window();
}
const std::string& InstanceUpdate::LaunchId() const {
if (delta_ && !delta_->LaunchId().empty()) {
return delta_->LaunchId();
}
if (state_ && !state_->LaunchId().empty()) {
return state_->LaunchId();
}
return base::EmptyString();
}
bool InstanceUpdate::LaunchIdChanged() const {
return delta_ && !delta_->LaunchId().empty() &&
(!state_ || (delta_->LaunchId() != state_->LaunchId()));
}
InstanceState InstanceUpdate::State() const {
if (delta_ && (delta_->State() != InstanceState::kUnknown)) {
return delta_->State();
}
if (state_) {
return state_->State();
}
return InstanceState::kUnknown;
}
bool InstanceUpdate::StateChanged() const {
return delta_ && (delta_->State() != InstanceState::kUnknown) &&
(!state_ || (delta_->State() != state_->State()));
}
base::Time InstanceUpdate::LastUpdatedTime() const {
if (delta_ && !delta_->LastUpdatedTime().is_null()) {
return delta_->LastUpdatedTime();
}
if (state_ && !state_->LastUpdatedTime().is_null()) {
return state_->LastUpdatedTime();
}
return base::Time();
}
bool InstanceUpdate::LastUpdatedTimeChanged() const {
return delta_ && !delta_->LastUpdatedTime().is_null() &&
(!state_ || (delta_->LastUpdatedTime() != state_->LastUpdatedTime()));
}
} // namespace apps
// 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.
#ifndef CHROME_SERVICES_APP_SERVICE_PUBLIC_CPP_INSTANCE_UPDATE_H_
#define CHROME_SERVICES_APP_SERVICE_PUBLIC_CPP_INSTANCE_UPDATE_H_
#include <string>
#include "base/time/time.h"
#include "chrome/services/app_service/public/cpp/instance.h"
namespace aura {
class Window;
}
namespace apps {
class Instance;
// Wraps two Instance's, a prior state and a delta on top of that state. The
// state is conceptually the "sum" of all of the previous deltas, with
// "addition" or "merging" simply being that the most recent version of each
// field "wins".
//
// The state may be nullptr, meaning that there are no previous deltas.
// Alternatively, the delta may be nullptr, meaning that there is no change in
// state. At least one of state and delta must be non-nullptr.
//
// The combination of the two (state and delta) can answer questions such as:
// - What is the app's launch_id? If the delta knows, that's the answer.
// Otherwise, ask the state.
// - Is the app launched? Likewise, if the delta says yes or no, that's the
// answer. Otherwise, the delta says "unknown", ask the state.
//
// An InstanceUpdate is read-only once constructed. All of its fields and
// methods are const. The constructor caller must guarantee that the Instance
// pointer remain valid for the lifetime of the AppUpdate.
//
// See the below two design docs for more details:
// go/app-service-instance-registry-design-doc
// go/appservice-for-per-app-time-limit-design-doc
class InstanceUpdate {
public:
// Modifies |state| by copying over all of |delta|'s known fields: those
// fields whose values aren't "unknown" or invalid. The |state| may not be
// nullptr.
static void Merge(Instance* state, const Instance* delta);
// At most one of |state| or |delta| may be nullptr.
InstanceUpdate(Instance* state, Instance* delta);
InstanceUpdate(const InstanceUpdate&) = delete;
InstanceUpdate& operator=(const InstanceUpdate&) = delete;
// Returns whether this is the first update for the given window.
// Equivalently, there are no previous deltas for the window.
bool StateIsNull() const;
const std::string& AppId() const;
const aura::Window* Window() const;
const std::string& LaunchId() const;
bool LaunchIdChanged() const;
InstanceState State() const;
bool StateChanged() const;
base::Time LastUpdatedTime() const;
bool LastUpdatedTimeChanged() const;
private:
Instance* state_;
Instance* delta_;
};
} // namespace apps
#endif // CHROME_SERVICES_APP_SERVICE_PUBLIC_CPP_INSTANCE_UPDATE_H_
// 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.
#include "chrome/services/app_service/public/cpp/instance_update.h"
#include "chrome/services/app_service/public/cpp/instance.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/aura/window.h"
namespace {
const char app_id[] = "abcdefgh";
const char test_launch_id0[] = "abc";
const char test_launch_id1[] = "xyz";
} // namespace
class InstanceUpdateTest : public testing::Test {
protected:
void ExpectNoChange() {
expect_launch_id_changed_ = false;
expect_state_changed_ = false;
expect_last_updated_time_changed_ = false;
}
void CheckExpects(const apps::InstanceUpdate& u) {
EXPECT_EQ(expect_launch_id_, u.LaunchId());
EXPECT_EQ(expect_launch_id_changed_, u.LaunchIdChanged());
EXPECT_EQ(expect_state_, u.State());
EXPECT_EQ(expect_state_changed_, u.StateChanged());
EXPECT_EQ(expect_last_updated_time_, u.LastUpdatedTime());
EXPECT_EQ(expect_last_updated_time_changed_, u.LastUpdatedTimeChanged());
}
void TestInstanceUpdate(apps::Instance* state, apps::Instance* delta) {
apps::InstanceUpdate u(state, delta);
EXPECT_EQ(app_id, u.AppId());
EXPECT_EQ(state == nullptr, u.StateIsNull());
expect_launch_id_ = base::EmptyString();
expect_state_ = apps::InstanceState::kUnknown;
expect_last_updated_time_ = base::Time();
ExpectNoChange();
CheckExpects(u);
if (delta) {
delta->SetLaunchId(test_launch_id0);
expect_launch_id_ = test_launch_id0;
expect_launch_id_changed_ = true;
CheckExpects(u);
}
if (state) {
state->SetLaunchId(test_launch_id0);
expect_launch_id_ = test_launch_id0;
expect_launch_id_changed_ = false;
CheckExpects(u);
}
if (state) {
apps::InstanceUpdate::Merge(state, delta);
ExpectNoChange();
CheckExpects(u);
}
if (delta) {
delta->SetLaunchId(test_launch_id1);
expect_launch_id_ = test_launch_id1;
expect_launch_id_changed_ = true;
CheckExpects(u);
}
// State and StateTime tests.
if (state) {
state->UpdateState(apps::InstanceState::kRunning,
base::Time::FromDoubleT(1000.0));
expect_state_ = apps::InstanceState::kRunning;
expect_last_updated_time_ = base::Time::FromDoubleT(1000.0);
expect_state_changed_ = false;
expect_last_updated_time_changed_ = false;
CheckExpects(u);
}
if (delta) {
delta->UpdateState(apps::InstanceState::kActive,
base::Time::FromDoubleT(2000.0));
expect_state_ = apps::InstanceState::kActive;
expect_last_updated_time_ = base::Time::FromDoubleT(2000.0);
expect_state_changed_ = true;
expect_last_updated_time_changed_ = true;
CheckExpects(u);
}
if (state) {
apps::InstanceUpdate::Merge(state, delta);
ExpectNoChange();
CheckExpects(u);
}
}
std::string expect_launch_id_;
bool expect_launch_id_changed_;
apps::InstanceState expect_state_;
bool expect_state_changed_;
base::Time expect_last_updated_time_;
bool expect_last_updated_time_changed_;
};
TEST_F(InstanceUpdateTest, StateIsNonNull) {
aura::Window window(nullptr);
window.Init(ui::LAYER_NOT_DRAWN);
std::unique_ptr<apps::Instance> state =
std::make_unique<apps::Instance>(app_id, &window);
TestInstanceUpdate(state.get(), nullptr);
}
TEST_F(InstanceUpdateTest, DeltaIsNonNull) {
aura::Window window(nullptr);
window.Init(ui::LAYER_NOT_DRAWN);
std::unique_ptr<apps::Instance> delta =
std::make_unique<apps::Instance>(app_id, &window);
TestInstanceUpdate(nullptr, delta.get());
}
TEST_F(InstanceUpdateTest, BothAreNonNull) {
aura::Window window(nullptr);
window.Init(ui::LAYER_NOT_DRAWN);
std::unique_ptr<apps::Instance> state =
std::make_unique<apps::Instance>(app_id, &window);
std::unique_ptr<apps::Instance> delta =
std::make_unique<apps::Instance>(app_id, &window);
TestInstanceUpdate(state.get(), delta.get());
}
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