diff --git a/bib-style.csl b/ieee-bib-style.csl similarity index 100% rename from bib-style.csl rename to ieee-bib-style.csl diff --git a/images/presentation/android-blue.png b/images/presentation/android-blue.png new file mode 100644 index 0000000..63e1afe Binary files /dev/null and b/images/presentation/android-blue.png differ diff --git a/images/presentation/android.png b/images/presentation/android.png new file mode 100644 index 0000000..7ebd1e2 Binary files /dev/null and b/images/presentation/android.png differ diff --git a/images/presentation/bg.svg b/images/presentation/bg.svg new file mode 100644 index 0000000..d1b622a --- /dev/null +++ b/images/presentation/bg.svg @@ -0,0 +1,26 @@ + +image/svg+xml diff --git a/images/presentation/bg_wave.svg b/images/presentation/bg_wave.svg new file mode 100644 index 0000000..49ecda2 --- /dev/null +++ b/images/presentation/bg_wave.svg @@ -0,0 +1,23 @@ + +image/svg+xml \ No newline at end of file diff --git a/images/presentation/components/core.svg b/images/presentation/components/core.svg new file mode 100644 index 0000000..b1fe024 --- /dev/null +++ b/images/presentation/components/core.svg @@ -0,0 +1,4 @@ + + + +
Management Core
State Model
State Persistence
User Interaction
Redirection
\ No newline at end of file diff --git a/images/presentation/components/model.svg b/images/presentation/components/model.svg new file mode 100644 index 0000000..118a7d9 --- /dev/null +++ b/images/presentation/components/model.svg @@ -0,0 +1,4 @@ + + + +
Management Core
State Model
State Persistence
User Interaction
Redirection
\ No newline at end of file diff --git a/images/presentation/components/persistence.svg b/images/presentation/components/persistence.svg new file mode 100644 index 0000000..778c961 --- /dev/null +++ b/images/presentation/components/persistence.svg @@ -0,0 +1,4 @@ + + + +
Management Core
State Model
State Persistence
User Interaction
Redirection
\ No newline at end of file diff --git a/images/presentation/components/redirection.svg b/images/presentation/components/redirection.svg new file mode 100644 index 0000000..a47795a --- /dev/null +++ b/images/presentation/components/redirection.svg @@ -0,0 +1,4 @@ + + + +
Management Core
State Model
State Persistence
User Interaction
Redirection
\ No newline at end of file diff --git a/images/presentation/components/ui.svg b/images/presentation/components/ui.svg new file mode 100644 index 0000000..cf137a6 --- /dev/null +++ b/images/presentation/components/ui.svg @@ -0,0 +1,4 @@ + + + +
Management Core
State Model
State Persistence
User Interaction
Redirection
\ No newline at end of file diff --git a/images/presentation/components/virtual-components-bw.svg b/images/presentation/components/virtual-components-bw.svg new file mode 100644 index 0000000..41c0043 --- /dev/null +++ b/images/presentation/components/virtual-components-bw.svg @@ -0,0 +1,4 @@ + + + +
Management Core
State Model
State Persistence
User Interaction
Redirection
\ No newline at end of file diff --git a/images/presentation/computer-science.png b/images/presentation/computer-science.png new file mode 100644 index 0000000..c67de06 Binary files /dev/null and b/images/presentation/computer-science.png differ diff --git a/images/presentation/contacts.svg b/images/presentation/contacts.svg new file mode 100644 index 0000000..c3fa626 --- /dev/null +++ b/images/presentation/contacts.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/images/presentation/dm-logo.png b/images/presentation/dm-logo.png new file mode 100644 index 0000000..be5807e Binary files /dev/null and b/images/presentation/dm-logo.png differ diff --git a/images/presentation/logo_text.svg b/images/presentation/logo_text.svg new file mode 100644 index 0000000..61ade6e --- /dev/null +++ b/images/presentation/logo_text.svg @@ -0,0 +1,1100 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/images/presentation/messages.png b/images/presentation/messages.png new file mode 100644 index 0000000..402d6bc Binary files /dev/null and b/images/presentation/messages.png differ diff --git a/images/presentation/noteit.png b/images/presentation/noteit.png new file mode 100644 index 0000000..06ab48b Binary files /dev/null and b/images/presentation/noteit.png differ diff --git a/images/presentation/virtualapp.png b/images/presentation/virtualapp.png new file mode 100644 index 0000000..3588a7e Binary files /dev/null and b/images/presentation/virtualapp.png differ diff --git a/images/presentation/virtualxposed.png b/images/presentation/virtualxposed.png new file mode 100644 index 0000000..e80de48 Binary files /dev/null and b/images/presentation/virtualxposed.png differ diff --git a/images/system-classes-bw.svg b/images/system-classes-bw.svg new file mode 100644 index 0000000..eef1759 --- /dev/null +++ b/images/system-classes-bw.svg @@ -0,0 +1,4 @@ + + + +

PermissionController

- mState
+ onPermissionUpdated()

PermissionManagerServiceImpl


- mRegistry


+ restorePermissionState()

AIDL


<<Interface>>
PermissionManager

- mPermissionManagerServiceImpl


PermissionManagerService

DevicePermissionState


UserPermissionState

UidPermissionState


+ getGrantedPermissions():

     List<PermissionState>

+ revokePermission()

PermissionState


- mGranted: boolean

- mFlags: int


+ grant()

+ revoke()

+ updateFlags()%3CmxGraphModel%3E%3Croot%3E%3CmxCell%20id%3D%220%22%2F%3E%3CmxCell%20id%3D%221%22%20parent%3D%220%22%2F%3E%3CmxCell%20id%3D%222%22%20value%3D%22%26lt%3Bp%20style%3D%26quot%3Bmargin%3A0px%3Bmargin-top%3A4px%3Btext-align%3Acenter%3B%26quot%3B%26gt%3B%26lt%3Bb%26gt%3BPermissionManagerServiceImpl%26lt%3B%2Fb%26gt%3B%26lt%3B%2Fp%26gt%3B%26lt%3Bhr%20size%3D%26quot%3B1%26quot%3B%20style%3D%26quot%3Bborder-style%3Asolid%3B%26quot%3B%26gt%3B%26lt%3Bp%20style%3D%26quot%3Bmargin%3A0px%3Bmargin-left%3A4px%3B%26quot%3B%26gt%3B%26lt%3Bbr%26gt%3B%26lt%3B%2Fp%26gt%3B%26lt%3Bhr%20size%3D%26quot%3B1%26quot%3B%20style%3D%26quot%3Bborder-style%3Asolid%3B%26quot%3B%26gt%3B%26lt%3Bp%20style%3D%26quot%3Bmargin%3A0px%3Bmargin-left%3A4px%3B%26quot%3B%26gt%3B%2B%20restorePermissionState()%26lt%3B%2Fp%26gt%3B%22%20style%3D%22verticalAlign%3Dtop%3Balign%3Dleft%3Boverflow%3Dfill%3Bhtml%3D1%3BwhiteSpace%3Dwrap%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%3CmxGeometry%20x%3D%22460%22%20y%3D%22305%22%20width%3D%22200%22%20height%3D%2290%22%20as%3D%22geometry%22%2F%3E%3C%2FmxCell%3E%3C%2Froot%3E%3C%2FmxGraphModel%

1..n
1..n
1..n

RuntimePermissionsPersistenceImpl


+ readForUser(user): RuntimePermissionsState

+ writeForUser(runtimePermissions, user)

- parseXml()

- serializeRuntimePermissions()


%3CmxGraphModel%3E%3Croot%3E%3CmxCell%20id%3D%220%22%2F%3E%3CmxCell%20id%3D%221%22%20parent%3D%220%22%2F%3E%3CmxCell%20id%3D%222%22%20value%3D%22%26lt%3Bp%20style%3D%26quot%3Bmargin%3A0px%3Bmargin-top%3A4px%3Btext-align%3Acenter%3B%26quot%3B%26gt%3B%26lt%3Bb%26gt%3BPermissionManagerServiceImpl%26lt%3B%2Fb%26gt%3B%26lt%3B%2Fp%26gt%3B%26lt%3Bhr%20size%3D%26quot%3B1%26quot%3B%20style%3D%26quot%3Bborder-style%3Asolid%3B%26quot%3B%26gt%3B%26lt%3Bp%20style%3D%26quot%3Bmargin%3A0px%3Bmargin-left%3A4px%3B%26quot%3B%26gt%3B%26lt%3Bbr%26gt%3B%26lt%3B%2Fp%26gt%3B%26lt%3Bhr%20size%3D%26quot%3B1%26quot%3B%20style%3D%26quot%3Bborder-style%3Asolid%3B%26quot%3B%26gt%3B%26lt%3Bp%20style%3D%26quot%3Bmargin%3A0px%3Bmargin-left%3A4px%3B%26quot%3B%26gt%3B%2B%20restorePermissionState()%26lt%3B%2Fp%26gt%3B%22%20style%3D%22verticalAlign%3Dtop%3Balign%3Dleft%3Boverflow%3Dfill%3Bhtml%3D1%3BwhiteSpace%3Dwrap%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%3CmxGeometry%20x%3D%22460%22%20y%3D%22305%22%20width%3D%22200%22%20height%3D%2290%22%20as%3D%22geometry%22%2F%3E%3C%2FmxCell%3E%3C%2Froot%3E%3C%2FmxGraphModel%

Settings


- mGranted: boolean

- mFlags: int


+ readLPw()

+ writePermissionStateForUserLPr()

%3CmxGraphModel%3E%3Croot%3E%3CmxCell%20id%3D%220%22%2F%3E%3CmxCell%20id%3D%221%22%20parent%3D%220%22%2F%3E%3CmxCell%20id%3D%222%22%20value%3D%22%26lt%3Bp%20style%3D%26quot%3Bmargin%3A0px%3Bmargin-top%3A4px%3Btext-align%3Acenter%3B%26quot%3B%26gt%3B%26lt%3Bb%26gt%3BPermissionManagerServiceImpl%26lt%3B%2Fb%26gt%3B%26lt%3B%2Fp%26gt%3B%26lt%3Bhr%20size%3D%26quot%3B1%26quot%3B%20style%3D%26quot%3Bborder-style%3Asolid%3B%26quot%3B%26gt%3B%26lt%3Bp%20style%3D%26quot%3Bmargin%3A0px%3Bmargin-left%3A4px%3B%26quot%3B%26gt%3B%26lt%3Bbr%26gt%3B%26lt%3B%2Fp%26gt%3B%26lt%3Bhr%20size%3D%26quot%3B1%26quot%3B%20style%3D%26quot%3Bborder-style%3Asolid%3B%26quot%3B%26gt%3B%26lt%3Bp%20style%3D%26quot%3Bmargin%3A0px%3Bmargin-left%3A4px%3B%26quot%3B%26gt%3B%2B%20restorePermissionState()%26lt%3B%2Fp%26gt%3B%22%20style%3D%22verticalAlign%3Dtop%3Balign%3Dleft%3Boverflow%3Dfill%3Bhtml%3D1%3BwhiteSpace%3Dwrap%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%3CmxGeometry%20x%3D%22460%22%20y%3D%22305%22%20width%3D%22200%22%20height%3D%2290%22%20as%3D%22geometry%22%2F%3E%3C%2FmxCell%3E%3C%2Froot%3E%3C%2FmxGraphModel%


<<Interface>>
RuntimePermissionsPersistence

RuntimePermissionPersistence


+ readStateForUserSync()

+ writeStateForUserAsync()


%3CmxGraphModel%3E%3Croot%3E%3CmxCell%20id%3D%220%22%2F%3E%3CmxCell%20id%3D%221%22%20parent%3D%220%22%2F%3E%3CmxCell%20id%3D%222%22%20value%3D%22%26lt%3Bp%20style%3D%26quot%3Bmargin%3A0px%3Bmargin-top%3A4px%3Btext-align%3Acenter%3B%26quot%3B%26gt%3B%26lt%3Bb%26gt%3BPermissionManagerServiceImpl%26lt%3B%2Fb%26gt%3B%26lt%3B%2Fp%26gt%3B%26lt%3Bhr%20size%3D%26quot%3B1%26quot%3B%20style%3D%26quot%3Bborder-style%3Asolid%3B%26quot%3B%26gt%3B%26lt%3Bp%20style%3D%26quot%3Bmargin%3A0px%3Bmargin-left%3A4px%3B%26quot%3B%26gt%3B%26lt%3Bbr%26gt%3B%26lt%3B%2Fp%26gt%3B%26lt%3Bhr%20size%3D%26quot%3B1%26quot%3B%20style%3D%26quot%3Bborder-style%3Asolid%3B%26quot%3B%26gt%3B%26lt%3Bp%20style%3D%26quot%3Bmargin%3A0px%3Bmargin-left%3A4px%3B%26quot%3B%26gt%3B%2B%20restorePermissionState()%26lt%3B%2Fp%26gt%3B%22%20style%3D%22verticalAlign%3Dtop%3Balign%3Dleft%3Boverflow%3Dfill%3Bhtml%3D1%3BwhiteSpace%3Dwrap%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%3CmxGeometry%20x%3D%22460%22%20y%3D%22305%22%20width%3D%22200%22%20height%3D%2290%22%20as%3D%22geometry%22%2F%3E%3C%2FmxCell%3E%3C%2Froot%3E%3C%2FmxGraphModel%

PackageManagerService


+ PackageManagerService()

+ writePermissionsSettings()

%3CmxGraphModel%3E%3Croot%3E%3CmxCell%20id%3D%220%22%2F%3E%3CmxCell%20id%3D%221%22%20parent%3D%220%22%2F%3E%3CmxCell%20id%3D%222%22%20value%3D%22%26lt%3Bp%20style%3D%26quot%3Bmargin%3A0px%3Bmargin-top%3A4px%3Btext-align%3Acenter%3B%26quot%3B%26gt%3B%26lt%3Bb%26gt%3BPermissionManagerServiceImpl%26lt%3B%2Fb%26gt%3B%26lt%3B%2Fp%26gt%3B%26lt%3Bhr%20size%3D%26quot%3B1%26quot%3B%20style%3D%26quot%3Bborder-style%3Asolid%3B%26quot%3B%26gt%3B%26lt%3Bp%20style%3D%26quot%3Bmargin%3A0px%3Bmargin-left%3A4px%3B%26quot%3B%26gt%3B%26lt%3Bbr%26gt%3B%26lt%3B%2Fp%26gt%3B%26lt%3Bhr%20size%3D%26quot%3B1%26quot%3B%20style%3D%26quot%3Bborder-style%3Asolid%3B%26quot%3B%26gt%3B%26lt%3Bp%20style%3D%26quot%3Bmargin%3A0px%3Bmargin-left%3A4px%3B%26quot%3B%26gt%3B%2B%20restorePermissionState()%26lt%3B%2Fp%26gt%3B%22%20style%3D%22verticalAlign%3Dtop%3Balign%3Dleft%3Boverflow%3Dfill%3Bhtml%3D1%3BwhiteSpace%3Dwrap%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%3CmxGeometry%20x%3D%22460%22%20y%3D%22305%22%20width%3D%22200%22%20height%3D%2290%22%20as%3D%22geometry%22%2F%3E%3C%2FmxCell%3E%3C%2Froot%3E%3C%2FmxGraphModel%

GrantPermissionsActivity


- showNextRequest()

\ No newline at end of file diff --git a/presentation-theme.typ b/presentation-theme.typ new file mode 100644 index 0000000..b4f190d --- /dev/null +++ b/presentation-theme.typ @@ -0,0 +1,286 @@ +#import "@preview/touying:0.5.2": * + +#let _header-logo = (colors, ..args) => { + let original = read("images/presentation/logo_text.svg") + let colored = original.replace("#B20E10", colors.neutral-lightest.to-hex()) + image.decode(colored, ..args) +} + +#let _footer-wave = (colors, ..args) => { + let original = read("images/presentation/bg_wave.svg") + let colored = original.replace("#9b0014", colors.primary.to-hex()) + image.decode(colored, ..args) +} + +#let _title-background = (colors, ..args) => { + let original = read("images/presentation/bg.svg") + let colored = original.replace("#9b0014", colors.primary.to-hex()).replace("#484f59", colors.secondary.to-hex()) + image.decode(colored, ..args) +} + +#let _background-logo = (colors, ..args) => { + let original = read("images/presentation/logo_text.svg") + let colored = original.replace("#B20E10", colors.primary.to-hex()) + image.decode(colored, ..args) +} + +#let _header(self, section: utils.display-current-heading(level: 1)) = { + set align(top) + place(rect(width: 100%, height: 100%, stroke: none, fill: self.colors.primary)) + place(horizon + right, dx: -1.5%, _header-logo(self.colors, height: 90%)) + place(horizon + left, dx: 2.5%, text(size: 34pt, fill: self.colors.neutral-lightest, section)) +} + +#let _footer(self) = { + place(bottom, _footer-wave(self.colors, width: 100%)) + place( + bottom + right, dx: -7%, dy: -27%, + text( + size: 18pt, + fill: self.colors.primary + .lighten(100%) + .saturate(30%), + context utils.slide-counter.display() + " of " + utils.last-slide-number + ) + ) +} + +#let outline-slide(title: utils.i18n-outline-title, ..bodies) = touying-slide-wrapper(self => { + let self = utils.merge-dicts( + self, + config-page( + header: _header.with(section: title), + footer: _footer, + ), + ) + let setting = body => { + show: block.with(width: 100%, height: 104%, inset: (left: 11em), breakable: false) + set text(size: 1.3em, fill: self.colors.primary, weight: "medium") + v(2.5fr) + body + v(2fr) + } + touying-slide(self: self, setting: setting, components.custom-progressive-outline( + depth: 1, + alpha: 20%, + vspace: (.4em,), + )) +}) + +#let slide( + title: utils.display-current-heading(level: 2), + section: utils.display-current-heading(level: 1), + config: (:), + repeat: auto, + setting: body => body, + composer: auto, + ..bodies, +) = touying-slide-wrapper(self => { + let self = utils.merge-dicts( + self, + config-page( + header: _header.with(section: section), + footer: _footer, + ), + ) + let new-setting = body => { + show: block.with(width: 100%, height: 104%, inset: (x: 3em), breakable: false) + set text(fill: self.colors.neutral-darkest) + show: setting + v(2.5fr) + if title != none { + show: block.with(inset: (y: -.5em)) + set text(size: 34pt, weight: "bold", fill: self.colors.primary) + title + v(.7em) + } + body + v(2fr) + } + touying-slide(self: self, config: config, repeat: repeat, setting: new-setting, composer: composer, ..bodies) +}) + +#let title-slide( + extra: none, + ..args, +) = touying-slide-wrapper(self => { + let info = self.info + args.named() + let body = { + // Background + place(top, _title-background(self.colors, width: 107%)) + + // Normalize data + if type(info.subtitle) == none { + info.subtitle = "" + } + if type(info.authors) != array { + info.authors = (info.authors,) + } + if type(info.date) == none { + info.date = "" + } + + set text(fill: self.colors.neutral-lightest) + set par(leading: .45em, spacing: .8em) + + // Images + v(10%) + align(center, block(width: 95%, height: 15%, grid( + columns: (1fr, 1fr), + image("images/presentation/computer-science.png"), + align(horizon, image(height: 65%, "images/presentation/dm-logo.png")), + ))) + v(5%) + // Title + align( + center, + box(inset: (x: 4em), text(size: 40pt, info.title)) + ) + v(1%) + // Subtitle + align( + center, + box(inset: (x: 2em), text(size: 24pt, info.subtitle)) + ) + // Authors + place(bottom, dx: 7.5%, dy: -20%, text(size: 20pt, { + info.authors.fold([], (acc, author) => acc + [#author \ ]) + parbreak() + info.date + })) + // Logo + place( + bottom + right, dx: -5%, dy: -3%, + _background-logo(self.colors, height: 17%) + ) + } + self = utils.merge-dicts( + self, + config-common(freeze-slide-counter: true), + config-page(fill: self.colors.neutral-lightest, margin: 0em), + ) + touying-slide(self: self, body) +}) + +#let filled-slide( + config: (:), + repeat: auto, + setting: body => body, + composer: auto, + ..bodies, +) = touying-slide-wrapper(self => { + let self = utils.merge-dicts(self, config-page(margin: 0em)) + let new-setting = body => { + set text(size: 44pt, fill: self.colors.neutral-lightest) + show: box.with(width: 100%, height: 100%, fill: self.colors.primary) + show: align.with(center + horizon) + show: setting + body + } + touying-slide(self: self, config: config, repeat: repeat, setting: new-setting, composer: composer, ..bodies) +}) + +#let new-section(title) = heading(level: 1, depth: 2, title) + +#let new-section-slide( + config: (:), + repeat: auto, + setting: body => body, + composer: auto, + title, +) = touying-slide-wrapper(self => { + let self = utils.merge-dicts( + self, + config-page( + header: _header, + footer: _footer, + ), + ) + let new-setting = body => { + show: align.with(center + horizon) + set text(size: 46pt, fill: self.colors.primary.lighten(15%), weight: "bold") + show: setting + body + } + touying-slide(self: self, config: config, repeat: repeat, setting: new-setting, composer: composer, + underline(stroke: 5pt, offset: .4em, utils.display-current-heading(level: 1)) + ) +}) + +#let unipd-theme( + ..args, + body, +) = { + show: touying-slides.with( + config-page( + paper: "presentation-4-3", + header-ascent: 0em, + footer-descent: 0em, + margin: (x: 0em, top: 12%, bottom: 12%), + ), + config-common( + slide-fn: slide, + new-section-slide-fn: outline-slide.with(title: utils.display-current-heading(level: 1)), + ), + config-methods( + init: (self: none, body) => { + set text(font: "Helvetica", size: 22pt, fill: self.colors.neutral-darkest) + show heading.where(level: 2): set text(fill: self.colors.primary) + show heading.where(level: 2): it => it + v(1em) + set list(indent: 1em, marker: text(font: "Arial", "•", fill: self.colors.primary.darken(5%))) + set enum(indent: 1em, numbering: n => text([#n.], fill: self.colors.primary.darken(5%))) + show "->": sym.arrow + show "=>": $=>$ + show raw: set text(1.1em, font: "Menlo") + body + }, + cover: (self: none, body) => box(hide(body)), + ), + config-colors( + primary: rgb(155, 0, 20), + secondary: rgb(72, 79, 89), + tertiary: rgb(0, 128, 0), + neutral-lightest: rgb("#ffffff"), + neutral-darkest: rgb("#000000"), + cover: self => self.colors.neutral-dark.lighten(80%) + ), + ..args + ) + + body +} + +#let grey(n, content) = { + let color = gray.lighten(50%) + only("-" + str(n - 1), { + set text(color) + set list(indent: 1em, marker: text(font: "Arial", "•", fill: color)) + set enum(indent: 1em, numbering: n => text([#n.], fill: color)) + content + }) + only(str(n) + "-", content) +} + +#let (alert-block, normal-block, example-block) = { + let make_block_fn(mk-header-color) = (title, body) => touying-fn-wrapper((self: none) => { + show: it => align(center, it) + show: it => box(width: 85%, it) + let slot = box.with(width: 100%, outset: 0em, stroke: self.colors.neutral-darkest) + stack( + slot( + inset: 0.5em, fill: mk-header-color(self), + align(left, heading(level: 3, text(fill: self.colors.neutral-lightest, weight: "regular")[#title])) + ), + slot( + inset: (x: 0.6em, y: 0.75em), + fill: self.colors.neutral-lighter.lighten(50%), align(left, body) + ) + ) + }) + + ( + make_block_fn(self => self.colors.primary), + make_block_fn(self => self.colors.secondary), + make_block_fn(self => self.colors.tertiary), + ) +} diff --git a/presentation.pdf b/presentation.pdf new file mode 100644 index 0000000..40acc9c Binary files /dev/null and b/presentation.pdf differ diff --git a/presentation.typ b/presentation.typ new file mode 100644 index 0000000..fd09db8 --- /dev/null +++ b/presentation.typ @@ -0,0 +1,442 @@ +#import "@preview/xarrow:0.3.1": xarrow +#import "presentation-theme.typ": ( + unipd-theme, + title-slide, + slide, + filled-slide, + pause, + meanwhile, + uncover, + only, + grey, + outline-slide, +) + +#show: unipd-theme + +#title-slide( + title: [Towards Secure Virtual Apps: Bringing Android Permission Model to Application Virtualization], + subtitle: [Master's degree in Computer Science], + authors: ( + [_Candidate:_ Alberto Lazari], + [_Supervisor:_ Prof. Eleonora Losiouk] + ), + date: [December 12, 2024], +) + +#slide(section: [Summary])[ + - App-level virtualization: run applications inside a container app + + #grey(2)[ + - Permissions for virtual apps shared with container + ] + + #meanwhile + #grey(3)[ + - Android's sandbox model violated: unintended access to restricted resources + ] + + #meanwhile + #grey(4)[ + - Analyze Android's permission model -> emulate it in virtual environment + ] + +] + +#outline-slide() + += Background +== Android App-Level Virtualization +Apps can load code dynamically to extend its functionalities. + +#pause +Imagine if an app loaded another app's code... + +#meanwhile +#v(30%) +#pause + +#pause +#align(center + horizon, +grid(columns: (33%, 10%, 33%), + { + place(center + horizon, dy: -65%, block(stroke: 1pt, inset: .5em, + image(width: 40%, "/images/presentation/android-blue.png") + block(stroke: 1pt, inset: .5em, image(width: 30%, "/images/presentation/messages.png")) + )) + }, + xarrow(width: 7em, sym: sym.arrow.l)[Install], + block(stroke: 1pt, inset: .5em, image(width: 30%, "/images/presentation/messages.png")), +)) + +== Use Cases +- Virtual apps isolation from system + +- App clones (multiple instances) + +- Isolated environments for testing and security + +- Finer control over app's environment + +== Dynamic Proxies +- Redirect virtual apps requests to the system + +- Necessary because apps live inside the container + +- Android knows nothing about them + +#pause +- Let's see an example + +--- + +// Place holder +#block(height: 45%, []) + +#only(1, +place(bottom + center, +align(center + horizon, +grid(columns: (auto, 34%, auto), rows: (20%, 43%), + grid.cell(rowspan: 2, + block(height: 100%, stroke: 1pt, + grid(rows: (auto, 35%, auto), inset: (x: 1em, y: .7em), + image(width: 60%, "/images/presentation/android-blue.png"), + rotate(-90deg, xarrow[`readContacts()`]), + block(stroke: 1pt, inset: 10%, image(width: 50%, "/images/presentation/messages.png")), + ))), + xarrow[(container) `readContacts()`], + grid.cell(rowspan: 2, align(top, image(height: 80%, "/images/presentation/android.png"))), +)))) + +#only(2, +place(bottom + center, +align(center + horizon, +grid(columns: (auto, 34%, auto), rows: (20%, 43%), + grid.cell(rowspan: 2, + block(height: 100%, stroke: 1pt, + grid(rows: (auto, 35%, auto), inset: (x: 1em, y: .7em), + image(width: 60%, "/images/presentation/android-blue.png"), + hide(rotate(-90deg, xarrow[`readContacts()`])) + + place(center + horizon, + rotate(-90deg, + xarrow(sym: sym.arrow.l, text(1.1em)[Contacts]))), + block(stroke: 1pt, inset: 10%, image(width: 50%, "/images/presentation/messages.png")), + ))), + xarrow(width: 9em, sym: sym.arrow.l)[(container) Contacts], + grid.cell(rowspan: 2, align(top, image(height: 80%, "/images/presentation/android.png"))), +)))) + + += Motivation +== Permissions in Virtual Frameworks +- The system enforces permissions normally on the container + +#grey(2)[ +- Android knows nothing about virtual apps +] +#grey(3)[ +#v(-.5em) #h(1.85em) +=> container has full responsibility over virtual apps +] +#grey(4)[ +#v(-.5em) #h(1.85em) +=> permissions are not enforced on virtual apps +] + +#pause +#pause +#pause +#pause +- Works fine for a single app + +--- + +// Place holder +#block(height: 45%, []) + +#only(1, +place(bottom + center, +align(center + horizon, +grid(columns: (auto, 34%, auto), rows: (20%, 43%), + grid.cell(rowspan: 2, + block(height: 100%, stroke: 1pt, + grid(rows: (auto, 35%, auto), inset: (x: 1em, y: .7em), + image(width: 60%, "/images/presentation/android-blue.png"), + rotate(-90deg, xarrow[`readContacts()`]), + block(stroke: 1pt, inset: 10%, image(width: 50%, "/images/presentation/messages.png")), + ))), + xarrow[(container) `readContacts()`], + grid.cell(rowspan: 2, align(top, image(height: 80%, "/images/presentation/android.png"))), +)))) + +#only(2, +place(bottom + center, +align(center + horizon, +grid(columns: (auto, 34%, auto), rows: (20%, 43%), + grid.cell(rowspan: 2, + block(height: 100%, stroke: 1pt, + grid(rows: (auto, 35%, auto), inset: (x: 1em, y: .7em), + image(width: 60%, "/images/presentation/android-blue.png"), + hide(rotate(-90deg, xarrow[`readContacts()`])), + block(stroke: 1pt, inset: 10%, image(width: 50%, "/images/presentation/messages.png")), + ))), + hide(xarrow[(container) `readContacts()`]) + + place(center + horizon, dx: 15%)[ + #set text(size: .8em) + Ok, container has Contacts permission + ], + grid.cell(rowspan: 2, align(top, image(height: 80%, "/images/presentation/android.png"))), +)))) + +#only(3, +place(bottom + center, +align(center + horizon, +grid(columns: (auto, 34%, auto), rows: (20%, 43%), + grid.cell(rowspan: 2, + block(height: 100%, stroke: 1pt, + grid(rows: (auto, 35%, auto), inset: (x: 1em, y: .7em), + image(width: 60%, "/images/presentation/android-blue.png"), + hide(rotate(-90deg, xarrow[`readContacts()`])) + + place(center + horizon, + rotate(-90deg, + xarrow(sym: sym.arrow.l, text(1.1em)[Contacts]))), + block(stroke: 1pt, inset: 10%, image(width: 50%, "/images/presentation/messages.png")), + ))), + xarrow(width: 9em, sym: sym.arrow.l)[(container) Contacts], + grid.cell(rowspan: 2, align(top, image(height: 80%, "/images/presentation/android.png"))), +)))) + +== What About Multiple Apps? +- Add notes app, declaring no permissions + +#pause +- Messages app requests contacts + +#pause +- Notes app is granted the permission too + +#meanwhile +#align(center + horizon, grid(columns: (23%, auto, 15%), rows: (20%, 15%), inset: .5em, + grid.cell(rowspan: 2, block(height: 100%, stroke: 1pt, inset: 5%, + image(width: 50%, "/images/presentation/android-blue.png") + + v(weak: true, 10%) + + grid(columns: (1fr, 1fr), + block(stroke: 1pt, inset: 5%, image(width: 70%, "/images/presentation/noteit.png")), + block(stroke: 1pt, inset: 5%, image(width: 70%, "/images/presentation/messages.png")), + ) + )), + pause + xarrow(width: 10em, []), + image.decode(width: 50%, read("/images/presentation/contacts.svg").replace("#e8eaed", "#495d92")), +)) + +--- + +- Containers usually have many permissions \ + => extensive attack surface for malicious apps + +#grey(2)[ +- Need to isolate virtual apps -> *virtual permission model* +] +#grey(3)[ +- Consistency with Android's model -> *analyze it* +] + + += Android Permission Model +== Permissions Overview +Three _protection levels_, based on information sensitivity: + +#grey(2)[ +- Normal: minimal effects on system +] + +#grey(3)[ +- Dangerous: access user's private informations +] +#grey(4)[ +- Signature: features available to same developer +] + +#v(5%) + +#pause +#pause +#pause +#pause +Two categories, based on protection level: + +- Install-time: normal + signature + +- Runtime: dangerous + +== Permission Groups +Runtime permissions require direct user approval \ +#pause +=> too many requests. + +#pause +#grid(columns: (2fr, 1fr))[ + One dialog to rule them all: + + - Similar permissions are requested once + + - Reduce user interaction + + - Hide complexity guiding choices +][ + #place(right + horizon, dy: -20%, image(width: 65%, "/images/cool-location-request.png")) +] + +== How Does It Translate to Code? +#block(height: 65%, []) +#place(center + horizon, dy: 11%, { + set image(height: 78%) + only("-1", image("/images/system-classes-bw.svg")) + only("2-", image("/images/system-classes.svg")) +}) + +== High-Level Components +#v(7%) +#figure(image(height: 45%, "/images/system-components.svg")) + +#{ + set text(.9em) + only("2-", place(left + horizon, [UI])) + only("3-", place(horizon + center, dy: -18%, dx: 9%, [Operations])) + only("4-", place(bottom + center, dy: -22%, dx: 45%, [Representation])) + only("5-", place(bottom + center, dy: -10%, dx: -4%, [Storage])) +} + + += Virtual Permission Model +== High-Level Components +#block(height: 75%, []) +#place(center + horizon, dy: 7%, { + only(1, figure(image(height: 45%, "/images/system-components.svg"))) + only(2, figure(image(height: 80%, "/images/virtual-components.svg"))) +}) + +== Final Architecture +#block(height: 75%, []) +#place(center + horizon, dy: 7%, { + figure(image(height: 80%, "/images/virtual-classes.svg")) +}) + +== Components Flow +#block(height: 75%, []) +#place(left + horizon, dy: -23%, xarrow[`requestPermissions()`]) +#place(center + horizon, dy: 7%, dx: 5%, { + only(1, figure(image(height: 80%, "/images/presentation/components/virtual-components-bw.svg"))) + only(2, figure(image(height: 80%, "/images/presentation/components/redirection.svg"))) + only(3, figure(image(height: 80%, "/images/presentation/components/ui.svg"))) + only(4, figure(image(height: 80%, "/images/presentation/components/core.svg"))) + only(5, figure(image(height: 80%, "/images/presentation/components/model.svg"))) + only(6, figure(image(height: 80%, "/images/presentation/components/persistence.svg"))) +}) + +== Implementation +#align(center + horizon, grid(columns: (1fr, 1fr), + image(width: 20%, "/images/presentation/virtualxposed.png"), + v(2%) + image(width: 100%, "/images/presentation/virtualapp.png"), +)) + +- VirtualXposed container app + +- VirtualApp underlying virtualization framework +#grey(2)[ +- Android 14 and technological update +] +#grey(3)[ +- Actual components implementation +] + + += Evaluation +== Permission Type Focus +- General model, different behaviors + +- Protection levels: + - Normal: less testing involved + - Signature: not even available to container + - Dangerous: most complicated, many edge cases + +== TestApp +App designed to test key aspects of the model. + +#align(center + horizon, grid(columns: (4fr, 3fr))[ + `PremissionRequestActivity` + #grid(columns: (1fr, 1fr), + image(height: 50%, "/images/testapp/permission-check.png"), + image(height: 50%, "/images/testapp/permission-request.png"), + ) +][ + #pause + `ContactsActivity` + #image(height: 50%, "/images/testapp/mario.png") +]) + +== Telegram +#block(height: 20%)[] + +#place(horizon, dy: 10%, +align(horizon, +grid(columns: (5fr, 2fr, 2fr), [ + - Test real-world scenario + + - Checks and requests work fine + + - Camera patch works + ], + figure(image(height: 50%, "/images/testapp/telegram-denied.png")), + figure(image(height: 50%, "/images/testapp/camera-denied.png")), +))) + +== Overall Result +- Proof of concept of general model + +- Effective for basic use cases + +#pause +- Limitations for actual applications + + += Future Directions +== Limitations +- Framework hands off operations to system + +- System services perform actual permission checks internally + +- Model cannot redirect system's calls + +== Solutions +- Manual hooks on all possible methods \ + (performed for contacts and camera) + +#grey(2)[ +- Automated permission analysis: + block every call lacking permissions. \ + -> Problem: lack of exhaustive mapping +] +#grey(3)[ +- Re-implement Android's services: + include Android's source in virtual framework. \ + -> Problem: probably still requires adaptation effort +] + + +#filled-slide[ + Question Time? +] + +#filled-slide[ + #let logo = read("images/presentation/logo_text.svg").replace("#B20E10", "#FFFFFF") + #image.decode(width: 40%, logo) + + Thank you for your attention! + + #v(10%) + #align(center, block(width: 85%, height: 13%, grid( + columns: (1fr, 1fr), + image("images/presentation/computer-science.png"), + align(horizon, image(height: 65%, "images/presentation/dm-logo.png")), + ))) +] diff --git a/readme.md b/readme.md index 57da953..a5897e2 100644 --- a/readme.md +++ b/readme.md @@ -1 +1,27 @@ # Master's Thesis + +Sources of my thesis +"Towards Secure Virtual Apps: Bringing Android Permission Model to Application Virtualization" +for my master's degree in Computer Science at the University of Padua. + +## Thesis PDF + +Here's the final [PDF](towards-secure-virtual-apps.pdf), +obtained with + +```sh +typst compile towards-secure-virtual-apps.typ --pdf-standard=a-2b +``` + +A printed version of the thesis, +with chapter openings on the right and optimized page margins, +can be compiled with + +```sh +typst compile towards-secure-virtual-apps.typ --input printed=true +``` + + +## Presentation + +The presentation for the final thesis discussion is also included [here](presentation.pdf). diff --git a/template.typ b/template.typ index dbfe2c4..64b0677 100644 --- a/template.typ +++ b/template.typ @@ -157,7 +157,7 @@ set page( header: header(chapter: chapter(number: false), subsection: none), ) - bibliography("sources.bib", style: "bib-style.csl") + bibliography("sources.bib", style: "ieee-bib-style.csl") body } diff --git a/thesis.pdf b/towards-secure-virtual-apps.pdf similarity index 99% rename from thesis.pdf rename to towards-secure-virtual-apps.pdf index 5279c84..ee029cc 100644 Binary files a/thesis.pdf and b/towards-secure-virtual-apps.pdf differ diff --git a/thesis.typ b/towards-secure-virtual-apps.typ similarity index 100% rename from thesis.typ rename to towards-secure-virtual-apps.typ