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 139 140 141 142 143
|
// 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.
#ifndef COMPONENTS_FEED_CORE_V2_SURFACE_UPDATER_H_
#define COMPONENTS_FEED_CORE_V2_SURFACE_UPDATER_H_
#include <map>
#include <string>
#include <vector>
#include "base/containers/flat_set.h"
#include "base/memory/raw_ptr.h"
#include "components/feed/core/proto/v2/ui.pb.h"
#include "components/feed/core/proto/v2/wire/reliability_logging_enums.pb.h"
#include "components/feed/core/v2/enums.h"
#include "components/feed/core/v2/launch_reliability_logger.h"
#include "components/feed/core/v2/stream_model.h"
#include "components/feed/core/v2/stream_surface_set.h"
#include "components/feed/core/v2/types.h"
#include "components/feed/core/v2/xsurface_datastore.h"
namespace feedui {
class StreamUpdate;
} // namespace feedui
namespace feed {
class SurfaceRenderer;
class MetricsReporter;
// Keeps the UI up to date by calling |FeedStreamSurface::StreamUpdate()|.
// Updates are triggered when |StreamModel| changes, or when loading state
// changes (for spinners and zero-state).
class SurfaceUpdater : public StreamModel::Observer,
public StreamSurfaceSet::Observer,
public XsurfaceDatastoreDataReader::Observer {
public:
explicit SurfaceUpdater(MetricsReporter* metrics_reporter,
XsurfaceDatastoreDataReader* global_datastore_slice,
StreamSurfaceSet* surfaces);
~SurfaceUpdater() override;
SurfaceUpdater(const SurfaceUpdater&) = delete;
SurfaceUpdater& operator=(const SurfaceUpdater&) = delete;
// Sets or unsets the model. When |model| is non-null, triggers the population
// of surfaces. When |model| is null, this does not send any updates to
// surfaces, so they will keep any content they may have been displaying
// before. We don't send a zero-state in this case, since we might want to
// immediately trigger a load.
void SetModel(StreamModel* model);
// StreamModel::Observer.
void OnUiUpdate(const StreamModel::UiUpdate& update) override;
// StreamSurfaceSet::Observer.
void SurfaceAdded(
SurfaceId surface_id,
SurfaceRenderer* renderer,
feedwire::DiscoverLaunchResult loading_not_allowed_reason) override;
void SurfaceRemoved(SurfaceId surface_id) override;
// XsurfaceDatastoreDataReader::Observer.
void DatastoreEntryUpdated(XsurfaceDatastoreDataReader* source,
const std::string& key) override;
void DatastoreEntryRemoved(XsurfaceDatastoreDataReader* source,
const std::string& key) override;
// Called to indicate the initial model load is in progress.
void LoadStreamStarted(bool manual_refreshing);
void LoadStreamComplete(bool success,
LoadStreamStatus load_stream_status,
feedwire::DiscoverLaunchResult launch_result);
// Called to indicate whether or not we are currently trying to load more
// content at the bottom of the stream.
void SetLoadingMore(bool is_loading);
// Returns the 0-based index of the slice in the stream, or -1 if the slice is
// not found. Ignores all non-content slices.
int GetSliceIndexFromSliceId(const std::string& slice_id);
void SetOfflinePageAvailability(const std::string& badge_id,
bool available_offline);
LaunchReliabilityLogger& launch_reliability_logger() {
return launch_reliability_logger_;
}
// State that together with |model_| determines what should be sent to a
// surface. |DrawState| is usually the same for all surfaces, except for the
// moment when a surface is first attached.
struct DrawState {
bool loading_more = false;
bool loading_initial = false;
feedui::ZeroStateSlice::Type zero_state_type =
feedui::ZeroStateSlice::UNKNOWN;
bool operator==(const DrawState& rhs) const;
};
private:
DrawState GetState() const;
bool ShouldSendStreamUpdate() const;
void SendStreamUpdateIfNeeded();
void SendStreamUpdate(
const std::vector<std::string>& updated_shared_state_ids);
void SendUpdateToSurface(SurfaceId surface_id,
SurfaceRenderer* surface,
const feedui::StreamUpdate& update);
void InsertDatastoreEntry(const std::string& key, const std::string& value);
void RemoveDatastoreEntry(const std::string& key);
// Owned by |FeedStream|.
raw_ptr<MetricsReporter> metrics_reporter_;
raw_ptr<StreamSurfaceSet> surfaces_;
// Per-StreamType xsurface data.
XsurfaceDatastoreSlice surface_data_slice_;
// Combines `surface_data_slice_`, and the global data.
XsurfaceDatastoreAggregate aggregate_data_;
// Members that affect what is sent to surfaces. A value change of these may
// require sending an update to surfaces.
bool loading_more_ = false;
bool loading_initial_ = false;
bool load_stream_failed_ = false;
LoadStreamStatus load_stream_status_ = LoadStreamStatus::kNoStatus;
// The |DrawState| when the last update was sent to all surfaces.
DrawState last_draw_state_;
// The set of content that has been sent to all attached surfaces.
base::flat_set<ContentRevision> sent_content_;
// Owned by |FeedStream|. Null when the model is not loaded.
raw_ptr<StreamModel, DanglingUntriaged> model_ = nullptr;
LaunchReliabilityLogger launch_reliability_logger_;
bool load_stream_started_ = false;
int current_load_more_indicator_id_ = 0;
};
} // namespace feed
#endif // COMPONENTS_FEED_CORE_V2_SURFACE_UPDATER_H_
|