• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/**
2 * Copyright (c) 2021-2023 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
16import common from '@ohos.app.ability.common';
17import Audio from '@ohos.multimedia.audio';
18import abilityAccessCtrl from '@ohos.abilityAccessCtrl';
19import DataShareExtensionAbility from '@ohos.application.DataShareExtensionAbility';
20import rpc from '@ohos.rpc';
21import process from '@ohos.process';
22import settings from '@ohos.settings';
23import relationalStore from '@ohos.data.relationalStore';
24import Want from '@ohos.app.ability.Want';
25import dataSharePredicates from '@ohos.data.dataSharePredicates';
26import { AsyncCallback, BusinessError } from '@ohos.base';
27import SettingsDataConfig from '../Utils/SettingsDataConfig';
28import SettingsDBHelper from '../Utils/SettingsDBHelper';
29import { Log } from '../Utils/Log';
30import { GlobalContext}  from '../Utils/GlobalContext';
31import contextConstant from '@ohos.app.ability.contextConstant';
32
33
34interface  IRequest {
35  operation:string ;
36  columns:string[];
37  predicates:dataSharePredicates.DataSharePredicates|relationalStore.RdbPredicates|null;
38  value:relationalStore.ValuesBucket|null
39}
40let rdbStore:relationalStore.RdbStore|undefined = undefined;
41let requests:IRequest[] = [];
42let SETTINGS_AUDIO_RINGTONE = 'settings.audio.ringtone'
43let SETTINGS_AUDIO_MEDIA = 'settings.audio.media'
44let SETTINGS_AUDIO_VOICE_CALL = 'settings.audio.voicecall'
45let trustList: String[] = [
46settings.display.SCREEN_BRIGHTNESS_STATUS,
47settings.display.AUTO_SCREEN_BRIGHTNESS,
48settings.display.SCREEN_OFF_TIMEOUT
49];
50let ret:number = 0;
51let err:BusinessError = {'code':-1} as BusinessError;
52
53export default class DataExtAbility extends DataShareExtensionAbility {
54  onCreate(want: Want) {
55    GlobalContext.getContext().setObject('abilityContext', this.context);
56    // database move to DE area;
57    this.context.area = contextConstant.AreaMode.EL2;
58    this.context.area = SettingsDBHelper.getInstance().getArea();
59    this.onInitialized();
60    Log.info('onCreate  context' + JSON.stringify(this.context));
61  }
62
63  onInitialized() {
64    Log.info('onInitialize start');
65    let context = GlobalContext.getContext().getObject('abilityContext') as Context;
66    Log.info('onInitialize start context: ' + JSON.stringify(this.context));
67    if (context !== null) {
68      SettingsDBHelper.getInstance().getRdbStore().then((rdb: relationalStore.RdbStore|undefined) => {
69        rdbStore = rdb;
70        if (!rdbStore) {
71          Log.error('onInitialized: get rdb store failed!');
72          return;
73        }
74        Log.info('onInitialized: get rdb store succeed!');
75        for (let i = 0; i < requests.length; i++) {
76          let opt: string = requests[i].operation;
77          let columns: string[] = requests[i].columns;
78          let predicates = (requests[i].predicates) as dataSharePredicates.DataSharePredicates;
79
80          let value: relationalStore.ValuesBucket|null = requests[i].value;
81          if (opt == 'insert') {
82            if(value){
83              rdbStore?.insert(SettingsDataConfig.TABLE_NAME, value,  (err, ret) => {
84                Log.info('onInitialized insert ret: ' + ret);
85              });
86            }
87          } else if (opt == 'query') {
88            if(predicates){
89              rdbStore?.query(SettingsDataConfig.TABLE_NAME, predicates, columns, (
90                err: BusinessError, resultSet: relationalStore.ResultSet) => {
91                Log.info('onInitialized query ret: ' + JSON.stringify(resultSet));
92              });
93            }
94
95          } else if (opt == 'update') {
96            if(value){
97              rdbStore?.update(SettingsDataConfig.TABLE_NAME, value, predicates, (err, ret) => {
98                Log.info('onInitialized update ret: ' + ret);
99              });
100            }
101          }
102        }
103      }).catch((err: Error) => {
104        Log.error('onInitialize failed:' + JSON.stringify(err));
105      })
106    } else {
107      Log.info('onInitialize context error!');
108    }
109    Log.info('onInitialize end');
110  }
111
112  insert(uri: string, value: relationalStore.ValuesBucket, callback : AsyncCallback<number>) {
113    Log.info('insert keyword = ' + value[SettingsDataConfig.FIELD_KEYWORD] + ' start:' + uri);
114    let rdbInsert = (GrantStatus: boolean) => {
115      if (!GrantStatus) {
116        callback(err, ret);
117        return;
118      }
119      this.DoSystemSetting(
120        value[SettingsDataConfig.FIELD_KEYWORD]?.toString(), value[SettingsDataConfig.FIELD_VALUE]?.toString());
121
122      if (rdbStore == null) {
123        let request: IRequest = {
124          operation: 'insert', columns: [], predicates: null, value: value
125        };
126        Log.info('insert request = ' + JSON.stringify(request));
127        requests.push(request);
128      } else {
129        rdbStore.insert(SettingsDataConfig.TABLE_NAME, value,  (err, ret) => {
130          Log.info('insert result: ' + ret);
131          callback(err, ret);
132        });
133      }
134    }
135
136    try {
137      Log.info('Start to verify permissions.');
138      this.verifyPermission(value, rdbInsert);
139    } catch (err) {
140      Log.error('Insert Data error:' + JSON.stringify(err));
141      callback(err, ret);
142    }
143  }
144
145
146  update(
147    uri: string, predicates: dataSharePredicates.DataSharePredicates,
148    value:relationalStore.ValuesBucket, callback: AsyncCallback<number>) {
149    Log.info('update keyword = ' + value[SettingsDataConfig.FIELD_KEYWORD] + ' start:' + uri);
150    let rdbUpData = (GrantStatus:boolean) => {
151      if (!GrantStatus) {
152        callback(err, ret);
153        return;
154      }
155      this.DoSystemSetting(
156        value[SettingsDataConfig.FIELD_KEYWORD]?.toString(), value[SettingsDataConfig.FIELD_VALUE]?.toString());
157      if (rdbStore == null) {
158        let request : IRequest = {
159          operation: 'update', columns: [], predicates: predicates, value: value
160        };
161        Log.info('update request = ' + JSON.stringify(request));
162        requests.push(request);
163      } else {
164        rdbStore.update(SettingsDataConfig.TABLE_NAME, value, predicates , (err, ret)=> {
165          Log.info('update result: ' + ret);
166          callback(err, ret);
167        });
168      }
169    }
170    try {
171      Log.info('Start to verify permissions.');
172      this.verifyPermission(value, rdbUpData);
173    } catch (err) {
174      Log.error('upData error:' + JSON.stringify(err));
175      callback(err, ret);
176    }
177  }
178
179  delete(uri: string, predicates: dataSharePredicates.DataSharePredicates, callback: AsyncCallback<number>) {
180    Log.info('nothing to do');
181  }
182
183  query(uri: string,
184        predicates: dataSharePredicates.DataSharePredicates, columns: string[], callback: AsyncCallback<Object>) {
185    Log.info( 'query start uri:' + uri);
186    if (rdbStore == null) {
187      let request: IRequest = {operation:'query', columns : columns, predicates : predicates, value:null};
188      Log.info('query request = ' + JSON.stringify(request));
189      requests.push(request);
190    } else {
191      rdbStore.query(SettingsDataConfig.TABLE_NAME, predicates, columns,
192        (err:BusinessError, resultSet:relationalStore.ResultSet)=> {
193        Log.info(
194          'query result:' + JSON.stringify(resultSet.rowCount) + 'columnNames' + JSON.stringify(resultSet.columnNames));
195        callback(err, resultSet);
196      })
197    }
198  }
199
200  private DoSystemSetting(settingsKey: string|undefined, settingsValue: string|undefined) {
201    switch (settingsKey) {
202      case SETTINGS_AUDIO_RINGTONE:
203        try {
204          let volumeType = Audio.AudioVolumeType.RINGTONE;
205          Audio.getAudioManager().setVolume(volumeType, Number(settingsValue)).then(() => {
206            Log.info('settings Promise returned to indicate a successful RINGTONE setting.')
207          });
208        } catch (err) {
209          Log.info('settings RINGTONE failed error = ' + JSON.stringify(err));
210        }
211        break
212      case SETTINGS_AUDIO_MEDIA:
213        try {
214          let volumeType = Audio.AudioVolumeType.MEDIA;
215          Audio.getAudioManager().setVolume(volumeType, Number(settingsValue)).then(() => {
216            Log.info('settings Promise returned to indicate a successful MEDIA setting.')
217          });
218        } catch (err) {
219          Log.info('settings MEDIA failed error = ' + JSON.stringify(err));
220        }
221        break
222      case SETTINGS_AUDIO_VOICE_CALL:
223        try {
224          let volumeType = Audio.AudioVolumeType.VOICE_CALL;
225          Audio.getAudioManager().setVolume(volumeType, Number(settingsValue)).then(() => {
226            Log.info('settings Promise returned to indicate a successful VOICE_CALL setting.')
227          });
228        } catch (err) {
229          Log.info('settings VOICE_CALL failed error = ' + JSON.stringify(err));
230        }
231        break
232      default:
233        Log.info(settingsKey + ' key is not audio');
234        break
235    }
236  }
237
238  private verifyPermission(value: relationalStore.ValuesBucket, callBack: (GrantStatus: boolean) => void ) {
239    if (this.isTrustList(
240      value[SettingsDataConfig.FIELD_KEYWORD] as string) || process.uid == rpc.IPCSkeleton.getCallingUid()) {
241      callBack(true);
242      return;
243    }
244    try {
245      let tokenID = rpc.IPCSkeleton.getCallingTokenId();
246      Log.info('tokenID = ' + tokenID);
247      let grantStatus = abilityAccessCtrl.createAtManager().verifyAccessToken(
248        tokenID, 'ohos.permission.MANAGE_SECURE_SETTINGS');
249      grantStatus.then(data => {
250        if (data == abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED) {
251          Log.info('MANAGE_SECURE_SETTINGS active');
252          callBack(true);
253        } else {
254          Log.warn('MANAGE_SECURE_SETTINGS grantStatus= ' + JSON.stringify(data));
255          callBack(false);
256        }
257      }).catch((err: BusinessError) => {
258        Log.error('tokenID = ' + tokenID + ' verifyAccessToken is failed: ' + JSON.stringify(err));
259        callBack(false);
260      })
261    } catch (err) {
262      Log.error('err = ' + JSON.stringify(err));
263      callBack(false);
264    }
265  }
266
267  private isTrustList(keyWord: string): boolean {
268    return trustList.includes(keyWord)
269  }
270}