Loading services/core/java/com/android/server/wm/AppWarnings.java +76 −0 Original line number Diff line number Diff line Loading @@ -32,6 +32,7 @@ import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.pm.ApplicationInfo; import android.content.pm.Flags; import android.content.pm.UserInfo; import android.content.res.Configuration; import android.os.Build; Loading @@ -40,6 +41,8 @@ import android.os.Looper; import android.os.Message; import android.os.SystemProperties; import android.os.UserHandle; import android.system.Os; import android.system.OsConstants; import android.util.ArrayMap; import android.util.ArraySet; import android.util.AtomicFile; Loading Loading @@ -76,6 +79,7 @@ class AppWarnings { public static final int FLAG_HIDE_COMPILE_SDK = 0x02; public static final int FLAG_HIDE_DEPRECATED_SDK = 0x04; public static final int FLAG_HIDE_DEPRECATED_ABI = 0x08; public static final int FLAG_HIDE_PAGE_SIZE_MISMATCH = 0x10; /** * Map of package flags for each user. Loading @@ -101,6 +105,7 @@ class AppWarnings { private SparseArray<UnsupportedCompileSdkDialog> mUnsupportedCompileSdkDialogs; private SparseArray<DeprecatedTargetSdkVersionDialog> mDeprecatedTargetSdkVersionDialogs; private SparseArray<DeprecatedAbiDialog> mDeprecatedAbiDialogs; private SparseArray<PageSizeMismatchDialog> mPageSizeMismatchDialogs; /** @see android.app.ActivityManager#alwaysShowUnsupportedCompileSdkWarning */ private final ArraySet<ComponentName> mAlwaysShowUnsupportedCompileSdkWarningActivities = Loading Loading @@ -250,6 +255,19 @@ class AppWarnings { } } public void showPageSizeMismatchDialogIfNeeded(ActivityRecord r) { // Don't show dialog if the app compat is enabled using property final boolean appCompatEnabled = SystemProperties.getBoolean( "bionic.linker.16kb.app_compat.enabled", false); if (appCompatEnabled) { return; } boolean is16KbDevice = Os.sysconf(OsConstants._SC_PAGESIZE) == 16384; if (is16KbDevice) { mUiHandler.showPageSizeMismatchDialog(r); } } /** * Called when an activity is being started. * Loading @@ -260,6 +278,9 @@ class AppWarnings { showUnsupportedDisplaySizeDialogIfNeeded(r); showDeprecatedTargetDialogIfNeeded(r); showDeprecatedAbiDialogIfNeeded(r); if (Flags.appCompatOption16kb()) { showPageSizeMismatchDialogIfNeeded(r); } } /** Loading Loading @@ -457,6 +478,41 @@ class AppWarnings { } } @UiThread private void showPageSizeMismatchDialogUiThread(@NonNull ActivityRecord ar) { String warning = mAtm.mContext .getPackageManager() .getPageSizeCompatWarningMessage(ar.info.packageName); if (warning == null) { return; } final int userId = getUserIdForActivity(ar); PageSizeMismatchDialog pageSizeMismatchDialog; if (mPageSizeMismatchDialogs != null) { pageSizeMismatchDialog = mPageSizeMismatchDialogs.get(userId); if (pageSizeMismatchDialog != null) { pageSizeMismatchDialog.dismiss(); mPageSizeMismatchDialogs.remove(userId); } } if (!hasPackageFlag(userId, ar.packageName, FLAG_HIDE_PAGE_SIZE_MISMATCH)) { pageSizeMismatchDialog = new PageSizeMismatchDialog( AppWarnings.this, getUiContextForActivity(ar), ar.info.applicationInfo, userId, warning); pageSizeMismatchDialog.show(); if (mPageSizeMismatchDialogs == null) { mPageSizeMismatchDialogs = new SparseArray<>(); } mPageSizeMismatchDialogs.put(userId, pageSizeMismatchDialog); } } /** * Dismisses all warnings for the given package. * <p> Loading Loading @@ -510,6 +566,16 @@ class AppWarnings { mDeprecatedAbiDialogs.remove(userId); } } // Hides the "page size app compat" dialog if necessary. if (mPageSizeMismatchDialogs != null) { PageSizeMismatchDialog pageSizeMismatchDialog = mPageSizeMismatchDialogs.get(userId); if (pageSizeMismatchDialog != null && (name == null || name.equals(pageSizeMismatchDialog.mPackageName))) { pageSizeMismatchDialog.dismiss(); mPageSizeMismatchDialogs.remove(userId); } } } /** Loading Loading @@ -649,6 +715,7 @@ class AppWarnings { private static final int MSG_HIDE_DIALOGS_FOR_PACKAGE = 4; private static final int MSG_SHOW_DEPRECATED_TARGET_SDK_DIALOG = 5; private static final int MSG_SHOW_DEPRECATED_ABI_DIALOG = 6; private static final int MSG_SHOW_PAGE_SIZE_APP_MISMATCH_DIALOG = 7; public UiHandler(Looper looper) { super(looper, null, true); Loading Loading @@ -681,6 +748,10 @@ class AppWarnings { final ActivityRecord ar = (ActivityRecord) msg.obj; showDeprecatedAbiDialogUiThread(ar); } break; case MSG_SHOW_PAGE_SIZE_APP_MISMATCH_DIALOG: { final ActivityRecord ar = (ActivityRecord) msg.obj; showPageSizeMismatchDialogUiThread(ar); } break; } } Loading Loading @@ -712,6 +783,11 @@ class AppWarnings { public void hideDialogsForPackage(String name, int userId) { obtainMessage(MSG_HIDE_DIALOGS_FOR_PACKAGE, userId, 0, name).sendToTarget(); } public void showPageSizeMismatchDialog(ActivityRecord r) { removeMessages(MSG_SHOW_PAGE_SIZE_APP_MISMATCH_DIALOG); obtainMessage(MSG_SHOW_PAGE_SIZE_APP_MISMATCH_DIALOG, r).sendToTarget(); } } static class BaseDialog { Loading services/core/java/com/android/server/wm/PageSizeMismatchDialog.java 0 → 100644 +72 −0 Original line number Diff line number Diff line /* * Copyright (C) 2024 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 com.android.server.wm; import static android.text.Html.FROM_HTML_MODE_COMPACT; import android.app.AlertDialog; import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.pm.PackageItemInfo; import android.content.pm.PackageManager; import android.text.Html; import android.view.Window; import android.view.WindowManager; import com.android.internal.R; /** * Show warning dialog when * - Uncompressed libs inside apk are not aligned to page size * - ELF Load segments are not page size aligned * This dialog will be shown everytime when app is launched. Apps can choose to override * by setting compat mode pageSizeCompat="enabled" in manifest or "disabled" to opt out. * Both cases will skip the PageSizeMismatchDialog. * */ class PageSizeMismatchDialog extends AppWarnings.BaseDialog { PageSizeMismatchDialog( final AppWarnings manager, Context context, ApplicationInfo appInfo, int userId, String warning) { super(manager, context, appInfo.packageName, userId); final PackageManager pm = context.getPackageManager(); final CharSequence label = appInfo.loadSafeLabel( pm, PackageItemInfo.DEFAULT_MAX_LABEL_SIZE_PX, PackageItemInfo.SAFE_LABEL_FLAG_FIRST_LINE | PackageItemInfo.SAFE_LABEL_FLAG_TRIM); final AlertDialog.Builder builder = new AlertDialog.Builder(context) .setPositiveButton( R.string.ok, (dialog, which) -> {/* Do nothing */}) .setMessage(Html.fromHtml(warning, FROM_HTML_MODE_COMPACT)) .setTitle(label); mDialog = builder.create(); mDialog.create(); final Window window = mDialog.getWindow(); window.setType(WindowManager.LayoutParams.TYPE_PHONE); } } Loading
services/core/java/com/android/server/wm/AppWarnings.java +76 −0 Original line number Diff line number Diff line Loading @@ -32,6 +32,7 @@ import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.pm.ApplicationInfo; import android.content.pm.Flags; import android.content.pm.UserInfo; import android.content.res.Configuration; import android.os.Build; Loading @@ -40,6 +41,8 @@ import android.os.Looper; import android.os.Message; import android.os.SystemProperties; import android.os.UserHandle; import android.system.Os; import android.system.OsConstants; import android.util.ArrayMap; import android.util.ArraySet; import android.util.AtomicFile; Loading Loading @@ -76,6 +79,7 @@ class AppWarnings { public static final int FLAG_HIDE_COMPILE_SDK = 0x02; public static final int FLAG_HIDE_DEPRECATED_SDK = 0x04; public static final int FLAG_HIDE_DEPRECATED_ABI = 0x08; public static final int FLAG_HIDE_PAGE_SIZE_MISMATCH = 0x10; /** * Map of package flags for each user. Loading @@ -101,6 +105,7 @@ class AppWarnings { private SparseArray<UnsupportedCompileSdkDialog> mUnsupportedCompileSdkDialogs; private SparseArray<DeprecatedTargetSdkVersionDialog> mDeprecatedTargetSdkVersionDialogs; private SparseArray<DeprecatedAbiDialog> mDeprecatedAbiDialogs; private SparseArray<PageSizeMismatchDialog> mPageSizeMismatchDialogs; /** @see android.app.ActivityManager#alwaysShowUnsupportedCompileSdkWarning */ private final ArraySet<ComponentName> mAlwaysShowUnsupportedCompileSdkWarningActivities = Loading Loading @@ -250,6 +255,19 @@ class AppWarnings { } } public void showPageSizeMismatchDialogIfNeeded(ActivityRecord r) { // Don't show dialog if the app compat is enabled using property final boolean appCompatEnabled = SystemProperties.getBoolean( "bionic.linker.16kb.app_compat.enabled", false); if (appCompatEnabled) { return; } boolean is16KbDevice = Os.sysconf(OsConstants._SC_PAGESIZE) == 16384; if (is16KbDevice) { mUiHandler.showPageSizeMismatchDialog(r); } } /** * Called when an activity is being started. * Loading @@ -260,6 +278,9 @@ class AppWarnings { showUnsupportedDisplaySizeDialogIfNeeded(r); showDeprecatedTargetDialogIfNeeded(r); showDeprecatedAbiDialogIfNeeded(r); if (Flags.appCompatOption16kb()) { showPageSizeMismatchDialogIfNeeded(r); } } /** Loading Loading @@ -457,6 +478,41 @@ class AppWarnings { } } @UiThread private void showPageSizeMismatchDialogUiThread(@NonNull ActivityRecord ar) { String warning = mAtm.mContext .getPackageManager() .getPageSizeCompatWarningMessage(ar.info.packageName); if (warning == null) { return; } final int userId = getUserIdForActivity(ar); PageSizeMismatchDialog pageSizeMismatchDialog; if (mPageSizeMismatchDialogs != null) { pageSizeMismatchDialog = mPageSizeMismatchDialogs.get(userId); if (pageSizeMismatchDialog != null) { pageSizeMismatchDialog.dismiss(); mPageSizeMismatchDialogs.remove(userId); } } if (!hasPackageFlag(userId, ar.packageName, FLAG_HIDE_PAGE_SIZE_MISMATCH)) { pageSizeMismatchDialog = new PageSizeMismatchDialog( AppWarnings.this, getUiContextForActivity(ar), ar.info.applicationInfo, userId, warning); pageSizeMismatchDialog.show(); if (mPageSizeMismatchDialogs == null) { mPageSizeMismatchDialogs = new SparseArray<>(); } mPageSizeMismatchDialogs.put(userId, pageSizeMismatchDialog); } } /** * Dismisses all warnings for the given package. * <p> Loading Loading @@ -510,6 +566,16 @@ class AppWarnings { mDeprecatedAbiDialogs.remove(userId); } } // Hides the "page size app compat" dialog if necessary. if (mPageSizeMismatchDialogs != null) { PageSizeMismatchDialog pageSizeMismatchDialog = mPageSizeMismatchDialogs.get(userId); if (pageSizeMismatchDialog != null && (name == null || name.equals(pageSizeMismatchDialog.mPackageName))) { pageSizeMismatchDialog.dismiss(); mPageSizeMismatchDialogs.remove(userId); } } } /** Loading Loading @@ -649,6 +715,7 @@ class AppWarnings { private static final int MSG_HIDE_DIALOGS_FOR_PACKAGE = 4; private static final int MSG_SHOW_DEPRECATED_TARGET_SDK_DIALOG = 5; private static final int MSG_SHOW_DEPRECATED_ABI_DIALOG = 6; private static final int MSG_SHOW_PAGE_SIZE_APP_MISMATCH_DIALOG = 7; public UiHandler(Looper looper) { super(looper, null, true); Loading Loading @@ -681,6 +748,10 @@ class AppWarnings { final ActivityRecord ar = (ActivityRecord) msg.obj; showDeprecatedAbiDialogUiThread(ar); } break; case MSG_SHOW_PAGE_SIZE_APP_MISMATCH_DIALOG: { final ActivityRecord ar = (ActivityRecord) msg.obj; showPageSizeMismatchDialogUiThread(ar); } break; } } Loading Loading @@ -712,6 +783,11 @@ class AppWarnings { public void hideDialogsForPackage(String name, int userId) { obtainMessage(MSG_HIDE_DIALOGS_FOR_PACKAGE, userId, 0, name).sendToTarget(); } public void showPageSizeMismatchDialog(ActivityRecord r) { removeMessages(MSG_SHOW_PAGE_SIZE_APP_MISMATCH_DIALOG); obtainMessage(MSG_SHOW_PAGE_SIZE_APP_MISMATCH_DIALOG, r).sendToTarget(); } } static class BaseDialog { Loading
services/core/java/com/android/server/wm/PageSizeMismatchDialog.java 0 → 100644 +72 −0 Original line number Diff line number Diff line /* * Copyright (C) 2024 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 com.android.server.wm; import static android.text.Html.FROM_HTML_MODE_COMPACT; import android.app.AlertDialog; import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.pm.PackageItemInfo; import android.content.pm.PackageManager; import android.text.Html; import android.view.Window; import android.view.WindowManager; import com.android.internal.R; /** * Show warning dialog when * - Uncompressed libs inside apk are not aligned to page size * - ELF Load segments are not page size aligned * This dialog will be shown everytime when app is launched. Apps can choose to override * by setting compat mode pageSizeCompat="enabled" in manifest or "disabled" to opt out. * Both cases will skip the PageSizeMismatchDialog. * */ class PageSizeMismatchDialog extends AppWarnings.BaseDialog { PageSizeMismatchDialog( final AppWarnings manager, Context context, ApplicationInfo appInfo, int userId, String warning) { super(manager, context, appInfo.packageName, userId); final PackageManager pm = context.getPackageManager(); final CharSequence label = appInfo.loadSafeLabel( pm, PackageItemInfo.DEFAULT_MAX_LABEL_SIZE_PX, PackageItemInfo.SAFE_LABEL_FLAG_FIRST_LINE | PackageItemInfo.SAFE_LABEL_FLAG_TRIM); final AlertDialog.Builder builder = new AlertDialog.Builder(context) .setPositiveButton( R.string.ok, (dialog, which) -> {/* Do nothing */}) .setMessage(Html.fromHtml(warning, FROM_HTML_MODE_COMPACT)) .setTitle(label); mDialog = builder.create(); mDialog.create(); final Window window = mDialog.getWindow(); window.setType(WindowManager.LayoutParams.TYPE_PHONE); } }