Merge "Unhide the new AndroidKeyStore API."
diff --git a/Android.mk b/Android.mk
index 3e049f7..f4b9551 100644
--- a/Android.mk
+++ b/Android.mk
@@ -195,7 +195,6 @@
core/java/android/os/IBatteryPropertiesListener.aidl \
core/java/android/os/IBatteryPropertiesRegistrar.aidl \
core/java/android/os/ICancellationSignal.aidl \
- core/java/android/os/IHardwareService.aidl \
core/java/android/os/IMessenger.aidl \
core/java/android/os/INetworkActivityListener.aidl \
core/java/android/os/INetworkManagementService.aidl \
diff --git a/core/java/android/app/IUserSwitchObserver.aidl b/core/java/android/app/IUserSwitchObserver.aidl
index 845897b..caee14f 100644
--- a/core/java/android/app/IUserSwitchObserver.aidl
+++ b/core/java/android/app/IUserSwitchObserver.aidl
@@ -22,4 +22,5 @@
oneway interface IUserSwitchObserver {
void onUserSwitching(int newUserId, IRemoteCallback reply);
void onUserSwitchComplete(int newUserId);
+ void onForegroundProfileSwitch(int newProfileId);
}
diff --git a/core/java/android/os/IHardwareService.aidl b/core/java/android/os/IHardwareService.aidl
deleted file mode 100644
index 38abfc00..0000000
--- a/core/java/android/os/IHardwareService.aidl
+++ /dev/null
@@ -1,26 +0,0 @@
-/**
- * Copyright (c) 2007, 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 android.os;
-
-/** {@hide} */
-interface IHardwareService
-{
- // obsolete flashlight support
- boolean getFlashlightEnabled();
- void setFlashlightEnabled(boolean on);
-}
-
diff --git a/core/java/android/widget/DatePickerCalendarDelegate.java b/core/java/android/widget/DatePickerCalendarDelegate.java
index a157087..06a5bd2 100755
--- a/core/java/android/widget/DatePickerCalendarDelegate.java
+++ b/core/java/android/widget/DatePickerCalendarDelegate.java
@@ -534,22 +534,23 @@
@Override
public void onRestoreInstanceState(Parcelable state) {
- SavedState ss = (SavedState) state;
+ final SavedState ss = (SavedState) state;
// TODO: Move instance state into DayPickerView, YearPickerView.
mCurrentDate.set(ss.getSelectedYear(), ss.getSelectedMonth(), ss.getSelectedDay());
- mCurrentView = ss.getCurrentView();
mMinDate.setTimeInMillis(ss.getMinDate());
mMaxDate.setTimeInMillis(ss.getMaxDate());
onCurrentDateChanged(false);
- setCurrentView(mCurrentView);
+
+ final int currentView = ss.getCurrentView();
+ setCurrentView(currentView);
final int listPosition = ss.getListPosition();
if (listPosition != -1) {
- if (mCurrentView == VIEW_MONTH_DAY) {
+ if (currentView == VIEW_MONTH_DAY) {
mDayPickerView.setCurrentItem(listPosition);
- } else if (mCurrentView == VIEW_YEAR) {
+ } else if (currentView == VIEW_YEAR) {
final int listPositionOffset = ss.getListPositionOffset();
mYearPickerView.setSelectionFromTop(listPosition, listPositionOffset);
}
@@ -601,7 +602,6 @@
* Class for managing state storing/restoring.
*/
private static class SavedState extends View.BaseSavedState {
-
private final int mSelectedYear;
private final int mSelectedMonth;
private final int mSelectedDay;
diff --git a/core/java/android/widget/DayPickerView.java b/core/java/android/widget/DayPickerView.java
index ec2528f..0e0b2d3 100644
--- a/core/java/android/widget/DayPickerView.java
+++ b/core/java/android/widget/DayPickerView.java
@@ -22,9 +22,12 @@
import android.content.Context;
import android.content.res.ColorStateList;
import android.content.res.TypedArray;
+import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.util.MathUtils;
+import android.view.View;
+import java.util.ArrayList;
import java.util.Calendar;
import java.util.Locale;
@@ -41,6 +44,8 @@
private final Calendar mMinDate = Calendar.getInstance();
private final Calendar mMaxDate = Calendar.getInstance();
+ private final ArrayList<View> mMatchParentChildren = new ArrayList<>(1);
+
private final DayPickerAdapter mAdapter;
/** Temporary calendar used for date calculations. */
@@ -140,6 +145,93 @@
});
}
+ @Override
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ populate();
+
+ // Everything below is mostly copied from FrameLayout.
+ int count = getChildCount();
+
+ final boolean measureMatchParentChildren =
+ MeasureSpec.getMode(widthMeasureSpec) != MeasureSpec.EXACTLY ||
+ MeasureSpec.getMode(heightMeasureSpec) != MeasureSpec.EXACTLY;
+
+ int maxHeight = 0;
+ int maxWidth = 0;
+ int childState = 0;
+
+ for (int i = 0; i < count; i++) {
+ final View child = getChildAt(i);
+ if (child.getVisibility() != GONE) {
+ measureChild(child, widthMeasureSpec, heightMeasureSpec);
+ final LayoutParams lp = (LayoutParams) child.getLayoutParams();
+ maxWidth = Math.max(maxWidth, child.getMeasuredWidth());
+ maxHeight = Math.max(maxHeight, child.getMeasuredHeight());
+ childState = combineMeasuredStates(childState, child.getMeasuredState());
+ if (measureMatchParentChildren) {
+ if (lp.width == LayoutParams.MATCH_PARENT ||
+ lp.height == LayoutParams.MATCH_PARENT) {
+ mMatchParentChildren.add(child);
+ }
+ }
+ }
+ }
+
+ // Account for padding too
+ maxWidth += getPaddingLeft() + getPaddingRight();
+ maxHeight += getPaddingTop() + getPaddingBottom();
+
+ // Check against our minimum height and width
+ maxHeight = Math.max(maxHeight, getSuggestedMinimumHeight());
+ maxWidth = Math.max(maxWidth, getSuggestedMinimumWidth());
+
+ // Check against our foreground's minimum height and width
+ final Drawable drawable = getForeground();
+ if (drawable != null) {
+ maxHeight = Math.max(maxHeight, drawable.getMinimumHeight());
+ maxWidth = Math.max(maxWidth, drawable.getMinimumWidth());
+ }
+
+ setMeasuredDimension(resolveSizeAndState(maxWidth, widthMeasureSpec, childState),
+ resolveSizeAndState(maxHeight, heightMeasureSpec,
+ childState << MEASURED_HEIGHT_STATE_SHIFT));
+
+ count = mMatchParentChildren.size();
+ if (count > 1) {
+ for (int i = 0; i < count; i++) {
+ final View child = mMatchParentChildren.get(i);
+
+ final LayoutParams lp = (LayoutParams) child.getLayoutParams();
+ final int childWidthMeasureSpec;
+ final int childHeightMeasureSpec;
+
+ if (lp.width == LayoutParams.MATCH_PARENT) {
+ childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(
+ getMeasuredWidth() - getPaddingLeft() - getPaddingRight(),
+ MeasureSpec.EXACTLY);
+ } else {
+ childWidthMeasureSpec = getChildMeasureSpec(widthMeasureSpec,
+ getPaddingLeft() + getPaddingRight(),
+ lp.width);
+ }
+
+ if (lp.height == LayoutParams.MATCH_PARENT) {
+ childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(
+ getMeasuredHeight() - getPaddingTop() - getPaddingBottom(),
+ MeasureSpec.EXACTLY);
+ } else {
+ childHeightMeasureSpec = getChildMeasureSpec(heightMeasureSpec,
+ getPaddingTop() + getPaddingBottom(),
+ lp.height);
+ }
+
+ child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
+ }
+ }
+
+ mMatchParentChildren.clear();
+ }
+
public void setDayOfWeekTextAppearance(int resId) {
mAdapter.setDayOfWeekTextAppearance(resId);
}
diff --git a/core/java/android/widget/SimpleMonthView.java b/core/java/android/widget/SimpleMonthView.java
index d9f1f0e..aa7f0b6 100644
--- a/core/java/android/widget/SimpleMonthView.java
+++ b/core/java/android/widget/SimpleMonthView.java
@@ -585,7 +585,6 @@
mToday = day;
}
}
- mNumWeeks = calculateNumRows();
// Invalidate the old title.
mTitle = null;
@@ -616,18 +615,6 @@
}
}
- public void reuse() {
- mNumWeeks = MAX_WEEKS_IN_MONTH;
- requestLayout();
- }
-
- private int calculateNumRows() {
- final int offset = findDayOffset();
- final int dividend = (offset + mDaysInMonth) / DAYS_IN_WEEK;
- final int remainder = (offset + mDaysInMonth) % DAYS_IN_WEEK;
- return dividend + (remainder > 0 ? 1 : 0);
- }
-
private boolean sameDay(int day, Calendar today) {
return mYear == today.get(Calendar.YEAR) && mMonth == today.get(Calendar.MONTH)
&& day == today.get(Calendar.DAY_OF_MONTH);
@@ -635,8 +622,9 @@
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
- final int preferredHeight = mDesiredDayHeight * mNumWeeks + mDesiredDayOfWeekHeight
- + mDesiredMonthHeight + getPaddingTop() + getPaddingBottom();
+ final int preferredHeight = mDesiredDayHeight * MAX_WEEKS_IN_MONTH
+ + mDesiredDayOfWeekHeight + mDesiredMonthHeight
+ + getPaddingTop() + getPaddingBottom();
final int preferredWidth = mDesiredCellWidth * DAYS_IN_WEEK
+ getPaddingStart() + getPaddingEnd();
final int resolvedWidth = resolveSize(preferredWidth, widthMeasureSpec);
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 5d60f99..9bbf375 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -540,6 +540,7 @@
private Layout mLayout;
private boolean mLocaleChanged = false;
+ @ViewDebug.ExportedProperty(category = "text")
private int mGravity = Gravity.TOP | Gravity.START;
private boolean mHorizontallyScrolling;
diff --git a/core/java/android/widget/YearPickerView.java b/core/java/android/widget/YearPickerView.java
index 7182414..89e59f9 100644
--- a/core/java/android/widget/YearPickerView.java
+++ b/core/java/android/widget/YearPickerView.java
@@ -178,24 +178,29 @@
@Override
public View getView(int position, View convertView, ViewGroup parent) {
- if (convertView == null) {
- convertView = mInflater.inflate(ITEM_LAYOUT, parent, false);
+ final TextView v;
+ final boolean hasNewView = convertView == null;
+ if (hasNewView) {
+ v = (TextView) mInflater.inflate(ITEM_LAYOUT, parent, false);
+ } else {
+ v = (TextView) convertView;
}
final int year = getYearForPosition(position);
final boolean activated = mActivatedYear == year;
- final int textAppearanceResId;
- if (activated && ITEM_TEXT_ACTIVATED_APPEARANCE != 0) {
- textAppearanceResId = ITEM_TEXT_ACTIVATED_APPEARANCE;
- } else {
- textAppearanceResId = ITEM_TEXT_APPEARANCE;
+ if (hasNewView || v.isActivated() != activated) {
+ final int textAppearanceResId;
+ if (activated && ITEM_TEXT_ACTIVATED_APPEARANCE != 0) {
+ textAppearanceResId = ITEM_TEXT_ACTIVATED_APPEARANCE;
+ } else {
+ textAppearanceResId = ITEM_TEXT_APPEARANCE;
+ }
+ v.setTextAppearance(textAppearanceResId);
+ v.setActivated(activated);
}
- final TextView v = (TextView) convertView;
- v.setText("" + year);
- v.setTextAppearance(v.getContext(), textAppearanceResId);
- v.setActivated(activated);
+ v.setText(Integer.toString(year));
return v;
}
diff --git a/core/java/com/android/internal/widget/DialogViewAnimator.java b/core/java/com/android/internal/widget/DialogViewAnimator.java
new file mode 100644
index 0000000..bdfc1af
--- /dev/null
+++ b/core/java/com/android/internal/widget/DialogViewAnimator.java
@@ -0,0 +1,141 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.widget;
+
+import android.content.Context;
+import android.graphics.drawable.Drawable;
+import android.util.AttributeSet;
+import android.view.View;
+import android.widget.ViewAnimator;
+
+import java.util.ArrayList;
+
+/**
+ * ViewAnimator with a more reasonable handling of MATCH_PARENT.
+ */
+public class DialogViewAnimator extends ViewAnimator {
+ private final ArrayList<View> mMatchParentChildren = new ArrayList<>(1);
+
+ public DialogViewAnimator(Context context) {
+ super(context);
+ }
+
+ public DialogViewAnimator(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ @Override
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ final boolean measureMatchParentChildren =
+ MeasureSpec.getMode(widthMeasureSpec) != MeasureSpec.EXACTLY ||
+ MeasureSpec.getMode(heightMeasureSpec) != MeasureSpec.EXACTLY;
+
+ int maxHeight = 0;
+ int maxWidth = 0;
+ int childState = 0;
+
+ // First measure all children and record maximum dimensions where the
+ // spec isn't MATCH_PARENT.
+ final int count = getChildCount();
+ for (int i = 0; i < count; i++) {
+ final View child = getChildAt(i);
+ if (getMeasureAllChildren() || child.getVisibility() != GONE) {
+ final LayoutParams lp = (LayoutParams) child.getLayoutParams();
+ final boolean matchWidth = lp.width == LayoutParams.MATCH_PARENT;
+ final boolean matchHeight = lp.height == LayoutParams.MATCH_PARENT;
+ if (measureMatchParentChildren && (matchWidth || matchHeight)) {
+ mMatchParentChildren.add(child);
+ }
+
+ measureChildWithMargins(child, widthMeasureSpec, 0, heightMeasureSpec, 0);
+
+ // Measured dimensions only count against the maximum
+ // dimensions if they're not MATCH_PARENT.
+ int state = 0;
+
+ if (measureMatchParentChildren && !matchWidth) {
+ maxWidth = Math.max(maxWidth, child.getMeasuredWidth()
+ + lp.leftMargin + lp.rightMargin);
+ state |= child.getMeasuredWidthAndState() & MEASURED_STATE_MASK;
+ }
+
+ if (measureMatchParentChildren && !matchHeight) {
+ maxHeight = Math.max(maxHeight, child.getMeasuredHeight()
+ + lp.topMargin + lp.bottomMargin);
+ state |= (child.getMeasuredHeightAndState() >> MEASURED_HEIGHT_STATE_SHIFT)
+ & (MEASURED_STATE_MASK >> MEASURED_HEIGHT_STATE_SHIFT);
+ }
+
+ childState = combineMeasuredStates(childState, state);
+ }
+ }
+
+ // Account for padding too.
+ maxWidth += getPaddingLeft() + getPaddingRight();
+ maxHeight += getPaddingTop() + getPaddingBottom();
+
+ // Check against our minimum height and width.
+ maxHeight = Math.max(maxHeight, getSuggestedMinimumHeight());
+ maxWidth = Math.max(maxWidth, getSuggestedMinimumWidth());
+
+ // Check against our foreground's minimum height and width.
+ final Drawable drawable = getForeground();
+ if (drawable != null) {
+ maxHeight = Math.max(maxHeight, drawable.getMinimumHeight());
+ maxWidth = Math.max(maxWidth, drawable.getMinimumWidth());
+ }
+
+ setMeasuredDimension(resolveSizeAndState(maxWidth, widthMeasureSpec, childState),
+ resolveSizeAndState(maxHeight, heightMeasureSpec,
+ childState << MEASURED_HEIGHT_STATE_SHIFT));
+
+ // Measure remaining MATCH_PARENT children again using real dimensions.
+ final int matchCount = mMatchParentChildren.size();
+ for (int i = 0; i < matchCount; i++) {
+ final View child = mMatchParentChildren.get(i);
+ final MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams();
+
+ final int childWidthMeasureSpec;
+ if (lp.width == LayoutParams.MATCH_PARENT) {
+ childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(
+ getMeasuredWidth() - getPaddingLeft() - getPaddingRight()
+ - lp.leftMargin - lp.rightMargin,
+ MeasureSpec.EXACTLY);
+ } else {
+ childWidthMeasureSpec = getChildMeasureSpec(widthMeasureSpec,
+ getPaddingLeft() + getPaddingRight() + lp.leftMargin + lp.rightMargin,
+ lp.width);
+ }
+
+ final int childHeightMeasureSpec;
+ if (lp.height == LayoutParams.MATCH_PARENT) {
+ childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(
+ getMeasuredHeight() - getPaddingTop() - getPaddingBottom()
+ - lp.topMargin - lp.bottomMargin,
+ MeasureSpec.EXACTLY);
+ } else {
+ childHeightMeasureSpec = getChildMeasureSpec(heightMeasureSpec,
+ getPaddingTop() + getPaddingBottom() + lp.topMargin + lp.bottomMargin,
+ lp.height);
+ }
+
+ child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
+ }
+
+ mMatchParentChildren.clear();
+ }
+}
diff --git a/core/java/com/android/internal/widget/ViewPager.java b/core/java/com/android/internal/widget/ViewPager.java
index 8d66191..5c08daf 100644
--- a/core/java/com/android/internal/widget/ViewPager.java
+++ b/core/java/com/android/internal/widget/ViewPager.java
@@ -889,7 +889,7 @@
}
}
- void populate() {
+ public void populate() {
populate(mCurItem);
}
diff --git a/core/res/res/anim/date_picker_fade_in_material.xml b/core/res/res/anim/date_picker_fade_in_material.xml
new file mode 100644
index 0000000..12e7ce3
--- /dev/null
+++ b/core/res/res/anim/date_picker_fade_in_material.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<alpha xmlns:android="http://schemas.android.com/apk/res/android"
+ android:interpolator="@interpolator/accelerate_quad"
+ android:fromAlpha="0.0"
+ android:toAlpha="1.0"
+ android:duration="250" />
diff --git a/core/res/res/anim/date_picker_fade_out_material.xml b/core/res/res/anim/date_picker_fade_out_material.xml
new file mode 100644
index 0000000..4084605
--- /dev/null
+++ b/core/res/res/anim/date_picker_fade_out_material.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<alpha xmlns:android="http://schemas.android.com/apk/res/android"
+ android:interpolator="@interpolator/decelerate_quad"
+ android:fromAlpha="1.0"
+ android:toAlpha="0.0"
+ android:duration="250" />
diff --git a/core/res/res/layout/date_picker_material.xml b/core/res/res/layout/date_picker_material.xml
index a1c97ff..763f2a4 100644
--- a/core/res/res/layout/date_picker_material.xml
+++ b/core/res/res/layout/date_picker_material.xml
@@ -16,8 +16,8 @@
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
android:orientation="vertical">
<include
diff --git a/core/res/res/layout/date_picker_view_animator_material.xml b/core/res/res/layout/date_picker_view_animator_material.xml
index 620ddfa..e863b28 100644
--- a/core/res/res/layout/date_picker_view_animator_material.xml
+++ b/core/res/res/layout/date_picker_view_animator_material.xml
@@ -15,23 +15,23 @@
limitations under the License.
-->
-<ViewAnimator xmlns:android="http://schemas.android.com/apk/res/android"
+<com.android.internal.widget.DialogViewAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/animator"
android:layout_width="match_parent"
- android:layout_height="0dp"
- android:layout_weight="1"
- android:gravity="center">
+ android:layout_height="wrap_content"
+ android:gravity="center"
+ android:inAnimation="@anim/date_picker_fade_in_material"
+ android:outAnimation="@anim/date_picker_fade_out_material"
+ android:measureAllChildren="true">
<android.widget.DayPickerView
android:id="@+id/date_picker_day_picker"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:inAnimation="@anim/fade_in"
- android:outAnimation="@anim/fade_out" />
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" />
<android.widget.YearPickerView
android:id="@+id/date_picker_year_picker"
android:layout_width="match_parent"
android:layout_height="match_parent" />
-</ViewAnimator>
+</com.android.internal.widget.DialogViewAnimator>
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java
index 18615d9..147ac19 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -763,6 +763,10 @@
mSwitchingUser = false;
startListeningForFingerprint();
}
+ @Override
+ public void onForegroundProfileSwitch(int newProfileId) {
+ // Ignore.
+ }
});
} catch (RemoteException e) {
// TODO Auto-generated catch block
diff --git a/services/core/java/com/android/server/InputMethodManagerService.java b/services/core/java/com/android/server/InputMethodManagerService.java
index d92a89f..0f9090d 100644
--- a/services/core/java/com/android/server/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/InputMethodManagerService.java
@@ -797,6 +797,11 @@
@Override
public void onUserSwitchComplete(int newUserId) throws RemoteException {
}
+
+ @Override
+ public void onForegroundProfileSwitch(int newProfileId) {
+ // Ignore.
+ }
});
userId = ActivityManagerNative.getDefault().getCurrentUser().id;
} catch (RemoteException e) {
diff --git a/services/core/java/com/android/server/TextServicesManagerService.java b/services/core/java/com/android/server/TextServicesManagerService.java
index 5add88e..9a6f696 100644
--- a/services/core/java/com/android/server/TextServicesManagerService.java
+++ b/services/core/java/com/android/server/TextServicesManagerService.java
@@ -116,6 +116,11 @@
@Override
public void onUserSwitchComplete(int newUserId) throws RemoteException {
}
+
+ @Override
+ public void onForegroundProfileSwitch(int newProfileId) {
+ // Ignore.
+ }
});
userId = ActivityManagerNative.getDefault().getCurrentUser().id;
} catch (RemoteException e) {
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index c2af765..6341807 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -1284,6 +1284,7 @@
static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 51;
static final int DELETE_DUMPHEAP_MSG = 52;
+ static final int FOREGROUND_PROFILE_CHANGED_MSG = 53;
static final int FIRST_ACTIVITY_STACK_MSG = 100;
static final int FIRST_BROADCAST_QUEUE_MSG = 200;
@@ -1922,6 +1923,9 @@
mMemWatchDumpUid = -1;
}
} break;
+ case FOREGROUND_PROFILE_CHANGED_MSG: {
+ dispatchForegroundProfileChanged(msg.arg1);
+ } break;
}
}
};
@@ -2523,6 +2527,11 @@
mWindowManager.setFocusedApp(r.appToken, true);
}
applyUpdateLockStateLocked(r);
+ if (last != null && last.userId != mFocusedActivity.userId) {
+ mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
+ mHandler.sendMessage(mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG,
+ mFocusedActivity.userId, 0));
+ }
}
EventLog.writeEvent(EventLogTags.AM_FOCUSED_ACTIVITY, mCurrentUserId,
mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName);
@@ -19072,6 +19081,18 @@
return true;
}
+ void dispatchForegroundProfileChanged(int userId) {
+ final int N = mUserSwitchObservers.beginBroadcast();
+ for (int i = 0; i < N; i++) {
+ try {
+ mUserSwitchObservers.getBroadcastItem(i).onForegroundProfileSwitch(userId);
+ } catch (RemoteException e) {
+ // Ignore
+ }
+ }
+ mUserSwitchObservers.finishBroadcast();
+ }
+
void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
long ident = Binder.clearCallingIdentity();
try {
diff --git a/services/core/java/com/android/server/display/DisplayBlanker.java b/services/core/java/com/android/server/display/DisplayBlanker.java
index eb0ae6a..816dc13 100644
--- a/services/core/java/com/android/server/display/DisplayBlanker.java
+++ b/services/core/java/com/android/server/display/DisplayBlanker.java
@@ -20,5 +20,5 @@
* Interface used to update the actual display state.
*/
public interface DisplayBlanker {
- void requestDisplayState(int state);
+ void requestDisplayState(int state, int brightness);
}
diff --git a/services/core/java/com/android/server/display/DisplayDevice.java b/services/core/java/com/android/server/display/DisplayDevice.java
index 61631d4..e16be71 100644
--- a/services/core/java/com/android/server/display/DisplayDevice.java
+++ b/services/core/java/com/android/server/display/DisplayDevice.java
@@ -118,10 +118,12 @@
/**
* Sets the display state, if supported.
*
+ * @param state The new display state.
+ * @param brightness The new display brightness.
* @return A runnable containing work to be deferred until after we have
* exited the critical section, or null if none.
*/
- public Runnable requestDisplayStateLocked(int state) {
+ public Runnable requestDisplayStateLocked(int state, int brightness) {
return null;
}
diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java
index 5f0ad9f..9ea0444 100644
--- a/services/core/java/com/android/server/display/DisplayManagerService.java
+++ b/services/core/java/com/android/server/display/DisplayManagerService.java
@@ -40,11 +40,13 @@
import android.os.IBinder.DeathRecipient;
import android.os.Looper;
import android.os.Message;
+import android.os.PowerManager;
import android.os.Process;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SystemClock;
import android.os.SystemProperties;
+import android.os.Trace;
import android.text.TextUtils;
import android.util.Slog;
import android.util.SparseArray;
@@ -179,7 +181,11 @@
// The overall display state, independent of changes that might influence one
// display or another in particular.
- private int mGlobalDisplayState = Display.STATE_UNKNOWN;
+ private int mGlobalDisplayState = Display.STATE_ON;
+
+ // The overall display brightness.
+ // For now, this only applies to the built-in display but we may split it up eventually.
+ private int mGlobalDisplayBrightness = PowerManager.BRIGHTNESS_DEFAULT;
// Set to true when there are pending display changes that have yet to be applied
// to the surface flinger state.
@@ -226,6 +232,9 @@
mUiHandler = UiThread.getHandler();
mDisplayAdapterListener = new DisplayAdapterListener();
mSingleDisplayDemoMode = SystemProperties.getBoolean("persist.demo.singledisplay", false);
+
+ PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
+ mGlobalDisplayBrightness = pm.getDefaultScreenBrightnessSetting();
}
@Override
@@ -322,16 +331,34 @@
}
}
- private void requestGlobalDisplayStateInternal(int state) {
+ private void requestGlobalDisplayStateInternal(int state, int brightness) {
+ if (state == Display.STATE_UNKNOWN) {
+ state = Display.STATE_ON;
+ }
+ if (state == Display.STATE_OFF) {
+ brightness = PowerManager.BRIGHTNESS_OFF;
+ } else if (brightness < 0) {
+ brightness = PowerManager.BRIGHTNESS_DEFAULT;
+ } else if (brightness > PowerManager.BRIGHTNESS_ON) {
+ brightness = PowerManager.BRIGHTNESS_ON;
+ }
+
synchronized (mTempDisplayStateWorkQueue) {
try {
// Update the display state within the lock.
synchronized (mSyncRoot) {
- if (mGlobalDisplayState != state) {
- mGlobalDisplayState = state;
- updateGlobalDisplayStateLocked(mTempDisplayStateWorkQueue);
- scheduleTraversalLocked(false);
+ if (mGlobalDisplayState == state
+ && mGlobalDisplayBrightness == brightness) {
+ return; // no change
}
+
+ Trace.traceBegin(Trace.TRACE_TAG_POWER, "requestGlobalDisplayState("
+ + Display.stateToString(state)
+ + ", brightness=" + brightness + ")");
+ mGlobalDisplayState = state;
+ mGlobalDisplayBrightness = brightness;
+ updateGlobalDisplayStateLocked(mTempDisplayStateWorkQueue);
+ scheduleTraversalLocked(false);
}
// Setting the display power state can take hundreds of milliseconds
@@ -341,6 +368,7 @@
for (int i = 0; i < mTempDisplayStateWorkQueue.size(); i++) {
mTempDisplayStateWorkQueue.get(i).run();
}
+ Trace.traceEnd(Trace.TRACE_TAG_POWER);
} finally {
mTempDisplayStateWorkQueue.clear();
}
@@ -708,7 +736,7 @@
// by the display power controller (if known).
DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked();
if ((info.flags & DisplayDeviceInfo.FLAG_NEVER_BLANK) == 0) {
- return device.requestDisplayStateLocked(mGlobalDisplayState);
+ return device.requestDisplayStateLocked(mGlobalDisplayState, mGlobalDisplayBrightness);
}
return null;
}
@@ -1462,16 +1490,16 @@
synchronized (mSyncRoot) {
DisplayBlanker blanker = new DisplayBlanker() {
@Override
- public void requestDisplayState(int state) {
+ public void requestDisplayState(int state, int brightness) {
// The order of operations is important for legacy reasons.
if (state == Display.STATE_OFF) {
- requestGlobalDisplayStateInternal(state);
+ requestGlobalDisplayStateInternal(state, brightness);
}
callbacks.onDisplayStateChange(state);
if (state != Display.STATE_OFF) {
- requestGlobalDisplayStateInternal(state);
+ requestGlobalDisplayStateInternal(state, brightness);
}
}
};
diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java
index cf1f4b0..f74601e 100644
--- a/services/core/java/com/android/server/display/DisplayPowerController.java
+++ b/services/core/java/com/android/server/display/DisplayPowerController.java
@@ -19,7 +19,6 @@
import com.android.internal.app.IBatteryStats;
import com.android.server.LocalServices;
import com.android.server.am.BatteryStatsService;
-import com.android.server.lights.LightsManager;
import android.animation.Animator;
import android.animation.ObjectAnimator;
@@ -122,9 +121,6 @@
// Battery stats.
private final IBatteryStats mBatteryStats;
- // The lights service.
- private final LightsManager mLights;
-
// The sensor manager.
private final SensorManager mSensorManager;
@@ -260,7 +256,6 @@
mCallbacks = callbacks;
mBatteryStats = BatteryStatsService.getService();
- mLights = LocalServices.getService(LightsManager.class);
mSensorManager = sensorManager;
mWindowManagerPolicy = LocalServices.getService(WindowManagerPolicy.class);
mBlanker = blanker;
@@ -443,7 +438,6 @@
// Initialize the power state object for the default display.
// In the future, we might manage multiple displays independently.
mPowerState = new DisplayPowerState(mBlanker,
- mLights.getLight(LightsManager.LIGHT_ID_BACKLIGHT),
new ColorFade(Display.DEFAULT_DISPLAY));
mColorFadeOnAnimator = ObjectAnimator.ofFloat(
diff --git a/services/core/java/com/android/server/display/DisplayPowerState.java b/services/core/java/com/android/server/display/DisplayPowerState.java
index a3c9738..f53ccc9 100644
--- a/services/core/java/com/android/server/display/DisplayPowerState.java
+++ b/services/core/java/com/android/server/display/DisplayPowerState.java
@@ -16,13 +16,10 @@
package com.android.server.display;
-import com.android.server.lights.Light;
-
import android.content.Context;
import android.os.Handler;
import android.os.Looper;
import android.os.PowerManager;
-import android.os.Trace;
import android.util.FloatProperty;
import android.util.IntProperty;
import android.util.Slog;
@@ -56,7 +53,6 @@
private final Handler mHandler;
private final Choreographer mChoreographer;
private final DisplayBlanker mBlanker;
- private final Light mBacklight;
private final ColorFade mColorFade;
private final PhotonicModulator mPhotonicModulator;
@@ -72,12 +68,11 @@
private Runnable mCleanListener;
- public DisplayPowerState(DisplayBlanker blanker, Light backlight, ColorFade electronBeam) {
+ public DisplayPowerState(DisplayBlanker blanker, ColorFade colorFade) {
mHandler = new Handler(true /*async*/);
mChoreographer = Choreographer.getInstance();
mBlanker = blanker;
- mBacklight = backlight;
- mColorFade = electronBeam;
+ mColorFade = colorFade;
mPhotonicModulator = new PhotonicModulator();
mPhotonicModulator.start();
@@ -415,35 +410,7 @@
Slog.d(TAG, "Updating screen state: state="
+ Display.stateToString(state) + ", backlight=" + backlight);
}
- boolean suspending = Display.isSuspendedState(state);
- if (stateChanged && !suspending) {
- requestDisplayState(state);
- }
- if (backlightChanged) {
- setBrightness(backlight);
- }
- if (stateChanged && suspending) {
- requestDisplayState(state);
- }
- }
- }
-
- private void requestDisplayState(int state) {
- Trace.traceBegin(Trace.TRACE_TAG_POWER, "requestDisplayState("
- + Display.stateToString(state) + ")");
- try {
- mBlanker.requestDisplayState(state);
- } finally {
- Trace.traceEnd(Trace.TRACE_TAG_POWER);
- }
- }
-
- private void setBrightness(int backlight) {
- Trace.traceBegin(Trace.TRACE_TAG_POWER, "setBrightness(" + backlight + ")");
- try {
- mBacklight.setBrightness(backlight);
- } finally {
- Trace.traceEnd(Trace.TRACE_TAG_POWER);
+ mBlanker.requestDisplayState(state, backlight);
}
}
}
diff --git a/services/core/java/com/android/server/display/LocalDisplayAdapter.java b/services/core/java/com/android/server/display/LocalDisplayAdapter.java
index 5ebe64d..e87f265 100644
--- a/services/core/java/com/android/server/display/LocalDisplayAdapter.java
+++ b/services/core/java/com/android/server/display/LocalDisplayAdapter.java
@@ -16,10 +16,15 @@
package com.android.server.display;
+import com.android.server.LocalServices;
+import com.android.server.lights.Light;
+import com.android.server.lights.LightsManager;
+
import android.content.Context;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
+import android.os.PowerManager;
import android.os.SystemProperties;
import android.os.Trace;
import android.util.Slog;
@@ -40,6 +45,7 @@
*/
final class LocalDisplayAdapter extends DisplayAdapter {
private static final String TAG = "LocalDisplayAdapter";
+ private static final boolean DEBUG = false;
private static final String UNIQUE_ID_PREFIX = "local:";
@@ -132,14 +138,17 @@
private final int mBuiltInDisplayId;
private final SurfaceControl.PhysicalDisplayInfo mPhys;
private final int mDefaultPhysicalDisplayInfo;
+ private final Light mBacklight;
private DisplayDeviceInfo mInfo;
private boolean mHavePendingChanges;
private int mState = Display.STATE_UNKNOWN;
+ private int mBrightness = PowerManager.BRIGHTNESS_DEFAULT;
private float[] mSupportedRefreshRates;
private int[] mRefreshRateConfigIndices;
private float mLastRequestedRefreshRate;
+
public LocalDisplayDevice(IBinder displayToken, int builtInDisplayId,
SurfaceControl.PhysicalDisplayInfo[] physicalDisplayInfos, int activeDisplayInfo) {
super(LocalDisplayAdapter.this, displayToken, UNIQUE_ID_PREFIX + builtInDisplayId);
@@ -148,6 +157,13 @@
physicalDisplayInfos[activeDisplayInfo]);
mDefaultPhysicalDisplayInfo = activeDisplayInfo;
updateSupportedRefreshRatesLocked(physicalDisplayInfos, mPhys);
+
+ if (mBuiltInDisplayId == SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN) {
+ LightsManager lights = LocalServices.getService(LightsManager.class);
+ mBacklight = lights.getLight(LightsManager.LIGHT_ID_BACKLIGHT);
+ } else {
+ mBacklight = null;
+ }
}
public boolean updatePhysicalDisplayInfoLocked(
@@ -225,28 +241,91 @@
}
@Override
- public Runnable requestDisplayStateLocked(final int state) {
- if (mState != state) {
+ public Runnable requestDisplayStateLocked(final int state, final int brightness) {
+ // Assume that the brightness is off if the display is being turned off.
+ assert state != Display.STATE_OFF || brightness == PowerManager.BRIGHTNESS_OFF;
+
+ final boolean stateChanged = (mState != state);
+ final boolean brightnessChanged = (mBrightness != brightness) && mBacklight != null;
+ if (stateChanged || brightnessChanged) {
final int displayId = mBuiltInDisplayId;
final IBinder token = getDisplayTokenLocked();
- final int mode = getPowerModeForState(state);
- mState = state;
- updateDeviceInfoLocked();
+ final int oldState = mState;
- // Defer actually setting the display power mode until we have exited
+ if (stateChanged) {
+ mState = state;
+ updateDeviceInfoLocked();
+ }
+
+ if (brightnessChanged) {
+ mBrightness = brightness;
+ }
+
+ // Defer actually setting the display state until after we have exited
// the critical section since it can take hundreds of milliseconds
// to complete.
return new Runnable() {
@Override
public void run() {
- Trace.traceBegin(Trace.TRACE_TAG_POWER, "requestDisplayState("
- + Display.stateToString(state) + ", id=" + displayId + ")");
+ // Exit a suspended state before making any changes.
+ int currentState = oldState;
+ if (Display.isSuspendedState(oldState)
+ || oldState == Display.STATE_UNKNOWN) {
+ if (!Display.isSuspendedState(state)) {
+ setDisplayState(state);
+ currentState = state;
+ } else if (state == Display.STATE_DOZE_SUSPEND
+ || oldState == Display.STATE_DOZE_SUSPEND) {
+ setDisplayState(Display.STATE_DOZE);
+ currentState = Display.STATE_DOZE;
+ } else {
+ return; // old state and new state is off
+ }
+ }
+
+ // Apply brightness changes given that we are in a non-suspended state.
+ if (brightnessChanged) {
+ setDisplayBrightness(brightness);
+ }
+
+ // Enter the final desired state, possibly suspended.
+ if (state != currentState) {
+ setDisplayState(state);
+ }
+ }
+
+ private void setDisplayState(int state) {
+ if (DEBUG) {
+ Slog.d(TAG, "setDisplayState("
+ + "id=" + displayId
+ + ", state=" + Display.stateToString(state) + ")");
+ }
+
+ Trace.traceBegin(Trace.TRACE_TAG_POWER, "setDisplayState("
+ + "id=" + displayId
+ + ", state=" + Display.stateToString(state) + ")");
try {
+ final int mode = getPowerModeForState(state);
SurfaceControl.setDisplayPowerMode(token, mode);
} finally {
Trace.traceEnd(Trace.TRACE_TAG_POWER);
}
}
+
+ private void setDisplayBrightness(int brightness) {
+ if (DEBUG) {
+ Slog.d(TAG, "setDisplayBrightness("
+ + "id=" + displayId + ", brightness=" + brightness + ")");
+ }
+
+ Trace.traceBegin(Trace.TRACE_TAG_POWER, "setDisplayBrightness("
+ + "id=" + displayId + ", brightness=" + brightness + ")");
+ try {
+ mBacklight.setBrightness(brightness);
+ } finally {
+ Trace.traceEnd(Trace.TRACE_TAG_POWER);
+ }
+ }
};
}
return null;
@@ -278,6 +357,8 @@
pw.println("mBuiltInDisplayId=" + mBuiltInDisplayId);
pw.println("mPhys=" + mPhys);
pw.println("mState=" + Display.stateToString(mState));
+ pw.println("mBrightness=" + mBrightness);
+ pw.println("mBacklight=" + mBacklight);
}
private void updateDeviceInfoLocked() {
diff --git a/services/core/java/com/android/server/display/VirtualDisplayAdapter.java b/services/core/java/com/android/server/display/VirtualDisplayAdapter.java
index f181cd5..6f59b54 100644
--- a/services/core/java/com/android/server/display/VirtualDisplayAdapter.java
+++ b/services/core/java/com/android/server/display/VirtualDisplayAdapter.java
@@ -221,7 +221,7 @@
}
@Override
- public Runnable requestDisplayStateLocked(int state) {
+ public Runnable requestDisplayStateLocked(int state, int brightness) {
if (state != mDisplayState) {
mDisplayState = state;
if (state == Display.STATE_OFF) {
diff --git a/services/core/java/com/android/server/lights/LightsService.java b/services/core/java/com/android/server/lights/LightsService.java
index 2da9d8e..ed884ef 100644
--- a/services/core/java/com/android/server/lights/LightsService.java
+++ b/services/core/java/com/android/server/lights/LightsService.java
@@ -19,16 +19,11 @@
import com.android.server.SystemService;
import android.content.Context;
-import android.content.pm.PackageManager;
import android.os.Handler;
-import android.os.IHardwareService;
import android.os.Message;
import android.os.Trace;
import android.util.Slog;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-
public class LightsService extends SystemService {
static final String TAG = "LightsService";
static final boolean DEBUG = false;
@@ -124,46 +119,6 @@
private boolean mFlashing;
}
- /* This class implements an obsolete API that was removed after eclair and re-added during the
- * final moments of the froyo release to support flashlight apps that had been using the private
- * IHardwareService API. This is expected to go away in the next release.
- */
- private final IHardwareService.Stub mLegacyFlashlightHack = new IHardwareService.Stub() {
-
- private static final String FLASHLIGHT_FILE = "/sys/class/leds/spotlight/brightness";
-
- public boolean getFlashlightEnabled() {
- try {
- FileInputStream fis = new FileInputStream(FLASHLIGHT_FILE);
- int result = fis.read();
- fis.close();
- return (result != '0');
- } catch (Exception e) {
- return false;
- }
- }
-
- public void setFlashlightEnabled(boolean on) {
- final Context context = getContext();
- if (context.checkCallingOrSelfPermission(android.Manifest.permission.FLASHLIGHT)
- != PackageManager.PERMISSION_GRANTED &&
- context.checkCallingOrSelfPermission(android.Manifest.permission.HARDWARE_TEST)
- != PackageManager.PERMISSION_GRANTED) {
- throw new SecurityException("Requires FLASHLIGHT or HARDWARE_TEST permission");
- }
- try {
- FileOutputStream fos = new FileOutputStream(FLASHLIGHT_FILE);
- byte[] bytes = new byte[2];
- bytes[0] = (byte)(on ? '1' : '0');
- bytes[1] = '\n';
- fos.write(bytes);
- fos.close();
- } catch (Exception e) {
- // fail silently
- }
- }
- };
-
public LightsService(Context context) {
super(context);
@@ -176,13 +131,12 @@
@Override
public void onStart() {
- publishBinderService("hardware", mLegacyFlashlightHack);
publishLocalService(LightsManager.class, mService);
}
private final LightsManager mService = new LightsManager() {
@Override
- public com.android.server.lights.Light getLight(int id) {
+ public Light getLight(int id) {
if (id < LIGHT_ID_COUNT) {
return mLights[id];
} else {
diff --git a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
index 99cf8df..54be380 100644
--- a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
+++ b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
@@ -538,6 +538,11 @@
@Override
public void onUserSwitchComplete(int newUserId) throws RemoteException {
}
+
+ @Override
+ public void onForegroundProfileSwitch(int newProfileId) {
+ // Ignore.
+ }
});
} catch (RemoteException e) {
// TODO Auto-generated catch block
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 53da75b..593853c 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -325,6 +325,9 @@
// initialize power management features.
mActivityManagerService.initPowerManagement();
+ // Manages LEDs and display backlight so we need it to bring up the display.
+ mSystemServiceManager.startService(LightsService.class);
+
// Display manager is needed to provide display metrics before package manager
// starts up.
mDisplayManagerService = mSystemServiceManager.startService(DisplayManagerService.class);
@@ -363,9 +366,6 @@
* Starts some essential services that are not tangled up in the bootstrap process.
*/
private void startCoreServices() {
- // Manages LEDs and display backlight.
- mSystemServiceManager.startService(LightsService.class);
-
// Tracks the battery level. Requires LightService.
mSystemServiceManager.startService(BatteryService.class);