Merge changes from topics "emergency-dialer-metrics", "telecom-metrics-for-emergency-dialer", "add_faster_emergency_dialer_flag" into pi-dev
* changes: Add extra data when starting emergency dialer intent Add new telecom metrics for emergency dialer Add new metrics constants for emergency dialer Separated emergency option final UI Fix Power menu background vanish Add separated emergency option on power menu Add emergency dialer option on power menu
This commit is contained in:
@@ -11235,6 +11235,14 @@ public final class Settings {
|
||||
*/
|
||||
public static final String EMERGENCY_AFFORDANCE_NEEDED = "emergency_affordance_needed";
|
||||
|
||||
/**
|
||||
* Enable faster emergency phone call feature.
|
||||
* The value is a boolean (1 or 0).
|
||||
* @hide
|
||||
*/
|
||||
public static final String FASTER_EMERGENCY_PHONE_CALL_ENABLED =
|
||||
"faster_emergency_phone_call_enabled";
|
||||
|
||||
/**
|
||||
* See RIL_PreferredNetworkType in ril.h
|
||||
* @hide
|
||||
|
||||
@@ -18,7 +18,7 @@ Copyright (C) 2014 The Android Open Source Project
|
||||
android:height="24.0dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0"
|
||||
android:tint="?attr/colorControlNormal">
|
||||
android:tint="?attr/colorError">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M6.8,17.3C5.3,15.9 4.5,14.0 4.5,12.0c0.0,-2.0 0.8,-3.8 2.1,-5.2l1.4,1.4c-1.0,1.0 -1.6,2.4 -1.6,3.8c0.0,1.5 0.6,2.9 1.6,3.9L6.8,17.3z"/>
|
||||
|
||||
31
core/res/res/drawable/ic_faster_emergency.xml
Normal file
31
core/res/res/drawable/ic_faster_emergency.xml
Normal file
@@ -0,0 +1,31 @@
|
||||
<!--
|
||||
Copyright (C) 2018 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24.0dp"
|
||||
android:height="24.0dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0"
|
||||
android:tint="?attr/colorError">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M19,3H5C3.9,3,3.01,3.9,3.01,5L3,19c0,1.1,0.9,2,2,2h14c1.1,0,2-0.9,2-2V5C21,3.9,20.1,3,19,3z M19,19L5,19V5h14V19z" />
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M 10.5 17 L 13.5 17 L 13.5 13.5 L 17 13.5 L 17 10.5 L 13.5 10.5 L 13.5 7 L 10.5 7 L 10.5 10.5 L 7 10.5 L 7 13.5 L 10.5 13.5 Z" />
|
||||
<path
|
||||
android:pathData="M0,0h24v24H0V0z" />
|
||||
|
||||
</vector>
|
||||
@@ -2613,6 +2613,7 @@
|
||||
"silent" = silent mode
|
||||
"users" = list of users
|
||||
"restart" = restart device
|
||||
"emergency" = Launch emergency dialer
|
||||
"lockdown" = Lock down device until the user authenticates
|
||||
"logout" = Logout the current user
|
||||
-->
|
||||
@@ -2623,6 +2624,7 @@
|
||||
<item>logout</item>
|
||||
<item>bugreport</item>
|
||||
<item>screenshot</item>
|
||||
<item>emergency</item>
|
||||
</string-array>
|
||||
|
||||
<!-- Number of milliseconds to hold a wake lock to ensure that drawing is fully
|
||||
|
||||
@@ -2989,7 +2989,7 @@
|
||||
<!-- Global actions icons -->
|
||||
<java-symbol type="drawable" name="ic_restart" />
|
||||
<java-symbol type="drawable" name="ic_screenshot" />
|
||||
|
||||
<java-symbol type="drawable" name="ic_faster_emergency" />
|
||||
<java-symbol type="drawable" name="emergency_icon" />
|
||||
|
||||
<java-symbol type="array" name="config_convert_to_emergency_number_map" />
|
||||
|
||||
@@ -237,6 +237,7 @@ public class SettingsBackupTest {
|
||||
Settings.Global.EUICC_SUPPORTED_COUNTRIES,
|
||||
Settings.Global.EUICC_FACTORY_RESET_TIMEOUT_MILLIS,
|
||||
Settings.Global.FANCY_IME_ANIMATIONS,
|
||||
Settings.Global.FASTER_EMERGENCY_PHONE_CALL_ENABLED,
|
||||
Settings.Global.FORCE_ALLOW_ON_EXTERNAL,
|
||||
Settings.Global.FORCED_APP_STANDBY_ENABLED,
|
||||
Settings.Global.FORCED_APP_STANDBY_FOR_SMALL_BATTERY_ENABLED,
|
||||
|
||||
@@ -3,7 +3,9 @@
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="top|right"
|
||||
android:layout_marginBottom="0dp"
|
||||
android:orientation="vertical"
|
||||
android:paddingTop="@dimen/global_actions_top_padding"
|
||||
android:clipToPadding="false"
|
||||
android:theme="@style/qs_theme"
|
||||
@@ -17,7 +19,19 @@
|
||||
android:layout_gravity="top|right"
|
||||
android:gravity="center"
|
||||
android:orientation="vertical"
|
||||
android:padding="12dp"
|
||||
android:translationZ="9dp" />
|
||||
android:padding="@dimen/global_actions_padding"
|
||||
android:translationZ="@dimen/global_actions_translate" />
|
||||
|
||||
<!-- For separated button-->
|
||||
<FrameLayout
|
||||
android:id="@+id/separated_button"
|
||||
android:layout_width="@dimen/global_actions_panel_width"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="top|right"
|
||||
android:layout_marginTop="6dp"
|
||||
android:gravity="center"
|
||||
android:orientation="vertical"
|
||||
android:padding="@dimen/global_actions_padding"
|
||||
android:translationZ="@dimen/global_actions_translate" />
|
||||
|
||||
</com.android.systemui.HardwareUiLayout>
|
||||
|
||||
@@ -922,6 +922,10 @@
|
||||
|
||||
<dimen name="global_actions_top_padding">120dp</dimen>
|
||||
|
||||
<dimen name="global_actions_padding">12dp</dimen>
|
||||
|
||||
<dimen name="global_actions_translate">9dp</dimen>
|
||||
|
||||
<!-- The maximum offset in either direction that elements are moved horizontally to prevent
|
||||
burn-in on AOD. -->
|
||||
<dimen name="burn_in_prevention_offset_x">8dp</dimen>
|
||||
|
||||
@@ -38,6 +38,7 @@ import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||
import com.android.internal.telephony.IccCardConstants.State;
|
||||
import com.android.internal.widget.LockPatternUtils;
|
||||
import com.android.internal.util.EmergencyAffordanceManager;
|
||||
import com.android.systemui.util.EmergencyDialerConstants;
|
||||
|
||||
/**
|
||||
* This class implements a smart emergency button that updates itself based
|
||||
@@ -47,11 +48,13 @@ import com.android.internal.util.EmergencyAffordanceManager;
|
||||
*/
|
||||
public class EmergencyButton extends Button {
|
||||
private static final Intent INTENT_EMERGENCY_DIAL = new Intent()
|
||||
.setAction("com.android.phone.EmergencyDialer.DIAL")
|
||||
.setAction(EmergencyDialerConstants.ACTION_DIAL)
|
||||
.setPackage("com.android.phone")
|
||||
.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
|
||||
| Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
|
||||
| Intent.FLAG_ACTIVITY_CLEAR_TOP);
|
||||
| Intent.FLAG_ACTIVITY_CLEAR_TOP)
|
||||
.putExtra(EmergencyDialerConstants.EXTRA_ENTRY_TYPE,
|
||||
EmergencyDialerConstants.ENTRY_TYPE_LOCKSCREEN_BUTTON);
|
||||
|
||||
private static final String LOG_TAG = "EmergencyButton";
|
||||
private final EmergencyAffordanceManager mEmergencyAffordanceManager;
|
||||
|
||||
@@ -27,32 +27,33 @@ import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.ViewOutlineProvider;
|
||||
import android.view.ViewTreeObserver;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.LinearLayout;
|
||||
|
||||
import com.android.systemui.tuner.TunerService;
|
||||
import com.android.systemui.tuner.TunerService.Tunable;
|
||||
import com.android.systemui.util.leak.RotationUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import static com.android.systemui.util.leak.RotationUtils.ROTATION_LANDSCAPE;
|
||||
import static com.android.systemui.util.leak.RotationUtils.ROTATION_NONE;
|
||||
import static com.android.systemui.util.leak.RotationUtils.ROTATION_SEASCAPE;
|
||||
|
||||
public class HardwareUiLayout extends FrameLayout implements Tunable {
|
||||
public class HardwareUiLayout extends LinearLayout implements Tunable {
|
||||
|
||||
private static final String EDGE_BLEED = "sysui_hwui_edge_bleed";
|
||||
private static final String ROUNDED_DIVIDER = "sysui_hwui_rounded_divider";
|
||||
private final int[] mTmp2 = new int[2];
|
||||
private View mChild;
|
||||
private View mList;
|
||||
private View mSeparatedView;
|
||||
private int mOldHeight;
|
||||
private boolean mAnimating;
|
||||
private AnimatorSet mAnimation;
|
||||
private View mDivision;
|
||||
private boolean mHasOutsideTouch;
|
||||
private HardwareBgDrawable mBackground;
|
||||
private HardwareBgDrawable mListBackground;
|
||||
private HardwareBgDrawable mSeparatedViewBackground;
|
||||
private Animator mAnimator;
|
||||
private boolean mCollapse;
|
||||
private boolean mHasSeparatedButton;
|
||||
private int mEndPoint;
|
||||
private boolean mEdgeBleed;
|
||||
private boolean mRoundedDivider;
|
||||
@@ -91,16 +92,19 @@ public class HardwareUiLayout extends FrameLayout implements Tunable {
|
||||
mRoundedDivider = Settings.Secure.getInt(getContext().getContentResolver(),
|
||||
ROUNDED_DIVIDER, 0) != 0;
|
||||
updateEdgeMargin(mEdgeBleed ? 0 : getEdgePadding());
|
||||
mBackground = new HardwareBgDrawable(mRoundedDivider, !mEdgeBleed, getContext());
|
||||
if (mChild != null) {
|
||||
mChild.setBackground(mBackground);
|
||||
mListBackground = new HardwareBgDrawable(mRoundedDivider, !mEdgeBleed, getContext());
|
||||
mSeparatedViewBackground = new HardwareBgDrawable(mRoundedDivider, !mEdgeBleed,
|
||||
getContext());
|
||||
if (mList != null) {
|
||||
mList.setBackground(mListBackground);
|
||||
mSeparatedView.setBackground(mSeparatedViewBackground);
|
||||
requestLayout();
|
||||
}
|
||||
}
|
||||
|
||||
private void updateEdgeMargin(int edge) {
|
||||
if (mChild != null) {
|
||||
MarginLayoutParams params = (MarginLayoutParams) mChild.getLayoutParams();
|
||||
if (mList != null) {
|
||||
MarginLayoutParams params = (MarginLayoutParams) mList.getLayoutParams();
|
||||
if (mRotation == ROTATION_LANDSCAPE) {
|
||||
params.topMargin = edge;
|
||||
} else if (mRotation == ROTATION_SEASCAPE) {
|
||||
@@ -108,7 +112,19 @@ public class HardwareUiLayout extends FrameLayout implements Tunable {
|
||||
} else {
|
||||
params.rightMargin = edge;
|
||||
}
|
||||
mChild.setLayoutParams(params);
|
||||
mList.setLayoutParams(params);
|
||||
}
|
||||
|
||||
if (mSeparatedView != null) {
|
||||
MarginLayoutParams params = (MarginLayoutParams) mSeparatedView.getLayoutParams();
|
||||
if (mRotation == ROTATION_LANDSCAPE) {
|
||||
params.topMargin = edge;
|
||||
} else if (mRotation == ROTATION_SEASCAPE) {
|
||||
params.bottomMargin = edge;
|
||||
} else {
|
||||
params.rightMargin = edge;
|
||||
}
|
||||
mSeparatedView.setLayoutParams(params);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -119,13 +135,15 @@ public class HardwareUiLayout extends FrameLayout implements Tunable {
|
||||
@Override
|
||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
|
||||
if (mChild == null) {
|
||||
if (mList == null) {
|
||||
if (getChildCount() != 0) {
|
||||
mChild = getChildAt(0);
|
||||
mChild.setBackground(mBackground);
|
||||
mList = getChildAt(0);
|
||||
mList.setBackground(mListBackground);
|
||||
mSeparatedView = getChildAt(1);
|
||||
mSeparatedView.setBackground(mSeparatedViewBackground);
|
||||
updateEdgeMargin(mEdgeBleed ? 0 : getEdgePadding());
|
||||
mOldHeight = mChild.getMeasuredHeight();
|
||||
mChild.addOnLayoutChangeListener(
|
||||
mOldHeight = mList.getMeasuredHeight();
|
||||
mList.addOnLayoutChangeListener(
|
||||
(v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) ->
|
||||
updatePosition());
|
||||
updateRotation();
|
||||
@@ -133,7 +151,7 @@ public class HardwareUiLayout extends FrameLayout implements Tunable {
|
||||
return;
|
||||
}
|
||||
}
|
||||
int newHeight = mChild.getMeasuredHeight();
|
||||
int newHeight = mList.getMeasuredHeight();
|
||||
if (newHeight != mOldHeight) {
|
||||
animateChild(mOldHeight, newHeight);
|
||||
}
|
||||
@@ -170,37 +188,60 @@ public class HardwareUiLayout extends FrameLayout implements Tunable {
|
||||
} else {
|
||||
rotateLeft();
|
||||
}
|
||||
if (mHasSeparatedButton) {
|
||||
if (from == ROTATION_SEASCAPE || to == ROTATION_SEASCAPE) {
|
||||
// Separated view has top margin, so seascape separated view need special rotation,
|
||||
// not a full left or right rotation.
|
||||
swapLeftAndTop(mSeparatedView);
|
||||
} else if (from == ROTATION_LANDSCAPE) {
|
||||
rotateRight(mSeparatedView);
|
||||
} else {
|
||||
rotateLeft(mSeparatedView);
|
||||
}
|
||||
}
|
||||
if (to != ROTATION_NONE) {
|
||||
if (mChild instanceof LinearLayout) {
|
||||
if (mList instanceof LinearLayout) {
|
||||
mRotatedBackground = true;
|
||||
mBackground.setRotatedBackground(true);
|
||||
LinearLayout linearLayout = (LinearLayout) mChild;
|
||||
mListBackground.setRotatedBackground(true);
|
||||
mSeparatedViewBackground.setRotatedBackground(true);
|
||||
LinearLayout linearLayout = (LinearLayout) mList;
|
||||
if (mSwapOrientation) {
|
||||
linearLayout.setOrientation(LinearLayout.HORIZONTAL);
|
||||
setOrientation(LinearLayout.HORIZONTAL);
|
||||
}
|
||||
swapDimens(this.mChild);
|
||||
swapDimens(mList);
|
||||
swapDimens(mSeparatedView);
|
||||
}
|
||||
} else {
|
||||
if (mChild instanceof LinearLayout) {
|
||||
if (mList instanceof LinearLayout) {
|
||||
mRotatedBackground = false;
|
||||
mBackground.setRotatedBackground(false);
|
||||
LinearLayout linearLayout = (LinearLayout) mChild;
|
||||
mListBackground.setRotatedBackground(false);
|
||||
mSeparatedViewBackground.setRotatedBackground(false);
|
||||
LinearLayout linearLayout = (LinearLayout) mList;
|
||||
if (mSwapOrientation) {
|
||||
linearLayout.setOrientation(LinearLayout.VERTICAL);
|
||||
setOrientation(LinearLayout.VERTICAL);
|
||||
}
|
||||
swapDimens(mChild);
|
||||
swapDimens(mList);
|
||||
swapDimens(mSeparatedView);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void rotateRight() {
|
||||
rotateRight(this);
|
||||
rotateRight(mChild);
|
||||
rotateRight(mList);
|
||||
swapDimens(this);
|
||||
|
||||
LayoutParams p = (LayoutParams) mChild.getLayoutParams();
|
||||
LayoutParams p = (LayoutParams) mList.getLayoutParams();
|
||||
p.gravity = rotateGravityRight(p.gravity);
|
||||
mChild.setLayoutParams(p);
|
||||
mList.setLayoutParams(p);
|
||||
|
||||
LayoutParams separatedViewLayoutParams = (LayoutParams) mSeparatedView.getLayoutParams();
|
||||
separatedViewLayoutParams.gravity = rotateGravityRight(separatedViewLayoutParams.gravity);
|
||||
mSeparatedView.setLayoutParams(separatedViewLayoutParams);
|
||||
|
||||
setGravity(p.gravity);
|
||||
}
|
||||
|
||||
private void swapDimens(View v) {
|
||||
@@ -247,12 +288,18 @@ public class HardwareUiLayout extends FrameLayout implements Tunable {
|
||||
|
||||
private void rotateLeft() {
|
||||
rotateLeft(this);
|
||||
rotateLeft(mChild);
|
||||
rotateLeft(mList);
|
||||
swapDimens(this);
|
||||
|
||||
LayoutParams p = (LayoutParams) mChild.getLayoutParams();
|
||||
LayoutParams p = (LayoutParams) mList.getLayoutParams();
|
||||
p.gravity = rotateGravityLeft(p.gravity);
|
||||
mChild.setLayoutParams(p);
|
||||
mList.setLayoutParams(p);
|
||||
|
||||
LayoutParams separatedViewLayoutParams = (LayoutParams) mSeparatedView.getLayoutParams();
|
||||
separatedViewLayoutParams.gravity = rotateGravityLeft(separatedViewLayoutParams.gravity);
|
||||
mSeparatedView.setLayoutParams(separatedViewLayoutParams);
|
||||
|
||||
setGravity(p.gravity);
|
||||
}
|
||||
|
||||
private int rotateGravityLeft(int gravity) {
|
||||
@@ -310,6 +357,15 @@ public class HardwareUiLayout extends FrameLayout implements Tunable {
|
||||
v.setLayoutParams(params);
|
||||
}
|
||||
|
||||
private void swapLeftAndTop(View v) {
|
||||
v.setPadding(v.getPaddingTop(), v.getPaddingLeft(), v.getPaddingBottom(),
|
||||
v.getPaddingRight());
|
||||
MarginLayoutParams params = (MarginLayoutParams) v.getLayoutParams();
|
||||
params.setMargins(params.topMargin, params.leftMargin, params.bottomMargin,
|
||||
params.rightMargin);
|
||||
v.setLayoutParams(params);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
|
||||
super.onLayout(changed, left, top, right, bottom);
|
||||
@@ -329,14 +385,14 @@ public class HardwareUiLayout extends FrameLayout implements Tunable {
|
||||
mAnimating = false;
|
||||
}
|
||||
});
|
||||
int fromTop = mChild.getTop();
|
||||
int fromBottom = mChild.getBottom();
|
||||
int fromTop = mList.getTop();
|
||||
int fromBottom = mList.getBottom();
|
||||
int toTop = fromTop - ((newHeight - oldHeight) / 2);
|
||||
int toBottom = fromBottom + ((newHeight - oldHeight) / 2);
|
||||
ObjectAnimator top = ObjectAnimator.ofInt(mChild, "top", fromTop, toTop);
|
||||
top.addUpdateListener(animation -> mBackground.invalidateSelf());
|
||||
ObjectAnimator top = ObjectAnimator.ofInt(mList, "top", fromTop, toTop);
|
||||
top.addUpdateListener(animation -> mListBackground.invalidateSelf());
|
||||
mAnimation.playTogether(top,
|
||||
ObjectAnimator.ofInt(mChild, "bottom", fromBottom, toBottom));
|
||||
ObjectAnimator.ofInt(mList, "bottom", fromBottom, toBottom));
|
||||
}
|
||||
|
||||
public void setDivisionView(View v) {
|
||||
@@ -350,26 +406,30 @@ public class HardwareUiLayout extends FrameLayout implements Tunable {
|
||||
}
|
||||
|
||||
private void updatePosition() {
|
||||
if (mChild == null) return;
|
||||
if (mList == null) return;
|
||||
// If got separated button, setRotatedBackground to false,
|
||||
// all items won't get white background.
|
||||
mListBackground.setRotatedBackground(mHasSeparatedButton);
|
||||
mSeparatedViewBackground.setRotatedBackground(mHasSeparatedButton);
|
||||
if (mDivision != null && mDivision.getVisibility() == VISIBLE) {
|
||||
int index = mRotatedBackground ? 0 : 1;
|
||||
mDivision.getLocationOnScreen(mTmp2);
|
||||
float trans = mRotatedBackground ? mDivision.getTranslationX()
|
||||
: mDivision.getTranslationY();
|
||||
int viewTop = (int) (mTmp2[index] + trans);
|
||||
mChild.getLocationOnScreen(mTmp2);
|
||||
mList.getLocationOnScreen(mTmp2);
|
||||
viewTop -= mTmp2[index];
|
||||
setCutPoint(viewTop);
|
||||
} else {
|
||||
setCutPoint(mChild.getMeasuredHeight());
|
||||
setCutPoint(mList.getMeasuredHeight());
|
||||
}
|
||||
}
|
||||
|
||||
private void setCutPoint(int point) {
|
||||
int curPoint = mBackground.getCutPoint();
|
||||
int curPoint = mListBackground.getCutPoint();
|
||||
if (curPoint == point) return;
|
||||
if (getAlpha() == 0 || curPoint == 0) {
|
||||
mBackground.setCutPoint(point);
|
||||
mListBackground.setCutPoint(point);
|
||||
return;
|
||||
}
|
||||
if (mAnimator != null) {
|
||||
@@ -379,7 +439,7 @@ public class HardwareUiLayout extends FrameLayout implements Tunable {
|
||||
mAnimator.cancel();
|
||||
}
|
||||
mEndPoint = point;
|
||||
mAnimator = ObjectAnimator.ofInt(mBackground, "cutPoint", curPoint, point);
|
||||
mAnimator = ObjectAnimator.ofInt(mListBackground, "cutPoint", curPoint, point);
|
||||
if (mCollapse) {
|
||||
mAnimator.setStartDelay(300);
|
||||
mCollapse = false;
|
||||
@@ -404,6 +464,10 @@ public class HardwareUiLayout extends FrameLayout implements Tunable {
|
||||
mCollapse = true;
|
||||
}
|
||||
|
||||
public void setHasSeparatedButton(boolean hasSeparatedButton) {
|
||||
mHasSeparatedButton = hasSeparatedButton;
|
||||
}
|
||||
|
||||
public static HardwareUiLayout get(View v) {
|
||||
if (v instanceof HardwareUiLayout) return (HardwareUiLayout) v;
|
||||
if (v.getParent() instanceof View) {
|
||||
@@ -413,14 +477,14 @@ public class HardwareUiLayout extends FrameLayout implements Tunable {
|
||||
}
|
||||
|
||||
private final ViewTreeObserver.OnComputeInternalInsetsListener mInsetsListener = inoutInfo -> {
|
||||
if (mHasOutsideTouch || (mChild == null)) {
|
||||
if (mHasOutsideTouch || (mList == null)) {
|
||||
inoutInfo.setTouchableInsets(
|
||||
ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME);
|
||||
return;
|
||||
}
|
||||
inoutInfo.setTouchableInsets(
|
||||
ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_CONTENT);
|
||||
inoutInfo.contentInsets.set(mChild.getLeft(), mChild.getTop(),
|
||||
0, getBottom() - mChild.getBottom());
|
||||
inoutInfo.contentInsets.set(mList.getLeft(), mList.getTop(),
|
||||
0, getBottom() - mList.getBottom());
|
||||
};
|
||||
}
|
||||
|
||||
@@ -28,12 +28,10 @@ import android.app.WallpaperManager;
|
||||
import android.app.admin.DevicePolicyManager;
|
||||
import android.app.trust.TrustManager;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.ServiceConnection;
|
||||
import android.content.pm.UserInfo;
|
||||
import android.database.ContentObserver;
|
||||
import android.graphics.Point;
|
||||
@@ -42,9 +40,7 @@ import android.media.AudioManager;
|
||||
import android.net.ConnectivityManager;
|
||||
import android.os.Build;
|
||||
import android.os.Handler;
|
||||
import android.os.IBinder;
|
||||
import android.os.Message;
|
||||
import android.os.Messenger;
|
||||
import android.os.RemoteException;
|
||||
import android.os.ServiceManager;
|
||||
import android.os.SystemProperties;
|
||||
@@ -68,9 +64,9 @@ import android.view.Window;
|
||||
import android.view.WindowManager;
|
||||
import android.view.WindowManagerGlobal;
|
||||
import android.view.accessibility.AccessibilityEvent;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.AdapterView.OnItemLongClickListener;
|
||||
import android.widget.BaseAdapter;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.ImageView.ScaleType;
|
||||
import android.widget.LinearLayout;
|
||||
@@ -93,6 +89,7 @@ import com.android.systemui.Interpolators;
|
||||
import com.android.systemui.colorextraction.SysuiColorExtractor;
|
||||
import com.android.systemui.plugins.GlobalActions.GlobalActionsManager;
|
||||
import com.android.systemui.statusbar.phone.ScrimController;
|
||||
import com.android.systemui.util.EmergencyDialerConstants;
|
||||
import com.android.systemui.volume.SystemUIInterpolators.LogAccelerateInterpolator;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -127,6 +124,7 @@ class GlobalActionsDialog implements DialogInterface.OnDismissListener,
|
||||
private static final String GLOBAL_ACTION_KEY_ASSIST = "assist";
|
||||
private static final String GLOBAL_ACTION_KEY_RESTART = "restart";
|
||||
private static final String GLOBAL_ACTION_KEY_LOGOUT = "logout";
|
||||
private static final String GLOBAL_ACTION_KEY_EMERGENCY = "emergency";
|
||||
private static final String GLOBAL_ACTION_KEY_SCREENSHOT = "screenshot";
|
||||
|
||||
private final Context mContext;
|
||||
@@ -153,6 +151,7 @@ class GlobalActionsDialog implements DialogInterface.OnDismissListener,
|
||||
private boolean mHasVibrator;
|
||||
private boolean mHasLogoutButton;
|
||||
private boolean mHasLockdownButton;
|
||||
private boolean mSeparatedEmergencyButtonEnabled;
|
||||
private final boolean mShowSilentToggle;
|
||||
private final EmergencyAffordanceManager mEmergencyAffordanceManager;
|
||||
private final ScreenshotHelper mScreenshotHelper;
|
||||
@@ -319,6 +318,8 @@ class GlobalActionsDialog implements DialogInterface.OnDismissListener,
|
||||
ArraySet<String> addedKeys = new ArraySet<String>();
|
||||
mHasLogoutButton = false;
|
||||
mHasLockdownButton = false;
|
||||
mSeparatedEmergencyButtonEnabled = Settings.Global.getInt(mContext.getContentResolver(),
|
||||
Settings.Global.FASTER_EMERGENCY_PHONE_CALL_ENABLED, 0) != 0;
|
||||
for (int i = 0; i < defaultActions.length; i++) {
|
||||
String actionKey = defaultActions[i];
|
||||
if (addedKeys.contains(actionKey)) {
|
||||
@@ -365,6 +366,11 @@ class GlobalActionsDialog implements DialogInterface.OnDismissListener,
|
||||
mItems.add(new LogoutAction());
|
||||
mHasLogoutButton = true;
|
||||
}
|
||||
} else if (GLOBAL_ACTION_KEY_EMERGENCY.equals(actionKey)) {
|
||||
if (mSeparatedEmergencyButtonEnabled
|
||||
&& !mEmergencyAffordanceManager.needsEmergencyAffordance()) {
|
||||
mItems.add(new EmergencyDialerAction());
|
||||
}
|
||||
} else {
|
||||
Log.e(TAG, "Invalid global action key " + actionKey);
|
||||
}
|
||||
@@ -386,7 +392,8 @@ class GlobalActionsDialog implements DialogInterface.OnDismissListener,
|
||||
}
|
||||
return false;
|
||||
};
|
||||
ActionsDialog dialog = new ActionsDialog(mContext, this, mAdapter, onItemLongClickListener);
|
||||
ActionsDialog dialog = new ActionsDialog(mContext, this, mAdapter, onItemLongClickListener,
|
||||
mSeparatedEmergencyButtonEnabled);
|
||||
dialog.setCanceledOnTouchOutside(false); // Handled by the custom class.
|
||||
dialog.setKeyguardShowing(mKeyguardShowing);
|
||||
|
||||
@@ -441,6 +448,32 @@ class GlobalActionsDialog implements DialogInterface.OnDismissListener,
|
||||
}
|
||||
}
|
||||
|
||||
private class EmergencyDialerAction extends SinglePressAction {
|
||||
private EmergencyDialerAction() {
|
||||
super(R.drawable.ic_faster_emergency,
|
||||
R.string.global_action_emergency);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPress() {
|
||||
Intent intent = new Intent(EmergencyDialerConstants.ACTION_DIAL);
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
|
||||
intent.putExtra(EmergencyDialerConstants.EXTRA_ENTRY_TYPE,
|
||||
EmergencyDialerConstants.ENTRY_TYPE_POWER_MENU);
|
||||
mContext.startActivityAsUser(intent, UserHandle.CURRENT);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean showDuringKeyguard() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean showBeforeProvisioning() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private final class RestartAction extends SinglePressAction implements LongPressAction {
|
||||
private RestartAction() {
|
||||
super(R.drawable.ic_restart, R.string.global_action_restart);
|
||||
@@ -626,6 +659,12 @@ class GlobalActionsDialog implements DialogInterface.OnDismissListener,
|
||||
}
|
||||
|
||||
private Action getEmergencyAction() {
|
||||
Drawable emergencyIcon = mContext.getDrawable(R.drawable.emergency_icon);
|
||||
if(!mSeparatedEmergencyButtonEnabled) {
|
||||
// use un-colored legacy treatment
|
||||
emergencyIcon.setTintList(null);
|
||||
}
|
||||
|
||||
return new SinglePressAction(R.drawable.emergency_icon,
|
||||
R.string.global_action_emergency) {
|
||||
@Override
|
||||
@@ -1354,15 +1393,17 @@ class GlobalActionsDialog implements DialogInterface.OnDismissListener,
|
||||
private final Context mContext;
|
||||
private final MyAdapter mAdapter;
|
||||
private final LinearLayout mListView;
|
||||
private final FrameLayout mSeparatedView;
|
||||
private final HardwareUiLayout mHardwareLayout;
|
||||
private final OnClickListener mClickListener;
|
||||
private final OnItemLongClickListener mLongClickListener;
|
||||
private final GradientDrawable mGradientDrawable;
|
||||
private final ColorExtractor mColorExtractor;
|
||||
private boolean mKeyguardShowing;
|
||||
private boolean mShouldDisplaySeparatedButton;
|
||||
|
||||
public ActionsDialog(Context context, OnClickListener clickListener, MyAdapter adapter,
|
||||
OnItemLongClickListener longClickListener) {
|
||||
OnItemLongClickListener longClickListener, boolean shouldDisplaySeparatedButton) {
|
||||
super(context, com.android.systemui.R.style.Theme_SystemUI_Dialog_GlobalActions);
|
||||
mContext = context;
|
||||
mAdapter = adapter;
|
||||
@@ -1370,6 +1411,7 @@ class GlobalActionsDialog implements DialogInterface.OnDismissListener,
|
||||
mLongClickListener = longClickListener;
|
||||
mGradientDrawable = new GradientDrawable(mContext);
|
||||
mColorExtractor = Dependency.get(SysuiColorExtractor.class);
|
||||
mShouldDisplaySeparatedButton = shouldDisplaySeparatedButton;
|
||||
|
||||
// Window initialization
|
||||
Window window = getWindow();
|
||||
@@ -1393,8 +1435,13 @@ class GlobalActionsDialog implements DialogInterface.OnDismissListener,
|
||||
|
||||
setContentView(com.android.systemui.R.layout.global_actions_wrapped);
|
||||
mListView = findViewById(android.R.id.list);
|
||||
mSeparatedView = findViewById(com.android.systemui.R.id.separated_button);
|
||||
if (!mShouldDisplaySeparatedButton) {
|
||||
mSeparatedView.setVisibility(View.GONE);
|
||||
}
|
||||
mHardwareLayout = HardwareUiLayout.get(mListView);
|
||||
mHardwareLayout.setOutsideTouchListener(view -> dismiss());
|
||||
mHardwareLayout.setHasSeparatedButton(mShouldDisplaySeparatedButton);
|
||||
setTitle(R.string.global_actions);
|
||||
mListView.setAccessibilityDelegate(new View.AccessibilityDelegate() {
|
||||
@Override
|
||||
@@ -1409,13 +1456,16 @@ class GlobalActionsDialog implements DialogInterface.OnDismissListener,
|
||||
|
||||
private void updateList() {
|
||||
mListView.removeAllViews();
|
||||
mSeparatedView.removeAllViews();
|
||||
for (int i = 0; i < mAdapter.getCount(); i++) {
|
||||
View v = mAdapter.getView(i, null, mListView);
|
||||
ViewGroup parentView = mShouldDisplaySeparatedButton && i == mAdapter.getCount() - 1
|
||||
? mSeparatedView : mListView;
|
||||
View v = mAdapter.getView(i, null, parentView);
|
||||
final int pos = i;
|
||||
v.setOnClickListener(view -> mClickListener.onClick(this, pos));
|
||||
v.setOnLongClickListener(view ->
|
||||
mLongClickListener.onItemLongClick(null, v, pos, 0));
|
||||
mListView.addView(v);
|
||||
parentView.addView(v);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (C) 2018 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.systemui.util;
|
||||
|
||||
/**
|
||||
* Constants defined and used in emergency dialer.
|
||||
* Please keep these constants being consistent with those in com.android.phone.EmergencyDialer.
|
||||
*/
|
||||
public class EmergencyDialerConstants {
|
||||
// Intent action for emergency dialer activity.
|
||||
public static final String ACTION_DIAL = "com.android.phone.EmergencyDialer.DIAL";
|
||||
|
||||
/**
|
||||
* Extra included in {@link #ACTION_DIAL} to indicate the entry type that user starts
|
||||
* the emergency dialer.
|
||||
*/
|
||||
public static final String EXTRA_ENTRY_TYPE =
|
||||
"com.android.phone.EmergencyDialer.extra.ENTRY_TYPE";
|
||||
|
||||
// Indicating the entrance to emergency dialer
|
||||
public static final int ENTRY_TYPE_UNKNOWN = 0;
|
||||
public static final int ENTRY_TYPE_LOCKSCREEN_BUTTON = 1;
|
||||
public static final int ENTRY_TYPE_POWER_MENU = 2;
|
||||
}
|
||||
@@ -6429,6 +6429,59 @@ message MetricsEvent {
|
||||
// OS: Q (will also ship in PQ1A)
|
||||
FIELD_ACTIVITY_RECORD_MILLIS_SINCE_LAST_LAUNCH = 1553;
|
||||
|
||||
// OPEN: Emergency dialer opened
|
||||
// CLOSE: Emergency dialer closed
|
||||
// SUBTYPE: The entry type that user opened emergency dialer
|
||||
// CATEGORY: EMERGENCY_DIALER
|
||||
// OS: Q
|
||||
EMERGENCY_DIALER = 1558;
|
||||
|
||||
// FIELD: The screen is currently locked
|
||||
// CATEGORY: EMERGENCY_DIALER
|
||||
// OS: Q
|
||||
FIELD_EMERGENCY_DIALER_IS_SCREEN_LOCKED = 1559;
|
||||
|
||||
// FIELD: Bit flag indicating the actions performed by user
|
||||
// CATEGORY: EMERGENCY_DIALER
|
||||
// OS: Q
|
||||
FIELD_EMERGENCY_DIALER_USER_ACTIONS = 1560;
|
||||
|
||||
// FIELD: The duration user stayed at emergency dialer
|
||||
// CATEGORY: EMERGENCY_DIALER
|
||||
// OS: Q
|
||||
FIELD_EMERGENCY_DIALER_DURATION_MS = 1561;
|
||||
|
||||
// ACTION: Making call via emergency dialer
|
||||
// SUBTYPE: The UI that user made phone call
|
||||
// CATEGORY: EMERGENCY_DIALER
|
||||
// OS: Q
|
||||
EMERGENCY_DIALER_MAKE_CALL = 1562;
|
||||
|
||||
// FIELD: The phone number type of a call user made
|
||||
// CATEGORY: EMERGENCY_DIALER
|
||||
// OS: Q
|
||||
FIELD_EMERGENCY_DIALER_PHONE_NUMBER_TYPE = 1563;
|
||||
|
||||
// FIELD: There is a shortcut for the phone number
|
||||
// CATEGORY: EMERGENCY_DIALER
|
||||
// OS: Q
|
||||
FIELD_EMERGENCY_DIALER_PHONE_NUMBER_HAS_SHORTCUT = 1564;
|
||||
|
||||
// FIELD: The phone is in pocket while using emergency dialer
|
||||
// CATEGORY: EMERGENCY_DIALER
|
||||
// OS: Q
|
||||
FIELD_EMERGENCY_DIALER_IN_POCKET = 1565;
|
||||
|
||||
// ACTION: The second tap on emergency shortcut to make a phone call
|
||||
// CATEGORY: EMERGENCY_DIALER
|
||||
// OS: Q
|
||||
EMERGENCY_DIALER_SHORTCUT_CONFIRM_TAP = 1566;
|
||||
|
||||
// FIELD: The time in milliseconds of second tap on shortcut since first tap
|
||||
// CATEGORY: EMERGENCY_DIALER
|
||||
// OS: Q
|
||||
FIELD_EMERGENCY_DIALER_SHORTCUT_TAPS_INTERVAL = 1567;
|
||||
|
||||
// ---- End Q Constants, all Q constants go above this line ----
|
||||
|
||||
// Add new aosp constants above this line.
|
||||
|
||||
@@ -195,6 +195,8 @@ public class ParcelableCallAnalytics implements Parcelable {
|
||||
public static final int BLOCK_CHECK_FINISHED_TIMING = 9;
|
||||
public static final int FILTERING_COMPLETED_TIMING = 10;
|
||||
public static final int FILTERING_TIMED_OUT_TIMING = 11;
|
||||
/** {@hide} */
|
||||
public static final int START_CONNECTION_TO_REQUEST_DISCONNECT_TIMING = 12;
|
||||
|
||||
public static final int INVALID = 999999;
|
||||
|
||||
@@ -256,6 +258,27 @@ public class ParcelableCallAnalytics implements Parcelable {
|
||||
public static final int SIP_PHONE = 0x8;
|
||||
public static final int THIRD_PARTY_PHONE = 0x10;
|
||||
|
||||
/**
|
||||
* Indicating the call source is not specified.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public static final int CALL_SOURCE_UNSPECIFIED = 0;
|
||||
|
||||
/**
|
||||
* Indicating the call is initiated via emergency dialer's dialpad.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public static final int CALL_SOURCE_EMERGENCY_DIALPAD = 1;
|
||||
|
||||
/**
|
||||
* Indicating the call is initiated via emergency dialer's shortcut button.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public static final int CALL_SOURCE_EMERGENCY_SHORTCUT = 2;
|
||||
|
||||
public static final long MILLIS_IN_5_MINUTES = 1000 * 60 * 5;
|
||||
public static final long MILLIS_IN_1_SECOND = 1000;
|
||||
|
||||
@@ -319,6 +342,9 @@ public class ParcelableCallAnalytics implements Parcelable {
|
||||
// A list of video events that have occurred.
|
||||
private List<VideoEvent> videoEvents;
|
||||
|
||||
// The source where user initiated this call. ONE OF the CALL_SOURCE_* constants.
|
||||
private int callSource = CALL_SOURCE_UNSPECIFIED;
|
||||
|
||||
public ParcelableCallAnalytics(long startTimeMillis, long callDurationMillis, int callType,
|
||||
boolean isAdditionalCall, boolean isInterrupted, int callTechnologies,
|
||||
int callTerminationCode, boolean isEmergencyCall, String connectionService,
|
||||
@@ -356,6 +382,7 @@ public class ParcelableCallAnalytics implements Parcelable {
|
||||
isVideoCall = readByteAsBoolean(in);
|
||||
videoEvents = new LinkedList<>();
|
||||
in.readTypedList(videoEvents, VideoEvent.CREATOR);
|
||||
callSource = in.readInt();
|
||||
}
|
||||
|
||||
public void writeToParcel(Parcel out, int flags) {
|
||||
@@ -373,6 +400,7 @@ public class ParcelableCallAnalytics implements Parcelable {
|
||||
out.writeTypedList(eventTimings);
|
||||
writeBooleanAsByte(out, isVideoCall);
|
||||
out.writeTypedList(videoEvents);
|
||||
out.writeInt(callSource);
|
||||
}
|
||||
|
||||
/** {@hide} */
|
||||
@@ -385,6 +413,11 @@ public class ParcelableCallAnalytics implements Parcelable {
|
||||
this.videoEvents = videoEvents;
|
||||
}
|
||||
|
||||
/** {@hide} */
|
||||
public void setCallSource(int callSource) {
|
||||
this.callSource = callSource;
|
||||
}
|
||||
|
||||
public long getStartTimeMillis() {
|
||||
return startTimeMillis;
|
||||
}
|
||||
@@ -443,6 +476,11 @@ public class ParcelableCallAnalytics implements Parcelable {
|
||||
return videoEvents;
|
||||
}
|
||||
|
||||
/** {@hide} */
|
||||
public int getCallSource() {
|
||||
return callSource;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
|
||||
@@ -618,6 +618,18 @@ public class TelecomManager {
|
||||
public static final String EXTRA_USE_ASSISTED_DIALING =
|
||||
"android.telecom.extra.USE_ASSISTED_DIALING";
|
||||
|
||||
/**
|
||||
* Optional extra for {@link #placeCall(Uri, Bundle)} containing an integer that specifies
|
||||
* the source where user initiated this call. This data is used in metrics.
|
||||
* Valid source are:
|
||||
* {@link ParcelableCallAnalytics#CALL_SOURCE_UNSPECIFIED},
|
||||
* {@link ParcelableCallAnalytics#CALL_SOURCE_EMERGENCY_DIALPAD},
|
||||
* {@link ParcelableCallAnalytics#CALL_SOURCE_EMERGENCY_SHORTCUT}.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public static final String EXTRA_CALL_SOURCE = "android.telecom.extra.CALL_SOURCE";
|
||||
|
||||
/**
|
||||
* The following 4 constants define how properties such as phone numbers and names are
|
||||
* displayed to the user.
|
||||
|
||||
Reference in New Issue
Block a user