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
This commit is contained in:
committed by
Songchun Fan
parent
f91a331f1d
commit
2b1fff32fa
@@ -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] -->
|
||||
|
||||
@@ -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" />
|
||||
|
||||
@@ -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 =
|
||||
@@ -165,6 +169,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.
|
||||
*
|
||||
@@ -174,6 +203,7 @@ class AppWarnings {
|
||||
showUnsupportedCompileSdkDialogIfNeeded(r);
|
||||
showUnsupportedDisplaySizeDialogIfNeeded(r);
|
||||
showDeprecatedTargetDialogIfNeeded(r);
|
||||
showDeprecatedAbiDialogIfNeeded(r);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -298,6 +328,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>
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user