1/* 2 * Copyright (c) 2021 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 * Environment 18 * 19 * Injects device properties ("environment") into AppStorage 20 * 21 */ 22 23class Environment { 24 private static Instance_: Environment = undefined; 25 private static EnvBackend_: IEnvironmentBackend; 26 private props_: Map<string, SubscribedAbstractProperty<any>>; 27 28 private static GetOrCreate(): Environment { 29 if (Environment.Instance_) { 30 // already initialized 31 return Environment.Instance_; 32 } 33 34 Environment.Instance_ = new Environment(); 35 return Environment.Instance_; 36 } 37 38 public static ConfigureBackend(envBackend: IEnvironmentBackend): void { 39 Environment.EnvBackend_ = envBackend; 40 } 41 42 public static AboutToBeDeleted(): void { 43 if (!Environment.Instance_) { 44 return; 45 } 46 47 Environment.GetOrCreate().aboutToBeDeleted(); 48 Environment.Instance_ = undefined; 49 } 50 51 public static EnvProp<S>(key: string, value: S): boolean { 52 return Environment.GetOrCreate().envProp<S>(key, value); 53 } 54 55 public static EnvProps(props: { 56 key: string, 57 defaultValue: any 58 }[] 59 ): void { 60 Environment.GetOrCreate().envProps(props); 61 } 62 63 static Keys(): Array<string> { 64 return Environment.GetOrCreate().keys(); 65 } 66 67 private constructor() { 68 this.props_ = new Map<string, ObservedPropertyAbstract<any>>(); 69 70 Environment.EnvBackend_.onValueChanged(this.onValueChanged.bind(this)); 71 } 72 73 private envProp<S>(key: string, value: S): boolean { 74 let prop = AppStorage.Prop(key); 75 if (prop) { 76 stateMgmtConsole.warn(`Environment: envProp '${key}': Property already exists in AppStorage. Not using environment property.`); 77 return false; 78 } 79 let tmp; 80 switch(key) { 81 case "accessibilityEnabled": 82 tmp = Environment.EnvBackend_ .getAccessibilityEnabled(); 83 break; 84 case "colorMode": 85 tmp = Environment.EnvBackend_ .getColorMode(); 86 break; 87 case "fontScale": 88 tmp = Environment.EnvBackend_ .getFontScale(); 89 break; 90 case "fontWeightScale": 91 tmp = Environment.EnvBackend_ .getFontWeightScale().toFixed(2); 92 break; 93 case "layoutDirection": 94 tmp = Environment.EnvBackend_ .getLayoutDirection(); 95 break; 96 case "languageCode": 97 tmp = Environment.EnvBackend_ .getLanguageCode(); 98 break; 99 default: 100 tmp = value; 101 } 102 prop = AppStorage.SetAndProp(key, tmp); 103 this.props_.set(key, prop); 104 stateMgmtConsole.debug(`Environment: envProp for '${key}' done.`); 105 } 106 107 private envProps(properties: { 108 key: string, 109 defaultValue: any 110 }[]): void { 111 properties.forEach(property => { 112 this.envProp(property.key, property.defaultValue); 113 stateMgmtConsole.debug(`Environment: envProps for '${property.key}' done.`); 114 }); 115 } 116 117 keys(): Array<string> { 118 let result = []; 119 const it = this.props_.keys(); 120 let val = it.next(); 121 122 while (!val.done) { 123 result.push(val.value); 124 val = it.next(); 125 } 126 127 return result; 128 } 129 130 onValueChanged(key: string, value: any): void { 131 let ok = AppStorage.Set(key, value); 132 if (ok) { 133 stateMgmtConsole.debug(`Environment: onValueChanged: ${key} changed to ${value}`); 134 } else { 135 stateMgmtConsole.warn(`Environment: onValueChanged: error changing ${key}! See results above.`); 136 } 137 } 138 139 aboutToBeDeleted() { 140 this.props_.forEach((val, key, map) => { 141 val.aboutToBeDeleted(); 142 AppStorage.Delete(key); 143 }); 144 } 145} 146