summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--api/current.txt5
-rw-r--r--api/test-current.txt1
-rw-r--r--core/java/android/os/StrictMode.java44
-rw-r--r--core/java/android/os/strictmode/NonSdkApiUsedViolation.java28
-rw-r--r--graphics/java/android/graphics/ImageDecoder.java19
-rw-r--r--packages/SystemUI/src/com/android/systemui/SystemUIFactory.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardDismissHandler.java29
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardDismissUtil.java53
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyView.java15
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SmartReplyViewTest.java45
11 files changed, 235 insertions, 9 deletions
diff --git a/api/current.txt b/api/current.txt
index 527d3644435c..08f5d003eefc 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -33160,6 +33160,7 @@ package android.os {
method public android.os.StrictMode.VmPolicy.Builder detectLeakedClosableObjects();
method public android.os.StrictMode.VmPolicy.Builder detectLeakedRegistrationObjects();
method public android.os.StrictMode.VmPolicy.Builder detectLeakedSqlLiteObjects();
+ method public android.os.StrictMode.VmPolicy.Builder detectNonSdkApiUsage();
method public android.os.StrictMode.VmPolicy.Builder detectUntaggedSockets();
method public android.os.StrictMode.VmPolicy.Builder penaltyDeath();
method public android.os.StrictMode.VmPolicy.Builder penaltyDeathOnCleartextNetwork();
@@ -33167,6 +33168,7 @@ package android.os {
method public android.os.StrictMode.VmPolicy.Builder penaltyDropBox();
method public android.os.StrictMode.VmPolicy.Builder penaltyListener(java.util.concurrent.Executor, android.os.StrictMode.OnVmViolationListener);
method public android.os.StrictMode.VmPolicy.Builder penaltyLog();
+ method public android.os.StrictMode.VmPolicy.Builder permitNonSdkApiUsage();
method public android.os.StrictMode.VmPolicy.Builder setClassInstanceLimit(java.lang.Class, int);
}
@@ -33581,6 +33583,9 @@ package android.os.strictmode {
public final class NetworkViolation extends android.os.strictmode.Violation {
}
+ public final class NonSdkApiUsedViolation extends android.os.strictmode.Violation {
+ }
+
public final class ResourceMismatchViolation extends android.os.strictmode.Violation {
}
diff --git a/api/test-current.txt b/api/test-current.txt
index 9f5fa0cb0863..9153a39d874a 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -527,6 +527,7 @@ package android.os {
field public static final int DETECT_VM_CURSOR_LEAKS = 256; // 0x100
field public static final int DETECT_VM_FILE_URI_EXPOSURE = 8192; // 0x2000
field public static final int DETECT_VM_INSTANCE_LEAKS = 2048; // 0x800
+ field public static final int DETECT_VM_NON_SDK_API_USAGE = 1073741824; // 0x40000000
field public static final int DETECT_VM_REGISTRATION_LEAKS = 4096; // 0x1000
field public static final int DETECT_VM_UNTAGGED_SOCKET = -2147483648; // 0x80000000
}
diff --git a/core/java/android/os/StrictMode.java b/core/java/android/os/StrictMode.java
index a93e25aa6d89..59380fd3d06b 100644
--- a/core/java/android/os/StrictMode.java
+++ b/core/java/android/os/StrictMode.java
@@ -39,6 +39,7 @@ import android.os.strictmode.InstanceCountViolation;
import android.os.strictmode.IntentReceiverLeakedViolation;
import android.os.strictmode.LeakedClosableViolation;
import android.os.strictmode.NetworkViolation;
+import android.os.strictmode.NonSdkApiUsedViolation;
import android.os.strictmode.ResourceMismatchViolation;
import android.os.strictmode.ServiceConnectionLeakedViolation;
import android.os.strictmode.SqliteObjectLeakedViolation;
@@ -76,6 +77,7 @@ import java.util.HashMap;
import java.util.concurrent.Executor;
import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.atomic.AtomicInteger;
+import java.util.function.Consumer;
/**
* StrictMode is a developer tool which detects things you might be doing by accident and brings
@@ -262,6 +264,9 @@ public final class StrictMode {
/** @hide */
@TestApi public static final int DETECT_VM_UNTAGGED_SOCKET = 0x80 << 24; // for VmPolicy
+ /** @hide */
+ @TestApi public static final int DETECT_VM_NON_SDK_API_USAGE = 0x40 << 24; // for VmPolicy
+
private static final int ALL_VM_DETECT_BITS =
DETECT_VM_CURSOR_LEAKS
| DETECT_VM_CLOSABLE_LEAKS
@@ -271,7 +276,9 @@ public final class StrictMode {
| DETECT_VM_FILE_URI_EXPOSURE
| DETECT_VM_CLEARTEXT_NETWORK
| DETECT_VM_CONTENT_URI_WITHOUT_PERMISSION
- | DETECT_VM_UNTAGGED_SOCKET;
+ | DETECT_VM_UNTAGGED_SOCKET
+ | DETECT_VM_NON_SDK_API_USAGE;
+
// Byte 3: Penalty
@@ -413,6 +420,13 @@ public final class StrictMode {
*/
private static final AtomicInteger sDropboxCallsInFlight = new AtomicInteger(0);
+ /**
+ * Callback supplied to dalvik / libcore to get informed of usages of java API that are not
+ * a part of the public SDK.
+ */
+ private static final Consumer<String> sNonSdkApiUsageConsumer =
+ message -> onVmPolicyViolation(new NonSdkApiUsedViolation(message));
+
private StrictMode() {}
/**
@@ -796,6 +810,23 @@ public final class StrictMode {
}
/**
+ * Detect reflective usage of APIs that are not part of the public Android SDK.
+ */
+ public Builder detectNonSdkApiUsage() {
+ return enable(DETECT_VM_NON_SDK_API_USAGE);
+ }
+
+ /**
+ * Permit reflective usage of APIs that are not part of the public Android SDK. Note
+ * that this <b>only</b> affects {@code StrictMode}, the underlying runtime may
+ * continue to restrict or warn on access to methods that are not part of the
+ * public SDK.
+ */
+ public Builder permitNonSdkApiUsage() {
+ return disable(DETECT_VM_NON_SDK_API_USAGE);
+ }
+
+ /**
* Detect everything that's potentially suspect.
*
* <p>In the Honeycomb release this includes leaks of SQLite cursors, Activities, and
@@ -826,6 +857,8 @@ public final class StrictMode {
detectContentUriWithoutPermission();
detectUntaggedSockets();
}
+
+ // TODO: Decide whether to detect non SDK API usage beyond a certain API level.
return this;
}
@@ -1848,6 +1881,13 @@ public final class StrictMode {
} else if (networkPolicy != NETWORK_POLICY_ACCEPT) {
Log.w(TAG, "Dropping requested network policy due to missing service!");
}
+
+
+ if ((sVmPolicy.mask & DETECT_VM_NON_SDK_API_USAGE) != 0) {
+ VMRuntime.setNonSdkApiUsageConsumer(sNonSdkApiUsageConsumer);
+ } else {
+ VMRuntime.setNonSdkApiUsageConsumer(null);
+ }
}
}
@@ -2576,6 +2616,8 @@ public final class StrictMode {
return DETECT_VM_CONTENT_URI_WITHOUT_PERMISSION;
} else if (mViolation instanceof UntaggedSocketViolation) {
return DETECT_VM_UNTAGGED_SOCKET;
+ } else if (mViolation instanceof NonSdkApiUsedViolation) {
+ return DETECT_VM_NON_SDK_API_USAGE;
}
throw new IllegalStateException("missing violation bit");
}
diff --git a/core/java/android/os/strictmode/NonSdkApiUsedViolation.java b/core/java/android/os/strictmode/NonSdkApiUsedViolation.java
new file mode 100644
index 000000000000..2f0cb50cdfc4
--- /dev/null
+++ b/core/java/android/os/strictmode/NonSdkApiUsedViolation.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2018 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.
+ */
+
+package android.os.strictmode;
+
+/**
+ * Subclass of {@code Violation} that is used when a process accesses
+ * a non SDK API.
+ */
+public final class NonSdkApiUsedViolation extends Violation {
+ /** @hide */
+ public NonSdkApiUsedViolation(String message) {
+ super(message);
+ }
+}
diff --git a/graphics/java/android/graphics/ImageDecoder.java b/graphics/java/android/graphics/ImageDecoder.java
index 31abf9223e98..4210c5caa690 100644
--- a/graphics/java/android/graphics/ImageDecoder.java
+++ b/graphics/java/android/graphics/ImageDecoder.java
@@ -23,8 +23,10 @@ import static java.lang.annotation.RetentionPolicy.SOURCE;
import android.annotation.AnyThread;
import android.annotation.IntDef;
+import android.annotation.IntRange;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.Px;
import android.annotation.TestApi;
import android.annotation.WorkerThread;
import android.content.ContentResolver;
@@ -1020,10 +1022,11 @@ public final class ImageDecoder implements AutoCloseable {
* <p>Like all setters on ImageDecoder, this must be called inside
* {@link OnHeaderDecodedListener#onHeaderDecoded onHeaderDecoded}.</p>
*
- * @param width must be greater than 0.
- * @param height must be greater than 0.
+ * @param width width in pixels of the output, must be greater than 0
+ * @param height height in pixels of the output, must be greater than 0
*/
- public void setTargetSize(int width, int height) {
+ public void setTargetSize(@Px @IntRange(from = 1) int width,
+ @Px @IntRange(from = 1) int height) {
if (width <= 0 || height <= 0) {
throw new IllegalArgumentException("Dimensions must be positive! "
+ "provided (" + width + ", " + height + ")");
@@ -1083,14 +1086,20 @@ public final class ImageDecoder implements AutoCloseable {
*
* <p>Must be greater than or equal to 1.</p>
*
+ * <p>This has the same effect as calling {@link #setTargetSize} with
+ * dimensions based on the {@code sampleSize}. Unlike dividing the original
+ * width and height by the {@code sampleSize} manually, calling this method
+ * allows {@code ImageDecoder} to round in the direction that it can do most
+ * efficiently.</p>
+ *
* <p>Only the last call to this or {@link #setTargetSize} is respected.</p>
*
* <p>Like all setters on ImageDecoder, this must be called inside
* {@link OnHeaderDecodedListener#onHeaderDecoded onHeaderDecoded}.</p>
*
- * @param sampleSize Sampling rate of the encoded image.
+ * @param sampleSize sampling rate of the encoded image.
*/
- public void setTargetSampleSize(int sampleSize) {
+ public void setTargetSampleSize(@IntRange(from = 1) int sampleSize) {
Size size = this.getSampledSize(sampleSize);
int targetWidth = getTargetDimension(mWidth, sampleSize, size.getWidth());
int targetHeight = getTargetDimension(mHeight, sampleSize, size.getHeight());
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java b/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java
index 039e7b5a6613..0ba26e94ce1e 100644
--- a/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java
@@ -44,6 +44,7 @@ import com.android.systemui.statusbar.ScrimView;
import com.android.systemui.statusbar.notification.VisualStabilityManager;
import com.android.systemui.statusbar.phone.DozeParameters;
import com.android.systemui.statusbar.phone.KeyguardBouncer;
+import com.android.systemui.statusbar.phone.KeyguardDismissUtil;
import com.android.systemui.statusbar.phone.LightBarController;
import com.android.systemui.statusbar.phone.LockIcon;
import com.android.systemui.statusbar.phone.LockscreenWallpaper;
@@ -142,5 +143,6 @@ public class SystemUIFactory {
providers.put(NotificationViewHierarchyManager.class,
() -> new NotificationViewHierarchyManager(context));
providers.put(NotificationEntryManager.class, () -> new NotificationEntryManager(context));
+ providers.put(KeyguardDismissUtil.class, KeyguardDismissUtil::new);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardDismissHandler.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardDismissHandler.java
new file mode 100644
index 000000000000..759a0d173cdd
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardDismissHandler.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2018 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
+ */
+
+package com.android.systemui.statusbar.phone;
+
+import android.annotation.Nullable;
+
+import com.android.keyguard.KeyguardHostView.OnDismissAction;
+
+
+/** Executes actions that require the screen to be unlocked. */
+public interface KeyguardDismissHandler {
+ /** Executes an action that requres the screen to be unlocked. */
+ void dismissKeyguardThenExecute(
+ OnDismissAction action, @Nullable Runnable cancelAction, boolean afterKeyguardGone);
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardDismissUtil.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardDismissUtil.java
new file mode 100644
index 000000000000..c38b0b63190d
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardDismissUtil.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2018 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
+ */
+
+package com.android.systemui.statusbar.phone;
+
+import android.util.Log;
+
+import com.android.keyguard.KeyguardHostView.OnDismissAction;
+
+/**
+ * Executes actions that require the screen to be unlocked. Delegates the actual handling to an
+ * implementation passed via {@link #setDismissHandler}.
+ */
+public class KeyguardDismissUtil implements KeyguardDismissHandler {
+ private static final String TAG = "KeyguardDismissUtil";
+
+ private volatile KeyguardDismissHandler mDismissHandler;
+
+ /** Sets the actual {@link DismissHandler} implementation. */
+ public void setDismissHandler(KeyguardDismissHandler dismissHandler) {
+ mDismissHandler = dismissHandler;
+ }
+
+ /**
+ * Executes an action that requres the screen to be unlocked.
+ *
+ * <p>Must be called after {@link #setDismissHandler}.
+ */
+ @Override
+ public void dismissKeyguardThenExecute(
+ OnDismissAction action, Runnable cancelAction, boolean afterKeyguardGone) {
+ KeyguardDismissHandler dismissHandler = mDismissHandler;
+ if (dismissHandler == null) {
+ Log.wtf(TAG, "KeyguardDismissHandler not set.");
+ action.onDismiss();
+ return;
+ }
+ dismissHandler.dismissKeyguardThenExecute(action, cancelAction, afterKeyguardGone);
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
index 340b462d2540..7987bfd9bfb8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -213,6 +213,7 @@ import com.android.systemui.statusbar.notification.AboveShelfObserver;
import com.android.systemui.statusbar.notification.ActivityLaunchAnimator;
import com.android.systemui.statusbar.notification.VisualStabilityManager;
import com.android.systemui.statusbar.phone.UnlockMethodCache.OnUnlockMethodChangedListener;
+import com.android.systemui.statusbar.phone.KeyguardDismissUtil;
import com.android.systemui.statusbar.policy.BatteryController;
import com.android.systemui.statusbar.policy.BatteryController.BatteryStateChangeCallback;
import com.android.systemui.statusbar.policy.BrightnessMirrorController;
@@ -1300,6 +1301,8 @@ public class StatusBar extends SystemUI implements DemoMode,
mKeyguardViewMediatorCallback = keyguardViewMediator.getViewMediatorCallback();
mLightBarController.setFingerprintUnlockController(mFingerprintUnlockController);
+ Dependency.get(KeyguardDismissUtil.class).setDismissHandler(
+ this::dismissKeyguardThenExecute);
Trace.endSection();
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyView.java
index 790135fc03ca..74b39268fc2d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyView.java
@@ -20,8 +20,10 @@ import android.view.ViewGroup;
import android.widget.Button;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.keyguard.KeyguardHostView.OnDismissAction;
import com.android.systemui.Dependency;
import com.android.systemui.R;
+import com.android.systemui.statusbar.phone.KeyguardDismissUtil;
import java.text.BreakIterator;
import java.util.Comparator;
@@ -42,6 +44,7 @@ public class SmartReplyView extends ViewGroup {
private static final int SQUEEZE_FAILED = -1;
private final SmartReplyConstants mConstants;
+ private final KeyguardDismissUtil mKeyguardDismissUtil;
/** Spacing to be applied between views. */
private final int mSpacing;
@@ -62,6 +65,7 @@ public class SmartReplyView extends ViewGroup {
public SmartReplyView(Context context, AttributeSet attrs) {
super(context, attrs);
mConstants = Dependency.get(SmartReplyConstants.class);
+ mKeyguardDismissUtil = Dependency.get(KeyguardDismissUtil.class);
int spacing = 0;
int singleLineButtonPaddingHorizontal = 0;
@@ -126,12 +130,13 @@ public class SmartReplyView extends ViewGroup {
}
@VisibleForTesting
- static Button inflateReplyButton(Context context, ViewGroup root, CharSequence choice,
+ Button inflateReplyButton(Context context, ViewGroup root, CharSequence choice,
RemoteInput remoteInput, PendingIntent pendingIntent) {
Button b = (Button) LayoutInflater.from(context).inflate(
R.layout.smart_reply_button, root, false);
b.setText(choice);
- b.setOnClickListener(view -> {
+
+ OnDismissAction action = () -> {
Bundle results = new Bundle();
results.putString(remoteInput.getResultKey(), choice.toString());
Intent intent = new Intent().addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
@@ -142,6 +147,12 @@ public class SmartReplyView extends ViewGroup {
} catch (PendingIntent.CanceledException e) {
Log.w(TAG, "Unable to send smart reply", e);
}
+ return false; // do not defer
+ };
+
+ b.setOnClickListener(view -> {
+ mKeyguardDismissUtil.dismissKeyguardThenExecute(
+ action, null /* cancelAction */, false /* afterKeyguardGone */);
});
return b;
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SmartReplyViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SmartReplyViewTest.java
index a9b2c96d3ae1..56882c654b33 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SmartReplyViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SmartReplyViewTest.java
@@ -18,6 +18,7 @@ import static android.view.View.MeasureSpec;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertNull;
import static junit.framework.Assert.assertTrue;
import static junit.framework.Assert.fail;
@@ -34,8 +35,12 @@ import android.view.ViewGroup;
import android.widget.Button;
import android.widget.LinearLayout;
+import com.android.keyguard.KeyguardHostView.OnDismissAction;
import com.android.systemui.R;
import com.android.systemui.SysuiTestCase;
+import com.android.systemui.statusbar.phone.KeyguardDismissUtil;
+
+import java.util.concurrent.atomic.AtomicReference;
import org.junit.After;
import org.junit.Before;
@@ -65,6 +70,8 @@ public class SmartReplyViewTest extends SysuiTestCase {
public void setUp() {
mReceiver = new BlockingQueueIntentReceiver();
mContext.registerReceiver(mReceiver, new IntentFilter(TEST_ACTION));
+ mDependency.get(KeyguardDismissUtil.class).setDismissHandler(
+ (action, cancelAction, afterKeyguardGone) -> action.onDismiss());
mView = SmartReplyView.inflate(mContext, null);
@@ -95,6 +102,42 @@ public class SmartReplyViewTest extends SysuiTestCase {
}
@Test
+ public void testSendSmartReply_keyguardCancelled() throws InterruptedException {
+ mDependency.get(KeyguardDismissUtil.class).setDismissHandler(
+ (action, cancelAction, afterKeyguardGone) -> {
+ if (cancelAction != null) {
+ cancelAction.run();
+ }
+ });
+ setRepliesFromRemoteInput(TEST_CHOICES);
+
+ mView.getChildAt(2).performClick();
+
+ assertNull(mReceiver.waitForIntent());
+ }
+
+ @Test
+ public void testSendSmartReply_waitsForKeyguard() throws InterruptedException {
+ AtomicReference<OnDismissAction> actionRef = new AtomicReference<>();
+ mDependency.get(KeyguardDismissUtil.class).setDismissHandler(
+ (action, cancelAction, afterKeyguardGone) -> actionRef.set(action));
+ setRepliesFromRemoteInput(TEST_CHOICES);
+
+ mView.getChildAt(2).performClick();
+
+ // No intent until the screen is unlocked.
+ assertNull(mReceiver.waitForIntent());
+
+ actionRef.get().onDismiss();
+
+ // Now the intent should arrive.
+ Intent resultIntent = mReceiver.waitForIntent();
+ assertEquals(TEST_CHOICES[2],
+ RemoteInput.getResultsFromIntent(resultIntent).get(TEST_RESULT_KEY));
+ assertEquals(RemoteInput.SOURCE_CHOICE, RemoteInput.getResultsSource(resultIntent));
+ }
+
+ @Test
public void testMeasure_empty() {
mView.measure(WIDTH_SPEC, HEIGHT_SPEC);
assertEquals(500, mView.getMeasuredWidthAndState());
@@ -301,7 +344,7 @@ public class SmartReplyViewTest extends SysuiTestCase {
Button previous = null;
for (CharSequence choice : choices) {
- Button current = SmartReplyView.inflateReplyButton(mContext, mView, choice, null, null);
+ Button current = mView.inflateReplyButton(mContext, mView, choice, null, null);
current.setPadding(paddingHorizontal, current.getPaddingTop(), paddingHorizontal,
current.getPaddingBottom());
if (previous != null) {