OSDN Git Service

HardwareCollector: send hardware information to GA
[android-x86/packages-services-Analytics.git] / HardwareCollector / src / org / android_x86 / hardwarecollector / HardwareCollectorService.java
1 /*
2  * Copyright 2016 Jide Technology Ltd.
3  *
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
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16 package org.android_x86.hardwarecollector;
17
18 import org.android_x86.analytics.AnalyticsHelper;
19 import org.android_x86.analytics.GeneralLogs;
20
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;
31
32 import org.json.JSONObject;
33
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;
40 import java.io.File;
41 import java.io.FileReader;
42 import java.io.FileWriter;
43 import java.io.IOException;
44 import java.io.PrintWriter;
45
46 public class HardwareCollectorService extends IntentService {
47     private static final String TAG = "HardwareCollectorService";
48
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";
56
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;
61
62     private Context mContext;
63     private File mInfoFile;
64     private JSONObject mInfoJson;
65
66     public HardwareCollectorService() {
67         super("HardwareCollectorService");
68     }
69
70     @Override
71     public void onCreate() {
72         super.onCreate();
73         mContext = getBaseContext();
74         mInfoFile = new File(getApplicationContext().getFilesDir(), LAST_INFO_FILE_NAME);
75     }
76
77     @Override
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)) {
82             uploadHardwareInfo();
83         }
84     }
85
86     private void uploadHardwareInfo() {
87         getLastInfo();
88         collectOpenGLInfo();
89         collectCPUInfo();
90         collectTouchScreenInfo();
91         collectBatteryInfo();
92     }
93
94     private void collectOpenGLInfo() {
95         try {
96             EGL10 egl = (EGL10) EGLContext.getEGL();
97             EGLSurface eglSurface = null;
98             EGLContext eglContext = null;
99
100             // initialize display
101             EGLDisplay eglDisplay = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
102             int[] iparam = new int[2];
103             egl.eglInitialize(eglDisplay, iparam);
104
105             // choose config
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)
110                     && iparam[0] > 0) {
111                 // create surface
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) {
116                     // create context
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);
121                 }
122             }
123
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);
127         }
128     }
129
130     private void collectCPUInfo() {
131         try {
132             BufferedReader reader = new BufferedReader(new FileReader(CPU_INFO_FILE));
133             String cpuInfo;
134             String model = null;
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);
139                     break;
140                 }
141             }
142             reader.close();
143         } catch (Exception e) {
144             Log.e(TAG, "fail to get CPU model name", e);
145         }
146     }
147
148     private void collectTouchScreenInfo() {
149         int[] ids = InputManager.getInstance().getInputDeviceIds();
150         for (int id : ids) {
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);
155                 break;
156             }
157         }
158     }
159
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();
170     }
171
172     private void getLastInfo() {
173         try {
174             if (mInfoFile.exists()) {
175                 String fileString = readFileAsString(mInfoFile.getPath());
176                 mInfoJson = new JSONObject(fileString);
177             } else {
178                 mInfoJson = new JSONObject();
179             }
180         } catch (Exception e) {
181             Log.e(TAG, "fail to get last info file", e);
182         }
183     }
184
185     private boolean isDifferentInfo(String key, String value) {
186         try {
187             if (mInfoJson.has(key)) {
188                 String lastValue = mInfoJson.getString(key);
189                 return lastValue == null || !lastValue.equals(value);
190             }
191         } catch (Exception e) {
192             Log.e(TAG, "check info failed", e);
193         }
194         return true;
195     }
196
197     private void checkAndSend(String key, String value) {
198         if (isDifferentInfo(key, value)) {
199             sendToGA(key, value);
200             saveInfo(key, value);
201         }
202     }
203
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();
209     }
210
211     private void sendToAnalytics(String key, String value) {
212         GeneralLogs logs = new GeneralLogs();
213         logs.set(key, value);
214         AnalyticsHelper.uploadLogToLogServer(mContext, logs);
215     }
216
217     private void saveInfo(String key, String value) {
218         try {
219             mInfoJson.put(key, value);
220             writeStringToFile(mInfoFile.getPath(), mInfoJson.toString());
221         } catch (Exception e) {
222             Log.e(TAG, "write info file failed", e);
223         }
224     }
225
226     public static void writeStringToFile(String filePath, String sets) throws IOException {
227         FileWriter fileWriter = new FileWriter(filePath);
228         PrintWriter out = new PrintWriter(fileWriter);
229         out.write(sets);
230         out.println();
231         fileWriter.close();
232         out.close();
233     }
234
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];
239         int count = 0;
240         while ((count = reader.read(buf)) != -1) {
241             String readData = String.valueOf(buf, 0, count);
242             fileData.append(readData);
243         }
244         reader.close();
245         return fileData.toString();
246     }
247 }