Merge "Make the silent/vibrate status icon reflect overall device state. (DO NOT MERGE)" into froyo
diff --git a/Android.mk b/Android.mk
index 10b6d67..8783934 100644
--- a/Android.mk
+++ b/Android.mk
@@ -369,6 +369,7 @@
-since ./frameworks/base/api/5.xml 5 \
-since ./frameworks/base/api/6.xml 6 \
-since ./frameworks/base/api/7.xml 7 \
+ -since ./frameworks/base/api/8.xml 8 \
-error 1 -error 2 -warning 3 -error 4 -error 6 -error 8 \
-overview $(LOCAL_PATH)/core/java/overview.html
diff --git a/core/java/android/pim/vcard/VCardComposer.java b/core/java/android/pim/vcard/VCardComposer.java
index dc0d864..0e8b665 100644
--- a/core/java/android/pim/vcard/VCardComposer.java
+++ b/core/java/android/pim/vcard/VCardComposer.java
@@ -534,9 +534,11 @@
.appendEmails(contentValuesListMap.get(Email.CONTENT_ITEM_TYPE))
.appendPostals(contentValuesListMap.get(StructuredPostal.CONTENT_ITEM_TYPE))
.appendOrganizations(contentValuesListMap.get(Organization.CONTENT_ITEM_TYPE))
- .appendWebsites(contentValuesListMap.get(Website.CONTENT_ITEM_TYPE))
- .appendPhotos(contentValuesListMap.get(Photo.CONTENT_ITEM_TYPE))
- .appendNotes(contentValuesListMap.get(Note.CONTENT_ITEM_TYPE))
+ .appendWebsites(contentValuesListMap.get(Website.CONTENT_ITEM_TYPE));
+ if ((mVCardType & VCardConfig.FLAG_REFRAIN_IMAGE_EXPORT) == 0) {
+ builder.appendPhotos(contentValuesListMap.get(Photo.CONTENT_ITEM_TYPE));
+ }
+ builder.appendNotes(contentValuesListMap.get(Note.CONTENT_ITEM_TYPE))
.appendEvents(contentValuesListMap.get(Event.CONTENT_ITEM_TYPE))
.appendIms(contentValuesListMap.get(Im.CONTENT_ITEM_TYPE))
.appendRelation(contentValuesListMap.get(Relation.CONTENT_ITEM_TYPE));
diff --git a/core/java/android/pim/vcard/VCardConfig.java b/core/java/android/pim/vcard/VCardConfig.java
index 3442ae7..3409be6 100644
--- a/core/java/android/pim/vcard/VCardConfig.java
+++ b/core/java/android/pim/vcard/VCardConfig.java
@@ -182,6 +182,14 @@
*/
public static final int FLAG_APPEND_TYPE_PARAM = 0x04000000;
+ /**
+ * <P>
+ * The flag asking exporter to refrain image export.
+ * </P>
+ * @hide will be deleted in the near future.
+ */
+ public static final int FLAG_REFRAIN_IMAGE_EXPORT = 0x02000000;
+
//// The followings are VCard types available from importer/exporter. ////
/**
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index d99ebc9..11e5ad1 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -1512,6 +1512,13 @@
* @hide
*/
static final int CANCEL_NEXT_UP_EVENT = 0x04000000;
+
+ /**
+ * Indicates that we should awaken scroll bars once attached
+ *
+ * @hide
+ */
+ private static final int AWAKEN_SCROLL_BARS_ON_ATTACH = 0x08000000;
/**
* The parent this view is attached to.
@@ -3838,6 +3845,13 @@
* {@link #INVISIBLE} or {@link #GONE}.
*/
protected void onVisibilityChanged(View changedView, int visibility) {
+ if (visibility == VISIBLE) {
+ if (mAttachInfo != null) {
+ initialAwakenScrollBars();
+ } else {
+ mPrivateFlags |= AWAKEN_SCROLL_BARS_ON_ATTACH;
+ }
+ }
}
/**
@@ -3888,6 +3902,9 @@
* @param visibility The new visibility of the window.
*/
protected void onWindowVisibilityChanged(int visibility) {
+ if (visibility == VISIBLE) {
+ initialAwakenScrollBars();
+ }
}
/**
@@ -4909,6 +4926,19 @@
}
/**
+ * Trigger the scrollbars to draw.
+ * This method differs from awakenScrollBars() only in its default duration.
+ * initialAwakenScrollBars() will show the scroll bars for longer than
+ * usual to give the user more of a chance to notice them.
+ *
+ * @return true if the animation is played, false otherwise.
+ */
+ private boolean initialAwakenScrollBars() {
+ return mScrollCache != null &&
+ awakenScrollBars(mScrollCache.scrollBarDefaultDelayBeforeFade * 4, true);
+ }
+
+ /**
* <p>
* Trigger the scrollbars to draw. When invoked this method starts an
* animation to fade the scrollbars out after a fixed delay. If a subclass
@@ -5900,6 +5930,10 @@
if ((mPrivateFlags & REQUEST_TRANSPARENT_REGIONS) != 0) {
mParent.requestTransparentRegion(this);
}
+ if ((mPrivateFlags & AWAKEN_SCROLL_BARS_ON_ATTACH) != 0) {
+ initialAwakenScrollBars();
+ mPrivateFlags &= ~AWAKEN_SCROLL_BARS_ON_ATTACH;
+ }
}
/**
diff --git a/core/java/android/webkit/PluginFullScreenHolder.java b/core/java/android/webkit/PluginFullScreenHolder.java
index 6d9e108..ae326d5 100644
--- a/core/java/android/webkit/PluginFullScreenHolder.java
+++ b/core/java/android/webkit/PluginFullScreenHolder.java
@@ -27,6 +27,7 @@
import android.app.Dialog;
import android.view.KeyEvent;
import android.view.MotionEvent;
+import android.view.SurfaceView;
import android.view.View;
import android.view.ViewGroup;
@@ -51,6 +52,16 @@
contentView.setLayoutParams(new ViewGroup.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT));
+ // fixed size is only used either during pinch zoom or surface is too
+ // big. Make sure it is not fixed size before setting it to the full
+ // screen content view. The SurfaceView will be set to the correct mode
+ // by the ViewManager when it is re-attached to the WebView.
+ if (contentView instanceof SurfaceView) {
+ final SurfaceView sView = (SurfaceView) contentView;
+ if (sView.isFixedSize()) {
+ sView.getHolder().setSizeFromLayout();
+ }
+ }
super.setContentView(contentView);
mContentView = contentView;
}
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 6db974c..ff233d2 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -874,18 +874,18 @@
}
private void updateZoomButtonsEnabled() {
+ if (mZoomButtonsController == null) return;
boolean canZoomIn = mActualScale < mMaxZoomScale;
boolean canZoomOut = mActualScale > mMinZoomScale && !mInZoomOverview;
- ZoomButtonsController controller = getZoomButtonsController();
if (!canZoomIn && !canZoomOut) {
// Hide the zoom in and out buttons, as well as the fit to page
// button, if the page cannot zoom
- controller.getZoomControls().setVisibility(View.GONE);
+ mZoomButtonsController.getZoomControls().setVisibility(View.GONE);
} else {
// Set each one individually, as a page may be able to zoom in
// or out.
- controller.setZoomInEnabled(canZoomIn);
- controller.setZoomOutEnabled(canZoomOut);
+ mZoomButtonsController.setZoomInEnabled(canZoomIn);
+ mZoomButtonsController.setZoomOutEnabled(canZoomOut);
}
}
@@ -4013,7 +4013,8 @@
}
} else {
if (mWebViewCore != null && getSettings().getBuiltInZoomControls()
- && !getZoomButtonsController().isVisible()) {
+ && (mZoomButtonsController == null ||
+ !mZoomButtonsController.isVisible())) {
/*
* The zoom controls come in their own window, so our window
* loses focus. Our policy is to not draw the cursor ring if
@@ -4939,6 +4940,11 @@
WebViewCore.pauseUpdatePicture(mWebViewCore);
// fall through to TOUCH_DRAG_MODE
} else {
+ // WebKit may consume the touch event and modify
+ // DOM. drawContentPicture() will be called with
+ // animateSroll as true for better performance.
+ // Force redraw in high-quality.
+ invalidate();
break;
}
} else {
@@ -5837,7 +5843,7 @@
}
WebSettings settings = getSettings();
if (settings.getBuiltInZoomControls()) {
- if (getZoomButtonsController().isVisible()) {
+ if (mZoomButtonsController != null) {
mZoomButtonsController.setVisible(false);
}
} else {
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index 6660c276..9fbf171 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -712,15 +712,6 @@
mOptions.add(opt);
}
- char lockProfSampleBuf[sizeof("-Xlockprofsample:") + sizeof(propBuf)];
- property_get("dalvik.vm.lockprof.sample", propBuf, "");
- if (strlen(propBuf) > 0) {
- strcpy(lockProfSampleBuf, "-Xlockprofsample:");
- strcat(lockProfSampleBuf, propBuf);
- opt.optionString = lockProfSampleBuf;
- mOptions.add(opt);
- }
-
#if defined(WITH_JIT)
/* Minimal profile threshold to trigger JIT compilation */
char jitThresholdBuf[sizeof("-Xjitthreshold:") + PROPERTY_VALUE_MAX];
diff --git a/include/binder/IMemory.h b/include/binder/IMemory.h
index ae042cb..74d2cc7 100644
--- a/include/binder/IMemory.h
+++ b/include/binder/IMemory.h
@@ -36,8 +36,7 @@
// flags returned by getFlags()
enum {
- READ_ONLY = 0x00000001,
- MAP_ONCE = 0x00000002
+ READ_ONLY = 0x00000001
};
virtual int getHeapID() const = 0;
diff --git a/include/binder/MemoryHeapBase.h b/include/binder/MemoryHeapBase.h
index d793c24..2f2e31b 100644
--- a/include/binder/MemoryHeapBase.h
+++ b/include/binder/MemoryHeapBase.h
@@ -32,7 +32,6 @@
public:
enum {
READ_ONLY = IMemoryHeap::READ_ONLY,
- MAP_ONCE = IMemoryHeap::MAP_ONCE,
// memory won't be mapped locally, but will be mapped in the remote
// process.
DONT_MAP_LOCALLY = 0x00000100,
diff --git a/include/binder/MemoryHeapPmem.h b/include/binder/MemoryHeapPmem.h
index aac164f..e1660c4 100644
--- a/include/binder/MemoryHeapPmem.h
+++ b/include/binder/MemoryHeapPmem.h
@@ -46,8 +46,7 @@
sp<MemoryHeapPmem> mClientHeap;
};
- MemoryHeapPmem(const sp<MemoryHeapBase>& pmemHeap,
- uint32_t flags = IMemoryHeap::MAP_ONCE);
+ MemoryHeapPmem(const sp<MemoryHeapBase>& pmemHeap, uint32_t flags = 0);
~MemoryHeapPmem();
/* HeapInterface additions */
diff --git a/libs/binder/IMemory.cpp b/libs/binder/IMemory.cpp
index 6c1d225..bc8c412 100644
--- a/libs/binder/IMemory.cpp
+++ b/libs/binder/IMemory.cpp
@@ -46,7 +46,6 @@
virtual void binderDied(const wp<IBinder>& who);
sp<IMemoryHeap> find_heap(const sp<IBinder>& binder);
- void pin_heap(const sp<IBinder>& binder);
void free_heap(const sp<IBinder>& binder);
sp<IMemoryHeap> get_heap(const sp<IBinder>& binder);
void dump_heaps();
@@ -100,13 +99,9 @@
static inline void dump_heaps() {
gHeapCache->dump_heaps();
}
- void inline pin_heap() const {
- gHeapCache->pin_heap(const_cast<BpMemoryHeap*>(this)->asBinder());
- }
void assertMapped() const;
void assertReallyMapped() const;
- void pinHeap() const;
mutable volatile int32_t mHeapId;
mutable void* mBase;
@@ -320,11 +315,6 @@
asBinder().get(), size, fd, strerror(errno));
close(fd);
} else {
- if (flags & MAP_ONCE) {
- //LOGD("pinning heap (binder=%p, size=%d, fd=%d",
- // asBinder().get(), size, fd);
- pin_heap();
- }
mSize = size;
mFlags = flags;
android_atomic_write(fd, &mHeapId);
@@ -421,19 +411,6 @@
}
}
-void HeapCache::pin_heap(const sp<IBinder>& binder)
-{
- Mutex::Autolock _l(mHeapCacheLock);
- ssize_t i = mHeapCache.indexOfKey(binder);
- if (i>=0) {
- heap_info_t& info(mHeapCache.editValueAt(i));
- android_atomic_inc(&info.count);
- binder->linkToDeath(this);
- } else {
- LOGE("pin_heap binder=%p not found!!!", binder.get());
- }
-}
-
void HeapCache::free_heap(const sp<IBinder>& binder) {
free_heap( wp<IBinder>(binder) );
}
diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java
index a38be48..df07059 100644
--- a/media/java/android/media/AudioService.java
+++ b/media/java/android/media/AudioService.java
@@ -279,6 +279,12 @@
mMode = AudioSystem.MODE_INVALID;
setMode(AudioSystem.MODE_NORMAL, null);
mMediaServerOk = true;
+
+ // Call setRingerModeInt() to apply correct mute
+ // state on streams affected by ringer mode.
+ mRingerModeMutedStreams = 0;
+ setRingerModeInt(getRingerMode(), false);
+
AudioSystem.setErrorCallback(mAudioSystemCallback);
loadSoundEffects();
@@ -1728,6 +1734,9 @@
}
private void makeA2dpDeviceUnavailableLater(String address) {
+ // prevent any activity on the A2DP audio output to avoid unwanted
+ // reconnection of the sink.
+ AudioSystem.setParameters("A2dpSuspended=true");
// the device will be made unavailable later, so consider it disconnected right away
mConnectedDevices.remove(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP);
// send the delayed message to make the device unavailable later
diff --git a/media/java/android/media/MediaScanner.java b/media/java/android/media/MediaScanner.java
index f845fec1..e80ece6 100644
--- a/media/java/android/media/MediaScanner.java
+++ b/media/java/android/media/MediaScanner.java
@@ -714,7 +714,12 @@
}
}
}
- if (isAudio) {
+ long rowId = entry.mRowId;
+ if (isAudio && rowId == 0) {
+ // Only set these for new entries. For existing entries, they
+ // may have been modified later, and we want to keep the current
+ // values so that custom ringtones still show up in the ringtone
+ // picker.
values.put(Audio.Media.IS_RINGTONE, ringtones);
values.put(Audio.Media.IS_NOTIFICATION, notifications);
values.put(Audio.Media.IS_ALARM, alarms);
@@ -764,7 +769,6 @@
}
Uri result = null;
- long rowId = entry.mRowId;
if (rowId == 0) {
// new file, insert it
result = mMediaProvider.insert(tableUri, values);
diff --git a/opengl/java/android/opengl/GLSurfaceView.java b/opengl/java/android/opengl/GLSurfaceView.java
index 5ad0361..f904cdf 100644
--- a/opengl/java/android/opengl/GLSurfaceView.java
+++ b/opengl/java/android/opengl/GLSurfaceView.java
@@ -973,9 +973,12 @@
mEglDisplay, mEglConfig, holder);
if (mEglSurface == null || mEglSurface == EGL10.EGL_NO_SURFACE) {
- Log.w("EglHelper", "createWindowSurface failed. mEglDisplay: " + mEglDisplay +
- " mEglConfig: " + mEglConfig + " holder: " + holder);
- throwEglException("createWindowSurface");
+ int error = mEgl.eglGetError();
+ if (error == EGL10.EGL_BAD_NATIVE_WINDOW) {
+ Log.e("EglHelper", "createWindowSurface returned EGL_BAD_NATIVE_WINDOW.");
+ return null;
+ }
+ throwEglException("createWindowSurface", error);
}
/*
@@ -1019,9 +1022,16 @@
* get a new surface.
*/
int error = mEgl.eglGetError();
- if (error == EGL11.EGL_CONTEXT_LOST) {
+ switch(error) {
+ case EGL11.EGL_CONTEXT_LOST:
return false;
- } else {
+ case EGL10.EGL_BAD_NATIVE_WINDOW:
+ // The native window is bad, probably because the
+ // window manager has closed it. Ignore this error,
+ // on the expectation that the application will be closed soon.
+ Log.e("EglHelper", "eglSwapBuffers returned EGL_BAD_NATIVE_WINDOW. tid=" + Thread.currentThread().getId());
+ break;
+ default:
throwEglException("eglSwapBuffers", error);
}
}
@@ -1292,6 +1302,10 @@
Log.w("GLThread", "egl createSurface");
}
gl = (GL10) mEglHelper.createSurface(getHolder());
+ if (gl == null) {
+ // Couldn't create a surface. Quit quietly.
+ break;
+ }
sGLThreadManager.checkGLDriver(gl);
createEglSurface = false;
}
diff --git a/services/java/com/android/server/NotificationPlayer.java b/services/java/com/android/server/NotificationPlayer.java
index 4c4da5a..acc4c85 100644
--- a/services/java/com/android/server/NotificationPlayer.java
+++ b/services/java/com/android/server/NotificationPlayer.java
@@ -95,6 +95,7 @@
audioManager.requestAudioFocus(null, mCmd.stream,
AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK);
}
+ player.setOnCompletionListener(NotificationPlayer.this);
player.start();
if (mPlayer != null) {
mPlayer.release();
@@ -125,7 +126,6 @@
t.start();
t.wait();
}
- mPlayer.setOnCompletionListener(this);
//-----------------------------------
long delay = SystemClock.uptimeMillis() - cmd.requestTime;
diff --git a/services/java/com/android/server/ThrottleService.java b/services/java/com/android/server/ThrottleService.java
index 9838fd2..4d2d2f9 100644
--- a/services/java/com/android/server/ThrottleService.java
+++ b/services/java/com/android/server/ThrottleService.java
@@ -20,7 +20,6 @@
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
-import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.ContentResolver;
import android.content.Context;
@@ -79,8 +78,6 @@
private static final int TESTING_RESET_PERIOD_SEC = 60 * 10;
private static final long TESTING_THRESHOLD = 1 * 1024 * 1024;
- private static final int PERIOD_COUNT = 6;
-
private int mPolicyPollPeriodSec;
private long mPolicyThreshold;
private int mPolicyThrottleValue;
@@ -106,7 +103,6 @@
private String mIface;
private static final int NOTIFICATION_WARNING = 2;
- private static final int NOTIFICATION_ALL = 0xFFFFFFFF;
private Notification mThrottlingNotification;
private boolean mWarningNotificationSent = false;
@@ -177,32 +173,31 @@
"ThrottleService");
}
+ private long ntpToWallTime(long ntpTime) {
+ long bestNow = getBestTime();
+ long localNow = System.currentTimeMillis();
+ return localNow + (ntpTime - bestNow);
+ }
+
// TODO - fetch for the iface
// return time in the local, system wall time, correcting for the use of ntp
+
public synchronized long getResetTime(String iface) {
enforceAccessPermission();
long resetTime = 0;
if (mRecorder != null) {
- long bestEnd = mRecorder.getPeriodEnd();
- long bestNow = getBestTime();
- long localNow = System.currentTimeMillis();
-
- resetTime = localNow + (bestEnd - bestNow);
+ resetTime = ntpToWallTime(mRecorder.getPeriodEnd());
}
return resetTime;
}
// TODO - fetch for the iface
- // return time in the loca, system wall tiem, correcting for the use of ntp
+ // return time in the local, system wall time, correcting for the use of ntp
public synchronized long getPeriodStartTime(String iface) {
enforceAccessPermission();
long startTime = 0;
if (mRecorder != null) {
- long bestStart = mRecorder.getPeriodStart();
- long bestNow = getBestTime();
- long localNow = System.currentTimeMillis();
-
- startTime = localNow + (bestStart - bestNow);
+ startTime = ntpToWallTime(mRecorder.getPeriodStart());
}
return startTime;
}
@@ -440,8 +435,8 @@
Intent broadcast = new Intent(ThrottleManager.THROTTLE_POLL_ACTION);
broadcast.putExtra(ThrottleManager.EXTRA_CYCLE_READ, periodRx);
broadcast.putExtra(ThrottleManager.EXTRA_CYCLE_WRITE, periodTx);
- broadcast.putExtra(ThrottleManager.EXTRA_CYCLE_START, ThrottleService.this.getPeriodStartTime(mIface));
- broadcast.putExtra(ThrottleManager.EXTRA_CYCLE_END, ThrottleService.this.getResetTime(mIface));
+ broadcast.putExtra(ThrottleManager.EXTRA_CYCLE_START, getPeriodStartTime(mIface));
+ broadcast.putExtra(ThrottleManager.EXTRA_CYCLE_END, getResetTime(mIface));
mContext.sendStickyBroadcast(broadcast);
mAlarmManager.cancel(mPendingPollIntent);
@@ -625,6 +620,7 @@
if (mRecorder.setNextPeriod(start, end)) {
clearThrottleAndNotification();
+ onPollAlarm();
}
mAlarmManager.cancel(mPendingResetIntent);
@@ -642,31 +638,40 @@
private void checkForAuthoritativeTime() {
if (mNtpActive || (mNtpServer == null)) return;
- SntpClient client = new SntpClient();
- if (client.requestTime(mNtpServer, 10000)) {
- mNtpActive = true;
- if (DBG) Slog.d(TAG, "found Authoritative time - reseting alarm");
- mHandler.obtainMessage(EVENT_RESET_ALARM).sendToTarget();
- }
+ // will try to get the ntp time and switch to it if found.
+ // will also cache the time so we don't fetch it repeatedly.
+ getBestTime();
}
- private long getBestTime() {
- SntpClient client = new SntpClient();
+ private static final int MAX_NTP_CACHE_AGE = 30 * 1000;
+ private static final int MAX_NTP_FETCH_WAIT = 10 * 1000;
+ private long cachedNtp;
+ private long cachedNtpTimestamp;
- long time;
- if ((mNtpServer != null) && client.requestTime(mNtpServer, 10000)) {
- time = client.getNtpTime() ;
- if (!mNtpActive) {
- mNtpActive = true;
- if (DBG) Slog.d(TAG, "found Authoritative time - reseting alarm");
- mHandler.obtainMessage(EVENT_RESET_ALARM).sendToTarget();
+ private long getBestTime() {
+ if (mNtpServer != null) {
+ if (mNtpActive) {
+ long ntpAge = SystemClock.elapsedRealtime() - cachedNtpTimestamp;
+ if (ntpAge < MAX_NTP_CACHE_AGE) {
+ return cachedNtp + ntpAge;
+ }
}
- if (DBG) Slog.d(TAG, "using Authoritative time: " + time);
- } else {
- time = System.currentTimeMillis();
- if (DBG) Slog.d(TAG, "using User time: " + time);
- mNtpActive = false;
+ SntpClient client = new SntpClient();
+ if (client.requestTime(mNtpServer, MAX_NTP_FETCH_WAIT)) {
+ cachedNtp = client.getNtpTime();
+ cachedNtpTimestamp = SystemClock.elapsedRealtime();
+ if (!mNtpActive) {
+ mNtpActive = true;
+ if (DBG) Slog.d(TAG, "found Authoritative time - reseting alarm");
+ mHandler.obtainMessage(EVENT_RESET_ALARM).sendToTarget();
+ }
+ if (DBG) Slog.d(TAG, "using Authoritative time: " + cachedNtp);
+ return cachedNtp;
+ }
}
+ long time = System.currentTimeMillis();
+ if (DBG) Slog.d(TAG, "using User time: " + time);
+ mNtpActive = false;
return time;
}
@@ -705,7 +710,6 @@
mPeriodStart = Calendar.getInstance();
mPeriodEnd = Calendar.getInstance();
- zeroData(0);
retrieve();
}
}
@@ -915,6 +919,9 @@
}
private void retrieve() {
+ // clean out any old data first. If we fail to read we don't want old stuff
+ zeroData(0);
+
File f = getDataFile();
byte[] buffer;
FileInputStream s = null;
@@ -952,7 +959,7 @@
mPeriodCount = Integer.parseInt(parsed[parsedUsed++]);
if (parsed.length != 5 + (2 * mPeriodCount)) {
- Slog.e(TAG, "reading data file with bad length ("+parsed.length+" != "+(4 + (2*mPeriodCount))+") - ignoring");
+ Slog.e(TAG, "reading data file with bad length ("+parsed.length+" != "+(5 + (2*mPeriodCount))+") - ignoring");
return;
}
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 13690bc..7e095b5 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -123,6 +123,8 @@
import java.util.Locale;
import java.util.Map;
import java.util.Set;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicLong;
public final class ActivityManagerService extends ActivityManagerNative implements Watchdog.Monitor {
static final String TAG = "ActivityManager";
@@ -927,7 +929,9 @@
*/
final ProcessStats mProcessStats = new ProcessStats(
MONITOR_THREAD_CPU_USAGE);
- long mLastCpuTime = 0;
+ final AtomicLong mLastCpuTime = new AtomicLong(0);
+ final AtomicBoolean mProcessStatsMutexFree = new AtomicBoolean(true);
+
long mLastWriteTime = 0;
long mInitialStartTime = 0;
@@ -1430,7 +1434,7 @@
try {
synchronized(this) {
final long now = SystemClock.uptimeMillis();
- long nextCpuDelay = (mLastCpuTime+MONITOR_CPU_MAX_TIME)-now;
+ long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
//Slog.i(TAG, "Cpu delay=" + nextCpuDelay
// + ", write delay=" + nextWriteDelay);
@@ -1438,12 +1442,12 @@
nextCpuDelay = nextWriteDelay;
}
if (nextCpuDelay > 0) {
+ mProcessStatsMutexFree.set(true);
this.wait(nextCpuDelay);
}
}
} catch (InterruptedException e) {
}
-
updateCpuStatsNow();
} catch (Exception e) {
Slog.e(TAG, "Unexpected exception collecting process stats", e);
@@ -1470,22 +1474,26 @@
}
void updateCpuStats() {
- synchronized (mProcessStatsThread) {
- final long now = SystemClock.uptimeMillis();
- if (mLastCpuTime < (now-MONITOR_CPU_MIN_TIME)) {
+ final long now = SystemClock.uptimeMillis();
+ if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
+ return;
+ }
+ if (mProcessStatsMutexFree.compareAndSet(true, false)) {
+ synchronized (mProcessStatsThread) {
mProcessStatsThread.notify();
}
}
}
-
+
void updateCpuStatsNow() {
synchronized (mProcessStatsThread) {
+ mProcessStatsMutexFree.set(false);
final long now = SystemClock.uptimeMillis();
boolean haveNewCpuStats = false;
if (MONITOR_CPU_USAGE &&
- mLastCpuTime < (now-MONITOR_CPU_MIN_TIME)) {
- mLastCpuTime = now;
+ mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
+ mLastCpuTime.set(now);
haveNewCpuStats = true;
mProcessStats.update();
//Slog.i(TAG, mProcessStats.printCurrentState());
@@ -6133,12 +6141,10 @@
if (!(pendingResult instanceof PendingIntentRecord)) {
return null;
}
- synchronized(this) {
- try {
- PendingIntentRecord res = (PendingIntentRecord)pendingResult;
- return res.key.packageName;
- } catch (ClassCastException e) {
- }
+ try {
+ PendingIntentRecord res = (PendingIntentRecord)pendingResult;
+ return res.key.packageName;
+ } catch (ClassCastException e) {
}
return null;
}
diff --git a/wifi/java/android/net/wifi/WifiStateTracker.java b/wifi/java/android/net/wifi/WifiStateTracker.java
index 4f84aab..978d821 100644
--- a/wifi/java/android/net/wifi/WifiStateTracker.java
+++ b/wifi/java/android/net/wifi/WifiStateTracker.java
@@ -735,6 +735,8 @@
mRunState = RUN_STATE_RUNNING;
noteRunState();
checkUseStaticIp();
+ /* Reset notification state on new connection */
+ resetNotificationTimer();
/*
* DHCP requests are blocking, so run them in a separate thread.
*/