Loading core/java/android/app/ActivityManagerInternal.java +13 −0 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ import android.content.ComponentName; import android.content.IIntentSender; import android.content.Intent; import android.content.res.Configuration; import android.net.NetworkPolicyManager.UidStateWithSeqObserver; import android.os.Bundle; import android.os.IBinder; import android.service.voice.IVoiceInteractionSession; Loading Loading @@ -233,4 +234,16 @@ public abstract class ActivityManagerInternal { * @see android.view.WindowManager.LayoutParams#TYPE_APPLICATION_OVERLAY */ public abstract void setHasOverlayUi(int pid, boolean hasOverlayUi); /** * Set observer which listens to uid state changes. Uid state change along with the sequence * number associated with it needs to be passed to {@link UidStateWithSeqObserver}. */ public abstract void setUidStateWithSeqObserver(UidStateWithSeqObserver observer); /** * Notifies that NetworkPolicyManagerService has updated the network policy rules for * a specific {@param uid} and {@param procStateSeq}. */ public abstract void notifyNetworkPolicyRulesUpdated(int uid, long procStateSeq); } core/java/android/app/ActivityThread.java +146 −0 Original line number Diff line number Diff line Loading @@ -180,6 +180,7 @@ public final class ActivityThread { public static final boolean DEBUG_CONFIGURATION = false; private static final boolean DEBUG_SERVICE = false; private static final boolean DEBUG_MEMORY_TRIM = false; private static final boolean DEBUG_NETWORK = false; private static final boolean DEBUG_PROVIDER = false; private static final boolean DEBUG_ORDER = false; private static final long MIN_TIME_BETWEEN_GCS = 5*1000; Loading @@ -202,6 +203,55 @@ public final class ActivityThread { // Whether to invoke an activity callback after delivering new configuration. private static final boolean REPORT_TO_ACTIVITY = true; /** * This is the time main thread waits for the NetworkPolicyManagerService to notify * that network is unrestricted. After this the app components will be launched anyway. */ private long mWaitForNetworkTimeoutMs; /** * This is only for logging purposes. This will help us identify if the waiting for network * is responsible for any lag that user might see. */ private static final int WAIT_FOR_NETWORK_THRESHOLD_MS = 100; // 0.1 sec /** * State indicating that there is no need for any blocking for network. */ public static final int NETWORK_STATE_NO_CHANGE = 0; /** * State indicating that main thread should wait for ActivityManagerService to notify * before the app components are launched. */ public static final int NETWORK_STATE_BLOCK = 1; /** * State indicating that any threads waiting for ActivityManagerService to notify should * be unblocked. */ public static final int NETWORK_STATE_UNBLOCK = 2; /** * Constant for indicating a invalid sequence number. */ public static final long INVALID_PROC_STATE_SEQ = -1; /** * Current sequence number associated with the process state change. */ @GuardedBy("mNetworkPolicyLock") private long mCurProcStateSeq; /** * Indicates whether any component being launched should block for network before * proceeding. */ @GuardedBy("mNetworkPolicyLock") private boolean mShouldBlockForNetwork; private Object mNetworkPolicyLock = new Object(); private ContextImpl mSystemContext; static volatile IPackageManager sPackageManager; Loading Loading @@ -1305,6 +1355,18 @@ public final class ActivityThread { } } @Override public void setBlockForNetworkState(int blockState, long targetProcStateSeq) { synchronized (mNetworkPolicyLock) { if (blockState == NETWORK_STATE_UNBLOCK) { unblockForNetworkAccessLN(targetProcStateSeq); } else if (blockState == NETWORK_STATE_BLOCK) { mShouldBlockForNetwork = true; } mCurProcStateSeq = targetProcStateSeq; } } @Override public void scheduleInstallProvider(ProviderInfo provider) { sendMessage(H.INSTALL_PROVIDER, provider); Loading Loading @@ -1388,6 +1450,13 @@ public final class ActivityThread { public void handleTrustStorageUpdate() { NetworkSecurityPolicy.getInstance().handleTrustStorageUpdate(); } @Override public void notifyNetworkStateUpdated(long curProcStateSeq) { synchronized (mNetworkPolicyLock) { unblockForNetworkAccessLN(curProcStateSeq); } } } private int getLifecycleSeq() { Loading Loading @@ -2079,6 +2148,79 @@ public final class ActivityThread { } } void blockForNetworkAccessInForegroundService(long procStateSeq) { synchronized (mNetworkPolicyLock) { if (mCurProcStateSeq >= procStateSeq) { if (mShouldBlockForNetwork) { blockForNetworkAccessLN(); } } else { mCurProcStateSeq = procStateSeq; mShouldBlockForNetwork = true; blockForNetworkAccessLN(); } } } /** * Block for unrestricted network. It will register a listener to AMS and wait for it to * notify that network policy rules are updated. This method is called before relevant app * components are launched. */ private void blockForNetworkAccessLN() { try { if (ActivityManager.getService().registerNetworkRulesUpdateListener( mAppThread, mCurProcStateSeq)) { try { Slog.d(TAG, "Uid: " + mBoundApplication.appInfo.uid + " seq: " + mCurProcStateSeq + ". Blocking for network. callers: " + Debug.getCallers(3)); final long blockStartTime = SystemClock.elapsedRealtime(); mNetworkPolicyLock.wait(mWaitForNetworkTimeoutMs); final long totalWaitTime = (SystemClock.elapsedRealtime() - blockStartTime); if (totalWaitTime >= mWaitForNetworkTimeoutMs) { Slog.wtf(TAG, "Timed out waiting for the network rules to get updated." + " Uid: " + mBoundApplication.appInfo.uid + " seq: " + mCurProcStateSeq); } else if (totalWaitTime >= WAIT_FOR_NETWORK_THRESHOLD_MS) { Slog.d(TAG, "Waited for time greater than threshold." + " Uid: " + mBoundApplication.appInfo.uid + " seq: " + mCurProcStateSeq); } if (DEBUG_NETWORK) { Slog.d(TAG, "Uid: " + mBoundApplication.appInfo.uid + " seq: " + mCurProcStateSeq + ". Time waited for network: " + totalWaitTime); } } catch (InterruptedException ignored) { } } } catch (RemoteException ignored) { } } public void checkAndBlockForNetworkAccess() { synchronized (mNetworkPolicyLock) { if (mWaitForNetworkTimeoutMs > 0 && mShouldBlockForNetwork) { blockForNetworkAccessLN(); } } } /** * Unblock the main thread if it is waiting for network. */ private void unblockForNetworkAccessLN(long procStateSeq) { if (mShouldBlockForNetwork && procStateSeq >= mCurProcStateSeq) { if (DEBUG_NETWORK) { Slog.d(TAG, "Unblocking threads waiting for network. uid: " + mBoundApplication.appInfo.uid + " procStateSeq: " + procStateSeq); } mNetworkPolicyLock.notifyAll(); mShouldBlockForNetwork = false; } } ActivityThread() { mResourcesManager = ResourcesManager.getInstance(); } Loading Loading @@ -2671,6 +2813,7 @@ public final class ActivityThread { activity.mIntent = customIntent; } r.lastNonConfigurationInstances = null; checkAndBlockForNetworkAccess(); activity.mStartedActivity = false; int theme = r.activityInfo.getThemeResource(); if (theme != 0) { Loading Loading @@ -5350,6 +5493,9 @@ public final class ActivityThread { View.mDebugViewAttributes = mCoreSettings.getInt(Settings.Global.DEBUG_VIEW_ATTRIBUTES, 0) != 0; mWaitForNetworkTimeoutMs = mCoreSettings.getLong( Settings.Global.WAIT_FOR_NETWORK_TIMEOUT_MS); /** * For system applications on userdebug/eng builds, log stack * traces of disk and network access to dropbox for analysis. Loading core/java/android/app/IActivityManager.aidl +11 −1 Original line number Diff line number Diff line Loading @@ -199,7 +199,7 @@ interface IActivityManager { int getRequestedOrientation(in IBinder token); void unbindFinished(in IBinder token, in Intent service, boolean doRebind); void setProcessForeground(in IBinder token, int pid, boolean isForeground); void setServiceForeground(in ComponentName className, in IBinder token, long setServiceForeground(in ComponentName className, in IBinder token, int id, in Notification notification, int flags); boolean moveActivityTaskToBack(in IBinder token, boolean nonRoot); void getMemoryInfo(out ActivityManager.MemoryInfo outInfo); Loading Loading @@ -603,6 +603,16 @@ interface IActivityManager { ActivityManager.TaskSnapshot getTaskSnapshot(int taskId); void scheduleApplicationInfoChanged(in List<String> packageNames, int userId); /** * Registers a listener for network rules state. When the network policy rules in * NetworkPolicyManagerService are updated, ActivityManagerService will notify these * registered listeners. * * @param procStateSeq The sequence number for which the listener is interested in knowing * the network policy rules state. * @return true if the listener is registered, false otherwise. */ boolean registerNetworkRulesUpdateListener(IApplicationThread listener, long procStateSeq); // WARNING: when these transactions are updated, check if they are any callers on the native // side. If so, make sure they are using the correct transaction ids and arguments. Loading core/java/android/app/IApplicationThread.aidl +2 −0 Original line number Diff line number Diff line Loading @@ -153,4 +153,6 @@ oneway interface IApplicationThread { void handleTrustStorageUpdate(); void attachAgent(String path); void scheduleApplicationInfoChanged(in ApplicationInfo ai); void setBlockForNetworkState(int blockState, long procStateSeq); void notifyNetworkStateUpdated(long procStateSeq); } core/java/android/app/Service.java +9 −7 Original line number Diff line number Diff line Loading @@ -700,9 +700,11 @@ public abstract class Service extends ContextWrapper implements ComponentCallbac */ public final void startForeground(int id, Notification notification) { try { mActivityManager.setServiceForeground( new ComponentName(this, mClassName), mToken, id, notification, 0); final long procStateSeq = mActivityManager.setServiceForeground( new ComponentName(this, mClassName), mToken, id, notification, 0); if (procStateSeq != ActivityThread.INVALID_PROC_STATE_SEQ && mThread != null) { mThread.blockForNetworkAccessInForegroundService(procStateSeq); } } catch (RemoteException ex) { } } Loading Loading
core/java/android/app/ActivityManagerInternal.java +13 −0 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ import android.content.ComponentName; import android.content.IIntentSender; import android.content.Intent; import android.content.res.Configuration; import android.net.NetworkPolicyManager.UidStateWithSeqObserver; import android.os.Bundle; import android.os.IBinder; import android.service.voice.IVoiceInteractionSession; Loading Loading @@ -233,4 +234,16 @@ public abstract class ActivityManagerInternal { * @see android.view.WindowManager.LayoutParams#TYPE_APPLICATION_OVERLAY */ public abstract void setHasOverlayUi(int pid, boolean hasOverlayUi); /** * Set observer which listens to uid state changes. Uid state change along with the sequence * number associated with it needs to be passed to {@link UidStateWithSeqObserver}. */ public abstract void setUidStateWithSeqObserver(UidStateWithSeqObserver observer); /** * Notifies that NetworkPolicyManagerService has updated the network policy rules for * a specific {@param uid} and {@param procStateSeq}. */ public abstract void notifyNetworkPolicyRulesUpdated(int uid, long procStateSeq); }
core/java/android/app/ActivityThread.java +146 −0 Original line number Diff line number Diff line Loading @@ -180,6 +180,7 @@ public final class ActivityThread { public static final boolean DEBUG_CONFIGURATION = false; private static final boolean DEBUG_SERVICE = false; private static final boolean DEBUG_MEMORY_TRIM = false; private static final boolean DEBUG_NETWORK = false; private static final boolean DEBUG_PROVIDER = false; private static final boolean DEBUG_ORDER = false; private static final long MIN_TIME_BETWEEN_GCS = 5*1000; Loading @@ -202,6 +203,55 @@ public final class ActivityThread { // Whether to invoke an activity callback after delivering new configuration. private static final boolean REPORT_TO_ACTIVITY = true; /** * This is the time main thread waits for the NetworkPolicyManagerService to notify * that network is unrestricted. After this the app components will be launched anyway. */ private long mWaitForNetworkTimeoutMs; /** * This is only for logging purposes. This will help us identify if the waiting for network * is responsible for any lag that user might see. */ private static final int WAIT_FOR_NETWORK_THRESHOLD_MS = 100; // 0.1 sec /** * State indicating that there is no need for any blocking for network. */ public static final int NETWORK_STATE_NO_CHANGE = 0; /** * State indicating that main thread should wait for ActivityManagerService to notify * before the app components are launched. */ public static final int NETWORK_STATE_BLOCK = 1; /** * State indicating that any threads waiting for ActivityManagerService to notify should * be unblocked. */ public static final int NETWORK_STATE_UNBLOCK = 2; /** * Constant for indicating a invalid sequence number. */ public static final long INVALID_PROC_STATE_SEQ = -1; /** * Current sequence number associated with the process state change. */ @GuardedBy("mNetworkPolicyLock") private long mCurProcStateSeq; /** * Indicates whether any component being launched should block for network before * proceeding. */ @GuardedBy("mNetworkPolicyLock") private boolean mShouldBlockForNetwork; private Object mNetworkPolicyLock = new Object(); private ContextImpl mSystemContext; static volatile IPackageManager sPackageManager; Loading Loading @@ -1305,6 +1355,18 @@ public final class ActivityThread { } } @Override public void setBlockForNetworkState(int blockState, long targetProcStateSeq) { synchronized (mNetworkPolicyLock) { if (blockState == NETWORK_STATE_UNBLOCK) { unblockForNetworkAccessLN(targetProcStateSeq); } else if (blockState == NETWORK_STATE_BLOCK) { mShouldBlockForNetwork = true; } mCurProcStateSeq = targetProcStateSeq; } } @Override public void scheduleInstallProvider(ProviderInfo provider) { sendMessage(H.INSTALL_PROVIDER, provider); Loading Loading @@ -1388,6 +1450,13 @@ public final class ActivityThread { public void handleTrustStorageUpdate() { NetworkSecurityPolicy.getInstance().handleTrustStorageUpdate(); } @Override public void notifyNetworkStateUpdated(long curProcStateSeq) { synchronized (mNetworkPolicyLock) { unblockForNetworkAccessLN(curProcStateSeq); } } } private int getLifecycleSeq() { Loading Loading @@ -2079,6 +2148,79 @@ public final class ActivityThread { } } void blockForNetworkAccessInForegroundService(long procStateSeq) { synchronized (mNetworkPolicyLock) { if (mCurProcStateSeq >= procStateSeq) { if (mShouldBlockForNetwork) { blockForNetworkAccessLN(); } } else { mCurProcStateSeq = procStateSeq; mShouldBlockForNetwork = true; blockForNetworkAccessLN(); } } } /** * Block for unrestricted network. It will register a listener to AMS and wait for it to * notify that network policy rules are updated. This method is called before relevant app * components are launched. */ private void blockForNetworkAccessLN() { try { if (ActivityManager.getService().registerNetworkRulesUpdateListener( mAppThread, mCurProcStateSeq)) { try { Slog.d(TAG, "Uid: " + mBoundApplication.appInfo.uid + " seq: " + mCurProcStateSeq + ". Blocking for network. callers: " + Debug.getCallers(3)); final long blockStartTime = SystemClock.elapsedRealtime(); mNetworkPolicyLock.wait(mWaitForNetworkTimeoutMs); final long totalWaitTime = (SystemClock.elapsedRealtime() - blockStartTime); if (totalWaitTime >= mWaitForNetworkTimeoutMs) { Slog.wtf(TAG, "Timed out waiting for the network rules to get updated." + " Uid: " + mBoundApplication.appInfo.uid + " seq: " + mCurProcStateSeq); } else if (totalWaitTime >= WAIT_FOR_NETWORK_THRESHOLD_MS) { Slog.d(TAG, "Waited for time greater than threshold." + " Uid: " + mBoundApplication.appInfo.uid + " seq: " + mCurProcStateSeq); } if (DEBUG_NETWORK) { Slog.d(TAG, "Uid: " + mBoundApplication.appInfo.uid + " seq: " + mCurProcStateSeq + ". Time waited for network: " + totalWaitTime); } } catch (InterruptedException ignored) { } } } catch (RemoteException ignored) { } } public void checkAndBlockForNetworkAccess() { synchronized (mNetworkPolicyLock) { if (mWaitForNetworkTimeoutMs > 0 && mShouldBlockForNetwork) { blockForNetworkAccessLN(); } } } /** * Unblock the main thread if it is waiting for network. */ private void unblockForNetworkAccessLN(long procStateSeq) { if (mShouldBlockForNetwork && procStateSeq >= mCurProcStateSeq) { if (DEBUG_NETWORK) { Slog.d(TAG, "Unblocking threads waiting for network. uid: " + mBoundApplication.appInfo.uid + " procStateSeq: " + procStateSeq); } mNetworkPolicyLock.notifyAll(); mShouldBlockForNetwork = false; } } ActivityThread() { mResourcesManager = ResourcesManager.getInstance(); } Loading Loading @@ -2671,6 +2813,7 @@ public final class ActivityThread { activity.mIntent = customIntent; } r.lastNonConfigurationInstances = null; checkAndBlockForNetworkAccess(); activity.mStartedActivity = false; int theme = r.activityInfo.getThemeResource(); if (theme != 0) { Loading Loading @@ -5350,6 +5493,9 @@ public final class ActivityThread { View.mDebugViewAttributes = mCoreSettings.getInt(Settings.Global.DEBUG_VIEW_ATTRIBUTES, 0) != 0; mWaitForNetworkTimeoutMs = mCoreSettings.getLong( Settings.Global.WAIT_FOR_NETWORK_TIMEOUT_MS); /** * For system applications on userdebug/eng builds, log stack * traces of disk and network access to dropbox for analysis. Loading
core/java/android/app/IActivityManager.aidl +11 −1 Original line number Diff line number Diff line Loading @@ -199,7 +199,7 @@ interface IActivityManager { int getRequestedOrientation(in IBinder token); void unbindFinished(in IBinder token, in Intent service, boolean doRebind); void setProcessForeground(in IBinder token, int pid, boolean isForeground); void setServiceForeground(in ComponentName className, in IBinder token, long setServiceForeground(in ComponentName className, in IBinder token, int id, in Notification notification, int flags); boolean moveActivityTaskToBack(in IBinder token, boolean nonRoot); void getMemoryInfo(out ActivityManager.MemoryInfo outInfo); Loading Loading @@ -603,6 +603,16 @@ interface IActivityManager { ActivityManager.TaskSnapshot getTaskSnapshot(int taskId); void scheduleApplicationInfoChanged(in List<String> packageNames, int userId); /** * Registers a listener for network rules state. When the network policy rules in * NetworkPolicyManagerService are updated, ActivityManagerService will notify these * registered listeners. * * @param procStateSeq The sequence number for which the listener is interested in knowing * the network policy rules state. * @return true if the listener is registered, false otherwise. */ boolean registerNetworkRulesUpdateListener(IApplicationThread listener, long procStateSeq); // WARNING: when these transactions are updated, check if they are any callers on the native // side. If so, make sure they are using the correct transaction ids and arguments. Loading
core/java/android/app/IApplicationThread.aidl +2 −0 Original line number Diff line number Diff line Loading @@ -153,4 +153,6 @@ oneway interface IApplicationThread { void handleTrustStorageUpdate(); void attachAgent(String path); void scheduleApplicationInfoChanged(in ApplicationInfo ai); void setBlockForNetworkState(int blockState, long procStateSeq); void notifyNetworkStateUpdated(long procStateSeq); }
core/java/android/app/Service.java +9 −7 Original line number Diff line number Diff line Loading @@ -700,9 +700,11 @@ public abstract class Service extends ContextWrapper implements ComponentCallbac */ public final void startForeground(int id, Notification notification) { try { mActivityManager.setServiceForeground( new ComponentName(this, mClassName), mToken, id, notification, 0); final long procStateSeq = mActivityManager.setServiceForeground( new ComponentName(this, mClassName), mToken, id, notification, 0); if (procStateSeq != ActivityThread.INVALID_PROC_STATE_SEQ && mThread != null) { mThread.blockForNetworkAccessInForegroundService(procStateSeq); } } catch (RemoteException ex) { } } Loading