mirror of
https://github.com/feicong/rom-course.git
synced 2025-05-06 10:31:18 +00:00
code
This commit is contained in:
parent
b8f0fc5a4b
commit
8b908c7126
1095
code/chapter-02/default.xml
Normal file
1095
code/chapter-02/default.xml
Normal file
File diff suppressed because it is too large
Load Diff
119
code/chapter-02/initGit.py
Normal file
119
code/chapter-02/initGit.py
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
#!/usr/bin/python3
|
||||||
|
|
||||||
|
import gitlab
|
||||||
|
import os
|
||||||
|
import re
|
||||||
|
import time
|
||||||
|
|
||||||
|
MANIFEST_XML = "default.xml"
|
||||||
|
ROOT = os.getcwd()
|
||||||
|
ROOT_GROUP = "Android6NewC"
|
||||||
|
MANIFEST_XML_PATH_NAME_RE = re.compile(r"<project\s+path=\"(?P<path>[^\"]+)\"\s+name=\"(?P<name>[^\"]+)\"\s+/>",
|
||||||
|
re.DOTALL)
|
||||||
|
|
||||||
|
gl = gitlab.Gitlab('http://192.168.50.10/', private_token='xxxxxxx')
|
||||||
|
|
||||||
|
manifest_xml_project_paths = []
|
||||||
|
|
||||||
|
def parse_repo_manifest():
|
||||||
|
with open(os.path.join(ROOT, MANIFEST_XML), "rb") as strReader:
|
||||||
|
for line in strReader:
|
||||||
|
if line is not None and len(line) != 0:
|
||||||
|
this_temp_line = line.decode()
|
||||||
|
if line.find("path".encode(encoding="utf-8")):
|
||||||
|
|
||||||
|
s = MANIFEST_XML_PATH_NAME_RE.search(this_temp_line)
|
||||||
|
|
||||||
|
if s is not None:
|
||||||
|
manifest_xml_project_paths.append(s.group("path"))
|
||||||
|
|
||||||
|
print("manifest_xml_project_paths=" + str(manifest_xml_project_paths))
|
||||||
|
print("manifest_xml_project_paths len=" + str(len(manifest_xml_project_paths)))
|
||||||
|
|
||||||
|
def create_group_and_project():
|
||||||
|
all_groups = gl.groups.list(all=True)
|
||||||
|
print("all_groups=" + str(all_groups))
|
||||||
|
group_parent = None
|
||||||
|
|
||||||
|
for g in all_groups:
|
||||||
|
if g.name == ROOT_GROUP:
|
||||||
|
group_parent = g
|
||||||
|
break
|
||||||
|
print("group parent=" + str(group_parent))
|
||||||
|
|
||||||
|
for path in manifest_xml_project_paths:
|
||||||
|
print("path=" + path)
|
||||||
|
paths = path.split("/")
|
||||||
|
print("paths=" + str(paths))
|
||||||
|
|
||||||
|
last_path_index = len(paths) - 1
|
||||||
|
|
||||||
|
group = group_parent
|
||||||
|
for index in range(0, last_path_index):
|
||||||
|
p = paths[index]
|
||||||
|
print("p=" + p)
|
||||||
|
# is the group exist
|
||||||
|
print("parent group=" + group.name)
|
||||||
|
try:
|
||||||
|
all_groups = group.subgroups.list(all=True)
|
||||||
|
except AttributeError:
|
||||||
|
all_groups = []
|
||||||
|
print("AttributeError: clear all subgroups")
|
||||||
|
|
||||||
|
is_group_exist = False
|
||||||
|
for g in all_groups:
|
||||||
|
if g.name == p:
|
||||||
|
is_group_exist = True
|
||||||
|
group = g
|
||||||
|
print("group exist=" + g.name)
|
||||||
|
break
|
||||||
|
if is_group_exist:
|
||||||
|
continue
|
||||||
|
# create subgroup
|
||||||
|
data = {
|
||||||
|
"name": p,
|
||||||
|
"path": p,
|
||||||
|
"parent_id": group.id
|
||||||
|
}
|
||||||
|
|
||||||
|
try:
|
||||||
|
group = gl.groups.create(data)
|
||||||
|
print("group create success name=" + p)
|
||||||
|
time.sleep(1)
|
||||||
|
except gitlab.exceptions.GitlabCreateError as e:
|
||||||
|
if e.response_code == 400:
|
||||||
|
print("group:" + p + " has already been created")
|
||||||
|
|
||||||
|
query_groups = gl.groups.list(all=True)
|
||||||
|
print("query_groups:" + str(query_groups))
|
||||||
|
for query_group in query_groups:
|
||||||
|
if query_group.name == p and query_group.parent_id == group.id:
|
||||||
|
group = query_group
|
||||||
|
print("update exit group:" + group.name)
|
||||||
|
break
|
||||||
|
|
||||||
|
project = paths[last_path_index]
|
||||||
|
print("group project list group=" + group.name)
|
||||||
|
real_group = gl.groups.get(group.id, lazy=True)
|
||||||
|
all_projects = real_group.projects.list(all=True)
|
||||||
|
print("group all projects=" + str(all_projects))
|
||||||
|
is_project_exist = False
|
||||||
|
for p in all_projects:
|
||||||
|
if p.name == project:
|
||||||
|
is_project_exist = True
|
||||||
|
print("project exist=" + p.name)
|
||||||
|
break
|
||||||
|
if not is_project_exist:
|
||||||
|
print("create project=" + project)
|
||||||
|
gl.projects.create({'name': project, 'path': project, 'namespace_id': group.id})
|
||||||
|
print("project create success name=" + project)
|
||||||
|
time.sleep(1)
|
||||||
|
|
||||||
|
def test_create_project_with_dot_name():
|
||||||
|
# need use path field, if don't use path, GitLab url will replace "." to "_"
|
||||||
|
gl.projects.create({'name': "xxx.yy.xy", 'path': "xxx.yy.xy"})
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
parse_repo_manifest()
|
||||||
|
create_group_and_project()
|
||||||
|
|
115
code/chapter-02/putGit.py
Normal file
115
code/chapter-02/putGit.py
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
#!/usr/bin/python3
|
||||||
|
|
||||||
|
import os
|
||||||
|
import re,time,subprocess
|
||||||
|
|
||||||
|
MANIFEST_XML = "./default.xml"
|
||||||
|
ROOT = os.getcwd()
|
||||||
|
LOG_FILE_PATH = os.path.join(ROOT, "push.log")
|
||||||
|
|
||||||
|
MANIFEST_XML_PATH_NAME_RE = re.compile(r"<project\s+path=\"(?P<path>[^\"]+)\"\s+name=\"(?P<name>[^\"]+)\"\s+",
|
||||||
|
re.DOTALL)
|
||||||
|
SOURCE_CODE_ROOT = "/home/king/android_src/aosp12_mikrom/"
|
||||||
|
REMOTE = "git@192.168.2.189:mikrom12/"
|
||||||
|
manifest_xml_project_paths = []
|
||||||
|
|
||||||
|
def parse_repo_manifest():
|
||||||
|
with open(os.path.join(ROOT, MANIFEST_XML), "rb") as strReader:
|
||||||
|
for line in strReader:
|
||||||
|
if line is not None and len(line) != 0:
|
||||||
|
this_temp_line = line.decode()
|
||||||
|
if line.find("path".encode(encoding="utf-8")):
|
||||||
|
|
||||||
|
s = MANIFEST_XML_PATH_NAME_RE.search(this_temp_line)
|
||||||
|
|
||||||
|
if s is not None:
|
||||||
|
manifest_xml_project_paths.append({"path":s.group("path"),"name":s.group("name")})
|
||||||
|
|
||||||
|
print("manifest_xml_project_paths=" + str(manifest_xml_project_paths))
|
||||||
|
print("manifest_xml_project_paths len=" + str(len(manifest_xml_project_paths)))
|
||||||
|
|
||||||
|
def exec(cmd):
|
||||||
|
proc = subprocess.Popen(
|
||||||
|
cmd,
|
||||||
|
shell=True,
|
||||||
|
stdout=subprocess.PIPE,
|
||||||
|
stderr=subprocess.STDOUT,
|
||||||
|
stdin=subprocess.PIPE # 重定向输入值
|
||||||
|
)
|
||||||
|
proc.stdin.close() # 既然没有命令行窗口,那就关闭输入
|
||||||
|
result = proc.stdout.read() # 读取cmd执行的输出结果(是byte类型,需要decode)
|
||||||
|
proc.stdout.close()
|
||||||
|
return result.decode(encoding="utf-8")
|
||||||
|
|
||||||
|
def push_source_code_by_folder(str_writer):
|
||||||
|
for path in manifest_xml_project_paths:
|
||||||
|
print("path=" + path["path"])
|
||||||
|
abs_path = SOURCE_CODE_ROOT + path["path"]
|
||||||
|
|
||||||
|
if os.path.exists(abs_path):
|
||||||
|
# change current work dir
|
||||||
|
os.chdir(abs_path + "/")
|
||||||
|
res= exec("git remote -v")
|
||||||
|
print(res)
|
||||||
|
if path["name"] in res:
|
||||||
|
continue
|
||||||
|
# 1\. delete .git & .gitignore folder
|
||||||
|
rm_git_cmd = "rm -rf .git"
|
||||||
|
rm_gitignore_cmd = "rm -rf .gitignore"
|
||||||
|
os.system(rm_git_cmd)
|
||||||
|
os.system(rm_gitignore_cmd)
|
||||||
|
|
||||||
|
# 2\. list dir
|
||||||
|
dir_data = os.listdir(os.getcwd())
|
||||||
|
|
||||||
|
cmd_list = []
|
||||||
|
|
||||||
|
print("changed cwd=" + os.getcwd())
|
||||||
|
|
||||||
|
if len(dir_data) == 0:
|
||||||
|
echo_cmd = "echo \"This is a empty repository.\" > ReadMe.md"
|
||||||
|
str_writer.write(f"empty repository:{abs_path}".encode() )
|
||||||
|
str_writer.write("\r\n".encode())
|
||||||
|
cmd_list.append(echo_cmd)
|
||||||
|
|
||||||
|
git_init_cmd = "git init"
|
||||||
|
cmd_list.append(git_init_cmd)
|
||||||
|
|
||||||
|
git_remote_cmd = "git remote add origin " + REMOTE + path["name"] + ".git"
|
||||||
|
cmd_list.append(git_remote_cmd)
|
||||||
|
|
||||||
|
git_add_dot_cmd = "git add ."
|
||||||
|
cmd_list.append(git_add_dot_cmd)
|
||||||
|
|
||||||
|
git_commit_cmd = "git commit -m \"Initial commit\""
|
||||||
|
cmd_list.append(git_commit_cmd)
|
||||||
|
|
||||||
|
git_push_cmd = "git push -u origin master"
|
||||||
|
cmd_list.append(git_push_cmd)
|
||||||
|
|
||||||
|
for cmd in cmd_list:
|
||||||
|
print("begin exec cmd=" + cmd)
|
||||||
|
os.system(cmd)
|
||||||
|
print("end exec cmd=" + cmd)
|
||||||
|
else:
|
||||||
|
print("abs_path=" + abs_path + " is not exist.")
|
||||||
|
str_writer.write(f"folder not exist:{abs_path}".encode() )
|
||||||
|
str_writer.write("\r\n".encode())
|
||||||
|
|
||||||
|
def wrapper_push_source_code_write_log():
|
||||||
|
with open(LOG_FILE_PATH, 'wb+') as strWriter:
|
||||||
|
push_source_code_by_folder(strWriter)
|
||||||
|
strWriter.close()
|
||||||
|
|
||||||
|
# def test_only_dot_git_folder():
|
||||||
|
# subdir_and_file = os.listdir(os.getcwd())
|
||||||
|
# print("subdir_and_file=" + str(subdir_and_file))
|
||||||
|
# with open(LOG_FILE_PATH, 'wb+') as strWriter:
|
||||||
|
# strWriter.write(str(subdir_and_file).encode())
|
||||||
|
# strWriter.write("\r\n".encode())
|
||||||
|
# strWriter.write(str(subdir_and_file).encode())
|
||||||
|
# strWriter.close()
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
parse_repo_manifest()
|
||||||
|
wrapper_push_source_code_write_log()
|
71
code/chapter-04/replaceIcon.py
Normal file
71
code/chapter-04/replaceIcon.py
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
import os
|
||||||
|
import shutil
|
||||||
|
import subprocess
|
||||||
|
|
||||||
|
# 执行cmd命令
|
||||||
|
def exec(cmd):
|
||||||
|
proc = subprocess.Popen(
|
||||||
|
cmd,
|
||||||
|
shell=True,
|
||||||
|
stdout=subprocess.PIPE,
|
||||||
|
stderr=subprocess.STDOUT,
|
||||||
|
stdin=subprocess.PIPE # 重定向输入值
|
||||||
|
)
|
||||||
|
proc.stdin.close() # 既然没有命令行窗口,那就关闭输入
|
||||||
|
result = proc.stdout.read() # 读取cmd执行的输出结果(是byte类型,需要decode)
|
||||||
|
proc.stdout.close()
|
||||||
|
return result.decode(encoding="utf-8")
|
||||||
|
|
||||||
|
# 替换图标
|
||||||
|
def replacePng(target,appName):
|
||||||
|
# 搜索该路径下的图标
|
||||||
|
cmdRes = exec(f"find /home/king/android_src/mikrom12_gitlab/packages/ -name {target}")
|
||||||
|
filePathList = cmdRes.split("\n")
|
||||||
|
curpath=os.getcwd()
|
||||||
|
# 遍历所有搜到的结果
|
||||||
|
for filepath in filePathList:
|
||||||
|
if filepath=="":
|
||||||
|
continue
|
||||||
|
# 为了避免其他应用的同名素材图标,所以使用appName过滤一下
|
||||||
|
if appName not in filepath:
|
||||||
|
continue
|
||||||
|
print('Found file: ' + filepath)
|
||||||
|
# 先将文件进行备份
|
||||||
|
shutil.copy(filepath,filepath+".bak")
|
||||||
|
# 然后将当前目录准备好的替换文件复制进去
|
||||||
|
replacePath=curpath+"/images/"+target
|
||||||
|
# 如果新文件不存在,则结束该文件的替换
|
||||||
|
if os.path.exists(replacePath)==False:
|
||||||
|
print("not found replace file:",replacePath)
|
||||||
|
break
|
||||||
|
shutil.copy(replacePath, filepath)
|
||||||
|
|
||||||
|
# 使用备份的文件还原该图标
|
||||||
|
def unReplacePng(target):
|
||||||
|
# 查找目标文件
|
||||||
|
cmdRes = exec(f"find /home/king/android_src/mikrom12_gitlab/frameworks/base/packages/ -name {target}")
|
||||||
|
filePathList = cmdRes.split("\n")
|
||||||
|
# 遍历所有结果
|
||||||
|
for filepath in filePathList:
|
||||||
|
if filepath=="":
|
||||||
|
continue
|
||||||
|
print('Found file: ' + filepath)
|
||||||
|
# 备份文件如果存在,则将其还原
|
||||||
|
bakfile=filepath + ".bak"
|
||||||
|
if os.path.exists(bakfile):
|
||||||
|
shutil.copy(bakfile, filepath)
|
||||||
|
print("unReplace file:",bakfile)
|
||||||
|
|
||||||
|
def main():
|
||||||
|
# 替换为新素材
|
||||||
|
replacePng('ic_launcher_settings.png',"Setting")
|
||||||
|
replacePng('ic_contacts_launcher.png',"Contacts")
|
||||||
|
replacePng('ic_launcher_calendar.png',"Calendar")
|
||||||
|
|
||||||
|
# 还原素材
|
||||||
|
# unReplacePng('ic_launcher_settings.png')
|
||||||
|
# unReplacePng('ic_contacts_launcher.png')
|
||||||
|
# unReplacePng('ic_launcher_calendar.png')
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
11
code/chapter-05/SystemAppDemo/Android.mk
Normal file
11
code/chapter-05/SystemAppDemo/Android.mk
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
LOCAL_PATH := $(call my-dir)
|
||||||
|
include $(CLEAR_VARS)
|
||||||
|
|
||||||
|
LOCAL_SRC_FILES := SystemAppDemo.apk
|
||||||
|
LOCAL_MODULE := SystemAppDemo
|
||||||
|
LOCAL_MODULE_CLASS := APPS
|
||||||
|
LOCAL_MODULE_TAGS := optional
|
||||||
|
LOCAL_CERTIFICATE := platform
|
||||||
|
LOCAL_DEX_PREOPT := false
|
||||||
|
|
||||||
|
include $(BUILD_PREBUILT)
|
BIN
code/chapter-05/SystemAppDemo/SystemAppDemo.apk
Normal file
BIN
code/chapter-05/SystemAppDemo/SystemAppDemo.apk
Normal file
Binary file not shown.
16
code/chapter-05/mysodemo/Android.mk
Normal file
16
code/chapter-05/mysodemo/Android.mk
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
LOCAL_PATH := $(call my-dir)
|
||||||
|
|
||||||
|
#--------------------------------
|
||||||
|
include $(CLEAR_VARS)
|
||||||
|
|
||||||
|
LOCAL_MODULE := libmysodemo
|
||||||
|
LOCAL_SRC_FILES_arm := libmysodemo.so
|
||||||
|
LOCAL_SRC_FILES_arm64 := libmysodemo_arm64.so
|
||||||
|
LOCAL_MODULE_TARGET_ARCHS:= arm arm64
|
||||||
|
LOCAL_MULTILIB := both
|
||||||
|
LOCAL_MODULE_SUFFIX := .so
|
||||||
|
LOCAL_MODULE_CLASS := SHARED_LIBRARIES
|
||||||
|
LOCAL_MODULE_TAGS := optional
|
||||||
|
LOCAL_SHARED_LIBRARIES := liblog
|
||||||
|
|
||||||
|
include $(BUILD_PREBUILT)
|
BIN
code/chapter-05/mysodemo/libmysodemo.so
Normal file
BIN
code/chapter-05/mysodemo/libmysodemo.so
Normal file
Binary file not shown.
BIN
code/chapter-05/mysodemo/libmysodemo_arm64.so
Normal file
BIN
code/chapter-05/mysodemo/libmysodemo_arm64.so
Normal file
Binary file not shown.
3250
code/chapter-06/ParsingPackageUtils.java
Normal file
3250
code/chapter-06/ParsingPackageUtils.java
Normal file
File diff suppressed because it is too large
Load Diff
10320
code/chapter-06/class_linker.cc
Normal file
10320
code/chapter-06/class_linker.cc
Normal file
File diff suppressed because it is too large
Load Diff
420
code/chapter-06/mikrom_service/Android.bp
Normal file
420
code/chapter-06/mikrom_service/Android.bp
Normal file
@ -0,0 +1,420 @@
|
|||||||
|
package {
|
||||||
|
// See: http://go/android-license-faq
|
||||||
|
// A large-scale-change added 'default_applicable_licenses' to import
|
||||||
|
// all of the 'license_kinds' from "frameworks_base_license"
|
||||||
|
// to get the below license kinds:
|
||||||
|
// SPDX-license-identifier-Apache-2.0
|
||||||
|
// SPDX-license-identifier-BSD
|
||||||
|
// legacy_unencumbered
|
||||||
|
default_applicable_licenses: ["frameworks_base_license"],
|
||||||
|
}
|
||||||
|
|
||||||
|
filegroup {
|
||||||
|
name: "framework-core-sources",
|
||||||
|
srcs: [
|
||||||
|
"**/*.java",
|
||||||
|
"**/*.aidl",
|
||||||
|
],
|
||||||
|
visibility: ["//frameworks/base"],
|
||||||
|
}
|
||||||
|
|
||||||
|
filegroup {
|
||||||
|
name: "IKeyAttestationApplicationIdProvider.aidl",
|
||||||
|
srcs: ["android/security/keymaster/IKeyAttestationApplicationIdProvider.aidl"],
|
||||||
|
}
|
||||||
|
|
||||||
|
filegroup {
|
||||||
|
name: "IDropBoxManagerService.aidl",
|
||||||
|
srcs: ["com/android/internal/os/IDropBoxManagerService.aidl"],
|
||||||
|
}
|
||||||
|
|
||||||
|
filegroup {
|
||||||
|
name: "ITracingServiceProxy.aidl",
|
||||||
|
srcs: ["android/tracing/ITracingServiceProxy.aidl"],
|
||||||
|
}
|
||||||
|
|
||||||
|
// These are subset of framework-core-sources that are needed by the
|
||||||
|
// android.test.mock library. The implementation of android.test.mock references
|
||||||
|
// private members of various components to allow mocking of classes that cannot
|
||||||
|
// be mocked without access to those internal implementation details.
|
||||||
|
filegroup {
|
||||||
|
name: "framework-core-sources-for-test-mock",
|
||||||
|
srcs: [
|
||||||
|
"android/accounts/AccountManagerCallback.java",
|
||||||
|
"android/accounts/AccountManagerFuture.java",
|
||||||
|
"android/accounts/AccountManager.java",
|
||||||
|
"android/accounts/AccountsException.java",
|
||||||
|
"android/accounts/AuthenticatorException.java",
|
||||||
|
"android/accounts/OperationCanceledException.java",
|
||||||
|
"android/app/Application.java",
|
||||||
|
"android/app/IApplicationThread.aidl",
|
||||||
|
"android/app/IServiceConnection.aidl",
|
||||||
|
"android/app/PackageDeleteObserver.java",
|
||||||
|
"android/content/ComponentCallbacks2.java",
|
||||||
|
"android/content/ComponentCallbacks.java",
|
||||||
|
"android/content/ContentInterface.java",
|
||||||
|
"android/content/ContentProvider.java",
|
||||||
|
"android/content/ContentProviderNative.java",
|
||||||
|
"android/content/ContentResolver.java",
|
||||||
|
"android/content/Context.java",
|
||||||
|
"android/content/ContextWrapper.java",
|
||||||
|
"android/content/DialogInterface.java",
|
||||||
|
"android/content/IContentProvider.java",
|
||||||
|
"android/content/Intent.java",
|
||||||
|
"android/content/IntentSender.java",
|
||||||
|
"android/content/OperationApplicationException.java",
|
||||||
|
"android/content/pm/ActivityInfo.java",
|
||||||
|
"android/content/pm/ApplicationInfo.java",
|
||||||
|
"android/content/pm/InstantAppInfo.java",
|
||||||
|
"android/content/pm/IPackageDataObserver.aidl",
|
||||||
|
"android/content/pm/KeySet.java",
|
||||||
|
"android/content/pm/PackageManager.java",
|
||||||
|
"android/content/pm/VerifierDeviceIdentity.java",
|
||||||
|
"android/content/res/Resources.java",
|
||||||
|
"android/database/CrossProcessCursor.java",
|
||||||
|
"android/database/CrossProcessCursorWrapper.java",
|
||||||
|
"android/database/Cursor.java",
|
||||||
|
"android/database/CursorWrapper.java",
|
||||||
|
"android/os/Binder.java",
|
||||||
|
"android/os/Bundle.java",
|
||||||
|
"android/os/IBinder.java",
|
||||||
|
"android/os/IInterface.java",
|
||||||
|
"android/os/Parcelable.java",
|
||||||
|
"android/os/ParcelFileDescriptor.java",
|
||||||
|
"android/os/RemoteException.java",
|
||||||
|
"android/os/storage/VolumeInfo.java",
|
||||||
|
"android/util/AndroidException.java",
|
||||||
|
"android/view/DisplayAdjustments.java",
|
||||||
|
"android/view/ViewDebug.java",
|
||||||
|
],
|
||||||
|
visibility: ["//frameworks/base/test-mock"],
|
||||||
|
}
|
||||||
|
|
||||||
|
filegroup {
|
||||||
|
name: "libincident_aidl",
|
||||||
|
srcs: [
|
||||||
|
"android/os/IIncidentDumpCallback.aidl",
|
||||||
|
"android/os/IIncidentManager.aidl",
|
||||||
|
"android/os/IIncidentReportStatusListener.aidl",
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
filegroup {
|
||||||
|
name: "libvibrator_aidl",
|
||||||
|
srcs: [
|
||||||
|
"android/os/IExternalVibrationController.aidl",
|
||||||
|
"android/os/IExternalVibratorService.aidl",
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
filegroup {
|
||||||
|
name: "libpowermanager_aidl",
|
||||||
|
srcs: [
|
||||||
|
"android/os/Temperature.aidl",
|
||||||
|
"android/os/CoolingDevice.aidl",
|
||||||
|
"android/os/IHintManager.aidl",
|
||||||
|
"android/os/IHintSession.aidl",
|
||||||
|
"android/os/IThermalEventListener.aidl",
|
||||||
|
"android/os/IThermalStatusListener.aidl",
|
||||||
|
"android/os/IThermalService.aidl",
|
||||||
|
"android/os/IPowerManager.aidl",
|
||||||
|
"android/os/IMikRomManager.aidl",
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
genrule {
|
||||||
|
name: "statslog-framework-java-gen",
|
||||||
|
tools: ["stats-log-api-gen"],
|
||||||
|
cmd: "$(location stats-log-api-gen) --java $(out) --module framework" +
|
||||||
|
" --javaPackage com.android.internal.util --javaClass FrameworkStatsLog --worksource",
|
||||||
|
out: ["com/android/internal/util/FrameworkStatsLog.java"],
|
||||||
|
}
|
||||||
|
|
||||||
|
java_library {
|
||||||
|
name: "uieventloggerlib",
|
||||||
|
srcs: [
|
||||||
|
"com/android/internal/logging/UiEvent.java",
|
||||||
|
"com/android/internal/logging/UiEventLogger.java",
|
||||||
|
"com/android/internal/logging/UiEventLoggerImpl.java",
|
||||||
|
"com/android/internal/logging/InstanceId.java",
|
||||||
|
"com/android/internal/logging/InstanceIdSequence.java",
|
||||||
|
":statslog-framework-java-gen",
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
filegroup {
|
||||||
|
name: "framework-services-net-module-wifi-shared-srcs",
|
||||||
|
srcs: [
|
||||||
|
"android/net/DhcpResults.java",
|
||||||
|
"android/util/LocalLog.java",
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
// keep these files in sync with the package/Tethering/jarjar-rules.txt and
|
||||||
|
// package/Connectivity/jarjar-rules.txt for the tethering module and connectivity module.
|
||||||
|
filegroup {
|
||||||
|
name: "framework-connectivity-shared-srcs",
|
||||||
|
srcs: [
|
||||||
|
"android/util/IndentingPrintWriter.java",
|
||||||
|
"android/util/LocalLog.java",
|
||||||
|
// This should be android.util.IndentingPrintWriter, but it's not available in all branches.
|
||||||
|
"com/android/internal/util/IndentingPrintWriter.java",
|
||||||
|
"com/android/internal/util/IState.java",
|
||||||
|
"com/android/internal/util/MessageUtils.java",
|
||||||
|
"com/android/internal/util/State.java",
|
||||||
|
"com/android/internal/util/StateMachine.java",
|
||||||
|
"com/android/internal/util/WakeupMessage.java",
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
// keep these files in sync with the apex/jobscheduler/service jarjar-rules.txt for
|
||||||
|
// the jobscheduler module.
|
||||||
|
filegroup {
|
||||||
|
name: "framework-jobscheduler-shared-srcs",
|
||||||
|
srcs: [
|
||||||
|
":modules-utils-preconditions-srcs",
|
||||||
|
"com/android/internal/util/ArrayUtils.java",
|
||||||
|
"com/android/internal/util/BitUtils.java",
|
||||||
|
"com/android/internal/util/CollectionUtils.java",
|
||||||
|
"com/android/internal/util/ConcurrentUtils.java",
|
||||||
|
"com/android/internal/util/DumpUtils.java",
|
||||||
|
"com/android/internal/util/FastPrintWriter.java",
|
||||||
|
"com/android/internal/util/FastXmlSerializer.java",
|
||||||
|
"com/android/internal/util/FunctionalUtils.java",
|
||||||
|
"com/android/internal/util/ParseUtils.java",
|
||||||
|
"com/android/internal/util/RingBufferIndices.java",
|
||||||
|
"com/android/internal/util/StatLogger.java",
|
||||||
|
"com/android/internal/util/XmlUtils.java",
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
// Keep these files in sync with the apex/permission/jarjar-rules.txt for the permission module.
|
||||||
|
filegroup {
|
||||||
|
name: "framework-permission-s-shared-srcs",
|
||||||
|
srcs: [
|
||||||
|
":modules-utils-preconditions-srcs",
|
||||||
|
"com/android/internal/infra/AndroidFuture.java",
|
||||||
|
"com/android/internal/infra/ServiceConnector.java",
|
||||||
|
"com/android/internal/infra/AndroidFuture.aidl",
|
||||||
|
"com/android/internal/infra/IAndroidFuture.aidl",
|
||||||
|
"android/os/HandlerExecutor.java",
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
// Keep these files in sync with the apex/permission/jarjar-rules.txt for the permission module.
|
||||||
|
filegroup {
|
||||||
|
name: "service-permission-shared-srcs",
|
||||||
|
srcs: [
|
||||||
|
"android/util/IndentingPrintWriter.java",
|
||||||
|
"com/android/internal/util/dump/DualDumpOutputStream.java",
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
filegroup {
|
||||||
|
name: "incremental_aidl",
|
||||||
|
srcs: [
|
||||||
|
"android/os/incremental/IIncrementalServiceConnector.aidl",
|
||||||
|
"android/os/incremental/IncrementalFileSystemControlParcel.aidl",
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
filegroup {
|
||||||
|
name: "dataloader_aidl",
|
||||||
|
srcs: [
|
||||||
|
"android/content/pm/DataLoaderParamsParcel.aidl",
|
||||||
|
"android/content/pm/DataLoaderType.aidl",
|
||||||
|
"android/content/pm/FileSystemControlParcel.aidl",
|
||||||
|
"android/content/pm/IDataLoader.aidl",
|
||||||
|
"android/content/pm/IDataLoaderManager.aidl",
|
||||||
|
"android/content/pm/InstallationFileParcel.aidl",
|
||||||
|
"android/content/pm/InstallationFileLocation.aidl",
|
||||||
|
"android/content/pm/IDataLoaderStatusListener.aidl",
|
||||||
|
"android/content/pm/IPackageInstallerSessionFileSystemConnector.aidl",
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
filegroup {
|
||||||
|
name: "incremental_manager_aidl",
|
||||||
|
srcs: [
|
||||||
|
"android/os/incremental/IIncrementalService.aidl",
|
||||||
|
"android/os/incremental/IStorageLoadingProgressListener.aidl",
|
||||||
|
"android/os/incremental/IncrementalNewFileParams.aidl",
|
||||||
|
"android/os/incremental/IStorageHealthListener.aidl",
|
||||||
|
"android/os/incremental/PerUidReadTimeouts.aidl",
|
||||||
|
"android/os/incremental/StorageHealthCheckParams.aidl",
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
filegroup {
|
||||||
|
name: "activity_manager_procstate_aidl",
|
||||||
|
srcs: [
|
||||||
|
"android/app/ProcessStateEnum.aidl",
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
cc_defaults {
|
||||||
|
name: "incremental_default",
|
||||||
|
cflags: [
|
||||||
|
"-Wall",
|
||||||
|
"-Wextra",
|
||||||
|
"-Wextra-semi",
|
||||||
|
"-Werror",
|
||||||
|
"-Wzero-as-null-pointer-constant",
|
||||||
|
"-DANDROID_BASE_UNIQUE_FD_DISABLE_IMPLICIT_CONVERSION",
|
||||||
|
],
|
||||||
|
shared_libs: [
|
||||||
|
"libbinder",
|
||||||
|
"libutils",
|
||||||
|
],
|
||||||
|
aidl: {
|
||||||
|
include_dirs: [
|
||||||
|
"frameworks/native/aidl/binder",
|
||||||
|
],
|
||||||
|
export_aidl_headers: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
cc_library {
|
||||||
|
name: "libincremental_aidl-cpp",
|
||||||
|
srcs: [
|
||||||
|
":incremental_aidl",
|
||||||
|
],
|
||||||
|
defaults: ["incremental_default"],
|
||||||
|
}
|
||||||
|
|
||||||
|
cc_library {
|
||||||
|
name: "libdataloader_aidl-cpp",
|
||||||
|
srcs: [
|
||||||
|
":dataloader_aidl",
|
||||||
|
],
|
||||||
|
defaults: ["incremental_default"],
|
||||||
|
shared_libs: [
|
||||||
|
"libincremental_aidl-cpp",
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
cc_library {
|
||||||
|
name: "libincremental_manager_aidl-cpp",
|
||||||
|
srcs: [
|
||||||
|
":incremental_manager_aidl",
|
||||||
|
],
|
||||||
|
defaults: ["incremental_default"],
|
||||||
|
shared_libs: [
|
||||||
|
"libincremental_aidl-cpp",
|
||||||
|
"libdataloader_aidl-cpp",
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build Rust bindings for PermissionController. Needed by keystore2.
|
||||||
|
aidl_interface {
|
||||||
|
name: "android.os.permissions_aidl",
|
||||||
|
unstable: true,
|
||||||
|
local_include_dir: ".",
|
||||||
|
srcs: [
|
||||||
|
"android/os/IPermissionController.aidl",
|
||||||
|
],
|
||||||
|
backend: {
|
||||||
|
rust: {
|
||||||
|
enabled: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
// Avoid including Parcelable classes as we don't want to have two copies of
|
||||||
|
// Parcelable cross the libraries. This is used by telephony-common (frameworks/opt/telephony)
|
||||||
|
// and TeleService app (packages/services/Telephony).
|
||||||
|
filegroup {
|
||||||
|
name: "framework-telephony-common-shared-srcs",
|
||||||
|
srcs: [
|
||||||
|
":modules-utils-preconditions-srcs",
|
||||||
|
"android/os/RegistrantList.java",
|
||||||
|
"android/os/Registrant.java",
|
||||||
|
"android/util/IndentingPrintWriter.java",
|
||||||
|
"android/util/LocalLog.java",
|
||||||
|
"android/util/TimeUtils.java",
|
||||||
|
"com/android/internal/os/SomeArgs.java",
|
||||||
|
"com/android/internal/util/AsyncChannel.java",
|
||||||
|
"com/android/internal/util/AsyncService.java",
|
||||||
|
"com/android/internal/util/BitwiseInputStream.java",
|
||||||
|
"com/android/internal/util/FastXmlSerializer.java",
|
||||||
|
"com/android/internal/util/HexDump.java",
|
||||||
|
"com/android/internal/util/IState.java",
|
||||||
|
"com/android/internal/util/IndentingPrintWriter.java",
|
||||||
|
"com/android/internal/util/State.java",
|
||||||
|
"com/android/internal/util/StateMachine.java",
|
||||||
|
"com/android/internal/util/UserIcons.java",
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
// Avoid including Parcelable classes as we don't want to have two copies of
|
||||||
|
// Parcelable cross the process.
|
||||||
|
filegroup {
|
||||||
|
name: "framework-cellbroadcast-shared-srcs",
|
||||||
|
srcs: [
|
||||||
|
":modules-utils-preconditions-srcs",
|
||||||
|
"android/os/HandlerExecutor.java",
|
||||||
|
"android/util/LocalLog.java",
|
||||||
|
"com/android/internal/util/IState.java",
|
||||||
|
"com/android/internal/util/State.java",
|
||||||
|
"com/android/internal/util/StateMachine.java",
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
filegroup {
|
||||||
|
name: "framework-ims-common-shared-srcs",
|
||||||
|
srcs: [
|
||||||
|
":modules-utils-preconditions-srcs",
|
||||||
|
"android/os/RegistrantList.java",
|
||||||
|
"android/os/Registrant.java",
|
||||||
|
"com/android/internal/os/SomeArgs.java",
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
// utility classes statically linked into wifi-service
|
||||||
|
filegroup {
|
||||||
|
name: "framework-wifi-service-shared-srcs",
|
||||||
|
srcs: [
|
||||||
|
"android/net/InterfaceConfiguration.java",
|
||||||
|
"android/util/BackupUtils.java",
|
||||||
|
"android/util/Rational.java",
|
||||||
|
"com/android/internal/util/FastXmlSerializer.java",
|
||||||
|
"com/android/internal/util/HexDump.java",
|
||||||
|
"com/android/internal/util/IState.java",
|
||||||
|
"com/android/internal/util/MessageUtils.java",
|
||||||
|
"com/android/internal/util/State.java",
|
||||||
|
"com/android/internal/util/StateMachine.java",
|
||||||
|
"com/android/internal/util/WakeupMessage.java",
|
||||||
|
],
|
||||||
|
visibility: [
|
||||||
|
"//frameworks/opt/net/wifi/service",
|
||||||
|
"//packages/modules/Wifi/service",
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
// protolog start
|
||||||
|
filegroup {
|
||||||
|
name: "protolog-common-src",
|
||||||
|
srcs: [
|
||||||
|
"com/android/internal/protolog/common/**/*.java",
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
java_library {
|
||||||
|
name: "protolog-lib",
|
||||||
|
platform_apis: true,
|
||||||
|
srcs: [
|
||||||
|
"com/android/internal/protolog/ProtoLogImpl.java",
|
||||||
|
"com/android/internal/protolog/ProtoLogViewerConfigReader.java",
|
||||||
|
":protolog-common-src",
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
java_library {
|
||||||
|
name: "protolog-groups",
|
||||||
|
srcs: [
|
||||||
|
"com/android/internal/protolog/ProtoLogGroup.java",
|
||||||
|
":protolog-common-src",
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
// protolog end
|
6922
code/chapter-06/mikrom_service/Context.java
Normal file
6922
code/chapter-06/mikrom_service/Context.java
Normal file
File diff suppressed because it is too large
Load Diff
23
code/chapter-06/mikrom_service/IMikRomManager.aidl
Normal file
23
code/chapter-06/mikrom_service/IMikRomManager.aidl
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
/* //device/java/android/android/os/IPowerManager.aidl
|
||||||
|
**
|
||||||
|
** Copyright 2007, The Android Open Source Project
|
||||||
|
**
|
||||||
|
** Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
** you may not use this file except in compliance with the License.
|
||||||
|
** You may obtain a copy of the License at
|
||||||
|
**
|
||||||
|
** http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
**
|
||||||
|
** Unless required by applicable law or agreed to in writing, software
|
||||||
|
** distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
** See the License for the specific language governing permissions and
|
||||||
|
** limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package android.os;
|
||||||
|
|
||||||
|
interface IMikRomManager
|
||||||
|
{
|
||||||
|
String hello();
|
||||||
|
}
|
46
code/chapter-06/mikrom_service/MikRomManager.java
Normal file
46
code/chapter-06/mikrom_service/MikRomManager.java
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
package android.os;
|
||||||
|
|
||||||
|
import android.annotation.NonNull;
|
||||||
|
import android.annotation.Nullable;
|
||||||
|
import android.compat.annotation.UnsupportedAppUsage;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.annotation.SystemService;
|
||||||
|
import android.os.IMikRomManager;
|
||||||
|
|
||||||
|
@SystemService(Context.MIKROM_SERVICE)
|
||||||
|
public final class MikRomManager {
|
||||||
|
private static final String TAG = "MikRomManager";
|
||||||
|
IMikRomManager mService;
|
||||||
|
public MikRomManager(IMikRomManager service) {
|
||||||
|
mService = service;
|
||||||
|
}
|
||||||
|
private static MikRomManager sInstance;
|
||||||
|
/**
|
||||||
|
*@hide
|
||||||
|
*/
|
||||||
|
@NonNull
|
||||||
|
@UnsupportedAppUsage
|
||||||
|
public static MikRomManager getInstance() {
|
||||||
|
synchronized (MikRomManager.class) {
|
||||||
|
if (sInstance == null) {
|
||||||
|
|
||||||
|
try {
|
||||||
|
IBinder mikromBinder = ServiceManager.getServiceOrThrow(Context.MIKROM_SERVICE);
|
||||||
|
IMikRomManager mikromService = IMikRomManager.Stub.asInterface(mikromBinder);
|
||||||
|
sInstance= new MikRomManager(mikromService);
|
||||||
|
} catch (ServiceManager.ServiceNotFoundException e) {
|
||||||
|
throw new IllegalStateException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return sInstance;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@Nullable
|
||||||
|
public String hello(){
|
||||||
|
try{
|
||||||
|
return mService.hello();
|
||||||
|
}catch (RemoteException ex){
|
||||||
|
throw ex.rethrowFromSystemServer();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
13
code/chapter-06/mikrom_service/MikRomManagerService.java
Normal file
13
code/chapter-06/mikrom_service/MikRomManagerService.java
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
package com.android.server;
|
||||||
|
|
||||||
|
import android.os.RemoteException;
|
||||||
|
import android.os.IMikRomManager;
|
||||||
|
|
||||||
|
public class MikRomManagerService extends IMikRomManager.Stub {
|
||||||
|
|
||||||
|
private String TAG="MikRomManagerService";
|
||||||
|
@Override
|
||||||
|
public String hello() throws RemoteException{
|
||||||
|
return "hello mikrom service";
|
||||||
|
}
|
||||||
|
}
|
3066
code/chapter-06/mikrom_service/SystemServer.java
Normal file
3066
code/chapter-06/mikrom_service/SystemServer.java
Normal file
File diff suppressed because it is too large
Load Diff
1969
code/chapter-06/mikrom_service/SystemServiceRegistry.java
Normal file
1969
code/chapter-06/mikrom_service/SystemServiceRegistry.java
Normal file
File diff suppressed because it is too large
Load Diff
BIN
code/chapter-08/apkjiagu.7z
Normal file
BIN
code/chapter-08/apkjiagu.7z
Normal file
Binary file not shown.
BIN
code/chapter-09/PineDemo.zip
Normal file
BIN
code/chapter-09/PineDemo.zip
Normal file
Binary file not shown.
BIN
code/chapter-12/NativeDemo.zip
Normal file
BIN
code/chapter-12/NativeDemo.zip
Normal file
Binary file not shown.
45
code/chapter-12/backtrace/Android.mk
Normal file
45
code/chapter-12/backtrace/Android.mk
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
|
||||||
|
#--------------------------------
|
||||||
|
include $(CLEAR_VARS)
|
||||||
|
|
||||||
|
LOCAL_MODULE := libxdl
|
||||||
|
LOCAL_SRC_FILES_arm := libxdl.so
|
||||||
|
LOCAL_SRC_FILES_arm64 := libxdl_arm64.so
|
||||||
|
LOCAL_MODULE_TARGET_ARCHS:= arm arm64
|
||||||
|
LOCAL_MULTILIB := both
|
||||||
|
LOCAL_MODULE_SUFFIX := .so
|
||||||
|
LOCAL_MODULE_CLASS := SHARED_LIBRARIES
|
||||||
|
LOCAL_MODULE_TAGS := optional
|
||||||
|
LOCAL_SHARED_LIBRARIES := liblog
|
||||||
|
|
||||||
|
include $(BUILD_PREBUILT)
|
||||||
|
|
||||||
|
#--------------------------------
|
||||||
|
include $(CLEAR_VARS)
|
||||||
|
|
||||||
|
LOCAL_MODULE := libxunwind
|
||||||
|
LOCAL_SRC_FILES_arm := libxunwind.so
|
||||||
|
LOCAL_SRC_FILES_arm64 := libxunwind_arm64.so
|
||||||
|
LOCAL_MODULE_TARGET_ARCHS:= arm arm64
|
||||||
|
LOCAL_MULTILIB := both
|
||||||
|
LOCAL_MODULE_SUFFIX := .so
|
||||||
|
LOCAL_MODULE_CLASS := SHARED_LIBRARIES
|
||||||
|
LOCAL_MODULE_TAGS := optional
|
||||||
|
LOCAL_SHARED_LIBRARIES := liblog libxdl
|
||||||
|
|
||||||
|
include $(BUILD_PREBUILT)
|
||||||
|
|
||||||
|
#--------------------------------
|
||||||
|
include $(CLEAR_VARS)
|
||||||
|
|
||||||
|
LOCAL_MODULE := libkbacktrace
|
||||||
|
LOCAL_SRC_FILES_arm := libkbacktrace_32.so
|
||||||
|
LOCAL_SRC_FILES_arm64 := libkbacktrace_64.so
|
||||||
|
LOCAL_MODULE_TARGET_ARCHS:= arm arm64
|
||||||
|
LOCAL_MULTILIB := both
|
||||||
|
LOCAL_MODULE_SUFFIX := .so
|
||||||
|
LOCAL_MODULE_CLASS := SHARED_LIBRARIES
|
||||||
|
LOCAL_MODULE_TAGS := optional
|
||||||
|
LOCAL_SHARED_LIBRARIES := liblog libxunwind
|
||||||
|
|
||||||
|
include $(BUILD_PREBUILT)
|
BIN
code/chapter-12/backtrace/libkbacktrace_32.so
Normal file
BIN
code/chapter-12/backtrace/libkbacktrace_32.so
Normal file
Binary file not shown.
BIN
code/chapter-12/backtrace/libkbacktrace_64.so
Normal file
BIN
code/chapter-12/backtrace/libkbacktrace_64.so
Normal file
Binary file not shown.
BIN
code/chapter-12/backtrace/libxdl.so
Normal file
BIN
code/chapter-12/backtrace/libxdl.so
Normal file
Binary file not shown.
BIN
code/chapter-12/backtrace/libxdl_arm64.so
Normal file
BIN
code/chapter-12/backtrace/libxdl_arm64.so
Normal file
Binary file not shown.
BIN
code/chapter-12/backtrace/libxunwind.so
Normal file
BIN
code/chapter-12/backtrace/libxunwind.so
Normal file
Binary file not shown.
BIN
code/chapter-12/backtrace/libxunwind_arm64.so
Normal file
BIN
code/chapter-12/backtrace/libxunwind_arm64.so
Normal file
Binary file not shown.
BIN
code/chapter-12/backtraceDemo.zip
Normal file
BIN
code/chapter-12/backtraceDemo.zip
Normal file
Binary file not shown.
1050
code/chapter-12/dalvik_system_DexFile.cc
Normal file
1050
code/chapter-12/dalvik_system_DexFile.cc
Normal file
File diff suppressed because it is too large
Load Diff
3444
code/chapter-12/jni_internal.cc
Normal file
3444
code/chapter-12/jni_internal.cc
Normal file
File diff suppressed because it is too large
Load Diff
391
code/chapter-12/quick_jni_entrypoints.cc
Normal file
391
code/chapter-12/quick_jni_entrypoints.cc
Normal file
@ -0,0 +1,391 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2012 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <android-base/logging.h>
|
||||||
|
|
||||||
|
#include "art_method-inl.h"
|
||||||
|
#include "base/casts.h"
|
||||||
|
#include "entrypoints/entrypoint_utils-inl.h"
|
||||||
|
#include "indirect_reference_table.h"
|
||||||
|
#include "mirror/object-inl.h"
|
||||||
|
#include "palette/palette.h"
|
||||||
|
#include "thread-inl.h"
|
||||||
|
#include "verify_object.h"
|
||||||
|
#include "utils/Log.h"
|
||||||
|
|
||||||
|
// For methods that monitor JNI invocations and report their begin/end to
|
||||||
|
// palette hooks.
|
||||||
|
#define MONITOR_JNI(kind) \
|
||||||
|
{ \
|
||||||
|
bool should_report = false; \
|
||||||
|
PaletteShouldReportJniInvocations(&should_report); \
|
||||||
|
if (should_report) { \
|
||||||
|
kind(self->GetJniEnv()); \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace art {
|
||||||
|
|
||||||
|
static_assert(sizeof(IRTSegmentState) == sizeof(uint32_t), "IRTSegmentState size unexpected");
|
||||||
|
static_assert(std::is_trivial<IRTSegmentState>::value, "IRTSegmentState not trivial");
|
||||||
|
|
||||||
|
static inline void GoToRunnableFast(Thread* self) REQUIRES_SHARED(Locks::mutator_lock_);
|
||||||
|
|
||||||
|
extern void ReadBarrierJni(mirror::CompressedReference<mirror::Class>* declaring_class,
|
||||||
|
Thread* self ATTRIBUTE_UNUSED) {
|
||||||
|
DCHECK(kUseReadBarrier);
|
||||||
|
if (kUseBakerReadBarrier) {
|
||||||
|
DCHECK(declaring_class->AsMirrorPtr() != nullptr)
|
||||||
|
<< "The class of a static jni call must not be null";
|
||||||
|
// Check the mark bit and return early if it's already marked.
|
||||||
|
if (LIKELY(declaring_class->AsMirrorPtr()->GetMarkBit() != 0)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Call the read barrier and update the handle.
|
||||||
|
mirror::Class* to_ref = ReadBarrier::BarrierForRoot(declaring_class);
|
||||||
|
declaring_class->Assign(to_ref);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Called on entry to fast JNI, push a new local reference table only.
|
||||||
|
extern uint32_t JniMethodFastStart(Thread* self) {
|
||||||
|
JNIEnvExt* env = self->GetJniEnv();
|
||||||
|
DCHECK(env != nullptr);
|
||||||
|
uint32_t saved_local_ref_cookie = bit_cast<uint32_t>(env->GetLocalRefCookie());
|
||||||
|
env->SetLocalRefCookie(env->GetLocalsSegmentState());
|
||||||
|
|
||||||
|
if (kIsDebugBuild) {
|
||||||
|
ArtMethod* native_method = *self->GetManagedStack()->GetTopQuickFrame();
|
||||||
|
CHECK(native_method->IsFastNative()) << native_method->PrettyMethod();
|
||||||
|
}
|
||||||
|
|
||||||
|
return saved_local_ref_cookie;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Called on entry to JNI, transition out of Runnable and release share of mutator_lock_.
|
||||||
|
extern uint32_t JniMethodStart(Thread* self) {
|
||||||
|
JNIEnvExt* env = self->GetJniEnv();
|
||||||
|
DCHECK(env != nullptr);
|
||||||
|
uint32_t saved_local_ref_cookie = bit_cast<uint32_t>(env->GetLocalRefCookie());
|
||||||
|
env->SetLocalRefCookie(env->GetLocalsSegmentState());
|
||||||
|
//add mikrom
|
||||||
|
Runtime* runtime=Runtime::Current();
|
||||||
|
if(runtime->GetConfigItem().isJNIMethodPrint){
|
||||||
|
ArtMethod* native_method = *self->GetManagedStack()->GetTopQuickFrame();
|
||||||
|
std::string methodname=native_method->PrettyMethod();
|
||||||
|
if(strstr(methodname.c_str(),runtime->GetConfigItem().jniFuncName)){
|
||||||
|
ALOGD("mikrom enter jni %s %p",methodname.c_str(),self);
|
||||||
|
runtime->GetConfigItem().jniEnable=true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//endadd
|
||||||
|
if (kIsDebugBuild) {
|
||||||
|
ArtMethod* native_method = *self->GetManagedStack()->GetTopQuickFrame();
|
||||||
|
CHECK(!native_method->IsFastNative()) << native_method->PrettyMethod();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Transition out of runnable.
|
||||||
|
self->TransitionFromRunnableToSuspended(kNative);
|
||||||
|
return saved_local_ref_cookie;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern uint32_t JniMethodStartSynchronized(jobject to_lock, Thread* self) {
|
||||||
|
self->DecodeJObject(to_lock)->MonitorEnter(self);
|
||||||
|
return JniMethodStart(self);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: NO_THREAD_SAFETY_ANALYSIS due to different control paths depending on fast JNI.
|
||||||
|
static void GoToRunnable(Thread* self) NO_THREAD_SAFETY_ANALYSIS {
|
||||||
|
if (kIsDebugBuild) {
|
||||||
|
ArtMethod* native_method = *self->GetManagedStack()->GetTopQuickFrame();
|
||||||
|
CHECK(!native_method->IsFastNative()) << native_method->PrettyMethod();
|
||||||
|
}
|
||||||
|
|
||||||
|
self->TransitionFromSuspendedToRunnable();
|
||||||
|
}
|
||||||
|
|
||||||
|
ALWAYS_INLINE static inline void GoToRunnableFast(Thread* self) {
|
||||||
|
if (kIsDebugBuild) {
|
||||||
|
// Should only enter here if the method is @FastNative.
|
||||||
|
ArtMethod* native_method = *self->GetManagedStack()->GetTopQuickFrame();
|
||||||
|
CHECK(native_method->IsFastNative()) << native_method->PrettyMethod();
|
||||||
|
}
|
||||||
|
|
||||||
|
// When we are in @FastNative, we are already Runnable.
|
||||||
|
// Only do a suspend check on the way out of JNI.
|
||||||
|
if (UNLIKELY(self->TestAllFlags())) {
|
||||||
|
// In fast JNI mode we never transitioned out of runnable. Perform a suspend check if there
|
||||||
|
// is a flag raised.
|
||||||
|
DCHECK(Locks::mutator_lock_->IsSharedHeld(self));
|
||||||
|
self->CheckSuspend();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void PopLocalReferences(uint32_t saved_local_ref_cookie, Thread* self)
|
||||||
|
REQUIRES_SHARED(Locks::mutator_lock_) {
|
||||||
|
JNIEnvExt* env = self->GetJniEnv();
|
||||||
|
if (UNLIKELY(env->IsCheckJniEnabled())) {
|
||||||
|
env->CheckNoHeldMonitors();
|
||||||
|
}
|
||||||
|
env->SetLocalSegmentState(env->GetLocalRefCookie());
|
||||||
|
env->SetLocalRefCookie(bit_cast<IRTSegmentState>(saved_local_ref_cookie));
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: annotalysis disabled as monitor semantics are maintained in Java code.
|
||||||
|
static inline void UnlockJniSynchronizedMethod(jobject locked, Thread* self)
|
||||||
|
NO_THREAD_SAFETY_ANALYSIS REQUIRES(!Roles::uninterruptible_) {
|
||||||
|
// Save any pending exception over monitor exit call.
|
||||||
|
ObjPtr<mirror::Throwable> saved_exception = nullptr;
|
||||||
|
if (UNLIKELY(self->IsExceptionPending())) {
|
||||||
|
saved_exception = self->GetException();
|
||||||
|
self->ClearException();
|
||||||
|
}
|
||||||
|
// Decode locked object and unlock, before popping local references.
|
||||||
|
self->DecodeJObject(locked)->MonitorExit(self);
|
||||||
|
if (UNLIKELY(self->IsExceptionPending())) {
|
||||||
|
LOG(FATAL) << "Synchronized JNI code returning with an exception:\n"
|
||||||
|
<< saved_exception->Dump()
|
||||||
|
<< "\nEncountered second exception during implicit MonitorExit:\n"
|
||||||
|
<< self->GetException()->Dump();
|
||||||
|
}
|
||||||
|
// Restore pending exception.
|
||||||
|
if (saved_exception != nullptr) {
|
||||||
|
self->SetException(saved_exception);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: These should probably be templatized or macro-ized.
|
||||||
|
// Otherwise there's just too much repetitive boilerplate.
|
||||||
|
|
||||||
|
extern void JniMethodEnd(uint32_t saved_local_ref_cookie, Thread* self) {
|
||||||
|
|
||||||
|
//add mikrom
|
||||||
|
Runtime* runtime=Runtime::Current();
|
||||||
|
if(runtime->GetConfigItem().isJNIMethodPrint){
|
||||||
|
ArtMethod* native_method = *self->GetManagedStack()->GetTopQuickFrame();
|
||||||
|
std::string methodname=native_method->PrettyMethod();
|
||||||
|
ALOGD("mikrom JniMethodEnd jni %s",methodname.c_str());
|
||||||
|
if(strstr(methodname.c_str(),runtime->GetConfigItem().jniFuncName)){
|
||||||
|
runtime->GetConfigItem().jniEnable=false;
|
||||||
|
ALOGD("mikrom leave jni %s",methodname.c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//endadd
|
||||||
|
// ArtMethod* native_method = *self->GetManagedStack()->GetTopQuickFrame();
|
||||||
|
// if(native_method!=nullptr){
|
||||||
|
// std::string methodname=native_method->PrettyMethod();
|
||||||
|
// ALOGD("mikrom JniMethodEnd %s",methodname.c_str());
|
||||||
|
// }
|
||||||
|
|
||||||
|
GoToRunnable(self);
|
||||||
|
PopLocalReferences(saved_local_ref_cookie, self);
|
||||||
|
}
|
||||||
|
|
||||||
|
extern void JniMethodFastEnd(uint32_t saved_local_ref_cookie, Thread* self) {
|
||||||
|
// ArtMethod* native_method = *self->GetManagedStack()->GetTopQuickFrame();
|
||||||
|
// if(native_method!=nullptr){
|
||||||
|
// std::string methodname=native_method->PrettyMethod();
|
||||||
|
// ALOGD("mikrom JniMethodFastEnd %s",methodname.c_str());
|
||||||
|
// }
|
||||||
|
GoToRunnableFast(self);
|
||||||
|
PopLocalReferences(saved_local_ref_cookie, self);
|
||||||
|
}
|
||||||
|
|
||||||
|
extern void JniMethodEndSynchronized(uint32_t saved_local_ref_cookie,
|
||||||
|
jobject locked,
|
||||||
|
Thread* self) {
|
||||||
|
// ArtMethod* native_method = *self->GetManagedStack()->GetTopQuickFrame();
|
||||||
|
// if(native_method!=nullptr){
|
||||||
|
// std::string methodname=native_method->PrettyMethod();
|
||||||
|
// ALOGD("mikrom JniMethodEndSynchronized %s",methodname.c_str());
|
||||||
|
// }
|
||||||
|
GoToRunnable(self);
|
||||||
|
UnlockJniSynchronizedMethod(locked, self); // Must decode before pop.
|
||||||
|
PopLocalReferences(saved_local_ref_cookie, self);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Common result handling for EndWithReference.
|
||||||
|
static mirror::Object* JniMethodEndWithReferenceHandleResult(jobject result,
|
||||||
|
uint32_t saved_local_ref_cookie,
|
||||||
|
Thread* self)
|
||||||
|
NO_THREAD_SAFETY_ANALYSIS {
|
||||||
|
|
||||||
|
//add mikrom
|
||||||
|
Runtime* runtime=Runtime::Current();
|
||||||
|
if(runtime->GetConfigItem().isJNIMethodPrint){
|
||||||
|
ArtMethod* native_method = *self->GetManagedStack()->GetTopQuickFrame();
|
||||||
|
std::string methodname=native_method->PrettyMethod();
|
||||||
|
if(strstr(methodname.c_str(),runtime->GetConfigItem().jniFuncName)){
|
||||||
|
runtime->GetConfigItem().jniEnable=false;
|
||||||
|
ALOGD("mikrom leave jni %s",methodname.c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//endadd
|
||||||
|
// ArtMethod* native_method = *self->GetManagedStack()->GetTopQuickFrame();
|
||||||
|
// if(native_method!=nullptr){
|
||||||
|
// std::string methodname=native_method->PrettyMethod();
|
||||||
|
// ALOGD("mikrom JniMethodEndWithReferenceHandleResult %s",methodname.c_str());
|
||||||
|
// }
|
||||||
|
// Must decode before pop. The 'result' may not be valid in case of an exception, though.
|
||||||
|
ObjPtr<mirror::Object> o;
|
||||||
|
if (!self->IsExceptionPending()) {
|
||||||
|
o = self->DecodeJObject(result);
|
||||||
|
}
|
||||||
|
PopLocalReferences(saved_local_ref_cookie, self);
|
||||||
|
// Process result.
|
||||||
|
if (UNLIKELY(self->GetJniEnv()->IsCheckJniEnabled())) {
|
||||||
|
// CheckReferenceResult can resolve types.
|
||||||
|
StackHandleScope<1> hs(self);
|
||||||
|
HandleWrapperObjPtr<mirror::Object> h_obj(hs.NewHandleWrapper(&o));
|
||||||
|
CheckReferenceResult(h_obj, self);
|
||||||
|
}
|
||||||
|
VerifyObject(o);
|
||||||
|
return o.Ptr();
|
||||||
|
}
|
||||||
|
|
||||||
|
extern mirror::Object* JniMethodFastEndWithReference(jobject result,
|
||||||
|
uint32_t saved_local_ref_cookie,
|
||||||
|
Thread* self) {
|
||||||
|
GoToRunnableFast(self);
|
||||||
|
return JniMethodEndWithReferenceHandleResult(result, saved_local_ref_cookie, self);
|
||||||
|
}
|
||||||
|
|
||||||
|
extern mirror::Object* JniMethodEndWithReference(jobject result,
|
||||||
|
uint32_t saved_local_ref_cookie,
|
||||||
|
Thread* self) {
|
||||||
|
GoToRunnable(self);
|
||||||
|
return JniMethodEndWithReferenceHandleResult(result, saved_local_ref_cookie, self);
|
||||||
|
}
|
||||||
|
|
||||||
|
extern mirror::Object* JniMethodEndWithReferenceSynchronized(jobject result,
|
||||||
|
uint32_t saved_local_ref_cookie,
|
||||||
|
jobject locked,
|
||||||
|
Thread* self) {
|
||||||
|
GoToRunnable(self);
|
||||||
|
UnlockJniSynchronizedMethod(locked, self);
|
||||||
|
return JniMethodEndWithReferenceHandleResult(result, saved_local_ref_cookie, self);
|
||||||
|
}
|
||||||
|
|
||||||
|
extern uint64_t GenericJniMethodEnd(Thread* self,
|
||||||
|
uint32_t saved_local_ref_cookie,
|
||||||
|
jvalue result,
|
||||||
|
uint64_t result_f,
|
||||||
|
ArtMethod* called)
|
||||||
|
// TODO: NO_THREAD_SAFETY_ANALYSIS as GoToRunnable() is NO_THREAD_SAFETY_ANALYSIS
|
||||||
|
NO_THREAD_SAFETY_ANALYSIS {
|
||||||
|
// ALOGD("mikrom GenericJniMethodEnd ");
|
||||||
|
bool critical_native = called->IsCriticalNative();
|
||||||
|
bool fast_native = called->IsFastNative();
|
||||||
|
bool normal_native = !critical_native && !fast_native;
|
||||||
|
|
||||||
|
// @CriticalNative does not do a state transition. @FastNative usually does not do a state
|
||||||
|
// transition either but it performs a suspend check that may do state transitions.
|
||||||
|
if (LIKELY(normal_native)) {
|
||||||
|
MONITOR_JNI(PaletteNotifyEndJniInvocation);
|
||||||
|
GoToRunnable(self);
|
||||||
|
} else if (fast_native) {
|
||||||
|
GoToRunnableFast(self);
|
||||||
|
}
|
||||||
|
// We need the mutator lock (i.e., calling GoToRunnable()) before accessing the shorty or the
|
||||||
|
// locked object.
|
||||||
|
if (called->IsSynchronized()) {
|
||||||
|
DCHECK(normal_native) << "@FastNative/@CriticalNative and synchronize is not supported";
|
||||||
|
jobject lock = GetGenericJniSynchronizationObject(self, called);
|
||||||
|
DCHECK(lock != nullptr);
|
||||||
|
UnlockJniSynchronizedMethod(lock, self);
|
||||||
|
}
|
||||||
|
char return_shorty_char = called->GetShorty()[0];
|
||||||
|
if (return_shorty_char == 'L') {
|
||||||
|
return reinterpret_cast<uint64_t>(JniMethodEndWithReferenceHandleResult(
|
||||||
|
result.l, saved_local_ref_cookie, self));
|
||||||
|
} else {
|
||||||
|
if (LIKELY(!critical_native)) {
|
||||||
|
PopLocalReferences(saved_local_ref_cookie, self);
|
||||||
|
}
|
||||||
|
switch (return_shorty_char) {
|
||||||
|
case 'F': {
|
||||||
|
if (kRuntimeISA == InstructionSet::kX86) {
|
||||||
|
// Convert back the result to float.
|
||||||
|
double d = bit_cast<double, uint64_t>(result_f);
|
||||||
|
return bit_cast<uint32_t, float>(static_cast<float>(d));
|
||||||
|
} else {
|
||||||
|
return result_f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case 'D':
|
||||||
|
return result_f;
|
||||||
|
case 'Z':
|
||||||
|
return result.z;
|
||||||
|
case 'B':
|
||||||
|
return result.b;
|
||||||
|
case 'C':
|
||||||
|
return result.c;
|
||||||
|
case 'S':
|
||||||
|
return result.s;
|
||||||
|
case 'I':
|
||||||
|
return result.i;
|
||||||
|
case 'J':
|
||||||
|
return result.j;
|
||||||
|
case 'V':
|
||||||
|
return 0;
|
||||||
|
default:
|
||||||
|
LOG(FATAL) << "Unexpected return shorty character " << return_shorty_char;
|
||||||
|
UNREACHABLE();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extern uint32_t JniMonitoredMethodStart(Thread* self) {
|
||||||
|
uint32_t result = JniMethodStart(self);
|
||||||
|
MONITOR_JNI(PaletteNotifyBeginJniInvocation);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern uint32_t JniMonitoredMethodStartSynchronized(jobject to_lock, Thread* self) {
|
||||||
|
uint32_t result = JniMethodStartSynchronized(to_lock, self);
|
||||||
|
MONITOR_JNI(PaletteNotifyBeginJniInvocation);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern void JniMonitoredMethodEnd(uint32_t saved_local_ref_cookie, Thread* self) {
|
||||||
|
MONITOR_JNI(PaletteNotifyEndJniInvocation);
|
||||||
|
return JniMethodEnd(saved_local_ref_cookie, self);
|
||||||
|
}
|
||||||
|
|
||||||
|
extern void JniMonitoredMethodEndSynchronized(uint32_t saved_local_ref_cookie,
|
||||||
|
jobject locked,
|
||||||
|
Thread* self) {
|
||||||
|
MONITOR_JNI(PaletteNotifyEndJniInvocation);
|
||||||
|
return JniMethodEndSynchronized(saved_local_ref_cookie, locked, self);
|
||||||
|
}
|
||||||
|
|
||||||
|
extern mirror::Object* JniMonitoredMethodEndWithReference(jobject result,
|
||||||
|
uint32_t saved_local_ref_cookie,
|
||||||
|
Thread* self) {
|
||||||
|
MONITOR_JNI(PaletteNotifyEndJniInvocation);
|
||||||
|
return JniMethodEndWithReference(result, saved_local_ref_cookie, self);
|
||||||
|
}
|
||||||
|
|
||||||
|
extern mirror::Object* JniMonitoredMethodEndWithReferenceSynchronized(
|
||||||
|
jobject result,
|
||||||
|
uint32_t saved_local_ref_cookie,
|
||||||
|
jobject locked,
|
||||||
|
Thread* self) {
|
||||||
|
MONITOR_JNI(PaletteNotifyEndJniInvocation);
|
||||||
|
return JniMethodEndWithReferenceSynchronized(result, saved_local_ref_cookie, locked, self);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace art
|
1258
code/chapter-12/reflection.cc
Normal file
1258
code/chapter-12/reflection.cc
Normal file
File diff suppressed because it is too large
Load Diff
177
code/chapter-12/reflection.h
Normal file
177
code/chapter-12/reflection.h
Normal file
@ -0,0 +1,177 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2011 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef ART_RUNTIME_REFLECTION_H_
|
||||||
|
#define ART_RUNTIME_REFLECTION_H_
|
||||||
|
|
||||||
|
#include "base/enums.h"
|
||||||
|
#include "base/locks.h"
|
||||||
|
#include "dex/primitive.h"
|
||||||
|
#include "jni.h"
|
||||||
|
#include "obj_ptr.h"
|
||||||
|
|
||||||
|
namespace art {
|
||||||
|
namespace mirror {
|
||||||
|
class Class;
|
||||||
|
class Object;
|
||||||
|
} // namespace mirror
|
||||||
|
class ArtField;
|
||||||
|
class ArtMethod;
|
||||||
|
union JValue;
|
||||||
|
class ScopedObjectAccessAlreadyRunnable;
|
||||||
|
class ShadowFrame;
|
||||||
|
|
||||||
|
ObjPtr<mirror::Object> BoxPrimitive(Primitive::Type src_class, const JValue& value)
|
||||||
|
REQUIRES_SHARED(Locks::mutator_lock_);
|
||||||
|
|
||||||
|
bool UnboxPrimitiveForField(ObjPtr<mirror::Object> o,
|
||||||
|
ObjPtr<mirror::Class> dst_class,
|
||||||
|
ArtField* f,
|
||||||
|
JValue* unboxed_value)
|
||||||
|
REQUIRES_SHARED(Locks::mutator_lock_);
|
||||||
|
|
||||||
|
bool UnboxPrimitiveForResult(ObjPtr<mirror::Object> o,
|
||||||
|
ObjPtr<mirror::Class> dst_class,
|
||||||
|
JValue* unboxed_value)
|
||||||
|
REQUIRES_SHARED(Locks::mutator_lock_);
|
||||||
|
|
||||||
|
ALWAYS_INLINE bool ConvertPrimitiveValueNoThrow(Primitive::Type src_class,
|
||||||
|
Primitive::Type dst_class,
|
||||||
|
const JValue& src,
|
||||||
|
JValue* dst)
|
||||||
|
REQUIRES_SHARED(Locks::mutator_lock_);
|
||||||
|
|
||||||
|
ALWAYS_INLINE bool ConvertPrimitiveValue(bool unbox_for_result,
|
||||||
|
Primitive::Type src_class,
|
||||||
|
Primitive::Type dst_class,
|
||||||
|
const JValue& src,
|
||||||
|
JValue* dst)
|
||||||
|
REQUIRES_SHARED(Locks::mutator_lock_);
|
||||||
|
|
||||||
|
// Invokes the given method (either an ArtMethod or a jmethodID) with direct/static semantics.
|
||||||
|
template<typename MethodType>
|
||||||
|
JValue InvokeWithVarArgs(const ScopedObjectAccessAlreadyRunnable& soa,
|
||||||
|
jobject obj,
|
||||||
|
MethodType mid,
|
||||||
|
va_list args)
|
||||||
|
REQUIRES_SHARED(Locks::mutator_lock_);
|
||||||
|
|
||||||
|
// Invokes the given method (either an ArtMethod or a jmethodID) with reflection semantics.
|
||||||
|
template<typename MethodType>
|
||||||
|
JValue InvokeWithJValues(const ScopedObjectAccessAlreadyRunnable& soa,
|
||||||
|
jobject obj,
|
||||||
|
MethodType mid,
|
||||||
|
const jvalue* args)
|
||||||
|
REQUIRES_SHARED(Locks::mutator_lock_);
|
||||||
|
|
||||||
|
// Invokes the given method (either an ArtMethod or a jmethodID) with virtual/interface semantics.
|
||||||
|
// Note this will perform lookup based on the 'obj' to determine which implementation of the given
|
||||||
|
// method should be invoked.
|
||||||
|
template<typename MethodType>
|
||||||
|
JValue InvokeVirtualOrInterfaceWithJValues(const ScopedObjectAccessAlreadyRunnable& soa,
|
||||||
|
jobject obj,
|
||||||
|
MethodType mid,
|
||||||
|
const jvalue* args)
|
||||||
|
REQUIRES_SHARED(Locks::mutator_lock_);
|
||||||
|
|
||||||
|
// Invokes the given method (either an ArtMethod or a jmethodID) with virtual/interface semantics.
|
||||||
|
// Note this will perform lookup based on the 'obj' to determine which implementation of the given
|
||||||
|
// method should be invoked.
|
||||||
|
template<typename MethodType>
|
||||||
|
JValue InvokeVirtualOrInterfaceWithVarArgs(const ScopedObjectAccessAlreadyRunnable& soa,
|
||||||
|
jobject obj,
|
||||||
|
MethodType mid,
|
||||||
|
va_list args)
|
||||||
|
REQUIRES_SHARED(Locks::mutator_lock_);
|
||||||
|
|
||||||
|
// num_frames is number of frames we look up for access check.
|
||||||
|
template<PointerSize pointer_size>
|
||||||
|
jobject InvokeMethod(const ScopedObjectAccessAlreadyRunnable& soa,
|
||||||
|
jobject method,
|
||||||
|
jobject receiver,
|
||||||
|
jobject args,
|
||||||
|
size_t num_frames = 1)
|
||||||
|
REQUIRES_SHARED(Locks::mutator_lock_);
|
||||||
|
|
||||||
|
void ShowVarArgs(const ScopedObjectAccessAlreadyRunnable& ,
|
||||||
|
const char* funcname,
|
||||||
|
const char* data )
|
||||||
|
REQUIRES_SHARED(Locks::mutator_lock_);
|
||||||
|
|
||||||
|
void ShowVarArgs(const ScopedObjectAccessAlreadyRunnable& ,
|
||||||
|
const char* funcname,
|
||||||
|
jboolean* is_copy ,
|
||||||
|
const char* data )
|
||||||
|
REQUIRES_SHARED(Locks::mutator_lock_);
|
||||||
|
|
||||||
|
void ShowVarArgs(const ScopedObjectAccessAlreadyRunnable& soa,const char* funcname,
|
||||||
|
jclass java_class, const char* name, const char* sig,jmethodID methodID)
|
||||||
|
REQUIRES_SHARED(Locks::mutator_lock_);
|
||||||
|
|
||||||
|
void ShowVarArgs(const ScopedObjectAccessAlreadyRunnable& soa,
|
||||||
|
const char* funcname,
|
||||||
|
jmethodID mid,
|
||||||
|
va_list valist)
|
||||||
|
REQUIRES_SHARED(Locks::mutator_lock_);
|
||||||
|
|
||||||
|
void ShowVarArgs(const ScopedObjectAccessAlreadyRunnable& soa,
|
||||||
|
const char* funcname,
|
||||||
|
jmethodID mid,
|
||||||
|
va_list valist,
|
||||||
|
jobject ret)
|
||||||
|
REQUIRES_SHARED(Locks::mutator_lock_);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Special-casing of the above. Assumes that the method is the correct constructor, the class is
|
||||||
|
// initialized, and that the receiver is an instance of the class.
|
||||||
|
void InvokeConstructor(const ScopedObjectAccessAlreadyRunnable& soa,
|
||||||
|
ArtMethod* constructor,
|
||||||
|
ObjPtr<mirror::Object> receiver,
|
||||||
|
jobject args)
|
||||||
|
REQUIRES_SHARED(Locks::mutator_lock_);
|
||||||
|
|
||||||
|
ALWAYS_INLINE bool VerifyObjectIsClass(ObjPtr<mirror::Object> o, ObjPtr<mirror::Class> c)
|
||||||
|
REQUIRES_SHARED(Locks::mutator_lock_);
|
||||||
|
|
||||||
|
bool VerifyAccess(Thread* self,
|
||||||
|
ObjPtr<mirror::Object> obj,
|
||||||
|
ObjPtr<mirror::Class> declaring_class,
|
||||||
|
uint32_t access_flags,
|
||||||
|
ObjPtr<mirror::Class>* calling_class,
|
||||||
|
size_t num_frames)
|
||||||
|
REQUIRES_SHARED(Locks::mutator_lock_);
|
||||||
|
|
||||||
|
// This version takes a known calling class.
|
||||||
|
bool VerifyAccess(ObjPtr<mirror::Object> obj,
|
||||||
|
ObjPtr<mirror::Class> declaring_class,
|
||||||
|
uint32_t access_flags,
|
||||||
|
ObjPtr<mirror::Class> calling_class)
|
||||||
|
REQUIRES_SHARED(Locks::mutator_lock_);
|
||||||
|
|
||||||
|
// Get the calling class by using a stack visitor, may return null for unattached native threads.
|
||||||
|
ObjPtr<mirror::Class> GetCallingClass(Thread* self, size_t num_frames)
|
||||||
|
REQUIRES_SHARED(Locks::mutator_lock_);
|
||||||
|
|
||||||
|
void InvalidReceiverError(ObjPtr<mirror::Object> o, ObjPtr<mirror::Class> c)
|
||||||
|
REQUIRES_SHARED(Locks::mutator_lock_);
|
||||||
|
|
||||||
|
void UpdateReference(Thread* self, jobject obj, ObjPtr<mirror::Object> result)
|
||||||
|
REQUIRES_SHARED(Locks::mutator_lock_);
|
||||||
|
|
||||||
|
} // namespace art
|
||||||
|
|
||||||
|
#endif // ART_RUNTIME_REFLECTION_H_
|
1478
code/chapter-12/runtime.h
Normal file
1478
code/chapter-12/runtime.h
Normal file
File diff suppressed because it is too large
Load Diff
BIN
code/chapter-12/xUnwind.zip
Normal file
BIN
code/chapter-12/xUnwind.zip
Normal file
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user