1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 #include "sal/config.h"
25 
26 #include "com/sun/star/bridge/UnoUrlResolver.hpp"
27 #include "com/sun/star/bridge/XUnoUrlResolver.hpp"
28 #include "com/sun/star/connection/NoConnectException.hpp"
29 #include "com/sun/star/frame/XDesktop.hpp"
30 #include "com/sun/star/lang/DisposedException.hpp"
31 #include "com/sun/star/uno/Reference.hxx"
32 #include "com/sun/star/uno/XComponentContext.hpp"
33 #include "cppuhelper/bootstrap.hxx"
34 #include <preextstl.h>
35 #include "gtest/gtest.h"
36 #include <postextstl.h>
37 #include "osl/process.h"
38 #include "osl/time.h"
39 #include "sal/types.h"
40 #include "test/officeconnection.hxx"
41 #include "test/toabsolutefileurl.hxx"
42 #include "test/uniquepipename.hxx"
43 
44 #include "getargument.hxx"
45 
46 namespace {
47 
48 namespace css = com::sun::star;
49 
50 }
51 
52 namespace test {
53 
OfficeConnection()54 OfficeConnection::OfficeConnection(): process_(0) {}
55 
~OfficeConnection()56 OfficeConnection::~OfficeConnection() {}
57 
setUp()58 void OfficeConnection::setUp() {
59     rtl::OUString desc;
60     rtl::OUString argSoffice;
61     EXPECT_TRUE(
62         detail::getArgument(
63             rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("soffice")),
64             &argSoffice));
65     if (argSoffice.matchAsciiL(RTL_CONSTASCII_STRINGPARAM("path:"))) {
66         desc = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("pipe,name=")) +
67             uniquePipeName(
68                 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("oootest")));
69         rtl::OUString noquickArg(
70             RTL_CONSTASCII_USTRINGPARAM("-quickstart=no"));
71         rtl::OUString nofirstArg(
72             RTL_CONSTASCII_USTRINGPARAM("-nofirststartwizard"));
73         rtl::OUString norestoreArg(RTL_CONSTASCII_USTRINGPARAM("-norestore"));
74         rtl::OUString acceptArg(
75             rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("-accept=")) + desc +
76             rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(";urp")));
77         rtl::OUString argUser;
78         EXPECT_TRUE(
79             detail::getArgument(
80                 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("user")), &argUser));
81         rtl::OUString userArg(
82             rtl::OUString(
83                 RTL_CONSTASCII_USTRINGPARAM("-env:UserInstallation=")) +
84             toAbsoluteFileUrl(argUser));
85         rtl::OUString jreArg(
86             RTL_CONSTASCII_USTRINGPARAM("-env:UNO_JAVA_JFW_ENV_JREHOME=true"));
87         rtl_uString * args[] = {
88             noquickArg.pData, nofirstArg.pData, norestoreArg.pData,
89             acceptArg.pData, userArg.pData, jreArg.pData };
90         rtl_uString ** envs = 0;
91         rtl::OUString argEnv;
92         if (detail::getArgument(
93                 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("env")), &argEnv))
94         {
95             envs = &argEnv.pData;
96         }
97         EXPECT_EQ(
98             osl_Process_E_None,
99             osl_executeProcess(
100                 toAbsoluteFileUrl(
101                     argSoffice.copy(RTL_CONSTASCII_LENGTH("path:"))).pData,
102                 args, sizeof args / sizeof args[0], 0, 0, 0, envs,
103                 envs == 0 ? 0 : 1, &process_));
104     } else if (argSoffice.matchAsciiL(RTL_CONSTASCII_STRINGPARAM("connect:"))) {
105         desc = argSoffice.copy(RTL_CONSTASCII_LENGTH("connect:"));
106     } else {
107         EXPECT_TRUE(false) <<
108             "\"soffice\" argument starts with neither \"path:\" nor"
109             " \"connect:\"";
110     }
111     css::uno::Reference< css::bridge::XUnoUrlResolver > resolver(
112         css::bridge::UnoUrlResolver::create(
113             cppu::defaultBootstrap_InitialComponentContext()));
114     for (;;) {
115         try {
116             context_ =
117                 css::uno::Reference< css::uno::XComponentContext >(
118                     resolver->resolve(
119                         rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("uno:")) +
120                         desc +
121                         rtl::OUString(
122                             RTL_CONSTASCII_USTRINGPARAM(
123                                 ";urp;StarOffice.ComponentContext"))),
124                     css::uno::UNO_QUERY_THROW);
125             break;
126         } catch (css::connection::NoConnectException &) {}
127         if (process_ != 0) {
128             TimeValue delay = { 1, 0 }; // 1 sec
129             EXPECT_EQ(
130                 osl_Process_E_TimedOut,
131                 osl_joinProcessWithTimeout(process_, &delay));
132         }
133     }
134 }
135 
tearDown()136 void OfficeConnection::tearDown() {
137     if (process_ != 0) {
138         if (context_.is()) {
139             css::uno::Reference< css::frame::XDesktop > desktop(
140                 context_->getServiceManager()->createInstanceWithContext(
141                     rtl::OUString(
142                         RTL_CONSTASCII_USTRINGPARAM(
143                             "com.sun.star.frame.Desktop")),
144                     context_),
145                 css::uno::UNO_QUERY_THROW);
146             context_.clear();
147             try {
148                 EXPECT_TRUE(desktop->terminate());
149                 desktop.clear();
150             } catch (css::lang::DisposedException &) {}
151                 // it appears that DisposedExceptions can already happen while
152                 // receiving the response of the terminate call
153         }
154         EXPECT_EQ(osl_Process_E_None, osl_joinProcess(process_));
155         oslProcessInfo info;
156         info.Size = sizeof info;
157         EXPECT_EQ(
158             osl_Process_E_None,
159             osl_getProcessInfo(process_, osl_Process_EXITCODE, &info));
160         EXPECT_EQ(oslProcessExitCode(0), info.Code);
161         osl_freeProcessHandle(process_);
162     }
163 }
164 
165 css::uno::Reference< css::uno::XComponentContext >
getComponentContext() const166 OfficeConnection::getComponentContext() const {
167     return context_;
168 }
169 
170 }
171