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 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158
|
// Copyright 2024 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chromeos/ash/components/growth/campaigns_utils.h"
#include <algorithm>
#include <map>
#include <string>
#include <string_view>
#include "base/containers/fixed_flat_map.h"
#include "base/notreached.h"
#include "base/strings/cstring_view.h"
#include "base/strings/strcat.h"
#include "base/strings/stringprintf.h"
#include "chromeos/ash/components/growth/campaigns_constants.h"
#include "url/gurl.h"
namespace growth {
namespace {
// NOTE: Do not change the number.
// The number of `campaign_id`s can be stored in the sparse histograms.
constexpr int kCampaignsCountPerHistogram = 500;
// The mapping of `app_id` or URL `domain` to `app_group_id`.
const auto& GetAppGroupIdMap() {
// TODO: b/341721256 - Get the app ids from their constants files.
// PWA:
static constexpr char kGoogleDocsAppIdPwa[] =
"mpnpojknpmmopombnjdcgaaiekajbnjb";
static constexpr char kGoogleDriveAppIdPwa[] =
"aghbiahbpaijignceidepookljebhfak";
static constexpr char kGmailAppIdPwa[] = "fmgjjmmmlfnkbppncabfkddbjimcfncm";
static constexpr char kGooglePhotosAppIdPwa[] =
"ncmjhecbjeaamljdfahankockkkdmedg";
// ARC:
static constexpr char kGoogleDocsAppIdArc[] =
"cgiadblnmjkjbhignimpegeiplgoidhe";
static constexpr char kGoogleDriveAppIdArc[] =
"ljmhbofhbaapdhebeafbhlcapoiipfbi";
static constexpr char kGmailAppIdArc[] = "hhkfkjpmacfncmbapfohfocpjpdnobjg";
static constexpr char kGooglePhotosAppIdArc[] =
"fdbkkojdbojonckghlanfaopfakedeca";
// Domain name:
static constexpr char kGoogleDocsAppDomain[] = "docs.google.com";
static constexpr char kGoogleDriveAppDomain[] = "drive.google.com";
static constexpr char kGmailAppDomain[] = "mail.google.com";
static constexpr char kGooglePhotosAppDomain[] = "photos.google.com";
// A list of supported apps group events.
// NOTE: An app can be grouped in multiple groups.
static constexpr char kGoogleDocsOpenedEvent[] = "DocsOpened";
static constexpr char kGoogleDriveOpenedEvent[] = "DriveOpened";
static constexpr char kGmailOpenedEvent[] = "GmailOpened";
static constexpr char kGooglePhotosOpenedEvent[] = "PhotosOpened";
static constexpr auto kAppGroupIdMap =
base::MakeFixedFlatMap<std::string_view, std::string_view>({
// Docs:
{kGoogleDocsAppIdPwa, kGoogleDocsOpenedEvent},
{kGoogleDocsAppIdArc, kGoogleDocsOpenedEvent},
{kGoogleDocsAppDomain, kGoogleDocsOpenedEvent},
// Drive:
{kGoogleDriveAppIdPwa, kGoogleDriveOpenedEvent},
{kGoogleDriveAppIdArc, kGoogleDriveOpenedEvent},
{kGoogleDriveAppDomain, kGoogleDriveOpenedEvent},
// Gmail:
{kGmailAppIdPwa, kGmailOpenedEvent},
{kGmailAppIdArc, kGmailOpenedEvent},
{kGmailAppDomain, kGmailOpenedEvent},
// Photos:
{kGooglePhotosAppIdPwa, kGooglePhotosOpenedEvent},
{kGooglePhotosAppIdArc, kGooglePhotosOpenedEvent},
{kGooglePhotosAppDomain, kGooglePhotosOpenedEvent},
});
return kAppGroupIdMap;
}
} // namespace
std::string_view GetGrowthCampaignsEventNamePrefix() {
// Only event name with this prefix can be processed by the Feature Engagement
// framework.
return "ChromeOSAshGrowthCampaigns_";
}
std::string GetEventName(CampaignEvent event, std::string_view id) {
switch (event) {
case CampaignEvent::kImpression:
return base::StrCat({"Campaign", id, "_Impression"});
case CampaignEvent::kDismissed:
return base::StrCat({"Campaign", id, "_Dismissed"});
case CampaignEvent::kAppOpened:
// TODO: b/342282901 - Migrate `CampaignEvent::kAppOpened` to
// `CampaignEvent::kEvent`, which can be used instead for similar case.
return base::StrCat({"AppOpened_AppId_", id});
case CampaignEvent::kEvent:
return base::StrCat({"Event_", id});
case CampaignEvent::kGroupImpression:
return base::StrCat({"Group", id, "_Impression"});
case CampaignEvent::kGroupDismissed:
return base::StrCat({"Group", id, "_Dismissed"});
}
NOTREACHED();
}
std::string_view GetAppGroupId(std::string_view app_id) {
const auto& map = GetAppGroupIdMap();
const auto it = map.find(app_id);
return (it == map.end()) ? std::string_view() : it->second;
}
std::string_view GetAppGroupId(const GURL& url) {
const auto& map = GetAppGroupIdMap();
const auto it = std::ranges::find_if(
map, [&](const auto& elem) { return url.DomainIs(elem.first); });
return (it == map.end()) ? std::string_view() : it->second;
}
std::map<std::string, std::string> CreateBasicConditionParams() {
std::map<std::string, std::string> conditions_params;
// `event_used` and `event_trigger` are required for feature_engagement
// config, although they are not used in campaign matching.
static constexpr char kTemplate[] =
"name:ChromeOSAshGrowthCampaigns_Event%s;comparator:any;window:1;storage:"
"1";
conditions_params["event_used"] = base::StringPrintf(kTemplate, "Used");
conditions_params["event_trigger"] = base::StringPrintf(kTemplate, "Trigger");
return conditions_params;
}
std::string CreateConditionParamForCap(base::cstring_view campaign_type,
int id,
base::cstring_view event_type,
int cap) {
return base::StringPrintf(
"name:ChromeOSAshGrowthCampaigns_%s%d_%s;comparator:<%d;window:3650;"
"storage:3650",
campaign_type.c_str(), id, event_type.c_str(), cap);
}
int GetHistogramMaxCampaignId(int campaign_id) {
// `campaign_id` starts at 0.
return (campaign_id / kCampaignsCountPerHistogram + 1) *
kCampaignsCountPerHistogram;
}
std::string ToString(bool value) {
return value ? "true" : "false";
}
} // namespace growth
|