Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
58 commits
Select commit Hold shift + click to select a range
bd33104
ui: migrate analytics and isInternalUser to embedder server
LalitMaganti Feb 18, 2026
7edd151
Merge remote-tracking branch 'origin/main' into dev/lalitm/embedder
LalitMaganti Feb 18, 2026
02b234e
Merge remote-tracking branch 'origin/main' into dev/lalitm/embedder
LalitMaganti Feb 20, 2026
01a3285
Merge remote-tracking branch 'origin/main' into dev/lalitm/embedder
LalitMaganti Feb 20, 2026
d4779b3
Merge remote-tracking branch 'origin/main' into dev/lalitm/embedder
LalitMaganti Feb 23, 2026
d9f23f7
Merge remote-tracking branch 'origin/main' into dev/lalitm/embedder
LalitMaganti Feb 23, 2026
8884f1e
Merge remote-tracking branch 'origin/main' into dev/lalitm/embedder
LalitMaganti Feb 23, 2026
e61f151
Merge remote-tracking branch 'origin/main' into dev/lalitm/embedder
LalitMaganti Feb 26, 2026
4e410f0
Enable by default
LalitMaganti Feb 26, 2026
3a9a928
Merge remote-tracking branch 'origin/main' into dev/lalitm/embedder
LalitMaganti Feb 27, 2026
2d65a4f
Merge remote-tracking branch 'origin/main' into dev/lalitm/embedder
LalitMaganti Mar 12, 2026
0d1cd44
Merge remote-tracking branch 'origin/main' into dev/lalitm/embedder
LalitMaganti Mar 12, 2026
20d51a6
Merge remote-tracking branch 'origin/main' into dev/lalitm/embedder
LalitMaganti Mar 12, 2026
6c620c6
Merge remote-tracking branch 'origin/main' into dev/lalitm/embedder
LalitMaganti Mar 12, 2026
7333ed1
Merge remote-tracking branch 'origin/main' into dev/lalitm/embedder
LalitMaganti Mar 12, 2026
4fe5e58
Merge remote-tracking branch 'origin/main' into dev/lalitm/embedder
LalitMaganti Mar 13, 2026
2e22514
Merge remote-tracking branch 'origin/main' into dev/lalitm/embedder
LalitMaganti Mar 13, 2026
2910a44
Merge remote-tracking branch 'origin/main' into dev/lalitm/embedder
LalitMaganti Mar 16, 2026
7b14f64
Merge remote-tracking branch 'origin/main' into dev/lalitm/embedder
LalitMaganti Mar 16, 2026
b54d7b0
Merge remote-tracking branch 'origin/main' into dev/lalitm/embedder
LalitMaganti Mar 18, 2026
752a94b
Merge remote-tracking branch 'origin/main' into dev/lalitm/embedder
LalitMaganti Mar 18, 2026
a1e04b0
Merge remote-tracking branch 'origin/main' into dev/lalitm/embedder
LalitMaganti Mar 18, 2026
c5017a1
Merge remote-tracking branch 'origin/main' into dev/lalitm/embedder
LalitMaganti Mar 18, 2026
7b3b35c
Merge remote-tracking branch 'origin/main' into dev/lalitm/embedder
LalitMaganti Mar 18, 2026
6d8dae8
Merge remote-tracking branch 'origin/main' into dev/lalitm/embedder
LalitMaganti Mar 18, 2026
5085d08
Merge remote-tracking branch 'origin/main' into dev/lalitm/embedder
LalitMaganti Mar 18, 2026
e663014
Merge remote-tracking branch 'origin/main' into dev/lalitm/embedder
LalitMaganti Mar 18, 2026
6fa7e45
Merge remote-tracking branch 'origin/main' into dev/lalitm/embedder
LalitMaganti Mar 18, 2026
49fa0aa
Merge remote-tracking branch 'origin/main' into dev/lalitm/embedder
LalitMaganti Mar 18, 2026
9101669
Merge remote-tracking branch 'origin/main' into dev/lalitm/embedder
LalitMaganti Mar 19, 2026
411da87
Merge remote-tracking branch 'origin/main' into dev/lalitm/embedder
LalitMaganti Mar 19, 2026
abcff00
Merge remote-tracking branch 'origin/main' into dev/lalitm/embedder
LalitMaganti Mar 19, 2026
2def460
Merge remote-tracking branch 'origin/main' into dev/lalitm/embedder
LalitMaganti Mar 20, 2026
a42602e
Merge remote-tracking branch 'origin/main' into dev/lalitm/embedder
LalitMaganti Mar 23, 2026
9f52f9e
Merge remote-tracking branch 'origin/main' into dev/lalitm/embedder
LalitMaganti Mar 23, 2026
2d0170b
Merge remote-tracking branch 'origin/main' into dev/lalitm/embedder
LalitMaganti Mar 24, 2026
ee87fba
Merge remote-tracking branch 'origin/main' into dev/lalitm/embedder
LalitMaganti Mar 24, 2026
573d1b0
Merge remote-tracking branch 'origin/main' into dev/lalitm/embedder
LalitMaganti Mar 24, 2026
d6bc1d8
Merge remote-tracking branch 'origin/main' into dev/lalitm/embedder
LalitMaganti Mar 24, 2026
e68cb54
Merge remote-tracking branch 'origin/main' into dev/lalitm/embedder
LalitMaganti Mar 24, 2026
48e67b4
Merge remote-tracking branch 'origin/main' into dev/lalitm/embedder
LalitMaganti Mar 25, 2026
ae1eb94
Merge remote-tracking branch 'origin/main' into dev/lalitm/embedder
LalitMaganti Mar 25, 2026
c2388e0
Merge remote-tracking branch 'origin/main' into dev/lalitm/embedder
LalitMaganti Mar 25, 2026
619d5f0
Merge remote-tracking branch 'origin/main' into dev/lalitm/embedder
LalitMaganti Mar 25, 2026
0311d2e
Merge remote-tracking branch 'origin/main' into dev/lalitm/embedder
LalitMaganti Mar 25, 2026
3271d25
Merge remote-tracking branch 'origin/main' into dev/lalitm/embedder
LalitMaganti Mar 25, 2026
2082fcc
Merge remote-tracking branch 'origin/main' into dev/lalitm/embedder
LalitMaganti Mar 26, 2026
e3259d1
Merge remote-tracking branch 'origin/main' into dev/lalitm/embedder
LalitMaganti Mar 26, 2026
b1b5870
Merge remote-tracking branch 'origin/main' into dev/lalitm/embedder
LalitMaganti Mar 26, 2026
fc564b4
Merge remote-tracking branch 'origin/main' into dev/lalitm/embedder
LalitMaganti Mar 27, 2026
728b72b
Merge remote-tracking branch 'origin/main' into dev/lalitm/embedder
LalitMaganti Mar 27, 2026
11d0a58
Merge remote-tracking branch 'origin/main' into dev/lalitm/embedder
LalitMaganti Mar 27, 2026
a76da54
Merge remote-tracking branch 'origin/main' into dev/lalitm/embedder
LalitMaganti Mar 27, 2026
beb39ea
Merge remote-tracking branch 'origin/main' into dev/lalitm/embedder
LalitMaganti Mar 30, 2026
3e67676
Merge remote-tracking branch 'origin/main' into dev/lalitm/embedder
LalitMaganti Mar 30, 2026
024ac89
Merge remote-tracking branch 'origin/main' into dev/lalitm/embedder
LalitMaganti Mar 30, 2026
45c802f
Fix
LalitMaganti Mar 30, 2026
240d1df
Fi
LalitMaganti Mar 30, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 30 additions & 9 deletions ui/src/core/analytics_impl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,10 @@ function getReferrer(): string {

// Interface exposed only to core (for the initialize method).
export interface AnalyticsInternal extends Analytics {
initialize(isInternalUser: boolean): void;
addDimension(
arg: {key: string; value: string} | Promise<{key: string; value: string}>,
): void;
initialize(): Promise<void>;
}

export function initAnalytics(
Expand All @@ -88,7 +91,10 @@ const gtagGlobals = window as {} as {
};

class NullAnalytics implements AnalyticsInternal {
initialize(_: boolean) {}
addDimension(
_arg: {key: string; value: string} | Promise<{key: string; value: string}>,
) {}
async initialize() {}
logEvent(_category: TraceCategories | null, _event: string) {}
logError(_err: ErrorDetails) {}
isEnabled(): boolean {
Expand All @@ -99,6 +105,8 @@ class NullAnalytics implements AnalyticsInternal {
class AnalyticsImpl implements AnalyticsInternal {
private initialized_ = false;
private readonly analyticsId: string;
private readonly dimensions: Array<Promise<{key: string; value: string}>> =
[];

constructor(analyticsId: string) {
this.analyticsId = analyticsId;
Expand All @@ -121,10 +129,18 @@ class AnalyticsImpl implements AnalyticsInternal {
gtagGlobals.gtag('js', new Date());
}

// This is callled only after the script that sets isInternalUser loads.
addDimension(
arg: {key: string; value: string} | Promise<{key: string; value: string}>,
) {
if (this.initialized_) {
throw new Error('Cannot add analytics dimensions after initialization');
}
this.dimensions.push(Promise.resolve(arg));
}

// It is fine to call updatePath() and log*() functions before initialize().
// The gtag() function internally enqueues all requests into |dataLayer|.
initialize(isInternalUser: boolean) {
async initialize() {
if (this.initialized_) return;
this.initialized_ = true;
const script = document.createElement('script');
Expand All @@ -133,10 +149,15 @@ class AnalyticsImpl implements AnalyticsInternal {
script.defer = true;
document.head.appendChild(script);
const route = window.location.href;
console.log(
`GA initialized. route=${route}`,
`isInternalUser=${isInternalUser}`,
);

// Await all dimension promises and build a map of extra dimensions.
const resolvedDimensions = await Promise.all(this.dimensions);
const extraDimensions: Record<string, string> = {};
for (const {key, value} of resolvedDimensions) {
extraDimensions[key] = value;
}

console.log(`GA initialized. route=${route}`);
// GA's recommendation for SPAs is to disable automatic page views and
// manually send page_view events. See:
// https://developers.google.com/analytics/devguides/collection/gtagjs/pages#manual_pageviews
Expand All @@ -148,12 +169,12 @@ class AnalyticsImpl implements AnalyticsInternal {
page_referrer: getReferrer(),
send_page_view: false,
page_title: PAGE_TITLE,
perfetto_is_internal_user: isInternalUser ? '1' : '0',
perfetto_version: VERSION,
// Release channel (canary, stable, autopush)
perfetto_channel: getCurrentChannel(),
// Referrer *if overridden* via the query string else empty string.
perfetto_referrer_override: getReferrerOverride() ?? '',
...extraDimensions,
});

gtagGlobals.gtag('event', 'page_view', {
Expand Down
10 changes: 6 additions & 4 deletions ui/src/core/app_impl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -185,10 +185,12 @@ export class AppImpl implements App {
return this._isInternalUser;
}

set isInternalUser(value: boolean) {
localStorage.setItem('isInternalUser', value ? '1' : '0');
this._isInternalUser = value;
raf.scheduleFullRedraw();
setIsInternalUser(promise: Promise<boolean>) {
promise.then((value) => {
this._isInternalUser = value;
localStorage.setItem('isInternalUser', value ? '1' : '0');
raf.scheduleFullRedraw();
});
}

get trace(): TraceImpl | undefined {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,11 @@ class AddExtensionServerModal {
);
private userInput: UserInput;
private loadedState?: LoadedState;
private readonly locked: boolean;
private readonly isEmbedderManaged: boolean;

constructor(server?: ExtensionServer, prefill?: ExtensionServer) {
this.userInput = createInitial(server ?? prefill);
this.locked = server?.locked ?? false;
this.isEmbedderManaged = server?.origin === 'embedder_managed';
this.scheduleManifestFetch(
server?.enabledModules ?? prefill?.enabledModules,
);
Expand Down Expand Up @@ -97,7 +97,7 @@ class AddExtensionServerModal {
enabledModules,
enabled: true,
auth: this.userInput.auth,
locked: this.locked,
origin: this.isEmbedderManaged ? 'embedder_managed' : 'user_added',
};
}
return {
Expand All @@ -106,7 +106,7 @@ class AddExtensionServerModal {
enabledModules,
enabled: true,
auth: this.userInput.auth,
locked: this.locked,
origin: this.isEmbedderManaged ? 'embedder_managed' : 'user_added',
};
}

Expand All @@ -128,7 +128,7 @@ class AddExtensionServerModal {
{label: 'HTTPS', icon: 'public'},
],
selectedOption: this.userInput.type === 'github' ? 0 : 1,
disabled: this.locked,
disabled: this.isEmbedderManaged,
onOptionSelected: (idx: number) => {
if (idx === 0 && this.userInput.type !== 'github') {
this.userInput = {
Expand All @@ -153,7 +153,7 @@ class AddExtensionServerModal {
m(TextInput, {
placeholder: 'owner/repo (e.g., perfetto-dev/extension-server-test)',
value: input.repo,
disabled: this.locked,
disabled: this.isEmbedderManaged,
onInput: (value: string) => {
input.repo = value;
this.debouncedFetch();
Expand All @@ -163,7 +163,7 @@ class AddExtensionServerModal {
m(TextInput, {
placeholder: 'e.g., main',
value: input.ref,
disabled: this.locked,
disabled: this.isEmbedderManaged,
onInput: (value: string) => {
input.ref = value;
this.debouncedFetch();
Expand All @@ -173,7 +173,7 @@ class AddExtensionServerModal {
m(TextInput, {
placeholder: '(default: /)',
value: input.path,
disabled: this.locked,
disabled: this.isEmbedderManaged,
onInput: (value: string) => {
input.path = value;
this.debouncedFetch();
Expand Down Expand Up @@ -209,7 +209,7 @@ class AddExtensionServerModal {
Select,
{
value: input.auth.type,
disabled: this.locked,
disabled: this.isEmbedderManaged,
onchange: (e: Event) => {
const value = (e.target as HTMLSelectElement).value;
input.auth =
Expand All @@ -227,7 +227,7 @@ class AddExtensionServerModal {
placeholder: 'github_pat_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
type: 'password',
value: input.auth.pat,
disabled: this.locked,
disabled: this.isEmbedderManaged,
onInput: (value: string) => {
input.auth = {type: 'github_pat', pat: value};
this.debouncedFetch();
Expand All @@ -242,7 +242,7 @@ class AddExtensionServerModal {
m(TextInput, {
placeholder: 'https://example.com/path/to/extensions',
value: input.url,
disabled: this.locked,
disabled: this.isEmbedderManaged,
onInput: (value: string) => {
input.url = value;
this.debouncedFetch();
Expand Down Expand Up @@ -284,7 +284,7 @@ class AddExtensionServerModal {
Select,
{
value: input.auth.type,
disabled: this.locked,
disabled: this.isEmbedderManaged,
onchange: (e: Event) => {
const value = (e.target as HTMLSelectElement).value;
if (value === 'https_basic') {
Expand Down Expand Up @@ -321,7 +321,7 @@ class AddExtensionServerModal {
m(TextInput, {
placeholder: 'Username',
value: auth.username,
disabled: this.locked,
disabled: this.isEmbedderManaged,
onInput: (value: string) => {
input.auth = {...auth, username: value};
this.debouncedFetch();
Expand All @@ -331,7 +331,7 @@ class AddExtensionServerModal {
placeholder: 'Password',
type: 'password',
value: auth.password,
disabled: this.locked,
disabled: this.isEmbedderManaged,
onInput: (value: string) => {
input.auth = {...auth, password: value};
this.debouncedFetch();
Expand Down Expand Up @@ -373,7 +373,7 @@ class AddExtensionServerModal {
Select,
{
value: auth.keyType,
disabled: this.locked,
disabled: this.isEmbedderManaged,
onchange: (e: Event) => {
const keyType = (e.target as HTMLSelectElement).value as
| 'bearer'
Expand All @@ -395,7 +395,7 @@ class AddExtensionServerModal {
m(TextInput, {
placeholder: 'Header name',
value: auth.customHeaderName,
disabled: this.locked,
disabled: this.isEmbedderManaged,
onInput: (value: string) => {
input.auth = {...auth, customHeaderName: value};
this.debouncedFetch();
Expand All @@ -405,7 +405,7 @@ class AddExtensionServerModal {
placeholder: 'API key',
type: 'password',
value: auth.key,
disabled: this.locked,
disabled: this.isEmbedderManaged,
onInput: (value: string) => {
input.auth = {...auth, key: value};
this.debouncedFetch();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ function testExtServer(
enabledModules: overrides.enabledModules ?? ['default'],
enabled: overrides.enabled ?? true,
auth: {type: 'none'},
locked: false,
origin: 'user_added',
};
}

Expand Down
Loading