From 4449ef5b6a85ef4e16dbd5d939db7b11eac0b586 Mon Sep 17 00:00:00 2001 From: Dimitry Ivanov Date: Thu, 25 Feb 2016 17:41:13 -0800 Subject: [PATCH] Display Toast with linker warnings after Activity.onStart() Displays list of problems linker encountered with app's native code including 1. Unauthorized access to private platform libraries. 2. Text relocations 3. Invalid DT_NEEDED entires This change is intended only for preview/beta releases and to be reverted before the first release build. Bug: http://b/27365747 Change-Id: I08735472059248c901ef22042682d574fb2b0c92 --- core/java/android/app/Activity.java | 30 +++++++++++++++++++++ core/jni/Android.mk | 1 + core/jni/AndroidRuntime.cpp | 2 ++ core/jni/android_app_Activity.cpp | 42 +++++++++++++++++++++++++++++ 4 files changed, 75 insertions(+) create mode 100644 core/jni/android_app_Activity.cpp diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java index 4792dc98c0eeb..ef2746c075142 100644 --- a/core/java/android/app/Activity.java +++ b/core/java/android/app/Activity.java @@ -41,6 +41,7 @@ import android.content.Intent; import android.content.IntentSender; import android.content.SharedPreferences; import android.content.pm.ActivityInfo; +import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.content.res.Configuration; @@ -68,6 +69,7 @@ import android.os.Parcelable; import android.os.PersistableBundle; import android.os.RemoteException; import android.os.StrictMode; +import android.os.SystemProperties; import android.os.UserHandle; import android.text.Selection; import android.text.SpannableStringBuilder; @@ -110,6 +112,7 @@ import android.view.WindowManager; import android.view.WindowManagerGlobal; import android.view.accessibility.AccessibilityEvent; import android.widget.AdapterView; +import android.widget.Toast; import android.widget.Toolbar; import com.android.internal.app.IVoiceInteractor; @@ -832,6 +835,8 @@ public class Activity extends ContextThemeWrapper private boolean mHasCurrentPermissionsRequest; private boolean mEatKeyUpEvent; + private static native String getDlWarning(); + /** Return the intent that started this activity. */ public Intent getIntent() { return mIntent; @@ -6621,6 +6626,31 @@ public class Activity extends ContextThemeWrapper } mFragments.dispatchStart(); mFragments.reportLoaderStart(); + + // This property is set for all builds except final release + boolean isDlwarningEnabled = SystemProperties.getInt("ro.bionic.ld.warning", 0) == 1; + boolean isAppDebuggable = + (mApplication.getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0; + + if (isAppDebuggable || isDlwarningEnabled) { + String dlwarning = getDlWarning(); + if (dlwarning != null) { + String appName = getString(mApplication.getApplicationInfo().labelRes); + String warning = "Detected problems with app native libraries\n" + + "(please consult log for detail):\n" + dlwarning; + if (isAppDebuggable) { + new AlertDialog.Builder(this). + setTitle(appName). + setMessage(warning). + setPositiveButton(android.R.string.ok, null). + setCancelable(false). + show(); + } else { + Toast.makeText(this, appName + "\n" + warning, Toast.LENGTH_LONG).show(); + } + } + } + mActivityTransitionState.enterReady(this); } diff --git a/core/jni/Android.mk b/core/jni/Android.mk index a8d684d7a6122..0e0e7a9f66ce9 100644 --- a/core/jni/Android.mk +++ b/core/jni/Android.mk @@ -33,6 +33,7 @@ LOCAL_SRC_FILES:= \ com_android_internal_content_NativeLibraryHelper.cpp \ com_google_android_gles_jni_EGLImpl.cpp \ com_google_android_gles_jni_GLImpl.cpp.arm \ + android_app_Activity.cpp \ android_app_ApplicationLoaders.cpp \ android_app_NativeActivity.cpp \ android_auditing_SecurityLog.cpp \ diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp index 6ed07a7c99906..2a04526ed3eb5 100644 --- a/core/jni/AndroidRuntime.cpp +++ b/core/jni/AndroidRuntime.cpp @@ -178,6 +178,7 @@ extern int register_android_backup_FileBackupHelperBase(JNIEnv *env); extern int register_android_backup_BackupHelperDispatcher(JNIEnv *env); extern int register_android_app_backup_FullBackup(JNIEnv *env); extern int register_android_app_ApplicationLoaders(JNIEnv* env); +extern int register_android_app_Activity(JNIEnv *env); extern int register_android_app_ActivityThread(JNIEnv *env); extern int register_android_app_NativeActivity(JNIEnv *env); extern int register_android_media_RemoteDisplay(JNIEnv *env); @@ -1373,6 +1374,7 @@ static const RegJNIRec gRegJNI[] = { REG_JNI(register_android_backup_BackupHelperDispatcher), REG_JNI(register_android_app_backup_FullBackup), REG_JNI(register_android_app_ApplicationLoaders), + REG_JNI(register_android_app_Activity), REG_JNI(register_android_app_ActivityThread), REG_JNI(register_android_app_NativeActivity), REG_JNI(register_android_util_jar_StrictJarFile), diff --git a/core/jni/android_app_Activity.cpp b/core/jni/android_app_Activity.cpp new file mode 100644 index 0000000000000..b1d7e82c73ae6 --- /dev/null +++ b/core/jni/android_app_Activity.cpp @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2010 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. + */ + +#include +#include + +#include "core_jni_helpers.h" + +namespace android +{ + +static jstring getDlWarning_native(JNIEnv* env, jobject) { + const char* text = android_dlwarning(); + return text == nullptr ? nullptr : env->NewStringUTF(text); +} + +static const JNINativeMethod g_methods[] = { + { "getDlWarning", + "()Ljava/lang/String;", + reinterpret_cast(getDlWarning_native) }, +}; + +static const char* const kActivityPathName = "android/app/Activity"; + +int register_android_app_Activity(JNIEnv* env) { + return RegisterMethodsOrDie(env, kActivityPathName, g_methods, NELEM(g_methods)); +} + +} // namespace android