diff options
| -rw-r--r-- | core/java/android/app/ActivityThread.java | 6 | ||||
| -rw-r--r-- | core/java/android/os/GraphicsEnvironment.java | 95 | ||||
| -rw-r--r-- | core/jni/Android.mk | 1 | ||||
| -rw-r--r-- | core/jni/AndroidRuntime.cpp | 2 | ||||
| -rw-r--r-- | core/jni/android_os_GraphicsEnvironment.cpp | 44 |
5 files changed, 146 insertions, 2 deletions
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index 45d325a859fa..0b3ae3a989d5 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -62,6 +62,7 @@ import android.os.Bundle; import android.os.Debug; import android.os.DropBoxManager; import android.os.Environment; +import android.os.GraphicsEnvironment; import android.os.Handler; import android.os.IBinder; import android.os.LocaleList; @@ -5106,7 +5107,7 @@ public final class ActivityThread { WindowManagerGlobal.getInstance().trimMemory(level); } - private void setupGraphicsSupport(LoadedApk info, File cacheDir) { + private void setupGraphicsSupport(Context context, File cacheDir) { if (Process.isIsolated()) { // Isolated processes aren't going to do UI. return; @@ -5119,6 +5120,7 @@ public final class ActivityThread { if (packages != null) { ThreadedRenderer.setupDiskCache(cacheDir); RenderScriptCacheDir.setupDiskCache(cacheDir); + GraphicsEnvironment.setupGraphicsEnvironment(context); } } catch (RemoteException e) { throw e.rethrowFromSystemServer(); @@ -5422,7 +5424,7 @@ public final class ActivityThread { final Context deviceContext = appContext.createDeviceProtectedStorageContext(); final File codeCacheDir = deviceContext.getCodeCacheDir(); if (codeCacheDir != null) { - setupGraphicsSupport(data.info, codeCacheDir); + setupGraphicsSupport(appContext, codeCacheDir); } else { Log.e(TAG, "Unable to setupGraphicsSupport due to missing code-cache directory"); } diff --git a/core/java/android/os/GraphicsEnvironment.java b/core/java/android/os/GraphicsEnvironment.java new file mode 100644 index 000000000000..4b130ed1adc8 --- /dev/null +++ b/core/java/android/os/GraphicsEnvironment.java @@ -0,0 +1,95 @@ +/* + * Copyright 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.os; + +import android.content.Context; +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageManager; +import android.os.SystemProperties; +import android.util.Log; + +import dalvik.system.VMRuntime; + +import java.io.File; + +/** @hide */ +public final class GraphicsEnvironment { + + private static final boolean DEBUG = false; + private static final String TAG = "GraphicsEnvironment"; + private static final String PROPERTY_GFX_DRIVER = "ro.gfx.driver.0"; + + public static void setupGraphicsEnvironment(Context context) { + String driverPackageName = SystemProperties.get(PROPERTY_GFX_DRIVER); + if (driverPackageName == null || driverPackageName.isEmpty()) { + return; + } + // To minimize risk of driver updates crippling the device beyond user repair, never use an + // updated driver for privileged or non-updated system apps. Presumably pre-installed apps + // were tested thoroughly with the pre-installed driver. + ApplicationInfo ai = context.getApplicationInfo(); + if (ai.isPrivilegedApp() || (ai.isSystemApp() && !ai.isUpdatedSystemApp())) { + if (DEBUG) Log.v(TAG, "ignoring driver package for privileged/non-updated system app"); + return; + } + ApplicationInfo driverInfo; + try { + driverInfo = context.getPackageManager().getApplicationInfo(driverPackageName, + PackageManager.MATCH_SYSTEM_ONLY); + } catch (PackageManager.NameNotFoundException e) { + Log.w(TAG, "driver package '" + driverPackageName + "' not installed"); + return; + } + String abi = chooseAbi(driverInfo); + if (abi == null) { + if (DEBUG) { + // This is the normal case for the pre-installed empty driver package, don't spam + if (driverInfo.isUpdatedSystemApp()) { + Log.w(TAG, "updated driver package has no compatible native libraries"); + } + } + return; + } + + StringBuilder sb = new StringBuilder(); + sb.append(driverInfo.nativeLibraryDir) + .append(File.pathSeparator); + sb.append(driverInfo.sourceDir) + .append("!/lib/") + .append(abi); + String paths = sb.toString(); + + if (DEBUG) Log.v(TAG, "gfx driver package libs: " + paths); + setDriverPath(paths); + } + + private static String chooseAbi(ApplicationInfo ai) { + String isa = VMRuntime.getCurrentInstructionSet(); + if (ai.primaryCpuAbi != null && + isa.equals(VMRuntime.getInstructionSet(ai.primaryCpuAbi))) { + return ai.primaryCpuAbi; + } + if (ai.secondaryCpuAbi != null && + isa.equals(VMRuntime.getInstructionSet(ai.secondaryCpuAbi))) { + return ai.secondaryCpuAbi; + } + return null; + } + + private static native void setDriverPath(String path); + +} diff --git a/core/jni/Android.mk b/core/jni/Android.mk index a1f8e92961d6..68034f65c39a 100644 --- a/core/jni/Android.mk +++ b/core/jni/Android.mk @@ -82,6 +82,7 @@ LOCAL_SRC_FILES:= \ android_text_AndroidBidi.cpp \ android_text_StaticLayout.cpp \ android_os_Debug.cpp \ + android_os_GraphicsEnvironment.cpp \ android_os_HwBinder.cpp \ android_os_HwBlob.cpp \ android_os_HwParcel.cpp \ diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp index c195cfe23bfb..fb5d0373725a 100644 --- a/core/jni/AndroidRuntime.cpp +++ b/core/jni/AndroidRuntime.cpp @@ -150,6 +150,7 @@ extern int register_android_database_SQLiteGlobal(JNIEnv* env); extern int register_android_database_SQLiteDebug(JNIEnv* env); extern int register_android_nio_utils(JNIEnv* env); extern int register_android_os_Debug(JNIEnv* env); +extern int register_android_os_GraphicsEnvironment(JNIEnv* env); extern int register_android_os_HwBinder(JNIEnv *env); extern int register_android_os_HwBlob(JNIEnv *env); extern int register_android_os_HwParcel(JNIEnv *env); @@ -1355,6 +1356,7 @@ static const RegJNIRec gRegJNI[] = { REG_JNI(register_android_database_SQLiteDebug), REG_JNI(register_android_os_Debug), REG_JNI(register_android_os_FileObserver), + REG_JNI(register_android_os_GraphicsEnvironment), REG_JNI(register_android_os_MessageQueue), REG_JNI(register_android_os_SELinux), REG_JNI(register_android_os_Trace), diff --git a/core/jni/android_os_GraphicsEnvironment.cpp b/core/jni/android_os_GraphicsEnvironment.cpp new file mode 100644 index 000000000000..905a85adc551 --- /dev/null +++ b/core/jni/android_os_GraphicsEnvironment.cpp @@ -0,0 +1,44 @@ +/* + * Copyright 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define LOG_TAG "GraphicsEnvironment" + +#include <gui/GraphicsEnv.h> +#include <nativehelper/ScopedUtfChars.h> +#include "core_jni_helpers.h" + +namespace { + +void setDriverPath(JNIEnv* env, jobject clazz, jstring path) { + ScopedUtfChars pathChars(env, path); + android::GraphicsEnv::getInstance().setDriverPath(pathChars.c_str()); +} + +const JNINativeMethod g_methods[] = { + { "setDriverPath", "(Ljava/lang/String;)V", reinterpret_cast<void*>(setDriverPath) }, +}; + +const char* const kGraphicsEnvironmentName = "android/os/GraphicsEnvironment"; + +} // anonymous namespace + +namespace android { + +int register_android_os_GraphicsEnvironment(JNIEnv* env) { + return RegisterMethodsOrDie(env, kGraphicsEnvironmentName, g_methods, NELEM(g_methods)); +} + +} // namespace android |