Merge "More adjustments to permissions." into jb-mr1-dev
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 05b04dc..7606d5e3 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -5010,7 +5010,21 @@
if (TextUtils.isEmpty(parentName)) {
return null;
}
- return new Intent().setClassName(this, parentName);
+
+ // If the parent itself has no parent, generate a main activity intent.
+ final ComponentName target = new ComponentName(this, parentName);
+ try {
+ final ActivityInfo parentInfo = getPackageManager().getActivityInfo(target, 0);
+ final String parentActivity = parentInfo.parentActivityName;
+ final Intent parentIntent = parentActivity == null
+ ? Intent.makeMainActivity(target)
+ : new Intent().setComponent(target);
+ return parentIntent;
+ } catch (NameNotFoundException e) {
+ Log.e(TAG, "getParentActivityIntent: bad parentActivityName '" + parentName +
+ "' in manifest");
+ return null;
+ }
}
// ------------------ Internal API ------------------
diff --git a/core/java/android/app/TaskStackBuilder.java b/core/java/android/app/TaskStackBuilder.java
index f21b3fd..9c83362 100644
--- a/core/java/android/app/TaskStackBuilder.java
+++ b/core/java/android/app/TaskStackBuilder.java
@@ -124,24 +124,12 @@
* @return This TaskStackBuilder for method chaining
*/
public TaskStackBuilder addParentStack(Activity sourceActivity) {
- final int insertAt = mIntents.size();
- Intent parent = sourceActivity.getParentActivityIntent();
- PackageManager pm = sourceActivity.getPackageManager();
- while (parent != null) {
- mIntents.add(insertAt, parent);
- try {
- ActivityInfo info = pm.getActivityInfo(parent.getComponent(), 0);
- String parentActivity = info.parentActivityName;
- if (parentActivity != null) {
- parent = new Intent().setComponent(
- new ComponentName(mSourceContext, parentActivity));
- } else {
- parent = null;
- }
- } catch (NameNotFoundException e) {
- Log.e(TAG, "Bad ComponentName while traversing activity parent metadata");
- throw new IllegalArgumentException(e);
- }
+ final Intent parent = sourceActivity.getParentActivityIntent();
+ if (parent != null) {
+ // We have the actual parent intent, build the rest from static metadata
+ // then add the direct parent intent to the end.
+ addParentStack(parent.getComponent());
+ addNextIntent(parent);
}
return this;
}
@@ -155,24 +143,7 @@
* @return This TaskStackBuilder for method chaining
*/
public TaskStackBuilder addParentStack(Class<?> sourceActivityClass) {
- final int insertAt = mIntents.size();
- PackageManager pm = mSourceContext.getPackageManager();
- try {
- ActivityInfo info = pm.getActivityInfo(
- new ComponentName(mSourceContext, sourceActivityClass), 0);
- String parentActivity = info.parentActivityName;
- while (parentActivity != null) {
- Intent parent = new Intent().setComponent(
- new ComponentName(mSourceContext, parentActivity));
- mIntents.add(insertAt, parent);
- info = pm.getActivityInfo(parent.getComponent(), 0);
- parentActivity = info.parentActivityName;
- }
- } catch (NameNotFoundException e) {
- Log.e(TAG, "Bad ComponentName while traversing activity parent metadata");
- throw new IllegalArgumentException(e);
- }
- return this;
+ return addParentStack(new ComponentName(mSourceContext, sourceActivityClass));
}
/**
@@ -191,11 +162,13 @@
ActivityInfo info = pm.getActivityInfo(sourceActivityName, 0);
String parentActivity = info.parentActivityName;
while (parentActivity != null) {
- Intent parent = new Intent().setComponent(
- new ComponentName(info.packageName, parentActivity));
- mIntents.add(insertAt, parent);
- info = pm.getActivityInfo(parent.getComponent(), 0);
+ final ComponentName target = new ComponentName(mSourceContext, parentActivity);
+ info = pm.getActivityInfo(target, 0);
parentActivity = info.parentActivityName;
+ final Intent parent = parentActivity == null && insertAt == 0
+ ? Intent.makeMainActivity(target)
+ : new Intent().setComponent(target);
+ mIntents.add(insertAt, parent);
}
} catch (NameNotFoundException e) {
Log.e(TAG, "Bad ComponentName while traversing activity parent metadata");
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index f3dbecb..a182234 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -3236,7 +3236,7 @@
public static final String DISPLAY_DENSITY_FORCED = Global.DISPLAY_DENSITY_FORCED;
/**
- * @deprecated Use {@link android.provider.Settings.Global#ASSISTED_GPS_ENABLE} instead
+ * @deprecated Use {@link android.provider.Settings.Global#ASSISTED_GPS_ENABLED} instead
* @hide
*/
@Deprecated
@@ -4345,21 +4345,18 @@
"sync_max_retry_delay_in_seconds";
/**
- * The interval in milliseconds at which to check the number of SMS sent
- * out without asking for use permit, to limit the un-authorized SMS
- * usage.
+ * @deprecated Use {@link Settings.Global#SMS_OUTGOING_CHECK_INTERVAL_MS} instead.
* @hide
*/
public static final String SMS_OUTGOING_CHECK_INTERVAL_MS =
- "sms_outgoing_check_interval_ms";
+ Global.SMS_OUTGOING_CHECK_INTERVAL_MS;
/**
- * The number of outgoing SMS sent without asking for user permit
- * (of {@link #SMS_OUTGOING_CHECK_INTERVAL_MS}
+ * @deprecated Use {@link Settings.Global#SMS_OUTGOING_CHECK_MAX_COUNT} instead.
* @hide
*/
public static final String SMS_OUTGOING_CHECK_MAX_COUNT =
- "sms_outgoing_check_max_count";
+ Global.SMS_OUTGOING_CHECK_MAX_COUNT;
/**
* The global search provider chosen by the user (if multiple global
@@ -4861,13 +4858,6 @@
"contacts_preauth_uri_expiration";
/**
- * Prefix for SMS short code regex patterns (country code is appended).
- * @see com.android.internal.telephony.SmsUsageMonitor
- * @hide
- */
- public static final String SMS_SHORT_CODES_PREFIX = "sms_short_codes_";
-
- /**
* Overlay display devices setting.
* The associated value is a specially formatted string that describes the
* size and density of simulated secondary display devices.
@@ -5341,6 +5331,13 @@
* {@hide} */
public static final String PACKAGE_VERIFIER_DEFAULT_RESPONSE = "verifier_default_response";
+ /** Show package verification setting in the Settings app.
+ * 1 = show (default)
+ * 0 = hide
+ * {@hide}
+ */
+ public static final String PACKAGE_VERIFIER_SETTING_VISIBLE = "verifier_setting_visible";
+
/**
* The interval in milliseconds at which to check packet counts on the
* mobile data interface when screen is on, to detect possible data
@@ -5427,6 +5424,38 @@
"setup_prepaid_detection_redir_host";
/**
+ * The interval in milliseconds at which to check the number of SMS sent out without asking
+ * for use permit, to limit the un-authorized SMS usage.
+ *
+ * @hide
+ */
+ public static final String SMS_OUTGOING_CHECK_INTERVAL_MS =
+ "sms_outgoing_check_interval_ms";
+
+ /**
+ * The number of outgoing SMS sent without asking for user permit (of {@link
+ * #SMS_OUTGOING_CHECK_INTERVAL_MS}
+ *
+ * @hide
+ */
+ public static final String SMS_OUTGOING_CHECK_MAX_COUNT =
+ "sms_outgoing_check_max_count";
+
+ /**
+ * Used to disable SMS short code confirmation - defaults to true.
+ * @see com.android.internal.telephony.SmsUsageMonitor
+ * @hide
+ */
+ public static final String SMS_SHORT_CODE_CONFIRMATION = "sms_short_code_confirmation";
+
+ /**
+ * Prefix for SMS short code regex patterns (country code is appended).
+ * @see com.android.internal.telephony.SmsUsageMonitor
+ * @hide
+ */
+ public static final String SMS_SHORT_CODES_PREFIX = "sms_short_codes_";
+
+ /**
* Used to disable Tethering on a device - defaults to true
* @hide
*/
diff --git a/core/java/android/view/ScaleGestureDetector.java b/core/java/android/view/ScaleGestureDetector.java
index bcb8800..fa03139 100644
--- a/core/java/android/view/ScaleGestureDetector.java
+++ b/core/java/android/view/ScaleGestureDetector.java
@@ -137,6 +137,7 @@
private long mPrevTime;
private boolean mInProgress;
private int mSpanSlop;
+ private int mMinSpan;
/**
* Consistency verifier for debugging purposes.
@@ -149,6 +150,8 @@
mContext = context;
mListener = listener;
mSpanSlop = ViewConfiguration.get(context).getScaledTouchSlop() * 2;
+ mMinSpan = context.getResources().getDimensionPixelSize(
+ com.android.internal.R.dimen.config_minScalingSpan);
}
/**
@@ -209,8 +212,11 @@
float devSumX = 0, devSumY = 0;
for (int i = 0; i < count; i++) {
if (skipIndex == i) continue;
- devSumX += Math.abs(event.getX(i) - focusX);
- devSumY += Math.abs(event.getY(i) - focusY);
+
+ // Average touch major and touch minor and convert the resulting diameter into a radius.
+ final float touchSize = (event.getTouchMajor(i) + event.getTouchMinor(i)) / 4;
+ devSumX += Math.abs(event.getX(i) - focusX) + touchSize;
+ devSumY += Math.abs(event.getY(i) - focusY) + touchSize;
}
final float devX = devSumX / div;
final float devY = devSumY / div;
@@ -228,7 +234,7 @@
final boolean wasInProgress = mInProgress;
mFocusX = focusX;
mFocusY = focusY;
- if (mInProgress && (span == 0 || configChanged)) {
+ if (mInProgress && (span < mMinSpan || configChanged)) {
mListener.onScaleEnd(this);
mInProgress = false;
mInitialSpan = span;
@@ -238,7 +244,7 @@
mPrevSpanY = mCurrSpanY = spanY;
mInitialSpan = mPrevSpan = mCurrSpan = span;
}
- if (!mInProgress && span != 0 &&
+ if (!mInProgress && span >= mMinSpan &&
(wasInProgress || Math.abs(span - mInitialSpan) > mSpanSlop)) {
mPrevSpanX = mCurrSpanX = spanX;
mPrevSpanY = mCurrSpanY = spanY;
diff --git a/core/res/res/anim/screen_user_enter.xml b/core/res/res/anim/screen_user_enter.xml
index a73dea3..cb0a634 100644
--- a/core/res/res/anim/screen_user_enter.xml
+++ b/core/res/res/anim/screen_user_enter.xml
@@ -17,9 +17,6 @@
-->
<set xmlns:android="http://schemas.android.com/apk/res/android">
- <translate android:fromXDelta="100%p" android:toXDelta="0"
- android:duration="500"
- android:interpolator="@interpolator/decelerate_quad" />
<alpha android:fromAlpha="0.0" android:toAlpha="1.0"
android:duration="500"
android:interpolator="@interpolator/decelerate_quad" />
diff --git a/core/res/res/anim/screen_user_exit.xml b/core/res/res/anim/screen_user_exit.xml
index ec94b76..3d465be 100644
--- a/core/res/res/anim/screen_user_exit.xml
+++ b/core/res/res/anim/screen_user_exit.xml
@@ -17,9 +17,6 @@
-->
<set xmlns:android="http://schemas.android.com/apk/res/android">
- <translate android:fromXDelta="0" android:toXDelta="-100%p"
- android:duration="500"
- android:interpolator="@interpolator/decelerate_quad" />
<alpha android:fromAlpha="1.0" android:toAlpha="0.0"
android:duration="500"
android:interpolator="@interpolator/decelerate_quad" />
diff --git a/core/res/res/drawable-hdpi/panel_bg_holo_dark.9.png b/core/res/res/drawable-hdpi/panel_bg_holo_dark.9.png
index 1b4fed8..a5ac279 100644
--- a/core/res/res/drawable-hdpi/panel_bg_holo_dark.9.png
+++ b/core/res/res/drawable-hdpi/panel_bg_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/panel_bg_holo_light.9.png b/core/res/res/drawable-hdpi/panel_bg_holo_light.9.png
index c8b3177..583865e 100644
--- a/core/res/res/drawable-hdpi/panel_bg_holo_light.9.png
+++ b/core/res/res/drawable-hdpi/panel_bg_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/panel_bg_holo_dark.9.png b/core/res/res/drawable-mdpi/panel_bg_holo_dark.9.png
index 8c51b01..588eb3c 100644
--- a/core/res/res/drawable-mdpi/panel_bg_holo_dark.9.png
+++ b/core/res/res/drawable-mdpi/panel_bg_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/panel_bg_holo_light.9.png b/core/res/res/drawable-mdpi/panel_bg_holo_light.9.png
index f4a25bc..c1cdbc7 100644
--- a/core/res/res/drawable-mdpi/panel_bg_holo_light.9.png
+++ b/core/res/res/drawable-mdpi/panel_bg_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/panel_bg_holo_dark.9.png b/core/res/res/drawable-xhdpi/panel_bg_holo_dark.9.png
index 0cf7ac8..aaf6d8b 100644
--- a/core/res/res/drawable-xhdpi/panel_bg_holo_dark.9.png
+++ b/core/res/res/drawable-xhdpi/panel_bg_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/panel_bg_holo_light.9.png b/core/res/res/drawable-xhdpi/panel_bg_holo_light.9.png
index 9bdf3f1..6ea7615 100644
--- a/core/res/res/drawable-xhdpi/panel_bg_holo_light.9.png
+++ b/core/res/res/drawable-xhdpi/panel_bg_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable/kg_avatar_overlay.xml b/core/res/res/drawable/kg_avatar_overlay.xml
new file mode 100644
index 0000000..781c1df
--- /dev/null
+++ b/core/res/res/drawable/kg_avatar_overlay.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2012 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.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:state_pressed="true"
+ android:drawable="@drawable/activity_picker_bg_activated" />
+</selector>
\ No newline at end of file
diff --git a/core/res/res/layout/keyguard_multi_user_avatar.xml b/core/res/res/layout/keyguard_multi_user_avatar.xml
index 9999177..23f9b6d 100644
--- a/core/res/res/layout/keyguard_multi_user_avatar.xml
+++ b/core/res/res/layout/keyguard_multi_user_avatar.xml
@@ -23,9 +23,11 @@
android:layout_width="125dp"
android:layout_height="125dp"
android:background="#550000ff"
- android:gravity="center_horizontal">
+ android:gravity="center_horizontal"
+ android:foreground="@drawable/kg_avatar_overlay">
<ImageView
android:id="@+id/keyguard_user_avatar"
+ android:scaleType="centerCrop"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"/>
diff --git a/core/res/res/layout/keyguard_multi_user_selector.xml b/core/res/res/layout/keyguard_multi_user_selector.xml
index 3ed9103..c599fd5dd 100644
--- a/core/res/res/layout/keyguard_multi_user_selector.xml
+++ b/core/res/res/layout/keyguard_multi_user_selector.xml
@@ -19,23 +19,15 @@
<com.android.internal.policy.impl.keyguard.KeyguardMultiUserSelectorView
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
- android:layout_width="375dp"
- android:layout_height="wrap_content"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
android:layout_gravity="center">
- <include
- android:id="@+id/keyguard_active_user"
- android:layout_width="250dp"
- android:layout_height="250dp"
- layout="@layout/keyguard_multi_user_avatar"/>
+ <com.android.internal.policy.impl.keyguard.KeyguardSubdivisionLayout
+ android:id="@+id/keyguard_users_grid"
+ android:orientation="horizontal"
+ android:layout_width="300dp"
+ android:layout_height="300dp"
+ android:layout_gravity="center" />
- <ScrollView
- android:layout_width="125dp"
- android:layout_height="250dp">
- <LinearLayout
- android:id="@+id/keyguard_inactive_users"
- android:orientation="vertical"
- layout_width="match_parent"
- layout_height="wrap_content"/>
- </ScrollView>
</com.android.internal.policy.impl.keyguard.KeyguardMultiUserSelectorView>
\ No newline at end of file
diff --git a/core/res/res/layout/sms_short_code_confirmation_dialog.xml b/core/res/res/layout/sms_short_code_confirmation_dialog.xml
new file mode 100644
index 0000000..ed08375
--- /dev/null
+++ b/core/res/res/layout/sms_short_code_confirmation_dialog.xml
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2012 The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/parentPanel"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="8dip"
+ android:layout_marginRight="8dip"
+ android:orientation="vertical">
+
+ <TextView android:id="@+id/sms_short_code_confirm_message"
+ style="?android:attr/textAppearanceMedium"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingLeft="16dip"
+ android:paddingRight="16dip"
+ android:paddingTop="8dip"
+ android:paddingBottom="8dip"/>
+
+ <LinearLayout android:id="@+id/sms_short_code_detail_layout"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ android:gravity="center_vertical"
+ android:minHeight="@dimen/alert_dialog_title_height"
+ android:layout_marginLeft="16dip"
+ android:layout_marginRight="16dip">
+ <ImageView android:id="@+id/sms_short_code_coins_icon"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:paddingRight="8dip"
+ android:src="@null" />
+ <TextView android:id="@+id/sms_short_code_detail_message"
+ style="?android:attr/textAppearanceMedium"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" />
+ </LinearLayout>
+
+ <CheckBox android:id="@+id/sms_short_code_remember_choice_checkbox"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/sms_short_code_remember_choice" />
+</LinearLayout>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 7895489..93d7fcc 100755
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -925,4 +925,16 @@
<!-- Maximum number of supported users -->
<integer name="config_multiuserMaximumUsers">1</integer>
+
+ <!-- Minimum span needed to begin a touch scaling gesture.
+ If the span is equal to or greater than this size, a scaling gesture
+ will begin, where supported. (See android.view.ScaleGestureDetector)
+
+ This also takes into account the size of any active touch points.
+ Devices with screens that deviate too far from their assigned density
+ bucket should consider tuning this value in a device-specific overlay.
+ For best results, care should be taken such that this value remains
+ larger than the minimum reported touchMajor/touchMinor values
+ reported by the hardware. -->
+ <dimen name="config_minScalingSpan">25mm</dimen>
</resources>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index dcb2ff2..73a61b6 100755
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -1258,26 +1258,26 @@
such as GPS or location providers.</string>
<!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
- <string name="permlab_accessFineLocation">precise (GPS) location</string>
+ <string name="permlab_accessFineLocation">precise location (GPS and
+ network-based)</string>
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
- <string name="permdesc_accessFineLocation" product="tablet">Access precise
- location sources such as the Global Positioning System on the tablet. When
- location services are available and turned on, this permission allows the
- app to determine your precise location.</string>
- <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
- <string name="permdesc_accessFineLocation" product="default">Access precise
- location sources such as the Global Positioning System on the phone. When
- location services are available and turned on, this permission allows the
- app to determine your precise location.</string>
+ <string name="permdesc_accessFineLocation">Allows the app to get your
+ precise location using the Global Positioning System (GPS) or network
+ location sources such as cell towers and Wi-Fi. These location services
+ must be turned on and available to your device for the app to use them.
+ Apps may use this to determine where you are, and may consume additional
+ battery power.</string>
<!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
- <string name="permlab_accessCoarseLocation">approximate (network-based) location</string>
+ <string name="permlab_accessCoarseLocation">approximate location
+ (network-based)</string>
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
- <string name="permdesc_accessCoarseLocation">Access
- approximate location from location providers using network sources such as
- cell tower and Wi-Fi. When these location services are available and turned
- on, this permission allows the app to determine your approximate
- location.</string>
+ <string name="permdesc_accessCoarseLocation">Allows the app to get your
+ approximate location. This location is derived by location services using
+ network location sources such as cell towers and Wi-Fi. These location
+ services must be turned on and available to your device for the app to
+ use them. Apps may use this to determine approximately where you
+ are.</string>
<!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permlab_accessSurfaceFlinger">access SurfaceFlinger</string>
@@ -3092,20 +3092,22 @@
<string name="sms_control_no">Deny</string>
<!-- SMS short code verification dialog. --> <skip />
- <!-- The dialog title for the SMS short code confirmation dialog. [CHAR LIMIT=30] -->
- <string name="sms_short_code_confirm_title">Send SMS to short code?</string>
- <!-- The dialog title for the SMS premium short code confirmation dialog. [CHAR LIMIT=30] -->
- <string name="sms_premium_short_code_confirm_title">Send premium SMS?</string>
<!-- The message text for the SMS short code confirmation dialog. [CHAR LIMIT=NONE] -->
- <string name="sms_short_code_confirm_message"><b><xliff:g id="app_name">%1$s</xliff:g></b> would like to send a text message to <b><xliff:g id="dest_address">%2$s</xliff:g></b>, which appears to be an SMS short code.<p>Sending text messages to some short codes may cause your mobile account to be billed for premium services.<p>Do you want to allow this app to send the message?</string>
- <!-- The message text for the SMS short code confirmation dialog. [CHAR LIMIT=NONE] -->
- <string name="sms_premium_short_code_confirm_message"><b><xliff:g id="app_name">%1$s</xliff:g></b> would like to send a text message to <b><xliff:g id="dest_address">%2$s</xliff:g></b>, which is a premium SMS short code.<p><b>Sending a message to this destination will cause your mobile account to be billed for premium services.</b><p>Do you want to allow this app to send the message?</string>
- <!-- Text of the approval button for the SMS short code confirmation dialog. [CHAR LIMIT=50] -->
- <string name="sms_short_code_confirm_allow">Send message</string>
+ <string name="sms_short_code_confirm_message"><b><xliff:g id="app_name">%1$s</xliff:g></b> would like to send a message to <b><xliff:g id="dest_address">%2$s</xliff:g></b>.</string>
+ <!-- Message details for the SMS short code confirmation dialog (possible premium short code). [CHAR LIMIT=NONE] -->
+ <string name="sms_short_code_details">This may cause charges on your mobile account.</string>
+ <!-- Message details for the SMS short code confirmation dialog (premium short code). [CHAR LIMIT=NONE] -->
+ <string name="sms_premium_short_code_details">This will cause charges on your mobile account.</string>
+ <!-- Text of the approval button for the SMS short code confirmation dialog. [CHAR LIMIT=30] -->
+ <string name="sms_short_code_confirm_allow">Send</string>
<!-- Text of the cancel button for the SMS short code confirmation dialog. [CHAR LIMIT=30] -->
- <string name="sms_short_code_confirm_deny">Don\'t send</string>
- <!-- Text of the button for the SMS short code confirmation dialog to report a malicious app. [CHAR LIMIT=30] -->
- <string name="sms_short_code_confirm_report">Report malicious app</string>
+ <string name="sms_short_code_confirm_deny">Cancel</string>
+ <!-- Text of the checkbox for the SMS short code confirmation dialog to remember the user's choice. [CHAR LIMIT=40] -->
+ <string name="sms_short_code_remember_choice">Remember my choice</string>
+ <!-- Text of the approval button for the SMS short code confirmation dialog when checkbox is checked. [CHAR LIMIT=30] -->
+ <string name="sms_short_code_confirm_always_allow">Always Allow</string>
+ <!-- Text of the cancel button for the SMS short code confirmation dialog when checkbox is checked. [CHAR LIMIT=30] -->
+ <string name="sms_short_code_confirm_never_allow">Never Allow</string>
<!-- SIM swap and device reboot Dialog --> <skip />
<!-- See SIM_REMOVED_DIALOG. This is the title of that dialog. -->
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index b9a1d64..2bfb06d 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -211,6 +211,10 @@
<java-symbol type="id" name="status_bar_latest_event_content" />
<java-symbol type="id" name="action_divider" />
<java-symbol type="id" name="overflow_divider" />
+ <java-symbol type="id" name="sms_short_code_confirm_message" />
+ <java-symbol type="id" name="sms_short_code_detail_layout" />
+ <java-symbol type="id" name="sms_short_code_detail_message" />
+ <java-symbol type="id" name="sms_short_code_remember_choice_checkbox" />
<java-symbol type="attr" name="actionModeShareDrawable" />
<java-symbol type="attr" name="alertDialogCenterButtons" />
@@ -739,13 +743,13 @@
<java-symbol type="string" name="sms_control_title" />
<java-symbol type="string" name="sms_control_no" />
<java-symbol type="string" name="sms_control_yes" />
- <java-symbol type="string" name="sms_premium_short_code_confirm_message" />
- <java-symbol type="string" name="sms_premium_short_code_confirm_title" />
<java-symbol type="string" name="sms_short_code_confirm_allow" />
<java-symbol type="string" name="sms_short_code_confirm_deny" />
+ <java-symbol type="string" name="sms_short_code_confirm_always_allow" />
+ <java-symbol type="string" name="sms_short_code_confirm_never_allow" />
<java-symbol type="string" name="sms_short_code_confirm_message" />
- <java-symbol type="string" name="sms_short_code_confirm_report" />
- <java-symbol type="string" name="sms_short_code_confirm_title" />
+ <java-symbol type="string" name="sms_short_code_details" />
+ <java-symbol type="string" name="sms_premium_short_code_details" />
<java-symbol type="string" name="submit" />
<java-symbol type="string" name="sync_binding_label" />
<java-symbol type="string" name="sync_do_nothing" />
@@ -1052,6 +1056,7 @@
<java-symbol type="layout" name="notification_template_inbox" />
<java-symbol type="layout" name="keyguard_multi_user_avatar" />
<java-symbol type="layout" name="keyguard_multi_user_selector_widget" />
+ <java-symbol type="layout" name="sms_short_code_confirmation_dialog" />
<java-symbol type="anim" name="slide_in_child_bottom" />
<java-symbol type="anim" name="slide_in_right" />
@@ -1113,6 +1118,8 @@
<java-symbol type="layout" name="media_route_list_item_collapse_group" />
<java-symbol type="string" name="bluetooth_a2dp_audio_route_name" />
+ <java-symbol type="dimen" name="config_minScalingSpan" />
+
<!-- From android.policy -->
<java-symbol type="anim" name="app_starting_exit" />
<java-symbol type="anim" name="lock_screen_behind_enter" />
@@ -1254,10 +1261,9 @@
<java-symbol type="id" name="pin_delete_button" />
<java-symbol type="id" name="keyguard_user_avatar" />
<java-symbol type="id" name="keyguard_user_name" />
- <java-symbol type="id" name="keyguard_active_user" />
- <java-symbol type="id" name="keyguard_inactive_users" />
<java-symbol type="id" name="keyguard_transport_control" />
<java-symbol type="id" name="keyguard_status_view" />
+ <java-symbol type="id" name="keyguard_users_grid" />
<java-symbol type="integer" name="config_carDockRotation" />
<java-symbol type="integer" name="config_defaultUiModeType" />
<java-symbol type="integer" name="config_deskDockRotation" />
diff --git a/core/tests/coretests/apks/install_bad_dex/Android.mk b/core/tests/coretests/apks/install_bad_dex/Android.mk
new file mode 100644
index 0000000..769a1b0
--- /dev/null
+++ b/core/tests/coretests/apks/install_bad_dex/Android.mk
@@ -0,0 +1,10 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+
+LOCAL_PACKAGE_NAME := install_bad_dex
+
+LOCAL_JAVA_RESOURCE_FILES := $(LOCAL_PATH)/classes.dex
+
+include $(FrameworkCoreTests_BUILD_PACKAGE)
diff --git a/core/tests/coretests/apks/install_bad_dex/AndroidManifest.xml b/core/tests/coretests/apks/install_bad_dex/AndroidManifest.xml
new file mode 100644
index 0000000..fe4dd8e
--- /dev/null
+++ b/core/tests/coretests/apks/install_bad_dex/AndroidManifest.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.frameworks.coretests.install_loc">
+
+ <application android:hasCode="true">
+ <activity
+ android:name="com.android.frameworks.coretests.TestActivity">
+ </activity>
+ </application>
+</manifest>
diff --git a/core/tests/coretests/apks/install_bad_dex/classes.dex b/core/tests/coretests/apks/install_bad_dex/classes.dex
new file mode 100644
index 0000000..284b6d4
--- /dev/null
+++ b/core/tests/coretests/apks/install_bad_dex/classes.dex
@@ -0,0 +1 @@
+This is a bad dex
diff --git a/core/tests/coretests/apks/install_bad_dex/res/values/strings.xml b/core/tests/coretests/apks/install_bad_dex/res/values/strings.xml
new file mode 100644
index 0000000..3b8b3b1
--- /dev/null
+++ b/core/tests/coretests/apks/install_bad_dex/res/values/strings.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!-- Just need this dummy file to have something to build. -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="dummy">dummy</string>
+</resources>
diff --git a/core/tests/coretests/apks/install_bad_dex/src/com/android/frameworks/coretests/TestActivity.java b/core/tests/coretests/apks/install_bad_dex/src/com/android/frameworks/coretests/TestActivity.java
new file mode 100644
index 0000000..10d0551
--- /dev/null
+++ b/core/tests/coretests/apks/install_bad_dex/src/com/android/frameworks/coretests/TestActivity.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.android.frameworks.coretests;
+
+import android.app.Activity;
+
+public class TestActivity extends Activity {
+
+}
diff --git a/core/tests/coretests/apks/install_jni_lib/Android.mk b/core/tests/coretests/apks/install_jni_lib/Android.mk
index de2993a..b61ea8e 100644
--- a/core/tests/coretests/apks/install_jni_lib/Android.mk
+++ b/core/tests/coretests/apks/install_jni_lib/Android.mk
@@ -23,6 +23,6 @@
libnativehelper
LOCAL_MODULE := libframeworks_coretests_jni
-LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_TAGS := tests
include $(BUILD_SHARED_LIBRARY)
diff --git a/core/tests/coretests/src/android/content/pm/PackageManagerTests.java b/core/tests/coretests/src/android/content/pm/PackageManagerTests.java
index 785842f..5881aa1 100755
--- a/core/tests/coretests/src/android/content/pm/PackageManagerTests.java
+++ b/core/tests/coretests/src/android/content/pm/PackageManagerTests.java
@@ -39,6 +39,7 @@
import android.os.ServiceManager;
import android.os.StatFs;
import android.os.SystemClock;
+import android.os.UserManager;
import android.os.storage.IMountService;
import android.os.storage.StorageListener;
import android.os.storage.StorageManager;
@@ -562,6 +563,14 @@
fail(pkgName + " shouldnt be installed");
} catch (NameNotFoundException e) {
}
+
+ UserManager um = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
+ List<UserInfo> users = um.getUsers();
+ for (UserInfo user : users) {
+ String dataDir = PackageManager.getDataDirForUser(user.id, pkgName);
+ assertFalse("Application data directory should not exist: " + dataDir,
+ new File(dataDir).exists());
+ }
}
class InstallParams {
@@ -707,9 +716,7 @@
PackageManager.GET_UNINSTALLED_PACKAGES);
GenericReceiver receiver = new DeleteReceiver(pkg.packageName);
invokeDeletePackage(pkg.packageName, 0, receiver);
- } catch (NameNotFoundException e1) {
- } catch (Exception e) {
- failStr(e);
+ } catch (NameNotFoundException e) {
}
}
try {
@@ -3476,6 +3483,12 @@
assertNotNull("signatures should not be null", packageInfo.signatures);
}
+ public void testInstall_BadDex_CleanUp() throws Exception {
+ int retCode = PackageManager.INSTALL_FAILED_DEXOPT;
+ installFromRawResource("install.apk", R.raw.install_bad_dex, 0, true, true, retCode,
+ PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
+ }
+
/*---------- Recommended install location tests ----*/
/*
* TODO's
diff --git a/graphics/jni/Android.mk b/graphics/jni/Android.mk
index e85a23c..80d7728 100644
--- a/graphics/jni/Android.mk
+++ b/graphics/jni/Android.mk
@@ -32,6 +32,6 @@
LOCAL_MODULE:= librs_jni
LOCAL_ADDITIONAL_DEPENDENCIES += $(rs_generated_source)
LOCAL_MODULE_TAGS := optional
-LOCAL_REQUIRED_MODULES := libRS
+LOCAL_REQUIRED_MODULES := libRS libRSDriver
include $(BUILD_SHARED_LIBRARY)
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardHostView.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardHostView.java
index 95f8500..8fe28a3 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardHostView.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardHostView.java
@@ -86,6 +86,11 @@
void show();
}
+ /*package*/ interface UserSwitcherCallback {
+ void hideSecurityView(int duration);
+ void showSecurityView();
+ }
+
public KeyguardHostView(Context context) {
this(context, null);
}
@@ -348,6 +353,7 @@
(failedAttemptsBeforeWipe - failedAttempts)
: Integer.MAX_VALUE; // because DPM returns 0 if no restriction
+ boolean showTimeout = false;
if (remainingBeforeWipe < LockPatternUtils.FAILED_ATTEMPTS_BEFORE_WIPE_GRACE) {
// If we reach this code, it means the user has installed a DevicePolicyManager
// that requests device wipe after N attempts. Once we get below the grace
@@ -361,7 +367,7 @@
showWipeDialog(failedAttempts);
}
} else {
- boolean showTimeout =
+ showTimeout =
(failedAttempts % LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT) == 0;
if (usingPattern && mEnableFallback) {
if (failedAttempts == failedAttemptWarning) {
@@ -374,12 +380,12 @@
showTimeout = false;
}
}
- if (showTimeout) {
- showTimeoutDialog();
- }
}
monitor.reportFailedUnlockAttempt();
mLockPatternUtils.reportFailedPasswordAttempt();
+ if (showTimeout) {
+ showTimeoutDialog();
+ }
}
/**
@@ -690,11 +696,27 @@
List<UserInfo> users = mUm.getUsers();
if (users.size() > 1) {
- KeyguardWidgetFrame userswitcher = (KeyguardWidgetFrame)
+ KeyguardWidgetFrame userSwitcher = (KeyguardWidgetFrame)
LayoutInflater.from(mContext).inflate(R.layout.keyguard_multi_user_selector_widget,
mAppWidgetContainer, false);
- // add the switcher to the left of status view
- mAppWidgetContainer.addView(userswitcher, getWidgetPosition(R.id.keyguard_status_view));
+
+ // add the switcher in the first position
+ mAppWidgetContainer.addView(userSwitcher, getWidgetPosition(R.id.keyguard_status_view));
+ KeyguardMultiUserSelectorView multiUser = (KeyguardMultiUserSelectorView)
+ userSwitcher.getChildAt(0);
+
+ UserSwitcherCallback callback = new UserSwitcherCallback() {
+ @Override
+ public void hideSecurityView(int duration) {
+ mSecurityViewContainer.animate().alpha(0).setDuration(duration);
+ }
+
+ @Override
+ public void showSecurityView() {
+ mSecurityViewContainer.setAlpha(1.0f);
+ }
+ };
+ multiUser.setCallback(callback);
}
}
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardMultiUserAvatar.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardMultiUserAvatar.java
index 8aef68f..759068d 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardMultiUserAvatar.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardMultiUserAvatar.java
@@ -16,16 +16,17 @@
package com.android.internal.policy.impl.keyguard;
-import android.app.ActivityManagerNative;
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.ValueAnimator;
+import android.animation.ValueAnimator.AnimatorUpdateListener;
import android.content.Context;
import android.content.pm.UserInfo;
+import android.graphics.Color;
import android.graphics.drawable.Drawable;
-import android.os.RemoteException;
import android.util.AttributeSet;
-import android.util.Log;
import android.view.LayoutInflater;
-import android.view.View;
-import android.view.WindowManagerGlobal;
+import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView;
@@ -33,11 +34,15 @@
import com.android.internal.R;
class KeyguardMultiUserAvatar extends FrameLayout {
- private static final String TAG = "KeyguardViewHost";
private ImageView mUserImage;
private TextView mUserName;
private UserInfo mUserInfo;
+ private static final int INACTIVE_COLOR = 85;
+ private static final int INACTIVE_ALPHA = 195;
+ private static final float ACTIVE_SCALE = 1.1f;
+ private boolean mActive;
+ private boolean mInit = true;
private KeyguardMultiUserSelectorView mUserSelector;
public static KeyguardMultiUserAvatar fromXml(int resId, Context context,
@@ -73,17 +78,86 @@
mUserImage.setImageDrawable(Drawable.createFromPath(mUserInfo.iconPath));
mUserName.setText(mUserInfo.name);
- setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- try {
- ActivityManagerNative.getDefault().switchUser(mUserInfo.id);
- WindowManagerGlobal.getWindowManagerService().lockNow();
- mUserSelector.init();
- } catch (RemoteException re) {
- Log.e(TAG, "Couldn't switch user " + re);
+ setOnClickListener(mUserSelector);
+ setActive(false, false, 0, null);
+ mInit = false;
+ }
+
+ public void setActive(boolean active, boolean animate, int duration, final Runnable onComplete) {
+ if (mActive != active || mInit) {
+ mActive = active;
+ final int finalFilterAlpha = mActive ? 0 : INACTIVE_ALPHA;
+ final int initFilterAlpha = mActive ? INACTIVE_ALPHA : 0;
+
+ final float finalScale = mActive ? ACTIVE_SCALE : 1.0f;
+ final float initScale = mActive ? 1.0f : ACTIVE_SCALE;
+
+ if (active) {
+ KeyguardSubdivisionLayout parent = (KeyguardSubdivisionLayout) getParent();
+ parent.setTopChild(parent.indexOfChild(this));
+ }
+
+ if (animate) {
+ ValueAnimator va = ValueAnimator.ofFloat(0f, 1f);
+ va.addUpdateListener(new AnimatorUpdateListener() {
+ @Override
+ public void onAnimationUpdate(ValueAnimator animation) {
+ float r = animation.getAnimatedFraction();
+ float scale = (1 - r) * initScale + r * finalScale;
+ int filterAlpha = (int) ((1 - r) * initFilterAlpha + r * finalFilterAlpha);
+ setScaleX(scale);
+ setScaleY(scale);
+ mUserImage.setColorFilter(Color.argb(filterAlpha, INACTIVE_COLOR,
+ INACTIVE_COLOR, INACTIVE_COLOR));
+ mUserSelector.invalidate();
+
+ }
+ });
+ va.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ if (onComplete != null) {
+ onComplete.run();
+ }
+ }
+ });
+ va.setDuration(duration);
+ va.start();
+ } else {
+ setScaleX(finalScale);
+ setScaleY(finalScale);
+ mUserImage.setColorFilter(Color.argb(finalFilterAlpha, INACTIVE_COLOR,
+ INACTIVE_COLOR, INACTIVE_COLOR));
+ if (onComplete != null) {
+ post(onComplete);
}
}
+ }
+ }
+
+ boolean mLockDrawableState = false;
+
+ public void lockDrawableState() {
+ mLockDrawableState = true;
+ }
+
+ public void resetDrawableState() {
+ mLockDrawableState = false;
+ post(new Runnable() {
+ @Override
+ public void run() {
+ refreshDrawableState();
+ }
});
}
+
+ protected void drawableStateChanged() {
+ if (!mLockDrawableState) {
+ super.drawableStateChanged();
+ }
+ }
+
+ public UserInfo getUserInfo() {
+ return mUserInfo;
+ }
}
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardMultiUserSelectorView.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardMultiUserSelectorView.java
index ba99a55..01d5d8c 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardMultiUserSelectorView.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardMultiUserSelectorView.java
@@ -22,15 +22,26 @@
import android.os.RemoteException;
import android.os.UserManager;
import android.util.AttributeSet;
-import android.widget.LinearLayout;
+import android.util.Log;
+import android.view.View;
+import android.view.WindowManagerGlobal;
+import android.widget.FrameLayout;
import com.android.internal.R;
+import com.android.internal.policy.impl.keyguard.KeyguardHostView.UserSwitcherCallback;
import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
-public class KeyguardMultiUserSelectorView extends LinearLayout{
- private KeyguardMultiUserAvatar mActiveUser;
- private LinearLayout mInactiveUsers;
+public class KeyguardMultiUserSelectorView extends FrameLayout implements View.OnClickListener {
+ private static final String TAG = "KeyguardMultiUserSelectorView";
+
+ private KeyguardSubdivisionLayout mUsersGrid;
+ private KeyguardMultiUserAvatar mActiveUserAvatar;
+ private UserSwitcherCallback mCallback;
+ private static final int SWITCH_ANIMATION_DURATION = 150;
+ private static final int FADE_OUT_ANIMATION_DURATION = 100;
public KeyguardMultiUserSelectorView(Context context) {
this(context, null, 0);
@@ -48,37 +59,77 @@
init();
}
+ public void setCallback(UserSwitcherCallback callback) {
+ mCallback = callback;
+ }
+
public void init() {
- mActiveUser = (KeyguardMultiUserAvatar) findViewById(R.id.keyguard_active_user);
- mInactiveUsers = (LinearLayout) findViewById(R.id.keyguard_inactive_users);
+ mUsersGrid = (KeyguardSubdivisionLayout) findViewById(R.id.keyguard_users_grid);
+ mUsersGrid.removeAllViews();
+ setClipChildren(false);
+ setClipToPadding(false);
- mInactiveUsers.removeAllViews();
-
- UserInfo currentUser;
+ UserInfo activeUser;
try {
- currentUser = ActivityManagerNative.getDefault().getCurrentUser();
+ activeUser = ActivityManagerNative.getDefault().getCurrentUser();
} catch (RemoteException re) {
- currentUser = null;
+ activeUser = null;
}
UserManager mUm = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
ArrayList<UserInfo> users = new ArrayList<UserInfo>(mUm.getUsers());
+ Collections.sort(users, mOrderAddedComparator);
+
for (UserInfo user: users) {
- if (user.id == currentUser.id) {
- setActiveUser(user);
- } else {
- createAndAddInactiveUser(user);
+ KeyguardMultiUserAvatar uv = createAndAddUser(user);
+ if (user.id == activeUser.id) {
+ mActiveUserAvatar = uv;
}
}
+ mActiveUserAvatar.setActive(true, false, 0, null);
}
- private void setActiveUser(UserInfo user) {
- mActiveUser.setup(user, this);
- }
+ Comparator<UserInfo> mOrderAddedComparator = new Comparator<UserInfo>() {
+ @Override
+ public int compare(UserInfo lhs, UserInfo rhs) {
+ return (lhs.serialNumber - rhs.serialNumber);
+ }
+ };
- private void createAndAddInactiveUser(UserInfo user) {
+ private KeyguardMultiUserAvatar createAndAddUser(UserInfo user) {
KeyguardMultiUserAvatar uv = KeyguardMultiUserAvatar.fromXml(
R.layout.keyguard_multi_user_avatar, mContext, this, user);
- mInactiveUsers.addView(uv);
+ mUsersGrid.addView(uv);
+ return uv;
+ }
+
+ @Override
+ public void onClick(View v) {
+ if (!(v instanceof KeyguardMultiUserAvatar)) return;
+ final KeyguardMultiUserAvatar avatar = (KeyguardMultiUserAvatar) v;
+ if (mActiveUserAvatar == avatar) {
+ // They clicked the active user, no need to do anything
+ return;
+ } else {
+ // Reset the previously active user to appear inactive
+ avatar.lockDrawableState();
+ mCallback.hideSecurityView(FADE_OUT_ANIMATION_DURATION);
+ mActiveUserAvatar.setActive(false, true, SWITCH_ANIMATION_DURATION, new Runnable() {
+ @Override
+ public void run() {
+ try {
+ ActivityManagerNative.getDefault().switchUser(avatar.getUserInfo().id);
+ WindowManagerGlobal.getWindowManagerService().lockNow();
+ // Set the new active user, and make it appear active
+ avatar.resetDrawableState();
+ mCallback.showSecurityView();
+ mActiveUserAvatar = avatar;
+ mActiveUserAvatar.setActive(true, false, 0, null);
+ } catch (RemoteException re) {
+ Log.e(TAG, "Couldn't switch user " + re);
+ }
+ }
+ });
+ }
}
}
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardPasswordView.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardPasswordView.java
index 7e9aa43..01f7af3 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardPasswordView.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardPasswordView.java
@@ -97,11 +97,17 @@
if (deadline != 0) {
handleAttemptLockout(deadline);
} else {
- mNavigationManager.setMessage(
- mIsAlpha ? R.string.kg_password_instructions : R.string.kg_pin_instructions);
+ resetState();
}
}
+ private void resetState() {
+ mNavigationManager.setMessage(
+ mIsAlpha ? R.string.kg_password_instructions : R.string.kg_pin_instructions);
+ mPasswordEntry.setEnabled(true);
+ mKeyboardView.setEnabled(true);
+ }
+
@Override
protected void onFinishInflate() {
mLockPatternUtils = new LockPatternUtils(mContext); // TODO: use common one
@@ -297,8 +303,7 @@
@Override
public void onFinish() {
- mPasswordEntry.setEnabled(true);
- mKeyboardView.setEnabled(true);
+ resetState();
}
}.start();
}
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardStatusViewManager.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardStatusViewManager.java
index e325f94..8d83484 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardStatusViewManager.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardStatusViewManager.java
@@ -54,7 +54,7 @@
private static final int BATTERY_INFO = 15;
private StatusMode mStatus;
- private String mDateFormatString;
+ private CharSequence mDateFormatString;
// Views that this class controls.
// NOTE: These may be null in some LockScreen screens and should protect from NPE
@@ -101,7 +101,8 @@
public KeyguardStatusViewManager(View view) {
if (DEBUG) Log.v(TAG, "KeyguardStatusViewManager()");
mContainer = view;
- mDateFormatString = getContext().getString(R.string.abbrev_wday_month_day_no_year);
+ mDateFormatString = getContext().getResources()
+ .getText(R.string.abbrev_wday_month_day_no_year);
mLockPatternUtils = new LockPatternUtils(view.getContext());
mUpdateMonitor = KeyguardUpdateMonitor.getInstance(view.getContext());
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSubdivisionLayout.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSubdivisionLayout.java
new file mode 100644
index 0000000..b7d94a9
--- /dev/null
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSubdivisionLayout.java
@@ -0,0 +1,212 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.internal.policy.impl.keyguard;
+
+import android.content.Context;
+import android.graphics.Rect;
+import android.util.AttributeSet;
+import android.view.View;
+import android.view.ViewGroup;
+
+import java.util.ArrayList;
+
+/**
+ * A layout that arranges its children into a special type of grid.
+ */
+public class KeyguardSubdivisionLayout extends ViewGroup {
+ ArrayList<BiTree> mCells = new ArrayList<BiTree>();
+ int mNumChildren = -1;
+ int mWidth = -1;
+ int mHeight = -1;
+ int mTopChild = 0;
+
+ public KeyguardSubdivisionLayout(Context context) {
+ this(context, null, 0);
+ }
+
+ public KeyguardSubdivisionLayout(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ public KeyguardSubdivisionLayout(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ setClipChildren(false);
+ setClipToPadding(false);
+ setChildrenDrawingOrderEnabled(true);
+ }
+
+ private class BiTree {
+ Rect rect;
+ BiTree left;
+ BiTree right;
+ int nodeDepth;
+ ArrayList<BiTree> leafs;
+
+ public BiTree(Rect r) {
+ rect = r;
+ }
+
+ public BiTree() {
+ }
+
+ boolean isLeaf() {
+ return (left == null) && (right == null);
+ }
+
+ int depth() {
+ if (left != null && right != null) {
+ return Math.max(left.depth(), right.depth()) + 1;
+ } else if (left != null) {
+ return left.depth() + 1;
+ } else if (right != null) {
+ return right.depth() + 1;
+ } else {
+ return 1;
+ }
+ }
+
+ int numLeafs() {
+ if (left != null && right != null) {
+ return left.numLeafs() + right.numLeafs();
+ } else if (left != null) {
+ return left.numLeafs();
+ } else if (right != null) {
+ return right.numLeafs();
+ } else {
+ return 1;
+ }
+ }
+
+ BiTree getNextNodeToBranch() {
+ if (leafs == null) {
+ leafs = new ArrayList<BiTree>();
+ }
+ leafs.clear();
+ getLeafs(leafs, 1);
+
+ // We find the first leaf who's depth is not
+ double r = log2(leafs.size());
+ if (Math.ceil(r) == Math.floor(r)) {
+ return leafs.get(leafs.size() - 1);
+ }
+
+ int treeDepth = depth();
+ for (int i = leafs.size() - 1; i >= 0; i--) {
+ BiTree n = leafs.get(i);
+ if (n.nodeDepth < treeDepth) {
+ return n;
+ }
+ }
+ return null;
+ }
+
+ // Gets leafs in left to right order
+ void getLeafs(ArrayList<BiTree> leafs, int depth) {
+ if (isLeaf()) {
+ this.nodeDepth = depth;
+ leafs.add(this);
+ } else {
+ if (left != null) {
+ left.getLeafs(leafs, depth + 1);
+ }
+ if (right != null) {
+ right.getLeafs(leafs, depth + 1);
+ }
+ }
+ }
+ }
+
+ double log2(double d) {
+ return Math.log(d) / Math.log(2);
+ }
+
+ private void addCell(BiTree tree) {
+ BiTree branch = tree.getNextNodeToBranch();
+ Rect r = branch.rect;
+ branch.left = new BiTree();
+ branch.right = new BiTree();
+ int newDepth = tree.depth();
+
+ // For each level of the tree, we alternate between horizontal and vertical division
+ if (newDepth % 2 == 0) {
+ // Divide the cell vertically
+ branch.left.rect = new Rect(r.left, r.top, r.right, r.top + r.height() / 2);
+ branch.right.rect = new Rect(r.left, r.top + r.height() / 2, r.right, r.bottom);
+ } else {
+ // Divide the cell horizontally
+ branch.left.rect = new Rect(r.left, r.top, r.left + r.width() / 2, r.bottom);
+ branch.right.rect = new Rect(r.left + r.width() / 2, r.top, r.right, r.bottom);
+ }
+ }
+
+ private void constructGrid(int width, int height, int numChildren) {
+ mCells.clear();
+ BiTree root = new BiTree(new Rect(0, 0, width, height));
+
+ // We add nodes systematically until the number of leafs matches the number of children
+ while (root.numLeafs() < numChildren) {
+ addCell(root);
+ }
+
+ // Spit out the final list of cells
+ root.getLeafs(mCells, 1);
+ }
+
+ @Override
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ int width = MeasureSpec.getSize(widthMeasureSpec);
+ int height = MeasureSpec.getSize(heightMeasureSpec);
+ int childCount = getChildCount();
+
+ if (mNumChildren != childCount || width != getMeasuredWidth() ||
+ height != getMeasuredHeight()) {
+ constructGrid(width, height, childCount);
+ }
+
+ for (int i = 0; i < childCount; i++) {
+ final View child = getChildAt(i);
+ Rect rect = mCells.get(i).rect;
+ child.measure(MeasureSpec.makeMeasureSpec(rect.width(), MeasureSpec.EXACTLY),
+ MeasureSpec.makeMeasureSpec(rect.height(), MeasureSpec.EXACTLY));
+ }
+ setMeasuredDimension(width, height);
+ }
+
+ @Override
+ protected void onLayout(boolean changed, int l, int t, int r, int b) {
+ int childCount = getChildCount();
+ for (int i = 0; i < childCount; i++) {
+ final View child = getChildAt(i);
+ Rect rect = mCells.get(i).rect;
+ child.layout(rect.left, rect.top, rect.right, rect.bottom);
+ }
+ }
+
+ public void setTopChild(int top) {
+ mTopChild = top;
+ invalidate();
+ }
+
+ protected int getChildDrawingOrder(int childCount, int i) {
+ int ret = i;
+ if (i == childCount - 1) {
+ ret = mTopChild;
+ } else if (i >= mTopChild){
+ ret = i + 1;
+ }
+ return ret;
+ }
+}
\ No newline at end of file
diff --git a/services/java/com/android/server/WifiService.java b/services/java/com/android/server/WifiService.java
index 5c3af79..68ac38a 100644
--- a/services/java/com/android/server/WifiService.java
+++ b/services/java/com/android/server/WifiService.java
@@ -16,6 +16,7 @@
package com.android.server;
+import android.app.ActivityManager;
import android.app.AlarmManager;
import android.app.Notification;
import android.app.NotificationManager;
@@ -55,6 +56,7 @@
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SystemProperties;
+import android.os.UserHandle;
import android.os.WorkSource;
import android.provider.Settings;
import android.text.TextUtils;
@@ -834,7 +836,11 @@
*/
public List<ScanResult> getScanResults() {
enforceAccessPermission();
- return mWifiStateMachine.syncGetScanResultsList();
+ if (UserHandle.getCallingUserId() != ActivityManager.getCurrentUser()) {
+ return new ArrayList<ScanResult>();
+ } else {
+ return mWifiStateMachine.syncGetScanResultsList();
+ }
}
/**
diff --git a/services/java/com/android/server/pm/PackageManagerService.java b/services/java/com/android/server/pm/PackageManagerService.java
index 2ef1f9e..ce52d2b 100644
--- a/services/java/com/android/server/pm/PackageManagerService.java
+++ b/services/java/com/android/server/pm/PackageManagerService.java
@@ -215,7 +215,7 @@
/**
* Whether verification is enabled by default.
*/
- private static final boolean DEFAULT_VERIFY_ENABLE = false;
+ private static final boolean DEFAULT_VERIFY_ENABLE = true;
/**
* The default maximum time to wait for the verification agent to return in
diff --git a/services/java/com/android/server/power/DisplayPowerState.java b/services/java/com/android/server/power/DisplayPowerState.java
index 3524a08..1bd7811 100644
--- a/services/java/com/android/server/power/DisplayPowerState.java
+++ b/services/java/com/android/server/power/DisplayPowerState.java
@@ -239,6 +239,7 @@
private void apply() {
if (mDirty != 0) {
if ((mDirty & DIRTY_SCREEN_ON) != 0 && !mScreenOn) {
+ mScreenBrightnessModulator.setBrightness(0, true /*sync*/);
PowerManagerService.nativeSetScreenState(false);
}
@@ -246,15 +247,16 @@
mElectronBeam.draw(mElectronBeamLevel);
}
- if ((mDirty & (DIRTY_BRIGHTNESS | DIRTY_SCREEN_ON | DIRTY_ELECTRON_BEAM)) != 0) {
- mScreenBrightnessModulator.setBrightness(mScreenOn ?
- (int)(mScreenBrightness * mElectronBeamLevel) : 0);
- }
-
if ((mDirty & DIRTY_SCREEN_ON) != 0 && mScreenOn) {
PowerManagerService.nativeSetScreenState(true);
}
+ if ((mDirty & (DIRTY_BRIGHTNESS | DIRTY_SCREEN_ON | DIRTY_ELECTRON_BEAM)) != 0
+ && mScreenOn) {
+ mScreenBrightnessModulator.setBrightness(
+ (int)(mScreenBrightness * mElectronBeamLevel), false /*sync*/);
+ }
+
mDirty = 0;
if (mCleanListener != null) {
diff --git a/services/java/com/android/server/power/PhotonicModulator.java b/services/java/com/android/server/power/PhotonicModulator.java
index f7c9c7d..c9b5d90 100644
--- a/services/java/com/android/server/power/PhotonicModulator.java
+++ b/services/java/com/android/server/power/PhotonicModulator.java
@@ -49,11 +49,12 @@
}
/**
- * Asynchronously sets the backlight brightness.
+ * Sets the backlight brightness, synchronously or asynchronously.
*
* @param lightValue The new light value, from 0 to 255.
+ * @param sync If true, waits for the brightness change to complete before returning.
*/
- public void setBrightness(int lightValue) {
+ public void setBrightness(int lightValue, boolean sync) {
synchronized (mLock) {
if (lightValue != mPendingLightValue) {
mPendingLightValue = lightValue;
@@ -63,6 +64,15 @@
mExecutor.execute(mTask);
}
}
+ if (sync) {
+ while (mPendingChange) {
+ try {
+ mLock.wait();
+ } catch (InterruptedException ex) {
+ // ignore it
+ }
+ }
+ }
}
}
@@ -76,6 +86,7 @@
if (newLightValue == mActualLightValue) {
mSuspendBlocker.release();
mPendingChange = false;
+ mLock.notifyAll();
return;
}
mActualLightValue = newLightValue;
diff --git a/services/java/com/android/server/wm/AppWindowAnimator.java b/services/java/com/android/server/wm/AppWindowAnimator.java
index c6b7e0d..2445b98 100644
--- a/services/java/com/android/server/wm/AppWindowAnimator.java
+++ b/services/java/com/android/server/wm/AppWindowAnimator.java
@@ -4,6 +4,7 @@
import android.graphics.Matrix;
import android.util.Slog;
+import android.view.Display;
import android.view.Surface;
import android.view.WindowManagerPolicy;
import android.view.animation.Animation;
@@ -134,11 +135,13 @@
thumbnailTransformation.clear();
thumbnailAnimation.getTransformation(currentTime, thumbnailTransformation);
thumbnailTransformation.getMatrix().preTranslate(thumbnailX, thumbnailY);
- final boolean screenAnimation = mAnimator.mScreenRotationAnimation != null
- && mAnimator.mScreenRotationAnimation.isAnimating();
+
+ ScreenRotationAnimation screenRotationAnimation =
+ mAnimator.getScreenRotationAnimationLocked(Display.DEFAULT_DISPLAY);
+ final boolean screenAnimation = screenRotationAnimation != null
+ && screenRotationAnimation.isAnimating();
if (screenAnimation) {
- thumbnailTransformation.postCompose(
- mAnimator.mScreenRotationAnimation.getEnterTransformation());
+ thumbnailTransformation.postCompose(screenRotationAnimation.getEnterTransformation());
}
// cache often used attributes locally
final float tmpFloats[] = mService.mTmpFloats;
diff --git a/services/java/com/android/server/wm/DimAnimator.java b/services/java/com/android/server/wm/DimAnimator.java
index 87a2880..9bca834 100644
--- a/services/java/com/android/server/wm/DimAnimator.java
+++ b/services/java/com/android/server/wm/DimAnimator.java
@@ -219,5 +219,13 @@
mDimHeight = o.mDimHeight;
mDimTarget = o.mDimTarget;
}
+
+ public void printTo(String prefix, PrintWriter pw) {
+ pw.print(prefix);
+ pw.print("mDimWinAnimator="); pw.print(mDimWinAnimator.mWin.mAttrs.getTitle());
+ pw.print(" "); pw.print(mDimWidth); pw.print(" x ");
+ pw.print(mDimHeight);
+ pw.print(" mDimTarget="); pw.println(mDimTarget);
+ }
}
}
diff --git a/services/java/com/android/server/wm/DisplayContent.java b/services/java/com/android/server/wm/DisplayContent.java
index d1742ff..3898ebc 100644
--- a/services/java/com/android/server/wm/DisplayContent.java
+++ b/services/java/com/android/server/wm/DisplayContent.java
@@ -101,31 +101,32 @@
mDisplay.getDisplayInfo(mDisplayInfo);
}
- public void dump(PrintWriter pw) {
- pw.print(" Display: mDisplayId="); pw.println(mDisplayId);
- pw.print(" init="); pw.print(mInitialDisplayWidth); pw.print("x");
- pw.print(mInitialDisplayHeight); pw.print(" "); pw.print(mInitialDisplayDensity);
- pw.print("dpi");
- if (mInitialDisplayWidth != mBaseDisplayWidth
- || mInitialDisplayHeight != mBaseDisplayHeight
- || mInitialDisplayDensity != mBaseDisplayDensity) {
- pw.print(" base=");
- pw.print(mBaseDisplayWidth); pw.print("x"); pw.print(mBaseDisplayHeight);
- pw.print(" "); pw.print(mBaseDisplayDensity); pw.print("dpi");
- }
- pw.print(" cur=");
- pw.print(mDisplayInfo.logicalWidth);
- pw.print("x"); pw.print(mDisplayInfo.logicalHeight);
- pw.print(" app=");
- pw.print(mDisplayInfo.appWidth);
- pw.print("x"); pw.print(mDisplayInfo.appHeight);
- pw.print(" rng="); pw.print(mDisplayInfo.smallestNominalAppWidth);
- pw.print("x"); pw.print(mDisplayInfo.smallestNominalAppHeight);
- pw.print("-"); pw.print(mDisplayInfo.largestNominalAppWidth);
- pw.print("x"); pw.println(mDisplayInfo.largestNominalAppHeight);
- pw.print(" layoutNeeded="); pw.println(layoutNeeded);
+ public void dump(String prefix, PrintWriter pw) {
+ pw.print(prefix); pw.print("Display: mDisplayId="); pw.println(mDisplayId);
+ final String subPrefix = " " + prefix;
+ pw.print(subPrefix); pw.print("init="); pw.print(mInitialDisplayWidth); pw.print("x");
+ pw.print(mInitialDisplayHeight); pw.print(" "); pw.print(mInitialDisplayDensity);
+ pw.print("dpi");
+ if (mInitialDisplayWidth != mBaseDisplayWidth
+ || mInitialDisplayHeight != mBaseDisplayHeight
+ || mInitialDisplayDensity != mBaseDisplayDensity) {
+ pw.print(" base=");
+ pw.print(mBaseDisplayWidth); pw.print("x"); pw.print(mBaseDisplayHeight);
+ pw.print(" "); pw.print(mBaseDisplayDensity); pw.print("dpi");
+ }
+ pw.print(" cur=");
+ pw.print(mDisplayInfo.logicalWidth);
+ pw.print("x"); pw.print(mDisplayInfo.logicalHeight);
+ pw.print(" app=");
+ pw.print(mDisplayInfo.appWidth);
+ pw.print("x"); pw.print(mDisplayInfo.appHeight);
+ pw.print(" rng="); pw.print(mDisplayInfo.smallestNominalAppWidth);
+ pw.print("x"); pw.print(mDisplayInfo.smallestNominalAppHeight);
+ pw.print("-"); pw.print(mDisplayInfo.largestNominalAppWidth);
+ pw.print("x"); pw.println(mDisplayInfo.largestNominalAppHeight);
+ pw.print(subPrefix); pw.print("layoutNeeded="); pw.print(layoutNeeded);
if (mMagnificationSpec != null) {
- pw.print(" mMagnificationSpec="); pw.println(mMagnificationSpec);
+ pw.print(" mMagnificationSpec="); pw.print(mMagnificationSpec);
}
pw.println();
}
diff --git a/services/java/com/android/server/wm/WindowAnimator.java b/services/java/com/android/server/wm/WindowAnimator.java
index cabe611..4494058 100644
--- a/services/java/com/android/server/wm/WindowAnimator.java
+++ b/services/java/com/android/server/wm/WindowAnimator.java
@@ -16,6 +16,7 @@
import android.os.SystemClock;
import android.util.Log;
import android.util.Slog;
+import android.util.SparseArray;
import android.util.SparseIntArray;
import android.view.Display;
import android.view.Surface;
@@ -39,8 +40,6 @@
final Context mContext;
final WindowManagerPolicy mPolicy;
- ArrayList<WinAnimatorList> mWinAnimatorLists = new ArrayList<WinAnimatorList>();
-
boolean mAnimating;
final Runnable mAnimationRunnable;
@@ -64,24 +63,19 @@
* is a long initialized to Long.MIN_VALUE so that it doesn't match this value on startup. */
private int mAnimTransactionSequence;
- /** The one and only screen rotation if one is happening */
- ScreenRotationAnimation mScreenRotationAnimation = null;
-
// Window currently running an animation that has requested it be detached
// from the wallpaper. This means we need to ensure the wallpaper is
// visible behind it in case it animates in a way that would allow it to be
// seen. If multiple windows satisfy this, use the lowest window.
WindowState mWindowDetachedWallpaper = null;
- DimSurface mWindowAnimationBackgroundSurface = null;
-
WindowStateAnimator mUniverseBackground = null;
int mAboveUniverseLayer = 0;
int mBulkUpdateParams = 0;
- DimAnimator mDimAnimator = null;
- DimAnimator.Parameters mDimParams = null;
+ SparseArray<DisplayContentsAnimator> mDisplayContentsAnimators =
+ new SparseArray<WindowAnimator.DisplayContentsAnimator>();
static final int WALLPAPER_ACTION_PENDING = 1;
int mPendingActions;
@@ -127,11 +121,18 @@
};
}
- void initializeLocked(final int layerStack) {
- mWindowAnimationBackgroundSurface =
- new DimSurface(mService.mFxSession, layerStack);
- mDimAnimator = new DimAnimator(mService.mFxSession, layerStack);
- mInitialized = true;
+ void addDisplayLocked(final int displayId) {
+ DisplayContentsAnimator displayAnimator = getDisplayContentsAnimatorLocked(displayId);
+ displayAnimator.mWindowAnimationBackgroundSurface =
+ new DimSurface(mService.mFxSession, displayId);
+ displayAnimator.mDimAnimator = new DimAnimator(mService.mFxSession, displayId);
+ if (displayId == Display.DEFAULT_DISPLAY) {
+ mInitialized = true;
+ }
+ }
+
+ void removeDisplayLocked(final int displayId) {
+ mDisplayContentsAnimators.delete(displayId);
}
/** Locked on mAnimToLayout */
@@ -165,8 +166,6 @@
mWallpaperTokens = new ArrayList<WindowToken>(layoutToAnim.mWallpaperTokens);
}
- mWinAnimatorLists =
- new ArrayList<WinAnimatorList>(layoutToAnim.mWinAnimatorLists);
mWallpaperTarget = layoutToAnim.mWallpaperTarget;
mWpAppAnimator = mWallpaperTarget == null
? null : mWallpaperTarget.mAppToken == null
@@ -175,20 +174,34 @@
mUpperWallpaperTarget = layoutToAnim.mUpperWallpaperTarget;
// Set the new DimAnimator params.
- DimAnimator.Parameters dimParams = layoutToAnim.mDimParams;
- if (dimParams == null) {
- mDimParams = null;
- } else {
- final WindowStateAnimator newWinAnimator = dimParams.mDimWinAnimator;
+ final int numDisplays = mDisplayContentsAnimators.size();
+ for (int i = 0; i < numDisplays; i++) {
+ final int displayId = mDisplayContentsAnimators.keyAt(i);
+ DisplayContentsAnimator displayAnimator = mDisplayContentsAnimators.valueAt(i);
- // Only set dim params on the highest dimmed layer.
- final WindowStateAnimator existingDimWinAnimator = mDimParams == null
- ? null : mDimParams.mDimWinAnimator;
- // Don't turn on for an unshown surface, or for any layer but the highest dimmed one.
- if (newWinAnimator.mSurfaceShown &&
- (existingDimWinAnimator == null || !existingDimWinAnimator.mSurfaceShown
- || existingDimWinAnimator.mAnimLayer < newWinAnimator.mAnimLayer)) {
- mDimParams = new DimAnimator.Parameters(dimParams);
+ displayAnimator.mWinAnimators.clear();
+ final WinAnimatorList winAnimators = layoutToAnim.mWinAnimatorLists.get(displayId);
+ if (winAnimators != null) {
+ displayAnimator.mWinAnimators.addAll(winAnimators);
+ }
+
+ DimAnimator.Parameters dimParams = layoutToAnim.mDimParams.get(displayId);
+ if (dimParams == null) {
+ displayAnimator.mDimParams = null;
+ } else {
+ final WindowStateAnimator newWinAnimator = dimParams.mDimWinAnimator;
+
+ // Only set dim params on the highest dimmed layer.
+ final WindowStateAnimator existingDimWinAnimator =
+ displayAnimator.mDimParams == null ?
+ null : displayAnimator.mDimParams.mDimWinAnimator;
+ // Don't turn on for an unshown surface, or for any layer but the highest
+ // dimmed layer.
+ if (newWinAnimator.mSurfaceShown && (existingDimWinAnimator == null
+ || !existingDimWinAnimator.mSurfaceShown
+ || existingDimWinAnimator.mAnimLayer < newWinAnimator.mAnimLayer)) {
+ displayAnimator.mDimParams = new DimAnimator.Parameters(dimParams);
+ }
}
}
@@ -225,7 +238,7 @@
}
}
- private void updateWindowsAppsAndRotationAnimationsLocked() {
+ private void updateAppWindowsLocked() {
int i;
final int NAT = mAppAnimators.size();
for (i=0; i<NAT; i++) {
@@ -258,21 +271,13 @@
"updateWindowsApps...: done animating exiting " + appAnimator.mAppToken);
}
}
-
- if (mScreenRotationAnimation != null && mScreenRotationAnimation.isAnimating()) {
- if (mScreenRotationAnimation.stepAnimationLocked(mCurrentTime)) {
- mAnimating = true;
- } else {
- mBulkUpdateParams |= SET_UPDATE_ROTATION;
- mScreenRotationAnimation.kill();
- mScreenRotationAnimation = null;
- }
- }
}
- private void updateWindowsLocked(final WinAnimatorList winAnimatorList) {
+ private void updateWindowsLocked(final int displayId) {
++mAnimTransactionSequence;
+ final WinAnimatorList winAnimatorList =
+ getDisplayContentsAnimatorLocked(displayId).mWinAnimators;
ArrayList<WindowStateAnimator> unForceHiding = null;
boolean wallpaperInUnForceHiding = false;
@@ -313,7 +318,6 @@
WindowManagerService.DEBUG_VISIBILITY) Slog.v(TAG,
"Animation started that could impact force hide: " + win);
mBulkUpdateParams |= SET_FORCE_HIDING_CHANGED;
- final int displayId = win.mDisplayContent.getDisplayId();
setPendingLayoutChanges(displayId,
WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER);
if (WindowManagerService.DEBUG_LAYOUT_REPEATS) {
@@ -391,7 +395,6 @@
if (winAnimator.mDrawState == WindowStateAnimator.READY_TO_SHOW) {
if (atoken == null || atoken.allDrawn) {
if (winAnimator.performShowLocked()) {
- final int displayId = win.mDisplayContent.getDisplayId();
mPendingLayoutChanges.put(displayId,
WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM);
if (WindowManagerService.DEBUG_LAYOUT_REPEATS) {
@@ -427,10 +430,15 @@
}
}
- private void updateWallpaperLocked(final WinAnimatorList winAnimatorList) {
+ private void updateWallpaperLocked(int displayId) {
+ final DisplayContentsAnimator displayAnimator =
+ getDisplayContentsAnimatorLocked(displayId);
+ final WinAnimatorList winAnimatorList = displayAnimator.mWinAnimators;
WindowStateAnimator windowAnimationBackground = null;
int windowAnimationBackgroundColor = 0;
WindowState detachedWallpaper = null;
+ final DimSurface windowAnimationBackgroundSurface =
+ displayAnimator.mWindowAnimationBackgroundSurface;
for (int i = winAnimatorList.size() - 1; i >= 0; i--) {
WindowStateAnimator winAnimator = winAnimatorList.get(i);
@@ -510,11 +518,11 @@
}
}
- mWindowAnimationBackgroundSurface.show(mDw, mDh,
+ windowAnimationBackgroundSurface.show(mDw, mDh,
animLayer - WindowManagerService.LAYER_OFFSET_DIM,
windowAnimationBackgroundColor);
} else {
- mWindowAnimationBackgroundSurface.hide();
+ windowAnimationBackgroundSurface.hide();
}
}
@@ -557,9 +565,9 @@
}
}
- private void performAnimationsLocked(final WinAnimatorList winAnimatorList) {
- updateWindowsLocked(winAnimatorList);
- updateWallpaperLocked(winAnimatorList);
+ private void performAnimationsLocked(final int displayId) {
+ updateWindowsLocked(displayId);
+ updateWallpaperLocked(displayId);
}
// TODO(cmautner): Change the following comment when no longer locked on mWindowMap */
@@ -582,15 +590,30 @@
TAG, ">>> OPEN TRANSACTION animateLocked");
Surface.openTransaction();
try {
- updateWindowsAppsAndRotationAnimationsLocked();
+ updateAppWindowsLocked();
- for (int i = mWinAnimatorLists.size() - 1; i >= 0; i--) {
- final WinAnimatorList winAnimatorList = mWinAnimatorLists.get(i);
+ final int numDisplays = mDisplayContentsAnimators.size();
+ for (int i = 0; i < numDisplays; i++) {
+ final int displayId = mDisplayContentsAnimators.keyAt(i);
+ DisplayContentsAnimator displayAnimator = mDisplayContentsAnimators.valueAt(i);
+
+ final ScreenRotationAnimation screenRotationAnimation =
+ displayAnimator.mScreenRotationAnimation;
+ if (screenRotationAnimation != null && screenRotationAnimation.isAnimating()) {
+ if (screenRotationAnimation.stepAnimationLocked(mCurrentTime)) {
+ mAnimating = true;
+ } else {
+ mBulkUpdateParams |= SET_UPDATE_ROTATION;
+ screenRotationAnimation.kill();
+ displayAnimator.mScreenRotationAnimation = null;
+ }
+ }
// Update animations of all applications, including those
// associated with exiting/removed apps
- performAnimationsLocked(winAnimatorList);
+ performAnimationsLocked(displayId);
+ final WinAnimatorList winAnimatorList = displayAnimator.mWinAnimators;
final int N = winAnimatorList.size();
for (int j = 0; j < N; j++) {
winAnimatorList.get(j).prepareSurfaceLocked(true);
@@ -599,16 +622,26 @@
testTokenMayBeDrawnLocked();
- if (mScreenRotationAnimation != null) {
- mScreenRotationAnimation.updateSurfacesInTransaction();
- }
+ for (int i = 0; i < numDisplays; i++) {
+ final int displayId = mDisplayContentsAnimators.keyAt(i);
+ DisplayContentsAnimator displayAnimator = mDisplayContentsAnimators.valueAt(i);
- if (mDimParams != null) {
- mDimAnimator.updateParameters(mContext.getResources(), mDimParams, mCurrentTime);
- }
- if (mDimAnimator != null && mDimAnimator.mDimShown) {
- mAnimating |= mDimAnimator.updateSurface(isDimming(), mCurrentTime,
- !mService.okToDisplay());
+ final ScreenRotationAnimation screenRotationAnimation =
+ displayAnimator.mScreenRotationAnimation;
+ if (screenRotationAnimation != null) {
+ screenRotationAnimation.updateSurfacesInTransaction();
+ }
+
+ final DimAnimator.Parameters dimParams = displayAnimator.mDimParams;
+ final DimAnimator dimAnimator = displayAnimator.mDimAnimator;
+ if (dimParams != null) {
+ dimAnimator.updateParameters(
+ mContext.getResources(), dimParams, mCurrentTime);
+ }
+ if (dimAnimator != null && dimAnimator.mDimShown) {
+ mAnimating |= dimAnimator.updateSurface(isDimmingLocked(displayId),
+ mCurrentTime, !mService.okToDisplay());
+ }
}
if (mService.mWatermark != null) {
@@ -661,15 +694,17 @@
mInnerDh = appHeight;
}
- boolean isDimming() {
- return mDimParams != null;
+ boolean isDimmingLocked(int displayId) {
+ return getDisplayContentsAnimatorLocked(displayId).mDimParams != null;
}
- boolean isDimming(final WindowStateAnimator winAnimator) {
- return mDimParams != null && mDimParams.mDimWinAnimator == winAnimator;
+ boolean isDimmingLocked(final WindowStateAnimator winAnimator) {
+ DimAnimator.Parameters dimParams =
+ getDisplayContentsAnimatorLocked(winAnimator.mWin.getDisplayId()).mDimParams;
+ return dimParams != null && dimParams.mDimWinAnimator == winAnimator;
}
- public void dump(PrintWriter pw, String prefix, boolean dumpAll) {
+ public void dumpLocked(PrintWriter pw, String prefix, boolean dumpAll) {
if (dumpAll) {
if (mWindowDetachedWallpaper != null) {
pw.print(prefix); pw.print("mWindowDetachedWallpaper=");
@@ -677,16 +712,36 @@
}
pw.print(prefix); pw.print("mAnimTransactionSequence=");
pw.println(mAnimTransactionSequence);
- if (mWindowAnimationBackgroundSurface != null) {
- pw.print(prefix); pw.print("mWindowAnimationBackgroundSurface:");
- mWindowAnimationBackgroundSurface.printTo(prefix + " ", pw);
+ for (int i = 0; i < mDisplayContentsAnimators.size(); i++) {
+ pw.print(prefix); pw.print("DisplayContentsAnimator #");
+ pw.println(mDisplayContentsAnimators.keyAt(i));
+ DisplayContentsAnimator displayAnimator = mDisplayContentsAnimators.valueAt(i);
+ final String subPrefix = " " + prefix;
+ final String subSubPrefix = " " + subPrefix;
+ if (displayAnimator.mWindowAnimationBackgroundSurface != null) {
+ pw.println(subPrefix + "mWindowAnimationBackgroundSurface:");
+ displayAnimator.mWindowAnimationBackgroundSurface.printTo(subSubPrefix, pw);
+ }
+ if (displayAnimator.mDimAnimator != null) {
+ pw.println(subPrefix + "mDimAnimator:");
+ displayAnimator.mDimAnimator.printTo(subSubPrefix, pw);
+ } else {
+ pw.println(subPrefix + "no DimAnimator ");
+ }
+ if (displayAnimator.mDimParams != null) {
+ pw.println(subPrefix + "mDimParams:");
+ displayAnimator.mDimParams.printTo(subSubPrefix, pw);
+ } else {
+ pw.println(subPrefix + "no DimParams ");
+ }
+ if (displayAnimator.mScreenRotationAnimation != null) {
+ pw.println(subPrefix + "mScreenRotationAnimation:");
+ displayAnimator.mScreenRotationAnimation.printTo(subSubPrefix, pw);
+ } else {
+ pw.print(subPrefix + "no ScreenRotationAnimation ");
+ }
}
- if (mDimAnimator != null) {
- pw.print(prefix); pw.print("mDimAnimator:");
- mDimAnimator.printTo(prefix + " ", pw);
- } else {
- pw.print(prefix); pw.print("no DimAnimator ");
- }
+ pw.println();
}
}
@@ -716,4 +771,29 @@
}
}
}
+
+ private DisplayContentsAnimator getDisplayContentsAnimatorLocked(int displayId) {
+ DisplayContentsAnimator displayAnimator = mDisplayContentsAnimators.get(displayId);
+ if (displayAnimator == null) {
+ displayAnimator = new DisplayContentsAnimator();
+ mDisplayContentsAnimators.put(displayId, displayAnimator);
+ }
+ return displayAnimator;
+ }
+
+ void setScreenRotationAnimationLocked(int displayId, ScreenRotationAnimation animation) {
+ getDisplayContentsAnimatorLocked(displayId).mScreenRotationAnimation = animation;
+ }
+
+ ScreenRotationAnimation getScreenRotationAnimationLocked(int displayId) {
+ return getDisplayContentsAnimatorLocked(displayId).mScreenRotationAnimation;
+ }
+
+ private static class DisplayContentsAnimator {
+ WinAnimatorList mWinAnimators = new WinAnimatorList();
+ DimAnimator mDimAnimator = null;
+ DimAnimator.Parameters mDimParams = null;
+ DimSurface mWindowAnimationBackgroundSurface = null;
+ ScreenRotationAnimation mScreenRotationAnimation = null;
+ }
}
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index 556613e..55a7c46 100755
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -623,11 +623,11 @@
long mChanges;
boolean mAnimationScheduled;
- ArrayList<WinAnimatorList> mWinAnimatorLists = new ArrayList<WinAnimatorList>();
+ SparseArray<WinAnimatorList> mWinAnimatorLists = new SparseArray<WinAnimatorList>();
WindowState mWallpaperTarget;
WindowState mLowerWallpaperTarget;
WindowState mUpperWallpaperTarget;
- DimAnimator.Parameters mDimParams;
+ SparseArray<DimAnimator.Parameters> mDimParams = new SparseArray<DimAnimator.Parameters>();
ArrayList<WindowToken> mWallpaperTokens = new ArrayList<WindowToken>();
ArrayList<AppWindowAnimParams> mAppWindowAnimParams = new ArrayList<AppWindowAnimParams>();
}
@@ -4121,6 +4121,7 @@
}
}
+ @Override
public void overridePendingAppTransitionScaleUp(int startX, int startY, int startWidth,
int startHeight) {
synchronized(mWindowMap) {
@@ -4138,6 +4139,7 @@
}
}
+ @Override
public void overridePendingAppTransitionThumb(Bitmap srcThumb, int startX,
int startY, IRemoteCallback startedCallback, boolean scaleUp) {
synchronized(mWindowMap) {
@@ -4157,6 +4159,7 @@
}
}
+ @Override
public void executeAppTransition() {
if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
"executeAppTransition()")) {
@@ -5943,8 +5946,9 @@
return false;
}
- if (mAnimator.mScreenRotationAnimation != null &&
- mAnimator.mScreenRotationAnimation.isAnimating()) {
+ ScreenRotationAnimation screenRotationAnimation =
+ mAnimator.getScreenRotationAnimationLocked(Display.DEFAULT_DISPLAY);
+ if (screenRotationAnimation != null && screenRotationAnimation.isAnimating()) {
// Rotation updates cannot be performed while the previous rotation change
// animation is still in progress. Skip this update. We will try updating
// again after the animation is finished and the display is unfrozen.
@@ -5996,6 +6000,9 @@
mWaitingForConfig = true;
getDefaultDisplayContentLocked().layoutNeeded = true;
startFreezingDisplayLocked(inTransaction, 0, 0);
+ // startFreezingDisplayLocked can reset the ScreenRotationAnimation.
+ screenRotationAnimation =
+ mAnimator.getScreenRotationAnimationLocked(Display.DEFAULT_DISPLAY);
// We need to update our screen size information to match the new
// rotation. Note that this is redundant with the later call to
@@ -6016,9 +6023,9 @@
try {
// NOTE: We disable the rotation in the emulator because
// it doesn't support hardware OpenGL emulation yet.
- if (CUSTOM_SCREEN_ROTATION && mAnimator.mScreenRotationAnimation != null
- && mAnimator.mScreenRotationAnimation.hasScreenshot()) {
- if (mAnimator.mScreenRotationAnimation.setRotationInTransaction(
+ if (CUSTOM_SCREEN_ROTATION && screenRotationAnimation != null
+ && screenRotationAnimation.hasScreenshot()) {
+ if (screenRotationAnimation.setRotationInTransaction(
rotation, mFxSession,
MAX_ANIMATION_DURATION, mTransitionAnimationScale,
displayInfo.logicalWidth, displayInfo.logicalHeight)) {
@@ -7158,8 +7165,6 @@
mIsTouchDevice = mContext.getPackageManager().hasSystemFeature(
PackageManager.FEATURE_TOUCHSCREEN);
- mAnimator.initializeLocked(display.getLayerStack());
-
final DisplayInfo displayInfo = getDefaultDisplayInfoLocked();
mAnimator.setDisplayDimensions(
displayInfo.logicalWidth, displayInfo.logicalHeight,
@@ -7181,6 +7186,7 @@
synchronized(mWindowMap) {
final DisplayContent displayContent = getDisplayContentLocked(displayId);
final DisplayInfo displayInfo;
+ mAnimator.addDisplayLocked(displayId);
synchronized(displayContent.mDisplaySizeLock) {
// Bootstrap the default logical display from the display manager.
displayInfo = displayContent.getDisplayInfo();
@@ -8136,7 +8142,7 @@
if (winAnimator.mAnimLayer != oldLayer) {
layerChanged = true;
}
- if (layerChanged && mAnimator.isDimming(winAnimator)) {
+ if (layerChanged && mAnimator.isDimmingLocked(winAnimator)) {
// Force an animation pass just to update the mDimAnimator layer.
updateLayoutToAnimationLocked();
}
@@ -8842,7 +8848,7 @@
//Slog.i(TAG, "DIM BEHIND: " + w);
mInnerFields.mDimming = true;
final WindowStateAnimator winAnimator = w.mWinAnimator;
- if (!mAnimator.isDimming(winAnimator)) {
+ if (!mAnimator.isDimmingLocked(winAnimator)) {
final int width, height;
if (attrs.type == WindowManager.LayoutParams.TYPE_BOOT_PROGRESS) {
final DisplayInfo displayInfo = w.mDisplayContent.getDisplayInfo();
@@ -8852,7 +8858,8 @@
width = innerDw;
height = innerDh;
}
- startDimming(winAnimator, w.mExiting ? 0 : w.mAttrs.dimAmount, width, height);
+ startDimmingLocked(
+ winAnimator, w.mExiting ? 0 : w.mAttrs.dimAmount, width, height);
}
}
}
@@ -9080,7 +9087,7 @@
}
}
- winAnimator.setSurfaceBoundaries(recoveringMemory);
+ winAnimator.setSurfaceBoundariesLocked(recoveringMemory);
final AppWindowToken atoken = w.mAppToken;
if (DEBUG_STARTING_WINDOW && atoken != null && w == atoken.startingWindow) {
@@ -9138,6 +9145,10 @@
updateResizingWindows(w);
}
+
+ if (!mInnerFields.mDimming && mAnimator.isDimmingLocked(displayId)) {
+ stopDimmingLocked(displayId);
+ }
}
if (updateAllDrawn) {
@@ -9147,10 +9158,6 @@
if (focusDisplayed) {
mH.sendEmptyMessage(H.REPORT_LOSING_FOCUS);
}
-
- if (!mInnerFields.mDimming && mAnimator.isDimming()) {
- stopDimming();
- }
} catch (RuntimeException e) {
Log.wtf(TAG, "Unhandled exception in Window Manager", e);
} finally {
@@ -9515,7 +9522,7 @@
final LayoutToAnimatorParams layoutToAnim = mLayoutToAnim;
synchronized (layoutToAnim) {
// Copy local params to transfer params.
- ArrayList<WinAnimatorList> allWinAnimatorLists = layoutToAnim.mWinAnimatorLists;
+ SparseArray<WinAnimatorList> allWinAnimatorLists = layoutToAnim.mWinAnimatorLists;
allWinAnimatorLists.clear();
DisplayContentsIterator iterator = new DisplayContentsIterator();
while (iterator.hasNext()) {
@@ -9529,7 +9536,7 @@
winAnimatorList.add(winAnimator);
}
}
- allWinAnimatorLists.add(winAnimatorList);
+ allWinAnimatorLists.put(displayContent.getDisplayId(), winAnimatorList);
}
layoutToAnim.mWallpaperTarget = mWallpaperTarget;
@@ -9555,20 +9562,21 @@
}
}
- void setAnimDimParams(DimAnimator.Parameters params) {
+ void setAnimDimParams(int displayId, DimAnimator.Parameters params) {
synchronized (mLayoutToAnim) {
- mLayoutToAnim.mDimParams = params;
+ mLayoutToAnim.mDimParams.put(displayId, params);
scheduleAnimationLocked();
}
}
- void startDimming(final WindowStateAnimator winAnimator, final float target,
+ void startDimmingLocked(final WindowStateAnimator winAnimator, final float target,
final int width, final int height) {
- setAnimDimParams(new DimAnimator.Parameters(winAnimator, width, height, target));
+ setAnimDimParams(winAnimator.mWin.getDisplayId(),
+ new DimAnimator.Parameters(winAnimator, width, height, target));
}
- void stopDimming() {
- setAnimDimParams(null);
+ void stopDimmingLocked(int displayId) {
+ setAnimDimParams(displayId, null);
}
private boolean needsLayout() {
@@ -9900,19 +9908,22 @@
}
if (CUSTOM_SCREEN_ROTATION) {
- if (mAnimator.mScreenRotationAnimation != null) {
- mAnimator.mScreenRotationAnimation.kill();
- mAnimator.mScreenRotationAnimation = null;
+ final DisplayContent displayContent = getDefaultDisplayContentLocked();
+ final int displayId = displayContent.getDisplayId();
+ ScreenRotationAnimation screenRotationAnimation =
+ mAnimator.getScreenRotationAnimationLocked(displayId);
+ if (screenRotationAnimation != null) {
+ screenRotationAnimation.kill();
}
// TODO(multidisplay): rotation on main screen only.
- final DisplayContent displayContent = getDefaultDisplayContentLocked();
final Display display = displayContent.getDisplay();
final DisplayInfo displayInfo = displayContent.getDisplayInfo();
- mAnimator.mScreenRotationAnimation = new ScreenRotationAnimation(mContext,
+ screenRotationAnimation = new ScreenRotationAnimation(mContext,
display, mFxSession, inTransaction, displayInfo.logicalWidth,
displayInfo.logicalHeight, display.getRotation(),
exitAnim, enterAnim);
+ mAnimator.setScreenRotationAnimationLocked(displayId, screenRotationAnimation);
}
}
@@ -9940,24 +9951,30 @@
boolean updateRotation = false;
- if (CUSTOM_SCREEN_ROTATION && mAnimator.mScreenRotationAnimation != null
- && mAnimator.mScreenRotationAnimation.hasScreenshot()) {
+ final DisplayContent displayContent = getDefaultDisplayContentLocked();
+ final int displayId = displayContent.getDisplayId();
+ ScreenRotationAnimation screenRotationAnimation =
+ mAnimator.getScreenRotationAnimationLocked(displayId);
+ if (CUSTOM_SCREEN_ROTATION && screenRotationAnimation != null
+ && screenRotationAnimation.hasScreenshot()) {
if (DEBUG_ORIENTATION) Slog.i(TAG, "**** Dismissing screen rotation animation");
// TODO(multidisplay): rotation on main screen only.
- DisplayInfo displayInfo = getDefaultDisplayContentLocked().getDisplayInfo();
- if (mAnimator.mScreenRotationAnimation.dismiss(mFxSession, MAX_ANIMATION_DURATION,
+ DisplayInfo displayInfo = displayContent.getDisplayInfo();
+ if (screenRotationAnimation.dismiss(mFxSession, MAX_ANIMATION_DURATION,
mTransitionAnimationScale, displayInfo.logicalWidth,
displayInfo.logicalHeight)) {
updateLayoutToAnimationLocked();
} else {
- mAnimator.mScreenRotationAnimation.kill();
- mAnimator.mScreenRotationAnimation = null;
+ screenRotationAnimation.kill();
+ screenRotationAnimation = null;
+ mAnimator.setScreenRotationAnimationLocked(displayId, screenRotationAnimation);
updateRotation = true;
}
} else {
- if (mAnimator.mScreenRotationAnimation != null) {
- mAnimator.mScreenRotationAnimation.kill();
- mAnimator.mScreenRotationAnimation = null;
+ if (screenRotationAnimation != null) {
+ screenRotationAnimation.kill();
+ screenRotationAnimation = null;
+ mAnimator.setScreenRotationAnimationLocked(displayId, screenRotationAnimation);
}
updateRotation = true;
}
@@ -10394,11 +10411,11 @@
pw.print(": "); pw.println(pair.second);
}
}
- pw.println();
+ pw.println(" DisplayContents");
if (mDisplayReady) {
DisplayContentsIterator dCIterator = new DisplayContentsIterator();
while (dCIterator.hasNext()) {
- dCIterator.next().dump(pw);
+ dCIterator.next().dump(" ", pw);
}
} else {
pw.println(" NO DISPLAY");
@@ -10463,10 +10480,6 @@
pw.print(" mLastWindowForcedOrientation="); pw.print(mLastWindowForcedOrientation);
pw.print(" mForcedAppOrientation="); pw.println(mForcedAppOrientation);
pw.print(" mDeferredRotationPauseCount="); pw.println(mDeferredRotationPauseCount);
- if (mAnimator.mScreenRotationAnimation != null) {
- pw.println(" mScreenRotationAnimation:");
- mAnimator.mScreenRotationAnimation.printTo(" ", pw);
- }
pw.print(" mWindowAnimationScale="); pw.print(mWindowAnimationScale);
pw.print(" mTransitionWindowAnimationScale="); pw.print(mTransitionAnimationScale);
pw.print(" mAnimatorDurationScale="); pw.println(mAnimatorDurationScale);
@@ -10515,7 +10528,7 @@
pw.print(" mStartingIconInTransition="); pw.print(mStartingIconInTransition);
pw.print(" mSkipAppTransitionAnimation="); pw.println(mSkipAppTransitionAnimation);
pw.println(" Window Animator:");
- mAnimator.dump(pw, " ", dumpAll);
+ mAnimator.dumpLocked(pw, " ", dumpAll);
}
}
@@ -10850,6 +10863,7 @@
private void handleDisplayAddedLocked(int displayId) {
createDisplayContentLocked(mDisplayManager.getDisplay(displayId));
+ displayReady(displayId);
}
@Override
@@ -10865,6 +10879,7 @@
final WindowState win = windows.get(i);
removeWindowLocked(win.mSession, win);
}
+ mAnimator.removeDisplayLocked(displayId);
}
@Override
diff --git a/services/java/com/android/server/wm/WindowStateAnimator.java b/services/java/com/android/server/wm/WindowStateAnimator.java
index 8912c73..000a191 100644
--- a/services/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/java/com/android/server/wm/WindowStateAnimator.java
@@ -31,6 +31,13 @@
import java.util.ArrayList;
class WinAnimatorList extends ArrayList<WindowStateAnimator> {
+ public WinAnimatorList() {
+ super();
+ }
+
+ public WinAnimatorList(WinAnimatorList other) {
+ super(other);
+ }
}
/**
@@ -840,8 +847,11 @@
}
}
- final boolean screenAnimation = mService.mAnimator.mScreenRotationAnimation != null
- && mService.mAnimator.mScreenRotationAnimation.isAnimating();
+ final int displayId = mWin.getDisplayId();
+ final ScreenRotationAnimation screenRotationAnimation =
+ mAnimator.getScreenRotationAnimationLocked(displayId);
+ final boolean screenAnimation =
+ screenRotationAnimation != null && screenRotationAnimation.isAnimating();
if (selfTransformation || attachedTransformation != null
|| appTransformation != null || screenAnimation) {
// cache often used attributes locally
@@ -883,8 +893,7 @@
tmpMatrix.postConcat(mAnimator.mUniverseBackground.mUniverseTransform.getMatrix());
}
if (screenAnimation) {
- tmpMatrix.postConcat(
- mService.mAnimator.mScreenRotationAnimation.getEnterTransformation().getMatrix());
+ tmpMatrix.postConcat(screenRotationAnimation.getEnterTransformation().getMatrix());
}
MagnificationSpec spec = mWin.getWindowMagnificationSpecLocked();
if (spec != null && !spec.isNop()) {
@@ -934,21 +943,21 @@
mShownAlpha *= mAnimator.mUniverseBackground.mUniverseTransform.getAlpha();
}
if (screenAnimation) {
- mShownAlpha *=
- mService.mAnimator.mScreenRotationAnimation.getEnterTransformation().getAlpha();
+ mShownAlpha *= screenRotationAnimation.getEnterTransformation().getAlpha();
}
} else {
//Slog.i(TAG, "Not applying alpha transform");
}
- if ((DEBUG_SURFACE_TRACE || WindowManagerService.localLOGV) && (mShownAlpha == 1.0 || mShownAlpha == 0.0)) Slog.v(
- TAG, "computeShownFrameLocked: Animating " + this +
- " mAlpha=" + mAlpha +
- " self=" + (selfTransformation ? mTransformation.getAlpha() : "null") +
- " attached=" + (attachedTransformation == null ? "null" : attachedTransformation.getAlpha()) +
- " app=" + (appTransformation == null ? "null" : appTransformation.getAlpha()) +
- " screen=" + (screenAnimation ? mService.mAnimator.mScreenRotationAnimation.getEnterTransformation().getAlpha()
- : "null"));
+ if ((DEBUG_SURFACE_TRACE || WindowManagerService.localLOGV)
+ && (mShownAlpha == 1.0 || mShownAlpha == 0.0)) Slog.v(
+ TAG, "computeShownFrameLocked: Animating " + this + " mAlpha=" + mAlpha
+ + " self=" + (selfTransformation ? mTransformation.getAlpha() : "null")
+ + " attached=" + (attachedTransformation == null ?
+ "null" : attachedTransformation.getAlpha())
+ + " app=" + (appTransformation == null ? "null" : appTransformation.getAlpha())
+ + " screen=" + (screenAnimation ?
+ screenRotationAnimation.getEnterTransformation().getAlpha() : "null"));
return;
} else if (mIsWallpaper &&
(mAnimator.mPendingActions & WindowAnimator.WALLPAPER_ACTION_PENDING) != 0) {
@@ -1083,7 +1092,7 @@
}
}
- void setSurfaceBoundaries(final boolean recoveringMemory) {
+ void setSurfaceBoundariesLocked(final boolean recoveringMemory) {
final WindowState w = mWin;
int width, height;
if ((w.mAttrs.flags & LayoutParams.FLAG_SCALED) != 0) {
@@ -1138,7 +1147,7 @@
WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER);
if ((w.mAttrs.flags & LayoutParams.FLAG_DIM_BEHIND) != 0) {
final DisplayInfo displayInfo = mWin.mDisplayContent.getDisplayInfo();
- mService.startDimming(this, w.mExiting ? 0 : w.mAttrs.dimAmount,
+ mService.startDimmingLocked(this, w.mExiting ? 0 : w.mAttrs.dimAmount,
displayInfo.appWidth, displayInfo.appHeight);
}
} catch (RuntimeException e) {
@@ -1172,7 +1181,7 @@
computeShownFrameLocked();
- setSurfaceBoundaries(recoveringMemory);
+ setSurfaceBoundariesLocked(recoveringMemory);
if (mIsWallpaper && !mWin.mWallpaperVisible) {
// Wallpaper is no longer visible and there is no wp target => hide it.