diff options
51 files changed, 762 insertions, 153 deletions
diff --git a/api/current.txt b/api/current.txt index 1ad58c4acf91..eb7891a607d5 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"; @@ -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 e659b2bfe2ad..08923119823d 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 ba1c507d778c..72cd62b150a6 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 b37f896c6c42..6a8fb05da98b 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/hardware/camera2/legacy/CameraDeviceUserShim.java b/core/java/android/hardware/camera2/legacy/CameraDeviceUserShim.java index e19f58757b76..fcf172c47ec4 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/RequestThreadManager.java b/core/java/android/hardware/camera2/legacy/RequestThreadManager.java index a9981d8952cb..a7ea89cab303 100644 --- a/core/java/android/hardware/camera2/legacy/RequestThreadManager.java +++ b/core/java/android/hardware/camera2/legacy/RequestThreadManager.java @@ -195,12 +195,12 @@ 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 (LegacyCameraDevice.containsSurfaceId(s, mJpegSurfaceIds)) { @@ -328,6 +328,7 @@ public class RequestThreadManager { resetJpegSurfaceFormats(mCallbackOutputs); mPreviewOutputs.clear(); mCallbackOutputs.clear(); + mJpegSurfaceIds.clear(); mPreviewTexture = null; int facing = mCharacteristics.get(CameraCharacteristics.LENS_FACING); @@ -356,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); @@ -780,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); diff --git a/core/java/android/os/Binder.java b/core/java/android/os/Binder.java index ba716052d8fc..362afba6006f 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/provider/Settings.java b/core/java/android/provider/Settings.java index 440b1ecbd9a7..ec4a53e656ab 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 b22fd9c9b621..35fff7407a21 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/view/AccessibilityInteractionController.java b/core/java/android/view/AccessibilityInteractionController.java index a283b91fb686..baa133d7e6c8 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 08160c8976a1..dffcca4152ba 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 2b8b4dce72a3..043916840fad 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 22600de1283d..5685ad757e07 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/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java index 71607244bb6b..85b58aa37fa8 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_util_Binder.cpp b/core/jni/android_util_Binder.cpp index 81e887de781e..2dbd382e70e5 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/strings.xml b/core/res/res/values/strings.xml index fd4b40ff2b19..9fc780150e4c 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 2620c27c4c14..72f756af960e 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -2067,4 +2067,5 @@ <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/graphics/java/android/graphics/drawable/RippleBackground.java b/graphics/java/android/graphics/drawable/RippleBackground.java index 4e709b5b4790..faa89bfa0e80 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 f0a207248006..e9e475c16679 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/browse/MediaBrowser.java b/media/java/android/media/browse/MediaBrowser.java index 34713e7b86db..1de8a8bb4fb7 100644 --- a/media/java/android/media/browse/MediaBrowser.java +++ b/media/java/android/media/browse/MediaBrowser.java @@ -708,6 +708,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 cfbf3af0a9b1..e490c2be8f9c 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 2c38697d776a..ad018ad53398 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/packages/SystemUI/res/anim/zen_toast_enter.xml b/packages/SystemUI/res/anim/zen_toast_enter.xml new file mode 100644 index 000000000000..e236782fb3c5 --- /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 000000000000..a9b1ab243b49 --- /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 000000000000..11e90637e18d --- /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 000000000000..681d49931d44 --- /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 000000000000..619fe208802b --- /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 d0fba20d53e4..ece6979724db 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 000000000000..1e3d3cf12755 --- /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 2e6f898dc470..13170add696b 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 c690ef4f89e9..4f41cd560ae4 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 e9a1acff87b0..48450ddfaf05 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 46e7587cb14e..909dc4279609 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 61ed095a955e..d8d70423b4cc 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 2b541d39e091..c1681c7c36d2 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 000000000000..96e2a8eb566f --- /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 00026dc58338..42ee666ec70b 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 ac78630af171..be3fc47ef07f 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/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java index 8e8e4a60a75d..01e80b708c79 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 d2e3d25efac9..4d2fd4c725ec 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 7f89947420a9..15dcd44c3b0b 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 2829e2b7aa2c..d8e5a982c44a 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 1c1a034492b3..6e2a8ada32f0 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 5038d03a48af..557a44e0cb7b 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 5938819e34d5..9fd0e0960d89 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/telecomm/java/android/telecom/PhoneAccount.java b/telecomm/java/android/telecom/PhoneAccount.java index ffe787ae3c2f..1d6d8bcc1147 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 796725b665d3..b18cb968f182 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 34b1454158d9..6ba151f66130 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 8b7c8838ab31..2455c9ccf59f 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/tools/aapt/ResourceTable.cpp b/tools/aapt/ResourceTable.cpp index b8c34543c361..77d3beb731e2 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 c548a851fb2e..eac5dd3f919f 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() { } |