• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2009 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 package android.accounts;
17 
18 import android.app.Activity;
19 import android.content.Context;
20 import android.content.Intent;
21 import android.content.pm.PackageManager;
22 import android.content.res.Resources;
23 import android.os.Bundle;
24 import android.os.Process;
25 import android.os.UserHandle;
26 import android.text.TextUtils;
27 import android.view.LayoutInflater;
28 import android.view.View;
29 import android.widget.LinearLayout;
30 import android.widget.TextView;
31 
32 import com.android.internal.R;
33 
34 import java.io.IOException;
35 
36 /**
37  * @hide
38  */
39 public class GrantCredentialsPermissionActivity extends Activity implements View.OnClickListener {
40     public static final String EXTRAS_ACCOUNT = "account";
41     public static final String EXTRAS_AUTH_TOKEN_TYPE = "authTokenType";
42     public static final String EXTRAS_RESPONSE = "response";
43     public static final String EXTRAS_REQUESTING_UID = "uid";
44 
45     private Account mAccount;
46     private String mAuthTokenType;
47     private int mUid;
48     private int mCallingUid;
49     private Bundle mResultBundle = null;
50     protected LayoutInflater mInflater;
51 
onCreate(Bundle savedInstanceState)52     protected void onCreate(Bundle savedInstanceState) {
53         super.onCreate(savedInstanceState);
54         getWindow().addSystemFlags(
55                 android.view.WindowManager.LayoutParams
56                         .SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS);
57         setContentView(R.layout.grant_credentials_permission);
58         setTitle(R.string.grant_permissions_header_text);
59 
60         mInflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
61 
62         final Bundle extras = getIntent().getExtras();
63         if (extras == null) {
64             // we were somehow started with bad parameters. abort the activity.
65             setResult(Activity.RESULT_CANCELED);
66             finish();
67             return;
68         }
69 
70         // Grant 'account'/'type' to mUID
71         mAccount = extras.getParcelable(EXTRAS_ACCOUNT);
72         mAuthTokenType = extras.getString(EXTRAS_AUTH_TOKEN_TYPE);
73         mUid = extras.getInt(EXTRAS_REQUESTING_UID);
74         final PackageManager pm = getPackageManager();
75         final String[] packages = pm.getPackagesForUid(mUid);
76 
77         if (mAccount == null || mAuthTokenType == null || packages == null) {
78             // we were somehow started with bad parameters. abort the activity.
79             setResult(Activity.RESULT_CANCELED);
80             finish();
81             return;
82         }
83 
84         mCallingUid = getLaunchedFromUid();
85 
86         if (!UserHandle.isSameApp(mCallingUid, Process.SYSTEM_UID) && mCallingUid != mUid) {
87             setResult(Activity.RESULT_CANCELED);
88             finish();
89             return;
90         }
91 
92         String accountTypeLabel;
93         try {
94             accountTypeLabel = getAccountLabel(mAccount);
95         } catch (IllegalArgumentException e) {
96             // label or resource was missing. abort the activity.
97             setResult(Activity.RESULT_CANCELED);
98             finish();
99             return;
100         }
101 
102         final TextView authTokenTypeView = findViewById(R.id.authtoken_type);
103         authTokenTypeView.setVisibility(View.GONE);
104 
105         final AccountManagerCallback<String> callback = new AccountManagerCallback<String>() {
106             public void run(AccountManagerFuture<String> future) {
107                 try {
108                     final String authTokenLabel = future.getResult();
109                     if (!TextUtils.isEmpty(authTokenLabel)) {
110                         runOnUiThread(new Runnable() {
111                             public void run() {
112                                 if (!isFinishing()) {
113                                     authTokenTypeView.setText(authTokenLabel);
114                                     authTokenTypeView.setVisibility(View.VISIBLE);
115                                 }
116                             }
117                         });
118                     }
119                 } catch (OperationCanceledException e) {
120                 } catch (IOException e) {
121                 } catch (AuthenticatorException e) {
122                 }
123             }
124         };
125 
126         if (!AccountManager.ACCOUNT_ACCESS_TOKEN_TYPE.equals(mAuthTokenType)) {
127             AccountManager.get(this).getAuthTokenLabel(mAccount.type,
128                     mAuthTokenType, callback, null);
129         }
130 
131         findViewById(R.id.allow_button).setOnClickListener(this);
132         findViewById(R.id.deny_button).setOnClickListener(this);
133 
134         LinearLayout packagesListView = findViewById(R.id.packages_list);
135 
136         for (String pkg : packages) {
137             String packageLabel;
138             try {
139                 packageLabel = pm.getApplicationLabel(pm.getApplicationInfo(pkg, 0)).toString();
140             } catch (PackageManager.NameNotFoundException e) {
141                 packageLabel = pkg;
142             }
143             packagesListView.addView(newPackageView(packageLabel));
144         }
145 
146         ((TextView) findViewById(R.id.account_name)).setText(mAccount.name);
147         ((TextView) findViewById(R.id.account_type)).setText(accountTypeLabel);
148     }
149 
getAccountLabel(Account account)150     private String getAccountLabel(Account account) {
151         final AuthenticatorDescription[] authenticatorTypes =
152                 AccountManager.get(this).getAuthenticatorTypes();
153         for (int i = 0, N = authenticatorTypes.length; i < N; i++) {
154             final AuthenticatorDescription desc = authenticatorTypes[i];
155             if (desc.type.equals(account.type)) {
156                 try {
157                     return createPackageContext(desc.packageName, 0).getString(desc.labelId);
158                 } catch (PackageManager.NameNotFoundException e) {
159                     return account.type;
160                 } catch (Resources.NotFoundException e) {
161                     return account.type;
162                 }
163             }
164         }
165         return account.type;
166     }
167 
newPackageView(String packageLabel)168     private View newPackageView(String packageLabel) {
169         View view = mInflater.inflate(R.layout.permissions_package_list_item, null);
170         ((TextView) view.findViewById(R.id.package_label)).setText(packageLabel);
171         return view;
172     }
173 
onClick(View v)174     public void onClick(View v) {
175         switch (v.getId()) {
176             case R.id.allow_button:
177                 AccountManager.get(this).updateAppPermission(mAccount, mAuthTokenType, mUid, true);
178                 Intent result = new Intent();
179                 result.putExtra("retry", true);
180                 setResult(RESULT_OK, result);
181                 setAccountAuthenticatorResult(result.getExtras());
182                 break;
183 
184             case R.id.deny_button:
185                 AccountManager.get(this).updateAppPermission(mAccount, mAuthTokenType, mUid, false);
186                 setResult(RESULT_CANCELED);
187                 break;
188         }
189         finish();
190     }
191 
setAccountAuthenticatorResult(Bundle result)192     public final void setAccountAuthenticatorResult(Bundle result) {
193         mResultBundle = result;
194     }
195 
196     /**
197      * Sends the result or a {@link AccountManager#ERROR_CODE_CANCELED} error if a
198      * result isn't present.
199      */
finish()200     public void finish() {
201         Intent intent = getIntent();
202         AccountAuthenticatorResponse response = intent.getParcelableExtra(EXTRAS_RESPONSE);
203         if (response != null) {
204             // send the result bundle back if set, otherwise send an error.
205             if (mResultBundle != null) {
206                 response.onResult(mResultBundle);
207             } else {
208                 response.onError(AccountManager.ERROR_CODE_CANCELED, "canceled");
209             }
210         }
211         super.finish();
212     }
213 }
214