[go: nahoru, domu]

Fixed the AbstractMethodError issue which happens when proguard is enabled

- Catch the AbstractMethodError additionally so that the app can still get a default ExtensionsManager instance and won't crash.
- Add proguard-rules.pro in camera-extensions module
- Enable proguard for the extension test app.

Relnote: "Fixed the AbstractMethodError issue which happens when proguard is enabled."

Bug: 201177844
Test: ./gradlew camera:camera-extensions:build && ./gradlew camera:camera-extensions:connectedAndroidTest && manual test
Change-Id: Iae4688ef953751255c49eff8dfd205a6df226cbc
diff --git a/camera/camera-extensions/build.gradle b/camera/camera-extensions/build.gradle
index 6feb049..6830280 100644
--- a/camera/camera-extensions/build.gradle
+++ b/camera/camera-extensions/build.gradle
@@ -66,6 +66,10 @@
         minSdkVersion 21
     }
 
+    buildTypes.all {
+        consumerProguardFiles "proguard-rules.pro"
+    }
+
     // Use Robolectric 4.+
     testOptions.unitTests.includeAndroidResources = true
 }
diff --git a/camera/camera-extensions/proguard-rules.pro b/camera/camera-extensions/proguard-rules.pro
new file mode 100644
index 0000000..f468308
--- /dev/null
+++ b/camera/camera-extensions/proguard-rules.pro
@@ -0,0 +1,17 @@
+# Copyright (C) 2020 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.
+
+# Needs to keep the classes implementing the vendor library interfaces in the extensions module.
+# Otherwise, it will cause AbstractMethodError if proguard is enabled.
+-keep class androidx.camera.extensions.ExtensionsManager$** {*;}
diff --git a/camera/camera-extensions/src/main/java/androidx/camera/extensions/ExtensionsManager.java b/camera/camera-extensions/src/main/java/androidx/camera/extensions/ExtensionsManager.java
index 3e74c77..47e658a 100644
--- a/camera/camera-extensions/src/main/java/androidx/camera/extensions/ExtensionsManager.java
+++ b/camera/camera-extensions/src/main/java/androidx/camera/extensions/ExtensionsManager.java
@@ -173,7 +173,7 @@
                                     }
                                 },
                                 CameraXExecutors.directExecutor());
-                    } catch (NoSuchMethodError | NoClassDefFoundError e) {
+                    } catch (NoSuchMethodError | NoClassDefFoundError | AbstractMethodError e) {
                         Logger.e(TAG, "Failed to initialize extensions. Some classes or methods "
                                 + "are missed in the vendor library. " + e);
                         completer.set(getOrCreateExtensionsManager(
diff --git a/camera/integration-tests/extensionstestapp/build.gradle b/camera/integration-tests/extensionstestapp/build.gradle
index a379c83..5ee99c03 100644
--- a/camera/integration-tests/extensionstestapp/build.gradle
+++ b/camera/integration-tests/extensionstestapp/build.gradle
@@ -27,6 +27,13 @@
         versionCode 1
         multiDexEnabled true
     }
+
+    buildTypes.all {
+        minifyEnabled true
+        shrinkResources true
+        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+        testProguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+    }
 }
 
 dependencies {
diff --git a/camera/integration-tests/extensionstestapp/proguard-rules.pro b/camera/integration-tests/extensionstestapp/proguard-rules.pro
new file mode 100644
index 0000000..8f6c13c
--- /dev/null
+++ b/camera/integration-tests/extensionstestapp/proguard-rules.pro
@@ -0,0 +1,14 @@
+-keep class androidx.test.** {*;}
+-keep class androidx.camera.testing.** {*;}
+-keep class androidx.camera.integration.extensions.CameraExtensionsActivity {*;}
+
+-keepclassmembers class androidx.camera.lifecycle.ProcessCameraProvider {
+    ** shutdown();
+}
+
+-keepclassmembers class androidx.camera.extensions.ExtensionsManager {
+    ** shutdown();
+}
+
+-keep class org.junit.** {*;}
+-keep class org.hamcrest.** {*;}