Home | History | Annotate | Download | only in appinfo
      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.app.AlertDialog;
     20 import android.content.Context;
     21 import android.content.DialogInterface;
     22 import android.content.Intent;
     23 import android.content.pm.PackageManager;
     24 import android.content.pm.ResolveInfo;
     25 import android.net.Uri;
     26 import android.os.Bundle;
     27 import android.os.UserHandle;
     28 import android.support.annotation.VisibleForTesting;
     29 import android.support.v7.preference.PreferenceScreen;
     30 import android.text.TextUtils;
     31 import android.view.Menu;
     32 import android.view.MenuInflater;
     33 import android.view.MenuItem;
     34 import android.view.View;
     35 import android.widget.Button;
     36 
     37 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
     38 import com.android.settings.R;
     39 import com.android.settings.applications.AppStoreUtil;
     40 import com.android.settings.applications.LayoutPreference;
     41 import com.android.settings.core.BasePreferenceController;
     42 import com.android.settings.overlay.FeatureFactory;
     43 import com.android.settingslib.applications.AppUtils;
     44 import com.android.settingslib.core.lifecycle.Lifecycle;
     45 import com.android.settingslib.core.lifecycle.LifecycleObserver;
     46 import com.android.settingslib.core.lifecycle.events.OnCreateOptionsMenu;
     47 import com.android.settingslib.core.lifecycle.events.OnOptionsItemSelected;
     48 import com.android.settingslib.core.lifecycle.events.OnPrepareOptionsMenu;
     49 import com.android.settingslib.wrapper.PackageManagerWrapper;
     50 
     51 import java.util.List;
     52 
     53 public class InstantAppButtonsPreferenceController extends BasePreferenceController implements
     54         LifecycleObserver, OnCreateOptionsMenu, OnPrepareOptionsMenu, OnOptionsItemSelected,
     55         DialogInterface.OnClickListener {
     56 
     57     private static final String KEY_INSTANT_APP_BUTTONS = "instant_app_buttons";
     58     private static final String META_DATA_DEFAULT_URI = "default-url";
     59 
     60     private final AppInfoDashboardFragment mParent;
     61     private final String mPackageName;
     62     private final PackageManagerWrapper mPackageManagerWrapper;
     63     private String mLaunchUri;
     64     private LayoutPreference mPreference;
     65     private MenuItem mInstallMenu;
     66 
     67     public InstantAppButtonsPreferenceController(Context context, AppInfoDashboardFragment parent,
     68             String packageName, Lifecycle lifecycle) {
     69         super(context, KEY_INSTANT_APP_BUTTONS);
     70         mParent = parent;
     71         mPackageName = packageName;
     72         mPackageManagerWrapper = new PackageManagerWrapper(context.getPackageManager());
     73         mLaunchUri = getDefaultLaunchUri();
     74         if (lifecycle != null) {
     75             lifecycle.addObserver(this);
     76         }
     77     }
     78 
     79     @Override
     80     public int getAvailabilityStatus() {
     81         return AppUtils.isInstant(mParent.getPackageInfo().applicationInfo)
     82                 ? AVAILABLE : DISABLED_FOR_USER;
     83     }
     84 
     85     @Override
     86     public void displayPreference(PreferenceScreen screen) {
     87         super.displayPreference(screen);
     88         mPreference = (LayoutPreference) screen.findPreference(KEY_INSTANT_APP_BUTTONS);
     89         initButtons(mPreference.findViewById(R.id.instant_app_button_container));
     90     }
     91 
     92     @Override
     93     public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
     94         if (!TextUtils.isEmpty(mLaunchUri)) {
     95             menu.add(0, AppInfoDashboardFragment.INSTALL_INSTANT_APP_MENU, 2, R.string.install_text)
     96                 .setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
     97         }
     98     }
     99 
    100     @Override
    101     public boolean onOptionsItemSelected(MenuItem menuItem) {
    102         if (menuItem.getItemId() == AppInfoDashboardFragment.INSTALL_INSTANT_APP_MENU) {
    103             final Intent appStoreIntent = AppStoreUtil.getAppStoreLink(mContext, mPackageName);
    104             if (appStoreIntent != null) {
    105                 mParent.startActivity(appStoreIntent);
    106             }
    107             return true;
    108         }
    109         return false;
    110     }
    111 
    112     @Override
    113     public void onPrepareOptionsMenu(Menu menu) {
    114         mInstallMenu = menu.findItem(AppInfoDashboardFragment.INSTALL_INSTANT_APP_MENU);
    115         if (mInstallMenu != null) {
    116             if (AppStoreUtil.getAppStoreLink(mContext, mPackageName) == null) {
    117                 mInstallMenu.setEnabled(false);
    118             }
    119         }
    120     }
    121 
    122     @Override
    123     public void onClick(DialogInterface dialog, int which) {
    124         FeatureFactory.getFactory(mContext).getMetricsFeatureProvider()
    125             .action(mContext, MetricsEvent.ACTION_SETTINGS_CLEAR_INSTANT_APP, mPackageName);
    126         mPackageManagerWrapper.deletePackageAsUser(
    127             mPackageName, null, 0, UserHandle.myUserId());
    128     }
    129 
    130     AlertDialog createDialog(int id) {
    131         if (id == AppInfoDashboardFragment.DLG_CLEAR_INSTANT_APP) {
    132             AlertDialog confirmDialog = new AlertDialog.Builder(mContext)
    133                 .setPositiveButton(R.string.clear_instant_app_data, this)
    134                 .setNegativeButton(R.string.cancel, null)
    135                 .setTitle(R.string.clear_instant_app_data)
    136                 .setMessage(mContext.getString(R.string.clear_instant_app_confirmation))
    137                 .create();
    138             return confirmDialog;
    139         }
    140         return null;
    141     }
    142 
    143     private void initButtons(View view) {
    144         final Button installButton = view.findViewById(R.id.install);
    145         final Button clearDataButton = view.findViewById(R.id.clear_data);
    146         final Button launchButton = view.findViewById(R.id.launch);
    147         if (!TextUtils.isEmpty(mLaunchUri)) {
    148             installButton.setVisibility(View.GONE);
    149             final Intent intent = new Intent(Intent.ACTION_VIEW);
    150             intent.addCategory(Intent.CATEGORY_BROWSABLE);
    151             intent.setPackage(mPackageName);
    152             intent.setData(Uri.parse(mLaunchUri));
    153             intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    154             launchButton.setOnClickListener(v -> mParent.startActivity(intent));
    155         } else {
    156             launchButton.setVisibility(View.GONE);
    157             final Intent appStoreIntent = AppStoreUtil.getAppStoreLink(mContext, mPackageName);
    158             if (appStoreIntent != null) {
    159                 installButton.setOnClickListener(v -> mParent.startActivity(appStoreIntent));
    160             } else {
    161                 installButton.setEnabled(false);
    162             }
    163         }
    164         clearDataButton.setOnClickListener(
    165             v -> mParent.showDialogInner(mParent.DLG_CLEAR_INSTANT_APP, 0));
    166     }
    167 
    168     private String getDefaultLaunchUri() {
    169         final PackageManager manager = mContext.getPackageManager();
    170         final Intent intent = new Intent(Intent.ACTION_MAIN);
    171         intent.addCategory(Intent.CATEGORY_LAUNCHER);
    172         intent.setPackage(mPackageName);
    173         final List<ResolveInfo> infos = manager.queryIntentActivities(
    174             intent, PackageManager.GET_META_DATA | PackageManager.MATCH_INSTANT);
    175         for (ResolveInfo info : infos) {
    176             final Bundle metaData = info.activityInfo.metaData;
    177             if (metaData != null) {
    178                 final String launchUri = metaData.getString(META_DATA_DEFAULT_URI);
    179                 if (!TextUtils.isEmpty(launchUri)) {
    180                     return launchUri;
    181                 }
    182             }
    183         }
    184         return null;
    185     }
    186 }
    187