summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xcore/java/android/provider/Settings.java11
-rw-r--r--core/java/android/util/TimedRemoteCaller.java96
-rw-r--r--core/java/android/view/SoundEffectConstants.java2
-rw-r--r--core/java/android/view/TextureView.java9
-rw-r--r--core/java/android/view/View.java6
-rw-r--r--core/java/android/view/ViewRootImpl.java4
-rw-r--r--core/java/android/view/WindowManagerPolicy.java1
-rw-r--r--core/java/com/android/internal/app/AssistUtils.java40
-rw-r--r--core/java/com/android/internal/os/BatteryStatsImpl.java18
-rw-r--r--core/res/res/drawable/ic_lock_power_off.xml36
-rw-r--r--core/res/res/drawable/ic_restart.xml28
-rw-r--r--core/res/res/values/config.xml6
-rw-r--r--core/res/res/values/strings.xml4
-rw-r--r--core/res/res/values/symbols.xml5
-rw-r--r--core/tests/coretests/src/com/android/internal/os/BatteryStatsSamplingTimerTest.java39
-rw-r--r--libs/common_time/common_time_server.cpp7
-rw-r--r--packages/Keyguard/src/com/android/keyguard/KeyguardPasswordView.java72
-rw-r--r--packages/SettingsLib/res/values/strings.xml3
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/drawer/SettingsDrawerActivity.java1
-rw-r--r--packages/Shell/tests/Android.mk4
-rw-r--r--packages/Shell/tests/AndroidManifest.xml2
-rw-r--r--packages/Shell/tests/src/com/android/shell/BugreportReceiverTest.java63
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QSContainer.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QSPanel.java10
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenWallpaper.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java3
-rw-r--r--services/core/java/com/android/server/pm/SELinuxMMAC.java8
-rw-r--r--services/core/java/com/android/server/policy/GlobalActions.java35
-rw-r--r--services/core/java/com/android/server/wallpaper/WallpaperManagerService.java4
-rw-r--r--services/core/java/com/android/server/wm/WindowAnimator.java17
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerService.java6
-rw-r--r--services/core/java/com/android/server/wm/WindowStateAnimator.java30
-rw-r--r--services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java98
-rw-r--r--services/usb/java/com/android/server/usb/UsbDeviceManager.java1
-rw-r--r--services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java3
-rw-r--r--telephony/java/android/telephony/DisconnectCause.java22
-rw-r--r--telephony/java/com/android/ims/ImsReasonInfo.java10
-rw-r--r--tools/aapt2/link/TableMerger.cpp2
-rw-r--r--tools/aapt2/link/TableMerger_test.cpp57
39 files changed, 579 insertions, 195 deletions
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 0b082def0c8a..bff4d7dad888 100755
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -6026,6 +6026,17 @@ public final class Settings {
public static final String ASSIST_SCREENSHOT_ENABLED = "assist_screenshot_enabled";
/**
+ * Specifies whether the screen will show an animation if screen contents are sent to the
+ * assist application (active voice interaction service).
+ *
+ * Note that the disclosure will be forced for third-party assistants or if the device
+ * does not support disabling it.
+ *
+ * @hide
+ */
+ public static final String ASSIST_DISCLOSURE_ENABLED = "assist_disclosure_enabled";
+
+ /**
* Names of the service components that the current user has explicitly allowed to
* see all of the user's notifications, separated by ':'.
*
diff --git a/core/java/android/util/TimedRemoteCaller.java b/core/java/android/util/TimedRemoteCaller.java
index abb2b6401d71..100c16e7f990 100644
--- a/core/java/android/util/TimedRemoteCaller.java
+++ b/core/java/android/util/TimedRemoteCaller.java
@@ -17,6 +17,7 @@
package android.util;
import android.os.SystemClock;
+import com.android.internal.annotations.GuardedBy;
import java.util.concurrent.TimeoutException;
@@ -29,8 +30,7 @@ import java.util.concurrent.TimeoutException;
* the sequence number. If the response comes within the timeout
* and its sequence number is the one sent in the method invocation,
* then the call succeeded. If the response does not come within
- * the timeout then the call failed. Older result received when
- * waiting for the result are ignored.
+ * the timeout then the call failed.
* <p>
* Typical usage is:
* </p>
@@ -66,66 +66,90 @@ public abstract class TimedRemoteCaller<T> {
public static final long DEFAULT_CALL_TIMEOUT_MILLIS = 5000;
- private static final int UNDEFINED_SEQUENCE = -1;
-
private final Object mLock = new Object();
private final long mCallTimeoutMillis;
- private int mSequenceCounter;
-
- private int mReceivedSequence = UNDEFINED_SEQUENCE;
+ /** The callbacks we are waiting for, key == sequence id, value == 1 */
+ @GuardedBy("mLock")
+ private final SparseIntArray mAwaitedCalls = new SparseIntArray(1);
- private int mAwaitedSequence = UNDEFINED_SEQUENCE;
+ /** The callbacks we received but for which the result has not yet been reported */
+ @GuardedBy("mLock")
+ private final SparseArray<T> mReceivedCalls = new SparseArray<>(1);
- private T mResult;
+ @GuardedBy("mLock")
+ private int mSequenceCounter;
+ /**
+ * Create a new timed caller.
+ *
+ * @param callTimeoutMillis The time to wait in {@link #getResultTimed} before a timed call will
+ * be declared timed out
+ */
public TimedRemoteCaller(long callTimeoutMillis) {
mCallTimeoutMillis = callTimeoutMillis;
}
- public final int onBeforeRemoteCall() {
+ /**
+ * Indicate that a timed call will be made.
+ *
+ * @return The sequence id for the call
+ */
+ protected final int onBeforeRemoteCall() {
synchronized (mLock) {
- mAwaitedSequence = mSequenceCounter++;
- return mAwaitedSequence;
- }
- }
+ int sequenceId;
+ do {
+ sequenceId = mSequenceCounter++;
+ } while (mAwaitedCalls.get(sequenceId) != 0);
- public final T getResultTimed(int sequence) throws TimeoutException {
- synchronized (mLock) {
- final boolean success = waitForResultTimedLocked(sequence);
- if (!success) {
- throw new TimeoutException("No reponse for sequence: " + sequence);
- }
- T result = mResult;
- mResult = null;
- return result;
+ mAwaitedCalls.put(sequenceId, 1);
+
+ return sequenceId;
}
}
- public final void onRemoteMethodResult(T result, int sequence) {
+ /**
+ * Indicate that the timed call has returned.
+ *
+ * @param result The result of the timed call
+ * @param sequence The sequence id of the call (from {@link #onBeforeRemoteCall()})
+ */
+ protected final void onRemoteMethodResult(T result, int sequence) {
synchronized (mLock) {
- if (sequence == mAwaitedSequence) {
- mReceivedSequence = sequence;
- mResult = result;
+ // Do nothing if we do not await the call anymore as it must have timed out
+ boolean containedSequenceId = mAwaitedCalls.get(sequence) != 0;
+ if (containedSequenceId) {
+ mAwaitedCalls.delete(sequence);
+ mReceivedCalls.put(sequence, result);
mLock.notifyAll();
}
}
}
- private boolean waitForResultTimedLocked(int sequence) {
+ /**
+ * Wait until the timed call has returned.
+ *
+ * @param sequence The sequence id of the call (from {@link #onBeforeRemoteCall()})
+ *
+ * @return The result of the timed call (set in {@link #onRemoteMethodResult(Object, int)})
+ */
+ protected final T getResultTimed(int sequence) throws TimeoutException {
final long startMillis = SystemClock.uptimeMillis();
while (true) {
try {
- if (mReceivedSequence == sequence) {
- return true;
- }
- final long elapsedMillis = SystemClock.uptimeMillis() - startMillis;
- final long waitMillis = mCallTimeoutMillis - elapsedMillis;
- if (waitMillis <= 0) {
- return false;
+ synchronized (mLock) {
+ if (mReceivedCalls.indexOfKey(sequence) >= 0) {
+ return mReceivedCalls.removeReturnOld(sequence);
+ }
+ final long elapsedMillis = SystemClock.uptimeMillis() - startMillis;
+ final long waitMillis = mCallTimeoutMillis - elapsedMillis;
+ if (waitMillis <= 0) {
+ mAwaitedCalls.delete(sequence);
+ throw new TimeoutException("No response for sequence: " + sequence);
+ }
+ mLock.wait(waitMillis);
}
- mLock.wait(waitMillis);
} catch (InterruptedException ie) {
/* ignore */
}
diff --git a/core/java/android/view/SoundEffectConstants.java b/core/java/android/view/SoundEffectConstants.java
index 4a77af47170d..8d891bbc2cfc 100644
--- a/core/java/android/view/SoundEffectConstants.java
+++ b/core/java/android/view/SoundEffectConstants.java
@@ -37,6 +37,8 @@ public class SoundEffectConstants {
* or {@link View#FOCUS_BACKWARD}
* @return The appropriate sonification constant.
+ * @throws {@link IllegalArgumentException} when the passed direction is not one of the
+ * documented values.
*/
public static int getContantForFocusDirection(int direction) {
switch (direction) {
diff --git a/core/java/android/view/TextureView.java b/core/java/android/view/TextureView.java
index 745da51a1dc1..bb771000b343 100644
--- a/core/java/android/view/TextureView.java
+++ b/core/java/android/view/TextureView.java
@@ -229,7 +229,6 @@ public class TextureView extends View {
@Override
protected void destroyHardwareResources() {
destroyHardwareLayer();
- mUpdateSurface = mSurface != null;
}
private void destroyHardwareLayer() {
@@ -376,17 +375,17 @@ public class TextureView extends View {
}
mLayer = mAttachInfo.mThreadedRenderer.createTextureLayer();
- if (!mUpdateSurface) {
+ boolean createNewSurface = (mSurface == null);
+ if (createNewSurface) {
// Create a new SurfaceTexture for the layer.
mSurface = new SurfaceTexture(false);
mLayer.setSurfaceTexture(mSurface);
nCreateNativeWindow(mSurface);
}
mSurface.setDefaultBufferSize(getWidth(), getHeight());
-
mSurface.setOnFrameAvailableListener(mUpdateListener, mAttachInfo.mHandler);
- if (mListener != null && !mUpdateSurface) {
+ if (mListener != null && createNewSurface) {
mListener.onSurfaceTextureAvailable(mSurface, getWidth(), getHeight());
}
mLayer.setLayerPaint(mLayerPaint);
@@ -745,9 +744,11 @@ public class TextureView extends View {
"released SurfaceTexture");
}
if (mSurface != null) {
+ nDestroyNativeWindow();
mSurface.release();
}
mSurface = surfaceTexture;
+ nCreateNativeWindow(mSurface);
/*
* If the view is visible and we already made a layer, update the
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index c37cf569a893..5a7f0ff08782 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -20656,7 +20656,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
* <li>{@link #DRAG_FLAG_GLOBAL}</li>
* <li>{@link #DRAG_FLAG_GLOBAL_PERSISTABLE_URI_PERMISSION}</li>
* <li>{@link #DRAG_FLAG_GLOBAL_PREFIX_URI_PERMISSION}</li>
- * <li>{@link #DRAG_FLAG_GLOBAL_PREFIX_URI_PERMISSION}</li>
* <li>{@link #DRAG_FLAG_GLOBAL_URI_READ}</li>
* <li>{@link #DRAG_FLAG_GLOBAL_URI_WRITE}</li>
* <li>{@link #DRAG_FLAG_OPAQUE}</li>
@@ -20674,6 +20673,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
Log.w(VIEW_LOG_TAG, "startDragAndDrop called on a detached view.");
return false;
}
+
+ data.prepareToLeaveProcess((flags & View.DRAG_FLAG_GLOBAL) != 0);
+
boolean okay = false;
Point shadowSize = new Point();
@@ -23864,7 +23866,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
* on the screen.
*/
private boolean shouldDrawRoundScrollbar() {
- if (!mResources.getConfiguration().isScreenRound()) {
+ if (!mResources.getConfiguration().isScreenRound() || mAttachInfo == null) {
return false;
}
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 2bc1d74ffb79..757727b6f1f8 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -5539,6 +5539,10 @@ public final class ViewRootImpl implements ViewParent,
// Remember who the current drag target is pre-dispatch
final View prevDragView = mCurrentDragView;
+ if (what == DragEvent.ACTION_DROP) {
+ event.getClipData().prepareToEnterProcess();
+ }
+
// Now dispatch the drag/drop event
boolean result = mView.dispatchDragEvent(event);
diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java
index f1fa21694976..0b9f9d09b483 100644
--- a/core/java/android/view/WindowManagerPolicy.java
+++ b/core/java/android/view/WindowManagerPolicy.java
@@ -484,6 +484,7 @@ public interface WindowManagerPolicy {
public void switchInputMethod(boolean forwardDirection);
public void shutdown(boolean confirm);
+ public void reboot(boolean confirm);
public void rebootSafeMode(boolean confirm);
/**
diff --git a/core/java/com/android/internal/app/AssistUtils.java b/core/java/com/android/internal/app/AssistUtils.java
index 56c5cc9b69ec..294007946c77 100644
--- a/core/java/com/android/internal/app/AssistUtils.java
+++ b/core/java/com/android/internal/app/AssistUtils.java
@@ -16,10 +16,13 @@
package com.android.internal.app;
+import com.android.internal.R;
+
import android.app.SearchManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
+import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.os.Bundle;
@@ -166,4 +169,41 @@ public class AssistUtils {
return null;
}
+ public static boolean isPreinstalledAssistant(Context context, ComponentName assistant) {
+ if (assistant == null) {
+ return false;
+ }
+ ApplicationInfo applicationInfo;
+ try {
+ applicationInfo = context.getPackageManager().getApplicationInfo(
+ assistant.getPackageName(), 0);
+ } catch (PackageManager.NameNotFoundException e) {
+ return false;
+ }
+ return applicationInfo.isSystemApp() || applicationInfo.isUpdatedSystemApp();
+ }
+
+ private static boolean isDisclosureEnabled(Context context) {
+ return Settings.Secure.getInt(context.getContentResolver(),
+ Settings.Secure.ASSIST_DISCLOSURE_ENABLED, 0) != 0;
+ }
+
+ /**
+ * @return if the disclosure animation should trigger for the given assistant.
+ *
+ * Third-party assistants will always need to disclose, while the user can configure this for
+ * pre-installed assistants.
+ */
+ public static boolean shouldDisclose(Context context, ComponentName assistant) {
+ if (!allowDisablingAssistDisclosure(context)) {
+ return true;
+ }
+
+ return isDisclosureEnabled(context) || !isPreinstalledAssistant(context, assistant);
+ }
+
+ public static boolean allowDisablingAssistDisclosure(Context context) {
+ return context.getResources().getBoolean(
+ com.android.internal.R.bool.config_allowDisablingAssistDisclosure);
+ }
}
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index fef4a5381485..0aa3a7e9c8a4 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -111,7 +111,7 @@ public class BatteryStatsImpl extends BatteryStats {
private static final int MAGIC = 0xBA757475; // 'BATSTATS'
// Current on-disk Parcel version
- private static final int VERSION = 149 + (USE_OLD_HISTORY ? 1000 : 0);
+ private static final int VERSION = 150 + (USE_OLD_HISTORY ? 1000 : 0);
// Maximum number of items we will record in the history.
private static final int MAX_HISTORY_ITEMS = 2000;
@@ -1425,22 +1425,6 @@ public class BatteryStatsImpl extends BatteryStats {
mUnpluggedReportedCount = 0;
return true;
}
-
- @Override
- public void writeSummaryFromParcelLocked(Parcel out, long batteryRealtime) {
- super.writeSummaryFromParcelLocked(out, batteryRealtime);
- out.writeLong(mCurrentReportedTotalTime);
- out.writeInt(mCurrentReportedCount);
- out.writeInt(mTrackingReportedValues ? 1 : 0);
- }
-
- @Override
- public void readSummaryFromParcelLocked(Parcel in) {
- super.readSummaryFromParcelLocked(in);
- mUnpluggedReportedTotalTime = mCurrentReportedTotalTime = in.readLong();
- mUnpluggedReportedCount = mCurrentReportedCount = in.readInt();
- mTrackingReportedValues = in.readInt() == 1;
- }
}
/**
diff --git a/core/res/res/drawable/ic_lock_power_off.xml b/core/res/res/drawable/ic_lock_power_off.xml
index 718f17ed0c19..babd1be220cb 100644
--- a/core/res/res/drawable/ic_lock_power_off.xml
+++ b/core/res/res/drawable/ic_lock_power_off.xml
@@ -1,19 +1,25 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2014 The Android Open Source Project
+<!--
+ Copyright (C) 2016 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
+ 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
+ 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.
+ 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.
-->
-
-<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
- android:src="@drawable/ic_lock_power_off_alpha"
- android:tint="?attr/colorControlNormal" />
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24.0dp"
+ android:height="24.0dp"
+ android:viewportHeight="24.0"
+ android:viewportWidth="24.0"
+ android:tint="?attr/colorControlNormal">
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M13.0,3.0l-2.0,0.0l0.0,10.0l2.0,0.0L13.0,3.0zm4.83,2.17l-1.42,1.42C17.99,7.86 19.0,9.81 19.0,12.0c0.0,3.87 -3.13,7.0 -7.0,7.0s-7.0,-3.13 -7.0,-7.0c0.0,-2.19 1.01,-4.14 2.58,-5.42L6.17,5.17C4.23,6.82 3.0,9.26 3.0,12.0c0.0,4.97 4.03,9.0 9.0,9.0s9.0,-4.03 9.0,-9.0c0.0,-2.74 -1.23,-5.18 -3.17,-6.83z"/>
+</vector>
diff --git a/core/res/res/drawable/ic_restart.xml b/core/res/res/drawable/ic_restart.xml
new file mode 100644
index 000000000000..47ac483fa311
--- /dev/null
+++ b/core/res/res/drawable/ic_restart.xml
@@ -0,0 +1,28 @@
+<!--
+ Copyright (C) 2016 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24.0dp"
+ android:height="24.0dp"
+ android:viewportHeight="24.0"
+ android:viewportWidth="24.0"
+ android:tint="?attr/colorControlNormal">
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M12.0,4.0L12.0,1.0L8.0,5.0l4.0,4.0L12.0,6.0c3.9,0.0 7.0,3.1 7.0,7.0c0.0,3.9 -3.1,7.0 -7.0,7.0l0.0,2.0c5.0,0.0 9.0,-4.0 9.0,-9.0C21.0,8.0 17.0,4.0 12.0,4.0z"/>
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M5.0,12.9C5.0,11.0 5.8,9.2 7.2,7.9L5.8,6.4C4.0,8.1 3.0,10.5 3.0,12.9c0.0,4.0 2.7,7.6 6.5,8.7l0.5,-1.9C7.1,18.8 5.0,16.1 5.0,12.9z"/>
+</vector>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 5b68ee139e93..6161494353f2 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -2091,9 +2091,11 @@
"bugreport" = Take bug report, if available
"silent" = silent mode
"users" = list of users
+ "restart" = restart device
-->
<string-array translatable="false" name="config_globalActionsList">
<item>power</item>
+ <item>restart</item>
<item>bugreport</item>
<item>users</item>
</string-array>
@@ -2520,6 +2522,10 @@
<!-- Flag indicating whether round icons should be parsed from the application manifest. -->
<bool name="config_useRoundIcon">false</bool>
+ <!-- Flag indicating whether the assist disclosure can be disabled using
+ ASSIST_DISCLOSURE_ENABLED. -->
+ <bool name="config_allowDisablingAssistDisclosure">false</bool>
+
<!-- True if the device supports system navigation keys. -->
<bool name="config_supportSystemNavigationKeys">false</bool>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 5a9099b8bf6a..c4594e5bdfe7 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -484,6 +484,10 @@
<!-- label for item that turns off power in phone options dialog -->
<string name="global_action_power_off">Power off</string>
+ <!-- label for item that restarts phone in phone options dialog -->
+ <!-- TODO: promote to separate string-->
+ <string name="global_action_restart" translatable="false">@string/sim_restart_button</string>
+
<!-- label for item that generates a bug report in the phone options dialog -->
<string name="global_action_bug_report">Bug report</string>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 3486b1b9524f..3c2b55b033b9 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -1593,6 +1593,7 @@
<java-symbol type="string" name="bugreport_title" />
<java-symbol type="string" name="faceunlock_multiple_failures" />
<java-symbol type="string" name="global_action_power_off" />
+ <java-symbol type="string" name="global_action_restart" />
<java-symbol type="string" name="global_actions_airplane_mode_off_status" />
<java-symbol type="string" name="global_actions_airplane_mode_on_status" />
<java-symbol type="string" name="global_actions_toggle_airplane_mode" />
@@ -2683,6 +2684,7 @@
<java-symbol type="drawable" name="ic_doc_generic" />
<java-symbol type="bool" name="config_nightDisplayAvailable" />
+ <java-symbol type="bool" name="config_allowDisablingAssistDisclosure" />
<java-symbol type="integer" name="config_defaultNightDisplayAutoMode" />
<java-symbol type="integer" name="config_defaultNightDisplayCustomStartTime" />
<java-symbol type="integer" name="config_defaultNightDisplayCustomEndTime" />
@@ -2692,4 +2694,7 @@
<java-symbol type="bool" name="config_permissionReviewRequired" />
+
+ <java-symbol type="drawable" name="ic_restart" />
+
</resources>
diff --git a/core/tests/coretests/src/com/android/internal/os/BatteryStatsSamplingTimerTest.java b/core/tests/coretests/src/com/android/internal/os/BatteryStatsSamplingTimerTest.java
index ce6879d0ef4e..b4afddab97c9 100644
--- a/core/tests/coretests/src/com/android/internal/os/BatteryStatsSamplingTimerTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/BatteryStatsSamplingTimerTest.java
@@ -178,19 +178,40 @@ public class BatteryStatsSamplingTimerTest extends TestCase {
clocks.elapsedRealtime() * 1000);
offBatterySummaryParcel.setDataPosition(0);
+ // Set the timebase running again. That way any issues with tracking reported values
+ // get tested when we unparcel the timers below.
+ timeBase.setRunning(true, clocks.uptimeMillis(), clocks.elapsedRealtime());
+
// Read the on battery summary from the parcel.
- BatteryStatsImpl.SamplingTimer unparceledTimer = new BatteryStatsImpl.SamplingTimer(
- clocks, timeBase);
- unparceledTimer.readSummaryFromParcelLocked(onBatterySummaryParcel);
+ BatteryStatsImpl.SamplingTimer unparceledOnBatteryTimer =
+ new BatteryStatsImpl.SamplingTimer(clocks, timeBase);
+ unparceledOnBatteryTimer.readSummaryFromParcelLocked(onBatterySummaryParcel);
- assertEquals(10, unparceledTimer.getTotalTimeLocked(0, BatteryStats.STATS_SINCE_CHARGED));
- assertEquals(1, unparceledTimer.getCountLocked(BatteryStats.STATS_SINCE_CHARGED));
+ assertEquals(10, unparceledOnBatteryTimer.getTotalTimeLocked(0,
+ BatteryStats.STATS_SINCE_CHARGED));
+ assertEquals(1, unparceledOnBatteryTimer.getCountLocked(BatteryStats.STATS_SINCE_CHARGED));
// Read the off battery summary from the parcel.
- unparceledTimer = new BatteryStatsImpl.SamplingTimer(clocks, timeBase);
- unparceledTimer.readSummaryFromParcelLocked(offBatterySummaryParcel);
+ BatteryStatsImpl.SamplingTimer unparceledOffBatteryTimer =
+ new BatteryStatsImpl.SamplingTimer(clocks, timeBase);
+ unparceledOffBatteryTimer.readSummaryFromParcelLocked(offBatterySummaryParcel);
+
+ assertEquals(10, unparceledOffBatteryTimer.getTotalTimeLocked(0,
+ BatteryStats.STATS_SINCE_CHARGED));
+ assertEquals(1, unparceledOffBatteryTimer.getCountLocked(BatteryStats.STATS_SINCE_CHARGED));
- assertEquals(10, unparceledTimer.getTotalTimeLocked(0, BatteryStats.STATS_SINCE_CHARGED));
- assertEquals(1, unparceledTimer.getCountLocked(BatteryStats.STATS_SINCE_CHARGED));
+ // Now, just like with a fresh timer, the first update should be absorbed to account for
+ // data being collected when we weren't recording.
+ unparceledOnBatteryTimer.update(10, 10);
+
+ assertEquals(10, unparceledOnBatteryTimer.getTotalTimeLocked(0,
+ BatteryStats.STATS_SINCE_CHARGED));
+ assertEquals(1, unparceledOnBatteryTimer.getCountLocked(BatteryStats.STATS_SINCE_CHARGED));
+
+ unparceledOffBatteryTimer.update(10, 10);
+
+ assertEquals(10, unparceledOffBatteryTimer.getTotalTimeLocked(0,
+ BatteryStats.STATS_SINCE_CHARGED));
+ assertEquals(1, unparceledOffBatteryTimer.getCountLocked(BatteryStats.STATS_SINCE_CHARGED));
}
}
diff --git a/libs/common_time/common_time_server.cpp b/libs/common_time/common_time_server.cpp
index f72ffaa63712..b1495effbc81 100644
--- a/libs/common_time/common_time_server.cpp
+++ b/libs/common_time/common_time_server.cpp
@@ -615,12 +615,11 @@ bool CommonTimeServer::handlePacket() {
ssize_t recvBytes = recvfrom(
mSocket, buf, sizeof(buf), 0,
- reinterpret_cast<const sockaddr *>(&srcAddr), &srcAddrLen);
+ reinterpret_cast<sockaddr *>(&srcAddr), &srcAddrLen);
if (recvBytes < 0) {
- mBadPktLog.log(ANDROID_LOG_ERROR, LOG_TAG,
- "recvfrom failed (res %d, errno %d)",
- recvBytes, errno);
+ mBadPktLog.log(ANDROID_LOG_ERROR, LOG_TAG, "recvfrom failed (%s)",
+ strerror(errno));
return false;
}
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardPasswordView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardPasswordView.java
index b75f52987a92..ddccc14a60f0 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardPasswordView.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardPasswordView.java
@@ -42,16 +42,21 @@ import java.util.List;
* Displays an alphanumeric (latin-1) key entry for the user to enter
* an unlock password
*/
-
public class KeyguardPasswordView extends KeyguardAbsKeyInputView
implements KeyguardSecurityView, OnEditorActionListener, TextWatcher {
private final boolean mShowImeAtScreenOn;
private final int mDisappearYTranslation;
+ // A delay constant to be used in a workaround for the situation where InputMethodManagerService
+ // is not switched to the new user yet.
+ // TODO: Remove this by ensuring such a race condition never happens.
+ private static final int DELAY_MILLIS_TO_REEVALUATE_IME_SWITCH_ICON = 500; // 500ms
+
InputMethodManager mImm;
private TextView mPasswordEntry;
private TextViewInputDisabler mPasswordEntryDisabler;
+ private View mSwitchImeButton;
private Interpolator mLinearOutSlowInInterpolator;
private Interpolator mFastOutLinearInInterpolator;
@@ -141,12 +146,31 @@ public class KeyguardPasswordView extends KeyguardAbsKeyInputView
mPasswordEntry.requestFocus();
}
+ private void updateSwitchImeButton() {
+ // If there's more than one IME, enable the IME switcher button
+ final boolean wasVisible = mSwitchImeButton.getVisibility() == View.VISIBLE;
+ final boolean shouldBeVisible = hasMultipleEnabledIMEsOrSubtypes(mImm, false);
+ if (wasVisible != shouldBeVisible) {
+ mSwitchImeButton.setVisibility(shouldBeVisible ? View.VISIBLE : View.GONE);
+ }
+
+ // TODO: Check if we still need this hack.
+ // If no icon is visible, reset the start margin on the password field so the text is
+ // still centered.
+ if (mSwitchImeButton.getVisibility() != View.VISIBLE) {
+ android.view.ViewGroup.LayoutParams params = mPasswordEntry.getLayoutParams();
+ if (params instanceof MarginLayoutParams) {
+ final MarginLayoutParams mlp = (MarginLayoutParams) params;
+ mlp.setMarginStart(0);
+ mPasswordEntry.setLayoutParams(params);
+ }
+ }
+ }
+
@Override
protected void onFinishInflate() {
super.onFinishInflate();
- boolean imeOrDeleteButtonVisible = false;
-
mImm = (InputMethodManager) getContext().getSystemService(
Context.INPUT_METHOD_SERVICE);
@@ -171,31 +195,29 @@ public class KeyguardPasswordView extends KeyguardAbsKeyInputView
mPasswordEntry.requestFocus();
+ mSwitchImeButton = findViewById(R.id.switch_ime_button);
+ mSwitchImeButton.setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ mCallback.userActivity(); // Leave the screen on a bit longer
+ // Do not show auxiliary subtypes in password lock screen.
+ mImm.showInputMethodPicker(false /* showAuxiliarySubtypes */);
+ }
+ });
+
// If there's more than one IME, enable the IME switcher button
- View switchImeButton = findViewById(R.id.switch_ime_button);
- if (switchImeButton != null && hasMultipleEnabledIMEsOrSubtypes(mImm, false)) {
- switchImeButton.setVisibility(View.VISIBLE);
- imeOrDeleteButtonVisible = true;
- switchImeButton.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- mCallback.userActivity(); // Leave the screen on a bit longer
- // Do not show auxiliary subtypes in password lock screen.
- mImm.showInputMethodPicker(false /* showAuxiliarySubtypes */);
- }
- });
- }
+ updateSwitchImeButton();
- // If no icon is visible, reset the start margin on the password field so the text is
- // still centered.
- if (!imeOrDeleteButtonVisible) {
- android.view.ViewGroup.LayoutParams params = mPasswordEntry.getLayoutParams();
- if (params instanceof MarginLayoutParams) {
- final MarginLayoutParams mlp = (MarginLayoutParams) params;
- mlp.setMarginStart(0);
- mPasswordEntry.setLayoutParams(params);
+ // When we the current user is switching, InputMethodManagerService sometimes has not
+ // switched internal state yet here. As a quick workaround, we check the keyboard state
+ // again.
+ // TODO: Remove this workaround by ensuring such a race condition never happens.
+ postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ updateSwitchImeButton();
}
- }
+ }, DELAY_MILLIS_TO_REEVALUATE_IME_SWITCH_ICON);
}
@Override
diff --git a/packages/SettingsLib/res/values/strings.xml b/packages/SettingsLib/res/values/strings.xml
index 3838143cc193..3bdb6fbdb3cb 100644
--- a/packages/SettingsLib/res/values/strings.xml
+++ b/packages/SettingsLib/res/values/strings.xml
@@ -863,4 +863,7 @@
<!-- Label for Help and feedback menu item -->
<string name="help_feedback_label">Help &amp; feedback</string>
+ <!-- Content description for drawer menu button [CHAR_LIMIT=30]-->
+ <string name="content_description_menu_button">Menu</string>
+
</resources>
diff --git a/packages/SettingsLib/src/com/android/settingslib/drawer/SettingsDrawerActivity.java b/packages/SettingsLib/src/com/android/settingslib/drawer/SettingsDrawerActivity.java
index 6658c14bd1cd..a50b366c26ac 100644
--- a/packages/SettingsLib/src/com/android/settingslib/drawer/SettingsDrawerActivity.java
+++ b/packages/SettingsLib/src/com/android/settingslib/drawer/SettingsDrawerActivity.java
@@ -226,6 +226,7 @@ public class SettingsDrawerActivity extends Activity {
public void showMenuIcon() {
mShowingMenu = true;
getActionBar().setHomeAsUpIndicator(R.drawable.ic_menu);
+ getActionBar().setHomeActionContentDescription(R.string.content_description_menu_button);
getActionBar().setDisplayHomeAsUpEnabled(true);
}
diff --git a/packages/Shell/tests/Android.mk b/packages/Shell/tests/Android.mk
index 1e0eaace35da..872eb7ac7dcf 100644
--- a/packages/Shell/tests/Android.mk
+++ b/packages/Shell/tests/Android.mk
@@ -8,7 +8,9 @@ LOCAL_SRC_FILES := $(call all-java-files-under, src)
LOCAL_JAVA_LIBRARIES := android.test.runner
-LOCAL_STATIC_JAVA_LIBRARIES := ub-uiautomator
+LOCAL_STATIC_JAVA_LIBRARIES := \
+ android-support-test \
+ ub-uiautomator \
LOCAL_PACKAGE_NAME := ShellTests
LOCAL_INSTRUMENTATION_FOR := Shell
diff --git a/packages/Shell/tests/AndroidManifest.xml b/packages/Shell/tests/AndroidManifest.xml
index 54b0802e1504..6d564c640fcd 100644
--- a/packages/Shell/tests/AndroidManifest.xml
+++ b/packages/Shell/tests/AndroidManifest.xml
@@ -36,7 +36,7 @@
</activity>
</application>
- <instrumentation android:name="android.test.InstrumentationTestRunner"
+ <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
android:targetPackage="com.android.shell"
android:label="Tests for Shell" />
diff --git a/packages/Shell/tests/src/com/android/shell/BugreportReceiverTest.java b/packages/Shell/tests/src/com/android/shell/BugreportReceiverTest.java
index 902c71d64ae9..dde71ebe5530 100644
--- a/packages/Shell/tests/src/com/android/shell/BugreportReceiverTest.java
+++ b/packages/Shell/tests/src/com/android/shell/BugreportReceiverTest.java
@@ -36,6 +36,13 @@ import static com.android.shell.BugreportProgressService.INTENT_BUGREPORT_STARTE
import static com.android.shell.BugreportProgressService.POLLING_FREQUENCY;
import static com.android.shell.BugreportProgressService.SCREENSHOT_DELAY_SECONDS;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
import java.io.BufferedOutputStream;
import java.io.BufferedWriter;
import java.io.ByteArrayOutputStream;
@@ -56,6 +63,13 @@ import java.util.zip.ZipOutputStream;
import libcore.io.Streams;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TestName;
+import org.junit.runner.RunWith;
+
import android.app.ActivityManager;
import android.app.ActivityManager.RunningServiceInfo;
import android.app.Instrumentation;
@@ -68,11 +82,12 @@ import android.os.Bundle;
import android.os.SystemClock;
import android.os.SystemProperties;
import android.service.notification.StatusBarNotification;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.LargeTest;
+import android.support.test.runner.AndroidJUnit4;
import android.support.test.uiautomator.UiDevice;
import android.support.test.uiautomator.UiObject;
import android.support.test.uiautomator.UiObjectNotFoundException;
-import android.test.InstrumentationTestCase;
-import android.test.suitebuilder.annotation.LargeTest;
import android.text.TextUtils;
import android.text.format.DateUtils;
import android.util.Log;
@@ -96,7 +111,8 @@ import com.android.shell.ActionSendMultipleConsumerActivity.CustomActionSendMult
* <strong>NOTE</strong>: these tests only work if the device is unlocked.
*/
@LargeTest
-public class BugreportReceiverTest extends InstrumentationTestCase {
+@RunWith(AndroidJUnit4.class)
+public class BugreportReceiverTest {
private static final String TAG = "BugreportReceiverTest";
// Timeout for UI operations, in milliseconds.
@@ -149,9 +165,10 @@ public class BugreportReceiverTest extends InstrumentationTestCase {
private UiBot mUiBot;
private CustomActionSendMultipleListener mListener;
- @Override
- protected void setUp() throws Exception {
- super.setUp();
+ @Rule public TestName mName = new TestName();
+
+ @Before
+ public void setUp() throws Exception {
Log.i(TAG, getName() + ".setup()");
Instrumentation instrumentation = getInstrumentation();
mContext = instrumentation.getTargetContext();
@@ -181,13 +198,13 @@ public class BugreportReceiverTest extends InstrumentationTestCase {
mUiBot.turnScreenOn();
}
- @Override
- protected void tearDown() throws Exception {
+ @After
+ public void tearDown() throws Exception {
Log.i(TAG, getName() + ".tearDown()");
cancelExistingNotifications();
- super.tearDown();
}
+ @Test
public void testProgress() throws Exception {
resetProperties();
sendBugreportStarted(1000);
@@ -233,6 +250,7 @@ public class BugreportReceiverTest extends InstrumentationTestCase {
assertServiceNotRunning();
}
+ @Test
public void testProgress_cancel() throws Exception {
resetProperties();
sendBugreportStarted(1000);
@@ -249,6 +267,7 @@ public class BugreportReceiverTest extends InstrumentationTestCase {
waitForService(false);
}
+ @Test
public void testProgress_takeExtraScreenshot() throws Exception {
resetProperties();
sendBugreportStarted(1000);
@@ -267,6 +286,7 @@ public class BugreportReceiverTest extends InstrumentationTestCase {
assertServiceNotRunning();
}
+ @Test
public void testScreenshotFinishesAfterBugreport() throws Exception {
resetProperties();
@@ -286,6 +306,7 @@ public class BugreportReceiverTest extends InstrumentationTestCase {
assertServiceNotRunning();
}
+ @Test
public void testProgress_changeDetailsInvalidInput() throws Exception {
resetProperties();
sendBugreportStarted(1000);
@@ -331,6 +352,7 @@ public class BugreportReceiverTest extends InstrumentationTestCase {
assertServiceNotRunning();
}
+ @Test
public void testProgress_cancelBugClosesDetailsDialog() throws Exception {
resetProperties();
sendBugreportStarted(1000);
@@ -346,10 +368,12 @@ public class BugreportReceiverTest extends InstrumentationTestCase {
assertServiceNotRunning();
}
+ @Test
public void testProgress_changeDetailsPlainBugreport() throws Exception {
changeDetailsTest(true);
}
+ @Test
public void testProgress_changeDetailsZippedBugreport() throws Exception {
changeDetailsTest(false);
}
@@ -383,10 +407,12 @@ public class BugreportReceiverTest extends InstrumentationTestCase {
assertServiceNotRunning();
}
+ @Test
public void testProgress_changeJustDetailsTouchingDetails() throws Exception {
changeJustDetailsTest(true);
}
+ @Test
public void testProgress_changeJustDetailsTouchingNotification() throws Exception {
changeJustDetailsTest(false);
}
@@ -410,6 +436,7 @@ public class BugreportReceiverTest extends InstrumentationTestCase {
assertServiceNotRunning();
}
+ @Test
public void testProgress_changeJustDetailsIsClearedOnSecondBugreport() throws Exception {
resetProperties();
sendBugreportStarted(ID, PID, NAME, 1000);
@@ -453,6 +480,7 @@ public class BugreportReceiverTest extends InstrumentationTestCase {
* Tests the scenario where the initial screenshot and dumpstate are finished while the user
* is changing the info in the details screen.
*/
+ @Test
public void testProgress_bugreportAndScreenshotFinishedWhileChangingDetails() throws Exception {
bugreportFinishedWhileChangingDetailsTest(false);
}
@@ -461,6 +489,7 @@ public class BugreportReceiverTest extends InstrumentationTestCase {
* Tests the scenario where dumpstate is finished while the user is changing the info in the
* details screen, but the initial screenshot finishes afterwards.
*/
+ @Test
public void testProgress_bugreportFinishedWhileChangingDetails() throws Exception {
bugreportFinishedWhileChangingDetailsTest(true);
}
@@ -500,14 +529,17 @@ public class BugreportReceiverTest extends InstrumentationTestCase {
assertServiceNotRunning();
}
+ @Test
public void testBugreportFinished_withWarningFirstTime() throws Exception {
bugreportFinishedWithWarningTest(null);
}
+ @Test
public void testBugreportFinished_withWarningUnknownState() throws Exception {
bugreportFinishedWithWarningTest(STATE_UNKNOWN);
}
+ @Test
public void testBugreportFinished_withWarningShowAgain() throws Exception {
bugreportFinishedWithWarningTest(STATE_SHOW);
}
@@ -560,6 +592,7 @@ public class BugreportReceiverTest extends InstrumentationTestCase {
assertEquals("Didn't change state", STATE_HIDE, newState);
}
+ @Test
public void testShareBugreportAfterServiceDies() throws Exception {
sendBugreportFinished(NO_ID, mPlainTextPath, NO_SCREENSHOT);
waitForService(false);
@@ -567,21 +600,25 @@ public class BugreportReceiverTest extends InstrumentationTestCase {
assertActionSendMultiple(extras, BUGREPORT_CONTENT, NO_SCREENSHOT);
}
+ @Test
public void testBugreportFinished_plainBugreportAndScreenshot() throws Exception {
Bundle extras = sendBugreportFinishedAndGetSharedIntent(mPlainTextPath, mScreenshotPath);
assertActionSendMultiple(extras, BUGREPORT_CONTENT, SCREENSHOT_CONTENT);
}
+ @Test
public void testBugreportFinished_zippedBugreportAndScreenshot() throws Exception {
Bundle extras = sendBugreportFinishedAndGetSharedIntent(mZipPath, mScreenshotPath);
assertActionSendMultiple(extras, BUGREPORT_CONTENT, SCREENSHOT_CONTENT);
}
+ @Test
public void testBugreportFinished_plainBugreportAndNoScreenshot() throws Exception {
Bundle extras = sendBugreportFinishedAndGetSharedIntent(mPlainTextPath, NO_SCREENSHOT);
assertActionSendMultiple(extras, BUGREPORT_CONTENT, NO_SCREENSHOT);
}
+ @Test
public void testBugreportFinished_zippedBugreportAndNoScreenshot() throws Exception {
Bundle extras = sendBugreportFinishedAndGetSharedIntent(mZipPath, NO_SCREENSHOT);
assertActionSendMultiple(extras, BUGREPORT_CONTENT, NO_SCREENSHOT);
@@ -1001,6 +1038,14 @@ public class BugreportReceiverTest extends InstrumentationTestCase {
mUiBot.assertNotVisibleById("android:id/alertTitle");
}
+ private String getName() {
+ return mName.getMethodName();
+ }
+
+ private Instrumentation getInstrumentation() {
+ return InstrumentationRegistry.getInstrumentation();
+ }
+
private static void sleep(long ms) {
Log.d(TAG, "sleeping for " + ms + "ms");
SystemClock.sleep(ms);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSContainer.java b/packages/SystemUI/src/com/android/systemui/qs/QSContainer.java
index ac90ce73fa03..19a5d522f530 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSContainer.java
@@ -237,6 +237,10 @@ public class QSContainer extends FrameLayout {
mQSPanel.setListening(mListening && mQsExpanded);
}
+ public void setHeaderListening(boolean listening) {
+ mHeader.setListening(listening);
+ }
+
public void setQsExpansion(float expansion, float headerTranslation) {
if (DEBUG) Log.d(TAG, "setQSExpansion " + expansion + " " + headerTranslation);
mQsExpansion = expansion;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
index b6597a025957..ed0fc1fee12a 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
@@ -251,10 +251,12 @@ public class QSPanel extends LinearLayout implements Tunable, Callback {
if (mListening) {
refreshAllTiles();
}
- if (listening) {
- mBrightnessController.registerCallbacks();
- } else {
- mBrightnessController.unregisterCallbacks();
+ if (mBrightnessView.getVisibility() == View.VISIBLE) {
+ if (listening) {
+ mBrightnessController.registerCallbacks();
+ } else {
+ mBrightnessController.unregisterCallbacks();
+ }
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenWallpaper.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenWallpaper.java
index 4638c8558ff7..1343c3ad0307 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenWallpaper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenWallpaper.java
@@ -26,6 +26,7 @@ import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Rect;
+import android.graphics.Xfermode;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.DrawableWrapper;
@@ -224,6 +225,12 @@ public class LockscreenWallpaper extends IWallpaperManagerCallback.Stub implemen
}
@Override
+ public void setXfermode(@Nullable Xfermode mode) {
+ // DrawableWrapper does not call this for us.
+ getDrawable().setXfermode(mode);
+ }
+
+ @Override
public int getIntrinsicWidth() {
return -1;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
index f27f8f53ad8d..812c5c151ce9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -1617,6 +1617,9 @@ public class NotificationPanelView extends PanelView implements
if (mQsExpanded) {
onQsExpansionStarted();
}
+ // Since there are QS tiles in the header now, we need to make sure we start listening
+ // immediately so they can be up to date.
+ mQsContainer.setHeaderListening(true);
}
@Override
diff --git a/services/core/java/com/android/server/pm/SELinuxMMAC.java b/services/core/java/com/android/server/pm/SELinuxMMAC.java
index a6350fe8cf35..89705560db7d 100644
--- a/services/core/java/com/android/server/pm/SELinuxMMAC.java
+++ b/services/core/java/com/android/server/pm/SELinuxMMAC.java
@@ -19,6 +19,7 @@ package com.android.server.pm;
import android.content.pm.PackageParser;
import android.content.pm.Signature;
import android.os.Environment;
+import android.os.SystemProperties;
import android.system.ErrnoException;
import android.system.Os;
import android.system.OsConstants;
@@ -64,6 +65,8 @@ public final class SELinuxMMAC {
// to synchronize access during policy load and access attempts.
private static List<Policy> sPolicies = new ArrayList<>();
+ private static final String PROP_FORCE_RESTORECON = "sys.force_restorecon";
+
/** Path to version on rootfs */
private static final File VERSION_FILE = new File("/selinux_version");
@@ -322,6 +325,11 @@ public final class SELinuxMMAC {
* @return Returns true if the restorecon should occur or false otherwise.
*/
public static boolean isRestoreconNeeded(File file) {
+ // To investigate boot timing, allow a property to always force restorecon
+ if (SystemProperties.getBoolean(PROP_FORCE_RESTORECON, false)) {
+ return true;
+ }
+
try {
final byte[] buf = new byte[20];
final int len = Os.getxattr(file.getAbsolutePath(), XATTR_SEAPP_HASH, buf);
diff --git a/services/core/java/com/android/server/policy/GlobalActions.java b/services/core/java/com/android/server/policy/GlobalActions.java
index 6fc15f0216e4..bb91f76ecf30 100644
--- a/services/core/java/com/android/server/policy/GlobalActions.java
+++ b/services/core/java/com/android/server/policy/GlobalActions.java
@@ -103,6 +103,7 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac
private static final String GLOBAL_ACTION_KEY_LOCKDOWN = "lockdown";
private static final String GLOBAL_ACTION_KEY_VOICEASSIST = "voiceassist";
private static final String GLOBAL_ACTION_KEY_ASSIST = "assist";
+ private static final String GLOBAL_ACTION_KEY_RESTART = "restart";
private final Context mContext;
private final WindowManagerFuncs mWindowManagerFuncs;
@@ -298,6 +299,8 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac
mItems.add(getVoiceAssistAction());
} else if (GLOBAL_ACTION_KEY_ASSIST.equals(actionKey)) {
mItems.add(getAssistAction());
+ } else if (GLOBAL_ACTION_KEY_RESTART.equals(actionKey)) {
+ mItems.add(new RestartAction());
} else {
Log.e(TAG, "Invalid global action key " + actionKey);
}
@@ -369,6 +372,38 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac
}
}
+ private final class RestartAction extends SinglePressAction implements LongPressAction {
+ private RestartAction() {
+ super(R.drawable.ic_restart, R.string.global_action_restart);
+ }
+
+ @Override
+ public boolean onLongPress() {
+ UserManager um = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
+ if (!um.hasUserRestriction(UserManager.DISALLOW_SAFE_BOOT)) {
+ mWindowManagerFuncs.rebootSafeMode(true);
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public boolean showDuringKeyguard() {
+ return true;
+ }
+
+ @Override
+ public boolean showBeforeProvisioning() {
+ return true;
+ }
+
+ @Override
+ public void onPress() {
+ mWindowManagerFuncs.reboot(false /* confirm */);
+ }
+ }
+
+
private class BugReportAction extends SinglePressAction implements LongPressAction {
public BugReportAction() {
diff --git a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
index e266b924cd0d..76f2f0e43e9b 100644
--- a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
+++ b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
@@ -1400,9 +1400,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub {
wallpaper.whichPending = which;
wallpaper.setComplete = completion;
wallpaper.cropHint.set(cropHint);
- if ((which & FLAG_SYSTEM) != 0) {
- wallpaper.allowBackup = allowBackup;
- }
+ wallpaper.allowBackup = allowBackup;
}
return pfd;
} finally {
diff --git a/services/core/java/com/android/server/wm/WindowAnimator.java b/services/core/java/com/android/server/wm/WindowAnimator.java
index 6515fbdd0587..34fa1b023dce 100644
--- a/services/core/java/com/android/server/wm/WindowAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowAnimator.java
@@ -119,6 +119,8 @@ public class WindowAnimator {
// check if some got replaced and can be removed.
private boolean mRemoveReplacedWindows = false;
+ private final AppTokenList mTmpExitingAppTokens = new AppTokenList();
+
private String forceHidingToString() {
switch (mForceHiding) {
case KEYGUARD_NOT_SHOWN: return "KEYGUARD_NOT_SHOWN";
@@ -189,10 +191,19 @@ public class WindowAnimator {
}
}
- final AppTokenList exitingAppTokens = stack.mExitingAppTokens;
- final int exitingCount = exitingAppTokens.size();
+ mTmpExitingAppTokens.clear();
+ mTmpExitingAppTokens.addAll(stack.mExitingAppTokens);
+
+ final int exitingCount = mTmpExitingAppTokens.size();
for (int i = 0; i < exitingCount; i++) {
- final AppWindowAnimator appAnimator = exitingAppTokens.get(i).mAppAnimator;
+ final AppWindowAnimator appAnimator = mTmpExitingAppTokens.get(i).mAppAnimator;
+ // stepAnimation can trigger finishExit->removeWindowInnerLocked
+ // ->performSurfacePlacement
+ // performSurfacePlacement will directly manipulate the mExitingAppTokens list
+ // so we need to iterate over a copy and check for modifications.
+ if (!stack.mExitingAppTokens.contains(appAnimator)) {
+ continue;
+ }
appAnimator.wasAnimating = appAnimator.animating;
if (appAnimator.stepAnimationLocked(mCurrentTime, displayId)) {
setAnimating(true);
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 1bcab99594b6..22120d016af4 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -4727,6 +4727,12 @@ public class WindowManagerService extends IWindowManager.Stub
// Called by window manager policy. Not exposed externally.
@Override
+ public void reboot(boolean confirm) {
+ ShutdownThread.reboot(mContext, PowerManager.SHUTDOWN_USER_REQUESTED, confirm);
+ }
+
+ // Called by window manager policy. Not exposed externally.
+ @Override
public void rebootSafeMode(boolean confirm) {
ShutdownThread.rebootSafeMode(mContext, confirm);
}
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index 0fcf0c71e474..dfee8de144d2 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -845,6 +845,22 @@ class WindowStateAnimator {
mPendingDestroySurface = null;
}
+ void applyMagnificationSpec(MagnificationSpec spec, Matrix transform) {
+ final int surfaceInsetLeft = mWin.mAttrs.surfaceInsets.left;
+ final int surfaceInsetTop = mWin.mAttrs.surfaceInsets.top;
+
+ if (spec != null && !spec.isNop()) {
+ float scale = spec.scale;
+ transform.postScale(scale, scale);
+ transform.postTranslate(spec.offsetX, spec.offsetY);
+
+ // As we are scaling the whole surface, to keep the content
+ // in the same position we will also have to scale the surfaceInsets.
+ transform.postTranslate(-(surfaceInsetLeft*scale - surfaceInsetLeft),
+ -(surfaceInsetTop*scale - surfaceInsetTop));
+ }
+ }
+
void computeShownFrameLocked() {
final boolean selfTransformation = mHasLocalTransformation;
Transformation attachedTransformation =
@@ -935,10 +951,7 @@ class WindowStateAnimator {
if (mService.mAccessibilityController != null && displayId == DEFAULT_DISPLAY) {
MagnificationSpec spec = mService.mAccessibilityController
.getMagnificationSpecForWindowLocked(mWin);
- if (spec != null && !spec.isNop()) {
- tmpMatrix.postScale(spec.scale, spec.scale);
- tmpMatrix.postTranslate(spec.offsetX, spec.offsetY);
- }
+ applyMagnificationSpec(spec, tmpMatrix);
}
// "convert" it into SurfaceFlinger's format
@@ -1037,10 +1050,7 @@ class WindowStateAnimator {
tmpMatrix.setScale(mWin.mGlobalScale, mWin.mGlobalScale);
tmpMatrix.postTranslate(frame.left + mWin.mXOffset, frame.top + mWin.mYOffset);
- if (spec != null && !spec.isNop()) {
- tmpMatrix.postScale(spec.scale, spec.scale);
- tmpMatrix.postTranslate(spec.offsetX, spec.offsetY);
- }
+ applyMagnificationSpec(spec, tmpMatrix);
tmpMatrix.getValues(tmpFloats);
@@ -1896,11 +1906,13 @@ class WindowStateAnimator {
if (mDeferTransactionUntilFrame < 0) {
return;
}
+ final WindowState parentWindow = mWin.getParentWindow();
long time = System.currentTimeMillis();
if (time > mDeferTransactionTime + PENDING_TRANSACTION_FINISH_WAIT_TIME) {
mDeferTransactionTime = -1;
mDeferTransactionUntilFrame = -1;
- } else {
+ } else if (parentWindow != null &&
+ parentWindow.mWinAnimator.hasSurface()) {
mSurfaceController.deferTransactionUntil(
mWin.getParentWindow().mWinAnimator.mSurfaceController.getHandle(),
mDeferTransactionUntilFrame);
diff --git a/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java
index 73033589e308..6247089953ad 100644
--- a/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java
@@ -34,6 +34,12 @@ import static com.android.server.net.NetworkPolicyManagerService.TYPE_LIMIT;
import static com.android.server.net.NetworkPolicyManagerService.TYPE_LIMIT_SNOOZED;
import static com.android.server.net.NetworkPolicyManagerService.TYPE_WARNING;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyBoolean;
import static org.mockito.Matchers.anyInt;
@@ -74,7 +80,8 @@ import android.os.Binder;
import android.os.INetworkManagementService;
import android.os.PowerManagerInternal;
import android.os.UserHandle;
-import android.test.AndroidTestCase;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.runner.AndroidJUnit4;
import android.text.format.Time;
import android.util.Log;
import android.util.TrustedTime;
@@ -86,6 +93,11 @@ import libcore.io.IoUtils;
import com.google.common.util.concurrent.AbstractFuture;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
@@ -105,7 +117,8 @@ import java.util.concurrent.TimeoutException;
/**
* Tests for {@link NetworkPolicyManagerService}.
*/
-public class NetworkPolicyManagerServiceTest extends AndroidTestCase {
+@RunWith(AndroidJUnit4.class)
+public class NetworkPolicyManagerServiceTest {
private static final String TAG = "NetworkPolicyManagerServiceTest";
private static final long TEST_START = 1194220800000L;
@@ -116,7 +129,6 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase {
private BroadcastInterceptingContext mServiceContext;
private File mPolicyDir;
- private List<Class<?>> mLocalServices = new ArrayList<>();
private @Mock IActivityManager mActivityManager;
private @Mock INetworkStatsService mStatsService;
@@ -124,7 +136,6 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase {
private @Mock TrustedTime mTime;
private @Mock IConnectivityManager mConnManager;
private @Mock INotificationManager mNotifManager;
- private @Mock UsageStatsManagerInternal mUsageStats;
private @Mock PackageManager mPackageManager;
private IUidObserver mUidObserver;
@@ -146,12 +157,20 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase {
private static final String PKG_NAME_A = "name.is.A,pkg.A";
- public void setUp() throws Exception {
- super.setUp();
+ @BeforeClass
+ public static void registerLocalServices() {
+ addLocalServiceMock(PowerManagerInternal.class);
+ addLocalServiceMock(DeviceIdleController.LocalService.class);
+ final UsageStatsManagerInternal usageStats =
+ addLocalServiceMock(UsageStatsManagerInternal.class);
+ when(usageStats.getIdleUidsForUser(anyInt())).thenReturn(new int[]{});
+ }
+ @Before
+ public void callSystemReady() throws Exception {
MockitoAnnotations.initMocks(this);
- final Context context = getContext();
+ final Context context = InstrumentationRegistry.getContext();
setCurrentTimeMillis(TEST_START);
@@ -183,10 +202,6 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase {
}
}).when(mActivityManager).registerUidObserver(any(), anyInt());
- addLocalServiceMock(PowerManagerInternal.class);
- addLocalServiceMock(DeviceIdleController.LocalService.class);
- addLocalServiceMock(UsageStatsManagerInternal.class, mUsageStats);
-
mService = new NetworkPolicyManagerService(mServiceContext, mActivityManager, mStatsService,
mNetworkManager, mTime, mPolicyDir, true);
mService.bindConnectivityManager(mConnManager);
@@ -216,7 +231,6 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase {
when(mPackageManager.getApplicationInfoAsUser(anyString(), anyInt(), anyInt()))
.thenReturn(new ApplicationInfo());
when(mPackageManager.getPackagesForUid(UID_A)).thenReturn(new String[] {PKG_NAME_A});
- when(mUsageStats.getIdleUidsForUser(anyInt())).thenReturn(new int[]{});
when(mNetworkManager.isBandwidthControlEnabled()).thenReturn(true);
expectCurrentTime();
@@ -230,28 +244,17 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase {
mNetworkObserver = networkObserver.getValue();
}
- public void tearDown() throws Exception {
+ @After
+ public void removeFiles() throws Exception {
for (File file : mPolicyDir.listFiles()) {
file.delete();
}
+ }
- mServiceContext = null;
- mPolicyDir = null;
-
- mActivityManager = null;
- mStatsService = null;
- mTime = null;
-
- mService = null;
-
- // TODO: must remove services, otherwise next test will fail.
- // JUnit4 would avoid that hack by using a static setup.
- removeLocalServiceMocks();
-
- // Added by NetworkPolicyManagerService's constructor.
+ @After
+ public void unregisterLocalServices() throws Exception {
+ // Registered by NetworkPolicyManagerService's constructor.
LocalServices.removeServiceForTest(NetworkPolicyManagerInternal.class);
-
- super.tearDown();
}
// NOTE: testPolicyChangeTriggersListener() and testUidForeground() are too superficial, they
@@ -259,6 +262,7 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase {
// different modes (Data Saver, Battery Saver, Doze, App idle, etc...).
// These scenarios are extensively tested on CTS' HostsideRestrictBackgroundNetworkTests.
+ @Test
public void testPolicyChangeTriggersListener() throws Exception {
mPolicyListener.expect().onRestrictBackgroundBlacklistChanged(anyInt(), anyBoolean());
@@ -268,6 +272,7 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase {
mPolicyListener.waitAndVerify().onRestrictBackgroundBlacklistChanged(APP_ID_A, true);
}
+ @Test
public void testUidForeground() throws Exception {
// push all uids into background
mUidObserver.onUidStateChanged(UID_A, ActivityManager.PROCESS_STATE_SERVICE);
@@ -287,6 +292,7 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase {
assertTrue(mService.isUidForeground(UID_B));
}
+ @Test
public void testLastCycleBoundaryThisMonth() throws Exception {
// assume cycle day of "5th", which should be in same month
final long currentTime = parseTime("2007-11-14T00:00:00.000Z");
@@ -298,6 +304,7 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase {
assertTimeEquals(expectedCycle, actualCycle);
}
+ @Test
public void testLastCycleBoundaryLastMonth() throws Exception {
// assume cycle day of "20th", which should be in last month
final long currentTime = parseTime("2007-11-14T00:00:00.000Z");
@@ -309,6 +316,7 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase {
assertTimeEquals(expectedCycle, actualCycle);
}
+ @Test
public void testLastCycleBoundaryThisMonthFebruary() throws Exception {
// assume cycle day of "30th" in february; should go to january
final long currentTime = parseTime("2007-02-14T00:00:00.000Z");
@@ -320,6 +328,7 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase {
assertTimeEquals(expectedCycle, actualCycle);
}
+ @Test
public void testLastCycleBoundaryLastMonthFebruary() throws Exception {
// assume cycle day of "30th" in february, which should clamp
final long currentTime = parseTime("2007-03-14T00:00:00.000Z");
@@ -331,6 +340,7 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase {
assertTimeEquals(expectedCycle, actualCycle);
}
+ @Test
public void testCycleBoundaryLeapYear() throws Exception {
final NetworkPolicy policy = new NetworkPolicy(
sTemplateWifi, 29, TIMEZONE_UTC, 1024L, 1024L, false);
@@ -354,6 +364,7 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase {
computeNextCycleBoundary(parseTime("2007-03-14T00:00:00.000Z"), policy));
}
+ @Test
public void testNextCycleTimezoneAfterUtc() throws Exception {
// US/Central is UTC-6
final NetworkPolicy policy = new NetworkPolicy(
@@ -362,6 +373,7 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase {
computeNextCycleBoundary(parseTime("2012-01-05T00:00:00.000Z"), policy));
}
+ @Test
public void testNextCycleTimezoneBeforeUtc() throws Exception {
// Israel is UTC+2
final NetworkPolicy policy = new NetworkPolicy(
@@ -370,6 +382,7 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase {
computeNextCycleBoundary(parseTime("2012-01-05T00:00:00.000Z"), policy));
}
+ @Test
public void testNextCycleSane() throws Exception {
final NetworkPolicy policy = new NetworkPolicy(
sTemplateWifi, 31, TIMEZONE_UTC, WARNING_DISABLED, LIMIT_DISABLED, false);
@@ -385,6 +398,7 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase {
}
}
+ @Test
public void testLastCycleSane() throws Exception {
final NetworkPolicy policy = new NetworkPolicy(
sTemplateWifi, 31, TIMEZONE_UTC, WARNING_DISABLED, LIMIT_DISABLED, false);
@@ -400,6 +414,7 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase {
}
}
+ @Test
public void testCycleTodayJanuary() throws Exception {
final NetworkPolicy policy = new NetworkPolicy(
sTemplateWifi, 14, "US/Pacific", 1024L, 1024L, false);
@@ -419,6 +434,7 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase {
computeLastCycleBoundary(parseTime("2013-01-14T15:11:00.000-08:00"), policy));
}
+ @Test
public void testLastCycleBoundaryDST() throws Exception {
final long currentTime = parseTime("1989-01-02T07:30:00.000");
final long expectedCycle = parseTime("1988-12-03T02:00:00.000Z");
@@ -429,6 +445,7 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase {
assertTimeEquals(expectedCycle, actualCycle);
}
+ @Test
public void testNetworkPolicyAppliedCycleLastMonth() throws Exception {
NetworkState[] state = null;
NetworkStats stats = null;
@@ -471,6 +488,7 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase {
verifySetInterfaceQuota(TEST_IFACE, (2 * MB_IN_BYTES) - 512);
}
+ @Test
public void testOverWarningLimitNotification() throws Exception {
NetworkState[] state = null;
NetworkStats stats = null;
@@ -579,6 +597,7 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase {
}
}
+ @Test
public void testMeteredNetworkWithoutLimit() throws Exception {
NetworkState[] state = null;
NetworkStats stats = null;
@@ -740,32 +759,13 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase {
/**
* Creates a mock and registers it to {@link LocalServices}.
*/
- private <T> T addLocalServiceMock(Class<T> clazz) {
+ private static <T> T addLocalServiceMock(Class<T> clazz) {
final T mock = mock(clazz);
- return addLocalServiceMock(clazz, mock);
- }
-
- /**
- * Registers a mock to {@link LocalServices}.
- */
- private <T> T addLocalServiceMock(Class<T> clazz, T mock) {
LocalServices.addService(clazz, mock);
- mLocalServices.add(clazz);
return mock;
}
/**
- * Unregisters all mocks from {@link LocalServices}.
- */
- private void removeLocalServiceMocks() {
- for (Class<?> clazz : mLocalServices) {
- Log.d(TAG, "removeLocalServiceMock(): " + clazz.getName());
- LocalServices.removeServiceForTest(clazz);
- }
- mLocalServices.clear();
- }
-
- /**
* Custom Mockito answer used to verify async {@link INetworkPolicyListener} calls.
*
* <p>Typical usage:
diff --git a/services/usb/java/com/android/server/usb/UsbDeviceManager.java b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
index 8560651fa7ec..efd479f394c5 100644
--- a/services/usb/java/com/android/server/usb/UsbDeviceManager.java
+++ b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
@@ -563,6 +563,7 @@ public class UsbDeviceManager {
mAccessoryModeRequestTime + ACCESSORY_REQUEST_TIMEOUT;
if (mConfigured && enteringAccessoryMode) {
+ mAccessoryModeRequestTime = 0;
// successfully entered accessory mode
if (mAccessoryStrings != null) {
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java
index b0cc2aca8981..c3075b3daa3e 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java
@@ -46,6 +46,7 @@ import android.util.Slog;
import android.view.IWindowManager;
import android.view.WindowManager;
+import com.android.internal.app.AssistUtils;
import com.android.internal.app.IAssistScreenshotReceiver;
import com.android.internal.app.IVoiceInteractionSessionShowCallback;
import com.android.internal.app.IVoiceInteractor;
@@ -301,7 +302,7 @@ final class VoiceInteractionSessionConnection implements ServiceConnection {
} else {
mScreenshot = null;
}
- if (needDisclosure) {
+ if (needDisclosure && AssistUtils.shouldDisclose(mContext, mSessionComponentName)) {
mHandler.post(mShowAssistDisclosureRunnable);
}
if (mSession != null) {
diff --git a/telephony/java/android/telephony/DisconnectCause.java b/telephony/java/android/telephony/DisconnectCause.java
index d7d4e840aa77..f5e422df7511 100644
--- a/telephony/java/android/telephony/DisconnectCause.java
+++ b/telephony/java/android/telephony/DisconnectCause.java
@@ -212,6 +212,20 @@ public class DisconnectCause {
*/
public static final int MAXIMUM_NUMBER_OF_CALLS_REACHED = 53;
+ /**
+ * The call was terminated because cellular data has been disabled.
+ * Used when in a video call and the user disables cellular data via the settings.
+ * {@hide}
+ */
+ public static final int DATA_DISABLED = 54;
+
+ /**
+ * The call was terminated because the data policy has disabled cellular data.
+ * Used when in a video call and the user has exceeded the device data limit.
+ * {@hide}
+ */
+ public static final int DATA_LIMIT_REACHED = 55;
+
//*********************************************************************************************
// When adding a disconnect type:
// 1) Please assign the new type the next id value below.
@@ -220,14 +234,14 @@ public class DisconnectCause {
// 4) Update toString() with the newly added disconnect type.
// 5) Update android.telecom.DisconnectCauseUtil with any mappings to a telecom.DisconnectCause.
//
- // NextId: 54
+ // NextId: 56
//*********************************************************************************************
/** Smallest valid value for call disconnect codes. */
public static final int MINIMUM_VALID_VALUE = NOT_DISCONNECTED;
/** Largest valid value for call disconnect codes. */
- public static final int MAXIMUM_VALID_VALUE = MAXIMUM_NUMBER_OF_CALLS_REACHED;
+ public static final int MAXIMUM_VALID_VALUE = DATA_LIMIT_REACHED;
/** Private constructor to avoid class instantiation. */
private DisconnectCause() {
@@ -343,6 +357,10 @@ public class DisconnectCause {
return "ANSWERED_ELSEWHERE";
case MAXIMUM_NUMBER_OF_CALLS_REACHED:
return "MAXIMUM_NUMER_OF_CALLS_REACHED";
+ case DATA_DISABLED:
+ return "DATA_DISABLED";
+ case DATA_LIMIT_REACHED:
+ return "DATA_LIMIT_REACHED";
default:
return "INVALID: " + cause;
}
diff --git a/telephony/java/com/android/ims/ImsReasonInfo.java b/telephony/java/com/android/ims/ImsReasonInfo.java
index 408ad31674c4..56b882221cd7 100644
--- a/telephony/java/com/android/ims/ImsReasonInfo.java
+++ b/telephony/java/com/android/ims/ImsReasonInfo.java
@@ -298,6 +298,16 @@ public class ImsReasonInfo implements Parcelable {
public static final int CODE_REMOTE_CALL_DECLINE = 1404;
/**
+ * Indicates the call was disconnected due to the user reaching their data limit.
+ */
+ public static final int CODE_DATA_LIMIT_REACHED = 1405;
+
+ /**
+ * Indicates the call was disconnected due to the user disabling cellular data.
+ */
+ public static final int CODE_DATA_DISABLED = 1406;
+
+ /**
* Network string error messages.
* mExtraMessage may have these values.
*/
diff --git a/tools/aapt2/link/TableMerger.cpp b/tools/aapt2/link/TableMerger.cpp
index 6ec88cbe3b0f..379c991c98d2 100644
--- a/tools/aapt2/link/TableMerger.cpp
+++ b/tools/aapt2/link/TableMerger.cpp
@@ -142,7 +142,7 @@ bool TableMerger::doMerge(const Source& src,
ResourceTableType* dstType = mMasterPackage->findOrCreateType(srcType->type);
if (srcType->symbolStatus.state == SymbolState::kPublic) {
if (dstType->symbolStatus.state == SymbolState::kPublic && dstType->id && srcType->id
- && dstType->id.value() == srcType->id.value()) {
+ && dstType->id.value() != srcType->id.value()) {
// Both types are public and have different IDs.
mContext->getDiagnostics()->error(DiagMessage(src)
<< "can not merge type '"
diff --git a/tools/aapt2/link/TableMerger_test.cpp b/tools/aapt2/link/TableMerger_test.cpp
index 300b56ddb3a1..ff3e21f12d19 100644
--- a/tools/aapt2/link/TableMerger_test.cpp
+++ b/tools/aapt2/link/TableMerger_test.cpp
@@ -164,6 +164,63 @@ TEST_F(TableMergerTest, OverrideResourceWithOverlay) {
EXPECT_EQ(0x0u, foo->value.data);
}
+TEST_F(TableMergerTest, OverrideSameResourceIdsWithOverlay) {
+ std::unique_ptr<ResourceTable> base = test::ResourceTableBuilder()
+ .setPackageId("", 0x7f)
+ .setSymbolState("bool/foo", ResourceId(0x7f, 0x01, 0x0001), SymbolState::kPublic)
+ .build();
+ std::unique_ptr<ResourceTable> overlay = test::ResourceTableBuilder()
+ .setPackageId("", 0x7f)
+ .setSymbolState("bool/foo", ResourceId(0x7f, 0x01, 0x0001), SymbolState::kPublic)
+ .build();
+
+ ResourceTable finalTable;
+ TableMergerOptions tableMergerOptions;
+ tableMergerOptions.autoAddOverlay = false;
+ TableMerger merger(mContext.get(), &finalTable, tableMergerOptions);
+
+ ASSERT_TRUE(merger.merge({}, base.get()));
+ ASSERT_TRUE(merger.mergeOverlay({}, overlay.get()));
+}
+
+TEST_F(TableMergerTest, FailToOverrideConflictingTypeIdsWithOverlay) {
+ std::unique_ptr<ResourceTable> base = test::ResourceTableBuilder()
+ .setPackageId("", 0x7f)
+ .setSymbolState("bool/foo", ResourceId(0x7f, 0x01, 0x0001), SymbolState::kPublic)
+ .build();
+ std::unique_ptr<ResourceTable> overlay = test::ResourceTableBuilder()
+ .setPackageId("", 0x7f)
+ .setSymbolState("bool/foo", ResourceId(0x7f, 0x02, 0x0001), SymbolState::kPublic)
+ .build();
+
+ ResourceTable finalTable;
+ TableMergerOptions tableMergerOptions;
+ tableMergerOptions.autoAddOverlay = false;
+ TableMerger merger(mContext.get(), &finalTable, tableMergerOptions);
+
+ ASSERT_TRUE(merger.merge({}, base.get()));
+ ASSERT_FALSE(merger.mergeOverlay({}, overlay.get()));
+}
+
+TEST_F(TableMergerTest, FailToOverrideConflictingEntryIdsWithOverlay) {
+ std::unique_ptr<ResourceTable> base = test::ResourceTableBuilder()
+ .setPackageId("", 0x7f)
+ .setSymbolState("bool/foo", ResourceId(0x7f, 0x01, 0x0001), SymbolState::kPublic)
+ .build();
+ std::unique_ptr<ResourceTable> overlay = test::ResourceTableBuilder()
+ .setPackageId("", 0x7f)
+ .setSymbolState("bool/foo", ResourceId(0x7f, 0x01, 0x0002), SymbolState::kPublic)
+ .build();
+
+ ResourceTable finalTable;
+ TableMergerOptions tableMergerOptions;
+ tableMergerOptions.autoAddOverlay = false;
+ TableMerger merger(mContext.get(), &finalTable, tableMergerOptions);
+
+ ASSERT_TRUE(merger.merge({}, base.get()));
+ ASSERT_FALSE(merger.mergeOverlay({}, overlay.get()));
+}
+
TEST_F(TableMergerTest, MergeAddResourceFromOverlay) {
std::unique_ptr<ResourceTable> tableA = test::ResourceTableBuilder()
.setPackageId("", 0x7f)