summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--api/current.txt20
-rw-r--r--cmds/bootanimation/BootAnimation.cpp45
-rw-r--r--cmds/bootanimation/BootAnimation.h1
-rw-r--r--cmds/media/src/com/android/commands/media/Media.java3
-rw-r--r--core/java/android/bluetooth/BluetoothGatt.java16
-rw-r--r--core/java/android/bluetooth/BluetoothGattCallbackWrapper.java4
-rw-r--r--core/java/android/bluetooth/BluetoothGattServer.java19
-rw-r--r--core/java/android/bluetooth/IBluetoothGattCallback.aidl1
-rw-r--r--core/java/android/bluetooth/IBluetoothGattServerCallback.aidl1
-rw-r--r--core/java/android/content/Intent.java6
-rw-r--r--core/java/android/hardware/camera2/legacy/BurstHolder.java11
-rw-r--r--core/java/android/hardware/camera2/legacy/CameraDeviceUserShim.java10
-rw-r--r--core/java/android/hardware/camera2/legacy/LegacyCameraDevice.java2
-rw-r--r--core/java/android/hardware/camera2/legacy/RequestHolder.java132
-rw-r--r--core/java/android/hardware/camera2/legacy/RequestQueue.java7
-rw-r--r--core/java/android/hardware/camera2/legacy/RequestThreadManager.java68
-rw-r--r--core/java/android/hardware/camera2/legacy/SurfaceTextureRenderer.java1
-rw-r--r--core/java/android/os/Binder.java24
-rw-r--r--core/java/android/os/RecoverySystem.java73
-rw-r--r--core/java/android/provider/Settings.java13
-rw-r--r--core/java/android/service/notification/NotificationListenerService.java2
-rw-r--r--core/java/android/speech/tts/SynthesisRequest.java2
-rw-r--r--core/java/android/speech/tts/TextToSpeech.java32
-rw-r--r--core/java/android/speech/tts/TextToSpeechService.java2
-rw-r--r--core/java/android/util/DisplayMetrics.java2
-rw-r--r--core/java/android/view/AccessibilityInteractionController.java8
-rw-r--r--core/java/android/view/WindowManagerGlobal.java7
-rw-r--r--core/java/android/widget/AbsListView.java56
-rw-r--r--core/java/com/android/internal/app/ResolverActivity.java18
-rw-r--r--core/java/com/android/internal/os/storage/ExternalStorageFormatter.java17
-rw-r--r--core/java/com/android/internal/widget/LockPatternUtils.java26
-rw-r--r--core/jni/android_hardware_camera2_legacy_LegacyCameraDevice.cpp25
-rw-r--r--core/jni/android_util_Binder.cpp2
-rw-r--r--core/res/res/values/config.xml7
-rw-r--r--core/res/res/values/strings.xml5
-rw-r--r--core/res/res/values/symbols.xml4
-rw-r--r--docs/html/app.yaml45
-rw-r--r--graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java11
-rw-r--r--graphics/java/android/graphics/drawable/RippleBackground.java2
-rw-r--r--location/java/com/android/internal/location/GpsNetInitiatedHandler.java2
-rw-r--r--media/java/android/media/ImageReader.java9
-rw-r--r--media/java/android/media/MediaCodec.java32
-rw-r--r--media/java/android/media/MediaCodecList.java2
-rw-r--r--media/java/android/media/browse/MediaBrowser.java1
-rw-r--r--media/java/android/media/session/MediaController.java3
-rw-r--r--media/java/android/media/session/MediaSession.java2
-rw-r--r--media/jni/android_media_ImageReader.cpp59
-rw-r--r--packages/SystemUI/res/anim/zen_toast_enter.xml20
-rw-r--r--packages/SystemUI/res/anim/zen_toast_exit.xml20
-rw-r--r--packages/SystemUI/res/drawable/ic_zen_important.xml25
-rw-r--r--packages/SystemUI/res/drawable/ic_zen_none.xml25
-rw-r--r--packages/SystemUI/res/drawable/zen_toast_background.xml19
-rw-r--r--packages/SystemUI/res/layout/zen_mode_panel.xml1
-rw-r--r--packages/SystemUI/res/layout/zen_toast.xml41
-rw-r--r--packages/SystemUI/res/values/config.xml6
-rw-r--r--packages/SystemUI/res/values/dimens.xml3
-rw-r--r--packages/SystemUI/res/values/strings.xml4
-rw-r--r--packages/SystemUI/res/values/styles.xml9
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationControllerImpl.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/ZenToast.java151
-rw-r--r--policy/src/com/android/internal/policy/impl/PhoneWindow.java60
-rw-r--r--services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java19
-rw-r--r--services/core/java/com/android/server/MasterClearReceiver.java3
-rwxr-xr-xservices/core/java/com/android/server/am/ActiveServices.java3
-rwxr-xr-xservices/core/java/com/android/server/am/ActivityManagerService.java26
-rw-r--r--services/core/java/com/android/server/input/InputManagerService.java35
-rw-r--r--services/core/java/com/android/server/notification/NotificationManagerService.java18
-rw-r--r--services/core/java/com/android/server/notification/ValidateNotificationPeople.java47
-rw-r--r--services/core/java/com/android/server/notification/ZenModeHelper.java11
-rw-r--r--services/devicepolicy/java/com/android/server/devicepolicy/DeviceOwner.java17
-rw-r--r--services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java30
-rw-r--r--telecomm/java/android/telecom/PhoneAccount.java3
-rw-r--r--telecomm/java/android/telecom/RemoteConference.java14
-rw-r--r--telephony/java/android/telephony/TelephonyManager.java23
-rw-r--r--tests/OneMedia/src/com/android/onemedia/PlayerSession.java12
-rw-r--r--tests/VectorDrawableTest/AndroidManifest.xml9
-rw-r--r--tests/VectorDrawableTest/res/drawable/vector_drawable24.xml15
-rw-r--r--tests/VectorDrawableTest/res/drawable/vector_drawable25.xml7
-rw-r--r--tests/VectorDrawableTest/src/com/android/test/dynamic/AnimatedVectorDrawableDupPerf.java122
-rw-r--r--tools/aapt/ResourceTable.cpp19
-rw-r--r--tools/aapt/ResourceTable.h1
82 files changed, 1265 insertions, 402 deletions
diff --git a/api/current.txt b/api/current.txt
index 047f8d5..eb7891a 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -25582,10 +25582,6 @@ package android.provider {
public static final class Telephony.Mms.Intents {
field public static final java.lang.String CONTENT_CHANGED_ACTION = "android.intent.action.CONTENT_CHANGED";
field public static final java.lang.String DELETED_CONTENTS = "deleted_contents";
- field public static final java.lang.String EXTRA_MMS_CONTENT_URI = "android.provider.Telephony.extra.MMS_CONTENT_URI";
- field public static final java.lang.String EXTRA_MMS_LOCATION_URL = "android.provider.Telephony.extra.MMS_LOCATION_URL";
- field public static final java.lang.String MMS_DOWNLOAD_ACTION = "android.provider.Telephony.MMS_DOWNLOAD";
- field public static final java.lang.String MMS_SEND_ACTION = "android.provider.Telephony.MMS_SEND";
}
public static final class Telephony.Mms.Outbox implements android.provider.Telephony.BaseMmsColumns {
@@ -25689,10 +25685,8 @@ package android.provider {
field public static final java.lang.String SMS_CB_RECEIVED_ACTION = "android.provider.Telephony.SMS_CB_RECEIVED";
field public static final java.lang.String SMS_DELIVER_ACTION = "android.provider.Telephony.SMS_DELIVER";
field public static final java.lang.String SMS_EMERGENCY_CB_RECEIVED_ACTION = "android.provider.Telephony.SMS_EMERGENCY_CB_RECEIVED";
- field public static final java.lang.String SMS_FILTER_ACTION = "android.provider.Telephony.SMS_FILTER";
field public static final java.lang.String SMS_RECEIVED_ACTION = "android.provider.Telephony.SMS_RECEIVED";
field public static final java.lang.String SMS_REJECTED_ACTION = "android.provider.Telephony.SMS_REJECTED";
- field public static final java.lang.String SMS_SEND_ACTION = "android.provider.Telephony.SMS_SEND";
field public static final java.lang.String SMS_SERVICE_CATEGORY_PROGRAM_DATA_RECEIVED_ACTION = "android.provider.Telephony.SMS_SERVICE_CATEGORY_PROGRAM_DATA_RECEIVED";
field public static final java.lang.String WAP_PUSH_DELIVER_ACTION = "android.provider.Telephony.WAP_PUSH_DELIVER";
field public static final java.lang.String WAP_PUSH_RECEIVED_ACTION = "android.provider.Telephony.WAP_PUSH_RECEIVED";
@@ -27277,8 +27271,8 @@ package android.speech.tts {
method public boolean isSpeaking();
method public int playEarcon(java.lang.String, int, android.os.Bundle, java.lang.String);
method public deprecated int playEarcon(java.lang.String, int, java.util.HashMap<java.lang.String, java.lang.String>);
- method public int playSilence(long, int, java.lang.String);
method public deprecated int playSilence(long, int, java.util.HashMap<java.lang.String, java.lang.String>);
+ method public int playSilentUtterance(long, int, java.lang.String);
method public int setAudioAttributes(android.media.AudioAttributes);
method public deprecated int setEngineByPackageName(java.lang.String);
method public int setLanguage(java.util.Locale);
@@ -28374,14 +28368,10 @@ package android.telephony {
method public void downloadMultimediaMessage(android.content.Context, java.lang.String, android.net.Uri, android.os.Bundle, android.app.PendingIntent);
method public android.os.Bundle getCarrierConfigValues();
method public static android.telephony.SmsManager getDefault();
- method public void injectSmsPdu(byte[], java.lang.String, android.app.PendingIntent);
method public void sendDataMessage(java.lang.String, java.lang.String, short, byte[], android.app.PendingIntent, android.app.PendingIntent);
method public void sendMultimediaMessage(android.content.Context, android.net.Uri, java.lang.String, android.os.Bundle, android.app.PendingIntent);
method public void sendMultipartTextMessage(java.lang.String, java.lang.String, java.util.ArrayList<java.lang.String>, java.util.ArrayList<android.app.PendingIntent>, java.util.ArrayList<android.app.PendingIntent>);
method public void sendTextMessage(java.lang.String, java.lang.String, java.lang.String, android.app.PendingIntent, android.app.PendingIntent);
- method public void updateMmsDownloadStatus(android.content.Context, int, int, android.net.Uri);
- method public void updateMmsSendStatus(android.content.Context, int, byte[], int, android.net.Uri);
- method public void updateSmsSendStatus(int, boolean);
field public static final java.lang.String EXTRA_MMS_DATA = "android.telephony.extra.MMS_DATA";
field public static final java.lang.String MMS_CONFIG_ALIAS_ENABLED = "aliasEnabled";
field public static final java.lang.String MMS_CONFIG_ALIAS_MAX_CHARS = "aliasMaxChars";
@@ -28514,7 +28504,6 @@ package android.telephony {
method public java.lang.String getSubscriberId();
method public java.lang.String getVoiceMailAlphaTag();
method public java.lang.String getVoiceMailNumber();
- method public int hasCarrierPrivileges();
method public boolean hasIccCard();
method public boolean iccCloseLogicalChannel(int);
method public byte[] iccExchangeSimIO(int, int, int, int, int, java.lang.String);
@@ -28525,18 +28514,11 @@ package android.telephony {
method public boolean isSmsCapable();
method public void listen(android.telephony.PhoneStateListener, int);
method public java.lang.String sendEnvelopeWithStatus(java.lang.String);
- method public boolean setGlobalPreferredNetworkType();
- method public void setLine1NumberForDisplay(java.lang.String, java.lang.String);
- method public boolean setOperatorBrandOverride(java.lang.String);
field public static final java.lang.String ACTION_PHONE_STATE_CHANGED = "android.intent.action.PHONE_STATE";
field public static final java.lang.String ACTION_RESPOND_VIA_MESSAGE = "android.intent.action.RESPOND_VIA_MESSAGE";
field public static final int CALL_STATE_IDLE = 0; // 0x0
field public static final int CALL_STATE_OFFHOOK = 2; // 0x2
field public static final int CALL_STATE_RINGING = 1; // 0x1
- field public static final int CARRIER_PRIVILEGE_STATUS_ERROR_LOADING_RULES = -2; // 0xfffffffe
- field public static final int CARRIER_PRIVILEGE_STATUS_HAS_ACCESS = 1; // 0x1
- field public static final int CARRIER_PRIVILEGE_STATUS_NO_ACCESS = 0; // 0x0
- field public static final int CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED = -1; // 0xffffffff
field public static final int DATA_ACTIVITY_DORMANT = 4; // 0x4
field public static final int DATA_ACTIVITY_IN = 1; // 0x1
field public static final int DATA_ACTIVITY_INOUT = 3; // 0x3
diff --git a/cmds/bootanimation/BootAnimation.cpp b/cmds/bootanimation/BootAnimation.cpp
index e659b2b..0892311 100644
--- a/cmds/bootanimation/BootAnimation.cpp
+++ b/cmds/bootanimation/BootAnimation.cpp
@@ -397,6 +397,31 @@ void BootAnimation::checkExit() {
}
}
+// Parse a color represented as an HTML-style 'RRGGBB' string: each pair of
+// characters in str is a hex number in [0, 255], which are converted to
+// floating point values in the range [0.0, 1.0] and placed in the
+// corresponding elements of color.
+//
+// If the input string isn't valid, parseColor returns false and color is
+// left unchanged.
+static bool parseColor(const char str[7], float color[3]) {
+ float tmpColor[3];
+ for (int i = 0; i < 3; i++) {
+ int val = 0;
+ for (int j = 0; j < 2; j++) {
+ val *= 16;
+ char c = str[2*i + j];
+ if (c >= '0' && c <= '9') val += c - '0';
+ else if (c >= 'A' && c <= 'F') val += (c - 'A') + 10;
+ else if (c >= 'a' && c <= 'f') val += (c - 'a') + 10;
+ else return false;
+ }
+ tmpColor[i] = static_cast<float>(val) / 255.0f;
+ }
+ memcpy(color, tmpColor, sizeof(tmpColor));
+ return true;
+}
+
bool BootAnimation::movie()
{
ZipEntryRO desc = mZip->findEntryByName("desc.txt");
@@ -427,20 +452,28 @@ bool BootAnimation::movie()
const char* l = line.string();
int fps, width, height, count, pause;
char path[ANIM_ENTRY_NAME_MAX];
+ char color[7] = "000000"; // default to black if unspecified
+
char pathType;
if (sscanf(l, "%d %d %d", &width, &height, &fps) == 3) {
- //LOGD("> w=%d, h=%d, fps=%d", width, height, fps);
+ // ALOGD("> w=%d, h=%d, fps=%d", width, height, fps);
animation.width = width;
animation.height = height;
animation.fps = fps;
}
- else if (sscanf(l, " %c %d %d %s", &pathType, &count, &pause, path) == 4) {
- //LOGD("> type=%c, count=%d, pause=%d, path=%s", pathType, count, pause, path);
+ else if (sscanf(l, " %c %d %d %s #%6s", &pathType, &count, &pause, path, color) >= 4) {
+ // ALOGD("> type=%c, count=%d, pause=%d, path=%s, color=%s", pathType, count, pause, path, color);
Animation::Part part;
part.playUntilComplete = pathType == 'c';
part.count = count;
part.pause = pause;
part.path = path;
+ if (!parseColor(color, part.backgroundColor)) {
+ ALOGE("> invalid color '#%s'", color);
+ part.backgroundColor[0] = 0.0f;
+ part.backgroundColor[1] = 0.0f;
+ part.backgroundColor[2] = 0.0f;
+ }
animation.parts.add(part);
}
@@ -526,6 +559,12 @@ bool BootAnimation::movie()
if(exitPending() && !part.playUntilComplete)
break;
+ glClearColor(
+ part.backgroundColor[0],
+ part.backgroundColor[1],
+ part.backgroundColor[2],
+ 1.0f);
+
for (size_t j=0 ; j<fcount && (!exitPending() || part.playUntilComplete) ; j++) {
const Animation::Frame& frame(part.frames[j]);
nsecs_t lastFrame = systemTime();
diff --git a/cmds/bootanimation/BootAnimation.h b/cmds/bootanimation/BootAnimation.h
index ba1c507..72cd62b 100644
--- a/cmds/bootanimation/BootAnimation.h
+++ b/cmds/bootanimation/BootAnimation.h
@@ -71,6 +71,7 @@ private:
String8 path;
SortedVector<Frame> frames;
bool playUntilComplete;
+ float backgroundColor[3];
};
int fps;
int width;
diff --git a/cmds/media/src/com/android/commands/media/Media.java b/cmds/media/src/com/android/commands/media/Media.java
index b37f896..6a8fb05 100644
--- a/cmds/media/src/com/android/commands/media/Media.java
+++ b/cmds/media/src/com/android/commands/media/Media.java
@@ -204,7 +204,8 @@ public class Media extends BaseCommand {
@Override
public void onQueueChanged(ParceledListSlice queue) throws RemoteException {
- System.out.println("onQueueChanged, size=" + queue.getList().size());
+ System.out.println("onQueueChanged, "
+ + (queue == null ? "null queue" : " size=" + queue.getList().size()));
}
@Override
diff --git a/core/java/android/bluetooth/BluetoothGatt.java b/core/java/android/bluetooth/BluetoothGatt.java
index 2276229..c203a8e 100644
--- a/core/java/android/bluetooth/BluetoothGatt.java
+++ b/core/java/android/bluetooth/BluetoothGatt.java
@@ -51,7 +51,6 @@ public final class BluetoothGatt implements BluetoothProfile {
private int mConnState;
private final Object mStateLock = new Object();
private Boolean mDeviceBusy = false;
- private Boolean mIsCongested = false;
private int mTransport;
private static final int CONN_STATE_IDLE = 0;
@@ -607,21 +606,6 @@ public final class BluetoothGatt implements BluetoothProfile {
Log.w(TAG, "Unhandled exception in callback", ex);
}
}
-
- /**
- * Callback indicating the remote device connection is congested.
- * @hide
- */
- public void onConnectionCongested(String address, boolean congested) {
- if (DBG) Log.d(TAG, "onConnectionCongested() - Device=" + address
- + " congested=" + congested);
- if (!address.equals(mDevice.getAddress())) return;
- try {
- mIsCongested = congested;
- } catch (Exception ex) {
- Log.w(TAG, "Unhandled exception in callback", ex);
- }
- }
};
/*package*/ BluetoothGatt(Context context, IBluetoothGatt iGatt, BluetoothDevice device,
diff --git a/core/java/android/bluetooth/BluetoothGattCallbackWrapper.java b/core/java/android/bluetooth/BluetoothGattCallbackWrapper.java
index da992f5..cdb24f4 100644
--- a/core/java/android/bluetooth/BluetoothGattCallbackWrapper.java
+++ b/core/java/android/bluetooth/BluetoothGattCallbackWrapper.java
@@ -120,10 +120,6 @@ public class BluetoothGattCallbackWrapper extends IBluetoothGattCallback.Stub {
}
@Override
- public void onConnectionCongested(String address, boolean congested) throws RemoteException {
- }
-
- @Override
public void onFoundOrLost(boolean onFound, ScanResult scanResult) throws RemoteException {
}
diff --git a/core/java/android/bluetooth/BluetoothGattServer.java b/core/java/android/bluetooth/BluetoothGattServer.java
index a7f117b..e94a8ce 100644
--- a/core/java/android/bluetooth/BluetoothGattServer.java
+++ b/core/java/android/bluetooth/BluetoothGattServer.java
@@ -48,7 +48,6 @@ public final class BluetoothGattServer implements BluetoothProfile {
private BluetoothAdapter mAdapter;
private IBluetoothGatt mService;
private BluetoothGattServerCallback mCallback;
- private Boolean mIsCongested = false;
private Object mServerIfLock = new Object();
private int mServerIf;
@@ -285,24 +284,6 @@ public final class BluetoothGattServer implements BluetoothProfile {
Log.w(TAG, "Unhandled exception: " + ex);
}
}
-
- /**
- * Callback indicating the remote device connection is congested.
- * @hide
- */
- public void onConnectionCongested(String address, boolean congested) {
- if (DBG) Log.d(TAG, "onConnectionCongested() - Device=" + address
- + " congested=" + congested);
-
- BluetoothDevice device = mAdapter.getRemoteDevice(address);
- if (device == null) return;
-
- try {
- mIsCongested = congested;
- } catch (Exception ex) {
- Log.w(TAG, "Unhandled exception in callback", ex);
- }
- }
};
/**
diff --git a/core/java/android/bluetooth/IBluetoothGattCallback.aidl b/core/java/android/bluetooth/IBluetoothGattCallback.aidl
index 00b6b1b..91e62ea 100644
--- a/core/java/android/bluetooth/IBluetoothGattCallback.aidl
+++ b/core/java/android/bluetooth/IBluetoothGattCallback.aidl
@@ -68,6 +68,5 @@ oneway interface IBluetoothGattCallback {
void onMultiAdvertiseCallback(in int status, boolean isStart,
in AdvertiseSettings advertiseSettings);
void onConfigureMTU(in String address, in int mtu, in int status);
- void onConnectionCongested(in String address, in boolean congested);
void onFoundOrLost(in boolean onFound, in ScanResult scanResult);
}
diff --git a/core/java/android/bluetooth/IBluetoothGattServerCallback.aidl b/core/java/android/bluetooth/IBluetoothGattServerCallback.aidl
index 6e31da1..5d4d6c6 100644
--- a/core/java/android/bluetooth/IBluetoothGattServerCallback.aidl
+++ b/core/java/android/bluetooth/IBluetoothGattServerCallback.aidl
@@ -59,5 +59,4 @@ oneway interface IBluetoothGattServerCallback {
in byte[] value);
void onExecuteWrite(in String address, in int transId, in boolean execWrite);
void onNotificationSent(in String address, in int status);
- void onConnectionCongested(in String address, in boolean congested);
}
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 702ac6b..77981f4 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -2723,6 +2723,9 @@ public class Intent implements Parcelable, Cloneable {
public static final String
ACTION_OPEN_DOCUMENT_TREE = "android.intent.action.OPEN_DOCUMENT_TREE";
+ /** {@hide} */
+ public static final String ACTION_MASTER_CLEAR = "android.intent.action.MASTER_CLEAR";
+
// ---------------------------------------------------------------------
// ---------------------------------------------------------------------
// Standard intent categories (see addCategory()).
@@ -3425,6 +3428,9 @@ public class Intent implements Parcelable, Cloneable {
public static final String EXTRA_TIME_PREF_24_HOUR_FORMAT =
"android.intent.extra.TIME_PREF_24_HOUR_FORMAT";
+ /** {@hide} */
+ public static final String EXTRA_REASON = "android.intent.extra.REASON";
+
// ---------------------------------------------------------------------
// ---------------------------------------------------------------------
// Intent flags (see mFlags variable).
diff --git a/core/java/android/hardware/camera2/legacy/BurstHolder.java b/core/java/android/hardware/camera2/legacy/BurstHolder.java
index c141c51..b9c89f8 100644
--- a/core/java/android/hardware/camera2/legacy/BurstHolder.java
+++ b/core/java/android/hardware/camera2/legacy/BurstHolder.java
@@ -22,6 +22,7 @@ import android.util.Log;
import android.view.Surface;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.List;
/**
@@ -38,14 +39,16 @@ public class BurstHolder {
*
* @param requestId id of the burst request.
* @param repeating true if this burst is repeating.
- * @param requests a {@link java.util.List} of {@link CaptureRequest}s in this burst.
+ * @param requests a {@link List} of {@link CaptureRequest}s in this burst.
+ * @param jpegSurfaceIds a {@link Collection} of IDs for the surfaces that have jpeg outputs.
*/
- public BurstHolder(int requestId, boolean repeating, List<CaptureRequest> requests) {
- mRequestBuilders = new ArrayList<RequestHolder.Builder>();
+ public BurstHolder(int requestId, boolean repeating, List<CaptureRequest> requests,
+ Collection<Long> jpegSurfaceIds) {
+ mRequestBuilders = new ArrayList<>();
int i = 0;
for (CaptureRequest r : requests) {
mRequestBuilders.add(new RequestHolder.Builder(requestId, /*subsequenceId*/i,
- /*request*/r, repeating));
+ /*request*/r, repeating, jpegSurfaceIds));
++i;
}
mRepeating = repeating;
diff --git a/core/java/android/hardware/camera2/legacy/CameraDeviceUserShim.java b/core/java/android/hardware/camera2/legacy/CameraDeviceUserShim.java
index e19f587..fcf172c 100644
--- a/core/java/android/hardware/camera2/legacy/CameraDeviceUserShim.java
+++ b/core/java/android/hardware/camera2/legacy/CameraDeviceUserShim.java
@@ -336,8 +336,16 @@ public class CameraDeviceUserShim implements ICameraDeviceUser {
CameraInfo info = new CameraInfo();
Camera.getCameraInfo(cameraId, info);
+ Camera.Parameters legacyParameters = null;
+ try {
+ legacyParameters = legacyCamera.getParameters();
+ } catch (RuntimeException e) {
+ throw new CameraRuntimeException(CameraAccessException.CAMERA_ERROR,
+ "Unable to get initial parameters", e);
+ }
+
CameraCharacteristics characteristics =
- LegacyMetadataMapper.createCharacteristics(legacyCamera.getParameters(), info);
+ LegacyMetadataMapper.createCharacteristics(legacyParameters, info);
LegacyCameraDevice device = new LegacyCameraDevice(
cameraId, legacyCamera, characteristics, threadCallbacks);
return new CameraDeviceUserShim(cameraId, device, characteristics, init, threadCallbacks);
diff --git a/core/java/android/hardware/camera2/legacy/LegacyCameraDevice.java b/core/java/android/hardware/camera2/legacy/LegacyCameraDevice.java
index a724b41..4587c6f 100644
--- a/core/java/android/hardware/camera2/legacy/LegacyCameraDevice.java
+++ b/core/java/android/hardware/camera2/legacy/LegacyCameraDevice.java
@@ -522,7 +522,7 @@ public class LegacyCameraDevice implements AutoCloseable {
return surfaceIds;
}
- static boolean containsSurfaceId(Surface s, List<Long> ids) {
+ static boolean containsSurfaceId(Surface s, Collection<Long> ids) {
long id = getSurfaceId(s);
return ids.contains(id);
}
diff --git a/core/java/android/hardware/camera2/legacy/RequestHolder.java b/core/java/android/hardware/camera2/legacy/RequestHolder.java
index 69c140b..edd8e4e 100644
--- a/core/java/android/hardware/camera2/legacy/RequestHolder.java
+++ b/core/java/android/hardware/camera2/legacy/RequestHolder.java
@@ -43,71 +43,6 @@ public class RequestHolder {
private volatile boolean mFailed = false;
/**
- * Returns true if the given surface requires jpeg buffers.
- *
- * @param s a {@link android.view.Surface} to check.
- * @return true if the surface requires a jpeg buffer.
- */
- public static boolean jpegType(Surface s)
- throws LegacyExceptionUtils.BufferQueueAbandonedException {
- return LegacyCameraDevice.detectSurfaceType(s) ==
- CameraMetadataNative.NATIVE_JPEG_FORMAT;
- }
-
- /**
- * Returns true if the given surface requires non-jpeg buffer types.
- *
- * <p>
- * "Jpeg buffer" refers to the buffers returned in the jpeg
- * {@link android.hardware.Camera.PictureCallback}. Non-jpeg buffers are created using a tee
- * of the preview stream drawn to the surface
- * set via {@link android.hardware.Camera#setPreviewDisplay(android.view.SurfaceHolder)} or
- * equivalent methods.
- * </p>
- * @param s a {@link android.view.Surface} to check.
- * @return true if the surface requires a non-jpeg buffer type.
- */
- public static boolean previewType(Surface s)
- throws LegacyExceptionUtils.BufferQueueAbandonedException {
- return LegacyCameraDevice.detectSurfaceType(s) !=
- CameraMetadataNative.NATIVE_JPEG_FORMAT;
- }
-
- /**
- * Returns the number of surfaces targeted by the request that require jpeg buffers.
- */
- private static int numJpegTargets(CaptureRequest request) {
- int count = 0;
- for (Surface s : request.getTargets()) {
- try {
- if (jpegType(s)) {
- ++count;
- }
- } catch (LegacyExceptionUtils.BufferQueueAbandonedException e) {
- Log.w(TAG, "Surface abandoned, skipping...", e);
- }
- }
- return count;
- }
-
- /**
- * Returns the number of surfaces targeted by the request that require non-jpeg buffers.
- */
- private static int numPreviewTargets(CaptureRequest request) {
- int count = 0;
- for (Surface s : request.getTargets()) {
- try {
- if (previewType(s)) {
- ++count;
- }
- } catch (LegacyExceptionUtils.BufferQueueAbandonedException e) {
- Log.w(TAG, "Surface abandoned, skipping...", e);
- }
- }
- return count;
- }
-
- /**
* A builder class for {@link RequestHolder} objects.
*
* <p>
@@ -121,6 +56,7 @@ public class RequestHolder {
private final boolean mRepeating;
private final int mNumJpegTargets;
private final int mNumPreviewTargets;
+ private final Collection<Long> mJpegSurfaceIds;
/**
* Construct a new {@link Builder} to generate {@link RequestHolder} objects.
@@ -132,17 +68,81 @@ public class RequestHolder {
* @param repeating {@code true} if the request is repeating.
*/
public Builder(int requestId, int subsequenceId, CaptureRequest request,
- boolean repeating) {
+ boolean repeating, Collection<Long> jpegSurfaceIds) {
checkNotNull(request, "request must not be null");
mRequestId = requestId;
mSubsequenceId = subsequenceId;
mRequest = request;
mRepeating = repeating;
+ mJpegSurfaceIds = jpegSurfaceIds;
mNumJpegTargets = numJpegTargets(mRequest);
mNumPreviewTargets = numPreviewTargets(mRequest);
}
/**
+ * Returns true if the given surface requires jpeg buffers.
+ *
+ * @param s a {@link android.view.Surface} to check.
+ * @return true if the surface requires a jpeg buffer.
+ */
+ private boolean jpegType(Surface s)
+ throws LegacyExceptionUtils.BufferQueueAbandonedException {
+ return LegacyCameraDevice.containsSurfaceId(s, mJpegSurfaceIds);
+ }
+
+ /**
+ * Returns true if the given surface requires non-jpeg buffer types.
+ *
+ * <p>
+ * "Jpeg buffer" refers to the buffers returned in the jpeg
+ * {@link android.hardware.Camera.PictureCallback}. Non-jpeg buffers are created using a tee
+ * of the preview stream drawn to the surface
+ * set via {@link android.hardware.Camera#setPreviewDisplay(android.view.SurfaceHolder)} or
+ * equivalent methods.
+ * </p>
+ * @param s a {@link android.view.Surface} to check.
+ * @return true if the surface requires a non-jpeg buffer type.
+ */
+ private boolean previewType(Surface s)
+ throws LegacyExceptionUtils.BufferQueueAbandonedException {
+ return !jpegType(s);
+ }
+
+ /**
+ * Returns the number of surfaces targeted by the request that require jpeg buffers.
+ */
+ private int numJpegTargets(CaptureRequest request) {
+ int count = 0;
+ for (Surface s : request.getTargets()) {
+ try {
+ if (jpegType(s)) {
+ ++count;
+ }
+ } catch (LegacyExceptionUtils.BufferQueueAbandonedException e) {
+ Log.d(TAG, "Surface abandoned, skipping...", e);
+ }
+ }
+ return count;
+ }
+
+ /**
+ * Returns the number of surfaces targeted by the request that require non-jpeg buffers.
+ */
+ private int numPreviewTargets(CaptureRequest request) {
+ int count = 0;
+ for (Surface s : request.getTargets()) {
+ try {
+ if (previewType(s)) {
+ ++count;
+ }
+ } catch (LegacyExceptionUtils.BufferQueueAbandonedException e) {
+ Log.d(TAG, "Surface abandoned, skipping...", e);
+ }
+ }
+ return count;
+ }
+
+ /**
* Build a new {@link RequestHolder} using with parameters generated from this
* {@link Builder}.
*
diff --git a/core/java/android/hardware/camera2/legacy/RequestQueue.java b/core/java/android/hardware/camera2/legacy/RequestQueue.java
index 7598f99..c995029 100644
--- a/core/java/android/hardware/camera2/legacy/RequestQueue.java
+++ b/core/java/android/hardware/camera2/legacy/RequestQueue.java
@@ -39,8 +39,11 @@ public class RequestQueue {
private long mCurrentFrameNumber = 0;
private long mCurrentRepeatingFrameNumber = INVALID_FRAME;
private int mCurrentRequestId = 0;
+ private final List<Long> mJpegSurfaceIds;
- public RequestQueue() {}
+ public RequestQueue(List<Long> jpegSurfaceIds) {
+ mJpegSurfaceIds = jpegSurfaceIds;
+ }
/**
* Return and remove the next burst on the queue.
@@ -117,7 +120,7 @@ public class RequestQueue {
public synchronized int submit(List<CaptureRequest> requests, boolean repeating,
/*out*/LongParcelable frameNumber) {
int requestId = mCurrentRequestId++;
- BurstHolder burst = new BurstHolder(requestId, repeating, requests);
+ BurstHolder burst = new BurstHolder(requestId, repeating, requests, mJpegSurfaceIds);
long ret = INVALID_FRAME;
if (burst.isRepeating()) {
Log.i(TAG, "Repeating capture request set.");
diff --git a/core/java/android/hardware/camera2/legacy/RequestThreadManager.java b/core/java/android/hardware/camera2/legacy/RequestThreadManager.java
index 4f8fe0b..a7ea89c 100644
--- a/core/java/android/hardware/camera2/legacy/RequestThreadManager.java
+++ b/core/java/android/hardware/camera2/legacy/RequestThreadManager.java
@@ -91,9 +91,11 @@ public class RequestThreadManager {
private SurfaceTexture mPreviewTexture;
private Camera.Parameters mParams;
+ private final List<Long> mJpegSurfaceIds = new ArrayList<>();
+
private Size mIntermediateBufferSize;
- private final RequestQueue mRequestQueue = new RequestQueue();
+ private final RequestQueue mRequestQueue = new RequestQueue(mJpegSurfaceIds);
private LegacyRequest mLastRequest = null;
private SurfaceTexture mDummyTexture;
private Surface mDummySurface;
@@ -102,6 +104,10 @@ public class RequestThreadManager {
private final FpsCounter mPrevCounter = new FpsCounter("Incoming Preview");
private final FpsCounter mRequestCounter = new FpsCounter("Incoming Requests");
+ // Stuff JPEGs into HAL_PIXEL_FORMAT_RGBA_8888 gralloc buffers to get around SW write
+ // limitations for (b/17379185).
+ private static final boolean USE_BLOB_FORMAT_OVERRIDE = true;
+
/**
* Container object for Configure messages.
*/
@@ -189,18 +195,21 @@ public class RequestThreadManager {
public void onPictureTaken(byte[] data, Camera camera) {
Log.i(TAG, "Received jpeg.");
Pair<RequestHolder, Long> captureInfo = mCaptureCollector.jpegProduced();
- RequestHolder holder = captureInfo.first;
- long timestamp = captureInfo.second;
- if (holder == null) {
+ if (captureInfo == null || captureInfo.first == null) {
Log.e(TAG, "Dropping jpeg frame.");
return;
}
+ RequestHolder holder = captureInfo.first;
+ long timestamp = captureInfo.second;
for (Surface s : holder.getHolderTargets()) {
try {
- if (RequestHolder.jpegType(s)) {
+ if (LegacyCameraDevice.containsSurfaceId(s, mJpegSurfaceIds)) {
Log.i(TAG, "Producing jpeg buffer...");
- LegacyCameraDevice.setSurfaceDimens(s, data.length +
- LegacyCameraDevice.nativeGetJpegFooterSize(), /*height*/1);
+
+ int totalSize = data.length + LegacyCameraDevice.nativeGetJpegFooterSize();
+ totalSize += ((totalSize - 1) & ~0x3) + 4; // align to next octonibble
+
+ LegacyCameraDevice.setSurfaceDimens(s, totalSize, /*height*/1);
LegacyCameraDevice.setNextTimestamp(s, timestamp);
LegacyCameraDevice.produceFrame(s, data, data.length, /*height*/1,
CameraMetadataNative.NATIVE_JPEG_FORMAT);
@@ -316,8 +325,10 @@ public class RequestThreadManager {
mGLThreadManager.ignoreNewFrames();
mGLThreadManager.waitUntilIdle();
}
+ resetJpegSurfaceFormats(mCallbackOutputs);
mPreviewOutputs.clear();
mCallbackOutputs.clear();
+ mJpegSurfaceIds.clear();
mPreviewTexture = null;
int facing = mCharacteristics.get(CameraCharacteristics.LENS_FACING);
@@ -329,6 +340,12 @@ public class RequestThreadManager {
LegacyCameraDevice.setSurfaceOrientation(s, facing, orientation);
switch (format) {
case CameraMetadataNative.NATIVE_JPEG_FORMAT:
+ if (USE_BLOB_FORMAT_OVERRIDE) {
+ // Override to RGBA_8888 format.
+ LegacyCameraDevice.setSurfaceFormat(s,
+ LegacyMetadataMapper.HAL_PIXEL_FORMAT_RGBA_8888);
+ }
+ mJpegSurfaceIds.add(LegacyCameraDevice.getSurfaceId(s));
mCallbackOutputs.add(s);
break;
default:
@@ -340,7 +357,14 @@ public class RequestThreadManager {
}
}
}
- mParams = mCamera.getParameters();
+ try {
+ mParams = mCamera.getParameters();
+ } catch (RuntimeException e) {
+ Log.e(TAG, "Received device exception: ", e);
+ mDeviceState.setError(
+ CameraDeviceImpl.CameraDeviceCallbacks.ERROR_CAMERA_DEVICE);
+ return;
+ }
List<int[]> supportedFpsRanges = mParams.getSupportedPreviewFpsRange();
int[] bestRange = getPhotoPreviewFpsRange(supportedFpsRanges);
@@ -426,8 +450,19 @@ public class RequestThreadManager {
}
mCamera.setParameters(mParams);
- // TODO: configure the JPEG surface with some arbitrary size
- // using LegacyCameraDevice.nativeConfigureSurface
+ }
+
+ private void resetJpegSurfaceFormats(Collection<Surface> surfaces) {
+ if (!USE_BLOB_FORMAT_OVERRIDE || surfaces == null) {
+ return;
+ }
+ for(Surface s : surfaces) {
+ try {
+ LegacyCameraDevice.setSurfaceFormat(s, LegacyMetadataMapper.HAL_PIXEL_FORMAT_BLOB);
+ } catch (LegacyExceptionUtils.BufferQueueAbandonedException e) {
+ Log.w(TAG, "Surface abandoned, skipping...", e);
+ }
+ }
}
/**
@@ -459,9 +494,8 @@ public class RequestThreadManager {
List<Size> configuredJpegSizes = new ArrayList<Size>();
for (Surface callbackSurface : callbackOutputs) {
try {
- int format = LegacyCameraDevice.detectSurfaceType(callbackSurface);
- if (format != CameraMetadataNative.NATIVE_JPEG_FORMAT) {
+ if (!LegacyCameraDevice.containsSurfaceId(callbackSurface, mJpegSurfaceIds)) {
continue; // Ignore non-JPEG callback formats
}
@@ -754,7 +788,14 @@ public class RequestThreadManager {
if (DEBUG) {
Log.d(TAG, "Params changed -- getting new Parameters from HAL.");
}
- mParams = mCamera.getParameters();
+ try {
+ mParams = mCamera.getParameters();
+ } catch (RuntimeException e) {
+ Log.e(TAG, "Received device exception: ", e);
+ mDeviceState.setError(
+ CameraDeviceImpl.CameraDeviceCallbacks.ERROR_CAMERA_DEVICE);
+ break;
+ }
// Update parameters to the latest that we think the camera is using
mLastRequest.setParameters(mParams);
@@ -821,6 +862,7 @@ public class RequestThreadManager {
if (mCamera != null) {
mCamera.release();
}
+ resetJpegSurfaceFormats(mCallbackOutputs);
break;
default:
throw new AssertionError("Unhandled message " + msg.what +
diff --git a/core/java/android/hardware/camera2/legacy/SurfaceTextureRenderer.java b/core/java/android/hardware/camera2/legacy/SurfaceTextureRenderer.java
index c018c3e..c0d1d5e 100644
--- a/core/java/android/hardware/camera2/legacy/SurfaceTextureRenderer.java
+++ b/core/java/android/hardware/camera2/legacy/SurfaceTextureRenderer.java
@@ -581,6 +581,7 @@ public class SurfaceTextureRenderer {
// If pixel conversions aren't handled by egl, use a pbuffer
try {
if (LegacyCameraDevice.needsConversion(s)) {
+ // Always override to YV12 output for YUV surface formats.
LegacyCameraDevice.setSurfaceFormat(s, ImageFormat.YV12);
EGLSurfaceHolder holder = new EGLSurfaceHolder();
holder.surface = s;
diff --git a/core/java/android/os/Binder.java b/core/java/android/os/Binder.java
index ba71605..362afba 100644
--- a/core/java/android/os/Binder.java
+++ b/core/java/android/os/Binder.java
@@ -17,6 +17,7 @@
package android.os;
import android.util.Log;
+import android.util.Slog;
import com.android.internal.util.FastPrintWriter;
import java.io.FileDescriptor;
@@ -48,7 +49,7 @@ public class Binder implements IBinder {
* of classes can potentially create leaks.
*/
private static final boolean FIND_POTENTIAL_LEAKS = false;
- private static final String TAG = "Binder";
+ static final String TAG = "Binder";
/**
* Control whether dump() calls are allowed.
@@ -385,7 +386,14 @@ public class Binder implements IBinder {
super.finalize();
}
}
-
+
+ static void checkParcel(Parcel parcel, String msg) {
+ if (parcel.dataSize() >= 800*1024) {
+ // Trying to send > 800k, this is way too much
+ Slog.wtfStack(TAG, msg + parcel.dataSize());
+ }
+ }
+
private native final void init();
private native final void destroy();
@@ -424,6 +432,7 @@ public class Binder implements IBinder {
reply.writeException(re);
res = true;
}
+ checkParcel(reply, "Unreasonably large binder reply buffer: ");
reply.recycle();
data.recycle();
return res;
@@ -433,13 +442,18 @@ public class Binder implements IBinder {
final class BinderProxy implements IBinder {
public native boolean pingBinder();
public native boolean isBinderAlive();
-
+
public IInterface queryLocalInterface(String descriptor) {
return null;
}
-
+
+ public boolean transact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {
+ Binder.checkParcel(data, "Unreasonably large binder buffer: ");
+ return transactNative(code, data, reply, flags);
+ }
+
public native String getInterfaceDescriptor() throws RemoteException;
- public native boolean transact(int code, Parcel data, Parcel reply,
+ public native boolean transactNative(int code, Parcel data, Parcel reply,
int flags) throws RemoteException;
public native void linkToDeath(DeathRecipient recipient, int flags)
throws RemoteException;
diff --git a/core/java/android/os/RecoverySystem.java b/core/java/android/os/RecoverySystem.java
index 7a46e40..b879c83 100644
--- a/core/java/android/os/RecoverySystem.java
+++ b/core/java/android/os/RecoverySystem.java
@@ -20,6 +20,7 @@ import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.UserManager;
+import android.text.TextUtils;
import android.util.Log;
import java.io.ByteArrayInputStream;
@@ -333,9 +334,10 @@ public class RecoverySystem {
throws IOException {
String filename = packageFile.getCanonicalPath();
Log.w(TAG, "!!! REBOOTING TO INSTALL " + filename + " !!!");
- String arg = "--update_package=" + filename +
- "\n--locale=" + Locale.getDefault().toString();
- bootCommand(context, arg);
+
+ final String filenameArg = "--update_package=" + filename;
+ final String localeArg = "--locale=" + Locale.getDefault().toString();
+ bootCommand(context, filenameArg, localeArg);
}
/**
@@ -352,7 +354,18 @@ public class RecoverySystem {
* @throws SecurityException if the current user is not allowed to wipe data.
*/
public static void rebootWipeUserData(Context context) throws IOException {
- rebootWipeUserData(context, false);
+ rebootWipeUserData(context, false, context.getPackageName());
+ }
+
+ /** {@hide} */
+ public static void rebootWipeUserData(Context context, String reason) throws IOException {
+ rebootWipeUserData(context, false, reason);
+ }
+
+ /** {@hide} */
+ public static void rebootWipeUserData(Context context, boolean shutdown)
+ throws IOException {
+ rebootWipeUserData(context, shutdown, context.getPackageName());
}
/**
@@ -373,8 +386,8 @@ public class RecoverySystem {
*
* @hide
*/
- public static void rebootWipeUserData(Context context, boolean shutdown)
- throws IOException {
+ public static void rebootWipeUserData(Context context, boolean shutdown, String reason)
+ throws IOException {
UserManager um = (UserManager) context.getSystemService(Context.USER_SERVICE);
if (um.hasUserRestriction(UserManager.DISALLOW_FACTORY_RESET)) {
throw new SecurityException("Wiping data is not allowed for this user.");
@@ -395,13 +408,18 @@ public class RecoverySystem {
// Block until the ordered broadcast has completed.
condition.block();
- String shutdownArg = "";
+ String shutdownArg = null;
if (shutdown) {
- shutdownArg = "--shutdown_after\n";
+ shutdownArg = "--shutdown_after";
+ }
+
+ String reasonArg = null;
+ if (!TextUtils.isEmpty(reason)) {
+ reasonArg = "--reason=" + sanitizeArg(reason);
}
- bootCommand(context, shutdownArg + "--wipe_data\n--locale=" +
- Locale.getDefault().toString());
+ final String localeArg = "--locale=" + Locale.getDefault().toString();
+ bootCommand(context, shutdownArg, "--wipe_data", reasonArg, localeArg);
}
/**
@@ -409,23 +427,38 @@ public class RecoverySystem {
* @throws IOException if something goes wrong.
*/
public static void rebootWipeCache(Context context) throws IOException {
- bootCommand(context, "--wipe_cache\n--locale=" + Locale.getDefault().toString());
+ rebootWipeCache(context, context.getPackageName());
+ }
+
+ /** {@hide} */
+ public static void rebootWipeCache(Context context, String reason) throws IOException {
+ String reasonArg = null;
+ if (!TextUtils.isEmpty(reason)) {
+ reasonArg = "--reason=" + sanitizeArg(reason);
+ }
+
+ final String localeArg = "--locale=" + Locale.getDefault().toString();
+ bootCommand(context, "--wipe_cache", reasonArg, localeArg);
}
/**
* Reboot into the recovery system with the supplied argument.
- * @param arg to pass to the recovery utility.
+ * @param args to pass to the recovery utility.
* @throws IOException if something goes wrong.
*/
- private static void bootCommand(Context context, String arg) throws IOException {
+ private static void bootCommand(Context context, String... args) throws IOException {
RECOVERY_DIR.mkdirs(); // In case we need it
COMMAND_FILE.delete(); // In case it's not writable
LOG_FILE.delete();
FileWriter command = new FileWriter(COMMAND_FILE);
try {
- command.write(arg);
- command.write("\n");
+ for (String arg : args) {
+ if (!TextUtils.isEmpty(arg)) {
+ command.write(arg);
+ command.write("\n");
+ }
+ }
} finally {
command.close();
}
@@ -470,5 +503,15 @@ public class RecoverySystem {
return log;
}
+ /**
+ * Internally, recovery treats each line of the command file as a separate
+ * argv, so we only need to protect against newlines and nulls.
+ */
+ private static String sanitizeArg(String arg) {
+ arg = arg.replace('\0', '?');
+ arg = arg.replace('\n', '?');
+ return arg;
+ }
+
private void RecoverySystem() { } // Do not instantiate
}
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 440b1ec..ec4a53e 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -978,6 +978,19 @@ public final class Settings {
public static final String EXTRA_INPUT_METHOD_ID = "input_method_id";
/**
+ * Activity Extra: The device identifier to act upon.
+ * <p>
+ * This can be passed as an extra field in an Activity Intent with a single
+ * InputDeviceIdentifier. This field is used by some activities to jump straight into the
+ * settings for the given device.
+ * <p>
+ * Example: The {@link #INPUT_METHOD_SETTINGS} intent opens the keyboard layout dialog for the
+ * given device.
+ * @hide
+ */
+ public static final String EXTRA_INPUT_DEVICE_IDENTIFIER = "input_device_identifier";
+
+ /**
* @hide
* Activity Extra: Enable or disable Airplane Mode.
* <p>
diff --git a/core/java/android/service/notification/NotificationListenerService.java b/core/java/android/service/notification/NotificationListenerService.java
index b22fd9c..35fff74 100644
--- a/core/java/android/service/notification/NotificationListenerService.java
+++ b/core/java/android/service/notification/NotificationListenerService.java
@@ -478,7 +478,7 @@ public abstract class NotificationListenerService extends Service {
public final int getCurrentInterruptionFilter() {
if (!isBound()) return 0;
try {
- return getNotificationInterface().getHintsFromListener(mWrapper);
+ return getNotificationInterface().getInterruptionFilterFromListener(mWrapper);
} catch (android.os.RemoteException ex) {
Log.v(TAG, "Unable to contact notification manager", ex);
return 0;
diff --git a/core/java/android/speech/tts/SynthesisRequest.java b/core/java/android/speech/tts/SynthesisRequest.java
index d41aa67..6262fcb 100644
--- a/core/java/android/speech/tts/SynthesisRequest.java
+++ b/core/java/android/speech/tts/SynthesisRequest.java
@@ -61,7 +61,7 @@ public final class SynthesisRequest {
/**
* Gets the text which should be synthesized.
- * @deprecated As of API level 20, replaced by {@link #getCharSequenceText}.
+ * @deprecated As of API level 21, replaced by {@link #getCharSequenceText}.
*/
@Deprecated
public String getText() {
diff --git a/core/java/android/speech/tts/TextToSpeech.java b/core/java/android/speech/tts/TextToSpeech.java
index 120c9e3..c59ca8a 100644
--- a/core/java/android/speech/tts/TextToSpeech.java
+++ b/core/java/android/speech/tts/TextToSpeech.java
@@ -575,7 +575,7 @@ public class TextToSpeech {
* @see TextToSpeech#synthesizeToFile(String, java.util.HashMap, String)
* @see TextToSpeech#getFeatures(java.util.Locale)
*
- * @deprecated Starting from API level 20, to select network synthesis, call
+ * @deprecated Starting from API level 21, to select network synthesis, call
* ({@link TextToSpeech#getVoices()}, find a suitable network voice
* ({@link Voice#isNetworkConnectionRequired()}) and pass it
* to {@link TextToSpeech#setVoice(Voice)}).
@@ -593,7 +593,7 @@ public class TextToSpeech {
* @see TextToSpeech#synthesizeToFile(String, java.util.HashMap, String)
* @see TextToSpeech#getFeatures(java.util.Locale)
- * @deprecated Starting from API level 20, to select embedded synthesis, call
+ * @deprecated Starting from API level 21, to select embedded synthesis, call
* ({@link TextToSpeech#getVoices()}, find a suitable embedded voice
* ({@link Voice#isNetworkConnectionRequired()}) and pass it
* to {@link TextToSpeech#setVoice(Voice)}).
@@ -1015,7 +1015,7 @@ public class TextToSpeech {
*
* @return Code indicating success or failure. See {@link #ERROR} and {@link #SUCCESS}.
*
- * @deprecated As of API level 20, replaced by
+ * @deprecated As of API level 21, replaced by
* {@link #addEarcon(String, File)}.
*/
@Deprecated
@@ -1124,7 +1124,7 @@ public class TextToSpeech {
* engine named "com.svox.pico" if it is being used.
*
* @return {@link #ERROR} or {@link #SUCCESS} of <b>queuing</b> the speak operation.
- * @deprecated As of API level 20, replaced by
+ * @deprecated As of API level 21, replaced by
* {@link #speak(CharSequence, int, Bundle, String)}.
*/
@Deprecated
@@ -1194,7 +1194,7 @@ public class TextToSpeech {
* engine named "com.svox.pico" if it is being used.
*
* @return {@link #ERROR} or {@link #SUCCESS} of <b>queuing</b> the playEarcon operation.
- * @deprecated As of API level 20, replaced by
+ * @deprecated As of API level 21, replaced by
* {@link #playEarcon(String, int, Bundle, String)}.
*/
@Deprecated
@@ -1218,9 +1218,9 @@ public class TextToSpeech {
* @param queueMode {@link #QUEUE_ADD} or {@link #QUEUE_FLUSH}.
* @param utteranceId An unique identifier for this request.
*
- * @return {@link #ERROR} or {@link #SUCCESS} of <b>queuing</b> the playSilence operation.
+ * @return {@link #ERROR} or {@link #SUCCESS} of <b>queuing</b> the playSilentUtterance operation.
*/
- public int playSilence(final long durationInMs, final int queueMode,
+ public int playSilentUtterance(final long durationInMs, final int queueMode,
final String utteranceId) {
return runAction(new Action<Integer>() {
@Override
@@ -1228,7 +1228,7 @@ public class TextToSpeech {
return service.playSilence(getCallerIdentity(), durationInMs,
queueMode, utteranceId);
}
- }, ERROR, "playSilence");
+ }, ERROR, "playSilentUtterance");
}
/**
@@ -1252,13 +1252,13 @@ public class TextToSpeech {
* engine named "com.svox.pico" if it is being used.
*
* @return {@link #ERROR} or {@link #SUCCESS} of <b>queuing</b> the playSilence operation.
- * @deprecated As of API level 20, replaced by
- * {@link #playSilence(long, int, String)}.
+ * @deprecated As of API level 21, replaced by
+ * {@link #playSilentUtterance(long, int, String)}.
*/
@Deprecated
public int playSilence(final long durationInMs, final int queueMode,
final HashMap<String, String> params) {
- return playSilence(durationInMs, queueMode,
+ return playSilentUtterance(durationInMs, queueMode,
params == null ? null : params.get(Engine.KEY_PARAM_UTTERANCE_ID));
}
@@ -1276,7 +1276,7 @@ public class TextToSpeech {
*
* @param locale The locale to query features for.
* @return Set instance. May return {@code null} on error.
- * @deprecated As of API level 20, please use voices. In order to query features of the voice,
+ * @deprecated As of API level 21, please use voices. In order to query features of the voice,
* call {@link #getVoices()} to retrieve the list of available voices and
* {@link Voice#getFeatures()} to retrieve the set of features.
*/
@@ -1421,7 +1421,7 @@ public class TextToSpeech {
*
* @return language, country (if any) and variant (if any) used by the client stored in a
* Locale instance, or {@code null} on error.
- * @deprecated As of API Level 20, use <code>getDefaultVoice().getLocale()</code> ({@link
+ * @deprecated As of API level 21, use <code>getDefaultVoice().getLocale()</code> ({@link
* #getDefaultVoice()})
*/
@Deprecated
@@ -1476,7 +1476,7 @@ public class TextToSpeech {
String variant = loc.getVariant();
- // As of API level 20, setLanguage is implemented using setVoice.
+ // As of API level 21, setLanguage is implemented using setVoice.
// (which, in the default implementation, will call loadLanguage on the service
// interface).
@@ -1535,7 +1535,7 @@ public class TextToSpeech {
* @return language, country (if any) and variant (if any) used by the client stored in a
* Locale instance, or {@code null} on error.
*
- * @deprecated As of API level 20, please use <code>getVoice().getLocale()</code>
+ * @deprecated As of API level 21, please use <code>getVoice().getLocale()</code>
* ({@link #getVoice()}).
*/
@Deprecated
@@ -1831,7 +1831,7 @@ public class TextToSpeech {
* something like "/sdcard/myappsounds/mysound.wav".
*
* @return {@link #ERROR} or {@link #SUCCESS} of <b>queuing</b> the synthesizeToFile operation.
- * @deprecated As of API level 20, replaced by
+ * @deprecated As of API level 21, replaced by
* {@link #synthesizeToFile(CharSequence, Bundle, File, String)}.
*/
@Deprecated
diff --git a/core/java/android/speech/tts/TextToSpeechService.java b/core/java/android/speech/tts/TextToSpeechService.java
index 079467a..9bb7f02 100644
--- a/core/java/android/speech/tts/TextToSpeechService.java
+++ b/core/java/android/speech/tts/TextToSpeechService.java
@@ -91,7 +91,7 @@ import java.util.Set;
* The first three methods are siblings of the {@link #onGetLanguage},
* {@link #onIsLanguageAvailable} and {@link #onLoadLanguage} methods. The last one,
* {@link #onGetDefaultVoiceNameFor(String, String, String)} is a link between locale and voice
- * based methods. Since API level 20 {@link TextToSpeech#setLanguage} is implemented by
+ * based methods. Since API level 21 {@link TextToSpeech#setLanguage} is implemented by
* calling {@link TextToSpeech#setVoice} with the voice returned by
* {@link #onGetDefaultVoiceNameFor(String, String, String)}.
*
diff --git a/core/java/android/util/DisplayMetrics.java b/core/java/android/util/DisplayMetrics.java
index 946a3f7..c855e57 100644
--- a/core/java/android/util/DisplayMetrics.java
+++ b/core/java/android/util/DisplayMetrics.java
@@ -81,7 +81,7 @@ public class DisplayMetrics {
/**
* Intermediate density for screens that sit somewhere between
- * {@link #DENSITY_XXHIGH} (480 dpi) and {@link #DENSITY_XXXHIGH} (560 dpi).
+ * {@link #DENSITY_XXHIGH} (480 dpi) and {@link #DENSITY_XXXHIGH} (640 dpi).
* This is not a density that applications should target, instead relying
* on the system to scale their {@link #DENSITY_XXXHIGH} assets for them.
*/
diff --git a/core/java/android/view/AccessibilityInteractionController.java b/core/java/android/view/AccessibilityInteractionController.java
index a283b91..baa133d 100644
--- a/core/java/android/view/AccessibilityInteractionController.java
+++ b/core/java/android/view/AccessibilityInteractionController.java
@@ -889,7 +889,13 @@ final class AccessibilityInteractionController {
}
}
} else {
- AccessibilityNodeInfo root = provider.createAccessibilityNodeInfo(virtualViewId);
+ final AccessibilityNodeInfo root;
+ if (virtualViewId != AccessibilityNodeInfo.UNDEFINED_ITEM_ID) {
+ root = provider.createAccessibilityNodeInfo(virtualViewId);
+ } else {
+ root = provider.createAccessibilityNodeInfo(
+ AccessibilityNodeProvider.HOST_VIEW_ID);
+ }
if (root != null) {
outInfos.add(root);
if ((fetchFlags & AccessibilityNodeInfo.FLAG_PREFETCH_PREDECESSORS) != 0) {
diff --git a/core/java/android/view/WindowManagerGlobal.java b/core/java/android/view/WindowManagerGlobal.java
index 08160c8..dffcca4 100644
--- a/core/java/android/view/WindowManagerGlobal.java
+++ b/core/java/android/view/WindowManagerGlobal.java
@@ -434,11 +434,12 @@ public final class WindowManagerGlobal {
boolean hasVisibleWindows = false;
synchronized (mLock) {
for (int i = mRoots.size() - 1; i >= 0; --i) {
- if (mRoots.get(i).getHostVisibility() == View.VISIBLE
- && mRoots.get(i).mAttachInfo.mHardwareRenderer != null) {
+ final ViewRootImpl root = mRoots.get(i);
+ if (root.mView != null && root.getHostVisibility() == View.VISIBLE
+ && root.mAttachInfo.mHardwareRenderer != null) {
hasVisibleWindows = true;
} else {
- mRoots.get(i).destroyHardwareResources();
+ root.destroyHardwareResources();
}
}
}
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index 2b8b4dc..0439168 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -1493,11 +1493,11 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
super.onInitializeAccessibilityNodeInfo(info);
info.setClassName(AbsListView.class.getName());
if (isEnabled()) {
- if (getFirstVisiblePosition() > 0) {
+ if (canScrollUp()) {
info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD);
info.setScrollable(true);
}
- if (getLastVisiblePosition() < getCount() - 1) {
+ if (canScrollDown()) {
info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD);
info.setScrollable(true);
}
@@ -2203,36 +2203,44 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
void updateScrollIndicators() {
if (mScrollUp != null) {
- boolean canScrollUp;
- // 0th element is not visible
- canScrollUp = mFirstPosition > 0;
-
- // ... Or top of 0th element is not visible
- if (!canScrollUp) {
- if (getChildCount() > 0) {
- View child = getChildAt(0);
- canScrollUp = child.getTop() < mListPadding.top;
- }
- }
-
- mScrollUp.setVisibility(canScrollUp ? View.VISIBLE : View.INVISIBLE);
+ mScrollUp.setVisibility(canScrollUp() ? View.VISIBLE : View.INVISIBLE);
}
if (mScrollDown != null) {
- boolean canScrollDown;
- int count = getChildCount();
+ mScrollDown.setVisibility(canScrollDown() ? View.VISIBLE : View.INVISIBLE);
+ }
+ }
- // Last item is not visible
- canScrollDown = (mFirstPosition + count) < mItemCount;
+ private boolean canScrollUp() {
+ boolean canScrollUp;
+ // 0th element is not visible
+ canScrollUp = mFirstPosition > 0;
- // ... Or bottom of the last element is not visible
- if (!canScrollDown && count > 0) {
- View child = getChildAt(count - 1);
- canScrollDown = child.getBottom() > mBottom - mListPadding.bottom;
+ // ... Or top of 0th element is not visible
+ if (!canScrollUp) {
+ if (getChildCount() > 0) {
+ View child = getChildAt(0);
+ canScrollUp = child.getTop() < mListPadding.top;
}
+ }
+
+ return canScrollUp;
+ }
- mScrollDown.setVisibility(canScrollDown ? View.VISIBLE : View.INVISIBLE);
+ private boolean canScrollDown() {
+ boolean canScrollDown;
+ int count = getChildCount();
+
+ // Last item is not visible
+ canScrollDown = (mFirstPosition + count) < mItemCount;
+
+ // ... Or bottom of the last element is not visible
+ if (!canScrollDown && count > 0) {
+ View child = getChildAt(count - 1);
+ canScrollDown = child.getBottom() > mBottom - mListPadding.bottom;
}
+
+ return canScrollDown;
}
@Override
diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java
index 22600de..5685ad7 100644
--- a/core/java/com/android/internal/app/ResolverActivity.java
+++ b/core/java/com/android/internal/app/ResolverActivity.java
@@ -128,7 +128,10 @@ public class ResolverActivity extends Activity implements AdapterView.OnItemClic
com.android.internal.R.string.whichSendApplicationNamed),
DEFAULT(null,
com.android.internal.R.string.whichApplication,
- com.android.internal.R.string.whichApplicationNamed);
+ com.android.internal.R.string.whichApplicationNamed),
+ HOME(Intent.ACTION_MAIN,
+ com.android.internal.R.string.whichHomeApplication,
+ com.android.internal.R.string.whichHomeApplicationNamed);
public final String action;
public final int titleRes;
@@ -142,7 +145,7 @@ public class ResolverActivity extends Activity implements AdapterView.OnItemClic
public static ActionTitle forAction(String action) {
for (ActionTitle title : values()) {
- if (action != null && action.equals(title.action)) {
+ if (title != HOME && action != null && action.equals(title.action)) {
return title;
}
}
@@ -165,26 +168,19 @@ public class ResolverActivity extends Activity implements AdapterView.OnItemClic
@Override
protected void onCreate(Bundle savedInstanceState) {
// Use a specialized prompt when we're handling the 'Home' app startActivity()
- final int titleResource;
final Intent intent = makeMyIntent();
final Set<String> categories = intent.getCategories();
if (Intent.ACTION_MAIN.equals(intent.getAction())
&& categories != null
&& categories.size() == 1
&& categories.contains(Intent.CATEGORY_HOME)) {
- titleResource = com.android.internal.R.string.whichHomeApplication;
-
// Note: this field is not set to true in the compatibility version.
mResolvingHome = true;
- } else {
- titleResource = 0;
}
setSafeForwardingMode(true);
- onCreate(savedInstanceState, intent,
- titleResource != 0 ? getResources().getText(titleResource) : null, titleResource,
- null, null, true);
+ onCreate(savedInstanceState, intent, null, 0, null, null, true);
}
/**
@@ -336,7 +332,7 @@ public class ResolverActivity extends Activity implements AdapterView.OnItemClic
}
protected CharSequence getTitleForAction(String action, int defaultTitleRes) {
- final ActionTitle title = ActionTitle.forAction(action);
+ final ActionTitle title = mResolvingHome ? ActionTitle.HOME : ActionTitle.forAction(action);
final boolean named = mAdapter.hasFilteredItem();
if (title == ActionTitle.DEFAULT && defaultTitleRes != 0) {
return getString(defaultTitleRes);
diff --git a/core/java/com/android/internal/os/storage/ExternalStorageFormatter.java b/core/java/com/android/internal/os/storage/ExternalStorageFormatter.java
index fb7f215..a529923 100644
--- a/core/java/com/android/internal/os/storage/ExternalStorageFormatter.java
+++ b/core/java/com/android/internal/os/storage/ExternalStorageFormatter.java
@@ -50,6 +50,7 @@ public class ExternalStorageFormatter extends Service
private boolean mFactoryReset = false;
private boolean mAlwaysReset = false;
+ private String mReason = null;
StorageEventListener mStorageListener = new StorageEventListener() {
@Override
@@ -84,6 +85,7 @@ public class ExternalStorageFormatter extends Service
mAlwaysReset = true;
}
+ mReason = intent.getStringExtra(Intent.EXTRA_REASON);
mStorageVolume = intent.getParcelableExtra(StorageVolume.EXTRA_STORAGE_VOLUME);
if (mProgressDialog == null) {
@@ -135,7 +137,10 @@ public class ExternalStorageFormatter extends Service
void fail(int msg) {
Toast.makeText(this, msg, Toast.LENGTH_LONG).show();
if (mAlwaysReset) {
- sendBroadcast(new Intent("android.intent.action.MASTER_CLEAR"));
+ Intent intent = new Intent(Intent.ACTION_MASTER_CLEAR);
+ intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
+ intent.putExtra(Intent.EXTRA_REASON, mReason);
+ sendBroadcast(intent);
}
stopSelf();
}
@@ -179,7 +184,10 @@ public class ExternalStorageFormatter extends Service
}
if (success) {
if (mFactoryReset) {
- sendBroadcast(new Intent("android.intent.action.MASTER_CLEAR"));
+ Intent intent = new Intent(Intent.ACTION_MASTER_CLEAR);
+ intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
+ intent.putExtra(Intent.EXTRA_REASON, mReason);
+ sendBroadcast(intent);
// Intent handling is asynchronous -- assume it will happen soon.
stopSelf();
return;
@@ -188,7 +196,10 @@ public class ExternalStorageFormatter extends Service
// If we didn't succeed, or aren't doing a full factory
// reset, then it is time to remount the storage.
if (!success && mAlwaysReset) {
- sendBroadcast(new Intent("android.intent.action.MASTER_CLEAR"));
+ Intent intent = new Intent(Intent.ACTION_MASTER_CLEAR);
+ intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
+ intent.putExtra(Intent.EXTRA_REASON, mReason);
+ sendBroadcast(intent);
} else {
try {
mountService.mountVolume(extStoragePath);
diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java
index 7160724..85b58aa 100644
--- a/core/java/com/android/internal/widget/LockPatternUtils.java
+++ b/core/java/com/android/internal/widget/LockPatternUtils.java
@@ -28,6 +28,7 @@ import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.UserInfo;
+import android.os.AsyncTask;
import android.os.IBinder;
import android.os.RemoteException;
import android.os.ServiceManager;
@@ -718,25 +719,31 @@ public class LockPatternUtils {
}
/** Update the encryption password if it is enabled **/
- private void updateEncryptionPassword(int type, String password) {
+ private void updateEncryptionPassword(final int type, final String password) {
DevicePolicyManager dpm = getDevicePolicyManager();
if (dpm.getStorageEncryptionStatus(getCurrentOrCallingUserId())
!= DevicePolicyManager.ENCRYPTION_STATUS_ACTIVE) {
return;
}
- IBinder service = ServiceManager.getService("mount");
+ final IBinder service = ServiceManager.getService("mount");
if (service == null) {
Log.e(TAG, "Could not find the mount service to update the encryption password");
return;
}
- IMountService mountService = IMountService.Stub.asInterface(service);
- try {
- mountService.changeEncryptionPassword(type, password);
- } catch (RemoteException e) {
- Log.e(TAG, "Error changing encryption password", e);
- }
+ new AsyncTask<Void, Void, Void>() {
+ @Override
+ protected Void doInBackground(Void... dummy) {
+ IMountService mountService = IMountService.Stub.asInterface(service);
+ try {
+ mountService.changeEncryptionPassword(type, password);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Error changing encryption password", e);
+ }
+ return null;
+ }
+ }.execute();
}
/**
@@ -773,9 +780,9 @@ public class LockPatternUtils {
*/
public void saveLockPassword(String password, int quality, boolean isFallback, int userHandle) {
try {
- getLockSettings().setLockPassword(password, userHandle);
DevicePolicyManager dpm = getDevicePolicyManager();
if (!TextUtils.isEmpty(password)) {
+ getLockSettings().setLockPassword(password, userHandle);
int computedQuality = computePasswordQuality(password);
if (userHandle == UserHandle.USER_OWNER) {
@@ -853,6 +860,7 @@ public class LockPatternUtils {
setString(PASSWORD_HISTORY_KEY, passwordHistory, userHandle);
} else {
// Empty password
+ getLockSettings().setLockPassword(null, userHandle);
if (userHandle == UserHandle.USER_OWNER) {
// Set the encryption password to default.
updateEncryptionPassword(StorageManager.CRYPT_TYPE_DEFAULT, null);
diff --git a/core/jni/android_hardware_camera2_legacy_LegacyCameraDevice.cpp b/core/jni/android_hardware_camera2_legacy_LegacyCameraDevice.cpp
index 980ead0..ee00161 100644
--- a/core/jni/android_hardware_camera2_legacy_LegacyCameraDevice.cpp
+++ b/core/jni/android_hardware_camera2_legacy_LegacyCameraDevice.cpp
@@ -200,7 +200,7 @@ static status_t produceFrame(const sp<ANativeWindow>& anw,
switch(pixelFmt) {
case HAL_PIXEL_FORMAT_YCrCb_420_SP: {
if (bufSize < width * height * 4) {
- ALOGE("%s: PixelBuffer size %" PRId32 " to small for given dimensions",
+ ALOGE("%s: PixelBuffer size %" PRId32 " too small for given dimensions",
__FUNCTION__, bufSize);
return BAD_VALUE;
}
@@ -222,7 +222,7 @@ static status_t produceFrame(const sp<ANativeWindow>& anw,
}
case HAL_PIXEL_FORMAT_YV12: {
if (bufSize < width * height * 4) {
- ALOGE("%s: PixelBuffer size %" PRId32 " to small for given dimensions",
+ ALOGE("%s: PixelBuffer size %" PRId32 " too small for given dimensions",
__FUNCTION__, bufSize);
return BAD_VALUE;
}
@@ -259,7 +259,7 @@ static status_t produceFrame(const sp<ANativeWindow>& anw,
// Software writes with YCbCr_420_888 format are unsupported
// by the gralloc module for now
if (bufSize < width * height * 4) {
- ALOGE("%s: PixelBuffer size %" PRId32 " to small for given dimensions",
+ ALOGE("%s: PixelBuffer size %" PRId32 " too small for given dimensions",
__FUNCTION__, bufSize);
return BAD_VALUE;
}
@@ -281,6 +281,18 @@ static status_t produceFrame(const sp<ANativeWindow>& anw,
return BAD_VALUE;
}
int8_t* img = NULL;
+ struct camera3_jpeg_blob footer = {
+ jpeg_blob_id: CAMERA3_JPEG_BLOB_ID,
+ jpeg_size: (uint32_t)width
+ };
+
+ size_t totalSize = static_cast<size_t>(width) + sizeof(footer);
+ size_t padding = ((totalSize - 1) & ~0x3) + 4; // align to next octonibble
+ totalSize += padding;
+ if (anb->width != totalSize) {
+ ALOGE("%s: gralloc buffer wrong size to hold jpeg, failed to produce buffer.");
+ return BAD_VALUE;
+ }
ALOGV("%s: Lock buffer from %p for write", __FUNCTION__, anw.get());
err = buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
@@ -289,12 +301,9 @@ static status_t produceFrame(const sp<ANativeWindow>& anw,
err);
return err;
}
- struct camera3_jpeg_blob footer = {
- jpeg_blob_id: CAMERA3_JPEG_BLOB_ID,
- jpeg_size: (uint32_t)width
- };
memcpy(img, pixelBuffer, width);
- memcpy(img + anb->width - sizeof(footer), &footer, sizeof(footer));
+ memset(img + width, 0, padding);
+ memcpy(img + totalSize - sizeof(footer), &footer, sizeof(footer));
break;
}
default: {
diff --git a/core/jni/android_util_Binder.cpp b/core/jni/android_util_Binder.cpp
index 81e887d..2dbd382 100644
--- a/core/jni/android_util_Binder.cpp
+++ b/core/jni/android_util_Binder.cpp
@@ -1239,7 +1239,7 @@ static const JNINativeMethod gBinderProxyMethods[] = {
{"pingBinder", "()Z", (void*)android_os_BinderProxy_pingBinder},
{"isBinderAlive", "()Z", (void*)android_os_BinderProxy_isBinderAlive},
{"getInterfaceDescriptor", "()Ljava/lang/String;", (void*)android_os_BinderProxy_getInterfaceDescriptor},
- {"transact", "(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z", (void*)android_os_BinderProxy_transact},
+ {"transactNative", "(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z", (void*)android_os_BinderProxy_transact},
{"linkToDeath", "(Landroid/os/IBinder$DeathRecipient;I)V", (void*)android_os_BinderProxy_linkToDeath},
{"unlinkToDeath", "(Landroid/os/IBinder$DeathRecipient;I)Z", (void*)android_os_BinderProxy_unlinkToDeath},
{"destroy", "()V", (void*)android_os_BinderProxy_destroy},
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 38f146b..bd9e2f6 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -365,6 +365,8 @@
<integer translatable="false" name="config_wifi_framework_wifi_score_bad_link_speed_5">12</integer>
<integer translatable="false" name="config_wifi_framework_wifi_score_good_link_speed_24">24</integer>
<integer translatable="false" name="config_wifi_framework_wifi_score_good_link_speed_5">36</integer>
+ <string translatable="false" name="config_wifi_random_mac_oui">DA-A1-19</string>
+
<bool translatable="false" name="config_wifi_framework_cellular_handover_enable_user_triggered_adjustment">true</bool>
<!-- Integer packet threshold used to allow scan while associated -->
@@ -1844,4 +1846,9 @@
<item>71610</item>
<item>732101</item>
</string-array>
+
+ <!-- Config determines whether to update phone object when voice registration
+ state changes. Voice radio tech change will always trigger an update of
+ phone object irrespective of this config -->
+ <bool name="config_switch_phone_on_voice_reg_state_change">true</bool>
</resources>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index fd4b40f..9fc7801 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -3440,7 +3440,10 @@
and a previously used application is known. -->
<string name="whichSendApplicationNamed">Share with %1$s</string>
<!-- Title of intent resolver dialog when selecting a HOME application to run. -->
- <string name="whichHomeApplication">Select a home app</string>
+ <string name="whichHomeApplication">Select a Home app</string>
+ <!-- Title of intent resolver dialog when selecting a HOME application to run
+ and a previously used application is known. -->
+ <string name="whichHomeApplicationNamed">Use %1$s as Home</string>
<!-- Option to always use the selected application resolution in the future. See the "Complete action using" dialog title-->
<string name="alwaysUse">Use by default for this action.</string>
<!-- Title of the list of alternate options to complete an action shown when the
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 5c246a4..72f756a 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -322,6 +322,8 @@
<java-symbol type="integer" name="config_wifi_framework_wifi_score_bad_link_speed_5" />
<java-symbol type="integer" name="config_wifi_framework_wifi_score_good_link_speed_24" />
<java-symbol type="integer" name="config_wifi_framework_wifi_score_good_link_speed_5" />
+ <java-symbol type="string" name="config_wifi_random_mac_oui" />
+
<java-symbol type="bool" name="editable_voicemailnumber" />
<java-symbol type="bool" name="config_wifi_framework_cellular_handover_enable_user_triggered_adjustment" />
@@ -2064,4 +2066,6 @@
<java-symbol type="array" name="dial_string_replace" />
<java-symbol type="bool" name="config_restart_radio_on_pdp_fail_regular_deactivation" />
<java-symbol type="array" name="networks_not_clear_data" />
+ <java-symbol type="bool" name="config_switch_phone_on_voice_reg_state_change" />
+ <java-symbol type="string" name="whichHomeApplicationNamed" />
</resources>
diff --git a/docs/html/app.yaml b/docs/html/app.yaml
index 9ffb775..520ee99 100644
--- a/docs/html/app.yaml
+++ b/docs/html/app.yaml
@@ -1,38 +1,25 @@
application: androidappdocs-staging
version: 1
-runtime: python
+runtime: python27
+threadsafe: true
api_version: 1
+# compatibility: gae-1.9.4+
-# This file defines two mutually exclusive
-# hander blocks:
-# - a handler for use on a local dev_appserver
-# during development or non-production doc build
-# - a handler for use on a production gae
-# instance. This handler requires that the
-# docs files in the app have been compressed
-# with divide_and_compress.py and that main.py
-# and gae_shell/ are present.
-#
-# Only one of the handler blocks should be
-# uncommented at any given time. By default,
-# the development handler is exposed.
+# handler for local staging servers
+# WARNING: NOT FOR USE IN PRODUCTION
+
+# Use this handler definition with
+# Google App Engine 1.9.4 or higher.
+# NOT compatible with prior GAE versions
handlers:
# DEVELOPMENT HANDLER
-# (this handler block *must* be commented
-# out before pushing to a production server)
-- url: /
- static_dir: /
+- url: /(.+)
+ static_files: \1
+ upload: (.+)
-# PRODUCTION GAE HANDLER
-#- url: /gae_shell/static
-# static_dir: gae_shell/static
-# expiration: 1d
-#
-#- url: /gae_shell/.*
-# script: /gae_shell/shell.py
-# login: admin
-#
-#- url: .*
-# script: main.py
+# Direct default, blank requests
+- url: /
+ static_files: index.html
+ upload: index.html \ No newline at end of file
diff --git a/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java b/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java
index 49e8b9d..df1b126 100644
--- a/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java
+++ b/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java
@@ -137,8 +137,7 @@ public class AnimatedVectorDrawable extends Drawable implements Animatable {
private boolean mMutated;
public AnimatedVectorDrawable() {
- mAnimatedVectorState = new AnimatedVectorDrawableState(
- new AnimatedVectorDrawableState(null));
+ mAnimatedVectorState = new AnimatedVectorDrawableState(null);
}
private AnimatedVectorDrawable(AnimatedVectorDrawableState state, Resources res,
@@ -160,10 +159,16 @@ public class AnimatedVectorDrawable extends Drawable implements Animatable {
@Override
public ConstantState getConstantState() {
+ mAnimatedVectorState.mChangingConfigurations = getChangingConfigurations();
return mAnimatedVectorState;
}
@Override
+ public int getChangingConfigurations() {
+ return super.getChangingConfigurations() | mAnimatedVectorState.mChangingConfigurations;
+ }
+
+ @Override
public void draw(Canvas canvas) {
mAnimatedVectorState.mVectorDrawable.draw(canvas);
if (isStarted()) {
@@ -347,6 +352,8 @@ public class AnimatedVectorDrawable extends Drawable implements Animatable {
mTargetNameMap.put(animClone, targetName);
}
}
+ } else {
+ mVectorDrawable = new VectorDrawable();
}
}
diff --git a/graphics/java/android/graphics/drawable/RippleBackground.java b/graphics/java/android/graphics/drawable/RippleBackground.java
index 4e709b5..faa89bf 100644
--- a/graphics/java/android/graphics/drawable/RippleBackground.java
+++ b/graphics/java/android/graphics/drawable/RippleBackground.java
@@ -106,7 +106,7 @@ class RippleBackground {
public void setup(int maxRadius, int color, float density) {
mColorOpaque = color | 0xFF000000;
- mColorAlpha = Color.alpha(color);
+ mColorAlpha = Color.alpha(color) / 2;
if (maxRadius != RippleDrawable.RADIUS_AUTO) {
mHasMaxRadius = true;
diff --git a/location/java/com/android/internal/location/GpsNetInitiatedHandler.java b/location/java/com/android/internal/location/GpsNetInitiatedHandler.java
index f0a2072..e9e475c 100644
--- a/location/java/com/android/internal/location/GpsNetInitiatedHandler.java
+++ b/location/java/com/android/internal/location/GpsNetInitiatedHandler.java
@@ -289,7 +289,7 @@ public class GpsNetInitiatedHandler {
+ " mPopupImmediately: " + mPopupImmediately
+ " mInEmergency: " + getInEmergency());
- if (getLocationEnabled() && !getInEmergency()) {
+ if (!getLocationEnabled() && !getInEmergency()) {
// Location is currently disabled, ignore all NI requests.
try {
mNetInitiatedListener.sendNiResponse(notif.notificationId,
diff --git a/media/java/android/media/ImageReader.java b/media/java/android/media/ImageReader.java
index b786f94..b541454 100644
--- a/media/java/android/media/ImageReader.java
+++ b/media/java/android/media/ImageReader.java
@@ -642,7 +642,7 @@ public class ImageReader implements AutoCloseable {
private void createSurfacePlanes() {
mPlanes = new SurfacePlane[ImageReader.this.mNumPlanes];
for (int i = 0; i < ImageReader.this.mNumPlanes; i++) {
- mPlanes[i] = nativeCreatePlane(i);
+ mPlanes[i] = nativeCreatePlane(i, ImageReader.this.mFormat);
}
}
private class SurfacePlane extends android.media.Image.Plane {
@@ -661,7 +661,8 @@ public class ImageReader implements AutoCloseable {
if (mBuffer != null) {
return mBuffer;
} else {
- mBuffer = SurfaceImage.this.nativeImageGetBuffer(mIndex);
+ mBuffer = SurfaceImage.this.nativeImageGetBuffer(mIndex,
+ ImageReader.this.mFormat);
// Set the byteBuffer order according to host endianness (native order),
// otherwise, the byteBuffer order defaults to ByteOrder.BIG_ENDIAN.
return mBuffer.order(ByteOrder.nativeOrder());
@@ -711,8 +712,8 @@ public class ImageReader implements AutoCloseable {
private SurfacePlane[] mPlanes;
private boolean mIsImageValid;
- private synchronized native ByteBuffer nativeImageGetBuffer(int idx);
- private synchronized native SurfacePlane nativeCreatePlane(int idx);
+ private synchronized native ByteBuffer nativeImageGetBuffer(int idx, int readerFormat);
+ private synchronized native SurfacePlane nativeCreatePlane(int idx, int readerFormat);
}
private synchronized native void nativeInit(Object weakSelf, int w, int h,
diff --git a/media/java/android/media/MediaCodec.java b/media/java/android/media/MediaCodec.java
index 5fb4f12..420510a 100644
--- a/media/java/android/media/MediaCodec.java
+++ b/media/java/android/media/MediaCodec.java
@@ -827,8 +827,13 @@ final public class MediaCodec {
invalidateByteBuffer(mCachedInputBuffers, index);
mDequeuedInputBuffers.remove(index);
}
- native_queueInputBuffer(
- index, offset, size, presentationTimeUs, flags);
+ try {
+ native_queueInputBuffer(
+ index, offset, size, presentationTimeUs, flags);
+ } catch (CryptoException | IllegalStateException e) {
+ revalidateByteBuffer(mCachedInputBuffers, index);
+ throw e;
+ }
}
private native final void native_queueInputBuffer(
@@ -947,8 +952,13 @@ final public class MediaCodec {
invalidateByteBuffer(mCachedInputBuffers, index);
mDequeuedInputBuffers.remove(index);
}
- native_queueSecureInputBuffer(
- index, offset, info, presentationTimeUs, flags);
+ try {
+ native_queueSecureInputBuffer(
+ index, offset, info, presentationTimeUs, flags);
+ } catch (CryptoException | IllegalStateException e) {
+ revalidateByteBuffer(mCachedInputBuffers, index);
+ throw e;
+ }
}
private native final void native_queueSecureInputBuffer(
@@ -1270,6 +1280,18 @@ final public class MediaCodec {
}
}
+ private final void revalidateByteBuffer(
+ ByteBuffer[] buffers, int index) {
+ synchronized(mBufferLock) {
+ if (buffers != null && index >= 0 && index < buffers.length) {
+ ByteBuffer buffer = buffers[index];
+ if (buffer != null) {
+ buffer.setAccessible(true);
+ }
+ }
+ }
+ }
+
private final void validateOutputByteBuffer(
ByteBuffer[] buffers, int index, BufferInfo info) {
if (buffers != null && index >= 0 && index < buffers.length) {
@@ -1307,7 +1329,7 @@ final public class MediaCodec {
}
private final void freeAllTrackedBuffers() {
- synchronized (mBufferLock) {
+ synchronized(mBufferLock) {
freeByteBuffers(mCachedInputBuffers);
freeByteBuffers(mCachedOutputBuffers);
mCachedInputBuffers = null;
diff --git a/media/java/android/media/MediaCodecList.java b/media/java/android/media/MediaCodecList.java
index 0dcbd65..bb848d9 100644
--- a/media/java/android/media/MediaCodecList.java
+++ b/media/java/android/media/MediaCodecList.java
@@ -204,7 +204,7 @@ final public class MediaCodecList {
* requests, or {@code null} if no such codec has been found.
*/
public final String findEncoderForFormat(MediaFormat format) {
- return findCodecForFormat(false /* encoder */, format);
+ return findCodecForFormat(true /* encoder */, format);
}
private String findCodecForFormat(boolean encoder, MediaFormat format) {
diff --git a/media/java/android/media/browse/MediaBrowser.java b/media/java/android/media/browse/MediaBrowser.java
index 0f9bded..3e5919f 100644
--- a/media/java/android/media/browse/MediaBrowser.java
+++ b/media/java/android/media/browse/MediaBrowser.java
@@ -713,6 +713,7 @@ public final class MediaBrowser {
// We make a new mServiceCallbacks each time we connect so that we can drop
// responses from previous connections.
mServiceCallbacks = getNewServiceCallbacks();
+ mState = CONNECT_STATE_CONNECTING;
// Call connect, which is async. When we get a response from that we will
// say that we're connected.
diff --git a/media/java/android/media/session/MediaController.java b/media/java/android/media/session/MediaController.java
index cfbf3af..e490c2b 100644
--- a/media/java/android/media/session/MediaController.java
+++ b/media/java/android/media/session/MediaController.java
@@ -918,7 +918,8 @@ public final class MediaController {
@Override
public void onQueueChanged(ParceledListSlice parceledQueue) {
- List<MediaSession.QueueItem> queue = parceledQueue.getList();
+ List<MediaSession.QueueItem> queue = parceledQueue == null ? null : parceledQueue
+ .getList();
MediaController controller = mController.get();
if (controller != null) {
controller.postMessage(MSG_UPDATE_QUEUE, queue, null);
diff --git a/media/java/android/media/session/MediaSession.java b/media/java/android/media/session/MediaSession.java
index 2c38697..ad018ad 100644
--- a/media/java/android/media/session/MediaSession.java
+++ b/media/java/android/media/session/MediaSession.java
@@ -427,7 +427,7 @@ public final class MediaSession {
*/
public void setQueue(@Nullable List<QueueItem> queue) {
try {
- mBinder.setQueue(new ParceledListSlice<QueueItem>(queue));
+ mBinder.setQueue(queue == null ? null : new ParceledListSlice<QueueItem>(queue));
} catch (RemoteException e) {
Log.wtf("Dead object in setQueue.", e);
}
diff --git a/media/jni/android_media_ImageReader.cpp b/media/jni/android_media_ImageReader.cpp
index fa4439d..a734774 100644
--- a/media/jni/android_media_ImageReader.cpp
+++ b/media/jni/android_media_ImageReader.cpp
@@ -317,8 +317,18 @@ static uint32_t Image_getJpegSize(CpuConsumer::LockedBuffer* buffer)
return size;
}
+static int32_t applyFormatOverrides(int32_t bufferFormat, int32_t readerCtxFormat)
+{
+ // Using HAL_PIXEL_FORMAT_RGBA_8888 gralloc buffers containing JPEGs to get around SW
+ // write limitations for some platforms (b/17379185).
+ if (readerCtxFormat == HAL_PIXEL_FORMAT_BLOB && bufferFormat == HAL_PIXEL_FORMAT_RGBA_8888) {
+ return HAL_PIXEL_FORMAT_BLOB;
+ }
+ return bufferFormat;
+}
+
static void Image_getLockedBufferInfo(JNIEnv* env, CpuConsumer::LockedBuffer* buffer, int idx,
- uint8_t **base, uint32_t *size)
+ uint8_t **base, uint32_t *size, int32_t readerFormat)
{
ALOG_ASSERT(buffer != NULL, "Input buffer is NULL!!!");
ALOG_ASSERT(base != NULL, "base is NULL!!!");
@@ -334,6 +344,8 @@ static void Image_getLockedBufferInfo(JNIEnv* env, CpuConsumer::LockedBuffer* bu
dataSize = ySize = cSize = cStride = 0;
int32_t fmt = buffer->format;
+
+ fmt = applyFormatOverrides(fmt, readerFormat);
switch (fmt) {
case HAL_PIXEL_FORMAT_YCbCr_420_888:
pData =
@@ -458,7 +470,8 @@ static void Image_getLockedBufferInfo(JNIEnv* env, CpuConsumer::LockedBuffer* bu
*size = dataSize;
}
-static jint Image_imageGetPixelStride(JNIEnv* env, CpuConsumer::LockedBuffer* buffer, int idx)
+static jint Image_imageGetPixelStride(JNIEnv* env, CpuConsumer::LockedBuffer* buffer, int idx,
+ int32_t readerFormat)
{
ALOGV("%s: buffer index: %d", __FUNCTION__, idx);
ALOG_ASSERT((idx < IMAGE_READER_MAX_NUM_PLANES) && (idx >= 0), "Index is out of range:%d", idx);
@@ -467,6 +480,9 @@ static jint Image_imageGetPixelStride(JNIEnv* env, CpuConsumer::LockedBuffer* bu
ALOG_ASSERT(buffer != NULL, "buffer is NULL");
int32_t fmt = buffer->format;
+
+ fmt = applyFormatOverrides(fmt, readerFormat);
+
switch (fmt) {
case HAL_PIXEL_FORMAT_YCbCr_420_888:
pixelStride = (idx == 0) ? 1 : buffer->chromaStep;
@@ -515,7 +531,8 @@ static jint Image_imageGetPixelStride(JNIEnv* env, CpuConsumer::LockedBuffer* bu
return pixelStride;
}
-static jint Image_imageGetRowStride(JNIEnv* env, CpuConsumer::LockedBuffer* buffer, int idx)
+static jint Image_imageGetRowStride(JNIEnv* env, CpuConsumer::LockedBuffer* buffer, int idx,
+ int32_t readerFormat)
{
ALOGV("%s: buffer index: %d", __FUNCTION__, idx);
ALOG_ASSERT((idx < IMAGE_READER_MAX_NUM_PLANES) && (idx >= 0));
@@ -525,6 +542,8 @@ static jint Image_imageGetRowStride(JNIEnv* env, CpuConsumer::LockedBuffer* buff
int32_t fmt = buffer->format;
+ fmt = applyFormatOverrides(fmt, readerFormat);
+
switch (fmt) {
case HAL_PIXEL_FORMAT_YCbCr_420_888:
rowStride = (idx == 0) ? buffer->stride : buffer->chromaStride;
@@ -777,9 +796,10 @@ static jint ImageReader_imageSetup(JNIEnv* env, jobject thiz,
outputHeight = buffer->crop.getHeight();
}
+ int imgReaderFmt = ctx->getBufferFormat();
int imageReaderWidth = ctx->getBufferWidth();
int imageReaderHeight = ctx->getBufferHeight();
- if ((buffer->format != HAL_PIXEL_FORMAT_BLOB) &&
+ if ((buffer->format != HAL_PIXEL_FORMAT_BLOB) && (imgReaderFmt != HAL_PIXEL_FORMAT_BLOB) &&
(imageReaderWidth != outputWidth || imageReaderHeight > outputHeight)) {
/**
* For video decoder, the buffer height is actually the vertical stride,
@@ -795,15 +815,19 @@ static jint ImageReader_imageSetup(JNIEnv* env, jobject thiz,
return -1;
}
- int imgReaderFmt = ctx->getBufferFormat();
int bufFmt = buffer->format;
if (imgReaderFmt != bufFmt) {
- // Special casing for when producer switches to a format compatible with flexible YUV
- // (HAL_PIXEL_FORMAT_YCbCr_420_888).
+
if (imgReaderFmt == HAL_PIXEL_FORMAT_YCbCr_420_888 && (bufFmt ==
HAL_PIXEL_FORMAT_YCrCb_420_SP || bufFmt == HAL_PIXEL_FORMAT_YV12)) {
+ // Special casing for when producer switches to a format compatible with flexible YUV
+ // (HAL_PIXEL_FORMAT_YCbCr_420_888).
ctx->setBufferFormat(bufFmt);
- ALOGV("%s: Overriding buffer format YUV_420_888 to %x.", __FUNCTION__, bufFmt);
+ ALOGD("%s: Overriding buffer format YUV_420_888 to %x.", __FUNCTION__, bufFmt);
+ } else if (imgReaderFmt == HAL_PIXEL_FORMAT_BLOB && bufFmt == HAL_PIXEL_FORMAT_RGBA_8888) {
+ // Using HAL_PIXEL_FORMAT_RGBA_8888 gralloc buffers containing JPEGs to get around SW
+ // write limitations for (b/17379185).
+ ALOGD("%s: Receiving JPEG in HAL_PIXEL_FORMAT_RGBA_8888 buffer.", __FUNCTION__);
} else {
// Return the buffer to the queue.
consumer->unlockBuffer(*buffer);
@@ -843,7 +867,7 @@ static jobject ImageReader_getSurface(JNIEnv* env, jobject thiz)
return android_view_Surface_createFromIGraphicBufferProducer(env, gbp);
}
-static jobject Image_createSurfacePlane(JNIEnv* env, jobject thiz, int idx)
+static jobject Image_createSurfacePlane(JNIEnv* env, jobject thiz, int idx, int readerFormat)
{
int rowStride, pixelStride;
ALOGV("%s: buffer index: %d", __FUNCTION__, idx);
@@ -854,8 +878,11 @@ static jobject Image_createSurfacePlane(JNIEnv* env, jobject thiz, int idx)
if (buffer == NULL) {
jniThrowException(env, "java/lang/IllegalStateException", "Image was released");
}
- rowStride = Image_imageGetRowStride(env, buffer, idx);
- pixelStride = Image_imageGetPixelStride(env, buffer, idx);
+
+ readerFormat = Image_getPixelFormat(env, readerFormat);
+
+ rowStride = Image_imageGetRowStride(env, buffer, idx, readerFormat);
+ pixelStride = Image_imageGetPixelStride(env, buffer, idx, readerFormat);
jobject surfPlaneObj = env->NewObject(gSurfacePlaneClassInfo.clazz,
gSurfacePlaneClassInfo.ctor, thiz, idx, rowStride, pixelStride);
@@ -863,7 +890,7 @@ static jobject Image_createSurfacePlane(JNIEnv* env, jobject thiz, int idx)
return surfPlaneObj;
}
-static jobject Image_getByteBuffer(JNIEnv* env, jobject thiz, int idx)
+static jobject Image_getByteBuffer(JNIEnv* env, jobject thiz, int idx, int readerFormat)
{
uint8_t *base = NULL;
uint32_t size = 0;
@@ -877,8 +904,10 @@ static jobject Image_getByteBuffer(JNIEnv* env, jobject thiz, int idx)
jniThrowException(env, "java/lang/IllegalStateException", "Image was released");
}
+ readerFormat = Image_getPixelFormat(env, readerFormat);
+
// Create byteBuffer from native buffer
- Image_getLockedBufferInfo(env, buffer, idx, &base, &size);
+ Image_getLockedBufferInfo(env, buffer, idx, &base, &size, readerFormat);
if (size > static_cast<uint32_t>(INT32_MAX)) {
// Byte buffer have 'int capacity', so check the range
@@ -910,8 +939,8 @@ static JNINativeMethod gImageReaderMethods[] = {
};
static JNINativeMethod gImageMethods[] = {
- {"nativeImageGetBuffer", "(I)Ljava/nio/ByteBuffer;", (void*)Image_getByteBuffer },
- {"nativeCreatePlane", "(I)Landroid/media/ImageReader$SurfaceImage$SurfacePlane;",
+ {"nativeImageGetBuffer", "(II)Ljava/nio/ByteBuffer;", (void*)Image_getByteBuffer },
+ {"nativeCreatePlane", "(II)Landroid/media/ImageReader$SurfaceImage$SurfacePlane;",
(void*)Image_createSurfacePlane },
};
diff --git a/packages/SystemUI/res/anim/zen_toast_enter.xml b/packages/SystemUI/res/anim/zen_toast_enter.xml
new file mode 100644
index 0000000..e236782
--- /dev/null
+++ b/packages/SystemUI/res/anim/zen_toast_enter.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 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.
+-->
+<alpha xmlns:android="http://schemas.android.com/apk/res/android"
+ android:interpolator="@android:interpolator/decelerate_quad"
+ android:fromAlpha="0.0" android:toAlpha="1.0"
+ android:duration="@integer/zen_toast_animation_duration" />
diff --git a/packages/SystemUI/res/anim/zen_toast_exit.xml b/packages/SystemUI/res/anim/zen_toast_exit.xml
new file mode 100644
index 0000000..a9b1ab2
--- /dev/null
+++ b/packages/SystemUI/res/anim/zen_toast_exit.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 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.
+-->
+<alpha xmlns:android="http://schemas.android.com/apk/res/android"
+ android:interpolator="@android:interpolator/accelerate_quad"
+ android:fromAlpha="1.0" android:toAlpha="0.0"
+ android:duration="@integer/zen_toast_animation_duration" />
diff --git a/packages/SystemUI/res/drawable/ic_zen_important.xml b/packages/SystemUI/res/drawable/ic_zen_important.xml
new file mode 100644
index 0000000..11e9063
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_zen_important.xml
@@ -0,0 +1,25 @@
+<!--
+Copyright (C) 2014 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="32dp"
+ android:height="32dp"
+ android:viewportWidth="24.0"
+ android:viewportHeight="24.0">
+
+ <path
+ android:fillColor="#FFFFFFFF"
+ android:pathData="M12.0,17.273l6.1800003,3.7269993 -1.6350002,-7.0290003 5.455,-4.7269993 -7.191,-0.6170006 -2.809,-6.627 -2.809,6.627 -7.191,0.6170006 5.455,4.7269993 -1.6349998,7.0290003z"/>
+</vector> \ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/ic_zen_none.xml b/packages/SystemUI/res/drawable/ic_zen_none.xml
new file mode 100644
index 0000000..681d499
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_zen_none.xml
@@ -0,0 +1,25 @@
+<!--
+Copyright (C) 2014 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="32dp"
+ android:height="32dp"
+ android:viewportWidth="48.0"
+ android:viewportHeight="48.0">
+
+ <path
+ android:fillColor="#FFFFFFFF"
+ android:pathData="M24.0,4.0C13.0,4.0 4.0,13.0 4.0,24.0c0.0,11.0 9.0,20.0 20.0,20.0c11.0,0.0 20.0,-9.0 20.0,-20.0C44.0,13.0 35.0,4.0 24.0,4.0zM24.0,40.0c-8.8,0.0 -16.0,-7.2 -16.0,-16.0c0.0,-3.7 1.3,-7.1 3.4,-9.8l22.4,22.4C31.1,38.7 27.7,40.0 24.0,40.0zM36.6,33.8L14.2,11.4C16.9,9.3 20.3,8.0 24.0,8.0c8.8,0.0 16.0,7.2 16.0,16.0C40.0,27.7 38.7,31.1 36.6,33.8z"/>
+</vector> \ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/zen_toast_background.xml b/packages/SystemUI/res/drawable/zen_toast_background.xml
new file mode 100644
index 0000000..619fe20
--- /dev/null
+++ b/packages/SystemUI/res/drawable/zen_toast_background.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 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.
+-->
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+ <solid android:color="@color/system_primary_color" />
+ <corners android:radius="@dimen/notification_material_rounded_rect_radius" />
+</shape>
diff --git a/packages/SystemUI/res/layout/zen_mode_panel.xml b/packages/SystemUI/res/layout/zen_mode_panel.xml
index d0fba20..ece6979 100644
--- a/packages/SystemUI/res/layout/zen_mode_panel.xml
+++ b/packages/SystemUI/res/layout/zen_mode_panel.xml
@@ -44,6 +44,7 @@
android:id="@+id/zen_subhead"
android:layout_width="match_parent"
android:layout_height="62dp"
+ android:gravity="center_vertical"
android:paddingLeft="8dp"
android:paddingRight="8dp" >
diff --git a/packages/SystemUI/res/layout/zen_toast.xml b/packages/SystemUI/res/layout/zen_toast.xml
new file mode 100644
index 0000000..1e3d3cf
--- /dev/null
+++ b/packages/SystemUI/res/layout/zen_toast.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 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.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:background="@drawable/zen_toast_background"
+ android:translationZ="@dimen/volume_panel_z"
+ android:padding="18dp"
+ android:gravity="center_horizontal"
+ android:orientation="vertical" >
+
+ <ImageView
+ android:id="@android:id/icon"
+ android:layout_width="32dp"
+ android:layout_height="32dp"
+ android:scaleType="center" />
+
+ <TextView
+ android:id="@android:id/message"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="12dp"
+ android:lineSpacingExtra="4dp"
+ android:gravity="center_horizontal"
+ android:textAppearance="@style/TextAppearance.QS.ZenToast" />
+
+</LinearLayout>
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index 2e6f898..13170ad 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -239,5 +239,11 @@
<!-- Number of times to show the strong alarm warning text in the volume dialog -->
<integer name="zen_mode_alarm_warning_threshold">5</integer>
+
+ <!-- Zen toast fade in/out duration -->
+ <integer name="zen_toast_animation_duration">500</integer>
+
+ <!-- Zen toast visibility duration -->
+ <integer name="zen_toast_visible_duration">500</integer>
</resources>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index c690ef4..4f41cd5 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -193,6 +193,9 @@
<dimen name="zen_mode_condition_detail_button_padding">8dp</dimen>
+ <!-- Explicit width of the zen toast window -->
+ <dimen name="zen_toast_width">224dp</dimen>
+
<!-- used by DessertCase -->
<dimen name="dessert_case_cell_size">192dp</dimen>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index e9a1acf..48450dd 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -900,10 +900,10 @@
<!-- Body of notification educating the user about enabling notifications on the lockscreen. [CHAR LIMIT=60] -->
<string name="hidden_notifications_text">See them before you unlock</string>
- <!-- Cancel action for notification educating the user about enabling notifications on the lockscreen. [CHAR LIMIT=10] -->
+ <!-- Cancel action for notification educating the user about enabling notifications on the lockscreen. [CHAR LIMIT=20] -->
<string name="hidden_notifications_cancel">No thanks</string>
- <!-- continue action for notification educating the user about enabling notifications on the lockscreen. [CHAR LIMIT=10] -->
+ <!-- continue action for notification educating the user about enabling notifications on the lockscreen. [CHAR LIMIT=20] -->
<string name="hidden_notifications_setup">Set up</string>
<!-- Indication that the current volume and other effects (vibration) are being suppressed by a third party, such as a notification listener. [CHAR LIMIT=30] -->
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index 46e7587..909dc42 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -167,6 +167,10 @@
<item name="android:textColor">@color/qs_subhead</item>
</style>
+ <style name="TextAppearance.QS.ZenToast">
+ <item name="android:textSize">14sp</item>
+ </style>
+
<style name="TextAppearance.QS.SegmentedButton">
<item name="android:textSize">14sp</item>
<item name="android:textAllCaps">true</item>
@@ -262,4 +266,9 @@
<style name="UserDetailView">
<item name="numColumns">3</item>
</style>
+
+ <style name="ZenToastAnimations">
+ <item name="android:windowEnterAnimation">@anim/zen_toast_enter</item>
+ <item name="android:windowExitAnimation">@anim/zen_toast_exit</item>
+ </style>
</resources>
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationControllerImpl.java
index 61ed095..d8d7042 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationControllerImpl.java
@@ -62,7 +62,7 @@ public class LocationControllerImpl extends BroadcastReceiver implements Locatio
IntentFilter filter = new IntentFilter();
filter.addAction(LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION);
- context.registerReceiver(this, filter);
+ context.registerReceiverAsUser(this, UserHandle.ALL, filter, null, null);
mAppOpsManager = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
mStatusBarManager
diff --git a/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java b/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java
index 2b541d3..c1681c7 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java
@@ -78,6 +78,7 @@ public class ZenModePanel extends LinearLayout {
private final Interpolator mFastOutSlowInInterpolator;
private final int mSubheadWarningColor;
private final int mSubheadColor;
+ private final ZenToast mZenToast;
private String mTag = TAG + "/" + Integer.toHexString(System.identityHashCode(this));
@@ -112,6 +113,7 @@ public class ZenModePanel extends LinearLayout {
final Resources res = mContext.getResources();
mSubheadWarningColor = res.getColor(R.color.system_warning_color);
mSubheadColor = res.getColor(R.color.qs_subhead);
+ mZenToast = new ZenToast(mContext);
if (DEBUG) Log.d(mTag, "new ZenModePanel");
}
@@ -155,6 +157,7 @@ public class ZenModePanel extends LinearLayout {
protected void onAttachedToWindow() {
super.onAttachedToWindow();
if (DEBUG) Log.d(mTag, "onAttachedToWindow");
+ mZenToast.hide();
mAttachedZen = getSelectedZen(-1);
mSessionZen = mAttachedZen;
mSessionExitCondition = copy(mExitCondition);
@@ -187,6 +190,10 @@ public class ZenModePanel extends LinearLayout {
if (selectedZen == Global.ZEN_MODE_NO_INTERRUPTIONS) {
mPrefs.trackNoneSelected();
}
+ if (selectedZen == Global.ZEN_MODE_NO_INTERRUPTIONS
+ || selectedZen == Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS) {
+ mZenToast.show(selectedZen);
+ }
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/ZenToast.java b/packages/SystemUI/src/com/android/systemui/volume/ZenToast.java
new file mode 100644
index 0000000..96e2a8e
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/volume/ZenToast.java
@@ -0,0 +1,151 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.volume;
+
+import static android.provider.Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
+import static android.provider.Settings.Global.ZEN_MODE_NO_INTERRUPTIONS;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.res.Resources;
+import android.graphics.PixelFormat;
+import android.os.Handler;
+import android.os.Message;
+import android.os.UserHandle;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.WindowManager;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import com.android.systemui.R;
+
+public class ZenToast {
+ private static final String ACTION_SHOW = ZenToast.class.getName() + ".SHOW";
+ private static final String ACTION_HIDE = ZenToast.class.getName() + ".HIDE";
+ private static final String EXTRA_ZEN = "zen";
+ private static final String EXTRA_TEXT = "text";
+
+ private static final int MSG_SHOW = 1;
+ private static final int MSG_HIDE = 2;
+
+ private final Context mContext;
+ private final WindowManager mWindowManager;
+
+ private View mZenToast;
+
+ public ZenToast(Context context) {
+ mContext = context;
+ mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
+ final IntentFilter filter = new IntentFilter();
+ filter.addAction(ACTION_SHOW);
+ filter.addAction(ACTION_HIDE);
+ mContext.registerReceiverAsUser(mReceiver, UserHandle.ALL, filter, null, mHandler);
+ }
+
+ public void show(int zen) {
+ mHandler.removeMessages(MSG_HIDE);
+ mHandler.removeMessages(MSG_SHOW);
+ mHandler.obtainMessage(MSG_SHOW, zen, 0).sendToTarget();
+ }
+
+ public void hide() {
+ mHandler.removeMessages(MSG_HIDE);
+ mHandler.removeMessages(MSG_SHOW);
+ mHandler.obtainMessage(MSG_HIDE).sendToTarget();
+ }
+
+ private void handleShow(int zen, String overrideText) {
+ handleHide();
+
+ String text;
+ final int iconRes;
+ switch (zen) {
+ case ZEN_MODE_NO_INTERRUPTIONS:
+ text = mContext.getString(R.string.zen_no_interruptions);
+ iconRes = R.drawable.ic_zen_none;
+ break;
+ case ZEN_MODE_IMPORTANT_INTERRUPTIONS:
+ text = mContext.getString(R.string.zen_important_interruptions);
+ iconRes = R.drawable.ic_zen_important;
+ break;
+ default:
+ return;
+ }
+ if (overrideText != null) {
+ text = overrideText;
+ }
+ final Resources res = mContext.getResources();
+ final WindowManager.LayoutParams params = new WindowManager.LayoutParams();
+ params.height = WindowManager.LayoutParams.WRAP_CONTENT;
+ params.width = res.getDimensionPixelSize(R.dimen.zen_toast_width);
+ params.format = PixelFormat.TRANSLUCENT;
+ params.windowAnimations = R.style.ZenToastAnimations;
+ params.type = WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL;
+ params.setTitle(getClass().getSimpleName());
+ params.flags = WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
+ | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
+ | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
+ params.gravity = Gravity.CENTER;
+ params.packageName = mContext.getPackageName();
+ mZenToast = LayoutInflater.from(mContext).inflate(R.layout.zen_toast, null);
+ final TextView message = (TextView) mZenToast.findViewById(android.R.id.message);
+ message.setText(text);
+ final ImageView icon = (ImageView) mZenToast.findViewById(android.R.id.icon);
+ icon.setImageResource(iconRes);
+ mWindowManager.addView(mZenToast, params);
+ final int animDuration = res.getInteger(R.integer.zen_toast_animation_duration);
+ final int visibleDuration = res.getInteger(R.integer.zen_toast_visible_duration);
+ mHandler.sendEmptyMessageDelayed(MSG_HIDE, animDuration + visibleDuration);
+ }
+
+ private void handleHide() {
+ if (mZenToast != null) {
+ mWindowManager.removeView(mZenToast);
+ mZenToast = null;
+ }
+ }
+
+ private final Handler mHandler = new Handler() {
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case MSG_SHOW:
+ handleShow(msg.arg1, null);
+ break;
+ case MSG_HIDE:
+ handleHide();
+ break;
+ }
+ }
+ };
+
+ private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (ACTION_SHOW.equals(intent.getAction())) {
+ final int zen = intent.getIntExtra(EXTRA_ZEN, ZEN_MODE_IMPORTANT_INTERRUPTIONS);
+ final String text = intent.getStringExtra(EXTRA_TEXT);
+ handleShow(zen, text);
+ } else if (ACTION_HIDE.equals(intent.getAction())) {
+ handleHide();
+ }
+ }
+ };
+}
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindow.java b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
index 00026dc..42ee666 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindow.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
@@ -274,6 +274,8 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
private long mBackgroundFadeDurationMillis = -1;
private Boolean mSharedElementsUseOverlay;
+ private Rect mTempRect;
+
static class WindowManagerHolder {
static final IWindowManager sWindowManager = IWindowManager.Stub.asInterface(
ServiceManager.getService("window"));
@@ -2892,37 +2894,53 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
// Show the status guard when the non-overlay contextual action bar is showing
if (mActionModeView != null) {
if (mActionModeView.getLayoutParams() instanceof MarginLayoutParams) {
- MarginLayoutParams mlp = (MarginLayoutParams) mActionModeView.getLayoutParams();
+ // Insets are magic!
+ final MarginLayoutParams mlp = (MarginLayoutParams)
+ mActionModeView.getLayoutParams();
boolean mlpChanged = false;
if (mActionModeView.isShown()) {
- final boolean nonOverlay = (getLocalFeatures()
- & (1 << FEATURE_ACTION_MODE_OVERLAY)) == 0;
- if (mlp.topMargin != insets.getSystemWindowInsetTop()) {
+ if (mTempRect == null) {
+ mTempRect = new Rect();
+ }
+ final Rect rect = mTempRect;
+
+ // If the parent doesn't consume the insets, manually
+ // apply the default system window insets.
+ mContentParent.computeSystemWindowInsets(insets, rect);
+ final int newMargin = rect.top == 0 ? insets.getSystemWindowInsetTop() : 0;
+ if (mlp.topMargin != newMargin) {
mlpChanged = true;
mlp.topMargin = insets.getSystemWindowInsetTop();
- // Only show status guard for non-overlay modes.
- if (nonOverlay) {
- if (mStatusGuard == null) {
- mStatusGuard = new View(mContext);
- mStatusGuard.setBackgroundColor(mContext.getResources()
- .getColor(R.color.input_method_navigation_guard));
- addView(mStatusGuard, indexOfChild(mStatusColorView),
- new LayoutParams(LayoutParams.MATCH_PARENT,
- mlp.topMargin,
- Gravity.START | Gravity.TOP));
- } else {
- LayoutParams lp = (LayoutParams) mStatusGuard.getLayoutParams();
- if (lp.height != mlp.topMargin) {
- lp.height = mlp.topMargin;
- mStatusGuard.setLayoutParams(lp);
- }
+ if (mStatusGuard == null) {
+ mStatusGuard = new View(mContext);
+ mStatusGuard.setBackgroundColor(mContext.getResources()
+ .getColor(R.color.input_method_navigation_guard));
+ addView(mStatusGuard, indexOfChild(mStatusColorView),
+ new LayoutParams(LayoutParams.MATCH_PARENT,
+ mlp.topMargin, Gravity.START | Gravity.TOP));
+ } else {
+ final LayoutParams lp = (LayoutParams)
+ mStatusGuard.getLayoutParams();
+ if (lp.height != mlp.topMargin) {
+ lp.height = mlp.topMargin;
+ mStatusGuard.setLayoutParams(lp);
}
}
}
+
+ // We only need to consume the insets if the action
+ // mode is overlaid on the app content (e.g. it's
+ // sitting in a FrameLayout, see
+ // screen_simple_overlay_action_mode.xml).
+ final boolean nonOverlay = (getLocalFeatures()
+ & (1 << FEATURE_ACTION_MODE_OVERLAY)) == 0;
insets = insets.consumeSystemWindowInsets(
false, nonOverlay /* top */, false, false);
- showStatusGuard = nonOverlay;
+
+ // The action mode's theme may differ from the app, so
+ // always show the status guard above it.
+ showStatusGuard = true;
} else {
// reset top margin
if (mlp.topMargin != 0) {
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
index ac78630..be3fc47 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -759,7 +759,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
}
int getActiveWindowId() {
- return mSecurityPolicy.mActiveWindowId;
+ return mSecurityPolicy.getActiveWindowId();
}
void onTouchInteractionStart() {
@@ -1169,7 +1169,8 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
// No enabled installed services => disable accessibility to avoid
// sending accessibility events with no recipient across processes.
- if (isEnabled && userState.mEnabledServices.isEmpty()) {
+ if (isEnabled && userState.mBoundServices.isEmpty()
+ && userState.mBindingServices.isEmpty()) {
userState.mIsAccessibilityEnabled = false;
Settings.Secure.putIntForUser(mContext.getContentResolver(),
Settings.Secure.ACCESSIBILITY_ENABLED, 0, userState.mUserId);
@@ -2599,6 +2600,9 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
userState.mInstalledServices.remove(mAccessibilityServiceInfo);
userState.mEnabledServices.remove(mComponentName);
userState.destroyUiAutomationService();
+ if (readConfigurationForUserStateLocked(userState)) {
+ onUserStateChangedLocked(userState);
+ }
}
}
}
@@ -2819,7 +2823,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
private int resolveAccessibilityWindowIdLocked(int accessibilityWindowId) {
if (accessibilityWindowId == AccessibilityNodeInfo.ACTIVE_WINDOW_ID) {
- return mSecurityPolicy.mActiveWindowId;
+ return mSecurityPolicy.getActiveWindowId();
}
return accessibilityWindowId;
}
@@ -3280,7 +3284,9 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
public void clearWindowsLocked() {
List<AccessibilityWindowInfo> windows = Collections.emptyList();
+ final int activeWindowId = mActiveWindowId;
updateWindowsLocked(windows);
+ mActiveWindowId = activeWindowId;
mWindows = null;
}
@@ -3493,6 +3499,13 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
}
}
+ public int getActiveWindowId() {
+ if (mActiveWindowId == INVALID_WINDOW_ID && !mTouchInteractionInProgress) {
+ mActiveWindowId = getFocusedWindowId();
+ }
+ return mActiveWindowId;
+ }
+
private void setActiveWindowLocked(int windowId) {
if (mActiveWindowId != windowId) {
mActiveWindowId = windowId;
diff --git a/services/core/java/com/android/server/MasterClearReceiver.java b/services/core/java/com/android/server/MasterClearReceiver.java
index e88bdf8..f1d5aa3 100644
--- a/services/core/java/com/android/server/MasterClearReceiver.java
+++ b/services/core/java/com/android/server/MasterClearReceiver.java
@@ -38,6 +38,7 @@ public class MasterClearReceiver extends BroadcastReceiver {
}
final boolean shutdown = intent.getBooleanExtra("shutdown", false);
+ final String reason = intent.getStringExtra(Intent.EXTRA_REASON);
Slog.w(TAG, "!!! FACTORY RESET !!!");
// The reboot call is blocking, so we need to do it on another thread.
@@ -45,7 +46,7 @@ public class MasterClearReceiver extends BroadcastReceiver {
@Override
public void run() {
try {
- RecoverySystem.rebootWipeUserData(context, shutdown);
+ RecoverySystem.rebootWipeUserData(context, shutdown, reason);
Log.wtf(TAG, "Still running after master clear?!");
} catch (IOException e) {
Slog.e(TAG, "Can't perform master clear/factory reset", e);
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index 8e8e4a6..01e80b7 100755
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -2134,7 +2134,8 @@ public final class ActiveServices {
if (!hasCreate) {
continue;
}
- if (proc != null && !proc.persistent && proc.thread != null
+ // XXX turned off for now until we have more time to get a better policy.
+ if (false && proc != null && !proc.persistent && proc.thread != null
&& proc.pid != 0 && proc.pid != ActivityManagerService.MY_PID
&& proc.setProcState >= ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
proc.kill("bound to service " + sr.name.flattenToShortString()
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index d2e3d25..4d2fd4c 100755
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -4690,8 +4690,8 @@ public final class ActivityManagerService extends ActivityManagerNative
private final void handleAppDiedLocked(ProcessRecord app,
boolean restarting, boolean allowRestart) {
int pid = app.pid;
- cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
- if (!restarting) {
+ boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
+ if (!kept && !restarting) {
removeLruProcessLocked(app);
if (pid > 0) {
ProcessList.remove(pid);
@@ -4816,6 +4816,14 @@ public final class ActivityManagerService extends ActivityManagerNative
}
final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread) {
+ // First check if this ProcessRecord is actually active for the pid.
+ synchronized (mPidsSelfLocked) {
+ ProcessRecord curProc = mPidsSelfLocked.get(pid);
+ if (curProc != app) {
+ Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
+ return;
+ }
+ }
BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
synchronized (stats) {
@@ -4833,7 +4841,7 @@ public final class ActivityManagerService extends ActivityManagerNative
boolean doOomAdj = doLowMem;
if (!app.killedByAm) {
Slog.i(TAG, "Process " + app.processName + " (pid " + pid
- + ") has died.");
+ + ") has died");
mAllowLowerMemLevel = true;
} else {
// Note that we always want to do oom adj to update our state with the
@@ -14310,8 +14318,11 @@ public final class ActivityManagerService extends ActivityManagerNative
* Main code for cleaning up a process when it has gone away. This is
* called both as a result of the process dying, or directly when stopping
* a process when running in single process mode.
+ *
+ * @return Returns true if the given process has been restarted, so the
+ * app that was passed in must remain on the process lists.
*/
- private final void cleanUpApplicationRecordLocked(ProcessRecord app,
+ private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
boolean restarting, boolean allowRestart, int index) {
if (index >= 0) {
removeLruProcessLocked(app);
@@ -14434,7 +14445,7 @@ public final class ActivityManagerService extends ActivityManagerNative
// If the caller is restarting this app, then leave it in its
// current lists and let the caller take care of it.
if (restarting) {
- return;
+ return false;
}
if (!app.persistent || app.isolated) {
@@ -14470,8 +14481,12 @@ public final class ActivityManagerService extends ActivityManagerNative
if (restart && !app.isolated) {
// We have components that still need to be running in the
// process, so re-launch it.
+ if (index < 0) {
+ ProcessList.remove(app.pid);
+ }
mProcessNames.put(app.processName, app.uid, app);
startProcessLocked(app, "restart", app.processName);
+ return true;
} else if (app.pid > 0 && app.pid != MY_PID) {
// Goodbye!
boolean removed;
@@ -14485,6 +14500,7 @@ public final class ActivityManagerService extends ActivityManagerNative
}
app.setPid(0);
}
+ return false;
}
boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
diff --git a/services/core/java/com/android/server/input/InputManagerService.java b/services/core/java/com/android/server/input/InputManagerService.java
index 7f89947..15dcd44 100644
--- a/services/core/java/com/android/server/input/InputManagerService.java
+++ b/services/core/java/com/android/server/input/InputManagerService.java
@@ -695,6 +695,8 @@ public class InputManagerService extends IInputManager.Stub
final int numFullKeyboards = mTempFullKeyboards.size();
boolean missingLayoutForExternalKeyboard = false;
boolean missingLayoutForExternalKeyboardAdded = false;
+ boolean multipleMissingLayoutsForExternalKeyboardsAdded = false;
+ InputDevice keyboardMissingLayout = null;
synchronized (mDataStore) {
for (int i = 0; i < numFullKeyboards; i++) {
final InputDevice inputDevice = mTempFullKeyboards.get(i);
@@ -704,13 +706,25 @@ public class InputManagerService extends IInputManager.Stub
missingLayoutForExternalKeyboard = true;
if (i < numFullKeyboardsAdded) {
missingLayoutForExternalKeyboardAdded = true;
+ if (keyboardMissingLayout == null) {
+ keyboardMissingLayout = inputDevice;
+ } else {
+ multipleMissingLayoutsForExternalKeyboardsAdded = true;
+ }
}
}
}
}
if (missingLayoutForExternalKeyboard) {
if (missingLayoutForExternalKeyboardAdded) {
- showMissingKeyboardLayoutNotification();
+ if (multipleMissingLayoutsForExternalKeyboardsAdded) {
+ // We have more than one keyboard missing a layout, so drop the
+ // user at the generic input methods page so they can pick which
+ // one to set.
+ showMissingKeyboardLayoutNotification(null);
+ } else {
+ showMissingKeyboardLayoutNotification(keyboardMissingLayout);
+ }
}
} else if (mKeyboardLayoutNotificationShown) {
hideMissingKeyboardLayoutNotification();
@@ -761,16 +775,17 @@ public class InputManagerService extends IInputManager.Stub
}
// Must be called on handler.
- private void showMissingKeyboardLayoutNotification() {
+ private void showMissingKeyboardLayoutNotification(InputDevice device) {
if (!mKeyboardLayoutNotificationShown) {
- if (mKeyboardLayoutIntent == null) {
- final Intent intent = new Intent("android.settings.INPUT_METHOD_SETTINGS");
- intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
- | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
- | Intent.FLAG_ACTIVITY_CLEAR_TOP);
- mKeyboardLayoutIntent = PendingIntent.getActivityAsUser(mContext, 0,
- intent, 0, null, UserHandle.CURRENT);
+ final Intent intent = new Intent(Settings.ACTION_INPUT_METHOD_SETTINGS);
+ if (device != null) {
+ intent.putExtra(Settings.EXTRA_INPUT_DEVICE_IDENTIFIER, device.getIdentifier());
}
+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
+ | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
+ | Intent.FLAG_ACTIVITY_CLEAR_TOP);
+ final PendingIntent keyboardLayoutIntent = PendingIntent.getActivityAsUser(mContext, 0,
+ intent, 0, null, UserHandle.CURRENT);
Resources r = mContext.getResources();
Notification notification = new Notification.Builder(mContext)
@@ -778,7 +793,7 @@ public class InputManagerService extends IInputManager.Stub
R.string.select_keyboard_layout_notification_title))
.setContentText(r.getString(
R.string.select_keyboard_layout_notification_message))
- .setContentIntent(mKeyboardLayoutIntent)
+ .setContentIntent(keyboardLayoutIntent)
.setSmallIcon(R.drawable.ic_settings_language)
.setPriority(Notification.PRIORITY_LOW)
.setColor(mContext.getResources().getColor(
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 2829e2b..d8e5a98 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -154,6 +154,16 @@ public class NotificationManagerService extends SystemService {
static final boolean ENABLE_BLOCKED_NOTIFICATIONS = true;
static final boolean ENABLE_BLOCKED_TOASTS = true;
+ // When #matchesCallFilter is called from the ringer, wait at most
+ // 3s to resolve the contacts. This timeout is required since
+ // ContactsProvider might take a long time to start up.
+ //
+ // Return STARRED_CONTACT when the timeout is hit in order to avoid
+ // missed calls in ZEN mode "Important".
+ static final int MATCHES_CALL_FILTER_CONTACTS_TIMEOUT_MS = 3000;
+ static final float MATCHES_CALL_FILTER_TIMEOUT_AFFINITY =
+ ValidateNotificationPeople.STARRED_CONTACT;
+
private IActivityManager mAm;
AudioManager mAudioManager;
StatusBarManagerInternal mStatusBar;
@@ -1474,8 +1484,12 @@ public class NotificationManagerService extends SystemService {
@Override
public boolean matchesCallFilter(Bundle extras) {
enforceSystemOrSystemUI("INotificationManager.matchesCallFilter");
- return mZenModeHelper.matchesCallFilter(UserHandle.getCallingUserHandle(), extras,
- mRankingHelper.findExtractor(ValidateNotificationPeople.class));
+ return mZenModeHelper.matchesCallFilter(
+ UserHandle.getCallingUserHandle(),
+ extras,
+ mRankingHelper.findExtractor(ValidateNotificationPeople.class),
+ MATCHES_CALL_FILTER_CONTACTS_TIMEOUT_MS,
+ MATCHES_CALL_FILTER_TIMEOUT_AFFINITY);
}
};
diff --git a/services/core/java/com/android/server/notification/ValidateNotificationPeople.java b/services/core/java/com/android/server/notification/ValidateNotificationPeople.java
index 1c1a034..6e2a8ad 100644
--- a/services/core/java/com/android/server/notification/ValidateNotificationPeople.java
+++ b/services/core/java/com/android/server/notification/ValidateNotificationPeople.java
@@ -22,6 +22,7 @@ import android.content.pm.PackageManager;
import android.database.ContentObserver;
import android.database.Cursor;
import android.net.Uri;
+import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.UserHandle;
@@ -37,6 +38,8 @@ import android.util.Slog;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Map;
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
/**
* This {@link NotificationSignalExtractor} attempts to validate
@@ -45,9 +48,10 @@ import java.util.Map;
* {@hide}
*/
public class ValidateNotificationPeople implements NotificationSignalExtractor {
- private static final String TAG = "ValidateNotificationPeople";
+ // Using a shorter log tag since setprop has a limit of 32chars on variable name.
+ private static final String TAG = "ValidateNoPeople";
private static final boolean INFO = true;
- private static final boolean DEBUG = false;
+ private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
private static final boolean ENABLE_PEOPLE_VALIDATOR = true;
private static final String SETTING_ENABLE_PEOPLE_VALIDATOR =
@@ -132,7 +136,14 @@ public class ValidateNotificationPeople implements NotificationSignalExtractor {
// ignore: config has no relevant information yet.
}
- public float getContactAffinity(UserHandle userHandle, Bundle extras) {
+ /**
+ * @param extras extras of the notification with EXTRA_PEOPLE populated
+ * @param timeoutMs timeout in milliseconds to wait for contacts response
+ * @param timeoutAffinity affinity to return when the timeout specified via
+ * <code>timeoutMs</code> is hit
+ */
+ public float getContactAffinity(UserHandle userHandle, Bundle extras, int timeoutMs,
+ float timeoutAffinity) {
if (DEBUG) Slog.d(TAG, "checking affinity for " + userHandle);
if (extras == null) return NONE;
final String key = Long.toString(System.nanoTime());
@@ -143,8 +154,31 @@ public class ValidateNotificationPeople implements NotificationSignalExtractor {
}
final PeopleRankingReconsideration prr = validatePeople(context, key, extras, affinityOut);
float affinity = affinityOut[0];
+
if (prr != null) {
- prr.work();
+ // Perform the heavy work on a background thread so we can abort when we hit the
+ // timeout.
+ final Semaphore s = new Semaphore(0);
+ AsyncTask.THREAD_POOL_EXECUTOR.execute(new Runnable() {
+ @Override
+ public void run() {
+ prr.work();
+ s.release();
+ }
+ });
+
+ try {
+ if (!s.tryAcquire(timeoutMs, TimeUnit.MILLISECONDS)) {
+ Slog.w(TAG, "Timeout while waiting for affinity: " + key + ". "
+ + "Returning timeoutAffinity=" + timeoutAffinity);
+ return timeoutAffinity;
+ }
+ } catch (InterruptedException e) {
+ Slog.w(TAG, "InterruptedException while waiting for affinity: " + key + ". "
+ + "Returning affinity=" + affinity, e);
+ return affinity;
+ }
+
affinity = Math.max(prr.getContactAffinity(), affinity);
}
return affinity;
@@ -391,6 +425,7 @@ public class ValidateNotificationPeople implements NotificationSignalExtractor {
@Override
public void work() {
if (INFO) Slog.i(TAG, "Executing: validation for: " + mKey);
+ long timeStartMs = System.currentTimeMillis();
for (final String handle: mPendingLookups) {
LookupResult lookupResult = null;
final Uri uri = Uri.parse(handle);
@@ -415,6 +450,10 @@ public class ValidateNotificationPeople implements NotificationSignalExtractor {
mContactAffinity = Math.max(mContactAffinity, lookupResult.getAffinity());
}
}
+ if (DEBUG) {
+ Slog.d(TAG, "Validation finished in " + (System.currentTimeMillis() - timeStartMs) +
+ "ms");
+ }
}
@Override
diff --git a/services/core/java/com/android/server/notification/ZenModeHelper.java b/services/core/java/com/android/server/notification/ZenModeHelper.java
index 5038d03..557a44e 100644
--- a/services/core/java/com/android/server/notification/ZenModeHelper.java
+++ b/services/core/java/com/android/server/notification/ZenModeHelper.java
@@ -376,14 +376,21 @@ public class ZenModeHelper {
return record.isCategory(Notification.CATEGORY_MESSAGE) || isDefaultMessagingApp(record);
}
+ /**
+ * @param extras extras of the notification with EXTRA_PEOPLE populated
+ * @param contactsTimeoutMs timeout in milliseconds to wait for contacts response
+ * @param timeoutAffinity affinity to return when the timeout specified via
+ * <code>contactsTimeoutMs</code> is hit
+ */
public boolean matchesCallFilter(UserHandle userHandle, Bundle extras,
- ValidateNotificationPeople validator) {
+ ValidateNotificationPeople validator, int contactsTimeoutMs, float timeoutAffinity) {
final int zen = mZenMode;
if (zen == Global.ZEN_MODE_NO_INTERRUPTIONS) return false; // nothing gets through
if (zen == Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS) {
if (!mConfig.allowCalls) return false; // no calls get through
if (validator != null) {
- final float contactAffinity = validator.getContactAffinity(userHandle, extras);
+ final float contactAffinity = validator.getContactAffinity(userHandle, extras,
+ contactsTimeoutMs, timeoutAffinity);
return audienceMatches(contactAffinity);
}
}
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DeviceOwner.java b/services/devicepolicy/java/com/android/server/devicepolicy/DeviceOwner.java
index 5938819..9fd0e09 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DeviceOwner.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DeviceOwner.java
@@ -229,11 +229,20 @@ public class DeviceOwner {
String profileOwnerComponentStr =
parser.getAttributeValue(null, ATTR_COMPONENT_NAME);
int userId = Integer.parseInt(parser.getAttributeValue(null, ATTR_USERID));
- OwnerInfo profileOwnerInfo;
+ OwnerInfo profileOwnerInfo = null;
if (profileOwnerComponentStr != null) {
- profileOwnerInfo = new OwnerInfo(profileOwnerName,
- ComponentName.unflattenFromString(profileOwnerComponentStr));
- } else {
+ ComponentName admin = ComponentName.unflattenFromString(
+ profileOwnerComponentStr);
+ if (admin != null) {
+ profileOwnerInfo = new OwnerInfo(profileOwnerName, admin);
+ } else {
+ // This shouldn't happen but switch from package name -> component name
+ // might have written bad device owner files. b/17652534
+ Slog.e(TAG, "Error parsing device-owner file. Bad component name " +
+ profileOwnerComponentStr);
+ }
+ }
+ if (profileOwnerInfo == null) {
profileOwnerInfo = new OwnerInfo(profileOwnerName, profileOwnerPackageName);
}
mProfileOwners.put(userId, profileOwnerInfo);
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 59d3dc8..d1aba3c 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -2862,7 +2862,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
return false;
}
- void wipeDataLocked(int flags) {
+ void wipeDataLocked(int flags, String reason) {
// If the SD card is encrypted and non-removable, we have to force a wipe.
boolean forceExtWipe = !Environment.isExternalStorageRemovable() && isExtStorageEncrypted();
boolean wipeExtRequested = (flags&DevicePolicyManager.WIPE_EXTERNAL_STORAGE) != 0;
@@ -2871,12 +2871,13 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
if ((forceExtWipe || wipeExtRequested) && !Environment.isExternalStorageEmulated()) {
Intent intent = new Intent(ExternalStorageFormatter.FORMAT_AND_FACTORY_RESET);
intent.putExtra(ExternalStorageFormatter.EXTRA_ALWAYS_RESET, true);
+ intent.putExtra(Intent.EXTRA_REASON, reason);
intent.setComponent(ExternalStorageFormatter.COMPONENT_NAME);
mWakeLock.acquire(10000);
mContext.startService(intent);
} else {
try {
- RecoverySystem.rebootWipeUserData(mContext);
+ RecoverySystem.rebootWipeUserData(mContext, reason);
} catch (IOException e) {
Slog.w(LOG_TAG, "Failed requesting data wipe", e);
} catch (SecurityException e) {
@@ -2885,6 +2886,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
}
}
+ @Override
public void wipeData(int flags, final int userHandle) {
if (!mHasFeature) {
return;
@@ -2896,20 +2898,34 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
synchronized (this) {
// This API can only be called by an active device admin,
// so try to retrieve it to check that the caller is one.
- getActiveAdminForCallerLocked(null,
+ final ActiveAdmin admin = getActiveAdminForCallerLocked(null,
DeviceAdminInfo.USES_POLICY_WIPE_DATA);
+
+ final String source;
+ if (admin != null && admin.info != null) {
+ final ComponentName cname = admin.info.getComponent();
+ if (cname != null) {
+ source = cname.flattenToShortString();
+ } else {
+ source = admin.info.getPackageName();
+ }
+ } else {
+ source = "?";
+ }
+
long ident = Binder.clearCallingIdentity();
try {
- wipeDeviceOrUserLocked(flags, userHandle);
+ wipeDeviceOrUserLocked(flags, userHandle,
+ "DevicePolicyManager.wipeData() from " + source);
} finally {
Binder.restoreCallingIdentity(ident);
}
}
}
- private void wipeDeviceOrUserLocked(int flags, final int userHandle) {
+ private void wipeDeviceOrUserLocked(int flags, final int userHandle, String reason) {
if (userHandle == UserHandle.USER_OWNER) {
- wipeDataLocked(flags);
+ wipeDataLocked(flags, reason);
} else {
mHandler.post(new Runnable() {
public void run() {
@@ -3061,7 +3077,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
}
if (wipeData) {
// Call without holding lock.
- wipeDeviceOrUserLocked(0, identifier);
+ wipeDeviceOrUserLocked(0, identifier, "reportFailedPasswordAttempt()");
}
} finally {
Binder.restoreCallingIdentity(ident);
diff --git a/telecomm/java/android/telecom/PhoneAccount.java b/telecomm/java/android/telecom/PhoneAccount.java
index ffe787a..1d6d8bc 100644
--- a/telecomm/java/android/telecom/PhoneAccount.java
+++ b/telecomm/java/android/telecom/PhoneAccount.java
@@ -286,9 +286,6 @@ public class PhoneAccount implements Parcelable {
* The raw callback number used for this {@code PhoneAccount}, as distinct from
* {@link #getAddress()}. For the majority of {@code PhoneAccount}s this should be registered
* as {@code null}. It is used by the system for SIM-based {@code PhoneAccount} registration
- * where {@link android.telephony.TelephonyManager#setLine1NumberForDisplay(String, String)}
- * has been used to alter the callback number.
- * <p>
*
* @return The subscription number, suitable for display to the user.
*/
diff --git a/telecomm/java/android/telecom/RemoteConference.java b/telecomm/java/android/telecom/RemoteConference.java
index 796725b..b18cb96 100644
--- a/telecomm/java/android/telecom/RemoteConference.java
+++ b/telecomm/java/android/telecom/RemoteConference.java
@@ -166,6 +166,20 @@ public final class RemoteConference {
}
}
+ public void merge() {
+ try {
+ mConnectionService.mergeConference(mId);
+ } catch (RemoteException e) {
+ }
+ }
+
+ public void swap() {
+ try {
+ mConnectionService.swapConference(mId);
+ } catch (RemoteException e) {
+ }
+ }
+
public void hold() {
try {
mConnectionService.hold(mId);
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 34b1454..6ba151f 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -1746,6 +1746,7 @@ public class TelephonyManager {
*
* @param alphaTag alpha-tagging of the dailing nubmer
* @param number The dialing number
+ * @hide
*/
public void setLine1NumberForDisplay(String alphaTag, String number) {
setLine1NumberForDisplayForSubscriber(getDefaultSubscription(), alphaTag, number);
@@ -2381,7 +2382,6 @@ public class TelephonyManager {
*
* <p>Requires Permission:
* {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}
- * Or the calling app has carrier privileges. @see #hasCarrierPrivileges
*
* @param AID Application id. See ETSI 102.221 and 101.220.
* @return an IccOpenLogicalChannelResponse object.
@@ -2402,7 +2402,6 @@ public class TelephonyManager {
*
* <p>Requires Permission:
* {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}
- * Or the calling app has carrier privileges. @see #hasCarrierPrivileges
*
* @param channel is the channel id to be closed as retruned by a successful
* iccOpenLogicalChannel.
@@ -2424,7 +2423,6 @@ public class TelephonyManager {
*
* <p>Requires Permission:
* {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}
- * Or the calling app has carrier privileges. @see #hasCarrierPrivileges
*
* @param channel is the channel id to be closed as returned by a successful
* iccOpenLogicalChannel.
@@ -2456,7 +2454,6 @@ public class TelephonyManager {
*
* <p>Requires Permission:
* {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}
- * Or the calling app has carrier privileges. @see #hasCarrierPrivileges
*
* @param cla Class of the APDU command.
* @param instruction Instruction of the APDU command.
@@ -2484,7 +2481,6 @@ public class TelephonyManager {
*
* <p>Requires Permission:
* {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}
- * Or the calling app has carrier privileges. @see #hasCarrierPrivileges
*
* @param fileID
* @param command
@@ -2510,7 +2506,6 @@ public class TelephonyManager {
*
* <p>Requires Permission:
* {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}
- * Or the calling app has carrier privileges. @see #hasCarrierPrivileges
*
* @param content String containing SAT/USAT response in hexadecimal
* format starting with command tag. See TS 102 223 for
@@ -2960,6 +2955,7 @@ public class TelephonyManager {
* Or the calling app has carrier privileges. @see #hasCarrierPrivileges
*
* @return true on success; false on any failure.
+ * @hide
*/
public boolean setGlobalPreferredNetworkType() {
return setPreferredNetworkType(RILConstants.NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA);
@@ -2967,10 +2963,23 @@ public class TelephonyManager {
/**
* Values used to return status for hasCarrierPrivileges call.
+ * @hide
*/
public static final int CARRIER_PRIVILEGE_STATUS_HAS_ACCESS = 1;
+ /**
+ * Values used to return status for hasCarrierPrivileges call.
+ * @hide
+ */
public static final int CARRIER_PRIVILEGE_STATUS_NO_ACCESS = 0;
+ /**
+ * Values used to return status for hasCarrierPrivileges call.
+ * @hide
+ */
public static final int CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED = -1;
+ /**
+ * Values used to return status for hasCarrierPrivileges call.
+ * @hide
+ */
public static final int CARRIER_PRIVILEGE_STATUS_ERROR_LOADING_RULES = -2;
/**
@@ -2987,6 +2996,7 @@ public class TelephonyManager {
* CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED if the carrier rules are not loaded.
* CARRIER_PRIVILEGE_STATUS_ERROR_LOADING_RULES if there was an error loading carrier
* rules (or if there are no rules).
+ * @hide
*/
public int hasCarrierPrivileges() {
try {
@@ -3013,6 +3023,7 @@ public class TelephonyManager {
*
* @param brand The brand name to display/set.
* @return true if the operation was executed correctly.
+ * @hide
*/
public boolean setOperatorBrandOverride(String brand) {
try {
diff --git a/tests/OneMedia/src/com/android/onemedia/PlayerSession.java b/tests/OneMedia/src/com/android/onemedia/PlayerSession.java
index 8b7c883..2455c9c 100644
--- a/tests/OneMedia/src/com/android/onemedia/PlayerSession.java
+++ b/tests/OneMedia/src/com/android/onemedia/PlayerSession.java
@@ -20,6 +20,7 @@ import android.content.Intent;
import android.graphics.Bitmap;
import android.media.MediaMetadata;
import android.media.session.MediaSession;
+import android.media.session.MediaSession.QueueItem;
import android.media.session.MediaSessionManager;
import android.media.session.PlaybackState;
import android.os.Bundle;
@@ -44,6 +45,8 @@ public class PlayerSession {
protected MediaSession.Callback mCallback;
protected Renderer.Listener mRenderListener;
protected MediaMetadata.Builder mMetadataBuilder;
+ protected ArrayList<MediaSession.QueueItem> mQueue;
+ protected boolean mUseQueue;
protected PlaybackState mPlaybackState;
protected Listener mListener;
@@ -58,6 +61,7 @@ public class PlayerSession {
PlaybackState.Builder psBob = new PlaybackState.Builder();
psBob.setActions(PlaybackState.ACTION_PAUSE | PlaybackState.ACTION_PLAY);
mPlaybackState = psBob.build();
+ mQueue = new ArrayList<MediaSession.QueueItem>();
mRenderer.registerListener(mRenderListener);
@@ -114,6 +118,8 @@ public class PlayerSession {
public void setIcon(Bitmap icon) {
mMetadataBuilder.putBitmap(MediaMetadata.METADATA_KEY_DISPLAY_ICON, icon);
+ mQueue.clear();
+ mQueue.add(new QueueItem(mMetadataBuilder.build().getDescription(), 11));
updateMetadata();
}
@@ -122,6 +128,10 @@ public class PlayerSession {
// code
if (mSession != null && mSession.isActive()) {
mSession.setMetadata(mMetadataBuilder.build());
+ // Just toggle the queue every time we update for testing
+ mSession.setQueue(mUseQueue ? mQueue : null);
+ mSession.setQueueTitle(mUseQueue ? "Queue title" : null);
+ mUseQueue = !mUseQueue;
}
}
@@ -141,6 +151,8 @@ public class PlayerSession {
"OneMedia display title");
mMetadataBuilder.putString(MediaMetadata.METADATA_KEY_DISPLAY_SUBTITLE,
"OneMedia display subtitle");
+
+ mQueue.add(new QueueItem(mMetadataBuilder.build().getDescription(), 11));
}
public interface Listener {
diff --git a/tests/VectorDrawableTest/AndroidManifest.xml b/tests/VectorDrawableTest/AndroidManifest.xml
index 4c835ec..7796953 100644
--- a/tests/VectorDrawableTest/AndroidManifest.xml
+++ b/tests/VectorDrawableTest/AndroidManifest.xml
@@ -99,6 +99,15 @@
</intent-filter>
</activity>
<activity
+ android:name="AnimatedVectorDrawableDupPerf"
+ android:label="Animated Vector Performance of clones" >
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+
+ <category android:name="com.android.test.dynamic.TEST" />
+ </intent-filter>
+ </activity>
+ <activity
android:name="VectorDrawableStaticPerf"
android:label="System icons" >
<intent-filter>
diff --git a/tests/VectorDrawableTest/res/drawable/vector_drawable24.xml b/tests/VectorDrawableTest/res/drawable/vector_drawable24.xml
index 5c1ccaa..f0b4699 100644
--- a/tests/VectorDrawableTest/res/drawable/vector_drawable24.xml
+++ b/tests/VectorDrawableTest/res/drawable/vector_drawable24.xml
@@ -19,8 +19,7 @@
android:viewportHeight="400"
android:viewportWidth="400" >
- <group android:name="backgroundGroup"
- android:alpha = "0.5" >
+ <group android:name="backgroundGroup">
<path
android:name="background1"
android:fillColor="#FF000000"
@@ -33,8 +32,7 @@
<group
android:name="translateToCenterGroup"
android:translateX="50.0"
- android:translateY="90.0"
- android:alpha = "0.5" >
+ android:translateY="90.0" >
<path
android:name="twoLines"
android:pathData="@string/twoLinePathData"
@@ -45,8 +43,7 @@
android:name="rotationGroup"
android:pivotX="0.0"
android:pivotY="0.0"
- android:rotation="-45.0"
- android:alpha = "0.5" >
+ android:rotation="-45.0">
<path
android:name="twoLines1"
android:pathData="@string/twoLinePathData"
@@ -56,8 +53,7 @@
<group
android:name="translateGroup"
android:translateX="130.0"
- android:translateY="160.0"
- android:alpha = "0.5">
+ android:translateY="160.0">
<group android:name="scaleGroup" >
<path
android:name="twoLines3"
@@ -70,8 +66,7 @@
<group
android:name="translateGroupHalf"
android:translateX="65.0"
- android:translateY="80.0"
- android:alpha = "0.5">
+ android:translateY="80.0">
<group android:name="scaleGroup" >
<path
android:name="twoLines2"
diff --git a/tests/VectorDrawableTest/res/drawable/vector_drawable25.xml b/tests/VectorDrawableTest/res/drawable/vector_drawable25.xml
index 069a531..f46d14e 100644
--- a/tests/VectorDrawableTest/res/drawable/vector_drawable25.xml
+++ b/tests/VectorDrawableTest/res/drawable/vector_drawable25.xml
@@ -21,12 +21,10 @@
<group
android:name="FirstLevelGroup"
- android:alpha="0.9"
android:translateX="100.0"
android:translateY="0.0" >
<group
android:name="SecondLevelGroup1"
- android:alpha="0.9"
android:translateX="-100.0"
android:translateY="50.0" >
<path
@@ -35,7 +33,6 @@
<group
android:name="ThridLevelGroup1"
- android:alpha="0.9"
android:translateX="-100.0"
android:translateY="50.0" >
<path
@@ -44,7 +41,6 @@
</group>
<group
android:name="ThridLevelGroup2"
- android:alpha="0.8"
android:translateX="100.0"
android:translateY="50.0" >
<path
@@ -54,7 +50,6 @@
</group>
<group
android:name="SecondLevelGroup2"
- android:alpha="0.8"
android:translateX="100.0"
android:translateY="50.0" >
<path
@@ -63,7 +58,6 @@
<group
android:name="ThridLevelGroup3"
- android:alpha="0.9"
android:translateX="-100.0"
android:translateY="50.0" >
<path
@@ -72,7 +66,6 @@
</group>
<group
android:name="ThridLevelGroup4"
- android:alpha="0.8"
android:translateX="100.0"
android:translateY="50.0" >
<path
diff --git a/tests/VectorDrawableTest/src/com/android/test/dynamic/AnimatedVectorDrawableDupPerf.java b/tests/VectorDrawableTest/src/com/android/test/dynamic/AnimatedVectorDrawableDupPerf.java
new file mode 100644
index 0000000..047e494
--- /dev/null
+++ b/tests/VectorDrawableTest/src/com/android/test/dynamic/AnimatedVectorDrawableDupPerf.java
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.android.test.dynamic;
+
+import android.app.Activity;
+import android.content.res.Resources;
+import android.graphics.drawable.AnimatedVectorDrawable;
+import android.graphics.drawable.VectorDrawable;
+import android.os.Bundle;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.util.Xml;
+import android.widget.Button;
+import android.widget.GridLayout;
+import android.widget.ScrollView;
+import android.widget.TextView;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.IOException;
+import java.text.DecimalFormat;
+
+
+@SuppressWarnings({"UnusedDeclaration"})
+public class AnimatedVectorDrawableDupPerf extends Activity {
+
+ private static final String LOGTAG = "AnimatedVectorDrawableDupPerf";
+ protected int[] icon = {
+ R.drawable.animation_vector_linear_progress_bar,
+ R.drawable.animation_vector_linear_progress_bar,
+ R.drawable.animation_vector_linear_progress_bar,
+ R.drawable.animation_vector_linear_progress_bar,
+ R.drawable.animation_vector_linear_progress_bar,
+ R.drawable.animation_vector_linear_progress_bar,
+ R.drawable.animation_vector_linear_progress_bar,
+ R.drawable.animation_vector_linear_progress_bar,
+ R.drawable.animation_vector_linear_progress_bar,
+ R.drawable.animation_vector_linear_progress_bar,
+ R.drawable.animation_vector_linear_progress_bar,
+ R.drawable.animation_vector_linear_progress_bar,
+ R.drawable.animation_vector_linear_progress_bar,
+ R.drawable.animation_vector_linear_progress_bar,
+ R.drawable.animation_vector_linear_progress_bar,
+ R.drawable.animation_vector_linear_progress_bar,
+ R.drawable.animation_vector_linear_progress_bar,
+ R.drawable.animation_vector_linear_progress_bar,
+ R.drawable.animation_vector_linear_progress_bar,
+ R.drawable.animation_vector_linear_progress_bar,
+ };
+
+ /** @hide */
+ public static AnimatedVectorDrawable create(Resources resources, int rid) {
+ try {
+ final XmlPullParser parser = resources.getXml(rid);
+ final AttributeSet attrs = Xml.asAttributeSet(parser);
+ int type;
+ while ((type=parser.next()) != XmlPullParser.START_TAG &&
+ type != XmlPullParser.END_DOCUMENT) {
+ // Empty loop
+ }
+ if (type != XmlPullParser.START_TAG) {
+ throw new XmlPullParserException("No start tag found");
+ }
+
+ final AnimatedVectorDrawable drawable = new AnimatedVectorDrawable();
+ drawable.inflate(resources, parser, attrs);
+
+ return drawable;
+ } catch (XmlPullParserException e) {
+ Log.e(LOGTAG, "parser error", e);
+ } catch (IOException e) {
+ Log.e(LOGTAG, "parser error", e);
+ }
+ return null;
+ }
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ ScrollView scrollView = new ScrollView(this);
+ GridLayout container = new GridLayout(this);
+ scrollView.addView(container);
+ container.setColumnCount(5);
+ Resources res = this.getResources();
+ container.setBackgroundColor(0xFF888888);
+ AnimatedVectorDrawable []d = new AnimatedVectorDrawable[icon.length];
+ long time = android.os.SystemClock.elapsedRealtimeNanos();
+ for (int i = 0; i < icon.length; i++) {
+ d[i] = create(res,icon[i]);
+ }
+ time = android.os.SystemClock.elapsedRealtimeNanos()-time;
+ TextView t = new TextView(this);
+ DecimalFormat df = new DecimalFormat("#.##");
+ t.setText("avgL=" + df.format(time / (icon.length * 1000000.)) + " ms");
+ container.addView(t);
+ time = android.os.SystemClock.elapsedRealtimeNanos();
+ for (int i = 0; i < icon.length; i++) {
+ Button button = new Button(this);
+ button.setWidth(200);
+ button.setBackgroundResource(icon[i]);
+ container.addView(button);
+ }
+ setContentView(scrollView);
+ time = android.os.SystemClock.elapsedRealtimeNanos()-time;
+ t = new TextView(this);
+ t.setText("avgS=" + df.format(time / (icon.length * 1000000.)) + " ms");
+ container.addView(t);
+ }
+
+}
diff --git a/tools/aapt/ResourceTable.cpp b/tools/aapt/ResourceTable.cpp
index b8c3454..77d3beb 100644
--- a/tools/aapt/ResourceTable.cpp
+++ b/tools/aapt/ResourceTable.cpp
@@ -3310,6 +3310,19 @@ ResourceTable::Entry::Entry(const Entry& entry)
, mParentId(entry.mParentId)
, mPos(entry.mPos) {}
+ResourceTable::Entry& ResourceTable::Entry::operator=(const Entry& entry) {
+ mName = entry.mName;
+ mParent = entry.mParent;
+ mType = entry.mType;
+ mItem = entry.mItem;
+ mItemFormat = entry.mItemFormat;
+ mBag = entry.mBag;
+ mNameIndex = entry.mNameIndex;
+ mParentId = entry.mParentId;
+ mPos = entry.mPos;
+ return *this;
+}
+
status_t ResourceTable::Entry::makeItABag(const SourcePos& sourcePos)
{
if (mType == TYPE_BAG) {
@@ -4352,7 +4365,11 @@ status_t ResourceTable::modifyForCompat(const Bundle* bundle) {
String8(entriesToAdd[i].value->getName()).string(),
entriesToAdd[i].key.toString().string());
- c->addEntry(entriesToAdd[i].key, entriesToAdd[i].value);
+ sp<Entry> newEntry = t->getEntry(c->getName(),
+ entriesToAdd[i].value->getPos(),
+ &entriesToAdd[i].key);
+
+ *newEntry = *entriesToAdd[i].value;
}
}
}
diff --git a/tools/aapt/ResourceTable.h b/tools/aapt/ResourceTable.h
index c548a85..eac5dd3 100644
--- a/tools/aapt/ResourceTable.h
+++ b/tools/aapt/ResourceTable.h
@@ -316,6 +316,7 @@ public:
{ }
Entry(const Entry& entry);
+ Entry& operator=(const Entry& entry);
virtual ~Entry() { }