1*6dbdd20aSAndroid Build Coastguard Worker// Copyright (C) 2024 The Android Open Source Project 2*6dbdd20aSAndroid Build Coastguard Worker// 3*6dbdd20aSAndroid Build Coastguard Worker// Licensed under the Apache License, Version 2.0 (the "License"); 4*6dbdd20aSAndroid Build Coastguard Worker// you may not use this file except in compliance with the License. 5*6dbdd20aSAndroid Build Coastguard Worker// You may obtain a copy of the License at 6*6dbdd20aSAndroid Build Coastguard Worker// 7*6dbdd20aSAndroid Build Coastguard Worker// http://www.apache.org/licenses/LICENSE-2.0 8*6dbdd20aSAndroid Build Coastguard Worker// 9*6dbdd20aSAndroid Build Coastguard Worker// Unless required by applicable law or agreed to in writing, software 10*6dbdd20aSAndroid Build Coastguard Worker// distributed under the License is distributed on an "AS IS" BASIS, 11*6dbdd20aSAndroid Build Coastguard Worker// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12*6dbdd20aSAndroid Build Coastguard Worker// See the License for the specific language governing permissions and 13*6dbdd20aSAndroid Build Coastguard Worker// limitations under the License. 14*6dbdd20aSAndroid Build Coastguard Worker 15*6dbdd20aSAndroid Build Coastguard Workerimport m from 'mithril'; 16*6dbdd20aSAndroid Build Coastguard Workerimport {copyToClipboard} from '../../base/clipboard'; 17*6dbdd20aSAndroid Build Coastguard Workerimport {Icons} from '../../base/semantic_icons'; 18*6dbdd20aSAndroid Build Coastguard Workerimport {exists} from '../../base/utils'; 19*6dbdd20aSAndroid Build Coastguard Workerimport {addEphemeralTab} from '../details/add_ephemeral_tab'; 20*6dbdd20aSAndroid Build Coastguard Workerimport {Upid} from '../sql_utils/core_types'; 21*6dbdd20aSAndroid Build Coastguard Workerimport { 22*6dbdd20aSAndroid Build Coastguard Worker getProcessInfo, 23*6dbdd20aSAndroid Build Coastguard Worker getProcessName, 24*6dbdd20aSAndroid Build Coastguard Worker ProcessInfo, 25*6dbdd20aSAndroid Build Coastguard Worker} from '../sql_utils/process'; 26*6dbdd20aSAndroid Build Coastguard Workerimport {Anchor} from '../../widgets/anchor'; 27*6dbdd20aSAndroid Build Coastguard Workerimport {MenuItem, PopupMenu2} from '../../widgets/menu'; 28*6dbdd20aSAndroid Build Coastguard Workerimport {ProcessDetailsTab} from '../details/process_details_tab'; 29*6dbdd20aSAndroid Build Coastguard Workerimport { 30*6dbdd20aSAndroid Build Coastguard Worker createSqlIdRefRenderer, 31*6dbdd20aSAndroid Build Coastguard Worker sqlIdRegistry, 32*6dbdd20aSAndroid Build Coastguard Worker} from '../widgets/sql/details/sql_ref_renderer_registry'; 33*6dbdd20aSAndroid Build Coastguard Workerimport {asUpid} from '../sql_utils/core_types'; 34*6dbdd20aSAndroid Build Coastguard Workerimport {AppImpl} from '../../core/app_impl'; 35*6dbdd20aSAndroid Build Coastguard Worker 36*6dbdd20aSAndroid Build Coastguard Workerexport function showProcessDetailsMenuItem( 37*6dbdd20aSAndroid Build Coastguard Worker upid: Upid, 38*6dbdd20aSAndroid Build Coastguard Worker pid?: number, 39*6dbdd20aSAndroid Build Coastguard Worker): m.Children { 40*6dbdd20aSAndroid Build Coastguard Worker return m(MenuItem, { 41*6dbdd20aSAndroid Build Coastguard Worker icon: Icons.ExternalLink, 42*6dbdd20aSAndroid Build Coastguard Worker label: 'Show process details', 43*6dbdd20aSAndroid Build Coastguard Worker onclick: () => { 44*6dbdd20aSAndroid Build Coastguard Worker // TODO(primiano): `trace` should be injected, but doing so would require 45*6dbdd20aSAndroid Build Coastguard Worker // an invasive refactoring of most classes in frontend/widgets/sql/*. 46*6dbdd20aSAndroid Build Coastguard Worker const trace = AppImpl.instance.trace; 47*6dbdd20aSAndroid Build Coastguard Worker if (trace === undefined) return; 48*6dbdd20aSAndroid Build Coastguard Worker addEphemeralTab( 49*6dbdd20aSAndroid Build Coastguard Worker 'processDetails', 50*6dbdd20aSAndroid Build Coastguard Worker new ProcessDetailsTab({ 51*6dbdd20aSAndroid Build Coastguard Worker trace, 52*6dbdd20aSAndroid Build Coastguard Worker upid, 53*6dbdd20aSAndroid Build Coastguard Worker pid, 54*6dbdd20aSAndroid Build Coastguard Worker }), 55*6dbdd20aSAndroid Build Coastguard Worker ); 56*6dbdd20aSAndroid Build Coastguard Worker }, 57*6dbdd20aSAndroid Build Coastguard Worker }); 58*6dbdd20aSAndroid Build Coastguard Worker} 59*6dbdd20aSAndroid Build Coastguard Worker 60*6dbdd20aSAndroid Build Coastguard Workerexport function processRefMenuItems(info: { 61*6dbdd20aSAndroid Build Coastguard Worker upid: Upid; 62*6dbdd20aSAndroid Build Coastguard Worker name?: string; 63*6dbdd20aSAndroid Build Coastguard Worker pid?: number; 64*6dbdd20aSAndroid Build Coastguard Worker}): m.Children { 65*6dbdd20aSAndroid Build Coastguard Worker // We capture a copy to be able to pass it across async boundary to `onclick`. 66*6dbdd20aSAndroid Build Coastguard Worker const name = info.name; 67*6dbdd20aSAndroid Build Coastguard Worker return [ 68*6dbdd20aSAndroid Build Coastguard Worker exists(name) && 69*6dbdd20aSAndroid Build Coastguard Worker m(MenuItem, { 70*6dbdd20aSAndroid Build Coastguard Worker icon: Icons.Copy, 71*6dbdd20aSAndroid Build Coastguard Worker label: 'Copy process name', 72*6dbdd20aSAndroid Build Coastguard Worker onclick: () => copyToClipboard(name), 73*6dbdd20aSAndroid Build Coastguard Worker }), 74*6dbdd20aSAndroid Build Coastguard Worker exists(info.pid) && 75*6dbdd20aSAndroid Build Coastguard Worker m(MenuItem, { 76*6dbdd20aSAndroid Build Coastguard Worker icon: Icons.Copy, 77*6dbdd20aSAndroid Build Coastguard Worker label: 'Copy pid', 78*6dbdd20aSAndroid Build Coastguard Worker onclick: () => copyToClipboard(`${info.pid}`), 79*6dbdd20aSAndroid Build Coastguard Worker }), 80*6dbdd20aSAndroid Build Coastguard Worker m(MenuItem, { 81*6dbdd20aSAndroid Build Coastguard Worker icon: Icons.Copy, 82*6dbdd20aSAndroid Build Coastguard Worker label: 'Copy upid', 83*6dbdd20aSAndroid Build Coastguard Worker onclick: () => copyToClipboard(`${info.upid}`), 84*6dbdd20aSAndroid Build Coastguard Worker }), 85*6dbdd20aSAndroid Build Coastguard Worker showProcessDetailsMenuItem(info.upid, info.pid), 86*6dbdd20aSAndroid Build Coastguard Worker ]; 87*6dbdd20aSAndroid Build Coastguard Worker} 88*6dbdd20aSAndroid Build Coastguard Worker 89*6dbdd20aSAndroid Build Coastguard Workerexport function renderProcessRef(info: ProcessInfo): m.Children { 90*6dbdd20aSAndroid Build Coastguard Worker return m( 91*6dbdd20aSAndroid Build Coastguard Worker PopupMenu2, 92*6dbdd20aSAndroid Build Coastguard Worker { 93*6dbdd20aSAndroid Build Coastguard Worker trigger: m(Anchor, getProcessName(info)), 94*6dbdd20aSAndroid Build Coastguard Worker }, 95*6dbdd20aSAndroid Build Coastguard Worker processRefMenuItems(info), 96*6dbdd20aSAndroid Build Coastguard Worker ); 97*6dbdd20aSAndroid Build Coastguard Worker} 98*6dbdd20aSAndroid Build Coastguard Worker 99*6dbdd20aSAndroid Build Coastguard WorkersqlIdRegistry['process'] = createSqlIdRefRenderer<ProcessInfo>( 100*6dbdd20aSAndroid Build Coastguard Worker async (engine, id) => await getProcessInfo(engine, asUpid(Number(id))), 101*6dbdd20aSAndroid Build Coastguard Worker (data: ProcessInfo) => ({ 102*6dbdd20aSAndroid Build Coastguard Worker value: renderProcessRef(data), 103*6dbdd20aSAndroid Build Coastguard Worker }), 104*6dbdd20aSAndroid Build Coastguard Worker); 105