- }
如果 当前的activity是从一个application启动的 , 也就是说参数caller!=null,此时的callingPid和callingUid可以从caller所处的进程中得出。
[java] view plain copy
-
ProcessRecord callerApp = null;
-
if (caller != null) {
-
callerApp = mService.getRecordForAppLocked(caller);
-
if (callerApp != null) {
-
callingPid = callerApp.pid;
-
callingUid = callerApp.info.uid;
-
} else {
-
Slog.w(TAG, "Unable to find app for caller " + caller
-
+ " (pid=" + callingPid + ") when starting: "
-
+ intent.toString());
-
err = START_PERMISSION_DENIED;
-
}
-
}
1.2.2.2 permission检查的规则
-
Root uid(0), System Server uid (Process.SYSTEM_UID), own process(MY_PID),将授权permission
-
如果请求启动的activity的属性
android:exported
=false, 并且请求的callingUid不等于请求启动的activity的UID,不允许启动;
3. 请求启动的activity没有设定permission,只有当activity的permission和其所在的application的android:permission
均为设置时才为null,直设置了application未设置activity,那么activity的permission与application相同。activity的permission为空,则授权;
4. 请求启动的activity设定了permission,那么检查请求方的activity中是否声明了使用这个permission,如果声明,授权。
[java] view plain copy
-
final int perm = mService.checkComponentPermission(aInfo.permission, callingPid,
-
callingUid, aInfo.exported ? -1 : aInfo.applicationInfo.uid);
-
if (perm != PackageManager.PERMISSION_GRANTED) {
-
if (resultRecord != null) {
-
sendActivityResultLocked(-1,
-
resultRecord, resultWho, requestCode,
-
Activity.RESULT_CANCELED, null);
-
}
-
String msg = "Permission Denial: starting " + intent.toString()
-
+ " from " + callerApp + " (pid=" + callingPid
-
+ “, uid=” + callingUid + “)”
-
+ " requires " + aInfo.permission;
-
Slog.w(TAG, msg);
-
throw new SecurityException(msg);
-
}
创建ActivityRecord
[java] view plain copy
-
ActivityRecord r = new ActivityRecord(mService, this, callerApp, callingUid,
-
intent, resolvedType, aInfo, mService.mConfiguration,
-
resultRecord, resultWho, requestCode, componentSpecified);
在android应用开发中,task是一个很重要的概念,在文章开始,我就画出了task和activity以及process整体的关系,在这里还需要说明一下,task和application的区别,application在android中的作用仅仅是activity在未被使用前的一个容器,我们开发android应用程序时,需要一个application来组织我们开发的activity,application和activity之间是一个静态关系,并且是一一对应的关系;也就是说我们开发的activity在PM中的最终形式是唯一的,永远对应一个application。
而task和activity之间的关系是动态的关系,是我们在运行应用程序时,activity的调用栈,同一个task中的activity可能来自不同的application。
关于task,更详细的资料参考:http://developer.android.com/guide/topics/fundamentals/tasks-and-back-stack.html
这部分源码主要是在
final int startActivityUncheckedLocked(ActivityRecord r,
ActivityRecord sourceRecord, Uri[] grantedUriPermissions,
int grantedMode, boolean onlyIfNeeded, boolean doResume)
这一部分比较繁琐,写的可能比较乱。
1.3.1 Intent.FLAG_ACTIVITY_NO_USER_ACTION
检查Intent是否设置了Intent.FLAG_ACTIVITY_NO_USER_ACTION,如果设置了,则在activity pause之前将不再调用activity的onUserLeaveHint()方法。
[java] view plain copy
-
mUserLeaving = (launchFlags&Intent.FLAG_ACTIVITY_NO_USER_ACTION) == 0;
-
if (DEBUG_USER_LEAVING) Slog.v(TAG,
-
“startActivity() => mUserLeaving=” + mUserLeaving);
1.3.2 Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP
检查Intent是否设置了Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP,这个标志我有点困惑,从它的注释可以看出它的含义是指如果设置了该flag,那么mHistory中最top的a