Don't crash if we can't find a resource

Fixes: 115938517
Test: AppTransitionTests
Change-Id: I774c4e6d8097c26fd2af29e65ee98ae40dad0ba4
diff --git a/services/core/java/com/android/server/wm/AppTransition.java b/services/core/java/com/android/server/wm/AppTransition.java
index 19ff438..bb5a221 100644
--- a/services/core/java/com/android/server/wm/AppTransition.java
+++ b/services/core/java/com/android/server/wm/AppTransition.java
@@ -86,6 +86,7 @@
 import android.content.res.Configuration;
 import android.content.res.ResourceId;
 import android.content.res.Resources;
+import android.content.res.Resources.NotFoundException;
 import android.graphics.Bitmap;
 import android.graphics.Canvas;
 import android.graphics.Color;
@@ -123,6 +124,7 @@
 import android.view.animation.TranslateAnimation;
 
 import com.android.internal.R;
+import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.DumpUtils.Dump;
 import com.android.internal.util.function.pooled.PooledLambda;
 import com.android.server.AttributeCache;
@@ -558,19 +560,19 @@
         }
         resId = updateToTranslucentAnimIfNeeded(resId, transit);
         if (ResourceId.isValid(resId)) {
-            return AnimationUtils.loadAnimation(context, resId);
+            return loadAnimationSafely(context, resId);
         }
         return null;
     }
 
-    Animation loadAnimationRes(LayoutParams lp, int resId) {
+    private Animation loadAnimationRes(LayoutParams lp, int resId) {
         Context context = mContext;
         if (ResourceId.isValid(resId)) {
             AttributeCache.Entry ent = getCachedAnimations(lp);
             if (ent != null) {
                 context = ent.context;
             }
-            return AnimationUtils.loadAnimation(context, resId);
+            return loadAnimationSafely(context, resId);
         }
         return null;
     }
@@ -579,12 +581,22 @@
         if (ResourceId.isValid(resId)) {
             AttributeCache.Entry ent = getCachedAnimations(packageName, resId);
             if (ent != null) {
-                return AnimationUtils.loadAnimation(ent.context, resId);
+                return loadAnimationSafely(ent.context, resId);
             }
         }
         return null;
     }
 
+    @VisibleForTesting
+    Animation loadAnimationSafely(Context context, int resId) {
+        try {
+            return AnimationUtils.loadAnimation(context, resId);
+        } catch (NotFoundException e) {
+            Slog.w(TAG, "Unable to load animation resource", e);
+            return null;
+        }
+    }
+
     private int updateToTranslucentAnimIfNeeded(int anim, int transit) {
         if (transit == TRANSIT_TRANSLUCENT_ACTIVITY_OPEN && anim == R.anim.activity_open_enter) {
             return R.anim.activity_translucent_open_enter;
diff --git a/services/tests/wmtests/src/com/android/server/wm/AppTransitionTests.java b/services/tests/wmtests/src/com/android/server/wm/AppTransitionTests.java
index b91f3ec..6e09167 100644
--- a/services/tests/wmtests/src/com/android/server/wm/AppTransitionTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/AppTransitionTests.java
@@ -23,29 +23,29 @@
 import static android.view.WindowManager.TRANSIT_CRASHING_ACTIVITY_CLOSE;
 import static android.view.WindowManager.TRANSIT_KEYGUARD_GOING_AWAY;
 import static android.view.WindowManager.TRANSIT_KEYGUARD_UNOCCLUDE;
-
+import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.anyBoolean;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
-
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 
 import android.graphics.Rect;
 import android.platform.test.annotations.Presubmit;
 import android.view.Display;
 
-import androidx.test.filters.SmallTest;
-
 import org.junit.Before;
 import org.junit.Test;
 
+import androidx.test.filters.SmallTest;
+
 /**
  * Test class for {@link AppTransition}.
  *
  * Build/Install/Run:
- *  atest FrameworksServicesTests:AppTransitionTests
+ *  atest WmTests:AppTransitionTests
  */
 @SmallTest
 @Presubmit
@@ -167,4 +167,11 @@
         assertFalse(dc1.mOpeningApps.contains(token1));
     }
 
+    @Test
+    public void testLoadAnimationSafely() {
+        DisplayContent dc = createNewDisplay(Display.STATE_ON);
+        assertNull(dc.mAppTransition.loadAnimationSafely(
+                getInstrumentation().getTargetContext(), -1));
+    }
+
 }