UnlaunchableAppActivity.java revision 945fd0074a631722e10c63c0006bfd10729ca8a0
1/*
2 * Copyright (C) 2016 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.internal.app;
18
19import static android.content.Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS;
20import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
21
22import android.app.Activity;
23import android.app.AlertDialog;
24import android.app.admin.DevicePolicyManager;
25import android.content.ComponentName;
26import android.content.Context;
27import android.content.DialogInterface;
28import android.content.Intent;
29import android.content.pm.ApplicationInfo;
30import android.content.pm.PackageManager;
31import android.content.pm.PackageManager.NameNotFoundException;
32import android.os.Bundle;
33import android.os.UserHandle;
34import android.os.UserManager;
35import android.text.TextUtils;
36import android.util.Log;
37import android.view.LayoutInflater;
38import android.view.View;
39import android.widget.TextView;
40
41import com.android.internal.R;
42
43/**
44 * A dialog shown to the user when they try to launch an app from a quiet profile
45 * ({@link UserManager#isQuietModeEnabled(UserHandle)}, or when the app is suspended by the
46 * profile owner or device owner.
47 */
48public class UnlaunchableAppActivity extends Activity
49        implements DialogInterface.OnDismissListener, DialogInterface.OnClickListener {
50    private static final String TAG = "UnlaunchableAppActivity";
51
52    private static final int UNLAUNCHABLE_REASON_QUIET_MODE = 1;
53    private static final int UNLAUNCHABLE_REASON_SUSPENDED_PACKAGE = 2;
54    private static final String EXTRA_UNLAUNCHABLE_REASON = "unlaunchable_reason";
55
56    private int mUserId;
57    private int mReason;
58
59    @Override
60    protected void onCreate(Bundle savedInstanceState) {
61        super.onCreate(savedInstanceState);
62        Intent intent = getIntent();
63        mReason = intent.getIntExtra(EXTRA_UNLAUNCHABLE_REASON, -1);
64        mUserId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
65
66        if (mUserId == UserHandle.USER_NULL) {
67            Log.wtf(TAG, "Invalid user id: " + mUserId + ". Stopping.");
68            finish();
69            return;
70        }
71
72        String dialogTitle;
73        String dialogMessage = null;
74        if (mReason == UNLAUNCHABLE_REASON_QUIET_MODE) {
75            dialogTitle = getResources().getString(R.string.work_mode_off_title);
76            dialogMessage = getResources().getString(R.string.work_mode_off_message);
77        } else if (mReason == UNLAUNCHABLE_REASON_SUSPENDED_PACKAGE) {
78            DevicePolicyManager dpm = (DevicePolicyManager) getSystemService(
79                    Context.DEVICE_POLICY_SERVICE);
80            String packageName = intent.getStringExtra(Intent.EXTRA_PACKAGE_NAME);
81            String packageLabel = packageName;
82            try {
83                Context userContext = createPackageContextAsUser(packageName, 0,
84                        UserHandle.of(mUserId));
85                ApplicationInfo appInfo = userContext.getApplicationInfo();
86                if (appInfo != null) {
87                    packageLabel = userContext.getPackageManager().getApplicationLabel(appInfo)
88                            .toString();
89                }
90            } catch (NameNotFoundException e) {
91            }
92            dialogTitle = String.format(getResources().getString(R.string.suspended_package_title),
93                    packageLabel);
94            ComponentName profileOwner = dpm.getProfileOwnerAsUser(mUserId);
95            String profileOwnerName = null;
96            if (profileOwner != null) {
97                dialogMessage = dpm.getShortSupportMessageForUser(profileOwner, mUserId);
98                profileOwnerName = dpm.getProfileOwnerNameAsUser(mUserId);
99            }
100            // Fall back to standard message if profile owner hasn't set something specific.
101            if (TextUtils.isEmpty(dialogMessage)) {
102                if (TextUtils.isEmpty(profileOwnerName)) {
103                    profileOwnerName = getResources().getString(R.string.unknownName);
104                }
105                dialogMessage = getResources().getString(R.string.suspended_package_message,
106                        profileOwnerName);
107            }
108        } else {
109            Log.wtf(TAG, "Invalid unlaunchable type: " + mReason);
110            finish();
111            return;
112        }
113
114        View rootView = LayoutInflater.from(this).inflate(R.layout.unlaunchable_app_activity, null);
115        TextView titleView = (TextView)rootView.findViewById(R.id.unlaunchable_app_title);
116        TextView messageView = (TextView)rootView.findViewById(R.id.unlaunchable_app_message);
117        titleView.setText(dialogTitle);
118        messageView.setText(dialogMessage);
119
120        AlertDialog.Builder builder = new AlertDialog.Builder(this)
121                .setView(rootView)
122                .setOnDismissListener(this);
123        if (mReason == UNLAUNCHABLE_REASON_QUIET_MODE) {
124            builder.setPositiveButton(R.string.work_mode_turn_on, this)
125                    .setNegativeButton(R.string.cancel, null);
126        } else {
127            builder.setPositiveButton(R.string.ok, null);
128        }
129        builder.show();
130    }
131
132    @Override
133    public void onDismiss(DialogInterface dialog) {
134        finish();
135    }
136
137    @Override
138    public void onClick(DialogInterface dialog, int which) {
139        if (mReason == UNLAUNCHABLE_REASON_QUIET_MODE && which == DialogInterface.BUTTON_POSITIVE) {
140            UserManager.get(this).setQuietModeEnabled(mUserId, false);
141        }
142    }
143
144    private static final Intent createBaseIntent() {
145        Intent intent = new Intent();
146        intent.setComponent(new ComponentName("android", UnlaunchableAppActivity.class.getName()));
147        intent.setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
148        return intent;
149    }
150
151    public static Intent createInQuietModeDialogIntent(int userId) {
152        Intent intent = createBaseIntent();
153        intent.putExtra(EXTRA_UNLAUNCHABLE_REASON, UNLAUNCHABLE_REASON_QUIET_MODE);
154        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
155        return intent;
156    }
157
158    public static Intent createPackageSuspendedDialogIntent(String packageName, int userId) {
159        Intent intent = createBaseIntent();
160        intent.putExtra(EXTRA_UNLAUNCHABLE_REASON, UNLAUNCHABLE_REASON_SUSPENDED_PACKAGE);
161        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
162        intent.putExtra(Intent.EXTRA_PACKAGE_NAME, packageName);
163        return intent;
164    }
165}
166