summaryrefslogtreecommitdiffstats
path: root/services/java/com/android/server
diff options
context:
space:
mode:
Diffstat (limited to 'services/java/com/android/server')
-rw-r--r--services/java/com/android/server/AppWidgetService.java115
-rw-r--r--services/java/com/android/server/BackupManagerService.java42
-rw-r--r--services/java/com/android/server/ConnectivityService.java60
-rw-r--r--services/java/com/android/server/WallpaperManagerService.java2
-rw-r--r--services/java/com/android/server/accessibility/AccessibilityManagerService.java84
-rw-r--r--services/java/com/android/server/net/NetworkStatsService.java106
-rw-r--r--services/java/com/android/server/wm/Session.java12
-rw-r--r--services/java/com/android/server/wm/WindowManagerService.java35
-rw-r--r--services/java/com/android/server/wm/WindowState.java12
9 files changed, 314 insertions, 154 deletions
diff --git a/services/java/com/android/server/AppWidgetService.java b/services/java/com/android/server/AppWidgetService.java
index 9f4936d..dd649e7 100644
--- a/services/java/com/android/server/AppWidgetService.java
+++ b/services/java/com/android/server/AppWidgetService.java
@@ -172,6 +172,10 @@ class AppWidgetService extends IAppWidgetService.Stub
boolean mSafeMode;
boolean mStateLoaded;
+ // These are for debugging only -- widgets are going missing in some rare instances
+ ArrayList<Provider> mDeletedProviders = new ArrayList<Provider>();
+ ArrayList<Host> mDeletedHosts = new ArrayList<Host>();
+
AppWidgetService(Context context) {
mContext = context;
mPackageManager = context.getPackageManager();
@@ -219,6 +223,55 @@ class AppWidgetService extends IAppWidgetService.Stub
}
}
+ private void dumpProvider(Provider p, int index, PrintWriter pw) {
+ AppWidgetProviderInfo info = p.info;
+ pw.print(" ["); pw.print(index); pw.print("] provider ");
+ pw.print(info.provider.flattenToShortString());
+ pw.println(':');
+ pw.print(" min=("); pw.print(info.minWidth);
+ pw.print("x"); pw.print(info.minHeight);
+ pw.print(") minResize=("); pw.print(info.minResizeWidth);
+ pw.print("x"); pw.print(info.minResizeHeight);
+ pw.print(") updatePeriodMillis=");
+ pw.print(info.updatePeriodMillis);
+ pw.print(" resizeMode=");
+ pw.print(info.resizeMode);
+ pw.print(" autoAdvanceViewId=");
+ pw.print(info.autoAdvanceViewId);
+ pw.print(" initialLayout=#");
+ pw.print(Integer.toHexString(info.initialLayout));
+ pw.print(" zombie="); pw.println(p.zombie);
+ }
+
+ private void dumpHost(Host host, int index, PrintWriter pw) {
+ pw.print(" ["); pw.print(index); pw.print("] hostId=");
+ pw.print(host.hostId); pw.print(' ');
+ pw.print(host.packageName); pw.print('/');
+ pw.print(host.uid); pw.println(':');
+ pw.print(" callbacks="); pw.println(host.callbacks);
+ pw.print(" instances.size="); pw.print(host.instances.size());
+ pw.print(" zombie="); pw.println(host.zombie);
+ }
+
+ private void dumpAppWidgetId(AppWidgetId id, int index, PrintWriter pw) {
+ pw.print(" ["); pw.print(index); pw.print("] id=");
+ pw.println(id.appWidgetId);
+ pw.print(" hostId=");
+ pw.print(id.host.hostId); pw.print(' ');
+ pw.print(id.host.packageName); pw.print('/');
+ pw.println(id.host.uid);
+ if (id.provider != null) {
+ pw.print(" provider=");
+ pw.println(id.provider.info.provider.flattenToShortString());
+ }
+ if (id.host != null) {
+ pw.print(" host.callbacks="); pw.println(id.host.callbacks);
+ }
+ if (id.views != null) {
+ pw.print(" views="); pw.println(id.views);
+ }
+ }
+
@Override
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
@@ -233,61 +286,35 @@ class AppWidgetService extends IAppWidgetService.Stub
int N = mInstalledProviders.size();
pw.println("Providers:");
for (int i=0; i<N; i++) {
- Provider p = mInstalledProviders.get(i);
- AppWidgetProviderInfo info = p.info;
- pw.print(" ["); pw.print(i); pw.print("] provider ");
- pw.print(info.provider.flattenToShortString());
- pw.println(':');
- pw.print(" min=("); pw.print(info.minWidth);
- pw.print("x"); pw.print(info.minHeight);
- pw.print(") minResize=("); pw.print(info.minResizeWidth);
- pw.print("x"); pw.print(info.minResizeHeight);
- pw.print(") updatePeriodMillis=");
- pw.print(info.updatePeriodMillis);
- pw.print(" resizeMode=");
- pw.print(info.resizeMode);
- pw.print(" autoAdvanceViewId=");
- pw.print(info.autoAdvanceViewId);
- pw.print(" initialLayout=#");
- pw.print(Integer.toHexString(info.initialLayout));
- pw.print(" zombie="); pw.println(p.zombie);
+ dumpProvider(mInstalledProviders.get(i), i, pw);
}
N = mAppWidgetIds.size();
pw.println(" ");
pw.println("AppWidgetIds:");
for (int i=0; i<N; i++) {
- AppWidgetId id = mAppWidgetIds.get(i);
- pw.print(" ["); pw.print(i); pw.print("] id=");
- pw.println(id.appWidgetId);
- pw.print(" hostId=");
- pw.print(id.host.hostId); pw.print(' ');
- pw.print(id.host.packageName); pw.print('/');
- pw.println(id.host.uid);
- if (id.provider != null) {
- pw.print(" provider=");
- pw.println(id.provider.info.provider.flattenToShortString());
- }
- if (id.host != null) {
- pw.print(" host.callbacks="); pw.println(id.host.callbacks);
- }
- if (id.views != null) {
- pw.print(" views="); pw.println(id.views);
- }
+ dumpAppWidgetId(mAppWidgetIds.get(i), i, pw);
}
N = mHosts.size();
pw.println(" ");
pw.println("Hosts:");
for (int i=0; i<N; i++) {
- Host host = mHosts.get(i);
- pw.print(" ["); pw.print(i); pw.print("] hostId=");
- pw.print(host.hostId); pw.print(' ');
- pw.print(host.packageName); pw.print('/');
- pw.print(host.uid); pw.println(':');
- pw.print(" callbacks="); pw.println(host.callbacks);
- pw.print(" instances.size="); pw.print(host.instances.size());
- pw.print(" zombie="); pw.println(host.zombie);
+ dumpHost(mHosts.get(i), i, pw);
+ }
+
+ N = mDeletedProviders.size();
+ pw.println(" ");
+ pw.println("Deleted Providers:");
+ for (int i=0; i<N; i++) {
+ dumpProvider(mDeletedProviders.get(i), i, pw);
+ }
+
+ N = mDeletedHosts.size();
+ pw.println(" ");
+ pw.println("Deleted Hosts:");
+ for (int i=0; i<N; i++) {
+ dumpHost(mDeletedHosts.get(i), i, pw);
}
}
}
@@ -363,6 +390,7 @@ class AppWidgetService extends IAppWidgetService.Stub
}
host.instances.clear();
mHosts.remove(host);
+ mDeletedHosts.add(host);
// it's gone or going away, abruptly drop the callback connection
host.callbacks = null;
}
@@ -934,6 +962,7 @@ class AppWidgetService extends IAppWidgetService.Stub
}
p.instances.clear();
mInstalledProviders.remove(index);
+ mDeletedProviders.add(p);
// no need to send the DISABLE broadcast, since the receiver is gone anyway
cancelBroadcasts(p);
}
diff --git a/services/java/com/android/server/BackupManagerService.java b/services/java/com/android/server/BackupManagerService.java
index 7b8657a..5758954 100644
--- a/services/java/com/android/server/BackupManagerService.java
+++ b/services/java/com/android/server/BackupManagerService.java
@@ -228,6 +228,7 @@ class BackupManagerService extends IBackupManager.Stub {
// completed.
final Object mAgentConnectLock = new Object();
IBackupAgent mConnectedAgent;
+ volatile boolean mBackupRunning;
volatile boolean mConnecting;
volatile long mLastBackupPass;
volatile long mNextBackupPass;
@@ -434,6 +435,9 @@ class BackupManagerService extends IBackupManager.Stub {
IBackupTransport transport = getTransport(mCurrentTransport);
if (transport == null) {
Slog.v(TAG, "Backup requested but no transport available");
+ synchronized (mQueueLock) {
+ mBackupRunning = false;
+ }
mWakelock.release();
break;
}
@@ -470,6 +474,9 @@ class BackupManagerService extends IBackupManager.Stub {
sendMessage(pbtMessage);
} else {
Slog.v(TAG, "Backup requested but nothing pending");
+ synchronized (mQueueLock) {
+ mBackupRunning = false;
+ }
mWakelock.release();
}
break;
@@ -804,14 +811,19 @@ class BackupManagerService extends IBackupManager.Stub {
// Don't run backups now if we're disabled or not yet
// fully set up.
if (mEnabled && mProvisioned) {
- if (DEBUG) Slog.v(TAG, "Running a backup pass");
+ if (!mBackupRunning) {
+ if (DEBUG) Slog.v(TAG, "Running a backup pass");
- // Acquire the wakelock and pass it to the backup thread. it will
- // be released once backup concludes.
- mWakelock.acquire();
+ // Acquire the wakelock and pass it to the backup thread. it will
+ // be released once backup concludes.
+ mBackupRunning = true;
+ mWakelock.acquire();
- Message msg = mBackupHandler.obtainMessage(MSG_RUN_BACKUP);
- mBackupHandler.sendMessage(msg);
+ Message msg = mBackupHandler.obtainMessage(MSG_RUN_BACKUP);
+ mBackupHandler.sendMessage(msg);
+ } else {
+ Slog.i(TAG, "Backup time but one already running");
+ }
} else {
Slog.w(TAG, "Backup pass but e=" + mEnabled + " p=" + mProvisioned);
}
@@ -1948,9 +1960,14 @@ class BackupManagerService extends IBackupManager.Stub {
writeRestoreTokens();
}
- // Set up the next backup pass
- if (mStatus == BackupConstants.TRANSPORT_NOT_INITIALIZED) {
- backupNow();
+ // Set up the next backup pass - at this point we can set mBackupRunning
+ // to false to allow another pass to fire, because we're done with the
+ // state machine sequence and the wakelock is refcounted.
+ synchronized (mQueueLock) {
+ mBackupRunning = false;
+ if (mStatus == BackupConstants.TRANSPORT_NOT_INITIALIZED) {
+ backupNow();
+ }
}
// Only once we're entirely finished do we release the wakelock
@@ -2400,8 +2417,8 @@ class BackupManagerService extends IBackupManager.Stub {
mLatchObject.notifyAll();
}
sendEndBackup();
- mWakelock.release();
if (DEBUG) Slog.d(TAG, "Full backup pass complete.");
+ mWakelock.release();
}
}
@@ -2908,8 +2925,8 @@ class BackupManagerService extends IBackupManager.Stub {
mLatchObject.notifyAll();
}
sendEndRestore();
- mWakelock.release();
Slog.d(TAG, "Full restore pass complete.");
+ mWakelock.release();
}
}
@@ -5630,7 +5647,8 @@ class BackupManagerService extends IBackupManager.Stub {
+ " / " + (!mProvisioned ? "not " : "") + "provisioned / "
+ (this.mPendingInits.size() == 0 ? "not " : "") + "pending init");
pw.println("Auto-restore is " + (mAutoRestore ? "enabled" : "disabled"));
- pw.println("Last backup pass: " + mLastBackupPass
+ if (mBackupRunning) pw.println("Backup currently running");
+ pw.println("Last backup pass started: " + mLastBackupPass
+ " (now = " + System.currentTimeMillis() + ')');
pw.println(" next scheduled: " + mNextBackupPass);
diff --git a/services/java/com/android/server/ConnectivityService.java b/services/java/com/android/server/ConnectivityService.java
index 8112b1d..ce31474 100644
--- a/services/java/com/android/server/ConnectivityService.java
+++ b/services/java/com/android/server/ConnectivityService.java
@@ -284,6 +284,9 @@ public class ConnectivityService extends IConnectivityManager.Stub {
// track the current default http proxy - tell the world if we get a new one (real change)
private ProxyProperties mDefaultProxy = null;
+ private Object mDefaultProxyLock = new Object();
+ private boolean mDefaultProxyDisabled = false;
+
// track the global proxy.
private ProxyProperties mGlobalProxy = null;
private final Object mGlobalProxyLock = new Object();
@@ -1770,7 +1773,7 @@ public class ConnectivityService extends IConnectivityManager.Stub {
}
}
if (mNetConfigs[netType].isDefault()) {
- handleApplyDefaultProxy(netType);
+ handleApplyDefaultProxy(newLp.getHttpProxy());
}
} else {
if (VDBG) {
@@ -2549,10 +2552,10 @@ public class ConnectivityService extends IConnectivityManager.Stub {
return;
}
- public synchronized ProxyProperties getProxy() {
- if (mGlobalProxy != null) return mGlobalProxy;
- if (mDefaultProxy != null) return mDefaultProxy;
- return null;
+ public ProxyProperties getProxy() {
+ synchronized (mDefaultProxyLock) {
+ return mDefaultProxyDisabled ? null : mDefaultProxy;
+ }
}
public void setGlobalProxy(ProxyProperties proxyProperties) {
@@ -2583,7 +2586,7 @@ public class ConnectivityService extends IConnectivityManager.Stub {
if (mGlobalProxy == null) {
proxyProperties = mDefaultProxy;
}
- sendProxyBroadcast(proxyProperties);
+ //sendProxyBroadcast(proxyProperties);
}
private void loadGlobalProxy() {
@@ -2606,23 +2609,19 @@ public class ConnectivityService extends IConnectivityManager.Stub {
}
}
- private void handleApplyDefaultProxy(int type) {
- // check if new default - push it out to all VM if so
- ProxyProperties proxy = mNetTrackers[type].getLinkProperties().getHttpProxy();
- synchronized (this) {
+ private void handleApplyDefaultProxy(ProxyProperties proxy) {
+ if (proxy != null && TextUtils.isEmpty(proxy.getHost())) {
+ proxy = null;
+ }
+ synchronized (mDefaultProxyLock) {
if (mDefaultProxy != null && mDefaultProxy.equals(proxy)) return;
if (mDefaultProxy == proxy) return;
- if (proxy != null && !TextUtils.isEmpty(proxy.getHost())) {
- mDefaultProxy = proxy;
- } else {
- mDefaultProxy = null;
+ mDefaultProxy = proxy;
+
+ if (!mDefaultProxyDisabled) {
+ sendProxyBroadcast(proxy);
}
}
- if (VDBG) log("changing default proxy to " + proxy);
-
- // global trumps default, if set, ignore this.
- if (mGlobalProxy != null) return;
- sendProxyBroadcast(proxy);
}
private void handleDeprecatedGlobalHttpProxy() {
@@ -2850,17 +2849,30 @@ public class ConnectivityService extends IConnectivityManager.Stub {
bumpDns();
}
- // TODO: temporarily remove http proxy?
+ // Temporarily disable the default proxy.
+ synchronized (mDefaultProxyLock) {
+ mDefaultProxyDisabled = true;
+ if (mDefaultProxy != null) {
+ sendProxyBroadcast(null);
+ }
+ }
+
+ // TODO: support proxy per network.
}
public void restore() {
synchronized (mDnsLock) {
- if (!mDnsOverridden) {
- return;
+ if (mDnsOverridden) {
+ mDnsOverridden = false;
+ mHandler.sendEmptyMessage(EVENT_RESTORE_DNS);
+ }
+ }
+ synchronized (mDefaultProxyLock) {
+ mDefaultProxyDisabled = false;
+ if (mDefaultProxy != null) {
+ sendProxyBroadcast(mDefaultProxy);
}
- mDnsOverridden = false;
}
- mHandler.sendEmptyMessage(EVENT_RESTORE_DNS);
}
}
}
diff --git a/services/java/com/android/server/WallpaperManagerService.java b/services/java/com/android/server/WallpaperManagerService.java
index 253e741..a0e28ed 100644
--- a/services/java/com/android/server/WallpaperManagerService.java
+++ b/services/java/com/android/server/WallpaperManagerService.java
@@ -834,7 +834,7 @@ class WallpaperManagerService extends IWallpaperManager.Stub {
}
if (DEBUG) Slog.v(TAG, "settingsRestored: success=" + success);
if (success) {
- bindWallpaperComponentLocked(null, false, false);
+ bindWallpaperComponentLocked(mNextWallpaperComponent, false, false);
}
}
}
diff --git a/services/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/java/com/android/server/accessibility/AccessibilityManagerService.java
index ed8fa40..fd528cc 100644
--- a/services/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -298,16 +298,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
super.onChange(selfChange);
synchronized (mLock) {
- mIsAccessibilityEnabled = Settings.Secure.getInt(
- mContext.getContentResolver(),
- Settings.Secure.ACCESSIBILITY_ENABLED, 0) == 1;
- if (mIsAccessibilityEnabled) {
- manageServicesLocked();
- } else {
- unbindAllServicesLocked();
- }
- updateInputFilterLocked();
- sendStateToClientsLocked();
+ handleAccessibilityEnabledSettingChangedLocked();
}
}
});
@@ -354,6 +345,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
client.asBinder().linkToDeath(new DeathRecipient() {
public void binderDied() {
synchronized (mLock) {
+ addedClient.asBinder().unlinkToDeath(this, 0);
mClients.remove(addedClient);
}
}
@@ -445,10 +437,12 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
IAccessibilityInteractionConnection connection) throws RemoteException {
synchronized (mLock) {
final IWindow addedWindowToken = windowToken;
+ final IAccessibilityInteractionConnection addedConnection = connection;
final int windowId = sNextWindowId++;
- connection.asBinder().linkToDeath(new DeathRecipient() {
+ addedConnection.asBinder().linkToDeath(new DeathRecipient() {
public void binderDied() {
synchronized (mLock) {
+ addedConnection.asBinder().unlinkToDeath(this, 0);
removeAccessibilityInteractionConnection(addedWindowToken);
}
}
@@ -485,21 +479,23 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
ComponentName componentName = new ComponentName("foo.bar",
"AutomationAccessibilityService");
synchronized (mLock) {
- Service oldService = mComponentNameToServiceMap.get(componentName);
- if (oldService != null) {
- tryRemoveServiceLocked(oldService);
+ // If an automation services is connected to the system all services are stopped
+ // so the automation one is the only one running. Settings are not changed so when
+ // the automation service goes away the state is restored from the settings.
+
+ // Disable all services.
+ final int runningServiceCount = mServices.size();
+ for (int i = 0; i < runningServiceCount; i++) {
+ Service runningService = mServices.get(i);
+ runningService.unbind();
+ }
+ // If necessary enable accessibility and announce that.
+ if (!mIsAccessibilityEnabled) {
+ mIsAccessibilityEnabled = true;
+ sendStateToClientsLocked();
}
- // Now this service is enabled.
- mEnabledServices.add(componentName);
- // Also make sure this service is the only one.
- Settings.Secure.putString(mContext.getContentResolver(),
- Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES,
- componentName.flattenToString());
- // This API is intended for testing so enable accessibility to make
- // sure clients can start poking with the window content.
- Settings.Secure.putInt(mContext.getContentResolver(),
- Settings.Secure.ACCESSIBILITY_ENABLED, 1);
}
+ // Hook the automation service up.
AccessibilityServiceInfo accessibilityServiceInfo = new AccessibilityServiceInfo();
accessibilityServiceInfo.eventTypes = AccessibilityEvent.TYPES_ALL_MASK;
accessibilityServiceInfo.feedbackType = AccessibilityServiceInfo.FEEDBACK_GENERIC;
@@ -717,11 +713,12 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
* Manages services by starting enabled ones and stopping disabled ones.
*/
private void manageServicesLocked() {
+ unbindAutomationService();
populateEnabledServicesLocked(mEnabledServices);
final int enabledInstalledServicesCount = updateServicesStateLocked(mInstalledServices,
mEnabledServices);
// No enabled installed services => disable accessibility to avoid
- // sending accessibility events with no recipient across processes.
+ // sending accessibility events with no recipient across processes.
if (mIsAccessibilityEnabled && enabledInstalledServicesCount == 0) {
Settings.Secure.putInt(mContext.getContentResolver(),
Settings.Secure.ACCESSIBILITY_ENABLED, 0);
@@ -744,6 +741,21 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
}
/**
+ * Unbinds the automation service if such is running.
+ */
+ private void unbindAutomationService() {
+ List<Service> runningServices = mServices;
+ int runningServiceCount = mServices.size();
+ for (int i = 0; i < runningServiceCount; i++) {
+ Service service = runningServices.get(i);
+ if (service.mIsAutomation) {
+ service.unbind();
+ return;
+ }
+ }
+ }
+
+ /**
* Populates a list with the {@link ComponentName}s of all enabled
* {@link AccessibilityService}s.
*
@@ -868,6 +880,22 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
}
/**
+ * Updated the state based on the accessibility enabled setting.
+ */
+ private void handleAccessibilityEnabledSettingChangedLocked() {
+ mIsAccessibilityEnabled = Settings.Secure.getInt(
+ mContext.getContentResolver(),
+ Settings.Secure.ACCESSIBILITY_ENABLED, 0) == 1;
+ if (mIsAccessibilityEnabled) {
+ manageServicesLocked();
+ } else {
+ unbindAllServicesLocked();
+ }
+ updateInputFilterLocked();
+ sendStateToClientsLocked();
+ }
+
+ /**
* This class represents an accessibility service. It stores all per service
* data required for the service management, provides API for starting/stopping the
* service and is responsible for adding/removing the service in the data structures
@@ -1171,7 +1199,13 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
public void binderDied() {
synchronized (mLock) {
+ mService.unlinkToDeath(this, 0);
tryRemoveServiceLocked(this);
+ // We no longer have an automation service, so restore
+ // the state based on values in the settings database.
+ if (mIsAutomation) {
+ handleAccessibilityEnabledSettingChangedLocked();
+ }
}
}
diff --git a/services/java/com/android/server/net/NetworkStatsService.java b/services/java/com/android/server/net/NetworkStatsService.java
index e5f0a77..789681e 100644
--- a/services/java/com/android/server/net/NetworkStatsService.java
+++ b/services/java/com/android/server/net/NetworkStatsService.java
@@ -32,6 +32,7 @@ import static android.net.NetworkStats.SET_DEFAULT;
import static android.net.NetworkStats.SET_FOREGROUND;
import static android.net.NetworkStats.TAG_NONE;
import static android.net.NetworkStats.UID_ALL;
+import static android.net.NetworkStatsHistory.randomLong;
import static android.net.NetworkTemplate.buildTemplateMobileAll;
import static android.net.NetworkTemplate.buildTemplateWifi;
import static android.net.TrafficStats.UID_REMOVED;
@@ -48,6 +49,7 @@ import static android.text.format.DateUtils.DAY_IN_MILLIS;
import static android.text.format.DateUtils.HOUR_IN_MILLIS;
import static android.text.format.DateUtils.MINUTE_IN_MILLIS;
import static android.text.format.DateUtils.SECOND_IN_MILLIS;
+import static android.text.format.DateUtils.WEEK_IN_MILLIS;
import static com.android.internal.util.Preconditions.checkNotNull;
import static com.android.server.NetworkManagementService.LIMIT_GLOBAL_ALERT;
import static com.android.server.NetworkManagementSocketTagger.resetKernelUidStats;
@@ -62,6 +64,8 @@ import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
import android.net.IConnectivityManager;
import android.net.INetworkManagementEventObserver;
import android.net.INetworkStatsService;
@@ -113,7 +117,7 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
-import java.util.List;
+import java.util.Random;
import libcore.io.IoUtils;
@@ -1347,7 +1351,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
synchronized (mStatsLock) {
// TODO: remove this testing code, since it corrupts stats
if (argSet.contains("generate")) {
- generateRandomLocked();
+ generateRandomLocked(args);
pw.println("Generated stub stats");
return;
}
@@ -1406,42 +1410,78 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
* @deprecated only for temporary testing
*/
@Deprecated
- private void generateRandomLocked() {
- final long NET_END = System.currentTimeMillis();
- final long NET_START = NET_END - mSettings.getNetworkMaxHistory();
- final long NET_RX_BYTES = 3 * GB_IN_BYTES;
- final long NET_RX_PACKETS = NET_RX_BYTES / 1024;
- final long NET_TX_BYTES = 2 * GB_IN_BYTES;
- final long NET_TX_PACKETS = NET_TX_BYTES / 1024;
-
- final long UID_END = System.currentTimeMillis();
- final long UID_START = UID_END - mSettings.getUidMaxHistory();
- final long UID_RX_BYTES = 500 * MB_IN_BYTES;
- final long UID_RX_PACKETS = UID_RX_BYTES / 1024;
- final long UID_TX_BYTES = 100 * MB_IN_BYTES;
- final long UID_TX_PACKETS = UID_TX_BYTES / 1024;
- final long UID_OPERATIONS = UID_RX_BYTES / 2048;
-
- final List<ApplicationInfo> installedApps = mContext
- .getPackageManager().getInstalledApplications(0);
+ private void generateRandomLocked(String[] args) {
+ final long totalBytes = Long.parseLong(args[1]);
+ final long totalTime = Long.parseLong(args[2]);
+
+ final PackageManager pm = mContext.getPackageManager();
+ final ArrayList<Integer> specialUidList = Lists.newArrayList();
+ for (int i = 3; i < args.length; i++) {
+ try {
+ specialUidList.add(pm.getApplicationInfo(args[i], 0).uid);
+ } catch (NameNotFoundException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ final HashSet<Integer> otherUidSet = Sets.newHashSet();
+ for (ApplicationInfo info : pm.getInstalledApplications(0)) {
+ if (pm.checkPermission(android.Manifest.permission.INTERNET, info.packageName)
+ == PackageManager.PERMISSION_GRANTED && !specialUidList.contains(info.uid)) {
+ otherUidSet.add(info.uid);
+ }
+ }
+
+ final ArrayList<Integer> otherUidList = new ArrayList<Integer>(otherUidSet);
+
+ final long end = System.currentTimeMillis();
+ final long start = end - totalTime;
mNetworkDevStats.clear();
mNetworkXtStats.clear();
mUidStats.clear();
+
+ final Random r = new Random();
for (NetworkIdentitySet ident : mActiveIfaces.values()) {
- findOrCreateNetworkDevStatsLocked(ident).generateRandom(NET_START, NET_END,
- NET_RX_BYTES, NET_RX_PACKETS, NET_TX_BYTES, NET_TX_PACKETS, 0L);
- findOrCreateNetworkXtStatsLocked(ident).generateRandom(NET_START, NET_END, NET_RX_BYTES,
- NET_RX_PACKETS, NET_TX_BYTES, NET_TX_PACKETS, 0L);
-
- for (ApplicationInfo info : installedApps) {
- final int uid = info.uid;
- findOrCreateUidStatsLocked(ident, uid, SET_DEFAULT, TAG_NONE).generateRandom(
- UID_START, UID_END, UID_RX_BYTES, UID_RX_PACKETS, UID_TX_BYTES,
- UID_TX_PACKETS, UID_OPERATIONS);
- findOrCreateUidStatsLocked(ident, uid, SET_FOREGROUND, TAG_NONE).generateRandom(
- UID_START, UID_END, UID_RX_BYTES, UID_RX_PACKETS, UID_TX_BYTES,
- UID_TX_PACKETS, UID_OPERATIONS);
+ final NetworkStatsHistory devHistory = findOrCreateNetworkDevStatsLocked(ident);
+ final NetworkStatsHistory xtHistory = findOrCreateNetworkXtStatsLocked(ident);
+
+ final ArrayList<Integer> uidList = new ArrayList<Integer>();
+ uidList.addAll(specialUidList);
+
+ if (uidList.size() == 0) {
+ Collections.shuffle(otherUidList);
+ uidList.addAll(otherUidList);
+ }
+
+ boolean first = true;
+ long remainingBytes = totalBytes;
+ for (int uid : uidList) {
+ final NetworkStatsHistory defaultHistory = findOrCreateUidStatsLocked(
+ ident, uid, SET_DEFAULT, TAG_NONE);
+ final NetworkStatsHistory foregroundHistory = findOrCreateUidStatsLocked(
+ ident, uid, SET_FOREGROUND, TAG_NONE);
+
+ final long uidBytes = totalBytes / uidList.size();
+
+ final float fractionDefault = r.nextFloat();
+ final long defaultBytes = (long) (uidBytes * fractionDefault);
+ final long foregroundBytes = (long) (uidBytes * (1 - fractionDefault));
+
+ defaultHistory.generateRandom(start, end, defaultBytes);
+ foregroundHistory.generateRandom(start, end, foregroundBytes);
+
+ if (first) {
+ final long bumpTime = (start + end) / 2;
+ defaultHistory.recordData(
+ bumpTime, bumpTime + DAY_IN_MILLIS, 200 * MB_IN_BYTES, 0);
+ first = false;
+ }
+
+ devHistory.recordEntireHistory(defaultHistory);
+ devHistory.recordEntireHistory(foregroundHistory);
+ xtHistory.recordEntireHistory(defaultHistory);
+ xtHistory.recordEntireHistory(foregroundHistory);
}
}
}
diff --git a/services/java/com/android/server/wm/Session.java b/services/java/com/android/server/wm/Session.java
index 2e0c9ab..10882f9 100644
--- a/services/java/com/android/server/wm/Session.java
+++ b/services/java/com/android/server/wm/Session.java
@@ -134,28 +134,28 @@ final class Session extends IWindowSession.Stub
}
}
- public int add(IWindow window, WindowManager.LayoutParams attrs,
+ public int add(IWindow window, int seq, WindowManager.LayoutParams attrs,
int viewVisibility, Rect outContentInsets, InputChannel outInputChannel) {
- return mService.addWindow(this, window, attrs, viewVisibility, outContentInsets,
+ return mService.addWindow(this, window, seq, attrs, viewVisibility, outContentInsets,
outInputChannel);
}
- public int addWithoutInputChannel(IWindow window, WindowManager.LayoutParams attrs,
+ public int addWithoutInputChannel(IWindow window, int seq, WindowManager.LayoutParams attrs,
int viewVisibility, Rect outContentInsets) {
- return mService.addWindow(this, window, attrs, viewVisibility, outContentInsets, null);
+ return mService.addWindow(this, window, seq, attrs, viewVisibility, outContentInsets, null);
}
public void remove(IWindow window) {
mService.removeWindow(this, window);
}
- public int relayout(IWindow window, WindowManager.LayoutParams attrs,
+ public int relayout(IWindow window, int seq, WindowManager.LayoutParams attrs,
int requestedWidth, int requestedHeight, int viewFlags,
boolean insetsPending, Rect outFrame, Rect outContentInsets,
Rect outVisibleInsets, Configuration outConfig, Surface outSurface) {
if (false) Slog.d(WindowManagerService.TAG, ">>>>>> ENTERED relayout from "
+ Binder.getCallingPid());
- int res = mService.relayoutWindow(this, window, attrs,
+ int res = mService.relayoutWindow(this, window, seq, attrs,
requestedWidth, requestedHeight, viewFlags, insetsPending,
outFrame, outContentInsets, outVisibleInsets, outConfig, outSurface);
if (false) Slog.d(WindowManagerService.TAG, "<<<<<< EXITING relayout to "
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index f1994d1..540c518 100644
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -1948,7 +1948,7 @@ public class WindowManagerService extends IWindowManager.Stub
}
}
- public int addWindow(Session session, IWindow client,
+ public int addWindow(Session session, IWindow client, int seq,
WindowManager.LayoutParams attrs, int viewVisibility,
Rect outContentInsets, InputChannel outInputChannel) {
int res = mPolicy.checkAddPermission(attrs);
@@ -2040,7 +2040,7 @@ public class WindowManagerService extends IWindowManager.Stub
}
win = new WindowState(this, session, client, token,
- attachedWindow, attrs, viewVisibility);
+ attachedWindow, seq, attrs, viewVisibility);
if (win.mDeathRecipient == null) {
// Client has apparently died, so there is no reason to
// continue.
@@ -2467,7 +2467,7 @@ public class WindowManagerService extends IWindowManager.Stub
return null;
}
- public int relayoutWindow(Session session, IWindow client,
+ public int relayoutWindow(Session session, IWindow client, int seq,
WindowManager.LayoutParams attrs, int requestedWidth,
int requestedHeight, int viewVisibility, boolean insetsPending,
Rect outFrame, Rect outContentInsets, Rect outVisibleInsets,
@@ -2477,13 +2477,13 @@ public class WindowManagerService extends IWindowManager.Stub
boolean configChanged;
// if they don't have this permission, mask out the status bar bits
+ int systemUiVisibility = 0;
if (attrs != null) {
- if (((attrs.systemUiVisibility|attrs.subtreeSystemUiVisibility)
- & StatusBarManager.DISABLE_MASK) != 0) {
+ systemUiVisibility = (attrs.systemUiVisibility|attrs.subtreeSystemUiVisibility);
+ if ((systemUiVisibility & StatusBarManager.DISABLE_MASK) != 0) {
if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.STATUS_BAR)
!= PackageManager.PERMISSION_GRANTED) {
- attrs.systemUiVisibility &= ~StatusBarManager.DISABLE_MASK;
- attrs.subtreeSystemUiVisibility &= ~StatusBarManager.DISABLE_MASK;
+ systemUiVisibility &= ~StatusBarManager.DISABLE_MASK;
}
}
}
@@ -2496,6 +2496,9 @@ public class WindowManagerService extends IWindowManager.Stub
}
win.mRequestedWidth = requestedWidth;
win.mRequestedHeight = requestedHeight;
+ if (attrs != null && seq == win.mSeq) {
+ win.mSystemUiVisibility = systemUiVisibility;
+ }
if (attrs != null) {
mPolicy.adjustWindowParamsLw(attrs);
@@ -9095,13 +9098,27 @@ public class WindowManagerService extends IWindowManager.Stub
@Override
public void statusBarVisibilityChanged(int visibility) {
mInputManager.setSystemUiVisibility(visibility);
+
synchronized (mWindowMap) {
final int N = mWindows.size();
for (int i = 0; i < N; i++) {
WindowState ws = mWindows.get(i);
try {
- if (ws.getAttrs().hasSystemUiListeners) {
- ws.mClient.dispatchSystemUiVisibilityChanged(visibility);
+ int curValue = ws.mSystemUiVisibility;
+ int diff = curValue ^ visibility;
+ // We are only interested in differences of one of the
+ // clearable flags...
+ diff &= View.SYSTEM_UI_CLEARABLE_FLAGS;
+ // ...if it has actually been cleared.
+ diff &= ~visibility;
+ int newValue = (curValue&~diff) | (visibility&diff);
+ if (newValue != curValue) {
+ ws.mSeq++;
+ ws.mSystemUiVisibility = newValue;
+ }
+ if (newValue != curValue || ws.mAttrs.hasSystemUiListeners) {
+ ws.mClient.dispatchSystemUiVisibilityChanged(ws.mSeq,
+ visibility, newValue, diff);
}
} catch (RemoteException e) {
// so sorry
diff --git a/services/java/com/android/server/wm/WindowState.java b/services/java/com/android/server/wm/WindowState.java
index 3640a15..47f74fb 100644
--- a/services/java/com/android/server/wm/WindowState.java
+++ b/services/java/com/android/server/wm/WindowState.java
@@ -76,8 +76,10 @@ final class WindowState implements WindowManagerPolicy.WindowState {
final boolean mIsImWindow;
final boolean mIsWallpaper;
final boolean mIsFloatingLayer;
+ int mSeq;
boolean mEnforceSizeCompat;
int mViewVisibility;
+ int mSystemUiVisibility;
boolean mPolicyVisibility = true;
boolean mPolicyVisibilityAfterAnim = true;
boolean mAppFreezing;
@@ -282,7 +284,7 @@ final class WindowState implements WindowManagerPolicy.WindowState {
boolean mWasPaused;
WindowState(WindowManagerService service, Session s, IWindow c, WindowToken token,
- WindowState attachedWindow, WindowManager.LayoutParams a,
+ WindowState attachedWindow, int seq, WindowManager.LayoutParams a,
int viewVisibility) {
mService = service;
mSession = s;
@@ -292,6 +294,7 @@ final class WindowState implements WindowManagerPolicy.WindowState {
mViewVisibility = viewVisibility;
DeathRecipient deathRecipient = new DeathRecipient();
mAlpha = a.alpha;
+ mSeq = seq;
mEnforceSizeCompat = (mAttrs.flags & FLAG_COMPATIBLE_WINDOW) != 0;
if (WindowManagerService.localLOGV) Slog.v(
WindowManagerService.TAG, "Window " + this + " client=" + c.asBinder()
@@ -551,6 +554,10 @@ final class WindowState implements WindowManagerPolicy.WindowState {
return mAttrs;
}
+ public int getSystemUiVisibility() {
+ return mSystemUiVisibility;
+ }
+
public int getSurfaceLayer() {
return mLayer;
}
@@ -1597,6 +1604,9 @@ final class WindowState implements WindowManagerPolicy.WindowState {
pw.print(" mLastHidden="); pw.print(mLastHidden);
pw.print(" mHaveFrame="); pw.print(mHaveFrame);
pw.print(" mObscured="); pw.println(mObscured);
+ pw.print(prefix); pw.print("mSeq="); pw.print(mSeq);
+ pw.print(" mSystemUiVisibility=0x");
+ pw.println(Integer.toHexString(mSystemUiVisibility));
}
if (!mPolicyVisibility || !mPolicyVisibilityAfterAnim || mAttachedHidden) {
pw.print(prefix); pw.print("mPolicyVisibility=");