Merge "fix array index out of bounds"
diff --git a/api/current.txt b/api/current.txt
index 415ce7c..0ca9875 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -4687,6 +4687,7 @@
method public abstract android.app.FragmentManager.BackStackEntry getBackStackEntryAt(int);
method public abstract int getBackStackEntryCount();
method public abstract android.app.Fragment getFragment(android.os.Bundle, java.lang.String);
+ method public abstract android.app.Fragment getPrimaryNavigationFragment();
method public void invalidateOptionsMenu();
method public abstract boolean isDestroyed();
method public abstract void popBackStack();
@@ -4763,6 +4764,7 @@
method public abstract android.app.FragmentTransaction setBreadCrumbTitle(java.lang.CharSequence);
method public abstract android.app.FragmentTransaction setCustomAnimations(int, int);
method public abstract android.app.FragmentTransaction setCustomAnimations(int, int, int, int);
+ method public abstract android.app.FragmentTransaction setPrimaryNavigationFragment(android.app.Fragment);
method public abstract android.app.FragmentTransaction setTransition(int);
method public abstract android.app.FragmentTransaction setTransitionStyle(int);
method public abstract android.app.FragmentTransaction show(android.app.Fragment);
@@ -9054,6 +9056,7 @@
field public static final java.lang.String CATEGORY_TYPED_OPENABLE = "android.intent.category.TYPED_OPENABLE";
field public static final java.lang.String CATEGORY_UNIT_TEST = "android.intent.category.UNIT_TEST";
field public static final java.lang.String CATEGORY_VOICE = "android.intent.category.VOICE";
+ field public static final java.lang.String CATEGORY_VR_HOME = "android.intent.category.VR_HOME";
field public static final android.os.Parcelable.Creator<android.content.Intent> CREATOR;
field public static final java.lang.String EXTRA_ALARM_COUNT = "android.intent.extra.ALARM_COUNT";
field public static final java.lang.String EXTRA_ALLOW_MULTIPLE = "android.intent.extra.ALLOW_MULTIPLE";
@@ -25571,6 +25574,7 @@
field public java.util.BitSet allowedProtocols;
field public android.net.wifi.WifiEnterpriseConfig enterpriseConfig;
field public boolean hiddenSSID;
+ field public boolean isHomeProviderNetwork;
field public int networkId;
field public java.lang.String preSharedKey;
field public int priority;
@@ -36124,7 +36128,7 @@
method public void deleteNotificationChannel(java.lang.String, java.lang.String);
method public java.util.List<android.app.NotificationChannel> getNotificationChannels(java.lang.String);
method public final android.os.IBinder onBind(android.content.Intent);
- method public abstract android.service.notification.Adjustment onNotificationEnqueued(android.service.notification.StatusBarNotification, int, boolean);
+ method public abstract android.service.notification.Adjustment onNotificationEnqueued(android.service.notification.StatusBarNotification);
method public abstract void onNotificationSnoozedUntilContext(android.service.notification.StatusBarNotification, java.lang.String);
method public final void unsnoozeNotification(java.lang.String);
method public void updateNotificationChannel(java.lang.String, android.app.NotificationChannel);
@@ -44077,8 +44081,8 @@
method public void drawableHotspotChanged(float, float);
method protected void drawableStateChanged();
method public android.view.View findFocus();
- method public final android.view.View findViewById(int);
- method public final android.view.View findViewWithTag(java.lang.Object);
+ method public final <T extends android.view.View> T findViewById(int);
+ method public final <T extends android.view.View> T findViewWithTag(java.lang.Object);
method public void findViewsWithText(java.util.ArrayList<android.view.View>, java.lang.CharSequence, int);
method protected deprecated boolean fitSystemWindows(android.graphics.Rect);
method public android.view.View focusSearch(int);
@@ -44944,8 +44948,8 @@
method public int getPersistentDrawingCache();
method public boolean getTouchscreenBlocksFocus();
method public int indexOfChild(android.view.View);
- method public final void invalidateChild(android.view.View, android.graphics.Rect);
- method public android.view.ViewParent invalidateChildInParent(int[], android.graphics.Rect);
+ method public final deprecated void invalidateChild(android.view.View, android.graphics.Rect);
+ method public deprecated android.view.ViewParent invalidateChildInParent(int[], android.graphics.Rect);
method public deprecated boolean isAlwaysDrawnWithCacheEnabled();
method public deprecated boolean isAnimationCacheEnabled();
method protected boolean isChildrenDrawingOrderEnabled();
@@ -45108,14 +45112,15 @@
method public abstract android.view.ViewParent getParentForAccessibility();
method public abstract int getTextAlignment();
method public abstract int getTextDirection();
- method public abstract void invalidateChild(android.view.View, android.graphics.Rect);
- method public abstract android.view.ViewParent invalidateChildInParent(int[], android.graphics.Rect);
+ method public abstract deprecated void invalidateChild(android.view.View, android.graphics.Rect);
+ method public abstract deprecated android.view.ViewParent invalidateChildInParent(int[], android.graphics.Rect);
method public abstract boolean isLayoutDirectionResolved();
method public abstract boolean isLayoutRequested();
method public abstract boolean isTextAlignmentResolved();
method public abstract boolean isTextDirectionResolved();
method public abstract android.view.View keyboardNavigationClusterSearch(android.view.View, int);
method public abstract void notifySubtreeAccessibilityStateChanged(android.view.View, android.view.View, int);
+ method public default void onDescendantInvalidated(android.view.View, android.view.View);
method public abstract boolean onNestedFling(android.view.View, float, float, boolean);
method public abstract boolean onNestedPreFling(android.view.View, float, float);
method public abstract boolean onNestedPrePerformAccessibilityAction(android.view.View, int, android.os.Bundle);
@@ -49021,8 +49026,6 @@
method public void addHeaderView(android.view.View);
method public boolean areFooterDividersEnabled();
method public boolean areHeaderDividersEnabled();
- method protected android.view.View findViewTraversal(int);
- method protected android.view.View findViewWithTagTraversal(java.lang.Object);
method public android.widget.ListAdapter getAdapter();
method public deprecated long[] getCheckItemIds();
method public android.graphics.drawable.Drawable getDivider();
diff --git a/api/system-current.txt b/api/system-current.txt
index 4c194d7..1311240 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -4847,6 +4847,7 @@
method public abstract android.app.FragmentManager.BackStackEntry getBackStackEntryAt(int);
method public abstract int getBackStackEntryCount();
method public abstract android.app.Fragment getFragment(android.os.Bundle, java.lang.String);
+ method public abstract android.app.Fragment getPrimaryNavigationFragment();
method public void invalidateOptionsMenu();
method public abstract boolean isDestroyed();
method public abstract void popBackStack();
@@ -4923,6 +4924,7 @@
method public abstract android.app.FragmentTransaction setBreadCrumbTitle(java.lang.CharSequence);
method public abstract android.app.FragmentTransaction setCustomAnimations(int, int);
method public abstract android.app.FragmentTransaction setCustomAnimations(int, int, int, int);
+ method public abstract android.app.FragmentTransaction setPrimaryNavigationFragment(android.app.Fragment);
method public abstract android.app.FragmentTransaction setTransition(int);
method public abstract android.app.FragmentTransaction setTransitionStyle(int);
method public abstract android.app.FragmentTransaction show(android.app.Fragment);
@@ -9466,6 +9468,7 @@
field public static final java.lang.String CATEGORY_TYPED_OPENABLE = "android.intent.category.TYPED_OPENABLE";
field public static final java.lang.String CATEGORY_UNIT_TEST = "android.intent.category.UNIT_TEST";
field public static final java.lang.String CATEGORY_VOICE = "android.intent.category.VOICE";
+ field public static final java.lang.String CATEGORY_VR_HOME = "android.intent.category.VR_HOME";
field public static final android.os.Parcelable.Creator<android.content.Intent> CREATOR;
field public static final java.lang.String EXTRA_ALARM_COUNT = "android.intent.extra.ALARM_COUNT";
field public static final java.lang.String EXTRA_ALLOW_MULTIPLE = "android.intent.extra.ALLOW_MULTIPLE";
@@ -28060,6 +28063,7 @@
field public int creatorUid;
field public android.net.wifi.WifiEnterpriseConfig enterpriseConfig;
field public boolean hiddenSSID;
+ field public boolean isHomeProviderNetwork;
field public java.lang.String lastUpdateName;
field public int lastUpdateUid;
field public boolean meteredHint;
@@ -33721,7 +33725,6 @@
method public final void attachBaseContext(android.content.Context);
method public final android.os.IBinder onBind(android.content.Intent);
method public abstract java.util.List<android.content.pm.permission.RuntimePermissionPresentationInfo> onGetAppPermissions(java.lang.String);
- method public abstract java.util.List<android.content.pm.ApplicationInfo> onGetAppsUsingPermissions(boolean);
field public static final java.lang.String SERVICE_INTERFACE = "android.permissionpresenterservice.RuntimePermissionPresenterService";
}
@@ -36829,6 +36832,7 @@
field public static final java.lang.String USE_GOOGLE_MAIL = "use_google_mail";
field public static final java.lang.String WAIT_FOR_DEBUGGER = "wait_for_debugger";
field public static final java.lang.String WEBVIEW_MULTIPROCESS = "webview_multiprocess";
+ field public static final java.lang.String WIFI_BADGING_THRESHOLDS = "wifi_badging_thresholds";
field public static final java.lang.String WIFI_DEVICE_OWNER_CONFIGS_LOCKDOWN = "wifi_device_owner_configs_lockdown";
field public static final java.lang.String WIFI_MAX_DHCP_RETRY_COUNT = "wifi_max_dhcp_retry_count";
field public static final java.lang.String WIFI_MOBILE_DATA_TRANSITION_WAKELOCK_TIMEOUT_MS = "wifi_mobile_data_transition_wakelock_timeout_ms";
@@ -39152,7 +39156,7 @@
method public void deleteNotificationChannel(java.lang.String, java.lang.String);
method public java.util.List<android.app.NotificationChannel> getNotificationChannels(java.lang.String);
method public final android.os.IBinder onBind(android.content.Intent);
- method public abstract android.service.notification.Adjustment onNotificationEnqueued(android.service.notification.StatusBarNotification, int, boolean);
+ method public abstract android.service.notification.Adjustment onNotificationEnqueued(android.service.notification.StatusBarNotification);
method public abstract void onNotificationSnoozedUntilContext(android.service.notification.StatusBarNotification, java.lang.String);
method public final void unsnoozeNotification(java.lang.String);
method public void updateNotificationChannel(java.lang.String, android.app.NotificationChannel);
@@ -47480,8 +47484,8 @@
method public void drawableHotspotChanged(float, float);
method protected void drawableStateChanged();
method public android.view.View findFocus();
- method public final android.view.View findViewById(int);
- method public final android.view.View findViewWithTag(java.lang.Object);
+ method public final <T extends android.view.View> T findViewById(int);
+ method public final <T extends android.view.View> T findViewWithTag(java.lang.Object);
method public void findViewsWithText(java.util.ArrayList<android.view.View>, java.lang.CharSequence, int);
method protected deprecated boolean fitSystemWindows(android.graphics.Rect);
method public android.view.View focusSearch(int);
@@ -48347,8 +48351,8 @@
method public int getPersistentDrawingCache();
method public boolean getTouchscreenBlocksFocus();
method public int indexOfChild(android.view.View);
- method public final void invalidateChild(android.view.View, android.graphics.Rect);
- method public android.view.ViewParent invalidateChildInParent(int[], android.graphics.Rect);
+ method public final deprecated void invalidateChild(android.view.View, android.graphics.Rect);
+ method public deprecated android.view.ViewParent invalidateChildInParent(int[], android.graphics.Rect);
method public deprecated boolean isAlwaysDrawnWithCacheEnabled();
method public deprecated boolean isAnimationCacheEnabled();
method protected boolean isChildrenDrawingOrderEnabled();
@@ -48511,14 +48515,15 @@
method public abstract android.view.ViewParent getParentForAccessibility();
method public abstract int getTextAlignment();
method public abstract int getTextDirection();
- method public abstract void invalidateChild(android.view.View, android.graphics.Rect);
- method public abstract android.view.ViewParent invalidateChildInParent(int[], android.graphics.Rect);
+ method public abstract deprecated void invalidateChild(android.view.View, android.graphics.Rect);
+ method public abstract deprecated android.view.ViewParent invalidateChildInParent(int[], android.graphics.Rect);
method public abstract boolean isLayoutDirectionResolved();
method public abstract boolean isLayoutRequested();
method public abstract boolean isTextAlignmentResolved();
method public abstract boolean isTextDirectionResolved();
method public abstract android.view.View keyboardNavigationClusterSearch(android.view.View, int);
method public abstract void notifySubtreeAccessibilityStateChanged(android.view.View, android.view.View, int);
+ method public default void onDescendantInvalidated(android.view.View, android.view.View);
method public abstract boolean onNestedFling(android.view.View, float, float, boolean);
method public abstract boolean onNestedPreFling(android.view.View, float, float);
method public abstract boolean onNestedPrePerformAccessibilityAction(android.view.View, int, android.os.Bundle);
@@ -52788,8 +52793,6 @@
method public void addHeaderView(android.view.View);
method public boolean areFooterDividersEnabled();
method public boolean areHeaderDividersEnabled();
- method protected android.view.View findViewTraversal(int);
- method protected android.view.View findViewWithTagTraversal(java.lang.Object);
method public android.widget.ListAdapter getAdapter();
method public deprecated long[] getCheckItemIds();
method public android.graphics.drawable.Drawable getDivider();
diff --git a/api/test-current.txt b/api/test-current.txt
index 244bee3..0261629 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -4697,6 +4697,7 @@
method public abstract android.app.FragmentManager.BackStackEntry getBackStackEntryAt(int);
method public abstract int getBackStackEntryCount();
method public abstract android.app.Fragment getFragment(android.os.Bundle, java.lang.String);
+ method public abstract android.app.Fragment getPrimaryNavigationFragment();
method public void invalidateOptionsMenu();
method public abstract boolean isDestroyed();
method public abstract void popBackStack();
@@ -4773,6 +4774,7 @@
method public abstract android.app.FragmentTransaction setBreadCrumbTitle(java.lang.CharSequence);
method public abstract android.app.FragmentTransaction setCustomAnimations(int, int);
method public abstract android.app.FragmentTransaction setCustomAnimations(int, int, int, int);
+ method public abstract android.app.FragmentTransaction setPrimaryNavigationFragment(android.app.Fragment);
method public abstract android.app.FragmentTransaction setTransition(int);
method public abstract android.app.FragmentTransaction setTransitionStyle(int);
method public abstract android.app.FragmentTransaction show(android.app.Fragment);
@@ -9080,6 +9082,7 @@
field public static final java.lang.String CATEGORY_TYPED_OPENABLE = "android.intent.category.TYPED_OPENABLE";
field public static final java.lang.String CATEGORY_UNIT_TEST = "android.intent.category.UNIT_TEST";
field public static final java.lang.String CATEGORY_VOICE = "android.intent.category.VOICE";
+ field public static final java.lang.String CATEGORY_VR_HOME = "android.intent.category.VR_HOME";
field public static final android.os.Parcelable.Creator<android.content.Intent> CREATOR;
field public static final java.lang.String EXTRA_ALARM_COUNT = "android.intent.extra.ALARM_COUNT";
field public static final java.lang.String EXTRA_ALLOW_MULTIPLE = "android.intent.extra.ALLOW_MULTIPLE";
@@ -25663,6 +25666,7 @@
field public java.util.BitSet allowedProtocols;
field public android.net.wifi.WifiEnterpriseConfig enterpriseConfig;
field public boolean hiddenSSID;
+ field public boolean isHomeProviderNetwork;
field public int networkId;
field public java.lang.String preSharedKey;
field public int priority;
@@ -36259,7 +36263,7 @@
method public void deleteNotificationChannel(java.lang.String, java.lang.String);
method public java.util.List<android.app.NotificationChannel> getNotificationChannels(java.lang.String);
method public final android.os.IBinder onBind(android.content.Intent);
- method public abstract android.service.notification.Adjustment onNotificationEnqueued(android.service.notification.StatusBarNotification, int, boolean);
+ method public abstract android.service.notification.Adjustment onNotificationEnqueued(android.service.notification.StatusBarNotification);
method public abstract void onNotificationSnoozedUntilContext(android.service.notification.StatusBarNotification, java.lang.String);
method public final void unsnoozeNotification(java.lang.String);
method public void updateNotificationChannel(java.lang.String, android.app.NotificationChannel);
@@ -44383,8 +44387,8 @@
method public void drawableHotspotChanged(float, float);
method protected void drawableStateChanged();
method public android.view.View findFocus();
- method public final android.view.View findViewById(int);
- method public final android.view.View findViewWithTag(java.lang.Object);
+ method public final <T extends android.view.View> T findViewById(int);
+ method public final <T extends android.view.View> T findViewWithTag(java.lang.Object);
method public void findViewsWithText(java.util.ArrayList<android.view.View>, java.lang.CharSequence, int);
method protected deprecated boolean fitSystemWindows(android.graphics.Rect);
method public android.view.View focusSearch(int);
@@ -45255,8 +45259,8 @@
method public int getPersistentDrawingCache();
method public boolean getTouchscreenBlocksFocus();
method public int indexOfChild(android.view.View);
- method public final void invalidateChild(android.view.View, android.graphics.Rect);
- method public android.view.ViewParent invalidateChildInParent(int[], android.graphics.Rect);
+ method public final deprecated void invalidateChild(android.view.View, android.graphics.Rect);
+ method public deprecated android.view.ViewParent invalidateChildInParent(int[], android.graphics.Rect);
method public deprecated boolean isAlwaysDrawnWithCacheEnabled();
method public deprecated boolean isAnimationCacheEnabled();
method protected boolean isChildrenDrawingOrderEnabled();
@@ -45419,14 +45423,15 @@
method public abstract android.view.ViewParent getParentForAccessibility();
method public abstract int getTextAlignment();
method public abstract int getTextDirection();
- method public abstract void invalidateChild(android.view.View, android.graphics.Rect);
- method public abstract android.view.ViewParent invalidateChildInParent(int[], android.graphics.Rect);
+ method public abstract deprecated void invalidateChild(android.view.View, android.graphics.Rect);
+ method public abstract deprecated android.view.ViewParent invalidateChildInParent(int[], android.graphics.Rect);
method public abstract boolean isLayoutDirectionResolved();
method public abstract boolean isLayoutRequested();
method public abstract boolean isTextAlignmentResolved();
method public abstract boolean isTextDirectionResolved();
method public abstract android.view.View keyboardNavigationClusterSearch(android.view.View, int);
method public abstract void notifySubtreeAccessibilityStateChanged(android.view.View, android.view.View, int);
+ method public default void onDescendantInvalidated(android.view.View, android.view.View);
method public abstract boolean onNestedFling(android.view.View, float, float, boolean);
method public abstract boolean onNestedPreFling(android.view.View, float, float);
method public abstract boolean onNestedPrePerformAccessibilityAction(android.view.View, int, android.os.Bundle);
@@ -49338,8 +49343,6 @@
method public void addHeaderView(android.view.View);
method public boolean areFooterDividersEnabled();
method public boolean areHeaderDividersEnabled();
- method protected android.view.View findViewTraversal(int);
- method protected android.view.View findViewWithTagTraversal(java.lang.Object);
method public android.widget.ListAdapter getAdapter();
method public deprecated long[] getCheckItemIds();
method public android.graphics.drawable.Drawable getDivider();
diff --git a/cmds/screencap/screencap.cpp b/cmds/screencap/screencap.cpp
index 377e29d..000420f 100644
--- a/cmds/screencap/screencap.cpp
+++ b/cmds/screencap/screencap.cpp
@@ -162,7 +162,9 @@
uint8_t displayOrientation = configs[activeConfig].orientation;
uint32_t captureOrientation = ORIENTATION_MAP[displayOrientation];
- status_t result = screenshot.update(display, Rect(), 0, 0, 0, -1U,
+ status_t result = screenshot.update(display, Rect(),
+ 0 /* reqWidth */, 0 /* reqHeight */,
+ INT32_MIN, INT32_MAX, /* all layers */
false, captureOrientation);
if (result == NO_ERROR) {
base = screenshot.getPixels();
diff --git a/compiled-classes-phone b/compiled-classes-phone
index ed0a4a6..e4ffaa3 100644
--- a/compiled-classes-phone
+++ b/compiled-classes-phone
@@ -633,6 +633,7 @@
android.bluetooth.BluetoothClass
android.bluetooth.BluetoothClass$1
android.bluetooth.BluetoothCodecConfig
+android.bluetooth.BluetoothCodecStatus
android.bluetooth.BluetoothDevice
android.bluetooth.BluetoothDevice$1
android.bluetooth.BluetoothDevice$2
diff --git a/core/java/android/app/BackStackRecord.java b/core/java/android/app/BackStackRecord.java
index 20a9a93..a27775e 100644
--- a/core/java/android/app/BackStackRecord.java
+++ b/core/java/android/app/BackStackRecord.java
@@ -186,6 +186,8 @@
static final int OP_SHOW = 5;
static final int OP_DETACH = 6;
static final int OP_ATTACH = 7;
+ static final int OP_SET_PRIMARY_NAV = 8;
+ static final int OP_UNSET_PRIMARY_NAV = 9;
static final class Op {
int cmd;
@@ -194,6 +196,14 @@
int exitAnim;
int popEnterAnim;
int popExitAnim;
+
+ Op() {
+ }
+
+ Op(int cmd, Fragment fragment) {
+ this.cmd = cmd;
+ this.fragment = fragment;
+ }
}
ArrayList<Op> mOps = new ArrayList<>();
@@ -318,6 +328,13 @@
case OP_ATTACH:
cmdStr = "ATTACH";
break;
+ case OP_SET_PRIMARY_NAV:
+ cmdStr="SET_PRIMARY_NAV";
+ break;
+ case OP_UNSET_PRIMARY_NAV:
+ cmdStr="UNSET_PRIMARY_NAV";
+ break;
+
default:
cmdStr = "cmd=" + op.cmd;
break;
@@ -438,10 +455,7 @@
fragment.mContainerId = fragment.mFragmentId = containerViewId;
}
- Op op = new Op();
- op.cmd = opcmd;
- op.fragment = fragment;
- addOp(op);
+ addOp(new Op(opcmd, fragment));
}
public FragmentTransaction replace(int containerViewId, Fragment fragment) {
@@ -458,46 +472,37 @@
}
public FragmentTransaction remove(Fragment fragment) {
- Op op = new Op();
- op.cmd = OP_REMOVE;
- op.fragment = fragment;
- addOp(op);
+ addOp(new Op(OP_REMOVE, fragment));
return this;
}
public FragmentTransaction hide(Fragment fragment) {
- Op op = new Op();
- op.cmd = OP_HIDE;
- op.fragment = fragment;
- addOp(op);
+ addOp(new Op(OP_HIDE, fragment));
return this;
}
public FragmentTransaction show(Fragment fragment) {
- Op op = new Op();
- op.cmd = OP_SHOW;
- op.fragment = fragment;
- addOp(op);
+ addOp(new Op(OP_SHOW, fragment));
return this;
}
public FragmentTransaction detach(Fragment fragment) {
- Op op = new Op();
- op.cmd = OP_DETACH;
- op.fragment = fragment;
- addOp(op);
+ addOp(new Op(OP_DETACH, fragment));
return this;
}
public FragmentTransaction attach(Fragment fragment) {
- Op op = new Op();
- op.cmd = OP_ATTACH;
- op.fragment = fragment;
- addOp(op);
+ addOp(new Op(OP_ATTACH, fragment));
+
+ return this;
+ }
+
+ public FragmentTransaction setPrimaryNavigationFragment(Fragment fragment) {
+ addOp(new Op(OP_SET_PRIMARY_NAV, fragment));
return this;
}
@@ -689,7 +694,8 @@
final int numOps = mOps.size();
for (int opNum = 0; opNum < numOps; opNum++) {
final Op op = mOps.get(opNum);
- if (op.fragment.mContainerId == containerId) {
+ final int fragContainer = op.fragment != null ? op.fragment.mContainerId : 0;
+ if (fragContainer != 0 && fragContainer == containerId) {
return true;
}
}
@@ -704,7 +710,7 @@
int lastContainer = -1;
for (int opNum = 0; opNum < numOps; opNum++) {
final Op op = mOps.get(opNum);
- final int container = op.fragment.mContainerId;
+ final int container = op.fragment != null ? op.fragment.mContainerId : 0;
if (container != 0 && container != lastContainer) {
lastContainer = container;
for (int i = startIndex; i < endIndex; i++) {
@@ -712,7 +718,9 @@
final int numThoseOps = record.mOps.size();
for (int thoseOpIndex = 0; thoseOpIndex < numThoseOps; thoseOpIndex++) {
final Op thatOp = record.mOps.get(thoseOpIndex);
- if (thatOp.fragment.mContainerId == container) {
+ final int thatContainer = thatOp.fragment != null
+ ? thatOp.fragment.mContainerId : 0;
+ if (thatContainer == container) {
return true;
}
}
@@ -731,7 +739,9 @@
for (int opNum = 0; opNum < numOps; opNum++) {
final Op op = mOps.get(opNum);
final Fragment f = op.fragment;
- f.setNextTransition(mTransition, mTransitionStyle);
+ if (f != null) {
+ f.setNextTransition(mTransition, mTransitionStyle);
+ }
switch (op.cmd) {
case OP_ADD:
f.setNextAnim(op.enterAnim);
@@ -757,10 +767,16 @@
f.setNextAnim(op.enterAnim);
mManager.attachFragment(f);
break;
+ case OP_SET_PRIMARY_NAV:
+ mManager.setPrimaryNavigationFragment(f);
+ break;
+ case OP_UNSET_PRIMARY_NAV:
+ mManager.setPrimaryNavigationFragment(null);
+ break;
default:
throw new IllegalArgumentException("Unknown cmd: " + op.cmd);
}
- if (!mAllowOptimization && op.cmd != OP_ADD) {
+ if (!mAllowOptimization && op.cmd != OP_ADD && f != null) {
mManager.moveFragmentToExpectedState(f);
}
}
@@ -778,7 +794,10 @@
for (int opNum = mOps.size() - 1; opNum >= 0; opNum--) {
final Op op = mOps.get(opNum);
Fragment f = op.fragment;
- f.setNextTransition(FragmentManagerImpl.reverseTransit(mTransition), mTransitionStyle);
+ if (f != null) {
+ f.setNextTransition(FragmentManagerImpl.reverseTransit(mTransition),
+ mTransitionStyle);
+ }
switch (op.cmd) {
case OP_ADD:
f.setNextAnim(op.popExitAnim);
@@ -804,10 +823,16 @@
f.setNextAnim(op.popExitAnim);
mManager.detachFragment(f);
break;
+ case OP_SET_PRIMARY_NAV:
+ mManager.setPrimaryNavigationFragment(null);
+ break;
+ case OP_UNSET_PRIMARY_NAV:
+ mManager.setPrimaryNavigationFragment(f);
+ break;
default:
throw new IllegalArgumentException("Unknown cmd: " + op.cmd);
}
- if (!mAllowOptimization && op.cmd != OP_REMOVE) {
+ if (!mAllowOptimization && op.cmd != OP_REMOVE && f != null) {
mManager.moveFragmentToExpectedState(f);
}
}
@@ -817,15 +842,28 @@
}
/**
- * Removes all OP_REPLACE ops and replaces them with the proper add and remove
- * operations that are equivalent to the replace. This must be called prior to
- * {@link #executeOps()} or any other call that operations on mOps.
+ * Expands all meta-ops into their more primitive equivalents. This must be called prior to
+ * {@link #executeOps()} or any other call that operations on mOps for forward navigation.
+ * It should not be called for pop/reverse navigation operations.
+ *
+ * <p>Removes all OP_REPLACE ops and replaces them with the proper add and remove
+ * operations that are equivalent to the replace.</p>
+ *
+ * <p>Adds OP_UNSET_PRIMARY_NAV ops to match OP_SET_PRIMARY_NAV, OP_REMOVE and OP_DETACH
+ * ops so that we can restore the old primary nav fragment later. Since callers call this
+ * method in a loop before running ops from several transactions at once, the caller should
+ * pass the return value from this method as the oldPrimaryNav parameter for the next call.
+ * The first call in such a loop should pass the value of
+ * {@link FragmentManager#getPrimaryNavigationFragment()}.</p>
*
* @param added Initialized to the fragments that are in the mManager.mAdded, this
* will be modified to contain the fragments that will be in mAdded
* after the execution ({@link #executeOps()}.
+ * @param oldPrimaryNav The tracked primary navigation fragment as of the beginning of
+ * this set of ops
+ * @return the new oldPrimaryNav fragment after this record's ops would be run
*/
- void expandReplaceOps(ArrayList<Fragment> added) {
+ Fragment expandOps(ArrayList<Fragment> added, Fragment oldPrimaryNav) {
for (int opNum = 0; opNum < mOps.size(); opNum++) {
final Op op = mOps.get(opNum);
switch (op.cmd) {
@@ -834,22 +872,33 @@
added.add(op.fragment);
break;
case OP_REMOVE:
- case OP_DETACH:
+ case OP_DETACH: {
added.remove(op.fragment);
- break;
+ if (op.fragment == oldPrimaryNav) {
+ mOps.add(opNum, new Op(OP_UNSET_PRIMARY_NAV, op.fragment));
+ opNum++;
+ oldPrimaryNav = null;
+ }
+ }
+ break;
case OP_REPLACE: {
- Fragment f = op.fragment;
- int containerId = f.mContainerId;
+ final Fragment f = op.fragment;
+ final int containerId = f.mContainerId;
boolean alreadyAdded = false;
for (int i = added.size() - 1; i >= 0; i--) {
- Fragment old = added.get(i);
+ final Fragment old = added.get(i);
if (old.mContainerId == containerId) {
if (old == f) {
alreadyAdded = true;
} else {
- Op removeOp = new Op();
- removeOp.cmd = OP_REMOVE;
- removeOp.fragment = old;
+ // This is duplicated from above since we only make
+ // a single pass for expanding ops. Unset any outgoing primary nav.
+ if (old == oldPrimaryNav) {
+ mOps.add(opNum, new Op(OP_UNSET_PRIMARY_NAV, old));
+ opNum++;
+ oldPrimaryNav = null;
+ }
+ final Op removeOp = new Op(OP_REMOVE, old);
removeOp.enterAnim = op.enterAnim;
removeOp.popEnterAnim = op.popEnterAnim;
removeOp.exitAnim = op.exitAnim;
@@ -869,8 +918,18 @@
}
}
break;
+ case OP_SET_PRIMARY_NAV: {
+ // It's ok if this is null, that means we will restore to no active
+ // primary navigation fragment on a pop.
+ mOps.add(opNum, new Op(OP_UNSET_PRIMARY_NAV, oldPrimaryNav));
+ opNum++;
+ // Will be set by the OP_SET_PRIMARY_NAV we inserted before when run
+ oldPrimaryNav = op.fragment;
+ }
+ break;
}
}
+ return oldPrimaryNav;
}
/**
@@ -917,8 +976,8 @@
private static boolean isFragmentPostponed(Op op) {
final Fragment fragment = op.fragment;
- return (fragment.mAdded && fragment.mView != null && !fragment.mDetached &&
- !fragment.mHidden && fragment.isPostponed());
+ return fragment != null && fragment.mAdded && fragment.mView != null && !fragment.mDetached
+ && !fragment.mHidden && fragment.isPostponed();
}
public String getName() {
diff --git a/core/java/android/app/FragmentManager.java b/core/java/android/app/FragmentManager.java
index 32cf1c3..b0150bd 100644
--- a/core/java/android/app/FragmentManager.java
+++ b/core/java/android/app/FragmentManager.java
@@ -360,6 +360,18 @@
public abstract void unregisterFragmentLifecycleCallbacks(FragmentLifecycleCallbacks cb);
/**
+ * Return the currently active primary navigation fragment for this FragmentManager.
+ *
+ * <p>The primary navigation fragment's
+ * {@link Fragment#getChildFragmentManager() child FragmentManager} will be called first
+ * to process delegated navigation actions such as {@link #popBackStack()} if no ID
+ * or transaction name is provided to pop to.</p>
+ *
+ * @return the fragment designated as the primary navigation fragment
+ */
+ public abstract Fragment getPrimaryNavigationFragment();
+
+ /**
* Print the FragmentManager's state into the given stream.
*
* @param prefix Text to print at the front of each line.
@@ -524,6 +536,7 @@
FragmentState[] mActive;
int[] mAdded;
BackStackState[] mBackStack;
+ int mPrimaryNavActiveIndex = -1;
public FragmentManagerState() {
}
@@ -532,6 +545,7 @@
mActive = in.createTypedArray(FragmentState.CREATOR);
mAdded = in.createIntArray();
mBackStack = in.createTypedArray(BackStackState.CREATOR);
+ mPrimaryNavActiveIndex = in.readInt();
}
public int describeContents() {
@@ -542,6 +556,7 @@
dest.writeTypedArray(mActive, flags);
dest.writeIntArray(mAdded);
dest.writeTypedArray(mBackStack, flags);
+ dest.writeInt(mPrimaryNavActiveIndex);
}
public static final Parcelable.Creator<FragmentManagerState> CREATOR
@@ -626,6 +641,7 @@
FragmentHostCallback<?> mHost;
FragmentContainer mContainer;
Fragment mParent;
+ Fragment mPrimaryNav;
boolean mNeedMenuInvalidate;
boolean mStateSaved;
@@ -783,6 +799,16 @@
execPendingActions();
ensureExecReady(true);
+ if (mPrimaryNav != null // We have a primary nav fragment
+ && id < 0 // No valid id (since they're local)
+ && name == null) { // no name to pop to (since they're local)
+ final FragmentManager childManager = mPrimaryNav.mChildFragmentManager;
+ if (childManager != null && childManager.popBackStackImmediate()) {
+ // We did something, just not to this specific FragmentManager. Return true.
+ return true;
+ }
+ }
+
boolean executePop = popBackStackState(mTmpRecords, mTmpIsPop, name, id, flags);
if (executePop) {
mExecutingActions = true;
@@ -2038,11 +2064,12 @@
if (mAdded != null) {
mTmpAddedFragments.addAll(mAdded);
}
+ Fragment oldPrimaryNav = getPrimaryNavigationFragment();
for (int recordNum = startIndex; recordNum < endIndex; recordNum++) {
final BackStackRecord record = records.get(recordNum);
final boolean isPop = isRecordPop.get(recordNum);
if (!isPop) {
- record.expandReplaceOps(mTmpAddedFragments);
+ oldPrimaryNav = record.expandOps(mTmpAddedFragments, oldPrimaryNav);
} else {
record.trackAddedFragmentsInPop(mTmpAddedFragments);
}
@@ -2318,20 +2345,20 @@
*/
private boolean generateOpsForPendingActions(ArrayList<BackStackRecord> records,
ArrayList<Boolean> isPop) {
- int numActions;
+ boolean didSomething = false;
synchronized (this) {
if (mPendingActions == null || mPendingActions.size() == 0) {
return false;
}
- numActions = mPendingActions.size();
+ final int numActions = mPendingActions.size();
for (int i = 0; i < numActions; i++) {
- mPendingActions.get(i).generateOps(records, isPop);
+ didSomething |= mPendingActions.get(i).generateOps(records, isPop);
}
mPendingActions.clear();
mHost.getHandler().removeCallbacks(mExecCommit);
}
- return numActions > 0;
+ return didSomething;
}
void doPendingDeferredStart() {
@@ -2618,6 +2645,9 @@
fms.mActive = active;
fms.mAdded = added;
fms.mBackStack = backStack;
+ if (mPrimaryNav != null) {
+ fms.mPrimaryNavActiveIndex = mPrimaryNav.mIndex;
+ }
return fms;
}
@@ -2744,6 +2774,10 @@
} else {
mBackStack = null;
}
+
+ if (fms.mPrimaryNavActiveIndex >= 0) {
+ mPrimaryNav = mActive.get(fms.mPrimaryNavActiveIndex);
+ }
}
public void attachController(FragmentHostCallback<?> host, FragmentContainer container,
@@ -2942,6 +2976,19 @@
}
}
+ public void setPrimaryNavigationFragment(Fragment f) {
+ if (f != null && (f.getFragmentManager() != this || f.mIndex >= mActive.size()
+ || mActive.get(f.mIndex) != f)) {
+ throw new IllegalArgumentException("Fragment " + f
+ + " is not an active fragment of FragmentManager " + this);
+ }
+ mPrimaryNav = f;
+ }
+
+ public Fragment getPrimaryNavigationFragment() {
+ return mPrimaryNav;
+ }
+
public void registerFragmentLifecycleCallbacks(FragmentLifecycleCallbacks cb,
boolean recursive) {
if (mLifecycleCallbacks == null) {
@@ -3386,6 +3433,16 @@
@Override
public boolean generateOps(ArrayList<BackStackRecord> records,
ArrayList<Boolean> isRecordPop) {
+ if (mPrimaryNav != null // We have a primary nav fragment
+ && mId < 0 // No valid id (since they're local)
+ && mName == null) { // no name to pop to (since they're local)
+ final FragmentManager childManager = mPrimaryNav.mChildFragmentManager;
+ if (childManager != null && childManager.popBackStackImmediate()) {
+ // We didn't add any operations for this FragmentManager even though
+ // a child did do work.
+ return false;
+ }
+ }
return popBackStackState(records, isRecordPop, mName, mId, mFlags);
}
}
diff --git a/core/java/android/app/FragmentTransaction.java b/core/java/android/app/FragmentTransaction.java
index 25a7839..07a313c 100644
--- a/core/java/android/app/FragmentTransaction.java
+++ b/core/java/android/app/FragmentTransaction.java
@@ -132,6 +132,24 @@
public abstract FragmentTransaction attach(Fragment fragment);
/**
+ * Set a currently active fragment in this FragmentManager as the primary navigation fragment.
+ *
+ * <p>The primary navigation fragment's
+ * {@link Fragment#getChildFragmentManager() child FragmentManager} will be called first
+ * to process delegated navigation actions such as {@link FragmentManager#popBackStack()}
+ * if no ID or transaction name is provided to pop to. Navigation operations outside of the
+ * fragment system may choose to delegate those actions to the primary navigation fragment
+ * as returned by {@link FragmentManager#getPrimaryNavigationFragment()}.</p>
+ *
+ * <p>The fragment provided must currently be added to the FragmentManager to be set as
+ * a primary navigation fragment, or previously added as part of this transaction.</p>
+ *
+ * @param fragment the fragment to set as the primary navigation fragment
+ * @return the same FragmentTransaction instance
+ */
+ public abstract FragmentTransaction setPrimaryNavigationFragment(Fragment fragment);
+
+ /**
* @return <code>true</code> if this transaction contains no operations,
* <code>false</code> otherwise.
*/
diff --git a/core/java/android/app/FragmentTransition.java b/core/java/android/app/FragmentTransition.java
index 80a5aac..2570d92 100644
--- a/core/java/android/app/FragmentTransition.java
+++ b/core/java/android/app/FragmentTransition.java
@@ -43,14 +43,16 @@
* REPLACE operations have already been replaced by add/remove operations.
*/
private static final int[] INVERSE_OPS = {
- BackStackRecord.OP_NULL, // inverse of OP_NULL (error)
- BackStackRecord.OP_REMOVE, // inverse of OP_ADD
- BackStackRecord.OP_NULL, // inverse of OP_REPLACE (error)
- BackStackRecord.OP_ADD, // inverse of OP_REMOVE
- BackStackRecord.OP_SHOW, // inverse of OP_HIDE
- BackStackRecord.OP_HIDE, // inverse of OP_SHOW
- BackStackRecord.OP_ATTACH, // inverse of OP_DETACH
- BackStackRecord.OP_DETACH, // inverse of OP_ATTACH
+ BackStackRecord.OP_NULL, // inverse of OP_NULL (error)
+ BackStackRecord.OP_REMOVE, // inverse of OP_ADD
+ BackStackRecord.OP_NULL, // inverse of OP_REPLACE (error)
+ BackStackRecord.OP_ADD, // inverse of OP_REMOVE
+ BackStackRecord.OP_SHOW, // inverse of OP_HIDE
+ BackStackRecord.OP_HIDE, // inverse of OP_SHOW
+ BackStackRecord.OP_ATTACH, // inverse of OP_DETACH
+ BackStackRecord.OP_DETACH, // inverse of OP_ATTACH
+ BackStackRecord.OP_UNSET_PRIMARY_NAV, // inverse of OP_SET_PRIMARY_NAV
+ BackStackRecord.OP_SET_PRIMARY_NAV, // inverse of OP_UNSET_PRIMARY_NAV
};
/**
@@ -1232,6 +1234,9 @@
SparseArray<FragmentContainerTransition> transitioningFragments, boolean isPop,
boolean isOptimizedTransaction) {
final Fragment fragment = op.fragment;
+ if (fragment == null) {
+ return; // no fragment, no transition
+ }
final int containerId = fragment.mContainerId;
if (containerId == 0) {
return; // no container, no transition
diff --git a/core/java/android/bluetooth/BluetoothA2dp.java b/core/java/android/bluetooth/BluetoothA2dp.java
index 1ce8007..6e31d80 100644
--- a/core/java/android/bluetooth/BluetoothA2dp.java
+++ b/core/java/android/bluetooth/BluetoothA2dp.java
@@ -106,10 +106,9 @@
* Intent used to broadcast the change in the Audio Codec state of the
* A2DP Source profile.
*
- * <p>This intent will have 3 extras:
+ * <p>This intent will have 2 extras:
* <ul>
- * <li> {@link #EXTRA_CODEC_CONFIG} - The current codec configuration. </li>
- * <li> {@link #EXTRA_PREVIOUS_CODEC_CONFIG} - The previous codec configuration. </li>
+ * <li> {@link BluetoothCodecStatus#EXTRA_CODEC_STATUS} - The codec status. </li>
* <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device if the device is currently
* connected, otherwise it is not included.</li>
* </ul>
@@ -565,24 +564,24 @@
}
/**
- * Gets the current codec configuration.
+ * Gets the current codec status (configuration and capability).
*
- * @return the current codec configuration
+ * @return the current codec status
* @hide
*/
- public BluetoothCodecConfig getCodecConfig() {
- if (DBG) Log.d(TAG, "getCodecConfig");
+ public BluetoothCodecStatus getCodecStatus() {
+ if (DBG) Log.d(TAG, "getCodecStatus");
try {
mServiceLock.readLock().lock();
if (mService != null && isEnabled()) {
- return mService.getCodecConfig();
+ return mService.getCodecStatus();
}
if (mService == null) {
Log.w(TAG, "Proxy not attached to service");
}
return null;
} catch (RemoteException e) {
- Log.e(TAG, "Error talking to BT service in getCodecConfig()", e);
+ Log.e(TAG, "Error talking to BT service in getCodecStatus()", e);
return null;
} finally {
mServiceLock.readLock().unlock();
diff --git a/core/java/android/bluetooth/BluetoothCodecConfig.java b/core/java/android/bluetooth/BluetoothCodecConfig.java
index a37a0b3..a482103 100644
--- a/core/java/android/bluetooth/BluetoothCodecConfig.java
+++ b/core/java/android/bluetooth/BluetoothCodecConfig.java
@@ -29,24 +29,6 @@
* {@hide}
*/
public final class BluetoothCodecConfig implements Parcelable {
-
- /**
- * Extra for the codec configuration intents of the individual profiles.
- *
- * This extra represents the current codec configuration of the A2DP
- * profile.
- */
- public static final String EXTRA_CODEC_CONFIG = "android.bluetooth.codec.extra.CODEC_CONFIG";
-
- /**
- * Extra for the codec configuration intents of the individual profiles.
- *
- * This extra represents the previous codec configuration of the A2DP
- * profile.
- */
- public static final String EXTRA_PREVIOUS_CODEC_CONFIG =
- "android.bluetooth.codec.extra.PREVIOUS_CODEC_CONFIG";
-
// Add an entry for each source codec here.
// NOTE: The values should be same as those listed in the following file:
// hardware/libhardware/include/hardware/bt_av.h
@@ -128,13 +110,93 @@
mCodecSpecific2, mCodecSpecific3, mCodecSpecific4);
}
+ /**
+ * Checks whether the object contains valid codec configuration.
+ *
+ * @return true if the object contains valid codec configuration,
+ * otherwise false.
+ */
+ public boolean isValid() {
+ return (mSampleRate != SAMPLE_RATE_NONE) &&
+ (mBitsPerSample != BITS_PER_SAMPLE_NONE) &&
+ (mChannelMode != CHANNEL_MODE_NONE);
+ }
+
+ /**
+ * Adds capability string to an existing string.
+ *
+ * @param prevStr the previous string with the capabilities. Can be
+ * a null pointer.
+ * @param capStr the capability string to append to prevStr argument.
+ * @return the result string in the form "prevStr|capStr".
+ */
+ private static String appendCapabilityToString(String prevStr,
+ String capStr) {
+ if (prevStr == null) {
+ return capStr;
+ }
+ return prevStr + "|" + capStr;
+ }
+
@Override
public String toString() {
- return "{mCodecType:" + mCodecType +
+ String sampleRateStr = null;
+ if (mSampleRate == SAMPLE_RATE_NONE) {
+ sampleRateStr = appendCapabilityToString(sampleRateStr, "NONE");
+ }
+ if ((mSampleRate & SAMPLE_RATE_44100) != 0) {
+ sampleRateStr = appendCapabilityToString(sampleRateStr, "44100");
+ }
+ if ((mSampleRate & SAMPLE_RATE_48000) != 0) {
+ sampleRateStr = appendCapabilityToString(sampleRateStr, "48000");
+ }
+ if ((mSampleRate & SAMPLE_RATE_88200) != 0) {
+ sampleRateStr = appendCapabilityToString(sampleRateStr, "88200");
+ }
+ if ((mSampleRate & SAMPLE_RATE_96000) != 0) {
+ sampleRateStr = appendCapabilityToString(sampleRateStr, "96000");
+ }
+ if ((mSampleRate & SAMPLE_RATE_176400) != 0) {
+ sampleRateStr = appendCapabilityToString(sampleRateStr, "176400");
+ }
+ if ((mSampleRate & SAMPLE_RATE_192000) != 0) {
+ sampleRateStr = appendCapabilityToString(sampleRateStr, "192000");
+ }
+
+ String bitsPerSampleStr = null;
+ if (mBitsPerSample == BITS_PER_SAMPLE_NONE) {
+ bitsPerSampleStr = appendCapabilityToString(bitsPerSampleStr, "NONE");
+ }
+ if ((mBitsPerSample & BITS_PER_SAMPLE_16) != 0) {
+ bitsPerSampleStr = appendCapabilityToString(bitsPerSampleStr, "16");
+ }
+ if ((mBitsPerSample & BITS_PER_SAMPLE_24) != 0) {
+ bitsPerSampleStr = appendCapabilityToString(bitsPerSampleStr, "24");
+ }
+ if ((mBitsPerSample & BITS_PER_SAMPLE_32) != 0) {
+ bitsPerSampleStr = appendCapabilityToString(bitsPerSampleStr, "32");
+ }
+
+ String channelModeStr = null;
+ if (mChannelMode == CHANNEL_MODE_NONE) {
+ channelModeStr = appendCapabilityToString(channelModeStr, "NONE");
+ }
+ if ((mChannelMode & CHANNEL_MODE_MONO) != 0) {
+ channelModeStr = appendCapabilityToString(channelModeStr, "MONO");
+ }
+ if ((mChannelMode & CHANNEL_MODE_STEREO) != 0) {
+ channelModeStr = appendCapabilityToString(channelModeStr, "STEREO");
+ }
+
+ return "{codecName:" + getCodecName() +
+ ",mCodecType:" + mCodecType +
",mCodecPriority:" + mCodecPriority +
",mSampleRate:" + String.format("0x%x", mSampleRate) +
+ "(" + sampleRateStr + ")" +
",mBitsPerSample:" + String.format("0x%x", mBitsPerSample) +
+ "(" + bitsPerSampleStr + ")" +
",mChannelMode:" + String.format("0x%x", mChannelMode) +
+ "(" + channelModeStr + ")" +
",mCodecSpecific1:" + mCodecSpecific1 +
",mCodecSpecific2:" + mCodecSpecific2 +
",mCodecSpecific3:" + mCodecSpecific3 +
@@ -181,7 +243,32 @@
}
/**
- * Returns the codec type.
+ * Gets the codec name.
+ *
+ * @return the codec name
+ */
+ public String getCodecName() {
+ switch (mCodecType) {
+ case SOURCE_CODEC_TYPE_SBC:
+ return "SBC";
+ case SOURCE_CODEC_TYPE_AAC:
+ return "AAC";
+ case SOURCE_CODEC_TYPE_APTX:
+ return "aptX";
+ case SOURCE_CODEC_TYPE_APTX_HD:
+ return "aptX HD";
+ case SOURCE_CODEC_TYPE_LDAC:
+ return "LDAC";
+ case SOURCE_CODEC_TYPE_INVALID:
+ return "INVALID CODEC";
+ default:
+ break;
+ }
+ return "UNKNOWN CODEC(" + mCodecType + ")";
+ }
+
+ /**
+ * Gets the codec type.
* See {@link android.bluetooth.BluetoothCodecConfig#SOURCE_CODEC_TYPE_SBC}.
*
* @return the codec type
@@ -191,7 +278,7 @@
}
/**
- * Returns the codec selection priority.
+ * Gets the codec selection priority.
* The codec selection priority is relative to other codecs: larger value
* means higher priority. If 0, reset to default.
*
@@ -202,7 +289,7 @@
}
/**
- * Returns the codec sample rate. The value can be a bitmask with all
+ * Gets the codec sample rate. The value can be a bitmask with all
* supported sample rates:
* {@link android.bluetooth.BluetoothCodecConfig#SAMPLE_RATE_NONE} or
* {@link android.bluetooth.BluetoothCodecConfig#SAMPLE_RATE_44100} or
@@ -219,7 +306,7 @@
}
/**
- * Returns the codec bits per sample. The value can be a bitmask with all
+ * Gets the codec bits per sample. The value can be a bitmask with all
* bits per sample supported:
* {@link android.bluetooth.BluetoothCodecConfig#BITS_PER_SAMPLE_NONE} or
* {@link android.bluetooth.BluetoothCodecConfig#BITS_PER_SAMPLE_16} or
@@ -233,7 +320,7 @@
}
/**
- * Returns the codec channel mode. The value can be a bitmask with all
+ * Gets the codec channel mode. The value can be a bitmask with all
* supported channel modes:
* {@link android.bluetooth.BluetoothCodecConfig#CHANNEL_MODE_NONE} or
* {@link android.bluetooth.BluetoothCodecConfig#CHANNEL_MODE_MONO} or
@@ -246,7 +333,7 @@
}
/**
- * Returns a codec specific value1.
+ * Gets a codec specific value1.
*
* @return a codec specific value1.
*/
@@ -255,7 +342,7 @@
}
/**
- * Returns a codec specific value2.
+ * Gets a codec specific value2.
*
* @return a codec specific value2
*/
@@ -264,7 +351,7 @@
}
/**
- * Returns a codec specific value3.
+ * Gets a codec specific value3.
*
* @return a codec specific value3
*/
@@ -273,7 +360,7 @@
}
/**
- * Returns a codec specific value4.
+ * Gets a codec specific value4.
*
* @return a codec specific value4
*/
diff --git a/core/java/android/bluetooth/BluetoothCodecStatus.aidl b/core/java/android/bluetooth/BluetoothCodecStatus.aidl
new file mode 100644
index 0000000..f9c3a3d
--- /dev/null
+++ b/core/java/android/bluetooth/BluetoothCodecStatus.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.bluetooth;
+
+parcelable BluetoothCodecStatus;
diff --git a/core/java/android/bluetooth/BluetoothCodecStatus.java b/core/java/android/bluetooth/BluetoothCodecStatus.java
new file mode 100644
index 0000000..c8cd8d1
--- /dev/null
+++ b/core/java/android/bluetooth/BluetoothCodecStatus.java
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.bluetooth;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.Arrays;
+import java.util.Objects;
+
+/**
+ * Represents the codec status (configuration and capability) for a Bluetooth
+ * A2DP source device.
+ *
+ * {@see BluetoothA2dp}
+ *
+ * {@hide}
+ */
+public final class BluetoothCodecStatus implements Parcelable {
+ /**
+ * Extra for the codec configuration intents of the individual profiles.
+ *
+ * This extra represents the current codec status of the A2DP
+ * profile.
+ */
+ public static final String EXTRA_CODEC_STATUS =
+ "android.bluetooth.codec.extra.CODEC_STATUS";
+
+ private final BluetoothCodecConfig mCodecConfig;
+ private final BluetoothCodecConfig[] mCodecsLocalCapabilities;
+ private final BluetoothCodecConfig[] mCodecsSelectableCapabilities;
+
+ public BluetoothCodecStatus(BluetoothCodecConfig codecConfig,
+ BluetoothCodecConfig[] codecsLocalCapabilities,
+ BluetoothCodecConfig[] codecsSelectableCapabilities) {
+ mCodecConfig = codecConfig;
+ mCodecsLocalCapabilities = codecsLocalCapabilities;
+ mCodecsSelectableCapabilities = codecsSelectableCapabilities;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (o instanceof BluetoothCodecStatus) {
+ BluetoothCodecStatus other = (BluetoothCodecStatus)o;
+ return (Objects.equals(other.mCodecConfig, mCodecConfig) &&
+ Objects.equals(other.mCodecsLocalCapabilities,
+ mCodecsLocalCapabilities) &&
+ Objects.equals(other.mCodecsSelectableCapabilities,
+ mCodecsSelectableCapabilities));
+ }
+ return false;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(mCodecConfig, mCodecsLocalCapabilities,
+ mCodecsLocalCapabilities);
+ }
+
+ @Override
+ public String toString() {
+ return "{mCodecConfig:" + mCodecConfig +
+ ",mCodecsLocalCapabilities:" + Arrays.toString(mCodecsLocalCapabilities) +
+ ",mCodecsSelectableCapabilities:" + Arrays.toString(mCodecsSelectableCapabilities) +
+ "}";
+ }
+
+ public int describeContents() {
+ return 0;
+ }
+
+ public static final Parcelable.Creator<BluetoothCodecStatus> CREATOR =
+ new Parcelable.Creator<BluetoothCodecStatus>() {
+ public BluetoothCodecStatus createFromParcel(Parcel in) {
+ final BluetoothCodecConfig codecConfig = in.readTypedObject(BluetoothCodecConfig.CREATOR);
+ final BluetoothCodecConfig[] codecsLocalCapabilities = in.createTypedArray(BluetoothCodecConfig.CREATOR);
+ final BluetoothCodecConfig[] codecsSelectableCapabilities = in.createTypedArray(BluetoothCodecConfig.CREATOR);
+
+ return new BluetoothCodecStatus(codecConfig,
+ codecsLocalCapabilities,
+ codecsSelectableCapabilities);
+ }
+ public BluetoothCodecStatus[] newArray(int size) {
+ return new BluetoothCodecStatus[size];
+ }
+ };
+
+ public void writeToParcel(Parcel out, int flags) {
+ out.writeTypedObject(mCodecConfig, 0);
+ out.writeTypedArray(mCodecsLocalCapabilities, 0);
+ out.writeTypedArray(mCodecsSelectableCapabilities, 0);
+ }
+
+ /**
+ * Gets the current codec configuration.
+ *
+ * @return the current codec configuration
+ */
+ public BluetoothCodecConfig getCodecConfig() {
+ return mCodecConfig;
+ }
+
+ /**
+ * Gets the codecs local capabilities.
+ *
+ * @return an array with the codecs local capabilities
+ */
+ public BluetoothCodecConfig[] getCodecsLocalCapabilities() {
+ return mCodecsLocalCapabilities;
+ }
+
+ /**
+ * Gets the codecs selectable capabilities.
+ *
+ * @return an array with the codecs selectable capabilities
+ */
+ public BluetoothCodecConfig[] getCodecsSelectableCapabilities() {
+ return mCodecsSelectableCapabilities;
+ }
+}
diff --git a/core/java/android/bluetooth/IBluetoothA2dp.aidl b/core/java/android/bluetooth/IBluetoothA2dp.aidl
index 5b524eb..dbb5b7d 100644
--- a/core/java/android/bluetooth/IBluetoothA2dp.aidl
+++ b/core/java/android/bluetooth/IBluetoothA2dp.aidl
@@ -17,6 +17,7 @@
package android.bluetooth;
import android.bluetooth.BluetoothCodecConfig;
+import android.bluetooth.BluetoothCodecStatus;
import android.bluetooth.BluetoothDevice;
/**
@@ -37,6 +38,6 @@
oneway void adjustAvrcpAbsoluteVolume(int direction);
oneway void setAvrcpAbsoluteVolume(int volume);
boolean isA2dpPlaying(in BluetoothDevice device);
- BluetoothCodecConfig getCodecConfig();
+ BluetoothCodecStatus getCodecStatus();
oneway void setCodecConfigPreference(in BluetoothCodecConfig codecConfig);
}
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 111b4d6..6a0da33 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -569,6 +569,7 @@
* <li> {@link #CATEGORY_HE_DESK_DOCK}
* <li> {@link #CATEGORY_CAR_MODE}
* <li> {@link #CATEGORY_APP_MARKET}
+ * <li> {@link #CATEGORY_VR_HOME}
* </ul>
*
* <h3>Standard Extra Data</h3>
@@ -3643,6 +3644,13 @@
@SdkConstant(SdkConstantType.INTENT_CATEGORY)
public static final String CATEGORY_CAR_MODE = "android.intent.category.CAR_MODE";
+ /**
+ * An activity to use for the launcher when the device is placed in a VR Headset viewer.
+ * Used with {@link #ACTION_MAIN} to launch an activity. For more
+ * information, see {@link android.app.UiModeManager}.
+ */
+ @SdkConstant(SdkConstantType.INTENT_CATEGORY)
+ public static final String CATEGORY_VR_HOME = "android.intent.category.VR_HOME";
// ---------------------------------------------------------------------
// ---------------------------------------------------------------------
// Application launch intent categories (see addCategory()).
diff --git a/core/java/android/content/pm/permission/IRuntimePermissionPresenter.aidl b/core/java/android/content/pm/permission/IRuntimePermissionPresenter.aidl
index 8766508..3c3b84d 100644
--- a/core/java/android/content/pm/permission/IRuntimePermissionPresenter.aidl
+++ b/core/java/android/content/pm/permission/IRuntimePermissionPresenter.aidl
@@ -25,5 +25,4 @@
*/
oneway interface IRuntimePermissionPresenter {
void getAppPermissions(String packageName, in RemoteCallback callback);
- void getAppsUsingPermissions(boolean system, in RemoteCallback callback);
-}
\ No newline at end of file
+}
diff --git a/core/java/android/content/pm/permission/RuntimePermissionPresenter.java b/core/java/android/content/pm/permission/RuntimePermissionPresenter.java
index 2e39926..6d55d2f 100644
--- a/core/java/android/content/pm/permission/RuntimePermissionPresenter.java
+++ b/core/java/android/content/pm/permission/RuntimePermissionPresenter.java
@@ -72,15 +72,6 @@
List<RuntimePermissionPresentationInfo> permissions) {
/* do nothing - stub */
}
-
- /**
- * The result for {@link #getAppsUsingPermissions(boolean, List)}.
- * @param system Whether to return only the system apps or only the non-system ones.
- * @param apps The apps using runtime permissions.
- */
- public void getAppsUsingPermissions(boolean system, @NonNull List<ApplicationInfo> apps) {
- /* do nothing - stub */
- }
}
private static final Object sLock = new Object();
@@ -127,29 +118,6 @@
mRemoteService.processMessage(message);
}
- /**
- * Gets the system apps that use runtime permissions. System apps are ones
- * that are considered system for presentation purposes instead of ones
- * that are preinstalled on the system image. System apps are ones that
- * are on the system image, haven't been updated (a.k.a factory apps)
- * that do not have a launcher icon.
- *
- * @param system If true only system apps are returned otherwise only
- * non-system ones are returned.
- * @param callback Callback to receive the result.
- * @param handler Handler on which to invoke the callback.
- */
- public void getAppsUsingPermissions(boolean system, @NonNull OnResultCallback callback,
- @Nullable Handler handler) {
- SomeArgs args = SomeArgs.obtain();
- args.arg1 = callback;
- args.arg2 = handler;
- args.argi1 = system ? 1 : 0;
- Message message = mRemoteService.obtainMessage(
- RemoteService.MSG_GET_APPS_USING_PERMISSIONS, args);
- mRemoteService.processMessage(message);
- }
-
private static final class RemoteService
extends Handler implements ServiceConnection {
private static final long UNBIND_TIMEOUT_MILLIS = 10000;
@@ -254,51 +222,6 @@
scheduleUnbind();
} break;
- case MSG_GET_APPS_USING_PERMISSIONS: {
- SomeArgs args = (SomeArgs) msg.obj;
- final OnResultCallback callback = (OnResultCallback) args.arg1;
- final Handler handler = (Handler) args.arg2;
- final boolean system = args.argi1 == 1;
- args.recycle();
- final IRuntimePermissionPresenter remoteInstance;
- synchronized (mLock) {
- remoteInstance = mRemoteInstance;
- }
- if (remoteInstance == null) {
- return;
- }
- try {
- remoteInstance.getAppsUsingPermissions(system, new RemoteCallback(
- new RemoteCallback.OnResultListener() {
- @Override
- public void onResult(Bundle result) {
- final List<ApplicationInfo> reportedApps;
- List<ApplicationInfo> apps = null;
- if (result != null) {
- apps = result.getParcelableArrayList(KEY_RESULT);
- }
- if (apps == null) {
- apps = Collections.emptyList();
- }
- reportedApps = apps;
- if (handler != null) {
- handler.post(new Runnable() {
- @Override
- public void run() {
- callback.getAppsUsingPermissions(system, reportedApps);
- }
- });
- } else {
- callback.getAppsUsingPermissions(system, reportedApps);
- }
- }
- }, this));
- } catch (RemoteException re) {
- Log.e(TAG, "Error getting apps using permissions", re);
- }
- scheduleUnbind();
- } break;
-
case MSG_UNBIND: {
synchronized (mLock) {
if (mBound) {
diff --git a/core/java/android/os/RecoverySystem.java b/core/java/android/os/RecoverySystem.java
index a8822c5..ef5bc5c 100644
--- a/core/java/android/os/RecoverySystem.java
+++ b/core/java/android/os/RecoverySystem.java
@@ -623,7 +623,8 @@
final ConditionVariable condition = new ConditionVariable();
Intent intent = new Intent("android.intent.action.MASTER_CLEAR_NOTIFICATION");
- intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
+ intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND
+ | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
context.sendOrderedBroadcastAsUser(intent, UserHandle.SYSTEM,
android.Manifest.permission.MASTER_CLEAR,
new BroadcastReceiver() {
diff --git a/core/java/android/permissionpresenterservice/RuntimePermissionPresenterService.java b/core/java/android/permissionpresenterservice/RuntimePermissionPresenterService.java
index 405be1a..344d947 100644
--- a/core/java/android/permissionpresenterservice/RuntimePermissionPresenterService.java
+++ b/core/java/android/permissionpresenterservice/RuntimePermissionPresenterService.java
@@ -72,14 +72,6 @@
*/
public abstract List<RuntimePermissionPresentationInfo> onGetAppPermissions(String packageName);
- /**
- * Gets the apps that use runtime permissions.
- *
- * @param system Whether to return only the system apps or only the non-system ones.
- * @return The app list.
- */
- public abstract List<ApplicationInfo> onGetAppsUsingPermissions(boolean system);
-
@Override
public final IBinder onBind(Intent intent) {
return new IRuntimePermissionPresenter.Stub() {
@@ -91,12 +83,6 @@
mHandler.obtainMessage(MyHandler.MSG_GET_APP_PERMISSIONS,
args).sendToTarget();
}
-
- @Override
- public void getAppsUsingPermissions(boolean system, RemoteCallback callback) {
- mHandler.obtainMessage(MyHandler.MSG_GET_APPS_USING_PERMISSIONS,
- system ? 1 : 0, 0, callback).sendToTarget();
- }
};
}
@@ -127,19 +113,6 @@
callback.sendResult(null);
}
} break;
-
- case MSG_GET_APPS_USING_PERMISSIONS: {
- RemoteCallback callback = (RemoteCallback) msg.obj;
- final boolean system = msg.arg1 == 1;
- List<ApplicationInfo> apps = onGetAppsUsingPermissions(system);
- if (apps != null && !apps.isEmpty()) {
- Bundle result = new Bundle();
- result.putParcelableList(RuntimePermissionPresenter.KEY_RESULT, apps);
- callback.sendResult(result);
- } else {
- callback.sendResult(null);
- }
- } break;
}
}
}
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 9bc7034..d71ce34 100755
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -8082,6 +8082,17 @@
public static final String NETWORK_AVOID_BAD_WIFI = "network_avoid_bad_wifi";
/**
+ * The thresholds of the wifi throughput badging (SD, HD etc.) as a comma-delimited list of
+ * colon-delimited key-value pairs. The key is the badging enum value defined in
+ * android.net.ScoredNetwork and the value is the minimum sustained network throughput in
+ * kbps required for the badge. For example: "10:3000,20:5000,30:25000"
+ *
+ * @hide
+ */
+ @SystemApi
+ public static final String WIFI_BADGING_THRESHOLDS = "wifi_badging_thresholds";
+
+ /**
* Whether Wifi display is enabled/disabled
* 0=disabled. 1=enabled.
* @hide
diff --git a/core/java/android/service/notification/INotificationListener.aidl b/core/java/android/service/notification/INotificationListener.aidl
index 01d3391..b26e328 100644
--- a/core/java/android/service/notification/INotificationListener.aidl
+++ b/core/java/android/service/notification/INotificationListener.aidl
@@ -34,6 +34,6 @@
void onInterruptionFilterChanged(int interruptionFilter);
// rankers only
- void onNotificationEnqueued(in IStatusBarNotificationHolder notificationHolder, int importance, boolean user);
+ void onNotificationEnqueued(in IStatusBarNotificationHolder notificationHolder);
void onNotificationSnoozedUntilContext(in IStatusBarNotificationHolder notificationHolder, String snoozeCriterionId);
}
diff --git a/core/java/android/service/notification/NotificationAssistantService.java b/core/java/android/service/notification/NotificationAssistantService.java
index cecdbee..de86b2d 100644
--- a/core/java/android/service/notification/NotificationAssistantService.java
+++ b/core/java/android/service/notification/NotificationAssistantService.java
@@ -77,12 +77,9 @@
* A notification was posted by an app. Called before alert.
*
* @param sbn the new notification
- * @param importance the initial importance of the notification.
- * @param user true if the initial importance reflects an explicit user preference.
* @return an adjustment or null to take no action, within 100ms.
*/
- abstract public Adjustment onNotificationEnqueued(StatusBarNotification sbn,
- int importance, boolean user);
+ abstract public Adjustment onNotificationEnqueued(StatusBarNotification sbn);
/**
* Updates a notification. N.B. this won’t cause
@@ -202,8 +199,7 @@
private class NotificationAssistantServiceWrapper extends NotificationListenerWrapper {
@Override
- public void onNotificationEnqueued(IStatusBarNotificationHolder sbnHolder,
- int importance, boolean user) {
+ public void onNotificationEnqueued(IStatusBarNotificationHolder sbnHolder) {
StatusBarNotification sbn;
try {
sbn = sbnHolder.get();
@@ -214,8 +210,6 @@
SomeArgs args = SomeArgs.obtain();
args.arg1 = sbn;
- args.argi1 = importance;
- args.argi2 = user ? 1 : 0;
mHandler.obtainMessage(MyHandler.MSG_ON_NOTIFICATION_ENQUEUED,
args).sendToTarget();
}
@@ -254,10 +248,8 @@
case MSG_ON_NOTIFICATION_ENQUEUED: {
SomeArgs args = (SomeArgs) msg.obj;
StatusBarNotification sbn = (StatusBarNotification) args.arg1;
- final int importance = args.argi1;
- final boolean user = args.argi2 == 1;
args.recycle();
- Adjustment adjustment = onNotificationEnqueued(sbn, importance, user);
+ Adjustment adjustment = onNotificationEnqueued(sbn);
if (adjustment != null) {
if (!isBound()) return;
try {
diff --git a/core/java/android/service/notification/NotificationListenerService.java b/core/java/android/service/notification/NotificationListenerService.java
index 22ad83a..e5abdac 100644
--- a/core/java/android/service/notification/NotificationListenerService.java
+++ b/core/java/android/service/notification/NotificationListenerService.java
@@ -1100,8 +1100,8 @@
}
@Override
- public void onNotificationEnqueued(IStatusBarNotificationHolder notificationHolder,
- int importance, boolean user) throws RemoteException {
+ public void onNotificationEnqueued(IStatusBarNotificationHolder notificationHolder)
+ throws RemoteException {
// no-op in the listener
}
diff --git a/core/java/android/text/SpannableStringInternal.java b/core/java/android/text/SpannableStringInternal.java
index 4b02df86..60d8a0f 100644
--- a/core/java/android/text/SpannableStringInternal.java
+++ b/core/java/android/text/SpannableStringInternal.java
@@ -53,12 +53,16 @@
* @param end End index in the source object.
*/
private final void copySpans(Spanned src, int start, int end) {
- Object[] spans = src.getSpans(start, end, Object.class);
+ final Object[] spans = src.getSpans(start, end, Object.class);
for (int i = 0; i < spans.length; i++) {
+ if (spans[i] instanceof NoCopySpan) {
+ continue;
+ }
+
int st = src.getSpanStart(spans[i]);
int en = src.getSpanEnd(spans[i]);
- int fl = src.getSpanFlags(spans[i]);
+ final int fl = src.getSpanFlags(spans[i]);
if (st < start)
st = start;
@@ -78,33 +82,42 @@
* @param end End index in the source object.
*/
private final void copySpans(SpannableStringInternal src, int start, int end) {
- if (start == 0 && end == src.length()) {
+ int count = 0;
+ boolean includesNoCopySpan = false;
+ final int[] srcData = src.mSpanData;
+ final Object[] srcSpans = src.mSpans;
+ final int limit = src.mSpanCount;
+
+ for (int i = 0; i < limit; i++) {
+ int spanStart = srcData[i * COLUMNS + START];
+ int spanEnd = srcData[i * COLUMNS + END];
+ if (isOutOfCopyRange(start, end, spanStart, spanEnd)) continue;
+ if (srcSpans[i] instanceof NoCopySpan) {
+ includesNoCopySpan = true;
+ continue;
+ }
+ count++;
+ }
+
+ if (count == 0) return;
+
+ if (!includesNoCopySpan && start == 0 && end == src.length()) {
mSpans = ArrayUtils.newUnpaddedObjectArray(src.mSpans.length);
mSpanData = new int[src.mSpanData.length];
mSpanCount = src.mSpanCount;
System.arraycopy(src.mSpans, 0, mSpans, 0, src.mSpans.length);
System.arraycopy(src.mSpanData, 0, mSpanData, 0, mSpanData.length);
} else {
- int count = 0;
- int[] srcData = src.mSpanData;
- int limit = src.mSpanCount;
- for (int i = 0; i < limit; i++) {
- int spanStart = srcData[i * COLUMNS + START];
- int spanEnd = srcData[i * COLUMNS + END];
- if (isOutOfCopyRange(start, end, spanStart, spanEnd)) continue;
- count++;
- }
-
- if (count == 0) return;
-
- Object[] srcSpans = src.mSpans;
mSpanCount = count;
mSpans = ArrayUtils.newUnpaddedObjectArray(mSpanCount);
mSpanData = new int[mSpans.length * COLUMNS];
for (int i = 0, j = 0; i < limit; i++) {
int spanStart = srcData[i * COLUMNS + START];
int spanEnd = srcData[i * COLUMNS + END];
- if (isOutOfCopyRange(start, end, spanStart, spanEnd)) continue;
+ if (isOutOfCopyRange(start, end, spanStart, spanEnd)
+ || srcSpans[i] instanceof NoCopySpan) {
+ continue;
+ }
if (spanStart < start) spanStart = start;
if (spanEnd > end) spanEnd = end;
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 597c051..1292243 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -14384,16 +14384,8 @@
* @hide
*/
protected void damageInParent() {
- final AttachInfo ai = mAttachInfo;
- final ViewParent p = mParent;
- if (p != null && ai != null) {
- final Rect r = ai.mTmpInvalRect;
- r.set(0, 0, mRight - mLeft, mBottom - mTop);
- if (mParent instanceof ViewGroup) {
- ((ViewGroup) mParent).damageChild(this, r);
- } else {
- mParent.invalidateChild(this, r);
- }
+ if (mParent != null && mAttachInfo != null) {
+ mParent.onDescendantInvalidated(this, this);
}
}
@@ -19995,38 +19987,39 @@
}
/**
- * {@hide}
* @param id the id of the view to be found
* @return the view of the specified id, null if cannot be found
+ * @hide
*/
- protected View findViewTraversal(@IdRes int id) {
+ protected <T extends View> T findViewTraversal(@IdRes int id) {
if (id == mID) {
- return this;
+ return (T) this;
}
return null;
}
/**
- * {@hide}
* @param tag the tag of the view to be found
* @return the view of specified tag, null if cannot be found
+ * @hide
*/
- protected View findViewWithTagTraversal(Object tag) {
+ protected <T extends View> T findViewWithTagTraversal(Object tag) {
if (tag != null && tag.equals(mTag)) {
- return this;
+ return (T) this;
}
return null;
}
/**
- * {@hide}
* @param predicate The predicate to evaluate.
* @param childToSkip If not null, ignores this child during the recursive traversal.
* @return The first view that matches the predicate or null.
+ * @hide
*/
- protected View findViewByPredicateTraversal(Predicate<View> predicate, View childToSkip) {
+ protected <T extends View> T findViewByPredicateTraversal(Predicate<View> predicate,
+ View childToSkip) {
if (predicate.apply(this)) {
- return this;
+ return (T) this;
}
return null;
}
@@ -20039,7 +20032,7 @@
* @return The view that has the given id in the hierarchy or null
*/
@Nullable
- public final View findViewById(@IdRes int id) {
+ public final <T extends View> T findViewById(@IdRes int id) {
if (id < 0) {
return null;
}
@@ -20052,11 +20045,11 @@
* @param accessibilityId The searched accessibility id.
* @return The found view.
*/
- final View findViewByAccessibilityId(int accessibilityId) {
+ final <T extends View> T findViewByAccessibilityId(int accessibilityId) {
if (accessibilityId < 0) {
return null;
}
- View view = findViewByAccessibilityIdTraversal(accessibilityId);
+ T view = findViewByAccessibilityIdTraversal(accessibilityId);
if (view != null) {
return view.includeForAccessibility() ? view : null;
}
@@ -20075,12 +20068,11 @@
*
* @param accessibilityId The accessibility id.
* @return The found view.
- *
* @hide
*/
- public View findViewByAccessibilityIdTraversal(int accessibilityId) {
+ public <T extends View> T findViewByAccessibilityIdTraversal(int accessibilityId) {
if (getAccessibilityViewId() == accessibilityId) {
- return this;
+ return (T) this;
}
return null;
}
@@ -20092,7 +20084,7 @@
* @param tag The tag to search for, using "tag.equals(getTag())".
* @return The View that has the given tag in the hierarchy or null
*/
- public final View findViewWithTag(Object tag) {
+ public final <T extends View> T findViewWithTag(Object tag) {
if (tag == null) {
return null;
}
@@ -20100,19 +20092,18 @@
}
/**
- * {@hide}
* Look for a child view that matches the specified predicate.
* If this view matches the predicate, return this view.
*
* @param predicate The predicate to evaluate.
* @return The first view that matches the predicate or null.
+ * @hide
*/
- public final View findViewByPredicate(Predicate<View> predicate) {
+ public final <T extends View> T findViewByPredicate(Predicate<View> predicate) {
return findViewByPredicateTraversal(predicate, null);
}
/**
- * {@hide}
* Look for a child view that matches the specified predicate,
* starting with the specified view and its descendents and then
* recusively searching the ancestors and siblings of that view
@@ -20126,11 +20117,13 @@
* @param start The view to start from.
* @param predicate The predicate to evaluate.
* @return The first view that matches the predicate or null.
+ * @hide
*/
- public final View findViewByPredicateInsideOut(View start, Predicate<View> predicate) {
+ public final <T extends View> T findViewByPredicateInsideOut(
+ View start, Predicate<View> predicate) {
View childToSkip = null;
for (;;) {
- View view = start.findViewByPredicateTraversal(predicate, childToSkip);
+ T view = start.findViewByPredicateTraversal(predicate, childToSkip);
if (view != null || start == this) {
return view;
}
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index b135bef..ab10ac1 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -19,6 +19,7 @@
import static android.os.Build.VERSION_CODES.JELLY_BEAN_MR1;
import android.animation.LayoutTransition;
+import android.annotation.CallSuper;
import android.annotation.IdRes;
import android.annotation.NonNull;
import android.annotation.UiThread;
@@ -4210,9 +4211,9 @@
* {@hide}
*/
@Override
- protected View findViewTraversal(@IdRes int id) {
+ protected <T extends View> T findViewTraversal(@IdRes int id) {
if (id == mID) {
- return this;
+ return (T) this;
}
final View[] where = mChildren;
@@ -4225,7 +4226,7 @@
v = v.findViewById(id);
if (v != null) {
- return v;
+ return (T) v;
}
}
}
@@ -4237,9 +4238,9 @@
* {@hide}
*/
@Override
- protected View findViewWithTagTraversal(Object tag) {
+ protected <T extends View> T findViewWithTagTraversal(Object tag) {
if (tag != null && tag.equals(mTag)) {
- return this;
+ return (T) this;
}
final View[] where = mChildren;
@@ -4252,7 +4253,7 @@
v = v.findViewWithTag(tag);
if (v != null) {
- return v;
+ return (T) v;
}
}
}
@@ -4264,9 +4265,10 @@
* {@hide}
*/
@Override
- protected View findViewByPredicateTraversal(Predicate<View> predicate, View childToSkip) {
+ protected <T extends View> T findViewByPredicateTraversal(Predicate<View> predicate,
+ View childToSkip) {
if (predicate.apply(this)) {
- return this;
+ return (T) this;
}
final View[] where = mChildren;
@@ -4279,7 +4281,7 @@
v = v.findViewByPredicate(predicate);
if (v != null) {
- return v;
+ return (T) v;
}
}
}
@@ -5412,100 +5414,60 @@
}
}
- /**
- * HW-only, Rect-ignoring invalidation path.
- *
- * Returns false if this path was unable to complete successfully. This means
- * it hit a ViewParent it doesn't recognize and needs to fall back to calculating
- * damage area.
- *
- * Hardware acceleration ignores damage rectangles, since native computes damage for everything
- * drawn by HWUI (and SW layer / drawing cache doesn't keep track of damage area).
- *
- * Ignores opaque dirty optimizations, always using the full PFLAG_DIRTY flag.
- *
- * Ignores FLAG_OPTIMIZE_INVALIDATE, since we're not computing a rect,
- * so no point in optimizing that.
- * @hide
- */
- public boolean tryInvalidateChildHardware(View child) {
- final AttachInfo attachInfo = mAttachInfo;
- if (attachInfo == null || !attachInfo.mHardwareAccelerated) {
- return false;
+ @Override
+ @CallSuper
+ public void onDescendantInvalidated(@NonNull View child, @NonNull View target) {
+ /*
+ * HW-only, Rect-ignoring damage codepath
+ *
+ * We don't deal with rectangles here, since RenderThread native code computes damage for
+ * everything drawn by HWUI (and SW layer / drawing cache doesn't keep track of damage area)
+ */
+
+ // if set, combine the animation flag into the parent
+ mPrivateFlags |= (target.mPrivateFlags & PFLAG_DRAW_ANIMATION);
+
+ if ((target.mPrivateFlags & ~PFLAG_DIRTY_MASK) != 0) {
+ // We lazily use PFLAG_DIRTY, since computing opaque isn't worth the potential
+ // optimization in provides in a DisplayList world.
+ mPrivateFlags = (mPrivateFlags & ~PFLAG_DIRTY_MASK) | PFLAG_DIRTY;
+
+ // simplified invalidateChildInParent behavior: clear cache validity to be safe...
+ mPrivateFlags &= ~PFLAG_DRAWING_CACHE_VALID;
}
- // verify it's ViewGroups up to a ViewRootImpl
- ViewRootImpl viewRoot = null;
- ViewParent parent = getParent();
- while (parent != null) {
- if (parent instanceof ViewGroup) {
- parent = parent.getParent();
- } else if (parent instanceof ViewRootImpl) {
- viewRoot = (ViewRootImpl) parent;
- break;
- } else {
- // unknown parent type, abort
- return false;
- }
- }
- if (viewRoot == null) {
- // unable to find ViewRoot
- return false;
+ // ... and mark inval if in software layer that needs to repaint (hw handled in native)
+ if (mLayerType == LAYER_TYPE_SOFTWARE) {
+ // Layered parents should be invalidated. Escalate to a full invalidate (and note that
+ // we do this after consuming any relevant flags from the originating descendant)
+ mPrivateFlags |= PFLAG_INVALIDATED | PFLAG_DIRTY;
+ target = this;
}
- final boolean drawAnimation = (child.mPrivateFlags & PFLAG_DRAW_ANIMATION) != 0;
-
- if (child.mLayerType != LAYER_TYPE_NONE) {
- mPrivateFlags |= PFLAG_INVALIDATED;
+ if (mParent != null) {
+ mParent.onDescendantInvalidated(this, target);
}
-
- parent = this;
- do {
- if (parent != viewRoot) {
- // Note: we cast here without checking isinstance, to avoid cost of isinstance again
- ViewGroup viewGroup = (ViewGroup) parent;
- if (drawAnimation) {
- viewGroup.mPrivateFlags |= PFLAG_DRAW_ANIMATION;
- }
-
- // We lazily use PFLAG_DIRTY, since computing opaque isn't worth the potential
- // optimization in provides in a DisplayList world.
- viewGroup.mPrivateFlags =
- (viewGroup.mPrivateFlags & ~PFLAG_DIRTY_MASK) | PFLAG_DIRTY;
-
- // simplified invalidateChildInParent behavior: clear cache validity to be safe,
- // and mark inval if in layer
- viewGroup.mPrivateFlags &= ~PFLAG_DRAWING_CACHE_VALID;
- if (viewGroup.mLayerType != LAYER_TYPE_NONE) {
- viewGroup.mPrivateFlags |= PFLAG_INVALIDATED;
- }
- } else {
- if (drawAnimation) {
- viewRoot.mIsAnimating = true;
- }
- ((ViewRootImpl) parent).invalidate();
- return true;
- }
-
- parent = parent.getParent();
- } while (parent != null);
- return true;
}
/**
* Don't call or override this method. It is used for the implementation of
* the view hierarchy.
+ *
+ * @deprecated Use {@link #onDescendantInvalidated(View, View)} instead to observe updates to
+ * draw state in descendants.
*/
+ @Deprecated
@Override
public final void invalidateChild(View child, final Rect dirty) {
- if (tryInvalidateChildHardware(child)) {
+ final AttachInfo attachInfo = mAttachInfo;
+ if (attachInfo != null && attachInfo.mHardwareAccelerated) {
+ // HW accelerated fast path
+ onDescendantInvalidated(child, child);
return;
}
ViewParent parent = this;
-
- final AttachInfo attachInfo = mAttachInfo;
if (attachInfo != null) {
// If the child is drawing an animation, we want to copy this flag onto
// ourselves and the parent to make sure the invalidate request goes
@@ -5608,7 +5570,11 @@
* This implementation returns null if this ViewGroup does not have a parent,
* if this ViewGroup is already fully invalidated or if the dirty rectangle
* does not intersect with this ViewGroup's bounds.
+ *
+ * @deprecated Use {@link #onDescendantInvalidated(View, View)} instead to observe updates to
+ * draw state in descendants.
*/
+ @Deprecated
@Override
public ViewParent invalidateChildInParent(final int[] location, final Rect dirty) {
if ((mPrivateFlags & (PFLAG_DRAWN | PFLAG_DRAWING_CACHE_VALID)) != 0) {
@@ -5657,74 +5623,6 @@
}
/**
- * Native-calculated damage path
- * Returns false if this path was unable to complete successfully. This means
- * it hit a ViewParent it doesn't recognize and needs to fall back to calculating
- * damage area
- * @hide
- */
- public boolean damageChildDeferred() {
- ViewParent parent = getParent();
- while (parent != null) {
- if (parent instanceof ViewGroup) {
- parent = parent.getParent();
- } else if (parent instanceof ViewRootImpl) {
- ((ViewRootImpl) parent).invalidate();
- return true;
- } else {
- parent = null;
- }
- }
- return false;
- }
-
- /**
- * Quick invalidation method called by View.invalidateViewProperty. This doesn't set the
- * DRAWN flags and doesn't handle the Animation logic that the default invalidation methods
- * do; all we want to do here is schedule a traversal with the appropriate dirty rect.
- *
- * @hide
- */
- public void damageChild(View child, final Rect dirty) {
- if (damageChildDeferred()) {
- return;
- }
-
- ViewParent parent = this;
-
- final AttachInfo attachInfo = mAttachInfo;
- if (attachInfo != null) {
- int left = child.mLeft;
- int top = child.mTop;
- if (!child.getMatrix().isIdentity()) {
- child.transformRect(dirty);
- }
-
- do {
- if (parent instanceof ViewGroup) {
- ViewGroup parentVG = (ViewGroup) parent;
- if (parentVG.mLayerType != LAYER_TYPE_NONE) {
- // Layered parents should be recreated, not just re-issued
- parentVG.invalidate();
- parent = null;
- } else {
- parent = parentVG.damageChildInParent(left, top, dirty);
- left = parentVG.mLeft;
- top = parentVG.mTop;
- }
- } else {
- // Reached the top; this calls into the usual invalidate method in
- // ViewRootImpl, which schedules a traversal
- final int[] location = attachInfo.mInvalidateChildLocation;
- location[0] = left;
- location[1] = top;
- parent = parent.invalidateChildInParent(location, dirty);
- }
- } while (parent != null);
- }
- }
-
- /**
* Quick invalidation method that simply transforms the dirty rect into the parent's
* coordinate system, pruning the invalidation if the parent has already been invalidated.
*
diff --git a/core/java/android/view/ViewOverlay.java b/core/java/android/view/ViewOverlay.java
index 1676a00..f061370 100644
--- a/core/java/android/view/ViewOverlay.java
+++ b/core/java/android/view/ViewOverlay.java
@@ -328,22 +328,10 @@
}
}
- /**
- * @hide
- */
@Override
- public void damageChild(View child, final Rect dirty) {
- if (mHostView != null) {
- // Note: This is not a "fast" invalidation. Would be nice to instead invalidate
- // using DisplayList properties and a dirty rect instead of causing a real
- // invalidation of the host view
- int left = child.mLeft;
- int top = child.mTop;
- if (!child.getMatrix().isIdentity()) {
- child.transformRect(dirty);
- }
- dirty.offset(left, top);
- mHostView.invalidate(dirty);
+ public void onDescendantInvalidated(@NonNull View child, @NonNull View target) {
+ if (mHostView != null && mHostView.getParent() != null) {
+ mHostView.getParent().onDescendantInvalidated(mHostView, target);
}
}
diff --git a/core/java/android/view/ViewParent.java b/core/java/android/view/ViewParent.java
index 79b05cd..cc11cb8 100644
--- a/core/java/android/view/ViewParent.java
+++ b/core/java/android/view/ViewParent.java
@@ -16,6 +16,7 @@
package android.view;
+import android.annotation.NonNull;
import android.graphics.Rect;
import android.os.Bundle;
import android.view.accessibility.AccessibilityEvent;
@@ -53,12 +54,36 @@
*/
public void requestTransparentRegion(View child);
+
+ /**
+ * The target View has been invalidated, or has had a drawing property changed that
+ * requires the hierarchy to re-render.
+ *
+ * This method is called by the View hierarchy to signal ancestors that a View either needs to
+ * re-record its drawing commands, or drawing properties have changed. This is how Views
+ * schedule a drawing traversal.
+ *
+ * This signal is generally only dispatched for attached Views, since only they need to draw.
+ *
+ * @param child Direct child of this ViewParent containing target
+ * @param target The view that needs to redraw
+ */
+ default void onDescendantInvalidated(@NonNull View child, @NonNull View target) {
+ if (getParent() != null) {
+ // Note: should pass 'this' as default, but can't since we may not be a View
+ getParent().onDescendantInvalidated(child, target);
+ }
+ }
+
/**
* All or part of a child is dirty and needs to be redrawn.
*
* @param child The child which is dirty
* @param r The area within the child that is invalid
+ *
+ * @deprecated Use {@link #onDescendantInvalidated(View, View)} instead.
*/
+ @Deprecated
public void invalidateChild(View child, Rect r);
/**
@@ -80,7 +105,10 @@
* @param r The area within the child that is invalid
*
* @return the parent of this ViewParent or null
+ *
+ * @deprecated Use {@link #onDescendantInvalidated(View, View)} instead.
*/
+ @Deprecated
public ViewParent invalidateChildInParent(int[] location, Rect r);
/**
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index c9b9d5f..9bfc260 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -16,6 +16,7 @@
package android.view;
+import static android.view.View.PFLAG_DRAW_ANIMATION;
import static android.view.WindowCallbacks.RESIZE_MODE_DOCKED_DIVIDER;
import static android.view.WindowCallbacks.RESIZE_MODE_FREEFORM;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_DECOR_VIEW_VISIBILITY;
@@ -1065,6 +1066,14 @@
return mLayoutRequested;
}
+ @Override
+ public void onDescendantInvalidated(@NonNull View child, @NonNull View descendant) {
+ if ((descendant.mPrivateFlags & PFLAG_DRAW_ANIMATION) != 0) {
+ mIsAnimating = true;
+ }
+ invalidate();
+ }
+
void invalidate() {
mDirty.set(0, 0, mWidth, mHeight);
if (!mWillDrawSoon) {
diff --git a/core/java/android/webkit/WebViewClient.java b/core/java/android/webkit/WebViewClient.java
index 8703468..0a73e17d 100644
--- a/core/java/android/webkit/WebViewClient.java
+++ b/core/java/android/webkit/WebViewClient.java
@@ -488,7 +488,8 @@
* @param view The WebView which needs to be cleaned up.
* @param detail the reason why it exited.
* @return true if the host application handled the situation that process has
- * exited, otherwise, application will crash.
+ * exited, otherwise, application will crash if render process crashed,
+ * or be killed if render process was killed by the system.
*/
public boolean onRenderProcessGone(WebView view, RenderProcessGoneDetail detail) {
return false;
diff --git a/core/java/android/widget/ActivityChooserView.java b/core/java/android/widget/ActivityChooserView.java
index 51587a7..9a39a17 100644
--- a/core/java/android/widget/ActivityChooserView.java
+++ b/core/java/android/widget/ActivityChooserView.java
@@ -250,7 +250,7 @@
mDefaultActivityButton = (FrameLayout) findViewById(R.id.default_activity_button);
mDefaultActivityButton.setOnClickListener(mCallbacks);
mDefaultActivityButton.setOnLongClickListener(mCallbacks);
- mDefaultActivityButtonImage = (ImageView) mDefaultActivityButton.findViewById(R.id.image);
+ mDefaultActivityButtonImage = mDefaultActivityButton.findViewById(R.id.image);
final FrameLayout expandButton = (FrameLayout) findViewById(R.id.expand_activities_button);
expandButton.setOnClickListener(mCallbacks);
@@ -282,7 +282,7 @@
mExpandActivityOverflowButton = expandButton;
mExpandActivityOverflowButtonImage =
- (ImageView) expandButton.findViewById(R.id.image);
+ expandButton.findViewById(R.id.image);
mExpandActivityOverflowButtonImage.setImageDrawable(expandActivityOverflowButtonDrawable);
mAdapter = new ActivityChooserViewAdapter();
@@ -760,7 +760,7 @@
convertView = LayoutInflater.from(getContext()).inflate(
R.layout.activity_chooser_view_list_item, parent, false);
convertView.setId(ITEM_VIEW_TYPE_FOOTER);
- TextView titleView = (TextView) convertView.findViewById(R.id.title);
+ TextView titleView = convertView.findViewById(R.id.title);
titleView.setText(mContext.getString(
R.string.activity_chooser_view_see_all));
}
@@ -772,11 +772,11 @@
}
PackageManager packageManager = mContext.getPackageManager();
// Set the icon
- ImageView iconView = (ImageView) convertView.findViewById(R.id.icon);
+ ImageView iconView = convertView.findViewById(R.id.icon);
ResolveInfo activity = (ResolveInfo) getItem(position);
iconView.setImageDrawable(activity.loadIcon(packageManager));
// Set the title.
- TextView titleView = (TextView) convertView.findViewById(R.id.title);
+ TextView titleView = convertView.findViewById(R.id.title);
titleView.setText(activity.loadLabel(packageManager));
// Highlight the default.
if (mShowDefaultActivity && position == 0 && mHighlightDefaultActivity) {
diff --git a/core/java/android/widget/AppSecurityPermissions.java b/core/java/android/widget/AppSecurityPermissions.java
index 68e6809..06d4868 100644
--- a/core/java/android/widget/AppSecurityPermissions.java
+++ b/core/java/android/widget/AppSecurityPermissions.java
@@ -451,7 +451,7 @@
private View getPermissionsView(int which, boolean showRevokeUI) {
LinearLayout permsView = (LinearLayout) mInflater.inflate(R.layout.app_perms_summary, null);
- LinearLayout displayList = (LinearLayout) permsView.findViewById(R.id.perms_list);
+ LinearLayout displayList = permsView.findViewById(R.id.perms_list);
View noPermsView = permsView.findViewById(R.id.no_permissions);
displayPermissions(mPermGroupsList, displayList, which, showRevokeUI);
@@ -517,8 +517,8 @@
CharSequence grpName, CharSequence permList, boolean dangerous, Drawable icon) {
View permView = inflater.inflate(R.layout.app_permission_item_old, null);
- TextView permGrpView = (TextView) permView.findViewById(R.id.permission_group);
- TextView permDescView = (TextView) permView.findViewById(R.id.permission_list);
+ TextView permGrpView = permView.findViewById(R.id.permission_group);
+ TextView permDescView = permView.findViewById(R.id.permission_list);
ImageView imgView = (ImageView)permView.findViewById(R.id.perm_icon);
imgView.setImageDrawable(icon);
diff --git a/core/java/android/widget/ArrayAdapter.java b/core/java/android/widget/ArrayAdapter.java
index bbc50da..81f0d3d 100644
--- a/core/java/android/widget/ArrayAdapter.java
+++ b/core/java/android/widget/ArrayAdapter.java
@@ -388,7 +388,7 @@
text = (TextView) view;
} else {
// Otherwise, find the TextView field within the layout
- text = (TextView) view.findViewById(mFieldId);
+ text = view.findViewById(mFieldId);
if (text == null) {
throw new RuntimeException("Failed to find view with ID "
diff --git a/core/java/android/widget/CalendarViewLegacyDelegate.java b/core/java/android/widget/CalendarViewLegacyDelegate.java
index 557d411..1b899db 100644
--- a/core/java/android/widget/CalendarViewLegacyDelegate.java
+++ b/core/java/android/widget/CalendarViewLegacyDelegate.java
@@ -316,9 +316,9 @@
View content = layoutInflater.inflate(R.layout.calendar_view, null, false);
mDelegator.addView(content);
- mListView = (ListView) mDelegator.findViewById(R.id.list);
- mDayNamesHeader = (ViewGroup) content.findViewById(R.id.day_names);
- mMonthName = (TextView) content.findViewById(R.id.month_name);
+ mListView = mDelegator.findViewById(R.id.list);
+ mDayNamesHeader = content.findViewById(R.id.day_names);
+ mMonthName = content.findViewById(R.id.month_name);
setUpHeader();
setUpListView();
diff --git a/core/java/android/widget/DatePickerCalendarDelegate.java b/core/java/android/widget/DatePickerCalendarDelegate.java
index f712685..907250a 100755
--- a/core/java/android/widget/DatePickerCalendarDelegate.java
+++ b/core/java/android/widget/DatePickerCalendarDelegate.java
@@ -115,10 +115,10 @@
mDelegator.addView(mContainer);
// Set up header views.
- final ViewGroup header = (ViewGroup) mContainer.findViewById(R.id.date_picker_header);
- mHeaderYear = (TextView) header.findViewById(R.id.date_picker_header_year);
+ final ViewGroup header = mContainer.findViewById(R.id.date_picker_header);
+ mHeaderYear = header.findViewById(R.id.date_picker_header_year);
mHeaderYear.setOnClickListener(mOnHeaderClickListener);
- mHeaderMonthDay = (TextView) header.findViewById(R.id.date_picker_header_date);
+ mHeaderMonthDay = header.findViewById(R.id.date_picker_header_date);
mHeaderMonthDay.setOnClickListener(mOnHeaderClickListener);
// For the sake of backwards compatibility, attempt to extract the text
@@ -154,10 +154,10 @@
a.recycle();
// Set up picker container.
- mAnimator = (ViewAnimator) mContainer.findViewById(R.id.animator);
+ mAnimator = mContainer.findViewById(R.id.animator);
// Set up day picker view.
- mDayPickerView = (DayPickerView) mAnimator.findViewById(R.id.date_picker_day_picker);
+ mDayPickerView = mAnimator.findViewById(R.id.date_picker_day_picker);
mDayPickerView.setFirstDayOfWeek(mFirstDayOfWeek);
mDayPickerView.setMinDate(mMinDate.getTimeInMillis());
mDayPickerView.setMaxDate(mMaxDate.getTimeInMillis());
@@ -165,7 +165,7 @@
mDayPickerView.setOnDaySelectedListener(mOnDaySelectedListener);
// Set up year picker view.
- mYearPickerView = (YearPickerView) mAnimator.findViewById(R.id.date_picker_year_picker);
+ mYearPickerView = mAnimator.findViewById(R.id.date_picker_year_picker);
mYearPickerView.setRange(mMinDate, mMaxDate);
mYearPickerView.setYear(mCurrentDate.get(Calendar.YEAR));
mYearPickerView.setOnYearSelectedListener(mOnYearSelectedListener);
diff --git a/core/java/android/widget/DayPickerPagerAdapter.java b/core/java/android/widget/DayPickerPagerAdapter.java
index 8d5bf8f..63621e1 100644
--- a/core/java/android/widget/DayPickerPagerAdapter.java
+++ b/core/java/android/widget/DayPickerPagerAdapter.java
@@ -225,7 +225,7 @@
public Object instantiateItem(ViewGroup container, int position) {
final View itemView = mInflater.inflate(mLayoutResId, container, false);
- final SimpleMonthView v = (SimpleMonthView) itemView.findViewById(mCalendarViewId);
+ final SimpleMonthView v = itemView.findViewById(mCalendarViewId);
v.setOnDayClickListener(mOnDayClickListener);
v.setMonthTextAppearance(mMonthTextAppearance);
v.setDayOfWeekTextAppearance(mDayOfWeekTextAppearance);
diff --git a/core/java/android/widget/DayPickerViewPager.java b/core/java/android/widget/DayPickerViewPager.java
index 94022ae..058baa6 100644
--- a/core/java/android/widget/DayPickerViewPager.java
+++ b/core/java/android/widget/DayPickerViewPager.java
@@ -137,9 +137,10 @@
}
@Override
- protected View findViewByPredicateTraversal(Predicate<View> predicate, View childToSkip) {
+ protected <T extends View> T findViewByPredicateTraversal(Predicate<View> predicate,
+ View childToSkip) {
if (predicate.apply(this)) {
- return this;
+ return (T) this;
}
// Always try the selected view first.
@@ -148,7 +149,7 @@
if (current != childToSkip && current != null) {
final View v = current.findViewByPredicate(predicate);
if (v != null) {
- return v;
+ return (T) v;
}
}
@@ -160,7 +161,7 @@
final View v = child.findViewByPredicate(predicate);
if (v != null) {
- return v;
+ return (T) v;
}
}
}
diff --git a/core/java/android/widget/ListView.java b/core/java/android/widget/ListView.java
index e52c13b..b7da04e 100644
--- a/core/java/android/widget/ListView.java
+++ b/core/java/android/widget/ListView.java
@@ -3735,32 +3735,30 @@
}
}
- /* (non-Javadoc)
+ /**
* @see android.view.View#findViewById(int)
- * First look in our children, then in any header and footer views that may be scrolled off.
+ * @removed For internal use only. This should have been hidden.
*/
@Override
- protected View findViewTraversal(@IdRes int id) {
- View v;
- v = super.findViewTraversal(id);
+ protected <T extends View> T findViewTraversal(@IdRes int id) {
+ // First look in our children, then in any header and footer views that
+ // may be scrolled off.
+ View v = super.findViewTraversal(id);
if (v == null) {
v = findViewInHeadersOrFooters(mHeaderViewInfos, id);
if (v != null) {
- return v;
+ return (T) v;
}
v = findViewInHeadersOrFooters(mFooterViewInfos, id);
if (v != null) {
- return v;
+ return (T) v;
}
}
- return v;
+ return (T) v;
}
- /* (non-Javadoc)
- *
- * Look in the passed in list of headers or footers for the view.
- */
View findViewInHeadersOrFooters(ArrayList<FixedViewInfo> where, int id) {
+ // Look in the passed in list of headers or footers for the view.
if (where != null) {
int len = where.size();
View v;
@@ -3780,33 +3778,32 @@
return null;
}
- /* (non-Javadoc)
+ /**
* @see android.view.View#findViewWithTag(Object)
- * First look in our children, then in any header and footer views that may be scrolled off.
+ * @removed For internal use only. This should have been hidden.
*/
@Override
- protected View findViewWithTagTraversal(Object tag) {
- View v;
- v = super.findViewWithTagTraversal(tag);
+ protected <T extends View> T findViewWithTagTraversal(Object tag) {
+ // First look in our children, then in any header and footer views that
+ // may be scrolled off.
+ View v = super.findViewWithTagTraversal(tag);
if (v == null) {
v = findViewWithTagInHeadersOrFooters(mHeaderViewInfos, tag);
if (v != null) {
- return v;
+ return (T) v;
}
v = findViewWithTagInHeadersOrFooters(mFooterViewInfos, tag);
if (v != null) {
- return v;
+ return (T) v;
}
}
- return v;
+ return (T) v;
}
- /* (non-Javadoc)
- *
- * Look in the passed in list of headers or footers for the view with the tag.
- */
View findViewWithTagInHeadersOrFooters(ArrayList<FixedViewInfo> where, Object tag) {
+ // Look in the passed in list of headers or footers for the view with
+ // the tag.
if (where != null) {
int len = where.size();
View v;
@@ -3827,32 +3824,33 @@
}
/**
- * @hide
+ * First look in our children, then in any header and footer views that may
+ * be scrolled off.
+ *
* @see android.view.View#findViewByPredicate(Predicate)
- * First look in our children, then in any header and footer views that may be scrolled off.
+ * @hide
*/
@Override
- protected View findViewByPredicateTraversal(Predicate<View> predicate, View childToSkip) {
- View v;
- v = super.findViewByPredicateTraversal(predicate, childToSkip);
+ protected <T extends View> T findViewByPredicateTraversal(
+ Predicate<View> predicate, View childToSkip) {
+ View v = super.findViewByPredicateTraversal(predicate, childToSkip);
if (v == null) {
v = findViewByPredicateInHeadersOrFooters(mHeaderViewInfos, predicate, childToSkip);
if (v != null) {
- return v;
+ return (T) v;
}
v = findViewByPredicateInHeadersOrFooters(mFooterViewInfos, predicate, childToSkip);
if (v != null) {
- return v;
+ return (T) v;
}
}
- return v;
+ return (T) v;
}
- /* (non-Javadoc)
- *
- * Look in the passed in list of headers or footers for the first view that matches
- * the predicate.
+ /**
+ * Look in the passed in list of headers or footers for the first view that
+ * matches the predicate.
*/
View findViewByPredicateInHeadersOrFooters(ArrayList<FixedViewInfo> where,
Predicate<View> predicate, View childToSkip) {
diff --git a/core/java/android/widget/MediaController.java b/core/java/android/widget/MediaController.java
index 8008637..8e04f1c 100644
--- a/core/java/android/widget/MediaController.java
+++ b/core/java/android/widget/MediaController.java
@@ -257,13 +257,13 @@
.getText(com.android.internal.R.string.lockscreen_transport_play_description);
mPauseDescription = res
.getText(com.android.internal.R.string.lockscreen_transport_pause_description);
- mPauseButton = (ImageButton) v.findViewById(com.android.internal.R.id.pause);
+ mPauseButton = v.findViewById(com.android.internal.R.id.pause);
if (mPauseButton != null) {
mPauseButton.requestFocus();
mPauseButton.setOnClickListener(mPauseListener);
}
- mFfwdButton = (ImageButton) v.findViewById(com.android.internal.R.id.ffwd);
+ mFfwdButton = v.findViewById(com.android.internal.R.id.ffwd);
if (mFfwdButton != null) {
mFfwdButton.setOnClickListener(mFfwdListener);
if (!mFromXml) {
@@ -271,7 +271,7 @@
}
}
- mRewButton = (ImageButton) v.findViewById(com.android.internal.R.id.rew);
+ mRewButton = v.findViewById(com.android.internal.R.id.rew);
if (mRewButton != null) {
mRewButton.setOnClickListener(mRewListener);
if (!mFromXml) {
@@ -280,16 +280,16 @@
}
// By default these are hidden. They will be enabled when setPrevNextListeners() is called
- mNextButton = (ImageButton) v.findViewById(com.android.internal.R.id.next);
+ mNextButton = v.findViewById(com.android.internal.R.id.next);
if (mNextButton != null && !mFromXml && !mListenersSet) {
mNextButton.setVisibility(View.GONE);
}
- mPrevButton = (ImageButton) v.findViewById(com.android.internal.R.id.prev);
+ mPrevButton = v.findViewById(com.android.internal.R.id.prev);
if (mPrevButton != null && !mFromXml && !mListenersSet) {
mPrevButton.setVisibility(View.GONE);
}
- mProgress = (ProgressBar) v.findViewById(com.android.internal.R.id.mediacontroller_progress);
+ mProgress = v.findViewById(com.android.internal.R.id.mediacontroller_progress);
if (mProgress != null) {
if (mProgress instanceof SeekBar) {
SeekBar seeker = (SeekBar) mProgress;
@@ -298,8 +298,8 @@
mProgress.setMax(1000);
}
- mEndTime = (TextView) v.findViewById(com.android.internal.R.id.time);
- mCurrentTime = (TextView) v.findViewById(com.android.internal.R.id.time_current);
+ mEndTime = v.findViewById(com.android.internal.R.id.time);
+ mCurrentTime = v.findViewById(com.android.internal.R.id.time_current);
mFormatBuilder = new StringBuilder();
mFormatter = new Formatter(mFormatBuilder, Locale.getDefault());
diff --git a/core/java/android/widget/RelativeLayout.java b/core/java/android/widget/RelativeLayout.java
index b424101..67bfe5e 100644
--- a/core/java/android/widget/RelativeLayout.java
+++ b/core/java/android/widget/RelativeLayout.java
@@ -1013,7 +1013,8 @@
while (v.getVisibility() == View.GONE) {
rules = ((LayoutParams) v.getLayoutParams()).getRules(v.getLayoutDirection());
node = mGraph.mKeyNodes.get((rules[relation]));
- if (node == null) return null;
+ // ignore self dependency. for more info look in git commit: da3003
+ if (node == null || v == node.view) return null;
v = node.view;
}
diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java
index 359d04e..5505f2f 100644
--- a/core/java/android/widget/RemoteViews.java
+++ b/core/java/android/widget/RemoteViews.java
@@ -1578,7 +1578,7 @@
@Override
public void apply(View root, ViewGroup rootParent, OnClickHandler handler) {
final Context context = root.getContext();
- final ViewGroup target = (ViewGroup) root.findViewById(viewId);
+ final ViewGroup target = root.findViewById(viewId);
if (target == null) return;
if (nestedViews != null) {
// Inflate nested views and add as children
@@ -1757,7 +1757,7 @@
@Override
public void apply(View root, ViewGroup rootParent, OnClickHandler handler) {
- final TextView target = (TextView) root.findViewById(viewId);
+ final TextView target = root.findViewById(viewId);
if (target == null) return;
if (drawablesLoaded) {
if (isRelative) {
@@ -1857,7 +1857,7 @@
@Override
public void apply(View root, ViewGroup rootParent, OnClickHandler handler) {
- final TextView target = (TextView) root.findViewById(viewId);
+ final TextView target = root.findViewById(viewId);
if (target == null) return;
target.setTextSize(units, size);
}
@@ -2045,7 +2045,7 @@
@Override
public void apply(View root, ViewGroup rootParent, OnClickHandler handler) {
- final TextView target = (TextView) root.findViewById(viewId);
+ final TextView target = root.findViewById(viewId);
if (target == null) return;
Drawable[] drawables = isRelative
? target.getCompoundDrawablesRelative()
diff --git a/core/java/android/widget/SuggestionsAdapter.java b/core/java/android/widget/SuggestionsAdapter.java
index f833d1b..fbb8993 100644
--- a/core/java/android/widget/SuggestionsAdapter.java
+++ b/core/java/android/widget/SuggestionsAdapter.java
@@ -286,7 +286,7 @@
v.setTag(new ChildViewCache(v));
// Set up icon.
- final ImageView iconRefine = (ImageView) v.findViewById(R.id.edit_query);
+ final ImageView iconRefine = v.findViewById(R.id.edit_query);
iconRefine.setImageResource(mCommitIconResId);
return v;
@@ -304,11 +304,11 @@
public final ImageView mIconRefine;
public ChildViewCache(View v) {
- mText1 = (TextView) v.findViewById(com.android.internal.R.id.text1);
- mText2 = (TextView) v.findViewById(com.android.internal.R.id.text2);
- mIcon1 = (ImageView) v.findViewById(com.android.internal.R.id.icon1);
- mIcon2 = (ImageView) v.findViewById(com.android.internal.R.id.icon2);
- mIconRefine = (ImageView) v.findViewById(com.android.internal.R.id.edit_query);
+ mText1 = v.findViewById(com.android.internal.R.id.text1);
+ mText2 = v.findViewById(com.android.internal.R.id.text2);
+ mIcon1 = v.findViewById(com.android.internal.R.id.icon1);
+ mIcon2 = v.findViewById(com.android.internal.R.id.icon2);
+ mIconRefine = v.findViewById(com.android.internal.R.id.edit_query);
}
}
diff --git a/core/java/android/widget/TabHost.java b/core/java/android/widget/TabHost.java
index 32418cd..7e2cadf 100644
--- a/core/java/android/widget/TabHost.java
+++ b/core/java/android/widget/TabHost.java
@@ -619,7 +619,7 @@
mTabWidget, // tab widget is the parent
false); // no inflate params
- final TextView tv = (TextView) tabIndicator.findViewById(R.id.title);
+ final TextView tv = tabIndicator.findViewById(R.id.title);
tv.setText(mLabel);
if (context.getApplicationInfo().targetSdkVersion <= Build.VERSION_CODES.DONUT) {
@@ -653,8 +653,8 @@
mTabWidget, // tab widget is the parent
false); // no inflate params
- final TextView tv = (TextView) tabIndicator.findViewById(R.id.title);
- final ImageView iconView = (ImageView) tabIndicator.findViewById(R.id.icon);
+ final TextView tv = tabIndicator.findViewById(R.id.title);
+ final ImageView iconView = tabIndicator.findViewById(R.id.icon);
// when icon is gone by default, we're in exclusive mode
final boolean exclusive = iconView.getVisibility() == View.GONE;
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 6322615..a7a8fb4 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -1162,12 +1162,12 @@
case com.android.internal.R.styleable.TextView_fontFamily:
try {
- fontTypeface = appearance.getFont(attr);
+ fontTypeface = a.getFont(attr);
} catch (UnsupportedOperationException e) {
// Expected if it is not a font resource.
}
if (fontTypeface == null) {
- fontFamily = appearance.getString(attr);
+ fontFamily = a.getString(attr);
}
fontFamilyExplicit = true;
break;
diff --git a/core/java/android/widget/TimePickerSpinnerDelegate.java b/core/java/android/widget/TimePickerSpinnerDelegate.java
index 6a68f60..4634631 100644
--- a/core/java/android/widget/TimePickerSpinnerDelegate.java
+++ b/core/java/android/widget/TimePickerSpinnerDelegate.java
@@ -86,7 +86,7 @@
inflater.inflate(layoutResourceId, mDelegator, true);
// hour
- mHourSpinner = (NumberPicker) delegator.findViewById(R.id.hour);
+ mHourSpinner = delegator.findViewById(R.id.hour);
mHourSpinner.setOnValueChangedListener(new NumberPicker.OnValueChangeListener() {
public void onValueChange(NumberPicker spinner, int oldVal, int newVal) {
updateInputState();
@@ -100,17 +100,17 @@
onTimeChanged();
}
});
- mHourSpinnerInput = (EditText) mHourSpinner.findViewById(R.id.numberpicker_input);
+ mHourSpinnerInput = mHourSpinner.findViewById(R.id.numberpicker_input);
mHourSpinnerInput.setImeOptions(EditorInfo.IME_ACTION_NEXT);
// divider (only for the new widget style)
- mDivider = (TextView) mDelegator.findViewById(R.id.divider);
+ mDivider = mDelegator.findViewById(R.id.divider);
if (mDivider != null) {
setDividerText();
}
// minute
- mMinuteSpinner = (NumberPicker) mDelegator.findViewById(R.id.minute);
+ mMinuteSpinner = mDelegator.findViewById(R.id.minute);
mMinuteSpinner.setMinValue(0);
mMinuteSpinner.setMaxValue(59);
mMinuteSpinner.setOnLongPressUpdateInterval(100);
@@ -138,7 +138,7 @@
onTimeChanged();
}
});
- mMinuteSpinnerInput = (EditText) mMinuteSpinner.findViewById(R.id.numberpicker_input);
+ mMinuteSpinnerInput = mMinuteSpinner.findViewById(R.id.numberpicker_input);
mMinuteSpinnerInput.setImeOptions(EditorInfo.IME_ACTION_NEXT);
// Get the localized am/pm strings and use them in the spinner.
@@ -173,13 +173,13 @@
onTimeChanged();
}
});
- mAmPmSpinnerInput = (EditText) mAmPmSpinner.findViewById(R.id.numberpicker_input);
+ mAmPmSpinnerInput = mAmPmSpinner.findViewById(R.id.numberpicker_input);
mAmPmSpinnerInput.setImeOptions(EditorInfo.IME_ACTION_DONE);
}
if (isAmPmAtStart()) {
// Move the am/pm view to the beginning
- ViewGroup amPmParent = (ViewGroup) delegator.findViewById(R.id.timePickerLayout);
+ ViewGroup amPmParent = delegator.findViewById(R.id.timePickerLayout);
amPmParent.removeView(amPmView);
amPmParent.addView(amPmView, 0);
// Swap layout margins if needed. They may be not symmetrical (Old Standard Theme
diff --git a/core/java/android/widget/Toast.java b/core/java/android/widget/Toast.java
index 789e60b..bf0601d 100644
--- a/core/java/android/widget/Toast.java
+++ b/core/java/android/widget/Toast.java
@@ -299,7 +299,7 @@
if (mNextView == null) {
throw new RuntimeException("This Toast was not created with Toast.makeText()");
}
- TextView tv = (TextView) mNextView.findViewById(com.android.internal.R.id.message);
+ TextView tv = mNextView.findViewById(com.android.internal.R.id.message);
if (tv == null) {
throw new RuntimeException("This Toast was not created with Toast.makeText()");
}
diff --git a/core/java/android/widget/ZoomButtonsController.java b/core/java/android/widget/ZoomButtonsController.java
index 69b79971..1a3ca86 100644
--- a/core/java/android/widget/ZoomButtonsController.java
+++ b/core/java/android/widget/ZoomButtonsController.java
@@ -264,7 +264,7 @@
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
inflater.inflate(com.android.internal.R.layout.zoom_container, container);
- mControls = (ZoomControls) container.findViewById(com.android.internal.R.id.zoomControls);
+ mControls = container.findViewById(com.android.internal.R.id.zoomControls);
mControls.setOnZoomInClickListener(new OnClickListener() {
public void onClick(View v) {
dismissControlsDelayed(ZOOM_CONTROLS_TIMEOUT);
diff --git a/core/java/com/android/internal/widget/WatchHeaderListView.java b/core/java/com/android/internal/widget/WatchHeaderListView.java
index 4fd19c3..53fa7ab 100644
--- a/core/java/com/android/internal/widget/WatchHeaderListView.java
+++ b/core/java/com/android/internal/widget/WatchHeaderListView.java
@@ -92,13 +92,14 @@
}
@Override
- protected View findViewByPredicateTraversal(Predicate<View> predicate, View childToSkip) {
+ protected <T extends View> T findViewByPredicateTraversal(
+ Predicate<View> predicate, View childToSkip) {
View v = super.findViewByPredicateTraversal(predicate, childToSkip);
if (v == null && mTopPanel != null && mTopPanel != childToSkip
&& !mTopPanel.isRootNamespace()) {
- return mTopPanel.findViewByPredicate(predicate);
+ return (T) mTopPanel.findViewByPredicate(predicate);
}
- return v;
+ return (T) v;
}
@Override
diff --git a/core/res/res/values-mcc704-mnc01/config.xml b/core/res/res/values-mcc704-mnc01/config.xml
new file mode 100644
index 0000000..10b6470
--- /dev/null
+++ b/core/res/res/values-mcc704-mnc01/config.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2016, 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 my 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.
+*/
+-->
+
+<resources>
+ <!-- Do not translate. Defines the slots is Two Digit Number for dialing normally not USSD -->
+ <string-array name="config_twoDigitNumberPattern">
+ <item>"*1"</item>
+ <item>"*5"</item>
+ <item>"*9"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-mcc708-mnc001/config.xml b/core/res/res/values-mcc708-mnc001/config.xml
new file mode 100755
index 0000000..7b7c48d
--- /dev/null
+++ b/core/res/res/values-mcc708-mnc001/config.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2016, 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 my 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.
+*/
+-->
+
+<!-- These resources are around just to allow their values to be customized
+ for different hardware and product builds. -->
+<resources>
+ <string-array translatable="false" name="config_twoDigitNumberPattern">
+ <item>"*1"</item>
+ <item>"*5"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index ac8c896..2ab0914 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -4460,4 +4460,6 @@
<!-- Category title for apps which are primarily productivity apps, such as cloud storage or workplace apps. [CHAR LIMIT=32] -->
<string name="app_category_productivity">Productivity</string>
+ <!-- Channel name for DeviceStorageMonitor notifications -->
+ <string name="device_storage_monitor_notification_channel">Device storage</string>
</resources>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 643dd02..15011c8 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -1880,6 +1880,7 @@
<java-symbol type="string" name="data_usage_wifi_limit_snoozed_title" />
<java-symbol type="string" name="data_usage_wifi_limit_title" />
<java-symbol type="string" name="default_wallpaper_component" />
+ <java-symbol type="string" name="device_storage_monitor_notification_channel" />
<java-symbol type="string" name="dlg_ok" />
<java-symbol type="string" name="dump_heap_notification" />
<java-symbol type="string" name="dump_heap_notification_detail" />
diff --git a/core/tests/coretests/src/android/view/ViewInvalidateTest.java b/core/tests/coretests/src/android/view/ViewInvalidateTest.java
index 4db70ec..9de7d9c 100644
--- a/core/tests/coretests/src/android/view/ViewInvalidateTest.java
+++ b/core/tests/coretests/src/android/view/ViewInvalidateTest.java
@@ -219,7 +219,27 @@
public void testInvalidateChild_childHardwareLayer() throws Throwable {
WidgetTestUtils.runOnMainAndDrawSync(mActivityRule, mParent, () -> {
// do in runnable, so tree won't be dirty
- mChild.setLayerType(View.LAYER_TYPE_HARDWARE, null);
+ mParent.setLayerType(View.LAYER_TYPE_HARDWARE, null);
+ });
+
+ mActivityRule.runOnUiThread(() -> {
+ validateInvalFlags(mParent,
+ View.PFLAG_DRAWING_CACHE_VALID,
+ View.PFLAG_DRAWN);
+
+ mParent.invalidateChild(mChild, new Rect(0, 0, 1, 1));
+
+ validateInvalFlags(mParent,
+ View.PFLAG_DIRTY,
+ View.PFLAG_DRAWN); // Note: note invalidated, since HW damage handled in native
+ });
+ }
+
+ @Test
+ public void testInvalidateChild_childSoftwareLayer() throws Throwable {
+ WidgetTestUtils.runOnMainAndDrawSync(mActivityRule, mParent, () -> {
+ // do in runnable, so tree won't be dirty
+ mParent.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
});
mActivityRule.runOnUiThread(() -> {
@@ -232,7 +252,7 @@
validateInvalFlags(mParent,
View.PFLAG_DIRTY,
View.PFLAG_DRAWN,
- View.PFLAG_INVALIDATED);
+ View.PFLAG_INVALIDATED); // Note: invalidated, since SW damage handled here
});
}
diff --git a/libs/hwui/tests/common/scenes/SaveLayer2Animation.cpp b/libs/hwui/tests/common/scenes/SaveLayer2Animation.cpp
new file mode 100644
index 0000000..ad0b1f1
--- /dev/null
+++ b/libs/hwui/tests/common/scenes/SaveLayer2Animation.cpp
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#include "TestSceneBase.h"
+#include <string>
+#include <hwui/Paint.h>
+#include <minikin/Layout.h>
+
+class SaveLayer2Animation;
+
+static TestScene::Registrar _SaveLayer(TestScene::Info{
+ "savelayer2",
+ "Interleaving 20 drawText/drawRect ops with saveLayer"
+ "Tests the clipped saveLayer performance and FBO switching overhead.",
+ TestScene::simpleCreateScene<SaveLayer2Animation>
+});
+
+class SaveLayer2Animation : public TestScene {
+public:
+ Paint mBluePaint;
+ Paint mGreenPaint;
+
+ void createContent(int width, int height, Canvas& canvas) override {
+ canvas.drawColor(SkColorSetARGB(255, 255, 0, 0), SkBlendMode::kSrcOver);
+ SkIRect bounds = SkIRect::MakeWH(width, height);
+ int regions = 20;
+ int smallRectHeight = (bounds.height()/regions);
+ int padding = smallRectHeight / 4;
+ int top = bounds.fTop;
+
+ mBluePaint.setColor(SkColorSetARGB(255, 0, 0, 255));
+ mBluePaint.setTextSize(padding);
+ mGreenPaint.setColor(SkColorSetARGB(255, 0, 255, 0));
+ mGreenPaint.setTextSize(padding);
+
+ //interleave drawText and drawRect with saveLayer ops
+ for (int i = 0; i < regions; i++, top += smallRectHeight) {
+ canvas.saveLayer(bounds.fLeft, top, bounds.fRight, top + padding,
+ &mBluePaint, SaveFlags::ClipToLayer | SaveFlags::MatrixClip);
+ canvas.drawColor(SkColorSetARGB(255, 255, 255, 0), SkBlendMode::kSrcOver);
+ std::string stri = std::to_string(i);
+ std::string offscreen = "offscreen line " + stri;
+ std::unique_ptr<uint16_t[]> offtext = TestUtils::asciiToUtf16(offscreen.c_str());
+ canvas.drawText(offtext.get(), 0, offscreen.length(), offscreen.length(),
+ bounds.fLeft, top + padding, minikin::kBidi_Force_LTR, mBluePaint, nullptr);
+ canvas.restore();
+
+ canvas.drawRect(bounds.fLeft, top + padding, bounds.fRight,
+ top + smallRectHeight - padding, mBluePaint);
+ std::string onscreen = "onscreen line " + stri;
+ std::unique_ptr<uint16_t[]> ontext = TestUtils::asciiToUtf16(onscreen.c_str());
+ canvas.drawText(ontext.get(), 0, onscreen.length(), onscreen.length(), bounds.fLeft,
+ top + smallRectHeight - padding, minikin::kBidi_Force_LTR, mGreenPaint,
+ nullptr);
+ }
+ }
+ void doFrame(int frameNr) override {
+ }
+};
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationGutsTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationGutsTest.java
index 166fcb1..3e0d15d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationGutsTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationGutsTest.java
@@ -63,6 +63,7 @@
private static final String TEST_CHANNEL = "test_channel";
private static final String TEST_CHANNEL_NAME = "TEST CHANNEL NAME";
+ private NotificationGuts mNotificationGuts;
private NotificationInfo mNotificationInfo;
private final INotificationManager mMockINotificationManager = mock(INotificationManager.class);
private final PackageManager mMockPackageManager = mock(PackageManager.class);
@@ -78,6 +79,9 @@
LayoutInflater.from(InstrumentationRegistry.getTargetContext());
mNotificationInfo = (NotificationInfo) layoutInflater.inflate(R.layout.notification_info,
null);
+ mNotificationGuts = (NotificationGuts) layoutInflater.inflate(R.layout.notification_guts,
+ null);
+ mNotificationInfo.setInteractionListener(mNotificationGuts);
// PackageManager must return a packageInfo and applicationInfo.
final PackageInfo packageInfo = new PackageInfo();
@@ -198,37 +202,38 @@
@Test
@UiThreadTest
- public void testCloseControls_DoesNotUpdateNotificationChannelIfUnchanged() throws Exception {
+ public void testSaveImportance_DoesNotUpdateNotificationChannelIfUnchanged() throws Exception {
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
mMockStatusBarNotification, mNotificationChannel, null, null, null);
- mNotificationInfo.closeControls();
+ mNotificationInfo.saveImportance();
verify(mMockINotificationManager, never()).updateNotificationChannelForPackage(
anyString(), anyInt(), any());
}
@Test
@UiThreadTest
- public void testCloseControls_DoesNotUpdateNotificationChannelIfUnspecified() throws Exception {
+ public void testSaveImportance_DoesNotUpdateNotificationChannelIfUnspecified()
+ throws Exception {
mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_UNSPECIFIED);
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
mMockStatusBarNotification, mNotificationChannel, null, null, null);
- mNotificationInfo.closeControls();
+ mNotificationInfo.saveImportance();
verify(mMockINotificationManager, never()).updateNotificationChannelForPackage(
anyString(), anyInt(), any());
}
@Test
@UiThreadTest
- public void testCloseControls_CallsUpdateNotificationChannelIfChanged() throws Exception {
+ public void testSaveImportance_CallsUpdateNotificationChannelIfChanged() throws Exception {
mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_LOW);
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
mMockStatusBarNotification, mNotificationChannel, null, null, null);
RadioButton highButton = (RadioButton) mNotificationInfo.findViewById(R.id.high_importance);
highButton.setChecked(true);
- mNotificationInfo.closeControls();
+ mNotificationInfo.saveImportance();
verify(mMockINotificationManager, times(1)).updateNotificationChannelForPackage(
eq(TEST_PACKAGE_NAME), anyInt(), eq(mNotificationChannel));
assertEquals(NotificationManager.IMPORTANCE_HIGH, mNotificationChannel.getImportance());
@@ -236,20 +241,6 @@
@Test
@UiThreadTest
- public void testCloseControls_DoesNotUpdateNotificationChannelIfSaveFalse() throws Exception {
- mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_LOW);
- mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- mMockStatusBarNotification, mNotificationChannel, null, null, null);
-
- RadioButton highButton = (RadioButton) mNotificationInfo.findViewById(R.id.high_importance);
- highButton.setChecked(true);
- mNotificationInfo.closeControls();
- verify(mMockINotificationManager, never()).updateNotificationChannelForPackage(
- anyString(), anyInt(), any());
- }
-
- @Test
- @UiThreadTest
public void testEnabledSwitchOnByDefault() throws Exception {
mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_LOW);
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
@@ -292,7 +283,7 @@
Switch enabledSwitch = (Switch) mNotificationInfo.findViewById(R.id.channel_enabled_switch);
enabledSwitch.setChecked(false);
- mNotificationInfo.closeControls();
+ mNotificationInfo.saveImportance();
verify(mMockINotificationManager, times(1)).updateNotificationChannelForPackage(
eq(TEST_PACKAGE_NAME), anyInt(), eq(mNotificationChannel));
}
@@ -308,7 +299,7 @@
RadioButton lowButton = (RadioButton) mNotificationInfo.findViewById(R.id.low_importance);
lowButton.setChecked(true);
enabledSwitch.setChecked(false);
- mNotificationInfo.closeControls();
+ mNotificationInfo.saveImportance();
assertEquals(NotificationManager.IMPORTANCE_NONE, mNotificationChannel.getImportance());
}
}
diff --git a/services/core/java/com/android/server/UiModeManagerService.java b/services/core/java/com/android/server/UiModeManagerService.java
index 8f99127..6f2f2c4 100644
--- a/services/core/java/com/android/server/UiModeManagerService.java
+++ b/services/core/java/com/android/server/UiModeManagerService.java
@@ -35,10 +35,12 @@
import android.os.BatteryManager;
import android.os.Binder;
import android.os.Handler;
-import android.os.IBinder;
import android.os.PowerManager;
import android.os.RemoteException;
+import android.os.ResultReceiver;
import android.os.ServiceManager;
+import android.os.ShellCallback;
+import android.os.ShellCommand;
import android.os.SystemProperties;
import android.os.UserHandle;
import android.provider.Settings;
@@ -47,8 +49,6 @@
import android.service.vr.IVrStateCallbacks;
import android.text.TextUtils;
import android.util.Slog;
-import android.view.WindowManagerInternal;
-import android.view.WindowManagerPolicy;
import java.io.File;
import java.io.FileDescriptor;
@@ -62,7 +62,6 @@
import com.android.server.twilight.TwilightListener;
import com.android.server.twilight.TwilightManager;
import com.android.server.twilight.TwilightState;
-import com.android.server.wm.WindowManagerService;
final class UiModeManagerService extends SystemService {
private static final String TAG = UiModeManager.class.getSimpleName();
@@ -238,7 +237,7 @@
publishBinderService(Context.UI_MODE_SERVICE, mService);
}
- private final IBinder mService = new IUiModeManager.Stub() {
+ private final IUiModeManager.Stub mService = new IUiModeManager.Stub() {
@Override
public void enableCarMode(int flags) {
if (isUiModeLocked()) {
@@ -390,6 +389,12 @@
}
@Override
+ public void onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err,
+ String[] args, ShellCallback callback, ResultReceiver resultReceiver) {
+ new Shell(mService).exec(mService, in, out, err, args, callback, resultReceiver);
+ }
+
+ @Override
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
if (getContext().checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
!= PackageManager.PERMISSION_GRANTED) {
@@ -777,4 +782,101 @@
}
}
+ /**
+ * Handles "adb shell" commands.
+ */
+ private static class Shell extends ShellCommand {
+ public static final String NIGHT_MODE_STR_YES = "yes";
+ public static final String NIGHT_MODE_STR_NO = "no";
+ public static final String NIGHT_MODE_STR_AUTO = "auto";
+ public static final String NIGHT_MODE_STR_UNKNOWN = "unknown";
+ private final IUiModeManager mInterface;
+
+ Shell(IUiModeManager iface) {
+ mInterface = iface;
+ }
+
+ @Override
+ public void onHelp() {
+ final PrintWriter pw = getOutPrintWriter();
+ pw.println("UiModeManager service (uimode) commands:");
+ pw.println(" help");
+ pw.println(" Print this help text.");
+ pw.println(" night [yes|no|auto]");
+ pw.println(" Set or read night mode.");
+ }
+
+ @Override
+ public int onCommand(String cmd) {
+ if (cmd == null) {
+ return handleDefaultCommands(cmd);
+ }
+
+ try {
+ switch (cmd) {
+ case "night":
+ return handleNightMode();
+ default:
+ return handleDefaultCommands(cmd);
+ }
+ } catch (RemoteException e) {
+ final PrintWriter err = getErrPrintWriter();
+ err.println("Remote exception: " + e);
+ }
+ return -1;
+ }
+
+ private int handleNightMode() throws RemoteException {
+ final PrintWriter err = getErrPrintWriter();
+ final String modeStr = getNextArg();
+ if (modeStr == null) {
+ printCurrentNightMode();
+ return 0;
+ }
+
+ final int mode = strToNightMode(modeStr);
+ if (mode >= 0) {
+ mInterface.setNightMode(mode);
+ printCurrentNightMode();
+ return 0;
+ } else {
+ err.println("Error: mode must be '" + NIGHT_MODE_STR_YES + "', '"
+ + NIGHT_MODE_STR_NO + "', or '" + NIGHT_MODE_STR_AUTO + "'");
+ return -1;
+ }
+ }
+
+ private void printCurrentNightMode() throws RemoteException {
+ final PrintWriter pw = getOutPrintWriter();
+ final int currMode = mInterface.getNightMode();
+ final String currModeStr = nightModeToStr(currMode);
+ pw.println("Night mode: " + currModeStr);
+ }
+
+ private static String nightModeToStr(int mode) {
+ switch (mode) {
+ case UiModeManager.MODE_NIGHT_YES:
+ return NIGHT_MODE_STR_YES;
+ case UiModeManager.MODE_NIGHT_NO:
+ return NIGHT_MODE_STR_NO;
+ case UiModeManager.MODE_NIGHT_AUTO:
+ return NIGHT_MODE_STR_AUTO;
+ default:
+ return NIGHT_MODE_STR_UNKNOWN;
+ }
+ }
+
+ private static int strToNightMode(String modeStr) {
+ switch (modeStr) {
+ case NIGHT_MODE_STR_YES:
+ return UiModeManager.MODE_NIGHT_YES;
+ case NIGHT_MODE_STR_NO:
+ return UiModeManager.MODE_NIGHT_NO;
+ case NIGHT_MODE_STR_AUTO:
+ return UiModeManager.MODE_NIGHT_AUTO;
+ default:
+ return -1;
+ }
+ }
+ }
}
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index b82999e..a835976 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -4559,18 +4559,18 @@
mHandler.post(new Runnable() {
@Override
public void run() {
- notifyEnqueued(info, sbnToPost, importance, fromUser);
+ notifyEnqueued(info, sbnToPost);
}
});
}
}
private void notifyEnqueued(final ManagedServiceInfo info,
- final StatusBarNotification sbn, int importance, boolean fromUser) {
+ final StatusBarNotification sbn) {
final INotificationListener assistant = (INotificationListener) info.service;
StatusBarNotificationHolder sbnHolder = new StatusBarNotificationHolder(sbn);
try {
- assistant.onNotificationEnqueued(sbnHolder, importance, fromUser);
+ assistant.onNotificationEnqueued(sbnHolder);
} catch (RemoteException ex) {
Log.e(TAG, "unable to notify assistant (enqueued): " + assistant, ex);
}
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index add2c66..24ab3c7 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -16484,13 +16484,13 @@
Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
}
- // Ephemeral apps must have target SDK >= O.
- // TODO: Update conditional and error message when O gets locked down
- if (ephemeral && pkg.applicationInfo.targetSdkVersion <= Build.VERSION_CODES.N_MR1) {
- res.setError(PackageManager.INSTALL_FAILED_EPHEMERAL_INVALID,
- "Ephemeral apps must have target SDK version of at least O");
- return;
- }
+// // Ephemeral apps must have target SDK >= O.
+// // TODO: Update conditional and error message when O gets locked down
+// if (ephemeral && pkg.applicationInfo.targetSdkVersion <= Build.VERSION_CODES.N_MR1) {
+// res.setError(PackageManager.INSTALL_FAILED_EPHEMERAL_INVALID,
+// "Ephemeral apps must have target SDK version of at least O");
+// return;
+// }
if (pkg.applicationInfo.isStaticSharedLibrary()) {
// Static shared libraries have synthetic package names
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 4350ed9..d623051 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -261,6 +261,9 @@
// No longer recommended for desk docks;
static final boolean ENABLE_DESK_DOCK_HOME_CAPTURE = false;
+ // Whether to allow devices placed in vr headset viewers to have an alternative Home intent.
+ static final boolean ENABLE_VR_HEADSET_HOME_CAPTURE = true;
+
static final boolean ALTERNATE_CAR_MODE_NAV_SIZE = false;
static final int SHORT_PRESS_POWER_NOTHING = 0;
@@ -684,6 +687,7 @@
Intent mHomeIntent;
Intent mCarDockIntent;
Intent mDeskDockIntent;
+ Intent mVrHeadsetHomeIntent;
boolean mSearchKeyShortcutPending;
boolean mConsumeSearchKeyUp;
boolean mAssistKeyLongPressed;
@@ -1791,6 +1795,10 @@
mDeskDockIntent.addCategory(Intent.CATEGORY_DESK_DOCK);
mDeskDockIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
| Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
+ mVrHeadsetHomeIntent = new Intent(Intent.ACTION_MAIN, null);
+ mVrHeadsetHomeIntent.addCategory(Intent.CATEGORY_VR_HOME);
+ mVrHeadsetHomeIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
+ | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
mPowerManager = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
mBroadcastWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
@@ -7392,6 +7400,10 @@
|| mDockMode == Intent.EXTRA_DOCK_STATE_LE_DESK)) {
// Always launch dock home from home when watch is docked, if it exists.
intent = mDeskDockIntent;
+ } else if (mUiMode == Configuration.UI_MODE_TYPE_VR_HEADSET) {
+ if (ENABLE_VR_HEADSET_HOME_CAPTURE) {
+ intent = mVrHeadsetHomeIntent;
+ }
}
if (intent == null) {
diff --git a/services/core/java/com/android/server/power/Notifier.java b/services/core/java/com/android/server/power/Notifier.java
index b215998..c31369e 100644
--- a/services/core/java/com/android/server/power/Notifier.java
+++ b/services/core/java/com/android/server/power/Notifier.java
@@ -22,6 +22,8 @@
import com.android.internal.app.IAppOpsService;
import com.android.internal.app.IBatteryStats;
+import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.server.EventLogTags;
import com.android.server.LocalServices;
@@ -32,6 +34,7 @@
import android.media.AudioManager;
import android.media.Ringtone;
import android.media.RingtoneManager;
+import android.metrics.LogMaker;
import android.net.Uri;
import android.os.BatteryStats;
import android.os.Handler;
@@ -401,6 +404,10 @@
mHandler.post(new Runnable() {
@Override
public void run() {
+ LogMaker log = new LogMaker(MetricsEvent.SCREEN);
+ log.setType(MetricsEvent.TYPE_OPEN);
+ log.setSubtype(0); // not user initiated
+ MetricsLogger.action(log);
EventLog.writeEvent(EventLogTags.POWER_SCREEN_STATE, 1, 0, 0, 0);
mPolicy.startedWakingUp();
}
@@ -457,6 +464,10 @@
mHandler.post(new Runnable() {
@Override
public void run() {
+ LogMaker log = new LogMaker(MetricsEvent.SCREEN);
+ log.setType(MetricsEvent.TYPE_CLOSE);
+ log.setSubtype(why);
+ MetricsLogger.action(log);
EventLog.writeEvent(EventLogTags.POWER_SCREEN_STATE, 0, why, 0, 0);
mPolicy.finishedGoingToSleep(why);
}
diff --git a/services/core/java/com/android/server/storage/DeviceStorageMonitorService.java b/services/core/java/com/android/server/storage/DeviceStorageMonitorService.java
index a3837b2..afdec9f 100644
--- a/services/core/java/com/android/server/storage/DeviceStorageMonitorService.java
+++ b/services/core/java/com/android/server/storage/DeviceStorageMonitorService.java
@@ -16,6 +16,7 @@
package com.android.server.storage;
+import android.app.NotificationChannel;
import com.android.server.EventLogTags;
import com.android.server.SystemService;
import com.android.server.pm.InstructionSets;
@@ -140,6 +141,8 @@
*/
static final String SERVICE = "devicestoragemonitor";
+ private static final String NOTIFICATION_CHANNEL_ID = SERVICE;
+
/**
* Handler that checks the amount of disk space on the device and sends a
* notification if the device runs low on disk space
@@ -365,7 +368,8 @@
@Override
public void onStart() {
// cache storage thresholds
- final StorageManager sm = StorageManager.from(getContext());
+ Context context = getContext();
+ final StorageManager sm = StorageManager.from(context);
mMemLowThreshold = sm.getStorageLowBytes(DATA_PATH);
mMemFullThreshold = sm.getStorageFullBytes(DATA_PATH);
@@ -378,6 +382,21 @@
mCacheFileDeletedObserver = new CacheFileDeletedObserver();
mCacheFileDeletedObserver.startWatching();
+ // Ensure that the notification channel is set up
+ NotificationManager notificationMgr =
+ (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
+ PackageManager packageManager = context.getPackageManager();
+ boolean isTv = packageManager.hasSystemFeature(PackageManager.FEATURE_LEANBACK);
+
+ int importance = isTv
+ ? NotificationManager.IMPORTANCE_HIGH // Do not change: this is TV-specific
+ : NotificationManager.IMPORTANCE_LOW;
+ notificationMgr.createNotificationChannel(
+ new NotificationChannel(NOTIFICATION_CHANNEL_ID,
+ context.getString(
+ com.android.internal.R.string.device_storage_monitor_notification_channel),
+ importance));
+
publishBinderService(SERVICE, mRemoteService);
publishLocalService(DeviceStorageMonitorInternal.class, mLocalService);
}
@@ -466,7 +485,7 @@
Intent lowMemIntent = new Intent(StorageManager.ACTION_MANAGE_STORAGE);
lowMemIntent.putExtra("memory", mFreeMem);
lowMemIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- NotificationManager mNotificationMgr =
+ NotificationManager notificationMgr =
(NotificationManager)context.getSystemService(
Context.NOTIFICATION_SERVICE);
CharSequence title = context.getText(
@@ -488,9 +507,11 @@
.bigText(details))
.setVisibility(Notification.VISIBILITY_PUBLIC)
.setCategory(Notification.CATEGORY_SYSTEM)
+ .setChannel(NOTIFICATION_CHANNEL_ID)
+ .extend(new Notification.TvExtender())
.build();
notification.flags |= Notification.FLAG_NO_CLEAR;
- mNotificationMgr.notifyAsUser(null, LOW_MEMORY_NOTIFICATION_ID, notification,
+ notificationMgr.notifyAsUser(null, LOW_MEMORY_NOTIFICATION_ID, notification,
UserHandle.ALL);
context.sendStickyBroadcastAsUser(mStorageLowIntent, UserHandle.ALL);
}
diff --git a/tests/UiBench/AndroidManifest.xml b/tests/UiBench/AndroidManifest.xml
index 07f7617..c20be51 100644
--- a/tests/UiBench/AndroidManifest.xml
+++ b/tests/UiBench/AndroidManifest.xml
@@ -100,6 +100,22 @@
</intent-filter>
</activity>
<activity
+ android:name=".FadingEdgeListActivity"
+ android:label="General/Fading Edge ListView" >
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="com.android.test.uibench.TEST" />
+ </intent-filter>
+ </activity>
+ <activity
+ android:name=".SaveLayerInterleaveActivity"
+ android:label="General/SaveLayer Animation" >
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="com.android.test.uibench.TEST" />
+ </intent-filter>
+ </activity>
+ <activity
android:name=".ClippedListActivity"
android:label="General/Clipped ListView"
android:theme="@style/NoActionBar">
diff --git a/tests/UiBench/src/com/android/test/uibench/FadingEdgeListActivity.java b/tests/UiBench/src/com/android/test/uibench/FadingEdgeListActivity.java
new file mode 100644
index 0000000..3241e66
--- /dev/null
+++ b/tests/UiBench/src/com/android/test/uibench/FadingEdgeListActivity.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2017 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.test.uibench;
+
+import android.support.v4.app.ListFragment;
+import android.widget.ArrayAdapter;
+import android.widget.ListAdapter;
+
+import com.android.test.uibench.listview.CompatListActivity;
+import com.android.test.uibench.listview.FadingEdgeListFragment;
+
+public class FadingEdgeListActivity extends CompatListActivity {
+
+ @Override
+ protected ListAdapter createListAdapter() {
+ return new ArrayAdapter<>(this, android.R.layout.simple_list_item_1,
+ TextUtils.buildSimpleStringList(40));
+ }
+
+ @Override
+ protected ListFragment createListFragment() {
+ return (ListFragment)new FadingEdgeListFragment();
+ }
+}
diff --git a/tests/UiBench/src/com/android/test/uibench/SaveLayerInterleaveActivity.java b/tests/UiBench/src/com/android/test/uibench/SaveLayerInterleaveActivity.java
new file mode 100644
index 0000000..eec91cb
--- /dev/null
+++ b/tests/UiBench/src/com/android/test/uibench/SaveLayerInterleaveActivity.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2017 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.test.uibench;
+
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.ColorFilter;
+import android.graphics.Paint;
+import android.graphics.PixelFormat;
+import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
+import android.os.Bundle;
+import android.support.v7.app.AppCompatActivity;
+
+/**
+ * Test Canvas.saveLayer performance by interleaving drawText/drawRect with saveLayer.
+ * This test will be used to measure if drawing interleaved layers at the beginning of a frame will
+ * decrease FBO switching overhead (this is a future optimization in SkiaGL rendering pipeline).
+ */
+public class SaveLayerInterleaveActivity extends AppCompatActivity {
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ getWindow().setBackgroundDrawable(new Drawable() {
+ private final Paint mBluePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+ private final Paint mGreenPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+
+ @Override
+ public void setAlpha(int alpha) {
+ }
+
+ @Override
+ public int getOpacity() {
+ return PixelFormat.OPAQUE;
+ }
+
+ @Override
+ public void setColorFilter(ColorFilter colorFilter) {
+ }
+
+ @Override
+ public void draw(Canvas canvas) {
+ canvas.drawColor(Color.RED);
+
+ Rect bounds = getBounds();
+ int regions = 20;
+ int smallRectHeight = (bounds.height()/regions);
+ int padding = smallRectHeight / 4;
+ int top = bounds.top;
+ mBluePaint.setColor(Color.BLUE);
+ mBluePaint.setTextSize(padding);
+ mGreenPaint.setColor(Color.GREEN);
+ mGreenPaint.setTextSize(padding);
+
+ //interleave drawText and drawRect with saveLayer ops
+ for (int i = 0; i < regions; i++, top += smallRectHeight) {
+ canvas.saveLayer(bounds.left, top, bounds.right, top + padding,
+ mBluePaint);
+ canvas.drawColor(Color.YELLOW);
+ canvas.drawText("offscreen line "+ i, bounds.left, top + padding,
+ mBluePaint);
+ canvas.restore();
+
+ Rect partX = new Rect(bounds.left, top + padding,
+ bounds.right,top + smallRectHeight - padding);
+ canvas.drawRect(partX, mBluePaint);
+ canvas.drawText("onscreen line "+ i, bounds.left,
+ top + smallRectHeight - padding, mGreenPaint);
+ }
+
+ invalidateSelf();
+ }
+ });
+ }
+}
diff --git a/tests/UiBench/src/com/android/test/uibench/listview/CompatListActivity.java b/tests/UiBench/src/com/android/test/uibench/listview/CompatListActivity.java
index 214c074..bb7f4a3 100644
--- a/tests/UiBench/src/com/android/test/uibench/listview/CompatListActivity.java
+++ b/tests/UiBench/src/com/android/test/uibench/listview/CompatListActivity.java
@@ -29,11 +29,15 @@
FragmentManager fm = getSupportFragmentManager();
if (fm.findFragmentById(android.R.id.content) == null) {
- ListFragment listFragment = new ListFragment();
+ ListFragment listFragment = createListFragment();
listFragment.setListAdapter(createListAdapter());
fm.beginTransaction().add(android.R.id.content, listFragment).commit();
}
}
protected abstract ListAdapter createListAdapter();
+
+ protected ListFragment createListFragment() {
+ return new ListFragment();
+ }
}
diff --git a/tests/UiBench/src/com/android/test/uibench/listview/FadingEdgeListFragment.java b/tests/UiBench/src/com/android/test/uibench/listview/FadingEdgeListFragment.java
new file mode 100644
index 0000000..a018b40
--- /dev/null
+++ b/tests/UiBench/src/com/android/test/uibench/listview/FadingEdgeListFragment.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2017 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.test.uibench.listview;
+
+import android.os.Bundle;
+import android.support.v4.app.ListFragment;
+import android.widget.ListView;
+
+public class FadingEdgeListFragment extends ListFragment {
+
+ @Override
+ public void onActivityCreated(Bundle savedInstanceState) {
+ ListView listView = getListView();
+ listView.setVerticalFadingEdgeEnabled(true);
+ listView.setFadingEdgeLength(500);
+ super.onActivityCreated(savedInstanceState);
+ }
+}
diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java
index 8cf7a24..dbf8cc1 100644
--- a/wifi/java/android/net/wifi/WifiConfiguration.java
+++ b/wifi/java/android/net/wifi/WifiConfiguration.java
@@ -373,6 +373,12 @@
public String providerFriendlyName;
/**
+ * Flag indicating if this network is provided by a home Passpoint provider or a roaming
+ * Passpoint provider.
+ */
+ public boolean isHomeProviderNetwork;
+
+ /**
* Roaming Consortium Id list for passpoint credential; identifies a set of networks where
* passpoint credential will be considered valid
*/
@@ -1891,6 +1897,7 @@
FQDN = source.FQDN;
roamingConsortiumIds = source.roamingConsortiumIds.clone();
providerFriendlyName = source.providerFriendlyName;
+ isHomeProviderNetwork = source.isHomeProviderNetwork;
preSharedKey = source.preSharedKey;
mNetworkSelectionStatus.copy(source.getNetworkSelectionStatus());
@@ -1971,6 +1978,7 @@
dest.writeInt(apChannel);
dest.writeString(FQDN);
dest.writeString(providerFriendlyName);
+ dest.writeInt(isHomeProviderNetwork ? 1 : 0);
dest.writeInt(roamingConsortiumIds.length);
for (long roamingConsortiumId : roamingConsortiumIds) {
dest.writeLong(roamingConsortiumId);
@@ -2036,6 +2044,7 @@
config.apChannel = in.readInt();
config.FQDN = in.readString();
config.providerFriendlyName = in.readString();
+ config.isHomeProviderNetwork = in.readInt() != 0;
int numRoamingConsortiumIds = in.readInt();
config.roamingConsortiumIds = new long[numRoamingConsortiumIds];
for (int i = 0; i < numRoamingConsortiumIds; i++) {
diff --git a/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java b/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java
index ca4d121..f1174b6 100644
--- a/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java
+++ b/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java
@@ -217,9 +217,9 @@
return (homeSp == null ? that.homeSp == null : homeSp.equals(that.homeSp))
&& (credential == null ? that.credential == null
: credential.equals(that.credential))
- && (policy == null) ? that.policy == null : policy.equals(that.policy)
- && (subscriptionUpdate == null) ? that.subscriptionUpdate == null
- : subscriptionUpdate.equals(that.subscriptionUpdate)
+ && (policy == null ? that.policy == null : policy.equals(that.policy))
+ && (subscriptionUpdate == null ? that.subscriptionUpdate == null
+ : subscriptionUpdate.equals(that.subscriptionUpdate))
&& isTrustRootCertListEquals(trustRootCertList, that.trustRootCertList)
&& updateIdentifier == that.updateIdentifier
&& credentialPriority == that.credentialPriority
diff --git a/wifi/java/android/net/wifi/hotspot2/pps/Policy.java b/wifi/java/android/net/wifi/hotspot2/pps/Policy.java
index b2583d3..bc29402 100644
--- a/wifi/java/android/net/wifi/hotspot2/pps/Policy.java
+++ b/wifi/java/android/net/wifi/hotspot2/pps/Policy.java
@@ -293,13 +293,13 @@
&& minRoamingDownlinkBandwidth == that.minRoamingDownlinkBandwidth
&& minRoamingUplinkBandwidth == that.minRoamingUplinkBandwidth
&& Arrays.equals(excludedSsidList, that.excludedSsidList)
- && (requiredProtoPortMap == null) ? that.requiredProtoPortMap == null
- : requiredProtoPortMap.equals(that.requiredProtoPortMap)
+ && (requiredProtoPortMap == null ? that.requiredProtoPortMap == null
+ : requiredProtoPortMap.equals(that.requiredProtoPortMap))
&& maximumBssLoadValue == that.maximumBssLoadValue
- && (preferredRoamingPartnerList == null) ? that.preferredRoamingPartnerList == null
- : preferredRoamingPartnerList.equals(that.preferredRoamingPartnerList)
- && (policyUpdate == null) ? that.policyUpdate == null
- : policyUpdate.equals(that.policyUpdate);
+ && (preferredRoamingPartnerList == null ? that.preferredRoamingPartnerList == null
+ : preferredRoamingPartnerList.equals(that.preferredRoamingPartnerList))
+ && (policyUpdate == null ? that.policyUpdate == null
+ : policyUpdate.equals(that.policyUpdate));
}
/**