1 /*
2  * Copyright (C) 2019 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.password;
18 
19 import static com.android.settings.Utils.SETTINGS_PACKAGE_NAME;
20 
21 import android.app.ActivityManager;
22 import android.app.IActivityManager;
23 import android.content.Context;
24 import android.content.pm.PackageManager;
25 import android.os.IBinder;
26 import android.os.RemoteException;
27 import android.os.UserHandle;
28 import android.util.Log;
29 import android.view.View;
30 import android.view.ViewGroup;
31 import android.widget.Button;
32 import android.widget.LinearLayout;
33 import android.widget.TextView;
34 
35 import androidx.annotation.Nullable;
36 
37 import com.android.settings.R;
38 import com.android.settings.Utils;
39 
40 public final class PasswordUtils extends com.android.settingslib.Utils {
41 
42     private static final String TAG = "Settings";
43 
44     /**
45      * Returns whether the uid which the activity with {@code activityToken} is launched from has
46      * been granted the {@code permission}.
47      */
isCallingAppPermitted(Context context, IBinder activityToken, String permission)48     public static boolean isCallingAppPermitted(Context context, IBinder activityToken,
49             String permission) {
50         try {
51             return context.checkPermission(permission, /* pid= */ -1,
52                     ActivityManager.getService().getLaunchedFromUid(activityToken))
53                     == PackageManager.PERMISSION_GRANTED;
54         } catch (RemoteException e) {
55             Log.v(TAG, "Could not talk to activity manager.", e);
56             return false;
57         }
58     }
59 
60     /**
61      * Returns the label of the package which the activity with {@code activityToken} is launched
62      * from or {@code null} if it is launched from the settings app itself.
63      */
64     @Nullable
getCallingAppLabel(Context context, IBinder activityToken)65     public static CharSequence getCallingAppLabel(Context context, IBinder activityToken) {
66         String pkg = getCallingAppPackageName(activityToken);
67         if (pkg == null || pkg.equals(SETTINGS_PACKAGE_NAME)) {
68             return null;
69         }
70 
71         return Utils.getApplicationLabel(context, pkg);
72     }
73 
74     /**
75      * Returns the package name which the activity with {@code activityToken} is launched from.
76      */
77     @Nullable
getCallingAppPackageName(IBinder activityToken)78     public static String getCallingAppPackageName(IBinder activityToken) {
79         String pkg = null;
80         try {
81             pkg = ActivityManager.getService().getLaunchedFromPackage(activityToken);
82         } catch (RemoteException e) {
83             Log.v(TAG, "Could not talk to activity manager.", e);
84         }
85         return pkg;
86     }
87 
88     /** Crashes the calling application and provides it with {@code message}. */
crashCallingApplication(IBinder activityToken, String message, int exceptionTypeId)89     public static void crashCallingApplication(IBinder activityToken, String message,
90             int exceptionTypeId) {
91         IActivityManager am = ActivityManager.getService();
92         try {
93             int uid = am.getLaunchedFromUid(activityToken);
94             int userId = UserHandle.getUserId(uid);
95             am.crashApplicationWithType(
96                     uid,
97                     /* initialPid= */ -1,
98                     getCallingAppPackageName(activityToken),
99                     userId,
100                     message,
101                     false,
102                     exceptionTypeId);
103         } catch (RemoteException e) {
104             Log.v(TAG, "Could not talk to activity manager.", e);
105         }
106     }
107 
108     /** Setup screen lock options button under the Glif Header. */
setupScreenLockOptionsButton(Context context, View view, Button optButton)109     public static void setupScreenLockOptionsButton(Context context, View view, Button optButton) {
110         final LinearLayout headerLayout = view.findViewById(
111                 com.google.android.setupdesign.R.id.sud_layout_header);
112         final TextView sucTitleView = headerLayout.findViewById(R.id.suc_layout_title);
113         if (headerLayout != null && sucTitleView != null) {
114             final ViewGroup.MarginLayoutParams layoutTitleParams =
115                     (ViewGroup.MarginLayoutParams) sucTitleView.getLayoutParams();
116             final ViewGroup.MarginLayoutParams lp = new ViewGroup.MarginLayoutParams(
117                     ViewGroup.LayoutParams.WRAP_CONTENT,
118                     ViewGroup.LayoutParams.WRAP_CONTENT);
119             lp.leftMargin = layoutTitleParams.leftMargin;
120             lp.topMargin = (int) context.getResources().getDimensionPixelSize(
121                     R.dimen.screen_lock_options_button_margin_top);
122             optButton.setPadding(0, 0, 0, 0);
123             optButton.setLayoutParams(lp);
124             optButton.setText(context.getString(R.string.setup_lock_settings_options_button_label));
125             headerLayout.addView(optButton);
126         }
127     }
128 }
129