content: /*
   * Copyright (C) 2016 The Android Open Source Project
   *
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   *      http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  
  package androidx.test.ui.app;
  
  import static com.google.common.base.Preconditions.checkNotNull;
  
  import android.Manifest;
  import android.accounts.AccountManager;
  import android.annotation.SuppressLint;
  import android.content.pm.PackageManager;
  import android.graphics.Color;
  import android.os.Bundle;
  import android.telephony.TelephonyManager;
  import android.view.View;
  import android.widget.TextView;
  import androidx.annotation.NonNull;
  import androidx.appcompat.app.AppCompatActivity;
  import androidx.appcompat.widget.Toolbar;
  import androidx.core.app.ActivityCompat;
  import androidx.core.content.ContextCompat;
  
  /**
   * Runtime Permissions Activity that request {@link Manifest.permission#READ_PHONE_STATE
   * READ_PHONE_STATE}
   */
  public class RuntimePermissionsActivity extends AppCompatActivity {
  
    private static final int REQUEST_CODE_READ_PHONE_STATE = 1;
    private static final int REQUEST_CODE_GET_ACCOUNTS = 2;
  
    private TextView mPhoneStatePermissionStatus;
    private TextView mGetAccountsPermissionStatus;
  
    @Override
    protected void onCreate(Bundle savedInstanceState) {
  
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_runtime_permissions);
  
      // Set up the toolbar.
      Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
      toolbar.setTitleTextColor(Color.WHITE);
      setSupportActionBar(toolbar);
      getSupportActionBar().setDisplayHomeAsUpEnabled(true);
  
      mPhoneStatePermissionStatus = (TextView) findViewById(
          R.id.phone_state_permission_permission_status);
      mGetAccountsPermissionStatus = (TextView) findViewById(R.id.get_accounts_permission_status);
    }
  
    public void requestPhoneStatePermission(View view) {
      checkPermissionOrRequest(Manifest.permission.READ_PHONE_STATE, REQUEST_CODE_READ_PHONE_STATE,
          new Runnable() {
            @Override
            public void run() {
              updateReadPhoneStatePermissionsGranted();
            }
          });
    }
  
    public void requestAccountsPermission(View view) {
      checkPermissionOrRequest(Manifest.permission.GET_ACCOUNTS, REQUEST_CODE_GET_ACCOUNTS,
          new Runnable() {
            @Override
            public void run() {
              updateGetAccountsPermissionsGranted();
            }
          });
    }
  
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
        @NonNull int[] grantResults) {
      if (REQUEST_CODE_READ_PHONE_STATE == requestCode) {
        if (1 == grantResults.length && PackageManager.PERMISSION_GRANTED == grantResults[0]) {
          // Read phone state permission has been granted
          updateReadPhoneStatePermissionsGranted();
        } else {
          updateReadPhoneStatePermissionsRevoked();
        }
      } else if (REQUEST_CODE_GET_ACCOUNTS == requestCode) {
        if (1 == grantResults.length && PackageManager.PERMISSION_GRANTED == grantResults[0]) {
          // Read phone state permission has been granted
          updateGetAccountsPermissionsGranted();
        } else {
          updateGetAccountsPermissionsRevoked();
        }
      } else {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
      }
    }
  
    private boolean checkPermissionOrRequest(String permission, int requestCode, Runnable
        requestFunction) {
      if (PackageManager.PERMISSION_GRANTED
          == ContextCompat.checkSelfPermission(this, permission)) {
        requestFunction.run();
        return true;
      } else {
        ActivityCompat.requestPermissions(this, new String[]{permission}, requestCode);
        return false;
      }
    }
  
    /**
     * This method purely serves the purpose of using an API which is guarded by a dangerous runtime
     * permission. In this case {@link TelephonyManager#getVoiceMailNumber()} requires {@link
     * Manifest.permission#READ_PHONE_STATE}
     */
    @SuppressLint("MissingPermission")
    private void getVoiceMailNumber() {
      ((TelephonyManager) getSystemService(RuntimePermissionsActivity.TELEPHONY_SERVICE))
          .getVoiceMailNumber();
    }
  
    private void updateReadPhoneStatePermissionsGranted() {
      getVoiceMailNumber();
      updateGrantedUi(mPhoneStatePermissionStatus);
    }
  
    private void updateReadPhoneStatePermissionsRevoked() {
      updateRevokedUi(mPhoneStatePermissionStatus);
    }
  
    /**
     * This method purely serves the purpose of using an API which is guarded by a dangerous runtime
     * permission. In this case {@link AccountManager#getAccounts()} requires {@link
     * Manifest.permission#GET_ACCOUNTS}
     */
    private void getAccounts() {
      ((AccountManager) getSystemService(RuntimePermissionsActivity.ACCOUNT_SERVICE))
          .getAccounts();
    }
  
    private void updateGetAccountsPermissionsGranted() {
      getAccounts();
      updateGrantedUi(mGetAccountsPermissionStatus);
    }
  
    private void updateGetAccountsPermissionsRevoked() {
      updateRevokedUi(mGetAccountsPermissionStatus);
    }
  
    private void updateGrantedUi(@NonNull TextView textView) {
      checkNotNull(textView, "textView cannot be null!");
      textView.setVisibility(View.VISIBLE);
      textView.setText(getString(R.string.permissionGranted));
    }
  
    private void updateRevokedUi(@NonNull TextView textView) {
      checkNotNull(textView, "textView cannot be null!");
      textView.setVisibility(View.VISIBLE);
      textView.setText(getString(R.string.permissionRevoked));
    }
  }
  