blob: 09f64581a52ca6c15f30fde27cdf51d6e6c506bf [file]
// Copyright (C) 2026 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import {z} from 'zod';
import {FLAMEGRAPH_STATE_SCHEMA} from '../../widgets/flamegraph';
// Schema for the slice of Heap Dump Explorer state that survives in a shared
// permalink. The session writes this on every state change via mountStore;
// the core serializes it into the permalink and restores it before the plugin
// loads (see core/state_serialization.ts).
//
// Timestamps are heap dump `ts` values (bigint) and are stored as decimal
// strings because JSON has no bigint.
const DUMP_REF_SCHEMA = z.object({
upid: z.number(),
ts: z.string(),
});
// A flamegraph tab always belongs to the active dump (tabs reset on dump
// switch), so the dump is taken from activeDump rather than stored per tab.
const FLAMEGRAPH_TAB_SCHEMA = z.object({
pathHashes: z.string(),
isDominator: z.boolean(),
});
const INSTANCE_TAB_SCHEMA = z.object({
objId: z.number(),
label: z.string(),
});
export const HDE_STATE_SCHEMA = z
.object({
// The selected heap dump; identifies which dump the rest of the state
// belongs to. Restore is skipped if it no longer matches a loaded dump.
activeDump: DUMP_REF_SCHEMA.optional(),
// The active navigation, as a stateToSubpage subpage string.
nav: z.string().optional(),
// Open "Flamegraph objects" drill-down tabs. The active one is not stored;
// it is re-derived from nav (which encodes the tab's pathHashes) on restore.
flamegraphTabs: z.array(FLAMEGRAPH_TAB_SCHEMA).optional(),
// Open object/instance inspector tabs. The active one is not stored; it is
// re-derived from nav (which encodes the object id) on restore.
instanceTabs: z.array(INSTANCE_TAB_SCHEMA).optional(),
// Filter / pivot / view state of the main Flamegraph tab.
flamegraphPanelState: FLAMEGRAPH_STATE_SCHEMA.optional(),
})
.readonly();
export type HdeState = z.infer<typeof HDE_STATE_SCHEMA>;
// An unparseable or older permalink falls back to empty state rather than
// throwing.
export function migrateHdeState(init: unknown): HdeState {
return HDE_STATE_SCHEMA.safeParse(init).data ?? {};
}