Moving setIsRootNamespace in notification one level higher

setIsRootNamespace was used to avoiding conflicts when we look for view by id but custom notifications layout happens to have view with the same id (b/13421971).
Unfortunately it also breaks keyboard navigation - once user enters notification with keyboard, they can't leave it.

The solution is to override focusSearch method but that can't be done on root view (id status_bar_latest_event_content) because it's coming from framework.
That's why setIsRootNamespace is called on view one level higher - NotificationContentView and then we override focusSearch.

Bug: 285554136
Test: PlatformScenarioTests:TabingThroughSplitShade
Change-Id: I8a6f0bc9012df8f55eb1ad1cb4c3d44af537b18c
This commit is contained in:
Michal Brzezinski
2023-06-06 11:47:22 +02:00
committed by Michał Brzeziński
parent 267665ed82
commit 03756131ca
3 changed files with 18 additions and 3 deletions

View File

@@ -402,7 +402,7 @@ public class NotificationRemoteInputManager implements Dumpable {
while (p != null) {
if (p instanceof View) {
View pv = (View) p;
if (pv.isRootNamespace()) {
if (pv.getId() == com.android.internal.R.id.status_bar_latest_event_content) {
riv = findRemoteInputView(pv);
row = (ExpandableNotificationRow) pv.getTag(R.id.row_tag_for_content_view);
break;

View File

@@ -474,7 +474,6 @@ public class NotificationContentInflater implements NotificationRowContentBinder
parentLayout,
remoteViewClickHandler);
validateView(v, entry, row.getResources());
v.setIsRootNamespace(true);
applyCallback.setResultView(v);
} else {
newContentView.reapply(
@@ -511,7 +510,6 @@ public class NotificationContentInflater implements NotificationRowContentBinder
return;
}
if (isNewView) {
v.setIsRootNamespace(true);
applyCallback.setResultView(v);
} else if (existingWrapper != null) {
existingWrapper.onReinflated();

View File

@@ -208,6 +208,23 @@ public class NotificationContentView extends FrameLayout implements Notification
mSmartReplyConstants = smartReplyConstants;
mSmartReplyController = smartReplyController;
mStatusBarService = statusBarService;
// We set root namespace so that we avoid searching children for id. Notification might
// contain custom view and their ids may clash with ids already existing in shade or
// notification panel
setIsRootNamespace(true);
}
@Override
public View focusSearch(View focused, int direction) {
// This implementation is copied from ViewGroup but with removed special handling of
// setIsRootNamespace. This view is set as tree root using setIsRootNamespace and it
// causes focus to be stuck inside of it. We need to be root to avoid id conflicts
// but we don't want to behave like root when it comes to focusing.
if (mParent != null) {
return mParent.focusSearch(focused, direction);
}
Log.wtf(TAG, "NotificationContentView doesn't have parent");
return null;
}
public void reinflate() {