|
|
Chromium Code Reviews
Description[NTP Client] Reset ActionItem view properties along visibility updates.
A section's ActionItem can be altered during a swipe to dismiss, but
its state is not properly cleared when new suggestions are added at
that same time. This patch fixes that by issuing a partial update
request on significant suggestion count changes.
BUG=687977
Review-Url: https://codereview.chromium.org/2635993002
Cr-Commit-Position: refs/heads/master@{#447808}
Committed: https://chromium.googlesource.com/chromium/src/+/6dd2506d48693bae425b7d37a8fc0fb21e0340e4
Patch Set 1 #
Total comments: 9
Patch Set 2 : rebase #Patch Set 3 : different approach to more button reset, adapter initiated #Patch Set 4 : rebase rewrite #
Total comments: 4
Patch Set 5 : rebase and rewrite #
Total comments: 2
Patch Set 6 : address comments #Patch Set 7 : rebase #Patch Set 8 : rebase #
Total comments: 2
Patch Set 9 : rebase, implement as callback #Patch Set 10 : _ #Patch Set 11 : remove log #
Total comments: 4
Patch Set 12 : update documentation #Patch Set 13 : Move callback to recyclerview #
Messages
Total messages: 56 (35 generated)
The CQ bit was checked by dgn@chromium.org to run a CQ dry run
Dry run: CQ is trying da patch. Follow status at https://chromium-cq-status.appspot.com/v2/patch-status/codereview.chromium.or...
dgn@chromium.org changed reviewers: + bauerb@chromium.org, mvanouwerkerk@chromium.org
PTAL https://codereview.chromium.org/2635993002/diff/1/chrome/android/java/src/org... File chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/NewTabPageRecyclerView.java (right): https://codereview.chromium.org/2635993002/diff/1/chrome/android/java/src/org... chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/NewTabPageRecyclerView.java:700: Log.d(TAG, "onChildDraw: orphaned view should be removed %s", viewHolder); I was investigating https://crbug.com/668104, but I can't find a good fix for it. It's quite hard to trigger and seems to not be a Chrome bug. But below are the things that could have an effect if some internal RecyclerView methods were available.
The CQ bit was unchecked by commit-bot@chromium.org
Dry run: This issue passed the CQ dry run.
https://codereview.chromium.org/2635993002/diff/1/chrome/android/java/src/org... File chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/NewTabPageRecyclerView.java (right): https://codereview.chromium.org/2635993002/diff/1/chrome/android/java/src/org... chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/NewTabPageRecyclerView.java:671: NewTabPageViewHolder sibling = ((SiblingViewHolder) viewHolder).getSibling(); Why does getNewTabPageAdapter().getDismissSibling(viewHolder) not work here? In general, we seem to be tying ourselves very much to the notion that each item has at most one sibling, which seems a bit arbitrary. I have a CL that generalizes this to a set of items that get dismissed together, which simplifies quite a bit of code: https://codereview.chromium.org/2617133002/.
https://codereview.chromium.org/2635993002/diff/1/chrome/android/java/src/org... File chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/CardViewHolder.java (right): https://codereview.chromium.org/2635993002/diff/1/chrome/android/java/src/org... chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/CardViewHolder.java:297: public abstract static class SiblingViewHolder extends CardViewHolder { Can this be a top level class? It seems a bit strange to have an inner class that extends the outer class, we don't usually set up inheritance that way.
https://codereview.chromium.org/2635993002/diff/1/chrome/android/java/src/org... File chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/NewTabPageRecyclerView.java (right): https://codereview.chromium.org/2635993002/diff/1/chrome/android/java/src/org... chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/NewTabPageRecyclerView.java:671: NewTabPageViewHolder sibling = ((SiblingViewHolder) viewHolder).getSibling(); On 2017/01/17 15:36:59, Bernhard Bauer wrote: > Why does getNewTabPageAdapter().getDismissSibling(viewHolder) not work here? > > In general, we seem to be tying ourselves very much to the notion that each item > has at most one sibling, which seems a bit arbitrary. I have a CL that > generalizes this to a set of items that get dismissed together, which simplifies > quite a bit of code: https://codereview.chromium.org/2617133002/. Because as far as the adapter is concerned, the item does not exist anymore, so it can't return a sibling for it. I don't think your patch would address that, since it's still based on the state of the adapter and the tree.
https://codereview.chromium.org/2635993002/diff/1/chrome/android/java/src/org... File chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/NewTabPageRecyclerView.java (right): https://codereview.chromium.org/2635993002/diff/1/chrome/android/java/src/org... chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/NewTabPageRecyclerView.java:671: NewTabPageViewHolder sibling = ((SiblingViewHolder) viewHolder).getSibling(); On 2017/01/17 16:09:01, dgn wrote: > On 2017/01/17 15:36:59, Bernhard Bauer wrote: > > Why does getNewTabPageAdapter().getDismissSibling(viewHolder) not work here? > > > > In general, we seem to be tying ourselves very much to the notion that each > item > > has at most one sibling, which seems a bit arbitrary. I have a CL that > > generalizes this to a set of items that get dismissed together, which > simplifies > > quite a bit of code: https://codereview.chromium.org/2617133002/. > > Because as far as the adapter is concerned, the item does not exist anymore, so > it can't return a sibling for it. I don't think your patch would address that, > since it's still based on the state of the adapter and the tree. Okay, so there are two things here we could do: 1) If we need to keep track of siblings even after an item has been removed from the adapter, we can do that, but there is no need to abuse the class hierarchy for that :) If our view holders can have optional siblings, that functionality can live in NewTabPageViewHolder without requiring a subclass. Then with my change we can just change the sibling reference to a sibling set. 2) Why do we need to reset the displacement in the first place? Just so that the state is correct when the view is recycled? In that case, could we just do that when we bind the ViewHolder? https://codereview.chromium.org/2635993002/diff/1/chrome/android/java/src/org... chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/NewTabPageRecyclerView.java:717: // parent implementation. (by default it changes the translation-X and elevation) In this CL we change the code so we do call the super implementation. Why is that? Does the comment need to be updated?
https://codereview.chromium.org/2635993002/diff/1/chrome/android/java/src/org... File chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/NewTabPageRecyclerView.java (right): https://codereview.chromium.org/2635993002/diff/1/chrome/android/java/src/org... chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/NewTabPageRecyclerView.java:671: NewTabPageViewHolder sibling = ((SiblingViewHolder) viewHolder).getSibling(); On 2017/01/17 16:59:36, Bernhard Bauer wrote: > On 2017/01/17 16:09:01, dgn wrote: > > On 2017/01/17 15:36:59, Bernhard Bauer wrote: > > > Why does getNewTabPageAdapter().getDismissSibling(viewHolder) not work here? > > > > > > In general, we seem to be tying ourselves very much to the notion that each > > item > > > has at most one sibling, which seems a bit arbitrary. I have a CL that > > > generalizes this to a set of items that get dismissed together, which > > simplifies > > > quite a bit of code: https://codereview.chromium.org/2617133002/. > > > > Because as far as the adapter is concerned, the item does not exist anymore, > so > > it can't return a sibling for it. I don't think your patch would address that, > > since it's still based on the state of the adapter and the tree. > > Okay, so there are two things here we could do: > 1) If we need to keep track of siblings even after an item has been removed from > the adapter, we can do that, but there is no need to abuse the class hierarchy > for that :) If our view holders can have optional siblings, that functionality > can live in NewTabPageViewHolder without requiring a subclass. Then with my > change we can just change the sibling reference to a sibling set. good point > 2) Why do we need to reset the displacement in the first place? Just so that the > state is correct when the view is recycled? In that case, could we just do that > when we bind the ViewHolder? The problem is that in this case the view is not recycled. We only remove the status card but keep the action item. So it is not rebound nor reattached to the view so we don't get to reset its state. We could possibly rely on ViewTreeObserver.OnPreDrawListener to check the state before the view is drawn but it seems more logical to me to clear the siblings when one of them is cleared. https://codereview.chromium.org/2635993002/diff/1/chrome/android/java/src/org... chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/NewTabPageRecyclerView.java:717: // parent implementation. (by default it changes the translation-X and elevation) On 2017/01/17 16:59:36, Bernhard Bauer wrote: > In this CL we change the code so we do call the super implementation. Why is > that? Does the comment need to be updated? No particular reason, mostly forgot to remove it. I added that in case some internal state that wasn't consistent was the reason for the observed bugs, but it doesn't seem to address them.
https://codereview.chromium.org/2635993002/diff/1/chrome/android/java/src/org... File chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/NewTabPageRecyclerView.java (right): https://codereview.chromium.org/2635993002/diff/1/chrome/android/java/src/org... chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/NewTabPageRecyclerView.java:671: NewTabPageViewHolder sibling = ((SiblingViewHolder) viewHolder).getSibling(); On 2017/01/17 17:34:29, dgn wrote: > On 2017/01/17 16:59:36, Bernhard Bauer wrote: > > On 2017/01/17 16:09:01, dgn wrote: > > > On 2017/01/17 15:36:59, Bernhard Bauer wrote: > > > > Why does getNewTabPageAdapter().getDismissSibling(viewHolder) not work > here? > > > > > > > > In general, we seem to be tying ourselves very much to the notion that > each > > > item > > > > has at most one sibling, which seems a bit arbitrary. I have a CL that > > > > generalizes this to a set of items that get dismissed together, which > > > simplifies > > > > quite a bit of code: https://codereview.chromium.org/2617133002/. > > > > > > Because as far as the adapter is concerned, the item does not exist anymore, > > so > > > it can't return a sibling for it. I don't think your patch would address > that, > > > since it's still based on the state of the adapter and the tree. > > > > Okay, so there are two things here we could do: > > 1) If we need to keep track of siblings even after an item has been removed > from > > the adapter, we can do that, but there is no need to abuse the class hierarchy > > for that :) If our view holders can have optional siblings, that functionality > > can live in NewTabPageViewHolder without requiring a subclass. Then with my > > change we can just change the sibling reference to a sibling set. > > good point > > > 2) Why do we need to reset the displacement in the first place? Just so that > the > > state is correct when the view is recycled? In that case, could we just do > that > > when we bind the ViewHolder? > > The problem is that in this case the view is not recycled. We only remove the > status card but keep the action item. So it is not rebound nor reattached to the > view so we don't get to reset its state. We could possibly rely on > ViewTreeObserver.OnPreDrawListener to check the state before the view is drawn > but it seems more logical to me to clear the siblings when one of them is > cleared. > Can you explain that a bit more? When would we dismiss the status card but not the action item?
Description was changed from
==========
[NTP Client] Reset the state of sibling when one is dismissed
ActionItem and StatusItem can be sibling when they are next to
each other. In that case, they are dismissed together but the
event fired when interaction with them is complete (clearView)
only triggers on the item interacted with, and the sibling doesnt
know when it should reset its state. This patch makes the siblings
aware of each other so that the event can be propagated.
BUG=None
==========
to
==========
[NTP Client] Reset the view for items that stop being dismissable
Notifies view holders that they need to reset the state of the view
when the dismissability changes, as if they were being modified by
a swipe to dismiss, they would keep the related property changes
(esp. alpha modification)
BUG=None
==========
PTAL On 2017/01/18 12:31:49, Bernhard Bauer wrote: > Can you explain that a bit more? When would we dismiss the status card but not > the action item? That's when the card is removed because of new suggestions coming in. So we don't go through #dismissItem(), it's the refreshChildrenVisibility() call that removes the status card.
https://codereview.chromium.org/2635993002/diff/60001/chrome/android/java/src... File chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/ActionItem.java (right): https://codereview.chromium.org/2635993002/diff/60001/chrome/android/java/src... chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/ActionItem.java:59: boolean newDismissability = !mParentSection.hasSuggestions(); Do we want to check here whether section dismissal is enabled in SnippetsConfig (instead of below)? https://codereview.chromium.org/2635993002/diff/60001/chrome/android/java/src... File chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/NewTabPageAdapter.java (right): https://codereview.chromium.org/2635993002/diff/60001/chrome/android/java/src... chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/NewTabPageAdapter.java:164: case PartialUpdateId.RESET_DISMISS_STATE: Uh, do we actually trigger this anywhere? Should the notifyItemChanged() call in ActionItem use this as a payload?
The CQ bit was checked by dgn@chromium.org to run a CQ dry run
Dry run: CQ is trying da patch. Follow status at https://chromium-cq-status.appspot.com/v2/patch-status/codereview.chromium.or...
Description was changed from
==========
[NTP Client] Reset the view for items that stop being dismissable
Notifies view holders that they need to reset the state of the view
when the dismissability changes, as if they were being modified by
a swipe to dismiss, they would keep the related property changes
(esp. alpha modification)
BUG=None
==========
to
==========
[NTP Client] Reset ActionItem view properties along visibility updates.
A section's ActionItem can be altered during a swipe to dismiss, but
its state is not properly cleared when new suggestions are added at
that same time. This patch fixes that by issuing a partial update
request on significant suggestion count changes.
BUG=None
==========
PTAL https://codereview.chromium.org/2635993002/diff/60001/chrome/android/java/src... File chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/ActionItem.java (right): https://codereview.chromium.org/2635993002/diff/60001/chrome/android/java/src... chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/ActionItem.java:59: boolean newDismissability = !mParentSection.hasSuggestions(); On 2017/01/27 12:01:57, Bernhard Bauer wrote: > Do we want to check here whether section dismissal is enabled in SnippetsConfig > (instead of below)? Removed it, as it's done by dismissgroup now. https://codereview.chromium.org/2635993002/diff/60001/chrome/android/java/src... File chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/NewTabPageAdapter.java (right): https://codereview.chromium.org/2635993002/diff/60001/chrome/android/java/src... chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/NewTabPageAdapter.java:164: case PartialUpdateId.RESET_DISMISS_STATE: On 2017/01/27 12:01:57, Bernhard Bauer wrote: > Uh, do we actually trigger this anywhere? Should the notifyItemChanged() call in > ActionItem use this as a payload? Rebase gone wrong. Fixed.
The CQ bit was unchecked by commit-bot@chromium.org
Dry run: This issue passed the CQ dry run.
https://codereview.chromium.org/2635993002/diff/80001/chrome/android/java/src... File chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/SuggestionsSection.java (right): https://codereview.chromium.org/2635993002/diff/80001/chrome/android/java/src... chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/SuggestionsSection.java:256: if (newSuggestionsCount > 0 && suggestionCountDelta < 0) return; This condition is stronger than the previous one, so if it is fulfilled, the previous one would have already returned.
The CQ bit was checked by dgn@chromium.org to run a CQ dry run
Dry run: CQ is trying da patch. Follow status at https://chromium-cq-status.appspot.com/v2/patch-status/codereview.chromium.or...
The CQ bit was unchecked by commit-bot@chromium.org
Dry run: Try jobs failed on following builders: android_n5x_swarming_rel on master.tryserver.chromium.android (JOB_FAILED, https://build.chromium.org/p/tryserver.chromium.android/builders/android_n5x_...)
The CQ bit was checked by dgn@chromium.org to run a CQ dry run
Dry run: CQ is trying da patch. Follow status at https://chromium-cq-status.appspot.com/v2/patch-status/codereview.chromium.or...
PTAL https://codereview.chromium.org/2635993002/diff/80001/chrome/android/java/src... File chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/SuggestionsSection.java (right): https://codereview.chromium.org/2635993002/diff/80001/chrome/android/java/src... chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/SuggestionsSection.java:256: if (newSuggestionsCount > 0 && suggestionCountDelta < 0) return; On 2017/02/01 15:56:28, Bernhard Bauer wrote: > This condition is stronger than the previous one, so if it is fulfilled, the > previous one would have already returned. Oh true. These conditions don't even check what the comments say. The first check works still, updated the attached comment.
The CQ bit was unchecked by commit-bot@chromium.org
Dry run: This issue passed the CQ dry run.
lgtm - and do you have a bug number for this?
https://codereview.chromium.org/2635993002/diff/140001/chrome/android/java/sr... File chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/SuggestionsSection.java (right): https://codereview.chromium.org/2635993002/diff/140001/chrome/android/java/sr... chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/SuggestionsSection.java:119: // away through onItemFoo() calls since the parent node is not set. But at this point only the parent of the SuggestionsSection isn't set yet -- the children should have their parent set to this object, no?
The CQ bit was checked by dgn@chromium.org to run a CQ dry run
Dry run: CQ is trying da patch. Follow status at https://chromium-cq-status.appspot.com/v2/patch-status/codereview.chromium.or...
Description was changed from ========== [NTP Client] Reset ActionItem view properties along visibility updates. A section's ActionItem can be altered during a swipe to dismiss, but its state is not properly cleared when new suggestions are added at that same time. This patch fixes that by issuing a partial update request on significant suggestion count changes. BUG=None ========== to ========== [NTP Client] Reset ActionItem view properties along visibility updates. A section's ActionItem can be altered during a swipe to dismiss, but its state is not properly cleared when new suggestions are added at that same time. This patch fixes that by issuing a partial update request on significant suggestion count changes. BUG=687977 ==========
The CQ bit was unchecked by commit-bot@chromium.org
Dry run: This issue passed the CQ dry run.
The CQ bit was checked by dgn@chromium.org to run a CQ dry run
Dry run: CQ is trying da patch. Follow status at https://chromium-cq-status.appspot.com/v2/patch-status/codereview.chromium.or...
The CQ bit was checked by dgn@chromium.org to run a CQ dry run
Dry run: CQ is trying da patch. Follow status at https://chromium-cq-status.appspot.com/v2/patch-status/codereview.chromium.or...
PTAL https://codereview.chromium.org/2635993002/diff/140001/chrome/android/java/sr... File chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/SuggestionsSection.java (right): https://codereview.chromium.org/2635993002/diff/140001/chrome/android/java/sr... chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/SuggestionsSection.java:119: // away through onItemFoo() calls since the parent node is not set. On 2017/02/02 14:11:32, Bernhard Bauer wrote: > But at this point only the parent of the SuggestionsSection isn't set yet -- the > children should have their parent set to this object, no? as discussed offline, the notification is on the section itself, so the parent is not set. Replaced with setting the visibility directly.
lgtm https://codereview.chromium.org/2635993002/diff/200001/chrome/android/java/sr... File chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/CardViewHolder.java (right): https://codereview.chromium.org/2635993002/diff/200001/chrome/android/java/sr... chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/CardViewHolder.java:362: private static class ResetForDismissCallback extends PartialBindCallback { Why don't we just move this to NewTabPageRecyclerView?
https://codereview.chromium.org/2635993002/diff/200001/chrome/android/java/sr... File chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/CardViewHolder.java (right): https://codereview.chromium.org/2635993002/diff/200001/chrome/android/java/sr... chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/CardViewHolder.java:362: private static class ResetForDismissCallback extends PartialBindCallback { On 2017/02/02 16:30:23, Bernhard Bauer wrote: > Why don't we just move this to NewTabPageRecyclerView? We care about this only for cards at the moment, and I don't see much advantage in adding it to that interface.
https://codereview.chromium.org/2635993002/diff/200001/chrome/android/java/sr... File chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/CardViewHolder.java (right): https://codereview.chromium.org/2635993002/diff/200001/chrome/android/java/sr... chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/CardViewHolder.java:362: private static class ResetForDismissCallback extends PartialBindCallback { On 2017/02/02 16:34:26, dgn wrote: > On 2017/02/02 16:30:23, Bernhard Bauer wrote: > > Why don't we just move this to NewTabPageRecyclerView? > > We care about this only for cards at the moment, and I don't see much advantage > in adding it to that interface. We end up in the RecyclerView anyway (which now also has its public API surface increased, because you make updateViewStateForDismiss() public.
The CQ bit was checked by dgn@chromium.org to run a CQ dry run
Dry run: CQ is trying da patch. Follow status at https://chromium-cq-status.appspot.com/v2/patch-status/codereview.chromium.or...
PTAL https://codereview.chromium.org/2635993002/diff/200001/chrome/android/java/sr... File chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/CardViewHolder.java (right): https://codereview.chromium.org/2635993002/diff/200001/chrome/android/java/sr... chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/CardViewHolder.java:362: private static class ResetForDismissCallback extends PartialBindCallback { On 2017/02/02 16:44:33, Bernhard Bauer wrote: > On 2017/02/02 16:34:26, dgn wrote: > > On 2017/02/02 16:30:23, Bernhard Bauer wrote: > > > Why don't we just move this to NewTabPageRecyclerView? > > > > We care about this only for cards at the moment, and I don't see much > advantage > > in adding it to that interface. > > We end up in the RecyclerView anyway (which now also has its public API surface > increased, because you make updateViewStateForDismiss() public. I was thinking NewTabPageViewHolder sorry. Tired today :/ Done.
The CQ bit was unchecked by dgn@chromium.org
The CQ bit was checked by dgn@chromium.org
The patchset sent to the CQ was uploaded after l-g-t-m from mvanouwerkerk@chromium.org, bauerb@chromium.org Link to the patchset: https://codereview.chromium.org/2635993002/#ps240001 (title: "Move callback to recyclerview")
CQ is trying da patch. Follow status at https://chromium-cq-status.appspot.com/v2/patch-status/codereview.chromium.or...
CQ is committing da patch.
Bot data: {"patchset_id": 240001, "attempt_start_ts": 1486058358982600,
"parent_rev": "91ce1ab1209aaec1750eb1c1c3b77d606333abe1", "commit_rev":
"6dd2506d48693bae425b7d37a8fc0fb21e0340e4"}
Message was sent while issue was closed.
Description was changed from ========== [NTP Client] Reset ActionItem view properties along visibility updates. A section's ActionItem can be altered during a swipe to dismiss, but its state is not properly cleared when new suggestions are added at that same time. This patch fixes that by issuing a partial update request on significant suggestion count changes. BUG=687977 ========== to ========== [NTP Client] Reset ActionItem view properties along visibility updates. A section's ActionItem can be altered during a swipe to dismiss, but its state is not properly cleared when new suggestions are added at that same time. This patch fixes that by issuing a partial update request on significant suggestion count changes. BUG=687977 Review-Url: https://codereview.chromium.org/2635993002 Cr-Commit-Position: refs/heads/master@{#447808} Committed: https://chromium.googlesource.com/chromium/src/+/6dd2506d48693bae425b7d37a8fc... ==========
Message was sent while issue was closed.
Committed patchset #13 (id:240001) as https://chromium.googlesource.com/chromium/src/+/6dd2506d48693bae425b7d37a8fc... |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
