diff options
author | Dianne Hackborn <hackbod@google.com> | 2011-05-26 10:00:00 -0700 |
---|---|---|
committer | Android Git Automerger <android-git-automerger@android.com> | 2011-05-26 10:00:00 -0700 |
commit | 80ef2a9745e6103efd9698577536bbfed1fd74f6 (patch) | |
tree | 2b507d2f664405313d5b9b6109777fa004ec807f | |
parent | a4e747445ac0bdd2cc561802c9c7abfedbd0d981 (diff) | |
parent | 42f8094c066209a65b09d53611ef5c93daba4c51 (diff) | |
download | frameworks_base-80ef2a9745e6103efd9698577536bbfed1fd74f6.zip frameworks_base-80ef2a9745e6103efd9698577536bbfed1fd74f6.tar.gz frameworks_base-80ef2a9745e6103efd9698577536bbfed1fd74f6.tar.bz2 |
am 42f8094c: Merge "Spiffy new compatibility mode UI." into honeycomb-mr2
* commit '42f8094c066209a65b09d53611ef5c93daba4c51':
Spiffy new compatibility mode UI.
13 files changed, 387 insertions, 46 deletions
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java index a70a219..48b8ca8 100644 --- a/core/java/android/app/ActivityManager.java +++ b/core/java/android/app/ActivityManager.java @@ -137,6 +137,25 @@ public class ActivityManager { } } + /** @hide */ + public boolean getPackageAskScreenCompat(String packageName) { + try { + return ActivityManagerNative.getDefault().getPackageAskScreenCompat(packageName); + } catch (RemoteException e) { + // System dead, we will be dead too soon! + return false; + } + } + + /** @hide */ + public void setPackageAskScreenCompat(String packageName, boolean ask) { + try { + ActivityManagerNative.getDefault().setPackageAskScreenCompat(packageName, ask); + } catch (RemoteException e) { + // System dead, we will be dead too soon! + } + } + /** * Return the approximate per-application memory class of the current * device. This gives you an idea of how hard a memory limit you should diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java index 4beb5cc..88293e8 100644 --- a/core/java/android/app/ActivityManagerNative.java +++ b/core/java/android/app/ActivityManagerNative.java @@ -1437,6 +1437,26 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM return true; } + case GET_PACKAGE_ASK_SCREEN_COMPAT_TRANSACTION: + { + data.enforceInterface(IActivityManager.descriptor); + String pkg = data.readString(); + boolean ask = getPackageAskScreenCompat(pkg); + reply.writeNoException(); + reply.writeInt(ask ? 1 : 0); + return true; + } + + case SET_PACKAGE_ASK_SCREEN_COMPAT_TRANSACTION: + { + data.enforceInterface(IActivityManager.descriptor); + String pkg = data.readString(); + boolean ask = data.readInt() != 0; + setPackageAskScreenCompat(pkg, ask); + reply.writeNoException(); + return true; + } + } return super.onTransact(code, data, reply, flags); @@ -3208,7 +3228,8 @@ class ActivityManagerProxy implements IActivityManager Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); data.writeInterfaceToken(IActivityManager.descriptor); - mRemote.transact(SET_PACKAGE_SCREEN_COMPAT_MODE_TRANSACTION, data, reply, 0); + data.writeString(packageName); + mRemote.transact(GET_PACKAGE_SCREEN_COMPAT_MODE_TRANSACTION, data, reply, 0); reply.readException(); int mode = reply.readInt(); reply.recycle(); @@ -3229,5 +3250,31 @@ class ActivityManagerProxy implements IActivityManager data.recycle(); } + public boolean getPackageAskScreenCompat(String packageName) throws RemoteException { + Parcel data = Parcel.obtain(); + Parcel reply = Parcel.obtain(); + data.writeInterfaceToken(IActivityManager.descriptor); + data.writeString(packageName); + mRemote.transact(GET_PACKAGE_ASK_SCREEN_COMPAT_TRANSACTION, data, reply, 0); + reply.readException(); + boolean ask = reply.readInt() != 0; + reply.recycle(); + data.recycle(); + return ask; + } + + public void setPackageAskScreenCompat(String packageName, boolean ask) + throws RemoteException { + Parcel data = Parcel.obtain(); + Parcel reply = Parcel.obtain(); + data.writeInterfaceToken(IActivityManager.descriptor); + data.writeString(packageName); + data.writeInt(ask ? 1 : 0); + mRemote.transact(SET_PACKAGE_ASK_SCREEN_COMPAT_TRANSACTION, data, reply, 0); + reply.readException(); + reply.recycle(); + data.recycle(); + } + private IBinder mRemote; } diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java index 24706f9..b0cbbb5 100644 --- a/core/java/android/app/IActivityManager.java +++ b/core/java/android/app/IActivityManager.java @@ -347,6 +347,9 @@ public interface IActivityManager extends IInterface { public int getPackageScreenCompatMode(String packageName) throws RemoteException; public void setPackageScreenCompatMode(String packageName, int mode) throws RemoteException; + public boolean getPackageAskScreenCompat(String packageName) throws RemoteException; + public void setPackageAskScreenCompat(String packageName, boolean ask) + throws RemoteException; /* * Private non-Binder interfaces @@ -567,4 +570,6 @@ public interface IActivityManager extends IInterface { int SET_FRONT_ACTIVITY_SCREEN_COMPAT_MODE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+124; int GET_PACKAGE_SCREEN_COMPAT_MODE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+125; int SET_PACKAGE_SCREEN_COMPAT_MODE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+126; + int GET_PACKAGE_ASK_SCREEN_COMPAT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+127; + int SET_PACKAGE_ASK_SCREEN_COMPAT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+128; } diff --git a/core/java/android/content/res/CompatibilityInfo.java b/core/java/android/content/res/CompatibilityInfo.java index 854d410..dca53a8 100644 --- a/core/java/android/content/res/CompatibilityInfo.java +++ b/core/java/android/content/res/CompatibilityInfo.java @@ -113,8 +113,13 @@ public class CompatibilityInfo implements Parcelable { public CompatibilityInfo(ApplicationInfo appInfo, int screenLayout, boolean forceCompat) { int compatFlags = 0; + // We can't rely on the application always setting + // FLAG_RESIZEABLE_FOR_SCREENS so will compute it based on various input. + boolean anyResizeable = false; + if ((appInfo.flags & ApplicationInfo.FLAG_SUPPORTS_LARGE_SCREENS) != 0) { compatFlags |= LARGE_SCREENS; + anyResizeable = true; if (!forceCompat) { // If we aren't forcing the app into compatibility mode, then // assume if it supports large screens that we should allow it @@ -123,9 +128,13 @@ public class CompatibilityInfo implements Parcelable { } } if ((appInfo.flags & ApplicationInfo.FLAG_SUPPORTS_XLARGE_SCREENS) != 0) { - compatFlags |= XLARGE_SCREENS | EXPANDABLE; + anyResizeable = true; + if (!forceCompat) { + compatFlags |= XLARGE_SCREENS | EXPANDABLE; + } } if ((appInfo.flags & ApplicationInfo.FLAG_RESIZEABLE_FOR_SCREENS) != 0) { + anyResizeable = true; compatFlags |= EXPANDABLE; } @@ -160,7 +169,7 @@ public class CompatibilityInfo implements Parcelable { if ((screenLayout&Configuration.SCREENLAYOUT_COMPAT_NEEDED) != 0) { if ((compatFlags&EXPANDABLE) != 0) { supportsScreen = true; - } else if ((appInfo.flags & ApplicationInfo.FLAG_RESIZEABLE_FOR_SCREENS) == 0) { + } else if (!anyResizeable) { compatFlags |= ALWAYS_COMPAT; } } diff --git a/core/res/res/layout/am_compat_mode_dialog.xml b/core/res/res/layout/am_compat_mode_dialog.xml new file mode 100644 index 0000000..a8d39cf --- /dev/null +++ b/core/res/res/layout/am_compat_mode_dialog.xml @@ -0,0 +1,60 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + * 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. +--> + +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" android:layout_height="match_parent" + android:layout_marginLeft="40dp" android:layout_marginRight="40dp" + android:layout_marginTop="15dp" android:layout_marginBottom="15dp" + android:orientation="vertical"> + <LinearLayout + android:layout_width="wrap_content" android:layout_height="wrap_content" + android:layout_gravity="center_horizontal" + android:orientation="horizontal" android:baselineAligned="true"> + <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" + android:layout_marginLeft="10dp" android:layout_marginRight="10dp" + android:textColor="?android:attr/textColorPrimary" + android:textSize="18sp" + android:text="@string/screen_compat_mode_scale" + /> + <Switch + android:id="@+id/compat_checkbox" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="center_vertical" + android:layout_marginRight="10dp" + /> + </LinearLayout> + + <View android:layout_width="wrap_content" android:layout_height="1dp" + android:layout_marginTop="10dp" android:layout_marginBottom="10dp" + android:background="@android:drawable/divider_horizontal_dark" + /> + + <CheckBox android:id="@+id/ask_checkbox" + android:layout_width="wrap_content" android:layout_height="wrap_content" + android:layout_gravity="center_horizontal" + android:text="@string/screen_compat_mode_show" + /> + <TextView + android:id="@+id/reask_hint" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:textAppearance="?android:attr/textAppearanceSmall" + android:gravity="center" + android:visibility="invisible" + android:text="@string/screen_compat_mode_hint" /> +</LinearLayout> diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml index 247f5fd..a7d0d78 100755 --- a/core/res/res/values/strings.xml +++ b/core/res/res/values/strings.xml @@ -2337,6 +2337,12 @@ <string name="launch_warning_replace"><xliff:g id="app_name">%1$s</xliff:g> is now running.</string> <!-- [CHAR LIMIT=50] Title of the alert when application launches on top of another. --> <string name="launch_warning_original"><xliff:g id="app_name">%1$s</xliff:g> was originally launched.</string> + <!-- [CHAR LIMIT=50] Compat mode dialog: compat mode switch label. --> + <string name="screen_compat_mode_scale">Scale</string> + <!-- [CHAR LIMIT=50] Compat mode dialog: compat mode switch label. --> + <string name="screen_compat_mode_show">Always show</string> + <!-- [CHAR LIMIT=200] Compat mode dialog: hint to re-enable compat mode dialog. --> + <string name="screen_compat_mode_hint">Re-enable this with Settings > Applications > Manage applications.</string> <!-- Text of the alert that is displayed when an application has violated StrictMode. --> <string name="smv_application">The application <xliff:g id="application">%1$s</xliff:g> diff --git a/packages/SystemUI/res/layout-sw600dp/status_bar_recent_panel.xml b/packages/SystemUI/res/layout-sw600dp/status_bar_recent_panel.xml index f019e2d..42940be 100644 --- a/packages/SystemUI/res/layout-sw600dp/status_bar_recent_panel.xml +++ b/packages/SystemUI/res/layout-sw600dp/status_bar_recent_panel.xml @@ -24,23 +24,11 @@ android:layout_height="match_parent" android:layout_width="wrap_content"> - <CheckBox android:id="@+id/recents_compat_mode" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_alignParentBottom="true" - android:layout_alignParentRight="true" - android:layout_marginLeft="16dp" - android:layout_marginBottom="@*android:dimen/status_bar_height" - android:background="@drawable/hd" - android:button="@null" - /> - <FrameLayout android:id="@+id/recents_bg_protect" android:background="@drawable/recents_bg_protect_tile" android:layout_width="wrap_content" android:layout_height="match_parent" - android:layout_toLeftOf="@id/recents_compat_mode" android:layout_alignParentBottom="true" android:paddingBottom="@*android:dimen/status_bar_height" android:clipToPadding="false"> diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/RecentAppsPanel.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/RecentAppsPanel.java index 7db1ce8..fd07a5a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/RecentAppsPanel.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/RecentAppsPanel.java @@ -358,15 +358,6 @@ public class RecentAppsPanel extends RelativeLayout implements StatusBarPanel, O mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); mRecentsContainer = (ListView) findViewById(R.id.recents_container); - mCompatMode = (CheckBox) findViewById(R.id.recents_compat_mode); - mCompatMode.setOnClickListener(new OnClickListener() { - public void onClick(View v) { - final ActivityManager am = (ActivityManager) - mContext.getSystemService(Context.ACTIVITY_SERVICE); - am.setFrontActivityScreenCompatMode(ActivityManager.COMPAT_MODE_TOGGLE); - hide(true); - } - }); View footer = inflater.inflate(R.layout.status_bar_recent_panel_footer, mRecentsContainer, false); mRecentsContainer.setScrollbarFadingEnabled(true); @@ -504,6 +495,9 @@ public class RecentAppsPanel extends RelativeLayout implements StatusBarPanel, O } private void updateShownCompatMode() { + if (mCompatMode == null) { + return; + } final ActivityManager am = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE); int mode = am.getFrontActivityScreenCompatMode(); diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java index 6619caf..65b3258 100644 --- a/services/java/com/android/server/am/ActivityManagerService.java +++ b/services/java/com/android/server/am/ActivityManagerService.java @@ -974,8 +974,10 @@ public final class ActivityManagerService extends ActivityManagerNative static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; static final int CLEAR_DNS_CACHE = 28; static final int UPDATE_HTTP_PROXY = 29; + static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; AlertDialog mUidAlert; + CompatModeDialog mCompatModeDialog; final Handler mHandler = new Handler() { //public Handler() { @@ -1274,6 +1276,33 @@ public final class ActivityManagerService extends ActivityManagerNative sendMessageDelayed(nmsg, POWER_CHECK_DELAY); } } break; + case SHOW_COMPAT_MODE_DIALOG_MSG: { + synchronized (ActivityManagerService.this) { + ActivityRecord ar = (ActivityRecord)msg.obj; + if (mCompatModeDialog != null) { + if (mCompatModeDialog.mAppInfo.packageName.equals( + ar.info.applicationInfo.packageName)) { + return; + } + mCompatModeDialog.dismiss(); + mCompatModeDialog = null; + } + if (ar != null) { + if (mCompatModePackages.getPackageAskCompatModeLocked( + ar.packageName)) { + int mode = mCompatModePackages.computeCompatModeLocked( + ar.info.applicationInfo); + if (mode == ActivityManager.COMPAT_MODE_DISABLED + || mode == ActivityManager.COMPAT_MODE_ENABLED) { + mCompatModeDialog = new CompatModeDialog( + ActivityManagerService.this, mContext, + ar.info.applicationInfo); + mCompatModeDialog.show(); + } + } + } + } + } } } }; @@ -2101,6 +2130,18 @@ public final class ActivityManagerService extends ActivityManagerNative } } + public boolean getPackageAskScreenCompat(String packageName) { + synchronized (this) { + return mCompatModePackages.getPackageAskCompatModeLocked(packageName); + } + } + + public void setPackageAskScreenCompat(String packageName, boolean ask) { + synchronized (this) { + mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); + } + } + void reportResumedActivityLocked(ActivityRecord r) { //Slog.i(TAG, "**** REPORT RESUME: " + r); @@ -7819,8 +7860,14 @@ public final class ActivityManagerService extends ActivityManagerNative if (dumpAll) { pw.println(" mConfigWillChange: " + mMainStack.mConfigWillChange); if (mCompatModePackages.getPackages().size() > 0) { - pw.print(" mScreenCompatPackages="); - pw.println(mCompatModePackages.getPackages()); + pw.println(" mScreenCompatPackages:"); + for (Map.Entry<String, Integer> entry + : mCompatModePackages.getPackages().entrySet()) { + String pkg = entry.getKey(); + int mode = entry.getValue(); + pw.print(" "); pw.print(pkg); pw.print(": "); + pw.print(mode); pw.println(); + } } } pw.println(" mSleeping=" + mSleeping + " mShuttingDown=" + mShuttingDown); diff --git a/services/java/com/android/server/am/ActivityStack.java b/services/java/com/android/server/am/ActivityStack.java index f385042..a704f88 100644 --- a/services/java/com/android/server/am/ActivityStack.java +++ b/services/java/com/android/server/am/ActivityStack.java @@ -483,6 +483,13 @@ public class ActivityStack { return null; } + final void showAskCompatModeDialogLocked(ActivityRecord r) { + Message msg = Message.obtain(); + msg.what = ActivityManagerService.SHOW_COMPAT_MODE_DIALOG_MSG; + msg.obj = r.task.askedCompatMode ? null : r; + mService.mHandler.sendMessage(msg); + } + final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app, boolean andResume, boolean checkConfig) throws RemoteException { @@ -538,6 +545,7 @@ public class ActivityStack { mService.ensurePackageDexOpt(r.intent.getComponent().getPackageName()); r.sleeping = false; r.forceNewConfig = false; + showAskCompatModeDialogLocked(r); app.thread.scheduleLaunchActivity(new Intent(r.intent), r, System.identityHashCode(r), r.info, mService.compatibilityInfoForPackageLocked(r.info.applicationInfo), @@ -1430,6 +1438,7 @@ public class ActivityStack { next.task.taskId, next.shortComponentName); next.sleeping = false; + showAskCompatModeDialogLocked(next); next.app.thread.scheduleResumeActivity(next, mService.isNextTransitionForward()); diff --git a/services/java/com/android/server/am/CompatModeDialog.java b/services/java/com/android/server/am/CompatModeDialog.java new file mode 100644 index 0000000..0442bda --- /dev/null +++ b/services/java/com/android/server/am/CompatModeDialog.java @@ -0,0 +1,90 @@ +/* + * 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 android.app.ActivityManager; +import android.app.Dialog; +import android.content.Context; +import android.content.pm.ApplicationInfo; +import android.view.Gravity; +import android.view.View; +import android.view.Window; +import android.view.WindowManager; +import android.widget.CheckBox; +import android.widget.CompoundButton; +import android.widget.Switch; + +public class CompatModeDialog extends Dialog { + final ActivityManagerService mService; + final ApplicationInfo mAppInfo; + + final Switch mCompatEnabled; + final CheckBox mAlwaysShow; + final View mHint; + + public CompatModeDialog(ActivityManagerService service, Context context, + ApplicationInfo appInfo) { + super(context, com.android.internal.R.style.Theme_Holo_Dialog_MinWidth); + setCancelable(true); + setCanceledOnTouchOutside(true); + getWindow().requestFeature(Window.FEATURE_NO_TITLE); + getWindow().setType(WindowManager.LayoutParams.TYPE_PHONE); + getWindow().setGravity(Gravity.BOTTOM|Gravity.CENTER_HORIZONTAL); + mService = service; + mAppInfo = appInfo; + + setContentView(com.android.internal.R.layout.am_compat_mode_dialog); + mCompatEnabled = (Switch)findViewById(com.android.internal.R.id.compat_checkbox); + mCompatEnabled.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { + synchronized (mService) { + mService.mCompatModePackages.setPackageScreenCompatModeLocked( + mAppInfo.packageName, + mCompatEnabled.isChecked() ? ActivityManager.COMPAT_MODE_ENABLED + : ActivityManager.COMPAT_MODE_DISABLED); + updateControls(); + } + } + }); + mAlwaysShow = (CheckBox)findViewById(com.android.internal.R.id.ask_checkbox); + mAlwaysShow.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { + synchronized (mService) { + mService.mCompatModePackages.setPackageAskCompatModeLocked( + mAppInfo.packageName, mAlwaysShow.isChecked()); + updateControls(); + } + } + }); + mHint = findViewById(com.android.internal.R.id.reask_hint); + + updateControls(); + } + + void updateControls() { + synchronized (mService) { + int mode = mService.mCompatModePackages.computeCompatModeLocked(mAppInfo); + mCompatEnabled.setChecked(mode == ActivityManager.COMPAT_MODE_ENABLED); + boolean ask = mService.mCompatModePackages.getPackageAskCompatModeLocked( + mAppInfo.packageName); + mAlwaysShow.setChecked(ask); + mHint.setVisibility(ask ? View.INVISIBLE : View.VISIBLE); + } + } +} diff --git a/services/java/com/android/server/am/CompatModePackages.java b/services/java/com/android/server/am/CompatModePackages.java index 1faf8da..1277bca 100644 --- a/services/java/com/android/server/am/CompatModePackages.java +++ b/services/java/com/android/server/am/CompatModePackages.java @@ -3,8 +3,10 @@ package com.android.server.am; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; +import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; +import java.util.Map; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; @@ -31,7 +33,12 @@ public class CompatModePackages { private final ActivityManagerService mService; private final AtomicFile mFile; - private final HashSet<String> mPackages = new HashSet<String>(); + // Compatibility state: no longer ask user to select the mode. + 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; + + private final HashMap<String, Integer> mPackages = new HashMap<String, Integer>(); private static final int MSG_WRITE = 1; @@ -71,7 +78,15 @@ public class CompatModePackages { if ("pkg".equals(tagName)) { String pkg = parser.getAttributeValue(null, "name"); if (pkg != null) { - mPackages.add(pkg); + String mode = parser.getAttributeValue(null, "mode"); + int modeInt = 0; + if (mode != null) { + try { + modeInt = Integer.parseInt(mode); + } catch (NumberFormatException e) { + } + } + mPackages.put(pkg, modeInt); } } } @@ -93,17 +108,22 @@ public class CompatModePackages { } } - public HashSet<String> getPackages() { + public HashMap<String, Integer> getPackages() { return mPackages; } + private int getPackageFlags(String packageName) { + Integer flags = mPackages.get(packageName); + return flags != null ? flags : 0; + } + public CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { return new CompatibilityInfo(ai, mService.mConfiguration.screenLayout, - mPackages.contains(ai.packageName)); + (getPackageFlags(ai.packageName)&COMPAT_FLAG_ENABLED) != 0); } - private int computeCompatModeLocked(ApplicationInfo ai) { - boolean enabled = mPackages.contains(ai.packageName); + public int computeCompatModeLocked(ApplicationInfo ai) { + boolean enabled = (getPackageFlags(ai.packageName)&COMPAT_FLAG_ENABLED) != 0; CompatibilityInfo info = new CompatibilityInfo(ai, mService.mConfiguration.screenLayout, enabled); if (info.alwaysSupportsScreen()) { @@ -116,6 +136,40 @@ public class CompatModePackages { : ActivityManager.COMPAT_MODE_DISABLED; } + public boolean getFrontActivityAskCompatModeLocked() { + ActivityRecord r = mService.mMainStack.topRunningActivityLocked(null); + if (r == null) { + return false; + } + return getPackageAskCompatModeLocked(r.packageName); + } + + public boolean getPackageAskCompatModeLocked(String packageName) { + return (getPackageFlags(packageName)&COMPAT_FLAG_DONT_ASK) == 0; + } + + public void setFrontActivityAskCompatModeLocked(boolean ask) { + ActivityRecord r = mService.mMainStack.topRunningActivityLocked(null); + if (r != null) { + setPackageAskCompatModeLocked(r.packageName, ask); + } + } + + public void setPackageAskCompatModeLocked(String packageName, boolean ask) { + int curFlags = getPackageFlags(packageName); + int newFlags = ask ? (curFlags&~COMPAT_FLAG_DONT_ASK) : (curFlags|COMPAT_FLAG_DONT_ASK); + if (curFlags != newFlags) { + if (newFlags != 0) { + mPackages.put(packageName, newFlags); + } else { + mPackages.remove(packageName); + } + mHandler.removeMessages(MSG_WRITE); + Message msg = mHandler.obtainMessage(MSG_WRITE); + mHandler.sendMessageDelayed(msg, 10000); + } + } + public int getFrontActivityScreenCompatModeLocked() { ActivityRecord r = mService.mMainStack.topRunningActivityLocked(null); if (r == null) { @@ -161,7 +215,8 @@ public class CompatModePackages { private void setPackageScreenCompatModeLocked(ApplicationInfo ai, int mode) { final String packageName = ai.packageName; - boolean changed = false; + int curFlags = getPackageFlags(packageName); + boolean enable; switch (mode) { case ActivityManager.COMPAT_MODE_DISABLED: @@ -171,24 +226,26 @@ public class CompatModePackages { enable = true; break; case ActivityManager.COMPAT_MODE_TOGGLE: - enable = !mPackages.contains(packageName); + enable = (curFlags&COMPAT_FLAG_ENABLED) == 0; break; default: Slog.w(TAG, "Unknown screen compat mode req #" + mode + "; ignoring"); return; } + + int newFlags = curFlags; if (enable) { - if (!mPackages.contains(packageName)) { - changed = true; - mPackages.add(packageName); - } + newFlags |= COMPAT_FLAG_ENABLED; } else { - if (mPackages.contains(packageName)) { - changed = true; + newFlags &= ~COMPAT_FLAG_ENABLED; + } + + if (newFlags != curFlags) { + if (newFlags != 0) { + mPackages.put(packageName, newFlags); + } else { mPackages.remove(packageName); } - } - if (changed) { CompatibilityInfo ci = compatibilityInfoForPackageLocked(ai); if (ci.alwaysSupportsScreen()) { Slog.w(TAG, "Ignoring compat mode change of " + packageName @@ -241,9 +298,9 @@ public class CompatModePackages { } void saveCompatModes() { - HashSet<String> pkgs; + HashMap<String, Integer> pkgs; synchronized (mService) { - pkgs = new HashSet<String>(mPackages); + pkgs = new HashMap<String, Integer>(mPackages); } FileOutputStream fos = null; @@ -258,9 +315,14 @@ public class CompatModePackages { final IPackageManager pm = AppGlobals.getPackageManager(); final int screenLayout = mService.mConfiguration.screenLayout; - final Iterator<String> it = pkgs.iterator(); + final Iterator<Map.Entry<String, Integer>> it = pkgs.entrySet().iterator(); while (it.hasNext()) { - String pkg = it.next(); + Map.Entry<String, Integer> entry = it.next(); + String pkg = entry.getKey(); + int mode = entry.getValue(); + if (mode == 0) { + continue; + } ApplicationInfo ai = null; try { ai = pm.getApplicationInfo(pkg, 0); @@ -278,6 +340,7 @@ public class CompatModePackages { } out.startTag(null, "pkg"); out.attribute(null, "name", pkg); + out.attribute(null, "mode", Integer.toString(mode)); out.endTag(null, "pkg"); } diff --git a/services/java/com/android/server/am/TaskRecord.java b/services/java/com/android/server/am/TaskRecord.java index 86cec42..76b4914 100644 --- a/services/java/com/android/server/am/TaskRecord.java +++ b/services/java/com/android/server/am/TaskRecord.java @@ -34,6 +34,7 @@ class TaskRecord { long lastActiveTime; // Last time this task was active, including sleep. boolean rootWasReset; // True if the intent at the root of the task had // the FLAG_ACTIVITY_RESET_TASK_IF_NEEDED flag. + boolean askedCompatMode;// Have asked the user about compat mode for this task. Bitmap lastThumbnail; // Last thumbnail captured for this task. CharSequence lastDescription; // Last description captured for this task. @@ -114,6 +115,9 @@ class TaskRecord { pw.print(prefix); pw.print("realActivity="); pw.println(realActivity.flattenToShortString()); } + if (!askedCompatMode) { + pw.print(prefix); pw.print("askedCompatMode="); pw.println(askedCompatMode); + } pw.print(prefix); pw.print("lastActiveTime="); pw.print(lastActiveTime); pw.print(" (inactive for "); pw.print((getInactiveDuration()/1000)); pw.println("s)"); |