summaryrefslogtreecommitdiffstats
path: root/services/java/com
diff options
context:
space:
mode:
Diffstat (limited to 'services/java/com')
-rw-r--r--services/java/com/android/server/AlarmManagerService.java12
-rw-r--r--services/java/com/android/server/InputMethodManagerService.java17
-rw-r--r--services/java/com/android/server/NetworkManagementService.java62
-rw-r--r--services/java/com/android/server/SystemServer.java10
-rw-r--r--services/java/com/android/server/TelephonyRegistry.java6
-rw-r--r--services/java/com/android/server/TextServicesManagerService.java120
-rw-r--r--services/java/com/android/server/ThrottleService.java5
-rw-r--r--services/java/com/android/server/WallpaperManagerService.java20
-rw-r--r--services/java/com/android/server/accessibility/AccessibilityManagerService.java214
-rw-r--r--services/java/com/android/server/am/ActivityManagerService.java140
-rw-r--r--services/java/com/android/server/am/ProcessList.java2
-rw-r--r--services/java/com/android/server/net/NetworkPolicyManagerService.java14
-rw-r--r--services/java/com/android/server/net/NetworkStatsService.java194
-rw-r--r--services/java/com/android/server/pm/PackageManagerService.java3
14 files changed, 470 insertions, 349 deletions
diff --git a/services/java/com/android/server/AlarmManagerService.java b/services/java/com/android/server/AlarmManagerService.java
index 5e54d61..5ffcdc5 100644
--- a/services/java/com/android/server/AlarmManagerService.java
+++ b/services/java/com/android/server/AlarmManagerService.java
@@ -764,12 +764,18 @@ class AlarmManagerService extends IAlarmManager.Stub {
public void scheduleTimeTickEvent() {
Calendar calendar = Calendar.getInstance();
- calendar.setTimeInMillis(System.currentTimeMillis());
+ final long currentTime = System.currentTimeMillis();
+ calendar.setTimeInMillis(currentTime);
calendar.add(Calendar.MINUTE, 1);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
-
- set(AlarmManager.RTC, calendar.getTimeInMillis(), mTimeTickSender);
+
+ // Schedule this event for the amount of time that it would take to get to
+ // the top of the next minute.
+ final long tickEventDelay = calendar.getTimeInMillis() - currentTime;
+
+ set(AlarmManager.ELAPSED_REALTIME, SystemClock.elapsedRealtime() + tickEventDelay,
+ mTimeTickSender);
}
public void scheduleDateChangedEvent() {
diff --git a/services/java/com/android/server/InputMethodManagerService.java b/services/java/com/android/server/InputMethodManagerService.java
index 6b64dd0..38bcebc 100644
--- a/services/java/com/android/server/InputMethodManagerService.java
+++ b/services/java/com/android/server/InputMethodManagerService.java
@@ -619,10 +619,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
}
void updateImeWindowStatusLocked() {
- if (mStatusBar != null) {
- mStatusBar.setImeWindowStatus(mCurToken, mImeWindowVis,
- mBackDisposition);
- }
+ setImeWindowStatus(mCurToken, mImeWindowVis, mBackDisposition);
}
@Override
@@ -995,6 +992,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
sessionState.session.finishSession();
} catch (RemoteException e) {
Slog.w(TAG, "Session failed to close due to remote exception", e);
+ mImeWindowVis = 0;
+ updateImeWindowStatusLocked();
}
}
}
@@ -1121,6 +1120,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
}
}
+ @SuppressWarnings("deprecation")
@Override
public void setImeWindowStatus(IBinder token, int vis, int backDisposition) {
int uid = Binder.getCallingUid();
@@ -2018,8 +2018,9 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
if (DEBUG) Slog.v(TAG, "Show switching menu");
final Context context = mContext;
-
final PackageManager pm = context.getPackageManager();
+ final boolean isScreenLocked = mKeyguardManager != null
+ && mKeyguardManager.isKeyguardLocked() && mKeyguardManager.isKeyguardSecure();
String lastInputMethodId = Settings.Secure.getString(context
.getContentResolver(), Settings.Secure.DEFAULT_INPUT_METHOD);
@@ -2075,7 +2076,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
final String subtypeHashCode = String.valueOf(subtype.hashCode());
// We show all enabled IMEs and subtypes when an IME is shown.
if (enabledSubtypeSet.contains(subtypeHashCode)
- && (mInputShown || !subtype.isAuxiliary())) {
+ && ((mInputShown && !isScreenLocked) || !subtype.isAuxiliary())) {
final CharSequence title;
final String mode = subtype.getMode();
title = TextUtils.concat(subtype.getDisplayName(context,
@@ -2162,8 +2163,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
}
});
- if (showSubtypes && mKeyguardManager != null && !(mKeyguardManager.isKeyguardLocked()
- && mKeyguardManager.isKeyguardSecure())) {
+ if (showSubtypes && !isScreenLocked) {
mDialogBuilder.setPositiveButton(
com.android.internal.R.string.configure_input_methods,
new DialogInterface.OnClickListener() {
@@ -2591,6 +2591,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
}
// TODO: We should change the return type from List to List<Parcelable>
+ @SuppressWarnings("rawtypes")
@Override
public List getShortcutInputMethodsAndSubtypes() {
synchronized (mMethodMap) {
diff --git a/services/java/com/android/server/NetworkManagementService.java b/services/java/com/android/server/NetworkManagementService.java
index 06077dd..85d8cece 100644
--- a/services/java/com/android/server/NetworkManagementService.java
+++ b/services/java/com/android/server/NetworkManagementService.java
@@ -16,6 +16,7 @@
package com.android.server;
+import static android.Manifest.permission.DUMP;
import static android.Manifest.permission.MANAGE_NETWORK_POLICY;
import static android.net.NetworkStats.IFACE_ALL;
import static android.net.NetworkStats.SET_DEFAULT;
@@ -51,10 +52,12 @@ import com.google.android.collect.Sets;
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.File;
+import java.io.FileDescriptor;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
+import java.io.PrintWriter;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.util.ArrayList;
@@ -69,7 +72,8 @@ import libcore.io.IoUtils;
/**
* @hide
*/
-class NetworkManagementService extends INetworkManagementService.Stub implements Watchdog.Monitor {
+public class NetworkManagementService extends INetworkManagementService.Stub
+ implements Watchdog.Monitor {
private static final String TAG = "NetworkManagementService";
private static final boolean DBG = false;
private static final String NETD_TAG = "NetdConnector";
@@ -87,6 +91,12 @@ class NetworkManagementService extends INetworkManagementService.Stub implements
/** Path to {@code /proc/net/xt_qtaguid/iface_stat}. */
private final File mStatsXtIface;
+ /**
+ * Name representing {@link #setGlobalAlert(long)} limit when delivered to
+ * {@link INetworkManagementEventObserver#limitReached(String, String)}.
+ */
+ public static final String LIMIT_GLOBAL_ALERT = "globalAlert";
+
/** {@link #mStatsXtUid} headers. */
private static final String KEY_IFACE = "iface";
private static final String KEY_UID = "uid_tag_int";
@@ -281,7 +291,6 @@ class NetworkManagementService extends INetworkManagementService.Stub implements
for (INetworkManagementEventObserver obs : mObservers) {
try {
obs.limitReached(limitName, iface);
- Slog.d(TAG, "Observer notified limit reached for " + limitName + " " + iface);
} catch (Exception ex) {
Slog.w(TAG, "Observer notifier failed", ex);
}
@@ -1024,7 +1033,6 @@ class NetworkManagementService extends INetworkManagementService.Stub implements
final NetworkStats stats = new NetworkStats(SystemClock.elapsedRealtime(), 6);
final NetworkStats.Entry entry = new NetworkStats.Entry();
- final HashSet<String> activeIfaces = Sets.newHashSet();
final ArrayList<String> values = Lists.newArrayList();
BufferedReader reader = null;
@@ -1050,26 +1058,24 @@ class NetworkManagementService extends INetworkManagementService.Stub implements
entry.txBytes = Long.parseLong(values.get(9));
entry.txPackets = Long.parseLong(values.get(10));
- activeIfaces.add(entry.iface);
stats.addValues(entry);
} catch (NumberFormatException e) {
Slog.w(TAG, "problem parsing stats row '" + line + "': " + e);
}
}
+ } catch (NullPointerException e) {
+ throw new IllegalStateException("problem parsing stats: " + e);
+ } catch (NumberFormatException e) {
+ throw new IllegalStateException("problem parsing stats: " + e);
} catch (IOException e) {
- Slog.w(TAG, "problem parsing stats: " + e);
+ throw new IllegalStateException("problem parsing stats: " + e);
} finally {
IoUtils.closeQuietly(reader);
}
- if (DBG) Slog.d(TAG, "recorded active stats from " + activeIfaces);
-
- // splice in stats from any disabled ifaces
+ // splice in historical stats not reflected in mStatsIface
if (mBandwidthControlEnabled) {
- final HashSet<String> xtIfaces = Sets.newHashSet(fileListWithoutNull(mStatsXtIface));
- xtIfaces.removeAll(activeIfaces);
-
- for (String iface : xtIfaces) {
+ for (String iface : fileListWithoutNull(mStatsXtIface)) {
final File ifacePath = new File(mStatsXtIface, iface);
entry.iface = iface;
@@ -1081,10 +1087,8 @@ class NetworkManagementService extends INetworkManagementService.Stub implements
entry.txBytes = readSingleLongFromFile(new File(ifacePath, "tx_bytes"));
entry.txPackets = readSingleLongFromFile(new File(ifacePath, "tx_packets"));
- stats.addValues(entry);
+ stats.combineValues(entry);
}
-
- if (DBG) Slog.d(TAG, "recorded stale stats from " + xtIfaces);
}
return stats;
@@ -1338,8 +1342,12 @@ class NetworkManagementService extends INetworkManagementService.Stub implements
Slog.w(TAG, "problem parsing stats row '" + line + "': " + e);
}
}
+ } catch (NullPointerException e) {
+ throw new IllegalStateException("problem parsing stats: " + e);
+ } catch (NumberFormatException e) {
+ throw new IllegalStateException("problem parsing stats: " + e);
} catch (IOException e) {
- Slog.w(TAG, "problem parsing stats: " + e);
+ throw new IllegalStateException("problem parsing stats: " + e);
} finally {
IoUtils.closeQuietly(reader);
}
@@ -1568,4 +1576,26 @@ class NetworkManagementService extends INetworkManagementService.Stub implements
mConnector.monitor();
}
}
+
+ @Override
+ protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+ mContext.enforceCallingOrSelfPermission(DUMP, TAG);
+
+ pw.print("Bandwidth control enabled: "); pw.println(mBandwidthControlEnabled);
+
+ synchronized (mQuotaLock) {
+ pw.print("Active quota ifaces: "); pw.println(mActiveQuotaIfaces.toString());
+ pw.print("Active alert ifaces: "); pw.println(mActiveAlertIfaces.toString());
+ }
+
+ synchronized (mUidRejectOnQuota) {
+ pw.print("UID reject on quota ifaces: [");
+ final int size = mUidRejectOnQuota.size();
+ for (int i = 0; i < size; i++) {
+ pw.print(mUidRejectOnQuota.keyAt(i));
+ if (i < size - 1) pw.print(",");
+ }
+ pw.println("]");
+ }
+ }
}
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index e6f92a5..d0e8b5e 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -182,7 +182,7 @@ class ServerThread extends Thread {
// only initialize the power service after we have started the
// lights service, content providers and the battery service.
- power.init(context, lights, ActivityManagerService.getDefault(), battery);
+ power.init(context, lights, ActivityManagerService.self(), battery);
Slog.i(TAG, "Alarm Manager");
alarm = new AlarmManagerService(context);
@@ -197,8 +197,7 @@ class ServerThread extends Thread {
factoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL);
ServiceManager.addService(Context.WINDOW_SERVICE, wm);
- ((ActivityManagerService)ServiceManager.getService("activity"))
- .setWindowManager(wm);
+ ActivityManagerService.self().setWindowManager(wm);
// Skip Bluetooth if we have an emulator kernel
// TODO: Use a more reliable check to see if this product should
@@ -265,7 +264,7 @@ class ServerThread extends Thread {
} catch (Throwable e) {
reportWtf("making display ready", e);
}
-
+
try {
pm.performBootDexOpt();
} catch (Throwable e) {
@@ -618,8 +617,7 @@ class ServerThread extends Thread {
// where third party code can really run (but before it has actually
// started launching the initial applications), for us to complete our
// initialization.
- ((ActivityManagerService)ActivityManagerNative.getDefault())
- .systemReady(new Runnable() {
+ ActivityManagerService.self().systemReady(new Runnable() {
public void run() {
Slog.i(TAG, "Making services ready");
diff --git a/services/java/com/android/server/TelephonyRegistry.java b/services/java/com/android/server/TelephonyRegistry.java
index dd54c16..4447ad0 100644
--- a/services/java/com/android/server/TelephonyRegistry.java
+++ b/services/java/com/android/server/TelephonyRegistry.java
@@ -421,11 +421,13 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
modified = true;
}
if (modified) {
- Slog.d(TAG, "onDataConnectionStateChanged(" + state + ", " + networkType + ")");
+ Slog.d(TAG, "onDataConnectionStateChanged(" + mDataConnectionState
+ + ", " + mDataConnectionNetworkType + ")");
for (Record r : mRecords) {
if ((r.events & PhoneStateListener.LISTEN_DATA_CONNECTION_STATE) != 0) {
try {
- r.callback.onDataConnectionStateChanged(state, networkType);
+ r.callback.onDataConnectionStateChanged(mDataConnectionState,
+ mDataConnectionNetworkType);
} catch (RemoteException ex) {
mRemoveList.add(r.binder);
}
diff --git a/services/java/com/android/server/TextServicesManagerService.java b/services/java/com/android/server/TextServicesManagerService.java
index 18ddabd..f6c369e 100644
--- a/services/java/com/android/server/TextServicesManagerService.java
+++ b/services/java/com/android/server/TextServicesManagerService.java
@@ -131,6 +131,11 @@ public class TextServicesManagerService extends ITextServicesManager.Stub {
if (DBG) Slog.d(TAG, "Add: " + compName);
try {
final SpellCheckerInfo sci = new SpellCheckerInfo(context, ri);
+ if (sci.getSubtypeCount() <= 0) {
+ Slog.w(TAG, "Skipping text service " + compName
+ + ": it does not contain subtypes.");
+ continue;
+ }
list.add(sci);
map.put(sci.getId(), sci);
} catch (XmlPullParserException e) {
@@ -173,7 +178,7 @@ public class TextServicesManagerService extends ITextServicesManager.Stub {
@Override
public SpellCheckerInfo getCurrentSpellChecker(String locale) {
synchronized (mSpellCheckerMap) {
- String curSpellCheckerId =
+ final String curSpellCheckerId =
Settings.Secure.getString(mContext.getContentResolver(),
Settings.Secure.SELECTED_SPELL_CHECKER);
if (DBG) {
@@ -186,9 +191,11 @@ public class TextServicesManagerService extends ITextServicesManager.Stub {
}
}
+ // TODO: Respect allowImplicitlySelectedSubtype
// TODO: Save SpellCheckerSubtype by supported languages.
@Override
- public SpellCheckerSubtype getCurrentSpellCheckerSubtype(String locale) {
+ public SpellCheckerSubtype getCurrentSpellCheckerSubtype(
+ String locale, boolean allowImplicitlySelectedSubtype) {
synchronized (mSpellCheckerMap) {
final String subtypeHashCodeStr =
Settings.Secure.getString(mContext.getContentResolver(),
@@ -197,21 +204,46 @@ public class TextServicesManagerService extends ITextServicesManager.Stub {
Slog.w(TAG, "getCurrentSpellChecker: " + subtypeHashCodeStr);
}
final SpellCheckerInfo sci = getCurrentSpellChecker(null);
- if (sci.getSubtypeCount() == 0) {
+ if (sci == null || sci.getSubtypeCount() == 0) {
+ if (DBG) {
+ Slog.w(TAG, "Subtype not found.");
+ }
return null;
}
- if (TextUtils.isEmpty(subtypeHashCodeStr)) {
- // Return the first Subtype if there is no settings for the current subtype.
- return sci.getSubtypeAt(0);
+ final int hashCode;
+ if (!TextUtils.isEmpty(subtypeHashCodeStr)) {
+ hashCode = Integer.valueOf(subtypeHashCodeStr);
+ } else {
+ hashCode = 0;
}
- final int hashCode = Integer.valueOf(subtypeHashCodeStr);
+ if (hashCode == 0 && !allowImplicitlySelectedSubtype) {
+ return null;
+ }
+ final String systemLocale =
+ mContext.getResources().getConfiguration().locale.toString();
+ SpellCheckerSubtype candidate = null;
for (int i = 0; i < sci.getSubtypeCount(); ++i) {
final SpellCheckerSubtype scs = sci.getSubtypeAt(i);
- if (scs.hashCode() == hashCode) {
+ if (hashCode == 0) {
+ if (systemLocale.equals(locale)) {
+ return scs;
+ } else if (candidate == null) {
+ final String scsLocale = scs.getLocale();
+ if (systemLocale.length() >= 2
+ && scsLocale.length() >= 2
+ && systemLocale.substring(0, 2).equals(
+ scsLocale.substring(0, 2))) {
+ candidate = scs;
+ }
+ }
+ } else if (scs.hashCode() == hashCode) {
+ if (DBG) {
+ Slog.w(TAG, "Return subtype " + scs.hashCode());
+ }
return scs;
}
}
- return sci.getSubtypeAt(0);
+ return candidate;
}
}
@@ -283,6 +315,13 @@ public class TextServicesManagerService extends ITextServicesManager.Stub {
return;
}
+ @Override
+ public boolean isSpellCheckerEnabled() {
+ synchronized(mSpellCheckerMap) {
+ return isSpellCheckerEnabledLocked();
+ }
+ }
+
private void startSpellCheckerServiceInnerLocked(SpellCheckerInfo info, String locale,
ITextServicesSessionListener tsListener, ISpellCheckerSessionListener scListener,
int uid, Bundle bundle) {
@@ -354,7 +393,21 @@ public class TextServicesManagerService extends ITextServicesManager.Stub {
"Requires permission "
+ android.Manifest.permission.WRITE_SECURE_SETTINGS);
}
- setCurrentSpellCheckerLocked(hashCode);
+ setCurrentSpellCheckerSubtypeLocked(hashCode);
+ }
+ }
+
+ @Override
+ public void setSpellCheckerEnabled(boolean enabled) {
+ synchronized(mSpellCheckerMap) {
+ if (mContext.checkCallingOrSelfPermission(
+ android.Manifest.permission.WRITE_SECURE_SETTINGS)
+ != PackageManager.PERMISSION_GRANTED) {
+ throw new SecurityException(
+ "Requires permission "
+ + android.Manifest.permission.WRITE_SECURE_SETTINGS);
+ }
+ setSpellCheckerEnabledLocked(enabled);
}
}
@@ -363,35 +416,64 @@ public class TextServicesManagerService extends ITextServicesManager.Stub {
Slog.w(TAG, "setCurrentSpellChecker: " + sciId);
}
if (TextUtils.isEmpty(sciId) || !mSpellCheckerMap.containsKey(sciId)) return;
+ final SpellCheckerInfo currentSci = getCurrentSpellChecker(null);
+ if (currentSci != null && currentSci.getId().equals(sciId)) {
+ // Do nothing if the current spell checker is same as new spell checker.
+ return;
+ }
final long ident = Binder.clearCallingIdentity();
try {
Settings.Secure.putString(mContext.getContentResolver(),
Settings.Secure.SELECTED_SPELL_CHECKER, sciId);
+ setCurrentSpellCheckerSubtypeLocked(0);
} finally {
Binder.restoreCallingIdentity(ident);
}
}
- private void setCurrentSpellCheckerLocked(int hashCode) {
+ private void setCurrentSpellCheckerSubtypeLocked(int hashCode) {
if (DBG) {
Slog.w(TAG, "setCurrentSpellCheckerSubtype: " + hashCode);
}
final SpellCheckerInfo sci = getCurrentSpellChecker(null);
- if (sci == null) return;
- boolean found = false;
- for (int i = 0; i < sci.getSubtypeCount(); ++i) {
+ int tempHashCode = 0;
+ for (int i = 0; sci != null && i < sci.getSubtypeCount(); ++i) {
if(sci.getSubtypeAt(i).hashCode() == hashCode) {
- found = true;
+ tempHashCode = hashCode;
break;
}
}
- if (!found) {
- return;
- }
final long ident = Binder.clearCallingIdentity();
try {
Settings.Secure.putString(mContext.getContentResolver(),
- Settings.Secure.SELECTED_SPELL_CHECKER_SUBTYPE, String.valueOf(hashCode));
+ Settings.Secure.SELECTED_SPELL_CHECKER_SUBTYPE, String.valueOf(tempHashCode));
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ }
+
+ private void setSpellCheckerEnabledLocked(boolean enabled) {
+ if (DBG) {
+ Slog.w(TAG, "setSpellCheckerEnabled: " + enabled);
+ }
+ final long ident = Binder.clearCallingIdentity();
+ try {
+ Settings.Secure.putInt(mContext.getContentResolver(),
+ Settings.Secure.SPELL_CHECKER_ENABLED, enabled ? 1 : 0);
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ }
+
+ private boolean isSpellCheckerEnabledLocked() {
+ final long ident = Binder.clearCallingIdentity();
+ try {
+ final boolean retval = Settings.Secure.getInt(mContext.getContentResolver(),
+ Settings.Secure.SPELL_CHECKER_ENABLED, 1) == 1;
+ if (DBG) {
+ Slog.w(TAG, "getSpellCheckerEnabled: " + retval);
+ }
+ return retval;
} finally {
Binder.restoreCallingIdentity(ident);
}
diff --git a/services/java/com/android/server/ThrottleService.java b/services/java/com/android/server/ThrottleService.java
index 24b6ac3..2155147 100644
--- a/services/java/com/android/server/ThrottleService.java
+++ b/services/java/com/android/server/ThrottleService.java
@@ -532,9 +532,12 @@ public class ThrottleService extends IThrottleManager.Stub {
mLastRead = 0;
mLastWrite = 0;
}
+ } catch (IllegalStateException e) {
+ Slog.e(TAG, "problem during onPollAlarm: " + e);
} catch (RemoteException e) {
- Slog.e(TAG, "got remoteException in onPollAlarm:" + e);
+ Slog.e(TAG, "problem during onPollAlarm: " + e);
}
+
// don't count this data if we're roaming.
boolean roaming = "true".equals(
SystemProperties.get(TelephonyProperties.PROPERTY_OPERATOR_ISROAMING));
diff --git a/services/java/com/android/server/WallpaperManagerService.java b/services/java/com/android/server/WallpaperManagerService.java
index 565063a..6ceccaf 100644
--- a/services/java/com/android/server/WallpaperManagerService.java
+++ b/services/java/com/android/server/WallpaperManagerService.java
@@ -118,9 +118,10 @@ class WallpaperManagerService extends IWallpaperManager.Stub {
File changedFile = new File(WALLPAPER_DIR, path);
if (WALLPAPER_FILE.equals(changedFile)) {
notifyCallbacksLocked();
- if (mWallpaperComponent == null ||
- mWallpaperComponent.equals(mImageWallpaperComponent)) {
- bindWallpaperComponentLocked(mWallpaperComponent, true);
+ if (mWallpaperComponent == null || mImageWallpaperPending) {
+ mImageWallpaperPending = false;
+ bindWallpaperComponentLocked(mImageWallpaperComponent, true);
+ saveSettingsLocked();
}
}
}
@@ -133,7 +134,12 @@ class WallpaperManagerService extends IWallpaperManager.Stub {
int mWidth = -1;
int mHeight = -1;
-
+
+ /**
+ * Client is currently writing a new image wallpaper.
+ */
+ boolean mImageWallpaperPending;
+
/**
* Resource name if using a picture from the wallpaper gallery
*/
@@ -343,6 +349,7 @@ class WallpaperManagerService extends IWallpaperManager.Stub {
}
final long ident = Binder.clearCallingIdentity();
try {
+ mImageWallpaperPending = false;
bindWallpaperComponentLocked(null, false);
} catch (IllegalArgumentException e) {
// This can happen if the default wallpaper component doesn't
@@ -433,9 +440,7 @@ class WallpaperManagerService extends IWallpaperManager.Stub {
try {
ParcelFileDescriptor pfd = updateWallpaperBitmapLocked(name);
if (pfd != null) {
- // Bind the wallpaper to an ImageWallpaper
- bindWallpaperComponentLocked(mImageWallpaperComponent, false);
- saveSettingsLocked();
+ mImageWallpaperPending = true;
}
return pfd;
} finally {
@@ -463,6 +468,7 @@ class WallpaperManagerService extends IWallpaperManager.Stub {
synchronized (mLock) {
final long ident = Binder.clearCallingIdentity();
try {
+ mImageWallpaperPending = false;
bindWallpaperComponentLocked(name, false);
} finally {
Binder.restoreCallingIdentity(ident);
diff --git a/services/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/java/com/android/server/accessibility/AccessibilityManagerService.java
index af01c5b..09ddc2f 100644
--- a/services/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -40,7 +40,6 @@ import android.os.IBinder;
import android.os.Message;
import android.os.RemoteException;
import android.os.ServiceManager;
-import android.os.SystemClock;
import android.provider.Settings;
import android.text.TextUtils;
import android.text.TextUtils.SimpleStringSplitter;
@@ -72,7 +71,6 @@ import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
-import java.util.concurrent.atomic.AtomicInteger;
/**
* This class is instantiated by the system as a system level service and can be
@@ -871,10 +869,6 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
boolean mIsAutomation;
- final Callback mCallback = new Callback();
-
- final AtomicInteger mInteractionIdCounter = new AtomicInteger();
-
final Rect mTempBounds = new Rect();
// the events pending events to be dispatched to this service
@@ -974,14 +968,16 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
}
}
- public AccessibilityNodeInfo findAccessibilityNodeInfoByViewIdInActiveWindow(int viewId)
+ public float findAccessibilityNodeInfoByViewIdInActiveWindow(int viewId,
+ int interactionId, IAccessibilityInteractionConnectionCallback callback,
+ long interrogatingTid)
throws RemoteException {
IAccessibilityInteractionConnection connection = null;
synchronized (mLock) {
mSecurityPolicy.enforceCanRetrieveWindowContent(this);
final boolean permissionGranted = mSecurityPolicy.canRetrieveWindowContent(this);
if (!permissionGranted) {
- return null;
+ return 0;
} else {
connection = getConnectionToRetrievalAllowingWindowLocked();
if (connection == null) {
@@ -989,22 +985,15 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
Slog.e(LOG_TAG, "No interaction connection to a retrieve "
+ "allowing window.");
}
- return null;
+ return 0;
}
}
}
+ final int interrogatingPid = Binder.getCallingPid();
final long identityToken = Binder.clearCallingIdentity();
try {
- final int interactionId = mInteractionIdCounter.getAndIncrement();
- connection.findAccessibilityNodeInfoByViewId(viewId, interactionId, mCallback);
- AccessibilityNodeInfo info = mCallback.getFindAccessibilityNodeInfoResultAndClear(
- interactionId);
- if (info != null) {
- applyCompatibilityScaleIfNeeded(info);
- info.setConnection(this);
- info.setSealed(true);
- }
- return info;
+ connection.findAccessibilityNodeInfoByViewId(viewId, interactionId, callback,
+ interrogatingPid, interrogatingTid);
} catch (RemoteException re) {
if (DEBUG) {
Slog.e(LOG_TAG, "Error finding node.");
@@ -1012,51 +1001,44 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
} finally {
Binder.restoreCallingIdentity(identityToken);
}
- return null;
+ return getCompatibilityScale(mSecurityPolicy.getRetrievalAllowingWindowLocked());
}
- public List<AccessibilityNodeInfo> findAccessibilityNodeInfosByViewTextInActiveWindow(
- String text) throws RemoteException {
+ public float findAccessibilityNodeInfosByViewTextInActiveWindow(
+ String text, int interactionId,
+ IAccessibilityInteractionConnectionCallback callback, long threadId)
+ throws RemoteException {
return findAccessibilityNodeInfosByViewText(text,
- mSecurityPolicy.mRetrievalAlowingWindowId, View.NO_ID);
+ mSecurityPolicy.mRetrievalAlowingWindowId, View.NO_ID, interactionId, callback,
+ threadId);
}
- public List<AccessibilityNodeInfo> findAccessibilityNodeInfosByViewText(String text,
- int accessibilityWindowId, int accessibilityViewId) throws RemoteException {
+ public float findAccessibilityNodeInfosByViewText(String text,
+ int accessibilityWindowId, int accessibilityViewId, int interactionId,
+ IAccessibilityInteractionConnectionCallback callback, long interrogatingTid)
+ throws RemoteException {
IAccessibilityInteractionConnection connection = null;
synchronized (mLock) {
mSecurityPolicy.enforceCanRetrieveWindowContent(this);
final boolean permissionGranted =
mSecurityPolicy.canGetAccessibilityNodeInfoLocked(this, accessibilityWindowId);
if (!permissionGranted) {
- return null;
+ return 0;
} else {
connection = getConnectionToRetrievalAllowingWindowLocked();
if (connection == null) {
if (DEBUG) {
Slog.e(LOG_TAG, "No interaction connection to focused window.");
}
- return null;
+ return 0;
}
}
}
+ final int interrogatingPid = Binder.getCallingPid();
final long identityToken = Binder.clearCallingIdentity();
try {
- final int interactionId = mInteractionIdCounter.getAndIncrement();
connection.findAccessibilityNodeInfosByViewText(text, accessibilityViewId,
- interactionId, mCallback);
- List<AccessibilityNodeInfo> infos =
- mCallback.getFindAccessibilityNodeInfosResultAndClear(interactionId);
- if (infos != null) {
- final int infoCount = infos.size();
- for (int i = 0; i < infoCount; i++) {
- AccessibilityNodeInfo info = infos.get(i);
- applyCompatibilityScaleIfNeeded(info);
- info.setConnection(this);
- info.setSealed(true);
- }
- }
- return infos;
+ interactionId, callback, interrogatingPid, interrogatingTid);
} catch (RemoteException re) {
if (DEBUG) {
Slog.e(LOG_TAG, "Error finding node.");
@@ -1064,18 +1046,20 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
} finally {
Binder.restoreCallingIdentity(identityToken);
}
- return null;
+ return getCompatibilityScale(accessibilityWindowId);
}
- public AccessibilityNodeInfo findAccessibilityNodeInfoByAccessibilityId(
- int accessibilityWindowId, int accessibilityViewId) throws RemoteException {
+ public float findAccessibilityNodeInfoByAccessibilityId(int accessibilityWindowId,
+ int accessibilityViewId, int interactionId,
+ IAccessibilityInteractionConnectionCallback callback, long interrogatingTid)
+ throws RemoteException {
IAccessibilityInteractionConnection connection = null;
synchronized (mLock) {
mSecurityPolicy.enforceCanRetrieveWindowContent(this);
final boolean permissionGranted =
mSecurityPolicy.canGetAccessibilityNodeInfoLocked(this, accessibilityWindowId);
if (!permissionGranted) {
- return null;
+ return 0;
} else {
connection = mWindowIdToInteractionConnectionMap.get(accessibilityWindowId);
if (connection == null) {
@@ -1083,23 +1067,15 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
Slog.e(LOG_TAG, "No interaction connection to window: "
+ accessibilityWindowId);
}
- return null;
+ return 0;
}
}
}
+ final int interrogatingPid = Binder.getCallingPid();
final long identityToken = Binder.clearCallingIdentity();
try {
- final int interactionId = mInteractionIdCounter.getAndIncrement();
connection.findAccessibilityNodeInfoByAccessibilityId(accessibilityViewId,
- interactionId, mCallback);
- AccessibilityNodeInfo info =
- mCallback.getFindAccessibilityNodeInfoResultAndClear(interactionId);
- if (info != null) {
- applyCompatibilityScaleIfNeeded(info);
- info.setConnection(this);
- info.setSealed(true);
- }
- return info;
+ interactionId, callback, interrogatingPid, interrogatingTid);
} catch (RemoteException re) {
if (DEBUG) {
Slog.e(LOG_TAG, "Error requesting node with accessibilityViewId: "
@@ -1108,11 +1084,12 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
} finally {
Binder.restoreCallingIdentity(identityToken);
}
- return null;
+ return getCompatibilityScale(accessibilityWindowId);
}
public boolean performAccessibilityAction(int accessibilityWindowId,
- int accessibilityViewId, int action) {
+ int accessibilityViewId, int action, int interactionId,
+ IAccessibilityInteractionConnectionCallback callback, long interrogatingTid) {
IAccessibilityInteractionConnection connection = null;
synchronized (mLock) {
final boolean permissionGranted = mSecurityPolicy.canPerformActionLocked(this,
@@ -1130,12 +1107,11 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
}
}
}
+ final int interrogatingPid = Binder.getCallingPid();
final long identityToken = Binder.clearCallingIdentity();
try {
- final int interactionId = mInteractionIdCounter.getAndIncrement();
connection.performAccessibilityAction(accessibilityViewId, action, interactionId,
- mCallback);
- return mCallback.getPerformAccessibilityActionResult(interactionId);
+ callback, interrogatingPid, interrogatingTid);
} catch (RemoteException re) {
if (DEBUG) {
Slog.e(LOG_TAG, "Error requesting node with accessibilityViewId: "
@@ -1144,7 +1120,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
} finally {
Binder.restoreCallingIdentity(identityToken);
}
- return false;
+ return true;
}
public void onServiceDisconnected(ComponentName componentName) {
@@ -1173,22 +1149,9 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
return mWindowIdToInteractionConnectionMap.get(windowId);
}
- private void applyCompatibilityScaleIfNeeded(AccessibilityNodeInfo info) {
- IBinder windowToken = mWindowIdToWindowTokenMap.get(info.getWindowId());
- final float scale = mWindowManagerService.getWindowCompatibilityScale(windowToken);
-
- if (scale == 1.0f) {
- return;
- }
-
- Rect bounds = mTempBounds;
- info.getBoundsInParent(bounds);
- bounds.scale(scale);
- info.setBoundsInParent(bounds);
-
- info.getBoundsInScreen(bounds);
- bounds.scale(scale);
- info.setBoundsInScreen(bounds);
+ private float getCompatibilityScale(int windowId) {
+ IBinder windowToken = mWindowIdToWindowTokenMap.get(windowId);
+ return mWindowManagerService.getWindowCompatibilityScale(windowToken);
}
}
@@ -1275,99 +1238,4 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
}
}
}
-
- final class Callback extends IAccessibilityInteractionConnectionCallback.Stub {
- private static final long TIMEOUT_INTERACTION_MILLIS = 5000;
-
- private int mInteractionId = -1;
- private AccessibilityNodeInfo mFindAccessibilityNodeInfoResult;
- private List<AccessibilityNodeInfo> mFindAccessibilityNodeInfosResult;
- private boolean mPerformAccessibilityActionResult;
-
- public void setFindAccessibilityNodeInfoResult(AccessibilityNodeInfo info,
- int interactionId) {
- synchronized (mLock) {
- if (interactionId > mInteractionId) {
- mFindAccessibilityNodeInfoResult = info;
- mInteractionId = interactionId;
- }
- mLock.notifyAll();
- }
- }
-
- public AccessibilityNodeInfo getFindAccessibilityNodeInfoResultAndClear(int interactionId) {
- synchronized (mLock) {
- waitForResultTimedLocked(TIMEOUT_INTERACTION_MILLIS, interactionId);
- AccessibilityNodeInfo result = mFindAccessibilityNodeInfoResult;
- clearLocked();
- return result;
- }
- }
-
- public void setFindAccessibilityNodeInfosResult(List<AccessibilityNodeInfo> infos,
- int interactionId) {
- synchronized (mLock) {
- if (interactionId > mInteractionId) {
- mFindAccessibilityNodeInfosResult = infos;
- mInteractionId = interactionId;
- }
- mLock.notifyAll();
- }
- }
-
- public List<AccessibilityNodeInfo> getFindAccessibilityNodeInfosResultAndClear(
- int interactionId) {
- synchronized (mLock) {
- waitForResultTimedLocked(TIMEOUT_INTERACTION_MILLIS, interactionId);
- List<AccessibilityNodeInfo> result = mFindAccessibilityNodeInfosResult;
- clearLocked();
- return result;
- }
- }
-
- public void setPerformAccessibilityActionResult(boolean succeeded, int interactionId) {
- synchronized (mLock) {
- if (interactionId > mInteractionId) {
- mPerformAccessibilityActionResult = succeeded;
- mInteractionId = interactionId;
- }
- mLock.notifyAll();
- }
- }
-
- public boolean getPerformAccessibilityActionResult(int interactionId) {
- synchronized (mLock) {
- waitForResultTimedLocked(TIMEOUT_INTERACTION_MILLIS, interactionId);
- final boolean result = mPerformAccessibilityActionResult;
- clearLocked();
- return result;
- }
- }
-
- public void clearLocked() {
- mInteractionId = -1;
- mFindAccessibilityNodeInfoResult = null;
- mFindAccessibilityNodeInfosResult = null;
- mPerformAccessibilityActionResult = false;
- }
-
- private void waitForResultTimedLocked(long waitTimeMillis, int interactionId) {
- final long startTimeMillis = SystemClock.uptimeMillis();
- while (true) {
- try {
- if (mInteractionId == interactionId) {
- return;
- }
- final long elapsedTimeMillis = SystemClock.uptimeMillis() - startTimeMillis;
- waitTimeMillis = TIMEOUT_INTERACTION_MILLIS - elapsedTimeMillis;
- if (waitTimeMillis <= 0) {
- return;
- }
- mLock.wait(waitTimeMillis);
- } catch (InterruptedException ie) {
- /* ignore */
- }
- }
- }
- }
}
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 7232a94..bb5e989 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -91,7 +91,6 @@ import android.os.Environment;
import android.os.FileObserver;
import android.os.FileUtils;
import android.os.Handler;
-import android.os.HandlerThread;
import android.os.IBinder;
import android.os.IPermissionController;
import android.os.Looper;
@@ -5518,6 +5517,48 @@ public final class ActivityManagerService extends ActivityManagerNative
return msg;
}
+ boolean incProviderCount(ProcessRecord r, ContentProviderRecord cpr) {
+ if (r != null) {
+ Integer cnt = r.conProviders.get(cpr);
+ if (DEBUG_PROVIDER) Slog.v(TAG,
+ "Adding provider requested by "
+ + r.processName + " from process "
+ + cpr.info.processName + ": " + cpr.name.flattenToShortString()
+ + " cnt=" + (cnt == null ? 1 : cnt));
+ if (cnt == null) {
+ cpr.clients.add(r);
+ r.conProviders.put(cpr, new Integer(1));
+ return true;
+ } else {
+ r.conProviders.put(cpr, new Integer(cnt.intValue()+1));
+ }
+ } else {
+ cpr.externals++;
+ }
+ return false;
+ }
+
+ boolean decProviderCount(ProcessRecord r, ContentProviderRecord cpr) {
+ if (r != null) {
+ Integer cnt = r.conProviders.get(cpr);
+ if (DEBUG_PROVIDER) Slog.v(TAG,
+ "Removing provider requested by "
+ + r.processName + " from process "
+ + cpr.info.processName + ": " + cpr.name.flattenToShortString()
+ + " cnt=" + cnt);
+ if (cnt == null || cnt.intValue() <= 1) {
+ cpr.clients.remove(r);
+ r.conProviders.remove(cpr);
+ return true;
+ } else {
+ r.conProviders.put(cpr, new Integer(cnt.intValue()-1));
+ }
+ } else {
+ cpr.externals++;
+ }
+ return false;
+ }
+
private final ContentProviderHolder getContentProviderImpl(
IApplicationThread caller, String name) {
ContentProviderRecord cpr;
@@ -5537,7 +5578,8 @@ public final class ActivityManagerService extends ActivityManagerNative
// First check if this content provider has been published...
cpr = mProvidersByName.get(name);
- if (cpr != null) {
+ boolean providerRunning = cpr != null;
+ if (providerRunning) {
cpi = cpr.info;
String msg;
if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
@@ -5561,18 +5603,8 @@ public final class ActivityManagerService extends ActivityManagerNative
// In this case the provider instance already exists, so we can
// return it right away.
- if (r != null) {
- if (DEBUG_PROVIDER) Slog.v(TAG,
- "Adding provider requested by "
- + r.processName + " from process "
- + cpr.info.processName);
- Integer cnt = r.conProviders.get(cpr);
- if (cnt == null) {
- r.conProviders.put(cpr, new Integer(1));
- } else {
- r.conProviders.put(cpr, new Integer(cnt.intValue()+1));
- }
- cpr.clients.add(r);
+ final boolean countChanged = incProviderCount(r, cpr);
+ if (countChanged) {
if (cpr.app != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
// If this is a perceptible app accessing the provider,
// make sure to count it as being accessed and thus
@@ -5580,17 +5612,46 @@ public final class ActivityManagerService extends ActivityManagerNative
// content providers are often expensive to start.
updateLruProcessLocked(cpr.app, false, true);
}
- } else {
- cpr.externals++;
}
if (cpr.app != null) {
- updateOomAdjLocked(cpr.app);
+ if (false) {
+ if (cpr.name.flattenToShortString().equals(
+ "com.android.providers.calendar/.CalendarProvider2")) {
+ Slog.v(TAG, "****************** KILLING "
+ + cpr.name.flattenToShortString());
+ Process.killProcess(cpr.app.pid);
+ }
+ }
+ boolean success = updateOomAdjLocked(cpr.app);
+ if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
+ // NOTE: there is still a race here where a signal could be
+ // pending on the process even though we managed to update its
+ // adj level. Not sure what to do about this, but at least
+ // the race is now smaller.
+ if (!success) {
+ // Uh oh... it looks like the provider's process
+ // has been killed on us. We need to wait for a new
+ // process to be started, and make sure its death
+ // doesn't kill our process.
+ Slog.i(TAG,
+ "Existing provider " + cpr.name.flattenToShortString()
+ + " is crashing; detaching " + r);
+ boolean lastRef = decProviderCount(r, cpr);
+ appDiedLocked(cpr.app, cpr.app.pid, cpr.app.thread);
+ if (!lastRef) {
+ // This wasn't the last ref our process had on
+ // the provider... we have now been killed, bail.
+ return null;
+ }
+ providerRunning = false;
+ }
}
Binder.restoreCallingIdentity(origId);
+ }
- } else {
+ if (!providerRunning) {
try {
cpi = AppGlobals.getPackageManager().
resolveContentProvider(name,
@@ -5701,22 +5762,7 @@ public final class ActivityManagerService extends ActivityManagerNative
mProvidersByClass.put(comp, cpr);
}
mProvidersByName.put(name, cpr);
-
- if (r != null) {
- if (DEBUG_PROVIDER) Slog.v(TAG,
- "Adding provider requested by "
- + r.processName + " from process "
- + cpr.info.processName);
- Integer cnt = r.conProviders.get(cpr);
- if (cnt == null) {
- r.conProviders.put(cpr, new Integer(1));
- } else {
- r.conProviders.put(cpr, new Integer(cnt.intValue()+1));
- }
- cpr.clients.add(r);
- } else {
- cpr.externals++;
- }
+ incProviderCount(r, cpr);
}
}
@@ -5780,24 +5826,16 @@ public final class ActivityManagerService extends ActivityManagerNative
//update content provider record entry info
ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
ContentProviderRecord localCpr = mProvidersByClass.get(comp);
- if (DEBUG_PROVIDER) Slog.v(TAG, "Removing provider requested by "
- + r.info.processName + " from process "
- + localCpr.appInfo.processName);
if (localCpr.app == r) {
//should not happen. taken care of as a local provider
Slog.w(TAG, "removeContentProvider called on local provider: "
+ cpr.info.name + " in process " + r.processName);
return;
} else {
- Integer cnt = r.conProviders.get(localCpr);
- if (cnt == null || cnt.intValue() <= 1) {
- localCpr.clients.remove(r);
- r.conProviders.remove(localCpr);
- } else {
- r.conProviders.put(localCpr, new Integer(cnt.intValue()-1));
+ if (decProviderCount(r, localCpr)) {
+ updateOomAdjLocked();
}
}
- updateOomAdjLocked();
}
}
@@ -13458,16 +13496,18 @@ public final class ActivityManagerService extends ActivityManagerNative
}
}
- private final void updateOomAdjLocked(
+ private final boolean updateOomAdjLocked(
ProcessRecord app, int hiddenAdj, ProcessRecord TOP_APP) {
app.hiddenAdj = hiddenAdj;
if (app.thread == null) {
- return;
+ return false;
}
final boolean wasKeeping = app.keeping;
+ boolean success = true;
+
computeOomAdjLocked(app, hiddenAdj, TOP_APP, false);
if (app.curRawAdj != app.setRawAdj) {
@@ -13504,6 +13544,7 @@ public final class ActivityManagerService extends ActivityManagerNative
" oom adj to " + app.curAdj + " because " + app.adjType);
app.setAdj = app.curAdj;
} else {
+ success = false;
Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj);
}
}
@@ -13518,6 +13559,7 @@ public final class ActivityManagerService extends ActivityManagerNative
EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
app.processName, app.setAdj, app.waitingToKill);
Process.killProcessQuiet(app.pid);
+ success = false;
} else {
if (true) {
long oldId = Binder.clearCallingIdentity();
@@ -13540,6 +13582,7 @@ public final class ActivityManagerService extends ActivityManagerNative
}
}
}
+ return success;
}
private final ActivityRecord resumedAppLocked() {
@@ -13553,7 +13596,7 @@ public final class ActivityManagerService extends ActivityManagerNative
return resumedActivity;
}
- private final void updateOomAdjLocked(ProcessRecord app) {
+ private final boolean updateOomAdjLocked(ProcessRecord app) {
final ActivityRecord TOP_ACT = resumedAppLocked();
final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
int curAdj = app.curAdj;
@@ -13562,7 +13605,7 @@ public final class ActivityManagerService extends ActivityManagerNative
mAdjSeq++;
- updateOomAdjLocked(app, app.hiddenAdj, TOP_APP);
+ boolean success = updateOomAdjLocked(app, app.hiddenAdj, TOP_APP);
final boolean nowHidden = app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
&& app.curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
if (nowHidden != wasHidden) {
@@ -13570,6 +13613,7 @@ public final class ActivityManagerService extends ActivityManagerNative
// list may also be changed.
updateOomAdjLocked();
}
+ return success;
}
final void updateOomAdjLocked() {
diff --git a/services/java/com/android/server/am/ProcessList.java b/services/java/com/android/server/am/ProcessList.java
index dfcc0bf..131255f 100644
--- a/services/java/com/android/server/am/ProcessList.java
+++ b/services/java/com/android/server/am/ProcessList.java
@@ -163,7 +163,7 @@ class ProcessList {
int minSize = 320*480; // 153600
int maxSize = 1280*800; // 1024000 230400 870400 .264
float scaleDisp = ((float)(displayWidth*displayHeight)-minSize)/(maxSize-minSize);
- Slog.i("XXXXXX", "scaleDisp=" + scaleDisp + " dw=" + displayWidth + " dh=" + displayHeight);
+ //Slog.i("XXXXXX", "scaleDisp=" + scaleDisp + " dw=" + displayWidth + " dh=" + displayHeight);
StringBuilder adjString = new StringBuilder();
StringBuilder memString = new StringBuilder();
diff --git a/services/java/com/android/server/net/NetworkPolicyManagerService.java b/services/java/com/android/server/net/NetworkPolicyManagerService.java
index 84880f9..77f53c2 100644
--- a/services/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -60,6 +60,7 @@ import static com.android.server.net.NetworkPolicyManagerService.XmlUtils.writeL
import static com.android.server.net.NetworkStatsService.ACTION_NETWORK_STATS_UPDATED;
import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
import static org.xmlpull.v1.XmlPullParser.START_TAG;
+import static com.android.server.NetworkManagementService.LIMIT_GLOBAL_ALERT;
import android.app.IActivityManager;
import android.app.INotificationManager;
@@ -132,6 +133,7 @@ import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
+import java.util.Map;
import libcore.io.IoUtils;
@@ -454,7 +456,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
synchronized (mRulesLock) {
- if (mMeteredIfaces.contains(iface)) {
+ if (mMeteredIfaces.contains(iface) && !LIMIT_GLOBAL_ALERT.equals(limitName)) {
try {
// force stats update to make sure we have numbers that
// caused alert to trigger.
@@ -763,7 +765,9 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
// disable data connection when over limit and not snoozed
final boolean overLimit = policy.limitBytes != LIMIT_DISABLED
&& totalBytes > policy.limitBytes && policy.lastSnooze < start;
- setNetworkTemplateEnabled(policy.template, !overLimit);
+ final boolean enabled = !overLimit;
+
+ setNetworkTemplateEnabled(policy.template, enabled);
}
}
@@ -772,7 +776,6 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
* for the given {@link NetworkTemplate}.
*/
private void setNetworkTemplateEnabled(NetworkTemplate template, boolean enabled) {
- if (LOGD) Slog.d(TAG, "setting template=" + template + " enabled=" + enabled);
switch (template.getMatchRule()) {
case MATCH_MOBILE_3G_LOWER:
case MATCH_MOBILE_4G:
@@ -830,9 +833,10 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
// collect all active ifaces that match this template
ifaceList.clear();
- for (NetworkIdentity ident : networks.keySet()) {
+ for (Map.Entry<NetworkIdentity, String> entry : networks.entrySet()) {
+ final NetworkIdentity ident = entry.getKey();
if (policy.template.matches(ident)) {
- final String iface = networks.get(ident);
+ final String iface = entry.getValue();
ifaceList.add(iface);
}
}
diff --git a/services/java/com/android/server/net/NetworkStatsService.java b/services/java/com/android/server/net/NetworkStatsService.java
index c911687..bb0a0d1 100644
--- a/services/java/com/android/server/net/NetworkStatsService.java
+++ b/services/java/com/android/server/net/NetworkStatsService.java
@@ -43,6 +43,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 com.android.internal.util.Preconditions.checkNotNull;
+import static com.android.server.NetworkManagementService.LIMIT_GLOBAL_ALERT;
import static com.android.server.NetworkManagementSocketTagger.resetKernelUidStats;
import static com.android.server.NetworkManagementSocketTagger.setKernelCounterSet;
@@ -56,6 +57,7 @@ import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.ApplicationInfo;
import android.net.IConnectivityManager;
+import android.net.INetworkManagementEventObserver;
import android.net.INetworkStatsService;
import android.net.NetworkIdentity;
import android.net.NetworkInfo;
@@ -121,7 +123,8 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
private static final int VERSION_UID_WITH_TAG = 3;
private static final int VERSION_UID_WITH_SET = 4;
- private static final int MSG_FORCE_UPDATE = 0x1;
+ private static final int MSG_PERFORM_POLL = 0x1;
+ private static final int MSG_PERFORM_POLL_DETAILED = 0x2;
private final Context mContext;
private final INetworkManagementService mNetworkManager;
@@ -141,7 +144,6 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
private PendingIntent mPollIntent;
- // TODO: listen for kernel push events through netd instead of polling
// TODO: trim empty history objects entirely
private static final long KB_IN_BYTES = 1024;
@@ -174,17 +176,18 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
/** Flag if {@link #mUidStats} have been loaded from disk. */
private boolean mUidStatsLoaded = false;
- private NetworkStats mLastNetworkSnapshot;
- private NetworkStats mLastPersistNetworkSnapshot;
+ private NetworkStats mLastPollNetworkSnapshot;
+ private NetworkStats mLastPollUidSnapshot;
+ private NetworkStats mLastPollOperationsSnapshot;
- private NetworkStats mLastUidSnapshot;
+ private NetworkStats mLastPersistNetworkSnapshot;
+ private NetworkStats mLastPersistUidSnapshot;
/** Current counter sets for each UID. */
private SparseIntArray mActiveUidCounterSet = new SparseIntArray();
/** Data layer operation counters for splicing into other structures. */
private NetworkStats mOperations = new NetworkStats(0L, 10);
- private NetworkStats mLastOperationsSnapshot;
private final HandlerThread mHandlerThread;
private final Handler mHandler;
@@ -252,13 +255,18 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
mContext.registerReceiver(mShutdownReceiver, shutdownFilter);
try {
- registerPollAlarmLocked();
+ mNetworkManager.registerObserver(mAlertObserver);
} catch (RemoteException e) {
- Slog.w(TAG, "unable to register poll alarm");
+ // ouch, no push updates means we fall back to
+ // ACTION_NETWORK_STATS_POLL intervals.
+ Slog.e(TAG, "unable to register INetworkManagementEventObserver", e);
}
- // kick off background poll to bootstrap deltas
- mHandler.obtainMessage(MSG_FORCE_UPDATE).sendToTarget();
+ registerPollAlarmLocked();
+ registerGlobalAlert();
+
+ // bootstrap initial stats to prevent double-counting later
+ bootstrapStats();
}
private void shutdownLocked() {
@@ -280,17 +288,37 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
* Clear any existing {@link #ACTION_NETWORK_STATS_POLL} alarms, and
* reschedule based on current {@link NetworkStatsSettings#getPollInterval()}.
*/
- private void registerPollAlarmLocked() throws RemoteException {
- if (mPollIntent != null) {
- mAlarmManager.remove(mPollIntent);
- }
+ private void registerPollAlarmLocked() {
+ try {
+ if (mPollIntent != null) {
+ mAlarmManager.remove(mPollIntent);
+ }
- mPollIntent = PendingIntent.getBroadcast(
- mContext, 0, new Intent(ACTION_NETWORK_STATS_POLL), 0);
+ mPollIntent = PendingIntent.getBroadcast(
+ mContext, 0, new Intent(ACTION_NETWORK_STATS_POLL), 0);
- final long currentRealtime = SystemClock.elapsedRealtime();
- mAlarmManager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME, currentRealtime,
- mSettings.getPollInterval(), mPollIntent);
+ final long currentRealtime = SystemClock.elapsedRealtime();
+ mAlarmManager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME, currentRealtime,
+ mSettings.getPollInterval(), mPollIntent);
+ } catch (RemoteException e) {
+ Slog.w(TAG, "problem registering for poll alarm: " + e);
+ }
+ }
+
+ /**
+ * Register for a global alert that is delivered through
+ * {@link INetworkManagementEventObserver} once a threshold amount of data
+ * has been transferred.
+ */
+ private void registerGlobalAlert() {
+ try {
+ final long alertBytes = mSettings.getPersistThreshold();
+ mNetworkManager.setGlobalAlert(alertBytes);
+ } catch (IllegalStateException e) {
+ Slog.w(TAG, "problem registering for global alert: " + e);
+ } catch (RemoteException e) {
+ Slog.w(TAG, "problem registering for global alert: " + e);
+ }
}
@Override
@@ -475,10 +503,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
@Override
public void forceUpdate() {
mContext.enforceCallingOrSelfPermission(READ_NETWORK_USAGE_HISTORY, TAG);
-
- synchronized (mStatsLock) {
- performPollLocked(true, false);
- }
+ performPoll(true, false);
}
/**
@@ -507,14 +532,10 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
public void onReceive(Context context, Intent intent) {
// on background handler thread, and verified UPDATE_DEVICE_STATS
// permission above.
- synchronized (mStatsLock) {
- mWakeLock.acquire();
- try {
- performPollLocked(true, false);
- } finally {
- mWakeLock.release();
- }
- }
+ performPoll(true, false);
+
+ // verify that we're watching global alert
+ registerGlobalAlert();
}
};
@@ -547,6 +568,26 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
};
/**
+ * Observer that watches for {@link INetworkManagementService} alerts.
+ */
+ private INetworkManagementEventObserver mAlertObserver = new NetworkAlertObserver() {
+ @Override
+ public void limitReached(String limitName, String iface) {
+ // only someone like NMS should be calling us
+ mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
+
+ if (LIMIT_GLOBAL_ALERT.equals(limitName)) {
+ // kick off background poll to collect network stats; UID stats
+ // are handled during normal polling interval.
+ mHandler.obtainMessage(MSG_PERFORM_POLL).sendToTarget();
+
+ // re-arm global alert for next update
+ registerGlobalAlert();
+ }
+ }
+ };
+
+ /**
* Inspect all current {@link NetworkState} to derive mapping from {@code
* iface} to {@link NetworkStatsHistory}. When multiple {@link NetworkInfo}
* are active on a single {@code iface}, they are combined under a single
@@ -588,6 +629,33 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
}
/**
+ * Bootstrap initial stats snapshot, usually during {@link #systemReady()}
+ * so we have baseline values without double-counting.
+ */
+ private void bootstrapStats() {
+ try {
+ mLastPollNetworkSnapshot = mNetworkManager.getNetworkStatsSummary();
+ mLastPollUidSnapshot = mNetworkManager.getNetworkStatsUidDetail(UID_ALL);
+ mLastPollOperationsSnapshot = new NetworkStats(0L, 0);
+ } catch (IllegalStateException e) {
+ Slog.w(TAG, "problem reading network stats: " + e);
+ } catch (RemoteException e) {
+ Slog.w(TAG, "problem reading network stats: " + e);
+ }
+ }
+
+ private void performPoll(boolean detailedPoll, boolean forcePersist) {
+ synchronized (mStatsLock) {
+ mWakeLock.acquire();
+ try {
+ performPollLocked(detailedPoll, forcePersist);
+ } finally {
+ mWakeLock.release();
+ }
+ }
+ }
+
+ /**
* Periodic poll operation, reading current statistics and recording into
* {@link NetworkStatsHistory}.
*
@@ -596,6 +664,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
*/
private void performPollLocked(boolean detailedPoll, boolean forcePersist) {
if (LOGV) Slog.v(TAG, "performPollLocked()");
+ final long startRealtime = SystemClock.elapsedRealtime();
// try refreshing time source when stale
if (mTime.getCacheAge() > mSettings.getTimeCacheMaxAge()) {
@@ -605,6 +674,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
// TODO: consider marking "untrusted" times in historical stats
final long currentTime = mTime.hasCache() ? mTime.currentTimeMillis()
: System.currentTimeMillis();
+ final long persistThreshold = mSettings.getPersistThreshold();
final NetworkStats networkSnapshot;
final NetworkStats uidSnapshot;
@@ -620,30 +690,32 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
}
performNetworkPollLocked(networkSnapshot, currentTime);
- if (detailedPoll) {
- performUidPollLocked(uidSnapshot, currentTime);
- }
- // decide if enough has changed to trigger persist
- final NetworkStats persistDelta = computeStatsDelta(
+ // persist when enough network data has occurred
+ final NetworkStats persistNetworkDelta = computeStatsDelta(
mLastPersistNetworkSnapshot, networkSnapshot, true);
- final long persistThreshold = mSettings.getPersistThreshold();
+ if (forcePersist || persistNetworkDelta.getTotalBytes() > persistThreshold) {
+ writeNetworkStatsLocked();
+ mLastPersistNetworkSnapshot = networkSnapshot;
+ }
- NetworkStats.Entry entry = null;
- for (String iface : persistDelta.getUniqueIfaces()) {
- final int index = persistDelta.findIndex(iface, UID_ALL, SET_DEFAULT, TAG_NONE);
- entry = persistDelta.getValues(index, entry);
- if (forcePersist || entry.rxBytes > persistThreshold
- || entry.txBytes > persistThreshold) {
- writeNetworkStatsLocked();
- if (mUidStatsLoaded) {
- writeUidStatsLocked();
- }
- mLastPersistNetworkSnapshot = networkSnapshot;
- break;
+ if (detailedPoll) {
+ performUidPollLocked(uidSnapshot, currentTime);
+
+ // persist when enough network data has occurred
+ final NetworkStats persistUidDelta = computeStatsDelta(
+ mLastPersistUidSnapshot, uidSnapshot, true);
+ if (forcePersist || persistUidDelta.getTotalBytes() > persistThreshold) {
+ writeUidStatsLocked();
+ mLastPersistUidSnapshot = networkSnapshot;
}
}
+ if (LOGV) {
+ final long duration = SystemClock.elapsedRealtime() - startRealtime;
+ Slog.v(TAG, "performPollLocked() took " + duration + "ms");
+ }
+
// finally, dispatch updated event to any listeners
final Intent updatedIntent = new Intent(ACTION_NETWORK_STATS_UPDATED);
updatedIntent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
@@ -656,7 +728,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
private void performNetworkPollLocked(NetworkStats networkSnapshot, long currentTime) {
final HashSet<String> unknownIface = Sets.newHashSet();
- final NetworkStats delta = computeStatsDelta(mLastNetworkSnapshot, networkSnapshot, false);
+ final NetworkStats delta = computeStatsDelta(mLastPollNetworkSnapshot, networkSnapshot, false);
final long timeStart = currentTime - delta.getElapsedRealtime();
NetworkStats.Entry entry = null;
@@ -678,7 +750,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
history.removeBucketsBefore(currentTime - maxHistory);
}
- mLastNetworkSnapshot = networkSnapshot;
+ mLastPollNetworkSnapshot = networkSnapshot;
if (LOGD && unknownIface.size() > 0) {
Slog.w(TAG, "unknown interfaces " + unknownIface.toString() + ", ignoring those stats");
@@ -691,9 +763,9 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
private void performUidPollLocked(NetworkStats uidSnapshot, long currentTime) {
ensureUidStatsLoadedLocked();
- final NetworkStats delta = computeStatsDelta(mLastUidSnapshot, uidSnapshot, false);
+ final NetworkStats delta = computeStatsDelta(mLastPollUidSnapshot, uidSnapshot, false);
final NetworkStats operationsDelta = computeStatsDelta(
- mLastOperationsSnapshot, mOperations, false);
+ mLastPollOperationsSnapshot, mOperations, false);
final long timeStart = currentTime - delta.getElapsedRealtime();
NetworkStats.Entry entry = null;
@@ -731,8 +803,8 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
}
}
- mLastUidSnapshot = uidSnapshot;
- mLastOperationsSnapshot = mOperations;
+ mLastPollUidSnapshot = uidSnapshot;
+ mLastPollOperationsSnapshot = mOperations;
mOperations = new NetworkStats(0L, 10);
}
@@ -1162,8 +1234,12 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
/** {@inheritDoc} */
public boolean handleMessage(Message msg) {
switch (msg.what) {
- case MSG_FORCE_UPDATE: {
- forceUpdate();
+ case MSG_PERFORM_POLL: {
+ performPoll(false, false);
+ return true;
+ }
+ case MSG_PERFORM_POLL_DETAILED: {
+ performPoll(true, false);
return true;
}
default: {
@@ -1226,10 +1302,10 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
}
public long getPollInterval() {
- return getSecureLong(NETSTATS_POLL_INTERVAL, 15 * MINUTE_IN_MILLIS);
+ return getSecureLong(NETSTATS_POLL_INTERVAL, 30 * MINUTE_IN_MILLIS);
}
public long getPersistThreshold() {
- return getSecureLong(NETSTATS_PERSIST_THRESHOLD, 16 * KB_IN_BYTES);
+ return getSecureLong(NETSTATS_PERSIST_THRESHOLD, 512 * KB_IN_BYTES);
}
public long getNetworkBucketDuration() {
return getSecureLong(NETSTATS_NETWORK_BUCKET_DURATION, HOUR_IN_MILLIS);
diff --git a/services/java/com/android/server/pm/PackageManagerService.java b/services/java/com/android/server/pm/PackageManagerService.java
index 2f19a46..b8797d1 100644
--- a/services/java/com/android/server/pm/PackageManagerService.java
+++ b/services/java/com/android/server/pm/PackageManagerService.java
@@ -194,7 +194,8 @@ public class PackageManagerService extends IPackageManager.Stub {
/**
* Whether verification is enabled by default.
*/
- private static final boolean DEFAULT_VERIFY_ENABLE = true;
+ // STOPSHIP: change this to true
+ private static final boolean DEFAULT_VERIFY_ENABLE = false;
/**
* The default maximum time to wait for the verification agent to return in