Reland "[WebLayer] Change the return type of Fragment.getActivity() to Activity."
This is a reland of ae52b2a4a4f3fdf121619fc62f300883b610bd46 with fixes
for robolectric tests, which run on the JVM which appears to have
stricter verification checks.
Original change's description:
> [WebLayer] Change the return type of Fragment.getActivity() to Activity.
>
> This CL adds the ability to specify a script in an android_aar_prebuilt
> rule that can modify prebuilt jar files, and adds a script to change
> Fragment.getActivity() and Fragment.requireActivity() to return an
> Activity instead of a FragmentActivity.
>
> This is the first CL in a chain that will allow us to remove the fake
> activity we create when embedding Fragments that cross classloader
> boundaries.
>
> Bug: 1123216
> Change-Id: I4b9d3ca5f9c3a4d86e08d64f49d601c08fca9a70
> Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2432413
> Reviewed-by: Theresa <[email protected]>
> Reviewed-by: Andrew Grieve <[email protected]>
> Commit-Queue: Robbie McElrath <[email protected]>
> Cr-Commit-Position: refs/heads/master@{#823582}
Bug: 1123216
Change-Id: I83ed0c47cda12e4a71ed90cc0bce4cde2a07782d
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2521343
Reviewed-by: Andrew Grieve <[email protected]>
Reviewed-by: Theresa <[email protected]>
Commit-Queue: Robbie McElrath <[email protected]>
Cr-Commit-Position: refs/heads/master@{#826944}
diff --git a/PRESUBMIT.py b/PRESUBMIT.py
index dec3bd3..0b09333e 100644
--- a/PRESUBMIT.py
+++ b/PRESUBMIT.py
@@ -1306,6 +1306,7 @@
'build/android/gyp/apkbuilder.pydeps',
'build/android/gyp/assert_static_initializers.pydeps',
'build/android/gyp/bytecode_processor.pydeps',
+ 'build/android/gyp/bytecode_rewriter.pydeps',
'build/android/gyp/compile_java.pydeps',
'build/android/gyp/compile_resources.pydeps',
'build/android/gyp/copy_ex.pydeps',
diff --git a/build/android/bytecode/BUILD.gn b/build/android/bytecode/BUILD.gn
index 4d29aca..b56f341 100644
--- a/build/android/bytecode/BUILD.gn
+++ b/build/android/bytecode/BUILD.gn
@@ -18,3 +18,17 @@
wrapper_script_name = "helper/bytecode_processor"
enable_bytecode_checks = false
}
+
+java_binary("fragment_activity_replacer") {
+ sources = [
+ "java/org/chromium/bytecode/ByteCodeRewriter.java",
+ "java/org/chromium/bytecode/FragmentActivityReplacer.java",
+ ]
+ main_class = "org.chromium.bytecode.FragmentActivityReplacer"
+ deps = [
+ "//third_party/android_deps:org_ow2_asm_asm_commons_java",
+ "//third_party/android_deps:org_ow2_asm_asm_java",
+ "//third_party/android_deps:org_ow2_asm_asm_util_java",
+ ]
+ wrapper_script_name = "helper/fragment_activity_replacer"
+}
diff --git a/build/android/bytecode/java/org/chromium/bytecode/ByteCodeRewriter.java b/build/android/bytecode/java/org/chromium/bytecode/ByteCodeRewriter.java
new file mode 100644
index 0000000..3d0d9cdd
--- /dev/null
+++ b/build/android/bytecode/java/org/chromium/bytecode/ByteCodeRewriter.java
@@ -0,0 +1,91 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.bytecode;
+
+import org.objectweb.asm.ClassReader;
+import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.ClassWriter;
+
+import java.io.BufferedInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipInputStream;
+import java.util.zip.ZipOutputStream;
+
+/**
+ * Base class for scripts that perform bytecode modifications on a jar file.
+ */
+public abstract class ByteCodeRewriter {
+ private static final String CLASS_FILE_SUFFIX = ".class";
+
+ public void rewrite(File inputJar, File outputJar) throws IOException {
+ if (!inputJar.exists()) {
+ throw new FileNotFoundException("Input jar not found: " + inputJar.getPath());
+ }
+ try (InputStream inputStream = new BufferedInputStream(new FileInputStream(inputJar))) {
+ try (OutputStream outputStream = new FileOutputStream(outputJar)) {
+ processZip(inputStream, outputStream);
+ }
+ }
+ }
+
+ /** Returns true if the class at the given path in the archive should be rewritten. */
+ protected abstract boolean shouldRewriteClass(String classPath);
+
+ /**
+ * Returns the ClassVisitor that should be used to modify the bytecode of class at the given
+ * path in the archive.
+ */
+ protected abstract ClassVisitor getClassVisitorForClass(
+ String classPath, ClassVisitor delegate);
+
+ private void processZip(InputStream inputStream, OutputStream outputStream) {
+ try (ZipOutputStream zipOutputStream = new ZipOutputStream(outputStream)) {
+ ZipInputStream zipInputStream = new ZipInputStream(inputStream);
+ ZipEntry entry;
+ while ((entry = zipInputStream.getNextEntry()) != null) {
+ ByteArrayOutputStream buffer = new ByteArrayOutputStream();
+ boolean handled = processClassEntry(entry, zipInputStream, buffer);
+ if (handled) {
+ ZipEntry newEntry = new ZipEntry(entry.getName());
+ zipOutputStream.putNextEntry(newEntry);
+ zipOutputStream.write(buffer.toByteArray(), 0, buffer.size());
+ } else {
+ zipOutputStream.putNextEntry(entry);
+ zipInputStream.transferTo(zipOutputStream);
+ }
+ }
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ private boolean processClassEntry(
+ ZipEntry entry, InputStream inputStream, OutputStream outputStream) {
+ if (!entry.getName().endsWith(CLASS_FILE_SUFFIX) || !shouldRewriteClass(entry.getName())) {
+ return false;
+ }
+ try {
+ ClassReader reader = new ClassReader(inputStream);
+ ClassWriter writer = new ClassWriter(reader, ClassWriter.COMPUTE_FRAMES);
+ ClassVisitor classVisitor = getClassVisitorForClass(entry.getName(), writer);
+ reader.accept(classVisitor, ClassReader.EXPAND_FRAMES);
+
+ writer.visitEnd();
+ byte[] classData = writer.toByteArray();
+ outputStream.write(classData, 0, classData.length);
+ return true;
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+}
diff --git a/build/android/bytecode/java/org/chromium/bytecode/FragmentActivityReplacer.java b/build/android/bytecode/java/org/chromium/bytecode/FragmentActivityReplacer.java
new file mode 100644
index 0000000..2199588b1
--- /dev/null
+++ b/build/android/bytecode/java/org/chromium/bytecode/FragmentActivityReplacer.java
@@ -0,0 +1,119 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.bytecode;
+
+import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.commons.MethodRemapper;
+import org.objectweb.asm.commons.Remapper;
+
+import java.io.File;
+import java.io.IOException;
+
+/**
+ * Java application that modifies Fragment.getActivity() to return an Activity instead of a
+ * FragmentActivity, and updates any existing getActivity() calls to reference the updated method.
+ *
+ * See crbug.com/1144345 for more context.
+ */
+public class FragmentActivityReplacer extends ByteCodeRewriter {
+ private static final String FRAGMENT_CLASS_PATH = "androidx/fragment/app/Fragment.class";
+ private static final String FRAGMENT_ACTIVITY_INTERNAL_CLASS_NAME =
+ "androidx/fragment/app/FragmentActivity";
+ private static final String ACTIVITY_INTERNAL_CLASS_NAME = "android/app/Activity";
+ private static final String GET_ACTIVITY_METHOD_NAME = "getActivity";
+ private static final String REQUIRE_ACTIVITY_METHOD_NAME = "requireActivity";
+ private static final String OLD_METHOD_DESCRIPTOR =
+ "()Landroidx/fragment/app/FragmentActivity;";
+ private static final String NEW_METHOD_DESCRIPTOR = "()Landroid/app/Activity;";
+
+ public static void main(String[] args) throws IOException {
+ // Invoke this script using //build/android/gyp/bytecode_processor.py
+ if (args.length != 2) {
+ System.err.println("Expected 2 arguments: [input.jar] [output.jar]");
+ System.exit(1);
+ }
+
+ FragmentActivityReplacer rewriter = new FragmentActivityReplacer();
+ rewriter.rewrite(new File(args[0]), new File(args[1]));
+ }
+
+ @Override
+ protected boolean shouldRewriteClass(String classPath) {
+ return true;
+ }
+
+ @Override
+ protected ClassVisitor getClassVisitorForClass(String classPath, ClassVisitor delegate) {
+ ClassVisitor getActivityReplacer = new GetActivityReplacer(delegate);
+ if (classPath.equals(FRAGMENT_CLASS_PATH)) {
+ return new FragmentClassVisitor(getActivityReplacer);
+ }
+ return getActivityReplacer;
+ }
+
+ /** Updates any Fragment.getActivity/requireActivity() calls to call the replaced method. */
+ private static class GetActivityReplacer extends ClassVisitor {
+ private GetActivityReplacer(ClassVisitor baseVisitor) {
+ super(Opcodes.ASM7, baseVisitor);
+ }
+
+ @Override
+ public MethodVisitor visitMethod(
+ int access, String name, String descriptor, String signature, String[] exceptions) {
+ MethodVisitor base = super.visitMethod(access, name, descriptor, signature, exceptions);
+ return new MethodVisitor(Opcodes.ASM7, base) {
+ @Override
+ public void visitMethodInsn(int opcode, String owner, String name,
+ String descriptor, boolean isInterface) {
+ if ((opcode == Opcodes.INVOKEVIRTUAL || opcode == Opcodes.INVOKESPECIAL)
+ && descriptor.equals(OLD_METHOD_DESCRIPTOR)
+ && (name.equals(GET_ACTIVITY_METHOD_NAME)
+ || name.equals(REQUIRE_ACTIVITY_METHOD_NAME))) {
+ super.visitMethodInsn(
+ opcode, owner, name, NEW_METHOD_DESCRIPTOR, isInterface);
+ } else {
+ super.visitMethodInsn(opcode, owner, name, descriptor, isInterface);
+ }
+ }
+ };
+ }
+ }
+
+ /**
+ * Makes Fragment.getActivity() and Fragment.requireActivity() non-final, and changes their
+ * return types to Activity.
+ */
+ private static class FragmentClassVisitor extends ClassVisitor {
+ private FragmentClassVisitor(ClassVisitor baseVisitor) {
+ super(Opcodes.ASM7, baseVisitor);
+ }
+
+ @Override
+ public MethodVisitor visitMethod(
+ int access, String name, String descriptor, String signature, String[] exceptions) {
+ MethodVisitor base;
+ // Update the descriptor of getActivity/requireActivity, and make them non-final.
+ if (name.equals(GET_ACTIVITY_METHOD_NAME)
+ || name.equals(REQUIRE_ACTIVITY_METHOD_NAME)) {
+ base = super.visitMethod(
+ access & ~Opcodes.ACC_FINAL, name, NEW_METHOD_DESCRIPTOR, null, exceptions);
+ } else {
+ base = super.visitMethod(access, name, descriptor, signature, exceptions);
+ }
+
+ return new MethodRemapper(base, new Remapper() {
+ @Override
+ public String mapType(String internalName) {
+ if (internalName.equals(FRAGMENT_ACTIVITY_INTERNAL_CLASS_NAME)) {
+ return ACTIVITY_INTERNAL_CLASS_NAME;
+ }
+ return internalName;
+ }
+ });
+ }
+ }
+}
diff --git a/build/android/gyp/bytecode_rewriter.py b/build/android/gyp/bytecode_rewriter.py
new file mode 100755
index 0000000..b37ef6f
--- /dev/null
+++ b/build/android/gyp/bytecode_rewriter.py
@@ -0,0 +1,37 @@
+#!/usr/bin/env python
+# Copyright 2020 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+"""Wrapper script around ByteCodeRewriter subclass scripts."""
+
+import argparse
+import sys
+
+from util import build_utils
+
+
+def main(argv):
+ argv = build_utils.ExpandFileArgs(argv[1:])
+ parser = argparse.ArgumentParser()
+ build_utils.AddDepfileOption(parser)
+ parser.add_argument('--script',
+ required=True,
+ help='Path to the java binary wrapper script.')
+ parser.add_argument('--classpath', action='append', nargs='+')
+ parser.add_argument('--input-jar', required=True)
+ parser.add_argument('--output-jar', required=True)
+ args = parser.parse_args(argv)
+
+ classpath = build_utils.ParseGnList(args.classpath)
+ build_utils.WriteDepfile(args.depfile, args.output_jar, inputs=classpath)
+
+ classpath.append(args.input_jar)
+ cmd = [
+ args.script, '--classpath', ':'.join(classpath), args.input_jar,
+ args.output_jar
+ ]
+ build_utils.CheckOutput(cmd, print_stdout=True)
+
+
+if __name__ == '__main__':
+ sys.exit(main(sys.argv))
diff --git a/build/android/gyp/bytecode_rewriter.pydeps b/build/android/gyp/bytecode_rewriter.pydeps
new file mode 100644
index 0000000..b8f304a
--- /dev/null
+++ b/build/android/gyp/bytecode_rewriter.pydeps
@@ -0,0 +1,6 @@
+# Generated by running:
+# build/print_python_deps.py --root build/android/gyp --output build/android/gyp/bytecode_rewriter.pydeps build/android/gyp/bytecode_rewriter.py
+../../gn_helpers.py
+bytecode_rewriter.py
+util/__init__.py
+util/build_utils.py
diff --git a/build/config/android/internal_rules.gni b/build/config/android/internal_rules.gni
index e4468d8..f79f26ef 100644
--- a/build/config/android/internal_rules.gni
+++ b/build/config/android/internal_rules.gni
@@ -3982,8 +3982,56 @@
}
} # _has_sources
- # TODO(crbug.com/1123216): Implement bytecode_rewriter_target.
- not_needed(invoker, [ "bytecode_rewriter_target" ])
+ if (_is_prebuilt || _build_device_jar || _build_host_jar) {
+ _unprocessed_jar_deps = _full_classpath_deps
+ if (_has_sources) {
+ _unprocessed_jar_deps += [ ":$_compile_java_target" ]
+ }
+ }
+
+ if (defined(invoker.bytecode_rewriter_target)) {
+ assert(_build_host_jar || _build_device_jar,
+ "A host or device jar must be created to use bytecode rewriting")
+
+ _rewritten_jar =
+ string_replace(_unprocessed_jar_path, ".jar", "_rewritten.jar")
+ _rewritten_jar_target_name = "${target_name}__rewritten"
+ _rewriter_path = root_build_dir + "/bin/helper/" +
+ get_label_info(invoker.bytecode_rewriter_target, "name")
+ _rebased_build_config = rebase_path(_build_config, root_build_dir)
+ action_with_pydeps(_rewritten_jar_target_name) {
+ script = "//build/android/gyp/bytecode_rewriter.py"
+ inputs = [
+ _rewriter_path,
+ _build_config,
+ _unprocessed_jar_path,
+ ]
+ outputs = [ _rewritten_jar ]
+ depfile = "$target_gen_dir/$target_name.d"
+ args = [
+ "--depfile",
+ rebase_path(depfile, root_build_dir),
+ "--script",
+ rebase_path(_rewriter_path, root_build_dir),
+ "--classpath",
+ "@FileArg($_rebased_build_config:deps_info:javac_full_classpath)",
+ "--classpath",
+ "@FileArg($_rebased_build_config:android:sdk_jars)",
+ "--input-jar",
+ rebase_path(_unprocessed_jar_path, root_build_dir),
+ "--output-jar",
+ rebase_path(_rewritten_jar, root_build_dir),
+ ]
+ deps = _unprocessed_jar_deps + [
+ ":$_build_config_target_name",
+ invoker.bytecode_rewriter_target,
+ ]
+ }
+
+ _unprocessed_jar_deps = []
+ _unprocessed_jar_deps = [ ":$_rewritten_jar_target_name" ]
+ _unprocessed_jar_path = _rewritten_jar
+ }
if (_is_prebuilt) {
generate_interface_jar(_header_target_name) {
@@ -3998,10 +4046,7 @@
# target. If we can change compile & desugar steps to use direct
# interface classpath rather than full interface classpath, then this
# could just be _non_java_deps.
- deps = _classpath_deps
- if (_has_sources) {
- deps += [ ":$_compile_java_target" ]
- }
+ deps = _unprocessed_jar_deps
}
_public_deps += [ ":$_header_target_name" ]
}
@@ -4017,10 +4062,7 @@
build_config = _build_config
build_config_dep = ":$_build_config_target_name"
input_jar_path = _unprocessed_jar_path
- jar_deps = _non_java_deps
- if (_has_sources) {
- jar_deps += [ ":$_compile_java_target" ]
- }
+ jar_deps = _unprocessed_jar_deps
if (_build_host_jar) {
host_jar_path = _host_processed_jar_path
}
@@ -4063,10 +4105,7 @@
_bytecode_checks_target = "${target_name}__validate_classpath"
bytecode_processor(_bytecode_checks_target) {
forward_variables_from(invoker, [ "missing_classes_allowlist" ])
- deps = _full_classpath_deps
- if (_has_sources) {
- deps += [ ":$_compile_java_target" ]
- }
+ deps = _unprocessed_jar_deps + [ ":$_build_config_target_name" ]
requires_android = _requires_android
target_label =
get_label_info(":${invoker.target_name}", "label_no_toolchain")
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunFragment.java b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunFragment.java
index baeda336..3d57b546 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunFragment.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunFragment.java
@@ -4,7 +4,7 @@
package org.chromium.chrome.browser.firstrun;
-import androidx.fragment.app.FragmentActivity;
+import android.app.Activity;
/**
* This interface is implemented by FRE fragments.
@@ -25,7 +25,7 @@
/**
* @see Fragment#getActivity().
*/
- FragmentActivity getActivity();
+ Activity getActivity();
/**
* Set the a11y focus when the fragment is shown on the screen.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/password_manager/settings/PasswordEntryEditor.java b/chrome/android/java/src/org/chromium/chrome/browser/password_manager/settings/PasswordEntryEditor.java
index bbb98097..d2782bf 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/password_manager/settings/PasswordEntryEditor.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/password_manager/settings/PasswordEntryEditor.java
@@ -141,8 +141,7 @@
}
mPendingAction = action;
ReauthenticationManager.displayReauthenticationFragment(reasonString, View.NO_ID,
- getActivity().getSupportFragmentManager(),
- ReauthenticationManager.ReauthScope.ONE_AT_A_TIME);
+ getParentFragmentManager(), ReauthenticationManager.ReauthScope.ONE_AT_A_TIME);
}
@Override
@@ -150,4 +149,4 @@
super.onDestroy();
PasswordEditingDelegateProvider.getInstance().getPasswordEditingDelegate().destroy();
}
-}
\ No newline at end of file
+}
diff --git a/chrome/browser/webauthn/android/java/src/org/chromium/chrome/browser/webauthn/CableAuthenticatorModuleProvider.java b/chrome/browser/webauthn/android/java/src/org/chromium/chrome/browser/webauthn/CableAuthenticatorModuleProvider.java
index 3e3796e..9c8f685 100644
--- a/chrome/browser/webauthn/android/java/src/org/chromium/chrome/browser/webauthn/CableAuthenticatorModuleProvider.java
+++ b/chrome/browser/webauthn/android/java/src/org/chromium/chrome/browser/webauthn/CableAuthenticatorModuleProvider.java
@@ -84,8 +84,7 @@
private void showModule() {
mStatus.setText("Installed.");
- FragmentTransaction transaction =
- getActivity().getSupportFragmentManager().beginTransaction();
+ FragmentTransaction transaction = getParentFragmentManager().beginTransaction();
Fragment fragment = Cablev2AuthenticatorModule.getImpl().getFragment();
Bundle arguments = getArguments();
if (arguments == null) {
diff --git a/third_party/android_deps/BUILD.gn b/third_party/android_deps/BUILD.gn
index 01850286..eca9299 100644
--- a/third_party/android_deps/BUILD.gn
+++ b/third_party/android_deps/BUILD.gn
@@ -366,6 +366,9 @@
jar_excluded_patterns = [ "androidx/fragment/app/DialogFragment*" ]
ignore_proguard_configs = true
+
+ bytecode_rewriter_target =
+ "//build/android/bytecode:fragment_activity_replacer"
}
# This is generated, do not edit. Update BuildConfigGenerator.groovy instead.
@@ -577,6 +580,8 @@
"androidx/preference/PreferenceFragmentCompat*",
]
+ bytecode_rewriter_target =
+ "//build/android/bytecode:fragment_activity_replacer"
ignore_proguard_configs = true
}
diff --git a/third_party/android_deps/buildSrc/src/main/groovy/BuildConfigGenerator.groovy b/third_party/android_deps/buildSrc/src/main/groovy/BuildConfigGenerator.groovy
index f83c1f95..e88767d 100644
--- a/third_party/android_deps/buildSrc/src/main/groovy/BuildConfigGenerator.groovy
+++ b/third_party/android_deps/buildSrc/src/main/groovy/BuildConfigGenerator.groovy
@@ -354,6 +354,8 @@
| ]
|
| ignore_proguard_configs = true
+ |
+ | bytecode_rewriter_target = "//build/android/bytecode:fragment_activity_replacer"
|""".stripMargin())
break
case 'androidx_media_media':
@@ -496,6 +498,7 @@
| "androidx/preference/PreferenceFragmentCompat*",
| ]
|
+ | bytecode_rewriter_target = "//build/android/bytecode:fragment_activity_replacer"
|""".stripMargin())
// Replace broad library -keep rules with a more limited set in
// chrome/android/java/proguard.flags instead.
diff --git a/third_party/android_deps/local_modifications/androidx_preference_preference/README b/third_party/android_deps/local_modifications/androidx_preference_preference/README
index f4fb51c..697cd14 100644
--- a/third_party/android_deps/local_modifications/androidx_preference_preference/README
+++ b/third_party/android_deps/local_modifications/androidx_preference_preference/README
@@ -1,8 +1,8 @@
This directory contains PreferenceFragmentCompat.java and
PreferenceDialogFragmentCompat.java, copied without changes from the AndroidX
-preference library at commit beeb6fb. These files contain two changes (commits
-72c0381 and beeb6fb) that we want in Chromium, but are not yet in an official
-preference library release.
+preference library at commit e865a9b. These files contain three changes
+(commits 72c0381, beeb6fb, and e865a9b) that we want in Chromium, but are not
+yet in an official preference library release.
To pull in these changes, we exclude PreferenceFragmentCompat and
PreferenceDialogFragmentCompat from the androidx_preference_preference library
diff --git a/third_party/android_deps/local_modifications/androidx_preference_preference/androidx_preference_preference_java.jar b/third_party/android_deps/local_modifications/androidx_preference_preference/androidx_preference_preference_java.jar
index 201cd50..de88d15 100644
--- a/third_party/android_deps/local_modifications/androidx_preference_preference/androidx_preference_preference_java.jar
+++ b/third_party/android_deps/local_modifications/androidx_preference_preference/androidx_preference_preference_java.jar
Binary files differ
diff --git a/third_party/android_deps/local_modifications/androidx_preference_preference/java/androidx/preference/PreferenceFragmentCompat.java b/third_party/android_deps/local_modifications/androidx_preference_preference/java/androidx/preference/PreferenceFragmentCompat.java
index 1fa26698..5922dfa 100644
--- a/third_party/android_deps/local_modifications/androidx_preference_preference/java/androidx/preference/PreferenceFragmentCompat.java
+++ b/third_party/android_deps/local_modifications/androidx_preference_preference/java/androidx/preference/PreferenceFragmentCompat.java
@@ -61,7 +61,7 @@
*
* <p>To build a hierarchy from code, use
* {@link PreferenceManager#createPreferenceScreen(Context)} to create the root
- * {@link PreferenceScreen}. Once you have added other {@link Preference}s to this root scree
+ * {@link PreferenceScreen}. Once you have added other {@link Preference}s to this root screen
* with {@link PreferenceScreen#addPreference(Preference)}, you then need to set the screen as
* the root screen in your hierarchy with {@link #setPreferenceScreen(PreferenceScreen)}.
*
@@ -420,8 +420,7 @@
+ "implement this method so that you can configure the new "
+ "fragment that will be displayed, and set a transition between "
+ "the fragments.");
- final FragmentManager fragmentManager = requireActivity()
- .getSupportFragmentManager();
+ final FragmentManager fragmentManager = getParentFragmentManager();
final Bundle args = preference.getExtras();
final Fragment fragment = fragmentManager.getFragmentFactory().instantiate(
requireActivity().getClassLoader(), preference.getFragment());
@@ -457,7 +456,7 @@
.onPreferenceStartScreen(this, preferenceScreen);
}
if (!handled && getContext() instanceof OnPreferenceStartScreenCallback) {
- ((OnPreferenceStartScreenCallback) getContext())
+ handled = ((OnPreferenceStartScreenCallback) getContext())
.onPreferenceStartScreen(this, preferenceScreen);
}
// Check the Activity as well in case getContext was overridden to return something other