Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Android autoplay #10120

Merged
merged 8 commits into from
Sep 27, 2021
Merged

Android autoplay #10120

merged 8 commits into from
Sep 27, 2021

Conversation

wchen342
Copy link
Contributor

@wchen342 wchen342 commented Sep 16, 2021

Resolves brave/brave-browser/issues/14142.

Submitter Checklist:

  • I confirm that no security/privacy review is needed, or that I have requested one
  • There is a ticket for my issue
  • Used Github auto-closing keywords in the PR description above
  • Wrote a good PR/commit description
  • Added appropriate labels (QA/Yes or QA/No; release-notes/include or release-notes/exclude; OS/...) to the associated issue
  • Checked the PR locally: npm run test -- brave_browser_tests, npm run test -- brave_unit_tests, npm run lint, npm run gn_check, npm run tslint
  • Ran git rebase master (if needed)

Reviewer Checklist:

  • A security review is not needed, or a link to one is included in the PR description
  • New files have MPL-2.0 license header
  • Adequate test coverage exists to prevent regressions
  • Major classes, functions and non-trivial code blocks are well-commented
  • Changes in component dependencies are properly reflected in gn
  • Code follows the style guide
  • Test plan is specified in PR before merging

After-merge Checklist:

Test Plan:

The setting spans multiple places. Test as the following:

  1. Open "Settings - Site settings - Autoplay" and toggle off to "Blocked"
  2. Go to any site with embedded video, make sure the video doesn't play.
  3. Wait until the webpage is fully loaded, then click on the lock icon on the left side of omnibox.
  4. From the popup menu, choose "Permissions - Autoplay", make sure the slide button is at "Blocked"
  5. Toggle the slide button to be "Allowed"
  6. Refresh the page, make sure the video now starts to play on itself
  7. Go back to "Settings - Site settings - Autoplay", make sure an exception is added for the site you just used

@wchen342 wchen342 added CI/skip-linux CI/skip-macos-x64 Do not run CI builds for macOS x64 CI/skip-ios Do not run CI builds for iOS labels Sep 16, 2021
@wchen342 wchen342 requested review from samartnik and a team as code owners September 16, 2021 16:02
@wchen342 wchen342 force-pushed the android_autoplay branch 3 times, most recently from f6b5914 to 4dc765b Compare September 16, 2021 16:13
@@ -159,6 +168,10 @@ private boolean shouldMakePublicMethod(String className, String methodName) {
mMakePublicMethods.entrySet()) {
String entryClassName = entry.getKey();
ArrayList<String> methodNames = entry.getValue();
// Why className.contains(entryClassName)? This seems erroneous
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it seems like we do need to change it to equals. Did you get that warning for any change?

@@ -252,6 +290,20 @@ protected void deleteInnerClass(String outerName, String innerName) {
innerNames.add(innerName);
}

private boolean shouldMakeNonFinalClass(String className) {
int idx = mMakeNonFinalClasses.indexOf(className);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't there contains method for that?

}

return (ResourceItem) BraveReflectionUtil.InvokeMethod(
ContentSettingsResources.class, null, "getResourceItem", int.class, contentType);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you check it in release? We should to allow list it in brave/android/java/proguard.flags. And we should add it to testMethodsForInvocationExist test to check that exact params and return type are not changed.
It applies to all calls via BraveReflectionUtil.InvokeMethod, I just don't want to duplicate this message for all of them.

Copy link
Contributor Author

@wchen342 wchen342 Sep 16, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added those to testMethodsExist but yeah that one doesn't test for parameter types. I will change to testMethodsForInvocationExist.

makePublicMethod(sContentSettingsResourcesClassName, "getResourceItem");
changeMethodOwner(
sContentSettingsResourcesClassName, "getResourceItem", sBraveContentSettingsResourcesClassName);
makePublicInnerClass(sContentSettingsResourcesClassName, "ResourceItem");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to add a test that checks that this inner class is still there.

sContentSettingsResourcesClassName, "getResourceItem", sBraveContentSettingsResourcesClassName);
makePublicInnerClass(sContentSettingsResourcesClassName, "ResourceItem");
redirectConstructor(sBraveContentSettingsResourcesResourceItemClassName, sContentSettingsResourcesResourceItemClassName);
redirectTypeInMethod("getResourceItem", sBraveContentSettingsResourcesResourceItemClassName, sContentSettingsResourcesResourceItemClassName);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to add a test that checks that new type is actually applied.

@@ -15,5 +15,8 @@ public BraveSingleCategorySettingsClassAdapter(ClassVisitor visitor) {
super(visitor);

changeSuperName(sSingleCategorySettingsClassName, sBraveSingleCategorySettingsClassName);
changeMethodOwner(sSingleCategorySettingsClassName, "onOptionsItemSelected", sBraveSingleCategorySettingsClassName);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see unit test for this change.

public BraveSingleWebsiteSettingsClassAdapter(ClassVisitor visitor) {
super(visitor);

changeSuperName(sSingleWebsiteSettingsClassName, sBraveSingleWebsiteSettingsClassName);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to add test to testSuperNames for this.
Generally, just to not duplicate similar message, could you please double check that every change in bytecode has its test in brave/android/javatests/org/chromium/chrome/browser/BytecodeTest.java.

@wchen342 wchen342 requested a review from samartnik September 17, 2021 14:46
@wchen342 wchen342 force-pushed the android_autoplay branch 2 times, most recently from ea3b9bb to 4e6ebda Compare September 21, 2021 13:17
@@ -8,3 +8,26 @@
-keep class org.chromium.chrome.browser.ChromeTabbedActivity {
*** hideOverview(...);
}

-keep class org.chromium.components.browser_ui.site_settings.ContentSettingsResources {
private static *** getResourceItem(...);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should generalize it, as we don't care whether it's private or not. And if they change it, we will simply get crash on trying to invoke it.
Same applies to static, we should add unit test instead to check that it is still static, as they may change it and we will get crash on trying to invoke it.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And we should also add tests that non-static functions remain non-static. As, if they change it in upstream, current tests will pass, but we will get crashes in runtime on trying to invoke them. This applies to hideOverview as well, we overlooked this moment before.

// NOTE: Add new checks above. For each new check in this method add proguard exception in
// `brave/android/java/proguard.flags` file under `Add methods for invocation below`
// section. Both test and regular apks should have the same exceptions.
Assert.assertTrue(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment says to put it all above.

@@ -159,6 +166,10 @@ private boolean shouldMakePublicMethod(String className, String methodName) {
mMakePublicMethods.entrySet()) {
String entryClassName = entry.getKey();
ArrayList<String> methodNames = entry.getValue();
// Why className.contains(entryClassName)? This seems erroneous
if (methodNames.contains(methodName) && className.equals(entryClassName) != className.contains(entryClassName)) {
System.out.println("Warning: class name " + className + " may not be written correctly!");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you get this warning? If not, we just need to change className.contains to className.equals below.

case ContentSettingsType::POPUPS:
case ContentSettingsType::SENSORS:
case ContentSettingsType::SOUND:
+ case ContentSettingsType::AUTOPLAY:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this can be done with a chromium src override
define AUTOMATIC_DOWNLOADS ContentSettingsType::AUTOPLAY: value = CONTENT_SETTINGS_ALLOW; break; AUTOMATIC_DOWNLOADS

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doesn't that still require a patch? Or is it for maintainability in the future?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it does not require a patch and it is extensible unlike this patch. Even if we patched, we wouldn't patch like this because this is not extensible and does not follow the patching guidelines

+ int NUM_ENTRIES = 24;
}

private final BrowserContextHandle mBrowserContextHandle;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe we have a way to replace static method calls with calls to a different method so can do BraveSiteSettingsCategory.contentSettingsType which calls SiteSettingsCategory.contentSettingsType and then checks for autoplay if the return is -1

Copy link
Contributor Author

@wchen342 wchen342 Sep 21, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's what I did with the rest of the java codes but it is impossible to do here because (1) the definition is annotated and to redirect the definition we need to do some very hacky bytecode manipulation (which I am not sure is possible at all), and if the descendant class has values not in the annotation compiler will probably complain too. (2) the value is extensive used in site_settings and some of them are not static, which means I need to do the hack of changing all type definitions in a function body with bytecode on all of them, which IMO is worse than just using a patch.

(I have asked @samartnik and he agree this part is not possible with bytecode).

return "use_storage";
case Type.VIRTUAL_REALITY:
return "virtual_reality";
+ case Type.AUTOPLAY:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same as above

</message>
<message name="IDS_WEBSITE_SETTINGS_ADD_SITE_DESCRIPTION_AUTOPLAY" desc="The description for the allow autoplay of muted videos for website dialog.">
Allow autoplay of muted videos for a specific site.
</message>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did we get the above strings from the old code?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah that's from old version.

return ContentSettingsType.VR;
// case Type.ALL_SITES
// case Type.USE_STORAGE
+ case Type.AUTOPLAY:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

these last two patches can be one line each

@wchen342 wchen342 requested review from a team as code owners September 24, 2021 13:31
@wchen342 wchen342 requested a review from samartnik September 24, 2021 13:35
Copy link
Contributor

@samartnik samartnik left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
CI/skip-ios Do not run CI builds for iOS CI/skip-macos-x64 Do not run CI builds for macOS x64
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Android Autoplay should parity Desktop
5 participants