Commit Graph

14284 Commits

Author SHA1 Message Date
Wale Ogunwale
7aa64840b8 Merge "Moved appNotResponding handling into ProcessRecord (23/n)" 2018-10-17 23:35:32 +00:00
TreeHugger Robot
1abd4feabb Merge "Removed AMS.mStackSuperivor (22/n)" 2018-10-17 20:08:41 +00:00
Eran Messeri
5cb1e8e636 Merge "Enterprise Policy for Private DNS Setting" 2018-10-17 16:59:57 +00:00
Wale Ogunwale
51cc98adbe Moved appNotResponding handling into ProcessRecord (23/n)
Allows for better seperation of AMS and ATMS, also the method mostly
accessed internal variables in ProcessRecord so it make sense for it
to be in that class.
Also, move inputDispatchingTimedOut back to AM side because it involves
lots of process stuff.

Test: Existing test pass
Bug: 80414790
Change-Id: I45b98dc550ff121e9df4bf004b2667af2426b79d
2018-10-17 09:47:09 -07:00
Wale Ogunwale
31913b50d1 Removed AMS.mStackSuperivor (22/n)
The stack supervisor object should only be accessed through ATMS.

Test: Existing test pass
Bug: 80414790
Change-Id: I0648a95161a6a5c4ad714264d217c7f5e55852d7
2018-10-17 09:47:08 -07:00
Rafal Slawik
0862158f13 Snapshot memory state for some native processes
Which processes to snapshot is controlled by a whitelist.

Benchmark for taking the snapshot:
https://docs.google.com/spreadsheets/d/1vG9ku8Uu8104CmKbO4cNeEKVeeByvHY--p0_dK1GAdA/edit?usp=sharing
(The difference between the first two sheets.)
~20ms constant cost plus ~4ms per process.

Bug: 115968899
Test: manually verified that statsd is included in the report
Change-Id: Iba680531c563ba28fae849e44044313866b2103f
2018-10-17 10:34:27 +01:00
Wale Ogunwale
80d3529acd Merge changes I0d33b4d3,I7034fcb2
* changes:
  Moved some log config. to ActivityTaskManagerDebugConfig (21/n)
  Moved more stuff from AMS to ATMS (20/n)
2018-10-16 12:39:09 +00:00
TreeHugger Robot
1728c04cae Merge "Instantiate InputMethodManager for each display (2nd try)" 2018-10-16 08:02:49 +00:00
TreeHugger Robot
77f7614558 Merge "Add phsyical activity recognition AppOp" 2018-10-16 07:50:27 +00:00
Wale Ogunwale
98875615dc Moved some log config. to ActivityTaskManagerDebugConfig (21/n)
Test: Existing test pass
Bug: 80414790
Change-Id: I0d33b4d325be805ac49a97ea02ad1a10fd1bf24f
2018-10-15 18:27:14 -07:00
TreeHugger Robot
02f2a315d7 Merge "Add Context.getDisplayId() to avoid possible IPC" 2018-10-16 00:20:52 +00:00
TreeHugger Robot
bc9ebba7e5 Merge "Suspending app can customize intercepting dialog" 2018-10-15 21:51:52 +00:00
Zimuzo
6cbf9cc6e1 Add phsyical activity recognition AppOp
Add AppOps for physical activity recognition to better track apps detecting physical activity.

Test: AppOpsmanager#noteOp is ALLOWED
Bug: 111411340
Change-Id: I2ee336ead4da11f0a12733b14a63840437c7a2e1
2018-10-15 21:52:16 +01:00
TreeHugger Robot
8aaf27259c Merge "Fixes touch ripples on media buttons." 2018-10-15 17:21:17 +00:00
Gus Prevas
9cc966012f Fixes touch ripples on media buttons.
This change makes touch ripples appear correctly on the action buttons
on media notifications.  This involves the following changes:

- NotificationViewWrapper.onReinflated() sets the notification content
root's background to transparent rather than null when transferring the
background color to the NotificationBackgroundView.  This gives the
ripples a surface to draw on.
- The RemoteViews for the media templates are changed to use a fixed
set of buttons instead of removing and re-adding them on every update.
This prevents the update caused by whatever action the tap invokes from
interrupting the ripples.
- A method is added to RemoteViews allowing the ripple color to be
specified.  This allows us to change the ripple color to match the
foreground color of the controls, which is necessary for the ripples to
show up against a dark background.

Test: manual
Change-Id: I907f9a1a75efb48da496133ad357fc5150de4410
Fixes: 35856702
2018-10-15 09:42:06 -04:00
Stefano Tommasini
6f6e67bcce Merge "Add onCreate method to SystemBackup agent that receives UserHandle." 2018-10-15 12:45:38 +00:00
Eran Messeri
a2e0ca77a8 Enterprise Policy for Private DNS Setting
A new API for setting the Private DNS settings value programatically via
the DevicePolicyManager.

Since there are two separate settings for Private DNS, and the value
provided for the hostname needs to be validated, a new
DevicePolicyManager API is introduced.

Only a Device Policy Client in Device Owner mode may change these
settings.
The DPC may additionally set a user restriction (added in a separate CL)
to prevent the user from changing Private DNS settings.

Bug: 112982691
Test: atest com.android.cts.devicepolicy.DeviceOwnerTest#testPrivateDnsPolicy
Change-Id: I566437e4fe10e1346858149120c50b3c20ca073f
2018-10-15 11:53:22 +01:00
Stefanot
14bbdedec0 Add onCreate method to SystemBackup agent that receives UserHandle.
This is done for go/br-framework-multi-user.

Bug:117590564
Test: Builds.
Change-Id: I7af0f7c604979da03efc3d88dbed2b2c9631bace
2018-10-15 10:27:11 +01:00
Yohei Yukawa
4052a10f29 Instantiate InputMethodManager for each display (2nd try)
InputMethodManager has been a per-process singleton object. In order
to support behavior changes for multi-display support in Android Q,
however, InputMethodManager now needs to be per-display objects.

With this CL, context.getSystemService(InputMethodManager.class) will
start returning per-display InputMethodManager (IMM) instance.

  Why?

There are two major reasons.
 1. To support per-display focused window.
 2. To support more simplified API for multi-session IME.

Currently per-process InputMethodManager instance directly receives
callback from ViewRootImpl upon windowFocusChanged, then it keeps
track of which Window is focused by storing its root view into
InputMethodManager#mCurRootView.

This design assumes that (within the same process) at most one Window
can have window focus, which is no longer true once we start
supporting per-display focused window (Bug 111361570).

  Why we need to do this to support per-display focused window:

For traditional non multi-session IME cases (e.g. apps that use
Virtual Display APIs on phones), internal state of IMM can be easily
messed up once the system starts sending per-display
windowFocusChanged events to the same process, because IMM still
doesn't know that now each display has focused window. It is hard to
precisely predict what kind of issues we would see simply because such
a use case is most likely not expected in the original design.

  Why we need to do this for multi-session IME:

For multi-session IME scenarios, in addition to the above concern in
InputMethodManager, the current design allows at most one IME session
per process. This means that if a process X is showing Activities to 3
different displays, only one Activity can interact with the
multi-session IME at the same time. If we do not change the current
design, the only way to work around is to ask app developers to
explicitly use different processes for each Activity, which may
require a lot of work (e.g. SharedPreference is not optimized for
multi-process use cases). This would also make multi-session IME
development complicated because the IME cannot know on which display
the IME is interacting until startInputOrWindowGainedFocus() is
actually called, and needs to do all the preparation and cleanup tasks
whenever startInputOrWindowGainedFocus() is called for a different
display than it's currently interacting with.

  Alternative solutions considered:

Another possible approach is to update InputMethodManager singleton to
be able to maintain multiple mCurRootView and mServedView for each
display. This approach was abandoned because those fields and methods
are already marked as @UnsupportedAppUsage.  I concluded that touching
@UnsupportedAppUsage things would have bigger compatibility risks than
per-display instance model.

  Implementation note:

* Public APIs in IMM that take View instance as the first parameter
  will verify whether the given View and IMM are associated with the
  same display ID or not.  If there is a display ID mismatch, such an
  API call will be automatically forwarded to the correct IMM instance
  IMM with a clear warning in logcat which tells that app developers
  should use the correct IMM instance to avoid unnecessary performance
  overhead.

* As a general rule, system server process cannot trust display ID
  reported from applications.  In order to enable IMMS to verify the
  reported display ID, this CL also exposes display ID verification
  logic from WMS to other system components via WindowManagerInternal.

* isInputMethodClientFocus() in WindowManagerService (WMS) is updated
  to use top-focused-display to determine whether a given IME client
  has IME focus or not.  This is now necessary because with a recent
  change [1] each display can have focused window.  The previous logic
  to check all the displays that belong to the given pid/uid [2] no
  longer makes sense.

* Currently per-display InputMethodManager instances will not be
  garbage collected because InputMethodManager#sInstanceMap keeps
  holding strong references to them.  Freeing those instances is
  technically possible, but we need to be careful because multiple
  processes (app, system, IME) are involved and at least system
  process has a strict verification logic that lets the calling
  process crash with SecurityException.  We need to carefully
  implement such a cleanup logic to avoid random process crash due to
  race condition.  Bug 116699479 will take care of this task.

Also to make sure that the performance regression (Bug 117434607) we
observed after my initial attempt [3] no longer exists, here are the
benchmark results with and without this CL.

  testExpandNotificationsLatency on taimen-userdebug
    without this CL:
      results=[55, 46, 61, 67, 50, 48, 57, 50, 55, 63]
      min:46.0, max:67.0, avg:55.2, median:55.0, std_dev:6.539
    with this CL:
      results=[45, 55, 58, 57, 47, 60, 59, 60, 56, 53]
      min:45.0, max:60.0, avg:55.0, median:56.5, std_dev:4.980

 [1]: I776cabaeaf41ff4240f504fb1430d3e40892023d
      1e5b10a217
 [2]: I8da315936caebdc8b2c16cff4e24192c06743251
      90120a8b5b
 [3]: I7242e765426353672823fcc8277f20ac361930d7
      c53d78e992

Bug: 111364446
Fix: 115893206
Test: atest ActivityManagerMultiDisplayTests
Test: atest CtsInputMethodTestCases CtsInputMethodServiceHostTestCases
Test: atest FrameworksCoreTests:android.view.inputmethod.InputMethodManagerTest
Test: No perf regression in LatencyTests#testExpandNotificationsLatency()
Change-Id: I78ad7cccb9586474c83f7e2f90c0bcabb221c47b
2018-10-15 15:35:55 +08:00
Ricky Wai
6763d1f3fe Merge "Return app hidden details activity in launcher api" 2018-10-15 04:21:59 +00:00
Wale Ogunwale
342fbe9cff Moved more stuff from AMS to ATMS (20/n)
- Mirror a few more fields from ProcessRecord to WindowProcessController
- Moved mCheckedForSetup to ActivityStartController where it is actually used
- Move configuration and locale message processing to ATMS
- Switched dependency on ProcessRecord to WindowProcessController in a few places

Test: Existing test pass
Bug: 80414790
Change-Id: I7034fcb2f15defea81ad07a52d8f498da35f0760
2018-10-14 19:39:26 -07:00
Yohei Yukawa
5281b6b4c0 Add Context.getDisplayId() to avoid possible IPC
ContextImpl has an internal rule that when ContextImpl#mDisplay is
null the Context is associated with the default display.  The problem
is that, as discussed in Bug 117709581, when ContextImpl#mDisplay is
null ContextImpl#getDisplay() tries to get some non-null Display
object by making an IPC to the system server, which is redundant when
the display ID is the only thing that the caller wants to know.

By having an @hide method Context.getDisplayId(), we can ensure that
display ID can be obtained without any IPC.  This enables us to
re-submit my CL [1] that aimed to instantiate InputMethodManager (IMM)
for each display but then got reverted due to a performance regression
(Bug 117434607).

There should be no developer-observable behavior change.

 [1]: I7242e765426353672823fcc8277f20ac361930d7
      c53d78e992

Fix: 117712745
Test: atest FrameworksCoreTests:android.content.ContextTest
Test: prebuilts/checkstyle/checkstyle.py -f \
      frameworks/base/core/tests/coretests/src/android/content/ContextTest.java
Change-Id: I2534530a5ce90e2620c5039d793a6454a0a1e154
2018-10-15 07:38:25 +08:00
Suprabh Shukla
389cb6f54a Suspending app can customize intercepting dialog
The suspending app has more context about why a particular app was
suspended by the user, but we do not want to delegate the interception
of the suspended activity out of the system.
Hence allowing it further customizations to the dialog to make
it clearer.

Test: atest com.android.server.pm.SuspendDialogInfoTest \
com.android.server.pm.SuspendPackagesTest \
com.android.server.pm.PackageUserStateTest \
com.android.server.pm.PackageManagerSettingsTests \
com.android.server.am.ActivityStartInterceptorTest

atest GtsSuspendAppsPermissionTestCases GtsSuspendAppsTestCases

Bug: 112486945
Bug: 113150060
Change-Id: If9f4d14587a2b75bb572e7984a90e300a2c72d16
2018-10-12 16:02:53 -07:00
TreeHugger Robot
018f47a2b0 Merge "Revert "Instantiate InputMethodManager for each display"" 2018-10-11 15:23:34 +00:00
Ricky Wai
cf134ebfb7 Return app hidden details activity in launcher api
If a normal app does not have launcher icon, launcher api
will return app details activity instead, so user will
be noticed that the app is still installed.

Bug: 111348460

Test: Installed an app without launcher activity, an app icon is being
shown in launcher allapps, and it forwards user to app details page.

Change-Id: I9c17f5edfdefe19727145e7176d7e113286c997d
2018-10-11 14:19:04 +00:00
Yohei Yukawa
1df32c5e5c Revert "Instantiate InputMethodManager for each display"
This reverts commit c53d78e992.

Reason for revert:
Caused performance regression in
LatencyTests#testExpandNotificationsLatency.

Fix: 117434607
Bug: 111364446
Bug: 115893206
Test: atest google/perf/app-transition/sysui-latency-test-trace
Change-Id: If0d7a1b8f6d126d5a7c384ec4c2ff44260b8c35f
2018-10-11 11:52:02 +00:00
Philip P. Moltmann
e5e217dac2 Merge "Change DevicePolicyManager APIs as requested" 2018-10-10 19:50:06 +00:00
Michael Groover
a28ad42768 Merge "Protect Device Identifiers behind priv permission and DO/PO checks" 2018-10-10 18:05:23 +00:00
Adam He
c472b0ac9e Merge "Added mAutofillFlags for parcelization, and new tests." 2018-10-10 17:31:47 +00:00
TreeHugger Robot
515de0d6c2 Merge "Fix and cleanup smart replies checking" 2018-10-10 11:10:33 +00:00
Tony Mak
638430e76e Fix and cleanup smart replies checking
1. We now apply smart replies to the first action button that has
   (freeform) remote input. For example, if the notification have
   both reply and reply all buttons, smart replies will be applied
   to the first button only.
2. Enforced getAllowGeneratedReplies check in system generated
   smart replies.
3. Fixed an bug that smartRepliesAdded is not called for system
   generated smart replies.

BUG: 111546109
BUG: 111406942

Test: atest com.android.server.notification.NotificationTest
Test: Check apps generated smart replies via Messenger
Test: Check system generated smart replies via Hangouts

Change-Id: I4db34f557f7e9988be612e4162347b86393d1faf
2018-10-10 10:12:16 +01:00
Adam He
df59684d8f Added mAutofillFlags for parcelization, and new tests.
Change-Id: Ib23ee7158020b5e41ccb7781279709fc3c6ef354
Fixes: 37567426
Test: atest app.assist.AssistStructureTest
Test: atest CtsAutoFillServiceTestCases
2018-10-09 15:42:32 -07:00
Cody Northrop
70687b7783 Merge "Add ANGLE_ENABLED_APP to CoreSettings" 2018-10-09 21:43:59 +00:00
Michael Groover
6d20d75e9e Protect Device Identifiers behind priv permission and DO/PO checks
Bug: 110099294
Test: cts-tradefed run cts -m CtsDevicePolicyManagerTestCases \
      -t com.android.cts.devicepolicy.DeviceOwnerTest.testDeviceOwnerCanGetDeviceIdentifiers
Test: cts-tradefed run cts -m CtsDevicePolicyManagerTestCases \
      -t com.android.cts.devicepolicy.ManagedProfileTest#testGetDeviceIdentifiers
Test: cts-tradefed run cts -m CtsTelephonyTestCases -t android.telephony.cts.TelephonyManagerTest
Test: cts-tradefed run cts -m CtsPermissionTestCases -t android.permission.cts.TelephonyManagerPermissionTest

Change-Id: I3c82c53ec89cd17b34a61166ccc9e9747388efac
2018-10-09 13:44:02 -07:00
kopriva
c997fc62e0 Merge "docs: fixing errors found with lint check" into pi-dev am: 8c7d2142f6
am: 4d12f4c42b

Change-Id: I96a6dab05b6d4ea40950fe2ddc0948adf1b4e48f
2018-10-09 13:29:04 -07:00
kopriva
4d12f4c42b Merge "docs: fixing errors found with lint check" into pi-dev
am: 8c7d2142f6

Change-Id: Ief137b64e798b4b5bb6be5e6d25a35e08037abe5
2018-10-09 13:18:06 -07:00
Philip P. Moltmann
0ada0a6044 Change DevicePolicyManager APIs as requested
This requires RestrictedLockUtils to change which then causes further
changes.

I left the old APIs available for non-system-api customers.

Test: RunSettingsLibRoboTests
Bug: 116798569
Change-Id: Id5384ee074bb245e615012b7e0d5298b8bf27ba4
2018-10-09 12:38:23 -07:00
kopriva
a1a7848f83 docs: fixing errors found with lint check
This covers directories through /app.

removed unused import in KeyguardManager.java

Test: make ds-docs

Bug: 117494359

Change-Id: Ie2536676ae8d3ab9349aa43dc3e3248b618dd143
Exempt-From-Owner-Approval: Docs-only change
2018-10-09 10:27:35 -07:00
kopriva
dae6ec0db7 Merge "docs: fixing 'mange' instead of 'manage'" into pi-dev am: 14aa42cfda
am: 57adb99451

Change-Id: I477a610e0602e464847c1a1ccb13b21644ee1ae8
2018-10-08 19:30:00 -07:00
kopriva
57adb99451 Merge "docs: fixing 'mange' instead of 'manage'" into pi-dev
am: 14aa42cfda

Change-Id: Id461e2430301c62be5ee76f5046370069cb1a34c
2018-10-08 19:14:44 -07:00
kopriva
82c591b78b docs: fixing 'mange' instead of 'manage'
Test: make ds-docs

Bug: 117449040

Change-Id: I282a2e960bbf722bf3a72dd932e3bf685abb74e5
Exempt-From-Owner-Approval: Docs-only change
2018-10-08 15:57:00 -07:00
TreeHugger Robot
10efed0b49 Merge "Remove SMS access for apps other than current SMS handler" 2018-10-06 20:14:06 +00:00
TreeHugger Robot
ce10f9b15f Merge "Instantiate InputMethodManager for each display" 2018-10-06 17:19:58 +00:00
Wale Ogunwale
2f6c71d781 Merge "Moved startHomeActivity methods from AMS to ATMS (19/n)" 2018-10-06 13:45:13 +00:00
Wale Ogunwale
214f348ebb Moved startHomeActivity methods from AMS to ATMS (19/n)
Bug: 80414790
Test: Existing tests pass.
Change-Id: Ie3354304ea800777bd9ca7a83885b379776704e2
2018-10-05 23:32:49 -07:00
Eugene Susla
9351985f7a Remove SMS access for apps other than current SMS handler
Bug: 110098858
Test: atest android.telephony.cts.SmsManagerTest#testContentProviderAccessRestrictions
Change-Id: I9da992565b04ca5fa2656801fd2cfe4b196ef9b4
2018-10-05 16:51:13 -07:00
Yohei Yukawa
c53d78e992 Instantiate InputMethodManager for each display
InputMethodManager has been a per-process singleton object. In order
to support behavior changes for multi-display support in Android Q,
however, InputMethodManager now needs to be per-display objects.

With this CL, context.getSystemService(InputMethodManager.class) will
start returning per-display InputMethodManager (IMM) instance.

  Why?

There are two major reasons.
 1. To support per-display focused window.
 2. To support more simplified API for multi-session IME.

Currently per-process InputMethodManager instance directly receives
callback from ViewRootImpl upon windowFocusChanged, then it keeps
track of which Window is focused by storing its root view into
InputMethodManager#mCurRootView.

This design assumes that (within the same process) at most one Window
can have window focus, which is no longer true once we start
supporting per-display focused window (Bug 111361570).

  Why we need to do this to support per-display focused window:

For traditional non multi-session IME cases (e.g. apps that use
Virtual Display APIs on phones), internal state of IMM can be easily
messed up once the system starts sending per-display
windowFocusChanged events to the same process, because IMM still
doesn't know that now each display has focused window. It is hard to
precisely predict what kind of issues we would see simply because such
a use case is most likely not expected in the original design.

  Why we need to do this for multi-session IME:

For multi-session IME scenarios, in addition to the above concern in
InputMethodManager, the current design allows at most one IME session
per process. This means that if a process X is showing Activities to 3
different displays, only one Activity can interact with the
multi-session IME at the same time. If we do not change the current
design, the only way to work around is to ask app developers to
explicitly use different processes for each Activity, which may
require a lot of work (e.g. SharedPreference is not optimized for
multi-process use cases). This would also make multi-session IME
development complicated because the IME cannot know on which display
the IME is interacting until startInputOrWindowGainedFocus() is
actually called, and needs to do all the preparation and cleanup tasks
whenever startInputOrWindowGainedFocus() is called for a different
display than it's currently interacting with.

  Alternative solutions considered:

Another possible approach is to update InputMethodManager singleton to
be able to maintain multiple mCurRootView and mServedView for each
display. This approach was abandoned because those fields and methods
are already marked as @UnsupportedAppUsage.  I concluded that touching
@UnsupportedAppUsage things would have bigger compatibility risks than
per-display instance model.

  Implementation note:

* Public APIs in IMM that take View instance as the first parameter
  will verify whether the given View and IMM are associated with the
  same display ID or not.  If there is a display ID mismatch, such an
  API call will be automatically forwarded to the correct IMM instance
  IMM with a clear warning in logcat which tells that app developers
  should use the correct IMM instance to avoid unnecessary performance
  overhead.

* As a general rule, system server process cannot trust display ID
  reported from applications.  In order to enable IMMS to verify the
  reported display ID, this CL also exposes display ID verification
  logic from WMS to other system components via WindowManagerInternal.

* isInputMethodClientFocus() in WindowManagerService (WMS) is updated
  to use top-focused-display to determine whether a given IME client
  has IME focus or not.  This is now necessary because with a recent
  change [1] each display can have focused window.  The previous logic
  to check all the displays that belong to the given pid/uid [2] no
  longer makes sense.

* Currently per-display InputMethodManager instances will not be
  garbage collected because InputMethodManager#sInstanceMap keeps
  holding strong references to them.  Freeing those instances is
  technically possible, but we need to be careful because multiple
  processes (app, system, IME) are involved and at least system
  process has a strict verification logic that lets the calling
  process crash with SecurityException.  We need to carefully
  implement such a cleanup logic to avoid random process crash due to
  race condition.  Bug 116699479 will take care of this task.

 [1]: I776cabaeaf41ff4240f504fb1430d3e40892023d
      1e5b10a217
 [2]: I8da315936caebdc8b2c16cff4e24192c06743251
      90120a8b5b

Bug: 111364446
Fix: 115893206
Test: atest ActivityManagerMultiDisplayTests
Test: atest CtsInputMethodTestCases CtsInputMethodServiceHostTestCases
Test: atest FrameworksCoreTests:android.view.inputmethod.InputMethodManagerTest
Change-Id: I7242e765426353672823fcc8277f20ac361930d7
2018-10-05 15:54:41 -07:00
Cody Northrop
deb432823c Add ANGLE_ENABLED_APP to CoreSettings
The way we were checking Settings was invoking a 2ms hit.

Move ANGLE_ENABLED_APP to CoreSettings, which are already
available to the ActivityThread, eliminating the hit.

Test: Verify developer option works as expected
Test: atest google/perf/app-startup/benchmark-app-hermetic/cold-dropcache-test
Bug: 117107368
Bug: 80239516
Change-Id: I3df4c3c43489a338b3631484a8811b38c4eff2e6
2018-10-04 23:05:26 +00:00
Andrew Solovay
d10e384d6c resolve merge conflicts of a3e34fe9fe to pi-dev-plus-aosp
Bug: None
Test: Eyeballed (comment-only change).
Change-Id: Ia644cde66376b2bddeb27bb2a147b3266037aa2c
Exempt-From-Owner-Approval: Docs-only change
Merged-In: Ia06e1fffd814671289a1caebd5962aedc18a28d7
2018-10-04 22:50:39 +00:00
Andrew Solovay
a3e34fe9fe Merge "docs: Replacing {#link with {@link" into pi-dev 2018-10-04 20:06:59 +00:00