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