Merge "Consume event on singleTapUp."
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index ec0cc6d..d4e6c82 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -100,6 +100,16 @@
public static final String CONNECTIVITY_ACTION = "android.net.conn.CONNECTIVITY_CHANGE";
/**
+ * A temporary hack until SUPL system can get off the legacy APIS.
+ * They do too many network requests and the long list of apps listening
+ * and waking due to the CONNECTIVITY_ACTION bcast makes it expensive.
+ * Use this bcast intent instead for SUPL requests.
+ * @hide
+ */
+ public static final String CONNECTIVITY_ACTION_SUPL =
+ "android.net.conn.CONNECTIVITY_CHANGE_SUPL";
+
+ /**
* The device has connected to a network that has presented a captive
* portal, which is blocking Internet connectivity. The user was presented
* with a notification that network sign in is required,
diff --git a/core/java/com/android/internal/view/FloatingActionMode.java b/core/java/com/android/internal/view/FloatingActionMode.java
index 9761661..44df0ce 100644
--- a/core/java/com/android/internal/view/FloatingActionMode.java
+++ b/core/java/com/android/internal/view/FloatingActionMode.java
@@ -76,6 +76,15 @@
mMenu = new MenuBuilder(context).setDefaultShowAsAction(
MenuItem.SHOW_AS_ACTION_IF_ROOM);
setType(ActionMode.TYPE_FLOATING);
+ mMenu.setCallback(new MenuBuilder.Callback() {
+ @Override
+ public void onMenuModeChange(MenuBuilder menu) {}
+
+ @Override
+ public boolean onMenuItemSelected(MenuBuilder menu, MenuItem item) {
+ return mCallback.onActionItemClicked(FloatingActionMode.this, item);
+ }
+ });
mContentRect = new Rect();
mContentRectOnScreen = new Rect();
mPreviousContentRectOnScreen = new Rect();
@@ -99,7 +108,7 @@
.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
- return mCallback.onActionItemClicked(FloatingActionMode.this, item);
+ return mMenu.performItemAction(item, 0);
}
});
mFloatingToolbarVisibilityHelper = new FloatingToolbarVisibilityHelper(mFloatingToolbar);
diff --git a/core/res/res/values-mcc204-mnc12/config.xml b/core/res/res/values-mcc204-mnc12/config.xml
new file mode 100644
index 0000000..80432d7
--- /dev/null
+++ b/core/res/res/values-mcc204-mnc12/config.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2015, 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 my 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.
+*/
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Don't use roaming icon for considered operators -->
+ <string-array translatable="false" name="config_operatorConsideredNonRoaming">
+ <item>20408</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-mcc450-mnc06/config.xml b/core/res/res/values-mcc450-mnc06/config.xml
index 63f9823..819c2a5 100644
--- a/core/res/res/values-mcc450-mnc06/config.xml
+++ b/core/res/res/values-mcc450-mnc06/config.xml
@@ -25,4 +25,7 @@
-->
<integer name="config_mobile_mtu">1428</integer>
+ <!-- Do not set the system language as value of EF LI/EF PL -->
+ <bool name="config_use_sim_language_file">false</bool>
+
</resources>
diff --git a/core/res/res/values-mcc450-mnc08/config.xml b/core/res/res/values-mcc450-mnc08/config.xml
index 950c62b..ca26ec1 100644
--- a/core/res/res/values-mcc450-mnc08/config.xml
+++ b/core/res/res/values-mcc450-mnc08/config.xml
@@ -25,4 +25,7 @@
-->
<integer name="config_mobile_mtu">1450</integer>
+ <!-- Do not set the system language as value of EF LI/EF PL -->
+ <bool name="config_use_sim_language_file">false</bool>
+
</resources>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index c313392..e43a8d3 100755
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -170,6 +170,21 @@
so that applications can still use their own mechanisms. -->
<bool name="config_enableAutoPowerModes">false</bool>
+ <!-- The threshold angle for any motion detection in auto-power save modes.
+ In hundreths of a degree. -->
+ <integer name="config_autoPowerModeThresholdAngle">200</integer>
+
+ <!-- The sensor id of an "any motion" sensor used in auto-power save modes.
+ 0 indicates this sensor is not available. -->
+ <integer name="config_autoPowerModeAnyMotionSensor">0</integer>
+
+ <!-- If an any motion sensor is not available, prefer the wrist tilt detector over the
+ SMD. -->
+ <bool name="config_autoPowerModePreferWristTilt">false</bool>
+
+ <!-- If a location should be pre-fetched when going into device idle. -->
+ <bool name="config_autoPowerModePrefetchLocation">true</bool>
+
<!-- The duration (in milliseconds) that the radio will scan for a signal
when there's no network connection. If the scan doesn't timeout, use zero -->
<integer name="config_radioScanningTimeout">0</integer>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 1cf1c1f..48a7a1c5 100755
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -254,6 +254,10 @@
<java-symbol type="bool" name="config_cellBroadcastAppLinks" />
<java-symbol type="bool" name="config_duplicate_port_omadm_wappush" />
<java-symbol type="bool" name="config_enableAutoPowerModes" />
+ <java-symbol type="integer" name="config_autoPowerModeThresholdAngle" />
+ <java-symbol type="integer" name="config_autoPowerModeAnyMotionSensor" />
+ <java-symbol type="bool" name="config_autoPowerModePreferWristTilt" />
+ <java-symbol type="bool" name="config_autoPowerModePrefetchLocation" />
<java-symbol type="bool" name="config_enable_emergency_call_while_sim_locked" />
<java-symbol type="bool" name="config_enable_puk_unlock_screen" />
<java-symbol type="bool" name="config_enableBurnInProtection" />
diff --git a/core/tests/bluetoothtests/AndroidManifest.xml b/core/tests/bluetoothtests/AndroidManifest.xml
index e43ba12..7f9d874 100644
--- a/core/tests/bluetoothtests/AndroidManifest.xml
+++ b/core/tests/bluetoothtests/AndroidManifest.xml
@@ -21,6 +21,7 @@
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.BROADCAST_STICKY" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
+ <uses-permission android:name="android.permission.LOCAL_MAC_ADDRESS" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_SETTINGS" />
diff --git a/libs/hwui/utils/LinearAllocator.cpp b/libs/hwui/utils/LinearAllocator.cpp
index 01cf5d2..0abe88b 100644
--- a/libs/hwui/utils/LinearAllocator.cpp
+++ b/libs/hwui/utils/LinearAllocator.cpp
@@ -140,7 +140,7 @@
}
void* LinearAllocator::start(Page* p) {
- return ALIGN_PTR(((size_t*)p) + sizeof(Page));
+ return ALIGN_PTR((size_t)p + sizeof(Page));
}
void* LinearAllocator::end(Page* p) {
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardPinBasedInputView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardPinBasedInputView.java
index ce2d11a..f51e10f 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardPinBasedInputView.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardPinBasedInputView.java
@@ -64,7 +64,7 @@
@Override
protected void resetState() {
- mPasswordEntry.setEnabled(true);
+ setPasswordEntryEnabled(true);
}
@Override
diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml
index e00b55e..05591cc 100644
--- a/packages/Shell/AndroidManifest.xml
+++ b/packages/Shell/AndroidManifest.xml
@@ -39,6 +39,7 @@
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.EXPAND_STATUS_BAR" />
+ <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
<!-- System tool permissions granted to the shell. -->
<uses-permission android:name="android.permission.REAL_GET_TASKS" />
<uses-permission android:name="android.permission.CHANGE_CONFIGURATION" />
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
index de6c4b1..2c964be 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
@@ -1754,11 +1754,13 @@
protected void handleVisibleToUserChanged(boolean visibleToUser) {
try {
if (visibleToUser) {
- boolean clearNotificationEffects = !isPanelFullyCollapsed() &&
- (mShowLockscreenNotifications ||
- (mState == StatusBarState.SHADE || mState == StatusBarState.SHADE_LOCKED));
+ boolean pinnedHeadsUp = mHeadsUpManager.hasPinnedHeadsUp();
+ boolean clearNotificationEffects =
+ ((mShowLockscreenNotifications && mState == StatusBarState.KEYGUARD) ||
+ (!pinnedHeadsUp && (mState == StatusBarState.SHADE
+ || mState == StatusBarState.SHADE_LOCKED)));
int notificationLoad = mNotificationData.getActiveNotifications().size();
- if (mHeadsUpManager.hasPinnedHeadsUp() && isPanelFullyCollapsed()) {
+ if (pinnedHeadsUp && isPanelFullyCollapsed()) {
notificationLoad = 1;
} else {
MetricsLogger.histogram(mContext, "note_load", notificationLoad);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/FingerprintUnlockController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/FingerprintUnlockController.java
index 4e69999..84082db 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/FingerprintUnlockController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/FingerprintUnlockController.java
@@ -227,7 +227,7 @@
return MODE_DISMISS_BOUNCER;
} else if (unlockingAllowed) {
return MODE_UNLOCK;
- } else {
+ } else if (!mStatusBarKeyguardViewManager.isBouncerShowing()) {
return MODE_SHOW_BOUNCER;
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupManager.java
index 950b162..310625e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupManager.java
@@ -78,6 +78,13 @@
Notification notif = sbn.getNotification();
String groupKey = sbn.getGroupKey();
final NotificationGroup group = mGroupMap.get(groupKey);
+ if (group == null) {
+ // When an app posts 2 different notifications as summary of the same group, then a
+ // cancellation of the first notification removes this group.
+ // This situation is not supported and we will not allow such notifications anymore in
+ // the close future. See b/23676310 for reference.
+ return;
+ }
if (notif.isGroupSummary()) {
group.summary = null;
} else {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index ab1b597..55fbb2a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -3794,12 +3794,9 @@
// down on the lockscreen), clear notification LED, vibration,
// ringing.
// Other transitions are covered in handleVisibleToUserChanged().
- if (state != mState && mVisible && state == StatusBarState.SHADE_LOCKED) {
- try {
- mBarService.clearNotificationEffects();
- } catch (RemoteException e) {
- // Ignore.
- }
+ if (state != mState && mVisible && (state == StatusBarState.SHADE_LOCKED
+ || (state == StatusBarState.SHADE && isGoingToNotificationShade()))) {
+ clearNotificationEffects();
}
mState = state;
mGroupManager.setStatusBarState(state);
diff --git a/services/core/java/com/android/server/AnyMotionDetector.java b/services/core/java/com/android/server/AnyMotionDetector.java
index 6a67316..a0b5c15 100644
--- a/services/core/java/com/android/server/AnyMotionDetector.java
+++ b/services/core/java/com/android/server/AnyMotionDetector.java
@@ -58,9 +58,6 @@
/** Current measurement state. */
private int mState;
- /** Threshold angle in degrees beyond which the device is considered moving. */
- private final float THRESHOLD_ANGLE = 2f;
-
/** Threshold energy above which the device is considered moving. */
private final float THRESHOLD_ENERGY = 5f;
@@ -88,6 +85,9 @@
private SensorManager mSensorManager;
private PowerManager.WakeLock mWakeLock;
+ /** Threshold angle in degrees beyond which the device is considered moving. */
+ private final float mThresholdAngle;
+
/** The minimum number of samples required to detect AnyMotion. */
private int mNumSufficientSamples;
@@ -106,7 +106,7 @@
private DeviceIdleCallback mCallback = null;
public AnyMotionDetector(PowerManager pm, Handler handler, SensorManager sm,
- DeviceIdleCallback callback) {
+ DeviceIdleCallback callback, float thresholdAngle) {
if (DEBUG) Slog.d(TAG, "AnyMotionDetector instantiated.");
mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
mWakeLock.setReferenceCounted(false);
@@ -116,6 +116,7 @@
mMeasurementInProgress = false;
mState = STATE_INACTIVE;
mCallback = callback;
+ mThresholdAngle = thresholdAngle;
mRunningStats = new RunningSignalStats();
mNumSufficientSamples = (int) Math.ceil(
((double)ORIENTATION_MEASUREMENT_DURATION_MILLIS / SAMPLING_INTERVAL_MILLIS));
@@ -224,8 +225,9 @@
Vector3 previousGravityVectorNormalized = mPreviousGravityVector.normalized();
Vector3 currentGravityVectorNormalized = mCurrentGravityVector.normalized();
float angle = previousGravityVectorNormalized.angleBetween(currentGravityVectorNormalized);
- if (DEBUG) Slog.d(TAG, "getStationaryStatus: angle = " + angle);
- if ((angle < THRESHOLD_ANGLE) && (mRunningStats.getEnergy() < THRESHOLD_ENERGY)) {
+ if (DEBUG) Slog.d(TAG, "getStationaryStatus: angle = " + angle
+ + " energy = " + mRunningStats.getEnergy());
+ if ((angle < mThresholdAngle) && (mRunningStats.getEnergy() < THRESHOLD_ENERGY)) {
return RESULT_STATIONARY;
} else if (Float.isNaN(angle)) {
/**
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index e19447d..2bcee91 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -1524,10 +1524,14 @@
final long ident = Binder.clearCallingIdentity();
if (ConnectivityManager.CONNECTIVITY_ACTION.equals(intent.getAction())) {
+ final NetworkInfo ni = intent.getParcelableExtra(
+ ConnectivityManager.EXTRA_NETWORK_INFO);
+ if (ni.getType() == ConnectivityManager.TYPE_MOBILE_SUPL) {
+ intent.setAction(ConnectivityManager.CONNECTIVITY_ACTION_SUPL);
+ intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
+ }
final IBatteryStats bs = BatteryStatsService.getService();
try {
- NetworkInfo ni = intent.getParcelableExtra(
- ConnectivityManager.EXTRA_NETWORK_INFO);
bs.noteConnectivityChanged(intent.getIntExtra(
ConnectivityManager.EXTRA_NETWORK_TYPE, ConnectivityManager.TYPE_NONE),
ni != null ? ni.getState().toString() : "?");
diff --git a/services/core/java/com/android/server/DeviceIdleController.java b/services/core/java/com/android/server/DeviceIdleController.java
index 80fd441..46fd28a 100644
--- a/services/core/java/com/android/server/DeviceIdleController.java
+++ b/services/core/java/com/android/server/DeviceIdleController.java
@@ -128,7 +128,8 @@
private boolean mNotMoving;
private boolean mLocating;
private boolean mLocated;
- private boolean mHaveGps;
+ private boolean mHasGps;
+ private boolean mHasNetworkLocation;
private Location mLastGenericLocation;
private Location mLastGpsLocation;
@@ -882,17 +883,37 @@
mDisplayManager = (DisplayManager) getContext().getSystemService(
Context.DISPLAY_SERVICE);
mSensorManager = (SensorManager) getContext().getSystemService(Context.SENSOR_SERVICE);
- mSigMotionSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_SIGNIFICANT_MOTION);
- mLocationManager = (LocationManager) getContext().getSystemService(
- Context.LOCATION_SERVICE);
- mLocationRequest = new LocationRequest()
- .setQuality(LocationRequest.ACCURACY_FINE)
- .setInterval(0)
- .setFastestInterval(0)
- .setNumUpdates(1);
+ int sigMotionSensorId = getContext().getResources().getInteger(
+ com.android.internal.R.integer.config_autoPowerModeAnyMotionSensor);
+ if (sigMotionSensorId > 0) {
+ mSigMotionSensor = mSensorManager.getDefaultSensor(sigMotionSensorId, true);
+ }
+ if (mSigMotionSensor == null && getContext().getResources().getBoolean(
+ com.android.internal.R.bool.config_autoPowerModePreferWristTilt)) {
+ mSigMotionSensor = mSensorManager.getDefaultSensor(
+ Sensor.TYPE_WRIST_TILT_GESTURE);
+ }
+ if (mSigMotionSensor == null) {
+ // As a last ditch, fall back to SMD.
+ mSigMotionSensor = mSensorManager.getDefaultSensor(
+ Sensor.TYPE_SIGNIFICANT_MOTION);
+ }
+ if (getContext().getResources().getBoolean(
+ com.android.internal.R.bool.config_autoPowerModePrefetchLocation)) {
+ mLocationManager = (LocationManager) getContext().getSystemService(
+ Context.LOCATION_SERVICE);
+ mLocationRequest = new LocationRequest()
+ .setQuality(LocationRequest.ACCURACY_FINE)
+ .setInterval(0)
+ .setFastestInterval(0)
+ .setNumUpdates(1);
+ }
+
+ float angleThreshold = getContext().getResources().getInteger(
+ com.android.internal.R.integer.config_autoPowerModeThresholdAngle) / 100f;
mAnyMotionDetector = new AnyMotionDetector(
(PowerManager) getContext().getSystemService(Context.POWER_SERVICE),
- mHandler, mSensorManager, this);
+ mHandler, mSensorManager, this, angleThreshold);
Intent intent = new Intent(ACTION_STEP_IDLE_STATE)
.setPackage("android")
@@ -1279,17 +1300,30 @@
EventLogTags.writeDeviceIdle(mState, "step");
cancelSensingAlarmLocked();
scheduleSensingAlarmLocked(mConstants.LOCATING_TIMEOUT);
- mLocating = true;
- mLocationManager.requestLocationUpdates(mLocationRequest, mGenericLocationListener,
- mHandler.getLooper());
- if (mLocationManager.getProvider(LocationManager.GPS_PROVIDER) != null) {
- mHaveGps = true;
+ if (mLocationManager != null
+ && mLocationManager.getProvider(LocationManager.NETWORK_PROVIDER) != null) {
+ mLocationManager.requestLocationUpdates(mLocationRequest,
+ mGenericLocationListener, mHandler.getLooper());
+ mLocating = true;
+ } else {
+ mHasNetworkLocation = false;
+ }
+ if (mLocationManager != null
+ && mLocationManager.getProvider(LocationManager.GPS_PROVIDER) != null) {
+ mHasGps = true;
mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 5,
mGpsLocationListener, mHandler.getLooper());
+ mLocating = true;
} else {
- mHaveGps = false;
+ mHasGps = false;
}
- break;
+ // If we have a location provider, we're all set, the listeners will move state
+ // forward.
+ if (mLocating) {
+ break;
+ }
+
+ // Otherwise, we have to move from locating into idle maintenance.
case STATE_LOCATING:
cancelSensingAlarmLocked();
cancelLocatingLocked();
@@ -1346,7 +1380,7 @@
}
if (DEBUG) Slog.d(TAG, "Generic location: " + location);
mLastGenericLocation = new Location(location);
- if (location.getAccuracy() > mConstants.LOCATION_ACCURACY && mHaveGps) {
+ if (location.getAccuracy() > mConstants.LOCATION_ACCURACY && mHasGps) {
return;
}
mLocated = true;
@@ -1413,9 +1447,9 @@
void scheduleAlarmLocked(long delay, boolean idleUntil) {
if (DEBUG) Slog.d(TAG, "scheduleAlarmLocked(" + delay + ", " + idleUntil + ")");
if (mSigMotionSensor == null) {
- // If there is no significant motion sensor on this device, then we won't schedule
+ // If there is no motion sensor on this device, then we won't schedule
// alarms, because we can't determine if the device is not moving. This effectively
- // turns off normal exeuction of device idling, although it is still possible to
+ // turns off normal execution of device idling, although it is still possible to
// manually poke it by pretending like the alarm is going off.
return;
}
@@ -1902,8 +1936,9 @@
pw.print(" mSigMotionActive="); pw.println(mSigMotionActive);
pw.print(" mSensing="); pw.print(mSensing); pw.print(" mNotMoving=");
pw.println(mNotMoving);
- pw.print(" mLocating="); pw.print(mLocating); pw.print(" mHaveGps=");
- pw.print(mHaveGps); pw.print(" mLocated="); pw.println(mLocated);
+ pw.print(" mLocating="); pw.print(mLocating); pw.print(" mHasGps=");
+ pw.print(mHasGps); pw.print(" mHasNetwork=");
+ pw.print(mHasNetworkLocation); pw.print(" mLocated="); pw.println(mLocated);
if (mLastGenericLocation != null) {
pw.print(" mLastGenericLocation="); pw.println(mLastGenericLocation);
}
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 09ac7d9..3554c39 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -407,6 +407,17 @@
private static final int PERSISTENT_MASK =
ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
+
+ // Delay to disable app launch boost
+ static final int APP_BOOST_MESSAGE_DELAY = 3000;
+ // Lower delay than APP_BOOST_MESSAGE_DELAY to disable the boost
+ static final int APP_BOOST_TIMEOUT = 2500;
+
+ private static native int nativeMigrateToBoost();
+ private static native int nativeMigrateFromBoost();
+ private boolean mIsBoosted = false;
+ private long mBoostStartTime = 0;
+
/** All system services */
SystemServiceManager mSystemServiceManager;
@@ -1368,6 +1379,7 @@
static final int REPORT_TIME_TRACKER_MSG = 55;
static final int REPORT_USER_SWITCH_COMPLETE_MSG = 56;
static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 57;
+ static final int APP_BOOST_DEACTIVATE_MSG = 58;
static final int FIRST_ACTIVITY_STACK_MSG = 100;
static final int FIRST_BROADCAST_QUEUE_MSG = 200;
@@ -2048,6 +2060,20 @@
// it is finished we make sure it is reset to its default.
mUserIsMonkey = false;
} break;
+ case APP_BOOST_DEACTIVATE_MSG : {
+ synchronized(ActivityManagerService.this) {
+ if (mIsBoosted) {
+ if (mBoostStartTime < (SystemClock.uptimeMillis() - APP_BOOST_TIMEOUT)) {
+ nativeMigrateFromBoost();
+ mIsBoosted = false;
+ mBoostStartTime = 0;
+ } else {
+ Message newmsg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
+ mHandler.sendMessageDelayed(newmsg, APP_BOOST_TIMEOUT);
+ }
+ }
+ }
+ } break;
}
}
};
@@ -3180,6 +3206,16 @@
app = null;
}
+ // app launch boost for big.little configurations
+ // use cpusets to migrate freshly launched tasks to big cores
+ synchronized(ActivityManagerService.this) {
+ nativeMigrateToBoost();
+ mIsBoosted = true;
+ mBoostStartTime = SystemClock.uptimeMillis();
+ Message msg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
+ mHandler.sendMessageDelayed(msg, APP_BOOST_MESSAGE_DELAY);
+ }
+
// We don't have to do anything more if:
// (1) There is an existing application record; and
// (2) The caller doesn't think it is dead, OR there is no thread
diff --git a/services/core/java/com/android/server/am/BroadcastQueue.java b/services/core/java/com/android/server/am/BroadcastQueue.java
index a956c56..960cbf1 100644
--- a/services/core/java/com/android/server/am/BroadcastQueue.java
+++ b/services/core/java/com/android/server/am/BroadcastQueue.java
@@ -509,7 +509,7 @@
break;
}
int appOp = AppOpsManager.permissionToOpCode(requiredPermission);
- if (appOp != r.appOp
+ if (appOp != AppOpsManager.OP_NONE && appOp != r.appOp
&& mService.mAppOpsService.noteOperation(appOp,
filter.receiverList.uid, filter.packageName)
!= AppOpsManager.MODE_ALLOWED) {
diff --git a/services/core/java/com/android/server/fingerprint/FingerprintService.java b/services/core/java/com/android/server/fingerprint/FingerprintService.java
index cbb3c39..67c9ee8 100644
--- a/services/core/java/com/android/server/fingerprint/FingerprintService.java
+++ b/services/core/java/com/android/server/fingerprint/FingerprintService.java
@@ -18,9 +18,12 @@
import android.Manifest;
import android.app.ActivityManager;
+import android.app.ActivityManager.RunningAppProcessInfo;
+import android.app.ActivityManager.RunningTaskInfo;
import android.app.ActivityManagerNative;
import android.app.AppOpsManager;
import android.app.IUserSwitchObserver;
+import android.content.ComponentName;
import android.content.Context;
import android.content.pm.PackageManager;
import android.content.pm.UserInfo;
@@ -54,6 +57,7 @@
import android.hardware.fingerprint.IFingerprintDaemonCallback;
import android.hardware.fingerprint.IFingerprintServiceReceiver;
+import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
import static android.Manifest.permission.MANAGE_FINGERPRINT;
import static android.Manifest.permission.RESET_FINGERPRINT_LOCKOUT;
import static android.Manifest.permission.USE_FINGERPRINT;
@@ -93,6 +97,7 @@
private static final long FAIL_LOCKOUT_TIMEOUT_MS = 30*1000;
private static final int MAX_FAILED_ATTEMPTS = 5;
private static final int FINGERPRINT_ACQUIRED_GOOD = 0;
+ private final String mKeyguardPackage;
Handler mHandler = new Handler() {
@Override
@@ -125,6 +130,8 @@
public FingerprintService(Context context) {
super(context);
mContext = context;
+ mKeyguardPackage = ComponentName.unflattenFromString(context.getResources().getString(
+ com.android.internal.R.string.config_keyguardComponent)).getPackageName();
mAppOps = context.getSystemService(AppOpsManager.class);
mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
}
@@ -498,10 +505,50 @@
return false;
}
- private boolean canUseFingerprint(String opPackageName) {
+ private boolean isForegroundActivity(int uid, int pid) {
+ try {
+ List<RunningAppProcessInfo> procs =
+ ActivityManagerNative.getDefault().getRunningAppProcesses();
+ int N = procs.size();
+ for (int i = 0; i < N; i++) {
+ RunningAppProcessInfo proc = procs.get(i);
+ if (proc.pid == pid && proc.uid == uid
+ && proc.importance == IMPORTANCE_FOREGROUND) {
+ return true;
+ }
+ }
+ } catch (RemoteException e) {
+ Slog.w(TAG, "am.getRunningAppProcesses() failed");
+ }
+ return false;
+ }
+
+ /**
+ * @param opPackageName name of package for caller
+ * @param foregroundOnly only allow this call while app is in the foreground
+ * @return true if caller can use fingerprint API
+ */
+ private boolean canUseFingerprint(String opPackageName, boolean foregroundOnly) {
checkPermission(USE_FINGERPRINT);
- return mAppOps.noteOp(AppOpsManager.OP_USE_FINGERPRINT, Binder.getCallingUid(),
- opPackageName) == AppOpsManager.MODE_ALLOWED;
+ final int uid = Binder.getCallingUid();
+ final int pid = Binder.getCallingPid();
+ if (opPackageName.equals(mKeyguardPackage)) {
+ return true; // Keyguard is always allowed
+ }
+ if (!isCurrentUserOrProfile(UserHandle.getCallingUserId())) {
+ Slog.w(TAG,"Rejecting " + opPackageName + " ; not a current user or profile");
+ return false;
+ }
+ if (mAppOps.noteOp(AppOpsManager.OP_USE_FINGERPRINT, uid, opPackageName)
+ != AppOpsManager.MODE_ALLOWED) {
+ Slog.v(TAG, "Rejecting " + opPackageName + " ; permission denied");
+ return false;
+ }
+ if (foregroundOnly && !isForegroundActivity(uid, pid)) {
+ Slog.v(TAG, "Rejecting " + opPackageName + " ; not in foreground");
+ return false;
+ }
+ return true;
}
private void addLockoutResetMonitor(FingerprintServiceLockoutResetMonitor monitor) {
@@ -834,12 +881,7 @@
public void authenticate(final IBinder token, final long opId, final int groupId,
final IFingerprintServiceReceiver receiver, final int flags,
final String opPackageName) {
- if (!isCurrentUserOrProfile(UserHandle.getCallingUserId())) {
- Slog.w(TAG, "Can't authenticate non-current user");
- return;
- }
- if (!canUseFingerprint(opPackageName)) {
- Slog.w(TAG, "Calling not granted permission to use fingerprint");
+ if (!canUseFingerprint(opPackageName, true /* foregroundOnly */)) {
return;
}
@@ -859,7 +901,7 @@
@Override // Binder call
public void cancelAuthentication(final IBinder token, String opPackageName) {
- if (!canUseFingerprint(opPackageName)) {
+ if (!canUseFingerprint(opPackageName, false /* foregroundOnly */)) {
return;
}
mHandler.post(new Runnable() {
@@ -890,7 +932,7 @@
@Override // Binder call
public boolean isHardwareDetected(long deviceId, String opPackageName) {
- if (!canUseFingerprint(opPackageName)) {
+ if (!canUseFingerprint(opPackageName, false /* foregroundOnly */)) {
return false;
}
return mHalDeviceId != 0;
@@ -914,7 +956,7 @@
@Override // Binder call
public List<Fingerprint> getEnrolledFingerprints(int userId, String opPackageName) {
- if (!canUseFingerprint(opPackageName)) {
+ if (!canUseFingerprint(opPackageName, false /* foregroundOnly */)) {
return Collections.emptyList();
}
int effectiveUserId = getEffectiveUserId(userId);
@@ -924,7 +966,7 @@
@Override // Binder call
public boolean hasEnrolledFingerprints(int userId, String opPackageName) {
- if (!canUseFingerprint(opPackageName)) {
+ if (!canUseFingerprint(opPackageName, false /* foregroundOnly */)) {
return false;
}
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index e69dda1..3991489 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -978,13 +978,12 @@
}
// TODO: move to NotificationManager once we can mock it
- // XXX what to do about multi-user?
try {
final String packageName = mContext.getPackageName();
final int[] idReceived = new int[1];
mNotifManager.enqueueNotificationWithTag(
packageName, packageName, tag, 0x0, builder.getNotification(), idReceived,
- UserHandle.USER_OWNER);
+ UserHandle.USER_ALL);
mActiveNotifs.add(tag);
} catch (RemoteException e) {
// ignored; service lives in system_server
@@ -1016,12 +1015,11 @@
PendingIntent.getBroadcast(mContext, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT));
// TODO: move to NotificationManager once we can mock it
- // XXX what to do about multi-user?
try {
final String packageName = mContext.getPackageName();
final int[] idReceived = new int[1];
mNotifManager.enqueueNotificationWithTag(packageName, packageName, tag,
- 0x0, builder.getNotification(), idReceived, UserHandle.USER_OWNER);
+ 0x0, builder.getNotification(), idReceived, UserHandle.USER_ALL);
mActiveNotifs.add(tag);
} catch (RemoteException e) {
// ignored; service lives in system_server
@@ -1030,11 +1028,10 @@
private void cancelNotification(String tag) {
// TODO: move to NotificationManager once we can mock it
- // XXX what to do about multi-user?
try {
final String packageName = mContext.getPackageName();
mNotifManager.cancelNotificationWithTag(
- packageName, tag, 0x0, UserHandle.USER_OWNER);
+ packageName, tag, 0x0, UserHandle.USER_ALL);
} catch (RemoteException e) {
// ignored; service lives in system_server
}
@@ -1418,7 +1415,8 @@
final int policy = readIntAttribute(in, ATTR_POLICY);
// TODO: set for other users during upgrade
- final int uid = UserHandle.getUid(UserHandle.USER_OWNER, appId);
+ // app policy is deprecated so this is only used in pre system user split.
+ final int uid = UserHandle.getUid(UserHandle.USER_SYSTEM, appId);
if (UserHandle.isApp(uid)) {
setUidPolicyUncheckedLocked(uid, policy, false);
} else {
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index e1f3528..88088fa 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -2319,16 +2319,16 @@
}
updatePermissionsLPw(null, null, updateFlags);
ver.sdkVersion = mSdkVersion;
- // clear only after permissions have been updated
- mExistingSystemPackages.clear();
- mPromoteSystemApps = false;
- // If this is the first boot, and it is a normal boot, then
- // we need to initialize the default preferred apps.
- if (!mRestoredSettings && !onlyCore) {
- mSettings.applyDefaultPreferredAppsLPw(this, UserHandle.USER_OWNER);
- applyFactoryDefaultBrowserLPw(UserHandle.USER_OWNER);
- primeDomainVerificationsLPw(UserHandle.USER_OWNER);
+ // If this is the first boot or an update from pre-M, and it is a normal
+ // boot, then we need to initialize the default preferred apps across
+ // all defined users.
+ if (!onlyCore && (mPromoteSystemApps || !mRestoredSettings)) {
+ for (UserInfo user : sUserManager.getUsers(true)) {
+ mSettings.applyDefaultPreferredAppsLPw(this, user.id);
+ applyFactoryDefaultBrowserLPw(user.id);
+ primeDomainVerificationsLPw(user.id);
+ }
}
// If this is first boot after an OTA, and a normal boot, then
@@ -2346,6 +2346,10 @@
checkDefaultBrowser();
+ // clear only after permissions and other defaults have been updated
+ mExistingSystemPackages.clear();
+ mPromoteSystemApps = false;
+
// All the changes are done during package scanning.
ver.databaseVersion = Settings.CURRENT_DATABASE_VERSION;
diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java
index a7ef2f8..f21f00a 100644
--- a/services/core/java/com/android/server/wm/TaskStack.java
+++ b/services/core/java/com/android/server/wm/TaskStack.java
@@ -405,7 +405,10 @@
for (int appNdx = appWindowTokens.size() - 1; appNdx >= 0; --appNdx) {
final WindowList appWindows = appWindowTokens.get(appNdx).allAppWindows;
for (int winNdx = appWindows.size() - 1; winNdx >= 0; --winNdx) {
- mService.removeWindowInnerLocked(appWindows.get(winNdx));
+ // We are in the middle of changing the state of displays/stacks/tasks. We need
+ // to finish that, before we let layout interfere with it.
+ mService.removeWindowInnerLocked(appWindows.get(winNdx),
+ false /* performLayout */);
doAnotherLayoutPass = true;
}
}
diff --git a/services/core/java/com/android/server/wm/WallpaperController.java b/services/core/java/com/android/server/wm/WallpaperController.java
index d0962f4..fc23fd1 100644
--- a/services/core/java/com/android/server/wm/WallpaperController.java
+++ b/services/core/java/com/android/server/wm/WallpaperController.java
@@ -750,7 +750,7 @@
}
boolean adjustWallpaperWindows() {
- mService.mInnerFields.mWallpaperMayChange = false;
+ mService.mWindowPlacerLocked.mWallpaperMayChange = false;
final WindowList windows = mService.getDefaultWindowListLocked();
// First find top-most window that has asked to be on top of the wallpaper;
diff --git a/services/core/java/com/android/server/wm/WindowAnimator.java b/services/core/java/com/android/server/wm/WindowAnimator.java
index e6a1be1..b334a05 100644
--- a/services/core/java/com/android/server/wm/WindowAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowAnimator.java
@@ -23,11 +23,11 @@
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_SYSTEM_ERROR;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
import static com.android.server.wm.WindowManagerService.DEBUG_KEYGUARD;
-import static com.android.server.wm.WindowManagerService.LayoutFields.SET_UPDATE_ROTATION;
-import static com.android.server.wm.WindowManagerService.LayoutFields.SET_WALLPAPER_MAY_CHANGE;
-import static com.android.server.wm.WindowManagerService.LayoutFields.SET_FORCE_HIDING_CHANGED;
-import static com.android.server.wm.WindowManagerService.LayoutFields.SET_ORIENTATION_CHANGE_COMPLETE;
-import static com.android.server.wm.WindowManagerService.LayoutFields.SET_WALLPAPER_ACTION_PENDING;
+import static com.android.server.wm.WindowSurfacePlacer.SET_UPDATE_ROTATION;
+import static com.android.server.wm.WindowSurfacePlacer.SET_WALLPAPER_MAY_CHANGE;
+import static com.android.server.wm.WindowSurfacePlacer.SET_FORCE_HIDING_CHANGED;
+import static com.android.server.wm.WindowSurfacePlacer.SET_ORIENTATION_CHANGE_COMPLETE;
+import static com.android.server.wm.WindowSurfacePlacer.SET_WALLPAPER_ACTION_PENDING;
import android.content.Context;
import android.os.RemoteException;
@@ -41,8 +41,6 @@
import android.view.animation.Animation;
import android.view.Choreographer;
-import com.android.server.wm.WindowManagerService.LayoutFields;
-
import java.io.PrintWriter;
import java.util.ArrayList;
@@ -84,8 +82,7 @@
int mBulkUpdateParams = 0;
Object mLastWindowFreezeSource;
- SparseArray<DisplayContentsAnimator> mDisplayContentsAnimators =
- new SparseArray<DisplayContentsAnimator>(2);
+ SparseArray<DisplayContentsAnimator> mDisplayContentsAnimators = new SparseArray<>(2);
boolean mInitialized = false;
@@ -179,10 +176,12 @@
mAnimating = mAppWindowAnimating = true;
} else if (appAnimator.wasAnimating) {
// stopped animating, do one more pass through the layout
- setAppLayoutChanges(appAnimator, WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER,
- "exiting appToken " + appAnimator.mAppToken + " done", displayId);
+ setAppLayoutChanges(appAnimator,
+ WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER,
+ "exiting appToken " + appAnimator.mAppToken + " done", displayId);
if (WindowManagerService.DEBUG_ANIM) Slog.v(TAG,
- "updateWindowsApps...: done animating exiting " + appAnimator.mAppToken);
+ "updateWindowsApps...: done animating exiting "
+ + appAnimator.mAppToken);
}
}
}
@@ -301,7 +300,8 @@
setPendingLayoutChanges(Display.DEFAULT_DISPLAY,
WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER);
if (WindowManagerService.DEBUG_LAYOUT_REPEATS) {
- mService.debugLayoutRepeats("updateWindowsAndWallpaperLocked 2",
+ mService.mWindowPlacerLocked.debugLayoutRepeats(
+ "updateWindowsAndWallpaperLocked 2",
getPendingLayoutChanges(Display.DEFAULT_DISPLAY));
}
}
@@ -315,7 +315,8 @@
setPendingLayoutChanges(displayId,
WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER);
if (WindowManagerService.DEBUG_LAYOUT_REPEATS) {
- mService.debugLayoutRepeats("updateWindowsAndWallpaperLocked 3",
+ mService.mWindowPlacerLocked.debugLayoutRepeats(
+ "updateWindowsAndWallpaperLocked 3",
getPendingLayoutChanges(displayId));
}
mService.mFocusMayChange = true;
@@ -409,7 +410,8 @@
setPendingLayoutChanges(Display.DEFAULT_DISPLAY,
WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER);
if (WindowManagerService.DEBUG_LAYOUT_REPEATS) {
- mService.debugLayoutRepeats("updateWindowsAndWallpaperLocked 4",
+ mService.mWindowPlacerLocked.debugLayoutRepeats(
+ "updateWindowsAndWallpaperLocked 4",
getPendingLayoutChanges(Display.DEFAULT_DISPLAY));
}
}
@@ -433,7 +435,8 @@
setPendingLayoutChanges(displayId,
WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM);
if (WindowManagerService.DEBUG_LAYOUT_REPEATS) {
- mService.debugLayoutRepeats("updateWindowsAndWallpaperLocked 5",
+ mService.mWindowPlacerLocked.debugLayoutRepeats(
+ "updateWindowsAndWallpaperLocked 5",
getPendingLayoutChanges(displayId));
}
}
@@ -607,7 +610,8 @@
"Setting mOrientationChangeComplete=true because wtoken "
+ wtoken + " numInteresting=" + wtoken.numInterestingWindows
+ " numDrawn=" + wtoken.numDrawnWindows);
- // This will set mOrientationChangeComplete and cause a pass through layout.
+ // This will set mOrientationChangeComplete and cause a pass through
+ // layout.
setAppLayoutChanges(appAnimator,
WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER,
"testTokenMayBeDrawnLocked: freezingScreen", displayId);
@@ -737,7 +741,7 @@
boolean doRequest = false;
if (mBulkUpdateParams != 0) {
- doRequest = mService.copyAnimToLayoutParamsLocked();
+ doRequest = mService.mWindowPlacerLocked.copyAnimToLayoutParamsLocked();
}
if (hasPendingLayoutChanges || doRequest) {
@@ -755,21 +759,21 @@
}
}
- static String bulkUpdateParamsToString(int bulkUpdateParams) {
+ private static String bulkUpdateParamsToString(int bulkUpdateParams) {
StringBuilder builder = new StringBuilder(128);
- if ((bulkUpdateParams & LayoutFields.SET_UPDATE_ROTATION) != 0) {
+ if ((bulkUpdateParams & WindowSurfacePlacer.SET_UPDATE_ROTATION) != 0) {
builder.append(" UPDATE_ROTATION");
}
- if ((bulkUpdateParams & LayoutFields.SET_WALLPAPER_MAY_CHANGE) != 0) {
+ if ((bulkUpdateParams & WindowSurfacePlacer.SET_WALLPAPER_MAY_CHANGE) != 0) {
builder.append(" WALLPAPER_MAY_CHANGE");
}
- if ((bulkUpdateParams & LayoutFields.SET_FORCE_HIDING_CHANGED) != 0) {
+ if ((bulkUpdateParams & WindowSurfacePlacer.SET_FORCE_HIDING_CHANGED) != 0) {
builder.append(" FORCE_HIDING_CHANGED");
}
- if ((bulkUpdateParams & LayoutFields.SET_ORIENTATION_CHANGE_COMPLETE) != 0) {
+ if ((bulkUpdateParams & WindowSurfacePlacer.SET_ORIENTATION_CHANGE_COMPLETE) != 0) {
builder.append(" ORIENTATION_CHANGE_COMPLETE");
}
- if ((bulkUpdateParams & LayoutFields.SET_TURN_ON_SCREEN) != 0) {
+ if ((bulkUpdateParams & WindowSurfacePlacer.SET_TURN_ON_SCREEN) != 0) {
builder.append(" TURN_ON_SCREEN");
}
return builder.toString();
@@ -846,7 +850,8 @@
if (displayId == windows.get(i).getDisplayId()) {
setPendingLayoutChanges(displayId, changes);
if (WindowManagerService.DEBUG_LAYOUT_REPEATS) {
- mService.debugLayoutRepeats(reason, getPendingLayoutChanges(displayId));
+ mService.mWindowPlacerLocked.debugLayoutRepeats(reason,
+ getPendingLayoutChanges(displayId));
}
break;
}
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index bf7d1e7..cf093f5 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -34,8 +34,6 @@
import android.content.res.Configuration;
import android.database.ContentObserver;
import android.graphics.Bitmap;
-import android.graphics.Bitmap.Config;
-import android.graphics.Canvas;
import android.graphics.PixelFormat;
import android.graphics.Point;
import android.graphics.Rect;
@@ -70,7 +68,6 @@
import android.util.ArraySet;
import android.util.DisplayMetrics;
import android.util.EventLog;
-import android.util.IntArray;
import android.util.Log;
import android.util.Pair;
import android.util.Slog;
@@ -112,7 +109,6 @@
import android.view.WindowManagerPolicy;
import android.view.WindowManagerPolicy.PointerEventListener;
import android.view.animation.Animation;
-import android.view.animation.AnimationUtils;
import static com.android.server.wm.WindowState.BOUNDS_FOR_TOUCH;
import com.android.internal.app.IAssistScreenshotReceiver;
@@ -157,16 +153,12 @@
import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW;
import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW;
import static android.view.WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
-import static android.view.WindowManager.LayoutParams.FLAG_DIM_BEHIND;
-import static android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
import static android.view.WindowManager.LayoutParams.FLAG_SECURE;
import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
import static android.view.WindowManager.LayoutParams.LAST_APPLICATION_WINDOW;
import static android.view.WindowManager.LayoutParams.LAST_SUB_WINDOW;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_COMPATIBLE_WINDOW;
-import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD;
-import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMATION;
import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
import static android.view.WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST;
import static android.view.WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY;
@@ -177,11 +169,8 @@
import static android.view.WindowManager.LayoutParams.TYPE_DREAM;
import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG;
-import static android.view.WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG;
import static android.view.WindowManager.LayoutParams.TYPE_PRIVATE_PRESENTATION;
import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR;
-import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG;
-import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_ERROR;
import static android.view.WindowManager.LayoutParams.TYPE_VOICE_INTERACTION;
import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
@@ -313,6 +302,7 @@
}
}
};
+ final WindowSurfacePlacer mWindowPlacerLocked;
/**
* Current user when multi-user is enabled. Don't show windows of
@@ -444,7 +434,6 @@
final float[] mTmpFloats = new float[9];
final Rect mTmpContentRect = new Rect();
- private final Rect mTmpStartRect = new Rect();
boolean mDisplayReady;
boolean mSafeMode;
@@ -491,7 +480,7 @@
final static int WINDOWS_FREEZING_SCREENS_NONE = 0;
final static int WINDOWS_FREEZING_SCREENS_ACTIVE = 1;
final static int WINDOWS_FREEZING_SCREENS_TIMEOUT = 2;
- private int mWindowsFreezingScreen = WINDOWS_FREEZING_SCREENS_NONE;
+ int mWindowsFreezingScreen = WINDOWS_FREEZING_SCREENS_NONE;
boolean mClientFreezingScreen = false;
int mAppsFreezingScreen = 0;
@@ -614,51 +603,11 @@
// For frozen screen animations.
int mExitAnimId, mEnterAnimId;
- /** Pulled out of performLayoutAndPlaceSurfacesLockedInner in order to refactor into multiple
- * methods. */
- class LayoutFields {
- static final int SET_UPDATE_ROTATION = 1 << 0;
- static final int SET_WALLPAPER_MAY_CHANGE = 1 << 1;
- static final int SET_FORCE_HIDING_CHANGED = 1 << 2;
- static final int SET_ORIENTATION_CHANGE_COMPLETE = 1 << 3;
- static final int SET_TURN_ON_SCREEN = 1 << 4;
- static final int SET_WALLPAPER_ACTION_PENDING = 1 << 5;
-
- boolean mWallpaperForceHidingChanged = false;
- boolean mWallpaperMayChange = false;
- boolean mOrientationChangeComplete = true;
- Object mLastWindowFreezeSource = null;
- private Session mHoldScreen = null;
- private boolean mObscured = false;
- private boolean mSyswin = false;
- private float mScreenBrightness = -1;
- private float mButtonBrightness = -1;
- private long mUserActivityTimeout = -1;
- private boolean mUpdateRotation = false;
- boolean mWallpaperActionPending = false;
-
- // Set to true when the display contains content to show the user.
- // When false, the display manager may choose to mirror or blank the display.
- boolean mDisplayHasContent = false;
-
- // Only set while traversing the default display based on its content.
- // Affects the behavior of mirroring on secondary displays.
- boolean mObscureApplicationContentOnSecondaryDisplays = false;
-
- float mPreferredRefreshRate = 0;
-
- int mPreferredModeId = 0;
- }
- final LayoutFields mInnerFields = new LayoutFields();
-
boolean mAnimationScheduled;
/** Skip repeated AppWindowTokens initialization. Note that AppWindowsToken's version of this
* is a long initialized to Long.MIN_VALUE so that it doesn't match this value on startup. */
- private int mTransactionSequence;
-
- /** Only do a maximum of 6 repeated layouts. After that quit */
- private int mLayoutRepeatCount;
+ int mTransactionSequence;
final WindowAnimator mAnimator;
@@ -768,7 +717,7 @@
boolean mInTouchMode;
private ViewServer mViewServer;
- private final ArrayList<WindowChangeListener> mWindowChangeListeners = new ArrayList<>();
+ final ArrayList<WindowChangeListener> mWindowChangeListeners = new ArrayList<>();
boolean mWindowsChanged = false;
public interface WindowChangeListener {
@@ -788,7 +737,7 @@
// List of clients without a transtiton animation that we notify once we are done transitioning
// since they won't be notified through the app window animator.
- private final List<IBinder> mNoAnimationNotifyOnTransitionFinished = new ArrayList<>();
+ final List<IBinder> mNoAnimationNotifyOnTransitionFinished = new ArrayList<>();
/** Listener to notify activity manager about app transitions. */
private final WindowManagerInternal.AppTransitionListener mActivityManagerAppTransitionNotifier
@@ -866,6 +815,9 @@
mDisplaySettings = new DisplaySettings();
mDisplaySettings.readSettingsLocked();
+ mWallpaperControllerLocked = new WallpaperController(this);
+ mWindowPlacerLocked = new WindowSurfacePlacer(this);
+
LocalServices.addService(WindowManagerPolicy.class, mPolicy);
mPointerEventDispatcher = new PointerEventDispatcher(mInputManager.monitorInput(TAG));
@@ -953,8 +905,6 @@
updateCircularDisplayMaskIfNeeded();
showEmulatorDisplayOverlayIfNeeded();
-
- mWallpaperControllerLocked = new WallpaperController(this);
}
public InputMonitor getInputMonitor() {
@@ -2154,7 +2104,7 @@
}
final boolean focusChanged = updateFocusedWindowLocked(
UPDATE_FOCUS_WILL_PLACE_SURFACES, false /*updateInputWindows*/);
- performLayoutAndPlaceSurfacesLocked();
+ mWindowPlacerLocked.performSurfacePlacement();
if (appToken != null) {
appToken.updateReportedVisibilityLocked();
}
@@ -2177,6 +2127,10 @@
}
void removeWindowInnerLocked(WindowState win) {
+ removeWindowInnerLocked(win, true);
+ }
+
+ void removeWindowInnerLocked(WindowState win, boolean performLayout) {
if (win.mRemoved) {
// Nothing to do.
return;
@@ -2268,13 +2222,15 @@
final WindowList windows = win.getWindowList();
if (windows != null) {
windows.remove(win);
- if (!mInLayout) {
+ if (!mWindowPlacerLocked.isInLayout()) {
assignLayersLocked(windows);
final DisplayContent displayContent = win.getDisplayContent();
if (displayContent != null) {
displayContent.layoutNeeded = true;
}
- performLayoutAndPlaceSurfacesLocked();
+ if (performLayout) {
+ mWindowPlacerLocked.performSurfacePlacement();
+ }
if (win.mAppToken != null) {
win.mAppToken.updateReportedVisibilityLocked();
}
@@ -2357,7 +2313,7 @@
if (displayContent != null) {
displayContent.layoutNeeded = true;
}
- performLayoutAndPlaceSurfacesLocked();
+ mWindowPlacerLocked.performSurfacePlacement();
}
}
} finally {
@@ -2686,7 +2642,7 @@
}
win.mGivenInsetsPending = (flags&WindowManagerGlobal.RELAYOUT_INSETS_PENDING) != 0;
configChanged = updateOrientationFromAppTokensLocked(false);
- performLayoutAndPlaceSurfacesLocked();
+ mWindowPlacerLocked.performSurfacePlacement();
if (toBeDisplayed && win.mIsWallpaper) {
DisplayInfo displayInfo = getDefaultDisplayInfoLocked();
mWallpaperControllerLocked.updateWallpaperOffset(
@@ -3019,7 +2975,7 @@
wtoken.hidden = true;
if (changed) {
- performLayoutAndPlaceSurfacesLocked();
+ mWindowPlacerLocked.performSurfacePlacement();
updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL,
false /*updateInputWindows*/);
}
@@ -3385,7 +3341,7 @@
mWaitingForConfig = false;
mLastFinishedFreezeSource = "new-config";
}
- performLayoutAndPlaceSurfacesLocked();
+ mWindowPlacerLocked.performSurfacePlacement();
}
}
@@ -3583,7 +3539,7 @@
mAppTransition.setReady();
final long origId = Binder.clearCallingIdentity();
try {
- performLayoutAndPlaceSurfacesLocked();
+ mWindowPlacerLocked.performSurfacePlacement();
} finally {
Binder.restoreCallingIdentity(origId);
}
@@ -3690,7 +3646,7 @@
updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
true /*updateInputWindows*/);
getDefaultDisplayContentLocked().layoutNeeded = true;
- performLayoutAndPlaceSurfacesLocked();
+ mWindowPlacerLocked.performSurfacePlacement();
Binder.restoreCallingIdentity(origId);
return;
} else if (ttoken.startingData != null) {
@@ -3956,7 +3912,7 @@
if (performLayout) {
updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
false /*updateInputWindows*/);
- performLayoutAndPlaceSurfacesLocked();
+ mWindowPlacerLocked.performSurfacePlacement();
}
mInputMonitor.updateInputWindowsLw(false /*force*/);
}
@@ -4094,7 +4050,7 @@
&& mWindowsFreezingScreen != WINDOWS_FREEZING_SCREENS_TIMEOUT) {
if (DEBUG_ORIENTATION) Slog.v(TAG, "set mOrientationChanging of " + w);
w.mOrientationChanging = true;
- mInnerFields.mOrientationChangeComplete = false;
+ mWindowPlacerLocked.mOrientationChangeComplete = false;
}
w.mLastFreezeDuration = 0;
unfrozeWindows = true;
@@ -4114,7 +4070,7 @@
}
if (unfreezeSurfaceNow) {
if (unfrozeWindows) {
- performLayoutAndPlaceSurfacesLocked();
+ mWindowPlacerLocked.performSurfacePlacement();
}
stopFreezingDisplayLocked();
}
@@ -4402,7 +4358,7 @@
}
mInputMonitor.setUpdateInputWindowsNeededLw();
- performLayoutAndPlaceSurfacesLocked();
+ mWindowPlacerLocked.performSurfacePlacement();
mInputMonitor.updateInputWindowsLw(false /*force*/);
//dump();
@@ -4525,7 +4481,9 @@
}
public void removeStack(int stackId) {
- mStackIdToStack.remove(stackId);
+ synchronized (mWindowMap) {
+ mStackIdToStack.remove(stackId);
+ }
}
public void removeTask(int taskId) {
@@ -4552,7 +4510,7 @@
stack.addTask(task, toTop);
final DisplayContent displayContent = stack.getDisplayContent();
displayContent.layoutNeeded = true;
- performLayoutAndPlaceSurfacesLocked();
+ mWindowPlacerLocked.performSurfacePlacement();
}
}
@@ -4573,7 +4531,7 @@
task.moveTaskToStack(stack, toTop);
final DisplayContent displayContent = stack.getDisplayContent();
displayContent.layoutNeeded = true;
- performLayoutAndPlaceSurfacesLocked();
+ mWindowPlacerLocked.performSurfacePlacement();
}
}
@@ -4608,7 +4566,7 @@
if (stack.setBounds(bounds, resizeTasks, configs, taskBounds)) {
stack.resizeWindows();
stack.getDisplayContent().layoutNeeded = true;
- performLayoutAndPlaceSurfacesLocked();
+ mWindowPlacerLocked.performSurfacePlacement();
}
return stack.isFullscreen();
}
@@ -4633,7 +4591,7 @@
task.positionTaskInStack(stack, position);
final DisplayContent displayContent = stack.getDisplayContent();
displayContent.layoutNeeded = true;
- performLayoutAndPlaceSurfacesLocked();
+ mWindowPlacerLocked.performSurfacePlacement();
}
}
@@ -4653,7 +4611,7 @@
task.resizeWindows();
if (relayout) {
task.getDisplayContent().layoutNeeded = true;
- performLayoutAndPlaceSurfacesLocked();
+ mWindowPlacerLocked.performSurfacePlacement();
}
}
}
@@ -5046,7 +5004,7 @@
displayContent.switchUserStacks();
rebuildAppWindowListLocked(displayContent);
}
- performLayoutAndPlaceSurfacesLocked();
+ mWindowPlacerLocked.performSurfacePlacement();
}
}
@@ -5885,7 +5843,7 @@
changed = updateRotationUncheckedLocked(false);
if (!changed || forceRelayout) {
getDefaultDisplayContentLocked().layoutNeeded = true;
- performLayoutAndPlaceSurfacesLocked();
+ mWindowPlacerLocked.performSurfacePlacement();
}
}
@@ -6019,7 +5977,7 @@
if (w.mHasSurface) {
if (DEBUG_ORIENTATION) Slog.v(TAG, "Set mOrientationChanging of " + w);
w.mOrientationChanging = true;
- mInnerFields.mOrientationChangeComplete = false;
+ mWindowPlacerLocked.mOrientationChangeComplete = false;
}
w.mLastFreezeDuration = 0;
}
@@ -7170,7 +7128,7 @@
case DO_TRAVERSAL: {
synchronized(mWindowMap) {
mTraversalScheduled = false;
- performLayoutAndPlaceSurfacesLocked();
+ mWindowPlacerLocked.performSurfacePlacement();
}
} break;
@@ -7342,7 +7300,7 @@
Slog.w(TAG, "Force clearing orientation change: " + w);
}
}
- performLayoutAndPlaceSurfacesLocked();
+ mWindowPlacerLocked.performSurfacePlacement();
}
break;
}
@@ -7356,7 +7314,7 @@
+ " mOpeningApps.size()=" + mOpeningApps.size()
+ " mClosingApps.size()=" + mClosingApps.size());
mAppTransition.setTimeout();
- performLayoutAndPlaceSurfacesLocked();
+ mWindowPlacerLocked.performSurfacePlacement();
}
}
break;
@@ -7619,7 +7577,7 @@
case WALLPAPER_DRAW_PENDING_TIMEOUT: {
synchronized (mWindowMap) {
if (mWallpaperControllerLocked.processWallpaperDrawPendingTimeout()) {
- performLayoutAndPlaceSurfacesLocked();
+ mWindowPlacerLocked.performSurfacePlacement();
}
}
}
@@ -8011,7 +7969,7 @@
mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
}
- performLayoutAndPlaceSurfacesLocked();
+ mWindowPlacerLocked.performSurfacePlacement();
}
private void configureDisplayPolicyLocked(DisplayContent displayContent) {
@@ -8199,7 +8157,7 @@
Arrays.fill(mRebuildTmp, null);
}
- private final void assignLayersLocked(WindowList windows) {
+ final void assignLayersLocked(WindowList windows) {
int N = windows.size();
int curBaseLayer = 0;
int curLayer = 0;
@@ -8269,253 +8227,6 @@
}
}
- private final void performLayoutAndPlaceSurfacesLocked() {
- int loopCount = 6;
- do {
- mTraversalScheduled = false;
- performLayoutAndPlaceSurfacesLockedLoop();
- mH.removeMessages(H.DO_TRAVERSAL);
- loopCount--;
- } while (mTraversalScheduled && loopCount > 0);
- mInnerFields.mWallpaperActionPending = false;
- }
-
- private boolean mInLayout = false;
- private final void performLayoutAndPlaceSurfacesLockedLoop() {
- if (mInLayout) {
- if (DEBUG) {
- throw new RuntimeException("Recursive call!");
- }
- Slog.w(TAG, "performLayoutAndPlaceSurfacesLocked called while in layout. Callers="
- + Debug.getCallers(3));
- return;
- }
-
- if (mWaitingForConfig) {
- // Our configuration has changed (most likely rotation), but we
- // don't yet have the complete configuration to report to
- // applications. Don't do any window layout until we have it.
- return;
- }
-
- if (!mDisplayReady) {
- // Not yet initialized, nothing to do.
- return;
- }
-
- Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "wmLayout");
- mInLayout = true;
-
- boolean recoveringMemory = false;
- if (!mForceRemoves.isEmpty()) {
- recoveringMemory = true;
- // Wait a little bit for things to settle down, and off we go.
- while (!mForceRemoves.isEmpty()) {
- WindowState ws = mForceRemoves.remove(0);
- Slog.i(TAG, "Force removing: " + ws);
- removeWindowInnerLocked(ws);
- }
- Slog.w(TAG, "Due to memory failure, waiting a bit for next layout");
- Object tmp = new Object();
- synchronized (tmp) {
- try {
- tmp.wait(250);
- } catch (InterruptedException e) {
- }
- }
- }
-
- try {
- performLayoutAndPlaceSurfacesLockedInner(recoveringMemory);
-
- mInLayout = false;
-
- if (needsLayout()) {
- if (++mLayoutRepeatCount < 6) {
- requestTraversalLocked();
- } else {
- Slog.e(TAG, "Performed 6 layouts in a row. Skipping");
- mLayoutRepeatCount = 0;
- }
- } else {
- mLayoutRepeatCount = 0;
- }
-
- if (mWindowsChanged && !mWindowChangeListeners.isEmpty()) {
- mH.removeMessages(H.REPORT_WINDOWS_CHANGE);
- mH.sendEmptyMessage(H.REPORT_WINDOWS_CHANGE);
- }
- } catch (RuntimeException e) {
- mInLayout = false;
- Slog.wtf(TAG, "Unhandled exception while laying out windows", e);
- }
-
- Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
- }
-
- private final void performLayoutLockedInner(final DisplayContent displayContent,
- boolean initial, boolean updateInputWindows) {
- if (!displayContent.layoutNeeded) {
- return;
- }
- displayContent.layoutNeeded = false;
- WindowList windows = displayContent.getWindowList();
- boolean isDefaultDisplay = displayContent.isDefaultDisplay;
-
- DisplayInfo displayInfo = displayContent.getDisplayInfo();
- final int dw = displayInfo.logicalWidth;
- final int dh = displayInfo.logicalHeight;
-
- if (mInputConsumer != null) {
- mInputConsumer.layout(dw, dh);
- }
-
- final int N = windows.size();
- int i;
-
- if (DEBUG_LAYOUT) {
- Slog.v(TAG, "-------------------------------------");
- Slog.v(TAG, "performLayout: needed="
- + displayContent.layoutNeeded + " dw=" + dw + " dh=" + dh);
- }
-
- mPolicy.beginLayoutLw(isDefaultDisplay, dw, dh, mRotation);
- if (isDefaultDisplay) {
- // Not needed on non-default displays.
- mSystemDecorLayer = mPolicy.getSystemDecorLayerLw();
- mScreenRect.set(0, 0, dw, dh);
- }
-
- mPolicy.getContentRectLw(mTmpContentRect);
- displayContent.resize(mTmpContentRect);
-
- int seq = mLayoutSeq+1;
- if (seq < 0) seq = 0;
- mLayoutSeq = seq;
-
- boolean behindDream = false;
-
- // First perform layout of any root windows (not attached
- // to another window).
- int topAttached = -1;
- for (i = N-1; i >= 0; i--) {
- final WindowState win = windows.get(i);
-
- // Don't do layout of a window if it is not visible, or
- // soon won't be visible, to avoid wasting time and funky
- // changes while a window is animating away.
- final boolean gone = (behindDream && mPolicy.canBeForceHidden(win, win.mAttrs))
- || win.isGoneForLayoutLw();
-
- if (DEBUG_LAYOUT && !win.mLayoutAttached) {
- Slog.v(TAG, "1ST PASS " + win
- + ": gone=" + gone + " mHaveFrame=" + win.mHaveFrame
- + " mLayoutAttached=" + win.mLayoutAttached
- + " screen changed=" + win.isConfigChanged());
- final AppWindowToken atoken = win.mAppToken;
- if (gone) Slog.v(TAG, " GONE: mViewVisibility="
- + win.mViewVisibility + " mRelayoutCalled="
- + win.mRelayoutCalled + " hidden="
- + win.mRootToken.hidden + " hiddenRequested="
- + (atoken != null && atoken.hiddenRequested)
- + " mAttachedHidden=" + win.mAttachedHidden);
- else Slog.v(TAG, " VIS: mViewVisibility="
- + win.mViewVisibility + " mRelayoutCalled="
- + win.mRelayoutCalled + " hidden="
- + win.mRootToken.hidden + " hiddenRequested="
- + (atoken != null && atoken.hiddenRequested)
- + " mAttachedHidden=" + win.mAttachedHidden);
- }
-
- // If this view is GONE, then skip it -- keep the current
- // frame, and let the caller know so they can ignore it
- // if they want. (We do the normal layout for INVISIBLE
- // windows, since that means "perform layout as normal,
- // just don't display").
- if (!gone || !win.mHaveFrame || win.mLayoutNeeded
- || ((win.isConfigChanged() || win.setInsetsChanged()) &&
- ((win.mAttrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0 ||
- (win.mHasSurface && win.mAppToken != null &&
- win.mAppToken.layoutConfigChanges)))) {
- if (!win.mLayoutAttached) {
- if (initial) {
- //Slog.i(TAG, "Window " + this + " clearing mContentChanged - initial");
- win.mContentChanged = false;
- }
- if (win.mAttrs.type == TYPE_DREAM) {
- // Don't layout windows behind a dream, so that if it
- // does stuff like hide the status bar we won't get a
- // bad transition when it goes away.
- behindDream = true;
- }
- win.mLayoutNeeded = false;
- win.prelayout();
- mPolicy.layoutWindowLw(win, null);
- win.mLayoutSeq = seq;
- if (DEBUG_LAYOUT) Slog.v(TAG, " LAYOUT: mFrame="
- + win.mFrame + " mContainingFrame="
- + win.mContainingFrame + " mDisplayFrame="
- + win.mDisplayFrame);
- } else {
- if (topAttached < 0) topAttached = i;
- }
- }
- }
-
- boolean attachedBehindDream = false;
-
- // Now perform layout of attached windows, which usually
- // depend on the position of the window they are attached to.
- // XXX does not deal with windows that are attached to windows
- // that are themselves attached.
- for (i = topAttached; i >= 0; i--) {
- final WindowState win = windows.get(i);
-
- if (win.mLayoutAttached) {
- if (DEBUG_LAYOUT) Slog.v(TAG, "2ND PASS " + win
- + " mHaveFrame=" + win.mHaveFrame
- + " mViewVisibility=" + win.mViewVisibility
- + " mRelayoutCalled=" + win.mRelayoutCalled);
- // If this view is GONE, then skip it -- keep the current
- // frame, and let the caller know so they can ignore it
- // if they want. (We do the normal layout for INVISIBLE
- // windows, since that means "perform layout as normal,
- // just don't display").
- if (attachedBehindDream && mPolicy.canBeForceHidden(win, win.mAttrs)) {
- continue;
- }
- if ((win.mViewVisibility != View.GONE && win.mRelayoutCalled)
- || !win.mHaveFrame || win.mLayoutNeeded) {
- if (initial) {
- //Slog.i(TAG, "Window " + this + " clearing mContentChanged - initial");
- win.mContentChanged = false;
- }
- win.mLayoutNeeded = false;
- win.prelayout();
- mPolicy.layoutWindowLw(win, win.mAttachedWindow);
- win.mLayoutSeq = seq;
- if (DEBUG_LAYOUT) Slog.v(TAG, " LAYOUT: mFrame="
- + win.mFrame + " mContainingFrame="
- + win.mContainingFrame + " mDisplayFrame="
- + win.mDisplayFrame);
- }
- } else if (win.mAttrs.type == TYPE_DREAM) {
- // Don't layout windows behind a dream, so that if it
- // does stuff like hide the status bar we won't get a
- // bad transition when it goes away.
- attachedBehindDream = behindDream;
- }
- }
-
- // Window frames may have changed. Tell the input dispatcher about it.
- mInputMonitor.setUpdateInputWindowsNeededLw();
- if (updateInputWindows) {
- mInputMonitor.updateInputWindowsLw(false /*force*/);
- }
-
- mPolicy.finishLayoutLw();
- }
-
void makeWindowFreezingScreenIfNeededLocked(WindowState w) {
// If the screen is currently frozen or off, then keep
// it frozen/off until this window draws at its new
@@ -8524,7 +8235,7 @@
if (DEBUG_ORIENTATION) Slog.v(TAG, "Changing surface while display frozen: " + w);
w.mOrientationChanging = true;
w.mLastFreezeDuration = 0;
- mInnerFields.mOrientationChangeComplete = false;
+ mWindowPlacerLocked.mOrientationChangeComplete = false;
if (mWindowsFreezingScreen == WINDOWS_FREEZING_SCREENS_NONE) {
mWindowsFreezingScreen = WINDOWS_FREEZING_SCREENS_ACTIVE;
// XXX should probably keep timeout from
@@ -8537,411 +8248,9 @@
}
/**
- * Extracted from {@link #performLayoutAndPlaceSurfacesLockedInner} to reduce size of method.
- * @param windows List of windows on default display.
* @return bitmap indicating if another pass through layout must be made.
*/
- public int handleAppTransitionReadyLocked(WindowList windows) {
- int appsCount = mOpeningApps.size();
- if (!checkIfTransitionGoodToGo(appsCount)) {
- return 0;
- }
- if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "**** GOOD TO GO");
- int transit = mAppTransition.getAppTransition();
- if (mSkipAppTransitionAnimation) {
- transit = AppTransition.TRANSIT_UNSET;
- }
- mSkipAppTransitionAnimation = false;
- mNoAnimationNotifyOnTransitionFinished.clear();
-
- mH.removeMessages(H.APP_TRANSITION_TIMEOUT);
-
- rebuildAppWindowListLocked();
-
- mInnerFields.mWallpaperMayChange = false;
-
- // The top-most window will supply the layout params,
- // and we will determine it below.
- LayoutParams animLp = null;
- int bestAnimLayer = -1;
- boolean fullscreenAnim = false;
- boolean voiceInteraction = false;
-
- final WindowState lowerWallpaperTarget =
- mWallpaperControllerLocked.getLowerWallpaperTarget();
- final WindowState upperWallpaperTarget =
- mWallpaperControllerLocked.getUpperWallpaperTarget();
-
- boolean openingAppHasWallpaper = false;
- boolean closingAppHasWallpaper = false;
- final AppWindowToken lowerWallpaperAppToken;
- final AppWindowToken upperWallpaperAppToken;
- if (lowerWallpaperTarget == null) {
- lowerWallpaperAppToken = upperWallpaperAppToken = null;
- } else {
- lowerWallpaperAppToken = lowerWallpaperTarget.mAppToken;
- upperWallpaperAppToken = upperWallpaperTarget.mAppToken;
- }
-
- int i;
- // Do a first pass through the tokens for two
- // things:
- // (1) Determine if both the closing and opening
- // app token sets are wallpaper targets, in which
- // case special animations are needed
- // (since the wallpaper needs to stay static
- // behind them).
- // (2) Find the layout params of the top-most
- // application window in the tokens, which is
- // what will control the animation theme.
- final int closingAppsCount = mClosingApps.size();
- appsCount = closingAppsCount + mOpeningApps.size();
- for (i = 0; i < appsCount; i++) {
- final AppWindowToken wtoken;
- if (i < closingAppsCount) {
- wtoken = mClosingApps.valueAt(i);
- if (wtoken == lowerWallpaperAppToken || wtoken == upperWallpaperAppToken) {
- closingAppHasWallpaper = true;
- }
- } else {
- wtoken = mOpeningApps.valueAt(i - closingAppsCount);
- if (wtoken == lowerWallpaperAppToken || wtoken == upperWallpaperAppToken) {
- openingAppHasWallpaper = true;
- }
- }
-
- voiceInteraction |= wtoken.voiceInteraction;
-
- if (wtoken.appFullscreen) {
- WindowState ws = wtoken.findMainWindow();
- if (ws != null) {
- animLp = ws.mAttrs;
- bestAnimLayer = ws.mLayer;
- fullscreenAnim = true;
- }
- } else if (!fullscreenAnim) {
- WindowState ws = wtoken.findMainWindow();
- if (ws != null) {
- if (ws.mLayer > bestAnimLayer) {
- animLp = ws.mAttrs;
- bestAnimLayer = ws.mLayer;
- }
- }
- }
- }
-
- transit = maybeUpdateTransitToWallpaper(transit, openingAppHasWallpaper,
- closingAppHasWallpaper, lowerWallpaperTarget, upperWallpaperTarget);
-
- // If all closing windows are obscured, then there is
- // no need to do an animation. This is the case, for
- // example, when this transition is being done behind
- // the lock screen.
- if (!mPolicy.allowAppAnimationsLw()) {
- if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
- "Animations disallowed by keyguard or dream.");
- animLp = null;
- }
-
- processApplicationsAnimatingInPlace(transit);
-
- AppWindowToken topClosingApp = null;
- int topClosingLayer = 0;
- appsCount = mClosingApps.size();
- for (i = 0; i < appsCount; i++) {
- AppWindowToken wtoken = mClosingApps.valueAt(i);
- final AppWindowAnimator appAnimator = wtoken.mAppAnimator;
- if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Now closing app " + wtoken);
- appAnimator.clearThumbnail();
- appAnimator.animation = null;
- wtoken.inPendingTransaction = false;
- setTokenVisibilityLocked(wtoken, animLp, false, transit, false, voiceInteraction);
- wtoken.updateReportedVisibilityLocked();
- // Force the allDrawn flag, because we want to start
- // this guy's animations regardless of whether it's
- // gotten drawn.
- wtoken.allDrawn = true;
- wtoken.deferClearAllDrawn = false;
- // Ensure that apps that are mid-starting are also scheduled to have their
- // starting windows removed after the animation is complete
- if (wtoken.startingWindow != null && !wtoken.startingWindow.mExiting) {
- scheduleRemoveStartingWindowLocked(wtoken);
- }
- mAnimator.mAppWindowAnimating |= appAnimator.isAnimating();
-
- if (animLp != null) {
- int layer = -1;
- for (int j = 0; j < wtoken.windows.size(); j++) {
- WindowState win = wtoken.windows.get(j);
- if (win.mWinAnimator.mAnimLayer > layer) {
- layer = win.mWinAnimator.mAnimLayer;
- }
- }
- if (topClosingApp == null || layer > topClosingLayer) {
- topClosingApp = wtoken;
- topClosingLayer = layer;
- }
- }
- }
-
- AppWindowToken topOpeningApp = null;
- appsCount = mOpeningApps.size();
- for (i = 0; i < appsCount; i++) {
- AppWindowToken wtoken = mOpeningApps.valueAt(i);
- final AppWindowAnimator appAnimator = wtoken.mAppAnimator;
- if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Now opening app" + wtoken);
-
- if (!appAnimator.usingTransferredAnimation) {
- appAnimator.clearThumbnail();
- appAnimator.animation = null;
- }
- wtoken.inPendingTransaction = false;
- if (!setTokenVisibilityLocked(
- wtoken, animLp, true, transit, false, voiceInteraction)){
- // This token isn't going to be animating. Add it to the list of tokens to
- // be notified of app transition complete since the notification will not be
- // sent be the app window animator.
- mNoAnimationNotifyOnTransitionFinished.add(wtoken.token);
- }
- wtoken.updateReportedVisibilityLocked();
- wtoken.waitingToShow = false;
-
- appAnimator.mAllAppWinAnimators.clear();
- final int windowsCount = wtoken.allAppWindows.size();
- for (int j = 0; j < windowsCount; j++) {
- appAnimator.mAllAppWinAnimators.add(wtoken.allAppWindows.get(j).mWinAnimator);
- }
- mAnimator.mAnimating |= appAnimator.showAllWindowsLocked();
- mAnimator.mAppWindowAnimating |= appAnimator.isAnimating();
-
- int topOpeningLayer = 0;
- if (animLp != null) {
- int layer = -1;
- for (int j = 0; j < wtoken.windows.size(); j++) {
- WindowState win = wtoken.windows.get(j);
- if (win.mWinAnimator.mAnimLayer > layer) {
- layer = win.mWinAnimator.mAnimLayer;
- }
- }
- if (topOpeningApp == null || layer > topOpeningLayer) {
- topOpeningApp = wtoken;
- topOpeningLayer = layer;
- }
- }
- createThumbnailAppAnimator(transit, wtoken, topOpeningLayer, topClosingLayer);
- }
-
- AppWindowAnimator openingAppAnimator = (topOpeningApp == null) ? null :
- topOpeningApp.mAppAnimator;
- AppWindowAnimator closingAppAnimator = (topClosingApp == null) ? null :
- topClosingApp.mAppAnimator;
-
- mAppTransition.goodToGo(openingAppAnimator, closingAppAnimator);
- mAppTransition.postAnimationCallback();
- mAppTransition.clear();
-
- mOpeningApps.clear();
- mClosingApps.clear();
-
- // This has changed the visibility of windows, so perform
- // a new layout to get them all up-to-date.
- getDefaultDisplayContentLocked().layoutNeeded = true;
-
- // TODO(multidisplay): IMEs are only supported on the default display.
- if (windows == getDefaultWindowListLocked()
- && !moveInputMethodWindowsIfNeededLocked(true)) {
- assignLayersLocked(windows);
- }
- updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES, true /*updateInputWindows*/);
- mFocusMayChange = false;
- notifyActivityDrawnForKeyguard();
- return WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT
- | WindowManagerPolicy.FINISH_LAYOUT_REDO_CONFIG;
-
- }
-
- private int maybeUpdateTransitToWallpaper(int transit, boolean openingAppHasWallpaper,
- boolean closingAppHasWallpaper, WindowState lowerWallpaperTarget,
- WindowState upperWallpaperTarget) {
- // if wallpaper is animating in or out set oldWallpaper to null else to wallpaper
- final WindowState wallpaperTarget = mWallpaperControllerLocked.getWallpaperTarget();
- final WindowState oldWallpaper = mWallpaperControllerLocked.isWallpaperTargetAnimating()
- ? null : wallpaperTarget;
- if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
- "New wallpaper target=" + wallpaperTarget
- + ", oldWallpaper=" + oldWallpaper
- + ", lower target=" + lowerWallpaperTarget
- + ", upper target=" + upperWallpaperTarget);
- mAnimateWallpaperWithTarget = false;
- if (closingAppHasWallpaper && openingAppHasWallpaper) {
- if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Wallpaper animation!");
- switch (transit) {
- case AppTransition.TRANSIT_ACTIVITY_OPEN:
- case AppTransition.TRANSIT_TASK_OPEN:
- case AppTransition.TRANSIT_TASK_TO_FRONT:
- transit = AppTransition.TRANSIT_WALLPAPER_INTRA_OPEN;
- break;
- case AppTransition.TRANSIT_ACTIVITY_CLOSE:
- case AppTransition.TRANSIT_TASK_CLOSE:
- case AppTransition.TRANSIT_TASK_TO_BACK:
- transit = AppTransition.TRANSIT_WALLPAPER_INTRA_CLOSE;
- break;
- }
- if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
- "New transit: " + AppTransition.appTransitionToString(transit));
- } else if ((oldWallpaper != null) && !mOpeningApps.isEmpty()
- && !mOpeningApps.contains(oldWallpaper.mAppToken)) {
- // We are transitioning from an activity with
- // a wallpaper to one without.
- transit = AppTransition.TRANSIT_WALLPAPER_CLOSE;
- if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
- "New transit away from wallpaper: "
- + AppTransition.appTransitionToString(transit));
- } else if (wallpaperTarget != null && wallpaperTarget.isVisibleLw()) {
- // We are transitioning from an activity without
- // a wallpaper to now showing the wallpaper
- transit = AppTransition.TRANSIT_WALLPAPER_OPEN;
- if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
- "New transit into wallpaper: "
- + AppTransition.appTransitionToString(transit));
- } else {
- mAnimateWallpaperWithTarget = true;
- }
- return transit;
- }
-
- private void processApplicationsAnimatingInPlace(int transit) {
- if (transit == AppTransition.TRANSIT_TASK_IN_PLACE) {
- // Find the focused window
- final WindowState win =
- findFocusedWindowLocked(getDefaultDisplayContentLocked());
- if (win != null) {
- final AppWindowToken wtoken = win.mAppToken;
- final AppWindowAnimator appAnimator = wtoken.mAppAnimator;
- if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Now animating app in place " + wtoken);
- appAnimator.clearThumbnail();
- appAnimator.animation = null;
- updateTokenInPlaceLocked(wtoken, transit);
- wtoken.updateReportedVisibilityLocked();
-
- appAnimator.mAllAppWinAnimators.clear();
- final int N = wtoken.allAppWindows.size();
- for (int j = 0; j < N; j++) {
- appAnimator.mAllAppWinAnimators.add(wtoken.allAppWindows.get(j).mWinAnimator);
- }
- mAnimator.mAppWindowAnimating |= appAnimator.isAnimating();
- mAnimator.mAnimating |= appAnimator.showAllWindowsLocked();
- }
- }
- }
-
- private boolean checkIfTransitionGoodToGo(int appsCount) {
- if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
- "Checking " + appsCount + " opening apps (frozen="
- + mDisplayFrozen + " timeout="
- + mAppTransition.isTimeout() + ")...");
- if (!mAppTransition.isTimeout()) {
- for (int i = 0; i < appsCount; i++) {
- AppWindowToken wtoken = mOpeningApps.valueAt(i);
- if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
- "Check opening app=" + wtoken + ": allDrawn="
- + wtoken.allDrawn + " startingDisplayed="
- + wtoken.startingDisplayed + " startingMoved="
- + wtoken.startingMoved);
- if (!wtoken.allDrawn && !wtoken.startingDisplayed && !wtoken.startingMoved) {
- return false;
- }
- }
-
- // If the wallpaper is visible, we need to check it's ready too.
- return !mWallpaperControllerLocked.isWallpaperVisible() ||
- mWallpaperControllerLocked.wallpaperTransitionReady();
- }
- return true;
- }
-
- private void createThumbnailAppAnimator(int transit, AppWindowToken appToken,
- int openingLayer, int closingLayer) {
- AppWindowAnimator openingAppAnimator = (appToken == null) ? null : appToken.mAppAnimator;
- if (openingAppAnimator == null || openingAppAnimator.animation == null) {
- return;
- }
- final int taskId = appToken.mTask.mTaskId;
- Bitmap thumbnailHeader = mAppTransition.getAppTransitionThumbnailHeader(taskId);
- if (thumbnailHeader == null || thumbnailHeader.getConfig() == Config.ALPHA_8) {
- return;
- }
- // This thumbnail animation is very special, we need to have
- // an extra surface with the thumbnail included with the animation.
- Rect dirty = new Rect(0, 0, thumbnailHeader.getWidth(), thumbnailHeader.getHeight());
- try {
- // TODO(multi-display): support other displays
- final DisplayContent displayContent = getDefaultDisplayContentLocked();
- final Display display = displayContent.getDisplay();
- final DisplayInfo displayInfo = displayContent.getDisplayInfo();
-
- // Create a new surface for the thumbnail
- SurfaceControl surfaceControl = new SurfaceControl(mFxSession,
- "thumbnail anim", dirty.width(), dirty.height(),
- PixelFormat.TRANSLUCENT, SurfaceControl.HIDDEN);
- surfaceControl.setLayerStack(display.getLayerStack());
- if (SHOW_TRANSACTIONS) {
- Slog.i(TAG, " THUMBNAIL " + surfaceControl + ": CREATE");
- }
-
- // Draw the thumbnail onto the surface
- Surface drawSurface = new Surface();
- drawSurface.copyFrom(surfaceControl);
- Canvas c = drawSurface.lockCanvas(dirty);
- c.drawBitmap(thumbnailHeader, 0, 0, null);
- drawSurface.unlockCanvasAndPost(c);
- drawSurface.release();
-
- // Get the thumbnail animation
- Animation anim;
- if (mAppTransition.isNextThumbnailTransitionAspectScaled()) {
- // If this is a multi-window scenario, we use the windows frame as
- // destination of the thumbnail header animation. If this is a full screen
- // window scenario, we use the whole display as the target.
- WindowState win = appToken.findMainWindow();
- Rect appRect = win != null ? win.getContentFrameLw() :
- new Rect(0, 0, displayInfo.appWidth, displayInfo.appHeight);
- // For the new aspect-scaled transition, we want it to always show
- // above the animating opening/closing window, and we want to
- // synchronize its thumbnail surface with the surface for the
- // open/close animation (only on the way down)
- anim = mAppTransition.createThumbnailAspectScaleAnimationLocked(appRect,
- thumbnailHeader, taskId);
- Log.d(TAG, "assigning thumbnail force above layer: " + openingLayer + " " +
- closingLayer);
- openingAppAnimator.thumbnailForceAboveLayer = Math.max(openingLayer, closingLayer);
- openingAppAnimator.deferThumbnailDestruction =
- !mAppTransition.isNextThumbnailTransitionScaleUp();
- } else {
- anim = mAppTransition.createThumbnailScaleAnimationLocked(
- displayInfo.appWidth, displayInfo.appHeight, transit, thumbnailHeader);
- }
- anim.restrictDuration(MAX_ANIMATION_DURATION);
- anim.scaleCurrentDuration(getTransitionAnimationScaleLocked());
-
- openingAppAnimator.thumbnail = surfaceControl;
- openingAppAnimator.thumbnailLayer = openingLayer;
- openingAppAnimator.thumbnailAnimation = anim;
- mAppTransition.getNextAppTransitionStartRect(taskId, mTmpStartRect);
- openingAppAnimator.thumbnailX = mTmpStartRect.left;
- openingAppAnimator.thumbnailY = mTmpStartRect.top;
- } catch (OutOfResourcesException e) {
- Slog.e(TAG, "Can't allocate thumbnail/Canvas surface w=" + dirty.width()
- + " h=" + dirty.height(), e);
- openingAppAnimator.clearThumbnail();
- }
- }
-
- /**
- * Extracted from {@link #performLayoutAndPlaceSurfacesLockedInner} to reduce size of method.
- * @return bitmap indicating if another pass through layout must be made.
- */
- private int handleAnimatingStoppedAndTransitionLocked() {
+ int handleAnimatingStoppedAndTransitionLocked() {
int changes = 0;
mAppTransition.setIdle();
@@ -8971,7 +8280,7 @@
if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG,
"Wallpaper layer changed: assigning layers + relayout");
moveInputMethodWindowsIfNeededLocked(true);
- mInnerFields.mWallpaperMayChange = true;
+ mWindowPlacerLocked.mWallpaperMayChange = true;
// Since the window list has been rebuilt, focus might
// have to be recomputed since the actual order of windows
// might have changed again.
@@ -8980,7 +8289,7 @@
return changes;
}
- private void updateResizingWindows(final WindowState w) {
+ void updateResizingWindows(final WindowState w) {
final WindowStateAnimator winAnimator = w.mWinAnimator;
if (w.mHasSurface && w.mLayoutSeq == mLayoutSeq) {
w.setInsetsChanged();
@@ -9052,707 +8361,6 @@
}
}
- /**
- * Extracted from {@link #performLayoutAndPlaceSurfacesLockedInner} to reduce size of method.
- * @param w WindowState this method is applied to.
- * @param innerDw Width of app window.
- * @param innerDh Height of app window.
- */
- private void handleNotObscuredLocked(final WindowState w,
- final int innerDw, final int innerDh) {
- final WindowManager.LayoutParams attrs = w.mAttrs;
- final int attrFlags = attrs.flags;
- final boolean canBeSeen = w.isDisplayedLw();
- final boolean opaqueDrawn = canBeSeen && w.isOpaqueDrawn();
-
- if (opaqueDrawn && w.isFullscreen(innerDw, innerDh)) {
- // This window completely covers everything behind it,
- // so we want to leave all of them as undimmed (for
- // performance reasons).
- mInnerFields.mObscured = true;
- }
-
- if (w.mHasSurface) {
- if ((attrFlags&FLAG_KEEP_SCREEN_ON) != 0) {
- mInnerFields.mHoldScreen = w.mSession;
- }
- if (!mInnerFields.mSyswin && w.mAttrs.screenBrightness >= 0
- && mInnerFields.mScreenBrightness < 0) {
- mInnerFields.mScreenBrightness = w.mAttrs.screenBrightness;
- }
- if (!mInnerFields.mSyswin && w.mAttrs.buttonBrightness >= 0
- && mInnerFields.mButtonBrightness < 0) {
- mInnerFields.mButtonBrightness = w.mAttrs.buttonBrightness;
- }
- if (!mInnerFields.mSyswin && w.mAttrs.userActivityTimeout >= 0
- && mInnerFields.mUserActivityTimeout < 0) {
- mInnerFields.mUserActivityTimeout = w.mAttrs.userActivityTimeout;
- }
-
- final int type = attrs.type;
- if (canBeSeen
- && (type == TYPE_SYSTEM_DIALOG
- || type == TYPE_SYSTEM_ERROR
- || (attrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0)) {
- mInnerFields.mSyswin = true;
- }
-
- if (canBeSeen) {
- // This function assumes that the contents of the default display are
- // processed first before secondary displays.
- final DisplayContent displayContent = w.getDisplayContent();
- if (displayContent != null && displayContent.isDefaultDisplay) {
- // While a dream or keyguard is showing, obscure ordinary application
- // content on secondary displays (by forcibly enabling mirroring unless
- // there is other content we want to show) but still allow opaque
- // keyguard dialogs to be shown.
- if (type == TYPE_DREAM || (attrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0) {
- mInnerFields.mObscureApplicationContentOnSecondaryDisplays = true;
- }
- mInnerFields.mDisplayHasContent = true;
- } else if (displayContent != null &&
- (!mInnerFields.mObscureApplicationContentOnSecondaryDisplays
- || (mInnerFields.mObscured && type == TYPE_KEYGUARD_DIALOG))) {
- // Allow full screen keyguard presentation dialogs to be seen.
- mInnerFields.mDisplayHasContent = true;
- }
- if (mInnerFields.mPreferredRefreshRate == 0
- && w.mAttrs.preferredRefreshRate != 0) {
- mInnerFields.mPreferredRefreshRate = w.mAttrs.preferredRefreshRate;
- }
- if (mInnerFields.mPreferredModeId == 0
- && w.mAttrs.preferredDisplayModeId != 0) {
- mInnerFields.mPreferredModeId = w.mAttrs.preferredDisplayModeId;
- }
- }
- }
- }
-
- private void handleFlagDimBehind(WindowState w) {
- final WindowManager.LayoutParams attrs = w.mAttrs;
- if ((attrs.flags & FLAG_DIM_BEHIND) != 0
- && w.isDisplayedLw()
- && !w.mExiting) {
- final WindowStateAnimator winAnimator = w.mWinAnimator;
- final Task task = w.getTask();
- if (task == null) {
- return;
- }
- task.setContinueDimming();
- if (!task.isDimming(winAnimator)) {
- if (localLOGV) Slog.v(TAG, "Win " + w + " start dimming.");
- task.startDimmingIfNeeded(winAnimator);
- }
- }
- }
-
- private void updateAllDrawnLocked(DisplayContent displayContent) {
- // See if any windows have been drawn, so they (and others
- // associated with them) can now be shown.
- ArrayList<TaskStack> stacks = displayContent.getStacks();
- for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
- final ArrayList<Task> tasks = stacks.get(stackNdx).getTasks();
- for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) {
- final AppTokenList tokens = tasks.get(taskNdx).mAppTokens;
- for (int tokenNdx = tokens.size() - 1; tokenNdx >= 0; --tokenNdx) {
- final AppWindowToken wtoken = tokens.get(tokenNdx);
- if (!wtoken.allDrawn) {
- int numInteresting = wtoken.numInterestingWindows;
- if (numInteresting > 0 && wtoken.numDrawnWindows >= numInteresting) {
- if (DEBUG_VISIBILITY) Slog.v(TAG,
- "allDrawn: " + wtoken
- + " interesting=" + numInteresting
- + " drawn=" + wtoken.numDrawnWindows);
- wtoken.allDrawn = true;
- // Force an additional layout pass where WindowStateAnimator#
- // commitFinishDrawingLocked() will call performShowLocked().
- displayContent.layoutNeeded = true;
- mH.obtainMessage(H.NOTIFY_ACTIVITY_DRAWN, wtoken.token).sendToTarget();
- }
- }
- }
- }
- }
- }
-
- // "Something has changed! Let's make it correct now."
- private final void performLayoutAndPlaceSurfacesLockedInner(boolean recoveringMemory) {
- if (DEBUG_WINDOW_TRACE) {
- Slog.v(TAG, "performLayoutAndPlaceSurfacesLockedInner: entry. Called by "
- + Debug.getCallers(3));
- }
-
- int i;
- boolean updateInputWindowsNeeded = false;
-
- if (mFocusMayChange) {
- mFocusMayChange = false;
- updateInputWindowsNeeded = updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
- false /*updateInputWindows*/);
- }
-
- // Initialize state of exiting tokens.
- final int numDisplays = mDisplayContents.size();
- for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
- final DisplayContent displayContent = mDisplayContents.valueAt(displayNdx);
- for (i=displayContent.mExitingTokens.size()-1; i>=0; i--) {
- displayContent.mExitingTokens.get(i).hasVisible = false;
- }
- }
-
- for (int stackNdx = mStackIdToStack.size() - 1; stackNdx >= 0; --stackNdx) {
- // Initialize state of exiting applications.
- final AppTokenList exitingAppTokens =
- mStackIdToStack.valueAt(stackNdx).mExitingAppTokens;
- for (int tokenNdx = exitingAppTokens.size() - 1; tokenNdx >= 0; --tokenNdx) {
- exitingAppTokens.get(tokenNdx).hasVisible = false;
- }
- }
-
- mInnerFields.mHoldScreen = null;
- mInnerFields.mScreenBrightness = -1;
- mInnerFields.mButtonBrightness = -1;
- mInnerFields.mUserActivityTimeout = -1;
- mInnerFields.mObscureApplicationContentOnSecondaryDisplays = false;
-
- mTransactionSequence++;
-
- final DisplayContent defaultDisplay = getDefaultDisplayContentLocked();
- final DisplayInfo defaultInfo = defaultDisplay.getDisplayInfo();
- final int defaultDw = defaultInfo.logicalWidth;
- final int defaultDh = defaultInfo.logicalHeight;
-
- if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
- ">>> OPEN TRANSACTION performLayoutAndPlaceSurfaces");
- SurfaceControl.openTransaction();
- try {
-
- if (mWatermark != null) {
- mWatermark.positionSurface(defaultDw, defaultDh);
- }
- if (mStrictModeFlash != null) {
- mStrictModeFlash.positionSurface(defaultDw, defaultDh);
- }
- if (mCircularDisplayMask != null) {
- mCircularDisplayMask.positionSurface(defaultDw, defaultDh, mRotation);
- }
- if (mEmulatorDisplayOverlay != null) {
- mEmulatorDisplayOverlay.positionSurface(defaultDw, defaultDh, mRotation);
- }
-
- boolean focusDisplayed = false;
-
- for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
- final DisplayContent displayContent = mDisplayContents.valueAt(displayNdx);
- boolean updateAllDrawn = false;
- WindowList windows = displayContent.getWindowList();
- DisplayInfo displayInfo = displayContent.getDisplayInfo();
- final int displayId = displayContent.getDisplayId();
- final int dw = displayInfo.logicalWidth;
- final int dh = displayInfo.logicalHeight;
- final int innerDw = displayInfo.appWidth;
- final int innerDh = displayInfo.appHeight;
- final boolean isDefaultDisplay = (displayId == Display.DEFAULT_DISPLAY);
-
- // Reset for each display.
- mInnerFields.mDisplayHasContent = false;
- mInnerFields.mPreferredRefreshRate = 0;
- mInnerFields.mPreferredModeId = 0;
-
- int repeats = 0;
- do {
- repeats++;
- if (repeats > 6) {
- Slog.w(TAG, "Animation repeat aborted after too many iterations");
- displayContent.layoutNeeded = false;
- break;
- }
-
- if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("On entry to LockedInner",
- displayContent.pendingLayoutChanges);
-
- if ((displayContent.pendingLayoutChanges &
- WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER) != 0 &&
- mWallpaperControllerLocked.adjustWallpaperWindows()) {
- assignLayersLocked(windows);
- displayContent.layoutNeeded = true;
- }
-
- if (isDefaultDisplay && (displayContent.pendingLayoutChanges
- & WindowManagerPolicy.FINISH_LAYOUT_REDO_CONFIG) != 0) {
- if (DEBUG_LAYOUT) Slog.v(TAG, "Computing new config from layout");
- if (updateOrientationFromAppTokensLocked(true)) {
- displayContent.layoutNeeded = true;
- mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
- }
- }
-
- if ((displayContent.pendingLayoutChanges
- & WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT) != 0) {
- displayContent.layoutNeeded = true;
- }
-
- // FIRST LOOP: Perform a layout, if needed.
- if (repeats < LAYOUT_REPEAT_THRESHOLD) {
- performLayoutLockedInner(displayContent, repeats == 1,
- false /*updateInputWindows*/);
- } else {
- Slog.w(TAG, "Layout repeat skipped after too many iterations");
- }
-
- // FIRST AND ONE HALF LOOP: Make WindowManagerPolicy think
- // it is animating.
- displayContent.pendingLayoutChanges = 0;
-
- if (isDefaultDisplay) {
- mPolicy.beginPostLayoutPolicyLw(dw, dh);
- for (i = windows.size() - 1; i >= 0; i--) {
- WindowState w = windows.get(i);
- if (w.mHasSurface) {
- mPolicy.applyPostLayoutPolicyLw(w, w.mAttrs, w.mAttachedWindow);
- }
- }
- displayContent.pendingLayoutChanges |= mPolicy.finishPostLayoutPolicyLw();
- if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats(
- "after finishPostLayoutPolicyLw", displayContent.pendingLayoutChanges);
- }
- } while (displayContent.pendingLayoutChanges != 0);
-
- mInnerFields.mObscured = false;
- mInnerFields.mSyswin = false;
- displayContent.resetDimming();
-
- // Only used if default window
- final boolean someoneLosingFocus = !mLosingFocus.isEmpty();
-
- final int N = windows.size();
- for (i=N-1; i>=0; i--) {
- WindowState w = windows.get(i);
- final Task task = w.getTask();
- if (task == null && w.getAttrs().type != TYPE_PRIVATE_PRESENTATION) {
- continue;
- }
-
- final boolean obscuredChanged = w.mObscured != mInnerFields.mObscured;
-
- // Update effect.
- w.mObscured = mInnerFields.mObscured;
- if (!mInnerFields.mObscured) {
- handleNotObscuredLocked(w, innerDw, innerDh);
- }
-
- if (task != null && !task.getContinueDimming()) {
- handleFlagDimBehind(w);
- }
-
- if (isDefaultDisplay && obscuredChanged
- && mWallpaperControllerLocked.isWallpaperTarget(w) && w.isVisibleLw()) {
- // This is the wallpaper target and its obscured state
- // changed... make sure the current wallaper's visibility
- // has been updated accordingly.
- mWallpaperControllerLocked.updateWallpaperVisibility();
- }
-
- final WindowStateAnimator winAnimator = w.mWinAnimator;
-
- // If the window has moved due to its containing content frame changing, then
- // notify the listeners and optionally animate it.
- if (w.hasMoved()) {
- // Frame has moved, containing content frame has also moved, and we're not
- // currently animating... let's do something.
- final int left = w.mFrame.left;
- final int top = w.mFrame.top;
- if ((w.mAttrs.privateFlags & PRIVATE_FLAG_NO_MOVE_ANIMATION) == 0) {
- Animation a = AnimationUtils.loadAnimation(mContext,
- com.android.internal.R.anim.window_move_from_decor);
- winAnimator.setAnimation(a);
- winAnimator.mAnimDw = w.mLastFrame.left - left;
- winAnimator.mAnimDh = w.mLastFrame.top - top;
- winAnimator.mAnimateMove = true;
- winAnimator.mAnimatingMove = true;
- }
-
- //TODO (multidisplay): Accessibility supported only for the default display.
- if (mAccessibilityController != null
- && displayId == Display.DEFAULT_DISPLAY) {
- mAccessibilityController.onSomeWindowResizedOrMovedLocked();
- }
-
- try {
- w.mClient.moved(left, top);
- } catch (RemoteException e) {
- }
- }
-
- //Slog.i(TAG, "Window " + this + " clearing mContentChanged - done placing");
- w.mContentChanged = false;
-
- // Moved from updateWindowsAndWallpaperLocked().
- if (w.mHasSurface) {
- // Take care of the window being ready to display.
- final boolean committed =
- winAnimator.commitFinishDrawingLocked();
- if (isDefaultDisplay && committed) {
- if (w.mAttrs.type == TYPE_DREAM) {
- // HACK: When a dream is shown, it may at that
- // point hide the lock screen. So we need to
- // redo the layout to let the phone window manager
- // make this happen.
- displayContent.pendingLayoutChanges |=
- WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT;
- if (DEBUG_LAYOUT_REPEATS) {
- debugLayoutRepeats(
- "dream and commitFinishDrawingLocked true",
- displayContent.pendingLayoutChanges);
- }
- }
- if ((w.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0) {
- if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG,
- "First draw done in potential wallpaper target " + w);
- mInnerFields.mWallpaperMayChange = true;
- displayContent.pendingLayoutChanges |=
- WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
- if (DEBUG_LAYOUT_REPEATS) {
- debugLayoutRepeats(
- "wallpaper and commitFinishDrawingLocked true",
- displayContent.pendingLayoutChanges);
- }
- }
- }
-
- winAnimator.setSurfaceBoundariesLocked(recoveringMemory);
- }
-
- final AppWindowToken atoken = w.mAppToken;
- if (DEBUG_STARTING_WINDOW && atoken != null
- && w == atoken.startingWindow) {
- Slog.d(TAG, "updateWindows: starting " + w + " isOnScreen="
- + w.isOnScreen() + " allDrawn=" + atoken.allDrawn
- + " freezingScreen=" + atoken.mAppAnimator.freezingScreen);
- }
- if (atoken != null
- && (!atoken.allDrawn || atoken.mAppAnimator.freezingScreen)) {
- if (atoken.lastTransactionSequence != mTransactionSequence) {
- atoken.lastTransactionSequence = mTransactionSequence;
- atoken.numInterestingWindows = atoken.numDrawnWindows = 0;
- atoken.startingDisplayed = false;
- }
- if ((w.isOnScreenIgnoringKeyguard()
- || winAnimator.mAttrType == TYPE_BASE_APPLICATION)
- && !w.mExiting && !w.mDestroying) {
- if (DEBUG_VISIBILITY || DEBUG_ORIENTATION) {
- Slog.v(TAG, "Eval win " + w + ": isDrawn=" + w.isDrawnLw()
- + ", isAnimating=" + winAnimator.isAnimating());
- if (!w.isDrawnLw()) {
- Slog.v(TAG, "Not displayed: s=" + winAnimator.mSurfaceControl
- + " pv=" + w.mPolicyVisibility
- + " mDrawState=" + winAnimator.drawStateToString()
- + " ah=" + w.mAttachedHidden
- + " th=" + atoken.hiddenRequested
- + " a=" + winAnimator.mAnimating);
- }
- }
- if (w != atoken.startingWindow) {
- if (!atoken.mAppAnimator.freezingScreen || !w.mAppFreezing) {
- atoken.numInterestingWindows++;
- if (w.isDrawnLw()) {
- atoken.numDrawnWindows++;
- if (DEBUG_VISIBILITY || DEBUG_ORIENTATION) Slog.v(TAG,
- "tokenMayBeDrawn: " + atoken
- + " freezingScreen=" + atoken.mAppAnimator.freezingScreen
- + " mAppFreezing=" + w.mAppFreezing);
- updateAllDrawn = true;
- }
- }
- } else if (w.isDrawnLw()) {
- atoken.startingDisplayed = true;
- }
- }
- }
-
- if (isDefaultDisplay && someoneLosingFocus && (w == mCurrentFocus)
- && w.isDisplayedLw()) {
- focusDisplayed = true;
- }
-
- updateResizingWindows(w);
- }
-
- mDisplayManagerInternal.setDisplayProperties(displayId,
- mInnerFields.mDisplayHasContent, mInnerFields.mPreferredRefreshRate,
- mInnerFields.mPreferredModeId,
- true /* inTraversal, must call performTraversalInTrans... below */);
-
- getDisplayContentLocked(displayId).stopDimmingIfNeeded();
-
- if (updateAllDrawn) {
- updateAllDrawnLocked(displayContent);
- }
- }
-
- if (focusDisplayed) {
- mH.sendEmptyMessage(H.REPORT_LOSING_FOCUS);
- }
-
- // Give the display manager a chance to adjust properties
- // like display rotation if it needs to.
- mDisplayManagerInternal.performTraversalInTransactionFromWindowManager();
-
- } catch (RuntimeException e) {
- Slog.wtf(TAG, "Unhandled exception in Window Manager", e);
- } finally {
- SurfaceControl.closeTransaction();
- if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
- "<<< CLOSE TRANSACTION performLayoutAndPlaceSurfaces");
- }
-
- final WindowList defaultWindows = defaultDisplay.getWindowList();
-
- // If we are ready to perform an app transition, check through
- // all of the app tokens to be shown and see if they are ready
- // to go.
- if (mAppTransition.isReady()) {
- defaultDisplay.pendingLayoutChanges |= handleAppTransitionReadyLocked(defaultWindows);
- if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("after handleAppTransitionReadyLocked",
- defaultDisplay.pendingLayoutChanges);
- }
-
- if (!mAnimator.mAppWindowAnimating && mAppTransition.isRunning()) {
- // We have finished the animation of an app transition. To do
- // this, we have delayed a lot of operations like showing and
- // hiding apps, moving apps in Z-order, etc. The app token list
- // reflects the correct Z-order, but the window list may now
- // be out of sync with it. So here we will just rebuild the
- // entire app window list. Fun!
- defaultDisplay.pendingLayoutChanges |= handleAnimatingStoppedAndTransitionLocked();
- if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("after handleAnimStopAndXitionLock",
- defaultDisplay.pendingLayoutChanges);
- }
-
- if (mInnerFields.mWallpaperForceHidingChanged && defaultDisplay.pendingLayoutChanges == 0
- && !mAppTransition.isReady()) {
- // At this point, there was a window with a wallpaper that
- // was force hiding other windows behind it, but now it
- // is going away. This may be simple -- just animate
- // away the wallpaper and its window -- or it may be
- // hard -- the wallpaper now needs to be shown behind
- // something that was hidden.
- defaultDisplay.pendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT;
- if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("after animateAwayWallpaperLocked",
- defaultDisplay.pendingLayoutChanges);
- }
- mInnerFields.mWallpaperForceHidingChanged = false;
-
- if (mInnerFields.mWallpaperMayChange) {
- if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG, "Wallpaper may change! Adjusting");
- defaultDisplay.pendingLayoutChanges |=
- WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
- if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("WallpaperMayChange",
- defaultDisplay.pendingLayoutChanges);
- }
-
- if (mFocusMayChange) {
- mFocusMayChange = false;
- if (updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES,
- false /*updateInputWindows*/)) {
- updateInputWindowsNeeded = true;
- defaultDisplay.pendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM;
- }
- }
-
- if (needsLayout()) {
- defaultDisplay.pendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT;
- if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("mLayoutNeeded",
- defaultDisplay.pendingLayoutChanges);
- }
-
- for (i = mResizingWindows.size() - 1; i >= 0; i--) {
- WindowState win = mResizingWindows.get(i);
- if (win.mAppFreezing) {
- // Don't remove this window until rotation has completed.
- continue;
- }
- win.reportResized();
- mResizingWindows.remove(i);
- }
-
- if (DEBUG_ORIENTATION && mDisplayFrozen) Slog.v(TAG,
- "With display frozen, orientationChangeComplete="
- + mInnerFields.mOrientationChangeComplete);
- if (mInnerFields.mOrientationChangeComplete) {
- if (mWindowsFreezingScreen != WINDOWS_FREEZING_SCREENS_NONE) {
- mWindowsFreezingScreen = WINDOWS_FREEZING_SCREENS_NONE;
- mLastFinishedFreezeSource = mInnerFields.mLastWindowFreezeSource;
- mH.removeMessages(H.WINDOW_FREEZE_TIMEOUT);
- }
- stopFreezingDisplayLocked();
- }
-
- // Destroy the surface of any windows that are no longer visible.
- boolean wallpaperDestroyed = false;
- i = mDestroySurface.size();
- if (i > 0) {
- do {
- i--;
- WindowState win = mDestroySurface.get(i);
- win.mDestroying = false;
- if (mInputMethodWindow == win) {
- mInputMethodWindow = null;
- }
- if (mWallpaperControllerLocked.isWallpaperTarget(win)) {
- wallpaperDestroyed = true;
- }
- win.mWinAnimator.destroySurfaceLocked();
- } while (i > 0);
- mDestroySurface.clear();
- }
-
- // Time to remove any exiting tokens?
- for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
- final DisplayContent displayContent = mDisplayContents.valueAt(displayNdx);
- ArrayList<WindowToken> exitingTokens = displayContent.mExitingTokens;
- for (i = exitingTokens.size() - 1; i >= 0; i--) {
- WindowToken token = exitingTokens.get(i);
- if (!token.hasVisible) {
- exitingTokens.remove(i);
- if (token.windowType == TYPE_WALLPAPER) {
- mWallpaperControllerLocked.removeWallpaperToken(token);
- }
- }
- }
- }
-
- // Time to remove any exiting applications?
- for (int stackNdx = mStackIdToStack.size() - 1; stackNdx >= 0; --stackNdx) {
- // Initialize state of exiting applications.
- final AppTokenList exitingAppTokens =
- mStackIdToStack.valueAt(stackNdx).mExitingAppTokens;
- for (i = exitingAppTokens.size() - 1; i >= 0; i--) {
- AppWindowToken token = exitingAppTokens.get(i);
- if (!token.hasVisible && !mClosingApps.contains(token) &&
- (!token.mIsExiting || token.allAppWindows.isEmpty())) {
- // Make sure there is no animation running on this token,
- // so any windows associated with it will be removed as
- // soon as their animations are complete
- token.mAppAnimator.clearAnimation();
- token.mAppAnimator.animating = false;
- if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG,
- "performLayout: App token exiting now removed" + token);
- token.removeAppFromTaskLocked();
- }
- }
- }
-
- if (wallpaperDestroyed) {
- defaultDisplay.pendingLayoutChanges |=
- WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
- defaultDisplay.layoutNeeded = true;
- }
-
- for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
- final DisplayContent displayContent = mDisplayContents.valueAt(displayNdx);
- if (displayContent.pendingLayoutChanges != 0) {
- displayContent.layoutNeeded = true;
- }
- }
-
- // Finally update all input windows now that the window changes have stabilized.
- mInputMonitor.updateInputWindowsLw(true /*force*/);
-
- setHoldScreenLocked(mInnerFields.mHoldScreen);
- if (!mDisplayFrozen) {
- if (mInnerFields.mScreenBrightness < 0 || mInnerFields.mScreenBrightness > 1.0f) {
- mPowerManagerInternal.setScreenBrightnessOverrideFromWindowManager(-1);
- } else {
- mPowerManagerInternal.setScreenBrightnessOverrideFromWindowManager(
- toBrightnessOverride(mInnerFields.mScreenBrightness));
- }
- if (mInnerFields.mButtonBrightness < 0 || mInnerFields.mButtonBrightness > 1.0f) {
- mPowerManagerInternal.setButtonBrightnessOverrideFromWindowManager(-1);
- } else {
- mPowerManagerInternal.setButtonBrightnessOverrideFromWindowManager(
- toBrightnessOverride(mInnerFields.mButtonBrightness));
- }
- mPowerManagerInternal.setUserActivityTimeoutOverrideFromWindowManager(
- mInnerFields.mUserActivityTimeout);
- }
-
- if (mTurnOnScreen) {
- if (mAllowTheaterModeWakeFromLayout
- || Settings.Global.getInt(mContext.getContentResolver(),
- Settings.Global.THEATER_MODE_ON, 0) == 0) {
- if (DEBUG_VISIBILITY || DEBUG_POWER) {
- Slog.v(TAG, "Turning screen on after layout!");
- }
- mPowerManager.wakeUp(SystemClock.uptimeMillis(), "android.server.wm:TURN_ON");
- }
- mTurnOnScreen = false;
- }
-
- if (mInnerFields.mUpdateRotation) {
- if (DEBUG_ORIENTATION) Slog.d(TAG, "Performing post-rotate rotation");
- if (updateRotationUncheckedLocked(false)) {
- mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
- } else {
- mInnerFields.mUpdateRotation = false;
- }
- }
-
- if (mWaitingForDrawnCallback != null ||
- (mInnerFields.mOrientationChangeComplete && !defaultDisplay.layoutNeeded &&
- !mInnerFields.mUpdateRotation)) {
- checkDrawnWindowsLocked();
- }
-
- final int N = mPendingRemove.size();
- if (N > 0) {
- if (mPendingRemoveTmp.length < N) {
- mPendingRemoveTmp = new WindowState[N+10];
- }
- mPendingRemove.toArray(mPendingRemoveTmp);
- mPendingRemove.clear();
- DisplayContentList displayList = new DisplayContentList();
- for (i = 0; i < N; i++) {
- WindowState w = mPendingRemoveTmp[i];
- removeWindowInnerLocked(w);
- final DisplayContent displayContent = w.getDisplayContent();
- if (displayContent != null && !displayList.contains(displayContent)) {
- displayList.add(displayContent);
- }
- }
-
- for (DisplayContent displayContent : displayList) {
- assignLayersLocked(displayContent.getWindowList());
- displayContent.layoutNeeded = true;
- }
- }
-
- // Remove all deferred displays stacks, tasks, and activities.
- for (int displayNdx = mDisplayContents.size() - 1; displayNdx >= 0; --displayNdx) {
- mDisplayContents.valueAt(displayNdx).checkForDeferredActions();
- }
-
- if (updateInputWindowsNeeded) {
- mInputMonitor.updateInputWindowsLw(false /*force*/);
- }
- setFocusTaskRegion();
-
- // Check to see if we are now in a state where the screen should
- // be enabled, because the window obscured flags have changed.
- enableScreenIfNeededLocked();
-
- scheduleAnimationLocked();
-
- if (DEBUG_WINDOW_TRACE) {
- Slog.e(TAG, "performLayoutAndPlaceSurfacesLockedInner exit: animating="
- + mAnimator.mAnimating);
- }
- }
-
- private int toBrightnessOverride(float value) {
- return (int)(value * PowerManager.BRIGHTNESS_ON);
- }
-
void checkDrawnWindowsLocked() {
if (mWaitingForDrawn.isEmpty() || mWaitingForDrawnCallback == null) {
return;
@@ -9821,7 +8429,7 @@
}
}
- private boolean needsLayout() {
+ boolean needsLayout() {
final int numDisplays = mDisplayContents.size();
for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
final DisplayContent displayContent = mDisplayContents.valueAt(displayNdx);
@@ -9832,41 +8440,6 @@
return false;
}
- boolean copyAnimToLayoutParamsLocked() {
- boolean doRequest = false;
-
- final int bulkUpdateParams = mAnimator.mBulkUpdateParams;
- if ((bulkUpdateParams & LayoutFields.SET_UPDATE_ROTATION) != 0) {
- mInnerFields.mUpdateRotation = true;
- doRequest = true;
- }
- if ((bulkUpdateParams & LayoutFields.SET_WALLPAPER_MAY_CHANGE) != 0) {
- mInnerFields.mWallpaperMayChange = true;
- doRequest = true;
- }
- if ((bulkUpdateParams & LayoutFields.SET_FORCE_HIDING_CHANGED) != 0) {
- mInnerFields.mWallpaperForceHidingChanged = true;
- doRequest = true;
- }
- if ((bulkUpdateParams & LayoutFields.SET_ORIENTATION_CHANGE_COMPLETE) == 0) {
- mInnerFields.mOrientationChangeComplete = false;
- } else {
- mInnerFields.mOrientationChangeComplete = true;
- mInnerFields.mLastWindowFreezeSource = mAnimator.mLastWindowFreezeSource;
- if (mWindowsFreezingScreen != WINDOWS_FREEZING_SCREENS_NONE) {
- doRequest = true;
- }
- }
- if ((bulkUpdateParams & LayoutFields.SET_TURN_ON_SCREEN) != 0) {
- mTurnOnScreen = true;
- }
- if ((bulkUpdateParams & LayoutFields.SET_WALLPAPER_ACTION_PENDING) != 0) {
- mInnerFields.mWallpaperActionPending = true;
- }
-
- return doRequest;
- }
-
/** If a window that has an animation specifying a colored background and the current wallpaper
* is visible, then the color goes *below* the wallpaper so we don't cause the wallpaper to
* suddenly disappear. */
@@ -9990,7 +8563,7 @@
return leakedSurface || killedApps;
}
- private boolean updateFocusedWindowLocked(int mode, boolean updateInputWindows) {
+ boolean updateFocusedWindowLocked(int mode, boolean updateInputWindows) {
WindowState newFocus = computeFocusedWindowLocked();
if (mCurrentFocus != newFocus) {
Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "wmUpdateFocus");
@@ -10019,7 +8592,8 @@
if (imWindowChanged && oldFocus != mInputMethodWindow) {
// Focus of the input method window changed. Perform layout if needed.
if (mode == UPDATE_FOCUS_PLACING_SURFACES) {
- performLayoutLockedInner(displayContent, true /*initial*/, updateInputWindows);
+ mWindowPlacerLocked.performLayoutLockedInner(displayContent, true /*initial*/,
+ updateInputWindows);
focusChanged &= ~WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT;
} else if (mode == UPDATE_FOCUS_WILL_PLACE_SURFACES) {
// Client will do the layout, but we need to assign layers
@@ -10032,7 +8606,8 @@
// The change in focus caused us to need to do a layout. Okay.
displayContent.layoutNeeded = true;
if (mode == UPDATE_FOCUS_PLACING_SURFACES) {
- performLayoutLockedInner(displayContent, true /*initial*/, updateInputWindows);
+ mWindowPlacerLocked.performLayoutLockedInner(displayContent, true /*initial*/,
+ updateInputWindows);
}
}
@@ -10060,7 +8635,7 @@
return null;
}
- private WindowState findFocusedWindowLocked(DisplayContent displayContent) {
+ WindowState findFocusedWindowLocked(DisplayContent displayContent) {
final WindowList windows = displayContent.getWindowList();
for (int i = windows.size() - 1; i >= 0; i--) {
final WindowState win = windows.get(i);
@@ -10184,7 +8759,7 @@
}
}
- private void stopFreezingDisplayLocked() {
+ void stopFreezingDisplayLocked() {
if (!mDisplayFrozen) {
return;
}
@@ -10391,7 +8966,7 @@
synchronized (mWindowMap) {
int visibility = mPolicy.adjustSystemUiVisibilityLw(mLastStatusBarVisibility);
updateStatusBarVisibilityLocked(visibility);
- performLayoutAndPlaceSurfacesLocked();
+ mWindowPlacerLocked.performSurfacePlacement();
}
}
@@ -11005,13 +9580,6 @@
synchronized (mWindowMap) { }
}
- void debugLayoutRepeats(final String msg, int pendingLayoutChanges) {
- if (mLayoutRepeatCount >= LAYOUT_REPEAT_THRESHOLD) {
- Slog.v(TAG, "Layouts looping: " + msg + ", mPendingLayoutChanges = 0x" +
- Integer.toHexString(pendingLayoutChanges));
- }
- }
-
private DisplayContent newDisplayContentLocked(final Display display) {
DisplayContent displayContent = new DisplayContent(display, this);
final int displayId = display.getDisplayId();
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 761e5eb..7e15dd5 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -18,6 +18,7 @@
import static android.app.ActivityManager.FREEFORM_WORKSPACE_STACK_ID;
import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW;
+import static android.view.WindowManager.LayoutParams.FLAG_DIM_BEHIND;
import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED;
import static android.view.WindowManager.LayoutParams.LAST_SUB_WINDOW;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_COMPATIBLE_WINDOW;
@@ -1255,6 +1256,20 @@
mInputWindowHandle.inputChannel = null;
}
+ void handleFlagDimBehind() {
+ if ((mAttrs.flags & FLAG_DIM_BEHIND) != 0 && isDisplayedLw() && !mExiting) {
+ final Task task = getTask();
+ if (task == null) {
+ return;
+ }
+ task.setContinueDimming();
+ if (!task.isDimming(mWinAnimator)) {
+ if (WindowManagerService.localLOGV) Slog.v(TAG, "Win " + this + " start dimming.");
+ task.startDimmingIfNeeded(mWinAnimator);
+ }
+ }
+ }
+
private class DeathRecipient implements IBinder.DeathRecipient {
@Override
public void binderDied() {
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index 109e627..a79d2aa 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -27,8 +27,8 @@
import static com.android.server.wm.WindowManagerService.SHOW_LIGHT_TRANSACTIONS;
import static com.android.server.wm.WindowManagerService.SHOW_SURFACE_ALLOC;
import static com.android.server.wm.WindowManagerService.localLOGV;
-import static com.android.server.wm.WindowManagerService.LayoutFields.SET_ORIENTATION_CHANGE_COMPLETE;
-import static com.android.server.wm.WindowManagerService.LayoutFields.SET_TURN_ON_SCREEN;
+import static com.android.server.wm.WindowSurfacePlacer.SET_ORIENTATION_CHANGE_COMPLETE;
+import static com.android.server.wm.WindowSurfacePlacer.SET_TURN_ON_SCREEN;
import android.content.Context;
import android.graphics.Matrix;
@@ -424,8 +424,9 @@
finishExit();
final int displayId = mWin.getDisplayId();
mAnimator.setPendingLayoutChanges(displayId, WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM);
- if (WindowManagerService.DEBUG_LAYOUT_REPEATS) mService.debugLayoutRepeats(
- "WindowStateAnimator", mAnimator.getPendingLayoutChanges(displayId));
+ if (WindowManagerService.DEBUG_LAYOUT_REPEATS)
+ mService.mWindowPlacerLocked.debugLayoutRepeats(
+ "WindowStateAnimator", mAnimator.getPendingLayoutChanges(displayId));
if (mWin.mAppToken != null) {
mWin.mAppToken.updateReportedVisibilityLocked();
@@ -1184,7 +1185,7 @@
+ " screen=" + (screenAnimation ?
screenRotationAnimation.getEnterTransformation().getAlpha() : "null"));
return;
- } else if (mIsWallpaper && mService.mInnerFields.mWallpaperActionPending) {
+ } else if (mIsWallpaper && mService.mWindowPlacerLocked.mWallpaperActionPending) {
return;
}
diff --git a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
new file mode 100644
index 0000000..ce07a9d
--- /dev/null
+++ b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
@@ -0,0 +1,1523 @@
+package com.android.server.wm;
+
+import static android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
+import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
+import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD;
+import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMATION;
+import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
+import static android.view.WindowManager.LayoutParams.TYPE_DREAM;
+import static android.view.WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG;
+import static android.view.WindowManager.LayoutParams.TYPE_PRIVATE_PRESENTATION;
+import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG;
+import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_ERROR;
+import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
+import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM;
+import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_CONFIG;
+import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT;
+import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
+import static com.android.server.wm.WindowManagerService.DEBUG;
+import static com.android.server.wm.WindowManagerService.DEBUG_ADD_REMOVE;
+import static com.android.server.wm.WindowManagerService.DEBUG_APP_TRANSITIONS;
+import static com.android.server.wm.WindowManagerService.DEBUG_LAYOUT;
+import static com.android.server.wm.WindowManagerService.DEBUG_LAYOUT_REPEATS;
+import static com.android.server.wm.WindowManagerService.DEBUG_ORIENTATION;
+import static com.android.server.wm.WindowManagerService.DEBUG_POWER;
+import static com.android.server.wm.WindowManagerService.DEBUG_STARTING_WINDOW;
+import static com.android.server.wm.WindowManagerService.DEBUG_TOKEN_MOVEMENT;
+import static com.android.server.wm.WindowManagerService.DEBUG_VISIBILITY;
+import static com.android.server.wm.WindowManagerService.DEBUG_WALLPAPER_LIGHT;
+import static com.android.server.wm.WindowManagerService.DEBUG_WINDOW_TRACE;
+import static com.android.server.wm.WindowManagerService.H.*;
+import static com.android.server.wm.WindowManagerService.LAYOUT_REPEAT_THRESHOLD;
+import static com.android.server.wm.WindowManagerService.MAX_ANIMATION_DURATION;
+import static com.android.server.wm.WindowManagerService.SHOW_LIGHT_TRANSACTIONS;
+import static com.android.server.wm.WindowManagerService.SHOW_TRANSACTIONS;
+import static com.android.server.wm.WindowManagerService.TAG;
+import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_PLACING_SURFACES;
+import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_WILL_PLACE_SURFACES;
+import static com.android.server.wm.WindowManagerService.WINDOWS_FREEZING_SCREENS_NONE;
+
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.PixelFormat;
+import android.graphics.Rect;
+import android.os.Debug;
+import android.os.PowerManager;
+import android.os.RemoteException;
+import android.os.SystemClock;
+import android.os.Trace;
+import android.provider.Settings;
+import android.util.Log;
+import android.util.Slog;
+import android.view.Display;
+import android.view.DisplayInfo;
+import android.view.Surface;
+import android.view.SurfaceControl;
+import android.view.View;
+import android.view.WindowManager;
+import android.view.animation.Animation;
+import android.view.animation.AnimationUtils;
+
+import java.util.ArrayList;
+
+/**
+ * Positions windows and their surfaces.
+ *
+ * It sets positions of windows by calculating their frames and then applies this by positioning
+ * surfaces according to these frames. Z layer is still assigned withing WindowManagerService.
+ */
+class WindowSurfacePlacer {
+ private final WindowManagerService mService;
+ private final WallpaperController mWallpaperControllerLocked;
+
+ private boolean mInLayout = false;
+
+ /** Only do a maximum of 6 repeated layouts. After that quit */
+ private int mLayoutRepeatCount;
+
+ static final int SET_UPDATE_ROTATION = 1 << 0;
+ static final int SET_WALLPAPER_MAY_CHANGE = 1 << 1;
+ static final int SET_FORCE_HIDING_CHANGED = 1 << 2;
+ static final int SET_ORIENTATION_CHANGE_COMPLETE = 1 << 3;
+ static final int SET_TURN_ON_SCREEN = 1 << 4;
+ static final int SET_WALLPAPER_ACTION_PENDING = 1 << 5;
+
+ boolean mWallpaperMayChange = false;
+ boolean mOrientationChangeComplete = true;
+ boolean mWallpaperActionPending = false;
+
+ private boolean mWallpaperForceHidingChanged = false;
+ private Object mLastWindowFreezeSource = null;
+ private Session mHoldScreen = null;
+ private boolean mObscured = false;
+ private boolean mSyswin = false;
+ private float mScreenBrightness = -1;
+ private float mButtonBrightness = -1;
+ private long mUserActivityTimeout = -1;
+ private boolean mUpdateRotation = false;
+ private final Rect mTmpStartRect = new Rect();
+
+ // Set to true when the display contains content to show the user.
+ // When false, the display manager may choose to mirror or blank the display.
+ private boolean mDisplayHasContent = false;
+
+ // Only set while traversing the default display based on its content.
+ // Affects the behavior of mirroring on secondary displays.
+ private boolean mObscureApplicationContentOnSecondaryDisplays = false;
+
+ private float mPreferredRefreshRate = 0;
+
+ private int mPreferredModeId = 0;
+
+ public WindowSurfacePlacer(WindowManagerService service) {
+ mService = service;
+ mWallpaperControllerLocked = mService.mWallpaperControllerLocked;
+ }
+
+ final void performSurfacePlacement() {
+ int loopCount = 6;
+ do {
+ mService.mTraversalScheduled = false;
+ performSurfacePlacementLoop();
+ mService.mH.removeMessages(DO_TRAVERSAL);
+ loopCount--;
+ } while (mService.mTraversalScheduled && loopCount > 0);
+ mWallpaperActionPending = false;
+ }
+
+ private void performSurfacePlacementLoop() {
+ if (mInLayout) {
+ if (DEBUG) {
+ throw new RuntimeException("Recursive call!");
+ }
+ Slog.w(TAG,
+ "performLayoutAndPlaceSurfacesLocked called while in layout. Callers="
+ + Debug.getCallers(3));
+ return;
+ }
+
+ if (mService.mWaitingForConfig) {
+ // Our configuration has changed (most likely rotation), but we
+ // don't yet have the complete configuration to report to
+ // applications. Don't do any window layout until we have it.
+ return;
+ }
+
+ if (!mService.mDisplayReady) {
+ // Not yet initialized, nothing to do.
+ return;
+ }
+
+ Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "wmLayout");
+ mInLayout = true;
+
+ boolean recoveringMemory = false;
+ if (!mService.mForceRemoves.isEmpty()) {
+ recoveringMemory = true;
+ // Wait a little bit for things to settle down, and off we go.
+ while (!mService.mForceRemoves.isEmpty()) {
+ WindowState ws = mService.mForceRemoves.remove(0);
+ Slog.i(TAG, "Force removing: " + ws);
+ mService.removeWindowInnerLocked(ws);
+ }
+ Slog.w(TAG,
+ "Due to memory failure, waiting a bit for next layout");
+ Object tmp = new Object();
+ synchronized (tmp) {
+ try {
+ tmp.wait(250);
+ } catch (InterruptedException e) {
+ }
+ }
+ }
+
+ try {
+ performSurfacePlacementInner(recoveringMemory);
+
+ mInLayout = false;
+
+ if (mService.needsLayout()) {
+ if (++mLayoutRepeatCount < 6) {
+ mService.requestTraversalLocked();
+ } else {
+ Slog.e(TAG, "Performed 6 layouts in a row. Skipping");
+ mLayoutRepeatCount = 0;
+ }
+ } else {
+ mLayoutRepeatCount = 0;
+ }
+
+ if (mService.mWindowsChanged && !mService.mWindowChangeListeners.isEmpty()) {
+ mService.mH.removeMessages(REPORT_WINDOWS_CHANGE);
+ mService.mH.sendEmptyMessage(REPORT_WINDOWS_CHANGE);
+ }
+ } catch (RuntimeException e) {
+ mInLayout = false;
+ Slog.wtf(TAG, "Unhandled exception while laying out windows", e);
+ }
+
+ Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
+ }
+
+ void debugLayoutRepeats(final String msg, int pendingLayoutChanges) {
+ if (mLayoutRepeatCount >= LAYOUT_REPEAT_THRESHOLD) {
+ Slog.v(TAG, "Layouts looping: " + msg +
+ ", mPendingLayoutChanges = 0x" + Integer.toHexString(pendingLayoutChanges));
+ }
+ }
+
+ // "Something has changed! Let's make it correct now."
+ private void performSurfacePlacementInner(boolean recoveringMemory) {
+ if (DEBUG_WINDOW_TRACE) {
+ Slog.v(TAG,
+ "performSurfacePlacementInner: entry. Called by "
+ + Debug.getCallers(3));
+ }
+
+ int i;
+ boolean updateInputWindowsNeeded = false;
+
+ if (mService.mFocusMayChange) {
+ mService.mFocusMayChange = false;
+ updateInputWindowsNeeded = mService.updateFocusedWindowLocked(
+ UPDATE_FOCUS_WILL_PLACE_SURFACES, false /*updateInputWindows*/);
+ }
+
+ // Initialize state of exiting tokens.
+ final int numDisplays = mService.mDisplayContents.size();
+ for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
+ final DisplayContent displayContent = mService.mDisplayContents.valueAt(displayNdx);
+ for (i=displayContent.mExitingTokens.size()-1; i>=0; i--) {
+ displayContent.mExitingTokens.get(i).hasVisible = false;
+ }
+ }
+
+ for (int stackNdx = mService.mStackIdToStack.size() - 1; stackNdx >= 0; --stackNdx) {
+ // Initialize state of exiting applications.
+ final AppTokenList exitingAppTokens =
+ mService.mStackIdToStack.valueAt(stackNdx).mExitingAppTokens;
+ for (int tokenNdx = exitingAppTokens.size() - 1; tokenNdx >= 0; --tokenNdx) {
+ exitingAppTokens.get(tokenNdx).hasVisible = false;
+ }
+ }
+
+ mHoldScreen = null;
+ mScreenBrightness = -1;
+ mButtonBrightness = -1;
+ mUserActivityTimeout = -1;
+ mObscureApplicationContentOnSecondaryDisplays = false;
+
+ mService.mTransactionSequence++;
+
+ final DisplayContent defaultDisplay = mService.getDefaultDisplayContentLocked();
+ final DisplayInfo defaultInfo = defaultDisplay.getDisplayInfo();
+ final int defaultDw = defaultInfo.logicalWidth;
+ final int defaultDh = defaultInfo.logicalHeight;
+
+ if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
+ ">>> OPEN TRANSACTION performLayoutAndPlaceSurfaces");
+ SurfaceControl.openTransaction();
+ try {
+
+ if (mService.mWatermark != null) {
+ mService.mWatermark.positionSurface(defaultDw, defaultDh);
+ }
+ if (mService.mStrictModeFlash != null) {
+ mService.mStrictModeFlash.positionSurface(defaultDw, defaultDh);
+ }
+ if (mService.mCircularDisplayMask != null) {
+ mService.mCircularDisplayMask.positionSurface(defaultDw, defaultDh,
+ mService.mRotation);
+ }
+ if (mService.mEmulatorDisplayOverlay != null) {
+ mService.mEmulatorDisplayOverlay.positionSurface(defaultDw, defaultDh,
+ mService.mRotation);
+ }
+
+ boolean focusDisplayed = false;
+
+ for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
+ final DisplayContent displayContent = mService.mDisplayContents.valueAt(displayNdx);
+ boolean updateAllDrawn = false;
+ WindowList windows = displayContent.getWindowList();
+ DisplayInfo displayInfo = displayContent.getDisplayInfo();
+ final int displayId = displayContent.getDisplayId();
+ final int dw = displayInfo.logicalWidth;
+ final int dh = displayInfo.logicalHeight;
+ final int innerDw = displayInfo.appWidth;
+ final int innerDh = displayInfo.appHeight;
+ final boolean isDefaultDisplay = (displayId == Display.DEFAULT_DISPLAY);
+
+ // Reset for each display.
+ mDisplayHasContent = false;
+ mPreferredRefreshRate = 0;
+ mPreferredModeId = 0;
+
+ int repeats = 0;
+ do {
+ repeats++;
+ if (repeats > 6) {
+ Slog.w(TAG, "Animation repeat aborted after too many iterations");
+ displayContent.layoutNeeded = false;
+ break;
+ }
+
+ if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats(
+ "On entry to LockedInner", displayContent.pendingLayoutChanges);
+
+ if ((displayContent.pendingLayoutChanges &
+ FINISH_LAYOUT_REDO_WALLPAPER) != 0 &&
+ mWallpaperControllerLocked.adjustWallpaperWindows()) {
+ mService.assignLayersLocked(windows);
+ displayContent.layoutNeeded = true;
+ }
+
+ if (isDefaultDisplay && (displayContent.pendingLayoutChanges
+ & FINISH_LAYOUT_REDO_CONFIG) != 0) {
+ if (DEBUG_LAYOUT) Slog.v(TAG,
+ "Computing new config from layout");
+ if (mService.updateOrientationFromAppTokensLocked(true)) {
+ displayContent.layoutNeeded = true;
+ mService.mH.sendEmptyMessage(
+ SEND_NEW_CONFIGURATION);
+ }
+ }
+
+ if ((displayContent.pendingLayoutChanges
+ & FINISH_LAYOUT_REDO_LAYOUT) != 0) {
+ displayContent.layoutNeeded = true;
+ }
+
+ // FIRST LOOP: Perform a layout, if needed.
+ if (repeats < LAYOUT_REPEAT_THRESHOLD) {
+ performLayoutLockedInner(displayContent, repeats == 1,
+ false /*updateInputWindows*/);
+ } else {
+ Slog.w(TAG, "Layout repeat skipped after too many iterations");
+ }
+
+ // FIRST AND ONE HALF LOOP: Make WindowManagerPolicy think
+ // it is animating.
+ displayContent.pendingLayoutChanges = 0;
+
+ if (isDefaultDisplay) {
+ mService.mPolicy.beginPostLayoutPolicyLw(dw, dh);
+ for (i = windows.size() - 1; i >= 0; i--) {
+ WindowState w = windows.get(i);
+ if (w.mHasSurface) {
+ mService.mPolicy.applyPostLayoutPolicyLw(w, w.mAttrs,
+ w.mAttachedWindow);
+ }
+ }
+ displayContent.pendingLayoutChanges |=
+ mService.mPolicy.finishPostLayoutPolicyLw();
+ if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats(
+ "after finishPostLayoutPolicyLw",
+ displayContent.pendingLayoutChanges);
+ }
+ } while (displayContent.pendingLayoutChanges != 0);
+
+ mObscured = false;
+ mSyswin = false;
+ displayContent.resetDimming();
+
+ // Only used if default window
+ final boolean someoneLosingFocus = !mService.mLosingFocus.isEmpty();
+
+ final int N = windows.size();
+ for (i=N-1; i>=0; i--) {
+ WindowState w = windows.get(i);
+ final Task task = w.getTask();
+ if (task == null && w.getAttrs().type != TYPE_PRIVATE_PRESENTATION) {
+ continue;
+ }
+
+ final boolean obscuredChanged = w.mObscured != mObscured;
+
+ // Update effect.
+ w.mObscured = mObscured;
+ if (!mObscured) {
+ handleNotObscuredLocked(w, innerDw, innerDh);
+ }
+
+ if (task != null && !task.getContinueDimming()) {
+ w.handleFlagDimBehind();
+ }
+
+ if (isDefaultDisplay && obscuredChanged
+ && mWallpaperControllerLocked.isWallpaperTarget(w)
+ && w.isVisibleLw()) {
+ // This is the wallpaper target and its obscured state
+ // changed... make sure the current wallaper's visibility
+ // has been updated accordingly.
+ mWallpaperControllerLocked.updateWallpaperVisibility();
+ }
+
+ final WindowStateAnimator winAnimator = w.mWinAnimator;
+
+ // If the window has moved due to its containing content frame changing, then
+ // notify the listeners and optionally animate it.
+ if (w.hasMoved()) {
+ // Frame has moved, containing content frame has also moved, and we're not
+ // currently animating... let's do something.
+ final int left = w.mFrame.left;
+ final int top = w.mFrame.top;
+ if ((w.mAttrs.privateFlags & PRIVATE_FLAG_NO_MOVE_ANIMATION) == 0) {
+ Animation a = AnimationUtils.loadAnimation(mService.mContext,
+ com.android.internal.R.anim.window_move_from_decor);
+ winAnimator.setAnimation(a);
+ winAnimator.mAnimDw = w.mLastFrame.left - left;
+ winAnimator.mAnimDh = w.mLastFrame.top - top;
+ winAnimator.mAnimateMove = true;
+ winAnimator.mAnimatingMove = true;
+ }
+
+ //TODO (multidisplay): Accessibility supported only for the default display.
+ if (mService.mAccessibilityController != null
+ && displayId == Display.DEFAULT_DISPLAY) {
+ mService.mAccessibilityController.onSomeWindowResizedOrMovedLocked();
+ }
+
+ try {
+ w.mClient.moved(left, top);
+ } catch (RemoteException e) {
+ }
+ }
+
+ //Slog.i(TAG, "Window " + this + " clearing mContentChanged - done placing");
+ w.mContentChanged = false;
+
+ // Moved from updateWindowsAndWallpaperLocked().
+ if (w.mHasSurface) {
+ // Take care of the window being ready to display.
+ final boolean committed =
+ winAnimator.commitFinishDrawingLocked();
+ if (isDefaultDisplay && committed) {
+ if (w.mAttrs.type == TYPE_DREAM) {
+ // HACK: When a dream is shown, it may at that
+ // point hide the lock screen. So we need to
+ // redo the layout to let the phone window manager
+ // make this happen.
+ displayContent.pendingLayoutChanges |=
+ FINISH_LAYOUT_REDO_LAYOUT;
+ if (DEBUG_LAYOUT_REPEATS) {
+ debugLayoutRepeats(
+ "dream and commitFinishDrawingLocked true",
+ displayContent.pendingLayoutChanges);
+ }
+ }
+ if ((w.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0) {
+ if (DEBUG_WALLPAPER_LIGHT)
+ Slog.v(TAG,
+ "First draw done in potential wallpaper target " + w);
+ mWallpaperMayChange = true;
+ displayContent.pendingLayoutChanges |=
+ FINISH_LAYOUT_REDO_WALLPAPER;
+ if (DEBUG_LAYOUT_REPEATS) {
+ debugLayoutRepeats(
+ "wallpaper and commitFinishDrawingLocked true",
+ displayContent.pendingLayoutChanges);
+ }
+ }
+ }
+
+ winAnimator.setSurfaceBoundariesLocked(recoveringMemory);
+ }
+
+ final AppWindowToken atoken = w.mAppToken;
+ if (DEBUG_STARTING_WINDOW && atoken != null
+ && w == atoken.startingWindow) {
+ Slog.d(TAG, "updateWindows: starting " + w
+ + " isOnScreen=" + w.isOnScreen() + " allDrawn=" + atoken.allDrawn
+ + " freezingScreen=" + atoken.mAppAnimator.freezingScreen);
+ }
+ if (atoken != null
+ && (!atoken.allDrawn || atoken.mAppAnimator.freezingScreen)) {
+ if (atoken.lastTransactionSequence != mService.mTransactionSequence) {
+ atoken.lastTransactionSequence = mService.mTransactionSequence;
+ atoken.numInterestingWindows = atoken.numDrawnWindows = 0;
+ atoken.startingDisplayed = false;
+ }
+ if ((w.isOnScreenIgnoringKeyguard()
+ || winAnimator.mAttrType == TYPE_BASE_APPLICATION)
+ && !w.mExiting && !w.mDestroying) {
+ if (DEBUG_VISIBILITY || DEBUG_ORIENTATION) {
+ Slog.v(TAG, "Eval win " + w + ": isDrawn="
+ + w.isDrawnLw()
+ + ", isAnimating=" + winAnimator.isAnimating());
+ if (!w.isDrawnLw()) {
+ Slog.v(TAG, "Not displayed: s="
+ + winAnimator.mSurfaceControl
+ + " pv=" + w.mPolicyVisibility
+ + " mDrawState=" + winAnimator.drawStateToString()
+ + " ah=" + w.mAttachedHidden
+ + " th=" + atoken.hiddenRequested
+ + " a=" + winAnimator.mAnimating);
+ }
+ }
+ if (w != atoken.startingWindow) {
+ if (!atoken.mAppAnimator.freezingScreen || !w.mAppFreezing) {
+ atoken.numInterestingWindows++;
+ if (w.isDrawnLw()) {
+ atoken.numDrawnWindows++;
+ if (DEBUG_VISIBILITY
+ || DEBUG_ORIENTATION)
+ Slog.v(TAG,
+ "tokenMayBeDrawn: " + atoken
+ + " freezingScreen="
+ + atoken.mAppAnimator.freezingScreen
+ + " mAppFreezing=" + w.mAppFreezing);
+ updateAllDrawn = true;
+ }
+ }
+ } else if (w.isDrawnLw()) {
+ atoken.startingDisplayed = true;
+ }
+ }
+ }
+
+ if (isDefaultDisplay && someoneLosingFocus && (w == mService.mCurrentFocus)
+ && w.isDisplayedLw()) {
+ focusDisplayed = true;
+ }
+
+ mService.updateResizingWindows(w);
+ }
+
+ mService.mDisplayManagerInternal.setDisplayProperties(displayId,
+ mDisplayHasContent,
+ mPreferredRefreshRate,
+ mPreferredModeId,
+ true /* inTraversal, must call performTraversalInTrans... below */);
+
+ mService.getDisplayContentLocked(displayId).stopDimmingIfNeeded();
+
+ if (updateAllDrawn) {
+ updateAllDrawnLocked(displayContent);
+ }
+ }
+
+ if (focusDisplayed) {
+ mService.mH.sendEmptyMessage(REPORT_LOSING_FOCUS);
+ }
+
+ // Give the display manager a chance to adjust properties
+ // like display rotation if it needs to.
+ mService.mDisplayManagerInternal.performTraversalInTransactionFromWindowManager();
+
+ } catch (RuntimeException e) {
+ Slog.wtf(TAG, "Unhandled exception in Window Manager", e);
+ } finally {
+ SurfaceControl.closeTransaction();
+ if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
+ "<<< CLOSE TRANSACTION performLayoutAndPlaceSurfaces");
+ }
+
+ final WindowList defaultWindows = defaultDisplay.getWindowList();
+
+ // If we are ready to perform an app transition, check through
+ // all of the app tokens to be shown and see if they are ready
+ // to go.
+ if (mService.mAppTransition.isReady()) {
+ defaultDisplay.pendingLayoutChanges |= handleAppTransitionReadyLocked(defaultWindows);
+ if (DEBUG_LAYOUT_REPEATS)
+ debugLayoutRepeats("after handleAppTransitionReadyLocked",
+ defaultDisplay.pendingLayoutChanges);
+ }
+
+ if (!mService.mAnimator.mAppWindowAnimating && mService.mAppTransition.isRunning()) {
+ // We have finished the animation of an app transition. To do
+ // this, we have delayed a lot of operations like showing and
+ // hiding apps, moving apps in Z-order, etc. The app token list
+ // reflects the correct Z-order, but the window list may now
+ // be out of sync with it. So here we will just rebuild the
+ // entire app window list. Fun!
+ defaultDisplay.pendingLayoutChanges |=
+ mService.handleAnimatingStoppedAndTransitionLocked();
+ if (DEBUG_LAYOUT_REPEATS)
+ debugLayoutRepeats("after handleAnimStopAndXitionLock",
+ defaultDisplay.pendingLayoutChanges);
+ }
+
+ if (mWallpaperForceHidingChanged && defaultDisplay.pendingLayoutChanges == 0
+ && !mService.mAppTransition.isReady()) {
+ // At this point, there was a window with a wallpaper that
+ // was force hiding other windows behind it, but now it
+ // is going away. This may be simple -- just animate
+ // away the wallpaper and its window -- or it may be
+ // hard -- the wallpaper now needs to be shown behind
+ // something that was hidden.
+ defaultDisplay.pendingLayoutChanges |= FINISH_LAYOUT_REDO_LAYOUT;
+ if (DEBUG_LAYOUT_REPEATS)
+ debugLayoutRepeats("after animateAwayWallpaperLocked",
+ defaultDisplay.pendingLayoutChanges);
+ }
+ mWallpaperForceHidingChanged = false;
+
+ if (mWallpaperMayChange) {
+ if (DEBUG_WALLPAPER_LIGHT)
+ Slog.v(TAG, "Wallpaper may change! Adjusting");
+ defaultDisplay.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
+ if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("WallpaperMayChange",
+ defaultDisplay.pendingLayoutChanges);
+ }
+
+ if (mService.mFocusMayChange) {
+ mService.mFocusMayChange = false;
+ if (mService.updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES,
+ false /*updateInputWindows*/)) {
+ updateInputWindowsNeeded = true;
+ defaultDisplay.pendingLayoutChanges |= FINISH_LAYOUT_REDO_ANIM;
+ }
+ }
+
+ if (mService.needsLayout()) {
+ defaultDisplay.pendingLayoutChanges |= FINISH_LAYOUT_REDO_LAYOUT;
+ if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("mLayoutNeeded",
+ defaultDisplay.pendingLayoutChanges);
+ }
+
+ for (i = mService.mResizingWindows.size() - 1; i >= 0; i--) {
+ WindowState win = mService.mResizingWindows.get(i);
+ if (win.mAppFreezing) {
+ // Don't remove this window until rotation has completed.
+ continue;
+ }
+ win.reportResized();
+ mService.mResizingWindows.remove(i);
+ }
+
+ if (DEBUG_ORIENTATION && mService.mDisplayFrozen)
+ Slog.v(TAG,
+ "With display frozen, orientationChangeComplete="
+ + mOrientationChangeComplete);
+ if (mOrientationChangeComplete) {
+ if (mService.mWindowsFreezingScreen != WINDOWS_FREEZING_SCREENS_NONE) {
+ mService.mWindowsFreezingScreen = WINDOWS_FREEZING_SCREENS_NONE;
+ mService.mLastFinishedFreezeSource = mLastWindowFreezeSource;
+ mService.mH.removeMessages(WINDOW_FREEZE_TIMEOUT);
+ }
+ mService.stopFreezingDisplayLocked();
+ }
+
+ // Destroy the surface of any windows that are no longer visible.
+ boolean wallpaperDestroyed = false;
+ i = mService.mDestroySurface.size();
+ if (i > 0) {
+ do {
+ i--;
+ WindowState win = mService.mDestroySurface.get(i);
+ win.mDestroying = false;
+ if (mService.mInputMethodWindow == win) {
+ mService.mInputMethodWindow = null;
+ }
+ if (mWallpaperControllerLocked.isWallpaperTarget(win)) {
+ wallpaperDestroyed = true;
+ }
+ win.mWinAnimator.destroySurfaceLocked();
+ } while (i > 0);
+ mService.mDestroySurface.clear();
+ }
+
+ // Time to remove any exiting tokens?
+ for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
+ final DisplayContent displayContent = mService.mDisplayContents.valueAt(displayNdx);
+ ArrayList<WindowToken> exitingTokens = displayContent.mExitingTokens;
+ for (i = exitingTokens.size() - 1; i >= 0; i--) {
+ WindowToken token = exitingTokens.get(i);
+ if (!token.hasVisible) {
+ exitingTokens.remove(i);
+ if (token.windowType == TYPE_WALLPAPER) {
+ mWallpaperControllerLocked.removeWallpaperToken(token);
+ }
+ }
+ }
+ }
+
+ // Time to remove any exiting applications?
+ for (int stackNdx = mService.mStackIdToStack.size() - 1; stackNdx >= 0; --stackNdx) {
+ // Initialize state of exiting applications.
+ final AppTokenList exitingAppTokens =
+ mService.mStackIdToStack.valueAt(stackNdx).mExitingAppTokens;
+ for (i = exitingAppTokens.size() - 1; i >= 0; i--) {
+ AppWindowToken token = exitingAppTokens.get(i);
+ if (!token.hasVisible && !mService.mClosingApps.contains(token) &&
+ (!token.mIsExiting || token.allAppWindows.isEmpty())) {
+ // Make sure there is no animation running on this token,
+ // so any windows associated with it will be removed as
+ // soon as their animations are complete
+ token.mAppAnimator.clearAnimation();
+ token.mAppAnimator.animating = false;
+ if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT)
+ Slog.v(TAG,
+ "performLayout: App token exiting now removed" + token);
+ token.removeAppFromTaskLocked();
+ }
+ }
+ }
+
+ if (wallpaperDestroyed) {
+ defaultDisplay.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
+ defaultDisplay.layoutNeeded = true;
+ }
+
+ for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
+ final DisplayContent displayContent = mService.mDisplayContents.valueAt(displayNdx);
+ if (displayContent.pendingLayoutChanges != 0) {
+ displayContent.layoutNeeded = true;
+ }
+ }
+
+ // Finally update all input windows now that the window changes have stabilized.
+ mService.mInputMonitor.updateInputWindowsLw(true /*force*/);
+
+ mService.setHoldScreenLocked(mHoldScreen);
+ if (!mService.mDisplayFrozen) {
+ if (mScreenBrightness < 0 || mScreenBrightness > 1.0f) {
+ mService.mPowerManagerInternal.setScreenBrightnessOverrideFromWindowManager(-1);
+ } else {
+ mService.mPowerManagerInternal.setScreenBrightnessOverrideFromWindowManager(
+ toBrightnessOverride(mScreenBrightness));
+ }
+ if (mButtonBrightness < 0
+ || mButtonBrightness > 1.0f) {
+ mService.mPowerManagerInternal.setButtonBrightnessOverrideFromWindowManager(-1);
+ } else {
+ mService.mPowerManagerInternal.setButtonBrightnessOverrideFromWindowManager(
+ toBrightnessOverride(mButtonBrightness));
+ }
+ mService.mPowerManagerInternal.setUserActivityTimeoutOverrideFromWindowManager(
+ mUserActivityTimeout);
+ }
+
+ if (mService.mTurnOnScreen) {
+ if (mService.mAllowTheaterModeWakeFromLayout
+ || Settings.Global.getInt(mService.mContext.getContentResolver(),
+ Settings.Global.THEATER_MODE_ON, 0) == 0) {
+ if (DEBUG_VISIBILITY || DEBUG_POWER) {
+ Slog.v(TAG, "Turning screen on after layout!");
+ }
+ mService.mPowerManager.wakeUp(SystemClock.uptimeMillis(),
+ "android.server.wm:TURN_ON");
+ }
+ mService.mTurnOnScreen = false;
+ }
+
+ if (mUpdateRotation) {
+ if (DEBUG_ORIENTATION) Slog.d(TAG,
+ "Performing post-rotate rotation");
+ if (mService.updateRotationUncheckedLocked(false)) {
+ mService.mH.sendEmptyMessage(SEND_NEW_CONFIGURATION);
+ } else {
+ mUpdateRotation = false;
+ }
+ }
+
+ if (mService.mWaitingForDrawnCallback != null ||
+ (mOrientationChangeComplete && !defaultDisplay.layoutNeeded &&
+ !mUpdateRotation)) {
+ mService.checkDrawnWindowsLocked();
+ }
+
+ final int N = mService.mPendingRemove.size();
+ if (N > 0) {
+ if (mService.mPendingRemoveTmp.length < N) {
+ mService.mPendingRemoveTmp = new WindowState[N+10];
+ }
+ mService.mPendingRemove.toArray(mService.mPendingRemoveTmp);
+ mService.mPendingRemove.clear();
+ DisplayContentList displayList = new DisplayContentList();
+ for (i = 0; i < N; i++) {
+ WindowState w = mService.mPendingRemoveTmp[i];
+ mService.removeWindowInnerLocked(w);
+ final DisplayContent displayContent = w.getDisplayContent();
+ if (displayContent != null && !displayList.contains(displayContent)) {
+ displayList.add(displayContent);
+ }
+ }
+
+ for (DisplayContent displayContent : displayList) {
+ mService.assignLayersLocked(displayContent.getWindowList());
+ displayContent.layoutNeeded = true;
+ }
+ }
+
+ // Remove all deferred displays stacks, tasks, and activities.
+ for (int displayNdx = mService.mDisplayContents.size() - 1; displayNdx >= 0; --displayNdx) {
+ mService.mDisplayContents.valueAt(displayNdx).checkForDeferredActions();
+ }
+
+ if (updateInputWindowsNeeded) {
+ mService.mInputMonitor.updateInputWindowsLw(false /*force*/);
+ }
+ mService.setFocusTaskRegion();
+
+ // Check to see if we are now in a state where the screen should
+ // be enabled, because the window obscured flags have changed.
+ mService.enableScreenIfNeededLocked();
+
+ mService.scheduleAnimationLocked();
+
+ if (DEBUG_WINDOW_TRACE) {
+ Slog.e(TAG,
+ "performSurfacePlacementInner exit: animating="
+ + mService.mAnimator.mAnimating);
+ }
+ }
+
+ boolean isInLayout() {
+ return mInLayout;
+ }
+
+ final void performLayoutLockedInner(final DisplayContent displayContent,
+ boolean initial, boolean updateInputWindows) {
+ if (!displayContent.layoutNeeded) {
+ return;
+ }
+ displayContent.layoutNeeded = false;
+ WindowList windows = displayContent.getWindowList();
+ boolean isDefaultDisplay = displayContent.isDefaultDisplay;
+
+ DisplayInfo displayInfo = displayContent.getDisplayInfo();
+ final int dw = displayInfo.logicalWidth;
+ final int dh = displayInfo.logicalHeight;
+
+ if (mService.mInputConsumer != null) {
+ mService.mInputConsumer.layout(dw, dh);
+ }
+
+ final int N = windows.size();
+ int i;
+
+ if (DEBUG_LAYOUT) {
+ Slog.v(TAG, "-------------------------------------");
+ Slog.v(TAG, "performLayout: needed="
+ + displayContent.layoutNeeded + " dw=" + dw + " dh=" + dh);
+ }
+
+ mService.mPolicy.beginLayoutLw(isDefaultDisplay, dw, dh, mService.mRotation);
+ if (isDefaultDisplay) {
+ // Not needed on non-default displays.
+ mService.mSystemDecorLayer = mService.mPolicy.getSystemDecorLayerLw();
+ mService.mScreenRect.set(0, 0, dw, dh);
+ }
+
+ mService.mPolicy.getContentRectLw(mService.mTmpContentRect);
+ displayContent.resize(mService.mTmpContentRect);
+
+ int seq = mService.mLayoutSeq+1;
+ if (seq < 0) seq = 0;
+ mService.mLayoutSeq = seq;
+
+ boolean behindDream = false;
+
+ // First perform layout of any root windows (not attached
+ // to another window).
+ int topAttached = -1;
+ for (i = N-1; i >= 0; i--) {
+ final WindowState win = windows.get(i);
+
+ // Don't do layout of a window if it is not visible, or
+ // soon won't be visible, to avoid wasting time and funky
+ // changes while a window is animating away.
+ final boolean gone = (behindDream && mService.mPolicy.canBeForceHidden(win, win.mAttrs))
+ || win.isGoneForLayoutLw();
+
+ if (DEBUG_LAYOUT && !win.mLayoutAttached) {
+ Slog.v(TAG, "1ST PASS " + win
+ + ": gone=" + gone + " mHaveFrame=" + win.mHaveFrame
+ + " mLayoutAttached=" + win.mLayoutAttached
+ + " screen changed=" + win.isConfigChanged());
+ final AppWindowToken atoken = win.mAppToken;
+ if (gone) Slog.v(TAG, " GONE: mViewVisibility="
+ + win.mViewVisibility + " mRelayoutCalled="
+ + win.mRelayoutCalled + " hidden="
+ + win.mRootToken.hidden + " hiddenRequested="
+ + (atoken != null && atoken.hiddenRequested)
+ + " mAttachedHidden=" + win.mAttachedHidden);
+ else Slog.v(TAG, " VIS: mViewVisibility="
+ + win.mViewVisibility + " mRelayoutCalled="
+ + win.mRelayoutCalled + " hidden="
+ + win.mRootToken.hidden + " hiddenRequested="
+ + (atoken != null && atoken.hiddenRequested)
+ + " mAttachedHidden=" + win.mAttachedHidden);
+ }
+
+ // If this view is GONE, then skip it -- keep the current
+ // frame, and let the caller know so they can ignore it
+ // if they want. (We do the normal layout for INVISIBLE
+ // windows, since that means "perform layout as normal,
+ // just don't display").
+ if (!gone || !win.mHaveFrame || win.mLayoutNeeded
+ || ((win.isConfigChanged() || win.setInsetsChanged()) &&
+ ((win.mAttrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0 ||
+ (win.mHasSurface && win.mAppToken != null &&
+ win.mAppToken.layoutConfigChanges)))) {
+ if (!win.mLayoutAttached) {
+ if (initial) {
+ //Slog.i(TAG, "Window " + this + " clearing mContentChanged - initial");
+ win.mContentChanged = false;
+ }
+ if (win.mAttrs.type == TYPE_DREAM) {
+ // Don't layout windows behind a dream, so that if it
+ // does stuff like hide the status bar we won't get a
+ // bad transition when it goes away.
+ behindDream = true;
+ }
+ win.mLayoutNeeded = false;
+ win.prelayout();
+ mService.mPolicy.layoutWindowLw(win, null);
+ win.mLayoutSeq = seq;
+ if (DEBUG_LAYOUT) Slog.v(TAG,
+ " LAYOUT: mFrame="
+ + win.mFrame + " mContainingFrame="
+ + win.mContainingFrame + " mDisplayFrame="
+ + win.mDisplayFrame);
+ } else {
+ if (topAttached < 0) topAttached = i;
+ }
+ }
+ }
+
+ boolean attachedBehindDream = false;
+
+ // Now perform layout of attached windows, which usually
+ // depend on the position of the window they are attached to.
+ // XXX does not deal with windows that are attached to windows
+ // that are themselves attached.
+ for (i = topAttached; i >= 0; i--) {
+ final WindowState win = windows.get(i);
+
+ if (win.mLayoutAttached) {
+ if (DEBUG_LAYOUT) Slog.v(TAG,
+ "2ND PASS " + win + " mHaveFrame=" + win.mHaveFrame + " mViewVisibility="
+ + win.mViewVisibility + " mRelayoutCalled=" + win.mRelayoutCalled);
+ // If this view is GONE, then skip it -- keep the current
+ // frame, and let the caller know so they can ignore it
+ // if they want. (We do the normal layout for INVISIBLE
+ // windows, since that means "perform layout as normal,
+ // just don't display").
+ if (attachedBehindDream && mService.mPolicy.canBeForceHidden(win, win.mAttrs)) {
+ continue;
+ }
+ if ((win.mViewVisibility != View.GONE && win.mRelayoutCalled)
+ || !win.mHaveFrame || win.mLayoutNeeded) {
+ if (initial) {
+ //Slog.i(TAG, "Window " + this + " clearing mContentChanged - initial");
+ win.mContentChanged = false;
+ }
+ win.mLayoutNeeded = false;
+ win.prelayout();
+ mService.mPolicy.layoutWindowLw(win, win.mAttachedWindow);
+ win.mLayoutSeq = seq;
+ if (DEBUG_LAYOUT) Slog.v(TAG,
+ " LAYOUT: mFrame=" + win.mFrame + " mContainingFrame="
+ + win.mContainingFrame + " mDisplayFrame=" + win.mDisplayFrame);
+ }
+ } else if (win.mAttrs.type == TYPE_DREAM) {
+ // Don't layout windows behind a dream, so that if it
+ // does stuff like hide the status bar we won't get a
+ // bad transition when it goes away.
+ attachedBehindDream = behindDream;
+ }
+ }
+
+ // Window frames may have changed. Tell the input dispatcher about it.
+ mService.mInputMonitor.setUpdateInputWindowsNeededLw();
+ if (updateInputWindows) {
+ mService.mInputMonitor.updateInputWindowsLw(false /*force*/);
+ }
+
+ mService.mPolicy.finishLayoutLw();
+ }
+
+ /**
+ * @param windows List of windows on default display.
+ * @return bitmap indicating if another pass through layout must be made.
+ */
+ private int handleAppTransitionReadyLocked(WindowList windows) {
+ int appsCount = mService.mOpeningApps.size();
+ if (!transitionGoodToGo(appsCount)) {
+ return 0;
+ }
+ if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "**** GOOD TO GO");
+ int transit = mService.mAppTransition.getAppTransition();
+ if (mService.mSkipAppTransitionAnimation) {
+ transit = AppTransition.TRANSIT_UNSET;
+ }
+ mService.mSkipAppTransitionAnimation = false;
+ mService.mNoAnimationNotifyOnTransitionFinished.clear();
+
+ mService.mH.removeMessages(APP_TRANSITION_TIMEOUT);
+
+ mService.rebuildAppWindowListLocked();
+
+ mWallpaperMayChange = false;
+
+ // The top-most window will supply the layout params,
+ // and we will determine it below.
+ WindowManager.LayoutParams animLp = null;
+ int bestAnimLayer = -1;
+ boolean fullscreenAnim = false;
+ boolean voiceInteraction = false;
+
+ final WindowState lowerWallpaperTarget =
+ mWallpaperControllerLocked.getLowerWallpaperTarget();
+ final WindowState upperWallpaperTarget =
+ mWallpaperControllerLocked.getUpperWallpaperTarget();
+
+ boolean openingAppHasWallpaper = false;
+ boolean closingAppHasWallpaper = false;
+ final AppWindowToken lowerWallpaperAppToken;
+ final AppWindowToken upperWallpaperAppToken;
+ if (lowerWallpaperTarget == null) {
+ lowerWallpaperAppToken = upperWallpaperAppToken = null;
+ } else {
+ lowerWallpaperAppToken = lowerWallpaperTarget.mAppToken;
+ upperWallpaperAppToken = upperWallpaperTarget.mAppToken;
+ }
+
+ int i;
+ // Do a first pass through the tokens for two
+ // things:
+ // (1) Determine if both the closing and opening
+ // app token sets are wallpaper targets, in which
+ // case special animations are needed
+ // (since the wallpaper needs to stay static
+ // behind them).
+ // (2) Find the layout params of the top-most
+ // application window in the tokens, which is
+ // what will control the animation theme.
+ final int closingAppsCount = mService.mClosingApps.size();
+ appsCount = closingAppsCount + mService.mOpeningApps.size();
+ for (i = 0; i < appsCount; i++) {
+ final AppWindowToken wtoken;
+ if (i < closingAppsCount) {
+ wtoken = mService.mClosingApps.valueAt(i);
+ if (wtoken == lowerWallpaperAppToken || wtoken == upperWallpaperAppToken) {
+ closingAppHasWallpaper = true;
+ }
+ } else {
+ wtoken = mService.mOpeningApps.valueAt(i - closingAppsCount);
+ if (wtoken == lowerWallpaperAppToken || wtoken == upperWallpaperAppToken) {
+ openingAppHasWallpaper = true;
+ }
+ }
+
+ voiceInteraction |= wtoken.voiceInteraction;
+
+ if (wtoken.appFullscreen) {
+ WindowState ws = wtoken.findMainWindow();
+ if (ws != null) {
+ animLp = ws.mAttrs;
+ bestAnimLayer = ws.mLayer;
+ fullscreenAnim = true;
+ }
+ } else if (!fullscreenAnim) {
+ WindowState ws = wtoken.findMainWindow();
+ if (ws != null) {
+ if (ws.mLayer > bestAnimLayer) {
+ animLp = ws.mAttrs;
+ bestAnimLayer = ws.mLayer;
+ }
+ }
+ }
+ }
+
+ transit = maybeUpdateTransitToWallpaper(transit, openingAppHasWallpaper,
+ closingAppHasWallpaper, lowerWallpaperTarget, upperWallpaperTarget);
+
+ // If all closing windows are obscured, then there is
+ // no need to do an animation. This is the case, for
+ // example, when this transition is being done behind
+ // the lock screen.
+ if (!mService.mPolicy.allowAppAnimationsLw()) {
+ if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
+ "Animations disallowed by keyguard or dream.");
+ animLp = null;
+ }
+
+ processApplicationsAnimatingInPlace(transit);
+
+ AppWindowToken topClosingApp = null;
+ int topClosingLayer = 0;
+ appsCount = mService.mClosingApps.size();
+ for (i = 0; i < appsCount; i++) {
+ AppWindowToken wtoken = mService.mClosingApps.valueAt(i);
+ final AppWindowAnimator appAnimator = wtoken.mAppAnimator;
+ if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
+ "Now closing app " + wtoken);
+ appAnimator.clearThumbnail();
+ appAnimator.animation = null;
+ wtoken.inPendingTransaction = false;
+ mService.setTokenVisibilityLocked(wtoken, animLp, false, transit, false,
+ voiceInteraction);
+ wtoken.updateReportedVisibilityLocked();
+ // Force the allDrawn flag, because we want to start
+ // this guy's animations regardless of whether it's
+ // gotten drawn.
+ wtoken.allDrawn = true;
+ wtoken.deferClearAllDrawn = false;
+ // Ensure that apps that are mid-starting are also scheduled to have their
+ // starting windows removed after the animation is complete
+ if (wtoken.startingWindow != null && !wtoken.startingWindow.mExiting) {
+ mService.scheduleRemoveStartingWindowLocked(wtoken);
+ }
+ mService.mAnimator.mAppWindowAnimating |= appAnimator.isAnimating();
+
+ if (animLp != null) {
+ int layer = -1;
+ for (int j = 0; j < wtoken.windows.size(); j++) {
+ WindowState win = wtoken.windows.get(j);
+ if (win.mWinAnimator.mAnimLayer > layer) {
+ layer = win.mWinAnimator.mAnimLayer;
+ }
+ }
+ if (topClosingApp == null || layer > topClosingLayer) {
+ topClosingApp = wtoken;
+ topClosingLayer = layer;
+ }
+ }
+ }
+
+ AppWindowToken topOpeningApp = null;
+ appsCount = mService.mOpeningApps.size();
+ for (i = 0; i < appsCount; i++) {
+ AppWindowToken wtoken = mService.mOpeningApps.valueAt(i);
+ final AppWindowAnimator appAnimator = wtoken.mAppAnimator;
+ if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
+ "Now opening app" + wtoken);
+
+ if (!appAnimator.usingTransferredAnimation) {
+ appAnimator.clearThumbnail();
+ appAnimator.animation = null;
+ }
+ wtoken.inPendingTransaction = false;
+ if (!mService.setTokenVisibilityLocked(
+ wtoken, animLp, true, transit, false, voiceInteraction)){
+ // This token isn't going to be animating. Add it to the list of tokens to
+ // be notified of app transition complete since the notification will not be
+ // sent be the app window animator.
+ mService.mNoAnimationNotifyOnTransitionFinished.add(wtoken.token);
+ }
+ wtoken.updateReportedVisibilityLocked();
+ wtoken.waitingToShow = false;
+
+ appAnimator.mAllAppWinAnimators.clear();
+ final int windowsCount = wtoken.allAppWindows.size();
+ for (int j = 0; j < windowsCount; j++) {
+ appAnimator.mAllAppWinAnimators.add(wtoken.allAppWindows.get(j).mWinAnimator);
+ }
+ mService.mAnimator.mAnimating |= appAnimator.showAllWindowsLocked();
+ mService.mAnimator.mAppWindowAnimating |= appAnimator.isAnimating();
+
+ int topOpeningLayer = 0;
+ if (animLp != null) {
+ int layer = -1;
+ for (int j = 0; j < wtoken.windows.size(); j++) {
+ WindowState win = wtoken.windows.get(j);
+ if (win.mWinAnimator.mAnimLayer > layer) {
+ layer = win.mWinAnimator.mAnimLayer;
+ }
+ }
+ if (topOpeningApp == null || layer > topOpeningLayer) {
+ topOpeningApp = wtoken;
+ topOpeningLayer = layer;
+ }
+ }
+ createThumbnailAppAnimator(transit, wtoken, topOpeningLayer, topClosingLayer);
+ }
+
+ AppWindowAnimator openingAppAnimator = (topOpeningApp == null) ? null :
+ topOpeningApp.mAppAnimator;
+ AppWindowAnimator closingAppAnimator = (topClosingApp == null) ? null :
+ topClosingApp.mAppAnimator;
+
+ mService.mAppTransition.goodToGo(openingAppAnimator, closingAppAnimator);
+ mService.mAppTransition.postAnimationCallback();
+ mService.mAppTransition.clear();
+
+ mService.mOpeningApps.clear();
+ mService.mClosingApps.clear();
+
+ // This has changed the visibility of windows, so perform
+ // a new layout to get them all up-to-date.
+ mService.getDefaultDisplayContentLocked().layoutNeeded = true;
+
+ // TODO(multidisplay): IMEs are only supported on the default display.
+ if (windows == mService.getDefaultWindowListLocked()
+ && !mService.moveInputMethodWindowsIfNeededLocked(true)) {
+ mService.assignLayersLocked(windows);
+ }
+ mService.updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES,
+ true /*updateInputWindows*/);
+ mService.mFocusMayChange = false;
+ mService.notifyActivityDrawnForKeyguard();
+ return FINISH_LAYOUT_REDO_LAYOUT
+ | FINISH_LAYOUT_REDO_CONFIG;
+
+ }
+
+ private boolean transitionGoodToGo(int appsCount) {
+ if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
+ "Checking " + appsCount + " opening apps (frozen="
+ + mService.mDisplayFrozen + " timeout="
+ + mService.mAppTransition.isTimeout() + ")...");
+ if (!mService.mAppTransition.isTimeout()) {
+ for (int i = 0; i < appsCount; i++) {
+ AppWindowToken wtoken = mService.mOpeningApps.valueAt(i);
+ if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
+ "Check opening app=" + wtoken + ": allDrawn="
+ + wtoken.allDrawn + " startingDisplayed="
+ + wtoken.startingDisplayed + " startingMoved="
+ + wtoken.startingMoved);
+ if (!wtoken.allDrawn && !wtoken.startingDisplayed && !wtoken.startingMoved) {
+ return false;
+ }
+ }
+
+ // If the wallpaper is visible, we need to check it's ready too.
+ return !mWallpaperControllerLocked.isWallpaperVisible() ||
+ mWallpaperControllerLocked.wallpaperTransitionReady();
+ }
+ return true;
+ }
+
+ private int maybeUpdateTransitToWallpaper(int transit, boolean openingAppHasWallpaper,
+ boolean closingAppHasWallpaper, WindowState lowerWallpaperTarget,
+ WindowState upperWallpaperTarget) {
+ // if wallpaper is animating in or out set oldWallpaper to null else to wallpaper
+ final WindowState wallpaperTarget = mWallpaperControllerLocked.getWallpaperTarget();
+ final WindowState oldWallpaper =
+ mWallpaperControllerLocked.isWallpaperTargetAnimating()
+ ? null : wallpaperTarget;
+ if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
+ "New wallpaper target=" + wallpaperTarget
+ + ", oldWallpaper=" + oldWallpaper
+ + ", lower target=" + lowerWallpaperTarget
+ + ", upper target=" + upperWallpaperTarget);
+ mService.mAnimateWallpaperWithTarget = false;
+ if (closingAppHasWallpaper && openingAppHasWallpaper) {
+ if (DEBUG_APP_TRANSITIONS)
+ Slog.v(TAG, "Wallpaper animation!");
+ switch (transit) {
+ case AppTransition.TRANSIT_ACTIVITY_OPEN:
+ case AppTransition.TRANSIT_TASK_OPEN:
+ case AppTransition.TRANSIT_TASK_TO_FRONT:
+ transit = AppTransition.TRANSIT_WALLPAPER_INTRA_OPEN;
+ break;
+ case AppTransition.TRANSIT_ACTIVITY_CLOSE:
+ case AppTransition.TRANSIT_TASK_CLOSE:
+ case AppTransition.TRANSIT_TASK_TO_BACK:
+ transit = AppTransition.TRANSIT_WALLPAPER_INTRA_CLOSE;
+ break;
+ }
+ if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
+ "New transit: " + AppTransition.appTransitionToString(transit));
+ } else if ((oldWallpaper != null) && !mService.mOpeningApps.isEmpty()
+ && !mService.mOpeningApps.contains(oldWallpaper.mAppToken)) {
+ // We are transitioning from an activity with
+ // a wallpaper to one without.
+ transit = AppTransition.TRANSIT_WALLPAPER_CLOSE;
+ if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
+ "New transit away from wallpaper: "
+ + AppTransition.appTransitionToString(transit));
+ } else if (wallpaperTarget != null && wallpaperTarget.isVisibleLw()) {
+ // We are transitioning from an activity without
+ // a wallpaper to now showing the wallpaper
+ transit = AppTransition.TRANSIT_WALLPAPER_OPEN;
+ if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
+ "New transit into wallpaper: "
+ + AppTransition.appTransitionToString(transit));
+ } else {
+ mService.mAnimateWallpaperWithTarget = true;
+ }
+ return transit;
+ }
+
+ /**
+ * @param w WindowState this method is applied to.
+ * @param innerDw Width of app window.
+ * @param innerDh Height of app window.
+ */
+ private void handleNotObscuredLocked(final WindowState w, final int innerDw, final int innerDh) {
+ final WindowManager.LayoutParams attrs = w.mAttrs;
+ final int attrFlags = attrs.flags;
+ final boolean canBeSeen = w.isDisplayedLw();
+ final boolean opaqueDrawn = canBeSeen && w.isOpaqueDrawn();
+
+ if (opaqueDrawn && w.isFullscreen(innerDw, innerDh)) {
+ // This window completely covers everything behind it,
+ // so we want to leave all of them as undimmed (for
+ // performance reasons).
+ mObscured = true;
+ }
+
+ if (w.mHasSurface) {
+ if ((attrFlags&FLAG_KEEP_SCREEN_ON) != 0) {
+ mHoldScreen = w.mSession;
+ }
+ if (!mSyswin && w.mAttrs.screenBrightness >= 0
+ && mScreenBrightness < 0) {
+ mScreenBrightness = w.mAttrs.screenBrightness;
+ }
+ if (!mSyswin && w.mAttrs.buttonBrightness >= 0
+ && mButtonBrightness < 0) {
+ mButtonBrightness = w.mAttrs.buttonBrightness;
+ }
+ if (!mSyswin && w.mAttrs.userActivityTimeout >= 0
+ && mUserActivityTimeout < 0) {
+ mUserActivityTimeout = w.mAttrs.userActivityTimeout;
+ }
+
+ final int type = attrs.type;
+ if (canBeSeen
+ && (type == TYPE_SYSTEM_DIALOG
+ || type == TYPE_SYSTEM_ERROR
+ || (attrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0)) {
+ mSyswin = true;
+ }
+
+ if (canBeSeen) {
+ // This function assumes that the contents of the default display are
+ // processed first before secondary displays.
+ final DisplayContent displayContent = w.getDisplayContent();
+ if (displayContent != null && displayContent.isDefaultDisplay) {
+ // While a dream or keyguard is showing, obscure ordinary application
+ // content on secondary displays (by forcibly enabling mirroring unless
+ // there is other content we want to show) but still allow opaque
+ // keyguard dialogs to be shown.
+ if (type == TYPE_DREAM || (attrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0) {
+ mObscureApplicationContentOnSecondaryDisplays = true;
+ }
+ mDisplayHasContent = true;
+ } else if (displayContent != null &&
+ (!mObscureApplicationContentOnSecondaryDisplays
+ || (mObscured && type == TYPE_KEYGUARD_DIALOG))) {
+ // Allow full screen keyguard presentation dialogs to be seen.
+ mDisplayHasContent = true;
+ }
+ if (mPreferredRefreshRate == 0
+ && w.mAttrs.preferredRefreshRate != 0) {
+ mPreferredRefreshRate = w.mAttrs.preferredRefreshRate;
+ }
+ if (mPreferredModeId == 0
+ && w.mAttrs.preferredDisplayModeId != 0) {
+ mPreferredModeId = w.mAttrs.preferredDisplayModeId;
+ }
+ }
+ }
+ }
+
+ private void updateAllDrawnLocked(DisplayContent displayContent) {
+ // See if any windows have been drawn, so they (and others
+ // associated with them) can now be shown.
+ ArrayList<TaskStack> stacks = displayContent.getStacks();
+ for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
+ final ArrayList<Task> tasks = stacks.get(stackNdx).getTasks();
+ for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) {
+ final AppTokenList tokens = tasks.get(taskNdx).mAppTokens;
+ for (int tokenNdx = tokens.size() - 1; tokenNdx >= 0; --tokenNdx) {
+ final AppWindowToken wtoken = tokens.get(tokenNdx);
+ if (!wtoken.allDrawn) {
+ int numInteresting = wtoken.numInterestingWindows;
+ if (numInteresting > 0 && wtoken.numDrawnWindows >= numInteresting) {
+ if (DEBUG_VISIBILITY)
+ Slog.v(TAG, "allDrawn: " + wtoken
+ + " interesting=" + numInteresting
+ + " drawn=" + wtoken.numDrawnWindows);
+ wtoken.allDrawn = true;
+ // Force an additional layout pass where WindowStateAnimator#
+ // commitFinishDrawingLocked() will call performShowLocked().
+ displayContent.layoutNeeded = true;
+ mService.mH.obtainMessage(NOTIFY_ACTIVITY_DRAWN,
+ wtoken.token).sendToTarget();
+ }
+ }
+ }
+ }
+ }
+ }
+
+ private static int toBrightnessOverride(float value) {
+ return (int)(value * PowerManager.BRIGHTNESS_ON);
+ }
+
+ private void processApplicationsAnimatingInPlace(int transit) {
+ if (transit == AppTransition.TRANSIT_TASK_IN_PLACE) {
+ // Find the focused window
+ final WindowState win = mService.findFocusedWindowLocked(
+ mService.getDefaultDisplayContentLocked());
+ if (win != null) {
+ final AppWindowToken wtoken = win.mAppToken;
+ final AppWindowAnimator appAnimator = wtoken.mAppAnimator;
+ if (DEBUG_APP_TRANSITIONS)
+ Slog.v(TAG, "Now animating app in place " + wtoken);
+ appAnimator.clearThumbnail();
+ appAnimator.animation = null;
+ mService.updateTokenInPlaceLocked(wtoken, transit);
+ wtoken.updateReportedVisibilityLocked();
+
+ appAnimator.mAllAppWinAnimators.clear();
+ final int N = wtoken.allAppWindows.size();
+ for (int j = 0; j < N; j++) {
+ appAnimator.mAllAppWinAnimators.add(wtoken.allAppWindows.get(j).mWinAnimator);
+ }
+ mService.mAnimator.mAppWindowAnimating |= appAnimator.isAnimating();
+ mService.mAnimator.mAnimating |= appAnimator.showAllWindowsLocked();
+ }
+ }
+ }
+
+ private void createThumbnailAppAnimator(int transit, AppWindowToken appToken,
+ int openingLayer, int closingLayer) {
+ AppWindowAnimator openingAppAnimator = (appToken == null) ? null : appToken.mAppAnimator;
+ if (openingAppAnimator == null || openingAppAnimator.animation == null) {
+ return;
+ }
+ final int taskId = appToken.mTask.mTaskId;
+ Bitmap thumbnailHeader = mService.mAppTransition.getAppTransitionThumbnailHeader(taskId);
+ if (thumbnailHeader == null || thumbnailHeader.getConfig() == Bitmap.Config.ALPHA_8) {
+ return;
+ }
+ // This thumbnail animation is very special, we need to have
+ // an extra surface with the thumbnail included with the animation.
+ Rect dirty = new Rect(0, 0, thumbnailHeader.getWidth(), thumbnailHeader.getHeight());
+ try {
+ // TODO(multi-display): support other displays
+ final DisplayContent displayContent = mService.getDefaultDisplayContentLocked();
+ final Display display = displayContent.getDisplay();
+ final DisplayInfo displayInfo = displayContent.getDisplayInfo();
+
+ // Create a new surface for the thumbnail
+ SurfaceControl surfaceControl = new SurfaceControl(mService.mFxSession,
+ "thumbnail anim", dirty.width(), dirty.height(),
+ PixelFormat.TRANSLUCENT, SurfaceControl.HIDDEN);
+ surfaceControl.setLayerStack(display.getLayerStack());
+ if (SHOW_TRANSACTIONS) {
+ Slog.i(TAG, " THUMBNAIL " + surfaceControl + ": CREATE");
+ }
+
+ // Draw the thumbnail onto the surface
+ Surface drawSurface = new Surface();
+ drawSurface.copyFrom(surfaceControl);
+ Canvas c = drawSurface.lockCanvas(dirty);
+ c.drawBitmap(thumbnailHeader, 0, 0, null);
+ drawSurface.unlockCanvasAndPost(c);
+ drawSurface.release();
+
+ // Get the thumbnail animation
+ Animation anim;
+ if (mService.mAppTransition.isNextThumbnailTransitionAspectScaled()) {
+ // If this is a multi-window scenario, we use the windows frame as
+ // destination of the thumbnail header animation. If this is a full screen
+ // window scenario, we use the whole display as the target.
+ WindowState win = appToken.findMainWindow();
+ Rect appRect = win != null ? win.getContentFrameLw() :
+ new Rect(0, 0, displayInfo.appWidth, displayInfo.appHeight);
+ // For the new aspect-scaled transition, we want it to always show
+ // above the animating opening/closing window, and we want to
+ // synchronize its thumbnail surface with the surface for the
+ // open/close animation (only on the way down)
+ anim = mService.mAppTransition.createThumbnailAspectScaleAnimationLocked(appRect,
+ thumbnailHeader, taskId);
+ Log.d(TAG, "assigning thumbnail force above layer: "
+ + openingLayer + " " + closingLayer);
+ openingAppAnimator.thumbnailForceAboveLayer = Math.max(openingLayer, closingLayer);
+ openingAppAnimator.deferThumbnailDestruction =
+ !mService.mAppTransition.isNextThumbnailTransitionScaleUp();
+ } else {
+ anim = mService.mAppTransition.createThumbnailScaleAnimationLocked(
+ displayInfo.appWidth, displayInfo.appHeight, transit, thumbnailHeader);
+ }
+ anim.restrictDuration(MAX_ANIMATION_DURATION);
+ anim.scaleCurrentDuration(mService.getTransitionAnimationScaleLocked());
+
+ openingAppAnimator.thumbnail = surfaceControl;
+ openingAppAnimator.thumbnailLayer = openingLayer;
+ openingAppAnimator.thumbnailAnimation = anim;
+ mService.mAppTransition.getNextAppTransitionStartRect(taskId, mTmpStartRect);
+ openingAppAnimator.thumbnailX = mTmpStartRect.left;
+ openingAppAnimator.thumbnailY = mTmpStartRect.top;
+ } catch (Surface.OutOfResourcesException e) {
+ Slog.e(TAG, "Can't allocate thumbnail/Canvas surface w="
+ + dirty.width() + " h=" + dirty.height(), e);
+ openingAppAnimator.clearThumbnail();
+ }
+ }
+
+ boolean copyAnimToLayoutParamsLocked() {
+ boolean doRequest = false;
+
+ final int bulkUpdateParams = mService.mAnimator.mBulkUpdateParams;
+ if ((bulkUpdateParams & SET_UPDATE_ROTATION) != 0) {
+ mUpdateRotation = true;
+ doRequest = true;
+ }
+ if ((bulkUpdateParams & SET_WALLPAPER_MAY_CHANGE) != 0) {
+ mWallpaperMayChange = true;
+ doRequest = true;
+ }
+ if ((bulkUpdateParams & SET_FORCE_HIDING_CHANGED) != 0) {
+ mWallpaperForceHidingChanged = true;
+ doRequest = true;
+ }
+ if ((bulkUpdateParams & SET_ORIENTATION_CHANGE_COMPLETE) == 0) {
+ mOrientationChangeComplete = false;
+ } else {
+ mOrientationChangeComplete = true;
+ mLastWindowFreezeSource = mService.mAnimator.mLastWindowFreezeSource;
+ if (mService.mWindowsFreezingScreen != WINDOWS_FREEZING_SCREENS_NONE) {
+ doRequest = true;
+ }
+ }
+ if ((bulkUpdateParams & SET_TURN_ON_SCREEN) != 0) {
+ mService.mTurnOnScreen = true;
+ }
+ if ((bulkUpdateParams & SET_WALLPAPER_ACTION_PENDING) != 0) {
+ mWallpaperActionPending = true;
+ }
+
+ return doRequest;
+ }
+}
diff --git a/services/core/jni/Android.mk b/services/core/jni/Android.mk
index 9556b08..98d8d08 100644
--- a/services/core/jni/Android.mk
+++ b/services/core/jni/Android.mk
@@ -4,9 +4,16 @@
LOCAL_CFLAGS += -Wall -Werror -Wno-unused-parameter
+ifneq ($(ENABLE_CPUSETS),)
+ifneq ($(ENABLE_SCHED_BOOST),)
+LOCAL_CFLAGS += -DUSE_SCHED_BOOST
+endif
+endif
+
LOCAL_SRC_FILES += \
$(LOCAL_REL_DIR)/com_android_server_AlarmManagerService.cpp \
$(LOCAL_REL_DIR)/com_android_server_am_BatteryStatsService.cpp \
+ $(LOCAL_REL_DIR)/com_android_server_am_ActivityManagerService.cpp \
$(LOCAL_REL_DIR)/com_android_server_AssetAtlasService.cpp \
$(LOCAL_REL_DIR)/com_android_server_connectivity_Vpn.cpp \
$(LOCAL_REL_DIR)/com_android_server_ConsumerIrService.cpp \
diff --git a/services/core/jni/com_android_server_am_ActivityManagerService.cpp b/services/core/jni/com_android_server_am_ActivityManagerService.cpp
new file mode 100644
index 0000000..52217b9
--- /dev/null
+++ b/services/core/jni/com_android_server_am_ActivityManagerService.cpp
@@ -0,0 +1,151 @@
+/*
+ * Copyright (C) 2015 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.
+ */
+
+#define LOG_TAG "ActivityManagerService"
+//#define LOG_NDEBUG 0
+
+#include <android_runtime/AndroidRuntime.h>
+#include <jni.h>
+
+#include <ScopedLocalRef.h>
+#include <ScopedPrimitiveArray.h>
+
+#include <cutils/log.h>
+#include <utils/misc.h>
+#include <utils/Log.h>
+
+#include <stdio.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <semaphore.h>
+#include <stddef.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+namespace android
+{
+
+ // migrate from foreground to foreground_boost
+ static jint migrateToBoost(JNIEnv *env, jobject _this)
+ {
+#ifdef USE_SCHED_BOOST
+ // File descriptors open to /dev/cpuset/../tasks, setup by initialize, or -1 on error
+ FILE* fg_cpuset_file = NULL;
+ int boost_cpuset_fd = 0;
+ if (!access("/dev/cpuset/tasks", F_OK)) {
+ fg_cpuset_file = fopen("/dev/cpuset/foreground/tasks", "r+");
+ if (ferror(fg_cpuset_file)) {
+ return 0;
+ }
+ boost_cpuset_fd = open("/dev/cpuset/foreground/boost/tasks", O_WRONLY);
+ if (boost_cpuset_fd < 0) {
+ fclose(fg_cpuset_file);
+ return 0;
+ }
+
+ }
+ if (!fg_cpuset_file || !boost_cpuset_fd) {
+ fclose(fg_cpuset_file);
+ close(boost_cpuset_fd);
+ return 0;
+ }
+ char buf[17];
+ while (fgets(buf, 16, fg_cpuset_file)) {
+ int i = 0;
+ for (; i < 16; i++) {
+ if (buf[i] == '\n') {
+ buf[i] = 0;
+ break;
+ }
+ }
+ if (write(boost_cpuset_fd, buf, i) < 0) {
+ // ignore error
+ }
+ if (feof(fg_cpuset_file))
+ break;
+ }
+ fclose(fg_cpuset_file);
+ close(boost_cpuset_fd);
+#endif
+ return 0;
+ }
+
+ // migrate from foreground_boost to foreground
+ static jint migrateFromBoost(JNIEnv *env, jobject _this)
+ {
+#ifdef USE_SCHED_BOOST
+ // File descriptors open to /dev/cpuset/../tasks, setup by initialize, or -1 on error
+ int fg_cpuset_fd = 0;
+ FILE* boost_cpuset_file = NULL;
+ if (!access("/dev/cpuset/tasks", F_OK)) {
+ boost_cpuset_file = fopen("/dev/cpuset/foreground/boost/tasks", "r+");
+ if (ferror(boost_cpuset_file)) {
+ return 0;
+ }
+ fg_cpuset_fd = open("/dev/cpuset/foreground/tasks", O_WRONLY);
+ if (fg_cpuset_fd < 0) {
+ fclose(boost_cpuset_file);
+ return 0;
+ }
+
+ }
+ if (!boost_cpuset_file || !fg_cpuset_fd) {
+ fclose(boost_cpuset_file);
+ close(fg_cpuset_fd);
+ return 0;
+ }
+ char buf[17];
+ char *curBuf = buf;
+ while (fgets(buf, 16, boost_cpuset_file)) {
+ //ALOGE("Appending FD %s to fg", buf);
+ int i = 0;
+ for (; i < 16; i++) {
+ if (buf[i] == '\n') {
+ buf[i] = 0;
+ break;
+ }
+ }
+ if (write(fg_cpuset_fd, buf, i) < 0) {
+ //ALOGE("Appending FD %s to fg ERROR", buf);
+ // handle error?
+ }
+ if (feof(boost_cpuset_file))
+ break;
+ }
+
+ close(fg_cpuset_fd);
+ fclose(boost_cpuset_file);
+
+#endif
+ return 0;
+
+ }
+
+
+ static JNINativeMethod method_table[] = {
+ { "nativeMigrateToBoost", "()I", (void*)migrateToBoost },
+ { "nativeMigrateFromBoost", "()I", (void*)migrateFromBoost },
+ };
+
+ int register_android_server_ActivityManagerService(JNIEnv *env)
+ {
+ return jniRegisterNativeMethods(env, "com/android/server/am/ActivityManagerService",
+ method_table, NELEM(method_table));
+ }
+
+}
diff --git a/services/core/jni/onload.cpp b/services/core/jni/onload.cpp
index 67872da..1f3fde6 100644
--- a/services/core/jni/onload.cpp
+++ b/services/core/jni/onload.cpp
@@ -20,6 +20,7 @@
#include "utils/misc.h"
namespace android {
+int register_android_server_ActivityManagerService(JNIEnv* env);
int register_android_server_AlarmManagerService(JNIEnv* env);
int register_android_server_AssetAtlasService(JNIEnv* env);
int register_android_server_BatteryStatsService(JNIEnv* env);
@@ -57,6 +58,7 @@
}
ALOG_ASSERT(env, "Could not retrieve the env!");
+ register_android_server_ActivityManagerService(env);
register_android_server_PowerManagerService(env);
register_android_server_SerialService(env);
register_android_server_InputApplicationHandle(env);
@@ -80,5 +82,6 @@
register_android_server_PersistentDataBlockService(env);
register_android_server_Watchdog(env);
+
return JNI_VERSION_1_4;
}
diff --git a/telephony/java/android/telephony/PhoneNumberUtils.java b/telephony/java/android/telephony/PhoneNumberUtils.java
index 273cc93..b430340 100644
--- a/telephony/java/android/telephony/PhoneNumberUtils.java
+++ b/telephony/java/android/telephony/PhoneNumberUtils.java
@@ -1457,10 +1457,15 @@
String result = null;
try {
PhoneNumber pn = util.parseAndKeepRawInput(phoneNumber, defaultCountryIso);
+ /**
+ * Need to reformat any local Korean phone numbers (when the user is in Korea) with
+ * country code to corresponding national format which would replace the leading
+ * +82 with 0.
+ */
if (KOREA_ISO_COUNTRY_CODE.equals(defaultCountryIso) &&
- (pn.getCountryCode() == util.getCountryCodeForRegion(KOREA_ISO_COUNTRY_CODE))) {
- // Format local Korean phone numbers with country code to corresponding national
- // format which would replace the leading +82 with 0.
+ (pn.getCountryCode() == util.getCountryCodeForRegion(KOREA_ISO_COUNTRY_CODE)) &&
+ (pn.getCountryCodeSource() ==
+ PhoneNumber.CountryCodeSource.FROM_NUMBER_WITH_PLUS_SIGN)) {
result = util.format(pn, PhoneNumberUtil.PhoneNumberFormat.NATIONAL);
} else {
result = util.formatInOriginalFormat(pn, defaultCountryIso);
diff --git a/tools/aidl/Android.mk b/tools/aidl/Android.mk
index 542f272..8e6189f 100644
--- a/tools/aidl/Android.mk
+++ b/tools/aidl/Android.mk
@@ -31,7 +31,6 @@
aidl_language_y.y \
generate_java.cpp \
generate_java_binder.cpp \
- generate_java_rpc.cpp \
options.cpp \
search_path.cpp \
@@ -49,15 +48,23 @@
include $(BUILD_HOST_EXECUTABLE)
+# TODO(wiley) Compile these for mac as well after b/22771504
+ifeq ($(HOST_OS),linux)
# Unit tests
include $(CLEAR_VARS)
LOCAL_MODULE := aidl_unittests
LOCAL_CFLAGS := -g -DUNIT_TEST -Wall -Werror
+# Tragically, the code is riddled with unused parameters.
+LOCAL_CLANG_CFLAGS := -Wno-unused-parameter
LOCAL_SRC_FILES := \
options_unittest.cpp \
test_main.cpp \
- tests/test.cpp \
+ tests/end_to_end_tests.cpp \
+ tests/example_interface_test_data.cpp \
+
+LOCAL_SHARED_LIBRARIES := \
+ libchrome-host \
LOCAL_STATIC_LIBRARIES := \
libaidl-common \
@@ -67,5 +74,6 @@
LOCAL_LDLIBS_linux := -lrt
include $(BUILD_HOST_NATIVE_TEST)
+endif # HOST_OS == linux
endif # No TARGET_BUILD_APPS or TARGET_BUILD_PDK
diff --git a/tools/aidl/Type.cpp b/tools/aidl/Type.cpp
index 2267750..d9b8b88 100644
--- a/tools/aidl/Type.cpp
+++ b/tools/aidl/Type.cpp
@@ -28,9 +28,6 @@
Type* MAP_TYPE;
Type* LIST_TYPE;
Type* CLASSLOADER_TYPE;
-Type* RPC_DATA_TYPE;
-Type* RPC_ERROR_TYPE;
-Type* EVENT_FAKE_TYPE;
Expression* NULL_VALUE;
Expression* THIS_VALUE;
@@ -42,7 +39,6 @@
register_base_types()
{
VOID_TYPE = new BasicType("void",
- "XXX", "XXX", "XXX", "XXX", "XXX",
"XXX", "XXX", "XXX", "XXX", "XXX");
NAMES.Add(VOID_TYPE);
@@ -50,37 +46,37 @@
NAMES.Add(BOOLEAN_TYPE);
BYTE_TYPE = new BasicType("byte",
- "writeByte", "readByte", "writeByteArray", "createByteArray", "readByteArray",
- "putByte", "getByte", "putByteArray", "createByteArray", "getByteArray");
+ "writeByte", "readByte", "writeByteArray", "createByteArray",
+ "readByteArray");
NAMES.Add(BYTE_TYPE);
CHAR_TYPE = new CharType();
NAMES.Add(CHAR_TYPE);
INT_TYPE = new BasicType("int",
- "writeInt", "readInt", "writeIntArray", "createIntArray", "readIntArray",
- "putInteger", "getInteger", "putIntegerArray", "createIntegerArray", "getIntegerArray");
+ "writeInt", "readInt", "writeIntArray", "createIntArray",
+ "readIntArray");
NAMES.Add(INT_TYPE);
LONG_TYPE = new BasicType("long",
- "writeLong", "readLong", "writeLongArray", "createLongArray", "readLongArray",
- "putLong", "getLong", "putLongArray", "createLongArray", "getLongArray");
+ "writeLong", "readLong", "writeLongArray", "createLongArray",
+ "readLongArray");
NAMES.Add(LONG_TYPE);
FLOAT_TYPE = new BasicType("float",
- "writeFloat", "readFloat", "writeFloatArray", "createFloatArray", "readFloatArray",
- "putFloat", "getFloat", "putFloatArray", "createFloatArray", "getFloatArray");
+ "writeFloat", "readFloat", "writeFloatArray", "createFloatArray",
+ "readFloatArray");
NAMES.Add(FLOAT_TYPE);
DOUBLE_TYPE = new BasicType("double",
- "writeDouble", "readDouble", "writeDoubleArray", "createDoubleArray", "readDoubleArray",
- "putDouble", "getDouble", "putDoubleArray", "createDoubleArray", "getDoubleArray");
+ "writeDouble", "readDouble", "writeDoubleArray",
+ "createDoubleArray", "readDoubleArray");
NAMES.Add(DOUBLE_TYPE);
STRING_TYPE = new StringType();
NAMES.Add(STRING_TYPE);
- OBJECT_TYPE = new Type("java.lang", "Object", Type::BUILT_IN, false, false, false);
+ OBJECT_TYPE = new Type("java.lang", "Object", Type::BUILT_IN, false, false);
NAMES.Add(OBJECT_TYPE);
CHAR_SEQUENCE_TYPE = new CharSequenceType();
@@ -92,7 +88,7 @@
LIST_TYPE = new ListType();
NAMES.Add(LIST_TYPE);
- TEXT_UTILS_TYPE = new Type("android.text", "TextUtils", Type::BUILT_IN, false, false, false);
+ TEXT_UTILS_TYPE = new Type("android.text", "TextUtils", Type::BUILT_IN, false, false);
NAMES.Add(TEXT_UTILS_TYPE);
REMOTE_EXCEPTION_TYPE = new RemoteExceptionType();
@@ -119,19 +115,9 @@
PARCELABLE_INTERFACE_TYPE = new ParcelableInterfaceType();
NAMES.Add(PARCELABLE_INTERFACE_TYPE);
- CONTEXT_TYPE = new Type("android.content", "Context", Type::BUILT_IN, false, false, false);
+ CONTEXT_TYPE = new Type("android.content", "Context", Type::BUILT_IN, false, false);
NAMES.Add(CONTEXT_TYPE);
- RPC_DATA_TYPE = new RpcDataType();
- NAMES.Add(RPC_DATA_TYPE);
-
- RPC_ERROR_TYPE = new UserDataType("android.support.place.rpc", "RpcError",
- true, __FILE__, __LINE__);
- NAMES.Add(RPC_ERROR_TYPE);
-
- EVENT_FAKE_TYPE = new Type("event", Type::BUILT_IN, false, false, false);
- NAMES.Add(EVENT_FAKE_TYPE);
-
CLASSLOADER_TYPE = new ClassLoaderType();
NAMES.Add(CLASSLOADER_TYPE);
@@ -158,30 +144,27 @@
// ================================================================
-Type::Type(const string& name, int kind, bool canWriteToParcel, bool canWriteToRpcData,
- bool canBeOut)
+Type::Type(const string& name, int kind, bool canWriteToParcel, bool canBeOut)
:m_package(),
m_name(name),
m_declFile(""),
m_declLine(-1),
m_kind(kind),
m_canWriteToParcel(canWriteToParcel),
- m_canWriteToRpcData(canWriteToRpcData),
m_canBeOut(canBeOut)
{
m_qualifiedName = name;
}
Type::Type(const string& package, const string& name,
- int kind, bool canWriteToParcel, bool canWriteToRpcData,
- bool canBeOut, const string& declFile, int declLine)
+ int kind, bool canWriteToParcel, bool canBeOut,
+ const string& declFile, int declLine)
:m_package(package),
m_name(name),
m_declFile(declFile),
m_declLine(declLine),
m_kind(kind),
m_canWriteToParcel(canWriteToParcel),
- m_canWriteToRpcData(canWriteToRpcData),
m_canBeOut(canBeOut)
{
if (package.length() > 0) {
@@ -214,12 +197,6 @@
}
string
-Type::RpcCreatorName() const
-{
- return "";
-}
-
-string
Type::InstantiableName() const
{
return QualifiedName();
@@ -282,26 +259,6 @@
}
void
-Type::WriteToRpcData(StatementBlock* addTo, Expression* k, Variable* v,
- Variable* data, int flags)
-{
- fprintf(stderr, "aidl:internal error %s:%d qualifiedName=%s\n",
- __FILE__, __LINE__, m_qualifiedName.c_str());
- addTo->Add(new LiteralExpression("/* WriteToRpcData error "
- + m_qualifiedName + " */"));
-}
-
-void
-Type::CreateFromRpcData(StatementBlock* addTo, Expression* k, Variable* v, Variable* data,
- Variable** cl)
-{
- fprintf(stderr, "aidl:internal error %s:%d qualifiedName=%s\n",
- __FILE__, __LINE__, m_qualifiedName.c_str());
- addTo->Add(new LiteralExpression("/* ReadFromRpcData error "
- + m_qualifiedName + " */"));
-}
-
-void
Type::SetQualifiedName(const string& qualified)
{
m_qualifiedName = qualified;
@@ -324,20 +281,13 @@
BasicType::BasicType(const string& name, const string& marshallParcel,
const string& unmarshallParcel, const string& writeArrayParcel,
- const string& createArrayParcel, const string& readArrayParcel,
- const string& marshallRpc, const string& unmarshallRpc,
- const string& writeArrayRpc, const string& createArrayRpc, const string& readArrayRpc)
- :Type(name, BUILT_IN, true, true, false),
+ const string& createArrayParcel, const string& readArrayParcel)
+ :Type(name, BUILT_IN, true, false),
m_marshallParcel(marshallParcel),
m_unmarshallParcel(unmarshallParcel),
m_writeArrayParcel(writeArrayParcel),
m_createArrayParcel(createArrayParcel),
- m_readArrayParcel(readArrayParcel),
- m_marshallRpc(marshallRpc),
- m_unmarshallRpc(unmarshallRpc),
- m_writeArrayRpc(writeArrayRpc),
- m_createArrayRpc(createArrayRpc),
- m_readArrayRpc(readArrayRpc)
+ m_readArrayParcel(readArrayParcel)
{
}
@@ -378,24 +328,10 @@
addTo->Add(new MethodCall(parcel, m_readArrayParcel, 1, v));
}
-void
-BasicType::WriteToRpcData(StatementBlock* addTo, Expression* k, Variable* v,
- Variable* data, int flags)
-{
- addTo->Add(new MethodCall(data, m_marshallRpc, 2, k, v));
-}
-
-void
-BasicType::CreateFromRpcData(StatementBlock* addTo, Expression* k, Variable* v, Variable* data,
- Variable** cl)
-{
- addTo->Add(new Assignment(v, new MethodCall(data, m_unmarshallRpc, 1, k)));
-}
-
// ================================================================
BooleanType::BooleanType()
- :Type("boolean", BUILT_IN, true, true, false)
+ :Type("boolean", BUILT_IN, true, false)
{
}
@@ -439,24 +375,10 @@
addTo->Add(new MethodCall(parcel, "readBooleanArray", 1, v));
}
-void
-BooleanType::WriteToRpcData(StatementBlock* addTo, Expression* k, Variable* v,
- Variable* data, int flags)
-{
- addTo->Add(new MethodCall(data, "putBoolean", 2, k, v));
-}
-
-void
-BooleanType::CreateFromRpcData(StatementBlock* addTo, Expression* k, Variable* v, Variable* data,
- Variable** cl)
-{
- addTo->Add(new Assignment(v, new MethodCall(data, "getBoolean", 1, k)));
-}
-
// ================================================================
CharType::CharType()
- :Type("char", BUILT_IN, true, true, false)
+ :Type("char", BUILT_IN, true, false)
{
}
@@ -498,24 +420,10 @@
addTo->Add(new MethodCall(parcel, "readCharArray", 1, v));
}
-void
-CharType::WriteToRpcData(StatementBlock* addTo, Expression* k, Variable* v,
- Variable* data, int flags)
-{
- addTo->Add(new MethodCall(data, "putChar", 2, k, v));
-}
-
-void
-CharType::CreateFromRpcData(StatementBlock* addTo, Expression* k, Variable* v, Variable* data,
- Variable** cl)
-{
- addTo->Add(new Assignment(v, new MethodCall(data, "getChar", 1, k)));
-}
-
// ================================================================
StringType::StringType()
- :Type("java.lang", "String", BUILT_IN, true, true, false)
+ :Type("java.lang", "String", BUILT_IN, true, false)
{
}
@@ -562,24 +470,10 @@
addTo->Add(new MethodCall(parcel, "readStringArray", 1, v));
}
-void
-StringType::WriteToRpcData(StatementBlock* addTo, Expression* k, Variable* v,
- Variable* data, int flags)
-{
- addTo->Add(new MethodCall(data, "putString", 2, k, v));
-}
-
-void
-StringType::CreateFromRpcData(StatementBlock* addTo, Expression* k, Variable* v,
- Variable* data, Variable**)
-{
- addTo->Add(new Assignment(v, new MethodCall(data, "getString", 1, k)));
-}
-
// ================================================================
CharSequenceType::CharSequenceType()
- :Type("java.lang", "CharSequence", BUILT_IN, true, true, false)
+ :Type("java.lang", "CharSequence", BUILT_IN, true, false)
{
}
@@ -639,7 +533,7 @@
// ================================================================
RemoteExceptionType::RemoteExceptionType()
- :Type("android.os", "RemoteException", BUILT_IN, false, false, false)
+ :Type("android.os", "RemoteException", BUILT_IN, false, false)
{
}
@@ -658,7 +552,7 @@
// ================================================================
RuntimeExceptionType::RuntimeExceptionType()
- :Type("java.lang", "RuntimeException", BUILT_IN, false, false, false)
+ :Type("java.lang", "RuntimeException", BUILT_IN, false, false)
{
}
@@ -678,7 +572,7 @@
// ================================================================
IBinderType::IBinderType()
- :Type("android.os", "IBinder", BUILT_IN, true, false, false)
+ :Type("android.os", "IBinder", BUILT_IN, true, false)
{
}
@@ -717,7 +611,7 @@
// ================================================================
IInterfaceType::IInterfaceType()
- :Type("android.os", "IInterface", BUILT_IN, false, false, false)
+ :Type("android.os", "IInterface", BUILT_IN, false, false)
{
}
@@ -737,7 +631,7 @@
// ================================================================
BinderType::BinderType()
- :Type("android.os", "Binder", BUILT_IN, false, false, false)
+ :Type("android.os", "Binder", BUILT_IN, false, false)
{
}
@@ -758,7 +652,7 @@
// ================================================================
BinderProxyType::BinderProxyType()
- :Type("android.os", "BinderProxy", BUILT_IN, false, false, false)
+ :Type("android.os", "BinderProxy", BUILT_IN, false, false)
{
}
@@ -779,7 +673,7 @@
// ================================================================
ParcelType::ParcelType()
- :Type("android.os", "Parcel", BUILT_IN, false, false, false)
+ :Type("android.os", "Parcel", BUILT_IN, false, false)
{
}
@@ -798,7 +692,7 @@
// ================================================================
ParcelableInterfaceType::ParcelableInterfaceType()
- :Type("android.os", "Parcelable", BUILT_IN, false, false, false)
+ :Type("android.os", "Parcelable", BUILT_IN, false, false)
{
}
@@ -817,7 +711,7 @@
// ================================================================
MapType::MapType()
- :Type("java.util", "Map", BUILT_IN, true, false, true)
+ :Type("java.util", "Map", BUILT_IN, true, true)
{
}
@@ -857,7 +751,7 @@
// ================================================================
ListType::ListType()
- :Type("java.util", "List", BUILT_IN, true, true, true)
+ :Type("java.util", "List", BUILT_IN, true, true)
{
}
@@ -888,26 +782,12 @@
addTo->Add(new MethodCall(parcel, "readList", 2, v, *cl));
}
-void
-ListType::WriteToRpcData(StatementBlock* addTo, Expression* k, Variable* v,
- Variable* data, int flags)
-{
- addTo->Add(new MethodCall(data, "putList", 2, k, v));
-}
-
-void
-ListType::CreateFromRpcData(StatementBlock* addTo, Expression* k, Variable* v, Variable* data,
- Variable** cl)
-{
- addTo->Add(new Assignment(v, new MethodCall(data, "getList", 1, k)));
-}
-
// ================================================================
UserDataType::UserDataType(const string& package, const string& name,
- bool builtIn, bool canWriteToParcel, bool canWriteToRpcData,
+ bool builtIn, bool canWriteToParcel,
const string& declFile, int declLine)
- :Type(package, name, builtIn ? BUILT_IN : USERDATA, canWriteToParcel, canWriteToRpcData,
+ :Type(package, name, builtIn ? BUILT_IN : USERDATA, canWriteToParcel,
true, declFile, declLine)
{
}
@@ -918,12 +798,6 @@
return QualifiedName() + ".CREATOR";
}
-string
-UserDataType::RpcCreatorName() const
-{
- return QualifiedName() + ".RPC_CREATOR";
-}
-
void
UserDataType::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags)
{
@@ -1014,29 +888,12 @@
v, new LiteralExpression(creator)));
}
-void
-UserDataType::WriteToRpcData(StatementBlock* addTo, Expression* k, Variable* v,
- Variable* data, int flags)
-{
- // data.putFlattenable(k, v);
- addTo->Add(new MethodCall(data, "putFlattenable", 2, k, v));
-}
-
-void
-UserDataType::CreateFromRpcData(StatementBlock* addTo, Expression* k, Variable* v,
- Variable* data, Variable** cl)
-{
- // data.getFlattenable(k, CLASS.RPC_CREATOR);
- addTo->Add(new Assignment(v, new MethodCall(data, "getFlattenable", 2, k,
- new FieldVariable(v->type, "RPC_CREATOR"))));
-}
-
// ================================================================
InterfaceType::InterfaceType(const string& package, const string& name,
bool builtIn, bool oneway,
const string& declFile, int declLine)
- :Type(package, name, builtIn ? BUILT_IN : INTERFACE, true, false, false,
+ :Type(package, name, builtIn ? BUILT_IN : INTERFACE, true, false,
declFile, declLine)
,m_oneway(oneway)
{
@@ -1075,7 +932,7 @@
GenericType::GenericType(const string& package, const string& name,
const vector<Type*>& args)
- :Type(package, name, BUILT_IN, true, true, true)
+ :Type(package, name, BUILT_IN, true, true)
{
m_args = args;
@@ -1200,65 +1057,11 @@
}
}
-void
-GenericListType::WriteToRpcData(StatementBlock* addTo, Expression* k, Variable* v,
- Variable* data, int flags)
-{
- Type* generic = GenericArgumentTypes()[0];
- if (generic == RPC_DATA_TYPE) {
- addTo->Add(new MethodCall(data, "putRpcDataList", 2, k, v));
- } else if (generic->RpcCreatorName() != "") {
- addTo->Add(new MethodCall(data, "putFlattenableList", 2, k, v));
- } else {
- addTo->Add(new MethodCall(data, "putList", 2, k, v));
- }
-}
-
-void
-GenericListType::CreateFromRpcData(StatementBlock* addTo, Expression* k, Variable* v,
- Variable* data, Variable** cl)
-{
- Type* generic = GenericArgumentTypes()[0];
- if (generic == RPC_DATA_TYPE) {
- addTo->Add(new Assignment(v, new MethodCall(data, "getRpcDataList", 2, k)));
- } else if (generic->RpcCreatorName() != "") {
- addTo->Add(new Assignment(v, new MethodCall(data, "getFlattenableList", 2, k,
- new LiteralExpression(generic->RpcCreatorName()))));
- } else {
- string classArg = GenericArgumentTypes()[0]->QualifiedName();
- classArg += ".class";
- addTo->Add(new Assignment(v, new MethodCall(data, "getList", 2, k,
- new LiteralExpression(classArg))));
- }
-}
-
-
-// ================================================================
-
-RpcDataType::RpcDataType()
- :UserDataType("android.support.place.rpc", "RpcData", true, true, true)
-{
-}
-
-void
-RpcDataType::WriteToRpcData(StatementBlock* addTo, Expression* k, Variable* v,
- Variable* data, int flags)
-{
- addTo->Add(new MethodCall(data, "putRpcData", 2, k, v));
-}
-
-void
-RpcDataType::CreateFromRpcData(StatementBlock* addTo, Expression* k, Variable* v, Variable* data,
- Variable** cl)
-{
- addTo->Add(new Assignment(v, new MethodCall(data, "getRpcData", 1, k)));
-}
-
// ================================================================
ClassLoaderType::ClassLoaderType()
- :Type("java.lang", "ClassLoader", BUILT_IN, false, false, false)
+ :Type("java.lang", "ClassLoader", BUILT_IN, false, false)
{
}
diff --git a/tools/aidl/Type.h b/tools/aidl/Type.h
index d799fca..6ede79a 100644
--- a/tools/aidl/Type.h
+++ b/tools/aidl/Type.h
@@ -24,9 +24,9 @@
};
Type(const string& name, int kind, bool canWriteToParcel,
- bool canWriteToRpcData, bool canBeOut);
+ bool canBeOut);
Type(const string& package, const string& name,
- int kind, bool canWriteToParcel, bool canWriteToRpcData, bool canBeOut,
+ int kind, bool canWriteToParcel, bool canBeOut,
const string& declFile = "", int declLine = -1);
virtual ~Type();
@@ -37,12 +37,10 @@
inline string DeclFile() const { return m_declFile; }
inline int DeclLine() const { return m_declLine; }
inline bool CanWriteToParcel() const { return m_canWriteToParcel; }
- inline bool CanWriteToRpcData() const { return m_canWriteToRpcData; }
inline bool CanBeOutParameter() const { return m_canBeOut; }
virtual string ImportType() const;
virtual string CreatorName() const;
- virtual string RpcCreatorName() const;
virtual string InstantiableName() const;
virtual void WriteToParcel(StatementBlock* addTo, Variable* v,
@@ -61,11 +59,6 @@
virtual void ReadArrayFromParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, Variable** cl);
- virtual void WriteToRpcData(StatementBlock* addTo, Expression* k, Variable* v,
- Variable* data, int flags);
- virtual void CreateFromRpcData(StatementBlock* addTo, Expression* k, Variable* v,
- Variable* data, Variable** cl);
-
protected:
void SetQualifiedName(const string& qualified);
Expression* BuildWriteToParcelFlags(int flags);
@@ -81,7 +74,6 @@
int m_declLine;
int m_kind;
bool m_canWriteToParcel;
- bool m_canWriteToRpcData;
bool m_canBeOut;
};
@@ -93,12 +85,7 @@
const string& unmarshallParcel,
const string& writeArrayParcel,
const string& createArrayParcel,
- const string& readArrayParcel,
- const string& marshallRpc,
- const string& unmarshallRpc,
- const string& writeArrayRpc,
- const string& createArrayRpc,
- const string& readArrayRpc);
+ const string& readArrayParcel);
virtual void WriteToParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, int flags);
@@ -114,22 +101,12 @@
virtual void ReadArrayFromParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, Variable** cl);
- virtual void WriteToRpcData(StatementBlock* addTo, Expression* k, Variable* v,
- Variable* data, int flags);
- virtual void CreateFromRpcData(StatementBlock* addTo, Expression* k, Variable* v,
- Variable* data, Variable** cl);
-
private:
string m_marshallParcel;
string m_unmarshallParcel;
string m_writeArrayParcel;
string m_createArrayParcel;
string m_readArrayParcel;
- string m_marshallRpc;
- string m_unmarshallRpc;
- string m_writeArrayRpc;
- string m_createArrayRpc;
- string m_readArrayRpc;
};
class BooleanType : public Type
@@ -150,11 +127,6 @@
Variable* parcel, Variable** cl);
virtual void ReadArrayFromParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, Variable** cl);
-
- virtual void WriteToRpcData(StatementBlock* addTo, Expression* k, Variable* v,
- Variable* data, int flags);
- virtual void CreateFromRpcData(StatementBlock* addTo, Expression* k, Variable* v,
- Variable* data, Variable** cl);
};
class CharType : public Type
@@ -175,11 +147,6 @@
Variable* parcel, Variable** cl);
virtual void ReadArrayFromParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, Variable** cl);
-
- virtual void WriteToRpcData(StatementBlock* addTo, Expression* k, Variable* v,
- Variable* data, int flags);
- virtual void CreateFromRpcData(StatementBlock* addTo, Expression* k, Variable* v,
- Variable* data, Variable** cl);
};
@@ -203,11 +170,6 @@
Variable* parcel, Variable** cl);
virtual void ReadArrayFromParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, Variable** cl);
-
- virtual void WriteToRpcData(StatementBlock* addTo, Expression* k, Variable* v,
- Variable* data, int flags);
- virtual void CreateFromRpcData(StatementBlock* addTo, Expression* k, Variable* v,
- Variable* data, Variable** cl);
};
class CharSequenceType : public Type
@@ -344,22 +306,16 @@
Variable* parcel, Variable** cl);
virtual void ReadFromParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, Variable** cl);
-
- virtual void WriteToRpcData(StatementBlock* addTo, Expression* k, Variable* v,
- Variable* data, int flags);
- virtual void CreateFromRpcData(StatementBlock* addTo, Expression* k, Variable* v,
- Variable* data, Variable** cl);
};
class UserDataType : public Type
{
public:
UserDataType(const string& package, const string& name,
- bool builtIn, bool canWriteToParcel, bool canWriteToRpcData,
+ bool builtIn, bool canWriteToParcel,
const string& declFile = "", int declLine = -1);
virtual string CreatorName() const;
- virtual string RpcCreatorName() const;
virtual void WriteToParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, int flags);
@@ -376,11 +332,6 @@
Variable* parcel, Variable** cl);
virtual void ReadArrayFromParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, Variable** cl);
-
- virtual void WriteToRpcData(StatementBlock* addTo, Expression* k, Variable* v,
- Variable* data, int flags);
- virtual void CreateFromRpcData(StatementBlock* addTo, Expression* k, Variable* v,
- Variable* data, Variable** cl);
};
class InterfaceType : public Type
@@ -426,17 +377,6 @@
vector<Type*> m_args;
};
-class RpcDataType : public UserDataType
-{
-public:
- RpcDataType();
-
- virtual void WriteToRpcData(StatementBlock* addTo, Expression* k, Variable* v,
- Variable* data, int flags);
- virtual void CreateFromRpcData(StatementBlock* addTo, Expression* k, Variable* v,
- Variable* data, Variable** cl);
-};
-
class ClassLoaderType : public Type
{
public:
@@ -459,11 +399,6 @@
virtual void ReadFromParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, Variable** cl);
- virtual void WriteToRpcData(StatementBlock* addTo, Expression* k, Variable* v,
- Variable* data, int flags);
- virtual void CreateFromRpcData(StatementBlock* addTo, Expression* k, Variable* v,
- Variable* data, Variable** cl);
-
private:
string m_creator;
};
@@ -526,11 +461,6 @@
extern Type* CONTEXT_TYPE;
-extern Type* RPC_DATA_TYPE;
-extern Type* RPC_ERROR_TYPE;
-extern Type* RPC_CONTEXT_TYPE;
-extern Type* EVENT_FAKE_TYPE;
-
extern Expression* NULL_VALUE;
extern Expression* THIS_VALUE;
extern Expression* SUPER_VALUE;
diff --git a/tools/aidl/aidl.cpp b/tools/aidl/aidl.cpp
index a4ecb75..832c51c 100644
--- a/tools/aidl/aidl.cpp
+++ b/tools/aidl/aidl.cpp
@@ -60,12 +60,9 @@
}
else if (d->item_type == USER_DATA_TYPE) {
user_data_type* b = (user_data_type*)d;
- if ((b->flattening_methods & PARCELABLE_DATA) != 0) {
+ if (b->parcelable) {
printf("parcelable %s %s;\n", b->package, b->name.data);
}
- if ((b->flattening_methods & RPC_DATA) != 0) {
- printf("flattenable %s %s;\n", b->package, b->name.data);
- }
}
else {
printf("UNKNOWN d=0x%08lx d->item_type=%d\n", (long)d, d->item_type);
@@ -251,8 +248,7 @@
user_data_type* p = (user_data_type*)items;
err |= check_filename(filename, p->package, &p->name);
}
- else if (items->item_type == INTERFACE_TYPE_BINDER
- || items->item_type == INTERFACE_TYPE_RPC) {
+ else if (items->item_type == INTERFACE_TYPE_BINDER) {
interface_type* c = (interface_type*)items;
err |= check_filename(filename, c->package, &c->name);
}
@@ -303,11 +299,9 @@
if (items->item_type == USER_DATA_TYPE) {
user_data_type* p = (user_data_type*)items;
type = new UserDataType(p->package ? p->package : "", p->name.data,
- false, ((p->flattening_methods & PARCELABLE_DATA) != 0),
- ((p->flattening_methods & RPC_DATA) != 0), filename, p->name.lineno);
+ false, p->parcelable, filename, p->name.lineno);
}
- else if (items->item_type == INTERFACE_TYPE_BINDER
- || items->item_type == INTERFACE_TYPE_RPC) {
+ else if (items->item_type == INTERFACE_TYPE_BINDER) {
interface_type* c = (interface_type*)items;
type = new InterfaceType(c->package ? c->package : "",
c->name.data, false, c->oneway,
@@ -331,30 +325,17 @@
string name = c->name.data;
name += ".Stub";
Type* stub = new Type(c->package ? c->package : "",
- name, Type::GENERATED, false, false, false,
+ name, Type::GENERATED, false, false,
filename, c->name.lineno);
NAMES.Add(stub);
name = c->name.data;
name += ".Stub.Proxy";
Type* proxy = new Type(c->package ? c->package : "",
- name, Type::GENERATED, false, false, false,
+ name, Type::GENERATED, false, false,
filename, c->name.lineno);
NAMES.Add(proxy);
}
- else if (items->item_type == INTERFACE_TYPE_RPC) {
- // for interfaces, also add the service base type, we don't
- // bother checking these for duplicates, because the parser
- // won't let us do it.
- interface_type* c = (interface_type*)items;
-
- string name = c->name.data;
- name += ".ServiceBase";
- Type* base = new Type(c->package ? c->package : "",
- name, Type::GENERATED, false, false, false,
- filename, c->name.lineno);
- NAMES.Add(base);
- }
} else {
if (old->Kind() == Type::BUILT_IN) {
fprintf(stderr, "%s:%d attempt to redefine built in class %s\n",
@@ -406,7 +387,7 @@
}
static int
-check_method(const char* filename, int kind, method_type* m)
+check_method(const char* filename, method_type* m)
{
int err = 0;
@@ -419,19 +400,10 @@
return err;
}
- if (returnType == EVENT_FAKE_TYPE) {
- if (kind != INTERFACE_TYPE_RPC) {
- fprintf(stderr, "%s:%d event methods only supported for rpc interfaces\n",
- filename, m->type.type.lineno);
- err = 1;
- }
- } else {
- if (!(kind == INTERFACE_TYPE_BINDER ? returnType->CanWriteToParcel()
- : returnType->CanWriteToRpcData())) {
- fprintf(stderr, "%s:%d return type %s can't be marshalled.\n", filename,
+ if (!returnType->CanWriteToParcel()) {
+ fprintf(stderr, "%s:%d return type %s can't be marshalled.\n", filename,
m->type.type.lineno, m->type.type.data);
- err = 1;
- }
+ err = 1;
}
if (m->type.dimension > 0 && !returnType->CanBeArray()) {
@@ -464,30 +436,13 @@
goto next;
}
- if (t == EVENT_FAKE_TYPE) {
- fprintf(stderr, "%s:%d parameter %s (%d) event can not be used as a parameter %s\n",
- filename, m->type.type.lineno, arg->name.data, index,
- arg->type.type.data);
- err = 1;
- goto next;
- }
-
- if (!(kind == INTERFACE_TYPE_BINDER ? t->CanWriteToParcel() : t->CanWriteToRpcData())) {
+ if (!t->CanWriteToParcel()) {
fprintf(stderr, "%s:%d parameter %d: '%s %s' can't be marshalled.\n",
filename, m->type.type.lineno, index,
arg->type.type.data, arg->name.data);
err = 1;
}
- if (returnType == EVENT_FAKE_TYPE
- && convert_direction(arg->direction.data) != IN_PARAMETER) {
- fprintf(stderr, "%s:%d parameter %d: '%s %s' All paremeters on events must be 'in'.\n",
- filename, m->type.type.lineno, index,
- arg->type.type.data, arg->name.data);
- err = 1;
- goto next;
- }
-
if (arg->direction.data == NULL
&& (arg->type.dimension != 0 || t->CanBeOutParameter())) {
fprintf(stderr, "%s:%d parameter %d: '%s %s' can be an out"
@@ -549,8 +504,7 @@
int err = 0;
while (items) {
// (nothing to check for USER_DATA_TYPE)
- if (items->item_type == INTERFACE_TYPE_BINDER
- || items->item_type == INTERFACE_TYPE_RPC) {
+ if (items->item_type == INTERFACE_TYPE_BINDER) {
map<string,method_type*> methodNames;
interface_type* c = (interface_type*)items;
@@ -559,7 +513,7 @@
if (member->item_type == METHOD_TYPE) {
method_type* m = (method_type*)member;
- err |= check_method(filename, items->item_type, m);
+ err |= check_method(filename, m);
// prevent duplicate methods
if (methodNames.find(m->name.data) == methodNames.end()) {
@@ -600,9 +554,6 @@
if (next->item_type == INTERFACE_TYPE_BINDER) {
lineno = ((interface_type*)next)->interface_token.lineno;
}
- else if (next->item_type == INTERFACE_TYPE_RPC) {
- lineno = ((interface_type*)next)->interface_token.lineno;
- }
fprintf(stderr, "%s:%d aidl can only handle one interface per file\n",
filename, lineno);
return 1;
@@ -612,9 +563,9 @@
*onlyParcelable = true;
if (options.failOnParcelable) {
fprintf(stderr, "%s:%d aidl can only generate code for interfaces, not"
- " parcelables or flattenables,\n", filename,
+ " parcelables,\n", filename,
((user_data_type*)items)->keyword_token.lineno);
- fprintf(stderr, "%s:%d .aidl files that only declare parcelables or flattenables"
+ fprintf(stderr, "%s:%d .aidl files that only declare parcelables"
"may not go in the Makefile.\n", filename,
((user_data_type*)items)->keyword_token.lineno);
return 1;
@@ -651,7 +602,7 @@
slash = "";
}
- if (items->item_type == INTERFACE_TYPE_BINDER || items->item_type == INTERFACE_TYPE_RPC) {
+ if (items->item_type == INTERFACE_TYPE_BINDER) {
fprintf(to, "%s: \\\n", options.outputFileName.c_str());
} else {
// parcelable: there's no output file.
@@ -725,7 +676,7 @@
generate_outputFileName(const Options& options, const document_item_type* items)
{
// items has already been checked to have only one interface.
- if (items->item_type == INTERFACE_TYPE_BINDER || items->item_type == INTERFACE_TYPE_RPC) {
+ if (items->item_type == INTERFACE_TYPE_BINDER) {
interface_type* type = (interface_type*)items;
return generate_outputFileName2(options, type->name, type->package);
@@ -812,22 +763,7 @@
parcl->name.data = strdup(classname);
parcl->semicolon_token.lineno = lineno;
parcl->semicolon_token.data = strdup(";");
- parcl->flattening_methods = PARCELABLE_DATA;
- doc = (document_item_type*)parcl;
- }
- else if (0 == strcmp("flattenable", type)) {
- user_data_type* parcl = (user_data_type*)malloc(
- sizeof(user_data_type));
- memset(parcl, 0, sizeof(user_data_type));
- parcl->document_item.item_type = USER_DATA_TYPE;
- parcl->keyword_token.lineno = lineno;
- parcl->keyword_token.data = strdup(type);
- parcl->package = packagename ? strdup(packagename) : NULL;
- parcl->name.lineno = lineno;
- parcl->name.data = strdup(classname);
- parcl->semicolon_token.lineno = lineno;
- parcl->semicolon_token.data = strdup(";");
- parcl->flattening_methods = RPC_DATA;
+ parcl->parcelable = true;
doc = (document_item_type*)parcl;
}
else if (0 == strcmp("interface", type)) {
@@ -1081,12 +1017,9 @@
string line;
if (doc->item_type == USER_DATA_TYPE) {
user_data_type* parcelable = (user_data_type*)doc;
- if ((parcelable->flattening_methods & PARCELABLE_DATA) != 0) {
+ if (parcelable->parcelable) {
line = "parcelable ";
}
- if ((parcelable->flattening_methods & RPC_DATA) != 0) {
- line = "flattenable ";
- }
if (parcelable->package) {
line += parcelable->package;
line += '.';
diff --git a/tools/aidl/aidl_language.h b/tools/aidl/aidl_language.h
index 1be5a9b..a3b1efc 100644
--- a/tools/aidl/aidl_language.h
+++ b/tools/aidl/aidl_language.h
@@ -68,8 +68,7 @@
enum {
USER_DATA_TYPE = 12,
- INTERFACE_TYPE_BINDER,
- INTERFACE_TYPE_RPC
+ INTERFACE_TYPE_BINDER
};
typedef struct document_item_type {
@@ -78,19 +77,13 @@
} document_item_type;
-// for user_data_type.flattening_methods
-enum {
- PARCELABLE_DATA = 0x1,
- RPC_DATA = 0x2
-};
-
typedef struct user_data_type {
document_item_type document_item;
buffer_type keyword_token; // only the first one
char* package;
buffer_type name;
buffer_type semicolon_token;
- int flattening_methods;
+ bool parcelable;
} user_data_type;
typedef struct interface_type {
diff --git a/tools/aidl/aidl_language_l.l b/tools/aidl/aidl_language_l.l
index 3d33e7a..aa42f2e 100644
--- a/tools/aidl/aidl_language_l.l
+++ b/tools/aidl/aidl_language_l.l
@@ -83,8 +83,6 @@
/* keywords */
parcelable { SET_BUFFER(PARCELABLE); return PARCELABLE; }
interface { SET_BUFFER(INTERFACE); return INTERFACE; }
-flattenable { SET_BUFFER(FLATTENABLE); return FLATTENABLE; }
-rpc { SET_BUFFER(INTERFACE); return RPC; }
in { SET_BUFFER(IN); return IN; }
out { SET_BUFFER(OUT); return OUT; }
inout { SET_BUFFER(INOUT); return INOUT; }
diff --git a/tools/aidl/aidl_language_y.y b/tools/aidl/aidl_language_y.y
index 9b40d28..9c5d10e 100644
--- a/tools/aidl/aidl_language_y.y
+++ b/tools/aidl/aidl_language_y.y
@@ -20,8 +20,6 @@
%token ARRAY
%token PARCELABLE
%token INTERFACE
-%token FLATTENABLE
-%token RPC
%token IN
%token OUT
%token INOUT
@@ -88,7 +86,7 @@
b->name = $2.buffer;
b->package = g_currentPackage ? strdup(g_currentPackage) : NULL;
b->semicolon_token = $3.buffer;
- b->flattening_methods = PARCELABLE_DATA;
+ b->parcelable = true;
$$.user_data = b;
}
| PARCELABLE ';' {
@@ -101,28 +99,6 @@
g_currentFilename, $2.buffer.lineno, $2.buffer.data);
$$.user_data = NULL;
}
- | FLATTENABLE IDENTIFIER ';' {
- user_data_type* b = (user_data_type*)malloc(sizeof(user_data_type));
- b->document_item.item_type = USER_DATA_TYPE;
- b->document_item.next = NULL;
- b->keyword_token = $1.buffer;
- b->name = $2.buffer;
- b->package = g_currentPackage ? strdup(g_currentPackage) : NULL;
- b->semicolon_token = $3.buffer;
- b->flattening_methods = PARCELABLE_DATA | RPC_DATA;
- $$.user_data = b;
- }
- | FLATTENABLE ';' {
- fprintf(stderr, "%s:%d syntax error in flattenable declaration. Expected type name.\n",
- g_currentFilename, $1.buffer.lineno);
- $$.user_data = NULL;
- }
- | FLATTENABLE error ';' {
- fprintf(stderr, "%s:%d syntax error in flattenable declaration. Expected type name, saw \"%s\".\n",
- g_currentFilename, $2.buffer.lineno, $2.buffer.data);
- $$.user_data = NULL;
- }
-
;
interface_header:
@@ -146,21 +122,6 @@
c->comments_token = &c->oneway_token;
$$.interface_obj = c;
}
- | RPC {
- interface_type* c = (interface_type*)malloc(sizeof(interface_type));
- c->document_item.item_type = INTERFACE_TYPE_RPC;
- c->document_item.next = NULL;
- c->interface_token = $1.buffer;
- c->oneway = false;
- memset(&c->oneway_token, 0, sizeof(buffer_type));
- c->comments_token = &c->interface_token;
- $$.interface_obj = c;
- }
- ;
-
-interface_keywords:
- INTERFACE
- | RPC
;
interface_decl:
@@ -173,12 +134,12 @@
c->close_brace_token = $5.buffer;
$$.interface_obj = c;
}
- | interface_keywords error '{' interface_items '}' {
+ | INTERFACE error '{' interface_items '}' {
fprintf(stderr, "%s:%d: syntax error in interface declaration. Expected type name, saw \"%s\"\n",
g_currentFilename, $2.buffer.lineno, $2.buffer.data);
$$.document_item = NULL;
}
- | interface_keywords error '}' {
+ | INTERFACE error '}' {
fprintf(stderr, "%s:%d: syntax error in interface declaration. Expected type name, saw \"%s\"\n",
g_currentFilename, $2.buffer.lineno, $2.buffer.data);
$$.document_item = NULL;
diff --git a/tools/aidl/generate_java.cpp b/tools/aidl/generate_java.cpp
index 9e57407..1509340 100644
--- a/tools/aidl/generate_java.cpp
+++ b/tools/aidl/generate_java.cpp
@@ -66,9 +66,6 @@
if (iface->document_item.item_type == INTERFACE_TYPE_BINDER) {
cl = generate_binder_interface_class(iface);
}
- else if (iface->document_item.item_type == INTERFACE_TYPE_RPC) {
- cl = generate_rpc_interface_class(iface);
- }
Document* document = new Document;
document->comment = "";
diff --git a/tools/aidl/generate_java.h b/tools/aidl/generate_java.h
index ae7983f..4e79743 100644
--- a/tools/aidl/generate_java.h
+++ b/tools/aidl/generate_java.h
@@ -12,7 +12,6 @@
interface_type* iface);
Class* generate_binder_interface_class(const interface_type* iface);
-Class* generate_rpc_interface_class(const interface_type* iface);
string gather_comments(extra_text_type* extra);
string append(const char* a, const char* b);
diff --git a/tools/aidl/generate_java_rpc.cpp b/tools/aidl/generate_java_rpc.cpp
deleted file mode 100644
index 5e4dacc..0000000
--- a/tools/aidl/generate_java_rpc.cpp
+++ /dev/null
@@ -1,1001 +0,0 @@
-#include "generate_java.h"
-#include "Type.h"
-#include <string.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-Type* SERVICE_CONTEXT_TYPE = new Type("android.content",
- "Context", Type::BUILT_IN, false, false, false);
-Type* PRESENTER_BASE_TYPE = new Type("android.support.place.connector",
- "EventListener", Type::BUILT_IN, false, false, false);
-Type* PRESENTER_LISTENER_BASE_TYPE = new Type("android.support.place.connector",
- "EventListener.Listener", Type::BUILT_IN, false, false, false);
-Type* RPC_BROKER_TYPE = new Type("android.support.place.connector", "Broker",
- Type::BUILT_IN, false, false, false);
-Type* RPC_CONTAINER_TYPE = new Type("com.android.athome.connector", "ConnectorContainer",
- Type::BUILT_IN, false, false, false);
-Type* PLACE_INFO_TYPE = new Type("android.support.place.connector", "PlaceInfo",
- Type::BUILT_IN, false, false, false);
-// TODO: Just use Endpoint, so this works for all endpoints.
-Type* RPC_CONNECTOR_TYPE = new Type("android.support.place.connector", "Connector",
- Type::BUILT_IN, false, false, false);
-Type* RPC_ENDPOINT_INFO_TYPE = new UserDataType("android.support.place.rpc",
- "EndpointInfo", true, __FILE__, __LINE__);
-Type* RPC_RESULT_HANDLER_TYPE = new UserDataType("android.support.place.rpc", "RpcResultHandler",
- true, __FILE__, __LINE__);
-Type* RPC_ERROR_LISTENER_TYPE = new Type("android.support.place.rpc", "RpcErrorHandler",
- Type::BUILT_IN, false, false, false);
-Type* RPC_CONTEXT_TYPE = new UserDataType("android.support.place.rpc", "RpcContext", true,
- __FILE__, __LINE__);
-
-static void generate_create_from_data(Type* t, StatementBlock* addTo, const string& key,
- Variable* v, Variable* data, Variable** cl);
-static void generate_new_array(Type* t, StatementBlock* addTo, Variable* v, Variable* from);
-static void generate_write_to_data(Type* t, StatementBlock* addTo, Expression* k, Variable* v,
- Variable* data);
-
-static string
-format_int(int n)
-{
- char str[20];
- sprintf(str, "%d", n);
- return string(str);
-}
-
-static string
-class_name_leaf(const string& str)
-{
- string::size_type pos = str.rfind('.');
- if (pos == string::npos) {
- return str;
- } else {
- return string(str, pos+1);
- }
-}
-
-static string
-results_class_name(const string& n)
-{
- string str = n;
- str[0] = toupper(str[0]);
- str.insert(0, "On");
- return str;
-}
-
-static string
-results_method_name(const string& n)
-{
- string str = n;
- str[0] = toupper(str[0]);
- str.insert(0, "on");
- return str;
-}
-
-static string
-push_method_name(const string& n)
-{
- string str = n;
- str[0] = toupper(str[0]);
- str.insert(0, "push");
- return str;
-}
-
-// =================================================
-class DispatcherClass : public Class
-{
-public:
- DispatcherClass(const interface_type* iface, Expression* target);
- virtual ~DispatcherClass();
-
- void AddMethod(const method_type* method);
- void DoneWithMethods();
-
- Method* processMethod;
- Variable* actionParam;
- Variable* requestParam;
- Variable* rpcContextParam;
- Variable* errorParam;
- Variable* requestData;
- Variable* resultData;
- IfStatement* dispatchIfStatement;
- Expression* targetExpression;
-
-private:
- void generate_process();
-};
-
-DispatcherClass::DispatcherClass(const interface_type* iface, Expression* target)
- :Class(),
- dispatchIfStatement(NULL),
- targetExpression(target)
-{
- generate_process();
-}
-
-DispatcherClass::~DispatcherClass()
-{
-}
-
-void
-DispatcherClass::generate_process()
-{
- // byte[] process(String action, byte[] params, RpcContext context, RpcError status)
- this->processMethod = new Method;
- this->processMethod->modifiers = PUBLIC;
- this->processMethod->returnType = BYTE_TYPE;
- this->processMethod->returnTypeDimension = 1;
- this->processMethod->name = "process";
- this->processMethod->statements = new StatementBlock;
-
- this->actionParam = new Variable(STRING_TYPE, "action");
- this->processMethod->parameters.push_back(this->actionParam);
-
- this->requestParam = new Variable(BYTE_TYPE, "requestParam", 1);
- this->processMethod->parameters.push_back(this->requestParam);
-
- this->rpcContextParam = new Variable(RPC_CONTEXT_TYPE, "context", 0);
- this->processMethod->parameters.push_back(this->rpcContextParam);
-
- this->errorParam = new Variable(RPC_ERROR_TYPE, "errorParam", 0);
- this->processMethod->parameters.push_back(this->errorParam);
-
- this->requestData = new Variable(RPC_DATA_TYPE, "request");
- this->processMethod->statements->Add(new VariableDeclaration(requestData,
- new NewExpression(RPC_DATA_TYPE, 1, this->requestParam)));
-
- this->resultData = new Variable(RPC_DATA_TYPE, "resultData");
- this->processMethod->statements->Add(new VariableDeclaration(this->resultData,
- NULL_VALUE));
-}
-
-void
-DispatcherClass::AddMethod(const method_type* method)
-{
- arg_type* arg;
-
- // The if/switch statement
- IfStatement* ifs = new IfStatement();
- ifs->expression = new MethodCall(new StringLiteralExpression(method->name.data), "equals",
- 1, this->actionParam);
- StatementBlock* block = ifs->statements = new StatementBlock;
- if (this->dispatchIfStatement == NULL) {
- this->dispatchIfStatement = ifs;
- this->processMethod->statements->Add(dispatchIfStatement);
- } else {
- this->dispatchIfStatement->elseif = ifs;
- this->dispatchIfStatement = ifs;
- }
-
- // The call to decl (from above)
- MethodCall* realCall = new MethodCall(this->targetExpression, method->name.data);
-
- // args
- Variable* classLoader = NULL;
- VariableFactory stubArgs("_arg");
- arg = method->args;
- while (arg != NULL) {
- Type* t = NAMES.Search(arg->type.type.data);
- Variable* v = stubArgs.Get(t);
- v->dimension = arg->type.dimension;
-
- // Unmarshall the parameter
- block->Add(new VariableDeclaration(v));
- if (convert_direction(arg->direction.data) & IN_PARAMETER) {
- generate_create_from_data(t, block, arg->name.data, v,
- this->requestData, &classLoader);
- } else {
- if (arg->type.dimension == 0) {
- block->Add(new Assignment(v, new NewExpression(v->type)));
- }
- else if (arg->type.dimension == 1) {
- generate_new_array(v->type, block, v, this->requestData);
- }
- else {
- fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__,
- __LINE__);
- }
- }
-
- // Add that parameter to the method call
- realCall->arguments.push_back(v);
-
- arg = arg->next;
- }
-
- // Add a final parameter: RpcContext. Contains data about
- // incoming request (e.g., certificate)
- realCall->arguments.push_back(new Variable(RPC_CONTEXT_TYPE, "context", 0));
-
- Type* returnType = NAMES.Search(method->type.type.data);
- if (returnType == EVENT_FAKE_TYPE) {
- returnType = VOID_TYPE;
- }
-
- // the real call
- bool first = true;
- Variable* _result = NULL;
- if (returnType == VOID_TYPE) {
- block->Add(realCall);
- } else {
- _result = new Variable(returnType, "_result",
- method->type.dimension);
- block->Add(new VariableDeclaration(_result, realCall));
-
- // need the result RpcData
- if (first) {
- block->Add(new Assignment(this->resultData,
- new NewExpression(RPC_DATA_TYPE)));
- first = false;
- }
-
- // marshall the return value
- generate_write_to_data(returnType, block,
- new StringLiteralExpression("_result"), _result, this->resultData);
- }
-
- // out parameters
- int i = 0;
- arg = method->args;
- while (arg != NULL) {
- Type* t = NAMES.Search(arg->type.type.data);
- Variable* v = stubArgs.Get(i++);
-
- if (convert_direction(arg->direction.data) & OUT_PARAMETER) {
- // need the result RpcData
- if (first) {
- block->Add(new Assignment(this->resultData, new NewExpression(RPC_DATA_TYPE)));
- first = false;
- }
-
- generate_write_to_data(t, block, new StringLiteralExpression(arg->name.data),
- v, this->resultData);
- }
-
- arg = arg->next;
- }
-}
-
-void
-DispatcherClass::DoneWithMethods()
-{
- if (this->dispatchIfStatement == NULL) {
- return;
- }
-
- this->elements.push_back(this->processMethod);
-
- IfStatement* fallthrough = new IfStatement();
- fallthrough->statements = new StatementBlock;
- fallthrough->statements->Add(new ReturnStatement(
- new MethodCall(SUPER_VALUE, "process", 4,
- this->actionParam, this->requestParam,
- this->rpcContextParam,
- this->errorParam)));
- this->dispatchIfStatement->elseif = fallthrough;
- IfStatement* s = new IfStatement;
- s->statements = new StatementBlock;
- this->processMethod->statements->Add(s);
- s->expression = new Comparison(this->resultData, "!=", NULL_VALUE);
- s->statements->Add(new ReturnStatement(new MethodCall(this->resultData, "serialize")));
- s->elseif = new IfStatement;
- s = s->elseif;
- s->statements->Add(new ReturnStatement(NULL_VALUE));
-}
-
-// =================================================
-class RpcProxyClass : public Class
-{
-public:
- RpcProxyClass(const interface_type* iface, InterfaceType* interfaceType);
- virtual ~RpcProxyClass();
-
- Variable* endpoint;
- Variable* broker;
-
-private:
- void generate_ctor();
- void generate_get_endpoint_info();
-};
-
-RpcProxyClass::RpcProxyClass(const interface_type* iface, InterfaceType* interfaceType)
- :Class()
-{
- this->comment = gather_comments(iface->comments_token->extra);
- this->modifiers = PUBLIC;
- this->what = Class::CLASS;
- this->type = interfaceType;
-
- // broker
- this->broker = new Variable(RPC_BROKER_TYPE, "_broker");
- this->elements.push_back(new Field(PRIVATE, this->broker));
- // endpoint
- this->endpoint = new Variable(RPC_ENDPOINT_INFO_TYPE, "_endpoint");
- this->elements.push_back(new Field(PRIVATE, this->endpoint));
-
- // methods
- generate_ctor();
- generate_get_endpoint_info();
-}
-
-RpcProxyClass::~RpcProxyClass()
-{
-}
-
-void
-RpcProxyClass::generate_ctor()
-{
- Variable* broker = new Variable(RPC_BROKER_TYPE, "broker");
- Variable* endpoint = new Variable(RPC_ENDPOINT_INFO_TYPE, "endpoint");
- Method* ctor = new Method;
- ctor->modifiers = PUBLIC;
- ctor->name = class_name_leaf(this->type->Name());
- ctor->statements = new StatementBlock;
- ctor->parameters.push_back(broker);
- ctor->parameters.push_back(endpoint);
- this->elements.push_back(ctor);
-
- ctor->statements->Add(new Assignment(this->broker, broker));
- ctor->statements->Add(new Assignment(this->endpoint, endpoint));
-}
-
-void
-RpcProxyClass::generate_get_endpoint_info()
-{
- Method* get = new Method;
- get->modifiers = PUBLIC;
- get->returnType = RPC_ENDPOINT_INFO_TYPE;
- get->name = "getEndpointInfo";
- get->statements = new StatementBlock;
- this->elements.push_back(get);
-
- get->statements->Add(new ReturnStatement(this->endpoint));
-}
-
-// =================================================
-class EventListenerClass : public DispatcherClass
-{
-public:
- EventListenerClass(const interface_type* iface, Type* listenerType);
- virtual ~EventListenerClass();
-
- Variable* _listener;
-
-private:
- void generate_ctor();
-};
-
-Expression*
-generate_get_listener_expression(Type* cast)
-{
- return new Cast(cast, new MethodCall(THIS_VALUE, "getView"));
-}
-
-EventListenerClass::EventListenerClass(const interface_type* iface, Type* listenerType)
- :DispatcherClass(iface, new FieldVariable(THIS_VALUE, "_listener"))
-{
- this->modifiers = PRIVATE;
- this->what = Class::CLASS;
- this->type = new Type(iface->package ? iface->package : "",
- append(iface->name.data, ".Presenter"),
- Type::GENERATED, false, false, false);
- this->extends = PRESENTER_BASE_TYPE;
-
- this->_listener = new Variable(listenerType, "_listener");
- this->elements.push_back(new Field(PRIVATE, this->_listener));
-
- // methods
- generate_ctor();
-}
-
-EventListenerClass::~EventListenerClass()
-{
-}
-
-void
-EventListenerClass::generate_ctor()
-{
- Variable* broker = new Variable(RPC_BROKER_TYPE, "broker");
- Variable* listener = new Variable(this->_listener->type, "listener");
- Method* ctor = new Method;
- ctor->modifiers = PUBLIC;
- ctor->name = class_name_leaf(this->type->Name());
- ctor->statements = new StatementBlock;
- ctor->parameters.push_back(broker);
- ctor->parameters.push_back(listener);
- this->elements.push_back(ctor);
-
- ctor->statements->Add(new MethodCall("super", 2, broker, listener));
- ctor->statements->Add(new Assignment(this->_listener, listener));
-}
-
-// =================================================
-class ListenerClass : public Class
-{
-public:
- ListenerClass(const interface_type* iface);
- virtual ~ListenerClass();
-
- bool needed;
-
-private:
- void generate_ctor();
-};
-
-ListenerClass::ListenerClass(const interface_type* iface)
- :Class(),
- needed(false)
-{
- this->comment = "/** Extend this to listen to the events from this class. */";
- this->modifiers = STATIC | PUBLIC ;
- this->what = Class::CLASS;
- this->type = new Type(iface->package ? iface->package : "",
- append(iface->name.data, ".Listener"),
- Type::GENERATED, false, false, false);
- this->extends = PRESENTER_LISTENER_BASE_TYPE;
-}
-
-ListenerClass::~ListenerClass()
-{
-}
-
-// =================================================
-class EndpointBaseClass : public DispatcherClass
-{
-public:
- EndpointBaseClass(const interface_type* iface);
- virtual ~EndpointBaseClass();
-
- bool needed;
-
-private:
- void generate_ctor();
-};
-
-EndpointBaseClass::EndpointBaseClass(const interface_type* iface)
- :DispatcherClass(iface, THIS_VALUE),
- needed(false)
-{
- this->comment = "/** Extend this to implement a link service. */";
- this->modifiers = STATIC | PUBLIC | ABSTRACT;
- this->what = Class::CLASS;
- this->type = new Type(iface->package ? iface->package : "",
- append(iface->name.data, ".EndpointBase"),
- Type::GENERATED, false, false, false);
- this->extends = RPC_CONNECTOR_TYPE;
-
- // methods
- generate_ctor();
-}
-
-EndpointBaseClass::~EndpointBaseClass()
-{
-}
-
-void
-EndpointBaseClass::generate_ctor()
-{
- Variable* container = new Variable(RPC_CONTAINER_TYPE, "container");
- Variable* broker = new Variable(RPC_BROKER_TYPE, "broker");
- Variable* place = new Variable(PLACE_INFO_TYPE, "placeInfo");
- Method* ctor = new Method;
- ctor->modifiers = PUBLIC;
- ctor->name = class_name_leaf(this->type->Name());
- ctor->statements = new StatementBlock;
- ctor->parameters.push_back(container);
- ctor->parameters.push_back(broker);
- ctor->parameters.push_back(place);
- this->elements.push_back(ctor);
-
- ctor->statements->Add(new MethodCall("super", 3, container, broker, place));
-}
-
-// =================================================
-class ResultDispatcherClass : public Class
-{
-public:
- ResultDispatcherClass();
- virtual ~ResultDispatcherClass();
-
- void AddMethod(int index, const string& name, Method** method, Variable** param);
-
- bool needed;
- Variable* methodId;
- Variable* callback;
- Method* onResultMethod;
- Variable* resultParam;
- SwitchStatement* methodSwitch;
-
-private:
- void generate_ctor();
- void generate_onResult();
-};
-
-ResultDispatcherClass::ResultDispatcherClass()
- :Class(),
- needed(false)
-{
- this->modifiers = PRIVATE | FINAL;
- this->what = Class::CLASS;
- this->type = new Type("_ResultDispatcher", Type::GENERATED, false, false, false);
- this->interfaces.push_back(RPC_RESULT_HANDLER_TYPE);
-
- // methodId
- this->methodId = new Variable(INT_TYPE, "methodId");
- this->elements.push_back(new Field(PRIVATE, this->methodId));
- this->callback = new Variable(OBJECT_TYPE, "callback");
- this->elements.push_back(new Field(PRIVATE, this->callback));
-
- // methods
- generate_ctor();
- generate_onResult();
-}
-
-ResultDispatcherClass::~ResultDispatcherClass()
-{
-}
-
-void
-ResultDispatcherClass::generate_ctor()
-{
- Variable* methodIdParam = new Variable(INT_TYPE, "methId");
- Variable* callbackParam = new Variable(OBJECT_TYPE, "cbObj");
- Method* ctor = new Method;
- ctor->modifiers = PUBLIC;
- ctor->name = class_name_leaf(this->type->Name());
- ctor->statements = new StatementBlock;
- ctor->parameters.push_back(methodIdParam);
- ctor->parameters.push_back(callbackParam);
- this->elements.push_back(ctor);
-
- ctor->statements->Add(new Assignment(this->methodId, methodIdParam));
- ctor->statements->Add(new Assignment(this->callback, callbackParam));
-}
-
-void
-ResultDispatcherClass::generate_onResult()
-{
- this->onResultMethod = new Method;
- this->onResultMethod->modifiers = PUBLIC;
- this->onResultMethod->returnType = VOID_TYPE;
- this->onResultMethod->returnTypeDimension = 0;
- this->onResultMethod->name = "onResult";
- this->onResultMethod->statements = new StatementBlock;
- this->elements.push_back(this->onResultMethod);
-
- this->resultParam = new Variable(BYTE_TYPE, "result", 1);
- this->onResultMethod->parameters.push_back(this->resultParam);
-
- this->methodSwitch = new SwitchStatement(this->methodId);
- this->onResultMethod->statements->Add(this->methodSwitch);
-}
-
-void
-ResultDispatcherClass::AddMethod(int index, const string& name, Method** method, Variable** param)
-{
- Method* m = new Method;
- m->modifiers = PUBLIC;
- m->returnType = VOID_TYPE;
- m->returnTypeDimension = 0;
- m->name = name;
- m->statements = new StatementBlock;
- *param = new Variable(BYTE_TYPE, "result", 1);
- m->parameters.push_back(*param);
- this->elements.push_back(m);
- *method = m;
-
- Case* c = new Case(format_int(index));
- c->statements->Add(new MethodCall(new LiteralExpression("this"), name, 1, this->resultParam));
- c->statements->Add(new Break());
-
- this->methodSwitch->cases.push_back(c);
-}
-
-// =================================================
-static void
-generate_new_array(Type* t, StatementBlock* addTo, Variable* v, Variable* from)
-{
- fprintf(stderr, "aidl: implement generate_new_array %s:%d\n", __FILE__, __LINE__);
- exit(1);
-}
-
-static void
-generate_create_from_data(Type* t, StatementBlock* addTo, const string& key, Variable* v,
- Variable* data, Variable** cl)
-{
- Expression* k = new StringLiteralExpression(key);
- if (v->dimension == 0) {
- t->CreateFromRpcData(addTo, k, v, data, cl);
- }
- if (v->dimension == 1) {
- //t->ReadArrayFromRpcData(addTo, v, data, cl);
- fprintf(stderr, "aidl: implement generate_create_from_data for arrays%s:%d\n",
- __FILE__, __LINE__);
- }
-}
-
-static void
-generate_write_to_data(Type* t, StatementBlock* addTo, Expression* k, Variable* v, Variable* data)
-{
- if (v->dimension == 0) {
- t->WriteToRpcData(addTo, k, v, data, 0);
- }
- if (v->dimension == 1) {
- //t->WriteArrayToParcel(addTo, v, data);
- fprintf(stderr, "aidl: implement generate_write_to_data for arrays%s:%d\n",
- __FILE__, __LINE__);
- }
-}
-
-// =================================================
-static Type*
-generate_results_method(const method_type* method, RpcProxyClass* proxyClass)
-{
- arg_type* arg;
-
- string resultsMethodName = results_method_name(method->name.data);
- Type* resultsInterfaceType = new Type(results_class_name(method->name.data),
- Type::GENERATED, false, false, false);
-
- if (!method->oneway) {
- Class* resultsClass = new Class;
- resultsClass->modifiers = STATIC | PUBLIC;
- resultsClass->what = Class::INTERFACE;
- resultsClass->type = resultsInterfaceType;
-
- Method* resultMethod = new Method;
- resultMethod->comment = gather_comments(method->comments_token->extra);
- resultMethod->modifiers = PUBLIC;
- resultMethod->returnType = VOID_TYPE;
- resultMethod->returnTypeDimension = 0;
- resultMethod->name = resultsMethodName;
- if (0 != strcmp("void", method->type.type.data)) {
- resultMethod->parameters.push_back(new Variable(NAMES.Search(method->type.type.data),
- "_result", method->type.dimension));
- }
- arg = method->args;
- while (arg != NULL) {
- if (convert_direction(arg->direction.data) & OUT_PARAMETER) {
- resultMethod->parameters.push_back(new Variable(
- NAMES.Search(arg->type.type.data), arg->name.data,
- arg->type.dimension));
- }
- arg = arg->next;
- }
- resultsClass->elements.push_back(resultMethod);
-
- if (resultMethod->parameters.size() > 0) {
- proxyClass->elements.push_back(resultsClass);
- return resultsInterfaceType;
- }
- }
- //delete resultsInterfaceType;
- return NULL;
-}
-
-static void
-generate_proxy_method(const method_type* method, RpcProxyClass* proxyClass,
- ResultDispatcherClass* resultsDispatcherClass, Type* resultsInterfaceType, int index)
-{
- arg_type* arg;
- Method* proxyMethod = new Method;
- proxyMethod->comment = gather_comments(method->comments_token->extra);
- proxyMethod->modifiers = PUBLIC;
- proxyMethod->returnType = VOID_TYPE;
- proxyMethod->returnTypeDimension = 0;
- proxyMethod->name = method->name.data;
- proxyMethod->statements = new StatementBlock;
- proxyClass->elements.push_back(proxyMethod);
-
- // The local variables
- Variable* _data = new Variable(RPC_DATA_TYPE, "_data");
- proxyMethod->statements->Add(new VariableDeclaration(_data, new NewExpression(RPC_DATA_TYPE)));
-
- // Add the arguments
- arg = method->args;
- while (arg != NULL) {
- if (convert_direction(arg->direction.data) & IN_PARAMETER) {
- // Function signature
- Type* t = NAMES.Search(arg->type.type.data);
- Variable* v = new Variable(t, arg->name.data, arg->type.dimension);
- proxyMethod->parameters.push_back(v);
-
- // Input parameter marshalling
- generate_write_to_data(t, proxyMethod->statements,
- new StringLiteralExpression(arg->name.data), v, _data);
- }
- arg = arg->next;
- }
-
- // If there is a results interface for this class
- Expression* resultParameter;
- if (resultsInterfaceType != NULL) {
- // Result interface parameter
- Variable* resultListener = new Variable(resultsInterfaceType, "_result");
- proxyMethod->parameters.push_back(resultListener);
-
- // Add the results dispatcher callback
- resultsDispatcherClass->needed = true;
- resultParameter = new NewExpression(resultsDispatcherClass->type, 2,
- new LiteralExpression(format_int(index)), resultListener);
- } else {
- resultParameter = NULL_VALUE;
- }
-
- // All proxy methods take an error parameter
- Variable* errorListener = new Variable(RPC_ERROR_LISTENER_TYPE, "_errors");
- proxyMethod->parameters.push_back(errorListener);
-
- // Call the broker
- proxyMethod->statements->Add(new MethodCall(new FieldVariable(THIS_VALUE, "_broker"),
- "sendRpc", 5,
- proxyClass->endpoint,
- new StringLiteralExpression(method->name.data),
- new MethodCall(_data, "serialize"),
- resultParameter,
- errorListener));
-}
-
-static void
-generate_result_dispatcher_method(const method_type* method,
- ResultDispatcherClass* resultsDispatcherClass, Type* resultsInterfaceType, int index)
-{
- arg_type* arg;
- Method* dispatchMethod;
- Variable* dispatchParam;
- resultsDispatcherClass->AddMethod(index, method->name.data, &dispatchMethod, &dispatchParam);
-
- Variable* classLoader = NULL;
- Variable* resultData = new Variable(RPC_DATA_TYPE, "resultData");
- dispatchMethod->statements->Add(new VariableDeclaration(resultData,
- new NewExpression(RPC_DATA_TYPE, 1, dispatchParam)));
-
- // The callback method itself
- MethodCall* realCall = new MethodCall(
- new Cast(resultsInterfaceType, new FieldVariable(THIS_VALUE, "callback")),
- results_method_name(method->name.data));
-
- // The return value
- {
- Type* t = NAMES.Search(method->type.type.data);
- if (t != VOID_TYPE) {
- Variable* rv = new Variable(t, "rv");
- dispatchMethod->statements->Add(new VariableDeclaration(rv));
- generate_create_from_data(t, dispatchMethod->statements, "_result", rv,
- resultData, &classLoader);
- realCall->arguments.push_back(rv);
- }
- }
-
- VariableFactory stubArgs("arg");
- arg = method->args;
- while (arg != NULL) {
- if (convert_direction(arg->direction.data) & OUT_PARAMETER) {
- // Unmarshall the results
- Type* t = NAMES.Search(arg->type.type.data);
- Variable* v = stubArgs.Get(t);
- dispatchMethod->statements->Add(new VariableDeclaration(v));
-
- generate_create_from_data(t, dispatchMethod->statements, arg->name.data, v,
- resultData, &classLoader);
-
- // Add the argument to the callback
- realCall->arguments.push_back(v);
- }
- arg = arg->next;
- }
-
- // Call the callback method
- IfStatement* ifst = new IfStatement;
- ifst->expression = new Comparison(new FieldVariable(THIS_VALUE, "callback"), "!=", NULL_VALUE);
- dispatchMethod->statements->Add(ifst);
- ifst->statements->Add(realCall);
-}
-
-static void
-generate_regular_method(const method_type* method, RpcProxyClass* proxyClass,
- EndpointBaseClass* serviceBaseClass, ResultDispatcherClass* resultsDispatcherClass,
- int index)
-{
- arg_type* arg;
-
- // == the callback interface for results ================================
- // the service base class
- Type* resultsInterfaceType = generate_results_method(method, proxyClass);
-
- // == the method in the proxy class =====================================
- generate_proxy_method(method, proxyClass, resultsDispatcherClass, resultsInterfaceType, index);
-
- // == the method in the result dispatcher class =========================
- if (resultsInterfaceType != NULL) {
- generate_result_dispatcher_method(method, resultsDispatcherClass, resultsInterfaceType,
- index);
- }
-
- // == The abstract method that the service developers implement ==========
- Method* decl = new Method;
- decl->comment = gather_comments(method->comments_token->extra);
- decl->modifiers = PUBLIC | ABSTRACT;
- decl->returnType = NAMES.Search(method->type.type.data);
- decl->returnTypeDimension = method->type.dimension;
- decl->name = method->name.data;
- arg = method->args;
- while (arg != NULL) {
- decl->parameters.push_back(new Variable(
- NAMES.Search(arg->type.type.data), arg->name.data,
- arg->type.dimension));
- arg = arg->next;
- }
-
- // Add the default RpcContext param to all methods
- decl->parameters.push_back(new Variable(RPC_CONTEXT_TYPE, "context", 0));
-
- serviceBaseClass->elements.push_back(decl);
-
-
- // == the dispatch method in the service base class ======================
- serviceBaseClass->AddMethod(method);
-}
-
-static void
-generate_event_method(const method_type* method, RpcProxyClass* proxyClass,
- EndpointBaseClass* serviceBaseClass, ListenerClass* listenerClass,
- EventListenerClass* presenterClass, int index)
-{
- arg_type* arg;
- listenerClass->needed = true;
-
- // == the push method in the service base class =========================
- Method* push = new Method;
- push->modifiers = PUBLIC;
- push->name = push_method_name(method->name.data);
- push->statements = new StatementBlock;
- push->returnType = VOID_TYPE;
- serviceBaseClass->elements.push_back(push);
-
- // The local variables
- Variable* _data = new Variable(RPC_DATA_TYPE, "_data");
- push->statements->Add(new VariableDeclaration(_data, new NewExpression(RPC_DATA_TYPE)));
-
- // Add the arguments
- arg = method->args;
- while (arg != NULL) {
- // Function signature
- Type* t = NAMES.Search(arg->type.type.data);
- Variable* v = new Variable(t, arg->name.data, arg->type.dimension);
- push->parameters.push_back(v);
-
- // Input parameter marshalling
- generate_write_to_data(t, push->statements,
- new StringLiteralExpression(arg->name.data), v, _data);
-
- arg = arg->next;
- }
-
- // Send the notifications
- push->statements->Add(new MethodCall("pushEvent", 2,
- new StringLiteralExpression(method->name.data),
- new MethodCall(_data, "serialize")));
-
- // == the event callback dispatcher method ====================================
- presenterClass->AddMethod(method);
-
- // == the event method in the listener base class =====================
- Method* event = new Method;
- event->modifiers = PUBLIC;
- event->name = method->name.data;
- event->statements = new StatementBlock;
- event->returnType = VOID_TYPE;
- listenerClass->elements.push_back(event);
- arg = method->args;
- while (arg != NULL) {
- event->parameters.push_back(new Variable(
- NAMES.Search(arg->type.type.data), arg->name.data,
- arg->type.dimension));
- arg = arg->next;
- }
-
- // Add a final parameter: RpcContext. Contains data about
- // incoming request (e.g., certificate)
- event->parameters.push_back(new Variable(RPC_CONTEXT_TYPE, "context", 0));
-}
-
-static void
-generate_listener_methods(RpcProxyClass* proxyClass, Type* presenterType, Type* listenerType)
-{
- // AndroidAtHomePresenter _presenter;
- // void startListening(Listener listener) {
- // stopListening();
- // _presenter = new Presenter(_broker, listener);
- // _presenter.startListening(_endpoint);
- // }
- // void stopListening() {
- // if (_presenter != null) {
- // _presenter.stopListening();
- // }
- // }
-
- Variable* _presenter = new Variable(presenterType, "_presenter");
- proxyClass->elements.push_back(new Field(PRIVATE, _presenter));
-
- Variable* listener = new Variable(listenerType, "listener");
-
- Method* startListeningMethod = new Method;
- startListeningMethod->modifiers = PUBLIC;
- startListeningMethod->returnType = VOID_TYPE;
- startListeningMethod->name = "startListening";
- startListeningMethod->statements = new StatementBlock;
- startListeningMethod->parameters.push_back(listener);
- proxyClass->elements.push_back(startListeningMethod);
-
- startListeningMethod->statements->Add(new MethodCall(THIS_VALUE, "stopListening"));
- startListeningMethod->statements->Add(new Assignment(_presenter,
- new NewExpression(presenterType, 2, proxyClass->broker, listener)));
- startListeningMethod->statements->Add(new MethodCall(_presenter,
- "startListening", 1, proxyClass->endpoint));
-
- Method* stopListeningMethod = new Method;
- stopListeningMethod->modifiers = PUBLIC;
- stopListeningMethod->returnType = VOID_TYPE;
- stopListeningMethod->name = "stopListening";
- stopListeningMethod->statements = new StatementBlock;
- proxyClass->elements.push_back(stopListeningMethod);
-
- IfStatement* ifst = new IfStatement;
- ifst->expression = new Comparison(_presenter, "!=", NULL_VALUE);
- stopListeningMethod->statements->Add(ifst);
-
- ifst->statements->Add(new MethodCall(_presenter, "stopListening"));
- ifst->statements->Add(new Assignment(_presenter, NULL_VALUE));
-}
-
-Class*
-generate_rpc_interface_class(const interface_type* iface)
-{
- // the proxy class
- InterfaceType* interfaceType = static_cast<InterfaceType*>(
- NAMES.Find(iface->package, iface->name.data));
- RpcProxyClass* proxy = new RpcProxyClass(iface, interfaceType);
-
- // the listener class
- ListenerClass* listener = new ListenerClass(iface);
-
- // the presenter class
- EventListenerClass* presenter = new EventListenerClass(iface, listener->type);
-
- // the service base class
- EndpointBaseClass* base = new EndpointBaseClass(iface);
- proxy->elements.push_back(base);
-
- // the result dispatcher
- ResultDispatcherClass* results = new ResultDispatcherClass();
-
- // all the declared methods of the proxy
- int index = 0;
- interface_item_type* item = iface->interface_items;
- while (item != NULL) {
- if (item->item_type == METHOD_TYPE) {
- if (NAMES.Search(((method_type*)item)->type.type.data) == EVENT_FAKE_TYPE) {
- generate_event_method((method_type*)item, proxy, base, listener, presenter, index);
- } else {
- generate_regular_method((method_type*)item, proxy, base, results, index);
- }
- }
- item = item->next;
- index++;
- }
- presenter->DoneWithMethods();
- base->DoneWithMethods();
-
- // only add this if there are methods with results / out parameters
- if (results->needed) {
- proxy->elements.push_back(results);
- }
- if (listener->needed) {
- proxy->elements.push_back(listener);
- proxy->elements.push_back(presenter);
- generate_listener_methods(proxy, presenter->type, listener->type);
- }
-
- return proxy;
-}
diff --git a/tools/aidl/options_test.cpp b/tools/aidl/options_test.cpp
deleted file mode 100644
index bd106ce..0000000
--- a/tools/aidl/options_test.cpp
+++ /dev/null
@@ -1,291 +0,0 @@
-#include <iostream>
-#include "options.h"
-
-const bool VERBOSE = false;
-
-using namespace std;
-
-struct Answer {
- const char* argv[8];
- int result;
- const char* systemSearchPath[8];
- const char* localSearchPath[8];
- const char* inputFileName;
- language_t nativeLanguage;
- const char* outputH;
- const char* outputCPP;
- const char* outputJava;
-};
-
-bool
-match_arrays(const char* const*expected, const vector<string> &got)
-{
- int count = 0;
- while (expected[count] != NULL) {
- count++;
- }
- if (got.size() != count) {
- return false;
- }
- for (int i=0; i<count; i++) {
- if (got[i] != expected[i]) {
- return false;
- }
- }
- return true;
-}
-
-void
-print_array(const char* prefix, const char* const*expected)
-{
- while (*expected) {
- cout << prefix << *expected << endl;
- expected++;
- }
-}
-
-void
-print_array(const char* prefix, const vector<string> &got)
-{
- size_t count = got.size();
- for (size_t i=0; i<count; i++) {
- cout << prefix << got[i] << endl;
- }
-}
-
-static int
-test(const Answer& answer)
-{
- int argc = 0;
- while (answer.argv[argc]) {
- argc++;
- }
-
- int err = 0;
-
- Options options;
- int result = parse_options(argc, answer.argv, &options);
-
- // result
- if (((bool)result) != ((bool)answer.result)) {
- cout << "mismatch: result: got " << result << " expected " <<
- answer.result << endl;
- err = 1;
- }
-
- if (result != 0) {
- // if it failed, everything is invalid
- return err;
- }
-
- // systemSearchPath
- if (!match_arrays(answer.systemSearchPath, options.systemSearchPath)) {
- cout << "mismatch: systemSearchPath: got" << endl;
- print_array(" ", options.systemSearchPath);
- cout << " expected" << endl;
- print_array(" ", answer.systemSearchPath);
- err = 1;
- }
-
- // localSearchPath
- if (!match_arrays(answer.localSearchPath, options.localSearchPath)) {
- cout << "mismatch: localSearchPath: got" << endl;
- print_array(" ", options.localSearchPath);
- cout << " expected" << endl;
- print_array(" ", answer.localSearchPath);
- err = 1;
- }
-
- // inputFileName
- if (answer.inputFileName != options.inputFileName) {
- cout << "mismatch: inputFileName: got " << options.inputFileName
- << " expected " << answer.inputFileName << endl;
- err = 1;
- }
-
- // nativeLanguage
- if (answer.nativeLanguage != options.nativeLanguage) {
- cout << "mismatch: nativeLanguage: got " << options.nativeLanguage
- << " expected " << answer.nativeLanguage << endl;
- err = 1;
- }
-
- // outputH
- if (answer.outputH != options.outputH) {
- cout << "mismatch: outputH: got " << options.outputH
- << " expected " << answer.outputH << endl;
- err = 1;
- }
-
- // outputCPP
- if (answer.outputCPP != options.outputCPP) {
- cout << "mismatch: outputCPP: got " << options.outputCPP
- << " expected " << answer.outputCPP << endl;
- err = 1;
- }
-
- // outputJava
- if (answer.outputJava != options.outputJava) {
- cout << "mismatch: outputJava: got " << options.outputJava
- << " expected " << answer.outputJava << endl;
- err = 1;
- }
-
- return err;
-}
-
-const Answer g_tests[] = {
-
- {
- /* argv */ { "test", "-i/moof", "-I/blah", "-Ibleh", "-imoo", "inputFileName.aidl_cpp", NULL, NULL },
- /* result */ 0,
- /* systemSearchPath */ { "/blah", "bleh", NULL, NULL, NULL, NULL, NULL, NULL },
- /* localSearchPath */ { "/moof", "moo", NULL, NULL, NULL, NULL, NULL, NULL },
- /* inputFileName */ "inputFileName.aidl_cpp",
- /* nativeLanguage */ CPP,
- /* outputH */ "",
- /* outputCPP */ "",
- /* outputJava */ ""
- },
-
- {
- /* argv */ { "test", "inputFileName.aidl_cpp", "-oh", "outputH", NULL, NULL, NULL, NULL },
- /* result */ 0,
- /* systemSearchPath */ { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
- /* localSearchPath */ { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
- /* inputFileName */ "inputFileName.aidl_cpp",
- /* nativeLanguage */ CPP,
- /* outputH */ "outputH",
- /* outputCPP */ "",
- /* outputJava */ ""
- },
-
- {
- /* argv */ { "test", "inputFileName.aidl_cpp", "-ocpp", "outputCPP", NULL, NULL, NULL, NULL },
- /* result */ 0,
- /* systemSearchPath */ { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
- /* localSearchPath */ { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
- /* inputFileName */ "inputFileName.aidl_cpp",
- /* nativeLanguage */ CPP,
- /* outputH */ "",
- /* outputCPP */ "outputCPP",
- /* outputJava */ ""
- },
-
- {
- /* argv */ { "test", "inputFileName.aidl_cpp", "-ojava", "outputJava", NULL, NULL, NULL, NULL },
- /* result */ 0,
- /* systemSearchPath */ { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
- /* localSearchPath */ { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
- /* inputFileName */ "inputFileName.aidl_cpp",
- /* nativeLanguage */ CPP,
- /* outputH */ "",
- /* outputCPP */ "",
- /* outputJava */ "outputJava"
- },
-
- {
- /* argv */ { "test", "inputFileName.aidl_cpp", "-oh", "outputH", "-ocpp", "outputCPP", "-ojava", "outputJava" },
- /* result */ 0,
- /* systemSearchPath */ { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
- /* localSearchPath */ { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
- /* inputFileName */ "inputFileName.aidl_cpp",
- /* nativeLanguage */ CPP,
- /* outputH */ "outputH",
- /* outputCPP */ "outputCPP",
- /* outputJava */ "outputJava"
- },
-
- {
- /* argv */ { "test", "inputFileName.aidl_cpp", "-oh", "outputH", "-oh", "outputH1", NULL, NULL },
- /* result */ 1,
- /* systemSearchPath */ { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
- /* localSearchPath */ { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
- /* inputFileName */ "",
- /* nativeLanguage */ CPP,
- /* outputH */ "",
- /* outputCPP */ "",
- /* outputJava */ ""
- },
-
- {
- /* argv */ { "test", "inputFileName.aidl_cpp", "-ocpp", "outputCPP", "-ocpp", "outputCPP1", NULL, NULL },
- /* result */ 1,
- /* systemSearchPath */ { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
- /* localSearchPath */ { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
- /* inputFileName */ "",
- /* nativeLanguage */ CPP,
- /* outputH */ "",
- /* outputCPP */ "",
- /* outputJava */ ""
- },
-
- {
- /* argv */ { "test", "inputFileName.aidl_cpp", "-ojava", "outputJava", "-ojava", "outputJava1", NULL, NULL },
- /* result */ 1,
- /* systemSearchPath */ { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
- /* localSearchPath */ { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
- /* inputFileName */ "",
- /* nativeLanguage */ CPP,
- /* outputH */ "",
- /* outputCPP */ "",
- /* outputJava */ ""
- },
-
-};
-
-int
-main(int argc, const char** argv)
-{
- const int count = sizeof(g_tests)/sizeof(g_tests[0]);
- int matches[count];
-
- int result = 0;
- for (int i=0; i<count; i++) {
- if (VERBOSE) {
- cout << endl;
- cout << "---------------------------------------------" << endl;
- const char* const* p = g_tests[i].argv;
- while (*p) {
- cout << " " << *p;
- p++;
- }
- cout << endl;
- cout << "---------------------------------------------" << endl;
- }
- matches[i] = test(g_tests[i]);
- if (VERBOSE) {
- if (0 == matches[i]) {
- cout << "passed" << endl;
- } else {
- cout << "failed" << endl;
- }
- result |= matches[i];
- }
- }
-
- cout << endl;
- cout << "=============================================" << endl;
- cout << "options_test summary" << endl;
- cout << "=============================================" << endl;
-
- if (!result) {
- cout << "passed" << endl;
- } else {
- cout << "failed the following tests:" << endl;
- for (int i=0; i<count; i++) {
- if (matches[i]) {
- cout << " ";
- const char* const* p = g_tests[i].argv;
- while (*p) {
- cout << " " << *p;
- p++;
- }
- cout << endl;
- }
- }
- }
-
- return result;
-}
-
diff --git a/tools/aidl/tests/end_to_end_tests.cpp b/tools/aidl/tests/end_to_end_tests.cpp
new file mode 100644
index 0000000..54ca603
--- /dev/null
+++ b/tools/aidl/tests/end_to_end_tests.cpp
@@ -0,0 +1,165 @@
+/*
+ * Copyright (C) 2015, 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.
+ */
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include <base/logging.h>
+#include <base/files/file_path.h>
+#include <base/files/file_util.h>
+#include <gtest/gtest.h>
+
+#include "aidl.h"
+#include "options.h"
+#include "tests/test_data.h"
+
+using base::FilePath;
+using std::string;
+using std::unique_ptr;
+using std::vector;
+
+using namespace aidl::test_data;
+
+namespace {
+
+const char kDiffTemplate[] = "diff %s %s";
+const char kStubInterfaceTemplate[] = "package %s;\ninterface %s { }";
+const char kStubParcelableTemplate[] = "package %s;\nparcelable %s;";
+
+FilePath GetPathForPackageClass(const char* package_class,
+ const char* extension) {
+ string rel_path{package_class};
+ for (char& c : rel_path) {
+ if (c == '.') {
+ c = FilePath::kSeparators[0];
+ }
+ }
+ rel_path += extension;
+ return FilePath(rel_path);
+}
+
+void SplitPackageClass(const string& package_class,
+ FilePath* rel_path,
+ string* package,
+ string* class_name) {
+ *package = string{package_class, 0, package_class.rfind('.')};
+ *class_name = string{package_class, package_class.rfind('.') + 1};
+ *rel_path = GetPathForPackageClass(package_class.c_str(), ".aidl");
+}
+
+} // namespace
+
+class EndToEndTest : public ::testing::Test {
+ protected:
+ virtual void SetUp() {
+ ASSERT_TRUE(base::CreateNewTempDirectory(
+ string{"end_to_end_testsyyyy"}, &tmpDir_));
+ inputDir_ = tmpDir_.Append("input");
+ outputDir_ = tmpDir_.Append("output");
+ ASSERT_TRUE(base::CreateDirectory(inputDir_));
+ ASSERT_TRUE(base::CreateDirectory(outputDir_));
+ }
+
+ virtual void TearDown() {
+ ASSERT_TRUE(DeleteFile(tmpDir_, true))
+ << "Failed to remove temp directory: " << tmpDir_.value();
+ }
+
+ FilePath CreateInputFile(const FilePath& relative_path,
+ const char contents[],
+ int size) {
+ const FilePath created_file = inputDir_.Append(relative_path);
+ EXPECT_TRUE(base::CreateDirectory(created_file.DirName()));
+ EXPECT_TRUE(base::WriteFile(created_file, contents, size));
+ return created_file;
+ }
+
+ void CreateStubAidlFile(const string& package_class,
+ const char* file_template) {
+ string package, class_name;
+ FilePath rel_path;
+ SplitPackageClass(package_class, &rel_path, &package, &class_name);
+ const size_t buf_len =
+ strlen(file_template) + package.length() + class_name.length() + 1;
+ unique_ptr<char[]> contents(new char[buf_len]);
+ const int written = snprintf(contents.get(), buf_len, file_template,
+ package.c_str(), class_name.c_str());
+ EXPECT_GT(written, 0);
+ CreateInputFile(rel_path, contents.get(), written);
+ }
+
+ void WriteStubAidls(const char** parcelables, const char** interfaces) {
+ while (*parcelables) {
+ CreateStubAidlFile(string{*parcelables}, kStubParcelableTemplate);
+ ++parcelables;
+ }
+ while (*interfaces) {
+ CreateStubAidlFile(string{*interfaces}, kStubInterfaceTemplate);
+ ++interfaces;
+ }
+ }
+
+ void CheckFileContents(const FilePath& rel_path,
+ const string& expected_content) {
+ string actual_contents;
+ FilePath actual_path = outputDir_.Append(rel_path);
+ if (!ReadFileToString(actual_path, &actual_contents)) {
+ FAIL() << "Failed to read expected output file: " << rel_path.value();
+ }
+ // Generated .java files mention the "original" file as part of their
+ // comment header. Thus we look for expected_content being a substring.
+ if (actual_contents.find(expected_content) == string::npos) {
+ // When the match fails, display a diff of what's wrong. This greatly
+ // aids in debugging.
+ FilePath expected_path;
+ EXPECT_TRUE(CreateTemporaryFileInDir(tmpDir_, &expected_path));
+ base::WriteFile(expected_path, expected_content.c_str(),
+ expected_content.length());
+ const size_t buf_len =
+ strlen(kDiffTemplate) + actual_path.value().length() +
+ expected_path.value().length() + 1;
+ unique_ptr<char[]> diff_cmd(new char[buf_len]);
+ EXPECT_GT(snprintf(diff_cmd.get(), buf_len, kDiffTemplate,
+ expected_path.value().c_str(),
+ actual_path.value().c_str()), 0);
+ system(diff_cmd.get());
+ FAIL() << "Actual contents of " << rel_path.value()
+ << " did not match expected content";
+ }
+ }
+
+ FilePath tmpDir_;
+ FilePath inputDir_;
+ FilePath outputDir_;
+};
+
+TEST_F(EndToEndTest, IExampleInterface) {
+ Options options;
+ options.failOnParcelable = true;
+ options.importPaths.push_back(inputDir_.value());
+ options.inputFileName =
+ CreateInputFile(GetPathForPackageClass(kIExampleInterfaceClass, ".aidl"),
+ kIExampleInterfaceContents,
+ strlen(kIExampleInterfaceContents)).value();
+ options.autoDepFile = true;
+ options.outputBaseFolder = outputDir_.value();
+ WriteStubAidls(kIExampleInterfaceParcelables, kIExampleInterfaceInterfaces);
+ EXPECT_EQ(compile_aidl(options), 0);
+ CheckFileContents(GetPathForPackageClass(kIExampleInterfaceClass, ".java"),
+ kIExampleInterfaceJava);
+ // We'd like to check the depends file, but it mentions unique file paths.
+}
diff --git a/tools/aidl/tests/example_interface_test_data.cpp b/tools/aidl/tests/example_interface_test_data.cpp
new file mode 100644
index 0000000..b17a800
--- /dev/null
+++ b/tools/aidl/tests/example_interface_test_data.cpp
@@ -0,0 +1,404 @@
+/*
+ * Copyright (C) 2015, 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.
+ */
+
+#include "tests/test_data.h"
+
+namespace aidl {
+namespace test_data {
+
+const char kIExampleInterfaceClass[] = "android.test.IExampleInterface";
+
+const char* kIExampleInterfaceParcelables[] = {
+ "android.foo.ExampleParcelable",
+ "android.test.ExampleParcelable2",
+ nullptr,
+};
+
+const char* kIExampleInterfaceInterfaces[] = {
+ "android.bar.IAuxInterface",
+ "android.test.IAuxInterface2",
+ nullptr,
+};
+
+const char kIExampleInterfaceContents[] = R"(
+package android.test;
+
+import android.foo.ExampleParcelable;
+import android.test.ExampleParcelable2;
+import android.bar.IAuxInterface;
+import android.test.IAuxInterface2;
+
+interface IExampleInterface {
+ boolean isEnabled();
+ int getState();
+ String getAddress();
+
+ ExampleParcelable[] getParcelables();
+
+ boolean setScanMode(int mode, int duration);
+
+ void registerBinder(IAuxInterface foo);
+ IExampleInterface getRecursiveBinder();
+
+ int takesAnInterface(in IAuxInterface2 arg);
+ int takesAParcelable(in ExampleParcelable2 arg);
+}
+)";
+
+const char kIExampleInterfaceDeps[] =
+R"(/tmp/.org.chromium.Chromium.Cdq7YZ/output/android/test/IExampleInterface.java: \
+ /tmp/.org.chromium.Chromium.Cdq7YZ/input/android/test/IExampleInterface.aidl \
+ /tmp/.org.chromium.Chromium.Cdq7YZ/input/android/foo/ExampleParcelable.aidl \
+ /tmp/.org.chromium.Chromium.Cdq7YZ/input/android/test/ExampleParcelable2.aidl \
+ /tmp/.org.chromium.Chromium.Cdq7YZ/input/android/bar/IAuxInterface.aidl \
+ /tmp/.org.chromium.Chromium.Cdq7YZ/input/android/test/IAuxInterface2.aidl
+
+/tmp/.org.chromium.Chromium.Cdq7YZ/input/android/test/IExampleInterface.aidl :
+/tmp/.org.chromium.Chromium.Cdq7YZ/input/android/foo/ExampleParcelable.aidl :
+/tmp/.org.chromium.Chromium.Cdq7YZ/input/android/test/ExampleParcelable2.aidl :
+/tmp/.org.chromium.Chromium.Cdq7YZ/input/android/bar/IAuxInterface.aidl :
+/tmp/.org.chromium.Chromium.Cdq7YZ/input/android/test/IAuxInterface2.aidl :)";
+
+const char kIExampleInterfaceJava[] =
+R"(package android.test;
+public interface IExampleInterface extends android.os.IInterface
+{
+/** Local-side IPC implementation stub class. */
+public static abstract class Stub extends android.os.Binder implements android.test.IExampleInterface
+{
+private static final java.lang.String DESCRIPTOR = "android.test.IExampleInterface";
+/** Construct the stub at attach it to the interface. */
+public Stub()
+{
+this.attachInterface(this, DESCRIPTOR);
+}
+/**
+ * Cast an IBinder object into an android.test.IExampleInterface interface,
+ * generating a proxy if needed.
+ */
+public static android.test.IExampleInterface asInterface(android.os.IBinder obj)
+{
+if ((obj==null)) {
+return null;
+}
+android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
+if (((iin!=null)&&(iin instanceof android.test.IExampleInterface))) {
+return ((android.test.IExampleInterface)iin);
+}
+return new android.test.IExampleInterface.Stub.Proxy(obj);
+}
+@Override public android.os.IBinder asBinder()
+{
+return this;
+}
+@Override public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException
+{
+switch (code)
+{
+case INTERFACE_TRANSACTION:
+{
+reply.writeString(DESCRIPTOR);
+return true;
+}
+case TRANSACTION_isEnabled:
+{
+data.enforceInterface(DESCRIPTOR);
+boolean _result = this.isEnabled();
+reply.writeNoException();
+reply.writeInt(((_result)?(1):(0)));
+return true;
+}
+case TRANSACTION_getState:
+{
+data.enforceInterface(DESCRIPTOR);
+int _result = this.getState();
+reply.writeNoException();
+reply.writeInt(_result);
+return true;
+}
+case TRANSACTION_getAddress:
+{
+data.enforceInterface(DESCRIPTOR);
+java.lang.String _result = this.getAddress();
+reply.writeNoException();
+reply.writeString(_result);
+return true;
+}
+case TRANSACTION_getParcelables:
+{
+data.enforceInterface(DESCRIPTOR);
+android.foo.ExampleParcelable[] _result = this.getParcelables();
+reply.writeNoException();
+reply.writeTypedArray(_result, android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
+return true;
+}
+case TRANSACTION_setScanMode:
+{
+data.enforceInterface(DESCRIPTOR);
+int _arg0;
+_arg0 = data.readInt();
+int _arg1;
+_arg1 = data.readInt();
+boolean _result = this.setScanMode(_arg0, _arg1);
+reply.writeNoException();
+reply.writeInt(((_result)?(1):(0)));
+return true;
+}
+case TRANSACTION_registerBinder:
+{
+data.enforceInterface(DESCRIPTOR);
+android.bar.IAuxInterface _arg0;
+_arg0 = android.bar.IAuxInterface.Stub.asInterface(data.readStrongBinder());
+this.registerBinder(_arg0);
+reply.writeNoException();
+return true;
+}
+case TRANSACTION_getRecursiveBinder:
+{
+data.enforceInterface(DESCRIPTOR);
+android.test.IExampleInterface _result = this.getRecursiveBinder();
+reply.writeNoException();
+reply.writeStrongBinder((((_result!=null))?(_result.asBinder()):(null)));
+return true;
+}
+case TRANSACTION_takesAnInterface:
+{
+data.enforceInterface(DESCRIPTOR);
+android.test.IAuxInterface2 _arg0;
+_arg0 = android.test.IAuxInterface2.Stub.asInterface(data.readStrongBinder());
+int _result = this.takesAnInterface(_arg0);
+reply.writeNoException();
+reply.writeInt(_result);
+return true;
+}
+case TRANSACTION_takesAParcelable:
+{
+data.enforceInterface(DESCRIPTOR);
+android.test.ExampleParcelable2 _arg0;
+if ((0!=data.readInt())) {
+_arg0 = android.test.ExampleParcelable2.CREATOR.createFromParcel(data);
+}
+else {
+_arg0 = null;
+}
+int _result = this.takesAParcelable(_arg0);
+reply.writeNoException();
+reply.writeInt(_result);
+return true;
+}
+}
+return super.onTransact(code, data, reply, flags);
+}
+private static class Proxy implements android.test.IExampleInterface
+{
+private android.os.IBinder mRemote;
+Proxy(android.os.IBinder remote)
+{
+mRemote = remote;
+}
+@Override public android.os.IBinder asBinder()
+{
+return mRemote;
+}
+public java.lang.String getInterfaceDescriptor()
+{
+return DESCRIPTOR;
+}
+@Override public boolean isEnabled() throws android.os.RemoteException
+{
+android.os.Parcel _data = android.os.Parcel.obtain();
+android.os.Parcel _reply = android.os.Parcel.obtain();
+boolean _result;
+try {
+_data.writeInterfaceToken(DESCRIPTOR);
+mRemote.transact(Stub.TRANSACTION_isEnabled, _data, _reply, 0);
+_reply.readException();
+_result = (0!=_reply.readInt());
+}
+finally {
+_reply.recycle();
+_data.recycle();
+}
+return _result;
+}
+@Override public int getState() throws android.os.RemoteException
+{
+android.os.Parcel _data = android.os.Parcel.obtain();
+android.os.Parcel _reply = android.os.Parcel.obtain();
+int _result;
+try {
+_data.writeInterfaceToken(DESCRIPTOR);
+mRemote.transact(Stub.TRANSACTION_getState, _data, _reply, 0);
+_reply.readException();
+_result = _reply.readInt();
+}
+finally {
+_reply.recycle();
+_data.recycle();
+}
+return _result;
+}
+@Override public java.lang.String getAddress() throws android.os.RemoteException
+{
+android.os.Parcel _data = android.os.Parcel.obtain();
+android.os.Parcel _reply = android.os.Parcel.obtain();
+java.lang.String _result;
+try {
+_data.writeInterfaceToken(DESCRIPTOR);
+mRemote.transact(Stub.TRANSACTION_getAddress, _data, _reply, 0);
+_reply.readException();
+_result = _reply.readString();
+}
+finally {
+_reply.recycle();
+_data.recycle();
+}
+return _result;
+}
+@Override public android.foo.ExampleParcelable[] getParcelables() throws android.os.RemoteException
+{
+android.os.Parcel _data = android.os.Parcel.obtain();
+android.os.Parcel _reply = android.os.Parcel.obtain();
+android.foo.ExampleParcelable[] _result;
+try {
+_data.writeInterfaceToken(DESCRIPTOR);
+mRemote.transact(Stub.TRANSACTION_getParcelables, _data, _reply, 0);
+_reply.readException();
+_result = _reply.createTypedArray(android.foo.ExampleParcelable.CREATOR);
+}
+finally {
+_reply.recycle();
+_data.recycle();
+}
+return _result;
+}
+@Override public boolean setScanMode(int mode, int duration) throws android.os.RemoteException
+{
+android.os.Parcel _data = android.os.Parcel.obtain();
+android.os.Parcel _reply = android.os.Parcel.obtain();
+boolean _result;
+try {
+_data.writeInterfaceToken(DESCRIPTOR);
+_data.writeInt(mode);
+_data.writeInt(duration);
+mRemote.transact(Stub.TRANSACTION_setScanMode, _data, _reply, 0);
+_reply.readException();
+_result = (0!=_reply.readInt());
+}
+finally {
+_reply.recycle();
+_data.recycle();
+}
+return _result;
+}
+@Override public void registerBinder(android.bar.IAuxInterface foo) throws android.os.RemoteException
+{
+android.os.Parcel _data = android.os.Parcel.obtain();
+android.os.Parcel _reply = android.os.Parcel.obtain();
+try {
+_data.writeInterfaceToken(DESCRIPTOR);
+_data.writeStrongBinder((((foo!=null))?(foo.asBinder()):(null)));
+mRemote.transact(Stub.TRANSACTION_registerBinder, _data, _reply, 0);
+_reply.readException();
+}
+finally {
+_reply.recycle();
+_data.recycle();
+}
+}
+@Override public android.test.IExampleInterface getRecursiveBinder() throws android.os.RemoteException
+{
+android.os.Parcel _data = android.os.Parcel.obtain();
+android.os.Parcel _reply = android.os.Parcel.obtain();
+android.test.IExampleInterface _result;
+try {
+_data.writeInterfaceToken(DESCRIPTOR);
+mRemote.transact(Stub.TRANSACTION_getRecursiveBinder, _data, _reply, 0);
+_reply.readException();
+_result = android.test.IExampleInterface.Stub.asInterface(_reply.readStrongBinder());
+}
+finally {
+_reply.recycle();
+_data.recycle();
+}
+return _result;
+}
+@Override public int takesAnInterface(android.test.IAuxInterface2 arg) throws android.os.RemoteException
+{
+android.os.Parcel _data = android.os.Parcel.obtain();
+android.os.Parcel _reply = android.os.Parcel.obtain();
+int _result;
+try {
+_data.writeInterfaceToken(DESCRIPTOR);
+_data.writeStrongBinder((((arg!=null))?(arg.asBinder()):(null)));
+mRemote.transact(Stub.TRANSACTION_takesAnInterface, _data, _reply, 0);
+_reply.readException();
+_result = _reply.readInt();
+}
+finally {
+_reply.recycle();
+_data.recycle();
+}
+return _result;
+}
+@Override public int takesAParcelable(android.test.ExampleParcelable2 arg) throws android.os.RemoteException
+{
+android.os.Parcel _data = android.os.Parcel.obtain();
+android.os.Parcel _reply = android.os.Parcel.obtain();
+int _result;
+try {
+_data.writeInterfaceToken(DESCRIPTOR);
+if ((arg!=null)) {
+_data.writeInt(1);
+arg.writeToParcel(_data, 0);
+}
+else {
+_data.writeInt(0);
+}
+mRemote.transact(Stub.TRANSACTION_takesAParcelable, _data, _reply, 0);
+_reply.readException();
+_result = _reply.readInt();
+}
+finally {
+_reply.recycle();
+_data.recycle();
+}
+return _result;
+}
+}
+static final int TRANSACTION_isEnabled = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
+static final int TRANSACTION_getState = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);
+static final int TRANSACTION_getAddress = (android.os.IBinder.FIRST_CALL_TRANSACTION + 2);
+static final int TRANSACTION_getParcelables = (android.os.IBinder.FIRST_CALL_TRANSACTION + 3);
+static final int TRANSACTION_setScanMode = (android.os.IBinder.FIRST_CALL_TRANSACTION + 4);
+static final int TRANSACTION_registerBinder = (android.os.IBinder.FIRST_CALL_TRANSACTION + 5);
+static final int TRANSACTION_getRecursiveBinder = (android.os.IBinder.FIRST_CALL_TRANSACTION + 6);
+static final int TRANSACTION_takesAnInterface = (android.os.IBinder.FIRST_CALL_TRANSACTION + 7);
+static final int TRANSACTION_takesAParcelable = (android.os.IBinder.FIRST_CALL_TRANSACTION + 8);
+}
+public boolean isEnabled() throws android.os.RemoteException;
+public int getState() throws android.os.RemoteException;
+public java.lang.String getAddress() throws android.os.RemoteException;
+public android.foo.ExampleParcelable[] getParcelables() throws android.os.RemoteException;
+public boolean setScanMode(int mode, int duration) throws android.os.RemoteException;
+public void registerBinder(android.bar.IAuxInterface foo) throws android.os.RemoteException;
+public android.test.IExampleInterface getRecursiveBinder() throws android.os.RemoteException;
+public int takesAnInterface(android.test.IAuxInterface2 arg) throws android.os.RemoteException;
+public int takesAParcelable(android.test.ExampleParcelable2 arg) throws android.os.RemoteException;
+})";
+
+} // namespace test_data
+} // namespace aidl
diff --git a/tools/aidl/tests/test.cpp b/tools/aidl/tests/test.cpp
deleted file mode 100644
index 15ae294..0000000
--- a/tools/aidl/tests/test.cpp
+++ /dev/null
@@ -1,3 +0,0 @@
-#include <gtest/gtest.h>
-
-TEST(DummyCase, DummyTest) {}
diff --git a/tools/aidl/tests/test_data.h b/tools/aidl/tests/test_data.h
new file mode 100644
index 0000000..cd8887f
--- /dev/null
+++ b/tools/aidl/tests/test_data.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2015, 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.
+ */
+
+#ifndef AIDL_TESTS_TEST_DATA_H_
+#define AIDL_TESTS_TEST_DATA_H_
+
+namespace aidl {
+namespace test_data {
+
+extern const char kIExampleInterfaceClass[];
+extern const char kIExampleInterfaceContents[];
+extern const char* kIExampleInterfaceParcelables[];
+extern const char* kIExampleInterfaceInterfaces[];
+
+extern const char kIExampleInterfaceDeps[];
+extern const char kIExampleInterfaceJava[];
+
+} // namespace test_data
+} // namespace aidl
+#endif // AIDL_TESTS_TEST_DATA_H_
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
index 1f3802e..689e359 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
@@ -36,8 +36,8 @@
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
-import android.annotation.Nullable;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.ContentResolver;
@@ -139,8 +139,9 @@
private Map<StyleResourceValue, Integer> mStyleToDynamicIdMap;
private int mDynamicIdGenerator = 0x02030000; // Base id for R.style in custom namespace
- // cache for TypedArray generated from IStyleResourceValue object
- private Map<int[], Map<Integer, BridgeTypedArray>> mTypedArrayCache;
+ // cache for TypedArray generated from StyleResourceValue object
+ private Map<int[], Map<List<StyleResourceValue>, Map<Integer, BridgeTypedArray>>>
+ mTypedArrayCache;
private BridgeInflater mBridgeInflater;
private BridgeContentResolver mContentResolver;
@@ -621,31 +622,38 @@
}
}
+ // The map is from
+ // attrs (int[]) -> context's current themes (List<StyleRV>) -> resid (int) -> typed array.
if (mTypedArrayCache == null) {
- mTypedArrayCache = new HashMap<int[], Map<Integer,BridgeTypedArray>>();
-
- Map<Integer, BridgeTypedArray> map = new HashMap<Integer, BridgeTypedArray>();
- mTypedArrayCache.put(attrs, map);
-
- BridgeTypedArray ta = createStyleBasedTypedArray(style, attrs);
- map.put(resid, ta);
-
- return ta;
+ mTypedArrayCache = new IdentityHashMap<int[],
+ Map<List<StyleResourceValue>, Map<Integer, BridgeTypedArray>>>();
}
// get the 2nd map
- Map<Integer, BridgeTypedArray> map = mTypedArrayCache.get(attrs);
- if (map == null) {
- map = new HashMap<Integer, BridgeTypedArray>();
- mTypedArrayCache.put(attrs, map);
+ Map<List<StyleResourceValue>, Map<Integer, BridgeTypedArray>> map2 =
+ mTypedArrayCache.get(attrs);
+ if (map2 == null) {
+ map2 = new HashMap<List<StyleResourceValue>, Map<Integer, BridgeTypedArray>>();
+ mTypedArrayCache.put(attrs, map2);
}
- // get the array from the 2nd map
- BridgeTypedArray ta = map.get(resid);
+ // get the 3rd map
+ List<StyleResourceValue> currentThemes = mRenderResources.getAllThemes();
+ Map<Integer, BridgeTypedArray> map3 = map2.get(currentThemes);
+ if (map3 == null) {
+ map3 = new HashMap<Integer, BridgeTypedArray>();
+ // Create a copy of the list before adding it to the map. This allows reusing the
+ // existing list.
+ currentThemes = new ArrayList<StyleResourceValue>(currentThemes);
+ map2.put(currentThemes, map3);
+ }
+
+ // get the array from the 3rd map
+ BridgeTypedArray ta = map3.get(resid);
if (ta == null) {
ta = createStyleBasedTypedArray(style, attrs);
- map.put(resid, ta);
+ map3.put(resid, ta);
}
return ta;