Home | History | Annotate | Download | only in pm
      1 /*
      2  * Copyright (C) 2016 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.car.pm;
     17 
     18 import android.app.Activity;
     19 import android.car.Car;
     20 import android.car.CarNotConnectedException;
     21 import android.car.content.pm.CarPackageManager;
     22 import android.content.ComponentName;
     23 import android.content.Intent;
     24 import android.content.ServiceConnection;
     25 import android.content.pm.PackageManager;
     26 import android.content.pm.ResolveInfo;
     27 import android.os.Bundle;
     28 import android.os.Handler;
     29 import android.os.IBinder;
     30 import android.os.Looper;
     31 import android.util.Log;
     32 import android.view.View;
     33 import android.widget.Button;
     34 
     35 import com.android.car.CarLog;
     36 import com.android.car.R;
     37 
     38 /**
     39  * Default activity that will be launched when the current foreground activity is not allowed.
     40  * Additional information on blocked Activity will be passed as extra in Intent
     41  * via {@link #INTENT_KEY_BLOCKED_ACTIVITY} key. *
     42  */
     43 public class ActivityBlockingActivity extends Activity {
     44 
     45     public static final String INTENT_KEY_BLOCKED_ACTIVITY = "blocked_activity";
     46 
     47     private static final long AUTO_DISMISS_TIME_MS = 3000;
     48 
     49     private Handler mHandler;
     50 
     51     private Button mExitButton;
     52 
     53     private Car mCar;
     54 
     55     private boolean mExitRequested;
     56 
     57     private final Runnable mFinishRunnable = () -> handleFinish();
     58 
     59     @Override
     60     protected void onCreate(Bundle savedInstanceState) {
     61         super.onCreate(savedInstanceState);
     62         setContentView(R.layout.activity_blocking);
     63         mHandler = new Handler(Looper.getMainLooper());
     64         mExitButton = (Button) findViewById(R.id.botton_exit_now);
     65         mExitButton.setOnClickListener((View v) -> handleFinish());
     66         mCar = Car.createCar(this, new ServiceConnection() {
     67 
     68             @Override
     69             public void onServiceConnected(ComponentName name, IBinder service) {
     70                 if (mExitRequested) {
     71                     handleFinish();
     72                 }
     73             }
     74 
     75             @Override
     76             public void onServiceDisconnected(ComponentName name) {
     77             }
     78 
     79         });
     80         mCar.connect();
     81     }
     82 
     83     @Override
     84     protected void onResume() {
     85         super.onResume();
     86         mHandler.postDelayed(mFinishRunnable, AUTO_DISMISS_TIME_MS);
     87     }
     88 
     89     @Override
     90     protected void onDestroy() {
     91         super.onDestroy();
     92         mHandler.removeCallbacks(mFinishRunnable);
     93         mCar.disconnect();
     94     }
     95 
     96     private void handleFinish() {
     97         if (!mCar.isConnected()) {
     98             mExitRequested = true;
     99             return;
    100         }
    101         if (isFinishing()) {
    102             return;
    103         }
    104         try {
    105             CarPackageManager carPm = (CarPackageManager) mCar.getCarManager(Car.PACKAGE_SERVICE);
    106 
    107             // finish itself only when it will not lead into another blocking
    108             if (carPm.isActivityBackedBySafeActivity(getComponentName())) {
    109                 finish();
    110                 return;
    111             }
    112             // back activity is not safe either. Now try home
    113             Intent homeIntent = new Intent(Intent.ACTION_MAIN);
    114             homeIntent.addCategory(Intent.CATEGORY_HOME);
    115             PackageManager pm = getPackageManager();
    116             ComponentName homeComponent = homeIntent.resolveActivity(pm);
    117             if (carPm.isActivityAllowedWhileDriving(homeComponent.getPackageName(),
    118                     homeComponent.getClassName())) {
    119                 startActivity(homeIntent);
    120                 finish();
    121                 return;
    122             } else {
    123                 Log.w(CarLog.TAG_AM, "Home activity is not in white list. Keep blocking activity. "
    124                         + ", Home Activity:" + homeComponent);
    125             }
    126         } catch (CarNotConnectedException e) {
    127             Log.w(CarLog.TAG_AM, "Car service not avaiable, will finish", e);
    128             finish();
    129         }
    130     }
    131 }
    132