From e2515eebf42c763c0a2d9f873a153711778cfc17 Mon Sep 17 00:00:00 2001 From: Dianne Hackborn Date: Wed, 27 Apr 2011 18:52:56 -0400 Subject: Better compat mode part one: start scaling windows. First step of improving app screen size compatibility mode. When running in compat mode, an application's windows are scaled up on the screen rather than being small with 1:1 pixels. Currently we scale the application to fill the entire screen, so don't use an even pixel scaling. Though this may have some negative impact on the appearance (it looks okay to me), it has a big benefit of allowing us to now treat these apps as normal full-screens apps and do the normal transition animations as you move in and out and around in them. This introduces fun stuff in the input system to take care of modifying pointer coordinates to account for the app window surface scaling. The input dispatcher is told about the scale that is being applied to each window and, when there is one, adjusts pointer events appropriately as they are being sent to the transport. Also modified is CompatibilityInfo, which has been greatly simplified to not be so insane and incomprehendible. It is now simple -- when constructed it determines if the given app is compatible with the current screen size and density, and that is that. There are new APIs on ActivityManagerService to put applications that we would traditionally consider compatible with larger screens in compatibility mode. This is the start of a facility to have a UI affordance for a user to switch apps in and out of compatibility. To test switching of modes, there is a new variation of the "am" command to do this: am screen-compat [on|off] [package] This mode switching has the fundamentals of restarting activities when it is changed, though the state still needs to be persisted and the overall mode switch cleaned up. For the few small apps I have tested, things mostly seem to be working well. I know of one problem with the text selection handles being drawn at the wrong position because at some point the window offset is being scaled incorrectly. There are probably other similar issues around the interaction between two windows because the different window coordinate spaces are done in a hacky way instead of being formally integrated into the window manager layout process. Change-Id: Ie038e3746b448135117bd860859d74e360938557 --- core/java/android/app/ApplicationThreadNative.java | 65 ++++++++++++++++------ 1 file changed, 49 insertions(+), 16 deletions(-) (limited to 'core/java/android/app/ApplicationThreadNative.java') diff --git a/core/java/android/app/ApplicationThreadNative.java b/core/java/android/app/ApplicationThreadNative.java index aa26b0471fdf..e1d76a44e477 100644 --- a/core/java/android/app/ApplicationThreadNative.java +++ b/core/java/android/app/ApplicationThreadNative.java @@ -23,6 +23,7 @@ import android.content.pm.ActivityInfo; import android.content.pm.ApplicationInfo; import android.content.pm.ProviderInfo; import android.content.pm.ServiceInfo; +import android.content.res.CompatibilityInfo; import android.content.res.Configuration; import android.os.Binder; import android.os.Bundle; @@ -131,12 +132,13 @@ public abstract class ApplicationThreadNative extends Binder IBinder b = data.readStrongBinder(); int ident = data.readInt(); ActivityInfo info = ActivityInfo.CREATOR.createFromParcel(data); + CompatibilityInfo compatInfo = CompatibilityInfo.CREATOR.createFromParcel(data); Bundle state = data.readBundle(); List ri = data.createTypedArrayList(ResultInfo.CREATOR); List pi = data.createTypedArrayList(Intent.CREATOR); boolean notResumed = data.readInt() != 0; boolean isForward = data.readInt() != 0; - scheduleLaunchActivity(intent, b, ident, info, state, ri, pi, + scheduleLaunchActivity(intent, b, ident, info, compatInfo, state, ri, pi, notResumed, isForward); return true; } @@ -181,11 +183,12 @@ public abstract class ApplicationThreadNative extends Binder data.enforceInterface(IApplicationThread.descriptor); Intent intent = Intent.CREATOR.createFromParcel(data); ActivityInfo info = ActivityInfo.CREATOR.createFromParcel(data); + CompatibilityInfo compatInfo = CompatibilityInfo.CREATOR.createFromParcel(data); int resultCode = data.readInt(); String resultData = data.readString(); Bundle resultExtras = data.readBundle(); boolean sync = data.readInt() != 0; - scheduleReceiver(intent, info, resultCode, resultData, + scheduleReceiver(intent, info, compatInfo, resultCode, resultData, resultExtras, sync); return true; } @@ -194,7 +197,8 @@ public abstract class ApplicationThreadNative extends Binder data.enforceInterface(IApplicationThread.descriptor); IBinder token = data.readStrongBinder(); ServiceInfo info = ServiceInfo.CREATOR.createFromParcel(data); - scheduleCreateService(token, info); + CompatibilityInfo compatInfo = CompatibilityInfo.CREATOR.createFromParcel(data); + scheduleCreateService(token, info, compatInfo); return true; } @@ -256,12 +260,13 @@ public abstract class ApplicationThreadNative extends Binder int testMode = data.readInt(); boolean restrictedBackupMode = (data.readInt() != 0); Configuration config = Configuration.CREATOR.createFromParcel(data); + CompatibilityInfo compatInfo = CompatibilityInfo.CREATOR.createFromParcel(data); HashMap services = data.readHashMap(null); Bundle coreSettings = data.readBundle(); bindApplication(packageName, info, providers, testName, profileName, testArgs, testWatcher, testMode, restrictedBackupMode, - config, services, coreSettings); + config, compatInfo, services, coreSettings); return true; } @@ -389,8 +394,9 @@ public abstract class ApplicationThreadNative extends Binder { data.enforceInterface(IApplicationThread.descriptor); ApplicationInfo appInfo = ApplicationInfo.CREATOR.createFromParcel(data); + CompatibilityInfo compatInfo = CompatibilityInfo.CREATOR.createFromParcel(data); int backupMode = data.readInt(); - scheduleCreateBackupAgent(appInfo, backupMode); + scheduleCreateBackupAgent(appInfo, compatInfo, backupMode); return true; } @@ -398,7 +404,8 @@ public abstract class ApplicationThreadNative extends Binder { data.enforceInterface(IApplicationThread.descriptor); ApplicationInfo appInfo = ApplicationInfo.CREATOR.createFromParcel(data); - scheduleDestroyBackupAgent(appInfo); + CompatibilityInfo compatInfo = CompatibilityInfo.CREATOR.createFromParcel(data); + scheduleDestroyBackupAgent(appInfo, compatInfo); return true; } @@ -456,12 +463,20 @@ public abstract class ApplicationThreadNative extends Binder return true; } - case SET_CORE_SETTINGS: { + case SET_CORE_SETTINGS_TRANSACTION: { data.enforceInterface(IApplicationThread.descriptor); Bundle settings = data.readBundle(); setCoreSettings(settings); return true; } + + case UPDATE_PACKAGE_COMPATIBILITY_INFO_TRANSACTION: { + data.enforceInterface(IApplicationThread.descriptor); + String pkg = data.readString(); + CompatibilityInfo compat = CompatibilityInfo.CREATOR.createFromParcel(data); + updatePackageCompatibilityInfo(pkg, compat); + return true; + } } return super.onTransact(code, data, reply, flags); @@ -554,7 +569,8 @@ class ApplicationThreadProxy implements IApplicationThread { } public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident, - ActivityInfo info, Bundle state, List pendingResults, + ActivityInfo info, CompatibilityInfo compatInfo, Bundle state, + List pendingResults, List pendingNewIntents, boolean notResumed, boolean isForward) throws RemoteException { Parcel data = Parcel.obtain(); @@ -563,6 +579,7 @@ class ApplicationThreadProxy implements IApplicationThread { data.writeStrongBinder(token); data.writeInt(ident); info.writeToParcel(data, 0); + compatInfo.writeToParcel(data, 0); data.writeBundle(state); data.writeTypedList(pendingResults); data.writeTypedList(pendingNewIntents); @@ -619,12 +636,13 @@ class ApplicationThreadProxy implements IApplicationThread { } public final void scheduleReceiver(Intent intent, ActivityInfo info, - int resultCode, String resultData, + CompatibilityInfo compatInfo, int resultCode, String resultData, Bundle map, boolean sync) throws RemoteException { Parcel data = Parcel.obtain(); data.writeInterfaceToken(IApplicationThread.descriptor); intent.writeToParcel(data, 0); info.writeToParcel(data, 0); + compatInfo.writeToParcel(data, 0); data.writeInt(resultCode); data.writeString(resultData); data.writeBundle(map); @@ -634,32 +652,36 @@ class ApplicationThreadProxy implements IApplicationThread { data.recycle(); } - public final void scheduleCreateBackupAgent(ApplicationInfo app, int backupMode) - throws RemoteException { + public final void scheduleCreateBackupAgent(ApplicationInfo app, + CompatibilityInfo compatInfo, int backupMode) throws RemoteException { Parcel data = Parcel.obtain(); data.writeInterfaceToken(IApplicationThread.descriptor); app.writeToParcel(data, 0); + compatInfo.writeToParcel(data, 0); data.writeInt(backupMode); mRemote.transact(SCHEDULE_CREATE_BACKUP_AGENT_TRANSACTION, data, null, IBinder.FLAG_ONEWAY); data.recycle(); } - public final void scheduleDestroyBackupAgent(ApplicationInfo app) throws RemoteException { + public final void scheduleDestroyBackupAgent(ApplicationInfo app, + CompatibilityInfo compatInfo) throws RemoteException { Parcel data = Parcel.obtain(); data.writeInterfaceToken(IApplicationThread.descriptor); app.writeToParcel(data, 0); + compatInfo.writeToParcel(data, 0); mRemote.transact(SCHEDULE_DESTROY_BACKUP_AGENT_TRANSACTION, data, null, IBinder.FLAG_ONEWAY); data.recycle(); } - public final void scheduleCreateService(IBinder token, ServiceInfo info) - throws RemoteException { + public final void scheduleCreateService(IBinder token, ServiceInfo info, + CompatibilityInfo compatInfo) throws RemoteException { Parcel data = Parcel.obtain(); data.writeInterfaceToken(IApplicationThread.descriptor); data.writeStrongBinder(token); info.writeToParcel(data, 0); + compatInfo.writeToParcel(data, 0); mRemote.transact(SCHEDULE_CREATE_SERVICE_TRANSACTION, data, null, IBinder.FLAG_ONEWAY); data.recycle(); @@ -719,7 +741,7 @@ class ApplicationThreadProxy implements IApplicationThread { public final void bindApplication(String packageName, ApplicationInfo info, List providers, ComponentName testName, String profileName, Bundle testArgs, IInstrumentationWatcher testWatcher, int debugMode, - boolean restrictedBackupMode, Configuration config, + boolean restrictedBackupMode, Configuration config, CompatibilityInfo compatInfo, Map services, Bundle coreSettings) throws RemoteException { Parcel data = Parcel.obtain(); data.writeInterfaceToken(IApplicationThread.descriptor); @@ -738,6 +760,7 @@ class ApplicationThreadProxy implements IApplicationThread { data.writeInt(debugMode); data.writeInt(restrictedBackupMode ? 1 : 0); config.writeToParcel(data, 0); + compatInfo.writeToParcel(data, 0); data.writeMap(services); data.writeBundle(coreSettings); mRemote.transact(BIND_APPLICATION_TRANSACTION, data, null, @@ -952,6 +975,16 @@ class ApplicationThreadProxy implements IApplicationThread { Parcel data = Parcel.obtain(); data.writeInterfaceToken(IApplicationThread.descriptor); data.writeBundle(coreSettings); - mRemote.transact(SET_CORE_SETTINGS, data, null, IBinder.FLAG_ONEWAY); + mRemote.transact(SET_CORE_SETTINGS_TRANSACTION, data, null, IBinder.FLAG_ONEWAY); + } + + public void updatePackageCompatibilityInfo(String pkg, CompatibilityInfo info) + throws RemoteException { + Parcel data = Parcel.obtain(); + data.writeInterfaceToken(IApplicationThread.descriptor); + data.writeString(pkg); + info.writeToParcel(data, 0); + mRemote.transact(UPDATE_PACKAGE_COMPATIBILITY_INFO_TRANSACTION, data, null, + IBinder.FLAG_ONEWAY); } } -- cgit v1.2.3