1 /* 2 * Copyright (C) 2017 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.applications.appinfo; 18 19 import android.content.Context; 20 import android.content.Intent; 21 import android.content.pm.PackageManager; 22 import android.content.pm.ResolveInfo; 23 import android.net.Uri; 24 import android.os.Bundle; 25 import android.text.TextUtils; 26 import android.view.Menu; 27 import android.view.MenuInflater; 28 import android.view.MenuItem; 29 import android.view.View; 30 import android.widget.Button; 31 32 import androidx.fragment.app.DialogFragment; 33 import androidx.preference.PreferenceScreen; 34 35 import com.android.settings.R; 36 import com.android.settings.applications.AppStoreUtil; 37 import com.android.settings.core.BasePreferenceController; 38 import com.android.settingslib.applications.AppUtils; 39 import com.android.settingslib.core.lifecycle.Lifecycle; 40 import com.android.settingslib.core.lifecycle.LifecycleObserver; 41 import com.android.settingslib.core.lifecycle.events.OnCreateOptionsMenu; 42 import com.android.settingslib.core.lifecycle.events.OnOptionsItemSelected; 43 import com.android.settingslib.core.lifecycle.events.OnPrepareOptionsMenu; 44 import com.android.settingslib.widget.LayoutPreference; 45 46 import java.util.List; 47 48 public class InstantAppButtonsPreferenceController extends BasePreferenceController implements 49 LifecycleObserver, OnCreateOptionsMenu, OnPrepareOptionsMenu, OnOptionsItemSelected { 50 51 private static final String KEY_INSTANT_APP_BUTTONS = "instant_app_buttons"; 52 private static final String META_DATA_DEFAULT_URI = "default-url"; 53 54 private final AppInfoDashboardFragment mParent; 55 private final String mPackageName; 56 private String mLaunchUri; 57 private LayoutPreference mPreference; 58 private MenuItem mInstallMenu; 59 InstantAppButtonsPreferenceController(Context context, AppInfoDashboardFragment parent, String packageName, Lifecycle lifecycle)60 public InstantAppButtonsPreferenceController(Context context, AppInfoDashboardFragment parent, 61 String packageName, Lifecycle lifecycle) { 62 super(context, KEY_INSTANT_APP_BUTTONS); 63 mParent = parent; 64 mPackageName = packageName; 65 mLaunchUri = getDefaultLaunchUri(); 66 if (lifecycle != null) { 67 lifecycle.addObserver(this); 68 } 69 } 70 71 @Override getAvailabilityStatus()72 public int getAvailabilityStatus() { 73 return AppUtils.isInstant(mParent.getPackageInfo().applicationInfo) 74 ? AVAILABLE : DISABLED_FOR_USER; 75 } 76 77 @Override displayPreference(PreferenceScreen screen)78 public void displayPreference(PreferenceScreen screen) { 79 super.displayPreference(screen); 80 mPreference = screen.findPreference(KEY_INSTANT_APP_BUTTONS); 81 initButtons(mPreference.findViewById(R.id.instant_app_button_container)); 82 } 83 84 @Override onCreateOptionsMenu(Menu menu, MenuInflater inflater)85 public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { 86 if (!TextUtils.isEmpty(mLaunchUri)) { 87 menu.add(0, AppInfoDashboardFragment.INSTALL_INSTANT_APP_MENU, 2, R.string.install_text) 88 .setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER); 89 } 90 } 91 92 @Override onOptionsItemSelected(MenuItem menuItem)93 public boolean onOptionsItemSelected(MenuItem menuItem) { 94 if (menuItem.getItemId() == AppInfoDashboardFragment.INSTALL_INSTANT_APP_MENU) { 95 final Intent appStoreIntent = AppStoreUtil.getAppStoreLink(mContext, mPackageName); 96 if (appStoreIntent != null) { 97 mParent.startActivity(appStoreIntent); 98 } 99 return true; 100 } 101 return false; 102 } 103 104 @Override onPrepareOptionsMenu(Menu menu)105 public void onPrepareOptionsMenu(Menu menu) { 106 mInstallMenu = menu.findItem(AppInfoDashboardFragment.INSTALL_INSTANT_APP_MENU); 107 if (mInstallMenu != null) { 108 if (AppStoreUtil.getAppStoreLink(mContext, mPackageName) == null) { 109 mInstallMenu.setEnabled(false); 110 } 111 } 112 } 113 initButtons(View view)114 private void initButtons(View view) { 115 final Button installButton = view.findViewById(R.id.install); 116 final Button clearDataButton = view.findViewById(R.id.clear_data); 117 final Button launchButton = view.findViewById(R.id.launch); 118 if (!TextUtils.isEmpty(mLaunchUri)) { 119 installButton.setVisibility(View.GONE); 120 final Intent intent = new Intent(Intent.ACTION_VIEW); 121 intent.addCategory(Intent.CATEGORY_BROWSABLE); 122 intent.setPackage(mPackageName); 123 intent.setData(Uri.parse(mLaunchUri)); 124 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 125 launchButton.setOnClickListener(v -> mParent.startActivity(intent)); 126 } else { 127 launchButton.setVisibility(View.GONE); 128 final Intent appStoreIntent = AppStoreUtil.getAppStoreLink(mContext, mPackageName); 129 if (appStoreIntent != null) { 130 installButton.setOnClickListener(v -> mParent.startActivity(appStoreIntent)); 131 } else { 132 installButton.setEnabled(false); 133 } 134 } 135 clearDataButton.setOnClickListener(v -> showDialog()); 136 } 137 showDialog()138 private void showDialog() { 139 final DialogFragment newFragment = 140 InstantAppButtonDialogFragment.newInstance(mPackageName); 141 newFragment.setTargetFragment(mParent, 0); 142 newFragment.show(mParent.getFragmentManager(), KEY_INSTANT_APP_BUTTONS); 143 } 144 getDefaultLaunchUri()145 private String getDefaultLaunchUri() { 146 final PackageManager manager = mContext.getPackageManager(); 147 final Intent intent = new Intent(Intent.ACTION_MAIN); 148 intent.addCategory(Intent.CATEGORY_LAUNCHER); 149 intent.setPackage(mPackageName); 150 final List<ResolveInfo> infos = manager.queryIntentActivities( 151 intent, PackageManager.GET_META_DATA | PackageManager.MATCH_INSTANT); 152 for (ResolveInfo info : infos) { 153 final Bundle metaData = info.activityInfo.metaData; 154 if (metaData != null) { 155 final String launchUri = metaData.getString(META_DATA_DEFAULT_URI); 156 if (!TextUtils.isEmpty(launchUri)) { 157 return launchUri; 158 } 159 } 160 } 161 return null; 162 } 163 } 164