From 17af39b4b7280212f8eb4aec17ea24561568fd0b Mon Sep 17 00:00:00 2001 From: Pawan Chilka Date: Tue, 20 Nov 2018 14:25:06 +0530 Subject: [PATCH 001/240] Revert "Revert "Utilize 5G apis from telephony-ext instead of qtiNetworkLib."". This reverts commit 2f2a3ac9a6cabf50a365963668a8f864630a56c8. Change-Id: I2f4f6dc1a553f2594b8ed2be31b0fb9452a80a36 --- packages/SystemUI/Android.bp | 6 ++--- .../statusbar/policy/FiveGServiceClient.java | 22 +++++++++---------- packages/SystemUI/tests/Android.mk | 1 + 3 files changed, 15 insertions(+), 14 deletions(-) diff --git a/packages/SystemUI/Android.bp b/packages/SystemUI/Android.bp index e88eba67bab..172ee8a9970 100644 --- a/packages/SystemUI/Android.bp +++ b/packages/SystemUI/Android.bp @@ -58,7 +58,6 @@ android_library { "androidx.slice_slice-builders", "androidx.arch.core_core-runtime", "androidx.lifecycle_lifecycle-extensions", - "qtiNetworkLib", "SystemUI-tags", "SystemUI-proto", ], @@ -68,7 +67,7 @@ android_library { "telephony-common", "android.car", "android.car.user", - "ims-common", + "qtiNetworkLib", ], aaptflags: [ @@ -146,10 +145,11 @@ android_app { }, libs: [ + "telephony-ext", "telephony-common", "android.car", "android.car.user", - "ims-common", + "ims-common", ], dxflags: ["--multi-dex"], diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/FiveGServiceClient.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/FiveGServiceClient.java index 7b03eb82871..58a0d2b9b7c 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/FiveGServiceClient.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/FiveGServiceClient.java @@ -44,14 +44,14 @@ import java.lang.Exception; -import org.codeaurora.qti.qtiNetworkLib.Client; -import org.codeaurora.qti.qtiNetworkLib.DcParam; -import org.codeaurora.qti.qtiNetworkLib.INetworkCallback; -import org.codeaurora.qti.qtiNetworkLib.INetworkInterface; -import org.codeaurora.qti.qtiNetworkLib.ServiceUtil; -import org.codeaurora.qti.qtiNetworkLib.SignalStrength; -import org.codeaurora.qti.qtiNetworkLib.Status; -import org.codeaurora.qti.qtiNetworkLib.Token; +import org.codeaurora.internal.Client; +import org.codeaurora.internal.DcParam; +import org.codeaurora.internal.IExtTelephony; +import org.codeaurora.internal.INetworkCallback; +import org.codeaurora.internal.ServiceUtil; +import org.codeaurora.internal.SignalStrength; +import org.codeaurora.internal.Status; +import org.codeaurora.internal.Token; import com.android.systemui.R; @@ -72,7 +72,7 @@ public class FiveGServiceClient { private Context mContext; private boolean mServiceConnected; - private INetworkInterface mNetworkService; + private IExtTelephony mNetworkService; private String mPackageName; private Client mClient; private int mBindRetryTimes = 0; @@ -301,7 +301,7 @@ public void onServiceConnected(ComponentName name, IBinder service) { Log.d(TAG, "onServiceConnected:" + service); try { - mNetworkService = INetworkInterface.Stub.asInterface(service); + mNetworkService = IExtTelephony.Stub.asInterface(service); mClient = mNetworkService.registerCallback(mPackageName, mCallback); mServiceConnected = true; initFiveGServiceState(); @@ -392,7 +392,7 @@ public void onNrBearerAllocation(int slotId, Token token, Status status, boolean @Override public void onSignalStrength(int slotId, Token token, Status status, - org.codeaurora.qti.qtiNetworkLib.SignalStrength + org.codeaurora.internal.SignalStrength signalStrength) throws RemoteException { if ( DEBUG ) { Log.d(TAG, "onSignalStrength: slotId=" + slotId + " token=" + token diff --git a/packages/SystemUI/tests/Android.mk b/packages/SystemUI/tests/Android.mk index 4a49958dbba..288e671e54a 100644 --- a/packages/SystemUI/tests/Android.mk +++ b/packages/SystemUI/tests/Android.mk @@ -40,6 +40,7 @@ LOCAL_JAVA_LIBRARIES := \ android.test.base \ android.car \ android.car.user \ + telephony-ext \ ims-common LOCAL_AAPT_FLAGS := --extra-packages com.android.systemui:com.android.keyguard From 1e19ca34dd9a6aa93002b9da77afc1cedb40c503 Mon Sep 17 00:00:00 2001 From: Pawan Chilka Date: Tue, 20 Nov 2018 16:45:25 +0530 Subject: [PATCH 002/240] removing libs. Change-Id: I6e220fc6cdbd763d45b4e1cb467e8240aa0d3b03 --- packages/SystemUI/Android.bp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/packages/SystemUI/Android.bp b/packages/SystemUI/Android.bp index 172ee8a9970..3da85d1486f 100644 --- a/packages/SystemUI/Android.bp +++ b/packages/SystemUI/Android.bp @@ -67,7 +67,8 @@ android_library { "telephony-common", "android.car", "android.car.user", - "qtiNetworkLib", + "telephony-ext", + "ims-common", ], aaptflags: [ @@ -123,6 +124,8 @@ android_library { "android.car", "android.car.user", "android.test.base", + "telephony-ext", + "ims-common", ], aaptflags: [ "--extra-packages", @@ -145,11 +148,11 @@ android_app { }, libs: [ - "telephony-ext", "telephony-common", "android.car", "android.car.user", - "ims-common", + "telephony-ext", + "ims-common", ], dxflags: ["--multi-dex"], From 54ca89ac624fb1f10a084963e39c585b7e1fe883 Mon Sep 17 00:00:00 2001 From: Karthik Gopalan Date: Fri, 30 Nov 2018 19:56:23 +0530 Subject: [PATCH 003/240] Revert "Modify game detection logic" This reverts commit 564494b379e75cd671c84009af6c41e2370026cf. CRs-Fixed: 2359219 Change-Id: I9a8486ca2045149589ba27892b395376455003fd --- core/java/android/util/BoostFramework.java | 8 -------- .../com/android/server/am/ActivityStackSupervisor.java | 3 +-- 2 files changed, 1 insertion(+), 10 deletions(-) diff --git a/core/java/android/util/BoostFramework.java b/core/java/android/util/BoostFramework.java index 1c679f178ba..eca87fad115 100644 --- a/core/java/android/util/BoostFramework.java +++ b/core/java/android/util/BoostFramework.java @@ -117,14 +117,6 @@ public class Draw { public static final int EVENT_TYPE_V1 = 1; }; - public class WorkloadType { - public static final int NOT_KNOWN = 0; - public static final int APP = 1; - public static final int GAME = 2; - public static final int BROWSER = 3; - public static final int PREPROAPP = 4; - }; - /** @hide */ public BoostFramework() { initFunctions(); diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java index 90fdaa1b899..2af79f1ef64 100644 --- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java +++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java @@ -3427,8 +3427,7 @@ void acquireAppLaunchPerfLock(ActivityRecord r) { mPerfSendTapHint = true; mPerfBoost.perfHint(BoostFramework.VENDOR_HINT_FIRST_LAUNCH_BOOST, r.packageName, -1, BoostFramework.Launch.BOOST_V2); - if(mPerfBoost.perfGetFeedback(BoostFramework.VENDOR_FEEDBACK_WORKLOAD_TYPE, r.packageName) == BoostFramework.WorkloadType.GAME) - { + if (r.isAppInfoGame() == 1) { mPerfHandle = mPerfBoost.perfHint(BoostFramework.VENDOR_HINT_FIRST_LAUNCH_BOOST, r.packageName, -1, BoostFramework.Launch.BOOST_GAME); } else { From ac8d34bbe343d7a2d09adb3faef1e778d7358828 Mon Sep 17 00:00:00 2001 From: Karthik Gopalan Date: Mon, 3 Dec 2018 10:59:31 +0530 Subject: [PATCH 004/240] Revert "Add perfGetFeedback api support from framework" This reverts commit 7cbcaa1863b99f6e6af54a688c9ab0e0bfdf28f4. CRs-Fixed: 2359219 Change-Id: I3a580c2c4e9b2c945d447de1533029867725837d --- core/java/android/util/BoostFramework.java | 21 --------------------- 1 file changed, 21 deletions(-) diff --git a/core/java/android/util/BoostFramework.java b/core/java/android/util/BoostFramework.java index eca87fad115..856969ea0a1 100644 --- a/core/java/android/util/BoostFramework.java +++ b/core/java/android/util/BoostFramework.java @@ -53,7 +53,6 @@ public class BoostFramework { private static Method sPerfHintFunc = null; private static Method sReleaseFunc = null; private static Method sReleaseHandlerFunc = null; - private static Method sFeedbackFunc = null; private static int sIopv2 = -1; private static Method sIOPStart = null; @@ -84,9 +83,6 @@ public class BoostFramework { //perf events public static final int VENDOR_HINT_FIRST_DRAW = 0x00001042; public static final int VENDOR_HINT_TAP_EVENT = 0x00001043; - //feedback hints - public static final int VENDOR_FEEDBACK_WORKLOAD_TYPE = 0x00001601; - public static final int VENDOR_FEEDBACK_LAUNCH_END_POINT = 0x00001602; //UXE Events and Triggers public static final int UXE_TRIGGER = 1; @@ -190,9 +186,6 @@ private void initFunctions () { argClasses = new Class[] {int.class}; sReleaseHandlerFunc = sPerfClass.getDeclaredMethod("perfLockReleaseHandler", argClasses); - argClasses = new Class[] {int.class, String.class}; - sFeedbackFunc = sPerfClass.getMethod("perfGetFeedback", argClasses); - argClasses = new Class[] {int.class, String.class, String.class}; sIOPStart = sPerfClass.getDeclaredMethod("perfIOPrefetchStart", argClasses); @@ -299,20 +292,6 @@ public int perfHint(int hint, String userDataStr, int userData1, int userData2) return ret; } -/** @hide */ - public int perfGetFeedback(int req, String userDataStr) { - int ret = -1; - try { - if (sFeedbackFunc != null) { - Object retVal = sFeedbackFunc.invoke(mPerf, req, userDataStr); - ret = (int)retVal; - } - } catch(Exception e) { - Log.e(TAG,"Exception " + e); - } - return ret; - } - /** @hide */ public int perfIOPrefetchStart(int pid, String pkgName, String codePath) { int ret = -1; From 6d814fa86c05cd4a158e016f188f79821d0801fd Mon Sep 17 00:00:00 2001 From: Karthik Gopalan Date: Fri, 30 Nov 2018 19:58:27 +0530 Subject: [PATCH 005/240] Revert "Precise new activity boost. (#2)" This reverts commit f893260618712d3894d1279e27ee121d4be8817f. CRs-Fixed: 2359219 Change-Id: Ia5ff12e12207031a8fb68f5410c2e20b4d5d0c48 --- .../java/com/android/server/am/ActivityMetricsLogger.java | 5 ----- .../core/java/com/android/server/am/ActivityRecord.java | 7 ++----- .../core/java/com/android/server/am/ActivityStarter.java | 7 +------ 3 files changed, 3 insertions(+), 16 deletions(-) diff --git a/services/core/java/com/android/server/am/ActivityMetricsLogger.java b/services/core/java/com/android/server/am/ActivityMetricsLogger.java index ae73f000e2f..0883001bd88 100644 --- a/services/core/java/com/android/server/am/ActivityMetricsLogger.java +++ b/services/core/java/com/android/server/am/ActivityMetricsLogger.java @@ -699,11 +699,6 @@ private void logAppDisplayed(WindowingModeTransitionInfoSnapshot info) { if (mPerfFirstDraw != null) { mPerfFirstDraw.perfHint(BoostFramework.VENDOR_HINT_FIRST_DRAW, info.packageName, info.windowsDrawnDelayMs, BoostFramework.Draw.EVENT_TYPE_V1); } - - if (mLaunchedActivity.mPerf != null && mLaunchedActivity.perfActivityBoostHandler > 0) { - mLaunchedActivity.mPerf.perfLockReleaseHandler(mLaunchedActivity.perfActivityBoostHandler); - mLaunchedActivity.perfActivityBoostHandler = -1; - } } private int convertAppStartTransitionType(int tronType) { diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java index 934336dee81..f1a3f84bada 100644 --- a/services/core/java/com/android/server/am/ActivityRecord.java +++ b/services/core/java/com/android/server/am/ActivityRecord.java @@ -275,7 +275,7 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo private int theme; // resource identifier of activity's theme. private int realTheme; // actual theme resource we will use, never 0. private int windowFlags; // custom window flags for preview window. - public int perfActivityBoostHandler = -1; //perflock handler when activity is created. + int perfActivityBoostHandler = -1; //perflock handler when activity is created. private TaskRecord task; // the task this is in. private long createTime = System.currentTimeMillis(); long lastVisibleTime; // last time this activity became visible @@ -369,7 +369,7 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo boolean pendingVoiceInteractionStart; // Waiting for activity-invoked voice session IVoiceInteractionSession voiceSession; // Voice interaction session for this activity - public BoostFramework mPerf = null; + private BoostFramework mPerf = null; public BoostFramework mUxPerf = new BoostFramework(); public BoostFramework mPerf_iop = null; @@ -1021,9 +1021,6 @@ boolean isResolverOrChildActivity() { lockTaskLaunchMode = LOCK_TASK_LAUNCH_MODE_IF_WHITELISTED; } } - - if (mPerf == null) - mPerf = new BoostFramework(); } void setProcess(WindowProcessController proc) { diff --git a/services/core/java/com/android/server/am/ActivityStarter.java b/services/core/java/com/android/server/am/ActivityStarter.java index b1a912bafb8..8b8523d02fa 100644 --- a/services/core/java/com/android/server/am/ActivityStarter.java +++ b/services/core/java/com/android/server/am/ActivityStarter.java @@ -1462,7 +1462,6 @@ private int startActivityUnchecked(final ActivityRecord r, ActivityRecord source newTask = true; String packageName= mService.mContext.getPackageName(); if (mPerf != null) { - mStartActivity.perfActivityBoostHandler = mPerf.perfHint(BoostFramework.VENDOR_HINT_FIRST_LAUNCH_BOOST, packageName, -1, BoostFramework.Launch.BOOST_V1); } @@ -2135,11 +2134,7 @@ private int setTaskFromSourceRecord() { return START_RETURN_LOCK_TASK_MODE_VIOLATION; } String packageName= mService.mContext.getPackageName(); - if (mPerf != null) { - mStartActivity.perfActivityBoostHandler = - mPerf.perfHint(BoostFramework.VENDOR_HINT_FIRST_LAUNCH_BOOST, - packageName, -1, BoostFramework.Launch.BOOST_V1); - } + final TaskRecord sourceTask = mSourceRecord.getTask(); final ActivityStack sourceStack = mSourceRecord.getStack(); // We only want to allow changing stack in two cases: From 26f604f17164904c245090ef7b164324d55a3870 Mon Sep 17 00:00:00 2001 From: Karthik Gopalan Date: Sat, 1 Dec 2018 19:09:53 +0530 Subject: [PATCH 006/240] Revert "Disable swipe boost and preferred apps for certain cases" This reverts commit c0cbee2fe77113d04cc1ee6abfb0e0206efc93ef. CRs-Fixed: 2359219 Change-Id: Ib605a974aa6fceb0e2d260846225dc171f4da065 --- core/java/android/util/BoostFramework.java | 3 +- core/java/android/view/ViewRootImpl.java | 2 +- core/java/android/widget/OverScroller.java | 5 ++- .../server/am/ActivityManagerService.java | 2 ++ .../server/am/ActivityMetricsLogger.java | 5 --- .../com/android/server/am/ActivityRecord.java | 13 ++------ .../server/am/ActivityStackSupervisor.java | 18 ++--------- .../server/policy/PhoneWindowManager.java | 32 +++---------------- .../SystemGesturesPointerEventListener.java | 3 -- .../wm/TaskTapPointerEventListener.java | 9 ++---- 10 files changed, 19 insertions(+), 73 deletions(-) diff --git a/core/java/android/util/BoostFramework.java b/core/java/android/util/BoostFramework.java index 856969ea0a1..c6af8383bf4 100644 --- a/core/java/android/util/BoostFramework.java +++ b/core/java/android/util/BoostFramework.java @@ -89,7 +89,7 @@ public class BoostFramework { public static final int UXE_EVENT_BINDAPP = 2; public static final int UXE_EVENT_DISPLAYED_ACT = 3; public static final int UXE_EVENT_KILL = 4; - public static final int UXE_EVENT_GAME = 5; + public static final int UXE_EVENT_WAKELOCK = 5; public static final int UXE_EVENT_SUB_LAUNCH = 6; public static final int UXE_EVENT_PKG_UNINSTALL = 7; public static final int UXE_EVENT_PKG_INSTALL = 8; @@ -105,7 +105,6 @@ public class Launch { public static final int BOOST_V1 = 1; public static final int BOOST_V2 = 2; public static final int BOOST_V3 = 3; - public static final int BOOST_GAME = 4; public static final int TYPE_SERVICE_START = 100; }; diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index 3e6480e7024..f4ad236e35e 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -168,7 +168,7 @@ public final class ViewRootImpl implements ViewParent, public static final String PROPERTY_EMULATOR_WIN_OUTSET_BOTTOM_PX = "ro.emu.win_outset_bottom_px"; - private final boolean SCROLL_BOOST_SS_ENABLE = + private static final boolean SCROLL_BOOST_SS_ENABLE = SystemProperties.getBoolean("vendor.perf.gestureflingboost.enable", false); /** diff --git a/core/java/android/widget/OverScroller.java b/core/java/android/widget/OverScroller.java index 88799011125..c9fd53d95ff 100644 --- a/core/java/android/widget/OverScroller.java +++ b/core/java/android/widget/OverScroller.java @@ -47,7 +47,8 @@ public class OverScroller { private static final int SCROLL_MODE = 0; private static final int FLING_MODE = 1; - private static boolean SCROLL_BOOST_SS_ENABLE = false; + private static final boolean SCROLL_BOOST_SS_ENABLE = + SystemProperties.getBoolean("vendor.perf.gestureflingboost.enable", false); /** @@ -86,8 +87,6 @@ public OverScroller(Context context, Interpolator interpolator, boolean flywheel mFlywheel = flywheel; mScrollerX = new SplineOverScroller(context); mScrollerY = new SplineOverScroller(context); - SCROLL_BOOST_SS_ENABLE = - SystemProperties.getBoolean("vendor.perf.gestureflingboost.enable", false); } /** diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index c3ac53ab8d4..020086a9f34 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -527,7 +527,9 @@ public class ActivityManagerService extends IActivityManager.Stub private static final int NATIVE_DUMP_TIMEOUT_MS = 2000; // 2 seconds; /* Freq Aggr boost objects */ + public static BoostFramework mPerf = null; public static BoostFramework mPerfServiceStartHint = null; + public static boolean mIsPerfLockAcquired = false; /* UX perf event object */ public static BoostFramework mUxPerf = new BoostFramework(); diff --git a/services/core/java/com/android/server/am/ActivityMetricsLogger.java b/services/core/java/com/android/server/am/ActivityMetricsLogger.java index 0883001bd88..f8c078cee27 100644 --- a/services/core/java/com/android/server/am/ActivityMetricsLogger.java +++ b/services/core/java/com/android/server/am/ActivityMetricsLogger.java @@ -687,11 +687,6 @@ private void logAppDisplayed(WindowingModeTransitionInfoSnapshot info) { Log.i(TAG, sb.toString()); - int isGame = mLaunchedActivity.isAppInfoGame(); - if (mLaunchedActivity.mUxPerf != null) { - mLaunchedActivity.mUxPerf.perfUXEngine_events(BoostFramework.UXE_EVENT_GAME, 0, info.packageName, isGame); - } - if (mPerfFirstDraw == null) { mPerfFirstDraw = new BoostFramework(); } diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java index f1a3f84bada..deece8bb813 100644 --- a/services/core/java/com/android/server/am/ActivityRecord.java +++ b/services/core/java/com/android/server/am/ActivityRecord.java @@ -1021,6 +1021,9 @@ boolean isResolverOrChildActivity() { lockTaskLaunchMode = LOCK_TASK_LAUNCH_MODE_IF_WHITELISTED; } } + + if (mPerf == null) + mPerf = new BoostFramework(); } void setProcess(WindowProcessController proc) { @@ -2075,16 +2078,6 @@ public void reportFullyDrawnLocked(boolean restoredFromBundle) { info.windowsFullyDrawnDelayMs); } } - - public int isAppInfoGame() { - int isGame = 0; - if (appInfo != null) { - isGame = (appInfo.category == ApplicationInfo.CATEGORY_GAME || - (appInfo.flags & ApplicationInfo.FLAG_IS_GAME) == ApplicationInfo.FLAG_IS_GAME) ? 1 : 0; - } - return isGame; - } - @Override public void onStartingWindowDrawn(long timestamp) { synchronized (service.mGlobalLock) { diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java index 2af79f1ef64..a0965fc8b7e 100644 --- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java +++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java @@ -232,8 +232,6 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D static final int LAUNCH_TIMEOUT_MSG = FIRST_SUPERVISOR_STACK_MSG + 4; public static boolean mPerfSendTapHint = false; - public static boolean mIsPerfBoostAcquired = false; - public static int mPerfHandle = -1; public BoostFramework mPerfBoost = null; public BoostFramework mUxPerf = null; static final int HANDLE_DISPLAY_ADDED = FIRST_SUPERVISOR_STACK_MSG + 5; @@ -3426,23 +3424,13 @@ void acquireAppLaunchPerfLock(ActivityRecord r) { mPerfBoost.perfHint(BoostFramework.VENDOR_HINT_FIRST_LAUNCH_BOOST, r.packageName, -1, BoostFramework.Launch.BOOST_V1); mPerfSendTapHint = true; mPerfBoost.perfHint(BoostFramework.VENDOR_HINT_FIRST_LAUNCH_BOOST, r.packageName, -1, BoostFramework.Launch.BOOST_V2); - - if (r.isAppInfoGame() == 1) { - mPerfHandle = mPerfBoost.perfHint(BoostFramework.VENDOR_HINT_FIRST_LAUNCH_BOOST, r.packageName, -1, - BoostFramework.Launch.BOOST_GAME); - } else { - mPerfHandle = mPerfBoost.perfHint(BoostFramework.VENDOR_HINT_FIRST_LAUNCH_BOOST, r.packageName, -1, - BoostFramework.Launch.BOOST_V3); - } - if (mPerfHandle > 0) - mIsPerfBoostAcquired = true; + } // Start IOP mPerfBoost.perfIOPrefetchStart(-1,r.packageName, r.appInfo.sourceDir.substring(0, r.appInfo.sourceDir.lastIndexOf('/'))); - } - } + } - void acquireUxPerfLock(int opcode, String packageName) { + void acquireUxPerfLock(int opcode, String packageName) { mUxPerf = new BoostFramework(); if (mUxPerf != null) { mUxPerf.perfUXEngine_events(opcode, 0, packageName, 0); diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java index 32623389856..47bef22ed79 100644 --- a/services/core/java/com/android/server/policy/PhoneWindowManager.java +++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java @@ -22,7 +22,6 @@ import static android.app.AppOpsManager.OP_TOAST_WINDOW; import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME; import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD; -import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS; import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM; import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY; @@ -1848,24 +1847,6 @@ public void setDefaultDisplay(DisplayContentInfo displayContentInfo) { mDefaultOrientationListener = mDefaultDisplayRotation.getOrientationListener(); } - private boolean isTopAppGame() { - boolean isGame = false; - try { - ActivityManager.RunningTaskInfo rti = ActivityManager.getService().getFilteredTasks(1, - ACTIVITY_TYPE_RECENTS, WINDOWING_MODE_UNDEFINED).get(0); - ApplicationInfo ai = mContext.getPackageManager().getApplicationInfo( - rti.topActivity.getPackageName(), 0); - if(ai != null) { - isGame = (ai.category == ApplicationInfo.CATEGORY_GAME) || - ((ai.flags & ApplicationInfo.FLAG_IS_GAME) == - ApplicationInfo.FLAG_IS_GAME); - } - } catch (Exception e) { - return false; - } - return isGame; - } - /** {@inheritDoc} */ @Override public void init(Context context, IWindowManager windowManager, @@ -2069,16 +2050,12 @@ public void onSwipeFromLeft() { } @Override public void onFling(int duration) { + String currentPackage = mContext.getPackageName(); if (mPowerManagerInternal != null) { mPowerManagerInternal.powerHint( PowerHint.INTERACTION, duration); } - } - @Override - public void onVerticalFling(int duration) { - String currentPackage = mContext.getPackageName(); - boolean isGame = isTopAppGame(); - if (SCROLL_BOOST_SS_ENABLE && !isGame) { + if (SCROLL_BOOST_SS_ENABLE) { if (mPerfBoostFling == null) { mPerfBoostFling = new BoostFramework(); mIsPerfBoostFlingAcquired = false; @@ -2096,7 +2073,6 @@ public void onVerticalFling(int duration) { @Override public void onScroll(boolean started) { String currentPackage = mContext.getPackageName(); - boolean isGame = isTopAppGame(); if (mPerfBoostDrag == null) { mPerfBoostDrag = new BoostFramework(); } @@ -2104,7 +2080,7 @@ public void onScroll(boolean started) { Slog.e(TAG, "Error: boost object null"); return; } - if (SCROLL_BOOST_SS_ENABLE && !isGame) { + if (SCROLL_BOOST_SS_ENABLE) { if (mPerfBoostPrefling == null) { mPerfBoostPrefling = new BoostFramework(); } @@ -2115,7 +2091,7 @@ public void onScroll(boolean started) { mPerfBoostPrefling.perfHint(BoostFramework.VENDOR_HINT_SCROLL_BOOST, currentPackage, -1, BoostFramework.Scroll.PREFILING); } - if (!isGame && started) { + if (started) { mPerfBoostDrag.perfHint(BoostFramework.VENDOR_HINT_DRAG_BOOST, currentPackage, -1, 1); } else { diff --git a/services/core/java/com/android/server/policy/SystemGesturesPointerEventListener.java b/services/core/java/com/android/server/policy/SystemGesturesPointerEventListener.java index 1c3faed3f30..c718365177b 100644 --- a/services/core/java/com/android/server/policy/SystemGesturesPointerEventListener.java +++ b/services/core/java/com/android/server/policy/SystemGesturesPointerEventListener.java @@ -269,8 +269,6 @@ public boolean onFling(MotionEvent down, MotionEvent up, if (duration > MAX_FLING_TIME_MILLIS) { duration = MAX_FLING_TIME_MILLIS; } - if(Math.abs(velocityY) >= Math.abs(velocityX)) - mCallbacks.onVerticalFling(duration); mLastFlingTime = now; mCallbacks.onFling(duration); return true; @@ -293,7 +291,6 @@ interface Callbacks { void onSwipeFromRight(); void onSwipeFromLeft(); void onFling(int durationMs); - void onVerticalFling(int durationMs); void onScroll(boolean started); void onDown(); void onUpOrCancel(); diff --git a/services/core/java/com/android/server/wm/TaskTapPointerEventListener.java b/services/core/java/com/android/server/wm/TaskTapPointerEventListener.java index 93caa7d9848..b2f5142fa2d 100644 --- a/services/core/java/com/android/server/wm/TaskTapPointerEventListener.java +++ b/services/core/java/com/android/server/wm/TaskTapPointerEventListener.java @@ -118,12 +118,9 @@ public void onPointerEvent(MotionEvent motionEvent) { } break; } - if (ActivityStackSupervisor.mIsPerfBoostAcquired && (mPerfObj != null)) { - if (ActivityStackSupervisor.mPerfHandle > 0) { - mPerfObj.perfLockReleaseHandler(ActivityStackSupervisor.mPerfHandle); - ActivityStackSupervisor.mPerfHandle = -1; - } - ActivityStackSupervisor.mIsPerfBoostAcquired = false; + if (ActivityManagerService.mIsPerfLockAcquired) { + ActivityManagerService.mPerf.perfLockRelease(); + ActivityManagerService.mIsPerfLockAcquired = false; } if (ActivityStackSupervisor.mPerfSendTapHint && (mPerfObj != null)) { mPerfObj.perfHint(BoostFramework.VENDOR_HINT_TAP_EVENT, null); From 9bff92ac2041db498c2200110f580b851b17ed0d Mon Sep 17 00:00:00 2001 From: Karthik Gopalan Date: Mon, 3 Dec 2018 11:03:05 +0530 Subject: [PATCH 007/240] Revert "Support the perflock request from system/priv apps whose domain are untrusted" This reverts commit e10907f2e60ddd0035ddb2477300c22aaaa4491f. CRs-Fixed: 2359219 Change-Id: I88a0f9aed2c35abfd7092fa363cf1a760ba1708e --- core/java/android/util/BoostFramework.java | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/core/java/android/util/BoostFramework.java b/core/java/android/util/BoostFramework.java index c6af8383bf4..b351bac9af2 100644 --- a/core/java/android/util/BoostFramework.java +++ b/core/java/android/util/BoostFramework.java @@ -148,25 +148,6 @@ public BoostFramework(Context context) { } } -/** @hide */ - public BoostFramework(boolean isUntrustedDomain) { - initFunctions(); - - try { - if (sPerfClass != null) { - Constructor cons = sPerfClass.getConstructor(boolean.class); - if (cons != null) - mPerf = cons.newInstance(isUntrustedDomain); - } - if (sUxPerfClass != null) { - mUxPerf = sUxPerfClass.newInstance(); - } - } - catch(Exception e) { - Log.e(TAG,"BoostFramework() : Exception_5 = " + e); - } - } - private void initFunctions () { synchronized(BoostFramework.class) { if (sIsLoaded == false) { From 704dc2b9ef591b52b4f2b27232c85d3bce9e4c85 Mon Sep 17 00:00:00 2001 From: Karthik Gopalan Date: Mon, 3 Dec 2018 11:10:22 +0530 Subject: [PATCH 008/240] Revert "IOP/UXE: This change is related to IOP and UXE Feature." This reverts commit 48c825913424338b51da30b2d7e5591ccbfaefc6. CRs-Fixed: 2359219 Change-Id: I416f8341ba10137ba398a11e4b6a3736d3e8e40a --- core/java/android/app/ActivityThread.java | 19 +-- core/java/android/util/BoostFramework.java | 134 +----------------- .../server/am/ActivityManagerService.java | 46 ------ .../server/am/ActivityMetricsLogger.java | 19 --- .../com/android/server/am/ActivityRecord.java | 37 +---- .../server/am/ActivityStackSupervisor.java | 37 ++--- .../com/android/server/am/ProcessRecord.java | 5 - .../server/pm/PackageManagerService.java | 14 -- 8 files changed, 21 insertions(+), 290 deletions(-) diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index 6090938066a..d973b0c2484 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -116,7 +116,6 @@ import android.security.net.config.NetworkSecurityConfigProvider; import android.util.AndroidRuntimeException; import android.util.ArrayMap; -import android.util.BoostFramework; import android.util.DisplayMetrics; import android.util.EventLog; import android.util.Log; @@ -5730,8 +5729,6 @@ private void updateLocaleListFromAppContext(Context context, LocaleList newLocal @UnsupportedAppUsage private void handleBindApplication(AppBindData data) { - long st_bindApp = SystemClock.uptimeMillis(); - BoostFramework ux_perf = null; // Register the UI Thread as a sensitive thread to the runtime. VMRuntime.registerSensitiveThread(); if (data.trackAllocation) { @@ -5956,7 +5953,12 @@ private void handleBindApplication(AppBindData data) { mResourcesManager.getConfiguration().getLocales()); if (!Process.isIsolated()) { - ux_perf = new BoostFramework(appContext); + final int old_mask = StrictMode.allowThreadDiskWritesMask(); + try { + // ux_perf = new BoostFramework(appContext); + } finally { + StrictMode.setThreadPolicyMask(old_mask); + } } if (!Process.isIsolated()) { @@ -6114,15 +6116,6 @@ private void handleBindApplication(AppBindData data) { throw e.rethrowFromSystemServer(); } } - long end_bindApp = SystemClock.uptimeMillis(); - int bindApp_dur = (int) (end_bindApp - st_bindApp); - String pkg_name = null; - if (appContext != null) { - pkg_name = appContext.getPackageName(); - } - if (ux_perf != null && !Process.isIsolated() && pkg_name != null) { - ux_perf.perfUXEngine_events(BoostFramework.UXE_EVENT_BINDAPP, 0, pkg_name, bindApp_dur); - } } /*package*/ final void finishInstrumentation(int resultCode, Bundle results) { diff --git a/core/java/android/util/BoostFramework.java b/core/java/android/util/BoostFramework.java index b351bac9af2..ccc3695a407 100644 --- a/core/java/android/util/BoostFramework.java +++ b/core/java/android/util/BoostFramework.java @@ -29,12 +29,10 @@ package android.util; -import android.content.Context; -import android.os.SystemProperties; import android.util.Log; - import java.lang.reflect.Constructor; import java.lang.reflect.Method; +import android.content.Context; /** @hide */ public class BoostFramework { @@ -43,9 +41,6 @@ public class BoostFramework { private static final String PERFORMANCE_JAR = "/system/framework/QPerformance.jar"; private static final String PERFORMANCE_CLASS = "com.qualcomm.qti.Performance"; - private static final String UXPERFORMANCE_JAR = "/system/framework/UxPerformance.jar"; - private static final String UXPERFORMANCE_CLASS = "com.qualcomm.qti.UxPerformance"; - /** @hide */ private static boolean sIsLoaded = false; private static Class sPerfClass = null; @@ -54,19 +49,8 @@ public class BoostFramework { private static Method sReleaseFunc = null; private static Method sReleaseHandlerFunc = null; - private static int sIopv2 = -1; - private static Method sIOPStart = null; - private static Method sIOPStop = null; - private static Method sUXEngineEvents = null; - private static Method sUXEngineTrigger = null; - - private static boolean sUxIsLoaded = false; - private static Class sUxPerfClass = null; - private static Method sUxIOPStart = null; - /** @hide */ private Object mPerf = null; - private Object mUxPerf = null; //perf hints public static final int VENDOR_HINT_SCROLL_BOOST = 0x00001080; @@ -84,16 +68,6 @@ public class BoostFramework { public static final int VENDOR_HINT_FIRST_DRAW = 0x00001042; public static final int VENDOR_HINT_TAP_EVENT = 0x00001043; - //UXE Events and Triggers - public static final int UXE_TRIGGER = 1; - public static final int UXE_EVENT_BINDAPP = 2; - public static final int UXE_EVENT_DISPLAYED_ACT = 3; - public static final int UXE_EVENT_KILL = 4; - public static final int UXE_EVENT_WAKELOCK = 5; - public static final int UXE_EVENT_SUB_LAUNCH = 6; - public static final int UXE_EVENT_PKG_UNINSTALL = 7; - public static final int UXE_EVENT_PKG_INSTALL = 8; - public class Scroll { public static final int VERTICAL = 1; public static final int HORIZONTAL = 2; @@ -120,9 +94,6 @@ public BoostFramework() { if (sPerfClass != null) { mPerf = sPerfClass.newInstance(); } - if (sUxPerfClass != null) { - mUxPerf = sUxPerfClass.newInstance(); - } } catch(Exception e) { Log.e(TAG,"BoostFramework() : Exception_2 = " + e); @@ -139,9 +110,6 @@ public BoostFramework(Context context) { if (cons != null) mPerf = cons.newInstance(context); } - if (sUxPerfClass != null) { - mUxPerf = sUxPerfClass.newInstance(); - } } catch(Exception e) { Log.e(TAG,"BoostFramework() : Exception_3 = " + e); @@ -166,42 +134,11 @@ private void initFunctions () { argClasses = new Class[] {int.class}; sReleaseHandlerFunc = sPerfClass.getDeclaredMethod("perfLockReleaseHandler", argClasses); - argClasses = new Class[] {int.class, String.class, String.class}; - sIOPStart = sPerfClass.getDeclaredMethod("perfIOPrefetchStart", argClasses); - - argClasses = new Class[] {}; - sIOPStop = sPerfClass.getDeclaredMethod("perfIOPrefetchStop", argClasses); - - try { - argClasses = new Class[] {int.class, int.class, String.class, int.class}; - sUXEngineEvents = sPerfClass.getDeclaredMethod("perfUXEngine_events", - argClasses); - - argClasses = new Class[] {int.class}; - sUXEngineTrigger = sPerfClass.getDeclaredMethod("perfUXEngine_trigger", - argClasses); - } catch (Exception e) { - Log.i(TAG, "BoostFramework() : Exception_4 = PreferredApps not supported"); - } - sIsLoaded = true; } catch(Exception e) { Log.e(TAG,"BoostFramework() : Exception_1 = " + e); } - // Load UXE Class now Adding new try/catch block to avoid - // any interference with Qperformance - try { - sUxPerfClass = Class.forName(UXPERFORMANCE_CLASS); - - Class[] argUxClasses = new Class[] {int.class, String.class, String.class}; - sUxIOPStart = sUxPerfClass.getDeclaredMethod("perfIOPrefetchStart", argUxClasses); - - sUxIsLoaded = true; - } - catch(Exception e) { - Log.e(TAG,"BoostFramework() Ux Perf: Exception = " + e); - } } } } @@ -271,73 +208,4 @@ public int perfHint(int hint, String userDataStr, int userData1, int userData2) } return ret; } - -/** @hide */ - public int perfIOPrefetchStart(int pid, String pkgName, String codePath) { - int ret = -1; - try { - Object retVal = sIOPStart.invoke(mPerf, pid, pkgName, codePath); - ret = (int) retVal; - } catch (Exception e) { - Log.e(TAG, "Exception " + e); - } - try { - Object retVal = sUxIOPStart.invoke(mUxPerf, pid, pkgName, codePath); - ret = (int) retVal; - } catch (Exception e) { - Log.e(TAG, "Ux Perf Exception " + e); - } - - return ret; - } - -/** @hide */ - public int perfIOPrefetchStop() { - int ret = -1; - try { - Object retVal = sIOPStop.invoke(mPerf); - ret = (int) retVal; - } catch (Exception e) { - Log.e(TAG, "Exception " + e); - } - return ret; - } - -/** @hide */ - public int perfUXEngine_events(int opcode, int pid, String pkgName, int lat) { - int ret = -1; - if (sIopv2 == -1) { - sIopv2 = SystemProperties.getInt("vendor.iop.enable_uxe", 0); - } - - try { - if (sIopv2 == 0 || sUXEngineEvents == null) { - return ret; - } - Object retVal = sUXEngineEvents.invoke(mPerf, opcode, pid, pkgName, lat); - ret = (int) retVal; - } catch (Exception e) { - Log.e(TAG, "Exception " + e); - } - return ret; - } - - -/** @hide */ - public String perfUXEngine_trigger(int opcode) { - String ret = null; - if (sIopv2 == -1) { - sIopv2 = SystemProperties.getInt("vendor.iop.enable_uxe", 0); - } - try { - if (sIopv2 == 0 || sUXEngineTrigger == null) { - return ret; - } - Object retVal = sUXEngineTrigger.invoke(mPerf, opcode); - ret = (String) retVal; - } catch (Exception e) { - Log.e(TAG, "Exception " + e); - } - return ret; - } }; diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 020086a9f34..0e12f134293 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -530,8 +530,6 @@ public class ActivityManagerService extends IActivityManager.Stub public static BoostFramework mPerf = null; public static BoostFramework mPerfServiceStartHint = null; public static boolean mIsPerfLockAcquired = false; - /* UX perf event object */ - public static BoostFramework mUxPerf = new BoostFramework(); /** All system services */ SystemServiceManager mSystemServiceManager; @@ -3054,41 +3052,6 @@ public final int startActivityFromRecents(int taskId, Bundle bOptions) { return mActivityTaskManager.startActivityFromRecents(taskId, bOptions); } - final int startActivityAsUserEmpty(IApplicationThread caller, String callingPackage, - Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, - int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { - ArrayList pApps = options.getStringArrayList("start_empty_apps"); - if (pApps != null && pApps.size() > 0) { - Iterator apps_itr = pApps.iterator(); - while (apps_itr.hasNext()) { - ProcessRecord empty_app = null; - String app_str = apps_itr.next(); - if (app_str == null) - continue; - synchronized (this) { - Intent intent_l = null; - try { - intent_l = mContext.getPackageManager().getLaunchIntentForPackage(app_str); - if (intent_l == null) - continue; - ActivityInfo aInfo = mStackSupervisor.resolveActivity(intent_l, null, - 0, null, 0, 0); - if (aInfo == null) - continue; - empty_app = startProcessLocked(app_str, aInfo.applicationInfo, false, 0, - "activity", null, false, false, true); - if (empty_app != null) - updateOomAdjLocked(empty_app, true); - } catch (Exception e) { - if (DEBUG_PROCESSES) - Slog.w(TAG, "Exception raised trying to start app as empty " + e); - } - } - } - } - return 1; - } - @Override public void startRecentsActivity(Intent intent, IAssistDataReceiver assistDataReceiver, IRecentsAnimationRunner recentsAnimationRunner) { @@ -3311,11 +3274,6 @@ final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread, mAllowLowerMemLevel = false; doLowMem = false; } - - if (mUxPerf != null) { - mUxPerf.perfUXEngine_events(BoostFramework.UXE_EVENT_KILL, 0, app.processName, 0); - } - EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName, app.setAdj, app.setProcState); if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP, @@ -4186,10 +4144,6 @@ final boolean forceStopPackageLocked(String packageName, int appId, Slog.i(TAG, "Force stopping u" + userId + ": " + reason); } - if (mUxPerf != null) { - mUxPerf.perfUXEngine_events(BoostFramework.UXE_EVENT_KILL, 0, packageName, 0); - } - mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId); } diff --git a/services/core/java/com/android/server/am/ActivityMetricsLogger.java b/services/core/java/com/android/server/am/ActivityMetricsLogger.java index f8c078cee27..a0dd87811da 100644 --- a/services/core/java/com/android/server/am/ActivityMetricsLogger.java +++ b/services/core/java/com/android/server/am/ActivityMetricsLogger.java @@ -91,7 +91,6 @@ import android.os.Message; import android.os.SystemClock; import android.os.Trace; -import android.util.BoostFramework; import android.util.EventLog; import android.util.Log; import android.util.Slog; @@ -158,9 +157,6 @@ class ActivityMetricsLogger { private ArtManagerInternal mArtManagerInternal; private final StringBuilder mStringBuilder = new StringBuilder(); - public static BoostFramework mPerfFirstDraw = null; - private static ActivityRecord mLaunchedActivity; - private final class H extends Handler { public H(Looper looper) { @@ -587,8 +583,6 @@ private void logAppTransitionMultiEvents() { return; } - mLaunchedActivity = info.launchedActivity; - // Take a snapshot of the transition info before sending it to the handler for logging. // This will avoid any races with other operations that modify the ActivityRecord. final WindowingModeTransitionInfoSnapshot infoSnapshot = @@ -680,20 +674,7 @@ private void logAppDisplayed(WindowingModeTransitionInfoSnapshot info) { sb.append(info.launchedActivityShortComponentName); sb.append(": "); TimeUtils.formatDuration(info.windowsDrawnDelayMs, sb); - - if (mLaunchedActivity.mUxPerf != null) { - mLaunchedActivity.mUxPerf.perfUXEngine_events(BoostFramework.UXE_EVENT_DISPLAYED_ACT, 0, info.packageName, info.windowsDrawnDelayMs); - } - Log.i(TAG, sb.toString()); - - if (mPerfFirstDraw == null) { - mPerfFirstDraw = new BoostFramework(); - } - - if (mPerfFirstDraw != null) { - mPerfFirstDraw.perfHint(BoostFramework.VENDOR_HINT_FIRST_DRAW, info.packageName, info.windowsDrawnDelayMs, BoostFramework.Draw.EVENT_TYPE_V1); - } } private int convertAppStartTransitionType(int tronType) { diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java index deece8bb813..ac8dcde2b50 100644 --- a/services/core/java/com/android/server/am/ActivityRecord.java +++ b/services/core/java/com/android/server/am/ActivityRecord.java @@ -201,7 +201,6 @@ import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import org.xmlpull.v1.XmlSerializer; -import android.util.BoostFramework; import java.io.File; import java.io.IOException; @@ -214,9 +213,6 @@ import java.util.Objects; import android.util.BoostFramework; -import android.os.AsyncTask; -import android.util.BoostFramework; - /** * An entry in the history stack, representing an activity. */ @@ -370,8 +366,6 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo IVoiceInteractionSession voiceSession; // Voice interaction session for this activity private BoostFramework mPerf = null; - public BoostFramework mUxPerf = new BoostFramework(); - public BoostFramework mPerf_iop = null; // A hint to override the window specified rotation animation, or -1 // to use the window specified value. We use this so that @@ -801,30 +795,7 @@ void setWillCloseOrEnterPip(boolean willCloseOrEnterPip) { getWindowContainerController().setWillCloseOrEnterPip(willCloseOrEnterPip); } - private class PreferredAppsTask extends AsyncTask { - @Override - protected Void doInBackground(Void... params) { - String res = null; - if (mUxPerf != null) { - res = mUxPerf.perfUXEngine_trigger(BoostFramework.UXE_TRIGGER); - if (res == null) - return null; - String[] p_apps = res.split("/"); - if (p_apps.length != 0) { - ArrayList apps_l = new ArrayList(Arrays.asList(p_apps)); - Bundle bParams = new Bundle(); - if (bParams == null) - return null; - bParams.putStringArrayList("start_empty_apps", apps_l); - service.mAm.startActivityAsUserEmpty(null, null, intent, null, - null, null, 0, 0, null, bParams, 0); - } - } - return null; - } - } - - static class Token extends IApplicationToken.Stub { + static class Token extends IApplicationToken.Stub { private final WeakReference weakActivity; private final String name; @@ -1929,12 +1900,8 @@ void completeResumeLocked() { if (hasProcess() && app != service.mHomeProcess) { service.mHomeProcess = app; } - try { - new PreferredAppsTask().execute(); - } catch (Exception e) { - Log.v (TAG, "Exception: " + e); - } } + if (nowVisible) { // We won't get a call to reportActivityVisibleLocked() so dismiss lockscreen now. mStackSupervisor.reportActivityVisibleLocked(this); diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java index a0965fc8b7e..188e1562b7a 100644 --- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java +++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java @@ -233,7 +233,8 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D public static boolean mPerfSendTapHint = false; public BoostFramework mPerfBoost = null; - public BoostFramework mUxPerf = null; + public BoostFramework mPerfPack = null; + static final int HANDLE_DISPLAY_ADDED = FIRST_SUPERVISOR_STACK_MSG + 5; static final int HANDLE_DISPLAY_CHANGED = FIRST_SUPERVISOR_STACK_MSG + 6; static final int HANDLE_DISPLAY_REMOVED = FIRST_SUPERVISOR_STACK_MSG + 7; @@ -2289,7 +2290,7 @@ void findTaskToMoveToFront(TaskRecord task, int flags, ActivityOptions options, //top_activity = task.stack.topRunningActivityLocked(); /* App is launching from recent apps and it's a new process */ if(top_activity != null && top_activity.getState() == ActivityState.DESTROYED) { - acquireAppLaunchPerfLock(top_activity); + acquireAppLaunchPerfLock(top_activity.packageName); } if (currentStack == null) { @@ -3415,26 +3416,21 @@ boolean moveFocusableActivityToTop(ActivityRecord r, String reason) { return true; } - void acquireAppLaunchPerfLock(ActivityRecord r) { + void acquireAppLaunchPerfLock(String packageName) { /* Acquire perf lock during new app launch */ if (mPerfBoost == null) { mPerfBoost = new BoostFramework(); } if (mPerfBoost != null) { - mPerfBoost.perfHint(BoostFramework.VENDOR_HINT_FIRST_LAUNCH_BOOST, r.packageName, -1, BoostFramework.Launch.BOOST_V1); + mPerfBoost.perfHint(BoostFramework.VENDOR_HINT_FIRST_LAUNCH_BOOST, packageName, -1, BoostFramework.Launch.BOOST_V1); mPerfSendTapHint = true; - mPerfBoost.perfHint(BoostFramework.VENDOR_HINT_FIRST_LAUNCH_BOOST, r.packageName, -1, BoostFramework.Launch.BOOST_V2); } - // Start IOP - mPerfBoost.perfIOPrefetchStart(-1,r.packageName, - r.appInfo.sourceDir.substring(0, r.appInfo.sourceDir.lastIndexOf('/'))); - } - - void acquireUxPerfLock(int opcode, String packageName) { - mUxPerf = new BoostFramework(); - if (mUxPerf != null) { - mUxPerf.perfUXEngine_events(opcode, 0, packageName, 0); - } + if (mPerfPack == null) { + mPerfPack = new BoostFramework(); + } + if (mPerfPack != null) { + mPerfPack.perfHint(BoostFramework.VENDOR_HINT_FIRST_LAUNCH_BOOST, packageName, -1, BoostFramework.Launch.BOOST_V2); + } } ActivityRecord findTaskLocked(ActivityRecord r, int preferredDisplayId) { @@ -3458,22 +3454,13 @@ ActivityRecord findTaskLocked(ActivityRecord r, int preferredDisplayId) { display.findTaskLocked(r, false /* isPreferredDisplay */, mTmpFindTaskResult); if (mTmpFindTaskResult.mIdealMatch) { - if(mTmpFindTaskResult.mRecord.getState() == ActivityState.DESTROYED ) { - /*It's a new app launch */ - acquireAppLaunchPerfLock(r); - } - - if(mTmpFindTaskResult.mRecord.getState() == ActivityState.STOPPED) { - /*Warm launch */ - acquireUxPerfLock(BoostFramework.UXE_EVENT_SUB_LAUNCH, r.packageName); - } return mTmpFindTaskResult.mRecord; } } /* Acquire perf lock *only* during new app launch */ if (mTmpFindTaskResult.mRecord == null || mTmpFindTaskResult.mRecord.getState() == ActivityState.DESTROYED) { - acquireAppLaunchPerfLock(r); + acquireAppLaunchPerfLock(r.packageName); } if (DEBUG_TASKS && mTmpFindTaskResult.mRecord == null) Slog.d(TAG_TASKS, "No task found"); diff --git a/services/core/java/com/android/server/am/ProcessRecord.java b/services/core/java/com/android/server/am/ProcessRecord.java index 307c72a9726..7d45fbfdc76 100644 --- a/services/core/java/com/android/server/am/ProcessRecord.java +++ b/services/core/java/com/android/server/am/ProcessRecord.java @@ -53,7 +53,6 @@ import android.util.StatsLog; import android.util.TimeUtils; import android.util.proto.ProtoOutputStream; -import android.util.BoostFramework; import com.android.internal.app.procstats.ProcessState; import com.android.internal.app.procstats.ProcessStats; @@ -752,7 +751,6 @@ void scheduleCrash(String message) { void kill(String reason, boolean noisy) { if (!killedByAm) { Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "kill"); - BoostFramework ux_perf = new BoostFramework(); if (mService != null && (noisy || info.uid == mService.mCurOomAdjUid)) { mService.reportUidInfoMessageLocked(TAG, "Killing " + toShortString() + " (adj " + setAdj + "): " + reason, @@ -769,9 +767,6 @@ void kill(String reason, boolean noisy) { killed = true; killedByAm = true; } - if (ux_perf != null) { - ux_perf.perfUXEngine_events(BoostFramework.UXE_EVENT_KILL, 0, this.processName, 0); - } Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); } } diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 552715142ac..c571d731d53 100755 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -268,7 +268,6 @@ import android.util.Xml; import android.util.jar.StrictJarFile; import android.util.proto.ProtoOutputStream; -import android.util.BoostFramework; import android.view.Display; import com.android.internal.R; @@ -14949,8 +14948,6 @@ private void updateSettingsInternalLI(PackageParser.Package pkg, final String pkgName = pkg.packageName; if (DEBUG_INSTALL) Slog.d(TAG, "New package installed in " + pkg.codePath); - if (pkgName != null) - acquireUxPerfLock(BoostFramework.UXE_EVENT_PKG_INSTALL, pkgName, 0); synchronized (mPackages) { // NOTE: This changes slightly to include UPDATE_PERMISSIONS_ALL regardless of the size of pkg.permissions mPermissionManager.updatePermissions(pkg.packageName, pkg, true, mPackages.values(), @@ -15889,7 +15886,6 @@ private PrepareResult preparePackageLI(InstallArgs args, PackageInstalledInfo re // on the device; we should replace it. replace = true; if (DEBUG_INSTALL) Slog.d(TAG, "Replace existing pacakge: " + pkgName); - acquireUxPerfLock(BoostFramework.UXE_EVENT_PKG_INSTALL, pkgName, 1); } // Child packages are installed through the parent package @@ -17104,19 +17100,9 @@ int deletePackageX(String packageName, long versionCode, int userId, int deleteF } } - if (res && packageName != null) { - acquireUxPerfLock(BoostFramework.UXE_EVENT_PKG_UNINSTALL, packageName, userId); - } return res ? PackageManager.DELETE_SUCCEEDED : PackageManager.DELETE_FAILED_INTERNAL_ERROR; } - private void acquireUxPerfLock(int opcode, String pkgName, int dat) { - BoostFramework ux_perf = new BoostFramework(); - if (ux_perf != null) { - ux_perf.perfUXEngine_events(opcode, 0, pkgName, dat); - } - } - static class PackageRemovedInfo { final PackageSender packageSender; String removedPackage; From 953c8de98d069f4b2d8d7515d1a36b3c79e8ac6c Mon Sep 17 00:00:00 2001 From: Karthik Gopalan Date: Mon, 3 Dec 2018 11:13:03 +0530 Subject: [PATCH 009/240] IOP/UXE: This change is related to IOP and UXE Feature. The following functionalities are squashed in this change. 1. IOP: BoostFramework support and hooks for IOP APIs 2. UX Engine Boostframework changes 3. UX Engine Start Empty F/W & Hooks + Fixes and Fixes for droidbugs: 1155119, 1159403 4. BoostFramework: Move property checks to pass sepolicy requirements. 5. IOP : Adding support for UXPerf Class 6. BoostFramework: Clean up code CRs-Fixed: 2213942 2251317 2259228 2281919 Squash of following change-IDs: Change-Id: I540c6f37d43c6c2c9eebb95a0cbb9a86cf7b17d6 Change-Id: Ib654cd7aa6368406e021814f7abc4677f87abb8f Change-Id: I1c24d31147ee00420f9e419c78809a8aa414ae20 Change-Id: Iadb716eab71e10e40bc77c97b138d3c6d90e5951 Initial Q-Change-Id: I540c6f37d43c6c2c9eebb95a0cbb9a86cf7b17d6 Change-Id: Ia5dea03e2bcb98460a28013dfe81e02a1416d611 --- core/java/android/app/ActivityThread.java | 14 +- core/java/android/util/BoostFramework.java | 134 +++++++++++++++++- .../server/am/ActivityManagerService.java | 46 ++++++ .../server/am/ActivityMetricsLogger.java | 19 +++ .../com/android/server/am/ActivityRecord.java | 37 ++++- .../server/am/ActivityStackSupervisor.java | 37 +++-- .../com/android/server/am/ProcessRecord.java | 5 + .../server/pm/PackageManagerService.java | 14 ++ 8 files changed, 290 insertions(+), 16 deletions(-) diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index d973b0c2484..7a7cc44d974 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -116,6 +116,7 @@ import android.security.net.config.NetworkSecurityConfigProvider; import android.util.AndroidRuntimeException; import android.util.ArrayMap; +import android.util.BoostFramework; import android.util.DisplayMetrics; import android.util.EventLog; import android.util.Log; @@ -5729,6 +5730,8 @@ private void updateLocaleListFromAppContext(Context context, LocaleList newLocal @UnsupportedAppUsage private void handleBindApplication(AppBindData data) { + long st_bindApp = SystemClock.uptimeMillis(); + BoostFramework ux_perf = null; // Register the UI Thread as a sensitive thread to the runtime. VMRuntime.registerSensitiveThread(); if (data.trackAllocation) { @@ -5955,7 +5958,7 @@ private void handleBindApplication(AppBindData data) { if (!Process.isIsolated()) { final int old_mask = StrictMode.allowThreadDiskWritesMask(); try { - // ux_perf = new BoostFramework(appContext); + ux_perf = new BoostFramework(appContext); } finally { StrictMode.setThreadPolicyMask(old_mask); } @@ -6116,6 +6119,15 @@ private void handleBindApplication(AppBindData data) { throw e.rethrowFromSystemServer(); } } + long end_bindApp = SystemClock.uptimeMillis(); + int bindApp_dur = (int) (end_bindApp - st_bindApp); + String pkg_name = null; + if (appContext != null) { + pkg_name = appContext.getPackageName(); + } + if (ux_perf != null && !Process.isIsolated() && pkg_name != null) { + ux_perf.perfUXEngine_events(BoostFramework.UXE_EVENT_BINDAPP, 0, pkg_name, bindApp_dur); + } } /*package*/ final void finishInstrumentation(int resultCode, Bundle results) { diff --git a/core/java/android/util/BoostFramework.java b/core/java/android/util/BoostFramework.java index ccc3695a407..b351bac9af2 100644 --- a/core/java/android/util/BoostFramework.java +++ b/core/java/android/util/BoostFramework.java @@ -29,10 +29,12 @@ package android.util; +import android.content.Context; +import android.os.SystemProperties; import android.util.Log; + import java.lang.reflect.Constructor; import java.lang.reflect.Method; -import android.content.Context; /** @hide */ public class BoostFramework { @@ -41,6 +43,9 @@ public class BoostFramework { private static final String PERFORMANCE_JAR = "/system/framework/QPerformance.jar"; private static final String PERFORMANCE_CLASS = "com.qualcomm.qti.Performance"; + private static final String UXPERFORMANCE_JAR = "/system/framework/UxPerformance.jar"; + private static final String UXPERFORMANCE_CLASS = "com.qualcomm.qti.UxPerformance"; + /** @hide */ private static boolean sIsLoaded = false; private static Class sPerfClass = null; @@ -49,8 +54,19 @@ public class BoostFramework { private static Method sReleaseFunc = null; private static Method sReleaseHandlerFunc = null; + private static int sIopv2 = -1; + private static Method sIOPStart = null; + private static Method sIOPStop = null; + private static Method sUXEngineEvents = null; + private static Method sUXEngineTrigger = null; + + private static boolean sUxIsLoaded = false; + private static Class sUxPerfClass = null; + private static Method sUxIOPStart = null; + /** @hide */ private Object mPerf = null; + private Object mUxPerf = null; //perf hints public static final int VENDOR_HINT_SCROLL_BOOST = 0x00001080; @@ -68,6 +84,16 @@ public class BoostFramework { public static final int VENDOR_HINT_FIRST_DRAW = 0x00001042; public static final int VENDOR_HINT_TAP_EVENT = 0x00001043; + //UXE Events and Triggers + public static final int UXE_TRIGGER = 1; + public static final int UXE_EVENT_BINDAPP = 2; + public static final int UXE_EVENT_DISPLAYED_ACT = 3; + public static final int UXE_EVENT_KILL = 4; + public static final int UXE_EVENT_WAKELOCK = 5; + public static final int UXE_EVENT_SUB_LAUNCH = 6; + public static final int UXE_EVENT_PKG_UNINSTALL = 7; + public static final int UXE_EVENT_PKG_INSTALL = 8; + public class Scroll { public static final int VERTICAL = 1; public static final int HORIZONTAL = 2; @@ -94,6 +120,9 @@ public BoostFramework() { if (sPerfClass != null) { mPerf = sPerfClass.newInstance(); } + if (sUxPerfClass != null) { + mUxPerf = sUxPerfClass.newInstance(); + } } catch(Exception e) { Log.e(TAG,"BoostFramework() : Exception_2 = " + e); @@ -110,6 +139,9 @@ public BoostFramework(Context context) { if (cons != null) mPerf = cons.newInstance(context); } + if (sUxPerfClass != null) { + mUxPerf = sUxPerfClass.newInstance(); + } } catch(Exception e) { Log.e(TAG,"BoostFramework() : Exception_3 = " + e); @@ -134,11 +166,42 @@ private void initFunctions () { argClasses = new Class[] {int.class}; sReleaseHandlerFunc = sPerfClass.getDeclaredMethod("perfLockReleaseHandler", argClasses); + argClasses = new Class[] {int.class, String.class, String.class}; + sIOPStart = sPerfClass.getDeclaredMethod("perfIOPrefetchStart", argClasses); + + argClasses = new Class[] {}; + sIOPStop = sPerfClass.getDeclaredMethod("perfIOPrefetchStop", argClasses); + + try { + argClasses = new Class[] {int.class, int.class, String.class, int.class}; + sUXEngineEvents = sPerfClass.getDeclaredMethod("perfUXEngine_events", + argClasses); + + argClasses = new Class[] {int.class}; + sUXEngineTrigger = sPerfClass.getDeclaredMethod("perfUXEngine_trigger", + argClasses); + } catch (Exception e) { + Log.i(TAG, "BoostFramework() : Exception_4 = PreferredApps not supported"); + } + sIsLoaded = true; } catch(Exception e) { Log.e(TAG,"BoostFramework() : Exception_1 = " + e); } + // Load UXE Class now Adding new try/catch block to avoid + // any interference with Qperformance + try { + sUxPerfClass = Class.forName(UXPERFORMANCE_CLASS); + + Class[] argUxClasses = new Class[] {int.class, String.class, String.class}; + sUxIOPStart = sUxPerfClass.getDeclaredMethod("perfIOPrefetchStart", argUxClasses); + + sUxIsLoaded = true; + } + catch(Exception e) { + Log.e(TAG,"BoostFramework() Ux Perf: Exception = " + e); + } } } } @@ -208,4 +271,73 @@ public int perfHint(int hint, String userDataStr, int userData1, int userData2) } return ret; } + +/** @hide */ + public int perfIOPrefetchStart(int pid, String pkgName, String codePath) { + int ret = -1; + try { + Object retVal = sIOPStart.invoke(mPerf, pid, pkgName, codePath); + ret = (int) retVal; + } catch (Exception e) { + Log.e(TAG, "Exception " + e); + } + try { + Object retVal = sUxIOPStart.invoke(mUxPerf, pid, pkgName, codePath); + ret = (int) retVal; + } catch (Exception e) { + Log.e(TAG, "Ux Perf Exception " + e); + } + + return ret; + } + +/** @hide */ + public int perfIOPrefetchStop() { + int ret = -1; + try { + Object retVal = sIOPStop.invoke(mPerf); + ret = (int) retVal; + } catch (Exception e) { + Log.e(TAG, "Exception " + e); + } + return ret; + } + +/** @hide */ + public int perfUXEngine_events(int opcode, int pid, String pkgName, int lat) { + int ret = -1; + if (sIopv2 == -1) { + sIopv2 = SystemProperties.getInt("vendor.iop.enable_uxe", 0); + } + + try { + if (sIopv2 == 0 || sUXEngineEvents == null) { + return ret; + } + Object retVal = sUXEngineEvents.invoke(mPerf, opcode, pid, pkgName, lat); + ret = (int) retVal; + } catch (Exception e) { + Log.e(TAG, "Exception " + e); + } + return ret; + } + + +/** @hide */ + public String perfUXEngine_trigger(int opcode) { + String ret = null; + if (sIopv2 == -1) { + sIopv2 = SystemProperties.getInt("vendor.iop.enable_uxe", 0); + } + try { + if (sIopv2 == 0 || sUXEngineTrigger == null) { + return ret; + } + Object retVal = sUXEngineTrigger.invoke(mPerf, opcode); + ret = (String) retVal; + } catch (Exception e) { + Log.e(TAG, "Exception " + e); + } + return ret; + } }; diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 0e12f134293..020086a9f34 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -530,6 +530,8 @@ public class ActivityManagerService extends IActivityManager.Stub public static BoostFramework mPerf = null; public static BoostFramework mPerfServiceStartHint = null; public static boolean mIsPerfLockAcquired = false; + /* UX perf event object */ + public static BoostFramework mUxPerf = new BoostFramework(); /** All system services */ SystemServiceManager mSystemServiceManager; @@ -3052,6 +3054,41 @@ public final int startActivityFromRecents(int taskId, Bundle bOptions) { return mActivityTaskManager.startActivityFromRecents(taskId, bOptions); } + final int startActivityAsUserEmpty(IApplicationThread caller, String callingPackage, + Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, + int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { + ArrayList pApps = options.getStringArrayList("start_empty_apps"); + if (pApps != null && pApps.size() > 0) { + Iterator apps_itr = pApps.iterator(); + while (apps_itr.hasNext()) { + ProcessRecord empty_app = null; + String app_str = apps_itr.next(); + if (app_str == null) + continue; + synchronized (this) { + Intent intent_l = null; + try { + intent_l = mContext.getPackageManager().getLaunchIntentForPackage(app_str); + if (intent_l == null) + continue; + ActivityInfo aInfo = mStackSupervisor.resolveActivity(intent_l, null, + 0, null, 0, 0); + if (aInfo == null) + continue; + empty_app = startProcessLocked(app_str, aInfo.applicationInfo, false, 0, + "activity", null, false, false, true); + if (empty_app != null) + updateOomAdjLocked(empty_app, true); + } catch (Exception e) { + if (DEBUG_PROCESSES) + Slog.w(TAG, "Exception raised trying to start app as empty " + e); + } + } + } + } + return 1; + } + @Override public void startRecentsActivity(Intent intent, IAssistDataReceiver assistDataReceiver, IRecentsAnimationRunner recentsAnimationRunner) { @@ -3274,6 +3311,11 @@ final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread, mAllowLowerMemLevel = false; doLowMem = false; } + + if (mUxPerf != null) { + mUxPerf.perfUXEngine_events(BoostFramework.UXE_EVENT_KILL, 0, app.processName, 0); + } + EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName, app.setAdj, app.setProcState); if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP, @@ -4144,6 +4186,10 @@ final boolean forceStopPackageLocked(String packageName, int appId, Slog.i(TAG, "Force stopping u" + userId + ": " + reason); } + if (mUxPerf != null) { + mUxPerf.perfUXEngine_events(BoostFramework.UXE_EVENT_KILL, 0, packageName, 0); + } + mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId); } diff --git a/services/core/java/com/android/server/am/ActivityMetricsLogger.java b/services/core/java/com/android/server/am/ActivityMetricsLogger.java index a0dd87811da..f8c078cee27 100644 --- a/services/core/java/com/android/server/am/ActivityMetricsLogger.java +++ b/services/core/java/com/android/server/am/ActivityMetricsLogger.java @@ -91,6 +91,7 @@ import android.os.Message; import android.os.SystemClock; import android.os.Trace; +import android.util.BoostFramework; import android.util.EventLog; import android.util.Log; import android.util.Slog; @@ -157,6 +158,9 @@ class ActivityMetricsLogger { private ArtManagerInternal mArtManagerInternal; private final StringBuilder mStringBuilder = new StringBuilder(); + public static BoostFramework mPerfFirstDraw = null; + private static ActivityRecord mLaunchedActivity; + private final class H extends Handler { public H(Looper looper) { @@ -583,6 +587,8 @@ private void logAppTransitionMultiEvents() { return; } + mLaunchedActivity = info.launchedActivity; + // Take a snapshot of the transition info before sending it to the handler for logging. // This will avoid any races with other operations that modify the ActivityRecord. final WindowingModeTransitionInfoSnapshot infoSnapshot = @@ -674,7 +680,20 @@ private void logAppDisplayed(WindowingModeTransitionInfoSnapshot info) { sb.append(info.launchedActivityShortComponentName); sb.append(": "); TimeUtils.formatDuration(info.windowsDrawnDelayMs, sb); + + if (mLaunchedActivity.mUxPerf != null) { + mLaunchedActivity.mUxPerf.perfUXEngine_events(BoostFramework.UXE_EVENT_DISPLAYED_ACT, 0, info.packageName, info.windowsDrawnDelayMs); + } + Log.i(TAG, sb.toString()); + + if (mPerfFirstDraw == null) { + mPerfFirstDraw = new BoostFramework(); + } + + if (mPerfFirstDraw != null) { + mPerfFirstDraw.perfHint(BoostFramework.VENDOR_HINT_FIRST_DRAW, info.packageName, info.windowsDrawnDelayMs, BoostFramework.Draw.EVENT_TYPE_V1); + } } private int convertAppStartTransitionType(int tronType) { diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java index ac8dcde2b50..deece8bb813 100644 --- a/services/core/java/com/android/server/am/ActivityRecord.java +++ b/services/core/java/com/android/server/am/ActivityRecord.java @@ -201,6 +201,7 @@ import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import org.xmlpull.v1.XmlSerializer; +import android.util.BoostFramework; import java.io.File; import java.io.IOException; @@ -213,6 +214,9 @@ import java.util.Objects; import android.util.BoostFramework; +import android.os.AsyncTask; +import android.util.BoostFramework; + /** * An entry in the history stack, representing an activity. */ @@ -366,6 +370,8 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo IVoiceInteractionSession voiceSession; // Voice interaction session for this activity private BoostFramework mPerf = null; + public BoostFramework mUxPerf = new BoostFramework(); + public BoostFramework mPerf_iop = null; // A hint to override the window specified rotation animation, or -1 // to use the window specified value. We use this so that @@ -795,7 +801,30 @@ void setWillCloseOrEnterPip(boolean willCloseOrEnterPip) { getWindowContainerController().setWillCloseOrEnterPip(willCloseOrEnterPip); } - static class Token extends IApplicationToken.Stub { + private class PreferredAppsTask extends AsyncTask { + @Override + protected Void doInBackground(Void... params) { + String res = null; + if (mUxPerf != null) { + res = mUxPerf.perfUXEngine_trigger(BoostFramework.UXE_TRIGGER); + if (res == null) + return null; + String[] p_apps = res.split("/"); + if (p_apps.length != 0) { + ArrayList apps_l = new ArrayList(Arrays.asList(p_apps)); + Bundle bParams = new Bundle(); + if (bParams == null) + return null; + bParams.putStringArrayList("start_empty_apps", apps_l); + service.mAm.startActivityAsUserEmpty(null, null, intent, null, + null, null, 0, 0, null, bParams, 0); + } + } + return null; + } + } + + static class Token extends IApplicationToken.Stub { private final WeakReference weakActivity; private final String name; @@ -1900,8 +1929,12 @@ void completeResumeLocked() { if (hasProcess() && app != service.mHomeProcess) { service.mHomeProcess = app; } + try { + new PreferredAppsTask().execute(); + } catch (Exception e) { + Log.v (TAG, "Exception: " + e); + } } - if (nowVisible) { // We won't get a call to reportActivityVisibleLocked() so dismiss lockscreen now. mStackSupervisor.reportActivityVisibleLocked(this); diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java index 188e1562b7a..a0965fc8b7e 100644 --- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java +++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java @@ -233,8 +233,7 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D public static boolean mPerfSendTapHint = false; public BoostFramework mPerfBoost = null; - public BoostFramework mPerfPack = null; - + public BoostFramework mUxPerf = null; static final int HANDLE_DISPLAY_ADDED = FIRST_SUPERVISOR_STACK_MSG + 5; static final int HANDLE_DISPLAY_CHANGED = FIRST_SUPERVISOR_STACK_MSG + 6; static final int HANDLE_DISPLAY_REMOVED = FIRST_SUPERVISOR_STACK_MSG + 7; @@ -2290,7 +2289,7 @@ void findTaskToMoveToFront(TaskRecord task, int flags, ActivityOptions options, //top_activity = task.stack.topRunningActivityLocked(); /* App is launching from recent apps and it's a new process */ if(top_activity != null && top_activity.getState() == ActivityState.DESTROYED) { - acquireAppLaunchPerfLock(top_activity.packageName); + acquireAppLaunchPerfLock(top_activity); } if (currentStack == null) { @@ -3416,21 +3415,26 @@ boolean moveFocusableActivityToTop(ActivityRecord r, String reason) { return true; } - void acquireAppLaunchPerfLock(String packageName) { + void acquireAppLaunchPerfLock(ActivityRecord r) { /* Acquire perf lock during new app launch */ if (mPerfBoost == null) { mPerfBoost = new BoostFramework(); } if (mPerfBoost != null) { - mPerfBoost.perfHint(BoostFramework.VENDOR_HINT_FIRST_LAUNCH_BOOST, packageName, -1, BoostFramework.Launch.BOOST_V1); + mPerfBoost.perfHint(BoostFramework.VENDOR_HINT_FIRST_LAUNCH_BOOST, r.packageName, -1, BoostFramework.Launch.BOOST_V1); mPerfSendTapHint = true; + mPerfBoost.perfHint(BoostFramework.VENDOR_HINT_FIRST_LAUNCH_BOOST, r.packageName, -1, BoostFramework.Launch.BOOST_V2); } - if (mPerfPack == null) { - mPerfPack = new BoostFramework(); - } - if (mPerfPack != null) { - mPerfPack.perfHint(BoostFramework.VENDOR_HINT_FIRST_LAUNCH_BOOST, packageName, -1, BoostFramework.Launch.BOOST_V2); - } + // Start IOP + mPerfBoost.perfIOPrefetchStart(-1,r.packageName, + r.appInfo.sourceDir.substring(0, r.appInfo.sourceDir.lastIndexOf('/'))); + } + + void acquireUxPerfLock(int opcode, String packageName) { + mUxPerf = new BoostFramework(); + if (mUxPerf != null) { + mUxPerf.perfUXEngine_events(opcode, 0, packageName, 0); + } } ActivityRecord findTaskLocked(ActivityRecord r, int preferredDisplayId) { @@ -3454,13 +3458,22 @@ ActivityRecord findTaskLocked(ActivityRecord r, int preferredDisplayId) { display.findTaskLocked(r, false /* isPreferredDisplay */, mTmpFindTaskResult); if (mTmpFindTaskResult.mIdealMatch) { + if(mTmpFindTaskResult.mRecord.getState() == ActivityState.DESTROYED ) { + /*It's a new app launch */ + acquireAppLaunchPerfLock(r); + } + + if(mTmpFindTaskResult.mRecord.getState() == ActivityState.STOPPED) { + /*Warm launch */ + acquireUxPerfLock(BoostFramework.UXE_EVENT_SUB_LAUNCH, r.packageName); + } return mTmpFindTaskResult.mRecord; } } /* Acquire perf lock *only* during new app launch */ if (mTmpFindTaskResult.mRecord == null || mTmpFindTaskResult.mRecord.getState() == ActivityState.DESTROYED) { - acquireAppLaunchPerfLock(r.packageName); + acquireAppLaunchPerfLock(r); } if (DEBUG_TASKS && mTmpFindTaskResult.mRecord == null) Slog.d(TAG_TASKS, "No task found"); diff --git a/services/core/java/com/android/server/am/ProcessRecord.java b/services/core/java/com/android/server/am/ProcessRecord.java index 7d45fbfdc76..307c72a9726 100644 --- a/services/core/java/com/android/server/am/ProcessRecord.java +++ b/services/core/java/com/android/server/am/ProcessRecord.java @@ -53,6 +53,7 @@ import android.util.StatsLog; import android.util.TimeUtils; import android.util.proto.ProtoOutputStream; +import android.util.BoostFramework; import com.android.internal.app.procstats.ProcessState; import com.android.internal.app.procstats.ProcessStats; @@ -751,6 +752,7 @@ void scheduleCrash(String message) { void kill(String reason, boolean noisy) { if (!killedByAm) { Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "kill"); + BoostFramework ux_perf = new BoostFramework(); if (mService != null && (noisy || info.uid == mService.mCurOomAdjUid)) { mService.reportUidInfoMessageLocked(TAG, "Killing " + toShortString() + " (adj " + setAdj + "): " + reason, @@ -767,6 +769,9 @@ void kill(String reason, boolean noisy) { killed = true; killedByAm = true; } + if (ux_perf != null) { + ux_perf.perfUXEngine_events(BoostFramework.UXE_EVENT_KILL, 0, this.processName, 0); + } Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); } } diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index c571d731d53..552715142ac 100755 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -268,6 +268,7 @@ import android.util.Xml; import android.util.jar.StrictJarFile; import android.util.proto.ProtoOutputStream; +import android.util.BoostFramework; import android.view.Display; import com.android.internal.R; @@ -14948,6 +14949,8 @@ private void updateSettingsInternalLI(PackageParser.Package pkg, final String pkgName = pkg.packageName; if (DEBUG_INSTALL) Slog.d(TAG, "New package installed in " + pkg.codePath); + if (pkgName != null) + acquireUxPerfLock(BoostFramework.UXE_EVENT_PKG_INSTALL, pkgName, 0); synchronized (mPackages) { // NOTE: This changes slightly to include UPDATE_PERMISSIONS_ALL regardless of the size of pkg.permissions mPermissionManager.updatePermissions(pkg.packageName, pkg, true, mPackages.values(), @@ -15886,6 +15889,7 @@ private PrepareResult preparePackageLI(InstallArgs args, PackageInstalledInfo re // on the device; we should replace it. replace = true; if (DEBUG_INSTALL) Slog.d(TAG, "Replace existing pacakge: " + pkgName); + acquireUxPerfLock(BoostFramework.UXE_EVENT_PKG_INSTALL, pkgName, 1); } // Child packages are installed through the parent package @@ -17100,9 +17104,19 @@ int deletePackageX(String packageName, long versionCode, int userId, int deleteF } } + if (res && packageName != null) { + acquireUxPerfLock(BoostFramework.UXE_EVENT_PKG_UNINSTALL, packageName, userId); + } return res ? PackageManager.DELETE_SUCCEEDED : PackageManager.DELETE_FAILED_INTERNAL_ERROR; } + private void acquireUxPerfLock(int opcode, String pkgName, int dat) { + BoostFramework ux_perf = new BoostFramework(); + if (ux_perf != null) { + ux_perf.perfUXEngine_events(opcode, 0, pkgName, dat); + } + } + static class PackageRemovedInfo { final PackageSender packageSender; String removedPackage; From 64039628eaf76e190f76a4593932049275fdaea4 Mon Sep 17 00:00:00 2001 From: Karthik Gopalan Date: Mon, 3 Dec 2018 11:14:31 +0530 Subject: [PATCH 010/240] Support the perflock request from system/priv apps whose domain are untrusted CRs-Fixed: 2312892 Initial Q-Change-Id: I50a9ecf6fee59e39bd896f5b285c3c58fd8ae851 Change-Id: Ic4a2b1b25004048cce4d1b5014bba4197bd7fb5c --- core/java/android/util/BoostFramework.java | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/core/java/android/util/BoostFramework.java b/core/java/android/util/BoostFramework.java index b351bac9af2..c6af8383bf4 100644 --- a/core/java/android/util/BoostFramework.java +++ b/core/java/android/util/BoostFramework.java @@ -148,6 +148,25 @@ public BoostFramework(Context context) { } } +/** @hide */ + public BoostFramework(boolean isUntrustedDomain) { + initFunctions(); + + try { + if (sPerfClass != null) { + Constructor cons = sPerfClass.getConstructor(boolean.class); + if (cons != null) + mPerf = cons.newInstance(isUntrustedDomain); + } + if (sUxPerfClass != null) { + mUxPerf = sUxPerfClass.newInstance(); + } + } + catch(Exception e) { + Log.e(TAG,"BoostFramework() : Exception_5 = " + e); + } + } + private void initFunctions () { synchronized(BoostFramework.class) { if (sIsLoaded == false) { From eac37867f0c6a727fde2f7be6d4fa994f9d62874 Mon Sep 17 00:00:00 2001 From: Karthik Gopalan Date: Mon, 3 Dec 2018 11:20:11 +0530 Subject: [PATCH 011/240] Disable swipe boost and preferred apps for certain cases This change is a combination of the following changes (a) Disable swipe boost and preferred apps for certain cases (b) Add Game boost & modify launchboostv2 invocation. (a) swipe boost: This change disables swipe boost for the following cases: 1. If top app is a game, swipe boost is completely disabled. 2. Swipe boost is disabled for horizontal fling motion. Preferred Apps: This change also helps preferred apps filter games. An app will not start as empty if that app is detected to be a game. (b) Add Game boost & modify launchboostv2 invocation. Trigger LBv2 from where LBv1 is triggered. Recent app behavior changes cause oringinal LBv2 in startProcess to not trigger. This is fixed. Detect if app is a game & trigger game boost, for faster game launch latency. CRs-Fixed: 2287732 2309700 Squash of following change-IDs: Change-Id: I299f60c7e34c4087a8f66b4eeac70f6824de764d Change-Id: I1b332639559043977e0581f537e62eccdaf55dd0 Initial Q-Change-Id: I394b51307ea9ac8f7778badaed6f5be08a42eade Change-Id: I003f95cfe7cbe3a667f4be4d22b805858790e06f --- core/java/android/util/BoostFramework.java | 3 +- core/java/android/view/ViewRootImpl.java | 2 +- core/java/android/widget/OverScroller.java | 5 +-- .../server/am/ActivityManagerService.java | 2 -- .../server/am/ActivityMetricsLogger.java | 5 +++ .../com/android/server/am/ActivityRecord.java | 13 ++++++-- .../server/am/ActivityStackSupervisor.java | 18 +++++++++-- .../server/policy/PhoneWindowManager.java | 32 ++++++++++++++++--- .../SystemGesturesPointerEventListener.java | 3 ++ .../wm/TaskTapPointerEventListener.java | 9 ++++-- 10 files changed, 73 insertions(+), 19 deletions(-) diff --git a/core/java/android/util/BoostFramework.java b/core/java/android/util/BoostFramework.java index c6af8383bf4..856969ea0a1 100644 --- a/core/java/android/util/BoostFramework.java +++ b/core/java/android/util/BoostFramework.java @@ -89,7 +89,7 @@ public class BoostFramework { public static final int UXE_EVENT_BINDAPP = 2; public static final int UXE_EVENT_DISPLAYED_ACT = 3; public static final int UXE_EVENT_KILL = 4; - public static final int UXE_EVENT_WAKELOCK = 5; + public static final int UXE_EVENT_GAME = 5; public static final int UXE_EVENT_SUB_LAUNCH = 6; public static final int UXE_EVENT_PKG_UNINSTALL = 7; public static final int UXE_EVENT_PKG_INSTALL = 8; @@ -105,6 +105,7 @@ public class Launch { public static final int BOOST_V1 = 1; public static final int BOOST_V2 = 2; public static final int BOOST_V3 = 3; + public static final int BOOST_GAME = 4; public static final int TYPE_SERVICE_START = 100; }; diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index f4ad236e35e..3e6480e7024 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -168,7 +168,7 @@ public final class ViewRootImpl implements ViewParent, public static final String PROPERTY_EMULATOR_WIN_OUTSET_BOTTOM_PX = "ro.emu.win_outset_bottom_px"; - private static final boolean SCROLL_BOOST_SS_ENABLE = + private final boolean SCROLL_BOOST_SS_ENABLE = SystemProperties.getBoolean("vendor.perf.gestureflingboost.enable", false); /** diff --git a/core/java/android/widget/OverScroller.java b/core/java/android/widget/OverScroller.java index c9fd53d95ff..88799011125 100644 --- a/core/java/android/widget/OverScroller.java +++ b/core/java/android/widget/OverScroller.java @@ -47,8 +47,7 @@ public class OverScroller { private static final int SCROLL_MODE = 0; private static final int FLING_MODE = 1; - private static final boolean SCROLL_BOOST_SS_ENABLE = - SystemProperties.getBoolean("vendor.perf.gestureflingboost.enable", false); + private static boolean SCROLL_BOOST_SS_ENABLE = false; /** @@ -87,6 +86,8 @@ public OverScroller(Context context, Interpolator interpolator, boolean flywheel mFlywheel = flywheel; mScrollerX = new SplineOverScroller(context); mScrollerY = new SplineOverScroller(context); + SCROLL_BOOST_SS_ENABLE = + SystemProperties.getBoolean("vendor.perf.gestureflingboost.enable", false); } /** diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 020086a9f34..c3ac53ab8d4 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -527,9 +527,7 @@ public class ActivityManagerService extends IActivityManager.Stub private static final int NATIVE_DUMP_TIMEOUT_MS = 2000; // 2 seconds; /* Freq Aggr boost objects */ - public static BoostFramework mPerf = null; public static BoostFramework mPerfServiceStartHint = null; - public static boolean mIsPerfLockAcquired = false; /* UX perf event object */ public static BoostFramework mUxPerf = new BoostFramework(); diff --git a/services/core/java/com/android/server/am/ActivityMetricsLogger.java b/services/core/java/com/android/server/am/ActivityMetricsLogger.java index f8c078cee27..0883001bd88 100644 --- a/services/core/java/com/android/server/am/ActivityMetricsLogger.java +++ b/services/core/java/com/android/server/am/ActivityMetricsLogger.java @@ -687,6 +687,11 @@ private void logAppDisplayed(WindowingModeTransitionInfoSnapshot info) { Log.i(TAG, sb.toString()); + int isGame = mLaunchedActivity.isAppInfoGame(); + if (mLaunchedActivity.mUxPerf != null) { + mLaunchedActivity.mUxPerf.perfUXEngine_events(BoostFramework.UXE_EVENT_GAME, 0, info.packageName, isGame); + } + if (mPerfFirstDraw == null) { mPerfFirstDraw = new BoostFramework(); } diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java index deece8bb813..f1a3f84bada 100644 --- a/services/core/java/com/android/server/am/ActivityRecord.java +++ b/services/core/java/com/android/server/am/ActivityRecord.java @@ -1021,9 +1021,6 @@ boolean isResolverOrChildActivity() { lockTaskLaunchMode = LOCK_TASK_LAUNCH_MODE_IF_WHITELISTED; } } - - if (mPerf == null) - mPerf = new BoostFramework(); } void setProcess(WindowProcessController proc) { @@ -2078,6 +2075,16 @@ public void reportFullyDrawnLocked(boolean restoredFromBundle) { info.windowsFullyDrawnDelayMs); } } + + public int isAppInfoGame() { + int isGame = 0; + if (appInfo != null) { + isGame = (appInfo.category == ApplicationInfo.CATEGORY_GAME || + (appInfo.flags & ApplicationInfo.FLAG_IS_GAME) == ApplicationInfo.FLAG_IS_GAME) ? 1 : 0; + } + return isGame; + } + @Override public void onStartingWindowDrawn(long timestamp) { synchronized (service.mGlobalLock) { diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java index a0965fc8b7e..2af79f1ef64 100644 --- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java +++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java @@ -232,6 +232,8 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D static final int LAUNCH_TIMEOUT_MSG = FIRST_SUPERVISOR_STACK_MSG + 4; public static boolean mPerfSendTapHint = false; + public static boolean mIsPerfBoostAcquired = false; + public static int mPerfHandle = -1; public BoostFramework mPerfBoost = null; public BoostFramework mUxPerf = null; static final int HANDLE_DISPLAY_ADDED = FIRST_SUPERVISOR_STACK_MSG + 5; @@ -3424,13 +3426,23 @@ void acquireAppLaunchPerfLock(ActivityRecord r) { mPerfBoost.perfHint(BoostFramework.VENDOR_HINT_FIRST_LAUNCH_BOOST, r.packageName, -1, BoostFramework.Launch.BOOST_V1); mPerfSendTapHint = true; mPerfBoost.perfHint(BoostFramework.VENDOR_HINT_FIRST_LAUNCH_BOOST, r.packageName, -1, BoostFramework.Launch.BOOST_V2); - } + + if (r.isAppInfoGame() == 1) { + mPerfHandle = mPerfBoost.perfHint(BoostFramework.VENDOR_HINT_FIRST_LAUNCH_BOOST, r.packageName, -1, + BoostFramework.Launch.BOOST_GAME); + } else { + mPerfHandle = mPerfBoost.perfHint(BoostFramework.VENDOR_HINT_FIRST_LAUNCH_BOOST, r.packageName, -1, + BoostFramework.Launch.BOOST_V3); + } + if (mPerfHandle > 0) + mIsPerfBoostAcquired = true; // Start IOP mPerfBoost.perfIOPrefetchStart(-1,r.packageName, r.appInfo.sourceDir.substring(0, r.appInfo.sourceDir.lastIndexOf('/'))); - } + } + } - void acquireUxPerfLock(int opcode, String packageName) { + void acquireUxPerfLock(int opcode, String packageName) { mUxPerf = new BoostFramework(); if (mUxPerf != null) { mUxPerf.perfUXEngine_events(opcode, 0, packageName, 0); diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java index 47bef22ed79..32623389856 100644 --- a/services/core/java/com/android/server/policy/PhoneWindowManager.java +++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java @@ -22,6 +22,7 @@ import static android.app.AppOpsManager.OP_TOAST_WINDOW; import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME; import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD; +import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS; import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM; import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY; @@ -1847,6 +1848,24 @@ public void setDefaultDisplay(DisplayContentInfo displayContentInfo) { mDefaultOrientationListener = mDefaultDisplayRotation.getOrientationListener(); } + private boolean isTopAppGame() { + boolean isGame = false; + try { + ActivityManager.RunningTaskInfo rti = ActivityManager.getService().getFilteredTasks(1, + ACTIVITY_TYPE_RECENTS, WINDOWING_MODE_UNDEFINED).get(0); + ApplicationInfo ai = mContext.getPackageManager().getApplicationInfo( + rti.topActivity.getPackageName(), 0); + if(ai != null) { + isGame = (ai.category == ApplicationInfo.CATEGORY_GAME) || + ((ai.flags & ApplicationInfo.FLAG_IS_GAME) == + ApplicationInfo.FLAG_IS_GAME); + } + } catch (Exception e) { + return false; + } + return isGame; + } + /** {@inheritDoc} */ @Override public void init(Context context, IWindowManager windowManager, @@ -2050,12 +2069,16 @@ public void onSwipeFromLeft() { } @Override public void onFling(int duration) { - String currentPackage = mContext.getPackageName(); if (mPowerManagerInternal != null) { mPowerManagerInternal.powerHint( PowerHint.INTERACTION, duration); } - if (SCROLL_BOOST_SS_ENABLE) { + } + @Override + public void onVerticalFling(int duration) { + String currentPackage = mContext.getPackageName(); + boolean isGame = isTopAppGame(); + if (SCROLL_BOOST_SS_ENABLE && !isGame) { if (mPerfBoostFling == null) { mPerfBoostFling = new BoostFramework(); mIsPerfBoostFlingAcquired = false; @@ -2073,6 +2096,7 @@ public void onFling(int duration) { @Override public void onScroll(boolean started) { String currentPackage = mContext.getPackageName(); + boolean isGame = isTopAppGame(); if (mPerfBoostDrag == null) { mPerfBoostDrag = new BoostFramework(); } @@ -2080,7 +2104,7 @@ public void onScroll(boolean started) { Slog.e(TAG, "Error: boost object null"); return; } - if (SCROLL_BOOST_SS_ENABLE) { + if (SCROLL_BOOST_SS_ENABLE && !isGame) { if (mPerfBoostPrefling == null) { mPerfBoostPrefling = new BoostFramework(); } @@ -2091,7 +2115,7 @@ public void onScroll(boolean started) { mPerfBoostPrefling.perfHint(BoostFramework.VENDOR_HINT_SCROLL_BOOST, currentPackage, -1, BoostFramework.Scroll.PREFILING); } - if (started) { + if (!isGame && started) { mPerfBoostDrag.perfHint(BoostFramework.VENDOR_HINT_DRAG_BOOST, currentPackage, -1, 1); } else { diff --git a/services/core/java/com/android/server/policy/SystemGesturesPointerEventListener.java b/services/core/java/com/android/server/policy/SystemGesturesPointerEventListener.java index c718365177b..1c3faed3f30 100644 --- a/services/core/java/com/android/server/policy/SystemGesturesPointerEventListener.java +++ b/services/core/java/com/android/server/policy/SystemGesturesPointerEventListener.java @@ -269,6 +269,8 @@ public boolean onFling(MotionEvent down, MotionEvent up, if (duration > MAX_FLING_TIME_MILLIS) { duration = MAX_FLING_TIME_MILLIS; } + if(Math.abs(velocityY) >= Math.abs(velocityX)) + mCallbacks.onVerticalFling(duration); mLastFlingTime = now; mCallbacks.onFling(duration); return true; @@ -291,6 +293,7 @@ interface Callbacks { void onSwipeFromRight(); void onSwipeFromLeft(); void onFling(int durationMs); + void onVerticalFling(int durationMs); void onScroll(boolean started); void onDown(); void onUpOrCancel(); diff --git a/services/core/java/com/android/server/wm/TaskTapPointerEventListener.java b/services/core/java/com/android/server/wm/TaskTapPointerEventListener.java index b2f5142fa2d..93caa7d9848 100644 --- a/services/core/java/com/android/server/wm/TaskTapPointerEventListener.java +++ b/services/core/java/com/android/server/wm/TaskTapPointerEventListener.java @@ -118,9 +118,12 @@ public void onPointerEvent(MotionEvent motionEvent) { } break; } - if (ActivityManagerService.mIsPerfLockAcquired) { - ActivityManagerService.mPerf.perfLockRelease(); - ActivityManagerService.mIsPerfLockAcquired = false; + if (ActivityStackSupervisor.mIsPerfBoostAcquired && (mPerfObj != null)) { + if (ActivityStackSupervisor.mPerfHandle > 0) { + mPerfObj.perfLockReleaseHandler(ActivityStackSupervisor.mPerfHandle); + ActivityStackSupervisor.mPerfHandle = -1; + } + ActivityStackSupervisor.mIsPerfBoostAcquired = false; } if (ActivityStackSupervisor.mPerfSendTapHint && (mPerfObj != null)) { mPerfObj.perfHint(BoostFramework.VENDOR_HINT_TAP_EVENT, null); From edc3abf00d89b8b1fded90156bca884022ccba46 Mon Sep 17 00:00:00 2001 From: Karthik Gopalan Date: Mon, 3 Dec 2018 11:22:55 +0530 Subject: [PATCH 012/240] Precise new activity boost (#2) This feature benefits to all new activity creation cases. The duration is acurate, power impact is very limited. CRs-Fixed: 2222580 Initial Q-Change-Id: I5aabc41b7b6cede052779e897c9be24f987fdac7 Change-Id: I7bc96267743110799be94bf64983f2a652ae0137 --- .../java/com/android/server/am/ActivityMetricsLogger.java | 5 +++++ .../core/java/com/android/server/am/ActivityRecord.java | 7 +++++-- .../core/java/com/android/server/am/ActivityStarter.java | 7 ++++++- 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/services/core/java/com/android/server/am/ActivityMetricsLogger.java b/services/core/java/com/android/server/am/ActivityMetricsLogger.java index 0883001bd88..ae73f000e2f 100644 --- a/services/core/java/com/android/server/am/ActivityMetricsLogger.java +++ b/services/core/java/com/android/server/am/ActivityMetricsLogger.java @@ -699,6 +699,11 @@ private void logAppDisplayed(WindowingModeTransitionInfoSnapshot info) { if (mPerfFirstDraw != null) { mPerfFirstDraw.perfHint(BoostFramework.VENDOR_HINT_FIRST_DRAW, info.packageName, info.windowsDrawnDelayMs, BoostFramework.Draw.EVENT_TYPE_V1); } + + if (mLaunchedActivity.mPerf != null && mLaunchedActivity.perfActivityBoostHandler > 0) { + mLaunchedActivity.mPerf.perfLockReleaseHandler(mLaunchedActivity.perfActivityBoostHandler); + mLaunchedActivity.perfActivityBoostHandler = -1; + } } private int convertAppStartTransitionType(int tronType) { diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java index f1a3f84bada..934336dee81 100644 --- a/services/core/java/com/android/server/am/ActivityRecord.java +++ b/services/core/java/com/android/server/am/ActivityRecord.java @@ -275,7 +275,7 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo private int theme; // resource identifier of activity's theme. private int realTheme; // actual theme resource we will use, never 0. private int windowFlags; // custom window flags for preview window. - int perfActivityBoostHandler = -1; //perflock handler when activity is created. + public int perfActivityBoostHandler = -1; //perflock handler when activity is created. private TaskRecord task; // the task this is in. private long createTime = System.currentTimeMillis(); long lastVisibleTime; // last time this activity became visible @@ -369,7 +369,7 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo boolean pendingVoiceInteractionStart; // Waiting for activity-invoked voice session IVoiceInteractionSession voiceSession; // Voice interaction session for this activity - private BoostFramework mPerf = null; + public BoostFramework mPerf = null; public BoostFramework mUxPerf = new BoostFramework(); public BoostFramework mPerf_iop = null; @@ -1021,6 +1021,9 @@ boolean isResolverOrChildActivity() { lockTaskLaunchMode = LOCK_TASK_LAUNCH_MODE_IF_WHITELISTED; } } + + if (mPerf == null) + mPerf = new BoostFramework(); } void setProcess(WindowProcessController proc) { diff --git a/services/core/java/com/android/server/am/ActivityStarter.java b/services/core/java/com/android/server/am/ActivityStarter.java index 8b8523d02fa..b1a912bafb8 100644 --- a/services/core/java/com/android/server/am/ActivityStarter.java +++ b/services/core/java/com/android/server/am/ActivityStarter.java @@ -1462,6 +1462,7 @@ private int startActivityUnchecked(final ActivityRecord r, ActivityRecord source newTask = true; String packageName= mService.mContext.getPackageName(); if (mPerf != null) { + mStartActivity.perfActivityBoostHandler = mPerf.perfHint(BoostFramework.VENDOR_HINT_FIRST_LAUNCH_BOOST, packageName, -1, BoostFramework.Launch.BOOST_V1); } @@ -2134,7 +2135,11 @@ private int setTaskFromSourceRecord() { return START_RETURN_LOCK_TASK_MODE_VIOLATION; } String packageName= mService.mContext.getPackageName(); - + if (mPerf != null) { + mStartActivity.perfActivityBoostHandler = + mPerf.perfHint(BoostFramework.VENDOR_HINT_FIRST_LAUNCH_BOOST, + packageName, -1, BoostFramework.Launch.BOOST_V1); + } final TaskRecord sourceTask = mSourceRecord.getTask(); final ActivityStack sourceStack = mSourceRecord.getStack(); // We only want to allow changing stack in two cases: From 45cff1e987fb0dfcf7cc039505ad8b40973aa10e Mon Sep 17 00:00:00 2001 From: Karthik Gopalan Date: Mon, 3 Dec 2018 11:24:11 +0530 Subject: [PATCH 013/240] Add perfGetFeedback api support from framework Adding the support for perfGetFeedback api in framework also, so client can access it. CRs-Fixed: 2337154 Initial Q-Change-Id: Ie9c3db67de417e0c8d85dbaca8c13aea49620137 Change-Id: I1847b50e659ba9ab27b02826ab5d5d7cec850537 --- core/java/android/util/BoostFramework.java | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/core/java/android/util/BoostFramework.java b/core/java/android/util/BoostFramework.java index 856969ea0a1..eca87fad115 100644 --- a/core/java/android/util/BoostFramework.java +++ b/core/java/android/util/BoostFramework.java @@ -53,6 +53,7 @@ public class BoostFramework { private static Method sPerfHintFunc = null; private static Method sReleaseFunc = null; private static Method sReleaseHandlerFunc = null; + private static Method sFeedbackFunc = null; private static int sIopv2 = -1; private static Method sIOPStart = null; @@ -83,6 +84,9 @@ public class BoostFramework { //perf events public static final int VENDOR_HINT_FIRST_DRAW = 0x00001042; public static final int VENDOR_HINT_TAP_EVENT = 0x00001043; + //feedback hints + public static final int VENDOR_FEEDBACK_WORKLOAD_TYPE = 0x00001601; + public static final int VENDOR_FEEDBACK_LAUNCH_END_POINT = 0x00001602; //UXE Events and Triggers public static final int UXE_TRIGGER = 1; @@ -186,6 +190,9 @@ private void initFunctions () { argClasses = new Class[] {int.class}; sReleaseHandlerFunc = sPerfClass.getDeclaredMethod("perfLockReleaseHandler", argClasses); + argClasses = new Class[] {int.class, String.class}; + sFeedbackFunc = sPerfClass.getMethod("perfGetFeedback", argClasses); + argClasses = new Class[] {int.class, String.class, String.class}; sIOPStart = sPerfClass.getDeclaredMethod("perfIOPrefetchStart", argClasses); @@ -292,6 +299,20 @@ public int perfHint(int hint, String userDataStr, int userData1, int userData2) return ret; } +/** @hide */ + public int perfGetFeedback(int req, String userDataStr) { + int ret = -1; + try { + if (sFeedbackFunc != null) { + Object retVal = sFeedbackFunc.invoke(mPerf, req, userDataStr); + ret = (int)retVal; + } + } catch(Exception e) { + Log.e(TAG,"Exception " + e); + } + return ret; + } + /** @hide */ public int perfIOPrefetchStart(int pid, String pkgName, String codePath) { int ret = -1; From b1e08532815ac84789bb4d6d15502e47abd1e0a8 Mon Sep 17 00:00:00 2001 From: Karthik Gopalan Date: Mon, 3 Dec 2018 11:34:43 +0530 Subject: [PATCH 014/240] Modify game detection logic. Using PERF API to get the workload type of the app. This is to improve the game detection logic. CRs-Fixed: 2338456 Initial Q-Change-Id: Ie18f62d0badb99d882660cbd78d9ac2a0d998184 Change-Id: I65c3c32853177cb7629510f6019b9ce70902f817 --- core/java/android/util/BoostFramework.java | 8 ++++++++ .../com/android/server/am/ActivityStackSupervisor.java | 3 ++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/core/java/android/util/BoostFramework.java b/core/java/android/util/BoostFramework.java index eca87fad115..1c679f178ba 100644 --- a/core/java/android/util/BoostFramework.java +++ b/core/java/android/util/BoostFramework.java @@ -117,6 +117,14 @@ public class Draw { public static final int EVENT_TYPE_V1 = 1; }; + public class WorkloadType { + public static final int NOT_KNOWN = 0; + public static final int APP = 1; + public static final int GAME = 2; + public static final int BROWSER = 3; + public static final int PREPROAPP = 4; + }; + /** @hide */ public BoostFramework() { initFunctions(); diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java index 2af79f1ef64..90fdaa1b899 100644 --- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java +++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java @@ -3427,7 +3427,8 @@ void acquireAppLaunchPerfLock(ActivityRecord r) { mPerfSendTapHint = true; mPerfBoost.perfHint(BoostFramework.VENDOR_HINT_FIRST_LAUNCH_BOOST, r.packageName, -1, BoostFramework.Launch.BOOST_V2); - if (r.isAppInfoGame() == 1) { + if(mPerfBoost.perfGetFeedback(BoostFramework.VENDOR_FEEDBACK_WORKLOAD_TYPE, r.packageName) == BoostFramework.WorkloadType.GAME) + { mPerfHandle = mPerfBoost.perfHint(BoostFramework.VENDOR_HINT_FIRST_LAUNCH_BOOST, r.packageName, -1, BoostFramework.Launch.BOOST_GAME); } else { From ba94c312dea63dbebb55f218d99f6f89f0e71acd Mon Sep 17 00:00:00 2001 From: Piyush Balwani Date: Thu, 10 Jan 2019 12:23:11 +0530 Subject: [PATCH 015/240] fixing merge conflict issue Change-Id: Ie8a06297cec5cdbd51e9c8b1d3199fb6e82e90dc --- packages/SystemUI/Android.bp | 1 + .../statusbar/policy/FiveGServiceClient.java | 22 +++++++++---------- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/packages/SystemUI/Android.bp b/packages/SystemUI/Android.bp index 0184c190858..1531468c44e 100644 --- a/packages/SystemUI/Android.bp +++ b/packages/SystemUI/Android.bp @@ -58,6 +58,7 @@ android_library { "androidx.slice_slice-builders", "androidx.arch.core_core-runtime", "androidx.lifecycle_lifecycle-extensions", + "qtiNetworkLib", "SystemUI-tags", "SystemUI-proto", ], diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/FiveGServiceClient.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/FiveGServiceClient.java index 58a0d2b9b7c..7b03eb82871 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/FiveGServiceClient.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/FiveGServiceClient.java @@ -44,14 +44,14 @@ import java.lang.Exception; -import org.codeaurora.internal.Client; -import org.codeaurora.internal.DcParam; -import org.codeaurora.internal.IExtTelephony; -import org.codeaurora.internal.INetworkCallback; -import org.codeaurora.internal.ServiceUtil; -import org.codeaurora.internal.SignalStrength; -import org.codeaurora.internal.Status; -import org.codeaurora.internal.Token; +import org.codeaurora.qti.qtiNetworkLib.Client; +import org.codeaurora.qti.qtiNetworkLib.DcParam; +import org.codeaurora.qti.qtiNetworkLib.INetworkCallback; +import org.codeaurora.qti.qtiNetworkLib.INetworkInterface; +import org.codeaurora.qti.qtiNetworkLib.ServiceUtil; +import org.codeaurora.qti.qtiNetworkLib.SignalStrength; +import org.codeaurora.qti.qtiNetworkLib.Status; +import org.codeaurora.qti.qtiNetworkLib.Token; import com.android.systemui.R; @@ -72,7 +72,7 @@ public class FiveGServiceClient { private Context mContext; private boolean mServiceConnected; - private IExtTelephony mNetworkService; + private INetworkInterface mNetworkService; private String mPackageName; private Client mClient; private int mBindRetryTimes = 0; @@ -301,7 +301,7 @@ public void onServiceConnected(ComponentName name, IBinder service) { Log.d(TAG, "onServiceConnected:" + service); try { - mNetworkService = IExtTelephony.Stub.asInterface(service); + mNetworkService = INetworkInterface.Stub.asInterface(service); mClient = mNetworkService.registerCallback(mPackageName, mCallback); mServiceConnected = true; initFiveGServiceState(); @@ -392,7 +392,7 @@ public void onNrBearerAllocation(int slotId, Token token, Status status, boolean @Override public void onSignalStrength(int slotId, Token token, Status status, - org.codeaurora.internal.SignalStrength + org.codeaurora.qti.qtiNetworkLib.SignalStrength signalStrength) throws RemoteException { if ( DEBUG ) { Log.d(TAG, "onSignalStrength: slotId=" + slotId + " token=" + token From 40ec224b885d205e7b706e5c2dcdba1f1b073170 Mon Sep 17 00:00:00 2001 From: Avinash Nalluri Date: Fri, 30 Nov 2018 14:39:02 -0800 Subject: [PATCH 016/240] Revert "Revert "Utilize 5G apis from telephony-ext instead of qtiNetworkLib."" -This reverts commit 2f2a3ac9a6cabf50a365963668a8f864630a56c8. -Remove qtiNetworkLib and also add telephony-ext 5G library to SystemUI. -Use NetworkCallbackBase instead of INetworkInterface to remove two-way dependecny b/w SystemUI and 5G telphony fwk. Change-Id: Ie0c99df345391bd8e075fa6866e3075fa8fff9f0 CRs-Fixed: 2360180 --- packages/SystemUI/Android.bp | 4 ++- .../statusbar/policy/FiveGServiceClient.java | 25 ++++++++++--------- packages/SystemUI/tests/Android.mk | 1 + 3 files changed, 17 insertions(+), 13 deletions(-) diff --git a/packages/SystemUI/Android.bp b/packages/SystemUI/Android.bp index 1531468c44e..c02b6a50b2e 100644 --- a/packages/SystemUI/Android.bp +++ b/packages/SystemUI/Android.bp @@ -58,7 +58,6 @@ android_library { "androidx.slice_slice-builders", "androidx.arch.core_core-runtime", "androidx.lifecycle_lifecycle-extensions", - "qtiNetworkLib", "SystemUI-tags", "SystemUI-proto", ], @@ -68,6 +67,7 @@ android_library { "telephony-common", "android.car", "android.car.userlib", + "telephony-ext", "ims-common", ], @@ -125,6 +125,7 @@ android_library { "android.car", "android.car.userlib", "android.test.base", + "telephony-ext", "ims-common", ], aaptflags: [ @@ -148,6 +149,7 @@ android_app { }, libs: [ + "telephony-ext", "telephony-common", "android.car", "android.car.userlib", diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/FiveGServiceClient.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/FiveGServiceClient.java index 7b03eb82871..18c117cda5b 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/FiveGServiceClient.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/FiveGServiceClient.java @@ -44,14 +44,15 @@ import java.lang.Exception; -import org.codeaurora.qti.qtiNetworkLib.Client; -import org.codeaurora.qti.qtiNetworkLib.DcParam; -import org.codeaurora.qti.qtiNetworkLib.INetworkCallback; -import org.codeaurora.qti.qtiNetworkLib.INetworkInterface; -import org.codeaurora.qti.qtiNetworkLib.ServiceUtil; -import org.codeaurora.qti.qtiNetworkLib.SignalStrength; -import org.codeaurora.qti.qtiNetworkLib.Status; -import org.codeaurora.qti.qtiNetworkLib.Token; +import org.codeaurora.internal.Client; +import org.codeaurora.internal.DcParam; +import org.codeaurora.internal.IExtTelephony; +import org.codeaurora.internal.INetworkCallback; +import org.codeaurora.internal.NetworkCallbackBase; +import org.codeaurora.internal.ServiceUtil; +import org.codeaurora.internal.SignalStrength; +import org.codeaurora.internal.Status; +import org.codeaurora.internal.Token; import com.android.systemui.R; @@ -72,7 +73,7 @@ public class FiveGServiceClient { private Context mContext; private boolean mServiceConnected; - private INetworkInterface mNetworkService; + private IExtTelephony mNetworkService; private String mPackageName; private Client mClient; private int mBindRetryTimes = 0; @@ -301,7 +302,7 @@ public void onServiceConnected(ComponentName name, IBinder service) { Log.d(TAG, "onServiceConnected:" + service); try { - mNetworkService = INetworkInterface.Stub.asInterface(service); + mNetworkService = IExtTelephony.Stub.asInterface(service); mClient = mNetworkService.registerCallback(mPackageName, mCallback); mServiceConnected = true; initFiveGServiceState(); @@ -337,7 +338,7 @@ private void cleanup() { }; - private INetworkCallback mCallback = new INetworkCallback.Stub() { + private INetworkCallback mCallback = new NetworkCallbackBase() { @Override public void on5gStatus(int slotId, Token token, Status status, boolean enableStatus) throws RemoteException { @@ -392,7 +393,7 @@ public void onNrBearerAllocation(int slotId, Token token, Status status, boolean @Override public void onSignalStrength(int slotId, Token token, Status status, - org.codeaurora.qti.qtiNetworkLib.SignalStrength + org.codeaurora.internal.SignalStrength signalStrength) throws RemoteException { if ( DEBUG ) { Log.d(TAG, "onSignalStrength: slotId=" + slotId + " token=" + token diff --git a/packages/SystemUI/tests/Android.mk b/packages/SystemUI/tests/Android.mk index 83419624dde..872d6f122e7 100644 --- a/packages/SystemUI/tests/Android.mk +++ b/packages/SystemUI/tests/Android.mk @@ -40,6 +40,7 @@ LOCAL_JAVA_LIBRARIES := \ android.test.base \ android.car \ android.car.userlib \ + telephony-ext \ ims-common LOCAL_AAPT_FLAGS := --extra-packages com.android.systemui:com.android.keyguard From d111d36e9f328d0de3ebf34ef900cc726af5e0f9 Mon Sep 17 00:00:00 2001 From: Weijie Wang Date: Wed, 24 Oct 2018 16:26:06 +0800 Subject: [PATCH 017/240] SystemUI: Display 5G Basic or 5G UWB icon per 5G service state MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Display 5G Basic(case1): 1.Data network type is LTE and 2.5gUwbIndicatorConfig is Configuration1 and 3.5gBasicIndicatorConfig is r15Enabled and 4.Plmn is 1(UpperLayerIndInfo.PLMN_INFO_LIST_AVAILABLE) and 5.UpperLayerInd is 0(UpperLayerIndInfo.UPPER_LAYER_IND_INFO_UNAVAILABLE) or restrict_dcnr is 1(DcParam.DCNR_RESTRICTED) Display 5G Basic(case2): 1.Data network type is LTE and 2.5gUwbIndicatorConfig is Configuration2 and 3.5gBasicIndicatorConfig is r15Enabled and 4.Plmn is 1(UpperLayerIndInfo.PLMN_INFO_LIST_AVAILABLE) and 5.Conditions to diaplay 5G UWB are not met(BearerAllocationStatus is neither BearerAllocationStatus.MMW_ALLOCATED nor BearerAllocationStatus.INVALID) Display 5G UWB icon(case1): 1.Data network type is LTE and 2.5gUwbIndicatorConfig is Configuration1 and 3.Plmn is 1(UpperLayerIndInfo.PLMN_INFO_LIST_AVAILABLE) and 4.UpperLayerInd is 1(UpperLayerIndInfo.UPPER_LAYER_IND_INFO_AVAILABLE) and 5.Restrict_dcnr is 0(DcParam.DCNR_UNRESTRICTED) Display 5G UWB icon(case2): 1.Data network type is LTE and 2.5gUwbIndicatorConfig is Configuration2 and 3.Rat_value is EXT_3GPP_5G and 5G_mmw is 1 (BearerAllocationStatus is BearerAllocationStatus.MMW_ALLOCATED) Change-Id: Ic6e7670d6ebe536ad3508899f5d4394cf6b5ba63 CRs-Fixed: 2338146 --- .../res/drawable/ic_5g_uwb_mobiledata.xml | 49 +++ .../layout/status_bar_mobile_signal_group.xml | 160 +++----- packages/SystemUI/res/values/strings.xml | 4 + .../com/android/systemui/qs/QSFooterImpl.java | 6 +- .../systemui/qs/tiles/CellularTile.java | 6 +- .../systemui/statusbar/SignalClusterView.java | 9 +- .../statusbar/StatusBarMobileView.java | 66 +--- .../phone/StatusBarSignalPolicy.java | 33 +- .../statusbar/policy/CallbackHandler.java | 12 +- .../statusbar/policy/FiveGServiceClient.java | 350 +++++++++++++++--- .../policy/MobileSignalController.java | 54 +-- .../statusbar/policy/NetworkController.java | 6 +- .../statusbar/policy/TelephonyIcons.java | 28 ++ .../statusbar/policy/CallbackHandlerTest.java | 23 +- .../policy/NetworkControllerBaseTest.java | 15 +- 15 files changed, 462 insertions(+), 359 deletions(-) create mode 100644 packages/SystemUI/res/drawable/ic_5g_uwb_mobiledata.xml diff --git a/packages/SystemUI/res/drawable/ic_5g_uwb_mobiledata.xml b/packages/SystemUI/res/drawable/ic_5g_uwb_mobiledata.xml new file mode 100644 index 00000000000..41a82af16d5 --- /dev/null +++ b/packages/SystemUI/res/drawable/ic_5g_uwb_mobiledata.xml @@ -0,0 +1,49 @@ + + + + + + + + + diff --git a/packages/SystemUI/res/layout/status_bar_mobile_signal_group.xml b/packages/SystemUI/res/layout/status_bar_mobile_signal_group.xml index 310a3ba62f2..23b90deb269 100644 --- a/packages/SystemUI/res/layout/status_bar_mobile_signal_group.xml +++ b/packages/SystemUI/res/layout/status_bar_mobile_signal_group.xml @@ -24,139 +24,71 @@ android:layout_height="match_parent" android:gravity="center_vertical"> - + + android:visibility="gone" + android:paddingEnd="2dp"/> + - - - - + android:paddingEnd="2dp" + /> - - - - - - - + + - - - - - - + + - - + - - - - + android:src="@drawable/stat_sys_roaming" + android:contentDescription="@string/data_connection_roaming" + android:visibility="gone" /> + diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml index bbb28a799f3..19552b5ceac 100644 --- a/packages/SystemUI/res/values/strings.xml +++ b/packages/SystemUI/res/values/strings.xml @@ -409,6 +409,10 @@ 1X + 5GBasic + + 5GUWB + Roaming diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFooterImpl.java b/packages/SystemUI/src/com/android/systemui/qs/QSFooterImpl.java index 730444f89a0..9ca7041330d 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSFooterImpl.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSFooterImpl.java @@ -429,10 +429,8 @@ private void handleUpdateState() { public void setMobileDataIndicators(NetworkController.IconState statusIcon, NetworkController.IconState qsIcon, int statusType, int qsType, boolean activityIn, boolean activityOut, - int dataActivityId, int stackedDataIcon, int stackedVoiceIcon, - String typeContentDescription, - String description, boolean isWide, int subId, boolean roaming, - boolean fiveGAvailable, int fiveGSignalStrengId, boolean dataOnFiveG) { + int volteIcon, String typeContentDescription, + String description, boolean isWide, int subId, boolean roaming) { mInfo.visible = statusIcon.visible; mInfo.mobileSignalIconId = statusIcon.icon; mInfo.contentDescription = statusIcon.contentDescription; 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 621dce07cc1..0165dcb5f4b 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java @@ -244,11 +244,9 @@ private final class CellSignalCallback implements SignalCallback { @Override public void setMobileDataIndicators(IconState statusIcon, IconState qsIcon, int statusType, - int qsType, boolean activityIn, boolean activityOut, int dataActivityId, - int stackedDataIcon, int stackedVoiceIcon, + int qsType, boolean activityIn, boolean activityOut, int volteIcon, String typeContentDescription, String description, boolean isWide, - int subId, boolean roaming, - boolean fiveGAvailable, int fiveGSignalStrengId, boolean dataOnFiveG) { + int subId, boolean roaming) { if (qsIcon == null) { // Not data sim, don't display. return; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java b/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java index 324ae67fb23..c03a8c125ef 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java @@ -294,11 +294,9 @@ public void setWifiIndicators(boolean enabled, IconState statusIcon, IconState q @Override public void setMobileDataIndicators(IconState statusIcon, IconState qsIcon, int statusType, - int qsType, boolean activityIn, boolean activityOut, int dataActivityId, - int stackedDataId, int stackedVoiceId, + int qsType, boolean activityIn, boolean activityOut, int volteIcon, String typeContentDescription, String description, boolean isWide, - int subId, boolean roaming, - boolean fiveGAvailable, int fiveGStrengthId, boolean dataOnFiveG) { + int subId, boolean roaming) { PhoneState state = getState(subId); if (state == null) { return; @@ -311,9 +309,6 @@ public void setMobileDataIndicators(IconState statusIcon, IconState qsIcon, int state.mRoaming = roaming; state.mActivityIn = activityIn && mActivityEnabled; state.mActivityOut = activityOut && mActivityEnabled; - state.mDataActivityId = dataActivityId; - state.mStackedDataId = stackedDataId; - state.mStackedVoiceId = stackedVoiceId; apply(); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarMobileView.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarMobileView.java index bd120185c38..f87ec9f7463 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarMobileView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarMobileView.java @@ -60,14 +60,6 @@ public class StatusBarMobileView extends FrameLayout implements DarkReceiver, private int mVisibleState = -1; private ImageView mVolte; - private LinearLayout mFiveGGroup; - private SignalDrawable mFiveGMobileDrawable; - private View mFiveGInoutContainer; - private ImageView mFiveGIn; - private ImageView mFiveGOut; - private ImageView mFiveGMobile, mFiveGMobileType, mFiveGMobileRoaming; - private View mFiveGMobileRoamingSpace; - public static StatusBarMobileView fromContext(Context context, String slot) { LayoutInflater inflater = LayoutInflater.from(context); StatusBarMobileView v = (StatusBarMobileView) @@ -121,18 +113,6 @@ private void init() { mMobileDrawable = new SignalDrawable(getContext()); mMobile.setImageDrawable(mMobileDrawable); - mFiveGGroup = findViewById(R.id.five_g_group); - mFiveGMobile = findViewById(R.id.five_g_mobile_signal); - mFiveGMobileType = findViewById(R.id.five_g_mobile_type); - mFiveGMobileRoaming = findViewById(R.id.five_g_mobile_roaming); - mFiveGMobileRoamingSpace = findViewById(R.id.five_g_mobile_roaming_space); - mFiveGIn = findViewById(R.id.five_g_mobile_in); - mFiveGOut = findViewById(R.id.five_g_mobile_out); - mFiveGInoutContainer = findViewById(R.id.five_g_inout_container); - - mFiveGMobileDrawable = new SignalDrawable(getContext()); - mFiveGMobile.setImageDrawable(mFiveGMobileDrawable); - initDotView(); } @@ -205,8 +185,6 @@ private void initViewState() { }else { mVolte.setVisibility(View.GONE); } - - mFiveGGroup.setVisibility(View.GONE); } private boolean updateState(MobileIconState state) { @@ -247,7 +225,6 @@ private boolean updateState(MobileIconState state) { } } - updateFiveGState(state); needsLayout |= state.roaming != mState.roaming || state.activityIn != mState.activityIn || state.activityOut != mState.activityOut; @@ -256,33 +233,6 @@ private boolean updateState(MobileIconState state) { return needsLayout; } - private void updateFiveGState(MobileIconState state) { - if ( state.fiveGIconVisible ) { - mFiveGMobileType.setVisibility(View.VISIBLE); - mFiveGGroup.setVisibility(View.VISIBLE); - }else { - mFiveGGroup.setVisibility(View.GONE); - } - - if ( state.dataOnFiveG ) { - if (mState.fiveGStrengthId != state.fiveGStrengthId) { - mFiveGMobileDrawable.setLevel(state.fiveGStrengthId); - } - mFiveGIn.setVisibility(state.activityIn ? View.VISIBLE : View.GONE); - mFiveGOut.setVisibility(state.activityOut ? View.VISIBLE : View.GONE ); - mFiveGInoutContainer.setVisibility((state.activityIn || state.activityOut) - ? View.VISIBLE : View.GONE ); - mFiveGMobile.setVisibility(View.VISIBLE); - mInoutContainer.setVisibility(View.GONE); - mFiveGMobileRoaming.setVisibility(state.roaming ? View.VISIBLE : View.GONE); - mFiveGMobileRoamingSpace.setVisibility(state.roaming ? View.VISIBLE : View.GONE); - }else { - mFiveGInoutContainer.setVisibility(View.GONE); - mFiveGMobile.setVisibility(View.GONE); - } - mMobileGroup.setVisibility(state.is4GStateVisible ? View.VISIBLE : View.GONE); - } - @Override public void onDarkChanged(Rect area, float darkIntensity, int tint) { if (!isInArea(area, this)) { @@ -296,12 +246,6 @@ public void onDarkChanged(Rect area, float darkIntensity, int tint) { mMobileRoaming.setImageTintList(color); mDotView.setDecorColor(tint); mDotView.setIconColor(tint, false); - - mFiveGMobileDrawable.setDarkIntensity(darkIntensity); - mFiveGIn.setImageTintList(color); - mFiveGOut.setImageTintList(color); - mFiveGMobileType.setImageTintList(color); - mFiveGMobileRoaming.setImageTintList(color); } @Override @@ -324,12 +268,6 @@ public void setStaticDrawableColor(int color) { mMobileType.setImageTintList(list); mMobileRoaming.setImageTintList(list); mDotView.setDecorColor(color); - - mFiveGMobileDrawable.setDarkIntensity(intensity); - mFiveGIn.setImageTintList(list); - mFiveGOut.setImageTintList(list); - mFiveGMobileType.setImageTintList(list); - mFiveGMobileRoaming.setImageTintList(list); } @Override @@ -377,7 +315,7 @@ public MobileIconState getState() { } private boolean needFixVisibleState() { - if ( (mState.visible||mState.fiveGIconVisible) && (getVisibility() != View.VISIBLE) ) { + if ( mState.visible && (getVisibility() != View.VISIBLE) ) { return true; }else { return false; @@ -385,7 +323,7 @@ private boolean needFixVisibleState() { } private boolean needFixInVisibleState() { - if ( (!mState.visible && !mState.fiveGIconVisible ) && (getVisibility() == View.VISIBLE)) { + if ( !mState.visible && (getVisibility() == View.VISIBLE)) { return true; }else { return false; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarSignalPolicy.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarSignalPolicy.java index 62a91ed133d..def76b0a344 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarSignalPolicy.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarSignalPolicy.java @@ -178,10 +178,9 @@ private void updateWifiIconWithState(WifiIconState state) { @Override public void setMobileDataIndicators(IconState statusIcon, IconState qsIcon, int statusType, - int qsType, boolean activityIn, boolean activityOut, int dataActivityId, - int stackedDataId, int stackedVoiceId, String typeContentDescription, - String description, boolean isWide, int subId, boolean roaming, - boolean fiveGAvailable, int fiveGStrengthId, boolean dataOnFiveG) { + int qsType, boolean activityIn, boolean activityOut, int volteIcon, + String typeContentDescription, String description, boolean isWide, + int subId, boolean roaming) { MobileIconState state = getState(subId); if (state == null) { return; @@ -198,12 +197,7 @@ public void setMobileDataIndicators(IconState statusIcon, IconState qsIcon, int state.roaming = roaming; state.activityIn = activityIn && mActivityEnabled; state.activityOut = activityOut && mActivityEnabled; - state.volteId = stackedVoiceId; - - state.fiveGIconVisible = fiveGAvailable &&(dataOnFiveG || m4GStateEnabledOn5G); - state.fiveGStrengthId = fiveGStrengthId; - state.dataOnFiveG = dataOnFiveG; - state.is4GStateVisible = m4GStateEnabledOn5G || !(fiveGAvailable&&dataOnFiveG); + state.volteId = volteIcon; // Always send a copy to maintain value type semantics mIconController.setMobileIcons(mSlotMobile, MobileIconState.copyStates(mMobileStates)); @@ -398,10 +392,6 @@ public static class MobileIconState extends SignalIconState { public boolean needsLeadingPadding; public String typeContentDescription; public int volteId; - public boolean fiveGIconVisible; - public int fiveGStrengthId; - public boolean dataOnFiveG; - public boolean is4GStateVisible; private MobileIconState(int subId) { super(); @@ -423,11 +413,7 @@ public boolean equals(Object o) { roaming == that.roaming && needsLeadingPadding == that.needsLeadingPadding && Objects.equals(typeContentDescription, that.typeContentDescription) && - volteId == that.volteId && - fiveGIconVisible == that.fiveGIconVisible && - fiveGStrengthId == that.fiveGStrengthId && - dataOnFiveG == that.dataOnFiveG && - is4GStateVisible == that.is4GStateVisible; + volteId == that.volteId; } @Override @@ -453,10 +439,6 @@ public void copyTo(MobileIconState other) { other.needsLeadingPadding = needsLeadingPadding; other.typeContentDescription = typeContentDescription; other.volteId = volteId; - other.fiveGIconVisible = fiveGIconVisible; - other.fiveGStrengthId = fiveGStrengthId; - other.dataOnFiveG = dataOnFiveG; - other.is4GStateVisible = is4GStateVisible; } private static List copyStates(List inStates) { @@ -473,10 +455,7 @@ private static List copyStates(List inStates) @Override public String toString() { return "MobileIconState(subId=" + subId + ", strengthId=" + strengthId + ", roaming=" + roaming + ", typeId=" + typeId + ", volteId=" + volteId - + ", visible=" + visible + "), " - + "5GState(fiveGIconVisible=" + fiveGIconVisible + ", fiveGStrengthId=" - + fiveGStrengthId + ", dataOnFiveG=" + dataOnFiveG - + ", is4GStateVisible=" + is4GStateVisible + ")"; + + ", visible=" + visible + ")"; } } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/CallbackHandler.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/CallbackHandler.java index 876497a5f0d..5e47f95945d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/CallbackHandler.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/CallbackHandler.java @@ -125,20 +125,16 @@ public void run() { @Override public void setMobileDataIndicators(final IconState statusIcon, final IconState qsIcon, final int statusType, final int qsType,final boolean activityIn, - final boolean activityOut, final int dataActivityId, - final int stackedDataIcon, final int stackedVoiceIcon, + final boolean activityOut, final int volteIcon, final String typeContentDescription, final String description, final boolean isWide, - final int subId, boolean roaming, - boolean fiveGAvailable, int fiveGStrengthId, boolean dataOnFiveG) { + final int subId, boolean roaming) { post(new Runnable() { @Override public void run() { for (SignalCallback signalCluster : mSignalCallbacks) { signalCluster.setMobileDataIndicators(statusIcon, qsIcon, statusType, qsType, - activityIn, activityOut, dataActivityId, - stackedDataIcon, stackedVoiceIcon, typeContentDescription, - description, isWide, subId, roaming, - fiveGAvailable, fiveGStrengthId, dataOnFiveG); + activityIn, activityOut, volteIcon, typeContentDescription, + description, isWide, subId, roaming); } } }); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/FiveGServiceClient.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/FiveGServiceClient.java index 18c117cda5b..5b84aab34a0 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/FiveGServiceClient.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/FiveGServiceClient.java @@ -29,36 +29,51 @@ package com.android.systemui.statusbar.policy; -import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; +import android.content.ContentResolver; import android.content.ServiceConnection; +import android.database.ContentObserver; +import android.net.Uri; import android.os.Handler; import android.os.IBinder; import android.os.Message; import android.os.RemoteException; +import android.provider.Settings; +import android.telephony.SubscriptionManager; +import android.telephony.TelephonyManager; import android.util.Log; import android.util.SparseArray; import java.lang.Exception; +import org.codeaurora.internal.BearerAllocationStatus; import org.codeaurora.internal.Client; import org.codeaurora.internal.DcParam; import org.codeaurora.internal.IExtTelephony; import org.codeaurora.internal.INetworkCallback; import org.codeaurora.internal.NetworkCallbackBase; +import org.codeaurora.internal.NrConfigType; import org.codeaurora.internal.ServiceUtil; import org.codeaurora.internal.SignalStrength; import org.codeaurora.internal.Status; import org.codeaurora.internal.Token; +import org.codeaurora.internal.UpperLayerIndInfo; import com.android.systemui.R; +import com.android.systemui.statusbar.policy.MobileSignalController.MobileIconGroup; public class FiveGServiceClient { private static final String TAG = "FiveGServiceClient"; - private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); + private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG)||true; + private static final String FIVEG_UWB_INDICATOR_CONFIG = "5gUwbIndicatorConfig"; + private static final String FIVEG_BASIC_INDICATOR_CONFIG = "5gBasicIndicatorConfig"; + private static final String INDICATOR_CONFIG_UNKNOWN = "unknown"; + private static final String INDICATOR_CONFIG_CONFIGURATION1 = "Configuration1"; + private static final String INDICATOR_CONFIG_CONFIGURATION2 = "Configuration2"; + private static final String INDICATOR_CONFIG_SPARE1 = "Spare1"; + private static final String INDICATOR_CONFIG_SPARE2 = "Spare2"; + private static final String INDICATOR_CONFIG_R15_ENABLED = "r15Enabled"; private static final int MESSAGE_REBIND = 1024; private static final int MESSAGE_REINIT = MESSAGE_REBIND+1; private static final int MAX_RETRY = 4; @@ -70,6 +85,7 @@ public class FiveGServiceClient { private final SparseArray mStatesListeners = new SparseArray<>(); private final SparseArray mCurrentServiceStates = new SparseArray<>(); private final SparseArray mLastServiceStates = new SparseArray<>(); + private final SparseArray mIndicatorConfigs = new SparseArray<>(); private Context mContext; private boolean mServiceConnected; @@ -79,59 +95,99 @@ public class FiveGServiceClient { private int mBindRetryTimes = 0; private int mInitRetryTimes = 0; + private ContentResolver mResolver; + + private int mPhoneCount; + private ContentObserver mConfigObserver; + + private class IndicatorConfig { + public String uwb; + public String basic; + + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append(FIVEG_UWB_INDICATOR_CONFIG +"=" +uwb).append(" ") + .append(FIVEG_BASIC_INDICATOR_CONFIG).append("=").append(basic); + return builder.toString(); + } + } + public static class FiveGServiceState{ - private int mEndc; + private int mBearerAllocationStatus; + private int mPlmn; + private int mUpperLayerInd; private int mDcnr; - private boolean mEnabled; - private boolean mDataConnected; private int mLevel; + private int mNrConfigType; + private MobileIconGroup mIconGroup; public FiveGServiceState(){ - mEndc = DcParam.ENDC_UNAVAILABLE; + mBearerAllocationStatus = BearerAllocationStatus.NOT_ALLOCATED; + mPlmn = UpperLayerIndInfo.PLMN_INFO_LIST_UNAVAILABLE; + mUpperLayerInd = UpperLayerIndInfo.UPPER_LAYER_IND_INFO_UNAVAILABLE; mDcnr = DcParam.DCNR_RESTRICTED; - mEnabled = false; - mDataConnected = false; mLevel = 0; + mNrConfigType = NrConfigType.INVALID; + mIconGroup = TelephonyIcons.UNKNOWN; } - public boolean equals(FiveGServiceState state) { - return mDataConnected == state.mDataConnected - && mLevel == state.mLevel - &&isServiceAvailable() == state.isServiceAvailable(); - } - public boolean isServiceAvailable() { - boolean available = false; - if ( mEndc == DcParam.ENDC_AVAILABLE && mDcnr == DcParam.DCNR_UNRESTRICTED ) { - available = true; + public boolean isConnected(boolean isDataRegisteredOnLte) { + boolean connected = false; + if ( mIconGroup != TelephonyIcons.UNKNOWN ) { + if ( mNrConfigType == NrConfigType.SA_CONFIGURATION ) { + connected = true; + }else if ( mNrConfigType == NrConfigType.NSA_CONFIGURATION + && isDataRegisteredOnLte ) { + connected = true; + } } - return available; + + return connected; } - public boolean isDataConnected() { - return this.mDataConnected; + public MobileIconGroup getIconGroup() { + return mIconGroup; } - public int getLevel() { - return this.mLevel; + public int getSignalLevel() { + return mLevel; + } + + public int getAllocated() { + return mBearerAllocationStatus; } public void copyFrom(FiveGServiceState state) { - this.mEndc = state.mEndc; + this.mBearerAllocationStatus = state.mBearerAllocationStatus; + this.mPlmn = state.mPlmn; + this.mUpperLayerInd = state.mUpperLayerInd; this.mDcnr = state.mDcnr; - this.mEnabled = state.mEnabled; - this.mDataConnected = state.mDataConnected; this.mLevel = state.mLevel; + this.mNrConfigType = state.mNrConfigType; + this.mIconGroup = state.mIconGroup; } + public boolean equals(FiveGServiceState state) { + return this.mBearerAllocationStatus == state.mBearerAllocationStatus + && this.mPlmn == state.mPlmn + && this.mUpperLayerInd == state.mUpperLayerInd + && this.mDcnr == state.mDcnr + && this.mLevel == state.mLevel + && this.mNrConfigType == state.mNrConfigType + && this.mIconGroup == state.mIconGroup; + } @Override public String toString() { StringBuilder builder = new StringBuilder(); - builder.append("mEndc=").append(mEndc).append(", "). - append("mDcnr=").append(mDcnr).append(", "). - append("mEnabled=").append(mEnabled).append(", "). - append("mDataConnected=").append(mDataConnected).append(", "). - append("mLevel=" + mLevel); + builder.append("mBearerAllocationStatus="). + append(mBearerAllocationStatus).append(", "). + append("mPlmn=").append(mPlmn).append(", "). + append("mUpperLayerInd=").append(mUpperLayerInd).append(", "). + append("mDcnr=" + mDcnr).append(", "). + append("mLevel=").append(mLevel).append(", "). + append("mNrConfigType=").append(mNrConfigType).append(", "). + append("mIconGroup").append(mIconGroup); return builder.toString(); } @@ -140,12 +196,17 @@ public String toString() { public FiveGServiceClient(Context context) { mContext = context; mPackageName = mContext.getPackageName(); + mResolver = mContext.getContentResolver(); + TelephonyManager tm = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE); + mPhoneCount = tm.getPhoneCount(); NUM_LEVELS = getNumLevels(context); mRsrpThresholds = mContext.getResources().getIntArray(R.array.config_5g_signal_rsrp_thresholds); mSnrThresholds = mContext.getResources().getIntArray(R.array.config_5g_signal_snr_thresholds); + + initContentObserver(); } public void registerListener(int phoneId, IFiveGStateListener listener) { @@ -232,11 +293,11 @@ private static int getLevel(int value, int[]thresholds) { private void notifyListenersIfNecessary(int phoneId) { FiveGServiceState currentState = getCurrentServiceState(phoneId); FiveGServiceState lastState = getLastServiceState(phoneId); - if ( !currentState.equals(lastState) ) { if ( DEBUG ) { - Log.d(TAG, "Change in state from " + lastState + " \n"+ + Log.d(TAG,"phoneId(" + phoneId + ") Config=" + getIndicatorConfig(phoneId)); + Log.d(TAG, "phoneId(" + phoneId + ") Change in state from " + lastState + " \n"+ "\tto " + currentState); } @@ -265,10 +326,18 @@ private void initFiveGServiceState(int phoneId) { try { Token token = mNetworkService.queryNrDcParam(phoneId, mClient); Log.d(TAG, "queryNrDcParam result:" + token); - mNetworkService.queryNrBearerAllocation(phoneId, mClient); + + token = mNetworkService.queryNrBearerAllocation(phoneId, mClient); Log.d(TAG, "queryNrBearerAllocation result:" + token); - mNetworkService.queryNrSignalStrength(phoneId, mClient); + + token = mNetworkService.queryNrSignalStrength(phoneId, mClient); Log.d(TAG, "queryNrSignalStrength result:" + token); + + token = mNetworkService.queryUpperLayerIndInfo(phoneId, mClient); + Log.d(TAG, "queryUpperLayerIndInfo result:" + token); + + token = mNetworkService.query5gConfigInfo(phoneId, mClient); + Log.d(TAG, "query5gConfigInfo result:" + token); }catch (Exception e) { Log.d(TAG, "initFiveGServiceState: Exception = " + e); if ( mInitRetryTimes < MAX_RETRY && !mHandler.hasMessages(MESSAGE_REINIT) ) { @@ -280,6 +349,148 @@ private void initFiveGServiceState(int phoneId) { } } + private void initContentObserver() { + mConfigObserver = new ContentObserver(null) { + public void onChange(boolean selfChange, Uri uri) { + onConfigChange(); + } + }; + + if ( mPhoneCount > 1 ) { + for (int i = 0; i < mPhoneCount; i++) { + Uri uwbUri = Settings.Global.getUriFor(FIVEG_UWB_INDICATOR_CONFIG + i); + Uri basicUri = Settings.Global.getUriFor(FIVEG_BASIC_INDICATOR_CONFIG + i); + mResolver.registerContentObserver(uwbUri, false, mConfigObserver); + mResolver.registerContentObserver(basicUri, false, mConfigObserver); + Log.d(TAG, "addUri:" +uwbUri); + Log.d(TAG, "addUri:" +basicUri); + } + }else { + Uri uwbUri = Settings.Global.getUriFor(FIVEG_UWB_INDICATOR_CONFIG); + Uri basicUri = Settings.Global.getUriFor(FIVEG_BASIC_INDICATOR_CONFIG); + mResolver.registerContentObserver(uwbUri, false, mConfigObserver); + mResolver.registerContentObserver(basicUri, false, mConfigObserver); + Log.d(TAG, "addUri:" +uwbUri); + Log.d(TAG, "addUri:" +basicUri); + } + } + + private IndicatorConfig getIndicatorConfig(int phoneId) { + IndicatorConfig config = mIndicatorConfigs.get(phoneId); + if ( config == null ) { + config = new IndicatorConfig(); + if ( mPhoneCount > 1 ) { + loadConfg(phoneId, config); + }else { + loadConfg(config); + } + Log.d(TAG, "new config for phoneId=" + phoneId + " confg=" + config); + mIndicatorConfigs.put(phoneId, config); + } + + return config; + } + + private void onConfigChange() { + Log.d(TAG, "onConfigChange mPhoneCount=" + mPhoneCount); + if ( mPhoneCount > 1 ) { + for ( int i=0; i < mStatesListeners.size(); ++i ) { + int phoneId = mStatesListeners.keyAt(i); + IndicatorConfig config = getIndicatorConfig(phoneId); + loadConfg(phoneId, config); + + Log.d(TAG, "phoneId=" + phoneId + " " + + FIVEG_BASIC_INDICATOR_CONFIG + "=" + config.basic + " " + + FIVEG_UWB_INDICATOR_CONFIG + "=" + config.uwb); + + FiveGServiceState state = getCurrentServiceState(phoneId); + update5GIcon(state, phoneId); + notifyListenersIfNecessary(phoneId); + } + }else{ + int phoneId = mStatesListeners.keyAt(0); + IndicatorConfig config = getIndicatorConfig(phoneId); + loadConfg(config); + Log.d(TAG, "phoneId=" + phoneId + " " + + FIVEG_BASIC_INDICATOR_CONFIG + "=" + config.basic + " " + + FIVEG_UWB_INDICATOR_CONFIG + "=" + config.uwb); + + FiveGServiceState state = getCurrentServiceState(phoneId); + update5GIcon(state, phoneId); + notifyListenersIfNecessary(phoneId); + } + } + + private void loadConfg(int phoneId, IndicatorConfig config) { + String uwb = Settings.Global.getString(mResolver, + FIVEG_UWB_INDICATOR_CONFIG + phoneId); + config.uwb = uwb != null ? uwb : INDICATOR_CONFIG_UNKNOWN; + + String basic = Settings.Global.getString(mResolver, + FIVEG_BASIC_INDICATOR_CONFIG + phoneId); + config.basic = basic != null ? basic : INDICATOR_CONFIG_UNKNOWN; + } + + private void loadConfg(IndicatorConfig config) { + String uwb = Settings.Global.getString(mResolver, FIVEG_UWB_INDICATOR_CONFIG); + config.uwb = uwb != null ? uwb : INDICATOR_CONFIG_UNKNOWN; + + String basic = Settings.Global.getString(mResolver, FIVEG_BASIC_INDICATOR_CONFIG); + config.basic = basic != null ? basic : INDICATOR_CONFIG_UNKNOWN; + } + + private void update5GIcon(FiveGServiceState state,int phoneId) { + if ( state.mNrConfigType == NrConfigType.SA_CONFIGURATION ) { + state.mIconGroup = getSaIcon(state); + }else if ( state.mNrConfigType == NrConfigType.NSA_CONFIGURATION){ + state.mIconGroup = getNsaIcon(state, phoneId); + }else { + state.mIconGroup = TelephonyIcons.UNKNOWN; + } + } + + private MobileIconGroup getSaIcon(FiveGServiceState state) { + if ( state.mBearerAllocationStatus > BearerAllocationStatus.NOT_ALLOCATED ) { + return TelephonyIcons.FIVE_G_BASIC; + }else { + return TelephonyIcons.UNKNOWN; + } + } + + private MobileIconGroup getNsaIcon(FiveGServiceState state, int phoneId) { + MobileIconGroup iconGroup = TelephonyIcons.UNKNOWN; + IndicatorConfig config = getIndicatorConfig(phoneId); + if (config.uwb.equals(INDICATOR_CONFIG_CONFIGURATION1)) { + if (state.mPlmn == UpperLayerIndInfo.PLMN_INFO_LIST_AVAILABLE + && state.mUpperLayerInd == UpperLayerIndInfo.UPPER_LAYER_IND_INFO_AVAILABLE + && state.mDcnr == DcParam.DCNR_UNRESTRICTED) { + iconGroup = TelephonyIcons.FIVE_G_UWB; + } else if (config.basic.equals(INDICATOR_CONFIG_R15_ENABLED) + && state.mPlmn == UpperLayerIndInfo.PLMN_INFO_LIST_AVAILABLE + && (state.mUpperLayerInd == UpperLayerIndInfo.UPPER_LAYER_IND_INFO_UNAVAILABLE + || state.mDcnr == DcParam.DCNR_RESTRICTED)) { + iconGroup = TelephonyIcons.FIVE_G_BASIC; + } + } else if (config.uwb.equals(INDICATOR_CONFIG_CONFIGURATION2)) { + if (state.mBearerAllocationStatus == BearerAllocationStatus.MMW_ALLOCATED) { + iconGroup = TelephonyIcons.FIVE_G_UWB; + } else if (config.basic.equals(INDICATOR_CONFIG_R15_ENABLED) + && state.mPlmn == UpperLayerIndInfo.PLMN_INFO_LIST_AVAILABLE + && state.mBearerAllocationStatus != BearerAllocationStatus.MMW_ALLOCATED) { + iconGroup = TelephonyIcons.FIVE_G_BASIC; + } + }else if ( !config.uwb.equals(INDICATOR_CONFIG_SPARE1) + && !config.uwb.equals(INDICATOR_CONFIG_SPARE1) ) { + // For FR44465 + if ( state.mUpperLayerInd == UpperLayerIndInfo.UPPER_LAYER_IND_INFO_AVAILABLE + && state.mDcnr == DcParam.DCNR_UNRESTRICTED ) { + iconGroup = TelephonyIcons.FIVE_G_BASIC; + } + } + + return iconGroup; + } + private Handler mHandler = new Handler() { public void handleMessage(Message msg) { int what = msg.what; @@ -342,18 +553,10 @@ private void cleanup() { @Override public void on5gStatus(int slotId, Token token, Status status, boolean enableStatus) throws RemoteException { - if ( DEBUG ) { Log.d(TAG, "on5gStatus: slotId= " + slotId + " token=" + token + " status=" + status + " enableStatus=" + enableStatus); } - - if (status.get() == Status.SUCCESS) { - FiveGServiceState state = getCurrentServiceState(slotId); - state.mEnabled = enableStatus; - - notifyListenersIfNecessary(slotId); - } } @Override @@ -368,46 +571,73 @@ public void onNrDcParam(int slotId, Token token, Status status, DcParam dcParam) if (status.get() == Status.SUCCESS) { FiveGServiceState state = getCurrentServiceState(slotId); state.mDcnr = dcParam.getDcnr(); - state.mEndc = dcParam.getEndc(); - + update5GIcon(state, slotId); notifyListenersIfNecessary(slotId); } } @Override - public void onNrBearerAllocation(int slotId, Token token, Status status, boolean - allocated) throws RemoteException { + public void onSignalStrength(int slotId, Token token, Status status, + org.codeaurora.internal.SignalStrength + signalStrength) throws RemoteException { + if ( DEBUG ) { + Log.d(TAG, "onSignalStrength: slotId=" + slotId + " token=" + token + + " status=" + status + " signalStrength=" + signalStrength); + } + + if (status.get() == Status.SUCCESS && signalStrength != null) { + FiveGServiceState state = getCurrentServiceState(slotId); + state.mLevel = getRsrpLevel(signalStrength.getRsrp()); + notifyListenersIfNecessary(slotId); + } + } + @Override + public void onAnyNrBearerAllocation(int slotId, Token token, Status status, + BearerAllocationStatus bearerStatus) throws RemoteException { if ( DEBUG ) { - Log.d(TAG, "onNrBearerAllocationChange: slotId=" + slotId + " token=" + token - + "status=" + status + " allocated=" + allocated); + Log.d(TAG, "onAnyNrBearerAllocation bearerStatus=" + bearerStatus.get()); } if (status.get() == Status.SUCCESS) { FiveGServiceState state = getCurrentServiceState(slotId); - state.mDataConnected = allocated; - + state.mBearerAllocationStatus = bearerStatus.get(); + update5GIcon(state, slotId); notifyListenersIfNecessary(slotId); } + } @Override - public void onSignalStrength(int slotId, Token token, Status status, - org.codeaurora.internal.SignalStrength - signalStrength) throws RemoteException { + public void onUpperLayerIndInfo(int slotId, Token token, Status status, + UpperLayerIndInfo uilInfo) throws RemoteException { if ( DEBUG ) { - Log.d(TAG, "onSignalStrength: slotId=" + slotId + " token=" + token - + " status=" + status + " signalStrength=" + signalStrength); + Log.d(TAG, "onUpperLayerIndInfo plmn=" + uilInfo.getPlmnInfoListAvailable() + + " upperLayerIndInfo=" + uilInfo.getUpperLayerIndInfoAvailable()); } - if (status.get() == Status.SUCCESS && signalStrength != null) { + if (status.get() == Status.SUCCESS) { FiveGServiceState state = getCurrentServiceState(slotId); - state.mLevel = getRsrpLevel(signalStrength.getRsrp()); - + state.mPlmn = uilInfo.getPlmnInfoListAvailable(); + state.mUpperLayerInd = uilInfo.getUpperLayerIndInfoAvailable(); + update5GIcon(state, slotId); notifyListenersIfNecessary(slotId); } } + @Override + public void on5gConfigInfo(int slotId, Token token, Status status, NrConfigType + nrConfigType) throws RemoteException { + Log.d(TAG, + "on5gConfigInfo: slotId = " + slotId + " token = " + token + " " + "status" + + status + " NrConfigType = " + nrConfigType); + if (status.get() == Status.SUCCESS) { + FiveGServiceState state = getCurrentServiceState(slotId); + state.mNrConfigType = nrConfigType.get(); + update5GIcon(state, slotId); + notifyListenersIfNecessary(slotId); + } + } }; public interface IFiveGStateListener { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java index 307c4252396..3c4be79d918 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java @@ -94,7 +94,7 @@ public class MobileSignalController extends SignalController< /****************************5G****************************/ private FiveGStateListener mFiveGStateListener; - private MobileState mFiveGState; + private FiveGServiceState mFiveGState; private final int NUM_LEVELS_ON_5G; /**********************************************************/ @@ -136,7 +136,6 @@ public MobileSignalController(Context context, Config config, boolean hasMobileD // Get initial data sim state. updateDataSim(); - mFiveGState = cleanState(); NUM_LEVELS_ON_5G = FiveGServiceClient.getNumLevels(mContext); int phoneId = SubscriptionManager.getPhoneId(mSubscriptionInfo.getSubscriptionId()); @@ -304,7 +303,7 @@ public int getCurrentIconId() { if (mCurrentState.iconGroup == TelephonyIcons.CARRIER_NETWORK_CHANGE) { return SignalDrawable.getCarrierChangeState(getNumLevels()); } else if (mCurrentState.connected) { - int level = mCurrentState.level; + int level = is5GConnected() ? mFiveGState.getSignalLevel() : mCurrentState.level; if (mConfig.inflateSignalStrengths) { level++; } @@ -324,23 +323,6 @@ public int getCurrentIconId() { } } - public int getCurrentFiveGIconId() { - if (mFiveGState.connected) { - int level = mFiveGState.level; - if (mConfig.inflateSignalStrengths) { - level++; - } - - boolean dataDisabled = mCurrentState.userSetup - && mCurrentState.iconGroup == TelephonyIcons.DATA_DISABLED; - boolean noInternet = mCurrentState.inetCondition == 0; - boolean cutOut = dataDisabled || noInternet; - return SignalDrawable.getState(level, NUM_LEVELS_ON_5G , cutOut); - } else{ - return SignalDrawable.getEmptyState(NUM_LEVELS_ON_5G); - } - } - @Override public int getQsCurrentIconId() { if (mCurrentState.airplaneMode) { @@ -378,14 +360,18 @@ private void updateImsRegistrationState() { @Override public void notifyListeners(SignalCallback callback) { MobileIconGroup icons = getIcons(); + final boolean dataDisabled = mCurrentState.iconGroup == TelephonyIcons.DATA_DISABLED + && mCurrentState.userSetup; + + if ( is5GConnected() && !dataDisabled) { + icons = mFiveGState.getIconGroup(); + } String contentDescription = getStringIfExists(getContentDescription()); String dataContentDescription = getStringIfExists(icons.mDataContentDescription); if (mCurrentState.inetCondition == 0) { dataContentDescription = mContext.getString(R.string.data_connection_no_internet); } - final boolean dataDisabled = mCurrentState.iconGroup == TelephonyIcons.DATA_DISABLED - && mCurrentState.userSetup; // Show icon in QS when we are connected or data is disabled. boolean showDataIcon = mCurrentState.dataConnected || dataDisabled; @@ -413,8 +399,6 @@ public void notifyListeners(SignalCallback callback) { icons.mDataType : 0; int volteIcon = mConfig.showVolteIcon && isEnhanced4gLteModeSettingEnabled() ? getVolteResId() : 0; - boolean show5GIcon = mFiveGState.connected && isDataRegisteredOnLte() - && mCurrentState.dataConnected; if (DEBUG) { Log.d(mTag, "notifyListeners mAlwasyShowTypeIcon=" + mAlwasyShowTypeIcon + " mDataNetType:" + mDataNetType + @@ -426,14 +410,12 @@ public void notifyListeners(SignalCallback callback) { + " icons.mDataType=" + icons.mDataType + " mConfig.showVolteIcon=" + mConfig.showVolteIcon + " isEnhanced4gLteModeSettingEnabled=" + isEnhanced4gLteModeSettingEnabled() - + " volteIcon=" + volteIcon + " show5GIcon=" + show5GIcon); + + " volteIcon=" + volteIcon); } callback.setMobileDataIndicators(statusIcon, qsIcon, typeIcon, qsTypeIcon, - activityIn, activityOut, 0, - 0, volteIcon, + activityIn, activityOut,volteIcon, dataContentDescription, description, icons.mIsWide, - mSubscriptionInfo.getSubscriptionId(), mCurrentState.roaming, - show5GIcon, getCurrentFiveGIconId(), mFiveGState.dataConnected); + mSubscriptionInfo.getSubscriptionId(), mCurrentState.roaming); } @Override @@ -715,7 +697,6 @@ public void registerFiveGStateListener(FiveGServiceClient client) { public void unregisterFiveGStateListener(FiveGServiceClient client) { int phoneId = SubscriptionManager.getPhoneId(mSubscriptionInfo.getSubscriptionId()); client.unregisterListener(phoneId); - mFiveGState = cleanState(); } private boolean isDataRegisteredOnLte() { @@ -728,6 +709,10 @@ private boolean isDataRegisteredOnLte() { return registered; } + private boolean is5GConnected() { + return mFiveGState != null && mFiveGState.isConnected(isDataRegisteredOnLte()); + } + @Override public void dump(PrintWriter pw) { super.dump(pw); @@ -819,14 +804,8 @@ public void onStateChanged(FiveGServiceState state) { if (DEBUG) { Log.d(mTag, "onStateChanged: state=" + state); } - - mFiveGState.connected = state.isServiceAvailable(); - mFiveGState.level = state.getLevel(); - mFiveGState.dataConnected = state.isDataConnected(); - mFiveGState.time = System.currentTimeMillis(); - + mFiveGState = state; notifyListeners(); - } } @@ -893,6 +872,7 @@ static class MobileState extends SignalController.State { boolean roaming; boolean imsResitered; + @Override public void copyFrom(State s) { super.copyFrom(s); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java index a144cefb209..291f9bbf901 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java @@ -51,11 +51,9 @@ default void setWifiIndicators(boolean enabled, IconState statusIcon, IconState String statusLabel) {} default void setMobileDataIndicators(IconState statusIcon, IconState qsIcon, int statusType, - int qsType, boolean activityIn, boolean activityOut, int dataActivityId, - int stackedDataIcon, int stackedVoiceIcon, + int qsType, boolean activityIn, boolean activityOut, int volteIcon, String typeContentDescription, String description, boolean isWide, - int subId, boolean roaming, - boolean fiveGAvailable, int fiveGStrengthId, boolean dataOnFiveG) {} + int subId, boolean roaming) {} default void setSubs(List subs) {} default void setNoSims(boolean show, boolean simDetected) {} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/TelephonyIcons.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/TelephonyIcons.java index 3f353d0b3f3..cf932dee8f5 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/TelephonyIcons.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/TelephonyIcons.java @@ -55,6 +55,8 @@ class TelephonyIcons { static final int ICON_4G = R.drawable.ic_4g_mobiledata; static final int ICON_4G_PLUS = R.drawable.ic_4g_plus_mobiledata; static final int ICON_1X = R.drawable.ic_1x_mobiledata; + static final int ICON_5G_BASIC = R.drawable.ic_5g_mobiledata; + static final int ICON_5G_UWB = R.drawable.ic_5g_uwb_mobiledata; static final MobileIconGroup CARRIER_NETWORK_CHANGE = new MobileIconGroup( "CARRIER_NETWORK_CHANGE", @@ -246,6 +248,32 @@ class TelephonyIcons { TelephonyIcons.ICON_2G, false); + static final MobileIconGroup FIVE_G_BASIC = new MobileIconGroup( + "5GBasic", + null, + null, + AccessibilityContentDescriptions.PHONE_SIGNAL_STRENGTH, + 0, 0, + 0, + 0, + AccessibilityContentDescriptions.PHONE_SIGNAL_STRENGTH[0], + R.string.data_connection_5g_basic, + TelephonyIcons.ICON_5G_BASIC, + false); + + static final MobileIconGroup FIVE_G_UWB = new MobileIconGroup( + "5GUWB", + null, + null, + AccessibilityContentDescriptions.PHONE_SIGNAL_STRENGTH, + 0, 0, + 0, + 0, + AccessibilityContentDescriptions.PHONE_SIGNAL_STRENGTH[0], + R.string.data_connection_5g_uwb, + TelephonyIcons.ICON_5G_UWB, + false); + static final int DATA_TYPE_UNKNOWN = 0; static final int DATA_TYPE_G = 1; static final int DATA_TYPE_E = 2; diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/CallbackHandlerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/CallbackHandlerTest.java index 9fe8a78e1a7..f4ffb3b6c83 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/CallbackHandlerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/CallbackHandlerTest.java @@ -116,14 +116,10 @@ public void testSignalCallback_setMobileDataIndicators() { int type = TelephonyIcons.ICON_1X; int qsType = TelephonyIcons.ICON_1X; boolean wide = true; - int phoneId = 1; + int subId = 5; boolean roaming = true; - boolean fiveGAvailable = true; - int fiveGStrengthId = 5; - boolean dataOnFiveG = true; - mHandler.setMobileDataIndicators(status, qs, type, qsType, in, out, 0, 0, 0, - typeDescription, description, wide, phoneId, roaming, - fiveGAvailable, fiveGStrengthId, dataOnFiveG); + mHandler.setMobileDataIndicators(status, qs, type, qsType, in, out, 0, + typeDescription, description, wide, subId, roaming); waitForCallbacks(); ArgumentCaptor statusArg = ArgumentCaptor.forClass(IconState.class); @@ -136,18 +132,12 @@ public void testSignalCallback_setMobileDataIndicators() { ArgumentCaptor descArg = ArgumentCaptor.forClass(String.class); ArgumentCaptor wideArg = ArgumentCaptor.forClass(Boolean.class); ArgumentCaptor subIdArg = ArgumentCaptor.forClass(Integer.class); - ArgumentCaptor fiveGAvailableArg = ArgumentCaptor.forClass(Boolean.class); - ArgumentCaptor fiveGStrengthIdArg = ArgumentCaptor.forClass(Integer.class); - ArgumentCaptor dataOnFiveGArg = ArgumentCaptor.forClass(Boolean.class); Mockito.verify(mSignalCallback).setMobileDataIndicators(statusArg.capture(), qsArg.capture(), typeIconArg.capture(), qsTypeIconArg.capture(), inArg.capture(), outArg.capture(), ArgumentCaptor.forClass(Integer.class).capture(), - ArgumentCaptor.forClass(Integer.class).capture(), - ArgumentCaptor.forClass(Integer.class).capture(), typeContentArg.capture(), descArg.capture(), wideArg.capture(), - subIdArg.capture(), eq(roaming), fiveGAvailableArg.capture(), - fiveGStrengthIdArg.capture(), dataOnFiveGArg.capture()); + subIdArg.capture(), eq(roaming)); assertEquals(status, statusArg.getValue()); assertEquals(qs, qsArg.getValue()); assertEquals(type, (int) typeIconArg.getValue()); @@ -157,10 +147,7 @@ public void testSignalCallback_setMobileDataIndicators() { assertEquals(typeDescription, typeContentArg.getValue()); assertEquals(description, descArg.getValue()); assertEquals(wide, (boolean) wideArg.getValue()); - assertEquals(phoneId, (int) subIdArg.getValue()); - assertEquals(fiveGAvailable, (boolean) fiveGAvailableArg.getValue()); - assertEquals(fiveGStrengthId, (int) fiveGStrengthIdArg.getValue()); - assertEquals(dataOnFiveG, (boolean) dataOnFiveGArg.getValue()); + assertEquals(subId, (int) subIdArg.getValue()); } @SuppressWarnings("unchecked") diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java index 35c8b3e8ede..b47b6d26062 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java @@ -335,10 +335,7 @@ protected void verifyLastQsMobileDataIndicators(boolean visible, int icon, int t anyInt(), typeIconArg.capture(), dataInArg.capture(), dataOutArg.capture(), ArgumentCaptor.forClass(Integer.class).capture(), - ArgumentCaptor.forClass(Integer.class).capture(), - ArgumentCaptor.forClass(Integer.class).capture(), - anyString(), anyString(), anyBoolean(), anyInt(), anyBoolean(), - anyBoolean(), anyInt(), anyBoolean()); + anyString(), anyString(), anyBoolean(), anyInt(), anyBoolean()); IconState iconState = iconArg.getValue(); int state = SignalDrawable.getState(icon, SignalStrength.NUM_SIGNAL_STRENGTH_BINS, false); @@ -372,11 +369,8 @@ protected void verifyLastMobileDataIndicators(boolean visible, int icon, int typ typeIconArg.capture(), anyInt(), anyBoolean(), anyBoolean(), ArgumentCaptor.forClass(Integer.class).capture(), - ArgumentCaptor.forClass(Integer.class).capture(), - ArgumentCaptor.forClass(Integer.class).capture(), anyString(), anyString(), anyBoolean(), - anyInt(), eq(roaming), - anyBoolean(), anyInt(), anyBoolean()); + anyInt(), eq(roaming)); IconState iconState = iconArg.getValue(); int state = icon == -1 ? 0 @@ -410,10 +404,7 @@ protected void verifyLastMobileDataIndicators(boolean visible, int icon, int typ dataInArg.capture(), dataOutArg.capture(), ArgumentCaptor.forClass(Integer.class).capture(), - ArgumentCaptor.forClass(Integer.class).capture(), - ArgumentCaptor.forClass(Integer.class).capture(), - anyString(), anyString(), anyBoolean(), anyInt(), anyBoolean(), - anyBoolean(), anyInt(), anyBoolean()); + anyString(), anyString(), anyBoolean(), anyInt(), anyBoolean()); IconState iconState = iconArg.getValue(); From 6b01437c4ac21c5d921001a97d16ae79b2e18574 Mon Sep 17 00:00:00 2001 From: Weijie Wang Date: Mon, 12 Nov 2018 19:11:52 +0800 Subject: [PATCH 018/240] SystemUI: Use same URI format for SSSS and DSDS 1.Use same URI format for SSSS and DSDS 2.Define different description for 5G icons(5G, 5G Basic,5G UWB and 5G SA) Change-Id: Ib679f27388475864ff1b798a13a80ce08f38a3fa CRs-Fixed: 2347856 --- packages/SystemUI/res/values/strings.xml | 8 ++ .../statusbar/policy/FiveGServiceClient.java | 98 ++++++------------- .../policy/MobileSignalController.java | 31 ++++-- .../statusbar/policy/TelephonyIcons.java | 28 ++++++ 4 files changed, 91 insertions(+), 74 deletions(-) diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml index 19552b5ceac..791bba243c0 100644 --- a/packages/SystemUI/res/values/strings.xml +++ b/packages/SystemUI/res/values/strings.xml @@ -409,10 +409,18 @@ 1X + + 5G + + 5GBasic + 5GUWB + + 5GSA + Roaming diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/FiveGServiceClient.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/FiveGServiceClient.java index 5b84aab34a0..7779724ab38 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/FiveGServiceClient.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/FiveGServiceClient.java @@ -79,7 +79,6 @@ public class FiveGServiceClient { private static final int MAX_RETRY = 4; private static final int DELAY_MILLISECOND = 3000; private static final int DELAY_INCREMENT = 2000; - private final int NUM_LEVELS; private final int mRsrpThresholds[]; private final int mSnrThresholds[]; private final SparseArray mStatesListeners = new SparseArray<>(); @@ -96,8 +95,6 @@ public class FiveGServiceClient { private int mInitRetryTimes = 0; private ContentResolver mResolver; - - private int mPhoneCount; private ContentObserver mConfigObserver; private class IndicatorConfig { @@ -131,18 +128,21 @@ public FiveGServiceState(){ mIconGroup = TelephonyIcons.UNKNOWN; } - - public boolean isConnected(boolean isDataRegisteredOnLte) { + public boolean isConnectedOnSaMode() { boolean connected = false; - if ( mIconGroup != TelephonyIcons.UNKNOWN ) { - if ( mNrConfigType == NrConfigType.SA_CONFIGURATION ) { - connected = true; - }else if ( mNrConfigType == NrConfigType.NSA_CONFIGURATION - && isDataRegisteredOnLte ) { - connected = true; - } + if ( mNrConfigType == NrConfigType.SA_CONFIGURATION + && mIconGroup != TelephonyIcons.UNKNOWN) { + connected = true; } + return connected; + } + public boolean isConnectedOnNsaMode() { + boolean connected = false; + if ( mNrConfigType == NrConfigType.NSA_CONFIGURATION + && mIconGroup != TelephonyIcons.UNKNOWN) { + connected = true; + } return connected; } @@ -187,7 +187,7 @@ public String toString() { append("mDcnr=" + mDcnr).append(", "). append("mLevel=").append(mLevel).append(", "). append("mNrConfigType=").append(mNrConfigType).append(", "). - append("mIconGroup").append(mIconGroup); + append("mIconGroup=").append(mIconGroup); return builder.toString(); } @@ -197,9 +197,6 @@ public FiveGServiceClient(Context context) { mContext = context; mPackageName = mContext.getPackageName(); mResolver = mContext.getContentResolver(); - TelephonyManager tm = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE); - mPhoneCount = tm.getPhoneCount(); - NUM_LEVELS = getNumLevels(context); mRsrpThresholds = mContext.getResources().getIntArray(R.array.config_5g_signal_rsrp_thresholds); @@ -356,22 +353,16 @@ public void onChange(boolean selfChange, Uri uri) { } }; - if ( mPhoneCount > 1 ) { - for (int i = 0; i < mPhoneCount; i++) { - Uri uwbUri = Settings.Global.getUriFor(FIVEG_UWB_INDICATOR_CONFIG + i); - Uri basicUri = Settings.Global.getUriFor(FIVEG_BASIC_INDICATOR_CONFIG + i); - mResolver.registerContentObserver(uwbUri, false, mConfigObserver); - mResolver.registerContentObserver(basicUri, false, mConfigObserver); - Log.d(TAG, "addUri:" +uwbUri); - Log.d(TAG, "addUri:" +basicUri); - } - }else { - Uri uwbUri = Settings.Global.getUriFor(FIVEG_UWB_INDICATOR_CONFIG); - Uri basicUri = Settings.Global.getUriFor(FIVEG_BASIC_INDICATOR_CONFIG); + TelephonyManager tm = (TelephonyManager) + mContext.getSystemService(Context.TELEPHONY_SERVICE); + int phoneCount = tm.getPhoneCount(); + for (int i = 0; i < phoneCount; i++) { + Uri uwbUri = Settings.Global.getUriFor(FIVEG_UWB_INDICATOR_CONFIG + i); + Uri basicUri = Settings.Global.getUriFor(FIVEG_BASIC_INDICATOR_CONFIG + i); mResolver.registerContentObserver(uwbUri, false, mConfigObserver); mResolver.registerContentObserver(basicUri, false, mConfigObserver); - Log.d(TAG, "addUri:" +uwbUri); - Log.d(TAG, "addUri:" +basicUri); + Log.d(TAG, "Register observer to watch global settings uri(" + uwbUri + ")"); + Log.d(TAG, "Register observer to watch global settings uri(" + basicUri + ")"); } } @@ -379,11 +370,7 @@ private IndicatorConfig getIndicatorConfig(int phoneId) { IndicatorConfig config = mIndicatorConfigs.get(phoneId); if ( config == null ) { config = new IndicatorConfig(); - if ( mPhoneCount > 1 ) { - loadConfg(phoneId, config); - }else { - loadConfg(config); - } + loadConfg(phoneId, config); Log.d(TAG, "new config for phoneId=" + phoneId + " confg=" + config); mIndicatorConfigs.put(phoneId, config); } @@ -392,30 +379,15 @@ private IndicatorConfig getIndicatorConfig(int phoneId) { } private void onConfigChange() { - Log.d(TAG, "onConfigChange mPhoneCount=" + mPhoneCount); - if ( mPhoneCount > 1 ) { - for ( int i=0; i < mStatesListeners.size(); ++i ) { - int phoneId = mStatesListeners.keyAt(i); - IndicatorConfig config = getIndicatorConfig(phoneId); - loadConfg(phoneId, config); - - Log.d(TAG, "phoneId=" + phoneId + " " - + FIVEG_BASIC_INDICATOR_CONFIG + "=" + config.basic + " " - + FIVEG_UWB_INDICATOR_CONFIG + "=" + config.uwb); - - FiveGServiceState state = getCurrentServiceState(phoneId); - update5GIcon(state, phoneId); - notifyListenersIfNecessary(phoneId); - } - }else{ - int phoneId = mStatesListeners.keyAt(0); + Log.d(TAG, "onConfigChange"); + for ( int i=0; i < mStatesListeners.size(); ++i ) { + int phoneId = mStatesListeners.keyAt(i); IndicatorConfig config = getIndicatorConfig(phoneId); - loadConfg(config); - Log.d(TAG, "phoneId=" + phoneId + " " - + FIVEG_BASIC_INDICATOR_CONFIG + "=" + config.basic + " " - + FIVEG_UWB_INDICATOR_CONFIG + "=" + config.uwb); - + loadConfg(phoneId, config); FiveGServiceState state = getCurrentServiceState(phoneId); + + Log.d(TAG, "phoneId(" + phoneId + ") " + config + " state=" + state); + update5GIcon(state, phoneId); notifyListenersIfNecessary(phoneId); } @@ -431,14 +403,6 @@ private void loadConfg(int phoneId, IndicatorConfig config) { config.basic = basic != null ? basic : INDICATOR_CONFIG_UNKNOWN; } - private void loadConfg(IndicatorConfig config) { - String uwb = Settings.Global.getString(mResolver, FIVEG_UWB_INDICATOR_CONFIG); - config.uwb = uwb != null ? uwb : INDICATOR_CONFIG_UNKNOWN; - - String basic = Settings.Global.getString(mResolver, FIVEG_BASIC_INDICATOR_CONFIG); - config.basic = basic != null ? basic : INDICATOR_CONFIG_UNKNOWN; - } - private void update5GIcon(FiveGServiceState state,int phoneId) { if ( state.mNrConfigType == NrConfigType.SA_CONFIGURATION ) { state.mIconGroup = getSaIcon(state); @@ -451,7 +415,7 @@ private void update5GIcon(FiveGServiceState state,int phoneId) { private MobileIconGroup getSaIcon(FiveGServiceState state) { if ( state.mBearerAllocationStatus > BearerAllocationStatus.NOT_ALLOCATED ) { - return TelephonyIcons.FIVE_G_BASIC; + return TelephonyIcons.FIVE_G_SA; }else { return TelephonyIcons.UNKNOWN; } @@ -484,7 +448,7 @@ private MobileIconGroup getNsaIcon(FiveGServiceState state, int phoneId) { // For FR44465 if ( state.mUpperLayerInd == UpperLayerIndInfo.UPPER_LAYER_IND_INFO_AVAILABLE && state.mDcnr == DcParam.DCNR_UNRESTRICTED ) { - iconGroup = TelephonyIcons.FIVE_G_BASIC; + iconGroup = TelephonyIcons.FIVE_G; } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java index 3c4be79d918..3ed4b0e84a5 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java @@ -117,6 +117,7 @@ public MobileSignalController(Context context, Config config, boolean hasMobileD mPhoneStateListener = new MobilePhoneStateListener(info.getSubscriptionId(), receiverLooper); mFiveGStateListener = new FiveGStateListener(); + mFiveGState = new FiveGServiceState(); mNetworkNameSeparator = getStringIfExists(R.string.status_bar_network_name_separator); mNetworkNameDefault = getStringIfExists( com.android.internal.R.string.lockscreen_carrier_default); @@ -303,7 +304,7 @@ public int getCurrentIconId() { if (mCurrentState.iconGroup == TelephonyIcons.CARRIER_NETWORK_CHANGE) { return SignalDrawable.getCarrierChangeState(getNumLevels()); } else if (mCurrentState.connected) { - int level = is5GConnected() ? mFiveGState.getSignalLevel() : mCurrentState.level; + int level = mCurrentState.level; if (mConfig.inflateSignalStrengths) { level++; } @@ -323,6 +324,18 @@ public int getCurrentIconId() { } } + public int getCurrent5GIconId() { + int level = mFiveGState.getSignalLevel(); + if (mConfig.inflateSignalStrengths) { + level++; + } + boolean dataDisabled = mCurrentState.userSetup + && mCurrentState.iconGroup == TelephonyIcons.DATA_DISABLED; + boolean noInternet = mCurrentState.inetCondition == 0; + boolean cutOut = dataDisabled || noInternet; + return SignalDrawable.getState(level, NUM_LEVELS_ON_5G , cutOut); + } + @Override public int getQsCurrentIconId() { if (mCurrentState.airplaneMode) { @@ -363,8 +376,11 @@ public void notifyListeners(SignalCallback callback) { final boolean dataDisabled = mCurrentState.iconGroup == TelephonyIcons.DATA_DISABLED && mCurrentState.userSetup; - if ( is5GConnected() && !dataDisabled) { - icons = mFiveGState.getIconGroup(); + if ( is5GConnected() ) { + if ( mFiveGState.isConnectedOnSaMode() + || mFiveGState.isConnectedOnNsaMode() && !dataDisabled ) { + icons = mFiveGState.getIconGroup(); + } } String contentDescription = getStringIfExists(getContentDescription()); @@ -376,7 +392,7 @@ public void notifyListeners(SignalCallback callback) { // Show icon in QS when we are connected or data is disabled. boolean showDataIcon = mCurrentState.dataConnected || dataDisabled; IconState statusIcon = new IconState(mCurrentState.enabled && !mCurrentState.airplaneMode, - getCurrentIconId(), contentDescription); + is5GConnected() ? getCurrent5GIconId() : getCurrentIconId(), contentDescription); int qsTypeIcon = 0; IconState qsIcon = null; @@ -395,8 +411,8 @@ public void notifyListeners(SignalCallback callback) { && !mCurrentState.carrierNetworkChangeMode && mCurrentState.activityOut; showDataIcon &= mCurrentState.isDefault || dataDisabled; - int typeIcon = (showDataIcon || mConfig.alwaysShowDataRatIcon || mAlwasyShowTypeIcon) ? - icons.mDataType : 0; + int typeIcon = (showDataIcon || mConfig.alwaysShowDataRatIcon || mAlwasyShowTypeIcon + || mFiveGState.isConnectedOnSaMode() ) ? icons.mDataType : 0; int volteIcon = mConfig.showVolteIcon && isEnhanced4gLteModeSettingEnabled() ? getVolteResId() : 0; if (DEBUG) { @@ -710,7 +726,8 @@ private boolean isDataRegisteredOnLte() { } private boolean is5GConnected() { - return mFiveGState != null && mFiveGState.isConnected(isDataRegisteredOnLte()); + return mFiveGState.isConnectedOnSaMode() + || mFiveGState.isConnectedOnNsaMode() && isDataRegisteredOnLte(); } @Override diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/TelephonyIcons.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/TelephonyIcons.java index cf932dee8f5..e9214318bbe 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/TelephonyIcons.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/TelephonyIcons.java @@ -55,6 +55,8 @@ class TelephonyIcons { static final int ICON_4G = R.drawable.ic_4g_mobiledata; static final int ICON_4G_PLUS = R.drawable.ic_4g_plus_mobiledata; static final int ICON_1X = R.drawable.ic_1x_mobiledata; + static final int ICON_5G = R.drawable.ic_5g_mobiledata; + static final int ICON_5G_SA = R.drawable.ic_5g_mobiledata; static final int ICON_5G_BASIC = R.drawable.ic_5g_mobiledata; static final int ICON_5G_UWB = R.drawable.ic_5g_uwb_mobiledata; @@ -248,6 +250,19 @@ class TelephonyIcons { TelephonyIcons.ICON_2G, false); + static final MobileIconGroup FIVE_G = new MobileIconGroup( + "5G", + null, + null, + AccessibilityContentDescriptions.PHONE_SIGNAL_STRENGTH, + 0, 0, + 0, + 0, + AccessibilityContentDescriptions.PHONE_SIGNAL_STRENGTH[0], + R.string.data_connection_5g, + TelephonyIcons.ICON_5G, + false); + static final MobileIconGroup FIVE_G_BASIC = new MobileIconGroup( "5GBasic", null, @@ -274,6 +289,19 @@ class TelephonyIcons { TelephonyIcons.ICON_5G_UWB, false); + static final MobileIconGroup FIVE_G_SA = new MobileIconGroup( + "5GSA", + null, + null, + AccessibilityContentDescriptions.PHONE_SIGNAL_STRENGTH, + 0, 0, + 0, + 0, + AccessibilityContentDescriptions.PHONE_SIGNAL_STRENGTH[0], + R.string.data_connection_5g_sa, + TelephonyIcons.ICON_5G_SA, + false); + static final int DATA_TYPE_UNKNOWN = 0; static final int DATA_TYPE_G = 1; static final int DATA_TYPE_E = 2; From c94242e71eb4f32afb6d53939e671d3e2a2837d6 Mon Sep 17 00:00:00 2001 From: Weijie Wang Date: Thu, 6 Dec 2018 10:03:54 +0800 Subject: [PATCH 019/240] SystemUI: Set NSA as default 5G mode Set NSA as default 5G mode Change-Id: I86d4deaf5b55965d75348029ef653a491d9a2482 CRs-Fixed: 2361951 --- .../android/systemui/statusbar/policy/FiveGServiceClient.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/FiveGServiceClient.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/FiveGServiceClient.java index 7779724ab38..539ae27a7c3 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/FiveGServiceClient.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/FiveGServiceClient.java @@ -124,7 +124,7 @@ public FiveGServiceState(){ mUpperLayerInd = UpperLayerIndInfo.UPPER_LAYER_IND_INFO_UNAVAILABLE; mDcnr = DcParam.DCNR_RESTRICTED; mLevel = 0; - mNrConfigType = NrConfigType.INVALID; + mNrConfigType = NrConfigType.NSA_CONFIGURATION; mIconGroup = TelephonyIcons.UNKNOWN; } From 3b3b6d871ca9d4dc57b4351ca8abbdae1f4fb173 Mon Sep 17 00:00:00 2001 From: Weijie Wang Date: Sun, 2 Dec 2018 12:08:14 +0800 Subject: [PATCH 020/240] SystemUI: Add 5G states into dump logs Add 5G states into dump logs Change-Id: Id688c3591793a1a7bf778252b42b34d5e86651c5 CRs-Fixed: 2359277 --- .../android/systemui/statusbar/policy/FiveGServiceClient.java | 2 +- .../systemui/statusbar/policy/MobileSignalController.java | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/FiveGServiceClient.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/FiveGServiceClient.java index 539ae27a7c3..f530336b830 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/FiveGServiceClient.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/FiveGServiceClient.java @@ -444,7 +444,7 @@ private MobileIconGroup getNsaIcon(FiveGServiceState state, int phoneId) { iconGroup = TelephonyIcons.FIVE_G_BASIC; } }else if ( !config.uwb.equals(INDICATOR_CONFIG_SPARE1) - && !config.uwb.equals(INDICATOR_CONFIG_SPARE1) ) { + && !config.uwb.equals(INDICATOR_CONFIG_SPARE2) ) { // For FR44465 if ( state.mUpperLayerInd == UpperLayerIndInfo.UPPER_LAYER_IND_INFO_AVAILABLE && state.mDcnr == DcParam.DCNR_UNRESTRICTED ) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java index 3ed4b0e84a5..c21a9b0c4ae 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java @@ -738,6 +738,7 @@ public void dump(PrintWriter pw) { pw.println(" mSignalStrength=" + mSignalStrength + ","); pw.println(" mDataState=" + mDataState + ","); pw.println(" mDataNetType=" + mDataNetType + ","); + pw.println(" mFiveGState=" + mFiveGState + ","); } class MobilePhoneStateListener extends PhoneStateListener { From da829ee03fee60870c31caaab6120c52b095cb6f Mon Sep 17 00:00:00 2001 From: Sneh Bansal Date: Mon, 18 Mar 2019 17:42:33 +0530 Subject: [PATCH 021/240] Revert "Make HardwareRenderer public API" This reverts commit fe5dfcacfc670f48967472fa87a774d8284ac943. Its a temporary fix to unblock testing until Google fixes this on its own. Change-Id: If292f646be021f253339b902d562bbf6161c436b --- api/current.txt | 28 --- .../java/android/view/RenderNodeAnimator.java | 7 +- core/java/android/view/ThreadedRenderer.java | 6 +- core/java/android/view/ViewRootImpl.java | 32 ++- core/jni/android_view_ThreadedRenderer.cpp | 80 +++++- .../android/graphics/HardwareRenderer.java | 234 ++++++------------ .../drawable/AnimatedVectorDrawable.java | 7 +- tests/HwAccelerationTest/AndroidManifest.xml | 24 +- .../com/android/test/hwui/CustomRenderer.java | 76 ------ .../test/hwui/MyLittleTextureView.java | 87 ------- 10 files changed, 163 insertions(+), 418 deletions(-) delete mode 100644 tests/HwAccelerationTest/src/com/android/test/hwui/CustomRenderer.java delete mode 100644 tests/HwAccelerationTest/src/com/android/test/hwui/MyLittleTextureView.java diff --git a/api/current.txt b/api/current.txt index 35486e0f551..0bddbef747d 100644 --- a/api/current.txt +++ b/api/current.txt @@ -14107,34 +14107,6 @@ package android.graphics { ctor @Deprecated public EmbossMaskFilter(float[], float, float, float); } - public class HardwareRenderer { - ctor public HardwareRenderer(); - method public void clearContent(); - method public android.graphics.HardwareRenderer.FrameRenderRequest createRenderRequest(); - method public void destroy(); - method public boolean isOpaque(); - method public void notifyFramePending(); - method public void setContentRoot(@Nullable android.graphics.RenderNode); - method public void setLightSourceAlpha(@FloatRange(from=0.0f, to=1.0f) float, @FloatRange(from=0.0f, to=1.0f) float); - method public void setLightSourceGeometry(float, float, float, float); - method public void setName(String); - method public void setOpaque(boolean); - method public void setStopped(boolean); - method public void setSurface(@Nullable android.view.Surface); - field public static final int SYNC_CONTEXT_IS_STOPPED = 4; // 0x4 - field public static final int SYNC_FRAME_DROPPED = 8; // 0x8 - field public static final int SYNC_LOST_SURFACE_REWARD_IF_FOUND = 2; // 0x2 - field public static final int SYNC_OK = 0; // 0x0 - field public static final int SYNC_REDRAW_REQUESTED = 1; // 0x1 - } - - public final class HardwareRenderer.FrameRenderRequest { - method public android.graphics.HardwareRenderer.FrameRenderRequest setFrameCommitCallback(@NonNull java.util.concurrent.Executor, @NonNull Runnable); - method public android.graphics.HardwareRenderer.FrameRenderRequest setVsyncTime(long); - method public android.graphics.HardwareRenderer.FrameRenderRequest setWaitForPresent(boolean); - method public int syncAndDraw(); - } - public final class ImageDecoder implements java.lang.AutoCloseable { method public void close(); method @AnyThread @NonNull public static android.graphics.ImageDecoder.Source createSource(@NonNull android.content.res.Resources, int); diff --git a/core/java/android/view/RenderNodeAnimator.java b/core/java/android/view/RenderNodeAnimator.java index 23f2b8a0a3c..99c451d0288 100644 --- a/core/java/android/view/RenderNodeAnimator.java +++ b/core/java/android/view/RenderNodeAnimator.java @@ -25,7 +25,6 @@ import android.graphics.RecordingCanvas; import android.graphics.RenderNode; import android.os.Build; -import android.os.Handler; import android.util.SparseIntArray; import com.android.internal.util.VirtualRefBasePtr; @@ -85,7 +84,6 @@ public class RenderNodeAnimator extends Animator { private VirtualRefBasePtr mNativePtr; - private Handler mHandler; private RenderNode mTarget; private View mViewTarget; private int mRenderProperty = -1; @@ -224,9 +222,6 @@ private void doStart() { private void moveToRunningState() { mState = STATE_RUNNING; if (mNativePtr != null) { - if (mHandler == null) { - mHandler = new Handler(); - } nStart(mNativePtr.get()); } notifyStartListeners(); @@ -502,7 +497,7 @@ public void run() { // Called by native @UnsupportedAppUsage private static void callOnFinished(RenderNodeAnimator animator) { - animator.mHandler.post(animator::onFinished); + animator.onFinished(); } @Override diff --git a/core/java/android/view/ThreadedRenderer.java b/core/java/android/view/ThreadedRenderer.java index 3d3d5dc7db3..636477acd97 100644 --- a/core/java/android/view/ThreadedRenderer.java +++ b/core/java/android/view/ThreadedRenderer.java @@ -453,7 +453,7 @@ void registerRtFrameCallback(FrameDrawingCallback callback) { */ void destroyHardwareResources(View view) { destroyResources(view); - clearContent(); + destroyHardwareResources(); } private static void destroyResources(View view) { @@ -735,9 +735,7 @@ public void draw(final FrameDrawingCallback callback) { if (callback != null) { setFrameCallback(callback); } - createRenderRequest() - .setVsyncTime(vsync) - .syncAndDraw(); + syncAndDrawFrame(vsync); } } } diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index aefb3789f09..d2263ac1a2e 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -3481,25 +3481,21 @@ private void performDraw() { .captureFrameCommitCallbacks(); if (mReportNextDraw) { usingAsyncReport = true; - final Handler handler = mAttachInfo.mHandler; - mAttachInfo.mThreadedRenderer.setFrameCompleteCallback((long frameNr) -> - handler.post(() -> { - // TODO: Use the frame number - pendingDrawFinished(); - if (commitCallbacks != null) { - for (int i = 0; i < commitCallbacks.size(); i++) { - commitCallbacks.get(i).run(); - } - } - })); + mAttachInfo.mThreadedRenderer.setFrameCompleteCallback((long frameNr) -> { + // TODO: Use the frame number + pendingDrawFinished(); + if (commitCallbacks != null) { + for (int i = 0; i < commitCallbacks.size(); i++) { + commitCallbacks.get(i).run(); + } + } + }); } else if (commitCallbacks != null && commitCallbacks.size() > 0) { - final Handler handler = mAttachInfo.mHandler; - mAttachInfo.mThreadedRenderer.setFrameCompleteCallback((long frameNr) -> - handler.post(() -> { - for (int i = 0; i < commitCallbacks.size(); i++) { - commitCallbacks.get(i).run(); - } - })); + mAttachInfo.mThreadedRenderer.setFrameCompleteCallback((long frameNr) -> { + for (int i = 0; i < commitCallbacks.size(); i++) { + commitCallbacks.get(i).run(); + } + }); } } diff --git a/core/jni/android_view_ThreadedRenderer.cpp b/core/jni/android_view_ThreadedRenderer.cpp index ecc2dd0d359..dd9c9b04818 100644 --- a/core/jni/android_view_ThreadedRenderer.cpp +++ b/core/jni/android_view_ThreadedRenderer.cpp @@ -33,6 +33,7 @@ #include +#include #include #include #include @@ -143,22 +144,52 @@ class FinishAndInvokeListener : public MessageHandler { uint32_t mRequestId; }; -class FrameCompleteWrapper : public LightRefBase { +class RenderingException : public MessageHandler { public: - explicit FrameCompleteWrapper(JNIEnv* env, jobject jobject) { + RenderingException(JavaVM* vm, const std::string& message) + : mVm(vm) + , mMessage(message) { + } + + virtual void handleMessage(const Message&) { + throwException(mVm, mMessage); + } + + static void throwException(JavaVM* vm, const std::string& message) { + JNIEnv* env = getenv(vm); + jniThrowException(env, "java/lang/IllegalStateException", message.c_str()); + } + +private: + JavaVM* mVm; + std::string mMessage; +}; + +class FrameCompleteWrapper : public MessageHandler { +public: + FrameCompleteWrapper(JNIEnv* env, jobject jobject) { + mLooper = Looper::getForThread(); + LOG_ALWAYS_FATAL_IF(!mLooper.get(), "Must create runnable on a Looper thread!"); env->GetJavaVM(&mVm); mObject = env->NewGlobalRef(jobject); LOG_ALWAYS_FATAL_IF(!mObject, "Failed to make global ref"); } - ~FrameCompleteWrapper() { + virtual ~FrameCompleteWrapper() { releaseObject(); } - void onFrameComplete(int64_t frameNr) { + void postFrameComplete(int64_t frameNr) { + if (mObject) { + mFrameNr = frameNr; + mLooper->sendMessage(this, 0); + } + } + + virtual void handleMessage(const Message&) { if (mObject) { - ATRACE_FORMAT("frameComplete %" PRId64, frameNr); - getenv(mVm)->CallVoidMethod(mObject, gFrameCompleteCallback.onFrameComplete, frameNr); + ATRACE_FORMAT("frameComplete %" PRId64, mFrameNr); + getenv(mVm)->CallVoidMethod(mObject, gFrameCompleteCallback.onFrameComplete, mFrameNr); releaseObject(); } } @@ -166,6 +197,8 @@ class FrameCompleteWrapper : public LightRefBase { private: JavaVM* mVm; jobject mObject; + sp mLooper; + int64_t mFrameNr = -1; void releaseObject() { if (mObject) { @@ -178,14 +211,16 @@ class FrameCompleteWrapper : public LightRefBase { class RootRenderNode : public RenderNode, ErrorHandler { public: explicit RootRenderNode(JNIEnv* env) : RenderNode() { + mLooper = Looper::getForThread(); + LOG_ALWAYS_FATAL_IF(!mLooper.get(), + "Must create RootRenderNode on a thread with a looper!"); env->GetJavaVM(&mVm); } virtual ~RootRenderNode() {} virtual void onError(const std::string& message) override { - JNIEnv* env = getenv(mVm); - jniThrowException(env, "java/lang/IllegalStateException", message.c_str()); + mLooper->sendMessage(new RenderingException(mVm, message), 0); } virtual void prepareTree(TreeInfo& info) override { @@ -214,6 +249,14 @@ class RootRenderNode : public RenderNode, ErrorHandler { info.errorHandler = nullptr; } + void sendMessage(const sp& handler) { + mLooper->sendMessage(handler, 0); + } + + void sendMessageDelayed(const sp& handler, nsecs_t delayInMs) { + mLooper->sendMessageDelayed(ms2ns(delayInMs), handler, 0); + } + void attachAnimatingNode(RenderNode* animatingNode) { mPendingAnimatingRenderNodes.push_back(animatingNode); } @@ -361,6 +404,7 @@ class RootRenderNode : public RenderNode, ErrorHandler { } private: + sp mLooper; JavaVM* mVm; std::vector< sp > mPendingAnimatingRenderNodes; std::set< sp > mPendingVectorDrawableAnimators; @@ -391,9 +435,7 @@ class RootRenderNode : public RenderNode, ErrorHandler { // the onFinished callback will then be ignored. sp message = new FinishAndInvokeListener(anim); - auto looper = Looper::getForThread(); - LOG_ALWAYS_FATAL_IF(looper == nullptr, "Not on a looper thread?"); - looper->sendMessageDelayed(ms2ns(remainingTimeInMs), message, 0); + sendMessageDelayed(message, remainingTimeInMs); anim->clearOneShotListener(); } } @@ -421,6 +463,7 @@ class AnimationContextBridge : public AnimationContext { virtual void runRemainingAnimations(TreeInfo& info) { AnimationContext::runRemainingAnimations(info); mRootNode->runVectorDrawableAnimators(this, info); + postOnFinishedEvents(); } virtual void pauseAnimators() override { @@ -428,16 +471,27 @@ class AnimationContextBridge : public AnimationContext { } virtual void callOnFinished(BaseRenderNodeAnimator* animator, AnimationListener* listener) { - listener->onAnimationFinished(animator); + OnFinishedEvent event(animator, listener); + mOnFinishedEvents.push_back(event); } virtual void destroy() { AnimationContext::destroy(); mRootNode->detachAnimators(); + postOnFinishedEvents(); } private: sp mRootNode; + std::vector mOnFinishedEvents; + + void postOnFinishedEvents() { + if (mOnFinishedEvents.size()) { + sp message + = new InvokeAnimationListeners(mOnFinishedEvents); + mRootNode->sendMessage(message); + } + } }; class ContextFactoryImpl : public IContextFactory { @@ -904,7 +958,7 @@ static void android_view_ThreadedRenderer_setFrameCompleteCallback(JNIEnv* env, } else { sp wrapper = new FrameCompleteWrapper{env, callback}; proxy->setFrameCompleteCallback([wrapper](int64_t frameNr) { - wrapper->onFrameComplete(frameNr); + wrapper->postFrameComplete(frameNr); }); } } diff --git a/graphics/java/android/graphics/HardwareRenderer.java b/graphics/java/android/graphics/HardwareRenderer.java index e6233548651..abf8bc5e6cc 100644 --- a/graphics/java/android/graphics/HardwareRenderer.java +++ b/graphics/java/android/graphics/HardwareRenderer.java @@ -20,6 +20,7 @@ import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; +import android.annotation.TestApi; import android.app.Activity; import android.app.ActivityManager; import android.os.IBinder; @@ -27,16 +28,13 @@ import android.os.RemoteException; import android.os.ServiceManager; import android.util.Log; -import android.util.TimeUtils; import android.view.FrameMetricsObserver; import android.view.IGraphicsStats; import android.view.IGraphicsStatsCallback; import android.view.NativeVectorDrawableAnimator; -import android.view.PixelCopy; import android.view.Surface; import android.view.SurfaceHolder; import android.view.TextureLayer; -import android.view.animation.AnimationUtils; import com.android.internal.util.VirtualRefBasePtr; @@ -44,7 +42,6 @@ import java.io.FileDescriptor; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; -import java.util.concurrent.Executor; import sun.misc.Cleaner; @@ -53,8 +50,13 @@ * from {@link RenderNode}'s to an output {@link android.view.Surface}. There can be as many * HardwareRenderer instances as desired.

* - *

Resources & lifecycle

+ *

Threading

+ *

HardwareRenderer is not thread safe. An instance of a HardwareRenderer must only be + * created & used from a single thread. It does not matter what thread is used, however + * it must have a {@link android.os.Looper}. Multiple instances do not have to share the same + * thread, although they can.

* + *

Resources & lifecycle

*

All HardwareRenderer instances share a common render thread. The render thread contains * the GPU context & resources necessary to do GPU-accelerated rendering. As such, the first * HardwareRenderer created comes with the cost of also creating the associated GPU contexts, @@ -62,7 +64,6 @@ * is to have a HardwareRenderer instance for every active {@link Surface}. For example * when an Activity shows a Dialog the system internally will use 2 hardware renderers, both * of which may be drawing at the same time.

- * *

NOTE: Due to the shared, cooperative nature of the render thread it is critical that * any {@link Surface} used must have a prompt, reliable consuming side. System-provided * consumers such as {@link android.view.SurfaceView}, @@ -72,6 +73,8 @@ * it is the app's responsibility to ensure that they consume updates promptly and rapidly. * Failure to do so will cause the render thread to stall on that surface, blocking all * HardwareRenderer instances.

+ * + * @hide */ public class HardwareRenderer { private static final String LOG_TAG = "HardwareRenderer"; @@ -86,18 +89,18 @@ public class HardwareRenderer { * The renderer is requesting a redraw. This can occur if there's an animation that's running * in the RenderNode tree and the hardware renderer is unable to self-animate. * - *

If this is returned from syncAndDraw the expectation is that syncAndDraw + * If this is returned from syncAndDrawFrame the expectation is that syncAndDrawFrame * will be called again on the next vsync signal. */ public static final int SYNC_REDRAW_REQUESTED = 1 << 0; /** * The hardware renderer no longer has a valid {@link android.view.Surface} to render to. - * This can happen if {@link Surface#release()} was called. The user should no longer - * attempt to call syncAndDraw until a new surface has been provided by calling + * This can happen if {@link Surface#destroy()} was called. The user should no longer + * attempt to call syncAndDrawFrame until a new surface has been provided by calling * setSurface. * - *

Spoiler: the reward is GPU-accelerated drawing, better find that Surface! + * Spoiler: the reward is GPU-accelerated drawing, better find that Surface! */ public static final int SYNC_LOST_SURFACE_REWARD_IF_FOUND = 1 << 1; @@ -116,7 +119,6 @@ public class HardwareRenderer { */ public static final int SYNC_FRAME_DROPPED = 1 << 3; - /** @hide */ @IntDef(value = { SYNC_OK, SYNC_REDRAW_REQUESTED, SYNC_LOST_SURFACE_REWARD_IF_FOUND, SYNC_CONTEXT_IS_STOPPED, SYNC_FRAME_DROPPED}) @@ -151,6 +153,7 @@ public class HardwareRenderer { protected RenderNode mRootNode; private boolean mOpaque = true; private boolean mForceDark = false; + private FrameInfo mScratchInfo; private boolean mIsWideGamut = false; /** @@ -172,14 +175,14 @@ public HardwareRenderer() { * Destroys the rendering context of this HardwareRenderer. This destroys the resources * associated with this renderer and releases the currently set {@link Surface}. * - *

The renderer may be restored from this state by setting a new {@link Surface}, setting + * The renderer may be restored from this state by setting a new {@link Surface}, setting * new rendering content with {@link #setContentRoot(RenderNode)}, and resuming - * rendering by issuing a new {@link FrameRenderRequest}. + * rendering with {@link #syncAndDrawFrame(long)}. * - *

It is suggested to call this in response to callbacks such as + * It is suggested to call this in response to callbacks such as * {@link android.view.SurfaceHolder.Callback#surfaceDestroyed(SurfaceHolder)}. * - *

Note that if there are any outstanding frame commit callbacks they may never being + * Note that if there are any outstanding frame commit callbacks they may end up never being * invoked if the frame was deferred to a later vsync. */ public void destroy() { @@ -201,14 +204,14 @@ public void setName(String name) { * Sets the center of the light source. The light source point controls the directionality * and shape of shadows rendered by RenderNode Z & elevation. * - *

The platform's recommendation is to set lightX to 'displayWidth / 2f - windowLeft', set + * The platform's recommendation is to set lightX to 'displayWidth / 2f - windowLeft', set * lightY to 0 - windowTop, lightZ set to 600dp, and lightRadius to 800dp. * - *

The light source should be setup both as part of initial configuration, and whenever + * The light source should be setup both as part of initial configuration, and whenever * the window moves to ensure the light source stays anchored in display space instead * of in window space. * - *

This must be set at least once along with {@link #setLightSourceAlpha(float, float)} + * This must be set at least once along with {@link #setLightSourceAlpha(float, float)} * before shadows will work. * * @param lightX The X position of the light source @@ -230,10 +233,10 @@ public void setLightSourceGeometry(float lightX, float lightY, float lightZ, * Configures the ambient & spot shadow alphas. This is the alpha used when the shadow * has max alpha, and ramps down from the values provided to zero. * - *

These values are typically provided by the current theme, see + * These values are typically provided by the current theme, see * {@link android.R.attr#spotShadowAlpha} and {@link android.R.attr#ambientShadowAlpha}. * - *

This must be set at least once along with + * This must be set at least once along with * {@link #setLightSourceGeometry(float, float, float, float)} before shadows will work. * * @param ambientShadowAlpha The alpha for the ambient shadow. If unsure, a reasonable default @@ -251,8 +254,8 @@ public void setLightSourceAlpha(@FloatRange(from = 0.0f, to = 1.0f) float ambien /** * Sets the content root to render. It is not necessary to call this whenever the content * recording changes. Any mutations to the RenderNode content, or any of the RenderNode's - * contained within the content node, will be applied whenever a new {@link FrameRenderRequest} - * is issued via {@link #createRenderRequest()} and {@link FrameRenderRequest#syncAndDraw()}. + * contained within the content node, will be applied whenever {@link #syncAndDrawFrame(long)} + * is called. * * @param content The content to set as the root RenderNode. If null the content root is removed * and the renderer will draw nothing. @@ -292,133 +295,53 @@ public void setSurface(@Nullable Surface surface) { } /** - * Sets the parameters that can be used to control a render request for a - * {@link HardwareRenderer}. This is not thread-safe and must not be held on to for longer - * than a single frame request. + * Syncs the RenderNode tree to the render thread and requests a frame to be drawn. + * + * @hide */ - public final class FrameRenderRequest { - private FrameInfo mFrameInfo = new FrameInfo(); - private boolean mWaitForPresent; - - private FrameRenderRequest() { } - - private void reset() { - mWaitForPresent = false; - // Default to the animation time which, if choreographer is in play, will default to the - // current vsync time. Otherwise it will be 'now'. - mRenderRequest.setVsyncTime( - AnimationUtils.currentAnimationTimeMillis() * TimeUtils.NANOS_PER_MS); - } - - /** @hide */ - public void setFrameInfo(FrameInfo info) { - System.arraycopy(info.frameInfo, 0, mFrameInfo.frameInfo, 0, info.frameInfo.length); - } - - /** - * Sets the vsync time that represents the start point of this frame. Typically this - * comes from {@link android.view.Choreographer.FrameCallback}. Other compatible time - * sources include {@link System#nanoTime()}, however if the result is being displayed - * on-screen then using {@link android.view.Choreographer} is strongly recommended to - * ensure smooth animations. - * - *

If the clock source is not from a CLOCK_MONOTONIC source then any animations driven - * directly by RenderThread will not be synchronized properly with the current frame. - * - * @param vsyncTime The vsync timestamp for this frame. The timestamp is in nanoseconds - * and should come from a CLOCK_MONOTONIC source. - * - * @return this instance - */ - public FrameRenderRequest setVsyncTime(long vsyncTime) { - mFrameInfo.setVsync(vsyncTime, vsyncTime); - mFrameInfo.addFlags(FrameInfo.FLAG_SURFACE_CANVAS); - return this; - } - - /** - * Adds a frame commit callback. This callback will be invoked when the current rendering - * content has been rendered into a frame and submitted to the swap chain. The frame may - * not currently be visible on the display when this is invoked, but it has been submitted. - * This callback is useful in combination with {@link PixelCopy} to capture the current - * rendered content of the UI reliably. - * - * @param executor The executor to run the callback on. It is strongly recommended that - * this executor post to a different thread, as the calling thread is - * highly sensitive to being blocked. - * @param frameCommitCallback The callback to invoke when the frame content has been drawn. - * Will be invoked on the given {@link Executor}. - * - * @return this instance - */ - public FrameRenderRequest setFrameCommitCallback(@NonNull Executor executor, - @NonNull Runnable frameCommitCallback) { - setFrameCompleteCallback(frameNr -> executor.execute(frameCommitCallback)); - return this; - } - - /** - * Sets whether or not {@link #syncAndDraw()} should block until the frame has been - * presented. If this is true and {@link #syncAndDraw()} does not return - * {@link #SYNC_FRAME_DROPPED} or an error then when {@link #syncAndDraw()} has returned - * the frame has been submitted to the {@link Surface}. The default and typically - * recommended value is false, as blocking for present will prevent pipelining from - * happening, reducing overall throughput. This is useful for situations such as - * {@link SurfaceHolder.Callback2#surfaceRedrawNeeded(SurfaceHolder)} where it is desired - * to block until a frame has been presented to ensure first-frame consistency with - * other Surfaces. - * - * @param shouldWait If true the next call to {@link #syncAndDraw()} will block until - * completion. - * @return this instance - */ - public FrameRenderRequest setWaitForPresent(boolean shouldWait) { - mWaitForPresent = shouldWait; - return this; - } - - /** - * Syncs the RenderNode tree to the render thread and requests a frame to be drawn. This - * {@link FrameRenderRequest} instance should no longer be used after calling this method. - * The system internally may reuse instances of {@link FrameRenderRequest} to reduce - * allocation churn. - * - * @return The result of the sync operation. See {@link SyncAndDrawResult}. - */ - @SyncAndDrawResult - public int syncAndDraw() { - int syncResult = syncAndDrawFrame(mFrameInfo); - if (mWaitForPresent && (syncResult & SYNC_FRAME_DROPPED) == 0) { - fence(); - } - return syncResult; - } + @SyncAndDrawResult + public int syncAndDrawFrame(@NonNull FrameInfo frameInfo) { + return nSyncAndDrawFrame(mNativeProxy, frameInfo.frameInfo, frameInfo.frameInfo.length); } - private FrameRenderRequest mRenderRequest = new FrameRenderRequest(); - /** - * Returns a {@link FrameRenderRequest} that can be used to render a new frame. This is used - * to synchronize the RenderNode content provided by {@link #setContentRoot(RenderNode)} with - * the RenderThread and then renders a single frame to the Surface set with - * {@link #setSurface(Surface)}. + * Syncs the RenderNode tree to the render thread and requests a frame to be drawn. * - * @return An instance of {@link FrameRenderRequest}. The instance may be reused for every - * frame, so the caller should not hold onto it for longer than a single render request. + * @param vsyncTime The vsync timestamp for this frame. Typically this comes from + * {@link android.view.Choreographer.FrameCallback}. Must be set and be valid + * as the renderer uses this time internally to drive animations. + * @return The result of the sync operation. See {@link SyncAndDrawResult}. */ - public FrameRenderRequest createRenderRequest() { - mRenderRequest.reset(); - return mRenderRequest; + @SyncAndDrawResult + public int syncAndDrawFrame(long vsyncTime) { + if (mScratchInfo == null) { + mScratchInfo = new FrameInfo(); + } + mScratchInfo.setVsync(vsyncTime, vsyncTime); + mScratchInfo.addFlags(FrameInfo.FLAG_SURFACE_CANVAS); + return syncAndDrawFrame(mScratchInfo); } /** * Syncs the RenderNode tree to the render thread and requests a frame to be drawn. + * frameCommitCallback callback will be invoked when the current rendering content has been + * rendered into a frame and submitted to the swap chain. * - * @hide + * @param vsyncTime The vsync timestamp for this frame. Typically this comes from + * {@link android.view.Choreographer.FrameCallback}. Must be set and + * be valid as the renderer uses this time internally to drive + * animations. + * @param frameCommitCallback The callback to invoke when the frame content has been drawn. + * Will be invoked on the current {@link android.os.Looper} thread. + * @return The result of the sync operation. See {@link SyncAndDrawResult}. */ @SyncAndDrawResult - public int syncAndDrawFrame(@NonNull FrameInfo frameInfo) { - return nSyncAndDrawFrame(mNativeProxy, frameInfo.frameInfo, frameInfo.frameInfo.length); + public int syncAndDrawFrame(long vsyncTime, + @Nullable Runnable frameCommitCallback) { + if (frameCommitCallback != null) { + setFrameCompleteCallback(frameNr -> frameCommitCallback.run()); + } + return syncAndDrawFrame(vsyncTime); } /** @@ -426,11 +349,10 @@ public int syncAndDrawFrame(@NonNull FrameInfo frameInfo) { * is useful to temporarily suspend using the active Surface in order to do any Surface * mutations necessary. * - *

Any subsequent draws will override the pause, resuming normal operation. + * Any subsequent draws will override the pause, resuming normal operation. * * @return true if there was an outstanding render request, false otherwise. If this is true - * the caller should ensure that {@link #createRenderRequest()} - * and {@link FrameRenderRequest#syncAndDraw()} is called at the soonest + * the caller should ensure that {@link #syncAndDrawFrame(long)} is called at the soonest * possible time to resume normal operation. * * TODO Should this be exposed? ViewRootImpl needs it because it destroys the old @@ -445,14 +367,14 @@ public boolean pause() { /** * Hard stops rendering into the surface. If the renderer is stopped it will - * block any attempt to render. Calls to {@link FrameRenderRequest#syncAndDraw()} will - * still sync over the latest rendering content, however they will not render and instead + * block any attempt to render. Calls to {@link #syncAndDrawFrame(long)} will still + * sync over the latest rendering content, however they will not render and instead * {@link #SYNC_CONTEXT_IS_STOPPED} will be returned. * - *

If false is passed then rendering will resume as normal. Any pending rendering requests + * If false is passed then rendering will resume as normal. Any pending rendering requests * will produce a new frame at the next vsync signal. * - *

This is useful in combination with lifecycle events such as {@link Activity#onStop()} + * This is useful in combination with lifecycle events such as {@link Activity#onStop()} * and {@link Activity#onStart()}. * * @param stopped true to stop all rendering, false to resume @@ -462,26 +384,24 @@ public void setStopped(boolean stopped) { } /** - * Destroys all the display lists associated with the current rendering content. + * Destroys all hardware rendering resources associated with the current rendering content. * This includes releasing a reference to the current content root RenderNode. It will * therefore be necessary to call {@link #setContentRoot(RenderNode)} in order to resume - * rendering after calling this, along with re-recording the display lists for the - * RenderNode tree. + * rendering after calling this. * - *

It is recommended, but not necessary, to use this in combination with lifecycle events + * It is recommended, but not necessary, to use this in combination with lifecycle events * such as {@link Activity#onStop()} and {@link Activity#onStart()} or in response to * {@link android.content.ComponentCallbacks2#onTrimMemory(int)} signals such as * {@link android.content.ComponentCallbacks2#TRIM_MEMORY_UI_HIDDEN} * * See also {@link #setStopped(boolean)} */ - public void clearContent() { + public void destroyHardwareResources() { nDestroyHardwareResources(mNativeProxy); } /** * Whether or not the force-dark feature should be used for this renderer. - * @hide */ public boolean setForceDark(boolean enable) { if (mForceDark != enable) { @@ -495,24 +415,20 @@ public boolean setForceDark(boolean enable) { /** * Allocate buffers ahead of time to avoid allocation delays during rendering. * - *

Typically a Surface will allocate buffers lazily. This is usually fine and reduces the + * Typically a Surface will allocate buffers lazily. This is usually fine and reduces the * memory usage of Surfaces that render rarely or never hit triple buffering. However * for UI it can result in a slight bit of jank on first launch. This hint will * tell the HardwareRenderer that now is a good time to allocate the 3 buffers * necessary for typical rendering. * - *

Must be called after a {@link Surface} has been set. - * - * TODO: Figure out if we even need/want this. Should HWUI just be doing this in response - * to setSurface anyway? Vulkan swapchain makes this murky, so delay making it public - * @hide + * Must be called after a {@link Surface} has been set. */ public void allocateBuffers() { nAllocateBuffers(mNativeProxy); } /** - * Notifies the hardware renderer that a call to {@link FrameRenderRequest#syncAndDraw()} will + * Notifies the hardware renderer that a call to {@link #syncAndDrawFrame(long)} will * be coming soon. This is used to help schedule when RenderThread-driven animations will * happen as the renderer wants to avoid producing more than one frame per vsync signal. */ @@ -523,7 +439,7 @@ public void notifyFramePending() { /** * Change the HardwareRenderer's opacity. Will take effect on the next frame produced. * - *

If the renderer is set to opaque it is the app's responsibility to ensure that the + * If the renderer is set to opaque it is the app's responsibility to ensure that the * content renders to every pixel of the Surface, otherwise corruption may result. Note that * this includes ensuring that the first draw of any given pixel does not attempt to blend * against the destination. If this is false then the hardware renderer will clear to @@ -611,7 +527,7 @@ public void registerVectorDrawableAnimator(NativeVectorDrawableAnimator animator } /** - * Prevents any further drawing until {@link FrameRenderRequest#syncAndDraw()} is called. + * Prevents any further drawing until {@link #syncAndDrawFrame(long)} is called. * This is a signal that the contents of the RenderNode tree are no longer safe to play back. * In practice this usually means that there are Functor pointers in the * display list that are no longer valid. @@ -802,8 +718,10 @@ public interface FrameCompleteCallback { * Interface for listening to picture captures * @hide */ + @TestApi public interface PictureCapturedCallback { /** @hide */ + @TestApi void onPictureCaptured(Picture picture); } diff --git a/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java b/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java index d7aee776752..789e38c4e65 100644 --- a/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java +++ b/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java @@ -43,7 +43,6 @@ import android.graphics.Rect; import android.graphics.RenderNode; import android.os.Build; -import android.os.Handler; import android.util.ArrayMap; import android.util.AttributeSet; import android.util.IntArray; @@ -1242,7 +1241,6 @@ public static class VectorDrawableAnimatorRT implements VectorDrawableAnimator, // If the duration of an animation is more than 300 frames, we cap the sample size to 300. private static final int MAX_SAMPLE_POINTS = 300; - private Handler mHandler; private AnimatorListener mListener = null; private final LongArray mStartDelays = new LongArray(); private PropertyValuesHolder.PropertyValues mTmpValues = @@ -1673,9 +1671,6 @@ private void startAnimation() { .mRootName); } mStarted = true; - if (mHandler == null) { - mHandler = new Handler(); - } nStart(mSetPtr, this, ++mLastListenerId); invalidateOwningView(); if (mListener != null) { @@ -1785,7 +1780,7 @@ private void onAnimationEnd(int listenerId) { // onFinished: should be called from native @UnsupportedAppUsage private static void callOnFinished(VectorDrawableAnimatorRT set, int id) { - set.mHandler.post(() -> set.onAnimationEnd(id)); + set.onAnimationEnd(id); } private void transferPendingActions(VectorDrawableAnimator animatorSet) { diff --git a/tests/HwAccelerationTest/AndroidManifest.xml b/tests/HwAccelerationTest/AndroidManifest.xml index 7b8c154dea1..1a4ec94d77b 100644 --- a/tests/HwAccelerationTest/AndroidManifest.xml +++ b/tests/HwAccelerationTest/AndroidManifest.xml @@ -1028,28 +1028,8 @@ - - - - - - - - - - - - - - diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/CustomRenderer.java b/tests/HwAccelerationTest/src/com/android/test/hwui/CustomRenderer.java deleted file mode 100644 index fece8babb40..00000000000 --- a/tests/HwAccelerationTest/src/com/android/test/hwui/CustomRenderer.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.test.hwui; - -import android.app.Activity; -import android.graphics.Color; -import android.graphics.HardwareRenderer; -import android.graphics.Paint; -import android.graphics.RecordingCanvas; -import android.graphics.RenderNode; -import android.os.Bundle; -import android.util.Log; -import android.view.SurfaceHolder; - -public class CustomRenderer extends Activity { - private RenderNode mContent = new RenderNode("CustomRenderer"); - private HardwareRenderer mRenderer = new HardwareRenderer(); - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - getWindow().takeSurface(mSurfaceCallbacks); - } - - private SurfaceHolder.Callback2 mSurfaceCallbacks = new SurfaceHolder.Callback2() { - - @Override - public void surfaceRedrawNeeded(SurfaceHolder holder) { - } - - @Override - public void surfaceCreated(SurfaceHolder holder) { - } - - @Override - public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { - mContent.setLeftTopRightBottom(0, 0, width, height); - RecordingCanvas canvas = mContent.beginRecording(); - canvas.drawColor(Color.WHITE); - Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG); - paint.setColor(Color.BLACK); - paint.setTextAlign(Paint.Align.CENTER); - paint.setTextSize(Math.min(width, height) * .05f); - canvas.drawText("Hello custom renderer!", width / 2, height / 2, paint); - mContent.endRecording(); - - mRenderer.setContentRoot(mContent); - mRenderer.setSurface(holder.getSurface()); - mRenderer.createRenderRequest() - .setVsyncTime(System.nanoTime()) - .setFrameCommitCallback(Runnable::run, () -> { - Log.d("CustomRenderer", "Frame committed!"); - }) - .syncAndDraw(); - } - - @Override - public void surfaceDestroyed(SurfaceHolder holder) { - mRenderer.destroy(); - } - }; -} diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/MyLittleTextureView.java b/tests/HwAccelerationTest/src/com/android/test/hwui/MyLittleTextureView.java deleted file mode 100644 index 08d5d4fff50..00000000000 --- a/tests/HwAccelerationTest/src/com/android/test/hwui/MyLittleTextureView.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.test.hwui; - -import android.app.Activity; -import android.graphics.Bitmap; -import android.graphics.Canvas; -import android.graphics.Color; -import android.graphics.ColorSpace; -import android.graphics.HardwareRenderer; -import android.graphics.Outline; -import android.graphics.PixelFormat; -import android.graphics.Rect; -import android.graphics.RenderNode; -import android.hardware.HardwareBuffer; -import android.media.Image; -import android.media.ImageReader; -import android.os.Bundle; -import android.widget.ImageView; - -public class MyLittleTextureView extends Activity { - private RenderNode mContent = new RenderNode("CustomRenderer"); - private HardwareRenderer mRenderer = new HardwareRenderer(); - private ImageView mImageView; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - mImageView = new ImageView(this); - mImageView.setScaleType(ImageView.ScaleType.FIT_CENTER); - setContentView(mImageView); - - ImageReader reader = ImageReader.newInstance(100, 100, PixelFormat.RGBA_8888, 3, - HardwareBuffer.USAGE_GPU_SAMPLED_IMAGE | HardwareBuffer.USAGE_GPU_COLOR_OUTPUT); - mRenderer.setSurface(reader.getSurface()); - mRenderer.setLightSourceAlpha(0.0f, 1.0f); - mRenderer.setLightSourceGeometry(100 / 2f, 0f, 800.0f, 20.0f); - mContent.setLeftTopRightBottom(0, 0, 100, 100); - - Rect childRect = new Rect(25, 25, 65, 65); - RenderNode childNode = new RenderNode("shadowCaster"); - childNode.setLeftTopRightBottom(childRect.left, childRect.top, - childRect.right, childRect.bottom); - Outline outline = new Outline(); - outline.setRect(new Rect(0, 0, childRect.width(), childRect.height())); - outline.setAlpha(1f); - childNode.setOutline(outline); - { - Canvas canvas = childNode.beginRecording(); - canvas.drawColor(Color.BLUE); - } - childNode.endRecording(); - childNode.setElevation(20f); - - { - Canvas canvas = mContent.beginRecording(); - canvas.drawColor(Color.WHITE); - canvas.enableZ(); - canvas.drawRenderNode(childNode); - canvas.disableZ(); - } - mContent.endRecording(); - mRenderer.setContentRoot(mContent); - mRenderer.createRenderRequest() - .setWaitForPresent(true) - .syncAndDraw(); - Image image = reader.acquireNextImage(); - Bitmap bitmap = Bitmap.wrapHardwareBuffer(image.getHardwareBuffer(), - ColorSpace.get(ColorSpace.Named.SRGB)); - mImageView.setImageBitmap(bitmap); - image.close(); - } -} From 5da47b26c0435c565b7d714b3bd93135b465fb88 Mon Sep 17 00:00:00 2001 From: Naval saini Date: Wed, 13 Feb 2019 15:43:27 +0530 Subject: [PATCH 022/240] Matching codec index between frameworks and stack Aptx-Adaptive and LDAC codecs indexs were reverse in order which was not matching with stack side codec index. Now this discrepancy is corrected on framework side. CRs-Fixed: 2397930 Change-Id: I9b000d798695a28f523e55e6a7d7bc78a5c8b6b8 --- core/java/android/bluetooth/BluetoothCodecConfig.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/java/android/bluetooth/BluetoothCodecConfig.java b/core/java/android/bluetooth/BluetoothCodecConfig.java index 5a8270e4509..0f4fbf1cd1b 100644 --- a/core/java/android/bluetooth/BluetoothCodecConfig.java +++ b/core/java/android/bluetooth/BluetoothCodecConfig.java @@ -42,9 +42,9 @@ public final class BluetoothCodecConfig implements Parcelable { @UnsupportedAppUsage public static final int SOURCE_CODEC_TYPE_APTX_HD = 3; @UnsupportedAppUsage - public static final int SOURCE_CODEC_TYPE_LDAC = 4; + public static final int SOURCE_CODEC_TYPE_APTX_ADAPTIVE = 4; @UnsupportedAppUsage - public static final int SOURCE_CODEC_TYPE_APTX_ADAPTIVE = 5; + public static final int SOURCE_CODEC_TYPE_LDAC = 5; @UnsupportedAppUsage public static final int SOURCE_CODEC_TYPE_MAX = 6; From 307bf40a5f186a9c786912b17c7413f4914747b6 Mon Sep 17 00:00:00 2001 From: chen xu Date: Mon, 4 Mar 2019 17:19:48 -0800 Subject: [PATCH 023/240] fix the issue that sending wrong preferred networktype to RIL Bug: 126805258 Test: Manual CRs-Fixed: 2419635 Change-Id: Ifb1fc21423a09f0d000553d4d06bafa023adc9d6 Merged-in: Ifb1fc21423a09f0d000553d4d06bafa023adc9d6 (cherry picked from commit 42814534d91b61e8c8a29f4f1023c00d1a82d014) --- telephony/java/android/telephony/RadioAccessFamily.java | 5 ++++- telephony/java/android/telephony/TelephonyManager.java | 4 ++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/telephony/java/android/telephony/RadioAccessFamily.java b/telephony/java/android/telephony/RadioAccessFamily.java index c1786befb09..eb889c6171a 100644 --- a/telephony/java/android/telephony/RadioAccessFamily.java +++ b/telephony/java/android/telephony/RadioAccessFamily.java @@ -22,6 +22,7 @@ import android.os.Build; import android.os.Parcel; import android.os.Parcelable; +import android.telephony.TelephonyManager.PrefNetworkMode; import com.android.internal.telephony.RILConstants; @@ -170,7 +171,8 @@ public android.telephony.RadioAccessFamily[] newArray(int size) { }; @UnsupportedAppUsage - public static int getRafFromNetworkType(int type) { + @TelephonyManager.NetworkTypeBitMask + public static int getRafFromNetworkType(@PrefNetworkMode int type) { switch (type) { case RILConstants.NETWORK_MODE_WCDMA_PREF: return GSM | WCDMA; @@ -279,6 +281,7 @@ public static int getHighestRafCapability(int raf) { } @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) + @PrefNetworkMode public static int getNetworkTypeFromRaf(int raf) { raf = getAdjustedRaf(raf); diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java index 10439880b58..4fd914f0824 100644 --- a/telephony/java/android/telephony/TelephonyManager.java +++ b/telephony/java/android/telephony/TelephonyManager.java @@ -6856,12 +6856,12 @@ public int getNetworkSelectionMode() { * app has carrier privileges (see {@link #hasCarrierPrivileges}). * * @param subId the id of the subscription to set the preferred network type for. - * @param networkType the preferred network type, defined in RILConstants.java. + * @param networkType the preferred network type * @return true on success; false on any failure. * @hide */ @UnsupportedAppUsage - public boolean setPreferredNetworkType(int subId, int networkType) { + public boolean setPreferredNetworkType(int subId, @PrefNetworkMode int networkType) { try { ITelephony telephony = getITelephony(); if (telephony != null) { From e9c2b78d77c3b0ef2a3bfb824865a73986fe67b9 Mon Sep 17 00:00:00 2001 From: chen xu Date: Wed, 13 Mar 2019 13:26:39 -0700 Subject: [PATCH 024/240] fix the issue that setPreferredNW send wrong RAT to HAL Bug: 126805258 Test: Manual test to set LTE only mode CRs-Fixed: 2419635 Change-Id: I2e88d3bc22ca8d1e626bf381840cc80f832a8b3f (cherry picked from commit 14778d38e8014f4c65f3df25935eb39e43c8d214) --- .../android/telephony/RadioAccessFamily.java | 77 ------------------- 1 file changed, 77 deletions(-) diff --git a/telephony/java/android/telephony/RadioAccessFamily.java b/telephony/java/android/telephony/RadioAccessFamily.java index eb889c6171a..3317c22da4b 100644 --- a/telephony/java/android/telephony/RadioAccessFamily.java +++ b/telephony/java/android/telephony/RadioAccessFamily.java @@ -397,81 +397,4 @@ public static int rafTypeFromString(String rafList) { } return result; } - - /** - * convert RAF from {@link android.hardware.radio.V1_0.RadioAccessFamily} to - * {@link TelephonyManager.NetworkTypeBitMask}, the bitmask represented by - * {@link TelephonyManager.NetworkType}. - * - * @param raf {@link android.hardware.radio.V1_0.RadioAccessFamily} - * @return {@link TelephonyManager.NetworkTypeBitMask} - */ - public static int convertToNetworkTypeBitMask(int raf) { - int networkTypeRaf = 0; - - if ((raf & android.hardware.radio.V1_0.RadioAccessFamily.GSM) != 0) { - networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_GSM; - } - if ((raf & android.hardware.radio.V1_0.RadioAccessFamily.GPRS) != 0) { - networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_GPRS; - } - if ((raf & android.hardware.radio.V1_0.RadioAccessFamily.EDGE) != 0) { - networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_EDGE; - } - // convert both IS95A/IS95B to CDMA as network mode doesn't support CDMA - if ((raf & android.hardware.radio.V1_0.RadioAccessFamily.IS95A) != 0) { - networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_CDMA; - } - if ((raf & android.hardware.radio.V1_0.RadioAccessFamily.IS95B) != 0) { - networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_CDMA; - } - if ((raf & android.hardware.radio.V1_0.RadioAccessFamily.ONE_X_RTT) != 0) { - networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_1xRTT; - } - if ((raf & android.hardware.radio.V1_0.RadioAccessFamily.EVDO_0) != 0) { - networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_EVDO_0; - } - if ((raf & android.hardware.radio.V1_0.RadioAccessFamily.EVDO_A) != 0) { - networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_EVDO_A; - } - if ((raf & android.hardware.radio.V1_0.RadioAccessFamily.EVDO_B) != 0) { - networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_EVDO_B; - } - if ((raf & android.hardware.radio.V1_0.RadioAccessFamily.EHRPD) != 0) { - networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_EHRPD; - } - if ((raf & android.hardware.radio.V1_0.RadioAccessFamily.HSUPA) != 0) { - networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_HSUPA; - } - if ((raf & android.hardware.radio.V1_0.RadioAccessFamily.HSDPA) != 0) { - networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_HSDPA; - } - if ((raf & android.hardware.radio.V1_0.RadioAccessFamily.HSPA) != 0) { - networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_HSPA; - } - if ((raf & android.hardware.radio.V1_0.RadioAccessFamily.HSPAP) != 0) { - networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_HSPAP; - } - if ((raf & android.hardware.radio.V1_0.RadioAccessFamily.UMTS) != 0) { - networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_UMTS; - } - if ((raf & android.hardware.radio.V1_0.RadioAccessFamily.TD_SCDMA) != 0) { - networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_TD_SCDMA; - } - if ((raf & android.hardware.radio.V1_0.RadioAccessFamily.LTE) != 0) { - networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_LTE; - } - if ((raf & android.hardware.radio.V1_0.RadioAccessFamily.LTE_CA) != 0) { - networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_LTE_CA; - } - if ((raf & android.hardware.radio.V1_4.RadioAccessFamily.NR) != 0) { - networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_NR; - } - // TODO: need hal definition - if ((raf & (1 << ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN)) != 0) { - networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_IWLAN; - } - - return (networkTypeRaf == 0) ? TelephonyManager.NETWORK_TYPE_UNKNOWN : networkTypeRaf; - } } From dae8c49191ffaa3401343f2cc2765167eaf9d59a Mon Sep 17 00:00:00 2001 From: Vara Prasad A V S G Date: Sun, 7 Apr 2019 19:21:22 +0530 Subject: [PATCH 025/240] Revert "Revert "Make HardwareRenderer public API"". This reverts commit da829ee03fee60870c31caaab6120c52b095cb6f. Change-Id: I7a7b8690c996dd022d9ea38ec4bdc2873fbfd43c --- api/current.txt | 28 +++ .../java/android/view/RenderNodeAnimator.java | 7 +- core/java/android/view/ThreadedRenderer.java | 6 +- core/java/android/view/ViewRootImpl.java | 32 +-- core/jni/android_view_ThreadedRenderer.cpp | 80 +----- .../android/graphics/HardwareRenderer.java | 234 ++++++++++++------ .../drawable/AnimatedVectorDrawable.java | 7 +- tests/HwAccelerationTest/AndroidManifest.xml | 24 +- .../com/android/test/hwui/CustomRenderer.java | 76 ++++++ .../test/hwui/MyLittleTextureView.java | 87 +++++++ 10 files changed, 418 insertions(+), 163 deletions(-) create mode 100644 tests/HwAccelerationTest/src/com/android/test/hwui/CustomRenderer.java create mode 100644 tests/HwAccelerationTest/src/com/android/test/hwui/MyLittleTextureView.java diff --git a/api/current.txt b/api/current.txt index 0bddbef747d..35486e0f551 100644 --- a/api/current.txt +++ b/api/current.txt @@ -14107,6 +14107,34 @@ package android.graphics { ctor @Deprecated public EmbossMaskFilter(float[], float, float, float); } + public class HardwareRenderer { + ctor public HardwareRenderer(); + method public void clearContent(); + method public android.graphics.HardwareRenderer.FrameRenderRequest createRenderRequest(); + method public void destroy(); + method public boolean isOpaque(); + method public void notifyFramePending(); + method public void setContentRoot(@Nullable android.graphics.RenderNode); + method public void setLightSourceAlpha(@FloatRange(from=0.0f, to=1.0f) float, @FloatRange(from=0.0f, to=1.0f) float); + method public void setLightSourceGeometry(float, float, float, float); + method public void setName(String); + method public void setOpaque(boolean); + method public void setStopped(boolean); + method public void setSurface(@Nullable android.view.Surface); + field public static final int SYNC_CONTEXT_IS_STOPPED = 4; // 0x4 + field public static final int SYNC_FRAME_DROPPED = 8; // 0x8 + field public static final int SYNC_LOST_SURFACE_REWARD_IF_FOUND = 2; // 0x2 + field public static final int SYNC_OK = 0; // 0x0 + field public static final int SYNC_REDRAW_REQUESTED = 1; // 0x1 + } + + public final class HardwareRenderer.FrameRenderRequest { + method public android.graphics.HardwareRenderer.FrameRenderRequest setFrameCommitCallback(@NonNull java.util.concurrent.Executor, @NonNull Runnable); + method public android.graphics.HardwareRenderer.FrameRenderRequest setVsyncTime(long); + method public android.graphics.HardwareRenderer.FrameRenderRequest setWaitForPresent(boolean); + method public int syncAndDraw(); + } + public final class ImageDecoder implements java.lang.AutoCloseable { method public void close(); method @AnyThread @NonNull public static android.graphics.ImageDecoder.Source createSource(@NonNull android.content.res.Resources, int); diff --git a/core/java/android/view/RenderNodeAnimator.java b/core/java/android/view/RenderNodeAnimator.java index 99c451d0288..23f2b8a0a3c 100644 --- a/core/java/android/view/RenderNodeAnimator.java +++ b/core/java/android/view/RenderNodeAnimator.java @@ -25,6 +25,7 @@ import android.graphics.RecordingCanvas; import android.graphics.RenderNode; import android.os.Build; +import android.os.Handler; import android.util.SparseIntArray; import com.android.internal.util.VirtualRefBasePtr; @@ -84,6 +85,7 @@ public class RenderNodeAnimator extends Animator { private VirtualRefBasePtr mNativePtr; + private Handler mHandler; private RenderNode mTarget; private View mViewTarget; private int mRenderProperty = -1; @@ -222,6 +224,9 @@ private void doStart() { private void moveToRunningState() { mState = STATE_RUNNING; if (mNativePtr != null) { + if (mHandler == null) { + mHandler = new Handler(); + } nStart(mNativePtr.get()); } notifyStartListeners(); @@ -497,7 +502,7 @@ public void run() { // Called by native @UnsupportedAppUsage private static void callOnFinished(RenderNodeAnimator animator) { - animator.onFinished(); + animator.mHandler.post(animator::onFinished); } @Override diff --git a/core/java/android/view/ThreadedRenderer.java b/core/java/android/view/ThreadedRenderer.java index 636477acd97..3d3d5dc7db3 100644 --- a/core/java/android/view/ThreadedRenderer.java +++ b/core/java/android/view/ThreadedRenderer.java @@ -453,7 +453,7 @@ void registerRtFrameCallback(FrameDrawingCallback callback) { */ void destroyHardwareResources(View view) { destroyResources(view); - destroyHardwareResources(); + clearContent(); } private static void destroyResources(View view) { @@ -735,7 +735,9 @@ public void draw(final FrameDrawingCallback callback) { if (callback != null) { setFrameCallback(callback); } - syncAndDrawFrame(vsync); + createRenderRequest() + .setVsyncTime(vsync) + .syncAndDraw(); } } } diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index d2263ac1a2e..aefb3789f09 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -3481,21 +3481,25 @@ private void performDraw() { .captureFrameCommitCallbacks(); if (mReportNextDraw) { usingAsyncReport = true; - mAttachInfo.mThreadedRenderer.setFrameCompleteCallback((long frameNr) -> { - // TODO: Use the frame number - pendingDrawFinished(); - if (commitCallbacks != null) { - for (int i = 0; i < commitCallbacks.size(); i++) { - commitCallbacks.get(i).run(); - } - } - }); + final Handler handler = mAttachInfo.mHandler; + mAttachInfo.mThreadedRenderer.setFrameCompleteCallback((long frameNr) -> + handler.post(() -> { + // TODO: Use the frame number + pendingDrawFinished(); + if (commitCallbacks != null) { + for (int i = 0; i < commitCallbacks.size(); i++) { + commitCallbacks.get(i).run(); + } + } + })); } else if (commitCallbacks != null && commitCallbacks.size() > 0) { - mAttachInfo.mThreadedRenderer.setFrameCompleteCallback((long frameNr) -> { - for (int i = 0; i < commitCallbacks.size(); i++) { - commitCallbacks.get(i).run(); - } - }); + final Handler handler = mAttachInfo.mHandler; + mAttachInfo.mThreadedRenderer.setFrameCompleteCallback((long frameNr) -> + handler.post(() -> { + for (int i = 0; i < commitCallbacks.size(); i++) { + commitCallbacks.get(i).run(); + } + })); } } diff --git a/core/jni/android_view_ThreadedRenderer.cpp b/core/jni/android_view_ThreadedRenderer.cpp index dd9c9b04818..ecc2dd0d359 100644 --- a/core/jni/android_view_ThreadedRenderer.cpp +++ b/core/jni/android_view_ThreadedRenderer.cpp @@ -33,7 +33,6 @@ #include -#include #include #include #include @@ -144,52 +143,22 @@ class FinishAndInvokeListener : public MessageHandler { uint32_t mRequestId; }; -class RenderingException : public MessageHandler { +class FrameCompleteWrapper : public LightRefBase { public: - RenderingException(JavaVM* vm, const std::string& message) - : mVm(vm) - , mMessage(message) { - } - - virtual void handleMessage(const Message&) { - throwException(mVm, mMessage); - } - - static void throwException(JavaVM* vm, const std::string& message) { - JNIEnv* env = getenv(vm); - jniThrowException(env, "java/lang/IllegalStateException", message.c_str()); - } - -private: - JavaVM* mVm; - std::string mMessage; -}; - -class FrameCompleteWrapper : public MessageHandler { -public: - FrameCompleteWrapper(JNIEnv* env, jobject jobject) { - mLooper = Looper::getForThread(); - LOG_ALWAYS_FATAL_IF(!mLooper.get(), "Must create runnable on a Looper thread!"); + explicit FrameCompleteWrapper(JNIEnv* env, jobject jobject) { env->GetJavaVM(&mVm); mObject = env->NewGlobalRef(jobject); LOG_ALWAYS_FATAL_IF(!mObject, "Failed to make global ref"); } - virtual ~FrameCompleteWrapper() { + ~FrameCompleteWrapper() { releaseObject(); } - void postFrameComplete(int64_t frameNr) { - if (mObject) { - mFrameNr = frameNr; - mLooper->sendMessage(this, 0); - } - } - - virtual void handleMessage(const Message&) { + void onFrameComplete(int64_t frameNr) { if (mObject) { - ATRACE_FORMAT("frameComplete %" PRId64, mFrameNr); - getenv(mVm)->CallVoidMethod(mObject, gFrameCompleteCallback.onFrameComplete, mFrameNr); + ATRACE_FORMAT("frameComplete %" PRId64, frameNr); + getenv(mVm)->CallVoidMethod(mObject, gFrameCompleteCallback.onFrameComplete, frameNr); releaseObject(); } } @@ -197,8 +166,6 @@ class FrameCompleteWrapper : public MessageHandler { private: JavaVM* mVm; jobject mObject; - sp mLooper; - int64_t mFrameNr = -1; void releaseObject() { if (mObject) { @@ -211,16 +178,14 @@ class FrameCompleteWrapper : public MessageHandler { class RootRenderNode : public RenderNode, ErrorHandler { public: explicit RootRenderNode(JNIEnv* env) : RenderNode() { - mLooper = Looper::getForThread(); - LOG_ALWAYS_FATAL_IF(!mLooper.get(), - "Must create RootRenderNode on a thread with a looper!"); env->GetJavaVM(&mVm); } virtual ~RootRenderNode() {} virtual void onError(const std::string& message) override { - mLooper->sendMessage(new RenderingException(mVm, message), 0); + JNIEnv* env = getenv(mVm); + jniThrowException(env, "java/lang/IllegalStateException", message.c_str()); } virtual void prepareTree(TreeInfo& info) override { @@ -249,14 +214,6 @@ class RootRenderNode : public RenderNode, ErrorHandler { info.errorHandler = nullptr; } - void sendMessage(const sp& handler) { - mLooper->sendMessage(handler, 0); - } - - void sendMessageDelayed(const sp& handler, nsecs_t delayInMs) { - mLooper->sendMessageDelayed(ms2ns(delayInMs), handler, 0); - } - void attachAnimatingNode(RenderNode* animatingNode) { mPendingAnimatingRenderNodes.push_back(animatingNode); } @@ -404,7 +361,6 @@ class RootRenderNode : public RenderNode, ErrorHandler { } private: - sp mLooper; JavaVM* mVm; std::vector< sp > mPendingAnimatingRenderNodes; std::set< sp > mPendingVectorDrawableAnimators; @@ -435,7 +391,9 @@ class RootRenderNode : public RenderNode, ErrorHandler { // the onFinished callback will then be ignored. sp message = new FinishAndInvokeListener(anim); - sendMessageDelayed(message, remainingTimeInMs); + auto looper = Looper::getForThread(); + LOG_ALWAYS_FATAL_IF(looper == nullptr, "Not on a looper thread?"); + looper->sendMessageDelayed(ms2ns(remainingTimeInMs), message, 0); anim->clearOneShotListener(); } } @@ -463,7 +421,6 @@ class AnimationContextBridge : public AnimationContext { virtual void runRemainingAnimations(TreeInfo& info) { AnimationContext::runRemainingAnimations(info); mRootNode->runVectorDrawableAnimators(this, info); - postOnFinishedEvents(); } virtual void pauseAnimators() override { @@ -471,27 +428,16 @@ class AnimationContextBridge : public AnimationContext { } virtual void callOnFinished(BaseRenderNodeAnimator* animator, AnimationListener* listener) { - OnFinishedEvent event(animator, listener); - mOnFinishedEvents.push_back(event); + listener->onAnimationFinished(animator); } virtual void destroy() { AnimationContext::destroy(); mRootNode->detachAnimators(); - postOnFinishedEvents(); } private: sp mRootNode; - std::vector mOnFinishedEvents; - - void postOnFinishedEvents() { - if (mOnFinishedEvents.size()) { - sp message - = new InvokeAnimationListeners(mOnFinishedEvents); - mRootNode->sendMessage(message); - } - } }; class ContextFactoryImpl : public IContextFactory { @@ -958,7 +904,7 @@ static void android_view_ThreadedRenderer_setFrameCompleteCallback(JNIEnv* env, } else { sp wrapper = new FrameCompleteWrapper{env, callback}; proxy->setFrameCompleteCallback([wrapper](int64_t frameNr) { - wrapper->postFrameComplete(frameNr); + wrapper->onFrameComplete(frameNr); }); } } diff --git a/graphics/java/android/graphics/HardwareRenderer.java b/graphics/java/android/graphics/HardwareRenderer.java index abf8bc5e6cc..e6233548651 100644 --- a/graphics/java/android/graphics/HardwareRenderer.java +++ b/graphics/java/android/graphics/HardwareRenderer.java @@ -20,7 +20,6 @@ import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.TestApi; import android.app.Activity; import android.app.ActivityManager; import android.os.IBinder; @@ -28,13 +27,16 @@ import android.os.RemoteException; import android.os.ServiceManager; import android.util.Log; +import android.util.TimeUtils; import android.view.FrameMetricsObserver; import android.view.IGraphicsStats; import android.view.IGraphicsStatsCallback; import android.view.NativeVectorDrawableAnimator; +import android.view.PixelCopy; import android.view.Surface; import android.view.SurfaceHolder; import android.view.TextureLayer; +import android.view.animation.AnimationUtils; import com.android.internal.util.VirtualRefBasePtr; @@ -42,6 +44,7 @@ import java.io.FileDescriptor; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; +import java.util.concurrent.Executor; import sun.misc.Cleaner; @@ -50,13 +53,8 @@ * from {@link RenderNode}'s to an output {@link android.view.Surface}. There can be as many * HardwareRenderer instances as desired.

* - *

Threading

- *

HardwareRenderer is not thread safe. An instance of a HardwareRenderer must only be - * created & used from a single thread. It does not matter what thread is used, however - * it must have a {@link android.os.Looper}. Multiple instances do not have to share the same - * thread, although they can.

- * *

Resources & lifecycle

+ * *

All HardwareRenderer instances share a common render thread. The render thread contains * the GPU context & resources necessary to do GPU-accelerated rendering. As such, the first * HardwareRenderer created comes with the cost of also creating the associated GPU contexts, @@ -64,6 +62,7 @@ * is to have a HardwareRenderer instance for every active {@link Surface}. For example * when an Activity shows a Dialog the system internally will use 2 hardware renderers, both * of which may be drawing at the same time.

+ * *

NOTE: Due to the shared, cooperative nature of the render thread it is critical that * any {@link Surface} used must have a prompt, reliable consuming side. System-provided * consumers such as {@link android.view.SurfaceView}, @@ -73,8 +72,6 @@ * it is the app's responsibility to ensure that they consume updates promptly and rapidly. * Failure to do so will cause the render thread to stall on that surface, blocking all * HardwareRenderer instances.

- * - * @hide */ public class HardwareRenderer { private static final String LOG_TAG = "HardwareRenderer"; @@ -89,18 +86,18 @@ public class HardwareRenderer { * The renderer is requesting a redraw. This can occur if there's an animation that's running * in the RenderNode tree and the hardware renderer is unable to self-animate. * - * If this is returned from syncAndDrawFrame the expectation is that syncAndDrawFrame + *

If this is returned from syncAndDraw the expectation is that syncAndDraw * will be called again on the next vsync signal. */ public static final int SYNC_REDRAW_REQUESTED = 1 << 0; /** * The hardware renderer no longer has a valid {@link android.view.Surface} to render to. - * This can happen if {@link Surface#destroy()} was called. The user should no longer - * attempt to call syncAndDrawFrame until a new surface has been provided by calling + * This can happen if {@link Surface#release()} was called. The user should no longer + * attempt to call syncAndDraw until a new surface has been provided by calling * setSurface. * - * Spoiler: the reward is GPU-accelerated drawing, better find that Surface! + *

Spoiler: the reward is GPU-accelerated drawing, better find that Surface! */ public static final int SYNC_LOST_SURFACE_REWARD_IF_FOUND = 1 << 1; @@ -119,6 +116,7 @@ public class HardwareRenderer { */ public static final int SYNC_FRAME_DROPPED = 1 << 3; + /** @hide */ @IntDef(value = { SYNC_OK, SYNC_REDRAW_REQUESTED, SYNC_LOST_SURFACE_REWARD_IF_FOUND, SYNC_CONTEXT_IS_STOPPED, SYNC_FRAME_DROPPED}) @@ -153,7 +151,6 @@ public class HardwareRenderer { protected RenderNode mRootNode; private boolean mOpaque = true; private boolean mForceDark = false; - private FrameInfo mScratchInfo; private boolean mIsWideGamut = false; /** @@ -175,14 +172,14 @@ public HardwareRenderer() { * Destroys the rendering context of this HardwareRenderer. This destroys the resources * associated with this renderer and releases the currently set {@link Surface}. * - * The renderer may be restored from this state by setting a new {@link Surface}, setting + *

The renderer may be restored from this state by setting a new {@link Surface}, setting * new rendering content with {@link #setContentRoot(RenderNode)}, and resuming - * rendering with {@link #syncAndDrawFrame(long)}. + * rendering by issuing a new {@link FrameRenderRequest}. * - * It is suggested to call this in response to callbacks such as + *

It is suggested to call this in response to callbacks such as * {@link android.view.SurfaceHolder.Callback#surfaceDestroyed(SurfaceHolder)}. * - * Note that if there are any outstanding frame commit callbacks they may end up never being + *

Note that if there are any outstanding frame commit callbacks they may never being * invoked if the frame was deferred to a later vsync. */ public void destroy() { @@ -204,14 +201,14 @@ public void setName(String name) { * Sets the center of the light source. The light source point controls the directionality * and shape of shadows rendered by RenderNode Z & elevation. * - * The platform's recommendation is to set lightX to 'displayWidth / 2f - windowLeft', set + *

The platform's recommendation is to set lightX to 'displayWidth / 2f - windowLeft', set * lightY to 0 - windowTop, lightZ set to 600dp, and lightRadius to 800dp. * - * The light source should be setup both as part of initial configuration, and whenever + *

The light source should be setup both as part of initial configuration, and whenever * the window moves to ensure the light source stays anchored in display space instead * of in window space. * - * This must be set at least once along with {@link #setLightSourceAlpha(float, float)} + *

This must be set at least once along with {@link #setLightSourceAlpha(float, float)} * before shadows will work. * * @param lightX The X position of the light source @@ -233,10 +230,10 @@ public void setLightSourceGeometry(float lightX, float lightY, float lightZ, * Configures the ambient & spot shadow alphas. This is the alpha used when the shadow * has max alpha, and ramps down from the values provided to zero. * - * These values are typically provided by the current theme, see + *

These values are typically provided by the current theme, see * {@link android.R.attr#spotShadowAlpha} and {@link android.R.attr#ambientShadowAlpha}. * - * This must be set at least once along with + *

This must be set at least once along with * {@link #setLightSourceGeometry(float, float, float, float)} before shadows will work. * * @param ambientShadowAlpha The alpha for the ambient shadow. If unsure, a reasonable default @@ -254,8 +251,8 @@ public void setLightSourceAlpha(@FloatRange(from = 0.0f, to = 1.0f) float ambien /** * Sets the content root to render. It is not necessary to call this whenever the content * recording changes. Any mutations to the RenderNode content, or any of the RenderNode's - * contained within the content node, will be applied whenever {@link #syncAndDrawFrame(long)} - * is called. + * contained within the content node, will be applied whenever a new {@link FrameRenderRequest} + * is issued via {@link #createRenderRequest()} and {@link FrameRenderRequest#syncAndDraw()}. * * @param content The content to set as the root RenderNode. If null the content root is removed * and the renderer will draw nothing. @@ -295,53 +292,133 @@ public void setSurface(@Nullable Surface surface) { } /** - * Syncs the RenderNode tree to the render thread and requests a frame to be drawn. - * - * @hide + * Sets the parameters that can be used to control a render request for a + * {@link HardwareRenderer}. This is not thread-safe and must not be held on to for longer + * than a single frame request. */ - @SyncAndDrawResult - public int syncAndDrawFrame(@NonNull FrameInfo frameInfo) { - return nSyncAndDrawFrame(mNativeProxy, frameInfo.frameInfo, frameInfo.frameInfo.length); + public final class FrameRenderRequest { + private FrameInfo mFrameInfo = new FrameInfo(); + private boolean mWaitForPresent; + + private FrameRenderRequest() { } + + private void reset() { + mWaitForPresent = false; + // Default to the animation time which, if choreographer is in play, will default to the + // current vsync time. Otherwise it will be 'now'. + mRenderRequest.setVsyncTime( + AnimationUtils.currentAnimationTimeMillis() * TimeUtils.NANOS_PER_MS); + } + + /** @hide */ + public void setFrameInfo(FrameInfo info) { + System.arraycopy(info.frameInfo, 0, mFrameInfo.frameInfo, 0, info.frameInfo.length); + } + + /** + * Sets the vsync time that represents the start point of this frame. Typically this + * comes from {@link android.view.Choreographer.FrameCallback}. Other compatible time + * sources include {@link System#nanoTime()}, however if the result is being displayed + * on-screen then using {@link android.view.Choreographer} is strongly recommended to + * ensure smooth animations. + * + *

If the clock source is not from a CLOCK_MONOTONIC source then any animations driven + * directly by RenderThread will not be synchronized properly with the current frame. + * + * @param vsyncTime The vsync timestamp for this frame. The timestamp is in nanoseconds + * and should come from a CLOCK_MONOTONIC source. + * + * @return this instance + */ + public FrameRenderRequest setVsyncTime(long vsyncTime) { + mFrameInfo.setVsync(vsyncTime, vsyncTime); + mFrameInfo.addFlags(FrameInfo.FLAG_SURFACE_CANVAS); + return this; + } + + /** + * Adds a frame commit callback. This callback will be invoked when the current rendering + * content has been rendered into a frame and submitted to the swap chain. The frame may + * not currently be visible on the display when this is invoked, but it has been submitted. + * This callback is useful in combination with {@link PixelCopy} to capture the current + * rendered content of the UI reliably. + * + * @param executor The executor to run the callback on. It is strongly recommended that + * this executor post to a different thread, as the calling thread is + * highly sensitive to being blocked. + * @param frameCommitCallback The callback to invoke when the frame content has been drawn. + * Will be invoked on the given {@link Executor}. + * + * @return this instance + */ + public FrameRenderRequest setFrameCommitCallback(@NonNull Executor executor, + @NonNull Runnable frameCommitCallback) { + setFrameCompleteCallback(frameNr -> executor.execute(frameCommitCallback)); + return this; + } + + /** + * Sets whether or not {@link #syncAndDraw()} should block until the frame has been + * presented. If this is true and {@link #syncAndDraw()} does not return + * {@link #SYNC_FRAME_DROPPED} or an error then when {@link #syncAndDraw()} has returned + * the frame has been submitted to the {@link Surface}. The default and typically + * recommended value is false, as blocking for present will prevent pipelining from + * happening, reducing overall throughput. This is useful for situations such as + * {@link SurfaceHolder.Callback2#surfaceRedrawNeeded(SurfaceHolder)} where it is desired + * to block until a frame has been presented to ensure first-frame consistency with + * other Surfaces. + * + * @param shouldWait If true the next call to {@link #syncAndDraw()} will block until + * completion. + * @return this instance + */ + public FrameRenderRequest setWaitForPresent(boolean shouldWait) { + mWaitForPresent = shouldWait; + return this; + } + + /** + * Syncs the RenderNode tree to the render thread and requests a frame to be drawn. This + * {@link FrameRenderRequest} instance should no longer be used after calling this method. + * The system internally may reuse instances of {@link FrameRenderRequest} to reduce + * allocation churn. + * + * @return The result of the sync operation. See {@link SyncAndDrawResult}. + */ + @SyncAndDrawResult + public int syncAndDraw() { + int syncResult = syncAndDrawFrame(mFrameInfo); + if (mWaitForPresent && (syncResult & SYNC_FRAME_DROPPED) == 0) { + fence(); + } + return syncResult; + } } + private FrameRenderRequest mRenderRequest = new FrameRenderRequest(); + /** - * Syncs the RenderNode tree to the render thread and requests a frame to be drawn. + * Returns a {@link FrameRenderRequest} that can be used to render a new frame. This is used + * to synchronize the RenderNode content provided by {@link #setContentRoot(RenderNode)} with + * the RenderThread and then renders a single frame to the Surface set with + * {@link #setSurface(Surface)}. * - * @param vsyncTime The vsync timestamp for this frame. Typically this comes from - * {@link android.view.Choreographer.FrameCallback}. Must be set and be valid - * as the renderer uses this time internally to drive animations. - * @return The result of the sync operation. See {@link SyncAndDrawResult}. + * @return An instance of {@link FrameRenderRequest}. The instance may be reused for every + * frame, so the caller should not hold onto it for longer than a single render request. */ - @SyncAndDrawResult - public int syncAndDrawFrame(long vsyncTime) { - if (mScratchInfo == null) { - mScratchInfo = new FrameInfo(); - } - mScratchInfo.setVsync(vsyncTime, vsyncTime); - mScratchInfo.addFlags(FrameInfo.FLAG_SURFACE_CANVAS); - return syncAndDrawFrame(mScratchInfo); + public FrameRenderRequest createRenderRequest() { + mRenderRequest.reset(); + return mRenderRequest; } /** * Syncs the RenderNode tree to the render thread and requests a frame to be drawn. - * frameCommitCallback callback will be invoked when the current rendering content has been - * rendered into a frame and submitted to the swap chain. * - * @param vsyncTime The vsync timestamp for this frame. Typically this comes from - * {@link android.view.Choreographer.FrameCallback}. Must be set and - * be valid as the renderer uses this time internally to drive - * animations. - * @param frameCommitCallback The callback to invoke when the frame content has been drawn. - * Will be invoked on the current {@link android.os.Looper} thread. - * @return The result of the sync operation. See {@link SyncAndDrawResult}. + * @hide */ @SyncAndDrawResult - public int syncAndDrawFrame(long vsyncTime, - @Nullable Runnable frameCommitCallback) { - if (frameCommitCallback != null) { - setFrameCompleteCallback(frameNr -> frameCommitCallback.run()); - } - return syncAndDrawFrame(vsyncTime); + public int syncAndDrawFrame(@NonNull FrameInfo frameInfo) { + return nSyncAndDrawFrame(mNativeProxy, frameInfo.frameInfo, frameInfo.frameInfo.length); } /** @@ -349,10 +426,11 @@ public int syncAndDrawFrame(long vsyncTime, * is useful to temporarily suspend using the active Surface in order to do any Surface * mutations necessary. * - * Any subsequent draws will override the pause, resuming normal operation. + *

Any subsequent draws will override the pause, resuming normal operation. * * @return true if there was an outstanding render request, false otherwise. If this is true - * the caller should ensure that {@link #syncAndDrawFrame(long)} is called at the soonest + * the caller should ensure that {@link #createRenderRequest()} + * and {@link FrameRenderRequest#syncAndDraw()} is called at the soonest * possible time to resume normal operation. * * TODO Should this be exposed? ViewRootImpl needs it because it destroys the old @@ -367,14 +445,14 @@ public boolean pause() { /** * Hard stops rendering into the surface. If the renderer is stopped it will - * block any attempt to render. Calls to {@link #syncAndDrawFrame(long)} will still - * sync over the latest rendering content, however they will not render and instead + * block any attempt to render. Calls to {@link FrameRenderRequest#syncAndDraw()} will + * still sync over the latest rendering content, however they will not render and instead * {@link #SYNC_CONTEXT_IS_STOPPED} will be returned. * - * If false is passed then rendering will resume as normal. Any pending rendering requests + *

If false is passed then rendering will resume as normal. Any pending rendering requests * will produce a new frame at the next vsync signal. * - * This is useful in combination with lifecycle events such as {@link Activity#onStop()} + *

This is useful in combination with lifecycle events such as {@link Activity#onStop()} * and {@link Activity#onStart()}. * * @param stopped true to stop all rendering, false to resume @@ -384,24 +462,26 @@ public void setStopped(boolean stopped) { } /** - * Destroys all hardware rendering resources associated with the current rendering content. + * Destroys all the display lists associated with the current rendering content. * This includes releasing a reference to the current content root RenderNode. It will * therefore be necessary to call {@link #setContentRoot(RenderNode)} in order to resume - * rendering after calling this. + * rendering after calling this, along with re-recording the display lists for the + * RenderNode tree. * - * It is recommended, but not necessary, to use this in combination with lifecycle events + *

It is recommended, but not necessary, to use this in combination with lifecycle events * such as {@link Activity#onStop()} and {@link Activity#onStart()} or in response to * {@link android.content.ComponentCallbacks2#onTrimMemory(int)} signals such as * {@link android.content.ComponentCallbacks2#TRIM_MEMORY_UI_HIDDEN} * * See also {@link #setStopped(boolean)} */ - public void destroyHardwareResources() { + public void clearContent() { nDestroyHardwareResources(mNativeProxy); } /** * Whether or not the force-dark feature should be used for this renderer. + * @hide */ public boolean setForceDark(boolean enable) { if (mForceDark != enable) { @@ -415,20 +495,24 @@ public boolean setForceDark(boolean enable) { /** * Allocate buffers ahead of time to avoid allocation delays during rendering. * - * Typically a Surface will allocate buffers lazily. This is usually fine and reduces the + *

Typically a Surface will allocate buffers lazily. This is usually fine and reduces the * memory usage of Surfaces that render rarely or never hit triple buffering. However * for UI it can result in a slight bit of jank on first launch. This hint will * tell the HardwareRenderer that now is a good time to allocate the 3 buffers * necessary for typical rendering. * - * Must be called after a {@link Surface} has been set. + *

Must be called after a {@link Surface} has been set. + * + * TODO: Figure out if we even need/want this. Should HWUI just be doing this in response + * to setSurface anyway? Vulkan swapchain makes this murky, so delay making it public + * @hide */ public void allocateBuffers() { nAllocateBuffers(mNativeProxy); } /** - * Notifies the hardware renderer that a call to {@link #syncAndDrawFrame(long)} will + * Notifies the hardware renderer that a call to {@link FrameRenderRequest#syncAndDraw()} will * be coming soon. This is used to help schedule when RenderThread-driven animations will * happen as the renderer wants to avoid producing more than one frame per vsync signal. */ @@ -439,7 +523,7 @@ public void notifyFramePending() { /** * Change the HardwareRenderer's opacity. Will take effect on the next frame produced. * - * If the renderer is set to opaque it is the app's responsibility to ensure that the + *

If the renderer is set to opaque it is the app's responsibility to ensure that the * content renders to every pixel of the Surface, otherwise corruption may result. Note that * this includes ensuring that the first draw of any given pixel does not attempt to blend * against the destination. If this is false then the hardware renderer will clear to @@ -527,7 +611,7 @@ public void registerVectorDrawableAnimator(NativeVectorDrawableAnimator animator } /** - * Prevents any further drawing until {@link #syncAndDrawFrame(long)} is called. + * Prevents any further drawing until {@link FrameRenderRequest#syncAndDraw()} is called. * This is a signal that the contents of the RenderNode tree are no longer safe to play back. * In practice this usually means that there are Functor pointers in the * display list that are no longer valid. @@ -718,10 +802,8 @@ public interface FrameCompleteCallback { * Interface for listening to picture captures * @hide */ - @TestApi public interface PictureCapturedCallback { /** @hide */ - @TestApi void onPictureCaptured(Picture picture); } diff --git a/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java b/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java index 789e38c4e65..d7aee776752 100644 --- a/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java +++ b/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java @@ -43,6 +43,7 @@ import android.graphics.Rect; import android.graphics.RenderNode; import android.os.Build; +import android.os.Handler; import android.util.ArrayMap; import android.util.AttributeSet; import android.util.IntArray; @@ -1241,6 +1242,7 @@ public static class VectorDrawableAnimatorRT implements VectorDrawableAnimator, // If the duration of an animation is more than 300 frames, we cap the sample size to 300. private static final int MAX_SAMPLE_POINTS = 300; + private Handler mHandler; private AnimatorListener mListener = null; private final LongArray mStartDelays = new LongArray(); private PropertyValuesHolder.PropertyValues mTmpValues = @@ -1671,6 +1673,9 @@ private void startAnimation() { .mRootName); } mStarted = true; + if (mHandler == null) { + mHandler = new Handler(); + } nStart(mSetPtr, this, ++mLastListenerId); invalidateOwningView(); if (mListener != null) { @@ -1780,7 +1785,7 @@ private void onAnimationEnd(int listenerId) { // onFinished: should be called from native @UnsupportedAppUsage private static void callOnFinished(VectorDrawableAnimatorRT set, int id) { - set.onAnimationEnd(id); + set.mHandler.post(() -> set.onAnimationEnd(id)); } private void transferPendingActions(VectorDrawableAnimator animatorSet) { diff --git a/tests/HwAccelerationTest/AndroidManifest.xml b/tests/HwAccelerationTest/AndroidManifest.xml index 1a4ec94d77b..7b8c154dea1 100644 --- a/tests/HwAccelerationTest/AndroidManifest.xml +++ b/tests/HwAccelerationTest/AndroidManifest.xml @@ -1028,8 +1028,28 @@ + + + + + + + + + + + + + + diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/CustomRenderer.java b/tests/HwAccelerationTest/src/com/android/test/hwui/CustomRenderer.java new file mode 100644 index 00000000000..fece8babb40 --- /dev/null +++ b/tests/HwAccelerationTest/src/com/android/test/hwui/CustomRenderer.java @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.test.hwui; + +import android.app.Activity; +import android.graphics.Color; +import android.graphics.HardwareRenderer; +import android.graphics.Paint; +import android.graphics.RecordingCanvas; +import android.graphics.RenderNode; +import android.os.Bundle; +import android.util.Log; +import android.view.SurfaceHolder; + +public class CustomRenderer extends Activity { + private RenderNode mContent = new RenderNode("CustomRenderer"); + private HardwareRenderer mRenderer = new HardwareRenderer(); + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getWindow().takeSurface(mSurfaceCallbacks); + } + + private SurfaceHolder.Callback2 mSurfaceCallbacks = new SurfaceHolder.Callback2() { + + @Override + public void surfaceRedrawNeeded(SurfaceHolder holder) { + } + + @Override + public void surfaceCreated(SurfaceHolder holder) { + } + + @Override + public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { + mContent.setLeftTopRightBottom(0, 0, width, height); + RecordingCanvas canvas = mContent.beginRecording(); + canvas.drawColor(Color.WHITE); + Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG); + paint.setColor(Color.BLACK); + paint.setTextAlign(Paint.Align.CENTER); + paint.setTextSize(Math.min(width, height) * .05f); + canvas.drawText("Hello custom renderer!", width / 2, height / 2, paint); + mContent.endRecording(); + + mRenderer.setContentRoot(mContent); + mRenderer.setSurface(holder.getSurface()); + mRenderer.createRenderRequest() + .setVsyncTime(System.nanoTime()) + .setFrameCommitCallback(Runnable::run, () -> { + Log.d("CustomRenderer", "Frame committed!"); + }) + .syncAndDraw(); + } + + @Override + public void surfaceDestroyed(SurfaceHolder holder) { + mRenderer.destroy(); + } + }; +} diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/MyLittleTextureView.java b/tests/HwAccelerationTest/src/com/android/test/hwui/MyLittleTextureView.java new file mode 100644 index 00000000000..08d5d4fff50 --- /dev/null +++ b/tests/HwAccelerationTest/src/com/android/test/hwui/MyLittleTextureView.java @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.test.hwui; + +import android.app.Activity; +import android.graphics.Bitmap; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.ColorSpace; +import android.graphics.HardwareRenderer; +import android.graphics.Outline; +import android.graphics.PixelFormat; +import android.graphics.Rect; +import android.graphics.RenderNode; +import android.hardware.HardwareBuffer; +import android.media.Image; +import android.media.ImageReader; +import android.os.Bundle; +import android.widget.ImageView; + +public class MyLittleTextureView extends Activity { + private RenderNode mContent = new RenderNode("CustomRenderer"); + private HardwareRenderer mRenderer = new HardwareRenderer(); + private ImageView mImageView; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + mImageView = new ImageView(this); + mImageView.setScaleType(ImageView.ScaleType.FIT_CENTER); + setContentView(mImageView); + + ImageReader reader = ImageReader.newInstance(100, 100, PixelFormat.RGBA_8888, 3, + HardwareBuffer.USAGE_GPU_SAMPLED_IMAGE | HardwareBuffer.USAGE_GPU_COLOR_OUTPUT); + mRenderer.setSurface(reader.getSurface()); + mRenderer.setLightSourceAlpha(0.0f, 1.0f); + mRenderer.setLightSourceGeometry(100 / 2f, 0f, 800.0f, 20.0f); + mContent.setLeftTopRightBottom(0, 0, 100, 100); + + Rect childRect = new Rect(25, 25, 65, 65); + RenderNode childNode = new RenderNode("shadowCaster"); + childNode.setLeftTopRightBottom(childRect.left, childRect.top, + childRect.right, childRect.bottom); + Outline outline = new Outline(); + outline.setRect(new Rect(0, 0, childRect.width(), childRect.height())); + outline.setAlpha(1f); + childNode.setOutline(outline); + { + Canvas canvas = childNode.beginRecording(); + canvas.drawColor(Color.BLUE); + } + childNode.endRecording(); + childNode.setElevation(20f); + + { + Canvas canvas = mContent.beginRecording(); + canvas.drawColor(Color.WHITE); + canvas.enableZ(); + canvas.drawRenderNode(childNode); + canvas.disableZ(); + } + mContent.endRecording(); + mRenderer.setContentRoot(mContent); + mRenderer.createRenderRequest() + .setWaitForPresent(true) + .syncAndDraw(); + Image image = reader.acquireNextImage(); + Bitmap bitmap = Bitmap.wrapHardwareBuffer(image.getHardwareBuffer(), + ColorSpace.get(ColorSpace.Named.SRGB)); + mImageView.setImageBitmap(bitmap); + image.close(); + } +} From 238228814af094f0aa5ae4f4af1a68960006bd79 Mon Sep 17 00:00:00 2001 From: Vara Prasad A V S G Date: Wed, 17 Apr 2019 17:19:23 +0530 Subject: [PATCH 026/240] wm: Use a different execution context to register WFD rotation receiver In some stress test case, there was a deadlock scenario between the UI thread and the activity manager thread while registering the WFD rotation receiver. Delegate the registration to another thread yet ensure that the intents are received in the UI thread context. Change-Id: I90deae0af1b02fe3046573e7326cbe6063b6aa83 --- .../android/server/wm/DisplayRotation.java | 77 ++++++++++--------- 1 file changed, 40 insertions(+), 37 deletions(-) diff --git a/services/core/java/com/android/server/wm/DisplayRotation.java b/services/core/java/com/android/server/wm/DisplayRotation.java index 26d53576aa8..d65de92f044 100644 --- a/services/core/java/com/android/server/wm/DisplayRotation.java +++ b/services/core/java/com/android/server/wm/DisplayRotation.java @@ -193,44 +193,47 @@ public class DisplayRotation { mSettingsObserver = new SettingsObserver(uiHandler); mSettingsObserver.observe(); } - /* Register for WIFI Display Intents */ - IntentFilter wifiDisplayFilter = new IntentFilter(ACTION_WIFI_DISPLAY_VIDEO); - Intent wifidisplayIntent = context.registerReceiver( - mWifiDisplayReceiver, wifiDisplayFilter); - } - - final BroadcastReceiver mWifiDisplayReceiver = new BroadcastReceiver() { - public void onReceive(Context context, Intent intent) { - String action = intent.getAction(); - if (action.equals(ACTION_WIFI_DISPLAY_VIDEO)) { - int state = intent.getIntExtra("state", 0); - if(state == 1) { - mWifiDisplayConnected = true; - } else { - mWifiDisplayConnected = false; - } - int rotation = intent.getIntExtra("wfd_UIBC_rot", -1); - switch (rotation) { - case 0: - mWifiDisplayRotation = Surface.ROTATION_0; - break; - case 1: - mWifiDisplayRotation = Surface.ROTATION_90; - break; - case 2: - mWifiDisplayRotation = Surface.ROTATION_180; - break; - case 3: - mWifiDisplayRotation = Surface.ROTATION_270; - break; - default: - mWifiDisplayRotation = -1; - } - mService.updateRotation(true /* alwaysSendConfiguration */, - false/* forceRelayout */); + /* Register for WIFI Display Intents in a spearte thread + * to avoid possible deadlock between ActivityManager and + * WndowManager global locks*/ + Thread t = new Thread(){ + public void run() { + context.registerReceiver(new BroadcastReceiver(){ + public void onReceive(Context context, Intent intent) { + String action = intent.getAction(); + if (action.equals(ACTION_WIFI_DISPLAY_VIDEO)) { + int state = intent.getIntExtra("state", 0); + if(state == 1) { + mWifiDisplayConnected = true; + } else { + mWifiDisplayConnected = false; + } + int rotation = intent.getIntExtra("wfd_UIBC_rot", -1); + switch (rotation) { + case 0: + mWifiDisplayRotation = Surface.ROTATION_0; + break; + case 1: + mWifiDisplayRotation = Surface.ROTATION_90; + break; + case 2: + mWifiDisplayRotation = Surface.ROTATION_180; + break; + case 3: + mWifiDisplayRotation = Surface.ROTATION_270; + break; + default: + mWifiDisplayRotation = -1; + } + mService.updateRotation(true /* alwaysSendConfiguration */, + false/* forceRelayout */); + } + } + }, new IntentFilter(ACTION_WIFI_DISPLAY_VIDEO), null, UiThread.getHandler()); } - } - }; + }; + t.start(); + } private int readRotation(int resID) { try { From 4c50fb223a637fed59a9d4882680b6081cbaf1f8 Mon Sep 17 00:00:00 2001 From: Vara Prasad A V S G Date: Wed, 17 Apr 2019 17:18:22 +0530 Subject: [PATCH 027/240] Revert "display: Add support for multiple displays" This reverts commit 2125109939b05a03d7aa20fbd4864204f1d0aff5. CRs-Fixed: 2429504 Change-Id: I0a86af9fdd07202efc1f99b14687f27af921c503 --- core/java/android/view/SurfaceControl.java | 14 ---------- .../android/server/display/DisplayDevice.java | 17 ------------ .../server/display/DisplayManagerService.java | 12 +-------- .../server/display/LocalDisplayAdapter.java | 26 ++----------------- 4 files changed, 3 insertions(+), 66 deletions(-) diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java index 28f8bf344e0..39ac7589f0f 100644 --- a/core/java/android/view/SurfaceControl.java +++ b/core/java/android/view/SurfaceControl.java @@ -360,20 +360,6 @@ private static native boolean nativeSetDisplayBrightness(IBinder displayToken, */ public static final int BUILT_IN_DISPLAY_ID_HDMI = 1; - /** - * Built-in physical display id: Additional Built-in display id range. - * HDMI display ID range will be HDMI ID to EXT_MIN ID. - * Built-in display ID range will bee EXT_MIN ID to EXT_MAX ID. - * Use only with {@link SurfaceControl#getBuiltInDisplay(int)}. - * - * @hide - */ - public static final int BUILT_IN_DISPLAY_ID_EXT_MIN = 5; - /** - * @hide - */ - public static final int BUILT_IN_DISPLAY_ID_EXT_MAX = 7; - // Display power modes. /** * Display power mode off: used while blanking the screen. diff --git a/services/core/java/com/android/server/display/DisplayDevice.java b/services/core/java/com/android/server/display/DisplayDevice.java index 036bd920ce6..9882f6c0d4c 100644 --- a/services/core/java/com/android/server/display/DisplayDevice.java +++ b/services/core/java/com/android/server/display/DisplayDevice.java @@ -36,7 +36,6 @@ abstract class DisplayDevice { private final DisplayAdapter mDisplayAdapter; private final IBinder mDisplayToken; private final String mUniqueId; - private long mPhysicalId = -1; // The display device does not manage these properties itself, they are set by // the display manager service. The display device shouldn't really be looking at these. @@ -53,12 +52,6 @@ abstract class DisplayDevice { // Do not use for any other purpose. DisplayDeviceInfo mDebugLastLoggedDeviceInfo; - public DisplayDevice(DisplayAdapter displayAdapter, IBinder displayToken, String uniqueId, - long physicalId) { - this(displayAdapter, displayToken, uniqueId); - mPhysicalId = physicalId; - } - public DisplayDevice(DisplayAdapter displayAdapter, IBinder displayToken, String uniqueId) { mDisplayAdapter = displayAdapter; mDisplayToken = displayToken; @@ -93,15 +86,6 @@ public final String getNameLocked() { return getDisplayDeviceInfoLocked().name; } - /** - * Gets the physical id (vendor specified) of the display device. - * - * @return The display device id. - */ - public final long getPhysicalId() { - return mPhysicalId; - } - /** * Returns the unique id of the display device. */ @@ -267,7 +251,6 @@ public final void populateViewportLocked(DisplayViewport viewport) { public void dumpLocked(PrintWriter pw) { pw.println("mAdapter=" + mDisplayAdapter.getName()); pw.println("mUniqueId=" + mUniqueId); - pw.println("mPhysicalId=" + mPhysicalId); pw.println("mDisplayToken=" + mDisplayToken); pw.println("mCurrentLayerStack=" + mCurrentLayerStack); pw.println("mCurrentOrientation=" + mCurrentOrientation); diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java index 060bc18e163..3010324488b 100644 --- a/services/core/java/com/android/server/display/DisplayManagerService.java +++ b/services/core/java/com/android/server/display/DisplayManagerService.java @@ -213,7 +213,6 @@ public final class DisplayManagerService extends SystemService { private final SparseArray mLogicalDisplays = new SparseArray(); private int mNextNonDefaultDisplayId = Display.DEFAULT_DISPLAY + 1; - private int mNextBuiltInDisplayId = 4096; // List of all display transaction listeners. private final CopyOnWriteArrayList mDisplayTransactionListeners = @@ -990,7 +989,7 @@ private LogicalDisplay addLogicalDisplayLocked(DisplayDevice device) { return null; } - final int displayId = assignDisplayIdLocked(isDefault, device.getPhysicalId()); + final int displayId = assignDisplayIdLocked(isDefault); final int layerStack = assignLayerStackLocked(displayId); LogicalDisplay display = new LogicalDisplay(displayId, layerStack, device); @@ -1023,15 +1022,6 @@ private int assignDisplayIdLocked(boolean isDefault) { return isDefault ? Display.DEFAULT_DISPLAY : mNextNonDefaultDisplayId++; } - private int assignDisplayIdLocked(boolean isDefault, long physicalId) { - if (physicalId >= SurfaceControl.BUILT_IN_DISPLAY_ID_EXT_MIN && - physicalId <= SurfaceControl.BUILT_IN_DISPLAY_ID_EXT_MAX) { - return mNextBuiltInDisplayId++; - } - - return assignDisplayIdLocked(isDefault); - } - private int assignLayerStackLocked(int displayId) { // Currently layer stacks and display ids are the same. // This need not be the case. diff --git a/services/core/java/com/android/server/display/LocalDisplayAdapter.java b/services/core/java/com/android/server/display/LocalDisplayAdapter.java index 67ccd8837ed..5e5ef26f662 100644 --- a/services/core/java/com/android/server/display/LocalDisplayAdapter.java +++ b/services/core/java/com/android/server/display/LocalDisplayAdapter.java @@ -188,8 +188,7 @@ private final class LocalDisplayDevice extends DisplayDevice { SurfaceControl.PhysicalDisplayInfo[] physicalDisplayInfos, int activeDisplayInfo, int[] allowedDisplayInfos, int[] colorModes, int activeColorMode, boolean isInternal) { - super(LocalDisplayAdapter.this, displayToken, UNIQUE_ID_PREFIX + physicalDisplayId, - physicalDisplayId); + super(LocalDisplayAdapter.this, displayToken, UNIQUE_ID_PREFIX + physicalDisplayId); mPhysicalDisplayId = physicalDisplayId; mIsInternal = isInternal; updatePhysicalDisplayInfoLocked(physicalDisplayInfos, activeDisplayInfo, @@ -437,8 +436,7 @@ public DisplayDeviceInfo getDisplayDeviceInfoLocked() { mInfo.xDpi = phys.xDpi; mInfo.yDpi = phys.yDpi; mInfo.touch = DisplayDeviceInfo.TOUCH_INTERNAL; - } else if (mPhysicalDisplayId >= SurfaceControl.BUILT_IN_DISPLAY_ID_HDMI && - mPhysicalDisplayId < SurfaceControl.BUILT_IN_DISPLAY_ID_EXT_MIN) { + } else { mInfo.displayCutout = null; mInfo.type = Display.TYPE_HDMI; mInfo.flags |= DisplayDeviceInfo.FLAG_PRESENTATION; @@ -467,26 +465,6 @@ public DisplayDeviceInfo getDisplayDeviceInfoLocked() { if (res.getBoolean(com.android.internal.R.bool.config_localDisplaysPrivate)) { mInfo.flags |= DisplayDeviceInfo.FLAG_PRIVATE; } - } else { - mInfo.type = Display.TYPE_BUILT_IN; - mInfo.touch = DisplayDeviceInfo.TOUCH_INTERNAL; - mInfo.name = getContext().getResources().getString( - com.android.internal.R.string.display_manager_built_in_display_name); - mInfo.flags |= DisplayDeviceInfo.FLAG_ROTATES_WITH_CONTENT; - - if (SystemProperties.getBoolean( - "vendor.display.builtin_presentation", false)) { - mInfo.flags |= DisplayDeviceInfo.FLAG_PRESENTATION; - } else { - mInfo.flags |= DisplayDeviceInfo.FLAG_PRIVATE; - } - - if (!SystemProperties.getBoolean( - "vendor.display.builtin_mirroring", false)) { - mInfo.flags |= DisplayDeviceInfo.FLAG_OWN_CONTENT_ONLY; - } - - mInfo.setAssumedDensityForExternalDisplay(phys.width, phys.height); } } return mInfo; From 39b583af67db99cdb2dc4864b54d8a0ed3f320d4 Mon Sep 17 00:00:00 2001 From: Vara Prasad A V S G Date: Wed, 17 Apr 2019 17:15:45 +0530 Subject: [PATCH 028/240] idmap2: ignore idmap create failures in scan. In onder to generate the idmap for QC overlays, ignore the first idmap create failure for issue GMS RRO. As a temprary solution, will be reverted once perfect fix available. CRs-Fixed: 2432898 Change-Id: I4aa43ee2c6ab4cd5b2be0ccaf27fb176cede57ad --- cmds/idmap2/idmap2/Scan.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cmds/idmap2/idmap2/Scan.cpp b/cmds/idmap2/idmap2/Scan.cpp index 55b1003c38a..bcc12bcc38c 100644 --- a/cmds/idmap2/idmap2/Scan.cpp +++ b/cmds/idmap2/idmap2/Scan.cpp @@ -211,7 +211,8 @@ Result Scan(const std::vector& args) { const auto create_ok = Create(create_args); if (!create_ok) { - return Error(create_ok.GetError(), "failed to create idmap"); + continue; + //return Error(create_ok.GetError(), "failed to create idmap"); } } From 7c3c2a5a78fe4b16bb8a75a64b3ed35093232e21 Mon Sep 17 00:00:00 2001 From: Vara Prasad A V S G Date: Wed, 17 Apr 2019 16:52:05 +0530 Subject: [PATCH 029/240] audio: Add support for audio extended codecs - Add support for APTX adaptive and CELT formats Change-Id: I735a297acc4d3d4c7f8d2cc9302a13ebcf4e4c3d CRs-Fixed: 2433041 --- media/java/android/media/AudioSystem.java | 5 +++++ services/core/java/com/android/server/audio/BtHelper.java | 4 ++++ 2 files changed, 9 insertions(+) diff --git a/media/java/android/media/AudioSystem.java b/media/java/android/media/AudioSystem.java index d105fa3d458..64069091ff0 100644 --- a/media/java/android/media/AudioSystem.java +++ b/media/java/android/media/AudioSystem.java @@ -152,6 +152,8 @@ public static String modeToString(int mode) { public static final int AUDIO_FORMAT_APTX = 0x20000000; public static final int AUDIO_FORMAT_APTX_HD = 0x21000000; public static final int AUDIO_FORMAT_LDAC = 0x23000000; + public static final int AUDIO_FORMAT_CELT = 0x26000000; + public static final int AUDIO_FORMAT_APTX_ADAPTIVE = 0x27000000; /** * Convert audio format enum values to Bluetooth codec values @@ -163,6 +165,9 @@ public static int audioFormatToBluetoothSourceCodec(int audioFormat) { case AUDIO_FORMAT_APTX: return BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX; case AUDIO_FORMAT_APTX_HD: return BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX_HD; case AUDIO_FORMAT_LDAC: return BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC; + case AUDIO_FORMAT_CELT: return BluetoothCodecConfig.SOURCE_CODEC_TYPE_CELT; + case AUDIO_FORMAT_APTX_ADAPTIVE: + return BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX_ADAPTIVE; default: return BluetoothCodecConfig.SOURCE_CODEC_TYPE_INVALID; } } diff --git a/services/core/java/com/android/server/audio/BtHelper.java b/services/core/java/com/android/server/audio/BtHelper.java index 388b5ee7316..b0f443f5191 100644 --- a/services/core/java/com/android/server/audio/BtHelper.java +++ b/services/core/java/com/android/server/audio/BtHelper.java @@ -1166,6 +1166,10 @@ private int mapBluetoothCodecToAudioFormat(int btCodecType) { return AudioSystem.AUDIO_FORMAT_APTX_HD; case BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC: return AudioSystem.AUDIO_FORMAT_LDAC; + case BluetoothCodecConfig.SOURCE_CODEC_TYPE_CELT: + return AudioSystem.AUDIO_FORMAT_CELT; + case BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX_ADAPTIVE: + return AudioSystem.AUDIO_FORMAT_APTX_ADAPTIVE; default: return AudioSystem.AUDIO_FORMAT_DEFAULT; } From 772d9d665f40e3a7c031ab5b20ea6493d514056e Mon Sep 17 00:00:00 2001 From: chaviw Date: Wed, 29 May 2019 14:57:50 -0700 Subject: [PATCH 030/240] Only updateBoundsSurface when surface size has changed. Currently, updateBoundsSurface was getting called when the surface changed, not just when the size changed. This meant it could be calling setWindowCrop and deferTransaction when no size had changed. If size hadn't changed, there was a high possibility that no new frames would be submitted by the client, causing the deferTransaction to wait forever. Since the deferTransaction was still waiting, SurfaceFlinger would wake up every vsync to check if it should call doTransaction for the deferred transaction. This caused 60Hz composition even when frames were rendered slower. Fixes: 132110524 Test: SF doesn't compose 30fps app at 60Hz Change-Id: Icf3a99b34c288575438bfcd05e9077ea7919b4ca (cherry picked from commit c0a8c4edbd63e5aad4650754306dfd95e40b5816) --- core/java/android/view/ViewRootImpl.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index d6588142770..a0b28618972 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -2219,6 +2219,8 @@ private void performTraversals() { final boolean isViewVisible = viewVisibility == View.VISIBLE; final boolean windowRelayoutWasForced = mForceNextWindowRelayout; + boolean surfaceSizeChanged = false; + if (mFirst || windowShouldResize || insetsChanged || viewVisibilityChanged || params != null || mForceNextWindowRelayout) { mForceNextWindowRelayout = false; @@ -2297,7 +2299,7 @@ private void performTraversals() { final boolean cutoutChanged = !mPendingDisplayCutout.equals( mAttachInfo.mDisplayCutout); final boolean outsetsChanged = !mPendingOutsets.equals(mAttachInfo.mOutsets); - final boolean surfaceSizeChanged = (relayoutResult + surfaceSizeChanged = (relayoutResult & WindowManagerGlobal.RELAYOUT_RES_SURFACE_RESIZED) != 0; surfaceChanged |= surfaceSizeChanged; final boolean alwaysConsumeSystemBarsChanged = @@ -2580,7 +2582,7 @@ private void performTraversals() { maybeHandleWindowMove(frame); } - if (surfaceChanged) { + if (surfaceSizeChanged) { updateBoundsSurface(); } From 64d3302861485200fe6c6d5cb31591dbc4c64692 Mon Sep 17 00:00:00 2001 From: Qimeng Pan Date: Fri, 5 Jul 2019 15:04:27 +0800 Subject: [PATCH 031/240] SystemUI: disable Lock Icon animation. Disable Lock Icon animation, since it will run infinitely which cause power issue. Will revert this change when animation issue fixed. Change-Id: Icae3c406e58e9777018e91f33169be5e7ca6657a CRs-Fixed: 2470003 --- .../src/com/android/systemui/statusbar/phone/LockIcon.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) mode change 100644 => 100755 packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java old mode 100644 new mode 100755 index 3d0c9e88ac9..f246507490a --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java @@ -232,7 +232,7 @@ public void update(boolean force) { || mLastBouncerVisible != mBouncerVisible || force) { int iconAnimRes = getAnimationResForTransition(mLastState, state, mLastPulsing, mPulsing, mLastDozing, mDozing, mBouncerVisible); - boolean isAnim = iconAnimRes != -1; + boolean isAnim = false; // iconAnimRes != -1; int iconRes = isAnim ? iconAnimRes : getIconForState(state); if (iconRes != mIconRes) { From 4b301566fd9db499206977f74e2ed5a44beac806 Mon Sep 17 00:00:00 2001 From: Weijie Wang Date: Thu, 11 Jul 2019 15:29:12 +0800 Subject: [PATCH 032/240] Fix dequence buffer timeout issue On Android Q, if dequene buffer operation takes over 500ms, it will fail the dequence operation and release the surface, which causes CTS test failing. The 500ms is too short, Change 500ms to 1000ms. The failing CTS test case: android.server.wm.KeyguardLockedTests#testDismissKeyguard android.server.wm.KeyguardLockedTests#testDismissKeyguardActivity_method android.server.wm.MultiDisplayLockedKeyguardTests#testDismissKeyguard_secondaryDisplay CRs-Fixed: 2459355 Change-Id: I62dd54c4f01f6bf303202bc4ad1eb1feaff9ff66 --- libs/hwui/renderthread/CanvasContext.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp index f326ce8d23e..8980498ef24 100644 --- a/libs/hwui/renderthread/CanvasContext.cpp +++ b/libs/hwui/renderthread/CanvasContext.cpp @@ -148,7 +148,7 @@ void CanvasContext::setSurface(sp&& surface) { if (surface) { mNativeSurface = new ReliableSurface{std::move(surface)}; - mNativeSurface->setDequeueTimeout(500_ms); + mNativeSurface->setDequeueTimeout(1000_ms); } else { mNativeSurface = nullptr; } From 1c42b9f1453ab5bd20dadac2f26814ce3439f2d6 Mon Sep 17 00:00:00 2001 From: Karthik Gopalan Date: Tue, 9 Jul 2019 15:41:51 +0530 Subject: [PATCH 033/240] perf: Remove Scroll Boosts and use GestureflingBoost Make use of GestureFling boost by enabling if needed and remove scroll boosts. CRs-Fixed: 2486520 Change-Id: I6d6228266d5fbac8d483be409e87fb0c8e672c66 --- core/java/android/view/ViewRootImpl.java | 27 +++------------ core/java/android/widget/OverScroller.java | 38 ---------------------- 2 files changed, 4 insertions(+), 61 deletions(-) diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index 55b94fa5382..101ed1e737d 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -86,7 +86,6 @@ import android.util.SparseArray; import android.util.TimeUtils; import android.util.TypedValue; -import android.util.BoostFramework; import android.view.Surface.OutOfResourcesException; import android.view.SurfaceControl.Transaction; import android.view.View.AttachInfo; @@ -215,8 +214,6 @@ public final class ViewRootImpl implements ViewParent, public static final String PROPERTY_EMULATOR_WIN_OUTSET_BOTTOM_PX = "ro.emu.win_outset_bottom_px"; - private boolean SCROLL_BOOST_SS_ENABLE = false; - /** * Maximum time we allow the user to roll the trackball enough to generate * a key event, before resetting the counters. @@ -590,8 +587,6 @@ static final class SystemUiVisibilityInfo { private String mTag = TAG; boolean mHaveMoveEvent = false; - boolean mIsPerfLockAcquired = false; - BoostFramework mPerf = null; public ViewRootImpl(Context context, Display display) { mContext = context; @@ -655,10 +650,6 @@ public ViewRootImpl(Context context, Display display) { } loadSystemProperties(); - mPerf = new BoostFramework(context); - - if (mPerf != null) - SCROLL_BOOST_SS_ENABLE = Boolean.parseBoolean(mPerf.perfGetProp("vendor.perf.gestureflingboost.enable", "false")); } public static void addFirstDrawHandler(Runnable callback) { @@ -3503,13 +3494,6 @@ private boolean draw(boolean fullRedrawNeeded) { scrollToRectOrFocus(null, false); if (mAttachInfo.mViewScrollChanged) { - if (!SCROLL_BOOST_SS_ENABLE && mHaveMoveEvent && !mIsPerfLockAcquired) { - mIsPerfLockAcquired = true; - if (mPerf != null) { - String currentPackage = mContext.getPackageName(); - mPerf.perfHint(BoostFramework.VENDOR_HINT_SCROLL_BOOST, currentPackage, -1, BoostFramework.Scroll.PREFILING); - } - } mAttachInfo.mViewScrollChanged = false; mAttachInfo.mTreeObserver.dispatchOnScrollChanged(); } @@ -5498,13 +5482,10 @@ private int processPointerEvent(QueuedInputEvent q) { mAttachInfo.mHandlingPointerEvent = true; boolean handled = mView.dispatchPointerEvent(event); int action = event.getActionMasked(); - if (!SCROLL_BOOST_SS_ENABLE) { - if (action == MotionEvent.ACTION_MOVE) { - mHaveMoveEvent = true; - } else if (action == MotionEvent.ACTION_UP) { - mHaveMoveEvent = false; - mIsPerfLockAcquired = false; - } + if (action == MotionEvent.ACTION_MOVE) { + mHaveMoveEvent = true; + } else if (action == MotionEvent.ACTION_UP) { + mHaveMoveEvent = false; } maybeUpdatePointerIcon(event); maybeUpdateTooltip(event); diff --git a/core/java/android/widget/OverScroller.java b/core/java/android/widget/OverScroller.java index b9778259db5..46b1c59a8dc 100644 --- a/core/java/android/widget/OverScroller.java +++ b/core/java/android/widget/OverScroller.java @@ -23,7 +23,6 @@ import android.view.ViewConfiguration; import android.view.animation.AnimationUtils; import android.view.animation.Interpolator; -import android.util.BoostFramework; import android.os.SystemProperties; /** @@ -47,9 +46,6 @@ public class OverScroller { private static final int SCROLL_MODE = 0; private static final int FLING_MODE = 1; - static boolean SCROLL_BOOST_SS_ENABLE = false; - BoostFramework mGetProp = null; - /** * Creates an OverScroller with a viscous fluid scroll interpolator and flywheel. * @param context @@ -86,11 +82,6 @@ public OverScroller(Context context, Interpolator interpolator, boolean flywheel mFlywheel = flywheel; mScrollerX = new SplineOverScroller(context); mScrollerY = new SplineOverScroller(context); - - mGetProp = new BoostFramework(); - - if (mGetProp != null) - SCROLL_BOOST_SS_ENABLE = Boolean.parseBoolean(mGetProp.perfGetProp("vendor.perf.gestureflingboost.enable", "false")); } /** @@ -620,14 +611,6 @@ static class SplineOverScroller { private static final int CUBIC = 1; private static final int BALLISTIC = 2; - /* - * Perf boost related variables - * Enabled/Disabled using config_enableCpuBoostForOverScrollerFling - * true value turns it on, by default will be turned off - */ - private BoostFramework mPerf = null; - private boolean mIsPerfLockAcquired = false; - static { float x_min = 0.0f; float y_min = 0.0f; @@ -673,10 +656,6 @@ void setFriction(float friction) { * 39.37f // inch/meter * ppi * 0.84f; // look and feel tuning - - if (!SCROLL_BOOST_SS_ENABLE && mPerf == null) { - mPerf = new BoostFramework(context); - } } void updateScroll(float q) { @@ -724,11 +703,6 @@ void startScroll(int start, int distance, int duration) { } void finish() { - if (!SCROLL_BOOST_SS_ENABLE && mIsPerfLockAcquired && mPerf != null) { - mPerf.perfLockRelease(); - mIsPerfLockAcquired = false; - } - mCurrentPosition = mFinal; // Not reset since WebView relies on this value for fast fling. // TODO: restore when WebView uses the fast fling implemented in this class. @@ -788,11 +762,6 @@ void fling(int start, int velocity, int min, int max, int over) { mStartTime = AnimationUtils.currentAnimationTimeMillis(); mCurrentPosition = mStart = start; - if (!SCROLL_BOOST_SS_ENABLE && mIsPerfLockAcquired && mPerf != null) { - mPerf.perfLockRelease(); - mIsPerfLockAcquired = false; - } - if (start > max || start < min) { startAfterEdge(start, min, max, velocity); return; @@ -957,13 +926,6 @@ boolean update() { return false; } - if (!SCROLL_BOOST_SS_ENABLE && mPerf != null && !mIsPerfLockAcquired) { - String currentPackage = mContext.getPackageName(); - - mIsPerfLockAcquired = true; - mPerf.perfHint(BoostFramework.VENDOR_HINT_SCROLL_BOOST, currentPackage, mDuration, BoostFramework.Scroll.VERTICAL); - } - double distance = 0.0; switch (mState) { case SPLINE: { From 6c3d2ee4dce7da5fa3eadb63d35114a33055f00e Mon Sep 17 00:00:00 2001 From: Weijie Wang Date: Mon, 22 Jul 2019 19:36:13 +0800 Subject: [PATCH 034/240] SystemUI: Update the media notification only when needed The media notification is updated every second even if the screen is turned off, which causes unnecessary power consumption. So update the media notification only when needed Change-Id: I4d5bcc56fe804754eebec92d83397dac354ec012 CRs-Fixed: 2493218 --- .../NotificationMediaTemplateViewWrapper.java | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationMediaTemplateViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationMediaTemplateViewWrapper.java index 20e8b733ce6..efa91972313 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationMediaTemplateViewWrapper.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationMediaTemplateViewWrapper.java @@ -32,6 +32,7 @@ import android.view.LayoutInflater; import android.view.View; import android.view.ViewStub; +import android.view.ViewTreeObserver; import android.widget.SeekBar; import android.widget.TextView; @@ -208,13 +209,18 @@ private void resolveViews() { private void startTimer() { clearTimer(); - mSeekBarTimer = new Timer(true /* isDaemon */); - mSeekBarTimer.schedule(new TimerTask() { + updateSeekBarView(); + } + + private void updateSeekBarView() { + mSeekBarView.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener(){ @Override - public void run() { - mHandler.post(mOnUpdateTimerTick); + public boolean onPreDraw(){ + mSeekBarView.getViewTreeObserver().removeOnPreDrawListener(this); + mHandler.postDelayed(mOnUpdateTimerTick,PROGRESS_UPDATE_INTERVAL); + return true; } - }, 0, PROGRESS_UPDATE_INTERVAL); + }); } private void clearTimer() { @@ -261,7 +267,7 @@ private void updateDuration() { public void run() { if (mMediaController != null && mSeekBar != null) { PlaybackState playbackState = mMediaController.getPlaybackState(); - + updateSeekBarView(); if (playbackState != null) { updatePlaybackUi(playbackState); } else { From 0d54288fd63aa34297fc76929b4164fc65002d63 Mon Sep 17 00:00:00 2001 From: Piyush Balwani Date: Wed, 24 Jul 2019 18:43:24 +0530 Subject: [PATCH 035/240] SystemUI: abnormal is observed after entering PIN1. SystemUI abnormal is observed after entering PIN1. Caused by wrong subid that be assigned when the SIM card status is ABSENT. Change-Id: I0c03a620fccfb58358f599cf8eac94e587cebfa4 CRs-Fixed: 2487131 --- .../SystemUI/src/com/android/keyguard/KeyguardSimPinView.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) mode change 100644 => 100755 packages/SystemUI/src/com/android/keyguard/KeyguardSimPinView.java diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinView.java old mode 100644 new mode 100755 index b65c87ffc19..d45f521ba65 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinView.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinView.java @@ -77,8 +77,7 @@ public void onSimStateChanged(int subId, int slotId, State simState) { if (mCallback != null) { mCallback.dismiss(true, KeyguardUpdateMonitor.getCurrentUser()); } - mSubId = subId; - break; + break; } case READY: { mRemainingAttempts = -1; From b1d671fcfd2b6863ba08ba87d9ae621354723ef6 Mon Sep 17 00:00:00 2001 From: richagar Date: Tue, 23 Jul 2019 12:06:12 +0530 Subject: [PATCH 036/240] Reverted I5b2a2fabe6f6ecdfc7139ee6b91421c090ea86d6 Added revert change to remove start support for Activity Trigger CRs-Fixed: 2494979 Change-Id: I5c8ed745dd9a9a8a6daaec1446c73b37c4892e9d --- core/java/com/android/internal/app/ActivityTrigger.java | 9 ++++++--- .../com/android/server/am/ActivityManagerService.java | 2 -- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/core/java/com/android/internal/app/ActivityTrigger.java b/core/java/com/android/internal/app/ActivityTrigger.java index 6e03d952ef7..61d030a4252 100644 --- a/core/java/com/android/internal/app/ActivityTrigger.java +++ b/core/java/com/android/internal/app/ActivityTrigger.java @@ -50,11 +50,14 @@ protected void finalize() { } /** @hide */ - public void activityStartTrigger(ApplicationInfo appInfo, int pid) { + public void activityStartTrigger(Intent intent, ActivityInfo acInfo, + ApplicationInfo appInfo, boolean IsInFullScreen) { int reserved =0; + ComponentName cn = intent.getComponent(); String activity = null; - activity = appInfo.packageName + "/" + appInfo.processName + "/" + - appInfo.longVersionCode + "/" + pid; + + if(cn != null) + activity = cn.flattenToString() + "/" + appInfo.versionCode; native_at_startActivity(activity, reserved); } diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 3c0d2603441..17ae411d400 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -5237,8 +5237,6 @@ app.compat, getCommonServicesLocked(app.isolated), app.hostingRecord.getType(), (app.hostingRecord.getName() != null ? app.hostingRecord.getName() : "")); - //send start notification to AT with the starting app's info. - mActivityTrigger.activityStartTrigger(app.info, app.pid); return true; } From 4c286d52b21320faa09ef9771b7596292fce2d1a Mon Sep 17 00:00:00 2001 From: Piyush Balwani Date: Wed, 21 Aug 2019 14:31:53 +0530 Subject: [PATCH 037/240] Revert "Reverted I5b2a2fabe6f6ecdfc7139ee6b91421c090ea86d6" This reverts commit b1d671fcfd2b6863ba08ba87d9ae621354723ef6. Change-Id: Ic3cb4f72447c5002174f4ed0a6a2f1b4471e4901 --- core/java/com/android/internal/app/ActivityTrigger.java | 9 +++------ .../com/android/server/am/ActivityManagerService.java | 2 ++ 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/core/java/com/android/internal/app/ActivityTrigger.java b/core/java/com/android/internal/app/ActivityTrigger.java index 61d030a4252..6e03d952ef7 100644 --- a/core/java/com/android/internal/app/ActivityTrigger.java +++ b/core/java/com/android/internal/app/ActivityTrigger.java @@ -50,14 +50,11 @@ protected void finalize() { } /** @hide */ - public void activityStartTrigger(Intent intent, ActivityInfo acInfo, - ApplicationInfo appInfo, boolean IsInFullScreen) { + public void activityStartTrigger(ApplicationInfo appInfo, int pid) { int reserved =0; - ComponentName cn = intent.getComponent(); String activity = null; - - if(cn != null) - activity = cn.flattenToString() + "/" + appInfo.versionCode; + activity = appInfo.packageName + "/" + appInfo.processName + "/" + + appInfo.longVersionCode + "/" + pid; native_at_startActivity(activity, reserved); } diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 17ae411d400..3c0d2603441 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -5237,6 +5237,8 @@ app.compat, getCommonServicesLocked(app.isolated), app.hostingRecord.getType(), (app.hostingRecord.getName() != null ? app.hostingRecord.getName() : "")); + //send start notification to AT with the starting app's info. + mActivityTrigger.activityStartTrigger(app.info, app.pid); return true; } From 6dc952ebfd05428af920aee23d7af206588c10ab Mon Sep 17 00:00:00 2001 From: Sai Manobhiram Date: Wed, 4 Sep 2019 14:59:47 +0530 Subject: [PATCH 038/240] NPE: check if hostingRecord Type is valid before comparing. CRs-Fixed: 2510886 Change-Id: I84b2b7551b492ec403adcda756a576f0866c41f8 --- services/core/java/com/android/server/am/ProcessList.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java index 884e34f9aea..ab53b97832f 100644 --- a/services/core/java/com/android/server/am/ProcessList.java +++ b/services/core/java/com/android/server/am/ProcessList.java @@ -1832,7 +1832,7 @@ private Process.ProcessStartResult startProcess(HostingRecord hostingRecord, Str new String[] {PROC_START_SEQ_IDENT + app.startSeq}); } if (mPerfServiceStartHint != null) { - if (hostingRecord.getType().equals("activity")) { + if ((hostingRecord.getType() != null) && (hostingRecord.getType().equals("activity"))) { if (startResult != null) { mPerfServiceStartHint.perfHint(BoostFramework.VENDOR_HINT_FIRST_LAUNCH_BOOST, app.processName, startResult.pid, BoostFramework.Launch.TYPE_START_PROC); } From 855e766c9b67cee7918db5354bf96fd82991f658 Mon Sep 17 00:00:00 2001 From: "Philip P. Moltmann" Date: Fri, 13 Sep 2019 15:12:34 -0700 Subject: [PATCH 039/240] [DO NOT MERGE] Split access-media-storage from read-external-storage And also pre-grant it to all apps that currently get any storage permission pre-granted. Test: atest SplitPermissionTest m -j gts && gts-tradefed run commandAndExit gts-dev -m GtsPermissionTestCases --test=com.google.android.permission.gts.DefaultPermissionGrantPolicyTest#testDefaultGrantsWithRemoteExceptions Manual testing: All combinations of - App targetSdk = 28 and 29 (and 22 for extra credit) - App having the tag for ACCESS_MEDIA_LOCATION or not - Upgrade from P->Q-QPR and from vanilla Q->Q-QPR Further upgrade of targetSdk from 28->29 while on Q-QPR ==> All permission behavior should make sense. Sometimes there are weird, but expected behaviors. Hence we need to collect the results and then look at the unexpected ones. See SplitPermissionTest for some tests I added for the location-background permission which was split from the fine/coarse-location permissions Fixes: 141048840,140961754 (cherry picked from commit ac7b10c135bb148edcad1aad8e19c733d333f769) Change-Id: I6bfee8fe8347a73463c6c13a9ecfdf70308fd3df --- core/java/android/app/AppOpsManager.java | 17 ++++++++++++++++- data/etc/platform.xml | 4 ++++ .../DefaultPermissionGrantPolicy.java | 1 + 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java index fb72e651ceb..f3e4892afdf 100644 --- a/core/java/android/app/AppOpsManager.java +++ b/core/java/android/app/AppOpsManager.java @@ -834,9 +834,12 @@ public static String flagsToString(@OpFlags int flags) { public static final int OP_ACCESS_ACCESSIBILITY = 88; /** @hide Read the device identifiers (IMEI / MEID, IMSI, SIM / Build serial) */ public static final int OP_READ_DEVICE_IDENTIFIERS = 89; + /** @hide Read location metadata from media */ + public static final int OP_ACCESS_MEDIA_LOCATION = 90; + /** @hide */ @UnsupportedAppUsage - public static final int _NUM_OP = 90; + public static final int _NUM_OP = 91; /** Access to coarse location information. */ public static final String OPSTR_COARSE_LOCATION = "android:coarse_location"; @@ -1107,6 +1110,9 @@ public static String flagsToString(@OpFlags int flags) { @TestApi @SystemApi public static final String OPSTR_LEGACY_STORAGE = "android:legacy_storage"; + /** @hide Read location metadata from media */ + public static final String OPSTR_ACCESS_MEDIA_LOCATION = "android:access_media_location"; + /** @hide Interact with accessibility. */ @SystemApi public static final String OPSTR_ACCESS_ACCESSIBILITY = "android:access_accessibility"; @@ -1134,6 +1140,7 @@ public static String flagsToString(@OpFlags int flags) { // Storage OP_READ_EXTERNAL_STORAGE, OP_WRITE_EXTERNAL_STORAGE, + OP_ACCESS_MEDIA_LOCATION, // Location OP_COARSE_LOCATION, OP_FINE_LOCATION, @@ -1273,6 +1280,7 @@ public static String flagsToString(@OpFlags int flags) { OP_LEGACY_STORAGE, // LEGACY_STORAGE OP_ACCESS_ACCESSIBILITY, // ACCESS_ACCESSIBILITY OP_READ_DEVICE_IDENTIFIERS, // READ_DEVICE_IDENTIFIERS + OP_ACCESS_MEDIA_LOCATION, // ACCESS_MEDIA_LOCATION }; /** @@ -1369,6 +1377,7 @@ public static String flagsToString(@OpFlags int flags) { OPSTR_LEGACY_STORAGE, OPSTR_ACCESS_ACCESSIBILITY, OPSTR_READ_DEVICE_IDENTIFIERS, + OPSTR_ACCESS_MEDIA_LOCATION, }; /** @@ -1466,6 +1475,7 @@ public static String flagsToString(@OpFlags int flags) { "LEGACY_STORAGE", "ACCESS_ACCESSIBILITY", "READ_DEVICE_IDENTIFIERS", + "ACCESS_MEDIA_LOCATION", }; /** @@ -1564,6 +1574,7 @@ public static String flagsToString(@OpFlags int flags) { null, // no permission for OP_LEGACY_STORAGE null, // no permission for OP_ACCESS_ACCESSIBILITY null, // no direct permission for OP_READ_DEVICE_IDENTIFIERS + Manifest.permission.ACCESS_MEDIA_LOCATION, }; /** @@ -1662,6 +1673,7 @@ public static String flagsToString(@OpFlags int flags) { null, // LEGACY_STORAGE null, // ACCESS_ACCESSIBILITY null, // READ_DEVICE_IDENTIFIERS + null, // ACCESS_MEDIA_LOCATION }; /** @@ -1759,6 +1771,7 @@ public static String flagsToString(@OpFlags int flags) { false, // LEGACY_STORAGE false, // ACCESS_ACCESSIBILITY false, // READ_DEVICE_IDENTIFIERS + false, // ACCESS_MEDIA_LOCATION }; /** @@ -1855,6 +1868,7 @@ public static String flagsToString(@OpFlags int flags) { AppOpsManager.MODE_DEFAULT, // LEGACY_STORAGE AppOpsManager.MODE_ALLOWED, // ACCESS_ACCESSIBILITY AppOpsManager.MODE_ERRORED, // READ_DEVICE_IDENTIFIERS + AppOpsManager.MODE_ALLOWED, // ALLOW_MEDIA_LOCATION }; /** @@ -1955,6 +1969,7 @@ public static String flagsToString(@OpFlags int flags) { false, // LEGACY_STORAGE false, // ACCESS_ACCESSIBILITY false, // READ_DEVICE_IDENTIFIERS + false, // ACCESS_MEDIA_LOCATION }; /** diff --git a/data/etc/platform.xml b/data/etc/platform.xml index 233f82640a2..65f784dbee8 100644 --- a/data/etc/platform.xml +++ b/data/etc/platform.xml @@ -205,6 +205,10 @@ targetSdk="29"> + + + diff --git a/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java b/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java index 4550446f88c..ecf66861a40 100644 --- a/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java +++ b/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java @@ -190,6 +190,7 @@ public final class DefaultPermissionGrantPolicy { static { STORAGE_PERMISSIONS.add(Manifest.permission.READ_EXTERNAL_STORAGE); STORAGE_PERMISSIONS.add(Manifest.permission.WRITE_EXTERNAL_STORAGE); + STORAGE_PERMISSIONS.add(Manifest.permission.ACCESS_MEDIA_LOCATION); } private static final int MSG_READ_DEFAULT_PERMISSION_EXCEPTIONS = 1; From 6d97b76a2f9fd508e5fbb66169f343fe0b1ad42d Mon Sep 17 00:00:00 2001 From: Danny Baumann Date: Wed, 23 Nov 2016 10:12:35 +0100 Subject: [PATCH 040/240] Make Build.TYPE and Build.FINGERPRINT consistent for apps Some apps (namely Android Wear) like to do comparisons between TYPE and FINGERPRINT and throw errors on inconsistencies. As our fingerprints are almost always taken from stock ROMs, they don't really match our builds, causing said comparisons to fail. Avoid those failures by taking build type out of fingerprint for apps. Change-Id: I1d4fbeea38331b48448e81a075fe9cf2c8fdd846 Signed-off-by: Joe Maples --- core/java/android/os/Build.java | 42 +++++++++++++++++++ .../com/android/internal/os/RuntimeInit.java | 2 + 2 files changed, 44 insertions(+) diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java index 77d367f0d93..8a20b50e493 100755 --- a/core/java/android/os/Build.java +++ b/core/java/android/os/Build.java @@ -34,9 +34,14 @@ import dalvik.system.VMRuntime; +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; + import java.util.ArrayList; import java.util.List; import java.util.Objects; +import java.util.regex.Matcher; +import java.util.regex.Pattern; /** * Information about the current build, extracted from system properties. @@ -994,6 +999,7 @@ public static class VERSION_CODES { /** The type of build, like "user" or "eng". */ public static final String TYPE = getString("ro.build.type"); + private static String TYPE_FOR_APPS = parseBuildTypeFromFingerprint(); /** Comma-separated tags describing the build, like "unsigned,debug". */ public static final String TAGS = getString("ro.build.tags"); @@ -1020,6 +1026,42 @@ private static String deriveFingerprint() { return finger; } + // Some apps like to compare the build type embedded in fingerprint + // to the actual build type. As the fingerprint in our case is almost + // always hardcoded to the stock ROM fingerprint, provide that instead + // of the actual one if possible. + private static String parseBuildTypeFromFingerprint() { + final String fingerprint = SystemProperties.get("ro.build.fingerprint"); + if (TextUtils.isEmpty(fingerprint)) { + return null; + } + Pattern fingerprintPattern = + Pattern.compile("(.*)\\/(.*)\\/(.*):(.*)\\/(.*)\\/(.*):(.*)\\/(.*)"); + Matcher matcher = fingerprintPattern.matcher(fingerprint); + return matcher.matches() ? matcher.group(7) : null; + } + + /** @hide */ + public static void adjustBuildTypeIfNeeded() { + if (Process.isApplicationUid(Process.myUid()) && !TextUtils.isEmpty(TYPE_FOR_APPS)) { + try { + // This is sick. TYPE is final (which can't be changed because it's an API + // guarantee), but we have to reassign it. Resort to reflection to unset the + // final modifier, change the value and restore the final modifier afterwards. + Field typeField = Build.class.getField("TYPE"); + Field accessFlagsField = Field.class.getDeclaredField("accessFlags"); + accessFlagsField.setAccessible(true); + int currentFlags = accessFlagsField.getInt(typeField); + accessFlagsField.setInt(typeField, currentFlags & ~Modifier.FINAL); + typeField.set(null, TYPE_FOR_APPS); + accessFlagsField.setInt(typeField, currentFlags); + accessFlagsField.setAccessible(false); + } catch (Exception e) { + // shouldn't happen, but we don't want to crash the app even if it does happen + } + } + } + /** * Ensure that raw fingerprint system property is defined. If it was derived * dynamically by {@link #deriveFingerprint()} this is where we push the diff --git a/core/java/com/android/internal/os/RuntimeInit.java b/core/java/com/android/internal/os/RuntimeInit.java index eac150dbd32..c3abc71c474 100644 --- a/core/java/com/android/internal/os/RuntimeInit.java +++ b/core/java/com/android/internal/os/RuntimeInit.java @@ -201,6 +201,8 @@ protected static final void commonInit() { RuntimeHooks.setUncaughtExceptionPreHandler(loggingHandler); Thread.setDefaultUncaughtExceptionHandler(new KillApplicationHandler(loggingHandler)); + Build.adjustBuildTypeIfNeeded(); + /* * Install a time zone supplier that uses the Android persistent time zone system property. */ From 330cc763c7e71076c2f833064c406bf34e4ae0f5 Mon Sep 17 00:00:00 2001 From: AdrianDC Date: Fri, 1 Jan 2016 15:56:47 +0100 Subject: [PATCH 041/240] SettingsProvider: Add missing INTERACT_ACROSS_USERS_FULL permission * DatabaseUtils: java.lang.SecurityException: Permission Denial: get/set setting for user asks to run as user 0 but is calling from user 10; this requires android.permission.INTERACT_ACROSS_USERS_FULL Change-Id: I444dac4c4134e70d0fdd828c64be9ca732d3a195 Signed-off-by: Joe Maples --- packages/SettingsProvider/AndroidManifest.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/SettingsProvider/AndroidManifest.xml b/packages/SettingsProvider/AndroidManifest.xml index 9bc2d754641..1063ef9aa49 100644 --- a/packages/SettingsProvider/AndroidManifest.xml +++ b/packages/SettingsProvider/AndroidManifest.xml @@ -3,6 +3,9 @@ coreApp="true" android:sharedUserId="android.uid.system"> + + + Date: Wed, 22 Mar 2017 18:41:15 +0800 Subject: [PATCH 042/240] FATAL EXCEPTION IN SYSTEM PROCESS: android.ui when 3rd party app put an extra with a bad serial object to start a service or sendbroadcast to system_server. It will cause system_server crash because of classNotFoundException. A test demo apk will cause system_server crash. It really affact the system stability Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); intent.putExtra(Intent.EXTRA_REFERRER, new serial() /*a Serializable class object*/); sendBroadcast(intent); Test: use the test apk attached in the issue below, system_server will crash every time. And it'll be OK with this CL. https://code.google.com/p/android/issues/detail?id=261031 Change-Id: I525852d57f697a81ba8225c253f604900a51ba0d Signed-off-by: Simao Gomes Viana Signed-off-by: Joe Maples --- core/java/android/os/BaseBundle.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/core/java/android/os/BaseBundle.java b/core/java/android/os/BaseBundle.java index 7f63f8fb9e2..bd94cef25b2 100644 --- a/core/java/android/os/BaseBundle.java +++ b/core/java/android/os/BaseBundle.java @@ -298,6 +298,13 @@ private void initializeFromParcelLocked(@NonNull Parcel parcelledData, boolean r } else { throw e; } + } catch (RuntimeException e) { + if (sShouldDefuse && (e.getCause() instanceof ClassNotFoundException)) { + Log.w(TAG, "Failed to parse Bundle, but defusing quietly", e); + map.erase(); + } else { + throw e; + } } finally { mMap = map; if (recycleParcel) { From 3db43b36eb11f5af437147ab2d43b3004e239ccd Mon Sep 17 00:00:00 2001 From: jhenrique09 Date: Mon, 9 Sep 2019 04:52:45 +0000 Subject: [PATCH 043/240] base: Add START_ACTIVITIES_FROM_BACKGROUND on phone priv-app whitelist Change-Id: I0cea91e77ba8f2ea604f18961bb5304b124da4e0 --- data/etc/privapp-permissions-platform.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml index ff4e1005c9d..918f6cbfc6a 100644 --- a/data/etc/privapp-permissions-platform.xml +++ b/data/etc/privapp-permissions-platform.xml @@ -152,6 +152,7 @@ applications that come with the platform + From 2b7908366ad331c20b1617b4fed0eda5931a8260 Mon Sep 17 00:00:00 2001 From: Bruno Martins Date: Fri, 10 Nov 2017 15:00:17 +0000 Subject: [PATCH 044/240] Disable notification channel warnings by default * Since we usually ship "userdebug" builds, it is better to globally disable the toast because we are not in control of third-party apps that haven't been properly aligned with new Oreo requirements. * Leave it enabled by default only for "eng" builds. Change-Id: If0c74bcd03de2b664794e5855c2aaceb5c633b6c --- .../android/server/notification/NotificationManagerService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index 35268fe0da0..719cf890255 100644 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -5058,7 +5058,7 @@ protected boolean canLaunchInActivityView(Context context, PendingIntent pending private void doChannelWarningToast(CharSequence toastText) { Binder.withCleanCallingIdentity(() -> { - final int defaultWarningEnabled = Build.IS_DEBUGGABLE ? 1 : 0; + final int defaultWarningEnabled = Build.TYPE.equals("eng") ? 1 : 0; final boolean warningEnabled = Settings.Global.getInt(getContext().getContentResolver(), Settings.Global.SHOW_NOTIFICATION_CHANNEL_WARNINGS, defaultWarningEnabled) != 0; if (warningEnabled) { From 9d2a773069023853f29943664f9d8cdd1f5ff5db Mon Sep 17 00:00:00 2001 From: Ethan Chen Date: Fri, 6 Oct 2017 00:05:08 -0700 Subject: [PATCH 045/240] Check for null callerPackage in getStorageEncryptionStatus * This function assumes that callerPackage is always valid, even though the parameter is annotated nullable. Check and assume the function was called by the system if the callerPackage was null. Change-Id: Ie936d401f666ac8022635fb49d9ab2adfb5916c4 --- .../DevicePolicyManagerService.java | 30 +++++++++++-------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index 37931be4eb1..1b2d296a013 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -7102,20 +7102,24 @@ public int getStorageEncryptionStatus(@Nullable String callerPackage, int userHa } enforceFullCrossUsersPermission(userHandle); - // It's not critical here, but let's make sure the package name is correct, in case - // we start using it for different purposes. - ensureCallerPackage(callerPackage); - - final ApplicationInfo ai; - try { - ai = mIPackageManager.getApplicationInfo(callerPackage, 0, userHandle); - } catch (RemoteException e) { - throw new SecurityException(e); - } - boolean legacyApp = false; - if (ai.targetSdkVersion <= Build.VERSION_CODES.M) { - legacyApp = true; + // callerPackage can only be null if we were called from within the system, + // which means that we are not a legacy app. + if (callerPackage != null) { + // It's not critical here, but let's make sure the package name is correct, in case + // we start using it for different purposes. + ensureCallerPackage(callerPackage); + + final ApplicationInfo ai; + try { + ai = mIPackageManager.getApplicationInfo(callerPackage, 0, userHandle); + } catch (RemoteException e) { + throw new SecurityException(e); + } + + if (ai.targetSdkVersion <= Build.VERSION_CODES.M) { + legacyApp = true; + } } final int rawStatus = getEncryptionStatus(); From be0b35a6c63cea5f2efaded44adad420da955897 Mon Sep 17 00:00:00 2001 From: dhacker29 Date: Tue, 24 Nov 2015 01:53:47 -0500 Subject: [PATCH 046/240] fw/b: Use ro.build.date to signal OTA upgrades Squash of: Author: dhacker29 Date: Tue Nov 24 01:53:47 2015 -0500 Core: Use ro.build.date to signal mIsUpgrade M: We use a static fingerprint that is only changed when a new OEM build is released, so every flash shows Android is starting instead of upgrading. This will fix that. N: even though we dont have the dexopt sceen on N, this is still needed to delete the correct caches, and grant/deny specific runtime permissions like a true oem update would do. Updated for Nougat By: BeansTown106 Change-Id: I0e3ed5c8f0351e48944432ae6a0c5194ddeff1fa Author: Sam Mortimer Date: Fri Sep 28 13:45:00 2018 -0700 fw/b UserManagerService: Use ro.build.date to signal upgrades *) We changed PackageManagerService to use Build.DATE instead of Build.FINGERPRINT to detect upgrade. Do the same for UserManagerService. *) Affects generation of preboot intent and app data migration. Change-Id: I56887b7ca842afdcf3cf84b27b4c04667cf43307 Author: Wang Han <416810799@qq.com> Date: Sat Dec 29 23:33:20 2018 +0800 ShortcutService: Use ro.build.date to signal package scanning * Affects system apps scanning. Change-Id: I5f6d6647929f5b5ae7e820b18e95bf5ed2ec8d1c Change-Id: If0eb969ba509981f9209ffa37a949d9042ef4c2a --- core/java/android/os/Build.java | 6 ++++++ .../core/java/com/android/server/am/UserController.java | 2 +- .../java/com/android/server/pm/PackageManagerService.java | 8 ++++---- services/core/java/com/android/server/pm/Settings.java | 8 ++++---- .../core/java/com/android/server/pm/ShortcutService.java | 2 +- .../java/com/android/server/pm/UserManagerService.java | 8 ++++---- .../android/server/policy/PermissionPolicyService.java | 2 +- 7 files changed, 21 insertions(+), 15 deletions(-) diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java index 8a20b50e493..57ecbe61941 100755 --- a/core/java/android/os/Build.java +++ b/core/java/android/os/Build.java @@ -67,6 +67,12 @@ public class Build { /** The name of the underlying board, like "goldfish". */ public static final String BOARD = getString("ro.product.board"); + /** + * The build date + * @hide + */ + public static final String DATE = getString("ro.build.date"); + /** * The name of the instruction set (CPU type + ABI convention) of native code. * diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java index b311233694c..1d0742bd4f4 100644 --- a/services/core/java/com/android/server/am/UserController.java +++ b/services/core/java/com/android/server/am/UserController.java @@ -501,7 +501,7 @@ void finishUserUnlocked(final UserState uss) { // purposefully block sending BOOT_COMPLETED until after all // PRE_BOOT receivers are finished to avoid ANR'ing apps final UserInfo info = getUserInfo(userId); - if (!Objects.equals(info.lastLoggedInFingerprint, Build.FINGERPRINT)) { + if (!Objects.equals(info.lastLoggedInFingerprint, Build.DATE)) { // Suppress double notifications for managed profiles that // were unlocked automatically as part of their parent user // being unlocked. diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index cb39b4b4256..632ab102ef3 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -2581,10 +2581,10 @@ public PackageManagerService(Context context, Installer installer, File frameworkDir = new File(Environment.getRootDirectory(), "framework"); final VersionInfo ver = mSettings.getInternalVersion(); - mIsUpgrade = !Build.FINGERPRINT.equals(ver.fingerprint); + mIsUpgrade = !Build.DATE.equals(ver.fingerprint); if (mIsUpgrade) { logCriticalInfo(Log.INFO, - "Upgrading from " + ver.fingerprint + " to " + Build.FINGERPRINT); + "Upgrading from " + ver.fingerprint + " to " + Build.DATE); } // when upgrading from pre-M, promote system app permissions from install to runtime @@ -3261,7 +3261,7 @@ public PackageManagerService(Context context, Installer installer, | Installer.FLAG_CLEAR_CODE_CACHE_ONLY); } } - ver.fingerprint = Build.FINGERPRINT; + ver.fingerprint = Build.DATE; } // Grandfather existing (installed before Q) non-system apps to hide @@ -22718,7 +22718,7 @@ private void loadPrivatePackagesInner(VolumeInfo vol) { Slog.w(TAG, "Failed to scan " + ps.codePath + ": " + e.getMessage()); } - if (!Build.FINGERPRINT.equals(ver.fingerprint)) { + if (!Build.DATE.equals(ver.fingerprint)) { clearAppDataLIF(ps.pkg, UserHandle.USER_ALL, FLAG_STORAGE_DE | FLAG_STORAGE_CE | FLAG_STORAGE_EXTERNAL | Installer.FLAG_CLEAR_CODE_CACHE_ONLY); } diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java index 11a8f4b895f..d23bef00c6b 100644 --- a/services/core/java/com/android/server/pm/Settings.java +++ b/services/core/java/com/android/server/pm/Settings.java @@ -320,7 +320,7 @@ public static class VersionInfo { public void forceCurrent() { sdkVersion = Build.VERSION.SDK_INT; databaseVersion = CURRENT_DATABASE_VERSION; - fingerprint = Build.FINGERPRINT; + fingerprint = Build.DATE; } } @@ -3069,7 +3069,7 @@ boolean readLPw(@NonNull List users) { // on update drop the files before loading them. if (PackageManagerService.CLEAR_RUNTIME_PERMISSIONS_ON_UPGRADE) { final VersionInfo internal = getInternalVersion(); - if (!Build.FINGERPRINT.equals(internal.fingerprint)) { + if (!Build.DATE.equals(internal.fingerprint)) { for (UserInfo user : users) { mRuntimePermissionsPersistence.deleteUserRuntimePermissionsFile(user.id); } @@ -5275,7 +5275,7 @@ private void writePermissionsSync(int userId) { serializer.endDocument(); destination.finishWrite(out); - if (Build.FINGERPRINT.equals(fingerprint)) { + if (Build.DATE.equals(fingerprint)) { mDefaultPermissionsGranted.put(userId, true); } // Any error while writing is fatal. @@ -5373,7 +5373,7 @@ private void parseRuntimePermissionsLPr(XmlPullParser parser, int userId) mVersions.put(userId, version); String fingerprint = parser.getAttributeValue(null, ATTR_FINGERPRINT); mFingerprints.put(userId, fingerprint); - final boolean defaultsGranted = Build.FINGERPRINT.equals(fingerprint); + final boolean defaultsGranted = Build.DATE.equals(fingerprint); mDefaultPermissionsGranted.put(userId, defaultsGranted); } break; diff --git a/services/core/java/com/android/server/pm/ShortcutService.java b/services/core/java/com/android/server/pm/ShortcutService.java index 2d8a2acd575..d1ee52eef2d 100644 --- a/services/core/java/com/android/server/pm/ShortcutService.java +++ b/services/core/java/com/android/server/pm/ShortcutService.java @@ -4302,7 +4302,7 @@ void injectRestoreCallingIdentity(long token) { // Injection point. String injectBuildFingerprint() { - return Build.FINGERPRINT; + return Build.DATE; } final void wtf(String message) { diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java index 204f186f9e1..4e3cda25345 100644 --- a/services/core/java/com/android/server/pm/UserManagerService.java +++ b/services/core/java/com/android/server/pm/UserManagerService.java @@ -2762,7 +2762,7 @@ private UserInfo createUserInternalUnchecked(String name, int flags, int parentI long now = System.currentTimeMillis(); userInfo.creationTime = (now > EPOCH_PLUS_30_YEARS) ? now : 0; userInfo.partial = true; - userInfo.lastLoggedInFingerprint = Build.FINGERPRINT; + userInfo.lastLoggedInFingerprint = Build.DATE; if (isManagedProfile && parentId != UserHandle.USER_NULL) { userInfo.profileBadge = getFreeProfileBadgeLU(parentId); } @@ -3452,7 +3452,7 @@ public void onBeforeStartUser(int userId) { } final int userSerial = userInfo.serialNumber; // Migrate only if build fingerprints mismatch - boolean migrateAppsData = !Build.FINGERPRINT.equals(userInfo.lastLoggedInFingerprint); + boolean migrateAppsData = !Build.DATE.equals(userInfo.lastLoggedInFingerprint); mUserDataPreparer.prepareUserData(userId, userSerial, StorageManager.FLAG_STORAGE_DE); mPm.reconcileAppsData(userId, StorageManager.FLAG_STORAGE_DE, migrateAppsData); @@ -3474,7 +3474,7 @@ public void onBeforeUnlockUser(@UserIdInt int userId) { } final int userSerial = userInfo.serialNumber; // Migrate only if build fingerprints mismatch - boolean migrateAppsData = !Build.FINGERPRINT.equals(userInfo.lastLoggedInFingerprint); + boolean migrateAppsData = !Build.DATE.equals(userInfo.lastLoggedInFingerprint); mUserDataPreparer.prepareUserData(userId, userSerial, StorageManager.FLAG_STORAGE_CE); mPm.reconcileAppsData(userId, StorageManager.FLAG_STORAGE_CE, migrateAppsData); } @@ -3504,7 +3504,7 @@ public void onUserLoggedIn(@UserIdInt int userId) { if (now > EPOCH_PLUS_30_YEARS) { userData.info.lastLoggedInTime = now; } - userData.info.lastLoggedInFingerprint = Build.FINGERPRINT; + userData.info.lastLoggedInFingerprint = Build.DATE; scheduleWriteUser(userData); } diff --git a/services/core/java/com/android/server/policy/PermissionPolicyService.java b/services/core/java/com/android/server/policy/PermissionPolicyService.java index 3d543c96aac..1d089a2ca93 100644 --- a/services/core/java/com/android/server/policy/PermissionPolicyService.java +++ b/services/core/java/com/android/server/policy/PermissionPolicyService.java @@ -307,7 +307,7 @@ private void grantOrUpgradeDefaultRuntimePermissionsIfNeeded(@UserIdInt int user /* ignore */ } - packageManagerInternal.setRuntimePermissionsFingerPrint(Build.FINGERPRINT, userId); + packageManagerInternal.setRuntimePermissionsFingerPrint(Build.DATE, userId); } } From 22433a06eb3925da0ce0ff2525b635310fc51fff Mon Sep 17 00:00:00 2001 From: Chris Crump Date: Tue, 17 Sep 2019 02:45:31 -0400 Subject: [PATCH 047/240] base: Re-implement privacy chips interface This readds privacy chips introduced in early Q builds, Google removed this for unknown reasons (as usual) but it's stable enough to use Change-Id: I86a62ed0e173a6ea3b0448e16f246af09dc11618 Reverts: 9a560e068d953d44472f0592a91357dd70ae7a3b & a6c1e6ab651718e24416a1ca061b92b7626c416a --- .../sysui/SystemUiDeviceConfigFlags.java | 9 +- .../res/layout/car_ongoing_privacy_chip.xml | 37 +++ .../res/layout/car_top_navigation_bar.xml | 2 + packages/CarSystemUI/res/values/dimens.xml | 20 ++ .../car/privacy/OngoingPrivacyChip.java | 228 ++++++++++++++ .../car/privacy/PrivacyApplication.java | 62 ++++ .../car/privacy/PrivacyDialogBuilder.java | 59 ++++ .../statusbar/car/privacy/PrivacyItem.java | 46 +++ .../statusbar/car/privacy/PrivacyType.java | 53 ++++ .../SystemUI/res/drawable/privacy_chip_bg.xml | 23 ++ .../res/layout/ongoing_privacy_chip.xml | 41 +++ .../res/layout/ongoing_privacy_text_item.xml | 24 ++ .../quick_status_bar_header_system_icons.xml | 27 ++ .../src/com/android/systemui/Dependency.java | 3 + .../systemui/appops/AppOpsControllerImpl.java | 65 +++- .../systemui/privacy/OngoingPrivacyChip.kt | 110 +++++++ .../systemui/privacy/PrivacyDialogBuilder.kt | 56 ++++ .../android/systemui/privacy/PrivacyItem.kt | 80 +++++ .../systemui/privacy/PrivacyItemController.kt | 294 ++++++++++++++++++ .../systemui/qs/QuickStatusBarHeader.java | 126 +++++++- .../statusbar/phone/PhoneStatusBarPolicy.java | 64 +++- .../systemui/appops/AppOpsControllerTest.java | 23 ++ .../privacy/PrivacyDialogBuilderTest.kt | 77 +++++ .../privacy/PrivacyItemControllerTest.kt | 293 +++++++++++++++++ 24 files changed, 1812 insertions(+), 10 deletions(-) create mode 100644 packages/CarSystemUI/res/layout/car_ongoing_privacy_chip.xml create mode 100644 packages/CarSystemUI/src/com/android/systemui/statusbar/car/privacy/OngoingPrivacyChip.java create mode 100644 packages/CarSystemUI/src/com/android/systemui/statusbar/car/privacy/PrivacyApplication.java create mode 100644 packages/CarSystemUI/src/com/android/systemui/statusbar/car/privacy/PrivacyDialogBuilder.java create mode 100644 packages/CarSystemUI/src/com/android/systemui/statusbar/car/privacy/PrivacyItem.java create mode 100644 packages/CarSystemUI/src/com/android/systemui/statusbar/car/privacy/PrivacyType.java create mode 100644 packages/SystemUI/res/drawable/privacy_chip_bg.xml create mode 100644 packages/SystemUI/res/layout/ongoing_privacy_chip.xml create mode 100644 packages/SystemUI/res/layout/ongoing_privacy_text_item.xml create mode 100644 packages/SystemUI/src/com/android/systemui/privacy/OngoingPrivacyChip.kt create mode 100644 packages/SystemUI/src/com/android/systemui/privacy/PrivacyDialogBuilder.kt create mode 100644 packages/SystemUI/src/com/android/systemui/privacy/PrivacyItem.kt create mode 100644 packages/SystemUI/src/com/android/systemui/privacy/PrivacyItemController.kt create mode 100644 packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyDialogBuilderTest.kt create mode 100644 packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyItemControllerTest.kt diff --git a/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java b/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java index 40ee511b072..d3abdcfb4c0 100644 --- a/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java +++ b/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java @@ -106,7 +106,14 @@ public final class SystemUiDeviceConfigFlags { */ public static final String HASH_SALT_MAX_DAYS = "hash_salt_max_days"; - // Flags related to Assistant + // Flag related to Privacy Indicators + + /** + * Whether the Permissions Hub is showing. + */ + public static final String PROPERTY_PERMISSIONS_HUB_ENABLED = "permissions_hub_enabled"; + + // Flags related to Assistant Handles /** * (String) Which behavior mode for the Assistant Handles to use. diff --git a/packages/CarSystemUI/res/layout/car_ongoing_privacy_chip.xml b/packages/CarSystemUI/res/layout/car_ongoing_privacy_chip.xml new file mode 100644 index 00000000000..918abd962dc --- /dev/null +++ b/packages/CarSystemUI/res/layout/car_ongoing_privacy_chip.xml @@ -0,0 +1,37 @@ + + + + + + + \ No newline at end of file diff --git a/packages/CarSystemUI/res/layout/car_top_navigation_bar.xml b/packages/CarSystemUI/res/layout/car_top_navigation_bar.xml index 925ccb4a162..cae89c16a03 100644 --- a/packages/CarSystemUI/res/layout/car_top_navigation_bar.xml +++ b/packages/CarSystemUI/res/layout/car_top_navigation_bar.xml @@ -65,6 +65,8 @@ /> + + 24dp 96dp 128dp + 36dp + 0dp + 0dp + 0dp + 0dp + + 0dp + 0dp + 0dp + 0dp 100dp @@ -76,6 +86,16 @@ 4dp 12dp + + 40dp + + 40dp + + 20dp + + 10dp + + 10dp @dimen/car_primary_icon_size diff --git a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/privacy/OngoingPrivacyChip.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/privacy/OngoingPrivacyChip.java new file mode 100644 index 00000000000..ead1de2bd35 --- /dev/null +++ b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/privacy/OngoingPrivacyChip.java @@ -0,0 +1,228 @@ +/* + * Copyright (C) 2019 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.statusbar.car.privacy; + +import android.app.ActivityManager; +import android.app.AppOpsManager; +import android.content.Context; +import android.content.Intent; +import android.os.Handler; +import android.os.Looper; +import android.os.UserHandle; +import android.os.UserManager; +import android.util.AttributeSet; +import android.view.View; +import android.widget.ImageView; +import android.widget.LinearLayout; + +import com.android.systemui.Dependency; +import com.android.systemui.R; +import com.android.systemui.appops.AppOpItem; +import com.android.systemui.appops.AppOpsController; +import com.android.systemui.plugins.ActivityStarter; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; + +/** + * Layout defining the privacy chip that will be displayed in CarStatusRar with the information for + * which applications are using AppOpps permission fpr camera, mic and location. + */ +public class OngoingPrivacyChip extends LinearLayout implements View.OnClickListener { + + private Context mContext; + + private LinearLayout mIconsContainer; + private List mPrivacyItems; + private static AppOpsController sAppOpsController; + private UserManager mUserManager; + private int mCurrentUser; + private List mCurrentUserIds; + private boolean mListening = false; + PrivacyDialogBuilder mPrivacyDialogBuilder; + private LinearLayout mPrivacyChip; + private ActivityStarter mActivityStarter; + + protected static final int[] OPS = new int[]{ + AppOpsManager.OP_CAMERA, + AppOpsManager.OP_RECORD_AUDIO, + AppOpsManager.OP_COARSE_LOCATION, + AppOpsManager.OP_FINE_LOCATION + }; + + public OngoingPrivacyChip(Context context) { + super(context, null); + init(context); + } + + public OngoingPrivacyChip(Context context, AttributeSet attr) { + super(context, attr); + init(context); + } + + public OngoingPrivacyChip(Context context, AttributeSet attr, int defStyle) { + super(context, attr, defStyle); + init(context); + } + + public OngoingPrivacyChip(Context context, AttributeSet attr, int defStyle, int a) { + super(context, attr, defStyle, a); + init(context); + } + + private void init(Context context) { + mContext = context; + mPrivacyItems = new ArrayList<>(); + sAppOpsController = Dependency.get(AppOpsController.class); + mUserManager = mContext.getSystemService(UserManager.class); + mActivityStarter = Dependency.get(ActivityStarter.class); + mCurrentUser = ActivityManager.getCurrentUser(); + mCurrentUserIds = mUserManager.getProfiles(mCurrentUser).stream().map( + userInfo -> userInfo.id).collect(Collectors.toList()); + + mPrivacyDialogBuilder = new PrivacyDialogBuilder(context, mPrivacyItems); + } + + private AppOpsController.Callback mCallback = new AppOpsController.Callback() { + + @Override + public void onActiveStateChanged(int code, int uid, String packageName, boolean active) { + int userId = UserHandle.getUserId(uid); + if (mCurrentUserIds.contains(userId)) { + updatePrivacyList(); + } + } + }; + + @Override + public void onFinishInflate() { + mIconsContainer = findViewById(R.id.icons_container); + mPrivacyChip = (LinearLayout) findViewById(R.id.car_privacy_chip); + if (mPrivacyChip != null) { + mPrivacyChip.setOnClickListener(this); + setListening(true); + } + } + + @Override + public void onDetachedFromWindow() { + if (mPrivacyChip != null) { + setListening(false); + } + super.onDetachedFromWindow(); + } + + @Override + public void onClick(View v) { + updatePrivacyList(); + Handler mUiHandler = new Handler(Looper.getMainLooper()); + mUiHandler.post(() -> { + mActivityStarter.postStartActivityDismissingKeyguard( + new Intent(Intent.ACTION_REVIEW_ONGOING_PERMISSION_USAGE), 0); + }); + } + + private void setListening(boolean listen) { + if (mListening == listen) { + return; + } + mListening = listen; + if (mListening) { + sAppOpsController.addCallback(OPS, mCallback); + updatePrivacyList(); + } else { + sAppOpsController.removeCallback(OPS, mCallback); + } + } + + private void updatePrivacyList() { + mPrivacyItems = mCurrentUserIds.stream() + .flatMap(item -> sAppOpsController.getActiveAppOpsForUser(item).stream()) + .filter(Objects::nonNull) + .map(item -> toPrivacyItem(item)) + .filter(Objects::nonNull) + .collect(Collectors.toList()); + mPrivacyDialogBuilder = new PrivacyDialogBuilder(mContext, mPrivacyItems); + + Handler refresh = new Handler(Looper.getMainLooper()); + refresh.post(new Runnable() { + @Override + public void run() { + updateView(); + } + }); + } + + private PrivacyItem toPrivacyItem(AppOpItem appOpItem) { + PrivacyType type; + switch (appOpItem.getCode()) { + case AppOpsManager.OP_CAMERA: + type = PrivacyType.TYPE_CAMERA; + break; + case AppOpsManager.OP_COARSE_LOCATION: + type = PrivacyType.TYPE_LOCATION; + break; + case AppOpsManager.OP_FINE_LOCATION: + type = PrivacyType.TYPE_LOCATION; + break; + case AppOpsManager.OP_RECORD_AUDIO: + type = PrivacyType.TYPE_MICROPHONE; + break; + default: + return null; + } + PrivacyApplication app = new PrivacyApplication(appOpItem.getPackageName(), mContext); + return new PrivacyItem(type, app, appOpItem.getTimeStarted()); + } + + // Should only be called if the mPrivacyDialogBuilder icons or app changed + private void updateView() { + if (mPrivacyItems.isEmpty()) { + mPrivacyChip.setVisibility(GONE); + return; + } + mPrivacyChip.setVisibility(VISIBLE); + setIcons(mPrivacyDialogBuilder); + + requestLayout(); + } + + private void setIcons(PrivacyDialogBuilder dialogBuilder) { + mIconsContainer.removeAllViews(); + dialogBuilder.generateIcons().forEach(item -> { + int size = mContext.getResources().getDimensionPixelSize( + R.dimen.privacy_chip_icon_height); + ImageView image = new ImageView(mContext); + image.setImageDrawable(item); + LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(size, size); + + int leftPadding = mContext.getResources().getDimensionPixelSize( + R.dimen.privacy_chip_icon_padding_left); + int topPadding = mContext.getResources().getDimensionPixelSize( + R.dimen.privacy_chip_icon_padding_top); + int rightPadding = mContext.getResources().getDimensionPixelSize( + R.dimen.privacy_chip_icon_padding_right); + int bottomPadding = mContext.getResources().getDimensionPixelSize( + R.dimen.privacy_chip_icon_padding_bottom); + image.setLayoutParams(layoutParams); + image.setPadding(leftPadding, topPadding, rightPadding, bottomPadding); + mIconsContainer.addView(image); + }); + } +} diff --git a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/privacy/PrivacyApplication.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/privacy/PrivacyApplication.java new file mode 100644 index 00000000000..5ec7a77cb30 --- /dev/null +++ b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/privacy/PrivacyApplication.java @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2019 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.statusbar.car.privacy; + +import android.car.userlib.CarUserManagerHelper; +import android.content.Context; +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageManager; +import android.graphics.drawable.Drawable; +import android.util.Log; + +/** + * Class to hold the data for the applications that are using the AppOps permissions. + */ +public class PrivacyApplication { + private static final String TAG = "PrivacyApplication"; + + private Drawable mIcon; + private String mApplicationName; + + public PrivacyApplication(String packageName, Context context) { + try { + CarUserManagerHelper carUserManagerHelper = new CarUserManagerHelper(context); + ApplicationInfo app = context.getPackageManager() + .getApplicationInfoAsUser(packageName, 0, + carUserManagerHelper.getCurrentForegroundUserId()); + mIcon = context.getPackageManager().getApplicationIcon(app); + mApplicationName = context.getPackageManager().getApplicationLabel(app).toString(); + } catch (PackageManager.NameNotFoundException e) { + mApplicationName = packageName; + Log.e(TAG, "Failed to to find package name", e); + } + } + + /** + * Gets the application name. + */ + public Drawable getIcon() { + return mIcon; + } + + /** + * Gets the application name. + */ + public String getApplicationName() { + return mApplicationName; + } +} diff --git a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/privacy/PrivacyDialogBuilder.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/privacy/PrivacyDialogBuilder.java new file mode 100644 index 00000000000..3b83e7cc062 --- /dev/null +++ b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/privacy/PrivacyDialogBuilder.java @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2019 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.statusbar.car.privacy; + +import android.content.Context; +import android.graphics.drawable.Drawable; + +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.stream.Collectors; + +/** + * Helper class to build the {@link OngoingPrivacyDialog} + */ +public class PrivacyDialogBuilder { + + private Map> mItemsByType; + private PrivacyApplication mApplication; + private Context mContext; + + public PrivacyDialogBuilder(Context context, List itemsList) { + mContext = context; + mItemsByType = itemsList.stream().filter(Objects::nonNull).collect( + Collectors.groupingBy(PrivacyItem::getPrivacyType)); + List apps = itemsList.stream().filter(Objects::nonNull).map( + PrivacyItem::getPrivacyApplication).distinct().collect(Collectors.toList()); + mApplication = apps.size() == 1 ? apps.get(0) : null; + } + + /** + * Gets the icon id for all the {@link PrivacyItem} in the same order as of itemList. + */ + public List generateIcons() { + return mItemsByType.keySet().stream().map(item -> item.getIconId(mContext)).collect( + Collectors.toList()); + } + + /** + * Gets the application object. + */ + public PrivacyApplication getApplication() { + return mApplication; + } +} diff --git a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/privacy/PrivacyItem.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/privacy/PrivacyItem.java new file mode 100644 index 00000000000..fca137392d7 --- /dev/null +++ b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/privacy/PrivacyItem.java @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2019 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.statusbar.car.privacy; + +/** + * Class for holding the data of each privacy item displayed in {@link OngoingPrivacyDialog} + */ +public class PrivacyItem { + + private PrivacyType mPrivacyType; + private PrivacyApplication mPrivacyApplication; + + public PrivacyItem(PrivacyType privacyType, PrivacyApplication privacyApplication, + long timeStarted) { + this.mPrivacyType = privacyType; + this.mPrivacyApplication = privacyApplication; + } + + /** + * Gets the application object. + */ + public PrivacyApplication getPrivacyApplication() { + return mPrivacyApplication; + } + + /** + * Gets the privacy type for the application. + */ + public PrivacyType getPrivacyType() { + return mPrivacyType; + } +} diff --git a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/privacy/PrivacyType.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/privacy/PrivacyType.java new file mode 100644 index 00000000000..8955c87bbff --- /dev/null +++ b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/privacy/PrivacyType.java @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2019 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.statusbar.car.privacy; + +import android.content.Context; +import android.graphics.drawable.Drawable; + +import com.android.systemui.R; + +/** + * Enum for storing data for camera, mic and location. + */ +public enum PrivacyType { + TYPE_CAMERA(R.string.privacy_type_camera, com.android.internal.R.drawable.ic_camera), + TYPE_LOCATION(R.string.privacy_type_location, R.drawable.stat_sys_location), + TYPE_MICROPHONE(R.string.privacy_type_microphone, R.drawable.ic_mic_white); + + private int mNameId; + private int mIconId; + + PrivacyType(int nameId, int iconId) { + mNameId = nameId; + mIconId = iconId; + } + + /** + * Get the icon Id. + */ + public Drawable getIconId(Context context) { + return context.getResources().getDrawable(mIconId, null); + } + + /** + * Get the name Id. + */ + public String getNameId(Context context) { + return context.getResources().getString(mNameId); + } +} diff --git a/packages/SystemUI/res/drawable/privacy_chip_bg.xml b/packages/SystemUI/res/drawable/privacy_chip_bg.xml new file mode 100644 index 00000000000..b7b21fa53b6 --- /dev/null +++ b/packages/SystemUI/res/drawable/privacy_chip_bg.xml @@ -0,0 +1,23 @@ + + + + + + + + \ No newline at end of file diff --git a/packages/SystemUI/res/layout/ongoing_privacy_chip.xml b/packages/SystemUI/res/layout/ongoing_privacy_chip.xml new file mode 100644 index 00000000000..dce9ce16e9c --- /dev/null +++ b/packages/SystemUI/res/layout/ongoing_privacy_chip.xml @@ -0,0 +1,41 @@ + + + + + + + + + + \ No newline at end of file diff --git a/packages/SystemUI/res/layout/ongoing_privacy_text_item.xml b/packages/SystemUI/res/layout/ongoing_privacy_text_item.xml new file mode 100644 index 00000000000..5595b130e04 --- /dev/null +++ b/packages/SystemUI/res/layout/ongoing_privacy_text_item.xml @@ -0,0 +1,24 @@ + + + + \ No newline at end of file diff --git a/packages/SystemUI/res/layout/quick_status_bar_header_system_icons.xml b/packages/SystemUI/res/layout/quick_status_bar_header_system_icons.xml index 54fb2168dfa..cd9f780ca24 100644 --- a/packages/SystemUI/res/layout/quick_status_bar_header_system_icons.xml +++ b/packages/SystemUI/res/layout/quick_status_bar_header_system_icons.xml @@ -22,11 +22,19 @@ android:layout_height="@*android:dimen/quick_qs_offset_height" android:clipChildren="false" android:clipToPadding="false" + android:gravity="center" android:orientation="horizontal" android:clickable="true" android:paddingStart="@dimen/status_bar_padding_start" android:paddingEnd="@dimen/status_bar_padding_end" > + + + + + + + + + + + diff --git a/packages/SystemUI/src/com/android/systemui/Dependency.java b/packages/SystemUI/src/com/android/systemui/Dependency.java index 15bea2484d7..ec2111d502c 100644 --- a/packages/SystemUI/src/com/android/systemui/Dependency.java +++ b/packages/SystemUI/src/com/android/systemui/Dependency.java @@ -47,6 +47,7 @@ import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.power.EnhancedEstimates; import com.android.systemui.power.PowerUI; +import com.android.systemui.privacy.PrivacyItemController; import com.android.systemui.recents.OverviewProxyService; import com.android.systemui.shared.plugins.PluginManager; import com.android.systemui.shared.system.ActivityManagerWrapper; @@ -280,6 +281,7 @@ public class Dependency { @Inject Lazy mSensorPrivacyManager; @Inject Lazy mAutoHideController; @Inject Lazy mForegroundServiceNotificationListener; + @Inject Lazy mPrivacyItemController; @Inject @Named(BG_LOOPER_NAME) Lazy mBgLooper; @Inject @Named(BG_HANDLER_NAME) Lazy mBgHandler; @Inject @Named(MAIN_HANDLER_NAME) Lazy mMainHandler; @@ -475,6 +477,7 @@ protected void start() { mProviders.put(ForegroundServiceNotificationListener.class, mForegroundServiceNotificationListener::get); mProviders.put(ClockManager.class, mClockManager::get); + mProviders.put(PrivacyItemController.class, mPrivacyItemController::get); mProviders.put(ActivityManagerWrapper.class, mActivityManagerWrapper::get); mProviders.put(DevicePolicyManagerWrapper.class, mDevicePolicyManagerWrapper::get); mProviders.put(PackageManagerWrapper.class, mPackageManagerWrapper::get); diff --git a/packages/SystemUI/src/com/android/systemui/appops/AppOpsControllerImpl.java b/packages/SystemUI/src/com/android/systemui/appops/AppOpsControllerImpl.java index 7a74dba27dc..9a967b659ee 100644 --- a/packages/SystemUI/src/com/android/systemui/appops/AppOpsControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/appops/AppOpsControllerImpl.java @@ -20,6 +20,7 @@ import android.app.AppOpsManager; import android.content.Context; +import android.content.pm.PackageManager; import android.os.Handler; import android.os.Looper; import android.os.UserHandle; @@ -211,6 +212,59 @@ private void addNoted(int code, int uid, String packageName) { mBGHandler.scheduleRemoval(item, NOTED_OP_TIME_DELAY_MS); } + /** + * Does the app-op code refer to a user sensitive permission for the specified user id + * and package. Only user sensitive permission should be shown to the user by default. + * + * @param appOpCode The code of the app-op. + * @param uid The uid of the user. + * @param packageName The name of the package. + * + * @return {@code true} iff the app-op item is user sensitive + */ + private boolean isUserSensitive(int appOpCode, int uid, String packageName) { + String permission = AppOpsManager.opToPermission(appOpCode); + if (permission == null) { + return false; + } + int permFlags = mContext.getPackageManager().getPermissionFlags(permission, + packageName, UserHandle.getUserHandleForUid(uid)); + return (permFlags & PackageManager.FLAG_PERMISSION_USER_SENSITIVE_WHEN_GRANTED) != 0; + } + + /** + * Does the app-op item refer to an operation that should be shown to the user. + * Only specficic ops (like SYSTEM_ALERT_WINDOW) or ops that refer to user sensitive + * permission should be shown to the user by default. + * + * @param item The item + * + * @return {@code true} iff the app-op item should be shown to the user + */ + private boolean isUserVisible(AppOpItem item) { + return isUserVisible(item.getCode(), item.getUid(), item.getPackageName()); + } + + + /** + * Does the app-op, uid and package name, refer to an operation that should be shown to the + * user. Only specficic ops (like {@link AppOpsManager.OP_SYSTEM_ALERT_WINDOW}) or + * ops that refer to user sensitive permission should be shown to the user by default. + * + * @param item The item + * + * @return {@code true} iff the app-op for should be shown to the user + */ + private boolean isUserVisible(int appOpCode, int uid, String packageName) { + // currently OP_SYSTEM_ALERT_WINDOW does not correspond to a platform permission + // which may be user senstive, so for now always show it to the user. + if (appOpCode == AppOpsManager.OP_SYSTEM_ALERT_WINDOW) { + return true; + } + + return isUserSensitive(appOpCode, uid, packageName); + } + /** * Returns a copy of the list containing all the active AppOps that the controller tracks. * @@ -234,8 +288,8 @@ public List getActiveAppOpsForUser(int userId) { final int numActiveItems = mActiveItems.size(); for (int i = 0; i < numActiveItems; i++) { AppOpItem item = mActiveItems.get(i); - if ((userId == UserHandle.USER_ALL - || UserHandle.getUserId(item.getUid()) == userId)) { + if ((userId == UserHandle.USER_ALL || UserHandle.getUserId(item.getUid()) == userId) + && isUserVisible(item)) { list.add(item); } } @@ -244,8 +298,8 @@ public List getActiveAppOpsForUser(int userId) { final int numNotedItems = mNotedItems.size(); for (int i = 0; i < numNotedItems; i++) { AppOpItem item = mNotedItems.get(i); - if ((userId == UserHandle.USER_ALL - || UserHandle.getUserId(item.getUid()) == userId)) { + if ((userId == UserHandle.USER_ALL || UserHandle.getUserId(item.getUid()) == userId) + && isUserVisible(item)) { list.add(item); } } @@ -271,7 +325,8 @@ public void onOpNoted(int code, int uid, String packageName, int result) { } private void notifySuscribers(int code, int uid, String packageName, boolean active) { - if (mCallbacksByCode.containsKey(code)) { + if (mCallbacksByCode.containsKey(code) + && isUserVisible(code, uid, packageName)) { for (Callback cb: mCallbacksByCode.get(code)) { cb.onActiveStateChanged(code, uid, packageName, active); } diff --git a/packages/SystemUI/src/com/android/systemui/privacy/OngoingPrivacyChip.kt b/packages/SystemUI/src/com/android/systemui/privacy/OngoingPrivacyChip.kt new file mode 100644 index 00000000000..a5a915b88ca --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/privacy/OngoingPrivacyChip.kt @@ -0,0 +1,110 @@ +/* + * 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.privacy + +import android.content.Context +import android.util.AttributeSet +import android.view.Gravity +import android.view.ViewGroup +import android.widget.FrameLayout +import android.widget.ImageView +import android.widget.LinearLayout +import com.android.systemui.R + +class OngoingPrivacyChip @JvmOverloads constructor( + context: Context, + attrs: AttributeSet? = null, + defStyleAttrs: Int = 0, + defStyleRes: Int = 0 +) : LinearLayout(context, attrs, defStyleAttrs, defStyleRes) { + + private val iconMarginExpanded = context.resources.getDimensionPixelSize( + R.dimen.ongoing_appops_chip_icon_margin_expanded) + private val iconMarginCollapsed = context.resources.getDimensionPixelSize( + R.dimen.ongoing_appops_chip_icon_margin_collapsed) + private val iconSize = + context.resources.getDimensionPixelSize(R.dimen.ongoing_appops_chip_icon_size) + private val iconColor = context.resources.getColor( + R.color.status_bar_clock_color, context.theme) + private val sidePadding = + context.resources.getDimensionPixelSize(R.dimen.ongoing_appops_chip_side_padding) + private val backgroundDrawable = context.getDrawable(R.drawable.privacy_chip_bg) + private lateinit var iconsContainer: LinearLayout + private lateinit var back: FrameLayout + var expanded = false + set(value) { + if (value != field) { + field = value + updateView() + } + } + + var builder = PrivacyDialogBuilder(context, emptyList()) + var privacyList = emptyList() + set(value) { + field = value + builder = PrivacyDialogBuilder(context, value) + updateView() + } + + override fun onFinishInflate() { + super.onFinishInflate() + + back = findViewById(R.id.background) + iconsContainer = findViewById(R.id.icons_container) + } + + // Should only be called if the builder icons or app changed + private fun updateView() { + back.background = if (expanded) backgroundDrawable else null + val padding = if (expanded) sidePadding else 0 + back.setPaddingRelative(padding, 0, padding, 0) + fun setIcons(dialogBuilder: PrivacyDialogBuilder, iconsContainer: ViewGroup) { + iconsContainer.removeAllViews() + dialogBuilder.generateIcons().forEachIndexed { i, it -> + it.mutate() + it.setTint(iconColor) + val image = ImageView(context).apply { + setImageDrawable(it) + scaleType = ImageView.ScaleType.CENTER_INSIDE + } + iconsContainer.addView(image, iconSize, iconSize) + if (i != 0) { + val lp = image.layoutParams as MarginLayoutParams + lp.marginStart = if (expanded) iconMarginExpanded else iconMarginCollapsed + image.layoutParams = lp + } + } + } + + if (!privacyList.isEmpty()) { + generateContentDescription() + setIcons(builder, iconsContainer) + val lp = iconsContainer.layoutParams as FrameLayout.LayoutParams + lp.gravity = Gravity.CENTER_VERTICAL or + (if (expanded) Gravity.CENTER_HORIZONTAL else Gravity.END) + iconsContainer.layoutParams = lp + } else { + iconsContainer.removeAllViews() + } + requestLayout() + } + + private fun generateContentDescription() { + val typesText = builder.joinTypes() + contentDescription = context.getString( + R.string.ongoing_privacy_chip_content_multiple_apps, typesText) + } +} \ No newline at end of file diff --git a/packages/SystemUI/src/com/android/systemui/privacy/PrivacyDialogBuilder.kt b/packages/SystemUI/src/com/android/systemui/privacy/PrivacyDialogBuilder.kt new file mode 100644 index 00000000000..d08a3733703 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/privacy/PrivacyDialogBuilder.kt @@ -0,0 +1,56 @@ +/* + * 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.privacy + +import android.content.Context +import android.graphics.drawable.Drawable +import com.android.systemui.R + +class PrivacyDialogBuilder(private val context: Context, itemsList: List) { + + val appsAndTypes: List>> + val types: List + private val separator = context.getString(R.string.ongoing_privacy_dialog_separator) + private val lastSeparator = context.getString(R.string.ongoing_privacy_dialog_last_separator) + + init { + appsAndTypes = itemsList.groupBy({ it.application }, { it.privacyType }) + .toList() + .sortedWith(compareBy({ -it.second.size }, // Sort by number of AppOps + { it.second.min() })) // Sort by "smallest" AppOpp (Location is largest) + types = itemsList.map { it.privacyType }.distinct().sorted() + } + + fun generateIconsForApp(types: List): List { + return types.sorted().map { it.getIcon(context) } + } + + fun generateIcons() = types.map { it.getIcon(context) } + + private fun List.joinWithAnd(): StringBuilder { + return subList(0, size - 1).joinTo(StringBuilder(), separator = separator).apply { + append(lastSeparator) + append(this@joinWithAnd.last()) + } + } + + fun joinTypes(): String { + return when (types.size) { + 0 -> "" + 1 -> types[0].getName(context) + else -> types.map { it.getName(context) }.joinWithAnd().toString() + } + } +} diff --git a/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItem.kt b/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItem.kt new file mode 100644 index 00000000000..290942412ee --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItem.kt @@ -0,0 +1,80 @@ +/* + * 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.privacy + +import android.content.Context +import android.content.pm.ApplicationInfo +import android.content.pm.PackageManager +import android.graphics.drawable.Drawable +import android.os.UserHandle +import android.util.IconDrawableFactory +import com.android.systemui.R + +typealias Privacy = PrivacyType + +enum class PrivacyType(private val nameId: Int, val iconId: Int) { + // This is uses the icons used by the corresponding permission groups in the AndroidManifest + TYPE_CAMERA(R.string.privacy_type_camera, + com.android.internal.R.drawable.perm_group_camera), + TYPE_MICROPHONE(R.string.privacy_type_microphone, + com.android.internal.R.drawable.perm_group_microphone), + TYPE_LOCATION(R.string.privacy_type_location, + com.android.internal.R.drawable.perm_group_location); + + fun getName(context: Context) = context.resources.getString(nameId) + + fun getIcon(context: Context) = context.resources.getDrawable(iconId, context.theme) +} + +data class PrivacyItem( + val privacyType: PrivacyType, + val application: PrivacyApplication +) + +data class PrivacyApplication(val packageName: String, val uid: Int, val context: Context) + : Comparable { + + override fun compareTo(other: PrivacyApplication): Int { + return applicationName.compareTo(other.applicationName) + } + + private val applicationInfo: ApplicationInfo? by lazy { + try { + val userHandle = UserHandle.getUserHandleForUid(uid) + context.createPackageContextAsUser(packageName, 0, userHandle).getPackageManager() + .getApplicationInfo(packageName, 0) + } catch (_: PackageManager.NameNotFoundException) { + null + } + } + val icon: Drawable by lazy { + applicationInfo?.let { + try { + val iconFactory = IconDrawableFactory.newInstance(context, true) + iconFactory.getBadgedIcon(it, UserHandle.getUserId(uid)) + } catch (_: Exception) { + null + } + } ?: context.getDrawable(android.R.drawable.sym_def_app_icon) + } + + val applicationName: String by lazy { + applicationInfo?.let { + context.packageManager.getApplicationLabel(it) as String + } ?: packageName + } + + override fun toString() = "PrivacyApplication(packageName=$packageName, uid=$uid)" +} diff --git a/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItemController.kt b/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItemController.kt new file mode 100644 index 00000000000..82a2c1fb43f --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItemController.kt @@ -0,0 +1,294 @@ +/* + * 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.privacy + +import android.app.ActivityManager +import android.app.AppOpsManager +import android.content.BroadcastReceiver +import android.content.Context +import android.content.Intent +import android.content.IntentFilter +import android.os.Handler +import android.os.Looper +import android.os.Message +import android.os.UserHandle +import android.os.UserManager +import android.provider.DeviceConfig +import com.android.internal.annotations.VisibleForTesting +import com.android.internal.config.sysui.SystemUiDeviceConfigFlags +import com.android.systemui.Dependency.BG_HANDLER_NAME +import com.android.systemui.Dependency.MAIN_HANDLER_NAME +import com.android.systemui.R +import com.android.systemui.appops.AppOpItem +import com.android.systemui.appops.AppOpsController +import com.android.systemui.Dumpable +import java.io.FileDescriptor +import java.io.PrintWriter +import java.lang.ref.WeakReference +import javax.inject.Inject +import javax.inject.Named +import javax.inject.Singleton + +fun isPermissionsHubEnabled() = DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_PRIVACY, + SystemUiDeviceConfigFlags.PROPERTY_PERMISSIONS_HUB_ENABLED, false) + +@Singleton +class PrivacyItemController @Inject constructor( + val context: Context, + private val appOpsController: AppOpsController, + @Named(MAIN_HANDLER_NAME) private val uiHandler: Handler, + @Named(BG_HANDLER_NAME) private val bgHandler: Handler +) : Dumpable { + + @VisibleForTesting + internal companion object { + val OPS = intArrayOf(AppOpsManager.OP_CAMERA, + AppOpsManager.OP_RECORD_AUDIO, + AppOpsManager.OP_COARSE_LOCATION, + AppOpsManager.OP_FINE_LOCATION) + val intents = listOf(Intent.ACTION_USER_FOREGROUND, + Intent.ACTION_MANAGED_PROFILE_ADDED, + Intent.ACTION_MANAGED_PROFILE_REMOVED) + const val TAG = "PrivacyItemController" + const val SYSTEM_UID = 1000 + const val MSG_ADD_CALLBACK = 0 + const val MSG_REMOVE_CALLBACK = 1 + const val MSG_UPDATE_LISTENING_STATE = 2 + } + + @VisibleForTesting + internal var privacyList = emptyList() + @Synchronized get() = field.toList() // Returns a shallow copy of the list + @Synchronized set + + private val userManager = context.getSystemService(UserManager::class.java) + private var currentUserIds = emptyList() + private var listening = false + val systemApp = + PrivacyApplication(context.getString(R.string.device_services), SYSTEM_UID, context) + private val callbacks = mutableListOf>() + private val messageHandler = H(WeakReference(this), uiHandler.looper) + + private val notifyChanges = Runnable { + val list = privacyList + callbacks.forEach { it.get()?.privacyChanged(list) } + } + + private val updateListAndNotifyChanges = Runnable { + updatePrivacyList() + uiHandler.post(notifyChanges) + } + + private var indicatorsAvailable = isPermissionsHubEnabled() + @VisibleForTesting + internal val devicePropertyChangedListener = + object : DeviceConfig.OnPropertyChangedListener { + override fun onPropertyChanged(namespace: String, name: String, value: String?) { + if (DeviceConfig.NAMESPACE_PRIVACY.equals(namespace) && + SystemUiDeviceConfigFlags.PROPERTY_PERMISSIONS_HUB_ENABLED.equals(name)) { + indicatorsAvailable = java.lang.Boolean.parseBoolean(value) + messageHandler.removeMessages(MSG_UPDATE_LISTENING_STATE) + messageHandler.sendEmptyMessage(MSG_UPDATE_LISTENING_STATE) + } + } + } + + private val cb = object : AppOpsController.Callback { + override fun onActiveStateChanged( + code: Int, + uid: Int, + packageName: String, + active: Boolean + ) { + val userId = UserHandle.getUserId(uid) + if (userId in currentUserIds) { + update(false) + } + } + } + + @VisibleForTesting + internal var userSwitcherReceiver = Receiver() + set(value) { + context.unregisterReceiver(field) + field = value + registerReceiver() + } + + init { + DeviceConfig.addOnPropertyChangedListener( + DeviceConfig.NAMESPACE_PRIVACY, context.mainExecutor, devicePropertyChangedListener) + } + + private fun unregisterReceiver() { + context.unregisterReceiver(userSwitcherReceiver) + } + + private fun registerReceiver() { + context.registerReceiverAsUser(userSwitcherReceiver, UserHandle.ALL, IntentFilter().apply { + intents.forEach { + addAction(it) + } + }, null, null) + } + + private fun update(updateUsers: Boolean) { + if (updateUsers) { + val currentUser = ActivityManager.getCurrentUser() + currentUserIds = userManager.getProfiles(currentUser).map { it.id } + } + bgHandler.post(updateListAndNotifyChanges) + } + + /** + * Updates listening status based on whether there are callbacks and the indicators are enabled + * + * This is only called from private (add/remove)Callback and from the config listener, all in + * main thread. + */ + private fun setListeningState() { + val listen = !callbacks.isEmpty() and indicatorsAvailable + if (listening == listen) return + listening = listen + if (listening) { + appOpsController.addCallback(OPS, cb) + registerReceiver() + update(true) + } else { + appOpsController.removeCallback(OPS, cb) + unregisterReceiver() + // Make sure that we remove all indicators and notify listeners if we are not + // listening anymore due to indicators being disabled + update(false) + } + } + + private fun addCallback(callback: WeakReference) { + callbacks.add(callback) + if (callbacks.isNotEmpty() && !listening) { + messageHandler.removeMessages(MSG_UPDATE_LISTENING_STATE) + messageHandler.sendEmptyMessage(MSG_UPDATE_LISTENING_STATE) + } + // Notify this callback if we didn't set to listening + else if (listening) uiHandler.post(NotifyChangesToCallback(callback.get(), privacyList)) + } + + private fun removeCallback(callback: WeakReference) { + // Removes also if the callback is null + callbacks.removeIf { it.get()?.equals(callback.get()) ?: true } + if (callbacks.isEmpty()) { + messageHandler.removeMessages(MSG_UPDATE_LISTENING_STATE) + messageHandler.sendEmptyMessage(MSG_UPDATE_LISTENING_STATE) + } + } + + fun addCallback(callback: Callback) { + messageHandler.obtainMessage(MSG_ADD_CALLBACK, callback).sendToTarget() + } + + fun removeCallback(callback: Callback) { + messageHandler.obtainMessage(MSG_REMOVE_CALLBACK, callback).sendToTarget() + } + + private fun updatePrivacyList() { + if (!listening) { + privacyList = emptyList() + return + } + val list = currentUserIds.flatMap { appOpsController.getActiveAppOpsForUser(it) } + .mapNotNull { toPrivacyItem(it) }.distinct() + privacyList = list + } + + private fun toPrivacyItem(appOpItem: AppOpItem): PrivacyItem? { + val type: PrivacyType = when (appOpItem.code) { + AppOpsManager.OP_CAMERA -> PrivacyType.TYPE_CAMERA + AppOpsManager.OP_COARSE_LOCATION -> PrivacyType.TYPE_LOCATION + AppOpsManager.OP_FINE_LOCATION -> PrivacyType.TYPE_LOCATION + AppOpsManager.OP_RECORD_AUDIO -> PrivacyType.TYPE_MICROPHONE + else -> return null + } + if (appOpItem.uid == SYSTEM_UID) return PrivacyItem(type, systemApp) + val app = PrivacyApplication(appOpItem.packageName, appOpItem.uid, context) + return PrivacyItem(type, app) + } + + // Used by containing class to get notified of changes + interface Callback { + fun privacyChanged(privacyItems: List) + } + + internal inner class Receiver : BroadcastReceiver() { + override fun onReceive(context: Context?, intent: Intent?) { + if (intent?.action in intents) { + update(true) + } + } + } + + private class NotifyChangesToCallback( + private val callback: Callback?, + private val list: List + ) : Runnable { + override fun run() { + callback?.privacyChanged(list) + } + } + + override fun dump(fd: FileDescriptor?, pw: PrintWriter?, args: Array?) { + pw?.println("PrivacyItemController state:") + pw?.println(" Listening: $listening") + pw?.println(" Current user ids: $currentUserIds") + pw?.println(" Privacy Items:") + privacyList.forEach { + pw?.print(" ") + pw?.println(it.toString()) + } + pw?.println(" Callbacks:") + callbacks.forEach { + it.get()?.let { + pw?.print(" ") + pw?.println(it.toString()) + } + } + } + + private class H( + private val outerClass: WeakReference, + looper: Looper + ) : Handler(looper) { + override fun handleMessage(msg: Message) { + super.handleMessage(msg) + when (msg.what) { + MSG_UPDATE_LISTENING_STATE -> outerClass.get()?.setListeningState() + + MSG_ADD_CALLBACK -> { + if (msg.obj !is PrivacyItemController.Callback) return + outerClass.get()?.addCallback( + WeakReference(msg.obj as PrivacyItemController.Callback)) + } + + MSG_REMOVE_CALLBACK -> { + if (msg.obj !is PrivacyItemController.Callback) return + outerClass.get()?.removeCallback( + WeakReference(msg.obj as PrivacyItemController.Callback)) + } + else -> {} + } + } + } +} \ No newline at end of file diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java index a28b60dbe13..66dabdbf773 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java @@ -32,24 +32,30 @@ import android.graphics.Rect; import android.media.AudioManager; import android.os.Handler; +import android.os.Looper; import android.provider.AlarmClock; +import android.provider.DeviceConfig; import android.provider.Settings; import android.service.notification.ZenModeConfig; import android.text.format.DateUtils; import android.util.AttributeSet; import android.util.Log; import android.util.Pair; +import android.util.StatsLog; import android.view.ContextThemeWrapper; import android.view.DisplayCutout; import android.view.View; import android.view.WindowInsets; import android.widget.FrameLayout; import android.widget.ImageView; +import android.widget.LinearLayout; import android.widget.RelativeLayout; +import android.widget.Space; import android.widget.TextView; import androidx.annotation.VisibleForTesting; +import com.android.internal.config.sysui.SystemUiDeviceConfigFlags; import com.android.settingslib.Utils; import com.android.systemui.BatteryMeterView; import com.android.systemui.DualToneHandler; @@ -57,6 +63,11 @@ import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.plugins.DarkIconDispatcher; import com.android.systemui.plugins.DarkIconDispatcher.DarkReceiver; +import com.android.systemui.privacy.OngoingPrivacyChip; +import com.android.systemui.privacy.PrivacyDialogBuilder; +import com.android.systemui.privacy.PrivacyItem; +import com.android.systemui.privacy.PrivacyItemController; +import com.android.systemui.privacy.PrivacyItemControllerKt; import com.android.systemui.qs.QSDetail.Callback; import com.android.systemui.statusbar.phone.PhoneStatusBarView; import com.android.systemui.statusbar.phone.StatusBarIconController; @@ -67,6 +78,8 @@ import com.android.systemui.statusbar.policy.NextAlarmController; import com.android.systemui.statusbar.policy.ZenModeController; +import java.util.ArrayList; +import java.util.List; import java.util.Locale; import java.util.Objects; @@ -108,6 +121,7 @@ public class QuickStatusBarHeader extends RelativeLayout implements private TintedIconManager mIconManager; private TouchAnimator mStatusIconsAlphaAnimator; private TouchAnimator mHeaderTextContainerAlphaAnimator; + private TouchAnimator mPrivacyChipAlphaAnimator; private DualToneHandler mDualToneHandler; private View mSystemIconsView; @@ -127,7 +141,12 @@ public class QuickStatusBarHeader extends RelativeLayout implements private View mRingerContainer; private Clock mClockView; private DateView mDateView; + private OngoingPrivacyChip mPrivacyChip; + private Space mSpace; private BatteryMeterView mBatteryRemainingIcon; + private boolean mPermissionsHubEnabled; + + private PrivacyItemController mPrivacyItemController; private final BroadcastReceiver mRingerReceiver = new BroadcastReceiver() { @Override @@ -137,17 +156,41 @@ public void onReceive(Context context, Intent intent) { } }; private boolean mHasTopCutout = false; + private boolean mPrivacyChipLogged = false; + + private final DeviceConfig.OnPropertyChangedListener mPropertyListener = + new DeviceConfig.OnPropertyChangedListener() { + @Override + public void onPropertyChanged(String namespace, String name, String value) { + if (DeviceConfig.NAMESPACE_PRIVACY.equals(namespace) + && SystemUiDeviceConfigFlags.PROPERTY_PERMISSIONS_HUB_ENABLED.equals( + name)) { + mPermissionsHubEnabled = Boolean.valueOf(value); + StatusIconContainer iconContainer = findViewById(R.id.statusIcons); + iconContainer.setIgnoredSlots(getIgnoredIconSlots()); + } + } + }; + + private PrivacyItemController.Callback mPICCallback = new PrivacyItemController.Callback() { + @Override + public void privacyChanged(List privacyItems) { + mPrivacyChip.setPrivacyList(privacyItems); + setChipVisibility(!privacyItems.isEmpty()); + } + }; @Inject public QuickStatusBarHeader(@Named(VIEW_CONTEXT) Context context, AttributeSet attrs, NextAlarmController nextAlarmController, ZenModeController zenModeController, StatusBarIconController statusBarIconController, - ActivityStarter activityStarter) { + ActivityStarter activityStarter, PrivacyItemController privacyItemController) { super(context, attrs); mAlarmController = nextAlarmController; mZenController = zenModeController; mStatusBarIconController = statusBarIconController; mActivityStarter = activityStarter; + mPrivacyItemController = privacyItemController; mDualToneHandler = new DualToneHandler( new ContextThemeWrapper(context, R.style.QSHeaderTheme)); } @@ -160,6 +203,8 @@ protected void onFinishInflate() { mSystemIconsView = findViewById(R.id.quick_status_bar_system_icons); mQuickQsStatusIcons = findViewById(R.id.quick_qs_status_icons); StatusIconContainer iconContainer = findViewById(R.id.statusIcons); + // Ignore privacy icons because they show in the space above QQS + iconContainer.addIgnoredSlots(getIgnoredIconSlots()); iconContainer.setShouldRestrictIcons(false); mIconManager = new TintedIconManager(iconContainer); @@ -173,6 +218,9 @@ protected void onFinishInflate() { mRingerModeIcon = findViewById(R.id.ringer_mode_icon); mRingerModeTextView = findViewById(R.id.ringer_mode_text); mRingerContainer = findViewById(R.id.ringer_container); + mRingerContainer.setOnClickListener(this::onClick); + mPrivacyChip = findViewById(R.id.privacy_chip); + mPrivacyChip.setOnClickListener(this::onClick); mCarrierGroup = findViewById(R.id.carrier_group); @@ -195,6 +243,7 @@ protected void onFinishInflate() { mClockView = findViewById(R.id.clock); mClockView.setOnClickListener(this); mDateView = findViewById(R.id.date); + mSpace = findViewById(R.id.space); // Tint for the battery icons are handled in setupHost() mBatteryRemainingIcon = findViewById(R.id.batteryRemainingIcon); @@ -205,6 +254,25 @@ protected void onFinishInflate() { mBatteryRemainingIcon.setPercentShowMode(BatteryMeterView.MODE_ESTIMATE); mRingerModeTextView.setSelected(true); mNextAlarmTextView.setSelected(true); + + mPermissionsHubEnabled = PrivacyItemControllerKt.isPermissionsHubEnabled(); + // Change the ignored slots when DeviceConfig flag changes + DeviceConfig.addOnPropertyChangedListener(DeviceConfig.NAMESPACE_PRIVACY, + mContext.getMainExecutor(), mPropertyListener); + } + + private List getIgnoredIconSlots() { + ArrayList ignored = new ArrayList<>(); + ignored.add(mContext.getResources().getString( + com.android.internal.R.string.status_bar_camera)); + ignored.add(mContext.getResources().getString( + com.android.internal.R.string.status_bar_microphone)); + if (mPermissionsHubEnabled) { + ignored.add(mContext.getResources().getString( + com.android.internal.R.string.status_bar_location)); + } + + return ignored; } private void updateStatusText() { @@ -218,6 +286,21 @@ private void updateStatusText() { } } + private void setChipVisibility(boolean chipVisible) { + if (chipVisible && mPermissionsHubEnabled) { + mPrivacyChip.setVisibility(View.VISIBLE); + // Makes sure that the chip is logged as viewed at most once each time QS is opened + // mListening makes sure that the callback didn't return after the user closed QS + if (!mPrivacyChipLogged && mListening) { + mPrivacyChipLogged = true; + StatsLog.write(StatsLog.PRIVACY_INDICATORS_INTERACTED, + StatsLog.PRIVACY_INDICATORS_INTERACTED__TYPE__CHIP_VIEWED); + } + } else { + mPrivacyChip.setVisibility(View.GONE); + } + } + private boolean updateRingerStatus() { boolean isOriginalVisible = mRingerModeTextView.getVisibility() == View.VISIBLE; CharSequence originalRingerText = mRingerModeTextView.getText(); @@ -324,6 +407,7 @@ private void updateResources() { updateStatusIconAlphaAnimator(); updateHeaderTextContainerAlphaAnimator(); + updatePrivacyChipAlphaAnimator(); } private void updateStatusIconAlphaAnimator() { @@ -338,6 +422,12 @@ private void updateHeaderTextContainerAlphaAnimator() { .build(); } + private void updatePrivacyChipAlphaAnimator() { + mPrivacyChipAlphaAnimator = new TouchAnimator.Builder() + .addFloat(mPrivacyChip, "alpha", 1, 0, 1) + .build(); + } + public void setExpanded(boolean expanded) { if (mExpanded == expanded) return; mExpanded = expanded; @@ -376,6 +466,10 @@ public void setExpansion(boolean forceExpanded, float expansionFraction, mHeaderTextContainerView.setVisibility(INVISIBLE); } } + if (mPrivacyChipAlphaAnimator != null) { + mPrivacyChip.setExpanded(expansionFraction > 0.5); + mPrivacyChipAlphaAnimator.setPosition(keyguardExpansionFraction); + } } public void disable(int state1, int state2, boolean animate) { @@ -408,6 +502,21 @@ public WindowInsets onApplyWindowInsets(WindowInsets insets) { mSystemIconsView.setPadding(padding.first, 0, padding.second, 0); } + LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) mSpace.getLayoutParams(); + if (cutout != null) { + Rect topCutout = cutout.getBoundingRectTop(); + if (topCutout.isEmpty()) { + mHasTopCutout = false; + lp.width = 0; + mSpace.setVisibility(View.GONE); + } else { + mHasTopCutout = true; + lp.width = topCutout.width(); + mSpace.setVisibility(View.VISIBLE); + } + } + mSpace.setLayoutParams(lp); + setChipVisibility(mPrivacyChip.getVisibility() == View.VISIBLE); return super.onApplyWindowInsets(insets); } @@ -432,10 +541,13 @@ public void setListening(boolean listening) { mAlarmController.addCallback(this); mContext.registerReceiver(mRingerReceiver, new IntentFilter(AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION)); + mPrivacyItemController.addCallback(mPICCallback); } else { mZenController.removeCallback(this); mAlarmController.removeCallback(this); + mPrivacyItemController.removeCallback(mPICCallback); mContext.unregisterReceiver(mRingerReceiver); + mPrivacyChipLogged = false; } } @@ -453,6 +565,18 @@ public void onClick(View v) { mActivityStarter.postStartActivityDismissingKeyguard(new Intent( AlarmClock.ACTION_SHOW_ALARMS), 0); } + } else if (v == mPrivacyChip) { + // Makes sure that the builder is grabbed as soon as the chip is pressed + PrivacyDialogBuilder builder = mPrivacyChip.getBuilder(); + if (builder.getAppsAndTypes().size() == 0) return; + Handler mUiHandler = new Handler(Looper.getMainLooper()); + StatsLog.write(StatsLog.PRIVACY_INDICATORS_INTERACTED, + StatsLog.PRIVACY_INDICATORS_INTERACTED__TYPE__CHIP_CLICKED); + mUiHandler.post(() -> { + mActivityStarter.postStartActivityDismissingKeyguard( + new Intent(Intent.ACTION_REVIEW_ONGOING_PERMISSION_USAGE), 0); + mHost.collapsePanels(); + }); } else if (v == mRingerContainer && mRingerContainer.isVisibleToUser()) { mActivityStarter.postStartActivityDismissingKeyguard(new Intent( Settings.ACTION_SOUND_SETTINGS), 0); 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 1c7bbb4bb8f..72defae3b0a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java @@ -43,6 +43,10 @@ import com.android.systemui.R; import com.android.systemui.SysUiServiceProvider; import com.android.systemui.UiOffloadThread; +import com.android.systemui.privacy.PrivacyItem; +import com.android.systemui.privacy.PrivacyItemController; +import com.android.systemui.privacy.PrivacyItemControllerKt; +import com.android.systemui.privacy.PrivacyType; import com.android.systemui.qs.tiles.DndTile; import com.android.systemui.qs.tiles.RotationLockTile; import com.android.systemui.statusbar.CommandQueue; @@ -63,6 +67,9 @@ import com.android.systemui.statusbar.policy.UserInfoController; import com.android.systemui.statusbar.policy.ZenModeController; +import java.io.PrintWriter; +import java.io.StringWriter; +import java.util.List; import java.util.Locale; /** @@ -77,12 +84,12 @@ public class PhoneStatusBarPolicy ZenModeController.Callback, DeviceProvisionedListener, KeyguardMonitor.Callback, + PrivacyItemController.Callback, LocationController.LocationChangeCallback { private static final String TAG = "PhoneStatusBarPolicy"; private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); - public static final int LOCATION_STATUS_ICON_ID = - com.android.internal.R.drawable.perm_group_location; + public static final int LOCATION_STATUS_ICON_ID = PrivacyType.TYPE_LOCATION.getIconId(); private final String mSlotCast; private final String mSlotHotspot; @@ -96,6 +103,8 @@ public class PhoneStatusBarPolicy private final String mSlotHeadset; private final String mSlotDataSaver; private final String mSlotLocation; + private final String mSlotMicrophone; + private final String mSlotCamera; private final String mSlotSensorsOff; private final Context mContext; @@ -113,6 +122,7 @@ public class PhoneStatusBarPolicy private final DeviceProvisionedController mProvisionedController; private final KeyguardMonitor mKeyguardMonitor; private final LocationController mLocationController; + private final PrivacyItemController mPrivacyItemController; private final UiOffloadThread mUiOffloadThread = Dependency.get(UiOffloadThread.class); private final SensorPrivacyController mSensorPrivacyController; @@ -146,6 +156,7 @@ public PhoneStatusBarPolicy(Context context, StatusBarIconController iconControl mProvisionedController = Dependency.get(DeviceProvisionedController.class); mKeyguardMonitor = Dependency.get(KeyguardMonitor.class); mLocationController = Dependency.get(LocationController.class); + mPrivacyItemController = Dependency.get(PrivacyItemController.class); mSensorPrivacyController = Dependency.get(SensorPrivacyController.class); mSlotCast = context.getString(com.android.internal.R.string.status_bar_cast); @@ -161,6 +172,8 @@ public PhoneStatusBarPolicy(Context context, StatusBarIconController iconControl mSlotHeadset = context.getString(com.android.internal.R.string.status_bar_headset); mSlotDataSaver = context.getString(com.android.internal.R.string.status_bar_data_saver); mSlotLocation = context.getString(com.android.internal.R.string.status_bar_location); + mSlotMicrophone = context.getString(com.android.internal.R.string.status_bar_microphone); + mSlotCamera = context.getString(com.android.internal.R.string.status_bar_camera); mSlotSensorsOff = context.getString(com.android.internal.R.string.status_bar_sensors_off); // listen for broadcasts @@ -221,6 +234,13 @@ public PhoneStatusBarPolicy(Context context, StatusBarIconController iconControl context.getString(R.string.accessibility_data_saver_on)); mIconController.setIconVisibility(mSlotDataSaver, false); + // privacy items + mIconController.setIcon(mSlotMicrophone, PrivacyType.TYPE_MICROPHONE.getIconId(), + PrivacyType.TYPE_MICROPHONE.getName(mContext)); + mIconController.setIconVisibility(mSlotMicrophone, false); + mIconController.setIcon(mSlotCamera, PrivacyType.TYPE_CAMERA.getIconId(), + PrivacyType.TYPE_CAMERA.getName(mContext)); + mIconController.setIconVisibility(mSlotCamera, false); mIconController.setIcon(mSlotLocation, LOCATION_STATUS_ICON_ID, mContext.getString(R.string.accessibility_location_active)); mIconController.setIconVisibility(mSlotLocation, false); @@ -240,6 +260,7 @@ public PhoneStatusBarPolicy(Context context, StatusBarIconController iconControl mNextAlarmController.addCallback(mNextAlarmCallback); mDataSaver.addCallback(this); mKeyguardMonitor.addCallback(this); + mPrivacyItemController.addCallback(this); mSensorPrivacyController.addCallback(mSensorPrivacyListener); mLocationController.addCallback(this); @@ -584,9 +605,46 @@ public void onDataSaverChanged(boolean isDataSaving) { mIconController.setIconVisibility(mSlotDataSaver, isDataSaving); } + @Override // PrivacyItemController.Callback + public void privacyChanged(List privacyItems) { + updatePrivacyItems(privacyItems); + } + + private void updatePrivacyItems(List items) { + boolean showCamera = false; + boolean showMicrophone = false; + boolean showLocation = false; + for (PrivacyItem item : items) { + if (item == null /* b/124234367 */) { + if (DEBUG) { + Log.e(TAG, "updatePrivacyItems - null item found"); + StringWriter out = new StringWriter(); + mPrivacyItemController.dump(null, new PrintWriter(out), null); + Log.e(TAG, out.toString()); + } + continue; + } + switch (item.getPrivacyType()) { + case TYPE_CAMERA: + showCamera = true; + break; + case TYPE_LOCATION: + showLocation = true; + break; + case TYPE_MICROPHONE: + showMicrophone = true; + break; + } + } + + mIconController.setIconVisibility(mSlotCamera, showCamera); + mIconController.setIconVisibility(mSlotMicrophone, showMicrophone); + mIconController.setIconVisibility(mSlotLocation, showLocation); + } + @Override public void onLocationActiveChanged(boolean active) { - updateLocation(); + if (!PrivacyItemControllerKt.isPermissionsHubEnabled()) updateLocation(); } // Updates the status view based on the current state of location requests. diff --git a/packages/SystemUI/tests/src/com/android/systemui/appops/AppOpsControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/appops/AppOpsControllerTest.java index 59d5c243af7..39f8a2d1894 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/appops/AppOpsControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/appops/AppOpsControllerTest.java @@ -24,9 +24,11 @@ import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; import android.app.AppOpsManager; import android.content.pm.PackageManager; @@ -52,6 +54,7 @@ public class AppOpsControllerTest extends SysuiTestCase { private static final String TEST_PACKAGE_NAME = "test"; private static final int TEST_UID = UserHandle.getUid(0, 0); private static final int TEST_UID_OTHER = UserHandle.getUid(1, 0); + private static final int TEST_UID_NON_USER_SENSITIVE = UserHandle.getUid(2, 0); @Mock private AppOpsManager mAppOpsManager; @@ -70,6 +73,18 @@ public void setUp() { getContext().addMockSystemService(AppOpsManager.class, mAppOpsManager); + // All permissions of TEST_UID and TEST_UID_OTHER are user sensitive. None of + // TEST_UID_NON_USER_SENSITIVE are user sensitive. + getContext().setMockPackageManager(mPackageManager); + when(mPackageManager.getPermissionFlags(anyString(), anyString(), + eq(UserHandle.getUserHandleForUid(TEST_UID)))).thenReturn( + PackageManager.FLAG_PERMISSION_USER_SENSITIVE_WHEN_GRANTED); + when(mPackageManager.getPermissionFlags(anyString(), anyString(), + eq(UserHandle.getUserHandleForUid(TEST_UID_OTHER)))).thenReturn( + PackageManager.FLAG_PERMISSION_USER_SENSITIVE_WHEN_GRANTED); + when(mPackageManager.getPermissionFlags(anyString(), anyString(), + eq(UserHandle.getUserHandleForUid(TEST_UID_NON_USER_SENSITIVE)))).thenReturn(0); + mController = new AppOpsControllerImpl(mContext, Dependency.get(Dependency.BG_LOOPER)); } @@ -161,6 +176,14 @@ public void getActiveItemsForUser() { mController.getActiveAppOpsForUser(UserHandle.getUserId(TEST_UID_OTHER)).size()); } + @Test + public void nonUserSensitiveOpsAreIgnored() { + mController.onOpActiveChanged(AppOpsManager.OP_RECORD_AUDIO, + TEST_UID_NON_USER_SENSITIVE, TEST_PACKAGE_NAME, true); + assertEquals(0, mController.getActiveAppOpsForUser( + UserHandle.getUserId(TEST_UID_NON_USER_SENSITIVE)).size()); + } + @Test public void opNotedScheduledForRemoval() { mController.setBGHandler(mMockHandler); diff --git a/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyDialogBuilderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyDialogBuilderTest.kt new file mode 100644 index 00000000000..6302f9d56dc --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyDialogBuilderTest.kt @@ -0,0 +1,77 @@ +/* + * 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.privacy + +import androidx.test.filters.SmallTest +import androidx.test.runner.AndroidJUnit4 +import com.android.systemui.SysuiTestCase +import org.junit.Assert.assertEquals +import org.junit.Test +import org.junit.runner.RunWith + +@RunWith(AndroidJUnit4::class) +@SmallTest +class PrivacyDialogBuilderTest : SysuiTestCase() { + + companion object { + val TEST_UID = 1 + } + + @Test + fun testGenerateAppsList() { + val bar2 = PrivacyItem(Privacy.TYPE_CAMERA, PrivacyApplication( + "Bar", TEST_UID, context)) + val bar3 = PrivacyItem(Privacy.TYPE_LOCATION, PrivacyApplication( + "Bar", TEST_UID, context)) + val foo0 = PrivacyItem(Privacy.TYPE_MICROPHONE, PrivacyApplication( + "Foo", TEST_UID, context)) + val baz1 = PrivacyItem(Privacy.TYPE_CAMERA, PrivacyApplication( + "Baz", TEST_UID, context)) + + val items = listOf(bar2, foo0, baz1, bar3) + + val textBuilder = PrivacyDialogBuilder(context, items) + + val list = textBuilder.appsAndTypes + assertEquals(3, list.size) + val appsList = list.map { it.first } + val typesList = list.map { it.second } + // List is sorted by number of types and then by types + assertEquals(listOf("Bar", "Baz", "Foo"), appsList.map { it.packageName }) + assertEquals(listOf(Privacy.TYPE_CAMERA, Privacy.TYPE_LOCATION), typesList[0]) + assertEquals(listOf(Privacy.TYPE_CAMERA), typesList[1]) + assertEquals(listOf(Privacy.TYPE_MICROPHONE), typesList[2]) + } + + @Test + fun testOrder() { + // We want location to always go last, so it will go in the "+ other apps" + val appCamera = PrivacyItem(PrivacyType.TYPE_CAMERA, + PrivacyApplication("Camera", TEST_UID, context)) + val appMicrophone = + PrivacyItem(PrivacyType.TYPE_MICROPHONE, + PrivacyApplication("Microphone", TEST_UID, context)) + val appLocation = + PrivacyItem(PrivacyType.TYPE_LOCATION, + PrivacyApplication("Location", TEST_UID, context)) + + val items = listOf(appLocation, appMicrophone, appCamera) + val textBuilder = PrivacyDialogBuilder(context, items) + val appList = textBuilder.appsAndTypes.map { it.first }.map { it.packageName } + assertEquals(listOf("Camera", "Microphone", "Location"), appList) + } +} \ No newline at end of file diff --git a/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyItemControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyItemControllerTest.kt new file mode 100644 index 00000000000..e2e0bb15122 --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyItemControllerTest.kt @@ -0,0 +1,293 @@ +/* + * 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.privacy + +import android.app.ActivityManager +import android.app.AppOpsManager +import android.content.Context +import android.content.Intent +import android.content.pm.UserInfo +import android.os.Handler +import android.os.UserHandle +import android.os.UserManager +import android.provider.DeviceConfig +import android.provider.Settings.RESET_MODE_PACKAGE_DEFAULTS +import android.testing.AndroidTestingRunner +import android.testing.TestableLooper +import android.testing.TestableLooper.RunWithLooper +import androidx.test.filters.SmallTest +import com.android.internal.config.sysui.SystemUiDeviceConfigFlags +import com.android.systemui.Dependency +import com.android.systemui.R +import com.android.systemui.SysuiTestCase +import com.android.systemui.appops.AppOpItem +import com.android.systemui.appops.AppOpsController +import org.hamcrest.Matchers.hasItem +import org.hamcrest.Matchers.not +import org.hamcrest.Matchers.nullValue +import org.junit.After +import org.junit.Assert.assertEquals +import org.junit.Assert.assertThat +import org.junit.Assert.assertTrue +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.ArgumentCaptor +import org.mockito.ArgumentMatchers.any +import org.mockito.ArgumentMatchers.anyInt +import org.mockito.ArgumentMatchers.anyList +import org.mockito.ArgumentMatchers.eq +import org.mockito.Captor +import org.mockito.Mock +import org.mockito.Mockito.atLeastOnce +import org.mockito.Mockito.doReturn +import org.mockito.Mockito.mock +import org.mockito.Mockito.never +import org.mockito.Mockito.reset +import org.mockito.Mockito.spy +import org.mockito.Mockito.verify +import org.mockito.Mockito.verifyNoMoreInteractions +import org.mockito.MockitoAnnotations + +@RunWith(AndroidTestingRunner::class) +@SmallTest +@RunWithLooper +class PrivacyItemControllerTest : SysuiTestCase() { + + companion object { + val CURRENT_USER_ID = ActivityManager.getCurrentUser() + val TEST_UID = CURRENT_USER_ID * UserHandle.PER_USER_RANGE + const val SYSTEM_UID = 1000 + const val TEST_PACKAGE_NAME = "test" + const val DEVICE_SERVICES_STRING = "Device services" + const val TAG = "PrivacyItemControllerTest" + fun capture(argumentCaptor: ArgumentCaptor): T = argumentCaptor.capture() + } + + @Mock + private lateinit var appOpsController: AppOpsController + @Mock + private lateinit var callback: PrivacyItemController.Callback + @Mock + private lateinit var userManager: UserManager + @Captor + private lateinit var argCaptor: ArgumentCaptor> + @Captor + private lateinit var argCaptorCallback: ArgumentCaptor + + private lateinit var testableLooper: TestableLooper + private lateinit var privacyItemController: PrivacyItemController + private lateinit var handler: Handler + + fun PrivacyItemController(context: Context) = + PrivacyItemController(context, appOpsController, handler, handler) + + @Before + fun setup() { + MockitoAnnotations.initMocks(this) + testableLooper = TestableLooper.get(this) + handler = Handler(testableLooper.looper) + + appOpsController = mDependency.injectMockDependency(AppOpsController::class.java) + mDependency.injectTestDependency(Dependency.BG_HANDLER, handler) + mDependency.injectTestDependency(Dependency.MAIN_HANDLER, handler) + mContext.addMockSystemService(UserManager::class.java, userManager) + mContext.getOrCreateTestableResources().addOverride(R.string.device_services, + DEVICE_SERVICES_STRING) + DeviceConfig.setProperty(DeviceConfig.NAMESPACE_PRIVACY, + SystemUiDeviceConfigFlags.PROPERTY_PERMISSIONS_HUB_ENABLED, + "true", false) + + doReturn(listOf(object : UserInfo() { + init { + id = CURRENT_USER_ID + } + })).`when`(userManager).getProfiles(anyInt()) + + privacyItemController = PrivacyItemController(mContext) + } + + @After + fun tearDown() { + DeviceConfig.resetToDefaults(RESET_MODE_PACKAGE_DEFAULTS, DeviceConfig.NAMESPACE_PRIVACY) + } + + @Test + fun testSetListeningTrueByAddingCallback() { + privacyItemController.addCallback(callback) + testableLooper.processAllMessages() + verify(appOpsController).addCallback(eq(PrivacyItemController.OPS), + any(AppOpsController.Callback::class.java)) + testableLooper.processAllMessages() + verify(callback).privacyChanged(anyList()) + } + + @Test + fun testSetListeningFalseByRemovingLastCallback() { + privacyItemController.addCallback(callback) + testableLooper.processAllMessages() + verify(appOpsController, never()).removeCallback(any(IntArray::class.java), + any(AppOpsController.Callback::class.java)) + privacyItemController.removeCallback(callback) + testableLooper.processAllMessages() + verify(appOpsController).removeCallback(eq(PrivacyItemController.OPS), + any(AppOpsController.Callback::class.java)) + verify(callback).privacyChanged(emptyList()) + } + + @Test + fun testDistinctItems() { + doReturn(listOf(AppOpItem(AppOpsManager.OP_CAMERA, TEST_UID, "", 0), + AppOpItem(AppOpsManager.OP_CAMERA, TEST_UID, "", 1))) + .`when`(appOpsController).getActiveAppOpsForUser(anyInt()) + + privacyItemController.addCallback(callback) + testableLooper.processAllMessages() + verify(callback).privacyChanged(capture(argCaptor)) + assertEquals(1, argCaptor.value.size) + } + + @Test + fun testSystemApps() { + doReturn(listOf(AppOpItem(AppOpsManager.OP_COARSE_LOCATION, SYSTEM_UID, TEST_PACKAGE_NAME, + 0))).`when`(appOpsController).getActiveAppOpsForUser(anyInt()) + privacyItemController.addCallback(callback) + testableLooper.processAllMessages() + verify(callback).privacyChanged(capture(argCaptor)) + assertEquals(1, argCaptor.value.size) + assertEquals(context.getString(R.string.device_services), + argCaptor.value[0].application.applicationName) + } + + @Test + fun testRegisterReceiver_allUsers() { + val spiedContext = spy(mContext) + val itemController = PrivacyItemController(spiedContext) + itemController.addCallback(callback) + testableLooper.processAllMessages() + verify(spiedContext, atLeastOnce()).registerReceiverAsUser( + eq(itemController.userSwitcherReceiver), eq(UserHandle.ALL), any(), eq(null), + eq(null)) + verify(spiedContext, never()).unregisterReceiver(eq(itemController.userSwitcherReceiver)) + } + + @Test + fun testReceiver_ACTION_USER_FOREGROUND() { + privacyItemController.userSwitcherReceiver.onReceive(context, + Intent(Intent.ACTION_USER_FOREGROUND)) + verify(userManager).getProfiles(anyInt()) + } + + @Test + fun testReceiver_ACTION_MANAGED_PROFILE_ADDED() { + privacyItemController.userSwitcherReceiver.onReceive(context, + Intent(Intent.ACTION_MANAGED_PROFILE_ADDED)) + verify(userManager).getProfiles(anyInt()) + } + + @Test + fun testReceiver_ACTION_MANAGED_PROFILE_REMOVED() { + privacyItemController.userSwitcherReceiver.onReceive(context, + Intent(Intent.ACTION_MANAGED_PROFILE_REMOVED)) + verify(userManager).getProfiles(anyInt()) + } + + @Test + fun testAddMultipleCallbacks() { + val otherCallback = mock(PrivacyItemController.Callback::class.java) + privacyItemController.addCallback(callback) + testableLooper.processAllMessages() + verify(callback).privacyChanged(anyList()) + + privacyItemController.addCallback(otherCallback) + testableLooper.processAllMessages() + verify(otherCallback).privacyChanged(anyList()) + // Adding a callback should not unnecessarily call previous ones + verifyNoMoreInteractions(callback) + } + + @Test + fun testMultipleCallbacksAreUpdated() { + doReturn(emptyList()).`when`(appOpsController).getActiveAppOpsForUser(anyInt()) + + val otherCallback = mock(PrivacyItemController.Callback::class.java) + privacyItemController.addCallback(callback) + privacyItemController.addCallback(otherCallback) + testableLooper.processAllMessages() + reset(callback) + reset(otherCallback) + + verify(appOpsController).addCallback(any(), capture(argCaptorCallback)) + argCaptorCallback.value.onActiveStateChanged(0, TEST_UID, "", true) + testableLooper.processAllMessages() + verify(callback).privacyChanged(anyList()) + verify(otherCallback).privacyChanged(anyList()) + } + + @Test + fun testRemoveCallback() { + doReturn(emptyList()).`when`(appOpsController).getActiveAppOpsForUser(anyInt()) + val otherCallback = mock(PrivacyItemController.Callback::class.java) + privacyItemController.addCallback(callback) + privacyItemController.addCallback(otherCallback) + testableLooper.processAllMessages() + reset(callback) + reset(otherCallback) + + verify(appOpsController).addCallback(any(), capture(argCaptorCallback)) + privacyItemController.removeCallback(callback) + argCaptorCallback.value.onActiveStateChanged(0, TEST_UID, "", true) + testableLooper.processAllMessages() + verify(callback, never()).privacyChanged(anyList()) + verify(otherCallback).privacyChanged(anyList()) + } + + @Test + fun testListShouldNotHaveNull() { + doReturn(listOf(AppOpItem(AppOpsManager.OP_ACTIVATE_VPN, TEST_UID, "", 0), + AppOpItem(AppOpsManager.OP_COARSE_LOCATION, TEST_UID, "", 0))) + .`when`(appOpsController).getActiveAppOpsForUser(anyInt()) + privacyItemController.addCallback(callback) + testableLooper.processAllMessages() + + verify(callback).privacyChanged(capture(argCaptor)) + assertEquals(1, argCaptor.value.size) + assertThat(argCaptor.value, not(hasItem(nullValue()))) + } + + @Test + fun testListShouldBeCopy() { + val list = listOf(PrivacyItem(PrivacyType.TYPE_CAMERA, + PrivacyApplication("", TEST_UID, mContext))) + privacyItemController.privacyList = list + val privacyList = privacyItemController.privacyList + assertEquals(list, privacyList) + assertTrue(list !== privacyList) + } + + @Test + fun testNotListeningWhenIndicatorsDisabled() { + privacyItemController.devicePropertyChangedListener.onPropertyChanged( + DeviceConfig.NAMESPACE_PRIVACY, + SystemUiDeviceConfigFlags.PROPERTY_PERMISSIONS_HUB_ENABLED, + "false") + privacyItemController.addCallback(callback) + testableLooper.processAllMessages() + verify(appOpsController, never()).addCallback(eq(PrivacyItemController.OPS), + any(AppOpsController.Callback::class.java)) + } +} \ No newline at end of file From 39f6b3dfaef67bd1341fee85cdd3fd3799c24bbd Mon Sep 17 00:00:00 2001 From: Luca Stefani Date: Wed, 4 Sep 2019 17:42:29 +0200 Subject: [PATCH 048/240] PrivacyItemController: Enable permission hub by default Change-Id: I7f3642602c6c5f16dae99dd5608d758fe0f246b4 --- .../src/com/android/systemui/privacy/PrivacyItemController.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItemController.kt b/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItemController.kt index 82a2c1fb43f..01c8cdc307e 100644 --- a/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItemController.kt +++ b/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItemController.kt @@ -44,7 +44,7 @@ import javax.inject.Named import javax.inject.Singleton fun isPermissionsHubEnabled() = DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_PRIVACY, - SystemUiDeviceConfigFlags.PROPERTY_PERMISSIONS_HUB_ENABLED, false) + SystemUiDeviceConfigFlags.PROPERTY_PERMISSIONS_HUB_ENABLED, true) @Singleton class PrivacyItemController @Inject constructor( From 6a7f13a88b2699045d7fc69d635168c7fd9d16ef Mon Sep 17 00:00:00 2001 From: Luca Stefani Date: Wed, 4 Sep 2019 16:49:59 +0200 Subject: [PATCH 049/240] Revert "Drop Type clock face." This reverts commit 583067c4e4799b0a633d8e861698c8fc2a5c7a6f. Change-Id: Ibdb3fca1345a270170b987f6b29f441c726b7cfe --- .../res-keyguard/layout/type_aod_clock.xml | 23 ++ .../res-keyguard/layout/typographic_clock.xml | 26 +++ .../SystemUI/res-keyguard/values/strings.xml | 100 +++++++++ .../android/keyguard/clock/ClockLayout.java | 8 + .../android/keyguard/clock/ClockManager.java | 1 + .../keyguard/clock/TypeClockController.java | 199 ++++++++++++++++++ .../keyguard/clock/TypographicClock.java | 130 ++++++++++++ 7 files changed, 487 insertions(+) create mode 100644 packages/SystemUI/res-keyguard/layout/type_aod_clock.xml create mode 100644 packages/SystemUI/res-keyguard/layout/typographic_clock.xml create mode 100644 packages/SystemUI/src/com/android/keyguard/clock/TypeClockController.java create mode 100644 packages/SystemUI/src/com/android/keyguard/clock/TypographicClock.java diff --git a/packages/SystemUI/res-keyguard/layout/type_aod_clock.xml b/packages/SystemUI/res-keyguard/layout/type_aod_clock.xml new file mode 100644 index 00000000000..28ff5a25331 --- /dev/null +++ b/packages/SystemUI/res-keyguard/layout/type_aod_clock.xml @@ -0,0 +1,23 @@ + + + + + diff --git a/packages/SystemUI/res-keyguard/layout/typographic_clock.xml b/packages/SystemUI/res-keyguard/layout/typographic_clock.xml new file mode 100644 index 00000000000..73bb4b9a0fc --- /dev/null +++ b/packages/SystemUI/res-keyguard/layout/typographic_clock.xml @@ -0,0 +1,26 @@ + + + diff --git a/packages/SystemUI/res-keyguard/values/strings.xml b/packages/SystemUI/res-keyguard/values/strings.xml index 17a7d0835f1..9b781262dc1 100644 --- a/packages/SystemUI/res-keyguard/values/strings.xml +++ b/packages/SystemUI/res-keyguard/values/strings.xml @@ -422,4 +422,104 @@ number">%d remaining attempts before SIM becomes permanently unusable. Analog + + + It\u2019s\n^1\n^2 + It\u2019s\n^1\n^2 + It\u2019s\n^1\n^2 + + + + + Twelve + One + Two + Three + Four + Five + Six + Seven + Eight + Nine + Ten + Eleven + + + + + O\u2019Clock + Oh One + Oh Two + Oh Three + Oh Four + Oh Five + Oh Six + Oh Seven + Oh Eight + Oh Nine + Ten + Eleven + Twelve + Thirteen + Fourteen + Fifteen + Sixteen + Seventeen + Eighteen + Nineteen + Twenty + Twenty\nOne + Twenty\nTwo + Twenty\nThree + Twenty\nFour + Twenty\nFive + Twenty\nSix + Twenty\nSeven + Twenty\nEight + Twenty\nNine + Thirty + Thirty\nOne + Thirty\nTwo + Thirty\nThree + Thirty\nFour + Thirty\nFive + Thirty\nSix + Thirty\nSeven + Thirty\nEight + Thirty\nNine + Forty + Forty\nOne + Forty\nTwo + Forty\nThree + Forty\nFour + Forty\nFive + Forty\nSix + Forty\nSeven + Forty\nEight + Forty\nNine + Fifty + Fifty\nOne + Fifty\nTwo + Fifty\nThree + Fifty\nFour + Fifty\nFive + Fifty\nSix + Fifty\nSeven + Fifty\nEight + Fifty\nNine + + diff --git a/packages/SystemUI/src/com/android/keyguard/clock/ClockLayout.java b/packages/SystemUI/src/com/android/keyguard/clock/ClockLayout.java index d44d89e63e8..ccb495fcec2 100644 --- a/packages/SystemUI/src/com/android/keyguard/clock/ClockLayout.java +++ b/packages/SystemUI/src/com/android/keyguard/clock/ClockLayout.java @@ -37,6 +37,7 @@ public class ClockLayout extends FrameLayout { * Clock face views. */ private View mAnalogClock; + private View mTypeClock; /** * Pixel shifting amplitudes used to prevent screen burn-in. @@ -62,6 +63,7 @@ public ClockLayout(Context context, AttributeSet attrs, int defStyleAttr) { protected void onFinishInflate() { super.onFinishInflate(); mAnalogClock = findViewById(R.id.analog_clock); + mTypeClock = findViewById(R.id.type_clock); // Get pixel shifting X, Y amplitudes from resources. Resources resources = getResources(); @@ -105,5 +107,11 @@ private void positionChildren() { mAnalogClock.setY(Math.max(0f, 0.5f * (getHeight() - mAnalogClock.getHeight())) + ANALOG_CLOCK_SHIFT_FACTOR * offsetY); } + + // Put the typographic clock part way down the screen. + if (mTypeClock != null) { + mTypeClock.setX(offsetX); + mTypeClock.setY(0.2f * getHeight() + offsetY); + } } } diff --git a/packages/SystemUI/src/com/android/keyguard/clock/ClockManager.java b/packages/SystemUI/src/com/android/keyguard/clock/ClockManager.java index 9e2464ea4fb..dafb273a4aa 100644 --- a/packages/SystemUI/src/com/android/keyguard/clock/ClockManager.java +++ b/packages/SystemUI/src/com/android/keyguard/clock/ClockManager.java @@ -150,6 +150,7 @@ public ClockManager(Context context, InjectionInflationController injectionInfla addBuiltinClock(() -> new DefaultClockController(res, layoutInflater, colorExtractor)); addBuiltinClock(() -> new BubbleClockController(res, layoutInflater, colorExtractor)); addBuiltinClock(() -> new AnalogClockController(res, layoutInflater, colorExtractor)); + addBuiltinClock(() -> new TypeClockController(res, layoutInflater, colorExtractor)); // Store the size of the display for generation of clock preview. DisplayMetrics dm = res.getDisplayMetrics(); diff --git a/packages/SystemUI/src/com/android/keyguard/clock/TypeClockController.java b/packages/SystemUI/src/com/android/keyguard/clock/TypeClockController.java new file mode 100644 index 00000000000..1c6b38b18b0 --- /dev/null +++ b/packages/SystemUI/src/com/android/keyguard/clock/TypeClockController.java @@ -0,0 +1,199 @@ +/* + * Copyright (C) 2019 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.keyguard.clock; + +import android.app.WallpaperManager; +import android.content.res.Resources; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.graphics.Color; +import android.graphics.Paint.Style; +import android.view.LayoutInflater; +import android.view.View; + +import com.android.internal.colorextraction.ColorExtractor; +import com.android.keyguard.R; +import com.android.systemui.colorextraction.SysuiColorExtractor; +import com.android.systemui.plugins.ClockPlugin; + +import java.util.TimeZone; + +/** + * Plugin for a custom Typographic clock face that displays the time in words. + */ +public class TypeClockController implements ClockPlugin { + + /** + * Resources used to get title and thumbnail. + */ + private final Resources mResources; + + /** + * LayoutInflater used to inflate custom clock views. + */ + private final LayoutInflater mLayoutInflater; + + /** + * Extracts accent color from wallpaper. + */ + private final SysuiColorExtractor mColorExtractor; + + /** + * Renders preview from clock view. + */ + private final ViewPreviewer mRenderer = new ViewPreviewer(); + + /** + * Custom clock shown on AOD screen and behind stack scroller on lock. + */ + private View mView; + private TypographicClock mTypeClock; + + /** + * Small clock shown on lock screen above stack scroller. + */ + private TypographicClock mLockClock; + + /** + * Controller for transition into dark state. + */ + private CrossFadeDarkController mDarkController; + + /** + * Create a TypeClockController instance. + * + * @param res Resources contains title and thumbnail. + * @param inflater Inflater used to inflate custom clock views. + * @param colorExtractor Extracts accent color from wallpaper. + */ + TypeClockController(Resources res, LayoutInflater inflater, + SysuiColorExtractor colorExtractor) { + mResources = res; + mLayoutInflater = inflater; + mColorExtractor = colorExtractor; + } + + private void createViews() { + mView = mLayoutInflater.inflate(R.layout.type_aod_clock, null); + mTypeClock = mView.findViewById(R.id.type_clock); + + // For now, this view is used to hide the default digital clock. + // Need better transition to lock screen. + mLockClock = (TypographicClock) mLayoutInflater.inflate(R.layout.typographic_clock, null); + mLockClock.setVisibility(View.GONE); + + mDarkController = new CrossFadeDarkController(mView, mLockClock); + } + + @Override + public void onDestroyView() { + mView = null; + mTypeClock = null; + mLockClock = null; + mDarkController = null; + } + + @Override + public String getName() { + return "type"; + } + + @Override + public String getTitle() { + return mResources.getString(R.string.clock_title_type); + } + + @Override + public Bitmap getThumbnail() { + return BitmapFactory.decodeResource(mResources, R.drawable.type_thumbnail); + } + + @Override + public Bitmap getPreview(int width, int height) { + + // Use the big clock view for the preview + View view = getBigClockView(); + + // Initialize state of plugin before generating preview. + setDarkAmount(1f); + setTextColor(Color.WHITE); + ColorExtractor.GradientColors colors = mColorExtractor.getColors( + WallpaperManager.FLAG_LOCK, true); + setColorPalette(colors.supportsDarkText(), colors.getColorPalette()); + onTimeTick(); + + return mRenderer.createPreview(view, width, height); + } + + @Override + public View getView() { + if (mLockClock == null) { + createViews(); + } + return mLockClock; + } + + @Override + public View getBigClockView() { + if (mView == null) { + createViews(); + } + return mView; + } + + @Override + public void setStyle(Style style) {} + + @Override + public void setTextColor(int color) { + mTypeClock.setTextColor(color); + mLockClock.setTextColor(color); + } + + @Override + public void setColorPalette(boolean supportsDarkText, int[] colorPalette) { + if (colorPalette == null || colorPalette.length == 0) { + return; + } + final int color = colorPalette[Math.max(0, colorPalette.length - 5)]; + mTypeClock.setClockColor(color); + mLockClock.setClockColor(color); + } + + @Override + public void onTimeTick() { + mTypeClock.onTimeChanged(); + mLockClock.onTimeChanged(); + } + + @Override + public void setDarkAmount(float darkAmount) { + if (mDarkController != null) { + mDarkController.setDarkAmount(darkAmount); + } + } + + @Override + public void onTimeZoneChanged(TimeZone timeZone) { + mTypeClock.onTimeZoneChanged(timeZone); + mLockClock.onTimeZoneChanged(timeZone); + } + + @Override + public boolean shouldShowStatusArea() { + return false; + } +} diff --git a/packages/SystemUI/src/com/android/keyguard/clock/TypographicClock.java b/packages/SystemUI/src/com/android/keyguard/clock/TypographicClock.java new file mode 100644 index 00000000000..572ab30d701 --- /dev/null +++ b/packages/SystemUI/src/com/android/keyguard/clock/TypographicClock.java @@ -0,0 +1,130 @@ +/* + * Copyright (C) 2019 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.keyguard.clock; + +import android.content.Context; +import android.content.res.Resources; +import android.text.Annotation; +import android.text.Spannable; +import android.text.SpannableString; +import android.text.SpannedString; +import android.text.TextUtils; +import android.text.format.DateFormat; +import android.text.style.ForegroundColorSpan; +import android.util.AttributeSet; +import android.widget.TextView; + +import com.android.keyguard.R; + +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.TimeZone; + +/** + * Clock that presents the time in words. + */ +public class TypographicClock extends TextView { + + private static final String ANNOTATION_COLOR = "color"; + + private final Resources mResources; + private final String[] mHours; + private final String[] mMinutes; + private int mAccentColor; + private final Calendar mTime = Calendar.getInstance(TimeZone.getDefault()); + private String mDescFormat; + private TimeZone mTimeZone; + + public TypographicClock(Context context) { + this(context, null); + } + + public TypographicClock(Context context, AttributeSet attrs) { + this(context, attrs, 0); + } + + public TypographicClock(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + mDescFormat = ((SimpleDateFormat) DateFormat.getTimeFormat(context)).toLocalizedPattern(); + mResources = context.getResources(); + mHours = mResources.getStringArray(R.array.type_clock_hours); + mMinutes = mResources.getStringArray(R.array.type_clock_minutes); + mAccentColor = mResources.getColor(R.color.typeClockAccentColor, null); + } + + /** + * Call when the time changes to update the text of the time. + */ + public void onTimeChanged() { + mTime.setTimeInMillis(System.currentTimeMillis()); + setContentDescription(DateFormat.format(mDescFormat, mTime)); + final int hour = mTime.get(Calendar.HOUR) % 12; + final int minute = mTime.get(Calendar.MINUTE) % 60; + + // Get the quantity based on the hour for languages like Portuguese and Czech. + SpannedString typeTemplate = (SpannedString) mResources.getQuantityText( + R.plurals.type_clock_header, hour); + + // Find the "color" annotation and set the foreground color to the accent color. + Annotation[] annotations = typeTemplate.getSpans(0, typeTemplate.length(), + Annotation.class); + SpannableString spanType = new SpannableString(typeTemplate); + for (int i = 0; i < annotations.length; i++) { + Annotation annotation = annotations[i]; + String key = annotation.getValue(); + if (ANNOTATION_COLOR.equals(key)) { + spanType.setSpan(new ForegroundColorSpan(mAccentColor), + spanType.getSpanStart(annotation), spanType.getSpanEnd(annotation), + Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); + } + } + + setText(TextUtils.expandTemplate(spanType, mHours[hour], mMinutes[minute])); + } + + /** + * Call when the time zone has changed to update clock time. + * + * @param timeZone The updated time zone that will be used. + */ + public void onTimeZoneChanged(TimeZone timeZone) { + mTimeZone = timeZone; + mTime.setTimeZone(timeZone); + } + + /** + * Sets the accent color used on the clock face. + */ + public void setClockColor(int color) { + mAccentColor = color; + onTimeChanged(); + } + + @Override + protected void onAttachedToWindow() { + super.onAttachedToWindow(); + mTime.setTimeZone(mTimeZone != null ? mTimeZone : TimeZone.getDefault()); + onTimeChanged(); + } + + /** + * Overriding hasOverlappingRendering as false to improve performance of crossfading. + */ + @Override + public boolean hasOverlappingRendering() { + return false; + } +} From 05e82068105177d79ba0b3a998ef0e8cecfdf474 Mon Sep 17 00:00:00 2001 From: Luca Stefani Date: Wed, 4 Sep 2019 17:27:11 +0200 Subject: [PATCH 050/240] Revert "Drop final remnants of Type clock face" This reverts commit 37fe8022174fc809ef4622f7d6c69f9bdff06913. Change-Id: Ieb5603fbdfc992a2f7f1fe9afee4e62524b844ec --- .../drawable-xxxhdpi/type_thumbnail.png | Bin 0 -> 6315 bytes .../SystemUI/res-keyguard/values/strings.xml | 4 ++++ 2 files changed, 4 insertions(+) create mode 100644 packages/SystemUI/res-keyguard/drawable-xxxhdpi/type_thumbnail.png diff --git a/packages/SystemUI/res-keyguard/drawable-xxxhdpi/type_thumbnail.png b/packages/SystemUI/res-keyguard/drawable-xxxhdpi/type_thumbnail.png new file mode 100644 index 0000000000000000000000000000000000000000..2bfd655e37de87d2e664da2e3abe90574560f3e6 GIT binary patch literal 6315 zcmb7}2{_dK+Q(5y5veR?%VQ@>L?MLid$w%Jl5HqsA6rjFlBEoju|1JtFf(P%*pkXJ zmKa8cp~w~nV{5GM&->@4mm^&wWd@Fw^Hadgdqt0|SSl zfvyz;1LG0!VmQJAj+htCz5u^i?ilOqGVCAx{LxsP4vw(hGjM=1FdRF1@M2^@=J0`o ztigt+daRR-Cm3ZFFTWNzI3(zE(>_=y5CZWG2nK&LFz5t%x&?cBh=lnBdyD8Bnp$|s zd$KYx@NpXIYTpbeFH-2{XT$c|R%!*iY^btYZ(5vM(%gOEp_R!p=Pmm&_;~t8 zf@RSnU8lOgv}hRRkRjodt`*0?!NRI@ZhE=J4YrXG(~ZdLy}R)JsD!$(RZKg>XZLHX z$X*Tk)(h;63>+%Lj0{Xn42+C%aSU2o3?d>7TwDxCjxZcP{O94nzxiL!|K-AeJ^zmn z`hTAPmxcWG{{L;E|L606z0d{oJ8_TkSxSnLx{&7D5T?8wj>TfF*Bw4j-scw-R2D2l zqn~eVgkqJLCOjgy*3fba3c_3SHC0tP_&5VGZrZn&L&Uc!DaV<9mtgr@z(m)y+uy&B z6H7N7!JUmimmj^6HD~YU_9|+*h1J2e_RX8LerBeL*JW62&(?bIRg7)@XaE|AD_)EH z??-U8UJw&XC6GuwGe?np`kny+W}?rZ^uv98d^+frL?V$p>61xYgA4Aajg9AS-A$Py z6D#f$Y=@bwEN<`Lb-8uxg`|02`@}>+ISywmlfixBL~7e_o}Qi)>yhGIM+`hYrygh` zETqH~T$_{xWu>K`_w@8=G@4!DgAWc4YQ#3-XijWLzCOKC7_>B|L3~RllXI9=vrIa_ zd`au~!PnGCEH$i}k@7hbT057@OG?s`colq`HMtYpDfMAfpOSdVxWK?bV=?aM24bSA zLK@upy^>2!+gNyJCUqNXD3RU?3$AnOA01uz6+)b=V&~xK`20D3?pJrV3M6(~wI@S@ z#lO0y<|$!HQP9!FrRPeK+Nq;H`Zx15WAj$Sz*=S6c4C?#95buEnzfC$7pUa?m@V|q z);w-|&j~~Yo{=GKvzwU6)`nZzp+m(5jEs$os;iZ8JsELvm=`a&ef<3gct}ow|XNzOc4C7wHp83h?Rl$q&<^#v)u6DXFQcYB9-g-(G}V>Rb$+ z8LaF7sAU_|>^eO&lc8oE7FG)xjPUZ3@C*OSf%$yrViCmk)~(X0SUH|_wJ_=vH@@lX z78W811=mazN&;P4`odmLVs&+u`*?ylA3HKW(i#nqTJ2U*R8=i$l!9J~-D?oh!ftOSQc7$f96Fpjl9%wxCGbFM%?uU*ROY1)-Ke||9LvYGD*{F0BK zA93UKkJdVFt~WNewh|#BAt?9k?Cgqn?@D&}Tw~~;)?(*B2`1`#Kp>FuT~6?^+(#e7 zH-C-6mO9P`Hn_or&YwR|+uL4}4YP2z8AmrYU7PwkFaY-t3>?{e=Eg^k`_gE8EmxND zL3ua3ByS})et9}O@M@{vYogE89Vr+;sPuy z3KiMxsF($xo0}_-mh1B#2rkFtZy}LLfkCB|d620K(jvjRiN?mpM&CIPGj-}=k3ISH zNv}wTLMHp-kD;ujrzQxb)z~j@par$HVdmZJ6lbT+GxTt*B!4bkzofL(sI;`y!_)Iq zuy&xozrp?cZx_#r8--RT?1p)7l)OP7Ar(9o!1{Js(nXLBHt4N*pcL&e_*wB?Z>K3tz$Sh(rS zGC4U(BRK|UrI?zSNF`0<@%SoPuhkVNpF6k52M0lRdp=Pl5^(dgqk+4aAcFROgS8M4@?4u^Dp)OI-O>FKdvtp$-k6nmM2g9G(EH(XsF3WZLr z(nFDg_1WH{%^^YLU22qu9TSs---%RV&C3)z0)Z&PV$Il&%nL9!k1MpcwxTvx78c5@ zYHMY?kJXM~*52Rs6~%7`?{2NT@B2r>U>UE*-@bjD8+VU#-80CCy*Z%4)pcC8l^mJ`9qAGZJ12%Pcit4x!AD@6&Lv< zWMjd>lRYLh)b{t5KY}(ZH?GVwN${~#pT++;TF|9u?cx$}wWgv%bbfxmZS1%vboyD2 zX6#t7T&@|R@@}t3P>_{F1BpmX4s5~xbBFaZqweD-(qIu)xyF;TA#jf2hhdp-W8eCFVldAn!V_F{p{JZ z_QjFfYMA1Jou1xfMWyu^g~G40NW)lQM^Y_fB=*_eTBly{+|%3dOml zCA*YVaI0i~R6)7==@Y|WzoxNr3bogc$CN2Cl1QZEAv08e!BiMMFZ~`?lC6*rCzD7C zSfNKLUb*4}d*I0H?cgUeYk{vF|6(A3k0@RjR4JUk|Cu1!(WKqZR8)rHVlY$g!c z#2ba&iMmx`qXh+`{Cs?>1L9w<<(u;#AH#rR>&aD{`L#}?11-DV%X=StM$6s3aPdwd zP%eF&z}k`XDgmQ!C_iIiFh?FB)EkQT z%uXN6=`rKvs=_`Uy)G2L&MX7psb1j{nA64v=^VBnM~d&Ah??ow=a zO$fBkiH2z2dCcj>Tb~Tcr9L&)`lf5w9j4j7QB{r3^@c!fYDRknBt-=H`1mY@yeqQZ z_-Mm-^RrS;^YC=C3P+`_hnUazw5SR=J39w`|L|C2Kc{W-;_mqTdgox7-Bg=!EW9gJ znnIxjtxV`KePF9k)~dAmG#XGlFf?TS^u7l$ZBERy_03HJeRT%Fi(V&zkWn0Rf{Wq7 zZ$O!gw=Ug2H5td=ng%oo)Sv!deg9n5$2)JWhaKW4rDG$kAHK}aPB#!MQ1UEK^&n>D zSeb0=?DZUL-Pvi7JAXc_$=2S!Bzn*Da?5QCkT<4nGP1ItW>%-B9;;lu zcnO=v74}sn?>*C1E1&Eq9 zXy>{(&-Com9oi>eSE;Z)qtg7mdTxTt}qx31#xJ5yKzbopMN$3ak&cN7}GOM4zmztd286p{*_; z>OML@<2&xWeK}eO)h|!wl$Mf8BOnxvt*z4m&>I43q|+nV5?Z<0Sxf~J(Kn5n=+kHU z1q6bFEkTwd_r^&i3E(4E_V!W-ga}Y9hVjJnwp3xjs%cN39<@&Q32V9K>}+%ON=PfI zK3jHiagjE@zh^f`c$t&aRd?A9R1-Zr?+SFf+MalCZzrNIcE4$E)ydg8?CO3*C^ANPfTm?{9T&S8EVM|q@24a~_EnjgX)~Jp4rk7sftN0TnE7a1N?gbX zWpn_mS2h5)_N{5u29Dc$SskcQZ$$0F{CxWN?`}m|&*!fX4GLXVQ-cWWMsZnNTa&+a zp_-dr0V-~;Z!ZX)R=svD?~+Kca&k@0<)Y?qssvXT<%_y8u&<@njrDbP=ut~R>6lzy zl36Z=x7B4^7+9CssiV?MD~+3Dge|2-Aea&0TV_;|Y@{oJX<2+Y2h9UmMlN=9gni^Z z=mYYE@eK`f-|v0hxC?x^#@O~Kbca264|2~4jBjlfg}MMmD@m+|-YeL*JQig5NQ{YAQ6<#+-)w@q%mEl=#K zyk@wgN*GT(dc^teM1TJa+BsGx#wpPu=8vEaw1W6SAj;waG8tBT?V%c72`55r&4e6W zEiGRSAX7?N+`?w^^YUsMkIf@_ag&kpV`F0)A+|rMKS)EWR2l*i%_S;oV`F1wV{_n9 zsAG}t?yUp&y&9L#o;mZns_G`_#?WLyz2eUeURn(qu8N*XmN{2ZT`evgyYqGuI!s|1 zrOd&T+9o^d#>9y#7PoHsMw&{t7Hnr^y{}Yz1A4$`$;pPXvCVTZz!K=LW+?>)&HmHR z@Al+aBDKw~wLbj$H@IFKPH1&=0I4k@E6&YUC8Uh_E4J1BPYxmMl`fiN% zkw@3h4UdiSq_$0l2f?wWx2&v0|IX$oV=p>2gj)ic+<%#p{Os9+k}!}m_|N-cVVi!9 z)ati0>$?p`cc0aAlPRkjD_=HL~dD@-W_B4FFQF+|YXf&nL2^n;CrIj`=c*14+gE32XDz79z&$~T{UHz^eeng- z-Vb9sVI)o!wo%^Clb@TbTphBwB@oPblAR^&hE5Q(A!wu{JkPU6e9vf;TsC90A71o_JnP zPHNDu{@7?_l%Jn*z4}nV*Y2qxpH1~&VEiEHYVlX%Z|rZgd4kzkcJ- zg_>=wh36vqZQb47J0B?`2pJ*B$b%1XF}vH?&e3XN>rL*y+!Y*5^}=jjR#x`ev}pg* zE#PEtp9b5cPVM{#`oH$D@o32o533tDZv5C-93fZlo+Y_IY8v$ zT22lQeJOa)Z24TUtGGiGz;7I2O-V^fmGVzJlx?mI4G}s!;cQx>&Ff!dX&sWCGJ4O) zL!U%0e|r$My;y5x1BE~qzrtuCC*Oc=^$ZWUcWDSe2V9#v-mCx!(z<7;6o>2GqVw|b zx*I~3*J5%eZ>VR5DfEtT}SPbU;Jf&l4lK^N!V8|jE>r^MI;L>2>#oQD{ zw`$s<5po?;#l^+BlW&M~CwdbbOG*q_SXfe`IUh|=dwFsr0az}7*CDO|k5t3zeLes6 z=iHoS4P280JYUfy5E7cJ7S_|}Cm2R2YzwMYIDf43WdQzIlb!;cCdhV0@m$E{XO0nc z@5smqm}y8|x^$_cp`mvQnQ3C1hAo=(T zTH_$Mw&Ru~8_66V8banhr+P?iS+Y*$HjOPUEz!>QplhamPY{-oT~8qj?=2_joDHp- z_pdybLi`Z$sNj!3-iID~9VHhVA)_cl}_z)n=>Rs}Y!#QWHlIt3d)F(-UM<#u@~+Tufa=}vo2 z@gWMbsug&=%)v}4`G#k7v@<|qFaE2nxCKlBCkX(%v>j2L}VE> zK{+=`_dvs+zg6sZl1p_RV0(V-p2HQh88Jr2c7T5sm-+!yLh|phFfkQB!EW3mOWtV2 zzGQu%0fg>gY(^Y#t{rKd$wI60zcgg~b58p2M%Mq>Tm93d_&<)M|KrFRJoZ1H|ECZ7 p$C3KK@BRL~?cbljcV?Hf;QJwNrrsy12mdoL)HBn?UcdeOe*tN_0pb7v literal 0 HcmV?d00001 diff --git a/packages/SystemUI/res-keyguard/values/strings.xml b/packages/SystemUI/res-keyguard/values/strings.xml index 9b781262dc1..7f2a804bba6 100644 --- a/packages/SystemUI/res-keyguard/values/strings.xml +++ b/packages/SystemUI/res-keyguard/values/strings.xml @@ -421,6 +421,10 @@ number">%d remaining attempts before SIM becomes permanently unusable. Bubble Analog + + Type + + + + + + + + + + + + diff --git a/core/res/res/values/reloaded_symbols.xml b/core/res/res/values/reloaded_symbols.xml new file mode 100644 index 00000000000..ca2b3e7acda --- /dev/null +++ b/core/res/res/values/reloaded_symbols.xml @@ -0,0 +1,23 @@ + + + + + + + + + diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 632ab102ef3..edd7574404f 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -1250,6 +1250,8 @@ private static boolean hasValidDomains(ActivityIntentInfo filter) { filter.hasDataScheme(IntentFilter.SCHEME_HTTPS)); } + ArrayList mDisabledComponentsList; + // Set of pending broadcasts for aggregating enable/disable of components. static class PendingPackageBroadcasts { // for each user id, a map of components within that package> @@ -3245,6 +3247,38 @@ public PackageManagerService(Context context, Installer installer, Slog.i(TAG, "Deferred reconcileAppsData finished " + count + " packages"); }, "prepareAppData"); + // Disable components marked for disabling at build-time + mDisabledComponentsList = new ArrayList(); + for (String name : mContext.getResources().getStringArray( + com.android.internal.R.array.config_disabledComponents)) { + ComponentName cn = ComponentName.unflattenFromString(name); + mDisabledComponentsList.add(cn); + Slog.v(TAG, "Disabling " + name); + String className = cn.getClassName(); + PackageSetting pkgSetting = mSettings.mPackages.get(cn.getPackageName()); + if (pkgSetting == null || pkgSetting.pkg == null + || !pkgSetting.pkg.hasComponentClassName(className)) { + Slog.w(TAG, "Unable to disable " + name); + continue; + } + pkgSetting.disableComponentLPw(className, UserHandle.USER_OWNER); + } + + // Enable components marked for forced-enable at build-time + for (String name : mContext.getResources().getStringArray( + com.android.internal.R.array.config_forceEnabledComponents)) { + ComponentName cn = ComponentName.unflattenFromString(name); + Slog.v(TAG, "Enabling " + name); + String className = cn.getClassName(); + PackageSetting pkgSetting = mSettings.mPackages.get(cn.getPackageName()); + if (pkgSetting == null || pkgSetting.pkg == null + || !pkgSetting.pkg.hasComponentClassName(className)) { + Slog.w(TAG, "Unable to enable " + name); + continue; + } + pkgSetting.enableComponentLPw(className, UserHandle.USER_OWNER); + } + // If this is first boot after an OTA, and a normal boot, then // we need to clear code cache directories. // Note that we do *not* clear the application profiles. These remain valid @@ -21297,6 +21331,12 @@ public void setUpdateAvailable(String packageName, boolean updateAvailable) { public void setComponentEnabledSetting(ComponentName componentName, int newState, int flags, int userId) { if (!sUserManager.exists(userId)) return; + // Don't allow to enable components marked for disabling at build-time + if (mDisabledComponentsList.contains(componentName)) { + Slog.d(TAG, "Ignoring attempt to set enabled state of disabled component " + + componentName.flattenToString()); + return; + } setEnabledSetting(componentName.getPackageName(), componentName.getClassName(), newState, flags, userId, null); } From 9780eb1b4c02b5d3c90940dd26a9fe0c6b1095ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hern=C3=A1n=20Casta=C3=B1=C3=B3n?= Date: Sun, 1 Oct 2017 02:09:09 +0200 Subject: [PATCH 056/240] SystemUI: enable NFC tile on quick settings Added to secondary tiles. Thanks to thecrazyskull for adding to AOSP Change-Id: Id0247d61cbee6cc371256fc0cae25a5a898d3a4b --- packages/SystemUI/res/values/config.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml index 35f2d04f444..9a9afc6719f 100644 --- a/packages/SystemUI/res/values/config.xml +++ b/packages/SystemUI/res/values/config.xml @@ -117,7 +117,7 @@ - wifi,cell,battery,dnd,flashlight,rotation,bt,airplane,location,hotspot,inversion,saver,dark,work,cast,night + wifi,cell,battery,dnd,flashlight,rotation,bt,airplane,location,hotspot,nfc,inversion,saver,dark,work,cast,night From e0a869613cbb23f86451996085925fefdb689c18 Mon Sep 17 00:00:00 2001 From: Andrzej Ressel Date: Wed, 9 Aug 2017 00:11:16 +0200 Subject: [PATCH 057/240] SystemUI: Allow user to add/remove QS with one click Demo: https://www.youtube.com/watch?v=SlnRKLa4K7o Change-Id: I9250fe5fd6a3edf567f1f4d30fd86838f5ef4610 --- .../src/com/android/systemui/qs/customize/TileAdapter.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java b/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java index 2542abdbef7..376151b0d96 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java +++ b/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java @@ -312,8 +312,13 @@ public void onLayoutChange(View v, int left, int top, int right, int bottom, holder.mTileView.handleStateChanged(info.state); holder.mTileView.setShowAppLabel(position > mEditIndex && !info.isSystem); + final boolean selectable = mAccessibilityAction == ACTION_NONE || position < mEditIndex; + if (!(mAccessibilityManager.isTouchExplorationEnabled() && selectable)) { + holder.mTileView.setOnClickListener(v -> move(holder.getAdapterPosition(), + mEditIndex, holder.mTileView)); + } + if (mAccessibilityManager.isTouchExplorationEnabled()) { - final boolean selectable = mAccessibilityAction == ACTION_NONE || position < mEditIndex; holder.mTileView.setClickable(selectable); holder.mTileView.setFocusable(selectable); holder.mTileView.setImportantForAccessibility(selectable From b29568c9df4db6f2cfcfe3ba4f0db5dfa7a3a54a Mon Sep 17 00:00:00 2001 From: LuK1337 Date: Sun, 9 Dec 2018 18:39:35 +0530 Subject: [PATCH 058/240] SystemUI: Allow overlaying max notification icons * I believe there are devices in this world that can fit more than 4 notification icons. Change-Id: Id0f3593c78a29765927c5001456ce582db3ce6b8 --- .../SystemUI/res/values/reloaded_config.xml | 23 +++++++++++++++++++ .../phone/NotificationIconContainer.java | 8 ++++--- 2 files changed, 28 insertions(+), 3 deletions(-) create mode 100644 packages/SystemUI/res/values/reloaded_config.xml diff --git a/packages/SystemUI/res/values/reloaded_config.xml b/packages/SystemUI/res/values/reloaded_config.xml new file mode 100644 index 00000000000..bb424179aa0 --- /dev/null +++ b/packages/SystemUI/res/values/reloaded_config.xml @@ -0,0 +1,23 @@ + + + + + + 4 + 5 + + diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java index a53ce9bb201..cf9646c6837 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java @@ -128,9 +128,9 @@ public AnimationFilter getAnimationFilter() { } }.setDuration(CONTENT_FADE_DURATION); - private static final int MAX_VISIBLE_ICONS_ON_LOCK = 5; - public static final int MAX_STATIC_ICONS = 4; - private static final int MAX_DOTS = 1; + public int MAX_VISIBLE_ICONS_ON_LOCK = 5; + public int MAX_STATIC_ICONS = 4; + final int MAX_DOTS = 1; private boolean mIsStaticLayout = true; private final HashMap mIconStates = new HashMap<>(); @@ -173,6 +173,8 @@ private void initDimens() { mDotPadding = getResources().getDimensionPixelSize(R.dimen.overflow_icon_dot_padding); mStaticDotRadius = getResources().getDimensionPixelSize(R.dimen.overflow_dot_radius); mStaticDotDiameter = 2 * mStaticDotRadius; + MAX_VISIBLE_ICONS_ON_LOCK = getResources().getInteger(R.integer.config_maxVisibleNotificationIconsOnLock); + MAX_STATIC_ICONS = getResources().getInteger(R.integer.config_maxVisibleNotificationIcons); } @Override From 139b21af4bad6dfe82fcfe1e109b94497768a049 Mon Sep 17 00:00:00 2001 From: Bruno Martins Date: Sat, 28 Sep 2019 04:30:22 -0400 Subject: [PATCH 059/240] Support for device specific key handlers This is a squash commit of the following changes, only modified for the new SDK. Author: Alexander Hofbauer Date: Thu Apr 12 01:24:24 2012 +0200 Dispatch keys to a device specific key handler Injects a device key handler into the input path to handle additional keys (as found on some docks with a hardware keyboard). Configurable via overlay settings config_deviceKeyHandlerLib and config_deviceKeyHandlerClass. Change-Id: I6678c89c7530fdb1d4d516ba4f1d2c9e30ce79a4 Author: Jorge Ruesga Date: Thu Jan 24 02:34:49 2013 +0100 DeviceKeyHandle: The device should consume only known keys When the device receive the key, only should consume it if the device know about the key. Otherwise, the key must be handle by the active app. Also make mDeviceKeyHandler private (is not useful outside this class) Change-Id: I4b9ea57b802e8c8c88c8b93a63d510f5952b0700 Signed-off-by: Jorge Ruesga Author: Danesh Mondegarian Date: Sun Oct 20 00:34:48 2013 -0700 DeviceKeyHandler : Allow handling keyevents while screen off Some devices require the keyevents to be processed while the screen is off, this patchset addresses that by moving the filter up in the call hierarchy. Change-Id: If71beecc81aa5e453dcd08aba72b7bea5c210590 Author: Steve Kondik Date: Sun Sep 11 00:49:41 2016 -0700 policy: Use PathClassLoader for loading the keyhandler * Fix crash on start due to getCacheDir throwing an exception. * We can't do this anymore due to the new storage/crypto in N. Change-Id: I28426a5df824460ebc74aa19068192adb00d4f7c Author: Zhao Wei Liew Date: Sun Nov 20 08:20:15 2016 +0800 PhoneWindowManager: Support multiple key handlers Convert the string overlay to a string-array overlay to allow devices to specify an array of key handlers. Note that the keyhandlers towards the start of the array take precedence when loading. Change-Id: Iaaab737f1501a97d7016d8d519ccf127ca059218 Author: Paul Keith Date: Thu Nov 23 21:47:51 2017 +0100 fw/b: Return a KeyEvent instead of a boolean in KeyHandler * Allows handlers to modify the event before sending it off to another KeyHandler class, to handle things like rotation Change-Id: I481107e050f6323c5897260a5d241e64b4e031ac Change-Id: Ie65a89cd7efd645622d99d47699df847bc3ad96b --- .../android/internal/os/DeviceKeyHandler.java | 31 ++++++++++ core/res/res/values/reloaded_config.xml | 8 +++ core/res/res/values/reloaded_symbols.xml | 4 ++ .../server/policy/PhoneWindowManager.java | 58 +++++++++++++++++++ 4 files changed, 101 insertions(+) create mode 100644 core/java/com/android/internal/os/DeviceKeyHandler.java diff --git a/core/java/com/android/internal/os/DeviceKeyHandler.java b/core/java/com/android/internal/os/DeviceKeyHandler.java new file mode 100644 index 00000000000..8902337f3eb --- /dev/null +++ b/core/java/com/android/internal/os/DeviceKeyHandler.java @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2012 The CyanogenMod 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.internal.os; + +import android.view.KeyEvent; + +public interface DeviceKeyHandler { + + /** + * Invoked when an unknown key was detected by the system, letting the device handle + * this special keys prior to pass the key to the active app. + * + * @param event The key event to be handled + * @return null if event is consumed, KeyEvent to be handled otherwise + */ + public KeyEvent handleKeyEvent(KeyEvent event); +} diff --git a/core/res/res/values/reloaded_config.xml b/core/res/res/values/reloaded_config.xml index ace119f3373..2b2d07383da 100644 --- a/core/res/res/values/reloaded_config.xml +++ b/core/res/res/values/reloaded_config.xml @@ -24,4 +24,12 @@ + + + + + + + + diff --git a/core/res/res/values/reloaded_symbols.xml b/core/res/res/values/reloaded_symbols.xml index ca2b3e7acda..ff9367a09fb 100644 --- a/core/res/res/values/reloaded_symbols.xml +++ b/core/res/res/values/reloaded_symbols.xml @@ -20,4 +20,8 @@ + + + + diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java index a6830fe0a7c..4572d3ede06 100644 --- a/services/core/java/com/android/server/policy/PhoneWindowManager.java +++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java @@ -201,6 +201,7 @@ import com.android.internal.accessibility.AccessibilityShortcutController; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto; +import com.android.internal.os.DeviceKeyHandler; import com.android.internal.os.RoSystemProperties; import com.android.internal.policy.IKeyguardDismissCallback; import com.android.internal.policy.IShortcutService; @@ -226,11 +227,15 @@ import com.android.server.wm.WindowManagerInternal; import com.android.server.wm.WindowManagerInternal.AppTransitionListener; +import dalvik.system.PathClassLoader; + import java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import java.io.PrintWriter; +import java.lang.reflect.Constructor; +import java.util.ArrayList; import java.util.HashSet; import java.util.List; @@ -619,6 +624,8 @@ public void onDrawn() { private int mPowerButtonSuppressionDelayMillis = POWER_BUTTON_SUPPRESSION_DELAY_DEFAULT_MILLIS; + private final List mDeviceKeyHandlers = new ArrayList<>(); + private static final int MSG_DISPATCH_MEDIA_KEY_WITH_WAKE_LOCK = 3; private static final int MSG_DISPATCH_MEDIA_KEY_REPEAT_WITH_WAKE_LOCK = 4; private static final int MSG_KEYGUARD_DRAWN_COMPLETE = 5; @@ -1974,6 +1981,30 @@ public void onShowingChanged() { mWindowManagerFuncs.onKeyguardShowingAndNotOccludedChanged(); } }); + + final Resources res = mContext.getResources(); + final String[] deviceKeyHandlerLibs = res.getStringArray( + com.android.internal.R.array.config_deviceKeyHandlerLibs); + final String[] deviceKeyHandlerClasses = res.getStringArray( + com.android.internal.R.array.config_deviceKeyHandlerClasses); + + for (int i = 0; + i < deviceKeyHandlerLibs.length && i < deviceKeyHandlerClasses.length; i++) { + try { + PathClassLoader loader = new PathClassLoader( + deviceKeyHandlerLibs[i], getClass().getClassLoader()); + Class klass = loader.loadClass(deviceKeyHandlerClasses[i]); + Constructor constructor = klass.getConstructor(Context.class); + mDeviceKeyHandlers.add((DeviceKeyHandler) constructor.newInstance(mContext)); + } catch (Exception e) { + Slog.w(TAG, "Could not instantiate device key handler " + + deviceKeyHandlerLibs[i] + " from class " + + deviceKeyHandlerClasses[i], e); + } + } + if (DEBUG_INPUT) { + Slog.d(TAG, "" + mDeviceKeyHandlers.size() + " device key handlers loaded"); + } } /** @@ -3032,6 +3063,11 @@ private long interceptKeyBeforeDispatchingInner(WindowState win, KeyEvent event, return -1; } + // Specific device key handling + if (dispatchKeyToKeyHandlers(event)) { + return -1; + } + if (down) { long shortcutCode = keyCode; if (event.isCtrlPressed()) { @@ -3137,6 +3173,23 @@ private void requestFullBugreport() { } } + private boolean dispatchKeyToKeyHandlers(KeyEvent event) { + for (DeviceKeyHandler handler : mDeviceKeyHandlers) { + try { + if (DEBUG_INPUT) { + Log.d(TAG, "Dispatching key event " + event + " to handler " + handler); + } + event = handler.handleKeyEvent(event); + if (event == null) { + return true; + } + } catch (Exception e) { + Slog.w(TAG, "Could not dispatch event to device key handler", e); + } + } + return false; + } + // TODO(b/117479243): handle it in InputPolicy /** {@inheritDoc} */ @Override @@ -3759,6 +3812,11 @@ public int interceptKeyBeforeQueueing(KeyEvent event, int policyFlags) { && (!isNavBarVirtKey || mNavBarVirtualKeyHapticFeedbackEnabled) && event.getRepeatCount() == 0; + // Specific device key handling + if (dispatchKeyToKeyHandlers(event)) { + return 0; + } + // Handle special keys. switch (keyCode) { case KeyEvent.KEYCODE_BACK: { From d4fbe5d6111286f0ffd636c62fa3e2599aea7b3b Mon Sep 17 00:00:00 2001 From: LuK1337 Date: Wed, 31 Oct 2018 16:31:19 +0100 Subject: [PATCH 060/240] SystemUI: Show bluetooth battery level when available * Somewhat inspired by change committed by Gavin Ni back in cm-13.0 days (see commit 88e7a6c). Since then completely rewritten using BluetoothDevice API introduced in Oreo, with new drawables meant to be used with 0-9 battery level range. Change-Id: I6179bfd41e033591534e8cf3c6adc98ce715a13d --- ...sys_data_bluetooth_connected_battery_0.xml | 37 +++++++++++++++++++ ...sys_data_bluetooth_connected_battery_1.xml | 37 +++++++++++++++++++ ...sys_data_bluetooth_connected_battery_2.xml | 37 +++++++++++++++++++ ...sys_data_bluetooth_connected_battery_3.xml | 37 +++++++++++++++++++ ...sys_data_bluetooth_connected_battery_4.xml | 37 +++++++++++++++++++ ...sys_data_bluetooth_connected_battery_5.xml | 37 +++++++++++++++++++ ...sys_data_bluetooth_connected_battery_6.xml | 37 +++++++++++++++++++ ...sys_data_bluetooth_connected_battery_7.xml | 37 +++++++++++++++++++ ...sys_data_bluetooth_connected_battery_8.xml | 37 +++++++++++++++++++ ...sys_data_bluetooth_connected_battery_9.xml | 34 +++++++++++++++++ .../statusbar/phone/PhoneStatusBarPolicy.java | 29 +++++++++++++++ 11 files changed, 396 insertions(+) create mode 100644 packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected_battery_0.xml create mode 100644 packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected_battery_1.xml create mode 100644 packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected_battery_2.xml create mode 100644 packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected_battery_3.xml create mode 100644 packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected_battery_4.xml create mode 100644 packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected_battery_5.xml create mode 100644 packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected_battery_6.xml create mode 100644 packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected_battery_7.xml create mode 100644 packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected_battery_8.xml create mode 100644 packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected_battery_9.xml diff --git a/packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected_battery_0.xml b/packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected_battery_0.xml new file mode 100644 index 00000000000..2df88bda48a --- /dev/null +++ b/packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected_battery_0.xml @@ -0,0 +1,37 @@ + + + + + + + + + diff --git a/packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected_battery_1.xml b/packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected_battery_1.xml new file mode 100644 index 00000000000..39b22e2e7b4 --- /dev/null +++ b/packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected_battery_1.xml @@ -0,0 +1,37 @@ + + + + + + + + + diff --git a/packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected_battery_2.xml b/packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected_battery_2.xml new file mode 100644 index 00000000000..a8684709e71 --- /dev/null +++ b/packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected_battery_2.xml @@ -0,0 +1,37 @@ + + + + + + + + + diff --git a/packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected_battery_3.xml b/packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected_battery_3.xml new file mode 100644 index 00000000000..63eadcd943d --- /dev/null +++ b/packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected_battery_3.xml @@ -0,0 +1,37 @@ + + + + + + + + + diff --git a/packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected_battery_4.xml b/packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected_battery_4.xml new file mode 100644 index 00000000000..1e768821065 --- /dev/null +++ b/packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected_battery_4.xml @@ -0,0 +1,37 @@ + + + + + + + + + diff --git a/packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected_battery_5.xml b/packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected_battery_5.xml new file mode 100644 index 00000000000..2684bb9381f --- /dev/null +++ b/packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected_battery_5.xml @@ -0,0 +1,37 @@ + + + + + + + + + diff --git a/packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected_battery_6.xml b/packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected_battery_6.xml new file mode 100644 index 00000000000..62a0732ca19 --- /dev/null +++ b/packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected_battery_6.xml @@ -0,0 +1,37 @@ + + + + + + + + + diff --git a/packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected_battery_7.xml b/packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected_battery_7.xml new file mode 100644 index 00000000000..b0bc839a33d --- /dev/null +++ b/packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected_battery_7.xml @@ -0,0 +1,37 @@ + + + + + + + + + diff --git a/packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected_battery_8.xml b/packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected_battery_8.xml new file mode 100644 index 00000000000..918fe80d10a --- /dev/null +++ b/packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected_battery_8.xml @@ -0,0 +1,37 @@ + + + + + + + + + diff --git a/packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected_battery_9.xml b/packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected_battery_9.xml new file mode 100644 index 00000000000..862daa21e89 --- /dev/null +++ b/packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected_battery_9.xml @@ -0,0 +1,34 @@ + + + + + + + + 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 72defae3b0a..a5bd67f1ddc 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java @@ -21,6 +21,7 @@ import android.app.AlarmManager; import android.app.AlarmManager.AlarmClockInfo; import android.app.SynchronousUserSwitchObserver; +import android.bluetooth.BluetoothDevice; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; @@ -181,6 +182,7 @@ public PhoneStatusBarPolicy(Context context, StatusBarIconController iconControl filter.addAction(AudioManager.RINGER_MODE_CHANGED_ACTION); filter.addAction(AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION); filter.addAction(AudioManager.ACTION_HEADSET_PLUG); + filter.addAction(BluetoothDevice.ACTION_BATTERY_LEVEL_CHANGED); filter.addAction(TelephonyIntents.ACTION_SIM_STATE_CHANGED); filter.addAction(TelecomManager.ACTION_CURRENT_TTY_MODE_CHANGED); filter.addAction(Intent.ACTION_MANAGED_PROFILE_AVAILABLE); @@ -404,6 +406,30 @@ private final void updateBluetooth() { boolean bluetoothVisible = false; if (mBluetooth != null) { if (mBluetooth.isBluetoothConnected()) { + int batteryLevel = mBluetooth.getConnectedDevices().get(0).getBatteryLevel(); + if (batteryLevel == 100) { + iconId = R.drawable.stat_sys_data_bluetooth_connected_battery_9; + } else if (batteryLevel >= 90) { + iconId = R.drawable.stat_sys_data_bluetooth_connected_battery_8; + } else if (batteryLevel >= 80) { + iconId = R.drawable.stat_sys_data_bluetooth_connected_battery_7; + } else if (batteryLevel >= 70) { + iconId = R.drawable.stat_sys_data_bluetooth_connected_battery_6; + } else if (batteryLevel >= 60) { + iconId = R.drawable.stat_sys_data_bluetooth_connected_battery_5; + } else if (batteryLevel >= 50) { + iconId = R.drawable.stat_sys_data_bluetooth_connected_battery_4; + } else if (batteryLevel >= 40) { + iconId = R.drawable.stat_sys_data_bluetooth_connected_battery_3; + } else if (batteryLevel >= 30) { + iconId = R.drawable.stat_sys_data_bluetooth_connected_battery_2; + } else if (batteryLevel >= 20) { + iconId = R.drawable.stat_sys_data_bluetooth_connected_battery_1; + } else if (batteryLevel >= 10) { + iconId = R.drawable.stat_sys_data_bluetooth_connected_battery_0; + } else { + iconId = R.drawable.stat_sys_data_bluetooth_connected; + } contentDescription = mContext.getString(R.string.accessibility_bluetooth_connected); bluetoothVisible = mBluetooth.isBluetoothEnabled(); } @@ -685,6 +711,9 @@ public void onReceive(Context context, Intent intent) { case AudioManager.ACTION_HEADSET_PLUG: updateHeadsetPlug(intent); break; + case BluetoothDevice.ACTION_BATTERY_LEVEL_CHANGED: + updateBluetooth(); + break; } } }; From c7976efe8a3ba32cd82dc99a96008aba87a78cbe Mon Sep 17 00:00:00 2001 From: ezio84 Date: Sat, 10 Nov 2018 15:00:55 +0100 Subject: [PATCH 061/240] SystemUI: Improvements for bluetooth battery levels skip some states and devices Change-Id: I9de6257643a0caa1a473cd4158b7f4597de7a9ef --- .../statusbar/phone/PhoneStatusBarPolicy.java | 97 +++++++++++++------ 1 file changed, 69 insertions(+), 28 deletions(-) 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 a5bd67f1ddc..41471beadab 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java @@ -21,7 +21,9 @@ import android.app.AlarmManager; import android.app.AlarmManager.AlarmClockInfo; import android.app.SynchronousUserSwitchObserver; +import android.bluetooth.BluetoothClass; import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothProfile; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; @@ -40,6 +42,7 @@ import com.android.internal.telephony.IccCardConstants; import com.android.internal.telephony.TelephonyIntents; +import com.android.settingslib.bluetooth.CachedBluetoothDevice; import com.android.systemui.Dependency; import com.android.systemui.R; import com.android.systemui.SysUiServiceProvider; @@ -70,6 +73,7 @@ import java.io.PrintWriter; import java.io.StringWriter; +import java.util.Collection; import java.util.List; import java.util.Locale; @@ -403,40 +407,77 @@ private final void updateBluetooth() { int iconId = R.drawable.stat_sys_data_bluetooth_connected; String contentDescription = mContext.getString(R.string.accessibility_quick_settings_bluetooth_on); - boolean bluetoothVisible = false; + boolean bluetoothEnabled = false; if (mBluetooth != null) { - if (mBluetooth.isBluetoothConnected()) { - int batteryLevel = mBluetooth.getConnectedDevices().get(0).getBatteryLevel(); - if (batteryLevel == 100) { - iconId = R.drawable.stat_sys_data_bluetooth_connected_battery_9; - } else if (batteryLevel >= 90) { - iconId = R.drawable.stat_sys_data_bluetooth_connected_battery_8; - } else if (batteryLevel >= 80) { - iconId = R.drawable.stat_sys_data_bluetooth_connected_battery_7; - } else if (batteryLevel >= 70) { - iconId = R.drawable.stat_sys_data_bluetooth_connected_battery_6; - } else if (batteryLevel >= 60) { - iconId = R.drawable.stat_sys_data_bluetooth_connected_battery_5; - } else if (batteryLevel >= 50) { - iconId = R.drawable.stat_sys_data_bluetooth_connected_battery_4; - } else if (batteryLevel >= 40) { - iconId = R.drawable.stat_sys_data_bluetooth_connected_battery_3; - } else if (batteryLevel >= 30) { - iconId = R.drawable.stat_sys_data_bluetooth_connected_battery_2; - } else if (batteryLevel >= 20) { - iconId = R.drawable.stat_sys_data_bluetooth_connected_battery_1; - } else if (batteryLevel >= 10) { - iconId = R.drawable.stat_sys_data_bluetooth_connected_battery_0; - } else { - iconId = R.drawable.stat_sys_data_bluetooth_connected; + bluetoothEnabled = mBluetooth.isBluetoothEnabled(); + final Collection devices = mBluetooth.getDevices(); + if (devices != null) { + // get battery level for the first device with battery level support + for (CachedBluetoothDevice device : devices) { + // don't get the level if still pairing + if (mBluetooth.getBondState(device) == BluetoothDevice.BOND_NONE) continue; + int state = device.getMaxConnectionState(); + if (state == BluetoothProfile.STATE_CONNECTED) { + int batteryLevel = device.getBatteryLevel(); + BluetoothClass type = device.getBtClass(); + if (batteryLevel != BluetoothDevice.BATTERY_LEVEL_UNKNOWN && showBatteryForThis(type)) { + iconId = getBtLevelIconRes(batteryLevel); + } else { + iconId = R.drawable.stat_sys_data_bluetooth_connected; + } + contentDescription = mContext.getString(R.string.accessibility_bluetooth_connected); + break; + } } - contentDescription = mContext.getString(R.string.accessibility_bluetooth_connected); - bluetoothVisible = mBluetooth.isBluetoothEnabled(); } } mIconController.setIcon(mSlotBluetooth, iconId, contentDescription); - mIconController.setIconVisibility(mSlotBluetooth, bluetoothVisible); + mIconController.setIconVisibility(mSlotBluetooth, bluetoothEnabled); + } + + private int getBtLevelIconRes(int batteryLevel) { + if (batteryLevel == 100) { + return R.drawable.stat_sys_data_bluetooth_connected_battery_9; + } else if (batteryLevel >= 90) { + return R.drawable.stat_sys_data_bluetooth_connected_battery_8; + } else if (batteryLevel >= 80) { + return R.drawable.stat_sys_data_bluetooth_connected_battery_7; + } else if (batteryLevel >= 70) { + return R.drawable.stat_sys_data_bluetooth_connected_battery_6; + } else if (batteryLevel >= 60) { + return R.drawable.stat_sys_data_bluetooth_connected_battery_5; + } else if (batteryLevel >= 50) { + return R.drawable.stat_sys_data_bluetooth_connected_battery_4; + } else if (batteryLevel >= 40) { + return R.drawable.stat_sys_data_bluetooth_connected_battery_3; + } else if (batteryLevel >= 30) { + return R.drawable.stat_sys_data_bluetooth_connected_battery_2; + } else if (batteryLevel >= 20) { + return R.drawable.stat_sys_data_bluetooth_connected_battery_1; + } else if (batteryLevel >= 10) { + return R.drawable.stat_sys_data_bluetooth_connected_battery_0; + } else { + return R.drawable.stat_sys_data_bluetooth_connected; + } + } + + private boolean showBatteryForThis(BluetoothClass type) { + boolean show = false; + if (type != null) { + switch (type.getDeviceClass()) { + case BluetoothClass.Device.AUDIO_VIDEO_WEARABLE_HEADSET: + case BluetoothClass.Device.AUDIO_VIDEO_HANDSFREE: + show = true; + break; + default: + show = false; + break; + } + } else { + show = false; + } + return show; } private final void updateTTY() { From 828992f44b985a0c89da1a611bcf435259b07cb4 Mon Sep 17 00:00:00 2001 From: maxwen Date: Tue, 19 Dec 2017 13:00:24 +0100 Subject: [PATCH 062/240] SystemUI: Add more bluetooth device filters Change-Id: Iac7e7359b7ea5348f5340b6ca0902a709ad07137 --- .../android/systemui/statusbar/phone/PhoneStatusBarPolicy.java | 3 +++ 1 file changed, 3 insertions(+) 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 41471beadab..9ecf72002e8 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java @@ -468,6 +468,9 @@ private boolean showBatteryForThis(BluetoothClass type) { switch (type.getDeviceClass()) { case BluetoothClass.Device.AUDIO_VIDEO_WEARABLE_HEADSET: case BluetoothClass.Device.AUDIO_VIDEO_HANDSFREE: + case BluetoothClass.Device.AUDIO_VIDEO_PORTABLE_AUDIO: + case BluetoothClass.Device.AUDIO_VIDEO_LOUDSPEAKER: + case BluetoothClass.Device.AUDIO_VIDEO_HEADPHONES: show = true; break; default: From 553e58c406b598c271374baf9c3565c2d90949b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hern=C3=A1n=20Casta=C3=B1=C3=B3n=20=C3=81lvarez?= Date: Tue, 1 Oct 2019 14:36:12 +0000 Subject: [PATCH 063/240] SystemUI: update Bluetooth battery level assets. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Outlined and polished. Made by Andrew Fluck. Change-Id: I94fd78d5788306f64623e850a00302bb42b7897d Signed-off-by: Hernán Castañón Álvarez --- ...sys_data_bluetooth_connected_battery_0.xml | 51 +++++-------------- ...sys_data_bluetooth_connected_battery_1.xml | 51 +++++-------------- ...sys_data_bluetooth_connected_battery_2.xml | 51 +++++-------------- ...sys_data_bluetooth_connected_battery_3.xml | 51 +++++-------------- ...sys_data_bluetooth_connected_battery_4.xml | 51 +++++-------------- ...sys_data_bluetooth_connected_battery_5.xml | 51 +++++-------------- ...sys_data_bluetooth_connected_battery_6.xml | 51 +++++-------------- ...sys_data_bluetooth_connected_battery_7.xml | 51 +++++-------------- ...sys_data_bluetooth_connected_battery_8.xml | 51 +++++-------------- ...sys_data_bluetooth_connected_battery_9.xml | 47 +++++------------ 10 files changed, 139 insertions(+), 367 deletions(-) diff --git a/packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected_battery_0.xml b/packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected_battery_0.xml index 2df88bda48a..d81be28d95c 100644 --- a/packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected_battery_0.xml +++ b/packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected_battery_0.xml @@ -1,37 +1,14 @@ - - - - - - - - - + + + + diff --git a/packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected_battery_1.xml b/packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected_battery_1.xml index 39b22e2e7b4..d693ef1f8d8 100644 --- a/packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected_battery_1.xml +++ b/packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected_battery_1.xml @@ -1,37 +1,14 @@ - - - - - - - - - + + + + diff --git a/packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected_battery_2.xml b/packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected_battery_2.xml index a8684709e71..0054a85ea32 100644 --- a/packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected_battery_2.xml +++ b/packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected_battery_2.xml @@ -1,37 +1,14 @@ - - - - - - - - - + + + + diff --git a/packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected_battery_3.xml b/packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected_battery_3.xml index 63eadcd943d..26e5ab2cc1d 100644 --- a/packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected_battery_3.xml +++ b/packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected_battery_3.xml @@ -1,37 +1,14 @@ - - - - - - - - - + + + + diff --git a/packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected_battery_4.xml b/packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected_battery_4.xml index 1e768821065..a7de28269db 100644 --- a/packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected_battery_4.xml +++ b/packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected_battery_4.xml @@ -1,37 +1,14 @@ - - - - - - - - - + + + + diff --git a/packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected_battery_5.xml b/packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected_battery_5.xml index 2684bb9381f..b4757459df0 100644 --- a/packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected_battery_5.xml +++ b/packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected_battery_5.xml @@ -1,37 +1,14 @@ - - - - - - - - - + + + + diff --git a/packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected_battery_6.xml b/packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected_battery_6.xml index 62a0732ca19..a31dc3ce57c 100644 --- a/packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected_battery_6.xml +++ b/packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected_battery_6.xml @@ -1,37 +1,14 @@ - - - - - - - - - + + + + diff --git a/packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected_battery_7.xml b/packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected_battery_7.xml index b0bc839a33d..4ce70f41b20 100644 --- a/packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected_battery_7.xml +++ b/packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected_battery_7.xml @@ -1,37 +1,14 @@ - - - - - - - - - + + + + diff --git a/packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected_battery_8.xml b/packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected_battery_8.xml index 918fe80d10a..2b90d357c29 100644 --- a/packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected_battery_8.xml +++ b/packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected_battery_8.xml @@ -1,37 +1,14 @@ - - - - - - - - - + + + + diff --git a/packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected_battery_9.xml b/packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected_battery_9.xml index 862daa21e89..9202a5a5f30 100644 --- a/packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected_battery_9.xml +++ b/packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected_battery_9.xml @@ -1,34 +1,13 @@ - - - - - - - - + + + + From c8144ab4f25065317426d1d4d403c3b24e635a39 Mon Sep 17 00:00:00 2001 From: Evan Laird Date: Mon, 29 Jan 2018 16:01:41 -0500 Subject: [PATCH 064/240] Only show bluetooth icon when connected && enabled Return aosp commit Change-Id: I56c3bc18979d2286870ec5755538c944a86abda0 --- .../systemui/statusbar/phone/PhoneStatusBarPolicy.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) 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 9ecf72002e8..8be4188f7da 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java @@ -407,9 +407,8 @@ private final void updateBluetooth() { int iconId = R.drawable.stat_sys_data_bluetooth_connected; String contentDescription = mContext.getString(R.string.accessibility_quick_settings_bluetooth_on); - boolean bluetoothEnabled = false; + boolean bluetoothVisible = false; if (mBluetooth != null) { - bluetoothEnabled = mBluetooth.isBluetoothEnabled(); final Collection devices = mBluetooth.getDevices(); if (devices != null) { // get battery level for the first device with battery level support @@ -426,6 +425,7 @@ private final void updateBluetooth() { iconId = R.drawable.stat_sys_data_bluetooth_connected; } contentDescription = mContext.getString(R.string.accessibility_bluetooth_connected); + bluetoothVisible = mBluetooth.isBluetoothEnabled(); break; } } @@ -433,7 +433,7 @@ private final void updateBluetooth() { } mIconController.setIcon(mSlotBluetooth, iconId, contentDescription); - mIconController.setIconVisibility(mSlotBluetooth, bluetoothEnabled); + mIconController.setIconVisibility(mSlotBluetooth, bluetoothVisible); } private int getBtLevelIconRes(int batteryLevel) { From e8aab336cf11bf5d42fb20d15acf2e6582642d8a Mon Sep 17 00:00:00 2001 From: Jake Weinstein Date: Thu, 10 Oct 2019 04:48:33 +0200 Subject: [PATCH 065/240] perf: enable gesture fling boost by default This defaults to false when perfconfigstore is not present (pre-Q BSPs). Qualcomm enables this by default in all targets in Q, so we may as well do the same. Change-Id: Ica0d7f8824458470314cef66bee506cfc323328c --- services/core/java/com/android/server/wm/DisplayPolicy.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java index 3d217268327..b6db0afd249 100644 --- a/services/core/java/com/android/server/wm/DisplayPolicy.java +++ b/services/core/java/com/android/server/wm/DisplayPolicy.java @@ -506,7 +506,7 @@ private boolean isTopAppGame(String currentPackage, BoostFramework BoostType) { } if (mPerf != null) - SCROLL_BOOST_SS_ENABLE = Boolean.parseBoolean(mPerf.perfGetProp("vendor.perf.gestureflingboost.enable", "false")); + SCROLL_BOOST_SS_ENABLE = Boolean.parseBoolean(mPerf.perfGetProp("vendor.perf.gestureflingboost.enable", "true")); isLowRAM = SystemProperties.getBoolean("ro.config.low_ram", false); final Looper looper = UiThread.getHandler().getLooper(); From a325bdb046d86ea0ad9dbc0430db7ecb32b788e9 Mon Sep 17 00:00:00 2001 From: Pawit Pornkitprasan Date: Mon, 17 Nov 2014 18:59:57 +0100 Subject: [PATCH 066/240] Improve scrolling cache Scrolling cache helps make short scrolls/flings smooth but will cause stutter when long flings are made. This patch disables scrolling cache when long flings are made. This patch also fixes a related bug where scrolling cache will not be enabled properly when transitioning from flinging to scrolling. Patch Set 2: Calculate threshold based on maximum velocity (Sang Tae Park) Change-Id: Iad52a35120212c871ffd35df6184aeb678ee44aa Signed-off-by: Alex Naidis --- core/java/android/widget/AbsListView.java | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java index 95cd192ce12..84d18f041d6 100755 --- a/core/java/android/widget/AbsListView.java +++ b/core/java/android/widget/AbsListView.java @@ -664,6 +664,7 @@ public abstract class AbsListView extends AdapterView implements Te private int mMinimumVelocity; @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 124051740) private int mMaximumVelocity; + private int mDecacheThreshold; private float mVelocityScale = 1.0f; final boolean[] mIsScrap = new boolean[1]; @@ -950,6 +951,7 @@ private void initAbsListView() { } mMinimumVelocity = configuration.getScaledMinimumFlingVelocity(); mMaximumVelocity = configuration.getScaledMaximumFlingVelocity(); + mDecacheThreshold = mMaximumVelocity / 2; mOverscrollDistance = configuration.getScaledOverscrollDistance(); mOverflingDistance = configuration.getScaledOverflingDistance(); @@ -4755,7 +4757,7 @@ public void run() { // Keep the fling alive a little longer postDelayed(this, FLYWHEEL_TIMEOUT); } else { - endFling(); + endFling(false); // Don't disable the scrolling cache right after it was enabled mTouchMode = TOUCH_MODE_SCROLL; reportScrollStateChange(OnScrollListener.SCROLL_STATE_TOUCH_SCROLL); } @@ -4771,6 +4773,11 @@ public void run() { // Use AbsListView#fling(int) instead @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P) void start(int initialVelocity) { + if (Math.abs(initialVelocity) > mDecacheThreshold) { + // For long flings, scrolling cache causes stutter, so don't use it + clearScrollingCache(); + } + int initialY = initialVelocity < 0 ? Integer.MAX_VALUE : 0; mLastFlingY = initialY; mScroller.setInterpolator(null); @@ -4850,6 +4857,10 @@ void startScroll(int distance, int duration, boolean linear, // To interrupt a fling early you should use smoothScrollBy(0,0) instead @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P) void endFling() { + endFling(true); + } + + void endFling(boolean clearCache) { mTouchMode = TOUCH_MODE_REST; removeCallbacks(this); @@ -4858,7 +4869,8 @@ void endFling() { if (!mSuppressIdleStateChangeCall) { reportScrollStateChange(OnScrollListener.SCROLL_STATE_IDLE); } - clearScrollingCache(); + if (clearCache) + clearScrollingCache(); mScroller.abortAnimation(); if (mFlingStrictSpan != null) { From 0360b6bf42f9dd34f4b1aab44f5a341ea21c0626 Mon Sep 17 00:00:00 2001 From: Jake Weinstein Date: Thu, 13 Oct 2016 23:56:02 -0400 Subject: [PATCH 067/240] base: set scrolling friction to 0.006f Improves responsiveness Change-Id: I18a52ac84ba9c8274adc757e41ca2ca995d514f6 --- core/java/android/widget/AbsListView.java | 1 + core/java/android/widget/ScrollView.java | 1 + 2 files changed, 2 insertions(+) diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java index 84d18f041d6..bb02f3b8ca5 100755 --- a/core/java/android/widget/AbsListView.java +++ b/core/java/android/widget/AbsListView.java @@ -4768,6 +4768,7 @@ public void run() { FlingRunnable() { mScroller = new OverScroller(getContext()); + mScroller.setFriction(0.006f); } // Use AbsListView#fling(int) instead diff --git a/core/java/android/widget/ScrollView.java b/core/java/android/widget/ScrollView.java index 51b0950a754..6c9fef29db6 100644 --- a/core/java/android/widget/ScrollView.java +++ b/core/java/android/widget/ScrollView.java @@ -343,6 +343,7 @@ public int getMaxScrollAmount() { private void initScrollView() { mScroller = new OverScroller(getContext()); + mScroller.setFriction(0.006f); setFocusable(true); setDescendantFocusability(FOCUS_AFTER_DESCENDANTS); setWillNotDraw(false); From 1e137a3d27264050bcc5ea9ff044a078d01eaef7 Mon Sep 17 00:00:00 2001 From: BigBrother1984 Date: Thu, 13 Nov 2014 22:46:12 +0100 Subject: [PATCH 068/240] SystemUI: Tiny expanding improvement Change-Id: I2b650c31d44f9f5762f6510611813b1795cdc740 Signed-off-by: BigBrother1984 Signed-off-by: Alex Naidis --- packages/SystemUI/src/com/android/systemui/ExpandHelper.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/SystemUI/src/com/android/systemui/ExpandHelper.java b/packages/SystemUI/src/com/android/systemui/ExpandHelper.java index ecf4c0a86bf..4bec7a094c8 100644 --- a/packages/SystemUI/src/com/android/systemui/ExpandHelper.java +++ b/packages/SystemUI/src/com/android/systemui/ExpandHelper.java @@ -519,7 +519,6 @@ boolean startExpanding(ExpandableView v, int expandType) { mExpanding = true; mCallback.expansionStateChanged(true); if (DEBUG) Log.d(TAG, "scale type " + expandType + " beginning on view: " + v); - mCallback.setUserLockedChild(v, true); mScaler.setView(v); mOldHeight = mScaler.getHeight(); mCurrentHeight = mOldHeight; @@ -532,6 +531,7 @@ boolean startExpanding(ExpandableView v, int expandType) { if (DEBUG) Log.d(TAG, "working on a non-expandable child"); mNaturalHeight = mOldHeight; } + mCallback.setUserLockedChild(v, true); if (DEBUG) Log.d(TAG, "got mOldHeight: " + mOldHeight + " mNaturalHeight: " + mNaturalHeight); return true; From 7b086adfad743fbe152109c25fd704fcbb7ee240 Mon Sep 17 00:00:00 2001 From: Alex Naidis Date: Thu, 16 Mar 2017 14:59:53 +0100 Subject: [PATCH 069/240] ViewConfiguration: Set scroll friction to 0.012 Reduce scroll friction to a better default value which is used in Scroller and Overscroller. Change-Id: I66a7663a18bb80263c51f3d54a2bb1e3fe5d0b4d Signed-off-by: Alex Naidis --- core/java/android/view/ViewConfiguration.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/java/android/view/ViewConfiguration.java b/core/java/android/view/ViewConfiguration.java index 9e914d4e7d4..4de0fb53438 100644 --- a/core/java/android/view/ViewConfiguration.java +++ b/core/java/android/view/ViewConfiguration.java @@ -234,7 +234,7 @@ public class ViewConfiguration { * The coefficient of friction applied to flings/scrolls. */ @UnsupportedAppUsage - private static final float SCROLL_FRICTION = 0.015f; + private static final float SCROLL_FRICTION = 0.012f; /** * Max distance in dips to overscroll for edge effects From 3bc8a1187ecb33850b536f46c9b52332eb7606bf Mon Sep 17 00:00:00 2001 From: kukku14 Date: Mon, 7 Oct 2019 01:03:29 +0000 Subject: [PATCH 070/240] storage: Set all sdcards to visible If they are visible to apps the media scanner will scan them Change-Id: I9ddecbde29de3d846e5aa3ed6abf6e0d5d85344e Signed-off-by: kukku14 --- .../core/java/com/android/server/StorageManagerService.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java index 1babb196f61..e6f11ce60b6 100644 --- a/services/core/java/com/android/server/StorageManagerService.java +++ b/services/core/java/com/android/server/StorageManagerService.java @@ -1281,9 +1281,9 @@ private void onVolumeCreatedLocked(VolumeInfo vol) { vol.mountFlags |= VolumeInfo.MOUNT_FLAG_VISIBLE; } - // Adoptable public disks are visible to apps, since they meet - // public API requirement of being in a stable location. - if (vol.disk.isAdoptable()) { + // Set sdcards to visible to apps. If they are visible media is scanned + // and they can be used for other stuff. + if (vol.disk.isSd()) { vol.mountFlags |= VolumeInfo.MOUNT_FLAG_VISIBLE; } From 3f3ba2b92a2ae6feb4fbbfff204d50c3e3cd7e05 Mon Sep 17 00:00:00 2001 From: woongki min Date: Wed, 25 Sep 2019 11:50:48 +0900 Subject: [PATCH 071/240] Reduce unnecessary NotificationListener binder transaction. When package suspend occurs, API calls are made as many as the number of changed packages, resulting in unnecessary binder transactions. This can rapidly consume the async space on the NotificationListener side, such as the SystemUI. JavaBinder: !!! FAILED BINDER TRANSACTION !!! (parcel size = 8844) NotificationListeners: unable to notify listener (posted): android.service.notification.INotificationListener$Stub$Proxy@8ed47e2 NotificationListeners: android.os.DeadObjectException: Transaction failed on small parcel; remote process probably died Test: Occurs ACTION_PACKAGES_UNSUSPENDED/SUSPENDED with a pkgList size of 50 or more Test: Async space of SystemUI(NotificationListener) decreases and binder transaction fails. Change-Id: I58d42ecf39e13b3adce7652ae72147de0be00e89 --- .../notification/NotificationManagerService.java | 13 ++++++------- .../NotificationManagerServiceTest.java | 8 ++++++-- 2 files changed, 12 insertions(+), 9 deletions(-) mode change 100644 => 100755 services/core/java/com/android/server/notification/NotificationManagerService.java mode change 100644 => 100755 services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java old mode 100644 new mode 100755 index 719cf890255..4258254284c --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -1270,16 +1270,15 @@ public void onReceive(Context context, Intent intent) { uidList = new int[] {intent.getIntExtra(Intent.EXTRA_UID, -1)}; } if (pkgList != null && (pkgList.length > 0)) { - for (String pkgName : pkgList) { - if (cancelNotifications) { + if (cancelNotifications) { + for (String pkgName : pkgList) { cancelAllNotificationsInt(MY_UID, MY_PID, pkgName, null, 0, 0, !queryRestart, changeUserId, reason, null); - } else if (hideNotifications) { - hideNotificationsForPackages(pkgList); - } else if (unhideNotifications) { - unhideNotificationsForPackages(pkgList); } - + } else if (hideNotifications) { + hideNotificationsForPackages(pkgList); + } else if (unhideNotifications) { + unhideNotificationsForPackages(pkgList); } } diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java old mode 100644 new mode 100755 index 6c91e2f52f0..b5542afed46 --- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java @@ -3678,7 +3678,9 @@ public void testHideAndUnhideNotificationsOnDistractingPackageBroadcast_multiPkg mService.simulatePackageDistractionBroadcast( PackageManager.RESTRICTION_HIDE_NOTIFICATIONS, new String[] {"a", "b"}); ArgumentCaptor> captorHide = ArgumentCaptor.forClass(List.class); - verify(mListeners, times(2)).notifyHiddenLocked(captorHide.capture()); + + // should be called only once. + verify(mListeners, times(1)).notifyHiddenLocked(captorHide.capture()); assertEquals(2, captorHide.getValue().size()); assertEquals("a", captorHide.getValue().get(0).sbn.getPackageName()); assertEquals("b", captorHide.getValue().get(1).sbn.getPackageName()); @@ -3687,7 +3689,9 @@ public void testHideAndUnhideNotificationsOnDistractingPackageBroadcast_multiPkg mService.simulatePackageDistractionBroadcast( PackageManager.RESTRICTION_HIDE_FROM_SUGGESTIONS, new String[] {"a", "b"}); ArgumentCaptor> captorUnhide = ArgumentCaptor.forClass(List.class); - verify(mListeners, times(2)).notifyUnhiddenLocked(captorUnhide.capture()); + + // should be called only once. + verify(mListeners, times(1)).notifyUnhiddenLocked(captorUnhide.capture()); assertEquals(2, captorUnhide.getValue().size()); assertEquals("a", captorUnhide.getValue().get(0).sbn.getPackageName()); assertEquals("b", captorUnhide.getValue().get(1).sbn.getPackageName()); From c6d6f1a3daa52f40334ac45f45ffaeed71f9c097 Mon Sep 17 00:00:00 2001 From: Luca Stefani Date: Sat, 5 Jan 2019 16:40:12 +0100 Subject: [PATCH 072/240] WindowOrientationListener: Check if proposed rotation is in range * Some OEMs *coughs OnePlus* decided it was a great idea to add a fourth kind of rotation ( flat ) Change-Id: I54c6e6360e897fbc8445edabbf411807521c624b --- .../android/server/policy/WindowOrientationListener.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/services/core/java/com/android/server/policy/WindowOrientationListener.java b/services/core/java/com/android/server/policy/WindowOrientationListener.java index d5adb5e1c11..47370b644b9 100644 --- a/services/core/java/com/android/server/policy/WindowOrientationListener.java +++ b/services/core/java/com/android/server/policy/WindowOrientationListener.java @@ -1047,8 +1047,14 @@ public void onTouchEndLocked(long whenElapsedNanos) { @Override public void onSensorChanged(SensorEvent event) { int newRotation; + + int reportedRotation = (int) event.values[0]; + if (reportedRotation < 0 || reportedRotation > 3) { + return; + } + synchronized (mLock) { - mDesiredRotation = (int) event.values[0]; + mDesiredRotation = reportedRotation; newRotation = evaluateRotationChangeLocked(); } if (newRotation >=0) { From 1d513bde6ef5b7ef3bf34d35ea89ecf6003de94a Mon Sep 17 00:00:00 2001 From: "vincent.cw_lee" Date: Tue, 15 Oct 2019 16:25:41 +0800 Subject: [PATCH 073/240] Fix: Recent Apps not closing Root Cause: notifyTaskStackChanged() will be invoked on activity pause state or finishing an activity from recents. However, launcher and recent apps are the same activity on android Q by default, so close an app with back button(activity has been finished) and open recent apps from launcher(activity lifecycle does not change) will not notify listeners of task stack changes. Solution: Notify task stack changes directly when user swipe an app away from recent apps. Test: 1. Close an app with back button 2. Go to recent apps and close the same app by swipe it away 3. Exit recent apps with back button 4. Open recent apps again and the app should be removed from the list. Bug: https://issuetracker.google.com/issues/140142873 Change-Id: I1f58747d5164c45d66d53843e0b5b8c54662cdc3 --- services/core/java/com/android/server/wm/ActivityRecord.java | 4 ---- .../java/com/android/server/wm/ActivityStackSupervisor.java | 1 + 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java index 9997628bb02..9656b181379 100644 --- a/services/core/java/com/android/server/wm/ActivityRecord.java +++ b/services/core/java/com/android/server/wm/ActivityRecord.java @@ -1552,10 +1552,6 @@ void makeFinishingLocked() { if (stopped) { clearOptionsLocked(); } - - if (mAtmService != null) { - mAtmService.getTaskChangeNotificationController().notifyTaskStackChanged(); - } } UriPermissionOwner getUriPermissionsLocked() { diff --git a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java index c4fcc4c4725..d88219e85b6 100644 --- a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java +++ b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java @@ -1843,6 +1843,7 @@ boolean removeTaskByIdLocked(int taskId, boolean killProcess, boolean removeFrom tr.removeTaskActivitiesLocked(pauseImmediately, reason); cleanUpRemovedTaskLocked(tr, killProcess, removeFromRecents); mService.getLockTaskController().clearLockedTask(tr); + mService.getTaskChangeNotificationController().notifyTaskStackChanged(); if (tr.isPersistable) { mService.notifyTaskPersisterLocked(null, true); } From 86b5fff2a18c99b7b5addeee5a2e14347e5152ad Mon Sep 17 00:00:00 2001 From: TheScarastic Date: Fri, 30 Aug 2019 20:02:35 +0530 Subject: [PATCH 074/240] core: Add camera intents for camera state Change-Id: Ib2e87a86d1f9d26c82f7de42c8cbfe526395ed9e --- core/java/android/content/Intent.java | 15 ++++++++++ core/res/AndroidManifest.xml | 4 +++ .../server/camera/CameraServiceProxy.java | 29 +++++++++++++++++++ 3 files changed, 48 insertions(+) diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java index 990d8a94bd6..11d453c1253 100644 --- a/core/java/android/content/Intent.java +++ b/core/java/android/content/Intent.java @@ -4421,6 +4421,21 @@ public static Intent createChooser(Intent target, CharSequence title, IntentSend @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION) public static final String ACTION_VIEW_LOCUS = "android.intent.action.VIEW_LOCUS"; + /** + * Broadcast action: Camera satus Changed + * @hide + */ + public static final String ACTION_CAMERA_STATUS_CHANGED = + "android.intent.action.CAMERA_STATUS_CHANGED"; + + /** + * This field is part of the intent {@link #ACTION_CAMERA_STATUS_CHANGED}. + * Intent extra field for the state of changed camera state + * @hide + */ + public static final String EXTRA_CAMERA_STATE = + "android.intent.extra.CAMERA_STATE"; + // --------------------------------------------------------------------- // --------------------------------------------------------------------- // Standard intent categories (see addCategory()). diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index ce290d15f35..0dfc7b87be2 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -667,6 +667,10 @@ + + + + diff --git a/services/core/java/com/android/server/camera/CameraServiceProxy.java b/services/core/java/com/android/server/camera/CameraServiceProxy.java index b46f0348bd1..c9174364de6 100644 --- a/services/core/java/com/android/server/camera/CameraServiceProxy.java +++ b/services/core/java/com/android/server/camera/CameraServiceProxy.java @@ -33,6 +33,7 @@ import android.os.RemoteException; import android.os.SystemClock; import android.os.SystemProperties; +import android.os.UserHandle; import android.os.UserManager; import android.util.ArrayMap; import android.util.ArraySet; @@ -76,9 +77,11 @@ public class CameraServiceProxy extends SystemService // Handler message codes private static final int MSG_SWITCH_USER = 1; + private static final int MSG_CAMERA_CLOSED = 1001; private static final int RETRY_DELAY_TIME = 20; //ms private static final int RETRY_TIMES = 30; + private static final int CAMERA_EVENT_DELAY_TIME = 70; //ms // Maximum entries to keep in usage history before dumping out private static final int MAX_USAGE_HISTORY = 100; @@ -124,6 +127,8 @@ public class CameraServiceProxy extends SystemService private final @NfcNotifyState int mNotifyNfc; private boolean mLastNfcPollState = true; + private long mClosedEvent; + /** * Structure to track camera usage */ @@ -214,6 +219,21 @@ public void notifyCameraState(String cameraId, int newCameraState, int facing, state + " for client " + clientName + " API Level " + apiLevel); updateActivityCount(cameraId, newCameraState, facing, clientName, apiLevel); + + if (facing == ICameraServiceProxy.CAMERA_FACING_FRONT) { + switch (newCameraState) { + case ICameraServiceProxy.CAMERA_STATE_OPEN : { + if (SystemClock.elapsedRealtime() - mClosedEvent < CAMERA_EVENT_DELAY_TIME) { + mHandler.removeMessages(MSG_CAMERA_CLOSED); + } + sendCameraStateIntent("1"); + } break; + case ICameraServiceProxy.CAMERA_STATE_CLOSED : { + mClosedEvent = SystemClock.elapsedRealtime(); + mHandler.sendEmptyMessageDelayed(MSG_CAMERA_CLOSED, CAMERA_EVENT_DELAY_TIME); + } break; + } + } } }; @@ -238,6 +258,9 @@ public boolean handleMessage(Message msg) { case MSG_SWITCH_USER: { notifySwitchWithRetries(msg.arg1); } break; + case MSG_CAMERA_CLOSED: { + sendCameraStateIntent("0"); + } break; default: { Slog.e(TAG, "CameraServiceProxy error, invalid message: " + msg.what); } break; @@ -585,4 +608,10 @@ private static String nfcNotifyToString(@NfcNotifyState int nfcNotifyState) { } return "UNKNOWN_NFC_NOTIFY"; } + + private void sendCameraStateIntent(String cameraState) { + Intent intent = new Intent(android.content.Intent.ACTION_CAMERA_STATUS_CHANGED); + intent.putExtra(android.content.Intent.EXTRA_CAMERA_STATE, cameraState); + mContext.sendBroadcastAsUser(intent, UserHandle.SYSTEM); + } } From 38fc389abfe38218ec9cc4b9cc238e43921b535b Mon Sep 17 00:00:00 2001 From: paphonb Date: Sat, 14 Sep 2019 09:05:16 +0000 Subject: [PATCH 075/240] Add colors to assistant animation Change-Id: I5164c68b3f161ea594cc24ebe90db90bfebf3e94 --- packages/SystemUI/res/values/colors.xml | 4 ++++ .../android/systemui/assist/ui/InvocationLightsView.java | 8 ++++++++ 2 files changed, 12 insertions(+) diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml index 61816f60d0b..a3c6552d4db 100644 --- a/packages/SystemUI/res/values/colors.xml +++ b/packages/SystemUI/res/values/colors.xml @@ -179,6 +179,10 @@ #ffffffff + #ff4185f4 + #ff3aa853 + #ffea4234 + #fffbbc06 #F8F9FA diff --git a/packages/SystemUI/src/com/android/systemui/assist/ui/InvocationLightsView.java b/packages/SystemUI/src/com/android/systemui/assist/ui/InvocationLightsView.java index bb3bd781df6..51083961ed8 100644 --- a/packages/SystemUI/src/com/android/systemui/assist/ui/InvocationLightsView.java +++ b/packages/SystemUI/src/com/android/systemui/assist/ui/InvocationLightsView.java @@ -20,6 +20,7 @@ import android.annotation.ColorInt; import android.annotation.Nullable; import android.content.Context; +import android.content.res.Resources; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; @@ -114,6 +115,13 @@ public InvocationLightsView(Context context, AttributeSet attrs, int defStyleAtt for (int i = 0; i < 4; i++) { mAssistInvocationLights.add(new EdgeLight(Color.TRANSPARENT, 0, 0)); } + + Resources res = mContext.getResources(); + int colorRed = res.getColor(R.color.edge_light_red); + int colorYellow = res.getColor(R.color.edge_light_yellow); + int colorBlue = res.getColor(R.color.edge_light_blue); + int colorGreen = res.getColor(R.color.edge_light_green); + setColors(colorBlue, colorRed, colorYellow, colorGreen); } /** From ecb2e16db935691a5cc024362f9f81359bf31efa Mon Sep 17 00:00:00 2001 From: argraur Date: Sun, 12 May 2019 16:40:31 +0000 Subject: [PATCH 076/240] SystemUI: assist: disable old Assistant animations * Disable Assistant Disclosure animation * Disable Assistant Orb Signed-off-by: argraur Change-Id: Iedd354e056adff34646c02f8048717cf60b841a5 --- .../src/com/android/systemui/assist/AssistManager.java | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java b/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java index 1a2d062f1b8..c01298a961b 100644 --- a/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java +++ b/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java @@ -356,10 +356,6 @@ private void startAssistActivity(Bundle args, @NonNull ComponentName assistCompo intent.setComponent(assistComponent); intent.putExtras(args); - if (structureEnabled) { - showDisclosure(); - } - try { final ActivityOptions opts = ActivityOptions.makeCustomAnimation(mContext, R.anim.search_launch_enter, R.anim.search_launch_exit); @@ -449,9 +445,7 @@ private ComponentName getAssistInfo() { return getAssistInfoForUser(KeyguardUpdateMonitor.getCurrentUser()); } - public void showDisclosure() { - mAssistDisclosure.postShow(); - } + public void showDisclosure() {} public void onLockscreenShown() { mAssistUtils.onLockscreenShown(); From 1349cc3027e8c9d7fe6568d494610235b903c0b6 Mon Sep 17 00:00:00 2001 From: Daniel Colascione Date: Tue, 8 Oct 2019 11:47:41 -0700 Subject: [PATCH 077/240] Apply JNI optimizations to HwParcel This change reduces the JNI overhead of binder calls by about 160ns per parameter. Test: boots Change-Id: Ie3acdbf9f3ad48c884042ada5e63bd9757c6b2e6 --- core/java/android/os/HwParcel.java | 52 +++++++++++++++++++++++++++++- 1 file changed, 51 insertions(+), 1 deletion(-) diff --git a/core/java/android/os/HwParcel.java b/core/java/android/os/HwParcel.java index cfb582ef442..5e8929c6c99 100644 --- a/core/java/android/os/HwParcel.java +++ b/core/java/android/os/HwParcel.java @@ -23,6 +23,8 @@ import android.annotation.TestApi; import android.annotation.UnsupportedAppUsage; +import dalvik.annotation.optimization.FastNative; + import libcore.util.NativeAllocationRegistry; import java.lang.annotation.Retention; @@ -72,46 +74,54 @@ public HwParcel() { /** * Writes an interface token into the parcel used to verify that - * a transaction has made it to the write type of interface. + * a transaction has made it to the right type of interface. * * @param interfaceName fully qualified name of interface message * is being sent to. */ + @FastNative public native final void writeInterfaceToken(String interfaceName); /** * Writes a boolean value to the end of the parcel. * @param val to write */ + @FastNative public native final void writeBool(boolean val); /** * Writes a byte value to the end of the parcel. * @param val to write */ + @FastNative public native final void writeInt8(byte val); /** * Writes a short value to the end of the parcel. * @param val to write */ + @FastNative public native final void writeInt16(short val); /** * Writes a int value to the end of the parcel. * @param val to write */ + @FastNative public native final void writeInt32(int val); /** * Writes a long value to the end of the parcel. * @param val to write */ + @FastNative public native final void writeInt64(long val); /** * Writes a float value to the end of the parcel. * @param val to write */ + @FastNative public native final void writeFloat(float val); /** * Writes a double value to the end of the parcel. * @param val to write */ + @FastNative public native final void writeDouble(double val); /** * Writes a String value to the end of the parcel. @@ -120,6 +130,7 @@ public HwParcel() { * * @param val to write */ + @FastNative public native final void writeString(String val); /** * Writes a native handle (without duplicating the underlying @@ -127,42 +138,50 @@ public HwParcel() { * * @param val to write */ + @FastNative public native final void writeNativeHandle(@Nullable NativeHandle val); /** * Writes an array of boolean values to the end of the parcel. * @param val to write */ + @FastNative private native final void writeBoolVector(boolean[] val); /** * Writes an array of byte values to the end of the parcel. * @param val to write */ + @FastNative private native final void writeInt8Vector(byte[] val); /** * Writes an array of short values to the end of the parcel. * @param val to write */ + @FastNative private native final void writeInt16Vector(short[] val); /** * Writes an array of int values to the end of the parcel. * @param val to write */ + @FastNative private native final void writeInt32Vector(int[] val); /** * Writes an array of long values to the end of the parcel. * @param val to write */ + @FastNative private native final void writeInt64Vector(long[] val); /** * Writes an array of float values to the end of the parcel. * @param val to write */ + @FastNative private native final void writeFloatVector(float[] val); /** * Writes an array of double values to the end of the parcel. * @param val to write */ + @FastNative private native final void writeDoubleVector(double[] val); /** * Writes an array of String values to the end of the parcel. @@ -171,6 +190,7 @@ public HwParcel() { * * @param val to write */ + @FastNative private native final void writeStringVector(String[] val); /** * Writes an array of native handles to the end of the parcel. @@ -179,6 +199,7 @@ public HwParcel() { * * @param val array of {@link NativeHandle} objects to write */ + @FastNative private native final void writeNativeHandleVector(NativeHandle[] val); /** @@ -299,6 +320,7 @@ public final void writeNativeHandleVector(@NonNull ArrayList val) * Write a hwbinder object to the end of the parcel. * @param binder value to write */ + @FastNative public native final void writeStrongBinder(IHwBinder binder); /** @@ -314,48 +336,56 @@ public final void writeNativeHandleVector(@NonNull ArrayList val) * @return value parsed from the parcel * @throws IllegalArgumentException if the parcel has no more data */ + @FastNative public native final boolean readBool(); /** * Reads a byte value from the current location in the parcel. * @return value parsed from the parcel * @throws IllegalArgumentException if the parcel has no more data */ + @FastNative public native final byte readInt8(); /** * Reads a short value from the current location in the parcel. * @return value parsed from the parcel * @throws IllegalArgumentException if the parcel has no more data */ + @FastNative public native final short readInt16(); /** * Reads a int value from the current location in the parcel. * @return value parsed from the parcel * @throws IllegalArgumentException if the parcel has no more data */ + @FastNative public native final int readInt32(); /** * Reads a long value from the current location in the parcel. * @return value parsed from the parcel * @throws IllegalArgumentException if the parcel has no more data */ + @FastNative public native final long readInt64(); /** * Reads a float value from the current location in the parcel. * @return value parsed from the parcel * @throws IllegalArgumentException if the parcel has no more data */ + @FastNative public native final float readFloat(); /** * Reads a double value from the current location in the parcel. * @return value parsed from the parcel * @throws IllegalArgumentException if the parcel has no more data */ + @FastNative public native final double readDouble(); /** * Reads a String value from the current location in the parcel. * @return value parsed from the parcel * @throws IllegalArgumentException if the parcel has no more data */ + @FastNative public native final String readString(); /** * Reads a native handle (without duplicating the underlying file @@ -366,6 +396,7 @@ public final void writeNativeHandleVector(@NonNull ArrayList val) * @return a {@link NativeHandle} instance parsed from the parcel * @throws IllegalArgumentException if the parcel has no more data */ + @FastNative public native final @Nullable NativeHandle readNativeHandle(); /** * Reads an embedded native handle (without duplicating the underlying @@ -379,6 +410,7 @@ public final void writeNativeHandleVector(@NonNull ArrayList val) * @return a {@link NativeHandle} instance parsed from the parcel * @throws IllegalArgumentException if the parcel has no more data */ + @FastNative public native final @Nullable NativeHandle readEmbeddedNativeHandle( long parentHandle, long offset); @@ -387,54 +419,63 @@ public final void writeNativeHandleVector(@NonNull ArrayList val) * @return array of parsed values * @throws IllegalArgumentException if the parcel has no more data */ + @FastNative private native final boolean[] readBoolVectorAsArray(); /** * Reads an array of byte values from the parcel. * @return array of parsed values * @throws IllegalArgumentException if the parcel has no more data */ + @FastNative private native final byte[] readInt8VectorAsArray(); /** * Reads an array of short values from the parcel. * @return array of parsed values * @throws IllegalArgumentException if the parcel has no more data */ + @FastNative private native final short[] readInt16VectorAsArray(); /** * Reads an array of int values from the parcel. * @return array of parsed values * @throws IllegalArgumentException if the parcel has no more data */ + @FastNative private native final int[] readInt32VectorAsArray(); /** * Reads an array of long values from the parcel. * @return array of parsed values * @throws IllegalArgumentException if the parcel has no more data */ + @FastNative private native final long[] readInt64VectorAsArray(); /** * Reads an array of float values from the parcel. * @return array of parsed values * @throws IllegalArgumentException if the parcel has no more data */ + @FastNative private native final float[] readFloatVectorAsArray(); /** * Reads an array of double values from the parcel. * @return array of parsed values * @throws IllegalArgumentException if the parcel has no more data */ + @FastNative private native final double[] readDoubleVectorAsArray(); /** * Reads an array of String values from the parcel. * @return array of parsed values * @throws IllegalArgumentException if the parcel has no more data */ + @FastNative private native final String[] readStringVectorAsArray(); /** * Reads an array of native handles from the parcel. * @return array of {@link NativeHandle} objects * @throws IllegalArgumentException if the parcel has no more data */ + @FastNative private native final NativeHandle[] readNativeHandleAsArray(); /** @@ -537,6 +578,7 @@ public final ArrayList readStringVector() { * @return binder object read from parcel or null if no binder can be read * @throws IllegalArgumentException if the parcel has no more data */ + @FastNative public native final IHwBinder readStrongBinder(); /** @@ -544,6 +586,7 @@ public final ArrayList readStringVector() { * @return blob of size expectedSize * @throws IllegalArgumentException if the parcel has no more data */ + @FastNative public native final HwBlob readBuffer(long expectedSize); /** @@ -559,6 +602,7 @@ public final ArrayList readStringVector() { * @throws NullPointerException if the transaction specified the blob to be null * but nullable is false */ + @FastNative public native final HwBlob readEmbeddedBuffer( long expectedSize, long parentHandle, long offset, boolean nullable); @@ -567,26 +611,31 @@ public native final HwBlob readEmbeddedBuffer( * Write a buffer into the transaction. * @param blob blob to write into the parcel. */ + @FastNative public native final void writeBuffer(HwBlob blob); /** * Write a status value into the blob. * @param status value to write */ + @FastNative public native final void writeStatus(int status); /** * @throws IllegalArgumentException if a success vaue cannot be read * @throws RemoteException if success value indicates a transaction error */ + @FastNative public native final void verifySuccess(); /** * Should be called to reduce memory pressure when this object no longer needs * to be written to. */ + @FastNative public native final void releaseTemporaryStorage(); /** * Should be called when object is no longer needed to reduce possible memory * pressure if the Java GC does not get to this object in time. */ + @FastNative public native final void release(); /** @@ -597,6 +646,7 @@ public native final HwBlob readEmbeddedBuffer( // Returns address of the "freeFunction". private static native final long native_init(); + @FastNative private native final void native_setup(boolean allocate); static { From 9bab85cd73220bd9c00c62b71b653745f95e13f6 Mon Sep 17 00:00:00 2001 From: Winson Chung Date: Fri, 4 Oct 2019 10:37:12 -0700 Subject: [PATCH 078/240] Always allow back gesture when there are transient bars showing Bug: 142091458 Test: Open immersive sticky app with exclusion rects specified, ensure that when transient bars are showing that we don't respect the exclusion rects Change-Id: I98cd6ff3b003c6188e93289d8ff92dce5ff2a7ba --- .../statusbar/phone/EdgeBackGestureHandler.java | 17 +++++++++++++++++ .../statusbar/phone/NavigationBarFragment.java | 3 +++ .../statusbar/phone/NavigationBarView.java | 4 ++++ 3 files changed, 24 insertions(+) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/EdgeBackGestureHandler.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/EdgeBackGestureHandler.java index 3bef5822291..e011224169a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/EdgeBackGestureHandler.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/EdgeBackGestureHandler.java @@ -16,6 +16,8 @@ package com.android.systemui.statusbar.phone; import static android.view.Display.INVALID_DISPLAY; +import static android.view.View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY; +import static android.view.View.NAVIGATION_BAR_TRANSIENT; import android.content.Context; import android.content.pm.ParceledListSlice; @@ -154,6 +156,7 @@ public void onSystemGestureExclusionChanged(int displayId, private boolean mIsAttached; private boolean mIsGesturalModeEnabled; private boolean mIsEnabled; + private boolean mIsInTransientImmersiveStickyState; private InputMonitor mInputMonitor; private InputEventReceiver mInputEventReceiver; @@ -215,6 +218,12 @@ public void onNavigationModeChanged(int mode, Context currentUserContext) { updateCurrentUserResources(currentUserContext.getResources()); } + public void onSystemUiVisibilityChanged(int systemUiVisibility) { + mIsInTransientImmersiveStickyState = + (systemUiVisibility & SYSTEM_UI_FLAG_IMMERSIVE_STICKY) != 0 + && (systemUiVisibility & NAVIGATION_BAR_TRANSIENT) != 0; + } + private void disposeInputChannel() { if (mInputEventReceiver != null) { mInputEventReceiver.dispose(); @@ -315,13 +324,21 @@ private void onInputEvent(InputEvent ev) { } private boolean isWithinTouchRegion(int x, int y) { + // Disallow if over the IME if (y > (mDisplaySize.y - Math.max(mImeHeight, mNavBarHeight))) { return false; } + // Disallow if too far from the edge if (x > mEdgeWidth + mLeftInset && x < (mDisplaySize.x - mEdgeWidth - mRightInset)) { return false; } + + // Always allow if the user is in a transient sticky immersive state + if (mIsInTransientImmersiveStickyState) { + return true; + } + boolean isInExcludedRegion = mExcludeRegion.contains(x, y); if (isInExcludedRegion) { mOverviewProxyService.notifyBackAction(false /* completed */, -1, -1, diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java index e9731c52130..f5f2dd9d243 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java @@ -539,6 +539,9 @@ public void setSystemUiVisibility(int displayId, int vis, int fullscreenStackVis } mAutoHideController.touchAutoHide(); } + if (mNavigationBarView != null) { + mNavigationBarView.onSystemUiVisibilityChanged(mSystemUiVisibility); + } } mLightBarController.onNavigationVisibilityChanged( vis, mask, nbModeChanged, mNavigationBarMode, navbarColorManagedByIme); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java index a2740c8dc32..f0415cb0c69 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java @@ -349,6 +349,10 @@ public boolean onTouchEvent(MotionEvent event) { return super.onTouchEvent(event); } + void onSystemUiVisibilityChanged(int systemUiVisibility) { + mEdgeBackGestureHandler.onSystemUiVisibilityChanged(systemUiVisibility); + } + void onBarTransition(int newMode) { if (newMode == MODE_OPAQUE) { // If the nav bar background is opaque, stop auto tinting since we know the icons are From 8094d854a7175fddacd1edfe4aa1d16f969507cd Mon Sep 17 00:00:00 2001 From: Satish Chandra Date: Wed, 5 Jun 2019 14:32:14 +0800 Subject: [PATCH 079/240] Fix for, BT Carkit position issue when music app is killed When Music application is killed by user or lower memory killer, Playback state is not set to null (or to default). So, BT AVRCP display (or remote display) continues to display with last music song position. Bug: 134560226 Test: 1. Connect to BT carkit Test: 2. Play music with music apk Test: 3. Force stop music apk in phone settings->app->force stop Test: 4. Start navigation with map apk. Test: Manuallytested the above scenerio on two carkits. Change-Id: I84a8c245f4c2fc258a316f498e2737942d438af6 --- .../core/java/com/android/server/media/MediaSessionRecord.java | 1 + 1 file changed, 1 insertion(+) diff --git a/services/core/java/com/android/server/media/MediaSessionRecord.java b/services/core/java/com/android/server/media/MediaSessionRecord.java index e2087e6ca82..e6b41bf498b 100644 --- a/services/core/java/com/android/server/media/MediaSessionRecord.java +++ b/services/core/java/com/android/server/media/MediaSessionRecord.java @@ -456,6 +456,7 @@ public void onDestroy() { return; } mDestroyed = true; + mPlaybackState = null; mHandler.post(MessageHandler.MSG_DESTROYED); } } From 21afd218d3878485121afad356612c4f27227e0d Mon Sep 17 00:00:00 2001 From: Mathieu Chartier Date: Thu, 29 Aug 2019 11:59:15 -0700 Subject: [PATCH 080/240] Clean up class preloading Remove logic to set heap target utilization to 0.8. The default is 0.75 and this should not have any fragmentation benefit since the GC is compacting. Removed some unused logging and a variable. Test: TH Change-Id: Ife7219e94fa0aa7f489569e16248cdd23d09089a --- core/java/com/android/internal/os/ZygoteInit.java | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java index dffaf252195..f2d66ca2d1b 100644 --- a/core/java/com/android/internal/os/ZygoteInit.java +++ b/core/java/com/android/internal/os/ZygoteInit.java @@ -91,11 +91,6 @@ public class ZygoteInit { private static final int LOG_BOOT_PROGRESS_PRELOAD_START = 3020; private static final int LOG_BOOT_PROGRESS_PRELOAD_END = 3030; - /** - * when preloading, GC after allocating this many bytes - */ - private static final int PRELOAD_GC_THRESHOLD = 50000; - private static final String ABI_LIST_ARG = "--abi-list="; // TODO (chriswailes): Re-name this --zygote-socket-name= and then add a @@ -285,11 +280,6 @@ private static void preloadClasses() { droppedPriviliges = true; } - // Alter the target heap utilization. With explicit GCs this - // is not likely to have any effect. - float defaultUtilization = runtime.getTargetHeapUtilization(); - runtime.setTargetHeapUtilization(0.8f); - try { BufferedReader br = new BufferedReader(new InputStreamReader(is), Zygote.SOCKET_BUFFER_SIZE); @@ -305,9 +295,6 @@ private static void preloadClasses() { Trace.traceBegin(Trace.TRACE_TAG_DALVIK, line); try { - if (false) { - Log.v(TAG, "Preloading " + line + "..."); - } // Load and explicitly initialize the given class. Use // Class.forName(String, boolean, ClassLoader) to avoid repeated stack lookups // (to derive the caller's class-loader). Use true to force initialization, and @@ -338,8 +325,6 @@ private static void preloadClasses() { Log.e(TAG, "Error reading " + PRELOADED_CLASSES + ".", e); } finally { IoUtils.closeQuietly(is); - // Restore default. - runtime.setTargetHeapUtilization(defaultUtilization); // Fill in dex caches with classes, fields, and methods brought in by preloading. Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PreloadDexCaches"); From b3c348852838a16ffdb811df1d0c3d4caa5542d2 Mon Sep 17 00:00:00 2001 From: Yifan Hong Date: Fri, 16 Aug 2019 13:20:57 -0700 Subject: [PATCH 081/240] BatteryService: scheduleUpdate asynchronously IBatteryPropertiesRegistrar.scheduleUpdate calls IHealth.update() asynchronously. BatteryStatsImpl calls scheduleUpdate while holding a lock, which may lead to deadlocks if the remote process calls back to the framework. Fixes: 139503418 Test: monitor HealthScheduleUpdate trace points Change-Id: I8168d7c4e4a0b1d31343360d2c7f6d36c7aa692a --- .../com/android/server/BatteryService.java | 25 ++++++++++++------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/services/core/java/com/android/server/BatteryService.java b/services/core/java/com/android/server/BatteryService.java index 6a9f5b65101..d18b4f64f03 100644 --- a/services/core/java/com/android/server/BatteryService.java +++ b/services/core/java/com/android/server/BatteryService.java @@ -1235,14 +1235,21 @@ public int getProperty(int id, final BatteryProperty prop) throws RemoteExceptio } @Override public void scheduleUpdate() throws RemoteException { - traceBegin("HealthScheduleUpdate"); - try { - IHealth service = mHealthServiceWrapper.getLastService(); - if (service == null) throw new RemoteException("no health service"); - service.update(); - } finally { - traceEnd(); - } + mHealthServiceWrapper.getHandlerThread().getThreadHandler().post(() -> { + traceBegin("HealthScheduleUpdate"); + try { + IHealth service = mHealthServiceWrapper.getLastService(); + if (service == null) { + Slog.e(TAG, "no health service"); + return; + } + service.update(); + } catch (RemoteException ex) { + Slog.e(TAG, "Cannot call update on health HAL", ex); + } finally { + traceEnd(); + } + }); } } @@ -1319,7 +1326,7 @@ static final class HealthServiceWrapper { Arrays.asList(INSTANCE_VENDOR, INSTANCE_HEALTHD); private final IServiceNotification mNotification = new Notification(); - private final HandlerThread mHandlerThread = new HandlerThread("HealthServiceRefresh"); + private final HandlerThread mHandlerThread = new HandlerThread("HealthServiceHwbinder"); // These variables are fixed after init. private Callback mCallback; private IHealthSupplier mHealthSupplier; From 5106db40d09716693165ffc0442e47f96d5be940 Mon Sep 17 00:00:00 2001 From: Mingyan Liu Date: Wed, 24 Jul 2019 15:42:19 +0800 Subject: [PATCH 082/240] Resolve NumberPicker display abnormal issue. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bugid: https://partnerissuetracker.corp.google.com/u/0/issues/138241751 Change-Id: Id5971e59d30506b0be2c5347a1e2dd4bb8371eaa --- core/java/android/widget/NumberPicker.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/core/java/android/widget/NumberPicker.java b/core/java/android/widget/NumberPicker.java index 685e8de3c01..b385534f185 100644 --- a/core/java/android/widget/NumberPicker.java +++ b/core/java/android/widget/NumberPicker.java @@ -922,10 +922,12 @@ public boolean onInterceptTouchEvent(MotionEvent event) { if (!mFlingScroller.isFinished()) { mFlingScroller.forceFinished(true); mAdjustScroller.forceFinished(true); + onScrollerFinished(mFlingScroller); onScrollStateChange(OnScrollListener.SCROLL_STATE_IDLE); } else if (!mAdjustScroller.isFinished()) { mFlingScroller.forceFinished(true); mAdjustScroller.forceFinished(true); + onScrollerFinished(mAdjustScroller); } else if (mLastDownEventY < mTopSelectionDividerTop) { postChangeCurrentByOneFromLongPress( false, ViewConfiguration.getLongPressTimeout()); From b3c27a85c91ec8e6f0199532ca85b84f31ecd780 Mon Sep 17 00:00:00 2001 From: liuxiaoyu7 Date: Thu, 19 Dec 2019 16:06:08 +0800 Subject: [PATCH 083/240] [Bugfix]audioservice:fix voice_call default volume if default and max property key is not be configured,maxvolume will be -1 so default volume will be set to -1. Change-Id: I11406786ca46d458d3feb6f57825a2a7bbc35346 Signed-off-by: liuxiaoyu7 --- services/core/java/com/android/server/audio/AudioService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java index 54ec30d5cd9..d244d11e822 100644 --- a/services/core/java/com/android/server/audio/AudioService.java +++ b/services/core/java/com/android/server/audio/AudioService.java @@ -689,7 +689,7 @@ public AudioService(Context context) { AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL] = defaultCallVolume; } else { AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL] = - (maxCallVolume * 3) / 4; + (MAX_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL] * 3) / 4; } int maxMusicVolume = SystemProperties.getInt("ro.config.media_vol_steps", -1); From 381f5f8f645dca44cdf8e6bc1367160cc36268d2 Mon Sep 17 00:00:00 2001 From: Arne Coucheron Date: Sat, 19 Oct 2019 17:48:59 +0200 Subject: [PATCH 084/240] SystemUI: Make BrightlineFalsingManager depend on config The anti-falsing implementation regularly prevents easy swipe to unlock or to pattern / pin on the keyguard lockscreen, requiring multiple attempts until accepted. Change-Id: Ib91fc2386f70f56aad68a0f7ad2e3445fbb42d79 --- .../android/systemui/classifier/FalsingManagerProxy.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerProxy.java b/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerProxy.java index cff06227b85..f3bb227e0d7 100644 --- a/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerProxy.java +++ b/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerProxy.java @@ -20,6 +20,7 @@ import static com.android.systemui.Dependency.MAIN_HANDLER_NAME; import android.content.Context; +import android.content.res.Resources; import android.net.Uri; import android.os.Handler; import android.provider.DeviceConfig; @@ -27,6 +28,7 @@ import com.android.internal.annotations.VisibleForTesting; import com.android.keyguard.KeyguardUpdateMonitor; +import com.android.systemui.R; import com.android.systemui.classifier.brightline.BrightLineFalsingManager; import com.android.systemui.classifier.brightline.FalsingDataProvider; import com.android.systemui.plugins.FalsingManager; @@ -96,8 +98,10 @@ private void onDeviceConfigPropertiesChanged(Context context, String namespace) */ @VisibleForTesting public void setupFalsingManager(Context context) { + Resources res = context.getResources(); boolean brightlineEnabled = DeviceConfig.getBoolean( - DeviceConfig.NAMESPACE_SYSTEMUI, BRIGHTLINE_FALSING_MANAGER_ENABLED, true); + DeviceConfig.NAMESPACE_SYSTEMUI, BRIGHTLINE_FALSING_MANAGER_ENABLED, + res.getBoolean(R.bool.config_lockscreenAntiFalsingClassifierEnabled)); if (mInternalFalsingManager != null) { mInternalFalsingManager.cleanup(); From 2d725a7894c7f8f79cf7d3ba56e67fb1fc4e3cb1 Mon Sep 17 00:00:00 2001 From: Jake Weinstein Date: Sat, 19 Oct 2019 19:27:36 +0200 Subject: [PATCH 085/240] CarrierConfigManager: enable LTE+ icon by default By popular demand. Change-Id: Ic8819c9b9cf5d1469a47f3d16cd10918285f40f9 --- telephony/java/android/telephony/CarrierConfigManager.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java index 43f63f6e410..50f0bb797c7 100644 --- a/telephony/java/android/telephony/CarrierConfigManager.java +++ b/telephony/java/android/telephony/CarrierConfigManager.java @@ -3513,7 +3513,7 @@ private Wifi() {} sDefaults.putBoolean(KEY_SHOW_4G_FOR_3G_DATA_ICON_BOOL, false); sDefaults.putString(KEY_OPERATOR_NAME_FILTER_PATTERN_STRING, ""); sDefaults.putString(KEY_SHOW_CARRIER_DATA_ICON_PATTERN_STRING, ""); - sDefaults.putBoolean(KEY_HIDE_LTE_PLUS_DATA_ICON_BOOL, true); + sDefaults.putBoolean(KEY_HIDE_LTE_PLUS_DATA_ICON_BOOL, false); sDefaults.putBoolean(KEY_LTE_ENABLED_BOOL, true); sDefaults.putBoolean(KEY_SUPPORT_TDSCDMA_BOOL, false); sDefaults.putStringArray(KEY_SUPPORT_TDSCDMA_ROAMING_NETWORKS_STRING_ARRAY, null); From 908e84e765876f78fc6e55da125da5a643387629 Mon Sep 17 00:00:00 2001 From: Fabian Leutenegger Date: Sat, 28 Sep 2019 14:52:55 +0200 Subject: [PATCH 086/240] SystemUI: Don't show build version in QS footer Change-Id: I012b70d5b1ad247f7ee34b545c043a6d4d556475 --- .../src/com/android/systemui/qs/QSFooterImpl.java | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFooterImpl.java b/packages/SystemUI/src/com/android/systemui/qs/QSFooterImpl.java index 644664ecaee..0c9d9277864 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSFooterImpl.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSFooterImpl.java @@ -165,15 +165,7 @@ protected void onFinishInflate() { private void setBuildText() { TextView v = findViewById(R.id.build); if (v == null) return; - if (DevelopmentSettingsEnabler.isDevelopmentSettingsEnabled(mContext)) { - v.setText(mContext.getString( - com.android.internal.R.string.bugreport_status, - Build.VERSION.RELEASE, - Build.ID)); - v.setVisibility(View.VISIBLE); - } else { - v.setVisibility(View.GONE); - } + v.setVisibility(View.GONE); } private void updateAnimator(int width) { From dfb21d6ccf7f63e10fd63a014ca4fef876079cfb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hern=C3=A1n=20Casta=C3=B1=C3=B3n=20=C3=81lvarez?= Date: Sat, 27 Jul 2019 12:26:14 +0200 Subject: [PATCH 087/240] SystemUI: hide Emergency button on bottom lockscreen for everyone. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Hernán Castañón Álvarez Change-Id: I0955268324debef97c0e53c6362e87665352c5da --- .../systemui/statusbar/phone/KeyguardBottomAreaView.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java index 8e57276c100..8ec9d5362a1 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java @@ -247,6 +247,7 @@ protected void onFinishInflate() { updateCameraVisibility(); mUnlockMethodCache = UnlockMethodCache.getInstance(getContext()); mUnlockMethodCache.addListener(this); + mEmergencyCarrierArea.setVisibility(INVISIBLE); setClipChildren(false); setClipToPadding(false); inflateCameraPreview(); @@ -739,7 +740,7 @@ public void setDozing(boolean dozing, boolean animate) { mEmergencyCarrierArea.setVisibility(INVISIBLE); } else { mOverlayContainer.setVisibility(VISIBLE); - mEmergencyCarrierArea.setVisibility(VISIBLE); + mEmergencyCarrierArea.setVisibility(INVISIBLE); if (animate) { startFinishDozeAnimation(); } From 636f75834087ebf0e26312b3aca254871aab006a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hern=C3=A1n=20Casta=C3=B1=C3=B3n=20=C3=81lvarez?= Date: Wed, 20 Nov 2019 21:16:17 +0000 Subject: [PATCH 088/240] SystemUI: actually set emergency button visibility to gone. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Seems to cause some weird looking issues on devices with no fod. Signed-off-by: Hernán Castañón Álvarez Change-Id: Ia86193956292d221d4add916ad0fa3cb87a0dead --- .../systemui/statusbar/phone/KeyguardBottomAreaView.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java index 8ec9d5362a1..fe1eb53ab8b 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java @@ -247,7 +247,7 @@ protected void onFinishInflate() { updateCameraVisibility(); mUnlockMethodCache = UnlockMethodCache.getInstance(getContext()); mUnlockMethodCache.addListener(this); - mEmergencyCarrierArea.setVisibility(INVISIBLE); + mEmergencyCarrierArea.setVisibility(GONE); setClipChildren(false); setClipToPadding(false); inflateCameraPreview(); @@ -740,7 +740,7 @@ public void setDozing(boolean dozing, boolean animate) { mEmergencyCarrierArea.setVisibility(INVISIBLE); } else { mOverlayContainer.setVisibility(VISIBLE); - mEmergencyCarrierArea.setVisibility(INVISIBLE); + mEmergencyCarrierArea.setVisibility(GONE); if (animate) { startFinishDozeAnimation(); } From 8497e9a771da07c5865facd2a7f219fab3721113 Mon Sep 17 00:00:00 2001 From: jhenrique09 Date: Mon, 13 Aug 2018 14:41:44 -0400 Subject: [PATCH 089/240] SystemUI: Remove GarbageMonitor tile Change-Id: I96e8b3d281133c0fad889caabb07a30462ef8e9c --- .../com/android/systemui/qs/customize/TileQueryHelper.java | 4 ++-- .../src/com/android/systemui/qs/tileimpl/QSFactoryImpl.java | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/qs/customize/TileQueryHelper.java b/packages/SystemUI/src/com/android/systemui/qs/customize/TileQueryHelper.java index 70062492c16..b9f2e208bae 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/customize/TileQueryHelper.java +++ b/packages/SystemUI/src/com/android/systemui/qs/customize/TileQueryHelper.java @@ -97,9 +97,9 @@ private void addCurrentAndStockTiles(QSTileHost host) { possibleTiles.add(spec); } } - if (Build.IS_DEBUGGABLE && !current.contains(GarbageMonitor.MemoryTile.TILE_SPEC)) { + /*if (Build.IS_DEBUGGABLE && !current.contains(GarbageMonitor.MemoryTile.TILE_SPEC)) { possibleTiles.add(GarbageMonitor.MemoryTile.TILE_SPEC); - } + }*/ final ArrayList tilesToAdd = new ArrayList<>(); for (String spec : possibleTiles) { diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSFactoryImpl.java b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSFactoryImpl.java index daaee4cd533..b8f51014569 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSFactoryImpl.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSFactoryImpl.java @@ -177,11 +177,11 @@ private QSTileImpl createTileInternal(String tileSpec) { if (tileSpec.startsWith(CustomTile.PREFIX)) return CustomTile.create(mHost, tileSpec); // Debug tiles. - if (Build.IS_DEBUGGABLE) { + /*if (Build.IS_DEBUGGABLE) { if (tileSpec.equals(GarbageMonitor.MemoryTile.TILE_SPEC)) { return mMemoryTileProvider.get(); } - } + }*/ // Broken tiles. Log.w(TAG, "No stock tile spec: " + tileSpec); From 1da67a4a2d3b4b387ec41e090470e0c3432b274e Mon Sep 17 00:00:00 2001 From: Tom Marshall Date: Tue, 24 Nov 2015 15:28:43 -0800 Subject: [PATCH 090/240] storage: Do not notify for volumes on non-removable disks Change-Id: Ia353ab43fbeba42d7d9c21d926f638f550a3dbbe --- core/java/android/os/storage/DiskInfo.java | 5 +++++ .../src/com/android/systemui/usb/StorageNotification.java | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/core/java/android/os/storage/DiskInfo.java b/core/java/android/os/storage/DiskInfo.java index 19d1ce16687..63ea6a73757 100644 --- a/core/java/android/os/storage/DiskInfo.java +++ b/core/java/android/os/storage/DiskInfo.java @@ -52,6 +52,7 @@ public class DiskInfo implements Parcelable { public static final int FLAG_USB = 1 << 3; public static final int FLAG_EMMC = 1 << 4; public static final int FLAG_UFS_CARD = 1 << 5; + public static final int FLAG_NON_REMOVABLE = 1 << 6; public final String id; @UnsupportedAppUsage @@ -154,6 +155,10 @@ public boolean isUsb() { return (flags & FLAG_USB) != 0; } + public boolean isNonRemovable() { + return (flags & FLAG_NON_REMOVABLE) != 0; + } + @Override public String toString() { final CharArrayWriter writer = new CharArrayWriter(); diff --git a/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java b/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java index ff5bd03740b..d90338c3435 100644 --- a/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java +++ b/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java @@ -287,6 +287,11 @@ private void onPrivateVolumeStateChangedInternal(VolumeInfo vol) { } private void onPublicVolumeStateChangedInternal(VolumeInfo vol) { + // Do not notify for volumes on non-removable disks + if (vol.disk.isNonRemovable()) { + return; + } + Log.d(TAG, "Notifying about public volume: " + vol.toString()); final Notification notif; From e9d2103c4ec3781b7b59d42f4d62e9964dd03851 Mon Sep 17 00:00:00 2001 From: Lucchetto Date: Wed, 4 Dec 2019 18:53:28 +0100 Subject: [PATCH 091/240] Revert "Apply front scrim to doze pulsing" This reverts commit d424e202b361ce1b055367f107f5d87118456ce8. Fixes doze pulse notification Change-Id: I208a06cbe9cf87f733932a0248a5a4a3c9ea6cad Signed-off-by: Lucchetto Signed-off-by: DennySPB --- .../systemui/statusbar/phone/ScrimController.java | 9 ++++----- .../android/systemui/statusbar/phone/ScrimState.java | 2 +- .../statusbar/phone/ScrimControllerTest.java | 12 +----------- 3 files changed, 6 insertions(+), 17 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java index 9019e9a3f44..12c6be4be95 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java @@ -455,11 +455,11 @@ private void applyExpansionToAlpha() { if (mDarkenWhileDragging) { mCurrentBehindAlpha = MathUtils.lerp(GRADIENT_SCRIM_ALPHA_BUSY, alphaBehind, interpolatedFract); - mCurrentInFrontAlpha = mState.getFrontAlpha(); + mCurrentInFrontAlpha = 0; } else { mCurrentBehindAlpha = MathUtils.lerp(0 /* start */, alphaBehind, interpolatedFract); - mCurrentInFrontAlpha = mState.getFrontAlpha(); + mCurrentInFrontAlpha = 0; } mCurrentBehindTint = ColorUtils.blendARGB(ScrimState.BOUNCER.getBehindTint(), mState.getBehindTint(), interpolatedFract); @@ -485,14 +485,13 @@ public void setScrimBehindDrawable(Drawable drawable) { * device is dozing when the light sensor is on. */ public void setAodFrontScrimAlpha(float alpha) { - if (((mState == ScrimState.AOD && mDozeParameters.getAlwaysOn()) - || mState == ScrimState.PULSING) && mCurrentInFrontAlpha != alpha) { + if (mState == ScrimState.AOD && mDozeParameters.getAlwaysOn() + && mCurrentInFrontAlpha != alpha) { mCurrentInFrontAlpha = alpha; updateScrims(); } mState.AOD.setAodFrontScrimAlpha(alpha); - mState.PULSING.setAodFrontScrimAlpha(alpha); } /** diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java index 5fa861c8a2a..3769924ec0c 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java @@ -127,7 +127,7 @@ public boolean isLowPowerState() { PULSING(5) { @Override public void prepare(ScrimState previousState) { - mCurrentInFrontAlpha = mAodFrontScrimAlpha; + mCurrentInFrontAlpha = 0; mCurrentBehindTint = Color.BLACK; mCurrentInFrontTint = Color.BLACK; mBlankScreen = mDisplayRequiresBlanking; diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java index 205312ca508..9918d1946b1 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java @@ -216,7 +216,7 @@ public void transitionToAod_withFrontAlphaUpdates() { } @Test - public void transitionToPulsing_withFrontAlphaUpdates() { + public void transitionToPulsing() { // Pre-condition // Need to go to AoD first because PULSING doesn't change // the back scrim opacity - otherwise it would hide AoD wallpapers. @@ -233,20 +233,10 @@ public void transitionToPulsing_withFrontAlphaUpdates() { assertScrimVisibility(VISIBILITY_FULLY_TRANSPARENT, VISIBILITY_FULLY_OPAQUE); assertScrimTint(mScrimBehind, true /* tinted */); - // ... and when ambient goes dark, front scrim should be semi-transparent - mScrimController.setAodFrontScrimAlpha(0.5f); - mScrimController.finishAnimationsImmediately(); - // Front scrim should be semi-transparent - assertScrimVisibility(VISIBILITY_SEMI_TRANSPARENT /* front */, - VISIBILITY_FULLY_OPAQUE /* back */); - mScrimController.setWakeLockScreenSensorActive(true); mScrimController.finishAnimationsImmediately(); assertScrimVisibility(VISIBILITY_SEMI_TRANSPARENT /* front */, VISIBILITY_SEMI_TRANSPARENT /* back */); - - // Reset value since enums are static. - mScrimController.setAodFrontScrimAlpha(0f); } @Test From f1caff4e070013d9405687fd246920cc4ddac73f Mon Sep 17 00:00:00 2001 From: xiamengsen Date: Thu, 5 Dec 2019 10:42:34 +0800 Subject: [PATCH 092/240] [BugFix]Fix enter deep doze when moving We should reset mRunningStats after getStationaryStatus as it was used in getStationaryStatus. This issue leads to enter deep doze and disable gps when driving. Change-Id: I0e43c64e89ec1450f9241d0a550dde17de37bee0 Signed-off-by: xiamengsen --- services/core/java/com/android/server/AnyMotionDetector.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/core/java/com/android/server/AnyMotionDetector.java b/services/core/java/com/android/server/AnyMotionDetector.java index 8c5ee7f3502..316306df4f4 100644 --- a/services/core/java/com/android/server/AnyMotionDetector.java +++ b/services/core/java/com/android/server/AnyMotionDetector.java @@ -231,8 +231,8 @@ private int stopOrientationMeasurementLocked() { Slog.d(TAG, "mCurrentGravityVector = " + currentGravityVectorString); Slog.d(TAG, "mPreviousGravityVector = " + previousGravityVectorString); } - mRunningStats.reset(); status = getStationaryStatus(); + mRunningStats.reset(); if (DEBUG) Slog.d(TAG, "getStationaryStatus() returned " + status); if (status != RESULT_UNKNOWN) { if (mWakeLock.isHeld()) { From 6f64dbad9a4ee110d26b3fbe6f6942669e3ba433 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hern=C3=A1n=20Casta=C3=B1=C3=B3n=20=C3=81lvarez?= Date: Mon, 25 Nov 2019 17:33:37 -0500 Subject: [PATCH 093/240] base: Disable WiFi/Hotspot generation numbering MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We will use a boolean so we can enable if desired again. Signed-off-by: Hernán Castañón Álvarez Change-Id: I8528ffe2270f26773edd6e88a1cf2b6f6740b7d4 --- core/res/res/values/reloaded_config.xml | 3 ++ core/res/res/values/reloaded_symbols.xml | 3 ++ .../src/com/android/settingslib/Utils.java | 34 +++++++++++-------- .../wifi/AccessPointPreference.java | 2 +- .../systemui/qs/tiles/HotspotTile.java | 4 ++- .../statusbar/phone/PhoneStatusBarPolicy.java | 22 +++++++----- .../policy/WifiSignalController.java | 18 ++++++---- 7 files changed, 55 insertions(+), 31 deletions(-) diff --git a/core/res/res/values/reloaded_config.xml b/core/res/res/values/reloaded_config.xml index 2b2d07383da..225ef6b58b9 100644 --- a/core/res/res/values/reloaded_config.xml +++ b/core/res/res/values/reloaded_config.xml @@ -32,4 +32,7 @@ + + false + diff --git a/core/res/res/values/reloaded_symbols.xml b/core/res/res/values/reloaded_symbols.xml index ff9367a09fb..08904de935f 100644 --- a/core/res/res/values/reloaded_symbols.xml +++ b/core/res/res/values/reloaded_symbols.xml @@ -24,4 +24,7 @@ + + + diff --git a/packages/SettingsLib/src/com/android/settingslib/Utils.java b/packages/SettingsLib/src/com/android/settingslib/Utils.java index 31b3548b2da..9c447983b67 100644 --- a/packages/SettingsLib/src/com/android/settingslib/Utils.java +++ b/packages/SettingsLib/src/com/android/settingslib/Utils.java @@ -353,25 +353,31 @@ public static boolean isDeviceProvisioningPackage(Resources resources, String pa * @param level The number of bars to show (0-4) * @throws IllegalArgumentException if an invalid RSSI level is given. */ - public static int getWifiIconResource(int level, int generation, boolean isReady) { + public static int getWifiIconResource(int level, int generation, boolean isReady, Context context) { if (level < 0 || level >= WIFI_PIE.length) { throw new IllegalArgumentException("No Wifi icon found for level: " + level); } - switch (generation) { - case 4: - return WIFI_4_PIE[level]; - case 5: - if (isReady) { + boolean useNetworkNum = context.getResources().getBoolean( + com.android.internal.R.bool.config_show_network_generation); + if (useNetworkNum) { + switch (generation) { + case 4: + return WIFI_4_PIE[level]; + case 5: + if (isReady) { + return WIFI_6_PIE[level]; + } else { + return WIFI_5_PIE[level]; + } + case 6: return WIFI_6_PIE[level]; - } else { - return WIFI_5_PIE[level]; - } - case 6: - return WIFI_6_PIE[level]; - default: - return WIFI_PIE[level]; - } + default: + return WIFI_PIE[level]; + } + } else { + return WIFI_PIE[level]; + } } public static int getDefaultStorageManagerDaysToRetain(Resources resources) { diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPointPreference.java b/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPointPreference.java index 9c3c805a32b..ac96c1564ab 100644 --- a/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPointPreference.java +++ b/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPointPreference.java @@ -354,7 +354,7 @@ public IconInjector(Context context) { } public Drawable getIcon(int level, int generation, boolean isReady) { - return mContext.getDrawable(Utils.getWifiIconResource(level, generation, isReady)); + return mContext.getDrawable(Utils.getWifiIconResource(level, generation, isReady, mContext)); } } } diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java index 1fca02bf27f..9d954a56c4a 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java @@ -118,6 +118,8 @@ protected void handleUpdateState(BooleanState state, Object arg) { final int numConnectedDevices; final boolean isTransient = transientEnabling || mHotspotController.isHotspotTransient(); final boolean isDataSaverEnabled; + final boolean useNetworkNum = mContext.getResources().getBoolean( + com.android.internal.R.bool.config_show_network_generation); checkIfRestrictionEnforcedByAdminOnly(state, UserManager.DISALLOW_CONFIG_TETHERING); @@ -139,7 +141,7 @@ protected void handleUpdateState(BooleanState state, Object arg) { if (state.isTransient) { state.icon = ResourceIcon.get( com.android.internal.R.drawable.ic_hotspot_transient_animation); - } else if (state.value) { + } else if (state.value && useNetworkNum) { int generation = mWifiManager.getSoftApWifiGeneration(); if (generation == WifiManager.WIFI_GENERATION_6) { state.icon = mWifi6EnabledStatic; 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 8be4188f7da..ade139d0e47 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java @@ -772,15 +772,19 @@ public void run() { private void updateHotspotIcon() { int generation = mWifiManager.getSoftApWifiGeneration(); - if (generation == WifiManager.WIFI_GENERATION_6) { - mIconController.setIcon(mSlotHotspot, R.drawable.stat_sys_wifi_6_hotspot, - mContext.getString(R.string.accessibility_status_bar_hotspot)); - } else if (generation == WifiManager.WIFI_GENERATION_5) { - mIconController.setIcon(mSlotHotspot, R.drawable.stat_sys_wifi_5_hotspot, - mContext.getString(R.string.accessibility_status_bar_hotspot)); - } else if (generation == WifiManager.WIFI_GENERATION_4) { - mIconController.setIcon(mSlotHotspot, R.drawable.stat_sys_wifi_4_hotspot, - mContext.getString(R.string.accessibility_status_bar_hotspot)); + boolean useNetworkNum = mContext.getResources().getBoolean( + com.android.internal.R.bool.config_show_network_generation); + if (useNetworkNum) { + if (generation == WifiManager.WIFI_GENERATION_6) { + mIconController.setIcon(mSlotHotspot, R.drawable.stat_sys_wifi_6_hotspot, + mContext.getString(R.string.accessibility_status_bar_hotspot)); + } else if (generation == WifiManager.WIFI_GENERATION_5) { + mIconController.setIcon(mSlotHotspot, R.drawable.stat_sys_wifi_5_hotspot, + mContext.getString(R.string.accessibility_status_bar_hotspot)); + } else if (generation == WifiManager.WIFI_GENERATION_4) { + mIconController.setIcon(mSlotHotspot, R.drawable.stat_sys_wifi_4_hotspot, + mContext.getString(R.string.accessibility_status_bar_hotspot)); + } } else { mIconController.setIcon(mSlotHotspot, R.drawable.stat_sys_hotspot, mContext.getString(R.string.accessibility_status_bar_hotspot)); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/WifiSignalController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/WifiSignalController.java index 3a5051a0148..8bb1e76a222 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/WifiSignalController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/WifiSignalController.java @@ -142,12 +142,18 @@ public void notifyListeners(SignalCallback callback) { private void updateIconGroup() { - if (mCurrentState.wifiGenerationVersion == 4) { - mCurrentState.iconGroup = mWifi4IconGroup; - } else if (mCurrentState.wifiGenerationVersion == 5) { - mCurrentState.iconGroup = mCurrentState.isReady ? mWifi6IconGroup : mWifi5IconGroup; - } else if (mCurrentState.wifiGenerationVersion == 6) { - mCurrentState.iconGroup = mWifi6IconGroup; + boolean useNetworkNum = mContext.getResources().getBoolean( + com.android.internal.R.bool.config_show_network_generation); + if (useNetworkNum) { + if (mCurrentState.wifiGenerationVersion == 4) { + mCurrentState.iconGroup = mWifi4IconGroup; + } else if (mCurrentState.wifiGenerationVersion == 5) { + mCurrentState.iconGroup = mCurrentState.isReady ? mWifi6IconGroup : mWifi5IconGroup; + } else if (mCurrentState.wifiGenerationVersion == 6) { + mCurrentState.iconGroup = mWifi6IconGroup; + } else { + mCurrentState.iconGroup = mDefaultWifiIconGroup; + } } else { mCurrentState.iconGroup = mDefaultWifiIconGroup; } From afbb4929d79eb4bd4f2b37b1636c89fc6d3ae55f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hern=C3=A1n=20Casta=C3=B1=C3=B3n=20=C3=81lvarez?= Date: Fri, 6 Dec 2019 12:33:03 +0000 Subject: [PATCH 094/240] base: wifi: return 0 on getSoftApWifiGeneration() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This will avoid crashes for devices which don´t have updated blobs. Signed-off-by: Hernán Castañón Álvarez Change-Id: I5c11226790a24c4d1b494bfb6057d0449f581f28 --- wifi/java/com/android/server/wifi/BaseWifiService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wifi/java/com/android/server/wifi/BaseWifiService.java b/wifi/java/com/android/server/wifi/BaseWifiService.java index dfed7e02b4a..001ba34f002 100644 --- a/wifi/java/com/android/server/wifi/BaseWifiService.java +++ b/wifi/java/com/android/server/wifi/BaseWifiService.java @@ -556,7 +556,7 @@ public String dppConfiguratorGetKey(int id) { @Override public int getSoftApWifiGeneration() { - throw new UnsupportedOperationException(); + return 0; } /* QTI Vendor Dual STA support APIs */ From 0622f455cba5ae3c6d7cc89070cbee00ee9ffde5 Mon Sep 17 00:00:00 2001 From: Ethan Chen Date: Wed, 6 Dec 2017 09:58:03 -0800 Subject: [PATCH 095/240] PackageManager: Add configuration to specify vendor platform signatures Devices with split system/vendor images may want to use the OEM's vendor image. In that case, the OEM's platform signature is not actually the same as the platform signature used to sign the Lineage system image. Allow devices to specify an OEM platform signature which will also be recognized as the system's platform signature. Change-Id: Ida9bb25a32234af9d9507a214eae6a4672320d2b --- core/res/res/values/reloaded_config.xml | 5 +++ core/res/res/values/reloaded_symbols.xml | 2 + .../server/pm/PackageManagerService.java | 39 +++++++++++++++++-- 3 files changed, 42 insertions(+), 4 deletions(-) diff --git a/core/res/res/values/reloaded_config.xml b/core/res/res/values/reloaded_config.xml index 225ef6b58b9..ad09384543d 100644 --- a/core/res/res/values/reloaded_config.xml +++ b/core/res/res/values/reloaded_config.xml @@ -35,4 +35,9 @@ false + + + + diff --git a/core/res/res/values/reloaded_symbols.xml b/core/res/res/values/reloaded_symbols.xml index 08904de935f..9ab7764025b 100644 --- a/core/res/res/values/reloaded_symbols.xml +++ b/core/res/res/values/reloaded_symbols.xml @@ -27,4 +27,6 @@ + + diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index edd7574404f..1bbccbc94d4 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -1418,6 +1418,8 @@ static class PostInstallData { private final PackageUsage mPackageUsage = new PackageUsage(); private final CompilerStats mCompilerStats = new CompilerStats(); + private final Signature[] mVendorPlatformSignatures; + class PackageHandler extends Handler { PackageHandler(Looper looper) { @@ -2404,6 +2406,14 @@ private static void requestCopyPreoptedFiles() { } } + private static Signature[] createSignatures(String[] hexBytes) { + Signature[] sigs = new Signature[hexBytes.length]; + for (int i = 0; i < sigs.length; i++) { + sigs[i] = new Signature(hexBytes[i]); + } + return sigs; + } + public PackageManagerService(Context context, Installer installer, boolean factoryTest, boolean onlyCore) { LockGuard.installLock(mPackages, LockGuard.INDEX_PACKAGES); @@ -2417,6 +2427,9 @@ public PackageManagerService(Context context, Installer installer, mContext = context; + mVendorPlatformSignatures = createSignatures(context.getResources().getStringArray( + R.array.config_vendorPlatformSignatures)); + mFactoryTest = factoryTest; mOnlyCore = onlyCore; mMetrics = new DisplayMetrics(); @@ -9202,6 +9215,19 @@ private void collectCertificatesLI(PackageSetting ps, PackageParser.Package pkg, try { Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "collectCertificates"); PackageParser.collectCertificates(pkg, skipVerify); + if (compareSignatures(pkg.mSigningDetails.signatures, + mVendorPlatformSignatures) == PackageManager.SIGNATURE_MATCH) { + // Overwrite package signature with our platform signature + // if the signature is the vendor's platform signature + if (mPlatformPackage != null) { + pkg.mSigningDetails = mPlatformPackage.mSigningDetails; + pkg.applicationInfo.seInfo = SELinuxMMAC.getSeInfo( + pkg, + pkg.isPrivileged(), + pkg.applicationInfo.targetSandboxVersion, + pkg.applicationInfo.targetSdkVersion); + } + } } catch (PackageParserException e) { throw PackageManagerException.from(e); } finally { @@ -9464,7 +9490,8 @@ private PackageParser.Package addForInitLI(PackageParser.Package pkg, disabledPkgSetting /* pkgSetting */, null /* disabledPkgSetting */, null /* originalPkgSetting */, null, parseFlags, scanFlags, (pkg == mPlatformPackage), user); - applyPolicy(pkg, parseFlags, scanFlags, mPlatformPackage); + applyPolicy(pkg, parseFlags, scanFlags, mPlatformPackage, + mVendorPlatformSignatures); final ScanResult scanResult = scanPackageOnlyLI(request, mFactoryTest, -1L); if (scanResult.existingSettingCopied && scanResult.request.pkgSetting != null) { scanResult.request.pkgSetting.updateFrom(scanResult.pkgSetting); @@ -11039,7 +11066,7 @@ private ScanResult scanPackageNewLI(@NonNull PackageParser.Package pkg, scanFlags = adjustScanFlags(scanFlags, pkgSetting, disabledPkgSetting, user, pkg); synchronized (mPackages) { - applyPolicy(pkg, parseFlags, scanFlags, mPlatformPackage); + applyPolicy(pkg, parseFlags, scanFlags, mPlatformPackage, mVendorPlatformSignatures); assertPackageIsValid(pkg, parseFlags, scanFlags); SharedUserSetting sharedUserSetting = null; @@ -11663,7 +11690,8 @@ private static void assertCodePolicy(PackageParser.Package pkg) * ideally be static, but, it requires locks to read system state. */ private static void applyPolicy(PackageParser.Package pkg, final @ParseFlags int parseFlags, - final @ScanFlags int scanFlags, PackageParser.Package platformPkg) { + final @ScanFlags int scanFlags, PackageParser.Package platformPkg, + Signature[] vendorPlatformSignatures) { if ((scanFlags & SCAN_AS_SYSTEM) != 0) { pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM; if (pkg.applicationInfo.isDirectBootAware()) { @@ -11759,8 +11787,11 @@ private static void applyPolicy(PackageParser.Package pkg, final @ParseFlags int // Check if the package is signed with the same key as the platform package. if (PLATFORM_PACKAGE_NAME.equals(pkg.packageName) || - (platformPkg != null && compareSignatures( + (platformPkg != null && (compareSignatures( platformPkg.mSigningDetails.signatures, + pkg.mSigningDetails.signatures) == PackageManager.SIGNATURE_MATCH) || + compareSignatures( + vendorPlatformSignatures, pkg.mSigningDetails.signatures) == PackageManager.SIGNATURE_MATCH)) { pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_SIGNED_WITH_PLATFORM_KEY; From e08d1d12d43f106d29fd6728fefccef3efbd6439 Mon Sep 17 00:00:00 2001 From: ezio84 Date: Wed, 25 Dec 2019 01:30:55 +0100 Subject: [PATCH 096/240] PackageInstaller: Show current and new version on APK installation Change-Id: I61dd683cb5e9c33791ce10692477c90842bcea9c --- .../res/layout/install_content_view.xml | 84 ++++++++++++++----- .../res/values/reloaded_strings.xml | 28 +++++++ .../PackageInstallerActivity.java | 25 ++++-- 3 files changed, 110 insertions(+), 27 deletions(-) create mode 100644 packages/PackageInstaller/res/values/reloaded_strings.xml diff --git a/packages/PackageInstaller/res/layout/install_content_view.xml b/packages/PackageInstaller/res/layout/install_content_view.xml index 5e94a29a639..bcd5f169f87 100644 --- a/packages/PackageInstaller/res/layout/install_content_view.xml +++ b/packages/PackageInstaller/res/layout/install_content_view.xml @@ -69,29 +69,71 @@ - - - + android:orientation="vertical" + android:visibility="invisible"> - + + + + + + + + + + + + + + + + + + + + Installed version: + %1$s + + + + To be installed: + %1$s + + diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/PackageInstallerActivity.java b/packages/PackageInstaller/src/com/android/packageinstaller/PackageInstallerActivity.java index 55ff591e3a1..f0be2c19ebc 100644 --- a/packages/PackageInstaller/src/com/android/packageinstaller/PackageInstallerActivity.java +++ b/packages/PackageInstaller/src/com/android/packageinstaller/PackageInstallerActivity.java @@ -48,6 +48,7 @@ import android.util.Log; import android.view.View; import android.widget.Button; +import android.widget.TextView; import com.android.internal.app.AlertActivity; @@ -119,19 +120,29 @@ public class PackageInstallerActivity extends AlertActivity { // Would the mOk button be enabled if this activity would be resumed private boolean mEnableOk = false; - private void startInstallConfirm() { - View viewToEnable; + private void startInstallConfirm(PackageInfo oldInfo) { + requireViewById(R.id.updating_app_view).setVisibility(View.VISIBLE); // the main layout + View viewToEnable; // which install_confirm view to show + View oldVersionView; + View newVersionView; if (mAppInfo != null) { viewToEnable = (mAppInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0 ? requireViewById(R.id.install_confirm_question_update_system) : requireViewById(R.id.install_confirm_question_update); + oldVersionView = requireViewById(R.id.installed_app_version); + ((TextView)oldVersionView).setText( + getString(R.string.old_version_number, oldInfo.versionName)); + oldVersionView.setVisibility(View.VISIBLE); } else { // This is a new application with no permissions. viewToEnable = requireViewById(R.id.install_confirm_question); } - + newVersionView = requireViewById(R.id.updating_app_version); + ((TextView)newVersionView).setText( + getString(R.string.new_version_number, mPkgInfo.versionName)); viewToEnable.setVisibility(View.VISIBLE); + newVersionView.setVisibility(View.VISIBLE); mEnableOk = true; mOk.setEnabled(true); @@ -256,20 +267,22 @@ private void initiateInstall() { mPkgInfo.applicationInfo.packageName = pkgName; } // Check if package is already installed. display confirmation dialog if replacing pkg + PackageInfo oldPackageInfo = null; try { // This is a little convoluted because we want to get all uninstalled // apps, but this may include apps with just data, and if it is just // data we still want to count it as "installed". - mAppInfo = mPm.getApplicationInfo(pkgName, + oldPackageInfo = mPm.getPackageInfo(pkgName, PackageManager.MATCH_UNINSTALLED_PACKAGES); - if ((mAppInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { + mAppInfo = oldPackageInfo.applicationInfo; + if (mAppInfo != null && (mAppInfo.flags & ApplicationInfo.FLAG_INSTALLED) == 0) { mAppInfo = null; } } catch (NameNotFoundException e) { mAppInfo = null; } - startInstallConfirm(); + startInstallConfirm(oldPackageInfo); } void setPmResult(int pmResult) { From 9f7b351686b7f1d442ecc3bb3f9308c6fbf4fe9a Mon Sep 17 00:00:00 2001 From: Jake Weinstein Date: Mon, 18 Nov 2019 22:26:23 +0100 Subject: [PATCH 097/240] Revert "Inform Servicetracker HAL about Service Lifecycle events" This thing constantly spams logs and is not needed. This reverts commit f99355f195f58b7b0b2a2977f38dc527c46d857a. Change-Id: I81457df20134fda2840f1883f8cb82d973a7ca1c --- services/core/Android.bp | 1 - .../com/android/server/am/ActiveServices.java | 114 ------------------ 2 files changed, 115 deletions(-) diff --git a/services/core/Android.bp b/services/core/Android.bp index 04dca9561db..9855e4ea339 100644 --- a/services/core/Android.bp +++ b/services/core/Android.bp @@ -54,7 +54,6 @@ java_library_static { "dnsresolver_aidl_interface-V2-java", "netd_aidl_interface-V2-java", "netd_event_listener_interface-java", - "vendor.qti.hardware.servicetracker-V1.0-java", ], } diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java index e16bb133bf2..3a158442254 100644 --- a/services/core/java/com/android/server/am/ActiveServices.java +++ b/services/core/java/com/android/server/am/ActiveServices.java @@ -111,10 +111,6 @@ import java.util.Set; import java.util.function.Predicate; -import vendor.qti.hardware.servicetracker.V1_0.IServicetracker; -import vendor.qti.hardware.servicetracker.V1_0.ServiceData; -import vendor.qti.hardware.servicetracker.V1_0.ClientData; - public final class ActiveServices { private static final String TAG = TAG_WITH_CLASS_NAME ? "ActiveServices" : TAG_AM; private static final String TAG_MU = TAG + POSTFIX_MU; @@ -187,8 +183,6 @@ public final class ActiveServices { /** Amount of time to allow a last ANR message to exist before freeing the memory. */ static final int LAST_ANR_LIFETIME_DURATION_MSECS = 2 * 60 * 60 * 1000; // Two hours - private IServicetracker mServicetracker; - String mLastAnrDump; final Runnable mLastAnrDumpClearer = new Runnable() { @@ -385,24 +379,6 @@ void systemServicesReady() { ast.addListener(new ForcedStandbyListener()); } - private boolean getServicetrackerInstance() { - if (mServicetracker == null ) { - try { - mServicetracker = IServicetracker.getService(false); - } catch (java.util.NoSuchElementException e) { - // Service doesn't exist or cannot be opened logged below - } catch (RemoteException e) { - if (DEBUG_SERVICE) Slog.e(TAG, "Failed to get servicetracker interface", e); - return false; - } - if (mServicetracker == null) { - if (DEBUG_SERVICE) Slog.w(TAG, "servicetracker HIDL not available"); - return false; - } - } - return true; - } - ServiceRecord getServiceByNameLocked(ComponentName name, int callingUser) { // TODO: Deal with global services if (DEBUG_MU) @@ -1810,30 +1786,6 @@ public void run() { } clist.add(c); - ServiceData sData = new ServiceData(); - sData.packageName = s.packageName; - sData.processName = s.shortInstanceName; - sData.lastActivity = s.lastActivity; - if (s.app != null) { - sData.pid = s.app.pid; - sData.serviceB = s.app.serviceb; - } else { - sData.pid = -1; - sData.serviceB = false; - } - - ClientData cData = new ClientData(); - cData.processName = callerApp.processName; - cData.pid = callerApp.pid; - try { - if (getServicetrackerInstance()) { - mServicetracker.bindService(sData, cData); - } - } catch (RemoteException e) { - Slog.e(TAG, "Failed to send bind details to servicetracker HAL", e); - mServicetracker = null; - } - if ((flags&Context.BIND_AUTO_CREATE) != 0) { s.lastActivity = SystemClock.uptimeMillis(); if (bringUpServiceLocked(s, service.getFlags(), callerFg, false, @@ -1988,29 +1940,6 @@ boolean unbindServiceLocked(IServiceConnection connection) { try { while (clist.size() > 0) { ConnectionRecord r = clist.get(0); - ServiceData sData = new ServiceData(); - sData.packageName = r.binding.service.packageName; - sData.processName = r.binding.service.shortInstanceName; - sData.lastActivity = r.binding.service.lastActivity; - if(r.binding.service.app != null) { - sData.pid = r.binding.service.app.pid; - sData.serviceB = r.binding.service.app.serviceb; - } else { - sData.pid = -1; - sData.serviceB = false; - } - - ClientData cData = new ClientData(); - cData.processName = r.binding.client.processName; - cData.pid = r.binding.client.pid; - try { - if (getServicetrackerInstance()) { - mServicetracker.unbindService(sData, cData); - } - } catch (RemoteException e) { - Slog.e(TAG, "Failed to send unbind details to servicetracker HAL", e); - mServicetracker = null; - } removeConnectionLocked(r, null, null); if (clist.size() > 0 && clist.get(0) == r) { // In case it didn't get removed above, do it now. @@ -2832,22 +2761,6 @@ private final void realStartServiceLocked(ServiceRecord r, app.getReportedProcState()); r.postNotification(); created = true; - - ServiceData sData = new ServiceData(); - sData.packageName = r.packageName; - sData.processName = r.shortInstanceName; - sData.pid = r.app.pid; - sData.lastActivity = r.lastActivity; - sData.serviceB = r.app.serviceb; - - try { - if (getServicetrackerInstance()) { - mServicetracker.startService(sData); - } - } catch (RemoteException e) { - Slog.e(TAG, "Failed to send start details to servicetracker HAL", e); - mServicetracker = null; - } } catch (DeadObjectException e) { Slog.w(TAG, "Application dead when creating service " + r); mAm.appDiedLocked(app); @@ -3044,25 +2957,7 @@ private final void bringDownServiceIfNeededLocked(ServiceRecord r, boolean knowC private final void bringDownServiceLocked(ServiceRecord r) { //Slog.i(TAG, "Bring down service:"); //r.dump(" "); - ServiceData sData = new ServiceData(); - sData.packageName = r.packageName; - sData.processName = r.shortInstanceName; - sData.lastActivity = r.lastActivity; - if (r.app != null) { - sData.pid = r.app.pid; - } else { - sData.pid = -1; - sData.serviceB = false; - } - try { - if (getServicetrackerInstance()) { - mServicetracker.destroyService(sData); - } - } catch (RemoteException e) { - Slog.e(TAG, "Failed to send destroy details to servicetracker HAL", e); - mServicetracker = null; - } // Report to all of the connections that the service is no longer // available. ArrayMap> connections = r.getConnections(); @@ -3725,15 +3620,6 @@ final void killServicesLocked(ProcessRecord app, boolean allowRestart) { } } - try { - if (getServicetrackerInstance()) { - mServicetracker.killProcess(app.pid); - } - } catch (RemoteException e) { - Slog.e(TAG, "Failed to send kill process details to servicetracker HAL", e); - mServicetracker = null; - } - // Clean up any connections this application has to other services. for (int i = app.connections.size() - 1; i >= 0; i--) { ConnectionRecord r = app.connections.valueAt(i); From dfac16dda3c396d06d42800b4d843dab529c302f Mon Sep 17 00:00:00 2001 From: Park Ju Hyung Date: Fri, 3 Jan 2020 00:37:57 +0900 Subject: [PATCH 098/240] aapt2: do not use compression Modern storage including both UFS and eMMC is (much) faster than zlib. Do not use compression on system apk/jar files for increased read performance and better use of Linux's page-cache. Note that the configuration on PinnerService might needs to be re-evaulated for potential increase in memory usage. In our configuration, we only have SystemUI as an apk, which only increased about 1 MiB. Change-Id: I581da3fa5dbe70ea76155cbaf9615a1b07ef338b Signed-off-by: Park Ju Hyung --- tools/aapt2/cmd/Convert.cpp | 2 +- tools/aapt2/cmd/Link.cpp | 36 +++++------------------------------- tools/aapt2/cmd/Optimize.cpp | 2 +- 3 files changed, 7 insertions(+), 33 deletions(-) diff --git a/tools/aapt2/cmd/Convert.cpp b/tools/aapt2/cmd/Convert.cpp index 0cf86ccdd59..32bacf653c2 100644 --- a/tools/aapt2/cmd/Convert.cpp +++ b/tools/aapt2/cmd/Convert.cpp @@ -160,7 +160,7 @@ class ProtoApkSerializer : public IApkSerializer { pb::ResourceTable pb_table; SerializeTableToPb(*table, &pb_table, context_->GetDiagnostics()); return io::CopyProtoToArchive(context_, &pb_table, kProtoResourceTablePath, - ArchiveEntry::kCompress, writer); + 0u, writer); } bool SerializeFile(FileReference* file, IArchiveWriter* writer) override { diff --git a/tools/aapt2/cmd/Link.cpp b/tools/aapt2/cmd/Link.cpp index f354bb61022..65582802e8c 100644 --- a/tools/aapt2/cmd/Link.cpp +++ b/tools/aapt2/cmd/Link.cpp @@ -234,7 +234,7 @@ static bool FlattenXml(IAaptContext* context, const xml::XmlResource& xml_res, io::BigBufferInputStream input_stream(&buffer); return io::CopyInputStreamToArchive(context, &input_stream, path.to_string(), - ArchiveEntry::kCompress, writer); + 0u, writer); } break; case OutputFormat::kProto: { @@ -243,8 +243,7 @@ static bool FlattenXml(IAaptContext* context, const xml::XmlResource& xml_res, SerializeXmlOptions options; options.remove_empty_text_nodes = (path == kAndroidManifestPath); SerializeXmlResourceToPb(xml_res, &pb_node); - return io::CopyProtoToArchive(context, &pb_node, path.to_string(), ArchiveEntry::kCompress, - writer); + return io::CopyProtoToArchive(context, &pb_node, path.to_string(), 0u, writer); } break; } return false; @@ -384,21 +383,7 @@ ResourceFileFlattener::ResourceFileFlattener(const ResourceFileFlattenerOptions& // TODO(rtmitchell): turn this function into a variable that points to a method that retrieves the // compression flag uint32_t ResourceFileFlattener::GetCompressionFlags(const StringPiece& str) { - if (options_.do_not_compress_anything) { - return 0; - } - - if (options_.regex_to_not_compress - && std::regex_search(str.to_string(), options_.regex_to_not_compress.value())) { - return 0; - } - - for (const std::string& extension : options_.extensions_to_not_compress) { - if (util::EndsWith(str, extension)) { - return 0; - } - } - return ArchiveEntry::kCompress; + return 0; } static bool IsTransitionElement(const std::string& name) { @@ -1067,7 +1052,7 @@ class Linker { pb::ResourceTable pb_table; SerializeTableToPb(*table, &pb_table, context_->GetDiagnostics()); return io::CopyProtoToArchive(context_, &pb_table, kProtoResourceTablePath, - ArchiveEntry::kCompress, writer); + 0u, writer); } break; } return false; @@ -1547,18 +1532,7 @@ class Linker { } for (auto& entry : merged_assets) { - uint32_t compression_flags = ArchiveEntry::kCompress; - std::string extension = file::GetExtension(entry.first).to_string(); - - if (options_.do_not_compress_anything - || options_.extensions_to_not_compress.count(extension) > 0 - || (options_.regex_to_not_compress - && std::regex_search(extension, options_.regex_to_not_compress.value()))) { - compression_flags = 0u; - } - - if (!io::CopyFileToArchive(context_, entry.second.get(), entry.first, compression_flags, - writer)) { + if (!io::CopyFileToArchive(context_, entry.second.get(), entry.first, 0u, writer)) { return false; } } diff --git a/tools/aapt2/cmd/Optimize.cpp b/tools/aapt2/cmd/Optimize.cpp index 2e6af18c194..df26f7d0fe4 100644 --- a/tools/aapt2/cmd/Optimize.cpp +++ b/tools/aapt2/cmd/Optimize.cpp @@ -230,7 +230,7 @@ class Optimizer { io::BigBufferInputStream manifest_buffer_in(&manifest_buffer); if (!io::CopyInputStreamToArchive(context_, &manifest_buffer_in, "AndroidManifest.xml", - ArchiveEntry::kCompress, writer)) { + 0u, writer)) { return false; } From 4257edff525e4d7cd9bde36362ec966f618c960c Mon Sep 17 00:00:00 2001 From: Park Ju Hyung Date: Tue, 7 Jan 2020 00:41:50 +0900 Subject: [PATCH 099/240] aapt2: silence positional arguments warnings These warnings take up significant portion of the entire stderr output during builds, and aren't important at all. Silence it so that other more meaningful stderr outputs could be noticed. Change-Id: If05955a6c392f3d5bfe0a4e2b424da2a08fc2f75 Signed-off-by: Park Ju Hyung --- tools/aapt2/ResourceParser.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/tools/aapt2/ResourceParser.cpp b/tools/aapt2/ResourceParser.cpp index 45cea819084..ead7ef1e531 100644 --- a/tools/aapt2/ResourceParser.cpp +++ b/tools/aapt2/ResourceParser.cpp @@ -821,15 +821,14 @@ bool ResourceParser::ParseString(xml::XmlPullParser* parser, if (formatted && translatable) { if (!util::VerifyJavaStringFormat(*string_value->value)) { - DiagMessage msg(out_resource->source); - msg << "multiple substitutions specified in non-positional format; " - "did you mean to add the formatted=\"false\" attribute?"; if (options_.error_on_positional_arguments) { + DiagMessage msg(out_resource->source); + msg << "multiple substitutions specified in non-positional format; " + "did you mean to add the formatted=\"false\" attribute?"; + diag_->Error(msg); return false; } - - diag_->Warn(msg); } } From 890631765f7d18e154cd35a2f928cf1a8225d5bf Mon Sep 17 00:00:00 2001 From: dianlujitao Date: Thu, 8 Feb 2018 21:48:44 +0800 Subject: [PATCH 100/240] NtpTrustedTime: Refresh NTP server from resources before requesting time * NtpTrustedTime initialized before carrier/country specific resources got loaded, so generally the default NTP server is always in use. * Always fetch NTP server from resources unless secure NTP server is set to ensure that carrier/country specific customization works. Change-Id: I9b09680ea5640c35660d1cd0b910af22af930144 --- core/java/android/util/NtpTrustedTime.java | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/core/java/android/util/NtpTrustedTime.java b/core/java/android/util/NtpTrustedTime.java index bb3ddcfbe3f..7144fb36f2b 100644 --- a/core/java/android/util/NtpTrustedTime.java +++ b/core/java/android/util/NtpTrustedTime.java @@ -1,5 +1,6 @@ /* * Copyright (C) 2011 The Android Open Source Project + * Copyright (C) 2018 The LineageOS Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -70,17 +71,14 @@ public static synchronized NtpTrustedTime getInstance(Context context) { final Resources res = context.getResources(); final ContentResolver resolver = context.getContentResolver(); - final String defaultServer = res.getString( - com.android.internal.R.string.config_ntpServer); final long defaultTimeout = res.getInteger( com.android.internal.R.integer.config_ntpTimeout); - final String secureServer = Settings.Global.getString( + final String server = Settings.Global.getString( resolver, Settings.Global.NTP_SERVER); final long timeout = Settings.Global.getLong( resolver, Settings.Global.NTP_TIMEOUT, defaultTimeout); - final String server = secureServer != null ? secureServer : defaultServer; sSingleton = new NtpTrustedTime(server, timeout); sContext = context; @@ -125,10 +123,8 @@ public boolean forceSync() { } public boolean forceRefresh(Network network) { - if (TextUtils.isEmpty(mServer)) { - // missing server, so no trusted time available - return false; - } + final String realServer = TextUtils.isEmpty(mServer) ? sContext.getResources().getString( + com.android.internal.R.string.config_ntpServer) : mServer; // We can't do this at initialization time: ConnectivityService might not be running yet. synchronized (this) { @@ -147,7 +143,7 @@ public boolean forceRefresh(Network network) { if (LOGD) Log.d(TAG, "forceRefresh() from cache miss"); final SntpClient client = new SntpClient(); - String targetServer = mServer; + String targetServer = realServer; if (getBackupmode()) { setBackupmode(false); targetServer = mBackupServer; From f19369f72ded22fa2d5bc41a97108417a61de4bd Mon Sep 17 00:00:00 2001 From: Park Ju Hyung Date: Sat, 4 Jan 2020 21:25:16 +0900 Subject: [PATCH 101/240] FingerprintManager: return "Try again" by default If HAL returns an unknown string by the framework, the SystemUI crashes because it received a null string. Simply display "Try again" by default. Change-Id: Id10b37c76acea70a22500c1de61f4bcf7a5e494a Signed-off-by: Park Ju Hyung --- .../android/hardware/fingerprint/FingerprintManager.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/core/java/android/hardware/fingerprint/FingerprintManager.java b/core/java/android/hardware/fingerprint/FingerprintManager.java index d0622c88b4c..d96adaa9a84 100644 --- a/core/java/android/hardware/fingerprint/FingerprintManager.java +++ b/core/java/android/hardware/fingerprint/FingerprintManager.java @@ -927,13 +927,15 @@ private void cancelAuthentication(android.hardware.biometrics.CryptoObject crypt * @hide */ public static String getErrorString(Context context, int errMsg, int vendorCode) { + final String retry = context.getString( + com.android.internal.R.string.fingerprint_error_unable_to_process); + switch (errMsg) { case FINGERPRINT_ERROR_HW_UNAVAILABLE: return context.getString( com.android.internal.R.string.fingerprint_error_hw_not_available); case FINGERPRINT_ERROR_UNABLE_TO_PROCESS: - return context.getString( - com.android.internal.R.string.fingerprint_error_unable_to_process); + return retry; case FINGERPRINT_ERROR_TIMEOUT: return context.getString(com.android.internal.R.string.fingerprint_error_timeout); case FINGERPRINT_ERROR_NO_SPACE: @@ -964,7 +966,7 @@ public static String getErrorString(Context context, int errMsg, int vendorCode) } } Slog.w(TAG, "Invalid error message: " + errMsg + ", " + vendorCode); - return null; + return retry; } /** From c80698898049d9752745925d6e0718559cae4b8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=8Dcaro=20Hoff?= Date: Sun, 4 Jun 2017 12:17:51 -0300 Subject: [PATCH 102/240] fingerprint: handle PerformanceStats NULL pointers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit bcc100a has added support for this feature, but the NULL checks weren't complete, only "handleAcquired" was checking if PerformanceStats was supported before calling the API. Extend the NULL checks to "handleAuthenticated" and "handleFailedAttempt" calls as well. Change-Id: I3cc9b35ea6b81dc0c503b9feab940873b344323e Signed-off-by: Ícaro Hoff --- .../biometrics/BiometricServiceBase.java | 20 +++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/services/core/java/com/android/server/biometrics/BiometricServiceBase.java b/services/core/java/com/android/server/biometrics/BiometricServiceBase.java index f3f9754bd32..042fb832740 100644 --- a/services/core/java/com/android/server/biometrics/BiometricServiceBase.java +++ b/services/core/java/com/android/server/biometrics/BiometricServiceBase.java @@ -263,10 +263,12 @@ public void notifyUserActivity() { @Override public int handleFailedAttempt() { final int lockoutMode = getLockoutMode(); - if (lockoutMode == AuthenticationClient.LOCKOUT_PERMANENT) { - mPerformanceStats.permanentLockout++; - } else if (lockoutMode == AuthenticationClient.LOCKOUT_TIMED) { - mPerformanceStats.lockout++; + if (mPerformanceStats != null) { + if (lockoutMode == AuthenticationClient.LOCKOUT_PERMANENT) { + mPerformanceStats.permanentLockout++; + } else if (lockoutMode == AuthenticationClient.LOCKOUT_TIMED) { + mPerformanceStats.lockout++; + } } // Failing multiple times will continue to push out the lockout time @@ -708,10 +710,12 @@ protected void handleAuthenticated(BiometricAuthenticator.Identifier identifier, if (client != null && client.onAuthenticated(identifier, authenticated, token)) { removeClient(client); } - if (authenticated) { - mPerformanceStats.accept++; - } else { - mPerformanceStats.reject++; + if (mPerformanceStats != null) { + if (authenticated) { + mPerformanceStats.accept++; + } else { + mPerformanceStats.reject++; + } } } From eac832f9622b6d8f6949dba9d3c8781b9676f116 Mon Sep 17 00:00:00 2001 From: qqzhou Date: Tue, 17 Dec 2013 14:10:08 +0800 Subject: [PATCH 103/240] Download: Add support to manually pause/resume download Add the pause and resume APIs here so that applications can pause and resume downloads manually through DownloadManager. This patch consists of 2 changes: 1. Add pause and resume download APIs 2. Add another paused reason for this download status Change-Id: I606b48ca20f43bcc6c119683818c2ab6ff03bfe5 --- core/java/android/app/DownloadManager.java | 40 ++++++++++++++++++++++ core/java/android/provider/Downloads.java | 5 +++ 2 files changed, 45 insertions(+) diff --git a/core/java/android/app/DownloadManager.java b/core/java/android/app/DownloadManager.java index 77a777024a2..a37fc80d6ee 100644 --- a/core/java/android/app/DownloadManager.java +++ b/core/java/android/app/DownloadManager.java @@ -294,6 +294,13 @@ public class DownloadManager { */ public final static int PAUSED_UNKNOWN = 4; + /** + * Value of {@link #COLUMN_REASON} when the download is paused manually. + * + * @hide + */ + public final static int PAUSED_MANUAL = 5; + /** * Broadcast intent action sent by the download manager when a download completes. */ @@ -987,6 +994,7 @@ Cursor runQuery(ContentResolver resolver, String[] projection, Uri baseUri) { parts.add(statusClause("=", Downloads.Impl.STATUS_WAITING_TO_RETRY)); parts.add(statusClause("=", Downloads.Impl.STATUS_WAITING_FOR_NETWORK)); parts.add(statusClause("=", Downloads.Impl.STATUS_QUEUED_FOR_WIFI)); + parts.add(statusClause("=", Downloads.Impl.STATUS_PAUSED_MANUAL)); } if ((mStatusFlags & STATUS_SUCCESSFUL) != 0) { parts.add(statusClause("=", Downloads.Impl.STATUS_SUCCESS)); @@ -1245,6 +1253,34 @@ public void forceDownload(long... ids) { mResolver.update(mBaseUri, values, getWhereClauseForIds(ids), getWhereArgsForIds(ids)); } + /** + * Pause the given running download manually. + * + * @param id the ID of the download to be paused + * @return the number of downloads actually updated + * @hide + */ + public int pauseDownload(long id) { + ContentValues values = new ContentValues(); + values.put(Downloads.Impl.COLUMN_STATUS, Downloads.Impl.STATUS_PAUSED_MANUAL); + + return mResolver.update(ContentUris.withAppendedId(mBaseUri, id), values, null, null); + } + + /** + * Resume the given paused download manually. + * + * @param id the ID of the download to be resumed + * @return the number of downloads actually updated + * @hide + */ + public int resumeDownload(long id) { + ContentValues values = new ContentValues(); + values.put(Downloads.Impl.COLUMN_STATUS, Downloads.Impl.STATUS_RUNNING); + + return mResolver.update(ContentUris.withAppendedId(mBaseUri, id), values, null, null); + } + /** * Returns maximum size, in bytes, of downloads that may go over a mobile connection; or null if * there's no limit @@ -1682,6 +1718,9 @@ private long getPausedReason(int status) { case Downloads.Impl.STATUS_QUEUED_FOR_WIFI: return PAUSED_QUEUED_FOR_WIFI; + case Downloads.Impl.STATUS_PAUSED_MANUAL: + return PAUSED_MANUAL; + default: return PAUSED_UNKNOWN; } @@ -1737,6 +1776,7 @@ private int translateStatus(int status) { case Downloads.Impl.STATUS_WAITING_TO_RETRY: case Downloads.Impl.STATUS_WAITING_FOR_NETWORK: case Downloads.Impl.STATUS_QUEUED_FOR_WIFI: + case Downloads.Impl.STATUS_PAUSED_MANUAL: return STATUS_PAUSED; case Downloads.Impl.STATUS_SUCCESS: diff --git a/core/java/android/provider/Downloads.java b/core/java/android/provider/Downloads.java index 9a384c6d9d7..e401ac3d403 100644 --- a/core/java/android/provider/Downloads.java +++ b/core/java/android/provider/Downloads.java @@ -645,6 +645,11 @@ public static boolean isStatusCompleted(int status) { */ public static final int STATUS_QUEUED_FOR_WIFI = 196; + /** + * This download is paused manually. + */ + public static final int STATUS_PAUSED_MANUAL = 197; + /** * This download couldn't be completed due to insufficient storage * space. Typically, this is because the SD card is full. From e3e428c558046f0f0ee86dcc060781fac851437e Mon Sep 17 00:00:00 2001 From: Joe Maples Date: Mon, 6 Aug 2018 18:36:55 -0400 Subject: [PATCH 104/240] SystemUI: re-enable Tuner Signed-off-by: Joe Maples --- .../src/com/android/systemui/tuner/TunerServiceImpl.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/tuner/TunerServiceImpl.java b/packages/SystemUI/src/com/android/systemui/tuner/TunerServiceImpl.java index 6185063e796..7b0ff2589e7 100644 --- a/packages/SystemUI/src/com/android/systemui/tuner/TunerServiceImpl.java +++ b/packages/SystemUI/src/com/android/systemui/tuner/TunerServiceImpl.java @@ -127,9 +127,7 @@ private void upgradeTuner(int oldVersion, int newVersion, Handler bgHandler) { TextUtils.join(",", iconBlacklist), mCurrentUser); } } - if (oldVersion < 2) { - setTunerEnabled(mContext, false); - } + // 2 Removed because we want tuner. // 3 Removed because of a revert. if (oldVersion < 4) { // Delay this so that we can wait for everything to be registered first. From 545318aa90dd4b886f0a6fc8388d2a3f465b327f Mon Sep 17 00:00:00 2001 From: Joe Maples Date: Mon, 6 Aug 2018 18:42:21 -0400 Subject: [PATCH 105/240] Tuner: Don't clear out prefs, it's not disabled Signed-off-by: Joe Maples --- .../systemui/tuner/TunerServiceImpl.java | 32 ++++++++----------- 1 file changed, 14 insertions(+), 18 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/tuner/TunerServiceImpl.java b/packages/SystemUI/src/com/android/systemui/tuner/TunerServiceImpl.java index 7b0ff2589e7..451377029c2 100644 --- a/packages/SystemUI/src/com/android/systemui/tuner/TunerServiceImpl.java +++ b/packages/SystemUI/src/com/android/systemui/tuner/TunerServiceImpl.java @@ -18,14 +18,21 @@ import static com.android.systemui.Dependency.BG_HANDLER_NAME; import android.app.ActivityManager; +import android.content.BroadcastReceiver; +import android.content.ComponentName; import android.content.ContentResolver; import android.content.Context; +import android.content.DialogInterface; +import android.content.DialogInterface.OnClickListener; import android.content.Intent; +import android.content.pm.PackageManager; +import android.content.pm.PackageManager.NameNotFoundException; import android.content.pm.UserInfo; import android.database.ContentObserver; import android.net.Uri; import android.os.Handler; import android.os.Looper; +import android.os.UserHandle; import android.os.UserManager; import android.provider.Settings; import android.provider.Settings.Secure; @@ -33,11 +40,15 @@ import android.util.ArrayMap; import android.util.ArraySet; -import com.android.internal.util.ArrayUtils; import com.android.systemui.DemoMode; import com.android.systemui.qs.QSTileHost; +import com.android.systemui.R; +import com.android.systemui.SysUiServiceProvider; +import com.android.systemui.SystemUI; +import com.android.systemui.SystemUIApplication; import com.android.systemui.settings.CurrentUserTracker; import com.android.systemui.statusbar.phone.StatusBarIconController; +import com.android.systemui.statusbar.phone.SystemUIDialog; import com.android.systemui.util.leak.LeakDetector; import java.util.HashMap; @@ -56,14 +67,7 @@ public class TunerServiceImpl extends TunerService { private static final String TUNER_VERSION = "sysui_tuner_version"; - private static final int CURRENT_TUNER_VERSION = 4; - - // Things that use the tunable infrastructure but are now real user settings and - // shouldn't be reset with tuner settings. - private static final String[] RESET_BLACKLIST = new String[] { - QSTileHost.TILES_SETTING, - Settings.Secure.DOZE_ALWAYS_ON - }; + private static final int CURRENT_TUNER_VERSION = 5; private final Observer mObserver = new Observer(); // Map of Uris we listen on to their settings keys. @@ -129,12 +133,7 @@ private void upgradeTuner(int oldVersion, int newVersion, Handler bgHandler) { } // 2 Removed because we want tuner. // 3 Removed because of a revert. - if (oldVersion < 4) { - // Delay this so that we can wait for everything to be registered first. - final int user = mCurrentUser; - bgHandler.postDelayed( - () -> clearAllFromUser(user), 5000); - } + // 4 Removed since we aren't filtering prefs. setValue(TUNER_VERSION, newVersion); } @@ -246,9 +245,6 @@ public void clearAllFromUser(int user) { mContext.sendBroadcast(intent); for (String key : mTunableLookup.keySet()) { - if (ArrayUtils.contains(RESET_BLACKLIST, key)) { - continue; - } Settings.Secure.putStringForUser(mContentResolver, key, null, user); } } From 8ed53fe22a5f2b9224fea0099bcb92674de118b0 Mon Sep 17 00:00:00 2001 From: Christian Oder Date: Mon, 29 Aug 2016 00:49:52 +0200 Subject: [PATCH 106/240] base: Show SystemUI Tuner by default Change-Id: I8c6a723de52766e6cd30a935090bcc8de81d467f Signed-off-by: Joe Maples --- packages/SystemUI/AndroidManifest.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml index ff767253f7b..934fe03dd65 100644 --- a/packages/SystemUI/AndroidManifest.xml +++ b/packages/SystemUI/AndroidManifest.xml @@ -315,7 +315,7 @@ android:exported="true" /> Date: Sun, 27 Aug 2017 17:24:37 -0400 Subject: [PATCH 107/240] qs: Hide tuner icon Change-Id: I0ef09f8875deb57fa74a945bf8d6d06788fd43a9 Signed-off-by: Joe Maples --- packages/SystemUI/src/com/android/systemui/qs/QSFooterImpl.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFooterImpl.java b/packages/SystemUI/src/com/android/systemui/qs/QSFooterImpl.java index 0c9d9277864..3ac1ec5b1a4 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSFooterImpl.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSFooterImpl.java @@ -308,8 +308,6 @@ private void updateClickabilities() { private void updateVisibilities() { mSettingsContainer.setVisibility(mQsDisabled ? View.GONE : View.VISIBLE); - mSettingsContainer.findViewById(R.id.tuner_icon).setVisibility( - TunerService.isTunerEnabled(mContext) ? View.VISIBLE : View.INVISIBLE); final boolean isDemo = UserManager.isDeviceInDemoMode(mContext); mMultiUserSwitch.setVisibility(showUserSwitcher() ? View.VISIBLE : View.INVISIBLE); mEditContainer.setVisibility(isDemo || !mExpanded ? View.INVISIBLE : View.VISIBLE); From 90b73d87ef86d2737272e32ba61ee0c7be8d3c6d Mon Sep 17 00:00:00 2001 From: Ritesh Saxena Date: Fri, 26 Apr 2019 13:42:30 +0000 Subject: [PATCH 108/240] SystemUI: Revamp our tuner Change-Id: Ibdace1f3d315c4f463938f2ff33045c79d3baef5 --- packages/SystemUI/AndroidManifest.xml | 14 +- .../drawable/ic_homepage_reloaded_tuner.xml | 14 ++ .../drawable/ic_settings_reloaded_tuner.xml | 9 ++ .../SystemUI/res/values/reloaded_colors.xml | 21 +++ .../SystemUI/res/values/reloaded_dimens.xml | 21 +++ .../SystemUI/res/values/reloaded_strings.xml | 26 ++++ .../SystemUI/res/xml/statusbar_settings.xml | 94 ++++++++++++ packages/SystemUI/res/xml/tuner_prefs.xml | 137 ++++-------------- .../systemui/tuner/StatusBarFragment.java | 28 ++++ .../android/systemui/tuner/TunerFragment.java | 79 +--------- .../android/systemui/tuner/TunerService.java | 3 - 11 files changed, 249 insertions(+), 197 deletions(-) create mode 100644 packages/SystemUI/res/drawable/ic_homepage_reloaded_tuner.xml create mode 100644 packages/SystemUI/res/drawable/ic_settings_reloaded_tuner.xml create mode 100644 packages/SystemUI/res/values/reloaded_colors.xml create mode 100644 packages/SystemUI/res/values/reloaded_dimens.xml create mode 100644 packages/SystemUI/res/values/reloaded_strings.xml create mode 100644 packages/SystemUI/res/xml/statusbar_settings.xml create mode 100644 packages/SystemUI/src/com/android/systemui/tuner/StatusBarFragment.java diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml index 934fe03dd65..2f5431d0e08 100644 --- a/packages/SystemUI/AndroidManifest.xml +++ b/packages/SystemUI/AndroidManifest.xml @@ -316,9 +316,9 @@ @@ -326,9 +326,15 @@ + android:value="com.android.settings.category.ia.homepage" /> + android:resource="@string/reloaded_tuner_summary"/> + + + + + + + + + + + + diff --git a/packages/SystemUI/res/drawable/ic_settings_reloaded_tuner.xml b/packages/SystemUI/res/drawable/ic_settings_reloaded_tuner.xml new file mode 100644 index 00000000000..07df7db118e --- /dev/null +++ b/packages/SystemUI/res/drawable/ic_settings_reloaded_tuner.xml @@ -0,0 +1,9 @@ + + + diff --git a/packages/SystemUI/res/values/reloaded_colors.xml b/packages/SystemUI/res/values/reloaded_colors.xml new file mode 100644 index 00000000000..2c81eb6e3bb --- /dev/null +++ b/packages/SystemUI/res/values/reloaded_colors.xml @@ -0,0 +1,21 @@ + + + + + #ff1a73e8 + + diff --git a/packages/SystemUI/res/values/reloaded_dimens.xml b/packages/SystemUI/res/values/reloaded_dimens.xml new file mode 100644 index 00000000000..e2302eaca92 --- /dev/null +++ b/packages/SystemUI/res/values/reloaded_dimens.xml @@ -0,0 +1,21 @@ + + + + + 24.0dip + + diff --git a/packages/SystemUI/res/values/reloaded_strings.xml b/packages/SystemUI/res/values/reloaded_strings.xml new file mode 100644 index 00000000000..0fd7e9e132c --- /dev/null +++ b/packages/SystemUI/res/values/reloaded_strings.xml @@ -0,0 +1,26 @@ + + + + + + Reloaded Tuner + Tune your experience + + + Statusbar icons + + diff --git a/packages/SystemUI/res/xml/statusbar_settings.xml b/packages/SystemUI/res/xml/statusbar_settings.xml new file mode 100644 index 00000000000..2006946caf5 --- /dev/null +++ b/packages/SystemUI/res/xml/statusbar_settings.xml @@ -0,0 +1,94 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/SystemUI/res/xml/tuner_prefs.xml b/packages/SystemUI/res/xml/tuner_prefs.xml index 6eec5dc9e1c..adae5bf25ba 100644 --- a/packages/SystemUI/res/xml/tuner_prefs.xml +++ b/packages/SystemUI/res/xml/tuner_prefs.xml @@ -16,138 +16,51 @@ + android:title="@string/reloaded_tuner_title"> - - - - - - - - - - - - - - - - - - - - - - - + android:title="@string/status_bar" + android:fragment="com.android.systemui.tuner.StatusBarFragment" /> - - - - - - - - - - - - - - - - - + - + - + + android:key="doze_always_on" + android:title="@string/tuner_doze_always_on" + sysui:defValue="true" /> - - + <- Action for this is + MetricsConstants.ACTION_TUNER_DO_NOT_DISTURB_VOLUME_SHORTCUT -> - - - - - - - - - - - - - + - + android:key="plugins" + android:title="@string/plugins" + android:fragment="com.android.systemui.tuner.PluginFragment" /> diff --git a/packages/SystemUI/src/com/android/systemui/tuner/StatusBarFragment.java b/packages/SystemUI/src/com/android/systemui/tuner/StatusBarFragment.java new file mode 100644 index 00000000000..9e7850a31e8 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/tuner/StatusBarFragment.java @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ + +package com.android.systemui.tuner; + +import android.os.Bundle; + +import androidx.preference.PreferenceFragment; + +import com.android.systemui.R; + +public class StatusBarFragment extends PreferenceFragment { + @Override + public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { + addPreferencesFromResource(R.xml.statusbar_settings); + } +} diff --git a/packages/SystemUI/src/com/android/systemui/tuner/TunerFragment.java b/packages/SystemUI/src/com/android/systemui/tuner/TunerFragment.java index 0070dcf9a60..cfa43decd1c 100644 --- a/packages/SystemUI/src/com/android/systemui/tuner/TunerFragment.java +++ b/packages/SystemUI/src/com/android/systemui/tuner/TunerFragment.java @@ -15,19 +15,9 @@ */ package com.android.systemui.tuner; -import android.app.AlertDialog; -import android.app.Dialog; -import android.app.DialogFragment; -import android.content.DialogInterface; import android.hardware.display.AmbientDisplayConfiguration; -import android.os.Build; import android.os.Bundle; -import android.provider.Settings; -import android.view.Menu; -import android.view.MenuInflater; -import android.view.MenuItem; -import androidx.preference.Preference; import androidx.preference.PreferenceFragment; import com.android.internal.logging.MetricsLogger; @@ -39,26 +29,12 @@ public class TunerFragment extends PreferenceFragment { private static final String TAG = "TunerFragment"; - private static final String KEY_BATTERY_PCT = "battery_pct"; private static final String KEY_PLUGINS = "plugins"; private static final CharSequence KEY_DOZE = "doze"; - public static final String SETTING_SEEN_TUNER_WARNING = "seen_tuner_warning"; - - private static final String WARNING_TAG = "tuner_warning"; - private static final String[] DEBUG_ONLY = new String[] { - "nav_bar", - "lockscreen", - "picture_in_picture", - }; - - private static final int MENU_REMOVE = Menu.FIRST + 1; - @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - - setHasOptionsMenu(true); } @Override @@ -76,19 +52,6 @@ public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { if (!alwaysOnAvailable()) { getPreferenceScreen().removePreference(findPreference(KEY_DOZE)); } - if (!Build.IS_DEBUGGABLE) { - for (int i = 0; i < DEBUG_ONLY.length; i++) { - Preference preference = findPreference(DEBUG_ONLY[i]); - if (preference != null) getPreferenceScreen().removePreference(preference); - } - } - - if (Settings.Secure.getInt(getContext().getContentResolver(), SETTING_SEEN_TUNER_WARNING, - 0) == 0) { - if (getFragmentManager().findFragmentByTag(WARNING_TAG) == null) { - new TunerWarningFragment().show(getFragmentManager(), WARNING_TAG); - } - } } private boolean alwaysOnAvailable() { @@ -98,7 +61,7 @@ private boolean alwaysOnAvailable() { @Override public void onResume() { super.onResume(); - getActivity().setTitle(R.string.system_ui_tuner); + getActivity().setTitle(R.string.reloaded_tuner_title); MetricsLogger.visibility(getContext(), MetricsEvent.TUNER, true); } @@ -110,44 +73,4 @@ public void onPause() { MetricsLogger.visibility(getContext(), MetricsEvent.TUNER, false); } - @Override - public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { - menu.add(Menu.NONE, MENU_REMOVE, Menu.NONE, R.string.remove_from_settings); - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - switch (item.getItemId()) { - case android.R.id.home: - getActivity().finish(); - return true; - case MENU_REMOVE: - TunerService.showResetRequest(getContext(), new Runnable() { - @Override - public void run() { - if (getActivity() != null) { - getActivity().finish(); - } - } - }); - return true; - } - return super.onOptionsItemSelected(item); - } - - public static class TunerWarningFragment extends DialogFragment { - @Override - public Dialog onCreateDialog(Bundle savedInstanceState) { - return new AlertDialog.Builder(getContext()) - .setTitle(R.string.tuner_warning_title) - .setMessage(R.string.tuner_warning) - .setPositiveButton(R.string.got_it, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - Settings.Secure.putInt(getContext().getContentResolver(), - SETTING_SEEN_TUNER_WARNING, 1); - } - }).show(); - } - } } diff --git a/packages/SystemUI/src/com/android/systemui/tuner/TunerService.java b/packages/SystemUI/src/com/android/systemui/tuner/TunerService.java index 338e1781abd..aea68e9d8c7 100644 --- a/packages/SystemUI/src/com/android/systemui/tuner/TunerService.java +++ b/packages/SystemUI/src/com/android/systemui/tuner/TunerService.java @@ -24,7 +24,6 @@ import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.os.UserHandle; -import android.provider.Settings; import com.android.systemui.Dependency; import com.android.systemui.R; @@ -98,8 +97,6 @@ public void onClick(DialogInterface dialog, int which) { // Disable access to tuner. TunerService.setTunerEnabled(context, false); // Make them sit through the warning dialog again. - Settings.Secure.putInt(context.getContentResolver(), - TunerFragment.SETTING_SEEN_TUNER_WARNING, 0); if (onDisabled != null) { onDisabled.run(); } From 8fb8d5ce65caed1f4e77b74263913f2fbfa71fbf Mon Sep 17 00:00:00 2001 From: Ali B Date: Mon, 2 Jul 2018 00:26:10 +0300 Subject: [PATCH 109/240] SystemUI: Add List and Switch Preferences Change-Id: I0cf7c2113efec7080e4bfd0300aee4fc2f897ff3 --- .../reloaded/SecureSettingListPreference.java | 69 ++++++++++++++++++ .../SecureSettingSwitchPreference.java | 51 +++++++++++++ .../reloaded/SecureSettingsStore.java | 73 +++++++++++++++++++ .../reloaded/SystemSettingListPreference.java | 69 ++++++++++++++++++ .../SystemSettingSwitchPreference.java | 50 +++++++++++++ .../reloaded/SystemSettingsStore.java | 73 +++++++++++++++++++ 6 files changed, 385 insertions(+) create mode 100644 packages/SystemUI/src/com/android/systemui/reloaded/SecureSettingListPreference.java create mode 100644 packages/SystemUI/src/com/android/systemui/reloaded/SecureSettingSwitchPreference.java create mode 100644 packages/SystemUI/src/com/android/systemui/reloaded/SecureSettingsStore.java create mode 100644 packages/SystemUI/src/com/android/systemui/reloaded/SystemSettingListPreference.java create mode 100644 packages/SystemUI/src/com/android/systemui/reloaded/SystemSettingSwitchPreference.java create mode 100644 packages/SystemUI/src/com/android/systemui/reloaded/SystemSettingsStore.java diff --git a/packages/SystemUI/src/com/android/systemui/reloaded/SecureSettingListPreference.java b/packages/SystemUI/src/com/android/systemui/reloaded/SecureSettingListPreference.java new file mode 100644 index 00000000000..8a109fc50e4 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/reloaded/SecureSettingListPreference.java @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2017-2018 AICP + * + * 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.reloaded; + +import android.content.Context; +import android.text.TextUtils; +import android.util.AttributeSet; +import androidx.preference.ListPreference; + +public class SecureSettingListPreference extends ListPreference { + private boolean mAutoSummary = false; + + public SecureSettingListPreference(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + setPreferenceDataStore(new SecureSettingsStore(context.getContentResolver())); + } + + public SecureSettingListPreference(Context context, AttributeSet attrs) { + super(context, attrs); + setPreferenceDataStore(new SecureSettingsStore(context.getContentResolver())); + } + + public SecureSettingListPreference(Context context) { + super(context); + setPreferenceDataStore(new SecureSettingsStore(context.getContentResolver())); + } + + @Override + public void setValue(String value) { + super.setValue(value); + if (mAutoSummary || TextUtils.isEmpty(getSummary())) { + setSummary(getEntry(), true); + } + } + + @Override + public void setSummary(CharSequence summary) { + setSummary(summary, false); + } + + private void setSummary(CharSequence summary, boolean autoSummary) { + mAutoSummary = autoSummary; + super.setSummary(summary); + } + + @Override + protected void onSetInitialValue(boolean restoreValue, Object defaultValue) { + // This is what default ListPreference implementation is doing without respecting + // real default value: + //setValue(restoreValue ? getPersistedString(mValue) : (String) defaultValue); + // Instead, we better do + setValue(restoreValue ? getPersistedString((String) defaultValue) : (String) defaultValue); + } + +} diff --git a/packages/SystemUI/src/com/android/systemui/reloaded/SecureSettingSwitchPreference.java b/packages/SystemUI/src/com/android/systemui/reloaded/SecureSettingSwitchPreference.java new file mode 100644 index 00000000000..ee73781110b --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/reloaded/SecureSettingSwitchPreference.java @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2017 AICP + * + * 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.reloaded; + +import android.content.Context; + +import android.util.AttributeSet; +import androidx.preference.SwitchPreference; + +public class SecureSettingSwitchPreference extends SwitchPreference { + + public SecureSettingSwitchPreference(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + setPreferenceDataStore(new SecureSettingsStore(context.getContentResolver())); + } + + public SecureSettingSwitchPreference(Context context, AttributeSet attrs) { + super(context, attrs); + setPreferenceDataStore(new SecureSettingsStore(context.getContentResolver())); + } + + public SecureSettingSwitchPreference(Context context) { + super(context); + setPreferenceDataStore(new SecureSettingsStore(context.getContentResolver())); + } + + @Override + protected void onSetInitialValue(boolean restoreValue, Object defaultValue) { + // This is what default TwoStatePreference implementation is doing without respecting + // real default value: + //setChecked(restoreValue ? getPersistedBoolean(mChecked) + // : (Boolean) defaultValue); + // Instead, we better do + setChecked(restoreValue ? getPersistedBoolean((Boolean) defaultValue) + : (Boolean) defaultValue); + } +} diff --git a/packages/SystemUI/src/com/android/systemui/reloaded/SecureSettingsStore.java b/packages/SystemUI/src/com/android/systemui/reloaded/SecureSettingsStore.java new file mode 100644 index 00000000000..a0f3be6e830 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/reloaded/SecureSettingsStore.java @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2017 AICP + * + * 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.reloaded; + +import android.content.ContentResolver; +import android.preference.PreferenceDataStore; +import android.provider.Settings; + +public class SecureSettingsStore extends androidx.preference.PreferenceDataStore + implements PreferenceDataStore { + + private ContentResolver mContentResolver; + + public SecureSettingsStore(ContentResolver contentResolver) { + mContentResolver = contentResolver; + } + + public boolean getBoolean(String key, boolean defValue) { + return getInt(key, defValue ? 1 : 0) != 0; + } + + public float getFloat(String key, float defValue) { + return Settings.Secure.getFloat(mContentResolver, key, defValue); + } + + public int getInt(String key, int defValue) { + return Settings.Secure.getInt(mContentResolver, key, defValue); + } + + public long getLong(String key, long defValue) { + return Settings.Secure.getLong(mContentResolver, key, defValue); + } + + public String getString(String key, String defValue) { + String result = Settings.Secure.getString(mContentResolver, key); + return result == null ? defValue : result; + } + + public void putBoolean(String key, boolean value) { + putInt(key, value ? 1 : 0); + } + + public void putFloat(String key, float value) { + Settings.Secure.putFloat(mContentResolver, key, value); + } + + public void putInt(String key, int value) { + Settings.Secure.putInt(mContentResolver, key, value); + } + + public void putLong(String key, long value) { + Settings.Secure.putLong(mContentResolver, key, value); + } + + public void putString(String key, String value) { + Settings.Secure.putString(mContentResolver, key, value); + } + +} diff --git a/packages/SystemUI/src/com/android/systemui/reloaded/SystemSettingListPreference.java b/packages/SystemUI/src/com/android/systemui/reloaded/SystemSettingListPreference.java new file mode 100644 index 00000000000..694d9d2ecb2 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/reloaded/SystemSettingListPreference.java @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2017-2018 AICP + * + * 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.reloaded; + +import android.content.Context; +import android.text.TextUtils; +import android.util.AttributeSet; +import androidx.preference.ListPreference; + +public class SystemSettingListPreference extends ListPreference { + private boolean mAutoSummary = false; + + public SystemSettingListPreference(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + setPreferenceDataStore(new SystemSettingsStore(context.getContentResolver())); + } + + public SystemSettingListPreference(Context context, AttributeSet attrs) { + super(context, attrs); + setPreferenceDataStore(new SystemSettingsStore(context.getContentResolver())); + } + + public SystemSettingListPreference(Context context) { + super(context); + setPreferenceDataStore(new SystemSettingsStore(context.getContentResolver())); + } + + @Override + public void setValue(String value) { + super.setValue(value); + if (mAutoSummary || TextUtils.isEmpty(getSummary())) { + setSummary(getEntry(), true); + } + } + + @Override + public void setSummary(CharSequence summary) { + setSummary(summary, false); + } + + private void setSummary(CharSequence summary, boolean autoSummary) { + mAutoSummary = autoSummary; + super.setSummary(summary); + } + + @Override + protected void onSetInitialValue(boolean restoreValue, Object defaultValue) { + // This is what default ListPreference implementation is doing without respecting + // real default value: + //setValue(restoreValue ? getPersistedString(mValue) : (String) defaultValue); + // Instead, we better do + setValue(restoreValue ? getPersistedString((String) defaultValue) : (String) defaultValue); + } + +} diff --git a/packages/SystemUI/src/com/android/systemui/reloaded/SystemSettingSwitchPreference.java b/packages/SystemUI/src/com/android/systemui/reloaded/SystemSettingSwitchPreference.java new file mode 100644 index 00000000000..4cc2e5a571d --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/reloaded/SystemSettingSwitchPreference.java @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2017 AICP + * + * 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.reloaded; + +import android.content.Context; +import android.util.AttributeSet; +import androidx.preference.SwitchPreference; + +public class SystemSettingSwitchPreference extends SwitchPreference { + + public SystemSettingSwitchPreference(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + setPreferenceDataStore(new SystemSettingsStore(context.getContentResolver())); + } + + public SystemSettingSwitchPreference(Context context, AttributeSet attrs) { + super(context, attrs); + setPreferenceDataStore(new SystemSettingsStore(context.getContentResolver())); + } + + public SystemSettingSwitchPreference(Context context) { + super(context); + setPreferenceDataStore(new SystemSettingsStore(context.getContentResolver())); + } + + @Override + protected void onSetInitialValue(boolean restoreValue, Object defaultValue) { + // This is what default TwoStatePreference implementation is doing without respecting + // real default value: + //setChecked(restoreValue ? getPersistedBoolean(mChecked) + // : (Boolean) defaultValue); + // Instead, we better do + setChecked(restoreValue ? getPersistedBoolean((Boolean) defaultValue) + : (Boolean) defaultValue); + } +} diff --git a/packages/SystemUI/src/com/android/systemui/reloaded/SystemSettingsStore.java b/packages/SystemUI/src/com/android/systemui/reloaded/SystemSettingsStore.java new file mode 100644 index 00000000000..d50d98da2d1 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/reloaded/SystemSettingsStore.java @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2017 AICP + * + * 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.reloaded; + +import android.content.ContentResolver; +import android.preference.PreferenceDataStore; +import android.provider.Settings; + +public class SystemSettingsStore extends androidx.preference.PreferenceDataStore + implements PreferenceDataStore { + + private ContentResolver mContentResolver; + + public SystemSettingsStore(ContentResolver contentResolver) { + mContentResolver = contentResolver; + } + + public boolean getBoolean(String key, boolean defValue) { + return getInt(key, defValue ? 1 : 0) != 0; + } + + public float getFloat(String key, float defValue) { + return Settings.System.getFloat(mContentResolver, key, defValue); + } + + public int getInt(String key, int defValue) { + return Settings.System.getInt(mContentResolver, key, defValue); + } + + public long getLong(String key, long defValue) { + return Settings.System.getLong(mContentResolver, key, defValue); + } + + public String getString(String key, String defValue) { + String result = Settings.System.getString(mContentResolver, key); + return result == null ? defValue : result; + } + + public void putBoolean(String key, boolean value) { + putInt(key, value ? 1 : 0); + } + + public void putFloat(String key, float value) { + Settings.System.putFloat(mContentResolver, key, value); + } + + public void putInt(String key, int value) { + Settings.System.putInt(mContentResolver, key, value); + } + + public void putLong(String key, long value) { + Settings.System.putLong(mContentResolver, key, value); + } + + public void putString(String key, String value) { + Settings.System.putString(mContentResolver, key, value); + } + +} From b007985b9377c2913fe0cbd986ac84f206ce9aa7 Mon Sep 17 00:00:00 2001 From: maxwen Date: Mon, 28 Aug 2017 03:37:08 +0200 Subject: [PATCH 110/240] base: Advanced reboot add a customReboot API that is used for advanced reboot fromm GlobaActions and use correct strings for the reboot progress dialog base: expose rebootCustom for OpenDelta Dont scare people by showing the wrong reboot progress Adapted for android 7.0 base: use new shutdown ui for all reboot actions Change-Id: I54e8c96543945200bf4ffc47d03782be145ac594 --- core/java/android/os/IPowerManager.aidl | 1 + core/java/android/os/PowerManager.java | 30 +++ core/java/android/provider/Settings.java | 14 ++ .../internal/statusbar/IStatusBar.aidl | 2 +- .../internal/statusbar/IStatusBarService.aidl | 2 +- core/res/res/values/reloaded_arrays.xml | 25 +++ core/res/res/values/reloaded_strings.xml | 36 ++++ core/res/res/values/reloaded_symbols.xml | 13 ++ .../systemui/plugins/GlobalActions.java | 4 +- .../res/drawable/ic_restart_bootloader.xml | 30 +++ .../res/drawable/ic_restart_recovery.xml | 42 ++++ .../SystemUI/res/values/reloaded_strings.xml | 7 + .../globalactions/GlobalActionsComponent.java | 8 +- .../globalactions/GlobalActionsDialog.java | 196 ++++++++++++++---- .../globalactions/GlobalActionsImpl.java | 20 +- .../systemui/statusbar/CommandQueue.java | 8 +- .../server/policy/WindowManagerPolicy.java | 6 + .../server/power/PowerManagerService.java | 36 +++- .../android/server/power/ShutdownThread.java | 67 +++++- .../statusbar/StatusBarManagerInternal.java | 2 +- .../statusbar/StatusBarManagerService.java | 9 +- .../server/wm/WindowManagerService.java | 12 ++ 22 files changed, 490 insertions(+), 80 deletions(-) create mode 100644 core/res/res/values/reloaded_arrays.xml create mode 100644 core/res/res/values/reloaded_strings.xml create mode 100644 packages/SystemUI/res/drawable/ic_restart_bootloader.xml create mode 100644 packages/SystemUI/res/drawable/ic_restart_recovery.xml diff --git a/core/java/android/os/IPowerManager.aidl b/core/java/android/os/IPowerManager.aidl index e1d605e1c99..a497f412673 100644 --- a/core/java/android/os/IPowerManager.aidl +++ b/core/java/android/os/IPowerManager.aidl @@ -63,6 +63,7 @@ interface IPowerManager @UnsupportedAppUsage void reboot(boolean confirm, String reason, boolean wait); void rebootSafeMode(boolean confirm, boolean wait); + void rebootCustom(boolean confirm, String reason, boolean wait); void shutdown(boolean confirm, String reason, boolean wait); void crash(String message); int getLastShutdownReason(); diff --git a/core/java/android/os/PowerManager.java b/core/java/android/os/PowerManager.java index 2fff595d715..9895f9b0a6c 100644 --- a/core/java/android/os/PowerManager.java +++ b/core/java/android/os/PowerManager.java @@ -579,6 +579,18 @@ public WakeData(long wakeTime, @WakeReason int wakeReason) { */ public static final String REBOOT_RECOVERY = "recovery"; + /** + * The value to pass as the 'reason' argument to reboot() to + * reboot into bootloader mode + *

+ * Requires the {@link android.Manifest.permission#RECOVERY} + * permission (in addition to + * {@link android.Manifest.permission#REBOOT}). + *

+ * @hide + */ + public static final String REBOOT_BOOTLOADER = "bootloader"; + /** * The value to pass as the 'reason' argument to reboot() to reboot into * recovery mode for applying system updates. @@ -1413,6 +1425,24 @@ public void rebootSafeMode() { } } + /** + * Reboot the device with custom progress meassges. + * Will not return if the reboot is successful. + *

+ * Requires the {@link android.Manifest.permission#REBOOT} permission. + *

+ * + * @param reason code to pass to the kernel (e.g., "recovery") to + * request special boot modes, or null. + * @hide + */ + public void rebootCustom(String reason) { + try { + mService.rebootCustom(false, reason, true); + } catch (RemoteException e) { + } + } + /** * Returns true if the device is currently in power save mode. When in this mode, * applications should reduce their functionality in order to conserve battery as diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index 7772c78db1b..a64c1211ce8 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -4477,6 +4477,17 @@ public boolean validate(@Nullable String value) { * it to PRIVATE_SETTINGS below. Also add a validator that can validate * the setting value. See an example above. */ + + /** + * Setting to determine whether or not to show the battery percentage in the status bar. + * 0 - Don't show percentage + * 1 - Show percentage + * @hide + */ + public static final String ADVANCED_REBOOT = "advanced_reboot"; + + /** @hide */ + private static final Validator ADVANCED_REBOOT_VALIDATOR = BOOLEAN_VALIDATOR; /** * Settings to backup. This is here so that it's in the same place as the settings @@ -4543,6 +4554,7 @@ public boolean validate(@Nullable String value) { DISPLAY_COLOR_MODE, ALARM_ALERT, NOTIFICATION_LIGHT_PULSE, + ADVANCED_REBOOT, }; /** @@ -4662,6 +4674,7 @@ public boolean validate(@Nullable String value) { PRIVATE_SETTINGS.add(EGG_MODE); PRIVATE_SETTINGS.add(SHOW_BATTERY_PERCENT); PRIVATE_SETTINGS.add(DISPLAY_COLOR_MODE); + PRIVATE_SETTINGS.add(ADVANCED_REBOOT); } /** @@ -4755,6 +4768,7 @@ public boolean validate(@Nullable String value) { VALIDATORS.put(WIFI_STATIC_DNS2, WIFI_STATIC_DNS2_VALIDATOR); VALIDATORS.put(SHOW_BATTERY_PERCENT, SHOW_BATTERY_PERCENT_VALIDATOR); VALIDATORS.put(NOTIFICATION_LIGHT_PULSE, BOOLEAN_VALIDATOR); + VALIDATORS.put(ADVANCED_REBOOT, ADVANCED_REBOOT_VALIDATOR); } /** diff --git a/core/java/com/android/internal/statusbar/IStatusBar.aidl b/core/java/com/android/internal/statusbar/IStatusBar.aidl index c715577cb7d..482e5961c1e 100644 --- a/core/java/com/android/internal/statusbar/IStatusBar.aidl +++ b/core/java/com/android/internal/statusbar/IStatusBar.aidl @@ -149,7 +149,7 @@ oneway interface IStatusBar void showPinningEnterExitToast(boolean entering); void showPinningEscapeToast(); - void showShutdownUi(boolean isReboot, String reason); + void showShutdownUi(boolean isReboot, String reason, boolean rebootCustom); // Used to show the dialog when BiometricService starts authentication void showBiometricDialog(in Bundle bundle, IBiometricServiceReceiverInternal receiver, int type, diff --git a/core/java/com/android/internal/statusbar/IStatusBarService.aidl b/core/java/com/android/internal/statusbar/IStatusBarService.aidl index 598c3917bf9..5921f64abed 100644 --- a/core/java/com/android/internal/statusbar/IStatusBarService.aidl +++ b/core/java/com/android/internal/statusbar/IStatusBarService.aidl @@ -85,7 +85,7 @@ interface IStatusBarService * These methods are needed for global actions control which the UI is shown in sysui. */ void shutdown(); - void reboot(boolean safeMode); + void reboot(boolean safeMode, String reason); void addTile(in ComponentName tile); void remTile(in ComponentName tile); diff --git a/core/res/res/values/reloaded_arrays.xml b/core/res/res/values/reloaded_arrays.xml new file mode 100644 index 00000000000..36fab4c1d39 --- /dev/null +++ b/core/res/res/values/reloaded_arrays.xml @@ -0,0 +1,25 @@ + + + + + + restart + reboot_recovery + reboot_bootloader + + + diff --git a/core/res/res/values/reloaded_strings.xml b/core/res/res/values/reloaded_strings.xml new file mode 100644 index 00000000000..933ec845f87 --- /dev/null +++ b/core/res/res/values/reloaded_strings.xml @@ -0,0 +1,36 @@ + + + + + + Do you want to reboot? + Reboot + + + Reboot bootloader + Rebooting to bootloader\u2026 + + + Reboot recovery + Rebooting to recovery\u2026 + + + Restart system + Restarting system\u2026 + + diff --git a/core/res/res/values/reloaded_symbols.xml b/core/res/res/values/reloaded_symbols.xml index 9ab7764025b..64c0a230b47 100644 --- a/core/res/res/values/reloaded_symbols.xml +++ b/core/res/res/values/reloaded_symbols.xml @@ -29,4 +29,17 @@ + + + + + + + + + + + + + diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/GlobalActions.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/GlobalActions.java index 95ff13b45fb..7775551b731 100644 --- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/GlobalActions.java +++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/GlobalActions.java @@ -26,7 +26,7 @@ public interface GlobalActions extends Plugin { int VERSION = 1; void showGlobalActions(GlobalActionsManager manager); - default void showShutdownUi(boolean isReboot, String reason) { + default void showShutdownUi(boolean isReboot, String reason, boolean rebootCustom) { } default void destroy() { @@ -40,6 +40,6 @@ public interface GlobalActionsManager { void onGlobalActionsHidden(); void shutdown(); - void reboot(boolean safeMode); + void reboot(boolean safeMode, String reason); } } diff --git a/packages/SystemUI/res/drawable/ic_restart_bootloader.xml b/packages/SystemUI/res/drawable/ic_restart_bootloader.xml new file mode 100644 index 00000000000..6029f4ff8b2 --- /dev/null +++ b/packages/SystemUI/res/drawable/ic_restart_bootloader.xml @@ -0,0 +1,30 @@ + + + + + diff --git a/packages/SystemUI/res/drawable/ic_restart_recovery.xml b/packages/SystemUI/res/drawable/ic_restart_recovery.xml new file mode 100644 index 00000000000..ee3cd171a3f --- /dev/null +++ b/packages/SystemUI/res/drawable/ic_restart_recovery.xml @@ -0,0 +1,42 @@ + + + + + diff --git a/packages/SystemUI/res/values/reloaded_strings.xml b/packages/SystemUI/res/values/reloaded_strings.xml index 0fd7e9e132c..1a18404557a 100644 --- a/packages/SystemUI/res/values/reloaded_strings.xml +++ b/packages/SystemUI/res/values/reloaded_strings.xml @@ -23,4 +23,11 @@ Statusbar icons + + Restart + Restart\u2026 + System + Recovery + Bootloader + diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsComponent.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsComponent.java index e8ef454bd46..adb975d78a9 100644 --- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsComponent.java +++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsComponent.java @@ -56,8 +56,8 @@ private void onExtensionCallback(GlobalActions newPlugin) { } @Override - public void handleShowShutdownUi(boolean isReboot, String reason) { - mExtension.get().showShutdownUi(isReboot, reason); + public void handleShowShutdownUi(boolean isReboot, String reason, boolean rebootCustom) { + mExtension.get().showShutdownUi(isReboot, reason, rebootCustom); } @Override @@ -90,9 +90,9 @@ public void shutdown() { } @Override - public void reboot(boolean safeMode) { + public void reboot(boolean safeMode, String reason) { try { - mBarService.reboot(safeMode); + mBarService.reboot(safeMode, reason); } catch (RemoteException e) { } } diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java index ff02e71147f..cfd48410682 100644 --- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java +++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java @@ -43,6 +43,8 @@ import android.os.Handler; import android.os.IBinder; import android.os.Message; +import android.os.Messenger; +import android.os.PowerManager; import android.os.RemoteException; import android.os.ServiceManager; import android.os.SystemProperties; @@ -136,6 +138,8 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener, 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 static final String GLOBAL_ACTION_KEY_REBOOT_RECOVERY = "reboot_recovery"; + private static final String GLOBAL_ACTION_KEY_REBOOT_BOOTLOADER = "reboot_bootloader"; private final Context mContext; private final GlobalActionsManager mWindowManagerFuncs; @@ -168,6 +172,12 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener, private final ActivityStarter mActivityStarter; private GlobalActionsPanelPlugin mPanelPlugin; + // advanced reboot + private String[] mRootMenuActions; + private String[] mRebootMenuActions; + private String[] mCurrentMenuActions; + private boolean mRebootMenu; + /** * @param context everything needs a context :( */ @@ -221,6 +231,12 @@ public GlobalActionsDialog(Context context, GlobalActionsManager windowManagerFu mDialog.mPanelController.onDeviceLockStateChanged(locked); } }); + + mRootMenuActions = mContext.getResources().getStringArray( + R.array.config_globalActionsList); + mRebootMenuActions = mContext.getResources().getStringArray( + R.array.config_rebootActionsList); + mItems = new ArrayList(); } /** @@ -233,6 +249,8 @@ public void showDialog(boolean keyguardShowing, boolean isDeviceProvisioned, mKeyguardShowing = keyguardShowing; mDeviceProvisioned = isDeviceProvisioned; mPanelPlugin = panelPlugin; + mRebootMenu = false; + mCurrentMenuActions = mRootMenuActions; if (mDialog != null) { mDialog.dismiss(); mDialog = null; @@ -337,16 +355,62 @@ public boolean showBeforeProvisioning() { } }; onAirplaneModeChanged(); + buildMenuList(); - mItems = new ArrayList(); - String[] defaultActions = mContext.getResources().getStringArray( - R.array.config_globalActionsList); + mAdapter = new MyAdapter(); + + GlobalActionsPanelPlugin.PanelViewController panelViewController = + mPanelPlugin != null + ? mPanelPlugin.onPanelShown( + new GlobalActionsPanelPlugin.Callbacks() { + @Override + public void dismissGlobalActionsMenu() { + if (mDialog != null) { + mDialog.dismiss(); + } + } + + @Override + public void startPendingIntentDismissingKeyguard( + PendingIntent intent) { + mActivityStarter + .startPendingIntentDismissingKeyguard(intent); + } + }, + mKeyguardManager.isDeviceLocked()) + : null; + + ActionsDialog dialog = new ActionsDialog(mContext, mAdapter, panelViewController); + dialog.setCanceledOnTouchOutside(false); // Handled by the custom class. + dialog.setKeyguardShowing(mKeyguardShowing); + + dialog.setOnDismissListener(this); + dialog.setOnShowListener(this); + + return dialog; + } + + private boolean advancedRebootEnabled(Context context) { + boolean advancedRebootEnabled = Settings.System.getInt(context.getContentResolver(), + Settings.System.ADVANCED_REBOOT, 0) == 1; + return advancedRebootEnabled; + } + + private boolean isSecureLocked() { + if (mKeyguardShowing) { + return mKeyguardManager.inKeyguardRestrictedInputMode() && mKeyguardManager.isKeyguardSecure(); + } + return false; + } + + private void buildMenuList() { + mItems.clear(); ArraySet addedKeys = new ArraySet(); mHasLogoutButton = false; mHasLockdownButton = false; - for (int i = 0; i < defaultActions.length; i++) { - String actionKey = defaultActions[i]; + for (int i = 0; i < mCurrentMenuActions.length; i++) { + String actionKey = mCurrentMenuActions[i]; if (addedKeys.contains(actionKey)) { // If we already have added this, don't add it again. continue; @@ -395,6 +459,10 @@ && getCurrentUser().id != UserHandle.USER_SYSTEM) { if (!mEmergencyAffordanceManager.needsEmergencyAffordance()) { mItems.add(new EmergencyDialerAction()); } + } else if (GLOBAL_ACTION_KEY_REBOOT_RECOVERY.equals(actionKey)) { + mItems.add(new RebootRecoveryAction()); + } else if (GLOBAL_ACTION_KEY_REBOOT_BOOTLOADER.equals(actionKey)) { + mItems.add(new RebootBootloaderAction()); } else { Log.e(TAG, "Invalid global action key " + actionKey); } @@ -402,41 +470,9 @@ && getCurrentUser().id != UserHandle.USER_SYSTEM) { addedKeys.add(actionKey); } - if (mEmergencyAffordanceManager.needsEmergencyAffordance()) { + if (mEmergencyAffordanceManager.needsEmergencyAffordance() && !mRebootMenu) { mItems.add(new EmergencyAffordanceAction()); } - - mAdapter = new MyAdapter(); - - GlobalActionsPanelPlugin.PanelViewController panelViewController = - mPanelPlugin != null - ? mPanelPlugin.onPanelShown( - new GlobalActionsPanelPlugin.Callbacks() { - @Override - public void dismissGlobalActionsMenu() { - if (mDialog != null) { - mDialog.dismiss(); - } - } - - @Override - public void startPendingIntentDismissingKeyguard( - PendingIntent intent) { - mActivityStarter - .startPendingIntentDismissingKeyguard(intent); - } - }, - mKeyguardManager.isDeviceLocked()) - : null; - - ActionsDialog dialog = new ActionsDialog(mContext, mAdapter, panelViewController); - dialog.setCanceledOnTouchOutside(false); // Handled by the custom class. - dialog.setKeyguardShowing(mKeyguardShowing); - - dialog.setOnDismissListener(this); - dialog.setOnShowListener(this); - - return dialog; } private boolean shouldDisplayLockdown() { @@ -474,7 +510,7 @@ private PowerAction() { public boolean onLongPress() { UserManager um = (UserManager) mContext.getSystemService(Context.USER_SERVICE); if (!um.hasUserRestriction(UserManager.DISALLOW_SAFE_BOOT)) { - mWindowManagerFuncs.reboot(true); + mWindowManagerFuncs.reboot(true, null); return true; } return false; @@ -571,14 +607,19 @@ public void onPress() { private final class RestartAction extends SinglePressAction implements LongPressAction { private RestartAction() { - super(R.drawable.ic_restart, R.string.global_action_restart); + super(R.drawable.ic_restart, com.android.systemui.R.string.global_action_reboot); + if (mRebootMenu) { + mMessageResId = com.android.systemui.R.string.global_action_reboot_sub; + } else if (advancedRebootEnabled(mContext)) { + mMessageResId = com.android.systemui.R.string.global_action_reboot_more; + } } @Override public boolean onLongPress() { UserManager um = (UserManager) mContext.getSystemService(Context.USER_SERVICE); if (!um.hasUserRestriction(UserManager.DISALLOW_SAFE_BOOT)) { - mWindowManagerFuncs.reboot(true); + mWindowManagerFuncs.reboot(true, null); return true; } return false; @@ -596,7 +637,62 @@ public boolean showBeforeProvisioning() { @Override public void onPress() { - mWindowManagerFuncs.reboot(false); + if (!mRebootMenu && advancedRebootEnabled(mContext) && !isSecureLocked()) { + mRebootMenu = true; + mCurrentMenuActions = mRebootMenuActions; + buildMenuList(); + mDialog.updateList(); + } else { + mDialog.dismiss(); + doReboot(); + } + } + + private void doReboot() { + mHandler.sendEmptyMessageDelayed(MESSAGE_DISMISS, DIALOG_DISMISS_DELAY); + mWindowManagerFuncs.reboot(false, null); + } + } + + private final class RebootRecoveryAction extends SinglePressAction { + private RebootRecoveryAction() { + super(com.android.systemui.R.drawable.ic_restart_recovery, com.android.systemui.R.string.global_action_reboot_recovery); + } + + @Override + public boolean showDuringKeyguard() { + return true; + } + + @Override + public boolean showBeforeProvisioning() { + return true; + } + + @Override + public void onPress() { + mWindowManagerFuncs.reboot(false, PowerManager.REBOOT_RECOVERY); + } + } + + private final class RebootBootloaderAction extends SinglePressAction { + private RebootBootloaderAction() { + super(com.android.systemui.R.drawable.ic_restart_bootloader, com.android.systemui.R.string.global_action_reboot_bootloader); + } + + @Override + public boolean showDuringKeyguard() { + return true; + } + + @Override + public boolean showBeforeProvisioning() { + return true; + } + + @Override + public void onPress() { + mWindowManagerFuncs.reboot(false, PowerManager.REBOOT_BOOTLOADER); } } @@ -928,6 +1024,14 @@ public void onShow(DialogInterface dialog) { MetricsLogger.visible(mContext, MetricsEvent.POWER_MENU); } + public void onClick(DialogInterface dialog, int which) { + Action item = mAdapter.getItem(which); + if (!(item instanceof SilentModeTriStateAction) && !(item instanceof RestartAction)) { + dialog.dismiss(); + } + item.onPress(); + } + /** * The adapter used for the list within the global actions dialog, taking * into account whether the keyguard is showing via @@ -1031,7 +1135,7 @@ public boolean onLongClickItem(int position) { @Override public void onClickItem(int position) { Action item = mAdapter.getItem(position); - if (!(item instanceof SilentModeTriStateAction)) { + if (!(item instanceof SilentModeTriStateAction) && !(item instanceof RestartAction)) { mDialog.dismiss(); } item.onPress(); @@ -1097,7 +1201,7 @@ private interface LongPressAction extends Action { private static abstract class SinglePressAction implements Action { private final int mIconResId; private final Drawable mIcon; - private final int mMessageResId; + protected int mMessageResId; private final CharSequence mMessage; protected SinglePressAction(int iconResId, int messageResId) { @@ -1810,6 +1914,10 @@ public void refreshDialog() { mGlobalActionsLayout.updateList(); } + public void updateList() { + mGlobalActionsLayout.updateList(); + } + public void onRotate(int from, int to) { if (mShowing) { refreshDialog(); diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsImpl.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsImpl.java index 1f3403b054c..15a711b1f18 100644 --- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsImpl.java +++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsImpl.java @@ -20,6 +20,8 @@ import android.app.Dialog; import android.app.KeyguardManager; import android.content.Context; +import android.graphics.Point; +import android.os.PowerManager; import android.view.View; import android.view.ViewGroup; import android.view.Window; @@ -86,7 +88,7 @@ public void showGlobalActions(GlobalActionsManager manager) { } @Override - public void showShutdownUi(boolean isReboot, String reason) { + public void showShutdownUi(boolean isReboot, String reason, boolean rebootCustom) { ScrimDrawable background = new ScrimDrawable(); background.setAlpha((int) (SHUTDOWN_SCRIM_ALPHA * 255)); @@ -127,7 +129,21 @@ public void showShutdownUi(boolean isReboot, String reason) { bar.getIndeterminateDrawable().setTint(color); TextView message = d.findViewById(R.id.text1); message.setTextColor(color); - if (isReboot) message.setText(R.string.reboot_to_reset_message); + if (rebootCustom) { + if (reason != null) { + if (PowerManager.REBOOT_BOOTLOADER.equals(reason)) { + message.setText(com.android.internal.R.string.reboot_to_bootloader_message); + } else if (PowerManager.REBOOT_RECOVERY.equals(reason)) { + message.setText(com.android.internal.R.string.reboot_to_recovery_message); + } + } else { + message.setText(com.android.internal.R.string.reboot_system_message); + } + } else { + if (isReboot) { + message.setText(R.string.reboot_to_reset_message); + } + } GradientColors colors = Dependency.get(SysuiColorExtractor.class).getNeutralColors(); background.setColor(colors.getMainColor(), false); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java index 6329af56077..789bc926f75 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java @@ -265,7 +265,7 @@ default void handleSystemKey(int arg1) { } default void showPinningEnterExitToast(boolean entering) { } default void showPinningEscapeToast() { } default void handleShowGlobalActionsMenu() { } - default void handleShowShutdownUi(boolean isReboot, String reason) { } + default void handleShowShutdownUi(boolean isReboot, String reason, boolean rebootCustom) { } default void showWirelessChargingAnimation(int batteryLevel) { } @@ -715,10 +715,10 @@ public void setTopAppHidesStatusBar(boolean hidesStatusBar) { } @Override - public void showShutdownUi(boolean isReboot, String reason) { + public void showShutdownUi(boolean isReboot, String reason, boolean rebootCustom) { synchronized (mLock) { mHandler.removeMessages(MSG_SHOW_SHUTDOWN_UI); - mHandler.obtainMessage(MSG_SHOW_SHUTDOWN_UI, isReboot ? 1 : 0, 0, reason) + mHandler.obtainMessage(MSG_SHOW_SHUTDOWN_UI, isReboot ? 1 : 0, rebootCustom ? 1 : 0, reason) .sendToTarget(); } } @@ -1012,7 +1012,7 @@ public void handleMessage(Message msg) { break; case MSG_SHOW_SHUTDOWN_UI: for (int i = 0; i < mCallbacks.size(); i++) { - mCallbacks.get(i).handleShowShutdownUi(msg.arg1 != 0, (String) msg.obj); + mCallbacks.get(i).handleShowShutdownUi(msg.arg1 != 0, (String) msg.obj, msg.arg2 != 0); } break; case MSG_SET_TOP_APP_HIDES_STATUS_BAR: diff --git a/services/core/java/com/android/server/policy/WindowManagerPolicy.java b/services/core/java/com/android/server/policy/WindowManagerPolicy.java index 6d9c71096cb..72013b2c5b8 100644 --- a/services/core/java/com/android/server/policy/WindowManagerPolicy.java +++ b/services/core/java/com/android/server/policy/WindowManagerPolicy.java @@ -557,6 +557,12 @@ public InputConsumer createInputConsumer(Looper looper, String name, public void reboot(boolean confirm); public void rebootSafeMode(boolean confirm); + /** @hide */ + void reboot(String reason, boolean confirm); + + /** @hide */ + void rebootCustom(String reason, boolean confirm); + /** * Return the window manager lock needed to correctly call "Lw" methods. */ diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java index e1b3e4d6fbc..88332eaff6d 100644 --- a/services/core/java/com/android/server/power/PowerManagerService.java +++ b/services/core/java/com/android/server/power/PowerManagerService.java @@ -2834,7 +2834,7 @@ private void handleBatteryStateChangedLocked() { } private void shutdownOrRebootInternal(final @HaltMode int haltMode, final boolean confirm, - final String reason, boolean wait) { + final String reason, boolean wait, final boolean custom) { if (mHandler == null || !mSystemReady) { if (RescueParty.isAttemptingFactoryReset()) { // If we're stuck in a really low-level reboot loop, and a @@ -2853,7 +2853,11 @@ public void run() { if (haltMode == HALT_MODE_REBOOT_SAFE_MODE) { ShutdownThread.rebootSafeMode(getUiContext(), confirm); } else if (haltMode == HALT_MODE_REBOOT) { - ShutdownThread.reboot(getUiContext(), reason, confirm); + if (custom) { + ShutdownThread.rebootCustom(getUiContext(), reason, confirm); + } else { + ShutdownThread.reboot(getUiContext(), reason, confirm); + } } else { ShutdownThread.shutdown(getUiContext(), reason, confirm); } @@ -4658,7 +4662,7 @@ public void reboot(boolean confirm, String reason, boolean wait) { final long ident = Binder.clearCallingIdentity(); try { - shutdownOrRebootInternal(HALT_MODE_REBOOT, confirm, reason, wait); + shutdownOrRebootInternal(HALT_MODE_REBOOT, confirm, reason, wait, false); } finally { Binder.restoreCallingIdentity(ident); } @@ -4677,7 +4681,29 @@ public void rebootSafeMode(boolean confirm, boolean wait) { final long ident = Binder.clearCallingIdentity(); try { shutdownOrRebootInternal(HALT_MODE_REBOOT_SAFE_MODE, confirm, - PowerManager.REBOOT_SAFE_MODE, wait); + PowerManager.REBOOT_SAFE_MODE, wait, false); + } finally { + Binder.restoreCallingIdentity(ident); + } + } + + /** + * Reboots the device with custom progress message. + * + * @param confirm If true, shows a reboot confirmation dialog. + * @param reason The reason for the reboot, or null if none. + * @param wait If true, this call waits for the reboot to complete and does not return. + */ + @Override // Binder call + public void rebootCustom(boolean confirm, String reason, boolean wait) { + mContext.enforceCallingOrSelfPermission(android.Manifest.permission.REBOOT, null); + if (PowerManager.REBOOT_RECOVERY.equals(reason)) { + mContext.enforceCallingOrSelfPermission(android.Manifest.permission.RECOVERY, null); + } + + final long ident = Binder.clearCallingIdentity(); + try { + shutdownOrRebootInternal(HALT_MODE_REBOOT, confirm, reason, wait, true); } finally { Binder.restoreCallingIdentity(ident); } @@ -4695,7 +4721,7 @@ public void shutdown(boolean confirm, String reason, boolean wait) { final long ident = Binder.clearCallingIdentity(); try { - shutdownOrRebootInternal(HALT_MODE_SHUTDOWN, confirm, reason, wait); + shutdownOrRebootInternal(HALT_MODE_SHUTDOWN, confirm, reason, wait, false); } finally { Binder.restoreCallingIdentity(ident); } diff --git a/services/core/java/com/android/server/power/ShutdownThread.java b/services/core/java/com/android/server/power/ShutdownThread.java index fa4c4568de4..74d169f86fc 100644 --- a/services/core/java/com/android/server/power/ShutdownThread.java +++ b/services/core/java/com/android/server/power/ShutdownThread.java @@ -91,6 +91,7 @@ public final class ShutdownThread extends Thread { private static boolean mRebootSafeMode; private static boolean mRebootHasProgressBar; private static String mReason; + private static boolean mRebootCustom; // Provides shutdown assurance in case the system_server is killed public static final String SHUTDOWN_ACTION_PROPERTY = "sys.shutdown.requested"; @@ -150,6 +151,7 @@ public static void shutdown(final Context context, String reason, boolean confir mReboot = false; mRebootSafeMode = false; mReason = reason; + mRebootCustom = false; shutdownInner(context, confirm); } @@ -239,6 +241,22 @@ public static void reboot(final Context context, String reason, boolean confirm) mRebootSafeMode = false; mRebootHasProgressBar = false; mReason = reason; + mRebootCustom = false; + shutdownInner(context, confirm); + } + + /** + * Request reboot system, reboot recovery or reboot bootloader + * + * @param context Context used to display the shutdown progress dialog. + * @param reason code to pass to the kernel (e.g. "recovery", "bootloader"), or null. + * @param confirm true if user confirmation is needed before rebooting. + */ + public static void rebootCustom(final Context context, String reason, boolean confirm) { + mReboot = true; + mRebootSafeMode = false; + mReason = reason; + mRebootCustom = true; shutdownInner(context, confirm); } @@ -260,6 +278,7 @@ public static void rebootSafeMode(final Context context, boolean confirm) { mRebootSafeMode = true; mRebootHasProgressBar = false; mReason = null; + mRebootCustom = false; shutdownInner(context, confirm); } @@ -313,20 +332,46 @@ private static ProgressDialog showShutdownDialog(Context context) { com.android.internal.R.string.reboot_to_update_reboot)); } } else if (mReason != null && mReason.equals(PowerManager.REBOOT_RECOVERY)) { - if (RescueParty.isAttemptingFactoryReset()) { - // We're not actually doing a factory reset yet; we're rebooting - // to ask the user if they'd like to reset, so give them a less - // scary dialog message. - pd.setTitle(context.getText(com.android.internal.R.string.power_off)); - pd.setMessage(context.getText(com.android.internal.R.string.shutdown_progress)); - pd.setIndeterminate(true); + if (!mRebootCustom) { + if (RescueParty.isAttemptingFactoryReset()) { + // We're not actually doing a factory reset yet; we're rebooting + // to ask the user if they'd like to reset, so give them a less + // scary dialog message. + pd.setTitle(context.getText(com.android.internal.R.string.power_off)); + pd.setMessage(context.getText(com.android.internal.R.string.shutdown_progress)); + pd.setIndeterminate(true); + } else { + // Factory reset path. Set the dialog message accordingly. + pd.setTitle(context.getText(com.android.internal.R.string.reboot_to_reset_title)); + pd.setMessage(context.getText( + com.android.internal.R.string.reboot_to_reset_message)); + pd.setIndeterminate(true); + } } else { - // Factory reset path. Set the dialog message accordingly. - pd.setTitle(context.getText(com.android.internal.R.string.reboot_to_reset_title)); + if (showSysuiReboot()) { + return null; + } + pd.setTitle(context.getText(com.android.internal.R.string.reboot_to_recovery_title)); pd.setMessage(context.getText( - com.android.internal.R.string.reboot_to_reset_message)); + com.android.internal.R.string.reboot_to_recovery_message)); pd.setIndeterminate(true); } + } else if (mReason != null && PowerManager.REBOOT_BOOTLOADER.equals(mReason) && mRebootCustom) { + if (showSysuiReboot()) { + return null; + } + pd.setTitle(context.getText(com.android.internal.R.string.reboot_to_bootloader_title)); + pd.setMessage(context.getText( + com.android.internal.R.string.reboot_to_bootloader_message)); + pd.setIndeterminate(true); + } else if (mReason == null && mRebootCustom) { + if (showSysuiReboot()) { + return null; + } + pd.setTitle(context.getText(com.android.internal.R.string.reboot_system_title)); + pd.setMessage(context.getText( + com.android.internal.R.string.reboot_system_message)); + pd.setIndeterminate(true); } else { if (showSysuiReboot()) { return null; @@ -347,7 +392,7 @@ private static boolean showSysuiReboot() { try { StatusBarManagerInternal service = LocalServices.getService( StatusBarManagerInternal.class); - if (service.showShutdownUi(mReboot, mReason)) { + if (service.showShutdownUi(mReboot, mReason, mRebootCustom)) { // Sysui will handle shutdown UI. Log.d(TAG, "SysUI handling shutdown UI"); return true; diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java b/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java index a93d2b8b6fb..9b265e0f94f 100644 --- a/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java +++ b/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java @@ -93,7 +93,7 @@ void setSystemUiVisibility(int displayId, int vis, int fullscreenStackVis, int d */ void setTopAppHidesStatusBar(boolean hidesStatusBar); - boolean showShutdownUi(boolean isReboot, String requestString); + boolean showShutdownUi(boolean isReboot, String requestString, boolean rebootCustom); /** * Show a rotation suggestion that a user may approve to rotate the screen. diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java index 083662c5a8c..3907f9561ab 100644 --- a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java +++ b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java @@ -426,13 +426,13 @@ public void setTopAppHidesStatusBar(boolean hidesStatusBar) { } @Override - public boolean showShutdownUi(boolean isReboot, String reason) { + public boolean showShutdownUi(boolean isReboot, String reason, boolean rebootCustom) { if (!mContext.getResources().getBoolean(R.bool.config_showSysuiShutdown)) { return false; } if (mBar != null) { try { - mBar.showShutdownUi(isReboot, reason); + mBar.showShutdownUi(isReboot, reason, rebootCustom); return true; } catch (RemoteException ex) {} } @@ -1127,7 +1127,7 @@ public void shutdown() { * Allows the status bar to reboot the device. */ @Override - public void reboot(boolean safeMode) { + public void reboot(boolean safeMode, String reason) { enforceStatusBarService(); long identity = Binder.clearCallingIdentity(); try { @@ -1136,8 +1136,7 @@ public void reboot(boolean safeMode) { if (safeMode) { ShutdownThread.rebootSafeMode(getUiContext(), true); } else { - ShutdownThread.reboot(getUiContext(), - PowerManager.SHUTDOWN_USER_REQUESTED, false); + ShutdownThread.rebootCustom(getUiContext(), reason, false); } }); } finally { diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 165154cf959..9f65587203c 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -3184,6 +3184,18 @@ public void rebootSafeMode(boolean confirm) { confirm); } + // Called by window manager policy. Not exposed externally. + @Override + public void reboot(String reason, boolean confirm) { + ShutdownThread.reboot(ActivityThread.currentActivityThread().getSystemUiContext(), reason, confirm); + } + + // Called by window manager policy. Not exposed externally. + @Override + public void rebootCustom(String reason, boolean confirm) { + ShutdownThread.rebootCustom(ActivityThread.currentActivityThread().getSystemUiContext(), reason, confirm); + } + public void setCurrentProfileIds(final int[] currentProfileIds) { synchronized (mGlobalLock) { mCurrentProfileIds = currentProfileIds; From 9789028a6f0094db683cb10fc0c28f0a497fb9c1 Mon Sep 17 00:00:00 2001 From: Ritesh Saxena Date: Fri, 25 Oct 2019 05:18:02 +0000 Subject: [PATCH 111/240] tuner: Add tunables for advanced reboot Change-Id: I52e04de6af013eb23c35dfe52f6b93e05b5af0d6 --- .../SystemUI/res/values/reloaded_strings.xml | 5 ++++ .../SystemUI/res/xml/power_menu_settings.xml | 27 ++++++++++++++++++ packages/SystemUI/res/xml/tuner_prefs.xml | 5 ++++ .../systemui/tuner/PowerMenuFragment.java | 28 +++++++++++++++++++ 4 files changed, 65 insertions(+) create mode 100644 packages/SystemUI/res/xml/power_menu_settings.xml create mode 100644 packages/SystemUI/src/com/android/systemui/tuner/PowerMenuFragment.java diff --git a/packages/SystemUI/res/values/reloaded_strings.xml b/packages/SystemUI/res/values/reloaded_strings.xml index 1a18404557a..180f05a2827 100644 --- a/packages/SystemUI/res/values/reloaded_strings.xml +++ b/packages/SystemUI/res/values/reloaded_strings.xml @@ -30,4 +30,9 @@ Recovery Bootloader + + Power Menu + Advanced restart + Show recovery and bootloader restart options + diff --git a/packages/SystemUI/res/xml/power_menu_settings.xml b/packages/SystemUI/res/xml/power_menu_settings.xml new file mode 100644 index 00000000000..bd2b8376fc9 --- /dev/null +++ b/packages/SystemUI/res/xml/power_menu_settings.xml @@ -0,0 +1,27 @@ + + + + + + + + diff --git a/packages/SystemUI/res/xml/tuner_prefs.xml b/packages/SystemUI/res/xml/tuner_prefs.xml index adae5bf25ba..79fb6293b5b 100644 --- a/packages/SystemUI/res/xml/tuner_prefs.xml +++ b/packages/SystemUI/res/xml/tuner_prefs.xml @@ -33,6 +33,11 @@ android:title="@string/tuner_lock_screen" android:fragment="com.android.systemui.tuner.LockscreenFragment" /> + + diff --git a/packages/SystemUI/src/com/android/systemui/tuner/PowerMenuFragment.java b/packages/SystemUI/src/com/android/systemui/tuner/PowerMenuFragment.java new file mode 100644 index 00000000000..c33b9df87cc --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/tuner/PowerMenuFragment.java @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ + +package com.android.systemui.tuner; + +import android.os.Bundle; + +import androidx.preference.PreferenceFragment; + +import com.android.systemui.R; + +public class PowerMenuFragment extends PreferenceFragment { + @Override + public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { + addPreferencesFromResource(R.xml.power_menu_settings); + } +} From 0765db2de35b47f4162d3489feb7313f742f59d8 Mon Sep 17 00:00:00 2001 From: Dalingrin Date: Thu, 12 Dec 2013 03:19:48 -0600 Subject: [PATCH 112/240] SystemUI: Add double-tap status bar to sleep Adin's edit: format to follow AOSP Java Code Style Change-Id: I4c54718e8ec8774677d13917b3a7ffa3b4b18cb5 --- core/java/android/provider/Settings.java | 13 +++ .../phone/NotificationPanelView.java | 77 +++++++++++++++++ .../statusbar/phone/StatusBarWindowView.java | 82 ++++++++++++++++++- 3 files changed, 171 insertions(+), 1 deletion(-) diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index a64c1211ce8..81c75996e65 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -4489,6 +4489,16 @@ public boolean validate(@Nullable String value) { /** @hide */ private static final Validator ADVANCED_REBOOT_VALIDATOR = BOOLEAN_VALIDATOR; + /** + * Enable statusbar double tap gesture on to put device to sleep + * @hide + */ + public static final String DOUBLE_TAP_SLEEP_GESTURE = "double_tap_sleep_gesture"; + + /** @hide */ + private static final Validator DOUBLE_TAP_SLEEP_GESTURE_VALIDATOR = + BOOLEAN_VALIDATOR; + /** * Settings to backup. This is here so that it's in the same place as the settings * keys and easy to update. @@ -4555,6 +4565,7 @@ public boolean validate(@Nullable String value) { ALARM_ALERT, NOTIFICATION_LIGHT_PULSE, ADVANCED_REBOOT, + DOUBLE_TAP_SLEEP_GESTURE, }; /** @@ -4675,6 +4686,7 @@ public boolean validate(@Nullable String value) { PRIVATE_SETTINGS.add(SHOW_BATTERY_PERCENT); PRIVATE_SETTINGS.add(DISPLAY_COLOR_MODE); PRIVATE_SETTINGS.add(ADVANCED_REBOOT); + PRIVATE_SETTINGS.add(DOUBLE_TAP_SLEEP_GESTURE); } /** @@ -4769,6 +4781,7 @@ public boolean validate(@Nullable String value) { VALIDATORS.put(SHOW_BATTERY_PERCENT, SHOW_BATTERY_PERCENT_VALIDATOR); VALIDATORS.put(NOTIFICATION_LIGHT_PULSE, BOOLEAN_VALIDATOR); VALIDATORS.put(ADVANCED_REBOOT, ADVANCED_REBOOT_VALIDATOR); + VALIDATORS.put(DOUBLE_TAP_SLEEP_GESTURE, DOUBLE_TAP_SLEEP_GESTURE_VALIDATOR); } /** 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 219750eb068..dd9b07e5c45 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java @@ -27,10 +27,12 @@ import android.app.ActivityManager; import android.app.Fragment; import android.app.StatusBarManager; +import android.content.ContentResolver; import android.content.Context; import android.content.pm.ResolveInfo; import android.content.res.Configuration; import android.content.res.Resources; +import android.database.ContentObserver; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; @@ -40,11 +42,15 @@ import android.graphics.Rect; import android.graphics.Region; import android.hardware.biometrics.BiometricSourceType; +import android.net.Uri; +import android.os.Handler; import android.os.PowerManager; import android.os.SystemClock; +import android.provider.Settings; import android.util.AttributeSet; import android.util.Log; import android.util.MathUtils; +import android.view.GestureDetector; import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.VelocityTracker; @@ -438,6 +444,13 @@ public void onAnimationEnd(Animator animation) { */ private boolean mDelayShowingKeyguardStatusBar; + private Handler mHandler = new Handler(); + private SettingsObserver mSettingsObserver; + + private boolean mDoubleTapToSleepEnabled; + private int mStatusBarHeaderHeight; + private GestureDetector mDoubleTapGesture; + @Inject public NotificationPanelView(@Named(VIEW_CONTEXT) Context context, AttributeSet attrs, InjectionInflationController injectionInflationController, @@ -478,6 +491,18 @@ public NotificationPanelView(@Named(VIEW_CONTEXT) Context context, AttributeSet }); mBottomAreaShadeAlphaAnimator.setDuration(160); mBottomAreaShadeAlphaAnimator.setInterpolator(Interpolators.ALPHA_OUT); + + mSettingsObserver = new SettingsObserver(mHandler); + mDoubleTapGesture = new GestureDetector(mContext, new GestureDetector.SimpleOnGestureListener() { + @Override + public boolean onDoubleTap(MotionEvent e) { + PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE); + if (pm != null) { + pm.goToSleep(e.getEventTime()); + } + return true; + } + }); } /** @@ -585,6 +610,7 @@ protected void loadDimens() { com.android.internal.R.dimen.status_bar_height); mHeadsUpInset = statusbarHeight + getResources().getDimensionPixelSize( R.dimen.heads_up_status_bar_padding); + mStatusBarHeaderHeight = getResources().getDimensionPixelSize(R.dimen.status_bar_height); } /** @@ -768,6 +794,16 @@ private void setIsFullWidth(boolean isFullWidth) { mNotificationStackScroller.setIsFullWidth(isFullWidth); } + @Override + public void onAttachedToWindow() { + mSettingsObserver.observe(); + } + + @Override + public void onDetachedFromWindow() { + mSettingsObserver.unobserve(); + } + private void startQsSizeChangeAnimation(int oldHeight, final int newHeight) { if (mQsSizeChangeAnimator != null) { oldHeight = (int) mQsSizeChangeAnimator.getAnimatedValue(); @@ -1241,6 +1277,13 @@ public boolean onTouchEvent(MotionEvent event) { if (mLastEventSynthesizedDown && event.getAction() == MotionEvent.ACTION_UP) { expand(true /* animate */); } + + if (mDoubleTapToSleepEnabled + && mBarState == StatusBarState.KEYGUARD + && event.getY() < mStatusBarHeaderHeight) { + mDoubleTapGesture.onTouchEvent(event); + } + initDownStates(event); if (!mIsExpanding && !shouldQuickSettingsIntercept(mDownX, mDownY, 0) && mPulseExpansionHandler.onTouchEvent(event)) { @@ -3191,6 +3234,40 @@ private void setGroupManager(NotificationGroupManager groupManager) { mGroupManager = groupManager; } + class SettingsObserver extends ContentObserver { + SettingsObserver(Handler handler) { + super(handler); + } + + void observe() { + ContentResolver resolver = mContext.getContentResolver(); + resolver.registerContentObserver(Settings.System.getUriFor( + Settings.System.DOUBLE_TAP_SLEEP_GESTURE), false, this); + update(); + } + + void unobserve() { + ContentResolver resolver = mContext.getContentResolver(); + resolver.unregisterContentObserver(this); + } + + @Override + public void onChange(boolean selfChange) { + update(); + } + + @Override + public void onChange(boolean selfChange, Uri uri) { + update(); + } + + public void update() { + ContentResolver resolver = mContext.getContentResolver(); + mDoubleTapToSleepEnabled = Settings.System.getInt( + resolver, Settings.System.DOUBLE_TAP_SLEEP_GESTURE, 0) == 1; + } + } + public boolean hideStatusBarIconsWhenExpanded() { if (mLaunchingNotification) { return mHideIconsDuringNotificationLaunch; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java index 6789930ab76..a5011baf898 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java @@ -20,9 +20,11 @@ import android.annotation.DrawableRes; import android.annotation.LayoutRes; import android.app.StatusBarManager; +import android.content.ContentResolver; import android.content.Context; import android.content.res.Configuration; import android.content.res.TypedArray; +import android.database.ContentObserver; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.PorterDuff; @@ -34,15 +36,22 @@ import android.media.session.MediaSessionLegacyHelper; import android.net.Uri; import android.os.Bundle; +import android.os.Handler; +import android.os.IPowerManager; +import android.os.PowerManager; +import android.os.RemoteException; +import android.os.ServiceManager; import android.os.SystemClock; import android.os.UserHandle; import android.provider.Settings; import android.util.AttributeSet; +import android.util.Log; import android.view.ActionMode; import android.view.DisplayCutout; import android.view.GestureDetector; import android.view.InputDevice; import android.view.InputQueue; +import android.view.GestureDetector; import android.view.KeyEvent; import android.view.LayoutInflater; import android.view.Menu; @@ -50,6 +59,7 @@ import android.view.MotionEvent; import android.view.SurfaceHolder; import android.view.View; +import android.view.ViewConfiguration; import android.view.ViewGroup; import android.view.ViewTreeObserver; import android.view.Window; @@ -144,6 +154,13 @@ public boolean onDoubleTap(MotionEvent e) { } }; + private int mStatusBarHeaderHeight; + + private boolean mDoubleTapToSleepEnabled; + private GestureDetector mDoubleTapGesture; + private Handler mHandler = new Handler(); + private SettingsObserver mSettingsObserver; + /** * If set to true, the current gesture started below the notch and we need to dispatch touch * events manually as it's outside of the regular view bounds. @@ -162,6 +179,10 @@ public StatusBarWindowView(Context context, AttributeSet attrs) { Dependency.get(TunerService.class).addTunable(mTunable, Settings.Secure.DOZE_DOUBLE_TAP_GESTURE, Settings.Secure.DOZE_TAP_SCREEN_GESTURE); + + mStatusBarHeaderHeight = context + .getResources().getDimensionPixelSize(R.dimen.status_bar_height); + mSettingsObserver = new SettingsObserver(mHandler); } @Override @@ -301,9 +322,31 @@ void setDragDownHelper(DragDownHelper dragDownHelper) { @Override protected void onAttachedToWindow () { super.onAttachedToWindow(); + + mSettingsObserver.observe(); + mDoubleTapGesture = new GestureDetector(mContext, new GestureDetector.SimpleOnGestureListener() { + @Override + public boolean onDoubleTap(MotionEvent e) { + PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE); + Log.d(TAG, "Gesture!!"); + if (pm != null) { + pm.goToSleep(e.getEventTime()); + } else { + Log.d(TAG, "getSystemService returned null PowerManager"); + } + return true; + } + }); + setWillNotDraw(!DEBUG); } + @Override + protected void onDetachedFromWindow() { + super.onDetachedFromWindow(); + mSettingsObserver.unobserve(); + } + @Override public boolean dispatchKeyEvent(KeyEvent event) { if (mService.interceptMediaKey(event)) { @@ -416,6 +459,11 @@ public boolean onInterceptTouchEvent(MotionEvent ev) { return true; } boolean intercept = false; + if (mDoubleTapToSleepEnabled + && ev.getY() < mStatusBarHeaderHeight) { + if (DEBUG) Log.w(TAG, "logging double tap gesture"); + mDoubleTapGesture.onTouchEvent(ev); + } if (mNotificationPanel.isFullyExpanded() && mDragDownHelper.isDragDownEnabled() && !mService.isBouncerShowing() @@ -890,5 +938,37 @@ public WindowInsetsController getInsetsController() { } }; -} + class SettingsObserver extends ContentObserver { + SettingsObserver(Handler handler) { + super(handler); + } + + void observe() { + ContentResolver resolver = mContext.getContentResolver(); + resolver.registerContentObserver(Settings.System.getUriFor( + Settings.System.DOUBLE_TAP_SLEEP_GESTURE), false, this); + update(); + } + + void unobserve() { + ContentResolver resolver = mContext.getContentResolver(); + resolver.unregisterContentObserver(this); + } + + @Override + public void onChange(boolean selfChange) { + update(); + } + + @Override + public void onChange(boolean selfChange, Uri uri) { + update(); + } + public void update() { + ContentResolver resolver = mContext.getContentResolver(); + mDoubleTapToSleepEnabled = Settings.System.getInt( + resolver, Settings.System.DOUBLE_TAP_SLEEP_GESTURE, 0) == 1; + } + } +} From 994c2205d5fee018cefd0305508c5d3b0971a19e Mon Sep 17 00:00:00 2001 From: Ritesh Saxena Date: Sun, 27 Oct 2019 12:07:51 +0000 Subject: [PATCH 113/240] tuner: Add tunable for double tap to sleep on statusbar Change-Id: I6a6fd11ce46d95505484d7bd3e36002e3f0d34d6 --- packages/SystemUI/res/values/reloaded_strings.xml | 4 ++++ packages/SystemUI/res/xml/statusbar_settings.xml | 6 ++++++ 2 files changed, 10 insertions(+) diff --git a/packages/SystemUI/res/values/reloaded_strings.xml b/packages/SystemUI/res/values/reloaded_strings.xml index 180f05a2827..2ac87ec9acb 100644 --- a/packages/SystemUI/res/values/reloaded_strings.xml +++ b/packages/SystemUI/res/values/reloaded_strings.xml @@ -35,4 +35,8 @@ Advanced restart Show recovery and bootloader restart options + + Double-tap to sleep + Double tap on the status bar to put the device to sleep + diff --git a/packages/SystemUI/res/xml/statusbar_settings.xml b/packages/SystemUI/res/xml/statusbar_settings.xml index 2006946caf5..3a864d0d3bc 100644 --- a/packages/SystemUI/res/xml/statusbar_settings.xml +++ b/packages/SystemUI/res/xml/statusbar_settings.xml @@ -91,4 +91,10 @@ + + From fd6cf3a2cbc883df84ed2cea691fcdcfc8f726f9 Mon Sep 17 00:00:00 2001 From: Altaf-Mahdi Date: Thu, 4 Feb 2016 15:53:42 +0100 Subject: [PATCH 114/240] SystemUI: Add double-tap lock screen to sleep Adin's edit: format to follow AOSP Java Code Style Change-Id: I71ee648e6268ff80e83e3c46abb189a90235248e --- core/java/android/provider/Settings.java | 14 +++++++++++ .../phone/NotificationPanelView.java | 23 +++++++++---------- 2 files changed, 25 insertions(+), 12 deletions(-) diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index 81c75996e65..cca341cc21d 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -4499,6 +4499,17 @@ public boolean validate(@Nullable String value) { private static final Validator DOUBLE_TAP_SLEEP_GESTURE_VALIDATOR = BOOLEAN_VALIDATOR; + /** + * Double tap on lockscreen to sleep + * @hide + */ + public static final String DOUBLE_TAP_SLEEP_LOCKSCREEN = + "double_tap_sleep_lockscreen"; + + /** @hide */ + private static final Validator DOUBLE_TAP_SLEEP_LOCKSCREEN_VALIDATOR = + BOOLEAN_VALIDATOR; + /** * Settings to backup. This is here so that it's in the same place as the settings * keys and easy to update. @@ -4566,6 +4577,7 @@ public boolean validate(@Nullable String value) { NOTIFICATION_LIGHT_PULSE, ADVANCED_REBOOT, DOUBLE_TAP_SLEEP_GESTURE, + DOUBLE_TAP_SLEEP_LOCKSCREEN, }; /** @@ -4687,6 +4699,7 @@ public boolean validate(@Nullable String value) { PRIVATE_SETTINGS.add(DISPLAY_COLOR_MODE); PRIVATE_SETTINGS.add(ADVANCED_REBOOT); PRIVATE_SETTINGS.add(DOUBLE_TAP_SLEEP_GESTURE); + PRIVATE_SETTINGS.add(DOUBLE_TAP_SLEEP_LOCKSCREEN); } /** @@ -4782,6 +4795,7 @@ public boolean validate(@Nullable String value) { VALIDATORS.put(NOTIFICATION_LIGHT_PULSE, BOOLEAN_VALIDATOR); VALIDATORS.put(ADVANCED_REBOOT, ADVANCED_REBOOT_VALIDATOR); VALIDATORS.put(DOUBLE_TAP_SLEEP_GESTURE, DOUBLE_TAP_SLEEP_GESTURE_VALIDATOR); + VALIDATORS.put(DOUBLE_TAP_SLEEP_LOCKSCREEN, DOUBLE_TAP_SLEEP_LOCKSCREEN_VALIDATOR); } /** 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 dd9b07e5c45..b946c16eae0 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java @@ -448,6 +448,7 @@ public void onAnimationEnd(Animator animation) { private SettingsObserver mSettingsObserver; private boolean mDoubleTapToSleepEnabled; + private boolean mDoubleTapToSleepLockscreen; private int mStatusBarHeaderHeight; private GestureDetector mDoubleTapGesture; @@ -570,6 +571,7 @@ protected void onAttachedToWindow() { // Theme might have changed between inflating this view and attaching it to the window, so // force a call to onThemeChanged onThemeChanged(); + mSettingsObserver.observe(); } @Override @@ -580,6 +582,7 @@ protected void onDetachedFromWindow() { Dependency.get(ZenModeController.class).removeCallback(this); Dependency.get(ConfigurationController.class).removeCallback(this); mUpdateMonitor.removeCallback(mKeyguardUpdateCallback); + mSettingsObserver.unobserve(); } @Override @@ -794,16 +797,6 @@ private void setIsFullWidth(boolean isFullWidth) { mNotificationStackScroller.setIsFullWidth(isFullWidth); } - @Override - public void onAttachedToWindow() { - mSettingsObserver.observe(); - } - - @Override - public void onDetachedFromWindow() { - mSettingsObserver.unobserve(); - } - private void startQsSizeChangeAnimation(int oldHeight, final int newHeight) { if (mQsSizeChangeAnimator != null) { oldHeight = (int) mQsSizeChangeAnimator.getAnimatedValue(); @@ -1278,9 +1271,11 @@ public boolean onTouchEvent(MotionEvent event) { expand(true /* animate */); } - if (mDoubleTapToSleepEnabled + if ((mDoubleTapToSleepEnabled && mBarState == StatusBarState.KEYGUARD - && event.getY() < mStatusBarHeaderHeight) { + && event.getY() < mStatusBarHeaderHeight) + || (mDoubleTapToSleepLockscreen + && mBarState == StatusBarState.KEYGUARD)) { mDoubleTapGesture.onTouchEvent(event); } @@ -3243,6 +3238,8 @@ void observe() { ContentResolver resolver = mContext.getContentResolver(); resolver.registerContentObserver(Settings.System.getUriFor( Settings.System.DOUBLE_TAP_SLEEP_GESTURE), false, this); + resolver.registerContentObserver(Settings.System.getUriFor( + Settings.System.DOUBLE_TAP_SLEEP_LOCKSCREEN), false, this); update(); } @@ -3265,6 +3262,8 @@ public void update() { ContentResolver resolver = mContext.getContentResolver(); mDoubleTapToSleepEnabled = Settings.System.getInt( resolver, Settings.System.DOUBLE_TAP_SLEEP_GESTURE, 0) == 1; + mDoubleTapToSleepLockscreen = Settings.System.getInt( + resolver, Settings.System.DOUBLE_TAP_SLEEP_LOCKSCREEN, 0) == 1; } } From 3b550321176a25d3bc780c890bf817a79ce82741 Mon Sep 17 00:00:00 2001 From: Ritesh Saxena Date: Sun, 27 Oct 2019 12:24:14 +0000 Subject: [PATCH 115/240] tuner: Add tunable for double tap to sleep on lockscreen Change-Id: I9c6fed523e66353edf408b4b3fd1b2d1671729e0 --- packages/SystemUI/res/values/reloaded_strings.xml | 2 ++ packages/SystemUI/res/xml/lockscreen_settings.xml | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/packages/SystemUI/res/values/reloaded_strings.xml b/packages/SystemUI/res/values/reloaded_strings.xml index 2ac87ec9acb..99549bb87b3 100644 --- a/packages/SystemUI/res/values/reloaded_strings.xml +++ b/packages/SystemUI/res/values/reloaded_strings.xml @@ -38,5 +38,7 @@ Double-tap to sleep Double tap on the status bar to put the device to sleep + Double tap to sleep + Double tap anywhere on the lock screen to put the device to sleep diff --git a/packages/SystemUI/res/xml/lockscreen_settings.xml b/packages/SystemUI/res/xml/lockscreen_settings.xml index 1e7d266cc5c..33e8e0f5bb6 100644 --- a/packages/SystemUI/res/xml/lockscreen_settings.xml +++ b/packages/SystemUI/res/xml/lockscreen_settings.xml @@ -39,4 +39,10 @@ android:title="@string/lockscreen_unlock_right" sysui:defValue="true" /> + + From 5793d1dc180d52e5d71b51dedbd89daeda2d2b33 Mon Sep 17 00:00:00 2001 From: maxwen Date: Sun, 21 Jan 2018 02:06:31 +0100 Subject: [PATCH 116/240] SystemUI: Prevent dummy expansion of status bar qs panel gets expanded on double-tap on status bar before screen is turned off. So stop all events once a double-tap is detected. Change-Id: Idd75ae5a9abefecb2b98c9020a34d3065e645018 Signed-off-by: Adin Kwok --- .../systemui/statusbar/phone/NotificationPanelView.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) 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 b946c16eae0..5adf06d4ce4 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java @@ -1276,7 +1276,9 @@ public boolean onTouchEvent(MotionEvent event) { && event.getY() < mStatusBarHeaderHeight) || (mDoubleTapToSleepLockscreen && mBarState == StatusBarState.KEYGUARD)) { - mDoubleTapGesture.onTouchEvent(event); + if (mDoubleTapGesture.onTouchEvent(event)) { + return false; + } } initDownStates(event); From bf3f7b6b1747063b2f6bd992d1f21c318601450b Mon Sep 17 00:00:00 2001 From: maxwen Date: Sun, 29 Mar 2015 18:39:55 +0200 Subject: [PATCH 117/240] base: allow disable of screenshot shutter sound [1/2] Change-Id: I47d52bba21170118af87d35376d81d7569587a2f --- core/java/android/provider/Settings.java | 13 +++++++++++++ .../systemui/screenshot/GlobalScreenshot.java | 8 ++++++-- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index cca341cc21d..468036b4896 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -4509,6 +4509,16 @@ public boolean validate(@Nullable String value) { /** @hide */ private static final Validator DOUBLE_TAP_SLEEP_LOCKSCREEN_VALIDATOR = BOOLEAN_VALIDATOR; + + /** + * Disable Screenshot shutter sound + * @hide + */ + public static final String SCREENSHOT_SHUTTER_SOUND = "screenshot_shutter_sound"; + + /** @hide */ + private static final Validator SCREENSHOT_SHUTTER_SOUND_VALIDATOR = + BOOLEAN_VALIDATOR; /** * Settings to backup. This is here so that it's in the same place as the settings @@ -4578,6 +4588,7 @@ public boolean validate(@Nullable String value) { ADVANCED_REBOOT, DOUBLE_TAP_SLEEP_GESTURE, DOUBLE_TAP_SLEEP_LOCKSCREEN, + SCREENSHOT_SHUTTER_SOUND, }; /** @@ -4700,6 +4711,7 @@ public boolean validate(@Nullable String value) { PRIVATE_SETTINGS.add(ADVANCED_REBOOT); PRIVATE_SETTINGS.add(DOUBLE_TAP_SLEEP_GESTURE); PRIVATE_SETTINGS.add(DOUBLE_TAP_SLEEP_LOCKSCREEN); + PRIVATE_SETTINGS.add(SCREENSHOT_SHUTTER_SOUND); } /** @@ -4796,6 +4808,7 @@ public boolean validate(@Nullable String value) { VALIDATORS.put(ADVANCED_REBOOT, ADVANCED_REBOOT_VALIDATOR); VALIDATORS.put(DOUBLE_TAP_SLEEP_GESTURE, DOUBLE_TAP_SLEEP_GESTURE_VALIDATOR); VALIDATORS.put(DOUBLE_TAP_SLEEP_LOCKSCREEN, DOUBLE_TAP_SLEEP_LOCKSCREEN_VALIDATOR); + VALIDATORS.put(SCREENSHOT_SHUTTER_SOUND, SCREENSHOT_SHUTTER_SOUND_VALIDATOR); } /** diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java index 11ca94f6f4e..44b73ddca5d 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java +++ b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java @@ -63,6 +63,7 @@ import android.os.Process; import android.os.UserHandle; import android.provider.MediaStore; +import android.provider.Settings; import android.text.TextUtils; import android.util.DisplayMetrics; import android.util.Slog; @@ -719,8 +720,11 @@ public void onAnimationEnd(Animator animation) { mScreenshotLayout.post(new Runnable() { @Override public void run() { - // Play the shutter sound to notify that we've taken a screenshot - mCameraSound.play(MediaActionSound.SHUTTER_CLICK); + if (Settings.System.getInt(mContext.getContentResolver(), + Settings.System.SCREENSHOT_SHUTTER_SOUND, 1) == 1) { + // Play the shutter sound to notify that we've taken a screenshot + mCameraSound.play(MediaActionSound.SHUTTER_CLICK); + } mScreenshotView.setLayerType(View.LAYER_TYPE_HARDWARE, null); mScreenshotView.buildLayer(); From b9f69ec9fd53a400d0a1d0a0c1154f8a2fced537 Mon Sep 17 00:00:00 2001 From: Ritesh Saxena Date: Sun, 27 Oct 2019 08:26:09 +0000 Subject: [PATCH 118/240] tuner: Add intent to lockscreen clock customizatons Change-Id: Ib2ba7e68219423ad46cf590c7eba6e4e62fa4a67 --- .../SystemUI/res/values/reloaded_strings.xml | 3 +++ .../SystemUI/res/xml/lockscreen_settings.xml | 3 +++ .../systemui/tuner/LockscreenFragment.java | 22 +++++++++++++++++++ 3 files changed, 28 insertions(+) diff --git a/packages/SystemUI/res/values/reloaded_strings.xml b/packages/SystemUI/res/values/reloaded_strings.xml index 99549bb87b3..4c11a3f5da2 100644 --- a/packages/SystemUI/res/values/reloaded_strings.xml +++ b/packages/SystemUI/res/values/reloaded_strings.xml @@ -41,4 +41,7 @@ Double tap to sleep Double tap anywhere on the lock screen to put the device to sleep + + Lockscreen clock + diff --git a/packages/SystemUI/res/xml/lockscreen_settings.xml b/packages/SystemUI/res/xml/lockscreen_settings.xml index 33e8e0f5bb6..dfce8276c33 100644 --- a/packages/SystemUI/res/xml/lockscreen_settings.xml +++ b/packages/SystemUI/res/xml/lockscreen_settings.xml @@ -18,6 +18,9 @@ xmlns:sysui="http://schemas.android.com/apk/res-auto" android:title="@string/other"> + Date: Mon, 19 Jun 2017 17:13:49 +0200 Subject: [PATCH 119/240] base: config to disable power menu on secure lock screen Change-Id: Ie3f0b7c29fec17f1f392f95b46733494ac5466f9 --- core/java/android/provider/Settings.java | 10 +++++ .../server/policy/PhoneWindowManager.java | 38 +++++++++++++------ 2 files changed, 36 insertions(+), 12 deletions(-) diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index 468036b4896..8e9b3e8975c 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -4520,6 +4520,13 @@ public boolean validate(@Nullable String value) { private static final Validator SCREENSHOT_SHUTTER_SOUND_VALIDATOR = BOOLEAN_VALIDATOR; + /** @hide */ + public static final String LOCK_POWER_MENU_DISABLED = "lockscreen_power_menu_disabled"; + + /** @hide */ + private static final Validator LOCK_POWER_MENU_DISABLED_VALIDATOR = + BOOLEAN_VALIDATOR; + /** * Settings to backup. This is here so that it's in the same place as the settings * keys and easy to update. @@ -4589,6 +4596,7 @@ public boolean validate(@Nullable String value) { DOUBLE_TAP_SLEEP_GESTURE, DOUBLE_TAP_SLEEP_LOCKSCREEN, SCREENSHOT_SHUTTER_SOUND, + LOCK_POWER_MENU_DISABLED, }; /** @@ -4712,6 +4720,7 @@ public boolean validate(@Nullable String value) { PRIVATE_SETTINGS.add(DOUBLE_TAP_SLEEP_GESTURE); PRIVATE_SETTINGS.add(DOUBLE_TAP_SLEEP_LOCKSCREEN); PRIVATE_SETTINGS.add(SCREENSHOT_SHUTTER_SOUND); + PRIVATE_SETTINGS.add(LOCK_POWER_MENU_DISABLED); } /** @@ -4809,6 +4818,7 @@ public boolean validate(@Nullable String value) { VALIDATORS.put(DOUBLE_TAP_SLEEP_GESTURE, DOUBLE_TAP_SLEEP_GESTURE_VALIDATOR); VALIDATORS.put(DOUBLE_TAP_SLEEP_LOCKSCREEN, DOUBLE_TAP_SLEEP_LOCKSCREEN_VALIDATOR); VALIDATORS.put(SCREENSHOT_SHUTTER_SOUND, SCREENSHOT_SHUTTER_SOUND_VALIDATOR); + VALIDATORS.put(LOCK_POWER_MENU_DISABLED, LOCK_POWER_MENU_DISABLED_VALIDATOR); } /** diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java index 4572d3ede06..c5d95f32f90 100644 --- a/services/core/java/com/android/server/policy/PhoneWindowManager.java +++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java @@ -652,6 +652,9 @@ public void onDrawn() { private static final int MSG_RINGER_TOGGLE_CHORD = 27; private static final int MSG_MOVE_DISPLAY_TO_TOP = 28; + // Global actions on lockk screen + private boolean mGlobalActionsOnLockDisable; + private class PolicyHandler extends Handler { @Override public void handleMessage(Message msg) { @@ -666,7 +669,7 @@ public void handleMessage(Message msg) { showRecentApps(false); break; case MSG_DISPATCH_SHOW_GLOBAL_ACTIONS: - showGlobalActionsInternal(); + showGlobalActionsInternal(false); break; case MSG_KEYGUARD_DRAWN_COMPLETE: if (DEBUG_WAKEUP) Slog.w(TAG, "Setting mKeyguardDrawComplete"); @@ -805,6 +808,8 @@ void observe() { resolver.registerContentObserver(Settings.Global.getUriFor( Settings.Global.POWER_BUTTON_SUPPRESSION_DELAY_AFTER_GESTURE_WAKE), false, this, UserHandle.USER_ALL); + resolver.registerContentObserver(Settings.System.getUriFor( + Settings.System.LOCK_POWER_MENU_DISABLED), false, this); updateSettings(); } @@ -1263,9 +1268,7 @@ private void powerLongPress() { break; case LONG_PRESS_POWER_GLOBAL_ACTIONS: mPowerKeyHandled = true; - performHapticFeedback(HapticFeedbackConstants.LONG_PRESS, false, - "Power - Long Press - Global Actions"); - showGlobalActionsInternal(); + showGlobalActionsInternal(true); break; case LONG_PRESS_POWER_SHUT_OFF: case LONG_PRESS_POWER_SHUT_OFF_NO_CONFIRM: @@ -1300,9 +1303,7 @@ private void powerVeryLongPress() { break; case VERY_LONG_PRESS_POWER_GLOBAL_ACTIONS: mPowerKeyHandled = true; - performHapticFeedback(HapticFeedbackConstants.LONG_PRESS, false, - "Power - Very Long Press - Show Global Actions"); - showGlobalActionsInternal(); + showGlobalActionsInternal(true); break; } } @@ -1445,9 +1446,7 @@ private void cancelPendingRingerToggleChordAction() { @Override public void run() { mEndCallKeyHandled = true; - performHapticFeedback(HapticFeedbackConstants.LONG_PRESS, false, - "End Call - Long Press - Show Global Actions"); - showGlobalActionsInternal(); + showGlobalActionsInternal(true); } }; @@ -1472,11 +1471,18 @@ public void showGlobalActions() { mHandler.sendEmptyMessage(MSG_DISPATCH_SHOW_GLOBAL_ACTIONS); } - void showGlobalActionsInternal() { + void showGlobalActionsInternal(boolean hapticFeedback) { + final boolean keyguardShowing = isKeyguardShowingAndNotOccluded(); + if (keyguardShowing && !isGlobalActionEnabled()) { + return; + } + if (hapticFeedback) { + performHapticFeedback(HapticFeedbackConstants.LONG_PRESS, false, + "Power - Very Long Press - Show Global Actions"); + } if (mGlobalActions == null) { mGlobalActions = new GlobalActions(mContext, mWindowManagerFuncs); } - final boolean keyguardShowing = isKeyguardShowingAndNotOccluded(); mGlobalActions.showDialog(keyguardShowing, isDeviceProvisioned()); // since it took two seconds of long press to bring this up, // poke the wake lock so they have some time to see the dialog. @@ -2093,6 +2099,8 @@ public void updateSettings() { Settings.Global.POWER_BUTTON_VERY_LONG_PRESS, mContext.getResources().getInteger( com.android.internal.R.integer.config_veryLongPressOnPowerBehavior)); + mGlobalActionsOnLockDisable = Settings.System.getInt(resolver, + Settings.System.LOCK_POWER_MENU_DISABLED, 0) != 0; } if (updateRotation) { updateRotation(true); @@ -5825,4 +5833,10 @@ public Boolean parseState(ExtconInfo extconIfno, String state) { } } + private boolean isGlobalActionEnabled() { + if (isKeyguardSecure(mCurrentUserId) && mGlobalActionsOnLockDisable) { + return false; + } + return true; + } } From 5d270115423d912600c8d36a45c5d9e6ce2210e2 Mon Sep 17 00:00:00 2001 From: Ritesh Saxena Date: Sun, 27 Oct 2019 11:30:17 +0000 Subject: [PATCH 120/240] tuner: Add toggle to disable power menu on secure lock screen Change-Id: I2ae1b14f080271ce09e34369f2daf3bd4a1d9f1c --- packages/SystemUI/res/values/reloaded_strings.xml | 4 +++- packages/SystemUI/res/xml/power_menu_settings.xml | 6 ++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/packages/SystemUI/res/values/reloaded_strings.xml b/packages/SystemUI/res/values/reloaded_strings.xml index 4c11a3f5da2..ecc2b2001c5 100644 --- a/packages/SystemUI/res/values/reloaded_strings.xml +++ b/packages/SystemUI/res/values/reloaded_strings.xml @@ -41,7 +41,9 @@ Double tap to sleep Double tap anywhere on the lock screen to put the device to sleep - + Lockscreen clock + Disable power menu when locked + Disable power menu on secure lock screens diff --git a/packages/SystemUI/res/xml/power_menu_settings.xml b/packages/SystemUI/res/xml/power_menu_settings.xml index bd2b8376fc9..f4df9701fe1 100644 --- a/packages/SystemUI/res/xml/power_menu_settings.xml +++ b/packages/SystemUI/res/xml/power_menu_settings.xml @@ -24,4 +24,10 @@ android:summary="@string/global_actions_advanced_reboot_summary" android:defaultValue="false" /> + + From 862830ad64cefd9ad80d38d84ad3f5df7998b838 Mon Sep 17 00:00:00 2001 From: beanstown106 Date: Thu, 14 Jan 2016 05:56:50 -0500 Subject: [PATCH 121/240] base: Fingerprint authentication vibration had a few requests for this, as most devices only vibrate when fingerprint authentication is unsucesful so made it configurable Change-Id: Ie1c0f5276e034b58b4f148d661f5c20e667f6866 --- core/java/android/provider/Settings.java | 14 ++++++++++++++ .../android/server/biometrics/ClientMonitor.java | 5 ++++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index 8e9b3e8975c..51112411cfe 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -4527,6 +4527,17 @@ public boolean validate(@Nullable String value) { private static final Validator LOCK_POWER_MENU_DISABLED_VALIDATOR = BOOLEAN_VALIDATOR; + /** + * whether to enable or disable vibration on succesful fingerprint auth + * + * @hide + */ + public static final String FINGERPRINT_SUCCESS_VIB = "fingerprint_success_vib"; + + /** @hide */ + private static final Validator FINGERPRINT_SUCCESS_VIB_VALIDATOR = + BOOLEAN_VALIDATOR; + /** * Settings to backup. This is here so that it's in the same place as the settings * keys and easy to update. @@ -4597,6 +4608,7 @@ public boolean validate(@Nullable String value) { DOUBLE_TAP_SLEEP_LOCKSCREEN, SCREENSHOT_SHUTTER_SOUND, LOCK_POWER_MENU_DISABLED, + FINGERPRINT_SUCCESS_VIB, }; /** @@ -4721,6 +4733,7 @@ public boolean validate(@Nullable String value) { PRIVATE_SETTINGS.add(DOUBLE_TAP_SLEEP_LOCKSCREEN); PRIVATE_SETTINGS.add(SCREENSHOT_SHUTTER_SOUND); PRIVATE_SETTINGS.add(LOCK_POWER_MENU_DISABLED); + PRIVATE_SETTINGS.add(FINGERPRINT_SUCCESS_VIB); } /** @@ -4819,6 +4832,7 @@ public boolean validate(@Nullable String value) { VALIDATORS.put(DOUBLE_TAP_SLEEP_LOCKSCREEN, DOUBLE_TAP_SLEEP_LOCKSCREEN_VALIDATOR); VALIDATORS.put(SCREENSHOT_SHUTTER_SOUND, SCREENSHOT_SHUTTER_SOUND_VALIDATOR); VALIDATORS.put(LOCK_POWER_MENU_DISABLED, LOCK_POWER_MENU_DISABLED_VALIDATOR); + VALIDATORS.put(FINGERPRINT_SUCCESS_VIB, FINGERPRINT_SUCCESS_VIB_VALIDATOR); } /** diff --git a/services/core/java/com/android/server/biometrics/ClientMonitor.java b/services/core/java/com/android/server/biometrics/ClientMonitor.java index 942e0501d88..34631a59645 100644 --- a/services/core/java/com/android/server/biometrics/ClientMonitor.java +++ b/services/core/java/com/android/server/biometrics/ClientMonitor.java @@ -24,6 +24,7 @@ import android.os.RemoteException; import android.os.VibrationEffect; import android.os.Vibrator; +import android.provider.Settings; import android.util.Slog; import com.android.internal.logging.MetricsLogger; @@ -291,7 +292,9 @@ public final IBinder getToken() { public final void vibrateSuccess() { Vibrator vibrator = mContext.getSystemService(Vibrator.class); - if (vibrator != null) { + boolean FingerprintVib = Settings.System.getInt(mContext.getContentResolver(), + Settings.System.FINGERPRINT_SUCCESS_VIB, 1) == 1; + if (vibrator != null && FingerprintVib) { vibrator.vibrate(mSuccessVibrationEffect, FINGERPRINT_SONFICATION_ATTRIBUTES); } } From 283f0d3bc1324b3f337c1606ab70d5509b7965fa Mon Sep 17 00:00:00 2001 From: Ritesh Saxena Date: Sun, 27 Oct 2019 12:59:34 +0000 Subject: [PATCH 122/240] tuner: Add tunables for fingerprint authentication vibration Change-Id: I23ef821d3720252fcb7bc455db8d07b3e3aebeb7 --- packages/SystemUI/res/values/reloaded_strings.xml | 4 ++++ packages/SystemUI/res/xml/lockscreen_settings.xml | 6 ++++++ 2 files changed, 10 insertions(+) diff --git a/packages/SystemUI/res/values/reloaded_strings.xml b/packages/SystemUI/res/values/reloaded_strings.xml index ecc2b2001c5..cc16131c527 100644 --- a/packages/SystemUI/res/values/reloaded_strings.xml +++ b/packages/SystemUI/res/values/reloaded_strings.xml @@ -46,4 +46,8 @@ Disable power menu when locked Disable power menu on secure lock screens + + Fingerprint authentication + Vibrate on successful fingerprint authentication + diff --git a/packages/SystemUI/res/xml/lockscreen_settings.xml b/packages/SystemUI/res/xml/lockscreen_settings.xml index dfce8276c33..886dfd342b5 100644 --- a/packages/SystemUI/res/xml/lockscreen_settings.xml +++ b/packages/SystemUI/res/xml/lockscreen_settings.xml @@ -48,4 +48,10 @@ android:summary="@string/double_tap_sleep_lockscreen_summary" android:defaultValue="false" /> + + From d9533f18232e807cd0fc1bf2e9a8321ad03e8dcc Mon Sep 17 00:00:00 2001 From: maxwen Date: Wed, 22 Aug 2018 13:37:12 +0200 Subject: [PATCH 123/240] base: tuner: remove unneeded statusbar tuner switches Change-Id: If3905cac9c42c255bbd66ffa1fea374ee4dfde60 (cherry picked from commit cd45eb192024f4cbb7953c137c4bdd88fd411327) --- packages/SystemUI/res/xml/statusbar_settings.xml | 8 -------- 1 file changed, 8 deletions(-) diff --git a/packages/SystemUI/res/xml/statusbar_settings.xml b/packages/SystemUI/res/xml/statusbar_settings.xml index 3a864d0d3bc..33741a85ddf 100644 --- a/packages/SystemUI/res/xml/statusbar_settings.xml +++ b/packages/SystemUI/res/xml/statusbar_settings.xml @@ -22,18 +22,10 @@ android:key="status_bar" android:title="@string/status_bar_icons" > - - - - From 468fe82cf96ad9621942b369a70862e6dbbfc97b Mon Sep 17 00:00:00 2001 From: maxwen Date: Thu, 25 Jan 2018 00:41:00 +0100 Subject: [PATCH 124/240] base: tuner: bring back tuner navbar editor from N Change-Id: I1b47c354f19b134af0ff39018b843c01864827bb --- .../SystemUI/res/drawable/ic_menu_reset.xml | 9 + .../SystemUI/res/layout/nav_bar_tuner.xml | 28 + .../SystemUI/res/layout/nav_width_view.xml | 3 +- .../SystemUI/res/menu/nav_bar_tuner_menu.xml | 22 + .../SystemUI/res/values/reloaded_strings.xml | 22 + packages/SystemUI/res/xml/nav_bar_tuner.xml | 40 +- .../phone/NavigationBarInflaterView.java | 5 +- .../tuner/KeycodeSelectionHelper.java | 83 +++ .../android/systemui/tuner/NavBarEditor.java | 644 ++++++++++++++++++ 9 files changed, 816 insertions(+), 40 deletions(-) create mode 100644 packages/SystemUI/res/drawable/ic_menu_reset.xml create mode 100644 packages/SystemUI/res/layout/nav_bar_tuner.xml create mode 100644 packages/SystemUI/res/menu/nav_bar_tuner_menu.xml create mode 100644 packages/SystemUI/src/com/android/systemui/tuner/KeycodeSelectionHelper.java create mode 100644 packages/SystemUI/src/com/android/systemui/tuner/NavBarEditor.java diff --git a/packages/SystemUI/res/drawable/ic_menu_reset.xml b/packages/SystemUI/res/drawable/ic_menu_reset.xml new file mode 100644 index 00000000000..38066b8e31b --- /dev/null +++ b/packages/SystemUI/res/drawable/ic_menu_reset.xml @@ -0,0 +1,9 @@ + + + diff --git a/packages/SystemUI/res/layout/nav_bar_tuner.xml b/packages/SystemUI/res/layout/nav_bar_tuner.xml new file mode 100644 index 00000000000..685f4687b18 --- /dev/null +++ b/packages/SystemUI/res/layout/nav_bar_tuner.xml @@ -0,0 +1,28 @@ + + + + + + + diff --git a/packages/SystemUI/res/layout/nav_width_view.xml b/packages/SystemUI/res/layout/nav_width_view.xml index 6a72faf9fbe..227b63b7ef3 100644 --- a/packages/SystemUI/res/layout/nav_width_view.xml +++ b/packages/SystemUI/res/layout/nav_width_view.xml @@ -22,5 +22,4 @@ android:id="@+id/seekbar" android:layout_height="wrap_content" android:layout_width="match_parent" - android:paddingTop="12dp" - android:paddingBottom="4dp" /> + android:padding="16dp" /> diff --git a/packages/SystemUI/res/menu/nav_bar_tuner_menu.xml b/packages/SystemUI/res/menu/nav_bar_tuner_menu.xml new file mode 100644 index 00000000000..a866a5da26c --- /dev/null +++ b/packages/SystemUI/res/menu/nav_bar_tuner_menu.xml @@ -0,0 +1,22 @@ + + + + + + diff --git a/packages/SystemUI/res/values/reloaded_strings.xml b/packages/SystemUI/res/values/reloaded_strings.xml index cc16131c527..286bed5aace 100644 --- a/packages/SystemUI/res/values/reloaded_strings.xml +++ b/packages/SystemUI/res/values/reloaded_strings.xml @@ -50,4 +50,26 @@ Fingerprint authentication Vibrate on successful fingerprint authentication + + Preview + Keycode + No home button found + A home button is required to be able to navigate this device. Please add a home button before saving. + The Clipboard allows items to be dragged directly to the clipboard. Items can also be dragged directly out of the clipboard when present. + Keycode buttons allow keyboard keys to be added to the Navigation Bar. When pressed they emulate the selected keyboard key. First the key must be selected for the button, followed by an image to be shown on the button. + Start + Center + End + Spacer + Menu / Keyboard Switcher + Select button to add + Add button + Save + Reset + Select Keyboard Button + Left + Right + Editor + Configure navigaton bar + diff --git a/packages/SystemUI/res/xml/nav_bar_tuner.xml b/packages/SystemUI/res/xml/nav_bar_tuner.xml index 68e8fad1e24..ca41623573d 100644 --- a/packages/SystemUI/res/xml/nav_bar_tuner.xml +++ b/packages/SystemUI/res/xml/nav_bar_tuner.xml @@ -26,42 +26,10 @@ android:entries="@array/nav_bar_layouts" android:entryValues="@array/nav_bar_layouts_values" /> - - - - - - - - - - + android:key="navbar_editor" + android:title="@string/navbar_editor_title" + android:summary="@string/navbar_editor_summary" + android:fragment="com.android.systemui.tuner.NavBarEditor" /> diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java index 662c744f8c9..7f346cab0d3 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java @@ -73,11 +73,12 @@ public class NavigationBarInflaterView extends FrameLayout public static final String KEY_CODE_START = "("; public static final String KEY_IMAGE_DELIM = ":"; public static final String KEY_CODE_END = ")"; - private static final String WEIGHT_SUFFIX = "W"; - private static final String WEIGHT_CENTERED_SUFFIX = "WC"; private static final String ABSOLUTE_SUFFIX = "A"; private static final String ABSOLUTE_VERTICAL_CENTERED_SUFFIX = "C"; + public static final String WEIGHT_SUFFIX = "W"; + public static final String WEIGHT_CENTERED_SUFFIX = "WC"; + protected LayoutInflater mLayoutInflater; protected LayoutInflater mLandscapeInflater; diff --git a/packages/SystemUI/src/com/android/systemui/tuner/KeycodeSelectionHelper.java b/packages/SystemUI/src/com/android/systemui/tuner/KeycodeSelectionHelper.java new file mode 100644 index 00000000000..096ecc0b8ba --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/tuner/KeycodeSelectionHelper.java @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ + +package com.android.systemui.tuner; + +import android.app.AlertDialog; +import android.content.Context; +import android.content.DialogInterface; +import android.content.Intent; +import android.view.KeyEvent; + +import com.android.systemui.R; + +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; +import java.util.ArrayList; + +public class KeycodeSelectionHelper { + + private static final ArrayList mKeycodeStrings = new ArrayList<>(); + private static final ArrayList mKeycodes = new ArrayList<>(); + + private static final String KEYCODE_STRING = "KEYCODE_"; + + static { + Class cls = KeyEvent.class; + for (Field field : cls.getDeclaredFields()) { + if (Modifier.isStatic(field.getModifiers()) + && field.getName().startsWith(KEYCODE_STRING) + && field.getType().equals(int.class)) { + try { + mKeycodeStrings.add(formatString(field.getName())); + mKeycodes.add((Integer) field.get(null)); + } catch (IllegalAccessException e) { + } + } + } + } + + // Force the string into something somewhat readable. + private static String formatString(String name) { + StringBuilder str = new StringBuilder(name.replace(KEYCODE_STRING, "").replace("_", " ") + .toLowerCase()); + for (int i = 0; i < str.length(); i++) { + if (i == 0 || str.charAt(i - 1) == ' ') { + str.setCharAt(i, Character.toUpperCase(str.charAt(i))); + } + } + return str.toString(); + } + + public static void showKeycodeSelect(Context context, final OnSelectionComplete listener) { + new AlertDialog.Builder(context) + .setTitle(R.string.select_keycode) + .setItems(mKeycodeStrings.toArray(new String[0]), + new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + listener.onSelectionComplete(mKeycodes.get(which)); + } + }).show(); + } + + public static Intent getSelectImageIntent() { + return new Intent(Intent.ACTION_OPEN_DOCUMENT).addCategory(Intent.CATEGORY_OPENABLE) + .setType("image/*"); + } + + public interface OnSelectionComplete { + void onSelectionComplete(int code); + } +} diff --git a/packages/SystemUI/src/com/android/systemui/tuner/NavBarEditor.java b/packages/SystemUI/src/com/android/systemui/tuner/NavBarEditor.java new file mode 100644 index 00000000000..7c55b0305cf --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/tuner/NavBarEditor.java @@ -0,0 +1,644 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ + +package com.android.systemui.tuner; + +import android.annotation.Nullable; +import android.app.Activity; +import android.app.AlertDialog; +import android.app.Fragment; +import android.content.Context; +import android.content.DialogInterface; +import android.content.Intent; +import android.content.res.ColorStateList; +import android.content.res.Configuration; +import android.content.res.TypedArray; +import android.graphics.Canvas; +import android.graphics.drawable.Drawable; +import android.net.Uri; +import android.os.Bundle; +import android.provider.Settings; +import android.util.Log; +import android.util.TypedValue; +import android.view.Display; +import android.view.LayoutInflater; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; +import android.view.MotionEvent; +import android.view.Surface; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.SeekBar; +import android.widget.TextView; +import androidx.preference.PreferenceFragment; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; +import androidx.recyclerview.widget.ItemTouchHelper; + +import com.android.systemui.R; + +import java.util.ArrayList; +import java.util.List; + +import com.android.systemui.Dependency; + +import static com.android.systemui.statusbar.phone.NavigationBarInflaterView.BACK; +import static com.android.systemui.statusbar.phone.NavigationBarInflaterView.BUTTON_SEPARATOR; +import static com.android.systemui.statusbar.phone.NavigationBarInflaterView.CLIPBOARD; +import static com.android.systemui.statusbar.phone.NavigationBarInflaterView.GRAVITY_SEPARATOR; +import static com.android.systemui.statusbar.phone.NavigationBarInflaterView.HOME; +import static com.android.systemui.statusbar.phone.NavigationBarInflaterView.KEY; +import static com.android.systemui.statusbar.phone.NavigationBarInflaterView.KEY_CODE_END; +import static com.android.systemui.statusbar.phone.NavigationBarInflaterView.KEY_CODE_START; +import static com.android.systemui.statusbar.phone.NavigationBarInflaterView.KEY_IMAGE_DELIM; +import static com.android.systemui.statusbar.phone.NavigationBarInflaterView.MENU_IME_ROTATE; +import static com.android.systemui.statusbar.phone.NavigationBarInflaterView.NAVSPACE; +import static com.android.systemui.statusbar.phone.NavigationBarInflaterView.NAV_BAR_VIEWS; +import static com.android.systemui.statusbar.phone.NavigationBarInflaterView.RECENT; +import static com.android.systemui.statusbar.phone.NavigationBarInflaterView.SIZE_MOD_END; +import static com.android.systemui.statusbar.phone.NavigationBarInflaterView.SIZE_MOD_START; +import static com.android.systemui.statusbar.phone.NavigationBarInflaterView.WEIGHT_SUFFIX; +import static com.android.systemui.statusbar.phone.NavigationBarInflaterView.WEIGHT_CENTERED_SUFFIX; +import static com.android.systemui.statusbar.phone.NavigationBarInflaterView.LEFT; +import static com.android.systemui.statusbar.phone.NavigationBarInflaterView.RIGHT; +import static com.android.systemui.statusbar.phone.NavigationBarInflaterView.extractButton; +import static com.android.systemui.statusbar.phone.NavigationBarInflaterView.extractSize; + +public class NavBarEditor extends PreferenceFragment implements TunerService.Tunable { + private static final String TAG = "NavBarEditor"; + private static final int READ_REQUEST = 42; + + private static final float PREVIEW_SCALE = .95f; + private static final float PREVIEW_SCALE_LANDSCAPE = .75f; + + private NavBarAdapter mNavBarAdapter; + + @Override + public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { + } + + @Override + public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, + Bundle savedInstanceState) { + final View view = inflater.inflate(R.layout.nav_bar_tuner, container, false); + getActivity().getActionBar().setDisplayHomeAsUpEnabled(true); + return view; + } + + private void notifyChanged() { + Settings.Secure.putString(getContext().getContentResolver(), + NAV_BAR_VIEWS, mNavBarAdapter.getNavString()); + } + + @Override + public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + RecyclerView recyclerView = (RecyclerView) view.findViewById(android.R.id.list); + final Context context = getContext(); + recyclerView.setLayoutManager(new LinearLayoutManager(context)); + mNavBarAdapter = new NavBarAdapter(context); + recyclerView.setAdapter(mNavBarAdapter); + recyclerView.addItemDecoration(new Dividers(context)); + final ItemTouchHelper itemTouchHelper = new ItemTouchHelper(mNavBarAdapter.mCallbacks); + mNavBarAdapter.setTouchHelper(itemTouchHelper); + itemTouchHelper.attachToRecyclerView(recyclerView); + setHasOptionsMenu(true); + Dependency.get(TunerService.class).addTunable(this, NAV_BAR_VIEWS); + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + Dependency.get(TunerService.class).removeTunable(this); + } + + @Override + public void onTuningChanged(String key, String navLayout) { + if (!NAV_BAR_VIEWS.equals(key)) return; + Context context = getContext(); + if (navLayout == null) { + navLayout = context.getString(R.string.config_navBarLayout); + } + String[] views = navLayout.split(GRAVITY_SEPARATOR); + String[] groups = new String[] { NavBarAdapter.START, NavBarAdapter.CENTER, + NavBarAdapter.END}; + CharSequence[] groupLabels = new String[] { getString(R.string.start), + getString(R.string.center), getString(R.string.end) }; + mNavBarAdapter.clear(); + for (int i = 0; i < 3; i++) { + mNavBarAdapter.addButton(groups[i], groupLabels[i]); + for (String button : views[i].split(BUTTON_SEPARATOR)) { + mNavBarAdapter.addButton(button, getLabel(button, context)); + } + } + mNavBarAdapter.addButton(NavBarAdapter.ADD, getString(R.string.add_button)); + } + + @Override + public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { + inflater.inflate(R.menu.nav_bar_tuner_menu, menu); + super.onCreateOptionsMenu(menu, inflater); + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + if (item.getItemId() == R.id.nav_bar_reset) { + Settings.Secure.putString(getContext().getContentResolver(), + NAV_BAR_VIEWS, null); + return true; + } else if (item.getItemId() == android.R.id.home) { + getActivity().onBackPressed(); + return true; + } + return super.onOptionsItemSelected(item); + } + + @Override + public void onActivityCreated(Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); + getActivity().getActionBar().setDisplayHomeAsUpEnabled(true); + } + + private static CharSequence getLabel(String button, Context context) { + if (button.startsWith(HOME)) { + return context.getString(R.string.accessibility_home); + } else if (button.startsWith(BACK)) { + return context.getString(R.string.accessibility_back); + } else if (button.startsWith(RECENT)) { + return context.getString(R.string.accessibility_recent); + } else if (button.startsWith(NAVSPACE)) { + return context.getString(R.string.space); + } else if (button.startsWith(LEFT)) { + return context.getString(R.string.left); + } else if (button.startsWith(RIGHT)) { + return context.getString(R.string.right); + /*} else if (button.equals(MENU_IME_ROTATE)) { + return context.getString(R.string.menu_ime);*/ + /*} else if (button.startsWith(CLIPBOARD)) { + return context.getString(R.string.clipboard);*/ + /*} else if (button.startsWith(KEY)) { + return context.getString(R.string.keycode);*/ + } + return button; + } + + private static class Holder extends RecyclerView.ViewHolder { + private TextView title; + + public Holder(View itemView) { + super(itemView); + title = (TextView) itemView.findViewById(android.R.id.title); + } + } + + private static class Dividers extends RecyclerView.ItemDecoration { + private final Drawable mDivider; + + public Dividers(Context context) { + TypedValue value = new TypedValue(); + context.getTheme().resolveAttribute(android.R.attr.listDivider, value, true); + mDivider = context.getDrawable(value.resourceId); + } + + @Override + public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) { + super.onDraw(c, parent, state); + final int left = parent.getPaddingLeft(); + final int right = parent.getWidth() - parent.getPaddingRight(); + + final int childCount = parent.getChildCount(); + for (int i = 0; i < childCount; i++) { + final View child = parent.getChildAt(i); + final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child + .getLayoutParams(); + final int top = child.getBottom() + params.bottomMargin; + final int bottom = top + mDivider.getIntrinsicHeight(); + mDivider.setBounds(left, top, right, bottom); + mDivider.draw(c); + } + } + } + + /*private void selectImage() { + startActivityForResult(KeycodeSelectionHelper.getSelectImageIntent(), READ_REQUEST); + }*/ + + /*@Override + public void onActivityResult(int requestCode, int resultCode, Intent data) { + if (requestCode == READ_REQUEST && resultCode == Activity.RESULT_OK && data != null) { + final Uri uri = data.getData(); + final int takeFlags = data.getFlags() & (Intent.FLAG_GRANT_READ_URI_PERMISSION); + getContext().getContentResolver().takePersistableUriPermission(uri, takeFlags); + mNavBarAdapter.onImageSelected(uri); + } else { + super.onActivityResult(requestCode, resultCode, data); + } + }*/ + + private class NavBarAdapter extends RecyclerView.Adapter + implements View.OnClickListener { + + private static final String START = "start"; + private static final String CENTER = "center"; + private static final String END = "end"; + private static final String ADD = "add"; + + private static final int ADD_ID = 0; + private static final int BUTTON_ID = 1; + private static final int CATEGORY_ID = 2; + + private List mButtons = new ArrayList<>(); + private List mLabels = new ArrayList<>(); + private int mCategoryLayout; + private int mButtonLayout; + private ItemTouchHelper mTouchHelper; + + // Stored keycode while we wait for image selection on a KEY. + private int mKeycode; + + public NavBarAdapter(Context context) { + TypedArray attrs = context.getTheme().obtainStyledAttributes(null, + android.R.styleable.Preference, android.R.attr.preferenceStyle, 0); + mButtonLayout = attrs.getResourceId(android.R.styleable.Preference_layout, 0); + attrs = context.getTheme().obtainStyledAttributes(null, + android.R.styleable.Preference, android.R.attr.preferenceCategoryStyle, 0); + mCategoryLayout = attrs.getResourceId(android.R.styleable.Preference_layout, 0); + } + + public void setTouchHelper(ItemTouchHelper itemTouchHelper) { + mTouchHelper = itemTouchHelper; + } + + public void clear() { + mButtons.clear(); + mLabels.clear(); + notifyDataSetChanged(); + } + + public void addButton(String button, CharSequence label) { + mButtons.add(button); + mLabels.add(label); + notifyItemInserted(mLabels.size() - 1); + } + + public boolean hasHomeButton() { + final int N = mButtons.size(); + for (int i = 0; i < N; i++) { + if (mButtons.get(i).startsWith(HOME)) { + return true; + } + } + return false; + } + + private String getNavString() { + StringBuilder builder = new StringBuilder(); + for (int i = 1; i < mButtons.size() - 1; i++) { + String button = mButtons.get(i); + if (button.equals(CENTER) || button.equals(END)) { + if (builder.length() == 0 || builder.toString().endsWith(GRAVITY_SEPARATOR)) { + // No start or center buttons, fill with a space. + builder.append(NAVSPACE); + } + builder.append(GRAVITY_SEPARATOR); + continue; + } else if (builder.length() != 0 && !builder.toString().endsWith( + GRAVITY_SEPARATOR)) { + builder.append(BUTTON_SEPARATOR); + } + builder.append(button); + } + if (builder.toString().endsWith(GRAVITY_SEPARATOR)) { + // No end buttons, fill with space. + builder.append(NAVSPACE); + } + return builder.toString(); + } + + @Override + public int getItemViewType(int position) { + String button = mButtons.get(position); + if (button.equals(START) || button.equals(CENTER) || button.equals(END)) { + return CATEGORY_ID; + } + if (button.equals(ADD)) { + return ADD_ID; + } + return BUTTON_ID; + } + + @Override + public Holder onCreateViewHolder(ViewGroup parent, int viewType) { + final Context context = parent.getContext(); + final LayoutInflater inflater = LayoutInflater.from(context); + final View view = inflater.inflate(getLayoutId(viewType), parent, false); + if (viewType == BUTTON_ID) { + inflater.inflate(R.layout.nav_control_widget, + (ViewGroup) view.findViewById(android.R.id.widget_frame)); + } + return new Holder(view); + } + + private int getLayoutId(int viewType) { + if (viewType == CATEGORY_ID) { + return mCategoryLayout; + } + return mButtonLayout; + } + + @Override + public void onBindViewHolder(Holder holder, int position) { + holder.title.setText(mLabels.get(position)); + if (holder.getItemViewType() == BUTTON_ID) { + bindButton(holder, position); + } else if (holder.getItemViewType() == ADD_ID) { + bindAdd(holder); + } + } + + private void bindAdd(Holder holder) { + TypedValue value = new TypedValue(); + final Context context = holder.itemView.getContext(); + context.getTheme().resolveAttribute(android.R.attr.colorAccent, value, true); + final ImageView icon = (ImageView) holder.itemView.findViewById(android.R.id.icon); + icon.setImageResource(R.drawable.ic_add); + icon.setImageTintList(ColorStateList.valueOf(context.getColor(value.resourceId))); + holder.itemView.findViewById(android.R.id.summary).setVisibility(View.GONE); + holder.itemView.setClickable(true); + holder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + showAddDialog(v.getContext()); + } + }); + } + + private void bindButton(final Holder holder, int position) { + final Context context = holder.itemView.getContext(); + holder.itemView.findViewById(android.R.id.icon_frame).setVisibility(View.GONE); + holder.itemView.findViewById(android.R.id.summary).setVisibility(View.GONE); + + if (mLabels.get(position).equals(context.getString(R.string.accessibility_home))) { + holder.itemView.findViewById(R.id.close).setVisibility(View.INVISIBLE); + } else { + holder.itemView.findViewById(R.id.close).setVisibility(View.VISIBLE); + bindClick(holder.itemView.findViewById(R.id.close), holder); + } + bindClick(holder.itemView.findViewById(R.id.width), holder); + holder.itemView.findViewById(R.id.drag).setOnTouchListener(new View.OnTouchListener() { + @Override + public boolean onTouch(View v, MotionEvent event) { + mTouchHelper.startDrag(holder); + return true; + } + }); + } + + private void showAddDialog(final Context context) { + final String[] options = new String[] { + BACK, HOME, RECENT, NAVSPACE, LEFT, RIGHT + }; + final CharSequence[] labels = new CharSequence[options.length]; + for (int i = 0; i < options.length; i++) { + labels[i] = getLabel(options[i], context); + } + new AlertDialog.Builder(context) + .setTitle(R.string.select_button) + .setItems(labels, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + /*if (KEY.equals(options[which])) { + showKeyDialogs(context); + } else {*/ + int index = mButtons.size() - 1; + //showAddedMessage(context, options[which]); + mButtons.add(index, options[which]); + mLabels.add(index, labels[which]); + + notifyItemInserted(index); + notifyChanged(); + //} + } + }).setNegativeButton(android.R.string.cancel, null) + .show(); + } + + /*private void onImageSelected(Uri uri) { + int index = mButtons.size() - 1; + mButtons.add(index, KEY + KEY_CODE_START + mKeycode + KEY_IMAGE_DELIM + uri.toString() + + KEY_CODE_END); + mLabels.add(index, getLabel(KEY, getContext())); + + notifyItemInserted(index); + notifyChanged(); + }*/ + + /*private void showKeyDialogs(final Context context) { + final KeycodeSelectionHelper.OnSelectionComplete listener = + new KeycodeSelectionHelper.OnSelectionComplete() { + @Override + public void onSelectionComplete(int code) { + mKeycode = code; + selectImage(); + } + }; + new AlertDialog.Builder(context) + .setTitle(R.string.keycode) + .setMessage(R.string.keycode_description) + .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + KeycodeSelectionHelper.showKeycodeSelect(context, listener); + } + }).show(); + }*/ + + /*private void showAddedMessage(Context context, String button) { + if (CLIPBOARD.equals(button)) { + new AlertDialog.Builder(context) + .setTitle(R.string.clipboard) + .setMessage(R.string.clipboard_description) + .setPositiveButton(android.R.string.ok, null) + .show(); + } + }*/ + + private void bindClick(View view, Holder holder) { + view.setOnClickListener(this); + view.setTag(holder); + } + + @Override + public void onClick(View v) { + Holder holder = (Holder) v.getTag(); + if (v.getId() == R.id.width) { + showWidthDialog(holder, v.getContext()); + } else if (v.getId() == R.id.close) { + int position = holder.getAdapterPosition(); + mButtons.remove(position); + mLabels.remove(position); + notifyItemRemoved(position); + notifyChanged(); + } + } + + private void showWidthDialog(final Holder holder, Context context) { + final String buttonSpec = mButtons.get(holder.getAdapterPosition()); + String sizeStr = extractSize(buttonSpec); + float amount = 1.0f; + if (sizeStr != null && sizeStr.contains(WEIGHT_SUFFIX)) { + amount = Float.parseFloat(sizeStr.substring(0, sizeStr.indexOf(WEIGHT_SUFFIX))); + } + final boolean isCenterButton = buttonSpec.startsWith(HOME) || buttonSpec.startsWith(BACK) || + buttonSpec.startsWith(RECENT); + final AlertDialog dialog = new AlertDialog.Builder(context) + .setTitle(R.string.adjust_button_width) + .setView(R.layout.nav_width_view) + .setNegativeButton(android.R.string.cancel, null).create(); + dialog.setButton(DialogInterface.BUTTON_POSITIVE, + context.getString(android.R.string.ok), + new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface d, int which) { + final String button = extractButton(buttonSpec); + SeekBar seekBar = (SeekBar) dialog.findViewById(R.id.seekbar); + float newAmount = getAmountValue(seekBar.getProgress()); + if (newAmount == 1f) { + mButtons.set(holder.getAdapterPosition(), button); + } else { + mButtons.set(holder.getAdapterPosition(), button + + SIZE_MOD_START + newAmount + (isCenterButton ? + WEIGHT_CENTERED_SUFFIX : WEIGHT_SUFFIX) + SIZE_MOD_END); + } + notifyChanged(); + } + }); + dialog.show(); + SeekBar seekBar = (SeekBar) dialog.findViewById(R.id.seekbar); + // Range is .25 - 1.75. + seekBar.setMax(6); + seekBar.setProgress(getProgressValue(amount)); + } + + private int getProgressValue(float amount) { + if (amount == .25f) { + return 0; + } + if (amount == .5f) { + return 1; + } + if (amount == .75f) { + return 2; + } + if (amount == 1f) { + return 3; + } + if (amount == 1.25f) { + return 4; + } + if (amount == 1.5f) { + return 5; + } + if (amount == 1.75f) { + return 6; + } + return 3; + } + + private float getAmountValue(int progress) { + if (progress == 0) { + return .25f; + } + if (progress == 1) { + return .5f; + } + if (progress == 2) { + return .75f; + } + if (progress == 3) { + return 1f; + } + if (progress == 4) { + return 1.25f; + } + if (progress == 5) { + return 1.5f; + } + if (progress == 6) { + return 1.75f; + } + return 1f; + } + + @Override + public int getItemCount() { + return mButtons.size(); + } + + private final ItemTouchHelper.Callback mCallbacks = new ItemTouchHelper.Callback() { + @Override + public boolean isLongPressDragEnabled() { + return true; + } + + @Override + public boolean isItemViewSwipeEnabled() { + return false; + } + + @Override + public int getMovementFlags(RecyclerView recyclerView, + RecyclerView.ViewHolder viewHolder) { + if (viewHolder.getItemViewType() != BUTTON_ID) { + return makeMovementFlags(0, 0); + } + int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN; + return makeMovementFlags(dragFlags, 0); + } + + @Override + public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, + RecyclerView.ViewHolder target) { + int from = viewHolder.getAdapterPosition(); + int to = target.getAdapterPosition(); + if (to == 0) { + // Can't go above the top. + return false; + } + move(from, to, mButtons); + move(from, to, mLabels); + notifyItemMoved(from, to); + return true; + } + + private void move(int from, int to, List list) { + list.add(from > to ? to : to + 1, list.get(from)); + list.remove(from > to ? from + 1 : from); + } + + @Override + public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) { + // Don't care. + } + + @Override + public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) { + super.clearView(recyclerView, viewHolder); + notifyChanged(); + } + }; + } +} From ed03c28eeedd26f47fa31552842c83ad4f9f5394 Mon Sep 17 00:00:00 2001 From: LuK1337 Date: Fri, 20 Sep 2019 18:30:03 +0200 Subject: [PATCH 125/240] SystemUI: Add navbar layout inversion tuning * Originally implemented by jesec but since then has been reworked by me to use RTL instead of replacing left / right buttons. Change-Id: I6159f0232ba2ee9f45d2afbba7d11072d902d9ac --- .../phone/NavigationBarInflaterView.java | 40 ++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java index 7f346cab0d3..302144e3931 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java @@ -39,17 +39,19 @@ import com.android.systemui.shared.system.QuickStepContract; import com.android.systemui.statusbar.phone.ReverseLinearLayout.ReverseRelativeLayout; import com.android.systemui.statusbar.policy.KeyButtonView; +import com.android.systemui.tuner.TunerService; import java.util.Objects; public class NavigationBarInflaterView extends FrameLayout - implements NavigationModeController.ModeChangedListener { + implements NavigationModeController.ModeChangedListener, TunerService.Tunable { private static final String TAG = "NavBarInflater"; public static final String NAV_BAR_VIEWS = "sysui_nav_bar"; public static final String NAV_BAR_LEFT = "sysui_nav_bar_left"; public static final String NAV_BAR_RIGHT = "sysui_nav_bar_right"; + public static final String NAV_BAR_INVERSE = "sysui_nav_bar_inverse"; public static final String MENU_IME_ROTATE = "menu_ime"; public static final String BACK = "back"; @@ -99,6 +101,8 @@ public class NavigationBarInflaterView extends FrameLayout private OverviewProxyService mOverviewProxyService; private int mNavBarMode = NAV_BAR_MODE_3BUTTON; + private boolean mInverseLayout; + public NavigationBarInflaterView(Context context, AttributeSet attrs) { super(context, attrs); createInflaters(); @@ -149,12 +153,33 @@ public void onNavigationModeChanged(int mode) { onLikelyDefaultLayoutChange(); } + @Override + protected void onAttachedToWindow() { + super.onAttachedToWindow(); + Dependency.get(TunerService.class).addTunable(this, NAV_BAR_INVERSE); + } + @Override protected void onDetachedFromWindow() { Dependency.get(NavigationModeController.class).removeListener(this); + Dependency.get(TunerService.class).removeTunable(this); super.onDetachedFromWindow(); } + @Override + public void onTuningChanged(String key, String newValue) { + if (NAV_BAR_INVERSE.equals(key)) { + mInverseLayout = TunerService.parseIntegerSwitch(newValue, false); + updateLayoutInversion(); + } + } + + @Override + public void onConfigurationChanged(Configuration newConfig) { + super.onConfigurationChanged(newConfig); + updateLayoutInversion(); + } + public void setNavigationBarLayout(String layoutValue) { if (!Objects.equals(mCurrentLayout, layoutValue)) { mUsingCustomLayout = layoutValue != null; @@ -275,6 +300,19 @@ protected void inflateLayout(String newLayout) { updateButtonDispatchersCurrentView(); } + private void updateLayoutInversion() { + if (mInverseLayout) { + Configuration config = mContext.getResources().getConfiguration(); + if (config.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL) { + setLayoutDirection(View.LAYOUT_DIRECTION_LTR); + } else { + setLayoutDirection(View.LAYOUT_DIRECTION_RTL); + } + } else { + setLayoutDirection(View.LAYOUT_DIRECTION_INHERIT); + } + } + private void addGravitySpacer(LinearLayout layout) { layout.addView(new Space(mContext), new LinearLayout.LayoutParams(0, 0, 1)); } From 0538877017ac060668cb96dd290ee116f6d6aac7 Mon Sep 17 00:00:00 2001 From: maxwen Date: Sun, 6 Oct 2019 23:13:52 +0200 Subject: [PATCH 126/240] base: tuner: fix navbar layout switch and remove old cruft Change-Id: Ic9c63c1abf0493ee69a1ef8a3e95710be52a9f8e --- packages/SystemUI/res/xml/nav_bar_tuner.xml | 8 +- .../phone/NavigationBarInflaterView.java | 7 +- .../systemui/tuner/CustomListPreference.java | 170 ------------------ .../android/systemui/tuner/NavBarTuner.java | 139 +------------- .../systemui/tuner/RadioListPreference.java | 143 --------------- .../tuner/TunerPreferenceFragment.java | 36 ---- 6 files changed, 11 insertions(+), 492 deletions(-) delete mode 100644 packages/SystemUI/src/com/android/systemui/tuner/CustomListPreference.java delete mode 100644 packages/SystemUI/src/com/android/systemui/tuner/RadioListPreference.java delete mode 100644 packages/SystemUI/src/com/android/systemui/tuner/TunerPreferenceFragment.java diff --git a/packages/SystemUI/res/xml/nav_bar_tuner.xml b/packages/SystemUI/res/xml/nav_bar_tuner.xml index ca41623573d..75d215e9991 100644 --- a/packages/SystemUI/res/xml/nav_bar_tuner.xml +++ b/packages/SystemUI/res/xml/nav_bar_tuner.xml @@ -18,7 +18,7 @@ xmlns:sysui="http://schemas.android.com/apk/res-auto" android:title="@string/nav_bar"> - - - diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java index 302144e3931..4c8c9febe88 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java @@ -40,11 +40,12 @@ import com.android.systemui.statusbar.phone.ReverseLinearLayout.ReverseRelativeLayout; import com.android.systemui.statusbar.policy.KeyButtonView; import com.android.systemui.tuner.TunerService; +import com.android.systemui.tuner.TunerService.Tunable; import java.util.Objects; public class NavigationBarInflaterView extends FrameLayout - implements NavigationModeController.ModeChangedListener, TunerService.Tunable { + implements NavigationModeController.ModeChangedListener, Tunable { private static final String TAG = "NavBarInflater"; @@ -157,6 +158,7 @@ public void onNavigationModeChanged(int mode) { protected void onAttachedToWindow() { super.onAttachedToWindow(); Dependency.get(TunerService.class).addTunable(this, NAV_BAR_INVERSE); + Dependency.get(TunerService.class).addTunable(this, NAV_BAR_VIEWS); } @Override @@ -172,6 +174,9 @@ public void onTuningChanged(String key, String newValue) { mInverseLayout = TunerService.parseIntegerSwitch(newValue, false); updateLayoutInversion(); } + if (NAV_BAR_VIEWS.equals(key)) { + setNavigationBarLayout(newValue); + } } @Override diff --git a/packages/SystemUI/src/com/android/systemui/tuner/CustomListPreference.java b/packages/SystemUI/src/com/android/systemui/tuner/CustomListPreference.java deleted file mode 100644 index ade1f825833..00000000000 --- a/packages/SystemUI/src/com/android/systemui/tuner/CustomListPreference.java +++ /dev/null @@ -1,170 +0,0 @@ -/* - * Copyright (C) 2017 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.tuner; - -import android.app.AlertDialog; -import android.app.Dialog; -import android.app.DialogFragment; -import android.content.Context; -import android.content.DialogInterface; -import android.content.DialogInterface.OnClickListener; -import android.os.Bundle; -import android.util.AttributeSet; - -import androidx.preference.ListPreference; -import androidx.preference.ListPreferenceDialogFragment; - -public class CustomListPreference extends ListPreference { - - public CustomListPreference(Context context, AttributeSet attrs) { - super(context, attrs); - } - - public CustomListPreference(Context context, AttributeSet attrs, int defStyleAttr, - int defStyleRes) { - super(context, attrs, defStyleAttr, defStyleRes); - } - - protected void onPrepareDialogBuilder(AlertDialog.Builder builder, - OnClickListener listener) { - } - - protected void onDialogClosed(boolean positiveResult) { - } - - protected Dialog onDialogCreated(DialogFragment fragment, Dialog dialog) { - return dialog; - } - - protected boolean isAutoClosePreference() { - return true; - } - - /** - * Called when a user is about to choose the given value, to determine if we - * should show a confirmation dialog. - * - * @param value the value the user is about to choose - * @return the message to show in a confirmation dialog, or {@code null} to - * not request confirmation - */ - protected CharSequence getConfirmationMessage(String value) { - return null; - } - - protected void onDialogStateRestored(DialogFragment fragment, Dialog dialog, - Bundle savedInstanceState) { - } - - public static class CustomListPreferenceDialogFragment extends ListPreferenceDialogFragment { - - private static final String KEY_CLICKED_ENTRY_INDEX - = "settings.CustomListPrefDialog.KEY_CLICKED_ENTRY_INDEX"; - - private int mClickedDialogEntryIndex; - - public static ListPreferenceDialogFragment newInstance(String key) { - final ListPreferenceDialogFragment fragment = new CustomListPreferenceDialogFragment(); - final Bundle b = new Bundle(1); - b.putString(ARG_KEY, key); - fragment.setArguments(b); - return fragment; - } - - public CustomListPreference getCustomizablePreference() { - return (CustomListPreference) getPreference(); - } - - @Override - protected void onPrepareDialogBuilder(AlertDialog.Builder builder) { - super.onPrepareDialogBuilder(builder); - mClickedDialogEntryIndex = getCustomizablePreference() - .findIndexOfValue(getCustomizablePreference().getValue()); - getCustomizablePreference().onPrepareDialogBuilder(builder, getOnItemClickListener()); - if (!getCustomizablePreference().isAutoClosePreference()) { - builder.setPositiveButton(com.android.internal.R.string.ok, new OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - onItemConfirmed(); - } - }); - } - } - - @Override - public Dialog onCreateDialog(Bundle savedInstanceState) { - Dialog dialog = super.onCreateDialog(savedInstanceState); - if (savedInstanceState != null) { - mClickedDialogEntryIndex = savedInstanceState.getInt(KEY_CLICKED_ENTRY_INDEX, - mClickedDialogEntryIndex); - } - return getCustomizablePreference().onDialogCreated(this, dialog); - } - - @Override - public void onSaveInstanceState(Bundle outState) { - super.onSaveInstanceState(outState); - outState.putInt(KEY_CLICKED_ENTRY_INDEX, mClickedDialogEntryIndex); - } - - @Override - public void onActivityCreated(Bundle savedInstanceState) { - super.onActivityCreated(savedInstanceState); - getCustomizablePreference().onDialogStateRestored(this, getDialog(), savedInstanceState); - } - - protected OnClickListener getOnItemClickListener() { - return new OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - setClickedDialogEntryIndex(which); - if (getCustomizablePreference().isAutoClosePreference()) { - onItemConfirmed(); - } - } - }; - } - - protected void setClickedDialogEntryIndex(int which) { - mClickedDialogEntryIndex = which; - } - - private String getValue() { - final ListPreference preference = getCustomizablePreference(); - if (mClickedDialogEntryIndex >= 0 && preference.getEntryValues() != null) { - return preference.getEntryValues()[mClickedDialogEntryIndex].toString(); - } else { - return null; - } - } - - protected void onItemConfirmed() { - onClick(getDialog(), DialogInterface.BUTTON_POSITIVE); - getDialog().dismiss(); - } - - @Override - public void onDialogClosed(boolean positiveResult) { - getCustomizablePreference().onDialogClosed(positiveResult); - final ListPreference preference = getCustomizablePreference(); - final String value = getValue(); - if (positiveResult && value != null) { - if (preference.callChangeListener(value)) { - preference.setValue(value); - } - } - } - } -} diff --git a/packages/SystemUI/src/com/android/systemui/tuner/NavBarTuner.java b/packages/SystemUI/src/com/android/systemui/tuner/NavBarTuner.java index fa531b5243b..dfa7f35bf3c 100644 --- a/packages/SystemUI/src/com/android/systemui/tuner/NavBarTuner.java +++ b/packages/SystemUI/src/com/android/systemui/tuner/NavBarTuner.java @@ -44,6 +44,7 @@ import androidx.preference.ListPreference; import androidx.preference.Preference; import androidx.preference.Preference.OnPreferenceChangeListener; +import androidx.preference.PreferenceFragment; import com.android.systemui.Dependency; import com.android.systemui.R; @@ -51,24 +52,9 @@ import java.util.ArrayList; -public class NavBarTuner extends TunerPreferenceFragment { +public class NavBarTuner extends PreferenceFragment { private static final String LAYOUT = "layout"; - private static final String LEFT = "left"; - private static final String RIGHT = "right"; - - private static final String TYPE = "type"; - private static final String KEYCODE = "keycode"; - private static final String ICON = "icon"; - - private static final int[][] ICONS = new int[][]{ - {R.drawable.ic_qs_circle, R.string.tuner_circle}, - {R.drawable.ic_add, R.string.tuner_plus}, - {R.drawable.ic_remove, R.string.tuner_minus}, - {R.drawable.ic_left, R.string.tuner_left}, - {R.drawable.ic_right, R.string.tuner_right}, - {R.drawable.ic_menu, R.string.tuner_menu}, - }; private final ArrayList mTunables = new ArrayList<>(); private Handler mHandler; @@ -89,8 +75,6 @@ public void onActivityCreated(@Nullable Bundle savedInstanceState) { public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { addPreferencesFromResource(R.xml.nav_bar_tuner); bindLayout((ListPreference) findPreference(LAYOUT)); - bindButton(NAV_BAR_LEFT, NAVSPACE, LEFT); - bindButton(NAV_BAR_RIGHT, MENU_IME_ROTATE, RIGHT); } @Override @@ -114,126 +98,11 @@ private void bindLayout(ListPreference preference) { }), NAV_BAR_VIEWS); preference.setOnPreferenceChangeListener((preference1, newValue) -> { String val = (String) newValue; + int valueIndex = preference.findIndexOfValue(val); + preference.setSummary(preference.getEntries()[valueIndex]); if ("default".equals(val)) val = null; Dependency.get(TunerService.class).setValue(NAV_BAR_VIEWS, val); return true; }); } - - private void bindButton(String setting, String def, String k) { - ListPreference type = (ListPreference) findPreference(TYPE + "_" + k); - Preference keycode = findPreference(KEYCODE + "_" + k); - ListPreference icon = (ListPreference) findPreference(ICON + "_" + k); - setupIcons(icon); - addTunable((key, newValue) -> mHandler.post(() -> { - String val = newValue; - if (val == null) { - val = def; - } - String button = extractButton(val); - if (button.startsWith(KEY)) { - type.setValue(KEY); - String uri = extractImage(button); - int code = extractKeycode(button); - icon.setValue(uri); - updateSummary(icon); - keycode.setSummary(code + ""); - keycode.setVisible(true); - icon.setVisible(true); - } else { - type.setValue(button); - keycode.setVisible(false); - icon.setVisible(false); - } - }), setting); - OnPreferenceChangeListener listener = (preference, newValue) -> { - mHandler.post(() -> { - setValue(setting, type, keycode, icon); - updateSummary(icon); - }); - return true; - }; - type.setOnPreferenceChangeListener(listener); - icon.setOnPreferenceChangeListener(listener); - keycode.setOnPreferenceClickListener(preference -> { - EditText editText = new EditText(getContext()); - new AlertDialog.Builder(getContext()) - .setTitle(preference.getTitle()) - .setView(editText) - .setNegativeButton(android.R.string.cancel, null) - .setPositiveButton(android.R.string.ok, (dialog, which) -> { - int code = KeyEvent.KEYCODE_ENTER; - try { - code = Integer.parseInt(editText.getText().toString()); - } catch (Exception e) { - } - keycode.setSummary(code + ""); - setValue(setting, type, keycode, icon); - }).show(); - return true; - }); - } - - private void updateSummary(ListPreference icon) { - try { - int size = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 14, - getContext().getResources().getDisplayMetrics()); - String pkg = icon.getValue().split("/")[0]; - int id = Integer.parseInt(icon.getValue().split("/")[1]); - SpannableStringBuilder builder = new SpannableStringBuilder(); - Drawable d = Icon.createWithResource(pkg, id) - .loadDrawable(getContext()); - d.setTint(Color.BLACK); - d.setBounds(0, 0, size, size); - ImageSpan span = new ImageSpan(d, ImageSpan.ALIGN_BASELINE); - builder.append(" ", span, 0); - builder.append(" "); - for (int i = 0; i < ICONS.length; i++) { - if (ICONS[i][0] == id) { - builder.append(getString(ICONS[i][1])); - } - } - icon.setSummary(builder); - } catch (Exception e) { - Log.d("NavButton", "Problem with summary", e); - icon.setSummary(null); - } - } - - private void setValue(String setting, ListPreference type, Preference keycode, - ListPreference icon) { - String button = type.getValue(); - if (KEY.equals(button)) { - String uri = icon.getValue(); - int code = KeyEvent.KEYCODE_ENTER; - try { - code = Integer.parseInt(keycode.getSummary().toString()); - } catch (Exception e) { - } - button = button + KEY_CODE_START + code + KEY_IMAGE_DELIM + uri + KEY_CODE_END; - } - Dependency.get(TunerService.class).setValue(setting, button); - } - - private void setupIcons(ListPreference icon) { - CharSequence[] labels = new CharSequence[ICONS.length]; - CharSequence[] values = new CharSequence[ICONS.length]; - int size = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 14, - getContext().getResources().getDisplayMetrics()); - for (int i = 0; i < ICONS.length; i++) { - SpannableStringBuilder builder = new SpannableStringBuilder(); - Drawable d = Icon.createWithResource(getContext().getPackageName(), ICONS[i][0]) - .loadDrawable(getContext()); - d.setTint(Color.BLACK); - d.setBounds(0, 0, size, size); - ImageSpan span = new ImageSpan(d, ImageSpan.ALIGN_BASELINE); - builder.append(" ", span, 0); - builder.append(" "); - builder.append(getString(ICONS[i][1])); - labels[i] = builder; - values[i] = getContext().getPackageName() + "/" + ICONS[i][0]; - } - icon.setEntries(labels); - icon.setEntryValues(values); - } } diff --git a/packages/SystemUI/src/com/android/systemui/tuner/RadioListPreference.java b/packages/SystemUI/src/com/android/systemui/tuner/RadioListPreference.java deleted file mode 100644 index 79811c5de42..00000000000 --- a/packages/SystemUI/src/com/android/systemui/tuner/RadioListPreference.java +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright (C) 2017 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.tuner; - -import android.app.AlertDialog.Builder; -import android.app.Dialog; -import android.app.DialogFragment; -import android.content.Context; -import android.content.DialogInterface.OnClickListener; -import android.os.Bundle; -import android.util.AttributeSet; -import android.view.View; -import android.widget.Toolbar; - -import androidx.preference.Preference; -import androidx.preference.PreferenceScreen; - -import com.android.settingslib.Utils; -import com.android.systemui.R; -import com.android.systemui.fragments.FragmentHostManager; - -import java.util.Objects; - -public class RadioListPreference extends CustomListPreference { - - private OnClickListener mOnClickListener; - private CharSequence mSummary; - - public RadioListPreference(Context context, AttributeSet attrs) { - super(context, attrs); - } - - @Override - protected void onPrepareDialogBuilder(Builder builder, OnClickListener listener) { - mOnClickListener = listener; - } - - @Override - public void setSummary(CharSequence summary) { - super.setSummary(summary); - mSummary = summary; - } - - @Override - public CharSequence getSummary() { - if (mSummary == null || mSummary.toString().contains("%s")) { - return super.getSummary(); - } - return mSummary; - } - - @Override - protected Dialog onDialogCreated(DialogFragment fragment, Dialog dialog) { - Dialog d = new Dialog(getContext(), android.R.style.Theme_DeviceDefault_Settings); - Toolbar t = (Toolbar) d.findViewById(com.android.internal.R.id.action_bar); - View v = new View(getContext()); - v.setId(R.id.content); - d.setContentView(v); - t.setTitle(getTitle()); - t.setNavigationIcon(Utils.getDrawable(d.getContext(), android.R.attr.homeAsUpIndicator)); - t.setNavigationOnClickListener(view -> d.dismiss()); - - RadioFragment f = new RadioFragment(); - f.setPreference(this); - FragmentHostManager.get(v).getFragmentManager() - .beginTransaction() - .add(android.R.id.content, f) - .commit(); - return d; - } - - @Override - protected void onDialogStateRestored(DialogFragment fragment, Dialog dialog, - Bundle savedInstanceState) { - super.onDialogStateRestored(fragment, dialog, savedInstanceState); - View view = dialog.findViewById(R.id.content); - RadioFragment radioFragment = (RadioFragment) FragmentHostManager.get(view) - .getFragmentManager().findFragmentById(R.id.content); - if (radioFragment != null) { - radioFragment.setPreference(this); - } - } - - @Override - protected void onDialogClosed(boolean positiveResult) { - super.onDialogClosed(positiveResult); - } - - public static class RadioFragment extends TunerPreferenceFragment { - private RadioListPreference mListPref; - - @Override - public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { - Context context = getPreferenceManager().getContext(); - PreferenceScreen screen = getPreferenceManager().createPreferenceScreen(context); - setPreferenceScreen(screen); - if (mListPref != null) { - update(); - } - } - - private void update() { - Context context = getPreferenceManager().getContext(); - - CharSequence[] entries = mListPref.getEntries(); - CharSequence[] values = mListPref.getEntryValues(); - CharSequence current = mListPref.getValue(); - for (int i = 0; i < entries.length; i++) { - CharSequence entry = entries[i]; - SelectablePreference pref = new SelectablePreference(context); - getPreferenceScreen().addPreference(pref); - pref.setTitle(entry); - pref.setChecked(Objects.equals(current, values[i])); - pref.setKey(String.valueOf(i)); - } - } - - @Override - public boolean onPreferenceTreeClick(Preference preference) { - mListPref.mOnClickListener.onClick(null, Integer.parseInt(preference.getKey())); - return true; - } - - public void setPreference(RadioListPreference radioListPreference) { - mListPref = radioListPreference; - if (getPreferenceManager() != null) { - update(); - } - } - } -} diff --git a/packages/SystemUI/src/com/android/systemui/tuner/TunerPreferenceFragment.java b/packages/SystemUI/src/com/android/systemui/tuner/TunerPreferenceFragment.java deleted file mode 100644 index 9cc8943aa6d..00000000000 --- a/packages/SystemUI/src/com/android/systemui/tuner/TunerPreferenceFragment.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (C) 2017 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.tuner; - -import android.app.DialogFragment; - -import androidx.preference.Preference; -import androidx.preference.PreferenceFragment; - -public abstract class TunerPreferenceFragment extends PreferenceFragment { - - @Override - public void onDisplayPreferenceDialog(Preference preference) { - DialogFragment f = null; - if (preference instanceof CustomListPreference) { - f = CustomListPreference.CustomListPreferenceDialogFragment - .newInstance(preference.getKey()); - } else { - super.onDisplayPreferenceDialog(preference); - } - f.setTargetFragment(this, 0); - f.show(getFragmentManager(), "dialog_preference"); - } -} From a98dd5049d5cdb0538a4847143e1e5e529c640f0 Mon Sep 17 00:00:00 2001 From: maxwen Date: Thu, 13 Sep 2018 14:47:41 +0200 Subject: [PATCH 127/240] base: SystemUI: tuner: fix hiding of statusbar clock clock in expanded quick settings will not be hidden from tuner setting Change-Id: Ic5db96fba79e5bc77282b70398e7f8055b998892 --- .../android/systemui/qs/QuickStatusBarHeader.java | 1 + .../phone/CollapsedStatusBarFragment.java | 13 +++++++++---- .../android/systemui/statusbar/policy/Clock.java | 15 +++++++++++++-- 3 files changed, 23 insertions(+), 6 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java index 66dabdbf773..088592371ac 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java @@ -242,6 +242,7 @@ protected void onFinishInflate() { mClockView = findViewById(R.id.clock); mClockView.setOnClickListener(this); + mClockView.setClockHideableByUser(false); mDateView = findViewById(R.id.date); mSpace = findViewById(R.id.space); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragment.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragment.java index d655b2fef41..166babe3436 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragment.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragment.java @@ -37,6 +37,7 @@ import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.statusbar.StatusBarState; import com.android.systemui.statusbar.phone.StatusBarIconController.DarkIconManager; +import com.android.systemui.statusbar.policy.Clock; import com.android.systemui.statusbar.policy.EncryptionHelper; import com.android.systemui.statusbar.policy.KeyguardMonitor; import com.android.systemui.statusbar.policy.NetworkController; @@ -60,7 +61,7 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue private KeyguardMonitor mKeyguardMonitor; private NetworkController mNetworkController; private LinearLayout mSystemIconArea; - private View mClockView; + private Clock mClockView; private View mNotificationIconAreaInner; private View mCenteredIconArea; private int mDisabled1; @@ -104,7 +105,7 @@ public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { mDarkIconManager.setShouldLog(true); Dependency.get(StatusBarIconController.class).addIconGroup(mDarkIconManager); mSystemIconArea = mStatusBar.findViewById(R.id.system_icon_area); - mClockView = mStatusBar.findViewById(R.id.clock); + mClockView = (Clock) mStatusBar.findViewById(R.id.clock); showSystemIconArea(false); showClock(false); initEmergencyCryptkeeperText(); @@ -256,11 +257,15 @@ public void showSystemIconArea(boolean animate) { } public void hideClock(boolean animate) { - animateHiddenState(mClockView, clockHiddenMode(), animate); + if (mClockView.isClockVisible()) { + animateHiddenState(mClockView, clockHiddenMode(), animate); + } } public void showClock(boolean animate) { - animateShow(mClockView, animate); + if (mClockView.isClockVisible()) { + animateShow(mClockView, animate); + } } /** diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java index c2c3f81527e..3e7744719d4 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java @@ -79,6 +79,7 @@ public class Clock extends TextView implements DemoMode, Tunable, CommandQueue.C private boolean mClockVisibleByPolicy = true; private boolean mClockVisibleByUser = true; + private boolean mClockHideableByUser = true; private boolean mAttached; private Calendar mCalendar; @@ -259,8 +260,10 @@ public void setVisibility(int visibility) { } public void setClockVisibleByUser(boolean visible) { - mClockVisibleByUser = visible; - updateClockVisibility(); + if (mClockHideableByUser) { + mClockVisibleByUser = visible; + updateClockVisibility(); + } } public void setClockVisibilityByPolicy(boolean visible) { @@ -278,6 +281,14 @@ private void updateClockVisibility() { super.setVisibility(visibility); } + public boolean isClockVisible() { + return mClockVisibleByPolicy && mClockVisibleByUser; + } + + public void setClockHideableByUser(boolean value) { + mClockHideableByUser = value; + } + final void updateClock() { if (mDemoMode) return; mCalendar.setTimeInMillis(System.currentTimeMillis()); From 54dd68fbdc9b630ad798d40f9ba17f1a87660adc Mon Sep 17 00:00:00 2001 From: gudenau Date: Tue, 25 Sep 2018 09:44:26 +0200 Subject: [PATCH 128/240] core: Add support for MicroG -fake signatures, enabled per app by dynamic permission Change-Id: I84fc7e5c606f4b57012d948a4cc6cb521db6b03e --- core/res/AndroidManifest.xml | 7 ++++++ core/res/res/values/reloaded_strings.xml | 5 ++++ .../server/pm/PackageManagerService.java | 23 +++++++++++++++++-- 3 files changed, 33 insertions(+), 2 deletions(-) diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index 0dfc7b87be2..d6e95e341ef 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -2673,6 +2673,13 @@ android:description="@string/permdesc_getPackageSize" android:protectionLevel="normal" /> + + + diff --git a/core/res/res/values/reloaded_strings.xml b/core/res/res/values/reloaded_strings.xml index 933ec845f87..6c6a7513a7c 100644 --- a/core/res/res/values/reloaded_strings.xml +++ b/core/res/res/values/reloaded_strings.xml @@ -33,4 +33,9 @@ Restart system Restarting system\u2026 + + Spoof package signature + + Allows the app to pretend to be a different app. Malicious applications might be able to use this to access private application data. Legitimate uses include an emulator pretending to be what it emulates. Grant this permission with caution only! diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 1bbccbc94d4..ad741ba30ac 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -4186,8 +4186,9 @@ private PackageInfo generatePackageInfo(PackageSetting ps, int flags, int userId final Set permissions = ArrayUtils.isEmpty(p.requestedPermissions) ? Collections.emptySet() : permissionsState.getPermissions(userId); - PackageInfo packageInfo = PackageParser.generatePackageInfo(p, gids, flags, - ps.firstInstallTime, ps.lastUpdateTime, permissions, state, userId); + PackageInfo packageInfo = mayFakeSignature(p, PackageParser.generatePackageInfo(p, gids, flags, + ps.firstInstallTime, ps.lastUpdateTime, permissions, state, userId), + permissions); if (packageInfo == null) { return null; @@ -4223,6 +4224,24 @@ private PackageInfo generatePackageInfo(PackageSetting ps, int flags, int userId } } + private PackageInfo mayFakeSignature(PackageParser.Package p, PackageInfo pi, + Set permissions) { + try { + if (permissions.contains("android.permission.FAKE_PACKAGE_SIGNATURE") + && p.applicationInfo.targetSdkVersion > Build.VERSION_CODES.LOLLIPOP_MR1 + && p.mAppMetaData != null) { + String sig = p.mAppMetaData.getString("fake-signature"); + if (sig != null) { + pi.signatures = new Signature[] {new Signature(sig)}; + } + } + } catch (Throwable t) { + // We should never die because of any failures, this is system code! + Log.w("PackageManagerService.FAKE_PACKAGE_SIGNATURE", t); + } + return pi; + } + @Override public void checkPackageStartable(String packageName, int userId) { final int callingUid = Binder.getCallingUid(); From b36cadb4a65e163e5d1c3725b43c43efc4cbb8d9 Mon Sep 17 00:00:00 2001 From: beanstown106 Date: Tue, 5 Sep 2017 14:34:10 +0800 Subject: [PATCH 129/240] base: Add incall vibration options [1/3] - allow setting vibration when call is connected - allow setting vibration when call is disconnected * - allow setting vibration for call waiting * - works with google and aosp dialer :) Change-Id: I9c4f780e62ed4ddc413f2bc9846e3fe7ab60434f --- core/java/android/provider/Settings.java | 36 ++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index 51112411cfe..5c3ac3e8a59 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -4538,6 +4538,33 @@ public boolean validate(@Nullable String value) { private static final Validator FINGERPRINT_SUCCESS_VIB_VALIDATOR = BOOLEAN_VALIDATOR; + /** + * Whether the phone vibrates on call connect + * @hide + */ + public static final String VIBRATE_ON_CONNECT = "vibrate_on_connect"; + + private static final Validator VIBRATE_ON_CONNECT_VALIDATOR = + BOOLEAN_VALIDATOR; + + /** + * Whether the phone vibrates on call waiting + * @hide + */ + public static final String VIBRATE_ON_CALLWAITING = "vibrate_on_callwaiting"; + + private static final Validator VIBRATE_ON_CALLWAITING_VALIDATOR = + BOOLEAN_VALIDATOR; + + /** + * Whether the phone vibrates on disconnect + * @hide + */ + public static final String VIBRATE_ON_DISCONNECT = "vibrate_on_disconnect"; + + private static final Validator VIBRATE_ON_DISCONNECT_VALIDATOR = + BOOLEAN_VALIDATOR; + /** * Settings to backup. This is here so that it's in the same place as the settings * keys and easy to update. @@ -4609,6 +4636,9 @@ public boolean validate(@Nullable String value) { SCREENSHOT_SHUTTER_SOUND, LOCK_POWER_MENU_DISABLED, FINGERPRINT_SUCCESS_VIB, + VIBRATE_ON_CONNECT, + VIBRATE_ON_CALLWAITING, + VIBRATE_ON_DISCONNECT, }; /** @@ -4734,6 +4764,9 @@ public boolean validate(@Nullable String value) { PRIVATE_SETTINGS.add(SCREENSHOT_SHUTTER_SOUND); PRIVATE_SETTINGS.add(LOCK_POWER_MENU_DISABLED); PRIVATE_SETTINGS.add(FINGERPRINT_SUCCESS_VIB); + PRIVATE_SETTINGS.add(VIBRATE_ON_CONNECT); + PRIVATE_SETTINGS.add(VIBRATE_ON_CALLWAITING); + PRIVATE_SETTINGS.add(VIBRATE_ON_DISCONNECT); } /** @@ -4833,6 +4866,9 @@ public boolean validate(@Nullable String value) { VALIDATORS.put(SCREENSHOT_SHUTTER_SOUND, SCREENSHOT_SHUTTER_SOUND_VALIDATOR); VALIDATORS.put(LOCK_POWER_MENU_DISABLED, LOCK_POWER_MENU_DISABLED_VALIDATOR); VALIDATORS.put(FINGERPRINT_SUCCESS_VIB, FINGERPRINT_SUCCESS_VIB_VALIDATOR); + VALIDATORS.put(VIBRATE_ON_CONNECT, VIBRATE_ON_CONNECT_VALIDATOR); + VALIDATORS.put(VIBRATE_ON_CALLWAITING, VIBRATE_ON_CALLWAITING_VALIDATOR); + VALIDATORS.put(VIBRATE_ON_DISCONNECT, VIBRATE_ON_DISCONNECT_VALIDATOR); } /** From 5186270b8516b4db65a04176a3c859fb3edcd52f Mon Sep 17 00:00:00 2001 From: Ritesh Saxena Date: Sun, 27 Oct 2019 16:22:20 +0000 Subject: [PATCH 130/240] Revert "Remove unused auto brightness drawables." This reverts commit 1f2484b2f790b2f1cd80bda12d75c263331314a6. --- .../ic_qs_brightness_auto_off_alpha.png | Bin 0 -> 2215 bytes .../ic_qs_brightness_auto_on_alpha.png | Bin 0 -> 2082 bytes .../ic_qs_brightness_auto_off_alpha.png | Bin 0 -> 1374 bytes .../ic_qs_brightness_auto_on_alpha.png | Bin 0 -> 1334 bytes .../ic_qs_brightness_auto_off_alpha.png | Bin 0 -> 3134 bytes .../ic_qs_brightness_auto_on_alpha.png | Bin 0 -> 2928 bytes .../ic_qs_brightness_auto_off_alpha.png | Bin 0 -> 3494 bytes .../ic_qs_brightness_auto_on_alpha.png | Bin 0 -> 3182 bytes .../drawable/ic_qs_brightness_auto_off.xml | 20 ++++++++++++++ .../res/drawable/ic_qs_brightness_auto_on.xml | 20 ++++++++++++++ .../quick_settings_brightness_dialog.xml | 10 +++++++ .../src/com/android/systemui/qs/QSPanel.java | 1 + .../settings/BrightnessController.java | 26 +++++++++++++++++- .../systemui/settings/BrightnessDialog.java | 4 ++- 14 files changed, 79 insertions(+), 2 deletions(-) create mode 100644 packages/SystemUI/res/drawable-hdpi/ic_qs_brightness_auto_off_alpha.png create mode 100644 packages/SystemUI/res/drawable-hdpi/ic_qs_brightness_auto_on_alpha.png create mode 100644 packages/SystemUI/res/drawable-mdpi/ic_qs_brightness_auto_off_alpha.png create mode 100644 packages/SystemUI/res/drawable-mdpi/ic_qs_brightness_auto_on_alpha.png create mode 100644 packages/SystemUI/res/drawable-xhdpi/ic_qs_brightness_auto_off_alpha.png create mode 100644 packages/SystemUI/res/drawable-xhdpi/ic_qs_brightness_auto_on_alpha.png create mode 100644 packages/SystemUI/res/drawable-xxhdpi/ic_qs_brightness_auto_off_alpha.png create mode 100644 packages/SystemUI/res/drawable-xxhdpi/ic_qs_brightness_auto_on_alpha.png create mode 100644 packages/SystemUI/res/drawable/ic_qs_brightness_auto_off.xml create mode 100644 packages/SystemUI/res/drawable/ic_qs_brightness_auto_on.xml diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_brightness_auto_off_alpha.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_brightness_auto_off_alpha.png new file mode 100644 index 0000000000000000000000000000000000000000..0a29157fbc5cc76278572315d75581f2d7d1a3c5 GIT binary patch literal 2215 zcmZ`*c{tPy7ycp3WhlD#JzK7AW-Ma~sRm=;LL^4U5@Tt`wTu`Q)h%QYqimT$_L3!g z*%A@ivJA4#*q0Hx8sGH&_x$j-)$ms^Y*003Tu`4tBygMWjI zgPC1ee?DN+DL)fy699Of!gGvdXVxqj2eV5+<$wf@S;*Wpcd!P4Xhi_P-v@vrri7;g zKsa;Csuuw0X90k4=!-`C3(N+Gx24$?;N*AYw-l!_l|MqwuVI*M{$H5(1{whXX9VJk ziIYF2CEMen$EaXW+zQ1YTO{m>Vz;-o)3*4?KSf^q@Uz;7b|v}j#?o|aS!YkT(uBJ^ z@Io%`bIz*Vts@hq{&qo@@DV4iGm;9i@UD_HG3_*E;=6<6f2+r{YX(}Ch{WdxGoceJ zn=M9+z>V628@N38Y5-1Xt1DM$`RAobV`YIQXs+;>*o_n)(&NHwhl*Bzn6!O8E1g*P z^CPhqw3uua6`x>!UM&ze6kElE*302wH$D@JNEj_f=zpS26||uDmr6e^UGwCpq(HA} zz7d`TT#lcTPRr+rPPS~>A>8k>oYd95*aW5R*rm68;domfJKVmJN;g2r6>R;zwl*n; zh&aXIU-&t6l>6kjJ5J~Mu5#I|R*IBH!1SaAPCg)$ltHk`q?>j(>3zzzrD?^3$ktgt zHr^Y3>k&Luma_OZHiHV=5tppO_%;?}mSl+3tkN@LztowPcnyITVq(zC1JS4abZB8S zCJdaKLxei?6%Py&qEb=cA{Vl1V+egX}=4P1x(huxrWe8=M;tc)5?5kHQv z$J_S%b4Cg%_p6`cgGrK;I+5+tL4VqC*Z|Ie8F0d?gPP#GE*~CrX-2|1tvQ_#{ew|U zGEk_vmHp(~qNg(Lpj$4@Ugu*(4ouwh=9t}j4^U4RnY%N5ivDOZtr11RaW}9XX5SjF zU>%VE%!v=1GxRc>GZtzPZs_*OjF(RPB|Qh4oBGqRX7CXe;`vn?W@`nDWWe6nJXV;I zp-B@I#V_b9)A9(xT5c;%6-fE(;|qI}(r*fWfZZ}HXnc%k7je0zIrX4$4YuWdp@lGp zJ5=sPuty>}F7M+-T(SV>c`_-YCTZn;`<^A@tZZL*QxA)829{d$i_j(41>?yk*Opec{KPm{qDuM zwlQiZLQEWp3GU45{ovD732hF^z@{MGoixvbdL76yig%NcvWO`KHONs@Ioj=>@JdUc zk2*y19pxcS?JB?BqRIf7(5m_26$ku4bf$!4TTv0fn->^Hv9(ep=;-KnzmD+}SyOTJ z?fgmjn?vIY+(q=W;AJ3Bd|qXsN;AbEF(F=KLAiEvhz zw%vt#5x6g+ys|6jKUH0>9V8iOCQzZOw<^}5GbiAsa#cVF{^@}XxwAuEeb4=C0*%65 z4zWUaaFIGImoy5}NkO}Eb4y>;OM~c7*}?578++s9HY*DmGw-IG!6u%qv(S8TbG>BE z@Dc~=mT)_esb`U)keP^NyXq>)k5OUUD$Yx44|%n+{uqG}BRPpCVj#;oODuRv=IUt}x;Op`eC=+4U=^nPHwQK{TYepgEIzgE5@^GEKa2G5WQi|>YnRlUKY z>igknHT4dMAI+sX|0Vg4^DIh{IrfHb{nUa_7slny2=YvYpuauk=5_`&WJA1KGe!q6cLVomBfyI7m zBg^Z}-S|PRZo|0uPm8KkhptNk6?Wm-ec{tmuO<8iM%x`dJm2ES<{hEDoiFNS?12#?Fx|!# z;_E(E*X`d5&5fkaqTgiDV&uKEExDo&RaqE89rZcb;ypbY#-20s0k&}2;AS(=uUzco z`l(nA1u~bJFOrJum*3XpDRhj_FpYb&?|FKiJRj^IhXG30KBzy^6pPT^R^E4~64FDH zzQmo@m&;8@>nH7Pvf9XdSPQ}J&(Ccix9wQ^<-NRUCw9n6J@2vcF0$D$tCqtrxtYM1s>{c{NUR=96n*oQd^S?h?!O|y!f|s3hryKhVgZVls1Zg z^XzG*CM(6Fj{U9>&>rJ($mLDOA`v{_nvO+fz12t(aAd-Wuy5h4;A=V~LTrnoR>!YiUH zIN+>O5=Z6_5RM(69FX1U-eK#qW0-}3s8wHs7 hgm|N55NM8Xy;D#Ci#M}k|F25D?9RRNL zul&FQ06Gf*_7fh}+nnYPgx$=H4FKNXD4>_7@jIdflgmUtoBS6>oxW%JTgw;&eS2>f zJ;$Ql#ctpG=uOt0}*9N#puZnIDlQ`RQk7`+$Ns~kteSPiBDP7&!1^RC%UhTS*@AI0U7Tx-3 z(tfyF=yBaY$x~Mm+OxU1NWT;Pb585-kS&CD_Vhz z3>@Da@6R0cDPemFUa_s-Y)h3HBO+H%E=JXS2qkJiY+g~CLbXLyN)z7YszjccWA=00 zkC<>(jxJHxzJ+upzc1`OzsNXL{iCWI64C@7OBnrS+gc^4( z)M^gM;bg$i!CnGp{`d0tPPNy74fK{22C{#29Hd*3lM2#c-)}W zhjL`GDW+5HD_HBSbS7glD`1zUK!8A$aFpNIIF)3pZ@rJJhTJqG<&}f!UEVS*=nBrVei?-|2%XTR(qdSo| zZJ8OMKd9772q%-)9UcD#+EVAv9j%fXu%$z1l2dmO&F->Ix-08LxxsogW?|%hmY5jQ zk9a&9+Ro}m*|}vD)0H7X^%CTZc1%)g(+jWJ=sxjq4$3csO?0N4Gk^MBpU=r{R>aKi zx;i49gDQ;9rUc&6sjGam@Hw9PZ?SgubeaFI&i#xv8Pu~TJgunj6ho4cMW2-M-U=5V z1vftKshFC8i=RAD;(6yt=!y z`CuYs9qY)`kEd9py>lZMNSH+AimqEpur>2bcajW->o2&ILVX)%Ey_ByNL5^%oZ1lk zk$hH6<*}j<)uq(gwK)9jlxBxyp5q*&*0exr0rRAd=j?m2EGi)o>b7e+Zv0@Fg=UIw z-@}6I6KcbvOBrLTbFGZ9yy7_2NaMMauFN{<^JhXiTE{JG3>A$jbE}<<28JUW!2h^1 z>;2Q(8P?Q4Gq%~nm}IQW1pOXencU~l5>|j^tv|k_a<_F@};;CrY&v~r1b*!7GrV=}c#f1=o;;QnrtXwW}4Q8{@M-Co?#^dkGI zSJ4Q9qtR5gJdhW1++k?GNgm8Oye2`Bd_aTwqHBpMHQ$Eb3NJ}jsdYG38cZ6~rF4d_ zVWkcAyRxTi^8;ST!~BMO?lv~45i?-ee(p%Q6}buwkYtk+kTLH26bHHzk_i$u#~g?r zr&FL7$NDSQ!_N#H+3hI$-FkFJX9;15sLfR>;k*pbx3T}YjQ)PKXI8!tKByhHq5OMaou}Y<#eA5{QUwX3{vjU?uz@8SzJTdeM z5T6HYl=}-fshdVeO8cRTkXE=)?FguYIaNC7phWq)4_NS{|J!N&3bU z7P`_YTm>DqF1&qf5~~%kxf4{~7sl17ZB?+#f0 z8&nN3ycFVr3&Eq^gYkR<5O7W83AoM)gtk3g7mYxmHFZwFPom-Qq7Ur<75E2w_;`l@ zf5BkprB8eZ=wAoBK+g~oE*KB!djz`S6)^rdFT5=t=Mf&%iU0en0gR!gLFIXD?0*2= CW#1bB literal 0 HcmV?d00001 diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_brightness_auto_off_alpha.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_brightness_auto_off_alpha.png new file mode 100644 index 0000000000000000000000000000000000000000..74df151e76b0a9885056923cc34ac5081da7d35e GIT binary patch literal 1374 zcmZ`(c~BB~6#gk{%BHrP4MeS0i`RIBR~{)!N`j^(sAHNa31TLg0h%|dwPSg#D(p?T!dHCb4ODdw)2F7AK($IhGYee;g*egD1OGydMXPy`eJpo_CkpQ@q0|2{pyF0*DHPAZm>+J=$ccSLL@Rq8ha|w5rsbbu}IQi%zT4iUA z_re5*{J|^piwVaX3}mhw(+N1A+!_P=*WWwM2=o%`*l|Bt)=lUQn}#@zgjal4K#oTd z!-s7&$WJU`!$M;mF<~&DUk+ih*ZSc;cdvWIqUTe)GGTIeIWJYY!dSdYj+QuYGZ)^B zR8-^{B6Fcb+}P81EoXv*8&>ulT+{rq-Z0^33IygId*v;H?%`M5xFI-lZE5^$hg7~H3T638R~ORj_0p;Hb%KTkp7pd@ z@jVPhORqcguv3qPj8B`tR9}_k_&yw!_@up!AyM{xT(_3T+r4*NNcsMXM)^nEE&Q8_ zt8QvztorE)Pr`BQjqIzH+3&ECh`)3@bvL#1LTTcMYZl9HEs0Tp_>kTm^W7^e4B82+l-qjbStjE2sgGA*WHp=AbJ$miF`NTaq z1Xocj(9AwsZy3WdD{Z!X_|ws;g(nd2r@T3?Nm_Afpum%BSR#6zL7X9S z8{y14WJFt`j?!{ui=bWEJu_*gbRFrv!IjYZNl6cy{5?pq%~>}B($HqUJh9Svcav)L zxIZJbEg8L$2f-z8o|j8^kNyaB*Aft~n#o(%vsYz6He4+Zs(yB@Bf9 z!baGnv+6LTGvnD>Ej^;O`C#2$IDGkY$QQ%f^mD-`CMNifyd9 zbd?Y`@vxkwZ+UXyOVA*sUeFUM73)rB`np6<2`hYS8f6BxoHHP8|~>D$jcJRe_cGsQpPbe z4+EXkZI;8*?%5)i5V>ut(A?B<#h4bo6-SVAZB2FsbN*g-kC9`PGz0Y??A*~+QqGnp zx^_*{L+6bwm05;akfp%`#P;m82}EE@R~k~bi%oKvAusOtM?%liog9CZmOCHm{ep z&QVIL$F_mmkxqm?eAr=wpO*jxK&PR8Im+uOH4#$LjLJARY6jby5w|W+PXEm zs21(W*s_+o&21^AL>NZtjg+3wElnjY)mE9szU{-#d!F|>@AJOTdA_|DPXuF(4J-`+ z0LD11UxB(H~vWAeSe1d!cs4FmBqv~j8L~;nm7t{<{Eo@%KVnc!e;O+x} z#|L0lBk|?|U_$^Xq5(i(17Ih!wC&^(%|bT@kMRQ=n{`W4U8GU;nb?SA4P*aBfQ;d- ziPOdT`4EWRKNJsKCWo2!W;V}VIS{L-?Hz-xoTvR{W)anMW^CNCA;-3l_w)U%Urp;} zUmJbY-ri8?Xy=49R+t8a8+6?Y@VQ`UZ!lzQwp~giv)(Tk`)7_vr7I`Ac32Hb*b25- zK`0A#*0OWf728x5HbEhaFdCP+WwB6HCH*nxbz^FwYh5VZ-7A{grs$dzY_)t}vU-;`St^2G25(2{ z_8zwV++}fP(cYZ9b*c4SmbQg$!f5q(R^6%Utn|a+Or+ze0i=~fyNPUb*UE$OEt?zs( zv^3&}TcX`=?Tqu@LQcUWjw2_5NawVqpe%pEHpag&Vwyg&I(MR!`Kq%%(L$}GZudef zbK^;~x$MUKI{m^xJgIQGT-0RtCRg6UxHn-hpH(#*UZ>urTN^&|G`+AS%bRe!Xwfn^ zxKtt9xwfv%;VbQ0>z(QmiCRNr4^S^NLOPB`U0uG?krKDOpg&o1+hw;YdySCysp72! zZi`?aoXQqSdLaZdx02CT)x&)-CXLl)AXK9ZE~OvJ}b8hmc9x1 z&Ndz%#yzt%A7D-$?=Pvgmnh#5x@xbv?~m5RrNc(j;abC!au8=G%*jg-BphnJ)Kl$Cz);17W|E6)MW&Xu2*?d z)HU=T2jxbqzW*1*KrK>m1sm5vI%!RI8Ei`>$#QyprPDKh-|0Bigt6hKhA+v&x>7ch zAmd^CFgz9SMyI9PP;JNDyM7s4I%70)sgim}Yf8%m@kyRj4l2S^3bB%Ss#y;s1KQYsv+V8{yCKqySKU-@YB=P)8vO-&1P)Px#AY({UO#lFTCIA3{ga82g0001h=l}q9FaQARU;qF* zm;eA5aGbhPJOBUy24YJ`L;(K){{a7>y{D4^000SaNLh0L002k;002k;M#*bF000XP zNklLHAb`8uB#ekJpeqR&|E7F{JfGZVUx~@mV zvz95m!7jNh{qUxuKNFY}b4#Kq3KyycbSD{v9<}#{wHX1Pu>b3U3BywjPBdKCc`dZJ zG%8fa@O zCiLDSYkQ%jLz3FT0Bw7AVQA}k8%$}3osy1rBMe&q=>DfjdO=cG(zprxo}}A@z)1RI z=zV4Pj|PJtE$Ii6#_Zj=(SE^rA!#6SOpgKV_iRafYg}8Bo|3dq(%0;NSH0lRHcC3z za8yHYucWgh@7cic6w1ZrZ4$EO$NwA)EDg^*xak7t13Q2YW$;tW61W=}GI|}-($@-j zOYL3cJt=Q4r>0mg`x>AIT7XYJva2x0OMxYsf`uv54MMx3-Hf&yZJGV=8g6c&CBRbS zS(q0@gV)iXwE>2#H|hu%q@czH@6^z3QSJR<>VvR$X1JVB+i;IJp4~pmy3DgOfD^d| zI0x7T{0Dd)cmwz!@D?y;0_EVnF;t__e&C4RF9tqbBaaV(+*l)|$nj|41YiYl5^yST z2Cx=*8uHsfuW)(ru2j+1Nf4(Skg-th#bjg_&R8Z`-hbx zxW%dubL+0fhVyU(%{u6qY!fD{^P73BplXLl=;ivZESsyOgu>X5c%(dsN5ZCxP>T zPXT9aG4$pUN!qr*%%Mo?+szRMdjN{q3T9e zWBJo1{W23ax^BGMsv5RyxTj|{HyW>YM%QJ!A<8^srGxU`1H(!&`2MU1eB9lZ33{=l zJ(-c}Lf{MxCasxTm6ZMTq-@#a)1HhU1=ck)*dXA!h=P z`?k@H-ncEa@!tPUjl8Z$bMduC@qETUP0}|dJ*1S3_)Of9^rob>D(eDkB)wq*<#WYM zz-hc;w4KjdEO}2+jRv$WfRjJnyHC96@d)p*wyQI+?!QATigq|6Z^!Oa~d=5_Q zapU1$usM?@!kEdv$#iKhr>X4mlaz}MlQ_#!J^9~J+E>Sn-2qYCG9p|`J9yV^kF(4 zo^3bW$#R+p6YdXh16NYU{ho_At)~x!cb5Vmr9O?F3-Gl1W5DO^Spobm(}D2L<;Qfo z(sZ0`AEPNxG!6sT06(XU#FVug0^T8IhyL#KEX+<*VZ26xFhD8?t1eDPJ6ec5#xP=q-Se}L98}=Tu_M(DjpEx z<*r$%4SWl@lir~MDHV2iI*ycwFBGh#EWo@)O37o-yKZ*^H<&Jym7X$Q1L z^Qd$a#0r$l;`7+cCbR3<)AO|k$i~Nz5k3ic7+4b+K&s+6jI!`B7VcdZ@1Qj%^GT+| zP>p`Q1_xT0IPJ5J8lY}%J@^XCFWPZSO@YSFPCimon zWrhu5HSl{b_1iv+l!%5Hm^djHyu_Js?|~7+yh!9mpL1F zkW>lIt>i~bY`)SwYX8=z7G0G~_nZQS=4o@h(_#EIN)2W^7+{*5K7iSyr zal-h?4A3D>e4h@_w~=PwxQjEF;49N%B1@d`pjp3Y6Z?(FT44oqB#Vq*n z0%YB0=1!G)#E_&vG{og|0Zwzf%9OoOSuoAz%Vn17cB*QUA-|4Q+M>Qu(hjBF-3WQ6 z)s=Kfz`sb<{Cut;)*mho{4S}HC$B*qHeGHs-HugFI^1+DWtF6xl&UZL8hYdrrBKsz z^m~G_<_etFJt}Jt!^S(x;;_$TzDd$qYB;V_F+dm!O{K6klCD*G2*P`0T+-FnW<=?r zgs0Twnmss;?M8dVcwMbBU5`WZT9b8FrLnw>6ieK$Tx7gQVQeWSC_6&Cnal~X*0;lG zdQYAz>6IEewyT=dRmyvfiZ@QXy~Nh3cVdZ!(Z$x*iz{0~yShoK4txT0*rKwC(J~&f zAe!T@%R6m$YfrTjdshSFb`aJ}*KYZ*N_wV7(KxZyO_hJe%Wx-8ul0lJ?hSTCaN$Lm7N%8wtq&nVlH8iJ!cS*7TUZ5z7qR|Rd8DN+cOWy+AZuf1{ z@s^i>SAadF?d(f|>nW3`x^3*;q>~~ql8)MV3VjSIxms=4Co*IDkaOBU1O7zXZeK}C zh|V(O4Uw|GTS;5$!$ncV;?4UqK&vQl!;B2z;634PO}Ovab%1geh`G798w&sHJR!%+R~x6%B~_!_ z0Vf(KKcv|g`WnEOkA5zs@-*qYq)PG9ph$G%$4N(BE@&`mAHpbe^KpIzgz+}jOW|2$5A!h{`FI##zt)l{^l zGLy@5fmf6&QY}?e@+C^g=6xIdi4Y!tAifufM)-@x;_E{+H&k=~_2BkC9KO+~Jw|hv z@t9VWHwXiK!G?khpI2f$rERIK7s&4Yc^!@$VukVez!{)&pY>ec*57SVs_2Z{{p7ox zc1|!O=2frB-``!!bJ>pQ%jAZejL zh8*O#!}S7v5WWUoC?hBwRvOfV_J0!6tB8aJ?JWQR03~!qSaf7zbY(hYa%Ew3WdJfT zF*7YNI4v?ZR4_R@GBP?bI4v+YIxsMz%HUuC001R)MObuXVRU6WZEs|0W_bWIFflVN zFgPtTHdHV0000PbVXQnQ*UN;cVTj606}DLVr3vnZDD6+ YQe|Oed2z{QJOBUy07*qoM6N<$f~n)#b^rhX literal 0 HcmV?d00001 diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_brightness_auto_on_alpha.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_brightness_auto_on_alpha.png new file mode 100644 index 0000000000000000000000000000000000000000..626e283a88a7b8fd584ce787a2b9ba1b820846e3 GIT binary patch literal 2928 zcmZ`*doV7A-QeTr|-Y-kMF$ad7tyV?|IJq&wJkU-gZ1~Ee?i&0RRxkpe?bxZ2k|z zg1fl_A3nBAdjgR5NC2o!7v07Q>}tM9to142S)bzEu28;+#@YkG6(|6ZuK@sew?v)= zfM^&1{O|?l4=woYb3H<#Rk6LLNyA_czv|HpZqyGz3H^CGDz~&fB zq%)EIA=mS%r`7(hMBeBKOD51W`tSkks4Ck5jJQr)+u? zKW=tQ;iZYJK%c7=VO5l_OZk^e*L{vsWHL%Y*gN&Y(p+R*+|m{gM&Pvejka!_;El2d zvKI0p*L$D3{nbMdzPKZVP-rSe*G6(S72J3R$9yM!CRL99Yso6y$I9p!f`RPN@YE~% z>e&TU*IFO5b!s7P-+Vk-6oQeq`g$sw{4+`jXIVwBF^VK>ugB?y^|H&0?48dK@{Ial zJdug-KtRg_)h$@TnsW_Lk0z!xKfjkD!m4G4+BCO;g7#q1?y7hPN5(-+z|DwD#PgvE zb{i)mdajYMEFGzc3mrjWFf-VM(>j`!;FfRrV^uZb4be%^t)Jz+E(HUzb%fpNXw zpG$~##TcpM;p*P3u_|zMD+j{ASa+5Ma(!L4(lyt9j&&O2iIIXXj8NO8_MlixuV=M* ze|V2R3Q*g$=W4R-<(Bfl$Wl??x_TYS3CA+(Uiw_JWereW(9Of77`=>bjyBaaDA@T` zXmyES?b7f^qEc9RTyAL)Z$*j5FZ#wfCZw6+$AEgLu(rw<_BG1NAxKUoRn<~#?Yief z8+G)iydN(-^)(+|H6kl04LhCd5>48YXS`-aC4Y>b!WQ5PJqfv5fu=PdxkrO!EU&k) zgo=>+VJJwNW~V@RdH5@u=4PklLO`Q5duqoHvV^E&hVY-uiFE;oL1XxHfRUs`zG~pF zzy*N|LVI(~?RCpK4wj55QfC?gqHK+@p^%{j@pzcd^3mlgQcB>09o3*sgb33z4FnGf z(Z%v4p1#iRAbXEcS4sPZ#OXqYBhq2+E*p^yW>RgD`VALyb)^$|rs~Zx{B&<8DCPlP z>?G>GI1@9u0uPf6lU7eDD$}Fy82wgXEW=0U={||KkHH{(sWLaZ*y(-_3d?)HEK)(t z@QFhiC)foxKMeREowv}!cns5#Y<=}Q;KH7DAaZeM4}RwuZc}Z_JRMNtZ)je4kplUE zn7<#_+@E*v;w1;pgxZAw6WJjrbaSVPb@gEO`O-A%wA|mecR~*?o3=v9)*f~5@ja+@ zw+UwFM$Jhek*~omziq^oKie8(Y&kyXCHnSc#e`ea*SKqSi{fuh4lAXN%gyT82>Fjn zZ*Nk->&Pn{UqyolJb%g+BXAaY1jLbwEM8UezBpSao^}s4{g^Ru(m-kDrbe2phXAns z$~P4i+gsxd^;$K_G!nN7X*Bdd(*PPpQzTd&Gk`AFsJeTlGsh z$d;UpQVXj}D(w4&g;X}=R#dNk;G?f@s)R+(CZu-TlpFRi7{c zqBSo`L4Ajm-Vrc4Vmx8}+IW25AbWBtk0dD#KiWiClvC0T;vsrZ>OT@LGy@aD<+>~% zb1q;+U(}Oou?Ls!F|z)CwDMjEvo!SOVY9v(`w{Zq-@e3nGi~y5{*7UEvE0PV^MBNr zWm@OACK=@=mOXmI?+%C|{N-rxYE$_(_`Sf0qCdjVe4xs61u2pTqV|+#p8qtTI!K&o zIq``jHx`%gaBigh5I4G+26lSE?h!nYB|qMxb^xz&%b|TnHO1r>3x%_J4j3#lj4x3Qb~jXv!BX^rK!j74m(F*9I9=;Nfwu{ zMwTYvo0R(tM|H(SHR^EShMdhN45r9_>!cIggT0U)n7=Gw8neS=!u~K`vxM zX99(dcPv!sMUAEH-k}0{A8{MMpg(8Vp3Up0r?d0rnaFNG66#69ZB!$c@7OFHV|-)J z(h#LT6d?#m{}g_(781B()%tDe;Cis|Ol&3(OC_Z+Vujf_!7n!A(Q(6LC)OrFWRm*K z(fD|TO}9_FLV9fHY7#`??PaZBNJ3HPz}JPJB zw_3o|lPZ~-U={HoL}gKBawz{bDs{)-yev{sqpF^c;wy&c;Dt0ITgP#_8aPS|BuGYlB-L6AkXL-7O+qQ9>oOzWx5t?t5j_B8OR~nJ_X{(qN zDc>0$(6~wXY$d>pZ!8@Ry|wl5cZ@xqJDgv7r7!O4uZMj)PQ7QalvS|C^t&zbC%_Sh zEbGH^4wq?U1NEi#4syqQhsFI;Z|F~+RcF_d;!m1b@2~loEwvA*AM?V)0osSNUScFD zzqUmA(c^H@35OEfyIO?IiKPN4N2$?By-2D@0wkmvlBCI7c(r`@UQf$wTh+zA&nj9f zLv6WjTT@!jg%_4It&$5YcM9r1Y%ONjsji>If=xG6p6I%#f?rn9;Y-Nw*8P9ziC#)R z678Bx{WR+&W7YicYp66cP_7pKjz}DO?%{U)+Kr+Em>J9!9rd21*0Lz^w&F2Ld>gAi zw!OH}9r(LrPnZ-;5St(inl$)oPK+S zoGAJ72*y zBOh$q>Gj<-(F-8Tzf;*S%Lx)ytOBt$wSKp}Gxb{gCbbjr?#!QRa^~L+g{(r+j&biTDgZ#e=I+0vQ%#dhnbp1GlQ8?NR}3)(sq+Im#$Kl z6iJ%by^2bUx@{`l5|yk`q<3`dzV9FRbN_hH=bZCA&+q)c-{1bn*%RpRtphcMfMXg2$P10Vx>tOF#w{(h@t?PkAM>g1OuEH`L-K?2MDCj z<*~!0VJtslv`FB>S+M7K#;5 z1Gv033Na9(@MlLWwnn?hz`Zx!eQT3q+3bw zKb;C=1;S_|F#yB5xH?Cp&}bMA=Yn>_;&5mu7zTyLAW^Ct=ZtnEVsS(a9`^l$tE`D* zVu`_Y=674F6A8|hO5=%0WKvR+OOmULNF0YmySuwDa9}XbDh+3eTqxzpoP`pb9}ILr z5-sM%OL-z8Y=MyzB}$Nz;3`l53_%djV*N!dlzdN=DrHC+CmxA*K_LZ#g}A<)?DAB0zhmA15lf_r0ghB8W{X7p9~}_L6-h-B zt|%Tx3&FwcS)6E|a6#a(P@q5Kr2}GKA`rtAiv+N587A`n&I47HXf)mpg~y=2MUEo4 z(y$baJDP%G(r66$cWli6lQpEu8RSBH{7<|55UF}_Vf$C}s}6sS4E)3|1{AtmndYl|8aAeZVc^5B!t~fioCBhD^Rs=cKi-rEOc#6Ar#i~R z-+1+I3V9H>E;OK=?PzPzX@&Kt=i9@A$kaV*>G#m&vNVsoy=4CBpqx<3N`uyptKA5` zuY!DOa!Kj3Q8q>+)7My^8T%y_anAr^ABgS)8lJ(}bXie$_q$Rf9s}IPhZOByOaTkD zqP1TbXfC>*YF1i_IC)>VH1K)kC}w#JRt9PK^+jTaZAPfp*<}+)4DFKV<~53ftZO88 zGVb8Zvy@dO&(P8w%HkHP^#>#6nB~=@{U%=h%@6g32}=MVvq!ydh~3a0Zh588gL;Ab z>4EIw*#}pLxl^|*1e7Vz%3kVB9;&Blv$bF7A4iMjLF4cACL4y+TCgi1GZ*SYwDxJ& zYj;?`kEL4W5*2`Uvk~d-j!8Ge=Vw9=dDxQ^3N2Wd3P;Ipxy!pDv)Tc)(>VFQ3u@8` zlf@&fU8O>yu6*BnJ+@t$FQgVqbWlPG4nttbL-q9A;EJ#SkzJ1-4(w&9oBYQBi(O!0 zfAgt!2FVjMK%&Q$7?!Hz3TBnTpinmTQul#>1w2v%dO&7lN%ffti6__0g0`GjKHfhW zt?g``FU*=MD1D}@Cp4aWpE3T_*YvJ8B}3E<{b?6aRu4%47fRbJfhO(k)_sObj50B| zb}m>6qGtX~JyLG$_OO5f!;J05W|JcZBkgDMQR*iuQ{N=d#Db)3^jcZP1rcTRiOiGb`e7^=DEEiY~xs0Zy(!wh4I6hwdTkGz(OJtjo z_ZF$88?I{8o32d1%TZqO1TMnZ`bP|Oxdl5wa)QXWm^h+=q`XN9`SduDyn%YfZosKz z?S71}mZ4UHgXBqW-CB>~>K=AH^use86dLK&6FCRtRC$NnXkT!cW$&x&9kx(=&gPZs zJboNZu7Kb7Mmb&YTBQeO$K!JpO4C8A)Iu?$&1s)hRxaBiJ?5=YTuOPg3-)?dHmSz1GQO+wr*21 zUrN>_UmCXcKV(bojRp?+Q+oYfA!ddmaJP`1Q*qwiL|QD-I;8d1sQDe@C}%6f@oR$; zARIrHpJY+=*5o(ywiAt>8I@XCQ{<&xcQyt;FJMc#zhrp5mRB-Ou=zS&Rkh9#BYjQ1 zSiMHb_NK9e;$%~PikOnUDPn9U?Ui8HO-*uE4JOf*F?#Li)mot@iaqm)LMODV)2=4M z+R4)yl?GwkH<%V&USyZxSv`4p7%_Kfja4Ex;jVMO*4KV5Xz`H2=n+=xOAEg@8rR2H zo?Lgwh2Xm0bp3oY;(d|UWkiQV>n`21=}t+I+N`?j51Wki+Jk~d!W2hJeerv$)O4>k zjc;9Viaa-M5TRkeKl@2_{l>~Cv!L6ACAvDBK5wiWIk)@#sH?Ij-yV>s)h(wb&a&`P zsfIPyEfqJ~w)i|D>+d)?mDpQ)48W?@)z=xmULRO71l}-M*Swc_Ll-Q%bKT3VE*P`! z%`y1=&cQ9s{S(-OBfV%%=o@=hP6hW{vBTfjIZr_qeQ%} zy<&6L-}(jnIARoN@EvU@PExY@)a`pCyKdBMI zM%-_LQ~t=wdgl19P}+q>@84j~bByy1x4W&CQVo6i;F@1)3dzs=M&WsPP3TMzCiQf) zZwH0RXk6A-S@fdKH1zQ8Bd2zls6);iJT){^-9cW@5;&yo*SNj%S;;5(6@8^$F@c{@5dHc=r3kO>3mtIA?aKZPLnU2;E?-Vw>@jK&2#f4U$$4CO+7%H z@%zGv-@l?ucshphraDc`Jy+bfxEJA*?4pDotC`Uy_AIUAmzRSYpKf=ar0p$qqt<23 z`<3u6{1u%cWj&a$lxD!)_;Ezth2cr0I!=U-N~kr$dA&%eYVcvYD47)3{^jD?rcB zus?Z7cJBK%zkC>Jq(})3d6GuNH-#yXlQ+E9KIqXqqL$?lvBXLmWMnq<$fOmf(T5~& z!u&gOnQXFL+*0q(KrzoaW}~CZO`~$cT*?r>+J^dlT${CGcqczU=%C#;WzwgDTj*9i z{PlE6EONjD&mj2|{11$GDBEwPWYthD9lER0c?FxDx94f>m7elg9Z-XRN&0YLd~kzl z@kKpHr(52RRpgVnssPVv@Pi}k?f7#8A&<6`Sm(@Z(iEk6NkNr5rhQ^>|{EqH(8*+|Kj{T&M5%ouL*TA%Ld>bTN4FFmQbJ z0A~7ELFebLN}VTWBeJ)su`l-Xsd47J0-_47Z;s@=%}aV&hdDY9%qJR*B>e^%-eh;t zZoID|?$^6!hT(V27bQIMPP1d{PImWs)Glf)no9GFt&DT9mmJu9S}T6rX3y3#=^Fa< zaHnDeuIRjgLTuPTKS~{Rwt_ygxMom9pgLuwNvaq5FfoyXgz zSb+7J0DQX!KEk(sDVY$Dy%1&G$}Jx~-ap5Zf20b?NCK^W^29iczI~5Q-2OP{XvRHt zWo6FhQqLNs-k_!4)@vO*41}lxdsz46IgmQ&#eKDt69ea8FZ??x z6-m+!rH;@^LPew_LXqEe>im9xoY(o|_q?9x`F_8j@8|vgT)(f^^Q6&Teo}+#K|vsp znvrkSN)WH$|J1aCj2N0`~oa%d835 zK_oYOhwrvzD>6JpB;u2h$mr;3vuLatPY{em6N$uS4h+UrreP|K;fh#dQ?3y4gTWpU z1`0y?qEH?ew#>*1;6;kaaG9rng}~v{XnzxPh2Ik;OBqtk;v>;!C?too9M?B(p~wyR zuN(iUEo8*-0i+usPln5O z%-Er95*kOqS>Uh~JPw1w6VPaa1=@jtC7>+Oc6gLI!QuzUKVebk4)$n*0~LiQ$|^y{ z+7WO>f*p=xXMwS`pknYpuufc|h{X*Ae%K9_+5L{S|5q%DA^=z-o`AvQMf~UhdI(R% z6Nd2kFp4`KW<+BJhH{q$TbB#;SG@LsAT$bKI|z6j*tZOmLjTDFS(IqBg*nOsgZdUZ zih!lyY%xT%Ey{sHp~Amo+5b=0kTPeG%kA+$?eaq;>%rye-_0*u{C#`?uI$VRWQU`R zavuQ#DHk}|+cLy`K@HEz;W(ak20X&S>kY$_yq0SXt~qDe*RI{qmeei^E*k$cch zmH1B28a4AyGt&xIa2KDA?bph^LvA)XsuV%_I(n$0RlfOCgHr0&)z!(~RnSOe{Svt*x`R`oZPa!xU=S2rE!|o8vl?u3VJdjswpdSMWE!iQDdrfSbHiY9@zL zyapn~O4HHv9QCuh^p))&8-7!!zaE+gM3w6XYkOS14wIexYyH3q1;S{^L3wAVE5C!v z4@@2Dk-ij6u*X7ybZH?Ds($%WyhP7N;icT?3A5%%O<+$p{B7Kr*QDz%)fS((PaY=7 zEo9cJf(#`;Y3rNDtzNHWMcJX2eI+BRbvwv8b@S?{G@#&9$0@zs zd(f7Ij^IKq_(jtYgRLd;A5`^c`>Jbobod2{=`Gg_GLtraV40EU5ITcO`U&qr5hojN z9QO8jlG6o!idA<5S66MX~K6rIK>fdWuH7O=YpJ=jc$r=ZZhw)-mQ-TR|6FY?7Abq@zRE^mdY7``CBFO|58eb<%3?lrQMAFM-c#vZM0UwC73Rk!)RBxIAY`uNEa2LlMVj;WM!(&dw2WsC>i z^0x2x%k5U3R~m{8wW|1I)kbo~Di(IVIUlTqC)TD5OWeVe-u_?DHJ21-PtES>hO0?KfT=X9B`mZa6b458*OA%2)`7zt{A=1FSSyMK#Ncq0Tt>06%I!6?Z zZ>~GoW$r>drwtF7<4wC8<>^?>D(kA6Etrc|mQ z7>?bzk^ee3Y`mjHK0KBxg1q@Us5kEy7NFe1mAVBQ-q1R^_x;dXB($i8f>bKPJkms5g0ra~UHTqFb@^lN$Z*tv7h!-V-($%hjw-4YpFiYxpOy$Wv4G1`oL zt_^B)Np6nfy*!so?@CGXBi)d6HPn%-MUcEE>CY(Tbsnnvk=>`Xb#n4o8J%TD)ohHH z0`$4emU6Y6-OiWBx0FbVC6lMGDnv>*f`$CdEQH}gJJcqrei zgnk%@-mLXZWFAw@qSe51OUF}7yVs2A5Izb4$?pl4XX4)Nt5TXd?gxIY^I16lXE_o0 zQd~G~b~D#67^6F^8|a#LrAM{M5}TMyq|qI&w_wrF(eNEUxr+~;TuP#T60hkPcrLMO z&?sx3gi`pd37z=Uk7&+Z4ZLo~yw!eUJ!z#i88Q`>k-YIY6~Tjjw{sSKHx>2nU}ZON z9b?T%E;=7nSXjM&(6Wf#sV=?+dcp3PCl8z4rGuXmG31w=BtBJjMh~gi`rKm9y*LP? zcFROHTalZYAm?0_m7z%u${AiT(Y`U%{_vRHs#MQ=J`5YFr+xEvc*06sz@$u}KGsIM zm!4HIvD%#CHkbFVI~Od+0R-h?Q%uSAtqIeh=ficICM<$G3BgSbe{B6pBu=gwp6W2_ zcKj6*+ul(Y*HLpkW^%2?qjPcvzFM<29r{|XT}MqmM$=5xry1tfDP>0Oz3sa~ds@W< zT}!k6C0~;Jo)InXO@fD{y>uI4qE1(V8Z>pk1W;&aH?ib}8{GSkC{Nye2mm*#do*Vy zE`7~e!iRa=f5|$uv}Wh~yo63Bvbe5d68tRSe9dt1&de@e!xVkA94YqKX+LXCs^h3+wBAARrc>7Gh$+7fXZGjpV`zxQ+_oO{oHus=OHnMzRIz3ci* zXm0Vq$43IN4N7@ig8c>=-#!Ogp{Y*!U$y)})Hr_HFjY9b{0HDfb+NCq H^H2B>mM%<4 literal 0 HcmV?d00001 diff --git a/packages/SystemUI/res/drawable/ic_qs_brightness_auto_off.xml b/packages/SystemUI/res/drawable/ic_qs_brightness_auto_off.xml new file mode 100644 index 00000000000..aaebc778e42 --- /dev/null +++ b/packages/SystemUI/res/drawable/ic_qs_brightness_auto_off.xml @@ -0,0 +1,20 @@ + + + + diff --git a/packages/SystemUI/res/drawable/ic_qs_brightness_auto_on.xml b/packages/SystemUI/res/drawable/ic_qs_brightness_auto_on.xml new file mode 100644 index 00000000000..e17b5335c55 --- /dev/null +++ b/packages/SystemUI/res/drawable/ic_qs_brightness_auto_on.xml @@ -0,0 +1,20 @@ + + + + diff --git a/packages/SystemUI/res/layout/quick_settings_brightness_dialog.xml b/packages/SystemUI/res/layout/quick_settings_brightness_dialog.xml index 28672241b1b..2efae71103f 100644 --- a/packages/SystemUI/res/layout/quick_settings_brightness_dialog.xml +++ b/packages/SystemUI/res/layout/quick_settings_brightness_dialog.xml @@ -22,6 +22,16 @@ android:paddingRight="16dp" style="@style/BrightnessDialogContainer"> + + Date: Sun, 3 Jan 2016 11:52:48 +0530 Subject: [PATCH 131/240] Add auto brightness toggle to Quick Settings - Not a new tile, just a small icon/toggle beside the brightness slider Change-Id: I99a39156f931943e98d539a07046698c16361d07 --- .../quick_settings_brightness_dialog.xml | 2 +- .../src/com/android/systemui/qs/QSPanel.java | 5 +++- .../settings/BrightnessController.java | 20 +++++++++++--- .../systemui/statusbar/phone/StatusBar.java | 2 +- .../policy/BrightnessMirrorController.java | 27 ++++++++++++++++++- 5 files changed, 49 insertions(+), 7 deletions(-) diff --git a/packages/SystemUI/res/layout/quick_settings_brightness_dialog.xml b/packages/SystemUI/res/layout/quick_settings_brightness_dialog.xml index 2efae71103f..bb91c00e77e 100644 --- a/packages/SystemUI/res/layout/quick_settings_brightness_dialog.xml +++ b/packages/SystemUI/res/layout/quick_settings_brightness_dialog.xml @@ -27,9 +27,9 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical" - android:layout_marginEnd="8dp" android:src="@drawable/ic_qs_brightness_auto_off" android:contentDescription="@null" + android:paddingLeft="8dp" android:visibility="gone" /> { mBrightnessMirrorVisible = visible; updateScrimController(); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BrightnessMirrorController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BrightnessMirrorController.java index b1986782e91..2651776fddc 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BrightnessMirrorController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BrightnessMirrorController.java @@ -20,8 +20,14 @@ import android.content.res.Resources; import android.util.ArraySet; import android.view.LayoutInflater; + +import android.content.ContentResolver; +import android.content.Context; +import android.os.UserHandle; +import android.provider.Settings; import android.view.View; import android.widget.FrameLayout; +import android.widget.ImageView; import com.android.internal.util.Preconditions; import com.android.systemui.R; @@ -42,9 +48,12 @@ public class BrightnessMirrorController private final ArraySet mBrightnessMirrorListeners = new ArraySet<>(); private final int[] mInt2Cache = new int[2]; private View mBrightnessMirror; + private final ImageView mIcon; + private Context mContext; - public BrightnessMirrorController(StatusBarWindowView statusBarWindow, + public BrightnessMirrorController(Context context, StatusBarWindowView statusBarWindow, @NonNull Consumer visibilityCallback) { + mContext = context; mStatusBarWindow = statusBarWindow; mBrightnessMirror = statusBarWindow.findViewById(R.id.brightness_mirror); mNotificationPanel = statusBarWindow.findViewById(R.id.notification_panel); @@ -52,9 +61,13 @@ public BrightnessMirrorController(StatusBarWindowView statusBarWindow, mBrightnessMirror.setVisibility(View.INVISIBLE); }); mVisibilityCallback = visibilityCallback; + mIcon = (ImageView) statusBarWindow.findViewById(R.id.brightness_icon); + // enable the brightness icon + mIcon.setVisibility(View.VISIBLE); } public void showMirror() { + updateIcon(); mBrightnessMirror.setVisibility(View.VISIBLE); mVisibilityCallback.accept(true); mNotificationPanel.setPanelAlpha(0, true /* animate */); @@ -133,4 +146,16 @@ public void onUiModeChanged() { public interface BrightnessMirrorListener { void onBrightnessMirrorReinflated(View brightnessMirror); } + + private void updateIcon() { + if (mIcon != null) { + boolean automatic = Settings.System.getIntForUser(mContext.getContentResolver(), + Settings.System.SCREEN_BRIGHTNESS_MODE, + Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL, + UserHandle.USER_CURRENT) != Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL; + mIcon.setImageResource(automatic ? + com.android.systemui.R.drawable.ic_qs_brightness_auto_on : + com.android.systemui.R.drawable.ic_qs_brightness_auto_off); + } + } } From 313f619c25111550f188631733d9ee82730482eb Mon Sep 17 00:00:00 2001 From: maxwen Date: Sun, 3 Jan 2016 17:11:54 +0100 Subject: [PATCH 132/240] QS auto brightness toggle rework - use different vector images and improve layout - fix color Change-Id: Iaa678ee81e20c3d212642297c8ff49bb40a72232 --- .../ic_qs_brightness_auto_off_new.xml | 26 +++++++++++++++++++ .../drawable/ic_qs_brightness_auto_on_new.xml | 25 ++++++++++++++++++ .../quick_settings_brightness_dialog.xml | 12 +++++---- .../settings/BrightnessController.java | 9 +++---- .../policy/BrightnessMirrorController.java | 4 +-- 5 files changed, 64 insertions(+), 12 deletions(-) create mode 100644 packages/SystemUI/res/drawable/ic_qs_brightness_auto_off_new.xml create mode 100644 packages/SystemUI/res/drawable/ic_qs_brightness_auto_on_new.xml diff --git a/packages/SystemUI/res/drawable/ic_qs_brightness_auto_off_new.xml b/packages/SystemUI/res/drawable/ic_qs_brightness_auto_off_new.xml new file mode 100644 index 00000000000..d980b92348a --- /dev/null +++ b/packages/SystemUI/res/drawable/ic_qs_brightness_auto_off_new.xml @@ -0,0 +1,26 @@ + + + + + + diff --git a/packages/SystemUI/res/drawable/ic_qs_brightness_auto_on_new.xml b/packages/SystemUI/res/drawable/ic_qs_brightness_auto_on_new.xml new file mode 100644 index 00000000000..1c9831645b8 --- /dev/null +++ b/packages/SystemUI/res/drawable/ic_qs_brightness_auto_on_new.xml @@ -0,0 +1,25 @@ + + + + + + diff --git a/packages/SystemUI/res/layout/quick_settings_brightness_dialog.xml b/packages/SystemUI/res/layout/quick_settings_brightness_dialog.xml index bb91c00e77e..739bb6ef70c 100644 --- a/packages/SystemUI/res/layout/quick_settings_brightness_dialog.xml +++ b/packages/SystemUI/res/layout/quick_settings_brightness_dialog.xml @@ -24,13 +24,15 @@ + android:visibility="gone" + android:scaleType="center" + android:layout_marginStart="8dp" + android:background="?android:attr/selectableItemBackgroundBorderless" /> Date: Mon, 31 Oct 2016 10:55:05 +0100 Subject: [PATCH 133/240] Fix automatic brightness QS toggle icon Change-Id: Iedcc7b3f43f758664629bc66b12f22cff0059f8f --- .../src/com/android/systemui/settings/BrightnessController.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/SystemUI/src/com/android/systemui/settings/BrightnessController.java b/packages/SystemUI/src/com/android/systemui/settings/BrightnessController.java index 950e7652c5f..336fb2ed671 100644 --- a/packages/SystemUI/src/com/android/systemui/settings/BrightnessController.java +++ b/packages/SystemUI/src/com/android/systemui/settings/BrightnessController.java @@ -239,7 +239,7 @@ public void handleMessage(Message msg) { try { switch (msg.what) { case MSG_UPDATE_ICON: - updateIcon(msg.arg1 != 0); + updateIcon(mAutomatic); break; case MSG_UPDATE_SLIDER: updateSlider(msg.arg1, msg.arg2 != 0); From b2e8565dd2a462512820f31f6b845ea3d036bacc Mon Sep 17 00:00:00 2001 From: Ritesh Saxena Date: Fri, 26 Apr 2019 16:33:46 +0000 Subject: [PATCH 134/240] Make brightness icon always visible Change-Id: I00953d5a74a540af113cb04eb4f6626146425f3a --- .../SystemUI/res/layout/quick_settings_brightness_dialog.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/SystemUI/res/layout/quick_settings_brightness_dialog.xml b/packages/SystemUI/res/layout/quick_settings_brightness_dialog.xml index 739bb6ef70c..e20b563bed8 100644 --- a/packages/SystemUI/res/layout/quick_settings_brightness_dialog.xml +++ b/packages/SystemUI/res/layout/quick_settings_brightness_dialog.xml @@ -29,7 +29,6 @@ android:layout_gravity="center_vertical" android:src="@drawable/ic_qs_brightness_auto_off_new" android:contentDescription="@null" - android:visibility="gone" android:scaleType="center" android:layout_marginStart="8dp" android:background="?android:attr/selectableItemBackgroundBorderless" /> From fe1e17024c35b471e6c0a68cc70bfdefe1cda13b Mon Sep 17 00:00:00 2001 From: Vachounet Date: Thu, 13 Sep 2018 19:55:39 +0200 Subject: [PATCH 135/240] SystemUI: allow to switch back to pre P mobile type icon style [Reloaded - @RiteshSaxena] - Adapt to Q Change-Id: I1c48af826c18e00960ae98d2dc684cf1f1d735e1 --- core/java/android/provider/Settings.java | 12 ++++ .../stat_sys_data_fully_connected_1x.xml | 27 +++++++++ .../stat_sys_data_fully_connected_3g.xml | 27 +++++++++ .../stat_sys_data_fully_connected_4g.xml | 27 +++++++++ .../stat_sys_data_fully_connected_4g_plus.xml | 30 ++++++++++ .../stat_sys_data_fully_connected_e.xml | 24 ++++++++ .../stat_sys_data_fully_connected_g.xml | 24 ++++++++ .../stat_sys_data_fully_connected_h.xml | 24 ++++++++ .../stat_sys_data_fully_connected_hp.xml | 27 +++++++++ .../stat_sys_data_fully_connected_lte.xml | 30 ++++++++++ ...stat_sys_data_fully_connected_lte_plus.xml | 33 +++++++++++ .../layout/status_bar_mobile_signal_group.xml | 6 ++ .../statusbar/StatusBarMobileView.java | 11 +++- .../systemui/statusbar/phone/StatusBar.java | 37 ++++++++++++ .../policy/MobileSignalController.java | 2 +- .../statusbar/policy/TelephonyIcons.java | 56 ++++++++++++------- 16 files changed, 374 insertions(+), 23 deletions(-) create mode 100644 packages/SystemUI/res/drawable/stat_sys_data_fully_connected_1x.xml create mode 100644 packages/SystemUI/res/drawable/stat_sys_data_fully_connected_3g.xml create mode 100644 packages/SystemUI/res/drawable/stat_sys_data_fully_connected_4g.xml create mode 100644 packages/SystemUI/res/drawable/stat_sys_data_fully_connected_4g_plus.xml create mode 100644 packages/SystemUI/res/drawable/stat_sys_data_fully_connected_e.xml create mode 100644 packages/SystemUI/res/drawable/stat_sys_data_fully_connected_g.xml create mode 100644 packages/SystemUI/res/drawable/stat_sys_data_fully_connected_h.xml create mode 100644 packages/SystemUI/res/drawable/stat_sys_data_fully_connected_hp.xml create mode 100644 packages/SystemUI/res/drawable/stat_sys_data_fully_connected_lte.xml create mode 100644 packages/SystemUI/res/drawable/stat_sys_data_fully_connected_lte_plus.xml diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index 5c3ac3e8a59..1bfd655cd75 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -4565,6 +4565,15 @@ public boolean validate(@Nullable String value) { private static final Validator VIBRATE_ON_DISCONNECT_VALIDATOR = BOOLEAN_VALIDATOR; + /** + * Whether to use old mobile data icons + * @hide + */ + public static final String USE_OLD_MOBILETYPE = "use_old_mobiletype"; + + private static final Validator USE_OLD_MOBILETYPE_VALIDATOR = + BOOLEAN_VALIDATOR; + /** * Settings to backup. This is here so that it's in the same place as the settings * keys and easy to update. @@ -4639,6 +4648,7 @@ public boolean validate(@Nullable String value) { VIBRATE_ON_CONNECT, VIBRATE_ON_CALLWAITING, VIBRATE_ON_DISCONNECT, + USE_OLD_MOBILETYPE, }; /** @@ -4767,6 +4777,7 @@ public boolean validate(@Nullable String value) { PRIVATE_SETTINGS.add(VIBRATE_ON_CONNECT); PRIVATE_SETTINGS.add(VIBRATE_ON_CALLWAITING); PRIVATE_SETTINGS.add(VIBRATE_ON_DISCONNECT); + PRIVATE_SETTINGS.add(USE_OLD_MOBILETYPE); } /** @@ -4869,6 +4880,7 @@ public boolean validate(@Nullable String value) { VALIDATORS.put(VIBRATE_ON_CONNECT, VIBRATE_ON_CONNECT_VALIDATOR); VALIDATORS.put(VIBRATE_ON_CALLWAITING, VIBRATE_ON_CALLWAITING_VALIDATOR); VALIDATORS.put(VIBRATE_ON_DISCONNECT, VIBRATE_ON_DISCONNECT_VALIDATOR); + VALIDATORS.put(USE_OLD_MOBILETYPE, USE_OLD_MOBILETYPE_VALIDATOR); } /** diff --git a/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_1x.xml b/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_1x.xml new file mode 100644 index 00000000000..d7463a44665 --- /dev/null +++ b/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_1x.xml @@ -0,0 +1,27 @@ + + + + + diff --git a/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_3g.xml b/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_3g.xml new file mode 100644 index 00000000000..6309b6d9903 --- /dev/null +++ b/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_3g.xml @@ -0,0 +1,27 @@ + + + + + diff --git a/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_4g.xml b/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_4g.xml new file mode 100644 index 00000000000..4067ae5b480 --- /dev/null +++ b/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_4g.xml @@ -0,0 +1,27 @@ + + + + + diff --git a/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_4g_plus.xml b/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_4g_plus.xml new file mode 100644 index 00000000000..719a6ca3b7e --- /dev/null +++ b/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_4g_plus.xml @@ -0,0 +1,30 @@ + + + + + + diff --git a/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_e.xml b/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_e.xml new file mode 100644 index 00000000000..acaa9b1c2be --- /dev/null +++ b/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_e.xml @@ -0,0 +1,24 @@ + + + + diff --git a/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_g.xml b/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_g.xml new file mode 100644 index 00000000000..7985237d8a4 --- /dev/null +++ b/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_g.xml @@ -0,0 +1,24 @@ + + + + diff --git a/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_h.xml b/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_h.xml new file mode 100644 index 00000000000..fda87612582 --- /dev/null +++ b/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_h.xml @@ -0,0 +1,24 @@ + + + + diff --git a/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_hp.xml b/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_hp.xml new file mode 100644 index 00000000000..a464e189bf3 --- /dev/null +++ b/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_hp.xml @@ -0,0 +1,27 @@ + + + + + diff --git a/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_lte.xml b/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_lte.xml new file mode 100644 index 00000000000..c08ff20c54f --- /dev/null +++ b/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_lte.xml @@ -0,0 +1,30 @@ + + + + + + diff --git a/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_lte_plus.xml b/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_lte_plus.xml new file mode 100644 index 00000000000..62159b36664 --- /dev/null +++ b/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_lte_plus.xml @@ -0,0 +1,33 @@ + + + + + + + diff --git a/packages/SystemUI/res/layout/status_bar_mobile_signal_group.xml b/packages/SystemUI/res/layout/status_bar_mobile_signal_group.xml index 23b90deb269..274daaf8697 100644 --- a/packages/SystemUI/res/layout/status_bar_mobile_signal_group.xml +++ b/packages/SystemUI/res/layout/status_bar_mobile_signal_group.xml @@ -81,6 +81,12 @@ android:layout_width="wrap_content" systemui:hasOverlappingRendering="false" /> + { @@ -793,6 +826,10 @@ public void start() { int disabledFlags2 = result.mDisabledFlags2; Dependency.get(InitController.class).addPostInitTask( () -> setUpDisableFlags(disabledFlags1, disabledFlags2)); + + mCustomSettingsObserver = new CustomSettingsObserver(mHandler); + mCustomSettingsObserver.observe(); + mCustomSettingsObserver.update(); } // ================================================================================ diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java index 69102ac50e4..552b46f27bb 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java @@ -1156,7 +1156,7 @@ public void onReceive(Context context, Intent intent) { static class MobileIconGroup extends SignalController.IconGroup { final int mDataContentDescription; // mContentDescriptionDataType - final int mDataType; + int mDataType; final boolean mIsWide; final int mQsDataType; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/TelephonyIcons.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/TelephonyIcons.java index f3a3e895925..bbc65f6e8a2 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/TelephonyIcons.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/TelephonyIcons.java @@ -17,26 +17,27 @@ package com.android.systemui.statusbar.policy; import com.android.systemui.R; +import com.android.systemui.statusbar.policy.MobileSignalController; import com.android.systemui.statusbar.policy.MobileSignalController.MobileIconGroup; import java.util.HashMap; import java.util.Map; -class TelephonyIcons { +public class TelephonyIcons { //***** Data connection icons static final int FLIGHT_MODE_ICON = R.drawable.stat_sys_airplane_mode; - static final int ICON_LTE = R.drawable.ic_lte_mobiledata; - static final int ICON_LTE_PLUS = R.drawable.ic_lte_plus_mobiledata; - static final int ICON_G = R.drawable.ic_g_mobiledata; - static final int ICON_E = R.drawable.ic_e_mobiledata; - static final int ICON_H = R.drawable.ic_h_mobiledata; - static final int ICON_H_PLUS = R.drawable.ic_h_plus_mobiledata; - static final int ICON_3G = R.drawable.ic_3g_mobiledata; - static final int ICON_4G = R.drawable.ic_4g_mobiledata; - static final int ICON_4G_PLUS = R.drawable.ic_4g_plus_mobiledata; + static int ICON_LTE = R.drawable.ic_lte_mobiledata; + static int ICON_LTE_PLUS = R.drawable.ic_lte_plus_mobiledata; + static int ICON_G = R.drawable.ic_g_mobiledata; + static int ICON_E = R.drawable.ic_e_mobiledata; + static int ICON_H = R.drawable.ic_h_mobiledata; + static int ICON_H_PLUS = R.drawable.ic_h_plus_mobiledata; + static int ICON_3G = R.drawable.ic_3g_mobiledata; + static int ICON_4G = R.drawable.ic_4g_mobiledata; + static int ICON_4G_PLUS = R.drawable.ic_4g_plus_mobiledata; static final int ICON_5G_E = R.drawable.ic_5g_e_mobiledata; - static final int ICON_1X = R.drawable.ic_1x_mobiledata; + static int ICON_1X = R.drawable.ic_1x_mobiledata; static final int ICON_5G = R.drawable.ic_5g_mobiledata; static final int ICON_5G_PLUS = R.drawable.ic_5g_plus_mobiledata; static final int ICON_5G_SA = R.drawable.ic_5g_mobiledata; @@ -56,7 +57,7 @@ class TelephonyIcons { 0, false); - static final MobileIconGroup THREE_G = new MobileIconGroup( + static MobileIconGroup THREE_G = new MobileIconGroup( "3G", null, null, @@ -91,7 +92,7 @@ class TelephonyIcons { AccessibilityContentDescriptions.PHONE_SIGNAL_STRENGTH[0], 0, 0, false); - static final MobileIconGroup E = new MobileIconGroup( + static MobileIconGroup E = new MobileIconGroup( "E", null, null, @@ -104,7 +105,7 @@ class TelephonyIcons { TelephonyIcons.ICON_E, false); - static final MobileIconGroup ONE_X = new MobileIconGroup( + static MobileIconGroup ONE_X = new MobileIconGroup( "1X", null, null, @@ -117,7 +118,7 @@ class TelephonyIcons { TelephonyIcons.ICON_1X, true); - static final MobileIconGroup G = new MobileIconGroup( + static MobileIconGroup G = new MobileIconGroup( "G", null, null, @@ -130,7 +131,7 @@ class TelephonyIcons { TelephonyIcons.ICON_G, false); - static final MobileIconGroup H = new MobileIconGroup( + static MobileIconGroup H = new MobileIconGroup( "H", null, null, @@ -143,7 +144,7 @@ class TelephonyIcons { TelephonyIcons.ICON_H, false); - static final MobileIconGroup H_PLUS = new MobileIconGroup( + static MobileIconGroup H_PLUS = new MobileIconGroup( "H+", null, null, @@ -156,7 +157,7 @@ class TelephonyIcons { TelephonyIcons.ICON_H_PLUS, false); - static final MobileIconGroup FOUR_G = new MobileIconGroup( + static MobileIconGroup FOUR_G = new MobileIconGroup( "4G", null, null, @@ -169,7 +170,7 @@ class TelephonyIcons { TelephonyIcons.ICON_4G, true); - static final MobileIconGroup FOUR_G_PLUS = new MobileIconGroup( + static MobileIconGroup FOUR_G_PLUS = new MobileIconGroup( "4G+", null, null, @@ -182,7 +183,7 @@ class TelephonyIcons { TelephonyIcons.ICON_4G_PLUS, true); - static final MobileIconGroup LTE = new MobileIconGroup( + static MobileIconGroup LTE = new MobileIconGroup( "LTE", null, null, @@ -195,7 +196,7 @@ class TelephonyIcons { TelephonyIcons.ICON_LTE, true); - static final MobileIconGroup LTE_PLUS = new MobileIconGroup( + static MobileIconGroup LTE_PLUS = new MobileIconGroup( "LTE+", null, null, @@ -354,5 +355,18 @@ class TelephonyIcons { ICON_NAME_TO_ICON.put("datadisable", DATA_DISABLED); ICON_NAME_TO_ICON.put("notdefaultdata", NOT_DEFAULT_DATA); } + + public static void updateIcons(boolean useOldStyle) { + TelephonyIcons.ICON_LTE = LTE.mDataType = useOldStyle ? R.drawable.stat_sys_data_fully_connected_lte : R.drawable.ic_lte_mobiledata; + TelephonyIcons.ICON_LTE_PLUS = LTE_PLUS.mDataType = useOldStyle ? R.drawable.stat_sys_data_fully_connected_lte_plus : R.drawable.ic_lte_plus_mobiledata; + TelephonyIcons.ICON_G = G.mDataType = useOldStyle ? R.drawable.stat_sys_data_fully_connected_g : R.drawable.ic_g_mobiledata; + TelephonyIcons.ICON_E = E.mDataType = useOldStyle ? R.drawable.stat_sys_data_fully_connected_e : R.drawable.ic_e_mobiledata; + TelephonyIcons.ICON_H = H.mDataType = useOldStyle ? R.drawable.stat_sys_data_fully_connected_h : R.drawable.ic_h_mobiledata; + TelephonyIcons.ICON_H_PLUS = H_PLUS.mDataType = useOldStyle ? R.drawable.stat_sys_data_fully_connected_hp : R.drawable.ic_h_plus_mobiledata; + TelephonyIcons.ICON_3G = THREE_G.mDataType = useOldStyle ? R.drawable.stat_sys_data_fully_connected_3g : R.drawable.ic_3g_mobiledata; + TelephonyIcons.ICON_4G = FOUR_G.mDataType = useOldStyle ? R.drawable.stat_sys_data_fully_connected_4g : R.drawable.ic_4g_mobiledata; + TelephonyIcons.ICON_4G_PLUS = FOUR_G_PLUS.mDataType = useOldStyle ? R.drawable.stat_sys_data_fully_connected_4g_plus : R.drawable.ic_4g_plus_mobiledata; + TelephonyIcons.ICON_1X = ONE_X.mDataType = useOldStyle ? R.drawable.stat_sys_data_fully_connected_1x : R.drawable.ic_1x_mobiledata; + } } From 5c3cb94e1d7554816116a3a46b731b924a5b7400 Mon Sep 17 00:00:00 2001 From: maxwen Date: Sun, 16 Sep 2018 23:20:07 +0200 Subject: [PATCH 136/240] base: SystemUI: fix visibility of mobile type icon Change-Id: I026ebde860b49c8198aac5978cd36f3c7b69f85a --- .../statusbar/StatusBarMobileView.java | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarMobileView.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarMobileView.java index 23152b2beb0..efad39ecaeb 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarMobileView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarMobileView.java @@ -63,6 +63,7 @@ public class StatusBarMobileView extends FrameLayout implements DarkReceiver, private DualToneHandler mDualToneHandler; private ImageView mVolte; + private boolean mMobileTypeStyleOld; public static StatusBarMobileView fromContext(Context context, String slot) { LayoutInflater inflater = LayoutInflater.from(context); @@ -104,10 +105,11 @@ public void getDrawingRect(Rect outRect) { } private void init() { + mMobileTypeStyleOld = StatusBar.USE_OLD_MOBILETYPE; mDualToneHandler = new DualToneHandler(getContext()); mMobileGroup = findViewById(R.id.mobile_group); mMobile = findViewById(R.id.mobile_signal); - mMobileType = findViewById(StatusBar.USE_OLD_MOBILETYPE ? R.id.mobile_type_old : R.id.mobile_type); + mMobileType = findViewById(mMobileTypeStyleOld ? R.id.mobile_type_old : R.id.mobile_type); mMobileRoaming = findViewById(R.id.mobile_roaming); mMobileRoamingSpace = findViewById(R.id.mobile_roaming_space); mIn = findViewById(R.id.mobile_in); @@ -122,9 +124,11 @@ private void init() { } private void updateMobileTypeView(boolean useOldStyle) { + mMobileTypeStyleOld = useOldStyle; + int visOld = mMobileType.getVisibility(); + mMobileType.setVisibility(View.GONE); mMobileType = findViewById(useOldStyle ? R.id.mobile_type_old : R.id.mobile_type); - findViewById(R.id.mobile_type).setVisibility(useOldStyle ? View.GONE : View.VISIBLE); - findViewById(R.id.mobile_type_old).setVisibility(useOldStyle ? View.VISIBLE : View.GONE); + mMobileType.setVisibility(visOld); } private void initDotView() { @@ -138,7 +142,6 @@ private void initDotView() { } public void applyMobileState(MobileIconState state) { - updateMobileTypeView(StatusBar.USE_OLD_MOBILETYPE); boolean requestLayout = false; if (state == null) { requestLayout = getVisibility() != View.GONE; @@ -152,6 +155,10 @@ public void applyMobileState(MobileIconState state) { requestLayout = updateState(state.copy()); } + if (mMobileTypeStyleOld != StatusBar.USE_OLD_MOBILETYPE) { + updateMobileTypeView(StatusBar.USE_OLD_MOBILETYPE); + } + if (requestLayout) { requestLayout(); } @@ -170,7 +177,9 @@ public void applyMobileState(MobileIconState state) { } private void initViewState() { - updateMobileTypeView(StatusBar.USE_OLD_MOBILETYPE); + if (mMobileTypeStyleOld != StatusBar.USE_OLD_MOBILETYPE) { + updateMobileTypeView(StatusBar.USE_OLD_MOBILETYPE); + } setContentDescription(mState.contentDescription); if (!mState.visible) { mMobileGroup.setVisibility(View.GONE); From 93e7453b570f6fcf8b77396ceee4f9c6c0d6e2cc Mon Sep 17 00:00:00 2001 From: maxwen Date: Sun, 23 Sep 2018 13:48:09 +0200 Subject: [PATCH 137/240] SystemUI: fix height of old data type icons Change-Id: I6a365f0818cae6dddc01470363a477b046d029c7 Signed-off-by: spezi77 Signed-off-by: Josh Fox (XlxFoXxlX) --- .../SystemUI/res/drawable/stat_sys_data_fully_connected_1x.xml | 2 +- .../SystemUI/res/drawable/stat_sys_data_fully_connected_3g.xml | 2 +- .../SystemUI/res/drawable/stat_sys_data_fully_connected_4g.xml | 2 +- .../res/drawable/stat_sys_data_fully_connected_4g_plus.xml | 2 +- .../SystemUI/res/drawable/stat_sys_data_fully_connected_e.xml | 2 +- .../SystemUI/res/drawable/stat_sys_data_fully_connected_g.xml | 2 +- .../SystemUI/res/drawable/stat_sys_data_fully_connected_h.xml | 2 +- .../SystemUI/res/drawable/stat_sys_data_fully_connected_hp.xml | 2 +- .../SystemUI/res/drawable/stat_sys_data_fully_connected_lte.xml | 2 +- .../res/drawable/stat_sys_data_fully_connected_lte_plus.xml | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) diff --git a/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_1x.xml b/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_1x.xml index d7463a44665..ffbd9ba49ca 100644 --- a/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_1x.xml +++ b/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_1x.xml @@ -17,7 +17,7 @@ Copyright (C) 2014 The Android Open Source Project android:width="8.5dp" android:height="17dp" android:viewportWidth="12.0" - android:viewportHeight="24.0"> + android:viewportHeight="26.0"> diff --git a/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_3g.xml b/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_3g.xml index 6309b6d9903..b0b0be5a185 100644 --- a/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_3g.xml +++ b/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_3g.xml @@ -17,7 +17,7 @@ Copyright (C) 2014 The Android Open Source Project android:width="9.208dp" android:height="17dp" android:viewportWidth="13.0" - android:viewportHeight="24.0"> + android:viewportHeight="26.0"> diff --git a/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_4g.xml b/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_4g.xml index 4067ae5b480..7069d612a84 100644 --- a/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_4g.xml +++ b/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_4g.xml @@ -17,7 +17,7 @@ Copyright (C) 2014 The Android Open Source Project android:width="8.5dp" android:height="17dp" android:viewportWidth="12.0" - android:viewportHeight="24.0"> + android:viewportHeight="26.0"> diff --git a/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_4g_plus.xml b/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_4g_plus.xml index 719a6ca3b7e..0e67a33c153 100644 --- a/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_4g_plus.xml +++ b/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_4g_plus.xml @@ -17,7 +17,7 @@ android:width="10.5dp" android:height="14.0dp" android:viewportWidth="18.0" - android:viewportHeight="24.0"> + android:viewportHeight="26.0"> diff --git a/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_e.xml b/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_e.xml index acaa9b1c2be..4709261cc4d 100644 --- a/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_e.xml +++ b/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_e.xml @@ -17,7 +17,7 @@ Copyright (C) 2014 The Android Open Source Project android:width="3.541dp" android:height="17dp" android:viewportWidth="5.0" - android:viewportHeight="24.0"> + android:viewportHeight="26.0"> diff --git a/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_g.xml b/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_g.xml index 7985237d8a4..51a2b5919cd 100644 --- a/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_g.xml +++ b/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_g.xml @@ -17,7 +17,7 @@ Copyright (C) 2014 The Android Open Source Project android:width="4.958dp" android:height="17dp" android:viewportWidth="7.0" - android:viewportHeight="24.0"> + android:viewportHeight="26.0"> diff --git a/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_h.xml b/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_h.xml index fda87612582..563016f86e1 100644 --- a/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_h.xml +++ b/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_h.xml @@ -17,7 +17,7 @@ Copyright (C) 2014 The Android Open Source Project android:width="4.25dp" android:height="17dp" android:viewportWidth="6.0" - android:viewportHeight="24.0"> + android:viewportHeight="26.0"> diff --git a/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_hp.xml b/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_hp.xml index a464e189bf3..67d65762a81 100644 --- a/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_hp.xml +++ b/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_hp.xml @@ -17,7 +17,7 @@ android:width="8.454dp" android:height="17dp" android:viewportWidth="8.454" - android:viewportHeight="17"> + android:viewportHeight="17.0"> diff --git a/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_lte.xml b/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_lte.xml index c08ff20c54f..2096b10452f 100644 --- a/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_lte.xml +++ b/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_lte.xml @@ -17,7 +17,7 @@ Copyright (C) 2014 The Android Open Source Project android:width="9.208dp" android:height="17dp" android:viewportWidth="13.0" - android:viewportHeight="24.0"> + android:viewportHeight="26.0"> diff --git a/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_lte_plus.xml b/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_lte_plus.xml index 62159b36664..5ad420f3b8d 100644 --- a/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_lte_plus.xml +++ b/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_lte_plus.xml @@ -17,7 +17,7 @@ android:width="11.08dp" android:height="14.0dp" android:viewportWidth="19.0" - android:viewportHeight="24.0"> + android:viewportHeight="26.0"> From 709d4adc9dcffdb29bc0fddaccafe79288c67545 Mon Sep 17 00:00:00 2001 From: umikaki Date: Sat, 30 Mar 2019 13:07:50 +0900 Subject: [PATCH 138/240] base: Fix old mobile signal icons * SystemUI: Fixed size of old mobile signal icon * SystemUI: Fixed padding of mobile data icon * SystemUI: Fixed padding of mobile data icon when mobile data icon is not wide type icon - Fixed padding when mobile data icon is not shown Signed-off-by: Adesh15 Change-Id: I93d7d445058284d9a16f5f11e5a55a4725481da1 --- .../res/drawable/stat_sys_data_fully_connected_1x.xml | 4 ++-- .../res/drawable/stat_sys_data_fully_connected_3g.xml | 2 +- .../res/drawable/stat_sys_data_fully_connected_4g.xml | 4 ++-- .../drawable/stat_sys_data_fully_connected_4g_plus.xml | 4 ++-- .../res/drawable/stat_sys_data_fully_connected_e.xml | 4 ++-- .../res/drawable/stat_sys_data_fully_connected_g.xml | 4 ++-- .../res/drawable/stat_sys_data_fully_connected_h.xml | 4 ++-- .../res/drawable/stat_sys_data_fully_connected_hp.xml | 4 ++-- .../res/drawable/stat_sys_data_fully_connected_lte.xml | 4 ++-- .../drawable/stat_sys_data_fully_connected_lte_plus.xml | 4 ++-- packages/SystemUI/res/values/dimens.xml | 2 +- .../android/systemui/statusbar/StatusBarMobileView.java | 8 ++++++++ 12 files changed, 28 insertions(+), 20 deletions(-) diff --git a/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_1x.xml b/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_1x.xml index ffbd9ba49ca..0e17c26d125 100644 --- a/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_1x.xml +++ b/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_1x.xml @@ -14,8 +14,8 @@ Copyright (C) 2014 The Android Open Source Project limitations under the License. --> diff --git a/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_4g.xml b/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_4g.xml index 7069d612a84..90bf3fdcd12 100644 --- a/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_4g.xml +++ b/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_4g.xml @@ -14,8 +14,8 @@ Copyright (C) 2014 The Android Open Source Project limitations under the License. --> - 2dp + 1.76dp diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarMobileView.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarMobileView.java index efad39ecaeb..ff8f953b226 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarMobileView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarMobileView.java @@ -129,6 +129,14 @@ private void updateMobileTypeView(boolean useOldStyle) { mMobileType.setVisibility(View.GONE); mMobileType = findViewById(useOldStyle ? R.id.mobile_type_old : R.id.mobile_type); mMobileType.setVisibility(visOld); + int wideTypeIconStartPadding = mContext.getResources().getDimensionPixelSize(R.dimen.wide_type_icon_start_padding); + mMobile.setPaddingRelative( + useOldStyle && + mState.typeId != 0 && + mState.typeId != R.drawable.stat_sys_data_fully_connected_g && + mState.typeId != R.drawable.stat_sys_data_fully_connected_e && + mState.typeId != R.drawable.stat_sys_data_fully_connected_h + ? wideTypeIconStartPadding : 0, 0, 0, 0); } private void initDotView() { From 2af662acc98aa71fa7d058b6fba42b248342dfe8 Mon Sep 17 00:00:00 2001 From: Ritesh Saxena Date: Wed, 19 Feb 2020 13:31:28 +0000 Subject: [PATCH 139/240] tuner: Add tunables for using pre P mobile type icon style Change-Id: I0120014c986c6b4ff8db838f9225b6452aaf9640 --- packages/SystemUI/res/values/reloaded_strings.xml | 2 ++ packages/SystemUI/res/xml/statusbar_settings.xml | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/packages/SystemUI/res/values/reloaded_strings.xml b/packages/SystemUI/res/values/reloaded_strings.xml index 286bed5aace..6ed5fc9baed 100644 --- a/packages/SystemUI/res/values/reloaded_strings.xml +++ b/packages/SystemUI/res/values/reloaded_strings.xml @@ -22,6 +22,8 @@ Statusbar icons + Use old mobile type style + Merge signal and type icons Restart diff --git a/packages/SystemUI/res/xml/statusbar_settings.xml b/packages/SystemUI/res/xml/statusbar_settings.xml index 33741a85ddf..103bc105b0e 100644 --- a/packages/SystemUI/res/xml/statusbar_settings.xml +++ b/packages/SystemUI/res/xml/statusbar_settings.xml @@ -89,4 +89,10 @@ android:summary="@string/double_tap_to_sleep_summary" android:defaultValue="false" /> + + From 12eea4f21b31c3ca38114033595680e331377ba1 Mon Sep 17 00:00:00 2001 From: Marko Man Date: Sat, 5 Oct 2019 22:44:20 +0200 Subject: [PATCH 140/240] base: Add QS pulldown with one finger Thanks to DU and their QS quick pull down topic. Change-Id: Ifbdc8c7b420f4205555d73d7e0e0da5cbad286c9 --- core/java/android/provider/Settings.java | 12 +++++++++ .../phone/NotificationPanelView.java | 27 ++++++++++++++++++- .../systemui/statusbar/phone/StatusBar.java | 10 ++++--- 3 files changed, 45 insertions(+), 4 deletions(-) diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index 1bfd655cd75..aa09a6a7ba4 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -4574,6 +4574,15 @@ public boolean validate(@Nullable String value) { private static final Validator USE_OLD_MOBILETYPE_VALIDATOR = BOOLEAN_VALIDATOR; + /** Whether to allow one finger quick settings expansion on the right side of the statusbar. + * + * @hide + */ + public static final String STATUS_BAR_QUICK_QS_PULLDOWN = "status_bar_quick_qs_pulldown"; + + private static final Validator STATUS_BAR_QUICK_QS_PULLDOWN_VALIDATOR = + ANY_INTEGER_VALIDATOR; + /** * Settings to backup. This is here so that it's in the same place as the settings * keys and easy to update. @@ -4649,6 +4658,7 @@ public boolean validate(@Nullable String value) { VIBRATE_ON_CALLWAITING, VIBRATE_ON_DISCONNECT, USE_OLD_MOBILETYPE, + STATUS_BAR_QUICK_QS_PULLDOWN, }; /** @@ -4778,6 +4788,7 @@ public boolean validate(@Nullable String value) { PRIVATE_SETTINGS.add(VIBRATE_ON_CALLWAITING); PRIVATE_SETTINGS.add(VIBRATE_ON_DISCONNECT); PRIVATE_SETTINGS.add(USE_OLD_MOBILETYPE); + PRIVATE_SETTINGS.add(STATUS_BAR_QUICK_QS_PULLDOWN); } /** @@ -4881,6 +4892,7 @@ public boolean validate(@Nullable String value) { VALIDATORS.put(VIBRATE_ON_CALLWAITING, VIBRATE_ON_CALLWAITING_VALIDATOR); VALIDATORS.put(VIBRATE_ON_DISCONNECT, VIBRATE_ON_DISCONNECT_VALIDATOR); VALIDATORS.put(USE_OLD_MOBILETYPE, USE_OLD_MOBILETYPE_VALIDATOR); + VALIDATORS.put(STATUS_BAR_QUICK_QS_PULLDOWN, STATUS_BAR_QUICK_QS_PULLDOWN_VALIDATOR); } /** 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 5adf06d4ce4..b8dd0c3472c 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java @@ -295,6 +295,8 @@ public void onKeyguardFadingAwayChanged() { private boolean mQsExpandImmediate; private boolean mTwoFingerQsExpandPossible; + private int mOneFingerQuickSettingsIntercept; + /** * If we are in a panel collapsing motion, we reset scrollY of our scroll view but still * need to take this into account in our panel height calculation. @@ -1382,7 +1384,25 @@ private boolean isOpenQsEvent(MotionEvent event) { && (event.isButtonPressed(MotionEvent.BUTTON_SECONDARY) || event.isButtonPressed(MotionEvent.BUTTON_TERTIARY)); - return twoFingerDrag || stylusButtonClickDrag || mouseButtonClickDrag; + final float w = getMeasuredWidth(); + final float x = event.getX(); + float region = w * 1.f / 3.f; // TODO overlay region fraction? + boolean showQsOverride = false; + + switch (mOneFingerQuickSettingsIntercept) { + case 1: // Right side pulldown + showQsOverride = isLayoutRtl() ? x < region : w - region < x; + break; + case 2: // Left side pulldown + showQsOverride = isLayoutRtl() ? w - region < x : x < region; + break; + case 3: // Always + showQsOverride = true; + break; + } + showQsOverride &= mBarState == StatusBarState.SHADE; + + return showQsOverride || twoFingerDrag || stylusButtonClickDrag || mouseButtonClickDrag; } private void handleQsDown(MotionEvent event) { @@ -3564,6 +3584,11 @@ public void setOnReinflationListener(Runnable onReinflationListener) { mOnReinflationListener = onReinflationListener; } + public void updateSettings() { + mOneFingerQuickSettingsIntercept = Settings.System.getInt(mContext.getContentResolver(), + Settings.System.STATUS_BAR_QUICK_QS_PULLDOWN, 0); + } + public void setPulseReason(int reason) { mNotificationStackScroller.setPulseReason(reason); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java index 8620542a0a2..c85f441ae92 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java @@ -623,9 +623,10 @@ private class CustomSettingsObserver extends ContentObserver { } void observe() { - mContext.getContentResolver().registerContentObserver( - Settings.System.getUriFor(Settings.System.USE_OLD_MOBILETYPE), - false, this); + mContext.getContentResolver().registerContentObserver(Settings.System.getUriFor( + Settings.System.USE_OLD_MOBILETYPE), false, this); + mContext.getContentResolver().registerContentObserver(Settings.System.getUriFor( + Settings.System.STATUS_BAR_QUICK_QS_PULLDOWN), false, this); } @Override @@ -640,6 +641,9 @@ public void update() { USE_OLD_MOBILETYPE = mOldMobileType; TelephonyIcons.updateIcons(USE_OLD_MOBILETYPE); } + if (mNotificationPanel != null) { + mNotificationPanel.updateSettings(); + } } } From 6db58d7c28af78492f750163b261d84acf9826bd Mon Sep 17 00:00:00 2001 From: Ritesh Saxena Date: Sun, 27 Oct 2019 12:49:09 +0000 Subject: [PATCH 141/240] tuner: Add tunables for QS Quick Pulldown Change-Id: Ic650ce94976edeb7813c790761d91c39ef007bba --- .../SystemUI/res/values/reloaded_arrays.xml | 34 +++++++++++++++++++ .../SystemUI/res/values/reloaded_strings.xml | 5 +++ .../SystemUI/res/xml/statusbar_settings.xml | 8 +++++ 3 files changed, 47 insertions(+) create mode 100644 packages/SystemUI/res/values/reloaded_arrays.xml diff --git a/packages/SystemUI/res/values/reloaded_arrays.xml b/packages/SystemUI/res/values/reloaded_arrays.xml new file mode 100644 index 00000000000..d4bd5785a47 --- /dev/null +++ b/packages/SystemUI/res/values/reloaded_arrays.xml @@ -0,0 +1,34 @@ + + + + + + + @string/status_bar_quick_qs_pulldown_off + @string/status_bar_quick_qs_pulldown_right + @string/status_bar_quick_qs_pulldown_left + @string/status_bar_quick_qs_pulldown_always + + + + 0 + 1 + 2 + 3 + + + diff --git a/packages/SystemUI/res/values/reloaded_strings.xml b/packages/SystemUI/res/values/reloaded_strings.xml index 6ed5fc9baed..cc380ea2134 100644 --- a/packages/SystemUI/res/values/reloaded_strings.xml +++ b/packages/SystemUI/res/values/reloaded_strings.xml @@ -24,6 +24,11 @@ Statusbar icons Use old mobile type style Merge signal and type icons + QS Quick pulldown + Off + Left + Right + Always Restart diff --git a/packages/SystemUI/res/xml/statusbar_settings.xml b/packages/SystemUI/res/xml/statusbar_settings.xml index 103bc105b0e..35a3513a1bc 100644 --- a/packages/SystemUI/res/xml/statusbar_settings.xml +++ b/packages/SystemUI/res/xml/statusbar_settings.xml @@ -89,6 +89,14 @@ android:summary="@string/double_tap_to_sleep_summary" android:defaultValue="false" /> + + Date: Sat, 5 Oct 2019 22:44:48 +0200 Subject: [PATCH 142/240] base: allow disabling quick settings on secure lock screens inspired by SlimRoms/frameworks_base@b76f8af DirtyUnicorns/android_frameworks_base@3a4d3be xyyx: adapted to Oreo Change-Id: I90736961fd8023b06b544e9a96a43be4202707e4 Signed-off-by: enzoo96 --- core/java/android/provider/Settings.java | 13 +++++++++ .../com/android/systemui/plugins/qs/QS.java | 1 + .../com/android/systemui/qs/QSFragment.java | 15 +++++++++-- .../phone/NotificationPanelView.java | 27 ++++++++++++++++--- .../systemui/statusbar/phone/StatusBar.java | 2 ++ 5 files changed, 52 insertions(+), 6 deletions(-) diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index aa09a6a7ba4..962c05df68b 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -4583,6 +4583,16 @@ public boolean validate(@Nullable String value) { private static final Validator STATUS_BAR_QUICK_QS_PULLDOWN_VALIDATOR = ANY_INTEGER_VALIDATOR; + /** + * Disable expanding quick settings on secure lock screens + * + * @hide + */ + public static final String LOCK_QS_DISABLED = "lockscreen_qs_disabled"; + + private static final Validator LOCK_QS_DISABLED_VALIDATOR = + BOOLEAN_VALIDATOR; + /** * Settings to backup. This is here so that it's in the same place as the settings * keys and easy to update. @@ -4659,6 +4669,7 @@ public boolean validate(@Nullable String value) { VIBRATE_ON_DISCONNECT, USE_OLD_MOBILETYPE, STATUS_BAR_QUICK_QS_PULLDOWN, + LOCK_QS_DISABLED, }; /** @@ -4789,6 +4800,7 @@ public boolean validate(@Nullable String value) { PRIVATE_SETTINGS.add(VIBRATE_ON_DISCONNECT); PRIVATE_SETTINGS.add(USE_OLD_MOBILETYPE); PRIVATE_SETTINGS.add(STATUS_BAR_QUICK_QS_PULLDOWN); + PRIVATE_SETTINGS.add(LOCK_QS_DISABLED); } /** @@ -4893,6 +4905,7 @@ public boolean validate(@Nullable String value) { VALIDATORS.put(VIBRATE_ON_DISCONNECT, VIBRATE_ON_DISCONNECT_VALIDATOR); VALIDATORS.put(USE_OLD_MOBILETYPE, USE_OLD_MOBILETYPE_VALIDATOR); VALIDATORS.put(STATUS_BAR_QUICK_QS_PULLDOWN, STATUS_BAR_QUICK_QS_PULLDOWN_VALIDATOR); + VALIDATORS.put(LOCK_QS_DISABLED, LOCK_QS_DISABLED_VALIDATOR); } /** diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QS.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QS.java index 85a9fec859f..cc150f770b3 100644 --- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QS.java +++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QS.java @@ -57,6 +57,7 @@ default void setShowCollapsedOnKeyguard(boolean showCollapsedOnKeyguard) {} void setQsExpansion(float qsExpansionFraction, float headerTranslation); void setHeaderListening(boolean listening); void notifyCustomizeChanged(); + void setSecureExpandDisabled(boolean value); void setContainer(ViewGroup container); void setExpandClickListener(OnClickListener onClickListener); diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java b/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java index 0a3b43a78f1..c5e75527dd5 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java @@ -106,6 +106,9 @@ public QSFragment(RemoteInputQuickSettingsDisabler remoteInputQsDisabler, mStatusBarStateController = statusBarStateController; } + // custom additions + private boolean mSecureExpandDisabled; + @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) { @@ -361,7 +364,7 @@ public void setQsExpansion(float expansion, float headerTranslation) { boolean onKeyguardAndExpanded = isKeyguardShowing() && !mShowCollapsedOnKeyguard; if (!mHeaderAnimating && !headerWillBeAnimating()) { getView().setTranslationY( - onKeyguardAndExpanded + (onKeyguardAndExpanded || mSecureExpandDisabled) ? translationScaleY * mHeader.getHeight() : headerTranslation); } @@ -408,6 +411,9 @@ private boolean headerWillBeAnimating() { @Override public void animateHeaderSlidingIn(long delay) { + if (mSecureExpandDisabled) { + return; + } if (DEBUG) Log.d(TAG, "animateHeaderSlidingIn"); // If the QS is already expanded we don't need to slide in the header as it's already // visible. @@ -490,7 +496,12 @@ public void setHeightOverride(int desiredHeight) { @Override public int getQsMinExpansionHeight() { - return mHeader.getHeight(); + return mSecureExpandDisabled ? 0 : mHeader.getHeight(); + } + + @Override + public void setSecureExpandDisabled(boolean value) { + mSecureExpandDisabled = value; } @Override 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 b8dd0c3472c..cded3db0d0c 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java @@ -63,6 +63,7 @@ import com.android.internal.annotations.VisibleForTesting; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; +import com.android.internal.widget.LockPatternUtils; import com.android.keyguard.KeyguardClockSwitch; import com.android.keyguard.KeyguardStatusView; import com.android.keyguard.KeyguardUpdateMonitor; @@ -334,6 +335,10 @@ public void onKeyguardFadingAwayChanged() { private FalsingManager mFalsingManager; private String mLastCameraLaunchSource = KeyguardBottomAreaView.CAMERA_LAUNCH_SOURCE_AFFORDANCE; + // Custom additions + private boolean mQsSecureExpandDisabled; + private LockPatternUtils mLockPatternUtils; + private Runnable mHeadsUpExistenceChangedRunnable = new Runnable() { @Override public void run() { @@ -466,6 +471,7 @@ public NotificationPanelView(@Named(VIEW_CONTEXT) Context context, AttributeSet setWillNotDraw(!DEBUG); mInjectionInflationController = injectionInflationController; mFalsingManager = falsingManager; + mLockPatternUtils = new LockPatternUtils(context); mPowerManager = context.getSystemService(PowerManager.class); mWakeUpCoordinator = coordinator; mAccessibilityManager = context.getSystemService(AccessibilityManager.class); @@ -950,7 +956,7 @@ public void animateToFullShade(long delay) { } public void setQsExpansionEnabled(boolean qsExpansionEnabled) { - mQsExpansionEnabled = qsExpansionEnabled; + mQsExpansionEnabled = qsExpansionEnabled && !isQsSecureExpandDisabled(); if (mQs == null) return; mQs.setHeaderClickable(qsExpansionEnabled); } @@ -1402,7 +1408,8 @@ private boolean isOpenQsEvent(MotionEvent event) { } showQsOverride &= mBarState == StatusBarState.SHADE; - return showQsOverride || twoFingerDrag || stylusButtonClickDrag || mouseButtonClickDrag; + return !isQsSecureExpandDisabled() && (showQsOverride || twoFingerDrag + || stylusButtonClickDrag || mouseButtonClickDrag); } private void handleQsDown(MotionEvent event) { @@ -1637,6 +1644,9 @@ public void onStateChanged(int statusBarState) { mBarState = statusBarState; mKeyguardShowing = keyguardShowing; + if (mQs != null) { + mQs.setSecureExpandDisabled(isQsSecureExpandDisabled()); + } if (oldState == StatusBarState.KEYGUARD && (goingToFullShade || statusBarState == StatusBarState.SHADE_LOCKED)) { @@ -3584,13 +3594,22 @@ public void setOnReinflationListener(Runnable onReinflationListener) { mOnReinflationListener = onReinflationListener; } + public void setPulseReason(int reason) { + mNotificationStackScroller.setPulseReason(reason); + } + public void updateSettings() { mOneFingerQuickSettingsIntercept = Settings.System.getInt(mContext.getContentResolver(), Settings.System.STATUS_BAR_QUICK_QS_PULLDOWN, 0); + mQsSecureExpandDisabled = Settings.System.getInt(mContext.getContentResolver(), + Settings.System.LOCK_QS_DISABLED, 0) != 0; } - public void setPulseReason(int reason) { - mNotificationStackScroller.setPulseReason(reason); + private boolean isQsSecureExpandDisabled() { + final boolean keyguardOrShadeShowing = mBarState == StatusBarState.KEYGUARD + || mBarState == StatusBarState.SHADE_LOCKED; + return mLockPatternUtils.isSecure(KeyguardUpdateMonitor.getCurrentUser()) && mQsSecureExpandDisabled && + keyguardOrShadeShowing; } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java index c85f441ae92..bf0424d2d94 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java @@ -627,6 +627,8 @@ void observe() { Settings.System.USE_OLD_MOBILETYPE), false, this); mContext.getContentResolver().registerContentObserver(Settings.System.getUriFor( Settings.System.STATUS_BAR_QUICK_QS_PULLDOWN), false, this); + mContext.getContentResolver().registerContentObserver(Settings.System.getUriFor( + Settings.System.LOCK_QS_DISABLED), false, this); } @Override From 1bb7a657b58f3490e5cb02a20525a3a29107bb97 Mon Sep 17 00:00:00 2001 From: maxwen Date: Tue, 8 Oct 2019 16:18:45 +0200 Subject: [PATCH 143/240] base: fix disabling quick settings on secure lock screens Change-Id: I50a75c3ddd32423dda1e71ba1d508d8ad6de4bc6 --- .../android/systemui/statusbar/phone/NotificationPanelView.java | 1 + 1 file changed, 1 insertion(+) 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 cded3db0d0c..5795cd5c4ca 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java @@ -3319,6 +3319,7 @@ public void onFragmentViewCreated(String tag, Fragment fragment) { mQs.setHeaderClickable(mQsExpansionEnabled); updateQSPulseExpansion(); mQs.setOverscrolling(mStackScrollerOverscrolling); + mQs.setSecureExpandDisabled(isQsSecureExpandDisabled()); // recompute internal state when qspanel height changes mQs.getView().addOnLayoutChangeListener( From 143c478174ce407522cf07f772cc86478a0bb39f Mon Sep 17 00:00:00 2001 From: Marko Man Date: Wed, 9 Oct 2019 10:06:25 +0200 Subject: [PATCH 144/240] SystemUI: Fix disable QS pulldown on secure lockscreens Change-Id: Ide95a72ff7b271476a8b3f8fbf163db8b7187b01 --- .../statusbar/phone/NotificationPanelView.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) 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 5795cd5c4ca..2d2275fa665 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java @@ -956,7 +956,7 @@ public void animateToFullShade(long delay) { } public void setQsExpansionEnabled(boolean qsExpansionEnabled) { - mQsExpansionEnabled = qsExpansionEnabled && !isQsSecureExpandDisabled(); + mQsExpansionEnabled = qsExpansionEnabled; if (mQs == null) return; mQs.setHeaderClickable(qsExpansionEnabled); } @@ -1018,7 +1018,7 @@ public void animateCloseQs(boolean animateAway) { } public void expandWithQs() { - if (mQsExpansionEnabled) { + if (mQsExpansionEnabled && !isQsSecureExpandDisabled()) { mQsExpandImmediate = true; mNotificationStackScroller.setShouldShowShelfOnly(true); } @@ -1328,7 +1328,7 @@ private boolean handleQsTouch(MotionEvent event) { final int action = event.getActionMasked(); if (action == MotionEvent.ACTION_DOWN && getExpandedFraction() == 1f && mBarState != StatusBarState.KEYGUARD && !mQsExpanded - && mQsExpansionEnabled) { + && mQsExpansionEnabled && !isQsSecureExpandDisabled()) { // Down in the empty area while fully expanded - go to QS. mQsTracking = true; @@ -1564,7 +1564,7 @@ private int getFalsingThreshold() { @Override public void onOverscrollTopChanged(float amount, boolean isRubberbanded) { cancelQsAnimation(); - if (!mQsExpansionEnabled) { + if (!mQsExpansionEnabled || isQsSecureExpandDisabled()) { amount = 0f; } float rounded = amount >= 1f ? amount : 0f; @@ -2096,7 +2096,7 @@ public void onAnimationEnd(Animator animation) { * @return Whether we should intercept a gesture to open Quick Settings. */ private boolean shouldQuickSettingsIntercept(float x, float y, float yDiff) { - if (!mQsExpansionEnabled || mCollapsedOnDown + if (!mQsExpansionEnabled || mCollapsedOnDown || isQsSecureExpandDisabled() || (mKeyguardShowing && mKeyguardBypassController.getBypassEnabled())) { return false; } From 3c6f934d0ad57477e95501c0aae9b78d039da1c4 Mon Sep 17 00:00:00 2001 From: maxwen Date: Sat, 9 Nov 2019 23:53:10 +0100 Subject: [PATCH 145/240] SystemUI: block open doors for disabled secure lock qs expand Change-Id: I4a4084e5fe8fb2a0989a367f2b4234a9ef60b7f7 --- .../systemui/statusbar/phone/NotificationPanelView.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) 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 2d2275fa665..8fe8aa229e8 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java @@ -1351,7 +1351,7 @@ private boolean handleQsTouch(MotionEvent event) { mConflictingQsExpansionGesture = false; } if (action == MotionEvent.ACTION_DOWN && isFullyCollapsed() - && mQsExpansionEnabled) { + && mQsExpansionEnabled && !isQsSecureExpandDisabled()) { mTwoFingerQsExpandPossible = true; } if (mTwoFingerQsExpandPossible && isOpenQsEvent(event) @@ -1580,8 +1580,8 @@ public void flingTopOverscroll(float velocity, boolean open) { mLastOverscroll = 0f; mQsExpansionFromOverscroll = false; setQsExpansion(mQsExpansionHeight); - flingSettings(!mQsExpansionEnabled && open ? 0f : velocity, - open && mQsExpansionEnabled ? FLING_EXPAND : FLING_COLLAPSE, + flingSettings((!mQsExpansionEnabled || isQsSecureExpandDisabled()) && open ? 0f : velocity, + open && (mQsExpansionEnabled && !isQsSecureExpandDisabled()) ? FLING_EXPAND : FLING_COLLAPSE, new Runnable() { @Override public void run() { @@ -2602,7 +2602,7 @@ public void onClick(View v) { if (mQsExpanded) { flingSettings(0 /* vel */, FLING_COLLAPSE, null /* onFinishRunnable */, true /* isClick */); - } else if (mQsExpansionEnabled) { + } else if (mQsExpansionEnabled && !isQsSecureExpandDisabled()) { mLockscreenGestureLogger.write(MetricsEvent.ACTION_SHADE_QS_TAP, 0, 0); flingSettings(0 /* vel */, FLING_EXPAND, null /* onFinishRunnable */, true /* isClick */); From fd1952d3a8b0f5f2eb78dee4f870b468d8ea1d0d Mon Sep 17 00:00:00 2001 From: Ritesh Saxena Date: Sun, 27 Oct 2019 14:05:30 +0000 Subject: [PATCH 146/240] tuner: Add tunables for disabling quick settings on secure lock screens Change-Id: Iaefcb0219c01e9146382f68e9d8510493cfc4be3 --- packages/SystemUI/res/values/reloaded_strings.xml | 2 ++ packages/SystemUI/res/xml/lockscreen_settings.xml | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/packages/SystemUI/res/values/reloaded_strings.xml b/packages/SystemUI/res/values/reloaded_strings.xml index cc380ea2134..b684b6b936c 100644 --- a/packages/SystemUI/res/values/reloaded_strings.xml +++ b/packages/SystemUI/res/values/reloaded_strings.xml @@ -52,6 +52,8 @@ Lockscreen clock Disable power menu when locked Disable power menu on secure lock screens + Disable quick settings when locked + Disable expanding quick settings on secure lock screens Fingerprint authentication diff --git a/packages/SystemUI/res/xml/lockscreen_settings.xml b/packages/SystemUI/res/xml/lockscreen_settings.xml index 886dfd342b5..d3d324b9fa3 100644 --- a/packages/SystemUI/res/xml/lockscreen_settings.xml +++ b/packages/SystemUI/res/xml/lockscreen_settings.xml @@ -48,6 +48,12 @@ android:summary="@string/double_tap_sleep_lockscreen_summary" android:defaultValue="false" /> + + Date: Wed, 15 Aug 2018 17:29:02 -0700 Subject: [PATCH 147/240] SystemUI: Remove data tile dialog Change-Id: Ib5e80e49795ce4413519e854d3f10195eab52e16 --- .../src/com/android/systemui/qs/tiles/CellularTile.java | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) 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 aef1d77b034..ba42fce207f 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java @@ -107,11 +107,7 @@ protected void handleClick() { if (getState().state == Tile.STATE_UNAVAILABLE) { return; } - if (mDataController.isMobileDataEnabled()) { - maybeShowDisableDialog(); - } else { - mDataController.setMobileDataEnabled(true); - } + mDataController.setMobileDataEnabled(!mDataController.isMobileDataEnabled()); } private void maybeShowDisableDialog() { From ee55233d0491ce3342cfb5fa865d8608d39f37d8 Mon Sep 17 00:00:00 2001 From: Danny Baumann Date: Mon, 12 Sep 2016 11:38:58 +0200 Subject: [PATCH 148/240] Allow adjusting screen density to smaller sizes. Accomodates for 6" 1080x1920 devices that run at 480dpi by default, but those physical resolution is ~360dpi. Change-Id: I82973b097612f1e7d26af9fdbb3ac2ae28c6b93b Signed-off-by: Joe Maples --- .../res/values/reloaded_strings.xml | 25 +++++++++++++++++++ .../display/DisplayDensityUtils.java | 6 +++-- 2 files changed, 29 insertions(+), 2 deletions(-) create mode 100644 packages/SettingsLib/res/values/reloaded_strings.xml diff --git a/packages/SettingsLib/res/values/reloaded_strings.xml b/packages/SettingsLib/res/values/reloaded_strings.xml new file mode 100644 index 00000000000..eb9dc9ce5f6 --- /dev/null +++ b/packages/SettingsLib/res/values/reloaded_strings.xml @@ -0,0 +1,25 @@ + + + + + + Smaller + + + Smallest + + diff --git a/packages/SettingsLib/src/com/android/settingslib/display/DisplayDensityUtils.java b/packages/SettingsLib/src/com/android/settingslib/display/DisplayDensityUtils.java index e0ca1ab0c07..39eac5d6c91 100644 --- a/packages/SettingsLib/src/com/android/settingslib/display/DisplayDensityUtils.java +++ b/packages/SettingsLib/src/com/android/settingslib/display/DisplayDensityUtils.java @@ -42,7 +42,7 @@ public class DisplayDensityUtils { private static final float MIN_SCALE_INTERVAL = 0.09f; /** Minimum density scale. This is available on all devices. */ - private static final float MIN_SCALE = 0.85f; + private static final float MIN_SCALE = 0.70f; /** Maximum density scale. The actual scale used depends on the device. */ private static final float MAX_SCALE = 1.50f; @@ -58,7 +58,9 @@ public class DisplayDensityUtils { * largest. */ private static final int[] SUMMARIES_SMALLER = new int[] { - R.string.screen_zoom_summary_small + R.string.screen_zoom_summary_small, + R.string.screen_zoom_summary_smaller, + R.string.screen_zoom_summary_smallest }; /** From 9e7c456fdf0e224f9ef91cf5e99b982d7c8e1013 Mon Sep 17 00:00:00 2001 From: Pranav Vashi Date: Thu, 22 Nov 2018 16:48:29 +0100 Subject: [PATCH 149/240] base: Allow using 4G icon instead LTE Change-Id: I7ba6f730fc5f16abdd0633224e9eaeff3674d850 --- core/java/android/provider/Settings.java | 12 +++++++ .../SystemUI/res/values/reloaded_strings.xml | 2 ++ .../SystemUI/res/xml/statusbar_settings.xml | 6 ++++ .../policy/MobileSignalController.java | 35 ++++++++++++++++++- 4 files changed, 54 insertions(+), 1 deletion(-) diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index 962c05df68b..a0f7b60c107 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -4593,6 +4593,15 @@ public boolean validate(@Nullable String value) { private static final Validator LOCK_QS_DISABLED_VALIDATOR = BOOLEAN_VALIDATOR; + /** + * Whether to display 4G icon instead LTE + * @hide + */ + public static final String SHOW_FOURG_ICON = "show_fourg_icon"; + + private static final Validator SHOW_FOURG_ICON_VALIDATOR = + BOOLEAN_VALIDATOR; + /** * Settings to backup. This is here so that it's in the same place as the settings * keys and easy to update. @@ -4670,6 +4679,7 @@ public boolean validate(@Nullable String value) { USE_OLD_MOBILETYPE, STATUS_BAR_QUICK_QS_PULLDOWN, LOCK_QS_DISABLED, + SHOW_FOURG_ICON, }; /** @@ -4801,6 +4811,7 @@ public boolean validate(@Nullable String value) { PRIVATE_SETTINGS.add(USE_OLD_MOBILETYPE); PRIVATE_SETTINGS.add(STATUS_BAR_QUICK_QS_PULLDOWN); PRIVATE_SETTINGS.add(LOCK_QS_DISABLED); + PRIVATE_SETTINGS.add(SHOW_FOURG_ICON); } /** @@ -4906,6 +4917,7 @@ public boolean validate(@Nullable String value) { VALIDATORS.put(USE_OLD_MOBILETYPE, USE_OLD_MOBILETYPE_VALIDATOR); VALIDATORS.put(STATUS_BAR_QUICK_QS_PULLDOWN, STATUS_BAR_QUICK_QS_PULLDOWN_VALIDATOR); VALIDATORS.put(LOCK_QS_DISABLED, LOCK_QS_DISABLED_VALIDATOR); + VALIDATORS.put(SHOW_FOURG_ICON, SHOW_FOURG_ICON_VALIDATOR); } /** diff --git a/packages/SystemUI/res/values/reloaded_strings.xml b/packages/SystemUI/res/values/reloaded_strings.xml index b684b6b936c..28580ee938c 100644 --- a/packages/SystemUI/res/values/reloaded_strings.xml +++ b/packages/SystemUI/res/values/reloaded_strings.xml @@ -29,6 +29,8 @@ Left Right Always + Show 4G icon + Display 4G icon instead of LTE icon Restart diff --git a/packages/SystemUI/res/xml/statusbar_settings.xml b/packages/SystemUI/res/xml/statusbar_settings.xml index 35a3513a1bc..4b265d131a2 100644 --- a/packages/SystemUI/res/xml/statusbar_settings.xml +++ b/packages/SystemUI/res/xml/statusbar_settings.xml @@ -103,4 +103,10 @@ android:summary="@string/use_old_mobiletype_summary" android:defaultValue="false" /> + + diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java index 552b46f27bb..037b61b6de9 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java @@ -25,6 +25,7 @@ import android.os.Handler; import android.os.Looper; import android.os.Message; +import android.provider.Settings; import android.provider.Settings.Global; import android.telephony.CellSignalStrengthNr; import android.telephony.ims.ImsMmTelManager; @@ -99,6 +100,7 @@ public class MobileSignalController extends SignalController< private MobileIconGroup mDefaultIcons; private Config mConfig; private final Handler mDisplayGraceHandler; + private boolean mShow4gForLte; @VisibleForTesting boolean mInflateSignalStrengths = false; @VisibleForTesting @@ -187,6 +189,37 @@ public void handleMessage(Message msg) { } } }; + Handler mHandler = new Handler(); + SettingsObserver settingsObserver = new SettingsObserver(mHandler); + settingsObserver.observe(); + } + + class SettingsObserver extends ContentObserver { + + SettingsObserver(Handler handler) { + super(handler); + } + + void observe() { + mContext.getContentResolver().registerContentObserver(Settings.System.getUriFor( + Settings.System.SHOW_FOURG_ICON), false, this); + updateSettings(); + } + + /* + * @hide + */ + @Override + public void onChange(boolean selfChange) { + updateSettings(); + } + } + + private void updateSettings() { + mShow4gForLte = Settings.System.getInt(mContext.getContentResolver(), + Settings.System.SHOW_FOURG_ICON, 0) == 1; + mapIconSets(); + updateTelephony(); } public void setConfiguration(Config config) { @@ -302,7 +335,7 @@ private void mapIconSets() { mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_HSPA, hGroup); mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_HSPAP, hPlusGroup); - if (mConfig.show4gForLte) { + if (mShow4gForLte) { mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_LTE, TelephonyIcons.FOUR_G); if (mConfig.hideLtePlus) { mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_LTE_CA, From 6428343db5f720c62c41d8d4801c663bfc5380dc Mon Sep 17 00:00:00 2001 From: SagarMakhar Date: Sat, 6 Apr 2019 08:21:09 +0000 Subject: [PATCH 150/240] base: Add VoLTE icon toggle Change-Id: I28a981517213509c0a40a815c6e40c695fea6c68 --- core/java/android/provider/Settings.java | 12 ++++++++++++ packages/SystemUI/res/values/config_qti.xml | 2 +- packages/SystemUI/res/values/reloaded_strings.xml | 2 ++ packages/SystemUI/res/xml/statusbar_settings.xml | 6 ++++++ .../statusbar/policy/MobileSignalController.java | 7 ++++++- 5 files changed, 27 insertions(+), 2 deletions(-) diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index a0f7b60c107..adefe7b15d5 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -4602,6 +4602,15 @@ public boolean validate(@Nullable String value) { private static final Validator SHOW_FOURG_ICON_VALIDATOR = BOOLEAN_VALIDATOR; + /** + * Whether to show VoLTE icon or not + * @hide + */ + public static final String SHOW_VOLTE_ICON = "show_volte_icon"; + + private static final Validator SHOW_VOLTE_ICON_VALIDATOR = + BOOLEAN_VALIDATOR; + /** * Settings to backup. This is here so that it's in the same place as the settings * keys and easy to update. @@ -4680,6 +4689,7 @@ public boolean validate(@Nullable String value) { STATUS_BAR_QUICK_QS_PULLDOWN, LOCK_QS_DISABLED, SHOW_FOURG_ICON, + SHOW_VOLTE_ICON, }; /** @@ -4812,6 +4822,7 @@ public boolean validate(@Nullable String value) { PRIVATE_SETTINGS.add(STATUS_BAR_QUICK_QS_PULLDOWN); PRIVATE_SETTINGS.add(LOCK_QS_DISABLED); PRIVATE_SETTINGS.add(SHOW_FOURG_ICON); + PRIVATE_SETTINGS.add(SHOW_VOLTE_ICON); } /** @@ -4918,6 +4929,7 @@ public boolean validate(@Nullable String value) { VALIDATORS.put(STATUS_BAR_QUICK_QS_PULLDOWN, STATUS_BAR_QUICK_QS_PULLDOWN_VALIDATOR); VALIDATORS.put(LOCK_QS_DISABLED, LOCK_QS_DISABLED_VALIDATOR); VALIDATORS.put(SHOW_FOURG_ICON, SHOW_FOURG_ICON_VALIDATOR); + VALIDATORS.put(SHOW_VOLTE_ICON, SHOW_VOLTE_ICON_VALIDATOR); } /** diff --git a/packages/SystemUI/res/values/config_qti.xml b/packages/SystemUI/res/values/config_qti.xml index 82c1a477c62..4731969b559 100644 --- a/packages/SystemUI/res/values/config_qti.xml +++ b/packages/SystemUI/res/values/config_qti.xml @@ -34,5 +34,5 @@ false false false - false + true diff --git a/packages/SystemUI/res/values/reloaded_strings.xml b/packages/SystemUI/res/values/reloaded_strings.xml index 28580ee938c..ed40172b3fc 100644 --- a/packages/SystemUI/res/values/reloaded_strings.xml +++ b/packages/SystemUI/res/values/reloaded_strings.xml @@ -31,6 +31,8 @@ Always Show 4G icon Display 4G icon instead of LTE icon + Show HD icon + Display VoLTE icon Restart diff --git a/packages/SystemUI/res/xml/statusbar_settings.xml b/packages/SystemUI/res/xml/statusbar_settings.xml index 4b265d131a2..2dae9231bad 100644 --- a/packages/SystemUI/res/xml/statusbar_settings.xml +++ b/packages/SystemUI/res/xml/statusbar_settings.xml @@ -109,4 +109,10 @@ android:summary="@string/show_fourg_icon_summary" android:defaultValue="false" /> + + diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java index 037b61b6de9..1d24b40e728 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java @@ -101,6 +101,7 @@ public class MobileSignalController extends SignalController< private Config mConfig; private final Handler mDisplayGraceHandler; private boolean mShow4gForLte; + private boolean mVoLTEicon; @VisibleForTesting boolean mInflateSignalStrengths = false; @VisibleForTesting @@ -203,6 +204,8 @@ class SettingsObserver extends ContentObserver { void observe() { mContext.getContentResolver().registerContentObserver(Settings.System.getUriFor( Settings.System.SHOW_FOURG_ICON), false, this); + mContext.getContentResolver().registerContentObserver(Settings.System.getUriFor( + Settings.System.SHOW_VOLTE_ICON), false, this); updateSettings(); } @@ -218,6 +221,8 @@ public void onChange(boolean selfChange) { private void updateSettings() { mShow4gForLte = Settings.System.getInt(mContext.getContentResolver(), Settings.System.SHOW_FOURG_ICON, 0) == 1; + mVoLTEicon = Settings.System.getInt(mContext.getContentResolver(), + Settings.System.SHOW_VOLTE_ICON, 0) == 1; mapIconSets(); updateTelephony(); } @@ -411,7 +416,7 @@ private int getVolteResId() { int resId = 0; int voiceNetTye = getVoiceNetworkType(); if ( (mCurrentState.voiceCapable || mCurrentState.videoCapable) - && mCurrentState.imsRegistered ) { + && mCurrentState.imsRegistered && mVoLTEicon) { resId = R.drawable.ic_volte; }else if ( (mDataNetType == TelephonyManager.NETWORK_TYPE_LTE || mDataNetType == TelephonyManager.NETWORK_TYPE_LTE_CA) From ccec1bd1c981a69209cd20712b9d53323b2a8958 Mon Sep 17 00:00:00 2001 From: Adarsh-MR Date: Fri, 19 Oct 2018 11:51:38 +0000 Subject: [PATCH 151/240] base: Fix VoLTE icon color on Light statusbar Change-Id: I96803c61311e8fafe8a395c0afe03c9a33d07feb Signed-off-by: Adarsh-MR --- .../src/com/android/systemui/statusbar/StatusBarMobileView.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarMobileView.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarMobileView.java index ff8f953b226..c8f418fcf9d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarMobileView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarMobileView.java @@ -276,6 +276,7 @@ public void onDarkChanged(Rect area, float darkIntensity, int tint) { mMobileType.setImageTintList(color); mVolte.setImageTintList(color); mMobileRoaming.setImageTintList(color); + mVolte.setImageTintList(color); mDotView.setDecorColor(tint); mDotView.setIconColor(tint, false); } @@ -302,6 +303,7 @@ public void setStaticDrawableColor(int color) { mMobileType.setImageTintList(list); mVolte.setImageTintList(list); mMobileRoaming.setImageTintList(list); + mVolte.setImageTintList(list); mDotView.setDecorColor(color); } From f5667eb4531a3d132ec7864546f2448668992dcb Mon Sep 17 00:00:00 2001 From: Adarsh-MR Date: Fri, 19 Oct 2018 18:16:26 +0000 Subject: [PATCH 152/240] base: SystemUI: new HD (VoLTE) icon * preview: https://i.imgur.com/csVJ8g2.jpg Change-Id: I11aaebd4dd9dc4277d64be6058b5612b61be5248 Signed-off-by: Adarsh-MR --- packages/SystemUI/res/drawable/ic_volte.xml | 25 ++++++++------------- 1 file changed, 9 insertions(+), 16 deletions(-) diff --git a/packages/SystemUI/res/drawable/ic_volte.xml b/packages/SystemUI/res/drawable/ic_volte.xml index e4c5d6df5be..5aaa15e464d 100644 --- a/packages/SystemUI/res/drawable/ic_volte.xml +++ b/packages/SystemUI/res/drawable/ic_volte.xml @@ -1,5 +1,6 @@ - - - - - + android:viewportWidth="17" + android:viewportHeight="17" + android:width="17dp" + android:height="17dp"> + \ No newline at end of file From e6f14be426ae295b920c553af4f14027e507a8be Mon Sep 17 00:00:00 2001 From: Ritesh Saxena Date: Mon, 28 Oct 2019 13:42:03 +0000 Subject: [PATCH 153/240] tuner: Add tunable for showing battery percentage Change-Id: I21b023800c3948fe1ba84673816332e146ec51aa --- packages/SystemUI/res/values/reloaded_strings.xml | 2 ++ packages/SystemUI/res/xml/statusbar_settings.xml | 11 ++++++----- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/packages/SystemUI/res/values/reloaded_strings.xml b/packages/SystemUI/res/values/reloaded_strings.xml index ed40172b3fc..ee1915ac3a9 100644 --- a/packages/SystemUI/res/values/reloaded_strings.xml +++ b/packages/SystemUI/res/values/reloaded_strings.xml @@ -33,6 +33,8 @@ Display 4G icon instead of LTE icon Show HD icon Display VoLTE icon + Battery percentage + Show battery percentage in status bar Restart diff --git a/packages/SystemUI/res/xml/statusbar_settings.xml b/packages/SystemUI/res/xml/statusbar_settings.xml index 2dae9231bad..9fd1aa49fa7 100644 --- a/packages/SystemUI/res/xml/statusbar_settings.xml +++ b/packages/SystemUI/res/xml/statusbar_settings.xml @@ -62,11 +62,6 @@ android:key="airplane" android:title="@string/status_bar_airplane" /> - - @@ -83,6 +78,12 @@ + + Date: Tue, 12 Nov 2019 05:42:27 +0000 Subject: [PATCH 154/240] base: Improve dark theme [1/2] Change-Id: I3628bee19d929f095d625af4846246e62da77c2e --- core/res/res/values-night/values.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/res/res/values-night/values.xml b/core/res/res/values-night/values.xml index 4e6b712f1f5..0297236216b 100644 --- a/core/res/res/values-night/values.xml +++ b/core/res/res/values-night/values.xml @@ -30,7 +30,7 @@ @color/black - @color/material_grey_800 + @color/material_grey_900