diff options
Diffstat (limited to 'services/java/com')
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 +} |