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