Merge "Clarify WebView's lack of plugin support."
diff --git a/CleanSpec.mk b/CleanSpec.mk
index 3f19b8f..2247e43 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -246,6 +246,7 @@
$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/statsdprotolite_intermediates)
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/framework/com.android.mediadrm.signer.jar)
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/framework/com.android.location.provider.jar)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/framework/com.android.future.usb.accessory.jar)
# ******************************************************************
# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST ABOVE THIS BANNER
# ******************************************************************
diff --git a/api/current.txt b/api/current.txt
index 20e62c0..c641a8c 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -41805,6 +41805,7 @@
field public static final java.lang.String KEY_SMS_REQUIRES_DESTINATION_NUMBER_CONVERSION_BOOL = "sms_requires_destination_number_conversion_bool";
field public static final java.lang.String KEY_SUPPORT_3GPP_CALL_FORWARDING_WHILE_ROAMING_BOOL = "support_3gpp_call_forwarding_while_roaming_bool";
field public static final java.lang.String KEY_SUPPORT_CONFERENCE_CALL_BOOL = "support_conference_call_bool";
+ field public static final java.lang.String KEY_SUPPORT_EMERGENCY_SMS_OVER_IMS_BOOL = "support_emergency_sms_over_ims_bool";
field public static final java.lang.String KEY_SUPPORT_PAUSE_IMS_VIDEO_CALLS_BOOL = "support_pause_ims_video_calls_bool";
field public static final java.lang.String KEY_SUPPORT_SWAP_AFTER_MERGE_BOOL = "support_swap_after_merge_bool";
field public static final java.lang.String KEY_TREAT_DOWNGRADED_VIDEO_CALLS_AS_VIDEO_CALLS_BOOL = "treat_downgraded_video_calls_as_video_calls_bool";
diff --git a/api/test-current.txt b/api/test-current.txt
index b08ae0e..718c0f2 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -130,6 +130,12 @@
method public android.content.ComponentName getEffectsSuppressor();
}
+ public final class PictureInPictureParams implements android.os.Parcelable {
+ method public java.util.List<android.app.RemoteAction> getActions();
+ method public float getAspectRatio();
+ method public android.graphics.Rect getSourceRectHint();
+ }
+
public class TimePickerDialog extends android.app.AlertDialog implements android.content.DialogInterface.OnClickListener android.widget.TimePicker.OnTimeChangedListener {
method public android.widget.TimePicker getTimePicker();
}
diff --git a/config/hiddenapi-light-greylist.txt b/config/hiddenapi-light-greylist.txt
index 0941d39..f805dea 100644
--- a/config/hiddenapi-light-greylist.txt
+++ b/config/hiddenapi-light-greylist.txt
@@ -857,9 +857,6 @@
Landroid/app/PictureInPictureArgs;-><init>()V
Landroid/app/PictureInPictureArgs;->setActions(Ljava/util/List;)V
Landroid/app/PictureInPictureArgs;->setAspectRatio(F)V
-Landroid/app/PictureInPictureParams;->getActions()Ljava/util/List;
-Landroid/app/PictureInPictureParams;->getAspectRatio()F
-Landroid/app/PictureInPictureParams;->getSourceRectHint()Landroid/graphics/Rect;
Landroid/app/Presentation;->createPresentationContext(Landroid/content/Context;Landroid/view/Display;I)Landroid/content/Context;
Landroid/app/ProgressDialog;->mMessageView:Landroid/widget/TextView;
Landroid/app/ProgressDialog;->mProgress:Landroid/widget/ProgressBar;
diff --git a/core/java/android/app/PictureInPictureParams.java b/core/java/android/app/PictureInPictureParams.java
index 7313b0d..edaae75 100644
--- a/core/java/android/app/PictureInPictureParams.java
+++ b/core/java/android/app/PictureInPictureParams.java
@@ -17,6 +17,7 @@
package android.app;
import android.annotation.Nullable;
+import android.annotation.TestApi;
import android.graphics.Rect;
import android.os.Parcel;
import android.os.Parcelable;
@@ -181,6 +182,7 @@
* @return the aspect ratio. If none is set, return 0.
* @hide
*/
+ @TestApi
public float getAspectRatio() {
if (mAspectRatio != null) {
return mAspectRatio.floatValue();
@@ -205,6 +207,7 @@
* @return the set of user actions.
* @hide
*/
+ @TestApi
public List<RemoteAction> getActions() {
return mUserActions;
}
@@ -231,6 +234,7 @@
* @return the source rect hint
* @hide
*/
+ @TestApi
public Rect getSourceRectHint() {
return mSourceRectHint;
}
diff --git a/core/java/android/app/backup/BackupAgent.java b/core/java/android/app/backup/BackupAgent.java
index 9657922..ec2cf0c 100644
--- a/core/java/android/app/backup/BackupAgent.java
+++ b/core/java/android/app/backup/BackupAgent.java
@@ -43,7 +43,6 @@
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
-import java.util.Collection;
import java.util.LinkedList;
import java.util.Map;
import java.util.Set;
@@ -833,7 +832,7 @@
}
if (excludes != null &&
- isFileSpecifiedInPathList(destination, excludes)) {
+ BackupUtils.isFileSpecifiedInPathList(destination, excludes)) {
if (Log.isLoggable(FullBackup.TAG_XML_PARSER, Log.VERBOSE)) {
Log.v(FullBackup.TAG_XML_PARSER,
"onRestoreFile: \"" + destinationCanonicalPath + "\": listed in"
@@ -847,7 +846,8 @@
// it's a small list), we'll go through and look for it.
boolean explicitlyIncluded = false;
for (Set<PathWithRequiredFlags> domainIncludes : includes.values()) {
- explicitlyIncluded |= isFileSpecifiedInPathList(destination, domainIncludes);
+ explicitlyIncluded |=
+ BackupUtils.isFileSpecifiedInPathList(destination, domainIncludes);
if (explicitlyIncluded) {
break;
}
@@ -866,33 +866,6 @@
}
/**
- * @return True if the provided file is either directly in the provided list, or the provided
- * file is within a directory in the list.
- */
- private boolean isFileSpecifiedInPathList(File file,
- Collection<PathWithRequiredFlags> canonicalPathList) throws IOException {
- for (PathWithRequiredFlags canonical : canonicalPathList) {
- String canonicalPath = canonical.getPath();
- File fileFromList = new File(canonicalPath);
- if (fileFromList.isDirectory()) {
- if (file.isDirectory()) {
- // If they are both directories check exact equals.
- return file.equals(fileFromList);
- } else {
- // O/w we have to check if the file is within the directory from the list.
- return file.getCanonicalPath().startsWith(canonicalPath);
- }
- } else {
- if (file.equals(fileFromList)) {
- // Need to check the explicit "equals" so we don't end up with substrings.
- return true;
- }
- }
- }
- return false;
- }
-
- /**
* Only specialized platform agents should overload this entry point to support
* restores to crazy non-app locations.
* @hide
diff --git a/core/java/android/app/backup/BackupUtils.java b/core/java/android/app/backup/BackupUtils.java
new file mode 100644
index 0000000..8cf8a84
--- /dev/null
+++ b/core/java/android/app/backup/BackupUtils.java
@@ -0,0 +1,58 @@
+/*
+ * 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.app.backup;
+
+import android.app.backup.FullBackup.BackupScheme.PathWithRequiredFlags;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Collection;
+
+/** @hide */
+public class BackupUtils {
+
+ private BackupUtils() {}
+
+ /**
+ * Returns {@code true} if {@code file} is either directly in {@code canonicalPathList} or is a
+ * file contained in a directory in the list.
+ */
+ public static boolean isFileSpecifiedInPathList(
+ File file, Collection<PathWithRequiredFlags> canonicalPathList) throws IOException {
+ for (PathWithRequiredFlags canonical : canonicalPathList) {
+ String canonicalPath = canonical.getPath();
+ File fileFromList = new File(canonicalPath);
+ if (fileFromList.isDirectory()) {
+ if (file.isDirectory()) {
+ // If they are both directories check exact equals.
+ if (file.equals(fileFromList)) {
+ return true;
+ }
+ } else {
+ // O/w we have to check if the file is within the directory from the list.
+ if (file.toPath().startsWith(canonicalPath)) {
+ return true;
+ }
+ }
+ } else if (file.equals(fileFromList)) {
+ // Need to check the explicit "equals" so we don't end up with substrings.
+ return true;
+ }
+ }
+ return false;
+ }
+}
diff --git a/core/java/android/view/SurfaceSession.java b/core/java/android/view/SurfaceSession.java
index b5912bc..ee08bf7 100644
--- a/core/java/android/view/SurfaceSession.java
+++ b/core/java/android/view/SurfaceSession.java
@@ -37,7 +37,12 @@
}
public SurfaceSession(Surface root) {
- mNativeClient = nativeCreateScoped(root.mNativeObject);
+ synchronized (root.mLock) {
+ if (root.mNativeObject == 0) {
+ throw new IllegalStateException("Surface is not initialized or has been released");
+ }
+ mNativeClient = nativeCreateScoped(root.mNativeObject);
+ }
}
/* no user serviceable parts here ... */
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 964ee5e..0e5527d 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -23993,6 +23993,10 @@
Log.w(VIEW_LOG_TAG, "startDragAndDrop called on a detached view.");
return false;
}
+ if (!mAttachInfo.mViewRootImpl.mSurface.isValid()) {
+ Log.w(VIEW_LOG_TAG, "startDragAndDrop called with an invalid surface.");
+ return false;
+ }
if (data != null) {
data.prepareToLeaveProcess((flags & View.DRAG_FLAG_GLOBAL) != 0);
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 381758f..aef48fa 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -2914,7 +2914,7 @@
<string name="config_keyguardComponent" translatable="false">com.android.systemui/com.android.systemui.keyguard.KeyguardService</string>
<!-- Limit for the number of face templates per user -->
- <integer name="config_face_MaxTemplatesPerUser">1</integer>
+ <integer name="config_faceMaxTemplatesPerUser">1</integer>
<!-- For performance and storage reasons, limit the number of fingerprints per user -->
<integer name="config_fingerprintMaxTemplatesPerUser">5</integer>
@@ -3374,6 +3374,9 @@
<!-- URI for in call notification sound -->
<string translatable="false" name="config_inCallNotificationSound">/system/media/audio/ui/InCallNotification.ogg</string>
+ <!-- Default number of notifications from the same app before they are automatically grouped by the OS -->
+ <integer translatable="false" name="config_autoGroupAtCount">4</integer>
+
<!-- The OEM specified sensor type for the lift trigger to launch the camera app. -->
<integer name="config_cameraLiftTriggerSensorType">-1</integer>
<!-- The OEM specified sensor string type for the gesture to launch camera app, this value
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 99d0dba..6054180 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -2446,7 +2446,7 @@
<java-symbol type="string" name="face_name_template" />
<!-- Face config -->
- <java-symbol type="integer" name="config_face_MaxTemplatesPerUser" />
+ <java-symbol type="integer" name="config_faceMaxTemplatesPerUser" />
<!-- From various Material changes -->
<java-symbol type="attr" name="titleTextAppearance" />
@@ -3266,6 +3266,7 @@
<java-symbol type="bool" name="config_handleVolumeKeysInWindowManager" />
<java-symbol type="dimen" name="config_inCallNotificationVolume" />
<java-symbol type="string" name="config_inCallNotificationSound" />
+ <java-symbol type="integer" name="config_autoGroupAtCount" />
<java-symbol type="bool" name="config_dozeAlwaysOnDisplayAvailable" />
<java-symbol type="bool" name="config_dozeAlwaysOnEnabled" />
<java-symbol type="bool" name="config_displayBlanksAfterDoze" />
diff --git a/libs/usb/Android.bp b/libs/usb/Android.bp
index b8f2904..027a748 100644
--- a/libs/usb/Android.bp
+++ b/libs/usb/Android.bp
@@ -1 +1,23 @@
+//
+// 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.
+//
+
+java_sdk_library {
+ name: "com.android.future.usb.accessory",
+ srcs: ["src/**/*.java"],
+ api_packages: ["com.android.future.usb"],
+}
+
subdirs = ["tests/*"]
diff --git a/libs/usb/Android.mk b/libs/usb/Android.mk
deleted file mode 100644
index 129828f..0000000
--- a/libs/usb/Android.mk
+++ /dev/null
@@ -1,27 +0,0 @@
-#
-# Copyright (C) 2011 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.
-#
-
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(call all-java-files-under,src)
-
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_MODULE:= com.android.future.usb.accessory
-
-include $(BUILD_JAVA_LIBRARY)
diff --git a/libs/usb/api/current.txt b/libs/usb/api/current.txt
new file mode 100644
index 0000000..8488db5
--- /dev/null
+++ b/libs/usb/api/current.txt
@@ -0,0 +1,25 @@
+package com.android.future.usb {
+
+ public class UsbAccessory {
+ method public java.lang.String getDescription();
+ method public java.lang.String getManufacturer();
+ method public java.lang.String getModel();
+ method public java.lang.String getSerial();
+ method public java.lang.String getUri();
+ method public java.lang.String getVersion();
+ }
+
+ public class UsbManager {
+ method public static com.android.future.usb.UsbAccessory getAccessory(android.content.Intent);
+ method public com.android.future.usb.UsbAccessory[] getAccessoryList();
+ method public static com.android.future.usb.UsbManager getInstance(android.content.Context);
+ method public boolean hasPermission(com.android.future.usb.UsbAccessory);
+ method public android.os.ParcelFileDescriptor openAccessory(com.android.future.usb.UsbAccessory);
+ method public void requestPermission(com.android.future.usb.UsbAccessory, android.app.PendingIntent);
+ field public static final java.lang.String ACTION_USB_ACCESSORY_ATTACHED = "android.hardware.usb.action.USB_ACCESSORY_ATTACHED";
+ field public static final java.lang.String ACTION_USB_ACCESSORY_DETACHED = "android.hardware.usb.action.USB_ACCESSORY_DETACHED";
+ field public static final java.lang.String EXTRA_PERMISSION_GRANTED = "permission";
+ }
+
+}
+
diff --git a/libs/usb/api/removed.txt b/libs/usb/api/removed.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/libs/usb/api/removed.txt
diff --git a/libs/usb/api/system-current.txt b/libs/usb/api/system-current.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/libs/usb/api/system-current.txt
diff --git a/libs/usb/api/system-removed.txt b/libs/usb/api/system-removed.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/libs/usb/api/system-removed.txt
diff --git a/libs/usb/api/test-current.txt b/libs/usb/api/test-current.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/libs/usb/api/test-current.txt
diff --git a/libs/usb/api/test-removed.txt b/libs/usb/api/test-removed.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/libs/usb/api/test-removed.txt
diff --git a/libs/usb/tests/AccessoryChat/Android.mk b/libs/usb/tests/AccessoryChat/Android.mk
index ecb455a..cfe2da1 100644
--- a/libs/usb/tests/AccessoryChat/Android.mk
+++ b/libs/usb/tests/AccessoryChat/Android.mk
@@ -23,4 +23,6 @@
LOCAL_PACKAGE_NAME := AccessoryChat
+LOCAL_PRIVATE_PLATFORM_APIS := true
+
include $(BUILD_PACKAGE)
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
index 1942fc1..745f81d 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
@@ -143,6 +143,7 @@
mSecurityViewFlipper.addView(v);
updateSecurityView(v);
view = (KeyguardSecurityView)v;
+ view.reset();
}
return view;
diff --git a/services/core/java/com/android/server/AlarmManagerService.java b/services/core/java/com/android/server/AlarmManagerService.java
index 3261209..cc5acdf 100644
--- a/services/core/java/com/android/server/AlarmManagerService.java
+++ b/services/core/java/com/android/server/AlarmManagerService.java
@@ -2685,19 +2685,23 @@
private void validateLastAlarmExpiredLocked(long nowElapsed) {
final StringBuilder errorMsg = new StringBuilder();
boolean stuck = false;
- if (mNextNonWakeup < nowElapsed && mLastWakeup < (mNextNonWakeup - 30_000)) {
+ if (mNextNonWakeup < (nowElapsed - 10_000) && mLastWakeup < mNextNonWakeup) {
stuck = true;
errorMsg.append("[mNextNonWakeup=");
TimeUtils.formatDuration(mNextNonWakeup - nowElapsed, errorMsg);
+ errorMsg.append(" set at ");
+ TimeUtils.formatDuration(mNextNonWakeUpSetAt, errorMsg);
errorMsg.append(", mLastWakeup=");
TimeUtils.formatDuration(mLastWakeup - nowElapsed, errorMsg);
errorMsg.append(", timerfd_gettime=" + getNextAlarm(mNativeData, ELAPSED_REALTIME));
errorMsg.append("];");
}
- if (mNextWakeup < nowElapsed && mLastWakeup < (mNextWakeup - 30_000)) {
+ if (mNextWakeup < (nowElapsed - 10_000) && mLastWakeup < mNextWakeup) {
stuck = true;
errorMsg.append("[mNextWakeup=");
TimeUtils.formatDuration(mNextWakeup - nowElapsed, errorMsg);
+ errorMsg.append(" set at ");
+ TimeUtils.formatDuration(mNextWakeUpSetAt, errorMsg);
errorMsg.append(", mLastWakeup=");
TimeUtils.formatDuration(mLastWakeup - nowElapsed, errorMsg);
errorMsg.append(", timerfd_gettime="
diff --git a/services/core/java/com/android/server/biometrics/face/FaceService.java b/services/core/java/com/android/server/biometrics/face/FaceService.java
index d2a29e4..35679a88 100644
--- a/services/core/java/com/android/server/biometrics/face/FaceService.java
+++ b/services/core/java/com/android/server/biometrics/face/FaceService.java
@@ -541,7 +541,7 @@
@Override
protected boolean hasReachedEnrollmentLimit(int userId) {
final int limit = getContext().getResources().getInteger(
- com.android.internal.R.integer.config_face_MaxTemplatesPerUser);
+ com.android.internal.R.integer.config_faceMaxTemplatesPerUser);
final int enrolled = FaceService.this.getEnrolledFaces(userId).size();
if (enrolled >= limit) {
Slog.w(TAG, "Too many faces registered");
diff --git a/services/core/java/com/android/server/notification/GroupHelper.java b/services/core/java/com/android/server/notification/GroupHelper.java
index ce805aad..b1cd627 100644
--- a/services/core/java/com/android/server/notification/GroupHelper.java
+++ b/services/core/java/com/android/server/notification/GroupHelper.java
@@ -32,16 +32,17 @@
private static final String TAG = "GroupHelper";
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
- protected static final int AUTOGROUP_AT_COUNT = 4;
protected static final String AUTOGROUP_KEY = "ranker_group";
private final Callback mCallback;
+ private final int mAutoGroupAtCount;
// Map of user : <Map of package : notification keys>. Only contains notifications that are not
// grouped by the app (aka no group or sort key).
Map<Integer, Map<String, LinkedHashSet<String>>> mUngroupedNotifications = new HashMap<>();
- public GroupHelper(Callback callback) {;
+ public GroupHelper(int autoGroupAtCount, Callback callback) {
+ mAutoGroupAtCount = autoGroupAtCount;
mCallback = callback;
}
@@ -68,7 +69,7 @@
notificationsForPackage.add(sbn.getKey());
ungroupedNotificationsByUser.put(sbn.getPackageName(), notificationsForPackage);
- if (notificationsForPackage.size() >= AUTOGROUP_AT_COUNT
+ if (notificationsForPackage.size() >= mAutoGroupAtCount
|| autogroupSummaryExists) {
notificationsToGroup.addAll(notificationsForPackage);
}
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 6402b7b..52f4461 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -400,6 +400,7 @@
private SnoozeHelper mSnoozeHelper;
private GroupHelper mGroupHelper;
+ private int mAutoGroupAtCount;
private boolean mIsTelevision;
private MetricsLogger mMetricsLogger;
@@ -1565,7 +1566,9 @@
}
private GroupHelper getGroupHelper() {
- return new GroupHelper(new GroupHelper.Callback() {
+ mAutoGroupAtCount =
+ getContext().getResources().getInteger(R.integer.config_autoGroupAtCount);
+ return new GroupHelper(mAutoGroupAtCount, new GroupHelper.Callback() {
@Override
public void addAutoGroup(String key) {
synchronized (mNotificationLock) {
diff --git a/services/robotests/src/android/app/backup/BackupUtilsTest.java b/services/robotests/src/android/app/backup/BackupUtilsTest.java
new file mode 100644
index 0000000..04a2a14
--- /dev/null
+++ b/services/robotests/src/android/app/backup/BackupUtilsTest.java
@@ -0,0 +1,195 @@
+/*
+ * 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.app.backup;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.app.backup.FullBackup.BackupScheme.PathWithRequiredFlags;
+import android.content.Context;
+import android.platform.test.annotations.Presubmit;
+
+import com.android.server.testing.FrameworkRobolectricTestRunner;
+import com.android.server.testing.SystemLoaderPackages;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+import org.robolectric.annotation.internal.DoNotInstrument;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Collection;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+@RunWith(FrameworkRobolectricTestRunner.class)
+@Config(manifest = Config.NONE, sdk = 26)
+@SystemLoaderPackages({"android.app.backup"})
+@Presubmit
+@DoNotInstrument
+public class BackupUtilsTest {
+ private Context mContext;
+
+ @Before
+ public void setUp() throws Exception {
+ mContext = RuntimeEnvironment.application;
+ }
+
+ @Test
+ public void testIsFileSpecifiedInPathList_whenFileAndPathListHasIt() throws Exception {
+ boolean isSpecified =
+ BackupUtils.isFileSpecifiedInPathList(file("a/b.txt"), paths(file("a/b.txt")));
+
+ assertThat(isSpecified).isTrue();
+ }
+
+ @Test
+ public void testIsFileSpecifiedInPathList_whenFileAndPathListHasItsDirectory()
+ throws Exception {
+ boolean isSpecified =
+ BackupUtils.isFileSpecifiedInPathList(file("a/b.txt"), paths(directory("a")));
+
+ assertThat(isSpecified).isTrue();
+ }
+
+ @Test
+ public void testIsFileSpecifiedInPathList_whenFileAndPathListHasOtherFile() throws Exception {
+ boolean isSpecified =
+ BackupUtils.isFileSpecifiedInPathList(file("a/b.txt"), paths(file("a/c.txt")));
+
+ assertThat(isSpecified).isFalse();
+ }
+
+ @Test
+ public void testIsFileSpecifiedInPathList_whenFileAndPathListEmpty() throws Exception {
+ boolean isSpecified = BackupUtils.isFileSpecifiedInPathList(file("a/b.txt"), paths());
+
+ assertThat(isSpecified).isFalse();
+ }
+
+ @Test
+ public void testIsFileSpecifiedInPathList_whenDirectoryAndPathListHasIt() throws Exception {
+ boolean isSpecified =
+ BackupUtils.isFileSpecifiedInPathList(directory("a"), paths(directory("a")));
+
+ assertThat(isSpecified).isTrue();
+ }
+
+ @Test
+ public void testIsFileSpecifiedInPathList_whenDirectoryAndPathListEmpty() throws Exception {
+ boolean isSpecified = BackupUtils.isFileSpecifiedInPathList(directory("a"), paths());
+
+ assertThat(isSpecified).isFalse();
+ }
+
+ @Test
+ public void testIsFileSpecifiedInPathList_whenDirectoryAndPathListHasParent() throws Exception {
+ boolean isSpecified =
+ BackupUtils.isFileSpecifiedInPathList(directory("a/b"), paths(directory("a")));
+
+ assertThat(isSpecified).isFalse();
+ }
+
+ @Test
+ public void testIsFileSpecifiedInPathList_whenFileAndPathListDoesntContainDirectory()
+ throws Exception {
+ boolean isSpecified =
+ BackupUtils.isFileSpecifiedInPathList(file("a/b.txt"), paths(directory("c")));
+
+ assertThat(isSpecified).isFalse();
+ }
+
+ @Test
+ public void testIsFileSpecifiedInPathList_whenFileAndPathListHasDirectoryWhoseNameIsPrefix()
+ throws Exception {
+ boolean isSpecified =
+ BackupUtils.isFileSpecifiedInPathList(file("a/b.txt"), paths(directory("a/b")));
+
+ assertThat(isSpecified).isFalse();
+ }
+
+ @Test
+ public void testIsFileSpecifiedInPathList_whenFileAndPathListHasDirectoryWhoseNameIsPrefix2()
+ throws Exception {
+ boolean isSpecified =
+ BackupUtils.isFileSpecifiedInPathList(
+ file("name/subname.txt"), paths(directory("nam")));
+
+ assertThat(isSpecified).isFalse();
+ }
+
+ @Test
+ public void
+ testIsFileSpecifiedInPathList_whenFileAndPathListContainsFirstNotRelatedAndSecondContainingDirectory()
+ throws Exception {
+ boolean isSpecified =
+ BackupUtils.isFileSpecifiedInPathList(
+ file("a/b.txt"), paths(directory("b"), directory("a")));
+
+ assertThat(isSpecified).isTrue();
+ }
+
+ @Test
+ public void
+ testIsFileSpecifiedInPathList_whenDirectoryAndPathListContainsFirstNotRelatedAndSecondSameDirectory()
+ throws Exception {
+ boolean isSpecified =
+ BackupUtils.isFileSpecifiedInPathList(
+ directory("a/b"), paths(directory("b"), directory("a/b")));
+
+ assertThat(isSpecified).isTrue();
+ }
+
+ @Test
+ public void
+ testIsFileSpecifiedInPathList_whenFileAndPathListContainsFirstNotRelatedFileAndSecondSameFile()
+ throws Exception {
+ boolean isSpecified =
+ BackupUtils.isFileSpecifiedInPathList(
+ file("a/b.txt"), paths(directory("b"), file("a/b.txt")));
+
+ assertThat(isSpecified).isTrue();
+ }
+
+ private File file(String path) throws IOException {
+ File file = new File(mContext.getDataDir(), path);
+ File parent = file.getParentFile();
+ parent.mkdirs();
+ file.createNewFile();
+ if (!file.isFile()) {
+ throw new IOException("Couldn't create file");
+ }
+ return file;
+ }
+
+ private File directory(String path) throws IOException {
+ File directory = new File(mContext.getDataDir(), path);
+ directory.mkdirs();
+ if (!directory.isDirectory()) {
+ throw new IOException("Couldn't create directory");
+ }
+ return directory;
+ }
+
+ private Collection<PathWithRequiredFlags> paths(File... files) {
+ return Stream.of(files)
+ .map(file -> new PathWithRequiredFlags(file.getPath(), 0))
+ .collect(Collectors.toList());
+ }
+}
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/GroupHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/GroupHelperTest.java
index 8d4c5b1..84ef0c9 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/GroupHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/GroupHelperTest.java
@@ -50,13 +50,14 @@
public class GroupHelperTest extends UiServiceTestCase {
private @Mock GroupHelper.Callback mCallback;
+ private final static int AUTOGROUP_AT_COUNT = 4;
private GroupHelper mGroupHelper;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
- mGroupHelper = new GroupHelper(mCallback);
+ mGroupHelper = new GroupHelper(AUTOGROUP_AT_COUNT, mCallback);
}
private StatusBarNotification getSbn(String pkg, int id, String tag,
@@ -79,7 +80,7 @@
@Test
public void testNoGroup_postingUnderLimit() throws Exception {
final String pkg = "package";
- for (int i = 0; i < GroupHelper.AUTOGROUP_AT_COUNT - 1; i++) {
+ for (int i = 0; i < AUTOGROUP_AT_COUNT - 1; i++) {
mGroupHelper.onNotificationPosted(getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM),
false);
}
@@ -94,12 +95,12 @@
public void testNoGroup_multiPackage() throws Exception {
final String pkg = "package";
final String pkg2 = "package2";
- for (int i = 0; i < GroupHelper.AUTOGROUP_AT_COUNT - 1; i++) {
+ for (int i = 0; i < AUTOGROUP_AT_COUNT - 1; i++) {
mGroupHelper.onNotificationPosted(getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM),
false);
}
mGroupHelper.onNotificationPosted(
- getSbn(pkg2, GroupHelper.AUTOGROUP_AT_COUNT, "four", UserHandle.SYSTEM), false);
+ getSbn(pkg2, AUTOGROUP_AT_COUNT, "four", UserHandle.SYSTEM), false);
verify(mCallback, never()).addAutoGroupSummary(
eq(UserHandle.USER_SYSTEM), eq(pkg), anyString());
verify(mCallback, never()).addAutoGroup(anyString());
@@ -110,13 +111,12 @@
@Test
public void testNoGroup_multiUser() throws Exception {
final String pkg = "package";
- for (int i = 0; i < GroupHelper.AUTOGROUP_AT_COUNT - 1; i++) {
+ for (int i = 0; i < AUTOGROUP_AT_COUNT - 1; i++) {
mGroupHelper.onNotificationPosted(getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM),
false);
}
mGroupHelper.onNotificationPosted(
- getSbn(pkg, GroupHelper.AUTOGROUP_AT_COUNT, "four", UserHandle.ALL),
- false);
+ getSbn(pkg, AUTOGROUP_AT_COUNT, "four", UserHandle.ALL), false);
verify(mCallback, never()).addAutoGroupSummary(anyInt(), eq(pkg), anyString());
verify(mCallback, never()).addAutoGroup(anyString());
verify(mCallback, never()).removeAutoGroup(anyString());
@@ -126,13 +126,12 @@
@Test
public void testNoGroup_someAreGrouped() throws Exception {
final String pkg = "package";
- for (int i = 0; i < GroupHelper.AUTOGROUP_AT_COUNT - 1; i++) {
+ for (int i = 0; i < AUTOGROUP_AT_COUNT - 1; i++) {
mGroupHelper.onNotificationPosted(
getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM), false);
}
mGroupHelper.onNotificationPosted(
- getSbn(pkg, GroupHelper.AUTOGROUP_AT_COUNT, "four", UserHandle.SYSTEM, "a"),
- false);
+ getSbn(pkg, AUTOGROUP_AT_COUNT, "four", UserHandle.SYSTEM, "a"), false);
verify(mCallback, never()).addAutoGroupSummary(
eq(UserHandle.USER_SYSTEM), eq(pkg), anyString());
verify(mCallback, never()).addAutoGroup(anyString());
@@ -144,12 +143,12 @@
@Test
public void testPostingOverLimit() throws Exception {
final String pkg = "package";
- for (int i = 0; i < GroupHelper.AUTOGROUP_AT_COUNT; i++) {
+ for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
mGroupHelper.onNotificationPosted(
getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM), false);
}
verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString());
- verify(mCallback, times(GroupHelper.AUTOGROUP_AT_COUNT)).addAutoGroup(anyString());
+ verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString());
verify(mCallback, never()).removeAutoGroup(anyString());
verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
}
@@ -158,18 +157,18 @@
public void testDropToZeroRemoveGroup() throws Exception {
final String pkg = "package";
List<StatusBarNotification> posted = new ArrayList<>();
- for (int i = 0; i < GroupHelper.AUTOGROUP_AT_COUNT; i++) {
+ for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
final StatusBarNotification sbn = getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM);
posted.add(sbn);
mGroupHelper.onNotificationPosted(sbn, false);
}
verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString());
- verify(mCallback, times(GroupHelper.AUTOGROUP_AT_COUNT)).addAutoGroup(anyString());
+ verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString());
verify(mCallback, never()).removeAutoGroup(anyString());
verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
Mockito.reset(mCallback);
- for (int i = 0; i < GroupHelper.AUTOGROUP_AT_COUNT - 1; i++) {
+ for (int i = 0; i < AUTOGROUP_AT_COUNT - 1; i++) {
mGroupHelper.onNotificationRemoved(posted.remove(0));
}
verify(mCallback, never()).removeAutoGroup(anyString());
@@ -185,28 +184,28 @@
public void testAppStartsGrouping() throws Exception {
final String pkg = "package";
List<StatusBarNotification> posted = new ArrayList<>();
- for (int i = 0; i < GroupHelper.AUTOGROUP_AT_COUNT; i++) {
+ for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
final StatusBarNotification sbn = getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM);
posted.add(sbn);
mGroupHelper.onNotificationPosted(sbn, false);
}
verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString());
- verify(mCallback, times(GroupHelper.AUTOGROUP_AT_COUNT)).addAutoGroup(anyString());
+ verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString());
verify(mCallback, never()).removeAutoGroup(anyString());
verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
Mockito.reset(mCallback);
int i = 0;
- for (i = 0; i < GroupHelper.AUTOGROUP_AT_COUNT - 2; i++) {
+ for (i = 0; i < AUTOGROUP_AT_COUNT - 2; i++) {
final StatusBarNotification sbn =
getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM, "app group");
mGroupHelper.onNotificationPosted(sbn, false);
}
- verify(mCallback, times(GroupHelper.AUTOGROUP_AT_COUNT - 2)).removeAutoGroup(anyString());
+ verify(mCallback, times(AUTOGROUP_AT_COUNT - 2)).removeAutoGroup(anyString());
verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
Mockito.reset(mCallback);
- for (; i < GroupHelper.AUTOGROUP_AT_COUNT; i++) {
+ for (; i < AUTOGROUP_AT_COUNT; i++) {
final StatusBarNotification sbn =
getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM, "app group");
mGroupHelper.onNotificationPosted(sbn, false);
@@ -220,13 +219,13 @@
throws Exception {
final String pkg = "package";
List<StatusBarNotification> posted = new ArrayList<>();
- for (int i = 0; i < GroupHelper.AUTOGROUP_AT_COUNT; i++) {
+ for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
final StatusBarNotification sbn = getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM);
posted.add(sbn);
mGroupHelper.onNotificationPosted(sbn, false);
}
verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString());
- verify(mCallback, times(GroupHelper.AUTOGROUP_AT_COUNT)).addAutoGroup(anyString());
+ verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString());
verify(mCallback, never()).removeAutoGroup(anyString());
verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
Mockito.reset(mCallback);
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index f60332e..3913dbb 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -116,6 +116,14 @@
public static final String
KEY_SIM_NETWORK_UNLOCK_ALLOW_DISMISS_BOOL = "sim_network_unlock_allow_dismiss_bool";
+ /**
+ * Flag indicating whether or not sending emergency SMS messages over IMS
+ * is supported when in LTE/limited LTE (Emergency only) service mode..
+ *
+ */
+ public static final String
+ KEY_SUPPORT_EMERGENCY_SMS_OVER_IMS_BOOL = "support_emergency_sms_over_ims_bool";
+
/** Flag indicating if the phone is a world phone */
public static final String KEY_WORLD_PHONE_BOOL = "world_phone_bool";
@@ -2025,6 +2033,7 @@
sDefaults.putBoolean(KEY_SHOW_APN_SETTING_CDMA_BOOL, false);
sDefaults.putBoolean(KEY_SHOW_CDMA_CHOICES_BOOL, false);
sDefaults.putBoolean(KEY_SMS_REQUIRES_DESTINATION_NUMBER_CONVERSION_BOOL, false);
+ sDefaults.putBoolean(KEY_SUPPORT_EMERGENCY_SMS_OVER_IMS_BOOL, false);
sDefaults.putBoolean(KEY_SHOW_ONSCREEN_DIAL_BUTTON_BOOL, true);
sDefaults.putBoolean(KEY_SIM_NETWORK_UNLOCK_ALLOW_DISMISS_BOOL, true);
sDefaults.putBoolean(KEY_SUPPORT_PAUSE_IMS_VIDEO_CALLS_BOOL, false);