1 /* 2 * Copyright (C) 2015 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 17 package com.android.settings; 18 19 import android.app.Activity; 20 import android.app.ActivityManagerNative; 21 import android.app.AlertDialog; 22 import android.app.AppGlobals; 23 import android.app.IActivityManager; 24 import android.app.admin.DevicePolicyManager; 25 import android.content.ComponentName; 26 import android.content.Context; 27 import android.content.DialogInterface; 28 import android.content.Intent; 29 import android.content.pm.ActivityInfo; 30 import android.content.pm.PackageManager; 31 import android.graphics.drawable.Drawable; 32 import android.os.Bundle; 33 import android.os.Process; 34 import android.os.RemoteException; 35 import android.os.UserHandle; 36 import android.util.Log; 37 import android.view.LayoutInflater; 38 import android.view.View; 39 import android.widget.ImageView; 40 import android.widget.TextView; 41 42 import com.android.settingslib.RestrictedLockUtils; 43 import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin; 44 45 public class ShowAdminSupportDetailsDialog extends Activity 46 implements DialogInterface.OnDismissListener { 47 48 private static final String TAG = "AdminSupportDialog"; 49 50 private DevicePolicyManager mDpm; 51 52 private EnforcedAdmin mEnforcedAdmin; 53 private View mDialogView; 54 55 @Override 56 protected void onCreate(Bundle savedInstanceState) { 57 super.onCreate(savedInstanceState); 58 59 mDpm = getSystemService(DevicePolicyManager.class); 60 mEnforcedAdmin = getAdminDetailsFromIntent(getIntent()); 61 62 AlertDialog.Builder builder = new AlertDialog.Builder(this); 63 mDialogView = LayoutInflater.from(builder.getContext()).inflate( 64 R.layout.admin_support_details_dialog, null); 65 initializeDialogViews(mDialogView, mEnforcedAdmin.component, mEnforcedAdmin.userId); 66 builder.setOnDismissListener(this) 67 .setPositiveButton(R.string.okay, null) 68 .setView(mDialogView) 69 .show(); 70 } 71 72 @Override 73 public void onNewIntent(Intent intent) { 74 super.onNewIntent(intent); 75 EnforcedAdmin admin = getAdminDetailsFromIntent(intent); 76 if (!mEnforcedAdmin.equals(admin)) { 77 mEnforcedAdmin = admin; 78 initializeDialogViews(mDialogView, mEnforcedAdmin.component, mEnforcedAdmin.userId); 79 } 80 } 81 82 private EnforcedAdmin getAdminDetailsFromIntent(Intent intent) { 83 EnforcedAdmin admin = new EnforcedAdmin(null, UserHandle.myUserId()); 84 if (intent == null) { 85 return admin; 86 } 87 // Only allow apps with MANAGE_DEVICE_ADMINS permission to specify admin and user. 88 if (checkIfCallerHasPermission(android.Manifest.permission.MANAGE_DEVICE_ADMINS)) { 89 admin.component = intent.getParcelableExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN); 90 admin.userId = intent.getIntExtra(Intent.EXTRA_USER_ID, UserHandle.myUserId()); 91 } 92 return admin; 93 } 94 95 private boolean checkIfCallerHasPermission(String permission) { 96 IActivityManager am = ActivityManagerNative.getDefault(); 97 try { 98 final int uid = am.getLaunchedFromUid(getActivityToken()); 99 return AppGlobals.getPackageManager().checkUidPermission(permission, uid) 100 == PackageManager.PERMISSION_GRANTED; 101 } catch (RemoteException e) { 102 Log.e(TAG, "Could not talk to activity manager.", e); 103 } 104 return false; 105 } 106 107 private void initializeDialogViews(View root, ComponentName admin, int userId) { 108 if (admin != null) { 109 if (!RestrictedLockUtils.isAdminInCurrentUserOrProfile(this, admin) 110 || !RestrictedLockUtils.isCurrentUserOrProfile(this, userId)) { 111 admin = null; 112 } else { 113 ActivityInfo ai = null; 114 try { 115 ai = AppGlobals.getPackageManager().getReceiverInfo(admin, 0 /* flags */, 116 userId); 117 } catch (RemoteException e) { 118 Log.w(TAG, "Missing reciever info", e); 119 } 120 if (ai != null) { 121 Drawable icon = ai.loadIcon(getPackageManager()); 122 Drawable badgedIcon = getPackageManager().getUserBadgedIcon( 123 icon, new UserHandle(userId)); 124 ((ImageView) root.findViewById(R.id.admin_support_icon)).setImageDrawable( 125 badgedIcon); 126 } 127 } 128 } 129 130 setAdminSupportDetails(this, root, new EnforcedAdmin(admin, userId), true); 131 } 132 133 public static void setAdminSupportDetails(final Activity activity, View root, 134 final EnforcedAdmin enforcedAdmin, final boolean finishActivity) { 135 if (enforcedAdmin == null) { 136 return; 137 } 138 139 if (enforcedAdmin.component != null) { 140 DevicePolicyManager dpm = (DevicePolicyManager) activity.getSystemService( 141 Context.DEVICE_POLICY_SERVICE); 142 if (!RestrictedLockUtils.isAdminInCurrentUserOrProfile(activity, 143 enforcedAdmin.component) || !RestrictedLockUtils.isCurrentUserOrProfile( 144 activity, enforcedAdmin.userId)) { 145 enforcedAdmin.component = null; 146 } else { 147 if (enforcedAdmin.userId == UserHandle.USER_NULL) { 148 enforcedAdmin.userId = UserHandle.myUserId(); 149 } 150 CharSequence supportMessage = null; 151 if (UserHandle.isSameApp(Process.myUid(), Process.SYSTEM_UID)) { 152 supportMessage = dpm.getShortSupportMessageForUser( 153 enforcedAdmin.component, enforcedAdmin.userId); 154 } 155 if (supportMessage != null) { 156 TextView textView = (TextView) root.findViewById(R.id.admin_support_msg); 157 textView.setText(supportMessage); 158 } 159 } 160 } 161 162 root.findViewById(R.id.admins_policies_list).setOnClickListener( 163 new View.OnClickListener() { 164 @Override 165 public void onClick(View view) { 166 Intent intent = new Intent(); 167 if (enforcedAdmin.component != null) { 168 intent.setClass(activity, DeviceAdminAdd.class); 169 intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, 170 enforcedAdmin.component); 171 intent.putExtra(DeviceAdminAdd.EXTRA_CALLED_FROM_SUPPORT_DIALOG, true); 172 // DeviceAdminAdd class may need to run as managed profile. 173 activity.startActivityAsUser(intent, 174 new UserHandle(enforcedAdmin.userId)); 175 } else { 176 intent.setClass(activity, Settings.DeviceAdminSettingsActivity.class); 177 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 178 // Activity merges both managed profile and parent users 179 // admins so show as same user as this activity. 180 activity.startActivity(intent); 181 } 182 if (finishActivity) { 183 activity.finish(); 184 } 185 } 186 }); 187 } 188 189 @Override 190 public void onDismiss(DialogInterface dialog) { 191 finish(); 192 } 193 } 194