1 /* 2 * Copyright (C) 2020 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 com.android.settings.applications.specialaccess.interactacrossprofiles; 17 18 import static android.app.admin.DevicePolicyResources.Strings.Settings.APP_CAN_ACCESS_PERSONAL_DATA; 19 import static android.app.admin.DevicePolicyResources.Strings.Settings.APP_CAN_ACCESS_PERSONAL_PERMISSIONS; 20 import static android.app.admin.DevicePolicyResources.Strings.Settings.CONNECTED_APPS_SHARE_PERMISSIONS_AND_DATA; 21 import static android.app.admin.DevicePolicyResources.Strings.Settings.CONNECTED_WORK_AND_PERSONAL_APPS_TITLE; 22 import static android.app.admin.DevicePolicyResources.Strings.Settings.CONNECT_APPS_DIALOG_SUMMARY; 23 import static android.app.admin.DevicePolicyResources.Strings.Settings.CONNECT_APPS_DIALOG_TITLE; 24 import static android.app.admin.DevicePolicyResources.Strings.Settings.HOW_TO_DISCONNECT_APPS; 25 import static android.app.admin.DevicePolicyResources.Strings.Settings.INSTALL_IN_PERSONAL_PROFILE_TO_CONNECT_PROMPT; 26 import static android.app.admin.DevicePolicyResources.Strings.Settings.INSTALL_IN_WORK_PROFILE_TO_CONNECT_PROMPT; 27 import static android.app.admin.DevicePolicyResources.Strings.Settings.ONLY_CONNECT_TRUSTED_APPS; 28 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE; 29 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE; 30 import static android.provider.Settings.ACTION_MANAGE_CROSS_PROFILE_ACCESS; 31 32 import android.Manifest; 33 import android.annotation.UserIdInt; 34 import android.app.ActionBar; 35 import android.app.AppOpsManager; 36 import android.app.admin.DevicePolicyEventLogger; 37 import android.app.admin.DevicePolicyManager; 38 import android.app.settings.SettingsEnums; 39 import android.content.Context; 40 import android.content.DialogInterface; 41 import android.content.Intent; 42 import android.content.PermissionChecker; 43 import android.content.pm.CrossProfileApps; 44 import android.content.pm.PackageInfo; 45 import android.content.pm.PackageManager; 46 import android.graphics.ColorMatrix; 47 import android.graphics.ColorMatrixColorFilter; 48 import android.graphics.drawable.Drawable; 49 import android.os.Bundle; 50 import android.os.UserHandle; 51 import android.os.UserManager; 52 import android.stats.devicepolicy.DevicePolicyEnums; 53 import android.util.IconDrawableFactory; 54 import android.util.Log; 55 import android.view.View; 56 import android.widget.ImageView; 57 import android.widget.TextView; 58 59 import androidx.appcompat.app.AlertDialog; 60 import androidx.preference.Preference; 61 62 import com.android.settings.R; 63 import com.android.settings.applications.AppInfoBase; 64 import com.android.settings.applications.AppStoreUtil; 65 import com.android.settings.widget.CardPreference; 66 import com.android.settingslib.RestrictedLockUtils; 67 import com.android.settingslib.RestrictedSwitchPreference; 68 import com.android.settingslib.widget.LayoutPreference; 69 70 public class InteractAcrossProfilesDetails extends AppInfoBase 71 implements Preference.OnPreferenceClickListener { 72 73 private static final String INTERACT_ACROSS_PROFILES_SETTINGS_SWITCH = 74 "interact_across_profiles_settings_switch"; 75 private static final String INTERACT_ACROSS_PROFILES_HEADER = "interact_across_profiles_header"; 76 public static final String INSTALL_APP_BANNER_KEY = "install_app_banner"; 77 public static final String INTERACT_ACROSS_PROFILE_EXTRA_SUMMARY_KEY = 78 "interact_across_profiles_extra_summary"; 79 public static final String EXTRA_SHOW_FRAGMENT_ARGS = ":settings:show_fragment_args"; 80 public static final String INTENT_KEY = "intent"; 81 private static final String TAG = "InteractAcrossProfilesDetails"; 82 83 private Context mContext; 84 private CrossProfileApps mCrossProfileApps; 85 private UserManager mUserManager; 86 private RestrictedSwitchPreference mSwitchPref; 87 private LayoutPreference mHeader; 88 private CardPreference mInstallBanner; 89 private PackageManager mPackageManager; 90 private UserHandle mPersonalProfile; 91 private UserHandle mWorkProfile; 92 private boolean mInstalledInPersonal; 93 private boolean mInstalledInWork; 94 private String mAppLabel; 95 private Intent mInstallAppIntent; 96 private boolean mIsPageLaunchedByApp; 97 98 @Override onCreate(Bundle savedInstanceState)99 public void onCreate(Bundle savedInstanceState) { 100 super.onCreate(savedInstanceState); 101 102 mContext = getContext(); 103 mCrossProfileApps = mContext.getSystemService(CrossProfileApps.class); 104 mUserManager = mContext.getSystemService(UserManager.class); 105 mPackageManager = mContext.getPackageManager(); 106 107 mWorkProfile = InteractAcrossProfilesSettings.getWorkProfile(mUserManager); 108 mPersonalProfile = mUserManager.getProfileParent(mWorkProfile); 109 mInstalledInWork = isPackageInstalled(mPackageName, mWorkProfile.getIdentifier()); 110 mInstalledInPersonal = isPackageInstalled(mPackageName, mPersonalProfile.getIdentifier()); 111 112 mAppLabel = mPackageInfo.applicationInfo.loadLabel(mPackageManager).toString(); 113 mInstallAppIntent = AppStoreUtil.getAppStoreLink(mContext, mPackageName); 114 115 addPreferencesFromResource(R.xml.interact_across_profiles_permissions_details); 116 117 replaceEnterprisePreferenceScreenTitle(CONNECTED_WORK_AND_PERSONAL_APPS_TITLE, 118 R.string.interact_across_profiles_title); 119 replaceEnterpriseStringSummary("interact_across_profiles_summary_1", 120 CONNECTED_APPS_SHARE_PERMISSIONS_AND_DATA, 121 R.string.interact_across_profiles_summary_1); 122 replaceEnterpriseStringSummary("interact_across_profiles_summary_2", 123 ONLY_CONNECT_TRUSTED_APPS, 124 R.string.interact_across_profiles_summary_2); 125 replaceEnterpriseStringSummary("interact_across_profiles_extra_summary", 126 HOW_TO_DISCONNECT_APPS, 127 R.string.interact_across_profiles_summary_3); 128 129 130 mSwitchPref = findPreference(INTERACT_ACROSS_PROFILES_SETTINGS_SWITCH); 131 mSwitchPref.setOnPreferenceClickListener(this); 132 133 mHeader = findPreference(INTERACT_ACROSS_PROFILES_HEADER); 134 135 mInstallBanner = findPreference(INSTALL_APP_BANNER_KEY); 136 mInstallBanner.setOnPreferenceClickListener(this); 137 138 mIsPageLaunchedByApp = launchedByApp(); 139 140 // refreshUi checks that the user can still configure the appOp, return to the 141 // previous page if it can't. 142 if (!refreshUi()) { 143 setIntentAndFinish(true/* appChanged */); 144 } 145 addAppTitleAndIcons(mPersonalProfile, mWorkProfile); 146 styleActionBar(); 147 maybeShowExtraSummary(); 148 logPageLaunchMetrics(); 149 } 150 maybeShowExtraSummary()151 private void maybeShowExtraSummary() { 152 Preference extraSummary = findPreference(INTERACT_ACROSS_PROFILE_EXTRA_SUMMARY_KEY); 153 if (extraSummary == null) { 154 return; 155 } 156 extraSummary.setVisible(mIsPageLaunchedByApp); 157 } 158 logPageLaunchMetrics()159 private void logPageLaunchMetrics() { 160 if (!mCrossProfileApps.canConfigureInteractAcrossProfiles(mPackageName)) { 161 logNonConfigurableAppMetrics(); 162 } 163 if (mIsPageLaunchedByApp) { 164 logEvent(DevicePolicyEnums.CROSS_PROFILE_SETTINGS_PAGE_LAUNCHED_FROM_APP); 165 } else { 166 logEvent(DevicePolicyEnums.CROSS_PROFILE_SETTINGS_PAGE_LAUNCHED_FROM_SETTINGS); 167 } 168 } 169 logNonConfigurableAppMetrics()170 private void logNonConfigurableAppMetrics() { 171 if (!isCrossProfilePackageAllowlisted(mPackageName)) { 172 logEvent(DevicePolicyEnums.CROSS_PROFILE_SETTINGS_PAGE_ADMIN_RESTRICTED); 173 return; 174 } 175 if (mInstallBanner == null) { 176 logEvent(DevicePolicyEnums.CROSS_PROFILE_SETTINGS_PAGE_MISSING_INSTALL_BANNER_INTENT); 177 } 178 if (!mInstalledInPersonal) { 179 logEvent(DevicePolicyEnums.CROSS_PROFILE_SETTINGS_PAGE_MISSING_PERSONAL_APP); 180 return; 181 } 182 if (!mInstalledInWork) { 183 logEvent(DevicePolicyEnums.CROSS_PROFILE_SETTINGS_PAGE_MISSING_WORK_APP); 184 } 185 } 186 logEvent(int eventId)187 private void logEvent(int eventId) { 188 DevicePolicyEventLogger.createEvent(eventId) 189 .setStrings(mPackageName) 190 .setInt(UserHandle.myUserId()) 191 .setAdmin(RestrictedLockUtils.getProfileOrDeviceOwner( 192 mContext, mWorkProfile).component) 193 .write(); 194 } 195 addAppTitleAndIcons(UserHandle personalProfile, UserHandle workProfile)196 private void addAppTitleAndIcons(UserHandle personalProfile, UserHandle workProfile) { 197 final TextView title = mHeader.findViewById(R.id.entity_header_title); 198 if (title != null) { 199 final String appLabel = mPackageInfo.applicationInfo.loadLabel( 200 mPackageManager).toString(); 201 title.setText(appLabel); 202 } 203 204 final ImageView personalIconView = mHeader.findViewById(R.id.entity_header_icon_personal); 205 if (personalIconView != null) { 206 Drawable icon = IconDrawableFactory.newInstance(mContext) 207 .getBadgedIcon(mPackageInfo.applicationInfo, personalProfile.getIdentifier()) 208 .mutate(); 209 if (!mInstalledInPersonal) { 210 icon.setColorFilter(createSuspendedColorMatrix()); 211 } 212 personalIconView.setImageDrawable(icon); 213 } 214 215 final ImageView workIconView = mHeader.findViewById(R.id.entity_header_icon_work); 216 if (workIconView != null) { 217 Drawable icon = IconDrawableFactory.newInstance(mContext) 218 .getBadgedIcon(mPackageInfo.applicationInfo, workProfile.getIdentifier()) 219 .mutate(); 220 if (!mInstalledInWork) { 221 icon.setColorFilter(createSuspendedColorMatrix()); 222 } 223 workIconView.setImageDrawable(icon); 224 } 225 } 226 styleActionBar()227 private void styleActionBar() { 228 final ActionBar actionBar = getActivity().getActionBar(); 229 if (actionBar != null) { 230 actionBar.setElevation(0); 231 } 232 } 233 createSuspendedColorMatrix()234 private ColorMatrixColorFilter createSuspendedColorMatrix() { 235 int grayValue = 127; 236 float scale = 0.5f; // half bright 237 238 ColorMatrix tempBrightnessMatrix = new ColorMatrix(); 239 float[] mat = tempBrightnessMatrix.getArray(); 240 mat[0] = scale; 241 mat[6] = scale; 242 mat[12] = scale; 243 mat[4] = grayValue; 244 mat[9] = grayValue; 245 mat[14] = grayValue; 246 247 ColorMatrix matrix = new ColorMatrix(); 248 matrix.setSaturation(0.0f); 249 matrix.preConcat(tempBrightnessMatrix); 250 return new ColorMatrixColorFilter(matrix); 251 } 252 253 @Override onPreferenceClick(Preference preference)254 public boolean onPreferenceClick(Preference preference) { 255 // refreshUi checks that the user can still configure the appOp, return to the 256 // previous page if it can't. 257 if (!refreshUi()) { 258 setIntentAndFinish(true/* appChanged */); 259 } 260 if (preference == mSwitchPref) { 261 handleSwitchPreferenceClick(); 262 return true; 263 } 264 if (preference == mInstallBanner) { 265 handleInstallBannerClick(); 266 return true; 267 } 268 return false; 269 } 270 handleSwitchPreferenceClick()271 private void handleSwitchPreferenceClick() { 272 if (isInteractAcrossProfilesEnabled()) { 273 logEvent(DevicePolicyEnums.CROSS_PROFILE_SETTINGS_PAGE_PERMISSION_REVOKED); 274 enableInteractAcrossProfiles(false); 275 refreshUi(); 276 } else { 277 showConsentDialog(); 278 } 279 } 280 showConsentDialog()281 private void showConsentDialog() { 282 final View dialogView = getLayoutInflater().inflate( 283 R.layout.interact_across_profiles_consent_dialog, null); 284 285 final TextView dialogTitle = dialogView.findViewById( 286 R.id.interact_across_profiles_consent_dialog_title); 287 dialogTitle.setText(mDpm.getResources().getString(CONNECT_APPS_DIALOG_TITLE, () -> 288 getString(R.string.interact_across_profiles_consent_dialog_title, mAppLabel), 289 mAppLabel)); 290 291 final TextView appDataSummary = dialogView.findViewById(R.id.app_data_summary); 292 appDataSummary.setText( 293 mDpm.getResources().getString(APP_CAN_ACCESS_PERSONAL_DATA, 294 () -> getString( 295 R.string.interact_across_profiles_consent_dialog_app_data_summary, 296 mAppLabel), mAppLabel)); 297 298 final TextView permissionsSummary = dialogView.findViewById(R.id.permissions_summary); 299 permissionsSummary.setText(mDpm.getResources().getString( 300 APP_CAN_ACCESS_PERSONAL_PERMISSIONS, 301 () -> getString( 302 R.string.interact_across_profiles_consent_dialog_permissions_summary, 303 mAppLabel), 304 mAppLabel)); 305 306 final TextView dialogSummary = 307 dialogView.findViewById(R.id.interact_across_profiles_consent_dialog_summary); 308 dialogSummary.setText(mDpm.getResources().getString(CONNECT_APPS_DIALOG_SUMMARY, 309 () -> getString( 310 R.string.interact_across_profiles_consent_dialog_summary))); 311 312 AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); 313 builder.setView(dialogView) 314 .setPositiveButton(R.string.allow, new DialogInterface.OnClickListener() { 315 public void onClick(DialogInterface dialog, int which) { 316 logEvent(DevicePolicyEnums.CROSS_PROFILE_SETTINGS_PAGE_USER_CONSENTED); 317 enableInteractAcrossProfiles(true); 318 refreshUi(); 319 if (mIsPageLaunchedByApp) { 320 setIntentAndFinish(/* appChanged= */ true); 321 } 322 } 323 }) 324 .setNegativeButton(R.string.deny, new DialogInterface.OnClickListener() { 325 public void onClick(DialogInterface dialog, int which) { 326 logEvent( 327 DevicePolicyEnums.CROSS_PROFILE_SETTINGS_PAGE_USER_DECLINED_CONSENT); 328 refreshUi(); 329 } 330 }) 331 .create().show(); 332 } 333 isInteractAcrossProfilesEnabled()334 private boolean isInteractAcrossProfilesEnabled() { 335 return isInteractAcrossProfilesEnabled(mContext, mPackageName); 336 } 337 isInteractAcrossProfilesEnabled( Context context, String packageName)338 static boolean isInteractAcrossProfilesEnabled( 339 Context context, String packageName) { 340 UserManager userManager = context.getSystemService(UserManager.class); 341 UserHandle workProfile = InteractAcrossProfilesSettings.getWorkProfile(userManager); 342 if (workProfile == null) { 343 return false; 344 } 345 UserHandle personalProfile = userManager.getProfileParent(workProfile); 346 return context.getSystemService( 347 CrossProfileApps.class).canConfigureInteractAcrossProfiles(packageName) 348 && isInteractAcrossProfilesEnabledInProfile(context, packageName, personalProfile) 349 && isInteractAcrossProfilesEnabledInProfile(context, packageName, workProfile); 350 351 } 352 isInteractAcrossProfilesEnabledInProfile( Context context, String packageName, UserHandle userHandle)353 private static boolean isInteractAcrossProfilesEnabledInProfile( 354 Context context, String packageName, UserHandle userHandle) { 355 final PackageManager packageManager = context.getPackageManager(); 356 final int uid; 357 try { 358 uid = packageManager.getApplicationInfoAsUser( 359 packageName, /* flags= */0, userHandle).uid; 360 } catch (PackageManager.NameNotFoundException e) { 361 return false; 362 } 363 return PermissionChecker.PERMISSION_GRANTED 364 == PermissionChecker.checkPermissionForPreflight( 365 context, 366 Manifest.permission.INTERACT_ACROSS_PROFILES, 367 PermissionChecker.PID_UNKNOWN, 368 uid, 369 packageName); 370 } 371 enableInteractAcrossProfiles(boolean newState)372 private void enableInteractAcrossProfiles(boolean newState) { 373 mCrossProfileApps.setInteractAcrossProfilesAppOp( 374 mPackageName, newState ? AppOpsManager.MODE_ALLOWED : AppOpsManager.MODE_IGNORED); 375 } 376 handleInstallBannerClick()377 private void handleInstallBannerClick() { 378 if (mInstallAppIntent == null) { 379 logEvent( 380 DevicePolicyEnums.CROSS_PROFILE_SETTINGS_PAGE_INSTALL_BANNER_NO_INTENT_CLICKED); 381 return; 382 } 383 if (!mInstalledInWork) { 384 logEvent(DevicePolicyEnums.CROSS_PROFILE_SETTINGS_PAGE_INSTALL_BANNER_CLICKED); 385 mContext.startActivityAsUser(mInstallAppIntent, mWorkProfile); 386 return; 387 } 388 if (!mInstalledInPersonal) { 389 logEvent(DevicePolicyEnums.CROSS_PROFILE_SETTINGS_PAGE_INSTALL_BANNER_CLICKED); 390 mContext.startActivityAsUser(mInstallAppIntent, mPersonalProfile); 391 } 392 } 393 394 /** 395 * @return the summary for the current state of whether the app associated with the given 396 * {@code packageName} is allowed to interact across profiles. 397 */ getPreferenceSummary( Context context, String packageName)398 public static CharSequence getPreferenceSummary( 399 Context context, String packageName) { 400 return context.getString(isInteractAcrossProfilesEnabled(context, packageName) 401 ? R.string.interact_across_profiles_summary_allowed 402 : R.string.interact_across_profiles_summary_not_allowed); 403 } 404 405 @Override refreshUi()406 protected boolean refreshUi() { 407 if (mPackageInfo == null || mPackageInfo.applicationInfo == null) { 408 return false; 409 } 410 if (!mCrossProfileApps.canUserAttemptToConfigureInteractAcrossProfiles(mPackageName)) { 411 // Invalid app entry. Should not allow changing permission 412 mSwitchPref.setEnabled(false); 413 return false; 414 } 415 if (!mCrossProfileApps.canConfigureInteractAcrossProfiles(mPackageName)) { 416 return refreshUiForNonConfigurableApps(); 417 } 418 refreshUiForConfigurableApps(); 419 return true; 420 } 421 refreshUiForNonConfigurableApps()422 private boolean refreshUiForNonConfigurableApps() { 423 mSwitchPref.setChecked(false); 424 mSwitchPref.setTitle(R.string.interact_across_profiles_switch_disabled); 425 if (!isCrossProfilePackageAllowlisted(mPackageName)) { 426 mInstallBanner.setVisible(false); 427 mSwitchPref.setDisabledByAdmin(RestrictedLockUtils.getProfileOrDeviceOwner( 428 mContext, mWorkProfile)); 429 return true; 430 } 431 mSwitchPref.setEnabled(false); 432 if (!mInstalledInPersonal && !mInstalledInWork) { 433 return false; 434 } 435 if (!mInstalledInPersonal) { 436 mInstallBanner.setTitle( 437 mDpm.getResources().getString(INSTALL_IN_PERSONAL_PROFILE_TO_CONNECT_PROMPT, 438 () -> getString( 439 R.string.interact_across_profiles_install_personal_app_title, 440 mAppLabel), 441 mAppLabel)); 442 if (mInstallAppIntent != null) { 443 mInstallBanner.setSummary( 444 R.string.interact_across_profiles_install_app_summary); 445 } 446 mInstallBanner.setVisible(true); 447 return true; 448 } 449 if (!mInstalledInWork) { 450 mInstallBanner.setTitle( 451 mDpm.getResources().getString(INSTALL_IN_WORK_PROFILE_TO_CONNECT_PROMPT, 452 () -> getString( 453 R.string.interact_across_profiles_install_work_app_title, 454 mAppLabel), 455 mAppLabel)); 456 if (mInstallAppIntent != null) { 457 mInstallBanner.setSummary( 458 R.string.interact_across_profiles_install_app_summary); 459 } 460 mInstallBanner.setVisible(true); 461 return true; 462 } 463 return false; 464 } 465 isCrossProfilePackageAllowlisted(String packageName)466 private boolean isCrossProfilePackageAllowlisted(String packageName) { 467 return mContext.getSystemService(DevicePolicyManager.class) 468 .getAllCrossProfilePackages().contains(packageName); 469 } 470 isPackageInstalled(String packageName, @UserIdInt int userId)471 private boolean isPackageInstalled(String packageName, @UserIdInt int userId) { 472 final PackageInfo info; 473 try { 474 info = mContext.createContextAsUser(UserHandle.of(userId), /* flags= */0) 475 .getPackageManager().getPackageInfo(packageName, 476 MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE); 477 } catch (PackageManager.NameNotFoundException e) { 478 return false; 479 } 480 return info != null; 481 } 482 refreshUiForConfigurableApps()483 private void refreshUiForConfigurableApps() { 484 mInstallBanner.setVisible(false); 485 mSwitchPref.setEnabled(true); 486 if (isInteractAcrossProfilesEnabled()) { 487 enableSwitchPref(); 488 } else { 489 disableSwitchPref(); 490 } 491 } 492 enableSwitchPref()493 private void enableSwitchPref() { 494 mSwitchPref.setChecked(true); 495 mSwitchPref.setTitle(R.string.interact_across_profiles_switch_enabled); 496 final ImageView horizontalArrowIcon = mHeader.findViewById(R.id.entity_header_swap_horiz); 497 if (horizontalArrowIcon != null) { 498 horizontalArrowIcon.setImageDrawable( 499 mContext.getDrawable(R.drawable.ic_swap_horiz_blue)); 500 } 501 } 502 disableSwitchPref()503 private void disableSwitchPref() { 504 mSwitchPref.setChecked(false); 505 mSwitchPref.setTitle(R.string.interact_across_profiles_switch_disabled); 506 final ImageView horizontalArrowIcon = mHeader.findViewById(R.id.entity_header_swap_horiz); 507 if (horizontalArrowIcon != null) { 508 horizontalArrowIcon.setImageDrawable( 509 mContext.getDrawable(R.drawable.ic_swap_horiz_grey)); 510 } 511 } 512 513 @Override createDialog(int id, int errorCode)514 protected AlertDialog createDialog(int id, int errorCode) { 515 return null; 516 } 517 518 @Override getMetricsCategory()519 public int getMetricsCategory() { 520 return SettingsEnums.INTERACT_ACROSS_PROFILES; 521 } 522 launchedByApp()523 private boolean launchedByApp() { 524 final Bundle bundle = getIntent().getBundleExtra(EXTRA_SHOW_FRAGMENT_ARGS); 525 if (bundle == null) { 526 return false; 527 } 528 final Intent intent = (Intent) bundle.get(INTENT_KEY); 529 if (intent == null) { 530 return false; 531 } 532 return ACTION_MANAGE_CROSS_PROFILE_ACCESS.equals(intent.getAction()); 533 } 534 } 535