diff options
| author | 2022-02-23 10:37:45 +0100 | |
|---|---|---|
| committer | 2023-05-23 11:30:57 -0700 | |
| commit | 2b1fff32fa2f1733fc25b6fc68b738db289af697 (patch) | |
| tree | 9864ef91fc4f63cdfd67b3800b5baccec4f585cb | |
| parent | f91a331f1d5d4d0c9476d1e86247133e221c882d (diff) | |
Warn when running activity from 32 bit app on 64 bit devices.
Starting August 1, 2019 it is required to have 64-bit versions of apps.
As we prepare for the 64-bit requirement this warning dialog notifies users when running an APK using deprecated ABI to update their apps or contact developers to comply to Google's policies.
BUG: 283266877
Test: will add CTS
Change-Id: If0ca5cbcee571a1095c45c96f0126fce8d0f218c
| -rw-r--r-- | core/res/res/values/strings.xml | 3 | ||||
| -rw-r--r-- | core/res/res/values/symbols.xml | 2 | ||||
| -rw-r--r-- | services/core/java/com/android/server/wm/AppWarnings.java | 68 | ||||
| -rw-r--r-- | services/core/java/com/android/server/wm/DeprecatedAbiDialog.java | 58 |
4 files changed, 131 insertions, 0 deletions
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml index 91fbf6bb9f06..fb3acbe79114 100644 --- a/core/res/res/values/strings.xml +++ b/core/res/res/values/strings.xml @@ -5410,6 +5410,9 @@ <!-- Title for button to see application detail in app store which it came from - it may allow user to update to newer version. [CHAR LIMIT=50] --> <string name="deprecated_target_sdk_app_store">Check for update</string> + <!-- Message displayed in dialog when app is 32 bit on a 64 bit system. [CHAR LIMIT=NONE] --> + <string name="deprecated_abi_message">This app isn\'t compatible with the latest version of Android. Check for an update or contact the app\'s developer.</string> + <!-- Notification title shown when new SMS/MMS is received while the device is locked [CHAR LIMIT=NONE] --> <string name="new_sms_notification_title">You have new messages</string> <!-- Notification content shown when new SMS/MMS is received while the device is locked [CHAR LIMIT=NONE] --> diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index f35e32b126ba..0c2800cbd3fa 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -3156,6 +3156,8 @@ <java-symbol type="string" name="deprecated_target_sdk_message" /> <java-symbol type="string" name="deprecated_target_sdk_app_store" /> + <java-symbol type="string" name="deprecated_abi_message" /> + <!-- New SMS notification while phone is locked. --> <java-symbol type="string" name="new_sms_notification_title" /> <java-symbol type="string" name="new_sms_notification_content" /> diff --git a/services/core/java/com/android/server/wm/AppWarnings.java b/services/core/java/com/android/server/wm/AppWarnings.java index d22c38e39799..123a74dbf597 100644 --- a/services/core/java/com/android/server/wm/AppWarnings.java +++ b/services/core/java/com/android/server/wm/AppWarnings.java @@ -28,11 +28,13 @@ import android.os.Build; import android.os.Handler; import android.os.Looper; import android.os.Message; +import android.os.SystemProperties; import android.util.AtomicFile; import android.util.DisplayMetrics; import android.util.Slog; import android.util.Xml; +import com.android.internal.util.ArrayUtils; import com.android.modules.utils.TypedXmlPullParser; import com.android.modules.utils.TypedXmlSerializer; @@ -56,6 +58,7 @@ class AppWarnings { public static final int FLAG_HIDE_DISPLAY_SIZE = 0x01; 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; private final HashMap<String, Integer> mPackageFlags = new HashMap<>(); @@ -68,6 +71,7 @@ class AppWarnings { private UnsupportedDisplaySizeDialog mUnsupportedDisplaySizeDialog; private UnsupportedCompileSdkDialog mUnsupportedCompileSdkDialog; private DeprecatedTargetSdkVersionDialog mDeprecatedTargetSdkVersionDialog; + private DeprecatedAbiDialog mDeprecatedAbiDialog; /** @see android.app.ActivityManager#alwaysShowUnsupportedCompileSdkWarning */ private HashSet<ComponentName> mAlwaysShowUnsupportedCompileSdkWarningActivities = @@ -166,6 +170,31 @@ class AppWarnings { } /** + * Shows the "deprecated abi" warning, if necessary. This can only happen is the device + * supports both 64-bit and 32-bit ABIs, and the app only contains 32-bit libraries. The app + * cannot be installed if the device only supports 64-bit ABI while the app contains only 32-bit + * libraries. + * + * @param r activity record for which the warning may be displayed + */ + public void showDeprecatedAbiDialogIfNeeded(ActivityRecord r) { + final boolean disableDeprecatedAbiDialog = SystemProperties.getBoolean( + "debug.wm.disable_deprecated_abi_dialog", false); + if (disableDeprecatedAbiDialog) { + return; + } + final String appPrimaryAbi = r.info.applicationInfo.primaryCpuAbi; + final String appSecondaryAbi = r.info.applicationInfo.secondaryCpuAbi; + final boolean appContainsOnly32bitLibraries = + (appPrimaryAbi != null && appSecondaryAbi == null && !appPrimaryAbi.contains("64")); + final boolean is64BitDevice = + ArrayUtils.find(Build.SUPPORTED_ABIS, abi -> abi.contains("64")) != null; + if (is64BitDevice && appContainsOnly32bitLibraries) { + mUiHandler.showDeprecatedAbiDialog(r); + } + } + + /** * Called when an activity is being started. * * @param r record for the activity being started @@ -174,6 +203,7 @@ class AppWarnings { showUnsupportedCompileSdkDialogIfNeeded(r); showUnsupportedDisplaySizeDialogIfNeeded(r); showDeprecatedTargetDialogIfNeeded(r); + showDeprecatedAbiDialogIfNeeded(r); } /** @@ -299,6 +329,27 @@ class AppWarnings { } /** + * Shows the "deprecated abi" warning for the given application. + * <p> + * <strong>Note:</strong> Must be called on the UI thread. + * + * @param ar record for the activity that triggered the warning + */ + @UiThread + private void showDeprecatedAbiDialogUiThread(ActivityRecord ar) { + if (mDeprecatedAbiDialog != null) { + mDeprecatedAbiDialog.dismiss(); + mDeprecatedAbiDialog = null; + } + if (ar != null && !hasPackageFlag( + ar.packageName, FLAG_HIDE_DEPRECATED_ABI)) { + mDeprecatedAbiDialog = new DeprecatedAbiDialog( + AppWarnings.this, mUiContext, ar.info.applicationInfo); + mDeprecatedAbiDialog.show(); + } + } + + /** * Dismisses all warnings for the given package. * <p> * <strong>Note:</strong> Must be called on the UI thread. @@ -328,6 +379,13 @@ class AppWarnings { mDeprecatedTargetSdkVersionDialog.dismiss(); mDeprecatedTargetSdkVersionDialog = null; } + + // Hides the "deprecated abi" dialog if necessary. + if (mDeprecatedAbiDialog != null && (name == null || name.equals( + mDeprecatedAbiDialog.mPackageName))) { + mDeprecatedAbiDialog.dismiss(); + mDeprecatedAbiDialog = null; + } } /** @@ -381,6 +439,7 @@ class AppWarnings { private static final int MSG_SHOW_UNSUPPORTED_COMPILE_SDK_DIALOG = 3; 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; public UiHandler(Looper looper) { super(looper, null, true); @@ -408,6 +467,10 @@ class AppWarnings { final ActivityRecord ar = (ActivityRecord) msg.obj; showDeprecatedTargetSdkDialogUiThread(ar); } break; + case MSG_SHOW_DEPRECATED_ABI_DIALOG: { + final ActivityRecord ar = (ActivityRecord) msg.obj; + showDeprecatedAbiDialogUiThread(ar); + } break; } } @@ -431,6 +494,11 @@ class AppWarnings { obtainMessage(MSG_SHOW_DEPRECATED_TARGET_SDK_DIALOG, r).sendToTarget(); } + public void showDeprecatedAbiDialog(ActivityRecord r) { + removeMessages(MSG_SHOW_DEPRECATED_ABI_DIALOG); + obtainMessage(MSG_SHOW_DEPRECATED_ABI_DIALOG, r).sendToTarget(); + } + public void hideDialogsForPackage(String name) { obtainMessage(MSG_HIDE_DIALOGS_FOR_PACKAGE, name).sendToTarget(); } diff --git a/services/core/java/com/android/server/wm/DeprecatedAbiDialog.java b/services/core/java/com/android/server/wm/DeprecatedAbiDialog.java new file mode 100644 index 000000000000..e96208d3d0b3 --- /dev/null +++ b/services/core/java/com/android/server/wm/DeprecatedAbiDialog.java @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2023 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 android.app.AlertDialog; +import android.content.Context; +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageItemInfo; +import android.content.pm.PackageManager; +import android.view.Window; +import android.view.WindowManager; + +import com.android.internal.R; + +class DeprecatedAbiDialog extends AppWarnings.BaseDialog { + DeprecatedAbiDialog(final AppWarnings manager, Context context, + ApplicationInfo appInfo) { + super(manager, appInfo.packageName); + + 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 CharSequence message = context.getString(R.string.deprecated_abi_message); + + final AlertDialog.Builder builder = new AlertDialog.Builder(context) + .setPositiveButton(R.string.ok, (dialog, which) -> + manager.setPackageFlag( + mPackageName, AppWarnings.FLAG_HIDE_DEPRECATED_ABI, true)) + .setMessage(message) + .setTitle(label); + + // Ensure the content view is prepared. + mDialog = builder.create(); + mDialog.create(); + + final Window window = mDialog.getWindow(); + window.setType(WindowManager.LayoutParams.TYPE_PHONE); + + // DO NOT MODIFY. Used by CTS to verify the dialog is displayed. + window.getAttributes().setTitle("DeprecatedAbiDialog"); + } +} |