blob: 8edb27237f22607d42968bd6eb27ae358f1bc00f [file] [log] [blame]
Peter Qiuc0beca52015-09-03 11:25:46 -07001//
2// Copyright (C) 2013 The Android Open Source Project
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8// http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15//
mukesh agrawalae30e9e2013-05-28 14:09:16 -070016
17#ifndef SHILL_EXTERNAL_TASK_H_
18#define SHILL_EXTERNAL_TASK_H_
19
20#include <sys/types.h>
21
22#include <map>
Ben Chancd477322014-10-17 14:19:30 -070023#include <memory>
mukesh agrawalae30e9e2013-05-28 14:09:16 -070024#include <string>
25#include <vector>
26
27#include <base/callback.h>
Ben Chana0ddf462014-02-06 11:32:42 -080028#include <base/files/file_path.h>
mukesh agrawalae30e9e2013-05-28 14:09:16 -070029#include <base/memory/weak_ptr.h>
30#include <gtest/gtest_prod.h> // for FRIEND_TEST
31
mukesh agrawalae30e9e2013-05-28 14:09:16 -070032#include "shill/rpc_task.h"
33
34namespace shill {
35
36class ControlInterface;
37class Error;
mukesh agrawal9da07772013-05-15 14:15:17 -070038class EventDispatcher;
Peter Qiua24480a2015-08-11 23:09:54 -070039class ProcessManager;
mukesh agrawalae30e9e2013-05-28 14:09:16 -070040
41class ExternalTask : public RPCTaskDelegate {
42 public:
Paul Stewarta794cd62015-06-16 13:13:10 -070043 ExternalTask(ControlInterface* control,
Peter Qiua24480a2015-08-11 23:09:54 -070044 ProcessManager* process_manager,
Paul Stewarta794cd62015-06-16 13:13:10 -070045 const base::WeakPtr<RPCTaskDelegate>& task_delegate,
46 const base::Callback<void(pid_t, int)>& death_callback);
Ben Chan5ea763b2014-08-13 11:07:54 -070047 ~ExternalTask() override; // But consider DestroyLater...
mukesh agrawal9da07772013-05-15 14:15:17 -070048
49 // Schedule later deletion of the ExternalTask. Useful when in the
50 // middle of an ExternalTask callback. Note that the caller _must_
51 // release ownership of |this|. For example:
52 //
53 // class Foo : public SupportsWeakPtr<Foo>, public RPCTaskDelegate {
54 // public:
55 // Foo() {
56 // task_.reset(new ExternalTask(...));
57 // }
58 //
59 // void Notify(...) {
60 // task_.release()->DestroyLater(...); // Passes ownership.
61 // }
62 //
63 // private:
Ben Chancd477322014-10-17 14:19:30 -070064 // std::unique_ptr<ExternalTask> task_;
mukesh agrawal9da07772013-05-15 14:15:17 -070065 // }
Paul Stewarta794cd62015-06-16 13:13:10 -070066 void DestroyLater(EventDispatcher* dispatcher);
mukesh agrawalae30e9e2013-05-28 14:09:16 -070067
68 // Forks off a process to run |program|, with the command-line
69 // arguments |arguments|, and the environment variables specified in
70 // |environment|.
71 //
mukesh agrawalc4f9aa02013-08-15 19:23:13 -070072 // If |terminate_with_parent| is true, the child process will be
73 // configured to terminate itself if this process dies. Otherwise,
74 // the child process will retain its default behavior.
75 //
mukesh agrawalae30e9e2013-05-28 14:09:16 -070076 // On success, returns true, and leaves |error| unmodified.
77 // On failure, returns false, and sets |error|.
78 //
79 // |environment| SHOULD NOT contain kRPCTaskServiceVariable or
80 // kRPCTaskPathVariable, as that may prevent the child process
81 // from communicating back to the ExternalTask.
Paul Stewarta794cd62015-06-16 13:13:10 -070082 virtual bool Start(const base::FilePath& program,
83 const std::vector<std::string>& arguments,
84 const std::map<std::string, std::string>& environment,
mukesh agrawalc4f9aa02013-08-15 19:23:13 -070085 bool terminate_with_parent,
Paul Stewarta794cd62015-06-16 13:13:10 -070086 Error* error);
mukesh agrawalae30e9e2013-05-28 14:09:16 -070087 virtual void Stop();
88
89 private:
90 friend class ExternalTaskTest;
91 FRIEND_TEST(ExternalTaskTest, Destructor);
92 FRIEND_TEST(ExternalTaskTest, GetLogin);
93 FRIEND_TEST(ExternalTaskTest, Notify);
94 FRIEND_TEST(ExternalTaskTest, OnTaskDied);
95 FRIEND_TEST(ExternalTaskTest, Start);
96 FRIEND_TEST(ExternalTaskTest, Stop);
97 FRIEND_TEST(ExternalTaskTest, StopNotStarted);
98
99 // Implements RPCTaskDelegate.
Paul Stewarta794cd62015-06-16 13:13:10 -0700100 void GetLogin(std::string* user, std::string* password) override;
Alex Vakulenko016fa0e2014-08-11 15:59:58 -0700101 void Notify(
Paul Stewarta794cd62015-06-16 13:13:10 -0700102 const std::string& event,
103 const std::map<std::string, std::string>& details) override;
Peter Qiua24480a2015-08-11 23:09:54 -0700104
mukesh agrawalae30e9e2013-05-28 14:09:16 -0700105 // Called when the external process exits.
Peter Qiua24480a2015-08-11 23:09:54 -0700106 void OnTaskDied(int exit_status);
mukesh agrawalae30e9e2013-05-28 14:09:16 -0700107
Paul Stewarta794cd62015-06-16 13:13:10 -0700108 static void Destroy(ExternalTask* task);
mukesh agrawal9da07772013-05-15 14:15:17 -0700109
Paul Stewarta794cd62015-06-16 13:13:10 -0700110 ControlInterface* control_;
Peter Qiua24480a2015-08-11 23:09:54 -0700111 ProcessManager* process_manager_;
mukesh agrawalae30e9e2013-05-28 14:09:16 -0700112
Ben Chancd477322014-10-17 14:19:30 -0700113 std::unique_ptr<RPCTask> rpc_task_;
mukesh agrawalae30e9e2013-05-28 14:09:16 -0700114 base::WeakPtr<RPCTaskDelegate> task_delegate_;
115 base::Callback<void(pid_t, int)> death_callback_;
116
117 // The PID of the spawned process. May be 0 if no process has been
118 // spawned yet or the process has died.
119 pid_t pid_;
120
mukesh agrawalae30e9e2013-05-28 14:09:16 -0700121 DISALLOW_COPY_AND_ASSIGN(ExternalTask);
122};
123
124} // namespace shill
125
126#endif // SHILL_EXTERNAL_TASK_H_