Search in sources :

Example 46 with BatteryStatsImpl

use of com.android.internal.os.BatteryStatsImpl in project android_frameworks_base by DirtyUnicorns.

the class ActivityManagerService method broadcastIntentLocked.

final int broadcastIntentLocked(ProcessRecord callerApp, String callerPackage, Intent intent, String resolvedType, IIntentReceiver resultTo, int resultCode, String resultData, Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions, boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
    intent = new Intent(intent);
    // By default broadcasts do not go to stopped apps.
    intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
    // If we have not finished booting, don't allow this to launch new processes.
    if (!mProcessesReady && (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
    }
    if (DEBUG_BROADCAST_LIGHT)
        Slog.v(TAG_BROADCAST, (sticky ? "Broadcast sticky: " : "Broadcast: ") + intent + " ordered=" + ordered + " userid=" + userId);
    if ((resultTo != null) && !ordered) {
        Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
    }
    userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true, ALLOW_NON_FULL, "broadcast", callerPackage);
    if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
        if ((callingUid != Process.SYSTEM_UID || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
            Slog.w(TAG, "Skipping broadcast of " + intent + ": user " + userId + " is stopped");
            return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
        }
    }
    BroadcastOptions brOptions = null;
    if (bOptions != null) {
        brOptions = new BroadcastOptions(bOptions);
        if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
            // PendingIntent), because that who is actually supplied the arguments.
            if (checkComponentPermission(android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST, Binder.getCallingPid(), Binder.getCallingUid(), -1, true) != PackageManager.PERMISSION_GRANTED) {
                String msg = "Permission Denial: " + intent.getAction() + " broadcast from " + callerPackage + " (pid=" + callingPid + ", uid=" + callingUid + ")" + " requires " + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
                Slog.w(TAG, msg);
                throw new SecurityException(msg);
            }
        }
    }
    // Verify that protected broadcasts are only being sent by system code,
    // and that system code is only sending protected broadcasts.
    final String action = intent.getAction();
    final boolean isProtectedBroadcast;
    try {
        isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
    } catch (RemoteException e) {
        Slog.w(TAG, "Remote exception", e);
        return ActivityManager.BROADCAST_SUCCESS;
    }
    final boolean isCallerSystem;
    switch(UserHandle.getAppId(callingUid)) {
        case Process.ROOT_UID:
        case Process.SYSTEM_UID:
        case Process.PHONE_UID:
        case Process.BLUETOOTH_UID:
        case Process.NFC_UID:
            isCallerSystem = true;
            break;
        default:
            isCallerSystem = (callerApp != null) && callerApp.persistent;
            break;
    }
    // sending protected broadcasts.
    if (!isCallerSystem) {
        if (isProtectedBroadcast) {
            String msg = "Permission Denial: not allowed to send broadcast " + action + " from pid=" + callingPid + ", uid=" + callingUid;
            Slog.w(TAG, msg);
            throw new SecurityException(msg);
        } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action) || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
            // just limit it to the caller.
            if (callerPackage == null) {
                String msg = "Permission Denial: not allowed to send broadcast " + action + " from unknown caller.";
                Slog.w(TAG, msg);
                throw new SecurityException(msg);
            } else if (intent.getComponent() != null) {
                // it is being sent to the calling app.
                if (!intent.getComponent().getPackageName().equals(callerPackage)) {
                    String msg = "Permission Denial: not allowed to send broadcast " + action + " to " + intent.getComponent().getPackageName() + " from " + callerPackage;
                    Slog.w(TAG, msg);
                    throw new SecurityException(msg);
                }
            } else {
                // Limit broadcast to their own package.
                intent.setPackage(callerPackage);
            }
        }
    }
    if (action != null) {
        switch(action) {
            case Intent.ACTION_UID_REMOVED:
            case Intent.ACTION_PACKAGE_REMOVED:
            case Intent.ACTION_PACKAGE_CHANGED:
            case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
            case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
            case Intent.ACTION_PACKAGES_SUSPENDED:
            case Intent.ACTION_PACKAGES_UNSUSPENDED:
                // its activities from the history stack.
                if (checkComponentPermission(android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
                    String msg = "Permission Denial: " + intent.getAction() + " broadcast from " + callerPackage + " (pid=" + callingPid + ", uid=" + callingUid + ")" + " requires " + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
                    Slog.w(TAG, msg);
                    throw new SecurityException(msg);
                }
                switch(action) {
                    case Intent.ACTION_UID_REMOVED:
                        final Bundle intentExtras = intent.getExtras();
                        final int uid = intentExtras != null ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
                        if (uid >= 0) {
                            mBatteryStatsService.removeUid(uid);
                            mAppOpsService.uidRemoved(uid);
                        }
                        break;
                    case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
                        // If resources are unavailable just force stop all those packages
                        // and flush the attribute cache as well.
                        String[] list = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
                        if (list != null && list.length > 0) {
                            for (int i = 0; i < list.length; i++) {
                                forceStopPackageLocked(list[i], -1, false, true, true, false, false, userId, "storage unmount");
                            }
                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
                            sendPackageBroadcastLocked(IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
                        }
                        break;
                    case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
                        mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
                        break;
                    case Intent.ACTION_PACKAGE_REMOVED:
                    case Intent.ACTION_PACKAGE_CHANGED:
                        Uri data = intent.getData();
                        String ssp;
                        if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
                            final boolean replacing = intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
                            final boolean killProcess = !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
                            final boolean fullUninstall = removed && !replacing;
                            if (removed) {
                                if (killProcess) {
                                    forceStopPackageLocked(ssp, UserHandle.getAppId(intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true, false, fullUninstall, userId, removed ? "pkg removed" : "pkg changed");
                                }
                                final int cmd = killProcess ? IApplicationThread.PACKAGE_REMOVED : IApplicationThread.PACKAGE_REMOVED_DONT_KILL;
                                sendPackageBroadcastLocked(cmd, new String[] { ssp }, userId);
                                if (fullUninstall) {
                                    mAppOpsService.packageRemoved(intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
                                    // Remove all permissions granted from/to this package
                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
                                    removeTasksByPackageNameLocked(ssp, userId);
                                    // Hide the "unsupported display" dialog if necessary.
                                    if (mUnsupportedDisplaySizeDialog != null && ssp.equals(mUnsupportedDisplaySizeDialog.getPackageName())) {
                                        mUnsupportedDisplaySizeDialog.dismiss();
                                        mUnsupportedDisplaySizeDialog = null;
                                    }
                                    mCompatModePackages.handlePackageUninstalledLocked(ssp);
                                    mBatteryStatsService.notePackageUninstalled(ssp);
                                }
                            } else {
                                if (killProcess) {
                                    killPackageProcessesLocked(ssp, UserHandle.getAppId(intent.getIntExtra(Intent.EXTRA_UID, -1)), userId, ProcessList.INVALID_ADJ, false, true, true, false, "change " + ssp);
                                }
                                cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess, intent.getStringArrayExtra(Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
                            }
                        }
                        break;
                    case Intent.ACTION_PACKAGES_SUSPENDED:
                    case Intent.ACTION_PACKAGES_UNSUSPENDED:
                        final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(intent.getAction());
                        final String[] packageNames = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
                        final int userHandle = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
                        synchronized (ActivityManagerService.this) {
                            mRecentTasks.onPackagesSuspendedChanged(packageNames, suspended, userHandle);
                        }
                        break;
                }
                break;
            case Intent.ACTION_PACKAGE_REPLACED:
                {
                    final Uri data = intent.getData();
                    final String ssp;
                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
                        final ApplicationInfo aInfo = getPackageManagerInternalLocked().getApplicationInfo(ssp, userId);
                        if (aInfo == null) {
                            Slog.w(TAG, "Dropping ACTION_PACKAGE_REPLACED for non-existent pkg:" + " ssp=" + ssp + " data=" + data);
                            return ActivityManager.BROADCAST_SUCCESS;
                        }
                        mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
                        sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REPLACED, new String[] { ssp }, userId);
                    }
                    break;
                }
            case Intent.ACTION_PACKAGE_ADDED:
                {
                    // Special case for adding a package: by default turn on compatibility mode.
                    Uri data = intent.getData();
                    String ssp;
                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
                        final boolean replacing = intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
                        try {
                            ApplicationInfo ai = AppGlobals.getPackageManager().getApplicationInfo(ssp, 0, 0);
                            mBatteryStatsService.notePackageInstalled(ssp, ai != null ? ai.versionCode : 0);
                        } catch (RemoteException e) {
                        }
                    }
                    break;
                }
            case Intent.ACTION_PACKAGE_DATA_CLEARED:
                {
                    Uri data = intent.getData();
                    String ssp;
                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
                        // Hide the "unsupported display" dialog if necessary.
                        if (mUnsupportedDisplaySizeDialog != null && ssp.equals(mUnsupportedDisplaySizeDialog.getPackageName())) {
                            mUnsupportedDisplaySizeDialog.dismiss();
                            mUnsupportedDisplaySizeDialog = null;
                        }
                        mCompatModePackages.handlePackageDataClearedLocked(ssp);
                    }
                    break;
                }
            case Intent.ACTION_TIMEZONE_CHANGED:
                // If this is the time zone changed action, queue up a message that will reset
                // the timezone of all currently running processes. This message will get
                // queued up before the broadcast happens.
                mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
                break;
            case Intent.ACTION_TIME_CHANGED:
                // If the user set the time, let all running processes know.
                final int is24Hour = intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
                mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
                synchronized (stats) {
                    stats.noteCurrentTimeChangedLocked();
                }
                break;
            case Intent.ACTION_CLEAR_DNS_CACHE:
                mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
                break;
            case Proxy.PROXY_CHANGE_ACTION:
                ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
                mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
                break;
            case android.hardware.Camera.ACTION_NEW_PICTURE:
            case android.hardware.Camera.ACTION_NEW_VIDEO:
                // These broadcasts are no longer allowed by the system, since they can
                // cause significant thrashing at a crictical point (using the camera).
                // Apps should use JobScehduler to monitor for media provider changes.
                Slog.w(TAG, action + " no longer allowed; dropping from " + UserHandle.formatUid(callingUid));
                if (resultTo != null) {
                    final BroadcastQueue queue = broadcastQueueForIntent(intent);
                    try {
                        queue.performReceiveLocked(callerApp, resultTo, intent, Activity.RESULT_CANCELED, null, null, false, false, userId);
                    } catch (RemoteException e) {
                        Slog.w(TAG, "Failure [" + queue.mQueueName + "] sending broadcast result of " + intent, e);
                    }
                }
                // Lie; we don't want to crash the app.
                return ActivityManager.BROADCAST_SUCCESS;
        }
    }
    // Add to the sticky list if requested.
    if (sticky) {
        if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, callingPid, callingUid) != PackageManager.PERMISSION_GRANTED) {
            String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" + callingPid + ", uid=" + callingUid + " requires " + android.Manifest.permission.BROADCAST_STICKY;
            Slog.w(TAG, msg);
            throw new SecurityException(msg);
        }
        if (requiredPermissions != null && requiredPermissions.length > 0) {
            Slog.w(TAG, "Can't broadcast sticky intent " + intent + " and enforce permissions " + Arrays.toString(requiredPermissions));
            return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
        }
        if (intent.getComponent() != null) {
            throw new SecurityException("Sticky broadcasts can't target a specific component");
        }
        // as a separate set of sticky broadcasts.
        if (userId != UserHandle.USER_ALL) {
            // But first, if this is not a broadcast to all users, then
            // make sure it doesn't conflict with an existing broadcast to
            // all users.
            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(UserHandle.USER_ALL);
            if (stickies != null) {
                ArrayList<Intent> list = stickies.get(intent.getAction());
                if (list != null) {
                    int N = list.size();
                    int i;
                    for (i = 0; i < N; i++) {
                        if (intent.filterEquals(list.get(i))) {
                            throw new IllegalArgumentException("Sticky broadcast " + intent + " for user " + userId + " conflicts with existing global broadcast");
                        }
                    }
                }
            }
        }
        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
        if (stickies == null) {
            stickies = new ArrayMap<>();
            mStickyBroadcasts.put(userId, stickies);
        }
        ArrayList<Intent> list = stickies.get(intent.getAction());
        if (list == null) {
            list = new ArrayList<>();
            stickies.put(intent.getAction(), list);
        }
        final int stickiesCount = list.size();
        int i;
        for (i = 0; i < stickiesCount; i++) {
            if (intent.filterEquals(list.get(i))) {
                // This sticky already exists, replace it.
                list.set(i, new Intent(intent));
                break;
            }
        }
        if (i >= stickiesCount) {
            list.add(new Intent(intent));
        }
    }
    int[] users;
    if (userId == UserHandle.USER_ALL) {
        // Caller wants broadcast to go to all started users.
        users = mUserController.getStartedUserArrayLocked();
    } else {
        // Caller wants broadcast to go to one specific user.
        users = new int[] { userId };
    }
    // Figure out who all will receive this broadcast.
    List receivers = null;
    List<BroadcastFilter> registeredReceivers = null;
    // Need to resolve the intent to interested receivers...
    if ((intent.getFlags() & Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
        receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
    }
    if (intent.getComponent() == null) {
        if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
            // Query one target user at a time, excluding shell-restricted users
            for (int i = 0; i < users.length; i++) {
                if (mUserController.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
                    continue;
                }
                List<BroadcastFilter> registeredReceiversForUser = mReceiverResolver.queryIntent(intent, resolvedType, false, users[i]);
                if (registeredReceivers == null) {
                    registeredReceivers = registeredReceiversForUser;
                } else if (registeredReceiversForUser != null) {
                    registeredReceivers.addAll(registeredReceiversForUser);
                }
            }
        } else {
            registeredReceivers = mReceiverResolver.queryIntent(intent, resolvedType, false, userId);
        }
    }
    final boolean replacePending = (intent.getFlags() & Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
    if (DEBUG_BROADCAST)
        Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction() + " replacePending=" + replacePending);
    int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
    if (!ordered && NR > 0) {
        // components to be launched.
        if (isCallerSystem) {
            checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid, isProtectedBroadcast, registeredReceivers);
        }
        final BroadcastQueue queue = broadcastQueueForIntent(intent);
        BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, callerPackage, callingPid, callingUid, resolvedType, requiredPermissions, appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData, resultExtras, ordered, sticky, false, userId);
        if (DEBUG_BROADCAST)
            Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
        final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
        if (!replaced) {
            queue.enqueueParallelBroadcastLocked(r);
            queue.scheduleBroadcastsLocked();
        }
        registeredReceivers = null;
        NR = 0;
    }
    // Merge into one list.
    int ir = 0;
    if (receivers != null) {
        // A special case for PACKAGE_ADDED: do not allow the package
        // being added to see this broadcast.  This prevents them from
        // using this as a back door to get run as soon as they are
        // installed.  Maybe in the future we want to have a special install
        // broadcast or such for apps, but we'd like to deliberately make
        // this decision.
        String[] skipPackages = null;
        if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
            Uri data = intent.getData();
            if (data != null) {
                String pkgName = data.getSchemeSpecificPart();
                if (pkgName != null) {
                    skipPackages = new String[] { pkgName };
                }
            }
        } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
            skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
        }
        if (skipPackages != null && (skipPackages.length > 0)) {
            for (String skipPackage : skipPackages) {
                if (skipPackage != null) {
                    int NT = receivers.size();
                    for (int it = 0; it < NT; it++) {
                        ResolveInfo curt = (ResolveInfo) receivers.get(it);
                        if (curt.activityInfo.packageName.equals(skipPackage)) {
                            receivers.remove(it);
                            it--;
                            NT--;
                        }
                    }
                }
            }
        }
        int NT = receivers != null ? receivers.size() : 0;
        int it = 0;
        ResolveInfo curt = null;
        BroadcastFilter curr = null;
        while (it < NT && ir < NR) {
            if (curt == null) {
                curt = (ResolveInfo) receivers.get(it);
            }
            if (curr == null) {
                curr = registeredReceivers.get(ir);
            }
            if (curr.getPriority() >= curt.priority) {
                // Insert this broadcast record into the final list.
                receivers.add(it, curr);
                ir++;
                curr = null;
                it++;
                NT++;
            } else {
                // Skip to the next ResolveInfo in the final list.
                it++;
                curt = null;
            }
        }
    }
    while (ir < NR) {
        if (receivers == null) {
            receivers = new ArrayList();
        }
        receivers.add(registeredReceivers.get(ir));
        ir++;
    }
    if (isCallerSystem) {
        checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid, isProtectedBroadcast, receivers);
    }
    if ((receivers != null && receivers.size() > 0) || resultTo != null) {
        BroadcastQueue queue = broadcastQueueForIntent(intent);
        BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, callerPackage, callingPid, callingUid, resolvedType, requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode, resultData, resultExtras, ordered, sticky, false, userId);
        if (DEBUG_BROADCAST)
            Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r + ": prev had " + queue.mOrderedBroadcasts.size());
        if (DEBUG_BROADCAST)
            Slog.i(TAG_BROADCAST, "Enqueueing broadcast " + r.intent.getAction());
        boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
        if (!replaced) {
            queue.enqueueOrderedBroadcastLocked(r);
            queue.scheduleBroadcastsLocked();
        }
    } else {
        // that it happened.
        if (intent.getComponent() == null && intent.getPackage() == null && (intent.getFlags() & Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
            // This was an implicit broadcast... let's record it for posterity.
            addBroadcastStatLocked(intent.getAction(), callerPackage, 0, 0, 0);
        }
    }
    return ActivityManager.BROADCAST_SUCCESS;
}
Also used : ApplicationInfo(android.content.pm.ApplicationInfo) ArrayList(java.util.ArrayList) Uri(android.net.Uri) ResolveInfo(android.content.pm.ResolveInfo) ProxyInfo(android.net.ProxyInfo) RemoteCallbackList(android.os.RemoteCallbackList) ArrayList(java.util.ArrayList) List(java.util.List) LocaleList(android.os.LocaleList) Bundle(android.os.Bundle) PersistableBundle(android.os.PersistableBundle) PendingIntent(android.app.PendingIntent) Intent(android.content.Intent) BatteryStatsImpl(com.android.internal.os.BatteryStatsImpl) Point(android.graphics.Point) BroadcastOptions(android.app.BroadcastOptions) RemoteException(android.os.RemoteException)

Example 47 with BatteryStatsImpl

use of com.android.internal.os.BatteryStatsImpl in project android_frameworks_base by DirtyUnicorns.

the class ActivityManagerService method newProcessRecordLocked.

// =========================================================
// GLOBAL MANAGEMENT
// =========================================================
final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, boolean isolated, int isolatedUid) {
    String proc = customProcess != null ? customProcess : info.processName;
    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
    final int userId = UserHandle.getUserId(info.uid);
    int uid = info.uid;
    if (isolated) {
        if (isolatedUid == 0) {
            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
            while (true) {
                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
                }
                uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
                mNextIsolatedProcessUid++;
                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
                    // No process for this uid, use it.
                    break;
                }
                stepsLeft--;
                if (stepsLeft <= 0) {
                    return null;
                }
            }
        } else {
            // Special case for startIsolatedProcess (internal only), where
            // the uid of the isolated process is specified by the caller.
            uid = isolatedUid;
        }
        // Register the isolated UID with this application so BatteryStats knows to
        // attribute resource usage to the application.
        //
        // NOTE: This is done here before addProcessNameLocked, which will tell BatteryStats
        // about the process state of the isolated UID *before* it is registered with the
        // owning application.
        mBatteryStatsService.addIsolatedUid(uid, info.uid);
    }
    final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
    if (!mBooted && !mBooting && userId == UserHandle.USER_SYSTEM && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
        r.persistent = true;
        r.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
    }
    addProcessNameLocked(r);
    return r;
}
Also used : BatteryStatsImpl(com.android.internal.os.BatteryStatsImpl) Point(android.graphics.Point)

Example 48 with BatteryStatsImpl

use of com.android.internal.os.BatteryStatsImpl in project android_frameworks_base by DirtyUnicorns.

the class ActivityStack method completePauseLocked.

private void completePauseLocked(boolean resumeNext, ActivityRecord resuming) {
    ActivityRecord prev = mPausingActivity;
    if (DEBUG_PAUSE)
        Slog.v(TAG_PAUSE, "Complete pause: " + prev);
    if (prev != null) {
        final boolean wasStopping = prev.state == ActivityState.STOPPING;
        prev.state = ActivityState.PAUSED;
        if (prev.finishing) {
            if (DEBUG_PAUSE)
                Slog.v(TAG_PAUSE, "Executing finish of activity: " + prev);
            prev = finishCurrentActivityLocked(prev, FINISH_AFTER_VISIBLE, false);
        } else if (prev.app != null) {
            if (DEBUG_PAUSE)
                Slog.v(TAG_PAUSE, "Enqueue pending stop if needed: " + prev + " wasStopping=" + wasStopping + " visible=" + prev.visible);
            if (mStackSupervisor.mWaitingVisibleActivities.remove(prev)) {
                if (DEBUG_SWITCH || DEBUG_PAUSE)
                    Slog.v(TAG_PAUSE, "Complete pause, no longer waiting: " + prev);
            }
            if (prev.deferRelaunchUntilPaused) {
                // Complete the deferred relaunch that was waiting for pause to complete.
                if (DEBUG_PAUSE)
                    Slog.v(TAG_PAUSE, "Re-launching after pause: " + prev);
                relaunchActivityLocked(prev, prev.configChangeFlags, false, prev.preserveWindowOnDeferredRelaunch);
            } else if (wasStopping) {
                // We are also stopping, the stop request must have gone soon after the pause.
                // We can't clobber it, because the stop confirmation will not be handled.
                // We don't need to schedule another stop, we only need to let it happen.
                prev.state = ActivityState.STOPPING;
            } else if ((!prev.visible && !hasVisibleBehindActivity()) || mService.isSleepingOrShuttingDownLocked()) {
                // If we were visible then resumeTopActivities will release resources before
                // stopping.
                addToStopping(prev, true);
            }
        } else {
            if (DEBUG_PAUSE)
                Slog.v(TAG_PAUSE, "App died during pause, not stopping: " + prev);
            prev = null;
        }
        // since it is no longer visible.
        if (prev != null) {
            prev.stopFreezingScreenLocked(true);
        }
        mPausingActivity = null;
    }
    if (resumeNext) {
        final ActivityStack topStack = mStackSupervisor.getFocusedStack();
        if (!mService.isSleepingOrShuttingDownLocked()) {
            mStackSupervisor.resumeFocusedStackTopActivityLocked(topStack, prev, null);
        } else {
            mStackSupervisor.checkReadyForSleepLocked();
            ActivityRecord top = topStack.topRunningActivityLocked();
            if (top == null || (prev != null && top != prev)) {
                // If there are no more activities available to run, do resume anyway to start
                // something. Also if the top activity on the stack is not the just paused
                // activity, we need to go ahead and resume it to ensure we complete an
                // in-flight app switch.
                mStackSupervisor.resumeFocusedStackTopActivityLocked();
            }
        }
    }
    if (prev != null) {
        prev.resumeKeyDispatchingLocked();
        if (prev.app != null && prev.cpuTimeAtResume > 0 && mService.mBatteryStatsService.isOnBattery()) {
            long diff = mService.mProcessCpuTracker.getCpuTimeForPid(prev.app.pid) - prev.cpuTimeAtResume;
            if (diff > 0) {
                BatteryStatsImpl bsi = mService.mBatteryStatsService.getActiveStatistics();
                synchronized (bsi) {
                    BatteryStatsImpl.Uid.Proc ps = bsi.getProcessStatsLocked(prev.info.applicationInfo.uid, prev.info.packageName);
                    if (ps != null) {
                        ps.addForegroundTimeLocked(diff);
                    }
                }
            }
        }
        // reset it
        prev.cpuTimeAtResume = 0;
    }
    // task stack changes, because its positioning may depend on it.
    if (mStackSupervisor.mAppVisibilitiesChangedSinceLastPause || mService.mStackSupervisor.getStack(PINNED_STACK_ID) != null) {
        mService.notifyTaskStackChangedLocked();
        mStackSupervisor.mAppVisibilitiesChangedSinceLastPause = false;
    }
    mStackSupervisor.ensureActivitiesVisibleLocked(resuming, 0, !PRESERVE_WINDOWS);
}
Also used : BatteryStatsImpl(com.android.internal.os.BatteryStatsImpl)

Example 49 with BatteryStatsImpl

use of com.android.internal.os.BatteryStatsImpl in project android_frameworks_base by DirtyUnicorns.

the class ActivityManagerService method noteWakeupAlarm.

public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
    if (sender != null && !(sender instanceof PendingIntentRecord)) {
        return;
    }
    final PendingIntentRecord rec = (PendingIntentRecord) sender;
    final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
    synchronized (stats) {
        if (mBatteryStatsService.isOnBattery()) {
            mBatteryStatsService.enforceCallingPermission();
            int MY_UID = Binder.getCallingUid();
            final int uid;
            if (sender == null) {
                uid = sourceUid;
            } else {
                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
            }
            BatteryStatsImpl.Uid.Pkg pkg = stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid, sourcePkg != null ? sourcePkg : rec.key.packageName);
            pkg.noteWakeupAlarmLocked(tag);
        }
    }
}
Also used : BatteryStatsImpl(com.android.internal.os.BatteryStatsImpl) Point(android.graphics.Point)

Example 50 with BatteryStatsImpl

use of com.android.internal.os.BatteryStatsImpl in project android_frameworks_base by DirtyUnicorns.

the class ActivityManagerService method updateCpuStatsNow.

void updateCpuStatsNow() {
    synchronized (mProcessCpuTracker) {
        mProcessCpuMutexFree.set(false);
        final long now = SystemClock.uptimeMillis();
        boolean haveNewCpuStats = false;
        if (MONITOR_CPU_USAGE && mLastCpuTime.get() < (now - MONITOR_CPU_MIN_TIME)) {
            mLastCpuTime.set(now);
            mProcessCpuTracker.update();
            if (mProcessCpuTracker.hasGoodLastStats()) {
                haveNewCpuStats = true;
                // Slog the cpu usage if the property is set.
                if ("true".equals(SystemProperties.get("events.cpu"))) {
                    int user = mProcessCpuTracker.getLastUserTime();
                    int system = mProcessCpuTracker.getLastSystemTime();
                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
                    int irq = mProcessCpuTracker.getLastIrqTime();
                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
                    int idle = mProcessCpuTracker.getLastIdleTime();
                    int total = user + system + iowait + irq + softIrq + idle;
                    if (total == 0)
                        total = 1;
                    EventLog.writeEvent(EventLogTags.CPU, ((user + system + iowait + irq + softIrq) * 100) / total, (user * 100) / total, (system * 100) / total, (iowait * 100) / total, (irq * 100) / total, (softIrq * 100) / total);
                }
            }
        }
        final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
        synchronized (bstats) {
            synchronized (mPidsSelfLocked) {
                if (haveNewCpuStats) {
                    if (bstats.startAddingCpuLocked()) {
                        int totalUTime = 0;
                        int totalSTime = 0;
                        final int N = mProcessCpuTracker.countStats();
                        for (int i = 0; i < N; i++) {
                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
                            if (!st.working) {
                                continue;
                            }
                            ProcessRecord pr = mPidsSelfLocked.get(st.pid);
                            totalUTime += st.rel_utime;
                            totalSTime += st.rel_stime;
                            if (pr != null) {
                                BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
                                if (ps == null || !ps.isActive()) {
                                    pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(pr.info.uid, pr.processName);
                                }
                                ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
                                pr.curCpuTime += st.rel_utime + st.rel_stime;
                            } else {
                                BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
                                if (ps == null || !ps.isActive()) {
                                    st.batteryStats = ps = bstats.getProcessStatsLocked(bstats.mapUid(st.uid), st.name);
                                }
                                ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
                            }
                        }
                        final int userTime = mProcessCpuTracker.getLastUserTime();
                        final int systemTime = mProcessCpuTracker.getLastSystemTime();
                        final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
                        final int irqTime = mProcessCpuTracker.getLastIrqTime();
                        final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
                        final int idleTime = mProcessCpuTracker.getLastIdleTime();
                        bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime, systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
                    }
                }
            }
            if (mLastWriteTime < (now - BATTERY_STATS_TIME)) {
                mLastWriteTime = now;
                mBatteryStatsService.scheduleWriteToDisk();
            }
        }
    }
}
Also used : ProcessCpuTracker(com.android.internal.os.ProcessCpuTracker) BatteryStatsImpl(com.android.internal.os.BatteryStatsImpl) Point(android.graphics.Point)

Aggregations

BatteryStatsImpl (com.android.internal.os.BatteryStatsImpl)62 RemoteException (android.os.RemoteException)19 Point (android.graphics.Point)18 ComponentName (android.content.ComponentName)15 ApplicationInfo (android.content.pm.ApplicationInfo)14 PendingIntent (android.app.PendingIntent)11 Intent (android.content.Intent)11 ResolveInfo (android.content.pm.ResolveInfo)11 IOException (java.io.IOException)9 ArrayList (java.util.ArrayList)8 PackageManager (android.content.pm.PackageManager)7 ServiceInfo (android.content.pm.ServiceInfo)7 NameNotFoundException (android.content.pm.PackageManager.NameNotFoundException)6 Parcel (android.os.Parcel)5 ParcelFormatException (android.os.ParcelFormatException)5 ActivityNotFoundException (android.content.ActivityNotFoundException)4 IPackageManager (android.content.pm.IPackageManager)4 Uri (android.net.Uri)4 Bundle (android.os.Bundle)4 RemoteCallbackList (android.os.RemoteCallbackList)4