summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/res/res/layout/unsupported_display_size_dialog_content.xml31
-rw-r--r--core/res/res/values/strings.xml5
-rw-r--r--core/res/res/values/symbols.xml3
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java56
-rw-r--r--services/core/java/com/android/server/am/ActivityStack.java1
-rw-r--r--services/core/java/com/android/server/am/ActivityStackSupervisor.java1
-rw-r--r--services/core/java/com/android/server/am/CompatModePackages.java56
-rw-r--r--services/core/java/com/android/server/am/UnsupportedDisplaySizeDialog.java78
8 files changed, 221 insertions, 10 deletions
diff --git a/core/res/res/layout/unsupported_display_size_dialog_content.xml b/core/res/res/layout/unsupported_display_size_dialog_content.xml
new file mode 100644
index 000000000000..5e5cf00b27ac
--- /dev/null
+++ b/core/res/res/layout/unsupported_display_size_dialog_content.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (C) 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.
+-->
+
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingTop="?attr/dialogPreferredPadding"
+ android:paddingLeft="?attr/dialogPreferredPadding"
+ android:paddingRight="?attr/dialogPreferredPadding">
+
+ <CheckBox
+ android:id="@+id/ask_checkbox"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="start"
+ android:text="@string/unsupported_display_size_show" />
+</FrameLayout>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 48744b61b965..b55a9b22118b 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -2768,6 +2768,11 @@
<!-- [CHAR LIMIT=200] Compat mode dialog: hint to re-enable compat mode dialog. -->
<string name="screen_compat_mode_hint">Re-enable this in System settings &gt; Apps &gt; Downloaded.</string>
+ <!-- [CHAR LIMIT=200] Unsupported display size dialog: message. Refers to "Display size" setting. -->
+ <string name="unsupported_display_size_message"><xliff:g id="app_name">%1$s</xliff:g> does not support the current Display size setting and may behave unexpectedly.</string>
+ <!-- [CHAR LIMIT=50] Unsupported display size dialog: check box label. -->
+ <string name="unsupported_display_size_show">Always show</string>
+
<!-- Text of the alert that is displayed when an application has violated StrictMode. -->
<string name="smv_application">The app <xliff:g id="application">%1$s</xliff:g>
(process <xliff:g id="process">%2$s</xliff:g>) has violated its self-enforced StrictMode policy.</string>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 7e9b57c7a49b..d154b034e058 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -2609,4 +2609,7 @@
<java-symbol type="array" name="config_defaultPinnerServiceFiles" />
<java-symbol type="string" name="suspended_widget_accessibility" />
+
+ <java-symbol type="layout" name="unsupported_display_size_dialog_content" />
+ <java-symbol type="string" name="unsupported_display_size_message" />
</resources>
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 402165ae2481..60acf756ba0a 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -102,7 +102,6 @@ import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.ProfilerInfo;
import android.app.admin.DevicePolicyManager;
-import android.app.admin.DevicePolicyManagerInternal;
import android.app.assist.AssistContent;
import android.app.assist.AssistStructure;
import android.app.backup.IBackupManager;
@@ -205,6 +204,7 @@ import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.AtomicFile;
import android.util.DebugUtils;
+import android.util.DisplayMetrics;
import android.util.EventLog;
import android.util.Log;
import android.util.Pair;
@@ -1513,6 +1513,7 @@ public final class ActivityManagerService extends ActivityManagerNative
static final int NOTIFY_FORCED_RESIZABLE_MSG = 67;
static final int NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG = 68;
static final int VR_MODE_APPLY_IF_NEEDED_MSG = 69;
+ static final int SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG = 70;
static final int FIRST_ACTIVITY_STACK_MSG = 100;
static final int FIRST_BROADCAST_QUEUE_MSG = 200;
@@ -1523,6 +1524,7 @@ public final class ActivityManagerService extends ActivityManagerNative
static KillHandler sKillHandler = null;
CompatModeDialog mCompatModeDialog;
+ UnsupportedDisplaySizeDialog mUnsupportedDisplaySizeDialog;
long mLastMemUsageReportTime = 0;
/**
@@ -1693,6 +1695,22 @@ public final class ActivityManagerService extends ActivityManagerNative
}
break;
}
+ case SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG: {
+ synchronized (ActivityManagerService.this) {
+ final ActivityRecord ar = (ActivityRecord) msg.obj;
+ if (mUnsupportedDisplaySizeDialog != null) {
+ mUnsupportedDisplaySizeDialog.dismiss();
+ mUnsupportedDisplaySizeDialog = null;
+ }
+ if (ar != null && mCompatModePackages.getPackageNotifyUnsupportedZoomLocked(
+ ar.packageName)) {
+ mUnsupportedDisplaySizeDialog = new UnsupportedDisplaySizeDialog(
+ ActivityManagerService.this, mContext, ar.info.applicationInfo);
+ mUnsupportedDisplaySizeDialog.show();
+ }
+ }
+ break;
+ }
case START_USER_SWITCH_UI_MSG: {
mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
break;
@@ -3099,6 +3117,16 @@ public final class ActivityManagerService extends ActivityManagerNative
mUiHandler.sendMessage(msg);
}
+ final void showUnsupportedZoomDialogIfNeededLocked(ActivityRecord r) {
+ if (mConfiguration.densityDpi != DisplayMetrics.DENSITY_DEVICE_STABLE
+ && r.appInfo.requiresSmallestWidthDp > mConfiguration.smallestScreenWidthDp) {
+ final Message msg = Message.obtain();
+ msg.what = SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG;
+ msg.obj = r;
+ mUiHandler.sendMessage(msg);
+ }
+ }
+
private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
String what, Object obj, ProcessRecord srcApp) {
app.lastActivityTime = now;
@@ -17763,6 +17791,14 @@ public final class ActivityManagerService extends ActivityManagerNative
removeUriPermissionsForPackageLocked(ssp, userId, true);
removeTasksByPackageNameLocked(ssp, userId);
+
+ // Hide the "unsupported display" dialog if necessary.
+ if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
+ mUnsupportedDisplaySizeDialog.getPackageName())) {
+ mUnsupportedDisplaySizeDialog.dismiss();
+ mUnsupportedDisplaySizeDialog = null;
+ }
+ mCompatModePackages.handlePackageUninstalledLocked(ssp);
mBatteryStatsService.notePackageUninstalled(ssp);
}
} else {
@@ -17834,6 +17870,21 @@ public final class ActivityManagerService extends ActivityManagerNative
}
break;
}
+ case Intent.ACTION_PACKAGE_DATA_CLEARED:
+ {
+ Uri data = intent.getData();
+ String ssp;
+ if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
+ // Hide the "unsupported display" dialog if necessary.
+ if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
+ mUnsupportedDisplaySizeDialog.getPackageName())) {
+ mUnsupportedDisplaySizeDialog.dismiss();
+ mUnsupportedDisplaySizeDialog = null;
+ }
+ mCompatModePackages.handlePackageDataClearedLocked(ssp);
+ }
+ break;
+ }
case Intent.ACTION_TIMEZONE_CHANGED:
// If this is the time zone changed action, queue up a message that will reset
// the timezone of all currently running processes. This message will get
@@ -18656,6 +18707,9 @@ public final class ActivityManagerService extends ActivityManagerNative
final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
if (isDensityChange) {
+ // Reset the unsupported display size dialog.
+ mUiHandler.sendEmptyMessage(SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG);
+
killAllBackgroundProcessesExcept(Build.VERSION_CODES.N,
ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
}
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index 0513b1ad8a8a..a5fb41741522 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -2481,6 +2481,7 @@ final class ActivityStack {
System.identityHashCode(next), next.task.taskId, next.shortComponentName);
next.sleeping = false;
+ mService.showUnsupportedZoomDialogIfNeededLocked(next);
mService.showAskCompatModeDialogLocked(next);
next.app.pendingUiClean = true;
next.app.forceProcessStateUpTo(mService.mTopProcessState);
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index 7a43d53d7021..15f0a903a2c8 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -1217,6 +1217,7 @@ public final class ActivityStackSupervisor implements DisplayListener {
PackageManager.NOTIFY_PACKAGE_USE_ACTIVITY);
r.sleeping = false;
r.forceNewConfig = false;
+ mService.showUnsupportedZoomDialogIfNeededLocked(r);
mService.showAskCompatModeDialogLocked(r);
r.compat = mService.compatibilityInfoForPackageLocked(r.info.applicationInfo);
ProfilerInfo profilerInfo = null;
diff --git a/services/core/java/com/android/server/am/CompatModePackages.java b/services/core/java/com/android/server/am/CompatModePackages.java
index 26264e5da147..a54df4bf069d 100644
--- a/services/core/java/com/android/server/am/CompatModePackages.java
+++ b/services/core/java/com/android/server/am/CompatModePackages.java
@@ -57,6 +57,8 @@ public final class CompatModePackages {
public static final int COMPAT_FLAG_DONT_ASK = 1<<0;
// Compatibility state: compatibility mode is enabled.
public static final int COMPAT_FLAG_ENABLED = 1<<1;
+ // Unsupported zoom state: don't warn the user about unsupported zoom mode.
+ public static final int UNSUPPORTED_ZOOM_FLAG_DONT_NOTIFY = 1<<2;
private final HashMap<String, Integer> mPackages = new HashMap<String, Integer>();
@@ -147,6 +149,24 @@ public final class CompatModePackages {
return flags != null ? flags : 0;
}
+ public void handlePackageDataClearedLocked(String packageName) {
+ // User has explicitly asked to clear all associated data.
+ removePackage(packageName);
+ }
+
+ public void handlePackageUninstalledLocked(String packageName) {
+ // Clear settings when app is uninstalled since this is an explicit
+ // signal from the user to remove the app and all associated data.
+ removePackage(packageName);
+ }
+
+ private void removePackage(String packageName) {
+ if (mPackages.containsKey(packageName)) {
+ mPackages.remove(packageName);
+ scheduleWrite();
+ }
+ }
+
public void handlePackageAddedLocked(String packageName, boolean updated) {
ApplicationInfo ai = null;
try {
@@ -165,13 +185,17 @@ public final class CompatModePackages {
// any current settings for it.
if (!mayCompat && mPackages.containsKey(packageName)) {
mPackages.remove(packageName);
- mHandler.removeMessages(MSG_WRITE);
- Message msg = mHandler.obtainMessage(MSG_WRITE);
- mHandler.sendMessageDelayed(msg, 10000);
+ scheduleWrite();
}
}
}
+ private void scheduleWrite() {
+ mHandler.removeMessages(MSG_WRITE);
+ Message msg = mHandler.obtainMessage(MSG_WRITE);
+ mHandler.sendMessageDelayed(msg, 10000);
+ }
+
public CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
CompatibilityInfo ci = new CompatibilityInfo(ai, mService.mConfiguration.screenLayout,
mService.mConfiguration.smallestScreenWidthDp,
@@ -207,6 +231,10 @@ public final class CompatModePackages {
return (getPackageFlags(packageName)&COMPAT_FLAG_DONT_ASK) == 0;
}
+ public boolean getPackageNotifyUnsupportedZoomLocked(String packageName) {
+ return (getPackageFlags(packageName)&UNSUPPORTED_ZOOM_FLAG_DONT_NOTIFY) == 0;
+ }
+
public void setFrontActivityAskCompatModeLocked(boolean ask) {
ActivityRecord r = mService.getFocusedStack().topRunningActivityLocked();
if (r != null) {
@@ -223,9 +251,21 @@ public final class CompatModePackages {
} else {
mPackages.remove(packageName);
}
- mHandler.removeMessages(MSG_WRITE);
- Message msg = mHandler.obtainMessage(MSG_WRITE);
- mHandler.sendMessageDelayed(msg, 10000);
+ scheduleWrite();
+ }
+ }
+
+ public void setPackageNotifyUnsupportedZoomLocked(String packageName, boolean notify) {
+ final int curFlags = getPackageFlags(packageName);
+ final int newFlags = notify ? (curFlags&~UNSUPPORTED_ZOOM_FLAG_DONT_NOTIFY) :
+ (curFlags|UNSUPPORTED_ZOOM_FLAG_DONT_NOTIFY);
+ if (curFlags != newFlags) {
+ if (newFlags != 0) {
+ mPackages.put(packageName, newFlags);
+ } else {
+ mPackages.remove(packageName);
+ }
+ scheduleWrite();
}
}
@@ -321,9 +361,7 @@ public final class CompatModePackages {
// Need to get compatibility info in new state.
ci = compatibilityInfoForPackageLocked(ai);
- mHandler.removeMessages(MSG_WRITE);
- Message msg = mHandler.obtainMessage(MSG_WRITE);
- mHandler.sendMessageDelayed(msg, 10000);
+ scheduleWrite();
final ActivityStack stack = mService.getFocusedStack();
ActivityRecord starting = stack.restartPackage(packageName);
diff --git a/services/core/java/com/android/server/am/UnsupportedDisplaySizeDialog.java b/services/core/java/com/android/server/am/UnsupportedDisplaySizeDialog.java
new file mode 100644
index 000000000000..501cd6bbba6d
--- /dev/null
+++ b/services/core/java/com/android/server/am/UnsupportedDisplaySizeDialog.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2011 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.am;
+
+import com.android.internal.R;
+
+import android.app.AlertDialog;
+import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.view.Window;
+import android.view.WindowManager;
+import android.widget.CheckBox;
+
+public class UnsupportedDisplaySizeDialog {
+ private final AlertDialog mDialog;
+ private final String mPackageName;
+
+ public UnsupportedDisplaySizeDialog(final ActivityManagerService service, Context context,
+ ApplicationInfo appInfo) {
+ mPackageName = appInfo.packageName;
+
+ final PackageManager pm = context.getPackageManager();
+ final CharSequence label = appInfo.loadSafeLabel(pm);
+ final CharSequence message = context.getString(
+ R.string.unsupported_display_size_message, label);
+
+ mDialog = new AlertDialog.Builder(context)
+ .setPositiveButton(R.string.ok, null)
+ .setMessage(message)
+ .setView(R.layout.unsupported_display_size_dialog_content)
+ .create();
+
+ // Ensure the content view is prepared.
+ 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("UnsupportedDisplaySizeDialog");
+
+ final CheckBox alwaysShow = (CheckBox) mDialog.findViewById(R.id.ask_checkbox);
+ alwaysShow.setChecked(true);
+ alwaysShow.setOnCheckedChangeListener((buttonView, isChecked) -> {
+ synchronized (service) {
+ service.mCompatModePackages.setPackageNotifyUnsupportedZoomLocked(
+ mPackageName, isChecked);
+ }
+ });
+ }
+
+ public String getPackageName() {
+ return mPackageName;
+ }
+
+ public void show() {
+ mDialog.show();
+ }
+
+ public void dismiss() {
+ mDialog.dismiss();
+ }
+}