1315b9658Sopenharmony_ci/**
2315b9658Sopenharmony_ci * Copyright (c) 2021-2023 Huawei Device Co., Ltd.
3315b9658Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4315b9658Sopenharmony_ci * you may not use this file except in compliance with the License.
5315b9658Sopenharmony_ci * You may obtain a copy of the License at
6315b9658Sopenharmony_ci *
7315b9658Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8315b9658Sopenharmony_ci *
9315b9658Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10315b9658Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11315b9658Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12315b9658Sopenharmony_ci * See the License for the specific language governing permissions and
13315b9658Sopenharmony_ci * limitations under the License.
14315b9658Sopenharmony_ci */
15315b9658Sopenharmony_ci
16315b9658Sopenharmony_ciimport common from '@ohos.app.ability.common';
17315b9658Sopenharmony_ciimport Audio from '@ohos.multimedia.audio';
18315b9658Sopenharmony_ciimport abilityAccessCtrl from '@ohos.abilityAccessCtrl';
19315b9658Sopenharmony_ciimport DataShareExtensionAbility from '@ohos.application.DataShareExtensionAbility';
20315b9658Sopenharmony_ciimport rpc from '@ohos.rpc';
21315b9658Sopenharmony_ciimport process from '@ohos.process';
22315b9658Sopenharmony_ciimport settings from '@ohos.settings';
23315b9658Sopenharmony_ciimport relationalStore from '@ohos.data.relationalStore';
24315b9658Sopenharmony_ciimport Want from '@ohos.app.ability.Want';
25315b9658Sopenharmony_ciimport dataSharePredicates from '@ohos.data.dataSharePredicates';
26315b9658Sopenharmony_ciimport { AsyncCallback, BusinessError } from '@ohos.base';
27315b9658Sopenharmony_ciimport SettingsDataConfig from '../Utils/SettingsDataConfig';
28315b9658Sopenharmony_ciimport SettingsDBHelper from '../Utils/SettingsDBHelper';
29315b9658Sopenharmony_ciimport { Log } from '../Utils/Log';
30315b9658Sopenharmony_ciimport { GlobalContext}  from '../Utils/GlobalContext';
31315b9658Sopenharmony_ciimport contextConstant from '@ohos.app.ability.contextConstant';
32315b9658Sopenharmony_ci
33315b9658Sopenharmony_ci
34315b9658Sopenharmony_ciinterface  IRequest {
35315b9658Sopenharmony_ci  operation:string ;
36315b9658Sopenharmony_ci  columns:string[];
37315b9658Sopenharmony_ci  predicates:dataSharePredicates.DataSharePredicates|relationalStore.RdbPredicates|null;
38315b9658Sopenharmony_ci  value:relationalStore.ValuesBucket|null
39315b9658Sopenharmony_ci}
40315b9658Sopenharmony_cilet rdbStore:relationalStore.RdbStore|undefined = undefined;
41315b9658Sopenharmony_cilet requests:IRequest[] = [];
42315b9658Sopenharmony_cilet SETTINGS_AUDIO_RINGTONE = 'settings.audio.ringtone'
43315b9658Sopenharmony_cilet SETTINGS_AUDIO_MEDIA = 'settings.audio.media'
44315b9658Sopenharmony_cilet SETTINGS_AUDIO_VOICE_CALL = 'settings.audio.voicecall'
45315b9658Sopenharmony_cilet trustList: String[] = [
46315b9658Sopenharmony_cisettings.display.SCREEN_BRIGHTNESS_STATUS,
47315b9658Sopenharmony_cisettings.display.AUTO_SCREEN_BRIGHTNESS,
48315b9658Sopenharmony_cisettings.display.SCREEN_OFF_TIMEOUT
49315b9658Sopenharmony_ci];
50315b9658Sopenharmony_cilet ret:number = 0;
51315b9658Sopenharmony_cilet err:BusinessError = {'code':-1} as BusinessError;
52315b9658Sopenharmony_ci
53315b9658Sopenharmony_ciexport default class DataExtAbility extends DataShareExtensionAbility {
54315b9658Sopenharmony_ci  onCreate(want: Want) {
55315b9658Sopenharmony_ci    GlobalContext.getContext().setObject('abilityContext', this.context);
56315b9658Sopenharmony_ci    // database move to DE area;
57315b9658Sopenharmony_ci    this.context.area = contextConstant.AreaMode.EL2;
58315b9658Sopenharmony_ci    this.context.area = SettingsDBHelper.getInstance().getArea();
59315b9658Sopenharmony_ci    this.onInitialized();
60315b9658Sopenharmony_ci    Log.info('onCreate  context' + JSON.stringify(this.context));
61315b9658Sopenharmony_ci  }
62315b9658Sopenharmony_ci
63315b9658Sopenharmony_ci  onInitialized() {
64315b9658Sopenharmony_ci    Log.info('onInitialize start');
65315b9658Sopenharmony_ci    let context = GlobalContext.getContext().getObject('abilityContext') as Context;
66315b9658Sopenharmony_ci    Log.info('onInitialize start context: ' + JSON.stringify(this.context));
67315b9658Sopenharmony_ci    if (context !== null) {
68315b9658Sopenharmony_ci      SettingsDBHelper.getInstance().getRdbStore().then((rdb: relationalStore.RdbStore|undefined) => {
69315b9658Sopenharmony_ci        rdbStore = rdb;
70315b9658Sopenharmony_ci        if (!rdbStore) {
71315b9658Sopenharmony_ci          Log.error('onInitialized: get rdb store failed!');
72315b9658Sopenharmony_ci          return;
73315b9658Sopenharmony_ci        }
74315b9658Sopenharmony_ci        Log.info('onInitialized: get rdb store succeed!');
75315b9658Sopenharmony_ci        for (let i = 0; i < requests.length; i++) {
76315b9658Sopenharmony_ci          let opt: string = requests[i].operation;
77315b9658Sopenharmony_ci          let columns: string[] = requests[i].columns;
78315b9658Sopenharmony_ci          let predicates = (requests[i].predicates) as dataSharePredicates.DataSharePredicates;
79315b9658Sopenharmony_ci
80315b9658Sopenharmony_ci          let value: relationalStore.ValuesBucket|null = requests[i].value;
81315b9658Sopenharmony_ci          if (opt == 'insert') {
82315b9658Sopenharmony_ci            if(value){
83315b9658Sopenharmony_ci              rdbStore?.insert(SettingsDataConfig.TABLE_NAME, value,  (err, ret) => {
84315b9658Sopenharmony_ci                Log.info('onInitialized insert ret: ' + ret);
85315b9658Sopenharmony_ci              });
86315b9658Sopenharmony_ci            }
87315b9658Sopenharmony_ci          } else if (opt == 'query') {
88315b9658Sopenharmony_ci            if(predicates){
89315b9658Sopenharmony_ci              rdbStore?.query(SettingsDataConfig.TABLE_NAME, predicates, columns, (
90315b9658Sopenharmony_ci                err: BusinessError, resultSet: relationalStore.ResultSet) => {
91315b9658Sopenharmony_ci                Log.info('onInitialized query ret: ' + JSON.stringify(resultSet));
92315b9658Sopenharmony_ci              });
93315b9658Sopenharmony_ci            }
94315b9658Sopenharmony_ci
95315b9658Sopenharmony_ci          } else if (opt == 'update') {
96315b9658Sopenharmony_ci            if(value){
97315b9658Sopenharmony_ci              rdbStore?.update(SettingsDataConfig.TABLE_NAME, value, predicates, (err, ret) => {
98315b9658Sopenharmony_ci                Log.info('onInitialized update ret: ' + ret);
99315b9658Sopenharmony_ci              });
100315b9658Sopenharmony_ci            }
101315b9658Sopenharmony_ci          }
102315b9658Sopenharmony_ci        }
103315b9658Sopenharmony_ci      }).catch((err: Error) => {
104315b9658Sopenharmony_ci        Log.error('onInitialize failed:' + JSON.stringify(err));
105315b9658Sopenharmony_ci      })
106315b9658Sopenharmony_ci    } else {
107315b9658Sopenharmony_ci      Log.info('onInitialize context error!');
108315b9658Sopenharmony_ci    }
109315b9658Sopenharmony_ci    Log.info('onInitialize end');
110315b9658Sopenharmony_ci  }
111315b9658Sopenharmony_ci
112315b9658Sopenharmony_ci  insert(uri: string, value: relationalStore.ValuesBucket, callback : AsyncCallback<number>) {
113315b9658Sopenharmony_ci    Log.info('insert keyword = ' + value[SettingsDataConfig.FIELD_KEYWORD] + ' start:' + uri);
114315b9658Sopenharmony_ci    let rdbInsert = (GrantStatus: boolean) => {
115315b9658Sopenharmony_ci      if (!GrantStatus) {
116315b9658Sopenharmony_ci        callback(err, ret);
117315b9658Sopenharmony_ci        return;
118315b9658Sopenharmony_ci      }
119315b9658Sopenharmony_ci      this.DoSystemSetting(
120315b9658Sopenharmony_ci        value[SettingsDataConfig.FIELD_KEYWORD]?.toString(), value[SettingsDataConfig.FIELD_VALUE]?.toString());
121315b9658Sopenharmony_ci
122315b9658Sopenharmony_ci      if (rdbStore == null) {
123315b9658Sopenharmony_ci        let request: IRequest = {
124315b9658Sopenharmony_ci          operation: 'insert', columns: [], predicates: null, value: value
125315b9658Sopenharmony_ci        };
126315b9658Sopenharmony_ci        Log.info('insert request = ' + JSON.stringify(request));
127315b9658Sopenharmony_ci        requests.push(request);
128315b9658Sopenharmony_ci        callback(err, ret);
129315b9658Sopenharmony_ci      } else {
130315b9658Sopenharmony_ci        rdbStore.insert(SettingsDataConfig.TABLE_NAME, value,  (err, ret) => {
131315b9658Sopenharmony_ci          Log.info('insert result: ' + ret);
132315b9658Sopenharmony_ci          callback(err, ret);
133315b9658Sopenharmony_ci        });
134315b9658Sopenharmony_ci      }
135315b9658Sopenharmony_ci    }
136315b9658Sopenharmony_ci
137315b9658Sopenharmony_ci    try {
138315b9658Sopenharmony_ci      Log.info('Start to verify permissions.');
139315b9658Sopenharmony_ci      this.verifyPermission(value, rdbInsert);
140315b9658Sopenharmony_ci    } catch (err) {
141315b9658Sopenharmony_ci      Log.error('Insert Data error:' + JSON.stringify(err));
142315b9658Sopenharmony_ci      callback(err, ret);
143315b9658Sopenharmony_ci    }
144315b9658Sopenharmony_ci  }
145315b9658Sopenharmony_ci
146315b9658Sopenharmony_ci
147315b9658Sopenharmony_ci  update(
148315b9658Sopenharmony_ci    uri: string, predicates: dataSharePredicates.DataSharePredicates,
149315b9658Sopenharmony_ci    value:relationalStore.ValuesBucket, callback: AsyncCallback<number>) {
150315b9658Sopenharmony_ci    Log.info('update keyword = ' + value[SettingsDataConfig.FIELD_KEYWORD] + ' start:' + uri);
151315b9658Sopenharmony_ci    let rdbUpData = (GrantStatus:boolean) => {
152315b9658Sopenharmony_ci      if (!GrantStatus) {
153315b9658Sopenharmony_ci        callback(err, ret);
154315b9658Sopenharmony_ci        return;
155315b9658Sopenharmony_ci      }
156315b9658Sopenharmony_ci      this.DoSystemSetting(
157315b9658Sopenharmony_ci        value[SettingsDataConfig.FIELD_KEYWORD]?.toString(), value[SettingsDataConfig.FIELD_VALUE]?.toString());
158315b9658Sopenharmony_ci      if (rdbStore == null) {
159315b9658Sopenharmony_ci        let request : IRequest = {
160315b9658Sopenharmony_ci          operation: 'update', columns: [], predicates: predicates, value: value
161315b9658Sopenharmony_ci        };
162315b9658Sopenharmony_ci        Log.info('update request = ' + JSON.stringify(request));
163315b9658Sopenharmony_ci        requests.push(request);
164315b9658Sopenharmony_ci        callback(err, ret);
165315b9658Sopenharmony_ci      } else {
166315b9658Sopenharmony_ci        rdbStore.update(SettingsDataConfig.TABLE_NAME, value, predicates , (err, ret)=> {
167315b9658Sopenharmony_ci          Log.info('update result: ' + ret);
168315b9658Sopenharmony_ci          callback(err, ret);
169315b9658Sopenharmony_ci        });
170315b9658Sopenharmony_ci      }
171315b9658Sopenharmony_ci    }
172315b9658Sopenharmony_ci    try {
173315b9658Sopenharmony_ci      Log.info('Start to verify permissions.');
174315b9658Sopenharmony_ci      this.verifyPermission(value, rdbUpData);
175315b9658Sopenharmony_ci    } catch (err) {
176315b9658Sopenharmony_ci      Log.error('upData error:' + JSON.stringify(err));
177315b9658Sopenharmony_ci      callback(err, ret);
178315b9658Sopenharmony_ci    }
179315b9658Sopenharmony_ci  }
180315b9658Sopenharmony_ci
181315b9658Sopenharmony_ci  delete(uri: string, predicates: dataSharePredicates.DataSharePredicates, callback: AsyncCallback<number>) {
182315b9658Sopenharmony_ci    Log.info('nothing to do');
183315b9658Sopenharmony_ci  }
184315b9658Sopenharmony_ci
185315b9658Sopenharmony_ci  query(uri: string,
186315b9658Sopenharmony_ci        predicates: dataSharePredicates.DataSharePredicates, columns: string[], callback: AsyncCallback<Object>) {
187315b9658Sopenharmony_ci    Log.info( 'query start uri:' + uri);
188315b9658Sopenharmony_ci    if (rdbStore == null) {
189315b9658Sopenharmony_ci      let request: IRequest = {operation:'query', columns : columns, predicates : predicates, value:null};
190315b9658Sopenharmony_ci      Log.info('query request = ' + JSON.stringify(request));
191315b9658Sopenharmony_ci      requests.push(request);
192315b9658Sopenharmony_ci      callback(err, {'_napiwrapper':{}});
193315b9658Sopenharmony_ci    } else {
194315b9658Sopenharmony_ci      rdbStore.query(SettingsDataConfig.TABLE_NAME, predicates, columns,
195315b9658Sopenharmony_ci        (err:BusinessError, resultSet:relationalStore.ResultSet)=> {
196315b9658Sopenharmony_ci        Log.info(
197315b9658Sopenharmony_ci          'query result:' + JSON.stringify(resultSet.rowCount) + 'columnNames' + JSON.stringify(resultSet.columnNames));
198315b9658Sopenharmony_ci        callback(err, resultSet);
199315b9658Sopenharmony_ci      })
200315b9658Sopenharmony_ci    }
201315b9658Sopenharmony_ci  }
202315b9658Sopenharmony_ci
203315b9658Sopenharmony_ci  private DoSystemSetting(settingsKey: string|undefined, settingsValue: string|undefined) {
204315b9658Sopenharmony_ci    switch (settingsKey) {
205315b9658Sopenharmony_ci      case SETTINGS_AUDIO_RINGTONE:
206315b9658Sopenharmony_ci        try {
207315b9658Sopenharmony_ci          let volumeType = Audio.AudioVolumeType.RINGTONE;
208315b9658Sopenharmony_ci          Audio.getAudioManager().setVolume(volumeType, Number(settingsValue)).then(() => {
209315b9658Sopenharmony_ci            Log.info('settings Promise returned to indicate a successful RINGTONE setting.')
210315b9658Sopenharmony_ci          });
211315b9658Sopenharmony_ci        } catch (err) {
212315b9658Sopenharmony_ci          Log.info('settings RINGTONE failed error = ' + JSON.stringify(err));
213315b9658Sopenharmony_ci        }
214315b9658Sopenharmony_ci        break
215315b9658Sopenharmony_ci      case SETTINGS_AUDIO_MEDIA:
216315b9658Sopenharmony_ci        try {
217315b9658Sopenharmony_ci          let volumeType = Audio.AudioVolumeType.MEDIA;
218315b9658Sopenharmony_ci          Audio.getAudioManager().setVolume(volumeType, Number(settingsValue)).then(() => {
219315b9658Sopenharmony_ci            Log.info('settings Promise returned to indicate a successful MEDIA setting.')
220315b9658Sopenharmony_ci          });
221315b9658Sopenharmony_ci        } catch (err) {
222315b9658Sopenharmony_ci          Log.info('settings MEDIA failed error = ' + JSON.stringify(err));
223315b9658Sopenharmony_ci        }
224315b9658Sopenharmony_ci        break
225315b9658Sopenharmony_ci      case SETTINGS_AUDIO_VOICE_CALL:
226315b9658Sopenharmony_ci        try {
227315b9658Sopenharmony_ci          let volumeType = Audio.AudioVolumeType.VOICE_CALL;
228315b9658Sopenharmony_ci          Audio.getAudioManager().setVolume(volumeType, Number(settingsValue)).then(() => {
229315b9658Sopenharmony_ci            Log.info('settings Promise returned to indicate a successful VOICE_CALL setting.')
230315b9658Sopenharmony_ci          });
231315b9658Sopenharmony_ci        } catch (err) {
232315b9658Sopenharmony_ci          Log.info('settings VOICE_CALL failed error = ' + JSON.stringify(err));
233315b9658Sopenharmony_ci        }
234315b9658Sopenharmony_ci        break
235315b9658Sopenharmony_ci      default:
236315b9658Sopenharmony_ci        Log.info(settingsKey + ' key is not audio');
237315b9658Sopenharmony_ci        break
238315b9658Sopenharmony_ci    }
239315b9658Sopenharmony_ci  }
240315b9658Sopenharmony_ci
241315b9658Sopenharmony_ci  private verifyPermission(value: relationalStore.ValuesBucket, callBack: (GrantStatus: boolean) => void ) {
242315b9658Sopenharmony_ci    if (this.isTrustList(
243315b9658Sopenharmony_ci      value[SettingsDataConfig.FIELD_KEYWORD] as string) || process.uid == rpc.IPCSkeleton.getCallingUid()) {
244315b9658Sopenharmony_ci      callBack(true);
245315b9658Sopenharmony_ci      return;
246315b9658Sopenharmony_ci    }
247315b9658Sopenharmony_ci    try {
248315b9658Sopenharmony_ci      let tokenID = rpc.IPCSkeleton.getCallingTokenId();
249315b9658Sopenharmony_ci      Log.info('tokenID = ' + tokenID);
250315b9658Sopenharmony_ci      let grantStatus = abilityAccessCtrl.createAtManager().verifyAccessToken(
251315b9658Sopenharmony_ci        tokenID, 'ohos.permission.MANAGE_SECURE_SETTINGS');
252315b9658Sopenharmony_ci      grantStatus.then(data => {
253315b9658Sopenharmony_ci        if (data == abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED) {
254315b9658Sopenharmony_ci          Log.info('MANAGE_SECURE_SETTINGS active');
255315b9658Sopenharmony_ci          callBack(true);
256315b9658Sopenharmony_ci        } else {
257315b9658Sopenharmony_ci          Log.warn('MANAGE_SECURE_SETTINGS grantStatus= ' + JSON.stringify(data));
258315b9658Sopenharmony_ci          callBack(false);
259315b9658Sopenharmony_ci        }
260315b9658Sopenharmony_ci      }).catch((err: BusinessError) => {
261315b9658Sopenharmony_ci        Log.error('tokenID = ' + tokenID + ' verifyAccessToken is failed: ' + JSON.stringify(err));
262315b9658Sopenharmony_ci        callBack(false);
263315b9658Sopenharmony_ci      })
264315b9658Sopenharmony_ci    } catch (err) {
265315b9658Sopenharmony_ci      Log.error('err = ' + JSON.stringify(err));
266315b9658Sopenharmony_ci      callBack(false);
267315b9658Sopenharmony_ci    }
268315b9658Sopenharmony_ci  }
269315b9658Sopenharmony_ci
270315b9658Sopenharmony_ci  private isTrustList(keyWord: string): boolean {
271315b9658Sopenharmony_ci    return trustList.includes(keyWord)
272315b9658Sopenharmony_ci  }
273315b9658Sopenharmony_ci}