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/AppWidgetService.java6
-rw-r--r--services/java/com/android/server/BackupManagerService.java91
-rw-r--r--services/java/com/android/server/ConnectivityService.java66
-rw-r--r--services/java/com/android/server/InputMethodManagerService.java36
-rw-r--r--services/java/com/android/server/MasterClearReceiver.java6
-rw-r--r--services/java/com/android/server/MountService.java6
-rw-r--r--services/java/com/android/server/WifiService.java13
-rw-r--r--services/java/com/android/server/accessibility/AccessibilityManagerService.java136
-rw-r--r--services/java/com/android/server/accessibility/TouchExplorer.java7
-rw-r--r--services/java/com/android/server/am/ActivityManagerService.java121
-rw-r--r--services/java/com/android/server/am/ActivityStack.java6
-rw-r--r--services/java/com/android/server/am/ProcessRecord.java8
-rw-r--r--services/java/com/android/server/net/NetworkPolicyManagerService.java80
-rw-r--r--services/java/com/android/server/net/NetworkStatsService.java29
-rw-r--r--services/java/com/android/server/pm/Settings.java29
-rw-r--r--services/java/com/android/server/usb/UsbDeviceManager.java5
-rw-r--r--services/java/com/android/server/wm/DragState.java34
-rw-r--r--services/java/com/android/server/wm/InputMonitor.java46
18 files changed, 520 insertions, 205 deletions
diff --git a/services/java/com/android/server/AppWidgetService.java b/services/java/com/android/server/AppWidgetService.java
index 0b15221..438883e 100644
--- a/services/java/com/android/server/AppWidgetService.java
+++ b/services/java/com/android/server/AppWidgetService.java
@@ -1022,6 +1022,12 @@ class AppWidgetService extends IAppWidgetService.Stub
info.minWidth = value != null ? value.data : 0;
value = sa.peekValue(com.android.internal.R.styleable.AppWidgetProviderInfo_minHeight);
info.minHeight = value != null ? value.data : 0;
+ value = sa.peekValue(
+ com.android.internal.R.styleable.AppWidgetProviderInfo_minResizeWidth);
+ info.minResizeWidth = value != null ? value.data : info.minWidth;
+ value = sa.peekValue(
+ com.android.internal.R.styleable.AppWidgetProviderInfo_minResizeHeight);
+ info.minResizeHeight = value != null ? value.data : info.minHeight;
info.updatePeriodMillis = sa.getInt(
com.android.internal.R.styleable.AppWidgetProviderInfo_updatePeriodMillis, 0);
diff --git a/services/java/com/android/server/BackupManagerService.java b/services/java/com/android/server/BackupManagerService.java
index 168b894..e9e66cb 100644
--- a/services/java/com/android/server/BackupManagerService.java
+++ b/services/java/com/android/server/BackupManagerService.java
@@ -87,8 +87,10 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.io.RandomAccessFile;
+import java.io.UnsupportedEncodingException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
@@ -109,6 +111,8 @@ class BackupManagerService extends IBackupManager.Stub {
// Name and current contents version of the full-backup manifest file
static final String BACKUP_MANIFEST_FILENAME = "_manifest";
static final int BACKUP_MANIFEST_VERSION = 1;
+ static final String BACKUP_FILE_HEADER_MAGIC = "ANDROID BACKUP\n";
+ static final int BACKUP_FILE_VERSION = 1;
// How often we perform a backup pass. Privileged external callers can
// trigger an immediate pass.
@@ -1791,16 +1795,42 @@ class BackupManagerService extends IBackupManager.Stub {
}
}
- // Set up the compression stage
FileOutputStream ofstream = new FileOutputStream(mOutputFile.getFileDescriptor());
+
+ // Set up the compression stage
Deflater deflater = new Deflater(Deflater.BEST_COMPRESSION);
DeflaterOutputStream out = new DeflaterOutputStream(ofstream, deflater, true);
- // !!! TODO: if using encryption, set up the encryption stage
- // and emit the tar header stating the password salt.
-
PackageInfo pkg = null;
try {
+
+ // !!! TODO: if using encryption, set up the encryption stage
+ // and emit the tar header stating the password salt.
+
+ // Write the global file header. All strings are UTF-8 encoded; lines end
+ // with a '\n' byte. Actual backup data begins immediately following the
+ // final '\n'.
+ //
+ // line 1: "ANDROID BACKUP"
+ // line 2: backup file format version, currently "1"
+ // line 3: compressed? "0" if not compressed, "1" if compressed.
+ // line 4: encryption salt? "-" if not encrypted, otherwise this
+ // line contains the encryption salt with which the user-
+ // supplied password is to be expanded, in hexadecimal.
+ StringBuffer headerbuf = new StringBuffer(256);
+ // !!! TODO: programmatically build the compressed / encryption salt fields
+ headerbuf.append(BACKUP_FILE_HEADER_MAGIC);
+ headerbuf.append("1\n1\n-\n");
+
+ try {
+ byte[] header = headerbuf.toString().getBytes("UTF-8");
+ ofstream.write(header);
+ } catch (Exception e) {
+ // Should never happen!
+ Slog.e(TAG, "Unable to emit archive header", e);
+ return;
+ }
+
// Now back up the app data via the agent mechanism
int N = packagesToBackup.size();
for (int i = 0; i < N; i++) {
@@ -2176,7 +2206,46 @@ class BackupManagerService extends IBackupManager.Stub {
mBytes = 0;
byte[] buffer = new byte[32 * 1024];
FileInputStream rawInStream = new FileInputStream(mInputFile.getFileDescriptor());
- InflaterInputStream in = new InflaterInputStream(rawInStream);
+
+ // First, parse out the unencrypted/uncompressed header
+ boolean compressed = false;
+ boolean encrypted = false;
+ final InputStream in;
+
+ boolean okay = false;
+ final int headerLen = BACKUP_FILE_HEADER_MAGIC.length();
+ byte[] streamHeader = new byte[headerLen];
+ try {
+ int got;
+ if ((got = rawInStream.read(streamHeader, 0, headerLen)) == headerLen) {
+ byte[] magicBytes = BACKUP_FILE_HEADER_MAGIC.getBytes("UTF-8");
+ if (Arrays.equals(magicBytes, streamHeader)) {
+ // okay, header looks good. now parse out the rest of the fields.
+ String s = readHeaderLine(rawInStream);
+ if (Integer.parseInt(s) == BACKUP_FILE_VERSION) {
+ // okay, it's a version we recognize
+ s = readHeaderLine(rawInStream);
+ compressed = (Integer.parseInt(s) != 0);
+ s = readHeaderLine(rawInStream);
+ if (!s.startsWith("-")) {
+ encrypted = true;
+ // TODO: parse out the salt here and process with the user pw
+ }
+ okay = true;
+ } else Slog.e(TAG, "Wrong header version: " + s);
+ } else Slog.e(TAG, "Didn't read the right header magic");
+ } else Slog.e(TAG, "Only read " + got + " bytes of header");
+ } catch (NumberFormatException e) {
+ Slog.e(TAG, "Can't parse restore data header");
+ }
+
+ if (!okay) {
+ Slog.e(TAG, "Invalid restore data; aborting.");
+ return;
+ }
+
+ // okay, use the right stream layer based on compression
+ in = (compressed) ? new InflaterInputStream(rawInStream) : rawInStream;
boolean didRestore;
do {
@@ -2184,6 +2253,8 @@ class BackupManagerService extends IBackupManager.Stub {
} while (didRestore);
if (DEBUG) Slog.v(TAG, "Done consuming input tarfile, total bytes=" + mBytes);
+ } catch (IOException e) {
+ Slog.e(TAG, "Unable to read restore input");
} finally {
tearDownPipes();
tearDownAgent(mTargetApp);
@@ -2207,6 +2278,16 @@ class BackupManagerService extends IBackupManager.Stub {
}
}
+ String readHeaderLine(InputStream in) throws IOException {
+ int c;
+ StringBuffer buffer = new StringBuffer(80);
+ while ((c = in.read()) >= 0) {
+ if (c == '\n') break; // consume and discard the newlines
+ buffer.append((char)c);
+ }
+ return buffer.toString();
+ }
+
boolean restoreOneFile(InputStream instream, byte[] buffer) {
FileMetadata info;
try {
diff --git a/services/java/com/android/server/ConnectivityService.java b/services/java/com/android/server/ConnectivityService.java
index 7812927..b78424b 100644
--- a/services/java/com/android/server/ConnectivityService.java
+++ b/services/java/com/android/server/ConnectivityService.java
@@ -248,7 +248,7 @@ public class ConnectivityService extends IConnectivityManager.Stub {
// list of DeathRecipients used to make sure features are turned off when
// a process dies
- private List mFeatureUsers;
+ private List<FeatureUser> mFeatureUsers;
private boolean mSystemReady;
private Intent mInitialBroadcast;
@@ -436,7 +436,7 @@ public class ConnectivityService extends IConnectivityManager.Stub {
mNetRequestersPids[i] = new ArrayList();
}
- mFeatureUsers = new ArrayList();
+ mFeatureUsers = new ArrayList<FeatureUser>();
mNumDnsEntries = 0;
@@ -795,6 +795,20 @@ public class ConnectivityService extends IConnectivityManager.Stub {
stopUsingNetworkFeature(this, false);
}
+ public boolean isSameUser(FeatureUser u) {
+ if (u == null) return false;
+
+ return isSameUser(u.mPid, u.mUid, u.mNetworkType, u.mFeature);
+ }
+
+ public boolean isSameUser(int pid, int uid, int networkType, String feature) {
+ if ((mPid == pid) && (mUid == uid) && (mNetworkType == networkType) &&
+ TextUtils.equals(mFeature, feature)) {
+ return true;
+ }
+ return false;
+ }
+
public String toString() {
return "FeatureUser("+mNetworkType+","+mFeature+","+mPid+","+mUid+"), created " +
(System.currentTimeMillis() - mCreateTime) + " mSec ago";
@@ -845,16 +859,29 @@ public class ConnectivityService extends IConnectivityManager.Stub {
}
}
+ int restoreTimer = getRestoreDefaultNetworkDelay(usedNetworkType);
+
synchronized(this) {
- mFeatureUsers.add(f);
+ boolean addToList = true;
+ if (restoreTimer < 0) {
+ // In case there is no timer is specified for the feature,
+ // make sure we don't add duplicate entry with the same request.
+ for (FeatureUser u : mFeatureUsers) {
+ if (u.isSameUser(f)) {
+ // Duplicate user is found. Do not add.
+ addToList = false;
+ break;
+ }
+ }
+ }
+
+ if (addToList) mFeatureUsers.add(f);
if (!mNetRequestersPids[usedNetworkType].contains(currentPid)) {
// this gets used for per-pid dns when connected
mNetRequestersPids[usedNetworkType].add(currentPid);
}
}
- int restoreTimer = getRestoreDefaultNetworkDelay(usedNetworkType);
-
if (restoreTimer >= 0) {
mHandler.sendMessageDelayed(
mHandler.obtainMessage(EVENT_RESTORE_DEFAULT_NETWORK, f), restoreTimer);
@@ -904,11 +931,9 @@ public class ConnectivityService extends IConnectivityManager.Stub {
boolean found = false;
synchronized(this) {
- for (int i = 0; i < mFeatureUsers.size() ; i++) {
- u = (FeatureUser)mFeatureUsers.get(i);
- if (uid == u.mUid && pid == u.mPid &&
- networkType == u.mNetworkType &&
- TextUtils.equals(feature, u.mFeature)) {
+ for (FeatureUser x : mFeatureUsers) {
+ if (x.isSameUser(pid, uid, networkType, feature)) {
+ u = x;
found = true;
break;
}
@@ -960,11 +985,8 @@ public class ConnectivityService extends IConnectivityManager.Stub {
// do not pay attention to duplicate requests - in effect the
// API does not refcount and a single stop will counter multiple starts.
if (ignoreDups == false) {
- for (int i = 0; i < mFeatureUsers.size() ; i++) {
- FeatureUser x = (FeatureUser)mFeatureUsers.get(i);
- if (x.mUid == u.mUid && x.mPid == u.mPid &&
- x.mNetworkType == u.mNetworkType &&
- TextUtils.equals(x.mFeature, u.mFeature)) {
+ for (FeatureUser x : mFeatureUsers) {
+ if (x.isSameUser(u)) {
if (DBG) log("ignoring stopUsingNetworkFeature as dup is found");
return 1;
}
@@ -1084,12 +1106,15 @@ public class ConnectivityService extends IConnectivityManager.Stub {
if (r.isHostRoute() == false) {
RouteInfo bestRoute = RouteInfo.selectBestRoute(lp.getRoutes(), r.getGateway());
if (bestRoute != null) {
- if (bestRoute.getGateway().equals(r.getGateway()) == false) {
- bestRoute = RouteInfo.makeHostRoute(r.getGateway(), bestRoute.getGateway());
- } else {
+ if (bestRoute.getGateway().equals(r.getGateway())) {
+ // if there is no better route, add the implied hostroute for our gateway
bestRoute = RouteInfo.makeHostRoute(r.getGateway());
+ } else {
+ // if we will connect to our gateway through another route, add a direct
+ // route to it's gateway
+ bestRoute = RouteInfo.makeHostRoute(r.getGateway(), bestRoute.getGateway());
}
- if (!modifyRoute(ifaceName, lp, bestRoute, cycleCount+1, doAdd)) return false;
+ modifyRoute(ifaceName, lp, bestRoute, cycleCount+1, doAdd);
}
}
if (doAdd) {
@@ -1168,9 +1193,6 @@ public class ConnectivityService extends IConnectivityManager.Stub {
public void setDataDependency(int networkType, boolean met) {
enforceConnectivityInternalPermission();
- if (DBG) {
- log("setDataDependency(" + networkType + ", " + met + ")");
- }
mHandler.sendMessage(mHandler.obtainMessage(EVENT_SET_DEPENDENCY_MET,
(met ? ENABLED : DISABLED), networkType));
}
diff --git a/services/java/com/android/server/InputMethodManagerService.java b/services/java/com/android/server/InputMethodManagerService.java
index 18d393f..2597978 100644
--- a/services/java/com/android/server/InputMethodManagerService.java
+++ b/services/java/com/android/server/InputMethodManagerService.java
@@ -35,6 +35,7 @@ import org.xmlpull.v1.XmlSerializer;
import android.app.ActivityManagerNative;
import android.app.AlertDialog;
+import android.app.KeyguardManager;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
@@ -47,6 +48,7 @@ import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
@@ -160,6 +162,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
// Ongoing notification
private final NotificationManager mNotificationManager;
+ private final KeyguardManager mKeyguardManager;
private final Notification mImeSwitcherNotification;
private final PendingIntent mImeSwitchPendingIntent;
private final boolean mShowOngoingImeSwitcherForPhones;
@@ -520,6 +523,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
}
});
+ mKeyguardManager = (KeyguardManager)
+ mContext.getSystemService(Context.KEYGUARD_SERVICE);
mNotificationManager = (NotificationManager)
mContext.getSystemService(Context.NOTIFICATION_SERVICE);
mImeSwitcherNotification = new Notification();
@@ -1632,19 +1637,27 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
}
@Override
- public boolean setAdditionalInputMethodSubtypes(IBinder token, InputMethodSubtype[] subtypes) {
- if (token == null || mCurToken != token) {
- return false;
- }
- if (subtypes == null || subtypes.length == 0) return false;
+ public boolean setAdditionalInputMethodSubtypes(String imiId, InputMethodSubtype[] subtypes) {
+ // By this IPC call, only a process which shares the same uid with the IME can add
+ // additional input method subtypes to the IME.
+ if (TextUtils.isEmpty(imiId) || subtypes == null || subtypes.length == 0) return false;
synchronized (mMethodMap) {
- final InputMethodInfo imi = mMethodMap.get(mCurMethodId);
+ final InputMethodInfo imi = mMethodMap.get(imiId);
if (imi == null) return false;
- final int N = subtypes.length;
- mFileManager.addInputMethodSubtypes(imi, subtypes);
- buildInputMethodListLocked(mMethodList, mMethodMap);
- return true;
+ final PackageManager pm = mContext.getPackageManager();
+ final String[] packageInfos = pm.getPackagesForUid(Binder.getCallingUid());
+ if (packageInfos != null) {
+ final int packageNum = packageInfos.length;
+ for (int i = 0; i < packageNum; ++i) {
+ if (packageInfos[i].equals(imi.getPackageName())) {
+ mFileManager.addInputMethodSubtypes(imi, subtypes);
+ buildInputMethodListLocked(mMethodList, mMethodMap);
+ return true;
+ }
+ }
+ }
}
+ return false;
}
private void setInputMethodWithSubtypeId(IBinder token, String id, int subtypeId) {
@@ -2118,7 +2131,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
}
});
- if (showSubtypes) {
+ if (showSubtypes && !(mKeyguardManager.isKeyguardLocked()
+ && mKeyguardManager.isKeyguardSecure())) {
mDialogBuilder.setPositiveButton(
com.android.internal.R.string.configure_input_methods,
new DialogInterface.OnClickListener() {
diff --git a/services/java/com/android/server/MasterClearReceiver.java b/services/java/com/android/server/MasterClearReceiver.java
index bdb5a24..86f57d1 100644
--- a/services/java/com/android/server/MasterClearReceiver.java
+++ b/services/java/com/android/server/MasterClearReceiver.java
@@ -43,11 +43,7 @@ public class MasterClearReceiver extends BroadcastReceiver {
@Override
public void run() {
try {
- if (intent.hasExtra("enableEFS")) {
- RecoverySystem.rebootToggleEFS(context, intent.getBooleanExtra("enableEFS", false));
- } else {
- RecoverySystem.rebootWipeUserData(context);
- }
+ RecoverySystem.rebootWipeUserData(context);
Log.wtf(TAG, "Still running after master clear?!");
} catch (IOException e) {
Slog.e(TAG, "Can't perform master clear/factory reset", e);
diff --git a/services/java/com/android/server/MountService.java b/services/java/com/android/server/MountService.java
index 94465fd..7f61c635 100644
--- a/services/java/com/android/server/MountService.java
+++ b/services/java/com/android/server/MountService.java
@@ -1339,7 +1339,11 @@ class MountService extends IMountService.Stub implements INativeDaemonConnectorC
String state = mVolumeStates.get(mountPoint);
if (state == null) {
Slog.w(TAG, "getVolumeState(" + mountPoint + "): Unknown volume");
- throw new IllegalArgumentException();
+ if (SystemProperties.get("vold.encrypt_progress").length() != 0) {
+ state = Environment.MEDIA_REMOVED;
+ } else {
+ throw new IllegalArgumentException();
+ }
}
return state;
diff --git a/services/java/com/android/server/WifiService.java b/services/java/com/android/server/WifiService.java
index 5f0922e..7112553 100644
--- a/services/java/com/android/server/WifiService.java
+++ b/services/java/com/android/server/WifiService.java
@@ -35,8 +35,8 @@ import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.net.wifi.WifiStateMachine;
import android.net.wifi.WifiConfiguration;
+import android.net.wifi.WifiWatchdogStateMachine;
import android.net.wifi.WifiConfiguration.KeyMgmt;
-import android.net.wifi.WifiWatchdogService;
import android.net.wifi.WpsConfiguration;
import android.net.wifi.WpsResult;
import android.net.ConnectivityManager;
@@ -343,7 +343,7 @@ public class WifiService extends IWifiManager.Stub {
* Protected by mWifiStateTracker lock.
*/
private final WorkSource mTmpWorkSource = new WorkSource();
- private WifiWatchdogService mWifiWatchdogService;
+ private WifiWatchdogStateMachine mWifiWatchdogStateMachine;
WifiService(Context context) {
mContext = context;
@@ -434,8 +434,9 @@ public class WifiService extends IWifiManager.Stub {
(wifiEnabled ? "enabled" : "disabled"));
setWifiEnabled(wifiEnabled);
- //TODO: as part of WWS refactor, create only when needed
- mWifiWatchdogService = new WifiWatchdogService(mContext);
+ mWifiWatchdogStateMachine = WifiWatchdogStateMachine.
+ makeWifiWatchdogStateMachine(mContext);
+
}
private boolean testAndClearWifiSavedState() {
@@ -1162,8 +1163,8 @@ public class WifiService extends IWifiManager.Stub {
mLocks.dump(pw);
pw.println();
- pw.println("WifiWatchdogService dump");
- mWifiWatchdogService.dump(pw);
+ pw.println("WifiWatchdogStateMachine dump");
+ mWifiWatchdogStateMachine.dump(pw);
}
private class WifiLock extends DeathRecipient {
diff --git a/services/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/java/com/android/server/accessibility/AccessibilityManagerService.java
index f99951fa..bb9d15b 100644
--- a/services/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -127,13 +127,15 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
private int mHandledFeedbackTypes = 0;
- private boolean mIsEnabled;
+ private boolean mIsAccessibilityEnabled;
+
+ private boolean mIsTouchExplorationRequested;
private AccessibilityInputFilter mInputFilter;
private final List<AccessibilityServiceInfo> mEnabledServicesForFeedbackTempList = new ArrayList<AccessibilityServiceInfo>();
- private boolean mHasInputFilter;
+ private boolean mIsTouchExplorationEnabled;
private final WindowManagerService mWindowManagerService;
@@ -230,16 +232,21 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
if (intent.getAction() == Intent.ACTION_BOOT_COMPLETED) {
synchronized (mLock) {
populateAccessibilityServiceListLocked();
- // get the accessibility enabled setting on boot
- mIsEnabled = Settings.Secure.getInt(mContext.getContentResolver(),
+ // get accessibility enabled setting on boot
+ mIsAccessibilityEnabled = Settings.Secure.getInt(
+ mContext.getContentResolver(),
Settings.Secure.ACCESSIBILITY_ENABLED, 0) == 1;
-
// if accessibility is enabled inform our clients we are on
- if (mIsEnabled) {
- updateClientsLocked();
+ if (mIsAccessibilityEnabled) {
+ sendAccessibilityEnabledToClientsLocked();
}
-
manageServicesLocked();
+
+ // get touch exploration enabled setting on boot
+ mIsTouchExplorationRequested = Settings.Secure.getInt(
+ mContext.getContentResolver(),
+ Settings.Secure.TOUCH_EXPLORATION_REQUESTED, 0) == 1;
+ updateTouchExplorationEnabledLocked();
}
return;
@@ -264,29 +271,48 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
private void registerSettingsContentObservers() {
ContentResolver contentResolver = mContext.getContentResolver();
- Uri enabledUri = Settings.Secure.getUriFor(Settings.Secure.ACCESSIBILITY_ENABLED);
- contentResolver.registerContentObserver(enabledUri, false,
+ Uri accessibilityEnabledUri = Settings.Secure.getUriFor(
+ Settings.Secure.ACCESSIBILITY_ENABLED);
+ contentResolver.registerContentObserver(accessibilityEnabledUri, false,
new ContentObserver(new Handler()) {
@Override
public void onChange(boolean selfChange) {
super.onChange(selfChange);
synchronized (mLock) {
- mIsEnabled = Settings.Secure.getInt(mContext.getContentResolver(),
+ mIsAccessibilityEnabled = Settings.Secure.getInt(
+ mContext.getContentResolver(),
Settings.Secure.ACCESSIBILITY_ENABLED, 0) == 1;
- if (mIsEnabled) {
+ if (mIsAccessibilityEnabled) {
manageServicesLocked();
} else {
unbindAllServicesLocked();
}
- updateClientsLocked();
+ sendAccessibilityEnabledToClientsLocked();
}
}
});
- Uri providersUri =
+ Uri touchExplorationRequestedUri = Settings.Secure.getUriFor(
+ Settings.Secure.TOUCH_EXPLORATION_REQUESTED);
+ contentResolver.registerContentObserver(touchExplorationRequestedUri, false,
+ new ContentObserver(new Handler()) {
+ @Override
+ public void onChange(boolean selfChange) {
+ super.onChange(selfChange);
+
+ synchronized (mLock) {
+ mIsTouchExplorationRequested = Settings.Secure.getInt(
+ mContext.getContentResolver(),
+ Settings.Secure.TOUCH_EXPLORATION_REQUESTED, 0) == 1;
+ updateTouchExplorationEnabledLocked();
+ }
+ }
+ });
+
+ Uri accessibilityServicesUri =
Settings.Secure.getUriFor(Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES);
- contentResolver.registerContentObserver(providersUri, false,
+ contentResolver.registerContentObserver(accessibilityServicesUri, false,
new ContentObserver(new Handler()) {
@Override
public void onChange(boolean selfChange) {
@@ -312,7 +338,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
}
}
}, 0);
- return mIsEnabled;
+ return mIsAccessibilityEnabled;
}
}
@@ -602,7 +628,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
service.linkToOwnDeath();
mServices.add(service);
mComponentNameToServiceMap.put(service.mComponentName, service);
- updateInputFilterLocked();
+ updateTouchExplorationEnabledLocked();
} catch (RemoteException e) {
/* do nothing */
}
@@ -622,7 +648,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
mComponentNameToServiceMap.remove(service.mComponentName);
mHandler.removeMessages(service.mId);
service.unlinkToOwnDeath();
- updateInputFilterLocked();
+ updateTouchExplorationEnabledLocked();
return removed;
}
@@ -727,7 +753,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
Set<ComponentName> enabledServices) {
Map<ComponentName, Service> componentNameToServiceMap = mComponentNameToServiceMap;
- boolean isEnabled = mIsEnabled;
+ boolean isEnabled = mIsAccessibilityEnabled;
for (int i = 0, count = installedServices.size(); i < count; i++) {
AccessibilityServiceInfo installedService = installedServices.get(i);
@@ -741,7 +767,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
service = new Service(componentName, installedService, false);
}
service.bind();
- } else if (!enabledServices.contains(componentName)) {
+ } else {
if (service != null) {
service.unbind();
}
@@ -757,10 +783,10 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
/**
* Updates the state of {@link android.view.accessibility.AccessibilityManager} clients.
*/
- private void updateClientsLocked() {
+ private void sendAccessibilityEnabledToClientsLocked() {
for (int i = 0, count = mClients.size(); i < count; i++) {
try {
- mClients.get(i).setEnabled(mIsEnabled);
+ mClients.get(i).setEnabled(mIsAccessibilityEnabled);
} catch (RemoteException re) {
mClients.remove(i);
count--;
@@ -770,29 +796,48 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
}
/**
- * Updates the input filter state. The filter is enabled if accessibility
- * is enabled and there is at least one accessibility service providing
- * spoken feedback.
+ * Sends the touch exploration state to clients.
*/
- private void updateInputFilterLocked() {
- if (mIsEnabled) {
- final boolean hasSpokenFeedbackServices = !getEnabledAccessibilityServiceList(
- AccessibilityServiceInfo.FEEDBACK_SPOKEN).isEmpty();
- if (hasSpokenFeedbackServices) {
- if (mHasInputFilter) {
- return;
+ private void sendTouchExplorationEnabledToClientsLocked() {
+ for (int i = 0, count = mClients.size(); i < count; i++) {
+ try {
+ mClients.get(i).setTouchExplorationEnabled(mIsTouchExplorationEnabled);
+ } catch (RemoteException re) {
+ mClients.remove(i);
+ count--;
+ i--;
+ }
+ }
+ }
+
+ /**
+ * Updates the touch exploration state. Touch exploration is enabled if it
+ * is requested, accessibility is on and there is at least one enabled
+ * accessibility service providing spoken feedback.
+ */
+ private void updateTouchExplorationEnabledLocked() {
+ if (mIsAccessibilityEnabled && mIsTouchExplorationRequested) {
+ final boolean hasSpeakingServicesEnabled = !getEnabledAccessibilityServiceList(
+ AccessibilityServiceInfo.FEEDBACK_SPOKEN).isEmpty();
+ if (!mIsTouchExplorationEnabled) {
+ if (!hasSpeakingServicesEnabled) {
+ return;
}
if (mInputFilter == null) {
mInputFilter = new AccessibilityInputFilter(mContext);
}
mWindowManagerService.setInputFilter(mInputFilter);
- mHasInputFilter = true;
+ mIsTouchExplorationEnabled = true;
+ sendTouchExplorationEnabledToClientsLocked();
+ return;
+ } else if (hasSpeakingServicesEnabled) {
return;
}
}
- if (mHasInputFilter) {
+ if (mIsTouchExplorationEnabled) {
mWindowManagerService.setInputFilter(null);
- mHasInputFilter = false;
+ mIsTouchExplorationEnabled = false;
+ sendTouchExplorationEnabledToClientsLocked();
}
}
@@ -935,9 +980,11 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
}
}
- public AccessibilityNodeInfo findAccessibilityNodeInfoByViewIdInActiveWindow(int viewId) {
+ public AccessibilityNodeInfo findAccessibilityNodeInfoByViewIdInActiveWindow(int viewId)
+ throws RemoteException {
IAccessibilityInteractionConnection connection = null;
synchronized (mLock) {
+ mSecurityPolicy.enforceCanRetrieveWindowContent(this);
final boolean permissionGranted = mSecurityPolicy.canRetrieveWindowContent(this);
if (!permissionGranted) {
return null;
@@ -975,15 +1022,16 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
}
public List<AccessibilityNodeInfo> findAccessibilityNodeInfosByViewTextInActiveWindow(
- String text) {
+ String text) throws RemoteException {
return findAccessibilityNodeInfosByViewText(text,
mSecurityPolicy.mRetrievalAlowingWindowId, View.NO_ID);
}
public List<AccessibilityNodeInfo> findAccessibilityNodeInfosByViewText(String text,
- int accessibilityWindowId, int accessibilityViewId) {
+ int accessibilityWindowId, int accessibilityViewId) throws RemoteException {
IAccessibilityInteractionConnection connection = null;
synchronized (mLock) {
+ mSecurityPolicy.enforceCanRetrieveWindowContent(this);
final boolean permissionGranted =
mSecurityPolicy.canGetAccessibilityNodeInfoLocked(this, accessibilityWindowId);
if (!permissionGranted) {
@@ -1026,9 +1074,10 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
}
public AccessibilityNodeInfo findAccessibilityNodeInfoByAccessibilityId(
- int accessibilityWindowId, int accessibilityViewId) {
+ int accessibilityWindowId, int accessibilityViewId) throws RemoteException {
IAccessibilityInteractionConnection connection = null;
synchronized (mLock) {
+ mSecurityPolicy.enforceCanRetrieveWindowContent(this);
final boolean permissionGranted =
mSecurityPolicy.canGetAccessibilityNodeInfoLocked(this, accessibilityWindowId);
if (!permissionGranted) {
@@ -1199,6 +1248,15 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
return service.mCanRetrieveScreenContent;
}
+ public void enforceCanRetrieveWindowContent(Service service) throws RemoteException {
+ // This happens due to incorrect registration so make it apparent.
+ if (!canRetrieveWindowContent(service)) {
+ Slog.e(LOG_TAG, "Accessibility serivce " + service.mComponentName + " does not " +
+ "declare android:canRetrieveWindowContent.");
+ throw new RemoteException();
+ }
+ }
+
private boolean isRetrievalAllowingWindow(int windowId) {
return (mRetrievalAlowingWindowId == windowId);
}
diff --git a/services/java/com/android/server/accessibility/TouchExplorer.java b/services/java/com/android/server/accessibility/TouchExplorer.java
index dbd9474..5a3a55d 100644
--- a/services/java/com/android/server/accessibility/TouchExplorer.java
+++ b/services/java/com/android/server/accessibility/TouchExplorer.java
@@ -116,9 +116,6 @@ public class TouchExplorer implements Explorer {
// which would perform a click and tapping and holding a long press.
private final int mTouchExplorationTapSlop;
- // Context handle for accessing resources.
- private final Context mContext;
-
// The InputFilter this tracker is associated with i.e. the filter
// which delegates event processing to this touch explorer.
private final InputFilter mInputFilter;
@@ -161,7 +158,6 @@ public class TouchExplorer implements Explorer {
ViewConfiguration.get(context).getScaledTouchExplorationTapSlop();
mDraggingDistance = mTouchExplorationTapSlop * COEFFICIENT_DRAGGING_DISTANCE;
mPointerTracker = new PointerTracker(context);
- mContext = context;
mHandler = new Handler(context.getMainLooper());
mSendHoverDelayed = new SendHoverDelayed();
mAccessibilityManager = AccessibilityManager.getInstance(context);
@@ -216,7 +212,8 @@ public class TouchExplorer implements Explorer {
// Send a hover for every finger down so the user gets feedback
// where she is currently touching.
mSendHoverDelayed.forceSendAndRemove();
- final int pointerIdBits = (1 << event.getActionIndex());
+ final int pointerIndex = event.getActionIndex();
+ final int pointerIdBits = (1 << event.getPointerId(pointerIndex));
mSendHoverDelayed.post(event, MotionEvent.ACTION_HOVER_ENTER, pointerIdBits,
policyFlags, DELAY_SEND_HOVER_MOVE);
} break;
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index f546cf1..0924b86 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -2439,7 +2439,7 @@ public final class ActivityManagerService extends ActivityManagerNative
r.mayFreezeScreenLocked(r.app) ? r : null);
if (config != null) {
r.frozenBeforeDestroy = true;
- if (!updateConfigurationLocked(config, r)) {
+ if (!updateConfigurationLocked(config, r, false)) {
mMainStack.resumeTopActivityLocked(null);
}
}
@@ -3610,8 +3610,10 @@ public final class ActivityManagerService extends ActivityManagerNative
String processName = app.processName;
try {
- thread.asBinder().linkToDeath(new AppDeathRecipient(
- app, pid, thread), 0);
+ AppDeathRecipient adr = new AppDeathRecipient(
+ app, pid, thread);
+ thread.asBinder().linkToDeath(adr, 0);
+ app.deathRecipient = adr;
} catch (RemoteException e) {
app.resetPackageList();
startProcessLocked(app, "link fail", processName);
@@ -3687,6 +3689,7 @@ public final class ActivityManagerService extends ActivityManagerNative
Slog.w(TAG, "Exception thrown during bind!", e);
app.resetPackageList();
+ app.unlinkDeathRecipient();
startProcessLocked(app, "bind fail", processName);
return false;
}
@@ -8885,25 +8888,59 @@ public final class ActivityManagerService extends ActivityManagerNative
pw.println("Applications Graphics Acceleration Info:");
pw.println("Uptime: " + uptime + " Realtime: " + realtime);
- String callArgs[] = {"graphics"};
for (int i = procs.size() - 1 ; i >= 0 ; i--) {
ProcessRecord r = procs.get(i);
if (r.thread != null) {
pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
pw.flush();
try {
- TransferPipe.goDump(r.thread.asBinder(), fd, callArgs);
+ TransferPipe tp = new TransferPipe();
+ try {
+ r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
+ tp.go(fd);
+ } finally {
+ tp.kill();
+ }
} catch (IOException e) {
- pw.println("Failure: " + e);
+ pw.println("Failure while dumping the app: " + r);
pw.flush();
} catch (RemoteException e) {
- pw.println("Got RemoteException!");
+ pw.println("Got a RemoteException while dumping the app " + r);
pw.flush();
}
}
}
}
+ final static class MemItem {
+ final String label;
+ final long pss;
+
+ public MemItem(String _label, long _pss) {
+ label = _label;
+ pss = _pss;
+ }
+ }
+
+ final void dumpMemItems(PrintWriter pw, String prefix, ArrayList<MemItem> items) {
+ Collections.sort(items, new Comparator<MemItem>() {
+ @Override
+ public int compare(MemItem lhs, MemItem rhs) {
+ if (lhs.pss < rhs.pss) {
+ return 1;
+ } else if (lhs.pss > rhs.pss) {
+ return -1;
+ }
+ return 0;
+ }
+ });
+
+ for (int i=0; i<items.size(); i++) {
+ MemItem mi = items.get(i);
+ pw.print(prefix); pw.printf("%8d Kb: ", mi.pss); pw.println(mi.label);
+ }
+ }
+
final void dumpApplicationMemoryUsage(FileDescriptor fd,
PrintWriter pw, String prefix, String[] args) {
ArrayList<ProcessRecord> procs = collectProcesses(pw, args);
@@ -8923,6 +8960,11 @@ public final class ActivityManagerService extends ActivityManagerNative
pw.println("Applications Memory Usage (kB):");
pw.println("Uptime: " + uptime + " Realtime: " + realtime);
}
+
+ ArrayList<MemItem> procMems = new ArrayList<MemItem>();
+ long nativePss=0, dalvikPss=0, otherPss=0;
+ long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
+
for (int i = procs.size() - 1 ; i >= 0 ; i--) {
ProcessRecord r = procs.get(i);
if (r.thread != null) {
@@ -8930,19 +8972,48 @@ public final class ActivityManagerService extends ActivityManagerNative
pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **");
pw.flush();
}
+ Debug.MemoryInfo mi = null;
try {
- TransferPipe.goDump(r.thread.asBinder(), fd, args);
- } catch (IOException e) {
- pw.println("Failure: " + e);
- pw.flush();
+ mi = r.thread.dumpMemInfo(fd, args);
} catch (RemoteException e) {
if (!isCheckinRequest) {
pw.println("Got RemoteException!");
pw.flush();
}
}
+ if (!isCheckinRequest && mi != null) {
+ procMems.add(new MemItem(r.processName + " (pid " + r.pid + ")",
+ mi.getTotalPss()));
+
+ nativePss += mi.nativePss;
+ dalvikPss += mi.dalvikPss;
+ otherPss += mi.otherPss;
+ for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
+ long mem = mi.getOtherPss(j);
+ miscPss[j] += mem;
+ otherPss -= mem;
+ }
+ }
}
}
+
+ if (!isCheckinRequest && procs.size() > 1) {
+ ArrayList<MemItem> catMems = new ArrayList<MemItem>();
+
+ catMems.add(new MemItem("Native", nativePss));
+ catMems.add(new MemItem("Dalvik", dalvikPss));
+ catMems.add(new MemItem("Unknown", otherPss));
+ for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
+ catMems.add(new MemItem(Debug.MemoryInfo.getOtherLabel(j), miscPss[j]));
+ }
+
+ pw.println();
+ pw.println("Total PSS by process:");
+ dumpMemItems(pw, " ", procMems);
+ pw.println();
+ pw.println("Total PSS by category:");
+ dumpMemItems(pw, " ", catMems);
+ }
}
/**
@@ -9142,6 +9213,7 @@ public final class ActivityManagerService extends ActivityManagerNative
app.notResponding = false;
app.resetPackageList();
+ app.unlinkDeathRecipient();
app.thread = null;
app.forcingToForeground = null;
app.foregroundServices = false;
@@ -9259,7 +9331,6 @@ public final class ActivityManagerService extends ActivityManagerNative
// This app is persistent, so we need to keep its record around.
// If it is not already on the pending app list, add it there
// and start a new process for it.
- app.thread = null;
app.forcingToForeground = null;
app.foregroundServices = false;
if (mPersistentStartingProcesses.indexOf(app) < 0) {
@@ -12327,6 +12398,22 @@ public final class ActivityManagerService extends ActivityManagerNative
return ci;
}
+ public void updatePersistentConfiguration(Configuration values) {
+ enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
+ "updateConfiguration()");
+ enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
+ "updateConfiguration()");
+ if (values == null) {
+ throw new NullPointerException("Configuration must not be null");
+ }
+
+ synchronized(this) {
+ final long origId = Binder.clearCallingIdentity();
+ updateConfigurationLocked(values, null, true);
+ Binder.restoreCallingIdentity(origId);
+ }
+ }
+
public void updateConfiguration(Configuration values) {
enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
"updateConfiguration()");
@@ -12338,7 +12425,10 @@ public final class ActivityManagerService extends ActivityManagerNative
}
final long origId = Binder.clearCallingIdentity();
- updateConfigurationLocked(values, null);
+ if (values != null) {
+ Settings.System.clearConfiguration(values);
+ }
+ updateConfigurationLocked(values, null, false);
Binder.restoreCallingIdentity(origId);
}
}
@@ -12349,9 +12439,10 @@ public final class ActivityManagerService extends ActivityManagerNative
* configuration. Returns true if the activity has been left running, or
* false if <var>starting</var> is being destroyed to match the new
* configuration.
+ * @param persistent TODO
*/
public boolean updateConfigurationLocked(Configuration values,
- ActivityRecord starting) {
+ ActivityRecord starting, boolean persistent) {
int changes = 0;
boolean kept = true;
@@ -12394,7 +12485,7 @@ public final class ActivityManagerService extends ActivityManagerNative
// code is executed.
mSystemThread.applyConfigurationToResources(newConfig);
- if (Settings.System.hasInterestingConfigurationChanges(changes)) {
+ if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
msg.obj = new Configuration(mConfiguration);
mHandler.sendMessage(msg);
diff --git a/services/java/com/android/server/am/ActivityStack.java b/services/java/com/android/server/am/ActivityStack.java
index 93d8164..0d89081 100644
--- a/services/java/com/android/server/am/ActivityStack.java
+++ b/services/java/com/android/server/am/ActivityStack.java
@@ -518,7 +518,7 @@ final class ActivityStack {
Configuration config = mService.mWindowManager.updateOrientationFromAppTokens(
mService.mConfiguration,
r.mayFreezeScreenLocked(app) ? r : null);
- mService.updateConfigurationLocked(config, r);
+ mService.updateConfigurationLocked(config, r, false);
}
r.app = app;
@@ -1424,7 +1424,7 @@ final class ActivityStack {
if (config != null) {
next.frozenBeforeDestroy = true;
}
- updated = mService.updateConfigurationLocked(config, next);
+ updated = mService.updateConfigurationLocked(config, next, false);
}
}
if (!updated) {
@@ -2817,7 +2817,7 @@ final class ActivityStack {
mConfigWillChange = false;
if (DEBUG_CONFIGURATION) Slog.v(TAG,
"Updating to new configuration after starting activity.");
- mService.updateConfigurationLocked(config, null);
+ mService.updateConfigurationLocked(config, null, false);
}
Binder.restoreCallingIdentity(origId);
diff --git a/services/java/com/android/server/am/ProcessRecord.java b/services/java/com/android/server/am/ProcessRecord.java
index 99830f9..9e597aa 100644
--- a/services/java/com/android/server/am/ProcessRecord.java
+++ b/services/java/com/android/server/am/ProcessRecord.java
@@ -73,6 +73,7 @@ class ProcessRecord {
int adjSeq; // Sequence id for identifying oom_adj assignment cycles
int lruSeq; // Sequence id for identifying LRU update cycles
CompatibilityInfo compat; // last used compatibility mode
+ IBinder.DeathRecipient deathRecipient; // Who is watching for the death.
ComponentName instrumentationClass;// class installed to instrument app
ApplicationInfo instrumentationInfo; // the application being instrumented
String instrumentationProfileFile; // where to save profiling
@@ -297,6 +298,13 @@ class ProcessRecord {
}
}
+ public void unlinkDeathRecipient() {
+ if (deathRecipient != null && thread != null) {
+ thread.asBinder().unlinkToDeath(deathRecipient, 0);
+ }
+ deathRecipient = null;
+ }
+
public String toShortString() {
if (shortStringName != null) {
return shortStringName;
diff --git a/services/java/com/android/server/net/NetworkPolicyManagerService.java b/services/java/com/android/server/net/NetworkPolicyManagerService.java
index 0c78fe7..435c394 100644
--- a/services/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -22,6 +22,7 @@ import static android.Manifest.permission.MANAGE_APP_TOKENS;
import static android.Manifest.permission.MANAGE_NETWORK_POLICY;
import static android.Manifest.permission.READ_NETWORK_USAGE_HISTORY;
import static android.Manifest.permission.READ_PHONE_STATE;
+import static android.content.Intent.ACTION_PACKAGE_ADDED;
import static android.content.Intent.ACTION_UID_REMOVED;
import static android.content.Intent.EXTRA_UID;
import static android.net.ConnectivityManager.ACTION_BACKGROUND_DATA_SETTING_CHANGED;
@@ -174,10 +175,12 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
/** Current policy for network templates. */
private ArrayList<NetworkPolicy> mNetworkPolicy = Lists.newArrayList();
+ /** Current derived network rules for ifaces. */
+ private HashMap<NetworkPolicy, String[]> mNetworkRules = Maps.newHashMap();
/** Current policy for each UID. */
private SparseIntArray mUidPolicy = new SparseIntArray();
- /** Current derived network rules for each UID. */
+ /** Current derived rules for each UID. */
private SparseIntArray mUidRules = new SparseIntArray();
/** Set of ifaces that are metered. */
@@ -199,8 +202,6 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
// TODO: keep whitelist of system-critical services that should never have
// rules enforced, such as system, phone, and radio UIDs.
- // TODO: watch for package added broadcast to catch new UIDs.
-
public NetworkPolicyManagerService(Context context, IActivityManager activityManager,
IPowerManager powerManager, INetworkStatsService networkStats,
INetworkManagementService networkManagement) {
@@ -242,7 +243,6 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
synchronized (mRulesLock) {
// read policy from disk
readPolicyLocked();
- updateNotificationsLocked();
}
updateScreenOn();
@@ -268,9 +268,12 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
final IntentFilter connFilter = new IntentFilter(CONNECTIVITY_ACTION);
mContext.registerReceiver(mConnReceiver, connFilter, CONNECTIVITY_INTERNAL, mHandler);
- // listen for uid removal to clean policy
- final IntentFilter removedFilter = new IntentFilter(ACTION_UID_REMOVED);
- mContext.registerReceiver(mRemovedReceiver, removedFilter, null, mHandler);
+ // listen for package/uid changes to update policy
+ final IntentFilter packageFilter = new IntentFilter();
+ packageFilter.addAction(ACTION_PACKAGE_ADDED);
+ packageFilter.addAction(ACTION_UID_REMOVED);
+ packageFilter.addDataScheme("package");
+ mContext.registerReceiver(mPackageReceiver, packageFilter, null, mHandler);
// listen for stats update events
final IntentFilter statsFilter = new IntentFilter(ACTION_NETWORK_STATS_UPDATED);
@@ -331,17 +334,28 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
}
};
- private BroadcastReceiver mRemovedReceiver = new BroadcastReceiver() {
+ private BroadcastReceiver mPackageReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
- // on background handler thread, and UID_REMOVED is protected
- // broadcast.
+ // on background handler thread, and PACKAGE_ADDED and UID_REMOVED
+ // are protected broadcasts.
+
+ final String action = intent.getAction();
final int uid = intent.getIntExtra(EXTRA_UID, 0);
synchronized (mRulesLock) {
- // remove any policy and update rules to clean up
- mUidPolicy.delete(uid);
- updateRulesForUidLocked(uid);
- writePolicyLocked();
+ if (ACTION_PACKAGE_ADDED.equals(action)) {
+ // update rules for UID, since it might be subject to
+ // global background data policy.
+ if (LOGV) Slog.v(TAG, "ACTION_PACKAGE_ADDED for uid=" + uid);
+ updateRulesForUidLocked(uid);
+
+ } else if (ACTION_UID_REMOVED.equals(action)) {
+ // remove any policy and update rules to clean up.
+ if (LOGV) Slog.v(TAG, "ACTION_UID_REMOVED for uid=" + uid);
+ mUidPolicy.delete(uid);
+ updateRulesForUidLocked(uid);
+ writePolicyLocked();
+ }
}
}
};
@@ -396,8 +410,8 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
// TODO: when switching to kernel notifications, compute next future
// cycle boundary to recompute notifications.
- // examine stats for each policy defined
- for (NetworkPolicy policy : mNetworkPolicy) {
+ // examine stats for each active policy
+ for (NetworkPolicy policy : mNetworkRules.keySet()) {
final long start = computeLastCycleBoundary(currentTime, policy);
final long end = currentTime;
@@ -424,6 +438,15 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
cancelNotification(policy, TYPE_WARNING);
}
}
+
+ }
+
+ // clear notifications for non-active policies
+ for (NetworkPolicy policy : mNetworkPolicy) {
+ if (!mNetworkRules.containsKey(policy)) {
+ cancelNotification(policy, TYPE_WARNING);
+ cancelNotification(policy, TYPE_LIMIT);
+ }
}
}
@@ -531,7 +554,8 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
// permission above.
synchronized (mRulesLock) {
ensureActiveMobilePolicyLocked();
- updateIfacesLocked();
+ updateNetworkRulesLocked();
+ updateNotificationsLocked();
}
}
};
@@ -541,7 +565,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
* {@link NetworkPolicy} that need to be enforced. When matches found, set
* remaining quota based on usage cycle and historical stats.
*/
- private void updateIfacesLocked() {
+ private void updateNetworkRulesLocked() {
if (LOGV) Slog.v(TAG, "updateIfacesLocked()");
final NetworkState[] states;
@@ -565,7 +589,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
}
// build list of rules and ifaces to enforce them against
- final HashMap<NetworkPolicy, String[]> rules = Maps.newHashMap();
+ mNetworkRules.clear();
final ArrayList<String> ifaceList = Lists.newArrayList();
for (NetworkPolicy policy : mNetworkPolicy) {
@@ -580,7 +604,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
if (ifaceList.size() > 0) {
final String[] ifaces = ifaceList.toArray(new String[ifaceList.size()]);
- rules.put(policy, ifaces);
+ mNetworkRules.put(policy, ifaces);
}
}
@@ -596,8 +620,8 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
// apply each policy that we found ifaces for; compute remaining data
// based on current cycle and historical stats, and push to kernel.
- for (NetworkPolicy policy : rules.keySet()) {
- final String[] ifaces = rules.get(policy);
+ for (NetworkPolicy policy : mNetworkRules.keySet()) {
+ final String[] ifaces = mNetworkRules.get(policy);
final long start = computeLastCycleBoundary(currentTime, policy);
final long end = currentTime;
@@ -670,17 +694,17 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
if (!mobileDefined) {
Slog.i(TAG, "no policy for active mobile network; generating default policy");
- // default mobile policy has combined 4GB warning, and assume usage
- // cycle starts today today.
+ // build default mobile policy, and assume usage cycle starts today
+ final long warningBytes = mContext.getResources().getInteger(
+ com.android.internal.R.integer.config_networkPolicyDefaultWarning)
+ * MB_IN_BYTES;
- // TODO: move this policy definition to overlay or secure setting
final Time time = new Time(Time.TIMEZONE_UTC);
time.setToNow();
final int cycleDay = time.monthDay;
final NetworkTemplate template = buildTemplateMobileAll(subscriberId);
- mNetworkPolicy.add(
- new NetworkPolicy(template, cycleDay, 4 * GB_IN_BYTES, LIMIT_DISABLED));
+ mNetworkPolicy.add(new NetworkPolicy(template, cycleDay, warningBytes, LIMIT_DISABLED));
writePolicyLocked();
}
}
@@ -859,7 +883,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
mNetworkPolicy.add(policy);
}
- updateIfacesLocked();
+ updateNetworkRulesLocked();
updateNotificationsLocked();
writePolicyLocked();
}
diff --git a/services/java/com/android/server/net/NetworkStatsService.java b/services/java/com/android/server/net/NetworkStatsService.java
index 7ec6b81..6cc01f4 100644
--- a/services/java/com/android/server/net/NetworkStatsService.java
+++ b/services/java/com/android/server/net/NetworkStatsService.java
@@ -60,6 +60,7 @@ import android.os.Environment;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.INetworkManagementService;
+import android.os.PowerManager;
import android.os.RemoteException;
import android.os.SystemClock;
import android.provider.Settings;
@@ -112,6 +113,8 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
private final TrustedTime mTime;
private final NetworkStatsSettings mSettings;
+ private final PowerManager.WakeLock mWakeLock;
+
private IConnectivityManager mConnManager;
// @VisibleForTesting
@@ -191,6 +194,10 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
mTime = checkNotNull(time, "missing TrustedTime");
mSettings = checkNotNull(settings, "missing NetworkStatsSettings");
+ final PowerManager powerManager = (PowerManager) context.getSystemService(
+ Context.POWER_SERVICE);
+ mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
+
mHandlerThread = new HandlerThread(TAG);
mHandlerThread.start();
mHandler = new Handler(mHandlerThread.getLooper());
@@ -408,7 +415,12 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
// on background handler thread, and verified CONNECTIVITY_INTERNAL
// permission above.
synchronized (mStatsLock) {
- updateIfacesLocked();
+ mWakeLock.acquire();
+ try {
+ updateIfacesLocked();
+ } finally {
+ mWakeLock.release();
+ }
}
}
};
@@ -419,8 +431,12 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
// on background handler thread, and verified UPDATE_DEVICE_STATS
// permission above.
synchronized (mStatsLock) {
- // TODO: acquire wakelock while performing poll
- performPollLocked(true, false);
+ mWakeLock.acquire();
+ try {
+ performPollLocked(true, false);
+ } finally {
+ mWakeLock.release();
+ }
}
}
};
@@ -433,7 +449,12 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
final int uid = intent.getIntExtra(EXTRA_UID, 0);
synchronized (mStatsLock) {
// TODO: perform one last stats poll for UID
- removeUidLocked(uid);
+ mWakeLock.acquire();
+ try {
+ removeUidLocked(uid);
+ } finally {
+ mWakeLock.release();
+ }
}
}
};
diff --git a/services/java/com/android/server/pm/Settings.java b/services/java/com/android/server/pm/Settings.java
index 5ed7988..f270003 100644
--- a/services/java/com/android/server/pm/Settings.java
+++ b/services/java/com/android/server/pm/Settings.java
@@ -1093,8 +1093,7 @@ final class Settings {
serializer.attribute(null, "uidError", "true");
}
if (pkg.enabled != COMPONENT_ENABLED_STATE_DEFAULT) {
- serializer.attribute(null, "enabled",
- pkg.enabled == COMPONENT_ENABLED_STATE_ENABLED ? "true" : "false");
+ serializer.attribute(null, "enabled", Integer.toString(pkg.enabled));
}
if (pkg.installStatus == PackageSettingBase.PKG_INSTALL_INCOMPLETE) {
serializer.attribute(null, "installStatus", "false");
@@ -1644,17 +1643,21 @@ final class Settings {
packageSetting.nativeLibraryPathString = nativeLibraryPathStr;
final String enabledStr = parser.getAttributeValue(null, "enabled");
if (enabledStr != null) {
- if (enabledStr.equalsIgnoreCase("true")) {
- packageSetting.enabled = COMPONENT_ENABLED_STATE_ENABLED;
- } else if (enabledStr.equalsIgnoreCase("false")) {
- packageSetting.enabled = COMPONENT_ENABLED_STATE_DISABLED;
- } else if (enabledStr.equalsIgnoreCase("default")) {
- packageSetting.enabled = COMPONENT_ENABLED_STATE_DEFAULT;
- } else {
- PackageManagerService.reportSettingsProblem(Log.WARN,
- "Error in package manager settings: package " + name
- + " has bad enabled value: " + idStr + " at "
- + parser.getPositionDescription());
+ try {
+ packageSetting.enabled = Integer.parseInt(enabledStr);
+ } catch (NumberFormatException e) {
+ if (enabledStr.equalsIgnoreCase("true")) {
+ packageSetting.enabled = COMPONENT_ENABLED_STATE_ENABLED;
+ } else if (enabledStr.equalsIgnoreCase("false")) {
+ packageSetting.enabled = COMPONENT_ENABLED_STATE_DISABLED;
+ } else if (enabledStr.equalsIgnoreCase("default")) {
+ packageSetting.enabled = COMPONENT_ENABLED_STATE_DEFAULT;
+ } else {
+ PackageManagerService.reportSettingsProblem(Log.WARN,
+ "Error in package manager settings: package " + name
+ + " has bad enabled value: " + idStr + " at "
+ + parser.getPositionDescription());
+ }
}
} else {
packageSetting.enabled = COMPONENT_ENABLED_STATE_DEFAULT;
diff --git a/services/java/com/android/server/usb/UsbDeviceManager.java b/services/java/com/android/server/usb/UsbDeviceManager.java
index 3139798..c80cd0a 100644
--- a/services/java/com/android/server/usb/UsbDeviceManager.java
+++ b/services/java/com/android/server/usb/UsbDeviceManager.java
@@ -473,10 +473,7 @@ public class UsbDeviceManager {
case MSG_SET_CURRENT_FUNCTION:
String function = (String)msg.obj;
boolean makeDefault = (msg.arg1 == 1);
- if (makeDefault) {
- if (function == null) {
- throw new NullPointerException();
- }
+ if (function != null && makeDefault) {
if (mAdbEnabled) {
function = addFunction(function, UsbManager.USB_FUNCTION_ADB);
}
diff --git a/services/java/com/android/server/wm/DragState.java b/services/java/com/android/server/wm/DragState.java
index 118cd55..8146fca 100644
--- a/services/java/com/android/server/wm/DragState.java
+++ b/services/java/com/android/server/wm/DragState.java
@@ -51,6 +51,8 @@ class DragState {
float mCurrentX, mCurrentY;
float mThumbOffsetX, mThumbOffsetY;
InputChannel mServerChannel, mClientChannel;
+ InputApplicationHandle mDragApplicationHandle;
+ InputWindowHandle mDragWindowHandle;
WindowState mTargetWindow;
ArrayList<WindowState> mNotifiedWindows;
boolean mDragInProgress;
@@ -91,6 +93,38 @@ class DragState {
mService.mInputManager.registerInputChannel(mServerChannel, null);
InputQueue.registerInputChannel(mClientChannel, mService.mDragInputHandler,
mService.mH.getLooper().getQueue());
+
+ mDragApplicationHandle = new InputApplicationHandle(null);
+ mDragApplicationHandle.name = "drag";
+ mDragApplicationHandle.dispatchingTimeoutNanos =
+ WindowManagerService.DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS;
+
+ mDragWindowHandle = new InputWindowHandle(mDragApplicationHandle, null);
+ mDragWindowHandle.name = "drag";
+ mDragWindowHandle.inputChannel = mServerChannel;
+ mDragWindowHandle.layer = getDragLayerLw();
+ mDragWindowHandle.layoutParamsFlags = 0;
+ mDragWindowHandle.layoutParamsType = WindowManager.LayoutParams.TYPE_DRAG;
+ mDragWindowHandle.dispatchingTimeoutNanos =
+ WindowManagerService.DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS;
+ mDragWindowHandle.visible = true;
+ mDragWindowHandle.canReceiveKeys = false;
+ mDragWindowHandle.hasFocus = true;
+ mDragWindowHandle.hasWallpaper = false;
+ mDragWindowHandle.paused = false;
+ mDragWindowHandle.ownerPid = Process.myPid();
+ mDragWindowHandle.ownerUid = Process.myUid();
+ mDragWindowHandle.inputFeatures = 0;
+ mDragWindowHandle.scaleFactor = 1.0f;
+
+ // The drag window cannot receive new touches.
+ mDragWindowHandle.touchableRegion.setEmpty();
+
+ // The drag window covers the entire display
+ mDragWindowHandle.frameLeft = 0;
+ mDragWindowHandle.frameTop = 0;
+ mDragWindowHandle.frameRight = mService.mDisplay.getRealWidth();
+ mDragWindowHandle.frameBottom = mService.mDisplay.getRealHeight();
}
}
diff --git a/services/java/com/android/server/wm/InputMonitor.java b/services/java/com/android/server/wm/InputMonitor.java
index 08a3560..12ef238 100644
--- a/services/java/com/android/server/wm/InputMonitor.java
+++ b/services/java/com/android/server/wm/InputMonitor.java
@@ -42,10 +42,6 @@ final class InputMonitor {
// When true, need to call updateInputWindowsLw().
private boolean mUpdateInputWindowsNeeded = true;
- // Fake handles for the drag surface, lazily initialized.
- private InputApplicationHandle mDragApplicationHandle;
- private InputWindowHandle mDragWindowHandle;
-
// Array of window handles to provide to the input dispatcher.
private InputWindowHandle[] mInputWindowHandles;
private int mInputWindowHandleCount;
@@ -121,44 +117,6 @@ final class InputMonitor {
return 0; // abort dispatching
}
- private void addDragInputWindowLw() {
- if (mDragWindowHandle == null) {
- mDragApplicationHandle = new InputApplicationHandle(null);
- mDragApplicationHandle.name = "drag";
- mDragApplicationHandle.dispatchingTimeoutNanos =
- WindowManagerService.DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS;
-
- mDragWindowHandle = new InputWindowHandle(mDragApplicationHandle, null);
- mDragWindowHandle.name = "drag";
- mDragWindowHandle.layoutParamsFlags = 0;
- mDragWindowHandle.layoutParamsType = WindowManager.LayoutParams.TYPE_DRAG;
- mDragWindowHandle.dispatchingTimeoutNanos =
- WindowManagerService.DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS;
- mDragWindowHandle.visible = true;
- mDragWindowHandle.canReceiveKeys = false;
- mDragWindowHandle.hasFocus = true;
- mDragWindowHandle.hasWallpaper = false;
- mDragWindowHandle.paused = false;
- mDragWindowHandle.ownerPid = Process.myPid();
- mDragWindowHandle.ownerUid = Process.myUid();
- mDragWindowHandle.inputFeatures = 0;
- mDragWindowHandle.scaleFactor = 1.0f;
-
- // The drag window cannot receive new touches.
- mDragWindowHandle.touchableRegion.setEmpty();
- }
-
- mDragWindowHandle.layer = mService.mDragState.getDragLayerLw();
-
- // The drag window covers the entire display
- mDragWindowHandle.frameLeft = 0;
- mDragWindowHandle.frameTop = 0;
- mDragWindowHandle.frameRight = mService.mDisplay.getRealWidth();
- mDragWindowHandle.frameBottom = mService.mDisplay.getRealHeight();
-
- addInputWindowHandleLw(mDragWindowHandle);
- }
-
private void addInputWindowHandleLw(InputWindowHandle windowHandle) {
if (mInputWindowHandles == null) {
mInputWindowHandles = new InputWindowHandle[16];
@@ -202,7 +160,7 @@ final class InputMonitor {
if (WindowManagerService.DEBUG_DRAG) {
Log.d(WindowManagerService.TAG, "Inserting drag window");
}
- addDragInputWindowLw();
+ addInputWindowHandleLw(mService.mDragState.mDragWindowHandle);
}
final int N = windows.size();
@@ -429,4 +387,4 @@ final class InputMonitor {
private void updateInputDispatchModeLw() {
mService.mInputManager.setInputDispatchMode(mInputDispatchEnabled, mInputDispatchFrozen);
}
-} \ No newline at end of file
+}