1 /*
2  * Copyright (c) 2020 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 #include "nativeapi_deviceinfo.h"
17 #include <string>
18 #include <new>
19 #include "global.h"
20 #include "js_async_work.h"
21 #include "nativeapi_common.h"
22 #include "nativeapi_config.h"
23 #include "parameter.h"
24 #include "common/screen.h"
25 
26 namespace OHOS {
27 namespace ACELite {
28 namespace {
ExecuteAsyncWork(const JSIValue thisVal,const JSIValue * args,uint8_t argsNum,AsyncWorkHandler ExecuteFunc,bool flag=false)29 JSIValue ExecuteAsyncWork(const JSIValue thisVal, const JSIValue* args,
30     uint8_t argsNum, AsyncWorkHandler ExecuteFunc, bool flag = false)
31 {
32     JSIValue undefValue = JSI::CreateUndefined();
33     if (!NativeapiCommon::IsValidJSIValue(args, argsNum)) {
34         return undefValue;
35     }
36     FuncParams* params = new(std::nothrow) FuncParams();
37     if (params == nullptr) {
38         return undefValue;
39     }
40     params->thisVal = JSI::AcquireValue(thisVal);
41     params->args = JSI::AcquireValue(args[0]);
42     params->flag = flag;
43     JsAsyncWork::DispatchAsyncWork(ExecuteFunc, reinterpret_cast<void *>(params));
44     return undefValue;
45 }
46 
ExecuteGetInfo(void * data)47 void ExecuteGetInfo(void* data)
48 {
49     FuncParams* params = reinterpret_cast<FuncParams *>(data);
50     if (params == nullptr) {
51         return;
52     }
53     JSIValue args = params->args;
54     JSIValue thisVal = params->thisVal;
55     JSIValue result = JSI::CreateObject();
56     if (!NativeapiDeviceInfo::GetProductInfo(result)) {
57         NativeapiCommon::FailCallBack(thisVal, args, ERROR_CODE_GENERAL);
58     } else {
59         NativeapiCommon::SuccessCallBack(thisVal, args, result);
60     }
61     JSI::ReleaseValueList(args, thisVal, result, ARGS_END);
62     delete params;
63     params = nullptr;
64 }
65 }
66 
InitDeviceModule(JSIValue exports)67 void InitDeviceModule(JSIValue exports)
68 {
69     JSI::SetModuleAPI(exports, "getInfo", NativeapiDeviceInfo::GetDeviceInfo);
70 }
71 
GetAPILevel(JSIValue result)72 bool NativeapiDeviceInfo::GetAPILevel(JSIValue result)
73 {
74     int apiLevel = GetSdkApiVersion();
75     if (apiLevel < 1) {
76         return false;
77     }
78     JSI::SetStringProperty(result, "apiVersion", std::to_string(apiLevel).c_str());
79     return true;
80 }
81 
GetDeviceInfo(const JSIValue thisVal,const JSIValue * args,uint8_t argsNum)82 JSIValue NativeapiDeviceInfo::GetDeviceInfo(const JSIValue thisVal, const JSIValue* args, uint8_t argsNum)
83 {
84     return ExecuteAsyncWork(thisVal, args, argsNum, ExecuteGetInfo);
85 }
86 
GetDeviceType(JSIValue result)87 bool NativeapiDeviceInfo::GetDeviceType(JSIValue result)
88 {
89     const char* deviceType = ::GetDeviceType();
90     if (deviceType == nullptr) {
91         return false;
92     }
93     JSI::SetStringProperty(result, "deviceType", deviceType);
94     return true;
95 }
96 
GetLanguage(JSIValue result)97 bool NativeapiDeviceInfo::GetLanguage(JSIValue result)
98 {
99     // because of MAX_LANGUAGE_LENGTH is little,we use array instead of pointer
100     char langStr[MAX_LANGUAGE_LENGTH + 1] = {0};
101     if (GLOBAL_GetLanguage(langStr, MAX_LANGUAGE_LENGTH) != 0) {
102         JSI::SetStringProperty(result, "language", "");
103     } else {
104         JSI::SetStringProperty(result, "language", langStr);
105     }
106     return true;
107 }
108 
GetProductInfo(JSIValue result)109 bool NativeapiDeviceInfo::GetProductInfo(JSIValue result)
110 {
111     bool isSuccess = true;
112     const char* brand =  GetBrand();
113     const char* manufacture = GetManufacture();
114     const char* model = GetProductModel();
115     if (brand == nullptr || manufacture == nullptr || model == nullptr) {
116         isSuccess = false;
117     } else {
118         JSI::SetStringProperty(result, "brand", brand);
119         JSI::SetStringProperty(result, "manufacturer", manufacture);
120         JSI::SetStringProperty(result, "model", model);
121         JSI::SetStringProperty(result, "product", model);
122     }
123     if (isSuccess) {
124         if (!NativeapiDeviceInfo::GetDeviceType(result) ||
125             !NativeapiDeviceInfo::GetLanguage(result) ||
126             !NativeapiDeviceInfo::GetAPILevel(result) ||
127             !NativeapiDeviceInfo::GetRegion(result)) {
128             isSuccess = false;
129         }
130     }
131 
132     Screen &screen = Screen::GetInstance();
133     JSI::SetNumberProperty(result, "windowWidth", static_cast<double>(screen.GetWidth()));
134     JSI::SetNumberProperty(result, "windowHeight", static_cast<double>(screen.GetHeight()));
135     // set default value
136     const uint8_t defaultScreenDensity = 195;
137     const char * const defaultScreenShape = "rect";
138     JSI::SetNumberProperty(result, "screenDensity", static_cast<double>(defaultScreenDensity));
139     JSI::SetStringProperty(result, "screenShape", defaultScreenShape);
140     return isSuccess;
141 }
142 
GetRegion(JSIValue result)143 bool NativeapiDeviceInfo::GetRegion(JSIValue result)
144 {
145     // because of MAX_REGION_LENGTH is little,we use array instead of pointer
146     char region[MAX_REGION_LENGTH + 1] = {0};
147     if (GLOBAL_GetRegion(region, MAX_REGION_LENGTH) != 0) {
148         JSI::SetStringProperty(result, "region", "");
149     } else {
150         JSI::SetStringProperty(result, "region", region);
151     }
152     return true;
153 }
154 } // ACELite
155 } // OHOS
156