forked from chromium/chromium
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathambient_controller.cc
138 lines (111 loc) · 4.08 KB
/
ambient_controller.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
// 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 "ash/ambient/ambient_controller.h"
#include "ash/ambient/ambient_constants.h"
#include "ash/ambient/model/photo_model_observer.h"
#include "ash/ambient/ui/ambient_container_view.h"
#include "ash/ambient/util/ambient_util.h"
#include "ash/assistant/assistant_controller.h"
#include "ash/login/ui/lock_screen.h"
#include "ash/public/cpp/ambient/photo_controller.h"
#include "chromeos/constants/chromeos_features.h"
#include "ui/views/widget/widget.h"
namespace ash {
namespace {
bool CanStartAmbientMode() {
return chromeos::features::IsAmbientModeEnabled() && PhotoController::Get() &&
!ambient::util::IsShowing(LockScreen::ScreenType::kLogin);
}
} // namespace
AmbientController::AmbientController(AssistantController* assistant_controller)
: assistant_controller_(assistant_controller) {}
AmbientController::~AmbientController() {
DestroyContainerView();
}
void AmbientController::OnWidgetDestroying(views::Widget* widget) {
refresh_timer_.Stop();
container_view_->GetWidget()->RemoveObserver(this);
container_view_ = nullptr;
// If our widget is being destroyed, Assistant UI is no longer visible.
// If Assistant UI was already closed, this is a no-op.
assistant_controller_->ui_controller()->CloseUi(
AssistantExitPoint::kUnspecified);
}
void AmbientController::Toggle() {
if (container_view_)
Stop();
else
Start();
}
void AmbientController::AddPhotoModelObserver(PhotoModelObserver* observer) {
model_.AddObserver(observer);
}
void AmbientController::RemovePhotoModelObserver(PhotoModelObserver* observer) {
model_.RemoveObserver(observer);
}
void AmbientController::Start() {
if (!CanStartAmbientMode()) {
// TODO(wutao): Show a toast to indicate that Ambient mode is not ready.
return;
}
// CloseUi to ensure standalone Assistant Ui doesn't exist when entering
// Ambient mode to avoid strange behavior caused by standalone Ui was
// only hidden at that time. This will be a no-op if Ui was already closed.
// TODO(meilinw): Handle embedded Ui.
assistant_controller_->ui_controller()->CloseUi(
AssistantExitPoint::kUnspecified);
CreateContainerView();
container_view_->GetWidget()->Show();
RefreshImage();
}
void AmbientController::Stop() {
DestroyContainerView();
}
void AmbientController::CreateContainerView() {
DCHECK(!container_view_);
container_view_ = new AmbientContainerView(this);
container_view_->GetWidget()->AddObserver(this);
}
void AmbientController::DestroyContainerView() {
// |container_view_|'s widget is owned by its native widget. After calling
// CloseNow(), it will trigger |OnWidgetDestroying|, where it will set the
// |container_view_| to nullptr.
if (container_view_)
container_view_->GetWidget()->CloseNow();
}
void AmbientController::RefreshImage() {
if (!PhotoController::Get())
return;
if (model_.ShouldFetchImmediately()) {
// TODO(b/140032139): Defer downloading image if it is animating.
base::SequencedTaskRunnerHandle::Get()->PostDelayedTask(
FROM_HERE,
base::BindOnce(&AmbientController::GetNextImage,
weak_factory_.GetWeakPtr()),
kAnimationDuration);
} else {
model_.ShowNextImage();
ScheduleRefreshImage();
}
}
void AmbientController::ScheduleRefreshImage() {
base::TimeDelta refresh_interval;
if (!model_.ShouldFetchImmediately()) {
// TODO(b/139953713): Change to a correct time interval.
refresh_interval = base::TimeDelta::FromSeconds(5);
}
refresh_timer_.Start(
FROM_HERE, refresh_interval,
base::BindOnce(&AmbientController::RefreshImage, base::Unretained(this)));
}
void AmbientController::GetNextImage() {
PhotoController::Get()->GetNextImage(base::BindOnce(
&AmbientController::OnPhotoDownloaded, weak_factory_.GetWeakPtr()));
}
void AmbientController::OnPhotoDownloaded(const gfx::ImageSkia& image) {
if (!image.isNull())
model_.AddNextImage(image);
ScheduleRefreshImage();
}
} // namespace ash