summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apct-tests/perftests/core/Android.mk5
-rw-r--r--apct-tests/perftests/core/AndroidManifest.xml1
-rw-r--r--apct-tests/perftests/core/src/android/os/ISomeService.aidl5
-rw-r--r--apct-tests/perftests/core/src/android/os/SomeService.java42
-rw-r--r--apct-tests/perftests/core/src/android/os/StrictModeTest.java127
-rw-r--r--api/current.txt1
-rw-r--r--api/system-current.txt2
-rw-r--r--api/test-current.txt1
-rw-r--r--core/java/android/content/Context.java1
-rwxr-xr-xcore/java/android/provider/Settings.java12
-rw-r--r--core/java/android/service/settings/suggestions/ISuggestionService.aidl6
-rw-r--r--core/java/android/service/settings/suggestions/SuggestionService.java17
-rw-r--r--core/java/android/view/ViewConfiguration.java18
-rw-r--r--core/java/android/view/textclassifier/Log.java46
-rw-r--r--core/java/android/view/textclassifier/TextClassifierImpl.java3
-rw-r--r--core/java/com/android/internal/app/LocalePickerWithRegion.java2
-rw-r--r--core/res/res/values/strings.xml2
-rw-r--r--core/res/res/values/symbols.xml1
-rw-r--r--core/tests/coretests/assets/fonts/StaticLayoutLineBreakingTestFont.ttfbin864 -> 0 bytes
-rw-r--r--core/tests/coretests/assets/fonts/StaticLayoutLineBreakingTestFont.ttx207
-rw-r--r--core/tests/coretests/src/android/provider/SettingsBackupTest.java1
-rw-r--r--core/tests/coretests/src/android/service/settings/suggestions/MockSuggestionService.java18
-rw-r--r--core/tests/coretests/src/android/service/settings/suggestions/SuggestionServiceTest.java32
-rw-r--r--core/tests/coretests/src/android/text/StaticLayoutLineBreakingTest.java431
-rw-r--r--libs/hwui/Extensions.cpp6
-rw-r--r--libs/hwui/pipeline/skia/SkiaOpenGLReadback.cpp2
-rw-r--r--libs/hwui/pipeline/skia/SkiaPipeline.cpp6
-rw-r--r--libs/hwui/pipeline/skia/SkiaPipeline.h1
-rw-r--r--libs/hwui/renderthread/CanvasContext.cpp1
-rw-r--r--libs/hwui/renderthread/IRenderPipeline.h1
-rw-r--r--libs/hwui/renderthread/OpenGLPipeline.h1
-rw-r--r--libs/hwui/tests/unit/SkiaPipelineTests.cpp34
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/wifi/OWNERS7
-rw-r--r--services/core/java/com/android/server/am/LockTaskController.java15
-rw-r--r--services/core/java/com/android/server/am/LockTaskNotify.java49
-rw-r--r--services/core/java/com/android/server/policy/PhoneWindowManager.java17
-rw-r--r--services/tests/servicestests/src/com/android/server/am/LockTaskControllerTest.java6
37 files changed, 438 insertions, 689 deletions
diff --git a/apct-tests/perftests/core/Android.mk b/apct-tests/perftests/core/Android.mk
index 200f92fb590c..f08b4025f95e 100644
--- a/apct-tests/perftests/core/Android.mk
+++ b/apct-tests/perftests/core/Android.mk
@@ -4,11 +4,14 @@ include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := tests
LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
+LOCAL_SRC_FILES := \
+ $(call all-java-files-under, src) \
+ src/android/os/ISomeService.aidl
LOCAL_STATIC_JAVA_LIBRARIES := \
android-support-test \
apct-perftests-utils \
+ guava \
legacy-android-test
LOCAL_PACKAGE_NAME := CorePerfTests
diff --git a/apct-tests/perftests/core/AndroidManifest.xml b/apct-tests/perftests/core/AndroidManifest.xml
index a709ee3ff913..f27e8c82a303 100644
--- a/apct-tests/perftests/core/AndroidManifest.xml
+++ b/apct-tests/perftests/core/AndroidManifest.xml
@@ -5,6 +5,7 @@
<application>
<uses-library android:name="android.test.runner" />
<activity android:name="android.perftests.utils.StubActivity" />
+ <service android:name="android.os.SomeService" android:exported="false" android:process=":some_service" />
</application>
<instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
diff --git a/apct-tests/perftests/core/src/android/os/ISomeService.aidl b/apct-tests/perftests/core/src/android/os/ISomeService.aidl
new file mode 100644
index 000000000000..0658b698eb7d
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/os/ISomeService.aidl
@@ -0,0 +1,5 @@
+package android.os;
+
+interface ISomeService {
+ void readDisk(int times);
+} \ No newline at end of file
diff --git a/apct-tests/perftests/core/src/android/os/SomeService.java b/apct-tests/perftests/core/src/android/os/SomeService.java
new file mode 100644
index 000000000000..bdfaa444fb3d
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/os/SomeService.java
@@ -0,0 +1,42 @@
+package android.os;
+
+import android.app.Service;
+import android.content.Intent;
+import java.io.File;
+import java.io.IOException;
+
+/** Service in separate process available for calling over binder. */
+public class SomeService extends Service {
+
+ private File mTempFile;
+
+ @Override
+ public void onCreate() {
+ super.onCreate();
+ try {
+ mTempFile = File.createTempFile("foo", "bar");
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ private final ISomeService.Stub mBinder =
+ new ISomeService.Stub() {
+ public void readDisk(int times) {
+ for (int i = 0; i < times; i++) {
+ mTempFile.exists();
+ }
+ }
+ };
+
+ @Override
+ public IBinder onBind(Intent intent) {
+ return mBinder;
+ }
+
+ @Override
+ public void onDestroy() {
+ super.onDestroy();
+ mTempFile.delete();
+ }
+}
diff --git a/apct-tests/perftests/core/src/android/os/StrictModeTest.java b/apct-tests/perftests/core/src/android/os/StrictModeTest.java
new file mode 100644
index 000000000000..d973c204f89e
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/os/StrictModeTest.java
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2017 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;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.net.Uri;
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.LargeTest;
+import android.support.test.runner.AndroidJUnit4;
+import com.google.common.util.concurrent.SettableFuture;
+import java.io.File;
+import java.io.IOException;
+import java.util.concurrent.ExecutionException;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class StrictModeTest {
+ @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+
+ @Test
+ public void timeVmViolation() {
+ final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder().detectAll().penaltyLog().build());
+ causeVmViolations(state);
+ }
+
+ @Test
+ public void timeVmViolationNoStrictMode() {
+ final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ causeVmViolations(state);
+ }
+
+ private static void causeVmViolations(BenchmarkState state) {
+ Intent intent = new Intent(Intent.ACTION_VIEW);
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ intent.setDataAndType(Uri.parse("content://com.example/foobar"), "image/jpeg");
+ final Context context = InstrumentationRegistry.getTargetContext();
+ while (state.keepRunning()) {
+ context.startActivity(intent);
+ }
+ }
+
+ @Test
+ public void timeThreadViolation() throws IOException {
+ final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ StrictMode.setThreadPolicy(
+ new StrictMode.ThreadPolicy.Builder().detectAll().penaltyLog().build());
+ causeThreadViolations(state);
+ }
+
+ @Test
+ public void timeThreadViolationNoStrictMode() throws IOException {
+ final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ causeThreadViolations(state);
+ }
+
+ private static void causeThreadViolations(BenchmarkState state) throws IOException {
+ final File test = File.createTempFile("foo", "bar");
+ while (state.keepRunning()) {
+ test.exists();
+ }
+ test.delete();
+ }
+
+ @Test
+ public void timeCrossBinderThreadViolation() throws Exception {
+ final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ StrictMode.setThreadPolicy(
+ new StrictMode.ThreadPolicy.Builder().detectAll().penaltyLog().build());
+ causeCrossProcessThreadViolations(state);
+ }
+
+ @Test
+ public void timeCrossBinderThreadViolationNoStrictMode() throws Exception {
+ final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ causeCrossProcessThreadViolations(state);
+ }
+
+ private static void causeCrossProcessThreadViolations(BenchmarkState state)
+ throws ExecutionException, InterruptedException, RemoteException {
+ final Context context = InstrumentationRegistry.getTargetContext();
+
+ SettableFuture<IBinder> binder = SettableFuture.create();
+ ServiceConnection connection =
+ new ServiceConnection() {
+ @Override
+ public void onServiceConnected(ComponentName className, IBinder service) {
+ binder.set(service);
+ }
+
+ @Override
+ public void onServiceDisconnected(ComponentName arg0) {
+ binder.set(null);
+ }
+ };
+ context.bindService(
+ new Intent(context, SomeService.class), connection, Context.BIND_AUTO_CREATE);
+ ISomeService someService = ISomeService.Stub.asInterface(binder.get());
+ while (state.keepRunning()) {
+ // Violate strictmode heavily.
+ someService.readDisk(10);
+ }
+ context.unbindService(connection);
+ }
+}
diff --git a/api/current.txt b/api/current.txt
index 8463260513b6..df8b7ef63bae 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -35074,6 +35074,7 @@ package android.provider {
field public static final java.lang.String ACTION_DEVICE_INFO_SETTINGS = "android.settings.DEVICE_INFO_SETTINGS";
field public static final java.lang.String ACTION_DISPLAY_SETTINGS = "android.settings.DISPLAY_SETTINGS";
field public static final java.lang.String ACTION_DREAM_SETTINGS = "android.settings.DREAM_SETTINGS";
+ field public static final java.lang.String ACTION_FINGERPRINT_ENROLL = "android.settings.FINGERPRINT_ENROLL";
field public static final java.lang.String ACTION_HARD_KEYBOARD_SETTINGS = "android.settings.HARD_KEYBOARD_SETTINGS";
field public static final java.lang.String ACTION_HOME_SETTINGS = "android.settings.HOME_SETTINGS";
field public static final java.lang.String ACTION_IGNORE_BACKGROUND_DATA_RESTRICTIONS_SETTINGS = "android.settings.IGNORE_BACKGROUND_DATA_RESTRICTIONS_SETTINGS";
diff --git a/api/system-current.txt b/api/system-current.txt
index 9a59503b1879..007316fcf524 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -38138,6 +38138,7 @@ package android.provider {
field public static final java.lang.String ACTION_DISPLAY_SETTINGS = "android.settings.DISPLAY_SETTINGS";
field public static final java.lang.String ACTION_DREAM_SETTINGS = "android.settings.DREAM_SETTINGS";
field public static final java.lang.String ACTION_ENTERPRISE_PRIVACY_SETTINGS = "android.settings.ENTERPRISE_PRIVACY_SETTINGS";
+ field public static final java.lang.String ACTION_FINGERPRINT_ENROLL = "android.settings.FINGERPRINT_ENROLL";
field public static final java.lang.String ACTION_HARD_KEYBOARD_SETTINGS = "android.settings.HARD_KEYBOARD_SETTINGS";
field public static final java.lang.String ACTION_HOME_SETTINGS = "android.settings.HOME_SETTINGS";
field public static final java.lang.String ACTION_IGNORE_BACKGROUND_DATA_RESTRICTIONS_SETTINGS = "android.settings.IGNORE_BACKGROUND_DATA_RESTRICTIONS_SETTINGS";
@@ -41101,6 +41102,7 @@ package android.service.settings.suggestions {
method public android.os.IBinder onBind(android.content.Intent);
method public abstract java.util.List<android.service.settings.suggestions.Suggestion> onGetSuggestions();
method public abstract void onSuggestionDismissed(android.service.settings.suggestions.Suggestion);
+ method public abstract void onSuggestionLaunched(android.service.settings.suggestions.Suggestion);
}
}
diff --git a/api/test-current.txt b/api/test-current.txt
index 965dc72c148b..faccb6b58a3c 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -35345,6 +35345,7 @@ package android.provider {
field public static final java.lang.String ACTION_DISPLAY_SETTINGS = "android.settings.DISPLAY_SETTINGS";
field public static final java.lang.String ACTION_DREAM_SETTINGS = "android.settings.DREAM_SETTINGS";
field public static final java.lang.String ACTION_ENTERPRISE_PRIVACY_SETTINGS = "android.settings.ENTERPRISE_PRIVACY_SETTINGS";
+ field public static final java.lang.String ACTION_FINGERPRINT_ENROLL = "android.settings.FINGERPRINT_ENROLL";
field public static final java.lang.String ACTION_HARD_KEYBOARD_SETTINGS = "android.settings.HARD_KEYBOARD_SETTINGS";
field public static final java.lang.String ACTION_HOME_SETTINGS = "android.settings.HOME_SETTINGS";
field public static final java.lang.String ACTION_IGNORE_BACKGROUND_DATA_RESTRICTIONS_SETTINGS = "android.settings.IGNORE_BACKGROUND_DATA_RESTRICTIONS_SETTINGS";
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 20fbf046a577..c165fb3e925c 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -3604,7 +3604,6 @@ public abstract class Context {
/**
* Use with {@link #getSystemService} to retrieve a
- * {@link android.text.ClipboardManager} for accessing and modifying
* {@link android.content.ClipboardManager} for accessing and modifying
* the contents of the global clipboard.
*
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 6f896446aa71..c200ae742125 100755
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -442,6 +442,18 @@ public final class Settings {
"android.settings.ASSIST_GESTURE_SETTINGS";
/**
+ * Activity Action: Show settings to enroll fingerprints, and setup PIN/Pattern/Pass if
+ * necessary.
+ * <p>
+ * Input: Nothing.
+ * <p>
+ * Output: Nothing.
+ */
+ @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
+ public static final String ACTION_FINGERPRINT_ENROLL =
+ "android.settings.FINGERPRINT_ENROLL";
+
+ /**
* Activity Action: Show settings to allow configuration of cast endpoints.
* <p>
* In some cases, a matching Activity may not exist, so ensure you
diff --git a/core/java/android/service/settings/suggestions/ISuggestionService.aidl b/core/java/android/service/settings/suggestions/ISuggestionService.aidl
index 423c507257c3..8dfa9c3193d3 100644
--- a/core/java/android/service/settings/suggestions/ISuggestionService.aidl
+++ b/core/java/android/service/settings/suggestions/ISuggestionService.aidl
@@ -17,4 +17,10 @@ interface ISuggestionService {
* calls.
*/
void dismissSuggestion(in Suggestion suggestion) = 2;
+
+ /**
+ * This is the opposite signal to {@link #dismissSuggestion}, indicating a suggestion has been
+ * launched.
+ */
+ void launchSuggestion(in Suggestion suggestion) = 3;
} \ No newline at end of file
diff --git a/core/java/android/service/settings/suggestions/SuggestionService.java b/core/java/android/service/settings/suggestions/SuggestionService.java
index 2a4c84c2a1cf..ce9501d699ed 100644
--- a/core/java/android/service/settings/suggestions/SuggestionService.java
+++ b/core/java/android/service/settings/suggestions/SuggestionService.java
@@ -48,12 +48,20 @@ public abstract class SuggestionService extends Service {
}
@Override
- public void dismissSuggestion(Suggestion suggestion) {
+ public void dismissSuggestion(Suggestion suggestion) {
if (DEBUG) {
Log.d(TAG, "dismissSuggestion() " + getPackageName());
}
onSuggestionDismissed(suggestion);
}
+
+ @Override
+ public void launchSuggestion(Suggestion suggestion) {
+ if (DEBUG) {
+ Log.d(TAG, "launchSuggestion() " + getPackageName());
+ }
+ onSuggestionLaunched(suggestion);
+ }
};
}
@@ -65,7 +73,12 @@ public abstract class SuggestionService extends Service {
/**
* Dismiss a suggestion. The suggestion will not be included in future
* {@link #onGetSuggestions()} calls.
- * @param suggestion
*/
public abstract void onSuggestionDismissed(Suggestion suggestion);
+
+ /**
+ * This is the opposite signal to {@link #onSuggestionDismissed}, indicating a suggestion has
+ * been launched.
+ */
+ public abstract void onSuggestionLaunched(Suggestion suggestion);
}
diff --git a/core/java/android/view/ViewConfiguration.java b/core/java/android/view/ViewConfiguration.java
index 574137b30f1e..45008627e019 100644
--- a/core/java/android/view/ViewConfiguration.java
+++ b/core/java/android/view/ViewConfiguration.java
@@ -84,12 +84,17 @@ public class ViewConfiguration {
/**
* Defines the duration in milliseconds a user needs to hold down the
- * appropriate button to bring up the accessibility shortcut (first time) or enable it
- * (once shortcut is configured).
+ * appropriate button to bring up the accessibility shortcut for the first time
*/
private static final int A11Y_SHORTCUT_KEY_TIMEOUT = 3000;
/**
+ * Defines the duration in milliseconds a user needs to hold down the
+ * appropriate button to enable the accessibility shortcut once it's configured.
+ */
+ private static final int A11Y_SHORTCUT_KEY_TIMEOUT_AFTER_CONFIRMATION = 1500;
+
+ /**
* Defines the duration in milliseconds we will wait to see if a touch event
* is a tap or a scroll. If the user does not move within this interval, it is
* considered to be a tap.
@@ -851,6 +856,15 @@ public class ViewConfiguration {
}
/**
+ * @return The amount of time a user needs to press the relevant keys to activate the
+ * accessibility shortcut after it's confirmed that accessibility shortcut is used.
+ * @hide
+ */
+ public long getAccessibilityShortcutKeyTimeoutAfterConfirmation() {
+ return A11Y_SHORTCUT_KEY_TIMEOUT_AFTER_CONFIRMATION;
+ }
+
+ /**
* The amount of friction applied to scrolls and flings.
*
* @return A scalar dimensionless value representing the coefficient of
diff --git a/core/java/android/view/textclassifier/Log.java b/core/java/android/view/textclassifier/Log.java
new file mode 100644
index 000000000000..83ca15df92f4
--- /dev/null
+++ b/core/java/android/view/textclassifier/Log.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2017 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.view.textclassifier;
+
+import android.util.Slog;
+
+/**
+ * Logging for android.view.textclassifier package.
+ */
+final class Log {
+
+ /**
+ * true: Enables full logging.
+ * false: Limits logging to debug level.
+ */
+ private static final boolean ENABLE_FULL_LOGGING = false;
+
+ private Log() {}
+
+ public static void d(String tag, String msg) {
+ Slog.d(tag, msg);
+ }
+
+ public static void e(String tag, String msg, Throwable tr) {
+ if (ENABLE_FULL_LOGGING) {
+ Slog.e(tag, msg, tr);
+ } else {
+ final String trString = (tr != null) ? tr.getClass().getSimpleName() : "??";
+ Slog.d(tag, String.format("%s (%s)", msg, trString));
+ }
+ }
+}
diff --git a/core/java/android/view/textclassifier/TextClassifierImpl.java b/core/java/android/view/textclassifier/TextClassifierImpl.java
index ef0874722d6f..1c07be4bcd75 100644
--- a/core/java/android/view/textclassifier/TextClassifierImpl.java
+++ b/core/java/android/view/textclassifier/TextClassifierImpl.java
@@ -35,7 +35,6 @@ import android.text.TextUtils;
import android.text.method.WordIterator;
import android.text.style.ClickableSpan;
import android.text.util.Linkify;
-import android.util.Log;
import android.util.Patterns;
import android.view.View;
import android.widget.TextViewMetrics;
@@ -163,7 +162,7 @@ final class TextClassifierImpl implements TextClassifier {
}
} catch (Throwable t) {
// Avoid throwing from this method. Log the error.
- Log.e(LOG_TAG, "Error getting assist info.", t);
+ Log.e(LOG_TAG, "Error getting text classification info.", t);
}
// Getting here means something went wrong, return a NO_OP result.
return TextClassifier.NO_OP.classifyText(
diff --git a/core/java/com/android/internal/app/LocalePickerWithRegion.java b/core/java/com/android/internal/app/LocalePickerWithRegion.java
index 3d5cd0f5847b..d0719eeca04e 100644
--- a/core/java/com/android/internal/app/LocalePickerWithRegion.java
+++ b/core/java/com/android/internal/app/LocalePickerWithRegion.java
@@ -238,7 +238,7 @@ public class LocalePickerWithRegion extends ListFragment implements SearchView.O
mSearchView.setOnQueryTextListener(this);
// Restore previous search status
- if (mPreviousSearch != null) {
+ if (!TextUtils.isEmpty(mPreviousSearch)) {
searchMenuItem.expandActionView();
mSearchView.setIconified(false);
mSearchView.setActivated(true);
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 93c02b0e05f6..78a8e2a3c748 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -4346,8 +4346,6 @@
<string name="lock_to_app_toast">To unpin this screen, touch &amp; hold Back and Overview
buttons</string>
- <!-- Notify user that they are locked in lock-to-app mode -->
- <string name="lock_to_app_toast_locked">This app can\'t be unpinned</string>
<!-- Starting lock-to-app indication. -->
<string name="lock_to_app_start">Screen pinned</string>
<!-- Exting lock-to-app indication. -->
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index a42cf42cb905..7bbd17e62c48 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -754,7 +754,6 @@
<java-symbol type="string" name="last_month" />
<java-symbol type="string" name="launchBrowserDefault" />
<java-symbol type="string" name="lock_to_app_toast" />
- <java-symbol type="string" name="lock_to_app_toast_locked" />
<java-symbol type="string" name="lock_to_app_start" />
<java-symbol type="string" name="lock_to_app_exit" />
<java-symbol type="string" name="lock_to_app_unlock_pin" />
diff --git a/core/tests/coretests/assets/fonts/StaticLayoutLineBreakingTestFont.ttf b/core/tests/coretests/assets/fonts/StaticLayoutLineBreakingTestFont.ttf
deleted file mode 100644
index 1bad6fe75090..000000000000
--- a/core/tests/coretests/assets/fonts/StaticLayoutLineBreakingTestFont.ttf
+++ /dev/null
Binary files differ
diff --git a/core/tests/coretests/assets/fonts/StaticLayoutLineBreakingTestFont.ttx b/core/tests/coretests/assets/fonts/StaticLayoutLineBreakingTestFont.ttx
deleted file mode 100644
index 0cf0f7914931..000000000000
--- a/core/tests/coretests/assets/fonts/StaticLayoutLineBreakingTestFont.ttx
+++ /dev/null
@@ -1,207 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2017 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.
--->
-<ttFont sfntVersion="\x00\x01\x00\x00" ttLibVersion="3.0">
-
- <GlyphOrder>
- <GlyphID id="0" name=".notdef"/>
- <GlyphID id="1" name="0em"/>
- <GlyphID id="2" name="1em"/>
- <GlyphID id="3" name="3em"/>
- <GlyphID id="4" name="5em"/>
- <GlyphID id="5" name="7em"/>
- <GlyphID id="6" name="10em"/>
- <GlyphID id="7" name="50em"/>
- <GlyphID id="8" name="100em"/>
- </GlyphOrder>
-
- <head>
- <tableVersion value="1.0"/>
- <fontRevision value="1.0"/>
- <checkSumAdjustment value="0x640cdb2f"/>
- <magicNumber value="0x5f0f3cf5"/>
- <flags value="00000000 00000011"/>
- <unitsPerEm value="100"/>
- <created value="Fri Mar 17 07:26:00 2017"/>
- <macStyle value="00000000 00000000"/>
- <lowestRecPPEM value="7"/>
- <fontDirectionHint value="2"/>
- <glyphDataFormat value="0"/>
- </head>
-
- <hhea>
- <tableVersion value="0x00010000"/>
- <ascent value="1000"/>
- <descent value="-200"/>
- <lineGap value="0"/>
- <caretSlopeRise value="1"/>
- <caretSlopeRun value="0"/>
- <caretOffset value="0"/>
- <reserved0 value="0"/>
- <reserved1 value="0"/>
- <reserved2 value="0"/>
- <reserved3 value="0"/>
- <metricDataFormat value="0"/>
- </hhea>
-
- <maxp>
- <tableVersion value="0x10000"/>
- <maxZones value="0"/>
- <maxTwilightPoints value="0"/>
- <maxStorage value="0"/>
- <maxFunctionDefs value="0"/>
- <maxInstructionDefs value="0"/>
- <maxStackElements value="0"/>
- <maxSizeOfInstructions value="0"/>
- <maxComponentElements value="0"/>
- </maxp>
-
- <OS_2>
- <!-- The fields 'usFirstCharIndex' and 'usLastCharIndex'
- will be recalculated by the compiler -->
- <version value="3"/>
- <xAvgCharWidth value="594"/>
- <usWeightClass value="400"/>
- <usWidthClass value="5"/>
- <fsType value="00000000 00001000"/>
- <ySubscriptXSize value="650"/>
- <ySubscriptYSize value="600"/>
- <ySubscriptXOffset value="0"/>
- <ySubscriptYOffset value="75"/>
- <ySuperscriptXSize value="650"/>
- <ySuperscriptYSize value="600"/>
- <ySuperscriptXOffset value="0"/>
- <ySuperscriptYOffset value="350"/>
- <yStrikeoutSize value="50"/>
- <yStrikeoutPosition value="300"/>
- <sFamilyClass value="0"/>
- <panose>
- <bFamilyType value="0"/>
- <bSerifStyle value="0"/>
- <bWeight value="5"/>
- <bProportion value="0"/>
- <bContrast value="0"/>
- <bStrokeVariation value="0"/>
- <bArmStyle value="0"/>
- <bLetterForm value="0"/>
- <bMidline value="0"/>
- <bXHeight value="0"/>
- </panose>
- <ulUnicodeRange1 value="00000000 00000000 00000000 00000001"/>
- <ulUnicodeRange2 value="00000000 00000000 00000000 00000000"/>
- <ulUnicodeRange3 value="00000000 00000000 00000000 00000000"/>
- <ulUnicodeRange4 value="00000000 00000000 00000000 00000000"/>
- <achVendID value="UKWN"/>
- <fsSelection value="00000000 01000000"/>
- <usFirstCharIndex value="32"/>
- <usLastCharIndex value="122"/>
- <sTypoAscender value="800"/>
- <sTypoDescender value="-200"/>
- <sTypoLineGap value="200"/>
- <usWinAscent value="1000"/>
- <usWinDescent value="200"/>
- <ulCodePageRange1 value="00000000 00000000 00000000 00000001"/>
- <ulCodePageRange2 value="00000000 00000000 00000000 00000000"/>
- <sxHeight value="500"/>
- <sCapHeight value="700"/>
- <usDefaultChar value="0"/>
- <usBreakChar value="32"/>
- <usMaxContext value="0"/>
- </OS_2>
-
- <hmtx>
- <mtx name=".notdef" width="50" lsb="0"/>
- <mtx name="0em" width="0" lsb="0"/>
- <mtx name="1em" width="100" lsb="0"/>
- <mtx name="3em" width="300" lsb="0"/>
- <mtx name="5em" width="500" lsb="0"/>
- <mtx name="7em" width="700" lsb="0"/>
- <mtx name="10em" width="1000" lsb="0"/>
- <mtx name="50em" width="5000" lsb="0"/>
- <mtx name="100em" width="10000" lsb="0"/>
- </hmtx>
-
- <cmap>
- <tableVersion version="0"/>
- <cmap_format_12 format="12" reserved="0" length="6" nGroups="1" platformID="3" platEncID="10" language="0">
- <map code="0x0020" name="10em" />
- <map code="0x002e" name="10em" /> <!-- . -->
- <map code="0x0043" name="100em" /> <!-- C -->
- <map code="0x0049" name="1em" /> <!-- I -->
- <map code="0x004c" name="50em" /> <!-- L -->
- <map code="0x0056" name="5em" /> <!-- V -->
- <map code="0x0058" name="10em" /> <!-- X -->
- <map code="0x005f" name="0em" /> <!-- _ -->
- <map code="0xfffd" name="7em" /> <!-- REPLACEMENT CHAR -->
- <map code="0x10331" name="10em" />
- </cmap_format_12>
- </cmap>
-
- <loca>
- <!-- The 'loca' table will be calculated by the compiler -->
- </loca>
-
- <glyf>
- <TTGlyph name=".notdef" xMin="0" yMin="0" xMax="0" yMax="0" />
- <TTGlyph name="0em" xMin="0" yMin="0" xMax="0" yMax="0" />
- <TTGlyph name="1em" xMin="0" yMin="0" xMax="0" yMax="0" />
- <TTGlyph name="3em" xMin="0" yMin="0" xMax="0" yMax="0" />
- <TTGlyph name="5em" xMin="0" yMin="0" xMax="0" yMax="0" />
- <TTGlyph name="7em" xMin="0" yMin="0" xMax="0" yMax="0" />
- <TTGlyph name="10em" xMin="0" yMin="0" xMax="0" yMax="0" />
- <TTGlyph name="50em" xMin="0" yMin="0" xMax="0" yMax="0" />
- <TTGlyph name="100em" xMin="0" yMin="0" xMax="0" yMax="0" />
- </glyf>
-
- <name>
- <namerecord nameID="1" platformID="1" platEncID="0" langID="0x0" unicode="True">
- Font for StaticLayoutLineBreakingTest
- </namerecord>
- <namerecord nameID="2" platformID="1" platEncID="0" langID="0x0" unicode="True">
- Regular
- </namerecord>
- <namerecord nameID="4" platformID="1" platEncID="0" langID="0x0" unicode="True">
- Font for StaticLayoutLineBreakingTest
- </namerecord>
- <namerecord nameID="6" platformID="1" platEncID="0" langID="0x0" unicode="True">
- SampleFont-Regular
- </namerecord>
- <namerecord nameID="1" platformID="3" platEncID="1" langID="0x409">
- Sample Font
- </namerecord>
- <namerecord nameID="2" platformID="3" platEncID="1" langID="0x409">
- Regular
- </namerecord>
- <namerecord nameID="4" platformID="3" platEncID="1" langID="0x409">
- Sample Font
- </namerecord>
- <namerecord nameID="6" platformID="3" platEncID="1" langID="0x409">
- SampleFont-Regular
- </namerecord>
- </name>
-
- <post>
- <formatType value="3.0"/>
- <italicAngle value="0.0"/>
- <underlinePosition value="-75"/>
- <underlineThickness value="50"/>
- <isFixedPitch value="0"/>
- <minMemType42 value="0"/>
- <maxMemType42 value="0"/>
- <minMemType1 value="0"/>
- <maxMemType1 value="0"/>
- </post>
-
-</ttFont>
diff --git a/core/tests/coretests/src/android/provider/SettingsBackupTest.java b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
index 0b768f878af8..ebe0527cbbec 100644
--- a/core/tests/coretests/src/android/provider/SettingsBackupTest.java
+++ b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
@@ -38,7 +38,6 @@ import java.util.HashSet;
import java.util.Set;
/** Tests that ensure appropriate settings are backed up. */
-@Presubmit
@RunWith(AndroidJUnit4.class)
@SmallTest
public class SettingsBackupTest {
diff --git a/core/tests/coretests/src/android/service/settings/suggestions/MockSuggestionService.java b/core/tests/coretests/src/android/service/settings/suggestions/MockSuggestionService.java
index c158b9f0bf71..ab541a15cdcc 100644
--- a/core/tests/coretests/src/android/service/settings/suggestions/MockSuggestionService.java
+++ b/core/tests/coretests/src/android/service/settings/suggestions/MockSuggestionService.java
@@ -16,11 +16,23 @@
package android.service.settings.suggestions;
+import android.support.annotation.VisibleForTesting;
+
import java.util.ArrayList;
import java.util.List;
public class MockSuggestionService extends SuggestionService {
+ @VisibleForTesting
+ static boolean sOnSuggestionLaunchedCalled;
+ @VisibleForTesting
+ static boolean sOnSuggestionDismissedCalled;
+
+ public static void reset() {
+ sOnSuggestionLaunchedCalled = false;
+ sOnSuggestionDismissedCalled = false;
+ }
+
@Override
public List<Suggestion> onGetSuggestions() {
final List<Suggestion> data = new ArrayList<>();
@@ -34,5 +46,11 @@ public class MockSuggestionService extends SuggestionService {
@Override
public void onSuggestionDismissed(Suggestion suggestion) {
+ sOnSuggestionDismissedCalled = true;
+ }
+
+ @Override
+ public void onSuggestionLaunched(Suggestion suggestion) {
+ sOnSuggestionLaunchedCalled = true;
}
}
diff --git a/core/tests/coretests/src/android/service/settings/suggestions/SuggestionServiceTest.java b/core/tests/coretests/src/android/service/settings/suggestions/SuggestionServiceTest.java
index bc8823184417..dca8c096dc59 100644
--- a/core/tests/coretests/src/android/service/settings/suggestions/SuggestionServiceTest.java
+++ b/core/tests/coretests/src/android/service/settings/suggestions/SuggestionServiceTest.java
@@ -16,12 +16,17 @@
package android.service.settings.suggestions;
+import static com.google.common.truth.Truth.assertThat;
+
import android.content.Intent;
+import android.os.IBinder;
+import android.os.RemoteException;
import android.support.test.InstrumentationRegistry;
import android.support.test.filters.SmallTest;
import android.support.test.rule.ServiceTestRule;
import android.support.test.runner.AndroidJUnit4;
+import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
@@ -45,9 +50,36 @@ public class SuggestionServiceTest {
MockSuggestionService.class);
}
+ @After
+ public void tearUp() {
+ MockSuggestionService.reset();
+ }
+
@Test
public void canStartService() throws TimeoutException {
mServiceTestRule.startService(mMockServiceIntent);
// Do nothing after starting service.
}
+
+ @Test
+ public void dismissSuggestion_shouldCallImplementation()
+ throws TimeoutException, RemoteException {
+ MockSuggestionService service = new MockSuggestionService();
+ IBinder binder = mServiceTestRule.bindService(mMockServiceIntent);
+ ISuggestionService serviceBinder = ISuggestionService.Stub.asInterface(binder);
+ serviceBinder.dismissSuggestion(null);
+
+ assertThat(service.sOnSuggestionDismissedCalled).isTrue();
+ }
+
+ @Test
+ public void launchSuggestion_shouldCallImplementation()
+ throws TimeoutException, RemoteException {
+ MockSuggestionService service = new MockSuggestionService();
+ IBinder binder = mServiceTestRule.bindService(mMockServiceIntent);
+ ISuggestionService serviceBinder = ISuggestionService.Stub.asInterface(binder);
+ serviceBinder.launchSuggestion(null);
+
+ assertThat(service.sOnSuggestionLaunchedCalled).isTrue();
+ }
}
diff --git a/core/tests/coretests/src/android/text/StaticLayoutLineBreakingTest.java b/core/tests/coretests/src/android/text/StaticLayoutLineBreakingTest.java
deleted file mode 100644
index f7dbafad38d1..000000000000
--- a/core/tests/coretests/src/android/text/StaticLayoutLineBreakingTest.java
+++ /dev/null
@@ -1,431 +0,0 @@
-/*
- * Copyright (C) 2012 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.text;
-
-import static org.junit.Assert.assertEquals;
-
-import android.content.Context;;
-import android.graphics.Typeface;
-import android.support.test.InstrumentationRegistry;
-import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
-import android.text.Layout.Alignment;
-import android.text.style.MetricAffectingSpan;
-import android.util.Log;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-@SmallTest
-@RunWith(AndroidJUnit4.class)
-public class StaticLayoutLineBreakingTest {
- // Span test are currently not supported because text measurement uses the MeasuredText
- // internal mWorkPaint instead of the provided MockTestPaint.
- private static final boolean SPAN_TESTS_SUPPORTED = false;
- private static final boolean DEBUG = false;
-
- private static final float SPACE_MULTI = 1.0f;
- private static final float SPACE_ADD = 0.0f;
- private static final int WIDTH = 100;
- private static final Alignment ALIGN = Alignment.ALIGN_LEFT;
-
- private static final char SURR_FIRST = '\uD800';
- private static final char SURR_SECOND = '\uDF31';
-
- private static final int[] NO_BREAK = new int[] {};
-
- private static final TextPaint sTextPaint = new TextPaint();
-
- static {
- // The test font has following coverage and width.
- // U+0020: 10em
- // U+002E (.): 10em
- // U+0043 (C): 100em
- // U+0049 (I): 1em
- // U+004C (L): 50em
- // U+0056 (V): 5em
- // U+0058 (X): 10em
- // U+005F (_): 0em
- // U+FFFD (invalid surrogate will be replaced to this): 7em
- // U+10331 (\uD800\uDF31): 10em
- Context context = InstrumentationRegistry.getTargetContext();
- sTextPaint.setTypeface(Typeface.createFromAsset(context.getAssets(),
- "fonts/StaticLayoutLineBreakingTestFont.ttf"));
- sTextPaint.setTextSize(1.0f); // Make 1em == 1px.
- }
-
- private static StaticLayout getStaticLayout(CharSequence source, int width) {
- return new StaticLayout(source, sTextPaint, width, ALIGN, SPACE_MULTI, SPACE_ADD, false);
- }
-
- private static int[] getBreaks(CharSequence source) {
- return getBreaks(source, WIDTH);
- }
-
- private static int[] getBreaks(CharSequence source, int width) {
- StaticLayout staticLayout = getStaticLayout(source, width);
-
- int[] breaks = new int[staticLayout.getLineCount() - 1];
- for (int line = 0; line < breaks.length; line++) {
- breaks[line] = staticLayout.getLineEnd(line);
- }
- return breaks;
- }
-
- private static void debugLayout(CharSequence source, StaticLayout staticLayout) {
- if (DEBUG) {
- int count = staticLayout.getLineCount();
- Log.i("SLLBTest", "\"" + source.toString() + "\": "
- + count + " lines");
- for (int line = 0; line < count; line++) {
- int lineStart = staticLayout.getLineStart(line);
- int lineEnd = staticLayout.getLineEnd(line);
- Log.i("SLLBTest", "Line " + line + " [" + lineStart + ".."
- + lineEnd + "]\t" + source.subSequence(lineStart, lineEnd));
- }
- }
- }
-
- private static void layout(CharSequence source, int[] breaks) {
- layout(source, breaks, WIDTH);
- }
-
- private static void layout(CharSequence source, int[] breaks, int width) {
- StaticLayout staticLayout = getStaticLayout(source, width);
-
- debugLayout(source, staticLayout);
-
- int lineCount = breaks.length + 1;
- assertEquals("Number of lines", lineCount, staticLayout.getLineCount());
-
- for (int line = 0; line < lineCount; line++) {
- int lineStart = staticLayout.getLineStart(line);
- int lineEnd = staticLayout.getLineEnd(line);
-
- if (line == 0) {
- assertEquals("Line start for first line", 0, lineStart);
- } else {
- assertEquals("Line start for line " + line, breaks[line - 1], lineStart);
- }
-
- if (line == lineCount - 1) {
- assertEquals("Line end for last line", source.length(), lineEnd);
- } else {
- assertEquals("Line end for line " + line, breaks[line], lineEnd);
- }
- }
- }
-
- private static void layoutMaxLines(CharSequence source, int[] breaks, int maxLines) {
- StaticLayout staticLayout = new StaticLayout(source, 0, source.length(), sTextPaint, WIDTH,
- ALIGN, TextDirectionHeuristics.LTR, SPACE_MULTI, SPACE_ADD, false /* includePad */,
- null, WIDTH, maxLines);
-
- debugLayout(source, staticLayout);
-
- final int lineCount = staticLayout.getLineCount();
-
- for (int line = 0; line < lineCount; line++) {
- int lineStart = staticLayout.getLineStart(line);
- int lineEnd = staticLayout.getLineEnd(line);
-
- if (line == 0) {
- assertEquals("Line start for first line", 0, lineStart);
- } else {
- assertEquals("Line start for line " + line, breaks[line - 1], lineStart);
- }
-
- if (line == lineCount - 1 && line != breaks.length - 1) {
- assertEquals("Line end for last line", source.length(), lineEnd);
- } else {
- assertEquals("Line end for line " + line, breaks[line], lineEnd);
- }
- }
- }
-
- private static final int MAX_SPAN_COUNT = 10;
- private static final int[] sSpanStarts = new int[MAX_SPAN_COUNT];
- private static final int[] sSpanEnds = new int[MAX_SPAN_COUNT];
-
- private static MetricAffectingSpan getMetricAffectingSpan() {
- return new MetricAffectingSpan() {
- @Override
- public void updateDrawState(TextPaint tp) { /* empty */ }
-
- @Override
- public void updateMeasureState(TextPaint p) { /* empty */ }
- };
- }
-
- /**
- * Replaces the "<...>" blocks by spans, assuming non overlapping, correctly defined spans
- * @param text
- * @return A CharSequence with '<' '>' replaced by MetricAffectingSpan
- */
- private static CharSequence spanify(String text) {
- int startIndex = text.indexOf('<');
- if (startIndex < 0) return text;
-
- int spanCount = 0;
- do {
- int endIndex = text.indexOf('>');
- if (endIndex < 0) throw new IllegalArgumentException("Unbalanced span markers");
-
- text = text.substring(0, startIndex) + text.substring(startIndex + 1, endIndex)
- + text.substring(endIndex + 1);
-
- sSpanStarts[spanCount] = startIndex;
- sSpanEnds[spanCount] = endIndex - 2;
- spanCount++;
-
- startIndex = text.indexOf('<');
- } while (startIndex >= 0);
-
- SpannableStringBuilder result = new SpannableStringBuilder(text);
- for (int i = 0; i < spanCount; i++) {
- result.setSpan(getMetricAffectingSpan(), sSpanStarts[i], sSpanEnds[i],
- Spanned.SPAN_INCLUSIVE_INCLUSIVE);
- }
- return result;
- }
-
- @Test
- public void testNoLineBreak() {
- // Width lower than WIDTH
- layout("", NO_BREAK);
- layout("I", NO_BREAK);
- layout("V", NO_BREAK);
- layout("X", NO_BREAK);
- layout("L", NO_BREAK);
- layout("I VILI", NO_BREAK);
- layout("XXXX", NO_BREAK);
- layout("LXXXX", NO_BREAK);
-
- // Width equal to WIDTH
- layout("C", NO_BREAK);
- layout("LL", NO_BREAK);
- layout("L XXXX", NO_BREAK);
- layout("XXXXXXXXXX", NO_BREAK);
- layout("XXX XXXXXX", NO_BREAK);
- layout("XXX XXXX X", NO_BREAK);
- layout("XXX XXXXX ", NO_BREAK);
- layout(" XXXXXXXX ", NO_BREAK);
- layout(" XX XXX ", NO_BREAK);
- // 0123456789
-
- // Width greater than WIDTH, but no break
- layout(" XX XXX ", NO_BREAK);
- layout("XX XXX XXX ", NO_BREAK);
- layout("XX XXX XXX ", NO_BREAK);
- layout("XXXXXXXXXX ", NO_BREAK);
- // 01234567890
- }
-
- @Test
- public void testOneLineBreak() {
- // 01234567890
- layout("XX XXX XXXX", new int[] {7});
- layout("XX XXXX XXX", new int[] {8});
- layout("XX XXXXX XX", new int[] {9});
- layout("XX XXXXXX X", new int[] {10});
- // 01234567890
- layout("XXXXXXXXXXX", new int[] {10});
- layout("XXXXXXXXX X", new int[] {10});
- layout("XXXXXXXX XX", new int[] {9});
- layout("XXXXXXX XXX", new int[] {8});
- layout("XXXXXX XXXX", new int[] {7});
- // 01234567890
- layout("LL LL", new int[] {3});
- layout("LLLL", new int[] {2});
- layout("C C", new int[] {2});
- layout("CC", new int[] {1});
- }
-
- @Test
- public void testSpaceAtBreak() {
- // 0123456789012
- layout("XXXX XXXXX X", new int[] {11});
- layout("XXXXXXXXXX X", new int[] {11});
- layout("XXXXXXXXXV X", new int[] {11});
- layout("C X", new int[] {2});
- }
-
- @Test
- public void testMultipleSpacesAtBreak() {
- // 0123456789012
- layout("LXX XXXX", new int[] {4});
- layout("LXX XXXX", new int[] {5});
- layout("LXX XXXX", new int[] {6});
- layout("LXX XXXX", new int[] {7});
- layout("LXX XXXX", new int[] {8});
- }
-
- @Test
- public void testZeroWidthCharacters() {
- // 0123456789012345678901234
- layout("X_X_X_X_X_X_X_X_X_X", NO_BREAK);
- layout("___X_X_X_X_X_X_X_X_X_X___", NO_BREAK);
- layout("C_X", new int[] {2});
- layout("C__X", new int[] {3});
- }
-
- /**
- * Note that when the text has spans, StaticLayout does not use the provided TextPaint to
- * measure text runs anymore. This is probably a bug.
- * To be able to use the fake sTextPaint and make this test pass, use mPaint instead of
- * mWorkPaint in MeasuredText#addStyleRun
- */
- @Test
- public void testWithSpans() {
- if (!SPAN_TESTS_SUPPORTED) return;
-
- layout(spanify("<012 456 89>"), NO_BREAK);
- layout(spanify("012 <456> 89"), NO_BREAK);
- layout(spanify("<012> <456>< 89>"), NO_BREAK);
- layout(spanify("<012> <456> <89>"), NO_BREAK);
-
- layout(spanify("<012> <456> <89>012"), new int[] {8});
- layout(spanify("<012> <456> 89<012>"), new int[] {8});
- layout(spanify("<012> <456> <89><012>"), new int[] {8});
- layout(spanify("<012> <456> 89 <123>"), new int[] {11});
- layout(spanify("<012> <456> 89< 123>"), new int[] {11});
- layout(spanify("<012> <456> <89> <123>"), new int[] {11});
- layout(spanify("012 456 89 <LXX> XX XX"), new int[] {11, 18});
- }
-
- /*
- * Adding a span to the string should not change the layout, since the metrics are unchanged.
- */
- @Test
- public void testWithOneSpan() {
- if (!SPAN_TESTS_SUPPORTED) return;
-
- String[] texts = new String[] { "0123", "012 456", "012 456 89 123", "012 45678 012",
- "012 456 89012 456 89012", "0123456789012" };
-
- MetricAffectingSpan metricAffectingSpan = getMetricAffectingSpan();
-
- for (String text : texts) {
- // Get the line breaks without any span
- int[] breaks = getBreaks(text);
-
- // Add spans on all possible offsets
- for (int spanStart = 0; spanStart < text.length(); spanStart++) {
- for (int spanEnd = spanStart; spanEnd < text.length(); spanEnd++) {
- SpannableStringBuilder ssb = new SpannableStringBuilder(text);
- ssb.setSpan(metricAffectingSpan, spanStart, spanEnd,
- Spanned.SPAN_INCLUSIVE_INCLUSIVE);
- layout(ssb, breaks);
- }
- }
- }
- }
-
- @Test
- public void testWithTwoSpans() {
- if (!SPAN_TESTS_SUPPORTED) return;
-
- String[] texts = new String[] { "0123", "012 456", "012 456 89 123", "012 45678 012",
- "012 456 89012 456 89012", "0123456789012" };
-
- MetricAffectingSpan metricAffectingSpan1 = getMetricAffectingSpan();
- MetricAffectingSpan metricAffectingSpan2 = getMetricAffectingSpan();
-
- for (String text : texts) {
- // Get the line breaks without any span
- int[] breaks = getBreaks(text);
-
- // Add spans on all possible offsets
- for (int spanStart1 = 0; spanStart1 < text.length(); spanStart1++) {
- for (int spanEnd1 = spanStart1; spanEnd1 < text.length(); spanEnd1++) {
- SpannableStringBuilder ssb = new SpannableStringBuilder(text);
- ssb.setSpan(metricAffectingSpan1, spanStart1, spanEnd1,
- Spanned.SPAN_INCLUSIVE_INCLUSIVE);
-
- for (int spanStart2 = 0; spanStart2 < text.length(); spanStart2++) {
- for (int spanEnd2 = spanStart2; spanEnd2 < text.length(); spanEnd2++) {
- ssb.setSpan(metricAffectingSpan2, spanStart2, spanEnd2,
- Spanned.SPAN_INCLUSIVE_INCLUSIVE);
- layout(ssb, breaks);
- }
- }
- }
- }
- }
- }
-
- public static String replace(String string, char c, char r) {
- return string.replaceAll(String.valueOf(c), String.valueOf(r));
- }
-
- @Test
- public void testWithSurrogate() {
- layout("LX" + SURR_FIRST + SURR_SECOND, NO_BREAK);
- layout("LXXXX" + SURR_FIRST + SURR_SECOND, NO_BREAK);
- // LXXXXI (91) + SURR_FIRST + SURR_SECOND (10). Do not break in the middle point of
- // surrogatge pair.
- layout("LXXXXI" + SURR_FIRST + SURR_SECOND, new int[] {6});
-
- // LXXXXI (91) + SURR_SECOND (replaced with REPLACEMENT CHARACTER. width is 7px) fits.
- // Break just after invalid trailing surrogate.
- layout("LXXXXI" + SURR_SECOND + SURR_FIRST, new int[] {7});
-
- layout("C" + SURR_FIRST + SURR_SECOND, new int[] {1});
- }
-
- @Test
- public void testNarrowWidth() {
- int[] widths = new int[] { 0, 4, 10 };
- String[] texts = new String[] { "", "X", " ", "XX", " X", "XXX" };
-
- for (String text: texts) {
- // 15 is such that only one character will fit
- int[] breaks = getBreaks(text, 15);
-
- // Width under 15 should all lead to the same line break
- for (int width: widths) {
- layout(text, breaks, width);
- }
- }
- }
-
- @Test
- public void testNarrowWidthZeroWidth() {
- int[] widths = new int[] { 1, 4 };
- for (int width: widths) {
- layout("X.", new int[] {1}, width);
- layout("X__", NO_BREAK, width);
- layout("X__X", new int[] {3}, width);
- layout("X__X_", new int[] {3}, width);
-
- layout("_", NO_BREAK, width);
- layout("__", NO_BREAK, width);
- layout("_X", new int[] {1}, width);
- layout("_X_", new int[] {1}, width);
- layout("__X__", new int[] {2}, width);
- }
- }
-
- @Test
- public void testMaxLines() {
- layoutMaxLines("C", NO_BREAK, 1);
- layoutMaxLines("C C", new int[] {2}, 1);
- layoutMaxLines("C C", new int[] {2}, 2);
- layoutMaxLines("CC", new int[] {1}, 1);
- layoutMaxLines("CC", new int[] {1}, 2);
- }
-}
diff --git a/libs/hwui/Extensions.cpp b/libs/hwui/Extensions.cpp
index 1e71cb081b39..6b8006cc5a33 100644
--- a/libs/hwui/Extensions.cpp
+++ b/libs/hwui/Extensions.cpp
@@ -31,6 +31,12 @@ namespace android {
namespace uirenderer {
Extensions::Extensions() {
+ if (Properties::getRenderPipelineType() != RenderPipelineType::OpenGL) {
+ //Extensions class is used only by OpenGL pipeline
+ //The code below will crash for SkiaVulkan, because OpenGL is not initialized
+ //TODO: instantiate Extensions class only for OpenGL pipeline
+ return;
+ }
const char* version = (const char*) glGetString(GL_VERSION);
// Section 6.1.5 of the OpenGL ES specification indicates the GL version
diff --git a/libs/hwui/pipeline/skia/SkiaOpenGLReadback.cpp b/libs/hwui/pipeline/skia/SkiaOpenGLReadback.cpp
index 9982a0cfe2bf..75967e9f6503 100644
--- a/libs/hwui/pipeline/skia/SkiaOpenGLReadback.cpp
+++ b/libs/hwui/pipeline/skia/SkiaOpenGLReadback.cpp
@@ -73,7 +73,7 @@ CopyResult SkiaOpenGLReadback::copyImageInto(EGLImageKHR eglImage, const Matrix4
* for reading back float buffers (skbug.com/6945).
*/
if (pixelConfig == kRGBA_half_GrPixelConfig &&
- !DeviceInfo::get()->extensions().hasFloatTextures()) {
+ !grContext->caps()->isConfigTexturable(kRGBA_half_GrPixelConfig)) {
ALOGW("Can't copy surface into bitmap, RGBA_F16 config is not supported");
return CopyResult::DestinationInvalid;
}
diff --git a/libs/hwui/pipeline/skia/SkiaPipeline.cpp b/libs/hwui/pipeline/skia/SkiaPipeline.cpp
index c4bd1e1b10d4..cdf4aee609fb 100644
--- a/libs/hwui/pipeline/skia/SkiaPipeline.cpp
+++ b/libs/hwui/pipeline/skia/SkiaPipeline.cpp
@@ -75,6 +75,12 @@ void SkiaPipeline::unpinImages() {
mPinnedImages.clear();
}
+void SkiaPipeline::onPrepareTree() {
+ // The only time mVectorDrawables is not empty is if prepare tree was called 2 times without
+ // a renderFrame in the middle.
+ mVectorDrawables.clear();
+}
+
void SkiaPipeline::renderLayers(const FrameBuilder::LightGeometry& lightGeometry,
LayerUpdateQueue* layerUpdateQueue, bool opaque, bool wideColorGamut,
const BakedOpRenderer::LightInfo& lightInfo) {
diff --git a/libs/hwui/pipeline/skia/SkiaPipeline.h b/libs/hwui/pipeline/skia/SkiaPipeline.h
index 3e6ae306217c..dc0b8f6dd2bc 100644
--- a/libs/hwui/pipeline/skia/SkiaPipeline.h
+++ b/libs/hwui/pipeline/skia/SkiaPipeline.h
@@ -37,6 +37,7 @@ public:
bool pinImages(std::vector<SkImage*>& mutableImages) override;
bool pinImages(LsaVector<sk_sp<Bitmap>>& images) override { return false; }
void unpinImages() override;
+ void onPrepareTree() override;
void renderLayers(const FrameBuilder::LightGeometry& lightGeometry,
LayerUpdateQueue* layerUpdateQueue, bool opaque, bool wideColorGamut,
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index 5d7f5948b0ec..ad684db56d94 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -331,6 +331,7 @@ void CanvasContext::prepareTree(TreeInfo& info, int64_t* uiFrameInfo,
info.layerUpdateQueue = &mLayerUpdateQueue;
mAnimationContext->startFrame(info.mode);
+ mRenderPipeline->onPrepareTree();
for (const sp<RenderNode>& node : mRenderNodes) {
// Only the primary target node will be drawn full - all other nodes would get drawn in
// real time mode. In case of a window, the primary node is the window content and the other
diff --git a/libs/hwui/renderthread/IRenderPipeline.h b/libs/hwui/renderthread/IRenderPipeline.h
index f9b6e384d211..0bb3889c7a1d 100644
--- a/libs/hwui/renderthread/IRenderPipeline.h
+++ b/libs/hwui/renderthread/IRenderPipeline.h
@@ -81,6 +81,7 @@ public:
virtual bool pinImages(std::vector<SkImage*>& mutableImages) = 0;
virtual bool pinImages(LsaVector<sk_sp<Bitmap>>& images) = 0;
virtual void unpinImages() = 0;
+ virtual void onPrepareTree() = 0;
virtual ~IRenderPipeline() {}
};
diff --git a/libs/hwui/renderthread/OpenGLPipeline.h b/libs/hwui/renderthread/OpenGLPipeline.h
index 4ca19fb6245c..1f467c164d7f 100644
--- a/libs/hwui/renderthread/OpenGLPipeline.h
+++ b/libs/hwui/renderthread/OpenGLPipeline.h
@@ -58,6 +58,7 @@ public:
bool pinImages(std::vector<SkImage*>& mutableImages) override { return false; }
bool pinImages(LsaVector<sk_sp<Bitmap>>& images) override;
void unpinImages() override;
+ void onPrepareTree() override {}
static void destroyLayer(RenderNode* node);
static void prepareToDraw(const RenderThread& thread, Bitmap* bitmap);
static void invokeFunctor(const RenderThread& thread, Functor* functor);
diff --git a/libs/hwui/tests/unit/SkiaPipelineTests.cpp b/libs/hwui/tests/unit/SkiaPipelineTests.cpp
index b397b151ad76..f430ce633717 100644
--- a/libs/hwui/tests/unit/SkiaPipelineTests.cpp
+++ b/libs/hwui/tests/unit/SkiaPipelineTests.cpp
@@ -56,6 +56,40 @@ RENDERTHREAD_SKIA_PIPELINE_TEST(SkiaPipeline, renderFrame) {
ASSERT_EQ(TestUtils::getColor(surface, 0, 0), SK_ColorRED);
}
+RENDERTHREAD_SKIA_PIPELINE_TEST(SkiaPipeline, testOnPrepareTree) {
+
+ auto redNode = TestUtils::createSkiaNode(0, 0, 1, 1,
+ [](RenderProperties& props, SkiaRecordingCanvas& redCanvas) {
+ redCanvas.drawColor(SK_ColorRED, SkBlendMode::kSrcOver);
+ });
+
+ LayerUpdateQueue layerUpdateQueue;
+ SkRect dirty = SkRect::MakeLargest();
+ std::vector<sp<RenderNode>> renderNodes;
+ renderNodes.push_back(redNode);
+ bool opaque = true;
+ android::uirenderer::Rect contentDrawBounds(0, 0, 1, 1);
+ auto pipeline = std::make_unique<SkiaOpenGLPipeline>(renderThread);
+ {
+ //add a pointer to a deleted vector drawable object in the pipeline
+ sp<VectorDrawableRoot> dirtyVD(new VectorDrawableRoot(new VectorDrawable::Group()));
+ dirtyVD->mutateProperties()->setScaledSize(5,5);
+ pipeline->getVectorDrawables()->push_back(dirtyVD.get());
+ }
+
+ //pipeline should clean list of dirty vector drawables before prepare tree
+ pipeline->onPrepareTree();
+
+ auto surface = SkSurface::MakeRasterN32Premul(1, 1);
+ surface->getCanvas()->drawColor(SK_ColorBLUE, SkBlendMode::kSrcOver);
+ ASSERT_EQ(TestUtils::getColor(surface, 0, 0), SK_ColorBLUE);
+
+ //drawFrame will crash if "SkiaPipeline::onPrepareTree" did not clean invalid VD pointer
+ pipeline->renderFrame(layerUpdateQueue, dirty, renderNodes,
+ opaque, false, contentDrawBounds, surface);
+ ASSERT_EQ(TestUtils::getColor(surface, 0, 0), SK_ColorRED);
+}
+
RENDERTHREAD_SKIA_PIPELINE_TEST(SkiaPipeline, renderFrameCheckOpaque) {
auto halfGreenNode = TestUtils::createSkiaNode(0, 0, 2, 2,
[](RenderProperties& props, SkiaRecordingCanvas& bottomHalfGreenCanvas) {
diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/OWNERS b/packages/SettingsLib/src/com/android/settingslib/wifi/OWNERS
new file mode 100644
index 000000000000..d5d2e9e8c146
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/wifi/OWNERS
@@ -0,0 +1,7 @@
+# Default reviewers for this and subdirectories.
+asapperstein@google.com
+asargent@google.com
+dling@google.com
+zhfan@google.com
+
+# Emergency approvers in case the above are not available \ No newline at end of file
diff --git a/services/core/java/com/android/server/am/LockTaskController.java b/services/core/java/com/android/server/am/LockTaskController.java
index 940f9051ec1e..1c094c174e6a 100644
--- a/services/core/java/com/android/server/am/LockTaskController.java
+++ b/services/core/java/com/android/server/am/LockTaskController.java
@@ -327,7 +327,9 @@ public class LockTaskController {
if (getDevicePolicyManager() != null) {
getDevicePolicyManager().notifyLockTaskModeChanged(false, null, userId);
}
- getLockTaskNotify().show(false);
+ if (mLockTaskModeState == LOCK_TASK_MODE_PINNED) {
+ getLockTaskNotify().showPinningExitToast();
+ }
try {
boolean shouldLockKeyguard = Settings.Secure.getIntForUser(
mContext.getContentResolver(),
@@ -349,10 +351,13 @@ public class LockTaskController {
}
/**
- * Show the lock task violation toast.
+ * Show the lock task violation toast. Currently we only show toast for screen pinning mode, and
+ * no-op if the device is in locked mode.
*/
void showLockTaskToast() {
- mHandler.post(() -> getLockTaskNotify().showToast(mLockTaskModeState));
+ if (mLockTaskModeState == LOCK_TASK_MODE_PINNED) {
+ mHandler.post(() -> getLockTaskNotify().showEscapeToast());
+ }
}
// Starting lock task
@@ -439,7 +444,9 @@ public class LockTaskController {
private void performStartLockTask(String packageName, int userId, int lockTaskModeState) {
// When lock task starts, we disable the status bars.
try {
- getLockTaskNotify().show(true);
+ if (lockTaskModeState == LOCK_TASK_MODE_PINNED) {
+ getLockTaskNotify().showPinningStartToast();
+ }
mLockTaskModeState = lockTaskModeState;
if (getStatusBarService() != null) {
int flags = 0;
diff --git a/services/core/java/com/android/server/am/LockTaskNotify.java b/services/core/java/com/android/server/am/LockTaskNotify.java
index 0412db5e49c9..5d6e9b58881f 100644
--- a/services/core/java/com/android/server/am/LockTaskNotify.java
+++ b/services/core/java/com/android/server/am/LockTaskNotify.java
@@ -16,7 +16,6 @@
package com.android.server.am;
-import android.app.ActivityManager;
import android.content.Context;
import android.os.Handler;
import android.os.Message;
@@ -29,7 +28,7 @@ import com.android.internal.R;
/**
* Helper to manage showing/hiding a image to notify them that they are entering
- * or exiting lock-to-app mode.
+ * or exiting screen pinning mode.
*/
public class LockTaskNotify {
private static final String TAG = "LockTaskNotify";
@@ -45,20 +44,22 @@ public class LockTaskNotify {
mHandler = new H();
}
- public void showToast(int lockTaskModeState) {
- mHandler.obtainMessage(H.SHOW_TOAST, lockTaskModeState, 0 /* Not used */).sendToTarget();
+ /** Show "Screen pinned" toast. */
+ void showPinningStartToast() {
+ makeAllUserToastAndShow(R.string.lock_to_app_start);
}
- public void handleShowToast(int lockTaskModeState) {
- String text = null;
- if (lockTaskModeState == ActivityManager.LOCK_TASK_MODE_LOCKED) {
- text = mContext.getString(R.string.lock_to_app_toast_locked);
- } else if (lockTaskModeState == ActivityManager.LOCK_TASK_MODE_PINNED) {
- text = mContext.getString(R.string.lock_to_app_toast);
- }
- if (text == null) {
- return;
- }
+ /** Show "Screen unpinned" toast. */
+ void showPinningExitToast() {
+ makeAllUserToastAndShow(R.string.lock_to_app_exit);
+ }
+
+ /** Show a toast that describes the gesture the user should use to escape pinned mode. */
+ void showEscapeToast() {
+ mHandler.obtainMessage(H.SHOW_ESCAPE_TOAST).sendToTarget();
+ }
+
+ private void handleShowEscapeToast() {
long showToastTime = SystemClock.elapsedRealtime();
if ((showToastTime - mLastShowToastTime) < SHOW_TOAST_MINIMUM_INTERVAL) {
Slog.i(TAG, "Ignore toast since it is requested in very short interval.");
@@ -67,20 +68,12 @@ public class LockTaskNotify {
if (mLastToast != null) {
mLastToast.cancel();
}
- mLastToast = makeAllUserToastAndShow(text);
+ mLastToast = makeAllUserToastAndShow(R.string.lock_to_app_toast);
mLastShowToastTime = showToastTime;
}
- public void show(boolean starting) {
- int showString = R.string.lock_to_app_exit;
- if (starting) {
- showString = R.string.lock_to_app_start;
- }
- makeAllUserToastAndShow(mContext.getString(showString));
- }
-
- private Toast makeAllUserToastAndShow(String text) {
- Toast toast = Toast.makeText(mContext, text, Toast.LENGTH_LONG);
+ private Toast makeAllUserToastAndShow(int resId) {
+ Toast toast = Toast.makeText(mContext, resId, Toast.LENGTH_LONG);
toast.getWindowParams().privateFlags |=
WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
toast.show();
@@ -88,13 +81,13 @@ public class LockTaskNotify {
}
private final class H extends Handler {
- private static final int SHOW_TOAST = 3;
+ private static final int SHOW_ESCAPE_TOAST = 3;
@Override
public void handleMessage(Message msg) {
switch(msg.what) {
- case SHOW_TOAST:
- handleShowToast(msg.arg1);
+ case SHOW_ESCAPE_TOAST:
+ handleShowEscapeToast();
break;
}
}
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index ceb0ad07e72c..6520dc94072f 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -1654,11 +1654,23 @@ public class PhoneWindowManager implements WindowManagerPolicy {
mScreenshotChordVolumeDownKeyConsumed = true;
mA11yShortcutChordVolumeUpKeyConsumed = true;
mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_ACCESSIBILITY_SHORTCUT),
- ViewConfiguration.get(mContext).getAccessibilityShortcutKeyTimeout());
+ getAccessibilityShortcutTimeout());
}
}
}
+ private long getAccessibilityShortcutTimeout() {
+ ViewConfiguration config = ViewConfiguration.get(mContext);
+ try {
+ return Settings.Secure.getIntForUser(mContext.getContentResolver(),
+ Settings.Secure.ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN, mCurrentUserId) == 0
+ ? config.getAccessibilityShortcutKeyTimeout()
+ : config.getAccessibilityShortcutKeyTimeoutAfterConfirmation();
+ } catch (Settings.SettingNotFoundException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
private long getScreenshotChordLongPressDelay() {
if (mKeyguardDelegate.isShowing()) {
// Double the time it takes to take a screenshot from the keyguard
@@ -3866,8 +3878,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
mAccessibilityTvScheduled = true;
Message msg = Message.obtain(mHandler, MSG_ACCESSIBILITY_TV);
msg.setAsynchronous(true);
- mHandler.sendMessageDelayed(msg,
- ViewConfiguration.get(mContext).getAccessibilityShortcutKeyTimeout());
+ mHandler.sendMessageDelayed(msg, getAccessibilityShortcutTimeout());
}
} else if (mAccessibilityTvScheduled) {
mHandler.removeMessages(MSG_ACCESSIBILITY_TV);
diff --git a/services/tests/servicestests/src/com/android/server/am/LockTaskControllerTest.java b/services/tests/servicestests/src/com/android/server/am/LockTaskControllerTest.java
index f9d7f9d4904a..4c1d3e9f0003 100644
--- a/services/tests/servicestests/src/com/android/server/am/LockTaskControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/LockTaskControllerTest.java
@@ -189,6 +189,8 @@ public class LockTaskControllerTest {
// THEN lock task mode should be started
verifyLockTaskStarted(STATUS_BAR_MASK_PINNED);
+ // THEN screen pinning toast should be shown
+ verify(mLockTaskNotify).showPinningStartToast();
}
@Test
@@ -255,8 +257,6 @@ public class LockTaskControllerTest {
// WHEN system calls stopLockTaskMode
mLockTaskController.stopLockTaskMode(true, SYSTEM_UID);
- // THEN a lock tash toast should be shown
- verify(mLockTaskNotify).showToast(LOCK_TASK_MODE_LOCKED);
// THEN lock task mode should still be active
assertEquals(LOCK_TASK_MODE_LOCKED, mLockTaskController.getLockTaskModeState());
}
@@ -302,6 +302,8 @@ public class LockTaskControllerTest {
verifyLockTaskStopped(times(1));
// THEN the keyguard should be shown
verify(mLockPatternUtils).requireCredentialEntry(UserHandle.USER_ALL);
+ // THEN screen pinning toast should be shown
+ verify(mLockTaskNotify).showPinningExitToast();
}
@Test