Alert Window 弹窗控制

aosp-5.1.1_r6

  • 源码分析
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
WMS.addWindow()
-> PhoneWindowManager.checkAddPermission() {
switch TYPE_SYSTEM_ALERT/TYPE_SYSTEM_OVERLAY/TYPE_SYSTEM_ERROR/TYPE_PHONE/TYPE_PRIORITY_PHONE:
permission = android.Manifest.permission.SYSTEM_ALERT_WINDOW
outAppOp[0] = AppOpsManager.OP_SYSTEM_ALERT_WINDOW (int数值24)
if mContext.checkCallingOrSelfPermission(permission) != PackageManager.PERMISSION_GRANTED:
return WindowManagerGlobal.ADD_PERMISSION_DENIED
}
-> ContextImpl.checkCallingOrSelfPermission(String permission)
-> ContextImpl.checkPermission(permission, Binder.getCallingPid(), Binder.getCallingUid())
-binder-> AMS.checkPermission(permission, pid, uid)
-> AMS.checkComponentPermission(permission, pid, UserHandle.getAppId(uid), owningUid=-1, exported=true)
-> ActivityManager.checkComponentPermission(permission, uid, owningUid, exported) {
if uid==0 || uid == Process.SYSTEM_UID: 允许
if UserHandle.isIsolated(uid): 禁止
if owningUid >= 0 && UserHandle.isSameApp(uid, owningUid): 允许
if !exported: 禁止
if permission == null: 允许
return AppGlobals.getPackageManager().checkUidPermission(permission, uid)
}

aosp-6.0.0_r1

查看更多

tensorflow rnn embedding

seq2seq 中的 rnn embedding 是 trainable 的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
legacy_seq2seq
embedding_attention_seq2seq

core_rnn_cell.py:line111: EmbeddingWrapper.call(self, inputs, state) inputs仍是list(token id)
embedding = vs.get_variable("embedding", [self._embedding_classes, self._embedding_size], initializer=initializer, dtype=data_type)
-> line1135 variable_scope.py: get_variable() # custom_getter=None, use_resource=None, Trainable=True
-> line991 variable_scope.py: VariableScope.get_variable(
_get_default_variable_store(), name, shape=shape, dtype=dtype, initializer=initializer, regularizer=regularizer,
trainable=trainable, collections=collections, caching_device=caching_device, partitioner=partitioner, valid_shape=valid_shape,
use_resource=use_resource, custom_getter=custom_getter, constraint=constraint)
return var_store.get_variable(full_name, ...) # full_name = self.name + "/" + name
-> line225 _VariableStore.get_variable(name, ...)
custom_getter == None: return _true_getter()
-> line329 _VariableScope.get_variable._true_getter()
-> line663 _VariableScope._get_single_variable()
-> variables.Variable(trainable=True)

uiautomator 启动流程

版本: android-6.0.0_r1

运行示例

1
uiautomator runtest AppiumBootstrap.jar -c io.appium.android.bootstrap.Bootstrap -e disableAndroidWatchers false -e acceptSslCerts false

shell 脚本

  • 位置 frameworks/base/cmds/uiautomator/cmds/uiautomator/uiautomator
1
2
3
4
基础 CLASSPATH=/system/framework/android.test.runner.jar:${base}/framework/uiautomator.jar
收集 runtest 后跟的所有 jar 添加到 CLASSPATH=${CLASSPATH}:${jars}, 设置 args="${cmd} 其余参数${args} -e jars ${jars}"

exec app_process /system/bin com.android.commands.uiautomator.Launcher ${args}

查看更多

repo refs/remotes/m 来源分析

refs/remotes/m 是什么

m 代表 merge, 是 git 仓库里的 .gitconfig 里 branch 的 merge 字段

refs/remotes/m 怎么来的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
git_refs.py
R_M = 'refs/remotes/m/'

使用
info.py
Info.findRemoteLocalDiff(project) 列出remote和local的diff

设置/读取
project.py Sync_NetworkHalf()
-> Project._InitMRef() {
self._InitAnyMRef(R_M + self.manifest.branch) 传参 'refs/remotes/m/'+manifests仓库的currentBranch.merge
self.revisionId == None: Project的创建在 manifest_xml.py _AddMetaProjectMirror()/_ParseProject() 两处revisionId均为None
remote=self.GetRemote(self.remote.name)
dst=remote.ToLocal(self.revisionExpr)
revisionExpr 顺序: 1.项目的 revision 字段, 2. remote 指定的 revision 字段, 3. default 指定的 revision 字段
参考: https://gerrit.googlesource.com/git-repo/+/master/docs/manifest-format.txt
self.bare_git.symbolic_ref('-m', msg, ref, dst) 设置symbolic-ref } 设置的ref log可通过 git reflog refs/remotes/m/rBranch 查看
-> Project._InitAnyMRef(ref) { self.bare_ref.symref(ref) }
-> git_refs.py GitRefs.symref(name) { self._EnsureLoaded(); return self._symref[name] }
-> GitRefs._EnsureLoaded() { if self._phyref is None or self._NeedUpdate(): self._LoadAll() }
-> GitRefs._LoadAll() {
self._ReadPackedRefs() 读取 .git/packed_refs 忽略 # 和 ^ 打头行, foreach 其余每行 ref_id name: self.phyref[name]=ref_id
self._ReadLoose('refs/') {
递归读取 .git/refs 目录
foreach 文件: _ReadLoose1(self, 文件路径path, 相对.git的文件名称name) {
读取文件 if 'ref: '打头: self._symref[name]=ref_id[5:] else: self._phyref[name]=ref_id
self._ReadLoose1(os.path.join(self._gitdir, HEAD), HEAD) } 读取 .git/HEAD

也就是说,refs/remotes/m/branchName 会在每次sync时候读取,若没有则创建,不需要自己创建并push到remote

SystemUI 最近应用 源码分析

版本: android-6.0.0_r1

初始化

1
2
3
4
5
RecentsTaskLoader.initialize() {
初始化 mApplicationIconCache/mThumbnailCache/mActivityLabelCache/mContentDescriptionCache
mLoadQueue = new TaskResourceLoadQueue()
new TaskResourceLoader(mLoadQueue) {用HandlerThread起LoaderThread, post自身(Runnable)} }
<- Recents.start() systemui启动时各模块初始化调用

TaskResourceLoader.mLoadThread 加载线程

  • 逐个加载推到 mLoadQueue的 Task的相关内容 icon/thumbnail/label
  • 加载完调用 (Task t).notifyTaskDataLoaded(thumbnail, icon) 通知更新

查看更多

Activity 透明/非透明 转换

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
Activity.convertFromTranslucent() {
ActivityManagerNative.getDefault().convertFromTranslucent(mToken)
WindowManagerGlobal.getInstance().changeCanvasOpacity(mToken, true)
}

--binder--> ActivityManagerService.convertFromTranslucent() {
(ActivityRecord r).changeWindowTranslucency(true)
r.task.stack.releaseBackgroundResources(r)
mStackSupervisor.ensureActivitiesVisibleLocked(null, 0)
mWindowManager.setAppFullscreen(token, true)
}
-> ActivityStackSupervisor.ensureActivitiesVisibleLocked() {
遍历 display, stack
ActivityStack.ensureActivitiesVisibleLocked() {
behindFullscreen && r.visible: 影响到的(ActivityRecord r) 根据r.state动作:
case RESUMED: mStackSupervisor.mStoppingActivities.add(r); mStackSupervisor.scheduleIdleLocked()
}
}

--IDLE_NOW_MSG--> ActivityStackSupervisor.activityIdleInternelLocked() {
ArrayList<ActivityRecord> stops = processStoppingActivitiesLocked(true) 从mStoppingActivities取要stop的
遍历stops: (ActivityStack stack).stopActivityLocked(r)
}

-> ActivityStack.stopActivityLocked(r) { r.app.thread.scheduleStopActivity() }
-> ApplicationThreadProxy.scheduleStopActivity(r.appToken, r.visible==false, r.configChangeFlags)
--binder--> (ActivityThread.ApplicationThread extends ApplicationThreadNative).scheduleStopActivity() { scheduleStopActivity() }
--handler STOP_ACTIVITY_HIDE--> ActivityThread.handleStopActivity()
-> ActivityThread.performStopActivityInner()
-> Activity.performStop()
-> Instrumentation.callActivityOnStop() { activity.onStop() }

PackageInstaller 中的 动态权限

manifest统计

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
.PackageInstallerActivity
action="android.content.pm.action.CONFIRM_PERMISSIONS"
category="android.intent.category.DEFAULT"

.permission.ui.GrantPermissionsActivity
action="android.content.pm.action.REQUEST_PERMISSIONS"
category="android.intent.category.DEFAULT"

.permission.ui.ManagePermissionsActivity
action="android.intent.action.MANAGE_PERMISSIONS"
action="android.intent.action.MANAGE_APP_PERMISSIONS"
action="android.intent.action.MANAGE_PERMISSION_APPS"
category="android.intent.category.DEFAULT"

receiver=".permission.model.PermissionStatusReceiver"
android:permission="android.permission.GRANT_RUNTIME_PERMISSIONS"
intent-filter action="android.intent.action.GET_PERMISSIONS_COUNT"

PackageInstallerActivity

1
2
入口activity
CONFIRM_PERMISSIONS 通过session进来, 记住sessionId, 选择后回调给session mInstaller.setPermissionsResult()

GrantPermissionsActivity

  • 应用主动申请权限时出现的授权界面
  • 授权权限按组进行
查看更多

ResolverActivity 流程

版本 aosp-5.1.1_r6

1
2
3
4
5
6
7
8
9
10
11
ResolverActivity.java ResolveListAdapter.ctor()
-> ResolveListAdapter.rebuildList()
--binder--> PackageManagerService.queryIntentActivities() {
if intent有component, 直接返回component指定的;
if intent有packageName, ActivityIntentResolver.queryIntentForPackage()
else ActivityIntentResolver.queryIntent()
}
->1. (ActivityIntentResolver父类 IntentResolver).queryIntent()
->2. (ActivityIntentResolver父类 IntentResolver).queryIntentForPackage()

-> IntentResolver.buildResolveList()

查看更多