2 * Copyright 2016 Jide Technology Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 package org.android_x86.hardwarecollector;
18 import org.android_x86.analytics.AnalyticsHelper;
19 import org.android_x86.analytics.GeneralLogs;
21 import android.app.IntentService;
22 import android.content.Context;
23 import android.content.Intent;
24 import android.content.IntentFilter;
25 import android.graphics.SurfaceTexture;
26 import android.hardware.input.InputManager;
27 import android.opengl.EGL14;
28 import android.opengl.GLES20;
29 import android.util.Log;
30 import android.view.InputDevice;
32 import org.json.JSONObject;
34 import javax.microedition.khronos.egl.EGL10;
35 import javax.microedition.khronos.egl.EGLConfig;
36 import javax.microedition.khronos.egl.EGLContext;
37 import javax.microedition.khronos.egl.EGLDisplay;
38 import javax.microedition.khronos.egl.EGLSurface;
39 import java.io.BufferedReader;
41 import java.io.FileReader;
42 import java.io.FileWriter;
43 import java.io.IOException;
44 import java.io.PrintWriter;
46 public class HardwareCollectorService extends IntentService {
47 private static final String TAG = "HardwareCollectorService";
49 private static final String GA_CATEGORY = "hardware_info";
50 private static final String GA_ACTION_GPU_RENDERER = "gpu_renderer";
51 private static final String GA_ACTION_CPU_MODEL = "cpu_model";
52 private static final String GA_ACTION_TOUCH_SCREEN_NAME = "touch_screen_name";
53 private static final String GA_ACTION_HAS_BATTERY = "has_battery";
54 private static final String GA_LABEL_HAS_BATTERY = "battery";
55 private static final String GA_LABEL_NO_BATTERY = "no_battery";
57 private static final String LAST_INFO_FILE_NAME = "lastInfo.json";
58 private static final String CPU_INFO_FILE = "/proc/cpuinfo";
59 private static final String CPU_INFO_MODEL_NAME_PRE = "model name\t: ";
60 private static final int TOUCHSCREEN_SOURCE_BIT = 4098;
62 private Context mContext;
63 private File mInfoFile;
64 private JSONObject mInfoJson;
66 public HardwareCollectorService() {
67 super("HardwareCollectorService");
71 public void onCreate() {
73 mContext = getBaseContext();
74 mInfoFile = new File(getApplicationContext().getFilesDir(), LAST_INFO_FILE_NAME);
78 protected void onHandleIntent(Intent intent) {
79 String action = intent.getAction();
80 Log.i(TAG, "handle intent:" + intent);
81 if (Intent.ACTION_BOOT_COMPLETED.equals(action)) {
86 private void uploadHardwareInfo() {
90 collectTouchScreenInfo();
94 private void collectOpenGLInfo() {
96 EGL10 egl = (EGL10) EGLContext.getEGL();
97 EGLSurface eglSurface = null;
98 EGLContext eglContext = null;
100 // initialize display
101 EGLDisplay eglDisplay = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
102 int[] iparam = new int[2];
103 egl.eglInitialize(eglDisplay, iparam);
106 EGLConfig[] eglConfigs = new EGLConfig[1];
107 final int[] configSpec =
108 {EGL10.EGL_RENDERABLE_TYPE, EGL14.EGL_OPENGL_ES2_BIT, EGL10.EGL_NONE};
109 if (egl.eglChooseConfig(eglDisplay, configSpec, eglConfigs, 1, iparam)
112 SurfaceTexture surfaceTexture = new SurfaceTexture(0);
113 eglSurface = egl.eglCreateWindowSurface(
114 eglDisplay, eglConfigs[0], surfaceTexture, null);
115 if (eglSurface != null && eglSurface != EGL10.EGL_NO_SURFACE) {
117 final int[] attribList = {EGL14.EGL_CONTEXT_CLIENT_VERSION, 2, EGL10.EGL_NONE};
118 eglContext = egl.eglCreateContext(
119 eglDisplay, eglConfigs[0], EGL10.EGL_NO_CONTEXT, attribList);
120 egl.eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext);
124 checkAndSend(GA_ACTION_GPU_RENDERER, GLES20.glGetString(GLES20.GL_RENDERER));
125 } catch (Exception e) {
126 Log.e(TAG, "fail to get GPU renderer", e);
130 private void collectCPUInfo() {
132 BufferedReader reader = new BufferedReader(new FileReader(CPU_INFO_FILE));
135 while ((cpuInfo = reader.readLine()) != null) {
136 if (cpuInfo.contains(CPU_INFO_MODEL_NAME_PRE)) {
137 model = cpuInfo.substring(CPU_INFO_MODEL_NAME_PRE.length());
138 checkAndSend(GA_ACTION_CPU_MODEL, model);
143 } catch (Exception e) {
144 Log.e(TAG, "fail to get CPU model name", e);
148 private void collectTouchScreenInfo() {
149 int[] ids = InputManager.getInstance().getInputDeviceIds();
151 InputDevice device = InputManager.getInstance().getInputDevice(id);
152 String name = device.getName();
153 if ((device.getSources() & TOUCHSCREEN_SOURCE_BIT) == TOUCHSCREEN_SOURCE_BIT) {
154 checkAndSend(GA_ACTION_TOUCH_SCREEN_NAME, name);
160 private void collectBatteryInfo() {
161 IntentFilter filter = new IntentFilter();
162 filter.addAction(Intent.ACTION_BATTERY_CHANGED);
163 Intent batteryIntent = mContext.registerReceiver(null, filter);
164 String label = batteryIntent.getBooleanExtra("present", false) ?
165 GA_LABEL_HAS_BATTERY : GA_LABEL_NO_BATTERY;
166 AnalyticsHelper.CustomEvent customEvent = AnalyticsHelper.newSystemCoreEvent(
167 mContext, GA_CATEGORY, GA_ACTION_HAS_BATTERY);
168 customEvent.setLabel(label);
169 customEvent.sendWithSampling();
172 private void getLastInfo() {
174 if (mInfoFile.exists()) {
175 String fileString = readFileAsString(mInfoFile.getPath());
176 mInfoJson = new JSONObject(fileString);
178 mInfoJson = new JSONObject();
180 } catch (Exception e) {
181 Log.e(TAG, "fail to get last info file", e);
185 private boolean isDifferentInfo(String key, String value) {
187 if (mInfoJson.has(key)) {
188 String lastValue = mInfoJson.getString(key);
189 return lastValue == null || !lastValue.equals(value);
191 } catch (Exception e) {
192 Log.e(TAG, "check info failed", e);
197 private void checkAndSend(String key, String value) {
198 if (isDifferentInfo(key, value)) {
199 sendToGA(key, value);
200 saveInfo(key, value);
204 private void sendToGA(String action, String label) {
205 AnalyticsHelper.CustomEvent customEvent =
206 AnalyticsHelper.newSystemCoreEvent(mContext, GA_CATEGORY, action);
207 customEvent.setLabel(label);
208 customEvent.sendWithoutSampling();
211 private void sendToAnalytics(String key, String value) {
212 GeneralLogs logs = new GeneralLogs();
213 logs.set(key, value);
214 AnalyticsHelper.uploadLogToLogServer(mContext, logs);
217 private void saveInfo(String key, String value) {
219 mInfoJson.put(key, value);
220 writeStringToFile(mInfoFile.getPath(), mInfoJson.toString());
221 } catch (Exception e) {
222 Log.e(TAG, "write info file failed", e);
226 public static void writeStringToFile(String filePath, String sets) throws IOException {
227 FileWriter fileWriter = new FileWriter(filePath);
228 PrintWriter out = new PrintWriter(fileWriter);
235 private static String readFileAsString(String filePath) throws IOException {
236 StringBuffer fileData = new StringBuffer();
237 BufferedReader reader = new BufferedReader(new FileReader(filePath));
238 char[] buf = new char[1024];
240 while ((count = reader.read(buf)) != -1) {
241 String readData = String.valueOf(buf, 0, count);
242 fileData.append(readData);
245 return fileData.toString();