1/* 2 * Copyright (c) 2024 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16const pip = requireNapi('pip'); 17const NodeController = requireNapi('arkui.node').NodeController; 18const FrameNode = requireNapi('arkui.node').FrameNode; 19 20const TAG = 'PiPContent'; 21const ABOUT_TO_STOP = 3; 22 23class XCNodeController extends NodeController { 24 constructor(m2) { 25 super(); 26 this.node = null; 27 this.mXComponent = m2; 28 } 29 makeNode(l2) { 30 this.node = new FrameNode(l2); 31 this.node.appendChild(this.mXComponent); 32 return this.node; 33 } 34 replaceNode(k) { 35 this.node?.removeChild(this.mXComponent); 36 this.mXComponent = k; 37 this.node?.appendChild(this.mXComponent); 38 } 39 removeNode() { 40 this.node?.removeChild(this.mXComponent); 41 } 42} 43 44class PiPContent extends ViewPU { 45 constructor(f2, g2, h2, i2 = -1, j2 = undefined, k2) { 46 super(f2, h2, i2, k2); 47 if (typeof f2 === 'function') { 48 this.paramsGenerator_ = j2; 49 } 50 this.xComponentController = new XComponentController(); 51 this.nodeController = null; 52 this.mXCNodeController = null; 53 this.__useNode = new ObservedPropertySimplePU(false, this, 'useNode'); 54 this.__nodeChange = new ObservedPropertySimplePU(false, this, 'nodeChange'); 55 this.xComponent = null; 56 this.xComponentId = 'pipContent'; 57 this.xComponentType = 'surface'; 58 this.setInitiallyProvidedValue(g2); 59 } 60 setInitiallyProvidedValue(e2) { 61 if (e2.xComponentController !== undefined) { 62 this.xComponentController = e2.xComponentController; 63 } 64 if (e2.nodeController !== undefined) { 65 this.nodeController = e2.nodeController; 66 } 67 if (e2.mXCNodeController !== undefined) { 68 this.mXCNodeController = e2.mXCNodeController; 69 } 70 if (e2.useNode !== undefined) { 71 this.useNode = e2.useNode; 72 } 73 if (e2.nodeChange !== undefined) { 74 this.nodeChange = e2.nodeChange; 75 } 76 if (e2.xComponent !== undefined) { 77 this.xComponent = e2.xComponent; 78 } 79 if (e2.xComponentId !== undefined) { 80 this.xComponentId = e2.xComponentId; 81 } 82 if (e2.xComponentType !== undefined) { 83 this.xComponentType = e2.xComponentType; 84 } 85 } 86 updateStateVars(d2) { 87 } 88 purgeVariableDependenciesOnElmtId(c2) { 89 this.__useNode.purgeDependencyOnElmtId(c2); 90 this.__nodeChange.purgeDependencyOnElmtId(c2); 91 } 92 aboutToBeDeleted() { 93 this.__useNode.aboutToBeDeleted(); 94 this.__nodeChange.aboutToBeDeleted(); 95 SubscriberManager.Get().delete(this.id__()); 96 this.aboutToBeDeletedInternal(); 97 } 98 get useNode() { 99 return this.__useNode.get(); 100 } 101 set useNode(j) { 102 this.__useNode.set(j); 103 } 104 get nodeChange() { 105 return this.__nodeChange.get(); 106 } 107 set nodeChange(i) { 108 this.__nodeChange.set(i); 109 } 110 validateNode(g) { 111 if (g === null || g === undefined) { 112 console.error(TAG, `validateNode node is null`); 113 return false; 114 } 115 let h = g.getNodeType(); 116 if (h !== 'XComponent') { 117 console.error(TAG, `node type mismatch: ${h}`); 118 return false; 119 } 120 return true; 121 } 122 registerUpdateNodeListener() { 123 pip.on('nodeUpdate', (f) => { 124 console.info(TAG, `nodeUpdate`); 125 if (!this.validateNode(f)) { 126 return; 127 } 128 if (this.useNode) { 129 pip.setPipNodeType(this.xComponent, false); 130 this.updatePipNodeType(f); 131 this.mXCNodeController?.replaceNode(f); 132 this.nodeChange = true; 133 } 134 else { 135 this.updatePipNodeType(f); 136 this.mXCNodeController = new XCNodeController(f); 137 console.info(TAG, 'update to Node Controller'); 138 this.registerStateChangeListener(); 139 this.useNode = true; 140 } 141 }); 142 } 143 updatePipNodeType(c) { 144 let d = c.getParent(); 145 if (d === null || d === undefined) { 146 pip.setPipNodeType(c, false); 147 } 148 else { 149 pip.setPipNodeType(c, true); 150 d.removeChild(c); 151 } 152 } 153 registerStateChangeListener() { 154 pip.on('stateChange', (b) => { 155 console.info(TAG, `stateChange state:${b}`); 156 if (b === ABOUT_TO_STOP) { 157 this.mXCNodeController?.removeNode(); 158 } 159 }); 160 } 161 aboutToAppear() { 162 this.nodeController = pip.getCustomUIController(); 163 this.registerUpdateNodeListener(); 164 this.xComponent = pip.getTypeNode(); 165 if (!this.validateNode(this.xComponent)) { 166 return; 167 } 168 if (this.xComponent === null) { 169 console.error(TAG, `validateNode node is null`); 170 return; 171 } 172 this.useNode = true; 173 this.updatePipNodeType(this.xComponent); 174 pip.setTypeNodeEnabled(); 175 this.mXCNodeController = new XCNodeController(this.xComponent); 176 console.info(TAG, 'use Node Controller'); 177 this.registerStateChangeListener(); 178 } 179 180 updatePipNodeType(a2) { 181 let b2 = a2.getParent(); 182 if (b2 === null || b2 === undefined) { 183 pip.setPipNodeType(a2, false); 184 } else { 185 pip.setPipNodeType(a2, true); 186 b2.removeChild(a2); 187 } 188 } 189 190 191 aboutToDisappear() { 192 pip.off('stateChange'); 193 pip.off('nodeUpdate'); 194 } 195 196 initialRender() { 197 this.observeComponentCreation2((s1, t1) => { 198 Stack.create(); 199 Stack.size({ width: '100%', height: '100%' }); 200 }, Stack); 201 this.observeComponentCreation2((h1, i1) => { 202 If.create(); 203 if (this.useNode || this.nodeChange) { 204 this.ifElseBranchUpdateFunction(0, () => { 205 this.buildNode.bind(this)(); 206 }); 207 } else { 208 this.ifElseBranchUpdateFunction(1, () => { 209 this.buildXComponent.bind(this)(); 210 }); 211 } 212 }, If); 213 If.pop(); 214 this.observeComponentCreation2((a1, b1) => { 215 If.create(); 216 if (this.nodeController !== null) { 217 this.ifElseBranchUpdateFunction(0, () => { 218 this.buildCustomUI.bind(this)(); 219 }); 220 } else { 221 this.ifElseBranchUpdateFunction(1, () => { 222 }); 223 } 224 }, If); 225 If.pop(); 226 Stack.pop(); 227 } 228 229 buildCustomUI(g1 = null) { 230 this.observeComponentCreation2((i1, j1) => { 231 NodeContainer.create(this.nodeController); 232 NodeContainer.size({ width: '100%', height: '100%'}); 233 }, NodeContainer); 234 } 235 236 buildXComponent(b1 = null) { 237 this.observeComponentCreation2((d1, e1) => { 238 XComponent.create({ 239 id: this.xComponentId, 240 type: this.xComponentType, 241 controller: this.xComponentController 242 }, 'pipContent_XComponent'); 243 XComponent.onLoad((() => { 244 pip.initXComponentController(this.xComponentController); 245 console.info(TAG, 'XComponent onLoad done'); 246 })); 247 XComponent.size({ width: '100%', height: '100%' }); 248 XComponent.backgroundColor(Color.Transparent); 249 }, XComponent); 250 } 251 252 buildNode(x = null) { 253 this.observeComponentCreation2((z, a1) => { 254 NodeContainer.create(this.mXCNodeController); 255 NodeContainer.size({ width: '100%', height: '100%' }); 256 }, NodeContainer); 257 } 258 259 rerender() { 260 this.updateDirtyElements(); 261 } 262 263 static getEntryName() { 264 return 'PiPContent'; 265 } 266} 267 268ViewStackProcessor.StartGetAccessRecordingFor(ViewStackProcessor.AllocateNewElmetIdForNextComponent()); 269loadDocument(new PiPContent(void 0, {})); 270ViewStackProcessor.StopGetAccessRecording();