diff options
Diffstat (limited to 'services')
26 files changed, 800 insertions, 655 deletions
diff --git a/services/audioflinger/AudioResamplerCubic.cpp b/services/audioflinger/AudioResamplerCubic.cpp index 1d247bd..4d721f6 100644 --- a/services/audioflinger/AudioResamplerCubic.cpp +++ b/services/audioflinger/AudioResamplerCubic.cpp @@ -14,6 +14,8 @@ * limitations under the License. */ +#define LOG_TAG "AudioSRC" + #include <stdint.h> #include <string.h> #include <sys/types.h> @@ -22,8 +24,6 @@ #include "AudioResampler.h" #include "AudioResamplerCubic.h" -#define LOG_TAG "AudioSRC" - namespace android { // ---------------------------------------------------------------------------- diff --git a/services/camera/libcameraservice/CameraHardwareStub.h b/services/camera/libcameraservice/CameraHardwareStub.h index 9b66a76..c6d8756 100644 --- a/services/camera/libcameraservice/CameraHardwareStub.h +++ b/services/camera/libcameraservice/CameraHardwareStub.h @@ -73,14 +73,7 @@ private: CameraHardwareStub* mHardware; public: PreviewThread(CameraHardwareStub* hw) : -#ifdef SINGLE_PROCESS - // In single process mode this thread needs to be a java thread, - // since we won't be calling through the binder. - Thread(true), -#else - Thread(false), -#endif - mHardware(hw) { } + Thread(false), mHardware(hw) { } virtual void onFirstRef() { run("CameraPreviewThread", PRIORITY_URGENT_DISPLAY); } diff --git a/services/input/InputDispatcher.cpp b/services/input/InputDispatcher.cpp index 10b9083..da9b55c 100644 --- a/services/input/InputDispatcher.cpp +++ b/services/input/InputDispatcher.cpp @@ -3154,11 +3154,9 @@ void InputDispatcher::setInputWindows(const Vector<InputWindow>& inputWindows) { mLastHoverWindow = NULL; } - mWindows.clear(); - // Loop over new windows and rebuild the necessary window pointers for // tracking focus and touch. - mWindows.appendVector(inputWindows); + mWindows = inputWindows; size_t numWindows = mWindows.size(); for (size_t i = 0; i < numWindows; i++) { @@ -4560,8 +4558,7 @@ void InputDispatcher::TouchState::copyFrom(const TouchState& other) { split = other.split; deviceId = other.deviceId; source = other.source; - windows.clear(); - windows.appendVector(other.windows); + windows = other.windows; } void InputDispatcher::TouchState::addOrUpdateWindow(const InputWindow* window, diff --git a/services/java/com/android/server/AppWidgetService.java b/services/java/com/android/server/AppWidgetService.java index 158c778..0b15221 100644 --- a/services/java/com/android/server/AppWidgetService.java +++ b/services/java/com/android/server/AppWidgetService.java @@ -1072,7 +1072,7 @@ class AppWidgetService extends IAppWidgetService.Stub throw new IllegalArgumentException("packageName and uid don't match packageName=" + packageName); } - if (callingUid != packageUid && Process.supportsProcesses()) { + if (callingUid != packageUid) { throw new IllegalArgumentException("packageName and uid don't match packageName=" + packageName); } diff --git a/services/java/com/android/server/BackupManagerService.java b/services/java/com/android/server/BackupManagerService.java index 6afccec..786f2fa 100644 --- a/services/java/com/android/server/BackupManagerService.java +++ b/services/java/com/android/server/BackupManagerService.java @@ -224,6 +224,7 @@ class BackupManagerService extends IBackupManager.Stub { public PackageInfo pkgInfo; public int pmToken; // in post-install restore, the PM's token for this transaction public boolean needFullBackup; + public String[] filterSet; RestoreParams(IBackupTransport _transport, IRestoreObserver _obs, long _token, PackageInfo _pkg, int _pmToken, boolean _needFullBackup) { @@ -233,6 +234,7 @@ class BackupManagerService extends IBackupManager.Stub { pkgInfo = _pkg; pmToken = _pmToken; needFullBackup = _needFullBackup; + filterSet = null; } RestoreParams(IBackupTransport _transport, IRestoreObserver _obs, long _token, @@ -243,6 +245,18 @@ class BackupManagerService extends IBackupManager.Stub { pkgInfo = null; pmToken = 0; needFullBackup = _needFullBackup; + filterSet = null; + } + + RestoreParams(IBackupTransport _transport, IRestoreObserver _obs, long _token, + String[] _filterSet, boolean _needFullBackup) { + transport = _transport; + observer = _obs; + token = _token; + pkgInfo = null; + pmToken = 0; + needFullBackup = _needFullBackup; + filterSet = _filterSet; } } @@ -404,7 +418,7 @@ class BackupManagerService extends IBackupManager.Stub { Slog.d(TAG, "MSG_RUN_RESTORE observer=" + params.observer); (new PerformRestoreTask(params.transport, params.observer, params.token, params.pkgInfo, params.pmToken, - params.needFullBackup)).run(); + params.needFullBackup, params.filterSet)).run(); break; } @@ -3020,6 +3034,7 @@ class BackupManagerService extends IBackupManager.Stub { private File mStateDir; private int mPmToken; private boolean mNeedFullBackup; + private HashSet<String> mFilterSet; class RestoreRequest { public PackageInfo app; @@ -3033,7 +3048,7 @@ class BackupManagerService extends IBackupManager.Stub { PerformRestoreTask(IBackupTransport transport, IRestoreObserver observer, long restoreSetToken, PackageInfo targetPackage, int pmToken, - boolean needFullBackup) { + boolean needFullBackup, String[] filterSet) { mTransport = transport; mObserver = observer; mToken = restoreSetToken; @@ -3041,6 +3056,15 @@ class BackupManagerService extends IBackupManager.Stub { mPmToken = pmToken; mNeedFullBackup = needFullBackup; + if (filterSet != null) { + mFilterSet = new HashSet<String>(); + for (String pkg : filterSet) { + mFilterSet.add(pkg); + } + } else { + mFilterSet = null; + } + try { mStateDir = new File(mBaseStateDir, transport.transportDirName()); } catch (RemoteException e) { @@ -3052,7 +3076,8 @@ class BackupManagerService extends IBackupManager.Stub { long startRealtime = SystemClock.elapsedRealtime(); if (DEBUG) Slog.v(TAG, "Beginning restore process mTransport=" + mTransport + " mObserver=" + mObserver + " mToken=" + Long.toHexString(mToken) - + " mTargetPackage=" + mTargetPackage + " mPmToken=" + mPmToken); + + " mTargetPackage=" + mTargetPackage + " mFilterSet=" + mFilterSet + + " mPmToken=" + mPmToken); PackageManagerBackupAgent pmAgent = null; int error = -1; // assume error @@ -3071,6 +3096,22 @@ class BackupManagerService extends IBackupManager.Stub { List<PackageInfo> agentPackages = allAgentPackages(); if (mTargetPackage == null) { + // if there's a filter set, strip out anything that isn't + // present before proceeding + if (mFilterSet != null) { + for (int i = agentPackages.size() - 1; i >= 0; i--) { + final PackageInfo pkg = agentPackages.get(i); + if (! mFilterSet.contains(pkg.packageName)) { + agentPackages.remove(i); + } + } + if (DEBUG) { + Slog.i(TAG, "Post-filter package set for restore:"); + for (PackageInfo p : agentPackages) { + Slog.i(TAG, " " + p); + } + } + } restorePackages.addAll(agentPackages); } else { // Just one package to attempt restore of @@ -4266,6 +4307,67 @@ class BackupManagerService extends IBackupManager.Stub { return -1; } + public synchronized int restoreSome(long token, IRestoreObserver observer, + String[] packages) { + mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP, + "performRestore"); + + if (DEBUG) { + StringBuilder b = new StringBuilder(128); + b.append("restoreSome token="); + b.append(Long.toHexString(token)); + b.append(" observer="); + b.append(observer.toString()); + b.append(" packages="); + if (packages == null) { + b.append("null"); + } else { + b.append('{'); + boolean first = true; + for (String s : packages) { + if (!first) { + b.append(", "); + } else first = false; + b.append(s); + } + b.append('}'); + } + Slog.d(TAG, b.toString()); + } + + if (mEnded) { + throw new IllegalStateException("Restore session already ended"); + } + + if (mRestoreTransport == null || mRestoreSets == null) { + Slog.e(TAG, "Ignoring restoreAll() with no restore set"); + return -1; + } + + if (mPackageName != null) { + Slog.e(TAG, "Ignoring restoreAll() on single-package session"); + return -1; + } + + synchronized (mQueueLock) { + for (int i = 0; i < mRestoreSets.length; i++) { + if (token == mRestoreSets[i].token) { + long oldId = Binder.clearCallingIdentity(); + mWakelock.acquire(); + Message msg = mBackupHandler.obtainMessage(MSG_RUN_RESTORE); + msg.obj = new RestoreParams(mRestoreTransport, observer, token, + packages, true); + mBackupHandler.sendMessage(msg); + Binder.restoreCallingIdentity(oldId); + return 0; + } + } + } + + Slog.w(TAG, "Restore token " + Long.toHexString(token) + " not found"); + return -1; + } + public synchronized int restorePackage(String packageName, IRestoreObserver observer) { if (DEBUG) Slog.v(TAG, "restorePackage pkg=" + packageName + " obs=" + observer); diff --git a/services/java/com/android/server/ConnectivityService.java b/services/java/com/android/server/ConnectivityService.java index b98d2a2..41450d2 100644 --- a/services/java/com/android/server/ConnectivityService.java +++ b/services/java/com/android/server/ConnectivityService.java @@ -1602,8 +1602,10 @@ public class ConnectivityService extends IConnectivityManager.Stub { if (linkProperties != null) { String iface = linkProperties.getInterfaceName(); if (TextUtils.isEmpty(iface) == false) { - if (DBG) log("resetConnections(" + iface + ")"); - NetworkUtils.resetConnections(iface); + if (DBG) { + log("resetConnections(" + iface + ", NetworkUtils.RESET_ALL_ADDRESSES)"); + } + NetworkUtils.resetConnections(iface, NetworkUtils.RESET_ALL_ADDRESSES); } } } diff --git a/services/java/com/android/server/InputMethodManagerService.java b/services/java/com/android/server/InputMethodManagerService.java index 2d55433..18d393f 100644 --- a/services/java/com/android/server/InputMethodManagerService.java +++ b/services/java/com/android/server/InputMethodManagerService.java @@ -531,10 +531,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub mImeSwitcherNotification.sound = null; mImeSwitcherNotification.vibrate = null; Intent intent = new Intent(Settings.ACTION_SHOW_INPUT_METHOD_PICKER); - intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK - | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED - | Intent.FLAG_ACTIVITY_CLEAR_TOP); - mImeSwitchPendingIntent = PendingIntent.getActivity(mContext, 0, intent, 0); + mImeSwitchPendingIntent = PendingIntent.getBroadcast(mContext, 0, intent, 0); mShowOngoingImeSwitcherForPhones = mRes.getBoolean( com.android.internal.R.bool.show_ongoing_ime_switcher); diff --git a/services/java/com/android/server/MountService.java b/services/java/com/android/server/MountService.java index 54e5432..2e54c99 100644 --- a/services/java/com/android/server/MountService.java +++ b/services/java/com/android/server/MountService.java @@ -1075,18 +1075,22 @@ class MountService extends IMountService.Stub implements INativeDaemonConnectorC com.android.internal.R.styleable.Storage_mtpReserve, 0); boolean allowMassStorage = a.getBoolean( com.android.internal.R.styleable.Storage_allowMassStorage, false); + // resource parser does not support longs, so XML value is in megabytes + long maxFileSize = a.getInt( + com.android.internal.R.styleable.Storage_maxFileSize, 0) * 1024L * 1024L; Slog.d(TAG, "got storage path: " + path + " description: " + description + " primary: " + primary + " removable: " + removable + " emulated: " + emulated + " mtpReserve: " + mtpReserve + - " allowMassStorage: " + allowMassStorage); + " allowMassStorage: " + allowMassStorage + + " maxFileSize: " + maxFileSize); if (path == null || description == null) { Slog.e(TAG, "path or description is null in readStorageList"); } else { String pathString = path.toString(); StorageVolume volume = new StorageVolume(pathString, description.toString(), removable, emulated, - mtpReserve, allowMassStorage); + mtpReserve, allowMassStorage, maxFileSize); if (primary) { if (mPrimaryVolume == null) { mPrimaryVolume = volume; diff --git a/services/java/com/android/server/NetworkManagementService.java b/services/java/com/android/server/NetworkManagementService.java index da1bf83..829df39 100644 --- a/services/java/com/android/server/NetworkManagementService.java +++ b/services/java/com/android/server/NetworkManagementService.java @@ -77,11 +77,15 @@ class NetworkManagementService extends INetworkManagementService.Stub { /** Path to {@code /proc/uid_stat}. */ @Deprecated - private final File mProcStatsUidstat; + private final File mStatsUid; + /** Path to {@code /proc/net/dev}. */ + private final File mStatsIface; /** Path to {@code /proc/net/xt_qtaguid/stats}. */ - private final File mProcStatsNetfilter; + private final File mStatsXtUid; + /** Path to {@code /proc/net/xt_qtaguid/iface_stat}. */ + private final File mStatsXtIface; - /** {@link #mProcStatsNetfilter} headers. */ + /** {@link #mStatsXtUid} headers. */ private static final String KEY_IFACE = "iface"; private static final String KEY_TAG_HEX = "acct_tag_hex"; private static final String KEY_UID = "uid_tag_int"; @@ -137,8 +141,10 @@ class NetworkManagementService extends INetworkManagementService.Stub { mContext = context; mObservers = new ArrayList<INetworkManagementEventObserver>(); - mProcStatsUidstat = new File(procRoot, "uid_stat"); - mProcStatsNetfilter = new File(procRoot, "net/xt_qtaguid/stats"); + mStatsUid = new File(procRoot, "uid_stat"); + mStatsIface = new File(procRoot, "net/dev"); + mStatsXtUid = new File(procRoot, "net/xt_qtaguid/stats"); + mStatsXtIface = new File(procRoot, "net/xt_qtaguid/iface_stat"); if ("simulator".equals(SystemProperties.get("ro.product.device"))) { return; @@ -161,9 +167,12 @@ class NetworkManagementService extends INetworkManagementService.Stub { } // @VisibleForTesting - public static NetworkManagementService createForTest(Context context, File procRoot) { + public static NetworkManagementService createForTest( + Context context, File procRoot, boolean bandwidthControlEnabled) { // TODO: eventually connect with mock netd - return new NetworkManagementService(context, procRoot); + final NetworkManagementService service = new NetworkManagementService(context, procRoot); + service.mBandwidthControlEnabled = bandwidthControlEnabled; + return service; } public void systemReady() { @@ -930,13 +939,68 @@ class NetworkManagementService extends INetworkManagementService.Stub { mContext.enforceCallingOrSelfPermission( android.Manifest.permission.ACCESS_NETWORK_STATE, "NetworkManagementService"); - final String[] ifaces = listInterfaces(); - final NetworkStats stats = new NetworkStats(SystemClock.elapsedRealtime(), ifaces.length); + final NetworkStats stats = new NetworkStats(SystemClock.elapsedRealtime(), 6); + final NetworkStats.Entry entry = new NetworkStats.Entry(); + + final HashSet<String> activeIfaces = Sets.newHashSet(); + final ArrayList<String> values = Lists.newArrayList(); + + BufferedReader reader = null; + try { + reader = new BufferedReader(new FileReader(mStatsIface)); + + // skip first two header lines + reader.readLine(); + reader.readLine(); + + // parse remaining lines + String line; + while ((line = reader.readLine()) != null) { + splitLine(line, values); + + try { + entry.iface = values.get(0); + entry.uid = UID_ALL; + entry.tag = TAG_NONE; + entry.rxBytes = Long.parseLong(values.get(1)); + entry.rxPackets = Long.parseLong(values.get(2)); + entry.txBytes = Long.parseLong(values.get(9)); + entry.txPackets = Long.parseLong(values.get(10)); + + activeIfaces.add(entry.iface); + stats.addValues(entry); + } catch (NumberFormatException e) { + Slog.w(TAG, "problem parsing stats row '" + line + "': " + e); + } + } + } catch (IOException e) { + Slog.w(TAG, "problem parsing stats: " + e); + } finally { + IoUtils.closeQuietly(reader); + } + + if (DBG) Slog.d(TAG, "recorded active stats from " + activeIfaces); + + // splice in stats from any disabled ifaces + if (mBandwidthControlEnabled) { + final HashSet<String> xtIfaces = Sets.newHashSet(fileListWithoutNull(mStatsXtIface)); + xtIfaces.removeAll(activeIfaces); + + for (String iface : xtIfaces) { + final File ifacePath = new File(mStatsXtIface, iface); + + entry.iface = iface; + entry.uid = UID_ALL; + entry.tag = TAG_NONE; + entry.rxBytes = readSingleLongFromFile(new File(ifacePath, "rx_bytes")); + entry.rxPackets = readSingleLongFromFile(new File(ifacePath, "rx_packets")); + entry.txBytes = readSingleLongFromFile(new File(ifacePath, "tx_bytes")); + entry.txPackets = readSingleLongFromFile(new File(ifacePath, "tx_packets")); - for (String iface : ifaces) { - final long rx = getInterfaceCounter(iface, true); - final long tx = getInterfaceCounter(iface, false); - stats.addEntry(iface, UID_ALL, TAG_NONE, rx, tx); + stats.addValues(entry); + } + + if (DBG) Slog.d(TAG, "recorded stale stats from " + xtIfaces); } return stats; @@ -1063,13 +1127,15 @@ class NetworkManagementService extends INetworkManagementService.Stub { */ private NetworkStats getNetworkStatsDetailNetfilter(int limitUid) { final NetworkStats stats = new NetworkStats(SystemClock.elapsedRealtime(), 24); + final NetworkStats.Entry entry = new NetworkStats.Entry(); + final ArrayList<String> keys = Lists.newArrayList(); final ArrayList<String> values = Lists.newArrayList(); final HashMap<String, String> parsed = Maps.newHashMap(); BufferedReader reader = null; try { - reader = new BufferedReader(new FileReader(mProcStatsNetfilter)); + reader = new BufferedReader(new FileReader(mStatsXtUid)); // parse first line as header String line = reader.readLine(); @@ -1081,15 +1147,16 @@ class NetworkManagementService extends INetworkManagementService.Stub { parseLine(keys, values, parsed); try { - final String iface = parsed.get(KEY_IFACE); - final int tag = NetworkManagementSocketTagger.kernelToTag( + // TODO: add rxPackets/txPackets once kernel exports + entry.iface = parsed.get(KEY_IFACE); + entry.tag = NetworkManagementSocketTagger.kernelToTag( parsed.get(KEY_TAG_HEX)); - final int uid = Integer.parseInt(parsed.get(KEY_UID)); - final long rx = Long.parseLong(parsed.get(KEY_RX)); - final long tx = Long.parseLong(parsed.get(KEY_TX)); + entry.uid = Integer.parseInt(parsed.get(KEY_UID)); + entry.rxBytes = Long.parseLong(parsed.get(KEY_RX)); + entry.txBytes = Long.parseLong(parsed.get(KEY_TX)); - if (limitUid == UID_ALL || limitUid == uid) { - stats.addEntry(iface, uid, tag, rx, tx); + if (limitUid == UID_ALL || limitUid == entry.uid) { + stats.addValues(entry); } } catch (NumberFormatException e) { Slog.w(TAG, "problem parsing stats row '" + line + "': " + e); @@ -1114,19 +1181,27 @@ class NetworkManagementService extends INetworkManagementService.Stub { private NetworkStats getNetworkStatsDetailUidstat(int limitUid) { final String[] knownUids; if (limitUid == UID_ALL) { - knownUids = mProcStatsUidstat.list(); + knownUids = fileListWithoutNull(mStatsUid); } else { knownUids = new String[] { String.valueOf(limitUid) }; } final NetworkStats stats = new NetworkStats( SystemClock.elapsedRealtime(), knownUids.length); + final NetworkStats.Entry entry = new NetworkStats.Entry(); for (String uid : knownUids) { final int uidInt = Integer.parseInt(uid); - final File uidPath = new File(mProcStatsUidstat, uid); - final long rx = readSingleLongFromFile(new File(uidPath, "tcp_rcv")); - final long tx = readSingleLongFromFile(new File(uidPath, "tcp_snd")); - stats.addEntry(IFACE_ALL, uidInt, TAG_NONE, rx, tx); + final File uidPath = new File(mStatsUid, uid); + + entry.iface = IFACE_ALL; + entry.uid = uidInt; + entry.tag = TAG_NONE; + entry.rxBytes = readSingleLongFromFile(new File(uidPath, "tcp_rcv")); + entry.rxPackets = readSingleLongFromFile(new File(uidPath, "tcp_rcv_pkt")); + entry.txBytes = readSingleLongFromFile(new File(uidPath, "tcp_snd")); + entry.txPackets = readSingleLongFromFile(new File(uidPath, "tcp_snd_pkt")); + + stats.addValues(entry); } return stats; @@ -1197,7 +1272,7 @@ class NetworkManagementService extends INetworkManagementService.Stub { private static void splitLine(String line, ArrayList<String> outSplit) { outSplit.clear(); - final StringTokenizer t = new StringTokenizer(line); + final StringTokenizer t = new StringTokenizer(line, " \t\n\r\f:"); while (t.hasMoreTokens()) { outSplit.add(t.nextToken()); } @@ -1232,6 +1307,15 @@ class NetworkManagementService extends INetworkManagementService.Stub { } } + /** + * Wrapper for {@link File#list()} that returns empty array instead of + * {@code null}. + */ + private static String[] fileListWithoutNull(File file) { + final String[] list = file.list(); + return list != null ? list : new String[0]; + } + public void setDefaultInterfaceForDns(String iface) throws IllegalStateException { mContext.enforceCallingOrSelfPermission( android.Manifest.permission.CHANGE_NETWORK_STATE, "NetworkManagementService"); diff --git a/services/java/com/android/server/NetworkTimeUpdateService.java b/services/java/com/android/server/NetworkTimeUpdateService.java index 15f22c0..f7fe39e 100644 --- a/services/java/com/android/server/NetworkTimeUpdateService.java +++ b/services/java/com/android/server/NetworkTimeUpdateService.java @@ -16,8 +16,6 @@ package com.android.server; -import com.android.internal.telephony.TelephonyIntents; - import android.app.AlarmManager; import android.app.PendingIntent; import android.content.BroadcastReceiver; @@ -28,7 +26,6 @@ import android.content.IntentFilter; import android.database.ContentObserver; import android.net.ConnectivityManager; import android.net.NetworkInfo; -import android.net.SntpClient; import android.os.Handler; import android.os.HandlerThread; import android.os.Looper; @@ -36,12 +33,10 @@ import android.os.Message; import android.os.SystemClock; import android.provider.Settings; import android.util.Log; -import android.util.Slog; +import android.util.NtpTrustedTime; +import android.util.TrustedTime; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.util.Properties; +import com.android.internal.telephony.TelephonyIntents; /** * Monitors the network time and updates the system time if it is out of sync @@ -68,14 +63,11 @@ public class NetworkTimeUpdateService { private static final long POLLING_INTERVAL_SHORTER_MS = 60 * 1000L; // 60 seconds /** Number of times to try again */ private static final int TRY_AGAIN_TIMES_MAX = 3; - /** How long to wait for the NTP server to respond. */ - private static final int MAX_NTP_FETCH_WAIT_MS = 20 * 1000; /** If the time difference is greater than this threshold, then update the time. */ private static final int TIME_ERROR_THRESHOLD_MS = 5 * 1000; private static final String ACTION_POLL = "com.android.server.NetworkTimeUpdateService.action.POLL"; - private static final String PROPERTIES_FILE = "/etc/gps.conf"; private static int POLL_REQUEST = 0; private static final long NOT_SET = -1; @@ -84,14 +76,14 @@ public class NetworkTimeUpdateService { private long mNitzZoneSetTime = NOT_SET; private Context mContext; + private TrustedTime mTime; + // NTP lookup is done on this thread and handler private Handler mHandler; private HandlerThread mThread; private AlarmManager mAlarmManager; private PendingIntent mPendingPollIntent; private SettingsObserver mSettingsObserver; - // Address of the NTP server - private String mNtpServer; // The last time that we successfully fetched the NTP time. private long mLastNtpFetchTime = NOT_SET; // Keeps track of how many quick attempts were made to fetch NTP time. @@ -101,6 +93,7 @@ public class NetworkTimeUpdateService { public NetworkTimeUpdateService(Context context) { mContext = context; + mTime = NtpTrustedTime.getInstance(context); mAlarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE); Intent pollIntent = new Intent(ACTION_POLL, null); mPendingPollIntent = PendingIntent.getBroadcast(mContext, POLL_REQUEST, pollIntent, 0); @@ -108,12 +101,6 @@ public class NetworkTimeUpdateService { /** Initialize the receivers and initiate the first NTP request */ public void systemReady() { - mNtpServer = getNtpServerAddress(); - if (mNtpServer == null) { - Slog.e(TAG, "NTP server address not found, not syncing to NTP time"); - return; - } - registerForTelephonyIntents(); registerForAlarms(); registerForConnectivityIntents(); @@ -128,27 +115,6 @@ public class NetworkTimeUpdateService { mSettingsObserver.observe(mContext); } - private String getNtpServerAddress() { - String serverAddress = null; - FileInputStream stream = null; - try { - Properties properties = new Properties(); - File file = new File(PROPERTIES_FILE); - stream = new FileInputStream(file); - properties.load(stream); - serverAddress = properties.getProperty("NTP_SERVER", null); - } catch (IOException e) { - Slog.e(TAG, "Could not open GPS configuration file " + PROPERTIES_FILE); - } finally { - if (stream != null) { - try { - stream.close(); - } catch (Exception e) {} - } - } - return serverAddress; - } - private void registerForTelephonyIntents() { IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction(TelephonyIntents.ACTION_NETWORK_SET_TIME); @@ -189,9 +155,15 @@ public class NetworkTimeUpdateService { if (mLastNtpFetchTime == NOT_SET || refTime >= mLastNtpFetchTime + POLLING_INTERVAL_MS || event == EVENT_AUTO_TIME_CHANGED) { if (DBG) Log.d(TAG, "Before Ntp fetch"); - long ntp = getNtpTime(); - if (DBG) Log.d(TAG, "Ntp = " + ntp); - if (ntp > 0) { + + // force refresh NTP cache when outdated + if (mTime.getCacheAge() >= POLLING_INTERVAL_MS) { + mTime.forceRefresh(); + } + + // only update when NTP time is fresh + if (mTime.getCacheAge() < POLLING_INTERVAL_MS) { + final long ntp = mTime.currentTimeMillis(); mTryAgainCounter = 0; mLastNtpFetchTime = SystemClock.elapsedRealtime(); if (Math.abs(ntp - currentTime) > TIME_ERROR_THRESHOLD_MS) { @@ -232,15 +204,6 @@ public class NetworkTimeUpdateService { mAlarmManager.set(AlarmManager.ELAPSED_REALTIME, next, mPendingPollIntent); } - private long getNtpTime() { - SntpClient client = new SntpClient(); - if (client.requestTime(mNtpServer, MAX_NTP_FETCH_WAIT_MS)) { - return client.getNtpTime(); - } else { - return 0; - } - } - /** * Checks if the user prefers to automatically set the time. */ diff --git a/services/java/com/android/server/ThrottleService.java b/services/java/com/android/server/ThrottleService.java index d81dfdb..24d4dd3 100644 --- a/services/java/com/android/server/ThrottleService.java +++ b/services/java/com/android/server/ThrottleService.java @@ -16,9 +16,6 @@ package com.android.server; -import com.android.internal.R; -import com.android.internal.telephony.TelephonyProperties; - import android.app.AlarmManager; import android.app.Notification; import android.app.NotificationManager; @@ -54,6 +51,9 @@ import android.util.NtpTrustedTime; import android.util.Slog; import android.util.TrustedTime; +import com.android.internal.R; +import com.android.internal.telephony.TelephonyProperties; + import java.io.BufferedWriter; import java.io.File; import java.io.FileDescriptor; @@ -63,7 +63,6 @@ import java.io.IOException; import java.io.PrintWriter; import java.util.Calendar; import java.util.GregorianCalendar; -import java.util.Properties; import java.util.Random; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicLong; @@ -87,7 +86,6 @@ public class ThrottleService extends IThrottleManager.Stub { private static final long TESTING_THRESHOLD = 1 * 1024 * 1024; private static final long MAX_NTP_CACHE_AGE = 24 * 60 * 60 * 1000; - private static final long MAX_NTP_FETCH_WAIT = 20 * 1000; private long mMaxNtpCacheAge = MAX_NTP_CACHE_AGE; @@ -127,8 +125,6 @@ public class ThrottleService extends IThrottleManager.Stub { private static final int THROTTLE_INDEX_UNINITIALIZED = -1; private static final int THROTTLE_INDEX_UNTHROTTLED = 0; - private static final String PROPERTIES_FILE = "/etc/gps.conf"; - private Intent mPollStickyBroadcast; private TrustedTime mTime; @@ -139,8 +135,7 @@ public class ThrottleService extends IThrottleManager.Stub { } public ThrottleService(Context context) { - // TODO: move to using cached NtpTrustedTime - this(context, getNetworkManagementService(), new NtpTrustedTime(), + this(context, getNetworkManagementService(), NtpTrustedTime.getInstance(context), context.getResources().getString(R.string.config_datause_iface)); } @@ -341,26 +336,6 @@ public class ThrottleService extends IThrottleManager.Stub { } }, new IntentFilter(ACTION_RESET)); - FileInputStream stream = null; - try { - Properties properties = new Properties(); - File file = new File(PROPERTIES_FILE); - stream = new FileInputStream(file); - properties.load(stream); - final String ntpServer = properties.getProperty("NTP_SERVER", null); - if (mTime instanceof NtpTrustedTime) { - ((NtpTrustedTime) mTime).setNtpServer(ntpServer, MAX_NTP_FETCH_WAIT); - } - } catch (IOException e) { - Slog.e(TAG, "Could not open GPS configuration file " + PROPERTIES_FILE); - } finally { - if (stream != null) { - try { - stream.close(); - } catch (Exception e) {} - } - } - // use a new thread as we don't want to stall the system for file writes mThread = new HandlerThread(TAG); mThread.start(); diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java index 29cccb6..8501163 100644 --- a/services/java/com/android/server/am/ActivityManagerService.java +++ b/services/java/com/android/server/am/ActivityManagerService.java @@ -208,6 +208,12 @@ public final class ActivityManagerService extends ActivityManagerNative // before we decide it's never going to come up for real. static final int PROC_START_TIMEOUT = 10*1000; + // How long we wait for a launched process to attach to the activity manager + // before we decide it's never going to come up for real, when the process was + // started with a wrapper for instrumentation (such as Valgrind) because it + // could take much longer than usual. + static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000; + // How long to wait after going idle before forcing apps to GC. static final int GC_TIMEOUT = 5*1000; @@ -502,15 +508,6 @@ public final class ActivityManagerService extends ActivityManagerNative = new ArrayList<ProcessRecord>(); /** - * List of records for processes that we have started and are waiting - * for them to call back. This is really only needed when running in - * single processes mode, in which case we do not have a unique pid for - * each process. - */ - final ArrayList<ProcessRecord> mStartingProcesses - = new ArrayList<ProcessRecord>(); - - /** * List of persistent applications that are in the process * of being started. */ @@ -1959,8 +1956,13 @@ public final class ActivityManagerService extends ActivityManagerNative if ("1".equals(SystemProperties.get("debug.assert"))) { debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; } - int pid = Process.start("android.app.ActivityThread", - app.processName, uid, uid, gids, debugFlags, null); + + // Start the process. It will either succeed and return a result containing + // the PID of the new process, or else throw a RuntimeException. + Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread", + app.processName, uid, uid, gids, debugFlags, + app.info.targetSdkVersion, null); + BatteryStatsImpl bs = app.batteryStats.getBatteryStats(); synchronized (bs) { if (bs.isOnBattery()) { @@ -1968,12 +1970,12 @@ public final class ActivityManagerService extends ActivityManagerNative } } - EventLog.writeEvent(EventLogTags.AM_PROC_START, pid, uid, + EventLog.writeEvent(EventLogTags.AM_PROC_START, startResult.pid, uid, app.processName, hostingType, hostingNameStr != null ? hostingNameStr : ""); if (app.persistent) { - Watchdog.getInstance().processStarted(app.processName, pid); + Watchdog.getInstance().processStarted(app.processName, startResult.pid); } StringBuilder buf = mStringBuilder; @@ -1987,7 +1989,7 @@ public final class ActivityManagerService extends ActivityManagerNative buf.append(hostingNameStr); } buf.append(": pid="); - buf.append(pid); + buf.append(startResult.pid); buf.append(" uid="); buf.append(uid); buf.append(" gids={"); @@ -2000,26 +2002,15 @@ public final class ActivityManagerService extends ActivityManagerNative } buf.append("}"); Slog.i(TAG, buf.toString()); - if (pid == 0 || pid == MY_PID) { - // Processes are being emulated with threads. - app.pid = MY_PID; - app.removed = false; - mStartingProcesses.add(app); - } else if (pid > 0) { - app.pid = pid; - app.removed = false; - synchronized (mPidsSelfLocked) { - this.mPidsSelfLocked.put(pid, app); - Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); - msg.obj = app; - mHandler.sendMessageDelayed(msg, PROC_START_TIMEOUT); - } - } else { - app.pid = 0; - RuntimeException e = new RuntimeException( - "Failure starting process " + app.processName - + ": returned pid=" + pid); - Slog.e(TAG, e.getMessage(), e); + app.pid = startResult.pid; + app.usingWrapper = startResult.usingWrapper; + app.removed = false; + synchronized (mPidsSelfLocked) { + this.mPidsSelfLocked.put(startResult.pid, app); + Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); + msg.obj = app; + mHandler.sendMessageDelayed(msg, startResult.usingWrapper + ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); } } catch (RuntimeException e) { // XXX do better error recovery. @@ -3605,9 +3596,6 @@ public final class ActivityManagerService extends ActivityManagerNative synchronized (mPidsSelfLocked) { app = mPidsSelfLocked.get(pid); } - } else if (mStartingProcesses.size() > 0) { - app = mStartingProcesses.remove(0); - app.setPid(pid); } else { app = null; } @@ -4041,8 +4029,7 @@ public final class ActivityManagerService extends ActivityManagerNative synchronized(this) { int callingUid = Binder.getCallingUid(); try { - if (callingUid != 0 && callingUid != Process.SYSTEM_UID && - Process.supportsProcesses()) { + if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { int uid = AppGlobals.getPackageManager() .getPackageUid(packageName); if (uid != Binder.getCallingUid()) { @@ -4301,8 +4288,7 @@ public final class ActivityManagerService extends ActivityManagerNative } // Root, system server and our own process get to do everything. - if (uid == 0 || uid == Process.SYSTEM_UID || pid == MY_PID || - !Process.supportsProcesses()) { + if (uid == 0 || uid == Process.SYSTEM_UID || pid == MY_PID) { return PackageManager.PERMISSION_GRANTED; } // If there is a uid that owns whatever is being accessed, it has @@ -4446,7 +4432,7 @@ public final class ActivityManagerService extends ActivityManagerNative private final boolean checkUriPermissionLocked(Uri uri, int uid, int modeFlags) { // Root gets to do everything. - if (uid == 0 || !Process.supportsProcesses()) { + if (uid == 0) { return true; } HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid); @@ -5527,8 +5513,8 @@ public final class ActivityManagerService extends ActivityManagerNative // CONTENT PROVIDERS // ========================================================= - private final List generateApplicationProvidersLocked(ProcessRecord app) { - List providers = null; + private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { + List<ProviderInfo> providers = null; try { providers = AppGlobals.getPackageManager(). queryContentProviders(app.processName, app.info.uid, @@ -5966,7 +5952,7 @@ public final class ActivityManagerService extends ActivityManagerNative } public static final void installSystemProviders() { - List providers; + List<ProviderInfo> providers; synchronized (mSelf) { ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID); providers = mSelf.generateApplicationProvidersLocked(app); @@ -6584,13 +6570,6 @@ public final class ActivityManagerService extends ActivityManagerNative } public void systemReady(final Runnable goingCallback) { - // In the simulator, startRunning will never have been called, which - // normally sets a few crucial variables. Do it here instead. - if (!Process.supportsProcesses()) { - mStartRunning = true; - mTopAction = Intent.ACTION_MAIN; - } - synchronized(this) { if (mSystemReady) { if (goingCallback != null) goingCallback.run(); @@ -7954,14 +7933,6 @@ public final class ActivityManagerService extends ActivityManagerNative "Starting Norm", "Restarting PERS"); } - if (mStartingProcesses.size() > 0) { - if (needSep) pw.println(" "); - needSep = true; - pw.println(" Processes that are starting:"); - dumpProcessList(pw, this, mStartingProcesses, " ", - "Starting Norm", "Starting PERS"); - } - if (mRemovedProcesses.size() > 0) { if (needSep) pw.println(" "); needSep = true; @@ -13127,74 +13098,72 @@ public final class ActivityManagerService extends ActivityManagerNative int adj = computeOomAdjLocked(app, hiddenAdj, TOP_APP, false); - if ((app.pid != 0 && app.pid != MY_PID) || Process.supportsProcesses()) { - if (app.curRawAdj != app.setRawAdj) { - if (app.curRawAdj > FOREGROUND_APP_ADJ - && app.setRawAdj <= FOREGROUND_APP_ADJ) { - // If this app is transitioning from foreground to - // non-foreground, have it do a gc. - scheduleAppGcLocked(app); - } else if (app.curRawAdj >= HIDDEN_APP_MIN_ADJ - && app.setRawAdj < HIDDEN_APP_MIN_ADJ) { - // Likewise do a gc when an app is moving in to the - // background (such as a service stopping). - scheduleAppGcLocked(app); - } - - if (wasKeeping && !app.keeping) { - // This app is no longer something we want to keep. Note - // its current wake lock time to later know to kill it if - // it is not behaving well. - BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); - synchronized (stats) { - app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, - app.pid, SystemClock.elapsedRealtime()); - } - app.lastCpuTime = app.curCpuTime; + if (app.curRawAdj != app.setRawAdj) { + if (app.curRawAdj > FOREGROUND_APP_ADJ + && app.setRawAdj <= FOREGROUND_APP_ADJ) { + // If this app is transitioning from foreground to + // non-foreground, have it do a gc. + scheduleAppGcLocked(app); + } else if (app.curRawAdj >= HIDDEN_APP_MIN_ADJ + && app.setRawAdj < HIDDEN_APP_MIN_ADJ) { + // Likewise do a gc when an app is moving in to the + // background (such as a service stopping). + scheduleAppGcLocked(app); + } + + if (wasKeeping && !app.keeping) { + // This app is no longer something we want to keep. Note + // its current wake lock time to later know to kill it if + // it is not behaving well. + BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); + synchronized (stats) { + app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, + app.pid, SystemClock.elapsedRealtime()); } + app.lastCpuTime = app.curCpuTime; + } - app.setRawAdj = app.curRawAdj; + app.setRawAdj = app.curRawAdj; + } + if (adj != app.setAdj) { + if (Process.setOomAdj(app.pid, adj)) { + if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( + TAG, "Set app " + app.processName + + " oom adj to " + adj); + app.setAdj = adj; + } else { + success = false; } - if (adj != app.setAdj) { - if (Process.setOomAdj(app.pid, adj)) { - if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( - TAG, "Set app " + app.processName + - " oom adj to " + adj); - app.setAdj = adj; - } else { - success = false; + } + if (app.setSchedGroup != app.curSchedGroup) { + app.setSchedGroup = app.curSchedGroup; + if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, + "Setting process group of " + app.processName + + " to " + app.curSchedGroup); + if (app.waitingToKill != null && + app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { + Slog.i(TAG, "Killing " + app.toShortString() + ": " + app.waitingToKill); + EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, + app.processName, app.setAdj, app.waitingToKill); + Process.killProcessQuiet(app.pid); + } else { + if (true) { + long oldId = Binder.clearCallingIdentity(); + try { + Process.setProcessGroup(app.pid, app.curSchedGroup); + } catch (Exception e) { + Slog.w(TAG, "Failed setting process group of " + app.pid + + " to " + app.curSchedGroup); + e.printStackTrace(); + } finally { + Binder.restoreCallingIdentity(oldId); + } } - } - if (app.setSchedGroup != app.curSchedGroup) { - app.setSchedGroup = app.curSchedGroup; - if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, - "Setting process group of " + app.processName - + " to " + app.curSchedGroup); - if (app.waitingToKill != null && - app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { - Slog.i(TAG, "Killing " + app.toShortString() + ": " + app.waitingToKill); - EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, - app.processName, app.setAdj, app.waitingToKill); - Process.killProcessQuiet(app.pid); - } else { - if (true) { - long oldId = Binder.clearCallingIdentity(); + if (false) { + if (app.thread != null) { try { - Process.setProcessGroup(app.pid, app.curSchedGroup); - } catch (Exception e) { - Slog.w(TAG, "Failed setting process group of " + app.pid - + " to " + app.curSchedGroup); - e.printStackTrace(); - } finally { - Binder.restoreCallingIdentity(oldId); - } - } - if (false) { - if (app.thread != null) { - try { - app.thread.setSchedulingGroup(app.curSchedGroup); - } catch (RemoteException e) { - } + app.thread.setSchedulingGroup(app.curSchedGroup); + } catch (RemoteException e) { } } } diff --git a/services/java/com/android/server/am/ActivityRecord.java b/services/java/com/android/server/am/ActivityRecord.java index 090e26b..73ffafb 100644 --- a/services/java/com/android/server/am/ActivityRecord.java +++ b/services/java/com/android/server/am/ActivityRecord.java @@ -658,12 +658,12 @@ final class ActivityRecord extends IApplicationToken.Stub { public long getKeyDispatchingTimeout() { synchronized(service) { ActivityRecord r = getWaitingHistoryRecordLocked(); - if (r == null || r.app == null - || r.app.instrumentationClass == null) { - return ActivityManagerService.KEY_DISPATCHING_TIMEOUT; + if (r != null && r.app != null + && (r.app.instrumentationClass != null || r.app.usingWrapper)) { + return ActivityManagerService.INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; } - - return ActivityManagerService.INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; + + return ActivityManagerService.KEY_DISPATCHING_TIMEOUT; } } diff --git a/services/java/com/android/server/am/ProcessRecord.java b/services/java/com/android/server/am/ProcessRecord.java index 3968f66..da83e7d 100644 --- a/services/java/com/android/server/am/ProcessRecord.java +++ b/services/java/com/android/server/am/ProcessRecord.java @@ -78,6 +78,7 @@ class ProcessRecord { IInstrumentationWatcher instrumentationWatcher; // who is waiting Bundle instrumentationArguments;// as given to us ComponentName instrumentationResultClass;// copy of instrumentationClass + boolean usingWrapper; // Set to true when process was launched with a wrapper attached BroadcastRecord curReceiver;// receiver currently running in the app long lastWakeTime; // How long proc held wake lock at last check long lastCpuTime; // How long proc has run CPU at last check diff --git a/services/java/com/android/server/am/UsageStatsService.java b/services/java/com/android/server/am/UsageStatsService.java index 6e8f248..12c8ccf 100644 --- a/services/java/com/android/server/am/UsageStatsService.java +++ b/services/java/com/android/server/am/UsageStatsService.java @@ -63,7 +63,7 @@ public final class UsageStatsService extends IUsageStats.Stub { private static final String TAG = "UsageStats"; // Current on-disk Parcel version - private static final int VERSION = 1005; + private static final int VERSION = 1006; private static final int CHECKIN_VERSION = 4; @@ -145,6 +145,8 @@ public final class UsageStatsService extends IUsageStats.Stub { final HashMap<String, TimeStats> mLaunchTimes = new HashMap<String, TimeStats>(); int mLaunchCount; + final HashMap<String, Long> mLastResumeTimes + = new HashMap<String, Long>(); long mUsageTime; long mPausedTime; long mResumedTime; @@ -160,20 +162,28 @@ public final class UsageStatsService extends IUsageStats.Stub { if (localLOGV) Slog.v(TAG, "Launch count: " + mLaunchCount + ", Usage time:" + mUsageTime); - final int N = in.readInt(); - if (localLOGV) Slog.v(TAG, "Reading comps: " + N); - for (int i=0; i<N; i++) { + final int numTimeStats = in.readInt(); + if (localLOGV) Slog.v(TAG, "Reading comps: " + numTimeStats); + for (int i=0; i<numTimeStats; i++) { String comp = in.readString(); if (localLOGV) Slog.v(TAG, "Component: " + comp); TimeStats times = new TimeStats(in); mLaunchTimes.put(comp, times); } + final int numResumeTimes = in.readInt(); + if (localLOGV) Slog.v(TAG, "Reading last resume times: " + numResumeTimes); + for (int i=0; i<numResumeTimes; i++) { + String comp = in.readString(); + if (localLOGV) Slog.v(TAG, "Component: " + comp); + mLastResumeTimes.put(comp, in.readLong()); + } } - - void updateResume(boolean launched) { + + void updateResume(String comp, boolean launched) { if (launched) { mLaunchCount ++; } + mLastResumeTimes.put(comp, System.currentTimeMillis()); mResumedTime = SystemClock.elapsedRealtime(); } @@ -203,20 +213,29 @@ public final class UsageStatsService extends IUsageStats.Stub { void writeToParcel(Parcel out) { out.writeInt(mLaunchCount); out.writeLong(mUsageTime); - final int N = mLaunchTimes.size(); - out.writeInt(N); - if (N > 0) { + final int numTimeStats = mLaunchTimes.size(); + out.writeInt(numTimeStats); + if (numTimeStats > 0) { for (Map.Entry<String, TimeStats> ent : mLaunchTimes.entrySet()) { out.writeString(ent.getKey()); TimeStats times = ent.getValue(); times.writeToParcel(out); } } + final int numResumeTimes = mLastResumeTimes.size(); + out.writeInt(numResumeTimes); + if (numResumeTimes > 0) { + for (Map.Entry<String, Long> ent : mLastResumeTimes.entrySet()) { + out.writeString(ent.getKey()); + out.writeLong(ent.getValue()); + } + } } void clear() { mLaunchTimes.clear(); mLaunchCount = 0; + mLastResumeTimes.clear(); mUsageTime = 0; } } @@ -546,7 +565,7 @@ public final class UsageStatsService extends IUsageStats.Stub { pus = new PkgUsageStatsExtended(); mStats.put(pkgName, pus); } - pus.updateResume(!samePackage); + pus.updateResume(mLastResumedComp, !samePackage); if (!sameComp) { pus.addLaunchCount(mLastResumedComp); } @@ -624,7 +643,8 @@ public final class UsageStatsService extends IUsageStats.Stub { if (pus == null) { return null; } - return new PkgUsageStats(pkgName, pus.mLaunchCount, pus.mUsageTime); + return new PkgUsageStats(pkgName, pus.mLaunchCount, pus.mUsageTime, + pus.mLastResumeTimes); } } @@ -641,7 +661,8 @@ public final class UsageStatsService extends IUsageStats.Stub { int i = 0; for (String key: keys) { PkgUsageStatsExtended pus = mStats.get(key); - retArr[i] = new PkgUsageStats(key, pus.mLaunchCount, pus.mUsageTime); + retArr[i] = new PkgUsageStats(key, pus.mLaunchCount, pus.mUsageTime, + pus.mLastResumeTimes); i++; } return retArr; diff --git a/services/java/com/android/server/connectivity/Tethering.java b/services/java/com/android/server/connectivity/Tethering.java index 6bb7949..d7d4b03 100644 --- a/services/java/com/android/server/connectivity/Tethering.java +++ b/services/java/com/android/server/connectivity/Tethering.java @@ -221,8 +221,6 @@ public class Tethering extends INetworkManagementEventObserver.Stub { } public void interfaceLinkStateChanged(String iface, boolean up) { - if (DEBUG) Log.d(TAG, "interfaceLinkStateChanged " + iface + ", " + up); - interfaceStatusChanged(iface, up); } private boolean isUsb(String iface) { diff --git a/services/java/com/android/server/location/GpsLocationProvider.java b/services/java/com/android/server/location/GpsLocationProvider.java index 4fa3bda..c813d37 100755 --- a/services/java/com/android/server/location/GpsLocationProvider.java +++ b/services/java/com/android/server/location/GpsLocationProvider.java @@ -32,7 +32,6 @@ import android.location.LocationManager; import android.location.LocationProvider; import android.net.ConnectivityManager; import android.net.NetworkInfo; -import android.net.SntpClient; import android.os.Binder; import android.os.Bundle; import android.os.Handler; @@ -51,6 +50,7 @@ import android.telephony.SmsMessage; import android.telephony.TelephonyManager; import android.telephony.gsm.GsmCellLocation; import android.util.Log; +import android.util.NtpTrustedTime; import android.util.SparseIntArray; import com.android.internal.app.IBatteryStats; @@ -61,7 +61,7 @@ import com.android.internal.telephony.Phone; import java.io.File; import java.io.FileInputStream; import java.io.IOException; -import java.io.StringBufferInputStream; +import java.io.StringReader; import java.util.ArrayList; import java.util.Date; import java.util.Map.Entry; @@ -235,13 +235,13 @@ public class GpsLocationProvider implements LocationProviderInterface { // properties loaded from PROPERTIES_FILE private Properties mProperties; - private String mNtpServer; private String mSuplServerHost; private int mSuplServerPort; private String mC2KServerHost; private int mC2KServerPort; private final Context mContext; + private final NtpTrustedTime mNtpTime; private final ILocationManager mLocationManager; private Location mLocation = new Location(LocationManager.GPS_PROVIDER); private Bundle mLocationExtras = new Bundle(); @@ -286,10 +286,6 @@ public class GpsLocationProvider implements LocationProviderInterface { // current setting - 5 minutes private static final long RETRY_INTERVAL = 5*60*1000; - // to avoid injecting bad NTP time, we reject any time fixes that differ from system time - // by more than 5 minutes. - private static final long MAX_NTP_SYSTEM_TIME_OFFSET = 5*60*1000; - private final IGpsStatusProvider mGpsStatusProvider = new IGpsStatusProvider.Stub() { public void addGpsStatusListener(IGpsStatusListener listener) throws RemoteException { if (listener == null) { @@ -378,6 +374,7 @@ public class GpsLocationProvider implements LocationProviderInterface { public GpsLocationProvider(Context context, ILocationManager locationManager) { mContext = context; + mNtpTime = NtpTrustedTime.getInstance(context); mLocationManager = locationManager; mNIHandler = new GpsNetInitiatedHandler(context); @@ -418,7 +415,6 @@ public class GpsLocationProvider implements LocationProviderInterface { FileInputStream stream = new FileInputStream(file); mProperties.load(stream); stream.close(); - mNtpServer = mProperties.getProperty("NTP_SERVER", null); mSuplServerHost = mProperties.getProperty("SUPL_HOST"); String portString = mProperties.getProperty("SUPL_PORT"); @@ -530,13 +526,18 @@ public class GpsLocationProvider implements LocationProviderInterface { } mInjectNtpTimePending = false; - SntpClient client = new SntpClient(); long delay; - if (client.requestTime(mNtpServer, 10000)) { - long time = client.getNtpTime(); - long timeReference = client.getNtpTimeReference(); - int certainty = (int)(client.getRoundTripTime()/2); + // force refresh NTP cache when outdated + if (mNtpTime.getCacheAge() >= NTP_INTERVAL) { + mNtpTime.forceRefresh(); + } + + // only update when NTP time is fresh + if (mNtpTime.getCacheAge() < NTP_INTERVAL) { + long time = mNtpTime.getCachedNtpTime(); + long timeReference = mNtpTime.getCachedNtpTimeReference(); + long certainty = mNtpTime.getCacheCertainty(); long now = System.currentTimeMillis(); Log.d(TAG, "NTP server returned: " @@ -545,7 +546,7 @@ public class GpsLocationProvider implements LocationProviderInterface { + " certainty: " + certainty + " system time offset: " + (time - now)); - native_inject_time(time, timeReference, certainty); + native_inject_time(time, timeReference, (int) certainty); delay = NTP_INTERVAL; } else { if (DEBUG) Log.d(TAG, "requestTime failed"); @@ -1395,7 +1396,7 @@ public class GpsLocationProvider implements LocationProviderInterface { Properties extraProp = new Properties(); try { - extraProp.load(new StringBufferInputStream(extras)); + extraProp.load(new StringReader(extras)); } catch (IOException e) { diff --git a/services/java/com/android/server/net/NetworkPolicyManagerService.java b/services/java/com/android/server/net/NetworkPolicyManagerService.java index 2a17cbe..d23d0f4 100644 --- a/services/java/com/android/server/net/NetworkPolicyManagerService.java +++ b/services/java/com/android/server/net/NetworkPolicyManagerService.java @@ -204,9 +204,8 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { public NetworkPolicyManagerService(Context context, IActivityManager activityManager, IPowerManager powerManager, INetworkStatsService networkStats, INetworkManagementService networkManagement) { - // TODO: move to using cached NtpTrustedTime this(context, activityManager, powerManager, networkStats, networkManagement, - new NtpTrustedTime(), getSystemDir()); + NtpTrustedTime.getInstance(context), getSystemDir()); } private static File getSystemDir() { diff --git a/services/java/com/android/server/net/NetworkStatsService.java b/services/java/com/android/server/net/NetworkStatsService.java index b4bd176..b6834f6 100644 --- a/services/java/com/android/server/net/NetworkStatsService.java +++ b/services/java/com/android/server/net/NetworkStatsService.java @@ -27,7 +27,6 @@ import static android.net.NetworkStats.IFACE_ALL; import static android.net.NetworkStats.TAG_NONE; import static android.net.NetworkStats.UID_ALL; import static android.net.TrafficStats.UID_REMOVED; -import static android.provider.Settings.Secure.NETSTATS_ENABLED; import static android.provider.Settings.Secure.NETSTATS_NETWORK_BUCKET_DURATION; import static android.provider.Settings.Secure.NETSTATS_NETWORK_MAX_HISTORY; import static android.provider.Settings.Secure.NETSTATS_PERSIST_THRESHOLD; @@ -71,7 +70,6 @@ import android.util.Slog; import android.util.TrustedTime; import com.android.internal.os.AtomicFile; -import com.android.server.NativeDaemonConnectorException; import com.google.android.collect.Maps; import com.google.android.collect.Sets; @@ -175,9 +173,8 @@ public class NetworkStatsService extends INetworkStatsService.Stub { public NetworkStatsService( Context context, INetworkManagementService networkManager, IAlarmManager alarmManager) { - // TODO: move to using cached NtpTrustedTime - this(context, networkManager, alarmManager, new NtpTrustedTime(), getSystemDir(), - new DefaultNetworkStatsSettings(context)); + this(context, networkManager, alarmManager, NtpTrustedTime.getInstance(context), + getSystemDir(), new DefaultNetworkStatsSettings(context)); } private static File getSystemDir() { diff --git a/services/java/com/android/server/pm/PackageManagerService.java b/services/java/com/android/server/pm/PackageManagerService.java index ea5d26b..d6a15e6 100644 --- a/services/java/com/android/server/pm/PackageManagerService.java +++ b/services/java/com/android/server/pm/PackageManagerService.java @@ -778,16 +778,7 @@ public class PackageManagerService extends IPackageManager.Stub { mSeparateProcesses = null; } - Installer installer = new Installer(); - // Little hacky thing to check if installd is here, to determine - // whether we are running on the simulator and thus need to take - // care of building the /data file structure ourself. - // (apparently the sim now has a working installer) - if (installer.ping() && Process.supportsProcesses()) { - mInstaller = installer; - } else { - mInstaller = null; - } + mInstaller = new Installer(); WindowManager wm = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE); Display d = wm.getDefaultDisplay(); @@ -806,17 +797,6 @@ public class PackageManagerService extends IPackageManager.Stub { mUserManager = new UserManager(mInstaller, mUserAppDataDir); - if (mInstaller == null) { - // Make sure these dirs exist, when we are running in - // the simulator. - // Make a wide-open directory for random misc stuff. - File miscDir = new File(dataDir, "misc"); - miscDir.mkdirs(); - mAppDataDir.mkdirs(); - mUserAppDataDir.mkdirs(); - mDrmAppPrivateInstallDir.mkdirs(); - } - readPermissions(); mRestoredSettings = mSettings.readLPw(); @@ -838,104 +818,102 @@ public class PackageManagerService extends IPackageManager.Stub { mFrameworkDir = new File(Environment.getRootDirectory(), "framework"); mDalvikCacheDir = new File(dataDir, "dalvik-cache"); - if (mInstaller != null) { - boolean didDexOpt = false; - - /** - * Out of paranoia, ensure that everything in the boot class - * path has been dexed. - */ - String bootClassPath = System.getProperty("java.boot.class.path"); - if (bootClassPath != null) { - String[] paths = splitString(bootClassPath, ':'); - for (int i=0; i<paths.length; i++) { - try { - if (dalvik.system.DexFile.isDexOptNeeded(paths[i])) { - libFiles.add(paths[i]); - mInstaller.dexopt(paths[i], Process.SYSTEM_UID, true); - didDexOpt = true; - } - } catch (FileNotFoundException e) { - Slog.w(TAG, "Boot class path not found: " + paths[i]); - } catch (IOException e) { - Slog.w(TAG, "Exception reading boot class path: " + paths[i], e); + boolean didDexOpt = false; + + /** + * Out of paranoia, ensure that everything in the boot class + * path has been dexed. + */ + String bootClassPath = System.getProperty("java.boot.class.path"); + if (bootClassPath != null) { + String[] paths = splitString(bootClassPath, ':'); + for (int i=0; i<paths.length; i++) { + try { + if (dalvik.system.DexFile.isDexOptNeeded(paths[i])) { + libFiles.add(paths[i]); + mInstaller.dexopt(paths[i], Process.SYSTEM_UID, true); + didDexOpt = true; } + } catch (FileNotFoundException e) { + Slog.w(TAG, "Boot class path not found: " + paths[i]); + } catch (IOException e) { + Slog.w(TAG, "Exception reading boot class path: " + paths[i], e); } - } else { - Slog.w(TAG, "No BOOTCLASSPATH found!"); } + } else { + Slog.w(TAG, "No BOOTCLASSPATH found!"); + } - /** - * Also ensure all external libraries have had dexopt run on them. - */ - if (mSharedLibraries.size() > 0) { - Iterator<String> libs = mSharedLibraries.values().iterator(); - while (libs.hasNext()) { - String lib = libs.next(); - try { - if (dalvik.system.DexFile.isDexOptNeeded(lib)) { - libFiles.add(lib); - mInstaller.dexopt(lib, Process.SYSTEM_UID, true); - didDexOpt = true; - } - } catch (FileNotFoundException e) { - Slog.w(TAG, "Library not found: " + lib); - } catch (IOException e) { - Slog.w(TAG, "Exception reading library: " + lib, e); + /** + * Also ensure all external libraries have had dexopt run on them. + */ + if (mSharedLibraries.size() > 0) { + Iterator<String> libs = mSharedLibraries.values().iterator(); + while (libs.hasNext()) { + String lib = libs.next(); + try { + if (dalvik.system.DexFile.isDexOptNeeded(lib)) { + libFiles.add(lib); + mInstaller.dexopt(lib, Process.SYSTEM_UID, true); + didDexOpt = true; } + } catch (FileNotFoundException e) { + Slog.w(TAG, "Library not found: " + lib); + } catch (IOException e) { + Slog.w(TAG, "Exception reading library: " + lib, e); } } + } - // Gross hack for now: we know this file doesn't contain any - // code, so don't dexopt it to avoid the resulting log spew. - libFiles.add(mFrameworkDir.getPath() + "/framework-res.apk"); - - /** - * And there are a number of commands implemented in Java, which - * we currently need to do the dexopt on so that they can be - * run from a non-root shell. - */ - String[] frameworkFiles = mFrameworkDir.list(); - if (frameworkFiles != null) { - for (int i=0; i<frameworkFiles.length; i++) { - File libPath = new File(mFrameworkDir, frameworkFiles[i]); - String path = libPath.getPath(); - // Skip the file if we alrady did it. - if (libFiles.contains(path)) { - continue; - } - // Skip the file if it is not a type we want to dexopt. - if (!path.endsWith(".apk") && !path.endsWith(".jar")) { - continue; - } - try { - if (dalvik.system.DexFile.isDexOptNeeded(path)) { - mInstaller.dexopt(path, Process.SYSTEM_UID, true); - didDexOpt = true; - } - } catch (FileNotFoundException e) { - Slog.w(TAG, "Jar not found: " + path); - } catch (IOException e) { - Slog.w(TAG, "Exception reading jar: " + path, e); + // Gross hack for now: we know this file doesn't contain any + // code, so don't dexopt it to avoid the resulting log spew. + libFiles.add(mFrameworkDir.getPath() + "/framework-res.apk"); + + /** + * And there are a number of commands implemented in Java, which + * we currently need to do the dexopt on so that they can be + * run from a non-root shell. + */ + String[] frameworkFiles = mFrameworkDir.list(); + if (frameworkFiles != null) { + for (int i=0; i<frameworkFiles.length; i++) { + File libPath = new File(mFrameworkDir, frameworkFiles[i]); + String path = libPath.getPath(); + // Skip the file if we alrady did it. + if (libFiles.contains(path)) { + continue; + } + // Skip the file if it is not a type we want to dexopt. + if (!path.endsWith(".apk") && !path.endsWith(".jar")) { + continue; + } + try { + if (dalvik.system.DexFile.isDexOptNeeded(path)) { + mInstaller.dexopt(path, Process.SYSTEM_UID, true); + didDexOpt = true; } + } catch (FileNotFoundException e) { + Slog.w(TAG, "Jar not found: " + path); + } catch (IOException e) { + Slog.w(TAG, "Exception reading jar: " + path, e); } } + } - if (didDexOpt) { - // If we had to do a dexopt of one of the previous - // things, then something on the system has changed. - // Consider this significant, and wipe away all other - // existing dexopt files to ensure we don't leave any - // dangling around. - String[] files = mDalvikCacheDir.list(); - if (files != null) { - for (int i=0; i<files.length; i++) { - String fn = files[i]; - if (fn.startsWith("data@app@") - || fn.startsWith("data@app-private@")) { - Slog.i(TAG, "Pruning dalvik file: " + fn); - (new File(mDalvikCacheDir, fn)).delete(); - } + if (didDexOpt) { + // If we had to do a dexopt of one of the previous + // things, then something on the system has changed. + // Consider this significant, and wipe away all other + // existing dexopt files to ensure we don't leave any + // dangling around. + String[] files = mDalvikCacheDir.list(); + if (files != null) { + for (int i=0; i<files.length; i++) { + String fn = files[i]; + if (fn.startsWith("data@app@") + || fn.startsWith("data@app-private@")) { + Slog.i(TAG, "Pruning dalvik file: " + fn); + (new File(mDalvikCacheDir, fn)).delete(); } } } @@ -965,11 +943,9 @@ public class PackageManagerService extends IPackageManager.Stub { scanDirLI(mVendorAppDir, PackageParser.PARSE_IS_SYSTEM | PackageParser.PARSE_IS_SYSTEM_DIR, scanMode, 0); - if (mInstaller != null) { - if (DEBUG_UPGRADE) Log.v(TAG, "Running installd update commands"); - mInstaller.moveFiles(); - } - + if (DEBUG_UPGRADE) Log.v(TAG, "Running installd update commands"); + mInstaller.moveFiles(); + // Prune any system packages that no longer exist. Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator(); while (psit.hasNext()) { @@ -981,19 +957,12 @@ public class PackageManagerService extends IPackageManager.Stub { String msg = "System package " + ps.name + " no longer exists; wiping its data"; reportSettingsProblem(Log.WARN, msg); - if (mInstaller != null) { - mInstaller.remove(ps.name, 0); - mUserManager.removePackageForAllUsers(ps.name); - } + mInstaller.remove(ps.name, 0); + mUserManager.removePackageForAllUsers(ps.name); } } mAppInstallDir = new File(dataDir, "app"); - if (mInstaller == null) { - // Make sure these dirs exist, when we are running in - // the simulator. - mAppInstallDir.mkdirs(); // scanDirLI() assumes this dir exists - } //look for any incomplete package installations ArrayList<PackageSetting> deletePkgsList = mSettings.getListOfIncompleteInstallPackagesLPr(); //clean up list @@ -1067,19 +1036,12 @@ public class PackageManagerService extends IPackageManager.Stub { void cleanupInstallFailedPackage(PackageSetting ps) { Slog.i(TAG, "Cleaning up incompletely installed app: " + ps.name); - if (mInstaller != null) { - int retCode = mInstaller.remove(ps.name, 0); - if (retCode < 0) { - Slog.w(TAG, "Couldn't remove app data directory for package: " - + ps.name + ", retcode=" + retCode); - } else { - mUserManager.removePackageForAllUsers(ps.name); - } + int retCode = mInstaller.remove(ps.name, 0); + if (retCode < 0) { + Slog.w(TAG, "Couldn't remove app data directory for package: " + + ps.name + ", retcode=" + retCode); } else { - //for emulator - PackageParser.Package pkg = mPackages.get(ps.name); - File dataDir = new File(pkg.applicationInfo.dataDir); - dataDir.delete(); + mUserManager.removePackageForAllUsers(ps.name); } if (ps.codePath != null) { if (!ps.codePath.delete()) { @@ -1562,12 +1524,10 @@ public class PackageManagerService extends IPackageManager.Stub { public void run() { mHandler.removeCallbacks(this); int retCode = -1; - if (mInstaller != null) { - retCode = mInstaller.freeCache(freeStorageSize); - if (retCode < 0) { - Slog.w(TAG, "Couldn't clear application caches"); - } - } //end if mInstaller + retCode = mInstaller.freeCache(freeStorageSize); + if (retCode < 0) { + Slog.w(TAG, "Couldn't clear application caches"); + } if (observer != null) { try { observer.onRemoveCompleted(null, (retCode >= 0)); @@ -1587,11 +1547,9 @@ public class PackageManagerService extends IPackageManager.Stub { public void run() { mHandler.removeCallbacks(this); int retCode = -1; - if (mInstaller != null) { - retCode = mInstaller.freeCache(freeStorageSize); - if (retCode < 0) { - Slog.w(TAG, "Couldn't clear application caches"); - } + retCode = mInstaller.freeCache(freeStorageSize); + if (retCode < 0) { + Slog.w(TAG, "Couldn't clear application caches"); } if(pi != null) { try { @@ -2850,7 +2808,7 @@ public class PackageManagerService extends IPackageManager.Stub { private int performDexOptLI(PackageParser.Package pkg, boolean forceDex) { boolean performed = false; - if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_HAS_CODE) != 0 && mInstaller != null) { + if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_HAS_CODE) != 0) { String path = pkg.mScanPath; int ret = 0; try { @@ -3235,42 +3193,39 @@ public class PackageManagerService extends IPackageManager.Stub { mOutPermissions[1] = 0; FileUtils.getPermissions(dataPath.getPath(), mOutPermissions); - // If we have mismatched owners for the data path, we have a - // problem (unless we're running in the simulator.) - if (mOutPermissions[1] != pkg.applicationInfo.uid && Process.supportsProcesses()) { + // If we have mismatched owners for the data path, we have a problem. + if (mOutPermissions[1] != pkg.applicationInfo.uid) { boolean recovered = false; if ((parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0) { // If this is a system app, we can at least delete its // current data so the application will still work. - if (mInstaller != null) { - int ret = mInstaller.remove(pkgName, 0); - if (ret >= 0) { - // TODO: Kill the processes first - // Remove the data directories for all users - mUserManager.removePackageForAllUsers(pkgName); - // Old data gone! - String msg = "System package " + pkg.packageName - + " has changed from uid: " - + mOutPermissions[1] + " to " - + pkg.applicationInfo.uid + "; old data erased"; + int ret = mInstaller.remove(pkgName, 0); + if (ret >= 0) { + // TODO: Kill the processes first + // Remove the data directories for all users + mUserManager.removePackageForAllUsers(pkgName); + // Old data gone! + String msg = "System package " + pkg.packageName + + " has changed from uid: " + + mOutPermissions[1] + " to " + + pkg.applicationInfo.uid + "; old data erased"; + reportSettingsProblem(Log.WARN, msg); + recovered = true; + + // And now re-install the app. + ret = mInstaller.install(pkgName, pkg.applicationInfo.uid, + pkg.applicationInfo.uid); + if (ret == -1) { + // Ack should not happen! + msg = "System package " + pkg.packageName + + " could not have data directory re-created after delete."; reportSettingsProblem(Log.WARN, msg); - recovered = true; - - // And now re-install the app. - ret = mInstaller.install(pkgName, pkg.applicationInfo.uid, - pkg.applicationInfo.uid); - if (ret == -1) { - // Ack should not happen! - msg = "System package " + pkg.packageName - + " could not have data directory re-created after delete."; - reportSettingsProblem(Log.WARN, msg); - mLastScanError = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; - return null; - } - // Create data directories for all users - mUserManager.installPackageForAllUsers(pkgName, - pkg.applicationInfo.uid); + mLastScanError = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; + return null; } + // Create data directories for all users + mUserManager.installPackageForAllUsers(pkgName, + pkg.applicationInfo.uid); } if (!recovered) { mHasSystemUidErrors = true; @@ -3303,25 +3258,16 @@ public class PackageManagerService extends IPackageManager.Stub { Log.v(TAG, "Want this data dir: " + dataPath); } //invoke installer to do the actual installation - if (mInstaller != null) { - int ret = mInstaller.install(pkgName, pkg.applicationInfo.uid, - pkg.applicationInfo.uid); - if (ret < 0) { - // Error from installer - mLastScanError = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; - return null; - } - // Create data directories for all users - mUserManager.installPackageForAllUsers(pkgName, pkg.applicationInfo.uid); - } else { - dataPath.mkdirs(); - if (dataPath.exists()) { - FileUtils.setPermissions( - dataPath.toString(), - FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH, - pkg.applicationInfo.uid, pkg.applicationInfo.uid); - } + int ret = mInstaller.install(pkgName, pkg.applicationInfo.uid, + pkg.applicationInfo.uid); + if (ret < 0) { + // Error from installer + mLastScanError = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; + return null; } + // Create data directories for all users + mUserManager.installPackageForAllUsers(pkgName, pkg.applicationInfo.uid); + if (dataPath.exists()) { pkg.applicationInfo.dataDir = dataPath.getPath(); } else { @@ -3352,65 +3298,62 @@ public class PackageManagerService extends IPackageManager.Stub { pkgSetting.uidError = uidError; } - // If we're running in the simulator, we don't need to unpack anything. - if (mInstaller != null) { - String path = scanFile.getPath(); - /* Note: We don't want to unpack the native binaries for - * system applications, unless they have been updated - * (the binaries are already under /system/lib). - * Also, don't unpack libs for apps on the external card - * since they should have their libraries in the ASEC - * container already. - * - * In other words, we're going to unpack the binaries - * only for non-system apps and system app upgrades. - */ - if (pkg.applicationInfo.nativeLibraryDir != null) { - try { - final File nativeLibraryDir = new File(pkg.applicationInfo.nativeLibraryDir); - final String dataPathString = dataPath.getCanonicalFile().getPath(); + String path = scanFile.getPath(); + /* Note: We don't want to unpack the native binaries for + * system applications, unless they have been updated + * (the binaries are already under /system/lib). + * Also, don't unpack libs for apps on the external card + * since they should have their libraries in the ASEC + * container already. + * + * In other words, we're going to unpack the binaries + * only for non-system apps and system app upgrades. + */ + if (pkg.applicationInfo.nativeLibraryDir != null) { + try { + final File nativeLibraryDir = new File(pkg.applicationInfo.nativeLibraryDir); + final String dataPathString = dataPath.getCanonicalFile().getPath(); - if (isSystemApp(pkg) && !isUpdatedSystemApp(pkg)) { - /* - * Upgrading from a previous version of the OS sometimes - * leaves native libraries in the /data/data/<app>/lib - * directory for system apps even when they shouldn't be. - * Recent changes in the JNI library search path - * necessitates we remove those to match previous behavior. - */ - if (NativeLibraryHelper.removeNativeBinariesFromDirLI(nativeLibraryDir)) { - Log.i(TAG, "removed obsolete native libraries for system package " - + path); - } - } else if (nativeLibraryDir.getCanonicalFile().getParent() - .equals(dataPathString)) { - /* - * If this is an internal application or our - * nativeLibraryPath points to our data directory, unpack - * the libraries. The native library path pointing to the - * data directory for an application in an ASEC container - * can happen for older apps that existed before an OTA to - * Gingerbread. - */ - Slog.i(TAG, "Unpacking native libraries for " + path); - mInstaller.unlinkNativeLibraryDirectory(dataPathString); - NativeLibraryHelper.copyNativeBinariesLI(scanFile, nativeLibraryDir); - } else { - Slog.i(TAG, "Linking native library dir for " + path); - mInstaller.linkNativeLibraryDirectory(dataPathString, - pkg.applicationInfo.nativeLibraryDir); + if (isSystemApp(pkg) && !isUpdatedSystemApp(pkg)) { + /* + * Upgrading from a previous version of the OS sometimes + * leaves native libraries in the /data/data/<app>/lib + * directory for system apps even when they shouldn't be. + * Recent changes in the JNI library search path + * necessitates we remove those to match previous behavior. + */ + if (NativeLibraryHelper.removeNativeBinariesFromDirLI(nativeLibraryDir)) { + Log.i(TAG, "removed obsolete native libraries for system package " + + path); } - } catch (IOException ioe) { - Log.e(TAG, "Unable to get canonical file " + ioe.toString()); + } else if (nativeLibraryDir.getCanonicalFile().getParent() + .equals(dataPathString)) { + /* + * If this is an internal application or our + * nativeLibraryPath points to our data directory, unpack + * the libraries. The native library path pointing to the + * data directory for an application in an ASEC container + * can happen for older apps that existed before an OTA to + * Gingerbread. + */ + Slog.i(TAG, "Unpacking native libraries for " + path); + mInstaller.unlinkNativeLibraryDirectory(dataPathString); + NativeLibraryHelper.copyNativeBinariesLI(scanFile, nativeLibraryDir); + } else { + Slog.i(TAG, "Linking native library dir for " + path); + mInstaller.linkNativeLibraryDirectory(dataPathString, + pkg.applicationInfo.nativeLibraryDir); } + } catch (IOException ioe) { + Log.e(TAG, "Unable to get canonical file " + ioe.toString()); } - pkg.mScanPath = path; + } + pkg.mScanPath = path; - if ((scanMode&SCAN_NO_DEX) == 0) { - if (performDexOptLI(pkg, forceDex) == DEX_OPT_FAILED) { - mLastScanError = PackageManager.INSTALL_FAILED_DEXOPT; - return null; - } + if ((scanMode&SCAN_NO_DEX) == 0) { + if (performDexOptLI(pkg, forceDex) == DEX_OPT_FAILED) { + mLastScanError = PackageManager.INSTALL_FAILED_DEXOPT; + return null; } } @@ -5434,7 +5377,7 @@ public class PackageManagerService extends IPackageManager.Stub { void cleanUpResourcesLI() { String sourceDir = getCodePath(); - if (cleanUp() && mInstaller != null) { + if (cleanUp()) { int retCode = mInstaller.rmdex(sourceDir); if (retCode < 0) { Slog.w(TAG, "Couldn't remove dex file for package: " @@ -5662,14 +5605,12 @@ public class PackageManagerService extends IPackageManager.Stub { void cleanUpResourcesLI() { String sourceFile = getCodePath(); // Remove dex file - if (mInstaller != null) { - int retCode = mInstaller.rmdex(sourceFile); - if (retCode < 0) { - Slog.w(TAG, "Couldn't remove dex file for package: " - + " at location " - + sourceFile.toString() + ", retcode=" + retCode); - // we don't consider this to be a failure of the core package deletion - } + int retCode = mInstaller.rmdex(sourceFile); + if (retCode < 0) { + Slog.w(TAG, "Couldn't remove dex file for package: " + + " at location " + + sourceFile.toString() + ", retcode=" + retCode); + // we don't consider this to be a failure of the core package deletion } cleanUp(); } @@ -6077,9 +6018,7 @@ public class PackageManagerService extends IPackageManager.Stub { } if((res.returnCode = setPermissionsLI(newPackage)) != PackageManager.INSTALL_SUCCEEDED) { - if (mInstaller != null) { - mInstaller.rmdex(newPackage.mScanPath); - } + mInstaller.rmdex(newPackage.mScanPath); return; } else { Log.d(TAG, "New package installed in " + newPackage.mPath); @@ -6207,15 +6146,8 @@ public class PackageManagerService extends IPackageManager.Stub { } finally { //TODO clean up the extracted public files } - if (mInstaller != null) { - retCode = mInstaller.setForwardLockPerm(getApkName(newPackage.mPath), - newPackage.applicationInfo.uid); - } else { - final int filePermissions = - FileUtils.S_IRUSR|FileUtils.S_IWUSR|FileUtils.S_IRGRP; - retCode = FileUtils.setPermissions(newPackage.mPath, filePermissions, -1, - newPackage.applicationInfo.uid); - } + retCode = mInstaller.setForwardLockPerm(getApkName(newPackage.mPath), + newPackage.applicationInfo.uid); } else { // The permissions on the resource file was set when it was copied for // non forward locked apps and apps on sdcard @@ -6478,25 +6410,14 @@ public class PackageManagerService extends IPackageManager.Stub { deletedPs = mSettings.mPackages.get(packageName); } if ((flags&PackageManager.DONT_DELETE_DATA) == 0) { - if (mInstaller != null) { - int retCode = mInstaller.remove(packageName, 0); - if (retCode < 0) { - Slog.w(TAG, "Couldn't remove app data or cache directory for package: " - + packageName + ", retcode=" + retCode); - // we don't consider this to be a failure of the core package deletion - } else { - // TODO: Kill the processes first - mUserManager.removePackageForAllUsers(packageName); - } + int retCode = mInstaller.remove(packageName, 0); + if (retCode < 0) { + Slog.w(TAG, "Couldn't remove app data or cache directory for package: " + + packageName + ", retcode=" + retCode); + // we don't consider this to be a failure of the core package deletion } else { - // for simulator - File dataDir; - // reader - synchronized (mPackages) { - PackageParser.Package pkg = mPackages.get(packageName); - dataDir = new File(pkg.applicationInfo.dataDir); - } - dataDir.delete(); + // TODO: Kill the processes first + mUserManager.removePackageForAllUsers(packageName); } schedulePackageCleaning(packageName); } @@ -6745,13 +6666,11 @@ public class PackageManagerService extends IPackageManager.Stub { return false; } } - if (mInstaller != null) { - int retCode = mInstaller.clearUserData(packageName, 0); // TODO - correct userId - if (retCode < 0) { - Slog.w(TAG, "Couldn't remove cache files for package: " - + packageName); - return false; - } + int retCode = mInstaller.clearUserData(packageName, 0); // TODO - correct userId + if (retCode < 0) { + Slog.w(TAG, "Couldn't remove cache files for package: " + + packageName); + return false; } return true; } @@ -6797,13 +6716,11 @@ public class PackageManagerService extends IPackageManager.Stub { Slog.w(TAG, "Package " + packageName + " has no applicationInfo."); return false; } - if (mInstaller != null) { - int retCode = mInstaller.deleteCacheFiles(packageName); - if (retCode < 0) { - Slog.w(TAG, "Couldn't remove cache files for package: " - + packageName); - return false; - } + int retCode = mInstaller.deleteCacheFiles(packageName); + if (retCode < 0) { + Slog.w(TAG, "Couldn't remove cache files for package: " + + packageName); + return false; } return true; } @@ -6867,14 +6784,10 @@ public class PackageManagerService extends IPackageManager.Stub { publicSrcDir = applicationInfo.publicSourceDir; } } - if (mInstaller != null) { - int res = mInstaller.getSizeInfo(packageName, p.mPath, publicSrcDir, - asecPath, pStats); - if (res < 0) { - return false; - } else { - return true; - } + int res = mInstaller.getSizeInfo(packageName, p.mPath, publicSrcDir, + asecPath, pStats); + if (res < 0) { + return false; } return true; } diff --git a/services/java/com/android/server/usb/UsbDeviceManager.java b/services/java/com/android/server/usb/UsbDeviceManager.java index d645160..86b3d36 100644 --- a/services/java/com/android/server/usb/UsbDeviceManager.java +++ b/services/java/com/android/server/usb/UsbDeviceManager.java @@ -251,19 +251,18 @@ public class UsbDeviceManager { public UsbHandler() { try { + // persist.sys.usb.config should never be unset. But if it is, set it to "adb" + // so we have a chance of debugging what happened. + mDefaultFunctions = SystemProperties.get("persist.sys.usb.config", "adb"); // sanity check the sys.usb.config system property // this may be necessary if we crashed while switching USB configurations String config = SystemProperties.get("sys.usb.config", "none"); - if (config.equals("none")) { - String persistConfig = SystemProperties.get("persist.sys.usb.config", "none"); - Slog.w(TAG, "resetting config to persistent property: " + persistConfig); - SystemProperties.set("sys.usb.config", persistConfig); + if (!config.equals(mDefaultFunctions)) { + Slog.w(TAG, "resetting config to persistent property: " + mDefaultFunctions); + SystemProperties.set("sys.usb.config", mDefaultFunctions); } - // Read initial USB state - mCurrentFunctions = FileUtils.readTextFile( - new File(FUNCTIONS_PATH), 0, null).trim(); - mDefaultFunctions = mCurrentFunctions; + mCurrentFunctions = mDefaultFunctions; String state = FileUtils.readTextFile(new File(STATE_PATH), 0, null).trim(); updateState(state); mAdbEnabled = containsFunction(mCurrentFunctions, UsbManager.USB_FUNCTION_ADB); @@ -621,6 +620,16 @@ public class UsbDeviceManager { pw.println(" mConnected: " + mConnected); pw.println(" mConfigured: " + mConfigured); pw.println(" mCurrentAccessory: " + mCurrentAccessory); + try { + pw.println(" Kernel state: " + + FileUtils.readTextFile(new File(STATE_PATH), 0, null).trim()); + pw.println(" Kernel function list: " + + FileUtils.readTextFile(new File(FUNCTIONS_PATH), 0, null).trim()); + pw.println(" Mass storage backing file: " + + FileUtils.readTextFile(new File(MASS_STORAGE_FILE_PATH), 0, null).trim()); + } catch (IOException e) { + pw.println("IOException: " + e); + } } } @@ -630,20 +639,20 @@ public class UsbDeviceManager { } /* opens the currently attached USB accessory */ - public ParcelFileDescriptor openAccessory(UsbAccessory accessory) { - UsbAccessory currentAccessory = mHandler.getCurrentAccessory(); - if (currentAccessory == null) { - throw new IllegalArgumentException("no accessory attached"); - } - if (!currentAccessory.equals(accessory)) { - String error = accessory.toString() - + " does not match current accessory " - + currentAccessory; - throw new IllegalArgumentException(error); - } - mSettingsManager.checkPermission(accessory); - return nativeOpenAccessory(); + public ParcelFileDescriptor openAccessory(UsbAccessory accessory) { + UsbAccessory currentAccessory = mHandler.getCurrentAccessory(); + if (currentAccessory == null) { + throw new IllegalArgumentException("no accessory attached"); + } + if (!currentAccessory.equals(accessory)) { + String error = accessory.toString() + + " does not match current accessory " + + currentAccessory; + throw new IllegalArgumentException(error); } + mSettingsManager.checkPermission(accessory); + return nativeOpenAccessory(); + } public void setCurrentFunction(String function, boolean makeDefault) { if (DEBUG) Slog.d(TAG, "setCurrentFunction(" + function + ") default: " + makeDefault); diff --git a/services/surfaceflinger/DisplayHardware/DisplayHardware.cpp b/services/surfaceflinger/DisplayHardware/DisplayHardware.cpp index 33125c4..7bf3e0a 100644 --- a/services/surfaceflinger/DisplayHardware/DisplayHardware.cpp +++ b/services/surfaceflinger/DisplayHardware/DisplayHardware.cpp @@ -99,6 +99,31 @@ uint32_t DisplayHardware::getMaxViewportDims() const { mMaxViewportDims[0] : mMaxViewportDims[1]; } +static status_t selectConfigForPixelFormat( + EGLDisplay dpy, + EGLint const* attrs, + PixelFormat format, + EGLConfig* outConfig) +{ + EGLConfig config = NULL; + EGLint numConfigs = -1, n=0; + eglGetConfigs(dpy, NULL, 0, &numConfigs); + EGLConfig* const configs = new EGLConfig[numConfigs]; + eglChooseConfig(dpy, attrs, configs, numConfigs, &n); + for (int i=0 ; i<n ; i++) { + EGLint nativeVisualId = 0; + eglGetConfigAttrib(dpy, configs[i], EGL_NATIVE_VISUAL_ID, &nativeVisualId); + if (nativeVisualId>0 && format == nativeVisualId) { + *outConfig = configs[i]; + delete [] configs; + return NO_ERROR; + } + } + delete [] configs; + return NAME_NOT_FOUND; +} + + void DisplayHardware::init(uint32_t dpy) { mNativeWindow = new FramebufferNativeWindow(); @@ -108,6 +133,9 @@ void DisplayHardware::init(uint32_t dpy) exit(0); } + int format; + ANativeWindow const * const window = mNativeWindow.get(); + window->query(window, NATIVE_WINDOW_FORMAT, &format); mDpiX = mNativeWindow->xdpi; mDpiY = mNativeWindow->ydpi; mRefreshRate = fbDev->fps; @@ -116,11 +144,13 @@ void DisplayHardware::init(uint32_t dpy) EGLint numConfigs=0; EGLSurface surface; EGLContext context; + EGLBoolean result; + status_t err; // initialize EGL EGLint attribs[] = { - EGL_SURFACE_TYPE, EGL_WINDOW_BIT, - EGL_NONE, 0, + EGL_SURFACE_TYPE, EGL_WINDOW_BIT, + EGL_NONE, 0, EGL_NONE }; @@ -141,9 +171,8 @@ void DisplayHardware::init(uint32_t dpy) eglInitialize(display, NULL, NULL); eglGetConfigs(display, NULL, 0, &numConfigs); - EGLConfig config; - status_t err = EGLUtils::selectConfigForNativeWindow( - display, attribs, mNativeWindow.get(), &config); + EGLConfig config = NULL; + err = selectConfigForPixelFormat(display, attribs, format, &config); LOGE_IF(err, "couldn't find an EGLConfig matching the screen format"); EGLint r,g,b,a; @@ -224,7 +253,11 @@ void DisplayHardware::init(uint32_t dpy) * Gather OpenGL ES extensions */ - eglMakeCurrent(display, surface, surface, context); + result = eglMakeCurrent(display, surface, surface, context); + if (!result) { + LOGE("Couldn't create a working GLES context. check logs. exiting..."); + exit(0); + } GLExtensions& extensions(GLExtensions::getInstance()); extensions.initWithGLStrings( diff --git a/services/surfaceflinger/LayerBase.cpp b/services/surfaceflinger/LayerBase.cpp index bcd8c83..c86c659 100644 --- a/services/surfaceflinger/LayerBase.cpp +++ b/services/surfaceflinger/LayerBase.cpp @@ -228,13 +228,18 @@ void LayerBase::validateVisibility(const Transform& planeTransform) const Layer::State& s(drawingState()); const Transform tr(planeTransform * s.transform); const bool transformed = tr.transformed(); - + const DisplayHardware& hw(graphicPlane(0).displayHardware()); + const uint32_t hw_h = hw.getHeight(); + uint32_t w = s.w; uint32_t h = s.h; tr.transform(mVertices[0], 0, 0); tr.transform(mVertices[1], 0, h); tr.transform(mVertices[2], w, h); tr.transform(mVertices[3], w, 0); + for (size_t i=0 ; i<4 ; i++) + mVertices[i][1] = hw_h - mVertices[i][1]; + if (UNLIKELY(transformed)) { // NOTE: here we could also punt if we have too many rectangles // in the transparent region diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index cccab4a..b0881a4 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -276,7 +276,8 @@ status_t SurfaceFlinger::readyToRun() glViewport(0, 0, w, h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); - glOrthof(0, w, h, 0, 0, 1); + // put the origin in the left-bottom corner + glOrthof(0, w, 0, h, 0, 1); // l=0, r=w ; b=0, t=h mReadyToRunBarrier.open(); @@ -1791,7 +1792,7 @@ status_t SurfaceFlinger::electronBeamOffAnimationImplLocked() } GLfloat vtx[8]; - const GLfloat texCoords[4][2] = { {0,v}, {0,0}, {u,0}, {u,v} }; + const GLfloat texCoords[4][2] = { {0,1}, {0,1-v}, {u,1-v}, {u,1} }; glBindTexture(GL_TEXTURE_2D, tname); glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); @@ -1800,6 +1801,22 @@ status_t SurfaceFlinger::electronBeamOffAnimationImplLocked() glEnableClientState(GL_TEXTURE_COORD_ARRAY); glVertexPointer(2, GL_FLOAT, 0, vtx); + /* + * Texture coordinate mapping + * + * u + * 1 +----------+---+ + * | | | | image is inverted + * | V | | w.r.t. the texture + * 1-v +----------+ | coordinates + * | | + * | | + * | | + * 0 +--------------+ + * 0 1 + * + */ + class s_curve_interpolator { const float nbFrames, s, v; public: @@ -1824,10 +1841,10 @@ status_t SurfaceFlinger::electronBeamOffAnimationImplLocked() const GLfloat h = hw_h - (hw_h * v); const GLfloat x = (hw_w - w) * 0.5f; const GLfloat y = (hw_h - h) * 0.5f; - vtx[0] = x; vtx[1] = y + h; - vtx[2] = x; vtx[3] = y; - vtx[4] = x + w; vtx[5] = y; - vtx[6] = x + w; vtx[7] = y + h; + vtx[0] = x; vtx[1] = y; + vtx[2] = x; vtx[3] = y + h; + vtx[4] = x + w; vtx[5] = y + h; + vtx[6] = x + w; vtx[7] = y; } }; @@ -1842,15 +1859,20 @@ status_t SurfaceFlinger::electronBeamOffAnimationImplLocked() const GLfloat h = 1.0f; const GLfloat x = (hw_w - w) * 0.5f; const GLfloat y = (hw_h - h) * 0.5f; - vtx[0] = x; vtx[1] = y + h; - vtx[2] = x; vtx[3] = y; - vtx[4] = x + w; vtx[5] = y; - vtx[6] = x + w; vtx[7] = y + h; + vtx[0] = x; vtx[1] = y; + vtx[2] = x; vtx[3] = y + h; + vtx[4] = x + w; vtx[5] = y + h; + vtx[6] = x + w; vtx[7] = y; } }; // the full animation is 24 frames - const int nbFrames = 12; + char value[PROPERTY_VALUE_MAX]; + property_get("debug.sf.electron_frames", value, "24"); + int nbFrames = (atoi(value) + 1) >> 1; + if (nbFrames <= 0) // just in case + nbFrames = 24; + s_curve_interpolator itr(nbFrames, 7.5f); s_curve_interpolator itg(nbFrames, 8.0f); s_curve_interpolator itb(nbFrames, 8.5f); @@ -2225,10 +2247,11 @@ status_t SurfaceFlinger::captureScreenImplLocked(DisplayID dpy, // invert everything, b/c glReadPixel() below will invert the FB glViewport(0, 0, sw, sh); glScissor(0, 0, sw, sh); + glEnable(GL_SCISSOR_TEST); glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); - glOrthof(0, hw_w, 0, hw_h, 0, 1); + glOrthof(0, hw_w, hw_h, 0, 0, 1); glMatrixMode(GL_MODELVIEW); // redraw the screen entirely... @@ -2244,6 +2267,7 @@ status_t SurfaceFlinger::captureScreenImplLocked(DisplayID dpy, } // XXX: this is needed on tegra + glEnable(GL_SCISSOR_TEST); glScissor(0, 0, sw, sh); // check for errors and return screen capture diff --git a/services/tests/servicestests/res/raw/net_dev_typical b/services/tests/servicestests/res/raw/net_dev_typical new file mode 100644 index 0000000..290bf03 --- /dev/null +++ b/services/tests/servicestests/res/raw/net_dev_typical @@ -0,0 +1,8 @@ +Inter-| Receive | Transmit + face |bytes packets errs drop fifo frame compressed multicast|bytes packets errs drop fifo colls carrier compressed + lo: 8308 116 0 0 0 0 0 0 8308 116 0 0 0 0 0 0 +rmnet0: 1507570 2205 0 0 0 0 0 0 489339 2237 0 0 0 0 0 0 + ifb0: 52454 151 0 151 0 0 0 0 0 0 0 0 0 0 0 0 + ifb1: 52454 151 0 151 0 0 0 0 0 0 0 0 0 0 0 0 + sit0: 0 0 0 0 0 0 0 0 0 0 148 0 0 0 0 0 +ip6tnl0: 0 0 0 0 0 0 0 0 0 0 151 151 0 0 0 0 diff --git a/services/tests/servicestests/src/com/android/server/NetworkManagementServiceTest.java b/services/tests/servicestests/src/com/android/server/NetworkManagementServiceTest.java index ac7cb5a..56ef995 100644 --- a/services/tests/servicestests/src/com/android/server/NetworkManagementServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/NetworkManagementServiceTest.java @@ -16,6 +16,8 @@ package com.android.server; +import static android.net.NetworkStats.TAG_NONE; +import static android.net.NetworkStats.UID_ALL; import static com.android.server.NetworkManagementSocketTagger.kernelToTag; import static com.android.server.NetworkManagementSocketTagger.tagToKernel; @@ -25,9 +27,11 @@ import android.test.AndroidTestCase; import android.test.suitebuilder.annotation.LargeTest; import com.android.frameworks.servicestests.R; +import com.google.common.io.Files; import java.io.File; import java.io.FileOutputStream; +import java.io.FileWriter; import java.io.InputStream; import java.io.OutputStream; @@ -46,14 +50,23 @@ public class NetworkManagementServiceTest extends AndroidTestCase { public void setUp() throws Exception { super.setUp(); - mTestProc = getContext().getFilesDir(); - mService = NetworkManagementService.createForTest(mContext, mTestProc); + final File canonicalFilesDir = getContext().getFilesDir().getCanonicalFile(); + mTestProc = new File(canonicalFilesDir, "proc"); + if (mTestProc.exists()) { + Files.deleteRecursively(mTestProc); + } + + mService = NetworkManagementService.createForTest(mContext, mTestProc, true); } @Override public void tearDown() throws Exception { mService = null; + if (mTestProc.exists()) { + Files.deleteRecursively(mTestProc); + } + super.tearDown(); } @@ -61,7 +74,7 @@ public class NetworkManagementServiceTest extends AndroidTestCase { stageFile(R.raw.xt_qtaguid_typical, new File(mTestProc, "net/xt_qtaguid/stats")); final NetworkStats stats = mService.getNetworkStatsDetail(); - assertEquals(31, stats.size); + assertEquals(31, stats.size()); assertStatsEntry(stats, "wlan0", 0, 0, 14615L, 4270L); assertStatsEntry(stats, "wlan0", 10004, 0, 333821L, 53558L); assertStatsEntry(stats, "wlan0", 10004, 1947740890, 18725L, 1066L); @@ -73,11 +86,37 @@ public class NetworkManagementServiceTest extends AndroidTestCase { stageFile(R.raw.xt_qtaguid_extended, new File(mTestProc, "net/xt_qtaguid/stats")); final NetworkStats stats = mService.getNetworkStatsDetail(); - assertEquals(2, stats.size); + assertEquals(2, stats.size()); assertStatsEntry(stats, "test0", 1000, 0, 1024L, 2048L); assertStatsEntry(stats, "test0", 1000, 0xF00D, 512L, 512L); } + public void testNetworkStatsSummary() throws Exception { + stageFile(R.raw.net_dev_typical, new File(mTestProc, "net/dev")); + + final NetworkStats stats = mService.getNetworkStatsSummary(); + assertEquals(6, stats.size()); + assertStatsEntry(stats, "lo", UID_ALL, TAG_NONE, 8308L, 8308L); + assertStatsEntry(stats, "rmnet0", UID_ALL, TAG_NONE, 1507570L, 489339L); + assertStatsEntry(stats, "ifb0", UID_ALL, TAG_NONE, 52454L, 0L); + assertStatsEntry(stats, "ifb1", UID_ALL, TAG_NONE, 52454L, 0L); + assertStatsEntry(stats, "sit0", UID_ALL, TAG_NONE, 0L, 0L); + assertStatsEntry(stats, "ip6tnl0", UID_ALL, TAG_NONE, 0L, 0L); + } + + public void testNetworkStatsSummaryDown() throws Exception { + stageFile(R.raw.net_dev_typical, new File(mTestProc, "net/dev")); + stageLong(1024L, new File(mTestProc, "net/xt_qtaguid/iface_stat/wlan0/rx_bytes")); + stageLong(128L, new File(mTestProc, "net/xt_qtaguid/iface_stat/wlan0/rx_packets")); + stageLong(2048L, new File(mTestProc, "net/xt_qtaguid/iface_stat/wlan0/tx_bytes")); + stageLong(256L, new File(mTestProc, "net/xt_qtaguid/iface_stat/wlan0/tx_packets")); + + final NetworkStats stats = mService.getNetworkStatsSummary(); + assertEquals(7, stats.size()); + assertStatsEntry(stats, "rmnet0", UID_ALL, TAG_NONE, 1507570L, 489339L); + assertStatsEntry(stats, "wlan0", UID_ALL, TAG_NONE, 1024L, 2048L); + } + public void testKernelTags() throws Exception { assertEquals("0", tagToKernel(0x0)); assertEquals("214748364800", tagToKernel(0x32)); @@ -90,7 +129,6 @@ public class NetworkManagementServiceTest extends AndroidTestCase { assertEquals(2147483647, kernelToTag("0x7fffffff00000000")); assertEquals(0, kernelToTag("0x0000000000000000")); assertEquals(2147483136, kernelToTag("0x7FFFFE0000000000")); - } /** @@ -111,11 +149,23 @@ public class NetworkManagementServiceTest extends AndroidTestCase { } } + private void stageLong(long value, File file) throws Exception { + new File(file.getParent()).mkdirs(); + FileWriter out = null; + try { + out = new FileWriter(file); + out.write(Long.toString(value)); + } finally { + IoUtils.closeQuietly(out); + } + } + private static void assertStatsEntry( - NetworkStats stats, String iface, int uid, int tag, long rx, long tx) { + NetworkStats stats, String iface, int uid, int tag, long rxBytes, long txBytes) { final int i = stats.findIndex(iface, uid, tag); - assertEquals(rx, stats.rx[i]); - assertEquals(tx, stats.tx[i]); + final NetworkStats.Entry entry = stats.getValues(i, null); + assertEquals(rxBytes, entry.rxBytes); + assertEquals(txBytes, entry.txBytes); } } |