|
3 | 3 | use super::{OrpcCtx, helpers::internal_err}; |
4 | 4 | use crate::commands::{apply, evolve, rollback}; |
5 | 5 | use crate::privileged_helper::{ |
6 | | - protocol::{HelperServiceStatus, SyncAgentLaunchConfig}, |
7 | | - service, |
| 6 | + protocol::SyncAgentLaunchConfig, |
8 | 7 | sync_agent::{self, SyncAgentStatus}, |
9 | 8 | }; |
10 | 9 | use crate::shared_types::{ |
11 | 10 | AppManagementCheckResult, BuildCheckResult, EtcClobberCheckResult, EvolveCancelResult, |
12 | 11 | OkResult, RebuildStatus, RollbackResult, |
13 | 12 | }; |
| 13 | +use crate::system::helper_permission; |
14 | 14 | use orpc::*; |
15 | 15 | use serde::{Deserialize, Serialize}; |
16 | 16 | use specta::Type; |
@@ -68,6 +68,28 @@ struct InstallSyncAgentInput { |
68 | 68 | config: Option<SyncAgentLaunchConfig>, |
69 | 69 | } |
70 | 70 |
|
| 71 | +/// What one reconciliation run found, for a client that only has to display it: |
| 72 | +/// whether the helper is installed and answering at this build, and the sentence |
| 73 | +/// that says what else is true. |
| 74 | +#[derive(Debug, Deserialize, Serialize, Type)] |
| 75 | +#[serde(rename_all = "camelCase")] |
| 76 | +struct HelperReport { |
| 77 | + at_this_build: bool, |
| 78 | + detail: String, |
| 79 | +} |
| 80 | + |
| 81 | +impl HelperReport { |
| 82 | + fn of(report: &crate::privileged_helper::reconcile::Reconciled) -> Self { |
| 83 | + Self { |
| 84 | + at_this_build: matches!( |
| 85 | + report, |
| 86 | + crate::privileged_helper::reconcile::Reconciled::AtThisBuild |
| 87 | + ), |
| 88 | + detail: helper_permission::describe(report), |
| 89 | + } |
| 90 | + } |
| 91 | +} |
| 92 | + |
71 | 93 | #[derive(Debug, Deserialize, Serialize, Type)] |
72 | 94 | #[serde(rename_all = "camelCase")] |
73 | 95 | struct AdoptManualChangesResult { |
@@ -193,16 +215,29 @@ async fn rebuild_status(ctx: OrpcCtx, _input: ()) -> Result<RebuildStatus, ORPCE |
193 | 215 | .map_err(|error| internal_err("darwin.rebuildStatus", error)) |
194 | 216 | } |
195 | 217 |
|
196 | | -async fn helper_status(_ctx: OrpcCtx, _input: ()) -> Result<HelperServiceStatus, ORPCError> { |
197 | | - Ok(service::status()) |
| 218 | +/// One run of the reconciliation function, reported. It takes no decision of its |
| 219 | +/// own and opens nothing — only [`helper_grant`] opens Login Items. The one thing |
| 220 | +/// it may store is the adoption: a registration that already exists is recorded as |
| 221 | +/// the user's earlier opt-in before anything is mutated under it. |
| 222 | +/// |
| 223 | +/// The same single run a status refresh makes, and no more than that: a refresh |
| 224 | +/// also starts the convergence loop, and this does not. |
| 225 | +async fn helper_status(ctx: OrpcCtx, _input: ()) -> Result<HelperReport, ORPCError> { |
| 226 | + Ok(HelperReport::of(&helper_permission::observe(&ctx.app))) |
198 | 227 | } |
199 | 228 |
|
200 | | -async fn helper_register(_ctx: OrpcCtx, _input: ()) -> Result<HelperServiceStatus, ORPCError> { |
201 | | - service::register().map_err(|error| internal_err("darwin.helperRegister", error)) |
| 229 | +/// The explicit Grant action. Grant is the only action that may open Login |
| 230 | +/// Items; `permissions.request("privileged-helper")` is the same action reached |
| 231 | +/// from the permission row. |
| 232 | +async fn helper_grant(ctx: OrpcCtx, _input: ()) -> Result<HelperReport, ORPCError> { |
| 233 | + Ok(HelperReport::of(&helper_permission::grant(&ctx.app))) |
202 | 234 | } |
203 | 235 |
|
204 | | -async fn helper_unregister(_ctx: OrpcCtx, _input: ()) -> Result<HelperServiceStatus, ORPCError> { |
205 | | - service::unregister().map_err(|error| internal_err("darwin.helperUnregister", error)) |
| 236 | +/// The explicit Disable action: unregister the helper (deferring while an |
| 237 | +/// activation runs) and |
| 238 | +/// register nothing. No later automatic run overrides it. |
| 239 | +async fn helper_disable(ctx: OrpcCtx, _input: ()) -> Result<HelperReport, ORPCError> { |
| 240 | + Ok(HelperReport::of(&helper_permission::disable(&ctx.app))) |
206 | 241 | } |
207 | 242 |
|
208 | 243 | async fn sync_agent_status(_ctx: OrpcCtx, _input: ()) -> Result<SyncAgentStatus, ORPCError> { |
@@ -278,14 +313,14 @@ pub fn routes() -> Router<OrpcCtx> { |
278 | 313 | .output(orpc_specta::specta::<RebuildStatus>()) |
279 | 314 | .handler(rebuild_status), |
280 | 315 | "helperStatus" => os::<OrpcCtx>() |
281 | | - .output(orpc_specta::specta::<HelperServiceStatus>()) |
| 316 | + .output(orpc_specta::specta::<HelperReport>()) |
282 | 317 | .handler(helper_status), |
283 | | - "helperRegister" => os::<OrpcCtx>() |
284 | | - .output(orpc_specta::specta::<HelperServiceStatus>()) |
285 | | - .handler(helper_register), |
286 | | - "helperUnregister" => os::<OrpcCtx>() |
287 | | - .output(orpc_specta::specta::<HelperServiceStatus>()) |
288 | | - .handler(helper_unregister), |
| 318 | + "helperGrant" => os::<OrpcCtx>() |
| 319 | + .output(orpc_specta::specta::<HelperReport>()) |
| 320 | + .handler(helper_grant), |
| 321 | + "helperDisable" => os::<OrpcCtx>() |
| 322 | + .output(orpc_specta::specta::<HelperReport>()) |
| 323 | + .handler(helper_disable), |
289 | 324 | "syncAgentStatus" => os::<OrpcCtx>() |
290 | 325 | .output(orpc_specta::specta::<SyncAgentStatus>()) |
291 | 326 | .handler(sync_agent_status), |
|
0 commit comments