Merge "Update MediaRouteChooserDialog grouping UI" into jb-dev
diff --git a/core/java/android/view/Choreographer.java b/core/java/android/view/Choreographer.java
index 78dc86f..4d1b836 100644
--- a/core/java/android/view/Choreographer.java
+++ b/core/java/android/view/Choreographer.java
@@ -79,6 +79,16 @@
// be dequeued.
private static final long DEFAULT_FRAME_DELAY = 10;
+ // The fake vsync delay in milliseconds.
+ // When the screen is off, we might not receive real vsync pulses from the hardware
+ // which would cause posted Choreographer callbacks to not run. This is bad because
+ // messages in the Looper might be blocked behind a barrier that is scheduled to be
+ // removed by one of those Choreographer callback (see ViewRootImpl.doTraversals).
+ // Until the barrier is removed, those messages will not run. To prevent starvation
+ // of the Looper, we synthesize fake vsync pulses at a reduced rate whenever the
+ // display hardware stops generating them.
+ private static final long FAKE_VSYNC_DELAY = 100;
+
// The number of milliseconds between animation frames.
private static volatile long sFrameDelay = DEFAULT_FRAME_DELAY;
@@ -113,6 +123,7 @@
private static final int MSG_DO_FRAME = 0;
private static final int MSG_DO_SCHEDULE_VSYNC = 1;
private static final int MSG_DO_SCHEDULE_CALLBACK = 2;
+ private static final int MSG_FAKE_VSYNC = 3;
// All frame callbacks posted by applications have this token.
private static final Object FRAME_CALLBACK_TOKEN = new Object() {
@@ -587,6 +598,13 @@
private void scheduleVsyncLocked() {
mDisplayEventReceiver.scheduleVsync();
+
+ // Post a message to simulate a fake vsync pulse at a reduced rate in case the
+ // display hardware stops generating them. This ensures that Choreographer
+ // callbacks can continue to run even if the screen is off.
+ Message msg = mHandler.obtainMessage(MSG_FAKE_VSYNC);
+ msg.setAsynchronous(true);
+ mHandler.sendMessageDelayed(msg, FAKE_VSYNC_DELAY);
}
private boolean isRunningOnLooperThreadLocked() {
@@ -662,6 +680,12 @@
case MSG_DO_SCHEDULE_CALLBACK:
doScheduleCallback(msg.arg1);
break;
+ case MSG_FAKE_VSYNC:
+ if (DEBUG) {
+ Log.d(TAG, "Handling fake vsync while screen is off.");
+ }
+ doFrame(System.nanoTime(), 0);
+ break;
}
}
}
@@ -683,6 +707,17 @@
// the message queue. If there are no messages in the queue with timestamps
// earlier than the frame time, then the vsync event will be processed immediately.
// Otherwise, messages that predate the vsync event will be handled first.
+ if (mHavePendingVsync) {
+ if (DEBUG) {
+ Log.d(TAG, "Already have a pending vsync event. There should only be "
+ + "one at a time but they can double up when a fake vsync "
+ + "is handled in place of a real one.");
+ }
+ mHandler.removeCallbacks(this);
+ } else {
+ mHavePendingVsync = true;
+ }
+
long now = System.nanoTime();
if (timestampNanos > now) {
Log.w(TAG, "Frame time is " + ((timestampNanos - now) * 0.000001f)
@@ -691,12 +726,7 @@
timestampNanos = now;
}
- if (mHavePendingVsync) {
- Log.w(TAG, "Already have a pending vsync event. There should only be "
- + "one at a time.");
- } else {
- mHavePendingVsync = true;
- }
+ mHandler.removeMessages(MSG_FAKE_VSYNC);
mTimestampNanos = timestampNanos;
mFrame = frame;
diff --git a/core/jni/android_bluetooth_HeadsetBase.cpp b/core/jni/android_bluetooth_HeadsetBase.cpp
index 0df211a..34447ef 100644
--- a/core/jni/android_bluetooth_HeadsetBase.cpp
+++ b/core/jni/android_bluetooth_HeadsetBase.cpp
@@ -115,7 +115,7 @@
pfd.fd = fd;
pfd.events = POLLIN;
*err = errno = 0;
- int ret = poll(&pfd, 1, timeout_ms);
+ int ret = TEMP_FAILURE_RETRY(poll(&pfd, 1, timeout_ms));
if (ret < 0) {
ALOGE("poll() error\n");
*err = errno;
@@ -136,7 +136,7 @@
while ((int)(bufit - buf) < (len - 1))
{
errno = 0;
- int rc = read(fd, bufit, 1);
+ int rc = TEMP_FAILURE_RETRY(read(fd, bufit, 1));
if (!rc)
break;
@@ -427,7 +427,7 @@
{
char ch;
errno = 0;
- int nr = read(nat->rfcomm_sock, &ch, 1);
+ int nr = TEMP_FAILURE_RETRY(read(nat->rfcomm_sock, &ch, 1));
/* It should be that nr != 1 because we just opened a socket
and we haven't sent anything over it for the other side to
respond... but one can't be paranoid enough.
diff --git a/data/sounds/ringtones/ogg/Themos.ogg b/data/sounds/ringtones/ogg/Themos.ogg
index bc850b8..4ddc71c 100644
--- a/data/sounds/ringtones/ogg/Themos.ogg
+++ b/data/sounds/ringtones/ogg/Themos.ogg
Binary files differ
diff --git a/data/sounds/ringtones/wav/Themos.wav b/data/sounds/ringtones/wav/Themos.wav
index d4d5c6e..fa3178f 100644
--- a/data/sounds/ringtones/wav/Themos.wav
+++ b/data/sounds/ringtones/wav/Themos.wav
Binary files differ
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 1eb353f..f18e33e 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -117,7 +117,7 @@
</string>
<!-- Separator for PLMN and SPN in network name. -->
- <string name="status_bar_network_name_separator" translatable="false">"\n"</string>
+ <string name="status_bar_network_name_separator" translatable="false">|</string>
<!-- Network connection string for Bluetooth Reverse Tethering -->
<string name="bluetooth_tethered">Bluetooth tethered</string>
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index 9c99653..3c19ad2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -462,11 +462,12 @@
signalCluster.setNetworkController(mNetworkController);
if (SHOW_CARRIER_LABEL) {
- // for wifi-only devices, we show SSID; otherwise, we show PLMN
+ // for mobile devices, we always show mobile connection info here (SPN/PLMN)
+ // for other devices, we show whatever network is connected
if (mNetworkController.hasMobileDataFeature()) {
mNetworkController.addMobileLabelView(mCarrierLabel);
} else {
- mNetworkController.addWifiLabelView(mCarrierLabel);
+ mNetworkController.addCombinedLabelView(mCarrierLabel);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
index b8f6054..1068267 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
@@ -121,8 +121,12 @@
private int mWimaxSignal = 0;
private int mWimaxState = 0;
private int mWimaxExtraState = 0;
+
// data connectivity (regardless of state, can we access the internet?)
// state of inet connection - 0 not connected, 100 connected
+ private boolean mConnected = false;
+ private int mConnectedNetworkType = ConnectivityManager.TYPE_NONE;
+ private String mConnectedNetworkTypeName;
private int mInetCondition = 0;
private static final int INET_CONDITION_THRESHOLD = 50;
@@ -868,6 +872,16 @@
.getSystemService(Context.CONNECTIVITY_SERVICE);
final NetworkInfo info = connManager.getActiveNetworkInfo();
+ // Are we connected at all, by any interface?
+ mConnected = info != null && info.isConnected();
+ if (mConnected) {
+ mConnectedNetworkType = info.getType();
+ mConnectedNetworkTypeName = info.getTypeName();
+ } else {
+ mConnectedNetworkType = ConnectivityManager.TYPE_NONE;
+ mConnectedNetworkTypeName = null;
+ }
+
int connectionStatus = intent.getIntExtra(ConnectivityManager.EXTRA_INET_CONDITION, 0);
if (CHATTY) {
@@ -912,12 +926,13 @@
// - We are connected to mobile data, or
// - We are not connected to mobile data, as long as the *reason* packets are not
// being routed over that link is that we have better connectivity via wifi.
- // If data is disconnected for some other reason but wifi is connected, we show nothing.
+ // If data is disconnected for some other reason but wifi (or ethernet/bluetooth)
+ // is connected, we show nothing.
// Otherwise (nothing connected) we show "No internet connection".
if (mDataConnected) {
mobileLabel = mNetworkName;
- } else if (mWifiConnected) {
+ } else if (mConnected) {
if (hasService()) {
mobileLabel = mNetworkName;
} else {
@@ -997,6 +1012,12 @@
R.string.accessibility_bluetooth_tether);
}
+ final boolean ethernetConnected = (mConnectedNetworkType == ConnectivityManager.TYPE_ETHERNET);
+ if (ethernetConnected) {
+ // TODO: icons and strings for Ethernet connectivity
+ combinedLabel = mConnectedNetworkTypeName;
+ }
+
if (mAirplaneMode &&
(mServiceState == null || (!hasService() && !mServiceState.isEmergencyOnly()))) {
// Only display the flight-mode icon if not in "emergency calls only" mode.
@@ -1023,7 +1044,7 @@
combinedSignalIconId = mDataSignalIconId;
}
}
- else if (!mDataConnected && !mWifiConnected && !mBluetoothTethered && !mWimaxConnected) {
+ else if (!mDataConnected && !mWifiConnected && !mBluetoothTethered && !mWimaxConnected && !ethernetConnected) {
// pretty much totally disconnected
combinedLabel = context.getString(R.string.status_bar_settings_signal_meter_disconnected);
@@ -1224,6 +1245,9 @@
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
pw.println("NetworkController state:");
+ pw.println(String.format(" %s network type %d (%s)",
+ mConnected?"CONNECTED":"DISCONNECTED",
+ mConnectedNetworkType, mConnectedNetworkTypeName));
pw.println(" - telephony ------");
pw.print(" hasService()=");
pw.println(hasService());
diff --git a/services/java/com/android/server/am/ActivityStack.java b/services/java/com/android/server/am/ActivityStack.java
index 8a86fe7..1eef2cf 100755
--- a/services/java/com/android/server/am/ActivityStack.java
+++ b/services/java/com/android/server/am/ActivityStack.java
@@ -1474,6 +1474,21 @@
return true;
}
+ // If the most recent activity was noHistory but was only stopped rather
+ // than stopped+finished because the device went to sleep, we need to make
+ // sure to finish it as we're making a new activity topmost.
+ final ActivityRecord last = mLastPausedActivity;
+ if (mService.mSleeping && last != null && !last.finishing) {
+ if ((last.intent.getFlags()&Intent.FLAG_ACTIVITY_NO_HISTORY) != 0
+ || (last.info.flags&ActivityInfo.FLAG_NO_HISTORY) != 0) {
+ if (DEBUG_STATES) {
+ Slog.d(TAG, "no-history finish of " + last + " on new resume");
+ }
+ requestFinishActivityLocked(last.appToken, Activity.RESULT_CANCELED, null,
+ "no-history");
+ }
+ }
+
if (prev != null && prev != next) {
if (!prev.waitingVisible && next != null && !next.nowVisible) {
prev.waitingVisible = true;
@@ -3279,8 +3294,16 @@
if ((r.intent.getFlags()&Intent.FLAG_ACTIVITY_NO_HISTORY) != 0
|| (r.info.flags&ActivityInfo.FLAG_NO_HISTORY) != 0) {
if (!r.finishing) {
- requestFinishActivityLocked(r.appToken, Activity.RESULT_CANCELED, null,
- "no-history");
+ if (!mService.mSleeping) {
+ if (DEBUG_STATES) {
+ Slog.d(TAG, "no-history finish of " + r);
+ }
+ requestFinishActivityLocked(r.appToken, Activity.RESULT_CANCELED, null,
+ "no-history");
+ } else {
+ if (DEBUG_STATES) Slog.d(TAG, "Not finishing noHistory " + r
+ + " on stop because we're just sleeping");
+ }
}
}
@@ -3526,9 +3549,10 @@
final boolean requestFinishActivityLocked(IBinder token, int resultCode,
Intent resultData, String reason) {
int index = indexOfTokenLocked(token);
- if (DEBUG_RESULTS) Slog.v(
+ if (DEBUG_RESULTS || DEBUG_STATES) Slog.v(
TAG, "Finishing activity @" + index + ": token=" + token
- + ", result=" + resultCode + ", data=" + resultData);
+ + ", result=" + resultCode + ", data=" + resultData
+ + ", reason=" + reason);
if (index < 0) {
return false;
}
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index 5d9dce7..6c8d969 100755
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -885,8 +885,8 @@
filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
mContext.registerReceiver(mBroadcastReceiver, filter);
- mHoldingScreenWakeLock = pmc.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK,
- "KEEP_SCREEN_ON_FLAG");
+ mHoldingScreenWakeLock = pmc.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK
+ | PowerManager.ON_AFTER_RELEASE, "KEEP_SCREEN_ON_FLAG");
mHoldingScreenWakeLock.setReferenceCounted(false);
mInputManager = new InputManagerService(context, mInputMonitor);