1/* 2 * Copyright (c) 2025 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 16/** 17 * @file 18 * @kit ArkData 19 */ 20 21import hilog from '@ohos.hilog' 22import { BusinessError } from '@ohos.base' 23import type { AsyncCallback } from '@ohos.base' 24import Context from 'application.Context' 25import DataShareResultSet from '@ohos.data.DataShareResultSet' 26import dataSharePredicates from '@ohos.data.dataSharePredicates' 27import { ValuesBucket } from '@ohos.data.ValuesBucket' 28 29export namespace dataShare { 30 loadLibrary("datashare_ani") 31 32 export interface DataShareHelperOptions { 33 isProxy?: boolean; 34 } 35 36 enum ChangeType { 37 INSERT = 0, 38 DELETE, 39 UPDATE 40 } 41 42 export enum SubscriptionType { 43 SUBSCRIPTION_TYPE_EXACT_URI = 0, 44 } 45 46 export interface ChangeInfo { 47 type: ChangeType 48 uri: string 49 values: Array<ValuesBucket> 50 } 51 52 export interface DataShareHelper { 53 on(type: 'dataChange', uri: string, callback: AsyncCallback<void>): void 54 off(type: 'dataChange', uri: string, callback?: AsyncCallback<void>): void 55 on(event: 'dataChange', type: SubscriptionType, uri: string, callback: AsyncCallback<ChangeInfo>): void 56 off(event: 'dataChange', type: SubscriptionType, uri: string, callback?: AsyncCallback<ChangeInfo>): void 57 query(uri: string, predicates: dataSharePredicates.DataSharePredicates, columns: Array<string>, callback: AsyncCallback<DataShareResultSet>): void 58 query(uri: string, predicates: dataSharePredicates.DataSharePredicates, columns: Array<string>): Promise<DataShareResultSet> 59 update(uri: string, predicates: dataSharePredicates.DataSharePredicates, value: ValuesBucket, callback: AsyncCallback<number>): void 60 update(uri: string, predicates: dataSharePredicates.DataSharePredicates, value: ValuesBucket): Promise<number> 61 } 62 63 export native function create(context: Context, uri: string, options?: DataShareHelperOptions): DataShareHelper 64 65 export function createDataShareHelper(context: Context, uri: string, callback: AsyncCallback<DataShareHelper>): void { 66 let p = taskpool.execute(create, context, uri, undefined) 67 p.then((e: NullishType) => { 68 let r = e as DataShareHelper 69 let err: BusinessError<void> 70 callback(err, r) 71 }).catch((error: NullishType) => { 72 let r = new DataShareHelperInner(0) 73 let err = error as BusinessError<void> 74 hilog.error(0x0000, 'DataShareHelper', "create failed:" + err) 75 callback(err, r) 76 }) 77 } 78 79 export function createDataShareHelper(context: Context, uri: string, options: DataShareHelperOptions, callback: AsyncCallback<DataShareHelper>): void { 80 let p = taskpool.execute(create, context, uri, options) 81 p.then((e: NullishType) => { 82 let r = e as DataShareHelper 83 let err: BusinessError<void> 84 callback(err, r) 85 }).catch((error: NullishType) => { 86 let r = new DataShareHelperInner(0) 87 let err = error as BusinessError<void> 88 hilog.error(0x0000, 'DataShareHelper', "create failed:" + err) 89 callback(err, r) 90 }) 91 } 92 93 export function createDataShareHelper(context: Context, uri: string, options?: DataShareHelperOptions): Promise<DataShareHelper> { 94 console.println("createDataShareHelper enter") 95 return new Promise<DataShareHelper>((resolve: (v: DataShareHelper) => void, reject: (error: Error) => void) => { 96 let p = taskpool.execute(create, context, uri, options) 97 p.then((e: NullishType) => { 98 let r = e as DataShareHelper 99 resolve(r) 100 }).catch((e: Error): void => { 101 hilog.error(0x0000, 'DataShareHelper', "create failed:" + e) 102 reject(e) 103 }) 104 }) 105 } 106 107 class ChangeInfoInner implements ChangeInfo { 108 type: ChangeType 109 uri: string 110 values: Array<ValuesBucket> 111 } 112 113 class Cleaner { 114 static callback(cleaner: Cleaner): void { 115 console.println("enter Cleaner.callback"); 116 cleaner.clean() 117 } 118 119 constructor(targetPtr: long) { 120 this.targetPtr = targetPtr 121 } 122 123 native clean(): void 124 125 private targetPtr: long = 0 126 } 127 128 class FinalizationAgent<T extends Object> { 129 constructor(obj: T, ptr: long) { 130 this.register(obj, ptr); 131 } 132 133 register(obj: T, ptr: long): void { 134 this.unregisterToken = {}; 135 this.cleaner = new Cleaner(ptr); 136 finalizer.register(obj, this.cleaner!, this.unregisterToken); 137 } 138 139 unregister(): void { 140 finalizer.unregister(this.unregisterToken); 141 } 142 143 private cleaner: Cleaner | null = null; 144 private unregisterToken: object; 145 } 146 147 let finalizer = new FinalizationRegistry<Cleaner>(Cleaner.callback) 148 149 class DataShareHelperInner implements DataShareHelper { 150 private nativePtr: long = 0 151 private fzAgent: FinalizationAgent<DataShareHelperInner>; 152 private onCallback: AsyncCallback<void> = () => {} 153 private offCallback?: AsyncCallback<void> 154 private onEventCallback: AsyncCallback<ChangeInfo> = () => {} 155 private offEventCallback?: AsyncCallback<ChangeInfo> 156 157 constructor(nativePtr:long) { 158 hilog.info(0x0000, 'DataShareHelper', "in constructor, context :" + nativePtr) 159 this.nativePtr = nativePtr 160 this.fzAgent = new FinalizationAgent<DataShareHelperInner>(this, this.nativePtr); 161 } 162 163 unregisterCleaner(): void { 164 this.fzAgent.unregister(); 165 } 166 167 getNativePtr(): long { 168 return this.nativePtr 169 } 170 171 native on(type: 'dataChange', uri: string, callback: AsyncCallback<void>): void 172 native off(type: 'dataChange', uri: string, callback?: AsyncCallback<void>): void 173 native on(event: 'dataChange', type: SubscriptionType, uri: string, callback: AsyncCallback<ChangeInfo>): void 174 native off(event: 'dataChange', type: SubscriptionType, uri: string, callback?: AsyncCallback<ChangeInfo>): void 175 native ani_query(uri: string, predicates: dataSharePredicates.DataSharePredicates, columns: Array<string>): DataShareResultSet 176 native ani_update(uri: string, predicates: dataSharePredicates.DataSharePredicates, value: ValuesBucket): number 177 178 query(uri: string, predicates: dataSharePredicates.DataSharePredicates, columns: Array<string>, callback: AsyncCallback<DataShareResultSet>): void { 179 let p = taskpool.execute(this.ani_query, uri, predicates, columns) 180 p.then((e: NullishType) => { 181 let r = e as DataShareResultSet 182 let err: BusinessError<void> 183 callback(err, r) 184 }).catch((error: NullishType) => { 185 let err = error as BusinessError<void> 186 hilog.error(0x0000, 'DataShareHelper', "query failed:" + err) 187 }) 188 } 189 190 query(uri: string, predicates: dataSharePredicates.DataSharePredicates, columns: Array<string>): Promise<DataShareResultSet> { 191 return new Promise<DataShareResultSet>((resolve: (v: DataShareResultSet) => void, reject: (error: Error) => void) => { 192 let p = taskpool.execute(this.ani_query, uri, predicates, columns) 193 p.then((e: NullishType) => { 194 let r = e as DataShareResultSet 195 resolve(r) 196 }).catch((e: Error): void => { 197 hilog.error(0x0000, 'DataShareHelper', "query failed:" + e) 198 reject(e) 199 }) 200 }) 201 } 202 203 update(uri: string, predicates: dataSharePredicates.DataSharePredicates, value: ValuesBucket, callback: AsyncCallback<number>): void { 204 let p = taskpool.execute(this.ani_update, uri, predicates, value) 205 p.then((e: NullishType) => { 206 let r = e as number 207 let err: BusinessError<void> 208 callback(err, r) 209 }).catch((error: NullishType) => { 210 let err = error as BusinessError<void> 211 hilog.error(0x0000, 'DataShareHelper', "create failed:" + err) 212 }) 213 } 214 215 update(uri: string, predicates: dataSharePredicates.DataSharePredicates, value: ValuesBucket): Promise<number> { 216 return new Promise<number>((resolve: (v: number) => void, reject: (error: Error) => void) => { 217 let p = taskpool.execute(this.ani_update, uri, predicates, value) 218 p.then((e: NullishType) => { 219 let r = e as number 220 resolve(r) 221 }).catch((e: Error): void => { 222 hilog.error(0x0000, 'DataShareHelper', "update failed:" + e) 223 reject(e) 224 }) 225 }) 226 } 227 } 228} 229