Merge "Expose android.media.AudioManager.getProperty()" into jb-mr1-dev
diff --git a/CleanSpec.mk b/CleanSpec.mk
index 61e5b4c..8711ad7 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -134,6 +134,7 @@
$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/core/java/android/accessibilityservice/IAccessibilityServiceClient.P)
$(call add-clean-step, rm -f $(PRODUCT_OUT)/system/media/video/Disco*)
$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework_intermediates)
+$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/APPS/ImageProcessing_intermediates)
# ************************************************
# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
# ************************************************
diff --git a/api/current.txt b/api/current.txt
index 3e9b7d9..b81a87b 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -18794,6 +18794,7 @@
field public static final java.lang.String DEVELOPMENT_SETTINGS_ENABLED = "development_settings_enabled";
field public static final java.lang.String DEVICE_PROVISIONED = "device_provisioned";
field public static final java.lang.String INSTALL_NON_MARKET_APPS = "install_non_market_apps";
+ field public static final java.lang.String MODE_RINGER = "mode_ringer";
field public static final java.lang.String NETWORK_PREFERENCE = "network_preference";
field public static final java.lang.String RADIO_BLUETOOTH = "bluetooth";
field public static final java.lang.String RADIO_CELL = "cell";
@@ -18957,7 +18958,7 @@
field public static final deprecated java.lang.String LOCK_PATTERN_TACTILE_FEEDBACK_ENABLED = "lock_pattern_tactile_feedback_enabled";
field public static final deprecated java.lang.String LOCK_PATTERN_VISIBLE = "lock_pattern_visible_pattern";
field public static final deprecated java.lang.String LOGGING_ID = "logging_id";
- field public static final java.lang.String MODE_RINGER = "mode_ringer";
+ field public static final deprecated java.lang.String MODE_RINGER = "mode_ringer";
field public static final java.lang.String MODE_RINGER_STREAMS_AFFECTED = "mode_ringer_streams_affected";
field public static final java.lang.String MUTE_STREAMS_AFFECTED = "mute_streams_affected";
field public static final deprecated java.lang.String NETWORK_PREFERENCE = "network_preference";
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 9b82f2a..81d87659 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -52,6 +52,7 @@
import android.os.Binder;
import android.os.Bundle;
import android.os.Debug;
+import android.os.DropBoxManager;
import android.os.Environment;
import android.os.Handler;
import android.os.IBinder;
@@ -108,6 +109,7 @@
import java.util.TimeZone;
import java.util.regex.Pattern;
+import libcore.io.DropBox;
import libcore.io.EventLogger;
import libcore.io.IoUtils;
@@ -4831,7 +4833,10 @@
"Unable to instantiate Application():" + e.toString(), e);
}
}
-
+
+ // add dropbox logging to libcore
+ DropBox.setReporter(new DropBoxReporter());
+
ViewRootImpl.addConfigCallback(new ComponentCallbacks2() {
public void onConfigurationChanged(Configuration newConfig) {
synchronized (mPackages) {
@@ -4887,6 +4892,25 @@
}
}
+ private class DropBoxReporter implements DropBox.Reporter {
+
+ private DropBoxManager dropBox;
+
+ public DropBoxReporter() {
+ dropBox = (DropBoxManager) getSystemContext().getSystemService(Context.DROPBOX_SERVICE);
+ }
+
+ @Override
+ public void addData(String tag, byte[] data, int flags) {
+ dropBox.addData(tag, data, flags);
+ }
+
+ @Override
+ public void addText(String tag, String data) {
+ dropBox.addText(tag, data);
+ }
+ }
+
public static void main(String[] args) {
SamplingProfilerIntegration.start();
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index cb83dc2..7896450 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -1923,6 +1923,7 @@
contentView.setViewVisibility(rowId, View.GONE);
}
+
int i=0;
while (i < mTexts.size() && i < rowIds.length) {
CharSequence str = mTexts.get(i);
@@ -1933,11 +1934,11 @@
i++;
}
- if (mTexts.size() > rowIds.length) {
- contentView.setViewVisibility(R.id.inbox_more, View.VISIBLE);
- } else {
- contentView.setViewVisibility(R.id.inbox_more, View.GONE);
- }
+ contentView.setViewVisibility(R.id.inbox_end_pad,
+ mTexts.size() > 0 ? View.VISIBLE : View.GONE);
+
+ contentView.setViewVisibility(R.id.inbox_more,
+ mTexts.size() > rowIds.length ? View.VISIBLE : View.GONE);
return contentView;
}
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index bb118b2..cc9abff 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -934,6 +934,7 @@
MOVED_TO_GLOBAL.add(Settings.Global.POWER_SOUNDS_ENABLED);
MOVED_TO_GLOBAL.add(Settings.Global.STAY_ON_WHILE_PLUGGED_IN);
MOVED_TO_GLOBAL.add(Settings.Global.WIFI_SLEEP_POLICY);
+ MOVED_TO_GLOBAL.add(Settings.Global.MODE_RINGER);
}
private static void lazyInitCache() {
@@ -1497,6 +1498,12 @@
@Deprecated
public static final int WIFI_SLEEP_POLICY_NEVER = Global.WIFI_SLEEP_POLICY_NEVER;
+ /**
+ * @deprecated Use {@link android.provider.Settings.Global#MODE_RINGER} instead
+ */
+ @Deprecated
+ public static final String MODE_RINGER = Global.MODE_RINGER;
+
//TODO: deprecate static IP constants
/**
* Whether to use static IP and other static network attributes.
@@ -1666,13 +1673,6 @@
public static final String ALWAYS_FINISH_ACTIVITIES =
"always_finish_activities";
-
- /**
- * Ringer mode. This is used internally, changing this value will not
- * change the ringer mode. See AudioManager.
- */
- public static final String MODE_RINGER = "mode_ringer";
-
/**
* Determines which streams are affected by ringer mode changes. The
* stream type's bit should be set to 1 if it should be muted when going
@@ -5738,7 +5738,11 @@
*/
public static final String WTF_IS_FATAL = "wtf_is_fatal";
-
+ /**
+ * Ringer mode. This is used internally, changing this value will not
+ * change the ringer mode. See AudioManager.
+ */
+ public static final String MODE_RINGER = "mode_ringer";
// Populated lazily, guarded by class object:
diff --git a/core/java/android/text/format/DateUtils.java b/core/java/android/text/format/DateUtils.java
index 0babcc5..1060bd8 100644
--- a/core/java/android/text/format/DateUtils.java
+++ b/core/java/android/text/format/DateUtils.java
@@ -45,7 +45,6 @@
private static final String FAST_FORMAT_HMMSS = "%1$d:%2$02d:%3$02d";
private static final String FAST_FORMAT_MMSS = "%1$02d:%2$02d";
- private static final char TIME_PADDING = '0';
private static final char TIME_SEPARATOR = ':';
@@ -648,33 +647,36 @@
}
}
+ private static void append(StringBuilder sb, long value, boolean pad, char zeroDigit) {
+ if (value < 10) {
+ if (pad) {
+ sb.append(zeroDigit);
+ }
+ } else {
+ sb.append((char) (zeroDigit + (value / 10)));
+ }
+ sb.append((char) (zeroDigit + (value % 10)));
+ }
+
/**
- * Fast formatting of h:mm:ss
+ * Fast formatting of h:mm:ss.
*/
private static String formatElapsedTime(StringBuilder recycle, String format, long hours,
long minutes, long seconds) {
if (FAST_FORMAT_HMMSS.equals(format)) {
+ char zeroDigit = LocaleData.get(Locale.getDefault()).zeroDigit;
+
StringBuilder sb = recycle;
if (sb == null) {
sb = new StringBuilder(8);
} else {
sb.setLength(0);
}
- sb.append(hours);
+ append(sb, hours, false, zeroDigit);
sb.append(TIME_SEPARATOR);
- if (minutes < 10) {
- sb.append(TIME_PADDING);
- } else {
- sb.append(toDigitChar(minutes / 10));
- }
- sb.append(toDigitChar(minutes % 10));
+ append(sb, minutes, true, zeroDigit);
sb.append(TIME_SEPARATOR);
- if (seconds < 10) {
- sb.append(TIME_PADDING);
- } else {
- sb.append(toDigitChar(seconds / 10));
- }
- sb.append(toDigitChar(seconds % 10));
+ append(sb, seconds, true, zeroDigit);
return sb.toString();
} else {
return String.format(format, hours, minutes, seconds);
@@ -682,40 +684,28 @@
}
/**
- * Fast formatting of m:ss
+ * Fast formatting of mm:ss.
*/
private static String formatElapsedTime(StringBuilder recycle, String format, long minutes,
long seconds) {
if (FAST_FORMAT_MMSS.equals(format)) {
+ char zeroDigit = LocaleData.get(Locale.getDefault()).zeroDigit;
+
StringBuilder sb = recycle;
if (sb == null) {
sb = new StringBuilder(8);
} else {
sb.setLength(0);
}
- if (minutes < 10) {
- sb.append(TIME_PADDING);
- } else {
- sb.append(toDigitChar(minutes / 10));
- }
- sb.append(toDigitChar(minutes % 10));
+ append(sb, minutes, false, zeroDigit);
sb.append(TIME_SEPARATOR);
- if (seconds < 10) {
- sb.append(TIME_PADDING);
- } else {
- sb.append(toDigitChar(seconds / 10));
- }
- sb.append(toDigitChar(seconds % 10));
+ append(sb, seconds, true, zeroDigit);
return sb.toString();
} else {
return String.format(format, minutes, seconds);
}
}
- private static char toDigitChar(long digit) {
- return (char) (digit + '0');
- }
-
/**
* Format a date / time such that if the then is on the same day as now, it shows
* just the time and if it's a different day, it shows just the date.
@@ -1387,6 +1377,14 @@
String endMonthDayString = isInstant ? null : endDate.format(MONTH_DAY_FORMAT);
String endYearString = isInstant ? null : endDate.format(YEAR_FORMAT);
+ String startStandaloneMonthString = startMonthString;
+ String endStandaloneMonthString = endMonthString;
+ // We need standalone months for these strings in Persian (fa): http://b/6811327
+ if (!numericDate && !abbrevMonth && Locale.getDefault().getLanguage().equals("fa")) {
+ startStandaloneMonthString = startDate.format("%-B");
+ endStandaloneMonthString = endDate.format("%-B");
+ }
+
if (startMonthNum != endMonthNum) {
// Same year, different month.
// Example: "October 28 - November 3"
@@ -1407,7 +1405,8 @@
startWeekDayString, startMonthString, startMonthDayString,
startYearString, startTimeString,
endWeekDayString, endMonthString, endMonthDayString,
- endYearString, endTimeString);
+ endYearString, endTimeString,
+ startStandaloneMonthString, endStandaloneMonthString);
}
if (startDay != endDay) {
@@ -1426,7 +1425,8 @@
startWeekDayString, startMonthString, startMonthDayString,
startYearString, startTimeString,
endWeekDayString, endMonthString, endMonthDayString,
- endYearString, endTimeString);
+ endYearString, endTimeString,
+ startStandaloneMonthString, endStandaloneMonthString);
}
// Same start and end day
diff --git a/core/java/android/text/format/Time.java b/core/java/android/text/format/Time.java
index 45d5a70..5ef86b1 100644
--- a/core/java/android/text/format/Time.java
+++ b/core/java/android/text/format/Time.java
@@ -151,6 +151,9 @@
private static String sDateTimeFormat;
private static String sAm;
private static String sPm;
+ private static char sZeroDigit;
+
+ // Referenced by native code.
private static String sDateCommand = "%a %b %e %H:%M:%S %Z %Y";
/**
@@ -323,6 +326,7 @@
sAm = localeData.amPm[0];
sPm = localeData.amPm[1];
+ sZeroDigit = localeData.zeroDigit;
sShortMonths = localeData.shortMonthNames;
sLongMonths = localeData.longMonthNames;
@@ -338,12 +342,32 @@
sLocale = locale;
}
- return format1(format);
+ String result = format1(format);
+ if (sZeroDigit != '0') {
+ result = localizeDigits(result);
+ }
+ return result;
}
}
native private String format1(String format);
+ // TODO: unify this with java.util.Formatter's copy.
+ private String localizeDigits(String s) {
+ int length = s.length();
+ int offsetToLocalizedDigits = sZeroDigit - '0';
+ StringBuilder result = new StringBuilder(length);
+ for (int i = 0; i < length; ++i) {
+ char ch = s.charAt(i);
+ if (ch >= '0' && ch <= '9') {
+ ch += offsetToLocalizedDigits;
+ }
+ result.append(ch);
+ }
+ return result.toString();
+ }
+
+
/**
* Return the current time in YYYYMMDDTHHMMSS<tz> format
*/
@@ -673,7 +697,7 @@
int minutes = (offset % 3600) / 60;
int hours = offset / 3600;
- return String.format("%s%s%02d:%02d", base, sign, hours, minutes);
+ return String.format(Locale.US, "%s%s%02d:%02d", base, sign, hours, minutes);
}
}
diff --git a/core/java/android/webkit/WebViewCore.java b/core/java/android/webkit/WebViewCore.java
index ddc0319..33fe834 100644
--- a/core/java/android/webkit/WebViewCore.java
+++ b/core/java/android/webkit/WebViewCore.java
@@ -2528,6 +2528,9 @@
adjust = (float) mContext.getResources().getDisplayMetrics().densityDpi
/ mViewportDensityDpi;
}
+ // We make bad assumptions about multiplying and dividing by 100, force
+ // them to be true with this hack
+ adjust = ((int) (adjust * 100)) / 100.0f;
// Remove any update density messages in flight.
// If the density is indeed different from WebView's default scale,
// a new message will be queued.
diff --git a/core/java/android/webkit/ZoomManager.java b/core/java/android/webkit/ZoomManager.java
index 80a6782..1d864e5 100644
--- a/core/java/android/webkit/ZoomManager.java
+++ b/core/java/android/webkit/ZoomManager.java
@@ -287,6 +287,7 @@
if (!exceedsMinScaleIncrement(mMinZoomScale, mMaxZoomScale)) {
mMaxZoomScale = mMinZoomScale;
}
+ sanitizeMinMaxScales();
}
public final float getScale() {
@@ -909,6 +910,14 @@
}
}
+ private void sanitizeMinMaxScales() {
+ if (mMinZoomScale > mMaxZoomScale) {
+ Log.w(LOGTAG, "mMinZoom > mMaxZoom!!! " + mMinZoomScale + " > " + mMaxZoomScale,
+ new Exception());
+ mMaxZoomScale = mMinZoomScale;
+ }
+ }
+
public void onSizeChanged(int w, int h, int ow, int oh) {
// reset zoom and anchor to the top left corner of the screen
// unless we are already zooming
@@ -933,6 +942,7 @@
if (mInitialScale > 0 && mInitialScale < mMinZoomScale) {
mMinZoomScale = mInitialScale;
}
+ sanitizeMinMaxScales();
}
dismissZoomPicker();
@@ -1004,6 +1014,7 @@
} else {
mMaxZoomScale = viewState.mMaxScale;
}
+ sanitizeMinMaxScales();
}
/**
@@ -1033,6 +1044,7 @@
if (!mMinZoomScaleFixed || settings.getUseWideViewPort()) {
mMinZoomScale = newZoomOverviewScale;
mMaxZoomScale = Math.max(mMaxZoomScale, mMinZoomScale);
+ sanitizeMinMaxScales();
}
// fit the content width to the current view for the first new picture
// after first layout.
@@ -1113,6 +1125,7 @@
mMinZoomScale = (mInitialScale > 0) ?
Math.min(mInitialScale, overviewScale) : overviewScale;
mMaxZoomScale = Math.max(mMaxZoomScale, mMinZoomScale);
+ sanitizeMinMaxScales();
}
if (!mWebView.drawHistory()) {
diff --git a/core/res/res/layout/notification_action_list.xml b/core/res/res/layout/notification_action_list.xml
index 591c9ea..400decc 100644
--- a/core/res/res/layout/notification_action_list.xml
+++ b/core/res/res/layout/notification_action_list.xml
@@ -21,6 +21,7 @@
android:layout_height="wrap_content"
android:orientation="horizontal"
android:visibility="gone"
+ android:layout_marginBottom="8dp"
android:showDividers="middle"
android:divider="?android:attr/listDivider"
android:dividerPadding="12dp"
diff --git a/core/res/res/layout/notification_template_big_text.xml b/core/res/res/layout/notification_template_big_text.xml
index 988a81f..01f1acf 100644
--- a/core/res/res/layout/notification_template_big_text.xml
+++ b/core/res/res/layout/notification_template_big_text.xml
@@ -34,13 +34,14 @@
android:layout_gravity="fill_vertical"
android:layout_marginStart="@dimen/notification_large_icon_width"
android:orientation="vertical"
- android:paddingTop="2dp"
+ android:paddingTop="0dp"
android:paddingBottom="2dp"
android:gravity="top"
>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
+ android:minHeight="@dimen/notification_large_icon_height"
android:orientation="vertical"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
@@ -50,7 +51,7 @@
android:id="@+id/line1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:paddingTop="6dp"
+ android:paddingTop="8dp"
android:orientation="horizontal"
android:layout_gravity="top"
android:layout_weight="0"
diff --git a/core/res/res/layout/notification_template_inbox.xml b/core/res/res/layout/notification_template_inbox.xml
index 6ebb443..1b7e659 100644
--- a/core/res/res/layout/notification_template_inbox.xml
+++ b/core/res/res/layout/notification_template_inbox.xml
@@ -36,163 +36,178 @@
android:layout_marginStart="@dimen/notification_large_icon_width"
android:minHeight="@dimen/notification_large_icon_height"
android:orientation="vertical"
- android:paddingTop="2dp"
+ android:paddingTop="0dp"
android:paddingBottom="2dp"
android:gravity="top"
>
<LinearLayout
- android:id="@+id/line1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:layout_marginStart="8dp"
- android:layout_marginEnd="8dp"
- android:paddingTop="6dp"
- android:orientation="horizontal"
- android:layout_weight="0"
+ android:minHeight="@dimen/notification_large_icon_height"
+ android:paddingTop="2dp"
+ android:orientation="vertical"
>
- <TextView android:id="@+id/title"
- android:textAppearance="@style/TextAppearance.StatusBar.EventContent.Title"
+ <LinearLayout
+ android:id="@+id/line1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
+ android:layout_marginStart="8dp"
+ android:layout_marginEnd="8dp"
+ android:paddingTop="6dp"
+ android:orientation="horizontal"
+ android:layout_weight="0"
+ >
+ <TextView android:id="@+id/title"
+ android:textAppearance="@style/TextAppearance.StatusBar.EventContent.Title"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:singleLine="true"
+ android:ellipsize="marquee"
+ android:fadingEdge="horizontal"
+ android:layout_weight="1"
+ />
+ <ViewStub android:id="@+id/time"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ android:layout_weight="0"
+ android:visibility="gone"
+ android:layout="@layout/notification_template_part_time"
+ />
+ <ViewStub android:id="@+id/chronometer"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ android:layout_weight="0"
+ android:visibility="gone"
+ android:layout="@layout/notification_template_part_chronometer"
+ />
+ </LinearLayout>
+ <TextView android:id="@+id/text2"
+ android:textAppearance="@style/TextAppearance.StatusBar.EventContent.Line2"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="-2dp"
+ android:layout_marginBottom="-2dp"
+ android:layout_marginStart="8dp"
+ android:layout_marginEnd="8dp"
android:singleLine="true"
- android:ellipsize="marquee"
android:fadingEdge="horizontal"
+ android:ellipsize="marquee"
+ android:visibility="gone"
+ android:layout_weight="0"
+ />
+ <ProgressBar
+ android:id="@android:id/progress"
+ android:layout_width="match_parent"
+ android:layout_height="12dp"
+ android:layout_marginStart="8dp"
+ android:layout_marginEnd="8dp"
+ android:visibility="gone"
+ android:layout_weight="0"
+ style="?android:attr/progressBarStyleHorizontal"
+ />
+ <TextView android:id="@+id/inbox_text0"
+ android:textAppearance="@style/TextAppearance.StatusBar.EventContent"
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:layout_marginStart="8dp"
+ android:layout_marginEnd="8dp"
+ android:singleLine="true"
+ android:ellipsize="end"
+ android:visibility="gone"
android:layout_weight="1"
/>
- <ViewStub android:id="@+id/time"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center"
- android:layout_weight="0"
+ <TextView android:id="@+id/inbox_text1"
+ android:textAppearance="@style/TextAppearance.StatusBar.EventContent"
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:layout_marginStart="8dp"
+ android:layout_marginEnd="8dp"
+ android:singleLine="true"
+ android:ellipsize="end"
android:visibility="gone"
- android:layout="@layout/notification_template_part_time"
+ android:layout_weight="1"
/>
- <ViewStub android:id="@+id/chronometer"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center"
- android:layout_weight="0"
+ <TextView android:id="@+id/inbox_text2"
+ android:textAppearance="@style/TextAppearance.StatusBar.EventContent"
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:layout_marginStart="8dp"
+ android:layout_marginEnd="8dp"
+ android:singleLine="true"
+ android:ellipsize="end"
android:visibility="gone"
- android:layout="@layout/notification_template_part_chronometer"
+ android:layout_weight="1"
/>
+ <TextView android:id="@+id/inbox_text3"
+ android:textAppearance="@style/TextAppearance.StatusBar.EventContent"
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:layout_marginStart="8dp"
+ android:layout_marginEnd="8dp"
+ android:singleLine="true"
+ android:ellipsize="end"
+ android:visibility="gone"
+ android:layout_weight="1"
+ />
+ <TextView android:id="@+id/inbox_text4"
+ android:textAppearance="@style/TextAppearance.StatusBar.EventContent"
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:layout_marginStart="8dp"
+ android:singleLine="true"
+ android:ellipsize="end"
+ android:visibility="gone"
+ android:layout_weight="1"
+ />
+ <TextView android:id="@+id/inbox_text5"
+ android:textAppearance="@style/TextAppearance.StatusBar.EventContent"
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:layout_marginStart="8dp"
+ android:layout_marginEnd="8dp"
+ android:singleLine="true"
+ android:ellipsize="end"
+ android:visibility="gone"
+ android:layout_weight="1"
+ />
+ <TextView android:id="@+id/inbox_text6"
+ android:textAppearance="@style/TextAppearance.StatusBar.EventContent"
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:layout_marginStart="8dp"
+ android:layout_marginEnd="8dp"
+ android:singleLine="true"
+ android:ellipsize="end"
+ android:visibility="gone"
+ android:layout_weight="1"
+ />
+ <TextView android:id="@+id/inbox_more"
+ android:textAppearance="@style/TextAppearance.StatusBar.EventContent"
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:layout_marginStart="8dp"
+ android:layout_marginEnd="8dp"
+ android:singleLine="true"
+ android:ellipsize="end"
+ android:visibility="gone"
+ android:layout_weight="1"
+ android:text="@android:string/ellipsis"
+ />
+ <FrameLayout
+ android:id="@+id/inbox_end_pad"
+ android:layout_width="match_parent"
+ android:layout_height="8dip"
+ android:visibility="gone"
+ android:layout_weight="0"
+ />
</LinearLayout>
- <TextView android:id="@+id/text2"
- android:textAppearance="@style/TextAppearance.StatusBar.EventContent.Line2"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginTop="-2dp"
- android:layout_marginBottom="-2dp"
- android:layout_marginStart="8dp"
- android:layout_marginEnd="8dp"
- android:singleLine="true"
- android:fadingEdge="horizontal"
- android:ellipsize="marquee"
- android:visibility="gone"
- android:layout_weight="0"
- />
- <ProgressBar
- android:id="@android:id/progress"
- android:layout_width="match_parent"
- android:layout_height="12dp"
- android:layout_marginStart="8dp"
- android:layout_marginEnd="8dp"
- android:visibility="gone"
- android:layout_weight="0"
- style="?android:attr/progressBarStyleHorizontal"
- />
- <TextView android:id="@+id/inbox_text0"
- android:textAppearance="@style/TextAppearance.StatusBar.EventContent"
- android:layout_width="match_parent"
- android:layout_height="0dp"
- android:layout_marginStart="8dp"
- android:layout_marginEnd="8dp"
- android:singleLine="true"
- android:ellipsize="end"
- android:visibility="gone"
- android:layout_weight="1"
- />
- <TextView android:id="@+id/inbox_text1"
- android:textAppearance="@style/TextAppearance.StatusBar.EventContent"
- android:layout_width="match_parent"
- android:layout_height="0dp"
- android:layout_marginStart="8dp"
- android:layout_marginEnd="8dp"
- android:singleLine="true"
- android:ellipsize="end"
- android:visibility="gone"
- android:layout_weight="1"
- />
- <TextView android:id="@+id/inbox_text2"
- android:textAppearance="@style/TextAppearance.StatusBar.EventContent"
- android:layout_width="match_parent"
- android:layout_height="0dp"
- android:layout_marginStart="8dp"
- android:layout_marginEnd="8dp"
- android:singleLine="true"
- android:ellipsize="end"
- android:visibility="gone"
- android:layout_weight="1"
- />
- <TextView android:id="@+id/inbox_text3"
- android:textAppearance="@style/TextAppearance.StatusBar.EventContent"
- android:layout_width="match_parent"
- android:layout_height="0dp"
- android:layout_marginStart="8dp"
- android:layout_marginEnd="8dp"
- android:singleLine="true"
- android:ellipsize="end"
- android:visibility="gone"
- android:layout_weight="1"
- />
- <TextView android:id="@+id/inbox_text4"
- android:textAppearance="@style/TextAppearance.StatusBar.EventContent"
- android:layout_width="match_parent"
- android:layout_height="0dp"
- android:layout_marginStart="8dp"
- android:singleLine="true"
- android:ellipsize="end"
- android:visibility="gone"
- android:layout_weight="1"
- />
- <TextView android:id="@+id/inbox_text5"
- android:textAppearance="@style/TextAppearance.StatusBar.EventContent"
- android:layout_width="match_parent"
- android:layout_height="0dp"
- android:layout_marginStart="8dp"
- android:layout_marginEnd="8dp"
- android:singleLine="true"
- android:ellipsize="end"
- android:visibility="gone"
- android:layout_weight="1"
- />
- <TextView android:id="@+id/inbox_text6"
- android:textAppearance="@style/TextAppearance.StatusBar.EventContent"
- android:layout_width="match_parent"
- android:layout_height="0dp"
- android:layout_marginStart="8dp"
- android:layout_marginEnd="8dp"
- android:singleLine="true"
- android:ellipsize="end"
- android:visibility="gone"
- android:layout_weight="1"
- />
- <TextView android:id="@+id/inbox_more"
- android:textAppearance="@style/TextAppearance.StatusBar.EventContent"
- android:layout_width="match_parent"
- android:layout_height="0dp"
- android:layout_marginStart="8dp"
- android:layout_marginEnd="8dp"
- android:singleLine="true"
- android:ellipsize="end"
- android:visibility="gone"
- android:layout_weight="1"
- android:text="@android:string/ellipsis"
- />
<ImageView
android:layout_width="match_parent"
- android:layout_height="1px"
+ android:layout_height="1dip"
+ android:layout_marginTop="-1px"
android:id="@+id/action_divider"
- android:visibility="gone"
android:background="?android:attr/dividerHorizontal" />
<include
layout="@layout/notification_action_list"
@@ -202,9 +217,9 @@
/>
<ImageView
android:layout_width="match_parent"
- android:layout_height="1px"
+ android:layout_height="1dip"
+ android:layout_marginTop="-1px"
android:id="@+id/overflow_divider"
- android:layout_marginTop="8dp"
android:visibility="visible"
android:background="?android:attr/dividerHorizontal" />
<LinearLayout
diff --git a/core/res/res/values-fa/donottranslate-cldr.xml b/core/res/res/values-fa/donottranslate-cldr.xml
index b05268e..402311a 100644
--- a/core/res/res/values-fa/donottranslate-cldr.xml
+++ b/core/res/res/values-fa/donottranslate-cldr.xml
@@ -37,22 +37,22 @@
<string name="time_wday_date">%1$s، %2$s %3$s</string>
<string name="wday_date">%2$s %3$s</string>
<string name="time_wday">%1$s، %2$s</string>
- <string name="same_year_md1_md2">%3$s LLLL تا %8$s LLLL</string>
- <string name="same_year_wday1_md1_wday2_md2">%1$s %3$s LLLL تا %6$s %8$s LLLL</string>
- <string name="same_year_md1_time1_md2_time2">%5$s، %3$s LLLL تا %10$s، %8$s LLLL</string>
- <string name="same_month_md1_time1_md2_time2">%5$s، %3$s LLLL تا %10$s، %8$s LLLL</string>
- <string name="same_year_wday1_md1_time1_wday2_md2_time2">%5$s، %1$s %3$s LLLL تا %10$s، %6$s %8$s LLLL</string>
- <string name="same_month_wday1_md1_time1_wday2_md2_time2">%5$s، %1$s %3$s LLLL تا %10$s، %6$s %8$s LLLL</string>
+ <string name="same_year_md1_md2">%3$s %11$s تا %8$s %12$s</string>
+ <string name="same_year_wday1_md1_wday2_md2">%1$s %3$s %11$s تا %6$s %8$s %12$s</string>
+ <string name="same_year_md1_time1_md2_time2">%5$s، %3$s %11$s تا %10$s، %8$s %12$s</string>
+ <string name="same_month_md1_time1_md2_time2">%5$s، %3$s %11$s تا %10$s، %8$s %12$s</string>
+ <string name="same_year_wday1_md1_time1_wday2_md2_time2">%5$s، %1$s %3$s %11$s تا %10$s، %6$s %8$s %12$s</string>
+ <string name="same_month_wday1_md1_time1_wday2_md2_time2">%5$s، %1$s %3$s %11$s تا %10$s، %6$s %8$s %12$s</string>
<string name="same_year_mdy1_time1_mdy2_time2">%5$s، %3$s %2$s %4$s تا %10$s، %8$s %7$s %9$s</string>
<string name="same_month_mdy1_time1_mdy2_time2">%5$s، %3$s %2$s %4$s تا %10$s، %8$s %7$s %9$s</string>
<string name="same_year_wday1_mdy1_time1_wday2_mdy2_time2">%5$s، %1$s %3$s %2$s %4$s تا %10$s، %6$s %8$s %7$s %9$s</string>
<string name="same_month_wday1_mdy1_time1_wday2_mdy2_time2">%5$s، %1$s %3$s %2$s %4$s تا %10$s، %6$s %8$s %7$s %9$s</string>
<string name="same_month_wday1_mdy1_wday2_mdy2">%1$s %3$s %2$s %4$s تا %6$s %8$s %7$s %9$s</string>
- <string name="same_month_md1_md2">%3$s تا %8$s LLL</string>
- <string name="same_month_wday1_md1_wday2_md2">%1$s %3$s LLLL تا %6$s %8$s LLLL</string>
- <string name="same_year_mdy1_mdy2">%3$s LLL تا %8$s %2$s %9$s</string>
+ <string name="same_month_md1_md2">%3$s تا %8$s %11$s</string>
+ <string name="same_month_wday1_md1_wday2_md2">%1$s %3$s %11$s تا %6$s %8$s %12$s</string>
+ <string name="same_year_mdy1_mdy2">%3$s %11$s تا %8$s %7$s %9$s</string>
<string name="same_month_mdy1_mdy2">%3$s تا %8$s %2$s %9$s</string>
- <string name="same_year_wday1_mdy1_wday2_mdy2">%1$s %3$s LLL تا %6$s %8$s %2$s %9$s</string>
+ <string name="same_year_wday1_mdy1_wday2_mdy2">%1$s %3$s %11$s تا %6$s %8$s %7$s %9$s</string>
<string name="short_format_month">%b</string>
<string name="full_wday_month_day_no_year">E d LLLL</string>
<string name="abbrev_wday_month_day_no_year">E d LLLL</string>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index ffc1a04..a424135 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -208,6 +208,7 @@
<java-symbol type="id" name="inbox_text5" />
<java-symbol type="id" name="inbox_text6" />
<java-symbol type="id" name="inbox_more" />
+ <java-symbol type="id" name="inbox_end_pad" />
<java-symbol type="id" name="status_bar_latest_event_content" />
<java-symbol type="id" name="action_divider" />
<java-symbol type="id" name="overflow_divider" />
diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java
index 3a398a1..5b3350a 100644
--- a/media/java/android/media/AudioService.java
+++ b/media/java/android/media/AudioService.java
@@ -480,6 +480,7 @@
intentFilter.addAction(Intent.ACTION_BOOT_COMPLETED);
intentFilter.addAction(Intent.ACTION_SCREEN_ON);
intentFilter.addAction(Intent.ACTION_SCREEN_OFF);
+ intentFilter.addAction(Intent.ACTION_USER_SWITCHED);
// Register a configuration change listener only if requested by system properties
// to monitor orientation changes (off by default)
@@ -608,7 +609,7 @@
final ContentResolver cr = mContentResolver;
int ringerModeFromSettings =
- System.getInt(cr, System.MODE_RINGER, AudioManager.RINGER_MODE_NORMAL);
+ Settings.Global.getInt(cr, System.MODE_RINGER, AudioManager.RINGER_MODE_NORMAL);
int ringerMode = ringerModeFromSettings;
// sanity check in case the settings are restored from a device with incompatible
// ringer modes
@@ -619,7 +620,7 @@
ringerMode = AudioManager.RINGER_MODE_SILENT;
}
if (ringerMode != ringerModeFromSettings) {
- System.putInt(cr, System.MODE_RINGER, ringerMode);
+ Settings.Global.putInt(cr, System.MODE_RINGER, ringerMode);
}
synchronized(mSettingsLock) {
mRingerMode = ringerMode;
@@ -638,23 +639,30 @@
// make sure settings for ringer mode are consistent with device type: non voice capable
// devices (tablets) include media stream in silent mode whereas phones don't.
- mRingerModeAffectedStreams = Settings.System.getInt(cr,
+ mRingerModeAffectedStreams = Settings.System.getIntForUser(cr,
Settings.System.MODE_RINGER_STREAMS_AFFECTED,
((1 << AudioSystem.STREAM_RING)|(1 << AudioSystem.STREAM_NOTIFICATION)|
- (1 << AudioSystem.STREAM_SYSTEM)|(1 << AudioSystem.STREAM_SYSTEM_ENFORCED)));
+ (1 << AudioSystem.STREAM_SYSTEM)|(1 << AudioSystem.STREAM_SYSTEM_ENFORCED)),
+ UserHandle.USER_CURRENT);
if (mVoiceCapable) {
mRingerModeAffectedStreams &= ~(1 << AudioSystem.STREAM_MUSIC);
} else {
mRingerModeAffectedStreams |= (1 << AudioSystem.STREAM_MUSIC);
}
- Settings.System.putInt(cr,
- Settings.System.MODE_RINGER_STREAMS_AFFECTED, mRingerModeAffectedStreams);
+ Settings.System.putIntForUser(cr,
+ Settings.System.MODE_RINGER_STREAMS_AFFECTED,
+ mRingerModeAffectedStreams,
+ UserHandle.USER_CURRENT);
- mMuteAffectedStreams = System.getInt(cr,
+ mMuteAffectedStreams = System.getIntForUser(cr,
System.MUTE_STREAMS_AFFECTED,
- ((1 << AudioSystem.STREAM_MUSIC)|(1 << AudioSystem.STREAM_RING)|(1 << AudioSystem.STREAM_SYSTEM)));
+ ((1 << AudioSystem.STREAM_MUSIC)|
+ (1 << AudioSystem.STREAM_RING)|
+ (1 << AudioSystem.STREAM_SYSTEM)),
+ UserHandle.USER_CURRENT);
- boolean masterMute = System.getInt(cr, System.VOLUME_MASTER_MUTE, 0) == 1;
+ boolean masterMute = System.getIntForUser(cr, System.VOLUME_MASTER_MUTE,
+ 0, UserHandle.USER_CURRENT) == 1;
AudioSystem.setMasterMute(masterMute);
broadcastMasterMuteStatus(masterMute);
@@ -1237,8 +1245,8 @@
private void restoreMasterVolume() {
if (mUseMasterVolume) {
- float volume = Settings.System.getFloat(mContentResolver,
- Settings.System.VOLUME_MASTER, -1.0f);
+ float volume = Settings.System.getFloatForUser(mContentResolver,
+ Settings.System.VOLUME_MASTER, -1.0f, UserHandle.USER_CURRENT);
if (volume >= 0.0f) {
AudioSystem.setMasterVolume(volume);
}
@@ -1674,6 +1682,10 @@
/** @see AudioManager#reloadAudioSettings() */
public void reloadAudioSettings() {
+ readAudioSettings(false /*userSwitch*/);
+ }
+
+ private void readAudioSettings(boolean userSwitch) {
// restore ringer mode, ringer mode affected streams, mute affected streams and vibrate settings
readPersistedSettings();
@@ -1682,6 +1694,10 @@
for (int streamType = 0; streamType < numStreamTypes; streamType++) {
VolumeStreamState streamState = mStreamStates[streamType];
+ if (userSwitch && mStreamVolumeAlias[streamType] == AudioSystem.STREAM_MUSIC) {
+ continue;
+ }
+
synchronized (streamState) {
streamState.readSettings();
@@ -2536,7 +2552,8 @@
// device, continue otherwise
int defaultIndex = (device == AudioSystem.DEVICE_OUT_DEFAULT) ?
AudioManager.DEFAULT_STREAM_VOLUME[mStreamType] : -1;
- int index = Settings.System.getInt(mContentResolver, name, defaultIndex);
+ int index = Settings.System.getIntForUser(
+ mContentResolver, name, defaultIndex, UserHandle.USER_CURRENT);
if (index == -1) {
continue;
}
@@ -2547,7 +2564,8 @@
// or default index
defaultIndex = (index > 0) ?
index : AudioManager.DEFAULT_STREAM_VOLUME[mStreamType];
- int lastAudibleIndex = Settings.System.getInt(mContentResolver, name, defaultIndex);
+ int lastAudibleIndex = Settings.System.getIntForUser(
+ mContentResolver, name, defaultIndex, UserHandle.USER_CURRENT);
// a last audible index of 0 should never be stored for ring and notification
// streams on phones (voice capable devices).
@@ -2959,19 +2977,21 @@
int persistType,
int device) {
if ((persistType & PERSIST_CURRENT) != 0) {
- System.putInt(mContentResolver,
+ System.putIntForUser(mContentResolver,
streamState.getSettingNameForDevice(false /* lastAudible */, device),
- (streamState.getIndex(device, false /* lastAudible */) + 5)/ 10);
+ (streamState.getIndex(device, false /* lastAudible */) + 5)/ 10,
+ UserHandle.USER_CURRENT);
}
if ((persistType & PERSIST_LAST_AUDIBLE) != 0) {
- System.putInt(mContentResolver,
+ System.putIntForUser(mContentResolver,
streamState.getSettingNameForDevice(true /* lastAudible */, device),
- (streamState.getIndex(device, true /* lastAudible */) + 5) / 10);
+ (streamState.getIndex(device, true /* lastAudible */) + 5) / 10,
+ UserHandle.USER_CURRENT);
}
}
private void persistRingerMode(int ringerMode) {
- System.putInt(mContentResolver, System.MODE_RINGER, ringerMode);
+ Settings.Global.putInt(mContentResolver, System.MODE_RINGER, ringerMode);
}
private void playSoundEffect(int effectType, int volume) {
@@ -3021,8 +3041,10 @@
}
private void onHandlePersistMediaButtonReceiver(ComponentName receiver) {
- Settings.System.putString(mContentResolver, Settings.System.MEDIA_BUTTON_RECEIVER,
- receiver == null ? "" : receiver.flattenToString());
+ Settings.System.putStringForUser(mContentResolver,
+ Settings.System.MEDIA_BUTTON_RECEIVER,
+ receiver == null ? "" : receiver.flattenToString(),
+ UserHandle.USER_CURRENT);
}
private void cleanupPlayer(MediaPlayer mp) {
@@ -3058,13 +3080,17 @@
break;
case MSG_PERSIST_MASTER_VOLUME:
- Settings.System.putFloat(mContentResolver, Settings.System.VOLUME_MASTER,
- (float)msg.arg1 / (float)1000.0);
+ Settings.System.putFloatForUser(mContentResolver,
+ Settings.System.VOLUME_MASTER,
+ (float)msg.arg1 / (float)1000.0,
+ UserHandle.USER_CURRENT);
break;
case MSG_PERSIST_MASTER_VOLUME_MUTE:
- Settings.System.putInt(mContentResolver, Settings.System.VOLUME_MASTER_MUTE,
- msg.arg1);
+ Settings.System.putIntForUser(mContentResolver,
+ Settings.System.VOLUME_MASTER_MUTE,
+ msg.arg1,
+ UserHandle.USER_CURRENT);
break;
case MSG_PERSIST_RINGER_MODE:
@@ -3248,10 +3274,11 @@
// and mRingerModeAffectedStreams, so will leave this synchronized for now.
// mRingerModeMutedStreams and mMuteAffectedStreams are safe (only accessed once).
synchronized (mSettingsLock) {
- int ringerModeAffectedStreams = Settings.System.getInt(mContentResolver,
+ int ringerModeAffectedStreams = Settings.System.getIntForUser(mContentResolver,
Settings.System.MODE_RINGER_STREAMS_AFFECTED,
((1 << AudioSystem.STREAM_RING)|(1 << AudioSystem.STREAM_NOTIFICATION)|
- (1 << AudioSystem.STREAM_SYSTEM)|(1 << AudioSystem.STREAM_SYSTEM_ENFORCED)));
+ (1 << AudioSystem.STREAM_SYSTEM)|(1 << AudioSystem.STREAM_SYSTEM_ENFORCED)),
+ UserHandle.USER_CURRENT);
if (mVoiceCapable) {
ringerModeAffectedStreams &= ~(1 << AudioSystem.STREAM_MUSIC);
} else {
@@ -3673,6 +3700,15 @@
AudioSystem.setParameters("screen_state=off");
} else if (action.equalsIgnoreCase(Intent.ACTION_CONFIGURATION_CHANGED)) {
handleConfigurationChanged(context);
+ } else if (action.equals(Intent.ACTION_USER_SWITCHED)) {
+ readAudioSettings(true /*userSwitch*/);
+ // preserve STREAM_MUSIC volume from one user to the next.
+ sendMsg(mAudioHandler,
+ MSG_SET_ALL_VOLUMES,
+ SENDMSG_QUEUE,
+ 0,
+ 0,
+ mStreamStates[AudioSystem.STREAM_MUSIC], 0);
}
}
}
@@ -4547,8 +4583,8 @@
* Restore remote control receiver from the system settings.
*/
private void restoreMediaButtonReceiver() {
- String receiverName = Settings.System.getString(mContentResolver,
- Settings.System.MEDIA_BUTTON_RECEIVER);
+ String receiverName = Settings.System.getStringForUser(mContentResolver,
+ Settings.System.MEDIA_BUTTON_RECEIVER, UserHandle.USER_CURRENT);
if ((null != receiverName) && !receiverName.isEmpty()) {
ComponentName eventReceiver = ComponentName.unflattenFromString(receiverName);
// construct a PendingIntent targeted to the restored component name
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 2792704..6c5a4e2 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -148,6 +148,7 @@
NetworkTimeUpdateService networkTimeUpdater = null;
CommonTimeManagementService commonTimeMgmtService = null;
InputManagerService inputManager = null;
+ TelephonyRegistry telephonyRegistry = null;
// Create a shared handler thread for UI within the system server.
// This thread is used by at least the following components:
@@ -218,7 +219,8 @@
ServiceManager.addService(Context.DISPLAY_SERVICE, display, true);
Slog.i(TAG, "Telephony Registry");
- ServiceManager.addService("telephony.registry", new TelephonyRegistry(context));
+ telephonyRegistry = new TelephonyRegistry(context);
+ ServiceManager.addService("telephony.registry", telephonyRegistry);
Slog.i(TAG, "Scheduling Policy");
ServiceManager.addService(Context.SCHEDULING_POLICY_SERVICE,
@@ -844,6 +846,7 @@
final StatusBarManagerService statusBarF = statusBar;
final DreamManagerService dreamyF = dreamy;
final InputManagerService inputManagerF = inputManager;
+ final TelephonyRegistry telephonyRegistryF = telephonyRegistry;
// We now tell the activity manager it is okay to run third party
// code. It will call back into us once it has gotten to the state
@@ -971,6 +974,11 @@
} catch (Throwable e) {
reportWtf("making InputManagerService ready", e);
}
+ try {
+ if (telephonyRegistryF != null) telephonyRegistryF.systemReady();
+ } catch (Throwable e) {
+ reportWtf("making TelephonyRegistry ready", e);
+ }
}
});
diff --git a/services/java/com/android/server/TelephonyRegistry.java b/services/java/com/android/server/TelephonyRegistry.java
index 8361477..26684de 100644
--- a/services/java/com/android/server/TelephonyRegistry.java
+++ b/services/java/com/android/server/TelephonyRegistry.java
@@ -16,14 +16,19 @@
package com.android.server;
+import android.app.ActivityManager;
+import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
+import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.net.LinkCapabilities;
import android.net.LinkProperties;
import android.os.Binder;
import android.os.Bundle;
+import android.os.Handler;
import android.os.IBinder;
+import android.os.Message;
import android.os.RemoteException;
import android.os.UserHandle;
import android.telephony.CellLocation;
@@ -39,13 +44,11 @@
import java.util.List;
import java.io.FileDescriptor;
import java.io.PrintWriter;
-import java.net.NetworkInterface;
import com.android.internal.app.IBatteryStats;
import com.android.internal.telephony.ITelephonyRegistry;
import com.android.internal.telephony.IPhoneStateListener;
import com.android.internal.telephony.DefaultPhoneNotifier;
-import com.android.internal.telephony.Phone;
import com.android.internal.telephony.PhoneConstants;
import com.android.internal.telephony.ServiceStateTracker;
import com.android.internal.telephony.TelephonyIntents;
@@ -58,6 +61,7 @@
class TelephonyRegistry extends ITelephonyRegistry.Stub {
private static final String TAG = "TelephonyRegistry";
private static final boolean DBG = false;
+ private static final boolean DBG_LOC = false;
private static class Record {
String pkgForDebug;
@@ -66,7 +70,15 @@
IPhoneStateListener callback;
+ int callerUid;
+
int events;
+
+ @Override
+ public String toString() {
+ return "{pkgForDebug=" + pkgForDebug + " callerUid=" + callerUid +
+ " events=" + Integer.toHexString(events) + "}";
+ }
}
private final Context mContext;
@@ -120,6 +132,32 @@
PhoneStateListener.LISTEN_DATA_CONNECTION_STATE |
PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR;
+ private static final int MSG_USER_SWITCHED = 1;
+
+ private final Handler mHandler = new Handler() {
+ @Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case MSG_USER_SWITCHED: {
+ Slog.d(TAG, "MSG_USER_SWITCHED userId=" + msg.arg1);
+ TelephonyRegistry.this.notifyCellLocation(mCellLocation);
+ break;
+ }
+ }
+ }
+ };
+
+ private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ String action = intent.getAction();
+ if (Intent.ACTION_USER_SWITCHED.equals(action)) {
+ mHandler.sendMessage(mHandler.obtainMessage(MSG_USER_SWITCHED,
+ intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0), 0));
+ }
+ }
+ };
+
// we keep a copy of all of the state so we can send it out when folks
// register for it
//
@@ -140,10 +178,24 @@
mConnectedApns = new ArrayList<String>();
}
+ public void systemReady() {
+ // Watch for interesting updates
+ final IntentFilter filter = new IntentFilter();
+ filter.addAction(Intent.ACTION_USER_SWITCHED);
+ filter.addAction(Intent.ACTION_USER_REMOVED);
+ mContext.registerReceiver(mBroadcastReceiver, filter);
+ }
+
+ @Override
public void listen(String pkgForDebug, IPhoneStateListener callback, int events,
boolean notifyNow) {
- // Slog.d(TAG, "listen pkg=" + pkgForDebug + " events=0x" +
- // Integer.toHexString(events));
+ int callerUid = UserHandle.getCallingUserId();
+ int myUid = UserHandle.myUserId();
+ if (DBG) {
+ Slog.d(TAG, "listen: E pkg=" + pkgForDebug + " events=0x" + Integer.toHexString(events)
+ + " myUid=" + myUid
+ + " callerUid=" + callerUid);
+ }
if (events != 0) {
/* Checks permission and throws Security exception */
checkListenerPermission(events);
@@ -164,7 +216,9 @@
r.binder = b;
r.callback = callback;
r.pkgForDebug = pkgForDebug;
+ r.callerUid = callerUid;
mRecords.add(r);
+ if (DBG) Slog.i(TAG, "listen: add new record=" + r);
}
int send = events & (events ^ r.events);
r.events = events;
@@ -199,8 +253,9 @@
remove(r.binder);
}
}
- if ((events & PhoneStateListener.LISTEN_CELL_LOCATION) != 0) {
+ if (validateEventsAndUserLocked(r, PhoneStateListener.LISTEN_CELL_LOCATION)) {
try {
+ if (DBG_LOC) Slog.d(TAG, "listen: mCellLocation=" + mCellLocation);
r.callback.onCellLocationChanged(new Bundle(mCellLocation));
} catch (RemoteException ex) {
remove(r.binder);
@@ -242,8 +297,9 @@
remove(r.binder);
}
}
- if ((events & PhoneStateListener.LISTEN_CELL_INFO) != 0) {
+ if (validateEventsAndUserLocked(r, PhoneStateListener.LISTEN_CELL_INFO)) {
try {
+ if (DBG_LOC) Slog.d(TAG, "listen: mCellInfo=" + mCellInfo);
r.callback.onCellInfoChanged(mCellInfo);
} catch (RemoteException ex) {
remove(r.binder);
@@ -346,8 +402,11 @@
synchronized (mRecords) {
mCellInfo = cellInfo;
for (Record r : mRecords) {
- if ((r.events & PhoneStateListener.LISTEN_CELL_INFO) != 0) {
+ if (validateEventsAndUserLocked(r, PhoneStateListener.LISTEN_CELL_INFO)) {
try {
+ if (DBG_LOC) {
+ Slog.d(TAG, "notifyCellInfo: mCellInfo=" + mCellInfo + " r=" + r);
+ }
r.callback.onCellInfoChanged(cellInfo);
} catch (RemoteException ex) {
mRemoveList.add(r.binder);
@@ -424,7 +483,8 @@
if (DBG) {
Slog.i(TAG, "notifyDataConnection: state=" + state + " isDataConnectivityPossible="
+ isDataConnectivityPossible + " reason='" + reason
- + "' apn='" + apn + "' apnType=" + apnType + " networkType=" + networkType);
+ + "' apn='" + apn + "' apnType=" + apnType + " networkType=" + networkType
+ + " mRecords.size()=" + mRecords.size() + " mRecords=" + mRecords);
}
synchronized (mRecords) {
boolean modified = false;
@@ -506,8 +566,12 @@
synchronized (mRecords) {
mCellLocation = cellLocation;
for (Record r : mRecords) {
- if ((r.events & PhoneStateListener.LISTEN_CELL_LOCATION) != 0) {
+ if (validateEventsAndUserLocked(r, PhoneStateListener.LISTEN_CELL_LOCATION)) {
try {
+ if (DBG_LOC) {
+ Slog.d(TAG, "notifyCellLocation: mCellLocation=" + mCellLocation
+ + " r=" + r);
+ }
r.callback.onCellLocationChanged(new Bundle(cellLocation));
} catch (RemoteException ex) {
mRemoveList.add(r.binder);
@@ -712,4 +776,22 @@
mRemoveList.clear();
}
}
+
+ private boolean validateEventsAndUserLocked(Record r, int events) {
+ int foregroundUser;
+ long callingIdentity = Binder.clearCallingIdentity();
+ boolean valid = false;
+ try {
+ foregroundUser = ActivityManager.getCurrentUser();
+ valid = r.callerUid == foregroundUser && (r.events & events) != 0;
+ if (DBG | DBG_LOC) {
+ Slog.d(TAG, "validateEventsAndUserLocked: valid=" + valid
+ + " r.callerUid=" + r.callerUid + " foregroundUser=" + foregroundUser
+ + " r.events=" + r.events + " events=" + events);
+ }
+ } finally {
+ Binder.restoreCallingIdentity(callingIdentity);
+ }
+ return valid;
+ }
}
diff --git a/services/java/com/android/server/updates/ConfigUpdateInstallReceiver.java b/services/java/com/android/server/updates/ConfigUpdateInstallReceiver.java
index a74a648..e07230d 100644
--- a/services/java/com/android/server/updates/ConfigUpdateInstallReceiver.java
+++ b/services/java/com/android/server/updates/ConfigUpdateInstallReceiver.java
@@ -89,8 +89,7 @@
// get the hash of the currently used value
String currentHash = getCurrentHash(getCurrentContent());
if (!verifyVersion(currentVersion, altVersion)) {
- EventLog.writeEvent(EventLogTags.CONFIG_INSTALL_FAILED,
- "New version is not greater than current version");
+ Slog.i(TAG, "Not installing, new version is <= current version");
} else if (!verifyPreviousHash(currentHash, altRequiredHash)) {
EventLog.writeEvent(EventLogTags.CONFIG_INSTALL_FAILED,
"Current hash did not match required value");
@@ -224,7 +223,7 @@
return signer.verify(Base64.decode(signature.getBytes(), Base64.DEFAULT));
}
- private void writeUpdate(File dir, File file, String content) {
+ private void writeUpdate(File dir, File file, String content) throws IOException {
FileOutputStream out = null;
File tmp = null;
try {
@@ -248,8 +247,6 @@
if (!tmp.renameTo(file)) {
throw new IOException("Failed to atomically rename " + file.getCanonicalPath());
}
- } catch (IOException e) {
- Slog.e(TAG, "Failed to write update", e);
} finally {
if (tmp != null) {
tmp.delete();
@@ -258,7 +255,7 @@
}
}
- private void install(String content, int version) {
+ private void install(String content, int version) throws IOException {
writeUpdate(updateDir, updateContent, content);
writeUpdate(updateDir, updateVersion, Long.toString(version));
}
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 15ffd63..2fa41e7 100755
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -220,6 +220,7 @@
public CellLocation getCellLocation() {
try {
Bundle bundle = getITelephony().getCellLocation();
+ if (bundle.isEmpty()) return null;
CellLocation cl = CellLocation.newFromBundle(bundle);
if (cl.isEmpty())
return null;
diff --git a/tests/RenderScriptTests/tests/src/com/android/rs/test/RSTestCore.java b/tests/RenderScriptTests/tests/src/com/android/rs/test/RSTestCore.java
index 4d6fd10..c585065 100644
--- a/tests/RenderScriptTests/tests/src/com/android/rs/test/RSTestCore.java
+++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/RSTestCore.java
@@ -70,6 +70,7 @@
unitTests.add(new UT_unsigned(this, mRes, mCtx));
unitTests.add(new UT_array_init(this, mRes, mCtx));
unitTests.add(new UT_array_alloc(this, mRes, mCtx));
+ unitTests.add(new UT_kernel(this, mRes, mCtx));
unitTests.add(new UT_clamp(this, mRes, mCtx));
unitTests.add(new UT_clamp_relaxed(this, mRes, mCtx));
unitTests.add(new UT_convert(this, mRes, mCtx));
diff --git a/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_kernel.java b/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_kernel.java
new file mode 100644
index 0000000..e0bd33e
--- /dev/null
+++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_kernel.java
@@ -0,0 +1,60 @@
+/*
+ * 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.rs.test;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.renderscript.*;
+import android.util.Log;
+
+public class UT_kernel extends UnitTest {
+ private Resources mRes;
+ private Allocation A;
+ private Allocation B;
+
+ protected UT_kernel(RSTestCore rstc, Resources res, Context ctx) {
+ super(rstc, "Kernels (pass-by-value)", ctx);
+ mRes = res;
+ }
+
+ private void initializeGlobals(RenderScript RS, ScriptC_kernel s) {
+ Type.Builder typeBuilder = new Type.Builder(RS, Element.I32(RS));
+ int X = 5;
+ s.set_dimX(X);
+ typeBuilder.setX(X);
+ A = Allocation.createTyped(RS, typeBuilder.create());
+ s.bind_ain(A);
+ B = Allocation.createTyped(RS, typeBuilder.create());
+ s.bind_aout(B);
+
+ return;
+ }
+
+ public void run() {
+ RenderScript pRS = RenderScript.create(mCtx);
+ ScriptC_kernel s = new ScriptC_kernel(pRS);
+ pRS.setMessageHandler(mRsMessage);
+ initializeGlobals(pRS, s);
+ s.forEach_init_vars(A);
+ s.forEach_root(A, B);
+ s.invoke_verify_root();
+ s.invoke_kernel_test();
+ pRS.finish();
+ waitForMessage();
+ pRS.destroy();
+ }
+}
diff --git a/tests/RenderScriptTests/tests/src/com/android/rs/test/kernel.rs b/tests/RenderScriptTests/tests/src/com/android/rs/test/kernel.rs
new file mode 100644
index 0000000..d6c9df3
--- /dev/null
+++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/kernel.rs
@@ -0,0 +1,47 @@
+#include "shared.rsh"
+
+int *ain;
+int *aout;
+int dimX;
+static bool failed = false;
+
+void init_vars(int *out) {
+ *out = 7;
+}
+
+
+int __attribute__((kernel)) root(int ain, uint32_t x) {
+ _RS_ASSERT(ain == 7);
+ return ain + x;
+}
+
+static bool test_root_output() {
+ bool failed = false;
+ int i;
+
+ for (i = 0; i < dimX; i++) {
+ _RS_ASSERT(aout[i] == (i + ain[i]));
+ }
+
+ if (failed) {
+ rsDebug("test_root_output FAILED", 0);
+ }
+ else {
+ rsDebug("test_root_output PASSED", 0);
+ }
+
+ return failed;
+}
+
+void verify_root() {
+ failed |= test_root_output();
+}
+
+void kernel_test() {
+ if (failed) {
+ rsSendToClientBlocking(RS_MSG_TEST_FAILED);
+ }
+ else {
+ rsSendToClientBlocking(RS_MSG_TEST_PASSED);
+ }
+}