frameworks/base
修訂 | 6cefdd607aaa7a9e25f551013630100a6e221fd9 (tree) |
---|---|
時間 | 2013-09-25 12:02:23 |
作者 | Chih-Wei Huang <cwhuang@linu...> |
Commiter | Chih-Wei Huang |
Merge branch 'android-ia3' into jb-x86
@@ -363,6 +363,15 @@ public abstract class PackageManager { | ||
363 | 363 | public static final int INSTALL_SUCCEEDED = 1; |
364 | 364 | |
365 | 365 | /** |
366 | + * Native Library Copy return code: this is passed to {@link PackageManagerService} by | |
367 | + * {@link NativeLibararyHelper} on successful copy of native library. | |
368 | + * It indicates that the native library being copied matches 2nd ABI. | |
369 | + * @hide | |
370 | + */ | |
371 | + | |
372 | + public static final int INSTALL_ABI2_SUCCEEDED = 2; | |
373 | + | |
374 | + /** | |
366 | 375 | * Installation return code: this is passed to the {@link IPackageInstallObserver} by |
367 | 376 | * {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)} if the package is |
368 | 377 | * already installed. |
@@ -16,7 +16,9 @@ | ||
16 | 16 | |
17 | 17 | package com.android.internal.content; |
18 | 18 | |
19 | +import android.content.pm.PackageManager; | |
19 | 20 | import android.os.Build; |
21 | +import android.os.SystemProperties; | |
20 | 22 | import android.util.Slog; |
21 | 23 | |
22 | 24 | import java.io.File; |
@@ -42,9 +44,49 @@ public class NativeLibraryHelper { | ||
42 | 44 | public static long sumNativeBinariesLI(File apkFile) { |
43 | 45 | final String cpuAbi = Build.CPU_ABI; |
44 | 46 | final String cpuAbi2 = Build.CPU_ABI2; |
45 | - return nativeSumNativeBinaries(apkFile.getPath(), cpuAbi, cpuAbi2); | |
47 | + | |
48 | + String abi2 = SystemProperties.get("ro.product.cpu.abi2"); | |
49 | + if (abi2.length() == 0) { | |
50 | + return nativeSumNativeBinaries(apkFile.getPath(), cpuAbi, cpuAbi2); | |
51 | + } else { | |
52 | + // abi2 is set, houdini is enabled | |
53 | + long result = nativeSumNativeBinaries(apkFile.getPath(), cpuAbi, cpuAbi2); | |
54 | + if (result == 0) { | |
55 | + String abiUpgrade = SystemProperties.get("ro.product.cpu.upgradeabi", "armeabi"); | |
56 | + result = nativeSumNativeBinaries(apkFile.getPath(), cpuAbi, abiUpgrade); | |
57 | + } | |
58 | + return result; | |
59 | + } | |
46 | 60 | } |
47 | 61 | |
62 | + private static native int nativeListNativeBinaries(String file, String cpuAbi, String cpuAbi2); | |
63 | + | |
64 | + /** | |
65 | + * List the native binaries info in an APK. | |
66 | + * | |
67 | + * @param apkFile APK file to scan for native libraries | |
68 | + * @return {@link PackageManager#INSTALL_SUCCEEDED} or {@link PackageManager#INSTALL_ABI2_SUCCEEDED} | |
69 | + * or another error code from that class if not | |
70 | + */ | |
71 | + public static int listNativeBinariesLI(File apkFile) { | |
72 | + final String cpuAbi = Build.CPU_ABI; | |
73 | + final String cpuAbi2 = Build.CPU_ABI2; | |
74 | + | |
75 | + String abi2 = SystemProperties.get("ro.product.cpu.abi2"); | |
76 | + if (abi2.length() == 0) { | |
77 | + return nativeListNativeBinaries(apkFile.getPath(), cpuAbi, cpuAbi2); | |
78 | + } else { | |
79 | + // abi2 is set, houdini is enabled | |
80 | + int result = nativeListNativeBinaries(apkFile.getPath(), cpuAbi, cpuAbi2); | |
81 | + if ((result != PackageManager.INSTALL_SUCCEEDED) && (result != PackageManager.INSTALL_ABI2_SUCCEEDED)) { | |
82 | + String abiUpgrade = SystemProperties.get("ro.product.cpu.upgradeabi", "armeabi"); | |
83 | + result = nativeListNativeBinaries(apkFile.getPath(), cpuAbi, abiUpgrade); | |
84 | + } | |
85 | + return result; | |
86 | + } | |
87 | + } | |
88 | + | |
89 | + | |
48 | 90 | private native static int nativeCopyNativeBinaries(String filePath, String sharedLibraryPath, |
49 | 91 | String cpuAbi, String cpuAbi2); |
50 | 92 |
@@ -53,14 +95,25 @@ public class NativeLibraryHelper { | ||
53 | 95 | * |
54 | 96 | * @param apkFile APK file to scan for native libraries |
55 | 97 | * @param sharedLibraryDir directory for libraries to be copied to |
56 | - * @return {@link PackageManager#INSTALL_SUCCEEDED} if successful or another | |
57 | - * error code from that class if not | |
98 | + * @return {@link PackageManager#INSTALL_SUCCEEDED} or {@link PackageManager#INSTALL_ABI2_SUCCEEDED} | |
99 | + * if successful or another error code from that class if not | |
58 | 100 | */ |
59 | 101 | public static int copyNativeBinariesIfNeededLI(File apkFile, File sharedLibraryDir) { |
60 | 102 | final String cpuAbi = Build.CPU_ABI; |
61 | 103 | final String cpuAbi2 = Build.CPU_ABI2; |
62 | - return nativeCopyNativeBinaries(apkFile.getPath(), sharedLibraryDir.getPath(), cpuAbi, | |
63 | - cpuAbi2); | |
104 | + | |
105 | + String abi2 = SystemProperties.get("ro.product.cpu.abi2"); | |
106 | + if (abi2.length() == 0) { | |
107 | + return nativeCopyNativeBinaries(apkFile.getPath(), sharedLibraryDir.getPath(), cpuAbi, cpuAbi2); | |
108 | + } else { | |
109 | + // abi2 is set, houdini is enabled | |
110 | + int result = nativeCopyNativeBinaries(apkFile.getPath(), sharedLibraryDir.getPath(), cpuAbi, cpuAbi2); | |
111 | + if ((result != PackageManager.INSTALL_SUCCEEDED) && (result != PackageManager.INSTALL_ABI2_SUCCEEDED)) { | |
112 | + String abiUpgrade = SystemProperties.get("ro.product.cpu.upgradeabi", "armeabi"); | |
113 | + result = nativeCopyNativeBinaries(apkFile.getPath(), sharedLibraryDir.getPath(), cpuAbi, abiUpgrade); | |
114 | + } | |
115 | + return result; | |
116 | + } | |
64 | 117 | } |
65 | 118 | |
66 | 119 | // Convenience method to call removeNativeBinariesFromDirLI(File) |
@@ -11,6 +11,11 @@ else | ||
11 | 11 | LOCAL_CFLAGS += -DPACKED="" |
12 | 12 | endif |
13 | 13 | |
14 | +ifeq ($(INTEL_HOUDINI), true) | |
15 | + LOCAL_CFLAGS += -DWITH_HOUDINI | |
16 | + LOCAL_STATIC_LIBRARIES += libhoudini_hook | |
17 | +endif | |
18 | + | |
14 | 19 | ifeq ($(USE_OPENGL_RENDERER),true) |
15 | 20 | LOCAL_CFLAGS += -DUSE_OPENGL_RENDERER |
16 | 21 | endif |
@@ -43,6 +43,7 @@ bool YuvToJpegEncoder::encode(SkWStream* stream, void* inYuv, int width, | ||
43 | 43 | compress(&cinfo, (uint8_t*) inYuv, offsets); |
44 | 44 | |
45 | 45 | jpeg_finish_compress(&cinfo); |
46 | + jpeg_destroy_compress(&cinfo); | |
46 | 47 | |
47 | 48 | return true; |
48 | 49 | } |
@@ -41,6 +41,14 @@ | ||
41 | 41 | #define LOG_TRACE(...) |
42 | 42 | //#define LOG_TRACE(...) ALOG(LOG_DEBUG, LOG_TAG, __VA_ARGS__) |
43 | 43 | |
44 | +#ifdef WITH_HOUDINI | |
45 | +namespace houdini { | |
46 | +void* hookDlopen(const char* filename, int flag, bool* useHoudini); | |
47 | +void* hookDlsym(bool useHoudini, void* handle, const char* symbol); | |
48 | +void hookCreateActivity(bool useHoudini, void* createActivityFunc, void* activity, void*houdiniActivity, void* savedState, size_t savedStateSize); | |
49 | +} | |
50 | +#endif | |
51 | + | |
44 | 52 | namespace android |
45 | 53 | { |
46 | 54 |
@@ -109,6 +117,9 @@ struct NativeCode : public ANativeActivity { | ||
109 | 117 | createActivityFunc = _createFunc; |
110 | 118 | nativeWindow = NULL; |
111 | 119 | mainWorkRead = mainWorkWrite = -1; |
120 | +#ifdef WITH_HOUDINI | |
121 | + houdiniNativeActivity = NULL; | |
122 | +#endif | |
112 | 123 | } |
113 | 124 | |
114 | 125 | ~NativeCode() { |
@@ -130,6 +141,10 @@ struct NativeCode : public ANativeActivity { | ||
130 | 141 | // is really no benefit to unloading the code. |
131 | 142 | //dlclose(dlhandle); |
132 | 143 | } |
144 | +#ifdef WITH_HOUDINI | |
145 | + if (houdiniNativeActivity != NULL) | |
146 | + delete houdiniNativeActivity; | |
147 | +#endif | |
133 | 148 | } |
134 | 149 | |
135 | 150 | void setSurface(jobject _surface) { |
@@ -157,6 +172,9 @@ struct NativeCode : public ANativeActivity { | ||
157 | 172 | int mainWorkRead; |
158 | 173 | int mainWorkWrite; |
159 | 174 | sp<MessageQueue> messageQueue; |
175 | +#ifdef WITH_HOUDINI | |
176 | + ANativeActivity *houdiniNativeActivity; | |
177 | +#endif | |
160 | 178 | }; |
161 | 179 | |
162 | 180 | void android_NativeActivity_finish(ANativeActivity* activity) { |
@@ -252,14 +270,24 @@ loadNativeCode_native(JNIEnv* env, jobject clazz, jstring path, jstring funcName | ||
252 | 270 | const char* pathStr = env->GetStringUTFChars(path, NULL); |
253 | 271 | NativeCode* code = NULL; |
254 | 272 | |
273 | +#ifdef WITH_HOUDINI | |
274 | + bool useHoudini = false; | |
275 | + void* handle = houdini::hookDlopen(pathStr, RTLD_LAZY, &useHoudini); | |
276 | +#else | |
255 | 277 | void* handle = dlopen(pathStr, RTLD_LAZY); |
278 | +#endif | |
256 | 279 | |
257 | 280 | env->ReleaseStringUTFChars(path, pathStr); |
258 | 281 | |
259 | 282 | if (handle != NULL) { |
260 | 283 | const char* funcStr = env->GetStringUTFChars(funcName, NULL); |
284 | +#ifdef WITH_HOUDINI | |
285 | + code = new NativeCode(handle, (ANativeActivity_createFunc*) | |
286 | + houdini::hookDlsym(useHoudini, handle, funcStr)); | |
287 | +#else | |
261 | 288 | code = new NativeCode(handle, (ANativeActivity_createFunc*) |
262 | 289 | dlsym(handle, funcStr)); |
290 | +#endif | |
263 | 291 | env->ReleaseStringUTFChars(funcName, funcStr); |
264 | 292 | |
265 | 293 | if (code->createActivityFunc == NULL) { |
@@ -327,7 +355,21 @@ loadNativeCode_native(JNIEnv* env, jobject clazz, jstring path, jstring funcName | ||
327 | 355 | rawSavedSize = env->GetArrayLength(savedState); |
328 | 356 | } |
329 | 357 | |
358 | +#ifdef WITH_HOUDINI | |
359 | + if (useHoudini) { | |
360 | + /* | |
361 | + * If houdini is used, code is used by x86 code. So we create | |
362 | + * a houdini version for code. x86 version will store peer's | |
363 | + * pointer in houdiniNativeActivity each other. | |
364 | + */ | |
365 | + code->houdiniNativeActivity = new ANativeActivity; | |
366 | + *code->houdiniNativeActivity = *(ANativeActivity *)code; | |
367 | + } | |
368 | + | |
369 | + houdini::hookCreateActivity(useHoudini, (void*)code->createActivityFunc, (void*)code, (void*)code->houdiniNativeActivity, (void*)rawSavedState, rawSavedSize); | |
370 | +#else | |
330 | 371 | code->createActivityFunc(code, rawSavedState, rawSavedSize); |
372 | +#endif | |
331 | 373 | |
332 | 374 | if (rawSavedState != NULL) { |
333 | 375 | env->ReleaseByteArrayElements(savedState, rawSavedState, 0); |
@@ -54,8 +54,14 @@ namespace android { | ||
54 | 54 | // These match PackageManager.java install codes |
55 | 55 | typedef enum { |
56 | 56 | INSTALL_SUCCEEDED = 1, |
57 | +#ifdef WITH_HOUDINI | |
58 | + INSTALL_ABI2_SUCCEEDED = 2, | |
59 | +#endif | |
57 | 60 | INSTALL_FAILED_INVALID_APK = -2, |
58 | 61 | INSTALL_FAILED_INSUFFICIENT_STORAGE = -4, |
62 | +#ifdef WITH_HOUDINI | |
63 | + INSTALL_FAILED_CPU_ABI_INCOMPATIBLE = -16, | |
64 | +#endif | |
59 | 65 | INSTALL_FAILED_CONTAINER_ERROR = -18, |
60 | 66 | INSTALL_FAILED_INTERNAL_ERROR = -110, |
61 | 67 | } install_status_t; |
@@ -157,6 +163,14 @@ sumFiles(JNIEnv* env, void* arg, ZipFileRO* zipFile, ZipEntryRO zipEntry, const | ||
157 | 163 | return INSTALL_SUCCEEDED; |
158 | 164 | } |
159 | 165 | |
166 | +#ifdef WITH_HOUDINI | |
167 | +static install_status_t | |
168 | +listFiles(JNIEnv* env, void* arg, ZipFileRO* zipFile, ZipEntryRO zipEntry, const char* fileName) | |
169 | +{ | |
170 | + return INSTALL_SUCCEEDED; | |
171 | +} | |
172 | +#endif | |
173 | + | |
160 | 174 | /* |
161 | 175 | * Copy the native library if needed. |
162 | 176 | * |
@@ -284,6 +298,10 @@ iterateOverNativeFiles(JNIEnv *env, jstring javaFilePath, jstring javaCpuAbi, js | ||
284 | 298 | |
285 | 299 | char fileName[PATH_MAX]; |
286 | 300 | bool hasPrimaryAbi = false; |
301 | +#ifdef WITH_HOUDINI | |
302 | + bool useSecondaryAbi = false; | |
303 | + bool noMatchAbi = false; | |
304 | +#endif | |
287 | 305 | |
288 | 306 | for (int i = 0; i < N; i++) { |
289 | 307 | const ZipEntryRO entry = zipFile.findEntryByIndex(i); |
@@ -333,9 +351,15 @@ iterateOverNativeFiles(JNIEnv *env, jstring javaFilePath, jstring javaCpuAbi, js | ||
333 | 351 | ALOGV("Already saw primary ABI, skipping secondary ABI %s\n", cpuAbi2.c_str()); |
334 | 352 | continue; |
335 | 353 | } else { |
354 | +#ifdef WITH_HOUDINI | |
355 | + useSecondaryAbi = true; | |
356 | +#endif | |
336 | 357 | ALOGV("Using secondary ABI %s\n", cpuAbi2.c_str()); |
337 | 358 | } |
338 | 359 | } else { |
360 | +#ifdef WITH_HOUDINI | |
361 | + noMatchAbi = true; | |
362 | +#endif | |
339 | 363 | ALOGV("abi didn't match anything: %s (end at %zd)\n", cpuAbiOffset, cpuAbiRegionSize); |
340 | 364 | continue; |
341 | 365 | } |
@@ -355,6 +379,14 @@ iterateOverNativeFiles(JNIEnv *env, jstring javaFilePath, jstring javaCpuAbi, js | ||
355 | 379 | } |
356 | 380 | } |
357 | 381 | |
382 | +#ifdef WITH_HOUDINI | |
383 | + if (!hasPrimaryAbi && !useSecondaryAbi && noMatchAbi) | |
384 | + return INSTALL_FAILED_CPU_ABI_INCOMPATIBLE; | |
385 | + | |
386 | + if (!hasPrimaryAbi && useSecondaryAbi) | |
387 | + return INSTALL_ABI2_SUCCEEDED; | |
388 | +#endif | |
389 | + | |
358 | 390 | return INSTALL_SUCCEEDED; |
359 | 391 | } |
360 | 392 |
@@ -377,6 +409,15 @@ com_android_internal_content_NativeLibraryHelper_sumNativeBinaries(JNIEnv *env, | ||
377 | 409 | return totalSize; |
378 | 410 | } |
379 | 411 | |
412 | +#ifdef WITH_HOUDINI | |
413 | +static jint | |
414 | +com_android_internal_content_NativeLibraryHelper_listNativeBinaries(JNIEnv *env, jclass clazz, | |
415 | + jstring javaFilePath, jstring javaCpuAbi, jstring javaCpuAbi2) | |
416 | +{ | |
417 | + return (jint) iterateOverNativeFiles(env, javaFilePath, javaCpuAbi, javaCpuAbi2, listFiles, NULL); | |
418 | +} | |
419 | +#endif | |
420 | + | |
380 | 421 | static JNINativeMethod gMethods[] = { |
381 | 422 | {"nativeCopyNativeBinaries", |
382 | 423 | "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)I", |
@@ -384,6 +425,11 @@ static JNINativeMethod gMethods[] = { | ||
384 | 425 | {"nativeSumNativeBinaries", |
385 | 426 | "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)J", |
386 | 427 | (void *)com_android_internal_content_NativeLibraryHelper_sumNativeBinaries}, |
428 | +#ifdef WITH_HOUDINI | |
429 | + {"nativeListNativeBinaries", | |
430 | + "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)I", | |
431 | + (void *)com_android_internal_content_NativeLibraryHelper_listNativeBinaries}, | |
432 | +#endif | |
387 | 433 | }; |
388 | 434 | |
389 | 435 |
@@ -144,8 +144,8 @@ key 121 NUMPAD_COMMA | ||
144 | 144 | key 122 KANA |
145 | 145 | key 123 EISU |
146 | 146 | key 124 YEN |
147 | -key 125 META_LEFT | |
148 | -key 126 META_RIGHT | |
147 | +key 125 HOME | |
148 | +key 126 HOME | |
149 | 149 | key 127 MENU WAKE_DROPPED |
150 | 150 | key 128 MEDIA_STOP |
151 | 151 | # key 129 "KEY_AGAIN" |
@@ -255,12 +255,28 @@ Layer* LayerRenderer::createLayer(uint32_t width, uint32_t height, bool isOpaque | ||
255 | 255 | |
256 | 256 | // Initialize the texture if needed |
257 | 257 | if (layer->isEmpty()) { |
258 | + int an_error; | |
259 | + int num_errors; | |
260 | + /* | |
261 | + * Make sure there is no stale error leftover from some previous code | |
262 | + * sequence before we embark on this series of gl operations. | |
263 | + */ | |
264 | + while ((an_error = glGetError()) != GL_NO_ERROR) { | |
265 | + ALOGD("createLayer clearing stale error code 0x%04x", an_error); | |
266 | + } | |
267 | + | |
258 | 268 | layer->setEmpty(false); |
259 | 269 | layer->allocateTexture(); |
260 | 270 | |
261 | - // This should only happen if we run out of memory | |
262 | - if (glGetError() != GL_NO_ERROR) { | |
263 | - ALOGE("Could not allocate texture for layer (fbo=%d %dx%d)", fbo, width, height); | |
271 | + /* Detect and clear errors from setEmpty(), allocateTexture() */ | |
272 | + num_errors = 0; | |
273 | + while ((an_error = glGetError()) != GL_NO_ERROR) { | |
274 | + num_errors++; | |
275 | + ALOGD("Could not allocate texture for layer (fbo=%d %dx%d)" | |
276 | + " (error=0x%04x)", | |
277 | + fbo, width, height, an_error); | |
278 | + } | |
279 | + if (num_errors != 0) { | |
264 | 280 | glBindFramebuffer(GL_FRAMEBUFFER, previousFbo); |
265 | 281 | caches.resourceCache.decrementRefcount(layer); |
266 | 282 | return NULL; |
@@ -496,7 +496,7 @@ public class AudioManager { | ||
496 | 496 | if (mUseMasterVolume) { |
497 | 497 | setMasterMute(!isMasterMute()); |
498 | 498 | } else { |
499 | - // TODO: Actually handle MUTE. | |
499 | + setMasterMute(!isMasterMute()); | |
500 | 500 | } |
501 | 501 | } |
502 | 502 | break; |
@@ -940,7 +940,7 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback | ||
940 | 940 | int a = findConfigAttrib(egl, display, config, |
941 | 941 | EGL10.EGL_ALPHA_SIZE, 0); |
942 | 942 | if ((r == mRedSize) && (g == mGreenSize) |
943 | - && (b == mBlueSize) && (a == mAlphaSize)) { | |
943 | + && (b == mBlueSize) && (a >= mAlphaSize)) { | |
944 | 944 | return config; |
945 | 945 | } |
946 | 946 | } |
@@ -403,7 +403,7 @@ public class DefaultContainerService extends IntentService { | ||
403 | 403 | final File sharedLibraryDir = new File(newCachePath, LIB_DIR_NAME); |
404 | 404 | if (sharedLibraryDir.mkdir()) { |
405 | 405 | int ret = NativeLibraryHelper.copyNativeBinariesIfNeededLI(codeFile, sharedLibraryDir); |
406 | - if (ret != PackageManager.INSTALL_SUCCEEDED) { | |
406 | + if ((ret != PackageManager.INSTALL_SUCCEEDED) && (ret != PackageManager.INSTALL_ABI2_SUCCEEDED)) { | |
407 | 407 | Slog.e(TAG, "Could not copy native libraries to " + sharedLibraryDir.getPath()); |
408 | 408 | PackageHelper.destroySdDir(newCid); |
409 | 409 | return null; |
@@ -40,6 +40,7 @@ | ||
40 | 40 | <uses-permission android:name="android.permission.UPDATE_DEVICE_STATS" /> |
41 | 41 | <uses-permission android:name="android.permission.MASTER_CLEAR" /> |
42 | 42 | <uses-permission android:name="android.permission.VIBRATE" /> |
43 | + <uses-permission android:name="android.permission.SHUTDOWN" /> | |
43 | 44 | |
44 | 45 | <!-- ActivityManager --> |
45 | 46 | <uses-permission android:name="android.permission.GET_TASKS" /> |
@@ -0,0 +1,25 @@ | ||
1 | +<?xml version="1.0" encoding="utf-8"?> | |
2 | +<!-- Copyright (C) 2012 The Android Open Source Project | |
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 | +<TextView | |
17 | + xmlns:android="http://schemas.android.com/apk/res/android" | |
18 | + style="@style/TextAppearance.QuickSettings.TileView" | |
19 | + android:id="@+id/poweroff_tileview" | |
20 | + android:layout_width="wrap_content" | |
21 | + android:layout_height="wrap_content" | |
22 | + android:layout_gravity="center" | |
23 | + android:gravity="center" | |
24 | + android:drawableTop="@android:drawable/ic_lock_power_off" | |
25 | + /> | |
\ No newline at end of file |
@@ -514,6 +514,8 @@ | ||
514 | 514 | <string name="quick_settings_brightness_dialog_title">Brightness</string> |
515 | 515 | <!-- QuickSettings: Brightness dialog auto brightness button [CHAR LIMIT=NONE] --> |
516 | 516 | <string name="quick_settings_brightness_dialog_auto_brightness_label">AUTO</string> |
517 | + <!-- QuickSettings: Power Off [CHAR LIMIT=NONE] --> | |
518 | + <string name="quick_settings_poweroff_label">Power Off</string> | |
517 | 519 | |
518 | 520 | <!-- Title of help text shown when the notification panel is pulled down for the very first time. [CHAR LIMIT=NONE] --> |
519 | 521 | <string name="status_bar_help_title">Notifications appear here</string> |
@@ -622,7 +622,7 @@ public class ImageWallpaper extends WallpaperService { | ||
622 | 622 | |
623 | 623 | mEglConfig = chooseEglConfig(); |
624 | 624 | if (mEglConfig == null) { |
625 | - throw new RuntimeException("eglConfig not initialized"); | |
625 | + return false; | |
626 | 626 | } |
627 | 627 | |
628 | 628 | mEglContext = createContext(mEgl, mEglDisplay, mEglConfig); |
@@ -587,6 +587,24 @@ class QuickSettings { | ||
587 | 587 | parent.addView(bluetoothTile); |
588 | 588 | } |
589 | 589 | |
590 | + // Power off | |
591 | + QuickSettingsTileView powerOffTile = (QuickSettingsTileView) | |
592 | + inflater.inflate(R.layout.quick_settings_tile, parent, false); | |
593 | + powerOffTile.setContent(R.layout.quick_settings_tile_poweroff, inflater); | |
594 | + powerOffTile.setOnClickListener(new View.OnClickListener() { | |
595 | + @Override | |
596 | + public void onClick(View v) { | |
597 | + onClickPowerOff(); | |
598 | + } | |
599 | + }); | |
600 | + mModel.addPowerOffTile(powerOffTile, new QuickSettingsModel.RefreshCallback() { | |
601 | + @Override | |
602 | + public void refreshView(QuickSettingsTileView view, State state) { | |
603 | + TextView tv = (TextView) view.findViewById(R.id.poweroff_tileview); | |
604 | + tv.setText(state.label); | |
605 | + } | |
606 | + }); | |
607 | + parent.addView(powerOffTile); | |
590 | 608 | } |
591 | 609 | |
592 | 610 | private void addTemporaryTiles(final ViewGroup parent, final LayoutInflater inflater) { |
@@ -832,4 +850,31 @@ class QuickSettings { | ||
832 | 850 | |
833 | 851 | } |
834 | 852 | }; |
853 | + | |
854 | + // Power off | |
855 | + // ---------------------------- | |
856 | + private void onClickPowerOff() { | |
857 | + if (mBar != null) { | |
858 | + mBar.collapseAllPanels(true); | |
859 | + } | |
860 | + | |
861 | + // Create dialog to get user confirmation | |
862 | + final AlertDialog dialog = new AlertDialog.Builder(mContext) | |
863 | + .setTitle(com.android.internal.R.string.power_off) | |
864 | + .setMessage(com.android.internal.R.string.shutdown_confirm_question) | |
865 | + .setPositiveButton(com.android.internal.R.string.yes, | |
866 | + new DialogInterface.OnClickListener() { | |
867 | + public void onClick(DialogInterface dialog, int which) { | |
868 | + // Send request to start ShutdownActivity | |
869 | + Intent intent = new Intent(Intent.ACTION_REQUEST_SHUTDOWN); | |
870 | + intent.putExtra(Intent.EXTRA_KEY_CONFIRM, false); | |
871 | + intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); | |
872 | + mContext.startActivity(intent); | |
873 | + } | |
874 | + }) | |
875 | + .setNegativeButton(com.android.internal.R.string.no, null) | |
876 | + .create(); | |
877 | + dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG); | |
878 | + dialog.show(); | |
879 | + } | |
835 | 880 | } |
@@ -259,6 +259,10 @@ class QuickSettingsModel implements BluetoothStateChangeCallback, | ||
259 | 259 | private RefreshCallback mSettingsCallback; |
260 | 260 | private State mSettingsState = new State(); |
261 | 261 | |
262 | + private QuickSettingsTileView mPowerOffTile; | |
263 | + private RefreshCallback mPowerOffCallback; | |
264 | + private State mPowerOffState = new State(); | |
265 | + | |
262 | 266 | public QuickSettingsModel(Context context) { |
263 | 267 | mContext = context; |
264 | 268 | mHandler = new Handler(); |
@@ -731,4 +735,17 @@ class QuickSettingsModel implements BluetoothStateChangeCallback, | ||
731 | 735 | void refreshBrightnessTile() { |
732 | 736 | onBrightnessLevelChanged(); |
733 | 737 | } |
738 | + | |
739 | + // Power off | |
740 | + void addPowerOffTile(QuickSettingsTileView view, RefreshCallback cb) { | |
741 | + mPowerOffTile = view; | |
742 | + mPowerOffCallback = cb; | |
743 | + refreshPowerOffTile(); | |
744 | + } | |
745 | + void refreshPowerOffTile() { | |
746 | + Resources r = mContext.getResources(); | |
747 | + mPowerOffState.label = r.getString(R.string.quick_settings_poweroff_label); | |
748 | + mPowerOffCallback.refreshView(mPowerOffTile, mPowerOffState); | |
749 | + } | |
750 | + | |
734 | 751 | } |
@@ -1009,8 +1009,17 @@ static const int32_t GAMEPAD_KEYCODES[] = { | ||
1009 | 1009 | }; |
1010 | 1010 | |
1011 | 1011 | status_t EventHub::openDeviceLocked(const char *devicePath) { |
1012 | + return openDeviceLocked(devicePath, false); | |
1013 | +} | |
1014 | + | |
1015 | +status_t EventHub::openDeviceLocked(const char *devicePath, bool ignoreAlreadyOpened) { | |
1012 | 1016 | char buffer[80]; |
1013 | 1017 | |
1018 | + if (ignoreAlreadyOpened && (getDeviceByPathLocked(devicePath) != 0)) { | |
1019 | + ALOGV("Ignoring device '%s' that has already been opened.", devicePath); | |
1020 | + return 0; | |
1021 | + } | |
1022 | + | |
1014 | 1023 | ALOGV("Opening device: %s", devicePath); |
1015 | 1024 | |
1016 | 1025 | int fd = open(devicePath, O_RDWR | O_CLOEXEC); |
@@ -1208,7 +1217,11 @@ status_t EventHub::openDeviceLocked(const char *devicePath) { | ||
1208 | 1217 | |
1209 | 1218 | // 'Q' key support = cheap test of whether this is an alpha-capable kbd |
1210 | 1219 | if (hasKeycodeLocked(device, AKEYCODE_Q)) { |
1211 | - device->classes |= INPUT_DEVICE_CLASS_ALPHAKEY; | |
1220 | + char value[PROPERTY_VALUE_MAX]; | |
1221 | + property_get("ro.ignore_atkbd", value, "0"); | |
1222 | + if ((device->identifier.name != "AT Translated Set 2 keyboard") || (!atoi(value))) { | |
1223 | + device->classes |= INPUT_DEVICE_CLASS_ALPHAKEY; | |
1224 | + } | |
1212 | 1225 | } |
1213 | 1226 | |
1214 | 1227 | // See if this device has a DPAD. |
@@ -1476,7 +1489,7 @@ status_t EventHub::readNotifyLocked() { | ||
1476 | 1489 | if(event->len) { |
1477 | 1490 | strcpy(filename, event->name); |
1478 | 1491 | if(event->mask & IN_CREATE) { |
1479 | - openDeviceLocked(devname); | |
1492 | + openDeviceLocked(devname, true); | |
1480 | 1493 | } else { |
1481 | 1494 | ALOGI("Removing device '%s' due to inotify event\n", devname); |
1482 | 1495 | closeDeviceByPathLocked(devname); |
@@ -362,6 +362,7 @@ private: | ||
362 | 362 | }; |
363 | 363 | |
364 | 364 | status_t openDeviceLocked(const char *devicePath); |
365 | + status_t openDeviceLocked(const char *devicePath, bool ignoreAlreadyOpened); | |
365 | 366 | void createVirtualKeyboardLocked(); |
366 | 367 | void addDeviceLocked(Device* device); |
367 | 368 |
@@ -0,0 +1,46 @@ | ||
1 | +package com.android.server.pm; | |
2 | +/* | |
3 | + * Copyright (C) 2006 The Android Open Source Project | |
4 | + * | |
5 | + * Licensed under the Apache License, Version 2.0 (the "License"); | |
6 | + * you may not use this file except in compliance with the License. | |
7 | + * You may obtain a copy of the License at | |
8 | + * | |
9 | + * http://www.apache.org/licenses/LICENSE-2.0 | |
10 | + * | |
11 | + * Unless required by applicable law or agreed to in writing, software | |
12 | + * distributed under the License is distributed on an "AS IS" BASIS, | |
13 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
14 | + * See the License for the specific language governing permissions and | |
15 | + * limitations under the License. | |
16 | + */ | |
17 | + | |
18 | +import java.util.List; | |
19 | +import java.util.ArrayList; | |
20 | + | |
21 | +/* | |
22 | + * class CheckExt is trying to check params | |
23 | + */ | |
24 | +public class CheckExt implements ICheckExt { | |
25 | + final private String TAG = "CheckExt"; | |
26 | + private List<ICheckExt> checklist; | |
27 | + | |
28 | + public CheckExt() { | |
29 | + checklist = new ArrayList<ICheckExt>(); | |
30 | + ICheckExt check = new xmlCheckExt(); | |
31 | + checklist.add(check); | |
32 | + } | |
33 | + | |
34 | + public boolean doCheck(String... params) { | |
35 | + if (checklist.size() == 0) | |
36 | + return false; | |
37 | + ICheckExt check; | |
38 | + for (int i = 0; i < checklist.size(); i++) { | |
39 | + check = checklist.get(i); | |
40 | + if(check.doCheck(params)) | |
41 | + return true; | |
42 | + | |
43 | + } | |
44 | + return false; | |
45 | + } | |
46 | +} |
@@ -0,0 +1,30 @@ | ||
1 | +package com.android.server.pm; | |
2 | +/* | |
3 | + * Copyright (C) 2006 The Android Open Source Project | |
4 | + * | |
5 | + * Licensed under the Apache License, Version 2.0 (the "License"); | |
6 | + * you may not use this file except in compliance with the License. | |
7 | + * You may obtain a copy of the License at | |
8 | + * | |
9 | + * http://www.apache.org/licenses/LICENSE-2.0 | |
10 | + * | |
11 | + * Unless required by applicable law or agreed to in writing, software | |
12 | + * distributed under the License is distributed on an "AS IS" BASIS, | |
13 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
14 | + * See the License for the specific language governing permissions and | |
15 | + * limitations under the License. | |
16 | + */ | |
17 | + | |
18 | +public interface ICheckExt { | |
19 | + | |
20 | + /*Function: doCheck | |
21 | + *Description: | |
22 | + * check parameters to decide whether it should pass or not | |
23 | + *Parameter: | |
24 | + * params : parameters for apk to check | |
25 | + *Return: | |
26 | + * true - check pass | |
27 | + * false - check fail | |
28 | + */ | |
29 | + boolean doCheck(String... params); | |
30 | +} |
@@ -134,6 +134,7 @@ import java.io.FileOutputStream; | ||
134 | 134 | import java.io.FileReader; |
135 | 135 | import java.io.FilenameFilter; |
136 | 136 | import java.io.IOException; |
137 | +import java.io.ObjectOutputStream; | |
137 | 138 | import java.io.PrintWriter; |
138 | 139 | import java.security.NoSuchAlgorithmException; |
139 | 140 | import java.security.PublicKey; |
@@ -492,6 +493,11 @@ public class PackageManagerService extends IPackageManager.Stub { | ||
492 | 493 | // or internal storage. |
493 | 494 | private IMediaContainerService mContainerService = null; |
494 | 495 | |
496 | + // Packages that have been installed with library matching 2nd ABI. | |
497 | + final HashMap<Integer, String> mPackagesMatchABI2 = new HashMap<Integer,String>(); | |
498 | + // Packages that have been installed with library matching 2nd ABI and matching neon app list | |
499 | + final HashMap<Integer, String> mPackagesMatchABI2Neon = new HashMap<Integer,String>(); | |
500 | + | |
495 | 501 | static final int SEND_PENDING_BROADCAST = 1; |
496 | 502 | static final int MCS_BOUND = 3; |
497 | 503 | static final int END_COPY = 4; |
@@ -3790,6 +3796,53 @@ public class PackageManagerService extends IPackageManager.Stub { | ||
3790 | 3796 | return new File(mUserAppDataDir.getAbsolutePath() + File.separator + userId); |
3791 | 3797 | } |
3792 | 3798 | |
3799 | + private void writeAppwithABI2Internal(String fileName, HashMap<Integer, String> map) { | |
3800 | + File outputFile; | |
3801 | + FileOutputStream out = null; | |
3802 | + File appDataDir = new File("/data/data"); | |
3803 | + | |
3804 | + try { | |
3805 | + File tempFile = File.createTempFile("tmp", "tmp", appDataDir); | |
3806 | + String tempFilePath = tempFile.getPath(); | |
3807 | + outputFile = new File(fileName); | |
3808 | + if (FileUtils.setPermissions(tempFilePath, | |
3809 | + FileUtils.S_IRUSR | FileUtils.S_IWUSR | | |
3810 | + FileUtils.S_IRGRP | FileUtils.S_IROTH, -1, -1) != 0 | |
3811 | + || !tempFile.renameTo(outputFile)) { | |
3812 | + tempFile.delete(); | |
3813 | + } | |
3814 | + out = new FileOutputStream(outputFile); | |
3815 | + Iterator<HashMap.Entry<Integer, String>> | |
3816 | + it = map.entrySet().iterator(); | |
3817 | + while (it.hasNext()) { | |
3818 | + HashMap.Entry<Integer, String> ent = it.next(); | |
3819 | + int userID = ent.getKey().intValue(); | |
3820 | + out.write(userID & 0xff); | |
3821 | + out.write((userID>>8) & 0xff); | |
3822 | + out.write((userID>>16) & 0xff); | |
3823 | + out.write((userID>>24) & 0xff); | |
3824 | + Slog.i(TAG, "Data written:"+ userID); | |
3825 | + } | |
3826 | + } catch (Exception e) { | |
3827 | + Slog.e(TAG, "File Access Error: Not Able to write Data into " + fileName); | |
3828 | + } finally { | |
3829 | + try { | |
3830 | + if (out != null) { | |
3831 | + out.close(); | |
3832 | + Slog.i(TAG, "Data written into " + fileName); | |
3833 | + } | |
3834 | + } catch (IOException e) {} | |
3835 | + } | |
3836 | + } | |
3837 | + | |
3838 | + private void writeAppwithABI2() { | |
3839 | + writeAppwithABI2Internal(new String("/data/data/.appwithABI2"), mPackagesMatchABI2); | |
3840 | + } | |
3841 | + | |
3842 | + private void writeAppwithABI2Neon() { | |
3843 | + writeAppwithABI2Internal(new String("/data/data/.appwithABI2neon"), mPackagesMatchABI2Neon); | |
3844 | + } | |
3845 | + | |
3793 | 3846 | private File getDataPathForPackage(String packageName, int userId) { |
3794 | 3847 | /* |
3795 | 3848 | * Until we fully support multiple users, return the directory we |
@@ -4108,6 +4161,27 @@ public class PackageManagerService extends IPackageManager.Stub { | ||
4108 | 4161 | Slog.w(TAG, "Package " + pkg.packageName |
4109 | 4162 | + " was transferred to another, but its .apk remains"); |
4110 | 4163 | } |
4164 | + | |
4165 | + String abi2 = SystemProperties.get("ro.product.cpu.abi2"); | |
4166 | + if (abi2.length() != 0) { | |
4167 | + // abi2 is set, houdini is enabled | |
4168 | + PackageSetting p = mSettings.mPackages.get(pkg.packageName); | |
4169 | + if ((p != null) && (!p.codePath.equals(destCodeFile))){ | |
4170 | + | |
4171 | + // Already existing package. Make sure not upgrade to black list | |
4172 | + int result = NativeLibraryHelper.listNativeBinariesLI(scanFile); | |
4173 | + | |
4174 | + if (result == PackageManager.INSTALL_ABI2_SUCCEEDED) { | |
4175 | + ICheckExt check = new CheckExt(); | |
4176 | + if(check.doCheck(pkg.packageName, new String("filter"))){ | |
4177 | + Slog.i(TAG, "Reject application in black list::" + pkg.packageName); | |
4178 | + mLastScanError = PackageManager.INSTALL_FAILED_INVALID_APK; | |
4179 | + return null; | |
4180 | + } | |
4181 | + } | |
4182 | + | |
4183 | + } | |
4184 | + } | |
4111 | 4185 | |
4112 | 4186 | // Just create the setting, don't add it yet. For already existing packages |
4113 | 4187 | // the PkgSetting exists already and doesn't have to be created. |
@@ -4413,7 +4487,34 @@ public class PackageManagerService extends IPackageManager.Stub { | ||
4413 | 4487 | } |
4414 | 4488 | |
4415 | 4489 | try { |
4416 | - if (copyNativeLibrariesForInternalApp(scanFile, nativeLibraryDir) != PackageManager.INSTALL_SUCCEEDED) { | |
4490 | + int copyRet = copyNativeLibrariesForInternalApp(scanFile, nativeLibraryDir); | |
4491 | + Integer pkgUidInt = new Integer(pkg.applicationInfo.uid); | |
4492 | + if (copyRet == PackageManager.INSTALL_SUCCEEDED) { | |
4493 | + String abi2 = SystemProperties.get("ro.product.cpu.abi2"); | |
4494 | + if (abi2.length() != 0 && mPackagesMatchABI2.containsKey(pkgUidInt)) { | |
4495 | + Slog.i(TAG, "Replace package with primary ABI Library"); | |
4496 | + mPackagesMatchABI2.remove(pkgUidInt); | |
4497 | + writeAppwithABI2(); | |
4498 | + if (mPackagesMatchABI2Neon.containsKey(pkgUidInt)) { | |
4499 | + mPackagesMatchABI2Neon.remove(pkgUidInt); | |
4500 | + writeAppwithABI2Neon(); | |
4501 | + } | |
4502 | + } | |
4503 | + } else if (copyRet == PackageManager.INSTALL_ABI2_SUCCEEDED) { | |
4504 | + ICheckExt check = new CheckExt(); | |
4505 | + if(check.doCheck(pkgName, new String("filter"))) { | |
4506 | + Slog.i(TAG, "Package with second ABI is in black list: " + pkgUidInt + pkg.applicationInfo.processName); | |
4507 | + mLastScanError = PackageManager.INSTALL_FAILED_INVALID_APK; | |
4508 | + return null; | |
4509 | + } | |
4510 | + Slog.i(TAG, "Package installed with second ABI Library: " + pkgUidInt + pkg.applicationInfo.processName); | |
4511 | + mPackagesMatchABI2.put(pkgUidInt, pkg.applicationInfo.processName); | |
4512 | + writeAppwithABI2(); | |
4513 | + if (check.doCheck(pkgName, new String("neon"))) { | |
4514 | + mPackagesMatchABI2Neon.put(pkgUidInt, pkg.applicationInfo.processName); | |
4515 | + writeAppwithABI2Neon(); | |
4516 | + } | |
4517 | + } else { | |
4417 | 4518 | Slog.e(TAG, "Unable to copy native libraries"); |
4418 | 4519 | mLastScanError = PackageManager.INSTALL_FAILED_INTERNAL_ERROR; |
4419 | 4520 | return null; |
@@ -4906,6 +5007,19 @@ public class PackageManagerService extends IPackageManager.Stub { | ||
4906 | 5007 | final PackageParser.Package pkg = ps.pkg; |
4907 | 5008 | if (pkg != null) { |
4908 | 5009 | cleanPackageDataStructuresLILPw(pkg, chatty); |
5010 | + | |
5011 | + String abi2 = SystemProperties.get("ro.product.cpu.abi2"); | |
5012 | + Integer pkgUidInt = new Integer(pkg.applicationInfo.uid); | |
5013 | + if (abi2.length() != 0 && mPackagesMatchABI2.containsKey(pkgUidInt)) { | |
5014 | + Slog.i(TAG, "Uninstall package with second ABI Library"); | |
5015 | + mPackagesMatchABI2.remove(pkgUidInt); | |
5016 | + writeAppwithABI2(); | |
5017 | + if (mPackagesMatchABI2Neon.containsKey(pkgUidInt)) { | |
5018 | + mPackagesMatchABI2Neon.remove(pkgUidInt); | |
5019 | + writeAppwithABI2Neon(); | |
5020 | + } | |
5021 | + } | |
5022 | + | |
4909 | 5023 | } |
4910 | 5024 | } |
4911 | 5025 | } |
@@ -4923,6 +5037,18 @@ public class PackageManagerService extends IPackageManager.Stub { | ||
4923 | 5037 | mAppDirs.remove(pkg.mPath); |
4924 | 5038 | } |
4925 | 5039 | cleanPackageDataStructuresLILPw(pkg, chatty); |
5040 | + | |
5041 | + String abi2 = SystemProperties.get("ro.product.cpu.abi2"); | |
5042 | + if (abi2.length() != 0 && mPackagesMatchABI2.containsKey(new Integer(pkg.applicationInfo.uid))) { | |
5043 | + Slog.i(TAG, "Uninstall package with second ABI Library"); | |
5044 | + mPackagesMatchABI2.remove(new Integer(pkg.applicationInfo.uid)); | |
5045 | + writeAppwithABI2(); | |
5046 | + if (mPackagesMatchABI2Neon.containsKey(new Integer(pkg.applicationInfo.uid))) { | |
5047 | + mPackagesMatchABI2Neon.remove(new Integer(pkg.applicationInfo.uid)); | |
5048 | + writeAppwithABI2Neon(); | |
5049 | + } | |
5050 | + } | |
5051 | + | |
4926 | 5052 | } |
4927 | 5053 | } |
4928 | 5054 |
@@ -7459,7 +7585,7 @@ public class PackageManagerService extends IPackageManager.Stub { | ||
7459 | 7585 | } |
7460 | 7586 | try { |
7461 | 7587 | int copyRet = copyNativeLibrariesForInternalApp(codeFile, nativeLibraryFile); |
7462 | - if (copyRet != PackageManager.INSTALL_SUCCEEDED) { | |
7588 | + if (copyRet != PackageManager.INSTALL_SUCCEEDED && copyRet != PackageManager.INSTALL_ABI2_SUCCEEDED) { | |
7463 | 7589 | return copyRet; |
7464 | 7590 | } |
7465 | 7591 | } catch (IOException e) { |
@@ -0,0 +1,116 @@ | ||
1 | +package com.android.server.pm; | |
2 | +/* | |
3 | + * Copyright (C) 2006 The Android Open Source Project | |
4 | + * | |
5 | + * Licensed under the Apache License, Version 2.0 (the "License"); | |
6 | + * you may not use this file except in compliance with the License. | |
7 | + * You may obtain a copy of the License at | |
8 | + * | |
9 | + * http://www.apache.org/licenses/LICENSE-2.0 | |
10 | + * | |
11 | + * Unless required by applicable law or agreed to in writing, software | |
12 | + * distributed under the License is distributed on an "AS IS" BASIS, | |
13 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
14 | + * See the License for the specific language governing permissions and | |
15 | + * limitations under the License. | |
16 | + */ | |
17 | + | |
18 | +import java.io.File; | |
19 | +import java.io.FileInputStream; | |
20 | +import java.io.FileNotFoundException; | |
21 | +import java.io.IOException; | |
22 | +import java.io.InputStream; | |
23 | +import java.util.HashMap; | |
24 | +import java.util.List; | |
25 | + | |
26 | +import org.xmlpull.v1.XmlPullParser; | |
27 | +import org.xmlpull.v1.XmlPullParserException; | |
28 | + | |
29 | +import android.app.Activity; | |
30 | +import android.content.res.AssetManager; | |
31 | +import android.util.Log; | |
32 | +import android.util.Xml; | |
33 | + | |
34 | +/* | |
35 | + * class xmlCheckExt is trying to check by xml rules definition | |
36 | + */ | |
37 | +public class xmlCheckExt implements ICheckExt { | |
38 | + final private String TAG = "xmlCheckExt"; | |
39 | + final private String CHECKXMLPATH = "/system/lib/arm/check.xml"; | |
40 | + private HashMap<String,String > mMap = new HashMap<String,String >(); | |
41 | + | |
42 | + public boolean doCheck(String... params) { | |
43 | + String param = null; | |
44 | + String param_tag = null; | |
45 | + try { | |
46 | + int eventType; | |
47 | + String tag; | |
48 | + if (params.length == 0) | |
49 | + return false; | |
50 | + param = params[0]; | |
51 | + param_tag = params[1]; | |
52 | + XmlPullParser xmlParser = Xml.newPullParser(); | |
53 | + File file = new File(CHECKXMLPATH); | |
54 | + if (!file.exists()) | |
55 | + return false; | |
56 | + InputStream in=null; | |
57 | + in = new FileInputStream(file); | |
58 | + xmlParser.setInput(in, "utf-8"); | |
59 | + | |
60 | + eventType = xmlParser.getEventType(); | |
61 | + while (eventType != XmlPullParser.END_DOCUMENT) { | |
62 | + switch (eventType) { | |
63 | + case XmlPullParser.START_TAG: | |
64 | + tag = xmlParser.getName(); | |
65 | + Log.d(TAG,"<"+tag+">"); | |
66 | + addTag(tag, xmlParser.nextText()); | |
67 | + break; | |
68 | + case XmlPullParser.END_TAG: | |
69 | + tag = xmlParser.getName(); | |
70 | + Log.d(TAG,"</"+tag+">"); | |
71 | + break; | |
72 | + default: | |
73 | + break; | |
74 | + } | |
75 | + eventType = xmlParser.next(); | |
76 | + } | |
77 | + in.close(); | |
78 | + } catch (XmlPullParserException e) { | |
79 | + // TODO Auto-generated catch block | |
80 | + e.printStackTrace(); | |
81 | + } catch (FileNotFoundException e) { | |
82 | + // TODO Auto-generated catch block | |
83 | + e.printStackTrace(); | |
84 | + } catch (IOException e) { | |
85 | + // TODO Auto-generated catch block | |
86 | + e.printStackTrace(); | |
87 | + } | |
88 | + return checkPkgName(param, param_tag); | |
89 | + } | |
90 | + | |
91 | + /*Function:checkTag | |
92 | + *Description: | |
93 | + * add tag name to hash map | |
94 | + *Parameter: | |
95 | + * tag - tag name in xml | |
96 | + * text - text for the tag | |
97 | + *Return: | |
98 | + * true | |
99 | + */ | |
100 | + boolean addTag(String tag, String text) { | |
101 | + String pkgName = text; | |
102 | + Log.d(TAG, " pkgName = " + pkgName); | |
103 | + if(!mMap.containsKey(pkgName)) | |
104 | + mMap.put(pkgName,tag); | |
105 | + return true; | |
106 | + } | |
107 | + | |
108 | + boolean checkPkgName(String pkgName, String tag) { | |
109 | + String value = mMap.get(pkgName); | |
110 | + if (value == null) | |
111 | + return false; | |
112 | + else | |
113 | + return value.equals(tag); | |
114 | + } | |
115 | + | |
116 | +} |