diff options
37 files changed, 326 insertions, 19 deletions
diff --git a/api/current.txt b/api/current.txt index 8236f387f5d4..d4964090dc18 100644 --- a/api/current.txt +++ b/api/current.txt @@ -5424,6 +5424,7 @@ package android.app.admin { method public java.lang.String[] getAccountTypesWithManagementDisabled(); method public java.util.List<android.content.ComponentName> getActiveAdmins(); method public android.os.Bundle getApplicationRestrictions(android.content.ComponentName, java.lang.String); + method public boolean getAutoTimeRequired(); method public boolean getCameraDisabled(android.content.ComponentName); method public boolean getCrossProfileCallerIdDisabled(android.content.ComponentName); method public java.util.List<java.lang.String> getCrossProfileWidgetProviders(android.content.ComponentName); @@ -5469,6 +5470,7 @@ package android.app.admin { method public void setAccountManagementDisabled(android.content.ComponentName, java.lang.String, boolean); method public boolean setApplicationHidden(android.content.ComponentName, java.lang.String, boolean); method public void setApplicationRestrictions(android.content.ComponentName, java.lang.String, android.os.Bundle); + method public void setAutoTimeRequired(android.content.ComponentName, boolean); method public void setCameraDisabled(android.content.ComponentName, boolean); method public void setCrossProfileCallerIdDisabled(android.content.ComponentName, boolean); method public void setGlobalSetting(android.content.ComponentName, java.lang.String, java.lang.String); diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java index 5c24540f5ead..a13bb3ac26b1 100644 --- a/core/java/android/app/admin/DevicePolicyManager.java +++ b/core/java/android/app/admin/DevicePolicyManager.java @@ -1885,7 +1885,7 @@ public class DevicePolicyManager { * security exception will be thrown. * * @param admin Which {@link DeviceAdminReceiver} this request is associated with. - * @param disabled Whether or not screen capture should be disabled. + * @param disabled Whether screen capture is disabled or not. */ public void setScreenCaptureDisabled(ComponentName admin, boolean disabled) { if (mService != null) { @@ -1920,6 +1920,42 @@ public class DevicePolicyManager { } /** + * Called by a device owner to set whether auto time is required. If auto time is + * required the user cannot set the date and time, but has to use network date and time. + * + * <p>Note: if auto time is required the user can still manually set the time zone. + * + * <p>The calling device admin must be a device owner. If it is not, a security exception will + * be thrown. + * + * @param admin Which {@link DeviceAdminReceiver} this request is associated with. + * @param required Whether auto time is set required or not. + */ + public void setAutoTimeRequired(ComponentName admin, boolean required) { + if (mService != null) { + try { + mService.setAutoTimeRequired(admin, UserHandle.myUserId(), required); + } catch (RemoteException e) { + Log.w(TAG, "Failed talking with device policy service", e); + } + } + } + + /** + * @return true if auto time is required. + */ + public boolean getAutoTimeRequired() { + if (mService != null) { + try { + return mService.getAutoTimeRequired(); + } catch (RemoteException e) { + Log.w(TAG, "Failed talking with device policy service", e); + } + } + return false; + } + + /** * Called by an application that is administering the device to disable keyguard customizations, * such as widgets. After setting this, keyguard features will be disabled according to the * provided feature list. diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl index 1e17bb65aaef..23f36fb31e5d 100644 --- a/core/java/android/app/admin/IDevicePolicyManager.aidl +++ b/core/java/android/app/admin/IDevicePolicyManager.aidl @@ -186,4 +186,7 @@ interface IDevicePolicyManager { boolean addCrossProfileWidgetProvider(in ComponentName admin, String packageName); boolean removeCrossProfileWidgetProvider(in ComponentName admin, String packageName); List<String> getCrossProfileWidgetProviders(in ComponentName admin); + + void setAutoTimeRequired(in ComponentName who, int userHandle, boolean required); + boolean getAutoTimeRequired(); } diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp index a8b8bef18a95..62d803690616 100644 --- a/core/jni/AndroidRuntime.cpp +++ b/core/jni/AndroidRuntime.cpp @@ -879,9 +879,17 @@ int AndroidRuntime::startVm(JavaVM** pJavaVM, JNIEnv** pEnv) parseRuntimeOption("dalvik.vm.profile.max-stack-depth", profileMaxStackDepth, "-Xprofile-max-stack-depth:"); - } - parseRuntimeOption("ro.dalvik.vm.native.bridge", nativeBridgeLibrary, "-XX:NativeBridge="); + // Native bridge library. "0" means that native bridge is disabled. + property_get("ro.dalvik.vm.native.bridge", propBuf, ""); + if (propBuf[0] == '\0') { + ALOGW("ro.dalvik.vm.native.bridge is not expected to be empty"); + } else if (strcmp(propBuf, "0") != 0) { + snprintf(nativeBridgeLibrary, sizeof("-XX:NativeBridge=") + PROPERTY_VALUE_MAX, + "-XX:NativeBridge=%s", propBuf); + addOption(nativeBridgeLibrary); + } + } initArgs.version = JNI_VERSION_1_4; initArgs.options = mOptions.editArray(); diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index 4f0757cade5a..af213ba06f56 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -26,6 +26,7 @@ <item><xliff:g id="id">ime</xliff:g></item> <item><xliff:g id="id">sync_failing</xliff:g></item> <item><xliff:g id="id">sync_active</xliff:g></item> + <item><xliff:g id="id">cast</xliff:g></item> <item><xliff:g id="id">location</xliff:g></item> <item><xliff:g id="id">bluetooth</xliff:g></item> <item><xliff:g id="id">nfc</xliff:g></item> diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_cast_available.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_cast_available.png Binary files differdeleted file mode 100644 index f256fbbb246a..000000000000 --- a/packages/SystemUI/res/drawable-hdpi/ic_qs_cast_available.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_cast_connected.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_cast_connected.png Binary files differdeleted file mode 100644 index b946ec9029f7..000000000000 --- a/packages/SystemUI/res/drawable-hdpi/ic_qs_cast_connected.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_cast_available.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_cast_available.png Binary files differdeleted file mode 100644 index b1e984c7c0a0..000000000000 --- a/packages/SystemUI/res/drawable-mdpi/ic_qs_cast_available.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_cast_connected.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_cast_connected.png Binary files differdeleted file mode 100644 index ceda1bb6398a..000000000000 --- a/packages/SystemUI/res/drawable-mdpi/ic_qs_cast_connected.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_cast_available.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_cast_available.png Binary files differdeleted file mode 100644 index 47be502e0a31..000000000000 --- a/packages/SystemUI/res/drawable-xhdpi/ic_qs_cast_available.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_cast_connected.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_cast_connected.png Binary files differdeleted file mode 100644 index 4b12809b9c96..000000000000 --- a/packages/SystemUI/res/drawable-xhdpi/ic_qs_cast_connected.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_cast_available.png b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_cast_available.png Binary files differdeleted file mode 100644 index 8e225af212ef..000000000000 --- a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_cast_available.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_cast_connected.png b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_cast_connected.png Binary files differdeleted file mode 100644 index 937202bdf809..000000000000 --- a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_cast_connected.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable/stat_sys_cast.xml b/packages/SystemUI/res/drawable/stat_sys_cast.xml new file mode 100644 index 000000000000..c9e65e029ed2 --- /dev/null +++ b/packages/SystemUI/res/drawable/stat_sys_cast.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="18dp" + android:height="18dp" + android:viewportWidth="48.0" + android:viewportHeight="48.0"> + + <path + android:fillColor="#FFFFFFFF" + android:pathData="M2.0,36.0l0.0,6.0l6.0,0.0C8.0,38.7 5.3,36.0 2.0,36.0zM2.0,28.0l0.0,4.0c5.5,0.0 10.0,4.5 10.0,10.0l4.0,0.0C16.0,34.3 9.7,28.0 2.0,28.0zM38.0,14.0L10.0,14.0l0.0,3.3c7.9,2.6 14.2,8.8 16.7,16.7L38.0,34.0L38.0,14.0zM2.0,20.0l0.0,4.0c9.9,0.0 18.0,8.1 18.0,18.0l4.0,0.0C24.0,29.8 14.1,20.0 2.0,20.0zM42.0,6.0L6.0,6.0c-2.2,0.0 -4.0,1.8 -4.0,4.0l0.0,6.0l4.0,0.0l0.0,-6.0l36.0,0.0l0.0,28.0L28.0,38.0l0.0,4.0l14.0,0.0c2.2,0.0 4.0,-1.8 4.0,-4.0L46.0,10.0C46.0,7.8 44.2,6.0 42.0,6.0z"/> +</vector> diff --git a/packages/SystemUI/res/layout/status_bar_notification_dismiss_all.xml b/packages/SystemUI/res/layout/status_bar_notification_dismiss_all.xml index 902b837ea4fc..9e0f82cb2f75 100644 --- a/packages/SystemUI/res/layout/status_bar_notification_dismiss_all.xml +++ b/packages/SystemUI/res/layout/status_bar_notification_dismiss_all.xml @@ -27,5 +27,6 @@ android:layout_height="48dp" android:layout_gravity="end" android:src="@drawable/ic_dismiss_all" - android:background="@drawable/ripple_drawable" /> + android:background="@drawable/ripple_drawable" + android:contentDescription="@string/accessibility_clear_all" /> </com.android.systemui.statusbar.DismissView> diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml index 0af693d29329..bc941ca8ce3c 100644 --- a/packages/SystemUI/res/values/dimens.xml +++ b/packages/SystemUI/res/values/dimens.xml @@ -278,8 +278,14 @@ <!-- The height of the speed bump view. --> <dimen name="speed_bump_height">16dp</dimen> - <!-- Lockscreen affordance drag distance for camera and phone. --> - <dimen name="affordance_drag_distance">100dp</dimen> + <!-- Lockscreen unlocking falsing threshold. --> + <dimen name="unlock_falsing_threshold">100dp</dimen> + + <!-- Lockscreen falsing threshold for quick settings. --> + <dimen name="qs_falsing_threshold">60dp</dimen> + + <!-- Falsing threshold used when dismissing notifications from the lockscreen. --> + <dimen name="swipe_helper_falsing_threshold">100dp</dimen> <dimen name="notifications_top_padding">8dp</dimen> @@ -299,7 +305,7 @@ <dimen name="heads_up_window_height">250dp</dimen> <!-- The minimum amount the user needs to swipe to go to the camera / phone. --> - <dimen name="keyguard_min_swipe_amount">75dp</dimen> + <dimen name="keyguard_min_swipe_amount">85dp</dimen> <!-- The minimum background radius when swiping to a side for the camera / phone affordances. --> <dimen name="keyguard_affordance_min_background_radius">30dp</dimen> diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml index 120af1deefae..0fe389a7d77b 100644 --- a/packages/SystemUI/res/values/strings.xml +++ b/packages/SystemUI/res/values/strings.xml @@ -392,6 +392,9 @@ <!-- Content description of the ringer silent icon in the notification panel for accessibility (not shown on the screen). [CHAR LIMIT=NONE] --> <string name="accessibility_ringer_silent">Ringer silent.</string> + <!-- Content description of the cast icon in the notification panel for accessibility (not shown on the screen). [CHAR LIMIT=NONE] --> + <string name="accessibility_casting">@string/quick_settings_casting</string> + <!-- Content description to tell the user that this button will remove an application from recents --> <string name="accessibility_recents_item_will_be_dismissed">Dismiss <xliff:g id="app" example="Calendar">%s</xliff:g>.</string> <!-- Content description to tell the user an application has been removed from recents --> diff --git a/packages/SystemUI/src/com/android/systemui/SwipeHelper.java b/packages/SystemUI/src/com/android/systemui/SwipeHelper.java index a18b0c084430..8e603ba16a63 100644 --- a/packages/SystemUI/src/com/android/systemui/SwipeHelper.java +++ b/packages/SystemUI/src/com/android/systemui/SwipeHelper.java @@ -81,6 +81,8 @@ public class SwipeHelper implements Gefingerpoken { private long mLongPressTimeout; final private int[] mTmpPos = new int[2]; + private int mFalsingThreshold; + private boolean mTouchAboveFalsingThreshold; public SwipeHelper(int swipeDirection, Callback callback, Context context) { mCallback = callback; @@ -93,6 +95,8 @@ public class SwipeHelper implements Gefingerpoken { mLongPressTimeout = (long) (ViewConfiguration.getLongPressTimeout() * 1.5f); // extra long-press! mFastOutLinearInInterpolator = AnimationUtils.loadInterpolator(context, android.R.interpolator.fast_out_linear_in); + mFalsingThreshold = context.getResources().getDimensionPixelSize( + R.dimen.swipe_helper_falsing_threshold); } public void setLongPressListener(LongPressListener listener) { @@ -222,6 +226,7 @@ public class SwipeHelper implements Gefingerpoken { switch (action) { case MotionEvent.ACTION_DOWN: + mTouchAboveFalsingThreshold = false; mDragging = false; mLongPressSent = false; mCurrView = mCallback.getChildAtPosition(ev); @@ -406,12 +411,16 @@ public class SwipeHelper implements Gefingerpoken { case MotionEvent.ACTION_MOVE: if (mCurrView != null) { float delta = getPos(ev) - mInitialTouchPos; + float absDelta = Math.abs(delta); + if (absDelta >= mFalsingThreshold) { + mTouchAboveFalsingThreshold = true; + } // don't let items that can't be dismissed be dragged more than // maxScrollDistance if (CONSTRAIN_SWIPE && !mCallback.canChildBeDismissed(mCurrView)) { float size = getSize(mCurrAnimView); float maxScrollDistance = 0.15f * size; - if (Math.abs(delta) >= size) { + if (absDelta >= size) { delta = delta > 0 ? maxScrollDistance : -maxScrollDistance; } else { delta = maxScrollDistance * (float) Math.sin((delta/size)*(Math.PI/2)); @@ -437,9 +446,11 @@ public class SwipeHelper implements Gefingerpoken { boolean childSwipedFastEnough = (Math.abs(velocity) > escapeVelocity) && (Math.abs(velocity) > Math.abs(perpendicularVelocity)) && (velocity > 0) == (getTranslation(mCurrAnimView) > 0); + boolean falsingDetected = mCallback.isAntiFalsingNeeded() + && !mTouchAboveFalsingThreshold; - boolean dismissChild = mCallback.canChildBeDismissed(mCurrView) && - (childSwipedFastEnough || childSwipedFarEnough); + boolean dismissChild = mCallback.canChildBeDismissed(mCurrView) + && !falsingDetected && (childSwipedFastEnough || childSwipedFarEnough); if (dismissChild) { // flingadingy @@ -462,6 +473,8 @@ public class SwipeHelper implements Gefingerpoken { boolean canChildBeDismissed(View v); + boolean isAntiFalsingNeeded(); + void onBeginDrag(View v); void onChildDismissed(View v); diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java index a2136d2b938b..a3ffc4e6141e 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java @@ -401,16 +401,23 @@ public class QSPanel extends ViewGroup { mBrightnessView.layout(0, mBrightnessPaddingTop, mBrightnessView.getMeasuredWidth(), mBrightnessPaddingTop + mBrightnessView.getMeasuredHeight()); + boolean isRtl = getLayoutDirection() == LAYOUT_DIRECTION_RTL; for (TileRecord record : mRecords) { if (record.tileView.getVisibility() == GONE) continue; final int cols = getColumnCount(record.row); final int cw = record.row == 0 ? mLargeCellWidth : mCellWidth; final int extra = (w - cw * cols) / (cols + 1); - final int left = record.col * cw + (record.col + 1) * extra; + int left = record.col * cw + (record.col + 1) * extra; final int top = getRowTop(record.row); - record.tileView.layout(left, top, - left + record.tileView.getMeasuredWidth(), - top + record.tileView.getMeasuredHeight()); + int right; + int tileWith = record.tileView.getMeasuredWidth(); + if (isRtl) { + right = w - left; + left = right - tileWith; + } else { + right = left + tileWith; + } + record.tileView.layout(left, top, right, top + record.tileView.getMeasuredHeight()); } final int dh = Math.max(mDetail.getMeasuredHeight(), getMeasuredHeight()); mDetail.layout(0, 0, mDetail.getMeasuredWidth(), dh); diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSTile.java b/packages/SystemUI/src/com/android/systemui/qs/QSTile.java index 876652c37be2..2b071cce5090 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSTile.java @@ -306,6 +306,7 @@ public abstract class QSTile<TState extends State> implements Listenable { public String label; public String contentDescription; public String dualLabelContentDescription; + public boolean autoMirrorDrawable = true; public boolean copyTo(State other) { if (other == null) throw new IllegalArgumentException(); @@ -315,6 +316,7 @@ public abstract class QSTile<TState extends State> implements Listenable { || !Objects.equals(other.icon, icon) || !Objects.equals(other.label, label) || !Objects.equals(other.contentDescription, contentDescription) + || !Objects.equals(other.autoMirrorDrawable, autoMirrorDrawable) || !Objects.equals(other.dualLabelContentDescription, dualLabelContentDescription); other.visible = visible; @@ -323,6 +325,7 @@ public abstract class QSTile<TState extends State> implements Listenable { other.label = label; other.contentDescription = contentDescription; other.dualLabelContentDescription = dualLabelContentDescription; + other.autoMirrorDrawable = autoMirrorDrawable; return changed; } @@ -339,6 +342,7 @@ public abstract class QSTile<TState extends State> implements Listenable { sb.append(",label=").append(label); sb.append(",contentDescription=").append(contentDescription); sb.append(",dualLabelContentDescription=").append(dualLabelContentDescription); + sb.append(",autoMirrorDrawable=").append(autoMirrorDrawable); return sb.append(']'); } } diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSTileView.java b/packages/SystemUI/src/com/android/systemui/qs/QSTileView.java index 20fd5a0aa5f2..93216149ab3c 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSTileView.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSTileView.java @@ -265,6 +265,10 @@ public class QSTileView extends ViewGroup { } else if (state.iconId > 0) { iv.setImageResource(state.iconId); } + Drawable drawable = iv.getDrawable(); + if (state.autoMirrorDrawable && drawable != null) { + drawable.setAutoMirrored(true); + } } if (mDual) { mDualLabel.setText(state.label); diff --git a/packages/SystemUI/src/com/android/systemui/qs/SignalTileView.java b/packages/SystemUI/src/com/android/systemui/qs/SignalTileView.java index 1df3d20a1765..0ecdeaa45990 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/SignalTileView.java +++ b/packages/SystemUI/src/com/android/systemui/qs/SignalTileView.java @@ -18,6 +18,7 @@ package com.android.systemui.qs; import android.animation.ValueAnimator; import android.content.Context; +import android.graphics.drawable.Drawable; import android.view.View; import android.widget.FrameLayout; import android.widget.ImageView; @@ -78,10 +79,19 @@ public final class SignalTileView extends QSTileView { } private void layoutIndicator(View indicator) { + boolean isRtl = getLayoutDirection() == LAYOUT_DIRECTION_RTL; + int left, right; + if (isRtl) { + right = mIconFrame.getLeft(); + left = right - indicator.getMeasuredWidth(); + } else { + left = mIconFrame.getRight(); + right = left + indicator.getMeasuredWidth(); + } indicator.layout( - mIconFrame.getRight(), + left, mIconFrame.getBottom() - indicator.getMeasuredHeight(), - mIconFrame.getRight() + indicator.getMeasuredWidth(), + right, mIconFrame.getBottom()); } @@ -96,6 +106,10 @@ public final class SignalTileView extends QSTileView { } else { mOverlay.setVisibility(GONE); } + Drawable drawable = mSignal.getDrawable(); + if (state.autoMirrorDrawable && drawable != null) { + drawable.setAutoMirrored(true); + } final boolean shown = isShown(); setVisibility(mIn, shown, s.activityIn); setVisibility(mOut, shown, s.activityOut); diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java index 109237b3c102..0b838780da9d 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java @@ -88,6 +88,7 @@ public class BluetoothTile extends QSTile<QSTile.BooleanState> { final boolean connecting = mController.isBluetoothConnecting(); state.visible = supported; state.value = enabled; + state.autoMirrorDrawable = false; if (enabled) { state.label = null; if (connected) { diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java index f5036579ff7c..830429136808 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java @@ -93,6 +93,7 @@ public class CastTile extends QSTile<QSTile.BooleanState> { state.visible = !(mKeyguard.isSecure() && mKeyguard.isShowing()); state.label = mContext.getString(R.string.quick_settings_cast_title); state.value = false; + state.autoMirrorDrawable = false; final Set<CastDevice> devices = mController.getCastDevices(); boolean connecting = false; for (CastDevice device : devices) { diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java index ce42d47b6036..25bcfd2f375b 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java @@ -95,6 +95,7 @@ public class CellularTile extends QSTile<QSTile.SignalState> { : !cb.enabled || cb.airplaneModeEnabled ? R.drawable.ic_qs_signal_disabled : cb.mobileSignalIconId > 0 ? cb.mobileSignalIconId : R.drawable.ic_qs_signal_no_signal; + state.autoMirrorDrawable = !cb.noSim; state.overlayIconId = cb.enabled && (cb.dataTypeIconId > 0) && !cb.wifiConnected ? cb.dataTypeIconId : 0; diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentsHorizontalScrollView.java b/packages/SystemUI/src/com/android/systemui/recent/RecentsHorizontalScrollView.java index 25a62ae819fb..bdb0ad3c4fed 100644 --- a/packages/SystemUI/src/com/android/systemui/recent/RecentsHorizontalScrollView.java +++ b/packages/SystemUI/src/com/android/systemui/recent/RecentsHorizontalScrollView.java @@ -191,6 +191,11 @@ public class RecentsHorizontalScrollView extends HorizontalScrollView return true; } + @Override + public boolean isAntiFalsingNeeded() { + return false; + } + public void dismissChild(View v) { mSwipeHelper.dismissChild(v, 0); } diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentsVerticalScrollView.java b/packages/SystemUI/src/com/android/systemui/recent/RecentsVerticalScrollView.java index e8e9d529e246..47c096f6f970 100644 --- a/packages/SystemUI/src/com/android/systemui/recent/RecentsVerticalScrollView.java +++ b/packages/SystemUI/src/com/android/systemui/recent/RecentsVerticalScrollView.java @@ -199,6 +199,11 @@ public class RecentsVerticalScrollView extends ScrollView return true; } + @Override + public boolean isAntiFalsingNeeded() { + return false; + } + public void dismissChild(View v) { mSwipeHelper.dismissChild(v, 0); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java index 548e7d224093..e6eca22e4a2d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java @@ -211,6 +211,7 @@ public class NotificationContentView extends FrameLayout { private void setImageViewDark(boolean dark, boolean fade, int imageViewId) { // TODO: implement fade final ImageView v = (ImageView) mContractedChild.findViewById(imageViewId); + if (v == null) return; final Drawable d = v.getBackground(); if (dark) { v.setLayerType(LAYER_TYPE_HARDWARE, INVERT_PAINT); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DemoStatusIcons.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DemoStatusIcons.java index 936479beadc3..c5d06b94a115 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DemoStatusIcons.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DemoStatusIcons.java @@ -120,6 +120,11 @@ public class DemoStatusIcons extends LinearLayout implements DemoMode { : 0; updateSlot("speakerphone", null, iconId); } + String cast = args.getString("cast"); + if (cast != null) { + int iconId = cast.equals("cast") ? R.drawable.stat_sys_cast : 0; + updateSlot("cast", null, iconId); + } } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java index 387abc319335..d3c3f56b6f08 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java @@ -160,6 +160,8 @@ public class NotificationPanelView extends PanelView implements private boolean mQsScrimEnabled = true; private boolean mLastAnnouncementWasQuickSettings; + private boolean mQsTouchAboveFalsingThreshold; + private int mQsFalsingThreshold; public NotificationPanelView(Context context, AttributeSet attrs) { super(context, attrs); @@ -230,6 +232,8 @@ public class NotificationPanelView extends PanelView implements mClockPositionAlgorithm.loadDimens(getResources()); mNotificationScrimWaitDistance = getResources().getDimensionPixelSize(R.dimen.notification_scrim_wait_distance); + mQsFalsingThreshold = getResources().getDimensionPixelSize( + R.dimen.qs_falsing_threshold); } public void updateResources() { @@ -526,6 +530,7 @@ public class NotificationPanelView extends PanelView implements private void resetDownStates(MotionEvent event) { if (event.getActionMasked() == MotionEvent.ACTION_DOWN) { mOnlyAffordanceInThisMotion = false; + mQsTouchAboveFalsingThreshold = mQsFullyExpanded; } } @@ -546,6 +551,9 @@ public class NotificationPanelView extends PanelView implements } private boolean flingExpandsQs(float vel) { + if (!mQsTouchAboveFalsingThreshold && mStatusBarState == StatusBarState.KEYGUARD) { + return false; + } if (Math.abs(vel) < mFlingAnimationUtils.getMinVelocityPxPerSecond()) { return getQsExpansionFraction() > 0.5f; } else { @@ -690,6 +698,9 @@ public class NotificationPanelView extends PanelView implements case MotionEvent.ACTION_MOVE: final float h = y - mInitialTouchY; setQsExpansion(h + mInitialHeightOnTouch); + if (h >= mQsFalsingThreshold) { + mQsTouchAboveFalsingThreshold = true; + } trackMovement(event); break; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java index b175fd5cdd17..e818d2350ddd 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java @@ -68,6 +68,8 @@ public abstract class PanelView extends FrameLayout { protected boolean mHintAnimationRunning; private boolean mOverExpandedBeforeFling; private float mOriginalIndicationY; + private boolean mTouchAboveFalsingThreshold; + private int mUnlockFalsingThreshold; private ValueAnimator mHeightAnimator; private ObjectAnimator mPeekAnimator; @@ -183,6 +185,7 @@ public abstract class PanelView extends FrameLayout { mTouchSlop = configuration.getScaledTouchSlop(); mHintDistance = res.getDimension(R.dimen.hint_move_distance); mEdgeTapAreaWidth = res.getDimensionPixelSize(R.dimen.edge_tap_area_width); + mUnlockFalsingThreshold = res.getDimensionPixelSize(R.dimen.unlock_falsing_threshold); } private void trackMovement(MotionEvent event) { @@ -234,6 +237,7 @@ public abstract class PanelView extends FrameLayout { mHasLayoutedSinceDown = false; mUpdateFlingOnLayout = false; mPeekTouching = mPanelClosedOnDown; + mTouchAboveFalsingThreshold = false; if (mVelocityTracker == null) { initVelocityTracker(); } @@ -298,6 +302,9 @@ public abstract class PanelView extends FrameLayout { } mJustPeeked = false; } + if (-h >= mUnlockFalsingThreshold) { + mTouchAboveFalsingThreshold = true; + } if (!mJustPeeked && (!waitForTouchSlop || mTracking) && !isTrackingBlocked()) { setExpandedHeightInternal(newHeight); } @@ -399,6 +406,7 @@ public abstract class PanelView extends FrameLayout { mPanelClosedOnDown = mExpandedHeight == 0.0f; mHasLayoutedSinceDown = false; mUpdateFlingOnLayout = false; + mTouchAboveFalsingThreshold = false; initVelocityTracker(); trackMovement(event); break; @@ -471,6 +479,9 @@ public abstract class PanelView extends FrameLayout { * @return whether a fling should expands the panel; contracts otherwise */ protected boolean flingExpands(float vel, float vectorVel) { + if (!mTouchAboveFalsingThreshold && mStatusBar.isFalsingThresholdNeeded()) { + return true; + } if (Math.abs(vectorVel) < mFlingAnimationUtils.getMinVelocityPxPerSecond()) { return getExpandedFraction() > 0.5f; } else { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java index 620d3ecf62bd..788d5cee5fcb 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java @@ -562,7 +562,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, addNavigationBar(); // Lastly, call to the icon policy to install/update all the icons. - mIconPolicy = new PhoneStatusBarPolicy(mContext); + mIconPolicy = new PhoneStatusBarPolicy(mContext, mCastController); mSettingsObserver.onChange(false); // set up mHeadsUpObserver.onChange(true); // set up @@ -686,6 +686,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, mStackScroller = (NotificationStackScrollLayout) mStatusBarWindow.findViewById( R.id.notification_stack_scroller); mStackScroller.setLongPressListener(getNotificationLongClicker()); + mStackScroller.setPhoneStatusBar(this); mKeyguardIconOverflowContainer = (NotificationOverflowContainer) LayoutInflater.from(mContext).inflate( @@ -2015,7 +2016,12 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, .alpha(1f) .setDuration(320) .setInterpolator(ALPHA_IN) - .setStartDelay(50); + .setStartDelay(50) + + // We need to clean up any pending end action from animateStatusBarHide if we call + // both hide and show in the same frame before the animation actually gets started. + // cancel() doesn't really remove the end action. + .withEndAction(null); // Synchronize the motion with the Keyguard fading if necessary. if (mKeyguardFadingAway) { @@ -2053,6 +2059,12 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, return mNotificationPanel.isQsExpanded(); } + public boolean isFalsingThresholdNeeded() { + boolean onKeyguard = getBarState() == StatusBarState.KEYGUARD; + boolean isMethodInSecure = mUnlockMethodCache.isMethodInsecure(); + return onKeyguard && isMethodInSecure; + } + @Override // NotificationData.Environment public String getCurrentMediaNotificationKey() { return mMediaNotificationKey; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java index bd52cd39282f..237b78272b47 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java @@ -33,6 +33,8 @@ import android.util.Log; import com.android.internal.telephony.IccCardConstants; import com.android.internal.telephony.TelephonyIntents; import com.android.systemui.R; +import com.android.systemui.statusbar.policy.CastController; +import com.android.systemui.statusbar.policy.CastController.CastDevice; /** * This class contains all of the policy about which icons are installed in the status @@ -46,6 +48,7 @@ public class PhoneStatusBarPolicy { private static final boolean SHOW_SYNC_ICON = false; private static final String SLOT_SYNC_ACTIVE = "sync_active"; + private static final String SLOT_CAST = "cast"; private static final String SLOT_BLUETOOTH = "bluetooth"; private static final String SLOT_TTY = "tty"; private static final String SLOT_ZEN = "zen"; @@ -56,6 +59,7 @@ public class PhoneStatusBarPolicy { private final Context mContext; private final StatusBarManager mService; private final Handler mHandler = new Handler(); + private final CastController mCast; // Assume it's all good unless we hear otherwise. We don't always seem // to get broadcasts that it *is* there. @@ -98,8 +102,9 @@ public class PhoneStatusBarPolicy { } }; - public PhoneStatusBarPolicy(Context context) { + public PhoneStatusBarPolicy(Context context, CastController cast) { mContext = context; + mCast = cast; mService = (StatusBarManager)context.getSystemService(Context.STATUS_BAR_SERVICE); // listen for broadcasts @@ -151,6 +156,11 @@ public class PhoneStatusBarPolicy { mService.setIcon(SLOT_VOLUME, R.drawable.stat_sys_ringer_vibrate, 0, null); mService.setIconVisibility(SLOT_VOLUME, false); updateVolumeZen(); + + // cast + mService.setIcon(SLOT_CAST, R.drawable.stat_sys_cast, 0, null); + mService.setIconVisibility(SLOT_CAST, false); + mCast.addCallback(mCastCallback); } public void setZenMode(int zen) { @@ -287,4 +297,28 @@ public class PhoneStatusBarPolicy { mService.setIconVisibility(SLOT_TTY, false); } } + + private void updateCast() { + boolean isCasting = false; + for (CastDevice device : mCast.getCastDevices()) { + if (device.state == CastDevice.STATE_CONNECTING + || device.state == CastDevice.STATE_CONNECTED) { + isCasting = true; + break; + } + } + if (DEBUG) Log.v(TAG, "updateCast: isCasting: " + isCasting); + if (isCasting) { + mService.setIcon(SLOT_CAST, R.drawable.stat_sys_cast, 0, + mContext.getString(R.string.accessibility_casting)); + } + mService.setIconVisibility(SLOT_CAST, isCasting); + } + + private final CastController.Callback mCastCallback = new CastController.Callback() { + @Override + public void onCastDevicesChanged() { + updateCast(); + } + }; } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpNotificationView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpNotificationView.java index 6ae076f94828..b2009c32c852 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpNotificationView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpNotificationView.java @@ -301,6 +301,11 @@ public class HeadsUpNotificationView extends FrameLayout implements SwipeHelper. } @Override + public boolean isAntiFalsingNeeded() { + return false; + } + + @Override public void onChildDismissed(View v) { Log.v(TAG, "User swiped heads up to dismiss"); mBar.onHeadsUpDismissed(); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java index 82efd1d65c19..0aa1114fbacf 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java @@ -40,6 +40,7 @@ import com.android.systemui.statusbar.EmptyShadeView; import com.android.systemui.statusbar.ExpandableNotificationRow; import com.android.systemui.statusbar.ExpandableView; import com.android.systemui.statusbar.SpeedBumpView; +import com.android.systemui.statusbar.phone.PhoneStatusBar; import com.android.systemui.statusbar.policy.ScrollAdapter; import com.android.systemui.statusbar.stack.StackScrollState.ViewState; @@ -195,6 +196,7 @@ public class NotificationStackScrollLayout extends ViewGroup return true; } }; + private PhoneStatusBar mPhoneStatusBar; public NotificationStackScrollLayout(Context context) { this(context, null); @@ -640,6 +642,11 @@ public class NotificationStackScrollLayout extends ViewGroup return (veto != null && veto.getVisibility() != View.GONE); } + @Override + public boolean isAntiFalsingNeeded() { + return mPhoneStatusBar.isFalsingThresholdNeeded(); + } + private void setSwipingInProgress(boolean isSwiped) { mSwipingInProgress = isSwiped; if(isSwiped) { @@ -2185,6 +2192,10 @@ public class NotificationStackScrollLayout extends ViewGroup mStackScrollAlgorithm.updateIsSmallScreen(mMaxLayoutHeight - qsMinHeight); } + public void setPhoneStatusBar(PhoneStatusBar phoneStatusBar) { + this.mPhoneStatusBar = phoneStatusBar; + } + /** * A listener that is notified when some child locations might have changed. */ diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index 7baa258845ae..9856f5b0fc82 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -287,6 +287,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { private static final String TAG_DISABLE_CALLER_ID = "disable-caller-id"; private static final String TAG_DISABLE_SCREEN_CAPTURE = "disable-screen-capture"; private static final String TAG_DISABLE_ACCOUNT_MANAGEMENT = "disable-account-management"; + private static final String TAG_REQUIRE_AUTO_TIME = "require_auto_time"; private static final String TAG_ACCOUNT_TYPE = "account-type"; private static final String TAG_PERMITTED_ACCESSIBILITY_SERVICES = "permitted-accessiblity-services"; @@ -365,6 +366,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { boolean disableCamera = false; boolean disableCallerId = false; boolean disableScreenCapture = false; // Can only be set by a device/profile owner. + boolean requireAutoTime = false; // Can only be set by a device owner. Set<String> accountTypesWithManagementDisabled = new HashSet<String>(); @@ -501,6 +503,11 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { out.attribute(null, ATTR_VALUE, Boolean.toString(disableScreenCapture)); out.endTag(null, TAG_DISABLE_SCREEN_CAPTURE); } + if (requireAutoTime) { + out.startTag(null, TAG_REQUIRE_AUTO_TIME); + out.attribute(null, ATTR_VALUE, Boolean.toString(requireAutoTime)); + out.endTag(null, TAG_REQUIRE_AUTO_TIME); + } if (disabledKeyguardFeatures != DEF_KEYGUARD_FEATURES_DISABLED) { out.startTag(null, TAG_DISABLE_KEYGUARD_FEATURES); out.attribute(null, ATTR_VALUE, Integer.toString(disabledKeyguardFeatures)); @@ -634,6 +641,9 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } else if (TAG_DISABLE_SCREEN_CAPTURE.equals(tag)) { disableScreenCapture = Boolean.parseBoolean( parser.getAttributeValue(null, ATTR_VALUE)); + } else if (TAG_REQUIRE_AUTO_TIME.equals(tag)) { + requireAutoTime= Boolean.parseBoolean( + parser.getAttributeValue(null, ATTR_VALUE)); } else if (TAG_DISABLE_KEYGUARD_FEATURES.equals(tag)) { disabledKeyguardFeatures = Integer.parseInt( parser.getAttributeValue(null, ATTR_VALUE)); @@ -818,6 +828,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { pw.println(disableCallerId); pw.print(prefix); pw.print("disableScreenCapture="); pw.println(disableScreenCapture); + pw.print(prefix); pw.print("requireAutoTime="); + pw.println(requireAutoTime); pw.print(prefix); pw.print("disabledKeyguardFeatures="); pw.println(disabledKeyguardFeatures); pw.print(prefix); pw.print("crossProfileWidgetProviders="); @@ -3291,6 +3303,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { if (!mHasFeature) { return; } + enforceCrossUserPermission(userHandle); synchronized (this) { if (who == null) { throw new NullPointerException("ComponentName is null"); @@ -3343,6 +3356,51 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } /** + * Set whether auto time is required by the specified admin (must be device owner). + */ + public void setAutoTimeRequired(ComponentName who, int userHandle, boolean required) { + if (!mHasFeature) { + return; + } + enforceCrossUserPermission(userHandle); + synchronized (this) { + if (who == null) { + throw new NullPointerException("ComponentName is null"); + } + ActiveAdmin admin = getActiveAdminForCallerLocked(who, + DeviceAdminInfo.USES_POLICY_DEVICE_OWNER); + if (admin.requireAutoTime != required) { + admin.requireAutoTime = required; + saveSettingsLocked(userHandle); + } + } + + // Turn AUTO_TIME on in settings if it is required + if (required) { + long ident = Binder.clearCallingIdentity(); + try { + Settings.Global.putInt(mContext.getContentResolver(), + Settings.Global.AUTO_TIME, 1 /* AUTO_TIME on */); + } finally { + Binder.restoreCallingIdentity(ident); + } + } + } + + /** + * Returns whether or not auto time is required by the device owner. + */ + public boolean getAutoTimeRequired() { + if (!mHasFeature) { + return false; + } + synchronized (this) { + ActiveAdmin deviceOwner = getDeviceOwnerAdmin(); + return (deviceOwner != null) ? deviceOwner.requireAutoTime : false; + } + } + + /** * The system property used to share the state of the camera. The native camera service * is expected to read this property and act accordingly. */ @@ -3522,6 +3580,24 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { return null; } + // Returns the active device owner or null if there is no device owner. + private ActiveAdmin getDeviceOwnerAdmin() { + String deviceOwnerPackageName = getDeviceOwner(); + if (deviceOwnerPackageName == null) { + return null; + } + + DevicePolicyData policy = getUserData(UserHandle.USER_OWNER); + final int n = policy.mAdminList.size(); + for (int i = 0; i < n; i++) { + ActiveAdmin admin = policy.mAdminList.get(i); + if (deviceOwnerPackageName.equals(admin.info.getPackageName())) { + return admin; + } + } + return null; + } + @Override public void clearDeviceOwner(String packageName) { if (packageName == null) { diff --git a/wifi/java/android/net/wifi/ScanResult.java b/wifi/java/android/net/wifi/ScanResult.java index a280348af1b5..e80a8f4846f3 100644 --- a/wifi/java/android/net/wifi/ScanResult.java +++ b/wifi/java/android/net/wifi/ScanResult.java @@ -354,6 +354,7 @@ public class ScanResult implements Parcelable { sr.autoJoinStatus = in.readInt(); sr.untrusted = in.readInt() != 0; sr.numConnection = in.readInt(); + sr.numUsage = in.readInt(); int n = in.readInt(); if (n != 0) { sr.informationElements = new InformationElement[n]; |