From bee0735954b4d48da886907cea86e9f1c256b11c Mon Sep 17 00:00:00 2001 From: Chris Wailes Date: Tue, 28 Jan 2020 17:26:56 -0800 Subject: [PATCH 001/157] Purge unused native memory before Zygote fork events This CL causes the Zygote to purge unused native memory before fork events. This results in a decrease in the RSS before a fork, which decreases false sharing between parent and child, and results in less private dirty memory in the child when allocations and deallocations begin to dirty bookkeeping data on pages in the anon:libc_malloc memory region. The result of these changes is a negligible change to application startup times, the reduction of usap32 process private dirty memory by 40 KiB and usap64 process private dirty memory by 128 KiB. Application RSS and private dirty memory usage (for Calendar) was reduced by 804 KiB and 624 KiB respectively. Test: Launched Calendar 500 times Change-Id: I52f72a5a02182a9e2748f7f87b45665059d9891a Merged-In: I52f72a5a02182a9e2748f7f87b45665059d9891a Signed-off-by: mydongistiny --- core/jni/com_android_internal_os_Zygote.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/core/jni/com_android_internal_os_Zygote.cpp b/core/jni/com_android_internal_os_Zygote.cpp index 82c27f02ba872..ae051ddf116a6 100644 --- a/core/jni/com_android_internal_os_Zygote.cpp +++ b/core/jni/com_android_internal_os_Zygote.cpp @@ -933,6 +933,13 @@ static pid_t ForkCommon(JNIEnv* env, bool is_system_server, android_fdsan_error_level fdsan_error_level = android_fdsan_get_error_level(); + // Purge unused native memory in an attempt to reduce the amount of false + // sharing with the child process. By reducing the size of the libc_malloc + // region shared with the child process we reduce the number of pages that + // transition to the private-dirty state when malloc adjusts the meta-data + // on each of the pages it is managing after the fork. + mallopt(M_PURGE, 0); + pid_t pid = fork(); if (pid == 0) { From f7e3a0abf1498aaae5313a008af7117061f41a96 Mon Sep 17 00:00:00 2001 From: Chris Wailes Date: Wed, 4 Mar 2020 13:40:28 -0800 Subject: [PATCH 002/157] Teaches the ProcessCpuTracker about USAPs This CL updates the ProcessCpuTracer.getName method to force a refresh of the process name when the current state indicates that it was named either 'usap32' or 'usap64'. This will prevent false attribution of process statistics to system service processes. Bug: 146614089 Test: Treehugger Change-Id: Ieca4715b7aeb44ef7d1ec98773b25bdfa0a9fc6b Signed-off-by: mydongistiny --- core/java/com/android/internal/os/ProcessCpuTracker.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/core/java/com/android/internal/os/ProcessCpuTracker.java b/core/java/com/android/internal/os/ProcessCpuTracker.java index dcf8d285eca96..83b00ec33fd2a 100644 --- a/core/java/com/android/internal/os/ProcessCpuTracker.java +++ b/core/java/com/android/internal/os/ProcessCpuTracker.java @@ -878,8 +878,11 @@ private void printProcessCPU(PrintWriter pw, String prefix, int pid, String labe private void getName(Stats st, String cmdlineFile) { String newName = st.name; - if (st.name == null || st.name.equals("app_process") - || st.name.equals("")) { + if (st.name == null + || st.name.equals("app_process") + || st.name.equals("") + || st.name.equals("usap32") + || st.name.equals("usap64")) { String cmdName = ProcStatsUtil.readTerminatedProcFile(cmdlineFile, (byte) '\0'); if (cmdName != null && cmdName.length() > 1) { newName = cmdName; From e200b31aa858c376b95eb9d50a587d71b0c38b08 Mon Sep 17 00:00:00 2001 From: Andreas Gampe Date: Thu, 25 Jul 2019 14:49:53 -0700 Subject: [PATCH 003/157] BGDexopt: Clean up ordering Downgrade apps before optimizing. Also, Remove spurious error logging in BackgroundDexOptService The old logic created a log entry indicating an error when the actual result was success. Test: m Change-Id: I6a361ff63158a7c1187d65c4f9520498d6740747 Signed-off-by: Pranav Vashi --- .../server/pm/BackgroundDexOptService.java | 84 ++++++++++++------- 1 file changed, 54 insertions(+), 30 deletions(-) diff --git a/services/core/java/com/android/server/pm/BackgroundDexOptService.java b/services/core/java/com/android/server/pm/BackgroundDexOptService.java index ad9ac12324378..984f22f014655 100644 --- a/services/core/java/com/android/server/pm/BackgroundDexOptService.java +++ b/services/core/java/com/android/server/pm/BackgroundDexOptService.java @@ -254,9 +254,16 @@ private boolean runIdleOptimization(final JobParameters jobParams, @Override public void run() { int result = idleOptimization(pm, pkgs, BackgroundDexOptService.this); - if (result != OPTIMIZE_ABORT_BY_JOB_SCHEDULER) { + if (result == OPTIMIZE_PROCESSED) { + Log.i(TAG, "Idle optimizations completed."); + } else if (result == OPTIMIZE_ABORT_NO_SPACE_LEFT) { Log.w(TAG, "Idle optimizations aborted because of space constraints."); - // If we didn't abort we ran to completion (or stopped because of space). + } else if (result == OPTIMIZE_ABORT_BY_JOB_SCHEDULER) { + Log.w(TAG, "Idle optimizations aborted by job scheduler."); + } else { + Log.w(TAG, "Idle optimizations ended with unexpected code: " + result); + } + if (result != OPTIMIZE_ABORT_BY_JOB_SCHEDULER) { // Abandon our timeslice and do not reschedule. jobFinished(jobParams, /* reschedule */ false); } @@ -338,38 +345,55 @@ private long getPackageSize(PackageManagerService pm, String pkg) { private int optimizePackages(PackageManagerService pm, ArraySet pkgs, long lowStorageThreshold, boolean isForPrimaryDex) { ArraySet updatedPackages = new ArraySet<>(); - Set unusedPackages = pm.getUnusedPackages(mDowngradeUnusedAppsThresholdInMillis); - Log.d(TAG, "Unsused Packages " + String.join(",", unusedPackages)); - // Only downgrade apps when space is low on device. - // Threshold is selected above the lowStorageThreshold so that we can pro-actively clean - // up disk before user hits the actual lowStorageThreshold. - final long lowStorageThresholdForDowngrade = LOW_THRESHOLD_MULTIPLIER_FOR_DOWNGRADE * - lowStorageThreshold; - boolean shouldDowngrade = shouldDowngrade(lowStorageThresholdForDowngrade); - Log.d(TAG, "Should Downgrade " + shouldDowngrade); - boolean dex_opt_performed = false; - for (String pkg : pkgs) { - int abort_code = abortIdleOptimizations(lowStorageThreshold); - if (abort_code == OPTIMIZE_ABORT_BY_JOB_SCHEDULER) { - return abort_code; - } - // Downgrade unused packages. - if (unusedPackages.contains(pkg) && shouldDowngrade) { - dex_opt_performed = downgradePackage(pm, pkg, isForPrimaryDex); - } else { - if (abort_code == OPTIMIZE_ABORT_NO_SPACE_LEFT) { - // can't dexopt because of low space. - continue; + + try { + // Only downgrade apps when space is low on device. + // Threshold is selected above the lowStorageThreshold so that we can pro-actively clean + // up disk before user hits the actual lowStorageThreshold. + final long lowStorageThresholdForDowngrade = LOW_THRESHOLD_MULTIPLIER_FOR_DOWNGRADE + * lowStorageThreshold; + boolean shouldDowngrade = shouldDowngrade(lowStorageThresholdForDowngrade); + Log.d(TAG, "Should Downgrade " + shouldDowngrade); + if (shouldDowngrade) { + Set unusedPackages = + pm.getUnusedPackages(mDowngradeUnusedAppsThresholdInMillis); + Log.d(TAG, "Unsused Packages " + String.join(",", unusedPackages)); + + for (String pkg : unusedPackages) { + int abortCode = abortIdleOptimizations(/*lowStorageThreshold*/ -1); + if (abortCode != OPTIMIZE_CONTINUE) { + // Should be aborted by the scheduler. + return abortCode; + } + if (downgradePackage(pm, pkg, isForPrimaryDex)) { + updatedPackages.add(pkg); + } + } + + if (!unusedPackages.isEmpty()) { + pkgs = new ArraySet<>(pkgs); + pkgs.removeAll(unusedPackages); } - dex_opt_performed = optimizePackage(pm, pkg, isForPrimaryDex); } - if (dex_opt_performed) { - updatedPackages.add(pkg); + + for (String pkg : pkgs) { + int abortCode = abortIdleOptimizations(lowStorageThreshold); + if (abortCode != OPTIMIZE_CONTINUE) { + // Either aborted by the scheduler or no space left. + return abortCode; + } + + boolean dexOptPerformed = optimizePackage(pm, pkg, isForPrimaryDex); + if (dexOptPerformed) { + updatedPackages.add(pkg); + } } - } - notifyPinService(updatedPackages); - return OPTIMIZE_PROCESSED; + return OPTIMIZE_PROCESSED; + } finally { + // Always let the pinner service know about changes. + notifyPinService(updatedPackages); + } } From 65378dba338ca297df0d2fdc767662e2fb448dea Mon Sep 17 00:00:00 2001 From: Chris Wailes Date: Tue, 23 Apr 2019 14:26:13 -0700 Subject: [PATCH 004/157] Change USAP name to application name as soon as possible. This patch changes the location where the process's name is changed to that of the application being launched. It also attempts to use the package name if the "nice name" is missing. Test: m & flash & boot Bug: 146614089 Change-Id: Id3a3d0b2b66d31c48274f8a986e86e9ed1d28f34 Merged-In: Id3a3d0b2b66d31c48274f8a986e86e9ed1d28f34 --- core/java/com/android/internal/os/Zygote.java | 48 +++++++++++-------- .../android/internal/os/ZygoteConnection.java | 4 +- 2 files changed, 28 insertions(+), 24 deletions(-) diff --git a/core/java/com/android/internal/os/Zygote.java b/core/java/com/android/internal/os/Zygote.java index 2ba9cf1961e99..ae9a74c9d35e8 100644 --- a/core/java/com/android/internal/os/Zygote.java +++ b/core/java/com/android/internal/os/Zygote.java @@ -49,9 +49,9 @@ /** @hide */ public final class Zygote { /* - * Bit values for "runtimeFlags" argument. The definitions are duplicated - * in the native code. - */ + * Bit values for "runtimeFlags" argument. The definitions are duplicated + * in the native code. + */ /** enable debugging over JDWP */ public static final int DEBUG_ENABLE_JDWP = 1; @@ -467,7 +467,7 @@ static FileDescriptor getUsapPoolEventFD() { * application that is passed up from usapMain. */ static Runnable forkUsap(LocalServerSocket usapPoolSocket, - int[] sessionSocketRawFDs) { + int[] sessionSocketRawFDs) { FileDescriptor[] pipeFDs = null; try { @@ -491,8 +491,8 @@ static Runnable forkUsap(LocalServerSocket usapPoolSocket, } private static native int nativeForkUsap(int readPipeFD, - int writePipeFD, - int[] sessionSocketRawFDs); + int writePipeFD, + int[] sessionSocketRawFDs); /** * This function is used by unspecialized app processes to wait for specialization requests from @@ -503,7 +503,7 @@ private static native int nativeForkUsap(int readPipeFD, * @return A runnable oject representing the new application. */ private static Runnable usapMain(LocalServerSocket usapPoolSocket, - FileDescriptor writePipe) { + FileDescriptor writePipe) { final int pid = Process.myPid(); Process.setArgV0(Process.is64Bit() ? "usap64" : "usap32"); @@ -553,6 +553,7 @@ private static Runnable usapMain(LocalServerSocket usapPoolSocket, try { // SIGTERM is blocked on loop exit. This prevents a USAP that is specializing from // being killed during a pool flush. + setAppProcessName(args, "USAP"); applyUidSecurityPolicy(args, peerCredentials); applyDebuggerSystemProperty(args); @@ -616,19 +617,14 @@ private static Runnable usapMain(LocalServerSocket usapPoolSocket, args.mRuntimeFlags, rlimits, args.mMountExternal, args.mSeInfo, args.mNiceName, args.mStartChildZygote, args.mInstructionSet, args.mAppDataDir); - disableExecuteOnly(args.mTargetSdkVersion); - if (args.mNiceName != null) { - Process.setArgV0(args.mNiceName); - } - // End of the postFork event. Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); return ZygoteInit.zygoteInit(args.mTargetSdkVersion, - args.mRemainingArgs, - null /* classLoader */); + args.mRemainingArgs, + null /* classLoader */); } finally { // Unblock SIGTERM to restore the process to default behavior. unblockSigTerm(); @@ -647,6 +643,16 @@ private static void unblockSigTerm() { private static native void nativeUnblockSigTerm(); + static void setAppProcessName(ZygoteArguments args, String loggingTag) { + if (args.mNiceName != null) { + Process.setArgV0(args.mNiceName); + } else if (args.mPackageName != null) { + Process.setArgV0(args.mPackageName); + } else { + Log.w(loggingTag, "Unable to set package name."); + } + } + private static final String USAP_ERROR_PREFIX = "Invalid command to USAP: "; /** @@ -669,7 +675,7 @@ private static void validateUsapCommand(ZygoteArguments args) { throw new IllegalArgumentException(USAP_ERROR_PREFIX + "--start-child-zygote"); } else if (args.mApiBlacklistExemptions != null) { throw new IllegalArgumentException( - USAP_ERROR_PREFIX + "--set-api-blacklist-exemptions"); + USAP_ERROR_PREFIX + "--set-api-blacklist-exemptions"); } else if (args.mHiddenApiAccessLogSampleRate != -1) { throw new IllegalArgumentException( USAP_ERROR_PREFIX + "--hidden-api-log-sampling-rate="); @@ -680,8 +686,8 @@ private static void validateUsapCommand(ZygoteArguments args) { throw new IllegalArgumentException(USAP_ERROR_PREFIX + "--invoke-with"); } else if (args.mPermittedCapabilities != 0 || args.mEffectiveCapabilities != 0) { throw new ZygoteSecurityException("Client may not specify capabilities: " - + "permitted=0x" + Long.toHexString(args.mPermittedCapabilities) - + ", effective=0x" + Long.toHexString(args.mEffectiveCapabilities)); + + "permitted=0x" + Long.toHexString(args.mPermittedCapabilities) + + ", effective=0x" + Long.toHexString(args.mEffectiveCapabilities)); } } @@ -738,7 +744,7 @@ protected static void applyUidSecurityPolicy(ZygoteArguments args, Credentials p if (uidRestricted && args.mUidSpecified && (args.mUid < Process.SYSTEM_UID)) { throw new ZygoteSecurityException( "System UID may not launch process with UID < " - + Process.SYSTEM_UID); + + Process.SYSTEM_UID); } } @@ -788,8 +794,8 @@ protected static void applyInvokeWithSecurityPolicy(ZygoteArguments args, Creden if (args.mInvokeWith != null && peerUid != 0 && (args.mRuntimeFlags & Zygote.DEBUG_ENABLE_JDWP) == 0) { throw new ZygoteSecurityException("Peer is permitted to specify an " - + "explicit invoke-with wrapper command only for debuggable " - + "applications."); + + "explicit invoke-with wrapper command only for debuggable " + + "applications."); } } @@ -872,7 +878,7 @@ static LocalServerSocket createManagedSocketFromInitSocket(String socketName) { return new LocalServerSocket(fd); } catch (IOException ex) { throw new RuntimeException( - "Error building socket from file descriptor: " + fileDesc, ex); + "Error building socket from file descriptor: " + fileDesc, ex); } } diff --git a/core/java/com/android/internal/os/ZygoteConnection.java b/core/java/com/android/internal/os/ZygoteConnection.java index e556dd4d8243a..8a05b9eee21e8 100644 --- a/core/java/com/android/internal/os/ZygoteConnection.java +++ b/core/java/com/android/internal/os/ZygoteConnection.java @@ -580,9 +580,7 @@ private Runnable handleChildProc(ZygoteArguments parsedArgs, FileDescriptor[] de } } - if (parsedArgs.mNiceName != null) { - Process.setArgV0(parsedArgs.mNiceName); - } + Zygote.setAppProcessName(parsedArgs, TAG); // End of the postFork event. Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); From a3ad2546d21247388b9d0957d1b5187fe8d73bde Mon Sep 17 00:00:00 2001 From: Chris Wailes Date: Thu, 9 May 2019 17:11:00 -0700 Subject: [PATCH 005/157] Adjusts the USAP pool refill mechanism. This patch adjusts the USAP pool refill mechanism so that it is less disruptive to launching applications. Refill events are now delayed by several (3) seconds if delaying wouldn't cause the pool to be below the minimum population size. This patch also adjusts the process priorities for the USAPs and other processes spawned from the Zygote so that they behave better in the context they are spawned in. Bug: 131362095 Bug: 146614089 Test: booted & launched apps & checked logs Change-Id: I7328f304c9b744cfdbfbdbe522a5f9aeea5233bb Merged-In: I7328f304c9b744cfdbfbdbe522a5f9aeea5233bb --- core/java/com/android/internal/os/Zygote.java | 47 ++- .../android/internal/os/ZygoteConnection.java | 2 +- .../com/android/internal/os/ZygoteInit.java | 5 +- .../com/android/internal/os/ZygoteServer.java | 326 +++++++++++------- core/jni/com_android_internal_os_Zygote.cpp | 43 ++- 5 files changed, 275 insertions(+), 148 deletions(-) diff --git a/core/java/com/android/internal/os/Zygote.java b/core/java/com/android/internal/os/Zygote.java index ae9a74c9d35e8..9333c470b95d8 100644 --- a/core/java/com/android/internal/os/Zygote.java +++ b/core/java/com/android/internal/os/Zygote.java @@ -172,6 +172,11 @@ public final class Zygote { */ public static final int SOCKET_BUFFER_SIZE = 256; + /** + * @hide for internal use only + */ + private static final int PRIORITY_MAX = -20; + /** a prototype instance for a future List.toArray() */ protected static final int[][] INT_ARRAY_2D = new int[0][0]; @@ -236,8 +241,7 @@ public static int forkAndSpecialize(int uid, int gid, int[] gids, int runtimeFla int[] fdsToIgnore, boolean startChildZygote, String instructionSet, String appDataDir, int targetSdkVersion) { ZygoteHooks.preFork(); - // Resets nice priority for zygote process. - resetNicePriority(); + int pid = nativeForkAndSpecialize( uid, gid, gids, runtimeFlags, rlimits, mountExternal, seInfo, niceName, fdsToClose, fdsToIgnore, startChildZygote, instructionSet, appDataDir); @@ -249,6 +253,7 @@ public static int forkAndSpecialize(int uid, int gid, int[] gids, int runtimeFla // Note that this event ends at the end of handleChildProc, Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "PostFork"); } + ZygoteHooks.postForkCommon(); return pid; } @@ -335,15 +340,16 @@ private static native void nativeSpecializeAppProcess(int uid, int gid, int[] gi public static int forkSystemServer(int uid, int gid, int[] gids, int runtimeFlags, int[][] rlimits, long permittedCapabilities, long effectiveCapabilities) { ZygoteHooks.preFork(); - // Resets nice priority for zygote process. - resetNicePriority(); + int pid = nativeForkSystemServer( uid, gid, gids, runtimeFlags, rlimits, permittedCapabilities, effectiveCapabilities); + // Enable tracing as soon as we enter the system_server. if (pid == 0) { Trace.setTracingEnabled(true, runtimeFlags); } + ZygoteHooks.postForkCommon(); return pid; } @@ -461,13 +467,16 @@ static FileDescriptor getUsapPoolEventFD() { /** * Fork a new unspecialized app process from the zygote * + * @param usapPoolSocket The server socket the USAP will call accept on * @param sessionSocketRawFDs Anonymous session sockets that are currently open + * @param isPriorityFork Value controlling the process priority level until accept is called * @return In the Zygote process this function will always return null; in unspecialized app * processes this function will return a Runnable object representing the new * application that is passed up from usapMain. */ static Runnable forkUsap(LocalServerSocket usapPoolSocket, - int[] sessionSocketRawFDs) { + int[] sessionSocketRawFDs, + boolean isPriorityFork) { FileDescriptor[] pipeFDs = null; try { @@ -477,7 +486,8 @@ static Runnable forkUsap(LocalServerSocket usapPoolSocket, } int pid = - nativeForkUsap(pipeFDs[0].getInt$(), pipeFDs[1].getInt$(), sessionSocketRawFDs); + nativeForkUsap(pipeFDs[0].getInt$(), pipeFDs[1].getInt$(), + sessionSocketRawFDs, isPriorityFork); if (pid == 0) { IoUtils.closeQuietly(pipeFDs[0]); @@ -491,8 +501,9 @@ static Runnable forkUsap(LocalServerSocket usapPoolSocket, } private static native int nativeForkUsap(int readPipeFD, - int writePipeFD, - int[] sessionSocketRawFDs); + int writePipeFD, + int[] sessionSocketRawFDs, + boolean isPriorityFork); /** * This function is used by unspecialized app processes to wait for specialization requests from @@ -512,6 +523,11 @@ private static Runnable usapMain(LocalServerSocket usapPoolSocket, Credentials peerCredentials = null; ZygoteArguments args = null; + // Change the priority to max before calling accept so we can respond to new specialization + // requests as quickly as possible. This will be reverted to the default priority in the + // native specialization code. + boostUsapPriority(); + while (true) { try { sessionSocket = usapPoolSocket.accept(); @@ -643,6 +659,12 @@ private static void unblockSigTerm() { private static native void nativeUnblockSigTerm(); + private static void boostUsapPriority() { + nativeBoostUsapPriority(); + } + + private static native void nativeBoostUsapPriority(); + static void setAppProcessName(ZygoteArguments args, String loggingTag) { if (args.mNiceName != null) { Process.setArgV0(args.mNiceName); @@ -892,15 +914,6 @@ private static void callPostForkChildHooks(int runtimeFlags, boolean isSystemSer ZygoteHooks.postForkChild(runtimeFlags, isSystemServer, isZygote, instructionSet); } - /** - * Resets the calling thread priority to the default value (Thread.NORM_PRIORITY - * or nice value 0). This updates both the priority value in java.lang.Thread and - * the nice value (setpriority). - */ - static void resetNicePriority() { - Thread.currentThread().setPriority(Thread.NORM_PRIORITY); - } - /** * Executes "/system/bin/sh -c <command>" using the exec() system call. * This method throws a runtime exception if exec() failed, otherwise, this diff --git a/core/java/com/android/internal/os/ZygoteConnection.java b/core/java/com/android/internal/os/ZygoteConnection.java index 8a05b9eee21e8..c58266d06d151 100644 --- a/core/java/com/android/internal/os/ZygoteConnection.java +++ b/core/java/com/android/internal/os/ZygoteConnection.java @@ -347,7 +347,7 @@ private Runnable stateChangeWithUsapPoolReset(ZygoteServer zygoteServer, if (zygoteServer.isUsapPoolEnabled()) { Runnable fpResult = zygoteServer.fillUsapPool( - new int[]{mSocket.getFileDescriptor().getInt$()}); + new int[]{mSocket.getFileDescriptor().getInt$()}, false); if (fpResult != null) { zygoteServer.setForkChild(); diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java index 2d7ce1a1c49cb..7c50806d2e29f 100644 --- a/core/java/com/android/internal/os/ZygoteInit.java +++ b/core/java/com/android/internal/os/ZygoteInit.java @@ -804,6 +804,9 @@ private static long posixCapabilitiesAsBits(int... capabilities) { public static void main(String argv[]) { ZygoteServer zygoteServer = null; + // Set the initial thread priority to the "normal" value. + Thread.currentThread().setPriority(Thread.NORM_PRIORITY); + // Mark zygote start. This ensures that thread creation will throw // an error. ZygoteHooks.startZygoteNoThreadCreation(); @@ -863,8 +866,6 @@ public static void main(String argv[]) { EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END, SystemClock.uptimeMillis()); bootTimingsTraceLog.traceEnd(); // ZygotePreload - } else { - Zygote.resetNicePriority(); } // Do an initial gc to clean up after startup diff --git a/core/java/com/android/internal/os/ZygoteServer.java b/core/java/com/android/internal/os/ZygoteServer.java index 5d1911b9c29a2..bbbcbfcca858d 100644 --- a/core/java/com/android/internal/os/ZygoteServer.java +++ b/core/java/com/android/internal/os/ZygoteServer.java @@ -66,6 +66,15 @@ class ZygoteServer { /** The default value used for the USAP_POOL_SIZE_MIN device property */ private static final String USAP_POOL_SIZE_MIN_DEFAULT = "1"; + /** + * Number of milliseconds to delay before refilling the pool if it hasn't reached its + * minimum value. + */ + private static final int USAP_REFILL_DELAY_MS = 3000; + + /** The "not a timestamp" value for the refill delay timestamp mechanism. */ + private static final int INVALID_TIMESTAMP = -1; + /** * Indicates if this Zygote server can support a unspecialized app process pool. Currently this * should only be true for the primary and secondary Zygotes, and not the App Zygotes or the @@ -131,6 +140,12 @@ class ZygoteServer { */ private int mUsapPoolRefillThreshold = 0; + private enum UsapPoolRefillAction { + DELAYED, + IMMEDIATE, + NONE + } + ZygoteServer() { mUsapPoolEventFD = null; mZygoteSocket = null; @@ -293,9 +308,16 @@ private void fetchUsapPoolPolicyPropsWithMinInterval() { } } + private void fetchUsapPoolPolicyPropsIfUnfetched() { + if (mIsFirstPropertyCheck) { + mIsFirstPropertyCheck = false; + fetchUsapPoolPolicyProps(); + } + } + /** - * Checks to see if the current policy says that pool should be refilled, and spawns new USAPs - * if necessary. + * Refill the USAP Pool to the appropriate level, determined by whether this is a priority + * refill event or not. * * @param sessionSocketRawFDs Anonymous session sockets that are currently open * @return In the Zygote process this function will always return null; in unspecialized app @@ -303,39 +325,46 @@ private void fetchUsapPoolPolicyPropsWithMinInterval() { * application that is passed up from usapMain. */ - Runnable fillUsapPool(int[] sessionSocketRawFDs) { + Runnable fillUsapPool(int[] sessionSocketRawFDs, boolean isPriorityRefill) { Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Zygote:FillUsapPool"); // Ensure that the pool properties have been fetched. - fetchUsapPoolPolicyPropsWithMinInterval(); + fetchUsapPoolPolicyPropsIfUnfetched(); int usapPoolCount = Zygote.getUsapPoolCount(); - int numUsapsToSpawn = mUsapPoolSizeMax - usapPoolCount; + int numUsapsToSpawn; - if (usapPoolCount < mUsapPoolSizeMin - || numUsapsToSpawn >= mUsapPoolRefillThreshold) { + if (isPriorityRefill) { + // Refill to min + numUsapsToSpawn = mUsapPoolSizeMin - usapPoolCount; - // Disable some VM functionality and reset some system values - // before forking. - ZygoteHooks.preFork(); - Zygote.resetNicePriority(); + Log.i("zygote", + "Priority USAP Pool refill. New USAPs: " + numUsapsToSpawn); + } else { + // Refill up to max + numUsapsToSpawn = mUsapPoolSizeMax - usapPoolCount; - while (usapPoolCount++ < mUsapPoolSizeMax) { - Runnable caller = Zygote.forkUsap(mUsapPoolSocket, sessionSocketRawFDs); + Log.i("zygote", + "Delayed USAP Pool refill. New USAPs: " + numUsapsToSpawn); + } - if (caller != null) { - return caller; - } - } + // Disable some VM functionality and reset some system values + // before forking. + ZygoteHooks.preFork(); - // Re-enable runtime services for the Zygote. Services for unspecialized app process - // are re-enabled in specializeAppProcess. - ZygoteHooks.postForkCommon(); + while (--numUsapsToSpawn >= 0) { + Runnable caller = + Zygote.forkUsap(mUsapPoolSocket, sessionSocketRawFDs, isPriorityRefill); - Log.i("zygote", - "Filled the USAP pool. New USAPs: " + numUsapsToSpawn); + if (caller != null) { + return caller; + } } + // Re-enable runtime services for the Zygote. Services for unspecialized app process + // are re-enabled in specializeAppProcess. + ZygoteHooks.postForkCommon(); + Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); return null; @@ -358,7 +387,7 @@ Runnable setUsapPoolStatus(boolean newStatus, LocalSocket sessionSocket) { mUsapPoolEnabled = newStatus; if (newStatus) { - return fillUsapPool(new int[]{ sessionSocket.getFileDescriptor().getInt$() }); + return fillUsapPool(new int[]{ sessionSocket.getFileDescriptor().getInt$() }, false); } else { Zygote.emptyUsapPool(); return null; @@ -377,6 +406,8 @@ Runnable runSelectLoop(String abiList) { socketFDs.add(mZygoteSocket.getFileDescriptor()); peers.add(null); + long usapPoolRefillTriggerTimestamp = INVALID_TIMESTAMP; + while (true) { fetchUsapPoolPolicyPropsWithMinInterval(); @@ -428,140 +459,193 @@ Runnable runSelectLoop(String abiList) { } } + int pollTimeoutMs; + + if (usapPoolRefillTriggerTimestamp == INVALID_TIMESTAMP) { + pollTimeoutMs = -1; + } else { + int elapsedTimeMs = + (int) (System.currentTimeMillis() - usapPoolRefillTriggerTimestamp); + + if (elapsedTimeMs >= USAP_REFILL_DELAY_MS) { + // Normalize the poll timeout value when the time between one poll event and the + // next pushes us over the delay value. This prevents poll receiving a 0 + // timeout value, which would result in it returning immediately. + pollTimeoutMs = -1; + } else { + pollTimeoutMs = USAP_REFILL_DELAY_MS - elapsedTimeMs; + } + } + + int pollReturnValue; try { - Os.poll(pollFDs, -1); + pollReturnValue = Os.poll(pollFDs, pollTimeoutMs); } catch (ErrnoException ex) { throw new RuntimeException("poll failed", ex); } - boolean usapPoolFDRead = false; - - while (--pollIndex >= 0) { - if ((pollFDs[pollIndex].revents & POLLIN) == 0) { - continue; - } - - if (pollIndex == 0) { - // Zygote server socket + UsapPoolRefillAction usapPoolRefillAction = UsapPoolRefillAction.NONE; + if (pollReturnValue == 0) { + // The poll timeout has been exceeded. This only occurs when we have finished the + // USAP pool refill delay period. - ZygoteConnection newPeer = acceptCommandPeer(abiList); - peers.add(newPeer); - socketFDs.add(newPeer.getFileDescriptor()); + usapPoolRefillTriggerTimestamp = INVALID_TIMESTAMP; + usapPoolRefillAction = UsapPoolRefillAction.DELAYED; - } else if (pollIndex < usapPoolEventFDIndex) { - // Session socket accepted from the Zygote server socket + } else { + boolean usapPoolFDRead = false; - try { - ZygoteConnection connection = peers.get(pollIndex); - final Runnable command = connection.processOneCommand(this); + while (--pollIndex >= 0) { + if ((pollFDs[pollIndex].revents & POLLIN) == 0) { + continue; + } - // TODO (chriswailes): Is this extra check necessary? - if (mIsForkChild) { - // We're in the child. We should always have a command to run at this - // stage if processOneCommand hasn't called "exec". - if (command == null) { - throw new IllegalStateException("command == null"); + if (pollIndex == 0) { + // Zygote server socket + + ZygoteConnection newPeer = acceptCommandPeer(abiList); + peers.add(newPeer); + socketFDs.add(newPeer.getFileDescriptor()); + + } else if (pollIndex < usapPoolEventFDIndex) { + // Session socket accepted from the Zygote server socket + + try { + ZygoteConnection connection = peers.get(pollIndex); + final Runnable command = connection.processOneCommand(this); + + // TODO (chriswailes): Is this extra check necessary? + if (mIsForkChild) { + // We're in the child. We should always have a command to run at + // this stage if processOneCommand hasn't called "exec". + if (command == null) { + throw new IllegalStateException("command == null"); + } + + return command; + } else { + // We're in the server - we should never have any commands to run. + if (command != null) { + throw new IllegalStateException("command != null"); + } + + // We don't know whether the remote side of the socket was closed or + // not until we attempt to read from it from processOneCommand. This + // shows up as a regular POLLIN event in our regular processing + // loop. + if (connection.isClosedByPeer()) { + connection.closeSocket(); + peers.remove(pollIndex); + socketFDs.remove(pollIndex); + } } + } catch (Exception e) { + if (!mIsForkChild) { + // We're in the server so any exception here is one that has taken + // place pre-fork while processing commands or reading / writing + // from the control socket. Make a loud noise about any such + // exceptions so that we know exactly what failed and why. - return command; - } else { - // We're in the server - we should never have any commands to run. - if (command != null) { - throw new IllegalStateException("command != null"); - } + Slog.e(TAG, "Exception executing zygote command: ", e); + + // Make sure the socket is closed so that the other end knows + // immediately that something has gone wrong and doesn't time out + // waiting for a response. + ZygoteConnection conn = peers.remove(pollIndex); + conn.closeSocket(); - // We don't know whether the remote side of the socket was closed or - // not until we attempt to read from it from processOneCommand. This - // shows up as a regular POLLIN event in our regular processing loop. - if (connection.isClosedByPeer()) { - connection.closeSocket(); - peers.remove(pollIndex); socketFDs.remove(pollIndex); + } else { + // We're in the child so any exception caught here has happened post + // fork and before we execute ActivityThread.main (or any other + // main() method). Log the details of the exception and bring down + // the process. + Log.e(TAG, "Caught post-fork exception in child process.", e); + throw e; } + } finally { + // Reset the child flag, in the event that the child process is a child- + // zygote. The flag will not be consulted this loop pass after the + // Runnable is returned. + mIsForkChild = false; } - } catch (Exception e) { - if (!mIsForkChild) { - // We're in the server so any exception here is one that has taken place - // pre-fork while processing commands or reading / writing from the - // control socket. Make a loud noise about any such exceptions so that - // we know exactly what failed and why. - - Slog.e(TAG, "Exception executing zygote command: ", e); - - // Make sure the socket is closed so that the other end knows - // immediately that something has gone wrong and doesn't time out - // waiting for a response. - ZygoteConnection conn = peers.remove(pollIndex); - conn.closeSocket(); - - socketFDs.remove(pollIndex); - } else { - // We're in the child so any exception caught here has happened post - // fork and before we execute ActivityThread.main (or any other main() - // method). Log the details of the exception and bring down the process. - Log.e(TAG, "Caught post-fork exception in child process.", e); - throw e; - } - } finally { - // Reset the child flag, in the event that the child process is a child- - // zygote. The flag will not be consulted this loop pass after the Runnable - // is returned. - mIsForkChild = false; - } - } else { - // Either the USAP pool event FD or a USAP reporting pipe. - - // If this is the event FD the payload will be the number of USAPs removed. - // If this is a reporting pipe FD the payload will be the PID of the USAP - // that was just specialized. - long messagePayload = -1; - try { - byte[] buffer = new byte[Zygote.USAP_MANAGEMENT_MESSAGE_BYTES]; - int readBytes = Os.read(pollFDs[pollIndex].fd, buffer, 0, buffer.length); - - if (readBytes == Zygote.USAP_MANAGEMENT_MESSAGE_BYTES) { - DataInputStream inputStream = - new DataInputStream(new ByteArrayInputStream(buffer)); + } else { + // Either the USAP pool event FD or a USAP reporting pipe. + + // If this is the event FD the payload will be the number of USAPs removed. + // If this is a reporting pipe FD the payload will be the PID of the USAP + // that was just specialized. The `continue` statements below ensure that + // the messagePayload will always be valid if we complete the try block + // without an exception. + long messagePayload; + + try { + byte[] buffer = new byte[Zygote.USAP_MANAGEMENT_MESSAGE_BYTES]; + int readBytes = + Os.read(pollFDs[pollIndex].fd, buffer, 0, buffer.length); + + if (readBytes == Zygote.USAP_MANAGEMENT_MESSAGE_BYTES) { + DataInputStream inputStream = + new DataInputStream(new ByteArrayInputStream(buffer)); + + messagePayload = inputStream.readLong(); + } else { + Log.e(TAG, "Incomplete read from USAP management FD of size " + + readBytes); + continue; + } + } catch (Exception ex) { + if (pollIndex == usapPoolEventFDIndex) { + Log.e(TAG, "Failed to read from USAP pool event FD: " + + ex.getMessage()); + } else { + Log.e(TAG, "Failed to read from USAP reporting pipe: " + + ex.getMessage()); + } - messagePayload = inputStream.readLong(); - } else { - Log.e(TAG, "Incomplete read from USAP management FD of size " - + readBytes); continue; } - } catch (Exception ex) { - if (pollIndex == usapPoolEventFDIndex) { - Log.e(TAG, "Failed to read from USAP pool event FD: " - + ex.getMessage()); - } else { - Log.e(TAG, "Failed to read from USAP reporting pipe: " - + ex.getMessage()); + + if (pollIndex > usapPoolEventFDIndex) { + Zygote.removeUsapTableEntry((int) messagePayload); } - continue; + usapPoolFDRead = true; } + } - if (pollIndex > usapPoolEventFDIndex) { - Zygote.removeUsapTableEntry((int) messagePayload); - } + if (usapPoolFDRead) { + int usapPoolCount = Zygote.getUsapPoolCount(); - usapPoolFDRead = true; + if (usapPoolCount < mUsapPoolSizeMin) { + // Immediate refill + usapPoolRefillAction = UsapPoolRefillAction.IMMEDIATE; + } else if (mUsapPoolSizeMax - usapPoolCount >= mUsapPoolRefillThreshold) { + // Delayed refill + usapPoolRefillTriggerTimestamp = System.currentTimeMillis(); + } } } - // Check to see if the USAP pool needs to be refilled. - if (usapPoolFDRead) { + if (usapPoolRefillAction != UsapPoolRefillAction.NONE) { int[] sessionSocketRawFDs = socketFDs.subList(1, socketFDs.size()) .stream() .mapToInt(fd -> fd.getInt$()) .toArray(); - final Runnable command = fillUsapPool(sessionSocketRawFDs); + final boolean isPriorityRefill = + usapPoolRefillAction == UsapPoolRefillAction.IMMEDIATE; + + final Runnable command = + fillUsapPool(sessionSocketRawFDs, isPriorityRefill); if (command != null) { return command; + } else if (isPriorityRefill) { + // Schedule a delayed refill to finish refilling the pool. + usapPoolRefillTriggerTimestamp = System.currentTimeMillis(); } } } diff --git a/core/jni/com_android_internal_os_Zygote.cpp b/core/jni/com_android_internal_os_Zygote.cpp index ae051ddf116a6..16a727122fd96 100644 --- a/core/jni/com_android_internal_os_Zygote.cpp +++ b/core/jni/com_android_internal_os_Zygote.cpp @@ -169,6 +169,15 @@ static int gUsapPoolEventFD = -1; */ static constexpr int USAP_POOL_SIZE_MAX_LIMIT = 100; +/** The numeric value for the maximum priority a process may possess. */ +static constexpr int PROCESS_PRIORITY_MAX = -20; + +/** The numeric value for the minimum priority a process may possess. */ +static constexpr int PROCESS_PRIORITY_MIN = 19; + +/** The numeric value for the normal priority a process should have. */ +static constexpr int PROCESS_PRIORITY_DEFAULT = 0; + /** * A helper class containing accounting information for USAPs. */ @@ -903,7 +912,8 @@ static void ClearUsapTable() { // Utility routine to fork a process from the zygote. static pid_t ForkCommon(JNIEnv* env, bool is_system_server, const std::vector& fds_to_close, - const std::vector& fds_to_ignore) { + const std::vector& fds_to_ignore, + bool is_priority_fork) { SetSignalHandlers(); // Curry a failure function. @@ -943,6 +953,12 @@ static pid_t ForkCommon(JNIEnv* env, bool is_system_server, pid_t pid = fork(); if (pid == 0) { + if (is_priority_fork) { + setpriority(PRIO_PROCESS, 0, PROCESS_PRIORITY_MAX); + } else { + setpriority(PRIO_PROCESS, 0, PROCESS_PRIORITY_MIN); + } + // The child process. PreApplicationInit(); @@ -1140,6 +1156,9 @@ static void SpecializeCommon(JNIEnv* env, uid_t uid, gid_t gid, jintArray gids, env->CallStaticVoidMethod(gZygoteClass, gCallPostForkChildHooks, runtime_flags, is_system_server, is_child_zygote, managed_instruction_set); + // Reset the process priority to the default value. + setpriority(PRIO_PROCESS, 0, PROCESS_PRIORITY_DEFAULT); + if (env->ExceptionCheck()) { fail_fn("Error calling post fork hooks."); } @@ -1379,7 +1398,7 @@ static jint com_android_internal_os_Zygote_nativeForkAndSpecialize( fds_to_ignore.push_back(gUsapPoolEventFD); } - pid_t pid = ForkCommon(env, false, fds_to_close, fds_to_ignore); + pid_t pid = ForkCommon(env, false, fds_to_close, fds_to_ignore, true); if (pid == 0) { SpecializeCommon(env, uid, gid, gids, runtime_flags, rlimits, @@ -1406,7 +1425,8 @@ static jint com_android_internal_os_Zygote_nativeForkSystemServer( pid_t pid = ForkCommon(env, true, fds_to_close, - fds_to_ignore); + fds_to_ignore, + true); if (pid == 0) { SpecializeCommon(env, uid, gid, gids, runtime_flags, rlimits, permitted_capabilities, effective_capabilities, @@ -1448,13 +1468,15 @@ static jint com_android_internal_os_Zygote_nativeForkSystemServer( * zygote in managed code. * @param managed_session_socket_fds A list of anonymous session sockets that must be ignored by * the FD hygiene code and automatically "closed" in the new USAP. + * @param is_priority_fork Controls the nice level assigned to the newly created process * @return */ static jint com_android_internal_os_Zygote_nativeForkUsap(JNIEnv* env, jclass, jint read_pipe_fd, jint write_pipe_fd, - jintArray managed_session_socket_fds) { + jintArray managed_session_socket_fds, + jboolean is_priority_fork) { std::vector fds_to_close(MakeUsapPipeReadFDVector()), fds_to_ignore(fds_to_close); @@ -1476,7 +1498,8 @@ static jint com_android_internal_os_Zygote_nativeForkUsap(JNIEnv* env, fds_to_ignore.push_back(write_pipe_fd); fds_to_ignore.insert(fds_to_ignore.end(), session_socket_fds.begin(), session_socket_fds.end()); - pid_t usap_pid = ForkCommon(env, /* is_system_server= */ false, fds_to_close, fds_to_ignore); + pid_t usap_pid = ForkCommon(env, /* is_system_server= */ false, fds_to_close, fds_to_ignore, + is_priority_fork == JNI_TRUE); if (usap_pid != 0) { ++gUsapPoolCount; @@ -1713,6 +1736,10 @@ static void com_android_internal_os_Zygote_nativeUnblockSigTerm(JNIEnv* env, jcl UnblockSignal(SIGTERM, fail_fn); } +static void com_android_internal_os_Zygote_nativeBoostUsapPriority(JNIEnv* env, jclass) { + setpriority(PRIO_PROCESS, 0, PROCESS_PRIORITY_MAX); +} + static const JNINativeMethod gMethods[] = { { "nativeForkAndSpecialize", "(II[II[[IILjava/lang/String;Ljava/lang/String;[I[IZLjava/lang/String;Ljava/lang/String;)I", @@ -1725,7 +1752,7 @@ static const JNINativeMethod gMethods[] = { (void *) com_android_internal_os_Zygote_nativePreApplicationInit }, { "nativeInstallSeccompUidGidFilter", "(II)V", (void *) com_android_internal_os_Zygote_nativeInstallSeccompUidGidFilter }, - { "nativeForkUsap", "(II[I)I", + { "nativeForkUsap", "(II[IZ)I", (void *) com_android_internal_os_Zygote_nativeForkUsap }, { "nativeSpecializeAppProcess", "(II[II[[IILjava/lang/String;Ljava/lang/String;ZLjava/lang/String;Ljava/lang/String;)V", @@ -1747,7 +1774,9 @@ static const JNINativeMethod gMethods[] = { { "nativeBlockSigTerm", "()V", (void* ) com_android_internal_os_Zygote_nativeBlockSigTerm }, { "nativeUnblockSigTerm", "()V", - (void* ) com_android_internal_os_Zygote_nativeUnblockSigTerm } + (void* ) com_android_internal_os_Zygote_nativeUnblockSigTerm }, + { "nativeBoostUsapPriority", "()V", + (void* ) com_android_internal_os_Zygote_nativeBoostUsapPriority } }; int register_com_android_internal_os_Zygote(JNIEnv* env) { From 08cf1c6fb47eb2b66b0c687f645dfad6fe0f62dc Mon Sep 17 00:00:00 2001 From: Chris Wailes Date: Wed, 15 May 2019 14:00:22 -0700 Subject: [PATCH 006/157] Make the USAP Pool refill delay configurable. This patch fetches the USAP pool refill delay value from device_config instead of hardcoding it. Bug: 131362095 Bug: 146614089 Test: Build and launch 10+ apps successfully Change-Id: Idfeb30fa62fa296492da211b2b44902ff4f99b18 Merged-In: Idfeb30fa62fa296492da211b2b44902ff4f99b18 --- .../com/android/internal/os/ZygoteServer.java | 24 +++++++++++++------ 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/core/java/com/android/internal/os/ZygoteServer.java b/core/java/com/android/internal/os/ZygoteServer.java index bbbcbfcca858d..23abaac93204e 100644 --- a/core/java/com/android/internal/os/ZygoteServer.java +++ b/core/java/com/android/internal/os/ZygoteServer.java @@ -66,11 +66,8 @@ class ZygoteServer { /** The default value used for the USAP_POOL_SIZE_MIN device property */ private static final String USAP_POOL_SIZE_MIN_DEFAULT = "1"; - /** - * Number of milliseconds to delay before refilling the pool if it hasn't reached its - * minimum value. - */ - private static final int USAP_REFILL_DELAY_MS = 3000; + /** The default value used for the USAP_REFILL_DELAY_MS device property */ + private static final String USAP_POOL_REFILL_DELAY_MS_DEFAULT = "3000"; /** The "not a timestamp" value for the refill delay timestamp mechanism. */ private static final int INVALID_TIMESTAMP = -1; @@ -140,6 +137,12 @@ class ZygoteServer { */ private int mUsapPoolRefillThreshold = 0; + /** + * Number of milliseconds to delay before refilling the pool if it hasn't reached its + * minimum value. + */ + private int mUsapPoolRefillDelayMs = -1; + private enum UsapPoolRefillAction { DELAYED, IMMEDIATE, @@ -282,6 +285,13 @@ private void fetchUsapPoolPolicyProps() { mUsapPoolSizeMax); } + final String usapPoolRefillDelayMsPropString = Zygote.getConfigurationProperty( + ZygoteConfig.USAP_POOL_REFILL_DELAY_MS, USAP_POOL_REFILL_DELAY_MS_DEFAULT); + + if (!usapPoolRefillDelayMsPropString.isEmpty()) { + mUsapPoolRefillDelayMs = Integer.parseInt(usapPoolRefillDelayMsPropString); + } + // Sanity check if (mUsapPoolSizeMin >= mUsapPoolSizeMax) { Log.w(TAG, "The max size of the USAP pool must be greater than the minimum size." @@ -467,13 +477,13 @@ Runnable runSelectLoop(String abiList) { int elapsedTimeMs = (int) (System.currentTimeMillis() - usapPoolRefillTriggerTimestamp); - if (elapsedTimeMs >= USAP_REFILL_DELAY_MS) { + if (elapsedTimeMs >= mUsapPoolRefillDelayMs) { // Normalize the poll timeout value when the time between one poll event and the // next pushes us over the delay value. This prevents poll receiving a 0 // timeout value, which would result in it returning immediately. pollTimeoutMs = -1; } else { - pollTimeoutMs = USAP_REFILL_DELAY_MS - elapsedTimeMs; + pollTimeoutMs = mUsapPoolRefillDelayMs - elapsedTimeMs; } } From cf3f70ece877dd5621c841aa4135363d53e74c0e Mon Sep 17 00:00:00 2001 From: Chris Wailes Date: Thu, 23 May 2019 17:41:48 -0700 Subject: [PATCH 007/157] Resets the refill action/timing info after a pool fill event. Bug: 132794985 Bug: 146614089 Test: m & flash & launch more apps than USAPs in the pool Change-Id: I9ee74d76692fa8aeba9c70765b3e8f98ea9105bc Merged-In: I9ee74d76692fa8aeba9c70765b3e8f98ea9105bc --- .../com/android/internal/os/ZygoteServer.java | 35 +++++++++++++------ 1 file changed, 24 insertions(+), 11 deletions(-) diff --git a/core/java/com/android/internal/os/ZygoteServer.java b/core/java/com/android/internal/os/ZygoteServer.java index 23abaac93204e..8e9a2f2c4bbc1 100644 --- a/core/java/com/android/internal/os/ZygoteServer.java +++ b/core/java/com/android/internal/os/ZygoteServer.java @@ -143,6 +143,12 @@ class ZygoteServer { */ private int mUsapPoolRefillDelayMs = -1; + /** + * If and when we should refill the USAP pool. + */ + private UsapPoolRefillAction mUsapPoolRefillAction; + private long mUsapPoolRefillTriggerTimestamp; + private enum UsapPoolRefillAction { DELAYED, IMMEDIATE, @@ -375,6 +381,8 @@ Runnable fillUsapPool(int[] sessionSocketRawFDs, boolean isPriorityRefill) { // are re-enabled in specializeAppProcess. ZygoteHooks.postForkCommon(); + resetUsapRefillState(); + Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); return null; @@ -404,6 +412,11 @@ Runnable setUsapPoolStatus(boolean newStatus, LocalSocket sessionSocket) { } } + void resetUsapRefillState() { + mUsapPoolRefillAction = UsapPoolRefillAction.NONE; + mUsapPoolRefillTriggerTimestamp = INVALID_TIMESTAMP; + } + /** * Runs the zygote process's select loop. Accepts new connections as * they happen, and reads commands from connections one spawn-request's @@ -416,10 +429,11 @@ Runnable runSelectLoop(String abiList) { socketFDs.add(mZygoteSocket.getFileDescriptor()); peers.add(null); - long usapPoolRefillTriggerTimestamp = INVALID_TIMESTAMP; + mUsapPoolRefillTriggerTimestamp = INVALID_TIMESTAMP; while (true) { fetchUsapPoolPolicyPropsWithMinInterval(); + mUsapPoolRefillAction = UsapPoolRefillAction.NONE; int[] usapPipeFDs = null; StructPollfd[] pollFDs = null; @@ -471,11 +485,11 @@ Runnable runSelectLoop(String abiList) { int pollTimeoutMs; - if (usapPoolRefillTriggerTimestamp == INVALID_TIMESTAMP) { + if (mUsapPoolRefillTriggerTimestamp == INVALID_TIMESTAMP) { pollTimeoutMs = -1; } else { int elapsedTimeMs = - (int) (System.currentTimeMillis() - usapPoolRefillTriggerTimestamp); + (int) (System.currentTimeMillis() - mUsapPoolRefillTriggerTimestamp); if (elapsedTimeMs >= mUsapPoolRefillDelayMs) { // Normalize the poll timeout value when the time between one poll event and the @@ -494,13 +508,12 @@ Runnable runSelectLoop(String abiList) { throw new RuntimeException("poll failed", ex); } - UsapPoolRefillAction usapPoolRefillAction = UsapPoolRefillAction.NONE; if (pollReturnValue == 0) { // The poll timeout has been exceeded. This only occurs when we have finished the // USAP pool refill delay period. - usapPoolRefillTriggerTimestamp = INVALID_TIMESTAMP; - usapPoolRefillAction = UsapPoolRefillAction.DELAYED; + mUsapPoolRefillTriggerTimestamp = INVALID_TIMESTAMP; + mUsapPoolRefillAction = UsapPoolRefillAction.DELAYED; } else { boolean usapPoolFDRead = false; @@ -630,15 +643,15 @@ Runnable runSelectLoop(String abiList) { if (usapPoolCount < mUsapPoolSizeMin) { // Immediate refill - usapPoolRefillAction = UsapPoolRefillAction.IMMEDIATE; + mUsapPoolRefillAction = UsapPoolRefillAction.IMMEDIATE; } else if (mUsapPoolSizeMax - usapPoolCount >= mUsapPoolRefillThreshold) { // Delayed refill - usapPoolRefillTriggerTimestamp = System.currentTimeMillis(); + mUsapPoolRefillTriggerTimestamp = System.currentTimeMillis(); } } } - if (usapPoolRefillAction != UsapPoolRefillAction.NONE) { + if (mUsapPoolRefillAction != UsapPoolRefillAction.NONE) { int[] sessionSocketRawFDs = socketFDs.subList(1, socketFDs.size()) .stream() @@ -646,7 +659,7 @@ Runnable runSelectLoop(String abiList) { .toArray(); final boolean isPriorityRefill = - usapPoolRefillAction == UsapPoolRefillAction.IMMEDIATE; + mUsapPoolRefillAction == UsapPoolRefillAction.IMMEDIATE; final Runnable command = fillUsapPool(sessionSocketRawFDs, isPriorityRefill); @@ -655,7 +668,7 @@ Runnable runSelectLoop(String abiList) { return command; } else if (isPriorityRefill) { // Schedule a delayed refill to finish refilling the pool. - usapPoolRefillTriggerTimestamp = System.currentTimeMillis(); + mUsapPoolRefillTriggerTimestamp = System.currentTimeMillis(); } } } From 3d1c24faa3b68da7da30b76ad06ce469d525c25f Mon Sep 17 00:00:00 2001 From: Chris Wailes Date: Tue, 11 Jun 2019 11:12:25 -0700 Subject: [PATCH 008/157] Improved timekeeping logic for USAP Pool refill mechanism. This patch makes two changes to increase the reliability of the USAP pool refill mechanism. The first is to change the storage type of the result of an expression from int to long. This will help avoid potential overflow issues. The second change mitigates the impact of the non-monotonic system clock having its value changed. If the clock goes backwards in time past when the initial event triggered the refill delay, the delay will now be reset. Bug: 146614089 Test: Treehugger Change-Id: Ic6f65de51757803b5ba95975bab3b9322a91c837 Merged-In: Ic6f65de51757803b5ba95975bab3b9322a91c837 --- core/java/com/android/internal/os/ZygoteServer.java | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/core/java/com/android/internal/os/ZygoteServer.java b/core/java/com/android/internal/os/ZygoteServer.java index 8e9a2f2c4bbc1..bc1b31e913662 100644 --- a/core/java/com/android/internal/os/ZygoteServer.java +++ b/core/java/com/android/internal/os/ZygoteServer.java @@ -488,16 +488,23 @@ Runnable runSelectLoop(String abiList) { if (mUsapPoolRefillTriggerTimestamp == INVALID_TIMESTAMP) { pollTimeoutMs = -1; } else { - int elapsedTimeMs = - (int) (System.currentTimeMillis() - mUsapPoolRefillTriggerTimestamp); + long elapsedTimeMs = System.currentTimeMillis() - mUsapPoolRefillTriggerTimestamp; if (elapsedTimeMs >= mUsapPoolRefillDelayMs) { // Normalize the poll timeout value when the time between one poll event and the // next pushes us over the delay value. This prevents poll receiving a 0 // timeout value, which would result in it returning immediately. pollTimeoutMs = -1; + + } else if (elapsedTimeMs <= 0) { + // This can occur if the clock used by currentTimeMillis is reset, which is + // possible because it is not guaranteed to be monotonic. Because we can't tell + // how far back the clock was set the best way to recover is to simply re-start + // the respawn delay countdown. + pollTimeoutMs = mUsapPoolRefillDelayMs; + } else { - pollTimeoutMs = mUsapPoolRefillDelayMs - elapsedTimeMs; + pollTimeoutMs = (int) (mUsapPoolRefillDelayMs - elapsedTimeMs); } } From 304daa029a720e1353785c3b1f027a955dd6b210 Mon Sep 17 00:00:00 2001 From: Chris Wailes Date: Thu, 19 Dec 2019 14:19:06 -0800 Subject: [PATCH 009/157] Fixed an issue Zygote initialization. An assignment to a flag and a call to a function that uses that flag were in the wrong order. Bug: 146614089 Test: Treehugger Change-Id: If046aa62084892b8dae10497f15cf4c685d226db Merged-In: If046aa62084892b8dae10497f15cf4c685d226db --- core/java/com/android/internal/os/ZygoteServer.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/core/java/com/android/internal/os/ZygoteServer.java b/core/java/com/android/internal/os/ZygoteServer.java index bc1b31e913662..b5f33fb08480a 100644 --- a/core/java/com/android/internal/os/ZygoteServer.java +++ b/core/java/com/android/internal/os/ZygoteServer.java @@ -184,9 +184,8 @@ private enum UsapPoolRefillAction { Zygote.USAP_POOL_SECONDARY_SOCKET_NAME); } - fetchUsapPoolPolicyProps(); - mUsapPoolSupported = true; + fetchUsapPoolPolicyProps(); } void setForkChild() { From 6271d731d5e02b7de8915a1455b0064a9088f1b1 Mon Sep 17 00:00:00 2001 From: Chris Wailes Date: Tue, 21 May 2019 16:23:50 -0700 Subject: [PATCH 010/157] Adjust Java Language thread priority in new processes. Previously init started the Zygote with -20 nice value and then immediately switched it to 0 in ZygoteInit.main so that new applications forked from the Zygote have the correct Java Language thread priority. This patch delays this priority change so that it only affects the new processes and not the priority of the Zygote. Test: m & flash & check ps Bug: 146614089 Change-Id: Id00d0cfd642f02640c40b6e7b2aa8933a320b60c Merged-In: Id00d0cfd642f02640c40b6e7b2aa8933a320b60c --- core/java/com/android/internal/os/Zygote.java | 3 +++ .../android/internal/os/ZygoteConnection.java | 3 +++ .../com/android/internal/os/ZygoteInit.java | 18 +++++++++++++++--- 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/core/java/com/android/internal/os/Zygote.java b/core/java/com/android/internal/os/Zygote.java index 9333c470b95d8..67ce88268eda2 100644 --- a/core/java/com/android/internal/os/Zygote.java +++ b/core/java/com/android/internal/os/Zygote.java @@ -638,6 +638,9 @@ private static Runnable usapMain(LocalServerSocket usapPoolSocket, // End of the postFork event. Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); + // Set the Java Language thread priority to the default value for new apps. + Thread.currentThread().setPriority(Thread.NORM_PRIORITY); + return ZygoteInit.zygoteInit(args.mTargetSdkVersion, args.mRemainingArgs, null /* classLoader */); diff --git a/core/java/com/android/internal/os/ZygoteConnection.java b/core/java/com/android/internal/os/ZygoteConnection.java index c58266d06d151..76acf3e9ef0d4 100644 --- a/core/java/com/android/internal/os/ZygoteConnection.java +++ b/core/java/com/android/internal/os/ZygoteConnection.java @@ -582,6 +582,9 @@ private Runnable handleChildProc(ZygoteArguments parsedArgs, FileDescriptor[] de Zygote.setAppProcessName(parsedArgs, TAG); + // Set the Java Language thread priority to the default value for new apps. + Thread.currentThread().setPriority(Thread.NORM_PRIORITY); + // End of the postFork event. Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); if (parsedArgs.mInvokeWith != null) { diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java index 7c50806d2e29f..9c541f6ffc6dc 100644 --- a/core/java/com/android/internal/os/ZygoteInit.java +++ b/core/java/com/android/internal/os/ZygoteInit.java @@ -492,6 +492,9 @@ private static Runnable handleSystemServerProcess(ZygoteArguments parsedArgs) { } } + // Set the Java Language thread priority to the default value for the system server. + Thread.currentThread().setPriority(Thread.NORM_PRIORITY); + if (parsedArgs.mInvokeWith != null) { String[] args = parsedArgs.mRemainingArgs; // If we have a non-null system server class path, we'll have to duplicate the @@ -800,13 +803,22 @@ private static long posixCapabilitiesAsBits(int... capabilities) { return result; } + /** + * This is the entry point for a Zygote process. It creates the Zygote server, loads resources, + * and handles other tasks related to preparing the process for forking into applications. + * + * This process is started with a nice value of -20 (highest priority). All paths that flow + * into new processes are required to either set the priority to the default value or terminate + * before executing any non-system code. The native side of this occurs in SpecializeCommon, + * while the Java Language priority is changed in ZygoteInit.handleSystemServerProcess, + * ZygoteConnection.handleChildProc, and Zygote.usapMain. + * + * @param argv Command line arguments used to specify the Zygote's configuration. + */ @UnsupportedAppUsage public static void main(String argv[]) { ZygoteServer zygoteServer = null; - // Set the initial thread priority to the "normal" value. - Thread.currentThread().setPriority(Thread.NORM_PRIORITY); - // Mark zygote start. This ensures that thread creation will throw // an error. ZygoteHooks.startZygoteNoThreadCreation(); From 2ba58d524b6b6d93ef1601bc108a3bcf5860cbf2 Mon Sep 17 00:00:00 2001 From: Chris Wailes Date: Mon, 10 Jun 2019 11:15:35 -0700 Subject: [PATCH 011/157] Moved some thread priority changes. The previous place I had moved these changes resulted in runtime threads being created at the wrong priority. This patch moves the calls to the correct location. Test: atest CtsJvmtiRunTest924HostTestCases Bug: 146614089 Change-Id: Iad2e17cd137eab81c595cb6816608a36b009da8b Merged-In: Iad2e17cd137eab81c595cb6816608a36b009da8b --- core/java/com/android/internal/os/Zygote.java | 15 +++++++++------ .../com/android/internal/os/ZygoteConnection.java | 3 --- core/java/com/android/internal/os/ZygoteInit.java | 3 --- 3 files changed, 9 insertions(+), 12 deletions(-) diff --git a/core/java/com/android/internal/os/Zygote.java b/core/java/com/android/internal/os/Zygote.java index 67ce88268eda2..ee99c122a9dd0 100644 --- a/core/java/com/android/internal/os/Zygote.java +++ b/core/java/com/android/internal/os/Zygote.java @@ -254,6 +254,9 @@ public static int forkAndSpecialize(int uid, int gid, int[] gids, int runtimeFla Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "PostFork"); } + // Set the Java Language thread priority to the default value for new apps. + Thread.currentThread().setPriority(Thread.NORM_PRIORITY); + ZygoteHooks.postForkCommon(); return pid; } @@ -296,6 +299,9 @@ public static void specializeAppProcess(int uid, int gid, int[] gids, int runtim // Note that this event ends at the end of handleChildProc. Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "PostFork"); + // Set the Java Language thread priority to the default value for new apps. + Thread.currentThread().setPriority(Thread.NORM_PRIORITY); + /* * This is called here (instead of after the fork but before the specialize) to maintain * consistancy with the code paths for forkAndSpecialize. @@ -350,6 +356,9 @@ public static int forkSystemServer(int uid, int gid, int[] gids, int runtimeFlag Trace.setTracingEnabled(true, runtimeFlags); } + // Set the Java Language thread priority to the default value for new apps. + Thread.currentThread().setPriority(Thread.NORM_PRIORITY); + ZygoteHooks.postForkCommon(); return pid; } @@ -635,12 +644,6 @@ private static Runnable usapMain(LocalServerSocket usapPoolSocket, args.mInstructionSet, args.mAppDataDir); disableExecuteOnly(args.mTargetSdkVersion); - // End of the postFork event. - Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); - - // Set the Java Language thread priority to the default value for new apps. - Thread.currentThread().setPriority(Thread.NORM_PRIORITY); - return ZygoteInit.zygoteInit(args.mTargetSdkVersion, args.mRemainingArgs, null /* classLoader */); diff --git a/core/java/com/android/internal/os/ZygoteConnection.java b/core/java/com/android/internal/os/ZygoteConnection.java index 76acf3e9ef0d4..c58266d06d151 100644 --- a/core/java/com/android/internal/os/ZygoteConnection.java +++ b/core/java/com/android/internal/os/ZygoteConnection.java @@ -582,9 +582,6 @@ private Runnable handleChildProc(ZygoteArguments parsedArgs, FileDescriptor[] de Zygote.setAppProcessName(parsedArgs, TAG); - // Set the Java Language thread priority to the default value for new apps. - Thread.currentThread().setPriority(Thread.NORM_PRIORITY); - // End of the postFork event. Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); if (parsedArgs.mInvokeWith != null) { diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java index 9c541f6ffc6dc..fbaa5c4cc8f92 100644 --- a/core/java/com/android/internal/os/ZygoteInit.java +++ b/core/java/com/android/internal/os/ZygoteInit.java @@ -492,9 +492,6 @@ private static Runnable handleSystemServerProcess(ZygoteArguments parsedArgs) { } } - // Set the Java Language thread priority to the default value for the system server. - Thread.currentThread().setPriority(Thread.NORM_PRIORITY); - if (parsedArgs.mInvokeWith != null) { String[] args = parsedArgs.mRemainingArgs; // If we have a non-null system server class path, we'll have to duplicate the From 09fc77fc6aac2a0fb98c0cc61683e4f84bfd9192 Mon Sep 17 00:00:00 2001 From: Chris Wailes Date: Tue, 11 Jun 2019 14:39:08 -0700 Subject: [PATCH 012/157] Re-adds a trace point that was accidentally removed. Test: Built and collected a trace to verify slice ended Bug: 146614089 Change-Id: Ic75d65fc7b2a417fc3a58c2df8ec9deb795fb418 Merged-In: Ic75d65fc7b2a417fc3a58c2df8ec9deb795fb418 --- core/java/com/android/internal/os/Zygote.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/core/java/com/android/internal/os/Zygote.java b/core/java/com/android/internal/os/Zygote.java index ee99c122a9dd0..ba6645a05c498 100644 --- a/core/java/com/android/internal/os/Zygote.java +++ b/core/java/com/android/internal/os/Zygote.java @@ -644,6 +644,8 @@ private static Runnable usapMain(LocalServerSocket usapPoolSocket, args.mInstructionSet, args.mAppDataDir); disableExecuteOnly(args.mTargetSdkVersion); + Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); + return ZygoteInit.zygoteInit(args.mTargetSdkVersion, args.mRemainingArgs, null /* classLoader */); From 06301c383c0f52e296d1bc8e4d2644a9509693ba Mon Sep 17 00:00:00 2001 From: Vaisakh Murali Date: Thu, 30 Apr 2020 09:28:29 +0200 Subject: [PATCH 013/157] base: Fix notification LED blink for missed calls * Code reversed from Asus Stock framework Co-authored-by: SayanAcharya Change-Id: I9eb324750599b191b7854af28274ee260d63201e --- .../notification/NotificationManagerService.java | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index a11e2fe93b521..4a0bd9fe7b151 100755 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -6148,15 +6148,22 @@ boolean canShowLightsLocked(final NotificationRecord record, boolean aboveThresh return false; } // not if in call or the screen's on - if (isInCall() || mScreenOn) { - return false; + if (!isInCall() || !mScreenOn) { + return true; + } + // Check for phone missed calls + boolean equals = record.getChannel().getId().equals("phone_missed_call"); + String str = TAG; + if (equals) { + Slog.w(str, "canShowLightsLocked phone_missed_call return true!!!"); + return true; } // check current user if (!isNotificationForCurrentUser(record)) { return false; } - return true; + return false; } private void forceShowLed(int color) { From 948ff301ab65aed53a2af642a23a46289aaba9c7 Mon Sep 17 00:00:00 2001 From: shagbag913 Date: Tue, 24 Mar 2020 20:17:34 -0400 Subject: [PATCH 014/157] ActivityTaskManagerService: don't show build consistency dialog Change-Id: I9e46834fcb95642cbbf4e3ed93d3275d73eb2e57 --- .../java/com/android/server/wm/ActivityTaskManagerService.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java index 223205377bb9f..a1a54684350a3 100644 --- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java +++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java @@ -6517,6 +6517,7 @@ public void showSystemReadyErrorDialogsIfNeeded() { if (!Build.isBuildConsistent()) { Slog.e(TAG, "Build fingerprint is not consistent, warning user"); + /* mUiHandler.post(() -> { if (mShowDialogs) { AlertDialog d = new BaseErrorDialog(mUiContext); @@ -6530,6 +6531,7 @@ public void showSystemReadyErrorDialogsIfNeeded() { d.show(); } }); + */ } } } From b411f760464f92827871f4c7b44536a7bbd8f441 Mon Sep 17 00:00:00 2001 From: Till Kottmann Date: Fri, 24 Aug 2018 08:56:47 +0200 Subject: [PATCH 015/157] (Point) Only calculate sin and cos once Change-Id: I6157d91ca93a771b32bd2c3b859c19ed42efa469 --- .../mca/filterfw/java/android/filterfw/geometry/Point.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/media/mca/filterfw/java/android/filterfw/geometry/Point.java b/media/mca/filterfw/java/android/filterfw/geometry/Point.java index d7acf12dd1de6..425d5f74bd27f 100644 --- a/media/mca/filterfw/java/android/filterfw/geometry/Point.java +++ b/media/mca/filterfw/java/android/filterfw/geometry/Point.java @@ -102,9 +102,9 @@ public Point rotated90(int count) { } public Point rotated(float radians) { - // TODO(renn): Optimize: Keep cache of cos/sin values - return new Point((float)(Math.cos(radians) * x - Math.sin(radians) * y), - (float)(Math.sin(radians) * x + Math.cos(radians) * y)); + double cos = Math.cos(radians); + double sin = Math.sin(radians); + return new Point((float)(cos * x - sin * y), (float)(sin * x + cos * y)); } public Point rotatedAround(Point center, float radians) { From 3fc86f86096d43def594394c3d162aa39305d7cd Mon Sep 17 00:00:00 2001 From: Till Kottmann Date: Tue, 5 Jun 2018 19:57:34 +0200 Subject: [PATCH 016/157] Cache KeyStoreService Change-Id: Id0fcc1805f4144463b4d3f040fb4d2ea1644c1a2 --- ...droid_server_fingerprint_FingerprintService.cpp | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/services/core/jni/com_android_server_fingerprint_FingerprintService.cpp b/services/core/jni/com_android_server_fingerprint_FingerprintService.cpp index 503f0cf993d4e..478eb868e123a 100644 --- a/services/core/jni/com_android_server_fingerprint_FingerprintService.cpp +++ b/services/core/jni/com_android_server_fingerprint_FingerprintService.cpp @@ -53,6 +53,7 @@ static struct { static sp gLooper; static jobject gCallback; +static sp gService; class CallbackHandler : public MessageHandler { int type; @@ -70,12 +71,13 @@ class CallbackHandler : public MessageHandler { static void notifyKeystore(uint8_t *auth_token, size_t auth_token_length) { if (auth_token != NULL && auth_token_length > 0) { - // TODO: cache service? - sp sm = defaultServiceManager(); - sp binder = sm->getService(String16("android.security.keystore")); - sp service = interface_cast(binder); - if (service != NULL) { - status_t ret = service->addAuthToken(auth_token, auth_token_length); + if(gService == NULL) { + sp sm = defaultServiceManager(); + sp binder = sm->getService(String16("android.security.keystore")); + gService = interface_cast(binder); + } + if (gService != NULL) { + status_t ret = gService->addAuthToken(auth_token, auth_token_length); if (ret != ResponseCode::NO_ERROR) { ALOGE("Falure sending auth token to KeyStore: %d", ret); } From 03b19458337bc2956fda9154dcd8d1ff9219f757 Mon Sep 17 00:00:00 2001 From: Till Kottmann Date: Mon, 4 Jun 2018 19:14:22 +0200 Subject: [PATCH 017/157] Cache the global proxy to avoid fetching it for every request Change-Id: I549b7a98fdf06141d64c0eb78887c901283c1e1c --- core/java/android/net/Network.java | 32 ++++++++++++++++++------------ 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/core/java/android/net/Network.java b/core/java/android/net/Network.java index 3f56def6d7d58..781cbf360a51f 100644 --- a/core/java/android/net/Network.java +++ b/core/java/android/net/Network.java @@ -105,6 +105,8 @@ public class Network implements Parcelable { // code search audits are possible. private final transient boolean mPrivateDnsBypass; + private java.net.Proxy mProxy = null; + /** * @hide */ @@ -315,6 +317,22 @@ private void maybeInitUrlConnectionFactory() { } } + private java.net.Proxy getProxy() throws IOException { + if (mProxy == null) { + final ConnectivityManager cm = ConnectivityManager.getInstanceOrNull(); + if (cm == null) { + throw new IOException("No ConnectivityManager yet constructed, please construct one"); + } + final ProxyInfo proxyInfo = cm.getProxyForNetwork(this); + if (proxyInfo != null) { + mProxy = proxyInfo.makeProxy(); + } else { + mProxy = java.net.Proxy.NO_PROXY; + } + } + return mProxy; + } + /** * Opens the specified {@link URL} on this {@code Network}, such that all traffic will be sent * on this Network. The URL protocol must be {@code HTTP} or {@code HTTPS}. @@ -325,19 +343,7 @@ private void maybeInitUrlConnectionFactory() { * @see java.net.URL#openConnection() */ public URLConnection openConnection(URL url) throws IOException { - final ConnectivityManager cm = ConnectivityManager.getInstanceOrNull(); - if (cm == null) { - throw new IOException("No ConnectivityManager yet constructed, please construct one"); - } - // TODO: Should this be optimized to avoid fetching the global proxy for every request? - final ProxyInfo proxyInfo = cm.getProxyForNetwork(this); - final java.net.Proxy proxy; - if (proxyInfo != null) { - proxy = proxyInfo.makeProxy(); - } else { - proxy = java.net.Proxy.NO_PROXY; - } - return openConnection(url, proxy); + return openConnection(url, getProxy()); } /** From f3b71d529f46c0a5bb356be5f160f557ed206f01 Mon Sep 17 00:00:00 2001 From: Till Kottmann Date: Mon, 4 Jun 2018 17:44:56 +0200 Subject: [PATCH 018/157] Cache pin algorithms in PinSet Change-Id: I6c2cd0261885b656910feffe76d67e169d8523c8 --- core/java/android/security/net/config/PinSet.java | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/core/java/android/security/net/config/PinSet.java b/core/java/android/security/net/config/PinSet.java index d3c975eb31014..87fcde943dbcd 100644 --- a/core/java/android/security/net/config/PinSet.java +++ b/core/java/android/security/net/config/PinSet.java @@ -22,6 +22,7 @@ /** @hide */ public final class PinSet { + private static Set algorithms; public static final PinSet EMPTY_PINSET = new PinSet(Collections.emptySet(), Long.MAX_VALUE); public final long expirationTime; @@ -36,10 +37,11 @@ public PinSet(Set pins, long expirationTime) { } Set getPinAlgorithms() { - // TODO: Cache this. - Set algorithms = new ArraySet(); - for (Pin pin : pins) { - algorithms.add(pin.digestAlgorithm); + if(algorithms == null){ + algorithms = new ArraySet(); + for (Pin pin : pins) { + algorithms.add(pin.digestAlgorithm); + } } return algorithms; } From 6bd0786eaea339a393e6aad869533ca4339e818d Mon Sep 17 00:00:00 2001 From: Jyotiraditya Date: Thu, 2 Apr 2020 19:12:51 +0200 Subject: [PATCH 019/157] SystemUI: Modify brightness slider icon --- .../res/drawable/ic_brightness_thumb.xml | 25 ++++++++----------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/packages/SystemUI/res/drawable/ic_brightness_thumb.xml b/packages/SystemUI/res/drawable/ic_brightness_thumb.xml index d72198874b734..2e46126205d8b 100644 --- a/packages/SystemUI/res/drawable/ic_brightness_thumb.xml +++ b/packages/SystemUI/res/drawable/ic_brightness_thumb.xml @@ -1,29 +1,26 @@ - - + + android:fillColor="?android:attr/colorAccent" + android:pathData="M 21 0 C 32.5979797464 0 42 9.40202025355 42 21 C 42 32.5979797464 32.5979797464 42 21 42 C 9.40202025355 42 0 32.5979797464 0 21 C 0 9.40202025355 9.40202025355 0 21 0 Z" + android:strokeWidth="1.0" /> From 592348b24b790045339b09f173c2581db6e89ea0 Mon Sep 17 00:00:00 2001 From: riteshm321 Date: Fri, 5 Jun 2020 01:48:05 +0700 Subject: [PATCH 020/157] [SQUASH] Some FOD Reverts for new impl Revert "FODCircleView: Don't show circle if already Authenticated" This reverts commit 9410dade12eb9fc09dcb77eb2ace448b1cfb892d. Revert "FODCircleView: Patch screen flickering" This reverts commit ba153faef27846f027d167c8736f5c136bf5bd75. Revert "FODCircleView: Add partial wakelock on aod" This reverts commit a8db16bda90703c25a729b759407730f9be43c4f. Revert "FODCircleView: fix incorrect position on keyguard" This reverts commit 0c98818652f39bcc9084fb3d3a4077bfac2f4169. Revert "FODCircleView: Dont change alpha of fod on AOD" This reverts commit f6ed50751affd783068d890ec44b7ce08a416371. Revert "FODCircleView: only move in Y direction" This reverts commit afe679bd166c31fbfc68352af4558e0cac5f651f. Revert "FOD: Show fod circle below pattern/pin view" This reverts commit 972fccd2777440a75512f8386243e176642597cd. --- .../SystemUI/res-keyguard/values/dimens.xml | 2 +- .../res-keyguard/values/du_dimens.xml | 5 +- .../keyguard/KeyguardSecurityContainer.java | 19 ------- .../keyguard/KeyguardUpdateMonitor.java | 10 ---- .../systemui/biometrics/FODCircleView.java | 55 ++----------------- 5 files changed, 8 insertions(+), 83 deletions(-) diff --git a/packages/SystemUI/res-keyguard/values/dimens.xml b/packages/SystemUI/res-keyguard/values/dimens.xml index f231e20adbe49..f9389ce24d96c 100644 --- a/packages/SystemUI/res-keyguard/values/dimens.xml +++ b/packages/SystemUI/res-keyguard/values/dimens.xml @@ -31,7 +31,7 @@ - 570dp + 450dp 8dp diff --git a/packages/SystemUI/res-keyguard/values/du_dimens.xml b/packages/SystemUI/res-keyguard/values/du_dimens.xml index 53c63116d4b44..efd8058efecb5 100644 --- a/packages/SystemUI/res-keyguard/values/du_dimens.xml +++ b/packages/SystemUI/res-keyguard/values/du_dimens.xml @@ -162,12 +162,9 @@ 10dp 6dp - - - 120dp 0dp 4dp + diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java index 3ea220f4f421a..33e6926aba2f7 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java @@ -32,7 +32,6 @@ import android.view.MotionEvent; import android.view.VelocityTracker; import android.view.View; -import android.view.ViewGroup; import android.view.ViewConfiguration; import android.view.WindowManager; import android.widget.FrameLayout; @@ -55,7 +54,6 @@ public class KeyguardSecurityContainer extends FrameLayout implements KeyguardSecurityView { private static final boolean DEBUG = KeyguardConstants.DEBUG; private static final String TAG = "KeyguardSecurityView"; - private static final String FOD = "vendor.lineage.biometrics.fingerprint.inscreen"; private static final int USER_TYPE_PRIMARY = 1; private static final int USER_TYPE_WORK_PROFILE = 2; @@ -102,7 +100,6 @@ public class KeyguardSecurityContainer extends FrameLayout implements KeyguardSe private int mActivePointerId = -1; private boolean mIsDragging; private float mStartTouchY = -1; - private final int mFODmargin; // Used to notify the container when something interesting happens. public interface SecurityCallback { @@ -138,8 +135,6 @@ public KeyguardSecurityContainer(Context context, AttributeSet attrs, int defSty SystemUIFactory.getInstance().getRootComponent()); mUnlockMethodCache = UnlockMethodCache.getInstance(context); mViewConfiguration = ViewConfiguration.get(context); - mFODmargin = mContext.getResources().getDimensionPixelSize( - R.dimen.keyguard_security_fod_view_margin); } public void setSecurityCallback(SecurityCallback callback) { @@ -302,15 +297,6 @@ private KeyguardSecurityView getSecurityView(SecurityMode securityMode) { if (DEBUG) Log.v(TAG, "inflating id = " + layoutId); View v = mInjectionInflationController.injectable(inflater) .inflate(layoutId, mSecurityViewFlipper, false); - View eca = v.findViewById(R.id.keyguard_selector_fade_container); - if (eca != null && hasInDisplayFingerprint() && - (securityMode == SecurityMode.Pattern - || securityMode == SecurityMode.PIN)) { - ViewGroup.MarginLayoutParams lp = (ViewGroup.MarginLayoutParams) - eca.getLayoutParams(); - lp.setMargins(lp.leftMargin, mFODmargin, lp.rightMargin, - lp.bottomMargin); - } mSecurityViewFlipper.addView(v); updateSecurityView(v); view = (KeyguardSecurityView)v; @@ -480,10 +466,6 @@ private void reportFailedUnlockAttempt(int userId, int timeoutMs) { } } - private boolean hasInDisplayFingerprint() { - return mContext.getPackageManager().hasSystemFeature(FOD); - } - /** * Shows the primary security screen for the user. This will be either the multi-selector * or the user's security method. @@ -600,7 +582,6 @@ private void showSecurityScreen(SecurityMode securityMode) { mCurrentSecurityView = newView; mSecurityCallback.onSecurityModeChanged(securityMode, securityMode != SecurityMode.None && newView.needsInput()); - mUpdateMonitor.setSecurityMode(securityMode); } private KeyguardSecurityViewFlipper getFlipper() { diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java index 69654691d58c2..8187617cf3067 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java @@ -98,7 +98,6 @@ import com.android.internal.telephony.TelephonyIntents; import com.android.internal.util.Preconditions; import com.android.internal.widget.LockPatternUtils; -import com.android.keyguard.KeyguardSecurityModel.SecurityMode; import com.android.settingslib.WirelessUtils; import com.android.systemui.R; import com.android.systemui.shared.system.ActivityManagerWrapper; @@ -261,7 +260,6 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener { private int mFingerprintRunningState = BIOMETRIC_STATE_STOPPED; private int mFaceRunningState = BIOMETRIC_STATE_STOPPED; private LockPatternUtils mLockPatternUtils; - private SecurityMode mCurrentSecurityMode = SecurityMode.Invalid; private final IDreamManager mDreamManager; private boolean mIsDreaming; private final DevicePolicyManager mDevicePolicyManager; @@ -976,14 +974,6 @@ private void handleFaceUnlockStateChanged(boolean running, int userId) { } } - public SecurityMode getSecurityMode() { - return mCurrentSecurityMode; - } - - public void setSecurityMode(SecurityMode securityMode) { - mCurrentSecurityMode = securityMode; - } - public boolean isFaceUnlockRunning(int userId) { return mUserFaceUnlockRunning.get(userId); } diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/FODCircleView.java b/packages/SystemUI/src/com/android/systemui/biometrics/FODCircleView.java index 55f15edcbd4d5..dfd98ae47f312 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/FODCircleView.java +++ b/packages/SystemUI/src/com/android/systemui/biometrics/FODCircleView.java @@ -27,11 +27,9 @@ import android.graphics.drawable.AnimationDrawable; import android.graphics.PixelFormat; import android.graphics.Point; -import android.hardware.biometrics.BiometricSourceType; import android.os.Handler; import android.os.UserHandle; import android.os.Looper; -import android.os.PowerManager; import android.os.RemoteException; import android.provider.Settings; import android.view.Display; @@ -45,9 +43,7 @@ import com.android.keyguard.KeyguardUpdateMonitor; import com.android.keyguard.KeyguardUpdateMonitorCallback; -import com.android.keyguard.KeyguardSecurityModel.SecurityMode; import com.android.internal.widget.LockPatternUtils; -import com.android.systemui.Dependency; import com.android.systemui.R; import vendor.lineage.biometrics.fingerprint.inscreen.V1_0.IFingerprintInscreen; @@ -75,18 +71,13 @@ public class FODCircleView extends ImageView { private boolean mIsBouncer; private boolean mIsDreaming; - private boolean mIsKeyguard; private boolean mIsShowing; private boolean mIsCircleShowing; - private boolean mIsAuthenticated; private Handler mHandler; private LockPatternUtils mLockPatternUtils; - private PowerManager mPowerManager; - private PowerManager.WakeLock mWakeLock; - private Timer mBurnInProtectionTimer; private FODAnimation mFODAnimation; @@ -140,7 +131,6 @@ public void onDreamingStateChanged(boolean dreaming) { public void onKeyguardVisibilityChanged(boolean showing) { mIsKeyguard = showing; updateStyle(); - updatePosition(); if (mFODAnimation != null) { mFODAnimation.setAnimationKeyguard(mIsKeyguard); } @@ -161,15 +151,6 @@ public void onKeyguardBouncerChanged(boolean isBouncer) { } } - @Override - public void onBiometricAuthenticated(int userId, BiometricSourceType biometricSourceType) { - super.onBiometricAuthenticated(userId, biometricSourceType); - if (biometricSourceType == BiometricSourceType.FINGERPRINT){ - mIsAuthenticated = true; - } - } - - @Override public void onScreenTurnedOff() { hide(); } @@ -245,10 +226,6 @@ public FODCircleView(Context context) { mUpdateMonitor = KeyguardUpdateMonitor.getInstance(context); mUpdateMonitor.registerCallback(mMonitorCallback); - mPowerManager = context.getSystemService(PowerManager.class); - mWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, - FODCircleView.class.getSimpleName()); - mFODAnimation = new FODAnimation(context, mPositionX, mPositionY); } @@ -261,17 +238,6 @@ protected void onDraw(Canvas canvas) { } } - @Override - protected void onLayout(boolean changed, int left, int top, int right, int bottom) { - super.onLayout(changed, left, top, right, bottom); - - if (mIsCircleShowing) { - dispatchPress(); - } else { - dispatchRelease(); - } - } - @Override public boolean onTouchEvent(MotionEvent event) { float x = event.getAxisValue(MotionEvent.AXIS_X); @@ -357,20 +323,13 @@ public void dispatchHide() { } public void showCircle() { - if (mIsAuthenticated) { - return; - } - mIsCircleShowing = true; setKeepScreenOn(true); - if (mIsDreaming) { - mWakeLock.acquire(300); - } - setDim(true); updateAlpha(); + dispatchPress(); setImageResource(PRESSED_STYLES[mPressedIcon]); invalidate(); @@ -382,6 +341,8 @@ public void hideCircle() { setImageResource(ICON_STYLES[mSelectedIcon]); invalidate(); + dispatchRelease(); + setDim(false); updateAlpha(); @@ -400,7 +361,6 @@ public void show() { } mIsShowing = true; - mIsAuthenticated = false; dispatchShow(); setVisibility(View.VISIBLE); @@ -417,6 +377,8 @@ public void hide() { private void updateAlpha() { if (mIsCircleShowing) { setAlpha(1.0f); + } else { + setAlpha(mIsDreaming ? 0.5f : 1.0f); } } @@ -460,13 +422,8 @@ private void updatePosition() { throw new IllegalArgumentException("Unknown rotation: " + rotation); } - if (mIsKeyguard) { - mParams.x = mPositionX; - mParams.y = mPositionY; - } - if (mIsDreaming) { - //mParams.x += mDreamingOffsetX; + mParams.x += mDreamingOffsetX; mParams.y += mDreamingOffsetY; mFODAnimation.updateParams(mParams.y); } From 4493017fdb75f8d9a6ba3c516d42e36bd6e1b5d3 Mon Sep 17 00:00:00 2001 From: TheScarastic Date: Mon, 8 Jun 2020 13:45:06 +0530 Subject: [PATCH 021/157] FODCircleView: Add support for pressed fod layer --- packages/SystemUI/res/values/du_colors.xml | 4 + .../systemui/biometrics/FODCircleView.java | 95 ++++++++++++------- 2 files changed, 64 insertions(+), 35 deletions(-) diff --git a/packages/SystemUI/res/values/du_colors.xml b/packages/SystemUI/res/values/du_colors.xml index 0db54f67dba71..f7372a796d60a 100644 --- a/packages/SystemUI/res/values/du_colors.xml +++ b/packages/SystemUI/res/values/du_colors.xml @@ -46,4 +46,8 @@ #ff000000 + + + #20000000 + diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/FODCircleView.java b/packages/SystemUI/src/com/android/systemui/biometrics/FODCircleView.java index dfd98ae47f312..21fbf776f1968 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/FODCircleView.java +++ b/packages/SystemUI/src/com/android/systemui/biometrics/FODCircleView.java @@ -25,6 +25,7 @@ import android.graphics.Color; import android.graphics.Paint; import android.graphics.drawable.AnimationDrawable; +import android.hardware.biometrics.BiometricSourceType; import android.graphics.PixelFormat; import android.graphics.Point; import android.os.Handler; @@ -60,22 +61,27 @@ public class FODCircleView extends ImageView { private final int mDreamingMaxOffset; private final int mNavigationBarSize; private final boolean mShouldBoostBrightness; - private final Paint mPaintFingerprint = new Paint(); + private final Paint mPaintFingerprintBackground = new Paint(); private final WindowManager.LayoutParams mParams = new WindowManager.LayoutParams(); + private final WindowManager.LayoutParams mPressedParams = new WindowManager.LayoutParams(); private final WindowManager mWindowManager; private IFingerprintInscreen mFingerprintInscreenDaemon; private int mDreamingOffsetX; private int mDreamingOffsetY; + + private int mColorBackground; private boolean mIsBouncer; private boolean mIsDreaming; - private boolean mIsShowing; + private boolean mIsKeyguard; private boolean mIsCircleShowing; private Handler mHandler; + private final ImageView mPressedView; + private LockPatternUtils mLockPatternUtils; private Timer mBurnInProtectionTimer; @@ -140,7 +146,7 @@ public void onKeyguardVisibilityChanged(boolean showing) { public void onKeyguardBouncerChanged(boolean isBouncer) { mIsBouncer = isBouncer; - if (mIsKeyguard && mUpdateMonitor.isFingerprintDetectionRunning()) { + if (mUpdateMonitor.isFingerprintDetectionRunning()) { if (isPinOrPattern(mUpdateMonitor.getCurrentUser()) || !isBouncer) { show(); } else { @@ -192,8 +198,9 @@ public FODCircleView(Context context) { Resources res = context.getResources(); - mPaintFingerprint.setAntiAlias(true); - mPaintFingerprint.setColor(res.getColor(R.color.config_fodColor)); + mColorBackground = res.getColor(R.color.config_fodColorBackground); + mPaintFingerprintBackground.setColor(mColorBackground); + mPaintFingerprintBackground.setAntiAlias(true); mWindowManager = context.getSystemService(WindowManager.class); @@ -207,13 +214,27 @@ public FODCircleView(Context context) { mParams.width = mSize; mParams.format = PixelFormat.TRANSLUCENT; - mParams.setTitle("Fingerprint on display"); mParams.packageName = "android"; mParams.type = WindowManager.LayoutParams.TYPE_DISPLAY_OVERLAY; mParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | - WindowManager.LayoutParams.FLAG_DIM_BEHIND | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN; mParams.gravity = Gravity.TOP | Gravity.LEFT; + + mPressedParams.copyFrom(mParams); + mPressedParams.flags |= WindowManager.LayoutParams.FLAG_DIM_BEHIND; + + mParams.setTitle("Fingerprint on display"); + mPressedParams.setTitle("Fingerprint on display.touched"); + + mPressedView = new ImageView(context) { + @Override + protected void onDraw(Canvas canvas) { + if (mIsCircleShowing) { + setImageResource(PRESSED_STYLES[mPressedIcon]); + } + super.onDraw(canvas); + } + }; mWindowManager.addView(this, mParams); @@ -231,11 +252,10 @@ public FODCircleView(Context context) { @Override protected void onDraw(Canvas canvas) { - super.onDraw(canvas); - - if (mIsCircleShowing) { - setImageResource(PRESSED_STYLES[mPressedIcon]); + if (!mIsCircleShowing) { + canvas.drawCircle(mSize / 2, mSize / 2, mSize / 2.0f, mPaintFingerprintBackground); } + super.onDraw(canvas); } @Override @@ -328,7 +348,6 @@ public void showCircle() { setKeepScreenOn(true); setDim(true); - updateAlpha(); dispatchPress(); setImageResource(PRESSED_STYLES[mPressedIcon]); @@ -344,7 +363,6 @@ public void hideCircle() { dispatchRelease(); setDim(false); - updateAlpha(); setKeepScreenOn(false); } @@ -360,14 +378,11 @@ public void show() { return; } - mIsShowing = true; - dispatchShow(); setVisibility(View.VISIBLE); } public void hide() { - mIsShowing = false; setVisibility(View.GONE); hideCircle(); @@ -375,11 +390,7 @@ public void hide() { } private void updateAlpha() { - if (mIsCircleShowing) { - setAlpha(1.0f); - } else { - setAlpha(mIsDreaming ? 0.5f : 1.0f); - } + setAlpha(mIsDreaming ? 0.5f : 1.0f); } private void updateStyle() { @@ -401,26 +412,30 @@ private void updatePosition() { defaultDisplay.getRealSize(size); int rotation = defaultDisplay.getRotation(); + int x, y; switch (rotation) { case Surface.ROTATION_0: - mParams.x = mPositionX; - mParams.y = mPositionY; + x = mPositionX; + y = mPositionY; break; case Surface.ROTATION_90: - mParams.x = mPositionY; - mParams.y = mPositionX; + x = mPositionY; + y = mPositionX; break; case Surface.ROTATION_180: - mParams.x = mPositionX; - mParams.y = size.y - mPositionY - mSize; + x = mPositionX; + y = size.y - mPositionY - mSize; break; case Surface.ROTATION_270: - mParams.x = size.x - mPositionY - mSize - mNavigationBarSize; - mParams.y = mPositionX; + x = size.x - mPositionY - mSize - mNavigationBarSize; + y = mPositionX; break; default: throw new IllegalArgumentException("Unknown rotation: " + rotation); } + + mPressedParams.x = mParams.x = x; + mPressedParams.y = mParams.y = y; if (mIsDreaming) { mParams.x += mDreamingOffsetX; @@ -429,6 +444,10 @@ private void updatePosition() { } mWindowManager.updateViewLayout(this, mParams); + + if (mPressedView.getParent() != null) { + mWindowManager.updateViewLayout(mPressedView, mPressedParams); + } } private boolean isPinOrPattern(int userId) { @@ -459,16 +478,22 @@ private void setDim(boolean dim) { } if (mShouldBoostBrightness) { - mParams.screenBrightness = 1.0f; + mPressedParams.screenBrightness = 1.0f; } - mParams.dimAmount = dimAmount / 255.0f; + mPressedParams.dimAmount = dimAmount / 255.0f; + if (mPressedView.getParent() == null) { + mWindowManager.addView(mPressedView, mPressedParams); + } else { + mWindowManager.updateViewLayout(mPressedView, mPressedParams); + } } else { - mParams.screenBrightness = 0.0f; - mParams.dimAmount = 0.0f; + mPressedParams.screenBrightness = 0.0f; + mPressedParams.dimAmount = 0.0f; + if (mPressedView.getParent() != null) { + mWindowManager.removeView(mPressedView); + } } - - mWindowManager.updateViewLayout(this, mParams); } private class BurnInProtectionTask extends TimerTask { From 3729009359023ce7cd7001332aa47eedd87ee6ba Mon Sep 17 00:00:00 2001 From: jhenrique09 Date: Mon, 8 Jun 2020 14:31:59 +0530 Subject: [PATCH 022/157] FODCircleView: Don't show on certain cases --- .../systemui/biometrics/FODCircleView.java | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/FODCircleView.java b/packages/SystemUI/src/com/android/systemui/biometrics/FODCircleView.java index 21fbf776f1968..fa7b16ba53ec1 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/FODCircleView.java +++ b/packages/SystemUI/src/com/android/systemui/biometrics/FODCircleView.java @@ -16,6 +16,13 @@ package com.android.systemui.biometrics; +import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW; +import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_LOCKOUT; +import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_TIMEOUT; +import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN; + +import android.app.ActivityManager; + import android.app.admin.DevicePolicyManager; import android.content.ContentResolver; import android.content.Context; @@ -77,6 +84,7 @@ public class FODCircleView extends ImageView { private boolean mIsDreaming; private boolean mIsKeyguard; private boolean mIsCircleShowing; + private boolean mCanUnlockWithFp; private Handler mHandler; @@ -177,7 +185,35 @@ public void onBiometricHelp(int msgId, String helpString, mHandler.post(() -> mFODAnimation.hideFODanimation()); } } + + @Override + public void onStrongAuthStateChanged(int userId) { + mCanUnlockWithFp = canUnlockWithFp(); + if (!mCanUnlockWithFp){ + hide(); + } + } }; + + private boolean canUnlockWithFp() { + int currentUser = ActivityManager.getCurrentUser(); + boolean biometrics = mUpdateMonitor.isUnlockingWithBiometricsPossible(currentUser); + KeyguardUpdateMonitor.StrongAuthTracker strongAuthTracker = + mUpdateMonitor.getStrongAuthTracker(); + int strongAuth = strongAuthTracker.getStrongAuthForUser(currentUser); + if (biometrics && !strongAuthTracker.hasUserAuthenticatedSinceBoot()) { + return false; + } else if (biometrics && (strongAuth & STRONG_AUTH_REQUIRED_AFTER_TIMEOUT) != 0) { + return false; + } else if (biometrics && (strongAuth & STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW) != 0) { + return false; + } else if (biometrics && (strongAuth & STRONG_AUTH_REQUIRED_AFTER_LOCKOUT) != 0) { + return false; + } else if (biometrics && (strongAuth & STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN) != 0) { + return false; + } + return true; + } public FODCircleView(Context context) { super(context); @@ -246,6 +282,8 @@ protected void onDraw(Canvas canvas) { mUpdateMonitor = KeyguardUpdateMonitor.getInstance(context); mUpdateMonitor.registerCallback(mMonitorCallback); + + mCanUnlockWithFp = canUnlockWithFp(); mFODAnimation = new FODAnimation(context, mPositionX, mPositionY); } @@ -378,6 +416,11 @@ public void show() { return; } + if (!mCanUnlockWithFp){ + // Ignore when unlocking with fp is not possible + return; + } + dispatchShow(); setVisibility(View.VISIBLE); } From c80d56b46959b1b6bfb121b071e3a8678b4dc7ea Mon Sep 17 00:00:00 2001 From: Anushek Prasal Date: Tue, 14 Apr 2020 23:41:01 +0530 Subject: [PATCH 023/157] base: Swipe up on keyguard to use Face Unlock [1/2] --- core/java/android/provider/Settings.java | 6 ++++++ core/res/res/values/du_config.xml | 3 +++ core/res/res/values/du_symbols.xml | 3 +++ packages/SystemUI/res/values/du_config.xml | 3 --- .../com/android/keyguard/KeyguardUpdateMonitor.java | 13 +++++++++---- 5 files changed, 21 insertions(+), 7 deletions(-) diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index 39942791b47fc..0ac29790f5bbd 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -11445,6 +11445,12 @@ public boolean validate(@Nullable String value) { */ public static final String HARDWARE_KEYS_ENABLE = "hardware_keys_enable"; + /** + * Whether face unlock is allowed only on security view. + * @hide + */ + public static final String FACE_UNLOCK_ALWAYS_REQUIRE_SWIPE = "face_unlock_always_require_swipe"; + /** * This are the settings to be backed up. * diff --git a/core/res/res/values/du_config.xml b/core/res/res/values/du_config.xml index d420503b398ab..5442590da28a3 100644 --- a/core/res/res/values/du_config.xml +++ b/core/res/res/values/du_config.xml @@ -277,4 +277,7 @@ 0x3980FF + + + false diff --git a/core/res/res/values/du_symbols.xml b/core/res/res/values/du_symbols.xml index 2f48a6ad2bdee..0f406d67efb47 100644 --- a/core/res/res/values/du_symbols.xml +++ b/core/res/res/values/du_symbols.xml @@ -260,4 +260,7 @@ + + + diff --git a/packages/SystemUI/res/values/du_config.xml b/packages/SystemUI/res/values/du_config.xml index 375cd349b3ef2..1a3c92fe69c57 100644 --- a/packages/SystemUI/res/values/du_config.xml +++ b/packages/SystemUI/res/values/du_config.xml @@ -72,9 +72,6 @@ true - - false - false diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java index 8187617cf3067..27748c1d84b12 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java @@ -269,7 +269,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener { private int mActiveMobileDataSubscription = SubscriptionManager.INVALID_SUBSCRIPTION_ID; private final boolean mFingerprintWakeAndUnlock; - private final boolean mFaceAuthOnlyOnSecurityView; + private final boolean mFaceAuthOnSecurityView; /** * Short delay before restarting biometric authentication after a successful try @@ -1581,8 +1581,8 @@ protected KeyguardUpdateMonitor(Context context) { mStrongAuthTracker = new StrongAuthTracker(context, this::notifyStrongAuthStateChanged); mFingerprintWakeAndUnlock = mContext.getResources().getBoolean( R.bool.config_fingerprintWakeAndUnlock); - mFaceAuthOnlyOnSecurityView = mContext.getResources().getBoolean( - R.bool.config_faceAuthOnlyOnSecurityView); + mFaceAuthOnSecurityView = mContext.getResources().getBoolean( + com.android.internal.R.bool.config_faceAuthOnSecurityView); // Since device can't be un-provisioned, we only need to register a content observer // to update mDeviceProvisioned when we are... @@ -1827,7 +1827,7 @@ public boolean shouldListenForFace() { && !isLockOutOrLockDown; boolean unlockPossible = true; - if ((!mBouncer || !awakeKeyguard) && mFaceAuthOnlyOnSecurityView){ + if ((!mBouncer || !awakeKeyguard) && isFaceAuthOnlyOnSecurityView()){ unlockPossible = false; } @@ -1948,6 +1948,11 @@ private void stopListeningForFace() { } } + private boolean isFaceAuthOnlyOnSecurityView() { + return Settings.Secure.getInt(mContext.getContentResolver(), + Settings.Secure.FACE_UNLOCK_ALWAYS_REQUIRE_SWIPE, mFaceAuthOnSecurityView ? 1 : 0) != 0; + } + private boolean isDeviceProvisionedInSettingsDb() { return Settings.Global.getInt(mContext.getContentResolver(), Settings.Global.DEVICE_PROVISIONED, 0) != 0; From 1ea2c5dc25e5166d84af94d81e2d4b3f78e9623e Mon Sep 17 00:00:00 2001 From: AnkitGourav Date: Thu, 28 May 2020 06:21:10 +0530 Subject: [PATCH 024/157] Utils: add method to check if device is connected to Wi-Fi extracted from da89b4d81d094beb2e5c10a8887abca0985198b3 Signed-off-by: AnkitGourav --- core/java/com/android/internal/util/du/Utils.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/core/java/com/android/internal/util/du/Utils.java b/core/java/com/android/internal/util/du/Utils.java index 37a2e8b55cb9d..5ff2e8602f299 100644 --- a/core/java/com/android/internal/util/du/Utils.java +++ b/core/java/com/android/internal/util/du/Utils.java @@ -68,6 +68,15 @@ public static boolean isWifiOnly(Context context) { return (cm.isNetworkSupported(ConnectivityManager.TYPE_MOBILE) == false); } + // Check if device is connected to Wi-Fi + public static boolean isWiFiConnected(Context context) { + ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); + if (cm == null) return false; + + NetworkInfo wifi = cm.getNetworkInfo(ConnectivityManager.TYPE_WIFI); + return wifi.isConnected(); + } + // Check to see if device is connected to the internet public static boolean isConnected(Context context) { ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); From 78765d9d39d54f6ea378894a25c1cf9d70881de7 Mon Sep 17 00:00:00 2001 From: AnkitGourav Date: Thu, 28 May 2020 06:24:17 +0530 Subject: [PATCH 025/157] QSHeaderDataUsage: show Wi-Fi usage if device is connected to Wi-Fi Signed-off-by: AnkitGourav --- .../android/settingslib/net/DataUsageController.java | 4 ++++ .../systemui/statusbar/info/DataUsageView.java | 12 ++++++++---- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java b/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java index fc9e48c8def7c..812127c59e94c 100644 --- a/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java +++ b/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java @@ -298,7 +298,11 @@ public interface Callback { public DataUsageInfo getDailyDataUsageInfo() { NetworkTemplate template = DataUsageUtils.getMobileTemplate(mContext, mSubscriptionId); + return getDailyDataUsageInfo(template); + } + public DataUsageInfo getDailyWifiDataUsageInfo() { + NetworkTemplate template = NetworkTemplate.buildTemplateWifiWildcard(); return getDailyDataUsageInfo(template); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/info/DataUsageView.java b/packages/SystemUI/src/com/android/systemui/statusbar/info/DataUsageView.java index 611579fdc324e..af551507f5918 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/info/DataUsageView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/info/DataUsageView.java @@ -14,6 +14,7 @@ import android.provider.Settings; import android.view.View; +import com.android.internal.util.du.Utils; import com.android.systemui.Dependency; import com.android.systemui.R; import com.android.systemui.statusbar.policy.NetworkController; @@ -59,10 +60,13 @@ private void updateUsageData() { mobileDataController.setSubscriptionId( SubscriptionManager.getDefaultDataSubscriptionId()); final DataUsageController.DataUsageInfo info = isDataUsageEnabled() == 1 ? - mobileDataController.getDailyDataUsageInfo() - : mobileDataController.getDataUsageInfo(); - - formatedinfo = formatDataUsage(info.usageLevel); + (Utils.isWiFiConnected(mContext) ? + mobileDataController.getDailyWifiDataUsageInfo() + : mobileDataController.getDailyDataUsageInfo()) + : (Utils.isWiFiConnected(mContext) ? + mobileDataController.getWifiDataUsageInfo() + : mobileDataController.getDataUsageInfo()); + formatedinfo = formatDataUsage(info.usageLevel) + " "; } public int isDataUsageEnabled() { From eba1a43ee4bceb3648e703f75dfb451cc8ddd966 Mon Sep 17 00:00:00 2001 From: AnkitGourav Date: Thu, 28 May 2020 07:23:24 +0530 Subject: [PATCH 026/157] QSHeaderDataUsage: hide usage if device is not connected to internet - also clean-up DataUsageView Signed-off-by: AnkitGourav --- .../systemui/qs/QuickStatusBarHeader.java | 15 ++++++++--- .../statusbar/info/DataUsageView.java | 26 +++++-------------- .../phone/NotificationPanelView.java | 1 - .../systemui/statusbar/phone/StatusBar.java | 4 --- 4 files changed, 19 insertions(+), 27 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java index c671a7e80a882..90cbaa76012f2 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java @@ -56,6 +56,7 @@ import androidx.annotation.VisibleForTesting; +import com.android.internal.util.du.Utils; import com.android.settingslib.Utils; import com.android.systemui.BatteryMeterView; import com.android.systemui.DualToneHandler; @@ -386,9 +387,16 @@ private void updateshowBatteryInBar() { private void updateDataUsageView() { if (mDataUsageView.isDataUsageEnabled() != 0) { - mDataUsageLayout.setVisibility(View.VISIBLE); - mDataUsageImage.setVisibility(View.VISIBLE); - mDataUsageView.setVisibility(View.VISIBLE); + if (Utils.isConnected(mContext)) { + DataUsageView.updateUsage(); + mDataUsageLayout.setVisibility(View.VISIBLE); + mDataUsageImage.setVisibility(View.VISIBLE); + mDataUsageView.setVisibility(View.VISIBLE); + } else { + mDataUsageView.setVisibility(View.GONE); + mDataUsageImage.setVisibility(View.GONE); + mDataUsageLayout.setVisibility(View.GONE); + } } else { mDataUsageView.setVisibility(View.GONE); mDataUsageImage.setVisibility(View.GONE); @@ -426,6 +434,7 @@ public void setExpanded(boolean expanded) { mExpanded = expanded; mHeaderQsPanel.setExpanded(expanded); updateEverything(); + updateDataUsageView(); } /** diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/info/DataUsageView.java b/packages/SystemUI/src/com/android/systemui/statusbar/info/DataUsageView.java index af551507f5918..3bad365492984 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/info/DataUsageView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/info/DataUsageView.java @@ -3,23 +3,19 @@ import android.content.Context; import android.graphics.Canvas; -import android.graphics.Typeface; -import android.util.AttributeSet; -import android.os.AsyncTask; +import android.provider.Settings; import android.telephony.SubscriptionManager; import android.text.BidiFormatter; import android.text.format.Formatter; import android.text.format.Formatter.BytesResult; +import android.util.AttributeSet; import android.widget.TextView; -import android.provider.Settings; -import android.view.View; import com.android.internal.util.du.Utils; +import com.android.settingslib.net.DataUsageController; import com.android.systemui.Dependency; import com.android.systemui.R; import com.android.systemui.statusbar.policy.NetworkController; -import com.android.systemui.statusbar.policy.NetworkController.SignalCallback; -import com.android.settingslib.net.DataUsageController; public class DataUsageView extends TextView { @@ -40,18 +36,10 @@ protected void onDraw(Canvas canvas) { if ((isDataUsageEnabled() == 0) && this.getText().toString() != "") { setText(""); - } - if (isDataUsageEnabled() != 0) { - if(shouldUpdateData) { - shouldUpdateData = false; - AsyncTask.execute(new Runnable() { - @Override - public void run() { - updateUsageData(); - } - }); - setText(formatedinfo); - } + } else if (isDataUsageEnabled() != 0 && shouldUpdateData) { + shouldUpdateData = false; + updateUsageData(); + setText(formatedinfo); } } 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 d65d0ec9819f5..328357d1b1f91 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java @@ -2323,7 +2323,6 @@ private void updateNotificationTranslucency() { alpha *= mClockPositionResult.clockAlpha; } mNotificationStackScroller.setAlpha(alpha); - mStatusBar.updateQSDataUsageInfo(); mStatusBar.updateBlurVisibility(); mStatusBar.setDismissAllVisible(true); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java index 287c039e36d1f..51da7175f0ff0 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java @@ -2489,10 +2489,6 @@ private void setHeadsUpBlacklist() { mPresenter.setHeadsUpBlacklist(); } - public void updateQSDataUsageInfo() { - DataUsageView.updateUsage(); - } - private void setScreenBrightnessMode() { int mode = Settings.System.getIntForUser(mContext.getContentResolver(), Settings.System.SCREEN_BRIGHTNESS_MODE, From 2fb834659afd067ca0c572acd6f114b360fc19ac Mon Sep 17 00:00:00 2001 From: AnkitGourav Date: Wed, 27 May 2020 14:20:17 +0530 Subject: [PATCH 027/157] QSTiles: improve haptic feedback Signed-off-by: AnkitGourav --- .../src/com/android/systemui/qs/tileimpl/QSTileImpl.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java index b310e5a5f2d61..6489635519a33 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java @@ -201,9 +201,8 @@ public void vibrateTile() { return; } if (mVibrator != null) { - if (mVibrator.hasVibrator()) { - mVibrator.vibrate(VibrationEffect.get(VibrationEffect.EFFECT_CLICK)); - } + if (mVibrator.hasVibrator()) + mVibrator.vibrate(VibrationEffect.createOneShot(20, VibrationEffect.DEFAULT_AMPLITUDE)); } } From 7f9467a69f68b68a007683a61a7eb48eb085a259 Mon Sep 17 00:00:00 2001 From: Genkzsz11 Date: Mon, 15 Jun 2020 10:21:05 +0700 Subject: [PATCH 028/157] move some utils to own class --- .../android/internal/util/du/ActionUtils.java | 28 +++++++++++++++++++ .../com/android/internal/util/du/Utils.java | 26 ----------------- .../systemui/qs/QuickStatusBarHeader.java | 4 +-- .../statusbar/info/DataUsageView.java | 6 ++-- 4 files changed, 33 insertions(+), 31 deletions(-) diff --git a/core/java/com/android/internal/util/du/ActionUtils.java b/core/java/com/android/internal/util/du/ActionUtils.java index 3beafc4512e9d..923ee7e3c024a 100644 --- a/core/java/com/android/internal/util/du/ActionUtils.java +++ b/core/java/com/android/internal/util/du/ActionUtils.java @@ -21,6 +21,8 @@ import android.content.Context; import android.content.Intent; import android.media.AudioManager; +import android.net.ConnectivityManager; +import android.net.NetworkInfo; import android.os.PowerManager; import android.os.RemoteException; import android.os.ServiceManager; @@ -52,6 +54,32 @@ private static IStatusBarService getStatusBarService() { } } + // Check to see if device is WiFi only + public static boolean isWifiOnly(Context context) { + ConnectivityManager cm = (ConnectivityManager)context.getSystemService( + Context.CONNECTIVITY_SERVICE); + return (cm.isNetworkSupported(ConnectivityManager.TYPE_MOBILE) == false); + } + + // Check if device is connected to Wi-Fi + public static boolean isWiFiConnected(Context context) { + ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); + if (cm == null) return false; + + NetworkInfo wifi = cm.getNetworkInfo(ConnectivityManager.TYPE_WIFI); + return wifi.isConnected(); + } + + // Check to see if device is connected to the internet + public static boolean isConnected(Context context) { + ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); + if (cm == null) return false; + + NetworkInfo wifi = cm.getNetworkInfo(ConnectivityManager.TYPE_WIFI); + NetworkInfo mobile = cm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE); + return wifi.isConnected() || mobile.isConnected(); + } + // Screen off public static void switchScreenOff(Context ctx) { PowerManager pm = (PowerManager) ctx.getSystemService(Context.POWER_SERVICE); diff --git a/core/java/com/android/internal/util/du/Utils.java b/core/java/com/android/internal/util/du/Utils.java index 5ff2e8602f299..2d0f569894722 100644 --- a/core/java/com/android/internal/util/du/Utils.java +++ b/core/java/com/android/internal/util/du/Utils.java @@ -61,32 +61,6 @@ public class Utils { private static OverlayManager mOverlayService; - // Check to see if device is WiFi only - public static boolean isWifiOnly(Context context) { - ConnectivityManager cm = (ConnectivityManager)context.getSystemService( - Context.CONNECTIVITY_SERVICE); - return (cm.isNetworkSupported(ConnectivityManager.TYPE_MOBILE) == false); - } - - // Check if device is connected to Wi-Fi - public static boolean isWiFiConnected(Context context) { - ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); - if (cm == null) return false; - - NetworkInfo wifi = cm.getNetworkInfo(ConnectivityManager.TYPE_WIFI); - return wifi.isConnected(); - } - - // Check to see if device is connected to the internet - public static boolean isConnected(Context context) { - ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); - if (cm == null) return false; - - NetworkInfo wifi = cm.getNetworkInfo(ConnectivityManager.TYPE_WIFI); - NetworkInfo mobile = cm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE); - return wifi.isConnected() || mobile.isConnected(); - } - // Check to see if a package is installed public static boolean isPackageInstalled(Context context, String pkg, boolean ignoreState) { if (pkg != null) { diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java index 90cbaa76012f2..4e77761c06c87 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java @@ -56,7 +56,7 @@ import androidx.annotation.VisibleForTesting; -import com.android.internal.util.du.Utils; +import com.android.internal.util.du.ActionUtils; import com.android.settingslib.Utils; import com.android.systemui.BatteryMeterView; import com.android.systemui.DualToneHandler; @@ -387,7 +387,7 @@ private void updateshowBatteryInBar() { private void updateDataUsageView() { if (mDataUsageView.isDataUsageEnabled() != 0) { - if (Utils.isConnected(mContext)) { + if (ActionUtils.isConnected(mContext)) { DataUsageView.updateUsage(); mDataUsageLayout.setVisibility(View.VISIBLE); mDataUsageImage.setVisibility(View.VISIBLE); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/info/DataUsageView.java b/packages/SystemUI/src/com/android/systemui/statusbar/info/DataUsageView.java index 3bad365492984..1e577c854884f 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/info/DataUsageView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/info/DataUsageView.java @@ -11,7 +11,7 @@ import android.util.AttributeSet; import android.widget.TextView; -import com.android.internal.util.du.Utils; +import com.android.internal.util.du.ActionUtils; import com.android.settingslib.net.DataUsageController; import com.android.systemui.Dependency; import com.android.systemui.R; @@ -48,10 +48,10 @@ private void updateUsageData() { mobileDataController.setSubscriptionId( SubscriptionManager.getDefaultDataSubscriptionId()); final DataUsageController.DataUsageInfo info = isDataUsageEnabled() == 1 ? - (Utils.isWiFiConnected(mContext) ? + (ActionUtils.isWiFiConnected(mContext) ? mobileDataController.getDailyWifiDataUsageInfo() : mobileDataController.getDailyDataUsageInfo()) - : (Utils.isWiFiConnected(mContext) ? + : (ActionUtils.isWiFiConnected(mContext) ? mobileDataController.getWifiDataUsageInfo() : mobileDataController.getDataUsageInfo()); formatedinfo = formatDataUsage(info.usageLevel) + " "; From e9aad085652c38bc657412338985421e7fb2965f Mon Sep 17 00:00:00 2001 From: Anushek Prasal Date: Wed, 3 Jun 2020 22:11:01 +0530 Subject: [PATCH 029/157] SystemUI: Fix Ticker layout Signed-off-by: Anushek Prasal --- packages/SystemUI/res/layout/status_bar_ticker.xml | 7 ++++--- packages/SystemUI/res/values/du_dimens.xml | 2 +- packages/SystemUI/res/values/du_styles.xml | 4 ++-- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/packages/SystemUI/res/layout/status_bar_ticker.xml b/packages/SystemUI/res/layout/status_bar_ticker.xml index f25fd56134ef0..3102bf3049e0f 100644 --- a/packages/SystemUI/res/layout/status_bar_ticker.xml +++ b/packages/SystemUI/res/layout/status_bar_ticker.xml @@ -19,7 +19,9 @@ xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" + android:gravity="center_vertical" android:paddingStart="@dimen/ticker_start_padding" + android:paddingTop="@dimen/ticker_top_padding" android:animationCache="false" android:orientation="horizontal"> @@ -31,19 +33,18 @@ 6dp + 1.5dp 4dp - 2dp 10dp diff --git a/packages/SystemUI/res/values/du_styles.xml b/packages/SystemUI/res/values/du_styles.xml index dcf82a8815597..eca67bbbf9bda 100644 --- a/packages/SystemUI/res/values/du_styles.xml +++ b/packages/SystemUI/res/values/du_styles.xml @@ -33,8 +33,8 @@