/* * Copyright 2016 The OpenYOLO Authors. All Rights Reserved. * * 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 org.openyolo.demoprovider.barbican; import android.annotation.SuppressLint; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.graphics.drawable.Drawable; import android.os.AsyncTask; import android.os.Bundle; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.support.design.widget.AppBarLayout; import android.support.design.widget.Snackbar; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.Toolbar; import android.util.Log; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.EditText; import android.widget.ImageView; import android.widget.Spinner; import android.widget.TextView; import butterknife.BindView; import butterknife.ButterKnife; import butterknife.OnItemSelected; import butterknife.OnTextChanged; import java.io.IOException; import java.util.ArrayList; import java.util.List; import org.openyolo.demoprovider.barbican.storage.CredentialStorageClient; import org.openyolo.protocol.AuthenticationDomain; import org.openyolo.protocol.AuthenticationMethods; import org.openyolo.protocol.Credential; /** * Creates credentials from manual user input for storage. */ public class CreateCredentialActivity extends AppCompatActivity implements CredentialStorageClient.ConnectedCallback { private static final String LOG_TAG = "CreateCredential"; private static final int MIN_ID_LENGTH = 1; private static final int MIN_PASS_LENGTH = 1; @BindView(android.R.id.content) View mRootView; @BindView(R.id.headerToolbar) Toolbar mToolbar; @BindView(R.id.appBar) AppBarLayout mAppBar; @BindView(R.id.credential_authority) Spinner mCredentialAuthority; @BindView(R.id.credential_id) EditText mCredentialId; @BindView(R.id.credential_password) EditText mCredentialPassword; private MenuItem mDoneButton; private CredentialStorageClient mStorageClient; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.create_credential_layout); ButterKnife.bind(this); getSupportActionBar(); setSupportActionBar(mToolbar); mToolbar.setNavigationIcon(R.drawable.back); mToolbar.setNavigationOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { finish(); } }); mCredentialAuthority.setAdapter(new AppAdapter(getInstalledApps())); } @Override protected void onStart() { super.onStart(); CredentialStorageClient.connect(this, this); } @Override public void onStorageConnected(CredentialStorageClient client) { mStorageClient = client; } @Override protected void onStop() { super.onStop(); mStorageClient.disconnect(this); } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.menu_create, menu); mDoneButton = menu.findItem(R.id.action_done); onFieldsChanged(); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { if (super.onOptionsItemSelected(item)) { return true; } if (R.id.action_done == item.getItemId()) { App app = (App) mCredentialAuthority.getSelectedItem(); String username = mCredentialId.getText().toString(); String password = mCredentialPassword.getText().toString(); new StoreCredentialTask(app.mPackageName, username, password).execute(); } return false; } @OnItemSelected(R.id.credential_authority) @OnTextChanged({R.id.credential_id, R.id.credential_password}) void onFieldsChanged() { boolean validCredential = mCredentialAuthority.getSelectedItemPosition() != Spinner.INVALID_POSITION && mCredentialId.length() >= MIN_ID_LENGTH && mCredentialPassword.length() >= MIN_PASS_LENGTH; if (mDoneButton != null) { mDoneButton.setEnabled(validCredential); } } private List<App> getInstalledApps() { List<String> appPackageNames = InstalledAppsUtil.getInstalledAppsList(this); ArrayList<App> apps = new ArrayList<>(); PackageManager pm = getPackageManager(); for (String packageName : appPackageNames) { try { ApplicationInfo info = pm.getApplicationInfo(packageName, 0); String appName = pm.getApplicationLabel(info).toString(); Drawable appIcon = pm.getApplicationIcon(info); apps.add(new App(packageName, appName, appIcon)); } catch (PackageManager.NameNotFoundException e) { // skip this app } } return apps; } @SuppressLint("StaticFieldLeak") private class StoreCredentialTask extends AsyncTask<Void, Void, Boolean> { final String mPackageName; final String mUsername; final String mPassword; StoreCredentialTask( String packageName, String username, String password) { mPackageName = packageName; mUsername = username; mPassword = password; } @Override protected Boolean doInBackground(Void... params) { AuthenticationDomain domain = AuthenticationDomain.fromPackageName( CreateCredentialActivity.this, mPackageName); if (null == domain) { Log.e(LOG_TAG, "Failed to find auth-domain associated with package name."); return null; } Credential credential = new Credential.Builder( mUsername, AuthenticationMethods.EMAIL, domain) .setPassword(mPassword) .build(); try { mStorageClient.upsertCredential(credential.toProtobuf()); return true; } catch (IOException e) { Log.w(LOG_TAG, "Failed to upsert credential to database"); } return null; } @Override protected void onPostExecute(Boolean success) { if (success) { finish(); } else { Snackbar.make( mRootView, R.string.save_failed, Snackbar.LENGTH_SHORT).show(); } } } private class App implements Comparable<App> { @NonNull String mName; @NonNull String mPackageName; @Nullable Drawable mIcon; App(@NonNull String packageName, @NonNull String name, @Nullable Drawable icon) { mPackageName = packageName; mName = name; mIcon = icon; } @Override public int compareTo(@NonNull App app) { return mName.compareTo(app.mName); } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (!(obj instanceof App)) { return false; } App other = (App) obj; return mPackageName.equals(other.mPackageName); } @Override public int hashCode() { return mPackageName.hashCode(); } } private class AppAdapter extends BaseAdapter { private final List<App> mApps; private final LayoutInflater mInflater; AppAdapter(@NonNull List<App> apps) { mApps = apps; mInflater = LayoutInflater.from(CreateCredentialActivity.this); } @Override public int getCount() { return mApps.size(); } @Override public Object getItem(int index) { return mApps.get(index); } @Override public long getItemId(int index) { return mApps.get(index).hashCode(); } @Override public View getView(int index, View view, ViewGroup viewGroup) { App app = mApps.get(index); if (view == null) { view = mInflater.inflate(R.layout.app_item, viewGroup, false); } ImageView iconView = (ImageView) view.findViewById(R.id.app_icon); if (app.mIcon != null) { iconView.setImageDrawable(app.mIcon); iconView.setVisibility(View.VISIBLE); } else { iconView.setVisibility(View.INVISIBLE); } TextView nameView = (TextView) view.findViewById(R.id.app_name); nameView.setText(app.mName); return view; } } }