use of android.content.pm.ActivityInfo in project android_frameworks_base by ParanoidAndroid.
the class ActivityManagerService method systemReady.
public void systemReady(final Runnable goingCallback) {
synchronized (this) {
if (mSystemReady) {
if (goingCallback != null)
goingCallback.run();
return;
}
// Check to see if there are any update receivers to run.
if (!mDidUpdate) {
if (mWaitingUpdate) {
return;
}
Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
List<ResolveInfo> ris = null;
try {
ris = AppGlobals.getPackageManager().queryIntentReceivers(intent, null, 0, 0);
} catch (RemoteException e) {
}
if (ris != null) {
for (int i = ris.size() - 1; i >= 0; i--) {
if ((ris.get(i).activityInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
ris.remove(i);
}
}
intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
for (int i = 0; i < ris.size(); i++) {
ActivityInfo ai = ris.get(i).activityInfo;
ComponentName comp = new ComponentName(ai.packageName, ai.name);
if (lastDoneReceivers.contains(comp)) {
ris.remove(i);
i--;
}
}
final int[] users = getUsersLocked();
for (int i = 0; i < ris.size(); i++) {
ActivityInfo ai = ris.get(i).activityInfo;
ComponentName comp = new ComponentName(ai.packageName, ai.name);
doneReceivers.add(comp);
intent.setComponent(comp);
for (int j = 0; j < users.length; j++) {
IIntentReceiver finisher = null;
if (i == ris.size() - 1 && j == users.length - 1) {
finisher = new IIntentReceiver.Stub() {
public void performReceive(Intent intent, int resultCode, String data, Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
// The raw IIntentReceiver interface is called
// with the AM lock held, so redispatch to
// execute our code without the lock.
mHandler.post(new Runnable() {
public void run() {
synchronized (ActivityManagerService.this) {
mDidUpdate = true;
}
writeLastDonePreBootReceivers(doneReceivers);
showBootMessage(mContext.getText(R.string.android_upgrading_complete), false);
systemReady(goingCallback);
}
});
}
};
}
Slog.i(TAG, "Sending system update to " + intent.getComponent() + " for user " + users[j]);
broadcastIntentLocked(null, null, intent, null, finisher, 0, null, null, null, AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, users[j]);
if (finisher != null) {
mWaitingUpdate = true;
}
}
}
}
if (mWaitingUpdate) {
return;
}
mDidUpdate = true;
}
mAppOpsService.systemReady();
mSystemReady = true;
if (!mStartRunning) {
return;
}
}
ArrayList<ProcessRecord> procsToKill = null;
synchronized (mPidsSelfLocked) {
for (int i = mPidsSelfLocked.size() - 1; i >= 0; i--) {
ProcessRecord proc = mPidsSelfLocked.valueAt(i);
if (!isAllowedWhileBooting(proc.info)) {
if (procsToKill == null) {
procsToKill = new ArrayList<ProcessRecord>();
}
procsToKill.add(proc);
}
}
}
synchronized (this) {
if (procsToKill != null) {
for (int i = procsToKill.size() - 1; i >= 0; i--) {
ProcessRecord proc = procsToKill.get(i);
Slog.i(TAG, "Removing system update proc: " + proc);
removeProcessLocked(proc, true, false, "system update done");
}
}
// Now that we have cleaned up any update processes, we
// are ready to start launching real processes and know that
// we won't trample on them any more.
mProcessesReady = true;
}
Slog.i(TAG, "System now ready");
EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, SystemClock.uptimeMillis());
synchronized (this) {
if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) {
ResolveInfo ri = mContext.getPackageManager().resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), STOCK_PM_FLAGS);
CharSequence errorMsg = null;
if (ri != null) {
ActivityInfo ai = ri.activityInfo;
ApplicationInfo app = ai.applicationInfo;
if ((app.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
mTopAction = Intent.ACTION_FACTORY_TEST;
mTopData = null;
mTopComponent = new ComponentName(app.packageName, ai.name);
} else {
errorMsg = mContext.getResources().getText(com.android.internal.R.string.factorytest_not_system);
}
} else {
errorMsg = mContext.getResources().getText(com.android.internal.R.string.factorytest_no_action);
}
if (errorMsg != null) {
mTopAction = null;
mTopData = null;
mTopComponent = null;
Message msg = Message.obtain();
msg.what = SHOW_FACTORY_ERROR_MSG;
msg.getData().putCharSequence("msg", errorMsg);
mHandler.sendMessage(msg);
}
}
}
retrieveSettings();
if (goingCallback != null)
goingCallback.run();
synchronized (this) {
if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
try {
List apps = AppGlobals.getPackageManager().getPersistentApplications(STOCK_PM_FLAGS);
if (apps != null) {
int N = apps.size();
int i;
for (i = 0; i < N; i++) {
ApplicationInfo info = (ApplicationInfo) apps.get(i);
if (info != null && !info.packageName.equals("android")) {
addAppLocked(info, false);
}
}
}
} catch (RemoteException ex) {
// pm is in same process, this will never happen.
}
}
// Start up initial activity.
mBooting = true;
try {
if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
Message msg = Message.obtain();
msg.what = SHOW_UID_ERROR_MSG;
mHandler.sendMessage(msg);
}
} catch (RemoteException e) {
}
long ident = Binder.clearCallingIdentity();
try {
Intent intent = new Intent(Intent.ACTION_USER_STARTED);
intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_FOREGROUND);
intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
intent = new Intent(Intent.ACTION_USER_STARTING);
intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
broadcastIntentLocked(null, null, intent, null, new IIntentReceiver.Stub() {
@Override
public void performReceive(Intent intent, int resultCode, String data, Bundle extras, boolean ordered, boolean sticky, int sendingUser) throws RemoteException {
}
}, 0, null, null, android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
} finally {
Binder.restoreCallingIdentity(ident);
}
mMainStack.resumeTopActivityLocked(null);
sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
}
}
use of android.content.pm.ActivityInfo in project android_frameworks_base by ParanoidAndroid.
the class ActivityManagerService method startNextMatchingActivity.
public boolean startNextMatchingActivity(IBinder callingActivity, Intent intent, Bundle options) {
// Refuse possible leaked file descriptors
if (intent != null && intent.hasFileDescriptors() == true) {
throw new IllegalArgumentException("File descriptors passed in Intent");
}
synchronized (this) {
ActivityRecord r = mMainStack.isInStackLocked(callingActivity);
if (r == null) {
ActivityOptions.abort(options);
return false;
}
if (r.app == null || r.app.thread == null) {
// The caller is not running... d'oh!
ActivityOptions.abort(options);
return false;
}
intent = new Intent(intent);
// The caller is not allowed to change the data.
intent.setDataAndType(r.intent.getData(), r.intent.getType());
// And we are resetting to find the next component...
intent.setComponent(null);
ActivityInfo aInfo = null;
try {
List<ResolveInfo> resolves = AppGlobals.getPackageManager().queryIntentActivities(intent, r.resolvedType, PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, UserHandle.getCallingUserId());
// Look for the original activity in the list...
final int N = resolves != null ? resolves.size() : 0;
for (int i = 0; i < N; i++) {
ResolveInfo rInfo = resolves.get(i);
if (rInfo.activityInfo.packageName.equals(r.packageName) && rInfo.activityInfo.name.equals(r.info.name)) {
// We found the current one... the next matching is
// after it.
i++;
if (i < N) {
aInfo = resolves.get(i).activityInfo;
}
break;
}
}
} catch (RemoteException e) {
}
if (aInfo == null) {
// Nobody who is next!
ActivityOptions.abort(options);
return false;
}
intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
intent.setFlags(intent.getFlags() & ~(Intent.FLAG_ACTIVITY_FORWARD_RESULT | Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_MULTIPLE_TASK | Intent.FLAG_ACTIVITY_NEW_TASK));
// Okay now we need to start the new activity, replacing the
// currently running activity. This is a little tricky because
// we want to start the new one as if the current one is finished,
// but not finish the current one first so that there is no flicker.
// And thus...
final boolean wasFinishing = r.finishing;
r.finishing = true;
// Propagate reply information over to the new activity.
final ActivityRecord resultTo = r.resultTo;
final String resultWho = r.resultWho;
final int requestCode = r.requestCode;
r.resultTo = null;
if (resultTo != null) {
resultTo.removeResultsLocked(r, resultWho, requestCode);
}
final long origId = Binder.clearCallingIdentity();
int res = mMainStack.startActivityLocked(r.app.thread, intent, r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0, options, false, null);
Binder.restoreCallingIdentity(origId);
r.finishing = wasFinishing;
if (res != ActivityManager.START_SUCCESS) {
return false;
}
return true;
}
}
use of android.content.pm.ActivityInfo in project android_frameworks_base by ParanoidAndroid.
the class ActivityManagerService method navigateUpTo.
public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, Intent resultData) {
ComponentName dest = destIntent.getComponent();
synchronized (this) {
ActivityRecord srec = ActivityRecord.forToken(token);
if (srec == null) {
return false;
}
ArrayList<ActivityRecord> history = srec.stack.mHistory;
final int start = history.indexOf(srec);
if (start < 0) {
// Current activity is not in history stack; do nothing.
return false;
}
int finishTo = start - 1;
ActivityRecord parent = null;
boolean foundParentInTask = false;
if (dest != null) {
TaskRecord tr = srec.task;
for (int i = start - 1; i >= 0; i--) {
ActivityRecord r = history.get(i);
if (tr != r.task) {
// Couldn't find parent in the same task; stop at the one above this.
// (Root of current task; in-app "home" behavior)
// Always at least finish the current activity.
finishTo = Math.min(start - 1, i + 1);
parent = history.get(finishTo);
break;
} else if (r.info.packageName.equals(dest.getPackageName()) && r.info.name.equals(dest.getClassName())) {
finishTo = i;
parent = r;
foundParentInTask = true;
break;
}
}
}
if (mController != null) {
ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
if (next != null) {
// ask watcher if this is allowed
boolean resumeOK = true;
try {
resumeOK = mController.activityResuming(next.packageName);
} catch (RemoteException e) {
mController = null;
Watchdog.getInstance().setActivityController(null);
}
if (!resumeOK) {
return false;
}
}
}
final long origId = Binder.clearCallingIdentity();
for (int i = start; i > finishTo; i--) {
ActivityRecord r = history.get(i);
mMainStack.requestFinishActivityLocked(r.appToken, resultCode, resultData, "navigate-up", true);
// Only return the supplied result for the first activity finished
resultCode = Activity.RESULT_CANCELED;
resultData = null;
}
if (parent != null && foundParentInTask) {
final int parentLaunchMode = parent.info.launchMode;
final int destIntentFlags = destIntent.getFlags();
if (parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE || parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TASK || parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TOP || (destIntentFlags & Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
parent.deliverNewIntentLocked(srec.info.applicationInfo.uid, destIntent);
} else {
try {
ActivityInfo aInfo = AppGlobals.getPackageManager().getActivityInfo(destIntent.getComponent(), 0, srec.userId);
int res = mMainStack.startActivityLocked(srec.app.thread, destIntent, null, aInfo, parent.appToken, null, 0, -1, parent.launchedFromUid, parent.launchedFromPackage, 0, null, true, null);
foundParentInTask = res == ActivityManager.START_SUCCESS;
} catch (RemoteException e) {
foundParentInTask = false;
}
mMainStack.requestFinishActivityLocked(parent.appToken, resultCode, resultData, "navigate-up", true);
}
}
Binder.restoreCallingIdentity(origId);
return foundParentInTask;
}
}
use of android.content.pm.ActivityInfo in project android_frameworks_base by ParanoidAndroid.
the class ActivityStack method startActivities.
final int startActivities(IApplicationThread caller, int callingUid, String callingPackage, Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, int userId) {
if (intents == null) {
throw new NullPointerException("intents is null");
}
if (resolvedTypes == null) {
throw new NullPointerException("resolvedTypes is null");
}
if (intents.length != resolvedTypes.length) {
throw new IllegalArgumentException("intents are length different than resolvedTypes");
}
ActivityRecord[] outActivity = new ActivityRecord[1];
int callingPid;
if (callingUid >= 0) {
callingPid = -1;
} else if (caller == null) {
callingPid = Binder.getCallingPid();
callingUid = Binder.getCallingUid();
} else {
callingPid = callingUid = -1;
}
final long origId = Binder.clearCallingIdentity();
try {
synchronized (mService) {
// we must resolve if the last intent in the stack is floating to give the flag to the previous
boolean floating = false;
if (intents.length > 0) {
floating = (intents[intents.length - 1].getFlags() & Intent.FLAG_FLOATING_WINDOW) == Intent.FLAG_FLOATING_WINDOW;
}
for (int i = 0; i < intents.length; i++) {
Intent intent = intents[i];
if (intent == null) {
continue;
}
// Refuse possible leaked file descriptors
if (intent != null && intent.hasFileDescriptors()) {
throw new IllegalArgumentException("File descriptors passed in Intent");
}
boolean componentSpecified = intent.getComponent() != null;
// Don't modify the client's object!
intent = new Intent(intent);
// Collect information about the target of the Intent.
ActivityInfo aInfo = resolveActivity(intent, resolvedTypes[i], 0, null, null, userId);
// TODO: New, check if this is correct
aInfo = mService.getActivityInfoForUser(aInfo, userId);
if (mMainStack && aInfo != null && (aInfo.applicationInfo.flags & ApplicationInfo.FLAG_CANT_SAVE_STATE) != 0) {
throw new IllegalArgumentException("FLAG_CANT_SAVE_STATE not supported here");
}
if (floating) {
intent.addFlags(Intent.FLAG_FLOATING_WINDOW);
}
Bundle theseOptions;
if (options != null && i == intents.length - 1) {
theseOptions = options;
} else {
theseOptions = null;
}
int res = startActivityLocked(caller, intent, resolvedTypes[i], aInfo, resultTo, null, -1, callingPid, callingUid, callingPackage, 0, theseOptions, componentSpecified, outActivity);
if (res < 0) {
return res;
}
resultTo = outActivity[0] != null ? outActivity[0].appToken : null;
}
}
} finally {
Binder.restoreCallingIdentity(origId);
}
return ActivityManager.START_SUCCESS;
}
use of android.content.pm.ActivityInfo in project android_frameworks_base by ParanoidAndroid.
the class ActivityStack method startActivityMayWait.
final int startActivityMayWait(IApplicationThread caller, int callingUid, String callingPackage, Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int startFlags, String profileFile, ParcelFileDescriptor profileFd, WaitResult outResult, Configuration config, Bundle options, int userId) {
// Refuse possible leaked file descriptors
if (intent != null && intent.hasFileDescriptors()) {
throw new IllegalArgumentException("File descriptors passed in Intent");
}
boolean componentSpecified = intent.getComponent() != null;
// Don't modify the client's object!
intent = new Intent(intent);
// Collect information about the target of the Intent.
ActivityInfo aInfo = resolveActivity(intent, resolvedType, startFlags, profileFile, profileFd, userId);
synchronized (mService) {
int callingPid;
if (callingUid >= 0) {
callingPid = -1;
} else if (caller == null) {
callingPid = Binder.getCallingPid();
callingUid = Binder.getCallingUid();
} else {
callingPid = callingUid = -1;
}
mConfigWillChange = config != null && mService.mConfiguration.diff(config) != 0;
if (DEBUG_CONFIGURATION)
Slog.v(TAG, "Starting activity when config will change = " + mConfigWillChange);
final long origId = Binder.clearCallingIdentity();
if (mMainStack && aInfo != null && (aInfo.applicationInfo.flags & ApplicationInfo.FLAG_CANT_SAVE_STATE) != 0) {
// have another, different heavy-weight process running.
if (aInfo.processName.equals(aInfo.applicationInfo.packageName)) {
if (mService.mHeavyWeightProcess != null && (mService.mHeavyWeightProcess.info.uid != aInfo.applicationInfo.uid || !mService.mHeavyWeightProcess.processName.equals(aInfo.processName))) {
int realCallingPid = callingPid;
int realCallingUid = callingUid;
if (caller != null) {
ProcessRecord callerApp = mService.getRecordForAppLocked(caller);
if (callerApp != null) {
realCallingPid = callerApp.pid;
realCallingUid = callerApp.info.uid;
} else {
Slog.w(TAG, "Unable to find app for caller " + caller + " (pid=" + realCallingPid + ") when starting: " + intent.toString());
ActivityOptions.abort(options);
return ActivityManager.START_PERMISSION_DENIED;
}
}
IIntentSender target = mService.getIntentSenderLocked(ActivityManager.INTENT_SENDER_ACTIVITY, "android", realCallingUid, userId, null, null, 0, new Intent[] { intent }, new String[] { resolvedType }, PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_ONE_SHOT, null);
Intent newIntent = new Intent();
if (requestCode >= 0) {
// Caller is requesting a result.
newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_HAS_RESULT, true);
}
newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_INTENT, new IntentSender(target));
if (mService.mHeavyWeightProcess.activities.size() > 0) {
ActivityRecord hist = mService.mHeavyWeightProcess.activities.get(0);
newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_CUR_APP, hist.packageName);
newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_CUR_TASK, hist.task.taskId);
}
newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_NEW_APP, aInfo.packageName);
newIntent.setFlags(intent.getFlags());
newIntent.setClassName("android", HeavyWeightSwitcherActivity.class.getName());
intent = newIntent;
resolvedType = null;
caller = null;
callingUid = Binder.getCallingUid();
callingPid = Binder.getCallingPid();
componentSpecified = true;
try {
ResolveInfo rInfo = AppGlobals.getPackageManager().resolveIntent(intent, null, PackageManager.MATCH_DEFAULT_ONLY | ActivityManagerService.STOCK_PM_FLAGS, userId);
aInfo = rInfo != null ? rInfo.activityInfo : null;
aInfo = mService.getActivityInfoForUser(aInfo, userId);
} catch (RemoteException e) {
aInfo = null;
}
}
}
}
int res = startActivityLocked(caller, intent, resolvedType, aInfo, resultTo, resultWho, requestCode, callingPid, callingUid, callingPackage, startFlags, options, componentSpecified, null);
if (mConfigWillChange && mMainStack) {
// If the caller also wants to switch to a new configuration,
// do so now. This allows a clean switch, as we are waiting
// for the current activity to pause (so we will not destroy
// it), and have not yet started the next activity.
mService.enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, "updateConfiguration()");
mConfigWillChange = false;
if (DEBUG_CONFIGURATION)
Slog.v(TAG, "Updating to new configuration after starting activity.");
mService.updateConfigurationLocked(config, null, false, false);
}
Binder.restoreCallingIdentity(origId);
if (outResult != null) {
outResult.result = res;
if (res == ActivityManager.START_SUCCESS) {
mWaitingActivityLaunched.add(outResult);
do {
try {
mService.wait();
} catch (InterruptedException e) {
}
} while (!outResult.timeout && outResult.who == null);
} else if (res == ActivityManager.START_TASK_TO_FRONT) {
ActivityRecord r = this.topRunningActivityLocked(null);
if (r.nowVisible) {
outResult.timeout = false;
outResult.who = new ComponentName(r.info.packageName, r.info.name);
outResult.totalTime = 0;
outResult.thisTime = 0;
} else {
outResult.thisTime = SystemClock.uptimeMillis();
mWaitingActivityVisible.add(outResult);
do {
try {
mService.wait();
} catch (InterruptedException e) {
}
} while (!outResult.timeout && outResult.who == null);
}
}
}
return res;
}
}
Aggregations