diff options
48 files changed, 713 insertions, 231 deletions
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java index 4215f20..fa87c80 100644 --- a/core/java/android/net/ConnectivityManager.java +++ b/core/java/android/net/ConnectivityManager.java @@ -37,6 +37,7 @@ import android.os.Messenger; import android.os.RemoteException; import android.os.ServiceManager; import android.provider.Settings; +import android.telephony.SubscriptionManager; import android.telephony.TelephonyManager; import android.util.ArrayMap; import android.util.Log; @@ -1295,9 +1296,15 @@ public class ConnectivityManager { if (b != null) { try { ITelephony it = ITelephony.Stub.asInterface(b); - return it.getDataEnabled(); + int subId = SubscriptionManager.getDefaultDataSubId(); + Log.d("ConnectivityManager", "getMobileDataEnabled()+ subId=" + subId); + boolean retVal = it.getDataEnabled(subId); + Log.d("ConnectivityManager", "getMobileDataEnabled()- subId=" + subId + + " retVal=" + retVal); + return retVal; } catch (RemoteException e) { } } + Log.d("ConnectivityManager", "getMobileDataEnabled()- remote exception retVal=false"); return false; } diff --git a/core/java/android/net/INetworkStatsService.aidl b/core/java/android/net/INetworkStatsService.aidl index b7b8731..2c3881c 100644 --- a/core/java/android/net/INetworkStatsService.aidl +++ b/core/java/android/net/INetworkStatsService.aidl @@ -40,8 +40,12 @@ interface INetworkStatsService { /** Mark given UID as being in foreground for stats purposes. */ void setUidForeground(int uid, boolean uidForeground); + + /** Force update of ifaces. */ + void forceUpdateIfaces(); /** Force update of statistics. */ void forceUpdate(); + /** Advise persistance threshold; may be overridden internally. */ void advisePersistThreshold(long thresholdBytes); diff --git a/core/java/android/net/NetworkIdentity.java b/core/java/android/net/NetworkIdentity.java index 6864749..a9de23e 100644 --- a/core/java/android/net/NetworkIdentity.java +++ b/core/java/android/net/NetworkIdentity.java @@ -41,7 +41,11 @@ public class NetworkIdentity implements Comparable<NetworkIdentity> { /** * When enabled, combine all {@link #mSubType} together under * {@link #SUBTYPE_COMBINED}. + * + * @deprecated we no longer offer to collect statistics on a per-subtype + * basis; this is always disabled. */ + @Deprecated public static final boolean COMBINE_SUBTYPE_ENABLED = true; public static final int SUBTYPE_COMBINED = -1; diff --git a/core/java/android/net/NetworkTemplate.java b/core/java/android/net/NetworkTemplate.java index 6cfab92..57eef83 100644 --- a/core/java/android/net/NetworkTemplate.java +++ b/core/java/android/net/NetworkTemplate.java @@ -49,7 +49,9 @@ import java.util.Objects; public class NetworkTemplate implements Parcelable { public static final int MATCH_MOBILE_ALL = 1; + @Deprecated public static final int MATCH_MOBILE_3G_LOWER = 2; + @Deprecated public static final int MATCH_MOBILE_4G = 3; public static final int MATCH_WIFI = 4; public static final int MATCH_ETHERNET = 5; @@ -293,6 +295,7 @@ public class NetworkTemplate implements Parcelable { /** * Check if mobile network classified 3G or lower with matching IMSI. */ + @Deprecated private boolean matchesMobile3gLower(NetworkIdentity ident) { ensureSubtypeAvailable(); if (ident.mType == TYPE_WIMAX) { @@ -311,6 +314,7 @@ public class NetworkTemplate implements Parcelable { /** * Check if mobile network classified 4G with matching IMSI. */ + @Deprecated private boolean matchesMobile4g(NetworkIdentity ident) { ensureSubtypeAvailable(); if (ident.mType == TYPE_WIMAX) { diff --git a/core/java/android/os/Debug.java b/core/java/android/os/Debug.java index 3f42d25..a9deaf3 100644 --- a/core/java/android/os/Debug.java +++ b/core/java/android/os/Debug.java @@ -168,7 +168,7 @@ public final class Debug public static final int NUM_OTHER_STATS = 17; /** @hide */ - public static final int NUM_DVK_STATS = 5; + public static final int NUM_DVK_STATS = 8; /** @hide */ public static final int NUM_CATEGORIES = 7; @@ -314,6 +314,9 @@ public final class Debug case 19: return ".LinearAlloc"; case 20: return ".GC"; case 21: return ".JITCache"; + case 22: return ".Zygote"; + case 23: return ".NonMoving"; + case 24: return ".IndirectRef"; default: return "????"; } } @@ -1071,9 +1074,10 @@ href="{@docRoot}guide/developing/tools/traceview.html">Traceview: A Graphical Lo /** * Retrieves the PSS memory used by the process as given by the * smaps. Optionally supply a long array of 1 entry to also - * receive the uss of the process. @hide + * receive the uss of the process, and another array to also + * retrieve the separate memtrack size. @hide */ - public static native long getPss(int pid, long[] outUss); + public static native long getPss(int pid, long[] outUss, long[] outMemtrack); /** @hide */ public static final int MEMINFO_TOTAL = 0; diff --git a/core/java/android/service/wallpaper/WallpaperService.java b/core/java/android/service/wallpaper/WallpaperService.java index 67f632f..9496b53 100644 --- a/core/java/android/service/wallpaper/WallpaperService.java +++ b/core/java/android/service/wallpaper/WallpaperService.java @@ -691,8 +691,8 @@ public abstract class WallpaperService extends Service { if (DEBUG) Log.v(TAG, "New surface: " + mSurfaceHolder.mSurface + ", frame=" + mWinFrame); - int w = mWinFrame.width() + mOverscanInsets.left + mOverscanInsets.right; - int h = mWinFrame.height() + mOverscanInsets.top + mOverscanInsets.bottom; + int w = mWinFrame.width(); + int h = mWinFrame.height(); if (!fixedSize) { final Rect padding = mIWallpaperEngine.mDisplayPadding; diff --git a/core/java/android/view/RenderNodeAnimator.java b/core/java/android/view/RenderNodeAnimator.java index 7feca30..7b35a3b 100644 --- a/core/java/android/view/RenderNodeAnimator.java +++ b/core/java/android/view/RenderNodeAnimator.java @@ -148,6 +148,10 @@ public class RenderNodeAnimator extends Animator { if (mState != STATE_PREPARE) { throw new IllegalStateException("Animator has already started, cannot change it now!"); } + if (mNativePtr == null) { + throw new IllegalStateException("Animator's target has been destroyed " + + "(trying to modify an animation after activity destroy?)"); + } } static boolean isNativeInterpolator(TimeInterpolator interpolator) { @@ -180,7 +184,10 @@ public class RenderNodeAnimator extends Animator { mState = STATE_DELAYED; applyInterpolator(); - if (mStartDelay <= 0 || !mUiThreadHandlesDelay) { + if (mNativePtr == null) { + // It's dead, immediately cancel + cancel(); + } else if (mStartDelay <= 0 || !mUiThreadHandlesDelay) { nSetStartDelay(mNativePtr.get(), mStartDelay); doStart(); } else { @@ -208,7 +215,9 @@ public class RenderNodeAnimator extends Animator { private void moveToRunningState() { mState = STATE_RUNNING; - nStart(mNativePtr.get(), this); + if (mNativePtr != null) { + nStart(mNativePtr.get()); + } notifyStartListeners(); } @@ -227,7 +236,6 @@ public class RenderNodeAnimator extends Animator { getHelper().removeDelayedAnimation(this); moveToRunningState(); } - nEnd(mNativePtr.get()); final ArrayList<AnimatorListener> listeners = cloneListeners(); final int numListeners = listeners == null ? 0 : listeners.size(); @@ -235,10 +243,7 @@ public class RenderNodeAnimator extends Animator { listeners.get(i).onAnimationCancel(this); } - if (mViewTarget != null) { - // Kick off a frame to flush the state change - mViewTarget.invalidateViewProperty(true, false); - } + end(); } } @@ -249,10 +254,15 @@ public class RenderNodeAnimator extends Animator { getHelper().removeDelayedAnimation(this); doStart(); } - nEnd(mNativePtr.get()); - if (mViewTarget != null) { - // Kick off a frame to flush the state change - mViewTarget.invalidateViewProperty(true, false); + if (mNativePtr != null) { + nEnd(mNativePtr.get()); + if (mViewTarget != null) { + // Kick off a frame to flush the state change + mViewTarget.invalidateViewProperty(true, false); + } + } else { + // It's already dead, jump to onFinish + onFinished(); } } } @@ -281,9 +291,11 @@ public class RenderNodeAnimator extends Animator { } private void setTarget(RenderNode node) { + checkMutable(); if (mTarget != null) { throw new IllegalStateException("Target already set!"); } + nSetListener(mNativePtr.get(), this); mTarget = node; mTarget.addAnimator(this); } @@ -346,6 +358,12 @@ public class RenderNodeAnimator extends Animator { } protected void onFinished() { + if (mState == STATE_PREPARE) { + // Unlikely but possible, the native side has been destroyed + // before we have started. + releaseNativePtr(); + return; + } if (mState == STATE_DELAYED) { getHelper().removeDelayedAnimation(this); notifyStartListeners(); @@ -361,8 +379,14 @@ public class RenderNodeAnimator extends Animator { // Release the native object, as it has a global reference to us. This // breaks the cyclic reference chain, and allows this object to be // GC'd - mNativePtr.release(); - mNativePtr = null; + releaseNativePtr(); + } + + private void releaseNativePtr() { + if (mNativePtr != null) { + mNativePtr.release(); + mNativePtr = null; + } } @SuppressWarnings("unchecked") @@ -484,7 +508,8 @@ public class RenderNodeAnimator extends Animator { private static native void nSetStartDelay(long nativePtr, long startDelay); private static native void nSetInterpolator(long animPtr, long interpolatorPtr); private static native void nSetAllowRunningAsync(long animPtr, boolean mayRunAsync); + private static native void nSetListener(long animPtr, RenderNodeAnimator listener); - private static native void nStart(long animPtr, RenderNodeAnimator finishListener); + private static native void nStart(long animPtr); private static native void nEnd(long animPtr); } diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index f7cd523..2bb1ebc 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -5938,9 +5938,12 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * layer. * * @param outRects List to which to add clickable areas. + * + * @hide */ - void addClickableRectsForAccessibility(List<RectF> outRects) { - if (isClickable() || isLongClickable()) { + public void addClickableRectsForAccessibility(List<RectF> outRects) { + if (isClickable() || isLongClickable() + || (mListenerInfo != null && mListenerInfo.mOnTouchListener != null)) { RectF bounds = new RectF(); bounds.set(0, 0, getWidth(), getHeight()); outRects.add(bounds); diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java index ba0ddd5..25a70eb 100644 --- a/core/java/android/view/ViewGroup.java +++ b/core/java/android/view/ViewGroup.java @@ -883,8 +883,11 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager return true; } + /** + * @hide + */ @Override - void addClickableRectsForAccessibility(List<RectF> outRects) { + public void addClickableRectsForAccessibility(List<RectF> outRects) { int sizeBefore = outRects.size(); super.addClickableRectsForAccessibility(outRects); diff --git a/core/java/android/view/accessibility/AccessibilityCache.java b/core/java/android/view/accessibility/AccessibilityCache.java index a218e4d..52912b1 100644 --- a/core/java/android/view/accessibility/AccessibilityCache.java +++ b/core/java/android/view/accessibility/AccessibilityCache.java @@ -78,6 +78,7 @@ final class AccessibilityCache { case AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED: case AccessibilityEvent.TYPE_VIEW_SELECTED: case AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED: + case AccessibilityEvent.TYPE_VIEW_CLICKED: case AccessibilityEvent.TYPE_VIEW_TEXT_SELECTION_CHANGED: { refreshCachedNodeLocked(event.getWindowId(), event.getSourceNodeId()); } break; diff --git a/core/java/android/widget/HorizontalScrollView.java b/core/java/android/widget/HorizontalScrollView.java index 0c65c50..371b480 100644 --- a/core/java/android/widget/HorizontalScrollView.java +++ b/core/java/android/widget/HorizontalScrollView.java @@ -20,6 +20,7 @@ import android.content.Context; import android.content.res.TypedArray; import android.graphics.Canvas; import android.graphics.Rect; +import android.graphics.RectF; import android.os.Build; import android.os.Bundle; import android.os.Parcel; @@ -757,10 +758,22 @@ public class HorizontalScrollView extends FrameLayout { } else { super.scrollTo(scrollX, scrollY); } - + awakenScrollBars(); } + /** + * @hide + */ + @Override + public void addClickableRectsForAccessibility(List<RectF> outRects) { + // This class always consumes touch events, therefore if it + // covers a view we do not want to send a click over it. + RectF bounds = new RectF(); + bounds.set(0, 0, getWidth(), getHeight()); + outRects.add(bounds); + } + @Override public boolean performAccessibilityAction(int action, Bundle arguments) { if (super.performAccessibilityAction(action, arguments)) { diff --git a/core/java/android/widget/ListPopupWindow.java b/core/java/android/widget/ListPopupWindow.java index a31d37e..fe8b08b 100644 --- a/core/java/android/widget/ListPopupWindow.java +++ b/core/java/android/widget/ListPopupWindow.java @@ -1385,7 +1385,9 @@ public class ListPopupWindow { clearCallbacks(); final View src = mSrc; - if (!src.isEnabled()) { + if (!src.isEnabled() || src.isLongClickable()) { + // Ignore long-press if the view is disabled or has its own + // handler. return; } @@ -1394,12 +1396,12 @@ public class ListPopupWindow { } // Don't let the parent intercept our events. - mSrc.getParent().requestDisallowInterceptTouchEvent(true); + src.getParent().requestDisallowInterceptTouchEvent(true); // Make sure we cancel any ongoing source event stream. final long now = SystemClock.uptimeMillis(); final MotionEvent e = MotionEvent.obtain(now, now, MotionEvent.ACTION_CANCEL, 0, 0, 0); - mSrc.onTouchEvent(e); + src.onTouchEvent(e); e.recycle(); mForwarding = true; diff --git a/core/java/android/widget/RadialTimePickerView.java b/core/java/android/widget/RadialTimePickerView.java index 04b5616..75c6184 100644 --- a/core/java/android/widget/RadialTimePickerView.java +++ b/core/java/android/widget/RadialTimePickerView.java @@ -1246,37 +1246,40 @@ public class RadialTimePickerView extends View implements View.OnTouchListener { } final int[] selectionDegrees = mSelectionDegrees; - int type = -1; - int newValue = -1; + final int type; + final int newValue; + final boolean valueChanged; if (mShowHours) { final int snapDegrees = snapOnly30s(degrees, 0) % 360; - if (forceSelection - || selectionDegrees[HOURS] != snapDegrees + valueChanged = selectionDegrees[HOURS] != snapDegrees || selectionDegrees[HOURS_INNER] != snapDegrees - || wasOnInnerCircle != mIsOnInnerCircle) { - selectionDegrees[HOURS] = snapDegrees; - selectionDegrees[HOURS_INNER] = snapDegrees; + || wasOnInnerCircle != mIsOnInnerCircle; - type = HOURS; - newValue = getCurrentHour(); - } + selectionDegrees[HOURS] = snapDegrees; + selectionDegrees[HOURS_INNER] = snapDegrees; + type = HOURS; + newValue = getCurrentHour(); } else { final int snapDegrees = snapPrefer30s(degrees) % 360; - if (forceSelection || selectionDegrees[MINUTES] != snapDegrees) { - selectionDegrees[MINUTES] = snapDegrees; + valueChanged = selectionDegrees[MINUTES] != snapDegrees; - type = MINUTES; - newValue = getCurrentMinute(); - } + selectionDegrees[MINUTES] = snapDegrees; + type = MINUTES; + newValue = getCurrentMinute(); } - if (newValue != -1) { + if (valueChanged || forceSelection || autoAdvance) { + // Fire the listener even if we just need to auto-advance. if (mListener != null) { mListener.onValueSelected(type, newValue, autoAdvance); } - performHapticFeedback(HapticFeedbackConstants.CLOCK_TICK); - invalidate(); + + // Only provide feedback if the value actually changed. + if (valueChanged || forceSelection) { + performHapticFeedback(HapticFeedbackConstants.CLOCK_TICK); + invalidate(); + } return true; } diff --git a/core/java/android/widget/Switch.java b/core/java/android/widget/Switch.java index 4c8aa51..7a22224 100644 --- a/core/java/android/widget/Switch.java +++ b/core/java/android/widget/Switch.java @@ -689,6 +689,10 @@ public class Switch extends CompoundButton { * @return true if (x, y) is within the target area of the switch thumb */ private boolean hitThumb(float x, float y) { + if (mThumbDrawable == null) { + return false; + } + // Relies on mTempRect, MUST be called first! final int thumbOffset = getThumbOffset(); diff --git a/core/jni/android_os_Debug.cpp b/core/jni/android_os_Debug.cpp index e572d22..5a32718 100644 --- a/core/jni/android_os_Debug.cpp +++ b/core/jni/android_os_Debug.cpp @@ -70,6 +70,9 @@ enum { HEAP_DALVIK_LINEARALLOC, HEAP_DALVIK_ACCOUNTING, HEAP_DALVIK_CODE_CACHE, + HEAP_DALVIK_ZYGOTE, + HEAP_DALVIK_NON_MOVING, + HEAP_DALVIK_INDIRECT_REFERENCE_TABLE, _NUM_HEAP, _NUM_EXCLUSIVE_HEAP = HEAP_OTHER_MEMTRACK+1, @@ -274,15 +277,21 @@ static void read_mapinfo(FILE *fp, stats_t* stats) if (strstr(name, "/dev/ashmem/dalvik-LinearAlloc") == name) { subHeap = HEAP_DALVIK_LINEARALLOC; } else if ((strstr(name, "/dev/ashmem/dalvik-alloc space") == name) || - (strstr(name, "/dev/ashmem/dalvik-main space") == name) || - (strstr(name, "/dev/ashmem/dalvik-zygote space") == name) || - (strstr(name, "/dev/ashmem/dalvik-non moving space") == name)) { + (strstr(name, "/dev/ashmem/dalvik-main space") == name)) { // This is the regular Dalvik heap. whichHeap = HEAP_DALVIK; subHeap = HEAP_DALVIK_NORMAL; } else if (strstr(name, "/dev/ashmem/dalvik-large object space") == name) { whichHeap = HEAP_DALVIK; subHeap = HEAP_DALVIK_LARGE; + } else if (strstr(name, "/dev/ashmem/dalvik-non moving space") == name) { + whichHeap = HEAP_DALVIK; + subHeap = HEAP_DALVIK_NON_MOVING; + } else if (strstr(name, "/dev/ashmem/dalvik-zygote space") == name) { + whichHeap = HEAP_DALVIK; + subHeap = HEAP_DALVIK_ZYGOTE; + } else if (strstr(name, "/dev/ashmem/dalvik-indirect ref") == name) { + subHeap = HEAP_DALVIK_INDIRECT_REFERENCE_TABLE; } else if (strstr(name, "/dev/ashmem/dalvik-jit-code-cache") == name) { subHeap = HEAP_DALVIK_CODE_CACHE; } else { @@ -486,11 +495,13 @@ static void android_os_Debug_getDirtyPages(JNIEnv *env, jobject clazz, jobject o android_os_Debug_getDirtyPagesPid(env, clazz, getpid(), object); } -static jlong android_os_Debug_getPssPid(JNIEnv *env, jobject clazz, jint pid, jlongArray outUss) +static jlong android_os_Debug_getPssPid(JNIEnv *env, jobject clazz, jint pid, jlongArray outUss, + jlongArray outMemtrack) { char line[1024]; jlong pss = 0; jlong uss = 0; + jlong memtrack = 0; unsigned temp; char tmp[128]; @@ -498,7 +509,7 @@ static jlong android_os_Debug_getPssPid(JNIEnv *env, jobject clazz, jint pid, jl struct graphics_memory_pss graphics_mem; if (read_memtrack_memory(pid, &graphics_mem) == 0) { - pss = uss = graphics_mem.graphics + graphics_mem.gl + graphics_mem.other; + pss = uss = memtrack = graphics_mem.graphics + graphics_mem.gl + graphics_mem.other; } sprintf(tmp, "/proc/%d/smaps", pid); @@ -541,12 +552,22 @@ static jlong android_os_Debug_getPssPid(JNIEnv *env, jobject clazz, jint pid, jl } } + if (outMemtrack != NULL) { + if (env->GetArrayLength(outMemtrack) >= 1) { + jlong* outMemtrackArray = env->GetLongArrayElements(outMemtrack, 0); + if (outMemtrackArray != NULL) { + outMemtrackArray[0] = memtrack; + } + env->ReleaseLongArrayElements(outMemtrack, outMemtrackArray, 0); + } + } + return pss; } static jlong android_os_Debug_getPss(JNIEnv *env, jobject clazz) { - return android_os_Debug_getPssPid(env, clazz, getpid(), NULL); + return android_os_Debug_getPssPid(env, clazz, getpid(), NULL, NULL); } enum { @@ -954,7 +975,7 @@ static JNINativeMethod gMethods[] = { (void*) android_os_Debug_getDirtyPagesPid }, { "getPss", "()J", (void*) android_os_Debug_getPss }, - { "getPss", "(I[J)J", + { "getPss", "(I[J[J)J", (void*) android_os_Debug_getPssPid }, { "getMemInfo", "([J)V", (void*) android_os_Debug_getMemInfo }, diff --git a/core/jni/android_view_RenderNodeAnimator.cpp b/core/jni/android_view_RenderNodeAnimator.cpp index 311882d..eb56639 100644 --- a/core/jni/android_view_RenderNodeAnimator.cpp +++ b/core/jni/android_view_RenderNodeAnimator.cpp @@ -177,9 +177,13 @@ static void setAllowRunningAsync(JNIEnv* env, jobject clazz, jlong animatorPtr, animator->setAllowRunningAsync(mayRunAsync); } -static void start(JNIEnv* env, jobject clazz, jlong animatorPtr, jobject finishListener) { +static void setListener(JNIEnv* env, jobject clazz, jlong animatorPtr, jobject finishListener) { BaseRenderNodeAnimator* animator = reinterpret_cast<BaseRenderNodeAnimator*>(animatorPtr); animator->setListener(new AnimationListenerBridge(env, finishListener)); +} + +static void start(JNIEnv* env, jobject clazz, jlong animatorPtr) { + BaseRenderNodeAnimator* animator = reinterpret_cast<BaseRenderNodeAnimator*>(animatorPtr); animator->start(); } @@ -208,7 +212,8 @@ static JNINativeMethod gMethods[] = { { "nSetStartDelay", "(JJ)V", (void*) setStartDelay }, { "nSetInterpolator", "(JJ)V", (void*) setInterpolator }, { "nSetAllowRunningAsync", "(JZ)V", (void*) setAllowRunningAsync }, - { "nStart", "(JLandroid/view/RenderNodeAnimator;)V", (void*) start }, + { "nSetListener", "(JLandroid/view/RenderNodeAnimator;)V", (void*) setListener}, + { "nStart", "(J)V", (void*) start}, { "nEnd", "(J)V", (void*) end }, #endif }; diff --git a/core/res/res/drawable/spinner_background_material.xml b/core/res/res/drawable/spinner_background_material.xml index 02ea11b..d99e367 100644 --- a/core/res/res/drawable/spinner_background_material.xml +++ b/core/res/res/drawable/spinner_background_material.xml @@ -16,16 +16,17 @@ <selector xmlns:android="http://schemas.android.com/apk/res/android" android:autoMirrored="true"> - <item android:state_checked="true"> + <item android:state_enabled="false"> <nine-patch android:src="@drawable/spinner_mtrl_am_alpha" - android:tint="?attr/colorControlActivated" /> + android:tint="?attr/colorControlNormal" + android:alpha="?attr/disabledAlpha" /> </item> - <item android:state_pressed="true"> + <item android:state_pressed="false" android:state_focused="false"> <nine-patch android:src="@drawable/spinner_mtrl_am_alpha" - android:tint="?attr/colorControlActivated" /> + android:tint="?attr/colorControlNormal" /> </item> <item> <nine-patch android:src="@drawable/spinner_mtrl_am_alpha" - android:tint="?attr/colorControlNormal" /> + android:tint="?attr/colorControlActivated" /> </item> </selector> diff --git a/core/res/res/drawable/spinner_textfield_background_material.xml b/core/res/res/drawable/spinner_textfield_background_material.xml index 2732d53..fab3dc9 100644 --- a/core/res/res/drawable/spinner_textfield_background_material.xml +++ b/core/res/res/drawable/spinner_textfield_background_material.xml @@ -17,7 +17,21 @@ <inset xmlns:android="http://schemas.android.com/apk/res/android" android:inset="@dimen/control_inset_material"> <selector android:autoMirrored="true"> - <item android:state_checked="false" android:state_pressed="false"> + <item android:state_enabled="false"> + <layer-list android:paddingMode="stack"> + <item> + <nine-patch android:src="@drawable/textfield_activated_mtrl_alpha" + android:tint="?attr/colorControlActivated" + android:alpha="?attr/disabledAlpha" /> + </item> + <item> + <nine-patch android:src="@drawable/spinner_mtrl_am_alpha" + android:tint="?attr/colorControlActivated" + android:alpha="?attr/disabledAlpha" /> + </item> + </layer-list> + </item> + <item android:state_pressed="false" android:state_focused="false"> <layer-list android:paddingMode="stack"> <item> <nine-patch android:src="@drawable/textfield_default_mtrl_alpha" diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index d0c612d..6769c85 100755 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -1830,6 +1830,9 @@ provisioning, availability etc --> <bool name="config_carrier_volte_available">false</bool> + <!-- Flag specifying whether VoLTE availability is based on provisioning --> + <bool name="config_carrier_volte_provisioned">false</bool> + <!-- Flag specifying whether VT is available on device --> <bool name="config_device_vt_available">false</bool> diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index 9845096..4f2ed22 100755 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -2079,6 +2079,7 @@ <java-symbol type="bool" name="imsServiceAllowTurnOff" /> <java-symbol type="bool" name="config_device_volte_available" /> <java-symbol type="bool" name="config_carrier_volte_available" /> + <java-symbol type="bool" name="config_carrier_volte_provisioned" /> <java-symbol type="bool" name="config_device_vt_available" /> <java-symbol type="bool" name="config_carrier_vt_available" /> <java-symbol type="bool" name="useImsAlwaysForEmergencyCall" /> diff --git a/graphics/java/android/graphics/drawable/AnimationDrawable.java b/graphics/java/android/graphics/drawable/AnimationDrawable.java index 9eb0251..74ff1b0 100644 --- a/graphics/java/android/graphics/drawable/AnimationDrawable.java +++ b/graphics/java/android/graphics/drawable/AnimationDrawable.java @@ -375,7 +375,7 @@ public class AnimationDrawable extends DrawableContainer implements Runnable, An mOneShot = orig.mOneShot; } else { mDurations = new int[getCapacity()]; - mOneShot = true; + mOneShot = false; } } diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java index 03ecad2..b99b4fd 100644 --- a/media/java/android/media/AudioService.java +++ b/media/java/android/media/AudioService.java @@ -3110,11 +3110,12 @@ public class AudioService extends IAudioService.Stub { break; } if ((direction == AudioManager.ADJUST_LOWER)) { - if (VOLUME_SETS_RINGER_MODE_SILENT - && mPrevVolDirection != AudioManager.ADJUST_LOWER) { - ringerMode = RINGER_MODE_SILENT; - } else { - result |= AudioManager.FLAG_SHOW_VIBRATE_HINT; + if (mPrevVolDirection != AudioManager.ADJUST_LOWER) { + if (VOLUME_SETS_RINGER_MODE_SILENT) { + ringerMode = RINGER_MODE_SILENT; + } else { + result |= AudioManager.FLAG_SHOW_VIBRATE_HINT; + } } } else if (direction == AudioManager.ADJUST_RAISE) { ringerMode = RINGER_MODE_NORMAL; diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardPinBasedInputView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardPinBasedInputView.java index bca0305..7c56e84 100644 --- a/packages/Keyguard/src/com/android/keyguard/KeyguardPinBasedInputView.java +++ b/packages/Keyguard/src/com/android/keyguard/KeyguardPinBasedInputView.java @@ -17,7 +17,11 @@ package com.android.keyguard; import android.content.Context; +import android.database.ContentObserver; import android.graphics.Rect; +import android.os.Handler; +import android.os.UserHandle; +import android.provider.Settings; import android.util.AttributeSet; import android.view.KeyEvent; import android.view.View; @@ -28,19 +32,39 @@ import android.view.View; public abstract class KeyguardPinBasedInputView extends KeyguardAbsKeyInputView implements View.OnKeyListener { + private final android.database.ContentObserver mSpeakPasswordObserver + = new ContentObserver(new Handler()) { + @Override + public void onChange(boolean selfChange) { + super.onChange(selfChange); + // Ensure that it's not called too early + if (mButton0 != null) { + mButton0.updateContentDescription(); + mButton1.updateContentDescription(); + mButton2.updateContentDescription(); + mButton3.updateContentDescription(); + mButton4.updateContentDescription(); + mButton5.updateContentDescription(); + mButton6.updateContentDescription(); + mButton7.updateContentDescription(); + mButton8.updateContentDescription(); + mButton9.updateContentDescription(); + } + } + }; protected PasswordTextView mPasswordEntry; private View mOkButton; private View mDeleteButton; - private View mButton0; - private View mButton1; - private View mButton2; - private View mButton3; - private View mButton4; - private View mButton5; - private View mButton6; - private View mButton7; - private View mButton8; - private View mButton9; + private NumPadKey mButton0; + private NumPadKey mButton1; + private NumPadKey mButton2; + private NumPadKey mButton3; + private NumPadKey mButton4; + private NumPadKey mButton5; + private NumPadKey mButton6; + private NumPadKey mButton7; + private NumPadKey mButton8; + private NumPadKey mButton9; public KeyguardPinBasedInputView(Context context) { this(context, null); @@ -48,6 +72,9 @@ public abstract class KeyguardPinBasedInputView extends KeyguardAbsKeyInputView public KeyguardPinBasedInputView(Context context, AttributeSet attrs) { super(context, attrs); + context.getContentResolver().registerContentObserver( + Settings.Secure.getUriFor(Settings.Secure.ACCESSIBILITY_SPEAK_PASSWORD), true, + mSpeakPasswordObserver, UserHandle.USER_ALL); } @Override @@ -188,16 +215,16 @@ public abstract class KeyguardPinBasedInputView extends KeyguardAbsKeyInputView } }); - mButton0 = findViewById(R.id.key0); - mButton1 = findViewById(R.id.key1); - mButton2 = findViewById(R.id.key2); - mButton3 = findViewById(R.id.key3); - mButton4 = findViewById(R.id.key4); - mButton5 = findViewById(R.id.key5); - mButton6 = findViewById(R.id.key6); - mButton7 = findViewById(R.id.key7); - mButton8 = findViewById(R.id.key8); - mButton9 = findViewById(R.id.key9); + mButton0 = (NumPadKey) findViewById(R.id.key0); + mButton1 = (NumPadKey) findViewById(R.id.key1); + mButton2 = (NumPadKey) findViewById(R.id.key2); + mButton3 = (NumPadKey) findViewById(R.id.key3); + mButton4 = (NumPadKey) findViewById(R.id.key4); + mButton5 = (NumPadKey) findViewById(R.id.key5); + mButton6 = (NumPadKey) findViewById(R.id.key6); + mButton7 = (NumPadKey) findViewById(R.id.key7); + mButton8 = (NumPadKey) findViewById(R.id.key8); + mButton9 = (NumPadKey) findViewById(R.id.key9); mPasswordEntry.requestFocus(); super.onFinishInflate(); diff --git a/packages/Keyguard/src/com/android/keyguard/NumPadKey.java b/packages/Keyguard/src/com/android/keyguard/NumPadKey.java index d539856..70a4108 100644 --- a/packages/Keyguard/src/com/android/keyguard/NumPadKey.java +++ b/packages/Keyguard/src/com/android/keyguard/NumPadKey.java @@ -22,6 +22,8 @@ import android.graphics.drawable.Drawable; import android.os.Debug; import android.os.PowerManager; import android.os.SystemClock; +import android.os.UserHandle; +import android.provider.Settings; import android.util.AttributeSet; import android.view.HapticFeedbackConstants; import android.view.KeyEvent; @@ -118,7 +120,17 @@ public class NumPadKey extends ViewGroup { } setBackground(mContext.getDrawable(R.drawable.ripple_drawable)); - setContentDescription(mDigitText.getText().toString() + mKlondikeText.getText().toString()); + updateContentDescription(); + } + + public void updateContentDescription() { + if (shouldSpeakPasswordsForAccessibility()) { + setContentDescription( + mDigitText.getText().toString() + mKlondikeText.getText().toString()); + } else { + setContentDescription(getContext().getString( + com.android.internal.R.string.keyboard_password_character_no_headset)); + } } @Override @@ -152,6 +164,15 @@ public class NumPadKey extends ViewGroup { mKlondikeText.layout(left, top, left + mKlondikeText.getMeasuredWidth(), bottom); } + /** + * @return true if the user has explicitly allowed accessibility services + * to speak passwords. + */ + private boolean shouldSpeakPasswordsForAccessibility() { + return (Settings.Secure.getIntForUser(mContext.getContentResolver(), + Settings.Secure.ACCESSIBILITY_SPEAK_PASSWORD, 0, UserHandle.USER_CURRENT) == 1); + } + @Override public boolean hasOverlappingRendering() { return false; diff --git a/packages/SystemUI/res/layout/keyguard_bottom_area.xml b/packages/SystemUI/res/layout/keyguard_bottom_area.xml index ca07c87..4cf4f52d 100644 --- a/packages/SystemUI/res/layout/keyguard_bottom_area.xml +++ b/packages/SystemUI/res/layout/keyguard_bottom_area.xml @@ -29,6 +29,7 @@ android:layout_height="wrap_content" android:layout_marginBottom="@dimen/keyguard_indication_margin_bottom" android:layout_gravity="bottom|center_horizontal" + android:gravity="center_horizontal" android:textStyle="italic" android:textColor="#ffffff" android:textAppearance="?android:attr/textAppearanceSmall" /> diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java index 0faad21..914b3d8 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java @@ -124,6 +124,7 @@ public class NotificationContentView extends FrameLayout { mContractedChild = child; mContractedWrapper = NotificationViewWrapper.wrap(getContext(), child); selectLayout(false /* animate */, true /* force */); + mContractedWrapper.setDark(mDark, false /* animate */, 0 /* delay */); } public void setExpandedChild(View child) { @@ -245,6 +246,7 @@ public class NotificationContentView extends FrameLayout { public void notifyContentUpdated() { selectLayout(false /* animate */, true /* force */); if (mContractedChild != null) { + mContractedWrapper.notifyContentUpdated(); mContractedWrapper.setDark(mDark, false /* animate */, 0 /* delay */); } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationTemplateViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationTemplateViewWrapper.java index 5b6e1cd..fbcba0b 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationTemplateViewWrapper.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationTemplateViewWrapper.java @@ -26,6 +26,7 @@ import android.graphics.ColorMatrix; import android.graphics.ColorMatrixColorFilter; import android.graphics.PorterDuff; import android.graphics.PorterDuffColorFilter; +import android.graphics.drawable.Drawable; import android.view.View; import android.view.animation.AnimationUtils; import android.view.animation.Interpolator; @@ -40,17 +41,18 @@ import com.android.systemui.statusbar.phone.NotificationPanelView; */ public class NotificationTemplateViewWrapper extends NotificationViewWrapper { - private final ViewInvertHelper mInvertHelper; - private final ImageView mIcon; - protected final ImageView mPicture; private final ColorMatrix mGrayscaleColorMatrix = new ColorMatrix(); private final PorterDuffColorFilter mIconColorFilter = new PorterDuffColorFilter( 0, PorterDuff.Mode.SRC_ATOP); private final int mIconDarkAlpha; - private final int mIconBackgroundColor; private final int mIconBackgroundDarkColor; private final Interpolator mLinearOutSlowInInterpolator; + private int mIconBackgroundColor; + private ViewInvertHelper mInvertHelper; + private ImageView mIcon; + protected ImageView mPicture; + protected NotificationTemplateViewWrapper(Context ctx, View view) { super(view); mIconDarkAlpha = ctx.getResources().getInteger(R.integer.doze_small_icon_alpha); @@ -58,12 +60,16 @@ public class NotificationTemplateViewWrapper extends NotificationViewWrapper { ctx.getResources().getColor(R.color.doze_small_icon_background_color); mLinearOutSlowInInterpolator = AnimationUtils.loadInterpolator(ctx, android.R.interpolator.linear_out_slow_in); - View mainColumn = view.findViewById(com.android.internal.R.id.notification_main_column); + resolveViews(); + } + + private void resolveViews() { + View mainColumn = mView.findViewById(com.android.internal.R.id.notification_main_column); mInvertHelper = mainColumn != null ? new ViewInvertHelper(mainColumn, NotificationPanelView.DOZE_ANIMATION_DURATION) : null; - ImageView largeIcon = (ImageView) view.findViewById(com.android.internal.R.id.icon); - ImageView rightIcon = (ImageView) view.findViewById(com.android.internal.R.id.right_icon); + ImageView largeIcon = (ImageView) mView.findViewById(com.android.internal.R.id.icon); + ImageView rightIcon = (ImageView) mView.findViewById(com.android.internal.R.id.right_icon); mIcon = resolveIcon(largeIcon, rightIcon); mPicture = resolvePicture(largeIcon); mIconBackgroundColor = resolveBackgroundColor(mIcon); @@ -92,6 +98,14 @@ public class NotificationTemplateViewWrapper extends NotificationViewWrapper { } @Override + public void notifyContentUpdated() { + super.notifyContentUpdated(); + + // Reinspect the notification. + resolveViews(); + } + + @Override public void setDark(boolean dark, boolean fade, long delay) { if (mInvertHelper != null) { if (fade) { @@ -180,7 +194,13 @@ public class NotificationTemplateViewWrapper extends NotificationViewWrapper { private void updateIconColorFilter(ImageView target, float intensity) { int color = interpolateColor(mIconBackgroundColor, mIconBackgroundDarkColor, intensity); mIconColorFilter.setColor(color); - target.getBackground().mutate().setColorFilter(mIconColorFilter); + Drawable background = target.getBackground(); + + // The notification might have been modified during the animation, so background might be + // null here. + if (background != null) { + background.mutate().setColorFilter(mIconColorFilter); + } } private void updateIconAlpha(ImageView target, boolean dark) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewWrapper.java index 0a02573..78b9739 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewWrapper.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewWrapper.java @@ -53,4 +53,9 @@ public abstract class NotificationViewWrapper { * @param delay if fading, the delay of the animation */ public abstract void setDark(boolean dark, boolean fade, long delay); + + /** + * Notifies this wrapper that the content of the view might have changed. + */ + public void notifyContentUpdated() {} } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java b/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java index 8e50abe..8e35ee9 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java @@ -277,9 +277,13 @@ public class SignalClusterView mWifiStrengthId)); boolean anyMobileVisible = false; + int firstMobileTypeId = 0; for (PhoneState state : mPhoneStates) { if (state.apply(anyMobileVisible)) { - anyMobileVisible = true; + if (!anyMobileVisible) { + firstMobileTypeId = state.mMobileTypeId; + anyMobileVisible = true; + } } } @@ -298,7 +302,7 @@ public class SignalClusterView mWifiAirplaneSpacer.setVisibility(View.GONE); } - if ((anyMobileVisible || mNoSimsVisible) && mWifiVisible) { + if (((anyMobileVisible && firstMobileTypeId != 0) || mNoSimsVisible) && mWifiVisible) { mWifiSignalSpacer.setVisibility(View.VISIBLE); } else { mWifiSignalSpacer.setVisibility(View.GONE); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileDataControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileDataControllerImpl.java index 30da9cb..af51266 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileDataControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileDataControllerImpl.java @@ -196,6 +196,7 @@ public class MobileDataControllerImpl implements NetworkController.MobileDataCon } public void setMobileDataEnabled(boolean enabled) { + Log.d(TAG, "setMobileDataEnabled: enabled=" + enabled); mTelephonyManager.setDataEnabled(enabled); if (mCallback != null) { mCallback.onMobileDataEnabled(enabled); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java index 6431ab5..3397a38 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java @@ -272,7 +272,7 @@ public class NetworkControllerImpl extends BroadcastReceiver if (mMobileSignalControllers.containsKey(dataSubId)) { return mMobileSignalControllers.get(dataSubId); } - Log.e(TAG, "Cannot find controller for data sub: " + dataSubId); + if (DEBUG) Log.e(TAG, "Cannot find controller for data sub: " + dataSubId); return mDefaultSignalController; } @@ -293,7 +293,7 @@ public class NetworkControllerImpl extends BroadcastReceiver if (mMobileSignalControllers.containsKey(voiceSubId)) { return mMobileSignalControllers.get(voiceSubId).isEmergencyOnly(); } - Log.e(TAG, "Cannot find controller for voice sub: " + voiceSubId); + if (DEBUG) Log.e(TAG, "Cannot find controller for voice sub: " + voiceSubId); // Something is wrong, better assume we can't make calls... return true; } @@ -483,6 +483,10 @@ public class NetworkControllerImpl extends BroadcastReceiver cachedControllers.get(key).unregisterListener(); } } + // There may be new MobileSignalControllers around, make sure they get the current + // inet condition and airplane mode. + pushConnectivityToSignals(); + updateAirplaneMode(true /* force */); } private boolean hasCorrectMobileControllers(List<SubscriptionInfo> allSubscriptions) { @@ -577,6 +581,13 @@ public class NetworkControllerImpl extends BroadcastReceiver mBluetoothTethered = mConnectedTransports.get(TRANSPORT_BLUETOOTH); mEthernetConnected = mConnectedTransports.get(TRANSPORT_ETHERNET); + pushConnectivityToSignals(); + } + + /** + * Pushes the current connectivity state to all SignalControllers. + */ + private void pushConnectivityToSignals() { // We want to update all the icons, all at once, for any condition change for (MobileSignalController mobileSignalController : mMobileSignalControllers.values()) { mobileSignalController.setInetCondition( diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java index dde158c..a86d564 100644 --- a/services/core/java/com/android/server/ConnectivityService.java +++ b/services/core/java/com/android/server/ConnectivityService.java @@ -231,6 +231,7 @@ public class ConnectivityService extends IConnectivityManager.Stub private static ConnectivityService sServiceInstance; private INetworkManagementService mNetd; + private INetworkStatsService mStatsService; private INetworkPolicyManager mPolicyManager; private String mCurrentTcpBufferSizes; @@ -630,6 +631,7 @@ public class ConnectivityService extends IConnectivityManager.Stub mContext = checkNotNull(context, "missing Context"); mNetd = checkNotNull(netManager, "missing INetworkManagementService"); + mStatsService = checkNotNull(statsService, "missing INetworkStatsService"); mPolicyManager = checkNotNull(policyManager, "missing INetworkPolicyManager"); mKeyStore = KeyStore.getInstance(); mTelephonyManager = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE); @@ -2166,6 +2168,7 @@ public class ConnectivityService extends IConnectivityManager.Stub if (isDefaultNetwork(nai)) { mDefaultInetConditionPublished = 0; } + notifyIfacesChanged(); notifyNetworkCallbacks(nai, ConnectivityManager.CALLBACK_LOST); nai.networkMonitor.sendMessage(NetworkMonitor.CMD_NETWORK_DISCONNECTED); mNetworkAgentInfos.remove(msg.replyTo); @@ -3660,6 +3663,7 @@ public class ConnectivityService extends IConnectivityManager.Stub if (isDefaultNetwork(networkAgent)) handleApplyDefaultProxy(newLp.getHttpProxy()); // TODO - move this check to cover the whole function if (!Objects.equals(newLp, oldLp)) { + notifyIfacesChanged(); notifyNetworkCallbacks(networkAgent, ConnectivityManager.CALLBACK_IP_CHANGED); } } @@ -4250,6 +4254,7 @@ public class ConnectivityService extends IConnectivityManager.Stub } networkAgent.created = true; updateLinkProperties(networkAgent, null); + notifyIfacesChanged(); notifyNetworkCallbacks(networkAgent, ConnectivityManager.CALLBACK_PRECHECK); networkAgent.networkMonitor.sendMessage(NetworkMonitor.CMD_NETWORK_CONNECTED); if (networkAgent.isVPN()) { @@ -4393,6 +4398,16 @@ public class ConnectivityService extends IConnectivityManager.Stub return "UNKNOWN"; } + /** + * Notify other system services that set of active ifaces has changed. + */ + private void notifyIfacesChanged() { + try { + mStatsService.forceUpdateIfaces(); + } catch (Exception ignored) { + } + } + @Override public boolean addVpnAddress(String address, int prefixLength) { throwIfLockdownEnabled(); diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 4eadff9..0373611 100755 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -1075,6 +1075,13 @@ public final class ActivityManagerService extends ActivityManagerNative */ boolean mSafeMode; + /** + * If true, we are running under a test environment so will sample PSS from processes + * much more rapidly to try to collect better data when the tests are rapidly + * running through apps. + */ + boolean mTestPssMode = false; + String mDebugApp = null; boolean mWaitForDebugger = false; boolean mDebugTransient = false; @@ -1091,6 +1098,8 @@ public final class ActivityManagerService extends ActivityManagerNative int mProfileType = 0; String mOpenGlTraceApp = null; + final long[] mTmpLong = new long[1]; + static class ProcessChangeItem { static final int CHANGE_ACTIVITIES = 1<<0; static final int CHANGE_PROCESS_STATE = 1<<1; @@ -1802,7 +1811,7 @@ public final class ActivityManagerService extends ActivityManagerNative continue; } } - nativeTotalPss += Debug.getPss(st.pid, null); + nativeTotalPss += Debug.getPss(st.pid, null, null); } } memInfo.readMemInfo(); @@ -1815,48 +1824,38 @@ public final class ActivityManagerService extends ActivityManagerNative } } - int i = 0; int num = 0; long[] tmp = new long[1]; do { ProcessRecord proc; int procState; int pid; + long lastPssTime; synchronized (ActivityManagerService.this) { - if (i >= mPendingPssProcesses.size()) { - if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i + if (mPendingPssProcesses.size() <= 0) { + if (mTestPssMode || DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " processes in " + (SystemClock.uptimeMillis()-start) + "ms"); mPendingPssProcesses.clear(); return; } - proc = mPendingPssProcesses.get(i); + proc = mPendingPssProcesses.remove(0); procState = proc.pssProcState; + lastPssTime = proc.lastPssTime; if (proc.thread != null && procState == proc.setProcState) { pid = proc.pid; } else { proc = null; pid = 0; } - i++; } if (proc != null) { - long pss = Debug.getPss(pid, tmp); + long pss = Debug.getPss(pid, tmp, null); synchronized (ActivityManagerService.this) { - if (proc.thread != null && proc.setProcState == procState - && proc.pid == pid) { + if (pss != 0 && proc.thread != null && proc.setProcState == procState + && proc.pid == pid && proc.lastPssTime == lastPssTime) { num++; - proc.lastPssTime = SystemClock.uptimeMillis(); - proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList); - if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString() - + ": " + pss + " lastPss=" + proc.lastPss - + " state=" + ProcessList.makeProcStateString(procState)); - if (proc.initialIdlePss == 0) { - proc.initialIdlePss = pss; - } - proc.lastPss = pss; - if (procState >= ActivityManager.PROCESS_STATE_HOME) { - proc.lastCachedPss = pss; - } + recordPssSample(proc, procState, pss, tmp[0], + SystemClock.uptimeMillis()); } } } @@ -5420,7 +5419,7 @@ public final class ActivityManagerService extends ActivityManagerNative } } long[] tmpUss = new long[1]; - pss[i] = Debug.getPss(pids[i], tmpUss); + pss[i] = Debug.getPss(pids[i], tmpUss, null); if (proc != null) { synchronized (this) { if (proc.thread != null && proc.setAdj == oomAdj) { @@ -10949,7 +10948,7 @@ public final class ActivityManagerService extends ActivityManagerNative proc.notCachedSinceIdle = true; proc.initialIdlePss = 0; proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, - isSleeping(), now); + mTestPssMode, isSleeping(), now); } } @@ -12919,7 +12918,8 @@ public final class ActivityManagerService extends ActivityManagerNative + PowerManagerInternal.wakefulnessToString(mWakefulness)); pw.println(" mSleeping=" + mSleeping + " mLockScreenShown=" + lockScreenShownToString()); - pw.println(" mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice); + pw.println(" mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice + + " mTestPssMode=" + mTestPssMode); } if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient || mOrigWaitForDebugger) { @@ -14014,7 +14014,7 @@ public final class ActivityManagerService extends ActivityManagerNative if (dumpDetails || (!brief && !oomOnly)) { Debug.getMemoryInfo(pid, mi); } else { - mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); + mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null); mi.dalvikPrivateDirty = (int)tmpLong[0]; } ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, @@ -14076,7 +14076,7 @@ public final class ActivityManagerService extends ActivityManagerNative if (dumpDetails || (!brief && !oomOnly)) { Debug.getMemoryInfo(pid, mi); } else { - mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); + mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null); mi.dalvikPrivateDirty = (int)tmpLong[0]; } if (dumpDetails) { @@ -14152,6 +14152,7 @@ public final class ActivityManagerService extends ActivityManagerNative // If we are showing aggregations, also look for native processes to // include so that our aggregations are more accurate. updateCpuStatsNow(); + mi = null; synchronized (mProcessCpuTracker) { final int N = mProcessCpuTracker.countStats(); for (int i=0; i<N; i++) { @@ -14163,7 +14164,7 @@ public final class ActivityManagerService extends ActivityManagerNative if (!brief && !oomOnly) { Debug.getMemoryInfo(st.pid, mi); } else { - mi.nativePss = (int)Debug.getPss(st.pid, tmpLong); + mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null); mi.nativePrivateDirty = (int)tmpLong[0]; } @@ -14354,7 +14355,7 @@ public final class ActivityManagerService extends ActivityManagerNative } private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss, - String name) { + long memtrack, String name) { sb.append(" "); sb.append(ProcessList.makeOomAdjString(oomAdj)); sb.append(' '); @@ -14363,11 +14364,16 @@ public final class ActivityManagerService extends ActivityManagerNative ProcessList.appendRamKb(sb, pss); sb.append(" kB: "); sb.append(name); + if (memtrack > 0) { + sb.append(" ("); + sb.append(memtrack); + sb.append(" kB memtrack)"); + } } private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) { - appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.name); - sb.append(" ("); + appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name); + sb.append(" (pid "); sb.append(mi.pid); sb.append(") "); sb.append(mi.adjType); @@ -14386,17 +14392,19 @@ public final class ActivityManagerService extends ActivityManagerNative infoMap.put(mi.pid, mi); } updateCpuStatsNow(); + long[] memtrackTmp = new long[1]; synchronized (mProcessCpuTracker) { final int N = mProcessCpuTracker.countStats(); for (int i=0; i<N; i++) { ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); if (st.vsize > 0) { - long pss = Debug.getPss(st.pid, null); + long pss = Debug.getPss(st.pid, null, memtrackTmp); if (pss > 0) { if (infoMap.indexOfKey(st.pid) < 0) { ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, ProcessList.NATIVE_ADJ, -1, "native", null); mi.pss = pss; + mi.memtrack = memtrackTmp[0]; memInfos.add(mi); } } @@ -14405,12 +14413,15 @@ public final class ActivityManagerService extends ActivityManagerNative } long totalPss = 0; + long totalMemtrack = 0; for (int i=0, N=memInfos.size(); i<N; i++) { ProcessMemInfo mi = memInfos.get(i); if (mi.pss == 0) { - mi.pss = Debug.getPss(mi.pid, null); + mi.pss = Debug.getPss(mi.pid, null, memtrackTmp); + mi.memtrack = memtrackTmp[0]; } totalPss += mi.pss; + totalMemtrack += mi.memtrack; } Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { @@ -14437,6 +14448,7 @@ public final class ActivityManagerService extends ActivityManagerNative boolean firstLine = true; int lastOomAdj = Integer.MIN_VALUE; long extraNativeRam = 0; + long extraNativeMemtrack = 0; long cachedPss = 0; for (int i=0, N=memInfos.size(); i<N; i++) { ProcessMemInfo mi = memInfos.get(i); @@ -14487,18 +14499,19 @@ public final class ActivityManagerService extends ActivityManagerNative appendMemInfo(fullNativeBuilder, mi); if (mi.oomAdj == ProcessList.NATIVE_ADJ) { - // The short form only has native processes that are >= 1MB. - if (mi.pss >= 1000) { + // The short form only has native processes that are >= 512K. + if (mi.pss >= 512) { appendMemInfo(shortNativeBuilder, mi); } else { extraNativeRam += mi.pss; + extraNativeMemtrack += mi.memtrack; } } else { // Short form has all other details, but if we have collected RAM // from smaller native processes let's dump a summary of that. if (extraNativeRam > 0) { appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ, - -1, extraNativeRam, "(Other native)"); + -1, extraNativeRam, extraNativeMemtrack, "(Other native)"); shortNativeBuilder.append('\n'); extraNativeRam = 0; } @@ -14508,7 +14521,14 @@ public final class ActivityManagerService extends ActivityManagerNative fullJavaBuilder.append(" "); ProcessList.appendRamKb(fullJavaBuilder, totalPss); - fullJavaBuilder.append(" kB: TOTAL\n"); + fullJavaBuilder.append(" kB: TOTAL"); + if (totalMemtrack > 0) { + fullJavaBuilder.append(" ("); + fullJavaBuilder.append(totalMemtrack); + fullJavaBuilder.append(" kB memtrack)"); + } else { + } + fullJavaBuilder.append("\n"); MemInfoReader memInfo = new MemInfoReader(); memInfo.readMemInfo(); @@ -17336,6 +17356,24 @@ public final class ActivityManagerService extends ActivityManagerNative } /** + * Record new PSS sample for a process. + */ + void recordPssSample(ProcessRecord proc, int procState, long pss, long uss, long now) { + proc.lastPssTime = now; + proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList); + if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString() + + ": " + pss + " lastPss=" + proc.lastPss + + " state=" + ProcessList.makeProcStateString(procState)); + if (proc.initialIdlePss == 0) { + proc.initialIdlePss = pss; + } + proc.lastPss = pss; + if (procState >= ActivityManager.PROCESS_STATE_HOME) { + proc.lastCachedPss = pss; + } + } + + /** * Schedule PSS collection of a process. */ void requestPssLocked(ProcessRecord proc, int procState) { @@ -17370,13 +17408,24 @@ public final class ActivityManagerService extends ActivityManagerNative if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { app.pssProcState = app.setProcState; app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, - isSleeping(), now); + mTestPssMode, isSleeping(), now); mPendingPssProcesses.add(app); } } mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); } + public void setTestPssMode(boolean enabled) { + synchronized (this) { + mTestPssMode = enabled; + if (enabled) { + // Whenever we enable the mode, we want to take a snapshot all of current + // process mem use. + requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true); + } + } + } + /** * Ask a given process to GC right now. */ @@ -17673,9 +17722,22 @@ public final class ActivityManagerService extends ActivityManagerNative } if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) { + if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) { + // Experimental code to more aggressively collect pss while + // running test... the problem is that this tends to collect + // the data right when a process is transitioning between process + // states, which well tend to give noisy data. + long start = SystemClock.uptimeMillis(); + long pss = Debug.getPss(app.pid, mTmpLong, null); + recordPssSample(app, app.curProcState, pss, mTmpLong[0], now); + mPendingPssProcesses.remove(app); + Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState + + " to " + app.curProcState + ": " + + (SystemClock.uptimeMillis()-start) + "ms"); + } app.lastStateTime = now; app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, - isSleeping(), now); + mTestPssMode, isSleeping(), now); if (DEBUG_PSS) Slog.d(TAG, "Process state change from " + ProcessList.makeProcStateString(app.setProcState) + " to " + ProcessList.makeProcStateString(app.curProcState) + " next pss in " @@ -17685,7 +17747,7 @@ public final class ActivityManagerService extends ActivityManagerNative && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) { requestPssLocked(app, app.setProcState); app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, - isSleeping(), now); + mTestPssMode, isSleeping(), now); } else if (false && DEBUG_PSS) { Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); } diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java index cdc5134..aa86786 100644 --- a/services/core/java/com/android/server/am/ProcessList.java +++ b/services/core/java/com/android/server/am/ProcessList.java @@ -441,6 +441,18 @@ final class ProcessList { // The amount of time until PSS when a cached process stays in the same state. private static final int PSS_SAME_CACHED_INTERVAL = 30*60*1000; + // The amount of time during testing until PSS when a process first becomes top. + private static final int PSS_TEST_FIRST_TOP_INTERVAL = 3*1000; + + // The amount of time during testing until PSS when a process first goes into the background. + private static final int PSS_TEST_FIRST_BACKGROUND_INTERVAL = 5*1000; + + // The amount of time during testing until PSS when an important process stays in same state. + private static final int PSS_TEST_SAME_IMPORTANT_INTERVAL = 10*1000; + + // The amount of time during testing until PSS when a background process stays in same state. + private static final int PSS_TEST_SAME_BACKGROUND_INTERVAL = 15*1000; + public static final int PROC_MEM_PERSISTENT = 0; public static final int PROC_MEM_TOP = 1; public static final int PROC_MEM_IMPORTANT = 2; @@ -498,16 +510,50 @@ final class ProcessList { PSS_SAME_CACHED_INTERVAL, // ActivityManager.PROCESS_STATE_CACHED_EMPTY }; + private static final long[] sTestFirstAwakePssTimes = new long[] { + PSS_TEST_FIRST_TOP_INTERVAL, // ActivityManager.PROCESS_STATE_PERSISTENT + PSS_TEST_FIRST_TOP_INTERVAL, // ActivityManager.PROCESS_STATE_PERSISTENT_UI + PSS_TEST_FIRST_TOP_INTERVAL, // ActivityManager.PROCESS_STATE_TOP + PSS_TEST_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND + PSS_TEST_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND + PSS_TEST_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_BACKUP + PSS_TEST_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_HEAVY_WEIGHT + PSS_TEST_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_SERVICE + PSS_TEST_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_RECEIVER + PSS_TEST_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_HOME + PSS_TEST_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_LAST_ACTIVITY + PSS_TEST_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY + PSS_TEST_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT + PSS_TEST_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_CACHED_EMPTY + }; + + private static final long[] sTestSameAwakePssTimes = new long[] { + PSS_TEST_SAME_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_PERSISTENT + PSS_TEST_SAME_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_PERSISTENT_UI + PSS_TEST_SAME_IMPORTANT_INTERVAL, // ActivityManager.PROCESS_STATE_TOP + PSS_TEST_SAME_IMPORTANT_INTERVAL, // ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND + PSS_TEST_SAME_IMPORTANT_INTERVAL, // ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND + PSS_TEST_SAME_IMPORTANT_INTERVAL, // ActivityManager.PROCESS_STATE_BACKUP + PSS_TEST_SAME_IMPORTANT_INTERVAL, // ActivityManager.PROCESS_STATE_HEAVY_WEIGHT + PSS_TEST_SAME_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_SERVICE + PSS_TEST_SAME_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_RECEIVER + PSS_TEST_SAME_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_HOME + PSS_TEST_SAME_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_LAST_ACTIVITY + PSS_TEST_SAME_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY + PSS_TEST_SAME_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT + PSS_TEST_SAME_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_CACHED_EMPTY + }; + public static boolean procStatesDifferForMem(int procState1, int procState2) { return sProcStateToProcMem[procState1] != sProcStateToProcMem[procState2]; } - public static long computeNextPssTime(int procState, boolean first, boolean sleeping, - long now) { - final long[] table = sleeping + public static long computeNextPssTime(int procState, boolean first, boolean test, + boolean sleeping, long now) { + final long[] table = test ? (first - ? sFirstAwakePssTimes - : sSameAwakePssTimes) + ? sTestFirstAwakePssTimes + : sTestSameAwakePssTimes) : (first ? sFirstAwakePssTimes : sSameAwakePssTimes); diff --git a/services/core/java/com/android/server/am/ProcessMemInfo.java b/services/core/java/com/android/server/am/ProcessMemInfo.java index c94694e..83d29e2 100644 --- a/services/core/java/com/android/server/am/ProcessMemInfo.java +++ b/services/core/java/com/android/server/am/ProcessMemInfo.java @@ -24,6 +24,7 @@ public class ProcessMemInfo { final String adjType; final String adjReason; long pss; + long memtrack; public ProcessMemInfo(String _name, int _pid, int _oomAdj, int _procState, String _adjType, String _adjReason) { diff --git a/services/core/java/com/android/server/am/ProcessStatsService.java b/services/core/java/com/android/server/am/ProcessStatsService.java index d05910b..55aec65 100644 --- a/services/core/java/com/android/server/am/ProcessStatsService.java +++ b/services/core/java/com/android/server/am/ProcessStatsService.java @@ -583,7 +583,7 @@ public final class ProcessStatsService extends IProcessStats.Stub { pw.println(" [--checkin|-c|--csv] [--csv-screen] [--csv-proc] [--csv-mem]"); pw.println(" [--details] [--full-details] [--current] [--hours N] [--last N]"); pw.println(" [--max N] --active] [--commit] [--reset] [--clear] [--write] [-h]"); - pw.println(" [<package.name>]"); + pw.println(" [--start-testing] [--stop-testing] [<package.name>]"); pw.println(" --checkin: perform a checkin: print and delete old committed states."); pw.println(" -c: print only state in checkin format."); pw.println(" --csv: output data suitable for putting in a spreadsheet."); @@ -603,6 +603,8 @@ public final class ProcessStatsService extends IProcessStats.Stub { pw.println(" --clear: clear all stats; does both --reset and deletes old stats."); pw.println(" --write: write current in-memory stats to disk."); pw.println(" --read: replace current stats with last-written stats."); + pw.println(" --start-testing: clear all stats and starting high frequency pss sampling."); + pw.println(" --stop-testing: stop high frequency pss sampling."); pw.println(" -a: print everything."); pw.println(" -h: print this help text."); pw.println(" <package.name>: optional name of package to filter output by."); @@ -636,6 +638,7 @@ public final class ProcessStatsService extends IProcessStats.Stub { boolean dumpDetails = false; boolean dumpFullDetails = false; boolean dumpAll = false; + boolean quit = false; int aggregateHours = 0; int lastIndex = 0; int maxNum = 2; @@ -761,14 +764,14 @@ public final class ProcessStatsService extends IProcessStats.Stub { mProcessStats.mFlags |= ProcessStats.FLAG_COMPLETE; writeStateLocked(true, true); pw.println("Process stats committed."); + quit = true; } - return; } else if ("--reset".equals(arg)) { synchronized (mAm) { mProcessStats.resetSafely(); pw.println("Process stats reset."); + quit = true; } - return; } else if ("--clear".equals(arg)) { synchronized (mAm) { mProcessStats.resetSafely(); @@ -779,20 +782,32 @@ public final class ProcessStatsService extends IProcessStats.Stub { } } pw.println("All process stats cleared."); + quit = true; } - return; } else if ("--write".equals(arg)) { synchronized (mAm) { writeStateSyncLocked(); pw.println("Process stats written."); + quit = true; } - return; } else if ("--read".equals(arg)) { synchronized (mAm) { readLocked(mProcessStats, mFile); pw.println("Process stats read."); + quit = true; + } + } else if ("--start-testing".equals(arg)) { + synchronized (mAm) { + mAm.setTestPssMode(true); + pw.println("Started high frequency sampling."); + quit = true; + } + } else if ("--stop-testing".equals(arg)) { + synchronized (mAm) { + mAm.setTestPssMode(false); + pw.println("Stopped high frequency sampling."); + quit = true; } - return; } else if ("-h".equals(arg)) { dumpHelp(pw); return; @@ -815,6 +830,10 @@ public final class ProcessStatsService extends IProcessStats.Stub { } } + if (quit) { + return; + } + if (isCsv) { pw.print("Processes running summed over"); if (!csvSepScreenStats) { diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java index d39f2ed..62de534 100644 --- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java +++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java @@ -1332,7 +1332,8 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice { if (old == null) { invokeDeviceEventListener(info, HdmiControlManager.DEVICE_EVENT_ADD_DEVICE); } else if (!old.equals(info)) { - invokeDeviceEventListener(info, HdmiControlManager.DEVICE_EVENT_UPDATE_DEVICE); + invokeDeviceEventListener(old, HdmiControlManager.DEVICE_EVENT_REMOVE_DEVICE); + invokeDeviceEventListener(info, HdmiControlManager.DEVICE_EVENT_ADD_DEVICE); } } diff --git a/services/core/java/com/android/server/net/NetworkStatsService.java b/services/core/java/com/android/server/net/NetworkStatsService.java index 61f9a26..856a076 100644 --- a/services/core/java/com/android/server/net/NetworkStatsService.java +++ b/services/core/java/com/android/server/net/NetworkStatsService.java @@ -26,9 +26,7 @@ import static android.content.Intent.ACTION_UID_REMOVED; import static android.content.Intent.ACTION_USER_REMOVED; import static android.content.Intent.EXTRA_UID; import static android.net.ConnectivityManager.ACTION_TETHER_STATE_CHANGED; -import static android.net.ConnectivityManager.CONNECTIVITY_ACTION_IMMEDIATE; import static android.net.ConnectivityManager.isNetworkTypeMobile; -import static android.net.NetworkIdentity.COMBINE_SUBTYPE_ENABLED; import static android.net.NetworkStats.IFACE_ALL; import static android.net.NetworkStats.SET_ALL; import static android.net.NetworkStats.SET_DEFAULT; @@ -55,8 +53,6 @@ import static android.provider.Settings.Global.NETSTATS_UID_TAG_BUCKET_DURATION; import static android.provider.Settings.Global.NETSTATS_UID_TAG_DELETE_AGE; import static android.provider.Settings.Global.NETSTATS_UID_TAG_PERSIST_BYTES; import static android.provider.Settings.Global.NETSTATS_UID_TAG_ROTATE_AGE; -import static android.telephony.PhoneStateListener.LISTEN_DATA_CONNECTION_STATE; -import static android.telephony.PhoneStateListener.LISTEN_NONE; import static android.text.format.DateUtils.DAY_IN_MILLIS; import static android.text.format.DateUtils.HOUR_IN_MILLIS; import static android.text.format.DateUtils.MINUTE_IN_MILLIS; @@ -102,7 +98,6 @@ import android.os.SystemClock; import android.os.UserHandle; import android.provider.Settings; import android.provider.Settings.Global; -import android.telephony.PhoneStateListener; import android.telephony.TelephonyManager; import android.text.format.DateUtils; import android.util.ArrayMap; @@ -308,10 +303,6 @@ public class NetworkStatsService extends INetworkStatsService.Stub { bootstrapStatsLocked(); } - // watch for network interfaces to be claimed - final IntentFilter connFilter = new IntentFilter(CONNECTIVITY_ACTION_IMMEDIATE); - mContext.registerReceiver(mConnReceiver, connFilter, CONNECTIVITY_INTERNAL, mHandler); - // watch for tethering changes final IntentFilter tetherFilter = new IntentFilter(ACTION_TETHER_STATE_CHANGED); mContext.registerReceiver(mTetherReceiver, tetherFilter, null, mHandler); @@ -338,12 +329,6 @@ public class NetworkStatsService extends INetworkStatsService.Stub { // ignored; service lives in system_server } - // watch for networkType changes that aren't broadcast through - // CONNECTIVITY_ACTION_IMMEDIATE above. - if (!COMBINE_SUBTYPE_ENABLED) { - mTeleManager.listen(mPhoneListener, LISTEN_DATA_CONNECTION_STATE); - } - registerPollAlarmLocked(); registerGlobalAlert(); } @@ -358,16 +343,11 @@ public class NetworkStatsService extends INetworkStatsService.Stub { } private void shutdownLocked() { - mContext.unregisterReceiver(mConnReceiver); mContext.unregisterReceiver(mTetherReceiver); mContext.unregisterReceiver(mPollReceiver); mContext.unregisterReceiver(mRemovedReceiver); mContext.unregisterReceiver(mShutdownReceiver); - if (!COMBINE_SUBTYPE_ENABLED) { - mTeleManager.listen(mPhoneListener, LISTEN_NONE); - } - final long currentTime = mTime.hasCache() ? mTime.currentTimeMillis() : System.currentTimeMillis(); @@ -620,6 +600,19 @@ public class NetworkStatsService extends INetworkStatsService.Stub { } @Override + public void forceUpdateIfaces() { + mContext.enforceCallingOrSelfPermission(READ_NETWORK_USAGE_HISTORY, TAG); + assertBandwidthControlEnabled(); + + final long token = Binder.clearCallingIdentity(); + try { + updateIfaces(); + } finally { + Binder.restoreCallingIdentity(token); + } + } + + @Override public void forceUpdate() { mContext.enforceCallingOrSelfPermission(READ_NETWORK_USAGE_HISTORY, TAG); assertBandwidthControlEnabled(); @@ -676,20 +669,6 @@ public class NetworkStatsService extends INetworkStatsService.Stub { } /** - * Receiver that watches for {@link IConnectivityManager} to claim network - * interfaces. Used to associate {@link TelephonyManager#getSubscriberId()} - * with mobile interfaces. - */ - private BroadcastReceiver mConnReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - // on background handler thread, and verified CONNECTIVITY_INTERNAL - // permission above. - updateIfaces(); - } - }; - - /** * Receiver that watches for {@link Tethering} to claim interface pairs. */ private BroadcastReceiver mTetherReceiver = new BroadcastReceiver() { @@ -784,35 +763,6 @@ public class NetworkStatsService extends INetworkStatsService.Stub { } }; - private int mLastPhoneState = TelephonyManager.DATA_UNKNOWN; - private int mLastPhoneNetworkType = TelephonyManager.NETWORK_TYPE_UNKNOWN; - - /** - * Receiver that watches for {@link TelephonyManager} changes, such as - * transitioning between network types. - */ - private PhoneStateListener mPhoneListener = new PhoneStateListener() { - @Override - public void onDataConnectionStateChanged(int state, int networkType) { - final boolean stateChanged = state != mLastPhoneState; - final boolean networkTypeChanged = networkType != mLastPhoneNetworkType; - - if (networkTypeChanged && !stateChanged) { - // networkType changed without a state change, which means we - // need to roll our own update. delay long enough for - // ConnectivityManager to process. - // TODO: add direct event to ConnectivityService instead of - // relying on this delay. - if (LOGV) Slog.v(TAG, "triggering delayed updateIfaces()"); - mHandler.sendMessageDelayed( - mHandler.obtainMessage(MSG_UPDATE_IFACES), SECOND_IN_MILLIS); - } - - mLastPhoneState = state; - mLastPhoneNetworkType = networkType; - } - }; - private void updateIfaces() { synchronized (mStatsLock) { mWakeLock.acquire(); diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 6f1e851..91637e3 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -10199,13 +10199,13 @@ public class PackageManagerService extends IPackageManager.Stub { // default to original signature matching if (compareSignatures(oldPackage.mSignatures, pkg.mSignatures) != PackageManager.SIGNATURE_MATCH) { - res.setError(INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES, + res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "New package has a different signature: " + pkgName); return; } } else { if(!checkUpgradeKeySetLP(ps, pkg)) { - res.setError(INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES, + res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "New package not signed by keys specified by upgrade-keysets: " + pkgName); return; diff --git a/services/core/java/com/android/server/telecom/TelecomLoaderService.java b/services/core/java/com/android/server/telecom/TelecomLoaderService.java new file mode 100644 index 0000000..64a67fc --- /dev/null +++ b/services/core/java/com/android/server/telecom/TelecomLoaderService.java @@ -0,0 +1,106 @@ +/* + * Copyright (C) 2014 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.server.telecom; + +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.content.ServiceConnection; +import android.os.IBinder; +import android.os.RemoteException; +import android.os.ServiceManager; +import android.os.UserHandle; +import android.util.Slog; + +import com.android.server.SystemService; + +/** + * Starts the telecom component by binding to its ITelecomService implementation. Telecom is setup + * to run in the system-server process so once it is loaded into memory it will stay running. + * @hide + */ +public class TelecomLoaderService extends SystemService { + private static final String TAG = "TelecomLoaderService"; + + private class TelecomServiceConnection implements ServiceConnection { + @Override + public void onServiceConnected(ComponentName name, IBinder service) { + // Normally, we would listen for death here, but since telecom runs in the same process + // as this loader (process="system") thats redundant here. + try { + service.linkToDeath(new IBinder.DeathRecipient() { + @Override + public void binderDied() { + connectToTelecom(); + } + }, 0); + + ServiceManager.addService(Context.TELECOM_SERVICE, service); + } catch (RemoteException e) { + Slog.w(TAG, "Failed linking to death."); + } + } + + @Override + public void onServiceDisconnected(ComponentName name) { + connectToTelecom(); + } + } + + private static final ComponentName SERVICE_COMPONENT = new ComponentName( + "com.android.server.telecom", + "com.android.server.telecom.TelecomService"); + + private static final String SERVICE_ACTION = "com.android.ITelecomService"; + + private final Context mContext; + private TelecomServiceConnection mServiceConnection; + + public TelecomLoaderService(Context context) { + super(context); + mContext = context; + } + + @Override + public void onStart() { + } + + @Override + public void onBootPhase(int phase) { + if (phase == PHASE_ACTIVITY_MANAGER_READY) { + connectToTelecom(); + } + } + + private void connectToTelecom() { + if (mServiceConnection != null) { + // TODO: Is unbinding worth doing or wait for system to rebind? + mContext.unbindService(mServiceConnection); + mServiceConnection = null; + } + + TelecomServiceConnection serviceConnection = new TelecomServiceConnection(); + Intent intent = new Intent(SERVICE_ACTION); + intent.setComponent(SERVICE_COMPONENT); + int flags = Context.BIND_IMPORTANT | Context.BIND_AUTO_CREATE; + + // Bind to Telecom and register the service + if (mContext.bindServiceAsUser(intent, serviceConnection, flags, UserHandle.OWNER)) { + mServiceConnection = serviceConnection; + } + } +} diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index ba89f23..021a6e4 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -617,8 +617,8 @@ final class WindowState implements WindowManagerPolicy.WindowState { mOverscanInsets.set(Math.max(mOverscanFrame.left - mFrame.left, 0), Math.max(mOverscanFrame.top - mFrame.top, 0), - Math.min(mFrame.right - mOverscanFrame.right, 0), - Math.min(mFrame.bottom - mOverscanFrame.bottom, 0)); + Math.max(mFrame.right - mOverscanFrame.right, 0), + Math.max(mFrame.bottom - mOverscanFrame.bottom, 0)); mContentInsets.set(mContentFrame.left - mFrame.left, mContentFrame.top - mFrame.top, diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java index b3a696e..334cdf6 100644 --- a/services/java/com/android/server/SystemServer.java +++ b/services/java/com/android/server/SystemServer.java @@ -89,6 +89,7 @@ import com.android.server.restrictions.RestrictionsManagerService; import com.android.server.search.SearchManagerService; import com.android.server.statusbar.StatusBarManagerService; import com.android.server.storage.DeviceStorageMonitorService; +import com.android.server.telecom.TelecomLoaderService; import com.android.server.trust.TrustManagerService; import com.android.server.tv.TvInputManagerService; import com.android.server.twilight.TwilightService; @@ -428,6 +429,8 @@ public final class SystemServer { Slog.i(TAG, "Scheduling Policy"); ServiceManager.addService("scheduling_policy", new SchedulingPolicyService()); + mSystemServiceManager.startService(TelecomLoaderService.class); + Slog.i(TAG, "Telephony Registry"); telephonyRegistry = new TelephonyRegistry(context); ServiceManager.addService("telephony.registry", telephonyRegistry); diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java index 83bf04f..73e3213 100644 --- a/telephony/java/android/telephony/TelephonyManager.java +++ b/telephony/java/android/telephony/TelephonyManager.java @@ -3509,8 +3509,15 @@ public class TelephonyManager { /** @hide */ @SystemApi public void setDataEnabled(boolean enable) { + setDataEnabled(SubscriptionManager.getDefaultDataSubId(), enable); + } + + /** @hide */ + @SystemApi + public void setDataEnabled(int subId, boolean enable) { try { - getITelephony().setDataEnabled(enable); + Log.d(TAG, "setDataEnabled: enabled=" + enable); + getITelephony().setDataEnabled(subId, enable); } catch (RemoteException e) { Log.e(TAG, "Error calling ITelephony#setDataEnabled", e); } @@ -3519,12 +3526,21 @@ public class TelephonyManager { /** @hide */ @SystemApi public boolean getDataEnabled() { + return getDataEnabled(SubscriptionManager.getDefaultDataSubId()); + } + + /** @hide */ + @SystemApi + public boolean getDataEnabled(int subId) { + boolean retVal; try { - return getITelephony().getDataEnabled(); + retVal = getITelephony().getDataEnabled(subId); } catch (RemoteException e) { Log.e(TAG, "Error calling ITelephony#getDataEnabled", e); + retVal = false; } - return false; + Log.d(TAG, "getDataEnabled: retVal=" + retVal); + return retVal; } /** diff --git a/telephony/java/com/android/ims/internal/IImsCallSession.aidl b/telephony/java/com/android/ims/internal/IImsCallSession.aidl index d1946e3..b1f2d32 100644 --- a/telephony/java/com/android/ims/internal/IImsCallSession.aidl +++ b/telephony/java/com/android/ims/internal/IImsCallSession.aidl @@ -223,6 +223,20 @@ interface IImsCallSession { void sendDtmf(char c, in Message result); /** + * Start a DTMF code. According to <a href="http://tools.ietf.org/html/rfc2833">RFC 2833</a>, + * event 0 ~ 9 maps to decimal value 0 ~ 9, '*' to 10, '#' to 11, event 'A' ~ 'D' to 12 ~ 15, + * and event flash to 16. Currently, event flash is not supported. + * + * @param c the DTMF to send. '0' ~ '9', 'A' ~ 'D', '*', '#' are valid inputs. + */ + void startDtmf(char c); + + /** + * Stop a DTMF code. + */ + void stopDtmf(); + + /** * Sends an USSD message. * * @param ussdMessage USSD message to send diff --git a/telephony/java/com/android/ims/internal/IImsConfig.aidl b/telephony/java/com/android/ims/internal/IImsConfig.aidl index c5ccf5f..c17637c 100644 --- a/telephony/java/com/android/ims/internal/IImsConfig.aidl +++ b/telephony/java/com/android/ims/internal/IImsConfig.aidl @@ -49,22 +49,22 @@ import com.android.ims.ImsConfigListener; */ interface IImsConfig { /** - * Gets the value for ims service/capabilities parameters from the master + * Gets the value for ims service/capabilities parameters from the provisioned * value storage. Synchronous blocking call. * * @param item, as defined in com.android.ims.ImsConfig#ConfigConstants. * @return value in Integer format. */ - int getMasterValue(int item); + int getProvisionedValue(int item); /** - * Gets the value for ims service/capabilities parameters from the master + * Gets the value for ims service/capabilities parameters from the provisioned * value storage. Synchronous blocking call. * * @param item, as defined in com.android.ims.ImsConfig#ConfigConstants. * @return value in String format. */ - String getMasterStringValue(int item); + String getProvisionedStringValue(int item); /** * Sets the value for IMS service/capabilities parameters by the operator device @@ -112,4 +112,12 @@ interface IImsConfig { * @return void */ oneway void setFeatureValue(int feature, int network, int value, ImsConfigListener listener); + + /** + * Gets the value for IMS volte provisioned. + * This should be the same as the operator provisioned value if applies. + * + * @return void + */ + boolean getVolteProvisioned(); } diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl index d19fa2c..4affad8 100644 --- a/telephony/java/com/android/internal/telephony/ITelephony.aidl +++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl @@ -679,14 +679,14 @@ interface ITelephony { * * @param enable true to turn on, else false */ - void setDataEnabled(boolean enable); + void setDataEnabled(int subId, boolean enable); /** * Get the user enabled state of Mobile Data. * * @return true on enabled */ - boolean getDataEnabled(); + boolean getDataEnabled(int subId); /** * Get P-CSCF address from PCO after data connection is established or modified. diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/RevealActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/RevealActivity.java index 256a1d4..1216fc4 100644 --- a/tests/HwAccelerationTest/src/com/android/test/hwui/RevealActivity.java +++ b/tests/HwAccelerationTest/src/com/android/test/hwui/RevealActivity.java @@ -17,12 +17,14 @@ package com.android.test.hwui; import android.animation.Animator; +import android.animation.Animator.AnimatorListener; import android.animation.AnimatorSet; import android.app.Activity; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.os.Bundle; +import android.util.Log; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewAnimationUtils; @@ -37,6 +39,29 @@ public class RevealActivity extends Activity implements OnClickListener { private boolean mShouldBlock; private int mIteration = 0; + private AnimatorListener mListener = new AnimatorListener() { + + @Override + public void onAnimationStart(Animator animation) { + Log.d("Reveal", "onAnimatorStart " + animation); + } + + @Override + public void onAnimationRepeat(Animator animation) { + Log.d("Reveal", "onAnimationRepeat " + animation); + } + + @Override + public void onAnimationEnd(Animator animation) { + Log.d("Reveal", "onAnimationEnd " + animation); + } + + @Override + public void onAnimationCancel(Animator animation) { + Log.d("Reveal", "onAnimationCancel " + animation); + } + }; + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -59,6 +84,8 @@ public class RevealActivity extends Activity implements OnClickListener { Animator animator = ViewAnimationUtils.createCircularReveal(view, view.getWidth() / 2, view.getHeight() / 2, 0, Math.max(view.getWidth(), view.getHeight())); + Log.d("Reveal", "Calling start..."); + animator.addListener(mListener); if (mIteration < 2) { animator.setDuration(DURATION); animator.start(); @@ -66,6 +93,7 @@ public class RevealActivity extends Activity implements OnClickListener { AnimatorSet set = new AnimatorSet(); set.playTogether(animator); set.setDuration(DURATION); + set.addListener(mListener); set.start(); } diff --git a/tools/aapt/Command.cpp b/tools/aapt/Command.cpp index f5f70c5..d23b82e 100644 --- a/tools/aapt/Command.cpp +++ b/tools/aapt/Command.cpp @@ -516,12 +516,10 @@ static void printFeatureGroup(const FeatureGroup& grp, const size_t numFeatures = grp.features.size(); for (size_t i = 0; i < numFeatures; i++) { - if (!grp.features[i]) { - continue; - } + const bool required = grp.features[i]; const String8& featureName = grp.features.keyAt(i); - printf(" uses-feature: name='%s'\n", + printf(" uses-feature%s: name='%s'\n", (required ? "" : "-not-required"), ResTable::normalizeForOutput(featureName.string()).string()); } @@ -1844,7 +1842,7 @@ int doDump(Bundle* bundle) } } - if (!grp.features.isEmpty()) { + if (!grp.features.isEmpty()) { printFeatureGroup(grp); } } |
