Merge "Spiffy new compatibility mode UI." into honeycomb-mr2
This commit is contained in:
committed by
Android (Google) Code Review
commit
42f8094c06
@ -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
|
* Return the approximate per-application memory class of the current
|
||||||
* device. This gives you an idea of how hard a memory limit you should
|
* device. This gives you an idea of how hard a memory limit you should
|
||||||
|
@ -1437,6 +1437,26 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
|
|||||||
return true;
|
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);
|
return super.onTransact(code, data, reply, flags);
|
||||||
@ -3208,7 +3228,8 @@ class ActivityManagerProxy implements IActivityManager
|
|||||||
Parcel data = Parcel.obtain();
|
Parcel data = Parcel.obtain();
|
||||||
Parcel reply = Parcel.obtain();
|
Parcel reply = Parcel.obtain();
|
||||||
data.writeInterfaceToken(IActivityManager.descriptor);
|
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();
|
reply.readException();
|
||||||
int mode = reply.readInt();
|
int mode = reply.readInt();
|
||||||
reply.recycle();
|
reply.recycle();
|
||||||
@ -3229,5 +3250,31 @@ class ActivityManagerProxy implements IActivityManager
|
|||||||
data.recycle();
|
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;
|
private IBinder mRemote;
|
||||||
}
|
}
|
||||||
|
@ -347,6 +347,9 @@ public interface IActivityManager extends IInterface {
|
|||||||
public int getPackageScreenCompatMode(String packageName) throws RemoteException;
|
public int getPackageScreenCompatMode(String packageName) throws RemoteException;
|
||||||
public void setPackageScreenCompatMode(String packageName, int mode)
|
public void setPackageScreenCompatMode(String packageName, int mode)
|
||||||
throws RemoteException;
|
throws RemoteException;
|
||||||
|
public boolean getPackageAskScreenCompat(String packageName) throws RemoteException;
|
||||||
|
public void setPackageAskScreenCompat(String packageName, boolean ask)
|
||||||
|
throws RemoteException;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Private non-Binder interfaces
|
* 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 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 GET_PACKAGE_SCREEN_COMPAT_MODE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+125;
|
||||||
int SET_PACKAGE_SCREEN_COMPAT_MODE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+126;
|
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;
|
||||||
}
|
}
|
||||||
|
@ -113,8 +113,13 @@ public class CompatibilityInfo implements Parcelable {
|
|||||||
public CompatibilityInfo(ApplicationInfo appInfo, int screenLayout, boolean forceCompat) {
|
public CompatibilityInfo(ApplicationInfo appInfo, int screenLayout, boolean forceCompat) {
|
||||||
int compatFlags = 0;
|
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) {
|
if ((appInfo.flags & ApplicationInfo.FLAG_SUPPORTS_LARGE_SCREENS) != 0) {
|
||||||
compatFlags |= LARGE_SCREENS;
|
compatFlags |= LARGE_SCREENS;
|
||||||
|
anyResizeable = true;
|
||||||
if (!forceCompat) {
|
if (!forceCompat) {
|
||||||
// If we aren't forcing the app into compatibility mode, then
|
// If we aren't forcing the app into compatibility mode, then
|
||||||
// assume if it supports large screens that we should allow it
|
// 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) {
|
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) {
|
if ((appInfo.flags & ApplicationInfo.FLAG_RESIZEABLE_FOR_SCREENS) != 0) {
|
||||||
|
anyResizeable = true;
|
||||||
compatFlags |= EXPANDABLE;
|
compatFlags |= EXPANDABLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -160,7 +169,7 @@ public class CompatibilityInfo implements Parcelable {
|
|||||||
if ((screenLayout&Configuration.SCREENLAYOUT_COMPAT_NEEDED) != 0) {
|
if ((screenLayout&Configuration.SCREENLAYOUT_COMPAT_NEEDED) != 0) {
|
||||||
if ((compatFlags&EXPANDABLE) != 0) {
|
if ((compatFlags&EXPANDABLE) != 0) {
|
||||||
supportsScreen = true;
|
supportsScreen = true;
|
||||||
} else if ((appInfo.flags & ApplicationInfo.FLAG_RESIZEABLE_FOR_SCREENS) == 0) {
|
} else if (!anyResizeable) {
|
||||||
compatFlags |= ALWAYS_COMPAT;
|
compatFlags |= ALWAYS_COMPAT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
60
core/res/res/layout/am_compat_mode_dialog.xml
Normal file
60
core/res/res/layout/am_compat_mode_dialog.xml
Normal file
@ -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>
|
@ -2337,6 +2337,12 @@
|
|||||||
<string name="launch_warning_replace"><xliff:g id="app_name">%1$s</xliff:g> is now running.</string>
|
<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. -->
|
<!-- [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>
|
<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. -->
|
<!-- 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>
|
<string name="smv_application">The application <xliff:g id="application">%1$s</xliff:g>
|
||||||
|
@ -24,23 +24,11 @@
|
|||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:layout_width="wrap_content">
|
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
|
<FrameLayout
|
||||||
android:id="@+id/recents_bg_protect"
|
android:id="@+id/recents_bg_protect"
|
||||||
android:background="@drawable/recents_bg_protect_tile"
|
android:background="@drawable/recents_bg_protect_tile"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:layout_toLeftOf="@id/recents_compat_mode"
|
|
||||||
android:layout_alignParentBottom="true"
|
android:layout_alignParentBottom="true"
|
||||||
android:paddingBottom="@*android:dimen/status_bar_height"
|
android:paddingBottom="@*android:dimen/status_bar_height"
|
||||||
android:clipToPadding="false">
|
android:clipToPadding="false">
|
||||||
|
@ -358,15 +358,6 @@ public class RecentAppsPanel extends RelativeLayout implements StatusBarPanel, O
|
|||||||
mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
||||||
|
|
||||||
mRecentsContainer = (ListView) findViewById(R.id.recents_container);
|
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,
|
View footer = inflater.inflate(R.layout.status_bar_recent_panel_footer,
|
||||||
mRecentsContainer, false);
|
mRecentsContainer, false);
|
||||||
mRecentsContainer.setScrollbarFadingEnabled(true);
|
mRecentsContainer.setScrollbarFadingEnabled(true);
|
||||||
@ -504,6 +495,9 @@ public class RecentAppsPanel extends RelativeLayout implements StatusBarPanel, O
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void updateShownCompatMode() {
|
private void updateShownCompatMode() {
|
||||||
|
if (mCompatMode == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
final ActivityManager am = (ActivityManager)
|
final ActivityManager am = (ActivityManager)
|
||||||
mContext.getSystemService(Context.ACTIVITY_SERVICE);
|
mContext.getSystemService(Context.ACTIVITY_SERVICE);
|
||||||
int mode = am.getFrontActivityScreenCompatMode();
|
int mode = am.getFrontActivityScreenCompatMode();
|
||||||
|
@ -974,8 +974,10 @@ public final class ActivityManagerService extends ActivityManagerNative
|
|||||||
static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
|
static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
|
||||||
static final int CLEAR_DNS_CACHE = 28;
|
static final int CLEAR_DNS_CACHE = 28;
|
||||||
static final int UPDATE_HTTP_PROXY = 29;
|
static final int UPDATE_HTTP_PROXY = 29;
|
||||||
|
static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
|
||||||
|
|
||||||
AlertDialog mUidAlert;
|
AlertDialog mUidAlert;
|
||||||
|
CompatModeDialog mCompatModeDialog;
|
||||||
|
|
||||||
final Handler mHandler = new Handler() {
|
final Handler mHandler = new Handler() {
|
||||||
//public Handler() {
|
//public Handler() {
|
||||||
@ -1274,6 +1276,33 @@ public final class ActivityManagerService extends ActivityManagerNative
|
|||||||
sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
|
sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
|
||||||
}
|
}
|
||||||
} break;
|
} 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) {
|
void reportResumedActivityLocked(ActivityRecord r) {
|
||||||
//Slog.i(TAG, "**** REPORT RESUME: " + r);
|
//Slog.i(TAG, "**** REPORT RESUME: " + r);
|
||||||
|
|
||||||
@ -7819,8 +7860,14 @@ public final class ActivityManagerService extends ActivityManagerNative
|
|||||||
if (dumpAll) {
|
if (dumpAll) {
|
||||||
pw.println(" mConfigWillChange: " + mMainStack.mConfigWillChange);
|
pw.println(" mConfigWillChange: " + mMainStack.mConfigWillChange);
|
||||||
if (mCompatModePackages.getPackages().size() > 0) {
|
if (mCompatModePackages.getPackages().size() > 0) {
|
||||||
pw.print(" mScreenCompatPackages=");
|
pw.println(" mScreenCompatPackages:");
|
||||||
pw.println(mCompatModePackages.getPackages());
|
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);
|
pw.println(" mSleeping=" + mSleeping + " mShuttingDown=" + mShuttingDown);
|
||||||
|
@ -483,6 +483,13 @@ public class ActivityStack {
|
|||||||
return null;
|
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,
|
final boolean realStartActivityLocked(ActivityRecord r,
|
||||||
ProcessRecord app, boolean andResume, boolean checkConfig)
|
ProcessRecord app, boolean andResume, boolean checkConfig)
|
||||||
throws RemoteException {
|
throws RemoteException {
|
||||||
@ -538,6 +545,7 @@ public class ActivityStack {
|
|||||||
mService.ensurePackageDexOpt(r.intent.getComponent().getPackageName());
|
mService.ensurePackageDexOpt(r.intent.getComponent().getPackageName());
|
||||||
r.sleeping = false;
|
r.sleeping = false;
|
||||||
r.forceNewConfig = false;
|
r.forceNewConfig = false;
|
||||||
|
showAskCompatModeDialogLocked(r);
|
||||||
app.thread.scheduleLaunchActivity(new Intent(r.intent), r,
|
app.thread.scheduleLaunchActivity(new Intent(r.intent), r,
|
||||||
System.identityHashCode(r),
|
System.identityHashCode(r),
|
||||||
r.info, mService.compatibilityInfoForPackageLocked(r.info.applicationInfo),
|
r.info, mService.compatibilityInfoForPackageLocked(r.info.applicationInfo),
|
||||||
@ -1430,6 +1438,7 @@ public class ActivityStack {
|
|||||||
next.task.taskId, next.shortComponentName);
|
next.task.taskId, next.shortComponentName);
|
||||||
|
|
||||||
next.sleeping = false;
|
next.sleeping = false;
|
||||||
|
showAskCompatModeDialogLocked(next);
|
||||||
next.app.thread.scheduleResumeActivity(next,
|
next.app.thread.scheduleResumeActivity(next,
|
||||||
mService.isNextTransitionForward());
|
mService.isNextTransitionForward());
|
||||||
|
|
||||||
|
90
services/java/com/android/server/am/CompatModeDialog.java
Normal file
90
services/java/com/android/server/am/CompatModeDialog.java
Normal file
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -3,8 +3,10 @@ package com.android.server.am;
|
|||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import org.xmlpull.v1.XmlPullParser;
|
import org.xmlpull.v1.XmlPullParser;
|
||||||
import org.xmlpull.v1.XmlPullParserException;
|
import org.xmlpull.v1.XmlPullParserException;
|
||||||
@ -31,7 +33,12 @@ public class CompatModePackages {
|
|||||||
private final ActivityManagerService mService;
|
private final ActivityManagerService mService;
|
||||||
private final AtomicFile mFile;
|
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;
|
private static final int MSG_WRITE = 1;
|
||||||
|
|
||||||
@ -71,7 +78,15 @@ public class CompatModePackages {
|
|||||||
if ("pkg".equals(tagName)) {
|
if ("pkg".equals(tagName)) {
|
||||||
String pkg = parser.getAttributeValue(null, "name");
|
String pkg = parser.getAttributeValue(null, "name");
|
||||||
if (pkg != null) {
|
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;
|
return mPackages;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private int getPackageFlags(String packageName) {
|
||||||
|
Integer flags = mPackages.get(packageName);
|
||||||
|
return flags != null ? flags : 0;
|
||||||
|
}
|
||||||
|
|
||||||
public CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
|
public CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
|
||||||
return new CompatibilityInfo(ai, mService.mConfiguration.screenLayout,
|
return new CompatibilityInfo(ai, mService.mConfiguration.screenLayout,
|
||||||
mPackages.contains(ai.packageName));
|
(getPackageFlags(ai.packageName)&COMPAT_FLAG_ENABLED) != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
private int computeCompatModeLocked(ApplicationInfo ai) {
|
public int computeCompatModeLocked(ApplicationInfo ai) {
|
||||||
boolean enabled = mPackages.contains(ai.packageName);
|
boolean enabled = (getPackageFlags(ai.packageName)&COMPAT_FLAG_ENABLED) != 0;
|
||||||
CompatibilityInfo info = new CompatibilityInfo(ai,
|
CompatibilityInfo info = new CompatibilityInfo(ai,
|
||||||
mService.mConfiguration.screenLayout, enabled);
|
mService.mConfiguration.screenLayout, enabled);
|
||||||
if (info.alwaysSupportsScreen()) {
|
if (info.alwaysSupportsScreen()) {
|
||||||
@ -116,6 +136,40 @@ public class CompatModePackages {
|
|||||||
: ActivityManager.COMPAT_MODE_DISABLED;
|
: 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() {
|
public int getFrontActivityScreenCompatModeLocked() {
|
||||||
ActivityRecord r = mService.mMainStack.topRunningActivityLocked(null);
|
ActivityRecord r = mService.mMainStack.topRunningActivityLocked(null);
|
||||||
if (r == null) {
|
if (r == null) {
|
||||||
@ -161,7 +215,8 @@ public class CompatModePackages {
|
|||||||
private void setPackageScreenCompatModeLocked(ApplicationInfo ai, int mode) {
|
private void setPackageScreenCompatModeLocked(ApplicationInfo ai, int mode) {
|
||||||
final String packageName = ai.packageName;
|
final String packageName = ai.packageName;
|
||||||
|
|
||||||
boolean changed = false;
|
int curFlags = getPackageFlags(packageName);
|
||||||
|
|
||||||
boolean enable;
|
boolean enable;
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
case ActivityManager.COMPAT_MODE_DISABLED:
|
case ActivityManager.COMPAT_MODE_DISABLED:
|
||||||
@ -171,24 +226,26 @@ public class CompatModePackages {
|
|||||||
enable = true;
|
enable = true;
|
||||||
break;
|
break;
|
||||||
case ActivityManager.COMPAT_MODE_TOGGLE:
|
case ActivityManager.COMPAT_MODE_TOGGLE:
|
||||||
enable = !mPackages.contains(packageName);
|
enable = (curFlags&COMPAT_FLAG_ENABLED) == 0;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
Slog.w(TAG, "Unknown screen compat mode req #" + mode + "; ignoring");
|
Slog.w(TAG, "Unknown screen compat mode req #" + mode + "; ignoring");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int newFlags = curFlags;
|
||||||
if (enable) {
|
if (enable) {
|
||||||
if (!mPackages.contains(packageName)) {
|
newFlags |= COMPAT_FLAG_ENABLED;
|
||||||
changed = true;
|
|
||||||
mPackages.add(packageName);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
if (mPackages.contains(packageName)) {
|
newFlags &= ~COMPAT_FLAG_ENABLED;
|
||||||
changed = true;
|
}
|
||||||
|
|
||||||
|
if (newFlags != curFlags) {
|
||||||
|
if (newFlags != 0) {
|
||||||
|
mPackages.put(packageName, newFlags);
|
||||||
|
} else {
|
||||||
mPackages.remove(packageName);
|
mPackages.remove(packageName);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (changed) {
|
|
||||||
CompatibilityInfo ci = compatibilityInfoForPackageLocked(ai);
|
CompatibilityInfo ci = compatibilityInfoForPackageLocked(ai);
|
||||||
if (ci.alwaysSupportsScreen()) {
|
if (ci.alwaysSupportsScreen()) {
|
||||||
Slog.w(TAG, "Ignoring compat mode change of " + packageName
|
Slog.w(TAG, "Ignoring compat mode change of " + packageName
|
||||||
@ -241,9 +298,9 @@ public class CompatModePackages {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void saveCompatModes() {
|
void saveCompatModes() {
|
||||||
HashSet<String> pkgs;
|
HashMap<String, Integer> pkgs;
|
||||||
synchronized (mService) {
|
synchronized (mService) {
|
||||||
pkgs = new HashSet<String>(mPackages);
|
pkgs = new HashMap<String, Integer>(mPackages);
|
||||||
}
|
}
|
||||||
|
|
||||||
FileOutputStream fos = null;
|
FileOutputStream fos = null;
|
||||||
@ -258,9 +315,14 @@ public class CompatModePackages {
|
|||||||
|
|
||||||
final IPackageManager pm = AppGlobals.getPackageManager();
|
final IPackageManager pm = AppGlobals.getPackageManager();
|
||||||
final int screenLayout = mService.mConfiguration.screenLayout;
|
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()) {
|
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;
|
ApplicationInfo ai = null;
|
||||||
try {
|
try {
|
||||||
ai = pm.getApplicationInfo(pkg, 0);
|
ai = pm.getApplicationInfo(pkg, 0);
|
||||||
@ -278,6 +340,7 @@ public class CompatModePackages {
|
|||||||
}
|
}
|
||||||
out.startTag(null, "pkg");
|
out.startTag(null, "pkg");
|
||||||
out.attribute(null, "name", pkg);
|
out.attribute(null, "name", pkg);
|
||||||
|
out.attribute(null, "mode", Integer.toString(mode));
|
||||||
out.endTag(null, "pkg");
|
out.endTag(null, "pkg");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,6 +34,7 @@ class TaskRecord {
|
|||||||
long lastActiveTime; // Last time this task was active, including sleep.
|
long lastActiveTime; // Last time this task was active, including sleep.
|
||||||
boolean rootWasReset; // True if the intent at the root of the task had
|
boolean rootWasReset; // True if the intent at the root of the task had
|
||||||
// the FLAG_ACTIVITY_RESET_TASK_IF_NEEDED flag.
|
// 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.
|
Bitmap lastThumbnail; // Last thumbnail captured for this task.
|
||||||
CharSequence lastDescription; // Last description 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.print(prefix); pw.print("realActivity=");
|
||||||
pw.println(realActivity.flattenToShortString());
|
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(prefix); pw.print("lastActiveTime="); pw.print(lastActiveTime);
|
||||||
pw.print(" (inactive for ");
|
pw.print(" (inactive for ");
|
||||||
pw.print((getInactiveDuration()/1000)); pw.println("s)");
|
pw.print((getInactiveDuration()/1000)); pw.println("s)");
|
||||||
|
Reference in New Issue
Block a user