1/*
2 * Copyright (C) 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.tv.settings.device.apps;
18
19import android.app.Activity;
20import android.app.ActivityManager;
21import android.app.admin.DevicePolicyManager;
22import android.content.BroadcastReceiver;
23import android.content.Context;
24import android.content.Intent;
25import android.content.pm.ApplicationInfo;
26import android.net.Uri;
27import android.os.UserHandle;
28
29/**
30 * Handles force stopping an application.
31 */
32class ForceStopManager {
33
34    private final Context mContext;
35    private AppInfo mAppInfo;
36    private boolean mShowForceStop;
37
38    ForceStopManager(Context context, AppInfo appInfo) {
39        mContext = context;
40        mAppInfo = appInfo;
41        mShowForceStop = false;
42    }
43
44    boolean canForceStop() {
45        checkForceStop();
46        return mShowForceStop;
47    }
48
49    void forceStop(ApplicationsState state) {
50        ActivityManager am = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
51        am.forceStopPackage(mAppInfo.getPackageName());
52        state.invalidatePackage(mAppInfo.getPackageName());
53        ApplicationsState.AppEntry newEnt = state.getEntry(mAppInfo.getPackageName());
54        if (newEnt != null) {
55            mAppInfo.setEntry(newEnt);
56        }
57    }
58
59    private void checkForceStop() {
60        DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
61                Context.DEVICE_POLICY_SERVICE);
62        if (dpm.packageHasActiveAdmins(mAppInfo.getPackageName())) {
63            // User can't force stop device admin.
64            mShowForceStop = false;
65        } else if (!mAppInfo.isStopped()) {
66            // If the app isn't explicitly stopped, then always show the
67            // force stop action.
68            mShowForceStop = true;
69        } else {
70            Intent intent = new Intent(Intent.ACTION_QUERY_PACKAGE_RESTART,
71                    Uri.fromParts("package", mAppInfo.getPackageName(), null));
72            intent.putExtra(Intent.EXTRA_PACKAGES, new String[] {
73            mAppInfo.getPackageName() });
74            intent.putExtra(Intent.EXTRA_UID, mAppInfo.getUid());
75            intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(mAppInfo.getUid()));
76            mContext.sendOrderedBroadcast(intent, null, new BroadcastReceiver() {
77                @Override
78                public void onReceive(Context context, Intent intent) {
79                    mShowForceStop = (getResultCode() != Activity.RESULT_CANCELED);
80                }
81            }, null, Activity.RESULT_CANCELED, null, null);
82        }
83    }
84}
85