14b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov/*
24b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov * Copyright (C) 2013 The Android Open Source Project
34b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov *
44b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov * Licensed under the Apache License, Version 2.0 (the "License");
54b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov * you may not use this file except in compliance with the License.
64b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov * You may obtain a copy of the License at
74b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov *
84b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov *      http://www.apache.org/licenses/LICENSE-2.0
94b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov *
104b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov * Unless required by applicable law or agreed to in writing, software
114b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov * distributed under the License is distributed on an "AS IS" BASIS,
124b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
134b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov * See the License for the specific language governing permissions and
144b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov * limitations under the License.
154b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov */
164b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov
174b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganovpackage com.android.server.print;
184b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov
19cd65448ccd13c4c2d0fe9e9623fec3a898ab9372Jeff Sharkeyimport static android.content.pm.PackageManager.GET_SERVICES;
20cd65448ccd13c4c2d0fe9e9623fec3a898ab9372Jeff Sharkeyimport static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
21b3baaab4af7e1ed8dfc5da1c976cc34d135fb82bPhilip P. Moltmannimport static android.content.pm.PackageManager.MATCH_INSTANT;
22b3baaab4af7e1ed8dfc5da1c976cc34d135fb82bPhilip P. Moltmannimport static android.os.Process.ROOT_UID;
23b3baaab4af7e1ed8dfc5da1c976cc34d135fb82bPhilip P. Moltmannimport static android.os.Process.SHELL_UID;
24cd65448ccd13c4c2d0fe9e9623fec3a898ab9372Jeff Sharkey
2576d7e3ee70c4299b22b1a03505d2b4f108716c75Philip P. Moltmannimport android.annotation.NonNull;
26b3baaab4af7e1ed8dfc5da1c976cc34d135fb82bPhilip P. Moltmannimport android.annotation.UserIdInt;
2786b1df234397802895771fe14cd8f2813fa43415Svetoslavimport android.app.ActivityManager;
28fef75eee1d7389f3bcff41fb8fded4f1801a2b92Vladislav Kuzkokovimport android.app.admin.DevicePolicyManagerInternal;
294b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganovimport android.content.ComponentName;
304b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganovimport android.content.Context;
314b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganovimport android.content.Intent;
324b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganovimport android.content.pm.PackageManager;
33d8f391b4e0e8d876ec7216d34f86a9b3e8bab7e5Svetoslavimport android.content.pm.ResolveInfo;
3404533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslavimport android.content.pm.UserInfo;
354b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganovimport android.database.ContentObserver;
36bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmannimport android.graphics.drawable.Icon;
374b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganovimport android.net.Uri;
384b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganovimport android.os.Binder;
397bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslavimport android.os.Bundle;
40792d58fbcef3da36dbde5fd8b0cf5a5b972bd12eVladislav Kuzkokovimport android.os.Looper;
414b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganovimport android.os.Process;
42704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganovimport android.os.RemoteException;
43b3baaab4af7e1ed8dfc5da1c976cc34d135fb82bPhilip P. Moltmannimport android.os.ResultReceiver;
44b3baaab4af7e1ed8dfc5da1c976cc34d135fb82bPhilip P. Moltmannimport android.os.ShellCallback;
454b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganovimport android.os.UserHandle;
4604533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslavimport android.os.UserManager;
47a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganovimport android.print.IPrintDocumentAdapter;
48704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganovimport android.print.IPrintJobStateChangeListener;
494b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganovimport android.print.IPrintManager;
5066c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmannimport android.print.IPrintServicesChangeListener;
5144720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganovimport android.print.IPrinterDiscoveryObserver;
524b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganovimport android.print.PrintAttributes;
532fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslavimport android.print.PrintJobId;
544b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganovimport android.print.PrintJobInfo;
5566c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmannimport android.print.PrintManager;
5644720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganovimport android.print.PrinterId;
57860f8a6b663ca96d30d17da09eca8caf065aae62Svetoslav Ganovimport android.printservice.PrintServiceInfo;
58fe9a53bc45fd0124a876dc0a49680aaf86641d3eJeff Sharkeyimport android.printservice.recommendation.IRecommendationsChangeListener;
59fe9a53bc45fd0124a876dc0a49680aaf86641d3eJeff Sharkeyimport android.printservice.recommendation.RecommendationInfo;
604b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganovimport android.provider.Settings;
61c0a128dc2b3e7af35cb39d5157ca4de9147aa3c8Philip P. Moltmannimport android.service.print.PrintServiceDumpProto;
6266c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmannimport android.util.Log;
63a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganovimport android.util.SparseArray;
64c0a128dc2b3e7af35cb39d5157ca4de9147aa3c8Philip P. Moltmannimport android.util.proto.ProtoOutputStream;
65792d58fbcef3da36dbde5fd8b0cf5a5b972bd12eVladislav Kuzkokovimport android.widget.Toast;
664b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov
674b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganovimport com.android.internal.content.PackageMonitor;
68a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganovimport com.android.internal.os.BackgroundThread;
69fe9a53bc45fd0124a876dc0a49680aaf86641d3eJeff Sharkeyimport com.android.internal.util.DumpUtils;
709a534c01ecd4a1442856c1b709e23b61f1baf9baPhilip P. Moltmannimport com.android.internal.util.IndentingPrintWriter;
7176d7e3ee70c4299b22b1a03505d2b4f108716c75Philip P. Moltmannimport com.android.internal.util.Preconditions;
72371a3b879ba82bbe5a4d914328a20659131d0220Philip P. Moltmannimport com.android.internal.util.dump.DualDumpOutputStream;
73fef75eee1d7389f3bcff41fb8fded4f1801a2b92Vladislav Kuzkokovimport com.android.server.LocalServices;
74817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasaniimport com.android.server.SystemService;
754b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov
76b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganovimport java.io.FileDescriptor;
77b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganovimport java.io.PrintWriter;
784b89d63b63d936e7ec71eafab92f5810f55014efPhilip P. Moltmannimport java.util.ArrayList;
794b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganovimport java.util.Iterator;
804b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganovimport java.util.List;
814b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov
82817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani/**
83817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani * SystemService wrapper for the PrintManager implementation. Publishes
84817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani * Context.PRINT_SERVICE.
85817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani * PrintManager implementation is contained within.
86817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani */
87817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasanipublic final class PrintManagerService extends SystemService {
8866c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann    private static final String LOG_TAG = "PrintManagerService";
8966c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann
90b880d880c6cd989eacc28c365fc9a41d31900da1Jeff Brown    private final PrintManagerImpl mPrintManagerImpl;
914b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov
92b880d880c6cd989eacc28c365fc9a41d31900da1Jeff Brown    public PrintManagerService(Context context) {
93b880d880c6cd989eacc28c365fc9a41d31900da1Jeff Brown        super(context);
94817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani        mPrintManagerImpl = new PrintManagerImpl(context);
954b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov    }
96b880d880c6cd989eacc28c365fc9a41d31900da1Jeff Brown
974b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov    @Override
98817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani    public void onStart() {
99817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani        publishBinderService(Context.PRINT_SERVICE, mPrintManagerImpl);
1004b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov    }
1014b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov
1024b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov    @Override
1030999c0d6e9c83873d9595ee764b6388dbc49dcb8Jeff Sharkey    public void onUnlockUser(int userHandle) {
1040999c0d6e9c83873d9595ee764b6388dbc49dcb8Jeff Sharkey        mPrintManagerImpl.handleUserUnlocked(userHandle);
10586b1df234397802895771fe14cd8f2813fa43415Svetoslav    }
10686b1df234397802895771fe14cd8f2813fa43415Svetoslav
10786b1df234397802895771fe14cd8f2813fa43415Svetoslav    @Override
10886b1df234397802895771fe14cd8f2813fa43415Svetoslav    public void onStopUser(int userHandle) {
10986b1df234397802895771fe14cd8f2813fa43415Svetoslav        mPrintManagerImpl.handleUserStopped(userHandle);
1104b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov    }
1114b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov
112817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani    class PrintManagerImpl extends IPrintManager.Stub {
11304533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav        private static final int BACKGROUND_USER_ID = -10;
11404533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav
115817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani        private final Object mLock = new Object();
116860f8a6b663ca96d30d17da09eca8caf065aae62Svetoslav Ganov
117817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani        private final Context mContext;
118d8dbc13b47bec3248a86a505a30af9d0474240dcSvetoslav
11904533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav        private final UserManager mUserManager;
12004533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav
12186b1df234397802895771fe14cd8f2813fa43415Svetoslav        private final SparseArray<UserState> mUserStates = new SparseArray<>();
122817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani
123817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani        PrintManagerImpl(Context context) {
124817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            mContext = context;
12504533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav            mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
126817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            registerContentObservers();
12704533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav            registerBroadcastReceivers();
12844720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov        }
12944720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov
130817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani        @Override
131b3baaab4af7e1ed8dfc5da1c976cc34d135fb82bPhilip P. Moltmann        public void onShellCommand(FileDescriptor in, FileDescriptor out,
132b3baaab4af7e1ed8dfc5da1c976cc34d135fb82bPhilip P. Moltmann                FileDescriptor err, String[] args, ShellCallback callback,
133b3baaab4af7e1ed8dfc5da1c976cc34d135fb82bPhilip P. Moltmann                ResultReceiver resultReceiver) {
134b3baaab4af7e1ed8dfc5da1c976cc34d135fb82bPhilip P. Moltmann            new PrintShellCommand(this).exec(this, in, out, err, args, callback, resultReceiver);
135b3baaab4af7e1ed8dfc5da1c976cc34d135fb82bPhilip P. Moltmann        }
136b3baaab4af7e1ed8dfc5da1c976cc34d135fb82bPhilip P. Moltmann
137b3baaab4af7e1ed8dfc5da1c976cc34d135fb82bPhilip P. Moltmann        @Override
138817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani        public Bundle print(String printJobName, IPrintDocumentAdapter adapter,
139817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani                PrintAttributes attributes, String packageName, int appId, int userId) {
14076d7e3ee70c4299b22b1a03505d2b4f108716c75Philip P. Moltmann            adapter = Preconditions.checkNotNull(adapter);
141792d58fbcef3da36dbde5fd8b0cf5a5b972bd12eVladislav Kuzkokov            if (!isPrintingEnabled()) {
142fef75eee1d7389f3bcff41fb8fded4f1801a2b92Vladislav Kuzkokov                CharSequence disabledMessage = null;
143fef75eee1d7389f3bcff41fb8fded4f1801a2b92Vladislav Kuzkokov                DevicePolicyManagerInternal dpmi =
144fef75eee1d7389f3bcff41fb8fded4f1801a2b92Vladislav Kuzkokov                        LocalServices.getService(DevicePolicyManagerInternal.class);
145fef75eee1d7389f3bcff41fb8fded4f1801a2b92Vladislav Kuzkokov                final int callingUserId = UserHandle.getCallingUserId();
146fef75eee1d7389f3bcff41fb8fded4f1801a2b92Vladislav Kuzkokov                final long identity = Binder.clearCallingIdentity();
147fef75eee1d7389f3bcff41fb8fded4f1801a2b92Vladislav Kuzkokov                try {
148fef75eee1d7389f3bcff41fb8fded4f1801a2b92Vladislav Kuzkokov                    disabledMessage = dpmi.getPrintingDisabledReasonForUser(callingUserId);
149fef75eee1d7389f3bcff41fb8fded4f1801a2b92Vladislav Kuzkokov                } finally {
150fef75eee1d7389f3bcff41fb8fded4f1801a2b92Vladislav Kuzkokov                    Binder.restoreCallingIdentity(identity);
151fef75eee1d7389f3bcff41fb8fded4f1801a2b92Vladislav Kuzkokov                }
152792d58fbcef3da36dbde5fd8b0cf5a5b972bd12eVladislav Kuzkokov                if (disabledMessage != null) {
153792d58fbcef3da36dbde5fd8b0cf5a5b972bd12eVladislav Kuzkokov                    Toast.makeText(mContext, Looper.getMainLooper(), disabledMessage,
154792d58fbcef3da36dbde5fd8b0cf5a5b972bd12eVladislav Kuzkokov                            Toast.LENGTH_LONG).show();
155792d58fbcef3da36dbde5fd8b0cf5a5b972bd12eVladislav Kuzkokov                }
156792d58fbcef3da36dbde5fd8b0cf5a5b972bd12eVladislav Kuzkokov                try {
157792d58fbcef3da36dbde5fd8b0cf5a5b972bd12eVladislav Kuzkokov                    adapter.start();
158792d58fbcef3da36dbde5fd8b0cf5a5b972bd12eVladislav Kuzkokov                } catch (RemoteException re) {
159792d58fbcef3da36dbde5fd8b0cf5a5b972bd12eVladislav Kuzkokov                    Log.e(LOG_TAG, "Error calling IPrintDocumentAdapter.start()");
160792d58fbcef3da36dbde5fd8b0cf5a5b972bd12eVladislav Kuzkokov                }
161792d58fbcef3da36dbde5fd8b0cf5a5b972bd12eVladislav Kuzkokov                try {
162792d58fbcef3da36dbde5fd8b0cf5a5b972bd12eVladislav Kuzkokov                    adapter.finish();
163792d58fbcef3da36dbde5fd8b0cf5a5b972bd12eVladislav Kuzkokov                } catch (RemoteException re) {
164792d58fbcef3da36dbde5fd8b0cf5a5b972bd12eVladislav Kuzkokov                    Log.e(LOG_TAG, "Error calling IPrintDocumentAdapter.finish()");
165792d58fbcef3da36dbde5fd8b0cf5a5b972bd12eVladislav Kuzkokov                }
166792d58fbcef3da36dbde5fd8b0cf5a5b972bd12eVladislav Kuzkokov                return null;
167792d58fbcef3da36dbde5fd8b0cf5a5b972bd12eVladislav Kuzkokov            }
168792d58fbcef3da36dbde5fd8b0cf5a5b972bd12eVladislav Kuzkokov            printJobName = Preconditions.checkStringNotEmpty(printJobName);
16976d7e3ee70c4299b22b1a03505d2b4f108716c75Philip P. Moltmann            packageName = Preconditions.checkStringNotEmpty(packageName);
17076d7e3ee70c4299b22b1a03505d2b4f108716c75Philip P. Moltmann
171817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId);
17204533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav            final int resolvedAppId;
173817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            final UserState userState;
17404533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav            final String resolvedPackageName;
175817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            synchronized (mLock) {
17604533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav                // Only the current group members can start new print jobs.
17786b1df234397802895771fe14cd8f2813fa43415Svetoslav                if (resolveCallingProfileParentLocked(resolvedUserId) != getCurrentUserId()) {
17804533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav                    return null;
17904533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav                }
18004533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav                resolvedAppId = resolveCallingAppEnforcingPermissions(appId);
18104533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav                resolvedPackageName = resolveCallingPackageNameEnforcingSecurity(packageName);
182e8ae15482eef7617494cb3187899983e27cb8a35Philip P. Moltmann                userState = getOrCreateUserStateLocked(resolvedUserId, false);
183817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            }
184817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            final long identity = Binder.clearCallingIdentity();
185817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            try {
186817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani                return userState.print(printJobName, adapter, attributes,
187817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani                        resolvedPackageName, resolvedAppId);
188817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            } finally {
189817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani                Binder.restoreCallingIdentity(identity);
190817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            }
19144720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov        }
192817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani
193817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani        @Override
194817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani        public List<PrintJobInfo> getPrintJobInfos(int appId, int userId) {
195817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId);
19604533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav            final int resolvedAppId;
197817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            final UserState userState;
198817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            synchronized (mLock) {
19904533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav                // Only the current group members can query for state of print jobs.
20086b1df234397802895771fe14cd8f2813fa43415Svetoslav                if (resolveCallingProfileParentLocked(resolvedUserId) != getCurrentUserId()) {
20104533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav                    return null;
20204533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav                }
20304533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav                resolvedAppId = resolveCallingAppEnforcingPermissions(appId);
204e8ae15482eef7617494cb3187899983e27cb8a35Philip P. Moltmann                userState = getOrCreateUserStateLocked(resolvedUserId, false);
205817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            }
206817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            final long identity = Binder.clearCallingIdentity();
207817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            try {
208817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani                return userState.getPrintJobInfos(resolvedAppId);
209817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            } finally {
210817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani                Binder.restoreCallingIdentity(identity);
211817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            }
21244720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov        }
21344720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov
214817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani        @Override
215817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani        public PrintJobInfo getPrintJobInfo(PrintJobId printJobId, int appId, int userId) {
21676d7e3ee70c4299b22b1a03505d2b4f108716c75Philip P. Moltmann            if (printJobId == null) {
21776d7e3ee70c4299b22b1a03505d2b4f108716c75Philip P. Moltmann                return null;
21876d7e3ee70c4299b22b1a03505d2b4f108716c75Philip P. Moltmann            }
21976d7e3ee70c4299b22b1a03505d2b4f108716c75Philip P. Moltmann
220817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId);
22104533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav            final int resolvedAppId;
222817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            final UserState userState;
223817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            synchronized (mLock) {
22404533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav                // Only the current group members can query for state of a print job.
22586b1df234397802895771fe14cd8f2813fa43415Svetoslav                if (resolveCallingProfileParentLocked(resolvedUserId) != getCurrentUserId()) {
22604533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav                    return null;
22704533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav                }
22804533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav                resolvedAppId = resolveCallingAppEnforcingPermissions(appId);
229e8ae15482eef7617494cb3187899983e27cb8a35Philip P. Moltmann                userState = getOrCreateUserStateLocked(resolvedUserId, false);
230817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            }
231817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            final long identity = Binder.clearCallingIdentity();
232817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            try {
233817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani                return userState.getPrintJobInfo(printJobId, resolvedAppId);
234817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            } finally {
235817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani                Binder.restoreCallingIdentity(identity);
236817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            }
23744720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov        }
238817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani
239817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani        @Override
240bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann        public Icon getCustomPrinterIcon(PrinterId printerId, int userId) {
24176d7e3ee70c4299b22b1a03505d2b4f108716c75Philip P. Moltmann            printerId = Preconditions.checkNotNull(printerId);
24276d7e3ee70c4299b22b1a03505d2b4f108716c75Philip P. Moltmann
243bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann            final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId);
244bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann            final UserState userState;
245bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann            synchronized (mLock) {
246bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann                // Only the current group members can get the printer icons.
247bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann                if (resolveCallingProfileParentLocked(resolvedUserId) != getCurrentUserId()) {
248bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann                    return null;
249bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann                }
250e8ae15482eef7617494cb3187899983e27cb8a35Philip P. Moltmann                userState = getOrCreateUserStateLocked(resolvedUserId, false);
251bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann            }
252bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann            final long identity = Binder.clearCallingIdentity();
253bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann            try {
254bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann                return userState.getCustomPrinterIcon(printerId);
255bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann            } finally {
256bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann                Binder.restoreCallingIdentity(identity);
257bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann            }
258bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann        }
259bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann
260bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann        @Override
261817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani        public void cancelPrintJob(PrintJobId printJobId, int appId, int userId) {
26276d7e3ee70c4299b22b1a03505d2b4f108716c75Philip P. Moltmann            if (printJobId == null) {
26376d7e3ee70c4299b22b1a03505d2b4f108716c75Philip P. Moltmann                return;
26476d7e3ee70c4299b22b1a03505d2b4f108716c75Philip P. Moltmann            }
26576d7e3ee70c4299b22b1a03505d2b4f108716c75Philip P. Moltmann
266817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId);
26704533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav            final int resolvedAppId;
268817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            final UserState userState;
269817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            synchronized (mLock) {
27004533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav                // Only the current group members can cancel a print job.
27186b1df234397802895771fe14cd8f2813fa43415Svetoslav                if (resolveCallingProfileParentLocked(resolvedUserId) != getCurrentUserId()) {
27204533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav                    return;
27304533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav                }
27404533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav                resolvedAppId = resolveCallingAppEnforcingPermissions(appId);
275e8ae15482eef7617494cb3187899983e27cb8a35Philip P. Moltmann                userState = getOrCreateUserStateLocked(resolvedUserId, false);
276817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            }
277817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            final long identity = Binder.clearCallingIdentity();
278817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            try {
279817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani                userState.cancelPrintJob(printJobId, resolvedAppId);
280817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            } finally {
281817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani                Binder.restoreCallingIdentity(identity);
282817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            }
28344720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov        }
28444720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov
285817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani        @Override
286817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani        public void restartPrintJob(PrintJobId printJobId, int appId, int userId) {
287792d58fbcef3da36dbde5fd8b0cf5a5b972bd12eVladislav Kuzkokov            if (printJobId == null || !isPrintingEnabled()) {
288792d58fbcef3da36dbde5fd8b0cf5a5b972bd12eVladislav Kuzkokov                // if printing is disabled the state just remains "failed".
28976d7e3ee70c4299b22b1a03505d2b4f108716c75Philip P. Moltmann                return;
29076d7e3ee70c4299b22b1a03505d2b4f108716c75Philip P. Moltmann            }
29176d7e3ee70c4299b22b1a03505d2b4f108716c75Philip P. Moltmann
292817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId);
29304533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav            final int resolvedAppId;
294817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            final UserState userState;
295817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            synchronized (mLock) {
29604533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav                // Only the current group members can restart a print job.
29786b1df234397802895771fe14cd8f2813fa43415Svetoslav                if (resolveCallingProfileParentLocked(resolvedUserId) != getCurrentUserId()) {
29804533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav                    return;
29904533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav                }
30004533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav                resolvedAppId = resolveCallingAppEnforcingPermissions(appId);
301e8ae15482eef7617494cb3187899983e27cb8a35Philip P. Moltmann                userState = getOrCreateUserStateLocked(resolvedUserId, false);
302817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            }
303817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            final long identity = Binder.clearCallingIdentity();
304817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            try {
305817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani                userState.restartPrintJob(printJobId, resolvedAppId);
306817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            } finally {
307817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani                Binder.restoreCallingIdentity(identity);
308817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            }
30944720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov        }
310817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani
311817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani        @Override
31266c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann        public List<PrintServiceInfo> getPrintServices(int selectionFlags, int userId) {
31366c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann            Preconditions.checkFlagsArgument(selectionFlags,
31466c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann                    PrintManager.DISABLED_SERVICES | PrintManager.ENABLED_SERVICES);
31566c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann
3166870033d374a15fd212675d570a2877c28f1cbf0Philip P. Moltmann            mContext.enforceCallingOrSelfPermission(
3176870033d374a15fd212675d570a2877c28f1cbf0Philip P. Moltmann                    android.Manifest.permission.READ_PRINT_SERVICES, null);
318817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId);
319817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            final UserState userState;
320817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            synchronized (mLock) {
3219dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann                // Only the current group members can get print services.
32286b1df234397802895771fe14cd8f2813fa43415Svetoslav                if (resolveCallingProfileParentLocked(resolvedUserId) != getCurrentUserId()) {
32304533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav                    return null;
32404533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav                }
325e8ae15482eef7617494cb3187899983e27cb8a35Philip P. Moltmann                userState = getOrCreateUserStateLocked(resolvedUserId, false);
326817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            }
327817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            final long identity = Binder.clearCallingIdentity();
328817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            try {
32966c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann                return userState.getPrintServices(selectionFlags);
330817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            } finally {
331817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani                Binder.restoreCallingIdentity(identity);
332817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            }
333d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov        }
334d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov
335817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani        @Override
33666c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann        public void setPrintServiceEnabled(ComponentName service, boolean isEnabled, int userId) {
337817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId);
33866c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann            final int appId = UserHandle.getAppId(Binder.getCallingUid());
33966c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann
34066c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann            try {
34166c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann                if (appId != Process.SYSTEM_UID && appId != UserHandle.getAppId(
34266c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann                        mContext.getPackageManager().getPackageUidAsUser(
34366c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann                                PrintManager.PRINT_SPOOLER_PACKAGE_NAME, resolvedUserId))) {
34466c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann                    throw new SecurityException("Only system and print spooler can call this");
34566c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann                }
34666c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann            } catch (PackageManager.NameNotFoundException e) {
34766c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann                Log.e(LOG_TAG, "Could not verify caller", e);
34866c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann                return;
34966c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann            }
35066c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann
35166c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann            service = Preconditions.checkNotNull(service);
35266c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann
353817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            final UserState userState;
354817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            synchronized (mLock) {
35566c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann                // Only the current group members can enable / disable services.
35686b1df234397802895771fe14cd8f2813fa43415Svetoslav                if (resolveCallingProfileParentLocked(resolvedUserId) != getCurrentUserId()) {
35766c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann                    return;
35804533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav                }
359e8ae15482eef7617494cb3187899983e27cb8a35Philip P. Moltmann                userState = getOrCreateUserStateLocked(resolvedUserId, false);
360817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            }
361817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            final long identity = Binder.clearCallingIdentity();
362817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            try {
36366c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann                userState.setPrintServiceEnabled(service, isEnabled);
364817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            } finally {
365817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani                Binder.restoreCallingIdentity(identity);
366817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            }
367d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov        }
368817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani
369817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani        @Override
3709dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann        public List<RecommendationInfo> getPrintServiceRecommendations(int userId) {
3716870033d374a15fd212675d570a2877c28f1cbf0Philip P. Moltmann            mContext.enforceCallingOrSelfPermission(
3726870033d374a15fd212675d570a2877c28f1cbf0Philip P. Moltmann                    android.Manifest.permission.READ_PRINT_SERVICE_RECOMMENDATIONS, null);
3739dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann            final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId);
3749dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann            final UserState userState;
3759dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann            synchronized (mLock) {
3769dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann                // Only the current group members can get print service recommendations.
3779dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann                if (resolveCallingProfileParentLocked(resolvedUserId) != getCurrentUserId()) {
3789dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann                    return null;
3799dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann                }
3809dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann                userState = getOrCreateUserStateLocked(resolvedUserId, false);
3819dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann            }
3829dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann            final long identity = Binder.clearCallingIdentity();
3839dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann            try {
3849dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann                return userState.getPrintServiceRecommendations();
3859dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann            } finally {
3869dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann                Binder.restoreCallingIdentity(identity);
3879dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann            }
3889dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann        }
3899dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann
3909dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann        @Override
391817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani        public void createPrinterDiscoverySession(IPrinterDiscoveryObserver observer,
392817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani                int userId) {
39376d7e3ee70c4299b22b1a03505d2b4f108716c75Philip P. Moltmann            observer = Preconditions.checkNotNull(observer);
39476d7e3ee70c4299b22b1a03505d2b4f108716c75Philip P. Moltmann
395817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId);
396817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            final UserState userState;
397817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            synchronized (mLock) {
39804533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav                // Only the current group members can create a discovery session.
39986b1df234397802895771fe14cd8f2813fa43415Svetoslav                if (resolveCallingProfileParentLocked(resolvedUserId) != getCurrentUserId()) {
40004533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav                    return;
40104533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav                }
402e8ae15482eef7617494cb3187899983e27cb8a35Philip P. Moltmann                userState = getOrCreateUserStateLocked(resolvedUserId, false);
403817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            }
404817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            final long identity = Binder.clearCallingIdentity();
405817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            try {
406817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani                userState.createPrinterDiscoverySession(observer);
407817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            } finally {
408817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani                Binder.restoreCallingIdentity(identity);
409817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            }
410d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov        }
411d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov
412817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani        @Override
413817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani        public void destroyPrinterDiscoverySession(IPrinterDiscoveryObserver observer,
414817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani                int userId) {
41576d7e3ee70c4299b22b1a03505d2b4f108716c75Philip P. Moltmann            observer = Preconditions.checkNotNull(observer);
41676d7e3ee70c4299b22b1a03505d2b4f108716c75Philip P. Moltmann
417817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId);
418817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            final UserState userState;
419817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            synchronized (mLock) {
42004533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav                // Only the current group members can destroy a discovery session.
42186b1df234397802895771fe14cd8f2813fa43415Svetoslav                if (resolveCallingProfileParentLocked(resolvedUserId) != getCurrentUserId()) {
42204533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav                    return;
42304533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav                }
424e8ae15482eef7617494cb3187899983e27cb8a35Philip P. Moltmann                userState = getOrCreateUserStateLocked(resolvedUserId, false);
425817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            }
426817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            final long identity = Binder.clearCallingIdentity();
427817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            try {
428817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani                userState.destroyPrinterDiscoverySession(observer);
429817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            } finally {
430817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani                Binder.restoreCallingIdentity(identity);
431817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            }
432d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov        }
433817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani
434817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani        @Override
435817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani        public void startPrinterDiscovery(IPrinterDiscoveryObserver observer,
436817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani                List<PrinterId> priorityList, int userId) {
43776d7e3ee70c4299b22b1a03505d2b4f108716c75Philip P. Moltmann            observer = Preconditions.checkNotNull(observer);
43876d7e3ee70c4299b22b1a03505d2b4f108716c75Philip P. Moltmann            if (priorityList != null) {
43976d7e3ee70c4299b22b1a03505d2b4f108716c75Philip P. Moltmann                priorityList = Preconditions.checkCollectionElementsNotNull(priorityList,
44076d7e3ee70c4299b22b1a03505d2b4f108716c75Philip P. Moltmann                        "PrinterId");
44176d7e3ee70c4299b22b1a03505d2b4f108716c75Philip P. Moltmann            }
44276d7e3ee70c4299b22b1a03505d2b4f108716c75Philip P. Moltmann
443817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId);
444817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            final UserState userState;
445817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            synchronized (mLock) {
44604533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav                // Only the current group members can start discovery.
44786b1df234397802895771fe14cd8f2813fa43415Svetoslav                if (resolveCallingProfileParentLocked(resolvedUserId) != getCurrentUserId()) {
44804533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav                    return;
44904533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav                }
450e8ae15482eef7617494cb3187899983e27cb8a35Philip P. Moltmann                userState = getOrCreateUserStateLocked(resolvedUserId, false);
451817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            }
452817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            final long identity = Binder.clearCallingIdentity();
453817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            try {
454817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani                userState.startPrinterDiscovery(observer, priorityList);
455817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            } finally {
456817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani                Binder.restoreCallingIdentity(identity);
457817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            }
45844720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov        }
45944720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov
460817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani        @Override
461817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani        public void stopPrinterDiscovery(IPrinterDiscoveryObserver observer, int userId) {
46276d7e3ee70c4299b22b1a03505d2b4f108716c75Philip P. Moltmann            observer = Preconditions.checkNotNull(observer);
46376d7e3ee70c4299b22b1a03505d2b4f108716c75Philip P. Moltmann
464817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId);
465817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            final UserState userState;
466817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            synchronized (mLock) {
46704533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav                // Only the current group members can stop discovery.
46886b1df234397802895771fe14cd8f2813fa43415Svetoslav                if (resolveCallingProfileParentLocked(resolvedUserId) != getCurrentUserId()) {
46904533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav                    return;
47004533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav                }
471e8ae15482eef7617494cb3187899983e27cb8a35Philip P. Moltmann                userState = getOrCreateUserStateLocked(resolvedUserId, false);
472817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            }
473817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            final long identity = Binder.clearCallingIdentity();
474817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            try {
475817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani                userState.stopPrinterDiscovery(observer);
476817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            } finally {
477817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani                Binder.restoreCallingIdentity(identity);
478817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            }
479704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov        }
480817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani
481817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani        @Override
482817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani        public void validatePrinters(List<PrinterId> printerIds, int userId) {
48376d7e3ee70c4299b22b1a03505d2b4f108716c75Philip P. Moltmann            printerIds = Preconditions.checkCollectionElementsNotNull(printerIds, "PrinterId");
48476d7e3ee70c4299b22b1a03505d2b4f108716c75Philip P. Moltmann
485817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId);
486817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            final UserState userState;
487817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            synchronized (mLock) {
48804533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav                // Only the current group members can validate printers.
48986b1df234397802895771fe14cd8f2813fa43415Svetoslav                if (resolveCallingProfileParentLocked(resolvedUserId) != getCurrentUserId()) {
49004533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav                    return;
49104533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav                }
492e8ae15482eef7617494cb3187899983e27cb8a35Philip P. Moltmann                userState = getOrCreateUserStateLocked(resolvedUserId, false);
493817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            }
494817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            final long identity = Binder.clearCallingIdentity();
495817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            try {
496817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani                userState.validatePrinters(printerIds);
497817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            } finally {
498817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani                Binder.restoreCallingIdentity(identity);
499817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            }
500704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov        }
501704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov
502817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani        @Override
503817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani        public void startPrinterStateTracking(PrinterId printerId, int userId) {
50476d7e3ee70c4299b22b1a03505d2b4f108716c75Philip P. Moltmann            printerId = Preconditions.checkNotNull(printerId);
50576d7e3ee70c4299b22b1a03505d2b4f108716c75Philip P. Moltmann
506817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId);
507817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            final UserState userState;
508817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            synchronized (mLock) {
50904533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav                // Only the current group members can start printer tracking.
51086b1df234397802895771fe14cd8f2813fa43415Svetoslav                if (resolveCallingProfileParentLocked(resolvedUserId) != getCurrentUserId()) {
51104533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav                    return;
51204533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav                }
513e8ae15482eef7617494cb3187899983e27cb8a35Philip P. Moltmann                userState = getOrCreateUserStateLocked(resolvedUserId, false);
514817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            }
515817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            final long identity = Binder.clearCallingIdentity();
516817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            try {
517817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani                userState.startPrinterStateTracking(printerId);
518817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            } finally {
519817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani                Binder.restoreCallingIdentity(identity);
520817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            }
521704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov        }
522817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani
523817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani        @Override
524817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani        public void stopPrinterStateTracking(PrinterId printerId, int userId) {
52576d7e3ee70c4299b22b1a03505d2b4f108716c75Philip P. Moltmann            printerId = Preconditions.checkNotNull(printerId);
52676d7e3ee70c4299b22b1a03505d2b4f108716c75Philip P. Moltmann
527817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId);
528817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            final UserState userState;
529817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            synchronized (mLock) {
53004533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav                // Only the current group members can stop printer tracking.
53186b1df234397802895771fe14cd8f2813fa43415Svetoslav                if (resolveCallingProfileParentLocked(resolvedUserId) != getCurrentUserId()) {
53204533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav                    return;
53304533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav                }
534e8ae15482eef7617494cb3187899983e27cb8a35Philip P. Moltmann                userState = getOrCreateUserStateLocked(resolvedUserId, false);
535817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            }
536817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            final long identity = Binder.clearCallingIdentity();
537817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            try {
538817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani                userState.stopPrinterStateTracking(printerId);
539817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            } finally {
540817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani                Binder.restoreCallingIdentity(identity);
541817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            }
542704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov        }
543704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov
544817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani        @Override
545817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani        public void addPrintJobStateChangeListener(IPrintJobStateChangeListener listener,
546817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani                int appId, int userId) throws RemoteException {
54776d7e3ee70c4299b22b1a03505d2b4f108716c75Philip P. Moltmann            listener = Preconditions.checkNotNull(listener);
54876d7e3ee70c4299b22b1a03505d2b4f108716c75Philip P. Moltmann
549817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId);
55004533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav            final int resolvedAppId;
551817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            final UserState userState;
552817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            synchronized (mLock) {
55304533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav                // Only the current group members can add a print job listener.
55486b1df234397802895771fe14cd8f2813fa43415Svetoslav                if (resolveCallingProfileParentLocked(resolvedUserId) != getCurrentUserId()) {
55504533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav                    return;
55604533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav                }
55704533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav                resolvedAppId = resolveCallingAppEnforcingPermissions(appId);
558e8ae15482eef7617494cb3187899983e27cb8a35Philip P. Moltmann                userState = getOrCreateUserStateLocked(resolvedUserId, false);
559817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            }
560817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            final long identity = Binder.clearCallingIdentity();
561817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            try {
562817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani                userState.addPrintJobStateChangeListener(listener, resolvedAppId);
563817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            } finally {
564817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani                Binder.restoreCallingIdentity(identity);
565817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            }
566b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov        }
567b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov
568817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani        @Override
569817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani        public void removePrintJobStateChangeListener(IPrintJobStateChangeListener listener,
570817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani                int userId) {
57176d7e3ee70c4299b22b1a03505d2b4f108716c75Philip P. Moltmann            listener = Preconditions.checkNotNull(listener);
57276d7e3ee70c4299b22b1a03505d2b4f108716c75Philip P. Moltmann
573817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId);
574817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            final UserState userState;
575817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            synchronized (mLock) {
57604533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav                // Only the current group members can remove a print job listener.
57786b1df234397802895771fe14cd8f2813fa43415Svetoslav                if (resolveCallingProfileParentLocked(resolvedUserId) != getCurrentUserId()) {
57804533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav                    return;
57904533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav                }
580e8ae15482eef7617494cb3187899983e27cb8a35Philip P. Moltmann                userState = getOrCreateUserStateLocked(resolvedUserId, false);
581817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            }
5825fe07aa7a81c840eaf52bf95d4d5bacd914a8106Svetoslav            final long identity = Binder.clearCallingIdentity();
5835fe07aa7a81c840eaf52bf95d4d5bacd914a8106Svetoslav            try {
584817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani                userState.removePrintJobStateChangeListener(listener);
5855fe07aa7a81c840eaf52bf95d4d5bacd914a8106Svetoslav            } finally {
5865fe07aa7a81c840eaf52bf95d4d5bacd914a8106Svetoslav                Binder.restoreCallingIdentity(identity);
587b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov            }
588b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov        }
589b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov
590817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani        @Override
59166c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann        public void addPrintServicesChangeListener(IPrintServicesChangeListener listener,
59266c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann                int userId) throws RemoteException {
59366c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann            listener = Preconditions.checkNotNull(listener);
59466c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann
5956870033d374a15fd212675d570a2877c28f1cbf0Philip P. Moltmann            mContext.enforceCallingOrSelfPermission(android.Manifest.permission.READ_PRINT_SERVICES,
5966870033d374a15fd212675d570a2877c28f1cbf0Philip P. Moltmann                    null);
59766c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann            final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId);
59866c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann            final UserState userState;
59966c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann            synchronized (mLock) {
60066c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann                // Only the current group members can add a print services listener.
60166c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann                if (resolveCallingProfileParentLocked(resolvedUserId) != getCurrentUserId()) {
60266c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann                    return;
60366c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann                }
604e8ae15482eef7617494cb3187899983e27cb8a35Philip P. Moltmann                userState = getOrCreateUserStateLocked(resolvedUserId, false);
60566c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann            }
60666c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann            final long identity = Binder.clearCallingIdentity();
60766c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann            try {
60866c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann                userState.addPrintServicesChangeListener(listener);
60966c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann            } finally {
61066c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann                Binder.restoreCallingIdentity(identity);
61166c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann            }
61266c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann        }
61366c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann
61466c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann        @Override
61566c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann        public void removePrintServicesChangeListener(IPrintServicesChangeListener listener,
61666c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann                int userId) {
61766c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann            listener = Preconditions.checkNotNull(listener);
61866c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann
6196870033d374a15fd212675d570a2877c28f1cbf0Philip P. Moltmann            mContext.enforceCallingOrSelfPermission(android.Manifest.permission.READ_PRINT_SERVICES,
6206870033d374a15fd212675d570a2877c28f1cbf0Philip P. Moltmann                    null);
62166c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann            final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId);
62266c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann            final UserState userState;
62366c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann            synchronized (mLock) {
6249dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann                // Only the current group members can remove a print services change listener.
62566c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann                if (resolveCallingProfileParentLocked(resolvedUserId) != getCurrentUserId()) {
62666c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann                    return;
62766c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann                }
628e8ae15482eef7617494cb3187899983e27cb8a35Philip P. Moltmann                userState = getOrCreateUserStateLocked(resolvedUserId, false);
62966c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann            }
63066c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann            final long identity = Binder.clearCallingIdentity();
63166c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann            try {
63266c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann                userState.removePrintServicesChangeListener(listener);
63366c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann            } finally {
63466c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann                Binder.restoreCallingIdentity(identity);
63566c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann            }
63666c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann        }
63766c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann
63866c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann        @Override
6399dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann        public void addPrintServiceRecommendationsChangeListener(
6409dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann                IRecommendationsChangeListener listener, int userId)
6419dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann                throws RemoteException {
6429dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann            listener = Preconditions.checkNotNull(listener);
6439dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann
6446870033d374a15fd212675d570a2877c28f1cbf0Philip P. Moltmann            mContext.enforceCallingOrSelfPermission(
6456870033d374a15fd212675d570a2877c28f1cbf0Philip P. Moltmann                    android.Manifest.permission.READ_PRINT_SERVICE_RECOMMENDATIONS, null);
6469dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann            final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId);
6479dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann            final UserState userState;
6489dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann            synchronized (mLock) {
6499dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann                // Only the current group members can add a print service recommendations listener.
6509dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann                if (resolveCallingProfileParentLocked(resolvedUserId) != getCurrentUserId()) {
6519dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann                    return;
6529dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann                }
6539dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann                userState = getOrCreateUserStateLocked(resolvedUserId, false);
6549dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann            }
6559dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann            final long identity = Binder.clearCallingIdentity();
6569dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann            try {
6579dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann                userState.addPrintServiceRecommendationsChangeListener(listener);
6589dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann            } finally {
6599dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann                Binder.restoreCallingIdentity(identity);
6609dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann            }
6619dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann        }
6629dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann
6639dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann        @Override
6649dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann        public void removePrintServiceRecommendationsChangeListener(
6659dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann                IRecommendationsChangeListener listener, int userId) {
6669dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann            listener = Preconditions.checkNotNull(listener);
6679dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann
6686870033d374a15fd212675d570a2877c28f1cbf0Philip P. Moltmann            mContext.enforceCallingOrSelfPermission(
6696870033d374a15fd212675d570a2877c28f1cbf0Philip P. Moltmann                    android.Manifest.permission.READ_PRINT_SERVICE_RECOMMENDATIONS, null);
6709dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann            final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId);
6719dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann            final UserState userState;
6729dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann            synchronized (mLock) {
6739dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann                // Only the current group members can remove a print service recommendations
6749dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann                // listener.
6759dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann                if (resolveCallingProfileParentLocked(resolvedUserId) != getCurrentUserId()) {
6769dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann                    return;
6779dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann                }
6789dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann                userState = getOrCreateUserStateLocked(resolvedUserId, false);
6799dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann            }
6809dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann            final long identity = Binder.clearCallingIdentity();
6819dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann            try {
6829dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann                userState.removePrintServiceRecommendationsChangeListener(listener);
6839dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann            } finally {
6849dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann                Binder.restoreCallingIdentity(identity);
6859dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann            }
6869dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann        }
6879dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann
6889dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann        @Override
689817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani        public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
69076d7e3ee70c4299b22b1a03505d2b4f108716c75Philip P. Moltmann            fd = Preconditions.checkNotNull(fd);
69176d7e3ee70c4299b22b1a03505d2b4f108716c75Philip P. Moltmann
692fe9a53bc45fd0124a876dc0a49680aaf86641d3eJeff Sharkey            if (!DumpUtils.checkDumpPermission(mContext, LOG_TAG, pw)) return;
6934b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov
694c0a128dc2b3e7af35cb39d5157ca4de9147aa3c8Philip P. Moltmann            int opti = 0;
695c0a128dc2b3e7af35cb39d5157ca4de9147aa3c8Philip P. Moltmann            boolean dumpAsProto = false;
696c0a128dc2b3e7af35cb39d5157ca4de9147aa3c8Philip P. Moltmann            while (opti < args.length) {
697c0a128dc2b3e7af35cb39d5157ca4de9147aa3c8Philip P. Moltmann                String opt = args[opti];
698c0a128dc2b3e7af35cb39d5157ca4de9147aa3c8Philip P. Moltmann                if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
699c0a128dc2b3e7af35cb39d5157ca4de9147aa3c8Philip P. Moltmann                    break;
700c0a128dc2b3e7af35cb39d5157ca4de9147aa3c8Philip P. Moltmann                }
701c0a128dc2b3e7af35cb39d5157ca4de9147aa3c8Philip P. Moltmann                opti++;
702c0a128dc2b3e7af35cb39d5157ca4de9147aa3c8Philip P. Moltmann                if ("--proto".equals(opt)) {
703c0a128dc2b3e7af35cb39d5157ca4de9147aa3c8Philip P. Moltmann                    dumpAsProto = true;
704c0a128dc2b3e7af35cb39d5157ca4de9147aa3c8Philip P. Moltmann                } else {
705c0a128dc2b3e7af35cb39d5157ca4de9147aa3c8Philip P. Moltmann                    pw.println("Unknown argument: " + opt + "; use -h for help");
706c0a128dc2b3e7af35cb39d5157ca4de9147aa3c8Philip P. Moltmann                }
707c0a128dc2b3e7af35cb39d5157ca4de9147aa3c8Philip P. Moltmann            }
708c0a128dc2b3e7af35cb39d5157ca4de9147aa3c8Philip P. Moltmann
7094b89d63b63d936e7ec71eafab92f5810f55014efPhilip P. Moltmann            ArrayList<UserState> userStatesToDump = new ArrayList<>();
710817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            synchronized (mLock) {
7114b89d63b63d936e7ec71eafab92f5810f55014efPhilip P. Moltmann                int numUserStates = mUserStates.size();
7124b89d63b63d936e7ec71eafab92f5810f55014efPhilip P. Moltmann                for (int i = 0; i < numUserStates; i++) {
7134b89d63b63d936e7ec71eafab92f5810f55014efPhilip P. Moltmann                    userStatesToDump.add(mUserStates.valueAt(i));
7144b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov                }
7154b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov            }
7164b89d63b63d936e7ec71eafab92f5810f55014efPhilip P. Moltmann
7174b89d63b63d936e7ec71eafab92f5810f55014efPhilip P. Moltmann            final long identity = Binder.clearCallingIdentity();
7184b89d63b63d936e7ec71eafab92f5810f55014efPhilip P. Moltmann            try {
7194b89d63b63d936e7ec71eafab92f5810f55014efPhilip P. Moltmann                if (dumpAsProto) {
720371a3b879ba82bbe5a4d914328a20659131d0220Philip P. Moltmann                    dump(new DualDumpOutputStream(new ProtoOutputStream(fd)),
7219a534c01ecd4a1442856c1b709e23b61f1baf9baPhilip P. Moltmann                            userStatesToDump);
7224b89d63b63d936e7ec71eafab92f5810f55014efPhilip P. Moltmann                } else {
7239a534c01ecd4a1442856c1b709e23b61f1baf9baPhilip P. Moltmann                    pw.println("PRINT MANAGER STATE (dumpsys print)");
7249a534c01ecd4a1442856c1b709e23b61f1baf9baPhilip P. Moltmann
725371a3b879ba82bbe5a4d914328a20659131d0220Philip P. Moltmann                    dump(new DualDumpOutputStream(new IndentingPrintWriter(pw, "  ")),
7269a534c01ecd4a1442856c1b709e23b61f1baf9baPhilip P. Moltmann                            userStatesToDump);
7274b89d63b63d936e7ec71eafab92f5810f55014efPhilip P. Moltmann                }
7284b89d63b63d936e7ec71eafab92f5810f55014efPhilip P. Moltmann            } finally {
7294b89d63b63d936e7ec71eafab92f5810f55014efPhilip P. Moltmann                Binder.restoreCallingIdentity(identity);
7304b89d63b63d936e7ec71eafab92f5810f55014efPhilip P. Moltmann            }
731817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani        }
7324b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov
733b3baaab4af7e1ed8dfc5da1c976cc34d135fb82bPhilip P. Moltmann        @Override
734b3baaab4af7e1ed8dfc5da1c976cc34d135fb82bPhilip P. Moltmann        public boolean getBindInstantServiceAllowed(@UserIdInt int userId) {
735b3baaab4af7e1ed8dfc5da1c976cc34d135fb82bPhilip P. Moltmann            int callingUid = Binder.getCallingUid();
736b3baaab4af7e1ed8dfc5da1c976cc34d135fb82bPhilip P. Moltmann            if (callingUid != SHELL_UID && callingUid != ROOT_UID) {
737b3baaab4af7e1ed8dfc5da1c976cc34d135fb82bPhilip P. Moltmann                throw new SecurityException("Can only be called by uid " + SHELL_UID
738b3baaab4af7e1ed8dfc5da1c976cc34d135fb82bPhilip P. Moltmann                        + " or " + ROOT_UID);
739b3baaab4af7e1ed8dfc5da1c976cc34d135fb82bPhilip P. Moltmann            }
740b3baaab4af7e1ed8dfc5da1c976cc34d135fb82bPhilip P. Moltmann
741b3baaab4af7e1ed8dfc5da1c976cc34d135fb82bPhilip P. Moltmann            final UserState userState;
742b3baaab4af7e1ed8dfc5da1c976cc34d135fb82bPhilip P. Moltmann            synchronized (mLock) {
743b3baaab4af7e1ed8dfc5da1c976cc34d135fb82bPhilip P. Moltmann                userState = getOrCreateUserStateLocked(userId, false);
744b3baaab4af7e1ed8dfc5da1c976cc34d135fb82bPhilip P. Moltmann            }
745b3baaab4af7e1ed8dfc5da1c976cc34d135fb82bPhilip P. Moltmann            final long identity = Binder.clearCallingIdentity();
746b3baaab4af7e1ed8dfc5da1c976cc34d135fb82bPhilip P. Moltmann            try {
747b3baaab4af7e1ed8dfc5da1c976cc34d135fb82bPhilip P. Moltmann                return userState.getBindInstantServiceAllowed();
748b3baaab4af7e1ed8dfc5da1c976cc34d135fb82bPhilip P. Moltmann            } finally {
749b3baaab4af7e1ed8dfc5da1c976cc34d135fb82bPhilip P. Moltmann                Binder.restoreCallingIdentity(identity);
750b3baaab4af7e1ed8dfc5da1c976cc34d135fb82bPhilip P. Moltmann            }
751b3baaab4af7e1ed8dfc5da1c976cc34d135fb82bPhilip P. Moltmann        }
752b3baaab4af7e1ed8dfc5da1c976cc34d135fb82bPhilip P. Moltmann
753b3baaab4af7e1ed8dfc5da1c976cc34d135fb82bPhilip P. Moltmann        @Override
754b3baaab4af7e1ed8dfc5da1c976cc34d135fb82bPhilip P. Moltmann        public void setBindInstantServiceAllowed(@UserIdInt int userId, boolean allowed) {
755b3baaab4af7e1ed8dfc5da1c976cc34d135fb82bPhilip P. Moltmann            int callingUid = Binder.getCallingUid();
756b3baaab4af7e1ed8dfc5da1c976cc34d135fb82bPhilip P. Moltmann            if (callingUid != SHELL_UID && callingUid != ROOT_UID) {
757b3baaab4af7e1ed8dfc5da1c976cc34d135fb82bPhilip P. Moltmann                throw new SecurityException("Can only be called by uid " + SHELL_UID
758b3baaab4af7e1ed8dfc5da1c976cc34d135fb82bPhilip P. Moltmann                        + " or " + ROOT_UID);
759b3baaab4af7e1ed8dfc5da1c976cc34d135fb82bPhilip P. Moltmann            }
760b3baaab4af7e1ed8dfc5da1c976cc34d135fb82bPhilip P. Moltmann
761b3baaab4af7e1ed8dfc5da1c976cc34d135fb82bPhilip P. Moltmann            final UserState userState;
762b3baaab4af7e1ed8dfc5da1c976cc34d135fb82bPhilip P. Moltmann            synchronized (mLock) {
763b3baaab4af7e1ed8dfc5da1c976cc34d135fb82bPhilip P. Moltmann                userState = getOrCreateUserStateLocked(userId, false);
764b3baaab4af7e1ed8dfc5da1c976cc34d135fb82bPhilip P. Moltmann            }
765b3baaab4af7e1ed8dfc5da1c976cc34d135fb82bPhilip P. Moltmann            final long identity = Binder.clearCallingIdentity();
766b3baaab4af7e1ed8dfc5da1c976cc34d135fb82bPhilip P. Moltmann            try {
767b3baaab4af7e1ed8dfc5da1c976cc34d135fb82bPhilip P. Moltmann                userState.setBindInstantServiceAllowed(allowed);
768b3baaab4af7e1ed8dfc5da1c976cc34d135fb82bPhilip P. Moltmann            } finally {
769b3baaab4af7e1ed8dfc5da1c976cc34d135fb82bPhilip P. Moltmann                Binder.restoreCallingIdentity(identity);
770b3baaab4af7e1ed8dfc5da1c976cc34d135fb82bPhilip P. Moltmann            }
771b3baaab4af7e1ed8dfc5da1c976cc34d135fb82bPhilip P. Moltmann        }
772b3baaab4af7e1ed8dfc5da1c976cc34d135fb82bPhilip P. Moltmann
773792d58fbcef3da36dbde5fd8b0cf5a5b972bd12eVladislav Kuzkokov        private boolean isPrintingEnabled() {
774bc630497b490de679b6856801521dc4a36416325Vladislav Kuzkokov            return !mUserManager.hasUserRestriction(UserManager.DISALLOW_PRINTING,
775bc630497b490de679b6856801521dc4a36416325Vladislav Kuzkokov                    Binder.getCallingUserHandle());
776792d58fbcef3da36dbde5fd8b0cf5a5b972bd12eVladislav Kuzkokov        }
777792d58fbcef3da36dbde5fd8b0cf5a5b972bd12eVladislav Kuzkokov
778bd62e9ae145c638845e41286156eca6e2d44a8eaPhilip P. Moltmann        private void dump(@NonNull DualDumpOutputStream dumpStream,
7794b89d63b63d936e7ec71eafab92f5810f55014efPhilip P. Moltmann                @NonNull ArrayList<UserState> userStatesToDump) {
7804b89d63b63d936e7ec71eafab92f5810f55014efPhilip P. Moltmann            final int userStateCount = userStatesToDump.size();
781c0a128dc2b3e7af35cb39d5157ca4de9147aa3c8Philip P. Moltmann            for (int i = 0; i < userStateCount; i++) {
782bd62e9ae145c638845e41286156eca6e2d44a8eaPhilip P. Moltmann                long token = dumpStream.start("user_states", PrintServiceDumpProto.USER_STATES);
783bd62e9ae145c638845e41286156eca6e2d44a8eaPhilip P. Moltmann                userStatesToDump.get(i).dump(dumpStream);
784bd62e9ae145c638845e41286156eca6e2d44a8eaPhilip P. Moltmann                dumpStream.end(token);
785c0a128dc2b3e7af35cb39d5157ca4de9147aa3c8Philip P. Moltmann            }
786c0a128dc2b3e7af35cb39d5157ca4de9147aa3c8Philip P. Moltmann
787bd62e9ae145c638845e41286156eca6e2d44a8eaPhilip P. Moltmann            dumpStream.flush();
788c0a128dc2b3e7af35cb39d5157ca4de9147aa3c8Philip P. Moltmann        }
789c0a128dc2b3e7af35cb39d5157ca4de9147aa3c8Philip P. Moltmann
790817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani        private void registerContentObservers() {
791817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            final Uri enabledPrintServicesUri = Settings.Secure.getUriFor(
7928141bdfa56f13c3946bed12ba7801e492ec25c11Philip P. Moltmann                    Settings.Secure.DISABLED_PRINT_SERVICES);
793817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            ContentObserver observer = new ContentObserver(BackgroundThread.getHandler()) {
794817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani                @Override
79586b1df234397802895771fe14cd8f2813fa43415Svetoslav                public void onChange(boolean selfChange, Uri uri, int userId) {
796817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani                    if (enabledPrintServicesUri.equals(uri)) {
797817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani                        synchronized (mLock) {
7980999c0d6e9c83873d9595ee764b6388dbc49dcb8Jeff Sharkey                            final int userCount = mUserStates.size();
7990999c0d6e9c83873d9595ee764b6388dbc49dcb8Jeff Sharkey                            for (int i = 0; i < userCount; i++) {
8000999c0d6e9c83873d9595ee764b6388dbc49dcb8Jeff Sharkey                                if (userId == UserHandle.USER_ALL
8010999c0d6e9c83873d9595ee764b6388dbc49dcb8Jeff Sharkey                                        || userId == mUserStates.keyAt(i)) {
8020999c0d6e9c83873d9595ee764b6388dbc49dcb8Jeff Sharkey                                    mUserStates.valueAt(i).updateIfNeededLocked();
80386b1df234397802895771fe14cd8f2813fa43415Svetoslav                                }
80486b1df234397802895771fe14cd8f2813fa43415Svetoslav                            }
805a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov                        }
8064b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov                    }
8074b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov                }
808817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            };
8094b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov
810817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            mContext.getContentResolver().registerContentObserver(enabledPrintServicesUri,
811817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani                    false, observer, UserHandle.USER_ALL);
812817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani        }
813817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani
81404533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav        private void registerBroadcastReceivers() {
815817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            PackageMonitor monitor = new PackageMonitor() {
816852c950bbfbfb10c6e05dc62dd2e662980238a46Philip P. Moltmann                /**
817852c950bbfbfb10c6e05dc62dd2e662980238a46Philip P. Moltmann                 * Checks if the package contains a print service.
818852c950bbfbfb10c6e05dc62dd2e662980238a46Philip P. Moltmann                 *
819852c950bbfbfb10c6e05dc62dd2e662980238a46Philip P. Moltmann                 * @param packageName The name of the package
820852c950bbfbfb10c6e05dc62dd2e662980238a46Philip P. Moltmann                 *
821852c950bbfbfb10c6e05dc62dd2e662980238a46Philip P. Moltmann                 * @return true iff the package contains a print service
822852c950bbfbfb10c6e05dc62dd2e662980238a46Philip P. Moltmann                 */
823852c950bbfbfb10c6e05dc62dd2e662980238a46Philip P. Moltmann                private boolean hasPrintService(String packageName) {
824852c950bbfbfb10c6e05dc62dd2e662980238a46Philip P. Moltmann                    Intent intent = new Intent(android.printservice.PrintService.SERVICE_INTERFACE);
825852c950bbfbfb10c6e05dc62dd2e662980238a46Philip P. Moltmann                    intent.setPackage(packageName);
8268141bdfa56f13c3946bed12ba7801e492ec25c11Philip P. Moltmann
827852c950bbfbfb10c6e05dc62dd2e662980238a46Philip P. Moltmann                    List<ResolveInfo> installedServices = mContext.getPackageManager()
828852c950bbfbfb10c6e05dc62dd2e662980238a46Philip P. Moltmann                            .queryIntentServicesAsUser(intent,
829b3baaab4af7e1ed8dfc5da1c976cc34d135fb82bPhilip P. Moltmann                                    GET_SERVICES | MATCH_DEBUG_TRIAGED_MISSING | MATCH_INSTANT,
830852c950bbfbfb10c6e05dc62dd2e662980238a46Philip P. Moltmann                                    getChangingUserId());
831852c950bbfbfb10c6e05dc62dd2e662980238a46Philip P. Moltmann
832852c950bbfbfb10c6e05dc62dd2e662980238a46Philip P. Moltmann                    return installedServices != null && !installedServices.isEmpty();
833852c950bbfbfb10c6e05dc62dd2e662980238a46Philip P. Moltmann                }
834852c950bbfbfb10c6e05dc62dd2e662980238a46Philip P. Moltmann
835852c950bbfbfb10c6e05dc62dd2e662980238a46Philip P. Moltmann                /**
836852c950bbfbfb10c6e05dc62dd2e662980238a46Philip P. Moltmann                 * Checks if there is a print service currently registered for this package.
837852c950bbfbfb10c6e05dc62dd2e662980238a46Philip P. Moltmann                 *
838852c950bbfbfb10c6e05dc62dd2e662980238a46Philip P. Moltmann                 * @param userState The userstate for the current user
839852c950bbfbfb10c6e05dc62dd2e662980238a46Philip P. Moltmann                 * @param packageName The name of the package
840852c950bbfbfb10c6e05dc62dd2e662980238a46Philip P. Moltmann                 *
841852c950bbfbfb10c6e05dc62dd2e662980238a46Philip P. Moltmann                 * @return true iff the package contained (and might still contain) a print service
842852c950bbfbfb10c6e05dc62dd2e662980238a46Philip P. Moltmann                 */
843852c950bbfbfb10c6e05dc62dd2e662980238a46Philip P. Moltmann                private boolean hadPrintService(@NonNull UserState userState, String packageName) {
844852c950bbfbfb10c6e05dc62dd2e662980238a46Philip P. Moltmann                    List<PrintServiceInfo> installedServices = userState
845852c950bbfbfb10c6e05dc62dd2e662980238a46Philip P. Moltmann                            .getPrintServices(PrintManager.ALL_SERVICES);
846852c950bbfbfb10c6e05dc62dd2e662980238a46Philip P. Moltmann
847852c950bbfbfb10c6e05dc62dd2e662980238a46Philip P. Moltmann                    if (installedServices == null) {
848852c950bbfbfb10c6e05dc62dd2e662980238a46Philip P. Moltmann                        return false;
849852c950bbfbfb10c6e05dc62dd2e662980238a46Philip P. Moltmann                    }
850852c950bbfbfb10c6e05dc62dd2e662980238a46Philip P. Moltmann
851852c950bbfbfb10c6e05dc62dd2e662980238a46Philip P. Moltmann                    final int numInstalledServices = installedServices.size();
852852c950bbfbfb10c6e05dc62dd2e662980238a46Philip P. Moltmann                    for (int i = 0; i < numInstalledServices; i++) {
853852c950bbfbfb10c6e05dc62dd2e662980238a46Philip P. Moltmann                        if (installedServices.get(i).getResolveInfo().serviceInfo.packageName
854852c950bbfbfb10c6e05dc62dd2e662980238a46Philip P. Moltmann                                .equals(packageName)) {
855852c950bbfbfb10c6e05dc62dd2e662980238a46Philip P. Moltmann                            return true;
8564b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov                        }
8574b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov                    }
858852c950bbfbfb10c6e05dc62dd2e662980238a46Philip P. Moltmann
859852c950bbfbfb10c6e05dc62dd2e662980238a46Philip P. Moltmann                    return false;
8604b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov                }
8614b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov
862817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani                @Override
8638141bdfa56f13c3946bed12ba7801e492ec25c11Philip P. Moltmann                public void onPackageModified(String packageName) {
864ce18c8167766f92856f94a8e88e19de4698960e6Jeff Sharkey                    if (!mUserManager.isUserUnlockingOrUnlocked(getChangingUserId())) return;
865e5d91213d05f192201bdbe03860efa161850fccbFyodor Kupolov                    UserState userState = getOrCreateUserStateLocked(getChangingUserId(), false,
866e5d91213d05f192201bdbe03860efa161850fccbFyodor Kupolov                            false /* enforceUserUnlockingOrUnlocked */);
867852c950bbfbfb10c6e05dc62dd2e662980238a46Philip P. Moltmann
868973d8af11b11da273d54f289217c04ce39bf9200Narayan Kamath                    boolean prunePrintServices = false;
869852c950bbfbfb10c6e05dc62dd2e662980238a46Philip P. Moltmann                    synchronized (mLock) {
870852c950bbfbfb10c6e05dc62dd2e662980238a46Philip P. Moltmann                        if (hadPrintService(userState, packageName)
871852c950bbfbfb10c6e05dc62dd2e662980238a46Philip P. Moltmann                                || hasPrintService(packageName)) {
872852c950bbfbfb10c6e05dc62dd2e662980238a46Philip P. Moltmann                            userState.updateIfNeededLocked();
873973d8af11b11da273d54f289217c04ce39bf9200Narayan Kamath                            prunePrintServices = true;
874852c950bbfbfb10c6e05dc62dd2e662980238a46Philip P. Moltmann                        }
875852c950bbfbfb10c6e05dc62dd2e662980238a46Philip P. Moltmann                    }
876852c950bbfbfb10c6e05dc62dd2e662980238a46Philip P. Moltmann
877973d8af11b11da273d54f289217c04ce39bf9200Narayan Kamath                    if (prunePrintServices) {
878973d8af11b11da273d54f289217c04ce39bf9200Narayan Kamath                        userState.prunePrintServices();
879973d8af11b11da273d54f289217c04ce39bf9200Narayan Kamath                    }
8808141bdfa56f13c3946bed12ba7801e492ec25c11Philip P. Moltmann                }
8818141bdfa56f13c3946bed12ba7801e492ec25c11Philip P. Moltmann
8828141bdfa56f13c3946bed12ba7801e492ec25c11Philip P. Moltmann                @Override
883817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani                public void onPackageRemoved(String packageName, int uid) {
884ce18c8167766f92856f94a8e88e19de4698960e6Jeff Sharkey                    if (!mUserManager.isUserUnlockingOrUnlocked(getChangingUserId())) return;
885e5d91213d05f192201bdbe03860efa161850fccbFyodor Kupolov                    UserState userState = getOrCreateUserStateLocked(getChangingUserId(), false,
886e5d91213d05f192201bdbe03860efa161850fccbFyodor Kupolov                            false /* enforceUserUnlockingOrUnlocked */);
887852c950bbfbfb10c6e05dc62dd2e662980238a46Philip P. Moltmann
888973d8af11b11da273d54f289217c04ce39bf9200Narayan Kamath                    boolean prunePrintServices = false;
889852c950bbfbfb10c6e05dc62dd2e662980238a46Philip P. Moltmann                    synchronized (mLock) {
890852c950bbfbfb10c6e05dc62dd2e662980238a46Philip P. Moltmann                        if (hadPrintService(userState, packageName)) {
891852c950bbfbfb10c6e05dc62dd2e662980238a46Philip P. Moltmann                            userState.updateIfNeededLocked();
892973d8af11b11da273d54f289217c04ce39bf9200Narayan Kamath                            prunePrintServices = true;
893852c950bbfbfb10c6e05dc62dd2e662980238a46Philip P. Moltmann                        }
894852c950bbfbfb10c6e05dc62dd2e662980238a46Philip P. Moltmann                    }
895852c950bbfbfb10c6e05dc62dd2e662980238a46Philip P. Moltmann
896973d8af11b11da273d54f289217c04ce39bf9200Narayan Kamath                    if (prunePrintServices) {
897973d8af11b11da273d54f289217c04ce39bf9200Narayan Kamath                        userState.prunePrintServices();
898973d8af11b11da273d54f289217c04ce39bf9200Narayan Kamath                    }
8994b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov                }
9004b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov
901817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani                @Override
902817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani                public boolean onHandleForceStop(Intent intent, String[] stoppedPackages,
903817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani                        int uid, boolean doit) {
904ce18c8167766f92856f94a8e88e19de4698960e6Jeff Sharkey                    if (!mUserManager.isUserUnlockingOrUnlocked(getChangingUserId())) return false;
905817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani                    synchronized (mLock) {
90604533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav                        // A background user/profile's print jobs are running but there is
90704533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav                        // no UI shown. Hence, if the packages of such a user change we need
90804533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav                        // to handle it as the change may affect ongoing print jobs.
909e5d91213d05f192201bdbe03860efa161850fccbFyodor Kupolov                        UserState userState = getOrCreateUserStateLocked(getChangingUserId(), false,
910e5d91213d05f192201bdbe03860efa161850fccbFyodor Kupolov                                false /* enforceUserUnlockingOrUnlocked */);
911817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani                        boolean stoppedSomePackages = false;
91205e34230709282f21d0df21b4bd69f6a4c5cf580Philip P. Moltmann
91305e34230709282f21d0df21b4bd69f6a4c5cf580Philip P. Moltmann                        List<PrintServiceInfo> enabledServices = userState
91466c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann                                .getPrintServices(PrintManager.ENABLED_SERVICES);
91505e34230709282f21d0df21b4bd69f6a4c5cf580Philip P. Moltmann                        if (enabledServices == null) {
91605e34230709282f21d0df21b4bd69f6a4c5cf580Philip P. Moltmann                            return false;
91705e34230709282f21d0df21b4bd69f6a4c5cf580Philip P. Moltmann                        }
91805e34230709282f21d0df21b4bd69f6a4c5cf580Philip P. Moltmann
91905e34230709282f21d0df21b4bd69f6a4c5cf580Philip P. Moltmann                        Iterator<PrintServiceInfo> iterator = enabledServices.iterator();
920817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani                        while (iterator.hasNext()) {
9218141bdfa56f13c3946bed12ba7801e492ec25c11Philip P. Moltmann                            ComponentName componentName = iterator.next().getComponentName();
922817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani                            String componentPackage = componentName.getPackageName();
923817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani                            for (String stoppedPackage : stoppedPackages) {
924817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani                                if (componentPackage.equals(stoppedPackage)) {
925817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani                                    if (!doit) {
926817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani                                        return true;
927817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani                                    }
928817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani                                    stoppedSomePackages = true;
929817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani                                    break;
9304b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov                                }
9314b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov                            }
9324b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov                        }
933817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani                        if (stoppedSomePackages) {
934817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani                            userState.updateIfNeededLocked();
935817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani                        }
936817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani                        return false;
9374b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov                    }
9384b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov                }
9394b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov
940817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani                @Override
941817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani                public void onPackageAdded(String packageName, int uid) {
942ce18c8167766f92856f94a8e88e19de4698960e6Jeff Sharkey                    if (!mUserManager.isUserUnlockingOrUnlocked(getChangingUserId())) return;
943852c950bbfbfb10c6e05dc62dd2e662980238a46Philip P. Moltmann                    synchronized (mLock) {
944852c950bbfbfb10c6e05dc62dd2e662980238a46Philip P. Moltmann                        if (hasPrintService(packageName)) {
945e8ae15482eef7617494cb3187899983e27cb8a35Philip P. Moltmann                            UserState userState = getOrCreateUserStateLocked(getChangingUserId(),
946e5d91213d05f192201bdbe03860efa161850fccbFyodor Kupolov                                    false, false /* enforceUserUnlockingOrUnlocked */);
947852c950bbfbfb10c6e05dc62dd2e662980238a46Philip P. Moltmann                            userState.updateIfNeededLocked();
948852c950bbfbfb10c6e05dc62dd2e662980238a46Philip P. Moltmann                        }
949a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov                    }
950a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov                }
951817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            };
952817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani
953817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            // package changes
954817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            monitor.register(mContext, BackgroundThread.getHandler().getLooper(),
955817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani                    UserHandle.ALL, true);
9564b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov        }
957e8ae15482eef7617494cb3187899983e27cb8a35Philip P. Moltmann        private UserState getOrCreateUserStateLocked(int userId, boolean lowPriority) {
958e5d91213d05f192201bdbe03860efa161850fccbFyodor Kupolov            return getOrCreateUserStateLocked(userId, lowPriority,
959e5d91213d05f192201bdbe03860efa161850fccbFyodor Kupolov                    true /* enforceUserUnlockingOrUnlocked */);
960e5d91213d05f192201bdbe03860efa161850fccbFyodor Kupolov        }
961e5d91213d05f192201bdbe03860efa161850fccbFyodor Kupolov
962e5d91213d05f192201bdbe03860efa161850fccbFyodor Kupolov        private UserState getOrCreateUserStateLocked(int userId, boolean lowPriority,
963e5d91213d05f192201bdbe03860efa161850fccbFyodor Kupolov                boolean enforceUserUnlockingOrUnlocked) {
964e5d91213d05f192201bdbe03860efa161850fccbFyodor Kupolov            if (enforceUserUnlockingOrUnlocked && !mUserManager.isUserUnlockingOrUnlocked(userId)) {
9650999c0d6e9c83873d9595ee764b6388dbc49dcb8Jeff Sharkey                throw new IllegalStateException(
9660999c0d6e9c83873d9595ee764b6388dbc49dcb8Jeff Sharkey                        "User " + userId + " must be unlocked for printing to be available");
9670999c0d6e9c83873d9595ee764b6388dbc49dcb8Jeff Sharkey            }
9680999c0d6e9c83873d9595ee764b6388dbc49dcb8Jeff Sharkey
969817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            UserState userState = mUserStates.get(userId);
9702fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav            if (userState == null) {
971e8ae15482eef7617494cb3187899983e27cb8a35Philip P. Moltmann                userState = new UserState(mContext, userId, mLock, lowPriority);
972817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani                mUserStates.put(userId, userState);
9732fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav            }
974e8ae15482eef7617494cb3187899983e27cb8a35Philip P. Moltmann
975e8ae15482eef7617494cb3187899983e27cb8a35Philip P. Moltmann            if (!lowPriority) {
976e8ae15482eef7617494cb3187899983e27cb8a35Philip P. Moltmann                userState.increasePriority();
977e8ae15482eef7617494cb3187899983e27cb8a35Philip P. Moltmann            }
978e8ae15482eef7617494cb3187899983e27cb8a35Philip P. Moltmann
979817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            return userState;
9804b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov        }
9814b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov
9820999c0d6e9c83873d9595ee764b6388dbc49dcb8Jeff Sharkey        private void handleUserUnlocked(final int userId) {
983c82768ff4b045b5b4edc08405964d504438a681fSvetoslav            // This code will touch the remote print spooler which
984c82768ff4b045b5b4edc08405964d504438a681fSvetoslav            // must be called off the main thread, so post the work.
985c82768ff4b045b5b4edc08405964d504438a681fSvetoslav            BackgroundThread.getHandler().post(new Runnable() {
986c82768ff4b045b5b4edc08405964d504438a681fSvetoslav                @Override
987c82768ff4b045b5b4edc08405964d504438a681fSvetoslav                public void run() {
988efb1950263b70dc3b7a6cd163bba1f38df54c15cPhilip P. Moltmann                    if (!mUserManager.isUserUnlockingOrUnlocked(userId)) return;
989efb1950263b70dc3b7a6cd163bba1f38df54c15cPhilip P. Moltmann
990c82768ff4b045b5b4edc08405964d504438a681fSvetoslav                    UserState userState;
991c82768ff4b045b5b4edc08405964d504438a681fSvetoslav                    synchronized (mLock) {
992e5d91213d05f192201bdbe03860efa161850fccbFyodor Kupolov                        userState = getOrCreateUserStateLocked(userId, true,
993e5d91213d05f192201bdbe03860efa161850fccbFyodor Kupolov                                false /*enforceUserUnlockingOrUnlocked */);
994c82768ff4b045b5b4edc08405964d504438a681fSvetoslav                        userState.updateIfNeededLocked();
995c82768ff4b045b5b4edc08405964d504438a681fSvetoslav                    }
996c82768ff4b045b5b4edc08405964d504438a681fSvetoslav                    // This is the first time we switch to this user after boot, so
997c82768ff4b045b5b4edc08405964d504438a681fSvetoslav                    // now is the time to remove obsolete print jobs since they
998c82768ff4b045b5b4edc08405964d504438a681fSvetoslav                    // are from the last boot and no application would query them.
999c82768ff4b045b5b4edc08405964d504438a681fSvetoslav                    userState.removeObsoletePrintJobs();
1000c82768ff4b045b5b4edc08405964d504438a681fSvetoslav                }
1001c82768ff4b045b5b4edc08405964d504438a681fSvetoslav            });
1002817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani        }
1003817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani
1004c82768ff4b045b5b4edc08405964d504438a681fSvetoslav        private void handleUserStopped(final int userId) {
1005c82768ff4b045b5b4edc08405964d504438a681fSvetoslav            // This code will touch the remote print spooler which
1006c82768ff4b045b5b4edc08405964d504438a681fSvetoslav            // must be called off the main thread, so post the work.
1007c82768ff4b045b5b4edc08405964d504438a681fSvetoslav            BackgroundThread.getHandler().post(new Runnable() {
1008c82768ff4b045b5b4edc08405964d504438a681fSvetoslav                @Override
1009c82768ff4b045b5b4edc08405964d504438a681fSvetoslav                public void run() {
1010c82768ff4b045b5b4edc08405964d504438a681fSvetoslav                    synchronized (mLock) {
1011c82768ff4b045b5b4edc08405964d504438a681fSvetoslav                        UserState userState = mUserStates.get(userId);
1012c82768ff4b045b5b4edc08405964d504438a681fSvetoslav                        if (userState != null) {
1013c82768ff4b045b5b4edc08405964d504438a681fSvetoslav                            userState.destroyLocked();
1014c82768ff4b045b5b4edc08405964d504438a681fSvetoslav                            mUserStates.remove(userId);
1015c82768ff4b045b5b4edc08405964d504438a681fSvetoslav                        }
1016c82768ff4b045b5b4edc08405964d504438a681fSvetoslav                    }
1017817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani                }
1018c82768ff4b045b5b4edc08405964d504438a681fSvetoslav            });
10194b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov        }
1020a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov
102104533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav        private int resolveCallingProfileParentLocked(int userId) {
102286b1df234397802895771fe14cd8f2813fa43415Svetoslav            if (userId != getCurrentUserId()) {
102304533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav                final long identity = Binder.clearCallingIdentity();
102404533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav                try {
102504533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav                    UserInfo parent = mUserManager.getProfileParent(userId);
102604533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav                    if (parent != null) {
102704533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav                        return parent.getUserHandle().getIdentifier();
102804533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav                    } else {
102904533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav                        return BACKGROUND_USER_ID;
103004533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav                    }
103104533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav                } finally {
103204533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav                    Binder.restoreCallingIdentity(identity);
103304533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav                }
103404533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav            }
103504533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav            return userId;
103604533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav        }
103704533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav
1038817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani        private int resolveCallingAppEnforcingPermissions(int appId) {
1039817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            final int callingUid = Binder.getCallingUid();
10406870033d374a15fd212675d570a2877c28f1cbf0Philip P. Moltmann            if (callingUid == 0) {
1041817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani                return appId;
1042817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            }
1043817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            final int callingAppId = UserHandle.getAppId(callingUid);
1044b3baaab4af7e1ed8dfc5da1c976cc34d135fb82bPhilip P. Moltmann            if (appId == callingAppId || callingAppId == SHELL_UID
10456870033d374a15fd212675d570a2877c28f1cbf0Philip P. Moltmann                    || callingAppId == Process.SYSTEM_UID) {
1046817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani                return appId;
1047817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            }
1048817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            if (mContext.checkCallingPermission(
1049817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani                    "com.android.printspooler.permission.ACCESS_ALL_PRINT_JOBS")
1050817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani                    != PackageManager.PERMISSION_GRANTED) {
1051817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani                throw new SecurityException("Call from app " + callingAppId + " as app "
1052817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani                        + appId + " without com.android.printspooler.permission"
1053817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani                        + ".ACCESS_ALL_PRINT_JOBS");
1054817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            }
1055a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov            return appId;
1056a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        }
10574b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov
1058817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani        private int resolveCallingUserEnforcingPermissions(int userId) {
105986b1df234397802895771fe14cd8f2813fa43415Svetoslav            try {
1060dc589ac82b5fe2063f4cfd94c8ae26d43d5420a0Sudheer Shanka                return ActivityManager.getService().handleIncomingUser(Binder.getCallingPid(),
106186b1df234397802895771fe14cd8f2813fa43415Svetoslav                        Binder.getCallingUid(), userId, true, true, "", null);
106286b1df234397802895771fe14cd8f2813fa43415Svetoslav            } catch (RemoteException re) {
106386b1df234397802895771fe14cd8f2813fa43415Svetoslav                // Shouldn't happen, local.
1064817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            }
1065194db6ad91c4aee995930ea8f04ea877730234fdSvet Ganov            return userId;
10664b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov        }
1067d8f391b4e0e8d876ec7216d34f86a9b3e8bab7e5Svetoslav
106876d7e3ee70c4299b22b1a03505d2b4f108716c75Philip P. Moltmann        private @NonNull String resolveCallingPackageNameEnforcingSecurity(
106976d7e3ee70c4299b22b1a03505d2b4f108716c75Philip P. Moltmann                @NonNull String packageName) {
1070817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            String[] packages = mContext.getPackageManager().getPackagesForUid(
1071817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani                    Binder.getCallingUid());
1072817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            final int packageCount = packages.length;
1073817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani            for (int i = 0; i < packageCount; i++) {
1074817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani                if (packageName.equals(packages[i])) {
1075817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani                    return packageName;
1076817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani                }
10777bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav            }
107876d7e3ee70c4299b22b1a03505d2b4f108716c75Philip P. Moltmann            throw new IllegalArgumentException("packageName has to belong to the caller");
10797bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav        }
10807bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav
108186b1df234397802895771fe14cd8f2813fa43415Svetoslav        private int getCurrentUserId () {
108286b1df234397802895771fe14cd8f2813fa43415Svetoslav            final long identity = Binder.clearCallingIdentity();
108386b1df234397802895771fe14cd8f2813fa43415Svetoslav            try {
108486b1df234397802895771fe14cd8f2813fa43415Svetoslav                return ActivityManager.getCurrentUser();
108586b1df234397802895771fe14cd8f2813fa43415Svetoslav            } finally {
108686b1df234397802895771fe14cd8f2813fa43415Svetoslav                Binder.restoreCallingIdentity(identity);
108786b1df234397802895771fe14cd8f2813fa43415Svetoslav            }
108886b1df234397802895771fe14cd8f2813fa43415Svetoslav        }
1089d8f391b4e0e8d876ec7216d34f86a9b3e8bab7e5Svetoslav    }
10904b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov}
1091